0b09ffb4664950790cb690771b584afa0d9130f5
[sdl_omap.git] / src / joystick / linux / SDL_sysjoystick.c
1 /*
2     SDL - Simple DirectMedia Layer
3     Copyright (C) 1997-2009 Sam Lantinga
4
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Lesser General Public
7     License as published by the Free Software Foundation; either
8     version 2.1 of the License, or (at your option) any later version.
9
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Lesser General Public License for more details.
14
15     You should have received a copy of the GNU Lesser General Public
16     License along with this library; if not, write to the Free Software
17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
19     Sam Lantinga
20     slouken@libsdl.org
21 */
22 #include "SDL_config.h"
23
24 #ifdef SDL_JOYSTICK_LINUX
25
26 /* This is the system specific header for the SDL joystick API */
27
28 #include <sys/stat.h>
29 #include <unistd.h>
30 #include <fcntl.h>
31 #include <sys/ioctl.h>
32 #include <limits.h>             /* For the definition of PATH_MAX */
33 #include <linux/joystick.h>
34 #if SDL_INPUT_LINUXEV
35 #include <linux/input.h>
36 #endif
37
38 #include "SDL_joystick.h"
39 #include "../SDL_sysjoystick.h"
40 #include "../SDL_joystick_c.h"
41
42 /* Special joystick configurations */
43 static struct {
44         const char *name;
45         int naxes;
46         int nhats;
47         int nballs;
48 } special_joysticks[] = {
49         { "MadCatz Panther XL", 3, 2, 1 }, /* We don't handle rudder (axis 8) */
50         { "SideWinder Precision Pro", 4, 1, 0 },
51         { "SideWinder 3D Pro", 4, 1, 0 },
52         { "Microsoft SideWinder 3D Pro", 4, 1, 0 },
53         { "Microsoft SideWinder Precision Pro", 4, 1, 0 },
54         { "Microsoft SideWinder Dual Strike USB version 1.0", 2, 1, 0 },
55         { "WingMan Interceptor", 3, 3, 0 },
56         { "WingMan Extreme Digital 3D", 4, 1, 0 },
57         { "Microsoft SideWinder Precision 2 Joystick", 4, 1, 0 },
58         { "Logitech Inc. WingMan Extreme Digital 3D", 4, 1, 0 },
59         { "Saitek Saitek X45", 6, 1, 0 }
60 };
61
62 /* It looks like newer kernels have the logical mapping at the driver level */
63 #define NO_LOGICAL_JOYSTICKS
64
65 #ifndef NO_LOGICAL_JOYSTICKS
66
67 /*
68    Some USB HIDs show up as a single joystick even though they actually
69    control 2 or more joysticks.
70 */
71 /*
72    This code handles the MP-8800 (Quad) and MP-8866 (Dual), which can
73    be identified by their transparent blue design. It's quite trivial
74    to add other joysticks with similar quirky behavior.
75    -id
76 */
77
78 struct joystick_logical_mapping {
79         int njoy;
80         int nthing;
81 };
82
83 /*
84    {logical joy, logical axis},
85    {logical joy, logical hat},
86    {logical joy, logical ball},
87    {logical joy, logical button}
88 */
89
90 static struct joystick_logical_mapping mp88xx_1_logical_axismap[] = {
91    {0,0},{0,1},{0,2},{0,3},{0,4},{0,5}
92 };
93 static struct joystick_logical_mapping mp88xx_1_logical_buttonmap[] = {
94    {0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{0,7},{0,8},{0,9},{0,10},{0,11}
95 };
96
97 static struct joystick_logical_mapping mp88xx_2_logical_axismap[] = {
98    {0,0},{0,1},{0,2},{1,0},{1,1},{0,3},
99    {1,2},{1,3},{0,4},{0,5},{1,4},{1,5}
100 };
101 static struct joystick_logical_mapping mp88xx_2_logical_buttonmap[] = {
102    {0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{0,7},{0,8},{0,9},{0,10},{0,11},
103    {1,0},{1,1},{1,2},{1,3},{1,4},{1,5},{1,6},{1,7},{1,8},{1,9},{1,10},{1,11}
104 };
105
106 static struct joystick_logical_mapping mp88xx_3_logical_axismap[] = {
107    {0,0},{0,1},{0,2},{1,0},{1,1},{0,3},
108    {1,2},{1,3},{2,0},{2,1},{2,2},{2,3},
109    {0,4},{0,5},{1,4},{1,5},{2,4},{2,5}
110 };
111 static struct joystick_logical_mapping mp88xx_3_logical_buttonmap[] = {
112    {0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{0,7},{0,8},{0,9},{0,10},{0,11},
113    {1,0},{1,1},{1,2},{1,3},{1,4},{1,5},{1,6},{1,7},{1,8},{1,9},{1,10},{1,11},
114    {2,0},{2,1},{2,2},{2,3},{2,4},{2,5},{2,6},{2,7},{2,8},{2,9},{2,10},{2,11}
115 };
116
117 static struct joystick_logical_mapping mp88xx_4_logical_axismap[] = {
118    {0,0},{0,1},{0,2},{1,0},{1,1},{0,3},
119    {1,2},{1,3},{2,0},{2,1},{2,2},{2,3},
120    {3,0},{3,1},{3,2},{3,3},{0,4},{0,5},
121    {1,4},{1,5},{2,4},{2,5},{3,4},{3,5}
122 };
123 static struct joystick_logical_mapping mp88xx_4_logical_buttonmap[] = {
124    {0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{0,7},{0,8},{0,9},{0,10},{0,11},
125    {1,0},{1,1},{1,2},{1,3},{1,4},{1,5},{1,6},{1,7},{1,8},{1,9},{1,10},{1,11},
126    {2,0},{2,1},{2,2},{2,3},{2,4},{2,5},{2,6},{2,7},{2,8},{2,9},{2,10},{2,11},
127    {3,0},{3,1},{3,2},{3,3},{3,4},{3,5},{3,6},{3,7},{3,8},{3,9},{3,10},{3,11}
128 };
129
130 struct joystick_logical_layout {
131         int naxes;
132         int nhats;
133         int nballs;
134         int nbuttons;
135 };
136
137 static struct joystick_logical_layout mp88xx_1_logical_layout[] = {
138         {6, 0, 0, 12}
139 };
140 static struct joystick_logical_layout mp88xx_2_logical_layout[] = {
141         {6, 0, 0, 12},
142         {6, 0, 0, 12}
143 };
144 static struct joystick_logical_layout mp88xx_3_logical_layout[] = {
145         {6, 0, 0, 12},
146         {6, 0, 0, 12},
147         {6, 0, 0, 12}
148 };
149 static struct joystick_logical_layout mp88xx_4_logical_layout[] = {
150         {6, 0, 0, 12},
151         {6, 0, 0, 12},
152         {6, 0, 0, 12},
153         {6, 0, 0, 12}
154 };
155
156 /*
157    This array sets up a means of mapping a single physical joystick to
158    multiple logical joysticks. (djm)
159                                                                                 
160    njoys
161         the number of logical joysticks
162                                                                                 
163    layouts
164         an array of layout structures, one to describe each logical joystick
165                                                                                 
166    axes, hats, balls, buttons
167         arrays that map a physical thingy to a logical thingy
168  */
169 struct joystick_logicalmap {
170         const char *name;
171         int nbuttons;
172         int njoys;
173         struct joystick_logical_layout *layout;
174         struct joystick_logical_mapping *axismap;
175         struct joystick_logical_mapping *hatmap;
176         struct joystick_logical_mapping *ballmap;
177         struct joystick_logical_mapping *buttonmap;
178 };
179
180 static struct joystick_logicalmap joystick_logicalmap[] = {
181         {
182                 "WiseGroup.,Ltd MP-8866 Dual USB Joypad",
183                 12,
184                 1,
185                 mp88xx_1_logical_layout,
186                 mp88xx_1_logical_axismap,
187                 NULL,
188                 NULL,
189                 mp88xx_1_logical_buttonmap
190         },
191         {
192                 "WiseGroup.,Ltd MP-8866 Dual USB Joypad",
193                 24,
194                 2,
195                 mp88xx_2_logical_layout,
196                 mp88xx_2_logical_axismap,
197                 NULL,
198                 NULL,
199                 mp88xx_2_logical_buttonmap
200         },
201         {
202                 "WiseGroup.,Ltd MP-8800 Quad USB Joypad",
203                 12,
204                 1,
205                 mp88xx_1_logical_layout,
206                 mp88xx_1_logical_axismap,
207                 NULL,
208                 NULL,
209                 mp88xx_1_logical_buttonmap
210         },
211         {
212                 "WiseGroup.,Ltd MP-8800 Quad USB Joypad",
213                 24,
214                 2,
215                 mp88xx_2_logical_layout,
216                 mp88xx_2_logical_axismap,
217                 NULL,
218                 NULL,
219                 mp88xx_2_logical_buttonmap
220         },
221         {
222                 "WiseGroup.,Ltd MP-8800 Quad USB Joypad",
223                 36,
224                 3,
225                 mp88xx_3_logical_layout,
226                 mp88xx_3_logical_axismap,
227                 NULL,
228                 NULL,
229                 mp88xx_3_logical_buttonmap
230         },
231         {
232                 "WiseGroup.,Ltd MP-8800 Quad USB Joypad",
233                 48,
234                 4,
235                 mp88xx_4_logical_layout,
236                 mp88xx_4_logical_axismap,
237                 NULL,
238                 NULL,
239                 mp88xx_4_logical_buttonmap
240         }
241 };
242
243 /* find the head of a linked list, given a point in it
244  */
245 #define SDL_joylist_head(i, start)\
246         for(i = start; SDL_joylist[i].fname == NULL;) i = SDL_joylist[i].prev;
247
248 #define SDL_logical_joydecl(d) d
249
250
251 #else
252
253 #define SDL_logical_joydecl(d)
254
255 #endif /* USE_LOGICAL_JOYSTICKS */
256
257 /* The maximum number of joysticks we'll detect */
258 #define MAX_JOYSTICKS   32
259
260 /* A list of available joysticks */
261 static struct
262 {
263         char* fname;
264 #ifndef NO_LOGICAL_JOYSTICKS
265         SDL_Joystick* joy;
266         struct joystick_logicalmap* map;
267         int prev;
268         int next;
269         int logicalno;
270 #endif /* USE_LOGICAL_JOYSTICKS */
271 } SDL_joylist[MAX_JOYSTICKS];
272
273
274 /* The private structure used to keep track of a joystick */
275 struct joystick_hwdata {
276         int fd;
277         /* The current linux joystick driver maps hats to two axes */
278         struct hwdata_hat {
279                 int axis[2];
280         } *hats;
281         /* The current linux joystick driver maps balls to two axes */
282         struct hwdata_ball {
283                 int axis[2];
284         } *balls;
285
286         /* Support for the Linux 2.4 unified input interface */
287 #if SDL_INPUT_LINUXEV
288         SDL_bool is_hid;
289         Uint8 key_map[KEY_MAX-BTN_MISC];
290         Uint8 abs_map[ABS_MAX];
291         struct axis_correct {
292                 int used;
293                 int coef[3];
294         } abs_correct[ABS_MAX];
295 #endif
296 };
297
298
299 #ifndef NO_LOGICAL_JOYSTICKS
300
301 static int CountLogicalJoysticks(int max)
302 {
303    register int i, j, k, ret, prev;
304    const char* name;
305    int nbuttons, fd;
306    unsigned char n;
307
308    ret = 0;
309
310    for(i = 0; i < max; i++) {
311       name = SDL_SYS_JoystickName(i);
312         
313       fd = open(SDL_joylist[i].fname, O_RDONLY, 0);
314       if ( fd >= 0 ) {
315          if ( ioctl(fd, JSIOCGBUTTONS, &n) < 0 ) {
316             nbuttons = -1;
317          } else {
318             nbuttons = n;
319          }
320          close(fd);
321       }
322       else {
323          nbuttons=-1;
324       }
325
326       if (name) {
327          for(j = 0; j < SDL_arraysize(joystick_logicalmap); j++) {
328             if (!SDL_strcmp(name, joystick_logicalmap[j].name) && (nbuttons==-1 || nbuttons==joystick_logicalmap[j].nbuttons)) {
329                prev = i;
330                SDL_joylist[prev].map = &(joystick_logicalmap[j]);
331
332                for(k = 1; k < joystick_logicalmap[j].njoys; k++) {
333                   SDL_joylist[prev].next = max + ret;
334                   SDL_joylist[max+ret].prev = prev;
335                   
336                   prev = max + ret;
337                   SDL_joylist[prev].logicalno = k;
338                   SDL_joylist[prev].map = &(joystick_logicalmap[j]);
339                   ret++;
340                }
341
342                break;
343             }
344          }
345       }
346    }
347
348    return ret;
349 }
350
351 static void LogicalSuffix(int logicalno, char* namebuf, int len)
352 {
353    register int slen;
354    const static char suffixs[] =
355       "01020304050607080910111213141516171819"
356       "20212223242526272829303132";
357    const char* suffix;
358    slen = SDL_strlen(namebuf);
359    suffix = NULL;
360
361    if (logicalno*2<sizeof(suffixs))
362       suffix = suffixs + (logicalno*2);
363
364    if (slen + 4 < len && suffix) {
365       namebuf[slen++] = ' ';
366       namebuf[slen++] = '#';
367       namebuf[slen++] = suffix[0];
368       namebuf[slen++] = suffix[1];
369       namebuf[slen++] = 0;
370    }
371 }
372
373 #endif /* USE_LOGICAL_JOYSTICKS */
374
375 #if SDL_INPUT_LINUXEV
376 #define test_bit(nr, addr) \
377         (((1UL << ((nr) % (sizeof(long) * 8))) & ((addr)[(nr) / (sizeof(long) * 8)])) != 0)
378 #define NBITS(x) ((((x)-1)/(sizeof(long) * 8))+1)
379
380 static int EV_IsJoystick(int fd)
381 {
382         unsigned long evbit[NBITS(EV_MAX)] = { 0 };
383         unsigned long keybit[NBITS(KEY_MAX)] = { 0 };
384         unsigned long absbit[NBITS(ABS_MAX)] = { 0 };
385
386         if ( (ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), evbit) < 0) ||
387              (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) < 0) ||
388              (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) < 0) ) {
389                 return(0);
390         }
391         if (!(test_bit(EV_KEY, evbit) && test_bit(EV_ABS, evbit) &&
392               test_bit(ABS_X, absbit) && test_bit(ABS_Y, absbit) &&
393              (test_bit(BTN_TRIGGER, keybit) || test_bit(BTN_A, keybit) || test_bit(BTN_1, keybit)))) return 0;
394         return(1);
395 }
396
397 #endif /* SDL_INPUT_LINUXEV */
398
399 /* Function to scan the system for joysticks */
400 int SDL_SYS_JoystickInit(void)
401 {
402         /* The base path of the joystick devices */
403         const char *joydev_pattern[] = {
404 #if SDL_INPUT_LINUXEV
405                 "/dev/input/event%d",
406 #endif
407                 "/dev/input/js%d",
408                 "/dev/js%d"
409         };
410         int numjoysticks;
411         int i, j;
412         int fd;
413         char path[PATH_MAX];
414         dev_t dev_nums[MAX_JOYSTICKS];  /* major/minor device numbers */
415         struct stat sb;
416         int n, duplicate;
417
418         numjoysticks = 0;
419
420         /* First see if the user specified a joystick to use */
421         if ( SDL_getenv("SDL_JOYSTICK_DEVICE") != NULL ) {
422                 SDL_strlcpy(path, SDL_getenv("SDL_JOYSTICK_DEVICE"), sizeof(path));
423                 if ( stat(path, &sb) == 0 ) {
424                         fd = open(path, O_RDONLY, 0);
425                         if ( fd >= 0 ) {
426                                 /* Assume the user knows what they're doing. */
427                                 SDL_joylist[numjoysticks].fname = SDL_strdup(path);
428                                 if ( SDL_joylist[numjoysticks].fname ) {
429                                         dev_nums[numjoysticks] = sb.st_rdev;
430                                         ++numjoysticks;
431                                 }
432                                 close(fd);
433                         }
434                 }
435         }
436
437         for ( i=0; i<SDL_arraysize(joydev_pattern); ++i ) {
438                 for ( j=0; j < MAX_JOYSTICKS; ++j ) {
439                         SDL_snprintf(path, SDL_arraysize(path), joydev_pattern[i], j);
440
441                         /* rcg06302000 replaced access(F_OK) call with stat().
442                          * stat() will fail if the file doesn't exist, so it's
443                          * equivalent behaviour.
444                          */
445                         if ( stat(path, &sb) == 0 ) {
446                                 /* Check to make sure it's not already in list.
447                                  * This happens when we see a stick via symlink.
448                                  */
449                                 duplicate = 0;
450                                 for (n=0; (n<numjoysticks) && !duplicate; ++n) {
451                                         if ( sb.st_rdev == dev_nums[n] ) {
452                                                 duplicate = 1;
453                                         }
454                                 }
455                                 if (duplicate) {
456                                         continue;
457                                 }
458
459                                 fd = open(path, O_RDONLY, 0);
460                                 if ( fd < 0 ) {
461                                         continue;
462                                 }
463 #if SDL_INPUT_LINUXEV
464 #ifdef DEBUG_INPUT_EVENTS
465                                 printf("Checking %s\n", path);
466 #endif
467                                 if ( (i == 0) && ! EV_IsJoystick(fd) ) {
468                                         close(fd);
469                                         continue;
470                                 }
471 #endif
472                                 close(fd);
473
474                                 /* We're fine, add this joystick */
475                                 SDL_joylist[numjoysticks].fname = SDL_strdup(path);
476                                 if ( SDL_joylist[numjoysticks].fname ) {
477                                         dev_nums[numjoysticks] = sb.st_rdev;
478                                         ++numjoysticks;
479                                 }
480                         }
481                 }
482
483 #if SDL_INPUT_LINUXEV
484                 /* This is a special case...
485                    If the event devices are valid then the joystick devices
486                    will be duplicates but without extra information about their
487                    hats or balls. Unfortunately, the event devices can't
488                    currently be calibrated, so it's a win-lose situation.
489                    So : /dev/input/eventX = /dev/input/jsY = /dev/jsY
490                 */
491                 if ( (i == 0) && (numjoysticks > 0) )
492                         break;
493 #endif
494         }
495 #ifndef NO_LOGICAL_JOYSTICKS
496         numjoysticks += CountLogicalJoysticks(numjoysticks);
497 #endif
498
499         return(numjoysticks);
500 }
501
502 /* Function to get the device-dependent name of a joystick */
503 const char *SDL_SYS_JoystickName(int index)
504 {
505         int fd;
506         static char namebuf[128];
507         char *name;
508         SDL_logical_joydecl(int oindex = index);
509
510 #ifndef NO_LOGICAL_JOYSTICKS
511         SDL_joylist_head(index, index);
512 #endif
513         name = NULL;
514         fd = open(SDL_joylist[index].fname, O_RDONLY, 0);
515         if ( fd >= 0 ) {
516                 if ( 
517 #if SDL_INPUT_LINUXEV
518                      (ioctl(fd, EVIOCGNAME(sizeof(namebuf)), namebuf) <= 0) &&
519 #endif
520                      (ioctl(fd, JSIOCGNAME(sizeof(namebuf)), namebuf) <= 0) ) {
521                         name = SDL_joylist[index].fname;
522                 } else {
523                         name = namebuf;
524                 }
525                 close(fd);
526
527
528 #ifndef NO_LOGICAL_JOYSTICKS
529                 if (SDL_joylist[oindex].prev || SDL_joylist[oindex].next || index!=oindex)
530                 {
531                    LogicalSuffix(SDL_joylist[oindex].logicalno, namebuf, 128);
532                 }
533 #endif
534         }
535         return name;
536 }
537
538 static int allocate_hatdata(SDL_Joystick *joystick)
539 {
540         int i;
541
542         joystick->hwdata->hats = (struct hwdata_hat *)SDL_malloc(
543                 joystick->nhats * sizeof(struct hwdata_hat));
544         if ( joystick->hwdata->hats == NULL ) {
545                 return(-1);
546         }
547         for ( i=0; i<joystick->nhats; ++i ) {
548                 joystick->hwdata->hats[i].axis[0] = 1;
549                 joystick->hwdata->hats[i].axis[1] = 1;
550         }
551         return(0);
552 }
553
554 static int allocate_balldata(SDL_Joystick *joystick)
555 {
556         int i;
557
558         joystick->hwdata->balls = (struct hwdata_ball *)SDL_malloc(
559                 joystick->nballs * sizeof(struct hwdata_ball));
560         if ( joystick->hwdata->balls == NULL ) {
561                 return(-1);
562         }
563         for ( i=0; i<joystick->nballs; ++i ) {
564                 joystick->hwdata->balls[i].axis[0] = 0;
565                 joystick->hwdata->balls[i].axis[1] = 0;
566         }
567         return(0);
568 }
569
570 static SDL_bool JS_ConfigJoystick(SDL_Joystick *joystick, int fd)
571 {
572         SDL_bool handled;
573         unsigned char n;
574         int old_axes, tmp_naxes, tmp_nhats, tmp_nballs;
575         const char *name;
576         char *env, env_name[128];
577         int i;
578
579         handled = SDL_FALSE;
580
581         /* Default joystick device settings */
582         if ( ioctl(fd, JSIOCGAXES, &n) < 0 ) {
583                 joystick->naxes = 2;
584         } else {
585                 joystick->naxes = n;
586         }
587         if ( ioctl(fd, JSIOCGBUTTONS, &n) < 0 ) {
588                 joystick->nbuttons = 2;
589         } else {
590                 joystick->nbuttons = n;
591         }
592
593         name = SDL_SYS_JoystickName(joystick->index);
594         old_axes = joystick->naxes;
595
596         /* Generic analog joystick support */
597         if ( SDL_strstr(name, "Analog") == name && SDL_strstr(name, "-hat") ) {
598                 if ( SDL_sscanf(name,"Analog %d-axis %*d-button %d-hat",
599                         &tmp_naxes, &tmp_nhats) == 2 ) {
600
601                         joystick->naxes = tmp_naxes;
602                         joystick->nhats = tmp_nhats;
603
604                         handled = SDL_TRUE;
605                 }
606         }
607
608         /* Special joystick support */
609         for ( i=0; i < SDL_arraysize(special_joysticks); ++i ) {
610                 if ( SDL_strcmp(name, special_joysticks[i].name) == 0 ) {
611
612                         joystick->naxes = special_joysticks[i].naxes;
613                         joystick->nhats = special_joysticks[i].nhats;
614                         joystick->nballs = special_joysticks[i].nballs;
615
616                         handled = SDL_TRUE;
617                         break;
618                 }
619         }
620
621         /* User environment joystick support */
622         if ( (env = SDL_getenv("SDL_LINUX_JOYSTICK")) ) {
623                 *env_name = '\0';
624                 if ( *env == '\'' && SDL_sscanf(env, "'%[^']s'", env_name) == 1 )
625                         env += SDL_strlen(env_name)+2;
626                 else if ( SDL_sscanf(env, "%s", env_name) == 1 )
627                         env += SDL_strlen(env_name);
628
629                 if ( SDL_strcmp(name, env_name) == 0 ) {
630
631                         if ( SDL_sscanf(env, "%d %d %d", &tmp_naxes, &tmp_nhats,
632                                 &tmp_nballs) == 3 ) {
633
634                                 joystick->naxes = tmp_naxes;
635                                 joystick->nhats = tmp_nhats;
636                                 joystick->nballs = tmp_nballs;
637
638                                 handled = SDL_TRUE;
639                         }
640                 }
641         }
642
643         /* Remap hats and balls */
644         if (handled) {
645                 if ( joystick->nhats > 0 ) {
646                         if ( allocate_hatdata(joystick) < 0 ) {
647                                 joystick->nhats = 0;
648                         }
649                 }
650                 if ( joystick->nballs > 0 ) {
651                         if ( allocate_balldata(joystick) < 0 ) {
652                                 joystick->nballs = 0;
653                         }
654                 }
655         }
656
657         return(handled);
658 }
659
660 #if SDL_INPUT_LINUXEV
661
662 static SDL_bool EV_ConfigJoystick(SDL_Joystick *joystick, int fd)
663 {
664         int i, t;
665         unsigned long keybit[NBITS(KEY_MAX)] = { 0 };
666         unsigned long absbit[NBITS(ABS_MAX)] = { 0 };
667         unsigned long relbit[NBITS(REL_MAX)] = { 0 };
668
669         /* See if this device uses the new unified event API */
670         if ( (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) >= 0) &&
671              (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) >= 0) &&
672              (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relbit)), relbit) >= 0) ) {
673                 joystick->hwdata->is_hid = SDL_TRUE;
674
675                 /* Get the number of buttons, axes, and other thingamajigs */
676                 for ( i=BTN_JOYSTICK; i < KEY_MAX; ++i ) {
677                         if ( test_bit(i, keybit) ) {
678 #ifdef DEBUG_INPUT_EVENTS
679                                 printf("Joystick has button: 0x%x\n", i);
680 #endif
681                                 joystick->hwdata->key_map[i-BTN_MISC] =
682                                                 joystick->nbuttons;
683                                 ++joystick->nbuttons;
684                         }
685                 }
686                 for ( i=BTN_MISC; i < BTN_JOYSTICK; ++i ) {
687                         if ( test_bit(i, keybit) ) {
688 #ifdef DEBUG_INPUT_EVENTS
689                                 printf("Joystick has button: 0x%x\n", i);
690 #endif
691                                 joystick->hwdata->key_map[i-BTN_MISC] =
692                                                 joystick->nbuttons;
693                                 ++joystick->nbuttons;
694                         }
695                 }
696                 for ( i=0; i<ABS_MAX; ++i ) {
697                         /* Skip hats */
698                         if ( i == ABS_HAT0X ) {
699                                 i = ABS_HAT3Y;
700                                 continue;
701                         }
702                         if ( test_bit(i, absbit) ) {
703                                 int values[5];
704
705                                 if ( ioctl(fd, EVIOCGABS(i), values) < 0 )
706                                         continue;
707 #ifdef DEBUG_INPUT_EVENTS
708                                 printf("Joystick has absolute axis: %x\n", i);
709                                 printf("Values = { %d, %d, %d, %d, %d }\n",
710                                         values[0], values[1],
711                                         values[2], values[3], values[4]);
712 #endif /* DEBUG_INPUT_EVENTS */
713                                 joystick->hwdata->abs_map[i] = joystick->naxes;
714                                 if ( values[1] == values[2] ) {
715                                     joystick->hwdata->abs_correct[i].used = 0;
716                                 } else {
717                                     joystick->hwdata->abs_correct[i].used = 1;
718                                     joystick->hwdata->abs_correct[i].coef[0] =
719                                         (values[2] + values[1]) / 2 - values[4];
720                                     joystick->hwdata->abs_correct[i].coef[1] =
721                                         (values[2] + values[1]) / 2 + values[4];
722                                     t = ((values[2] - values[1]) / 2 - 2 * values[4]);
723                                     if ( t != 0 ) {
724                                         joystick->hwdata->abs_correct[i].coef[2] = (1 << 29) / t;
725                                     } else {
726                                         joystick->hwdata->abs_correct[i].coef[2] = 0;
727                                     }
728                                 }
729                                 ++joystick->naxes;
730                         }
731                 }
732                 for ( i=ABS_HAT0X; i <= ABS_HAT3Y; i += 2 ) {
733                         if ( test_bit(i, absbit) || test_bit(i+1, absbit) ) {
734 #ifdef DEBUG_INPUT_EVENTS
735                                 printf("Joystick has hat %d\n",(i-ABS_HAT0X)/2);
736 #endif
737                                 ++joystick->nhats;
738                         }
739                 }
740                 if ( test_bit(REL_X, relbit) || test_bit(REL_Y, relbit) ) {
741                         ++joystick->nballs;
742                 }
743
744                 /* Allocate data to keep track of these thingamajigs */
745                 if ( joystick->nhats > 0 ) {
746                         if ( allocate_hatdata(joystick) < 0 ) {
747                                 joystick->nhats = 0;
748                         }
749                 }
750                 if ( joystick->nballs > 0 ) {
751                         if ( allocate_balldata(joystick) < 0 ) {
752                                 joystick->nballs = 0;
753                         }
754                 }
755         }
756         return(joystick->hwdata->is_hid);
757 }
758
759 #endif /* SDL_INPUT_LINUXEV */
760
761 #ifndef NO_LOGICAL_JOYSTICKS
762 static void ConfigLogicalJoystick(SDL_Joystick *joystick)
763 {
764         struct joystick_logical_layout* layout;
765                                                                                 
766         layout = SDL_joylist[joystick->index].map->layout +
767                 SDL_joylist[joystick->index].logicalno;
768                                                                                 
769         joystick->nbuttons = layout->nbuttons;
770         joystick->nhats = layout->nhats;
771         joystick->naxes = layout->naxes;
772         joystick->nballs = layout->nballs;
773 }
774 #endif
775
776
777 /* Function to open a joystick for use.
778    The joystick to open is specified by the index field of the joystick.
779    This should fill the nbuttons and naxes fields of the joystick structure.
780    It returns 0, or -1 if there is an error.
781  */
782 int SDL_SYS_JoystickOpen(SDL_Joystick *joystick)
783 {
784         int fd;
785         SDL_logical_joydecl(int realindex);
786         SDL_logical_joydecl(SDL_Joystick *realjoy = NULL);
787
788         /* Open the joystick and set the joystick file descriptor */
789 #ifndef NO_LOGICAL_JOYSTICKS
790         if (SDL_joylist[joystick->index].fname == NULL) {
791                 SDL_joylist_head(realindex, joystick->index);
792                 realjoy = SDL_JoystickOpen(realindex);
793
794                 if (realjoy == NULL)
795                         return(-1);
796                                                                                 
797                 fd = realjoy->hwdata->fd;
798
799         } else {
800                 fd = open(SDL_joylist[joystick->index].fname, O_RDONLY, 0);
801         }
802         SDL_joylist[joystick->index].joy = joystick;
803 #else
804         fd = open(SDL_joylist[joystick->index].fname, O_RDONLY, 0);
805 #endif
806
807         if ( fd < 0 ) {
808                 SDL_SetError("Unable to open %s\n",
809                              SDL_joylist[joystick->index]);
810                 return(-1);
811         }
812         joystick->hwdata = (struct joystick_hwdata *)
813                            SDL_malloc(sizeof(*joystick->hwdata));
814         if ( joystick->hwdata == NULL ) {
815                 SDL_OutOfMemory();
816                 close(fd);
817                 return(-1);
818         }
819         SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata));
820         joystick->hwdata->fd = fd;
821
822         /* Set the joystick to non-blocking read mode */
823         fcntl(fd, F_SETFL, O_NONBLOCK);
824
825         /* Get the number of buttons and axes on the joystick */
826 #ifndef NO_LOGICAL_JOYSTICKS
827         if (realjoy)
828                 ConfigLogicalJoystick(joystick);
829         else
830 #endif
831 #if SDL_INPUT_LINUXEV
832         if ( ! EV_ConfigJoystick(joystick, fd) )
833 #endif
834                 JS_ConfigJoystick(joystick, fd);
835
836         return(0);
837 }
838
839 #ifndef NO_LOGICAL_JOYSTICKS
840
841 static SDL_Joystick* FindLogicalJoystick(
842    SDL_Joystick *joystick, struct joystick_logical_mapping* v)
843 {
844         SDL_Joystick *logicaljoy;
845         register int i;
846
847         i = joystick->index;
848         logicaljoy = NULL;
849
850         /* get the fake joystick that will receive the event
851          */
852         for(;;) {
853
854            if (SDL_joylist[i].logicalno == v->njoy) {
855               logicaljoy = SDL_joylist[i].joy;
856               break;
857            }
858
859            if (SDL_joylist[i].next == 0)
860               break;
861
862            i = SDL_joylist[i].next;
863
864         }
865
866         return logicaljoy;
867 }
868
869 static int LogicalJoystickButton(
870    SDL_Joystick *joystick, Uint8 button, Uint8 state){
871         struct joystick_logical_mapping* buttons;
872         SDL_Joystick *logicaljoy = NULL;
873
874         /* if there's no map then this is just a regular joystick
875          */
876         if (SDL_joylist[joystick->index].map == NULL)
877            return 0;
878
879         /* get the logical joystick that will receive the event
880          */
881         buttons = SDL_joylist[joystick->index].map->buttonmap+button;
882         logicaljoy = FindLogicalJoystick(joystick, buttons);
883
884         if (logicaljoy == NULL)
885            return 1;
886
887         SDL_PrivateJoystickButton(logicaljoy, buttons->nthing, state);
888
889         return 1;
890 }
891
892 static int LogicalJoystickAxis(
893         SDL_Joystick *joystick, Uint8 axis, Sint16 value)
894 {
895         struct joystick_logical_mapping* axes;
896         SDL_Joystick *logicaljoy = NULL;
897
898         /* if there's no map then this is just a regular joystick
899          */
900         if (SDL_joylist[joystick->index].map == NULL)
901            return 0;
902
903         /* get the logical joystick that will receive the event
904          */
905         axes = SDL_joylist[joystick->index].map->axismap+axis;
906         logicaljoy = FindLogicalJoystick(joystick, axes);
907
908         if (logicaljoy == NULL)
909            return 1;
910
911         SDL_PrivateJoystickAxis(logicaljoy, axes->nthing, value);
912
913         return 1;
914 }
915 #endif /* USE_LOGICAL_JOYSTICKS */
916
917 static __inline__
918 void HandleHat(SDL_Joystick *stick, Uint8 hat, int axis, int value)
919 {
920         struct hwdata_hat *the_hat;
921         const Uint8 position_map[3][3] = {
922                 { SDL_HAT_LEFTUP, SDL_HAT_UP, SDL_HAT_RIGHTUP },
923                 { SDL_HAT_LEFT, SDL_HAT_CENTERED, SDL_HAT_RIGHT },
924                 { SDL_HAT_LEFTDOWN, SDL_HAT_DOWN, SDL_HAT_RIGHTDOWN }
925         };
926         SDL_logical_joydecl(SDL_Joystick *logicaljoy = NULL);
927         SDL_logical_joydecl(struct joystick_logical_mapping* hats = NULL);
928
929         the_hat = &stick->hwdata->hats[hat];
930         if ( value < 0 ) {
931                 value = 0;
932         } else
933         if ( value == 0 ) {
934                 value = 1;
935         } else
936         if ( value > 0 ) {
937                 value = 2;
938         }
939         if ( value != the_hat->axis[axis] ) {
940                 the_hat->axis[axis] = value;
941
942 #ifndef NO_LOGICAL_JOYSTICKS
943                 /* if there's no map then this is just a regular joystick
944                 */
945                 if (SDL_joylist[stick->index].map != NULL) {
946
947                         /* get the fake joystick that will receive the event
948                         */
949                         hats = SDL_joylist[stick->index].map->hatmap+hat;
950                         logicaljoy = FindLogicalJoystick(stick, hats);
951                 }
952
953                 if (logicaljoy) {
954                         stick = logicaljoy;
955                         hat = hats->nthing;
956                 }
957 #endif /* USE_LOGICAL_JOYSTICKS */
958
959                 SDL_PrivateJoystickHat(stick, hat,
960                         position_map[the_hat->axis[1]][the_hat->axis[0]]);
961         }
962 }
963
964 static __inline__
965 void HandleBall(SDL_Joystick *stick, Uint8 ball, int axis, int value)
966 {
967         stick->hwdata->balls[ball].axis[axis] += value;
968 }
969
970 /* Function to update the state of a joystick - called as a device poll.
971  * This function shouldn't update the joystick structure directly,
972  * but instead should call SDL_PrivateJoystick*() to deliver events
973  * and update joystick device state.
974  */
975 static __inline__ void JS_HandleEvents(SDL_Joystick *joystick)
976 {
977         struct js_event events[32];
978         int i, len;
979         Uint8 other_axis;
980
981 #ifndef NO_LOGICAL_JOYSTICKS
982         if (SDL_joylist[joystick->index].fname == NULL) {
983                 SDL_joylist_head(i, joystick->index);
984                 JS_HandleEvents(SDL_joylist[i].joy);
985                 return;
986         }
987 #endif
988
989         while ((len=read(joystick->hwdata->fd, events, (sizeof events))) > 0) {
990                 len /= sizeof(events[0]);
991                 for ( i=0; i<len; ++i ) {
992                         switch (events[i].type & ~JS_EVENT_INIT) {
993                             case JS_EVENT_AXIS:
994                                 if ( events[i].number < joystick->naxes ) {
995 #ifndef NO_LOGICAL_JOYSTICKS
996                                         if (!LogicalJoystickAxis(joystick,
997                                            events[i].number, events[i].value))
998 #endif
999                                         SDL_PrivateJoystickAxis(joystick,
1000                                            events[i].number, events[i].value);
1001                                         break;
1002                                 }
1003                                 events[i].number -= joystick->naxes;
1004                                 other_axis = (events[i].number / 2);
1005                                 if ( other_axis < joystick->nhats ) {
1006                                         HandleHat(joystick, other_axis,
1007                                                 events[i].number%2,
1008                                                 events[i].value);
1009                                         break;
1010                                 }
1011                                 events[i].number -= joystick->nhats*2;
1012                                 other_axis = (events[i].number / 2);
1013                                 if ( other_axis < joystick->nballs ) {
1014                                         HandleBall(joystick, other_axis,
1015                                                 events[i].number%2,
1016                                                 events[i].value);
1017                                         break;
1018                                 }
1019                                 break;
1020                             case JS_EVENT_BUTTON:
1021 #ifndef NO_LOGICAL_JOYSTICKS
1022                                 if (!LogicalJoystickButton(joystick,
1023                                            events[i].number, events[i].value))
1024 #endif
1025                                 SDL_PrivateJoystickButton(joystick,
1026                                            events[i].number, events[i].value);
1027                                 break;
1028                             default:
1029                                 /* ?? */
1030                                 break;
1031                         }
1032                 }
1033         }
1034 }
1035 #if SDL_INPUT_LINUXEV
1036 static __inline__ int EV_AxisCorrect(SDL_Joystick *joystick, int which, int value)
1037 {
1038         struct axis_correct *correct;
1039
1040         correct = &joystick->hwdata->abs_correct[which];
1041         if ( correct->used ) {
1042                 if ( value > correct->coef[0] ) {
1043                         if ( value < correct->coef[1] ) {
1044                                 return 0;
1045                         }
1046                         value -= correct->coef[1];
1047                 } else {
1048                         value -= correct->coef[0];
1049                 }
1050                 value *= correct->coef[2];
1051                 value >>= 14;
1052         }
1053
1054         /* Clamp and return */
1055         if ( value < -32768 ) return -32768;
1056         if ( value >  32767 ) return  32767;
1057
1058         return value;
1059 }
1060
1061 static __inline__ void EV_HandleEvents(SDL_Joystick *joystick)
1062 {
1063         struct input_event events[32];
1064         int i, len;
1065         int code;
1066
1067 #ifndef NO_LOGICAL_JOYSTICKS
1068         if (SDL_joylist[joystick->index].fname == NULL) {
1069                 SDL_joylist_head(i, joystick->index);
1070                 return EV_HandleEvents(SDL_joylist[i].joy);
1071         }
1072 #endif
1073
1074         while ((len=read(joystick->hwdata->fd, events, (sizeof events))) > 0) {
1075                 len /= sizeof(events[0]);
1076                 for ( i=0; i<len; ++i ) {
1077                         code = events[i].code;
1078                         switch (events[i].type) {
1079                             case EV_KEY:
1080                                 if ( code >= BTN_MISC ) {
1081                                         code -= BTN_MISC;
1082 #ifndef NO_LOGICAL_JOYSTICKS
1083                                         if (!LogicalJoystickButton(joystick,
1084                                            joystick->hwdata->key_map[code],
1085                                            events[i].value))
1086 #endif
1087                                         SDL_PrivateJoystickButton(joystick,
1088                                            joystick->hwdata->key_map[code],
1089                                            events[i].value);
1090                                 }
1091                                 break;
1092                             case EV_ABS:
1093                                 switch (code) {
1094                                     case ABS_HAT0X:
1095                                     case ABS_HAT0Y:
1096                                     case ABS_HAT1X:
1097                                     case ABS_HAT1Y:
1098                                     case ABS_HAT2X:
1099                                     case ABS_HAT2Y:
1100                                     case ABS_HAT3X:
1101                                     case ABS_HAT3Y:
1102                                         code -= ABS_HAT0X;
1103                                         HandleHat(joystick, code/2, code%2,
1104                                                         events[i].value);
1105                                         break;
1106                                     default:
1107                                         events[i].value = EV_AxisCorrect(joystick, code, events[i].value);
1108 #ifndef NO_LOGICAL_JOYSTICKS
1109                                         if (!LogicalJoystickAxis(joystick,
1110                                            joystick->hwdata->abs_map[code],
1111                                            events[i].value))
1112 #endif
1113                                         SDL_PrivateJoystickAxis(joystick,
1114                                            joystick->hwdata->abs_map[code],
1115                                            events[i].value);
1116                                         break;
1117                                 }
1118                                 break;
1119                             case EV_REL:
1120                                 switch (code) {
1121                                     case REL_X:
1122                                     case REL_Y:
1123                                         code -= REL_X;
1124                                         HandleBall(joystick, code/2, code%2,
1125                                                         events[i].value);
1126                                         break;
1127                                     default:
1128                                         break;
1129                                 }
1130                                 break;
1131                             default:
1132                                 break;
1133                         }
1134                 }
1135         }
1136 }
1137 #endif /* SDL_INPUT_LINUXEV */
1138
1139 void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
1140 {
1141         int i;
1142         
1143 #if SDL_INPUT_LINUXEV
1144         if ( joystick->hwdata->is_hid )
1145                 EV_HandleEvents(joystick);
1146         else
1147 #endif
1148                 JS_HandleEvents(joystick);
1149
1150         /* Deliver ball motion updates */
1151         for ( i=0; i<joystick->nballs; ++i ) {
1152                 int xrel, yrel;
1153
1154                 xrel = joystick->hwdata->balls[i].axis[0];
1155                 yrel = joystick->hwdata->balls[i].axis[1];
1156                 if ( xrel || yrel ) {
1157                         joystick->hwdata->balls[i].axis[0] = 0;
1158                         joystick->hwdata->balls[i].axis[1] = 0;
1159                         SDL_PrivateJoystickBall(joystick, (Uint8)i, xrel, yrel);
1160                 }
1161         }
1162 }
1163
1164 /* Function to close a joystick after use */
1165 void SDL_SYS_JoystickClose(SDL_Joystick *joystick)
1166 {
1167 #ifndef NO_LOGICAL_JOYSTICKS
1168         register int i;
1169         if (SDL_joylist[joystick->index].fname == NULL) {
1170                 SDL_joylist_head(i, joystick->index);
1171                 SDL_JoystickClose(SDL_joylist[i].joy);
1172         }
1173 #endif
1174
1175         if ( joystick->hwdata ) {
1176 #ifndef NO_LOGICAL_JOYSTICKS
1177                 if (SDL_joylist[joystick->index].fname != NULL)
1178 #endif
1179                 close(joystick->hwdata->fd);
1180                 if ( joystick->hwdata->hats ) {
1181                         SDL_free(joystick->hwdata->hats);
1182                 }
1183                 if ( joystick->hwdata->balls ) {
1184                         SDL_free(joystick->hwdata->balls);
1185                 }
1186                 SDL_free(joystick->hwdata);
1187                 joystick->hwdata = NULL;
1188         }
1189 }
1190
1191 /* Function to perform any system-specific joystick related cleanup */
1192 void SDL_SYS_JoystickQuit(void)
1193 {
1194         int i;
1195
1196         for ( i=0; SDL_joylist[i].fname; ++i ) {
1197                 SDL_free(SDL_joylist[i].fname);
1198                 SDL_joylist[i].fname = NULL;
1199         }
1200 }
1201
1202 #endif /* SDL_JOYSTICK_LINUX */