plan 9 kernel history: overview | file list | diff list

2001/1211/alphapc/mouse.c (diff list | history)

1999/0415/sys/src/9/alphapc/mouse.c:29,342001/0727/sys/src/9/alphapc/mouse.c:29,35 (short | long)
1999/0415    
static void 
serialmouse(int port, char *type, int setspeed) 
{ 
2001/0727    
#ifdef notdef 
1999/0415    
	if(mousetype == Mouseserial) 
		error(Emouseset); 
 
1999/0415/sys/src/9/alphapc/mouse.c:39,482001/0727/sys/src/9/alphapc/mouse.c:40,54
1999/0415    
	if(setspeed) 
		setspeed = 1200; 
	if(type && *type == 'M') 
		ns16552special(port, setspeed, 0, 0, m3mouseputc); 
2001/0727    
		uartspecial(port, setspeed, 0, 0, m3mouseputc); 
1999/0415    
	else 
		ns16552special(port, setspeed, 0, 0, mouseputc); 
2001/0727    
		uartspecial(port, setspeed, 0, 0, mouseputc); 
1999/0415    
	mousetype = Mouseserial; 
2001/0727    
	packetsize = 3; 
#else 
	error("serial mouse not supported yet"); 
	USED(port, type, setspeed); 
#endif /* notdef */ 
1999/0415    
} 
 
/* 
1999/0415/sys/src/9/alphapc/mouse.c:79,852001/0727/sys/src/9/alphapc/mouse.c:85,91
1999/0415    
		buttons = b[(msg[0]&7) | (shift ? 8 : 0)]; 
		dx = msg[1]; 
		dy = -msg[2]; 
		mousetrack(buttons, dx, dy); 
2001/0727    
		mousetrack(buttons, dx, dy, TK2MS(MACHP(0)->ticks)); 
1999/0415    
	} 
	return; 
} 
2001/0727/sys/src/9/alphapc/mouse.c:22,282001/1121/sys/src/9/alphapc/mouse.c:22,56 (short | long)
1999/0415    
	MousePS2=	2, 
}; 
static int mousetype; 
2001/1121    
static int intellimouse; 
static int packetsize; 
static int resolution; 
static int accelerated; 
1999/0415    
 
2001/1121    
enum 
{ 
	CMaccelerated, 
	CMintellimouse, 
	CMlinear, 
	CMps2, 
	CMps2intellimouse, 
	CMres, 
	CMreset, 
	CMserial, 
}; 
 
static Cmdtab mousectlmsg[] = 
{ 
	CMaccelerated,		"accelerated",		0, 
	CMintellimouse,		"intellimouse",		1, 
	CMlinear,		"linear",		1, 
	CMps2,			"ps2",			1, 
	CMps2intellimouse,	"ps2intellimouse",	1, 
	CMres,			"res",			0, 
	CMreset,		"reset",		1, 
	CMserial,		"serial",		0, 
}; 
 
1999/0415    
/* 
 *  setup a serial mouse 
 */ 
2001/0727/sys/src/9/alphapc/mouse.c:58,812001/1121/sys/src/9/alphapc/mouse.c:86,140
1999/0415    
 *	byte 1 -	DX 
 *	byte 2 -	DY 
 * 
 *  shift & left button is the same as middle button 
2001/1121    
 *  shift & right button is the same as middle button 
 * 
 * Intellimouse and AccuPoint with extra buttons deliver 
 *	byte 3 -	00 or 01 or FF according to extra button state. 
 * extra buttons are mapped in this code to buttons 4 and 5. 
 * AccuPoint generates repeated events for these buttons; 
*  it and Intellimouse generate 'down' events only, so 
 * user-level code is required to generate button 'up' events 
 * if they are needed by the application. 
 * Also on laptops with AccuPoint AND external mouse, the 
 * controller may deliver 3 or 4 bytes according to the type 
 * of the external mouse; code must adapt. 
 * 
 * On the NEC Versa series (and perhaps others?) we seem to 
 * lose a byte from the packet every once in a while, which 
 * means we lose where we are in the instruction stream. 
 * To resynchronize, if we get a byte more than two seconds 
 * after the previous byte, we assume it's the first in a packet. 
1999/0415    
 */ 
