* Copyright (c) 1992 The Regents of the University of California.
* This code is derived from software contributed to Berkeley by
* Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
* %sccs.include.redist.c%
* from: $Hdr: ms.c,v 4.300 91/06/09 06:22:04 root Rel41 $ SONY
* @(#)ms.c 7.4 (Berkeley) %G%
#include <news3400/iop/mouse.h>
#include <news3400/iop/msreg.h>
#include <news3400/sio/scc.h>
#include <news3400/hbdev/hbvar.h>
struct 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
;
return(sizeof(struct ms_stat
));
/* queue structure operators */
register volatile struct ms_queue
*q
= ms_stat
[unit
].mss_queue
;
q
->mq_head
= q
->mq_tail
= 0;
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
)
q
->mq_head
= ++q
->mq_head
% MS_MAXREPORT
;
return (q
->mq_head
!= q
->mq_tail
);
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
= q
->mq_queue
+ q
->mq_head
++;
q
->mq_head
%= MS_MAXREPORT
;
register volatile struct ms_queue
*q
= ms_stat
[unit
].mss_queue
;
register struct ms_event
*data
= q
->mq_queue
+ q
->mq_tail
;
/* if queue is full, newest data is gone away */
new = (q
->mq_tail
+ 1) % MS_MAXREPORT
;
register volatile struct ms_queue
*q
= ms_stat
[unit
].mss_queue
;
while (i
!= q
->mq_tail
) {
if (q
->mq_queue
[i
].mse_trig
== trig
)
q
->mq_queue
[i
].mse_inval
= -1;
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 };
if (unit
< 0 || unit
>= NMS
|| ii
== NULL
|| ii
->hi_alive
== 0)
/* check duplicable open */
if (ms
->mss_stat
& MS_ACTIVE
)
ms
->mss_queue
= malloc(sizeof(struct ms_queue
), M_DEVBUF
, M_WAITOK
);
if (ms
->mss_queue
== NULL
)
ms
->mss_stat
= MS_ACTIVE
;
/* communicate to IOP .. clear event mask, set initial xy. */
ms
->mss_data
.md_sw
= 0; /* XXX */
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) {
ms
->mss_pgrp
= curproc
->p_pid
;
curproc
->p_pgrp
->pg_id
= ms
->mss_pgrp
;
register struct ms_stat
*ms
= &ms_stat
[unit
];
register struct hb_device
*ii
= msinfo
[unit
];
if (unit
< 0 || unit
>= NMS
|| ii
== NULL
|| ii
->hi_alive
== 0)
if (!(ms
->mss_stat
& MS_ACTIVE
))
/* clear eventmask and status */
free(ms
->mss_queue
, M_DEVBUF
);
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
;
if (unit
< 0 || unit
>= NMS
|| ii
== NULL
|| ii
->hi_alive
== 0)
/* event mode -> waiting */
if (ms
->mss_eventmask
& MS_EMEVENT
) {
if (msq_stat(unit
) == 0 && (ms
->mss_stat
& MS_NBIO
)) {
while (msq_stat(unit
) == 0) {
ms
->mss_stat
|= MS_EVWAIT
;
sleep((caddr_t
)&ms
->mss_queue
, MSPRI
);
ms
->mss_stat
&= ~MS_EVWAIT
;
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
);
while ((data
= msq_read(unit
)) != NULL
&&
uio
->uio_resid
>= sizeof(struct ms_event
)) {
error
= uiomove((caddr_t
)data
,
sizeof(struct ms_event
), uio
);
while (uio
->uio_resid
>= sizeof(struct ms_data
)) {
error
= uiomove((caddr_t
)&xy
,
sizeof(struct ms_data
), uio
);
register int unit
= MSUNIT(dev
);
register struct ms_stat
*ms
= &ms_stat
[unit
];
register struct hb_device
*ii
= msinfo
[unit
];
if (unit
< 0 || unit
>= NMS
|| ii
== NULL
|| ii
->hi_alive
== 0)
while (uio
->uio_resid
>= sizeof(struct ms_coord
)) {
error
= uiomove((caddr_t
)&xy
, sizeof(xy
), uio
);
ms
->mss_data
.md_x
= xy
.mc_x
;
ms
->mss_data
.md_y
= xy
.mc_y
;
updateCursor(&ms
->mss_data
.md_x
, &ms
->mss_data
.md_y
, 1);
* Mouse I/O control function
msioctl(dev
, cmd
, data
, flag
)
register int unit
= MSUNIT(dev
);
register struct ms_stat
*ms
= &ms_stat
[unit
];
register struct hb_device
*ii
= msinfo
[unit
];
if (unit
< 0 || unit
>= NMS
|| ii
== NULL
|| ii
->hi_alive
== 0)
(*(int*)data
) = ms
->mss_eventmask
;
ms
->mss_eventmask
= *(int *)data
;
ms
->mss_data
.md_x
= ((struct ms_coord
*)data
)->mc_x
;
ms
->mss_data
.md_y
= ((struct ms_coord
*)data
)->mc_y
;
updateCursor(&ms
->mss_data
.md_x
, &ms
->mss_data
.md_y
, 1);
msq_flush(unit
, MSE_MOTION
);
ms
->mss_param
= *(struct ms_param
*)data
;
ms
->mss_range
= *(struct ms_range
*)data
;
ms
->mss_stat
&= ~MS_NBIO
;
ms
->mss_stat
|= MS_ASYNC
;
ms
->mss_stat
&= ~MS_ASYNC
;
ms
->mss_pgrp
= *(int *)data
;
*(int *)data
= ms
->mss_pgrp
;
register int unit
= MSUNIT(dev
);
register struct ms_stat
*ms
;
if (unit
< 0 || unit
>= NMS
)
if (!(ms
->mss_eventmask
& MS_EMEVENT
))
if (ms
->mss_rsel
&& ms
->mss_rsel
->p_wchan
== (caddr_t
)&selwait
)
ms
->mss_stat
|= MS_RCOLL
;
register struct ms_stat
*ms
;
selwakeup(ms
->mss_rsel
, ms
->mss_stat
&MS_RCOLL
);
ms
->mss_stat
&= ~MS_RCOLL
;
if (ms
->mss_stat
& MS_ASYNC
)
gsignal(ms
->mss_pgrp
, SIGIO
);
msputevent(unit
, trig
, dir
, code
)
int unit
, trig
, dir
, code
;
register struct ms_stat
*ms
= &ms_stat
[unit
];
register volatile struct ms_event
*me
;
me
->mse_data
= ms
->mss_data
;
if (ms
->mss_stat
& MS_EVWAIT
)
wakeup((caddr_t
)&ms
->mss_queue
);
mskeytrigger(unit
, up
, keycode
)
register struct ms_stat
*ms
= &ms_stat
[unit
];
if((ms
->mss_eventmask
& MS_EMEVENT
) == 0)
if((ms
->mss_eventmask
& MS_EMKEY
) == 0)
(void) msputevent(unit
, MSE_KEY
, up
? MSE_UP
: MSE_DOWN
, keycode
);
* 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.
register struct ms_stat
*ms
= &ms_stat
[unit
];
ms
->mss_data_old
= ms
->mss_data
;
dx
= rep
[MS_X_BYTE
] & MS_X_X06
;
dy
= rep
[MS_Y_BYTE
] & MS_Y_Y06
;
#define ABS(x) ((x)>=0 ? (x) : -(x))
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 (ady
> ms
->mss_param
.mp_delta
) {
ady
= ms
->mss_param
.mp_delta
+
(ady
- ms
->mss_param
.mp_delta
) * ms
->mss_param
.mp_mag
;
ms
->mss_data
.md_x
= min(ms
->mss_data
.md_x
,
ms
->mss_range
.mr_max
.mc_x
);
ms
->mss_data
.md_x
= max(ms
->mss_data
.md_x
,
ms
->mss_range
.mr_min
.mc_x
);
ms
->mss_data
.md_y
= min(ms
->mss_data
.md_y
,
ms
->mss_range
.mr_max
.mc_y
);
ms
->mss_data
.md_y
= max(ms
->mss_data
.md_y
,
ms
->mss_range
.mr_min
.mc_y
);
updateCursor(&ms
->mss_data
.md_x
, &ms
->mss_data
.md_y
, 0);
register struct ms_stat
*ms
= &ms_stat
[unit
];
if ((ms
->mss_eventmask
& MS_EMEVENT
) == 0)
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
;
if(changebits
& (1 << i
)) {
if((1 << i
) & ms
->mss_data
.md_sw
)
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);
* _ms_helper - open the mouse line and read mouse data and
* convert them into mouse data (events)
static char buf
[MS_DB_SIZE
];
#ifdef notyet /* KU:XXX */
while ((c
= xgetc(SCC_MOUSE
)) >= 0) {