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