summaryrefslogtreecommitdiff
path: root/src/usb-device-manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/usb-device-manager.c')
-rw-r--r--src/usb-device-manager.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/src/usb-device-manager.c b/src/usb-device-manager.c
index 0f8134f..312dae7 100644
--- a/src/usb-device-manager.c
+++ b/src/usb-device-manager.c
@@ -1676,6 +1676,26 @@ gboolean spice_usb_device_manager_connect_device_finish(
return g_task_propagate_boolean(task, err);
}
+/**
+ * spice_usb_device_manager_disconnect_device_finish:
+ * @self: a #SpiceUsbDeviceManager.
+ * @res: a #GAsyncResult
+ * @err: (allow-none): a return location for a #GError, or %NULL.
+ *
+ * Finishes an async operation. See spice_usb_device_manager_disconnect_device_async().
+ *
+ * Returns: %TRUE if disconnection is successful
+ */
+gboolean spice_usb_device_manager_disconnect_device_finish(
+ SpiceUsbDeviceManager *self, GAsyncResult *res, GError **err)
+{
+ GTask *task = G_TASK(res);
+
+ g_return_val_if_fail(g_task_is_valid(task, G_OBJECT(self)), FALSE);
+
+ return g_task_propagate_boolean(task, err);
+}
+
#ifdef USE_USBREDIR
static
void _connect_device_async_cb(GObject *gobject,
@@ -1722,6 +1742,70 @@ void spice_usb_device_manager_disconnect_device(SpiceUsbDeviceManager *self,
#endif
}
+typedef struct _disconnect_cb_data
+{
+ SpiceUsbDeviceManager *self;
+ SpiceUsbDevice *device;
+} disconnect_cb_data;
+
+#ifdef USE_USBREDIR
+static
+void _disconnect_device_async_cb(GObject *gobject,
+ GAsyncResult *channel_res,
+ gpointer user_data)
+{
+ SpiceUsbredirChannel *channel = SPICE_USBREDIR_CHANNEL(gobject);
+ GTask *task = user_data;
+ GError *err = NULL;
+
+#ifdef G_OS_WIN32
+ disconnect_cb_data *data = g_task_get_task_data(task);
+ SpiceUsbDeviceManager *self = SPICE_USB_DEVICE_MANAGER(data->self);
+
+ if (self->priv->use_usbclerk) {
+ _spice_usb_device_manager_uninstall_driver_async(self, data->device);
+ }
+#endif
+
+ spice_usbredir_channel_disconnect_device_finish(channel, channel_res, &err);
+ if (err)
+ g_task_return_error(task, err);
+ else
+ g_task_return_boolean(task, TRUE);
+
+ g_object_unref(task);
+}
+#endif
+
+void spice_usb_device_manager_disconnect_device_async(SpiceUsbDeviceManager *self,
+ SpiceUsbDevice *device,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+#ifdef USE_USBREDIR
+ GTask *nested;
+ g_return_if_fail(SPICE_IS_USB_DEVICE_MANAGER(self));
+
+ g_return_if_fail(device != NULL);
+
+ SPICE_DEBUG("disconnecting device %p", device);
+
+ SpiceUsbredirChannel *channel;
+
+ channel = spice_usb_device_manager_get_channel_for_dev(self, device);
+ nested = g_task_new(G_OBJECT(self), cancellable, callback, user_data);
+ disconnect_cb_data *data = g_new(disconnect_cb_data, 1);
+ data->self = self;
+ data->device = device;
+ g_task_set_task_data(nested, data, g_free);
+
+ spice_usbredir_channel_disconnect_device_async(channel, cancellable,
+ _disconnect_device_async_cb,
+ nested);
+#endif
+}
+
/**
* spice_usb_device_manager_can_redirect_device:
* @self: the #SpiceUsbDeviceManager manager