diff --git a/clutter/x11/clutter-device-manager-xi2.c b/clutter/x11/clutter-device-manager-xi2.c index 13c814871..bb438d56b 100644 --- a/clutter/x11/clutter-device-manager-xi2.c +++ b/clutter/x11/clutter-device-manager-xi2.c @@ -235,9 +235,6 @@ add_device (ClutterDeviceManagerXI2 *manager_xi2, /* we don't go through the DeviceManager::add_device() vfunc because * that emits the signal, and we only do it conditionally - * - * FIXME: add a boolean "emit_signal" argument to the add_device() - * wrapper in ClutterDeviceManager, and emit the signal only if true */ g_hash_table_replace (manager_xi2->devices_by_id, GINT_TO_POINTER (info->deviceid), @@ -329,6 +326,8 @@ translate_hierarchy_event (ClutterBackendX11 *backend_x11, XIDeviceInfo *info; int n_devices; + CLUTTER_NOTE (EVENT, "Hierarchy event: device enabled"); + info = XIQueryDevice (backend_x11->xdpy, ev->info[i].deviceid, &n_devices); @@ -336,6 +335,8 @@ translate_hierarchy_event (ClutterBackendX11 *backend_x11, } else if (ev->info[i].flags & XIDeviceDisabled) { + CLUTTER_NOTE (EVENT, "Hierarchy event: device disabled"); + remove_device (manager_xi2, ev->info[i].deviceid); } else if ((ev->info[i].flags & XISlaveAttached) || @@ -345,6 +346,11 @@ translate_hierarchy_event (ClutterBackendX11 *backend_x11, XIDeviceInfo *info; int n_devices; + CLUTTER_NOTE (EVENT, "Hierarchy event: slave %s", + (ev->info[i].flags & XISlaveAttached) + ? "attached" + : "detached"); + slave = g_hash_table_lookup (manager_xi2->devices_by_id, GINT_TO_POINTER (ev->info[i].deviceid)); master = clutter_input_device_get_associated_device (slave); @@ -533,8 +539,8 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, ClutterDeviceManagerXI2 *manager_xi2 = CLUTTER_DEVICE_MANAGER_XI2 (translator); ClutterTranslateReturn retval = CLUTTER_TRANSLATE_CONTINUE; ClutterBackendX11 *backend_x11; - ClutterStageX11 *stage_x11; - ClutterStage *stage; + ClutterStageX11 *stage_x11 = NULL; + ClutterStage *stage = NULL; ClutterInputDevice *device; XGenericEventCookie *cookie; XIEvent *xi_event; @@ -558,15 +564,19 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, xi_event = (XIEvent *) cookie->data; - stage = get_event_stage (translator, xi_event); - if (stage == NULL || CLUTTER_ACTOR_IN_DESTRUCTION (stage)) + if (!(xi_event->evtype == XI_HierarchyChanged || + xi_event->evtype == XI_DeviceChanged)) { - XFreeEventData (backend_x11->xdpy, cookie); - return CLUTTER_TRANSLATE_CONTINUE; + stage = get_event_stage (translator, xi_event); + if (stage == NULL || CLUTTER_ACTOR_IN_DESTRUCTION (stage)) + { + XFreeEventData (backend_x11->xdpy, cookie); + return CLUTTER_TRANSLATE_CONTINUE; + } + else + stage_x11 = CLUTTER_STAGE_X11 (_clutter_stage_get_window (stage)); } - stage_x11 = CLUTTER_STAGE_X11 (_clutter_stage_get_window (stage)); - event->any.stage = stage; switch (xi_event->evtype) diff --git a/tests/interactive/test-devices.c b/tests/interactive/test-devices.c index f38e3285e..e68a26d11 100644 --- a/tests/interactive/test-devices.c +++ b/tests/interactive/test-devices.c @@ -4,9 +4,9 @@ #include typedef struct { + ClutterActor *stage; GHashTable *devices; - } TestDevicesApp; static const gchar * @@ -77,11 +77,10 @@ axis_type_name (ClutterInputAxis axis) } static gboolean -stage_button_event_cb (ClutterActor *actor, - ClutterEvent *event, - gpointer userdata) +stage_button_event_cb (ClutterActor *actor, + ClutterEvent *event, + TestDevicesApp *app) { - TestDevicesApp *app = (TestDevicesApp *)userdata; ClutterInputDevice *device; ClutterInputDevice *source_device; ClutterActor *hand = NULL; @@ -128,11 +127,10 @@ stage_button_event_cb (ClutterActor *actor, } static gboolean -stage_motion_event_cb (ClutterActor *actor, - ClutterEvent *event, - gpointer userdata) +stage_motion_event_cb (ClutterActor *actor, + ClutterEvent *event, + TestDevicesApp *app) { - TestDevicesApp *app = (TestDevicesApp *)userdata; ClutterInputDevice *device; ClutterActor *hand = NULL; @@ -152,6 +150,65 @@ stage_motion_event_cb (ClutterActor *actor, return FALSE; } +static void +manager_device_added_cb (ClutterDeviceManager *manager, + ClutterInputDevice *device, + TestDevicesApp *app) +{ + ClutterInputDeviceType device_type; + ClutterActor *hand = NULL; + + g_print ("got a %s device '%s' with id %d\n", + device_type_name (device), + clutter_input_device_get_device_name (device), + clutter_input_device_get_device_id (device)); + + device_type = clutter_input_device_get_device_type (device); + if (device_type == CLUTTER_POINTER_DEVICE || + device_type == CLUTTER_PEN_DEVICE || + device_type == CLUTTER_POINTER_DEVICE) + { + g_print ("*** enabling device '%s' ***\n", + clutter_input_device_get_device_name (device)); + + clutter_input_device_set_enabled (device, TRUE); + + hand = clutter_texture_new_from_file (TESTS_DATADIR + G_DIR_SEPARATOR_S + "redhand.png", + NULL); + g_hash_table_insert (app->devices, device, hand); + + clutter_container_add_actor (CLUTTER_CONTAINER (app->stage), hand); + } +} + +static void +manager_device_removed_cb (ClutterDeviceManager *manager, + ClutterInputDevice *device, + TestDevicesApp *app) +{ + ClutterInputDeviceType device_type; + ClutterActor *hand = NULL; + + g_print ("removed a %s device '%s' with id %d\n", + device_type_name (device), + clutter_input_device_get_device_name (device), + clutter_input_device_get_device_id (device)); + + device_type = clutter_input_device_get_device_type (device); + if (device_type == CLUTTER_POINTER_DEVICE || + device_type == CLUTTER_PEN_DEVICE || + device_type == CLUTTER_POINTER_DEVICE) + { + hand = g_hash_table_lookup (app->devices, device); + if (hand != NULL) + clutter_container_add_actor (CLUTTER_CONTAINER (app->stage), hand); + + g_hash_table_remove (app->devices, device); + } +} + G_MODULE_EXPORT int test_devices_main (int argc, char **argv) { @@ -181,10 +238,18 @@ test_devices_main (int argc, char **argv) g_signal_connect (stage, "button-press-event", G_CALLBACK (stage_button_event_cb), app); + app->stage = stage; clutter_actor_show_all (stage); manager = clutter_device_manager_get_default (); + g_signal_connect (manager, + "device-added", G_CALLBACK (manager_device_added_cb), + app); + g_signal_connect (manager, + "device-removed", G_CALLBACK (manager_device_removed_cb), + app); + stage_devices = clutter_device_manager_peek_devices (manager); if (stage_devices == NULL)