Skip to content

Commit f72d01a

Browse files
committed
Clean up in preparation for Emscripten (WebHID) support
Mostly type casting correctness fixes to allow compiling in C++ mode with Clang/Emscripten. Also unify `usbdev_read_O` and `usbdev_read_N` into a single `usbdev_read` function that calls `usbdev_parse_O` or `usbdev_parse_N` based on the connected device.
1 parent f37c561 commit f72d01a

3 files changed

Lines changed: 102 additions & 80 deletions

File tree

src/serdev.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ int spndev_ser_open(struct spndev *dev, const char *devstr)
9494
dev->usb_vendor = dev->usb_product = 0xFFFF;
9595
dev->handle = 0;
9696

97-
if(!(sb = calloc(1, sizeof *sb))) {
97+
if(!(sb = (struct sball*)calloc(1, sizeof *sb))) {
9898
fprintf(stderr, "spndev_open: failed to allocate sball object\n");
9999
goto err;
100100
}
@@ -173,7 +173,7 @@ int spndev_ser_open(struct spndev *dev, const char *devstr)
173173
static void close_dev_serial(struct spndev *dev)
174174
{
175175
if(dev->drvdata) {
176-
stty_restore(dev->fd, dev->drvdata);
176+
stty_restore(dev->fd, (struct sball*)dev->drvdata);
177177
serclose(dev->fd);
178178
free(dev->drvdata);
179179
}
@@ -210,7 +210,7 @@ static int read_dev_serial(struct spndev* dev, union spndev_event* evt)
210210
static int init_dev(struct spndev *dev, int type)
211211
{
212212
int i;
213-
struct sball *sb = dev->drvdata;
213+
struct sball *sb = (struct sball*)dev->drvdata;
214214
static const char *axnames[] = {"Tx", "Ty", "Tz", "Rx", "Ry", "Rz"};
215215

216216
if(!(dev->name = strdup(devinfo[type].name))) {
@@ -220,11 +220,11 @@ static int init_dev(struct spndev *dev, int type)
220220
dev->num_buttons = devinfo[type].nbuttons;
221221
sb->keymask = 0xffff >> (16 - dev->num_buttons);
222222

223-
if(!(dev->aprop = malloc(dev->num_axes * sizeof *dev->aprop))) {
223+
if(!(dev->aprop = (struct axisprop*)malloc(dev->num_axes * sizeof *dev->aprop))) {
224224
free(dev->name);
225225
return -1;
226226
}
227-
if(!(dev->bn_name = malloc(dev->num_buttons * sizeof *dev->bn_name))) {
227+
if(!(dev->bn_name = (const char**)malloc(dev->num_buttons * sizeof *dev->bn_name))) {
228228
free(dev->aprop);
229229
free(dev->name);
230230
}

src/spnavdev.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ struct spndev *spndev_open(const char *devstr)
2525
struct spndev *dev;
2626
uint16_t vendor = 0xffff, product = 0xffff;
2727

28-
if(!(dev = malloc(sizeof *dev))) {
28+
if(!(dev = (struct spndev*)malloc(sizeof *dev))) {
2929
perror("spndev_open: failed to allocate device structure");
3030
return 0;
3131
}

src/usbdev.c

Lines changed: 96 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -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;
4550
typedef 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

8593
static int usbdev_init(struct spndev* dev, const unsigned type);
8694
static 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);
8998
static void usbdev_setled(struct spndev* dev, int led);
9099
static int usbdev_getled(struct spndev* dev);
91100
static 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

Comments
 (0)