読者です 読者をやめる 読者になる 読者になる

カラクリサイクル

『輝かしい青春』なんて無かった人の雑記

気合と根性で mlterm-fb on Archlinux でマウスが動かない件を直した

と言う事で以下パッチです。なお、このパッチの扱いは、

でお願いします。


パッチの中身

--- uitoolkit/fb/ui_display_linux.c.orig 2017-03-24 13:09:50.900050954 +0900
+++ uitoolkit/fb/ui_display_linux.c   2017-03-25 13:28:04.755449095 +0900
@@ -3,6 +3,8 @@
 #include <linux/kd.h>
 #include <linux/keyboard.h>
 #include <linux/vt.h> /* VT_GETSTATE */
+#include <linux/limits.h>
+#include <stdio.h>
 
 #define _GNU_SOURCE /* strcasestr */
 #include <string.h>
@@ -115,15 +117,15 @@
 }
 
 static void get_event_device_num_intern(int* kbd, int* mouse, char* class, int num_index) {
+  char dev[PATH_MAX] = "";
   int count;
   FILE* fp;
 
   *kbd = *mouse = -1;
 
   for (count = 0;; count++) {
-    class[num_index] = count + 0x30;
-
-    if (!(fp = fopen(class, "r"))) {
+    sprintf(dev, class, count);
+    if (!(fp = fopen(dev, "r"))) {
       break;
     } else {
       char buf[128];
@@ -132,7 +134,7 @@
         if (strcasestr(buf, "key")) {
           *kbd = count;
         } else {
-          static char* mouse_names[] = {"mouse", "ts", "touch"};
+          static char* mouse_names[] = {"mouse", "touch"};
           u_int idx;
 
           for (idx = 0; idx < sizeof(mouse_names) / sizeof(mouse_names[0]); idx++) {
@@ -155,14 +157,14 @@
 }
 
 static void get_event_device_num(int* kbd, int* mouse) {
-  char class1[] = "/sys/class/input/inputN/name";
+  char class1[] = "/sys/class/input/inpu%d/name";
 
   get_event_device_num_intern(kbd, mouse, class1, 22);
 
   if (*kbd == -1 || *mouse == -1) {
     int k;
     int m;
-    char class2[] = "/sys/class/input/eventN/device/name";
+    char class2[] = "/sys/class/input/event%d/device/name";
 
     get_event_device_num_intern(&k, &m, class2, 22);
 
@@ -177,18 +179,21 @@
 }
 
 static int open_event_device(int num, const char* path) {
-  char event[] = "/dev/input/eventN";
+  char fmt[] = "/dev/input/event%d";
+  char dev[PATH_MAX] = "";
   int fd;
 
   bl_priv_restore_euid();
   bl_priv_restore_egid();
 
   if (!path) {
-    event[16] = num + 0x30;
-    path = event;
+    sprintf(dev, fmt, num);
+  }
+  else {
+    *dev = *path;
   }
 
-  if ((fd = open(path, O_RDONLY | O_NONBLOCK)) == -1) {
+  if ((fd = open(dev, O_RDONLY | O_NONBLOCK)) == -1) {
     bl_error_printf("Couldn't open %s.\n", path);
   }
 #if 0

解説 - そもそもなんで動かなかったのか

まず、最初の原因として上げられるのは、Linux の framebuffer 上では、

mlterm-fb が正しい /dev/input/eventN を掴めていない

というのが有り、これの影響で、

mlterm-fb が /dev/input/mice or /dev/input/mouse0 にフォールバックしている

と言う状況が有りました。

それで、 Kernel Config の影響なのか、それとも Linux の仕様なのかは判りませんが、 /dev/input/eventN/dev/event/miceしゃべってるプロトコルがそもそも違う っぽく、 /dev/input/eventN の方は Linux の strtuct input_event を、 /dev/input/mice の方は恐らくは PS/2 接続のプロトコルをしゃべってる様な感じ(?)でした。

そのため、 /dev/input/mice の方へフォールバックしてしまうと、 /dev/inpupt/eventN としゃべってるプロトコルが違うが故に、 mlterm-fb が正しいくマウスイベントをハンドリング出来なくなった結果、 マウスが動かない! と言う感じになっていました。

そして、なんで mlterm-fb そもそも /dev/input/eventN を取れてなかったか、って言うと、 これは今回のパッチで修正した点なんですが、

  1. /dev/input/eventN の自動取得で本来マウスではないデバイスをマウスと誤認識している
  2. /dev/input/eventN の N の桁数が、 1 桁 (正確には一文字) しかサポートされてなかった

という、二つの原因が理由です。

それで、 (1) の誤認識に関しては、上記パッチの、

-          static char* mouse_names[] = {"mouse", "ts", "touch"};
+          static char* mouse_names[] = {"mouse", "touch"};

辺りが原因で、これはデバイス名からキーボードやらマウスやらタッチパッドを検出する部分なんですが、 この認識ルーチンの中で ts の部分が Intel HID events というデバイス (on XPS 9560) に誤爆していたっぽいので、 これを検出しない様に ts を削除 (対象から外す) をする事で、なんとかなりました。

で、 (2) に関しては、まあこれはそのまんまな理由で、僕の環境だと、

マウスデバイスの /dev/input/eventNN の部分が二桁になっている

と言う感じだったので、これを掴める様に、ちょいちょいと修正した、という感じです。はい。

その他、現状の問題点

とりあえず、上記パッチで、マウスは使えるようになったのですが、まだ実は問題があって、

タッチパッドのイベントハンドリングが、まるでタッチパネルの様になっている

という問題が有ったりします。

これ、どういう事かって言うと、上手く伝えられる自信が無いのですが、タッチパッドでの操作感が、 マウス風ではなく、完全にタッチパネルを触っているのと同じ状態になっている感じです。

そのため、タッチパッドの右上を触ればマウスカーソルは右上に出るし、 またタッチパネルの左下を触れば、マウスカーソルは左下に出る、という感じの操作感になっています。

ただし、これは直すのは今の僕にはちょっと無理そうなので、とりあえず、こういう問題が有るよ、 って話だけで終っておきます。はい。

以上

とりあえず、以上がここ数日ほど mlterm のソースコードとにらめっこして得た収穫です。 マウスが言い事を聞く様になった mlterm-fb は色々と出来て最高なので、 とりあえず問題の修正という成果が出来て良かったです。はい。