diff options
author | Richard Hughes <richard@hughsie.com> | 2017-07-22 21:11:27 +0100 |
---|---|---|
committer | Richard Hughes <richard@hughsie.com> | 2017-07-22 21:11:27 +0100 |
commit | fd83f8527733251bc0f90319ee51d364cca2ce0d (patch) | |
tree | 692399b9fedf041428ed282f84b6f21c0dcb3aa5 | |
parent | 8b223ea0cb16112b0820e4db5708a2cb6a2a00ed (diff) | |
download | gusb-wip/hughsie/GUsbContextFlags.tar.gz |
Add g_usb_context_set_flags()wip/hughsie/GUsbContextFlags
This allows us to auto-open devices as they are hotplugged.
-rw-r--r-- | gusb/gusb-context.c | 44 | ||||
-rw-r--r-- | gusb/gusb-context.h | 16 | ||||
-rw-r--r-- | gusb/gusb-device-private.h | 2 | ||||
-rw-r--r-- | gusb/gusb-device.c | 48 | ||||
-rw-r--r-- | gusb/libgusb.ver | 6 | ||||
-rw-r--r-- | tools/gusb-main.c | 29 |
6 files changed, 130 insertions, 15 deletions
diff --git a/gusb/gusb-context.c b/gusb/gusb-context.c index fbd56d7..a3a34fb 100644 --- a/gusb/gusb-context.c +++ b/gusb/gusb-context.c @@ -64,6 +64,7 @@ struct _GUsbContextPrivate volatile gint thread_event_run; guint hotplug_poll_id; int debug_level; + GUsbContextFlags flags; libusb_context *ctx; libusb_hotplug_callback_handle hotplug_id; }; @@ -324,6 +325,16 @@ g_usb_context_add_device (GUsbContext *context, goto out; } + /* auto-open */ + if (priv->flags & G_USB_CONTEXT_FLAGS_AUTO_OPEN_DEVICES) { + g_debug ("auto-opening %i:%i", bus, address); + if (!_g_usb_device_open_internal (device, &error)) { + g_warning ("cannot open the device: %s", error->message); + g_error_free (error); + goto out; + } + } + /* add to enumerated list */ g_ptr_array_add (priv->devices, g_object_ref (device)); @@ -527,6 +538,38 @@ g_usb_context_enumerate (GUsbContext *context) priv->done_enumerate = TRUE; } +/** + * g_usb_context_set_flags: + * @context: a #GUsbContext + * @flags: some #GUsbContextFlags, e.g. %G_USB_CONTEXT_FLAGS_AUTO_OPEN_DEVICES + * + * Sets the flags to use for the context. These should be set before + * g_usb_context_enumerate() is called. + * + * Since: 0.2.11 + **/ +void +g_usb_context_set_flags (GUsbContext *context, GUsbContextFlags flags) +{ + context->priv->flags = flags; +} + +/** + * g_usb_context_get_flags: + * @context: a #GUsbContext + * + * Sets the flags to use for the context. + * + * Return value: the #GUsbContextFlags, e.g. %G_USB_CONTEXT_FLAGS_AUTO_OPEN_DEVICES + * + * Since: 0.2.11 + **/ +GUsbContextFlags +g_usb_context_get_flags (GUsbContext *context) +{ + return context->priv->flags; +} + static gpointer g_usb_context_event_thread_cb (gpointer data) { @@ -545,6 +588,7 @@ g_usb_context_init (GUsbContext *context) GUsbContextPrivate *priv; priv = context->priv = g_usb_context_get_instance_private (context); + priv->flags = G_USB_CONTEXT_FLAGS_NONE; priv->devices = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); priv->dict_usb_ids = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); priv->dict_replug = g_hash_table_new_full (g_str_hash, g_str_equal, diff --git a/gusb/gusb-context.h b/gusb/gusb-context.h index 8b59d49..3232d3c 100644 --- a/gusb/gusb-context.h +++ b/gusb/gusb-context.h @@ -63,11 +63,27 @@ typedef enum { G_USB_CONTEXT_ERROR_INTERNAL } GUsbContextError; +/** + * GUsbContextFlags: + * + * The flags to use for the context. + **/ +typedef enum { + G_USB_CONTEXT_FLAGS_NONE = 0, + G_USB_CONTEXT_FLAGS_AUTO_OPEN_DEVICES = 1 << 0, + /*< private >*/ + G_USB_CONTEXT_FLAGS_LAST +} GUsbContextFlags; + GType g_usb_context_get_type (void); GQuark g_usb_context_error_quark (void); GUsbContext *g_usb_context_new (GError **error); +void g_usb_context_set_flags (GUsbContext *context, + GUsbContextFlags flags); +GUsbContextFlags g_usb_context_get_flags (GUsbContext *context); + G_DEPRECATED GUsbSource *g_usb_context_get_source (GUsbContext *context, GMainContext *main_ctx); diff --git a/gusb/gusb-device-private.h b/gusb/gusb-device-private.h index f073141..bceb8be 100644 --- a/gusb/gusb-device-private.h +++ b/gusb/gusb-device-private.h @@ -30,6 +30,8 @@ GUsbDevice *_g_usb_device_new (GUsbContext *context, GError **error); libusb_device *_g_usb_device_get_device (GUsbDevice *device); +gboolean _g_usb_device_open_internal (GUsbDevice *device, + GError **error); G_END_DECLS diff --git a/gusb/gusb-device.c b/gusb/gusb-device.c index c240c81..b16aabe 100644 --- a/gusb/gusb-device.c +++ b/gusb/gusb-device.c @@ -390,6 +390,26 @@ g_usb_device_async_not_open_error (GUsbDevice *device, g_usb_device_get_pid (device)); } +gboolean +_g_usb_device_open_internal (GUsbDevice *device, GError **error) +{ + gint rc; + + if (device->priv->handle != NULL) { + g_set_error (error, + G_USB_DEVICE_ERROR, + G_USB_DEVICE_ERROR_ALREADY_OPEN, + "Device %04x:%04x is already open", + g_usb_device_get_vid (device), + g_usb_device_get_pid (device)); + return FALSE; + } + + /* open device */ + rc = libusb_open (device->priv->device, &device->priv->handle); + return g_usb_device_libusb_error_to_gerror (device, rc, error); +} + /** * g_usb_device_open: * @device: a #GUsbDevice @@ -404,27 +424,19 @@ g_usb_device_async_not_open_error (GUsbDevice *device, * Since: 0.1.0 **/ gboolean -g_usb_device_open (GUsbDevice *device, - GError **error) +g_usb_device_open (GUsbDevice *device, GError **error) { - gint rc; - g_return_val_if_fail (G_USB_IS_DEVICE (device), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - if (device->priv->handle != NULL) { - g_set_error (error, - G_USB_DEVICE_ERROR, - G_USB_DEVICE_ERROR_ALREADY_OPEN, - "Device %04x:%04x is already open", - g_usb_device_get_vid (device), - g_usb_device_get_pid (device)); - return FALSE; + /* ignore */ + if (g_usb_context_get_flags (device->priv->context) & G_USB_CONTEXT_FLAGS_AUTO_OPEN_DEVICES) { + g_debug ("using AUTO_OPEN_DEVICES, ignoring"); + return TRUE; } - /* open device */ - rc = libusb_open (device->priv->device, &device->priv->handle); - return g_usb_device_libusb_error_to_gerror (device, rc, error); + /* open */ + return _g_usb_device_open_internal (device, error); } /** @@ -608,6 +620,12 @@ g_usb_device_close (GUsbDevice *device, g_return_val_if_fail (G_USB_IS_DEVICE (device), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + /* ignore */ + if (g_usb_context_get_flags (device->priv->context) & G_USB_CONTEXT_FLAGS_AUTO_OPEN_DEVICES) { + g_debug ("using AUTO_OPEN_DEVICES, ignoring"); + return TRUE; + } + if (device->priv->handle == NULL) return g_usb_device_not_open_error (device, error); diff --git a/gusb/libgusb.ver b/gusb/libgusb.ver index fc6f922..c4f9181 100644 --- a/gusb/libgusb.ver +++ b/gusb/libgusb.ver @@ -62,3 +62,9 @@ LIBGUSB_0.2.9 { global: g_usb_context_wait_for_replug; } LIBGUSB_0.2.8; + +LIBGUSB_0.2.11 { + global: + g_usb_context_set_flags; + g_usb_context_get_flags; +} LIBGUSB_0.2.9; diff --git a/tools/gusb-main.c b/tools/gusb-main.c index 234115c..7626719 100644 --- a/tools/gusb-main.c +++ b/tools/gusb-main.c @@ -158,6 +158,32 @@ gusb_cmd_get_descriptions (GPtrArray *array) return g_string_free (string, FALSE); } +static void +gusb_main_device_open (GUsbDevice *device) +{ + GError *error = NULL; + guint8 idx; + + /* open */ + if (!g_usb_device_open (device, &error)) { + g_print ("failed to open: %s\n", error->message); + g_error_free (error); + return; + } + + /* print info we can only get whilst open */ + idx = g_usb_device_get_product_index (device); + if (idx != 0x00) { + gchar *product = g_usb_device_get_string_descriptor (device, idx, &error); + if (product == NULL) { + g_print ("failed to get string desc: %s\n", error->message); + g_error_free (error); + return; + } + g_print ("product: %s\n", product); + } +} + /** * gusb_device_list_added_cb: **/ @@ -170,6 +196,7 @@ gusb_device_list_added_cb (GUsbContext *context, g_usb_device_get_platform_id (device), g_usb_device_get_bus (device), g_usb_device_get_address (device)); + gusb_main_device_open (device); } /** @@ -339,6 +366,7 @@ gusb_cmd_watch (GUsbCmdPrivate *priv, gchar **values, GError **error) g_usb_device_get_platform_id (device), g_usb_device_get_bus (device), g_usb_device_get_address (device)); + gusb_main_device_open (device); } loop = g_main_loop_new (NULL, FALSE); @@ -478,6 +506,7 @@ main (int argc, char *argv[]) /* GUsbContext */ priv->usb_ctx = g_usb_context_new (NULL); + g_usb_context_set_flags (priv->usb_ctx, G_USB_CONTEXT_FLAGS_AUTO_OPEN_DEVICES); /* add commands */ priv->cmd_array = g_ptr_array_new_with_free_func ((GDestroyNotify) gusb_cmd_item_free); |