summaryrefslogtreecommitdiff
path: root/hw/xfree86/os-support/sysv/xqueue.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/xfree86/os-support/sysv/xqueue.c')
-rw-r--r--hw/xfree86/os-support/sysv/xqueue.c606
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 */