Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xnest / Keyboard.c
1 /*
2
3 Copyright 1993 by Davor Matic
4
5 Permission to use, copy, modify, distribute, and sell this software
6 and its documentation for any purpose is hereby granted without fee,
7 provided that the above copyright notice appear in all copies and that
8 both that copyright notice and this permission notice appear in
9 supporting documentation. Davor Matic makes no representations about
10 the suitability of this software for any purpose. It is provided "as
11 is" 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
40 extern Bool
41 XkbQueryExtension(Display * /* dpy */ ,
42 int * /* opcodeReturn */ ,
43 int * /* eventBaseReturn */ ,
44 int * /* errorBaseReturn */ ,
45 int * /* majorRtrn */ ,
46 int * /* minorRtrn */
47 );
48
49 extern XkbDescPtr XkbGetKeyboard(Display * /* dpy */ ,
50 unsigned int /* which */ ,
51 unsigned int /* deviceSpec */
52 );
53
54 extern Status XkbGetControls(Display * /* dpy */ ,
55 unsigned long /* which */ ,
56 XkbDescPtr /* desc */
57 );
58
59 DeviceIntPtr xnestKeyboardDevice = NULL;
60
61 void
62 xnestBell(int volume, DeviceIntPtr pDev, pointer ctrl, int cls)
63 {
64 XBell(xnestDisplay, volume);
65 }
66
67 void
68 DDXRingBell(int volume, int pitch, int duration)
69 {
70 XBell(xnestDisplay, volume);
71 }
72
73 void
74 xnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl * ctrl)
75 {
76 #if 0
77 unsigned long value_mask;
78 XKeyboardControl values;
79 int i;
80
81 value_mask = KBKeyClickPercent |
82 KBBellPercent | KBBellPitch | KBBellDuration | KBAutoRepeatMode;
83
84 values.key_click_percent = ctrl->click;
85 values.bell_percent = ctrl->bell;
86 values.bell_pitch = ctrl->bell_pitch;
87 values.bell_duration = ctrl->bell_duration;
88 values.auto_repeat_mode = ctrl->autoRepeat ?
89 AutoRepeatModeOn : AutoRepeatModeOff;
90
91 XChangeKeyboardControl(xnestDisplay, value_mask, &values);
92
93 /*
94 value_mask = KBKey | KBAutoRepeatMode;
95 At this point, we need to walk through the vector and compare it
96 to the current server vector. If there are differences, report them.
97 */
98
99 value_mask = KBLed | KBLedMode;
100 for (i = 1; i <= 32; i++) {
101 values.led = i;
102 values.led_mode =
103 (ctrl->leds & (1 << (i - 1))) ? LedModeOn : LedModeOff;
104 XChangeKeyboardControl(xnestDisplay, value_mask, &values);
105 }
106 #endif
107 }
108
109 int
110 xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
111 {
112 XModifierKeymap *modifier_keymap;
113 KeySym *keymap;
114 int mapWidth;
115 int min_keycode, max_keycode;
116 KeySymsRec keySyms;
117 CARD8 modmap[MAP_LENGTH];
118 int i, j;
119 XKeyboardState values;
120 XkbDescPtr xkb;
121 int op, event, error, major, minor;
122
123 switch (onoff) {
124 case DEVICE_INIT:
125 XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode);
126 #ifdef _XSERVER64
127 {
128 KeySym64 *keymap64;
129 int len;
130
131 keymap64 = XGetKeyboardMapping(xnestDisplay,
132 min_keycode,
133 max_keycode - min_keycode + 1,
134 &mapWidth);
135 len = (max_keycode - min_keycode + 1) * mapWidth;
136 keymap = (KeySym *) malloc(len * sizeof(KeySym));
137 for (i = 0; i < len; ++i)
138 keymap[i] = keymap64[i];
139 XFree(keymap64);
140 }
141 #else
142 keymap = XGetKeyboardMapping(xnestDisplay,
143 min_keycode,
144 max_keycode - min_keycode + 1, &mapWidth);
145 #endif
146
147 memset(modmap, 0, sizeof(modmap));
148 modifier_keymap = XGetModifierMapping(xnestDisplay);
149 for (j = 0; j < 8; j++)
150 for (i = 0; i < modifier_keymap->max_keypermod; i++) {
151 CARD8 keycode;
152
153 if ((keycode =
154 modifier_keymap->modifiermap[j *
155 modifier_keymap->
156 max_keypermod + i]))
157 modmap[keycode] |= 1 << j;
158 }
159 XFreeModifiermap(modifier_keymap);
160
161 keySyms.minKeyCode = min_keycode;
162 keySyms.maxKeyCode = max_keycode;
163 keySyms.mapWidth = mapWidth;
164 keySyms.map = keymap;
165
166 if (XkbQueryExtension(xnestDisplay, &op, &event, &error, &major, &minor)
167 == 0) {
168 ErrorF("Unable to initialize XKEYBOARD extension.\n");
169 goto XkbError;
170 }
171 xkb =
172 XkbGetKeyboard(xnestDisplay, XkbGBN_AllComponentsMask,
173 XkbUseCoreKbd);
174 if (xkb == NULL || xkb->geom == NULL) {
175 ErrorF("Couldn't get keyboard.\n");
176 goto XkbError;
177 }
178 XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb);
179
180 InitKeyboardDeviceStruct(pDev, NULL,
181 xnestBell, xnestChangeKeyboardControl);
182
183 XkbApplyMappingChange(pDev, &keySyms, keySyms.minKeyCode,
184 keySyms.maxKeyCode - keySyms.minKeyCode + 1,
185 modmap, serverClient);
186
187 XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls);
188 XkbFreeKeyboard(xkb, 0, False);
189 free(keymap);
190 break;
191 case DEVICE_ON:
192 xnestEventMask |= XNEST_KEYBOARD_EVENT_MASK;
193 for (i = 0; i < xnestNumScreens; i++)
194 XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
195 break;
196 case DEVICE_OFF:
197 xnestEventMask &= ~XNEST_KEYBOARD_EVENT_MASK;
198 for (i = 0; i < xnestNumScreens; i++)
199 XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
200 break;
201 case DEVICE_CLOSE:
202 break;
203 }
204 return Success;
205
206 XkbError:
207 XGetKeyboardControl(xnestDisplay, &values);
208 memmove((char *) defaultKeyboardControl.autoRepeats,
209 (char *) values.auto_repeats, sizeof(values.auto_repeats));
210
211 InitKeyboardDeviceStruct(pDev, NULL, xnestBell, xnestChangeKeyboardControl);
212 free(keymap);
213 return Success;
214 }
215
216 Bool
217 LegalModifier(unsigned int key, DeviceIntPtr pDev)
218 {
219 return TRUE;
220 }
221
222 void
223 xnestUpdateModifierState(unsigned int state)
224 {
225 DeviceIntPtr pDev = xnestKeyboardDevice;
226 KeyClassPtr keyc = pDev->key;
227 int i;
228 CARD8 mask;
229 int xkb_state;
230
231 if (!pDev)
232 return;
233
234 xkb_state = XkbStateFieldFromRec(&pDev->key->xkbInfo->state);
235 state = state & 0xff;
236
237 if (xkb_state == state)
238 return;
239
240 for (i = 0, mask = 1; i < 8; i++, mask <<= 1) {
241 int key;
242
243 /* Modifier is down, but shouldn't be
244 */
245 if ((xkb_state & mask) && !(state & mask)) {
246 int count = keyc->modifierKeyCount[i];
247
248 for (key = 0; key < MAP_LENGTH; key++)
249 if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
250 if (key_is_down(pDev, key, KEY_PROCESSED))
251 xnestQueueKeyEvent(KeyRelease, key);
252
253 if (--count == 0)
254 break;
255 }
256 }
257
258 /* Modifier shoud be down, but isn't
259 */
260 if (!(xkb_state & mask) && (state & mask))
261 for (key = 0; key < MAP_LENGTH; key++)
262 if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
263 xnestQueueKeyEvent(KeyPress, key);
264 break;
265 }
266 }
267 }