I've got an embedded device running Linux/X11 that is connected to a device that provides touch events over a USB connection. This device is not recognized as any form of standard pointer/mouse input. What I'm trying to do is find a way to "inject" mouse events into X11 when the external device reports an event.
Doing so would remove the need for my application ( written in C using Gtk+ ) to fake mouse presses with Gtk+ calls.
If this can be done my Gtk+ application would not need to know or care about the device generating the touch events. It would just appear to the application as standard mouse events.
Anybody know how to go about inserting synthetic mouse events into X11?
Right now I'm doing the following which works, but isn't optimal.
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 );
}
There are several methods.
XSendEvent
. Caveat: some application frameworks ignore events sent with XSendEvent
. I think Gtk+ doesn't, but I have not checked.XTestFakeMotionEvent
and XTestFakeButtonEvent
. You need XTest extension on your X server.The Linux input system has a facility for user-space implementation of input devices called uinput. You can write a background program that uses your device's callback library to send input events to the kernel. The X server (assuming it is using the evdev input module) would then process these just as any other mouse event.
There's a library called libsuinput that makes this fairly easy to do. It even includes an example mouse input program that you can probably use as a model. However, since your device is a touch-based device it will probably use absolute axes (ABS_X, ABS_Y) instead of relative (REL_X, REL_Y).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With