@@ -30,8 +30,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
3030
3131#include "dev.h"
3232
33- #ifdef HAVE_HIDAPI
33+ #if defined(HAVE_HIDAPI ) || defined(HAVE_WEBHIDAPI )
34+
35+ #if defined(HAVE_HIDAPI )
3436#include "hidapi.h"
37+ #elif defined(HAVE_WEBHIDAPI )
38+ #include "webhidapi.h"
39+ #endif
3540
3641#define max_num_btn 48
3742#define max_buf_size 80
@@ -45,18 +50,21 @@ static const int axis_deadz = 0;
4550typedef struct spnav_hid {
4651 unsigned char btn [max_num_btn ];
4752 unsigned char buf [max_buf_size ];
53+ size_t reportsize ;
4854} tspnav_hid ;
4955
50- static const struct {
56+ typedef enum { O = 0 , N = 1 } oldnewreport ;
57+ typedef struct {
5158 uint16_t vid ;
5259 uint16_t pid ;
53- enum { O = 0 , N = 1 } posrotreport ; // Old (two reports) or New (single report) positon and rotation data
60+ oldnewreport posrotreport ; // Old (two reports) or New (single report) positon and rotation data
5461 const char * name ;
5562 const char * pn ; // "P/N:" part number "Part No." from the label or box
5663 int nbuttons ;
5764 const char * const bnames [32 ];
58- }
59- devinfo [] = {
65+ } dev_info ;
66+
67+ static const dev_info devinfo [] = {
6068 {0x046d , 0xc603 , O , "SpaceMouse Plus XT USB" , "" , 10 , {"1" , "2" , "3" , "4" , "5" , "6" , "7" , "8" , "9" , "10" }}, // Manual says 11 is the * reported? Buttons order? Side button names? "L" "R"?
6169 {0x046d , 0xc605 , O , "CadMan USB" , "" , 4 , {"1" , "2" , "3" , "4" }}, // Buttons order? Names? "CadMan3 USB" on the label // Tested working
6270 {0x046d , 0xc606 , O , "SpaceMouse Classic USB" , "" , 8 , {"1" , "2" , "3" , "4" , "5" , "6" , "7" , "8" }}, // Manual says 11 is the * reported?
@@ -84,8 +92,9 @@ static const unsigned num_known_devs = sizeof(devinfo)/sizeof(devinfo[0]);
8492
8593static int usbdev_init (struct spndev * dev , const unsigned type );
8694static void usbdev_close (struct spndev * dev );
87- static int usbdev_read_O (struct spndev * dev , union spndev_event * evt );
88- static int usbdev_read_N (struct spndev * dev , union spndev_event * evt );
95+ static int usbdev_read (struct spndev * dev , union spndev_event * evt );
96+ static int usbdev_parse_O (struct spndev * dev , union spndev_event * evt );
97+ static int usbdev_parse_N (struct spndev * dev , union spndev_event * evt );
8998static void usbdev_setled (struct spndev * dev , int led );
9099static int usbdev_getled (struct spndev * dev );
91100static inline void usbdev_parsebuttons (const struct spndev * dev , union spndev_event * evt , const unsigned char * report );
@@ -147,18 +156,18 @@ int spndev_usb_open(struct spndev *dev, const char *devstr, uint16_t vend, uint1
147156 if (hiddev ) {
148157 size_t name_length ;
149158
150- if (!(dev -> path = _strdup (cinfo -> path ))) {
159+ if (!(dev -> path = strdup (cinfo -> path ))) {
151160 fprintf (stderr , "spndev_open: Failed to allocate device path\n" );
152161 goto cleanup ;
153162 }
154163
155- // The length of the UTF8 encoding of the UTF16 device name + 1 fot the 0
156- name_length = 1 + wcsrtombs (0 , & cinfo -> product_string , 0 , 0 );
164+ // The length of the UTF8 encoding of the UTF16 device name + 1 for the 0
165+ name_length = 1 + wcsrtombs (0 , ( const wchar_t * * ) & cinfo -> product_string , 0 , 0 );
157166 if (!(dev -> name = (char * )calloc (1 , name_length ))) {
158167 fprintf (stderr , "spndev_open: Failed to allocate device name\n" );
159168 goto cleanup ;
160169 }
161- name_length = wcsrtombs (dev -> name , & cinfo -> product_string , name_length , 0 );
170+ name_length = wcsrtombs (dev -> name , ( const wchar_t * * ) & cinfo -> product_string , name_length , 0 );
162171
163172 if (-1 == hid_set_nonblocking (hiddev , 1 )) {
164173 fprintf (stderr , "spndev_open: Failed to set non-blocking HID mode.\n" );
@@ -224,10 +233,10 @@ static int usbdev_init(struct spndev* dev, const unsigned type)
224233 return -1 ;
225234 }
226235
227- if (!(dev -> aprop = malloc (dev -> num_axes * sizeof * dev -> aprop ))) {
236+ if (!(dev -> aprop = ( struct axisprop * ) malloc (dev -> num_axes * sizeof * dev -> aprop ))) {
228237 return -1 ;
229238 }
230- if (!(dev -> bn_name = malloc (dev -> num_buttons * sizeof * dev -> bn_name ))) {
239+ if (!(dev -> bn_name = ( const char * * ) malloc (dev -> num_buttons * sizeof * dev -> bn_name ))) {
231240 return -1 ;
232241 }
233242
@@ -242,17 +251,17 @@ static int usbdev_init(struct spndev* dev, const unsigned type)
242251 }
243252
244253 dev -> close = usbdev_close ;
254+ dev -> read = usbdev_read ;
245255 if (O == devinfo [type ].posrotreport ) {
246- dev -> read = usbdev_read_O ;
256+ (( tspnav_hid * ) dev -> drvdata ) -> reportsize = oldposrotreportsize ;
247257 } else if (N == devinfo [type ].posrotreport ) {
248- dev -> read = usbdev_read_N ;
249- }
250- else {
258+ ((tspnav_hid * )dev -> drvdata )-> reportsize = newposrotreportsize ;
259+ } else {
251260 // WTF?
252261 }
253262 dev -> getled = usbdev_getled ;
254263 dev -> setled = usbdev_setled ;
255- if ((dev -> usb_vendor == devinfo [5 ].vid ) && (dev -> usb_product == devinfo [5 ].pid )) { // ToDo: The constant 4 here is an ugly hack
264+ if ((dev -> usb_vendor == devinfo [5 ].vid ) && (dev -> usb_product == devinfo [5 ].pid )) { // ToDo: The constant 5 here is an ugly hack
256265 /* The device is a SpacePilot USB. Connect the LCD support functions. */
257266 dev -> setlcdbl = SpacePilotLCDSetBl ;
258267 dev -> getlcdbl = SpacePilotLCDGetBl ;
@@ -274,81 +283,94 @@ static void usbdev_close(struct spndev *dev) {
274283}
275284
276285
277- // Read and parse "Old" (two reports) style positon and rotation data
278- static int usbdev_read_O (struct spndev * dev , union spndev_event * evt )
286+ // Read and parse positon and rotation data
287+ static int usbdev_read (struct spndev * dev , union spndev_event * evt )
288+ {
289+ evt -> type = SPNDEV_NONE ;
290+ unsigned char * buffer = ((tspnav_hid * )dev -> drvdata )-> buf ;
291+
292+ if (hid_read ((hid_device * )dev -> handle , buffer , ((tspnav_hid * )dev -> drvdata )-> reportsize ) > 0 ) {
293+ if (oldposrotreportsize == ((tspnav_hid * )dev -> drvdata )-> reportsize ) {
294+ usbdev_parse_O (dev , evt );
295+ }
296+ else {
297+ usbdev_parse_N (dev , evt );
298+ }
299+ }
300+ return evt -> type ;
301+ }
302+
303+ // Parse "Old" (two reports) style positon and rotation data
304+ static int usbdev_parse_O (struct spndev * dev , union spndev_event * evt )
279305{
280306 evt -> type = SPNDEV_NONE ;
281307 unsigned char * buffer = ((tspnav_hid * )dev -> drvdata )-> buf ;
282308
283- if (hid_read ((hid_device * )dev -> handle , buffer , oldposrotreportsize ) > 0 ) {
284- switch (buffer [0 ]) {
285- case 0 :
286- for (size_t i = 0 ; i < oldposrotreportsize ; ++ i ) {
287- printf ("%x" , buffer [i ]);
288- }
289- break ;
309+ switch (buffer [0 ]) {
310+ case 0 :
311+ for (size_t i = 0 ; i < ((tspnav_hid * )dev -> drvdata )-> reportsize ; ++ i ) {
312+ printf ("%x" , buffer [i ]);
313+ }
314+ break ;
290315
291- case 1 : // Translation
292- evt -> type = SPNDEV_MOTION ;
293- for (int i = 0 ; i < 3 ; ++ i ) {
294- evt -> mot .v [i ] = * (int16_t * )(buffer + 1 + 2 * i );
295- checkrange (dev , evt -> mot .v [i ]);
296- }
297- break ;
316+ case 1 : // Translation
317+ evt -> type = SPNDEV_MOTION ;
318+ for (int i = 0 ; i < 3 ; ++ i ) {
319+ evt -> mot .v [i ] = * (int16_t * )(buffer + 1 + 2 * i );
320+ checkrange (dev , evt -> mot .v [i ]);
321+ }
322+ break ;
298323
299- case 2 : // Rotation
300- evt -> type = SPNDEV_MOTION ;
301- for (int i = 0 ; i < 3 ; ++ i ) {
302- evt -> mot .v [i + 3 ] = * (int16_t * )(buffer + 1 + 2 * i );
303- checkrange (dev , evt -> mot .v [i + 3 ]);
304- }
305- break ;
306- case 3 : // Buttons
307- usbdev_parsebuttons (dev , evt , buffer );
308- break ;
309-
310- default :
311- for (size_t i = 0 ; i < newposrotreportsize ; ++ i ) {
312- printf ("%x" , buffer [i ]);
313- }
314- break ;
324+ case 2 : // Rotation
325+ evt -> type = SPNDEV_MOTION ;
326+ for (int i = 0 ; i < 3 ; ++ i ) {
327+ evt -> mot .v [i + 3 ] = * (int16_t * )(buffer + 1 + 2 * i );
328+ checkrange (dev , evt -> mot .v [i + 3 ]);
329+ }
330+ break ;
331+ case 3 : // Buttons
332+ usbdev_parsebuttons (dev , evt , buffer );
333+ break ;
334+
335+ default :
336+ for (size_t i = 0 ; i < ((tspnav_hid * )dev -> drvdata )-> reportsize ; ++ i ) {
337+ printf ("%x" , buffer [i ]);
315338 }
339+ break ;
316340 }
317341 return evt -> type ;
318342}
319343
320- // Read and parse "New" (single report) style positon and rotation data
321- static int usbdev_read_N (struct spndev * dev , union spndev_event * evt )
344+ // Parse "New" (single report) style positon and rotation data
345+ static int usbdev_parse_N (struct spndev * dev , union spndev_event * evt )
322346{
323347 evt -> type = SPNDEV_NONE ;
324348 unsigned char * buffer = ((tspnav_hid * )dev -> drvdata )-> buf ;
325349
326- if (hid_read ((hid_device * )dev -> handle , buffer , newposrotreportsize ) > 0 ) {
327- switch (buffer [0 ]) {
328- case 0 :
329- for (size_t i = 0 ; i < newposrotreportsize ; ++ i ) {
330- printf ("%x" , buffer [i ]);
331- }
332- break ;
350+ switch (buffer [0 ]) {
351+ case 0 :
352+ for (size_t i = 0 ; i < ((tspnav_hid * )dev -> drvdata )-> reportsize ; ++ i ) {
353+ printf ("%x" , buffer [i ]);
354+ }
355+ break ;
333356
334- case 1 : // Translation & Rotation
335- evt -> type = SPNDEV_MOTION ;
336- for (int i = 0 ; i < 6 ; ++ i ) {
337- evt -> mot .v [i ] = * (int16_t * )(buffer + 1 + 2 * i );
338- checkrange (dev , evt -> mot .v [i ]);
339- }
340- break ;
357+ case 1 : // Translation & Rotation
358+ evt -> type = SPNDEV_MOTION ;
359+ for (int i = 0 ; i < 6 ; ++ i ) {
360+ evt -> mot .v [i ] = * (int16_t * )(buffer + 1 + 2 * i );
361+ checkrange (dev , evt -> mot .v [i ]);
362+ }
363+ break ;
341364
342- case 3 : // Buttons
343- usbdev_parsebuttons (dev , evt , buffer );
344- break ;
365+ case 3 : // Buttons
366+ usbdev_parsebuttons (dev , evt , buffer );
367+ break ;
345368
346- default :
347- for (size_t i = 0 ; i < newposrotreportsize ; ++ i ) {
348- printf ("%x" , buffer [i ]);
349- }
350- break ;
369+ default :
370+ for (size_t i = 0 ; i < ((tspnav_hid * )dev -> drvdata )-> reportsize ; ++ i ) {
371+ printf ("%x" , buffer [i ]);
351372 }
373+ break ;
352374 }
353375 return evt -> type ;
354376}
0 commit comments