Keyboard.c revision 4642e01f
1/*
2
3Copyright 1993 by Davor Matic
4
5Permission to use, copy, modify, distribute, and sell this software
6and its documentation for any purpose is hereby granted without fee,
7provided that the above copyright notice appear in all copies and that
8both that copyright notice and this permission notice appear in
9supporting documentation.  Davor Matic makes no representations about
10the suitability of this software for any purpose.  It is provided "as
11is" without express or implied warranty.
12
13*/
14
15#define NEED_EVENTS
16#ifdef HAVE_XNEST_CONFIG_H
17#include <xnest-config.h>
18#endif
19
20#include <X11/X.h>
21#include <X11/Xproto.h>
22#include <X11/keysym.h>
23#include "screenint.h"
24#include "inputstr.h"
25#include "misc.h"
26#include "scrnintstr.h"
27#include "servermd.h"
28
29#include "Xnest.h"
30
31#include "Display.h"
32#include "Screen.h"
33#include "Keyboard.h"
34#include "Args.h"
35#include "Events.h"
36
37#ifdef XKB
38#include <X11/extensions/XKB.h>
39#include <xkbsrv.h>
40#include <X11/extensions/XKBconfig.h>
41
42extern Bool
43XkbQueryExtension(
44	Display *		/* dpy */,
45	int *			/* opcodeReturn */,
46	int *			/* eventBaseReturn */,
47	int *			/* errorBaseReturn */,
48	int *			/* majorRtrn */,
49	int *			/* minorRtrn */
50);
51
52extern	XkbDescPtr XkbGetKeyboard(
53	Display *		/* dpy */,
54	unsigned int		/* which */,
55	unsigned int		/* deviceSpec */
56);
57
58extern	Status	XkbGetControls(
59	Display *		/* dpy */,
60	unsigned long		/* which */,
61	XkbDescPtr		/* desc */
62);
63
64#ifndef XKB_BASE_DIRECTORY
65#define	XKB_BASE_DIRECTORY	"/usr/X11R6/lib/X11/xkb/"
66#endif
67#ifndef XKB_CONFIG_FILE
68#define	XKB_CONFIG_FILE		"X0-config.keyboard"
69#endif
70#ifndef XKB_DFLT_RULES_FILE
71#define	XKB_DFLT_RULES_FILE	__XKBDEFRULES__
72#endif
73#ifndef XKB_DFLT_KB_LAYOUT
74#define	XKB_DFLT_KB_LAYOUT	"us"
75#endif
76#ifndef XKB_DFLT_KB_MODEL
77#define	XKB_DFLT_KB_MODEL	"pc101"
78#endif
79#ifndef XKB_DFLT_KB_VARIANT
80#define	XKB_DFLT_KB_VARIANT	NULL
81#endif
82#ifndef XKB_DFLT_KB_OPTIONS
83#define	XKB_DFLT_KB_OPTIONS	NULL
84#endif
85
86#endif
87
88DeviceIntPtr xnestKeyboardDevice = NULL;
89
90void
91xnestBell(int volume, DeviceIntPtr pDev, pointer ctrl, int cls)
92{
93  XBell(xnestDisplay, volume);
94}
95
96void
97DDXRingBell(int volume, int pitch, int duration)
98{
99  XBell(xnestDisplay, volume);
100}
101
102void
103xnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl *ctrl)
104{
105#if 0
106  unsigned long value_mask;
107  XKeyboardControl values;
108  int i;
109
110  value_mask = KBKeyClickPercent |
111               KBBellPercent |
112	       KBBellPitch |
113	       KBBellDuration |
114	       KBAutoRepeatMode;
115
116  values.key_click_percent = ctrl->click;
117  values.bell_percent = ctrl->bell;
118  values.bell_pitch = ctrl->bell_pitch;
119  values.bell_duration = ctrl->bell_duration;
120  values.auto_repeat_mode = ctrl->autoRepeat ?
121                             AutoRepeatModeOn : AutoRepeatModeOff;
122
123  XChangeKeyboardControl(xnestDisplay, value_mask, &values);
124
125  /*
126  value_mask = KBKey | KBAutoRepeatMode;
127  At this point, we need to walk through the vector and compare it
128  to the current server vector.  If there are differences, report them.
129  */
130
131  value_mask = KBLed | KBLedMode;
132  for (i = 1; i <= 32; i++) {
133    values.led = i;
134    values.led_mode = (ctrl->leds & (1 << (i - 1))) ? LedModeOn : LedModeOff;
135    XChangeKeyboardControl(xnestDisplay, value_mask, &values);
136  }
137#endif
138}
139
140int
141xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
142{
143  XModifierKeymap *modifier_keymap;
144  KeySym *keymap;
145  int mapWidth;
146  int min_keycode, max_keycode;
147  KeySymsRec keySyms;
148  CARD8 modmap[MAP_LENGTH];
149  int i, j;
150  XKeyboardState values;
151
152  switch (onoff)
153    {
154    case DEVICE_INIT:
155      modifier_keymap = XGetModifierMapping(xnestDisplay);
156      XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode);
157#ifdef _XSERVER64
158      {
159	KeySym64 *keymap64;
160	int i, len;
161	keymap64 = XGetKeyboardMapping(xnestDisplay,
162				     min_keycode,
163				     max_keycode - min_keycode + 1,
164				     &mapWidth);
165	len = (max_keycode - min_keycode + 1) * mapWidth;
166	keymap = (KeySym *)xalloc(len * sizeof(KeySym));
167	for(i = 0; i < len; ++i)
168	  keymap[i] = keymap64[i];
169	XFree(keymap64);
170      }
171#else
172      keymap = XGetKeyboardMapping(xnestDisplay,
173				   min_keycode,
174				   max_keycode - min_keycode + 1,
175				   &mapWidth);
176#endif
177
178      for (i = 0; i < MAP_LENGTH; i++)
179	modmap[i] = 0;
180      for (j = 0; j < 8; j++)
181	for(i = 0; i < modifier_keymap->max_keypermod; i++) {
182	  CARD8 keycode;
183	  if ((keycode =
184	      modifier_keymap->
185	        modifiermap[j * modifier_keymap->max_keypermod + i]))
186	    modmap[keycode] |= 1<<j;
187	}
188      XFreeModifiermap(modifier_keymap);
189
190      keySyms.minKeyCode = min_keycode;
191      keySyms.maxKeyCode = max_keycode;
192      keySyms.mapWidth = mapWidth;
193      keySyms.map = keymap;
194
195#ifdef XKB
196      if (noXkbExtension) {
197XkbError:
198#endif
199      XGetKeyboardControl(xnestDisplay, &values);
200
201      memmove((char *) defaultKeyboardControl.autoRepeats,
202             (char *) values.auto_repeats, sizeof(values.auto_repeats));
203
204      InitKeyboardDeviceStruct(&pDev->public, &keySyms, modmap,
205			       xnestBell, xnestChangeKeyboardControl);
206#ifdef XKB
207      } else {
208	XkbComponentNamesRec names;
209	char *rules, *model, *layout, *variants, *options;
210
211	XkbDescPtr xkb;
212	int op, event, error, major, minor;
213
214	if (XkbQueryExtension(xnestDisplay, &op, &event, &error, &major, &minor) == 0) {
215	  ErrorF("Unable to initialize XKEYBOARD extension.\n");
216	  goto XkbError;
217        }
218	xkb = XkbGetKeyboard(xnestDisplay, XkbGBN_AllComponentsMask, XkbUseCoreKbd);
219	if (xkb == NULL || xkb->geom == NULL) {
220	  ErrorF("Couldn't get keyboard.\n");
221	  goto XkbError;
222	}
223	XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb);
224
225	memset(&names, 0, sizeof(XkbComponentNamesRec));
226	rules = XKB_DFLT_RULES_FILE;
227	model = XKB_DFLT_KB_MODEL;
228	layout = XKB_DFLT_KB_LAYOUT;
229	variants = XKB_DFLT_KB_VARIANT;
230	options = XKB_DFLT_KB_OPTIONS;
231
232	XkbSetRulesDflts(rules, model, layout, variants, options);
233	XkbInitKeyboardDeviceStruct(pDev, &names, &keySyms, modmap,
234				    xnestBell, xnestChangeKeyboardControl);
235	XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls);
236	XkbFreeKeyboard(xkb, 0, False);
237      }
238#endif
239      xfree(keymap);
240      break;
241    case DEVICE_ON:
242      xnestEventMask |= XNEST_KEYBOARD_EVENT_MASK;
243      for (i = 0; i < xnestNumScreens; i++)
244	XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
245      break;
246    case DEVICE_OFF:
247      xnestEventMask &= ~XNEST_KEYBOARD_EVENT_MASK;
248      for (i = 0; i < xnestNumScreens; i++)
249	XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
250      break;
251    case DEVICE_CLOSE:
252      break;
253    }
254  return Success;
255}
256
257Bool
258LegalModifier(unsigned int key, DeviceIntPtr pDev)
259{
260  return TRUE;
261}
262
263void
264xnestUpdateModifierState(unsigned int state)
265{
266  DeviceIntPtr pDev = xnestKeyboardDevice;
267  KeyClassPtr keyc = pDev->key;
268  int i;
269  CARD8 mask;
270
271  state = state & 0xff;
272
273  if (keyc->state == state)
274    return;
275
276  for (i = 0, mask = 1; i < 8; i++, mask <<= 1) {
277    int key;
278
279    /* Modifier is down, but shouldn't be
280     */
281    if ((keyc->state & mask) && !(state & mask)) {
282      int count = keyc->modifierKeyCount[i];
283
284      for (key = 0; key < MAP_LENGTH; key++)
285	if (keyc->modifierMap[key] & mask) {
286	  int bit;
287	  BYTE *kptr;
288
289	  kptr = &keyc->down[key >> 3];
290	  bit = 1 << (key & 7);
291
292	  if (*kptr & bit)
293	    xnestQueueKeyEvent(KeyRelease, key);
294
295	  if (--count == 0)
296	    break;
297	}
298    }
299
300    /* Modifier shoud be down, but isn't
301     */
302    if (!(keyc->state & mask) && (state & mask))
303      for (key = 0; key < MAP_LENGTH; key++)
304	if (keyc->modifierMap[key] & mask) {
305	  xnestQueueKeyEvent(KeyPress, key);
306	  break;
307	}
308  }
309}
310