⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdl_sysjoystick.c

📁 网络MPEG4IP流媒体开发源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    SDL - Simple DirectMedia Layer    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga    This library is free software; you can redistribute it and/or    modify it under the terms of the GNU Library General Public    License as published by the Free Software Foundation; either    version 2 of the License, or (at your option) any later version.    This library is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    Library General Public License for more details.    You should have received a copy of the GNU Library General Public    License along with this library; if not, write to the Free    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA    Sam Lantinga    slouken@libsdl.org*/#ifdef SAVE_RCSIDstatic char rcsid = "@(#) $Id$";#endif/* This is the system specific header for the SDL joystick API */#include <stdio.h>		/* For the definition of NULL */#include <stdlib.h>		/* For getenv() prototype */#include <string.h>#include <sys/stat.h>#include <unistd.h>#include <fcntl.h>#include <sys/ioctl.h>#include <limits.h>		/* For the definition of PATH_MAX */#ifdef __arm__#include <linux/limits.h> /* Arm cross-compiler needs this */#endif#include <linux/joystick.h>#ifdef USE_INPUT_EVENTS#include <linux/input.h>#endif#include "SDL_error.h"#include "SDL_joystick.h"#include "SDL_sysjoystick.h"#include "SDL_joystick_c.h"/* Define this if you want to map axes to hats and trackballs */#define FANCY_HATS_AND_BALLS#ifdef FANCY_HATS_AND_BALLS/* Special joystick configurations:	'JoystickName' Naxes Nhats Nballs */static const char *special_joysticks[] = {	"'MadCatz Panther XL' 3 2 1", /* We don't handle a rudder (axis 8) */	"'SideWinder Precision Pro' 4 1 0",	"'SideWinder 3D Pro' 4 1 0",	"'Microsoft SideWinder 3D Pro' 4 1 0",	"'Microsoft SideWinder Dual Strike USB version 1.0' 2 1 0",	"'WingMan Interceptor' 3 3 0",	/* WingMan Extreme Analog - not recognized by default	"'Analog 3-axis 4-button joystick' 2 1 0",	*/	"'WingMan Extreme Digital 3D' 4 1 0",	"'Analog 2-axis 4-button 1-hat FCS joystick' 2 1 0",	"'Microsoft SideWinder Precision 2 Joystick' 4 1 0",	"'Logitech Inc. WingMan Extreme Digital 3D' 4 1 0",	"'Saitek Saitek X45' 6 1 0",	NULL};#else#undef USE_INPUT_EVENTS#endif/* The maximum number of joysticks we'll detect */#define MAX_JOYSTICKS	32/* A list of available joysticks */static char *SDL_joylist[MAX_JOYSTICKS];/* The private structure used to keep track of a joystick */struct joystick_hwdata {	int fd;	/* The current linux joystick driver maps hats to two axes */	int analog_hat;		/* Well, except for analog hats */	struct hwdata_hat {		int axis[2];	} *hats;	/* The current linux joystick driver maps balls to two axes */	struct hwdata_ball {		int axis[2];	} *balls;	/* Support for the Linux 2.4 unified input interface */	SDL_bool is_hid;#ifdef USE_INPUT_EVENTS	Uint8 key_map[KEY_MAX-BTN_MISC];	Uint8 abs_map[ABS_MAX];	struct axis_correct {		int used;		int coef[3];	} abs_correct[ABS_MAX];#endif};static char *mystrdup(const char *string){	char *newstring;	newstring = (char *)malloc(strlen(string)+1);	if ( newstring ) {		strcpy(newstring, string);	}	return(newstring);}#ifdef USE_INPUT_EVENTS#define test_bit(nr, addr) \	(((1UL << ((nr) & 31)) & (((const unsigned int *) addr)[(nr) >> 5])) != 0)static int EV_IsJoystick(int fd){	unsigned long evbit[40];	unsigned long keybit[40];	unsigned long absbit[40];	if ( (ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), evbit) < 0) ||	     (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) < 0) ||	     (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) < 0) ) {		return(0);	}	if (!(test_bit(EV_KEY, evbit) && test_bit(EV_ABS, evbit) &&	      test_bit(ABS_X, absbit) && test_bit(ABS_Y, absbit) &&	     (test_bit(BTN_TRIGGER, keybit) || test_bit(BTN_A, keybit) || test_bit(BTN_1, keybit)))) return 0;	return(1);}#endif /* USE_INPUT_EVENTS *//* Function to scan the system for joysticks */int SDL_SYS_JoystickInit(void){	/* The base path of the joystick devices */	const char *joydev_pattern[] = {		"/dev/js%d",#ifdef USE_INPUT_EVENTS		"/dev/input/event%d",#endif		"/dev/input/js%d"	};	int numjoysticks;	int i, j, done;	int fd;	char path[PATH_MAX];	dev_t dev_nums[MAX_JOYSTICKS];  /* major/minor device numbers */	struct stat sb;	int n, duplicate;	numjoysticks = 0;	/* First see if the user specified a joystick to use */	if ( getenv("SDL_JOYSTICK_DEVICE") != NULL ) {		strncpy(path, getenv("SDL_JOYSTICK_DEVICE"), sizeof(path));		path[sizeof(path)-1] = '\0';		if ( stat(path, &sb) == 0 ) {			fd = open(path, O_RDONLY, 0);			if ( fd >= 0 ) {				/* Assume the user knows what they're doing. */				SDL_joylist[numjoysticks] = mystrdup(path);				if ( SDL_joylist[numjoysticks] ) {					dev_nums[numjoysticks] = sb.st_rdev;					++numjoysticks;				}				close(fd);			}		}	}	for ( i=0; i<SDL_TABLESIZE(joydev_pattern); ++i ) {		done = 0;		for ( j=0; (j < MAX_JOYSTICKS) && !done; ++j ) {			sprintf(path, joydev_pattern[i], j);			/* rcg06302000 replaced access(F_OK) call with stat().			 * stat() will fail if the file doesn't exist, so it's			 * equivalent behaviour.			 */			if ( stat(path, &sb) == 0 ) {				/* Check to make sure it's not already in list.				 * This happens when we see a stick via symlink.				 */				duplicate = 0;				for (n=0; (n<numjoysticks) && !duplicate; ++n) {					if ( sb.st_rdev == dev_nums[n] ) {						duplicate = 1;					}				}				if (duplicate) {					continue;				}				fd = open(path, O_RDONLY, 0);				if ( fd < 0 ) {					continue;				}#ifdef USE_INPUT_EVENTS#ifdef DEBUG_INPUT_EVENTS				printf("Checking %s\n", path);#endif				if ( (i > 0) && ! EV_IsJoystick(fd) ) {					close(fd);					continue;				}#endif				close(fd);				/* We're fine, add this joystick */				SDL_joylist[numjoysticks] = mystrdup(path);				if ( SDL_joylist[numjoysticks] ) {					dev_nums[numjoysticks] = sb.st_rdev;					++numjoysticks;				}			} else {				done = 1;			}		}        /* This is a special case...           If we're looking at the /dev/input event devices, and we found           at least one, then we don't want to look at the input joystick           devices, since they're built on top of devices that we've already           seen, so we're done.         */        if ( i > 0 && j > 0 ) {            done = 1;        }	}	return(numjoysticks);}/* Function to get the device-dependent name of a joystick */const char *SDL_SYS_JoystickName(int index){	int fd;	static char namebuf[128];	char *name;	name = NULL;	fd = open(SDL_joylist[index], O_RDONLY, 0);	if ( fd >= 0 ) {		if ( #ifdef USE_INPUT_EVENTS		     (ioctl(fd, EVIOCGNAME(sizeof(namebuf)), namebuf) <= 0) &&#endif		     (ioctl(fd, JSIOCGNAME(sizeof(namebuf)), namebuf) <= 0) ) {			name = SDL_joylist[index];		} else {			name = namebuf;		}		close(fd);	}	return name;}#ifdef FANCY_HATS_AND_BALLSstatic int allocate_hatdata(SDL_Joystick *joystick){	int i;	joystick->hwdata->hats = (struct hwdata_hat *)malloc(		joystick->nhats * sizeof(struct hwdata_hat));	if ( joystick->hwdata->hats == NULL ) {		return(-1);	}	for ( i=0; i<joystick->nhats; ++i ) {		joystick->hwdata->hats[i].axis[0] = 1;		joystick->hwdata->hats[i].axis[1] = 1;	}	return(0);}static int allocate_balldata(SDL_Joystick *joystick){	int i;	joystick->hwdata->balls = (struct hwdata_ball *)malloc(		joystick->nballs * sizeof(struct hwdata_ball));	if ( joystick->hwdata->balls == NULL ) {		return(-1);	}	for ( i=0; i<joystick->nballs; ++i ) {		joystick->hwdata->balls[i].axis[0] = 0;		joystick->hwdata->balls[i].axis[1] = 0;	}	return(0);}static SDL_bool ConfigJoystick(SDL_Joystick *joystick,			const char *name, const char *config){	char cfg_name[128];	SDL_bool handled;	if ( config == NULL ) {		return(SDL_FALSE);	}	strcpy(cfg_name, "");	if ( *config == '\'' ) {		sscanf(config, "'%[^']s'", cfg_name);		config += strlen(cfg_name)+2;	} else {		sscanf(config, "%s", cfg_name);		config += strlen(cfg_name);	}	handled = SDL_FALSE;	if ( strcmp(cfg_name, name) == 0 ) {		/* Get the number of axes, hats and balls for this joystick */		int joystick_axes = joystick->naxes;		sscanf(config, "%d %d %d", 			&joystick->naxes, &joystick->nhats, &joystick->nballs);		/* Allocate the extra data for mapping them */		if ( joystick->nhats > 0 ) {			/* HACK: Analog hats map to only one axis */			if (joystick_axes == (joystick->naxes+joystick->nhats)){				joystick->hwdata->analog_hat = 1;			} else {				if ( allocate_hatdata(joystick) < 0 ) {					joystick->nhats = 0;				}				joystick->hwdata->analog_hat = 0;			}		}		if ( joystick->nballs > 0 ) {			if ( allocate_balldata(joystick) < 0 ) {				joystick->nballs = 0;			}		}		handled = SDL_TRUE;	}	return(handled);}#ifdef USE_INPUT_EVENTSstatic SDL_bool EV_ConfigJoystick(SDL_Joystick *joystick, int fd){	int i;	unsigned long keybit[40];	unsigned long absbit[40];	unsigned long relbit[40];	/* See if this device uses the new unified event API */	if ( (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) >= 0) &&	     (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) >= 0) &&	     (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relbit)), relbit) >= 0) ) {		joystick->hwdata->is_hid = SDL_TRUE;		/* Get the number of buttons, axes, and other thingamajigs */		for ( i=BTN_JOYSTICK; i < KEY_MAX; ++i ) {			if ( test_bit(i, keybit) ) {#ifdef DEBUG_INPUT_EVENTS				printf("Joystick has button: 0x%x\n", i);#endif				joystick->hwdata->key_map[i-BTN_MISC] =						joystick->nbuttons;				++joystick->nbuttons;			}		}		for ( i=BTN_MISC; i < BTN_JOYSTICK; ++i ) {			if ( test_bit(i, keybit) ) {#ifdef DEBUG_INPUT_EVENTS				printf("Joystick has button: 0x%x\n", i);#endif				joystick->hwdata->key_map[i-BTN_MISC] =						joystick->nbuttons;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -