aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/programs/Xserver/hw/sunLynx/sunLyMouse.c
diff options
context:
space:
mode:
Diffstat (limited to 'nx-X11/programs/Xserver/hw/sunLynx/sunLyMouse.c')
-rw-r--r--nx-X11/programs/Xserver/hw/sunLynx/sunLyMouse.c649
1 files changed, 649 insertions, 0 deletions
diff --git a/nx-X11/programs/Xserver/hw/sunLynx/sunLyMouse.c b/nx-X11/programs/Xserver/hw/sunLynx/sunLyMouse.c
new file mode 100644
index 000000000..00df3db7c
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/sunLynx/sunLyMouse.c
@@ -0,0 +1,649 @@
+/* $Xorg: sunLyMouse.c,v 1.3 2000/08/17 19:48:37 cpqbld Exp $ */
+/*
+ * This is sunMouse.c modified for LynxOS
+ * Copyright 1996 by Thomas Mueller
+ *
+ * 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 Thomas Mueller not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Thomas Mueller makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THOMAS MUELLER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THOMAS MUELLER 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.
+ *
+ */
+/* $XFree86: xc/programs/Xserver/hw/sunLynx/sunLyMouse.c,v 3.3 2001/01/17 22:36:53 dawes Exp $ */
+
+/*-
+ * Copyright 1987 by the Regents of the University of California
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies. The University of California
+ * makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without
+ * express or implied warranty.
+ */
+
+/************************************************************
+Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright no-
+tice appear in all copies and that both that copyright no-
+tice and this permission notice appear in supporting docu-
+mentation, and that the names of Sun or The Open Group
+not be used in advertising or publicity pertaining to
+distribution of the software without specific prior
+written permission. Sun and The Open Group make no
+representations about the suitability of this software for
+any purpose. It is provided "as is" without any express or
+implied warranty.
+
+SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
+NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI-
+ABLE 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.
+
+********************************************************/
+/*
+ * Copyright 1991, 1992, 1993 Kaleb S. Keithley
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies. Kaleb S. Keithley makes no
+ * representations about the suitability of this software for
+ * any purpose. It is provided "as is" without express or
+ * implied warranty.
+ */
+
+#define NEED_EVENTS
+#include "sun.h"
+
+Bool sunActiveZaphod = TRUE;
+
+static Bool sunCursorOffScreen();
+static void sunCrossScreen();
+static void sunWarpCursor();
+
+miPointerScreenFuncRec sunPointerScreenFuncs = {
+ sunCursorOffScreen,
+ sunCrossScreen,
+ sunWarpCursor,
+};
+
+/*-
+ *-----------------------------------------------------------------------
+ * sunMouseCtrl --
+ * Alter the control parameters for the mouse. Since acceleration
+ * etc. is done from the PtrCtrl record in the mouse's device record,
+ * there's nothing to do here.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static
+void sunMouseCtrl (
+ DeviceIntPtr device,
+ PtrCtrl* ctrl)
+{
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * sunMouseProc --
+ * Handle the initialization, etc. of a mouse
+ *
+ * Results:
+ * none.
+ *
+ * Side Effects:
+ *
+ * Note:
+ * When using sunwindows, all input comes off a single fd, stored in the
+ * global windowFd. Therefore, only one device should be enabled and
+ * disabled, even though the application still sees both mouse and
+ * keyboard. We have arbitrarily chosen to enable and disable windowFd
+ * in the keyboard routine sunKbdProc rather than in sunMouseProc.
+ *
+ *-----------------------------------------------------------------------
+ */
+int sunMouseProc (
+ DeviceIntPtr device,
+ int what)
+{
+ struct termio tty;
+ DevicePtr pMouse = (DevicePtr) device;
+ int format;
+ static int oformat;
+ BYTE map[4];
+ char *dev;
+
+ switch (what) {
+ case DEVICE_INIT:
+ if (pMouse != LookupPointerDevice()) {
+ ErrorF ("Cannot open non-system mouse");
+ return !Success;
+ }
+ if (sunPtrPriv.fd == -1)
+ return !Success;
+ pMouse->devicePrivate = (pointer) &sunPtrPriv;
+ pMouse->on = FALSE;
+ map[1] = 1;
+ map[2] = 2;
+ map[3] = 3;
+ InitPointerDeviceStruct(
+ pMouse, map, 3, miPointerGetMotionEvents,
+ sunMouseCtrl, miPointerGetMotionBufferSize());
+ break;
+
+ case DEVICE_ON:
+ /* set mouse to raw mode */
+ if (ioctl(sunPtrPriv.fd, TCGETA, &tty) != -1) {
+ tty.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP);
+ tty.c_oflag = 0;
+ tty.c_cflag = CREAD | CS8;
+ tty.c_lflag = 0;
+ tty.c_line = 0;
+ tty.c_cc[VTIME] = 0;
+ tty.c_cc[VMIN] = 0;
+ if (ioctl(sunPtrPriv.fd, TCSETAW, &tty) < 0)
+ perror("ioctl TCSETAW");
+ } else
+ perror("ioctl TCGETA");
+ sunPtrPriv.bmask = 0;
+ AddEnabledDevice (sunPtrPriv.fd);
+ pMouse->on = TRUE;
+ break;
+
+ case DEVICE_CLOSE:
+ pMouse->on = FALSE;
+ break;
+
+ case DEVICE_OFF:
+ pMouse->on = FALSE;
+ RemoveEnabledDevice (sunPtrPriv.fd);
+ break;
+ }
+ return Success;
+}
+
+/* mouse protocol code from XFree86 */
+
+#define P_MS 0 /* Microsoft */
+#define P_MSC 1 /* Mouse Systems Corp */
+#define P_MM 2 /* MMseries */
+#define P_LOGI 3 /* Logitech */
+#define P_BM 4 /* BusMouse ??? */
+#define P_LOGIMAN 5 /* MouseMan / TrackMan
+ [CHRIS-211092] */
+#define P_PS2 6 /* PS/2 mouse */
+#define P_MMHIT 7 /* MM_HitTab */
+
+static int
+xf86MouseProtocol(rBuf, nBytes, evBuf)
+ unsigned char *rBuf;
+ int nBytes;
+ Firm_event evBuf[];
+{
+ int i, buttons, dx, dy;
+ static int pBufP = 0;
+ static unsigned char pBuf[8];
+ static int lastButtons;
+ int change;
+ int numEvents = 0;
+
+ const int mseType = P_MSC;
+ const int chordMiddle = 0;
+
+ static unsigned char proto[8][5] = {
+ /* hd_mask hd_id dp_mask dp_id nobytes */
+ { 0x40, 0x40, 0x40, 0x00, 3 }, /* MicroSoft */
+ { 0xf8, 0x80, 0x00, 0x00, 5 }, /* MouseSystems */
+ { 0xe0, 0x80, 0x80, 0x00, 3 }, /* MMSeries */
+ { 0xe0, 0x80, 0x80, 0x00, 3 }, /* Logitech */
+ { 0xf8, 0x80, 0x00, 0x00, 5 }, /* BusMouse */
+ { 0x40, 0x40, 0x40, 0x00, 3 }, /* MouseMan
+ [CHRIS-211092] */
+ { 0xc0, 0x00, 0x00, 0x00, 3 }, /* PS/2 mouse */
+ { 0xe0, 0x80, 0x80, 0x00, 3 }, /* MM_HitTablet */
+ };
+
+ for ( i=0; i < nBytes; i++) {
+ /*
+ * Hack for resyncing: We check here for a package that is:
+ * a) illegal (detected by wrong data-package header)
+ * b) invalid (0x80 == -128 and that might be wrong for MouseSystems)
+ * c) bad header-package
+ *
+ * NOTE: b) is a voilation of the MouseSystems-Protocol, since values of
+ * -128 are allowed, but since they are very seldom we can easily
+ * use them as package-header with no button pressed.
+ * NOTE/2: On a PS/2 mouse any byte is valid as a data byte. Furthermore,
+ * 0x80 is not valid as a header byte. For a PS/2 mouse we skip
+ * checking data bytes.
+ * For resyncing a PS/2 mouse we require the two most significant
+ * bits in the header byte to be 0. These are the overflow bits,
+ * and in case of an overflow we actually lose sync. Overflows
+ * are very rare, however, and we quickly gain sync again after
+ * an overflow condition. This is the best we can do. (Actually,
+ * we could use bit 0x08 in the header byte for resyncing, since
+ * that bit is supposed to be always on, but nobody told
+ * Microsoft...)
+ */
+ if (pBufP != 0 && mseType != P_PS2 &&
+ ((rBuf[i] & proto[mseType][2]) != proto[mseType][3]
+ || rBuf[i] == 0x80))
+ {
+ pBufP = 0; /* skip package */
+ }
+
+ if (pBufP == 0 &&
+ (rBuf[i] & proto[mseType][0]) != proto[mseType][1])
+ {
+ /*
+ * Hack for Logitech MouseMan Mouse - Middle button
+ *
+ * Unfortunately this mouse has variable length packets: the standard
+ * Microsoft 3 byte packet plus an optional 4th byte whenever the
+ * middle button status changes.
+ *
+ * We have already processed the standard packet with the movement
+ * and button info. Now post an event message with the old status
+ * of the left and right buttons and the updated middle button.
+ */
+
+ /*
+ * Even worse, different MouseMen and TrackMen differ in the 4th
+ * byte: some will send 0x00/0x20, others 0x01/0x21, or even
+ * 0x02/0x22, so I have to strip off the lower bits. [CHRIS-211092]
+ */
+ if ((mseType == P_MS || mseType == P_LOGIMAN)
+ && (char)(rBuf[i] & ~0x23) == 0)
+ {
+ buttons = ((int)(rBuf[i] & 0x20) >> 4)
+ | (lastButtons & 0x05);
+
+ change = buttons ^ lastButtons;
+ /* a little naive, but sufficient for now */
+ if (change & 4)
+ {
+ evBuf[numEvents].id = MS_LEFT;
+ evBuf[numEvents].value = (buttons & 4) ? VKEY_DOWN : VKEY_UP;
+ ++numEvents;
+ }
+ if (change & 2)
+ {
+ evBuf[numEvents].id = MS_MIDDLE;
+ evBuf[numEvents].value = (buttons & 2) ? VKEY_DOWN : VKEY_UP;
+ ++numEvents;
+ }
+ if (change & 1)
+ {
+ evBuf[numEvents].id = MS_RIGHT;
+ evBuf[numEvents].value = (buttons & 1) ? VKEY_DOWN : VKEY_UP;
+ ++numEvents;
+ }
+ lastButtons = buttons;
+ }
+
+ continue; /* skip package */
+ }
+
+
+ pBuf[pBufP++] = rBuf[i];
+ if (pBufP != proto[mseType][4]) continue;
+
+
+ /*
+ * assembly full package
+ */
+ switch(mseType) {
+
+ case P_LOGIMAN: /* MouseMan / TrackMan [CHRIS-211092] */
+ case P_MS: /* Microsoft */
+ if (chordMiddle)
+ buttons = (((int) pBuf[0] & 0x30) == 0x30) ? 2 :
+ ((int)(pBuf[0] & 0x20) >> 3)
+ | ((int)(pBuf[0] & 0x10) >> 4);
+ else {
+ buttons = (lastButtons & 2)
+ | ((int)(pBuf[0] & 0x20) >> 3)
+ | ((int)(pBuf[0] & 0x10) >> 4);
+ }
+ dx = (char)((pBuf[0] & 0x03) << 6) | (pBuf[1] & 0x3F);
+ dy = (char)((pBuf[0] & 0x0C) << 4) | (pBuf[2] & 0x3F);
+ break;
+
+ case P_MSC: /* Mouse Systems Corp */
+ buttons = (~pBuf[0]) & 0x07;
+ dx = (char)(pBuf[1]) + (char)(pBuf[3]);
+ dy = - ((char)(pBuf[2]) + (char)(pBuf[4]));
+ break;
+
+
+ case P_MMHIT: /* MM_HitTablet */
+ buttons = pBuf[0] & 0x07;
+ if (buttons != 0)
+ buttons = 1 << (buttons - 1);
+ dx = (pBuf[0] & 0x10) ? pBuf[1] : - pBuf[1];
+ dy = (pBuf[0] & 0x08) ? - pBuf[2] : pBuf[2];
+ break;
+
+ case P_MM: /* MM Series */
+ case P_LOGI: /* Logitech Mice */
+ buttons = pBuf[0] & 0x07;
+ dx = (pBuf[0] & 0x10) ? pBuf[1] : - pBuf[1];
+ dy = (pBuf[0] & 0x08) ? - pBuf[2] : pBuf[2];
+ break;
+
+ case P_BM: /* BusMouse */
+ buttons = (~pBuf[0]) & 0x07;
+ dx = pBuf[1];
+ dy = - pBuf[2];
+ break;
+
+ case P_PS2: /* PS/2 mouse */
+ buttons = (pBuf[0] & 0x04) >> 1 | /* Middle */
+ (pBuf[0] & 0x02) >> 1 | /* Right */
+ (pBuf[0] & 0x01) << 2; /* Left */
+ dx = (pBuf[0] & 0x10) ? pBuf[1]-256 : pBuf[1];
+ dy = (pBuf[0] & 0x20) ? -(pBuf[2]-256) : -pBuf[2];
+ break;
+ }
+
+ /* a little naive, but sufficient for now */
+ change = buttons ^ lastButtons;
+ if (change & 4)
+ {
+ evBuf[numEvents].id = MS_LEFT;
+ evBuf[numEvents].value = (buttons & 4) ? VKEY_DOWN : VKEY_UP;
+ ++numEvents;
+ }
+ if (change & 2)
+ {
+ evBuf[numEvents].id = MS_MIDDLE;
+ evBuf[numEvents].value = (buttons & 2) ? VKEY_DOWN : VKEY_UP;
+ ++numEvents;
+ }
+ if (change & 1)
+ {
+ evBuf[numEvents].id = MS_RIGHT;
+ evBuf[numEvents].value = (buttons & 1) ? VKEY_DOWN : VKEY_UP;
+ ++numEvents;
+ }
+ lastButtons = buttons;
+
+ if (dx)
+ {
+ evBuf[numEvents].id = LOC_X_DELTA;
+ evBuf[numEvents].value = dx;
+ ++numEvents;
+ }
+ if (dy)
+ {
+ evBuf[numEvents].id = LOC_Y_DELTA;
+ evBuf[numEvents].value = -dy;
+ ++numEvents;
+ }
+ pBufP = 0;
+ }
+ return numEvents;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * sunMouseGetEvents --
+ * Return the events waiting in the wings for the given mouse.
+ *
+ * Results:
+ * A pointer to an array of Firm_events or (Firm_event *)0 if no events
+ * The number of events contained in the array.
+ * A boolean as to whether more events might be available.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ */
+
+Firm_event* sunMouseGetEvents (
+ int fd,
+ Bool on,
+ int* pNumEvents,
+ Bool* pAgain)
+{
+ static Firm_event evBuf[MAXEVENTS]; /* Buffer for Firm_events */
+ int nBytes; /* number of bytes available. */
+ char buf[8];
+
+ if ((nBytes = read(fd, buf, sizeof(buf))) == -1) {
+ if (errno == EWOULDBLOCK || errno == EAGAIN || errno == EINTR) {
+ *pNumEvents = 0;
+ if (errno == EINTR)
+ *pAgain = TRUE;
+ else
+ *pAgain = FALSE;
+ } else {
+ Error ("sunMouseGetEvents read");
+ FatalError ("Could not read from mouse");
+ }
+ } else {
+ if (on) {
+ *pAgain = (nBytes == sizeof(buf)); /* very unlikely... */
+ if (*pNumEvents = xf86MouseProtocol(buf, nBytes, evBuf))
+ {
+ struct timeval now;
+ int i;
+
+ X_GETTIMEOFDAY(&now);
+ for (i=0;i<*pNumEvents;i++)
+ evBuf[i].time = now;
+ }
+ } else {
+ *pNumEvents = 0;
+ *pAgain = FALSE;
+ }
+ }
+ return evBuf;
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * MouseAccelerate --
+ * Given a delta and a mouse, return the acceleration of the delta.
+ *
+ * Results:
+ * The corrected delta
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+static short
+MouseAccelerate (device, delta)
+ DeviceIntPtr device;
+ int delta;
+{
+ int sgn = sign(delta);
+ PtrCtrl *pCtrl;
+ short ret;
+
+ delta = abs(delta);
+ pCtrl = &device->ptrfeed->ctrl;
+ if (delta > pCtrl->threshold) {
+ ret =
+ (short) sgn *
+ (pCtrl->threshold + ((delta - pCtrl->threshold) * pCtrl->num) /
+ pCtrl->den);
+ } else {
+ ret = (short) sgn * delta;
+ }
+ return ret;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * sunMouseEnqueueEvent --
+ * Given a Firm_event for a mouse, pass it off the the dix layer
+ * properly converted...
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * The cursor may be redrawn...? devPrivate/x/y will be altered.
+ *
+ *-----------------------------------------------------------------------
+ */
+
+void sunMouseEnqueueEvent (
+ DeviceIntPtr device,
+ Firm_event *fe)
+{
+ xEvent xE;
+ sunPtrPrivPtr pPriv; /* Private data for pointer */
+ int bmask; /* Temporary button mask */
+ unsigned long time;
+ int x, y;
+
+ pPriv = (sunPtrPrivPtr)device->public.devicePrivate;
+
+ time = xE.u.keyButtonPointer.time = TVTOMILLI(fe->time);
+
+ switch (fe->id) {
+ case MS_LEFT:
+ case MS_MIDDLE:
+ case MS_RIGHT:
+ /*
+ * A button changed state. Sometimes we will get two events
+ * for a single state change. Should we get a button event which
+ * reflects the current state of affairs, that event is discarded.
+ *
+ * Mouse buttons start at 1.
+ */
+ xE.u.u.detail = (fe->id - MS_LEFT) + 1;
+ bmask = 1 << xE.u.u.detail;
+ if (fe->value == VKEY_UP) {
+ if (pPriv->bmask & bmask) {
+ xE.u.u.type = ButtonRelease;
+ pPriv->bmask &= ~bmask;
+ } else {
+ return;
+ }
+ } else {
+ if ((pPriv->bmask & bmask) == 0) {
+ xE.u.u.type = ButtonPress;
+ pPriv->bmask |= bmask;
+ } else {
+ return;
+ }
+ }
+ mieqEnqueue (&xE);
+ break;
+ case LOC_X_DELTA:
+ miPointerDeltaCursor (MouseAccelerate(device,fe->value),0,time);
+ break;
+ case LOC_Y_DELTA:
+ /*
+ * For some reason, motion up generates a positive y delta
+ * and motion down a negative delta, so we must subtract
+ * here instead of add...
+ */
+ miPointerDeltaCursor (0,-MouseAccelerate(device,fe->value),time);
+ break;
+ case LOC_X_ABSOLUTE:
+ miPointerPosition (&x, &y);
+ miPointerAbsoluteCursor (fe->value, y, time);
+ break;
+ case LOC_Y_ABSOLUTE:
+ miPointerPosition (&x, &y);
+ miPointerAbsoluteCursor (x, fe->value, time);
+ break;
+ default:
+ FatalError ("sunMouseEnqueueEvent: unrecognized id\n");
+ break;
+ }
+}
+
+/*ARGSUSED*/
+static Bool
+sunCursorOffScreen (pScreen, x, y)
+ ScreenPtr *pScreen;
+ int *x, *y;
+{
+ int index, ret = FALSE;
+ extern Bool PointerConfinedToScreen();
+
+ if (PointerConfinedToScreen()) return TRUE;
+ /*
+ * Active Zaphod implementation:
+ * increment or decrement the current screen
+ * if the x is to the right or the left of
+ * the current screen.
+ */
+ if (sunActiveZaphod &&
+ screenInfo.numScreens > 1 && (*x >= (*pScreen)->width || *x < 0)) {
+ index = (*pScreen)->myNum;
+ if (*x < 0) {
+ index = (index ? index : screenInfo.numScreens) - 1;
+ *pScreen = screenInfo.screens[index];
+ *x += (*pScreen)->width;
+ } else {
+ *x -= (*pScreen)->width;
+ index = (index + 1) % screenInfo.numScreens;
+ *pScreen = screenInfo.screens[index];
+ }
+ ret = TRUE;
+ }
+ return ret;
+}
+
+static void
+sunCrossScreen (pScreen, entering)
+ ScreenPtr pScreen;
+ Bool entering;
+{
+ if (sunFbs[pScreen->myNum].EnterLeave)
+ (*sunFbs[pScreen->myNum].EnterLeave) (pScreen, entering ? 0 : 1);
+}
+
+static void
+sunWarpCursor (pScreen, x, y)
+ ScreenPtr pScreen;
+ int x, y;
+{
+ sigset_t newsigmask;
+
+ (void) sigemptyset (&newsigmask);
+ (void) sigaddset (&newsigmask, SIGIO);
+ (void) sigprocmask (SIG_BLOCK, &newsigmask, (sigset_t *)NULL);
+ miPointerWarpCursor (pScreen, x, y);
+ (void) sigprocmask (SIG_UNBLOCK, &newsigmask, (sigset_t *)NULL);
+}