xf86-input-evdev-2.5.0 のSandS用パッチ
コンテンツ
追記(2011年2月21日)
定家さんこの記事のコードの改良版をgitに公開(下のURL)してくださいました。 http://gitorious.org/at-home-modifier しっかりとしたREADMEなどが付随しているので、現状ではそちらのコードを使用したほうが良いでしょう。 (追記終わり)
Linux で SandS の実現を目指す : xf86-input-evdev の修正(メモ) – 落書き、時々落学 を最新用にした. つまり,evdevがアップデートされたので,それに対応. といっても,ほぼ何もしていない. xcalloc が deprecated されたらしいので,とりあえず calloc に変えておいたぐらい.
PKGBUILD
pkgname=xf86-input-evdev pkgver=2.5.0 pkgrel=1 pkgdesc="X.org evdev input driver" arch=(i686 x86_64) url="http://xorg.freedesktop.org/" license=('custom') depends=('glibc') makedepends=('xorg-server-devel') conflicts=('xorg-server<1.9.0') options=('!libtool' !makeflags) groups=('xorg-input-drivers') source=(${url}/releases/individual/driver/${pkgname}-${pkgver}.tar.bz2 ${pkgname}-${pkgver}-mad-key.patch) build() { cd "${srcdir}/${pkgname}-${pkgver}" patch -p0 -i ${srcdir}/${pkgname}-${pkgver}-mad-key.patch ./configure --prefix=/usr make make DESTDIR="${pkgdir}" install install -m755 -d "${pkgdir}/usr/share/licenses/${pkgname}" install -m644 COPYING "${pkgdir}/usr/share/licenses/${pkgname}/" } sha1sums=('fe83410d76830ec15c4a73ace385d66644c58944' 'e5ed1217fb22594dffe6976883dae71427784ba6')
patch
http://dl.dropbox.com/u/662567/xf86-input-evdev-2.5.0-mad-key.patch に置いてある.念の為,ここにもコードを載せておく.
diff -Naur src.orig/evdev.c src/evdev.c --- src.orig/evdev.c 2010-10-02 11:34:25.213939676 +0900 +++ src/evdev.c 2010-10-02 11:42:23.187641557 +0900 @@ -115,6 +115,32 @@ * cannot be used by evdev, leaving us with a space of 2 at the end. */ static EvdevPtr evdev_devices[MAXDEVICES] = {NULL}; +static void AddMadKey(EvdevPtr pEvdev, int trigger, int transfer, MadKeyType type) +{ + MadKeyList *keyList = pEvdev->madKeyList; + MadKeyList *key; + if (keyList != NULL) { + while (keyList->next != NULL) + keyList = keyList->next; + } + + + key = calloc(sizeof(MadKeyList), 1); + if (key == NULL) + return; + + key->madKey = &key->madKeyEntity; + key->madKey->trigger = trigger; + key->madKey->transfer = transfer; + key->madKey->type = type; + key->next = NULL; + + if (keyList == NULL) + pEvdev->madKeyList = key; + else + keyList->next = key; +} + static int EvdevSwitchMode(ClientPtr client, DeviceIntPtr device, int mode) { InputInfoPtr pInfo; @@ -262,13 +288,25 @@ static int wheel_left_button = 6; static int wheel_right_button = 7; +static void +EvdevEnqueKeyEvent(EvdevPtr pEvdev, int code, int value) +{ + EventQueuePtr pQueue = &pEvdev->queue[pEvdev->num_queue]; + pQueue->type = EV_QUEUE_KEY; + pQueue->key = code + MIN_KEYCODE; + pQueue->val = value; + pEvdev->num_queue++; +} + void EvdevQueueKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value) { - int code = ev->code + MIN_KEYCODE; - EventQueuePtr pQueue; EvdevPtr pEvdev = pInfo->private; + int scanCode = ev->code; + unsigned int tmpScanCode = scanCode; + unsigned int lastScanCode = pEvdev->lastScanCode; + /* Filter all repeated events from device. We'll do softrepeat in the server, but only since 1.6 */ if (value == 2 @@ -289,11 +327,88 @@ return; } - pQueue = &pEvdev->queue[pEvdev->num_queue]; - pQueue->type = EV_QUEUE_KEY; - pQueue->key = code; - pQueue->val = value; - pEvdev->num_queue++; + + /* + * Sticky Key + */ + if (value) { + if (pEvdev->stickyPhase == 1) { + pEvdev->stickyPhase = 2; + EvdevEnqueKeyEvent(pEvdev, pEvdev->stickyScanCode, TRUE); + goto madKeyFinish; + } else if (pEvdev->stickyPhase == 2) { + pEvdev->stickyPhase = 0; + EvdevEnqueKeyEvent(pEvdev, pEvdev->stickyScanCode, FALSE); + goto madKeyFinish; + } + } else { + MadKeyList *keyList; + for (keyList = pEvdev->madKeyList; keyList != NULL; keyList = keyList->next) { + MadKey *key = keyList->madKey; + if (key->type == MAD_KEY_STICKY + && key->trigger == scanCode + && lastScanCode == scanCode) { + if (pEvdev->stickyPhase == -1) { /* ignore */ + pEvdev->stickyPhase = 0; + break; + } else { + pEvdev->stickyPhase = 1; + pEvdev->stickyScanCode = keyList->madKey->transfer; + return; + } + } + } + } + + /* + * Pseudo Modifier + */ + { + MadKeyList *keyList; + for (keyList = pEvdev->madKeyList; keyList != NULL; keyList = keyList->next) { + MadKey *key = keyList->madKey; + if (key->type == MAD_KEY_PSEUDO_MOD + && key->trigger == scanCode) { + if (lastScanCode == key->transfer) { + tmpScanCode = lastScanCode; + pEvdev->stickyPhase = -1; + } else if (value) + scanCode = key->transfer; + else { + if (lastScanCode == scanCode) { + EvdevEnqueKeyEvent(pEvdev, key->transfer, FALSE); + EvdevEnqueKeyEvent(pEvdev, key->trigger, TRUE); + } else + scanCode = key->transfer; + } + goto madKeyFinish; + } + } + } + + /* + * One Shot Modifier + */ + if (!value) { + MadKeyList *keyList; + for (keyList = pEvdev->madKeyList; keyList != NULL; keyList = keyList->next) { + MadKey *key = keyList->madKey; + if (key->type == MAD_KEY_ONE_SHOT_MOD + && key->trigger == scanCode + && lastScanCode == scanCode) { + scanCode = key->transfer; + EvdevEnqueKeyEvent(pEvdev, lastScanCode, FALSE); + EvdevEnqueKeyEvent(pEvdev, scanCode, TRUE); + goto madKeyFinish; + } + } + } + + madKeyFinish: + if (value) + pEvdev->lastScanCode = tmpScanCode; + + EvdevEnqueKeyEvent(pEvdev, scanCode, value); } void @@ -1100,6 +1215,8 @@ pInfo = device->public.devicePrivate; pEvdev = pInfo->private; + pEvdev->lastScanCode = 0; + pEvdev->stickyPhase = 0; /* sorry, no rules change allowed for you */ xf86ReplaceStrOption(pInfo->options, "xkb_rules", "evdev"); @@ -2126,6 +2243,62 @@ EvdevDragLockPreInit(pInfo); } + if (pEvdev->flags & EVDEV_KEYBOARD_EVENTS) + { + pEvdev->madKeyList = NULL; + if (xf86FindOption(pInfo->options, "StickyShift")) { + AddMadKey(pEvdev, KEY_LEFTSHIFT, KEY_LEFTSHIFT, MAD_KEY_STICKY); + AddMadKey(pEvdev, KEY_RIGHTSHIFT, KEY_RIGHTSHIFT, MAD_KEY_STICKY); + xf86Msg(X_CONFIG, "%s: StickyShift enabled\n", pInfo->name); + } + if (xf86FindOption(pInfo->options, "StickyCtrl")) { + AddMadKey(pEvdev, KEY_LEFTCTRL, KEY_LEFTCTRL, MAD_KEY_STICKY); + AddMadKey(pEvdev, KEY_RIGHTCTRL, KEY_RIGHTCTRL, MAD_KEY_STICKY); + xf86Msg(X_CONFIG, "%s: StickyCtrl enabled\n", pInfo->name); + } + if (xf86FindOption(pInfo->options, "StickyAlt")) { + AddMadKey(pEvdev, KEY_LEFTALT, KEY_LEFTALT, MAD_KEY_STICKY); + AddMadKey(pEvdev, KEY_RIGHTALT, KEY_RIGHTALT, MAD_KEY_STICKY); + xf86Msg(X_CONFIG, "%s: StickyAlt enabled\n", pInfo->name); + } + if (xf86FindOption(pInfo->options, "PseudoModSpace")) { + int transfer = xf86SetIntOption(pInfo->options, + "PseudoModSpace", + MIN_KEYCODE) - MIN_KEYCODE; + AddMadKey(pEvdev, KEY_SPACE, transfer, MAD_KEY_PSEUDO_MOD); + xf86Msg(X_CONFIG, "%s: PseudoModSpace enabled\n", pInfo->name); + } + if (xf86FindOption(pInfo->options, "OneShotShift")) { + int transfer = xf86SetIntOption(pInfo->options, + "OneShotShift", + MIN_KEYCODE) - MIN_KEYCODE; + AddMadKey(pEvdev, KEY_LEFTSHIFT, transfer, MAD_KEY_ONE_SHOT_MOD); + AddMadKey(pEvdev, KEY_RIGHTSHIFT, transfer, MAD_KEY_ONE_SHOT_MOD); + xf86Msg(X_CONFIG, "%s: OneShotShift enabled\n", pInfo->name); + } + if (xf86FindOption(pInfo->options, "OneShotCtrl")) { + int transfer = xf86SetIntOption(pInfo->options, + "OneShotCtrl", + MIN_KEYCODE) - MIN_KEYCODE; + AddMadKey(pEvdev, KEY_LEFTCTRL, transfer, MAD_KEY_ONE_SHOT_MOD); + AddMadKey(pEvdev, KEY_RIGHTCTRL, transfer, MAD_KEY_ONE_SHOT_MOD); +#ifdef XKB + if (xkb_options != NULL && strstr(xkb_options, "ctrl:swapcaps") != NULL) + AddMadKey(pEvdev, KEY_CAPSLOCK, transfer, MAD_KEY_ONE_SHOT_MOD); +#endif + xf86Msg(X_CONFIG, "%s: OneShotCtrl enabled\n", pInfo->name); + } + if (xf86FindOption(pInfo->options, "OneShotAlt")) { + int transfer = xf86SetIntOption(pInfo->options, + "OneShotAlt", + MIN_KEYCODE) - MIN_KEYCODE; + AddMadKey(pEvdev, KEY_LEFTALT, transfer, MAD_KEY_ONE_SHOT_MOD); + AddMadKey(pEvdev, KEY_RIGHTALT, transfer, MAD_KEY_ONE_SHOT_MOD); + xf86Msg(X_CONFIG, "%s: OneShotAlt enabled\n", pInfo->name); + } + + } + return pInfo; error: diff -Naur src.orig/evdev.h src/evdev.h --- src.orig/evdev.h 2010-10-02 11:34:25.213939676 +0900 +++ src/evdev.h 2010-10-02 11:34:32.114356654 +0900 @@ -104,6 +104,25 @@ int traveled_distance; } WheelAxis, *WheelAxisPtr; +/* key status data for mad-key system */ +typedef enum { + MAD_KEY_STICKY, + MAD_KEY_PSEUDO_MOD, + MAD_KEY_ONE_SHOT_MOD, +} MadKeyType; + +typedef struct { + int trigger; + int transfer; + MadKeyType type; +} MadKey; + +typedef struct MadKeyList { + MadKey madKeyEntity; + MadKey *madKey; + struct MadKeyList *next; +} MadKeyList; + /* Event queue used to defer keyboard/button events until EV_SYN time. */ typedef struct { enum { @@ -133,6 +152,17 @@ int delta[REL_CNT]; unsigned int abs, rel; + int lastScanCode; + int stickyScanCode; + /* + * -1: ignore + * 0: disabled + * 1: presss enabled + * 2: release enabled + */ + int stickyPhase; + MadKeyList *madKeyList; + /* XKB stuff has to be per-device rather than per-driver */ #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 5 XkbComponentNamesRec xkbnames;
作成者 Toru Mano
最終更新時刻 2023-01-01 (c70d5a1)