Personal tools
You are here: Home ブログ matsuyama Stuff xf86-input-keyboard-1.3.0-mad-key.patch
Document Actions

xf86-input-keyboard-1.3.0-mad-key.patch

Click here to get the file

Size 8.0 kB - File type text/x-patch

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;

Copyright(C) 2001 - 2006 Ariel Networks, Inc. All rights reserved.