static void 
ps2mouseputc(int c, int shift) 
{ 
	static short msg[3]; 
2001/1121    
	static short msg[4]; 
1999/0415    
	static int nb; 
	static uchar b[] = {0, 1, 4, 5, 2, 3, 6, 7, 0, 1, 2, 5, 2, 3, 6, 7 }; 
2001/1121    
	static uchar b[] = {0, 1, 4, 5, 2, 3, 6, 7, 0, 1, 2, 3, 2, 3, 6, 7 }; 
	static ulong lasttick; 
	ulong m; 
1999/0415    
	int buttons, dx, dy; 
 
2001/1121    
	/* 
	 * Resynchronize in stream with timing; see comment above. 
	 */ 
	m = MACHP(0)->ticks; 
	if(TK2SEC(m - lasttick) > 2) 
		nb = 0; 
	lasttick = m; 
 
1999/0415    
	/*  
	 *  check byte 0 for consistency 
	 */ 
	if(nb==0 && (c&0xc8)!=0x08) 
		return; 
2001/1121    
		if(intellimouse && (c==0x00 || c==0x01 || c==0xFF)){ 
			/* last byte of 4-byte packet */ 
			packetsize = 4; 
			return; 
		} 
1999/0415    
 
	msg[nb] = c; 
	if(++nb == 3){ 
2001/1121    
	if(++nb == packetsize){ 
1999/0415    
		nb = 0; 
		if(msg[0] & 0x10) 
			msg[1] |= 0xFF00; 
2001/0727/sys/src/9/alphapc/mouse.c:83,912001/1121/sys/src/9/alphapc/mouse.c:142,166
1999/0415    
			msg[2] |= 0xFF00; 
 
		buttons = b[(msg[0]&7) | (shift ? 8 : 0)]; 
2001/1121    
		if(intellimouse && packetsize==4){ 
			if((msg[3]&0xc8) == 0x08){ 
				/* first byte of 3-byte packet */ 
				packetsize = 3; 
				msg[0] = msg[3]; 
				nb = 1; 
				/* fall through to emit previous packet */ 
			}else{ 
				/* the AccuPoint on the Toshiba 34[48]0CT encodes extra buttons as 4 and 5 */ 
				/* they repeat and don't release, however, so user-level timing code is required */ 
				if(msg[3] == 0xFF)  
					buttons |= 1<<3; 
				if(msg[3] == 0x01)  
					buttons |= 1<<4; 
			} 
		} 
1999/0415    
		dx = msg[1]; 
		dy = -msg[2]; 
2001/0727    
		mousetrack(buttons, dx, dy, TK2MS(MACHP(0)->ticks)); 
2001/1121    
		mousetrack(dx, dy, buttons, TK2MS(MACHP(0)->ticks)); 
1999/0415    
	} 
	return; 
} 
2001/0727/sys/src/9/alphapc/mouse.c:105,1162001/1121/sys/src/9/alphapc/mouse.c:180,188
1999/0415    
	i8042auxcmd(0xF4); 
 
	mousetype = MousePS2; 
2001/1121    
	packetsize = 3; 
1999/0415    
} 
 
static int intellimouse; 
static int resolution; 
static int accelerated; 
                 
static void 
setaccelerated(int x) 
{ 
2001/0727/sys/src/9/alphapc/mouse.c:155,1602001/1121/sys/src/9/alphapc/mouse.c:227,233
1999/0415    
setintellimouse(void) 
{ 
	intellimouse = 1; 
2001/1121    
	packetsize = 4; 
1999/0415    
	switch(mousetype){ 
	case MousePS2: 
		i8042auxcmd(0xF3);	/* set sample */ 
2001/0727/sys/src/9/alphapc/mouse.c:170,1752001/1121/sys/src/9/alphapc/mouse.c:243,249
1999/0415    
static void 
resetmouse(void) 
{ 
2001/1121    
	packetsize = 3; 
1999/0415    
	switch(mousetype){ 
	case MousePS2: 
		i8042auxcmd(0xF6); 
2001/0727/sys/src/9/alphapc/mouse.c:182,2162001/1121/sys/src/9/alphapc/mouse.c:256,290
1999/0415    
} 
 
void 
mousectl(char* field[], int n) 
2001/1121    
mousectl(Cmdbuf *cb) 
1999/0415    
{ 
	if(strncmp(field[0], "serial", 6) == 0){ 
		switch(n){ 
		case 1: 
			serialmouse(atoi(field[0]+6), 0, 1); 
			break; 
		case 2: 
			serialmouse(atoi(field[1]), 0, 0); 
			break; 
		case 3: 
		default: 
			serialmouse(atoi(field[1]), field[2], 0); 
			break; 
		} 
	} else if(strcmp(field[0], "ps2") == 0){ 
2001/1121    
	Cmdtab *ct; 
 
	ct = lookupcmd(cb, mousectlmsg, nelem(mousectlmsg)); 
	switch(ct->index){ 
	case CMaccelerated: 
		setaccelerated(cb->nf == 1 ? 1 : atoi(cb->f[1])); 
		break; 
	case CMintellimouse: 
		setintellimouse(); 
		break; 
	case CMlinear: 
		setlinear(); 
		break; 
	case CMps2: 
1999/0415    
		ps2mouse(); 
	} else if(strcmp(field[0], "ps2intellimouse") == 0){ 
2001/1121    
		break; 
	case CMps2intellimouse: 
1999/0415    
		ps2mouse(); 
		setintellimouse(); 
	} else if(strcmp(field[0], "accelerated") == 0){ 
		setaccelerated(n == 1 ? 1 : atoi(field[1])); 
	} else if(strcmp(field[0], "linear") == 0){ 
		setlinear(); 
	} else if(strcmp(field[0], "res") == 0){ 
		if(n >= 2) 
			n = atoi(field[1]); 
		setres(n); 
	} else if(strcmp(field[0], "reset") == 0){ 
2001/1121    
		break; 
	case CMres: 
		if(cb->nf >= 2) 
			setres(atoi(cb->f[1])); 
		else 
			setres(1); 
		break; 
	case CMreset: 
1999/0415    
		resetmouse(); 
		if(accelerated) 
			setaccelerated(accelerated); 
2001/0727/sys/src/9/alphapc/mouse.c:218,2262001/1121/sys/src/9/alphapc/mouse.c:292,311
1999/0415    
			setres(resolution); 
		if(intellimouse) 
			setintellimouse(); 
	} else if(strcmp(field[0], "intellimouse") == 0){ 
		setintellimouse(); 
2001/1121    
		break; 
	case CMserial: 
		switch(cb->nf){ 
		case 1: 
			serialmouse(atoi(cb->f[0]+6), 0, 1); 
			break; 
		case 2: 
			serialmouse(atoi(cb->f[1]), 0, 0); 
			break; 
		case 3: 
		default: 
			serialmouse(atoi(cb->f[1]), cb->f[2], 0); 
			break; 
		} 
		break; 
1999/0415    
	} 
	else 
		error(Ebadctl); 
} 
2001/1121/sys/src/9/alphapc/mouse.c:1,3112001/1211/sys/src/9/alphapc/mouse.c:1 (short | long)
1999/0415    
#include "u.h" 
#include "../port/lib.h" 
#include "mem.h" 
#include "dat.h" 
#include "fns.h" 
#include "../port/error.h" 
#include "io.h" 
                 
#define	Image	IMAGE 
#include <draw.h> 
#include <memdraw.h> 
#include <cursor.h> 
#include "screen.h" 
                 
/* 
 *  mouse types 
 */ 
enum 
{ 
	Mouseother=	0, 
	Mouseserial=	1, 
	MousePS2=	2, 
}; 
static int mousetype; 
2001/1121    
static int intellimouse; 
static int packetsize; 
static int resolution; 
static int accelerated; 
1999/0415    
                 
2001/1121    
enum 
{ 
	CMaccelerated, 
	CMintellimouse, 
	CMlinear, 
	CMps2, 
	CMps2intellimouse, 
	CMres, 
	CMreset, 
	CMserial, 
}; 
                 
static Cmdtab mousectlmsg[] = 
{ 
	CMaccelerated,		"accelerated",		0, 
	CMintellimouse,		"intellimouse",		1, 
	CMlinear,		"linear",		1, 
	CMps2,			"ps2",			1, 
	CMps2intellimouse,	"ps2intellimouse",	1, 
	CMres,			"res",			0, 
	CMreset,		"reset",		1, 
	CMserial,		"serial",		0, 
}; 
                 
1999/0415    
/* 
 *  setup a serial mouse 
 */ 
static void 
serialmouse(int port, char *type, int setspeed) 
{ 
2001/0727    
#ifdef notdef 
1999/0415    
	if(mousetype == Mouseserial) 
		error(Emouseset); 
                 
	if(port >= 3 || port < 0) 
		error(Ebadarg); 
                 
	/* set up /dev/eia? as the mouse */ 
	if(setspeed) 
		setspeed = 1200; 
	if(type && *type == 'M') 
2001/0727    
		uartspecial(port, setspeed, 0, 0, m3mouseputc); 
1999/0415    
	else 
2001/0727    
		uartspecial(port, setspeed, 0, 0, mouseputc); 
1999/0415    
	mousetype = Mouseserial; 
2001/0727    
	packetsize = 3; 
#else 
	error("serial mouse not supported yet"); 
	USED(port, type, setspeed); 
#endif /* notdef */ 
1999/0415    
} 
                 
/* 
 *  ps/2 mouse message is three bytes 
 * 
 *	byte 0 -	0 0 SDY SDX 1 M R L 
 *	byte 1 -	DX 
 *	byte 2 -	DY 
 * 
2001/1121    
 *  shift & right button is the same as middle button 
 * 
 * Intellimouse and AccuPoint with extra buttons deliver 
 *	byte 3 -	00 or 01 or FF according to extra button state. 
 * extra buttons are mapped in this code to buttons 4 and 5. 
 * AccuPoint generates repeated events for these buttons; 
*  it and Intellimouse generate 'down' events only, so 
 * user-level code is required to generate button 'up' events 
 * if they are needed by the application. 
 * Also on laptops with AccuPoint AND external mouse, the 
 * controller may deliver 3 or 4 bytes according to the type 
 * of the external mouse; code must adapt. 
 * 
 * On the NEC Versa series (and perhaps others?) we seem to 
 * lose a byte from the packet every once in a while, which 
 * means we lose where we are in the instruction stream. 
 * To resynchronize, if we get a byte more than two seconds 
 * after the previous byte, we assume it's the first in a packet. 
1999/0415    
 */ 
static void 
ps2mouseputc(int c, int shift) 
{ 
2001/1121    
	static short msg[4]; 
1999/0415    
	static int nb; 
2001/1121    
	static uchar b[] = {0, 1, 4, 5, 2, 3, 6, 7, 0, 1, 2, 3, 2, 3, 6, 7 }; 
	static ulong lasttick; 
	ulong m; 
1999/0415    
	int buttons, dx, dy; 
                 
2001/1121    
	/* 
	 * Resynchronize in stream with timing; see comment above. 
	 */ 
	m = MACHP(0)->ticks; 
	if(TK2SEC(m - lasttick) > 2) 
		nb = 0; 
	lasttick = m; 
                 
1999/0415    
	/*  
	 *  check byte 0 for consistency 
	 */ 
	if(nb==0 && (c&0xc8)!=0x08) 
2001/1121    
		if(intellimouse && (c==0x00 || c==0x01 || c==0xFF)){ 
			/* last byte of 4-byte packet */ 
			packetsize = 4; 
			return; 
		} 
1999/0415    
                 
	msg[nb] = c; 
2001/1121    
	if(++nb == packetsize){ 
1999/0415    
		nb = 0; 
		if(msg[0] & 0x10) 
			msg[1] |= 0xFF00; 
		if(msg[0] & 0x20) 
			msg[2] |= 0xFF00; 
                 
		buttons = b[(msg[0]&7) | (shift ? 8 : 0)]; 
2001/1121    
		if(intellimouse && packetsize==4){ 
			if((msg[3]&0xc8) == 0x08){ 
				/* first byte of 3-byte packet */ 
				packetsize = 3; 
				msg[0] = msg[3]; 
				nb = 1; 
				/* fall through to emit previous packet */ 
			}else{ 
				/* the AccuPoint on the Toshiba 34[48]0CT encodes extra buttons as 4 and 5 */ 
				/* they repeat and don't release, however, so user-level timing code is required */ 
				if(msg[3] == 0xFF)  
					buttons |= 1<<3; 
				if(msg[3] == 0x01)  
					buttons |= 1<<4; 
			} 
		} 
1999/0415    
		dx = msg[1]; 
		dy = -msg[2]; 
2001/1121    
		mousetrack(dx, dy, buttons, TK2MS(MACHP(0)->ticks)); 
1999/0415    
	} 
	return; 
} 
                 
/* 
 *  set up a ps2 mouse 
 */ 
static void 
ps2mouse(void) 
{ 
	if(mousetype == MousePS2) 
		return; 
                 
	i8042auxenable(ps2mouseputc); 
	/* make mouse streaming, enabled */ 
	i8042auxcmd(0xEA); 
	i8042auxcmd(0xF4); 
                 
	mousetype = MousePS2; 
2001/1121    
	packetsize = 3; 
1999/0415    
} 
                 
static void 
setaccelerated(int x) 
{ 
	accelerated = x; 
	switch(mousetype){ 
	case MousePS2: 
		i8042auxcmd(0xE7); 
		break; 
	default: 
		mouseaccelerate(x); 
		break; 
	} 
} 
                 
static void 
setlinear(void) 
{ 
	accelerated = 0; 
	switch(mousetype){ 
	case MousePS2: 
		i8042auxcmd(0xE6); 
		break; 
	default: 
		mouseaccelerate(0); 
		break; 
	} 
} 
                 
static void 
setres(int n) 
{ 
	resolution = n; 
	switch(mousetype){ 
	case MousePS2: 
		i8042auxcmd(0xE8); 
		i8042auxcmd(n); 
		break; 
	} 
} 
                 
static void 
setintellimouse(void) 
{ 
	intellimouse = 1; 
2001/1121    
	packetsize = 4; 
1999/0415    
	switch(mousetype){ 
	case MousePS2: 
		i8042auxcmd(0xF3);	/* set sample */ 
		i8042auxcmd(0xC8); 
		i8042auxcmd(0xF3);	/* set sample */ 
		i8042auxcmd(0x64); 
		i8042auxcmd(0xF3);	/* set sample */ 
		i8042auxcmd(0x50); 
		break; 
	} 
} 
                 
static void 
resetmouse(void) 
{ 
2001/1121    
	packetsize = 3; 
1999/0415    
	switch(mousetype){ 
	case MousePS2: 
		i8042auxcmd(0xF6); 
		i8042auxcmd(0xEA);	/* streaming */ 
		i8042auxcmd(0xE8);	/* set resolution */ 
		i8042auxcmd(3); 
		i8042auxcmd(0xF4);	/* enabled */ 
		break; 
	} 
} 
                 
void 
2001/1121    
mousectl(Cmdbuf *cb) 
1999/0415    
{ 
2001/1121    
	Cmdtab *ct; 
                 
	ct = lookupcmd(cb, mousectlmsg, nelem(mousectlmsg)); 
	switch(ct->index){ 
	case CMaccelerated: 
		setaccelerated(cb->nf == 1 ? 1 : atoi(cb->f[1])); 
		break; 
	case CMintellimouse: 
		setintellimouse(); 
		break; 
	case CMlinear: 
		setlinear(); 
		break; 
	case CMps2: 
1999/0415    
		ps2mouse(); 
2001/1121    
		break; 
	case CMps2intellimouse: 
1999/0415    
		ps2mouse(); 
		setintellimouse(); 
2001/1121    
		break; 
	case CMres: 
		if(cb->nf >= 2) 
			setres(atoi(cb->f[1])); 
		else 
			setres(1); 
		break; 
	case CMreset: 
1999/0415    
		resetmouse(); 
		if(accelerated) 
			setaccelerated(accelerated); 
		if(resolution) 
			setres(resolution); 
		if(intellimouse) 
			setintellimouse(); 
2001/1121    
		break; 
	case CMserial: 
		switch(cb->nf){ 
		case 1: 
			serialmouse(atoi(cb->f[0]+6), 0, 1); 
			break; 
		case 2: 
			serialmouse(atoi(cb->f[1]), 0, 0); 
			break; 
		case 3: 
		default: 
			serialmouse(atoi(cb->f[1]), cb->f[2], 0); 
			break; 
		} 
		break; 
1999/0415    
	} 
} 
2001/1211    
#include "../pc/mouse.c" 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)