File contents
diff -Nru xf86-input-keyboard-1.3.0.orig/src/kbd.c xf86-input-keyboard-1.3.0/src/kbd.c
--- xf86-input-keyboard-1.3.0.orig/src/kbd.c 2008-03-21 03:55:18.000000000 +0900
+++ xf86-input-keyboard-1.3.0/src/kbd.c 2008-04-20 19:51:19.000000000 +0900
@@ -176,6 +176,30 @@
NULL,
};
+static void AddMadKey(KbdDevPtr keyboard, int trigger, int transfer, MadKeyType type)
+{
+ MadKeyList *keyList = keyboard->madKeyList;
+ if (keyList != NULL) {
+ while (keyList->next != NULL)
+ keyList = keyList->next;
+ }
+
+ MadKeyList *key = xcalloc(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)
+ keyboard->madKeyList = key;
+ else
+ keyList->next = key;
+}
+
#ifdef XKB
static char *xkb_rules;
static char *xkb_model;
@@ -346,6 +370,56 @@
xf86Msg(from, "%s: CustomKeycodes %s\n",
pInfo->name, pKbd->CustomKeycodes ? "enabled" : "disabled");
+ pKbd->madKeyList = NULL;
+ if (xf86FindOption(pInfo->options, "StickyShift")) {
+ AddMadKey(pKbd, KEY_ShiftL, KEY_ShiftL, MAD_KEY_STICKY);
+ AddMadKey(pKbd, KEY_ShiftR, KEY_ShiftR, MAD_KEY_STICKY);
+ xf86Msg(X_CONFIG, "%s: StickyShift enabled\n", pInfo->name);
+ }
+ if (xf86FindOption(pInfo->options, "StickyCtrl")) {
+ AddMadKey(pKbd, KEY_LCtrl, KEY_LCtrl, MAD_KEY_STICKY);
+ AddMadKey(pKbd, KEY_RCtrl, KEY_RCtrl, MAD_KEY_STICKY);
+ xf86Msg(X_CONFIG, "%s: StickyCtrl enabled\n", pInfo->name);
+ }
+ if (xf86FindOption(pInfo->options, "StickyAlt")) {
+ AddMadKey(pKbd, KEY_Alt, KEY_Alt, 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(pKbd, 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(pKbd, KEY_ShiftL, transfer, MAD_KEY_ONE_SHOT_MOD);
+ AddMadKey(pKbd, KEY_ShiftR, 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(pKbd, KEY_LCtrl, transfer, MAD_KEY_ONE_SHOT_MOD);
+ AddMadKey(pKbd, KEY_RCtrl, transfer, MAD_KEY_ONE_SHOT_MOD);
+#ifdef XKB
+ if (xkb_options != NULL && strstr(xkb_options, "ctrl:swapcaps") != NULL)
+ AddMadKey(pKbd, 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(pKbd, KEY_Alt, transfer, MAD_KEY_ONE_SHOT_MOD);
+ xf86Msg(X_CONFIG, "%s: OneShotAlt enabled\n", pInfo->name);
+ }
+
pInfo->flags |= XI86_CONFIGURED;
return pInfo;
@@ -491,6 +565,9 @@
pKbd->SetKbdRepeat(pInfo, rad);
} else
UpdateLeds(pInfo);
+
+ pKbd->lastScanCode = 0;
+ pKbd->stickyPhase = 0;
}
static int
@@ -582,6 +659,8 @@
KeyClassRec *keyc = device->key;
KbdFeedbackClassRec *kbdfeed = device->kbdfeed;
int specialkey = 0;
+ unsigned int tmpScanCode = 0;
+ unsigned int lastScanCode = pKbd->lastScanCode;
Bool UsePrefix = FALSE;
KeySym *keysym;
@@ -674,6 +753,88 @@
#endif
sunKeyboards:
+ tmpScanCode = scanCode;
+
+ /*
+ * Sticky Key
+ */
+ if (down) {
+ if (pKbd->stickyPhase == 1) {
+ pKbd->stickyPhase = 2;
+ xf86PostKeyboardEvent(device, pKbd->stickyScanCode + MIN_KEYCODE, TRUE);
+ goto madKeyFinish;
+ } else if (pKbd->stickyPhase == 2) {
+ pKbd->stickyPhase = 0;
+ xf86PostKeyboardEvent(device, pKbd->stickyScanCode + MIN_KEYCODE, FALSE);
+ goto madKeyFinish;
+ }
+ } else {
+ MadKeyList *keyList;
+ for (keyList = pKbd->madKeyList; keyList != NULL; keyList = keyList->next) {
+ MadKey *key = keyList->madKey;
+ if (key->type == MAD_KEY_STICKY
+ && key->trigger == scanCode
+ && lastScanCode == scanCode) {
+ if (pKbd->stickyPhase == -1) { /* ignore */
+ pKbd->stickyPhase = 0;
+ break;
+ } else {
+ pKbd->stickyPhase = 1;
+ pKbd->stickyScanCode = keyList->madKey->transfer;
+ return;
+ }
+ }
+ }
+ }
+
+ /*
+ * Pseudo Modifier
+ */
+ {
+ MadKeyList *keyList;
+ for (keyList = pKbd->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;
+ pKbd->stickyPhase = -1;
+ } else if (down)
+ scanCode = key->transfer;
+ else {
+ if (lastScanCode == scanCode) {
+ xf86PostKeyboardEvent(device, key->transfer + MIN_KEYCODE, FALSE);
+ xf86PostKeyboardEvent(device, key->trigger + MIN_KEYCODE, TRUE);
+ } else
+ scanCode = key->transfer;
+ }
+ goto madKeyFinish;
+ }
+ }
+ }
+
+ /*
+ * One Shot Modifier
+ */
+ if (!down) {
+ MadKeyList *keyList;
+ for (keyList = pKbd->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;
+ xf86PostKeyboardEvent(device, lastScanCode + MIN_KEYCODE, FALSE);
+ xf86PostKeyboardEvent(device, scanCode + MIN_KEYCODE, TRUE);
+ goto madKeyFinish;
+ }
+ }
+ }
+
+madKeyFinish:
+ if (down)
+ pKbd->lastScanCode = tmpScanCode;
+
/*
* Now map the scancodes to real X-keycodes ...
*/
diff -Nru xf86-input-keyboard-1.3.0.orig/src/xf86OSKbd.h xf86-input-keyboard-1.3.0/src/xf86OSKbd.h
--- xf86-input-keyboard-1.3.0.orig/src/xf86OSKbd.h 2008-03-21 03:55:18.000000000 +0900
+++ xf86-input-keyboard-1.3.0/src/xf86OSKbd.h 2008-04-20 17:28:38.000000000 +0900
@@ -56,6 +56,24 @@
unsigned char *map;
} TransMapRec, *TransMapPtr;
+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;
+
typedef struct {
KbdInitProc KbdInit;
KbdOnProc KbdOn;
@@ -88,6 +106,17 @@
TransMapPtr scancodeMap;
TransMapPtr specialMap;
+ int lastScanCode;
+ int stickyScanCode;
+ /*
+ * -1: ignore
+ * 0: disabled
+ * 1: presss enabled
+ * 2: release enabled
+ */
+ int stickyPhase;
+ MadKeyList *madKeyList;
+
/* os specific */
pointer private;
int kbdType;