Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xnest / Keyboard.c
CommitLineData
a09e091a
JB
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
41 XkbQueryExtension(Display * /* dpy */ ,
42 int * /* opcodeReturn */ ,
43 int * /* eventBaseReturn */ ,
44 int * /* errorBaseReturn */ ,
45 int * /* majorRtrn */ ,
46 int * /* minorRtrn */
47 );
48
49extern XkbDescPtr XkbGetKeyboard(Display * /* dpy */ ,
50 unsigned int /* which */ ,
51 unsigned int /* deviceSpec */
52 );
53
54extern Status XkbGetControls(Display * /* dpy */ ,
55 unsigned long /* which */ ,
56 XkbDescPtr /* desc */
57 );
58
59DeviceIntPtr xnestKeyboardDevice = NULL;
60
61void
62xnestBell(int volume, DeviceIntPtr pDev, pointer ctrl, int cls)
63{
64 XBell(xnestDisplay, volume);
65}
66
67void
68DDXRingBell(int volume, int pitch, int duration)
69{
70 XBell(xnestDisplay, volume);
71}
72
73void
74xnestChangeKeyboardControl(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
109int
110xnestKeyboardProc(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
216Bool
217LegalModifier(unsigned int key, DeviceIntPtr pDev)
218{
219 return TRUE;
220}
221
222void
223xnestUpdateModifierState(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}