comparison src/joystick/bsd/SDL_sysjoystick.c @ 1895:c121d94672cb

SDL 1.2 is moving to a branch, and SDL 1.3 is becoming the head.
author Sam Lantinga <slouken@libsdl.org>
date Mon, 10 Jul 2006 21:04:37 +0000
parents 92947e3a18db
children 99210400e8b9
comparison
equal deleted inserted replaced
1894:c69cee13dd76 1895:c121d94672cb
72 72
73 #define MAX_UHID_JOYS 4 73 #define MAX_UHID_JOYS 4
74 #define MAX_JOY_JOYS 2 74 #define MAX_JOY_JOYS 2
75 #define MAX_JOYS (MAX_UHID_JOYS + MAX_JOY_JOYS) 75 #define MAX_JOYS (MAX_UHID_JOYS + MAX_JOY_JOYS)
76 76
77 struct report { 77 struct report
78 struct usb_ctl_report *buf; /* Buffer */ 78 {
79 size_t size; /* Buffer size */ 79 struct usb_ctl_report *buf; /* Buffer */
80 int rid; /* Report ID */ 80 size_t size; /* Buffer size */
81 enum { 81 int rid; /* Report ID */
82 SREPORT_UNINIT, 82 enum
83 SREPORT_CLEAN, 83 {
84 SREPORT_DIRTY 84 SREPORT_UNINIT,
85 } status; 85 SREPORT_CLEAN,
86 SREPORT_DIRTY
87 } status;
86 }; 88 };
87 89
88 static struct { 90 static struct
89 int uhid_report; 91 {
90 hid_kind_t kind; 92 int uhid_report;
91 const char *name; 93 hid_kind_t kind;
94 const char *name;
92 } const repinfo[] = { 95 } const repinfo[] = {
93 { UHID_INPUT_REPORT, hid_input, "input" }, 96 {UHID_INPUT_REPORT, hid_input, "input"},
94 { UHID_OUTPUT_REPORT, hid_output, "output" }, 97 {UHID_OUTPUT_REPORT, hid_output, "output"},
95 { UHID_FEATURE_REPORT, hid_feature, "feature" } 98 {UHID_FEATURE_REPORT, hid_feature, "feature"}
96 }; 99 };
97 100
98 enum { 101 enum
99 REPORT_INPUT = 0, 102 {
100 REPORT_OUTPUT = 1, 103 REPORT_INPUT = 0,
101 REPORT_FEATURE = 2 104 REPORT_OUTPUT = 1,
105 REPORT_FEATURE = 2
102 }; 106 };
103 107
104 enum { 108 enum
105 JOYAXE_X, 109 {
106 JOYAXE_Y, 110 JOYAXE_X,
107 JOYAXE_Z, 111 JOYAXE_Y,
108 JOYAXE_SLIDER, 112 JOYAXE_Z,
109 JOYAXE_WHEEL, 113 JOYAXE_SLIDER,
110 JOYAXE_RX, 114 JOYAXE_WHEEL,
111 JOYAXE_RY, 115 JOYAXE_RX,
112 JOYAXE_RZ, 116 JOYAXE_RY,
113 JOYAXE_count 117 JOYAXE_RZ,
118 JOYAXE_count
114 }; 119 };
115 120
116 struct joystick_hwdata { 121 struct joystick_hwdata
117 int fd; 122 {
118 char *path; 123 int fd;
119 enum { 124 char *path;
120 BSDJOY_UHID, /* uhid(4) */ 125 enum
121 BSDJOY_JOY /* joy(4) */ 126 {
122 } type; 127 BSDJOY_UHID, /* uhid(4) */
123 struct report_desc *repdesc; 128 BSDJOY_JOY /* joy(4) */
124 struct report inreport; 129 } type;
125 int axis_map[JOYAXE_count]; /* map present JOYAXE_* to 0,1,..*/ 130 struct report_desc *repdesc;
131 struct report inreport;
132 int axis_map[JOYAXE_count]; /* map present JOYAXE_* to 0,1,.. */
126 }; 133 };
127 134
128 static char *joynames[MAX_JOYS]; 135 static char *joynames[MAX_JOYS];
129 static char *joydevnames[MAX_JOYS]; 136 static char *joydevnames[MAX_JOYS];
130 137
131 static int report_alloc(struct report *, struct report_desc *, int); 138 static int report_alloc(struct report *, struct report_desc *, int);
132 static void report_free(struct report *); 139 static void report_free(struct report *);
133 140
134 #ifdef USBHID_UCR_DATA 141 #ifdef USBHID_UCR_DATA
135 #define REP_BUF_DATA(rep) ((rep)->buf->ucr_data) 142 #define REP_BUF_DATA(rep) ((rep)->buf->ucr_data)
136 #else 143 #else
137 #define REP_BUF_DATA(rep) ((rep)->buf->data) 144 #define REP_BUF_DATA(rep) ((rep)->buf->data)
138 #endif 145 #endif
139 146
140 int 147 int
141 SDL_SYS_JoystickInit(void) 148 SDL_SYS_JoystickInit(void)
142 { 149 {
143 char s[16]; 150 char s[16];
144 int i, fd; 151 int i, fd;
145 152
146 SDL_numjoysticks = 0; 153 SDL_numjoysticks = 0;
147 154
148 SDL_memset(joynames, 0, sizeof(joynames)); 155 SDL_memset(joynames, 0, sizeof(joynames));
149 SDL_memset(joydevnames, 0, sizeof(joydevnames)); 156 SDL_memset(joydevnames, 0, sizeof(joydevnames));
150 157
151 for (i = 0; i < MAX_UHID_JOYS; i++) { 158 for (i = 0; i < MAX_UHID_JOYS; i++) {
152 SDL_Joystick nj; 159 SDL_Joystick nj;
153 160
154 SDL_snprintf(s, SDL_arraysize(s), "/dev/uhid%d", i); 161 SDL_snprintf(s, SDL_arraysize(s), "/dev/uhid%d", i);
155 162
156 nj.index = SDL_numjoysticks; 163 nj.index = SDL_numjoysticks;
157 joynames[nj.index] = strdup(s); 164 joynames[nj.index] = strdup(s);
158 165
159 if (SDL_SYS_JoystickOpen(&nj) == 0) { 166 if (SDL_SYS_JoystickOpen(&nj) == 0) {
160 SDL_SYS_JoystickClose(&nj); 167 SDL_SYS_JoystickClose(&nj);
161 SDL_numjoysticks++; 168 SDL_numjoysticks++;
162 } else { 169 } else {
163 SDL_free(joynames[nj.index]); 170 SDL_free(joynames[nj.index]);
164 joynames[nj.index] = NULL; 171 joynames[nj.index] = NULL;
165 } 172 }
166 } 173 }
167 for (i = 0; i < MAX_JOY_JOYS; i++) { 174 for (i = 0; i < MAX_JOY_JOYS; i++) {
168 SDL_snprintf(s, SDL_arraysize(s), "/dev/joy%d", i); 175 SDL_snprintf(s, SDL_arraysize(s), "/dev/joy%d", i);
169 fd = open(s, O_RDONLY); 176 fd = open(s, O_RDONLY);
170 if (fd != -1) { 177 if (fd != -1) {
171 joynames[SDL_numjoysticks++] = strdup(s); 178 joynames[SDL_numjoysticks++] = strdup(s);
172 close(fd); 179 close(fd);
173 } 180 }
174 } 181 }
175 182
176 /* Read the default USB HID usage table. */ 183 /* Read the default USB HID usage table. */
177 hid_init(NULL); 184 hid_init(NULL);
178 185
179 return (SDL_numjoysticks); 186 return (SDL_numjoysticks);
180 } 187 }
181 188
182 const char * 189 const char *
183 SDL_SYS_JoystickName(int index) 190 SDL_SYS_JoystickName(int index)
184 { 191 {
185 if (joydevnames[index] != NULL) { 192 if (joydevnames[index] != NULL) {
186 return (joydevnames[index]); 193 return (joydevnames[index]);
187 } 194 }
188 return (joynames[index]); 195 return (joynames[index]);
189 } 196 }
190 197
191 static int 198 static int
192 usage_to_joyaxe(unsigned usage) 199 usage_to_joyaxe(unsigned usage)
193 { 200 {
194 int joyaxe; 201 int joyaxe;
195 switch (usage) { 202 switch (usage) {
196 case HUG_X: 203 case HUG_X:
197 joyaxe = JOYAXE_X; break; 204 joyaxe = JOYAXE_X;
205 break;
198 case HUG_Y: 206 case HUG_Y:
199 joyaxe = JOYAXE_Y; break; 207 joyaxe = JOYAXE_Y;
208 break;
200 case HUG_Z: 209 case HUG_Z:
201 joyaxe = JOYAXE_Z; break; 210 joyaxe = JOYAXE_Z;
211 break;
202 case HUG_SLIDER: 212 case HUG_SLIDER:
203 joyaxe = JOYAXE_SLIDER; break; 213 joyaxe = JOYAXE_SLIDER;
214 break;
204 case HUG_WHEEL: 215 case HUG_WHEEL:
205 joyaxe = JOYAXE_WHEEL; break; 216 joyaxe = JOYAXE_WHEEL;
217 break;
206 case HUG_RX: 218 case HUG_RX:
207 joyaxe = JOYAXE_RX; break; 219 joyaxe = JOYAXE_RX;
220 break;
208 case HUG_RY: 221 case HUG_RY:
209 joyaxe = JOYAXE_RY; break; 222 joyaxe = JOYAXE_RY;
223 break;
210 case HUG_RZ: 224 case HUG_RZ:
211 joyaxe = JOYAXE_RZ; break; 225 joyaxe = JOYAXE_RZ;
226 break;
212 default: 227 default:
213 joyaxe = -1; 228 joyaxe = -1;
214 } 229 }
215 return joyaxe; 230 return joyaxe;
216 } 231 }
217 232
218 static unsigned 233 static unsigned
219 hatval_to_sdl(Sint32 hatval) 234 hatval_to_sdl(Sint32 hatval)
220 { 235 {
221 static const unsigned hat_dir_map[8] = { 236 static const unsigned hat_dir_map[8] = {
222 SDL_HAT_UP, SDL_HAT_RIGHTUP, SDL_HAT_RIGHT, SDL_HAT_RIGHTDOWN, 237 SDL_HAT_UP, SDL_HAT_RIGHTUP, SDL_HAT_RIGHT, SDL_HAT_RIGHTDOWN,
223 SDL_HAT_DOWN, SDL_HAT_LEFTDOWN, SDL_HAT_LEFT, SDL_HAT_LEFTUP 238 SDL_HAT_DOWN, SDL_HAT_LEFTDOWN, SDL_HAT_LEFT, SDL_HAT_LEFTUP
224 }; 239 };
225 unsigned result; 240 unsigned result;
226 if ((hatval & 7) == hatval) 241 if ((hatval & 7) == hatval)
227 result = hat_dir_map[hatval]; 242 result = hat_dir_map[hatval];
228 else 243 else
229 result = SDL_HAT_CENTERED; 244 result = SDL_HAT_CENTERED;
230 return result; 245 return result;
231 } 246 }
232 247
233 248
234 int 249 int
235 SDL_SYS_JoystickOpen(SDL_Joystick *joy) 250 SDL_SYS_JoystickOpen(SDL_Joystick * joy)
236 { 251 {
237 char *path = joynames[joy->index]; 252 char *path = joynames[joy->index];
238 struct joystick_hwdata *hw; 253 struct joystick_hwdata *hw;
239 struct hid_item hitem; 254 struct hid_item hitem;
240 struct hid_data *hdata; 255 struct hid_data *hdata;
241 struct report *rep; 256 struct report *rep;
242 int fd; 257 int fd;
243 int i; 258 int i;
244 259
245 fd = open(path, O_RDONLY); 260 fd = open(path, O_RDONLY);
246 if (fd == -1) { 261 if (fd == -1) {
247 SDL_SetError("%s: %s", path, strerror(errno)); 262 SDL_SetError("%s: %s", path, strerror(errno));
248 return (-1); 263 return (-1);
249 } 264 }
250 265
251 hw = (struct joystick_hwdata *)SDL_malloc(sizeof(struct joystick_hwdata)); 266 hw = (struct joystick_hwdata *)
252 if (hw == NULL) { 267 SDL_malloc(sizeof(struct joystick_hwdata));
253 SDL_OutOfMemory(); 268 if (hw == NULL) {
254 close(fd); 269 SDL_OutOfMemory();
255 return (-1); 270 close(fd);
256 } 271 return (-1);
257 joy->hwdata = hw; 272 }
258 hw->fd = fd; 273 joy->hwdata = hw;
259 hw->path = strdup(path); 274 hw->fd = fd;
260 if (! SDL_strncmp(path, "/dev/joy", 8)) { 275 hw->path = strdup(path);
261 hw->type = BSDJOY_JOY; 276 if (!SDL_strncmp(path, "/dev/joy", 8)) {
262 joy->naxes = 2; 277 hw->type = BSDJOY_JOY;
263 joy->nbuttons = 2; 278 joy->naxes = 2;
264 joy->nhats = 0; 279 joy->nbuttons = 2;
265 joy->nballs = 0; 280 joy->nhats = 0;
266 joydevnames[joy->index] = strdup("Gameport joystick"); 281 joy->nballs = 0;
267 goto usbend; 282 joydevnames[joy->index] = strdup("Gameport joystick");
268 } else { 283 goto usbend;
269 hw->type = BSDJOY_UHID; 284 } else {
270 } 285 hw->type = BSDJOY_UHID;
271 286 }
272 { 287
273 int ax; 288 {
274 for (ax = 0; ax < JOYAXE_count; ax++) 289 int ax;
275 hw->axis_map[ax] = -1; 290 for (ax = 0; ax < JOYAXE_count; ax++)
276 } 291 hw->axis_map[ax] = -1;
277 hw->repdesc = hid_get_report_desc(fd); 292 }
278 if (hw->repdesc == NULL) { 293 hw->repdesc = hid_get_report_desc(fd);
279 SDL_SetError("%s: USB_GET_REPORT_DESC: %s", hw->path, 294 if (hw->repdesc == NULL) {
280 strerror(errno)); 295 SDL_SetError("%s: USB_GET_REPORT_DESC: %s", hw->path,
281 goto usberr; 296 strerror(errno));
282 } 297 goto usberr;
283 298 }
284 rep = &hw->inreport; 299
285 if (ioctl(fd, USB_GET_REPORT_ID, &rep->rid) < 0) { 300 rep = &hw->inreport;
286 rep->rid = -1; /* XXX */ 301 if (ioctl(fd, USB_GET_REPORT_ID, &rep->rid) < 0) {
287 } 302 rep->rid = -1; /* XXX */
288 if (report_alloc(rep, hw->repdesc, REPORT_INPUT) < 0) { 303 }
289 goto usberr; 304 if (report_alloc(rep, hw->repdesc, REPORT_INPUT) < 0) {
290 } 305 goto usberr;
291 if (rep->size <= 0) { 306 }
292 SDL_SetError("%s: Input report descriptor has invalid length", 307 if (rep->size <= 0) {
293 hw->path); 308 SDL_SetError("%s: Input report descriptor has invalid length",
294 goto usberr; 309 hw->path);
295 } 310 goto usberr;
296 311 }
297 #if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_version >= 500111) 312 #if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_version >= 500111)
298 hdata = hid_start_parse(hw->repdesc, 1 << hid_input, rep->rid); 313 hdata = hid_start_parse(hw->repdesc, 1 << hid_input, rep->rid);
299 #else 314 #else
300 hdata = hid_start_parse(hw->repdesc, 1 << hid_input); 315 hdata = hid_start_parse(hw->repdesc, 1 << hid_input);
301 #endif 316 #endif
302 if (hdata == NULL) { 317 if (hdata == NULL) {
303 SDL_SetError("%s: Cannot start HID parser", hw->path); 318 SDL_SetError("%s: Cannot start HID parser", hw->path);
304 goto usberr; 319 goto usberr;
305 } 320 }
306 joy->naxes = 0; 321 joy->naxes = 0;
307 joy->nbuttons = 0; 322 joy->nbuttons = 0;
308 joy->nhats = 0; 323 joy->nhats = 0;
309 joy->nballs = 0; 324 joy->nballs = 0;
310 for (i=0; i<JOYAXE_count; i++) 325 for (i = 0; i < JOYAXE_count; i++)
311 hw->axis_map[i] = -1; 326 hw->axis_map[i] = -1;
312 327
313 while (hid_get_item(hdata, &hitem) > 0) { 328 while (hid_get_item(hdata, &hitem) > 0) {
314 char *sp; 329 char *sp;
315 const char *s; 330 const char *s;
316 331
317 switch (hitem.kind) { 332 switch (hitem.kind) {
318 case hid_collection: 333 case hid_collection:
319 switch (HID_PAGE(hitem.usage)) { 334 switch (HID_PAGE(hitem.usage)) {
320 case HUP_GENERIC_DESKTOP: 335 case HUP_GENERIC_DESKTOP:
321 switch (HID_USAGE(hitem.usage)) { 336 switch (HID_USAGE(hitem.usage)) {
322 case HUG_JOYSTICK: 337 case HUG_JOYSTICK:
323 case HUG_GAME_PAD: 338 case HUG_GAME_PAD:
324 s = hid_usage_in_page(hitem.usage); 339 s = hid_usage_in_page(hitem.usage);
325 sp = SDL_malloc(SDL_strlen(s) + 5); 340 sp = SDL_malloc(SDL_strlen(s) + 5);
326 SDL_snprintf(sp, SDL_strlen(s) + 5, "%s (%d)", s, 341 SDL_snprintf(sp, SDL_strlen(s) + 5, "%s (%d)",
327 joy->index); 342 s, joy->index);
328 joydevnames[joy->index] = sp; 343 joydevnames[joy->index] = sp;
329 } 344 }
330 } 345 }
331 break; 346 break;
332 case hid_input: 347 case hid_input:
333 switch (HID_PAGE(hitem.usage)) { 348 switch (HID_PAGE(hitem.usage)) {
334 case HUP_GENERIC_DESKTOP: { 349 case HUP_GENERIC_DESKTOP:
335 unsigned usage = HID_USAGE(hitem.usage); 350 {
336 int joyaxe = usage_to_joyaxe(usage); 351 unsigned usage = HID_USAGE(hitem.usage);
337 if (joyaxe >= 0) { 352 int joyaxe = usage_to_joyaxe(usage);
338 hw->axis_map[joyaxe] = 1; 353 if (joyaxe >= 0) {
339 } else if (usage == HUG_HAT_SWITCH) { 354 hw->axis_map[joyaxe] = 1;
340 joy->nhats++; 355 } else if (usage == HUG_HAT_SWITCH) {
341 } 356 joy->nhats++;
342 break; 357 }
343 } 358 break;
344 case HUP_BUTTON: 359 }
345 joy->nbuttons++; 360 case HUP_BUTTON:
346 break; 361 joy->nbuttons++;
347 default: 362 break;
348 break; 363 default:
349 } 364 break;
350 break; 365 }
351 default: 366 break;
352 break; 367 default:
353 } 368 break;
354 } 369 }
355 hid_end_parse(hdata); 370 }
356 for (i=0; i<JOYAXE_count; i++) 371 hid_end_parse(hdata);
357 if (hw->axis_map[i] > 0) 372 for (i = 0; i < JOYAXE_count; i++)
358 hw->axis_map[i] = joy->naxes++; 373 if (hw->axis_map[i] > 0)
359 374 hw->axis_map[i] = joy->naxes++;
360 usbend: 375
361 /* The poll blocks the event thread. */ 376 usbend:
362 fcntl(fd, F_SETFL, O_NONBLOCK); 377 /* The poll blocks the event thread. */
363 378 fcntl(fd, F_SETFL, O_NONBLOCK);
364 return (0); 379
365 usberr: 380 return (0);
366 close(hw->fd); 381 usberr:
367 SDL_free(hw->path); 382 close(hw->fd);
368 SDL_free(hw); 383 SDL_free(hw->path);
369 return (-1); 384 SDL_free(hw);
385 return (-1);
370 } 386 }
371 387
372 void 388 void
373 SDL_SYS_JoystickUpdate(SDL_Joystick *joy) 389 SDL_SYS_JoystickUpdate(SDL_Joystick * joy)
374 { 390 {
375 struct hid_item hitem; 391 struct hid_item hitem;
376 struct hid_data *hdata; 392 struct hid_data *hdata;
377 struct report *rep; 393 struct report *rep;
378 int nbutton, naxe = -1; 394 int nbutton, naxe = -1;
379 Sint32 v; 395 Sint32 v;
380 396
381 #if defined(__FREEBSD__) || SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H 397 #if defined(__FREEBSD__) || SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H
382 struct joystick gameport; 398 struct joystick gameport;
383 static int x, y, xmin = 0xffff, ymin = 0xffff, xmax = 0, ymax = 0; 399 static int x, y, xmin = 0xffff, ymin = 0xffff, xmax = 0, ymax = 0;
384 400
385 if (joy->hwdata->type == BSDJOY_JOY) { 401 if (joy->hwdata->type == BSDJOY_JOY) {
386 if (read(joy->hwdata->fd, &gameport, sizeof gameport) != sizeof gameport) 402 if (read(joy->hwdata->fd, &gameport, sizeof gameport) !=
387 return; 403 sizeof gameport)
388 if (abs(x - gameport.x) > 8) { 404 return;
389 x = gameport.x; 405 if (abs(x - gameport.x) > 8) {
390 if (x < xmin) { 406 x = gameport.x;
391 xmin = x; 407 if (x < xmin) {
392 } 408 xmin = x;
393 if (x > xmax) { 409 }
394 xmax = x; 410 if (x > xmax) {
395 } 411 xmax = x;
396 if (xmin == xmax) { 412 }
397 xmin--; 413 if (xmin == xmax) {
398 xmax++; 414 xmin--;
399 } 415 xmax++;
400 v = (Sint32)x; 416 }
401 v -= (xmax + xmin + 1)/2; 417 v = (Sint32) x;
402 v *= 32768/((xmax - xmin + 1)/2); 418 v -= (xmax + xmin + 1) / 2;
403 SDL_PrivateJoystickAxis(joy, 0, v); 419 v *= 32768 / ((xmax - xmin + 1) / 2);
404 } 420 SDL_PrivateJoystickAxis(joy, 0, v);
405 if (abs(y - gameport.y) > 8) { 421 }
406 y = gameport.y; 422 if (abs(y - gameport.y) > 8) {
407 if (y < ymin) { 423 y = gameport.y;
408 ymin = y; 424 if (y < ymin) {
409 } 425 ymin = y;
410 if (y > ymax) { 426 }
411 ymax = y; 427 if (y > ymax) {
412 } 428 ymax = y;
413 if (ymin == ymax) { 429 }
414 ymin--; 430 if (ymin == ymax) {
415 ymax++; 431 ymin--;
416 } 432 ymax++;
417 v = (Sint32)y; 433 }
418 v -= (ymax + ymin + 1)/2; 434 v = (Sint32) y;
419 v *= 32768/((ymax - ymin + 1)/2); 435 v -= (ymax + ymin + 1) / 2;
420 SDL_PrivateJoystickAxis(joy, 1, v); 436 v *= 32768 / ((ymax - ymin + 1) / 2);
421 } 437 SDL_PrivateJoystickAxis(joy, 1, v);
422 if (gameport.b1 != joy->buttons[0]) { 438 }
423 SDL_PrivateJoystickButton(joy, 0, gameport.b1); 439 if (gameport.b1 != joy->buttons[0]) {
424 } 440 SDL_PrivateJoystickButton(joy, 0, gameport.b1);
425 if (gameport.b2 != joy->buttons[1]) { 441 }
426 SDL_PrivateJoystickButton(joy, 1, gameport.b2); 442 if (gameport.b2 != joy->buttons[1]) {
427 } 443 SDL_PrivateJoystickButton(joy, 1, gameport.b2);
428 return; 444 }
429 } 445 return;
446 }
430 #endif /* defined(__FREEBSD__) || SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H */ 447 #endif /* defined(__FREEBSD__) || SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H */
431 448
432 rep = &joy->hwdata->inreport; 449 rep = &joy->hwdata->inreport;
433 450
434 if (read(joy->hwdata->fd, REP_BUF_DATA(rep), rep->size) != rep->size) { 451 if (read(joy->hwdata->fd, REP_BUF_DATA(rep), rep->size) != rep->size) {
435 return; 452 return;
436 } 453 }
437 #if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_version >= 500111) 454 #if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_version >= 500111)
438 hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input, rep->rid); 455 hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input, rep->rid);
439 #else 456 #else
440 hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input); 457 hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input);
441 #endif 458 #endif
442 if (hdata == NULL) { 459 if (hdata == NULL) {
443 fprintf(stderr, "%s: Cannot start HID parser\n", 460 fprintf(stderr, "%s: Cannot start HID parser\n", joy->hwdata->path);
444 joy->hwdata->path); 461 return;
445 return; 462 }
446 } 463
447 464 for (nbutton = 0; hid_get_item(hdata, &hitem) > 0;) {
448 for (nbutton = 0; hid_get_item(hdata, &hitem) > 0;) { 465 switch (hitem.kind) {
449 switch (hitem.kind) { 466 case hid_input:
450 case hid_input: 467 switch (HID_PAGE(hitem.usage)) {
451 switch (HID_PAGE(hitem.usage)) { 468 case HUP_GENERIC_DESKTOP:
452 case HUP_GENERIC_DESKTOP: { 469 {
453 unsigned usage = HID_USAGE(hitem.usage); 470 unsigned usage = HID_USAGE(hitem.usage);
454 int joyaxe = usage_to_joyaxe(usage); 471 int joyaxe = usage_to_joyaxe(usage);
455 if (joyaxe >= 0) { 472 if (joyaxe >= 0) {
456 naxe = joy->hwdata->axis_map[joyaxe]; 473 naxe = joy->hwdata->axis_map[joyaxe];
457 /* scaleaxe */ 474 /* scaleaxe */
458 v = (Sint32)hid_get_data(REP_BUF_DATA(rep), 475 v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
459 &hitem); 476 v -= (hitem.logical_maximum +
460 v -= (hitem.logical_maximum + hitem.logical_minimum + 1)/2; 477 hitem.logical_minimum + 1) / 2;
461 v *= 32768/((hitem.logical_maximum - hitem.logical_minimum + 1)/2); 478 v *= 32768 /
462 if (v != joy->axes[naxe]) { 479 ((hitem.logical_maximum -
463 SDL_PrivateJoystickAxis(joy, naxe, v); 480 hitem.logical_minimum + 1) / 2);
464 } 481 if (v != joy->axes[naxe]) {
465 } else if (usage == HUG_HAT_SWITCH) { 482 SDL_PrivateJoystickAxis(joy, naxe, v);
466 v = (Sint32)hid_get_data(REP_BUF_DATA(rep), 483 }
467 &hitem); 484 } else if (usage == HUG_HAT_SWITCH) {
468 SDL_PrivateJoystickHat(joy, 0, 485 v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
469 hatval_to_sdl(v)-hitem.logical_minimum); 486 SDL_PrivateJoystickHat(joy, 0,
470 } 487 hatval_to_sdl(v) -
471 break; 488 hitem.logical_minimum);
472 } 489 }
473 case HUP_BUTTON: 490 break;
474 v = (Sint32)hid_get_data(REP_BUF_DATA(rep), 491 }
475 &hitem); 492 case HUP_BUTTON:
476 if (joy->buttons[nbutton] != v) { 493 v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
477 SDL_PrivateJoystickButton(joy, 494 if (joy->buttons[nbutton] != v) {
478 nbutton, v); 495 SDL_PrivateJoystickButton(joy, nbutton, v);
479 } 496 }
480 nbutton++; 497 nbutton++;
481 break; 498 break;
482 default: 499 default:
483 continue; 500 continue;
484 } 501 }
485 break; 502 break;
486 default: 503 default:
487 break; 504 break;
488 } 505 }
489 } 506 }
490 hid_end_parse(hdata); 507 hid_end_parse(hdata);
491 508
492 return; 509 return;
493 } 510 }
494 511
495 /* Function to close a joystick after use */ 512 /* Function to close a joystick after use */
496 void 513 void
497 SDL_SYS_JoystickClose(SDL_Joystick *joy) 514 SDL_SYS_JoystickClose(SDL_Joystick * joy)
498 { 515 {
499 if (SDL_strncmp(joy->hwdata->path, "/dev/joy", 8)) { 516 if (SDL_strncmp(joy->hwdata->path, "/dev/joy", 8)) {
500 report_free(&joy->hwdata->inreport); 517 report_free(&joy->hwdata->inreport);
501 hid_dispose_report_desc(joy->hwdata->repdesc); 518 hid_dispose_report_desc(joy->hwdata->repdesc);
502 } 519 }
503 close(joy->hwdata->fd); 520 close(joy->hwdata->fd);
504 SDL_free(joy->hwdata->path); 521 SDL_free(joy->hwdata->path);
505 SDL_free(joy->hwdata); 522 SDL_free(joy->hwdata);
506 523
507 return; 524 return;
508 } 525 }
509 526
510 void 527 void
511 SDL_SYS_JoystickQuit(void) 528 SDL_SYS_JoystickQuit(void)
512 { 529 {
513 int i; 530 int i;
514 531
515 for (i = 0; i < MAX_JOYS; i++) { 532 for (i = 0; i < MAX_JOYS; i++) {
516 if (joynames[i] != NULL) 533 if (joynames[i] != NULL)
517 SDL_free(joynames[i]); 534 SDL_free(joynames[i]);
518 if (joydevnames[i] != NULL) 535 if (joydevnames[i] != NULL)
519 SDL_free(joydevnames[i]); 536 SDL_free(joydevnames[i]);
520 } 537 }
521 538
522 return; 539 return;
523 } 540 }
524 541
525 static int 542 static int
526 report_alloc(struct report *r, struct report_desc *rd, int repind) 543 report_alloc(struct report *r, struct report_desc *rd, int repind)
527 { 544 {
528 int len; 545 int len;
529 546
530 #ifdef __DragonFly__ 547 #ifdef __DragonFly__
531 len = hid_report_size(rd, r->rid, repinfo[repind].kind); 548 len = hid_report_size(rd, r->rid, repinfo[repind].kind);
532 #elif __FREEBSD__ 549 #elif __FREEBSD__
533 # if (__FreeBSD_version >= 460000) 550 # if (__FreeBSD_version >= 460000)
534 # if (__FreeBSD_version <= 500111) 551 # if (__FreeBSD_version <= 500111)
535 len = hid_report_size(rd, r->rid, repinfo[repind].kind); 552 len = hid_report_size(rd, r->rid, repinfo[repind].kind);
536 # else 553 # else
537 len = hid_report_size(rd, repinfo[repind].kind, r->rid); 554 len = hid_report_size(rd, repinfo[repind].kind, r->rid);
538 # endif 555 # endif
539 # else 556 # else
540 len = hid_report_size(rd, repinfo[repind].kind, &r->rid); 557 len = hid_report_size(rd, repinfo[repind].kind, &r->rid);
541 # endif 558 # endif
542 #else 559 #else
543 # ifdef USBHID_NEW 560 # ifdef USBHID_NEW
544 len = hid_report_size(rd, repinfo[repind].kind, r->rid); 561 len = hid_report_size(rd, repinfo[repind].kind, r->rid);
545 # else 562 # else
546 len = hid_report_size(rd, repinfo[repind].kind, &r->rid); 563 len = hid_report_size(rd, repinfo[repind].kind, &r->rid);
547 # endif 564 # endif
548 #endif 565 #endif
549 566
550 if (len < 0) { 567 if (len < 0) {
551 SDL_SetError("Negative HID report size"); 568 SDL_SetError("Negative HID report size");
552 return (-1); 569 return (-1);
553 } 570 }
554 r->size = len; 571 r->size = len;
555 572
556 if (r->size > 0) { 573 if (r->size > 0) {
557 r->buf = SDL_malloc(sizeof(*r->buf) - sizeof(REP_BUF_DATA(r)) + 574 r->buf = SDL_malloc(sizeof(*r->buf) - sizeof(REP_BUF_DATA(r)) +
558 r->size); 575 r->size);
559 if (r->buf == NULL) { 576 if (r->buf == NULL) {
560 SDL_OutOfMemory(); 577 SDL_OutOfMemory();
561 return (-1); 578 return (-1);
562 } 579 }
563 } else { 580 } else {
564 r->buf = NULL; 581 r->buf = NULL;
565 } 582 }
566 583
567 r->status = SREPORT_CLEAN; 584 r->status = SREPORT_CLEAN;
568 return (0); 585 return (0);
569 } 586 }
570 587
571 static void 588 static void
572 report_free(struct report *r) 589 report_free(struct report *r)
573 { 590 {
574 if (r->buf != NULL) { 591 if (r->buf != NULL) {
575 SDL_free(r->buf); 592 SDL_free(r->buf);
576 } 593 }
577 r->status = SREPORT_UNINIT; 594 r->status = SREPORT_UNINIT;
578 } 595 }
579 596
580 #endif /* SDL_JOYSTICK_USBHID */ 597 #endif /* SDL_JOYSTICK_USBHID */
598 /* vi: set ts=4 sw=4 expandtab: */