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