Home | History | Annotate | Download | only in linux
      1 /*
      2     SDL - Simple DirectMedia Layer
      3     Copyright (C) 1997-2012 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 (at) 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 one or more joysticks to use */
    421 	if ( SDL_getenv("SDL_JOYSTICK_DEVICE") != NULL ) {
    422 		char *envcopy, *envpath, *delim;
    423 		envcopy = SDL_strdup(SDL_getenv("SDL_JOYSTICK_DEVICE"));
    424 		envpath = envcopy;
    425 		while ( envpath != NULL ) {
    426 			delim = SDL_strchr(envpath, ':');
    427 			if ( delim != NULL ) {
    428 				*delim++ = '\0';
    429 			}
    430 			if ( stat(envpath, &sb) == 0 ) {
    431 				fd = open(envpath, O_RDONLY, 0);
    432 				if ( fd >= 0 ) {
    433 					/* Assume the user knows what they're doing. */
    434 					SDL_joylist[numjoysticks].fname = SDL_strdup(envpath);
    435 					if ( SDL_joylist[numjoysticks].fname ) {
    436 						dev_nums[numjoysticks] = sb.st_rdev;
    437 						++numjoysticks;
    438 					}
    439 					close(fd);
    440 				}
    441 			}
    442 			envpath = delim;
    443 		}
    444 		SDL_free(envcopy);
    445 	}
    446 
    447 	for ( i=0; i<SDL_arraysize(joydev_pattern); ++i ) {
    448 		for ( j=0; j < MAX_JOYSTICKS; ++j ) {
    449 			SDL_snprintf(path, SDL_arraysize(path), joydev_pattern[i], j);
    450 
    451 			/* rcg06302000 replaced access(F_OK) call with stat().
    452 			 * stat() will fail if the file doesn't exist, so it's
    453 			 * equivalent behaviour.
    454 			 */
    455 			if ( stat(path, &sb) == 0 ) {
    456 				/* Check to make sure it's not already in list.
    457 				 * This happens when we see a stick via symlink.
    458 				 */
    459 				duplicate = 0;
    460 				for (n=0; (n<numjoysticks) && !duplicate; ++n) {
    461 					if ( sb.st_rdev == dev_nums[n] ) {
    462 						duplicate = 1;
    463 					}
    464 				}
    465 				if (duplicate) {
    466 					continue;
    467 				}
    468 
    469 				fd = open(path, O_RDONLY, 0);
    470 				if ( fd < 0 ) {
    471 					continue;
    472 				}
    473 #if SDL_INPUT_LINUXEV
    474 #ifdef DEBUG_INPUT_EVENTS
    475 				printf("Checking %s\n", path);
    476 #endif
    477 				if ( (i == 0) && ! EV_IsJoystick(fd) ) {
    478 					close(fd);
    479 					continue;
    480 				}
    481 #endif
    482 				close(fd);
    483 
    484 				/* We're fine, add this joystick */
    485 				SDL_joylist[numjoysticks].fname = SDL_strdup(path);
    486 				if ( SDL_joylist[numjoysticks].fname ) {
    487 					dev_nums[numjoysticks] = sb.st_rdev;
    488 					++numjoysticks;
    489 				}
    490 			}
    491 		}
    492 
    493 #if SDL_INPUT_LINUXEV
    494 		/* This is a special case...
    495 		   If the event devices are valid then the joystick devices
    496 		   will be duplicates but without extra information about their
    497 		   hats or balls. Unfortunately, the event devices can't
    498 		   currently be calibrated, so it's a win-lose situation.
    499 		   So : /dev/input/eventX = /dev/input/jsY = /dev/jsY
    500 		*/
    501 		if ( (i == 0) && (numjoysticks > 0) )
    502 			break;
    503 #endif
    504 	}
    505 #ifndef NO_LOGICAL_JOYSTICKS
    506 	numjoysticks += CountLogicalJoysticks(numjoysticks);
    507 #endif
    508 
    509 	return(numjoysticks);
    510 }
    511 
    512 /* Function to get the device-dependent name of a joystick */
    513 const char *SDL_SYS_JoystickName(int index)
    514 {
    515 	int fd;
    516 	static char namebuf[128];
    517 	char *name;
    518 	SDL_logical_joydecl(int oindex = index);
    519 
    520 #ifndef NO_LOGICAL_JOYSTICKS
    521 	SDL_joylist_head(index, index);
    522 #endif
    523 	name = NULL;
    524 	fd = open(SDL_joylist[index].fname, O_RDONLY, 0);
    525 	if ( fd >= 0 ) {
    526 		if (
    527 #if SDL_INPUT_LINUXEV
    528 		     (ioctl(fd, EVIOCGNAME(sizeof(namebuf)), namebuf) <= 0) &&
    529 #endif
    530 		     (ioctl(fd, JSIOCGNAME(sizeof(namebuf)), namebuf) <= 0) ) {
    531 			name = SDL_joylist[index].fname;
    532 		} else {
    533 			name = namebuf;
    534 		}
    535 		close(fd);
    536 
    537 
    538 #ifndef NO_LOGICAL_JOYSTICKS
    539 		if (SDL_joylist[oindex].prev || SDL_joylist[oindex].next || index!=oindex)
    540 		{
    541        		   LogicalSuffix(SDL_joylist[oindex].logicalno, namebuf, 128);
    542 		}
    543 #endif
    544 	}
    545 	return name;
    546 }
    547 
    548 static int allocate_hatdata(SDL_Joystick *joystick)
    549 {
    550 	int i;
    551 
    552 	joystick->hwdata->hats = (struct hwdata_hat *)SDL_malloc(
    553 		joystick->nhats * sizeof(struct hwdata_hat));
    554 	if ( joystick->hwdata->hats == NULL ) {
    555 		return(-1);
    556 	}
    557 	for ( i=0; i<joystick->nhats; ++i ) {
    558 		joystick->hwdata->hats[i].axis[0] = 1;
    559 		joystick->hwdata->hats[i].axis[1] = 1;
    560 	}
    561 	return(0);
    562 }
    563 
    564 static int allocate_balldata(SDL_Joystick *joystick)
    565 {
    566 	int i;
    567 
    568 	joystick->hwdata->balls = (struct hwdata_ball *)SDL_malloc(
    569 		joystick->nballs * sizeof(struct hwdata_ball));
    570 	if ( joystick->hwdata->balls == NULL ) {
    571 		return(-1);
    572 	}
    573 	for ( i=0; i<joystick->nballs; ++i ) {
    574 		joystick->hwdata->balls[i].axis[0] = 0;
    575 		joystick->hwdata->balls[i].axis[1] = 0;
    576 	}
    577 	return(0);
    578 }
    579 
    580 static SDL_bool JS_ConfigJoystick(SDL_Joystick *joystick, int fd)
    581 {
    582 	SDL_bool handled;
    583 	unsigned char n;
    584 	int tmp_naxes, tmp_nhats, tmp_nballs;
    585 	const char *name;
    586 	char *env, env_name[128];
    587 	int i;
    588 
    589 	handled = SDL_FALSE;
    590 
    591 	/* Default joystick device settings */
    592 	if ( ioctl(fd, JSIOCGAXES, &n) < 0 ) {
    593 		joystick->naxes = 2;
    594 	} else {
    595 		joystick->naxes = n;
    596 	}
    597 	if ( ioctl(fd, JSIOCGBUTTONS, &n) < 0 ) {
    598 		joystick->nbuttons = 2;
    599 	} else {
    600 		joystick->nbuttons = n;
    601 	}
    602 
    603 	name = SDL_SYS_JoystickName(joystick->index);
    604 
    605 	/* Generic analog joystick support */
    606 	if ( SDL_strstr(name, "Analog") == name && SDL_strstr(name, "-hat") ) {
    607 		if ( SDL_sscanf(name,"Analog %d-axis %*d-button %d-hat",
    608 			&tmp_naxes, &tmp_nhats) == 2 ) {
    609 
    610 			joystick->naxes = tmp_naxes;
    611 			joystick->nhats = tmp_nhats;
    612 
    613 			handled = SDL_TRUE;
    614 		}
    615 	}
    616 
    617 	/* Special joystick support */
    618 	for ( i=0; i < SDL_arraysize(special_joysticks); ++i ) {
    619 		if ( SDL_strcmp(name, special_joysticks[i].name) == 0 ) {
    620 
    621 			joystick->naxes = special_joysticks[i].naxes;
    622 			joystick->nhats = special_joysticks[i].nhats;
    623 			joystick->nballs = special_joysticks[i].nballs;
    624 
    625 			handled = SDL_TRUE;
    626 			break;
    627 		}
    628 	}
    629 
    630 	/* User environment joystick support */
    631 	if ( (env = SDL_getenv("SDL_LINUX_JOYSTICK")) ) {
    632 		*env_name = '\0';
    633 		if ( *env == '\'' && SDL_sscanf(env, "'%[^']s'", env_name) == 1 )
    634 			env += SDL_strlen(env_name)+2;
    635 		else if ( SDL_sscanf(env, "%s", env_name) == 1 )
    636 			env += SDL_strlen(env_name);
    637 
    638 		if ( SDL_strcmp(name, env_name) == 0 ) {
    639 
    640 			if ( SDL_sscanf(env, "%d %d %d", &tmp_naxes, &tmp_nhats,
    641 				&tmp_nballs) == 3 ) {
    642 
    643 				joystick->naxes = tmp_naxes;
    644 				joystick->nhats = tmp_nhats;
    645 				joystick->nballs = tmp_nballs;
    646 
    647 				handled = SDL_TRUE;
    648 			}
    649 		}
    650 	}
    651 
    652 	/* Remap hats and balls */
    653 	if (handled) {
    654 		if ( joystick->nhats > 0 ) {
    655 			if ( allocate_hatdata(joystick) < 0 ) {
    656 				joystick->nhats = 0;
    657 			}
    658 		}
    659 		if ( joystick->nballs > 0 ) {
    660 			if ( allocate_balldata(joystick) < 0 ) {
    661 				joystick->nballs = 0;
    662 			}
    663 		}
    664 	}
    665 
    666 	return(handled);
    667 }
    668 
    669 #if SDL_INPUT_LINUXEV
    670 
    671 static SDL_bool EV_ConfigJoystick(SDL_Joystick *joystick, int fd)
    672 {
    673 	int i, t;
    674 	unsigned long keybit[NBITS(KEY_MAX)] = { 0 };
    675 	unsigned long absbit[NBITS(ABS_MAX)] = { 0 };
    676 	unsigned long relbit[NBITS(REL_MAX)] = { 0 };
    677 
    678 	/* See if this device uses the new unified event API */
    679 	if ( (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) >= 0) &&
    680 	     (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) >= 0) &&
    681 	     (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relbit)), relbit) >= 0) ) {
    682 		joystick->hwdata->is_hid = SDL_TRUE;
    683 
    684 		/* Get the number of buttons, axes, and other thingamajigs */
    685 		for ( i=BTN_JOYSTICK; i < KEY_MAX; ++i ) {
    686 			if ( test_bit(i, keybit) ) {
    687 #ifdef DEBUG_INPUT_EVENTS
    688 				printf("Joystick has button: 0x%x\n", i);
    689 #endif
    690 				joystick->hwdata->key_map[i-BTN_MISC] =
    691 						joystick->nbuttons;
    692 				++joystick->nbuttons;
    693 			}
    694 		}
    695 		for ( i=BTN_MISC; i < BTN_JOYSTICK; ++i ) {
    696 			if ( test_bit(i, keybit) ) {
    697 #ifdef DEBUG_INPUT_EVENTS
    698 				printf("Joystick has button: 0x%x\n", i);
    699 #endif
    700 				joystick->hwdata->key_map[i-BTN_MISC] =
    701 						joystick->nbuttons;
    702 				++joystick->nbuttons;
    703 			}
    704 		}
    705 		for ( i=0; i<ABS_MISC; ++i ) {
    706 			/* Skip hats */
    707 			if ( i == ABS_HAT0X ) {
    708 				i = ABS_HAT3Y;
    709 				continue;
    710 			}
    711 			if ( test_bit(i, absbit) ) {
    712 				struct input_absinfo absinfo;
    713 
    714 				if ( ioctl(fd, EVIOCGABS(i), &absinfo) < 0 )
    715 					continue;
    716 #ifdef DEBUG_INPUT_EVENTS
    717 				printf("Joystick has absolute axis: %x\n", i);
    718 				printf("Values = { %d, %d, %d, %d, %d }\n",
    719 					absinfo.value, absinfo.minimum,
    720 					absinfo.maximum, absinfo.fuzz, absinfo.flat);
    721 #endif /* DEBUG_INPUT_EVENTS */
    722 				joystick->hwdata->abs_map[i] = joystick->naxes;
    723 				if ( absinfo.minimum == absinfo.maximum ) {
    724 				    joystick->hwdata->abs_correct[i].used = 0;
    725 				} else {
    726 				    joystick->hwdata->abs_correct[i].used = 1;
    727 				    joystick->hwdata->abs_correct[i].coef[0] =
    728 					(absinfo.maximum + absinfo.minimum) / 2 - absinfo.flat;
    729 				    joystick->hwdata->abs_correct[i].coef[1] =
    730 					(absinfo.maximum + absinfo.minimum) / 2 + absinfo.flat;
    731 				    t = ((absinfo.maximum - absinfo.minimum) / 2 - 2 * absinfo.flat);
    732 				    if ( t != 0 ) {
    733 					joystick->hwdata->abs_correct[i].coef[2] = (1 << 29) / t;
    734 				    } else {
    735 					joystick->hwdata->abs_correct[i].coef[2] = 0;
    736 				    }
    737 				}
    738 				++joystick->naxes;
    739 			}
    740 		}
    741 		for ( i=ABS_HAT0X; i <= ABS_HAT3Y; i += 2 ) {
    742 			if ( test_bit(i, absbit) || test_bit(i+1, absbit) ) {
    743 #ifdef DEBUG_INPUT_EVENTS
    744 				printf("Joystick has hat %d\n",(i-ABS_HAT0X)/2);
    745 #endif
    746 				++joystick->nhats;
    747 			}
    748 		}
    749 		if ( test_bit(REL_X, relbit) || test_bit(REL_Y, relbit) ) {
    750 			++joystick->nballs;
    751 		}
    752 
    753 		/* Allocate data to keep track of these thingamajigs */
    754 		if ( joystick->nhats > 0 ) {
    755 			if ( allocate_hatdata(joystick) < 0 ) {
    756 				joystick->nhats = 0;
    757 			}
    758 		}
    759 		if ( joystick->nballs > 0 ) {
    760 			if ( allocate_balldata(joystick) < 0 ) {
    761 				joystick->nballs = 0;
    762 			}
    763 		}
    764 	}
    765 	return(joystick->hwdata->is_hid);
    766 }
    767 
    768 #endif /* SDL_INPUT_LINUXEV */
    769 
    770 #ifndef NO_LOGICAL_JOYSTICKS
    771 static void ConfigLogicalJoystick(SDL_Joystick *joystick)
    772 {
    773         struct joystick_logical_layout* layout;
    774 
    775         layout = SDL_joylist[joystick->index].map->layout +
    776                 SDL_joylist[joystick->index].logicalno;
    777 
    778         joystick->nbuttons = layout->nbuttons;
    779         joystick->nhats = layout->nhats;
    780         joystick->naxes = layout->naxes;
    781         joystick->nballs = layout->nballs;
    782 }
    783 #endif
    784 
    785 
    786 /* Function to open a joystick for use.
    787    The joystick to open is specified by the index field of the joystick.
    788    This should fill the nbuttons and naxes fields of the joystick structure.
    789    It returns 0, or -1 if there is an error.
    790  */
    791 int SDL_SYS_JoystickOpen(SDL_Joystick *joystick)
    792 {
    793 	int fd;
    794 	SDL_logical_joydecl(int realindex);
    795 	SDL_logical_joydecl(SDL_Joystick *realjoy = NULL);
    796 
    797 	/* Open the joystick and set the joystick file descriptor */
    798 #ifndef NO_LOGICAL_JOYSTICKS
    799 	if (SDL_joylist[joystick->index].fname == NULL) {
    800 		SDL_joylist_head(realindex, joystick->index);
    801 		realjoy = SDL_JoystickOpen(realindex);
    802 
    803 		if (realjoy == NULL)
    804 			return(-1);
    805 
    806 		fd = realjoy->hwdata->fd;
    807 
    808 	} else {
    809 		fd = open(SDL_joylist[joystick->index].fname, O_RDONLY, 0);
    810 	}
    811 	SDL_joylist[joystick->index].joy = joystick;
    812 #else
    813 	fd = open(SDL_joylist[joystick->index].fname, O_RDONLY, 0);
    814 #endif
    815 
    816 	if ( fd < 0 ) {
    817 		SDL_SetError("Unable to open %s\n",
    818 		             SDL_joylist[joystick->index]);
    819 		return(-1);
    820 	}
    821 	joystick->hwdata = (struct joystick_hwdata *)
    822 	                   SDL_malloc(sizeof(*joystick->hwdata));
    823 	if ( joystick->hwdata == NULL ) {
    824 		SDL_OutOfMemory();
    825 		close(fd);
    826 		return(-1);
    827 	}
    828 	SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata));
    829 	joystick->hwdata->fd = fd;
    830 
    831 	/* Set the joystick to non-blocking read mode */
    832 	fcntl(fd, F_SETFL, O_NONBLOCK);
    833 
    834 	/* Get the number of buttons and axes on the joystick */
    835 #ifndef NO_LOGICAL_JOYSTICKS
    836 	if (realjoy)
    837 		ConfigLogicalJoystick(joystick);
    838 	else
    839 #endif
    840 #if SDL_INPUT_LINUXEV
    841 	if ( ! EV_ConfigJoystick(joystick, fd) )
    842 #endif
    843 		JS_ConfigJoystick(joystick, fd);
    844 
    845 	return(0);
    846 }
    847 
    848 #ifndef NO_LOGICAL_JOYSTICKS
    849 
    850 static SDL_Joystick* FindLogicalJoystick(
    851    SDL_Joystick *joystick, struct joystick_logical_mapping* v)
    852 {
    853         SDL_Joystick *logicaljoy;
    854         register int i;
    855 
    856         i = joystick->index;
    857         logicaljoy = NULL;
    858 
    859         /* get the fake joystick that will receive the event
    860          */
    861         for(;;) {
    862 
    863            if (SDL_joylist[i].logicalno == v->njoy) {
    864               logicaljoy = SDL_joylist[i].joy;
    865               break;
    866            }
    867 
    868            if (SDL_joylist[i].next == 0)
    869               break;
    870 
    871            i = SDL_joylist[i].next;
    872 
    873         }
    874 
    875         return logicaljoy;
    876 }
    877 
    878 static int LogicalJoystickButton(
    879    SDL_Joystick *joystick, Uint8 button, Uint8 state){
    880         struct joystick_logical_mapping* buttons;
    881         SDL_Joystick *logicaljoy = NULL;
    882 
    883         /* if there's no map then this is just a regular joystick
    884          */
    885         if (SDL_joylist[joystick->index].map == NULL)
    886            return 0;
    887 
    888         /* get the logical joystick that will receive the event
    889          */
    890         buttons = SDL_joylist[joystick->index].map->buttonmap+button;
    891         logicaljoy = FindLogicalJoystick(joystick, buttons);
    892 
    893         if (logicaljoy == NULL)
    894            return 1;
    895 
    896         SDL_PrivateJoystickButton(logicaljoy, buttons->nthing, state);
    897 
    898         return 1;
    899 }
    900 
    901 static int LogicalJoystickAxis(
    902 	SDL_Joystick *joystick, Uint8 axis, Sint16 value)
    903 {
    904         struct joystick_logical_mapping* axes;
    905         SDL_Joystick *logicaljoy = NULL;
    906 
    907         /* if there's no map then this is just a regular joystick
    908          */
    909         if (SDL_joylist[joystick->index].map == NULL)
    910            return 0;
    911 
    912         /* get the logical joystick that will receive the event
    913          */
    914         axes = SDL_joylist[joystick->index].map->axismap+axis;
    915         logicaljoy = FindLogicalJoystick(joystick, axes);
    916 
    917         if (logicaljoy == NULL)
    918            return 1;
    919 
    920         SDL_PrivateJoystickAxis(logicaljoy, axes->nthing, value);
    921 
    922         return 1;
    923 }
    924 #endif /* USE_LOGICAL_JOYSTICKS */
    925 
    926 static __inline__
    927 void HandleHat(SDL_Joystick *stick, Uint8 hat, int axis, int value)
    928 {
    929 	struct hwdata_hat *the_hat;
    930 	const Uint8 position_map[3][3] = {
    931 		{ SDL_HAT_LEFTUP, SDL_HAT_UP, SDL_HAT_RIGHTUP },
    932 		{ SDL_HAT_LEFT, SDL_HAT_CENTERED, SDL_HAT_RIGHT },
    933 		{ SDL_HAT_LEFTDOWN, SDL_HAT_DOWN, SDL_HAT_RIGHTDOWN }
    934 	};
    935 	SDL_logical_joydecl(SDL_Joystick *logicaljoy = NULL);
    936 	SDL_logical_joydecl(struct joystick_logical_mapping* hats = NULL);
    937 
    938 	if (stick->nhats <= hat) {
    939 		return;  /* whoops, that shouldn't happen! */
    940 	}
    941 
    942 	the_hat = &stick->hwdata->hats[hat];
    943 	if ( value < 0 ) {
    944 		value = 0;
    945 	} else
    946 	if ( value == 0 ) {
    947 		value = 1;
    948 	} else
    949 	if ( value > 0 ) {
    950 		value = 2;
    951 	}
    952 	if ( value != the_hat->axis[axis] ) {
    953 		the_hat->axis[axis] = value;
    954 
    955 #ifndef NO_LOGICAL_JOYSTICKS
    956 		/* if there's no map then this is just a regular joystick
    957 		*/
    958 		if (SDL_joylist[stick->index].map != NULL) {
    959 
    960 			/* get the fake joystick that will receive the event
    961 			*/
    962 			hats = SDL_joylist[stick->index].map->hatmap+hat;
    963 			logicaljoy = FindLogicalJoystick(stick, hats);
    964 		}
    965 
    966 		if (logicaljoy) {
    967 			stick = logicaljoy;
    968 			hat = hats->nthing;
    969 		}
    970 #endif /* USE_LOGICAL_JOYSTICKS */
    971 
    972 		SDL_PrivateJoystickHat(stick, hat,
    973 			position_map[the_hat->axis[1]][the_hat->axis[0]]);
    974 	}
    975 }
    976 
    977 static __inline__
    978 void HandleBall(SDL_Joystick *stick, Uint8 ball, int axis, int value)
    979 {
    980 	if ((stick->nballs <= ball) || (axis >= 2)) {
    981 		return;  /* whoops, that shouldn't happen! */
    982 	}
    983 	stick->hwdata->balls[ball].axis[axis] += value;
    984 }
    985 
    986 /* Function to update the state of a joystick - called as a device poll.
    987  * This function shouldn't update the joystick structure directly,
    988  * but instead should call SDL_PrivateJoystick*() to deliver events
    989  * and update joystick device state.
    990  */
    991 static __inline__ void JS_HandleEvents(SDL_Joystick *joystick)
    992 {
    993 	struct js_event events[32];
    994 	int i, len;
    995 	Uint8 other_axis;
    996 
    997 #ifndef NO_LOGICAL_JOYSTICKS
    998 	if (SDL_joylist[joystick->index].fname == NULL) {
    999 		SDL_joylist_head(i, joystick->index);
   1000 		JS_HandleEvents(SDL_joylist[i].joy);
   1001 		return;
   1002 	}
   1003 #endif
   1004 
   1005 	while ((len=read(joystick->hwdata->fd, events, (sizeof events))) > 0) {
   1006 		len /= sizeof(events[0]);
   1007 		for ( i=0; i<len; ++i ) {
   1008 			switch (events[i].type & ~JS_EVENT_INIT) {
   1009 			    case JS_EVENT_AXIS:
   1010 				if ( events[i].number < joystick->naxes ) {
   1011 #ifndef NO_LOGICAL_JOYSTICKS
   1012 					if (!LogicalJoystickAxis(joystick,
   1013 				           events[i].number, events[i].value))
   1014 #endif
   1015 					SDL_PrivateJoystickAxis(joystick,
   1016 				           events[i].number, events[i].value);
   1017 					break;
   1018 				}
   1019 				events[i].number -= joystick->naxes;
   1020 				other_axis = (events[i].number / 2);
   1021 				if ( other_axis < joystick->nhats ) {
   1022 					HandleHat(joystick, other_axis,
   1023 						events[i].number%2,
   1024 						events[i].value);
   1025 					break;
   1026 				}
   1027 				events[i].number -= joystick->nhats*2;
   1028 				other_axis = (events[i].number / 2);
   1029 				if ( other_axis < joystick->nballs ) {
   1030 					HandleBall(joystick, other_axis,
   1031 						events[i].number%2,
   1032 						events[i].value);
   1033 					break;
   1034 				}
   1035 				break;
   1036 			    case JS_EVENT_BUTTON:
   1037 #ifndef NO_LOGICAL_JOYSTICKS
   1038 				if (!LogicalJoystickButton(joystick,
   1039 				           events[i].number, events[i].value))
   1040 #endif
   1041 				SDL_PrivateJoystickButton(joystick,
   1042 				           events[i].number, events[i].value);
   1043 				break;
   1044 			    default:
   1045 				/* ?? */
   1046 				break;
   1047 			}
   1048 		}
   1049 	}
   1050 }
   1051 #if SDL_INPUT_LINUXEV
   1052 static __inline__ int EV_AxisCorrect(SDL_Joystick *joystick, int which, int value)
   1053 {
   1054 	struct axis_correct *correct;
   1055 
   1056 	correct = &joystick->hwdata->abs_correct[which];
   1057 	if ( correct->used ) {
   1058 		if ( value > correct->coef[0] ) {
   1059 			if ( value < correct->coef[1] ) {
   1060 				return 0;
   1061 			}
   1062 			value -= correct->coef[1];
   1063 		} else {
   1064 			value -= correct->coef[0];
   1065 		}
   1066 		value *= correct->coef[2];
   1067 		value >>= 14;
   1068 	}
   1069 
   1070 	/* Clamp and return */
   1071 	if ( value < -32768 ) return -32768;
   1072 	if ( value >  32767 ) return  32767;
   1073 
   1074 	return value;
   1075 }
   1076 
   1077 static __inline__ void EV_HandleEvents(SDL_Joystick *joystick)
   1078 {
   1079 	struct input_event events[32];
   1080 	int i, len;
   1081 	int code;
   1082 
   1083 #ifndef NO_LOGICAL_JOYSTICKS
   1084 	if (SDL_joylist[joystick->index].fname == NULL) {
   1085 		SDL_joylist_head(i, joystick->index);
   1086 		return EV_HandleEvents(SDL_joylist[i].joy);
   1087 	}
   1088 #endif
   1089 
   1090 	while ((len=read(joystick->hwdata->fd, events, (sizeof events))) > 0) {
   1091 		len /= sizeof(events[0]);
   1092 		for ( i=0; i<len; ++i ) {
   1093 			code = events[i].code;
   1094 			switch (events[i].type) {
   1095 			    case EV_KEY:
   1096 				if ( code >= BTN_MISC ) {
   1097 					code -= BTN_MISC;
   1098 #ifndef NO_LOGICAL_JOYSTICKS
   1099 					if (!LogicalJoystickButton(joystick,
   1100 				           joystick->hwdata->key_map[code],
   1101 					   events[i].value))
   1102 #endif
   1103 					SDL_PrivateJoystickButton(joystick,
   1104 				           joystick->hwdata->key_map[code],
   1105 					   events[i].value);
   1106 				}
   1107 				break;
   1108 			    case EV_ABS:
   1109 				switch (code) {
   1110 				    case ABS_HAT0X:
   1111 				    case ABS_HAT0Y:
   1112 				    case ABS_HAT1X:
   1113 				    case ABS_HAT1Y:
   1114 				    case ABS_HAT2X:
   1115 				    case ABS_HAT2Y:
   1116 				    case ABS_HAT3X:
   1117 				    case ABS_HAT3Y:
   1118 					code -= ABS_HAT0X;
   1119 					HandleHat(joystick, code/2, code%2,
   1120 							events[i].value);
   1121 					break;
   1122 				    default:
   1123 					events[i].value = EV_AxisCorrect(joystick, code, events[i].value);
   1124 #ifndef NO_LOGICAL_JOYSTICKS
   1125 					if (!LogicalJoystickAxis(joystick,
   1126 				           joystick->hwdata->abs_map[code],
   1127 					   events[i].value))
   1128 #endif
   1129 					SDL_PrivateJoystickAxis(joystick,
   1130 				           joystick->hwdata->abs_map[code],
   1131 					   events[i].value);
   1132 					break;
   1133 				}
   1134 				break;
   1135 			    case EV_REL:
   1136 				switch (code) {
   1137 				    case REL_X:
   1138 				    case REL_Y:
   1139 					code -= REL_X;
   1140 					HandleBall(joystick, code/2, code%2,
   1141 							events[i].value);
   1142 					break;
   1143 				    default:
   1144 					break;
   1145 				}
   1146 				break;
   1147 			    default:
   1148 				break;
   1149 			}
   1150 		}
   1151 	}
   1152 }
   1153 #endif /* SDL_INPUT_LINUXEV */
   1154 
   1155 void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
   1156 {
   1157 	int i;
   1158 
   1159 #if SDL_INPUT_LINUXEV
   1160 	if ( joystick->hwdata->is_hid )
   1161 		EV_HandleEvents(joystick);
   1162 	else
   1163 #endif
   1164 		JS_HandleEvents(joystick);
   1165 
   1166 	/* Deliver ball motion updates */
   1167 	for ( i=0; i<joystick->nballs; ++i ) {
   1168 		int xrel, yrel;
   1169 
   1170 		xrel = joystick->hwdata->balls[i].axis[0];
   1171 		yrel = joystick->hwdata->balls[i].axis[1];
   1172 		if ( xrel || yrel ) {
   1173 			joystick->hwdata->balls[i].axis[0] = 0;
   1174 			joystick->hwdata->balls[i].axis[1] = 0;
   1175 			SDL_PrivateJoystickBall(joystick, (Uint8)i, xrel, yrel);
   1176 		}
   1177 	}
   1178 }
   1179 
   1180 /* Function to close a joystick after use */
   1181 void SDL_SYS_JoystickClose(SDL_Joystick *joystick)
   1182 {
   1183 #ifndef NO_LOGICAL_JOYSTICKS
   1184 	register int i;
   1185 	if (SDL_joylist[joystick->index].fname == NULL) {
   1186 		SDL_joylist_head(i, joystick->index);
   1187 		SDL_JoystickClose(SDL_joylist[i].joy);
   1188 	}
   1189 #endif
   1190 
   1191 	if ( joystick->hwdata ) {
   1192 #ifndef NO_LOGICAL_JOYSTICKS
   1193 		if (SDL_joylist[joystick->index].fname != NULL)
   1194 #endif
   1195 		close(joystick->hwdata->fd);
   1196 		if ( joystick->hwdata->hats ) {
   1197 			SDL_free(joystick->hwdata->hats);
   1198 		}
   1199 		if ( joystick->hwdata->balls ) {
   1200 			SDL_free(joystick->hwdata->balls);
   1201 		}
   1202 		SDL_free(joystick->hwdata);
   1203 		joystick->hwdata = NULL;
   1204 	}
   1205 }
   1206 
   1207 /* Function to perform any system-specific joystick related cleanup */
   1208 void SDL_SYS_JoystickQuit(void)
   1209 {
   1210 	int i;
   1211 
   1212 	for ( i=0; SDL_joylist[i].fname; ++i ) {
   1213 		SDL_free(SDL_joylist[i].fname);
   1214 		SDL_joylist[i].fname = NULL;
   1215 	}
   1216 }
   1217 
   1218 #endif /* SDL_JOYSTICK_LINUX */
   1219