Plan 9 from Bell Labs’s /usr/web/sources/extra/9hist/pc/mouse.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


## diffname pc/mouse.c 1997/0327
## diff -e /dev/null /n/emeliedump/1997/0327/sys/src/brazil/pc/mouse.c
0a
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "../port/error.h"
#include "io.h"

#include <libg.h>
#include "screen.h"

/*
 *  setup a serial mouse
 */
static void
serialmouse(int port, char *type, int setspeed)
{
	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')
		ns16552special(port, setspeed, 0, 0, m3mouseputc);
	else
		ns16552special(port, setspeed, 0, 0, mouseputc);
	mousetype = Mouseserial;
}

/*
 *  ps/2 mouse message is three bytes
 *
 *	byte 0 -	0 0 SDY SDX 1 M R L
 *	byte 1 -	DX
 *	byte 2 -	DY
 *
 *  shift & left button is the same as middle button
 */
static void
ps2mouseputc(int c, int shift)
{
	static short msg[3];
	static int nb;
	static uchar b[] = {0, 1, 4, 5, 2, 3, 6, 7, 0, 1, 2, 5, 2, 3, 6, 7 };
	int buttons, dx, dy;

	/* 
	 *  check byte 0 for consistency
	 */
	if(nb==0 && (c&0xc8)!=0x08)
		return;

	msg[nb] = c;
	if(++nb == 3){
		nb = 0;
		if(msg[0] & 0x10)
			msg[1] |= 0xFF00;
		if(msg[0] & 0x20)
			msg[2] |= 0xFF00;

		buttons = b[(msg[0]&7) | (shift ? 8 : 0)];
		dx = msg[1];
		dy = -msg[2];
		mousetrack(buttons, dx, dy);
	}
	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;
}

void
mousectl(char* arg)
{
	int n;
	char *field[3];

	n = parsefields(arg, field, 3, " ");
	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){
		ps2mouse();
	} else if(strcmp(field[0], "accelerated") == 0){
		switch(mousetype){
		case MousePS2:
			i8042auxcmd(0xE7);
			break;
		default:
			mouseaccelerate(field[1]);
			break;
		}
	} else if(strcmp(field[0], "linear") == 0){
		switch(mousetype){
		case MousePS2:
			i8042auxcmd(0xE6);
			break;
		default:
			mouseaccelerate("0");
			break;
		}
	} else if(strcmp(field[0], "res") == 0){
		if(n < 2)
			n = 1;
		else
			n = atoi(field[1]);
		switch(mousetype){
		case MousePS2:
			i8042auxcmd(0xE8);
			i8042auxcmd(n);
			break;
		}
	} else if(strcmp(field[0], "swap") == 0)
		mouseswap ^= 1;
	else
		error(Ebadctl);
}
.
## diffname pc/mouse.c 1997/0808
## diff -e /n/emeliedump/1997/0327/sys/src/brazil/pc/mouse.c /n/emeliedump/1997/0808/sys/src/brazil/pc/mouse.c
118c
			if(n == 1)
				mouseaccelerate("1");
			else
				mouseaccelerate(field[1]);
.
## diffname pc/mouse.c 1997/1101
## diff -e /n/emeliedump/1997/0808/sys/src/brazil/pc/mouse.c /n/emeliedump/1997/1101/sys/src/brazil/pc/mouse.c
10a

/*
 *  mouse types
 */
enum
{
	Mouseother=	0,
	Mouseserial=	1,
	MousePS2=	2,
};
static int mousetype;
.
9c
#define	Image	IMAGE
#include <draw.h>
#include <memdraw.h>
.
## diffname pc/mouse.c 1998/0417
## diff -e /n/emeliedump/1997/1101/sys/src/brazil/pc/mouse.c /n/emeliedump/1998/0417/sys/src/brazil/pc/mouse.c
157,158c
	}
