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)