EVDEV Support in Linux Quake2

The place to discuss your client and server issues, or to post your client and server related problems. Now with added Anticheat flavour.

Moderator: Moderators

Post Reply
Haudrauf
tripped on its own grenade
Posts: 331
Joined: Tue Aug 26, 2003 11:20 am
Location: de
Contact:

EVDEV Support in Linux Quake2

Post by Haudrauf »

Linux Quake2 with EVDEV support = super smooth mouse.
I used str-s code from the Fuhquake forums. It works.

Code: Select all

--- gl_glx.c	2003-06-22 12:08:00.000000000 +0200
+++ evdev_gl_glx.c	2004-06-15 19:04:31.357040248 +0200
@@ -55,6 +55,12 @@ Foundation, Inc., 59 Temple Place - Suit
 #include <X11/extensions/xf86dga.h>
 #include <X11/extensions/xf86vmode.h>
 
+#ifdef WITH_EVDEV 
+#include <fcntl.h> 
+#include <linux/input.h> 
+#endif 
+ 
+
 #include <GL/glx.h>
 
 glwstate_t glw_state;
@@ -101,6 +107,12 @@ static XF86VidModeModeInfo **vidmodes;
 static int num_vidmodes;
 static qboolean vidmode_active = false;
 
+#ifdef WITH_EVDEV 
+int mevdev; 
+int mevdev_fd; 
+#endif 
+ 
+
 static qboolean	mlooking;
 
 static qboolean mouse_active = false;
@@ -155,7 +167,6 @@ static void install_grabs(void)
 				 win,
 				 None,
 				 CurrentTime);
