2012-04-25 10 views
11

USB接続でタッチイベントを提供するデバイスに接続されているLinux/X11を搭載した組み込みデバイスがあります。このデバイスは、標準的なポインタ/マウス入力の形式として認識されません。私がしようとしているのは、外部デバイスがイベントを報告したときにマウスイベントをX11に「注入」する方法です。合成マウスイベントをX11入力キューに挿入する方法

これを行うと、Gtk +でマウスを押すことを偽装するために、私のアプリケーション(Gtk +を使ってCで書かれている)が不要になります。

私のGtk +アプリケーションは、タッチイベントを生成するデバイスを知っていたり気にする必要はありません。標準のマウスイベントとしてアプリケーションに表示されます。

誰もが合成マウスイベントをX11に挿入する方法を知っていますか?

今私は以下のことをしていますが、最適ではありません。

GtkWidget *btnSpin;  /* sample button */ 

gboolean buttonPress_cb(void *btn); 
gboolean buttonDePress_cb(void *btn); 


/* make this call after the device library calls the TouchEvent_cb() callback 
    and the application has determined which, if any, button was touched 

    In this example we are assuming btnSpin was touched. 

    This function will, in 5ms, begin the process of causing the button to do it's 
    normal animation (button in, button out effects) and then send the actual 
    button_clicked event to the button. 
*/ 
g_timeout_add(5, (GSourceFunc) buttonPress_cb, (void *)btnSpin); 


/* this callback is fired 5ms after the g_timeout_add() function above. 
    It first sets the button state to ACTIVE to begin the animation cycle (pressed look) 
    And then 250ms later calls buttonDePress_cb which will make the button look un-pressed 
    and then send the button_clicked event. 
*/  
gboolean buttonPress_cb(void *btn) 
{ 

    gtk_widget_set_state((GtkWidget *)btn, GTK_STATE_ACTIVE); 
    g_timeout_add(250, (GSourceFunc) buttonDePress_cb, btn); 


    return(FALSE); 
} 

/* Sets button state back to NORMAL (not pressed look) 
    and sends the button_clicked event so that the registered signal handler for the 
    button can be activated 
*/ 
gboolean buttonDePress_cb(void *btn) 
{ 

    gtk_widget_set_state(btn, GTK_STATE_NORMAL); 
    gtk_button_clicked(GTK_BUTTON(btn)); 

    return(FALSE); 
} 

答えて

9

Linux入力システムには、uinputと呼ばれる入力デバイスをユーザー空間で実装する機能があります。あなたのデバイスのコールバックライブラリを使って入力イベントをカーネルに送るバックグラウンドプログラムを書くことができます。 Xサーバ(evdev入力モジュールを使用していると仮定)は、他のマウスイベントと同様にこれらを処理します。

libsuinputというライブラリがあり、これはかなり簡単です。おそらくモデルとして使用できるexample mouse input programも含まれています。ただし、デバイスはタッチベースのデバイスなので、relative(REL_X、REL_Y)の代わりに絶対軸(ABS_X、ABS_Y)を使用することがあります。

+0

優秀な..これはちょうど答えかもしれません。私の組み込みLinuxデバイスが 'uinput'システムをサポートしているかどうかを確認する必要があります。 ありがとうございます。 – Chimera

9

いくつかの方法があります。

  1. ​​を使用してください。警告:一部のアプリケーションフレームワークでは、​​で送信されたイベントは無視されます。私はGtk +はしないと思うが、私はチェックしていない。
  2. XTestFakeMotionEventおよびXTestFakeButtonEventを使用してください。 XサーバにXTest拡張機能が必要です。
  3. デバイスのカーネルドライバを作成し、マウス/タッチパッドとして表示されるようにします。
+0

ありがとうございました。 – Chimera

6

カーネル内にデバイスドライバを実装して、evdevプロトコルを使用する/dev/input/eventXファイルを作成するのが最もクールです。これを行うには、Linux Device Driversという本を読むことをお勧めします。この本はウェブ上で自由に入手できます。

ユーザー空間でこれを行う場合は、Xlib(またはXCB)を使用することをお勧めします。プレーンXlib(C言語)では、X Test ExtensionまたはXSendEvent()を使用できます。

xautomationパッケージ(Debianではsudo apt-get install xautomation、その後はman xte)からxteというバイナリもあります。 xteは非常に使いやすく、そのソースコードを見てX Test Extensionの使い方を学ぶこともできます。

ポインタ:

+0

詳細な回答ありがとうございます。 – Chimera

1

AFTEこと思えますGtk +は、X11のコーディングやカーネルドライバの作成に深く掘り下げずに、自分が望むことができるGDKライブラリを使用しています。しかし、時間があったとしても、私はLinuxカーネルマウスドライバを書く方が好きです。私は次の操作を行うことができたGDK 2 Reference Manual使用

GdkEventButton用タイプのGdkEventGdkEventButton

に構造を付加する

使用gtk_event_put()は次のとおりです。

struct GdkEventButton { 
    GdkEventType type; 
    GdkWindow *window; 
    gint8 send_event; 
    guint32 time; 
    gdouble x; 
    gdouble y; 
    gdouble *axes; 
    guint state; 
    guint button; 
    GdkDevice *device; 
    gdouble x_root, y_root; 
}; 

これらのフィールドのほとんどは

を除いて記入するのは簡単です。

私は画面の相対座標を変換する方法を研究する必要があります。

*device - 拡張入力デバイスのため、このフィールド(NULLに設定)を使用する必要があるかどうかはわかりません。しかし、ここで有効なデバイスを用意する必要がある場合、私は使用できるはずですgdk_devices_list()

関連する問題