Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package spacenavd for openSUSE:Factory checked in at 2022-09-26 18:47:57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/spacenavd (Old) and /work/SRC/openSUSE:Factory/.spacenavd.new.2275 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "spacenavd" Mon Sep 26 18:47:57 2022 rev:10 rq:1005901 version:1.1 Changes: -------- --- /work/SRC/openSUSE:Factory/spacenavd/spacenavd.changes 2022-04-26 20:17:47.912762862 +0200 +++ /work/SRC/openSUSE:Factory/.spacenavd.new.2275/spacenavd.changes 2022-09-26 18:47:58.464028250 +0200 @@ -1,0 +2,27 @@ +Sun Sep 25 16:47:35 UTC 2022 - Herbert Graeber <[email protected]> + +- Add example files to package + +------------------------------------------------------------------- +Sun Sep 25 16:30:12 UTC 2022 - Herbert Graeber <[email protected]> + +- Update to version 1.1 + * fixed incorrect number of buttons reported on SpaceMouse Pro and SpaceMouse + Enterprise. + * fixed non-contiguous button numbers on SpaceMouse Pro and SpaceMouse Enterprise, + which could crash spnavcfg. + * linux evdev: detect button base offset, instead of hardcoding 256 (BN_MISC), + which fixes incorrect button numbers on the Magellan SpaceMouse USB. + * fixed crash when attempting to save configuration (save command received from + the client socket), and a configuration file does not already exist. + * linux hotplug: use delayed activation to avoid multiple hotplug triggers and + the resulting log spam. + * reduced logging on the "verbose" setting. Now accepting multiple -v arguments + for maximum verbosity. + * fixed compatibility with newer 3dconnexion SDK clients. + * fixed libm link omission, which broke the build on systems where isfinite is not + a macro to a compiler built-in (BSD libc). + * Added example configuration files with reasonable button mappings for the + SpacePilot and the SpaceMouse Enterprise under doc/. + +------------------------------------------------------------------- Old: ---- spacenavd-1.0.tar.gz New: ---- spacenavd-1.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ spacenavd.spec ++++++ --- /var/tmp/diff_new_pack.qxFv1e/_old 2022-09-26 18:47:58.964029195 +0200 +++ /var/tmp/diff_new_pack.qxFv1e/_new 2022-09-26 18:47:58.968029202 +0200 @@ -18,7 +18,7 @@ Name: spacenavd -Version: 1.0 +Version: 1.1 Release: 0 Summary: Daemon for 3Dconnexion devices License: GPL-3.0-or-later @@ -96,6 +96,9 @@ %files %license COPYING %doc README.md +%doc doc/example-spnavrc +%doc doc/spnavrc_smouse_ent +%doc doc/spnavrc_spilot %{_sbindir}/%{name} %{_sbindir}/rc%{name} %{_bindir}/spnavd_ctl ++++++ spacenavd-1.0.tar.gz -> spacenavd-1.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/spacenavd-1.0/Makefile.in new/spacenavd-1.1/Makefile.in --- old/spacenavd-1.0/Makefile.in 2022-04-01 04:19:11.000000000 +0200 +++ new/spacenavd-1.1/Makefile.in 2022-08-26 21:54:36.000000000 +0200 @@ -10,7 +10,7 @@ CC ?= gcc CFLAGS = $(warn) $(dbg) $(opt) -fno-strict-aliasing -fcommon \ -I$(srcdir)/src -I/usr/local/include -MMD $(add_cflags) -LDFLAGS = -L/usr/local/lib $(xlib) $(add_ldflags) +LDFLAGS = -L/usr/local/lib $(xlib) $(add_ldflags) -lm $(bin): $(obj) $(CC) -o $@ $(obj) $(LDFLAGS) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/spacenavd-1.0/README.md new/spacenavd-1.1/README.md --- old/spacenavd-1.0/README.md 2022-04-01 04:19:11.000000000 +0200 +++ new/spacenavd-1.1/README.md 2022-08-26 21:54:36.000000000 +0200 @@ -12,12 +12,19 @@ For more info on the spacenav project, visit: http://spacenav.sourceforge.net +> We are currently in the process of documenting how button numbers relate to +> physical buttons, across all 6dof devices: +> https://github.com/FreeSpacenav/spacenavd/wiki/Device-button-names +> +> If you have a device which is missing from that wiki page, please help us +> expand the database by adding it, or send us the information through email. + License ------- Copyright (C) 2007-2022 John Tsiombikas <[email protected]> This program is free software. Feel free to copy, modify and/or redistribute it -under the terms of the GNU General Public Licens version 3, or at your option, +under the terms of the GNU General Public License version 3, or at your option, any later version published by the Free Software Foundation. See COPYING for details. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/spacenavd-1.0/doc/spnavrc_smouse_ent new/spacenavd-1.1/doc/spnavrc_smouse_ent --- old/spacenavd-1.0/doc/spnavrc_smouse_ent 1970-01-01 01:00:00.000000000 +0100 +++ new/spacenavd-1.1/doc/spnavrc_smouse_ent 2022-08-26 21:54:36.000000000 +0200 @@ -0,0 +1,14 @@ +# Sensible button mappings for the SpaceMouse Enterprise +# Copy to /etc/spnavrc to use + +bnact2 = sensitivity-reset +bnact8 = sensitivity-down +bnact9 = sensitivity-up +kbmap18 = Escape +bnact22 = disable-rotation +kbmap13 = KP_Delete +kbmap20 = Shift_L +kbmap21 = Control_L +kbmap24 = Delete +kbmap25 = Tab +kbmap26 = space diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/spacenavd-1.0/doc/spnavrc_spilot new/spacenavd-1.1/doc/spnavrc_spilot --- old/spacenavd-1.0/doc/spnavrc_spilot 1970-01-01 01:00:00.000000000 +0100 +++ new/spacenavd-1.1/doc/spnavrc_spilot 2022-08-26 21:54:36.000000000 +0200 @@ -0,0 +1,15 @@ +# Sensible button mappings for the original SpacePilot +# Copy to /etc/spnavrc to use + +kbmap6 = KP_7 +kbmap8 = KP_3 +kbmap9 = KP_1 +kbmap11 = Alt_L +kbmap12 = Shift_L +kbmap13 = Control_L +kbmap14 = KP_Delete +kbmap19 = KP_5 +bnact16 = sensitivity-up +bnact17 = sensitivity-down +bnact18 = sensitivity-reset +kbmap10 = Escape diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/spacenavd-1.0/src/cfgfile.c new/spacenavd-1.1/src/cfgfile.c --- old/spacenavd-1.0/src/cfgfile.c 2022-04-01 04:19:11.000000000 +0200 +++ new/spacenavd-1.1/src/cfgfile.c 2022-08-26 21:54:36.000000000 +0200 @@ -469,6 +469,14 @@ return -1; } + if(!cfglines) { + if(!(cfglines = calloc(NUM_EXTRA_LINES, sizeof *cfglines))) { + logmsg(LOG_WARNING, "failed to allocate config lines buffer\n"); + fclose(fp); + return -1; + } + } + default_cfg(&def); /* default config for comparisons */ if(cfg->sensitivity != def.sensitivity) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/spacenavd-1.0/src/dev.c new/spacenavd-1.1/src/dev.c --- old/spacenavd-1.0/src/dev.c 2022-04-01 04:19:11.000000000 +0200 +++ new/spacenavd-1.1/src/dev.c 2022-08-26 21:54:36.000000000 +0200 @@ -35,8 +35,6 @@ #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 @@ -51,30 +49,37 @@ DF_INVYZ = 2 }; -static struct { +/* The bnmap function pointer in the device table was introduced to deal with + * certain USB devices which report a huge amount of buttons, and strange + * disjointed button numbers. The function is expected to return the number of + * actual buttons when a negative number is passed as argument, and the button + * mapping otherwise. + */ +static struct usbdb_entry { int usbid[2]; int type; unsigned int flags; -} devid_list[] = { - {{0x046d, 0xc603}, DEV_PLUSXT, 0}, /* spacemouse plus XT */ - {{0x046d, 0xc605}, DEV_CADMAN, 0}, /* cadman */ - {{0x046d, 0xc606}, DEV_SMCLASSIC, 0}, /* spacemouse classic */ - {{0x046d, 0xc621}, DEV_SB5000, 0}, /* spaceball 5000 */ - {{0x046d, 0xc623}, DEV_STRAVEL, DF_SWAPYZ | DF_INVYZ}, /* space traveller */ - {{0x046d, 0xc625}, DEV_SPILOT, DF_SWAPYZ | DF_INVYZ}, /* space pilot */ - {{0x046d, 0xc626}, DEV_SNAV, DF_SWAPYZ | DF_INVYZ}, /* space navigator */ - {{0x046d, 0xc627}, DEV_SEXP, DF_SWAPYZ | DF_INVYZ}, /* space explorer */ - {{0x046d, 0xc628}, DEV_SNAVNB, DF_SWAPYZ | DF_INVYZ}, /* space navigator for notebooks*/ - {{0x046d, 0xc629}, DEV_SPILOTPRO, DF_SWAPYZ | DF_INVYZ}, /* space pilot pro*/ - {{0x046d, 0xc62b}, DEV_SMPRO, DF_SWAPYZ | DF_INVYZ}, /* space mouse pro*/ - {{0x046d, 0xc640}, DEV_NULOOQ, 0}, /* nulooq */ - {{0x256f, 0xc62e}, DEV_SMW, DF_SWAPYZ | DF_INVYZ}, /* spacemouse wireless (USB cable) */ - {{0x256f, 0xc62f}, DEV_SMW, DF_SWAPYZ | DF_INVYZ}, /* spacemouse wireless receiver */ - {{0x256f, 0xc631}, DEV_SMPROW, DF_SWAPYZ | DF_INVYZ}, /* spacemouse pro wireless */ - {{0x256f, 0xc632}, DEV_SMPROW, DF_SWAPYZ | DF_INVYZ}, /* spacemouse pro wireless receiver */ - {{0x256f, 0xc633}, DEV_SMENT, DF_SWAPYZ | DF_INVYZ}, /* spacemouse enterprise */ - {{0x256f, 0xc635}, DEV_SMCOMP, DF_SWAPYZ | DF_INVYZ}, /* spacemouse compact */ - {{0x256f, 0xc636}, DEV_SMMOD, DF_SWAPYZ | DF_INVYZ}, /* spacemouse module */ + int (*bnmap)(int); /* remap buttons on problematic devices */ +} usbdb[] = { + {{0x046d, 0xc603}, DEV_PLUSXT, 0, 0}, /* spacemouse plus XT */ + {{0x046d, 0xc605}, DEV_CADMAN, 0, 0}, /* cadman */ + {{0x046d, 0xc606}, DEV_SMCLASSIC, 0, 0}, /* spacemouse classic */ + {{0x046d, 0xc621}, DEV_SB5000, 0, 0}, /* spaceball 5000 */ + {{0x046d, 0xc623}, DEV_STRAVEL, DF_SWAPYZ | DF_INVYZ, 0}, /* space traveller */ + {{0x046d, 0xc625}, DEV_SPILOT, DF_SWAPYZ | DF_INVYZ, 0}, /* space pilot */ + {{0x046d, 0xc626}, DEV_SNAV, DF_SWAPYZ | DF_INVYZ, 0}, /* space navigator */ + {{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, 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 */ + {{0x256f, 0xc631}, DEV_SMPROW, DF_SWAPYZ | DF_INVYZ, bnhack_smpro}, /* spacemouse pro wireless */ + {{0x256f, 0xc632}, DEV_SMPROW, DF_SWAPYZ | DF_INVYZ, bnhack_smpro}, /* spacemouse pro wireless receiver */ + {{0x256f, 0xc633}, DEV_SMENT, DF_SWAPYZ | DF_INVYZ, bnhack_sment}, /* spacemouse enterprise */ + {{0x256f, 0xc635}, DEV_SMCOMP, DF_SWAPYZ | DF_INVYZ, 0}, /* spacemouse compact */ + {{0x256f, 0xc636}, DEV_SMMOD, DF_SWAPYZ | DF_INVYZ, 0}, /* spacemouse module */ {{-1, -1}, DEV_UNKNOWN, 0} }; @@ -94,10 +99,8 @@ static struct device *add_device(void); -static struct device *dev_path_in_use(char const * dev_path); static int match_usbdev(const struct usb_dev_info *devinfo); -static int usbdevtype(unsigned int vid, unsigned int pid); -static unsigned int usbdevflags(unsigned int vid, unsigned int pid); +static struct usbdb_entry *find_usbdb_entry(unsigned int vid, unsigned int pid); static struct device *dev_list = NULL; static unsigned short last_id; @@ -152,6 +155,7 @@ int i; struct device *dev; struct usb_dev_info *usblist, *usbdev; + struct usbdb_entry *uent; spnav_event ev = {0}; char buf[256]; @@ -162,16 +166,19 @@ while(usbdev) { for(i=0; i<usbdev->num_devfiles; i++) { if((dev = dev_path_in_use(usbdev->devfiles[i]))) { - if(verbose) { + if(verbose > 1) { logmsg(LOG_WARNING, "already using device: %s (%s) (id: %d)\n", dev->name, dev->path, dev->id); } break; } + uent = find_usbdb_entry(usbdev->vendorid, usbdev->productid); + dev = add_device(); strcpy(dev->path, usbdev->devfiles[i]); - dev->type = usbdevtype(usbdev->vendorid, usbdev->productid); - dev->flags = usbdevflags(usbdev->vendorid, usbdev->productid); + dev->type = uent ? uent->type : DEV_UNKNOWN; + dev->flags = uent ? uent->flags : 0; + dev->bnhack = uent ? uent->bnmap : 0; dev->usbid[0] = usbdev->vendorid; dev->usbid[1] = usbdev->productid; @@ -179,7 +186,7 @@ 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 */ @@ -212,7 +219,9 @@ free_usb_devices_list(usblist); if(!usblist) { - logmsg(LOG_ERR, "failed to find any supported USB devices\n"); + if(verbose > 1) { + logmsg(LOG_ERR, "failed to find any supported USB devices\n"); + } return -1; } @@ -279,7 +288,7 @@ free(dev); } -static struct device *dev_path_in_use(char const *dev_path) +struct device *dev_path_in_use(const char *dev_path) { struct device *iter = dev_list; while(iter) { @@ -381,7 +390,7 @@ } /* 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. */ @@ -391,9 +400,9 @@ return 1; } - /* match any device in the devid_list */ - for(i=0; devid_list[i].usbid[0] > 0; i++) { - if(vid == devid_list[i].usbid[0] && pid == devid_list[i].usbid[1]) { + /* match any device in the usbdb */ + for(i=0; usbdb[i].usbid[0] > 0; i++) { + if(vid == usbdb[i].usbid[0] && pid == usbdb[i].usbid[1]) { return 1; } } @@ -407,24 +416,93 @@ return 0; /* no match */ } -static int usbdevtype(unsigned int vid, unsigned int pid) +static struct usbdb_entry *find_usbdb_entry(unsigned int vid, unsigned int pid) { int i; - for(i=0; devid_list[i].usbid[0] != -1; i++) { - if(devid_list[i].usbid[0] == vid && devid_list[i].usbid[1] == pid) { - return devid_list[i].type; + for(i=0; usbdb[i].usbid[0] != -1; i++) { + if(usbdb[i].usbid[0] == vid && usbdb[i].usbid[1] == pid) { + return usbdb + i; } } - return DEV_UNKNOWN; + return 0; } -static unsigned int usbdevflags(unsigned int vid, unsigned int pid) + +/* --- button remapping hack functions --- */ + +/* SpaceMouse Pro */ +int bnhack_smpro(int bn) { - int i; - for(i=0; devid_list[i].usbid[0] != -1; i++) { - if(devid_list[i].usbid[0] == vid && devid_list[i].usbid[1] == pid) { - return devid_list[i].flags; - } + if(bn < 0) return 15; /* button count */ + + switch(bn) { + case 256: return 4; /* menu */ + case 257: return 5; /* fit */ + case 258: return 6; /* [T] */ + case 260: return 7; /* [R] */ + case 261: return 8; /* [F] */ + case 264: return 9; /* [ ] */ + case 268: return 0; /* 1 */ + case 269: return 1; /* 2 */ + case 270: return 2; /* 3 */ + case 271: return 3; /* 4 */ + case 278: return 11; /* esc */ + case 279: return 12; /* alt */ + case 280: return 13; /* shift */ + case 281: return 14; /* ctrl */ + case 282: return 10; /* lock */ + default: + break; + } + return -1; /* ignore all other events */ +} + +/* SpaceMouse Enterprise */ +int bnhack_sment(int bn) +{ + if(bn < 0) return 31; /* button count */ + + switch(bn) { + case 256: return 12; /* menu */ + case 257: return 13; /* fit */ + case 258: return 14; /* [T] */ + case 260: return 15; /* [R] */ + case 261: return 16; /* [F] */ + case 264: return 17; /* [ ] */ + + case 266: return 30; /* iso */ + + case 268: return 0; /* 1 */ + case 269: return 1; /* 2 */ + case 270: return 2; /* 3 */ + case 271: return 3; /* 4 */ + case 272: return 4; /* 5 */ + case 273: return 5; /* 6 */ + case 274: return 6; /* 7 */ + case 275: return 7; /* 8 */ + case 276: return 8; /* 9 */ + case 277: return 9; /* 10 */ + + case 278: return 18; /* esc */ + case 279: return 19; /* alt */ + case 280: return 20; /* shift */ + case 281: return 21; /* ctrl */ + case 282: return 22; /* lock */ + + case 291: return 23; /* enter */ + case 292: return 24; /* delete */ + + case 332: return 10; /* 11 */ + case 333: return 11; /* 12 */ + + case 358: return 27; /* V1 */ + case 359: return 28; /* V2 */ + case 360: return 29; /* V3 */ + + case 430: return 25; /* tab */ + case 431: return 26; /* space */ + default: + break; } - return 0; + return -1; /* ignore all other events */ } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/spacenavd-1.0/src/dev.h new/spacenavd-1.1/src/dev.h --- old/spacenavd-1.0/src/dev.h 2022-04-01 04:19:11.000000000 +0200 +++ new/spacenavd-1.1/src/dev.h 2022-08-26 21:54:36.000000000 +0200 @@ -36,6 +36,7 @@ unsigned int flags; int num_axes, num_buttons; + int bnbase; /* button base (reported number of first button) */ int *minval, *maxval; /* input value range (default: -500, 500) */ int *fuzz; /* noise threshold */ @@ -43,6 +44,8 @@ int (*read)(struct device*, struct dev_input*); void (*set_led)(struct device*, int); + int (*bnhack)(int bn); + struct device *next; }; @@ -61,4 +64,6 @@ struct device *get_devices(void); +struct device *dev_path_in_use(const char *dev_path); + #endif /* SPNAV_DEV_H_ */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/spacenavd-1.0/src/dev_usb.h new/spacenavd-1.1/src/dev_usb.h --- old/spacenavd-1.0/src/dev_usb.h 2022-04-01 04:19:11.000000000 +0200 +++ new/spacenavd-1.1/src/dev_usb.h 2022-08-26 21:54:36.000000000 +0200 @@ -18,6 +18,9 @@ #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 @@ 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_ */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/spacenavd-1.0/src/dev_usb_linux.c new/spacenavd-1.1/src/dev_usb_linux.c --- old/spacenavd-1.0/src/dev_usb_linux.c 2022-04-01 04:19:11.000000000 +0200 +++ new/spacenavd-1.1/src/dev_usb_linux.c 2022-08-26 21:54:36.000000000 +0200 @@ -1,6 +1,6 @@ /* spacenavd - a free software replacement driver for 6dof space-mice. -Copyright (C) 2007-2019 John Tsiombikas <[email protected]> +Copyright (C) 2007-2022 John Tsiombikas <[email protected]> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -62,7 +62,6 @@ static int read_evdev(struct device *dev, struct dev_input *inp); static void set_led_evdev(struct device *dev, int state); - int open_dev_usb(struct device *dev) { int i, axes_rel = 0, axes_abs = 0; @@ -110,6 +109,15 @@ } 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 { @@ -119,6 +127,7 @@ } /* get number of buttons */ + dev->bnbase = -1; dev->num_buttons = 0; if(ioctl(dev->fd, EVIOCGBIT(EV_KEY, sizeof evtype_mask), evtype_mask) != -1) { for(i=0; i<KEY_CNT; i++) { @@ -126,18 +135,57 @@ int bit = i % 8; if(evtype_mask[idx] & (1 << bit)) { + if(dev->bnbase < 0) { + dev->bnbase = idx * 8 + bit; + } dev->num_buttons++; } } } else { logmsg(LOG_DEBUG, "EVIOCGBIT(EV_KEY) ioctl failed: %s\n", strerror(errno)); } + + if(dev->bnbase == -1) { + dev->bnbase = 0; + } + + /* 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 [email protected].\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) { + dev->num_buttons = dev->bnhack(-1); + } else { + 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)"); + } + } + } if(!dev->num_buttons) { logmsg(LOG_WARNING, "failed to retrieve number of buttons, will default to 2\n"); dev->num_buttons = 2; } else { if(verbose) { - logmsg(LOG_INFO, " Number of buttons: %d\n", dev->num_buttons); + logmsg(LOG_INFO, " Number of buttons: %d (evdev offset: %d)\n", dev->num_buttons, dev->bnbase); } } @@ -266,8 +314,16 @@ case EV_KEY: inp->type = INP_BUTTON; - inp->idx = iev.code - BTN_0; + if(dev->bnhack) { + /* for problematic devices, remap button numbers to a contiguous range */ + if((inp->idx = dev->bnhack(iev.code)) == -1) { + return -1; + } + } else { + inp->idx = iev.code - dev->bnbase; + } inp->val = iev.value; + /*logmsg(LOG_DEBUG, "EV_KEY c:%d (%d) v:%d\n", iev.code, inp->idx, iev.value);*/ break; case EV_SYN: @@ -275,8 +331,14 @@ /*printf("[%s] EV_SYN\n", dev->name);*/ break; + case EV_MSC: + /* don't know what to do with these MSC events, the spacemouse enterprise + * sends them on every button press. Silently ignore them for now. + */ + return -1; + default: - if(verbose) { + if(verbose > 1) { logmsg(LOG_DEBUG, "unhandled event: %d\n", iev.type); } return -1; @@ -314,7 +376,7 @@ DIR *dir; struct dirent *dent; - if(verbose) { + if(verbose > 1) { logmsg(LOG_INFO, "Device detection, parsing " PROC_DEV "\n"); } @@ -423,7 +485,7 @@ /* add it to the list */ struct usb_dev_info *node = malloc(sizeof *node); if(node) { - if(verbose) { + if(verbose > 1 || (verbose && !dev_path_in_use(devinfo.devfiles[0]))) { logmsg(LOG_INFO, "found usb device [%x:%x]: \"%s\" (%s) \n", devinfo.vendorid, devinfo.productid, devinfo.name ? devinfo.name : "unknown", devinfo.devfiles[0]); } @@ -458,7 +520,7 @@ /* otherwise try the alternative detection in case it finds something... */ alt_detect: - if(verbose) { + if(verbose > 1) { logmsg(LOG_INFO, "trying alternative detection, querying /dev/input/ devices...\n"); } @@ -485,7 +547,7 @@ sprintf(devinfo.devfiles[0], "/dev/input/%s", dent->d_name); devinfo.num_devfiles = 1; - if(verbose) { + if(verbose > 1) { logmsg(LOG_INFO, " trying \"%s\" ... \n", devinfo.devfiles[0]); } @@ -517,7 +579,7 @@ if(!match || match(&devinfo)) { struct usb_dev_info *node = malloc(sizeof *node); if(node) { - if(verbose) { + if(verbose > 1 || (verbose && !dev_path_in_use(devinfo.devfiles[0]))) { logmsg(LOG_INFO, "found usb device [%x:%x]: \"%s\" (%s) \n", devinfo.vendorid, devinfo.productid, devinfo.name ? devinfo.name : "unknown", devinfo.devfiles[0]); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/spacenavd-1.0/src/hotplug_linux.c new/spacenavd-1.1/src/hotplug_linux.c --- old/spacenavd-1.0/src/hotplug_linux.c 2022-04-01 04:19:11.000000000 +0200 +++ new/spacenavd-1.1/src/hotplug_linux.c 2022-08-26 21:54:36.000000000 +0200 @@ -1,6 +1,6 @@ /* spacenavd - a free software replacement driver for 6dof space-mice. -Copyright (C) 2007-2019 John Tsiombikas <[email protected]> +Copyright (C) 2007-2022 John Tsiombikas <[email protected]> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,6 +23,7 @@ #include <errno.h> #include <signal.h> #include <unistd.h> +#include <fcntl.h> #ifdef USE_NETLINK #include <sys/types.h> @@ -36,10 +37,12 @@ #include "cfgfile.h" static int con_hotplug(void); +static void delay_timeout(int sig); static void poll_timeout(int sig); static int hotplug_fd = -1; -static int poll_time, poll_pipe; +static int poll_time, poll_pipe = -1; +static int delay_pending, delay_pipe[2] = {-1, -1}; int init_hotplug(void) { @@ -65,6 +68,11 @@ poll_time = 1; signal(SIGALRM, poll_timeout); alarm(poll_time); + } else { + if(pipe(delay_pipe) == -1) { + logmsg(LOG_ERR, "failed to open hotplug delay self-pipe: %s\n", strerror(errno)); + return -1; + } } return hotplug_fd; @@ -81,39 +89,63 @@ close(poll_pipe); poll_pipe = -1; } + + if(delay_pipe[0] != -1) { + close(delay_pipe[0]); + close(delay_pipe[1]); + delay_pipe[0] = delay_pipe[1] = -1; + } } int get_hotplug_fd(void) { - return hotplug_fd; + return delay_pending ? delay_pipe[0] : hotplug_fd; } int handle_hotplug(void) { - char buf[512]; - read(hotplug_fd, buf, sizeof buf); + char buf[64]; - if(verbose) { - logmsg(LOG_DEBUG, "\nhandle_hotplug called\n"); + if(poll_pipe != -1 || delay_pending) { + delay_pending = 0; + + read(delay_pipe[0], buf, sizeof buf); + + if(verbose > 1) { + logmsg(LOG_DEBUG, "handle_hotplug: init_devices_usb\n"); + } + + if(init_devices_usb() == -1) { + return -1; + } + return 0; } - if(init_devices_usb() == -1) { - return -1; + while(read(hotplug_fd, buf, sizeof buf) > 0); + + if(verbose > 1) { + logmsg(LOG_DEBUG, "handle_hotplug: schedule delayed activation in 1 sec\n"); } + + /* schedule a delayed trigger to avoid multiple hotplug activations in a row */ + delay_pending = 1; + signal(SIGALRM, delay_timeout); + alarm(1); + return 0; } static int con_hotplug(void) { - int s = -1; - #ifdef USE_NETLINK + int s; struct sockaddr_nl addr; if((s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT)) == -1) { logmsg(LOG_ERR, "failed to open hotplug netlink socket: %s\n", strerror(errno)); return -1; } + fcntl(s, F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK); memset(&addr, 0, sizeof addr); addr.nl_family = AF_NETLINK; @@ -125,9 +157,15 @@ close(s); return -1; } + return s; +#else + return -1; #endif /* USE_NETLINK */ +} - return s; +static void delay_timeout(int sig) +{ + write(delay_pipe[1], &sig, 1); } static void poll_timeout(int sig) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/spacenavd-1.0/src/proto.c new/spacenavd-1.1/src/proto.c --- old/spacenavd-1.0/src/proto.c 2022-04-01 04:19:11.000000000 +0200 +++ new/spacenavd-1.1/src/proto.c 2022-08-26 21:54:36.000000000 +0200 @@ -10,16 +10,18 @@ int len; struct reqresp rr = {0}; - if(fd == -1 || !str) { + if(fd == -1) { return -1; } - len = strlen(str); + len = str ? strlen(str) : 0; rr.type = req; rr.data[6] = len; do { - memcpy(rr.data, str, len > REQSTR_CHUNK_SIZE ? REQSTR_CHUNK_SIZE : len); + if(str) { + memcpy(rr.data, str, len > REQSTR_CHUNK_SIZE ? REQSTR_CHUNK_SIZE : len); + } write(fd, &rr, sizeof rr); str += REQSTR_CHUNK_SIZE; len -= REQSTR_CHUNK_SIZE; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/spacenavd-1.0/src/proto_x11.c new/spacenavd-1.1/src/proto_x11.c --- old/spacenavd-1.0/src/proto_x11.c 2022-04-01 04:19:11.000000000 +0200 +++ new/spacenavd-1.1/src/proto_x11.c 2022-08-26 21:54:36.000000000 +0200 @@ -57,7 +57,8 @@ static Display *dpy; static Window win; -static Atom xa_event_motion, xa_event_bpress, xa_event_brelease, xa_event_cmd; +static Atom xa_event_motion, xa_event_bpress, xa_event_brelease; +static Atom xa_event_devdisc, xa_event_cmd; /* XXX This stands in for the client sensitivity. Due to the * bad design of the original magellan protocol, we can't know @@ -137,6 +138,7 @@ xa_event_motion = XInternAtom(dpy, "MotionEvent", False); xa_event_bpress = XInternAtom(dpy, "ButtonPressEvent", False); xa_event_brelease = XInternAtom(dpy, "ButtonReleaseEvent", False); + xa_event_devdisc = XInternAtom(dpy, "DeviceDisconnectEvent", False); xa_event_cmd = XInternAtom(dpy, "CommandEvent", False); /* Create a dummy window, so that clients are able to send us events diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/spacenavd-1.0/src/spnavd.c new/spacenavd-1.1/src/spnavd.c --- old/spacenavd-1.0/src/spnavd.c 2022-04-01 04:19:11.000000000 +0200 +++ new/spacenavd-1.1/src/spnavd.c 2022-08-26 21:54:36.000000000 +0200 @@ -58,7 +58,11 @@ for(i=1; i<argc; i++) { if(argv[i][0] == '-') { - if(argv[i][2] == 0) { + if(argv[i][1] == 'v') { + char *p = argv[i] + 1; + while(*p++) verbose++; + + } else if(argv[i][2] == 0) { switch(argv[i][1]) { case 'd': become_daemon = !become_daemon; @@ -92,10 +96,6 @@ } break; - case 'v': - verbose = 1; - break; - case 'V': printf("spacenavd " VERSION "\n"); return 0; @@ -266,7 +266,7 @@ printf(" -d: do not daemonize\n"); printf(" -c <file>: config file path (default: " DEF_CFGFILE ")\n"); printf(" -l <file>|syslog: log file path or log to syslog (default: " DEF_LOGFILE ")\n"); - printf(" -v: verbose output\n"); + printf(" -v: verbose output (use multiple times for greater effect)\n"); printf(" -V,-version: print version number and exit\n"); printf(" -h,-help: print usage information and exit\n"); }
