Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/freeglut/src/x11/fg_joystick_x11.c @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 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 |
