⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mouse.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#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 QLock mousectlqlock;static int mousetype;static int intellimouse;static int packetsize;static int resolution;static int accelerated;static int mousehwaccel;static char mouseport[5];enum{	CMaccelerated,	CMhwaccel,	CMintellimouse,	CMlinear,	CMps2,	CMps2intellimouse,	CMres,	CMreset,	CMserial,};static Cmdtab mousectlmsg[] ={	CMaccelerated,		"accelerated",		0,	CMhwaccel,		"hwaccel",		2,	CMintellimouse,		"intellimouse",		1,	CMlinear,		"linear",		1,	CMps2,			"ps2",			1,	CMps2intellimouse,	"ps2intellimouse",	1,	CMres,			"res",			0,	CMreset,		"reset",		1,	CMserial,		"serial",		0,};/* *  ps/2 mouse message is three bytes * *	byte 0 -	0 0 SDY SDX 1 M R L *	byte 1 -	DX *	byte 2 -	DY * *  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. */static voidps2mouseputc(int c, int shift){	static short msg[4];	static int nb;	static uchar b[] = {0, 1, 4, 5, 2, 3, 6, 7, 0, 1, 2, 3, 2, 3, 6, 7 };	static ulong lasttick;	ulong m;	int buttons, dx, dy;	/*	 * Resynchronize in stream with timing; see comment above.	 */	m = MACHP(0)->ticks;	if(TK2SEC(m - lasttick) > 2)		nb = 0;	lasttick = m;	/* 	 *  check byte 0 for consistency	 */	if(nb==0 && (c&0xc8)!=0x08)		if(intellimouse && (c==0x00 || c==0x01 || c==0xFF)){			/* last byte of 4-byte packet */			packetsize = 4;			return;		}	msg[nb] = c;	if(++nb == packetsize){		nb = 0;		if(msg[0] & 0x10)			msg[1] |= 0xFF00;		if(msg[0] & 0x20)			msg[2] |= 0xFF00;		buttons = b[(msg[0]&7) | (shift ? 8 : 0)];		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. Furthermore,				 * intellimice with 3buttons + scroll give a				 * two's complement number in the lower 4 bits				 * (bit 4 is sign extension) that describes				 * the amount the scroll wheel has moved during				 * the last sample. Here we use only the sign to				 * decide whether the wheel is moving up or down				 * and generate a single button 4 or 5 click				 * accordingly.				 */				if((msg[3] >> 3) & 1) 					buttons |= 1<<3;				else if(msg[3] & 0x7) 					buttons |= 1<<4;			}		}		dx = msg[1];		dy = -msg[2];		mousetrack(dx, dy, buttons, TK2MS(MACHP(0)->ticks));	}	return;}/* *  set up a ps2 mouse */static voidps2mouse(void){	if(mousetype == MousePS2)		return;	i8042auxenable(ps2mouseputc);	/* make mouse streaming, enabled */	i8042auxcmd(0xEA);	i8042auxcmd(0xF4);	mousetype = MousePS2;	packetsize = 3;	mousehwaccel = 1;}/* * 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/ */static voidsetaccelerated(int x){	accelerated = x;	if(mousehwaccel){		switch(mousetype){		case MousePS2:			i8042auxcmd(0xE7);			return;		}	}	mouseaccelerate(x);}static voidsetlinear(void){	accelerated = 0;	if(mousehwaccel){		switch(mousetype){		case MousePS2:			i8042auxcmd(0xE6);			return;		}	}	mouseaccelerate(0);}static voidsetres(int n){	resolution = n;	switch(mousetype){	case MousePS2:		i8042auxcmd(0xE8);		i8042auxcmd(n);		break;	}}static voidsetintellimouse(void){	intellimouse = 1;	packetsize = 4;	switch(mousetype){	case MousePS2:		i8042auxcmd(0xF3);	/* set sample */		i8042auxcmd(0xC8);		i8042auxcmd(0xF3);	/* set sample */		i8042auxcmd(0x64);		i8042auxcmd(0xF3);	/* set sample */		i8042auxcmd(0x50);		break;	case Mouseserial:		i8250setmouseputc(mouseport, m5mouseputc);		break;	}}static voidresetmouse(void){	packetsize = 3;	switch(mousetype){	case MousePS2:		i8042auxcmd(0xF6);		i8042auxcmd(0xEA);	/* streaming */		i8042auxcmd(0xE8);	/* set resolution */		i8042auxcmd(3);		i8042auxcmd(0xF4);	/* enabled */		break;	}}voidmousectl(Cmdbuf *cb){	Cmdtab *ct;	qlock(&mousectlqlock);	if(waserror()){		qunlock(&mousectlqlock);		nexterror();	}	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:		intellimouse = 0;		ps2mouse();		break;	case CMps2intellimouse:		ps2mouse();		setintellimouse();		break;	case CMres:		if(cb->nf >= 2)			setres(atoi(cb->f[1]));		else			setres(1);		break;	case CMreset:		resetmouse();		if(accelerated)			setaccelerated(accelerated);		if(resolution)			setres(resolution);		if(intellimouse)			setintellimouse();		break;	case CMserial:		if(mousetype == Mouseserial)			error(Emouseset);		if(cb->nf > 2){			if(strcmp(cb->f[2], "M") == 0)				i8250mouse(cb->f[1], m3mouseputc, 0);			else if(strcmp(cb->f[2], "MI") == 0)				i8250mouse(cb->f[1], m5mouseputc, 0);			else				i8250mouse(cb->f[1], mouseputc, cb->nf == 1);		} else			i8250mouse(cb->f[1], mouseputc, cb->nf == 1);		mousetype = Mouseserial;		strncpy(mouseport, cb->f[1], sizeof(mouseport)-1);		packetsize = 3;		break;	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");	}	qunlock(&mousectlqlock);	poperror();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -