diff options
-rw-r--r-- | src/evdev.c | 113 |
1 files changed, 102 insertions, 11 deletions
diff --git a/src/evdev.c b/src/evdev.c index f641468..1771ee8 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -20,7 +20,9 @@ * 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) + * Authors: + * Kristian Høgsberg (krh@redhat.com) + * Adam Jackson (ajax@redhat.com) */ #ifdef HAVE_CONFIG_H @@ -41,6 +43,11 @@ #include <exevents.h> #include <mipointer.h> +#if defined(XKB) +/* XXX VERY WRONG. this is a client side header. */ +#include <X11/extensions/XKBstr.h> +#endif + #include <xf86Module.h> #include <errno.h> @@ -78,8 +85,61 @@ typedef struct { int kernel24; + int noXkb; + + /* XKB stuff has to be per-device rather than per-driver */ +#ifdef XKB + char *xkb_rules; + char *xkb_model; + char *xkb_layout; + char *xkb_variant; + char *xkb_options; + XkbComponentNamesRec xkbnames; +#endif } EvdevRec, *EvdevPtr; +typedef enum { + OPTION_XKB_DISABLE, + OPTION_XKB_RULES, + OPTION_XKB_MODEL, + OPTION_XKB_LAYOUT, + OPTION_XKB_VARIANT, + OPTION_XKB_OPTIONS +} EvdevOpts; + +static const OptionInfoRec EvdevOptions[] = { + { OPTION_XKB_DISABLE, "XkbDisable", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_XKB_RULES, "XkbRules", OPTV_STRING, {0}, FALSE }, + { OPTION_XKB_MODEL, "XkbModel", OPTV_STRING, {0}, FALSE }, + { OPTION_XKB_LAYOUT, "XkbLayout", OPTV_STRING, {0}, FALSE }, + { OPTION_XKB_VARIANT, "XkbVariant", OPTV_STRING, {0}, FALSE }, + { OPTION_XKB_OPTIONS, "XkbOptions", OPTV_STRING, {0}, FALSE }, + { -1, NULL, OPTV_NONE, {0}, FALSE } +}; + +static const char *evdevDefaults[] = { + "XkbRules", "xfree86", + "XkbModel", "evdev", + "XkbLayout", "us", + NULL +}; + +static void +SetXkbOption(InputInfoPtr pInfo, char *name, char **option) +{ + char *s; + + if ((s = xf86SetStrOption(pInfo->options, name, NULL))) { + if (!s[0]) { + xfree(s); + *option = NULL; + } else { + *option = s; + xf86Msg(X_CONFIG, "%s: %s: \"%s\"\n", pInfo->name, name, s); + } + } +} + static int wheel_up_button = 4; static int wheel_down_button = 5; static int wheel_left_button = 6; @@ -383,6 +443,7 @@ EvdevAddKeyClass(DeviceIntPtr device) CARD8 modMap[MAP_LENGTH]; KeySym sym; int i, j; + EvdevPtr pEvdev; static struct { KeySym keysym; CARD8 mask; } modifiers[] = { { XK_Shift_L, ShiftMask }, @@ -399,11 +460,11 @@ EvdevAddKeyClass(DeviceIntPtr device) /* 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; + pEvdev = pInfo->private; /* Compute the modifier map */ memset(modMap, 0, sizeof modMap); @@ -421,14 +482,36 @@ EvdevAddKeyClass(DeviceIntPtr device) keySyms.minKeyCode = MIN_KEYCODE; keySyms.maxKeyCode = MIN_KEYCODE + ArrayLength(map) / GLYPHS_PER_KEY - 1; - if (!InitKeyClassDeviceStruct(device, &keySyms, modMap)) - return !Success; - - if (!InitFocusClassDeviceStruct(device)) - return !Success; - - if (!InitKbdFeedbackClassDeviceStruct(device, EvdevKbdBell, EvdevKbdCtrl)) - return !Success; +#ifdef XKB + if (pEvdev->noXkb) +#endif + { + xf86Msg(X_CONFIG, "XKB: disabled\n"); + if (!InitKeyboardDeviceStruct((DevicePtr)device, &keySyms, modMap, + EvdevKbdBell, EvdevKbdCtrl)) + return !Success; + } +#ifdef XKB + else + { + SetXkbOption(pInfo, "XkbRules", &pEvdev->xkb_rules); + SetXkbOption(pInfo, "XkbModel", &pEvdev->xkb_model); + SetXkbOption(pInfo, "XkbLayout", &pEvdev->xkb_layout); + SetXkbOption(pInfo, "XkbVariant", &pEvdev->xkb_variant); + SetXkbOption(pInfo, "XkbOptions", &pEvdev->xkb_options); + + if (pEvdev->xkbnames.keymap) + pEvdev->xkb_rules = NULL; + + XkbSetRulesDflts(pEvdev->xkb_rules, pEvdev->xkb_model, + pEvdev->xkb_layout, pEvdev->xkb_variant, + pEvdev->xkb_options); + if (!XkbInitKeyboardDeviceStruct(device, &pEvdev->xkbnames, + &keySyms, modMap, EvdevKbdBell, + EvdevKbdCtrl)) + return !Success; + } +#endif pInfo->flags |= XI86_KEYBOARD_CAPABLE; @@ -673,7 +756,12 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags) return pInfo; pInfo->private = pEvdev; - xf86CollectInputOptions(pInfo, NULL, NULL); + if (!(pEvdev = xcalloc(sizeof(EvdevRec), 1))) + return pInfo; + + pInfo->private = pEvdev; + + xf86CollectInputOptions(pInfo, evdevDefaults, NULL); xf86ProcessCommonOptions(pInfo, pInfo->options); device = xf86CheckStrOption(dev->commonOptions, "Path", NULL); @@ -697,6 +785,9 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags) return pInfo; } + pEvdev->noXkb = noXkbExtension; + /* parse the XKB options during kbd setup */ + if (EvdevProbe(pInfo)) xfree(pEvdev); |