2001-09-21 21:08:10 +00:00
/*
* Joystick input driver for LCDd
*
* Only two unique functions are defined:
*
* joy_getkey
* joy_close
*
* All others are at their defaults.
*
* The code here is configured for a Gravis Gamepad (2 axis, 4 button)
*
*/
1999-12-09 23:15:14 +00:00
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <string.h>
#include <sys/errno.h>
#include <sys/ioctl.h>
#include <sys/types.h>
2001-09-25 06:20:27 +00:00
#include <syslog.h>
1999-12-09 23:15:14 +00:00
#include <linux/joystick.h>
2001-09-21 21:08:10 +00:00
#ifndef JSIOCGNAME
#define JSIOCGNAME(len) _IOC(_IOC_READ, 'j', 0x13, len) /* get identifier string */
#endif
1999-12-09 23:15:14 +00:00
2001-05-25 03:14:27 +00:00
#include "shared/debug.h"
#include "shared/str.h"
1999-12-09 23:15:14 +00:00
#define NAME_LENGTH 128
2001-09-25 06:20:27 +00:00
#define JOY_DEFAULT_DEVICE "/dev/js0"
1999-12-09 23:15:14 +00:00
#include "lcd.h"
#include "joy.h"
lcd_logical_driver * joy ;
int fd ;
2001-09-25 06:20:27 +00:00
extern int debug_level ;
1999-12-09 23:15:14 +00:00
struct js_event js ;
char axes = 2 ;
char buttons = 2 ;
int jsversion = 0x000800 ;
char jsname [ NAME_LENGTH ] = "Unknown" ;
int * axis ;
int * button ;
// Configured for a Gravis Gamepad (2 axis, 4 button)
2000-03-30 20:20:41 +00:00
char * axismap = "EFGHIJKLMNOPQRST" ;
1999-12-09 23:15:14 +00:00
char * buttonmap = "BDACEFGHIJKLMNOP" ;
////////////////////////////////////////////////////////////
// init() should set up any device-specific stuff, and
// point all the function pointers.
2000-03-30 20:20:41 +00:00
int
joy_init ( struct lcd_logical_driver * driver , char * args )
1999-12-09 23:15:14 +00:00
{
2000-04-03 22:13:57 +00:00
char device [ 256 ];
char * argv [ 64 ];
2001-05-15 01:55:59 +00:00
int argc , i ;
2000-03-30 20:20:41 +00:00
2000-04-03 22:13:57 +00:00
joy = driver ;
1999-12-09 23:15:14 +00:00
2001-09-25 06:20:27 +00:00
strcpy ( device , JOY_DEFAULT_DEVICE );
1999-12-09 23:15:14 +00:00
2000-04-03 22:13:57 +00:00
argc = get_args ( argv , args , 64 );
2000-03-30 20:20:41 +00:00
2000-04-03 22:13:57 +00:00
for ( i = 0 ; i < argc ; i ++ ) {
//printf("Arg(%i): %s\n", i, argv[i]);
if ( 0 == strcmp ( argv [ i ], "-d" ) || 0 == strcmp ( argv [ i ], "--device" )) {
if ( i + 1 > argc ) {
fprintf ( stderr , "joy_init: %s requires an argument \n " , argv [ i ]);
return - 1 ;
}
strcpy ( device , argv [ ++ i ]);
} else if ( 0 == strcmp ( argv [ i ], "-a" ) || 0 == strcmp ( argv [ i ], "--axes" )) {
if ( i + 1 > argc ) {
fprintf ( stderr , "joy_init: %s requires an argument \n " , argv [ i ]);
return - 1 ;
}
strncpy ( axismap , argv [ ++ i ], 16 );
} else if ( 0 == strcmp ( argv [ i ], "-b" ) || 0 == strcmp ( argv [ i ], "--buttons" )) {
if ( i + 1 > argc ) {
fprintf ( stderr , "joy_init: %s requires an argument \n " , argv [ i ]);
return - 1 ;
}
strncpy ( buttonmap , argv [ ++ i ], 16 );
} else if ( 0 == strcmp ( argv [ i ], "-h" ) || 0 == strcmp ( argv [ i ], "--help" )) {
printf ( "LCDproc Joystick input driver \n " " \t -d \t --device \t Select the input device to use [/dev/js0] \n " " \t -a \t --axes \t\t Modify the axis map [%s] \n " " \t -b \t --buttons \t Modify the button map [%s] \n " " \t -h \t --help \t\t Show this help information \n " , axismap , buttonmap );
return - 1 ;
} else {
printf ( "Invalid parameter: %s \n " , argv [ i ]);
}
2000-03-30 20:20:41 +00:00
2000-04-03 22:13:57 +00:00
}
2000-03-30 20:20:41 +00:00
2000-04-03 22:13:57 +00:00
driver -> getkey = joy_getkey ;
driver -> close = joy_close ;
1999-12-09 23:15:14 +00:00
2001-09-25 06:20:27 +00:00
if (( fd = open ( device , O_RDONLY )) < 0 )
2000-04-03 22:13:57 +00:00
return - 1 ;
1999-12-09 23:15:14 +00:00
2001-09-25 06:20:27 +00:00
fcntl ( fd , F_SETFL , O_NONBLOCK );
2000-04-03 22:13:57 +00:00
ioctl ( fd , JSIOCGVERSION , & jsversion );
ioctl ( fd , JSIOCGAXES , & axes );
ioctl ( fd , JSIOCGBUTTONS , & buttons );
ioctl ( fd , JSIOCGNAME ( NAME_LENGTH ), jsname );
2000-03-30 20:20:41 +00:00
2001-09-25 06:20:27 +00:00
if ( debug_level > 2 ) {
syslog ( LOG_DEBUG , "Joystick (%s) has %d axes and %d buttons. Driver version is %d.%d.%d. \n " ,
jsname , axes , buttons ,
jsversion >> 16 , ( jsversion >> 8 ) & 0xff , jsversion & 0xff );
}
2000-03-30 20:20:41 +00:00
2001-09-25 06:20:27 +00:00
if (( axis = calloc ( axes , sizeof ( int ))) == NULL ) {
syslog ( LOG_ERR , "joystick: could not allocate memory for axes" );
return - 1 ;
}
if (( button = calloc ( buttons , sizeof ( char ))) == NULL ) {
syslog ( LOG_ERR , "joystick: could not allocate memory for buttons" );
return - 1 ;
}
2000-03-30 20:20:41 +00:00
2000-04-03 22:13:57 +00:00
return fd ; // 200 is arbitrary. (must be 1 or more)
1999-12-09 23:15:14 +00:00
}
2000-03-30 20:20:41 +00:00
void
joy_close ()
1999-12-09 23:15:14 +00:00
{
2000-04-03 22:13:57 +00:00
if ( joy -> framebuf != NULL )
free ( joy -> framebuf );
2001-09-25 06:20:27 +00:00
2000-04-03 22:13:57 +00:00
close ( fd );
2000-03-30 20:20:41 +00:00
2000-04-03 22:13:57 +00:00
joy -> framebuf = NULL ;
2000-03-30 20:20:41 +00:00
2000-04-03 22:13:57 +00:00
// Why do I have so much trouble getting memory freed without segfaults??
2001-09-25 06:20:27 +00:00
// Use gdb and find out :) In preliminary testing, this seemed to work...
if ( axis ) free ( axis );
if ( button ) free ( button );
1999-12-09 23:15:14 +00:00
}
//////////////////////////////////////////////////////////////////////
// Tries to read a character from an input device...
//
// Return 0 for "nothing available".
//
2000-03-30 20:20:41 +00:00
char
joy_getkey ()
1999-12-09 23:15:14 +00:00
{
2000-04-03 22:13:57 +00:00
int i ;
int err ;
2000-03-30 20:20:41 +00:00
2001-09-25 06:20:27 +00:00
if (( err = read ( fd , & js , sizeof ( struct js_event ))) <= 0 ) {
2000-04-03 22:13:57 +00:00
return 0 ;
2001-09-25 06:20:27 +00:00
} else
if ( err != sizeof ( struct js_event )) {
syslog ( LOG_ERR , "error reading joystick input" );
return 0 ;
}
1999-12-09 23:15:14 +00:00
// if(js.type & JS_EVENT_INIT) return 0;
2000-03-30 20:20:41 +00:00
2000-04-03 22:13:57 +00:00
switch ( js . type & ~ JS_EVENT_INIT ) {
2001-09-25 06:20:27 +00:00
case JS_EVENT_BUTTON :
button [ js . number ] = js . value ;
break ;
case JS_EVENT_AXIS :
axis [ js . number ] = js . value ;
break ;
2000-04-03 22:13:57 +00:00
}
1999-12-09 23:15:14 +00:00
2000-04-03 22:13:57 +00:00
if ( buttons ) {
//printf("Buttons: ");
for ( i = 0 ; i < buttons ; i ++ )
//printf("%2d:%s ", i, button[i] ? "on " : "off");
if ( button [ i ])
return buttonmap [ i ];
}
1999-12-09 23:15:14 +00:00
2000-04-03 22:13:57 +00:00
if ( axes ) {
//printf("Axes: ");
for ( i = 0 ; i < axes ; i ++ ) {
//printf("%2d:%6d ", i, axis[i]);
// Eliminate noise...
if ( axis [ i ] > 20000 )
return axismap [( 2 * i ) + 1 ];
if ( axis [ i ] < - 20000 )
return axismap [( 2 * i )];
}
}
2000-03-30 20:20:41 +00:00
2000-04-03 22:13:57 +00:00
return 0 ;
1999-12-09 23:15:14 +00:00
}