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