Keyboard.c revision 6747b715
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{
11705b261ecSmrg  KeySym *keymap;
11805b261ecSmrg  int mapWidth;
11905b261ecSmrg  int min_keycode, max_keycode;
12005b261ecSmrg  KeySymsRec keySyms;
1216747b715Smrg  int i;
12205b261ecSmrg  XKeyboardState values;
1236747b715Smrg  XkbDescPtr xkb;
1246747b715Smrg  int op, event, error, major, minor;
12505b261ecSmrg
12605b261ecSmrg  switch (onoff)
12705b261ecSmrg    {
12805b261ecSmrg    case DEVICE_INIT:
12905b261ecSmrg      XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode);
13005b261ecSmrg#ifdef _XSERVER64
13105b261ecSmrg      {
13205b261ecSmrg	KeySym64 *keymap64;
13305b261ecSmrg	int i, len;
13405b261ecSmrg	keymap64 = XGetKeyboardMapping(xnestDisplay,
13505b261ecSmrg				     min_keycode,
13605b261ecSmrg				     max_keycode - min_keycode + 1,
13705b261ecSmrg				     &mapWidth);
13805b261ecSmrg	len = (max_keycode - min_keycode + 1) * mapWidth;
1396747b715Smrg	keymap = (KeySym *)malloc(len * sizeof(KeySym));
14005b261ecSmrg	for(i = 0; i < len; ++i)
14105b261ecSmrg	  keymap[i] = keymap64[i];
14205b261ecSmrg	XFree(keymap64);
14305b261ecSmrg      }
14405b261ecSmrg#else
14505b261ecSmrg      keymap = XGetKeyboardMapping(xnestDisplay,
14605b261ecSmrg				   min_keycode,
14705b261ecSmrg				   max_keycode - min_keycode + 1,
14805b261ecSmrg				   &mapWidth);
14905b261ecSmrg#endif
15005b261ecSmrg
15105b261ecSmrg      keySyms.minKeyCode = min_keycode;
15205b261ecSmrg      keySyms.maxKeyCode = max_keycode;
15305b261ecSmrg      keySyms.mapWidth = mapWidth;
15405b261ecSmrg      keySyms.map = keymap;
15505b261ecSmrg
1566747b715Smrg      if (XkbQueryExtension(xnestDisplay, &op, &event, &error, &major, &minor) == 0) {
1576747b715Smrg          ErrorF("Unable to initialize XKEYBOARD extension.\n");
15805b261ecSmrg	  goto XkbError;
1596747b715Smrg      }
1606747b715Smrg      xkb = XkbGetKeyboard(xnestDisplay, XkbGBN_AllComponentsMask, XkbUseCoreKbd);
1616747b715Smrg      if (xkb == NULL || xkb->geom == NULL) {
16205b261ecSmrg	  ErrorF("Couldn't get keyboard.\n");
1636747b715Smrg          goto XkbError;
16405b261ecSmrg      }
1656747b715Smrg      XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb);
1666747b715Smrg
1676747b715Smrg      InitKeyboardDeviceStruct(pDev, NULL,
1686747b715Smrg			       xnestBell, xnestChangeKeyboardControl);
1696747b715Smrg      XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls);
1706747b715Smrg      XkbFreeKeyboard(xkb, 0, False);
1716747b715Smrg      free(keymap);
17205b261ecSmrg      break;
17305b261ecSmrg    case DEVICE_ON:
17405b261ecSmrg      xnestEventMask |= XNEST_KEYBOARD_EVENT_MASK;
17505b261ecSmrg      for (i = 0; i < xnestNumScreens; i++)
17605b261ecSmrg	XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
17705b261ecSmrg      break;
17805b261ecSmrg    case DEVICE_OFF:
17905b261ecSmrg      xnestEventMask &= ~XNEST_KEYBOARD_EVENT_MASK;
18005b261ecSmrg      for (i = 0; i < xnestNumScreens; i++)
18105b261ecSmrg	XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
18205b261ecSmrg      break;
18305b261ecSmrg    case DEVICE_CLOSE:
18405b261ecSmrg      break;
18505b261ecSmrg    }
18605b261ecSmrg  return Success;
1876747b715Smrg
1886747b715SmrgXkbError:
1896747b715Smrg  XGetKeyboardControl(xnestDisplay, &values);
1906747b715Smrg  memmove((char *)defaultKeyboardControl.autoRepeats,
1916747b715Smrg          (char *)values.auto_repeats,
1926747b715Smrg          sizeof(values.auto_repeats));
1936747b715Smrg
1946747b715Smrg  InitKeyboardDeviceStruct(pDev, NULL,
1956747b715Smrg                           xnestBell, xnestChangeKeyboardControl);
1966747b715Smrg  free(keymap);
1976747b715Smrg  return Success;
19805b261ecSmrg}
19905b261ecSmrg
20005b261ecSmrgBool
20105b261ecSmrgLegalModifier(unsigned int key, DeviceIntPtr pDev)
20205b261ecSmrg{
20305b261ecSmrg  return TRUE;
20405b261ecSmrg}
20505b261ecSmrg
20605b261ecSmrgvoid
20705b261ecSmrgxnestUpdateModifierState(unsigned int state)
20805b261ecSmrg{
20905b261ecSmrg  DeviceIntPtr pDev = xnestKeyboardDevice;
21005b261ecSmrg  KeyClassPtr keyc = pDev->key;
21105b261ecSmrg  int i;
21205b261ecSmrg  CARD8 mask;
2136747b715Smrg  int xkb_state;
2146747b715Smrg
2156747b715Smrg  if (!pDev)
2166747b715Smrg      return;
21705b261ecSmrg
2186747b715Smrg  xkb_state = XkbStateFieldFromRec(&pDev->key->xkbInfo->state);
21905b261ecSmrg  state = state & 0xff;
22005b261ecSmrg
2216747b715Smrg  if (xkb_state == state)
22205b261ecSmrg    return;
22305b261ecSmrg
22405b261ecSmrg  for (i = 0, mask = 1; i < 8; i++, mask <<= 1) {
22505b261ecSmrg    int key;
22605b261ecSmrg
22705b261ecSmrg    /* Modifier is down, but shouldn't be
22805b261ecSmrg     */
2296747b715Smrg    if ((xkb_state & mask) && !(state & mask)) {
23005b261ecSmrg      int count = keyc->modifierKeyCount[i];
23105b261ecSmrg
23205b261ecSmrg      for (key = 0; key < MAP_LENGTH; key++)
2336747b715Smrg	if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
2346747b715Smrg	  if (key_is_down(pDev, key, KEY_PROCESSED))
23505b261ecSmrg	    xnestQueueKeyEvent(KeyRelease, key);
23605b261ecSmrg
23705b261ecSmrg	  if (--count == 0)
23805b261ecSmrg	    break;
23905b261ecSmrg	}
24005b261ecSmrg    }
24105b261ecSmrg
24205b261ecSmrg    /* Modifier shoud be down, but isn't
24305b261ecSmrg     */
2446747b715Smrg    if (!(xkb_state & mask) && (state & mask))
24505b261ecSmrg      for (key = 0; key < MAP_LENGTH; key++)
2466747b715Smrg	if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
24705b261ecSmrg	  xnestQueueKeyEvent(KeyPress, key);
24805b261ecSmrg	  break;
24905b261ecSmrg	}
25005b261ecSmrg  }
25105b261ecSmrg}
252