mirror of
https://github.com/X11Libre/xf86-input-evdev.git
synced 2026-03-26 10:44:30 +00:00
Re-add XKB support.
Almost entirely taken from a patch I did ages ago in bug #3912, with slight cleanups, and with the KcCGST options removed as per evdev 1.x.
This commit is contained in:
109
src/evdev.c
109
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;
|
||||
#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 (!InitFocusClassDeviceStruct(device))
|
||||
return !Success;
|
||||
if (pEvdev->xkbnames.keymap)
|
||||
pEvdev->xkb_rules = NULL;
|
||||
|
||||
if (!InitKbdFeedbackClassDeviceStruct(device, EvdevKbdBell, EvdevKbdCtrl))
|
||||
return !Success;
|
||||
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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user