2015/05/17

Linux Trackball:Emulate3Buttons改造


1年くらい前にevdevのEmulate3Buttonsまわりのコードを改造したが、今回それに追加をすることにした。
xorg.confの設定において、Emulate3ButtonsはButton1(左クリック)とButton3(右クリック)を同時押しするとButton2のeventが発行されるというものである。
また、左右同時押し+トラックボールで画面のスクロールをしたい場合、EmulateWheelを"True"にすればよいわけだが、それを行うEmulateWheelButtonはEmulateされたボタンであってはならないという制約がデフォルトでは存在した。これを変更する改造を以前行ったわけだが、問題が完全に解決したわけではなかった。

自分の愛用しているKensingtonのExpert Mouse 7やSlimbladeにおいて、ボタンのフィジカルレイアウトは


2 | 8
-----
1 | 3
となっているわけだが、自分は


8 | 9
-----
1 | 3
のように使いたい。8をブラウザの戻る、9をブラウザの進むに割り当てると非常にブラウジングが快適になるからだ。
この設定はOption "ButtonMapping" "1 8 3 4 5 6 7 9"のようにすれば可能だが、こうするとEmulate3Buttonsで発行されるボタンはフィジカルボタンの2番目、つまり"8"が発行されてしまう。自分としては中クリックの"2"を発行したい。さらに、EmulateWheelButtonは"2"にしたい。

どうしたものかとしばらく悩んだが、解決策を思いついた。
Emulate3Buttonsで発行されるボタンを存在しないフィジカルボタンの9番目にして、そこをButtonMappingで"2"にすればいいのである。
xf86-input-evdev-2.9.2/src/emuMB.cのステートマシンのstateTab[][][0]が発行されるキー番号なので、ここの2を9に変更すればよい。以前変更したEvdevMBEmuFilterEventの変更部分はそのままで大丈夫だ。


diff -ur xf86-input-evdev-2.9.2/src/emuMB.c xf86-input-evdev-2.9.2-myMB/src/emuMB.c
--- xf86-input-evdev-2.9.2/src/emuMB.c 2015-03-11 12:24:39.000000000 +0900
+++ xf86-input-evdev-2.9.2-myMB/src/emuMB.c 2015-05-17 02:23:52.430447770 +0900
@@ -94,7 +94,7 @@
     {  0,  0,  0 },   /* nothing -> ground (no change) */
     {  0,  0,  1 },   /* left -> delayed left */
     {  0,  0,  2 },   /* right -> delayed right */
-    {  2,  0,  3 },   /* left & right (middle press) -> pressed middle */
+    {  9,  0,  3 },   /* left & right (middle press) -> pressed middle */
     {  0,  0, -1 }    /* timeout N/A */
   },
 /* 1 delayed left */
@@ -102,7 +102,7 @@
     {  1, -1,  0 },   /* nothing (left event) -> ground */
     {  0,  0,  1 },   /* left -> delayed left (no change) */
     {  1, -1,  2 },   /* right (left event) -> delayed right */
-    {  2,  0,  3 },   /* left & right (middle press) -> pressed middle */
+    {  9,  0,  3 },   /* left & right (middle press) -> pressed middle */
     {  1,  0,  4 },   /* timeout (left press) -> pressed left */
   },
 /* 2 delayed right */
@@ -110,12 +110,12 @@
     {  3, -3,  0 },   /* nothing (right event) -> ground */
     {  3, -3,  1 },   /* left (right event) -> delayed left (no change) */
     {  0,  0,  2 },   /* right -> delayed right (no change) */
-    {  2,  0,  3 },   /* left & right (middle press) -> pressed middle */
+    {  9,  0,  3 },   /* left & right (middle press) -> pressed middle */
     {  3,  0,  5 },   /* timeout (right press) -> pressed right */
   },
 /* 3 pressed middle */
   {
-    { -2,  0,  0 },   /* nothing (middle release) -> ground */
+    { -9,  0,  0 },   /* nothing (middle release) -> ground */
     {  0,  0,  7 },   /* left -> released right */
     {  0,  0,  6 },   /* right -> released left */
     {  0,  0,  3 },   /* left & right -> pressed middle (no change) */
@@ -139,33 +139,33 @@
   },
 /* 6 released left */
   {
-    { -2,  0,  0 },   /* nothing (middle release) -> ground */
-    { -2,  0,  1 },   /* left (middle release) -> delayed left */
+    { -9,  0,  0 },   /* nothing (middle release) -> ground */
+    { -9,  0,  1 },   /* left (middle release) -> delayed left */
     {  0,  0,  6 },   /* right -> released left (no change) */
     {  1,  0,  8 },   /* left & right (left press) -> repressed left */
     {  0,  0, -1 },   /* timeout N/A */
   },
 /* 7 released right */
   {
-    { -2,  0,  0 },   /* nothing (middle release) -> ground */
+    { -9,  0,  0 },   /* nothing (middle release) -> ground */
     {  0,  0,  7 },   /* left -> released right (no change) */
-    { -2,  0,  2 },   /* right (middle release) -> delayed right */
+    { -9,  0,  2 },   /* right (middle release) -> delayed right */
     {  3,  0,  9 },   /* left & right (right press) -> repressed right */
     {  0,  0, -1 },   /* timeout N/A */
   },
 /* 8 repressed left */
   {
-    { -2, -1,  0 },   /* nothing (middle release, left release) -> ground */
-    { -2,  0,  4 },   /* left (middle release) -> pressed left */
+    { -9, -1,  0 },   /* nothing (middle release, left release) -> ground */
+    { -9,  0,  4 },   /* left (middle release) -> pressed left */
     { -1,  0,  6 },   /* right (left release) -> released left */
     {  0,  0,  8 },   /* left & right -> repressed left (no change) */
     {  0,  0, -1 },   /* timeout N/A */
   },
 /* 9 repressed right */
   {
-    { -2, -3,  0 },   /* nothing (middle release, right release) -> ground */
+    { -9, -3,  0 },   /* nothing (middle release, right release) -> ground */
     { -3,  0,  7 },   /* left (right release) -> released right */
-    { -2,  0,  5 },   /* right (middle release) -> pressed right */
+    { -9,  0,  5 },   /* right (middle release) -> pressed right */
     {  0,  0,  9 },   /* left & right -> repressed right (no change) */
     {  0,  0, -1 },   /* timeout N/A */
   },
@@ -237,12 +237,14 @@

     if ((id = stateTab[pEvdev->emulateMB.state][*btstate][0]) != 0)
     {
-        EvdevQueueButtonEvent(pInfo, abs(id), (id >= 0));
+ if (!EvdevWheelEmuFilterButton(pInfo, abs(id), (id >= 0)))
+    EvdevQueueButtonEvent(pInfo, abs(id), (id >= 0));
         ret = TRUE;
     }
     if ((id = stateTab[pEvdev->emulateMB.state][*btstate][1]) != 0)
     {
-        EvdevQueueButtonEvent(pInfo, abs(id), (id >= 0));
+ if (!EvdevWheelEmuFilterButton(pInfo, abs(id), (id >= 0)))
+    EvdevQueueButtonEvent(pInfo, abs(id), (id >= 0));
         ret = TRUE;
     }

こうした後で、Option "ButtonMapping" "1 8 3 4 5 6 7 9 2"にする。
/etc/X11/xorg.confの該当部分はこんな感じ。


Section "InputDevice"
  Identifier "Kensington Slimblade"
  Driver "evdev"
  Option "Protocol" "auto"
Option "Device"   "/dev/input/by-id/usb-Kensington_Kensington_Slimblade_Trackball-event-mouse"
  Option "Buttons"  "9"
Option "Emulate3Buttons" "true"
Option "Emulate3Timeout" "100"
Option "EmulateWheel"        "true"
Option "EmulateWheelButton" "9" # requires evdev customize
Option "EmulateWheelTimeout" "250"
Option "YAxisMapping" "4 5"
Option "XAxisMapping" "6 7"
  Option "ButtonMapping" "1 8 3 4 5 6 7 9 2"
EndSection

これで、左右ボタン同時押しで中クリックとして使用し、左右ボタン同時押し+トラックボールでスクロールすることができる。ちなみに中ボタンドラッグができないのは仕様である。
非常に快適である。

0 件のコメント:

コメントを投稿