1706f2543Smrg/*
2706f2543Smrg
3706f2543SmrgCopyright 1993 by Davor Matic
4706f2543Smrg
5706f2543SmrgPermission to use, copy, modify, distribute, and sell this software
6706f2543Smrgand its documentation for any purpose is hereby granted without fee,
7706f2543Smrgprovided that the above copyright notice appear in all copies and that
8706f2543Smrgboth that copyright notice and this permission notice appear in
9706f2543Smrgsupporting documentation.  Davor Matic makes no representations about
10706f2543Smrgthe suitability of this software for any purpose.  It is provided "as
11706f2543Smrgis" without express or implied warranty.
12706f2543Smrg
13706f2543Smrg*/
14706f2543Smrg
15706f2543Smrg#ifdef HAVE_XNEST_CONFIG_H
16706f2543Smrg#include <xnest-config.h>
17706f2543Smrg#endif
18706f2543Smrg
19706f2543Smrg#include <X11/X.h>
20706f2543Smrg#include <X11/Xproto.h>
21706f2543Smrg#include <X11/keysym.h>
22706f2543Smrg#include "screenint.h"
23706f2543Smrg#include "inputstr.h"
24706f2543Smrg#include "misc.h"
25706f2543Smrg#include "scrnintstr.h"
26706f2543Smrg#include "servermd.h"
27706f2543Smrg
28706f2543Smrg#include "Xnest.h"
29706f2543Smrg
30706f2543Smrg#include "Display.h"
31706f2543Smrg#include "Screen.h"
32706f2543Smrg#include "Keyboard.h"
33706f2543Smrg#include "Args.h"
34706f2543Smrg#include "Events.h"
35706f2543Smrg
36706f2543Smrg#include <X11/extensions/XKB.h>
37706f2543Smrg#include "xkbsrv.h"
38706f2543Smrg#include <X11/extensions/XKBconfig.h>
39706f2543Smrg
40706f2543Smrgextern Bool
41706f2543SmrgXkbQueryExtension(
42706f2543Smrg	Display *		/* dpy */,
43706f2543Smrg	int *			/* opcodeReturn */,
44706f2543Smrg	int *			/* eventBaseReturn */,
45706f2543Smrg	int *			/* errorBaseReturn */,
46706f2543Smrg	int *			/* majorRtrn */,
47706f2543Smrg	int *			/* minorRtrn */
48706f2543Smrg);
49706f2543Smrg
50706f2543Smrgextern	XkbDescPtr XkbGetKeyboard(
51706f2543Smrg	Display *		/* dpy */,
52706f2543Smrg	unsigned int		/* which */,
53706f2543Smrg	unsigned int		/* deviceSpec */
54706f2543Smrg);
55706f2543Smrg
56706f2543Smrgextern	Status	XkbGetControls(
57706f2543Smrg	Display *		/* dpy */,
58706f2543Smrg	unsigned long		/* which */,
59706f2543Smrg	XkbDescPtr		/* desc */
60706f2543Smrg);
61706f2543Smrg
62706f2543SmrgDeviceIntPtr xnestKeyboardDevice = NULL;
63706f2543Smrg
64706f2543Smrgvoid
65706f2543SmrgxnestBell(int volume, DeviceIntPtr pDev, pointer ctrl, int cls)
66706f2543Smrg{
67706f2543Smrg  XBell(xnestDisplay, volume);
68706f2543Smrg}
69706f2543Smrg
70706f2543Smrgvoid
71706f2543SmrgDDXRingBell(int volume, int pitch, int duration)
72706f2543Smrg{
73706f2543Smrg  XBell(xnestDisplay, volume);
74706f2543Smrg}
75706f2543Smrg
76706f2543Smrgvoid
77706f2543SmrgxnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl *ctrl)
78706f2543Smrg{
79706f2543Smrg#if 0
80706f2543Smrg  unsigned long value_mask;
81706f2543Smrg  XKeyboardControl values;
82706f2543Smrg  int i;
83706f2543Smrg
84706f2543Smrg  value_mask = KBKeyClickPercent |
85706f2543Smrg               KBBellPercent |
86706f2543Smrg	       KBBellPitch |
87706f2543Smrg	       KBBellDuration |
88706f2543Smrg	       KBAutoRepeatMode;
89706f2543Smrg
90706f2543Smrg  values.key_click_percent = ctrl->click;
91706f2543Smrg  values.bell_percent = ctrl->bell;
92706f2543Smrg  values.bell_pitch = ctrl->bell_pitch;
93706f2543Smrg  values.bell_duration = ctrl->bell_duration;
94706f2543Smrg  values.auto_repeat_mode = ctrl->autoRepeat ?
95706f2543Smrg                             AutoRepeatModeOn : AutoRepeatModeOff;
96706f2543Smrg
97706f2543Smrg  XChangeKeyboardControl(xnestDisplay, value_mask, &values);
98706f2543Smrg
99706f2543Smrg  /*
100706f2543Smrg  value_mask = KBKey | KBAutoRepeatMode;
101706f2543Smrg  At this point, we need to walk through the vector and compare it
102706f2543Smrg  to the current server vector.  If there are differences, report them.
103706f2543Smrg  */
104706f2543Smrg
105706f2543Smrg  value_mask = KBLed | KBLedMode;
106706f2543Smrg  for (i = 1; i <= 32; i++) {
107706f2543Smrg    values.led = i;
108706f2543Smrg    values.led_mode = (ctrl->leds & (1 << (i - 1))) ? LedModeOn : LedModeOff;
109706f2543Smrg    XChangeKeyboardControl(xnestDisplay, value_mask, &values);
110706f2543Smrg  }
111706f2543Smrg#endif
112706f2543Smrg}
113706f2543Smrg
114706f2543Smrgint
115706f2543SmrgxnestKeyboardProc(DeviceIntPtr pDev, int onoff)
116706f2543Smrg{
117706f2543Smrg  XModifierKeymap *modifier_keymap;
118706f2543Smrg  KeySym *keymap;
119706f2543Smrg  int mapWidth;
120706f2543Smrg  int min_keycode, max_keycode;
121706f2543Smrg  KeySymsRec keySyms;
122706f2543Smrg  CARD8 modmap[MAP_LENGTH];
123706f2543Smrg  int i, j;
124706f2543Smrg  XKeyboardState values;
125706f2543Smrg  XkbDescPtr xkb;
126706f2543Smrg  int op, event, error, major, minor;
127706f2543Smrg
128706f2543Smrg  switch (onoff)
129706f2543Smrg    {
130706f2543Smrg    case DEVICE_INIT:
131706f2543Smrg      XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode);
132706f2543Smrg#ifdef _XSERVER64
133706f2543Smrg      {
134706f2543Smrg	KeySym64 *keymap64;
135706f2543Smrg	int len;
136706f2543Smrg	keymap64 = XGetKeyboardMapping(xnestDisplay,
137706f2543Smrg				     min_keycode,
138706f2543Smrg				     max_keycode - min_keycode + 1,
139706f2543Smrg				     &mapWidth);
140706f2543Smrg	len = (max_keycode - min_keycode + 1) * mapWidth;
141706f2543Smrg	keymap = (KeySym *)malloc(len * sizeof(KeySym));
142706f2543Smrg	for(i = 0; i < len; ++i)
143706f2543Smrg	  keymap[i] = keymap64[i];
144706f2543Smrg	XFree(keymap64);
145706f2543Smrg      }
146706f2543Smrg#else
147706f2543Smrg      keymap = XGetKeyboardMapping(xnestDisplay,
148706f2543Smrg				   min_keycode,
149706f2543Smrg				   max_keycode - min_keycode + 1,
150706f2543Smrg				   &mapWidth);
151706f2543Smrg#endif
152706f2543Smrg
153706f2543Smrg      memset(modmap, 0, sizeof(modmap));
154706f2543Smrg      modifier_keymap = XGetModifierMapping(xnestDisplay);
155706f2543Smrg      for (j = 0; j < 8; j++)
156706f2543Smrg            for(i = 0; i < modifier_keymap->max_keypermod; i++) {
157706f2543Smrg                  CARD8 keycode;
158706f2543Smrg                  if ((keycode = modifier_keymap->modifiermap[j * modifier_keymap->max_keypermod + i]))
159706f2543Smrg                      modmap[keycode] |= 1<<j;
160706f2543Smrg      }
161706f2543Smrg      XFreeModifiermap(modifier_keymap);
162706f2543Smrg
163706f2543Smrg      keySyms.minKeyCode = min_keycode;
164706f2543Smrg      keySyms.maxKeyCode = max_keycode;
165706f2543Smrg      keySyms.mapWidth = mapWidth;
166706f2543Smrg      keySyms.map = keymap;
167706f2543Smrg
168706f2543Smrg      if (XkbQueryExtension(xnestDisplay, &op, &event, &error, &major, &minor) == 0) {
169706f2543Smrg          ErrorF("Unable to initialize XKEYBOARD extension.\n");
170706f2543Smrg	  goto XkbError;
171706f2543Smrg      }
172706f2543Smrg      xkb = XkbGetKeyboard(xnestDisplay, XkbGBN_AllComponentsMask, XkbUseCoreKbd);
173706f2543Smrg      if (xkb == NULL || xkb->geom == NULL) {
174706f2543Smrg	  ErrorF("Couldn't get keyboard.\n");
175706f2543Smrg          goto XkbError;
176706f2543Smrg      }
177706f2543Smrg      XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb);
178706f2543Smrg
179706f2543Smrg      InitKeyboardDeviceStruct(pDev, NULL,
180706f2543Smrg                               xnestBell, xnestChangeKeyboardControl);
181706f2543Smrg
182706f2543Smrg      XkbApplyMappingChange(pDev, &keySyms, keySyms.minKeyCode,
183706f2543Smrg                            keySyms.maxKeyCode - keySyms.minKeyCode + 1,
184706f2543Smrg                            modmap, serverClient);
185706f2543Smrg
186706f2543Smrg      XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls);
187706f2543Smrg      XkbFreeKeyboard(xkb, 0, False);
188706f2543Smrg      free(keymap);
189706f2543Smrg      break;
190706f2543Smrg    case DEVICE_ON:
191706f2543Smrg      xnestEventMask |= XNEST_KEYBOARD_EVENT_MASK;
192706f2543Smrg      for (i = 0; i < xnestNumScreens; i++)
193706f2543Smrg	XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
194706f2543Smrg      break;
195706f2543Smrg    case DEVICE_OFF:
196706f2543Smrg      xnestEventMask &= ~XNEST_KEYBOARD_EVENT_MASK;
197706f2543Smrg      for (i = 0; i < xnestNumScreens; i++)
198706f2543Smrg	XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
199706f2543Smrg      break;
200706f2543Smrg    case DEVICE_CLOSE:
201706f2543Smrg      break;
202706f2543Smrg    }
203706f2543Smrg  return Success;
204706f2543Smrg
205706f2543SmrgXkbError:
206706f2543Smrg  XGetKeyboardControl(xnestDisplay, &values);
207706f2543Smrg  memmove((char *)defaultKeyboardControl.autoRepeats,
208706f2543Smrg          (char *)values.auto_repeats,
209706f2543Smrg          sizeof(values.auto_repeats));
210706f2543Smrg
211706f2543Smrg  InitKeyboardDeviceStruct(pDev, NULL,
212706f2543Smrg                           xnestBell, xnestChangeKeyboardControl);
213706f2543Smrg  free(keymap);
214706f2543Smrg  return Success;
215706f2543Smrg}
216706f2543Smrg
217706f2543SmrgBool
218706f2543SmrgLegalModifier(unsigned int key, DeviceIntPtr pDev)
219706f2543Smrg{
220706f2543Smrg  return TRUE;
221706f2543Smrg}
222706f2543Smrg
223706f2543Smrgvoid
224706f2543SmrgxnestUpdateModifierState(unsigned int state)
225706f2543Smrg{
226706f2543Smrg  DeviceIntPtr pDev = xnestKeyboardDevice;
227706f2543Smrg  KeyClassPtr keyc = pDev->key;
228706f2543Smrg  int i;
229706f2543Smrg  CARD8 mask;
230706f2543Smrg  int xkb_state;
231706f2543Smrg
232706f2543Smrg  if (!pDev)
233706f2543Smrg      return;
234706f2543Smrg
235706f2543Smrg  xkb_state = XkbStateFieldFromRec(&pDev->key->xkbInfo->state);
236706f2543Smrg  state = state & 0xff;
237706f2543Smrg
238706f2543Smrg  if (xkb_state == state)
239706f2543Smrg    return;
240706f2543Smrg
241706f2543Smrg  for (i = 0, mask = 1; i < 8; i++, mask <<= 1) {
242706f2543Smrg    int key;
243706f2543Smrg
244706f2543Smrg    /* Modifier is down, but shouldn't be
245706f2543Smrg     */
246706f2543Smrg    if ((xkb_state & mask) && !(state & mask)) {
247706f2543Smrg      int count = keyc->modifierKeyCount[i];
248706f2543Smrg
249706f2543Smrg      for (key = 0; key < MAP_LENGTH; key++)
250706f2543Smrg	if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
251706f2543Smrg	  if (key_is_down(pDev, key, KEY_PROCESSED))
252706f2543Smrg	    xnestQueueKeyEvent(KeyRelease, key);
253706f2543Smrg
254706f2543Smrg	  if (--count == 0)
255706f2543Smrg	    break;
256706f2543Smrg	}
257706f2543Smrg    }
258706f2543Smrg
259706f2543Smrg    /* Modifier shoud be down, but isn't
260706f2543Smrg     */
261706f2543Smrg    if (!(xkb_state & mask) && (state & mask))
262706f2543Smrg      for (key = 0; key < MAP_LENGTH; key++)
263706f2543Smrg	if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
264706f2543Smrg	  xnestQueueKeyEvent(KeyPress, key);
265706f2543Smrg	  break;
266706f2543Smrg	}
267706f2543Smrg  }
268706f2543Smrg}
269