/* Function to scan the system for joysticks */
int STJoystick::Sys_Initialize()
{
	/* The base path of the joystick devices */
	const char *joydev_pattern[] = {
#if SDL_INPUT_LINUXEV
		"/dev/input/event%d",
#endif
		"/dev/input/js%d",
		"/dev/js%d",
		NULL
	};
	int numjoysticks;
	int i, j;
	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));
		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].fname = strdup(path);
				if ( SDL_joylist[numjoysticks].fname ) {
					dev_nums[numjoysticks] = sb.st_rdev;
					++numjoysticks;
				}
				close(fd);
			}
		}
	}

	for ( i=0; joydev_pattern[i]; ++i ) {
		for ( j=0; j < MAX_JOYSTICKS; ++j ) {
			snprintf(path, sizeof(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;
				}
#if SDL_INPUT_LINUXEV
#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].fname = strdup(path);
				if ( SDL_joylist[numjoysticks].fname ) {
					dev_nums[numjoysticks] = sb.st_rdev;
					++numjoysticks;
				}
			} else
				break;
		}

#if SDL_INPUT_LINUXEV
		/* This is a special case...
		   If the event devices are valid then the joystick devices
		   will be duplicates but without extra information about their
		   hats or balls. Unfortunately, the event devices can't
		   currently be calibrated, so it's a win-lose situation.
		   So : /dev/input/eventX = /dev/input/jsY = /dev/jsY
		*/
		if ( (i == 0) && (numjoysticks > 0) )
			break;
#endif
	}
#ifndef NO_LOGICAL_JOYSTICKS
	numjoysticks += CountLogicalJoysticks(numjoysticks);
#endif

	return(numjoysticks);
}
示例#2
0
文件: pad.c 项目: DAOWAce/pcsxr
static void linux_set_vibrate(int pad)
{
	int jno = 0, devno, dev;
	const char *sdlj;
	int tjno = g.cfg.PadDef[pad].DevNum;

	g.PadState[pad].VibrateDev = -2;
	/* simulate SDL device opening; probably not very accurate */
	/* works for me, though */
	sdlj = getenv("SDL_JOYSTICK_DEVICE");
	if(sdlj) {
		dev = open(sdlj, O_RDONLY);
		if(dev >= 0) {
			if(!tjno) {
				close(dev);
				dev = open(sdlj, O_RDWR);
				if(dev < 0) {
					printf("%s has no permission to rumble\n", sdlj);
					return;
				}
				if(EV_IsJoystick(dev) != 2) {
					printf("%s has no rumble\n", sdlj);
					close(dev);
					return;
				}
				g.PadState[pad].VibrateDev = dev;
				return;
			}
			close(dev);
			jno++;
		} else
			perror(sdlj);
	}
	for(devno = 0; devno < 32; devno++) {
		char buf[20];

		sprintf(buf, "/dev/input/event%d", devno);
		dev = open(buf, O_RDONLY);
		if(dev >= 0) {
			int isj = EV_IsJoystick(dev);
			if(isj) {
				if(tjno == jno) {
					close(dev);
					if(isj != 2) {
						printf("%s has no rumble\n", buf);
						return;
					}
					dev = open(buf, O_RDWR);
					if(dev < 0) {
						printf("%s has no permission to rumble\n", buf);
						return;
					}
					g.PadState[pad].VibrateDev = dev;
					return;
				}
				jno++;
			}
			close(dev);
		}
	}
}