Add new DMX input code that uses the mi event queue and MPX

for handling of multiple input devices.
This commit is contained in:
David Reveman 2008-06-24 12:18:22 -04:00
parent 42b6df396a
commit 84ddb6de62
6 changed files with 334 additions and 544 deletions

View file

@ -71,12 +71,8 @@ void InitInput(int argc, char **argv)
for (i = 0, dmxInput = &dmxInputs[0]; i < dmxNumInputs; i++, dmxInput++)
dmxInputInit(dmxInput);
if (!dmxeqInitialized()) {
dmxLog(dmxWarning, "Use keyboard/mouse pair with the first -input\n");
dmxLog(dmxFatal, "At least one core keyboard/mouse pair required\n");
}
mieqInit();
mieqInit ();
}
/** Called from dix/dispatch.c in Dispatch() whenever input events
@ -87,6 +83,8 @@ void ProcessInputEvents(void)
int i;
DMXInputInfo *dmxInput;
mieqProcessInputEvents ();
for (i = 0, dmxInput = &dmxInputs[0]; i < dmxNumInputs; i++, dmxInput++)
if (!dmxInput->detached && dmxInput->processInputEvents)
dmxInput->processInputEvents(dmxInput);

View file

@ -57,10 +57,13 @@
#include "inputstr.h"
#include "input.h"
#include <X11/keysym.h>
#include "mi.h"
#include "mipointer.h"
#include "scrnintstr.h"
#include "windowstr.h"
static EventListPtr dmxEvents = NULL;
/* Private area for backend devices. */
typedef struct _myPrivate {
DMX_COMMON_PRIVATE;
@ -194,23 +197,6 @@ static DMXScreenInfo *dmxBackendGetEvent(myPrivate *priv, XEvent *X)
return NULL;
}
static DMXScreenInfo *dmxBackendPendingMotionEvent(myPrivate *priv, int save)
{
DMXScreenInfo *dmxScreen;
XEvent N;
if ((dmxScreen = dmxPropertyIterate(priv->be,
dmxBackendTestMotionEvent, &N))) {
if (save) {
XLIB_PROLOGUE (dmxScreen);
XPutBackEvent(dmxScreen->beDisplay, &N);
XLIB_EPILOGUE (dmxScreen);
}
return dmxScreen;
}
return NULL;
}
static void *dmxBackendTestWindow(DMXScreenInfo *dmxScreen, void *closure)
{
Window win = (Window)(long)closure;
@ -218,135 +204,241 @@ static void *dmxBackendTestWindow(DMXScreenInfo *dmxScreen, void *closure)
return NULL;
}
static DMXScreenInfo *dmxBackendFindWindow(myPrivate *priv, Window win)
{
return dmxPropertyIterate(priv->be, dmxBackendTestWindow,
(void *)(long)win);
}
/* If the cursor is over a set of overlapping screens and one of those
* screens takes backend input, then we want that particular screen to
* be current, not one of the other ones. */
static int dmxBackendFindOverlapping(myPrivate *priv, int screen, int x, int y)
{
DMXScreenInfo *start = &dmxScreens[screen];
DMXScreenInfo *pt;
if (!start->over) return screen;
for (pt = start->over; /* condition at end of loop */; pt = pt->over) {
if (pt->index == priv->myScreen
&& dmxOnScreen(x, y, &dmxScreens[pt->index])) return pt->index;
if (pt == start) break;
}
return screen;
}
/* Return non-zero if \a x and \a y are off \a screen. */
static int dmxBackendOffscreen(int screen, int x, int y)
{
DMXScreenInfo *dmxScreen = &dmxScreens[screen];
return (!dmxOnScreen(x, y, dmxScreen));
}
/** This routine is called from #dmxCoreMotion for each motion
* event. #x and #y are global coordinants. */
void dmxBackendUpdatePosition(pointer private, int x, int y)
{
GETPRIVFROMPRIVATE;
int screen = miPointerGetScreen(inputInfo.pointer)->myNum;
DMXScreenInfo *dmxScreen = &dmxScreens[priv->myScreen];
int oldRelative = priv->relative;
int topscreen = dmxBackendFindOverlapping(priv, screen, x, y);
int same = dmxBackendSameDisplay(priv, topscreen);
int offscreen = dmxBackendOffscreen(priv->myScreen, x, y);
int offthis = dmxBackendOffscreen(screen, x, y);
}
DMXDBG9("dmxBackendUpdatePosition(%d,%d) my=%d mi=%d rel=%d"
" topscreen=%d same=%d offscreen=%d offthis=%d\n",
x, y, priv->myScreen, screen, priv->relative,
topscreen, same, offscreen, offthis);
static DeviceIntPtr
dmxGetButtonDevice (DMXInputInfo *dmxInput)
{
int i;
if (offscreen) {
/* If the cursor is off the input screen, it should be moving
* relative unless it is visible on a screen of the same display
* (i.e., one that shares the mouse). */
if (same == 2 && !offthis) {
if (priv->relative) {
DMXDBG0(" Off screen, but not absolute\n");
priv->relative = 0;
}
} else {
if (!priv->relative) {
DMXDBG0(" Off screen, but not relative\n");
priv->relative = 1;
}
}
} else {
if (topscreen != screen) {
DMXDBG2(" Using screen %d instead of %d (from mi)\n",
topscreen, screen);
}
if (same) {
if (priv->relative) {
DMXDBG0(" On screen, but not absolute\n");
priv->relative = 0;
}
} else {
if (!priv->relative) {
DMXDBG0(" Not on screen, but not relative\n");
priv->relative = 1;
}
}
for (i = 0; i < dmxInput->numDevs; i++)
if (dmxInput->devs[i]->pDevice->button)
return dmxInput->devs[i]->pDevice;
return NULL;
}
static DeviceIntPtr
dmxGetPairedButtonDevice (DMXInputInfo *dmxInput,
DeviceIntPtr pOther)
{
return dmxGetButtonDevice (dmxInput);
}
static DeviceIntPtr
dmxGetKeyboardDevice (DMXInputInfo *dmxInput)
{
int i;
for (i = 0; i < dmxInput->numDevs; i++)
if (dmxInput->devs[i]->pDevice->key)
return dmxInput->devs[i]->pDevice;
return NULL;
}
static DeviceIntPtr
dmxGetPairedKeyboardDevice (DMXInputInfo *dmxInput,
DeviceIntPtr pOther)
{
return dmxGetKeyboardDevice (dmxInput);
}
static int
dmxButtonEvent (DeviceIntPtr pDevice,
int button,
int x,
int y,
int type)
{
ScreenPtr scr = miPointerGetScreen (pDevice);
int mx = pDevice->valuator->axes[0].max_value;
int my = pDevice->valuator->axes[1].max_value;
int v[2] = { x, y };
int nEvents, i;
pDevice->valuator->axes[0].max_value = scr->width;
pDevice->valuator->axes[1].max_value = scr->height;
GetEventList (&dmxEvents);
nEvents = GetPointerEvents (dmxEvents,
pDevice,
type,
button,
POINTER_ABSOLUTE,
0, 2,
v);
pDevice->valuator->axes[0].max_value = mx;
pDevice->valuator->axes[1].max_value = my;
for (i = 0; i < nEvents; i++)
mieqEnqueue (pDevice, dmxEvents[i].event);
if (button <= 5)
{
GETDMXLOCALFROMPDEVICE;
switch (type) {
case ButtonPress:
dmxLocal->state |= (Button1Mask >> 1) << button;
break;
case ButtonRelease:
dmxLocal->state &= ~((Button1Mask >> 1) << button);
default:
break;
}
}
if (oldRelative != priv->relative) {
DMXDBG2(" Do switch, relative=%d same=%d\n",
priv->relative, same);
/* Discard all pre-switch events */
dmxSync(dmxScreen, TRUE);
while (dmxBackendPendingMotionEvent(priv, FALSE));
if (dmxInput->console && offscreen) {
/* Our special case is a console window and a backend window
* share a display. In this case, the cursor is either on
* the backend window (taking absolute input), or not (in
* which case the cursor needs to be in the console
* window). */
if (priv->grabbedScreen) {
DMXDBG2(" *** force ungrab on %s, display=%p\n",
priv->grabbedScreen->name,
priv->grabbedScreen->beDisplay);
XLIB_PROLOGUE (dmxScreen);
XUngrabPointer(priv->grabbedScreen->beDisplay, CurrentTime);
XLIB_EPILOGUE (dmxScreen);
dmxSync(priv->grabbedScreen, TRUE);
priv->grabbedScreen = NULL;
}
DMXDBG0(" Capturing console\n");
dmxConsoleCapture(dmxInput);
} else {
priv->newscreen = 1;
if (priv->relative && !dmxInput->console) {
DMXDBG5(" Hide cursor; warp from %d,%d to %d,%d on %d\n",
priv->lastX, priv->lastY, priv->centerX, priv->centerY,
priv->myScreen);
dmxConsoleUncapture(dmxInput);
dmxHideCursor(dmxScreen);
priv->lastX = priv->centerX;
priv->lastY = priv->centerY;
XLIB_PROLOGUE (dmxScreen);
XWarpPointer(priv->display, None, priv->window,
0, 0, 0, 0, priv->lastX, priv->lastY);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, TRUE);
} else {
DMXDBG0(" Check cursor\n");
dmxCheckCursor();
}
}
return nEvents;
}
static int
dmxKeyEvent (DeviceIntPtr pDevice,
int key,
int type)
{
int i, nEvents;
GetEventList (&dmxEvents);
nEvents = GetKeyboardEvents (dmxEvents, pDevice, type, key);
for (i = 0; i < nEvents; i++)
mieqEnqueue (pDevice, dmxEvents[i].event);
if (key >= 8 && key <= 255)
{
KeyClassPtr keyc = pDevice->key;
GETDMXLOCALFROMPDEVICE;
switch (type) {
case KeyPress:
dmxLocal->state |= keyc->modifierMap[key];
break;
case KeyRelease:
dmxLocal->state &= ~keyc->modifierMap[key];
default:
break;
}
}
return nEvents;
}
/*
* Port of Mark McLoughlin's Xnest fix for focus in + modifier bug.
* See https://bugs.freedesktop.org/show_bug.cgi?id=3030
*/
static int
dmxUpdateModifierState (DeviceIntPtr pDevice,
unsigned int state)
{
KeyClassPtr keyc = pDevice->key;
int i, nEvents = 0;
CARD8 mask;
GETDMXLOCALFROMPDEVICE;
state = state & 0xff;
if ((dmxLocal->state & 0xff) == state)
return 0;
for (i = 0, mask = 1; i < 8; i++, mask <<= 1)
{
int key;
/* Modifier is down, but shouldn't be */
if ((dmxLocal->state & mask) && !(state & mask))
{
int count = keyc->modifierKeyCount[i];
for (key = 0; key < MAP_LENGTH; key++)
{
if (keyc->modifierMap[key] & mask)
{
int bit;
BYTE *kptr;
kptr = &keyc->down[key >> 3];
bit = 1 << (key & 7);
if (*kptr & bit)
{
nEvents += dmxKeyEvent (pDevice, key, KeyRelease);
if (--count == 0)
break;
}
}
}
}
/* Modifier should be down, but isn't */
if (!(dmxLocal->state & mask) && (state & mask))
{
for (key = 0; key < MAP_LENGTH; key++)
{
if (keyc->modifierMap[key] & mask)
{
if (keyc->modifierMap[key] & mask)
nEvents += dmxKeyEvent (pDevice, key, KeyPress);
break;
}
}
}
}
return nEvents;
}
static int
dmxUpdateSpritePosition (DeviceIntPtr pDevice,
int x,
int y)
{
if (x == pDevice->last.valuators[0] && y == pDevice->last.valuators[1])
return 0;
return dmxButtonEvent (pDevice, 0, x, y, MotionNotify);
}
static int
dmxUpdateButtonState (DeviceIntPtr pDevice,
unsigned int state)
{
int i, mask, nEvents = 0;
GETDMXLOCALFROMPDEVICE;
state = state & 0x1f00;
if ((dmxLocal->state & 0x1f00) == state)
return 0;
for (i = 0, mask = Button1Mask; i < 5; i++, mask <<= 1)
{
/* Button is down, but shouldn't be */
if ((dmxLocal->state & mask) && !(state & mask))
nEvents += dmxButtonEvent (pDevice,
i + 1,
pDevice->last.valuators[0],
pDevice->last.valuators[1],
ButtonRelease);
/* Button should be down, but isn't */
if (!(dmxLocal->state & mask) && (state & mask))
nEvents += dmxButtonEvent (pDevice,
i + 1,
pDevice->last.valuators[0],
pDevice->last.valuators[1],
ButtonPress);
}
return nEvents;
}
/** Get events from the X queue on the backend servers and put the
@ -361,161 +453,63 @@ void dmxBackendCollectEvents(DevicePtr pDev,
GETDMXINPUTFROMPRIV;
XEvent X;
DMXScreenInfo *dmxScreen;
int left = 0;
int entered = priv->entered;
int ignoreLeave = 0;
int v[2];
Window window = None;
int x = 0, y = 0;
DeviceIntPtr pButtonDev, pKeyDev;
while ((dmxScreen = dmxBackendGetEvent(priv, &X)))
{
if (X.xany.send_event)
continue;
while ((dmxScreen = dmxBackendGetEvent(priv, &X))) {
switch (X.type) {
case FocusIn:
dmxUnpauseCoreInput ();
break;
case FocusOut:
dmxPauseCoreInput ();
break;
case LeaveNotify:
if (ignoreLeave) {
ignoreLeave = 0;
continue;
}
if (left++)
continue;
if (priv->grabbedScreen) {
priv->grabbedScreen = NULL;
}
break;
case EnterNotify:
priv->entered = 1;
ignoreLeave = 1;
priv->grabbedScreen = dmxScreen;
if (X.xcrossing.mode != NotifyUngrab)
break;
window = X.xcrossing.window;
x = X.xcrossing.x;
y = X.xcrossing.y;
/* fall through */
case MotionNotify:
if (X.type == MotionNotify)
pButtonDev = dmxGetButtonDevice (dmxInput);
if (pButtonDev)
{
DMXDBG9("dmxBackendCollectEvents: MotionNotify %d/%d (mi %d)"
" newscreen=%d: %d %d (e=%d; last=%d,%d)\n",
dmxScreen->index, priv->myScreen,
miPointerCurrentScreen()->myNum,
priv->newscreen,
X.xmotion.x, X.xmotion.y,
entered, priv->lastX, priv->lastY);
if (dmxBackendPendingMotionEvent(priv, TRUE))
continue;
pKeyDev = dmxGetPairedKeyboardDevice (dmxInput, pButtonDev);
if (pKeyDev)
dmxUpdateModifierState (pKeyDev, X.xmotion.state);
window = X.xmotion.window;
x = X.xmotion.x;
y = X.xmotion.y;
dmxUpdateButtonState (pButtonDev, X.xmotion.state);
dmxUpdateSpritePosition (pButtonDev, X.xmotion.x, X.xmotion.y);
}
break;
case ButtonPress:
XLIB_PROLOGUE (dmxScreen);
XUngrabPointer (dmxScreen->beDisplay, CurrentTime);
XLIB_EPILOGUE (dmxScreen);
case ButtonRelease:
pButtonDev = dmxGetButtonDevice (dmxInput);
if (pButtonDev)
{
dmxUpdateSpritePosition (pButtonDev, X.xbutton.x, X.xbutton.y);
dmxUpdateButtonState (pButtonDev, X.xbutton.state);
if (!(dmxScreen = dmxBackendFindWindow(priv, window)))
dmxLog(dmxFatal,
" Event on non-existant window %lu\n",
X.xmotion.window);
if (!priv->relative || dmxInput->console) {
int newX = x - dmxScreen->rootX;
int newY = y - dmxScreen->rootY;
pKeyDev = dmxGetPairedKeyboardDevice (dmxInput, pButtonDev);
if (pKeyDev)
dmxUpdateModifierState (pKeyDev, X.xbutton.state);
if (!priv->newscreen) {
int width = dmxScreen->rootWidth;
int height = dmxScreen->rootHeight;
if (!newX) newX = -1;
if (newX == width - 1) newX = width;
if (!newY) newY = -1;
if (newY == height - 1) newY = height;
}
priv->newscreen = 0;
v[0] = dmxScreen->rootXOrigin + newX;
v[1] = dmxScreen->rootYOrigin + newY;
DMXDBG8(" Absolute move: %d,%d (r=%dx%d+%d+%d s=%dx%d)\n",
v[0], v[1],
priv->be->rootWidth, priv->be->rootHeight,
priv->be->rootX, priv->be->rootY,
priv->be->scrnWidth, priv->be->scrnHeight);
motion (priv->mou, v, 0, 2, DMX_ABSOLUTE, block);
priv->entered = 0;
} else {
int newX = priv->lastX - x;
int newY = priv->lastY - y;
priv->lastX = x;
priv->lastY = y;
v[0] = newX;
v[1] = newY;
DMXDBG2(" Relative move: %d, %d\n", v[0], v[1]);
motion (priv->mou, v, 0, 2, DMX_RELATIVE, block);
}
if (entered && priv->relative) {
DMXDBG4(" **** Relative %d %d instead of absolute %d %d\n",
v[0], v[1],
(dmxScreen->rootXOrigin + x
- dmxScreen->rootX),
(dmxScreen->rootYOrigin + y
- dmxScreen->rootY));
dmxButtonEvent (pButtonDev,
X.xbutton.button,
X.xbutton.x, X.xbutton.y,
X.type);
}
break;
case KeyPress:
case KeyRelease:
if (X.xany.send_event)
pKeyDev = dmxGetKeyboardDevice (dmxInput);
if (pKeyDev)
{
BYTE *kptr = &dmxInput->history[X.xkey.keycode >> 3];
int bit = 1 << (X.xkey.keycode & 7);
switch (X.type) {
case KeyPress: *kptr |= bit; break;
case KeyRelease: *kptr &= ~bit; break;
pButtonDev = dmxGetPairedButtonDevice (dmxInput, pKeyDev);
if (pButtonDev)
{
dmxUpdateSpritePosition (pButtonDev, X.xkey.x, X.xkey.y);
dmxUpdateButtonState (pButtonDev, X.xkey.state);
}
}
else
{
dmxInput->validHistory = FALSE;
enqueue (priv->kbd, X.type, X.xkey.keycode, 0, NULL, block);
}
break;
case ButtonPress:
if (!X.xany.send_event)
{
XLIB_PROLOGUE (dmxScreen);
XUngrabPointer (dmxScreen->beDisplay, CurrentTime);
XUngrabKeyboard (dmxScreen->beDisplay, CurrentTime);
XLIB_EPILOGUE (dmxScreen);
}
/* fall-through */
case ButtonRelease:
if (X.xany.send_event)
{
BYTE *bptr = &dmxInput->history[X.xbutton.button >> 3];
int bit = 1 << (X.xbutton.button & 7);
switch (X.type) {
case ButtonPress: *bptr |= bit; break;
case ButtonRelease:*bptr &= ~bit; break;
}
}
else
{
dmxInput->validHistory = FALSE;
enqueue (priv->mou, X.type, X.xbutton.button, 0, &X, block);
}
break;
case MappingNotify:
if (dmxLocal && dmxLocal->pDevice && dmxLocal->pDevice->key)
{
DMXLocalInitInfo info;
memset (&info, 0, sizeof (info));
dmxCommonKbdGetMap (pDev, &info.keySyms, info.modMap);
SetKeySymsMap (&dmxLocal->pDevice->key->curKeySyms,
&info.keySyms);
dmxUpdateModifierState (pKeyDev, X.xkey.state);
dmxKeyEvent (pKeyDev,
X.xkey.keycode,
X.type);
}
default:
break;
@ -609,7 +603,6 @@ void dmxBackendLateReInit(DevicePtr pDev)
dmxBackendComputeCenter(priv);
dmxGetGlobalPosition(&x, &y);
dmxInvalidateGlobalPosition(); /* To force event processing */
dmxBackendUpdatePosition(priv, x, y);
}
/** Initialized the backend device described by \a pDev. */
@ -686,3 +679,9 @@ int dmxBackendFunctions(pointer private, DMXFunctionType function)
return 0;
}
}
void dmxBackendKbdOff(DevicePtr pDev)
{
dmxUpdateModifierState ((DeviceIntPtr) pDev, 0);
dmxCommonKbdOff (pDev);
}

View file

@ -52,5 +52,6 @@ extern void dmxBackendCollectEvents(DevicePtr pDev,
extern void dmxBackendProcessInput(pointer private);
extern int dmxBackendFunctions(pointer private, DMXFunctionType function);
extern void dmxBackendUpdatePosition(pointer private, int x, int y);
extern void dmxBackendKbdOff(DevicePtr pDev);
#endif

View file

@ -210,17 +210,9 @@ static void dmxEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal, xEvent *e,
DMXScreenInfo *dmxFindFirstScreen(int x, int y)
{
int i;
for (i = 0; i < dmxNumScreens; i++) {
DMXScreenInfo *dmxScreen = &dmxScreens[i];
if (dmxOnScreen(x, y, dmxScreen))
return dmxScreen;
}
return NULL;
return dmxScreens;
}
/**
* Enqueue a motion event.
*/

View file

@ -114,7 +114,7 @@ static DMXLocalInputInfoRec DMXBackendKbd = {
1, /* With backend-mou or console-mou */
dmxCommonCopyPrivate, NULL,
dmxBackendInit, NULL, NULL, dmxBackendKbdGetInfo,
dmxCommonKbdOn, dmxCommonKbdOff, NULL,
dmxCommonKbdOn, dmxBackendKbdOff, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, dmxCommonKbdCtrl, dmxCommonKbdBell
@ -220,86 +220,6 @@ static DMXLocalInputInfoRec DMXLocalDevices[] = {
{ NULL } /* Must be last */
};
static void
dmxSyncKeys (DeviceIntPtr pDevice)
{
DevicePtr pDev = &pDevice->public;
DeviceIntPtr keyDev = inputInfo.keyboard;
KeyClassPtr keyc = keyDev->key;
xEvent ke;
int i, x, y;
GETDMXINPUTFROMPDEV;
miPointerGetPosition (inputInfo.pointer, &x, &y);
ke.u.keyButtonPointer.time = GetTimeInMillis ();
ke.u.keyButtonPointer.rootX = x;
ke.u.keyButtonPointer.rootY = y;
for (i = keyc->curKeySyms.minKeyCode; i < keyc->curKeySyms.maxKeyCode; i++)
{
ke.u.u.detail = i;
if (dmxInput->validHistory && BitIsOn (dmxInput->history, i))
{
if (!BitIsOn (keyc->down, i))
{
ke.u.u.type = KeyPress;
(*keyDev->public.processInputProc) (&ke, keyDev, 1);
}
}
else
{
if (BitIsOn (keyc->down, i))
{
ke.u.u.type = KeyRelease;
(*keyDev->public.processInputProc) (&ke, keyDev, 1);
}
}
}
}
static void
dmxSyncButtons (DeviceIntPtr pDevice)
{
DevicePtr pDev = &pDevice->public;
DeviceIntPtr buttonDev = inputInfo.pointer;
ButtonClassPtr buttonc = buttonDev->button;
xEvent be;
int i, x, y;
GETDMXINPUTFROMPDEV;
miPointerGetPosition (inputInfo.pointer, &x, &y);
be.u.keyButtonPointer.time = GetTimeInMillis ();
be.u.keyButtonPointer.rootX = x;
be.u.keyButtonPointer.rootY = y;
for (i = 1; i < DOWN_LENGTH; i++)
{
be.u.u.detail = i;
if (dmxInput->validHistory && BitIsOn (dmxInput->history, i))
{
if (!BitIsOn (buttonc->down, i))
{
be.u.u.type = ButtonPress;
(*buttonDev->public.processInputProc) (&be, buttonDev, 1);
}
}
else
{
if (BitIsOn (buttonc->down, i))
{
be.u.u.type = ButtonRelease;
(*buttonDev->public.processInputProc) (&be, buttonDev, 1);
}
}
}
}
#if 11 /*BP*/
void
DDXRingBell(int volume, int pitch, int duration)
@ -561,11 +481,11 @@ static int dmxDeviceOnOff(DeviceIntPtr pDevice, int what)
info.modMap,
dmxBell, dmxKbdCtrl);
}
if (info.buttonClass) {
if (info.buttonClass) {
InitButtonClassDeviceStruct(pDevice, info.numButtons, info.map);
}
if (info.valuatorClass) {
if (info.numRelAxes && dmxLocal->sendsCore) {
if (info.numRelAxes) {
InitValuatorClassDeviceStruct(pDevice, info.numRelAxes,
GetMaximumEventsNum(),
Relative);
@ -641,7 +561,6 @@ static void dmxProcessInputEvents(DMXInputInfo *dmxInput)
{
int i;
dmxeqProcessInputEvents();
#if 00 /*BP*/
miPointerUpdate();
#endif
@ -650,14 +569,10 @@ static void dmxProcessInputEvents(DMXInputInfo *dmxInput)
for (i = 0; i < dmxInput->numDevs; i += dmxInput->devs[i]->binding)
if (dmxInput->devs[i]->process_input) {
#if 11 /*BP*/
miPointerUpdateSprite(dmxInput->devs[i]->pDevice);
//miPointerUpdateSprite(dmxInput->devs[i]->pDevice);
#endif
dmxInput->devs[i]->process_input(dmxInput->devs[i]->private);
}
#if 11 /*BP*/
mieqProcessInputEvents();
#endif
}
static void dmxUpdateWindowInformation(DMXInputInfo *dmxInput,
@ -714,7 +629,7 @@ static void dmxBlockHandler(pointer blockData, OSTimePtr pTimeout,
{
DMXInputInfo *dmxInput = &dmxInputs[(int)blockData];
static unsigned long generation = 0;
if (generation != serverGeneration) {
generation = serverGeneration;
dmxCollectAll(dmxInput);
@ -797,8 +712,6 @@ static DeviceIntPtr dmxAddDevice(DMXLocalInputInfoPtr dmxLocal)
{
DeviceIntPtr pDevice;
Atom atom;
const char *name = NULL;
void (*registerProcPtr)(DeviceIntPtr) = NULL;
char *devname;
DMXInputInfo *dmxInput;
@ -806,30 +719,7 @@ static DeviceIntPtr dmxAddDevice(DMXLocalInputInfoPtr dmxLocal)
return NULL;
dmxInput = &dmxInputs[dmxLocal->inputIdx];
if (dmxLocal->sendsCore) {
if (dmxLocal->type == DMX_LOCAL_KEYBOARD && !dmxLocalCoreKeyboard) {
dmxLocal->isCore = 1;
dmxLocalCoreKeyboard = dmxLocal;
name = "keyboard";
registerProcPtr = RegisterKeyboardDevice;
}
if (dmxLocal->type == DMX_LOCAL_MOUSE && !dmxLocalCorePointer) {
dmxLocal->isCore = 1;
dmxLocalCorePointer = dmxLocal;
name = "pointer";
registerProcPtr = RegisterPointerDevice;
}
}
if (!name) {
name = "extension";
registerProcPtr = RegisterOtherDevice;
}
if (!name || !registerProcPtr)
dmxLog(dmxFatal, "Cannot add device %s\n", dmxLocal->name);
pDevice = AddInputDevice(serverClient, dmxDeviceOnOff, TRUE);
pDevice = AddInputDevice (serverClient, dmxDeviceOnOff, TRUE);
if (!pDevice) {
dmxLog(dmxError, "Too many devices -- cannot add device %s\n",
dmxLocal->name);
@ -843,21 +733,13 @@ static DeviceIntPtr dmxAddDevice(DMXLocalInputInfoPtr dmxLocal)
pDevice->type = atom;
pDevice->name = devname;
registerProcPtr(pDevice);
if (dmxLocal->isCore && dmxLocal->type == DMX_LOCAL_MOUSE) {
#if 00 /*BP*/
miRegisterPointerDevice(screenInfo.screens[0], pDevice);
#else
/* Nothing? dmxDeviceOnOff() should get called to init, right? */
#endif
}
RegisterOtherDevice (pDevice);
if (dmxLocal->create_private)
dmxLocal->private = dmxLocal->create_private(pDevice);
dmxLogInput(dmxInput, "Added %s as %s device called %s%s\n",
dmxLocal->name, name, devname,
dmxLocal->name, "extension", devname,
dmxLocal->isCore
? " [core]"
: (dmxLocal->sendsCore
@ -1066,7 +948,6 @@ void dmxInputLateReInit(DMXInputInfo *dmxInput)
/** Initialize all of the devices described in \a dmxInput. */
void dmxInputInit(DMXInputInfo *dmxInput)
{
DeviceIntPtr pPointer = NULL, pKeyboard = NULL;
dmxArg a;
const char *name;
int i;
@ -1124,7 +1005,7 @@ void dmxInputInit(DMXInputInfo *dmxInput)
dmxLog(dmxFatal,
"Cannot take input from shared backend (%s)\n",
name);
if (!dmxInput->core) {
if (0 && !dmxInput->core) {
dmxLog(dmxWarning,
"Cannot use core devices on a backend (%s)"
" as XInput devices\n", name);
@ -1167,25 +1048,11 @@ void dmxInputInit(DMXInputInfo *dmxInput)
for (i = 0; i < dmxInput->numDevs; i++) {
DMXLocalInputInfoPtr dmxLocal = dmxInput->devs[i];
dmxLocal->pDevice = dmxAddDevice(dmxLocal);
if (dmxLocal->isCore) {
if (dmxLocal->type == DMX_LOCAL_MOUSE)
pPointer = dmxLocal->pDevice;
if (dmxLocal->type == DMX_LOCAL_KEYBOARD)
pKeyboard = dmxLocal->pDevice;
}
}
if (pPointer && pKeyboard) {
if (dmxeqInit(&pKeyboard->public, &pPointer->public))
dmxLogInput(dmxInput, "Using %s and %s as true core devices\n",
pKeyboard->name, pPointer->name);
}
dmxInput->processInputEvents = dmxProcessInputEvents;
dmxInput->detached = False;
dmxInput->validHistory = FALSE;
RegisterBlockAndWakeupHandlers(dmxBlockHandler,
dmxWakeupHandler,
(void *)dmxInput->inputIdx);
@ -1208,13 +1075,10 @@ static void dmxInputFreeLocal(DMXLocalInputInfoRec *local)
xfree(local);
}
/** Free all of the memory associated with \a dmxInput */
void dmxInputFree(DMXInputInfo *dmxInput)
static void dmxInputFini(DMXInputInfo *dmxInput)
{
int i;
if (!dmxInput) return;
if (dmxInput->keycodes) xfree(dmxInput->keycodes);
if (dmxInput->symbols) xfree(dmxInput->symbols);
if (dmxInput->geometry) xfree(dmxInput->geometry);
@ -1226,6 +1090,15 @@ void dmxInputFree(DMXInputInfo *dmxInput)
xfree(dmxInput->devs);
dmxInput->devs = NULL;
dmxInput->numDevs = 0;
}
/** Free all of the memory associated with \a dmxInput */
void dmxInputFree(DMXInputInfo *dmxInput)
{
if (!dmxInput) return;
dmxInputFini (dmxInput);
if (dmxInput->freename) xfree(dmxInput->name);
dmxInput->name = NULL;
}
@ -1290,7 +1163,7 @@ int dmxInputDetach(DMXInputInfo *dmxInput)
int i;
if (dmxInput->detached) return BadAccess;
for (i = 0; i < dmxInput->numDevs; i++) {
DMXLocalInputInfoPtr dmxLocal = dmxInput->devs[i];
dmxLogInput(dmxInput, "Detaching device id %d: %s%s\n",
@ -1301,10 +1174,12 @@ int dmxInputDetach(DMXInputInfo *dmxInput)
: (dmxLocal->sendsCore
? " [sends core events]"
: ""));
dmxSyncKeys (dmxLocal->pDevice);
dmxSyncButtons (dmxLocal->pDevice);
DisableDevice(dmxLocal->pDevice);
DisableDevice (dmxLocal->pDevice);
ProcessInputEvents ();
DeleteInputDeviceRequest (dmxLocal->pDevice);
}
dmxInputFini (dmxInput);
dmxInput->detached = True;
dmxInputLogDevices();
return 0;
@ -1352,8 +1227,20 @@ DMXInputInfo *dmxInputLocateId(int id)
static int dmxInputAttachNew(DMXInputInfo *dmxInput, int *id)
{
int i;
dmxInputInit(dmxInput);
InitAndStartDevices();
for (i = 0; i < dmxInput->numDevs; i++) {
DMXLocalInputInfoPtr dmxLocal = dmxInput->devs[i];
if (ActivateDevice(dmxLocal->pDevice) != Success ||
EnableDevice(dmxLocal->pDevice) != TRUE) {
ErrorF ("[dmx] couldn't add or enable device\n");
return BadImplementation;
}
}
if (id && dmxInput->devs) *id = dmxInput->devs[0]->pDevice->id;
dmxInputLogDevices();
return 0;
@ -1364,21 +1251,18 @@ static int dmxInputAttachOld(DMXInputInfo *dmxInput, int *id)
int i;
dmxInput->detached = False;
dmxInputInit(dmxInput);
for (i = 0; i < dmxInput->numDevs; i++) {
DMXLocalInputInfoPtr dmxLocal = dmxInput->devs[i];
if (id) *id = dmxLocal->pDevice->id;
dmxLogInput(dmxInput,
"Attaching device id %d: %s%s\n",
dmxLocal->pDevice->id,
dmxLocal->pDevice->name,
dmxLocal->isCore
? " [core]"
: (dmxLocal->sendsCore
? " [sends core events]"
: ""));
/* EnableDevice(dmxLocal->pDevice); call InitAndStartDevices instead */
InitAndStartDevices();
if (ActivateDevice(dmxLocal->pDevice) != Success ||
EnableDevice(dmxLocal->pDevice) != TRUE) {
ErrorF ("[dmx] couldn't add or enable device\n");
return BadImplementation;
}
}
if (id && dmxInput->devs) *id = dmxInput->devs[0]->pDevice->id;
dmxInputLogDevices();
return 0;
}
@ -1432,87 +1316,3 @@ int dmxInputAttachBackend(int physicalScreen, int isCore, int *id)
dmxLogInput(dmxInput, "Attaching new backend input\n");
return dmxInputAttachNew(dmxInput, id);
}
void
dmxPauseCoreInput (void)
{
int i, j;
for (i = 0; i < dmxNumInputs; i++)
{
DMXInputInfo *dmxInput = &dmxInputs[i];
for (j = 0; j < dmxInput->numDevs; j++)
{
DMXLocalInputInfoPtr dmxLocal = dmxInput->devs[j];
DeviceIntPtr pDevice = (DeviceIntPtr) dmxLocal->pDevice;
if (!dmxInput->devs[j]->sendsCore)
continue;
if (pDevice->button)
{
if (inputInfo.pointer->enabled)
{
memcpy (dmxInput->history,
inputInfo.pointer->button->down,
sizeof (CARD8) * DOWN_LENGTH);
dmxInput->validHistory = TRUE;
}
}
else if (pDevice->key)
{
if (inputInfo.keyboard->enabled)
{
memcpy (dmxInput->history,
inputInfo.keyboard->key->down,
sizeof (CARD8) * DOWN_LENGTH);
dmxInput->validHistory = TRUE;
}
}
}
}
if (inputInfo.pointer->enabled)
DisableDevice (inputInfo.pointer);
if (inputInfo.keyboard->enabled)
DisableDevice (inputInfo.keyboard);
}
void
dmxUnpauseCoreInput (void)
{
int i, j;
for (i = 0; i < dmxNumInputs; i++)
{
DMXInputInfo *dmxInput = &dmxInputs[i];
for (j = 0; j < dmxInput->numDevs; j++)
{
DMXLocalInputInfoPtr dmxLocal = dmxInput->devs[j];
DeviceIntPtr pDevice = (DeviceIntPtr) dmxLocal->pDevice;
if (!dmxInput->devs[j]->sendsCore)
continue;
if (pDevice->button)
{
if (!inputInfo.pointer->enabled)
EnableDevice (inputInfo.pointer);
}
else if (pDevice->key)
{
if (!inputInfo.keyboard->enabled)
dmxSyncKeys (pDevice);
}
}
}
if (!inputInfo.pointer->enabled)
EnableDevice (inputInfo.pointer);
if (!inputInfo.keyboard->enabled)
EnableDevice (inputInfo.keyboard);
}

View file

@ -265,6 +265,9 @@ typedef struct _DMXLocalInputInfo {
* if any */
const char *deviceName; /**< devive name on remote
* side, if any */
unsigned int state; /**< Modifier/Button state */
} DMXLocalInputInfoRec;
extern DMXLocalInputInfoPtr dmxLocalCorePointer, dmxLocalCoreKeyboard;
@ -290,7 +293,4 @@ extern int dmxInputAttachConsole(const char *name, int isCore,
extern int dmxInputAttachBackend(int physicalScreen, int isCore,
int *id);
extern void dmxPauseCoreInput (void);
extern void dmxUnpauseCoreInput (void);
#endif