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>
#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-12-30 00:15:25 +00:00
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "lcd.h"
#include "joy.h"
#include "report.h"
2001-05-25 03:14:27 +00:00
#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
int fd ;
struct js_event js ;
char axes = 2 ;
char buttons = 2 ;
int jsversion = 0x000800 ;
char jsname [ NAME_LENGTH ] = "Unknown" ;
2001-12-30 00:15:25 +00:00
int * axis = NULL ;
int * button = NULL ;
1999-12-09 23:15:14 +00:00
// 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" ;
2001-12-30 00:15:25 +00:00
// Vars for the server core
MODULE_EXPORT char * api_version = API_VERSION ;
MODULE_EXPORT int stay_in_foreground = 0 ;
MODULE_EXPORT int supports_multiple = 0 ;
MODULE_EXPORT char * symbol_prefix = "joy_" ;
1999-12-09 23:15:14 +00:00
////////////////////////////////////////////////////////////
// init() should set up any device-specific stuff, and
// point all the function pointers.
2002-02-21 22:50:12 +00:00
MODULE_EXPORT int
2001-12-30 00:15:25 +00:00
joy_init ( Driver * drvthis , 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
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
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-12-30 00:15:25 +00:00
report ( RPT_NOTICE , "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 ) {
2001-12-30 00:15:25 +00:00
report ( RPT_ERR , "joystick: could not allocate memory for axes" );
2001-09-25 06:20:27 +00:00
return - 1 ;
}
if (( button = calloc ( buttons , sizeof ( char ))) == NULL ) {
2001-12-30 00:15:25 +00:00
report ( RPT_ERR , "joystick: could not allocate memory for buttons" );
2001-09-25 06:20:27 +00:00
return - 1 ;
}
2000-03-30 20:20:41 +00:00
2001-12-30 00:15:25 +00:00
return 0 ;
1999-12-09 23:15:14 +00:00
}
2001-12-30 00:15:25 +00:00
MODULE_EXPORT void
joy_close ( Driver * drvthis )
1999-12-09 23:15:14 +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
// 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...
2001-12-30 00:15:25 +00:00
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".
//
2001-12-30 00:15:25 +00:00
MODULE_EXPORT char
joy_getkey ( Driver * drvthis )
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 )) {
2001-12-30 00:15:25 +00:00
report ( RPT_ERR , "error reading joystick input" );
2001-09-25 06:20:27 +00:00
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
}