kdrive: add new auto-detecting and auto-switching mouse driver

This commit is contained in:
Keith Packard 2001-10-12 06:33:12 +00:00
parent 5f310d7f8b
commit 28fd5f7525
23 changed files with 1324 additions and 201 deletions

View File

@ -22,7 +22,7 @@
* *
* Author: Keith Packard, SuSE, Inc. * 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" #include "chips.h"
@ -45,7 +45,7 @@ InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
void void
InitInput (int argc, char **argv) InitInput (int argc, char **argv)
{ {
KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs); KdInitInput (&LinuxMouseFuncs, &LinuxKeyboardFuncs);
} }
int int

View File

@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE. * 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> #include <fbdev.h>
@ -42,11 +42,7 @@ InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
void void
InitInput (int argc, char **argv) InitInput (int argc, char **argv)
{ {
#ifdef __powerpc__ KdInitInput (&LinuxMouseFuncs, &LinuxKeyboardFuncs);
KdInitInput (&BusMouseFuncs, &LinuxKeyboardFuncs);
#else
KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs);
#endif
#ifdef TOUCHSCREEN #ifdef TOUCHSCREEN
KdInitTouchScreen (&TsFuncs); KdInitTouchScreen (&TsFuncs);
#endif #endif

View File

@ -66,7 +66,7 @@ InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
void void
InitInput (int argc, char **argv) InitInput (int argc, char **argv)
{ {
KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs); KdInitInput (&LinuxMouseFuncs, &LinuxKeyboardFuncs);
} }
int int

View File

@ -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 * Copyright © 2000 Keith Packard
* *
@ -53,7 +53,7 @@ InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
void void
InitInput (int argc, char **argv) InitInput (int argc, char **argv)
{ {
KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs); KdInitInput (&LinuxMouseFuncs, &LinuxKeyboardFuncs);
} }
int int

View File

@ -22,7 +22,7 @@
* Adapted from ts300.c by Alan Hourihane <alanh@fairlite.demon.co.uk> * Adapted from ts300.c by Alan Hourihane <alanh@fairlite.demon.co.uk>
* For the Compaq IPAQ handheld, with the HP VGA Out Card (F1252A). * 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" #include "pcmcia.h"
@ -47,11 +47,7 @@ InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
void void
InitInput (int argc, char **argv) InitInput (int argc, char **argv)
{ {
#ifdef __powerpc__ KdInitInput (&LinuxMouseFuncs, &LinuxKeyboardFuncs);
KdInitInput (&BusMouseFuncs, &LinuxKeyboardFuncs);
#else
KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs);
#endif
#ifdef TOUCHSCREEN #ifdef TOUCHSCREEN
KdInitTouchScreen (&TsFuncs); KdInitTouchScreen (&TsFuncs);
#endif #endif

View File

@ -1,5 +1,5 @@
XCOMM $XConsortium: Imakefile /main/10 1996/12/02 10:20:33 lehors $ 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=.. KDRIVE=..
#include "../Kdrive.tmpl" #include "../Kdrive.tmpl"
@ -8,9 +8,9 @@ TSSRCS = ts.c
TSOBJS = ts.o TSOBJS = ts.o
#endif #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) INCLUDES = -I. $(KDINCS)

View File

@ -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. * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
* *
@ -53,7 +53,7 @@ BusRead (int adbPort, void *closure)
flags |= KD_BUTTON_2; flags |= KD_BUTTON_2;
if ((buf[0] & 1) == 0) if ((buf[0] & 1) == 0)
flags |= KD_BUTTON_3; flags |= KD_BUTTON_3;
KdEnqueueMouseEvent (flags, dx, dy); KdEnqueueMouseEvent (kdMouseInfo, flags, dx, dy);
} }
} }

View File

@ -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 * Copyright © 1999 Keith Packard
* *
@ -438,8 +438,8 @@ LinuxKeyboardInit (void)
if (!LinuxKbdType) if (!LinuxKbdType)
LinuxKbdType = KdAllocInputType (); LinuxKbdType = KdAllocInputType ();
LinuxKeyboardEnable (LinuxConsoleFd, 0);
KdRegisterFd (LinuxKbdType, LinuxConsoleFd, LinuxKeyboardRead, 0); KdRegisterFd (LinuxKbdType, LinuxConsoleFd, LinuxKeyboardRead, 0);
LinuxKeyboardEnable (LinuxConsoleFd, 0);
KdRegisterFdEnableDisable (LinuxConsoleFd, KdRegisterFdEnableDisable (LinuxConsoleFd,
LinuxKeyboardEnable, LinuxKeyboardEnable,
LinuxKeyboardDisable); LinuxKeyboardDisable);

917
hw/kdrive/linux/mouse.c Normal file
View File

@ -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,
};

View File

@ -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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. 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 #define NEED_EVENTS
#include "X.h" #include "X.h"
@ -63,7 +63,7 @@ MsReadBytes (int fd, char *buf, int len, int min)
} }
void void
MsRead (int port) MsRead (int port, void *closure)
{ {
unsigned char buf[3 * 200]; unsigned char buf[3 * 200];
unsigned char *b; unsigned char *b;
@ -87,11 +87,13 @@ MsRead (int port)
dy = (char)(((b[0] & 0x0C) << 4) | (b[2] & 0x3F)); dy = (char)(((b[0] & 0x0C) << 4) | (b[2] & 0x3F));
n -= 3; n -= 3;
b += 3; b += 3;
KdEnqueueMouseEvent (flags, dx, dy); KdEnqueueMouseEvent (kdMouseInfo, flags, dx, dy);
} }
} }
} }
int MsInputType;
int int
MsInit (void) MsInit (void)
{ {
@ -100,6 +102,8 @@ MsInit (void)
struct termios t; struct termios t;
int ret; int ret;
if (!MsInputType)
MsInputType = KdAllocInputType ();
port = open (device, O_RDWR | O_NONBLOCK); port = open (device, O_RDWR | O_NONBLOCK);
if(port < 0) { if(port < 0) {
ErrorF("Couldn't open %s (%d)\n", device, (int)errno); ErrorF("Couldn't open %s (%d)\n", device, (int)errno);
@ -107,8 +111,7 @@ MsInit (void)
} else if (port == 0) { } else if (port == 0) {
ErrorF("Opening %s returned 0! Please complain to Keith.\n", ErrorF("Opening %s returned 0! Please complain to Keith.\n",
device); device);
close(port); goto bail;
return 0;
} }
if(!isatty(port)) { if(!isatty(port)) {
@ -137,7 +140,8 @@ MsInit (void)
ErrorF("Couldn't tcsetattr(%s): %d\n", device, errno); ErrorF("Couldn't tcsetattr(%s): %d\n", device, errno);
goto bail; goto bail;
} }
return port; if (KdRegisterFd (MsInputType, port, MsRead, (void *) 0))
return 1;
bail: bail:
close(port); close(port);
@ -145,14 +149,12 @@ MsInit (void)
} }
void void
MsFini (int port) MsFini (void)
{ {
if (port >= 0) KdUnregisterFds (MsInputType, TRUE);
close(port);
} }
KdMouseFuncs MsMouseFuncs = { KdMouseFuncs MsMouseFuncs = {
MsInit, MsInit,
MsRead,
MsFini MsFini
}; };

View File

@ -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 * Copyright © 1999 Keith Packard
* *
@ -110,7 +110,7 @@ Ps2Read (int ps2Port, void *closure)
dy = -dy; dy = -dy;
n -= 3; n -= 3;
b += 3; b += 3;
KdEnqueueMouseEvent (flags, dx, dy); KdEnqueueMouseEvent (kdMouseInfo, flags, dx, dy);
} }
} }
} }

View File

@ -22,7 +22,7 @@
* *
* Author: Keith Packard, SuSE, Inc. * 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" #include "mach64.h"
@ -44,7 +44,7 @@ InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
void void
InitInput (int argc, char **argv) InitInput (int argc, char **argv)
{ {
KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs); KdInitInput (&LinuxMouseFuncs, &LinuxKeyboardFuncs);
} }
int int

View File

@ -21,7 +21,7 @@
* *
* Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> * 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" #include "pcmcia.h"
@ -42,7 +42,7 @@ InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
void void
InitInput (int argc, char **argv) InitInput (int argc, char **argv)
{ {
KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs); KdInitInput (&LinuxMouseFuncs, &LinuxKeyboardFuncs);
} }
extern pcmciaDisplayModeRec pcmciaDefaultModes[]; extern pcmciaDisplayModeRec pcmciaDefaultModes[];

View File

@ -22,7 +22,7 @@
* *
* Author: Keith Packard, SuSE, Inc. * 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" #include "s3.h"
@ -61,7 +61,7 @@ InitInput (int argc, char **argv)
KdInitInput (&VxWorksMouseFuncs, &VxWorksKeyboardFuncs); KdInitInput (&VxWorksMouseFuncs, &VxWorksKeyboardFuncs);
#endif #endif
#ifdef linux #ifdef linux
KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs); KdInitInput (&LinuxMouseFuncs, &LinuxKeyboardFuncs);
#endif #endif
} }

View File

@ -22,7 +22,7 @@
* *
* Author: Keith Packard, SuSE, Inc. * 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" #include "sis.h"
@ -50,7 +50,7 @@ InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
void void
InitInput (int argc, char **argv) InitInput (int argc, char **argv)
{ {
KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs); KdInitInput (&LinuxMouseFuncs, &LinuxKeyboardFuncs);
} }
int int

View File

