home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
d
/
ddx-mips.zip
/
MIPSMOUS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-11
|
15KB
|
759 lines
/*
* $XConsortium$
*
* Copyright 1991 MIPS Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of MIPS not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. MIPS makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* MIPS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL MIPS
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ident "$Header: mipsMouse.c,v 1.13 92/08/11 16:38:06 dd Exp $"
#include <sys/types.h>
#include <sys/file.h>
#include <sysv/sys/termio.h>
#include <sysv/sys/kbd_ioctl.h>
#include <sysv/sys/uart_ioctl.h>
#include <sys/time.h>
#include "X.h"
#define NEED_EVENTS
#include "Xproto.h"
#include "scrnintstr.h"
#include "inputstr.h"
#include "mipointer.h"
#include "mips.h"
#include "mipsIo.h"
#include "mipsMouse.h"
static void decode5(), decode3();
MousePriv mousePriv = {
-1, /* fd */
0, /* unit */
0, /* cap */
1200, /* baud */
0, /* rate */
MIPS_MOUSE_DEFAULT, /* type */
0, /* buttonstate */
{ {RAW_LEFT, 1}, /* buttonmap */
{RAW_MIDDLE, 2},
{RAW_RIGHT, 3} },
0, 0, /* rootX, rootY */
decode5, /* decode */
};
#if PIXIE
extern int pixie;
#endif /* PIXIE */
/* mouse statistics */
int mserr = 0;
#ifdef X11R4
static long mipsEventTime();
static Bool mipsCursorOffScreen();
static void mipsCrossScreen();
extern void miPointerQueueEvent();
miPointerCursorFuncRec mipsPointerCursorFuncs = {
mipsEventTime,
mipsCursorOffScreen,
mipsCrossScreen,
miPointerQueueEvent,
};
volatile mouseQ_t mouseQ[MOUSEQSIZE];
volatile mouseQ_t *mouseQh = mouseQ;
volatile mouseQ_t *mouseQt = mouseQ;
/* Motion buffer */
int motionBufferSize = 100;
xTimecoord *motionBuf = NULL;
xTimecoord *motionTail = NULL;
static long
mipsEventTime(pScr)
ScreenPtr pScr;
{
return(lastEventTime);
}
#else /* X11R4 */
static Bool mipsCursorOffScreen();
static void mipsCrossScreen();
static void mipsWarpCursor();
miPointerScreenFuncRec mipsPointerScreenFuncs = {
mipsCursorOffScreen,
mipsCrossScreen,
mipsWarpCursor,
};
static void
mipsWarpCursor (pScr, x, y)
ScreenPtr pScr;
int x, y;
{
SIGHOLD_DCL
SIGHOLD;
miPointerWarpCursor (pScr, x, y);
SIGRELEASE;
}
#endif /* X11R4 */
static Bool
mipsCursorOffScreen(pScr, x, y)
ScreenPtr *pScr;
int *x;
int *y;
{
int i;
if ((screenInfo.numScreens > 1) && ((*x < 0) || ((*pScr)->width <= *x))) {
i = (*pScr)->myNum;
if (*x < 0) {
if (i == 0) i = screenInfo.numScreens;
i--;
*pScr = screenInfo.screens[i];
*x += (*pScr)->width;
}
else {
*x -= (*pScr)->width;
i++;
if (i == screenInfo.numScreens) i = 0;
*pScr = screenInfo.screens[i];
}
return(TRUE);
}
return(FALSE);
}
/*ARGSUSED*/
static void
mipsCrossScreen(pScr, enter)
ScreenPtr pScr;
Bool enter;
{
}
static int
ttyinit(pPriv)
MousePrivPtr pPriv;
{
int type;
int fd = pPriv->fd;
int vmin = 1;
int baud = pPriv->baud;
char *p, s[2];
static char ratecode[] = {
125, 'N', /* 150 per second */
85, 'Q', /* 100 per second */
60, 'M', /* 70 per second */
42, 'R', /* 50 per second */
27, 'L', /* 35 per second */
15, 'K', /* 20 per second */
1, 'J', /* 10 per second */
0, 'O', /* continuous */
};
if (!pPriv->cap & DEV_INIT)
return 0;
#ifdef KMOUSEFMT
if (ioctl(fd, KMOUSEFMT, &type) >= 0 &&
type == KMOUSE3BYTE) {
pPriv->type = MIPS_MOUSE_3BYTE;
pPriv->decode = decode3;
setSpeed(pPriv->fd, 1, 1200);
reset3(pPriv);
return 0;
}
#endif /* KMOUSEFMT */
setBaud(fd, vmin, 1200, baud);
setBaud(fd, vmin, 2400, baud);
setBaud(fd, vmin, 4800, baud);
setBaud(fd, vmin, 9600, baud);
switch (pPriv->type) {
case MIPS_MOUSE_DEFAULT:
/* 5 byte packed binary format */
s[0] = 'U';
/* rate code */
for (p = ratecode; p[0] != 0; p += 2)
if (pPriv->rate >= p[0])
break;
s[1] = p[1];
(void) write(fd, s, 2);
break;
case MIPS_MOUSE_MOUSEMAN:
sleep(1);
write(pPriv->fd, "*U", 2);
sleep(1);
while (read(pPriv->fd, s, 1) == 1)
/* nothing */ ;
break;
}
return 0;
}
static
setBaud(fd, vmin, current, new)
int fd;
int vmin;
int current;
int new;
{
setSpeed(fd, vmin, current);
#if PIXIE
if (!pixie)
#endif /* PIXIE */
{
char c, s[2];
switch (new) {
case 9600: c = 'q'; break;
case 4800: c = 'p'; break;
case 2400: c = 'o'; break;
default:
case 1200: c = 'n'; break;
}
s[0] = '*';
s[1] = c;
(void) write(fd, s, 2);
mipsUsleep(100000);
}
setSpeed(fd, vmin, new);
}
static
setSpeed(fd, vmin, speed)
int fd;
int vmin;
int speed;
{
struct termio logmode;
switch (speed) {
case 9600: speed = B9600; break;
case 4800: speed = B4800; break;
case 2400: speed = B2400; break;
default:
case 1200: speed = B1200; break;
}
logmode.c_iflag = IGNBRK | IGNPAR;
logmode.c_oflag = 0;
logmode.c_lflag = 0;
logmode.c_line = 0;
logmode.c_cc[VMIN] = vmin;
logmode.c_cc[VTIME] = 0;
logmode.c_cflag = speed |
CS8 | CSTOPB | CREAD | CLOCAL | HUPCL;
if (ioctl(fd, TCSETAF, &logmode) < 0) {
Error("cannot ioctl(TCSETAF) mouse");
return -1;
}
return 0;
}
static int
mouseAccel(d)
int d;
{
PtrCtrl *pctrl;
#ifdef X11R4
pctrl = &mousePriv.ctrl;
#else
pctrl = &((DeviceIntPtr) pMouse)->ptrfeed->ctrl;
#endif
if (d > pctrl->threshold ||
d < 0 && -d > pctrl->threshold) {
d *= pctrl->num;
d /= pctrl->den;
}
return d;
}
#ifdef X11R4
static void
enqueueMouse(time, dx, dy, bmask)
int time;
int dx, dy;
int bmask;
{
volatile mouseQ_t *newQt;
mouseQt->time = time;
mouseQt->scrn = mousePriv.scrn;
mouseQt->dx = mouseAccel(dx);
mouseQt->dy = mouseAccel(dy);
mouseQt->bmask = bmask;
newQt = mouseQt + 1;
if (newQt == (mouseQ + MOUSEQSIZE))
newQt = mouseQ;
if (newQt != mouseQh)
mouseQt = newQt;
}
static void
dequeueMouse()
{
volatile mouseQ_t *newQh;
newQh = mouseQh + 1;
if (newQh == (mouseQ + MOUSEQSIZE))
newQh = mouseQ;
mouseQh = newQh;
}
#endif /* X11R4 */
#ifdef X11R4
#define mouseEvent(pm, dx, dy, bmask, time) \
enqueueMouse((time), (dx), (dy), (bmask))
#endif /* X11R4 */
static void
decode5(pMouse, code, time)
DevicePtr pMouse;
char code;
int time;
{
MousePrivPtr pPriv = (MousePrivPtr) pMouse->devicePrivate;
int state = pPriv->decode_state;
char *msbuf = pPriv->msbuf;
/* look for sync byte */
if ((code & MS5_SYNCMASK) == MS5_SYNCVAL) {
if (state)
mserr++;
state = 1;
msbuf[0] = code;
}
else {
switch (state) {
case 0: /* Waiting for sync byte */
mserr++;
break;
case 1: /* Waiting for X0 */
case 2: /* Waiting for Y0 */
case 3: /* Waiting for X1 */
msbuf[state++] = code;
break;
case 4: /* Waiting for Y1 */
msbuf[4] = code;
mouseEvent(pMouse,
MS5_XVAL(msbuf), MS5_YVAL(msbuf),
MS5_BUTTON(msbuf), time);
state = 0;
break;
}
}
pPriv->decode_state = state;
}
static
reset3(pPriv)
MousePrivPtr pPriv;
{
#ifdef KMOUSERESET
(void) ioctl(pPriv->fd, KMOUSERESET, 0);
#endif /* KMOUSERESET */
pPriv->decode_state = -1;
}
static void
decode3(pMouse, code, time)
DevicePtr pMouse;
char code;
int time;
{
MousePrivPtr pPriv = (MousePrivPtr) pMouse->devicePrivate;
int state = pPriv->decode_state;
char *msbuf = pPriv->msbuf;
switch (state) {
case -1:
pPriv->decode_sync = code & MS3_SYNCMASK;
state = 0;
/* fall through */
case 0:
if ((code & MS3_SYNCMASK) != pPriv->decode_sync) {
mserr++;
reset3(pPriv);
break;
}
/* fall through */
case 1:
msbuf[state++] = code;
break;
case 2:
msbuf[2] = code;
if (MS3_XBADOVF(msbuf) || MS3_YBADOVF(msbuf)) {
mserr++;
reset3(pPriv);
break;
}
mouseEvent(pMouse,
MS3_XVAL(msbuf), MS3_YVAL(msbuf),
MS3_BUTTON(msbuf), time);
state = 0;
break;
}
pPriv->decode_state = state;
}
static
timestampMouse(pMouse, code)
DevicePtr pMouse;
char code;
{
static int state = -1;
static char data;
static time_t time;
u_char *ptime = (u_char *) &time;
state++;
switch (state) {
case 0: /* Looking for 1st sync byte */
case 1: /* Looking for 2nd sync byte */
case 2: /* Looking for 3rd sync byte */
if (((u_char) code) != KBDSYNCCHAR)
state = -1;
break;
case 3: /* Looking for data */
data = code;
break;
case 4: /* Looking for 1st time byte */
case 5: /* Looking for 2nd time byte */
case 6: /* Looking for 3rd time byte */
ptime[state - 4] = (u_char) code;
break;
case 7: /* Looking for 4th time byte */
ptime[state - 4] = (u_char) code;
(*mousePriv.decode)(pMouse, data, offsetTime(time));
state = -1;
break;
}
}
void
handleMouse(pMouse)
DevicePtr pMouse;
{
int nchar = 0;
int i;
char buf[MAXEVENTS];
#ifdef X11R4
SIGHOLD_DCL
SIGHOLD;
#else /* X11R4 */
if (!mousePriv.cap & DEV_TIMESTAMP)
lastEventTime = GetTimeInMillis();
#endif /* X11R4 */
if ((mousePriv.fd >= 0) && (mousePriv.cap & DEV_READ)) {
do {
if ((nchar = read(mousePriv.fd, buf, sizeof(buf))) <= 0)
break;
if (mousePriv.cap & DEV_TIMESTAMP) {
for (i = 0; i < nchar; ++i)
timestampMouse(pMouse, buf[i]);
}
else {
for (i = 0; i < nchar; ++i)
(*mousePriv.decode)(pMouse, buf[i], lastEventTime);
}
} while (nchar == sizeof(buf));
}
#ifdef X11R4
SIGRELEASE;
while (mouseQh != mouseQt) {
mouse_event(pMouse, mouseQh);
dequeueMouse();
}
#endif /* X11R4 */
}
/* ARGSUSED */
static void
mipsChangePointerControl(pDevice, ctrl)
DevicePtr pDevice;
PtrCtrl *ctrl;
{
mousePriv.ctrl = *ctrl;
}
#ifdef X11R4
/* ARGSUSED */
static int
mipsGetMotionEvents(dev, buff, start, stop)
DeviceIntPtr dev;
xTimecoord *buff;
CARD32 start, stop;
{
xTimecoord *ptc;
int count = 0;
if (motionBuf) {
ptc = motionTail;
do {
ptc++;
if (ptc == (motionBuf + motionBufferSize))
ptc = motionBuf;
if ((start <= ptc->time) && (ptc->time <= stop)) {
*buff++ = *ptc;
count++;
}
}
while ((ptc != motionTail) && (ptc->time <= stop));
}
return(count);
}
#endif /* X11R4 */
static mouseAsync(pPriv, set)
MousePrivPtr pPriv;
Bool set;
{
#if PIXIE
if (pixie)
return;
#endif /* PIXIE */
if (pPriv->cap & DEV_ASYNC) {
if (mipsStreamAsync(pPriv->fd, set) < 0) {
pPriv->cap &= ~DEV_ASYNC;
Error("cannot ioctl(I_SETSIG) mouse");
}
}
}
openMouse()
{
if (mousePriv.fd < 0) {
if ((mousePriv.fd = open(MOUSEDEV, O_RDWR|O_NDELAY)) >= 0) {
#ifndef SYSV
int flags;
if ((flags = fcntl(mousePriv.fd, F_GETFL, flags)) == -1)
Error("cannot fcntl(F_GETFL) mouse");
flags |= FNDELAY;
if (fcntl(mousePriv.fd, F_SETFL, flags) == -1)
Error("cannot fcntl(F_SETFL) mouse");
#endif /* SYSV */
mousePriv.cap = -1;
}
else {
mousePriv.cap = 0;
Error("cannot open mouse");
}
}
}
/* ARGSUSED */
int
mipsMouseProc(pMouse, onoff, argc, argv)
DevicePtr pMouse;
int onoff, argc;
char *argv[];
{
BYTE map[4];
int flags;
MousePrivPtr pPriv;
pPriv = (MousePrivPtr) pMouse->devicePrivate;
switch (onoff) {
case DEVICE_INIT:
pMouse->devicePrivate = (pointer) &mousePriv;
pPriv = (MousePrivPtr) pMouse->devicePrivate;
openMouse();
pMouse->on = FALSE;
map[1] = 1;
map[2] = 2;
map[3] = 3;
#ifdef X11R4
if (motionBufferSize) {
motionBuf = motionTail =
(xTimecoord *) Xalloc(motionBufferSize * sizeof(xTimecoord));
if (motionBuf)
bzero(motionBuf, motionBufferSize * sizeof(xTimecoord));
}
InitPointerDeviceStruct(pMouse, map, 3, mipsGetMotionEvents,
mipsChangePointerControl, motionBufferSize);
#else /* X11R4 */
InitPointerDeviceStruct(pMouse, map, 3, miPointerGetMotionEvents,
mipsChangePointerControl, miPointerGetMotionBufferSize());
#endif /* X11R4 */
break;
case DEVICE_ON:
if (pPriv->fd >= 0) {
if (pPriv->cap & DEV_TIMESTAMP) {
if (ioctl(pPriv->fd, UTCSETTIMESTAMP, 0) < 0) {
pPriv->cap &= ~DEV_TIMESTAMP;
Error("cannot ioctl(UTCSETTIMESTAMP) mouse");
}
}
if (ttyinit(pPriv) < 0)
ErrorF("cannot initialize mouse\n");
mouseAsync(pPriv, TRUE);
AddEnabledDevice(pPriv->fd);
}
pMouse->on = TRUE;
break;
case DEVICE_CLOSE:
pMouse->on = FALSE;
if (pPriv->fd >= 0) {
RemoveEnabledDevice(pPriv->fd);
(void) close(pPriv->fd);
}
pPriv->fd = -1;
pPriv->cap = 0;
#ifdef X11R4
if (motionBuf)
Xfree(motionBuf);
motionBuf = motionTail = NULL;
#endif /* X11R4 */
break;
case DEVICE_OFF:
pMouse->on = FALSE;
if (pPriv->fd >= 0)
RemoveEnabledDevice(pPriv->fd);
break;
}
return(Success);
}
#ifdef X11R4
static
mouse_event(pMouse, pQ)
DevicePtr pMouse;
mouseQ_t *pQ;
{
xEvent mevent;
int i;
int nbuttons;
MousePrivPtr pPriv;
lastEventTime = pQ->time;
pPriv = (MousePrivPtr) pMouse->devicePrivate;
/* a motion event? do cursor chase */
if (pQ->dx || pQ->dy) {
miPointerPosition(screenInfo.screens[0], &pPriv->rootX, &pPriv->rootY);
pPriv->rootX += pQ->dx;
pPriv->rootY += pQ->dy;
miPointerDeltaCursor(screenInfo.screens[0], pQ->dx, pQ->dy, TRUE);
if (motionBuf) {
motionTail++;
if (motionTail == (motionBuf + motionBufferSize))
motionTail = motionBuf;
motionTail->time = lastEventTime;
motionTail->x = pPriv->rootX;
motionTail->y = pPriv->rootY;
}
}
/* button change state? notify server. */
if (nbuttons = pQ->bmask ^ pPriv->buttonstate) {
mevent.u.keyButtonPointer.time = lastEventTime;
for(i=0;i<NBUTTONS;i++)
if (pPriv->buttonmap[i].mask&nbuttons) {
mevent.u.u.type =
(pQ->bmask & pPriv->buttonmap[i].mask) ?
ButtonPress : ButtonRelease;
mevent.u.u.detail = pPriv->buttonmap[i].val;
(*pMouse->processInputProc)(&mevent, pMouse, 1);
}
}
pPriv->buttonstate = pQ->bmask;
}
#else /* X11R4 */
static
mouseEvent(pMouse, dx, dy, bmask, time)
DevicePtr pMouse;
int dx, dy, bmask;
{
xEvent mevent;
int i;
int nbuttons;
MousePrivPtr pPriv;
lastEventTime = time;
pPriv = (MousePrivPtr) pMouse->devicePrivate;
/* a motion event? do cursor chase */
if (dx || dy)
{
dx = mouseAccel (pMouse, dx);
dy = mouseAccel (pMouse, dy);
miPointerDeltaCursor (dx, dy, time);
}
/* button change state? notify server. */
if (nbuttons = bmask ^ pPriv->buttonstate) {
mevent.u.keyButtonPointer.time = lastEventTime;
for(i=0;i<NBUTTONS;i++)
if (pPriv->buttonmap[i].mask&nbuttons) {
mevent.u.u.type =
(bmask & pPriv->buttonmap[i].mask) ?
ButtonPress : ButtonRelease;
mevent.u.u.detail = pPriv->buttonmap[i].val;
mieqEnqueue (&mevent);
}
}
pPriv->buttonstate = bmask;
}
#endif /* X11R4 */