| 1 | /* | 
|---|
| 2 | * fg_joystick_x11.c | 
|---|
| 3 | * | 
|---|
| 4 | * Joystick handling code | 
|---|
| 5 | * | 
|---|
| 6 | * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. | 
|---|
| 7 | * Written by Steve Baker, <sjbaker1@airmail.net> | 
|---|
| 8 | * Copied for Platform code by Evan Felix <karcaw at gmail.com> | 
|---|
| 9 | * Creation date: Thur Feb 2 2012 | 
|---|
| 10 | * | 
|---|
| 11 | * Permission is hereby granted, free of charge, to any person obtaining a | 
|---|
| 12 | * copy of this software and associated documentation files (the "Software"), | 
|---|
| 13 | * to deal in the Software without restriction, including without limitation | 
|---|
| 14 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | 
|---|
| 15 | * and/or sell copies of the Software, and to permit persons to whom the | 
|---|
| 16 | * Software is furnished to do so, subject to the following conditions: | 
|---|
| 17 | * | 
|---|
| 18 | * The above copyright notice and this permission notice shall be included | 
|---|
| 19 | * in all copies or substantial portions of the Software. | 
|---|
| 20 | * | 
|---|
| 21 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | 
|---|
| 22 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 
|---|
| 23 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL | 
|---|
| 24 | * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | 
|---|
| 25 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | 
|---|
| 26 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | 
|---|
| 27 | */ | 
|---|
| 28 |  | 
|---|
| 29 | /* | 
|---|
| 30 | * FreeBSD port by Stephen Montgomery-Smith <stephen@math.missouri.edu> | 
|---|
| 31 | * | 
|---|
| 32 | * Redone by John Fay 2/4/04 with another look from the PLIB "js" library. | 
|---|
| 33 | *  Many thanks for Steve Baker for permission to pull from that library. | 
|---|
| 34 | */ | 
|---|
| 35 |  | 
|---|
| 36 | #include <GL/freeglut.h> | 
|---|
| 37 | #include "../fg_internal.h" | 
|---|
| 38 | #ifdef HAVE_SYS_PARAM_H | 
|---|
| 39 | #    include <sys/param.h> | 
|---|
| 40 | #endif | 
|---|
| 41 |  | 
|---|
| 42 | #include <fcntl.h> | 
|---|
| 43 |  | 
|---|
| 44 |  | 
|---|
| 45 | /*this should be defined in a header file */ | 
|---|
| 46 | #define MAX_NUM_JOYSTICKS  2 | 
|---|
| 47 | extern SFG_Joystick *fgJoystick [ MAX_NUM_JOYSTICKS ]; | 
|---|
| 48 |  | 
|---|
| 49 | void fgPlatformJoystickRawRead( SFG_Joystick* joy, int* buttons, float* axes ) | 
|---|
| 50 | { | 
|---|
| 51 | int status; | 
|---|
| 52 |  | 
|---|
| 53 | #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) | 
|---|
| 54 | int len; | 
|---|
| 55 |  | 
|---|
| 56 | if ( joy->pJoystick.os->is_analog ) | 
|---|
| 57 | { | 
|---|
| 58 | int status = read ( joy->pJoystick.os->fd, &joy->pJoystick.os->ajs, sizeof(joy->pJoystick.os->ajs) ); | 
|---|
| 59 | if ( status != sizeof(joy->pJoystick.os->ajs) ) { | 
|---|
| 60 | perror ( joy->pJoystick.os->fname ); | 
|---|
| 61 | joy->error = GL_TRUE; | 
|---|
| 62 | return; | 
|---|
| 63 | } | 
|---|
| 64 | if ( buttons != NULL ) | 
|---|
| 65 | *buttons = ( joy->pJoystick.os->ajs.b1 ? 1 : 0 ) | ( joy->pJoystick.os->ajs.b2 ? 2 : 0 ); | 
|---|
| 66 |  | 
|---|
| 67 | if ( axes != NULL ) | 
|---|
| 68 | { | 
|---|
| 69 | axes[0] = (float) joy->pJoystick.os->ajs.x; | 
|---|
| 70 | axes[1] = (float) joy->pJoystick.os->ajs.y; | 
|---|
| 71 | } | 
|---|
| 72 |  | 
|---|
| 73 | return; | 
|---|
| 74 | } | 
|---|
| 75 |  | 
|---|
| 76 | #  ifdef HAVE_USB_JS | 
|---|
| 77 | while ( ( len = read ( joy->pJoystick.os->fd, joy->pJoystick.os->hid_data_buf, joy->pJoystick.os->hid_dlen ) ) == joy->pJoystick.os->hid_dlen ) | 
|---|
| 78 | { | 
|---|
| 79 | struct hid_item *h; | 
|---|
| 80 |  | 
|---|
| 81 | for  ( h = joy->pJoystick.os->hids; h; h = h->next ) | 
|---|
| 82 | { | 
|---|
| 83 | int d = hid_get_data ( joy->pJoystick.os->hid_data_buf, h ); | 
|---|
| 84 |  | 
|---|
| 85 | int page = HID_PAGE ( h->usage ); | 
|---|
| 86 | int usage = HID_USAGE ( h->usage ); | 
|---|
| 87 |  | 
|---|
| 88 | if ( page == HUP_GENERIC_DESKTOP ) | 
|---|
| 89 | { | 
|---|
| 90 | int i; | 
|---|
| 91 | for ( i = 0; i < joy->num_axes; i++ ) | 
|---|
| 92 | if (joy->pJoystick.os->axes_usage[i] == usage) | 
|---|
| 93 | { | 
|---|
| 94 | if (usage == HUG_HAT_SWITCH) | 
|---|
| 95 | { | 
|---|
| 96 | if (d < 0 || d > 8) | 
|---|
| 97 | d = 0;  /* safety */ | 
|---|
| 98 | joy->pJoystick.os->cache_axes[i] = (float)hatmap_x[d]; | 
|---|
| 99 | joy->pJoystick.os->cache_axes[i + 1] = (float)hatmap_y[d]; | 
|---|
| 100 | } | 
|---|
| 101 | else | 
|---|
| 102 | { | 
|---|
| 103 | joy->pJoystick.os->cache_axes[i] = (float)d; | 
|---|
| 104 | } | 
|---|
| 105 | break; | 
|---|
| 106 | } | 
|---|
| 107 | } | 
|---|
| 108 | else if (page == HUP_BUTTON) | 
|---|
| 109 | { | 
|---|
| 110 | if (usage > 0 && usage < _JS_MAX_BUTTONS + 1) | 
|---|
| 111 | { | 
|---|
| 112 | if (d) | 
|---|
| 113 | joy->pJoystick.os->cache_buttons |=  (1 << ( usage - 1 )); | 
|---|
| 114 | else | 
|---|
| 115 | joy->pJoystick.os->cache_buttons &= ~(1 << ( usage - 1 )); | 
|---|
| 116 | } | 
|---|
| 117 | } | 
|---|
| 118 | } | 
|---|
| 119 | } | 
|---|
| 120 | if ( len < 0 && errno != EAGAIN ) | 
|---|
| 121 | { | 
|---|
| 122 | perror( joy->pJoystick.os->fname ); | 
|---|
| 123 | joy->error = 1; | 
|---|
| 124 | } | 
|---|
| 125 | if ( buttons != NULL ) *buttons = joy->pJoystick.os->cache_buttons; | 
|---|
| 126 | if ( axes    != NULL ) | 
|---|
| 127 | memcpy ( axes, joy->pJoystick.os->cache_axes, sizeof(float) * joy->num_axes ); | 
|---|
| 128 | #  endif | 
|---|
| 129 | #endif | 
|---|
| 130 |  | 
|---|
| 131 | #ifdef JS_NEW | 
|---|
| 132 |  | 
|---|
| 133 | while ( 1 ) | 
|---|
| 134 | { | 
|---|
| 135 | status = read ( joy->pJoystick.fd, &joy->pJoystick.js, sizeof(struct js_event) ); | 
|---|
| 136 |  | 
|---|
| 137 | if ( status != sizeof( struct js_event ) ) | 
|---|
| 138 | { | 
|---|
| 139 | if ( errno == EAGAIN ) | 
|---|
| 140 | { | 
|---|
| 141 | /* Use the old values */ | 
|---|
| 142 | if ( buttons ) | 
|---|
| 143 | *buttons = joy->pJoystick.tmp_buttons; | 
|---|
| 144 | if ( axes ) | 
|---|
| 145 | memcpy( axes, joy->pJoystick.tmp_axes, | 
|---|
| 146 | sizeof( float ) * joy->num_axes ); | 
|---|
| 147 | return; | 
|---|
| 148 | } | 
|---|
| 149 |  | 
|---|
| 150 | fgWarning ( "%s", joy->pJoystick.fname ); | 
|---|
| 151 | joy->error = GL_TRUE; | 
|---|
| 152 | return; | 
|---|
| 153 | } | 
|---|
| 154 |  | 
|---|
| 155 | switch ( joy->pJoystick.js.type & ~JS_EVENT_INIT ) | 
|---|
| 156 | { | 
|---|
| 157 | case JS_EVENT_BUTTON: | 
|---|
| 158 | if( joy->pJoystick.js.value == 0 ) /* clear the flag */ | 
|---|
| 159 | joy->pJoystick.tmp_buttons &= ~( 1 << joy->pJoystick.js.number ); | 
|---|
| 160 | else | 
|---|
| 161 | joy->pJoystick.tmp_buttons |= ( 1 << joy->pJoystick.js.number ); | 
|---|
| 162 | break; | 
|---|
| 163 |  | 
|---|
| 164 | case JS_EVENT_AXIS: | 
|---|
| 165 | if ( joy->pJoystick.js.number < joy->num_axes ) | 
|---|
| 166 | { | 
|---|
| 167 | joy->pJoystick.tmp_axes[ joy->pJoystick.js.number ] = ( float )joy->pJoystick.js.value; | 
|---|
| 168 |  | 
|---|
| 169 | if( axes ) | 
|---|
| 170 | memcpy( axes, joy->pJoystick.tmp_axes, sizeof(float) * joy->num_axes ); | 
|---|
| 171 | } | 
|---|
| 172 | break; | 
|---|
| 173 |  | 
|---|
| 174 | default: | 
|---|
| 175 | fgWarning ( "PLIB_JS: Unrecognised /dev/js return!?!"); | 
|---|
| 176 |  | 
|---|
| 177 | /* use the old values */ | 
|---|
| 178 |  | 
|---|
| 179 | if ( buttons != NULL ) *buttons = joy->pJoystick.tmp_buttons; | 
|---|
| 180 | if ( axes    != NULL ) | 
|---|
| 181 | memcpy ( axes, joy->pJoystick.tmp_axes, sizeof(float) * joy->num_axes ); | 
|---|
| 182 |  | 
|---|
| 183 | return; | 
|---|
| 184 | } | 
|---|
| 185 |  | 
|---|
| 186 | if( buttons ) | 
|---|
| 187 | *buttons = joy->pJoystick.tmp_buttons; | 
|---|
| 188 | } | 
|---|
| 189 | #else | 
|---|
| 190 |  | 
|---|
| 191 | status = read( joy->pJoystick.fd, &joy->pJoystick.js, JS_RETURN ); | 
|---|
| 192 |  | 
|---|
| 193 | if ( status != JS_RETURN ) | 
|---|
| 194 | { | 
|---|
| 195 | fgWarning( "%s", joy->pJoystick.fname ); | 
|---|
| 196 | joy->error = GL_TRUE; | 
|---|
| 197 | return; | 
|---|
| 198 | } | 
|---|
| 199 |  | 
|---|
| 200 | if ( buttons ) | 
|---|
| 201 | #    if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ ) | 
|---|
| 202 | *buttons = ( joy->pJoystick.js.b1 ? 1 : 0 ) | ( joy->pJoystick.js.b2 ? 2 : 0 );  /* XXX Should not be here -- BSD is handled earlier */ | 
|---|
| 203 | #    else | 
|---|
| 204 | *buttons = joy->pJoystick.js.buttons; | 
|---|
| 205 | #    endif | 
|---|
| 206 |  | 
|---|
| 207 | if ( axes ) | 
|---|
| 208 | { | 
|---|
| 209 | axes[ 0 ] = (float) joy->pJoystick.js.x; | 
|---|
| 210 | axes[ 1 ] = (float) joy->pJoystick.js.y; | 
|---|
| 211 | } | 
|---|
| 212 | #endif | 
|---|
| 213 | } | 
|---|
| 214 |  | 
|---|
| 215 |  | 
|---|
| 216 | void fgPlatformJoystickOpen( SFG_Joystick* joy ) | 
|---|
| 217 | { | 
|---|
| 218 | #if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ ) | 
|---|
| 219 | int i = 0; | 
|---|
| 220 | char *cp; | 
|---|
| 221 | #endif | 
|---|
| 222 | #ifdef JS_NEW | 
|---|
| 223 | unsigned char u; | 
|---|
| 224 | int i=0; | 
|---|
| 225 | #else | 
|---|
| 226 | #  if defined( __linux__ ) || TARGET_HOST_SOLARIS | 
|---|
| 227 | int i = 0; | 
|---|
| 228 | int counter = 0; | 
|---|
| 229 | #  endif | 
|---|
| 230 | #endif | 
|---|
| 231 |  | 
|---|
| 232 | #if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ ) | 
|---|
| 233 | for( i = 0; i < _JS_MAX_AXES; i++ ) | 
|---|
| 234 | joy->pJoystick.os->cache_axes[ i ] = 0.0f; | 
|---|
| 235 |  | 
|---|
| 236 | joy->pJoystick.os->cache_buttons = 0; | 
|---|
| 237 |  | 
|---|
| 238 | joy->pJoystick.os->fd = open( joy->pJoystick.os->fname, O_RDONLY | O_NONBLOCK); | 
|---|
| 239 |  | 
|---|
| 240 | if( joy->pJoystick.os->fd < 0 && errno == EACCES ) | 
|---|
| 241 | fgWarning ( "%s exists but is not readable by you", joy->pJoystick.os->fname ); | 
|---|
| 242 |  | 
|---|
| 243 | joy->error =( joy->pJoystick.os->fd < 0 ); | 
|---|
| 244 |  | 
|---|
| 245 | if( joy->error ) | 
|---|
| 246 | return; | 
|---|
| 247 |  | 
|---|
| 248 | joy->num_axes = 0; | 
|---|
| 249 | joy->num_buttons = 0; | 
|---|
| 250 | if( joy->pJoystick.os->is_analog ) | 
|---|
| 251 | { | 
|---|
| 252 | FILE *joyfile; | 
|---|
| 253 | char joyfname[ 1024 ]; | 
|---|
| 254 | int noargs, in_no_axes; | 
|---|
| 255 |  | 
|---|
| 256 | float axes [ _JS_MAX_AXES ]; | 
|---|
| 257 | int buttons[ _JS_MAX_AXES ]; | 
|---|
| 258 |  | 
|---|
| 259 | joy->num_axes    =  2; | 
|---|
| 260 | joy->num_buttons = 32; | 
|---|
| 261 |  | 
|---|
| 262 | fghJoystickRawRead( joy, buttons, axes ); | 
|---|
| 263 | joy->error = axes[ 0 ] < -1000000000.0f; | 
|---|
| 264 | if( joy->error ) | 
|---|
| 265 | return; | 
|---|
| 266 |  | 
|---|
| 267 | snprintf( joyfname, sizeof(joyfname), "%s/.joy%drc", getenv( "HOME"), joy->id ); | 
|---|
| 268 |  | 
|---|
| 269 | joyfile = fopen( joyfname, "r"); | 
|---|
| 270 | joy->error =( joyfile == NULL ); | 
|---|
| 271 | if( joy->error ) | 
|---|
| 272 | return; | 
|---|
| 273 |  | 
|---|
| 274 | noargs = fscanf( joyfile, "%d%f%f%f%f%f%f", &in_no_axes, | 
|---|
| 275 | &joy->min[ 0 ], &joy->center[ 0 ], &joy->max[ 0 ], | 
|---|
| 276 | &joy->min[ 1 ], &joy->center[ 1 ], &joy->max[ 1 ] ); | 
|---|
| 277 | joy->error = noargs != 7 || in_no_axes != _JS_MAX_AXES; | 
|---|
| 278 | fclose( joyfile ); | 
|---|
| 279 | if( joy->error ) | 
|---|
| 280 | return; | 
|---|
| 281 |  | 
|---|
| 282 | for( i = 0; i < _JS_MAX_AXES; i++ ) | 
|---|
| 283 | { | 
|---|
| 284 | joy->dead_band[ i ] = 0.0f; | 
|---|
| 285 | joy->saturate [ i ] = 1.0f; | 
|---|
| 286 | } | 
|---|
| 287 |  | 
|---|
| 288 | return;    /* End of analog code */ | 
|---|
| 289 | } | 
|---|
| 290 |  | 
|---|
| 291 | #    ifdef HAVE_USB_JS | 
|---|
| 292 | if( ! fghJoystickInitializeHID( joy->pJoystick.os, &joy->num_axes, | 
|---|
| 293 | &joy->num_buttons ) ) | 
|---|
| 294 | { | 
|---|
| 295 | close( joy->pJoystick.os->fd ); | 
|---|
| 296 | joy->error = GL_TRUE; | 
|---|
| 297 | return; | 
|---|
| 298 | } | 
|---|
| 299 |  | 
|---|
| 300 | cp = strrchr( joy->pJoystick.os->fname, '/' ); | 
|---|
| 301 | if( cp ) | 
|---|
| 302 | { | 
|---|
| 303 | if( fghJoystickFindUSBdev( &cp[1], joy->name, sizeof( joy->name ) ) == | 
|---|
| 304 | 0 ) | 
|---|
| 305 | strcpy( joy->name, &cp[1] ); | 
|---|
| 306 | } | 
|---|
| 307 |  | 
|---|
| 308 | if( joy->num_axes > _JS_MAX_AXES ) | 
|---|
| 309 | joy->num_axes = _JS_MAX_AXES; | 
|---|
| 310 |  | 
|---|
| 311 | for( i = 0; i < _JS_MAX_AXES; i++ ) | 
|---|
| 312 | { | 
|---|
| 313 | /* We really should get this from the HID, but that data seems | 
|---|
| 314 | * to be quite unreliable for analog-to-USB converters. Punt for | 
|---|
| 315 | * now. | 
|---|
| 316 | */ | 
|---|
| 317 | if( joy->pJoystick.os->axes_usage[ i ] == HUG_HAT_SWITCH ) | 
|---|
| 318 | { | 
|---|
| 319 | joy->max   [ i ] = 1.0f; | 
|---|
| 320 | joy->center[ i ] = 0.0f; | 
|---|
| 321 | joy->min   [ i ] = -1.0f; | 
|---|
| 322 | } | 
|---|
| 323 | else | 
|---|
| 324 | { | 
|---|
| 325 | joy->max   [ i ] = 255.0f; | 
|---|
| 326 | joy->center[ i ] = 127.0f; | 
|---|
| 327 | joy->min   [ i ] = 0.0f; | 
|---|
| 328 | } | 
|---|
| 329 |  | 
|---|
| 330 | joy->dead_band[ i ] = 0.0f; | 
|---|
| 331 | joy->saturate[ i ] = 1.0f; | 
|---|
| 332 | } | 
|---|
| 333 | #    endif | 
|---|
| 334 | #endif | 
|---|
| 335 |  | 
|---|
| 336 | #if defined( __linux__ ) || TARGET_HOST_SOLARIS | 
|---|
| 337 | /* Default for older Linux systems. */ | 
|---|
| 338 | joy->num_axes    =  2; | 
|---|
| 339 | joy->num_buttons = 32; | 
|---|
| 340 |  | 
|---|
| 341 | #    ifdef JS_NEW | 
|---|
| 342 | for( i = 0; i < _JS_MAX_AXES; i++ ) | 
|---|
| 343 | joy->pJoystick.tmp_axes[ i ] = 0.0f; | 
|---|
| 344 |  | 
|---|
| 345 | joy->pJoystick.tmp_buttons = 0; | 
|---|
| 346 | #    endif | 
|---|
| 347 |  | 
|---|
| 348 | joy->pJoystick.fd = open( joy->pJoystick.fname, O_RDONLY ); | 
|---|
| 349 |  | 
|---|
| 350 | joy->error =( joy->pJoystick.fd < 0 ); | 
|---|
| 351 |  | 
|---|
| 352 | if( joy->error ) | 
|---|
| 353 | return; | 
|---|
| 354 |  | 
|---|
| 355 | /* Set the correct number of axes for the linux driver */ | 
|---|
| 356 | #    ifdef JS_NEW | 
|---|
| 357 | /* Melchior Franz's fixes for big-endian Linuxes since writing | 
|---|
| 358 | *  to the upper byte of an uninitialized word doesn't work. | 
|---|
| 359 | *  9 April 2003 | 
|---|
| 360 | */ | 
|---|
| 361 | ioctl( joy->pJoystick.fd, JSIOCGAXES, &u ); | 
|---|
| 362 | joy->num_axes = u; | 
|---|
| 363 | ioctl( joy->pJoystick.fd, JSIOCGBUTTONS, &u ); | 
|---|
| 364 | joy->num_buttons = u; | 
|---|
| 365 | ioctl( joy->pJoystick.fd, JSIOCGNAME( sizeof( joy->name ) ), joy->name ); | 
|---|
| 366 | fcntl( joy->pJoystick.fd, F_SETFL, O_NONBLOCK ); | 
|---|
| 367 | #    endif | 
|---|
| 368 |  | 
|---|
| 369 | /* | 
|---|
| 370 | * The Linux driver seems to return 512 for all axes | 
|---|
| 371 | * when no stick is present - but there is a chance | 
|---|
| 372 | * that could happen by accident - so it's gotta happen | 
|---|
| 373 | * on both axes for at least 100 attempts. | 
|---|
| 374 | * | 
|---|
| 375 | * PWO: shouldn't be that done somehow wiser on the kernel level? | 
|---|
| 376 | */ | 
|---|
| 377 | #    ifndef JS_NEW | 
|---|
| 378 | counter = 0; | 
|---|
| 379 |  | 
|---|
| 380 | do | 
|---|
| 381 | { | 
|---|
| 382 | fghJoystickRawRead( joy, NULL, joy->center ); | 
|---|
| 383 | counter++; | 
|---|
| 384 | } while( !joy->error && | 
|---|
| 385 | counter < 100 && | 
|---|
| 386 | joy->center[ 0 ] == 512.0f && | 
|---|
| 387 | joy->center[ 1 ] == 512.0f ); | 
|---|
| 388 |  | 
|---|
| 389 | if ( counter >= 100 ) | 
|---|
| 390 | joy->error = GL_TRUE; | 
|---|
| 391 | #    endif | 
|---|
| 392 |  | 
|---|
| 393 | for( i = 0; i < _JS_MAX_AXES; i++ ) | 
|---|
| 394 | { | 
|---|
| 395 | #    ifdef JS_NEW | 
|---|
| 396 | joy->max   [ i ] =  32767.0f; | 
|---|
| 397 | joy->center[ i ] =      0.0f; | 
|---|
| 398 | joy->min   [ i ] = -32767.0f; | 
|---|
| 399 | #    else | 
|---|
| 400 | joy->max[ i ] = joy->center[ i ] * 2.0f; | 
|---|
| 401 | joy->min[ i ] = 0.0f; | 
|---|
| 402 | #    endif | 
|---|
| 403 | joy->dead_band[ i ] = 0.0f; | 
|---|
| 404 | joy->saturate [ i ] = 1.0f; | 
|---|
| 405 | } | 
|---|
| 406 | #endif | 
|---|
| 407 | } | 
|---|
| 408 |  | 
|---|
| 409 |  | 
|---|
| 410 | void fgPlatformJoystickInit( SFG_Joystick *fgJoystick[], int ident ) | 
|---|
| 411 | { | 
|---|
| 412 | #if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ ) | 
|---|
| 413 | fgJoystick[ ident ]->id = ident; | 
|---|
| 414 | fgJoystick[ ident ]->error = GL_FALSE; | 
|---|
| 415 |  | 
|---|
| 416 | fgJoystick[ ident ]->pJoystick.os = calloc( 1, sizeof( struct os_specific_s ) ); | 
|---|
| 417 | memset( fgJoystick[ ident ]->pJoystick.os, 0, sizeof( struct os_specific_s ) ); | 
|---|
| 418 | if( ident < USB_IDENT_OFFSET ) | 
|---|
| 419 | fgJoystick[ ident ]->pJoystick.os->is_analog = 1; | 
|---|
| 420 | if( fgJoystick[ ident ]->pJoystick.os->is_analog ) | 
|---|
| 421 | snprintf( fgJoystick[ ident ]->pJoystick.os->fname, sizeof(fgJoystick[ ident ]->pJoystick.os->fname), "%s%d", AJSDEV, ident ); | 
|---|
| 422 | else | 
|---|
| 423 | snprintf( fgJoystick[ ident ]->pJoystick.os->fname, sizeof(fgJoystick[ ident ]->pJoystick.os->fname), "%s%d", UHIDDEV, | 
|---|
| 424 | ident - USB_IDENT_OFFSET ); | 
|---|
| 425 | #elif defined( __linux__ ) | 
|---|
| 426 | fgJoystick[ ident ]->id = ident; | 
|---|
| 427 | fgJoystick[ ident ]->error = GL_FALSE; | 
|---|
| 428 |  | 
|---|
| 429 | snprintf( fgJoystick[ident]->pJoystick.fname, sizeof(fgJoystick[ident]->pJoystick.fname), "/dev/input/js%d", ident ); | 
|---|
| 430 |  | 
|---|
| 431 | if( access( fgJoystick[ ident ]->pJoystick.fname, F_OK ) != 0 ) | 
|---|
| 432 | snprintf( fgJoystick[ ident ]->pJoystick.fname, sizeof(fgJoystick[ ident ]->pJoystick.fname), "/dev/js%d", ident ); | 
|---|
| 433 | #endif | 
|---|
| 434 | } | 
|---|
| 435 |  | 
|---|
| 436 |  | 
|---|
| 437 | void fgPlatformJoystickClose ( int ident ) | 
|---|
| 438 | { | 
|---|
| 439 | #if defined( __FreeBSD__ ) || defined(__FreeBSD_kernel__) || defined( __NetBSD__ ) | 
|---|
| 440 | if( fgJoystick[ident]->pJoystick.os ) | 
|---|
| 441 | { | 
|---|
| 442 | if( ! fgJoystick[ ident ]->error ) | 
|---|
| 443 | close( fgJoystick[ ident ]->pJoystick.os->fd ); | 
|---|
| 444 | #ifdef HAVE_USB_JS | 
|---|
| 445 | if( fgJoystick[ ident ]->pJoystick.os->hids ) | 
|---|
| 446 | free (fgJoystick[ ident ]->pJoystick.os->hids); | 
|---|
| 447 | if( fgJoystick[ ident ]->pJoystick.os->hid_data_buf ) | 
|---|
| 448 | free( fgJoystick[ ident ]->pJoystick.os->hid_data_buf ); | 
|---|
| 449 | #endif | 
|---|
| 450 | free( fgJoystick[ident]->pJoystick.os ); | 
|---|
| 451 | } | 
|---|
| 452 | #endif | 
|---|
| 453 |  | 
|---|
| 454 | if( ! fgJoystick[ident]->error ) | 
|---|
| 455 | close( fgJoystick[ ident ]->pJoystick.fd ); | 
|---|
| 456 | } | 
|---|
| 457 |  | 
|---|
| 458 |  | 
|---|