xref: /csrg-svn/sys/news3400/hbdev/ms.c (revision 63304)
153895Smckusick /*
2*63304Sbostic  * Copyright (c) 1992, 1993
3*63304Sbostic  *	The Regents of the University of California.  All rights reserved.
453895Smckusick  *
553895Smckusick  * This code is derived from software contributed to Berkeley by
653895Smckusick  * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
753895Smckusick  *
853895Smckusick  * %sccs.include.redist.c%
953895Smckusick  *
1053895Smckusick  * from: $Hdr: ms.c,v 4.300 91/06/09 06:22:04 root Rel41 $ SONY
1153895Smckusick  *
12*63304Sbostic  *	@(#)ms.c	8.1 (Berkeley) 06/11/93
1353895Smckusick  */
1453895Smckusick 
1557179Sutashiro #include "ms.h"
1653895Smckusick #if NMS > 0
1753895Smckusick /*
1853895Smckusick  * mouse
1953895Smckusick  */
2053895Smckusick 
2157179Sutashiro #include <sys/types.h>
2257179Sutashiro #include <machine/cpu.h>
2357179Sutashiro #include <machine/pte.h>
2457179Sutashiro #include <sys/param.h>
2557179Sutashiro #include <sys/proc.h>
2657179Sutashiro #include <sys/user.h>
2757179Sutashiro #include <sys/buf.h>
2857179Sutashiro #include <sys/malloc.h>
2957179Sutashiro #include <sys/systm.h>
3057179Sutashiro #include <sys/uio.h>
3157179Sutashiro #include <sys/kernel.h>
3257179Sutashiro #include <sys/file.h>
3353895Smckusick 
3457179Sutashiro #include <news3400/iop/mouse.h>
3557179Sutashiro #include <news3400/iop/msreg.h>
3653895Smckusick 
3757179Sutashiro #include <news3400/sio/scc.h>
3857179Sutashiro #include <news3400/hbdev/hbvar.h>
3953895Smckusick 
4053895Smckusick #ifndef mips
4153895Smckusick #define volatile
4258611Sutashiro #endif
4353895Smckusick 
4453895Smckusick struct ms_stat	 ms_stat[NMS];
4553895Smckusick 
4653895Smckusick int	msprobe(), msattach();
4753895Smckusick 
4853895Smckusick struct hb_device   *msinfo[NMS];
4953895Smckusick struct hb_driver   msdriver = {
5053895Smckusick 	msprobe, 0, msattach, 0, 0, "ms", msinfo, "mc", 0, 0
5153895Smckusick };
5253895Smckusick 
5353895Smckusick extern int tty00_is_console;
5453895Smckusick 
5553895Smckusick #ifdef news3400
5653895Smckusick #define	splms		spl4
5758611Sutashiro #else
5853895Smckusick #define	splms		spl5
5958611Sutashiro #endif
6053895Smckusick 
6153895Smckusick /*ARGSUSED*/
6253895Smckusick msprobe(ii)
6353895Smckusick 	struct hb_device *ii;
6453895Smckusick {
6553895Smckusick 	return(sizeof(struct ms_stat));
6653895Smckusick }
6753895Smckusick 
6853895Smckusick /*ARGSUSED*/
6953895Smckusick msattach(ii)
7053895Smckusick 	struct hb_device *ii;
7153895Smckusick {
7253895Smckusick 
7353895Smckusick }
7453895Smckusick 
7553895Smckusick /* queue structure operators */
7653895Smckusick 
msq_init(unit)7753895Smckusick msq_init(unit)
7853895Smckusick 	int unit;
7953895Smckusick {
8053895Smckusick 	register volatile struct ms_queue *q = ms_stat[unit].mss_queue;
8153895Smckusick 
8253895Smckusick 	q->mq_head = q->mq_tail = 0;
8353895Smckusick }
8453895Smckusick 
8553895Smckusick int
msq_stat(unit)8653895Smckusick msq_stat(unit)
8753895Smckusick 	int unit;
8853895Smckusick {
8953895Smckusick 	register volatile struct ms_queue *q = ms_stat[unit].mss_queue;
9053895Smckusick 
9153895Smckusick 	while (q->mq_head != q->mq_tail) {
9253895Smckusick 		if (!q->mq_queue[q->mq_head].mse_inval)
9353895Smckusick 			break;
9453895Smckusick 		q->mq_head = ++q->mq_head % MS_MAXREPORT;
9553895Smckusick 	}
9653895Smckusick 	return (q->mq_head != q->mq_tail);
9753895Smckusick }
9853895Smckusick 
9953895Smckusick struct ms_event *
msq_read(unit)10053895Smckusick msq_read(unit)
10153895Smckusick 	int unit;
10253895Smckusick {
10353895Smckusick 	register volatile struct ms_queue *q = ms_stat[unit].mss_queue;
10458611Sutashiro 	register struct ms_event *data;
10553895Smckusick 
10653895Smckusick 	while (q->mq_head != q->mq_tail && q->mq_queue[q->mq_head].mse_inval)
10753895Smckusick 		q->mq_head = ++q->mq_head % MS_MAXREPORT;
10853895Smckusick 	if (q->mq_head == q->mq_tail) {
10953895Smckusick 		data = NULL;
11053895Smckusick 	} else {
11153895Smckusick 		data = q->mq_queue + q->mq_head++;
11253895Smckusick 		q->mq_head %= MS_MAXREPORT;
11353895Smckusick 	}
11453895Smckusick 	return (data);
11553895Smckusick }
11653895Smckusick 
11753895Smckusick struct ms_event *
msq_write(unit)11853895Smckusick msq_write(unit)
11953895Smckusick 	int unit;
12053895Smckusick {
12153895Smckusick 	register volatile struct ms_queue *q = ms_stat[unit].mss_queue;
12258611Sutashiro 	register struct ms_event *data = q->mq_queue + q->mq_tail;
12353895Smckusick 	register int new;
12453895Smckusick 
12553895Smckusick 	/* if queue is full, newest data is gone away */
12653895Smckusick 	new = (q->mq_tail + 1) % MS_MAXREPORT;
12753895Smckusick 	if (new != q->mq_head)
12853895Smckusick 		q->mq_tail = new;
12953895Smckusick 	return (data);
13053895Smckusick }
13153895Smckusick 
msq_flush(unit,trig)13253895Smckusick msq_flush(unit, trig)
13353895Smckusick 	int unit;
13453895Smckusick 	char trig;
13553895Smckusick {
13653895Smckusick 	register volatile struct ms_queue *q = ms_stat[unit].mss_queue;
13753895Smckusick 	register int i;
13853895Smckusick 
13953895Smckusick 	i = q->mq_head;
14053895Smckusick 	while (i != q->mq_tail) {
14153895Smckusick 		if (q->mq_queue[i].mse_trig == trig)
14253895Smckusick 			q->mq_queue[i].mse_inval = -1;
14353895Smckusick 		i = ++i % MS_MAXREPORT;
14453895Smckusick 	}
14553895Smckusick }
14653895Smckusick 
14753895Smckusick /*
14853895Smckusick  * Mouse open function.
14953895Smckusick  */
msopen(dev,flag)15053895Smckusick msopen(dev, flag)
15153895Smckusick 	dev_t dev;
15253895Smckusick 	int flag;
15353895Smckusick {
15453895Smckusick 	register int unit = MSUNIT(dev);
15553895Smckusick 	register struct ms_stat *ms = &ms_stat[unit];
15653895Smckusick 	register struct hb_device *ii = msinfo[unit];
15753895Smckusick 	static struct ms_coord initxy = { 0, 0 };
15853895Smckusick 
15953895Smckusick 	/* check device */
16053895Smckusick 	if (unit < 0 || unit >= NMS || ii == NULL || ii->hi_alive == 0)
16153895Smckusick 		return(ENXIO);
16253895Smckusick 
16353895Smckusick 	/* check duplicable open */
16453895Smckusick 	if (ms->mss_stat & MS_ACTIVE)
16553895Smckusick 		return(EBUSY);
16653895Smckusick 
16753895Smckusick 	ms->mss_queue = malloc(sizeof(struct ms_queue), M_DEVBUF, M_WAITOK);
16853895Smckusick 	if (ms->mss_queue == NULL)
16953895Smckusick 		return (ENOMEM);
17053895Smckusick 	msq_init(unit);
17153895Smckusick 	ms->mss_mode = flag;
17253895Smckusick 	ms->mss_stat = MS_ACTIVE;
17353895Smckusick 
17453895Smckusick 	/* communicate to IOP .. clear event mask, set initial xy. */
17553895Smckusick 	ms->mss_eventmask = 0;
17653895Smckusick 	ms->mss_data.md_sw = 0;			/* XXX */
17753895Smckusick 	ms->mss_data.md_x = 0;
17853895Smckusick 	ms->mss_data.md_y = 0;
17953895Smckusick 	ms->mss_param.mp_delta = 5;
18053895Smckusick 	ms->mss_param.mp_mag = 3;
18153895Smckusick 	ms->mss_range.mr_min.mc_x = 0x80000000;
18253895Smckusick 	ms->mss_range.mr_min.mc_y = 0x80000000;
18353895Smckusick 	ms->mss_range.mr_max.mc_x = 0x7fffffff;
18453895Smckusick 	ms->mss_range.mr_max.mc_y = 0x7fffffff;
18553895Smckusick 
18653895Smckusick 	if (curproc->p_pgrp->pg_id == 0) {
18753895Smckusick 		if (ms->mss_pgrp == 0)
18853895Smckusick 			ms->mss_pgrp = curproc->p_pid;
18953895Smckusick 		curproc->p_pgrp->pg_id = ms->mss_pgrp;
19053895Smckusick 	}
19153895Smckusick 	if (tty00_is_console)
19253895Smckusick 		kbm_open(SCC_KEYBOARD);
19353895Smckusick 	kbm_open(SCC_MOUSE);
19453895Smckusick 
19553895Smckusick 	return (0);
19653895Smckusick }
19753895Smckusick 
19853895Smckusick /*
19953895Smckusick  * Mouse close function.
20053895Smckusick  */
20153895Smckusick 
20253895Smckusick /*ARGSUSED*/
msclose(dev,flag)20353895Smckusick msclose(dev, flag)
20453895Smckusick 	dev_t dev;
20553895Smckusick 	int flag;
20653895Smckusick {
20753895Smckusick 	int unit = MSUNIT(dev);
20853895Smckusick 	register struct ms_stat	*ms = &ms_stat[unit];
20953895Smckusick 	register struct hb_device *ii = msinfo[unit];
21053895Smckusick 
21153895Smckusick 	/* check unit no. */
21253895Smckusick 	if (unit < 0 || unit >= NMS || ii == NULL || ii->hi_alive == 0)
21353895Smckusick 		return ENXIO;
21453895Smckusick 
21553895Smckusick 	/* check status */
21653895Smckusick 	if (!(ms->mss_stat & MS_ACTIVE))
21753895Smckusick 		return ENXIO;
21853895Smckusick 
21953895Smckusick 	/* clear eventmask and status */
22053895Smckusick 	ms->mss_stat = 0;
22153895Smckusick 	ms->mss_eventmask = 0;
22253895Smckusick 
22353895Smckusick 	free(ms->mss_queue, M_DEVBUF);
22453895Smckusick 	ms->mss_pgrp = 0;
22553895Smckusick 	if (tty00_is_console)
22653895Smckusick 		kbm_close(SCC_KEYBOARD);
22753895Smckusick 	kbm_close(SCC_MOUSE);
22853895Smckusick 
22953895Smckusick 	return (0);
23053895Smckusick }
23153895Smckusick 
23253895Smckusick /*
23353895Smckusick  * Mouse read function.
23453895Smckusick  */
23553895Smckusick 
msread(dev,uio,flag)23653895Smckusick msread(dev, uio, flag)
23753895Smckusick 	dev_t dev;
23853895Smckusick 	struct uio *uio;
23953895Smckusick 	int flag;
24053895Smckusick {
24153895Smckusick 	register int unit = MSUNIT(dev);
24253895Smckusick 	register struct ms_stat *ms = &ms_stat[unit];
24353895Smckusick 	register struct hb_device *ii = msinfo[unit];
24453895Smckusick 	register volatile struct ms_event *data;
24553895Smckusick 	struct ms_data xy;
24653895Smckusick 	int s, error;
24753895Smckusick 
24853895Smckusick 	/* check argument */
24953895Smckusick 	if (unit < 0 || unit >= NMS || ii == NULL || ii->hi_alive == 0)
25053895Smckusick 		return ENXIO;
25153895Smckusick 
25253895Smckusick 	/* event mode -> waiting */
25353895Smckusick 	if (ms->mss_eventmask & MS_EMEVENT) {
25453895Smckusick 		s = splms();
25553895Smckusick 		if (msq_stat(unit) == 0 && (ms->mss_stat & MS_NBIO)) {
25653895Smckusick 			splx(s);
25753895Smckusick 			return (EWOULDBLOCK);
25853895Smckusick 		}
25953895Smckusick 		while (msq_stat(unit) == 0) {
26053895Smckusick 			ms->mss_stat |= MS_EVWAIT;
26153895Smckusick 			sleep((caddr_t)&ms->mss_queue, MSPRI);
26253895Smckusick 			ms->mss_stat &= ~MS_EVWAIT;
26353895Smckusick 		}
26453895Smckusick 		splx(s);
26553895Smckusick 		if(MSOLDIF(dev)) {
26653895Smckusick 			while ((data = msq_read(unit)) != NULL &&
26753895Smckusick 			    uio->uio_resid >= sizeof(struct ms_data)) {
26853895Smckusick 				error = uiomove((caddr_t)&data->mse_data,
26953895Smckusick 						sizeof(struct ms_data), uio);
27053895Smckusick 				if (error)
27153895Smckusick 					return error;
27253895Smckusick 			}
27353895Smckusick 		} else {
27453895Smckusick 			while ((data = msq_read(unit)) != NULL &&
27553895Smckusick 			    uio->uio_resid >= sizeof(struct ms_event)) {
27653895Smckusick 				error = uiomove((caddr_t)data,
27753895Smckusick 						sizeof(struct ms_event), uio);
27853895Smckusick 				if (error)
27953895Smckusick 					return error;
28053895Smckusick 			}
28153895Smckusick 		}
28253895Smckusick 	} else {
28353895Smckusick 		while (uio->uio_resid >= sizeof(struct ms_data)) {
28453895Smckusick 			s = splms();
28553895Smckusick 			xy = ms->mss_data;
28653895Smckusick 			splx(s);
28753895Smckusick 			error = uiomove((caddr_t)&xy,
28853895Smckusick 					sizeof(struct ms_data), uio);
28953895Smckusick 			if (error)
29053895Smckusick 				return error;
29153895Smckusick 		}
29253895Smckusick 	}
29353895Smckusick 	return 0;
29453895Smckusick }
29553895Smckusick 
29653895Smckusick /*
29753895Smckusick  * Mouse write function
29853895Smckusick  */
29953895Smckusick 
mswrite(dev,uio,flag)30053895Smckusick mswrite(dev, uio, flag)
30153895Smckusick 	dev_t dev;
30253895Smckusick 	struct uio *uio;
30353895Smckusick 	int flag;
30453895Smckusick {
30553895Smckusick 	register int unit = MSUNIT(dev);
30653895Smckusick 	register struct ms_stat *ms = &ms_stat[unit];
30753895Smckusick 	register struct hb_device *ii = msinfo[unit];
30853895Smckusick 	struct ms_coord xy;
30953895Smckusick 	register int s, error;
31053895Smckusick 
31153895Smckusick 	/* check argument */
31253895Smckusick 	if (unit < 0 || unit >= NMS || ii == NULL || ii->hi_alive == 0)
31353895Smckusick 		return ENXIO;
31453895Smckusick 
31553895Smckusick 	while (uio->uio_resid >= sizeof(struct ms_coord)) {
31653895Smckusick 		error = uiomove((caddr_t)&xy, sizeof(xy), uio);
31753895Smckusick 		if (error)
31853895Smckusick 			return error;
31953895Smckusick 		s = splms();
32053895Smckusick 		ms->mss_data.md_x = xy.mc_x;
32153895Smckusick 		ms->mss_data.md_y = xy.mc_y;
32253895Smckusick 		splx(s);
32353895Smckusick 		lock_bitmap();
32453895Smckusick 		updateCursor(&ms->mss_data.md_x, &ms->mss_data.md_y, 1);
32553895Smckusick 		unlock_bitmap();
32653895Smckusick 	}
32753895Smckusick 	return 0;
32853895Smckusick }
32953895Smckusick 
33053895Smckusick 
33153895Smckusick /*
33253895Smckusick  * Mouse I/O control function
33353895Smckusick  */
33453895Smckusick 
33553895Smckusick /*ARGSUSED*/
msioctl(dev,cmd,data,flag)33653895Smckusick msioctl(dev, cmd, data, flag)
33753895Smckusick 	dev_t dev;
33853895Smckusick 	int cmd;
33953895Smckusick 	caddr_t data;
34053895Smckusick 	int flag;
34153895Smckusick {
34253895Smckusick 	register int unit = MSUNIT(dev);
34353895Smckusick 	register struct ms_stat *ms = &ms_stat[unit];
34453895Smckusick 	register struct hb_device *ii = msinfo[unit];
34553895Smckusick 	register int s;
34653895Smckusick 
34753895Smckusick 	if (unit < 0 || unit >= NMS || ii == NULL || ii->hi_alive == 0)
34853895Smckusick 		return EIO;
34953895Smckusick 
35053895Smckusick 	s = splms();
35153895Smckusick 
35253895Smckusick 	switch (cmd) {
35353895Smckusick 	case MSIOCGETEM:
35453895Smckusick 		(*(int*)data) = ms->mss_eventmask;
35553895Smckusick 		break;
35653895Smckusick 	case MSIOCSETEM:
35753895Smckusick 		ms->mss_eventmask = *(int *)data;
35853895Smckusick 		break;
35953895Smckusick 	case MSIOCSETXY:
36053895Smckusick 		ms->mss_data.md_x = ((struct ms_coord*)data)->mc_x;
36153895Smckusick 		ms->mss_data.md_y = ((struct ms_coord*)data)->mc_y;
36253895Smckusick 		lock_bitmap();
36353895Smckusick 		updateCursor(&ms->mss_data.md_x, &ms->mss_data.md_y, 1);
36453895Smckusick 		unlock_bitmap();
36553895Smckusick 		msq_flush(unit, MSE_MOTION);
36653895Smckusick 		break;
36753895Smckusick 	case MSIOCFLUSH:
36853895Smckusick 		msq_init(unit);
36953895Smckusick 		break;
37053895Smckusick 	case MSIOCSETPARAM:
37153895Smckusick 		ms->mss_param = *(struct ms_param*)data;
37253895Smckusick 		break;
37353895Smckusick 	case MSIOCSETRANGE:
37453895Smckusick 		ms->mss_range = *(struct ms_range*)data;
37553895Smckusick 		break;
37653895Smckusick 	case FIONBIO:
37753895Smckusick 		if (*(int *)data)
37853895Smckusick 			ms->mss_stat |= MS_NBIO;
37953895Smckusick 		else
38053895Smckusick 			ms->mss_stat &= ~MS_NBIO;
38153895Smckusick 		break;
38253895Smckusick 	case FIOASYNC:
38353895Smckusick 		if (*(int *)data)
38453895Smckusick 			ms->mss_stat |= MS_ASYNC;
38553895Smckusick 		else
38653895Smckusick 			ms->mss_stat &= ~MS_ASYNC;
38753895Smckusick 		break;
38853895Smckusick 	case TIOCSPGRP:
38953895Smckusick 		ms->mss_pgrp = *(int *)data;
39053895Smckusick 		break;
39153895Smckusick 	case TIOCGPGRP:
39253895Smckusick 		*(int *)data = ms->mss_pgrp;
39353895Smckusick 		break;
39453895Smckusick 	default:
39553895Smckusick 		splx(s);
39653895Smckusick 		return ENOTTY;
39753895Smckusick 	}
39853895Smckusick 	splx(s);
39953895Smckusick 	return 0;
40053895Smckusick }
40153895Smckusick 
msselect(dev,flag)40253895Smckusick msselect(dev, flag)
40353895Smckusick 	dev_t dev;
40453895Smckusick 	int flag;
40553895Smckusick {
40653895Smckusick 	register int unit = MSUNIT(dev);
40753895Smckusick 	register struct ms_stat *ms;
40853895Smckusick 	int s;
40953895Smckusick 
41053895Smckusick 	if (unit < 0 || unit >= NMS)
41153895Smckusick 		return(0);
41253895Smckusick 
41353895Smckusick 	s = splms();
41453895Smckusick 	ms = &ms_stat[unit];
41553895Smckusick 
41653895Smckusick 	switch(flag) {
41753895Smckusick 	case FREAD:
41853895Smckusick 		if (!(ms->mss_eventmask & MS_EMEVENT))
41953895Smckusick 			goto win;
42053895Smckusick 		if(msq_stat(unit))
42153895Smckusick 			goto win;
42253895Smckusick 
42353895Smckusick 		if (ms->mss_rsel && ms->mss_rsel->p_wchan == (caddr_t)&selwait)
42453895Smckusick 			ms->mss_stat |= MS_RCOLL;
42553895Smckusick 		else
42653895Smckusick 			ms->mss_rsel = curproc;
42753895Smckusick 		break;
42853895Smckusick 
42953895Smckusick 	case FWRITE:
43053895Smckusick 		goto win;
43153895Smckusick 	}
43253895Smckusick 	splx(s);
43353895Smckusick 	return(0);
43453895Smckusick win:
43553895Smckusick 	splx(s);
43653895Smckusick 	return(1);
43753895Smckusick }
43853895Smckusick 
msselwakeup(ms)43953895Smckusick msselwakeup(ms)
44053895Smckusick 	register struct ms_stat *ms;
44153895Smckusick {
44253895Smckusick 	if (ms->mss_rsel) {
44353895Smckusick 		selwakeup(ms->mss_rsel, ms->mss_stat&MS_RCOLL);
44453895Smckusick 		ms->mss_stat &= ~MS_RCOLL;
44553895Smckusick 		ms->mss_rsel = 0;
44653895Smckusick 	}
44753895Smckusick 	if (ms->mss_stat & MS_ASYNC)
44853895Smckusick 		gsignal(ms->mss_pgrp, SIGIO);
44953895Smckusick }
45053895Smckusick 
mssint()45153895Smckusick mssint()
45253895Smckusick {
45353895Smckusick 	printf("mssint\n");
45453895Smckusick }
45553895Smckusick 
msputevent(unit,trig,dir,code)45653895Smckusick msputevent(unit, trig, dir, code)
45753895Smckusick 	int unit, trig, dir, code;
45853895Smckusick {
45953895Smckusick 	register struct ms_stat *ms = &ms_stat[unit];
46053895Smckusick 	register volatile struct ms_event *me;
46153895Smckusick 	register int s;
46253895Smckusick 
46353895Smckusick 	me = msq_write(unit);
46453895Smckusick 
46553895Smckusick 	s = splclock();
46653895Smckusick 	me->mse_time = time;
46753895Smckusick 	me->mse_inval = 0;
46853895Smckusick 	splx(s);
46953895Smckusick 
47053895Smckusick 	me->mse_trig = trig;
47153895Smckusick 	me->mse_dir = dir;
47253895Smckusick 	me->mse_code = code;
47353895Smckusick 	me->mse_data = ms->mss_data;
47453895Smckusick 
47553895Smckusick 	if (ms->mss_stat & MS_EVWAIT)
47653895Smckusick 		wakeup((caddr_t)&ms->mss_queue);
47753895Smckusick 
47853895Smckusick 	msselwakeup(ms);
47953895Smckusick 
48053895Smckusick 	return (0);
48153895Smckusick }
48253895Smckusick 
48353895Smckusick /*
48453895Smckusick  * for keyboard
48553895Smckusick  */
mskeytrigger(unit,up,keycode)48653895Smckusick mskeytrigger(unit, up, keycode)
48753895Smckusick 	int unit;
48853895Smckusick 	int up;
48953895Smckusick 	int keycode;
49053895Smckusick {
49153895Smckusick 	register struct ms_stat *ms = &ms_stat[unit];
49253895Smckusick 
49353895Smckusick 	if((ms->mss_eventmask & MS_EMEVENT) == 0)
49453895Smckusick 		return 0;
49553895Smckusick 	if((ms->mss_eventmask & MS_EMKEY) == 0)
49653895Smckusick 		return 0;
49753895Smckusick 
49853895Smckusick 	(void) msputevent(unit, MSE_KEY, up ? MSE_UP : MSE_DOWN, keycode);
49953895Smckusick 
50053895Smckusick 	return 1;
50153895Smckusick }
50253895Smckusick 
50353895Smckusick /*
50453895Smckusick  * msconv - convert mouse hardware reports(3 bytes) into internal mouse data
50553895Smckusick  *		it leaves the old mouse data in ms_data_old and
50653895Smckusick  *		new mouse data in ms_data.
50753895Smckusick  */
msconv(unit,rep)50853895Smckusick msconv(unit, rep)
50953895Smckusick 	int unit;
51053895Smckusick 	register char rep[];
51153895Smckusick {
51253895Smckusick 	register struct ms_stat *ms = &ms_stat[unit];
51353895Smckusick 	register int s_byte;
51453895Smckusick 	register int sw = 0;
51553895Smckusick 	register int dx, dy;
51653895Smckusick 	int adx, ady;
51753895Smckusick 
51853895Smckusick 	ms->mss_data_old = ms->mss_data;
51953895Smckusick 
52053895Smckusick 	/* switch status */
52153895Smckusick 	s_byte = rep[MS_S_BYTE];
52253895Smckusick 	if (s_byte & MS_S_SW1)
52353895Smckusick 		sw |= MS_BUTNL;
52453895Smckusick 	if (s_byte & MS_S_SW2)
52553895Smckusick 		sw |= MS_BUTNR;
52653895Smckusick 	if (s_byte & MS_S_SW3)
52753895Smckusick 		sw |= MS_BUTNM;
52853895Smckusick 	ms->mss_data.md_sw = sw;
52953895Smckusick 
53053895Smckusick 	/* delta x */
53153895Smckusick 	dx = rep[MS_X_BYTE] & MS_X_X06;
53253895Smckusick 	if (s_byte & MS_S_X7)
53353895Smckusick 		dx = (~0&~MS_X_X06)|dx;
53453895Smckusick 
53553895Smckusick 	dy = rep[MS_Y_BYTE] & MS_Y_Y06;
53653895Smckusick 	if (s_byte & MS_S_Y7)
53753895Smckusick 		dy = (~0&~MS_Y_Y06)|dy;
53853895Smckusick 
53953895Smckusick #define ABS(x)	((x)>=0 ? (x) : -(x))
54053895Smckusick 	adx = ABS(dx);
54153895Smckusick 	ady = ABS(dy);
54253895Smckusick #undef ABS
54353895Smckusick 
54453895Smckusick 	if (adx > ms->mss_param.mp_delta) {
54553895Smckusick 		adx = ms->mss_param.mp_delta +
54653895Smckusick 		      (adx - ms->mss_param.mp_delta) * ms->mss_param.mp_mag;
54753895Smckusick 		if (dx < 0)
54853895Smckusick 			dx = -adx;
54953895Smckusick 		else
55053895Smckusick 			dx = adx;
55153895Smckusick 	}
55253895Smckusick 	if (ady > ms->mss_param.mp_delta) {
55353895Smckusick 		ady = ms->mss_param.mp_delta +
55453895Smckusick 		      (ady - ms->mss_param.mp_delta) * ms->mss_param.mp_mag;
55553895Smckusick 		if (dy < 0)
55653895Smckusick 			dy = -ady;
55753895Smckusick 		else
55853895Smckusick 			dy = ady;
55953895Smckusick 	}
56053895Smckusick 	ms->mss_data.md_x += dx;
56153895Smckusick 	ms->mss_data.md_y += dy;
56253895Smckusick 
56353895Smckusick 	if (dx > 0)
56455764Sbostic 		ms->mss_data.md_x = min(ms->mss_data.md_x,
56553895Smckusick 					ms->mss_range.mr_max.mc_x);
56653895Smckusick 	else
56755764Sbostic 		ms->mss_data.md_x = max(ms->mss_data.md_x,
56853895Smckusick 					ms->mss_range.mr_min.mc_x);
56953895Smckusick 	if (dy > 0)
57055764Sbostic 		ms->mss_data.md_y = min(ms->mss_data.md_y,
57153895Smckusick 					ms->mss_range.mr_max.mc_y);
57253895Smckusick 	else
57355764Sbostic 		ms->mss_data.md_y = max(ms->mss_data.md_y,
57453895Smckusick 					ms->mss_range.mr_min.mc_y);
57553895Smckusick 
57653895Smckusick 	if (dx != 0 || dy != 0)
57753895Smckusick 		updateCursor(&ms->mss_data.md_x, &ms->mss_data.md_y, 0);
57853895Smckusick }
57953895Smckusick 
mscheckevent(unit)58053895Smckusick mscheckevent(unit)
58153895Smckusick 	int unit;
58253895Smckusick {
58353895Smckusick 	register struct ms_stat *ms = &ms_stat[unit];
58453895Smckusick 	register int i;
58553895Smckusick 	register int changebits;
58653895Smckusick 	register int dir;
58753895Smckusick 
58853895Smckusick 	if ((ms->mss_eventmask & MS_EMEVENT) == 0)
58953895Smckusick 		return;
59053895Smckusick 
59153895Smckusick 	if (ms->mss_data_old.md_sw != ms->mss_data.md_sw) {
59253895Smckusick 
59353895Smckusick 		changebits = (ms->mss_data_old.md_sw ^ ms->mss_data.md_sw);
59453895Smckusick 		changebits &= ms->mss_eventmask;
59553895Smckusick 
59653895Smckusick 		for(i = 0; i < 3; i++) {
59753895Smckusick 			if(changebits & (1 << i)) {
59853895Smckusick 				if((1 << i) & ms->mss_data.md_sw)
59953895Smckusick 					dir = MSE_DOWN;
60053895Smckusick 				else
60153895Smckusick 					dir = MSE_UP;
60253895Smckusick 				msputevent(unit, MSE_BUTTON, dir, i);
60353895Smckusick 			}
60453895Smckusick 		}
60553895Smckusick 	}
60653895Smckusick 
60753895Smckusick 	if ((ms->mss_eventmask & MS_EMMOTION) &&
60853895Smckusick 	    (ms->mss_data_old.md_x != ms->mss_data.md_x ||
60953895Smckusick 	     ms->mss_data_old.md_y != ms->mss_data.md_y)) {
61053895Smckusick 		msputevent(unit, MSE_MOTION, 0, 0);
61153895Smckusick 		return;
61253895Smckusick 	}
61353895Smckusick }
61453895Smckusick 
61553895Smckusick /*
61653895Smckusick  * _ms_helper - open the mouse line and read mouse data and
61753895Smckusick  *		convert them into mouse data (events)
61853895Smckusick  */
_ms_helper(unit)61953895Smckusick _ms_helper(unit)
62053895Smckusick 	int unit;
62153895Smckusick {
62253895Smckusick 	register int c;
62353895Smckusick 	static int counter = 0;
62453895Smckusick 	static char buf[MS_DB_SIZE];
62553895Smckusick 
62653895Smckusick #ifdef notyet /* KU:XXX */
62753895Smckusick 	intrcnt[INTR_MOUSE]++;
62853895Smckusick #endif
62953895Smckusick 
63053895Smckusick #if NBM > 0
63153895Smckusick 	rst_dimmer_cnt();
63253895Smckusick #endif
63353895Smckusick 
63453895Smckusick 	while ((c = xgetc(SCC_MOUSE)) >= 0) {
63553895Smckusick 		if (c & MS_S_MARK)
63653895Smckusick 			counter = 0;
63753895Smckusick 		buf[counter] = c;
63853895Smckusick 		if (++counter == 3) {
63953895Smckusick 			msconv(unit, buf);
64053895Smckusick 			mscheckevent(unit);
64153895Smckusick 			counter = 0;
64253895Smckusick 		}
64353895Smckusick 	}
64453895Smckusick }
64553895Smckusick #endif /* NMS > 0 */
646