diff options
Diffstat (limited to 'hw/xfree86/os-support/sysv/xqueue.c')
-rw-r--r-- | hw/xfree86/os-support/sysv/xqueue.c | 606 |
1 files changed, 369 insertions, 237 deletions
diff --git a/hw/xfree86/os-support/sysv/xqueue.c b/hw/xfree86/os-support/sysv/xqueue.c index 5e3c8e9fc..0478ee65e 100644 --- a/hw/xfree86/os-support/sysv/xqueue.c +++ b/hw/xfree86/os-support/sysv/xqueue.c @@ -1,38 +1,38 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sysv/xqueue.c,v 3.8.2.1 1997/07/13 14:45:04 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sysv/xqueue.c,v 3.20 2001/03/06 18:20:31 dawes Exp $ */ /* * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany + * Copyright 1993-1999 by 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 Thomas Roell not be used in + * documentation, and that the name of the copyright holders not be used in * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Thomas Roell makes no representations - * about the suitability of this software for any purpose. It is provided - * "as is" without express or implied warranty. + * specific, written prior permission. The copyright holders make no + * representations about the suitability of this software for any purpose. + * It is provided "as is" without express or implied warranty. * - * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * THE COPYRIGHT HOLDERS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * EVENT SHALL THE COPYRIGHT HOLDERS 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. * */ -/* $Xorg: xqueue.c,v 1.3 2000/08/17 19:51:33 cpqbld Exp $ */ +/* $XConsortium: xqueue.c /main/8 1996/10/19 18:08:11 kaleb $ */ -#define NEED_EVENTS #include "X.h" -#include "Xproto.h" -#include "inputstr.h" -#include "scrnintstr.h" #include "compiler.h" #include "xf86.h" -#include "xf86Procs.h" +#include "xf86Priv.h" #include "xf86_OSlib.h" +#include "xf86Xinput.h" +#include "xf86OSmouse.h" +#include "xqueue.h" #ifdef XQUEUE @@ -43,19 +43,23 @@ static int xquePipe[2]; #endif #ifdef XKB +#include "inputstr.h" #include <X11/extensions/XKB.h> #include <X11/extensions/XKBstr.h> #include <X11/extensions/XKBsrv.h> extern Bool noXkbExtension; #endif -#ifdef XINPUT -#include "xf86_Config.h" #include "xf86Xinput.h" -#endif -extern int miPointerGetMotionEvents(DeviceIntPtr pPtr, xTimecoord *coords, - unsigned long start, unsigned long stop, - ScreenPtr pScreen); +#include "mipointer.h" + +typedef struct { + int xquePending; + int xqueSema; +} XqInfoRec, *XqInfoPtr; + +InputInfoPtr XqMouse = NULL; +InputInfoPtr XqKeyboard = NULL; #ifndef XQUEUE_ASYNC /* @@ -67,7 +71,7 @@ extern int miPointerGetMotionEvents(DeviceIntPtr pPtr, xTimecoord *coords, static void xf86XqueSignal(int signum) { - xf86Info.mouseDev->xquePending = 1; + ((XqInfoPtr)(((MouseDevPtr)(XqMouse->private))->mousePriv))->xquePending = 1; /* * This is a hack, but it is the only reliable way I can find of letting * the main select() loop know that there is more input waiting. Receiving @@ -78,223 +82,14 @@ xf86XqueSignal(int signum) * Suggestions for better ways of dealing with this without going back to * asynchronous event processing are welcome. */ - write(xquePipe[1], "X", 1); - signal(SIGUSR2, xf86XqueSignal); -} -#endif - - -/* - * xf86XqueRequest -- - * Notice an i/o request from the xqueue. - */ - -void -xf86XqueRequest() -{ - xqEvent *XqueEvents = XqueQaddr->xq_events; - int XqueHead = XqueQaddr->xq_head; - char buf[100]; - - while (XqueHead != XqueQaddr->xq_tail) - { - - switch(XqueEvents[XqueHead].xq_type) { - - case XQ_BUTTON: - xf86PostMseEvent(xf86Info.pMouse, - ~(XqueEvents[XqueHead].xq_code) & 0x07, 0, 0); - break; - - case XQ_MOTION: - xf86PostMseEvent(xf86Info.pMouse, - ~(XqueEvents[XqueHead].xq_code) & 0x07, - XqueEvents[XqueHead].xq_x, - XqueEvents[XqueHead].xq_y); - break; - - case XQ_KEY: - xf86PostKbdEvent(XqueEvents[XqueHead].xq_code); - break; - - default: - ErrorF("Unknown Xque Event: 0x%02x\n", XqueEvents[XqueHead].xq_type); - } - - if ((++XqueHead) == XqueQaddr->xq_size) XqueHead = 0; - } - - /* reenable the signal-processing */ - xf86Info.inputPending = TRUE; -#ifdef XQUEUE_ASYNC - signal(SIGUSR2, (void (*)()) xf86XqueRequest); -#else -#if 0 - signal(SIGUSR2, (void (*)()) xf86XqueSignal); -#endif -#endif - -#ifndef XQUEUE_ASYNC - { - int rval; - - while ((rval = read(xquePipe[0], buf, sizeof(buf))) > 0) #ifdef DEBUG - ErrorF("Read %d bytes from xquePipe[0]\n", rval); -#else - ; -#endif - } + ErrorF("xf86XqueSignal\n"); #endif - - XqueQaddr->xq_head = XqueQaddr->xq_tail; - xf86Info.mouseDev->xquePending = 0; - XqueQaddr->xq_sigenable = 1; /* UNLOCK */ -} - - - -/* - * xf86XqueEnable -- - * Enable the handling of the Xque - */ - -static int -xf86XqueEnable() -{ - static struct kd_quemode xqueMode; - static Bool was_here = FALSE; - - if (!was_here) { - if ((xqueFd = open("/dev/mouse", O_RDONLY|O_NDELAY)) < 0) - { - if (xf86AllowMouseOpenFail) { - ErrorF("Cannot open /dev/mouse (%s) - Continuing...\n", - strerror(errno)); - return (Success); - } else { - Error ("Cannot open /dev/mouse"); - return (!Success); - } - } -#ifndef XQUEUE_ASYNC - pipe(xquePipe); - fcntl(xquePipe[0],F_SETFL,fcntl(xquePipe[0],F_GETFL,0)|O_NDELAY); - fcntl(xquePipe[1],F_SETFL,fcntl(xquePipe[1],F_GETFL,0)|O_NDELAY); -#endif - was_here = TRUE; - } - - if (xf86Info.mouseDev->xqueSema++ == 0) - { -#ifdef XQUEUE_ASYNC - (void) signal(SIGUSR2, (void (*)()) xf86XqueRequest); -#else - (void) signal(SIGUSR2, (void (*)()) xf86XqueSignal); -#endif - xqueMode.qsize = 64; /* max events */ - xqueMode.signo = SIGUSR2; - ioctl(xf86Info.consoleFd, KDQUEMODE, NULL); - - if (ioctl(xf86Info.consoleFd, KDQUEMODE, &xqueMode) < 0) { - Error ("Cannot set KDQUEMODE"); - /* CONSTCOND */ - return (!Success); - } - - XqueQaddr = (xqEventQueue *)xqueMode.qaddr; - XqueQaddr->xq_sigenable = 1; /* UNLOCK */ - } - - return(Success); -} - - - -/* - * xf86XqueDisable -- - * disable the handling of the Xque - */ - -static int -xf86XqueDisable() -{ - if (xf86Info.mouseDev->xqueSema-- == 1) - { - - XqueQaddr->xq_sigenable = 0; /* LOCK */ - - if (ioctl(xf86Info.consoleFd, KDQUEMODE, NULL) < 0) { - Error ("Cannot unset KDQUEMODE"); - /* CONSTCOND */ - return (!Success); - } - } - - return(Success); + write(xquePipe[1], "X", 1); + signal(SIGUSR2, xf86XqueSignal); } - - - -/* - * xf86XqueMseProc -- - * Handle the initialization, etc. of a mouse - */ - -int -xf86XqueMseProc(pPointer, what) - DeviceIntPtr pPointer; - int what; -{ - MouseDevPtr mouse = MOUSE_DEV(pPointer); - unchar map[4]; - int ret; - - mouse->device = pPointer; - - switch (what) - { - case DEVICE_INIT: - - pPointer->public.on = FALSE; - - map[1] = 1; - map[2] = 2; - map[3] = 3; - InitPointerDeviceStruct((DevicePtr)pPointer, - map, - 3, - miPointerGetMotionEvents, - (PtrCtrlProcPtr)xf86MseCtrl, - miPointerGetMotionBufferSize()); - break; - - case DEVICE_ON: - mouse->lastButtons = 0; - mouse->emulateState = 0; - pPointer->public.on = TRUE; - ret = xf86XqueEnable(); -#ifndef XQUEUE_ASYNC - if (xquePipe[0] != -1) - AddEnabledDevice(xquePipe[0]); -#endif - return(ret); - - case DEVICE_CLOSE: - case DEVICE_OFF: - pPointer->public.on = FALSE; - ret = xf86XqueDisable(); -#ifndef XQUEUE_ASYNC - if (xquePipe[0] != -1) - RemoveEnabledDevice(xquePipe[0]); #endif - return(ret); - } - return Success; -} - - /* * xf86XqueKbdProc -- @@ -302,9 +97,7 @@ xf86XqueMseProc(pPointer, what) */ int -xf86XqueKbdProc (pKeyboard, what) - DeviceIntPtr pKeyboard; /* Keyboard to manipulate */ - int what; /* What to do to it */ +xf86XqueKbdProc(DeviceIntPtr pKeyboard, int what) { KeySymsRec keySyms; CARD8 modMap[MAP_LENGTH]; @@ -381,12 +174,12 @@ xf86XqueKbdProc (pKeyboard, what) case DEVICE_ON: pKeyboard->public.on = TRUE; xf86InitKBD(FALSE); - return(xf86XqueEnable()); + break; case DEVICE_CLOSE: case DEVICE_OFF: pKeyboard->public.on = FALSE; - return(xf86XqueDisable()); + break; } return (Success); @@ -403,4 +196,343 @@ xf86XqueEvents() { } + +#ifdef XQUEUE_ASYNC +static void XqDoInput(int signum); +#endif + +void +XqReadInput(InputInfoPtr pInfo) +{ + MouseDevPtr pMse; + XqInfoPtr pXq; + xqEvent *XqueEvents; + int XqueHead; + char buf[100]; + signed char dx, dy; + + if (xqueFd < 0) + return; + + pMse = pInfo->private; + pXq = pMse->mousePriv; + + XqueEvents = XqueQaddr->xq_events; + XqueHead = XqueQaddr->xq_head; + + while (XqueHead != XqueQaddr->xq_tail) { + switch (XqueEvents[XqueHead].xq_type) { + case XQ_BUTTON: + pMse->PostEvent(pInfo, ~(XqueEvents[XqueHead].xq_code) & 0x07, + 0, 0, 0, 0); +#ifdef DEBUG + ErrorF("xqueue: buttons: %d\n", ~(XqueEvents[XqueHead].xq_code) & 0x07); +#endif + break; + + case XQ_MOTION: + dx = (signed char)XqueEvents[XqueHead].xq_x; + dy = (signed char)XqueEvents[XqueHead].xq_y; + pMse->PostEvent(pInfo, ~(XqueEvents[XqueHead].xq_code) & 0x07, + (int)dx, (int)dy, 0, 0); +#ifdef DEBUG + ErrorF("xqueue: Motion: (%d, %d) (buttons: %d)\n", dx, dy, ~(XqueEvents[XqueHead].xq_code) & 0x07); +#endif + break; + + case XQ_KEY: + /* XXX Need to deal with the keyboard part nicely. */ +#ifdef DEBUG + ErrorF("xqueue: key: %d\n", XqueEvents[XqueHead].xq_code); +#endif + xf86PostKbdEvent(XqueEvents[XqueHead].xq_code); + break; + default: + xf86Msg(X_WARNING, "Unknown Xque Event: 0x%02x\n", + XqueEvents[XqueHead].xq_type); + } + + if ((++XqueHead) == XqueQaddr->xq_size) XqueHead = 0; + xf86Info.inputPending = TRUE; + } + + /* reenable the signal-processing */ +#ifdef XQUEUE_ASYNC + signal(SIGUSR2, XqDoInput); +#endif + +#ifndef XQUEUE_ASYNC + { + int rval; + + while ((rval = read(xquePipe[0], buf, sizeof(buf))) > 0) +#ifdef DEBUG + ErrorF("Read %d bytes from xquePipe[0]\n", rval); +#else + ; +#endif + } +#endif + +#ifdef DEBUG + ErrorF("Leaving XqReadInput()\n"); +#endif + pXq->xquePending = 0; + XqueQaddr->xq_head = XqueQaddr->xq_tail; + XqueQaddr->xq_sigenable = 1; /* UNLOCK */ +} + +#ifdef XQUEUE_ASYNC +static void +XqDoInput(int signum) +{ + if (XqMouse) + XqReadInput(XqMouse); +} +#endif + +static void +XqBlock(pointer blockData, OSTimePtr pTimeout, pointer pReadmask) +{ + InputInfoPtr pInfo; + MouseDevPtr pMse; + XqInfoPtr pXq; + /* + * On MP SVR4 boxes, a race condition exists because the XQUEUE does + * not have anyway to lock it for exclusive access. This results in one + * processor putting something on the queue at the same time the other + * processor is taking it something off. The count of items in the queue + * can get off by 1. This just goes and checks to see if an extra event + * was put in the queue a during this period. The signal for this event + * was ignored while processing the previous event. + */ + + pInfo = blockData; + pMse = pInfo->private; + pXq = pMse-> mousePriv; + if (!pXq->xquePending) { +#ifdef DEBUG + ErrorF("XqBlock: calling XqReadInput()\n"); +#endif + XqReadInput((InputInfoPtr)blockData); + } else { +#ifdef DEBUG + ErrorF("XqBlock: not calling XqReadInput()\n"); +#endif + ; + } + /* + * Make sure that any events that come in here are passed on without. + * waiting for the next wakeup. + */ + if (xf86Info.inputPending) { +#ifdef DEBUG + ErrorF("XqBlock: calling ProcessInputEvents()\n"); +#endif + ProcessInputEvents(); + } else { +#ifdef DEBUG + ErrorF("XqBlock: not calling ProcessInputEvents()\n"); +#endif + ; + } +} + +/* + * XqEnable -- + * Enable the handling of the Xque + */ + +static int +XqEnable(InputInfoPtr pInfo) +{ + MouseDevPtr pMse; + XqInfoPtr pXq; + static struct kd_quemode xqueMode; + static Bool was_here = FALSE; + + pMse = pInfo->private; + pXq = pMse->mousePriv; + + if (xqueFd < 0) { + if ((xqueFd = open("/dev/mouse", O_RDONLY | O_NDELAY)) < 0) { + if (xf86GetAllowMouseOpenFail()) { + xf86Msg(X_WARNING, + "%s: Cannot open /dev/mouse (%s) - Continuing...\n", + pInfo->name, strerror(errno)); + return Success; + } else { + xf86Msg(X_ERROR, "%s: Cannot open /dev/mouse (%s)\n", + pInfo->name, strerror(errno)); + return !Success; + } + } + } +#ifndef XQUEUE_ASYNC + if (!was_here) { + pipe(xquePipe); + fcntl(xquePipe[0], F_SETFL, fcntl(xquePipe[0], F_GETFL, 0) | O_NDELAY); + fcntl(xquePipe[1], F_SETFL, fcntl(xquePipe[1], F_GETFL, 0) | O_NDELAY); + was_here = TRUE; + } +#endif + + if (pXq->xqueSema++ == 0) { +#ifdef XQUEUE_ASYNC + (void) signal(SIGUSR2, XqDoInput); +#else + (void) signal(SIGUSR2, xf86XqueSignal); +#endif + xqueMode.qsize = 64; /* max events */ + xqueMode.signo = SIGUSR2; + ioctl(xf86Info.consoleFd, KDQUEMODE, NULL); + + if (ioctl(xf86Info.consoleFd, KDQUEMODE, &xqueMode) < 0) { + xf86Msg(X_ERROR, "%s: Cannot set KDQUEMODE", pInfo->name); + return !Success; + } + XqueQaddr = (xqEventQueue *)xqueMode.qaddr; + XqueQaddr->xq_sigenable = 1; /* UNLOCK */ + } + + return Success; +} + + + +/* + * xf86XqueDisable -- + * disable the handling of the Xque + */ + +static int +XqDisable(InputInfoPtr pInfo) +{ + MouseDevPtr pMse; + XqInfoPtr pXq; + + pMse = pInfo->private; + pXq = pMse->mousePriv; + + if (pXq->xqueSema-- == 1) + { + XqueQaddr->xq_sigenable = 0; /* LOCK */ + + if (ioctl(xf86Info.consoleFd, KDQUEMODE, NULL) < 0) { + xf86Msg(X_ERROR, "%s: Cannot unset KDQUEMODE", pInfo->name); + return !Success; + } + } + + if (xqueFd >= 0) { + close(xqueFd); + xqueFd = -1; + } + + return Success; +} + +/* + * XqMouseProc -- + * Handle the initialization, etc. of a mouse + */ + +static int +XqMouseProc(DeviceIntPtr pPointer, int what) +{ + InputInfoPtr pInfo; + MouseDevPtr pMse; + unchar map[4]; + int ret; + + pInfo = pPointer->public.devicePrivate; + pMse = pInfo->private; + pMse->device = pPointer; + + switch (what) { + case DEVICE_INIT: + pPointer->public.on = FALSE; + + map[1] = 1; + map[2] = 2; + map[3] = 3; + + InitPointerDeviceStruct((DevicePtr)pPointer, + map, + 3, + miPointerGetMotionEvents, + pMse->Ctrl, + miPointerGetMotionBufferSize()); + /* X valuator */ + xf86InitValuatorAxisStruct(pPointer, 0, 0, -1, 1, 0, 1); + xf86InitValuatorDefaults(pPointer, 0); + /* Y valuator */ + xf86InitValuatorAxisStruct(pPointer, 1, 0, -1, 1, 0, 1); + xf86InitValuatorDefaults(pPointer, 1); + xf86MotionHistoryAllocate(pInfo); + RegisterBlockAndWakeupHandlers(XqBlock, (WakeupHandlerProcPtr)NoopDDA, + pInfo); + break; + + case DEVICE_ON: + pMse->lastButtons = 0; + pMse->emulateState = 0; + pPointer->public.on = TRUE; + ret = XqEnable(pInfo); +#ifndef XQUEUE_ASYNC + if (xquePipe[0] != -1) { + pInfo->fd = xquePipe[0]; + AddEnabledDevice(xquePipe[0]); + } +#endif + return ret; + + case DEVICE_CLOSE: + case DEVICE_OFF: + pPointer->public.on = FALSE; + ret = XqDisable(pInfo); +#ifndef XQUEUE_ASYNC + if (xquePipe[0] != -1) { + RemoveEnabledDevice(xquePipe[0]); + pInfo->fd = -1; + } +#endif + return ret; + } + return Success; +} + +Bool +XqueueMousePreInit(InputInfoPtr pInfo, const char *protocol, int flags) +{ + MouseDevPtr pMse; + XqInfoPtr pXq; + + pMse = pInfo->private; + pMse->protocol = protocol; + xf86Msg(X_CONFIG, "%s: Protocol: %s\n", pInfo->name, protocol); + pXq = pMse->mousePriv = xnfcalloc(sizeof(XqInfoRec), 1); + + /* Collect the options, and process the common options. */ + xf86CollectInputOptions(pInfo, NULL, NULL); + xf86ProcessCommonOptions(pInfo, pInfo->options); + + /* Process common mouse options (like Emulate3Buttons, etc). */ + pMse->CommonOptions(pInfo); + + /* Setup the local procs. */ + pInfo->device_control = XqMouseProc; +#ifdef XQUEUE_ASYNC + pInfo->read_input = NULL; +#else + pInfo->read_input = XqReadInput; +#endif + pInfo->fd = -1; + + XqMouse = pInfo; + + pInfo->flags |= XI86_CONFIGURED; + return TRUE; +} + #endif /* XQUEUE */ |