shithub: qk2

Download patch

ref: 92b27541349fc0d3d6f3bf5a548592fac8d384dc
parent: a96f72a41fed2a20c363865b5860fcbfeec7c90d
author: Konstantinn Bonnet <qu7uux@gmail.com>
date: Mon Apr 20 18:52:46 EDT 2015

fix mproc race conditions and incorrect mousewheel events parsing

also minor cleanups.

--- a/plan9/in_9.c
+++ b/plan9/in_9.c
@@ -21,7 +21,7 @@
 
 qboolean mouseon;
 qboolean mlooking;
-int mx, my, mbtn, dx, dy, oldmx, oldmy, oldmbtn;
+int dx, dy;
 int oldmwin;
 
 typedef struct Kev Kev;
@@ -30,10 +30,11 @@
 	int down;
 };
 enum{
-	Nbuf	= 64
+	Nbuf	= 64,
+	ITHGRP	= 2
 };
 Channel *kchan;
-int ktid = -1, mtid = -1;
+Channel *mchan;
 
 /* rw_9.c */
 extern int resized;
@@ -61,23 +62,37 @@
 
 void IN_Commands (void)
 {
-	int i;
+	/* joystick stuff */
+}
 
-	if(!mouseon)
-		return;
-	for(i = 0; i < 5; i++){
-		if(mbtn & 1<<i && ~oldmbtn & 1<<i)
-			Key_Event(K_MOUSE1+i, true, Sys_Milliseconds());
-		if(~mbtn & 1<<i && oldmbtn & 1<<i)
-			Key_Event(K_MOUSE1+i, false, Sys_Milliseconds());
+void btnev (int btn, ulong msec)
+{
+	static int oldb;
+	int i, b;
+
+	for(i = 0; i < 3; i++){
+		b = 1<<i;
+		if(btn & b && ~oldb & b)
+			Key_Event(K_MOUSE1+i, true, msec);
+		else if(~btn & b && oldb & b)
+			Key_Event(K_MOUSE1+i, false, msec);
 	}
-	oldmbtn = mbtn;
+	oldb = btn;
+	/* mwheelup and mwheeldn buttons are never held down */
+	for(i = 3; i < 5; i++){
+		b = 1<<i;
+		if(btn & b){
+			Key_Event(K_MOUSE1+i, true, msec);
+			Key_Event(K_MOUSE1+i, false, msec);
+		}
+	}
 }
 
 void KBD_Update (void)
 {
-	Kev ev;
 	int r;
+	Kev ev;
+	Mouse m;
 
 	if(oldmwin != m_windowed->value){
 		oldmwin = m_windowed->value;
@@ -87,10 +102,19 @@
 		Key_Event(ev.key, ev.down, Sys_Milliseconds());
 	if(r < 0)
 		sysfatal("KBD_Update:nbrecv: %r\n");
+	while((r = nbrecv(mchan, &m)) > 0){
+		dx += m.xy.x;
+		dy += m.xy.y;
+		btnev(m.buttons, m.msec);
+	}
+	if(r < 0)
+		sysfatal("KBD_Update:nbrecv: %r\n");
 }
 
 void IN_Move (usercmd_t *cmd)
 {
+	static int mx, my, oldmx, oldmy;
+
 	if(!mouseon)
 		return;
 
@@ -103,11 +127,11 @@
 	}
 	oldmx = dx;
 	oldmy = dy;
+	dx = dy = 0;
 	if(!mx && !my)
 		return;
 	mx *= sensitivity->value;
 	my *= sensitivity->value;
-	dx = dy = 0;
 
 	/* add mouse x/y movement to cmd */
 	if(in_strafe.state & 1 || lookstrafe->value && mlooking)
@@ -196,6 +220,8 @@
 	Rune r;
 	Kev ev;
 
+	if(threadsetgrp(ITHGRP) < 0)
+		sysfatal("kproc:threadsetgrp: %r");
 	if((fd = open("/dev/kbd", OREAD)) < 0)
 		sysfatal("open /dev/kbd: %r");
 
@@ -213,7 +239,7 @@
 					if(k = runetokey(r)){
 						ev.key = k;
 						ev.down = true;
-						if(nbsend(kchan, &ev) < 0)
+						if(send(kchan, &ev) < 0)
 							sysfatal("kproc:nbsend: %r\n");
 					}
 				}
@@ -227,7 +253,7 @@
 					if(k = runetokey(r)){
 						ev.key = k;
 						ev.down = false;
-						if(nbsend(kchan, &ev) < 0)
+						if(send(kchan, &ev) < 0)
 							sysfatal("mproc:nbsend: %r\n");
 					}
 				}
@@ -236,8 +262,8 @@
 		}
 		strcpy(kdown, buf);
 	}
+	fprint(2, "kproc: %r\n");
 	close(fd);
-	ktid = -1;
 }
 
 void mproc (void *)
@@ -244,8 +270,10 @@
 {
 	int n, nerr = 0, fd;
 	char buf[1+5*12];
-	int x, y;
+	Mouse m;
 
+	if(threadsetgrp(ITHGRP) < 0)
+		sysfatal("mproc:threadsetgrp: %r");
 	if((fd = open("/dev/mouse", ORDWR)) < 0)
 		sysfatal("open /dev/mouse: %r");
 
@@ -265,36 +293,34 @@
 			if(!mouseon)
 				break;
 
-			x = atoi(buf+1+0*12) - center.x;
-			y = atoi(buf+1+1*12) - center.y;
-			mbtn = atoi(buf+1+2*12);
-			dx += x;
-			dy += y;
-			if(x != 0 || y != 0)
+			m.xy.x = atoi(buf+1+0*12) - center.x;
+			m.xy.y = atoi(buf+1+1*12) - center.y;
+			if(m.xy.x != 0 || m.xy.y != 0)
 				fprint(fd, "m%d %d", center.x, center.y);
+			m.buttons = atoi(buf+1+2*12);
+			m.msec = atoi(buf+1+3*12);
+			if(nbsend(mchan, &m) < 0)
+				sysfatal("mproc:nbsend: %r\n");
 			break;
 		}
 	}
+	fprint(2, "mproc: %r\n");
+	IN_Grabm(0);
 	close(fd);
-	mtid = -1;
 }
 
 void IN_Shutdown (void)
 {
 	IN_Grabm(0);
-	if(ktid != -1){
-		threadkill(ktid);
-		ktid = -1;
-	}
-	if(mtid != -1){
-		threadkill(mtid);
-		mtid = -1;
-	}
+	threadkillgrp(ITHGRP);
 	if(kchan != nil){
 		chanfree(kchan);
 		kchan = nil;
 	}
-	mouseon = false;
+	if(mchan != nil){
+		chanfree(mchan);
+		mchan = nil;
+	}
 }
 
 void IN_Init (void)
@@ -315,10 +341,12 @@
 	ri.Cmd_AddCommand("-mlook", IN_MLookUp);
 	ri.Cmd_AddCommand("force_centerview", IN_ForceCenterView);
 
-	kchan = chancreate(sizeof(Kev), Nbuf);
-	if((ktid = proccreate(kproc, nil, 8192)) < 0)
+	if((kchan = chancreate(sizeof(Kev), Nbuf)) == nil)
+		sysfatal("chancreate kchan: %r");
+	if(proccreate(kproc, nil, 8192) < 0)
 		sysfatal("proccreate kproc: %r");
-	if((mtid = proccreate(mproc, nil, 8192)) < 0)
+	if((mchan = chancreate(sizeof(Mouse), Nbuf)) == nil)
+		sysfatal("chancreate kchan: %r");
+	if(proccreate(mproc, nil, 8192) < 0)
 		sysfatal("proccreate mproc: %r");
-	mx = my = 0;
 }