.
106,109d
104c
mousectl(char* field[], int n)
.
## diffname pc/mouse.c 1999/0119
## diff -e /n/emeliedump/1998/0417/sys/src/brazil/pc/mouse.c /n/emeliedump/1999/0119/sys/src/brazil/pc/mouse.c
11a
#include <cursor.h>
.
## diffname pc/mouse.c 1999/0224
## diff -e /n/emeliedump/1999/0119/sys/src/brazil/pc/mouse.c /n/emeliedump/1999/0224/sys/src/brazil/pc/mouse.c
153a
	} else if(strcmp(field[0], "reset") == 0){
		i8042auxcmd(0xF6);
		i8042auxcmd(0xEA);	/* streaming */
		i8042auxcmd(0xE8);	/* set resolution */
		i8042auxcmd(3);
		i8042auxcmd(0xF4);	/* enabled */
.
## diffname pc/mouse.c 1999/0225
## diff -e /n/emeliedump/1999/0224/sys/src/brazil/pc/mouse.c /n/emeliedump/1999/0225/sys/src/brazil/pc/mouse.c
155,159c
		resetmouse();
		if(accelerated)
			setaccelerated(accelerated);
		if(resolution)
			setres(resolution);
		if(intellimouse)
			setintellimouse();
	} else if(strcmp(field[0], "intellimouse") == 0){
		setintellimouse();
.
148,153c
		setres(n);
.
144,146c
		if(n >= 2)
.
135,142c
		setlinear();
.
123,133c
		setaccelerated(n == 1 ? 1 : atoi(field[1]));
.
121a
	} else if(strcmp(field[0], "ps2intellimouse") == 0){
		ps2mouse();
		setintellimouse();
.
103a
static int intellimouse;
static int resolution;
static int accelerated;

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;
	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)
{
	switch(mousetype){
	case MousePS2:
		i8042auxcmd(0xF6);
		i8042auxcmd(0xEA);	/* streaming */
		i8042auxcmd(0xE8);	/* set resolution */
		i8042auxcmd(3);
		i8042auxcmd(0xF4);	/* enabled */
		break;
	}
}

.
## diffname pc/mouse.c 2000/0716
## diff -e /n/emeliedump/1999/0225/sys/src/brazil/pc/mouse.c /n/emeliedump/2000/0716/sys/src/9/pc/mouse.c
62c
	static uchar b[] = {0, 1, 4, 5, 2, 3, 6, 7, 0, 1, 2, 3, 2, 3, 6, 7 };
.
## diffname pc/mouse.c 2000/0731
## diff -e /n/emeliedump/2000/0716/sys/src/9/pc/mouse.c /n/emeliedump/2000/0731/sys/src/9/pc/mouse.c
55c
 *  shift & right button is the same as middle button
.
## diffname pc/mouse.c 2000/1005
## diff -e /n/emeliedump/2000/0731/sys/src/9/pc/mouse.c /n/emeliedump/2000/1005/sys/src/9/pc/mouse.c
104,107d
## diffname pc/mouse.c 2000/1006
## diff -e /n/emeliedump/2000/1005/sys/src/9/pc/mouse.c /n/emeliedump/2000/1006/sys/src/9/pc/mouse.c
103a
static int intellimouse;
static int resolution;
static int accelerated;

.
## diffname pc/mouse.c 2000/1012
## diff -e /n/emeliedump/2000/1006/sys/src/9/pc/mouse.c /n/emeliedump/2000/1012/sys/src/9/pc/mouse.c
166a
	packetsize = 3;
.
151a
	packetsize = 4;
.
104,107d
101a
	packetsize = 3;
.
79a
		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;
			}
		}
.
72c
	if(++nb == packetsize){
.
69c
		if(intellimouse && (c==0x00 || c==0x01 || c==0xFF)){
			/* last byte of 4-byte packet */
			packetsize = 4;
			return;
		}
.
60c
	static short msg[4];
.
55a
 *
 * 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.
.
45a
	packetsize = 3;
.
24a
static int intellimouse;
static int packetsize;
static int resolution;
static int accelerated;
.
## diffname pc/mouse.c 2001/0404
## diff -e /n/emeliedump/2000/1012/sys/src/9/pc/mouse.c /n/emeliedump/2001/0404/sys/src/9/pc/mouse.c
79a

	/*
	 * Resynchronize in stream with timing; see comment above.
	 */
	m = MACHP(0)->ticks;
	if(TK2SEC(m - lasttick) > 2)
		nb = 0;
	lasttick = m;
.
78a
	static ulong lasttick;
	ulong m;
.
71a
 *
 * 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.
.
## diffname pc/mouse.c 2001/0527
## diff -e /n/emeliedump/2001/0404/sys/src/9/pc/mouse.c /n/emeliedump/2001/0527/sys/src/9/pc/mouse.c
134c
		mousetrack(dx, dy, buttons, TK2MS(MACHP(0)->ticks));
.
50a
#else
	error("serial mouse not supported yet");
	USED(port, type, setspeed);
#endif /* notdef */
.
48c
		uartspecial(port, setspeed, 0, 0, mouseputc);
.
46c
		uartspecial(port, setspeed, 0, 0, m3mouseputc);
.
35a
#ifdef notdef
.
## diffname pc/mouse.c 2001/1120
## diff -e /n/emeliedump/2001/0527/sys/src/9/pc/mouse.c /n/emeliedump/2001/1120/sys/src/9/pc/mouse.c
274,275d
271,272c
		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;
.
255,263c
		break;
	case CMres:
		if(cb->nf >= 2)
			setres(atoi(cb->f[1]));
		else
			setres(1);
		break;
	case CMreset:
.
252c
		break;
	case CMps2intellimouse:
.
237,250c
	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:
.
235c
mousectl(Cmdbuf *cb)
.
29a
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,
};

.
## diffname pc/mouse.c 2001/1121
## diff -e /n/emeliedump/2001/1120/sys/src/9/pc/mouse.c /n/emeliedump/2001/1121/sys/src/9/pc/mouse.c
309a
	case CMhwaccel:
		if(strcmp(cb->f[1], "on")==0)
			mousehwaccel = 1;
		else if(strcmp(cb->f[1], "off")==0)
			mousehwaccel = 0;
		else
			cmderror(cb, "bad mouse control message");
.
211a
	mouseaccelerate(0);
.
204,210c
	if(mousehwaccel){
		switch(mousetype){
		case MousePS2:
			i8042auxcmd(0xE6);
			return;
		}
.
197a
	mouseaccelerate(x);
.
190,196c
	if(mousehwaccel){
		switch(mousetype){
		case MousePS2:
			i8042auxcmd(0xE7);
			return;
		}
.
185a
/*
 * The PS/2 Trackpoint multiplexor on the IBM Thinkpad T23 ignores
 * acceleration commands.  It is supposed to pass them on
 * to the attached device, but my Logitech mouse is simply
 * not behaving any differently.  For such devices, we allow
 * the user to use "hwaccel off" to tell us to back off to
 * software acceleration even if we're using the PS/2 port.
 * (Serial mice are always software accelerated.)
 * For more information on the Thinkpad multiplexor, see
 * http://wwwcssrv.almaden.ibm.com/trackpoint/
 */
.
183a
	mousehwaccel = 1;
.
44a
	CMhwaccel,		"hwaccel",		2,
.
32a
	CMhwaccel,
.
28a
static int mousehwaccel;
.
## diffname pc/mouse.c 2002/0503
## diff -e /n/emeliedump/2001/1121/sys/src/9/pc/mouse.c /n/emeliedump/2002/0503/sys/src/9/pc/mouse.c
332a

	qunlock(&mousectlqlock);
	poperror();
.
312,323c
		if(mousetype == Mouseserial)
			error(Emouseset);

		if(cb->nf > 2 && *cb->f[2] == 'M')
			i8250mouse(cb->f[1], m3mouseputc, 0);
		else
			i8250mouse(cb->f[1], mouseputc, cb->nf == 1);

		mousetype = Mouseserial;
		packetsize = 3;
.
277a
	qlock(&mousectlqlock);
	if(waserror()){
		qunlock(&mousectlqlock);
		nexterror();
	}

.
58,85d
23a

static QLock mousectlqlock;
.

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.