summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2017-07-22 21:11:27 +0100
committerRichard Hughes <richard@hughsie.com>2017-07-22 21:11:27 +0100
commitfd83f8527733251bc0f90319ee51d364cca2ce0d (patch)
tree692399b9fedf041428ed282f84b6f21c0dcb3aa5
parent8b223ea0cb16112b0820e4db5708a2cb6a2a00ed (diff)
downloadgusb-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.c44
-rw-r--r--gusb/gusb-context.h16
-rw-r--r--gusb/gusb-device-private.h2
-rw-r--r--gusb/gusb-device.c48
-rw-r--r--gusb/libgusb.ver6
-rw-r--r--tools/gusb-main.c29
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);