Files
xf86-input-evdev/src/evdev_key.c
Daniel Stone a9e87f29cc Key: Force maximum keycode to be 255
Even though we don't have keycodes for anything above 127, make sure our
map always covers up to 255.  This ensures that the keycode range never
changes.
2007-03-21 12:19:48 +02:00

592 lines
19 KiB
C

/*
* Copyright © 2006 Zephaniah E. Hull
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Soft-
* ware"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, provided that the above copyright
* notice(s) and this permission notice appear in all copies of the Soft-
* ware and that both the above copyright notice(s) and this permission
* notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
* ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
* RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
* THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
* QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR-
* MANCE OF THIS SOFTWARE.
*
* Except as contained in this notice, the name of a copyright holder shall
* not be used in advertising or otherwise to promote the sale, use or
* other dealings in this Software without prior written authorization of
* the copyright holder.
*
* Author: Zephaniah E. Hull (warp@aehallh.com)
*/
/*
* Copyright © 2004 Red Hat, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of Red Hat
* not be used in advertising or publicity pertaining to distribution
* of the software without specific, written prior permission. Red
* Hat makes no representations about the suitability of this software
* for any purpose. It is provided "as is" without express or implied
* warranty.
*
* RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: Kristian Høgsberg (krh@redhat.com)
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "evdev.h"
#include <X11/keysym.h>
#include <X11/XF86keysym.h>
#include <X11/extensions/XIproto.h>
#include <linux/input.h>
#include <misc.h>
#include <xf86.h>
#include <xf86str.h>
#include <xf86_OSproc.h>
#include <xf86Xinput.h>
#include <exevents.h>
#include <mipointer.h>
#include <xf86Module.h>
#include <X11/extensions/XKB.h>
#include <X11/extensions/XKBstr.h>
#include <X11/extensions/XKBsrv.h>
#define ArrayLength(a) (sizeof(a) / (sizeof((a)[0])))
#define MIN_KEYCODE 8
#define GLYPHS_PER_KEY 2
#define AltMask Mod1Mask
#define NumLockMask Mod2Mask
#define AltLangMask Mod3Mask
#define KanaMask Mod4Mask
#define ScrollLockMask Mod5Mask
#define CAPSFLAG 1
#define NUMFLAG 2
#define SCROLLFLAG 4
#define MODEFLAG 8
#define COMPOSEFLAG 16
/* FIXME: this map works with evdev keyboards, but all the xkb maps
* probably don't. The easiest is to remap the event keycodes. */
static KeySym map[] = {
/* 0x00 */ NoSymbol, NoSymbol,
/* 0x01 */ XK_Escape, NoSymbol,
/* 0x02 */ XK_1, XK_exclam,
/* 0x03 */ XK_2, XK_at,
/* 0x04 */ XK_3, XK_numbersign,
/* 0x05 */ XK_4, XK_dollar,
/* 0x06 */ XK_5, XK_percent,
/* 0x07 */ XK_6, XK_asciicircum,
/* 0x08 */ XK_7, XK_ampersand,
/* 0x09 */ XK_8, XK_asterisk,
/* 0x0a */ XK_9, XK_parenleft,
/* 0x0b */ XK_0, XK_parenright,
/* 0x0c */ XK_minus, XK_underscore,
/* 0x0d */ XK_equal, XK_plus,
/* 0x0e */ XK_BackSpace, NoSymbol,
/* 0x0f */ XK_Tab, XK_ISO_Left_Tab,
/* 0x10 */ XK_Q, NoSymbol,
/* 0x11 */ XK_W, NoSymbol,
/* 0x12 */ XK_E, NoSymbol,
/* 0x13 */ XK_R, NoSymbol,
/* 0x14 */ XK_T, NoSymbol,
/* 0x15 */ XK_Y, NoSymbol,
/* 0x16 */ XK_U, NoSymbol,
/* 0x17 */ XK_I, NoSymbol,
/* 0x18 */ XK_O, NoSymbol,
/* 0x19 */ XK_P, NoSymbol,
/* 0x1a */ XK_bracketleft, XK_braceleft,
/* 0x1b */ XK_bracketright,XK_braceright,
/* 0x1c */ XK_Return, NoSymbol,
/* 0x1d */ XK_Control_L, NoSymbol,
/* 0x1e */ XK_A, NoSymbol,
/* 0x1f */ XK_S, NoSymbol,
/* 0x20 */ XK_D, NoSymbol,
/* 0x21 */ XK_F, NoSymbol,
/* 0x22 */ XK_G, NoSymbol,
/* 0x23 */ XK_H, NoSymbol,
/* 0x24 */ XK_J, NoSymbol,
/* 0x25 */ XK_K, NoSymbol,
/* 0x26 */ XK_L, NoSymbol,
/* 0x27 */ XK_semicolon, XK_colon,
/* 0x28 */ XK_quoteright, XK_quotedbl,
/* 0x29 */ XK_quoteleft, XK_asciitilde,
/* 0x2a */ XK_Shift_L, NoSymbol,
/* 0x2b */ XK_backslash, XK_bar,
/* 0x2c */ XK_Z, NoSymbol,
/* 0x2d */ XK_X, NoSymbol,
/* 0x2e */ XK_C, NoSymbol,
/* 0x2f */ XK_V, NoSymbol,
/* 0x30 */ XK_B, NoSymbol,
/* 0x31 */ XK_N, NoSymbol,
/* 0x32 */ XK_M, NoSymbol,
/* 0x33 */ XK_comma, XK_less,
/* 0x34 */ XK_period, XK_greater,
/* 0x35 */ XK_slash, XK_question,
/* 0x36 */ XK_Shift_R, NoSymbol,
/* 0x37 */ XK_KP_Multiply, NoSymbol,
/* 0x38 */ XK_Alt_L, XK_Meta_L,
/* 0x39 */ XK_space, NoSymbol,
/* 0x3a */ XK_Caps_Lock, NoSymbol,
/* 0x3b */ XK_F1, NoSymbol,
/* 0x3c */ XK_F2, NoSymbol,
/* 0x3d */ XK_F3, NoSymbol,
/* 0x3e */ XK_F4, NoSymbol,
/* 0x3f */ XK_F5, NoSymbol,
/* 0x40 */ XK_F6, NoSymbol,
/* 0x41 */ XK_F7, NoSymbol,
/* 0x42 */ XK_F8, NoSymbol,
/* 0x43 */ XK_F9, NoSymbol,
/* 0x44 */ XK_F10, NoSymbol,
/* 0x45 */ XK_Num_Lock, NoSymbol,
/* 0x46 */ XK_Scroll_Lock, NoSymbol,
/* These KP keys should have the KP_7 keysyms in the numlock
* modifer... ? */
/* 0x47 */ XK_KP_Home, XK_KP_7,
/* 0x48 */ XK_KP_Up, XK_KP_8,
/* 0x49 */ XK_KP_Prior, XK_KP_9,
/* 0x4a */ XK_KP_Subtract, NoSymbol,
/* 0x4b */ XK_KP_Left, XK_KP_4,
/* 0x4c */ XK_KP_Begin, XK_KP_5,
/* 0x4d */ XK_KP_Right, XK_KP_6,
/* 0x4e */ XK_KP_Add, NoSymbol,
/* 0x4f */ XK_KP_End, XK_KP_1,
/* 0x50 */ XK_KP_Down, XK_KP_2,
/* 0x51 */ XK_KP_Next, XK_KP_3,
/* 0x52 */ XK_KP_Insert, XK_KP_0,
/* 0x53 */ XK_KP_Delete, XK_KP_Decimal,
/* 0x54 */ NoSymbol, NoSymbol,
/* 0x55 */ XK_F13, NoSymbol,
/* 0x56 */ XK_less, XK_greater,
/* 0x57 */ XK_F11, NoSymbol,
/* 0x58 */ XK_F12, NoSymbol,
/* 0x59 */ XK_F14, NoSymbol,
/* 0x5a */ XK_F15, NoSymbol,
/* 0x5b */ XK_F16, NoSymbol,
/* 0x5c */ XK_F17, NoSymbol,
/* 0x5d */ XK_F18, NoSymbol,
/* 0x5e */ XK_F19, NoSymbol,
/* 0x5f */ XK_F20, NoSymbol,
/* 0x60 */ XK_KP_Enter, NoSymbol,
/* 0x61 */ XK_Control_R, NoSymbol,
/* 0x62 */ XK_KP_Divide, NoSymbol,
/* 0x63 */ XK_Print, XK_Sys_Req,
/* 0x64 */ XK_Alt_R, XK_Meta_R,
/* 0x65 */ NoSymbol, NoSymbol, /* KEY_LINEFEED */
/* 0x66 */ XK_Home, NoSymbol,
/* 0x67 */ XK_Up, NoSymbol,
/* 0x68 */ XK_Prior, NoSymbol,
/* 0x69 */ XK_Left, NoSymbol,
/* 0x6a */ XK_Right, NoSymbol,
/* 0x6b */ XK_End, NoSymbol,
/* 0x6c */ XK_Down, NoSymbol,
/* 0x6d */ XK_Next, NoSymbol,
/* 0x6e */ XK_Insert, NoSymbol,
/* 0x6f */ XK_Delete, NoSymbol,
/* 0x6f */ NoSymbol, NoSymbol, /* KEY_MACRO */
/* 0x70 */ NoSymbol, NoSymbol,
/* 0x71 */ NoSymbol, NoSymbol,
/* 0x72 */ NoSymbol, NoSymbol,
/* 0x73 */ NoSymbol, NoSymbol,
/* 0x74 */ NoSymbol, NoSymbol,
/* 0x75 */ XK_KP_Equal, NoSymbol,
/* 0x76 */ NoSymbol, NoSymbol,
/* 0x77 */ NoSymbol, NoSymbol,
/* 0x78 */ XK_F21, NoSymbol,
/* 0x79 */ XK_F22, NoSymbol,
/* 0x7a */ XK_F23, NoSymbol,
/* 0x7b */ XK_F24, NoSymbol,
/* 0x7c */ XK_KP_Separator, NoSymbol,
/* 0x7d */ XK_Meta_L, NoSymbol,
/* 0x7e */ XK_Meta_R, NoSymbol,
/* 0x7f */ XK_Multi_key, NoSymbol,
/* 0x80 */ NoSymbol, NoSymbol,
/* 0x81 */ NoSymbol, NoSymbol,
/* 0x82 */ NoSymbol, NoSymbol,
/* 0x83 */ NoSymbol, NoSymbol,
/* 0x84 */ NoSymbol, NoSymbol,
/* 0x85 */ NoSymbol, NoSymbol,
/* 0x86 */ NoSymbol, NoSymbol,
/* 0x87 */ NoSymbol, NoSymbol,
/* 0x88 */ NoSymbol, NoSymbol,
/* 0x89 */ NoSymbol, NoSymbol,
/* 0x8a */ NoSymbol, NoSymbol,
/* 0x8b */ NoSymbol, NoSymbol,
/* 0x8c */ NoSymbol, NoSymbol,
/* 0x8d */ NoSymbol, NoSymbol,
/* 0x8e */ NoSymbol, NoSymbol,
/* 0x8f */ NoSymbol, NoSymbol,
/* 0x90 */ NoSymbol, NoSymbol,
/* 0x91 */ NoSymbol, NoSymbol,
/* 0x92 */ NoSymbol, NoSymbol,
/* 0x93 */ NoSymbol, NoSymbol,
/* 0x94 */ NoSymbol, NoSymbol,
/* 0x95 */ NoSymbol, NoSymbol,
/* 0x96 */ NoSymbol, NoSymbol,
/* 0x97 */ NoSymbol, NoSymbol,
/* 0x98 */ NoSymbol, NoSymbol,
/* 0x99 */ NoSymbol, NoSymbol,
/* 0x9a */ NoSymbol, NoSymbol,
/* 0x9b */ NoSymbol, NoSymbol,
/* 0x9c */ NoSymbol, NoSymbol,
/* 0x9d */ NoSymbol, NoSymbol,
/* 0x9e */ NoSymbol, NoSymbol,
/* 0x9f */ NoSymbol, NoSymbol,
/* 0xa0 */ NoSymbol, NoSymbol,
/* 0xa1 */ NoSymbol, NoSymbol,
/* 0xa2 */ NoSymbol, NoSymbol,
/* 0xa3 */ NoSymbol, NoSymbol,
/* 0xa4 */ NoSymbol, NoSymbol,
/* 0xa5 */ NoSymbol, NoSymbol,
/* 0xa6 */ NoSymbol, NoSymbol,
/* 0xa7 */ NoSymbol, NoSymbol,
/* 0xa8 */ NoSymbol, NoSymbol,
/* 0xa9 */ NoSymbol, NoSymbol,
/* 0xaa */ NoSymbol, NoSymbol,
/* 0xab */ NoSymbol, NoSymbol,
/* 0xac */ NoSymbol, NoSymbol,
/* 0xad */ NoSymbol, NoSymbol,
/* 0xae */ NoSymbol, NoSymbol,
/* 0xaf */ NoSymbol, NoSymbol,
/* 0xb0 */ NoSymbol, NoSymbol,
/* 0xb1 */ NoSymbol, NoSymbol,
/* 0xb2 */ NoSymbol, NoSymbol,
/* 0xb3 */ NoSymbol, NoSymbol,
/* 0xb4 */ NoSymbol, NoSymbol,
/* 0xb5 */ NoSymbol, NoSymbol,
/* 0xb6 */ NoSymbol, NoSymbol,
/* 0xb7 */ NoSymbol, NoSymbol,
/* 0xb8 */ NoSymbol, NoSymbol,
/* 0xb9 */ NoSymbol, NoSymbol,
/* 0xba */ NoSymbol, NoSymbol,
/* 0xbb */ NoSymbol, NoSymbol,
/* 0xbc */ NoSymbol, NoSymbol,
/* 0xbd */ NoSymbol, NoSymbol,
/* 0xbe */ NoSymbol, NoSymbol,
/* 0xbf */ NoSymbol, NoSymbol,
/* 0xc0 */ NoSymbol, NoSymbol,
/* 0xc1 */ NoSymbol, NoSymbol,
/* 0xc2 */ NoSymbol, NoSymbol,
/* 0xc3 */ NoSymbol, NoSymbol,
/* 0xc4 */ NoSymbol, NoSymbol,
/* 0xc5 */ NoSymbol, NoSymbol,
/* 0xc6 */ NoSymbol, NoSymbol,
/* 0xc7 */ NoSymbol, NoSymbol,
/* 0xc8 */ NoSymbol, NoSymbol,
/* 0xc9 */ NoSymbol, NoSymbol,
/* 0xca */ NoSymbol, NoSymbol,
/* 0xcb */ NoSymbol, NoSymbol,
/* 0xcc */ NoSymbol, NoSymbol,
/* 0xcd */ NoSymbol, NoSymbol,
/* 0xce */ NoSymbol, NoSymbol,
/* 0xcf */ NoSymbol, NoSymbol,
/* 0xd0 */ NoSymbol, NoSymbol,
/* 0xd1 */ NoSymbol, NoSymbol,
/* 0xd2 */ NoSymbol, NoSymbol,
/* 0xd3 */ NoSymbol, NoSymbol,
/* 0xd4 */ NoSymbol, NoSymbol,
/* 0xd5 */ NoSymbol, NoSymbol,
/* 0xd6 */ NoSymbol, NoSymbol,
/* 0xd7 */ NoSymbol, NoSymbol,
/* 0xd8 */ NoSymbol, NoSymbol,
/* 0xd9 */ NoSymbol, NoSymbol,
/* 0xda */ NoSymbol, NoSymbol,
/* 0xdb */ NoSymbol, NoSymbol,
/* 0xdc */ NoSymbol, NoSymbol,
/* 0xdd */ NoSymbol, NoSymbol,
/* 0xde */ NoSymbol, NoSymbol,
/* 0xdf */ NoSymbol, NoSymbol,
/* 0xe0 */ NoSymbol, NoSymbol,
/* 0xe1 */ NoSymbol, NoSymbol,
/* 0xe2 */ NoSymbol, NoSymbol,
/* 0xe3 */ NoSymbol, NoSymbol,
/* 0xe4 */ NoSymbol, NoSymbol,
/* 0xe5 */ NoSymbol, NoSymbol,
/* 0xe6 */ NoSymbol, NoSymbol,
/* 0xe7 */ NoSymbol, NoSymbol,
/* 0xe8 */ NoSymbol, NoSymbol,
/* 0xe9 */ NoSymbol, NoSymbol,
/* 0xea */ NoSymbol, NoSymbol,
/* 0xeb */ NoSymbol, NoSymbol,
/* 0xec */ NoSymbol, NoSymbol,
/* 0xed */ NoSymbol, NoSymbol,
/* 0xee */ NoSymbol, NoSymbol,
/* 0xef */ NoSymbol, NoSymbol,
/* 0xf0 */ NoSymbol, NoSymbol,
/* 0xf1 */ NoSymbol, NoSymbol,
/* 0xf2 */ NoSymbol, NoSymbol,
/* 0xf3 */ NoSymbol, NoSymbol,
/* 0xf4 */ NoSymbol, NoSymbol,
/* 0xf5 */ NoSymbol, NoSymbol,
/* 0xf6 */ NoSymbol, NoSymbol,
/* 0xf7 */ NoSymbol, NoSymbol,
/* 0xf8 */ NoSymbol, NoSymbol,
};
/*
* FIXME: We have no way of ringing the bell ourselves.
*
* And recent versions of X don't have the system call.
* Who cares.
*/
static void
EvdevKbdBell (int percent, DeviceIntPtr device, pointer arg, int unused)
{
#if 0
KeybdCtrl *ctrl = arg;
xf86OSRingBell(percent, ctrl->bell_pitch, ctrl->bell_duration);
#endif
}
static void
EvdevKbdCtrl(DeviceIntPtr device, KeybdCtrl *ctrl)
{
static struct { int xbit, code; } bits[] = {
{ CAPSFLAG, LED_CAPSL },
{ NUMFLAG, LED_NUML },
{ SCROLLFLAG, LED_SCROLLL },
{ MODEFLAG, LED_KANA },
{ COMPOSEFLAG, LED_COMPOSE }
};
InputInfoPtr pInfo;
struct input_event ev[ArrayLength(bits)];
int i;
pInfo = device->public.devicePrivate;
for (i = 0; i < ArrayLength(bits); i++) {
ev[i].type = EV_LED;
ev[i].code = bits[i].code;
ev[i].value = (ctrl->leds & bits[i].xbit) > 0;
}
write(pInfo->fd, ev, sizeof(ev));
if (device->key && device->key->xkbInfo && device->key->xkbInfo->desc
&& device->key->xkbInfo->desc->ctrls) {
XkbControlsRec *ctrls = device->key->xkbInfo->desc->ctrls;
ev[0].type = EV_REP;
ev[0].code = REP_DELAY;
ev[0].value = ctrls->repeat_delay;
ev[1].type = EV_REP;
ev[1].code = REP_PERIOD;
ev[1].value = ctrls->repeat_interval;
write(pInfo->fd, ev, sizeof(ev[0]) * 2);
}
}
int
EvdevKeyInit (DeviceIntPtr device)
{
InputInfoPtr pInfo = device->public.devicePrivate;
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
KeySymsRec keySyms;
CARD8 modMap[MAP_LENGTH];
KeySym sym;
int i, j;
static struct { KeySym keysym; CARD8 mask; } modifiers[] = {
{ XK_Shift_L, ShiftMask },
{ XK_Shift_R, ShiftMask },
{ XK_Control_L, ControlMask },
{ XK_Control_R, ControlMask },
{ XK_Caps_Lock, LockMask },
{ XK_Alt_L, AltMask },
{ XK_Alt_R, AltMask },
{ XK_Num_Lock, NumLockMask },
{ XK_Scroll_Lock, ScrollLockMask },
{ XK_Mode_switch, AltLangMask }
};
/* TODO:
* Ctrl-Alt-Backspace and other Ctrl-Alt-stuff should work
* XKB, let's try without the #ifdef nightmare
* Get keyboard repeat under control (right now caps lock repeats!)
*/
pInfo = device->public.devicePrivate;
/* Compute the modifier map */
memset(modMap, 0, sizeof modMap);
for (i = 0; i < ArrayLength(map) / GLYPHS_PER_KEY; i++) {
sym = map[i * GLYPHS_PER_KEY];
for (j = 0; j < ArrayLength(modifiers); j++) {
if (modifiers[j].keysym == sym)
modMap[i + MIN_KEYCODE] = modifiers[j].mask;
}
}
keySyms.map = map;
keySyms.mapWidth = GLYPHS_PER_KEY;
keySyms.minKeyCode = MIN_KEYCODE;
keySyms.maxKeyCode = MIN_KEYCODE + ArrayLength(map) / GLYPHS_PER_KEY - 1;
XkbSetRulesDflts (state->key->xkb_rules, state->key->xkb_model,
state->key->xkb_layout, state->key->xkb_variant,
state->key->xkb_options);
XkbInitKeyboardDeviceStruct (device, &state->key->xkbnames, &keySyms, modMap,
EvdevKbdBell, EvdevKbdCtrl);
return Success;
}
static void
SetXkbOption(InputInfoPtr pInfo, char *name, char *value, char **option)
{
char *s;
if ((s = xf86SetStrOption(pInfo->options, name, value))) {
if (!s[0]) {
xfree(s);
*option = NULL;
} else {
*option = s;
}
}
}
int
EvdevKeyNew (InputInfoPtr pInfo)
{
evdevDevicePtr pEvdev = pInfo->private;
evdevStatePtr state = &pEvdev->state;
int i, keys = 0;
for (i = 0; i <= KEY_UNKNOWN; i++)
if (test_bit (i, pEvdev->bits.key)) {
keys = 1;
break;
}
if (!keys)
for (i = KEY_OK; i <= KEY_MAX; i++)
if (test_bit (i, pEvdev->bits.key)) {
keys = 1;
break;
}
if (!keys)
return !Success;
state->key = Xcalloc (sizeof (evdevKeyRec));
pInfo->type_name = XI_KEYBOARD;
pInfo->flags |= XI86_KEYBOARD_CAPABLE | XI86_CONFIGURED;
SetXkbOption (pInfo, "XkbRules", __XKBDEFRULES__, &state->key->xkb_rules);
SetXkbOption (pInfo, "XkbModel", "evdev", &state->key->xkb_model);
SetXkbOption (pInfo, "XkbLayout", "us", &state->key->xkb_layout);
SetXkbOption (pInfo, "XkbVariant", NULL, &state->key->xkb_variant);
SetXkbOption (pInfo, "XkbOptions", NULL, &state->key->xkb_options);
/*
SetXkbOption (pInfo, "XkbKeycodes", NULL, &state->key->xkbnames.keycodes);
SetXkbOption (pInfo, "XkbTypes", NULL, &state->key->xkbnames.types);
SetXkbOption (pInfo, "XkbCompat", NULL, &state->key->xkbnames.compat);
SetXkbOption (pInfo, "XkbSymbols", NULL, &state->key->xkbnames.symbols);
SetXkbOption (pInfo, "XkbGeometry", NULL, &state->key->xkbnames.geometry);
*/
return Success;
}
int
EvdevKeyOn (DeviceIntPtr device)
{
return Success;
}
int
EvdevKeyOff (DeviceIntPtr device)
{
unsigned int i;
KeyClassRec *keyc = device->key;
KeySym *map = keyc->curKeySyms.map;
/*
* A bit of a hack, vaguely stolen from xf86-input-keyboard.
*
* Don't leave any keys in the down state if we are getting turned
* off, as they are likely to be released before we are turned back
* on.
* (For example, if the user switches VTs, or if we are unplugged.)
*/
for (i = keyc->curKeySyms.minKeyCode, map = keyc->curKeySyms.map;
i < keyc->curKeySyms.maxKeyCode;
i++, map += keyc->curKeySyms.mapWidth)
if ((keyc->down[i >> 3] & (1 << (i & 7))))
{
switch (*map) {
/* Don't release the lock keys */
case XK_Caps_Lock:
case XK_Shift_Lock:
case XK_Num_Lock:
case XK_Scroll_Lock:
case XK_Kana_Lock:
break;
default:
xf86PostKeyboardEvent(device, i, 0);
}
}
return Success;
}
void
EvdevKeyProcess (InputInfoPtr pInfo, struct input_event *ev)
{
int keycode = ev->code + MIN_KEYCODE;
/* filter repeat events for chording keys */
if (ev->value == 2) {
DeviceIntPtr device = pInfo->dev;
KeyClassRec *keyc = device->key;
KbdFeedbackClassRec *kbdfeed = device->kbdfeed;
int num = keycode >> 3;
int bit = 1 << (keycode & 7);
if (keyc->modifierMap[keycode] ||
!(kbdfeed->ctrl.autoRepeats[num] & bit))
return;
}
xf86PostKeyboardEvent(pInfo->dev, keycode, ev->value);
}