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

📄 mou_ser.c

📁 神龙卡开发原代码
💻 C
字号:
/* * Copyright (c) 1999, 2000 Greg Haerr <greg@censoft.com> * Portions Copyright (c) 1991 David I. Bell * Permission is granted to use, distribute, or modify this source, * provided that this copyright notice remains intact. * * UNIX Serial Port Mouse Driver *  * This driver opens a serial port directly, and interprets serial data. * Microsoft, PC, Logitech and PS/2 mice are supported. * The PS/2 mouse is supported by using the /dev/psaux device. * * The following environment variables control the mouse type expected * and the serial port to open. * * Environment Var	Default		Allowed * MOUSE_TYPE		pc		ms, pc, logi, ps2 * MOUSE_PORT		/dev/ttyS1	any serial port or /dev/psaux */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <fcntl.h>#include <string.h>#include "device.h"#define TERMIOS		1	/* set to use termios serial port control*/#define SGTTY		0	/* set to use sgtty serial port control*/#define	SCALE		3	/* default scaling factor for acceleration */#define	THRESH		5	/* default threshhold for acceleration */#if TERMIOS#include <termios.h>#endif#if SGTTY#include <sgtty.h>#endif/* default settings*/#if _MINIX#define	MOUSE_PORT	"/dev/mouse"#define	MOUSE_TYPE	"ms"#else#if ELKS#define	MOUSE_PORT	"/dev/ttys0"	/* default mouse tty port */#else#define	MOUSE_PORT	"/dev/ttyS1"	/* default mouse tty port */#endif#define	MOUSE_TYPE	"pc"		/* default mouse type "ms","pc","ps2" */#endif#define MAX_BYTES	128		/* number of bytes for buffer *//* states for the mouse*/#define	IDLE			0		/* start of byte sequence */#define	XSET			1		/* setting x delta */#define	YSET			2		/* setting y delta */#define	XADD			3		/* adjusting x delta */#define	YADD			4		/* adjusting y delta *//* values in the bytes returned by the mouse for the buttons*/#define	PC_LEFT_BUTTON		4#define PC_MIDDLE_BUTTON	2#define PC_RIGHT_BUTTON		1#define	MS_LEFT_BUTTON		2#define MS_RIGHT_BUTTON		1#define PS2_CTRL_BYTE		0x08#define PS2_LEFT_BUTTON		1#define PS2_RIGHT_BUTTON	2/* Bit fields in the bytes sent by the mouse.*/#define TOP_FIVE_BITS		0xf8#define BOTTOM_THREE_BITS	0x07#define TOP_BIT			0x80#define SIXTH_BIT		0x40#define BOTTOM_TWO_BITS		0x03#define THIRD_FOURTH_BITS	0x0c#define BOTTOM_SIX_BITS  	0x3f/* local data*/static int		mouse_fd;	/* file descriptor for mouse */static int		state;		/* IDLE, XSET, ... */static int		buttons;	/* current mouse buttons pressed*/static int		availbuttons;	/* which buttons are available */static MWCOORD		xd;		/* change in x */static MWCOORD		yd;		/* change in y */static int		left;		/* because the button values change */static int		middle;		/* between mice, the buttons are */static int		right;		/* redefined */static unsigned char	*bp;		/* buffer pointer */static int		nbytes;		/* number of bytes left */static unsigned char	buffer[MAX_BYTES];	/* data bytes read */static int		(*parse)();	/* parse routine *//* local routines*/static int  	MOU_Open(MOUSEDEVICE *pmd);static void 	MOU_Close(void);static int  	MOU_GetButtonInfo(void);static void	MOU_GetDefaultAccel(int *pscale,int *pthresh);static int  	MOU_Read(MWCOORD *dx, MWCOORD *dy, MWCOORD *dz, int *bptr);static int	MOU_Poll(void);static int  	ParsePC(int);		/* routine to interpret PC mouse */static int  	ParseMS(int);		/* routine to interpret MS mouse */static int  	ParsePS2(int);		/* routine to interpret PS/2 mouse */MOUSEDEVICE mousedev = {	MOU_Open,	MOU_Close,	MOU_GetButtonInfo,	MOU_GetDefaultAccel,	MOU_Read,#if _MINIX	MOU_Poll#else	NULL#endif};/* * Open up the mouse device. * Returns the fd if successful, or negative if unsuccessful. */static intMOU_Open(MOUSEDEVICE *pmd){	char	*type;	char	*port;	struct termios termios;	/* get mouse type and port*/	if( !(type = getenv("MOUSE_TYPE")))		type = MOUSE_TYPE;	if( !(port = getenv("MOUSE_PORT")))		port = MOUSE_PORT;	/* set button bits and parse procedure*/	if(!strcmp(type, "pc") || !strcmp(type, "logi")) {		/* pc or logitech mouse*/		left = PC_LEFT_BUTTON;		middle = PC_MIDDLE_BUTTON;		right = PC_RIGHT_BUTTON;		parse = ParsePC;	} else if (strcmp(type, "ms") == 0) {		/* microsoft mouse*/		left = MS_LEFT_BUTTON;		right = MS_RIGHT_BUTTON;		middle = 0;		parse = ParseMS;	} else if (strcmp(type, "ps2") == 0) {		/* PS/2 mouse*/		left = PS2_LEFT_BUTTON;		right = PS2_RIGHT_BUTTON;		middle = 0;		parse = ParsePS2;	} else		return -1;	/* open mouse port*/	mouse_fd = open(port, O_NONBLOCK);	if (mouse_fd < 0) {		EPRINTF("Error %d opening serial mouse type %s on port %s.\n",			errno, type, port); 		return -1;	}#if SGTTY	/* set rawmode serial port using sgtty*/	struct sgttyb sgttyb;	if (ioctl(fd, TIOCGETP, &sgttyb) == -1)		goto err;	sgttyb.sg_flags |= RAW;	sgttyb.sg_flags &= ~(EVENP | ODDP | ECHO | XTABS | CRMOD);	if (ioctl(fd, TIOCSETP, &sgttyb) == -1)		goto err;	if (ioctl(fd, TIOCFLUSH, 0) < 0)		goto err;#endif#if TERMIOS	/*	 * Note we don't check success for the tcget/setattr calls,	 * some kernels don't support them for certain devices	 * (like /dev/psaux).	 */	/* set rawmode serial port using termios*/	tcgetattr(mouse_fd, &termios);	/* These functions appear to be broken in ELKS Dev86 */	if(cfgetispeed(&termios) != B1200)		cfsetispeed(&termios, B1200);#if _MINIX	if(cfgetospeed(&termios) != B1200)		cfsetospeed(&termios, B1200);#endif#if !_MINIX	termios.c_cflag &= ~CBAUD;	termios.c_cflag |= B1200;#endif	termios.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);	termios.c_iflag &= ~(ICRNL | INPCK | ISTRIP | IXON | BRKINT | IGNBRK);	termios.c_cflag &= ~(CSIZE | PARENB);	termios.c_cflag |= CS8;	termios.c_cc[VMIN] = 0;	termios.c_cc[VTIME] = 0;	tcsetattr(mouse_fd, TCSAFLUSH, &termios);#endif /* TERMIOS*/	/* initialize data*/	availbuttons = left | middle | right;	state = IDLE;	nbytes = 0;	buttons = 0;	xd = 0;	yd = 0;	return mouse_fd;err:	close(mouse_fd);	mouse_fd = 0;	return -1;}/* * Close the mouse device. */static voidMOU_Close(void){	if (mouse_fd > 0) {		close(mouse_fd);	}	mouse_fd = 0;}/* * Get mouse buttons supported */static intMOU_GetButtonInfo(void){	return availbuttons;}/* * Get default mouse acceleration settings */static voidMOU_GetDefaultAccel(int *pscale,int *pthresh){	*pscale = SCALE;	*pthresh = THRESH;}/* * Attempt to read bytes from the mouse and interpret them. * Returns -1 on error, 0 if either no bytes were read or not enough * was read for a complete state, or 1 if the new state was read. * When a new state is read, the current buttons and x and y deltas * are returned.  This routine does not block. */static intMOU_Read(MWCOORD *dx, MWCOORD *dy, MWCOORD *dz, int *bptr){	int	b;	/*	 * If there are no more bytes left, then read some more,	 * waiting for them to arrive.  On a signal or a non-blocking	 * error, return saying there is no new state available yet.	 */	if (nbytes <= 0) {		bp = buffer;		nbytes = read(mouse_fd, bp, MAX_BYTES);		if (nbytes < 0) {			if (errno == EINTR || errno == EAGAIN)				return 0;#if _MINIX			return 0;#else			return -1;#endif		}	}	/*	 * Loop over all the bytes read in the buffer, parsing them.	 * When a complete state has been read, return the results,	 * leaving further bytes in the buffer for later calls.	 */	while (nbytes-- > 0) {		if ((*parse)((int) *bp++)) {			*dx = xd;			*dy = yd;			*dz = 0;			b = 0;			if(buttons & left)				b |= MWBUTTON_L;			if(buttons & right)				b |= MWBUTTON_R;			if(buttons & middle)				b |= MWBUTTON_M;			*bptr = b;			return 1;		}	}	return 0;}/* * Input routine for PC mouse. * Returns nonzero when a new mouse state has been completed. */static intParsePC(int byte){	int	sign;			/* sign of movement */	switch (state) {		case IDLE:			if ((byte & TOP_FIVE_BITS) == TOP_BIT) {				buttons = ~byte & BOTTOM_THREE_BITS;				state = XSET;			}			break;		case XSET:			sign = 1;			if (byte > 127) {				byte = 256 - byte;				sign = -1;			}			xd = byte * sign;			state = YSET;			break;		case YSET:			sign = 1;			if (byte > 127) {				byte = 256 - byte;				sign = -1;			}			yd = -byte * sign;			state = XADD;			break;		case XADD:			sign = 1;			if (byte > 127) {				byte = 256 - byte;				sign = -1;			}			xd += byte * sign;			state = YADD;			break;		case YADD:			sign = 1;			if (byte > 127) {				byte = 256 - byte;				sign = -1;			}			yd -= byte * sign;			state = IDLE;			return 1;	}	return 0;}/* * Input routine for Microsoft mouse. * Returns nonzero when a new mouse state has been completed. */static intParseMS(int byte){	switch (state) {		case IDLE:			if (byte & SIXTH_BIT) {				buttons = (byte >> 4) & BOTTOM_TWO_BITS;				yd = ((byte & THIRD_FOURTH_BITS) << 4);				xd = ((byte & BOTTOM_TWO_BITS) << 6);				state = XADD;			}			break;		case XADD:			xd |= (byte & BOTTOM_SIX_BITS);			state = YADD;			break;		case YADD:			yd |= (byte & BOTTOM_SIX_BITS);			state = IDLE;			if (xd > 127)				xd -= 256;			if (yd > 127)				yd -= 256;			return 1;	}	return 0;}/* * Input routine for PS/2 mouse. * Returns nonzero when a new mouse state has been completed. */static intParsePS2(int byte){	switch (state) {		case IDLE:			if (byte & PS2_CTRL_BYTE) {				buttons = byte & 					(PS2_LEFT_BUTTON|PS2_RIGHT_BUTTON);				state = XSET;			}			break;		case XSET:			if(byte > 127)				byte -= 256;			xd = byte;			state = YSET;			break;		case YSET:			if(byte > 127)				byte -= 256;			yd = -byte;			state = IDLE;			return 1;	}	return 0;}static intMOU_Poll(void){	return 1;	/* used by _MINIX only*/}/*  #define TEST 1  */#if TESTmain(){	MWCOORD x, y, z;	int	b;	DPRINTF("Open Mouse\n");	if( MOU_Open(0) < 0)		DPRINTF("open failed mouse\n" );	while(1) 	{		if(MOU_Read(&x, &y, &z, &b) == 1) 		{	     		DPRINTF("%d,%d,%d\n", x, y, b);		}	}}#endif

⌨️ 快捷键说明

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