diff --git a/clutter/clutter/x11/clutter-device-manager-xi2.c b/clutter/clutter/x11/clutter-device-manager-xi2.c index 8c645cc62..32ddbfc65 100644 --- a/clutter/clutter/x11/clutter-device-manager-xi2.c +++ b/clutter/clutter/x11/clutter-device-manager-xi2.c @@ -29,6 +29,7 @@ #include "clutter-backend-x11.h" #include "clutter-input-device-xi2.h" +#include "clutter-virtual-input-device-x11.h" #include "clutter-stage-x11.h" #include "clutter-backend.h" @@ -1678,6 +1679,16 @@ clutter_device_manager_xi2_set_property (GObject *gobject, } } +static ClutterVirtualInputDevice * +clutter_device_manager_xi2_create_virtual_device (ClutterDeviceManager *manager, + ClutterInputDeviceType device_type) +{ + return g_object_new (CLUTTER_TYPE_VIRTUAL_INPUT_DEVICE_X11, + "device-manager", manager, + "device-type", device_type, + NULL); +} + static void clutter_device_manager_xi2_class_init (ClutterDeviceManagerXI2Class *klass) { @@ -1705,6 +1716,7 @@ clutter_device_manager_xi2_class_init (ClutterDeviceManagerXI2Class *klass) manager_class->get_core_device = clutter_device_manager_xi2_get_core_device; manager_class->get_device = clutter_device_manager_xi2_get_device; manager_class->select_stage_events = clutter_device_manager_xi2_select_stage_events; + manager_class->create_virtual_device = clutter_device_manager_xi2_create_virtual_device; } static void diff --git a/clutter/clutter/x11/clutter-virtual-input-device-x11.c b/clutter/clutter/x11/clutter-virtual-input-device-x11.c index a13915b12..704de5d59 100644 --- a/clutter/clutter/x11/clutter-virtual-input-device-x11.c +++ b/clutter/clutter/x11/clutter-virtual-input-device-x11.c @@ -27,6 +27,9 @@ #include +#include "clutter-x11.h" +#include "X11/extensions/XTest.h" + #include "clutter-virtual-input-device.h" #include "x11/clutter-virtual-input-device-x11.h" @@ -61,6 +64,8 @@ clutter_virtual_input_device_x11_notify_button (ClutterVirtualInputDevice *virtu uint32_t button, ClutterButtonState button_state) { + XTestFakeButtonEvent (clutter_x11_get_default_display (), + button, button_state == CLUTTER_BUTTON_STATE_PRESSED, 0); } static void @@ -69,6 +74,21 @@ clutter_virtual_input_device_x11_notify_key (ClutterVirtualInputDevice *virtual_ uint32_t key, ClutterKeyState key_state) { + XTestFakeKeyEvent (clutter_x11_get_default_display (), + key, key_state == CLUTTER_KEY_STATE_PRESSED, 0); +} + +static void +clutter_virtual_input_device_x11_notify_keyval (ClutterVirtualInputDevice *virtual_device, + uint64_t time_us, + uint32_t keyval, + ClutterKeyState key_state) +{ + KeyCode keycode; + + keycode = XKeysymToKeycode (clutter_x11_get_default_display (), keyval); + XTestFakeKeyEvent (clutter_x11_get_default_display (), + keycode, key_state == CLUTTER_KEY_STATE_PRESSED, 0); } static void @@ -86,4 +106,5 @@ clutter_virtual_input_device_x11_class_init (ClutterVirtualInputDeviceX11Class * virtual_input_device_class->notify_absolute_motion = clutter_virtual_input_device_x11_notify_absolute_motion; virtual_input_device_class->notify_button = clutter_virtual_input_device_x11_notify_button; virtual_input_device_class->notify_key = clutter_virtual_input_device_x11_notify_key; + virtual_input_device_class->notify_keyval = clutter_virtual_input_device_x11_notify_keyval; } diff --git a/clutter/configure.ac b/clutter/configure.ac index ad5be7cd4..f334cc1fd 100644 --- a/clutter/configure.ac +++ b/clutter/configure.ac @@ -382,6 +382,22 @@ AS_IF([test "x$SUPPORT_X11" = "x1"], [AC_MSG_ERROR([not found])] ) + # XTEST (required) + AC_MSG_CHECKING([for XTest extension]) + PKG_CHECK_EXISTS([xtst], [have_xtest=yes], [have_xtest=no]) + AS_IF([test "x$have_xtest" = "xyes"], + [ + AC_DEFINE(HAVE_XTEST, [1], [Define to 1 if we have the XTest X extension]) + + X11_LIBS="$X11_LIBS -lXtst" + X11_PC_FILES="$X11_PC_FILES xtst" + X11_EXTS="$X11_EXTS xtst" + + AC_MSG_RESULT([found]) + ], + [AC_MSG_ERROR([Not found])] + ) + # X Generic Extensions (optional) clutter_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $X11_CFLAGS"