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