kopia lustrzana https://github.com/FreeSpacenav/spacenavd
Wireless device detection, and CadMouse avoidance logic
New 3dconnexion devices seem to all use the same dongle with USB id 256f:c526. That includes at least the SpaceMouse Wireless and the CadMouse Wireless. This is a set of hacks to guess what's connected and act accordingly: - Drop the CadMouse (num_axes == 0) - Enable the button hack if it's a SpaceMouse Pro Wireless - Detect SpaceMouse Wirless and update name/type. Also added a test for the assumption that devices marked for button remapping always report 255-256 buttons. If that's not the case undo the button-hack and ask the user to report it as a bug.pull/65/head
rodzic
21d90d0db6
commit
3e1cbc52ef
11
src/dev.c
11
src/dev.c
|
@ -35,8 +35,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#endif
|
||||
|
||||
|
||||
#define VENDOR_3DCONNEXION 0x256f
|
||||
|
||||
/* The device flags are introduced to normalize input across all known
|
||||
* supported 6dof devices. Newer USB devices seem to use axis 1 as fwd/back and
|
||||
* axis 2 as up/down, while older serial devices (and possibly also the early
|
||||
|
@ -57,9 +55,6 @@ enum {
|
|||
* actual buttons when a negative number is passed as argument, and the button
|
||||
* mapping otherwise.
|
||||
*/
|
||||
int bnhack_smpro(int bn);
|
||||
int bnhack_sment(int bn);
|
||||
|
||||
static struct usbdb_entry {
|
||||
int usbid[2];
|
||||
int type;
|
||||
|
@ -76,7 +71,7 @@ static struct usbdb_entry {
|
|||
{{0x046d, 0xc627}, DEV_SEXP, DF_SWAPYZ | DF_INVYZ, 0}, /* space explorer */
|
||||
{{0x046d, 0xc628}, DEV_SNAVNB, DF_SWAPYZ | DF_INVYZ, 0}, /* space navigator for notebooks*/
|
||||
{{0x046d, 0xc629}, DEV_SPILOTPRO, DF_SWAPYZ | DF_INVYZ, 0}, /* space pilot pro*/
|
||||
{{0x046d, 0xc62b}, DEV_SMPRO, DF_SWAPYZ | DF_INVYZ, 0}, /* space mouse pro*/
|
||||
{{0x046d, 0xc62b}, DEV_SMPRO, DF_SWAPYZ | DF_INVYZ, bnhack_smpro}, /* space mouse pro*/
|
||||
{{0x046d, 0xc640}, DEV_NULOOQ, 0, 0}, /* nulooq */
|
||||
{{0x256f, 0xc62e}, DEV_SMW, DF_SWAPYZ | DF_INVYZ, 0}, /* spacemouse wireless (USB cable) */
|
||||
{{0x256f, 0xc62f}, DEV_SMW, DF_SWAPYZ | DF_INVYZ, 0}, /* spacemouse wireless receiver */
|
||||
|
@ -191,7 +186,7 @@ int init_devices_usb(void)
|
|||
remove_device(dev);
|
||||
} else {
|
||||
/* add the 6dof remapping flags to every future 3dconnexion device */
|
||||
if(dev->usbid[0] == VENDOR_3DCONNEXION) {
|
||||
if(dev->usbid[0] == VID_3DCONN) {
|
||||
dev->flags |= DF_SWAPYZ | DF_INVYZ;
|
||||
}
|
||||
/* sanity-check the device flags */
|
||||
|
@ -395,7 +390,7 @@ static int match_usbdev(const struct usb_dev_info *devinfo)
|
|||
}
|
||||
|
||||
/* match any device with the new 3Dconnexion device id */
|
||||
if(vid == VENDOR_3DCONNEXION) {
|
||||
if(vid == VID_3DCONN) {
|
||||
/* avoid matching and trying to grab the CAD mouse, when connected
|
||||
* on the same universal receiver as the spacemouse.
|
||||
*/
|
||||
|
|
|
@ -18,6 +18,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#ifndef SPNAV_DEV_USB_H_
|
||||
#define SPNAV_DEV_USB_H_
|
||||
|
||||
#define VID_3DCONN 0x256f
|
||||
#define PID_WIRELESS 0xc652
|
||||
|
||||
struct device;
|
||||
|
||||
int open_dev_usb(struct device *dev);
|
||||
|
@ -37,4 +40,8 @@ struct usb_dev_info *find_usb_devices(int (*match)(const struct usb_dev_info*));
|
|||
void free_usb_devices_list(struct usb_dev_info *list);
|
||||
void print_usb_device_info(struct usb_dev_info *devinfo);
|
||||
|
||||
/* see usbdb_entry table bnmap field in dev.c */
|
||||
int bnhack_smpro(int bn);
|
||||
int bnhack_sment(int bn);
|
||||
|
||||
#endif /* SPNAV_DEV_USB_H_ */
|
||||
|
|
|
@ -109,6 +109,15 @@ int open_dev_usb(struct device *dev)
|
|||
}
|
||||
dev->num_axes = axes_rel + axes_abs;
|
||||
if(!dev->num_axes) {
|
||||
if(dev->usbid[0] == VID_3DCONN && dev->usbid[1] == PID_WIRELESS) {
|
||||
/* a wireless 3Dconnexion device without axes is probably one of the
|
||||
* CadMouse products, drop it.
|
||||
*/
|
||||
logmsg(LOG_DEBUG, "No axes detected, probably a CadMouse, dropping\n");
|
||||
close(dev->fd);
|
||||
dev->fd = -1;
|
||||
return -1;
|
||||
}
|
||||
logmsg(LOG_WARNING, "failed to retrieve number of axes. assuming 6\n");
|
||||
dev->num_axes = 6;
|
||||
} else {
|
||||
|
@ -118,25 +127,49 @@ int open_dev_usb(struct device *dev)
|
|||
}
|
||||
|
||||
/* get number of buttons */
|
||||
dev->num_buttons = 0;
|
||||
if(ioctl(dev->fd, EVIOCGBIT(EV_KEY, sizeof evtype_mask), evtype_mask) != -1) {
|
||||
for(i=0; i<KEY_CNT; i++) {
|
||||
int idx = i / 8;
|
||||
int bit = i % 8;
|
||||
|
||||
if(evtype_mask[idx] & (1 << bit)) {
|
||||
dev->num_buttons++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logmsg(LOG_DEBUG, "EVIOCGBIT(EV_KEY) ioctl failed: %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
/* sanity check, problematic devices appear to report 256 buttons, if that's
|
||||
* not the case, this is probably a mistake.
|
||||
*/
|
||||
if(dev->bnhack && dev->num_buttons < 255) {
|
||||
logmsg(LOG_DEBUG, "BUG! Please report this at https://github.com/FreeSpacenav/spacenavd/issues, "
|
||||
"or by sending an email to nuclear@member.fsf.org.\n");
|
||||
logmsg(LOG_DEBUG, "This device (%04x:%04x) was marked for disjointed "
|
||||
"button remapping, but unexpectedly reports %d buttons\n",
|
||||
dev->usbid[0], dev->usbid[1], dev->num_buttons);
|
||||
|
||||
dev->bnhack = 0;
|
||||
}
|
||||
|
||||
if(dev->bnhack) {
|
||||
/* for those problematic devices, rely on the hardcoded button value in
|
||||
* their button remapping hack
|
||||
*/
|
||||
dev->num_buttons = dev->bnhack(-1);
|
||||
} else {
|
||||
dev->num_buttons = 0;
|
||||
if(ioctl(dev->fd, EVIOCGBIT(EV_KEY, sizeof evtype_mask), evtype_mask) != -1) {
|
||||
for(i=0; i<KEY_CNT; i++) {
|
||||
int idx = i / 8;
|
||||
int bit = i % 8;
|
||||
|
||||
if(evtype_mask[idx] & (1 << bit)) {
|
||||
logmsg(LOG_DEBUG, "bit %d (part %d bit %d)\n", idx * 8 + i, idx, bit);
|
||||
dev->num_buttons++;
|
||||
}
|
||||
if(dev->usbid[0] == VID_3DCONN && dev->usbid[1] == PID_WIRELESS) {
|
||||
/* Wireless devices use the same dongle, try to guess which actual
|
||||
* device this is, and apply the button hack if it's a SpcMouse Pro
|
||||
*/
|
||||
if(dev->num_buttons >= 255) {
|
||||
dev->type = DEV_SMPROW;
|
||||
dev->bnhack = bnhack_smpro;
|
||||
dev->num_buttons = bnhack_smpro(-1);
|
||||
strcpy(dev->name, "3Dconnexion SpaceMouse Pro Wireless (guess)");
|
||||
} else {
|
||||
dev->type = DEV_SMW;
|
||||
strcpy(dev->name, "3Dconnexion SpaceMouse Wireless (guess)");
|
||||
}
|
||||
} else {
|
||||
logmsg(LOG_DEBUG, "EVIOCGBIT(EV_KEY) ioctl failed: %s\n", strerror(errno));
|
||||
}
|
||||
}
|
||||
if(!dev->num_buttons) {
|
||||
|
|
Ładowanie…
Reference in New Issue