LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 10-06-2006, 05:47 PM   #1
samel_tvom
Member
 
Registered: Aug 2004
Posts: 133

Rep: Reputation: 15
use SDL to read joystick/gamepad input


Hi!

I have written a really ugly program in C that reads input from my gamepad and then generates xevents, or sends keycodes, whatever you wanna call it, using the Xtest library (#include <X11/extensions/XTest.h>). So that for example, when you press the X-button on the gamepad, I make X generate a "press return key event".

I read byte by byte from /dev/input/js0 and I figured that maybe all gamepads and joysticks haven't got the same output, so I wanted to use something generic to read joystick/gamepad input. Something like SDL maybe.

But I can't get SDL to read input when the SDL app window is passive. I rather not use a gui at all since I only want to launch a daemon that listens for gamepad inputs and then makes xevents.

Any idea how to do this? Any other lib to use?

And yes, I have heard of qjoypad. http://qjoypad.sourceforge.net/

Thanks!
 
Old 10-07-2006, 11:17 AM   #2
tuxdev
Senior Member
 
Registered: Jul 2005
Distribution: Slackware
Posts: 2,012

Rep: Reputation: 115Reputation: 115
Where's the code? Can't say why it is doing whatever it is doing without looking at the code. Make sure you wrap them in [code] tags to preserve indentation.
 
Old 10-07-2006, 03:33 PM   #3
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 78
Quote:
Originally Posted by samel_tvom
Hi!

I have written a really ugly program in C that reads input from my gamepad and then generates xevents, or sends keycodes, whatever you wanna call it, using the Xtest library (#include <X11/extensions/XTest.h>). So that for example, when you press the X-button on the gamepad, I make X generate a "press return key event".

I read byte by byte from /dev/input/js0 and I figured that maybe all gamepads and joysticks haven't got the same output, so I wanted to use something generic to read joystick/gamepad input. Something like SDL maybe.

But I can't get SDL to read input when the SDL app window is passive. I rather not use a gui at all since I only want to launch a daemon that listens for gamepad inputs and then makes xevents.
If you are going to use linux, the /dev/input/jsX interfaces all generate the same sort of output, regardless of manufacturer (IIRC, joydev is the driver responsible for this). Why are you reading one byte at a time? You should read more bytes (maybe 8?). Whatever the number, it's probably better to use sizeof(whatever_the_js_event_struct_is_called) instead. It's been awhile, but I think upon the opening of the device, joydev spits out some stuff (i.e., fake events with special meaning) that's supposed to tell you about the number of buttons/axes/etc. on this specific joypad. There are also some IOCTL's to figure this out.

You can use the linux joydev API directly instead of trying to find a library with its own joystick API (unless, of course, you want some sort of cross-platform portability). Documentation should be in the linux source tree.
 
Old 10-07-2006, 05:02 PM   #4
samel_tvom
Member
 
Registered: Aug 2004
Posts: 133

Original Poster
Rep: Reputation: 15
Yeah, I found out later on that using the js_event is probably the way to go. However, I can't seem to compile the program. Maybe you guys could help me.

Code:
#include <stdio.h>
#include <stdlib.h>
#include <linux/joystick.h>

int main() {
	int len;
	js_event msg;
	char* device = "/dev/input/js0";
	FILE *f = fopen(device, "rb+");
	
	while(1) {
		read(f, &msg, sizeof(js_event));
		if (len == (int) sizeof(js_event)) {
			printf("wii\n");
		}
	}
	
	return 0;

}
I try to compile with "gcc test.c" but I get
‘js_event’ undeclared (first use in this function)
and I can't figure out what lib the #include <linux/joystick.h> whould be in.
What args should I have to gcc?

Thanks!
 
Old 10-07-2006, 05:09 PM   #5
samel_tvom
Member
 
Registered: Aug 2004
Posts: 133

Original Poster
Rep: Reputation: 15
Hehe, I might add that the program I just posted is just a test program to get the reading from the joystick work =)

Now that I found out that using linux/joystick.h my old program (shitty and all) is useless, but I'll post it anyways.

There's some code from qjoypad, it's GPL'ed

Code:
// gcc gamepad.c -lXtst

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

#include <X11/extensions/XTest.h>
#include <X11/Xlib.h>

// so that we get the definintions of keys in keysymdef.h
#define XK_LATIN1
#define XK_MISCELLANY

#include <X11/keysymdef.h>


typedef struct xevent xevent;

struct xevent {
        int type;
        unsigned int value1;     //button, keycode, or x
        unsigned int value2; //y
};


void sendevent(xevent e, Display *display) {
	if (e.value1 == 0 && e.value2 == 0) return;
	if (e.type == 4) {
		XTestFakeRelativeMotionEvent(display, e.value1, e.value2, 0);
	}
	else {
		if (e.type == 0 || e.type == 1) {
			XTestFakeKeyEvent(display, e.value1, (e.type == 1), 0);
		}
		else if (e.type == 2 | e.type == 3) {
			XTestFakeButtonEvent(display, e.value1, (e.type == 3), 0);
		}
	}
	XFlush(display);
}




int main() {
	unsigned char down_down[] = {255, 127, 2, 1};
	unsigned char down_up[] = {0, 0, 2, 1};
	unsigned char up_down[] = {1, 128, 2, 1};
	unsigned char up_up[] = {0, 0, 2, 1};

	unsigned char left_down[] = {1, 128, 2, 0};
	unsigned char left_up[] = {0, 0, 2, 0};
	unsigned char right_down[] = {255, 127, 2, 0};
	unsigned char right_up[] = {0, 0, 2, 0};
	
	unsigned char anybutton_down[] = {1, 0, 1, 1};

	Display *display;
	display = XOpenDisplay(":0.0");	
	xevent e;

	char* device = "/dev/input/js0";
	unsigned char packet[8];
	unsigned char key[4];	

	FILE *f = fopen(device, "wb+");

	// read away stuff at the begining
	void *tmp = malloc(8*12*sizeof(char));
	fread(tmp, sizeof(char)*8*12, 1, f);
	free(tmp);
	
	while(1) {
		fread(&packet, sizeof(char)*8, 1, f);
		key[0] = packet[4];
		key[1] = packet[5];
		key[2] = packet[6];
		key[3] = packet[7];
		
		if(strncasecmp(key, up_down, 4) == 0) {
			e.type = 1;
			e.value1 = XKeysymToKeycode(display, XK_Up);
			sendevent(e, display);
			e.type = 0;
			sendevent(e, display);
			
		}
			
		if(strncasecmp(key, down_down, 4) == 0) {
			e.type = 1;
			e.value1 = XKeysymToKeycode(display, XK_Down);
			sendevent(e, display);
			e.type = 0;
			sendevent(e, display);
		}
		if(strncasecmp(key, left_down, 4) == 0) {
			e.type = 1;
			e.value1 = XKeysymToKeycode(display, XK_Left);
			sendevent(e, display);
			e.type = 0;
			sendevent(e, display);

		}
		if(strncasecmp(key, right_down, 4) == 0) {
			e.type = 1;
			e.value1 = XKeysymToKeycode(display, XK_Right);
			sendevent(e, display);
			e.type = 0;
			sendevent(e, display);
		}
		if(strncasecmp(key, anybutton_down, 4) == 0) {
			e.type = 1;
			e.value1 = XKeysymToKeycode(display, XK_Return);
			sendevent(e, display);
			e.type = 0;
			sendevent(e, display);
		}
			
		usleep(1000);
	}
	
	return 0;

}
 
Old 10-07-2006, 05:16 PM   #6
samel_tvom
Member
 
Registered: Aug 2004
Posts: 133

Original Poster
Rep: Reputation: 15
Hmm, I should think before I post, anyways. Since qjoypad is written in c++ maybe I should use
Code:
struct js_event msg;
However, adding the "struct" did no difference.
 
Old 10-07-2006, 10:02 PM   #7
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 78
Quote:
Originally Posted by samel_tvom
Hmm, I should think before I post, anyways. Since qjoypad is written in c++ maybe I should use
Code:
struct js_event msg;
However, adding the "struct" did no difference.
The struct is not typedef'd, so you need to add struct everytime you use it (i.e., wherever it says js_event, change it to struct js_event).

Also, currently, you don't do anything to len, rendering your program useless.

You could change
Code:
read(f, &msg, sizeof(struct js_event));
	if (len == (int) sizeof(struct js_event)) {
to
Code:
len = read(f, &msg, sizeof(struct js_event));
	if (len == (int) sizeof(struct js_event)) {
or even
Code:
if ( (len = read(f, &msg, sizeof(struct js_event))) == (int) sizeof struct js_event) {
Someone needs to brush up on their C.
 
Old 10-09-2006, 03:11 PM   #8
samel_tvom
Member
 
Registered: Aug 2004
Posts: 133

Original Poster
Rep: Reputation: 15
Yepp, that's totally true =)

Thanks for the info, really appreciate it!
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Useing Joystick/gamepad as mouse pointer zarathustra674 Linux - Hardware 6 09-15-2011 02:13 PM
gamepad/joystick/joypad as inputd evice in xorg samel_tvom Linux - Hardware 0 09-28-2006 02:44 PM
Gamepad/Joystick as Mouse nirj Linux - Hardware 1 03-26-2005 11:38 AM
Joystick/Gamepad help. ProtoformX Linux - Hardware 3 11-17-2004 11:24 AM
how do i get my joystick, gamepad, & wheel working? LavaDevil94 Linux - Hardware 4 10-07-2003 03:23 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 08:35 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration