+static const struct shuttle_dev {
+ const char *path;
+ unsigned vendor, product;
+} shuttle_devs[] = {
+ { "/dev/input/by-id/usb-Contour_Design_ShuttleXpress-event-if00",
+ 0x0b33, 0x0020 },
+ { "/dev/input/by-id/usb-Contour_Design_ShuttleXpress-event-mouse",
+ 0x0b33, 0x0020 },
+ { "/dev/input/by-id/usb-Contour_Design_ShuttlePRO_v2-event-if00",
+ 0x0b33, 0x0030 },
+ { "/dev/input/by-id/usb-Contour_Design_ShuttlePRO_v2-event-mouse",
+ 0x0b33, 0x0030 },
+ { "/dev/input/by-id/usb-Contour_Design_ShuttlePro-event-if00",
+ 0x0b33, 0x0030 },
+ { "/dev/input/by-id/usb-Contour_Design_ShuttlePro-event-mouse",
+ 0x0b33, 0x0030 },
+ { "/dev/input/by-id/usb-Contour_Design_ShuttlePRO_v2-event-joystick",
+ 0x0b33, 0x0030 },
+};
+
+#ifdef HAVE_SHUTTLE_USB
+void Shuttle::usb_probe(int idx)
+{
+ int ret = libusb_init(0);
+ if( ret < 0 ) return;
+ claimed = 0;
+ const struct shuttle_dev *s = &shuttle_devs[idx];
+ devsh = libusb_open_device_with_vid_pid(0, s->vendor, s->product);
+ if( devsh ) {
+ int sh_iface = SHUTTLE_INTERFACE;
+ libusb_detach_kernel_driver(devsh, sh_iface);
+ ret = libusb_claim_interface(devsh, sh_iface);
+ if( ret >= 0 ) claimed = 1;
+ }
+ if( !claimed )
+ usb_done();
+}
+
+void Shuttle::usb_done()
+{
+ if( devsh ) {
+ if( claimed > 0 ) {
+ int sh_iface = SHUTTLE_INTERFACE;
+ libusb_release_interface(devsh, sh_iface);
+ libusb_attach_kernel_driver(devsh, sh_iface);
+ claimed = 0;
+ }
+ libusb_close(devsh);
+ devsh = 0;
+ }
+ if( claimed >= 0 ) {
+ libusb_exit(0);
+ claimed = -1;
+ }
+}
+#endif
+
+int Shuttle::probe()