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