1673 lines
		
	
	
		
			39 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			1673 lines
		
	
	
		
			39 KiB
		
	
	
	
		
			C
		
	
	
	
/*
 | 
						|
 * Copyright  1999 Keith Packard
 | 
						|
 *
 | 
						|
 * 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.
 | 
						|
 */
 | 
						|
 | 
						|
#include <xgl-config.h>
 | 
						|
 | 
						|
#include <signal.h>
 | 
						|
#include <stdio.h>
 | 
						|
 | 
						|
#include "xegl.h"
 | 
						|
#include "mipointer.h"
 | 
						|
#include "inputstr.h"
 | 
						|
 | 
						|
#define XK_PUBLISHING
 | 
						|
#include <X11/keysym.h>
 | 
						|
#if HAVE_X11_XF86KEYSYM_H
 | 
						|
#include <X11/XF86keysym.h>
 | 
						|
#endif
 | 
						|
#include "kkeymap.h"
 | 
						|
 | 
						|
#ifdef XKB
 | 
						|
#define XKB_IN_SERVER
 | 
						|
#include <xkbsrv.h>
 | 
						|
#endif
 | 
						|
 | 
						|
static DeviceIntPtr	pKdKeyboard, pKdPointer;
 | 
						|
 | 
						|
#define MAX_MOUSE_DRIVERS   6
 | 
						|
 | 
						|
static KdMouseFuncs	*kdMouseFuncs[MAX_MOUSE_DRIVERS];
 | 
						|
static int		kdNMouseFuncs;
 | 
						|
static KdKeyboardFuncs	*kdKeyboardFuncs;
 | 
						|
static int		kdBellPitch;
 | 
						|
static int		kdBellDuration;
 | 
						|
static int		kdLeds;
 | 
						|
static Bool		kdInputEnabled;
 | 
						|
static Bool		kdOffScreen;
 | 
						|
static unsigned long	kdOffScreenTime;
 | 
						|
static KdMouseMatrix	kdMouseMatrix = {
 | 
						|
   { { 1, 0, 0 },
 | 
						|
     { 0, 1, 0 } }
 | 
						|
};
 | 
						|
 | 
						|
int		kdMouseButtonCount;
 | 
						|
int		kdMinScanCode;
 | 
						|
int		kdMaxScanCode;
 | 
						|
int		kdMinKeyCode;
 | 
						|
int		kdMaxKeyCode;
 | 
						|
int		kdKeymapWidth = KD_MAX_WIDTH;
 | 
						|
KeySym		kdKeymap[KD_MAX_LENGTH * KD_MAX_WIDTH];
 | 
						|
CARD8		kdModMap[MAP_LENGTH];
 | 
						|
KeySymsRec	kdKeySyms;
 | 
						|
 | 
						|
 | 
						|
void
 | 
						|
KdResetInputMachine (void);
 | 
						|
 | 
						|
#define KD_KEY_COUNT		248
 | 
						|
 | 
						|
CARD8		kdKeyState[KD_KEY_COUNT/8];
 | 
						|
 | 
						|
#define IsKeyDown(key) ((kdKeyState[(key) >> 3] >> ((key) & 7)) & 1)
 | 
						|
 | 
						|
#define KD_MAX_INPUT_FDS    8
 | 
						|
 | 
						|
typedef struct _kdInputFd {
 | 
						|
    int	    type;
 | 
						|
    int	    fd;
 | 
						|
    void    (*read) (int fd, void *closure);
 | 
						|
    int	    (*enable) (int fd, void *closure);
 | 
						|
    void    (*disable) (int fd, void *closure);
 | 
						|
    void    *closure;
 | 
						|
} KdInputFd;
 | 
						|
 | 
						|
KdInputFd    	kdInputFds[KD_MAX_INPUT_FDS];
 | 
						|
int		kdNumInputFds;
 | 
						|
int		kdInputTypeSequence;
 | 
						|
 | 
						|
static void
 | 
						|
KdSigio (int sig)
 | 
						|
{
 | 
						|
    int	i;
 | 
						|
 | 
						|
    for (i = 0; i < kdNumInputFds; i++)
 | 
						|
	(*kdInputFds[i].read) (kdInputFds[i].fd, kdInputFds[i].closure);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
KdBlockSigio (void)
 | 
						|
{
 | 
						|
    sigset_t	set;
 | 
						|
 | 
						|
    sigemptyset (&set);
 | 
						|
    sigaddset (&set, SIGIO);
 | 
						|
    sigprocmask (SIG_BLOCK, &set, 0);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
KdUnblockSigio (void)
 | 
						|
{
 | 
						|
    sigset_t	set;
 | 
						|
 | 
						|
    sigemptyset (&set);
 | 
						|
    sigaddset (&set, SIGIO);
 | 
						|
    sigprocmask (SIG_UNBLOCK, &set, 0);
 | 
						|
}
 | 
						|
 | 
						|
#undef VERIFY_SIGIO
 | 
						|
#ifdef VERIFY_SIGIO
 | 
						|
 | 
						|
void
 | 
						|
KdAssertSigioBlocked (char *where)
 | 
						|
{
 | 
						|
    sigset_t	set, old;
 | 
						|
 | 
						|
    sigemptyset (&set);
 | 
						|
    sigprocmask (SIG_BLOCK, &set, &old);
 | 
						|
    if (!sigismember (&old, SIGIO))
 | 
						|
	ErrorF ("SIGIO not blocked at %s\n", where);
 | 
						|
}
 | 
						|
 | 
						|
#else
 | 
						|
 | 
						|
#define KdAssertSigioBlocked(s)
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
static int  kdnFds;
 | 
						|
 | 
						|
#ifdef FNONBLOCK
 | 
						|
#define NOBLOCK FNONBLOCK
 | 
						|
#else
 | 
						|
#define NOBLOCK FNDELAY
 | 
						|
#endif
 | 
						|
 | 
						|
static void
 | 
						|
KdNonBlockFd (int fd)
 | 
						|
{
 | 
						|
    int	flags;
 | 
						|
    flags = fcntl (fd, F_GETFL);
 | 
						|
    flags |= FASYNC|NOBLOCK;
 | 
						|
    fcntl (fd, F_SETFL, flags);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
KdAddFd (int fd)
 | 
						|
{
 | 
						|
    struct sigaction	act;
 | 
						|
    sigset_t		set;
 | 
						|
 | 
						|
    kdnFds++;
 | 
						|
    fcntl (fd, F_SETOWN, getpid());
 | 
						|
    KdNonBlockFd (fd);
 | 
						|
    AddEnabledDevice (fd);
 | 
						|
    memset (&act, '\0', sizeof act);
 | 
						|
    act.sa_handler = KdSigio;
 | 
						|
    sigemptyset (&act.sa_mask);
 | 
						|
    sigaddset (&act.sa_mask, SIGIO);
 | 
						|
    sigaddset (&act.sa_mask, SIGALRM);
 | 
						|
    sigaddset (&act.sa_mask, SIGVTALRM);
 | 
						|
    sigaction (SIGIO, &act, 0);
 | 
						|
    sigemptyset (&set);
 | 
						|
    sigprocmask (SIG_SETMASK, &set, 0);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
KdRemoveFd (int fd)
 | 
						|
{
 | 
						|
    struct sigaction	act;
 | 
						|
    int			flags;
 | 
						|
 | 
						|
    kdnFds--;
 | 
						|
    RemoveEnabledDevice (fd);
 | 
						|
    flags = fcntl (fd, F_GETFL);
 | 
						|
    flags &= ~(FASYNC|NOBLOCK);
 | 
						|
    fcntl (fd, F_SETFL, flags);
 | 
						|
    if (kdnFds == 0)
 | 
						|
    {
 | 
						|
	memset (&act, '\0', sizeof act);
 | 
						|
	act.sa_handler = SIG_IGN;
 | 
						|
	sigemptyset (&act.sa_mask);
 | 
						|
	sigaction (SIGIO, &act, 0);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
KdAllocInputType (void)
 | 
						|
{
 | 
						|
    return ++kdInputTypeSequence;
 | 
						|
}
 | 
						|
 | 
						|
Bool
 | 
						|
KdRegisterFd (int type, int fd, void (*read) (int fd, void *closure), void *closure)
 | 
						|
{
 | 
						|
    if (kdNumInputFds == KD_MAX_INPUT_FDS)
 | 
						|
	return FALSE;
 | 
						|
    kdInputFds[kdNumInputFds].type = type;
 | 
						|
    kdInputFds[kdNumInputFds].fd = fd;
 | 
						|
    kdInputFds[kdNumInputFds].read = read;
 | 
						|
    kdInputFds[kdNumInputFds].enable = 0;
 | 
						|
    kdInputFds[kdNumInputFds].disable = 0;
 | 
						|
    kdInputFds[kdNumInputFds].closure = closure;
 | 
						|
    ++kdNumInputFds;
 | 
						|
    if (kdInputEnabled)
 | 
						|
	KdAddFd (fd);
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
KdRegisterFdEnableDisable (int fd,
 | 
						|
			   int (*enable) (int fd, void *closure),
 | 
						|
			   void (*disable) (int fd, void *closure))
 | 
						|
{
 | 
						|
    int	i;
 | 
						|
 | 
						|
    for (i = 0; i < kdNumInputFds; i++)
 | 
						|
	if (kdInputFds[i].fd == fd)
 | 
						|
	{
 | 
						|
	    kdInputFds[i].enable = enable;
 | 
						|
	    kdInputFds[i].disable = disable;
 | 
						|
	    break;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
KdUnregisterFds (int type, Bool do_close)
 | 
						|
{
 | 
						|
    int	i, j;
 | 
						|
 | 
						|
    for (i = 0; i < kdNumInputFds;)
 | 
						|
    {
 | 
						|
	if (kdInputFds[i].type == type)
 | 
						|
	{
 | 
						|
	    if (kdInputEnabled)
 | 
						|
		KdRemoveFd (kdInputFds[i].fd);
 | 
						|
	    if (do_close)
 | 
						|
		close (kdInputFds[i].fd);
 | 
						|
	    --kdNumInputFds;
 | 
						|
	    for (j = i; j < kdNumInputFds; j++)
 | 
						|
		kdInputFds[j] = kdInputFds[j+1];
 | 
						|
	}
 | 
						|
	else
 | 
						|
	    i++;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
KdDisableInput (void)
 | 
						|
{
 | 
						|
    int	i;
 | 
						|
 | 
						|
    KdBlockSigio ();
 | 
						|
 | 
						|
    for (i = 0; i < kdNumInputFds; i++)
 | 
						|
    {
 | 
						|
	KdRemoveFd (kdInputFds[i].fd);
 | 
						|
	if (kdInputFds[i].disable)
 | 
						|
	    (*kdInputFds[i].disable) (kdInputFds[i].fd, kdInputFds[i].closure);
 | 
						|
    }
 | 
						|
    kdInputEnabled = FALSE;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
KdEnableInput (void)
 | 
						|
{
 | 
						|
    xEvent	xE;
 | 
						|
    int	i;
 | 
						|
 | 
						|
    kdInputEnabled = TRUE;
 | 
						|
    for (i = 0; i < kdNumInputFds; i++)
 | 
						|
    {
 | 
						|
	KdNonBlockFd (kdInputFds[i].fd);
 | 
						|
	if (kdInputFds[i].enable)
 | 
						|
	    kdInputFds[i].fd = (*kdInputFds[i].enable) (kdInputFds[i].fd, kdInputFds[i].closure);
 | 
						|
	KdAddFd (kdInputFds[i].fd);
 | 
						|
    }
 | 
						|
 | 
						|
    /* reset screen saver */
 | 
						|
    xE.u.keyButtonPointer.time = GetTimeInMillis ();
 | 
						|
    NoticeEventTime (&xE);
 | 
						|
 | 
						|
    KdUnblockSigio ();
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
KdMouseProc(DeviceIntPtr pDevice, int onoff)
 | 
						|
{
 | 
						|
    BYTE	map[KD_MAX_BUTTON];
 | 
						|
    DevicePtr	pDev = (DevicePtr)pDevice;
 | 
						|
    int		i;
 | 
						|
 | 
						|
    if (!pDev)
 | 
						|
	return BadImplementation;
 | 
						|
 | 
						|
    switch (onoff)
 | 
						|
    {
 | 
						|
    case DEVICE_INIT:
 | 
						|
	for (i = 1; i <= kdMouseButtonCount; i++)
 | 
						|
	    map[i] = i;
 | 
						|
	InitPointerDeviceStruct(pDev, map, kdMouseButtonCount,
 | 
						|
	    miPointerGetMotionEvents,
 | 
						|
	    (PtrCtrlProcPtr)NoopDDA,
 | 
						|
	    miPointerGetMotionBufferSize());
 | 
						|
	break;
 | 
						|
 | 
						|
    case DEVICE_ON:
 | 
						|
	pDev->on = TRUE;
 | 
						|
	pKdPointer = pDevice;
 | 
						|
	for (i = 0; i < kdNMouseFuncs; i++)
 | 
						|
	    (*kdMouseFuncs[i]->Init)();
 | 
						|
	break;
 | 
						|
    case DEVICE_OFF:
 | 
						|
    case DEVICE_CLOSE:
 | 
						|
	if (pDev->on)
 | 
						|
	{
 | 
						|
	    pDev->on = FALSE;
 | 
						|
	    pKdPointer = 0;
 | 
						|
	    for (i = 0; i < kdNMouseFuncs; i++)
 | 
						|
		(*kdMouseFuncs[i]->Fini) ();
 | 
						|
	}
 | 
						|
	break;
 | 
						|
    }
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
Bool
 | 
						|
KdLegalModifier(unsigned int key, DevicePtr pDev)
 | 
						|
{
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
KdBell (int volume, DeviceIntPtr pDev, pointer ctrl, int something)
 | 
						|
{
 | 
						|
    if (kdInputEnabled)
 | 
						|
	(*kdKeyboardFuncs->Bell) (volume, kdBellPitch, kdBellDuration);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
static void
 | 
						|
KdSetLeds (void)
 | 
						|
{
 | 
						|
    if (kdInputEnabled)
 | 
						|
	(*kdKeyboardFuncs->Leds) (kdLeds);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
KdSetLed (int led, Bool on)
 | 
						|
{
 | 
						|
    NoteLedState (pKdKeyboard, led, on);
 | 
						|
    kdLeds = pKdKeyboard->kbdfeed->ctrl.leds;
 | 
						|
    KdSetLeds ();
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
KdSetMouseMatrix (KdMouseMatrix *matrix)
 | 
						|
{
 | 
						|
    kdMouseMatrix = *matrix;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
KdComputeMouseMatrix (KdMouseMatrix *m, Rotation randr, int width, int height)
 | 
						|
{
 | 
						|
    int		    x_dir = 1, y_dir = 1;
 | 
						|
    int		    i, j;
 | 
						|
    int		    size[2];
 | 
						|
 | 
						|
    size[0] = width; size[1] = height;
 | 
						|
    if (randr & RR_Reflect_X)
 | 
						|
	x_dir = -1;
 | 
						|
    if (randr & RR_Reflect_Y)
 | 
						|
	y_dir = -1;
 | 
						|
    switch (randr & (RR_Rotate_All)) {
 | 
						|
    case RR_Rotate_0:
 | 
						|
	m->matrix[0][0] = x_dir; m->matrix[0][1] = 0;
 | 
						|
	m->matrix[1][0] = 0; m->matrix[1][1] = y_dir;
 | 
						|
	break;
 | 
						|
    case RR_Rotate_90:
 | 
						|
	m->matrix[0][0] = 0; m->matrix[0][1] = -x_dir;
 | 
						|
	m->matrix[1][0] = y_dir; m->matrix[1][1] = 0;
 | 
						|
	break;
 | 
						|
    case RR_Rotate_180:
 | 
						|
	m->matrix[0][0] = -x_dir; m->matrix[0][1] = 0;
 | 
						|
	m->matrix[1][0] = 0; m->matrix[1][1] = -y_dir;
 | 
						|
	break;
 | 
						|
    case RR_Rotate_270:
 | 
						|
	m->matrix[0][0] = 0; m->matrix[0][1] = x_dir;
 | 
						|
	m->matrix[1][0] = -y_dir; m->matrix[1][1] = 0;
 | 
						|
	break;
 | 
						|
    }
 | 
						|
    for (i = 0; i < 2; i++)
 | 
						|
    {
 | 
						|
	m->matrix[i][2] = 0;
 | 
						|
	for (j = 0 ; j < 2; j++)
 | 
						|
	    if (m->matrix[i][j] < 0)
 | 
						|
		m->matrix[i][2] = size[j] - 1;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
KdKbdCtrl (DeviceIntPtr pDevice, KeybdCtrl *ctrl)
 | 
						|
{
 | 
						|
    kdLeds = ctrl->leds;
 | 
						|
    kdBellPitch = ctrl->bell_pitch;
 | 
						|
    kdBellDuration = ctrl->bell_duration;
 | 
						|
    KdSetLeds ();
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
KdKeybdProc(DeviceIntPtr pDevice, int onoff)
 | 
						|
{
 | 
						|
    Bool        ret;
 | 
						|
    DevicePtr   pDev = (DevicePtr)pDevice;
 | 
						|
#ifdef XKB
 | 
						|
    XkbComponentNamesRec names;
 | 
						|
#endif
 | 
						|
 | 
						|
    if (!pDev)
 | 
						|
	return BadImplementation;
 | 
						|
 | 
						|
    switch (onoff)
 | 
						|
    {
 | 
						|
    case DEVICE_INIT:
 | 
						|
	if (pDev != (DevicePtr)inputInfo.keyboard)
 | 
						|
	{
 | 
						|
	    return !Success;
 | 
						|
	}
 | 
						|
#ifndef XKB
 | 
						|
	ret = InitKeyboardDeviceStruct(pDev,
 | 
						|
				       &kdKeySyms,
 | 
						|
				       kdModMap,
 | 
						|
				       KdBell, KdKbdCtrl);
 | 
						|
#else
 | 
						|
	memset(&names, 0, sizeof(XkbComponentNamesRec));
 | 
						|
 | 
						|
	XkbSetRulesDflts ("base", "pc101", "us", NULL, NULL);
 | 
						|
	ret = XkbInitKeyboardDeviceStruct (pDev,
 | 
						|
					   &names,
 | 
						|
					   &kdKeySyms,
 | 
						|
					   kdModMap,
 | 
						|
					   KdBell, KdKbdCtrl);
 | 
						|
#endif
 | 
						|
	if (!ret)
 | 
						|
	    return BadImplementation;
 | 
						|
	break;
 | 
						|
    case DEVICE_ON:
 | 
						|
	pDev->on = TRUE;
 | 
						|
	pKdKeyboard = pDevice;
 | 
						|
	if (kdKeyboardFuncs)
 | 
						|
	    (*kdKeyboardFuncs->Init) ();
 | 
						|
	break;
 | 
						|
    case DEVICE_OFF:
 | 
						|
    case DEVICE_CLOSE:
 | 
						|
	pKdKeyboard = 0;
 | 
						|
	if (pDev->on)
 | 
						|
	{
 | 
						|
	    pDev->on = FALSE;
 | 
						|
	    if (kdKeyboardFuncs)
 | 
						|
		(*kdKeyboardFuncs->Fini) ();
 | 
						|
	}
 | 
						|
	break;
 | 
						|
    }
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
extern KeybdCtrl defaultKeyboardControl;
 | 
						|
 | 
						|
static void
 | 
						|
KdInitAutoRepeats (void)
 | 
						|
{
 | 
						|
    int		    key_code;
 | 
						|
    unsigned char   mask;
 | 
						|
    int		    i;
 | 
						|
    unsigned char   *repeats;
 | 
						|
 | 
						|
    repeats = defaultKeyboardControl.autoRepeats;
 | 
						|
    memset (repeats, '\0', 32);
 | 
						|
    for (key_code = KD_MIN_KEYCODE; key_code <= KD_MAX_KEYCODE; key_code++)
 | 
						|
    {
 | 
						|
	if (!kdModMap[key_code])
 | 
						|
	{
 | 
						|
	    i = key_code >> 3;
 | 
						|
	    mask = 1 << (key_code & 7);
 | 
						|
	    repeats[i] |= mask;
 | 
						|
	}
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
const KdKeySymModsRec kdKeySymMods[] = {
 | 
						|
  {  XK_Control_L,	ControlMask },
 | 
						|
  {  XK_Control_R, ControlMask },
 | 
						|
  {  XK_Shift_L,	ShiftMask },
 | 
						|
  {  XK_Shift_R,	ShiftMask },
 | 
						|
  {  XK_Caps_Lock,	LockMask },
 | 
						|
  {  XK_Shift_Lock, LockMask },
 | 
						|
  {  XK_Alt_L,	Mod1Mask },
 | 
						|
  {  XK_Alt_R,	Mod1Mask },
 | 
						|
  {  XK_Meta_L,	Mod1Mask },
 | 
						|
  {  XK_Meta_R,	Mod1Mask },
 | 
						|
  {  XK_Num_Lock,	Mod2Mask },
 | 
						|
  {  XK_Super_L,	Mod3Mask },
 | 
						|
  {  XK_Super_R,	Mod3Mask },
 | 
						|
  {  XK_Hyper_L,	Mod3Mask },
 | 
						|
  {  XK_Hyper_R,	Mod3Mask },
 | 
						|
  {  XK_Mode_switch, Mod4Mask },
 | 
						|
#ifdef TOUCHSCREEN
 | 
						|
  /* PDA specific hacks */
 | 
						|
#ifdef XF86XK_Start
 | 
						|
  {  XF86XK_Start, ControlMask },
 | 
						|
#endif
 | 
						|
  {  XK_Menu, ShiftMask },
 | 
						|
  {  XK_telephone, Mod1Mask },
 | 
						|
#ifdef XF86XK_AudioRecord
 | 
						|
  {  XF86XK_AudioRecord, Mod2Mask },
 | 
						|
#endif
 | 
						|
#ifdef XF86XK_Calendar
 | 
						|
  {  XF86XK_Calendar, Mod3Mask }
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
};
 | 
						|
 | 
						|
#define NUM_SYM_MODS (sizeof(kdKeySymMods) / sizeof(kdKeySymMods[0]))
 | 
						|
 | 
						|
static void
 | 
						|
KdInitModMap (void)
 | 
						|
{
 | 
						|
    int	    key_code;
 | 
						|
    int	    row;
 | 
						|
    int	    width;
 | 
						|
    KeySym  *syms;
 | 
						|
    int	    i;
 | 
						|
 | 
						|
    width = kdKeySyms.mapWidth;
 | 
						|
    for (key_code = kdMinKeyCode; key_code <= kdMaxKeyCode; key_code++)
 | 
						|
    {
 | 
						|
	kdModMap[key_code] = 0;
 | 
						|
	syms = kdKeymap + (key_code - kdMinKeyCode) * width;
 | 
						|
	for (row = 0; row < width; row++, syms++)
 | 
						|
	{
 | 
						|
	    for (i = 0; i < NUM_SYM_MODS; i++)
 | 
						|
	    {
 | 
						|
		if (*syms == kdKeySymMods[i].modsym)
 | 
						|
		    kdModMap[key_code] |= kdKeySymMods[i].modbit;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
KdAddMouseDriver(KdMouseFuncs *pMouseFuncs)
 | 
						|
{
 | 
						|
    if (kdNMouseFuncs < MAX_MOUSE_DRIVERS)
 | 
						|
	kdMouseFuncs[kdNMouseFuncs++] = pMouseFuncs;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
eglInitInput(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;
 | 
						|
    }
 | 
						|
 | 
						|
    kdNMouseFuncs = 0;
 | 
						|
    KdAddMouseDriver (pMouseFuncs);
 | 
						|
    kdKeyboardFuncs = pKeyboardFuncs;
 | 
						|
    memset (kdKeyState, '\0', sizeof (kdKeyState));
 | 
						|
    if (kdKeyboardFuncs)
 | 
						|
	(*kdKeyboardFuncs->Load) ();
 | 
						|
    kdMinKeyCode = kdMinScanCode + KD_KEY_OFFSET;
 | 
						|
    kdMaxKeyCode = kdMaxScanCode + KD_KEY_OFFSET;
 | 
						|
    kdKeySyms.map = kdKeymap;
 | 
						|
    kdKeySyms.minKeyCode = kdMinKeyCode;
 | 
						|
    kdKeySyms.maxKeyCode = kdMaxKeyCode;
 | 
						|
    kdKeySyms.mapWidth = kdKeymapWidth;
 | 
						|
    kdLeds = 0;
 | 
						|
    kdBellPitch = 1000;
 | 
						|
    kdBellDuration = 200;
 | 
						|
    kdInputEnabled = TRUE;
 | 
						|
    KdInitModMap ();
 | 
						|
    KdInitAutoRepeats ();
 | 
						|
    KdResetInputMachine ();
 | 
						|
    pPointer  = AddInputDevice(KdMouseProc, TRUE);
 | 
						|
    pKeyboard = AddInputDevice(KdKeybdProc, TRUE);
 | 
						|
    RegisterPointerDevice(pPointer);
 | 
						|
    RegisterKeyboardDevice(pKeyboard);
 | 
						|
    miRegisterPointerDevice(screenInfo.screens[0], pPointer);
 | 
						|
    mieqInit(&pKeyboard->public, &pPointer->public);
 | 
						|
#ifdef XINPUT
 | 
						|
    {
 | 
						|
	static long zero1, zero2;
 | 
						|
 | 
						|
	//SetExtInputCheck (&zero1, &zero2);
 | 
						|
	ErrorF("Extended Input Devices not yet supported. Impelement it at line %d in %s\n",
 | 
						|
	       __LINE__, __FILE__);
 | 
						|
    }
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Middle button emulation state machine
 | 
						|
 *
 | 
						|
 *  Possible transitions:
 | 
						|
 *	Button 1 press	    v1
 | 
						|
 *	Button 1 release    ^1
 | 
						|
 *	Button 2 press	    v2
 | 
						|
 *	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		    ...
 | 
						|
 *	outside box	    <->
 | 
						|
 *
 | 
						|
 *  States:
 | 
						|
 *	start
 | 
						|
 *	button_1_pend
 | 
						|
 *	button_1_down
 | 
						|
 *	button_2_down
 | 
						|
 *	button_3_pend
 | 
						|
 *	button_3_down
 | 
						|
 *	synthetic_2_down_13
 | 
						|
 *	synthetic_2_down_3
 | 
						|
 *	synthetic_2_down_1
 | 
						|
 *
 | 
						|
 *  Transition diagram
 | 
						|
 *
 | 
						|
 *  start
 | 
						|
 *	v1  -> (hold) (settimeout) button_1_pend
 | 
						|
 *	^1  -> (deliver) start
 | 
						|
 *	v2  -> (deliver) button_2_down
 | 
						|
 *	^2  -> (deliever) start
 | 
						|
 *	v3  -> (hold) (settimeout) button_3_pend
 | 
						|
 *	^3  -> (deliver) start
 | 
						|
 *	vo  -> (deliver) start
 | 
						|
 *	^o  -> (deliver) start
 | 
						|
 *	<>  -> (deliver) start
 | 
						|
 *	k   -> (deliver) start
 | 
						|
 *
 | 
						|
 *  button_1_pend	(button 1 is down, timeout pending)
 | 
						|
 *	^1  -> (release) (deliver) start
 | 
						|
 *	v2  -> (release) (deliver) button_1_down
 | 
						|
 *	^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
 | 
						|
 *	... -> (release) button_1_down
 | 
						|
 *
 | 
						|
 *  button_1_down	(button 1 is down)
 | 
						|
 *	^1  -> (deliver) start
 | 
						|
 *	v2  -> (deliver) button_1_down
 | 
						|
 *	^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
 | 
						|
 *
 | 
						|
 *  button_2_down	(button 2 is down)
 | 
						|
 *	v1  -> (deliver) button_2_down
 | 
						|
 *	^1  -> (deliver) button_2_down
 | 
						|
 *	^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
 | 
						|
 *
 | 
						|
 *  button_3_pend	(button 3 is down, timeout pending)
 | 
						|
 *	v1  -> (generate v2) synthetic_2_down
 | 
						|
 *	^1  -> (release) (deliver) button_3_down
 | 
						|
 *	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
 | 
						|
 *	... -> (release) button_3_down
 | 
						|
 *
 | 
						|
 *  button_3_down	(button 3 is down)
 | 
						|
 *	v1  -> (deliver) button_3_down
 | 
						|
 *	^1  -> (deliver) button_3_down
 | 
						|
 *	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
 | 
						|
 *
 | 
						|
 *  synthetic_2_down_13	(button 1 and 3 are down)
 | 
						|
 *	^1  -> (generate ^2) synthetic_2_down_3
 | 
						|
 *	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
 | 
						|
 *
 | 
						|
 *  synthetic_2_down_3 (button 3 is down)
 | 
						|
 *	v1  -> (deliver) synthetic_2_down_3
 | 
						|
 *	^1  -> (deliver) synthetic_2_down_3
 | 
						|
 *	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
 | 
						|
 *
 | 
						|
 *  synthetic_2_down_1 (button 1 is down)
 | 
						|
 *	^1  -> start
 | 
						|
 *	v2  -> synthetic_2_down_1
 | 
						|
 *	^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 _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
 | 
						|
} KdInputClass;
 | 
						|
 | 
						|
typedef enum _inputAction {
 | 
						|
    noop,
 | 
						|
    hold,
 | 
						|
    setto,
 | 
						|
    deliver,
 | 
						|
    release,
 | 
						|
    clearto,
 | 
						|
    gen_down_2,
 | 
						|
    gen_up_2
 | 
						|
} KdInputAction;
 | 
						|
 | 
						|
#define MAX_ACTIONS 2
 | 
						|
 | 
						|
typedef struct _inputTransition {
 | 
						|
    KdInputAction  actions[MAX_ACTIONS];
 | 
						|
    KdMouseState   nextState;
 | 
						|
} KdInputTransition;
 | 
						|
 | 
						|
KdInputTransition  kdInputMachine[num_input_states][num_input_class] = {
 | 
						|
    /* start */
 | 
						|
    {
 | 
						|
	{ { hold, setto },	    button_1_pend },	/* v1 */
 | 
						|
	{ { deliver, noop },	    start },		/* ^1 */
 | 
						|
	{ { deliver, noop },	    button_2_down },	/* v2 */
 | 
						|
	{ { 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 },		/* <-> */
 | 
						|
	{ { noop, noop },	    start },		/* k */
 | 
						|
	{ { noop, noop },	    start },		/* ... */
 | 
						|
    },
 | 
						|
    /* button_1_pend */
 | 
						|
    {
 | 
						|
	{ { noop, noop },	    button_1_pend },	/* v1 */
 | 
						|
	{ { release, deliver },	    start },		/* ^1 */
 | 
						|
	{ { release, deliver },	    button_1_down },	/* v2 */
 | 
						|
	{ { 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 },	/* <-> */
 | 
						|
	{ { noop, noop },	    button_1_down },	/* k */
 | 
						|
	{ { release, noop },	    button_1_down },	/* ... */
 | 
						|
    },
 | 
						|
    /* button_1_down */
 | 
						|
    {
 | 
						|
	{ { noop, noop },	    button_1_down },	/* v1 */
 | 
						|
	{ { deliver, noop },	    start },		/* ^1 */
 | 
						|
	{ { deliver, noop },	    button_1_down },	/* v2 */
 | 
						|
	{ { 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 },	/* <-> */
 | 
						|
	{ { noop, noop },	    button_1_down },	/* k */
 | 
						|
	{ { noop, noop },	    button_1_down },	/* ... */
 | 
						|
    },
 | 
						|
    /* button_2_down */
 | 
						|
    {
 | 
						|
	{ { deliver, noop },	    button_2_down },	/* v1 */
 | 
						|
	{ { deliver, noop },	    button_2_down },	/* ^1 */
 | 
						|
	{ { noop, noop },	    button_2_down },	/* v2 */
 | 
						|
	{ { 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 },	/* <-> */
 | 
						|
	{ { noop, noop },	    button_2_down },	/* k */
 | 
						|
	{ { noop, noop },	    button_2_down },	/* ... */
 | 
						|
    },
 | 
						|
    /* button_3_pend */
 | 
						|
    {
 | 
						|
	{ { clearto, gen_down_2 },  synth_2_down_13 },	/* v1 */
 | 
						|
	{ { release, deliver },	    button_3_down },	/* ^1 */
 | 
						|
	{ { release, deliver },	    button_3_down },	/* v2 */
 | 
						|
	{ { 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, noop },	    button_3_down },	/* k */
 | 
						|
	{ { release, noop },	    button_3_down },	/* ... */
 | 
						|
    },
 | 
						|
    /* button_3_down */
 | 
						|
    {
 | 
						|
	{ { deliver, noop },	    button_3_down },	/* v1 */
 | 
						|
	{ { deliver, noop },	    button_3_down },	/* ^1 */
 | 
						|
	{ { deliver, noop },	    button_3_down },	/* v2 */
 | 
						|
	{ { 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 },	/* <-> */
 | 
						|
	{ { noop, noop },	    button_3_down },	/* k */
 | 
						|
	{ { noop, noop },	    button_3_down },	/* ... */
 | 
						|
    },
 | 
						|
    /* synthetic_2_down_13 */
 | 
						|
    {
 | 
						|
	{ { noop, noop },	    synth_2_down_13 },	/* v1 */
 | 
						|
	{ { gen_up_2, noop },	    synth_2_down_3 },	/* ^1 */
 | 
						|
	{ { noop, noop },	    synth_2_down_13 },	/* v2 */
 | 
						|
	{ { 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 },	/* <-> */
 | 
						|
	{ { noop, noop },	    synth_2_down_13 },	/* k */
 | 
						|
	{ { noop, noop },	    synth_2_down_13 },	/* ... */
 | 
						|
    },
 | 
						|
    /* synthetic_2_down_3 */
 | 
						|
    {
 | 
						|
	{ { deliver, noop },	    synth_2_down_3 },	/* v1 */
 | 
						|
	{ { deliver, noop },	    synth_2_down_3 },	/* ^1 */
 | 
						|
	{ { deliver, noop },	    synth_2_down_3 },	/* v2 */
 | 
						|
	{ { 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 },	/* <-> */
 | 
						|
	{ { noop, noop },	    synth_2_down_3 },	/* k */
 | 
						|
	{ { noop, noop },	    synth_2_down_3 },	/* ... */
 | 
						|
    },
 | 
						|
    /* synthetic_2_down_1 */
 | 
						|
    {
 | 
						|
	{ { noop, noop },	    synth_2_down_1 },	/* v1 */
 | 
						|
	{ { noop, noop },	    start },		/* ^1 */
 | 
						|
	{ { deliver, noop },	    synth_2_down_1 },	/* v2 */
 | 
						|
	{ { 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 },	/* <-> */
 | 
						|
	{ { noop, noop },	    synth_2_down_1 },	/* k */
 | 
						|
	{ { noop, noop },	    synth_2_down_1 },	/* ... */
 | 
						|
    },
 | 
						|
};
 | 
						|
 | 
						|
#define EMULATION_WINDOW    10
 | 
						|
#define EMULATION_TIMEOUT   100
 | 
						|
 | 
						|
#define EventX(e)   ((e)->u.keyButtonPointer.rootX)
 | 
						|
#define EventY(e)   ((e)->u.keyButtonPointer.rootY)
 | 
						|
 | 
						|
static int
 | 
						|
KdInsideEmulationWindow (KdMouseInfo *mi, xEvent *ev)
 | 
						|
{
 | 
						|
    if (ev->u.keyButtonPointer.pad1)
 | 
						|
    {
 | 
						|
	mi->emulationDx += EventX(ev);
 | 
						|
	mi->emulationDy += EventY(ev);
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
	mi->emulationDx = EventX(&mi->heldEvent) - EventX(ev);
 | 
						|
	mi->emulationDy = EventY(&mi->heldEvent) - EventY(ev);
 | 
						|
    }
 | 
						|
    return (abs (mi->emulationDx) < EMULATION_WINDOW &&
 | 
						|
	    abs (mi->emulationDy) < EMULATION_WINDOW);
 | 
						|
}
 | 
						|
 | 
						|
static KdInputClass
 | 
						|
KdClassifyInput (KdMouseInfo *mi, xEvent *ev)
 | 
						|
{
 | 
						|
    switch (ev->u.u.type) {
 | 
						|
    case ButtonPress:
 | 
						|
	switch (ev->u.u.detail) {
 | 
						|
	case 1: return down_1;
 | 
						|
	case 2: return down_2;
 | 
						|
	case 3: return down_3;
 | 
						|
	default: return down_o;
 | 
						|
	}
 | 
						|
	break;
 | 
						|
    case ButtonRelease:
 | 
						|
	switch (ev->u.u.detail) {
 | 
						|
	case 1: return up_1;
 | 
						|
	case 2: return up_2;
 | 
						|
	case 3: return up_3;
 | 
						|
	default: return up_o;
 | 
						|
	}
 | 
						|
	break;
 | 
						|
    case MotionNotify:
 | 
						|
	if (mi->eventHeld && !KdInsideEmulationWindow(mi, ev))
 | 
						|
	    return outside_box;
 | 
						|
	else
 | 
						|
	    return motion;
 | 
						|
    default:
 | 
						|
	return keyboard;
 | 
						|
    }
 | 
						|
    return keyboard;
 | 
						|
}
 | 
						|
 | 
						|
#ifndef NDEBUG
 | 
						|
char	*kdStateNames[] = {
 | 
						|
    "start",
 | 
						|
    "button_1_pend",
 | 
						|
    "button_1_down",
 | 
						|
    "button_2_down",
 | 
						|
    "button_3_pend",
 | 
						|
    "button_3_down",
 | 
						|
    "synth_2_down_13",
 | 
						|
    "synth_2_down_3",
 | 
						|
    "synthetic_2_down_1",
 | 
						|
    "num_input_states"
 | 
						|
};
 | 
						|
 | 
						|
char	*kdClassNames[] = {
 | 
						|
    "down_1", "up_1",
 | 
						|
    "down_2", "up_2",
 | 
						|
    "down_3", "up_3",
 | 
						|
    "motion", "ouside_box",
 | 
						|
    "keyboard", "timeout",
 | 
						|
    "num_input_class"
 | 
						|
};
 | 
						|
 | 
						|
char *kdActionNames[] = {
 | 
						|
    "noop",
 | 
						|
    "hold",
 | 
						|
    "setto",
 | 
						|
    "deliver",
 | 
						|
    "release",
 | 
						|
    "clearto",
 | 
						|
    "gen_down_2",
 | 
						|
    "gen_up_2",
 | 
						|
};
 | 
						|
#endif
 | 
						|
 | 
						|
static void
 | 
						|
KdQueueEvent (xEvent *ev)
 | 
						|
{
 | 
						|
    KdAssertSigioBlocked ("KdQueueEvent");
 | 
						|
    if (ev->u.u.type == MotionNotify)
 | 
						|
    {
 | 
						|
	if (ev->u.keyButtonPointer.pad1)
 | 
						|
	{
 | 
						|
	    ev->u.keyButtonPointer.pad1 = 0;
 | 
						|
	    miPointerDeltaCursor (ev->u.keyButtonPointer.rootX,
 | 
						|
				  ev->u.keyButtonPointer.rootY,
 | 
						|
				  ev->u.keyButtonPointer.time);
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
	    miPointerAbsoluteCursor(ev->u.keyButtonPointer.rootX,
 | 
						|
				    ev->u.keyButtonPointer.rootY,
 | 
						|
				    ev->u.keyButtonPointer.time);
 | 
						|
	}
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
	mieqEnqueue (ev);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
KdRunMouseMachine (KdMouseInfo *mi, KdInputClass c, xEvent *ev)
 | 
						|
{
 | 
						|
    KdInputTransition	*t;
 | 
						|
    int			a;
 | 
						|
 | 
						|
    t = &kdInputMachine[mi->mouseState][c];
 | 
						|
    for (a = 0; a < MAX_ACTIONS; a++)
 | 
						|
    {
 | 
						|
	switch (t->actions[a]) {
 | 
						|
	case noop:
 | 
						|
	    break;
 | 
						|
	case hold:
 | 
						|
	    mi->eventHeld = TRUE;
 | 
						|
	    mi->emulationDx = 0;
 | 
						|
	    mi->emulationDy = 0;
 | 
						|
	    mi->heldEvent = *ev;
 | 
						|
	    break;
 | 
						|
	case setto:
 | 
						|
	    mi->emulationTimeout = GetTimeInMillis () + EMULATION_TIMEOUT;
 | 
						|
	    mi->timeoutPending = TRUE;
 | 
						|
	    break;
 | 
						|
	case deliver:
 | 
						|
	    KdQueueEvent (ev);
 | 
						|
	    break;
 | 
						|
	case release:
 | 
						|
	    mi->eventHeld = FALSE;
 | 
						|
	    mi->timeoutPending = FALSE;
 | 
						|
	    KdQueueEvent (&mi->heldEvent);
 | 
						|
	    break;
 | 
						|
	case clearto:
 | 
						|
	    mi->timeoutPending = FALSE;
 | 
						|
	    break;
 | 
						|
	case gen_down_2:
 | 
						|
	    ev->u.u.detail = 2;
 | 
						|
	    mi->eventHeld = FALSE;
 | 
						|
	    KdQueueEvent (ev);
 | 
						|
	    break;
 | 
						|
	case gen_up_2:
 | 
						|
	    ev->u.u.detail = 2;
 | 
						|
	    KdQueueEvent (ev);
 | 
						|
	    break;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    mi->mouseState = t->nextState;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
KdResetInputMachine (void)
 | 
						|
{
 | 
						|
    KdMouseInfo	*mi;
 | 
						|
 | 
						|
    for (mi = kdMouseInfo; mi; mi = mi->next)
 | 
						|
    {
 | 
						|
	mi->mouseState = start;
 | 
						|
	mi->eventHeld = FALSE;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
KdHandleMouseEvent (KdMouseInfo *mi, xEvent *ev)
 | 
						|
{
 | 
						|
    if (mi->emulateMiddleButton)
 | 
						|
	KdRunMouseMachine (mi, KdClassifyInput (mi, ev), ev);
 | 
						|
    else
 | 
						|
	KdQueueEvent (ev);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
KdReceiveTimeout (KdMouseInfo *mi)
 | 
						|
{
 | 
						|
    KdRunMouseMachine (mi, timeout, 0);
 | 
						|
}
 | 
						|
 | 
						|
#define KILL_SEQUENCE ((1L << KK_CONTROL)|(1L << KK_ALT)|(1L << KK_F8)|(1L << KK_F10))
 | 
						|
#define SPECIAL_SEQUENCE ((1L << KK_CONTROL) | (1L << KK_ALT))
 | 
						|
#define SETKILLKEY(b) (KdSpecialKeys |= (1L << (b)))
 | 
						|
#define CLEARKILLKEY(b) (KdSpecialKeys &= ~(1L << (b)))
 | 
						|
#define KEYMAP	    (pKdKeyboard->key->curKeySyms)
 | 
						|
#define KEYCOL1(k) (KEYMAP.map[((k)-kdMinKeyCode)*KEYMAP.mapWidth])
 | 
						|
 | 
						|
CARD32	KdSpecialKeys = 0;
 | 
						|
 | 
						|
extern char dispatchException;
 | 
						|
 | 
						|
/*
 | 
						|
 * kdCheckTermination
 | 
						|
 *
 | 
						|
 * This function checks for the key sequence that terminates the server.  When
 | 
						|
 * detected, it sets the dispatchException flag and returns.  The key sequence
 | 
						|
 * is:
 | 
						|
 *	Control-Alt
 | 
						|
 * It's assumed that the server will be waken up by the caller when this
 | 
						|
 * function returns.
 | 
						|
 */
 | 
						|
 | 
						|
extern int nClients;
 | 
						|
 | 
						|
static void
 | 
						|
KdCheckSpecialKeys(xEvent *xE)
 | 
						|
{
 | 
						|
    KeySym	sym = KEYCOL1(xE->u.u.detail);
 | 
						|
 | 
						|
    if (!pKdKeyboard) return;
 | 
						|
 | 
						|
    /*
 | 
						|
     * Ignore key releases
 | 
						|
     */
 | 
						|
 | 
						|
    if (xE->u.u.type == KeyRelease) return;
 | 
						|
 | 
						|
#ifdef XIPAQ
 | 
						|
    /*
 | 
						|
     * Check for buttons 1, 2 and 3 on the iPAQ
 | 
						|
     */
 | 
						|
    if (sym == XK_Pointer_Button1 && kdMouseInfo) {
 | 
						|
	KdEnqueueMouseEvent(kdMouseInfo, KD_MOUSE_DELTA | KD_BUTTON_1, 0, 0);
 | 
						|
	return;
 | 
						|
    }
 | 
						|
    if (sym == XK_Pointer_Button2 && kdMouseInfo) {
 | 
						|
	KdEnqueueMouseEvent(kdMouseInfo, KD_MOUSE_DELTA | KD_BUTTON_2, 0, 0);
 | 
						|
	return;
 | 
						|
    }
 | 
						|
    if (sym == XK_Pointer_Button3 && kdMouseInfo) {
 | 
						|
	KdEnqueueMouseEvent(kdMouseInfo, KD_MOUSE_DELTA | KD_BUTTON_3, 0, 0);
 | 
						|
	return;
 | 
						|
    }
 | 
						|
#endif
 | 
						|
 | 
						|
    /*
 | 
						|
     * Check for control/alt pressed
 | 
						|
     */
 | 
						|
    if ((pKdKeyboard->key->state & (ControlMask|Mod1Mask)) !=
 | 
						|
	(ControlMask|Mod1Mask))
 | 
						|
	return;
 | 
						|
 | 
						|
 | 
						|
    /*
 | 
						|
     * Let OS function see keysym first
 | 
						|
     */
 | 
						|
 | 
						|
    if (kdOsFuncs->SpecialKey)
 | 
						|
	if ((*kdOsFuncs->SpecialKey) (sym))
 | 
						|
	    return;
 | 
						|
 | 
						|
    /*
 | 
						|
     * Now check for backspace or delete; these signal the
 | 
						|
     * X server to terminate
 | 
						|
     */
 | 
						|
    switch (sym) {
 | 
						|
    case XK_BackSpace:
 | 
						|
    case XK_Delete:
 | 
						|
    case XK_KP_Delete:
 | 
						|
	/*
 | 
						|
	 * Set the dispatch exception flag so the server will terminate the
 | 
						|
	 * next time through the dispatch loop.
 | 
						|
	 */
 | 
						|
	if (kdDontZap == FALSE)
 | 
						|
	    dispatchException |= DE_TERMINATE;
 | 
						|
	break;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * kdEnqueueKeyboardEvent
 | 
						|
 *
 | 
						|
 * This function converts hardware keyboard event information into an X event
 | 
						|
 * and enqueues it using MI.  It wakes up the server before returning so that
 | 
						|
 * the event will be processed normally.
 | 
						|
 *
 | 
						|
 */
 | 
						|
 | 
						|
static void
 | 
						|
KdHandleKeyboardEvent (xEvent *ev)
 | 
						|
{
 | 
						|
    int		key = ev->u.u.detail;
 | 
						|
    int		byte;
 | 
						|
    CARD8	bit;
 | 
						|
    KdMouseInfo	*mi;
 | 
						|
 | 
						|
    byte = key >> 3;
 | 
						|
    bit = 1 << (key & 7);
 | 
						|
    switch (ev->u.u.type) {
 | 
						|
    case KeyPress:
 | 
						|
	kdKeyState[byte] |= bit;
 | 
						|
	break;
 | 
						|
    case KeyRelease:
 | 
						|
	kdKeyState[byte] &= ~bit;
 | 
						|
	break;
 | 
						|
    }
 | 
						|
    for (mi = kdMouseInfo; mi; mi = mi->next)
 | 
						|
	KdRunMouseMachine (mi, keyboard, 0);
 | 
						|
    KdQueueEvent (ev);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
KdReleaseAllKeys (void)
 | 
						|
{
 | 
						|
    xEvent  xE;
 | 
						|
    int	    key;
 | 
						|
 | 
						|
    KdBlockSigio ();
 | 
						|
    for (key = 0; key < KD_KEY_COUNT; key++)
 | 
						|
	if (IsKeyDown(key))
 | 
						|
	{
 | 
						|
	    xE.u.keyButtonPointer.time = GetTimeInMillis();
 | 
						|
	    xE.u.u.type = KeyRelease;
 | 
						|
	    xE.u.u.detail = key;
 | 
						|
	    KdHandleKeyboardEvent (&xE);
 | 
						|
	}
 | 
						|
    KdUnblockSigio ();
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
KdCheckLock (void)
 | 
						|
{
 | 
						|
    KeyClassPtr	    keyc = pKdKeyboard->key;
 | 
						|
    Bool	    isSet, shouldBeSet;
 | 
						|
 | 
						|
    if (kdKeyboardFuncs->LockLed)
 | 
						|
    {
 | 
						|
	isSet = (kdLeds & (1 << (kdKeyboardFuncs->LockLed-1))) != 0;
 | 
						|
	shouldBeSet = (keyc->state & LockMask) != 0;
 | 
						|
	if (isSet != shouldBeSet)
 | 
						|
	{
 | 
						|
	    KdSetLed (kdKeyboardFuncs->LockLed, shouldBeSet);
 | 
						|
	}
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
KdEnqueueKeyboardEvent(unsigned char	scan_code,
 | 
						|
		       unsigned char	is_up)
 | 
						|
{
 | 
						|
    unsigned char   key_code;
 | 
						|
    xEvent	    xE;
 | 
						|
    KeyClassPtr	    keyc;
 | 
						|
 | 
						|
    if (!pKdKeyboard)
 | 
						|
	return;
 | 
						|
    keyc = pKdKeyboard->key;
 | 
						|
 | 
						|
    xE.u.keyButtonPointer.time = GetTimeInMillis();
 | 
						|
 | 
						|
    if (kdMinScanCode <= scan_code && scan_code <= kdMaxScanCode)
 | 
						|
    {
 | 
						|
	key_code = scan_code + KD_MIN_KEYCODE - kdMinScanCode;
 | 
						|
 | 
						|
	/*
 | 
						|
	 * Set up this event -- the type may be modified below
 | 
						|
	 */
 | 
						|
	if (is_up)
 | 
						|
	    xE.u.u.type = KeyRelease;
 | 
						|
	else
 | 
						|
	    xE.u.u.type = KeyPress;
 | 
						|
	xE.u.u.detail = key_code;
 | 
						|
 | 
						|
	switch (KEYCOL1(key_code))
 | 
						|
	{
 | 
						|
	case XK_Num_Lock:
 | 
						|
	case XK_Scroll_Lock:
 | 
						|
	case XK_Shift_Lock:
 | 
						|
	case XK_Caps_Lock:
 | 
						|
	    if (xE.u.u.type == KeyRelease)
 | 
						|
		return;
 | 
						|
	    if (IsKeyDown (key_code))
 | 
						|
		xE.u.u.type = KeyRelease;
 | 
						|
	    else
 | 
						|
		xE.u.u.type = KeyPress;
 | 
						|
	}
 | 
						|
 | 
						|
	/*
 | 
						|
	 * Check pressed keys which are already down
 | 
						|
	 */
 | 
						|
	if (IsKeyDown (key_code) && xE.u.u.type == KeyPress)
 | 
						|
	{
 | 
						|
	    KeybdCtrl	*ctrl = &pKdKeyboard->kbdfeed->ctrl;
 | 
						|
 | 
						|
	    /*
 | 
						|
	     * Check auto repeat
 | 
						|
	     */
 | 
						|
	    if (!ctrl->autoRepeat || keyc->modifierMap[key_code] ||
 | 
						|
		!(ctrl->autoRepeats[key_code >> 3] & (1 << (key_code & 7))))
 | 
						|
	    {
 | 
						|
		return;
 | 
						|
	    }
 | 
						|
	    /*
 | 
						|
	     * X delivers press/release even for autorepeat
 | 
						|
	     */
 | 
						|
	    xE.u.u.type = KeyRelease;
 | 
						|
	    KdHandleKeyboardEvent (&xE);
 | 
						|
	    xE.u.u.type = KeyPress;
 | 
						|
	}
 | 
						|
	/*
 | 
						|
	 * Check released keys which are already up
 | 
						|
	 */
 | 
						|
	else if (!IsKeyDown (key_code) && xE.u.u.type == KeyRelease)
 | 
						|
	{
 | 
						|
	    return;
 | 
						|
	}
 | 
						|
	KdCheckSpecialKeys (&xE);
 | 
						|
	KdHandleKeyboardEvent (&xE);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
#define SetButton(mi, b, v, s) \
 | 
						|
{\
 | 
						|
    xE.u.u.detail = mi->map[b]; \
 | 
						|
    xE.u.u.type = v; \
 | 
						|
    KdHandleMouseEvent (mi, &xE); \
 | 
						|
}
 | 
						|
 | 
						|
#define Press(mi, b)         SetButton(mi, b, ButtonPress, "Down")
 | 
						|
#define Release(mi, b)       SetButton(mi, b, ButtonRelease, "Up")
 | 
						|
 | 
						|
/*
 | 
						|
 * kdEnqueueMouseEvent
 | 
						|
 *
 | 
						|
 * This function converts hardware mouse event information into X event
 | 
						|
 * information.  A mouse movement event is passed off to MI to generate
 | 
						|
 * a MotionNotify event, if appropriate.  Button events are created and
 | 
						|
 * passed off to MI for enqueueing.
 | 
						|
 */
 | 
						|
 | 
						|
static void
 | 
						|
KdMouseAccelerate (DeviceIntPtr	device, int *dx, int *dy)
 | 
						|
{
 | 
						|
    PtrCtrl *pCtrl = &device->ptrfeed->ctrl;
 | 
						|
    double  speed = sqrt (*dx * *dx + *dy * *dy);
 | 
						|
    double  accel;
 | 
						|
    double  m;
 | 
						|
 | 
						|
    /*
 | 
						|
     * Ok, so we want it moving num/den times faster at threshold*2
 | 
						|
     *
 | 
						|
     * accel = m *threshold + b
 | 
						|
     * 1 = m * 0 + b	-> b = 1
 | 
						|
     *
 | 
						|
     * num/den = m * (threshold * 2) + 1
 | 
						|
     *
 | 
						|
     * num / den - 1 = m * threshold * 2
 | 
						|
     * (num / den - 1) / threshold * 2 = m
 | 
						|
     */
 | 
						|
    m = (((double) pCtrl->num / (double) pCtrl->den - 1.0) /
 | 
						|
	 ((double) pCtrl->threshold * 2.0));
 | 
						|
    accel = m * speed + 1;
 | 
						|
    *dx = accel * *dx;
 | 
						|
    *dy = accel * *dy;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
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;
 | 
						|
    unsigned long   button;
 | 
						|
    int		    n;
 | 
						|
 | 
						|
    if (!pKdPointer)
 | 
						|
	return;
 | 
						|
 | 
						|
    ms = GetTimeInMillis();
 | 
						|
 | 
						|
    if (flags & KD_MOUSE_DELTA)
 | 
						|
    {
 | 
						|
	if (mi->transformCoordinates)
 | 
						|
	{
 | 
						|
	    x = matrix[0][0] * rx + matrix[0][1] * ry;
 | 
						|
	    y = matrix[1][0] * rx + matrix[1][1] * ry;
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
	    x = rx;
 | 
						|
	    y = ry;
 | 
						|
	}
 | 
						|
	KdMouseAccelerate (pKdPointer, &x, &y);
 | 
						|
	xE.u.keyButtonPointer.pad1 = 1;
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
	if (mi->transformCoordinates)
 | 
						|
	{
 | 
						|
	    x = matrix[0][0] * rx + matrix[0][1] * ry + matrix[0][2];
 | 
						|
	    y = matrix[1][0] * rx + matrix[1][1] * ry + matrix[1][2];
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
	    x = rx;
 | 
						|
	    y = ry;
 | 
						|
	}
 | 
						|
	xE.u.keyButtonPointer.pad1 = 0;
 | 
						|
    }
 | 
						|
    xE.u.keyButtonPointer.time = ms;
 | 
						|
    xE.u.keyButtonPointer.rootX = x;
 | 
						|
    xE.u.keyButtonPointer.rootY = y;
 | 
						|
 | 
						|
    xE.u.u.type = MotionNotify;
 | 
						|
    xE.u.u.detail = 0;
 | 
						|
    KdHandleMouseEvent (mi, &xE);
 | 
						|
 | 
						|
    buttons = flags;
 | 
						|
 | 
						|
    for (button = KD_BUTTON_1, n = 0; button <= KD_BUTTON_5; button <<= 1, n++)
 | 
						|
    {
 | 
						|
	if ((mi->buttonState & button) ^ (buttons & button))
 | 
						|
	{
 | 
						|
	    if (buttons & button)
 | 
						|
	    {
 | 
						|
		Press(mi, n);
 | 
						|
	    }
 | 
						|
	    else
 | 
						|
	    {
 | 
						|
		Release(mi, n);
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
    mi->buttonState = buttons;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
KdEnqueueMotionEvent (KdMouseInfo *mi, int x, int y)
 | 
						|
{
 | 
						|
    xEvent  xE;
 | 
						|
    CARD32  ms;
 | 
						|
 | 
						|
    ms = GetTimeInMillis();
 | 
						|
 | 
						|
    xE.u.u.type = MotionNotify;
 | 
						|
    xE.u.keyButtonPointer.time = ms;
 | 
						|
    xE.u.keyButtonPointer.rootX = x;
 | 
						|
    xE.u.keyButtonPointer.rootY = y;
 | 
						|
 | 
						|
    KdHandleMouseEvent (mi, &xE);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
KdBlockHandler (int		screen,
 | 
						|
		pointer		blockData,
 | 
						|
		pointer		timeout,
 | 
						|
		pointer		readmask)
 | 
						|
{
 | 
						|
    KdMouseInfo		    *mi;
 | 
						|
    int myTimeout=0;
 | 
						|
 | 
						|
    for (mi = kdMouseInfo; mi; mi = mi->next)
 | 
						|
    {
 | 
						|
	if (mi->timeoutPending)
 | 
						|
	{
 | 
						|
	    int	ms;
 | 
						|
 | 
						|
	    ms = mi->emulationTimeout - GetTimeInMillis ();
 | 
						|
	    if (ms < 1)
 | 
						|
		ms = 1;
 | 
						|
	    if(ms<myTimeout || myTimeout==0)
 | 
						|
		    myTimeout=ms;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    /* if we need to poll for events, do that */
 | 
						|
    if(kdOsFuncs->pollEvents)
 | 
						|
    {
 | 
						|
	    (*kdOsFuncs->pollEvents)();
 | 
						|
	    myTimeout=20;
 | 
						|
    }
 | 
						|
    if(myTimeout>0)
 | 
						|
    	AdjustWaitForDelay (timeout, myTimeout);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
KdWakeupHandler (pointer data,
 | 
						|
		 int	 result,
 | 
						|
		 pointer readmask)
 | 
						|
{
 | 
						|
    fd_set	*pReadmask = (fd_set *) readmask;
 | 
						|
    int		i;
 | 
						|
    KdMouseInfo	*mi;
 | 
						|
 | 
						|
    if (kdInputEnabled && result > 0)
 | 
						|
    {
 | 
						|
	for (i = 0; i < kdNumInputFds; i++)
 | 
						|
	    if (FD_ISSET (kdInputFds[i].fd, pReadmask))
 | 
						|
	    {
 | 
						|
		KdBlockSigio ();
 | 
						|
		(*kdInputFds[i].read) (kdInputFds[i].fd, kdInputFds[i].closure);
 | 
						|
		KdUnblockSigio ();
 | 
						|
	    }
 | 
						|
    }
 | 
						|
    for (mi = kdMouseInfo; mi; mi = mi->next)
 | 
						|
    {
 | 
						|
	if (mi->timeoutPending)
 | 
						|
	{
 | 
						|
	    if ((long) (GetTimeInMillis () - mi->emulationTimeout) >= 0)
 | 
						|
	    {
 | 
						|
		mi->timeoutPending = FALSE;
 | 
						|
		KdBlockSigio ();
 | 
						|
		KdReceiveTimeout (mi);
 | 
						|
		KdUnblockSigio ();
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
//  if (kdSwitchPending)
 | 
						|
//      kdProcessSwitch ();
 | 
						|
}
 | 
						|
 | 
						|
#define KdScreenOrigin(pScreen) (&(KdGetScreenPriv (pScreen)->origin))
 | 
						|
 | 
						|
static Bool
 | 
						|
KdCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
 | 
						|
{
 | 
						|
    ScreenPtr	pScreen  = *ppScreen;
 | 
						|
    ScreenPtr	pNewScreen;
 | 
						|
    int		n;
 | 
						|
    int		dx, dy;
 | 
						|
    int		best_x, best_y;
 | 
						|
    int		n_best_x, n_best_y;
 | 
						|
    CARD32	ms;
 | 
						|
 | 
						|
    if (kdDisableZaphod || screenInfo.numScreens <= 1)
 | 
						|
	return FALSE;
 | 
						|
 | 
						|
    if (0 <= *x && *x < pScreen->width && 0 <= *y && *y < pScreen->height)
 | 
						|
	return FALSE;
 | 
						|
 | 
						|
    ms = GetTimeInMillis ();
 | 
						|
    if (kdOffScreen && (int) (ms - kdOffScreenTime) < 1000)
 | 
						|
	return FALSE;
 | 
						|
    kdOffScreen = TRUE;
 | 
						|
    kdOffScreenTime = ms;
 | 
						|
    n_best_x = -1;
 | 
						|
    best_x = 32767;
 | 
						|
    n_best_y = -1;
 | 
						|
    best_y = 32767;
 | 
						|
    for (n = 0; n < screenInfo.numScreens; n++)
 | 
						|
    {
 | 
						|
	pNewScreen = screenInfo.screens[n];
 | 
						|
	if (pNewScreen == pScreen)
 | 
						|
	    continue;
 | 
						|
	dx = KdScreenOrigin(pNewScreen)->x - KdScreenOrigin(pScreen)->x;
 | 
						|
	dy = KdScreenOrigin(pNewScreen)->y - KdScreenOrigin(pScreen)->y;
 | 
						|
	if (*x < 0)
 | 
						|
	{
 | 
						|
	    if (dx <= 0 && -dx < best_x)
 | 
						|
	    {
 | 
						|
		best_x = -dx;
 | 
						|
		n_best_x = n;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
	else if (*x >= pScreen->width)
 | 
						|
	{
 | 
						|
	    if (dx >= 0 && dx < best_x)
 | 
						|
	    {
 | 
						|
		best_x = dx;
 | 
						|
		n_best_x = n;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
	if (*y < 0)
 | 
						|
	{
 | 
						|
	    if (dy <= 0 && -dy < best_y)
 | 
						|
	    {
 | 
						|
		best_y = -dy;
 | 
						|
		n_best_y = n;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
	else if (*y >= pScreen->height)
 | 
						|
	{
 | 
						|
	    if (dy >= 0 && dy < best_y)
 | 
						|
	    {
 | 
						|
		best_y = dy;
 | 
						|
		n_best_y = n;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
    if (best_y < best_x)
 | 
						|
	n_best_x = n_best_y;
 | 
						|
    if (n_best_x == -1)
 | 
						|
	return FALSE;
 | 
						|
    pNewScreen = screenInfo.screens[n_best_x];
 | 
						|
 | 
						|
    if (*x < 0)
 | 
						|
	*x += pNewScreen->width;
 | 
						|
    if (*y < 0)
 | 
						|
	*y += pNewScreen->height;
 | 
						|
 | 
						|
    if (*x >= pScreen->width)
 | 
						|
	*x -= pScreen->width;
 | 
						|
    if (*y >= pScreen->height)
 | 
						|
	*y -= pScreen->height;
 | 
						|
 | 
						|
    *ppScreen = pNewScreen;
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
KdCrossScreen(ScreenPtr pScreen, Bool entering)
 | 
						|
{
 | 
						|
#ifndef XIPAQ
 | 
						|
//  if (entering)
 | 
						|
//      KdEnableScreen (pScreen);
 | 
						|
//  else
 | 
						|
//      KdDisableScreen (pScreen);
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
int KdCurScreen;	/* current event screen */
 | 
						|
 | 
						|
static void
 | 
						|
KdWarpCursor (ScreenPtr pScreen, int x, int y)
 | 
						|
{
 | 
						|
    KdBlockSigio ();
 | 
						|
    KdCurScreen = pScreen->myNum;
 | 
						|
    miPointerWarpCursor (pScreen, x, y);
 | 
						|
    KdUnblockSigio ();
 | 
						|
}
 | 
						|
 | 
						|
miPointerScreenFuncRec kdPointerScreenFuncs =
 | 
						|
{
 | 
						|
    KdCursorOffScreen,
 | 
						|
    KdCrossScreen,
 | 
						|
    KdWarpCursor
 | 
						|
};
 | 
						|
 | 
						|
void
 | 
						|
KdProcessInputEvents (void)
 | 
						|
{
 | 
						|
    mieqProcessInputEvents();
 | 
						|
    miPointerUpdate();
 | 
						|
//  if (kdSwitchPending)
 | 
						|
//      KdProcessSwitch ();
 | 
						|
    KdCheckLock ();
 | 
						|
}
 |