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

📄 ms.c

📁 早期freebsd实现
💻 C
字号:
/* * Copyright (c) 1992, 1993 *	The Regents of the University of California.  All rights reserved. * * This code is derived from software contributed to Berkeley by * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * from: $Hdr: ms.c,v 4.300 91/06/09 06:22:04 root Rel41 $ SONY * *	@(#)ms.c	8.1 (Berkeley) 6/11/93 */#include "ms.h"#if NMS > 0/* * mouse  */#include <sys/types.h>#include <machine/cpu.h>#include <machine/pte.h>#include <sys/param.h>#include <sys/proc.h>#include <sys/user.h>#include <sys/buf.h>#include <sys/malloc.h>#include <sys/systm.h>#include <sys/uio.h>#include <sys/kernel.h>#include <sys/file.h>#include <news3400/iop/mouse.h>#include <news3400/iop/msreg.h>#include <news3400/sio/scc.h>#include <news3400/hbdev/hbvar.h>#ifndef mips#define volatile#endifstruct ms_stat	 ms_stat[NMS];int	msprobe(), msattach();struct hb_device   *msinfo[NMS];struct hb_driver   msdriver = {	msprobe, 0, msattach, 0, 0, "ms", msinfo, "mc", 0, 0};extern int tty00_is_console;#ifdef news3400#define	splms		spl4#else#define	splms		spl5#endif/*ARGSUSED*/msprobe(ii)	struct hb_device *ii;{	return(sizeof(struct ms_stat));}/*ARGSUSED*/msattach(ii)	struct hb_device *ii;{}/* queue structure operators */msq_init(unit)	int unit;{	register volatile struct ms_queue *q = ms_stat[unit].mss_queue;	q->mq_head = q->mq_tail = 0;}intmsq_stat(unit)	int unit;{	register volatile struct ms_queue *q = ms_stat[unit].mss_queue;	while (q->mq_head != q->mq_tail) {		if (!q->mq_queue[q->mq_head].mse_inval)			break;		q->mq_head = ++q->mq_head % MS_MAXREPORT;	}	return (q->mq_head != q->mq_tail);}struct ms_event *msq_read(unit)	int unit;{	register volatile struct ms_queue *q = ms_stat[unit].mss_queue;	register struct ms_event *data;	while (q->mq_head != q->mq_tail && q->mq_queue[q->mq_head].mse_inval)		q->mq_head = ++q->mq_head % MS_MAXREPORT;	if (q->mq_head == q->mq_tail) {		data = NULL;	} else {		data = q->mq_queue + q->mq_head++;		q->mq_head %= MS_MAXREPORT;	}	return (data);}struct ms_event *msq_write(unit)	int unit;{	register volatile struct ms_queue *q = ms_stat[unit].mss_queue;	register struct ms_event *data = q->mq_queue + q->mq_tail;	register int new;	/* if queue is full, newest data is gone away */	new = (q->mq_tail + 1) % MS_MAXREPORT;	if (new != q->mq_head)		q->mq_tail = new;	return (data);}msq_flush(unit, trig)	int unit;	char trig;{	register volatile struct ms_queue *q = ms_stat[unit].mss_queue;	register int i;	i = q->mq_head;	while (i != q->mq_tail) {		if (q->mq_queue[i].mse_trig == trig)			q->mq_queue[i].mse_inval = -1;		i = ++i % MS_MAXREPORT;	}}/* * Mouse open function. */msopen(dev, flag)	dev_t dev;	int flag;{	register int unit = MSUNIT(dev);	register struct ms_stat *ms = &ms_stat[unit];	register struct hb_device *ii = msinfo[unit];	static struct ms_coord initxy = { 0, 0 };	/* check device */	if (unit < 0 || unit >= NMS || ii == NULL || ii->hi_alive == 0)		return(ENXIO);	/* check duplicable open */	if (ms->mss_stat & MS_ACTIVE)		return(EBUSY);	ms->mss_queue = malloc(sizeof(struct ms_queue), M_DEVBUF, M_WAITOK);	if (ms->mss_queue == NULL)		return (ENOMEM);	msq_init(unit);	ms->mss_mode = flag;	ms->mss_stat = MS_ACTIVE;	/* communicate to IOP .. clear event mask, set initial xy. */	ms->mss_eventmask = 0;	ms->mss_data.md_sw = 0;			/* XXX */	ms->mss_data.md_x = 0;	ms->mss_data.md_y = 0;	ms->mss_param.mp_delta = 5;	ms->mss_param.mp_mag = 3;	ms->mss_range.mr_min.mc_x = 0x80000000;	ms->mss_range.mr_min.mc_y = 0x80000000;	ms->mss_range.mr_max.mc_x = 0x7fffffff;	ms->mss_range.mr_max.mc_y = 0x7fffffff;	if (curproc->p_pgrp->pg_id == 0) {		if (ms->mss_pgrp == 0)			ms->mss_pgrp = curproc->p_pid;		curproc->p_pgrp->pg_id = ms->mss_pgrp;	}	if (tty00_is_console)		kbm_open(SCC_KEYBOARD);	kbm_open(SCC_MOUSE);	return (0);}/* * Mouse close function. *//*ARGSUSED*/msclose(dev, flag)	dev_t dev;	int flag;{	int unit = MSUNIT(dev);	register struct ms_stat	*ms = &ms_stat[unit];	register struct hb_device *ii = msinfo[unit];	/* check unit no. */	if (unit < 0 || unit >= NMS || ii == NULL || ii->hi_alive == 0)		return ENXIO;	/* check status */	if (!(ms->mss_stat & MS_ACTIVE))		return ENXIO;	/* clear eventmask and status */	ms->mss_stat = 0;	ms->mss_eventmask = 0;	free(ms->mss_queue, M_DEVBUF);	ms->mss_pgrp = 0;	if (tty00_is_console)		kbm_close(SCC_KEYBOARD);	kbm_close(SCC_MOUSE);	return (0);}/* * Mouse read function. */msread(dev, uio, flag)	dev_t dev;	struct uio *uio;	int flag;{	register int unit = MSUNIT(dev);	register struct ms_stat *ms = &ms_stat[unit];	register struct hb_device *ii = msinfo[unit];	register volatile struct ms_event *data;	struct ms_data xy;	int s, error;	/* check argument */	if (unit < 0 || unit >= NMS || ii == NULL || ii->hi_alive == 0)		return ENXIO;	/* event mode -> waiting */	if (ms->mss_eventmask & MS_EMEVENT) {		s = splms();		if (msq_stat(unit) == 0 && (ms->mss_stat & MS_NBIO)) {			splx(s);			return (EWOULDBLOCK);		}		while (msq_stat(unit) == 0) {			ms->mss_stat |= MS_EVWAIT;			sleep((caddr_t)&ms->mss_queue, MSPRI);			ms->mss_stat &= ~MS_EVWAIT;		}		splx(s);		if(MSOLDIF(dev)) {			while ((data = msq_read(unit)) != NULL &&			    uio->uio_resid >= sizeof(struct ms_data)) {				error = uiomove((caddr_t)&data->mse_data,						sizeof(struct ms_data), uio);				if (error)					return error;			}		} else {			while ((data = msq_read(unit)) != NULL &&			    uio->uio_resid >= sizeof(struct ms_event)) {				error = uiomove((caddr_t)data,						sizeof(struct ms_event), uio);				if (error)					return error;			}		}	} else {		while (uio->uio_resid >= sizeof(struct ms_data)) {			s = splms();			xy = ms->mss_data;			splx(s);			error = uiomove((caddr_t)&xy,					sizeof(struct ms_data), uio);			if (error)				return error;		}	}	return 0;}/* * Mouse write function */mswrite(dev, uio, flag)	dev_t dev;	struct uio *uio;	int flag;{	register int unit = MSUNIT(dev);	register struct ms_stat *ms = &ms_stat[unit];	register struct hb_device *ii = msinfo[unit];	struct ms_coord xy;	register int s, error;	/* check argument */	if (unit < 0 || unit >= NMS || ii == NULL || ii->hi_alive == 0)		return ENXIO;	while (uio->uio_resid >= sizeof(struct ms_coord)) {		error = uiomove((caddr_t)&xy, sizeof(xy), uio);		if (error)			return error;		s = splms();		ms->mss_data.md_x = xy.mc_x;		ms->mss_data.md_y = xy.mc_y;		splx(s);		lock_bitmap();		updateCursor(&ms->mss_data.md_x, &ms->mss_data.md_y, 1);		unlock_bitmap();	}	return 0;}/* * Mouse I/O control function *//*ARGSUSED*/msioctl(dev, cmd, data, flag)	dev_t dev;	int cmd;	caddr_t data;	int flag;{	register int unit = MSUNIT(dev);	register struct ms_stat *ms = &ms_stat[unit];	register struct hb_device *ii = msinfo[unit];	register int s;	if (unit < 0 || unit >= NMS || ii == NULL || ii->hi_alive == 0)		return EIO;	s = splms();	switch (cmd) {	case MSIOCGETEM:		(*(int*)data) = ms->mss_eventmask;		break;	case MSIOCSETEM:		ms->mss_eventmask = *(int *)data;		break;	case MSIOCSETXY:		ms->mss_data.md_x = ((struct ms_coord*)data)->mc_x;		ms->mss_data.md_y = ((struct ms_coord*)data)->mc_y;		lock_bitmap();		updateCursor(&ms->mss_data.md_x, &ms->mss_data.md_y, 1);		unlock_bitmap();		msq_flush(unit, MSE_MOTION);		break;	case MSIOCFLUSH:		msq_init(unit);		break;	case MSIOCSETPARAM:		ms->mss_param = *(struct ms_param*)data;		break;	case MSIOCSETRANGE:		ms->mss_range = *(struct ms_range*)data;		break;	case FIONBIO:		if (*(int *)data)			ms->mss_stat |= MS_NBIO;		else			ms->mss_stat &= ~MS_NBIO;		break;	case FIOASYNC:		if (*(int *)data)			ms->mss_stat |= MS_ASYNC;		else			ms->mss_stat &= ~MS_ASYNC;		break;	case TIOCSPGRP:		ms->mss_pgrp = *(int *)data;		break;	case TIOCGPGRP:		*(int *)data = ms->mss_pgrp;		break;	default:		splx(s);		return ENOTTY;	}	splx(s);	return 0;}msselect(dev, flag)	dev_t dev;	int flag;{	register int unit = MSUNIT(dev);	register struct ms_stat *ms;		int s;	if (unit < 0 || unit >= NMS)		return(0);	s = splms();	ms = &ms_stat[unit];	switch(flag) {	case FREAD:		if (!(ms->mss_eventmask & MS_EMEVENT))			goto win;		if(msq_stat(unit))			goto win;		if (ms->mss_rsel && ms->mss_rsel->p_wchan == (caddr_t)&selwait)			ms->mss_stat |= MS_RCOLL;		else			ms->mss_rsel = curproc;		break;	case FWRITE:		goto win;	}	splx(s);	return(0);win:	splx(s);	return(1);}msselwakeup(ms)	register struct ms_stat *ms;	{	if (ms->mss_rsel) {		selwakeup(ms->mss_rsel, ms->mss_stat&MS_RCOLL);		ms->mss_stat &= ~MS_RCOLL;		ms->mss_rsel = 0;	}	if (ms->mss_stat & MS_ASYNC)		gsignal(ms->mss_pgrp, SIGIO);}mssint(){	printf("mssint\n");}msputevent(unit, trig, dir, code)	int unit, trig, dir, code;{	register struct ms_stat *ms = &ms_stat[unit];	register volatile struct ms_event *me;	register int s;	me = msq_write(unit);	s = splclock();	me->mse_time = time;	me->mse_inval = 0;	splx(s);	me->mse_trig = trig;	me->mse_dir = dir;	me->mse_code = code;	me->mse_data = ms->mss_data;	if (ms->mss_stat & MS_EVWAIT)		wakeup((caddr_t)&ms->mss_queue);	msselwakeup(ms);	return (0);}/* * for keyboard */mskeytrigger(unit, up, keycode)	int unit;	int up;	int keycode;{	register struct ms_stat *ms = &ms_stat[unit];	if((ms->mss_eventmask & MS_EMEVENT) == 0)		return 0;	if((ms->mss_eventmask & MS_EMKEY) == 0)		return 0;	(void) msputevent(unit, MSE_KEY, up ? MSE_UP : MSE_DOWN, keycode);	return 1;}/* * msconv - convert mouse hardware reports(3 bytes) into internal mouse data *		it leaves the old mouse data in ms_data_old and *		new mouse data in ms_data. */msconv(unit, rep)	int unit;	register char rep[];{	register struct ms_stat *ms = &ms_stat[unit];	register int s_byte;	register int sw = 0;	register int dx, dy;	int adx, ady;	ms->mss_data_old = ms->mss_data;	/* switch status */	s_byte = rep[MS_S_BYTE];	if (s_byte & MS_S_SW1)		sw |= MS_BUTNL;	if (s_byte & MS_S_SW2)		sw |= MS_BUTNR;	if (s_byte & MS_S_SW3)		sw |= MS_BUTNM;	ms->mss_data.md_sw = sw;	/* delta x */	dx = rep[MS_X_BYTE] & MS_X_X06;	if (s_byte & MS_S_X7)		dx = (~0&~MS_X_X06)|dx;	dy = rep[MS_Y_BYTE] & MS_Y_Y06;	if (s_byte & MS_S_Y7)		dy = (~0&~MS_Y_Y06)|dy;#define ABS(x)	((x)>=0 ? (x) : -(x))	adx = ABS(dx);	ady = ABS(dy);#undef ABS	if (adx > ms->mss_param.mp_delta) {		adx = ms->mss_param.mp_delta +		      (adx - ms->mss_param.mp_delta) * ms->mss_param.mp_mag;		if (dx < 0)			dx = -adx;		else			dx = adx;	}	if (ady > ms->mss_param.mp_delta) {		ady = ms->mss_param.mp_delta +		      (ady - ms->mss_param.mp_delta) * ms->mss_param.mp_mag;		if (dy < 0)			dy = -ady;		else			dy = ady;	}	ms->mss_data.md_x += dx;	ms->mss_data.md_y += dy;	if (dx > 0)		ms->mss_data.md_x = min(ms->mss_data.md_x,					ms->mss_range.mr_max.mc_x);	else		ms->mss_data.md_x = max(ms->mss_data.md_x,					ms->mss_range.mr_min.mc_x);	if (dy > 0)		ms->mss_data.md_y = min(ms->mss_data.md_y,					ms->mss_range.mr_max.mc_y);	else		ms->mss_data.md_y = max(ms->mss_data.md_y,					ms->mss_range.mr_min.mc_y);	if (dx != 0 || dy != 0)		updateCursor(&ms->mss_data.md_x, &ms->mss_data.md_y, 0);}mscheckevent(unit)	int unit;{	register struct ms_stat *ms = &ms_stat[unit];	register int i;	register int changebits;	register int dir;	if ((ms->mss_eventmask & MS_EMEVENT) == 0)		return;	if (ms->mss_data_old.md_sw != ms->mss_data.md_sw) {		changebits = (ms->mss_data_old.md_sw ^ ms->mss_data.md_sw);		changebits &= ms->mss_eventmask;		for(i = 0; i < 3; i++) {			if(changebits & (1 << i)) {				if((1 << i) & ms->mss_data.md_sw)					dir = MSE_DOWN;				else					dir = MSE_UP;				msputevent(unit, MSE_BUTTON, dir, i);			}		}	}	if ((ms->mss_eventmask & MS_EMMOTION) &&	    (ms->mss_data_old.md_x != ms->mss_data.md_x ||	     ms->mss_data_old.md_y != ms->mss_data.md_y)) {		msputevent(unit, MSE_MOTION, 0, 0);		return;	}}/* * _ms_helper - open the mouse line and read mouse data and *		convert them into mouse data (events) */_ms_helper(unit)	int unit;{	register int c;	static int counter = 0;	static char buf[MS_DB_SIZE];#ifdef notyet /* KU:XXX */	intrcnt[INTR_MOUSE]++;#endif#if NBM > 0	rst_dimmer_cnt();#endif	while ((c = xgetc(SCC_MOUSE)) >= 0) {		if (c & MS_S_MARK)			counter = 0;		buf[counter] = c;		if (++counter == 3) {			msconv(unit, buf);			mscheckevent(unit);			counter = 0;		}	}}#endif /* NMS > 0 */

⌨️ 快捷键说明

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