Re: [Spice-devel] [spice-gtk] [PATCH] Provide a method to check if a USB device matches a specific class, subclass and protocol
Great! Is there a good way to let it work for windows client? libusb is not fully support for windows... I tried to build libwdi with WDK, but I don't think it's a good way. On Tue, Nov 11, 2014 at 10:29 PM, Fabiano Fidêncio fiden...@redhat.com wrote: As we only can filter USB devices by their Classes and sometimes it is not enough (eg: I do not want to have Keyboard and Mouse, but want to have have Joysticks, being all of them part of HID Class), provide to the applications a way match the device itself with the desired Class, SubClass and Protocol, so the applications refine the filter provided by usbredir. --- This patch was written based on https://bugzilla.gnome.org/show_bug.cgi?id=698430 Any suggestion to have a shorter short-log is welcome :-) --- gtk/map-file | 1 + gtk/spice-glib-sym-file | 1 + gtk/usb-device-manager.c | 96 gtk/usb-device-manager.h | 1 + 4 files changed, 99 insertions(+) diff --git a/gtk/map-file b/gtk/map-file index 9f8d04e..6bbf407 100644 --- a/gtk/map-file +++ b/gtk/map-file @@ -124,6 +124,7 @@ spice_usb_device_manager_get_devices; spice_usb_device_manager_get_devices_with_filter; spice_usb_device_manager_get_type; spice_usb_device_manager_is_device_connected; +spice_usb_device_matches_interface; spice_usb_device_widget_get_type; spice_usb_device_widget_new; spice_usbredir_channel_get_type; diff --git a/gtk/spice-glib-sym-file b/gtk/spice-glib-sym-file index 2189fa5..83f7f18 100644 --- a/gtk/spice-glib-sym-file +++ b/gtk/spice-glib-sym-file @@ -101,6 +101,7 @@ spice_usb_device_manager_get_devices spice_usb_device_manager_get_devices_with_filter spice_usb_device_manager_get_type spice_usb_device_manager_is_device_connected +spice_usb_device_matches_interface spice_usbredir_channel_get_type spice_util_get_debug spice_util_get_version_string diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c index 5013b6c..6749b0d 100644 --- a/gtk/usb-device-manager.c +++ b/gtk/usb-device-manager.c @@ -706,6 +706,30 @@ static gboolean spice_usb_device_manager_get_device_descriptor( return TRUE; } +static gboolean spice_usb_device_manager_get_config_descriptor( +libusb_device *libdev, +struct libusb_config_descriptor **config) +{ +int errcode; +const gchar *errstr; + +g_return_val_if_fail(libdev != NULL, FALSE); +g_return_val_if_fail(config != NULL, FALSE); + +errcode = libusb_get_active_config_descriptor(libdev, config); +if (errcode 0) { +int bus, addr; + +bus = libusb_get_bus_number(libdev); +addr = libusb_get_device_address(libdev); +errstr = spice_usbutil_libusb_strerror(errcode); +g_warning(Cannot get config descriptor for (%p) %d.%d -- %s(%d), + libdev, bus, addr, errstr, errcode); +return FALSE; +} +return TRUE; +} + static gboolean spice_usb_device_manager_get_libdev_vid_pid( libusb_device *libdev, int *vid, int *pid) { @@ -1726,7 +1750,79 @@ gchar *spice_usb_device_get_description(SpiceUsbDevice *device, const gchar *for #endif } +static guint8 spice_usb_device_get_interface_class(libusb_device *libdev) +{ +struct libusb_config_descriptor *config; +guint8 interface_class; + +g_return_val_if_fail(libdev != NULL, 0); + +config = g_malloc(sizeof(*config)); +spice_usb_device_manager_get_config_descriptor(libdev, config); +interface_class = config-interface-altsetting-bInterfaceClass; +libusb_free_config_descriptor(config); + +return interface_class; +} + +static guint8 spice_usb_device_get_interface_subclass(libusb_device *libdev) +{ +struct libusb_config_descriptor *config; +guint8 interface_subclass; + +g_return_val_if_fail(libdev != NULL, 0); + +config = g_malloc(sizeof(*config)); +spice_usb_device_manager_get_config_descriptor(libdev, config); +interface_subclass = config-interface-altsetting-bInterfaceSubClass; +libusb_free_config_descriptor(config); + +return interface_subclass; +} + +static guint8 spice_usb_device_get_interface_protocol(libusb_device *libdev) +{ +struct libusb_config_descriptor *config; +guint8 interface_protocol; + +g_return_val_if_fail(libdev != NULL, 0); + +config = g_malloc(sizeof(*config)); +spice_usb_device_manager_get_config_descriptor(libdev, config); +interface_protocol = config-interface-altsetting-bInterfaceProtocol; +libusb_free_config_descriptor(config); + +return interface_protocol; +} + +/** + * spice_usb_device_matches_interface: + * @device: #SpiceUsbDevice to check if the interface info matches with + * @class: the interface class to be checked + * @subclass: the interface usbclass to be checked + * @protocol; the interface protocol to be checked + * + * Compares if the device's interface class, subclass
[Spice-devel] [PATCH spice-gtk] Release keyboard grab using keyboard shortcut
This commit adds the ability to release the keyboard grab when the release keys (ctrl+alt) are pressed and released. It allows to use keyboard shortcuts (eg alt+tab, alt+f4) on the client. The keyboard is grabbed again when the release keys are pressed and released or when the mouse moves. https://bugs.freedesktop.org/show_bug.cgi?id=85331 --- gtk/spice-widget-priv.h | 2 ++ gtk/spice-widget.c | 47 --- 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/gtk/spice-widget-priv.h b/gtk/spice-widget-priv.h index 9c38e2e..0e1f661 100644 --- a/gtk/spice-widget-priv.h +++ b/gtk/spice-widget-priv.h @@ -109,6 +109,8 @@ struct _SpiceDisplayPrivate { guint key_delayed_id; SpiceGrabSequence *grabseq; /* the configured key sequence */ gboolean*activeseq; /* the currently pressed keys */ +gbooleanseq_pressed; +gbooleankeyboard_grab_released; gintmark; #ifdef WIN32 HHOOK keyboard_hook; diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c index ae11073..6dca60f 100644 --- a/gtk/spice-widget.c +++ b/gtk/spice-widget.c @@ -719,6 +719,8 @@ static void try_keyboard_grab(SpiceDisplay *display) return; if (!d-mouse_have_pointer) return; +if (d-keyboard_grab_released) +return; g_return_if_fail(gtk_widget_is_focus(widget)); @@ -1198,6 +1200,9 @@ static void send_key(SpiceDisplay *display, int scancode, SendKeyType type, gboo if (d-disable_inputs) return; +if (d-keyboard_grab_released) +return; + i = scancode / 32; b = scancode % 32; m = (1 b); @@ -1259,7 +1264,8 @@ static void release_keys(SpiceDisplay *display) } } -static gboolean check_for_grab_key(SpiceDisplay *display, int type, int keyval) +static gboolean check_for_grab_key(SpiceDisplay *display, int type, int keyval, + int check_type, int reset_type) { SpiceDisplayPrivate *d = display-priv; int i; @@ -1267,13 +1273,13 @@ static gboolean check_for_grab_key(SpiceDisplay *display, int type, int keyval) if (!d-grabseq-nkeysyms) return FALSE; -if (type == GDK_KEY_PRESS) { -/* Record the new key press */ +if (type == check_type) { +/* Record the new key */ for (i = 0 ; i d-grabseq-nkeysyms ; i++) if (d-grabseq-keysyms[i] == keyval) d-activeseq[i] = TRUE; -/* Return if any key is not pressed */ +/* Return if any key is missing */ for (i = 0 ; i d-grabseq-nkeysyms ; i++) if (d-activeseq[i] == FALSE) return FALSE; @@ -1281,9 +1287,10 @@ static gboolean check_for_grab_key(SpiceDisplay *display, int type, int keyval) /* resets the whole grab sequence on success */ memset(d-activeseq, 0, sizeof(gboolean) * d-grabseq-nkeysyms); return TRUE; -} else if (type == GDK_KEY_RELEASE) { -/* Any key release resets the whole grab sequence */ +} else if (type == reset_type) { +/* reset key event type resets the whole grab sequence */ memset(d-activeseq, 0, sizeof(gboolean) * d-grabseq-nkeysyms); +d-seq_pressed = FALSE; return FALSE; } else g_warn_if_reached(); @@ -1291,6 +1298,16 @@ static gboolean check_for_grab_key(SpiceDisplay *display, int type, int keyval) return FALSE; } +static gboolean check_for_grab_key_pressed(SpiceDisplay *display, int type, int keyval) +{ +return check_for_grab_key(display, type, keyval, GDK_KEY_PRESS, GDK_KEY_RELEASE); +} + +static gboolean check_for_grab_key_released(SpiceDisplay *display, int type, int keyval) +{ +return check_for_grab_key(display, type, keyval, GDK_KEY_RELEASE, GDK_KEY_PRESS); +} + static void update_display(SpiceDisplay *display) { #ifdef G_OS_WIN32 @@ -1321,7 +1338,7 @@ static gboolean key_event(GtkWidget *widget, GdkEventKey *key) __FUNCTION__, key-type == GDK_KEY_PRESS ? press : release, key-hardware_keycode, key-state, key-group, key-is_modifier); -if (check_for_grab_key(display, key-type, key-keyval)) { +if (!d-seq_pressed check_for_grab_key_pressed(display, key-type, key-keyval)) { g_signal_emit(widget, signals[SPICE_DISPLAY_GRAB_KEY_PRESSED], 0); if (d-mouse_mode == SPICE_MOUSE_MODE_SERVER) { @@ -1330,6 +1347,16 @@ static gboolean key_event(GtkWidget *widget, GdkEventKey *key) else try_mouse_grab(display); } +d-seq_pressed = TRUE; +} else if (d-seq_pressed check_for_grab_key_released(display, key-type, key-keyval)) { +if (!d-keyboard_grab_released) { +d-keyboard_grab_released = TRUE; +try_keyboard_ungrab(display); +} else { +d-keyboard_grab_released = FALSE; +
Re: [Spice-devel] [spice-gtk] [PATCH] Provide a method to check if a USB device matches a specific class, subclass and protocol
On Tue, Nov 11, 2014 at 2:29 PM, Fabiano Fidêncio fiden...@redhat.com wrote: As we only can filter USB devices by their Classes and sometimes it is not enough (eg: I do not want to have Keyboard and Mouse, but want to have have Joysticks, being all of them part of HID Class), provide to the applications a way match the device itself with the desired Class, SubClass and Protocol, so the applications refine the filter provided by usbredir. I don't think its a good idea to create a separate API for this on the device level. I suggest either or both of following: * Extend (if possible without breaking existing API) the existing filtering mechanism for DeviceManager for this. * Provide getters for all these properties on device level so Apps can use that info for different things, including of course to filter devices in a list. This patch was written based on https://bugzilla.gnome.org/show_bug.cgi?id=698430 Any suggestion to have a shorter short-log is welcome :-) After all that practice with this in Boxes, I'm pretty sure you can do much better if you just try a bit. -- Regards, Zeeshan Ali (Khattak) Befriend GNOME: http://www.gnome.org/friends/ ___ Spice-devel mailing list Spice-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/spice-devel
Re: [Spice-devel] [spice-gtk] [PATCH] Provide a method to check if a USB device matches a specific class, subclass and protocol
Hi On Tue, Nov 11, 2014 at 3:29 PM, Fabiano Fidêncio fiden...@redhat.com wrote: As we only can filter USB devices by their Classes and sometimes it is not enough (eg: I do not want to have Keyboard and Mouse, but want to have have Joysticks, being all of them part of HID Class), provide to the applications a way match the device itself with the desired Class, SubClass and Protocol, so the applications refine the filter provided by usbredir. --- This patch was written based on https://bugzilla.gnome.org/show_bug.cgi?id=698430 Any suggestion to have a shorter short-log is welcome :-) Not so much the log, but rather the code could have been made much shorter. I would rather see a spice_usb_device_get_libusb_device() getter tbh. I don't think libusb is going to be replaced any time soon. Hans, could you review too? thanks --- gtk/map-file | 1 + gtk/spice-glib-sym-file | 1 + gtk/usb-device-manager.c | 96 gtk/usb-device-manager.h | 1 + 4 files changed, 99 insertions(+) diff --git a/gtk/map-file b/gtk/map-file index 9f8d04e..6bbf407 100644 --- a/gtk/map-file +++ b/gtk/map-file @@ -124,6 +124,7 @@ spice_usb_device_manager_get_devices; spice_usb_device_manager_get_devices_with_filter; spice_usb_device_manager_get_type; spice_usb_device_manager_is_device_connected; +spice_usb_device_matches_interface; spice_usb_device_widget_get_type; spice_usb_device_widget_new; spice_usbredir_channel_get_type; diff --git a/gtk/spice-glib-sym-file b/gtk/spice-glib-sym-file index 2189fa5..83f7f18 100644 --- a/gtk/spice-glib-sym-file +++ b/gtk/spice-glib-sym-file @@ -101,6 +101,7 @@ spice_usb_device_manager_get_devices spice_usb_device_manager_get_devices_with_filter spice_usb_device_manager_get_type spice_usb_device_manager_is_device_connected +spice_usb_device_matches_interface spice_usbredir_channel_get_type spice_util_get_debug spice_util_get_version_string diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c index 5013b6c..6749b0d 100644 --- a/gtk/usb-device-manager.c +++ b/gtk/usb-device-manager.c @@ -706,6 +706,30 @@ static gboolean spice_usb_device_manager_get_device_descriptor( return TRUE; } +static gboolean spice_usb_device_manager_get_config_descriptor( +libusb_device *libdev, +struct libusb_config_descriptor **config) +{ +int errcode; +const gchar *errstr; + +g_return_val_if_fail(libdev != NULL, FALSE); +g_return_val_if_fail(config != NULL, FALSE); + +errcode = libusb_get_active_config_descriptor(libdev, config); +if (errcode 0) { +int bus, addr; + +bus = libusb_get_bus_number(libdev); +addr = libusb_get_device_address(libdev); +errstr = spice_usbutil_libusb_strerror(errcode); +g_warning(Cannot get config descriptor for (%p) %d.%d -- %s(%d), + libdev, bus, addr, errstr, errcode); +return FALSE; +} +return TRUE; +} + static gboolean spice_usb_device_manager_get_libdev_vid_pid( libusb_device *libdev, int *vid, int *pid) { @@ -1726,7 +1750,79 @@ gchar *spice_usb_device_get_description(SpiceUsbDevice *device, const gchar *for #endif } +static guint8 spice_usb_device_get_interface_class(libusb_device *libdev) +{ +struct libusb_config_descriptor *config; +guint8 interface_class; + +g_return_val_if_fail(libdev != NULL, 0); + +config = g_malloc(sizeof(*config)); +spice_usb_device_manager_get_config_descriptor(libdev, config); +interface_class = config-interface-altsetting-bInterfaceClass; +libusb_free_config_descriptor(config); + +return interface_class; +} + +static guint8 spice_usb_device_get_interface_subclass(libusb_device *libdev) +{ +struct libusb_config_descriptor *config; +guint8 interface_subclass; + +g_return_val_if_fail(libdev != NULL, 0); + +config = g_malloc(sizeof(*config)); +spice_usb_device_manager_get_config_descriptor(libdev, config); +interface_subclass = config-interface-altsetting-bInterfaceSubClass; +libusb_free_config_descriptor(config); + +return interface_subclass; +} + +static guint8 spice_usb_device_get_interface_protocol(libusb_device *libdev) +{ +struct libusb_config_descriptor *config; +guint8 interface_protocol; + +g_return_val_if_fail(libdev != NULL, 0); + +config = g_malloc(sizeof(*config)); +spice_usb_device_manager_get_config_descriptor(libdev, config); +interface_protocol = config-interface-altsetting-bInterfaceProtocol; +libusb_free_config_descriptor(config); + +return interface_protocol; +} + +/** + * spice_usb_device_matches_interface: + * @device: #SpiceUsbDevice to check if the interface info matches with + * @class: the interface class to be checked + * @subclass: the interface usbclass to be checked + * @protocol; the interface protocol