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.
*/
/* $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

View File

@ -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

View File

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

View File

@ -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

View File

@ -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)

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.
*
@ -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);
}
}

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
*
@ -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);

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

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

View File

@ -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

View File

@ -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[];

View File

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

View File

@ -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

View File

@ -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

View File

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

View File

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

View File

@ -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))
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);
}
else
{
Release(0);
if (buttons & button)
{
Press(mi, n);
}
else
{
Release(mi, n);
}
}
}
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))
{
if (buttons & KD_BUTTON_3)
{
Press(2);
}
else
{
Release(2);
}
}
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)

View File

@ -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

View File

@ -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

View File

@ -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

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
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