-
 	if (in_dgamouse->value) {
 		int MajorVersion, MinorVersion;
 
@@ -221,15 +232,32 @@ static void RW_IN_MLookUp (void) 
 
 void RW_IN_Init(in_state_t *in_state_p)
 {
+#ifdef WITH_EVDEV 
+	char *mousedev; 
+	
+	mevdev = false; 
+	
+	ri.Con_Printf( PRINT_ALL, "evdev: INIT\n");
+//	if (COM_CheckParm("-mevdev")) { // fixme!
+//	mousedev = COM_Argv(COM_CheckParm("-mevdev")+2); 
+		mousedev = "/dev/input/event2"; // fixme
+		if ((mevdev_fd = open(mousedev, O_RDONLY)) != -1) { 
+			ri.Con_Printf( PRINT_ALL, "evdev: INIT SUCCESS %s\n", mousedev);
+			mevdev = true; 
+		} else { 
+			Sys_Error("evdev: unable to open %s\n", mousedev); 
+		} 
+//	} 
+#endif 
+
 //	int mtype;
 //	int i;
-
 	in_state = in_state_p;
 
 	// mouse variables
 	m_filter = ri.Cvar_Get ("m_filter", "0", 0);
-    in_mouse = ri.Cvar_Get ("in_mouse", "1", CVAR_ARCHIVE);
-    in_dgamouse = ri.Cvar_Get ("in_dgamouse", "1", CVAR_ARCHIVE);
+	in_mouse = ri.Cvar_Get ("in_mouse", "1", CVAR_ARCHIVE);
+	in_dgamouse = ri.Cvar_Get ("in_dgamouse", "1", CVAR_ARCHIVE);
 	freelook = ri.Cvar_Get( "freelook", "0", 0 );
 	lookstrafe = ri.Cvar_Get ("lookstrafe", "0", 0);
 	sensitivity = ri.Cvar_Get ("sensitivity", "3", 0);
@@ -249,6 +277,11 @@ void RW_IN_Init(in_state_t *in_state_p)
 
 void RW_IN_Shutdown(void)
 {
+#ifdef WITH_EVDEV 
+	if (mevdev) { 
+		close(mevdev_fd); 
+	} 
+#endif 
 	mouse_avail = false;
 }
 
@@ -257,8 +290,105 @@ void RW_IN_Shutdown(void)
 IN_Commands
 ===========
 */
+
 void RW_IN_Commands (void)
 {
+#ifdef WITH_EVDEV 
+	static struct input_event ev[64]; 
+	
+	fd_set set; 
+	struct timeval timeout; 
+	size_t bytes; 
+	int i; 
+
+	while (mevdev) { 
+//		poll instead of waiting 
+		timeout.tv_sec = 0; 
+		timeout.tv_usec = 0; 
+
+		FD_ZERO (&set); 
+		FD_SET (mevdev_fd, &set); 
+
+		if(select(FD_SETSIZE, &set, NULL, NULL, &timeout) < 1) { 
+			break; 
+		} 
+
+		bytes = read(mevdev_fd, ev, sizeof(struct input_event) * 64); 
+//		Com_Printf("evdev: bytes read: %i\n", (int)bytes);
+
+		if (bytes < (int) sizeof(struct input_event)) { 
+			Com_Printf("evdev: %i < %i\n", (int) bytes, (int) sizeof(struct input_event)); 
+			break; 
+		} 
+
+		for (i = 0; i < (int) (bytes / sizeof(struct input_event)); i++) { 
+			switch (ev[i].type) { 
+				case EV_KEY: 
+	
+					Com_Printf("evdev: inputcode: %i\n", ev[i].code);
+	
+					switch (ev[i].code) { 
+						case BTN_MOUSE: 
+							in_state->Key_Event_fp (K_MOUSE1, true);
+							Key_Event(K_MOUSE1, (int) ev[i].value, sys_msg_time); 
+						break;                
+						case BTN_MOUSE+1: 
+							in_state->Key_Event_fp (K_MOUSE2, true);
+							Key_Event(K_MOUSE2, (int) ev[i].value); 
+						break;                
+						case BTN_MOUSE+2: 
+							in_state->Key_Event_fp (K_MOUSE3, true);
+							Key_Event(K_MOUSE3, (int) ev[i].value, sys_msg_time); 
+						break;                
+						case BTN_MOUSE+3: 
+							in_state->Key_Event_fp (K_MOUSE4, true);
+							Key_Event(K_MOUSE4, (int) ev[i].valuei, sys_msg_time); 
+						break;                
+						case BTN_MOUSE+4: 
+							in_state->Key_Event_fp (K_MOUSE5, true);
+							Key_Event(K_MOUSE5, (int) ev[i].value, sys_msg_time); 
+						break;                
+						case BTN_MOUSE+5: 
+							in_state->Key_Event_fp (K_MOUSE6, true);
+							Key_Event(K_MOUSE6, (int) ev[i].value, sys_msg_time); 
+						break;                
+						case BTN_MOUSE+6: 
+							in_state->Key_Event_fp (K_MOUSE7, true);
+							Key_Event(K_MOUSE7, (int) ev[i].value, sys_msg_time); 
+						break;                
+						case BTN_MOUSE+7: 
+							in_state->Key_Event_fp (K_MOUSE8, true);
+							Key_Event(K_MOUSE8, (int) ev[i].value, sys_msg_time); 
+						break;                
+					} 
+				break; 
+				case EV_REL: 
+					switch (ev[i].code) { 
+						case REL_X: 
+							mx += (int) ev[i].value; 
+						break; 
+						case REL_Y: 
+							my += (int) ev[i].value; 
+						break; 
+						case REL_WHEEL: 
+							if((int) ev[i].value == 1) { 
+								in_state->Key_Event_fp (K_MWHEELUP, true);
+								in_state->Key_Event_fp (K_MWHEELUP, false);
+//								Key_Event(K_MWHEELUP, true, sys_msg_time); 
+//								Key_Event(K_MWHEELUP, false, sys_msg_time); 
+							} else if((int) ev[i].value == -1) { 
+								in_state->Key_Event_fp (K_MWHEELDOWN, true);
+								in_state->Key_Event_fp (K_MWHEELDOWN, false);
+//								Key_Event(K_MWHEELDOWN, true, sys_msg_time); 
+//								Key_Event(K_MWHEELDOWN, false, sys_msg_time); 
+							} 
+						break; 
+					} // end of switch
+				break; 
+			} // end of switch
+		} // end of for
+	} // end of while (evdev)
+#endif 
 }
 
 /*
@@ -268,9 +398,11 @@ IN_Move
 */
 void RW_IN_Move (usercmd_t *cmd)
 {
+//	ri.Con_Printf( PRINT_ALL, "evdev: RW_IN_MOVE\n");
 	if (!mouse_avail)
 		return;
-   
+
+
 	if (m_filter->value)
 	{
 		mx = (mx + old_mouse_x) * 0.5;
@@ -305,6 +437,7 @@ void RW_IN_Move (usercmd_t *cmd)
 
 static void IN_DeactivateMouse( void ) 
 {
+	ri.Con_Printf( PRINT_ALL, "evdev: IN_DeactivateMouse\n");
 	if (!mouse_avail || !dpy || !win)
 		return;
 
@@ -500,6 +633,11 @@ static void HandleEvents(void)
 
 		case MotionNotify:
 			if (mouse_active) {
+				#ifdef WITH_EVDEV 
+				if (mevdev) { 
+					break; 
+				} 
+				#endif 
 				if (dgamouse) {
 					mx += (event.xmotion.x + win_x) * 2;
 					my += (event.xmotion.y + win_y) * 2;
@@ -519,6 +657,12 @@ static void HandleEvents(void)
 
 
 		case ButtonPress:
+
+			#ifdef WITH_EVDEV
+			if (mevdev) {
+				break;
+			}
+			#endif
 			myxtime = event.xbutton.time;
 			b=-1;
 			if (event.xbutton.button == 1)
@@ -536,6 +680,12 @@ static void HandleEvents(void)
 			break;
 
 		case ButtonRelease:
+
+			#ifdef WITH_EVDEV 
+			if (mevdev) { 
+				break; 
+			} 
+			#endif 
 			b=-1;
 			if (event.xbutton.button == 1)
 				b = 0;
@@ -551,12 +701,12 @@ static void HandleEvents(void)
 				in_state->Key_Event_fp (K_MOUSE1 + b, false);
 			break;
 
-		case CreateNotify :
+		case CreateNotify:
 			win_x = event.xcreatewindow.x;
 			win_y = event.xcreatewindow.y;
 			break;
 
-		case ConfigureNotify :
+		case ConfigureNotify:
 			win_x = event.xconfigure.x;
 			win_y = event.xconfigure.y;
 			break;
There's still a question concerning the mousebuttons and how to get params off the commandline. See the "fixme"s.

Don't forget to add -DWITH_EVDEV to the Makefile where it says:

Code: Select all

GLXCFLAGS=
GLXLDFLAGS=-L/usr/X11R6/lib -ljpeg -lX11 -lXext -lXxf86dga -lXxf86vm
should be:

Code: Select all

GLXCFLAGS=-DWITH_EVDEV
GLXLDFLAGS=-L/usr/X11R6/lib -ljpeg -lX11 -lXext -lXxf86dga -lXxf86vm
ImageOwner of http://aq2maps.quadaver.org
Not part of #aq2admins for a reason.
Den
something dur dur
Posts: 2616
Joined: Fri Jul 25, 2003 8:56 am
Location: nl
Contact:

Post by Den »

:)
There's a chopper coming in 3 days and there's a katana on top of the cafe and that's all you need to know
Image
Post Reply