diff options
author | Keith Packard <keithp@keithp.com> | 2001-10-12 06:33:12 +0000 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2001-10-12 06:33:12 +0000 |
commit | 28fd5f7525848cf0109f9cf2d6311f3717570a5d (patch) | |
tree | 70adc7664477ac1c13ed92dcf62bee23a3b22e21 | |
parent | 5f310d7f8b566b1e331286752d349f87ef43a811 (diff) |
kdrive: add new auto-detecting and auto-switching mouse driver
-rw-r--r-- | hw/kdrive/chips/chipsstub.c | 4 | ||||
-rw-r--r-- | hw/kdrive/fbdev/fbinit.c | 8 | ||||
-rw-r--r-- | hw/kdrive/i810/i810stub.c | 2 | ||||
-rw-r--r-- | hw/kdrive/igs/igsstub.c | 4 | ||||
-rw-r--r-- | hw/kdrive/ipaq/ipaq.c | 8 | ||||
-rw-r--r-- | hw/kdrive/linux/Imakefile | 6 | ||||
-rw-r--r-- | hw/kdrive/linux/bus.c | 4 | ||||
-rw-r--r-- | hw/kdrive/linux/keyboard.c | 4 | ||||
-rw-r--r-- | hw/kdrive/linux/mouse.c | 917 | ||||
-rw-r--r-- | hw/kdrive/linux/ms.c | 22 | ||||
-rw-r--r-- | hw/kdrive/linux/ps2.c | 4 | ||||
-rw-r--r-- | hw/kdrive/mach64/mach64stub.c | 4 | ||||
-rw-r--r-- | hw/kdrive/pcmcia/pcmciastub.c | 4 | ||||
-rw-r--r-- | hw/kdrive/savage/s3stub.c | 4 | ||||
-rw-r--r-- | hw/kdrive/sis530/sisstub.c | 4 | ||||
-rw-r--r-- | hw/kdrive/src/kdrive.c | 120 | ||||
-rw-r--r-- | hw/kdrive/src/kdrive.h | 53 | ||||
-rw-r--r-- | hw/kdrive/src/kinfo.c | 36 | ||||
-rw-r--r-- | hw/kdrive/src/kinput.c | 301 | ||||
-rw-r--r-- | hw/kdrive/trident/tridentstub.c | 4 | ||||
-rw-r--r-- | hw/kdrive/trio/s3stub.c | 4 | ||||
-rw-r--r-- | hw/kdrive/ts300/ts300.c | 4 | ||||
-rw-r--r-- | hw/kdrive/vesa/vesainit.c | 4 |
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 |