Last active
August 29, 2015 14:05
-
-
Save tristan/58c041eb4588b5c54ccd to your computer and use it in GitHub Desktop.
xf86-input-evdev-remap patch for 2.9.2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Section "InputClass" | |
Identifier "evdev keyboard catchall" | |
MatchIsKeyboard "on" | |
MatchDevicePath "/dev/input/event*" | |
MatchProduct "BD Remote Control" | |
Driver "evdev" | |
Option "event_key_remap" "119=65 159=41 161=39 207=33 256=53 311=86 313=82 315=33 357=54 371=52 358=31 401=25 407=37 412=34 436=59 437=60 438=54" | |
EndSection |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/man/evdev.man b/man/evdev.man | |
index 06613fc..53fcb3f 100644 | |
--- a/man/evdev.man | |
+++ b/man/evdev.man | |
@@ -226,6 +226,17 @@ Specify the X Input 1.x type (see XListInputDevices(__libmansuffix__)). | |
There is rarely a need to use this option, evdev will guess the device type | |
based on the device's capabilities. This option is provided for devices that | |
need quirks. | |
+.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). | |
.TP 7 | |
.BI "Option \*qVertScrollDelta\*q \*q" integer \*q | |
The amount of motion considered one unit of scrolling vertically. | |
diff --git a/src/evdev.c b/src/evdev.c | |
index 7aecf36..3aeead4 100644 | |
--- a/src/evdev.c | |
+++ b/src/evdev.c | |
@@ -141,6 +141,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; | |
@@ -267,6 +307,42 @@ static int wheel_left_button = 6; | |
static int wheel_right_button = 7; | |
#endif | |
+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) | |
{ | |
@@ -285,7 +361,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. | |
@@ -1179,6 +1255,8 @@ EvdevAddKeyClass(DeviceIntPtr device) | |
rmlvo.variant = xf86SetStrOption(pInfo->options, "xkb_variant", NULL); | |
rmlvo.options = xf86SetStrOption(pInfo->options, "xkb_options", NULL); | |
+ SetRemapOption(pInfo, "event_key_remap"); | |
+ | |
if (!InitKeyboardDeviceStruct(device, &rmlvo, NULL, EvdevKbdCtrl)) | |
rc = !Success; | |
@@ -2003,6 +2081,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 2d6b62d..bc9cc39 100644 | |
--- a/src/evdev.h | |
+++ b/src/evdev.h | |
@@ -152,6 +152,13 @@ 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; | |
@@ -239,6 +246,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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
_pkgname=xf86-input-evdev | |
pkgname=${_pkgname}-remap | |
pkgver=2.9.2 | |
pkgrel=1 | |
pkgdesc="X.org evdev input driver" | |
arch=(i686 x86_64) | |
url="http://xorg.freedesktop.org/" | |
license=('custom') | |
depends=('glibc' 'systemd' 'mtdev' 'libevdev') | |
makedepends=('xorg-server-devel' 'resourceproto' 'scrnsaverproto') | |
provides=('xf86-input-evdev') | |
conflicts=('xorg-server<1.16.0' 'xf86-input-evdev' 'X-ABI-XINPUT_VERSION<21' 'X-ABI-XINPUT_VERSION>=22') | |
options=('!makeflags') | |
groups=('xorg-drivers' 'xorg') | |
source=(${url}/releases/individual/driver/${_pkgname}-${pkgver}.tar.bz2 | |
evdev-remap.patch) | |
sha256sums=('792329b531afc6928ccda94e4b51a5520d4ddf8ef9a00890a5d0d31898acefec' | |
'030e682fac851b15d990d506b6b4918d13b71c2205472412877080d9c899ca81') | |
prepare () { | |
cd "$srcdir/${_pkgname}-${pkgver}" | |
patch -Np1 -i "$srcdir/evdev-remap.patch" | |
} | |
build() { | |
cd ${_pkgname}-${pkgver} | |
./configure --prefix=/usr | |
make | |
} | |
package() { | |
cd ${_pkgname}-${pkgver} | |
make DESTDIR="${pkgdir}" install | |
install -m755 -d "${pkgdir}/usr/share/licenses/${_pkgname}" | |
install -m644 COPYING "${pkgdir}/usr/share/licenses/${_pkgname}/" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment