Keyboard.c revision 475c125c
105b261ecSmrg/*
205b261ecSmrg
305b261ecSmrgCopyright 1993 by Davor Matic
405b261ecSmrg
505b261ecSmrgPermission to use, copy, modify, distribute, and sell this software
605b261ecSmrgand its documentation for any purpose is hereby granted without fee,
705b261ecSmrgprovided that the above copyright notice appear in all copies and that
805b261ecSmrgboth that copyright notice and this permission notice appear in
905b261ecSmrgsupporting documentation.  Davor Matic makes no representations about
1005b261ecSmrgthe suitability of this software for any purpose.  It is provided "as
1105b261ecSmrgis" without express or implied warranty.
1205b261ecSmrg
1305b261ecSmrg*/
1405b261ecSmrg
1505b261ecSmrg#ifdef HAVE_XNEST_CONFIG_H
1605b261ecSmrg#include <xnest-config.h>
1705b261ecSmrg#endif
1805b261ecSmrg
1905b261ecSmrg#include <X11/X.h>
2005b261ecSmrg#include <X11/Xproto.h>
2105b261ecSmrg#include <X11/keysym.h>
2205b261ecSmrg#include "screenint.h"
2305b261ecSmrg#include "inputstr.h"
2405b261ecSmrg#include "misc.h"
2505b261ecSmrg#include "scrnintstr.h"
2605b261ecSmrg#include "servermd.h"
2705b261ecSmrg
2805b261ecSmrg#include "Xnest.h"
2905b261ecSmrg
3005b261ecSmrg#include "Display.h"
3105b261ecSmrg#include "Screen.h"
3205b261ecSmrg#include "Keyboard.h"
3305b261ecSmrg#include "Args.h"
3405b261ecSmrg#include "Events.h"
3505b261ecSmrg
3605b261ecSmrg#include <X11/extensions/XKB.h>
376747b715Smrg#include "xkbsrv.h"
3805b261ecSmrg#include <X11/extensions/XKBconfig.h>
3905b261ecSmrg
4005b261ecSmrgextern Bool
4105b261ecSmrgXkbQueryExtension(
4205b261ecSmrg	Display *		/* dpy */,
4305b261ecSmrg	int *			/* opcodeReturn */,
4405b261ecSmrg	int *			/* eventBaseReturn */,
4505b261ecSmrg	int *			/* errorBaseReturn */,
4605b261ecSmrg	int *			/* majorRtrn */,
4705b261ecSmrg	int *			/* minorRtrn */
4805b261ecSmrg);
4905b261ecSmrg
5005b261ecSmrgextern	XkbDescPtr XkbGetKeyboard(
5105b261ecSmrg	Display *		/* dpy */,
5205b261ecSmrg	unsigned int		/* which */,
5305b261ecSmrg	unsigned int		/* deviceSpec */
5405b261ecSmrg);
5505b261ecSmrg
5605b261ecSmrgextern	Status	XkbGetControls(
5705b261ecSmrg	Display *		/* dpy */,
5805b261ecSmrg	unsigned long		/* which */,
5905b261ecSmrg	XkbDescPtr		/* desc */
6005b261ecSmrg);
6105b261ecSmrg
6205b261ecSmrgDeviceIntPtr xnestKeyboardDevice = NULL;
6305b261ecSmrg
6405b261ecSmrgvoid
6505b261ecSmrgxnestBell(int volume, DeviceIntPtr pDev, pointer ctrl, int cls)
6605b261ecSmrg{
6705b261ecSmrg  XBell(xnestDisplay, volume);
6805b261ecSmrg}
6905b261ecSmrg
7005b261ecSmrgvoid
7105b261ecSmrgDDXRingBell(int volume, int pitch, int duration)
7205b261ecSmrg{
7305b261ecSmrg  XBell(xnestDisplay, volume);
7405b261ecSmrg}
7505b261ecSmrg
7605b261ecSmrgvoid
7705b261ecSmrgxnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl *ctrl)
7805b261ecSmrg{
7905b261ecSmrg#if 0
8005b261ecSmrg  unsigned long value_mask;
8105b261ecSmrg  XKeyboardControl values;
8205b261ecSmrg  int i;
8305b261ecSmrg
8405b261ecSmrg  value_mask = KBKeyClickPercent |
8505b261ecSmrg               KBBellPercent |
8605b261ecSmrg	       KBBellPitch |
8705b261ecSmrg	       KBBellDuration |
8805b261ecSmrg	       KBAutoRepeatMode;
8905b261ecSmrg
9005b261ecSmrg  values.key_click_percent = ctrl->click;
9105b261ecSmrg  values.bell_percent = ctrl->bell;
9205b261ecSmrg  values.bell_pitch = ctrl->bell_pitch;
9305b261ecSmrg  values.bell_duration = ctrl->bell_duration;
9405b261ecSmrg  values.auto_repeat_mode = ctrl->autoRepeat ?
9505b261ecSmrg                             AutoRepeatModeOn : AutoRepeatModeOff;
9605b261ecSmrg
9705b261ecSmrg  XChangeKeyboardControl(xnestDisplay, value_mask, &values);
9805b261ecSmrg
9905b261ecSmrg  /*
10005b261ecSmrg  value_mask = KBKey | KBAutoRepeatMode;
10105b261ecSmrg  At this point, we need to walk through the vector and compare it
10205b261ecSmrg  to the current server vector.  If there are differences, report them.
10305b261ecSmrg  */
10405b261ecSmrg
10505b261ecSmrg  value_mask = KBLed | KBLedMode;
10605b261ecSmrg  for (i = 1; i <= 32; i++) {
10705b261ecSmrg    values.led = i;
10805b261ecSmrg    values.led_mode = (ctrl->leds & (1 << (i - 1))) ? LedModeOn : LedModeOff;
10905b261ecSmrg    XChangeKeyboardControl(xnestDisplay, value_mask, &values);
11005b261ecSmrg  }
11105b261ecSmrg#endif
11205b261ecSmrg}
11305b261ecSmrg
11405b261ecSmrgint
11505b261ecSmrgxnestKeyboardProc(DeviceIntPtr pDev, int onoff)
11605b261ecSmrg{
117475c125cSmrg  XModifierKeymap *modifier_keymap;
11805b261ecSmrg  KeySym *keymap;
11905b261ecSmrg  int mapWidth;
12005b261ecSmrg  int min_keycode, max_keycode;
12105b261ecSmrg  KeySymsRec keySyms;
122475c125cSmrg  CARD8 modmap[MAP_LENGTH];
123475c125cSmrg  int i, j;
12405b261ecSmrg  XKeyboardState values;
1256747b715Smrg  XkbDescPtr xkb;
1266747b715Smrg  int op, event, error, major, minor;
12705b261ecSmrg
12805b261ecSmrg  switch (onoff)
12905b261ecSmrg    {
13005b261ecSmrg    case DEVICE_INIT:
13105b261ecSmrg      XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode);
13205b261ecSmrg#ifdef _XSERVER64
13305b261ecSmrg      {
13405b261ecSmrg	KeySym64 *keymap64;
135475c125cSmrg	int len;
13605b261ecSmrg	keymap64 = XGetKeyboardMapping(xnestDisplay,
13705b261ecSmrg				     min_keycode,
13805b261ecSmrg				     max_keycode - min_keycode + 1,
13905b261ecSmrg				     &mapWidth);
14005b261ecSmrg	len = (max_keycode - min_keycode + 1) * mapWidth;
1416747b715Smrg	keymap = (KeySym *)malloc(len * sizeof(KeySym));
14205b261ecSmrg	for(i = 0; i < len; ++i)
14305b261ecSmrg	  keymap[i] = keymap64[i];
14405b261ecSmrg	XFree(keymap64);
14505b261ecSmrg      }
14605b261ecSmrg#else
14705b261ecSmrg      keymap = XGetKeyboardMapping(xnestDisplay,
14805b261ecSmrg				   min_keycode,
14905b261ecSmrg				   max_keycode - min_keycode + 1,
15005b261ecSmrg				   &mapWidth);
15105b261ecSmrg#endif
152475c125cSmrg
153475c125cSmrg      memset(modmap, 0, sizeof(modmap));
154475c125cSmrg      modifier_keymap = XGetModifierMapping(xnestDisplay);
155475c125cSmrg      for (j = 0; j < 8; j++)
156475c125cSmrg            for(i = 0; i < modifier_keymap->max_keypermod; i++) {
157475c125cSmrg                  CARD8 keycode;
158475c125cSmrg                  if ((keycode = modifier_keymap->modifiermap[j * modifier_keymap->max_keypermod + i]))
159475c125cSmrg                      modmap[keycode] |= 1<<j;
160475c125cSmrg      }
161475c125cSmrg      XFreeModifiermap(modifier_keymap);
162475c125cSmrg
16305b261ecSmrg      keySyms.minKeyCode = min_keycode;
16405b261ecSmrg      keySyms.maxKeyCode = max_keycode;
16505b261ecSmrg      keySyms.mapWidth = mapWidth;
16605b261ecSmrg      keySyms.map = keymap;
16705b261ecSmrg
1686747b715Smrg      if (XkbQueryExtension(xnestDisplay, &op, &event, &error, &major, &minor) == 0) {
1696747b715Smrg          ErrorF("Unable to initialize XKEYBOARD extension.\n");
17005b261ecSmrg	  goto XkbError;
1716747b715Smrg      }
1726747b715Smrg      xkb = XkbGetKeyboard(xnestDisplay, XkbGBN_AllComponentsMask, XkbUseCoreKbd);
1736747b715Smrg      if (xkb == NULL || xkb->geom == NULL) {
17405b261ecSmrg	  ErrorF("Couldn't get keyboard.\n");
1756747b715Smrg          goto XkbError;
17605b261ecSmrg      }
1776747b715Smrg      XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb);
1786747b715Smrg
1796747b715Smrg      InitKeyboardDeviceStruct(pDev, NULL,
180475c125cSmrg                               xnestBell, xnestChangeKeyboardControl);
181475c125cSmrg
182475c125cSmrg      XkbApplyMappingChange(pDev, &keySyms, keySyms.minKeyCode,
183475c125cSmrg                            keySyms.maxKeyCode - keySyms.minKeyCode + 1,
184475c125cSmrg                            modmap, serverClient);
185475c125cSmrg
1866747b715Smrg      XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls);
1876747b715Smrg      XkbFreeKeyboard(xkb, 0, False);
1886747b715Smrg      free(keymap);
18905b261ecSmrg      break;
19005b261ecSmrg    case DEVICE_ON:
19105b261ecSmrg      xnestEventMask |= XNEST_KEYBOARD_EVENT_MASK;
19205b261ecSmrg      for (i = 0; i < xnestNumScreens; i++)
19305b261ecSmrg	XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
19405b261ecSmrg      break;
19505b261ecSmrg    case DEVICE_OFF:
19605b261ecSmrg      xnestEventMask &= ~XNEST_KEYBOARD_EVENT_MASK;
19705b261ecSmrg      for (i = 0; i < xnestNumScreens; i++)
19805b261ecSmrg	XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
19905b261ecSmrg      break;
20005b261ecSmrg    case DEVICE_CLOSE:
20105b261ecSmrg      break;
20205b261ecSmrg    }
20305b261ecSmrg  return Success;
2046747b715Smrg
2056747b715SmrgXkbError:
2066747b715Smrg  XGetKeyboardControl(xnestDisplay, &values);
2076747b715Smrg  memmove((char *)defaultKeyboardControl.autoRepeats,
2086747b715Smrg          (char *)values.auto_repeats,
2096747b715Smrg          sizeof(values.auto_repeats));
2106747b715Smrg
2116747b715Smrg  InitKeyboardDeviceStruct(pDev, NULL,
2126747b715Smrg                           xnestBell, xnestChangeKeyboardControl);
2136747b715Smrg  free(keymap);
2146747b715Smrg  return Success;
21505b261ecSmrg}
21605b261ecSmrg
21705b261ecSmrgBool
21805b261ecSmrgLegalModifier(unsigned int key, DeviceIntPtr pDev)
21905b261ecSmrg{
22005b261ecSmrg  return TRUE;
22105b261ecSmrg}
22205b261ecSmrg
22305b261ecSmrgvoid
22405b261ecSmrgxnestUpdateModifierState(unsigned int state)
22505b261ecSmrg{
22605b261ecSmrg  DeviceIntPtr pDev = xnestKeyboardDevice;
22705b261ecSmrg  KeyClassPtr keyc = pDev->key;
22805b261ecSmrg  int i;
22905b261ecSmrg  CARD8 mask;
2306747b715Smrg  int xkb_state;
2316747b715Smrg
2326747b715Smrg  if (!pDev)
2336747b715Smrg      return;
23405b261ecSmrg
2356747b715Smrg  xkb_state = XkbStateFieldFromRec(&pDev->key->xkbInfo->state);
23605b261ecSmrg  state = state & 0xff;
23705b261ecSmrg
2386747b715Smrg  if (xkb_state == state)
23905b261ecSmrg    return;
24005b261ecSmrg
24105b261ecSmrg  for (i = 0, mask = 1; i < 8; i++, mask <<= 1) {
24205b261ecSmrg    int key;
24305b261ecSmrg
24405b261ecSmrg    /* Modifier is down, but shouldn't be
24505b261ecSmrg     */
2466747b715Smrg    if ((xkb_state & mask) && !(state & mask)) {
24705b261ecSmrg      int count = keyc->modifierKeyCount[i];
24805b261ecSmrg
24905b261ecSmrg      for (key = 0; key < MAP_LENGTH; key++)
2506747b715Smrg	if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
2516747b715Smrg	  if (key_is_down(pDev, key, KEY_PROCESSED))
25205b261ecSmrg	    xnestQueueKeyEvent(KeyRelease, key);
25305b261ecSmrg
25405b261ecSmrg	  if (--count == 0)
25505b261ecSmrg	    break;
25605b261ecSmrg	}
25705b261ecSmrg    }
25805b261ecSmrg
25905b261ecSmrg    /* Modifier shoud be down, but isn't
26005b261ecSmrg     */
2616747b715Smrg    if (!(xkb_state & mask) && (state & mask))
26205b261ecSmrg      for (key = 0; key < MAP_LENGTH; key++)
2636747b715Smrg	if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
26405b261ecSmrg	  xnestQueueKeyEvent(KeyPress, key);
26505b261ecSmrg	  break;
26605b261ecSmrg	}
26705b261ecSmrg  }
26805b261ecSmrg}
269