Re: [Spice-devel] [spice-gtk] [PATCH] Provide a method to check if a USB device matches a specific class, subclass and protocol

2014-11-11 Thread Cody Chan
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

2014-11-11 Thread Pavel Grunt
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

2014-11-11 Thread Zeeshan Ali (Khattak)
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

2014-11-11 Thread Marc-André Lureau
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