From 73cf6bd52c282acc1cdb67724d2b55d3f822f7ef Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Wed, 19 Jan 2011 16:23:45 +0000 Subject: [PATCH] device: Allow enabling/disabling non-master devices Slave and floating devices should always be disabled, and not deliver events to the scene. It is up to the user to enable non-master devices and handle events coming from them. ClutterInputDevice gets a new :enabled property, defaulting to FALSE; when a device manager creates a new device it has to set it to TRUE if the :device-mode property is set to CLUTTER_INPUT_MODE_MASTER. The main event queue entry point, _clutter_event_push(), will automatically discard events coming from disabled devices. --- clutter/clutter-device-manager-private.h | 3 +- clutter/clutter-event.c | 9 +++ clutter/clutter-input-device.c | 66 +++++++++++++++++++ clutter/clutter-input-device.h | 3 + clutter/x11/clutter-device-manager-core-x11.c | 3 + clutter/x11/clutter-device-manager-xi2.c | 10 ++- tests/interactive/test-devices.c | 10 ++- 7 files changed, 100 insertions(+), 4 deletions(-) diff --git a/clutter/clutter-device-manager-private.h b/clutter/clutter-device-manager-private.h index a316f2c68..210995170 100644 --- a/clutter/clutter-device-manager-private.h +++ b/clutter/clutter-device-manager-private.h @@ -103,7 +103,8 @@ struct _ClutterInputDevice gint min_keycode; gint max_keycode; - guint has_cursor : 1; + guint has_cursor : 1; + guint is_enabled : 1; }; struct _ClutterInputDeviceClass diff --git a/clutter/clutter-event.c b/clutter/clutter-event.c index a5908a473..47264a773 100644 --- a/clutter/clutter-event.c +++ b/clutter/clutter-event.c @@ -832,10 +832,19 @@ _clutter_event_push (const ClutterEvent *event, gboolean do_copy) { ClutterMainContext *context = _clutter_context_get_default (); + ClutterInputDevice *device; /* FIXME: check queue is valid */ g_assert (context != NULL); + /* disabled devices don't propagate events */ + device = clutter_event_get_device (event); + if (device != NULL) + { + if (!clutter_input_device_get_enabled (device)) + return; + } + if (do_copy) { ClutterEvent *copy; diff --git a/clutter/clutter-input-device.c b/clutter/clutter-input-device.c index 261d24c7c..12ae2e2de 100644 --- a/clutter/clutter-input-device.c +++ b/clutter/clutter-input-device.c @@ -59,6 +59,7 @@ enum PROP_DEVICE_MODE, PROP_HAS_CURSOR, + PROP_ENABLED, PROP_N_AXES, @@ -139,6 +140,10 @@ clutter_input_device_set_property (GObject *gobject, self->has_cursor = g_value_get_boolean (value); break; + case PROP_ENABLED: + self->is_enabled = g_value_get_boolean (value); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); break; @@ -190,6 +195,10 @@ clutter_input_device_get_property (GObject *gobject, g_value_set_uint (value, 0); break; + case PROP_ENABLED: + g_value_set_boolean (value, self->is_enabled); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); break; @@ -270,6 +279,13 @@ clutter_input_device_class_init (ClutterInputDeviceClass *klass) FALSE, CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + obj_props[PROP_ENABLED] = + g_param_spec_boolean ("enabled", + P_("Enabled"), + P_("Whether the device is enabled"), + FALSE, + CLUTTER_PARAM_READWRITE); + obj_props[PROP_N_AXES] = g_param_spec_uint ("n-axes", P_("Number of Axes"), @@ -587,6 +603,56 @@ clutter_input_device_get_device_id (ClutterInputDevice *device) return device->id; } +/** + * clutter_input_device_set_enabled: + * @device: a #ClutterInputDevice + * @enabled: %TRUE to enable the @device + * + * Enables or disables a #ClutterInputDevice. + * + * Only devices with a #ClutterInputDevice:device-mode property set + * to %CLUTTER_INPUT_MODE_SLAVE or %CLUTTER_INPUT_MODE_FLOATING can + * be disabled. + * + * Since: 1.6 + */ +void +clutter_input_device_set_enabled (ClutterInputDevice *device, + gboolean enabled) +{ + g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device)); + + enabled = !!enabled; + + if (!enabled && device->device_mode == CLUTTER_INPUT_MODE_MASTER) + return; + + if (device->is_enabled == enabled) + return; + + device->is_enabled = enabled; + + g_object_notify_by_pspec (G_OBJECT (device), obj_props[PROP_ENABLED]); +} + +/** + * clutter_input_device_get_enabled: + * @device: a #ClutterInputDevice + * + * Retrieves whether @device is enabled. + * + * Return value: %TRUE if the device is enabled + * + * Since: 1.6 + */ +gboolean +clutter_input_device_get_enabled (ClutterInputDevice *device) +{ + g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE); + + return device->is_enabled; +} + /** * clutter_input_device_get_device_coords: * @device: a #ClutterInputDevice of type %CLUTTER_POINTER_DEVICE diff --git a/clutter/clutter-input-device.h b/clutter/clutter-input-device.h index 5bd20c42f..6772a3914 100644 --- a/clutter/clutter-input-device.h +++ b/clutter/clutter-input-device.h @@ -138,6 +138,9 @@ ClutterStage * clutter_input_device_get_pointer_stage (ClutterInputDev G_CONST_RETURN gchar * clutter_input_device_get_device_name (ClutterInputDevice *device); ClutterInputMode clutter_input_device_get_device_mode (ClutterInputDevice *device); gboolean clutter_input_device_get_has_cursor (ClutterInputDevice *device); +void clutter_input_device_set_enabled (ClutterInputDevice *device, + gboolean enabled); +gboolean clutter_input_device_get_enabled (ClutterInputDevice *device); guint clutter_input_device_get_n_axes (ClutterInputDevice *device); ClutterInputAxis clutter_input_device_get_axis (ClutterInputDevice *device, diff --git a/clutter/x11/clutter-device-manager-core-x11.c b/clutter/x11/clutter-device-manager-core-x11.c index a13d89480..af3397366 100644 --- a/clutter/x11/clutter-device-manager-core-x11.c +++ b/clutter/x11/clutter-device-manager-core-x11.c @@ -188,6 +188,7 @@ create_device (ClutterDeviceManagerX11 *manager_x11, "device-type", source, "device-mode", CLUTTER_INPUT_MODE_FLOATING, "backend", backend_x11, + "enabled", FALSE, NULL); translate_class_info (retval, info); @@ -581,6 +582,7 @@ default_device: "device-manager", manager_x11, "device-mode", CLUTTER_INPUT_MODE_MASTER, "backend", backend_x11, + "enabled", TRUE, NULL); CLUTTER_NOTE (BACKEND, "Added core pointer device"); @@ -592,6 +594,7 @@ default_device: "device-manager", manager_x11, "device-mode", CLUTTER_INPUT_MODE_MASTER, "backend", backend_x11, + "enabled", TRUE, NULL); CLUTTER_NOTE (BACKEND, "Added core keyboard device"); diff --git a/clutter/x11/clutter-device-manager-xi2.c b/clutter/x11/clutter-device-manager-xi2.c index 5aa723cf9..e9fbbdb68 100644 --- a/clutter/x11/clutter-device-manager-xi2.c +++ b/clutter/x11/clutter-device-manager-xi2.c @@ -159,6 +159,7 @@ create_device (ClutterDeviceManagerXI2 *manager_xi2, ClutterInputDeviceType source; ClutterInputDevice *retval; ClutterInputMode mode; + gboolean is_enabled; if (info->use == XIMasterKeyboard || info->use == XISlaveKeyboard) source = CLUTTER_KEYBOARD_DEVICE; @@ -185,16 +186,19 @@ create_device (ClutterDeviceManagerXI2 *manager_xi2, case XIMasterKeyboard: case XIMasterPointer: mode = CLUTTER_INPUT_MODE_MASTER; + is_enabled = TRUE; break; case XISlaveKeyboard: case XISlavePointer: mode = CLUTTER_INPUT_MODE_SLAVE; + is_enabled = FALSE; break; case XIFloatingSlave: default: mode = CLUTTER_INPUT_MODE_FLOATING; + is_enabled = FALSE; break; } @@ -206,6 +210,7 @@ create_device (ClutterDeviceManagerXI2 *manager_xi2, "device-type", source, "device-mode", mode, "backend", backend_x11, + "enabled", is_enabled, NULL); translate_device_classes (backend_x11->xdpy, retval, @@ -655,11 +660,14 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, event->key.unicode_value = (gunichar) '\0'; } - CLUTTER_NOTE (EVENT, "%s: win:0x%x, key: %12s (%d)", + CLUTTER_NOTE (EVENT, + "%s: win:0x%x device:%d source:%d, key: %12s (%d)", event->any.type == CLUTTER_KEY_PRESS ? "key press " : "key release", (unsigned int) stage_x11->xwin, + xev->deviceid, + xev->sourceid, event->key.keyval ? buffer : "(none)", event->key.keyval); diff --git a/tests/interactive/test-devices.c b/tests/interactive/test-devices.c index b311f8986..f38e3285e 100644 --- a/tests/interactive/test-devices.c +++ b/tests/interactive/test-devices.c @@ -196,15 +196,21 @@ test_devices_main (int argc, char **argv) ClutterInputDeviceType device_type; ClutterActor *hand = NULL; - g_print ("got a %s device '%s' with id %d...\n", + 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_EXTENSION_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",