--- ./src/arch/InputHandler/InputHandler_Linux_Joystick.cpp~	2008-01-05 02:32:14.000000000 +0100
+++ ./src/arch/InputHandler/InputHandler_Linux_Joystick.cpp	2008-01-05 03:13:56.000000000 +0100
@@ -9,20 +9,12 @@
 
 #include <errno.h>
 #include <sys/types.h>
-#include <linux/joystick.h>
+#include <linux/input.h>
 
 #include <set>
 
 REGISTER_INPUT_HANDLER_CLASS2( Joystick, Linux_Joystick );
 
-static const char *Paths[InputHandler_Linux_Joystick::NUM_JOYSTICKS] =
-{
-	"/dev/js0",
-	"/dev/js1",
-	"/dev/input/js0",
-	"/dev/input/js1",
-};
-
 InputHandler_Linux_Joystick::InputHandler_Linux_Joystick()
 {
 	LOG->Trace( "InputHandler_Linux_Joystick::InputHandler_Linux_Joystick" );
@@ -30,48 +22,75 @@
 	for(int i = 0; i < NUM_JOYSTICKS; ++i)
 		fds[i] = -1;
 
-	/* We check both eg. /dev/js0 and /dev/input/js0.  If both exist, they're probably
-	 * the same device; keep track of device IDs so we don't open the same joystick
-	 * twice. */
-	set< pair<int,int> > devices;
+	FILE *f = fopen("/proc/bus/input/devices", "r");
+	if (!f) {
+		LOG->Warn("Cannot open /proc/bus/input/devices: %s", strerror(errno));
+		return;
+	}
+
+	char line[255];
+	int i = 0;
 	bool bFoundAnyJoysticks = false;
-	
-	for(int i = 0; i < NUM_JOYSTICKS; ++i)
-	{
-		struct stat st;
-		if( stat( Paths[i], &st ) == -1 )
-		{
-			if( errno != ENOENT )
-				LOG->Warn( "Couldn't stat %s: %s", Paths[i], strerror(errno) );
+
+	/* We will scan /proc/bus/input/devices and find input
+	 * event devices for all the available joysticks. The
+	 * way we do it is admittely somewhat dirty. */
+	while (fgets(line, 255, f)) {
+		// Look just at the H: handler lines
+		if (line[0] != 'H')
 			continue;
-		}
 
-		if( !S_ISCHR( st.st_mode ) )
-		{
-			LOG->Warn( "Ignoring %s: not a character device", Paths[i] );
+		// The line looks like:
+		// 	H: Handlers=js0 event3
+
+		char *hlist = strchr(line, '=');
+		if (!hlist)
 			continue;
-		}
+		hlist++;
 
-		pair<int,int> dev( major(st.st_rdev), minor(st.st_rdev) );
-		if( devices.find(dev) != devices.end() )
-			continue; /* dupe */
-		devices.insert( dev );
+		char *tok = strtok(hlist, " ");
+		char *evdev = NULL;
+		bool is_joystick = false;
+		do {
+			if (!strncmp(tok, "event", 5)) {
+				evdev = tok;
+				continue;
+			}
+			if (!strncmp(tok, "js", 2)) {
+				is_joystick = true;
+				continue;
+			}
+		} while ((tok = strtok(NULL, " ")));
 
-		fds[i] = open( Paths[i], O_RDONLY );
+		if (is_joystick && evdev) {
+			/* This must be shorter than "H: Handlers=" ;-) */
+			static const char devpfx[] =  "/dev/input/";
+			evdev -= sizeof(devpfx) - 1;
+			strncpy(evdev, devpfx, sizeof(devpfx) - 1);
+
+			fds[i] = open( evdev, O_RDONLY );
+			if(fds[i] == -1) {
+				LOG->Warn("Cannot open %s: %s", evdev, strerror(errno));
+				continue;
+			}
 
-		if(fds[i] != -1)
-		{
 			char szName[1024];
 			ZERO( szName );
-			if( ioctl(fds[i], JSIOCGNAME(sizeof(szName)), szName) < 0 )
-				m_sDescription[i] = ssprintf( "Unknown joystick at %s", Paths[i] );
+			if( ioctl(fds[i], EVIOCGNAME(sizeof(szName)), szName) < 0 )
+				m_sDescription[i] = ssprintf( "Unknown joystick at %s", evdev );
 			else
 				m_sDescription[i] = szName;
 
-			LOG->Info("Opened %s", Paths[i]);
+			LOG->Info("Opened %s", evdev);
+
 			bFoundAnyJoysticks = true;
+			if (++i >= NUM_JOYSTICKS)
+				break;
 		}
-	}
+ 	}
+
+	LOG->Info("Found %d joysticks", i);
+	fclose(f);
 
 	m_bShutdown = false;
 
@@ -136,7 +155,7 @@
 			if(!FD_ISSET(fds[i], &fdset))
 				continue;
 
-			js_event event;
+			input_event event;
 			int ret = read(fds[i], &event, sizeof(event));
 			if(ret != sizeof(event))
 			{
@@ -148,30 +167,32 @@
 
 			InputDevice id = InputDevice(DEVICE_JOY1 + i);
 
-			event.type &= ~JS_EVENT_INIT;
 			switch (event.type) {
-			case JS_EVENT_BUTTON: {
-				int iNum = event.number;
+			case EV_KEY: {
+				int iNum = event.code - BTN_JOYSTICK;
 				// In 2.6.11 using an EMS USB2, the event number for P1 Tri (the first button)
 				// is being reported as 32 instead of 0.  Correct for this.
+				// XXX: This was for js_event. Does this still apply for input_event?
 				wrap( iNum, 32 );	// max number of joystick buttons.  Make this a constant?
 				ButtonPressed( DeviceInput(id, enum_add2(JOY_BUTTON_1, iNum), event.value, now) );
 				break;
 			}
-				
-			case JS_EVENT_AXIS: {
-				DeviceButton neg = enum_add2(JOY_LEFT, 2*event.number);
-				DeviceButton pos = enum_add2(JOY_RIGHT, 2*event.number);
-                                float l = SCALE( int(event.value), 0.0f, 32767, 0.0f, 1.0f );
-				ButtonPressed( DeviceInput(id, neg, max(-l,0), now) );
-				ButtonPressed( DeviceInput(id, pos, max(+l,0), now) );
-				break;
-			}
+
+			case EV_ABS: {
+				DeviceButton neg = enum_add2(JOY_LEFT, 2*event.code);
+				DeviceButton pos = enum_add2(JOY_RIGHT, 2*event.code);
+				/* The 128 test is a special hack for DragonPlus
+				 * PS->USB reduction, and possibly others - the base
+				 * value is 127 but it changes to 128 for L+R or U+D. */
+				float l_neg = (event.value < 127 || event.value == 128 ? 1.0f : 0.0f);
+				float l_pos = (event.value > 129 || event.value == 128 ? 1.0f : 0.0f);
+				ButtonPressed( DeviceInput(id, neg, l_neg, now) );
+				ButtonPressed( DeviceInput(id, pos, l_pos, now) );
+ 				break;
+ 			}
 				
 			default:
-				LOG->Warn("Unexpected packet (type %i) from joystick %i; disabled", event.type, i);
-				close(fds[i]);
-				fds[i] = -1;
+				LOG->Warn("Unexpected packet (type %i) from joystick %i", event.type, i);
 				continue;
 			}
 
