summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2001-10-12 06:33:12 +0000
committerKeith Packard <keithp@keithp.com>2001-10-12 06:33:12 +0000
commit28fd5f7525848cf0109f9cf2d6311f3717570a5d (patch)
tree70adc7664477ac1c13ed92dcf62bee23a3b22e21
parent5f310d7f8b566b1e331286752d349f87ef43a811 (diff)
kdrive: add new auto-detecting and auto-switching mouse driver
-rw-r--r--hw/kdrive/chips/chipsstub.c4
-rw-r--r--hw/kdrive/fbdev/fbinit.c8
-rw-r--r--hw/kdrive/i810/i810stub.c2
-rw-r--r--hw/kdrive/igs/igsstub.c4
-rw-r--r--hw/kdrive/ipaq/ipaq.c8
-rw-r--r--hw/kdrive/linux/Imakefile6
-rw-r--r--hw/kdrive/linux/bus.c4
-rw-r--r--hw/kdrive/linux/keyboard.c4
-rw-r--r--hw/kdrive/linux/mouse.c917
-rw-r--r--hw/kdrive/linux/ms.c22
-rw-r--r--hw/kdrive/linux/ps2.c4
-rw-r--r--hw/kdrive/mach64/mach64stub.c4
-rw-r--r--hw/kdrive/pcmcia/pcmciastub.c4
-rw-r--r--hw/kdrive/savage/s3stub.c4
-rw-r--r--hw/kdrive/sis530/sisstub.c4
-rw-r--r--hw/kdrive/src/kdrive.c120
-rw-r--r--hw/kdrive/src/kdrive.h53
-rw-r--r--hw/kdrive/src/kinfo.c36
-rw-r--r--hw/kdrive/src/kinput.c301
-rw-r--r--hw/kdrive/trident/tridentstub.c4
-rw-r--r--hw/kdrive/trio/s3stub.c4
-rw-r--r--hw/kdrive/ts300/ts300.c4
-rw-r--r--hw/kdrive/vesa/vesainit.c4
23 files changed, 1324 insertions, 201 deletions
diff --git a/hw/kdrive/chips/chipsstub.c b/hw/kdrive/chips/chipsstub.c
index 5c8a6d4c6..52dac0d97 100644
--- a/hw/kdrive/chips/chipsstub.c
+++ b/hw/kdrive/chips/chipsstub.c
@@ -22,7 +22,7 @@
*
* Author: Keith Packard, SuSE, Inc.
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/chips/chipsstub.c,v 1.5 2000/11/29 08:42:25 keithp Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/chips/chipsstub.c,v 1.1 2001/09/05 07:12:42 keithp Exp $ */
#include "chips.h"
@@ -45,7 +45,7 @@ InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
void
InitInput (int argc, char **argv)
{
- KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs);
+ KdInitInput (&LinuxMouseFuncs, &LinuxKeyboardFuncs);
}
int
diff --git a/hw/kdrive/fbdev/fbinit.c b/hw/kdrive/fbdev/fbinit.c
index 512382d06..7d70e6eae 100644
--- a/hw/kdrive/fbdev/fbinit.c
+++ b/hw/kdrive/fbdev/fbinit.c
@@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/fbdev/fbinit.c,v 1.7 2001/05/23 08:56:08 alanh Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/fbdev/fbinit.c,v 1.8 2001/05/29 17:47:55 keithp Exp $ */
#include <fbdev.h>
@@ -42,11 +42,7 @@ InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
void
InitInput (int argc, char **argv)
{
-#ifdef __powerpc__
- KdInitInput (&BusMouseFuncs, &LinuxKeyboardFuncs);
-#else
- KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs);
-#endif
+ KdInitInput (&LinuxMouseFuncs, &LinuxKeyboardFuncs);
#ifdef TOUCHSCREEN
KdInitTouchScreen (&TsFuncs);
#endif
diff --git a/hw/kdrive/i810/i810stub.c b/hw/kdrive/i810/i810stub.c
index f7097c7d8..f7fbbe259 100644
--- a/hw/kdrive/i810/i810stub.c
+++ b/hw/kdrive/i810/i810stub.c
@@ -66,7 +66,7 @@ InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
void
InitInput (int argc, char **argv)
{
- KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs);
+ KdInitInput (&LinuxMouseFuncs, &LinuxKeyboardFuncs);
}
int
diff --git a/hw/kdrive/igs/igsstub.c b/hw/kdrive/igs/igsstub.c
index af526a0e0..9d5949aa3 100644
--- a/hw/kdrive/igs/igsstub.c
+++ b/hw/kdrive/igs/igsstub.c
@@ -1,5 +1,5 @@
/*
- * $XFree86: xc/programs/Xserver/hw/kdrive/igs/igsstub.c,v 1.1 2000/05/06 22:17:44 keithp Exp $
+ * $XFree86: xc/programs/Xserver/hw/kdrive/igs/igsstub.c,v 1.2 2000/05/24 23:52:48 keithp Exp $
*
* Copyright © 2000 Keith Packard
*
@@ -53,7 +53,7 @@ InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
void
InitInput (int argc, char **argv)
{
- KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs);
+ KdInitInput (&LinuxMouseFuncs, &LinuxKeyboardFuncs);
}
int
diff --git a/hw/kdrive/ipaq/ipaq.c b/hw/kdrive/ipaq/ipaq.c
index 35963f6f3..53fb7fd4a 100644
--- a/hw/kdrive/ipaq/ipaq.c
+++ b/hw/kdrive/ipaq/ipaq.c
@@ -22,7 +22,7 @@
* Adapted from ts300.c by Alan Hourihane <alanh@fairlite.demon.co.uk>
* For the Compaq IPAQ handheld, with the HP VGA Out Card (F1252A).
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/ipaq/ipaq.c,v 1.1 2001/05/23 17:28:39 alanh Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/ipaq/ipaq.c,v 1.2 2001/05/29 17:47:55 keithp Exp $ */
#include "pcmcia.h"
@@ -47,11 +47,7 @@ InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
void
InitInput (int argc, char **argv)
{
-#ifdef __powerpc__
- KdInitInput (&BusMouseFuncs, &LinuxKeyboardFuncs);
-#else
- KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs);
-#endif
+ KdInitInput (&LinuxMouseFuncs, &LinuxKeyboardFuncs);
#ifdef TOUCHSCREEN
KdInitTouchScreen (&TsFuncs);
#endif
diff --git a/hw/kdrive/linux/Imakefile b/hw/kdrive/linux/Imakefile
index 51ff075d8..69a08d2e0 100644
--- a/hw/kdrive/linux/Imakefile
+++ b/hw/kdrive/linux/Imakefile
@@ -1,5 +1,5 @@
XCOMM $XConsortium: Imakefile /main/10 1996/12/02 10:20:33 lehors $
-XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/linux/Imakefile,v 1.6 2001/08/09 20:45:15 dawes Exp $
+XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/linux/Imakefile,v 1.7 2001/09/29 04:16:39 keithp Exp $
KDRIVE=..
#include "../Kdrive.tmpl"
@@ -8,9 +8,9 @@ TSSRCS = ts.c
TSOBJS = ts.o
#endif
-SRCS = keyboard.c linux.c ps2.c ms.c bus.c agp.c $(TSSRCS)
+SRCS = keyboard.c linux.c mouse.c ps2.c bus.c ms.c agp.c $(TSSRCS)
-OBJS = keyboard.o linux.o ps2.o ms.o bus.o agp.o $(TSOBJS)
+OBJS = keyboard.o linux.o mouse.o ps2.o bus.o ms.o agp.o $(TSOBJS)
INCLUDES = -I. $(KDINCS)
diff --git a/hw/kdrive/linux/bus.c b/hw/kdrive/linux/bus.c
index 0237e5279..58afc1f8c 100644
--- a/hw/kdrive/linux/bus.c
+++ b/hw/kdrive/linux/bus.c
@@ -1,5 +1,5 @@
/*
- * $XFree86$
+ * $XFree86: xc/programs/Xserver/hw/kdrive/linux/bus.c,v 1.2 2001/06/29 14:00:41 keithp Exp $
*
* Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
*
@@ -53,7 +53,7 @@ BusRead (int adbPort, void *closure)
flags |= KD_BUTTON_2;
if ((buf[0] & 1) == 0)
flags |= KD_BUTTON_3;
- KdEnqueueMouseEvent (flags, dx, dy);
+ KdEnqueueMouseEvent (kdMouseInfo, flags, dx, dy);
}
}
diff --git a/hw/kdrive/linux/keyboard.c b/hw/kdrive/linux/keyboard.c
index 12486adc5..2f8477d4c 100644
--- a/hw/kdrive/linux/keyboard.c
+++ b/hw/kdrive/linux/keyboard.c
@@ -1,5 +1,5 @@
/*
- * $XFree86: xc/programs/Xserver/hw/kdrive/linux/keyboard.c,v 1.7 2001/06/29 14:00:41 keithp Exp $
+ * $XFree86: xc/programs/Xserver/hw/kdrive/linux/keyboard.c,v 1.8 2001/09/29 04:16:39 keithp Exp $
*
* Copyright © 1999 Keith Packard
*
@@ -438,8 +438,8 @@ LinuxKeyboardInit (void)
if (!LinuxKbdType)
LinuxKbdType = KdAllocInputType ();
- LinuxKeyboardEnable (LinuxConsoleFd, 0);
KdRegisterFd (LinuxKbdType, LinuxConsoleFd, LinuxKeyboardRead, 0);
+ LinuxKeyboardEnable (LinuxConsoleFd, 0);
KdRegisterFdEnableDisable (LinuxConsoleFd,
LinuxKeyboardEnable,
LinuxKeyboardDisable);
diff --git a/hw/kdrive/linux/mouse.c b/hw/kdrive/linux/mouse.c
new file mode 100644
index 000000000..b208c0242
--- /dev/null
+++ b/hw/kdrive/linux/mouse.c
@@ -0,0 +1,917 @@
+/*
+ * $XFree86: $
+ *
+ * Copyright © 2001 Keith Packard, member of The XFree86 Project, 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "kdrive.h"
+#include "Xpoll.h"
+#include <errno.h>
+#include <termios.h>
+
+#undef DEBUG
+#undef DEBUG_BYTES
+#define KBUFIO_SIZE 256
+
+typedef struct _kbufio {
+ int fd;
+ unsigned char buf[KBUFIO_SIZE];
+ int avail;
+ int used;
+} Kbufio;
+
+Bool
+MouseWaitForReadable (int fd, int timeout)
+{
+ fd_set set;
+ struct timeval tv, *tp;
+ int n;
+
+ FD_ZERO (&set);
+ FD_SET (fd, &set);
+ if (timeout == -1)
+ tp = 0;
+ else
+ {
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout % 1000) * 1000;
+ tp = &tv;
+ }
+ n = select (fd + 1, &set, 0, 0, tp);
+ if (n > 0)
+ return TRUE;
+ return FALSE;
+}
+
+int
+MouseReadByte (Kbufio *b, int timeout)
+{
+ int n;
+ if (b->avail <= b->used)
+ {
+ if (timeout && !MouseWaitForReadable (b->fd, timeout))
+ return -1;
+ n = read (b->fd, b->buf, KBUFIO_SIZE);
+ if (n <= 0)
+ return -1;
+ b->avail = n;
+ b->used = 0;
+ }
+#ifdef DEBUG_BYTES
+ ErrorF ("\tget %02x\n", b->buf[b->used]);
+#endif
+ return b->buf[b->used++];
+}
+
+int
+MouseFlush (Kbufio *b, char *buf, int size)
+{
+ CARD32 now = GetTimeInMillis ();
+ CARD32 done = now + 100;
+ int p = 0;
+ int c;
+ int n = 0;
+
+ while ((c = MouseReadByte (b, done - now)) != -1)
+ {
+ if (buf)
+ {
+ if (n == size)
+ {
+ memmove (buf, buf + 1, size - 1);
+ n--;
+ }
+ buf[n++] = c;
+ }
+ now = GetTimeInMillis ();
+ if ((INT32) (now - done) >= 0)
+ break;
+ }
+ return n;
+}
+
+int
+MousePeekByte (Kbufio *b, int timeout)
+{
+ int c;
+
+ c = MouseReadByte (b, timeout);
+ if (c != -1)
+ --b->used;
+ return c;
+}
+
+Bool
+MouseWaitForWritable (int fd, int timeout)
+{
+ fd_set set;
+ struct timeval tv, *tp;
+ int n;
+
+ FD_ZERO (&set);
+ FD_SET (fd, &set);
+ if (timeout == -1)
+ tp = 0;
+ else
+ {
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout % 1000) * 1000;
+ tp = &tv;
+ }
+ n = select (fd + 1, 0, &set, 0, tp);
+ if (n > 0)
+ return TRUE;
+ return FALSE;
+}
+
+Bool
+MouseWriteByte (int fd, unsigned char c, int timeout)
+{
+ int ret;
+
+#ifdef DEBUG_BYTES
+ ErrorF ("\tput %02x\n", c);
+#endif
+ for (;;)
+ {
+ ret = write (fd, &c, 1);
+ if (ret == 1)
+ return TRUE;
+ if (ret == 0)
+ return FALSE;
+ if (errno != EWOULDBLOCK)
+ return FALSE;
+ if (!MouseWaitForWritable (fd, timeout))
+ return FALSE;
+ }
+}
+
+Bool
+MouseWriteBytes (int fd, unsigned char *c, int n, int timeout)
+{
+ while (n--)
+ if (!MouseWriteByte (fd, *c++, timeout))
+ return FALSE;
+ return TRUE;
+}
+
+#define MAX_MOUSE 10 /* maximum length of mouse protocol */
+#define MAX_SKIP 16 /* number of error bytes before switching */
+#define MAX_VALID 4 /* number of valid packets before accepting */
+
+typedef struct _kmouseProt {
+ char *name;
+ Bool (*Complete) (KdMouseInfo *mi, unsigned char *ev, int ne);
+ int (*Valid) (KdMouseInfo *mi, unsigned char *ev, int ne);
+ Bool (*Parse) (KdMouseInfo *mi, unsigned char *ev, int ne);
+ Bool (*Init) (KdMouseInfo *mi);
+ unsigned char headerMask, headerValid;
+ unsigned char dataMask, dataValid;
+ Bool tty;
+ unsigned int c_iflag;
+ unsigned int c_oflag;
+ unsigned int c_lflag;
+ unsigned int c_cflag;
+ unsigned int speed;
+ unsigned char *init;
+ unsigned long state;
+} KmouseProt;
+
+typedef enum _kmouseStage {
+ MouseBroken, MouseTesting, MouseWorking
+} KmouseStage;
+
+typedef struct _kmouse {
+ Kbufio iob;
+ const KmouseProt *prot;
+ int i_prot;
+ KmouseStage stage; /* protocol verification stage */
+ Bool tty; /* mouse device is a tty */
+ int valid; /* sequential valid events */
+ int tested; /* bytes scanned during Testing phase */
+ int invalid;/* total invalid bytes for this protocol */
+ unsigned long state; /* private per protocol, init to prot->state */
+} Kmouse;
+
+static int mouseValid (KdMouseInfo *mi, unsigned char *ev, int ne)
+{
+ Kmouse *km = mi->driver;
+ const KmouseProt *prot = km->prot;
+ int i;
+
+ for (i = 0; i < ne; i++)
+ if ((ev[i] & prot->headerMask) == prot->headerValid)
+ break;
+ if (i != 0)
+ return i;
+ for (i = 1; i < ne; i++)
+ if ((ev[i] & prot->dataMask) != prot->dataValid)
+ return -1;
+ return 0;
+}
+
+static Bool threeComplete (KdMouseInfo *mi, unsigned char *ev, int ne)
+{
+ return ne == 3;
+}
+
+static Bool fourComplete (KdMouseInfo *mi, unsigned char *ev, int ne)
+{
+ return ne == 4;
+}
+
+static Bool fiveComplete (KdMouseInfo *mi, unsigned char *ev, int ne)
+{
+ return ne == 5;
+}
+
+static Bool MouseReasonable (KdMouseInfo *mi, unsigned long flags, int dx, int dy)
+{
+ Kmouse *km = mi->driver;
+
+ if (km->stage == MouseWorking)
+ return TRUE;
+ if (dx < -50 || dx > 50)
+ {
+#ifdef DEBUG
+ ErrorF ("Large X %d\n", dx);
+#endif
+ return FALSE;
+ }
+ if (dy < -50 || dy > 50)
+ {
+#ifdef DEBUG
+ ErrorF ("Large Y %d\n", dy);
+#endif
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+ * Standard PS/2 mouse protocol
+ */
+static Bool ps2Parse (KdMouseInfo *mi, unsigned char *ev, int ne)
+{
+ Kmouse *km = mi->driver;
+ int dx, dy, dz;
+ unsigned long flags;
+
+ flags = KD_MOUSE_DELTA;
+ if (ev[0] & 4)
+ flags |= KD_BUTTON_2;
+ if (ev[0] & 2)
+ flags |= KD_BUTTON_3;
+ if (ev[0] & 1)
+ flags |= KD_BUTTON_1;
+
+ if (ne > 3)
+ {
+ dz = (int) (signed char) ev[3];
+ if (dz > 0)
+ flags |= KD_BUTTON_4;
+ else if (dz < 0)
+ flags |= KD_BUTTON_5;
+ }
+
+ dx = ev[1];
+ if (ev[0] & 0x10)
+ dx -= 256;
+ dy = ev[2];
+ if (ev[0] & 0x20)
+ dy -= 256;
+ dy = -dy;
+ if (!MouseReasonable (mi, flags, dx, dy))
+ return FALSE;
+ if (km->stage == MouseWorking)
+ KdEnqueueMouseEvent (mi, flags, dx, dy);
+ return TRUE;
+}
+
+static Bool ps2Init (KdMouseInfo *mi);
+
+static const KmouseProt ps2Prot = {
+ "ps/2",
+ threeComplete, mouseValid, ps2Parse, ps2Init,
+ 0x08, 0x08, 0x00, 0x00,
+ FALSE
+};
+
+static const KmouseProt imps2Prot = {
+ "imps/2",
+ fourComplete, mouseValid, ps2Parse, ps2Init,
+ 0x08, 0x08, 0x00, 0x00,
+ FALSE
+};
+
+static const KmouseProt exps2Prot = {
+ "exps/2",
+ fourComplete, mouseValid, ps2Parse, ps2Init,
+ 0x08, 0x08, 0x00, 0x00,
+ FALSE
+};
+
+/*
+ * Once the mouse is known to speak ps/2 protocol, go and find out
+ * what advanced capabilities it has and turn them on
+ */
+static unsigned char ps2_init[] = {
+ 0xf4, 0
+};
+
+#define NINIT_PS2 1
+
+static unsigned char wheel_3button_init[] = {
+ 0xf3, 0xc8, 0xf3, 0x64, 0xf3, 0x50, 0xf2, 0
+};
+
+#define NINIT_IMPS2 4
+
+static unsigned char wheel_5button_init[] = {
+ 0xf3, 0xc8, 0xf3, 0x64, 0xf3, 0x50,
+ 0xf3, 0xc8, 0xf3, 0xc8, 0xf3, 0x50, 0xf2, 0
+};
+
+#define NINIT_EXPS2 7
+
+static unsigned char intelli_init[] = {
+ 0xf3, 0xc8, 0xf3, 0x64, 0xf3, 0x50, 0
+};
+
+#define NINIT_INTELLI 3
+
+static int
+ps2SkipInit (KdMouseInfo *mi, int ninit, Bool ret_next)
+{
+ Kmouse *km = mi->driver;
+ int c;
+ int skipping;
+ Bool waiting;
+
+ skipping = 0;
+ waiting = FALSE;
+ while (ninit || ret_next)
+ {
+ c = MouseReadByte (&km->iob, 100);
+ if (c == -1)
+ break;
+ /* look for ACK */
+ if (c == 0xfa)
+ {
+ ninit--;
+ if (ret_next)
+ waiting = TRUE;
+ }
+ /* look for packet start -- not the response */
+ else if ((c & 0x08) == 0x08)
+ waiting = FALSE;
+ else if (waiting)
+ break;
+ }
+ return c;
+}
+
+static Bool
+ps2Init (KdMouseInfo *mi)
+{
+ Kmouse *km = mi->driver;
+ int c;
+ int skipping;
+ Bool waiting;
+ int id;
+ unsigned char *init;
+ int ninit;
+
+ /* Send Intellimouse initialization sequence */
+ MouseWriteBytes (km->iob.fd, intelli_init, strlen (intelli_init), 100);
+ /*
+ * Send ID command
+ */
+ if (!MouseWriteByte (km->iob.fd, 0xf2, 100))
+ return FALSE;
+ skipping = 0;
+ waiting = FALSE;
+ id = ps2SkipInit (mi, 0, TRUE);
+ switch (id) {
+ case 3:
+ init = wheel_3button_init;
+ ninit = NINIT_IMPS2;
+ km->prot = &imps2Prot;
+ break;
+ case 4:
+ init = wheel_5button_init;
+ ninit = NINIT_EXPS2;
+ km->prot = &exps2Prot;
+ break;
+ default:
+ init = ps2_init;
+ ninit = NINIT_PS2;
+ km->prot = &ps2Prot;
+ break;
+ }
+ if (init)
+ MouseWriteBytes (km->iob.fd, init, strlen (init), 100);
+ /*
+ * Flush out the available data to eliminate responses to the
+ * initialization string. Make sure any partial event is
+ * skipped
+ */
+ (void) ps2SkipInit (mi, ninit, FALSE);
+}
+
+static Bool busParse (KdMouseInfo *mi, unsigned char *ev, int ne)
+{
+ Kmouse *km = mi->driver;
+ int dx, dy;
+ unsigned long flags;
+
+ flags = KD_MOUSE_DELTA;
+ dx = (char) ev[1];
+ dy = -(char) ev[2];
+ if ((ev[0] & 4) == 0)
+ flags |= KD_BUTTON_1;
+ if ((ev[0] & 2) == 0)
+ flags |= KD_BUTTON_2;
+ if ((ev[0] & 1) == 0)
+ flags |= KD_BUTTON_3;
+ if (!MouseReasonable (mi, flags, dx, dy))
+ return FALSE;
+ if (km->stage == MouseWorking)
+ KdEnqueueMouseEvent (mi, flags, dx, dy);
+ return TRUE;
+}
+
+static const KmouseProt busProt = {
+ "bus",
+ threeComplete, mouseValid, busParse, 0,
+ 0xf8, 0x00, 0x00, 0x00,
+ FALSE
+};
+
+/*
+ * Standard MS serial protocol, three bytes
+ */
+
+static Bool msParse (KdMouseInfo *mi, unsigned char *ev, int ne)
+{
+ Kmouse *km = mi->driver;
+ int dx, dy;
+ unsigned long flags;
+
+ flags = KD_MOUSE_DELTA;
+
+ if (ev[0] & 0x20)
+ flags |= KD_BUTTON_1;
+ if (ev[0] & 0x10)
+ flags |= KD_BUTTON_3;
+
+ dx = (char)(((ev[0] & 0x03) << 6) | (ev[1] & 0x3F));
+ dy = (char)(((ev[0] & 0x0C) << 4) | (ev[2] & 0x3F));
+ if (!MouseReasonable (mi, flags, dx, dy))
+ return FALSE;
+ if (km->stage == MouseWorking)
+ KdEnqueueMouseEvent (mi, flags, dx, dy);
+ return TRUE;
+}
+
+static const KmouseProt msProt = {
+ "ms",
+ threeComplete, mouseValid, msParse, 0,
+ 0xc0, 0x40, 0xc0, 0x00,
+ TRUE,
+ IGNPAR,
+ 0,
+ 0,
+ CS7 | CSTOPB | CREAD | CLOCAL,
+ B1200,
+};
+
+/*
+ * Logitech mice send 3 or 4 bytes, the only way to tell is to look at the
+ * first byte of a synchronized protocol stream and see if it's got
+ * any bits turned on that can't occur in that fourth byte
+ */
+static Bool logiComplete (KdMouseInfo *mi, unsigned char *ev, int ne)
+{
+ Kmouse *km = mi->driver;
+ const KmouseProt *prot = km->prot;
+ int c;
+
+ if ((ev[0] & 0x40) == 0x40)
+ return ne == 3;
+ if (km->stage != MouseBroken && (ev[0] & ~0x23) == 0)
+ return ne == 1;
+}
+
+static int logiValid (KdMouseInfo *mi, unsigned char *ev, int ne)
+{
+ Kmouse *km = mi->driver;
+ const KmouseProt *prot = km->prot;
+ int i;
+
+ for (i = 0; i < ne; i++)
+ {
+ if ((ev[i] & 0x40) == 0x40)
+ break;
+ if (km->stage != MouseBroken && (ev[i] & ~0x23) == 0)
+ break;
+ }
+ if (i != 0)
+ return i;
+ for (i = 1; i < ne; i++)
+ if ((ev[i] & prot->dataMask) != prot->dataValid)
+ return -1;
+ return 0;
+}
+
+static Bool logiParse (KdMouseInfo *mi, unsigned char *ev, int ne)
+{
+ Kmouse *km = mi->driver;
+ int dx, dy;
+ unsigned long flags;
+
+ flags = KD_MOUSE_DELTA;
+
+ if (ne == 3)
+ {
+ if (ev[0] & 0x20)
+ flags |= KD_BUTTON_1;
+ if (ev[0] & 0x10)
+ flags |= KD_BUTTON_3;
+
+ dx = (char)(((ev[0] & 0x03) << 6) | (ev[1] & 0x3F));
+ dy = (char)(((ev[0] & 0x0C) << 4) | (ev[2] & 0x3F));
+ flags |= km->state & KD_BUTTON_2;
+ }
+ else
+ {
+ if (ev[0] & 0x20)
+ flags |= KD_BUTTON_2;
+ dx = 0;
+ dy = 0;
+ flags |= km->state & (KD_BUTTON_1|KD_BUTTON_3);
+ }
+
+ if (!MouseReasonable (mi, flags, dx, dy))
+ return FALSE;
+ if (km->stage == MouseWorking)
+ KdEnqueueMouseEvent (mi, flags, dx, dy);
+ return TRUE;
+}
+
+static const KmouseProt logiProt = {
+ "logitech",
+ logiComplete, logiValid, logiParse, 0,
+ 0xc0, 0x40, 0xc0, 0x00,
+ TRUE,
+ IGNPAR,
+ 0,
+ 0,
+ CS7 | CSTOPB | CREAD | CLOCAL,
+ B1200,
+};
+
+/*
+ * Mouse systems protocol, 5 bytes
+ */
+static Bool mscParse (KdMouseInfo *mi, unsigned char *ev, int ne)
+{
+ Kmouse *km = mi->driver;
+ int dx, dy;
+ unsigned long flags;
+
+ flags = KD_MOUSE_DELTA;
+
+ if (!(ev[0] & 0x4))
+ flags |= KD_BUTTON_1;
+ if (!(ev[0] & 0x2))
+ flags |= KD_BUTTON_2;
+ if (!(ev[0] & 0x1))
+ flags |= KD_BUTTON_3;
+ dx = (char)(ev[1]) + (char)(ev[3]);
+ dy = - ((char)(ev[2]) + (char)(ev[4]));
+
+ if (!MouseReasonable (mi, flags, dx, dy))
+ return FALSE;
+ if (km->stage == MouseWorking)
+ KdEnqueueMouseEvent (mi, flags, dx, dy);
+ return TRUE;
+}
+
+static const KmouseProt mscProt = {
+ "msc",
+ fiveComplete, mouseValid, mscParse, 0,
+ 0xf8, 0x80, 0x00, 0x00,
+ TRUE,
+ IGNPAR,
+ 0,
+ 0,
+ CS8 | CSTOPB | CREAD | CLOCAL,
+ B1200,
+};
+
+/*
+ * Use logitech before ms -- they're the same except that
+ * logitech sometimes has a fourth byte
+ */
+static const KmouseProt *kmouseProts[] = {
+ &ps2Prot, &imps2Prot, &exps2Prot, &busProt, &logiProt, &msProt, &mscProt,
+};
+
+#define NUM_PROT (sizeof (kmouseProts) / sizeof (kmouseProts[0]))
+
+void
+MouseInitProtocol (Kmouse *km)
+{
+ int ret;
+ struct termios t;
+
+ if (km->prot->tty)
+ {
+ ret = tcgetattr (km->iob.fd, &t);
+
+ if (ret >= 0)
+ {
+ t.c_iflag = km->prot->c_iflag;
+ t.c_oflag = km->prot->c_oflag;
+ t.c_lflag = km->prot->c_lflag;
+ t.c_cflag = km->prot->c_cflag;
+ cfsetispeed (&t, km->prot->speed);
+ cfsetospeed (&t, km->prot->speed);
+ ret = tcsetattr (km->iob.fd, TCSANOW, &t);
+ }
+ }
+ km->stage = MouseBroken;
+ km->valid = 0;
+ km->tested = 0;
+ km->invalid = 0;
+ km->state = km->prot->state;
+}
+
+void
+MouseFirstProtocol (Kmouse *km, char *prot)
+{
+ if (prot)
+ {
+ for (km->i_prot = 0; km->i_prot < NUM_PROT; km->i_prot++)
+ if (!strcmp (prot, kmouseProts[km->i_prot]->name))
+ break;
+ if (km->i_prot == NUM_PROT)
+ {
+ int i;
+ ErrorF ("Unknown mouse protocol \"%s\". Pick one of:", prot);
+ for (i = 0; i < NUM_PROT; i++)
+ ErrorF (" %s", kmouseProts[i]->name);
+ ErrorF ("\n");
+ }
+ else
+ {
+ km->prot = kmouseProts[km->i_prot];
+ if (km->tty && !km->prot->tty)
+ ErrorF ("Mouse device is serial port, protocol %s is not serial protocol\n",
+ prot);
+ else if (!km->tty && km->prot->tty)
+ ErrorF ("Mouse device is not serial port, protocol %s is serial protocol\n",
+ prot);
+ }
+ }
+ if (!km->prot)
+ {
+ for (km->i_prot = 0; kmouseProts[km->i_prot]->tty != km->tty; km->i_prot++)
+ ;
+ km->prot = kmouseProts[km->i_prot];
+ }
+ MouseInitProtocol (km);
+}
+
+void
+MouseNextProtocol (Kmouse *km)
+{
+ do
+ {
+ if (!km->prot)
+ km->i_prot = 0;
+ else
+ if (++km->i_prot == NUM_PROT) km->i_prot = 0;
+ km->prot = kmouseProts[km->i_prot];
+ } while (km->prot->tty != km->tty);
+ MouseInitProtocol (km);
+ ErrorF ("Switching to mouse protocol \"%s\"\n", km->prot->name);
+}
+
+void
+MouseRead (int mousePort, void *closure)
+{
+ KdMouseInfo *mi = closure;
+ Kmouse *km = mi->driver;
+ unsigned char event[MAX_MOUSE];
+ int ne;
+ int c;
+ int i;
+ int timeout;
+
+ timeout = 0;
+ ne = 0;
+ for(;;)
+ {
+ c = MouseReadByte (&km->iob, timeout);
+ if (c == -1)
+ {
+ if (ne)
+ {
+ km->invalid += ne + km->tested;
+ km->valid = 0;
+ km->tested = 0;
+ km->stage = MouseBroken;
+ }
+ break;
+ }
+ event[ne++] = c;
+ i = (*km->prot->Valid) (mi, event, ne);
+ if (i != 0)
+ {
+#ifdef DEBUG
+ ErrorF ("Mouse protocol %s broken %d of %d bytes bad\n",
+ km->prot->name, i > 0 ? i : ne, ne);
+#endif
+ if (i > 0 && i < ne)
+ {
+ ne -= i;
+ memmove (event, event + i, ne);
+ }
+ else
+ {
+ i = ne;
+ ne = 0;
+ }
+ km->invalid += i + km->tested;
+ km->valid = 0;
+ km->tested = 0;
+ km->stage = MouseBroken;
+ if (km->invalid > MAX_SKIP)
+ {
+ MouseNextProtocol (km);
+ ne = 0;
+ }
+ timeout = 0;
+ }
+ else
+ {
+ if ((*km->prot->Complete) (mi, event, ne))
+ {
+ if ((*km->prot->Parse) (mi, event, ne))
+ {
+ switch (km->stage)
+ {
+ case MouseBroken:
+#ifdef DEBUG
+ ErrorF ("Mouse protocol %s seems OK\n",
+ km->prot->name);
+#endif
+ /* do not zero invalid to accumulate invalid bytes */
+ km->valid = 0;
+ km->tested = 0;
+ km->stage = MouseTesting;
+ /* fall through ... */
+ case MouseTesting:
+ km->valid++;
+ km->tested += ne;
+ if (km->valid > MAX_VALID)
+ {
+#ifdef DEBUG
+ ErrorF ("Mouse protocol %s working\n",
+ km->prot->name);
+#endif
+ km->stage = MouseWorking;
+ km->invalid = 0;
+ km->tested = 0;
+ km->valid = 0;
+ if (km->prot->Init && !(*km->prot->Init) (mi))
+ km->stage = MouseBroken;
+ }
+ break;
+ }
+ }
+ else
+ {
+ km->invalid += ne + km->tested;
+ km->valid = 0;
+ km->tested = 0;
+ km->stage = MouseBroken;
+ }
+ ne = 0;
+ timeout = 0;
+ }
+ else
+ timeout = 100;
+ }
+ }
+}
+
+int MouseInputType;
+
+char *kdefaultMouse[] = {
+ "/dev/mouse",
+ "/dev/psaux",
+ "/dev/input/mice",
+ "/dev/adbmouse",
+ "/dev/ttyS0",
+ "/dev/ttyS1",
+};
+
+#define NUM_DEFAULT_MOUSE (sizeof (kdefaultMouse) / sizeof (kdefaultMouse[0]))
+
+int
+MouseInit (void)
+{
+ int i;
+ int fd;
+ Kmouse *km;
+ KdMouseInfo *mi, *next;
+ KmouseProt *mp;
+ int n = 0;
+ char *prot;
+
+ for (mi = kdMouseInfo; mi; mi = next)
+ {
+ next = mi->next;
+ prot = mi->prot;
+ if (!mi->name)
+ {
+ for (i = 0; i < NUM_DEFAULT_MOUSE; i++)
+ {
+ fd = open (kdefaultMouse[i], 2);
+ if (fd >= 0)
+ {
+ mi->name = KdSaveString (kdefaultMouse[i]);
+ break;
+ }
+ }
+ }
+ else
+ fd = open (mi->name, 2);
+
+ if (fd >= 0)
+ {
+ km = (Kmouse *) xalloc (sizeof (Kmouse));
+ if (km)
+ {
+ km->tty = isatty (fd);
+ mi->driver = km;
+ km->iob.fd = fd;
+ km->iob.avail = km->iob.used = 0;
+ MouseFirstProtocol (km, mi->prot);
+ if (KdRegisterFd (MouseInputType, fd, MouseRead, (void *) mi))
+ n++;
+ }
+ else
+ close (fd);
+ }
+ else
+ KdMouseInfoDispose (mi);
+ }
+}
+
+void
+MouseFini (void)
+{
+ KdMouseInfo *mi;
+
+ KdUnregisterFds (MouseInputType, TRUE);
+ for (mi = kdMouseInfo; mi; mi = mi->next)
+ {
+ if (mi->driver)
+ {
+ xfree (mi->driver);
+ mi->driver = 0;
+ }
+ }
+}
+
+KdMouseFuncs LinuxMouseFuncs = {
+ MouseInit,
+ MouseFini,
+};
diff --git a/hw/kdrive/linux/ms.c b/hw/kdrive/linux/ms.c
index 4eba864cb..762e2118b 100644
--- a/hw/kdrive/linux/ms.c
+++ b/hw/kdrive/linux/ms.c
@@ -20,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
-/* $XFree86$ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/linux/ms.c,v 1.1 2001/08/09 20:45:15 dawes Exp $ */
#define NEED_EVENTS
#include "X.h"
@@ -63,7 +63,7 @@ MsReadBytes (int fd, char *buf, int len, int min)
}
void
-MsRead (int port)
+MsRead (int port, void *closure)
{
unsigned char buf[3 * 200];
unsigned char *b;
@@ -87,11 +87,13 @@ MsRead (int port)
dy = (char)(((b[0] & 0x0C) << 4) | (b[2] & 0x3F));
n -= 3;
b += 3;
- KdEnqueueMouseEvent (flags, dx, dy);
+ KdEnqueueMouseEvent (kdMouseInfo, flags, dx, dy);
}
}
}
+int MsInputType;
+
int
MsInit (void)
{
@@ -100,6 +102,8 @@ MsInit (void)
struct termios t;
int ret;
+ if (!MsInputType)
+ MsInputType = KdAllocInputType ();
port = open (device, O_RDWR | O_NONBLOCK);
if(port < 0) {
ErrorF("Couldn't open %s (%d)\n", device, (int)errno);
@@ -107,8 +111,7 @@ MsInit (void)
} else if (port == 0) {
ErrorF("Opening %s returned 0! Please complain to Keith.\n",
device);
- close(port);
- return 0;
+ goto bail;
}
if(!isatty(port)) {
@@ -137,7 +140,8 @@ MsInit (void)
ErrorF("Couldn't tcsetattr(%s): %d\n", device, errno);
goto bail;
}
- return port;
+ if (KdRegisterFd (MsInputType, port, MsRead, (void *) 0))
+ return 1;
bail:
close(port);
@@ -145,14 +149,12 @@ MsInit (void)
}
void
-MsFini (int port)
+MsFini (void)
{
- if (port >= 0)
- close(port);
+ KdUnregisterFds (MsInputType, TRUE);
}
KdMouseFuncs MsMouseFuncs = {
MsInit,
- MsRead,
MsFini
};
diff --git a/hw/kdrive/linux/ps2.c b/hw/kdrive/linux/ps2.c
index f1ccfd77c..a3fc712a3 100644
--- a/hw/kdrive/linux/ps2.c
+++ b/hw/kdrive/linux/ps2.c
@@ -1,5 +1,5 @@
/*
- * $XFree86: xc/programs/Xserver/hw/kdrive/linux/ps2.c,v 1.4 2001/04/01 14:00:04 tsi Exp $
+ * $XFree86: xc/programs/Xserver/hw/kdrive/linux/ps2.c,v 1.5 2001/06/29 14:00:41 keithp Exp $
*
* Copyright © 1999 Keith Packard
*
@@ -110,7 +110,7 @@ Ps2Read (int ps2Port, void *closure)
dy = -dy;
n -= 3;
b += 3;
- KdEnqueueMouseEvent (flags, dx, dy);
+ KdEnqueueMouseEvent (kdMouseInfo, flags, dx, dy);
}
}
}
diff --git a/hw/kdrive/mach64/mach64stub.c b/hw/kdrive/mach64/mach64stub.c
index fac8d46ac..6647610fc 100644
--- a/hw/kdrive/mach64/mach64stub.c
+++ b/hw/kdrive/mach64/mach64stub.c
@@ -22,7 +22,7 @@
*
* Author: Keith Packard, SuSE, Inc.
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/mach64/mach64stub.c,v 1.5 2000/11/29 08:42:25 keithp Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/mach64/mach64stub.c,v 1.1 2001/06/03 18:48:19 keithp Exp $ */
#include "mach64.h"
@@ -44,7 +44,7 @@ InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
void
InitInput (int argc, char **argv)
{
- KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs);
+ KdInitInput (&LinuxMouseFuncs, &LinuxKeyboardFuncs);
}
int
diff --git a/hw/kdrive/pcmcia/pcmciastub.c b/hw/kdrive/pcmcia/pcmciastub.c
index e30881633..af05b4a6a 100644
--- a/hw/kdrive/pcmcia/pcmciastub.c
+++ b/hw/kdrive/pcmcia/pcmciastub.c
@@ -21,7 +21,7 @@
*
* Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
*/
-/* $XFree86$ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/pcmcia/pcmciastub.c,v 1.1 2001/05/23 08:56:09 alanh Exp $ */
#include "pcmcia.h"
@@ -42,7 +42,7 @@ InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
void
InitInput (int argc, char **argv)
{
- KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs);
+ KdInitInput (&LinuxMouseFuncs, &LinuxKeyboardFuncs);
}
extern pcmciaDisplayModeRec pcmciaDefaultModes[];
diff --git a/hw/kdrive/savage/s3stub.c b/hw/kdrive/savage/s3stub.c
index 89d05b376..90ade29c2 100644
--- a/hw/kdrive/savage/s3stub.c
+++ b/hw/kdrive/savage/s3stub.c
@@ -22,7 +22,7 @@
*
* Author: Keith Packard, SuSE, Inc.
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3stub.c,v 1.2 1999/12/30 03:03:13 robin Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3stub.c,v 1.3 2000/02/23 20:30:05 dawes Exp $ */
#include "s3.h"
@@ -61,7 +61,7 @@ InitInput (int argc, char **argv)
KdInitInput (&VxWorksMouseFuncs, &VxWorksKeyboardFuncs);
#endif
#ifdef linux
- KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs);
+ KdInitInput (&LinuxMouseFuncs, &LinuxKeyboardFuncs);
#endif
}
diff --git a/hw/kdrive/sis530/sisstub.c b/hw/kdrive/sis530/sisstub.c
index a0d28821e..323e5dcce 100644
--- a/hw/kdrive/sis530/sisstub.c
+++ b/hw/kdrive/sis530/sisstub.c
@@ -22,7 +22,7 @@
*
* Author: Keith Packard, SuSE, Inc.
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/sis530/sisstub.c,v 1.2 1999/12/30 03:03:15 robin Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/sis530/sisstub.c,v 1.4 2000/08/09 17:52:44 keithp Exp $ */
#include "sis.h"
@@ -50,7 +50,7 @@ InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
void
InitInput (int argc, char **argv)
{
- KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs);
+ KdInitInput (&LinuxMouseFuncs, &LinuxKeyboardFuncs);
}
int
diff --git a/hw/kdrive/src/kdrive.c b/hw/kdrive/src/kdrive.c
index 3e1aa84ff..dabfd9c22 100644
--- a/hw/kdrive/src/kdrive.c
+++ b/hw/kdrive/src/kdrive.c
@@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/kdrive.c,v 1.19 2001/07/24 21:26:17 keithp Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/kdrive.c,v 1.20 2001/09/29 04:16:38 keithp Exp $ */
#include "kdrive.h"
#ifdef PSEUDO8
@@ -373,7 +373,7 @@ KdParseScreen (KdScreenInfo *screen,
screen->fb[fb].depth = 0;
if (!arg)
return;
- if (strlen (arg) > sizeof (save))
+ if (strlen (arg) >= sizeof (save))
return;
for (i = 0; i < 2; i++)
@@ -460,6 +460,114 @@ KdParseScreen (KdScreenInfo *screen,
}
}
+/*
+ * Mouse argument syntax:
+ *
+ * device,protocol,options...
+ *
+ * Options are any of:
+ * 1-5 n button mouse
+ * 2button emulate middle button
+ * {NMO} Reorder buttons
+ */
+
+char *
+KdSaveString (char *str)
+{
+ char *n = (char *) xalloc (strlen (str) + 1);
+
+ if (!n)
+ return 0;
+ strcpy (n, str);
+ return n;
+}
+
+/*
+ * Parse mouse information. Syntax:
+ *
+ * <device>,<nbutton>,<protocol>{,<option>}...
+ *
+ * options: {nmo} pointer mapping (e.g. {321})
+ * 2button emulate middle button
+ * 3button dont emulate middle button
+ */
+
+void
+KdParseMouse (char *arg)
+{
+ char save[1024];
+ char delim;
+ KdMouseInfo *mi;
+ int i;
+
+ mi = KdMouseInfoAdd ();
+ if (!mi)
+ return;
+ mi->name = 0;
+ mi->prot = 0;
+ mi->emulateMiddleButton = kdEmulateMiddleButton;
+ mi->nbutton = 3;
+ for (i = 0; i < KD_MAX_BUTTON; i++)
+ mi->map[i] = i + 1;
+
+ if (!arg)
+ return;
+ if (strlen (arg) >= sizeof (save))
+ return;
+ arg = KdParseFindNext (arg, ",", save, &delim);
+ if (!save[0])
+ return;
+ mi->name = KdSaveString (save);
+ if (delim != ',')
+ return;
+
+ arg = KdParseFindNext (arg, ",", save, &delim);
+ if (!save[0])
+ return;
+
+ if ('1' <= save[0] && save[0] <= '0' + KD_MAX_BUTTON && save[1] == '\0')
+ {
+ mi->nbutton = save[0] - '0';
+ if (mi->nbutton > KD_MAX_BUTTON)
+ {
+ UseMsg ();
+ return;
+ }
+ }
+
+ if (!delim != ',')
+ return;
+
+ arg = KdParseFindNext (arg, ",", save, &delim);
+
+ if (save[0])
+ mi->prot = KdSaveString (save);
+
+ while (delim == ',')
+ {
+ arg = KdParseFindNext (arg, ",", save, &delim);
+ if (save[0] == '{')
+ {
+ char *s = save + 1;
+ i = 0;
+ while (*s && *s != '}')
+ {
+ if ('1' <= *s && *s <= '0' + mi->nbutton)
+ mi->map[i] = *s - '0';
+ else
+ UseMsg ();
+ s++;
+ }
+ }
+ else if (!strcmp (save, "2button"))
+ mi->emulateMiddleButton = TRUE;
+ else if (!strcmp (save, "3button"))
+ mi->emulateMiddleButton = FALSE;
+ else
+ UseMsg ();
+ }
+}
+
int
KdProcessArgument (int argc, char **argv, int i)
{
@@ -542,6 +650,14 @@ KdProcessArgument (int argc, char **argv, int i)
UseMsg ();
return 2;
}
+ if (!strcmp (argv[i], "-mouse"))
+ {
+ if ((i+1) < argc)
+ KdParseMouse (argv[i+1]);
+ else
+ UseMsg ();
+ return 2;
+ }
#ifdef PSEUDO8
return p8ProcessArgument (argc, argv, i);
#else
diff --git a/hw/kdrive/src/kdrive.h b/hw/kdrive/src/kdrive.h
index 0c3203320..48f08b712 100644
--- a/hw/kdrive/src/kdrive.h
+++ b/hw/kdrive/src/kdrive.h
@@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/kdrive.h,v 1.19 2001/07/24 21:26:17 keithp Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/kdrive.h,v 1.20 2001/08/09 20:45:15 dawes Exp $ */
#include <stdio.h>
#include "X.h"
@@ -167,6 +167,44 @@ typedef struct {
#endif
} KdPrivScreenRec, *KdPrivScreenPtr;
+typedef enum _kdMouseState {
+ start,
+ button_1_pend,
+ button_1_down,
+ button_2_down,
+ button_3_pend,
+ button_3_down,
+ synth_2_down_13,
+ synth_2_down_3,
+ synth_2_down_1,
+ num_input_states
+} KdMouseState;
+
+#define KD_MAX_BUTTON 7
+
+typedef struct _KdMouseInfo {
+ struct _KdMouseInfo *next;
+ void *driver;
+ void *closure;
+ char *name;
+ char *prot;
+ char map[KD_MAX_BUTTON];
+ int nbutton;
+ Bool emulateMiddleButton;
+ unsigned long emulationTimeout;
+ Bool timeoutPending;
+ KdMouseState mouseState;
+ Bool eventHeld;
+ xEvent heldEvent;
+ unsigned char buttonState;
+ int emulationDx, emulationDy;
+} KdMouseInfo;
+
+extern KdMouseInfo *kdMouseInfo;
+
+KdMouseInfo *KdMouseInfoAdd (void);
+void KdParseMouse (char *);
+
typedef struct _KdMouseFuncs {
int (*Init) (void);
void (*Fini) (void);
@@ -478,6 +516,12 @@ void
KdParseScreen (KdScreenInfo *screen,
char *arg);
+char *
+KdSaveString (char *str);
+
+void
+KdParseMouse (char *arg);
+
void
KdOsInit (KdOsFuncs *pOsFuncs);
@@ -560,13 +604,15 @@ KdEnqueueKeyboardEvent(unsigned char scan_code,
#define KD_BUTTON_1 0x01
#define KD_BUTTON_2 0x02
#define KD_BUTTON_3 0x04
+#define KD_BUTTON_4 0x08
+#define KD_BUTTON_5 0x10
#define KD_MOUSE_DELTA 0x80000000
void
-KdEnqueueMouseEvent(unsigned long flags, int x, int y);
+KdEnqueueMouseEvent(KdMouseInfo *mi, unsigned long flags, int x, int y);
void
-KdEnqueueMotionEvent (int x, int y);
+KdEnqueueMotionEvent (KdMouseInfo *mi, int x, int y);
void
KdReleaseAllKeys (void);
@@ -598,6 +644,7 @@ KdEnableInput (void);
void
ProcessInputEvents ();
+extern KdMouseFuncs LinuxMouseFuncs;
extern KdMouseFuncs Ps2MouseFuncs;
extern KdMouseFuncs BusMouseFuncs;
extern KdMouseFuncs MsMouseFuncs;
diff --git a/hw/kdrive/src/kinfo.c b/hw/kdrive/src/kinfo.c
index 911097834..7e245ebbb 100644
--- a/hw/kdrive/src/kinfo.c
+++ b/hw/kdrive/src/kinfo.c
@@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/kinfo.c,v 1.1 1999/11/19 13:53:49 hohndel Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/kinfo.c,v 1.2 2000/02/23 20:29:53 dawes Exp $ */
#include "kdrive.h"
@@ -108,3 +108,37 @@ KdScreenInfoDispose (KdScreenInfo *si)
break;
}
}
+
+KdMouseInfo *kdMouseInfo;
+
+KdMouseInfo *
+KdMouseInfoAdd (void)
+{
+ KdMouseInfo *mi, **prev;
+
+ mi = (KdMouseInfo *) xalloc (sizeof (KdMouseInfo));
+ if (!mi)
+ return 0;
+ bzero (mi, sizeof (KdMouseInfo));
+ for (prev = &kdMouseInfo; *prev; prev = &(*prev)->next);
+ *prev = mi;
+ return mi;
+}
+
+void
+KdMouseInfoDispose (KdMouseInfo *mi)
+{
+ KdMouseInfo **prev;
+
+ for (prev = &kdMouseInfo; *prev; prev = &(*prev)->next)
+ if (*prev == mi)
+ {
+ *prev = mi->next;
+ if (mi->name)
+ xfree (mi->name);
+ if (mi->prot)
+ xfree (mi->prot);
+ xfree (mi);
+ break;
+ }
+}
diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index d683e39fc..f778298b9 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/kinput.c,v 1.20 2001/08/09 09:06:08 keithp Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/kinput.c,v 1.21 2001/09/29 04:16:38 keithp Exp $ */
#include "kdrive.h"
#include "inputstr.h"
@@ -54,6 +54,7 @@ static KdMouseMatrix kdMouseMatrix = {
static KdMouseFuncs *kdTsFuncs;
#endif
+int kdMouseButtonCount;
int kdMinScanCode;
int kdMaxScanCode;
int kdMinKeyCode;
@@ -67,8 +68,6 @@ KeySymsRec kdKeySyms;
void
KdResetInputMachine (void);
-#define KD_MOUSEBUTTON_COUNT 3
-
#define KD_KEY_COUNT 248
CARD8 kdKeyState[KD_KEY_COUNT/8];
@@ -288,9 +287,10 @@ KdEnableInput (void)
static int
KdMouseProc(DeviceIntPtr pDevice, int onoff)
{
- BYTE map[4];
+ BYTE map[KD_MAX_BUTTON];
DevicePtr pDev = (DevicePtr)pDevice;
int i;
+ KdMouseInfo *mi;
if (!pDev)
return BadImplementation;
@@ -298,9 +298,9 @@ KdMouseProc(DeviceIntPtr pDevice, int onoff)
switch (onoff)
{
case DEVICE_INIT:
- for (i = 1; i <= KD_MOUSEBUTTON_COUNT; i++)
+ for (i = 1; i <= kdMouseButtonCount; i++)
map[i] = i;
- InitPointerDeviceStruct(pDev, map, KD_MOUSEBUTTON_COUNT,
+ InitPointerDeviceStruct(pDev, map, kdMouseButtonCount,
miPointerGetMotionEvents,
(PtrCtrlProcPtr)NoopDDA,
miPointerGetMotionBufferSize());
@@ -503,7 +503,17 @@ KdInitInput(KdMouseFuncs *pMouseFuncs,
KdKeyboardFuncs *pKeyboardFuncs)
{
DeviceIntPtr pKeyboard, pPointer;
+ KdMouseInfo *mi;
+ if (!kdMouseInfo)
+ KdParseMouse (0);
+ kdMouseButtonCount = 0;
+ for (mi = kdMouseInfo; mi; mi = mi->next)
+ {
+ if (mi->nbutton > kdMouseButtonCount)
+ kdMouseButtonCount = mi->nbutton;
+ }
+
kdMouseFuncs = pMouseFuncs;
kdKeyboardFuncs = pKeyboardFuncs;
memset (kdKeyState, '\0', sizeof (kdKeyState));
@@ -555,6 +565,8 @@ KdInitTouchScreen(KdMouseFuncs *pTsFuncs)
* Button 2 release ^2
* Button 3 press v3
* Button 3 release ^3
+ * Button other press vo
+ * Button other release ^o
* Mouse motion <>
* Keyboard event k
* timeout ...
@@ -580,6 +592,8 @@ KdInitTouchScreen(KdMouseFuncs *pTsFuncs)
* ^2 -> (deliever) start
* v3 -> (hold) (settimeout) button_3_pend
* ^3 -> (deliver) start
+ * vo -> (deliver) start
+ * ^o -> (deliver) start
* <> -> (deliver) start
* k -> (deliver) start
*
@@ -589,6 +603,8 @@ KdInitTouchScreen(KdMouseFuncs *pTsFuncs)
* ^2 -> (release) (deliver) button_1_down
* v3 -> (cleartimeout) (generate v2) synthetic_2_down_13
* ^3 -> (release) (deliver) button_1_down
+ * vo -> (release) (deliver) button_1_down
+ * ^o -> (release) (deliver) button_1_down
* <-> -> (release) (deliver) button_1_down
* <> -> (deliver) button_1_pend
* k -> (release) (deliver) button_1_down
@@ -600,6 +616,8 @@ KdInitTouchScreen(KdMouseFuncs *pTsFuncs)
* ^2 -> (deliver) button_1_down
* v3 -> (deliver) button_1_down
* ^3 -> (deliver) button_1_down
+ * vo -> (deliver) button_1_down
+ * ^o -> (deliver) button_1_down
* <> -> (deliver) button_1_down
* k -> (deliver) button_1_down
*
@@ -609,6 +627,8 @@ KdInitTouchScreen(KdMouseFuncs *pTsFuncs)
* ^2 -> (deliver) start
* v3 -> (deliver) button_2_down
* ^3 -> (deliver) button_2_down
+ * vo -> (deliver) button_2_down
+ * ^o -> (deliver) button_2_down
* <> -> (deliver) button_2_down
* k -> (deliver) button_2_down
*
@@ -618,6 +638,8 @@ KdInitTouchScreen(KdMouseFuncs *pTsFuncs)
* v2 -> (release) (deliver) button_3_down
* ^2 -> (release) (deliver) button_3_down
* ^3 -> (release) (deliver) start
+ * vo -> (release) (deliver) button_3_down
+ * ^o -> (release) (deliver) button_3_down
* <-> -> (release) (deliver) button_3_down
* <> -> (deliver) button_3_pend
* k -> (release) (deliver) button_3_down
@@ -629,6 +651,8 @@ KdInitTouchScreen(KdMouseFuncs *pTsFuncs)
* v2 -> (deliver) button_3_down
* ^2 -> (deliver) button_3_down
* ^3 -> (deliver) start
+ * vo -> (deliver) button_3_down
+ * ^o -> (deliver) button_3_down
* <> -> (deliver) button_3_down
* k -> (deliver) button_3_down
*
@@ -637,6 +661,8 @@ KdInitTouchScreen(KdMouseFuncs *pTsFuncs)
* v2 -> synthetic_2_down_13
* ^2 -> synthetic_2_down_13
* ^3 -> (generate ^2) synthetic_2_down_1
+ * vo -> (deliver) synthetic_2_down_13
+ * ^o -> (deliver) synthetic_2_down_13
* <> -> (deliver) synthetic_2_down_13
* k -> (deliver) synthetic_2_down_13
*
@@ -646,6 +672,8 @@ KdInitTouchScreen(KdMouseFuncs *pTsFuncs)
* v2 -> synthetic_2_down_3
* ^2 -> synthetic_2_down_3
* ^3 -> start
+ * vo -> (deliver) synthetic_2_down_3
+ * ^o -> (deliver) synthetic_2_down_3
* <> -> (deliver) synthetic_2_down_3
* k -> (deliver) synthetic_2_down_3
*
@@ -655,27 +683,17 @@ KdInitTouchScreen(KdMouseFuncs *pTsFuncs)
* ^2 -> synthetic_2_down_1
* v3 -> (deliver) synthetic_2_down_1
* ^3 -> (deliver) synthetic_2_down_1
+ * vo -> (deliver) synthetic_2_down_1
+ * ^o -> (deliver) synthetic_2_down_1
* <> -> (deliver) synthetic_2_down_1
* k -> (deliver) synthetic_2_down_1
*/
-typedef enum _inputState {
- start,
- button_1_pend,
- button_1_down,
- button_2_down,
- button_3_pend,
- button_3_down,
- synth_2_down_13,
- synth_2_down_3,
- synth_2_down_1,
- num_input_states
-} KdInputState;
-
typedef enum _inputClass {
down_1, up_1,
down_2, up_2,
down_3, up_3,
+ down_o, up_o,
motion, outside_box,
keyboard, timeout,
num_input_class
@@ -696,7 +714,7 @@ typedef enum _inputAction {
typedef struct _inputTransition {
KdInputAction actions[MAX_ACTIONS];
- KdInputState nextState;
+ KdMouseState nextState;
} KdInputTransition;
KdInputTransition kdInputMachine[num_input_states][num_input_class] = {
@@ -708,9 +726,11 @@ KdInputTransition kdInputMachine[num_input_states][num_input_class] = {
{ { deliver, noop }, start }, /* ^2 */
{ { hold, setto }, button_3_pend }, /* v3 */
{ { deliver, noop }, start }, /* ^3 */
+ { { deliver, noop }, start }, /* vo */
+ { { deliver, noop }, start }, /* ^o */
{ { deliver, noop }, start }, /* <> */
{ { deliver, noop }, start }, /* <-> */
- { { deliver, noop }, start }, /* k */
+ { { noop, noop }, start }, /* k */
{ { noop, noop }, start }, /* ... */
},
/* button_1_pend */
@@ -721,9 +741,11 @@ KdInputTransition kdInputMachine[num_input_states][num_input_class] = {
{ { release, deliver }, button_1_down }, /* ^2 */
{ { clearto, gen_down_2 }, synth_2_down_13 }, /* v3 */
{ { release, deliver }, button_1_down }, /* ^3 */
+ { { release, deliver }, button_1_down }, /* vo */
+ { { release, deliver }, button_1_down }, /* ^o */
{ { deliver, noop }, button_1_pend }, /* <> */
{ { release, deliver }, button_1_down }, /* <-> */
- { { release, deliver }, button_1_down }, /* k */
+ { { noop, noop }, button_1_down }, /* k */
{ { release, noop }, button_1_down }, /* ... */
},
/* button_1_down */
@@ -734,9 +756,11 @@ KdInputTransition kdInputMachine[num_input_states][num_input_class] = {
{ { deliver, noop }, button_1_down }, /* ^2 */
{ { deliver, noop }, button_1_down }, /* v3 */
{ { deliver, noop }, button_1_down }, /* ^3 */
+ { { deliver, noop }, button_1_down }, /* vo */
+ { { deliver, noop }, button_1_down }, /* ^o */
{ { deliver, noop }, button_1_down }, /* <> */
{ { deliver, noop }, button_1_down }, /* <-> */
- { { deliver, noop }, button_1_down }, /* k */
+ { { noop, noop }, button_1_down }, /* k */
{ { noop, noop }, button_1_down }, /* ... */
},
/* button_2_down */
@@ -747,9 +771,11 @@ KdInputTransition kdInputMachine[num_input_states][num_input_class] = {
{ { deliver, noop }, start }, /* ^2 */
{ { deliver, noop }, button_2_down }, /* v3 */
{ { deliver, noop }, button_2_down }, /* ^3 */
+ { { deliver, noop }, button_2_down }, /* vo */
+ { { deliver, noop }, button_2_down }, /* ^o */
{ { deliver, noop }, button_2_down }, /* <> */
{ { deliver, noop }, button_2_down }, /* <-> */
- { { deliver, noop }, button_2_down }, /* k */
+ { { noop, noop }, button_2_down }, /* k */
{ { noop, noop }, button_2_down }, /* ... */
},
/* button_3_pend */
@@ -760,9 +786,11 @@ KdInputTransition kdInputMachine[num_input_states][num_input_class] = {
{ { release, deliver }, button_3_down }, /* ^2 */
{ { release, deliver }, button_3_down }, /* v3 */
{ { release, deliver }, start }, /* ^3 */
+ { { release, deliver }, button_3_down }, /* vo */
+ { { release, deliver }, button_3_down }, /* ^o */
{ { deliver, noop }, button_3_pend }, /* <> */
{ { release, deliver }, button_3_down }, /* <-> */
- { { release, deliver }, button_3_down }, /* k */
+ { { release, noop }, button_3_down }, /* k */
{ { release, noop }, button_3_down }, /* ... */
},
/* button_3_down */
@@ -773,9 +801,11 @@ KdInputTransition kdInputMachine[num_input_states][num_input_class] = {
{ { deliver, noop }, button_3_down }, /* ^2 */
{ { noop, noop }, button_3_down }, /* v3 */
{ { deliver, noop }, start }, /* ^3 */
+ { { deliver, noop }, button_3_down }, /* vo */
+ { { deliver, noop }, button_3_down }, /* ^o */
{ { deliver, noop }, button_3_down }, /* <> */
{ { deliver, noop }, button_3_down }, /* <-> */
- { { deliver, noop }, button_3_down }, /* k */
+ { { noop, noop }, button_3_down }, /* k */
{ { noop, noop }, button_3_down }, /* ... */
},
/* synthetic_2_down_13 */
@@ -786,9 +816,11 @@ KdInputTransition kdInputMachine[num_input_states][num_input_class] = {
{ { noop, noop }, synth_2_down_13 }, /* ^2 */
{ { noop, noop }, synth_2_down_13 }, /* v3 */
{ { gen_up_2, noop }, synth_2_down_1 }, /* ^3 */
+ { { deliver, noop }, synth_2_down_13 }, /* vo */
+ { { deliver, noop }, synth_2_down_13 }, /* ^o */
{ { deliver, noop }, synth_2_down_13 }, /* <> */
{ { deliver, noop }, synth_2_down_13 }, /* <-> */
- { { deliver, noop }, synth_2_down_13 }, /* k */
+ { { noop, noop }, synth_2_down_13 }, /* k */
{ { noop, noop }, synth_2_down_13 }, /* ... */
},
/* synthetic_2_down_3 */
@@ -799,9 +831,11 @@ KdInputTransition kdInputMachine[num_input_states][num_input_class] = {
{ { deliver, noop }, synth_2_down_3 }, /* ^2 */
{ { noop, noop }, synth_2_down_3 }, /* v3 */
{ { noop, noop }, start }, /* ^3 */
+ { { deliver, noop }, synth_2_down_3 }, /* vo */
+ { { deliver, noop }, synth_2_down_3 }, /* ^o */
{ { deliver, noop }, synth_2_down_3 }, /* <> */
{ { deliver, noop }, synth_2_down_3 }, /* <-> */
- { { deliver, noop }, synth_2_down_3 }, /* k */
+ { { noop, noop }, synth_2_down_3 }, /* k */
{ { noop, noop }, synth_2_down_3 }, /* ... */
},
/* synthetic_2_down_1 */
@@ -812,17 +846,15 @@ KdInputTransition kdInputMachine[num_input_states][num_input_class] = {
{ { deliver, noop }, synth_2_down_1 }, /* ^2 */
{ { deliver, noop }, synth_2_down_1 }, /* v3 */
{ { deliver, noop }, synth_2_down_1 }, /* ^3 */
+ { { deliver, noop }, synth_2_down_1 }, /* vo */
+ { { deliver, noop }, synth_2_down_1 }, /* ^o */
{ { deliver, noop }, synth_2_down_1 }, /* <> */
{ { deliver, noop }, synth_2_down_1 }, /* <-> */
- { { deliver, noop }, synth_2_down_1 }, /* k */
+ { { noop, noop }, synth_2_down_1 }, /* k */
{ { noop, noop }, synth_2_down_1 }, /* ... */
},
};
-Bool kdEventHeld;
-xEvent kdHeldEvent;
-int kdEmulationDx, kdEmulationDy;
-
#define EMULATION_WINDOW 10
#define EMULATION_TIMEOUT 100
@@ -830,24 +862,24 @@ int kdEmulationDx, kdEmulationDy;
#define EventY(e) ((e)->u.keyButtonPointer.rootY)
int
-KdInsideEmulationWindow (xEvent *ev)
+KdInsideEmulationWindow (KdMouseInfo *mi, xEvent *ev)
{
if (ev->u.keyButtonPointer.pad1)
{
- kdEmulationDx += EventX(ev);
- kdEmulationDy += EventY(ev);
+ mi->emulationDx += EventX(ev);
+ mi->emulationDy += EventY(ev);
}
else
{
- kdEmulationDx = EventX(&kdHeldEvent) - EventX(ev);
- kdEmulationDy = EventY(&kdHeldEvent) - EventY(ev);
+ mi->emulationDx = EventX(&mi->heldEvent) - EventX(ev);
+ mi->emulationDy = EventY(&mi->heldEvent) - EventY(ev);
}
- return (abs (kdEmulationDx) < EMULATION_WINDOW &&
- abs (kdEmulationDy) < EMULATION_WINDOW);
+ return (abs (mi->emulationDx) < EMULATION_WINDOW &&
+ abs (mi->emulationDy) < EMULATION_WINDOW);
}
KdInputClass
-KdClassifyInput (xEvent *ev)
+KdClassifyInput (KdMouseInfo *mi, xEvent *ev)
{
switch (ev->u.u.type) {
case ButtonPress:
@@ -855,6 +887,7 @@ KdClassifyInput (xEvent *ev)
case 1: return down_1;
case 2: return down_2;
case 3: return down_3;
+ default: return down_o;
}
break;
case ButtonRelease:
@@ -862,10 +895,11 @@ KdClassifyInput (xEvent *ev)
case 1: return up_1;
case 2: return up_2;
case 3: return up_3;
+ default: return up_o;
}
break;
case MotionNotify:
- if (kdEventHeld && !KdInsideEmulationWindow(ev))
+ if (mi->eventHeld && !KdInsideEmulationWindow(mi, ev))
return outside_box;
else
return motion;
@@ -936,44 +970,42 @@ KdQueueEvent (xEvent *ev)
}
}
-KdInputState kdInputState;
-
static void
-KdRunInputMachine (KdInputClass c, xEvent *ev)
+KdRunMouseMachine (KdMouseInfo *mi, KdInputClass c, xEvent *ev)
{
KdInputTransition *t;
int a;
- t = &kdInputMachine[kdInputState][c];
+ t = &kdInputMachine[mi->mouseState][c];
for (a = 0; a < MAX_ACTIONS; a++)
{
switch (t->actions[a]) {
case noop:
break;
case hold:
- kdEventHeld = TRUE;
- kdEmulationDx = 0;
- kdEmulationDy = 0;
- kdHeldEvent = *ev;
+ mi->eventHeld = TRUE;
+ mi->emulationDx = 0;
+ mi->emulationDy = 0;
+ mi->heldEvent = *ev;
break;
case setto:
- kdEmulationTimeout = GetTimeInMillis () + EMULATION_TIMEOUT;
- kdTimeoutPending = TRUE;
+ mi->emulationTimeout = GetTimeInMillis () + EMULATION_TIMEOUT;
+ mi->timeoutPending = TRUE;
break;
case deliver:
KdQueueEvent (ev);
break;
case release:
- kdEventHeld = FALSE;
- kdTimeoutPending = FALSE;
- KdQueueEvent (&kdHeldEvent);
+ mi->eventHeld = FALSE;
+ mi->timeoutPending = FALSE;
+ KdQueueEvent (&mi->heldEvent);
break;
case clearto:
- kdTimeoutPending = FALSE;
+ mi->timeoutPending = FALSE;
break;
case gen_down_2:
ev->u.u.detail = 2;
- kdEventHeld = FALSE;
+ mi->eventHeld = FALSE;
KdQueueEvent (ev);
break;
case gen_up_2:
@@ -982,29 +1014,34 @@ KdRunInputMachine (KdInputClass c, xEvent *ev)
break;
}
}
- kdInputState = t->nextState;
+ mi->mouseState = t->nextState;
}
void
KdResetInputMachine (void)
{
- kdInputState = start;
- kdEventHeld = FALSE;
+ KdMouseInfo *mi;
+
+ for (mi = kdMouseInfo; mi; mi = mi->next)
+ {
+ mi->mouseState = start;
+ mi->eventHeld = FALSE;
+ }
}
void
-KdHandleEvent (xEvent *ev)
+KdHandleMouseEvent (KdMouseInfo *mi, xEvent *ev)
{
- if (kdEmulateMiddleButton)
- KdRunInputMachine (KdClassifyInput (ev), ev);
+ if (mi->emulateMiddleButton)
+ KdRunMouseMachine (mi, KdClassifyInput (mi, ev), ev);
else
KdQueueEvent (ev);
}
void
-KdReceiveTimeout (void)
+KdReceiveTimeout (KdMouseInfo *mi)
{
- KdRunInputMachine (timeout, 0);
+ KdRunMouseMachine (mi, timeout, 0);
}
#define KILL_SEQUENCE ((1L << KK_CONTROL)|(1L << KK_ALT)|(1L << KK_F8)|(1L << KK_F10))
@@ -1107,9 +1144,10 @@ KdCheckSpecialKeys(xEvent *xE)
void
KdHandleKeyboardEvent (xEvent *ev)
{
- int key = ev->u.u.detail;
- int byte;
- CARD8 bit;
+ int key = ev->u.u.detail;
+ int byte;
+ CARD8 bit;
+ KdMouseInfo *mi;
byte = key >> 3;
bit = 1 << (key & 7);
@@ -1121,7 +1159,9 @@ KdHandleKeyboardEvent (xEvent *ev)
kdKeyState[byte] &= ~bit;
break;
}
- KdHandleEvent (ev);
+ for (mi = kdMouseInfo; mi; mi = mi->next)
+ KdRunMouseMachine (mi, keyboard, 0);
+ KdQueueEvent (ev);
}
void
@@ -1235,17 +1275,15 @@ KdEnqueueKeyboardEvent(unsigned char scan_code,
}
}
-#define SetButton(b,v, s) \
+#define SetButton(mi, b, v, s) \
{\
- xE.u.u.detail = b; \
+ xE.u.u.detail = mi->map[b]; \
xE.u.u.type = v; \
- KdHandleEvent (&xE); \
+ KdHandleMouseEvent (mi, &xE); \
}
-#define Press(b) SetButton(b+1,ButtonPress,"Down")
-#define Release(b) SetButton(b+1,ButtonRelease,"Up")
-
-static unsigned char kdButtonState = 0;
+#define Press(mi, b) SetButton(mi, b, ButtonPress, "Down")
+#define Release(mi, b) SetButton(mi, b, ButtonRelease, "Up")
/*
* kdEnqueueMouseEvent
@@ -1267,13 +1305,15 @@ KdMouseAccelerate (DeviceIntPtr device, int delta)
}
void
-KdEnqueueMouseEvent(unsigned long flags, int rx, int ry)
+KdEnqueueMouseEvent(KdMouseInfo *mi, unsigned long flags, int rx, int ry)
{
- CARD32 ms;
- xEvent xE;
- unsigned char buttons;
- int x, y;
- int (*matrix)[3] = kdMouseMatrix.matrix;
+ CARD32 ms;
+ xEvent xE;
+ unsigned char buttons;
+ int x, y;
+ int (*matrix)[3] = kdMouseMatrix.matrix;
+ unsigned long button;
+ int n;
if (!pKdPointer)
return;
@@ -1300,48 +1340,29 @@ KdEnqueueMouseEvent(unsigned long flags, int rx, int ry)
xE.u.u.type = MotionNotify;
xE.u.u.detail = 0;
- KdHandleEvent (&xE);
+ KdHandleMouseEvent (mi, &xE);
buttons = flags;
- if ((kdButtonState & KD_BUTTON_1) ^ (buttons & KD_BUTTON_1))
- {
- if (buttons & KD_BUTTON_1)
- {
- Press(0);
- }
- else
- {
- Release(0);
- }
- }
- if ((kdButtonState & KD_BUTTON_2) ^ (buttons & KD_BUTTON_2))
- {
- if (buttons & KD_BUTTON_2)
- {
- Press(1);
- }
- else
- {
- Release(1);
- }
- }
- if ((kdButtonState & KD_BUTTON_3) ^ (buttons & KD_BUTTON_3))
+ for (button = KD_BUTTON_1, n = 0; button <= KD_BUTTON_5; button <<= 1, n++)
{
- if (buttons & KD_BUTTON_3)
- {
- Press(2);
- }
- else
+ if ((mi->buttonState & button) ^ (buttons & button))
{
- Release(2);
+ if (buttons & button)
+ {
+ Press(mi, n);
+ }
+ else
+ {
+ Release(mi, n);
+ }
}
}
- kdButtonState = buttons;
+ mi->buttonState = buttons;
}
void
-KdEnqueueMotionEvent (int x, int y)
+KdEnqueueMotionEvent (KdMouseInfo *mi, int x, int y)
{
xEvent xE;
CARD32 ms;
@@ -1353,7 +1374,7 @@ KdEnqueueMotionEvent (int x, int y)
xE.u.keyButtonPointer.rootX = x;
xE.u.keyButtonPointer.rootY = y;
- KdHandleEvent (&xE);
+ KdHandleMouseEvent (mi, &xE);
}
void
@@ -1362,29 +1383,19 @@ KdBlockHandler (int screen,
pointer timeout,
pointer readmask)
{
- struct timeval **pTimeout = timeout;
+ KdMouseInfo *mi;
- if (kdTimeoutPending)
+ for (mi = kdMouseInfo; mi; mi = mi->next)
{
- static struct timeval tv;
- int ms;
-
- ms = kdEmulationTimeout - GetTimeInMillis ();
- if (ms < 0)
- ms = 0;
- tv.tv_sec = ms / 1000;
- tv.tv_usec = (ms % 1000) * 1000;
- if (*pTimeout)
+ if (mi->timeoutPending)
{
- if ((*pTimeout)->tv_sec > tv.tv_sec ||
- ((*pTimeout)->tv_sec == tv.tv_sec &&
- (*pTimeout)->tv_usec > tv.tv_usec))
- {
- *pTimeout = &tv;
- }
+ int ms;
+
+ ms = mi->emulationTimeout - GetTimeInMillis ();
+ if (ms < 0)
+ ms = 0;
+ AdjustWaitForDelay (timeout, ms);
}
- else
- *pTimeout = &tv;
}
}
@@ -1394,9 +1405,10 @@ KdWakeupHandler (int screen,
unsigned long lresult,
pointer readmask)
{
- int result = (int) lresult;
- fd_set *pReadmask = (fd_set *) readmask;
- int i;
+ int result = (int) lresult;
+ fd_set *pReadmask = (fd_set *) readmask;
+ int i;
+ KdMouseInfo *mi;
if (kdInputEnabled && result > 0)
{
@@ -1408,14 +1420,17 @@ KdWakeupHandler (int screen,
KdUnblockSigio ();
}
}
- if (kdTimeoutPending)
+ for (mi = kdMouseInfo; mi; mi = mi->next)
{
- if ((long) (GetTimeInMillis () - kdEmulationTimeout) >= 0)
+ if (mi->timeoutPending)
{
- kdTimeoutPending = FALSE;
- KdBlockSigio ();
- KdReceiveTimeout ();
- KdUnblockSigio ();
+ if ((long) (GetTimeInMillis () - mi->emulationTimeout) >= 0)
+ {
+ mi->timeoutPending = FALSE;
+ KdBlockSigio ();
+ KdReceiveTimeout (mi);
+ KdUnblockSigio ();
+ }
}
}
if (kdSwitchPending)
diff --git a/hw/kdrive/trident/tridentstub.c b/hw/kdrive/trident/tridentstub.c
index 0b31bdfc6..b725670cb 100644
--- a/hw/kdrive/trident/tridentstub.c
+++ b/hw/kdrive/trident/tridentstub.c
@@ -22,7 +22,7 @@
*
* Author: Keith Packard, SuSE, Inc.
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/trident/tridentstub.c,v 1.4 2000/08/29 17:20:15 keithp Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/trident/tridentstub.c,v 1.5 2000/11/29 08:42:25 keithp Exp $ */
#include "trident.h"
@@ -46,7 +46,7 @@ InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
void
InitInput (int argc, char **argv)
{
- KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs);
+ KdInitInput (&LinuxMouseFuncs, &LinuxKeyboardFuncs);
}
int
diff --git a/hw/kdrive/trio/s3stub.c b/hw/kdrive/trio/s3stub.c
index f7605d50d..a4b4241e8 100644
--- a/hw/kdrive/trio/s3stub.c
+++ b/hw/kdrive/trio/s3stub.c
@@ -22,7 +22,7 @@
*
* Author: Keith Packard, SuSE, Inc.
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/trio/s3stub.c,v 1.2 1999/12/30 03:03:20 robin Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/trio/s3stub.c,v 1.3 2000/02/23 20:30:13 dawes Exp $ */
#include "s3.h"
@@ -49,7 +49,7 @@ InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
void
InitInput (int argc, char **argv)
{
- KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs);
+ KdInitInput (&LinuxMouseFuncs, &LinuxKeyboardFuncs);
}
int
diff --git a/hw/kdrive/ts300/ts300.c b/hw/kdrive/ts300/ts300.c
index f021109fc..394a14979 100644
--- a/hw/kdrive/ts300/ts300.c
+++ b/hw/kdrive/ts300/ts300.c
@@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/ts300/ts300.c,v 1.2 1999/12/30 03:03:20 robin Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/ts300/ts300.c,v 1.3 2000/02/23 20:30:14 dawes Exp $ */
#include "kdrive.h"
@@ -120,7 +120,7 @@ InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
void
InitInput (int argc, char **argv)
{
- KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs);
+ KdInitInput (&LinuxMouseFuncs, &LinuxKeyboardFuncs);
}
int
diff --git a/hw/kdrive/vesa/vesainit.c b/hw/kdrive/vesa/vesainit.c
index a409fc4fb..e61f9d11f 100644
--- a/hw/kdrive/vesa/vesainit.c
+++ b/hw/kdrive/vesa/vesainit.c
@@ -19,7 +19,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/vesa/vesainit.c,v 1.6 2001/06/04 09:45:42 keithp Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/vesa/vesainit.c,v 1.7 2001/09/05 07:12:43 keithp Exp $ */
#include "vesa.h"
@@ -69,7 +69,7 @@ InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
void
InitInput (int argc, char **argv)
{
- KdInitInput(&Ps2MouseFuncs, &LinuxKeyboardFuncs);
+ KdInitInput(&LinuxMouseFuncs, &LinuxKeyboardFuncs);
}
int