* The static joystick structure pointer\r
*/\r
#define MAX_NUM_JOYSTICKS 2\r
-static SFG_Joystick *fgJoystick [ MAX_NUM_JOYSTICKS ];\r
+SFG_Joystick *fgJoystick [ MAX_NUM_JOYSTICKS ];\r
\r
/*\r
* Read the raw joystick data\r
}\r
#endif\r
\r
-#if TARGET_HOST_POSIX_X11\r
-void fgPlatformJoystickRawRead( SFG_Joystick* joy, int* buttons, float* axes )\r
-{\r
- int status;\r
-\r
- int i;\r
-\r
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__)\r
- int len;\r
-\r
- if ( joy->pJoystick.os->is_analog )\r
- {\r
- int status = read ( joy->pJoystick.os->fd, &joy->pJoystick.os->ajs, sizeof(joy->pJoystick.os->ajs) );\r
- if ( status != sizeof(joy->pJoystick.os->ajs) ) {\r
- perror ( joy->pJoystick.os->fname );\r
- joy->error = GL_TRUE;\r
- return;\r
- }\r
- if ( buttons != NULL )\r
- *buttons = ( joy->pJoystick.os->ajs.b1 ? 1 : 0 ) | ( joy->pJoystick.os->ajs.b2 ? 2 : 0 );\r
-\r
- if ( axes != NULL )\r
- {\r
- axes[0] = (float) joy->pJoystick.os->ajs.x;\r
- axes[1] = (float) joy->pJoystick.os->ajs.y;\r
- }\r
-\r
- return;\r
- }\r
-\r
-# ifdef HAVE_USB_JS\r
- while ( ( len = read ( joy->pJoystick.os->fd, joy->pJoystick.os->hid_data_buf, joy->pJoystick.os->hid_dlen ) ) == joy->pJoystick.os->hid_dlen )\r
- {\r
- struct hid_item *h;\r
-\r
- for ( h = joy->pJoystick.os->hids; h; h = h->next )\r
- {\r
- int d = hid_get_data ( joy->pJoystick.os->hid_data_buf, h );\r
-\r
- int page = HID_PAGE ( h->usage );\r
- int usage = HID_USAGE ( h->usage );\r
-\r
- if ( page == HUP_GENERIC_DESKTOP )\r
- {\r
- int i;\r
- for ( i = 0; i < joy->num_axes; i++ )\r
- if (joy->pJoystick.os->axes_usage[i] == usage)\r
- {\r
- if (usage == HUG_HAT_SWITCH)\r
- {\r
- if (d < 0 || d > 8)\r
- d = 0; /* safety */\r
- joy->pJoystick.os->cache_axes[i] = (float)hatmap_x[d];\r
- joy->pJoystick.os->cache_axes[i + 1] = (float)hatmap_y[d];\r
- }\r
- else\r
- {\r
- joy->pJoystick.os->cache_axes[i] = (float)d;\r
- }\r
- break;\r
- }\r
- }\r
- else if (page == HUP_BUTTON)\r
- {\r
- if (usage > 0 && usage < _JS_MAX_BUTTONS + 1)\r
- {\r
- if (d)\r
- joy->pJoystick.os->cache_buttons |= (1 << ( usage - 1 ));\r
- else\r
- joy->pJoystick.os->cache_buttons &= ~(1 << ( usage - 1 ));\r
- }\r
- }\r
- }\r
- }\r
-# ifdef HAVE_ERRNO_H\r
- if ( len < 0 && errno != EAGAIN )\r
-# else\r
- if ( len < 0 )\r
-# endif\r
- {\r
- perror( joy->pJoystick.os->fname );\r
- joy->error = 1;\r
- }\r
- if ( buttons != NULL ) *buttons = joy->pJoystick.os->cache_buttons;\r
- if ( axes != NULL )\r
- memcpy ( axes, joy->pJoystick.os->cache_axes, sizeof(float) * joy->num_axes );\r
-# endif\r
-#endif\r
-\r
-#ifdef JS_NEW\r
-\r
- while ( 1 )\r
- {\r
- status = read ( joy->pJoystick.fd, &joy->pJoystick.js, sizeof(struct js_event) );\r
-\r
- if ( status != sizeof( struct js_event ) )\r
- {\r
-# ifdef HAVE_ERRNO_H\r
- if ( errno == EAGAIN )\r
- {\r
- /* Use the old values */\r
- if ( buttons )\r
- *buttons = joy->pJoystick.tmp_buttons;\r
- if ( axes )\r
- memcpy( axes, joy->pJoystick.tmp_axes,\r
- sizeof( float ) * joy->num_axes );\r
- return;\r
- }\r
-# endif\r
-\r
- fgWarning ( "%s", joy->pJoystick.fname );\r
- joy->error = GL_TRUE;\r
- return;\r
- }\r
-\r
- switch ( joy->pJoystick.js.type & ~JS_EVENT_INIT )\r
- {\r
- case JS_EVENT_BUTTON:\r
- if( joy->pJoystick.js.value == 0 ) /* clear the flag */\r
- joy->pJoystick.tmp_buttons &= ~( 1 << joy->pJoystick.js.number );\r
- else\r
- joy->pJoystick.tmp_buttons |= ( 1 << joy->pJoystick.js.number );\r
- break;\r
-\r
- case JS_EVENT_AXIS:\r
- if ( joy->pJoystick.js.number < joy->num_axes )\r
- {\r
- joy->pJoystick.tmp_axes[ joy->pJoystick.js.number ] = ( float )joy->pJoystick.js.value;\r
-\r
- if( axes )\r
- memcpy( axes, joy->pJoystick.tmp_axes, sizeof(float) * joy->num_axes );\r
- }\r
- break;\r
-\r
- default:\r
- fgWarning ( "PLIB_JS: Unrecognised /dev/js return!?!" );\r
-\r
- /* use the old values */\r
-\r
- if ( buttons != NULL ) *buttons = joy->pJoystick.tmp_buttons;\r
- if ( axes != NULL )\r
- memcpy ( axes, joy->pJoystick.tmp_axes, sizeof(float) * joy->num_axes );\r
-\r
- return;\r
- }\r
-\r
- if( buttons )\r
- *buttons = joy->pJoystick.tmp_buttons;\r
- }\r
-#else\r
-\r
- status = read( joy->pJoystick.fd, &joy->pJoystick.js, JS_RETURN );\r
-\r
- if ( status != JS_RETURN )\r
- {\r
- fgWarning( "%s", joy->pJoystick.fname );\r
- joy->error = GL_TRUE;\r
- return;\r
- }\r
-\r
- if ( buttons )\r
-# if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ )\r
- *buttons = ( joy->pJoystick.js.b1 ? 1 : 0 ) | ( joy->pJoystick.js.b2 ? 2 : 0 ); /* XXX Should not be here -- BSD is handled earlier */\r
-# else\r
- *buttons = joy->pJoystick.js.buttons;\r
-# endif\r
-\r
- if ( axes )\r
- {\r
- axes[ 0 ] = (float) joy->pJoystick.js.x;\r
- axes[ 1 ] = (float) joy->pJoystick.js.y;\r
- }\r
-#endif\r
-}\r
-\r
-\r
-void fgPlatformJoystickOpen( SFG_Joystick* joy )\r
-{\r
-#if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ )\r
- int i = 0;\r
- char *cp;\r
-#endif\r
-#ifdef JS_NEW\r
- int i = 0;\r
- unsigned char u;\r
-#else\r
-# if defined( __linux__ ) || TARGET_HOST_SOLARIS\r
- int i = 0;\r
- int counter = 0;\r
-# endif\r
-#endif\r
-\r
-#if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ )\r
- for( i = 0; i < _JS_MAX_AXES; i++ )\r
- joy->pJoystick.os->cache_axes[ i ] = 0.0f;\r
-\r
- joy->pJoystick.os->cache_buttons = 0;\r
-\r
- joy->pJoystick.os->fd = open( joy->pJoystick.os->fname, O_RDONLY | O_NONBLOCK);\r
-\r
-#ifdef HAVE_ERRNO_H\r
- if( joy->pJoystick.os->fd < 0 && errno == EACCES )\r
- fgWarning ( "%s exists but is not readable by you", joy->pJoystick.os->fname );\r
-#endif\r
-\r
- joy->error =( joy->pJoystick.os->fd < 0 );\r
-\r
- if( joy->error )\r
- return;\r
-\r
- joy->num_axes = 0;\r
- joy->num_buttons = 0;\r
- if( joy->pJoystick.os->is_analog )\r
- {\r
- FILE *joyfile;\r
- char joyfname[ 1024 ];\r
- int noargs, in_no_axes;\r
-\r
- float axes [ _JS_MAX_AXES ];\r
- int buttons[ _JS_MAX_AXES ];\r
-\r
- joy->num_axes = 2;\r
- joy->num_buttons = 32;\r
-\r
- fghJoystickRawRead( joy, buttons, axes );\r
- joy->error = axes[ 0 ] < -1000000000.0f;\r
- if( joy->error )\r
- return;\r
-\r
- snprintf( joyfname, sizeof(joyfname), "%s/.joy%drc", getenv( "HOME" ), joy->id );\r
-\r
- joyfile = fopen( joyfname, "r" );\r
- joy->error =( joyfile == NULL );\r
- if( joy->error )\r
- return;\r
-\r
- noargs = fscanf( joyfile, "%d%f%f%f%f%f%f", &in_no_axes,\r
- &joy->min[ 0 ], &joy->center[ 0 ], &joy->max[ 0 ],\r
- &joy->min[ 1 ], &joy->center[ 1 ], &joy->max[ 1 ] );\r
- joy->error = noargs != 7 || in_no_axes != _JS_MAX_AXES;\r
- fclose( joyfile );\r
- if( joy->error )\r
- return;\r
-\r
- for( i = 0; i < _JS_MAX_AXES; i++ )\r
- {\r
- joy->dead_band[ i ] = 0.0f;\r
- joy->saturate [ i ] = 1.0f;\r
- }\r
-\r
- return; /* End of analog code */\r
- }\r
-\r
-# ifdef HAVE_USB_JS\r
- if( ! fghJoystickInitializeHID( joy->pJoystick.os, &joy->num_axes,\r
- &joy->num_buttons ) )\r
- {\r
- close( joy->pJoystick.os->fd );\r
- joy->error = GL_TRUE;\r
- return;\r
- }\r
-\r
- cp = strrchr( joy->pJoystick.os->fname, '/' );\r
- if( cp )\r
- {\r
- if( fghJoystickFindUSBdev( &cp[1], joy->name, sizeof( joy->name ) ) ==\r
- 0 )\r
- strcpy( joy->name, &cp[1] );\r
- }\r
-\r
- if( joy->num_axes > _JS_MAX_AXES )\r
- joy->num_axes = _JS_MAX_AXES;\r
-\r
- for( i = 0; i < _JS_MAX_AXES; i++ )\r
- {\r
- /* We really should get this from the HID, but that data seems\r
- * to be quite unreliable for analog-to-USB converters. Punt for\r
- * now.\r
- */\r
- if( joy->pJoystick.os->axes_usage[ i ] == HUG_HAT_SWITCH )\r
- {\r
- joy->max [ i ] = 1.0f;\r
- joy->center[ i ] = 0.0f;\r
- joy->min [ i ] = -1.0f;\r
- }\r
- else\r
- {\r
- joy->max [ i ] = 255.0f;\r
- joy->center[ i ] = 127.0f;\r
- joy->min [ i ] = 0.0f;\r
- }\r
-\r
- joy->dead_band[ i ] = 0.0f;\r
- joy->saturate[ i ] = 1.0f;\r
- }\r
-# endif\r
-#endif\r
-\r
-#if defined( __linux__ ) || TARGET_HOST_SOLARIS\r
- /* Default for older Linux systems. */\r
- joy->num_axes = 2;\r
- joy->num_buttons = 32;\r
-\r
-# ifdef JS_NEW\r
- for( i = 0; i < _JS_MAX_AXES; i++ )\r
- joy->pJoystick.tmp_axes[ i ] = 0.0f;\r
-\r
- joy->pJoystick.tmp_buttons = 0;\r
-# endif\r
-\r
- joy->pJoystick.fd = open( joy->pJoystick.fname, O_RDONLY );\r
-\r
- joy->error =( joy->pJoystick.fd < 0 );\r
-\r
- if( joy->error )\r
- return;\r
-\r
- /* Set the correct number of axes for the linux driver */\r
-# ifdef JS_NEW\r
- /* Melchior Franz's fixes for big-endian Linuxes since writing\r
- * to the upper byte of an uninitialized word doesn't work.\r
- * 9 April 2003\r
- */\r
- ioctl( joy->pJoystick.fd, JSIOCGAXES, &u );\r
- joy->num_axes = u;\r
- ioctl( joy->pJoystick.fd, JSIOCGBUTTONS, &u );\r
- joy->num_buttons = u;\r
- ioctl( joy->pJoystick.fd, JSIOCGNAME( sizeof( joy->name ) ), joy->name );\r
- fcntl( joy->pJoystick.fd, F_SETFL, O_NONBLOCK );\r
-# endif\r
-\r
- /*\r
- * The Linux driver seems to return 512 for all axes\r
- * when no stick is present - but there is a chance\r
- * that could happen by accident - so it's gotta happen\r
- * on both axes for at least 100 attempts.\r
- *\r
- * PWO: shouldn't be that done somehow wiser on the kernel level?\r
- */\r
-# ifndef JS_NEW\r
- counter = 0;\r
-\r
- do\r
- {\r
- fghJoystickRawRead( joy, NULL, joy->center );\r
- counter++;\r
- } while( !joy->error &&\r
- counter < 100 &&\r
- joy->center[ 0 ] == 512.0f &&\r
- joy->center[ 1 ] == 512.0f );\r
-\r
- if ( counter >= 100 )\r
- joy->error = GL_TRUE;\r
-# endif\r
-\r
- for( i = 0; i < _JS_MAX_AXES; i++ )\r
- {\r
-# ifdef JS_NEW\r
- joy->max [ i ] = 32767.0f;\r
- joy->center[ i ] = 0.0f;\r
- joy->min [ i ] = -32767.0f;\r
-# else\r
- joy->max[ i ] = joy->center[ i ] * 2.0f;\r
- joy->min[ i ] = 0.0f;\r
-# endif\r
- joy->dead_band[ i ] = 0.0f;\r
- joy->saturate [ i ] = 1.0f;\r
- }\r
-#endif\r
-}\r
-\r
-\r
-void fgPlatformJoystickInit( SFG_Joystick *fgJoystick[], int ident )\r
-{\r
-#if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ )\r
- fgJoystick[ ident ]->id = ident;\r
- fgJoystick[ ident ]->error = GL_FALSE;\r
-\r
- fgJoystick[ ident ]->pJoystick.os = calloc( 1, sizeof( struct os_specific_s ) );\r
- memset( fgJoystick[ ident ]->pJoystick.os, 0, sizeof( struct os_specific_s ) );\r
- if( ident < USB_IDENT_OFFSET )\r
- fgJoystick[ ident ]->pJoystick.os->is_analog = 1;\r
- if( fgJoystick[ ident ]->pJoystick.os->is_analog )\r
- snprintf( fgJoystick[ ident ]->pJoystick.os->fname, sizeof(fgJoystick[ ident ]->pJoystick.os->fname), "%s%d", AJSDEV, ident );\r
- else\r
- snprintf( fgJoystick[ ident ]->pJoystick.os->fname, sizeof(fgJoystick[ ident ]->pJoystick.os->fname), "%s%d", UHIDDEV,\r
- ident - USB_IDENT_OFFSET );\r
-#elif defined( __linux__ )\r
- fgJoystick[ ident ]->id = ident;\r
- fgJoystick[ ident ]->error = GL_FALSE;\r
-\r
- snprintf( fgJoystick[ident]->pJoystick.fname, sizeof(fgJoystick[ident]->pJoystick.fname), "/dev/input/js%d", ident );\r
-\r
- if( access( fgJoystick[ ident ]->pJoystick.fname, F_OK ) != 0 )\r
- snprintf( fgJoystick[ ident ]->pJoystick.fname, sizeof(fgJoystick[ ident ]->pJoystick.fname), "/dev/js%d", ident );\r
-#endif\r
-}\r
-\r
-\r
-void fgPlatformJoystickClose ( int ident )\r
-{\r
-#if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ )\r
- if( fgJoystick[ident]->pJoystick.os )\r
- {\r
- if( ! fgJoystick[ ident ]->error )\r
- close( fgJoystick[ ident ]->pJoystick.os->fd );\r
-#ifdef HAVE_USB_JS\r
- if( fgJoystick[ ident ]->pJoystick.os->hids )\r
- free (fgJoystick[ ident ]->pJoystick.os->hids);\r
- if( fgJoystick[ ident ]->pJoystick.os->hid_data_buf )\r
- free( fgJoystick[ ident ]->pJoystick.os->hid_data_buf );\r
-#endif\r
- free( fgJoystick[ident]->pJoystick.os );\r
- }\r
-#endif\r
-\r
- if( ! fgJoystick[ident]->error )\r
- close( fgJoystick[ ident ]->pJoystick.fd );\r
-}\r
-#endif\r
-\r
-\r
-\r
\r
\r
\r
+/*\r
+ * freeglut_joystick_x11.c\r
+ *\r
+ * Joystick handling code\r
+ *\r
+ * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.\r
+ * Written by Steve Baker, <sjbaker1@airmail.net>\r
+ * Copied for Platform code by Evan Felix <karcaw at gmail.com>\r
+ * Creation date: Thur Feb 2 2012\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a\r
+ * copy of this software and associated documentation files (the "Software"),\r
+ * to deal in the Software without restriction, including without limitation\r
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
+ * and/or sell copies of the Software, and to permit persons to whom the\r
+ * Software is furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included\r
+ * in all copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\r
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ */\r
+\r
+/*\r
+ * FreeBSD port by Stephen Montgomery-Smith <stephen@math.missouri.edu>\r
+ *\r
+ * Redone by John Fay 2/4/04 with another look from the PLIB "js" library.\r
+ * Many thanks for Steve Baker for permission to pull from that library.\r
+ */\r
+\r
+#include <GL/freeglut.h>\r
+#include "freeglut_internal.h"\r
+#ifdef HAVE_SYS_PARAM_H\r
+# include <sys/param.h>\r
+#endif\r
+\r
+\r
+/*this should be defined in a header file */\r
+#define MAX_NUM_JOYSTICKS 2 \r
+extern SFG_Joystick *fgJoystick [ MAX_NUM_JOYSTICKS ];\r
+\r
+void fgPlatformJoystickRawRead( SFG_Joystick* joy, int* buttons, float* axes )\r
+{\r
+ int status;\r
+\r
+ int i;\r
+\r
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__)\r
+ int len;\r
+\r
+ if ( joy->pJoystick.os->is_analog )\r
+ {\r
+ int status = read ( joy->pJoystick.os->fd, &joy->pJoystick.os->ajs, sizeof(joy->pJoystick.os->ajs) );\r
+ if ( status != sizeof(joy->pJoystick.os->ajs) ) {\r
+ perror ( joy->pJoystick.os->fname );\r
+ joy->error = GL_TRUE;\r
+ return;\r
+ }\r
+ if ( buttons != NULL )\r
+ *buttons = ( joy->pJoystick.os->ajs.b1 ? 1 : 0 ) | ( joy->pJoystick.os->ajs.b2 ? 2 : 0 );\r
+\r
+ if ( axes != NULL )\r
+ {\r
+ axes[0] = (float) joy->pJoystick.os->ajs.x;\r
+ axes[1] = (float) joy->pJoystick.os->ajs.y;\r
+ }\r
+\r
+ return;\r
+ }\r
+\r
+# ifdef HAVE_USB_JS\r
+ while ( ( len = read ( joy->pJoystick.os->fd, joy->pJoystick.os->hid_data_buf, joy->pJoystick.os->hid_dlen ) ) == joy->pJoystick.os->hid_dlen )\r
+ {\r
+ struct hid_item *h;\r
+\r
+ for ( h = joy->pJoystick.os->hids; h; h = h->next )\r
+ {\r
+ int d = hid_get_data ( joy->pJoystick.os->hid_data_buf, h );\r
+\r
+ int page = HID_PAGE ( h->usage );\r
+ int usage = HID_USAGE ( h->usage );\r
+\r
+ if ( page == HUP_GENERIC_DESKTOP )\r
+ {\r
+ int i;\r
+ for ( i = 0; i < joy->num_axes; i++ )\r
+ if (joy->pJoystick.os->axes_usage[i] == usage)\r
+ {\r
+ if (usage == HUG_HAT_SWITCH)\r
+ {\r
+ if (d < 0 || d > 8)\r
+ d = 0; /* safety */\r
+ joy->pJoystick.os->cache_axes[i] = (float)hatmap_x[d];\r
+ joy->pJoystick.os->cache_axes[i + 1] = (float)hatmap_y[d];\r
+ }\r
+ else\r
+ {\r
+ joy->pJoystick.os->cache_axes[i] = (float)d;\r
+ }\r
+ break;\r
+ }\r
+ }\r
+ else if (page == HUP_BUTTON)\r
+ {\r
+ if (usage > 0 && usage < _JS_MAX_BUTTONS + 1)\r
+ {\r
+ if (d)\r
+ joy->pJoystick.os->cache_buttons |= (1 << ( usage - 1 ));\r
+ else\r
+ joy->pJoystick.os->cache_buttons &= ~(1 << ( usage - 1 ));\r
+ }\r
+ }\r
+ }\r
+ }\r
+# ifdef HAVE_ERRNO_H\r
+ if ( len < 0 && errno != EAGAIN )\r
+# else\r
+ if ( len < 0 )\r
+# endif\r
+ {\r
+ perror( joy->pJoystick.os->fname );\r
+ joy->error = 1;\r
+ }\r
+ if ( buttons != NULL ) *buttons = joy->pJoystick.os->cache_buttons;\r
+ if ( axes != NULL )\r
+ memcpy ( axes, joy->pJoystick.os->cache_axes, sizeof(float) * joy->num_axes );\r
+# endif\r
+#endif\r
+\r
+#ifdef JS_NEW\r
+\r
+ while ( 1 )\r
+ {\r
+ status = read ( joy->pJoystick.fd, &joy->pJoystick.js, sizeof(struct js_event) );\r
+\r
+ if ( status != sizeof( struct js_event ) )\r
+ {\r
+# ifdef HAVE_ERRNO_H\r
+ if ( errno == EAGAIN )\r
+ {\r
+ /* Use the old values */\r
+ if ( buttons )\r
+ *buttons = joy->pJoystick.tmp_buttons;\r
+ if ( axes )\r
+ memcpy( axes, joy->pJoystick.tmp_axes,\r
+ sizeof( float ) * joy->num_axes );\r
+ return;\r
+ }\r
+# endif\r
+\r
+ fgWarning ( "%s", joy->pJoystick.fname );\r
+ joy->error = GL_TRUE;\r
+ return;\r
+ }\r
+\r
+ switch ( joy->pJoystick.js.type & ~JS_EVENT_INIT )\r
+ {\r
+ case JS_EVENT_BUTTON:\r
+ if( joy->pJoystick.js.value == 0 ) /* clear the flag */\r
+ joy->pJoystick.tmp_buttons &= ~( 1 << joy->pJoystick.js.number );\r
+ else\r
+ joy->pJoystick.tmp_buttons |= ( 1 << joy->pJoystick.js.number );\r
+ break;\r
+\r
+ case JS_EVENT_AXIS:\r
+ if ( joy->pJoystick.js.number < joy->num_axes )\r
+ {\r
+ joy->pJoystick.tmp_axes[ joy->pJoystick.js.number ] = ( float )joy->pJoystick.js.value;\r
+\r
+ if( axes )\r
+ memcpy( axes, joy->pJoystick.tmp_axes, sizeof(float) * joy->num_axes );\r
+ }\r
+ break;\r
+\r
+ default:\r
+ fgWarning ( "PLIB_JS: Unrecognised /dev/js return!?!" );\r
+\r
+ /* use the old values */\r
+\r
+ if ( buttons != NULL ) *buttons = joy->pJoystick.tmp_buttons;\r
+ if ( axes != NULL )\r
+ memcpy ( axes, joy->pJoystick.tmp_axes, sizeof(float) * joy->num_axes );\r
+\r
+ return;\r
+ }\r
+\r
+ if( buttons )\r
+ *buttons = joy->pJoystick.tmp_buttons;\r
+ }\r
+#else\r
+\r
+ status = read( joy->pJoystick.fd, &joy->pJoystick.js, JS_RETURN );\r
+\r
+ if ( status != JS_RETURN )\r
+ {\r
+ fgWarning( "%s", joy->pJoystick.fname );\r
+ joy->error = GL_TRUE;\r
+ return;\r
+ }\r
+\r
+ if ( buttons )\r
+# if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ )\r
+ *buttons = ( joy->pJoystick.js.b1 ? 1 : 0 ) | ( joy->pJoystick.js.b2 ? 2 : 0 ); /* XXX Should not be here -- BSD is handled earlier */\r
+# else\r
+ *buttons = joy->pJoystick.js.buttons;\r
+# endif\r
+\r
+ if ( axes )\r
+ {\r
+ axes[ 0 ] = (float) joy->pJoystick.js.x;\r
+ axes[ 1 ] = (float) joy->pJoystick.js.y;\r
+ }\r
+#endif\r
+}\r
+\r
+\r
+void fgPlatformJoystickOpen( SFG_Joystick* joy )\r
+{\r
+#if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ )\r
+ int i = 0;\r
+ char *cp;\r
+#endif\r
+#ifdef JS_NEW\r
+ unsigned char u;\r
+ int i=0;\r
+#else\r
+# if defined( __linux__ ) || TARGET_HOST_SOLARIS\r
+ int i = 0;\r
+ int counter = 0;\r
+# endif\r
+#endif\r
+\r
+#if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ )\r
+ for( i = 0; i < _JS_MAX_AXES; i++ )\r
+ joy->pJoystick.os->cache_axes[ i ] = 0.0f;\r
+\r
+ joy->pJoystick.os->cache_buttons = 0;\r
+\r
+ joy->pJoystick.os->fd = open( joy->pJoystick.os->fname, O_RDONLY | O_NONBLOCK);\r
+\r
+#ifdef HAVE_ERRNO_H\r
+ if( joy->pJoystick.os->fd < 0 && errno == EACCES )\r
+ fgWarning ( "%s exists but is not readable by you", joy->pJoystick.os->fname );\r
+#endif\r
+\r
+ joy->error =( joy->pJoystick.os->fd < 0 );\r
+\r
+ if( joy->error )\r
+ return;\r
+\r
+ joy->num_axes = 0;\r
+ joy->num_buttons = 0;\r
+ if( joy->pJoystick.os->is_analog )\r
+ {\r
+ FILE *joyfile;\r
+ char joyfname[ 1024 ];\r
+ int noargs, in_no_axes;\r
+\r
+ float axes [ _JS_MAX_AXES ];\r
+ int buttons[ _JS_MAX_AXES ];\r
+\r
+ joy->num_axes = 2;\r
+ joy->num_buttons = 32;\r
+\r
+ fghJoystickRawRead( joy, buttons, axes );\r
+ joy->error = axes[ 0 ] < -1000000000.0f;\r
+ if( joy->error )\r
+ return;\r
+\r
+ snprintf( joyfname, sizeof(joyfname), "%s/.joy%drc", getenv( "HOME" ), joy->id );\r
+\r
+ joyfile = fopen( joyfname, "r" );\r
+ joy->error =( joyfile == NULL );\r
+ if( joy->error )\r
+ return;\r
+\r
+ noargs = fscanf( joyfile, "%d%f%f%f%f%f%f", &in_no_axes,\r
+ &joy->min[ 0 ], &joy->center[ 0 ], &joy->max[ 0 ],\r
+ &joy->min[ 1 ], &joy->center[ 1 ], &joy->max[ 1 ] );\r
+ joy->error = noargs != 7 || in_no_axes != _JS_MAX_AXES;\r
+ fclose( joyfile );\r
+ if( joy->error )\r
+ return;\r
+\r
+ for( i = 0; i < _JS_MAX_AXES; i++ )\r
+ {\r
+ joy->dead_band[ i ] = 0.0f;\r
+ joy->saturate [ i ] = 1.0f;\r
+ }\r
+\r
+ return; /* End of analog code */\r
+ }\r
+\r
+# ifdef HAVE_USB_JS\r
+ if( ! fghJoystickInitializeHID( joy->pJoystick.os, &joy->num_axes,\r
+ &joy->num_buttons ) )\r
+ {\r
+ close( joy->pJoystick.os->fd );\r
+ joy->error = GL_TRUE;\r
+ return;\r
+ }\r
+\r
+ cp = strrchr( joy->pJoystick.os->fname, '/' );\r
+ if( cp )\r
+ {\r
+ if( fghJoystickFindUSBdev( &cp[1], joy->name, sizeof( joy->name ) ) ==\r
+ 0 )\r
+ strcpy( joy->name, &cp[1] );\r
+ }\r
+\r
+ if( joy->num_axes > _JS_MAX_AXES )\r
+ joy->num_axes = _JS_MAX_AXES;\r
+\r
+ for( i = 0; i < _JS_MAX_AXES; i++ )\r
+ {\r
+ /* We really should get this from the HID, but that data seems\r
+ * to be quite unreliable for analog-to-USB converters. Punt for\r
+ * now.\r
+ */\r
+ if( joy->pJoystick.os->axes_usage[ i ] == HUG_HAT_SWITCH )\r
+ {\r
+ joy->max [ i ] = 1.0f;\r
+ joy->center[ i ] = 0.0f;\r
+ joy->min [ i ] = -1.0f;\r
+ }\r
+ else\r
+ {\r
+ joy->max [ i ] = 255.0f;\r
+ joy->center[ i ] = 127.0f;\r
+ joy->min [ i ] = 0.0f;\r
+ }\r
+\r
+ joy->dead_band[ i ] = 0.0f;\r
+ joy->saturate[ i ] = 1.0f;\r
+ }\r
+# endif\r
+#endif\r
+\r
+#if defined( __linux__ ) || TARGET_HOST_SOLARIS\r
+ /* Default for older Linux systems. */\r
+ joy->num_axes = 2;\r
+ joy->num_buttons = 32;\r
+\r
+# ifdef JS_NEW\r
+ for( i = 0; i < _JS_MAX_AXES; i++ )\r
+ joy->pJoystick.tmp_axes[ i ] = 0.0f;\r
+\r
+ joy->pJoystick.tmp_buttons = 0;\r
+# endif\r
+\r
+ joy->pJoystick.fd = open( joy->pJoystick.fname, O_RDONLY );\r
+\r
+ joy->error =( joy->pJoystick.fd < 0 );\r
+\r
+ if( joy->error )\r
+ return;\r
+\r
+ /* Set the correct number of axes for the linux driver */\r
+# ifdef JS_NEW\r
+ /* Melchior Franz's fixes for big-endian Linuxes since writing\r
+ * to the upper byte of an uninitialized word doesn't work.\r
+ * 9 April 2003\r
+ */\r
+ ioctl( joy->pJoystick.fd, JSIOCGAXES, &u );\r
+ joy->num_axes = u;\r
+ ioctl( joy->pJoystick.fd, JSIOCGBUTTONS, &u );\r
+ joy->num_buttons = u;\r
+ ioctl( joy->pJoystick.fd, JSIOCGNAME( sizeof( joy->name ) ), joy->name );\r
+ fcntl( joy->pJoystick.fd, F_SETFL, O_NONBLOCK );\r
+# endif\r
+\r
+ /*\r
+ * The Linux driver seems to return 512 for all axes\r
+ * when no stick is present - but there is a chance\r
+ * that could happen by accident - so it's gotta happen\r
+ * on both axes for at least 100 attempts.\r
+ *\r
+ * PWO: shouldn't be that done somehow wiser on the kernel level?\r
+ */\r
+# ifndef JS_NEW\r
+ counter = 0;\r
+\r
+ do\r
+ {\r
+ fghJoystickRawRead( joy, NULL, joy->center );\r
+ counter++;\r
+ } while( !joy->error &&\r
+ counter < 100 &&\r
+ joy->center[ 0 ] == 512.0f &&\r
+ joy->center[ 1 ] == 512.0f );\r
+\r
+ if ( counter >= 100 )\r
+ joy->error = GL_TRUE;\r
+# endif\r
+\r
+ for( i = 0; i < _JS_MAX_AXES; i++ )\r
+ {\r
+# ifdef JS_NEW\r
+ joy->max [ i ] = 32767.0f;\r
+ joy->center[ i ] = 0.0f;\r
+ joy->min [ i ] = -32767.0f;\r
+# else\r
+ joy->max[ i ] = joy->center[ i ] * 2.0f;\r
+ joy->min[ i ] = 0.0f;\r
+# endif\r
+ joy->dead_band[ i ] = 0.0f;\r
+ joy->saturate [ i ] = 1.0f;\r
+ }\r
+#endif\r
+}\r
+\r
+\r
+void fgPlatformJoystickInit( SFG_Joystick *fgJoystick[], int ident )\r
+{\r
+#if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ )\r
+ fgJoystick[ ident ]->id = ident;\r
+ fgJoystick[ ident ]->error = GL_FALSE;\r
+\r
+ fgJoystick[ ident ]->pJoystick.os = calloc( 1, sizeof( struct os_specific_s ) );\r
+ memset( fgJoystick[ ident ]->pJoystick.os, 0, sizeof( struct os_specific_s ) );\r
+ if( ident < USB_IDENT_OFFSET )\r
+ fgJoystick[ ident ]->pJoystick.os->is_analog = 1;\r
+ if( fgJoystick[ ident ]->pJoystick.os->is_analog )\r
+ snprintf( fgJoystick[ ident ]->pJoystick.os->fname, sizeof(fgJoystick[ ident ]->pJoystick.os->fname), "%s%d", AJSDEV, ident );\r
+ else\r
+ snprintf( fgJoystick[ ident ]->pJoystick.os->fname, sizeof(fgJoystick[ ident ]->pJoystick.os->fname), "%s%d", UHIDDEV,\r
+ ident - USB_IDENT_OFFSET );\r
+#elif defined( __linux__ )\r
+ fgJoystick[ ident ]->id = ident;\r
+ fgJoystick[ ident ]->error = GL_FALSE;\r
+\r
+ snprintf( fgJoystick[ident]->pJoystick.fname, sizeof(fgJoystick[ident]->pJoystick.fname), "/dev/input/js%d", ident );\r
+\r
+ if( access( fgJoystick[ ident ]->pJoystick.fname, F_OK ) != 0 )\r
+ snprintf( fgJoystick[ ident ]->pJoystick.fname, sizeof(fgJoystick[ ident ]->pJoystick.fname), "/dev/js%d", ident );\r
+#endif\r
+}\r
+\r
+\r
+void fgPlatformJoystickClose ( int ident )\r
+{\r
+#if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ )\r
+ if( fgJoystick[ident]->pJoystick.os )\r
+ {\r
+ if( ! fgJoystick[ ident ]->error )\r
+ close( fgJoystick[ ident ]->pJoystick.os->fd );\r
+#ifdef HAVE_USB_JS\r
+ if( fgJoystick[ ident ]->pJoystick.os->hids )\r
+ free (fgJoystick[ ident ]->pJoystick.os->hids);\r
+ if( fgJoystick[ ident ]->pJoystick.os->hid_data_buf )\r
+ free( fgJoystick[ ident ]->pJoystick.os->hid_data_buf );\r
+#endif\r
+ free( fgJoystick[ident]->pJoystick.os );\r
+ }\r
+#endif\r
+\r
+ if( ! fgJoystick[ident]->error )\r
+ close( fgJoystick[ ident ]->pJoystick.fd );\r
+}\r
+\r