Keyboard.c revision 6747b715
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#ifdef HAVE_XNEST_CONFIG_H
16#include <xnest-config.h>
17#endif
18
19#include <X11/X.h>
20#include <X11/Xproto.h>
21#include <X11/keysym.h>
22#include "screenint.h"
23#include "inputstr.h"
24#include "misc.h"
25#include "scrnintstr.h"
26#include "servermd.h"
27
28#include "Xnest.h"
29
30#include "Display.h"
31#include "Screen.h"
32#include "Keyboard.h"
33#include "Args.h"
34#include "Events.h"
35
36#include <X11/extensions/XKB.h>
37#include "xkbsrv.h"
38#include <X11/extensions/XKBconfig.h>
39
40extern Bool
41XkbQueryExtension(
42	Display *		/* dpy */,
43	int *			/* opcodeReturn */,
44	int *			/* eventBaseReturn */,
45	int *			/* errorBaseReturn */,
46	int *			/* majorRtrn */,
47	int *			/* minorRtrn */
48);
49
50extern	XkbDescPtr XkbGetKeyboard(
51	Display *		/* dpy */,
52	unsigned int		/* which */,
53	unsigned int		/* deviceSpec */
54);
55
56extern	Status	XkbGetControls(
57	Display *		/* dpy */,
58	unsigned long		/* which */,
59	XkbDescPtr		/* desc */
60);
61
62DeviceIntPtr xnestKeyboardDevice = NULL;
63
64void
65xnestBell(int volume, DeviceIntPtr pDev, pointer ctrl, int cls)
66{
67  XBell(xnestDisplay, volume);
68}
69
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  KeySym *keymap;
118  int mapWidth;
119  int min_keycode, max_keycode;
120  KeySymsRec keySyms;
121  int i;
122  XKeyboardState values;
123  XkbDescPtr xkb;
124  int op, event, error, major, minor;
125
126  switch (onoff)
127    {
128    case DEVICE_INIT:
129      XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode);
130#ifdef _XSERVER64
131      {
132	KeySym64 *keymap64;
133	int i, len;
134	keymap64 = XGetKeyboardMapping(xnestDisplay,
135				     min_keycode,
136				     max_keycode - min_keycode + 1,
137				     &mapWidth);
138	len = (max_keycode - min_keycode + 1) * mapWidth;
139	keymap = (KeySym *)malloc(len * sizeof(KeySym));
140	for(i = 0; i < len; ++i)
141	  keymap[i] = keymap64[i];
142	XFree(keymap64);
143      }
144#else
145      keymap = XGetKeyboardMapping(xnestDisplay,
146				   min_keycode,
147				   max_keycode - min_keycode + 1,
148				   &mapWidth);
149#endif
150
151      keySyms.minKeyCode = min_keycode;
152      keySyms.maxKeyCode = max_keycode;
153      keySyms.mapWidth = mapWidth;
154      keySyms.map = keymap;
155
156      if (XkbQueryExtension(xnestDisplay, &op, &event, &error, &major, &minor) == 0) {
157          ErrorF("Unable to initialize XKEYBOARD extension.\n");
158	  goto XkbError;
159      }
160      xkb = XkbGetKeyboard(xnestDisplay, XkbGBN_AllComponentsMask, XkbUseCoreKbd);
161      if (xkb == NULL || xkb->geom == NULL) {
162	  ErrorF("Couldn't get keyboard.\n");
163          goto XkbError;
164      }
165      XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb);
166
167      InitKeyboardDeviceStruct(pDev, NULL,
168			       xnestBell, xnestChangeKeyboardControl);
169      XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls);
170      XkbFreeKeyboard(xkb, 0, False);
171      free(keymap);
172      break;
173    case DEVICE_ON:
174      xnestEventMask |= XNEST_KEYBOARD_EVENT_MASK;
175      for (i = 0; i < xnestNumScreens; i++)
176	XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
177      break;
178    case DEVICE_OFF:
179      xnestEventMask &= ~XNEST_KEYBOARD_EVENT_MASK;
180      for (i = 0; i < xnestNumScreens; i++)
181	XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
182      break;
183    case DEVICE_CLOSE:
184      break;
185    }
186  return Success;
187
188XkbError:
189  XGetKeyboardControl(xnestDisplay, &values);
190  memmove((char *)defaultKeyboardControl.autoRepeats,
191          (char *)values.auto_repeats,
192          sizeof(values.auto_repeats));
193
194  InitKeyboardDeviceStruct(pDev, NULL,
195                           xnestBell, xnestChangeKeyboardControl);
196  free(keymap);
197  return Success;
198}
199
200Bool
201LegalModifier(unsigned int key, DeviceIntPtr pDev)
202{
203  return TRUE;
204}
205
206void
207xnestUpdateModifierState(unsigned int state)
208{
209  DeviceIntPtr pDev = xnestKeyboardDevice;
210  KeyClassPtr keyc = pDev->key;
211  int i;
212  CARD8 mask;
213  int xkb_state;
214
215  if (!pDev)
216      return;
217
218  xkb_state = XkbStateFieldFromRec(&pDev->key->xkbInfo->state);
219  state = state & 0xff;
220
221  if (xkb_state == state)
222    return;
223
224  for (i = 0, mask = 1; i < 8; i++, mask <<= 1) {
225    int key;
226
227    /* Modifier is down, but shouldn't be
228     */
229    if ((xkb_state & mask) && !(state & mask)) {
230      int count = keyc->modifierKeyCount[i];
231
232      for (key = 0; key < MAP_LENGTH; key++)
233	if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
234	  if (key_is_down(pDev, key, KEY_PROCESSED))
235	    xnestQueueKeyEvent(KeyRelease, key);
236
237	  if (--count == 0)
238	    break;
239	}
240    }
241
242    /* Modifier shoud be down, but isn't
243     */
244    if (!(xkb_state & mask) && (state & mask))
245      for (key = 0; key < MAP_LENGTH; key++)
246	if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
247	  xnestQueueKeyEvent(KeyPress, key);
248	  break;
249	}
250  }
251}
252