0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

VNC Viewer で戻る・進む・漢字

Last updated at Posted at 2017-09-12

はじめに

みなさん VDI してますかー?

このたび CentOS 7 の VNC Viewer で、マウスの戻る・進むボタン、漢字キーを使えるように出来たので、メモを残します。

背景

個人的に VDI ぽいことをしている私は、VNC に依存した生活をしています。最近わずかに環境を変えたことで、今まで気付かなかった不自由に遭遇しました。

操作が不自由

マウスを新調したり VNC Viewer を実行する環境を CentOS 7 に変更したりしたところ、少し困ったことになりました。

  • マウスの戻る・進むボタンが使えない
  • 漢字キーが使えない

まず、「だっせー知らなかったのかよ!」的な感じですが、マウスボタンが無反応でしたw 買って届いて挿したら動かないw そして、CentOS 6 ではフツーに使えていた漢字キーも無反応になりましたww

原因

VNC では第9ボタン以降が使えません。これは RFB (VNC のプロトコル)の制限で、マウスボタン情報用に1オクテットしか割り当てられていないからです。

加えて TigerVNC (CentOS 7 に同梱されている VNC 実装)は第8ボタン以降が使えません。これは VNC Viewer が利用している FLTK (GUI ツールキット)の制限で、ボタンとしては第1〜3ボタンしか走査していないからです。

マウスの第1〜3ボタンは左中右ボタン、第4〜7ボタンはホイールの上下左右、第8〜9ボタンが戻る・進むボタンです。

更に、CentOS 7 同梱の VNC Viewer は漢字キーの操作情報を捨てますw なんとww これは、TigerVNC 1.3 がキー入力情報をホワイトリストで取捨選択しているからです。そもそも FLTK に「漢字キー」が定義されていないので、リストに入るはずもなく、ポイっとw

ちなみに CentOS 6 の TigerVNC 1.1 は、そんな処理してません。最新の 1.8 も、そんな処理してません。

やったこと

前述の不自由を解消するため、やったことは3つです。

  • FLTK に第8〜9ボタンの定義を追加する
  • VNC Viewer に第8〜9ボタンイベントを認識させ、戻るキー・進むキーイベントに変換させる
  • VNC Viewer に漢字キーを捨てるのを止めさせるww

勝手に第8〜9ボタンの定義を追加する

diff -urN fltk-1.3.x-r9671/FL/Enumerations.H fltk-1.3.x-r9671-8th9th/FL/Enumerations.H
--- fltk-1.3.x-r9671/FL/Enumerations.H	2012-03-27 01:54:54.000000000 +0900
+++ fltk-1.3.x-r9671-8th9th/FL/Enumerations.H	2017-09-12 22:00:00.000000000 +0900
@@ -433,6 +433,8 @@
 #define FL_BUTTON1	0x01000000	///< Mouse button 1 is pushed
 #define FL_BUTTON2	0x02000000	///< Mouse button 2 is pushed
 #define FL_BUTTON3	0x04000000	///< Mouse button 3 is pushed
+#define FL_BUTTON8	0x08000000	///< Mouse button 8 is pushed
+#define FL_BUTTON9	0x10000000	///< Mouse button 9 is pushed
 #define FL_BUTTONS	0x7f000000	///< Any mouse button is pushed
 #define FL_BUTTON(n)	(0x00800000<<(n)) ///< Mouse button n (n > 0) is pushed
 
diff -urN fltk-1.3.x-r9671/src/Fl_x.cxx fltk-1.3.x-r9671-8th9th/src/Fl_x.cxx
--- fltk-1.3.x-r9671/src/Fl_x.cxx	2012-06-21 17:52:29.000000000 +0900
+++ fltk-1.3.x-r9671-8th9th/src/Fl_x.cxx	2017-09-12 22:00:00.000000000 +0900
@@ -1520,7 +1520,9 @@
 	Fl::e_dx = +1; // Right
 	event = FL_MOUSEWHEEL;
     } else {
-      Fl::e_state |= (FL_BUTTON1 << (xevent.xbutton.button-1));
+      Fl::e_state |= FL_BUTTON(
+        xevent.xbutton.button <= 7 ? xevent.xbutton.button : xevent.xbutton.button - 4
+      );
       event = FL_PUSH;
       checkdouble();
     }
@@ -1570,7 +1572,9 @@
   case ButtonRelease:
     Fl::e_keysym = FL_Button + xevent.xbutton.button;
     set_event_xy();
-    Fl::e_state &= ~(FL_BUTTON1 << (xevent.xbutton.button-1));
+    Fl::e_state &= ~FL_BUTTON(
+      xevent.xbutton.button <= 7 ? xevent.xbutton.button : xevent.xbutton.button - 4
+    );
     if (xevent.xbutton.button == Button4 ||
         xevent.xbutton.button == Button5) return 0;
     event = FL_RELEASE;

本件と関係ないですが、第4〜5ボタンのリリースイベントを捨てているところ、第6〜7ボタンも捨てないとダメな気がしますが、まぁ、もう古い実装なので。。。
(第4〜7ボタンは、ボタンイベントではなくホイールイベントとして伝達されます。)

条件演算子はインライン関数にすべきですねぇ。せっかく C++ なのに。

TigerVNC にパッチ

戻れ・進め
diff --git a/vncviewer/Viewport.cxx b/vncviewer/Viewport.cxx
index 9fd849f..5b018e6 100644
--- a/vncviewer/Viewport.cxx
+++ b/vncviewer/Viewport.cxx
@@ -422,6 +422,13 @@ int Viewport::handle(int event)
     } 
 
     handlePointerEvent(Point(Fl::event_x() - x(), Fl::event_y() - y()), buttonMask);
+
+    if (Fl::event_buttons() & FL_BUTTON8) {
+      handleKeyEvent(FL_Forward, FL_Forward, "", (event == FL_PUSH));
+    }
+    if (Fl::event_buttons() & FL_BUTTON9) {
+      handleKeyEvent(FL_Back, FL_Back, "", (event == FL_PUSH));
+    }
     return 1;
 
   case FL_FOCUS:
捨てるな漢字
diff --git a/vncviewer/Viewport.cxx b/vncviewer/Viewport.cxx
index 9fd849f..7820877 100644
--- a/vncviewer/Viewport.cxx
+++ b/vncviewer/Viewport.cxx
@@ -737,6 +737,9 @@ rdr::U32 Viewport::translateKeyEvent(int keyCode, int origKe
yCode, const char *k
   case XK_Multi_key:
     // Same for this...
     return XK_Multi_key;
+  case XK_Zenkaku_Hankaku:
+    // pass through to control IM
+    return XK_Zenkaku_Hankaku;
   }
 
   // Unknown special key?

おわりに

RFB を拡張して純粋に第8〜9ボタンの透過伝達を実現することは、今回は見送りました。現状の改修内容だと VNC Server 側は既存のものがそのまま使える利点があります。

というか、最近はマウスボタンが16個まで認識されるようなので、もしかしたら既に RFB が拡張されているのかも。そこも特に調べませんでした。

そのぶん、バイナリパッチ並のクイックハックに収まっていると思うので、ヨシとします。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?