Keyboard.c revision 475c125c
18c9fbc29Smrg/*
28c9fbc29Smrg
38c9fbc29SmrgCopyright 1993 by Davor Matic
48c9fbc29Smrg
58c9fbc29SmrgPermission to use, copy, modify, distribute, and sell this software
68c9fbc29Smrgand its documentation for any purpose is hereby granted without fee,
78c9fbc29Smrgprovided that the above copyright notice appear in all copies and that
88c9fbc29Smrgboth that copyright notice and this permission notice appear in
94cd6a3aeSmrgsupporting documentation.  Davor Matic makes no representations about
104cd6a3aeSmrgthe suitability of this software for any purpose.  It is provided "as
118c9fbc29Smrgis" without express or implied warranty.
124cd6a3aeSmrg
138c9fbc29Smrg*/
148c9fbc29Smrg
154cd6a3aeSmrg#ifdef HAVE_XNEST_CONFIG_H
164cd6a3aeSmrg#include <xnest-config.h>
174cd6a3aeSmrg#endif
188c9fbc29Smrg
194cd6a3aeSmrg#include <X11/X.h>
204cd6a3aeSmrg#include <X11/Xproto.h>
214cd6a3aeSmrg#include <X11/keysym.h>
228c9fbc29Smrg#include "screenint.h"
238c9fbc29Smrg#include "inputstr.h"
248c9fbc29Smrg#include "misc.h"
258c9fbc29Smrg#include "scrnintstr.h"
268c9fbc29Smrg#include "servermd.h"
278c9fbc29Smrg
288c9fbc29Smrg#include "Xnest.h"
298c9fbc29Smrg
308c9fbc29Smrg#include "Display.h"
318c9fbc29Smrg#include "Screen.h"
328c9fbc29Smrg#include "Keyboard.h"
338c9fbc29Smrg#include "Args.h"
348c9fbc29Smrg#include "Events.h"
358c9fbc29Smrg
368c9fbc29Smrg#include <X11/extensions/XKB.h>
378c9fbc29Smrg#include "xkbsrv.h"
388c9fbc29Smrg#include <X11/extensions/XKBconfig.h>
398c9fbc29Smrg
408c9fbc29Smrgextern Bool
418c9fbc29SmrgXkbQueryExtension(
428c9fbc29Smrg	Display *		/* dpy */,
438c9fbc29Smrg	int *			/* opcodeReturn */,
448c9fbc29Smrg	int *			/* eventBaseReturn */,
458c9fbc29Smrg	int *			/* errorBaseReturn */,
468c9fbc29Smrg	int *			/* majorRtrn */,
478c9fbc29Smrg	int *			/* minorRtrn */
488c9fbc29Smrg);
498c9fbc29Smrg
508c9fbc29Smrgextern	XkbDescPtr XkbGetKeyboard(
518c9fbc29Smrg	Display *		/* dpy */,
528c9fbc29Smrg	unsigned int		/* which */,
538c9fbc29Smrg	unsigned int		/* deviceSpec */
548c9fbc29Smrg);
558c9fbc29Smrg
568c9fbc29Smrgextern	Status	XkbGetControls(
578c9fbc29Smrg	Display *		/* dpy */,
588c9fbc29Smrg	unsigned long		/* which */,
598c9fbc29Smrg	XkbDescPtr		/* desc */
608c9fbc29Smrg);
618c9fbc29Smrg
628c9fbc29SmrgDeviceIntPtr xnestKeyboardDevice = NULL;
638c9fbc29Smrg
648c9fbc29Smrgvoid
658c9fbc29SmrgxnestBell(int volume, DeviceIntPtr pDev, pointer ctrl, int cls)
668c9fbc29Smrg{
678c9fbc29Smrg  XBell(xnestDisplay, volume);
688c9fbc29Smrg}
698c9fbc29Smrg
70void
71DDXRingBell(int volume, int pitch, int duration)
72{
73  XBell(xnestDisplay, volume);
74}
75
76void
77xnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl *ctrl)
78{
79#if 0
80  unsigned long value_mask;
81  XKeyboardControl values;
82  int i;
83
84  value_mask = KBKeyClickPercent |
85               KBBellPercent |
86	       KBBellPitch |
87	       KBBellDuration |
88	       KBAutoRepeatMode;
89
90  values.key_click_percent = ctrl->click;
91  values.bell_percent = ctrl->bell;
92  values.bell_pitch = ctrl->bell_pitch;
93  values.bell_duration = ctrl->bell_duration;
94  values.auto_repeat_mode = ctrl->autoRepeat ?
95                             AutoRepeatModeOn : AutoRepeatModeOff;
96
97  XChangeKeyboardControl(xnestDisplay, value_mask, &values);
98
99  /*
100  value_mask = KBKey | KBAutoRepeatMode;
101  At this point, we need to walk through the vector and compare it
102  to the current server vector.  If there are differences, report them.
103  */
104
105  value_mask = KBLed | KBLedMode;
106  for (i = 1; i <= 32; i++) {
107    values.led = i;
108    values.led_mode = (ctrl->leds & (1 << (i - 1))) ? LedModeOn : LedModeOff;
109    XChangeKeyboardControl(xnestDisplay, value_mask, &values);
110  }
111#endif
112}
113
114int
115xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
116{
117  XModifierKeymap *modifier_keymap;
118  KeySym *keymap;
119  int mapWidth;
120  int min_keycode, max_keycode;
121  KeySymsRec keySyms;
122  CARD8 modmap[MAP_LENGTH];
123  int i, j;
124  XKeyboardState values;
125  XkbDescPtr xkb;
126  int op, event, error, major, minor;
127
128  switch (onoff)
129    {
130    case DEVICE_INIT:
131      XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode);
132#ifdef _XSERVER64
133      {
134	KeySym64 *keymap64;
135	int len;
136	keymap64 = XGetKeyboardMapping(xnestDisplay,
137				     min_keycode,
138				     max_keycode - min_keycode + 1,
139				     &mapWidth);
140	len = (max_keycode - min_keycode + 1) * mapWidth;
141	keymap = (KeySym *)malloc(len * sizeof(KeySym));
142	for(i = 0; i < len; ++i)
143	  keymap[i] = keymap64[i];
144	XFree(keymap64);
145      }
146#else
147      keymap = XGetKeyboardMapping(xnestDisplay,
148				   min_keycode,
149				   max_keycode - min_keycode + 1,
150				   &mapWidth);
151#endif
152
153      memset(modmap, 0, sizeof(modmap));
154      modifier_keymap = XGetModifierMapping(xnestDisplay);
155      for (j = 0; j < 8; j++)
156            for(i = 0; i < modifier_keymap->max_keypermod; i++) {
157                  CARD8 keycode;
158                  if ((keycode = modifier_keymap->modifiermap[j * modifier_keymap->max_keypermod + i]))
159                      modmap[keycode] |= 1<<j;
160      }
161      XFreeModifiermap(modifier_keymap);
162
163      keySyms.minKeyCode = min_keycode;
164      keySyms.maxKeyCode = max_keycode;
165      keySyms.mapWidth = mapWidth;
166      keySyms.map = keymap;
167
168      if (XkbQueryExtension(xnestDisplay, &op, &event, &error, &major, &minor) == 0) {
169          ErrorF("Unable to initialize XKEYBOARD extension.\n");
170	  goto XkbError;
171      }
172      xkb = XkbGetKeyboard(xnestDisplay, XkbGBN_AllComponentsMask, XkbUseCoreKbd);
173      if (xkb == NULL || xkb->geom == NULL) {
174	  ErrorF("Couldn't get keyboard.\n");
175          goto XkbError;
176      }
177      XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb);
178
179      InitKeyboardDeviceStruct(pDev, NULL,
180                               xnestBell, xnestChangeKeyboardControl);
181
182      XkbApplyMappingChange(pDev, &keySyms, keySyms.minKeyCode,
183                            keySyms.maxKeyCode - keySyms.minKeyCode + 1,
184                            modmap, serverClient);
185
186      XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls);
187      XkbFreeKeyboard(xkb, 0, False);
188      free(keymap);
189      break;
190    case DEVICE_ON:
191      xnestEventMask |= XNEST_KEYBOARD_EVENT_MASK;
192      for (i = 0; i < xnestNumScreens; i++)
193	XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
194      break;
195    case DEVICE_OFF:
196      xnestEventMask &= ~XNEST_KEYBOARD_EVENT_MASK;
197      for (i = 0; i < xnestNumScreens; i++)
198	XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
199      break;
200    case DEVICE_CLOSE:
201      break;
202    }
203  return Success;
204
205XkbError:
206  XGetKeyboardControl(xnestDisplay, &values);
207  memmove((char *)defaultKeyboardControl.autoRepeats,
208          (char *)values.auto_repeats,
209          sizeof(values.auto_repeats));
210
211  InitKeyboardDeviceStruct(pDev, NULL,
212                           xnestBell, xnestChangeKeyboardControl);
213  free(keymap);
214  return Success;
215}
216
217Bool
218LegalModifier(unsigned int key, DeviceIntPtr pDev)
219{
220  return TRUE;
221}
222
223void
224xnestUpdateModifierState(unsigned int state)
225{
226  DeviceIntPtr pDev = xnestKeyboardDevice;
227  KeyClassPtr keyc = pDev->key;
228  int i;
229  CARD8 mask;
230  int xkb_state;
231
232  if (!pDev)
233      return;
234
235  xkb_state = XkbStateFieldFromRec(&pDev->key->xkbInfo->state);
236  state = state & 0xff;
237
238  if (xkb_state == state)
239    return;
240
241  for (i = 0, mask = 1; i < 8; i++, mask <<= 1) {
242    int key;
243
244    /* Modifier is down, but shouldn't be
245     */
246    if ((xkb_state & mask) && !(state & mask)) {
247      int count = keyc->modifierKeyCount[i];
248
249      for (key = 0; key < MAP_LENGTH; key++)
250	if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
251	  if (key_is_down(pDev, key, KEY_PROCESSED))
252	    xnestQueueKeyEvent(KeyRelease, key);
253
254	  if (--count == 0)
255	    break;
256	}
257    }
258
259    /* Modifier shoud be down, but isn't
260     */
261    if (!(xkb_state & mask) && (state & mask))
262      for (key = 0; key < MAP_LENGTH; key++)
263	if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
264	  xnestQueueKeyEvent(KeyPress, key);
265	  break;
266	}
267  }
268}
269