@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE. * 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" #include "kdrive.h"
#ifdef PSEUDO8 #ifdef PSEUDO8
@ -373,7 +373,7 @@ KdParseScreen (KdScreenInfo *screen,
screen->fb[fb].depth = 0; screen->fb[fb].depth = 0;
if (!arg) if (!arg)
return; return;
if (strlen (arg) > sizeof (save)) if (strlen (arg) >= sizeof (save))
return; return;
for (i = 0; i < 2; i++) 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 int
KdProcessArgument (int argc, char **argv, int i) KdProcessArgument (int argc, char **argv, int i)
{ {
@ -542,6 +650,14 @@ KdProcessArgument (int argc, char **argv, int i)
UseMsg (); UseMsg ();
return 2; return 2;
} }
if (!strcmp (argv[i], "-mouse"))
{
if ((i+1) < argc)
KdParseMouse (argv[i+1]);
else
UseMsg ();
return 2;
}
#ifdef PSEUDO8 #ifdef PSEUDO8
return p8ProcessArgument (argc, argv, i); return p8ProcessArgument (argc, argv, i);
#else #else

View File

@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE. * 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 <stdio.h>
#include "X.h" #include "X.h"
@ -167,6 +167,44 @@ typedef struct {
#endif #endif
} KdPrivScreenRec, *KdPrivScreenPtr; } 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 { typedef struct _KdMouseFuncs {
int (*Init) (void); int (*Init) (void);
void (*Fini) (void); void (*Fini) (void);
@ -478,6 +516,12 @@ void
KdParseScreen (KdScreenInfo *screen, KdParseScreen (KdScreenInfo *screen,
char *arg); char *arg);
char *
KdSaveString (char *str);
void
KdParseMouse (char *arg);
void void
KdOsInit (KdOsFuncs *pOsFuncs); KdOsInit (KdOsFuncs *pOsFuncs);
@ -560,13 +604,15 @@ KdEnqueueKeyboardEvent(unsigned char scan_code,
#define KD_BUTTON_1 0x01 #define KD_BUTTON_1 0x01
#define KD_BUTTON_2 0x02 #define KD_BUTTON_2 0x02
#define KD_BUTTON_3 0x04 #define KD_BUTTON_3 0x04
#define KD_BUTTON_4 0x08
#define KD_BUTTON_5 0x10
#define KD_MOUSE_DELTA 0x80000000 #define KD_MOUSE_DELTA 0x80000000
void void
KdEnqueueMouseEvent(unsigned long flags, int x, int y); KdEnqueueMouseEvent(KdMouseInfo *mi, unsigned long flags, int x, int y);
void void
KdEnqueueMotionEvent (int x, int y); KdEnqueueMotionEvent (KdMouseInfo *mi, int x, int y);
void void
KdReleaseAllKeys (void); KdReleaseAllKeys (void);
@ -598,6 +644,7 @@ KdEnableInput (void);
void void
ProcessInputEvents (); ProcessInputEvents ();
extern KdMouseFuncs LinuxMouseFuncs;
extern KdMouseFuncs Ps2MouseFuncs; extern KdMouseFuncs Ps2MouseFuncs;
extern KdMouseFuncs BusMouseFuncs; extern KdMouseFuncs BusMouseFuncs;
extern KdMouseFuncs MsMouseFuncs; extern KdMouseFuncs MsMouseFuncs;

View File

@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE. * 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" #include "kdrive.h"
@ -108,3 +108,37 @@ KdScreenInfoDispose (KdScreenInfo *si)
break; 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;
}
}

View File

@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE. * 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 "kdrive.h"
#include "inputstr.h" #include "inputstr.h"
@ -54,6 +54,7 @@ static KdMouseMatrix kdMouseMatrix = {
static KdMouseFuncs *kdTsFuncs; static KdMouseFuncs *kdTsFuncs;
#endif #endif
int kdMouseButtonCount;
int kdMinScanCode; int kdMinScanCode;
int kdMaxScanCode; int kdMaxScanCode;
int kdMinKeyCode; int kdMinKeyCode;
@ -67,8 +68,6 @@ KeySymsRec kdKeySyms;
void void
KdResetInputMachine (void); KdResetInputMachine (void);
#define KD_MOUSEBUTTON_COUNT 3
#define KD_KEY_COUNT 248 #define KD_KEY_COUNT 248
CARD8 kdKeyState[KD_KEY_COUNT/8]; CARD8 kdKeyState[KD_KEY_COUNT/8];
@ -288,9 +287,10 @@ KdEnableInput (void)
static int static int
KdMouseProc(DeviceIntPtr pDevice, int onoff) KdMouseProc(DeviceIntPtr pDevice, int onoff)
{ {
BYTE map[4]; BYTE map[KD_MAX_BUTTON];
DevicePtr pDev = (DevicePtr)pDevice; DevicePtr pDev = (DevicePtr)pDevice;
int i; int i;
KdMouseInfo *mi;
if (!pDev) if (!pDev)
return BadImplementation; return BadImplementation;
@ -298,9 +298,9 @@ KdMouseProc(DeviceIntPtr pDevice, int onoff)
switch (onoff) switch (onoff)
{ {
case DEVICE_INIT: case DEVICE_INIT:
for (i = 1; i <= KD_MOUSEBUTTON_COUNT; i++) for (i = 1; i <= kdMouseButtonCount; i++)
map[i] = i; map[i] = i;
InitPointerDeviceStruct(pDev, map, KD_MOUSEBUTTON_COUNT, InitPointerDeviceStruct(pDev, map, kdMouseButtonCount,
miPointerGetMotionEvents, miPointerGetMotionEvents,
(PtrCtrlProcPtr)NoopDDA, (PtrCtrlProcPtr)NoopDDA,
miPointerGetMotionBufferSize()); miPointerGetMotionBufferSize());
@ -503,7 +503,17 @@ KdInitInput(KdMouseFuncs *pMouseFuncs,
KdKeyboardFuncs *pKeyboardFuncs) KdKeyboardFuncs *pKeyboardFuncs)
{ {
DeviceIntPtr pKeyboard, pPointer; 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; kdMouseFuncs = pMouseFuncs;
kdKeyboardFuncs = pKeyboardFuncs; kdKeyboardFuncs = pKeyboardFuncs;
memset (kdKeyState, '\0', sizeof (kdKeyState)); memset (kdKeyState, '\0', sizeof (kdKeyState));
@ -555,6 +565,8 @@ KdInitTouchScreen(KdMouseFuncs *pTsFuncs)
* Button 2 release ^2 * Button 2 release ^2
* Button 3 press v3 * Button 3 press v3
* Button 3 release ^3 * Button 3 release ^3
* Button other press vo
* Button other release ^o
* Mouse motion <> * Mouse motion <>
* Keyboard event k * Keyboard event k
* timeout ... * timeout ...
@ -580,6 +592,8 @@ KdInitTouchScreen(KdMouseFuncs *pTsFuncs)
* ^2 -> (deliever) start * ^2 -> (deliever) start
* v3 -> (hold) (settimeout) button_3_pend * v3 -> (hold) (settimeout) button_3_pend
* ^3 -> (deliver) start * ^3 -> (deliver) start
* vo -> (deliver) start
* ^o -> (deliver) start
* <> -> (deliver) start * <> -> (deliver) start
* k -> (deliver) start * k -> (deliver) start
* *
@ -589,6 +603,8 @@ KdInitTouchScreen(KdMouseFuncs *pTsFuncs)
* ^2 -> (release) (deliver) button_1_down * ^2 -> (release) (deliver) button_1_down
* v3 -> (cleartimeout) (generate v2) synthetic_2_down_13 * v3 -> (cleartimeout) (generate v2) synthetic_2_down_13
* ^3 -> (release) (deliver) button_1_down * ^3 -> (release) (deliver) button_1_down
* vo -> (release) (deliver) button_1_down
* ^o -> (release) (deliver) button_1_down
* <-> -> (release) (deliver) button_1_down * <-> -> (release) (deliver) button_1_down
* <> -> (deliver) button_1_pend * <> -> (deliver) button_1_pend
* k -> (release) (deliver) button_1_down * k -> (release) (deliver) button_1_down
@ -600,6 +616,8 @@ KdInitTouchScreen(KdMouseFuncs *pTsFuncs)
* ^2 -> (deliver) button_1_down * ^2 -> (deliver) button_1_down
* v3 -> (deliver) button_1_down * v3 -> (deliver) button_1_down
* ^3 -> (deliver) button_1_down * ^3 -> (deliver) button_1_down
* vo -> (deliver) button_1_down
* ^o -> (deliver) button_1_down
* <> -> (deliver) button_1_down * <> -> (deliver) button_1_down
* k -> (deliver) button_1_down * k -> (deliver) button_1_down
* *
@ -609,6 +627,8 @@ KdInitTouchScreen(KdMouseFuncs *pTsFuncs)
* ^2 -> (deliver) start * ^2 -> (deliver) start
* v3 -> (deliver) button_2_down * v3 -> (deliver) button_2_down
* ^3 -> (deliver) button_2_down * ^3 -> (deliver) button_2_down
* vo -> (deliver) button_2_down
* ^o -> (deliver) button_2_down
* <> -> (deliver) button_2_down * <> -> (deliver) button_2_down
* k -> (deliver) button_2_down * k -> (deliver) button_2_down
* *
@ -618,6 +638,8 @@ KdInitTouchScreen(KdMouseFuncs *pTsFuncs)
* v2 -> (release) (deliver) button_3_down * v2 -> (release) (deliver) button_3_down
* ^2 -> (release) (deliver) button_3_down * ^2 -> (release) (deliver) button_3_down
* ^3 -> (release) (deliver) start * ^3 -> (release) (deliver) start
* vo -> (release) (deliver) button_3_down
* ^o -> (release) (deliver) button_3_down
* <-> -> (release) (deliver) button_3_down * <-> -> (release) (deliver) button_3_down
* <> -> (deliver) button_3_pend * <> -> (deliver) button_3_pend
* k -> (release) (deliver) button_3_down * k -> (release) (deliver) button_3_down
@ -629,6 +651,8 @@ KdInitTouchScreen(KdMouseFuncs *pTsFuncs)
* v2 -> (deliver) button_3_down * v2 -> (deliver) button_3_down
* ^2 -> (deliver) button_3_down * ^2 -> (deliver) button_3_down
* ^3 -> (deliver) start * ^3 -> (deliver) start
* vo -> (deliver) button_3_down
* ^o -> (deliver) button_3_down
* <> -> (deliver) button_3_down * <> -> (deliver) button_3_down
* k -> (deliver) button_3_down * k -> (deliver) button_3_down
* *
@ -637,6 +661,8 @@ KdInitTouchScreen(KdMouseFuncs *pTsFuncs)
* v2 -> synthetic_2_down_13 * v2 -> synthetic_2_down_13
* ^2 -> synthetic_2_down_13 * ^2 -> synthetic_2_down_13
* ^3 -> (generate ^2) synthetic_2_down_1 * ^3 -> (generate ^2) synthetic_2_down_1
* vo -> (deliver) synthetic_2_down_13
* ^o -> (deliver) synthetic_2_down_13
* <> -> (deliver) synthetic_2_down_13 * <> -> (deliver) synthetic_2_down_13
* k -> (deliver) synthetic_2_down_13 * k -> (deliver) synthetic_2_down_13
* *
@ -646,6 +672,8 @@ KdInitTouchScreen(KdMouseFuncs *pTsFuncs)
* v2 -> synthetic_2_down_3 * v2 -> synthetic_2_down_3
* ^2 -> synthetic_2_down_3 * ^2 -> synthetic_2_down_3
* ^3 -> start * ^3 -> start
* vo -> (deliver) synthetic_2_down_3
* ^o -> (deliver) synthetic_2_down_3
* <> -> (deliver) synthetic_2_down_3 * <> -> (deliver) synthetic_2_down_3
* k -> (deliver) synthetic_2_down_3 * k -> (deliver) synthetic_2_down_3
* *
@ -655,27 +683,17 @@ KdInitTouchScreen(KdMouseFuncs *pTsFuncs)
* ^2 -> synthetic_2_down_1 * ^2 -> synthetic_2_down_1
* v3 -> (deliver) synthetic_2_down_1 * v3 -> (deliver) synthetic_2_down_1
* ^3 -> (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 * <> -> (deliver) synthetic_2_down_1
* k -> (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 { typedef enum _inputClass {
down_1, up_1, down_1, up_1,
down_2, up_2, down_2, up_2,
down_3, up_3, down_3, up_3,
down_o, up_o,
motion, outside_box, motion, outside_box,
keyboard, timeout, keyboard, timeout,
num_input_class num_input_class
@ -696,7 +714,7 @@ typedef enum _inputAction {
typedef struct _inputTransition { typedef struct _inputTransition {
KdInputAction actions[MAX_ACTIONS]; KdInputAction actions[MAX_ACTIONS];
KdInputState nextState; KdMouseState nextState;
} KdInputTransition; } KdInputTransition;
KdInputTransition kdInputMachine[num_input_states][num_input_class] = { KdInputTransition kdInputMachine[num_input_states][num_input_class] = {
@ -708,9 +726,11 @@ KdInputTransition kdInputMachine[num_input_states][num_input_class] = {
{ { deliver, noop }, start }, /* ^2 */ { { deliver, noop }, start }, /* ^2 */
{ { hold, setto }, button_3_pend }, /* v3 */ { { hold, setto }, button_3_pend }, /* v3 */
{ { deliver, noop }, start }, /* ^3 */ { { deliver, noop }, start }, /* ^3 */
{ { deliver, noop }, start }, /* vo */
{ { deliver, noop }, start }, /* ^o */
{ { deliver, noop }, start }, /* <> */ { { deliver, noop }, start }, /* <> */
{ { deliver, noop }, start }, /* <-> */ { { deliver, noop }, start }, /* <-> */
{ { deliver, noop }, start }, /* k */ { { noop, noop }, start }, /* k */
{ { noop, noop }, start }, /* ... */ { { noop, noop }, start }, /* ... */
}, },
/* button_1_pend */ /* button_1_pend */
@ -721,9 +741,11 @@ KdInputTransition kdInputMachine[num_input_states][num_input_class] = {
{ { release, deliver }, button_1_down }, /* ^2 */ { { release, deliver }, button_1_down }, /* ^2 */
{ { clearto, gen_down_2 }, synth_2_down_13 }, /* v3 */ { { clearto, gen_down_2 }, synth_2_down_13 }, /* v3 */
{ { release, deliver }, button_1_down }, /* ^3 */ { { release, deliver }, button_1_down }, /* ^3 */
{ { release, deliver }, button_1_down }, /* vo */
{ { release, deliver }, button_1_down }, /* ^o */
{ { deliver, noop }, button_1_pend }, /* <> */ { { deliver, noop }, button_1_pend }, /* <> */
{ { release, deliver }, button_1_down }, /* <-> */ { { release, deliver }, button_1_down }, /* <-> */
{ { release, deliver }, button_1_down }, /* k */ { { noop, noop }, button_1_down }, /* k */
{ { release, noop }, button_1_down }, /* ... */ { { release, noop }, button_1_down }, /* ... */
}, },
/* 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 }, /* ^2 */
{ { deliver, noop }, button_1_down }, /* v3 */ { { deliver, noop }, button_1_down }, /* v3 */
{ { deliver, noop }, button_1_down }, /* ^3 */ { { 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 }, /* <-> */ { { deliver, noop }, button_1_down }, /* <-> */
{ { deliver, noop }, button_1_down }, /* k */ { { noop, noop }, button_1_down }, /* k */
{ { noop, noop }, button_1_down }, /* ... */ { { noop, noop }, button_1_down }, /* ... */
}, },
/* button_2_down */ /* button_2_down */
@ -747,9 +771,11 @@ KdInputTransition kdInputMachine[num_input_states][num_input_class] = {
{ { deliver, noop }, start }, /* ^2 */ { { deliver, noop }, start }, /* ^2 */
{ { deliver, noop }, button_2_down }, /* v3 */ { { deliver, noop }, button_2_down }, /* v3 */
{ { deliver, noop }, button_2_down }, /* ^3 */ { { 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 }, /* <-> */ { { deliver, noop }, button_2_down }, /* <-> */
{ { deliver, noop }, button_2_down }, /* k */ { { noop, noop }, button_2_down }, /* k */
{ { noop, noop }, button_2_down }, /* ... */ { { noop, noop }, button_2_down }, /* ... */
}, },
/* button_3_pend */ /* 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 }, /* ^2 */
{ { release, deliver }, button_3_down }, /* v3 */ { { release, deliver }, button_3_down }, /* v3 */
{ { release, deliver }, start }, /* ^3 */ { { release, deliver }, start }, /* ^3 */
{ { release, deliver }, button_3_down }, /* vo */
{ { release, deliver }, button_3_down }, /* ^o */
{ { deliver, noop }, button_3_pend }, /* <> */ { { deliver, noop }, button_3_pend }, /* <> */
{ { release, deliver }, button_3_down }, /* <-> */ { { release, deliver }, button_3_down }, /* <-> */
{ { release, deliver }, button_3_down }, /* k */ { { release, noop }, button_3_down }, /* k */
{ { release, noop }, button_3_down }, /* ... */ { { release, noop }, button_3_down }, /* ... */
}, },
/* button_3_down */ /* button_3_down */
@ -773,9 +801,11 @@ KdInputTransition kdInputMachine[num_input_states][num_input_class] = {
{ { deliver, noop }, button_3_down }, /* ^2 */ { { deliver, noop }, button_3_down }, /* ^2 */
{ { noop, noop }, button_3_down }, /* v3 */ { { noop, noop }, button_3_down }, /* v3 */
{ { deliver, noop }, start }, /* ^3 */ { { 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 }, /* <-> */ { { deliver, noop }, button_3_down }, /* <-> */
{ { deliver, noop }, button_3_down }, /* k */ { { noop, noop }, button_3_down }, /* k */
{ { noop, noop }, button_3_down }, /* ... */ { { noop, noop }, button_3_down }, /* ... */
}, },
/* synthetic_2_down_13 */ /* 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 }, /* ^2 */
{ { noop, noop }, synth_2_down_13 }, /* v3 */ { { noop, noop }, synth_2_down_13 }, /* v3 */
{ { gen_up_2, noop }, synth_2_down_1 }, /* ^3 */ { { 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 }, /* <-> */ { { 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 }, /* ... */ { { noop, noop }, synth_2_down_13 }, /* ... */
}, },
/* synthetic_2_down_3 */ /* synthetic_2_down_3 */
@ -799,9 +831,11 @@ KdInputTransition kdInputMachine[num_input_states][num_input_class] = {
{ { deliver, noop }, synth_2_down_3 }, /* ^2 */ { { deliver, noop }, synth_2_down_3 }, /* ^2 */
{ { noop, noop }, synth_2_down_3 }, /* v3 */ { { noop, noop }, synth_2_down_3 }, /* v3 */
{ { noop, noop }, start }, /* ^3 */ { { 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 }, /* <-> */ { { 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 }, /* ... */ { { noop, noop }, synth_2_down_3 }, /* ... */
}, },
/* synthetic_2_down_1 */ /* 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 }, /* ^2 */
{ { deliver, noop }, synth_2_down_1 }, /* v3 */ { { deliver, noop }, synth_2_down_1 }, /* v3 */
{ { deliver, noop }, synth_2_down_1 }, /* ^3 */ { { 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 }, /* <-> */ { { 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 }, /* ... */ { { noop, noop }, synth_2_down_1 }, /* ... */
}, },
}; };
Bool kdEventHeld;
xEvent kdHeldEvent;
int kdEmulationDx, kdEmulationDy;
#define EMULATION_WINDOW 10 #define EMULATION_WINDOW 10
#define EMULATION_TIMEOUT 100 #define EMULATION_TIMEOUT 100
@ -830,24 +862,24 @@ int kdEmulationDx, kdEmulationDy;
#define EventY(e) ((e)->u.keyButtonPointer.rootY) #define EventY(e) ((e)->u.keyButtonPointer.rootY)
int int
KdInsideEmulationWindow (xEvent *ev) KdInsideEmulationWindow (KdMouseInfo *mi, xEvent *ev)
{ {
if (ev->u.keyButtonPointer.pad1) if (ev->u.keyButtonPointer.pad1)
{ {
kdEmulationDx += EventX(ev); mi->emulationDx += EventX(ev);
kdEmulationDy += EventY(ev); mi->emulationDy += EventY(ev);
} }
else else
{ {
kdEmulationDx = EventX(&kdHeldEvent) - EventX(ev); mi->emulationDx = EventX(&mi->heldEvent) - EventX(ev);
kdEmulationDy = EventY(&kdHeldEvent) - EventY(ev); mi->emulationDy = EventY(&mi->heldEvent) - EventY(ev);
} }
return (abs (kdEmulationDx) < EMULATION_WINDOW && return (abs (mi->emulationDx) < EMULATION_WINDOW &&
abs (kdEmulationDy) < EMULATION_WINDOW); abs (mi->emulationDy) < EMULATION_WINDOW);
} }
KdInputClass KdInputClass
KdClassifyInput (xEvent *ev) KdClassifyInput (KdMouseInfo *mi, xEvent *ev)
{ {
switch (ev->u.u.type) { switch (ev->u.u.type) {
case ButtonPress: case ButtonPress:
@ -855,6 +887,7 @@ KdClassifyInput (xEvent *ev)
case 1: return down_1; case 1: return down_1;
case 2: return down_2; case 2: return down_2;
case 3: return down_3; case 3: return down_3;
default: return down_o;
} }
break; break;
case ButtonRelease: case ButtonRelease:
@ -862,10 +895,11 @@ KdClassifyInput (xEvent *ev)
case 1: return up_1; case 1: return up_1;
case 2: return up_2; case 2: return up_2;
case 3: return up_3; case 3: return up_3;
default: return up_o;
} }
break; break;
case MotionNotify: case MotionNotify:
if (kdEventHeld && !KdInsideEmulationWindow(ev)) if (mi->eventHeld && !KdInsideEmulationWindow(mi, ev))
return outside_box; return outside_box;
else else
return motion; return motion;
@ -936,44 +970,42 @@ KdQueueEvent (xEvent *ev)
} }
} }
KdInputState kdInputState;
static void static void
KdRunInputMachine (KdInputClass c, xEvent *ev) KdRunMouseMachine (KdMouseInfo *mi, KdInputClass c, xEvent *ev)
{ {
KdInputTransition *t; KdInputTransition *t;
int a; int a;
t = &kdInputMachine[kdInputState][c]; t = &kdInputMachine[mi->mouseState][c];
for (a = 0; a < MAX_ACTIONS; a++) for (a = 0; a < MAX_ACTIONS; a++)
{ {
switch (t->actions[a]) { switch (t->actions[a]) {
case noop: case noop:
break; break;
case hold: case hold:
kdEventHeld = TRUE; mi->eventHeld = TRUE;
kdEmulationDx = 0; mi->emulationDx = 0;
kdEmulationDy = 0; mi->emulationDy = 0;
kdHeldEvent = *ev; mi->heldEvent = *ev;
break; break;
case setto: case setto:
kdEmulationTimeout = GetTimeInMillis () + EMULATION_TIMEOUT; mi->emulationTimeout = GetTimeInMillis () + EMULATION_TIMEOUT;
kdTimeoutPending = TRUE; mi->timeoutPending = TRUE;
break; break;
case deliver: case deliver:
KdQueueEvent (ev); KdQueueEvent (ev);
break; break;
case release: case release:
kdEventHeld = FALSE; mi->eventHeld = FALSE;
kdTimeoutPending = FALSE; mi->timeoutPending = FALSE;
KdQueueEvent (&kdHeldEvent); KdQueueEvent (&mi->heldEvent);
break; break;
case clearto: case clearto:
kdTimeoutPending = FALSE; mi->timeoutPending = FALSE;
break; break;
case gen_down_2: case gen_down_2:
ev->u.u.detail = 2; ev->u.u.detail = 2;
kdEventHeld = FALSE; mi->eventHeld = FALSE;
KdQueueEvent (ev); KdQueueEvent (ev);
break; break;
case gen_up_2: case gen_up_2:
@ -982,29 +1014,34 @@ KdRunInputMachine (KdInputClass c, xEvent *ev)
break; break;
} }
} }
kdInputState = t->nextState; mi->mouseState = t->nextState;
} }
void void
KdResetInputMachine (void) KdResetInputMachine (void)
{ {
kdInputState = start; KdMouseInfo *mi;
kdEventHeld = FALSE;
for (mi = kdMouseInfo; mi; mi = mi->next)
{
mi->mouseState = start;
mi->eventHeld = FALSE;
}
} }
void void
KdHandleEvent (xEvent *ev) KdHandleMouseEvent (KdMouseInfo *mi, xEvent *ev)
{ {
if (kdEmulateMiddleButton) if (mi->emulateMiddleButton)
KdRunInputMachine (KdClassifyInput (ev), ev); KdRunMouseMachine (mi, KdClassifyInput (mi, ev), ev);
else else
KdQueueEvent (ev); KdQueueEvent (ev);
} }
void 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)) #define KILL_SEQUENCE ((1L << KK_CONTROL)|(1L << KK_ALT)|(1L << KK_F8)|(1L << KK_F10))
@ -1107,9 +1144,10 @@ KdCheckSpecialKeys(xEvent *xE)
void void
KdHandleKeyboardEvent (xEvent *ev) KdHandleKeyboardEvent (xEvent *ev)
{ {
int key = ev->u.u.detail; int key = ev->u.u.detail;
int byte; int byte;
CARD8 bit; CARD8 bit;
KdMouseInfo *mi;
byte = key >> 3; byte = key >> 3;
bit = 1 << (key & 7); bit = 1 << (key & 7);
@ -1121,7 +1159,9 @@ KdHandleKeyboardEvent (xEvent *ev)
kdKeyState[byte] &= ~bit; kdKeyState[byte] &= ~bit;
break; break;
} }
KdHandleEvent (ev); for (mi = kdMouseInfo; mi; mi = mi->next)
KdRunMouseMachine (mi, keyboard, 0);
KdQueueEvent (ev);
} }
void 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; \ xE.u.u.type = v; \
KdHandleEvent (&xE); \ KdHandleMouseEvent (mi, &xE); \
} }
#define Press(b) SetButton(b+1,ButtonPress,"Down") #define Press(mi, b) SetButton(mi, b, ButtonPress, "Down")
#define Release(b) SetButton(b+1,ButtonRelease,"Up") #define Release(mi, b) SetButton(mi, b, ButtonRelease, "Up")
static unsigned char kdButtonState = 0;
/* /*
* kdEnqueueMouseEvent * kdEnqueueMouseEvent
@ -1267,13 +1305,15 @@ KdMouseAccelerate (DeviceIntPtr device, int delta)
} }
void void
KdEnqueueMouseEvent(unsigned long flags, int rx, int ry) KdEnqueueMouseEvent(KdMouseInfo *mi, unsigned long flags, int rx, int ry)
{ {
CARD32 ms; CARD32 ms;
xEvent xE; xEvent xE;
unsigned char buttons; unsigned char buttons;
int x, y; int x, y;
int (*matrix)[3] = kdMouseMatrix.matrix; int (*matrix)[3] = kdMouseMatrix.matrix;
unsigned long button;
int n;
if (!pKdPointer) if (!pKdPointer)
return; return;
@ -1300,48 +1340,29 @@ KdEnqueueMouseEvent(unsigned long flags, int rx, int ry)
xE.u.u.type = MotionNotify; xE.u.u.type = MotionNotify;
xE.u.u.detail = 0; xE.u.u.detail = 0;
KdHandleEvent (&xE); KdHandleMouseEvent (mi, &xE);
buttons = flags; buttons = flags;
if ((kdButtonState & KD_BUTTON_1) ^ (buttons & KD_BUTTON_1)) for (button = KD_BUTTON_1, n = 0; button <= KD_BUTTON_5; button <<= 1, n++)
{ {
if (buttons & KD_BUTTON_1) if ((mi->buttonState & button) ^ (buttons & button))
{ {
Press(0); if (buttons & button)
} {
else Press(mi, n);
{ }
Release(0); else
{
Release(mi, n);
}
} }
} }
if ((kdButtonState & KD_BUTTON_2) ^ (buttons & KD_BUTTON_2)) mi->buttonState = buttons;
{
if (buttons & KD_BUTTON_2)
{
Press(1);
}
else
{
Release(1);
}
}
if ((kdButtonState & KD_BUTTON_3) ^ (buttons & KD_BUTTON_3))
{
if (buttons & KD_BUTTON_3)
{
Press(2);
}
else
{
Release(2);
}
}
kdButtonState = buttons;
} }
void void
KdEnqueueMotionEvent (int x, int y) KdEnqueueMotionEvent (KdMouseInfo *mi, int x, int y)
{ {
xEvent xE; xEvent xE;
CARD32 ms; CARD32 ms;
@ -1353,7 +1374,7 @@ KdEnqueueMotionEvent (int x, int y)
xE.u.keyButtonPointer.rootX = x; xE.u.keyButtonPointer.rootX = x;
xE.u.keyButtonPointer.rootY = y; xE.u.keyButtonPointer.rootY = y;
KdHandleEvent (&xE); KdHandleMouseEvent (mi, &xE);
} }
void void
@ -1362,29 +1383,19 @@ KdBlockHandler (int screen,
pointer timeout, pointer timeout,
pointer readmask) pointer readmask)
{ {
struct timeval **pTimeout = timeout; KdMouseInfo *mi;
if (kdTimeoutPending) for (mi = kdMouseInfo; mi; mi = mi->next)
{ {
static struct timeval tv; if (mi->timeoutPending)
int ms;
ms = kdEmulationTimeout - GetTimeInMillis ();
if (ms < 0)
ms = 0;
tv.tv_sec = ms / 1000;
tv.tv_usec = (ms % 1000) * 1000;
if (*pTimeout)
{ {
if ((*pTimeout)->tv_sec > tv.tv_sec || int ms;
((*pTimeout)->tv_sec == tv.tv_sec &&
(*pTimeout)->tv_usec > tv.tv_usec)) ms = mi->emulationTimeout - GetTimeInMillis ();
{ if (ms < 0)
*pTimeout = &tv; ms = 0;
} AdjustWaitForDelay (timeout, ms);
} }
else
*pTimeout = &tv;
} }
} }
@ -1394,9 +1405,10 @@ KdWakeupHandler (int screen,
unsigned long lresult, unsigned long lresult,
pointer readmask) pointer readmask)
{ {
int result = (int) lresult; int result = (int) lresult;
fd_set *pReadmask = (fd_set *) readmask; fd_set *pReadmask = (fd_set *) readmask;
int i; int i;
KdMouseInfo *mi;
if (kdInputEnabled && result > 0) if (kdInputEnabled && result > 0)
{ {
@ -1408,14 +1420,17 @@ KdWakeupHandler (int screen,
KdUnblockSigio (); KdUnblockSigio ();
} }
} }
if (kdTimeoutPending) for (mi = kdMouseInfo; mi; mi = mi->next)
{ {
if ((long) (GetTimeInMillis () - kdEmulationTimeout) >= 0) if (mi->timeoutPending)
{ {
kdTimeoutPending = FALSE; if ((long) (GetTimeInMillis () - mi->emulationTimeout) >= 0)
KdBlockSigio (); {
KdReceiveTimeout (); mi->timeoutPending = FALSE;
KdUnblockSigio (); KdBlockSigio ();
KdReceiveTimeout (mi);
KdUnblockSigio ();
}
} }
} }
if (kdSwitchPending) if (kdSwitchPending)

View File

@ -22,7 +22,7 @@
* *
* Author: Keith Packard, SuSE, Inc. * 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" #include "trident.h"
@ -46,7 +46,7 @@ InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
void void
InitInput (int argc, char **argv) InitInput (int argc, char **argv)
{ {
KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs); KdInitInput (&LinuxMouseFuncs, &LinuxKeyboardFuncs);
} }
int int

View File

@ -22,7 +22,7 @@
* *
* Author: Keith Packard, SuSE, Inc. * 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" #include "s3.h"
@ -49,7 +49,7 @@ InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
void void
InitInput (int argc, char **argv) InitInput (int argc, char **argv)
{ {
KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs); KdInitInput (&LinuxMouseFuncs, &LinuxKeyboardFuncs);
} }
int int

View File

@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE. * 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" #include "kdrive.h"
@ -120,7 +120,7 @@ InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
void void
InitInput (int argc, char **argv) InitInput (int argc, char **argv)
{ {
KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs); KdInitInput (&LinuxMouseFuncs, &LinuxKeyboardFuncs);
} }
int int

View File

@ -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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. 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" #include "vesa.h"
@ -69,7 +69,7 @@ InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
void void
InitInput (int argc, char **argv) InitInput (int argc, char **argv)
{ {
KdInitInput(&Ps2MouseFuncs, &LinuxKeyboardFuncs); KdInitInput(&LinuxMouseFuncs, &LinuxKeyboardFuncs);
} }
int int