aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGianni Ceccarelli <gianni.ceccarelli@net-a-porter.com>2012-04-03 12:29:03 +0100
committerdakkar <dakkar@thenautilus.net>2018-06-02 10:04:41 +0100
commitd32702a151fa235de79222f4c12eb72065a0ca69 (patch)
treee769e60f2fb952551d1aa5247de64b010779feee
parentevdev 2.10.6 (diff)
downloadxf86-input-evdev-code-remap-2.10.6.tar.gz
xf86-input-evdev-code-remap-2.10.6.tar.bz2
xf86-input-evdev-code-remap-2.10.6.zip
code-remap for 2.10.6code-remap-2.10.6
-rw-r--r--man/evdev.man12
-rw-r--r--src/evdev.c81
-rw-r--r--src/evdev.h10
3 files changed, 102 insertions, 1 deletions
diff --git a/man/evdev.man b/man/evdev.man
index e39736a..cd90e94 100644
--- a/man/evdev.man
+++ b/man/evdev.man
@@ -262,6 +262,18 @@ Sets the resolution of the device in dots per inch. The resolution is used
to scale relative motion events from mouse devices to 1000 DPI resolution. This
can be used to make high resolution mice less sensitive without turning off
acceleration. If set to 0 no scaling will be performed. Default: "0".
+.TP 7
+.BI "Option \*qevent_key_remap\*q \*q" "integer=integer ..." \*q
+Specifies a set of mappings for key events; the number on the
+left-hand side of the equal sign must be an evdev keycode (look it up
+with
+.B "showkey -k"
+; it can be between 0 and 65535), the number on the right-hand side of
+the equal sign must be an X11 keycode (look it up in the
+.B "__projectroot__/share/X11/xkb/keycodes/evdev"
+file; it can be between 8 and 255). Integers can be specified as in C
+source files (base-10, base-8 if they start with 0, base-16 if they
+start with 0x).
.SH SUPPORTED PROPERTIES
The following properties are provided by the
diff --git a/src/evdev.c b/src/evdev.c
index 6b5eadd..3d5520c 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -127,6 +127,46 @@ static Atom prop_device;
static Atom prop_virtual;
static Atom prop_scroll_dist;
+static uint16_t
+remapKey(EvdevPtr ev, uint16_t code)
+{
+ uint8_t slice=code/256;
+ uint8_t offs=code%256;
+
+ if (!ev->keyremap) return code;
+ if (!(ev->keyremap->sl[slice])) return code;
+ if (!(ev->keyremap->sl[slice]->cd[offs])) return code;
+ return ev->keyremap->sl[slice]->cd[offs];
+}
+
+static void
+addRemap(EvdevPtr ev,uint16_t code,uint8_t value)
+{
+ uint8_t slice=code/256;
+ uint8_t offs=code%256;
+
+ if (!ev->keyremap) {
+ ev->keyremap=(EvdevKeyRemapPtr)calloc(sizeof(EvdevKeyRemap),1);
+ }
+ if (!ev->keyremap->sl[slice]) {
+ ev->keyremap->sl[slice]=(EvdevKeyRemapSlice*)calloc(sizeof(EvdevKeyRemapSlice),1);
+ }
+ ev->keyremap->sl[slice]->cd[offs]=value;
+}
+
+static void
+freeRemap(EvdevPtr ev)
+{
+ uint16_t slice;
+ if (!ev->keyremap) return;
+ for (slice=0;slice<256;++slice) {
+ if (!ev->keyremap->sl[slice]) continue;
+ free(ev->keyremap->sl[slice]);
+ }
+ free(ev->keyremap);
+ ev->keyremap=0;
+}
+
static int EvdevSwitchMode(ClientPtr client, DeviceIntPtr device, int mode)
{
InputInfoPtr pInfo;
@@ -259,6 +299,42 @@ out:
}
+static void
+SetRemapOption(InputInfoPtr pInfo,const char* name)
+{
+ char *s,*c;
+ unsigned long int code,value;
+ int consumed;
+ EvdevPtr ev = pInfo->private;
+
+ s = xf86SetStrOption(pInfo->options, name, NULL);
+ if (!s) return;
+ if (!s[0]) {
+ free(s);
+ return;
+ }
+
+ c=s;
+ while (sscanf(c," %li = %li %n",&code,&value,&consumed) > 1) {
+ c+=consumed;
+ if (code < 0 || code > 65535L) {
+ xf86Msg(X_ERROR,"%s: input code %ld out of range for option \"event_key_remap\", ignoring.\n",pInfo->name,code);
+ continue;
+ }
+ if (value < MIN_KEYCODE || value > 255) {
+ xf86Msg(X_ERROR,"%s: output value %ld out of range for option \"event_key_remap\", ignoring.\n",pInfo->name,value);
+ continue;
+ }
+ xf86Msg(X_INFO,"%s: remapping %ld into %ld.\n",pInfo->name,code,value);
+ addRemap(ev,code,value-MIN_KEYCODE);
+ }
+
+ if (*c!='\0') {
+ xf86Msg(X_ERROR, "%s: invalid input for option \"event_key_remap\" starting at '%s', ignoring.\n",
+ pInfo->name, c);
+ }
+}
+
static EventQueuePtr
EvdevNextInQueue(InputInfoPtr pInfo)
{
@@ -277,7 +353,7 @@ EvdevNextInQueue(InputInfoPtr pInfo)
void
EvdevQueueKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value)
{
- int code = ev->code + MIN_KEYCODE;
+ int code = remapKey((EvdevPtr)(pInfo->private),ev->code) + MIN_KEYCODE;
EventQueuePtr pQueue;
/* Filter all repeated events from device.
@@ -1157,6 +1233,8 @@ EvdevAddKeyClass(DeviceIntPtr device)
rmlvo.variant = xf86SetStrOption(pInfo->options, "xkb_variant", defaults.variant);
rmlvo.options = xf86SetStrOption(pInfo->options, "xkb_options", defaults.options);
+ SetRemapOption(pInfo,"event_key_remap");
+
if (!InitKeyboardDeviceStruct(device, &rmlvo, NULL, EvdevKbdCtrl))
rc = !Success;
@@ -2031,6 +2109,7 @@ EvdevProc(DeviceIntPtr device, int what)
xf86IDrvMsg(pInfo, X_INFO, "Close\n");
EvdevCloseDevice(pInfo);
EvdevFreeMasks(pEvdev);
+ freeRemap(pEvdev);
pEvdev->min_maj = 0;
break;
diff --git a/src/evdev.h b/src/evdev.h
index 7081182..6a1242d 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -154,6 +154,14 @@ typedef struct {
} EventQueueRec, *EventQueuePtr;
typedef struct {
+ uint8_t cd[256];
+} EvdevKeyRemapSlice;
+
+typedef struct {
+ EvdevKeyRemapSlice* sl[256];
+} EvdevKeyRemap, *EvdevKeyRemapPtr;
+
+typedef struct {
struct libevdev *dev;
char *device;
@@ -242,6 +250,8 @@ typedef struct {
unsigned char btnmap[32]; /* config-file specified button mapping */
+ EvdevKeyRemapPtr keyremap;
+
int reopen_attempts; /* max attempts to re-open after read failure */
int reopen_left; /* number of attempts left to re-open the device */
OsTimerPtr reopen_timer;