Add initial pointer grab support. Passive pointer grabs are

currently disabled.
This commit is contained in:
David Reveman 2008-07-30 15:54:17 -04:00
parent 2150960fb4
commit 4b7d3bbe7c
12 changed files with 847 additions and 115 deletions

View file

@ -84,6 +84,7 @@
#include "dmxlog.h"
#include "dmxprop.h"
#include "dmxinput.h"
#include "dmxgrab.h"
#include "mipointer.h"
#include "windowstr.h"
@ -117,6 +118,9 @@ Bool dmxInitCursor(ScreenPtr pScreen)
if (!dixRequestPrivate(pScreen, sizeof(dmxCursorPrivRec)))
return FALSE;
if (!dixRequestPrivate (dmxDevicePrivateKey, sizeof(dmxDevicePrivRec)))
return FALSE;
return TRUE;
}
@ -804,11 +808,22 @@ dmxSetCursor (DeviceIntPtr pDev,
static Bool dmxDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScr)
{
dmxDevicePrivPtr pDevPriv = DMX_GET_DEVICE_PRIV (pDev);
DMX_WRAP (ActivateGrab, dmxActivatePointerGrab, pDevPriv,
&pDev->deviceGrab);
DMX_WRAP (DeactivateGrab, dmxDeactivatePointerGrab, pDevPriv,
&pDev->deviceGrab);
return TRUE;
}
static void dmxDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScr)
{
dmxDevicePrivPtr pDevPriv = DMX_GET_DEVICE_PRIV (pDev);
DMX_UNWRAP (ActivateGrab, pDevPriv, &pDev->deviceGrab);
DMX_UNWRAP (DeactivateGrab, pDevPriv, &pDev->deviceGrab);
}
miPointerSpriteFuncRec dmxPointerSpriteFuncs =

View file

@ -61,6 +61,7 @@ extern void dmxBECreateCursor(ScreenPtr pScreen, CursorPtr pCursor);
extern Bool dmxBEFreeCursor(ScreenPtr pScreen, CursorPtr pCursor);
#define DMX_GET_CURSOR_PRIV(_pCursor, _pScreen) ((dmxCursorPrivPtr) \
dixLookupPrivate(&(_pCursor)->devPrivates, CursorScreenKey(_pScreen)))
((dmxCursorPrivPtr)dixLookupPrivate(&(_pCursor)->devPrivates, \
CursorScreenKey(_pScreen))))
#endif /* DMXCURSOR_H */

View file

@ -58,6 +58,7 @@
#include "dmxrandr.h"
#endif
#include "dmxinput.h"
#include "dmxgrab.h"
#include "dmxsync.h"
#include "dmxscrinit.h"
#include "input/dmxinputinit.h"
@ -71,6 +72,10 @@
#include "cursorstr.h"
#include "propertyst.h"
#ifdef PANORAMIX
#include "panoramiXsrv.h"
#endif
#define dmxErrorSet(set, error, name, fmt, ...) \
if (set) (*set) (error, name, fmt, ##__VA_ARGS__)
@ -324,6 +329,14 @@ static void dmxAdjustCursorBoundaries(void)
}
}
static void dmxBERestorePassiveGrab(pointer value, XID id, pointer closure)
{
DMXInputInfo *dmxInput = (DMXInputInfo *) closure;
GrabPtr pGrab = value;
dmxBEAddPassiveGrab (dmxInput, pGrab);
}
/** Add an input with the specified attributes. If the input is added,
* the physical id is returned in \a deviceId. */
int dmxAddInput(DMXInputAttributesPtr attr, int *id)
@ -340,6 +353,21 @@ int dmxAddInput(DMXInputAttributesPtr attr, int *id)
/* Adjust the cursor boundaries */
dmxAdjustCursorBoundaries();
if (attr->inputType == 2)
{
int i, j;
for (i = 0; i < dmxNumInputs; i++)
if (attr->physicalScreen == dmxInputs[i].scrnIdx)
break;
for (j = currentMaxClients; --j >= 0; )
if (clients[j])
FindClientResourcesByType(clients[j], RT_PASSIVEGRAB,
dmxBERestorePassiveGrab,
(pointer) &dmxInputs[i]);
}
/* Force completion of the changes */
dmxSync(NULL, TRUE);
}
@ -454,8 +482,6 @@ void dmxUpdateScreenResources(ScreenPtr pScreen, int x, int y, int w, int h)
}
#ifdef PANORAMIX
#include "panoramiXsrv.h"
/** Change the "screen" window attributes by resizing the actual window
* on the back-end display (if necessary). */
static void dmxConfigureScreenWindow(int idx,

View file

@ -28,113 +28,392 @@
#endif
#include "dmx.h"
#include "dmxinput.h"
#include "dmxgrab.h"
#include "windowstr.h"
#ifdef PANORAMIX
#include "panoramiX.h"
#include "panoramiXsrv.h"
#endif
unsigned long DMX_PASSIVEGRAB;
static int (*dmxSaveProcVector[256]) (ClientPtr);
static int
dmxProcGrabPointer (ClientPtr client)
void
dmxBEAddPassiveGrab (DMXInputInfo *dmxInput,
GrabPtr pGrab)
{
int err;
REQUEST(xGrabPointerReq);
WindowPtr pWin = pGrab->window;
WindowPtr pConfineTo = pGrab->confineTo;
(void) stuff;
if (dixLookupResource ((pointer *) &pGrab,
pGrab->resource,
DMX_PASSIVEGRAB,
serverClient,
DixReadAccess) != Success)
return;
err = (*dmxSaveProcVector[X_GrabPointer]) (client);
if (err != Success)
return err;
#ifdef PANORAMIX
if (!noPanoramiXExtension)
{
PanoramiXRes *win, *confineToWin;
return err;
if (!(win = (PanoramiXRes *)SecurityLookupIDByType(
serverClient, pWin->drawable.id, XRT_WINDOW,
DixGetAttrAccess)) ||
dixLookupWindow (&pWin,
win->info[dmxInput->scrnIdx].id,
serverClient,
DixGetAttrAccess) != Success)
return;
if (pGrab->confineTo)
if (!(confineToWin = (PanoramiXRes *)SecurityLookupIDByType(
serverClient, pGrab->confineTo->drawable.id, XRT_WINDOW,
DixGetAttrAccess)) ||
dixLookupWindow (&pConfineTo,
confineToWin->info[dmxInput->scrnIdx].id,
serverClient,
DixGetAttrAccess) != Success)
return;
}
else
#endif
if (dmxInput->scrnIdx != pWin->drawable.pScreen->myNum)
return;
(*dmxInput->grabButton) (dmxInput,
pGrab->device,
pGrab->modifierDevice,
pWin,
pConfineTo,
pGrab->detail.exact,
pGrab->modifiersDetail.exact,
pGrab->cursor);
}
static int
dmxProcUngrabPointer (ClientPtr client)
dmxFreePassiveGrab (pointer value,
XID id)
{
int err;
REQUEST(xResourceReq);
GrabPtr pGrab = (GrabPtr) value;
(void) stuff;
#ifdef PANORAMIX
PanoramiXRes *win = NULL;
#endif
err = (*dmxSaveProcVector[X_UngrabPointer]) (client);
if (err != Success)
return err;
WindowPtr pWin = pGrab->window;
int i;
return err;
#ifdef PANORAMIX
if (!noPanoramiXExtension)
{
if (!(win = (PanoramiXRes *)SecurityLookupIDByType(
serverClient, pWin->drawable.id, XRT_WINDOW,
DixGetAttrAccess)))
return Success;
}
#endif
for (i = 0; i < dmxNumInputs; i++)
{
DMXInputInfo *dmxInput = &dmxInputs[i];
if (dmxInput->detached)
continue;
if (dmxInput->scrnIdx < 0)
continue;
if (!dmxInput->ungrabButton)
continue;
#ifdef PANORAMIX
if (!noPanoramiXExtension)
dixLookupWindow (&pWin,
win->info[dmxInput->scrnIdx].id,
serverClient,
DixGetAttrAccess);
else
#endif
if (dmxInput->scrnIdx != pWin->drawable.pScreen->myNum)
continue;
(*dmxInput->ungrabButton) (dmxInput,
pGrab->device,
pGrab->modifierDevice,
pWin,
pGrab->detail.exact,
pGrab->modifiersDetail.exact);
}
return Success;
}
static void
dmxGrabPointer (DeviceIntPtr pDev,
GrabPtr pGrab)
{
#ifdef PANORAMIX
PanoramiXRes *win = NULL, *confineToWin = NULL;
#endif
WindowPtr pWin, pConfineTo = NULL;
int i;
#ifdef PANORAMIX
if (!noPanoramiXExtension)
{
if (!(win = (PanoramiXRes *)SecurityLookupIDByType(
serverClient, pGrab->window->drawable.id, XRT_WINDOW,
DixGetAttrAccess)))
return;
if (pGrab->confineTo)
if (!(confineToWin = (PanoramiXRes *)SecurityLookupIDByType(
serverClient, pGrab->confineTo->drawable.id,
XRT_WINDOW, DixGetAttrAccess)))
return;
}
#endif
for (i = 0; i < dmxNumInputs; i++)
{
DMXInputInfo *dmxInput = &dmxInputs[i];
if (dmxInput->detached)
continue;
if (dmxInput->scrnIdx < 0)
continue;
if (!dmxInput->grabPointer)
continue;
#ifdef PANORAMIX
if (!noPanoramiXExtension)
{
dixLookupWindow (&pWin,
win->info[dmxInput->scrnIdx].id,
serverClient,
DixGetAttrAccess);
if (confineToWin)
dixLookupWindow (&pConfineTo,
confineToWin->info[dmxInput->scrnIdx].id,
serverClient,
DixGetAttrAccess);
}
else
#endif
if (dmxInput->scrnIdx != pWin->drawable.pScreen->myNum)
continue;
(*dmxInput->grabPointer) (dmxInput,
pDev,
pWin,
pConfineTo,
pGrab->cursor);
}
}
static void
dmxUngrabPointer (DeviceIntPtr pDev,
GrabPtr pGrab)
{
#ifdef PANORAMIX
PanoramiXRes *win = NULL;
#endif
WindowPtr pWin;
int i;
#ifdef PANORAMIX
if (!noPanoramiXExtension)
{
if (!(win = (PanoramiXRes *)SecurityLookupIDByType(
serverClient, pGrab->window->drawable.id, XRT_WINDOW,
DixGetAttrAccess)))
return;
}
#endif
for (i = 0; i < dmxNumInputs; i++)
{
DMXInputInfo *dmxInput = &dmxInputs[i];
if (dmxInput->detached)
continue;
if (dmxInput->scrnIdx < 0)
continue;
if (!dmxInput->ungrabPointer)
continue;
#ifdef PANORAMIX
if (!noPanoramiXExtension)
{
dixLookupWindow (&pWin,
win->info[dmxInput->scrnIdx].id,
serverClient,
DixGetAttrAccess);
}
else
#endif
if (dmxInput->scrnIdx != pWin->drawable.pScreen->myNum)
continue;
(*dmxInput->ungrabPointer) (dmxInput, pDev, pWin);
}
}
void
dmxActivatePointerGrab (DeviceIntPtr pDev,
GrabPtr pGrab,
TimeStamp time,
Bool autoGrab)
{
dmxDevicePrivPtr pDevPriv = DMX_GET_DEVICE_PRIV (pDev);
dmxGrabPointer (pDev, pGrab);
DMX_UNWRAP (ActivateGrab, pDevPriv, &pDev->deviceGrab);
(*pDev->deviceGrab.ActivateGrab) (pDev, pGrab, time, autoGrab);
DMX_WRAP (ActivateGrab, dmxActivatePointerGrab, pDevPriv,
&pDev->deviceGrab);
}
void
dmxDeactivatePointerGrab (DeviceIntPtr pDev)
{
dmxDevicePrivPtr pDevPriv = DMX_GET_DEVICE_PRIV (pDev);
GrabPtr pGrab = pDev->deviceGrab.grab;
DMX_UNWRAP (DeactivateGrab, pDevPriv, &pDev->deviceGrab);
(*pDev->deviceGrab.DeactivateGrab) (pDev);
DMX_WRAP (DeactivateGrab, dmxDeactivatePointerGrab, pDevPriv,
&pDev->deviceGrab);
dmxUngrabPointer (pDev, pGrab);
}
static int
dmxProcGrabButton (ClientPtr client)
{
int err;
REQUEST(xGrabButtonReq);
GrabPtr pGrab;
(void) stuff;
#ifdef PANORAMIX
PanoramiXRes *win = NULL, *confineToWin = NULL;
#endif
WindowPtr pWin, pConfineTo = NULL;
int i, err;
REQUEST(xGrabButtonReq);
err = (*dmxSaveProcVector[X_GrabButton]) (client);
if (err != Success)
return err;
return err;
}
return Success; /* PASSIVE GRABS DISABLED */
static int
dmxProcUngrabButton (ClientPtr client)
{
int err;
REQUEST(xUngrabButtonReq);
dixLookupWindow(&pWin, stuff->grabWindow, client, DixSetAttrAccess);
pGrab = wPassiveGrabs (pWin);
(void) stuff;
pConfineTo = pGrab->confineTo;
err = (*dmxSaveProcVector[X_UngrabButton]) (client);
if (err != Success)
return err;
#ifdef PANORAMIX
if (!noPanoramiXExtension)
{
if (!(win = (PanoramiXRes *)SecurityLookupIDByType(
client, stuff->grabWindow, XRT_WINDOW, DixSetAttrAccess)))
return Success;
if (pConfineTo)
if (!(confineToWin = (PanoramiXRes *)SecurityLookupIDByType(
client, stuff->confineTo, XRT_WINDOW, DixSetAttrAccess)))
return Success;
}
#endif
return err;
for (i = 0; i < dmxNumInputs; i++)
{
DMXInputInfo *dmxInput = &dmxInputs[i];
if (dmxInput->detached)
continue;
if (dmxInput->scrnIdx < 0)
continue;
if (!dmxInput->grabButton)
continue;
#ifdef PANORAMIX
if (!noPanoramiXExtension)
{
dixLookupWindow (&pWin,
win->info[dmxInput->scrnIdx].id,
client,
DixSetAttrAccess);
if (confineToWin)
dixLookupWindow (&pConfineTo,
confineToWin->info[dmxInput->scrnIdx].id,
client,
DixSetAttrAccess);
}
else
#endif
if (dmxInput->scrnIdx != pWin->drawable.pScreen->myNum)
continue;
(*dmxInput->grabButton) (dmxInput,
pGrab->device,
pGrab->modifierDevice,
pWin,
pConfineTo,
pGrab->detail.exact,
pGrab->modifiersDetail.exact,
pGrab->cursor);
}
AddResource (pGrab->resource, DMX_PASSIVEGRAB, pGrab);
return Success;
}
static int
dmxProcChangeActivePointerGrab (ClientPtr client)
{
int err;
REQUEST(xChangeActivePointerGrabReq);
(void) stuff;
DeviceIntPtr pDev;
GrabPtr pGrab;
int err;
err = (*dmxSaveProcVector[X_ChangeActivePointerGrab]) (client);
if (err != Success)
return err;
return err;
}
pDev = PickPointer (client);
pGrab = pDev->deviceGrab.grab;
if (pGrab)
dmxGrabPointer (pDev, pGrab);
static int
dmxProcAllowEvents (ClientPtr client)
{
int err;
REQUEST(xAllowEventsReq);
(void) stuff;
err = (*dmxSaveProcVector[X_AllowEvents]) (client);
if (err != Success)
return err;
return err;
return Success;
}
void dmxInitGrabs (void)
{
int i;
DMX_PASSIVEGRAB = CreateNewResourceType (dmxFreePassiveGrab);
for (i = 0; i < 256; i++)
dmxSaveProcVector[i] = ProcVector[i];
ProcVector[X_GrabPointer] = dmxProcGrabPointer;
ProcVector[X_UngrabPointer] = dmxProcUngrabPointer;
ProcVector[X_GrabButton] = dmxProcGrabButton;
ProcVector[X_UngrabButton] = dmxProcUngrabButton;
ProcVector[X_ChangeActivePointerGrab] = dmxProcChangeActivePointerGrab;
ProcVector[X_AllowEvents] = dmxProcAllowEvents;
}
void dmxResetGrabs (void)

View file

@ -26,6 +26,17 @@
#ifndef DMXGRAB_H
#define DMXGRAB_H
#include "dmxinput.h"
extern void dmxBEAddPassiveGrab (DMXInputInfo *dmxInput,
GrabPtr pGrab);
extern void dmxActivatePointerGrab (DeviceIntPtr pDev,
GrabPtr pGrab,
TimeStamp time,
Bool autoGrab);
extern void dmxDeactivatePointerGrab (DeviceIntPtr pDev);
extern void dmxInitGrabs (void);
extern void dmxResetGrabs (void);

View file

@ -47,6 +47,18 @@
#ifndef DMXINPUT_H
#define DMXINPUT_H
extern DevPrivateKey dmxDevicePrivateKey;
/** Device private area. */
typedef struct _dmxDevicePriv {
void (*ActivateGrab) (DeviceIntPtr, GrabPtr, TimeStamp, Bool);
void (*DeactivateGrab) (DeviceIntPtr);
} dmxDevicePrivRec, *dmxDevicePrivPtr;
#define DMX_GET_DEVICE_PRIV(_pDev) \
((dmxDevicePrivPtr)dixLookupPrivate(&(_pDev)->devPrivates, \
dmxDevicePrivateKey))
#define DMX_XINPUT_EVENT_NUM 18
/** Maximum number of file descriptors for SIGIO handling */
@ -67,6 +79,28 @@ typedef enum {
typedef void (*ProcessInputEventsProc)(struct _DMXInputInfo *);
typedef void (*UpdateWindowInfoProc)(struct _DMXInputInfo *,
DMXUpdateType, WindowPtr);
typedef void (*GrabButtonProc)(struct _DMXInputInfo *,
DeviceIntPtr pDevice,
DeviceIntPtr pModDevice,
WindowPtr pWindow,
WindowPtr pConfineTo,
int button,
int modifiers,
CursorPtr pCursor);
typedef void (*UngrabButtonProc)(struct _DMXInputInfo *,
DeviceIntPtr pDevice,
DeviceIntPtr pModDevice,
WindowPtr pWindow,
int button,
int modifiers);
typedef void (*GrabPointerProc) (struct _DMXInputInfo *,
DeviceIntPtr pDevice,
WindowPtr pWindow,
WindowPtr pConfineTo,
CursorPtr pCursor);
typedef void (*UngrabPointerProc) (struct _DMXInputInfo *,
DeviceIntPtr pDevice,
WindowPtr pWindow);
/** An opaque structure that is only exposed in the dmx/input layer. */
typedef struct _DMXLocalInputInfo *DMXLocalInputInfoPtr;
@ -103,6 +137,10 @@ struct _DMXInputInfo {
ProcessInputEventsProc processInputEvents;
UpdateWindowInfoProc updateWindowInfo;
GrabButtonProc grabButton;
UngrabButtonProc ungrabButton;
GrabPointerProc grabPointer;
UngrabPointerProc ungrabPointer;
/* Local input information */
dmxSigioState sigioState; /**< Current stat */

View file

@ -146,6 +146,8 @@ static int dmxScreenPrivateKeyIndex;
DevPrivateKey dmxScreenPrivateKey = &dmxScreenPrivateKeyIndex; /**< Private index for Screens */
static int dmxColormapPrivateKeyIndex;
DevPrivateKey dmxColormapPrivateKey = &dmxColormapPrivateKeyIndex; /**< Private index for Colormaps */
static int dmxDevicePrivateKeyIndex;
DevPrivateKey dmxDevicePrivateKey = &dmxDevicePrivateKeyIndex; /**< Private index for Devices */
#ifdef RENDER
static int dmxPictPrivateKeyIndex;
DevPrivateKey dmxPictPrivateKey = &dmxPictPrivateKeyIndex; /**< Private index for Picts */

View file

@ -47,6 +47,7 @@
#include "dmxcommon.h"
#include "dmxconsole.h"
#include "dmxcursor.h"
#include "dmxwindow.h"
#include "dmxprop.h"
#include "dmxsync.h"
#include "dmxxlibio.h"
@ -193,10 +194,11 @@ static Bool inputEventPredicate (Display *xdisplay,
XDeviceMotionEvent *dmev = (XDeviceMotionEvent *) X;
XMotionEvent *mev = (XMotionEvent *) data->X;
mev->type = MotionNotify;
mev->x = dmev->x;
mev->y = dmev->y;
mev->state = dmev->state;
mev->type = MotionNotify;
mev->x = dmev->x;
mev->y = dmev->y;
mev->state = dmev->state;
mev->window = dmev->window;
} break;
case XI_DeviceButtonPress: {
XDeviceButtonEvent *dbev = (XDeviceButtonEvent *) X;
@ -207,6 +209,7 @@ static Bool inputEventPredicate (Display *xdisplay,
bev->x = dbev->x;
bev->y = dbev->y;
bev->state = dbev->state;
bev->window = dbev->window;
} break;
case XI_DeviceButtonRelease: {
XDeviceButtonEvent *dbev = (XDeviceButtonEvent *) X;
@ -217,6 +220,7 @@ static Bool inputEventPredicate (Display *xdisplay,
bev->x = dbev->x;
bev->y = dbev->y;
bev->state = dbev->state;
bev->window = dbev->window;
} break;
case XI_DeviceKeyPress: {
XDeviceKeyEvent *dkev = (XDeviceKeyEvent *) X;
@ -684,6 +688,177 @@ void dmxBackendProcessInput(pointer private)
}
}
void dmxBackendGrabButton(DevicePtr pDev,
DevicePtr pModDev,
WindowPtr pWindow,
WindowPtr pConfineTo,
int button,
int modifiers,
CursorPtr pCursor)
{
GETPRIVFROMPDEV;
GETDMXINPUTFROMPRIV;
ScreenPtr pScreen = screenInfo.screens[dmxInput->scrnIdx];
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
Window confineTo = None;
Cursor cursor = None;
if (pConfineTo)
confineTo = (DMX_GET_WINDOW_PRIV (pConfineTo))->window;
if (pCursor)
cursor = (DMX_GET_CURSOR_PRIV (pCursor, pScreen))->cursor;
if (dmxLocal->deviceId >= 0)
{
XDevice *modDev = NULL;
if (pModDev)
modDev = ((DMXLocalInputInfoPtr) pModDev->devicePrivate)->device;
/* this is really useless as XGrabDeviceButton doesn't allow us
to specify a confineTo window or cursor */
XLIB_PROLOGUE (dmxScreen);
XGrabDeviceButton (dmxScreen->beDisplay,
dmxLocal->device,
button,
modifiers,
modDev,
(DMX_GET_WINDOW_PRIV (pWindow))->window,
TRUE,
0,
NULL,
GrabModeAsync,
GrabModeAsync);
XLIB_EPILOGUE (dmxScreen);
}
else
{
XLIB_PROLOGUE (dmxScreen);
XGrabButton (dmxScreen->beDisplay,
button,
modifiers,
(DMX_GET_WINDOW_PRIV (pWindow))->window,
TRUE,
0,
GrabModeAsync,
GrabModeAsync,
confineTo,
cursor);
XLIB_EPILOGUE (dmxScreen);
}
}
void dmxBackendUngrabButton(DevicePtr pDev,
DevicePtr pModDev,
WindowPtr pWindow,
int button,
int modifiers)
{
GETPRIVFROMPDEV;
GETDMXINPUTFROMPRIV;
ScreenPtr pScreen = screenInfo.screens[dmxInput->scrnIdx];
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
if (dmxLocal->deviceId >= 0)
{
XDevice *modDev = NULL;
if (pModDev)
modDev = ((DMXLocalInputInfoPtr) pModDev->devicePrivate)->device;
XLIB_PROLOGUE (dmxScreen);
XUngrabDeviceButton (dmxScreen->beDisplay,
dmxLocal->device,
button,
modifiers,
modDev,
(DMX_GET_WINDOW_PRIV (pWindow))->window);
XLIB_EPILOGUE (dmxScreen);
}
else
{
XLIB_PROLOGUE (dmxScreen);
XUngrabButton (dmxScreen->beDisplay,
button,
modifiers,
(DMX_GET_WINDOW_PRIV (pWindow))->window);
XLIB_EPILOGUE (dmxScreen);
}
}
void dmxBackendGrabPointer(DevicePtr pDev,
WindowPtr pWindow,
WindowPtr pConfineTo,
CursorPtr pCursor)
{
GETPRIVFROMPDEV;
GETDMXINPUTFROMPRIV;
ScreenPtr pScreen = screenInfo.screens[dmxInput->scrnIdx];
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
Window confineTo = None;
Cursor cursor = None;
if (pConfineTo)
confineTo = (DMX_GET_WINDOW_PRIV (pConfineTo))->window;
if (pCursor)
cursor = (DMX_GET_CURSOR_PRIV (pCursor, pScreen))->cursor;
if (dmxLocal->deviceId >= 0)
{
XLIB_PROLOGUE (dmxScreen);
XExtendedGrabDevice (dmxScreen->beDisplay,
dmxLocal->device,
(DMX_GET_WINDOW_PRIV (pWindow))->window,
GrabModeAsync,
TRUE,
confineTo,
cursor,
0,
NULL,
0,
NULL);
XLIB_EPILOGUE (dmxScreen);
}
else
{
XLIB_PROLOGUE (dmxScreen);
XGrabPointer (dmxScreen->beDisplay,
(DMX_GET_WINDOW_PRIV (pWindow))->window,
TRUE,
0,
GrabModeAsync,
GrabModeAsync,
confineTo,
cursor,
CurrentTime);
XLIB_EPILOGUE (dmxScreen);
}
}
void dmxBackendUngrabPointer(DevicePtr pDev,
WindowPtr pWindow)
{
GETPRIVFROMPDEV;
GETDMXINPUTFROMPRIV;
ScreenPtr pScreen = screenInfo.screens[dmxInput->scrnIdx];
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
if (dmxLocal->deviceId >= 0)
{
XLIB_PROLOGUE (dmxScreen);
XUngrabDevice (dmxScreen->beDisplay, dmxLocal->device, CurrentTime);
XLIB_EPILOGUE (dmxScreen);
}
else
{
XLIB_PROLOGUE (dmxScreen);
XUngrabPointer (dmxScreen->beDisplay, CurrentTime);
XLIB_EPILOGUE (dmxScreen);
}
}
static void dmxBackendComputeCenter(myPrivate *priv)
{
int centerX;

View file

@ -52,6 +52,24 @@ 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 dmxBackendGrabButton(DevicePtr pDev,
DevicePtr pModDev,
WindowPtr pWindow,
WindowPtr pConfineTo,
int button,
int modifiers,
CursorPtr pCursor);
extern void dmxBackendUngrabButton(DevicePtr pDev,
DevicePtr pModDev,
WindowPtr pWindow,
int button,
int modifiers);
extern void dmxBackendGrabPointer(DevicePtr pDevice,
WindowPtr pWindow,
WindowPtr pConfineTo,
CursorPtr pCursor);
extern void dmxBackendUngrabPointer(DevicePtr pDevice,
WindowPtr pWindow);
extern void dmxBackendKbdOff(DevicePtr pDev);
#endif

View file

@ -296,17 +296,21 @@ int dmxCommonKbdOn(DevicePtr pDev)
{
XEventClass cls[3];
if (!(priv->xi = XOpenDevice (priv->display, dmxLocal->deviceId))) {
if (!(dmxLocal->device = XOpenDevice (priv->display,
dmxLocal->deviceId))) {
dmxLog(dmxWarning, "Cannot open %s device (id=%d) on %s\n",
dmxLocal->deviceName ? dmxLocal->deviceName : "(unknown)",
dmxLocal->deviceId, dmxInput->name);
return -1;
}
DeviceKeyPress (priv->xi, dmxInput->event[XI_DeviceKeyPress], cls[0]);
DeviceKeyRelease (priv->xi, dmxInput->event[XI_DeviceKeyRelease],
DeviceKeyPress (dmxLocal->device,
dmxInput->event[XI_DeviceKeyPress],
cls[0]);
DeviceKeyRelease (dmxLocal->device,
dmxInput->event[XI_DeviceKeyRelease],
cls[1]);
DeviceStateNotify (priv->xi,
DeviceStateNotify (dmxLocal->device,
dmxInput->event[XI_DeviceStateNotify],
cls[2]);
@ -315,8 +319,8 @@ int dmxCommonKbdOn(DevicePtr pDev)
XLIB_EPILOGUE (priv->be);
XLIB_PROLOGUE (priv->be);
XSetInputFocus(priv->display, priv->window, RevertToPointerRoot,
CurrentTime);
XSetDeviceFocus(priv->display, dmxLocal->device, priv->window,
RevertToPointerRoot, CurrentTime);
XLIB_EPILOGUE (priv->be);
}
else
@ -338,10 +342,10 @@ int dmxCommonKbdOn(DevicePtr pDev)
void dmxCommonKbdOff(DevicePtr pDev)
{
GETPRIVFROMPDEV;
if (priv->xi)
if (dmxLocal->device)
{
XCloseDevice(priv->display, priv->xi);
priv->xi = NULL;
XCloseDevice(priv->display, dmxLocal->device);
dmxLocal->device = NULL;
}
else
{
@ -531,27 +535,32 @@ int dmxCommonMouOn(DevicePtr pDev)
if (priv->be && dmxLocal->deviceId >= 0)
{
XEventClass cls[4];
XEventClass cls[5];
if (!(priv->xi = XOpenDevice (priv->display, dmxLocal->deviceId))) {
if (!(dmxLocal->device = XOpenDevice (priv->display,
dmxLocal->deviceId))) {
dmxLog(dmxWarning, "Cannot open %s device (id=%d) on %s\n",
dmxLocal->deviceName ? dmxLocal->deviceName : "(unknown)",
dmxLocal->deviceId, dmxInput->name);
return -1;
}
DeviceMotionNotify (priv->xi, dmxInput->event[XI_DeviceMotionNotify],
DeviceMotionNotify (dmxLocal->device,
dmxInput->event[XI_DeviceMotionNotify],
cls[0]);
DeviceButtonPress (priv->xi, dmxInput->event[XI_DeviceButtonPress],
DeviceButtonPress (dmxLocal->device,
dmxInput->event[XI_DeviceButtonPress],
cls[1]);
DeviceButtonRelease (priv->xi, dmxInput->event[XI_DeviceButtonRelease],
DeviceButtonRelease (dmxLocal->device,
dmxInput->event[XI_DeviceButtonRelease],
cls[2]);
DeviceStateNotify (priv->xi,
DeviceButtonPressGrab (dmxLocal->device, 0, cls[3]);
DeviceStateNotify (dmxLocal->device,
dmxInput->event[XI_DeviceStateNotify],
cls[3]);
cls[4]);
XLIB_PROLOGUE (priv->be);
XSelectExtensionEvent(priv->display, priv->window, cls, 4);
XSelectExtensionEvent(priv->display, priv->window, cls, 5);
XLIB_EPILOGUE (priv->be);
}
else
@ -585,10 +594,10 @@ void dmxCommonMouOff(DevicePtr pDev)
GETPRIVFROMPDEV;
GETDMXINPUTFROMPRIV;
if (priv->xi)
if (dmxLocal->device)
{
XCloseDevice(priv->display, priv->xi);
priv->xi = NULL;
XCloseDevice(priv->display, dmxLocal->device);
dmxLocal->device = NULL;
}
else
{

View file

@ -106,6 +106,8 @@ static DMXLocalInputInfoRec DMXBackendMou = {
dmxCommonMouOn, dmxCommonMouOff, dmxBackendUpdatePosition,
NULL, NULL, NULL,
dmxBackendCollectEvents, dmxBackendProcessInput, dmxBackendFunctions, NULL,
dmxBackendGrabButton, dmxBackendUngrabButton,
dmxBackendGrabPointer, dmxBackendUngrabPointer,
dmxCommonMouCtrl
};
@ -117,6 +119,8 @@ static DMXLocalInputInfoRec DMXBackendKbd = {
dmxCommonKbdOn, dmxBackendKbdOff, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL, dmxCommonKbdCtrl, dmxCommonKbdBell
};
@ -126,7 +130,10 @@ static DMXLocalInputInfoRec DMXConsoleMou = {
dmxConsoleInit, dmxConsoleReInit, NULL, dmxConsoleMouGetInfo,
dmxCommonMouOn, dmxCommonMouOff, dmxConsoleUpdatePosition,
NULL, NULL, NULL,
dmxConsoleCollectEvents, NULL, dmxConsoleFunctions, dmxConsoleUpdateInfo,
dmxConsoleCollectEvents, NULL,
dmxConsoleFunctions, dmxConsoleUpdateInfo,
NULL, NULL,
NULL, NULL,
dmxCommonMouCtrl
};
@ -137,8 +144,10 @@ static DMXLocalInputInfoRec DMXConsoleKbd = {
dmxConsoleInit, dmxConsoleReInit, NULL, dmxConsoleKbdGetInfo,
dmxCommonKbdOn, dmxCommonKbdOff, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, dmxCommonKbdCtrl, dmxCommonKbdBell
NULL, NULL, NULL, NULL, NULL,
NULL, NULL,
NULL, NULL,
dmxCommonKbdCtrl, dmxCommonKbdBell
};
static DMXLocalInputInfoRec DMXCommonOth = {
@ -159,8 +168,10 @@ static DMXLocalInputInfoRec DMXLocalDevices[] = {
kbdLinuxInit, NULL, NULL, kbdLinuxGetInfo,
kbdLinuxOn, kbdLinuxOff, NULL,
kbdLinuxVTPreSwitch, kbdLinuxVTPostSwitch, kbdLinuxVTSwitch,
kbdLinuxRead, NULL, NULL, NULL,
NULL, kbdLinuxCtrl, kbdLinuxBell
kbdLinuxRead, NULL, NULL, NULL, NULL,
NULL, NULL,
NULL, NULL,
kbdLinuxCtrl, kbdLinuxBell
},
{
"ms", DMX_LOCAL_MOUSE, DMX_LOCAL_TYPE_LOCAL, 1,
@ -189,8 +200,10 @@ static DMXLocalInputInfoRec DMXLocalDevices[] = {
kbdUSBInit, NULL, NULL, kbdUSBGetInfo,
kbdUSBOn, usbOff, NULL,
NULL, NULL, NULL,
kbdUSBRead, NULL, NULL, NULL,
NULL, kbdUSBCtrl
kbdUSBRead, NULL, NULL, NULL, NULL,
NULL, NULL,
NULL, NULL,
kbdUSBCtrl
},
{
"usb-mou", DMX_LOCAL_MOUSE, DMX_LOCAL_TYPE_LOCAL, 1,
@ -575,6 +588,145 @@ static void dmxProcessInputEvents(DMXInputInfo *dmxInput)
}
}
static void dmxGrabButton(DMXInputInfo *dmxInput,
DeviceIntPtr pDevice,
DeviceIntPtr pModDevice,
WindowPtr pWindow,
WindowPtr pConfineTo,
int button,
int modifiers,
CursorPtr pCursor)
{
int i, j;
for (i = 0; i < dmxInput->numDevs; i++)
{
DevicePtr pDev = &dmxInput->devs[i]->pDevice->public;
if (dmxInput->devs[i]->pDevice->u.master != pDevice)
continue;
if (!dmxInput->devs[i]->grab_button)
continue;
if (modifiers & AnyModifier)
{
(*dmxInput->devs[i]->grab_button) (pDev,
NULL,
pWindow,
pConfineTo,
button,
modifiers,
pCursor);
}
else
{
for (j = 0; j < dmxInput->numDevs; j++)
{
DevicePtr pModDev = &dmxInput->devs[j]->pDevice->public;
if (dmxInput->devs[j]->pDevice->u.master == pModDevice)
(*dmxInput->devs[i]->grab_button) (pDev,
pModDev,
pWindow,
pConfineTo,
button,
modifiers,
pCursor);
}
}
}
}
static void dmxUngrabButton(DMXInputInfo *dmxInput,
DeviceIntPtr pDevice,
DeviceIntPtr pModDevice,
WindowPtr pWindow,
int button,
int modifiers)
{
int i, j;
for (i = 0; i < dmxInput->numDevs; i++)
{
DevicePtr pDev = &dmxInput->devs[i]->pDevice->public;
if (dmxInput->devs[i]->pDevice->u.master != pDevice)
continue;
if (!dmxInput->devs[i]->ungrab_button)
continue;
if (modifiers == AnyModifier)
{
(*dmxInput->devs[i]->ungrab_button) (pDev,
NULL,
pWindow,
button,
modifiers);
}
else
{
for (j = 0; j < dmxInput->numDevs; j++)
{
DevicePtr pModDev = &dmxInput->devs[j]->pDevice->public;
if (dmxInput->devs[j]->pDevice->u.master == pModDevice)
(*dmxInput->devs[i]->ungrab_button) (pDev,
pModDev,
pWindow,
button,
modifiers);
}
}
}
}
static void dmxGrabPointer (DMXInputInfo *dmxInput,
DeviceIntPtr pDevice,
WindowPtr pWindow,
WindowPtr pConfineTo,
CursorPtr pCursor)
{
int i;
for (i = 0; i < dmxInput->numDevs; i++)
{
DevicePtr pDev = &dmxInput->devs[i]->pDevice->public;
if (dmxInput->devs[i]->pDevice->u.master != pDevice)
continue;
if (!dmxInput->devs[i]->grab_pointer)
continue;
(*dmxInput->devs[i]->grab_pointer) (pDev,
pWindow,
pConfineTo,
pCursor);
}
}
static void dmxUngrabPointer (DMXInputInfo *dmxInput,
DeviceIntPtr pDevice,
WindowPtr pWindow)
{
int i;
for (i = 0; i < dmxInput->numDevs; i++)
{
DevicePtr pDev = &dmxInput->devs[i]->pDevice->public;
if (dmxInput->devs[i]->pDevice->u.master != pDevice)
continue;
if (!dmxInput->devs[i]->ungrab_pointer)
continue;
(*dmxInput->devs[i]->ungrab_pointer) (pDev, pWindow);
}
}
static void dmxUpdateWindowInformation(DMXInputInfo *dmxInput,
DMXUpdateType type,
WindowPtr pWindow)
@ -1112,6 +1264,10 @@ void dmxInputInit(DMXInputInfo *dmxInput)
}
dmxInput->processInputEvents = dmxProcessInputEvents;
dmxInput->grabButton = dmxGrabButton;
dmxInput->ungrabButton = dmxUngrabButton;
dmxInput->grabPointer = dmxGrabPointer;
dmxInput->ungrabPointer = dmxUngrabPointer;
dmxInput->detached = False;
RegisterBlockAndWakeupHandlers(dmxBlockHandler,
@ -1290,28 +1446,7 @@ DMXInputInfo *dmxInputLocateId(int id)
return NULL;
}
static int dmxInputAttachNew(DMXInputInfo *dmxInput, int *id)
{
int i;
dmxInputInit(dmxInput);
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;
}
static int dmxInputAttachOld(DMXInputInfo *dmxInput, int *id)
static int dmxInputAttach(DMXInputInfo *dmxInput, int *id)
{
int i;
@ -1344,7 +1479,7 @@ int dmxInputAttachConsole(const char *name, int isCore, int *id)
&& !strcmp(dmxInput->name, name)) {
/* Found match */
dmxLogInput(dmxInput, "Reattaching detached console input\n");
return dmxInputAttachOld(dmxInput, id);
return dmxInputAttach(dmxInput, id);
}
}
@ -1352,7 +1487,7 @@ int dmxInputAttachConsole(const char *name, int isCore, int *id)
dmxInput = dmxConfigAddInput(xstrdup(name), isCore);
dmxInput->freename = TRUE;
dmxLogInput(dmxInput, "Attaching new console input\n");
return dmxInputAttachNew(dmxInput, id);
return dmxInputAttach(dmxInput, id);
}
int dmxInputAttachBackend(int physicalScreen, int isCore, int *id)
@ -1370,7 +1505,7 @@ int dmxInputAttachBackend(int physicalScreen, int isCore, int *id)
dmxScreen = &dmxScreens[physicalScreen];
if (!dmxScreen->beDisplay) return BadAccess; /* Screen detached */
dmxLogInput(dmxInput, "Reattaching detached backend input\n");
return dmxInputAttachOld(dmxInput, id);
return dmxInputAttach(dmxInput, id);
}
}
/* No match found */
@ -1380,5 +1515,5 @@ int dmxInputAttachBackend(int physicalScreen, int isCore, int *id)
dmxInput->freename = TRUE;
dmxInput->scrnIdx = physicalScreen;
dmxLogInput(dmxInput, "Attaching new backend input\n");
return dmxInputAttachNew(dmxInput, id);
return dmxInputAttach(dmxInput, id);
}

View file

@ -165,6 +165,24 @@ typedef void (*dmxCollectEventsProcPtr)(DevicePtr,
typedef void (*dmxProcessInputProcPtr)(pointer);
typedef void (*dmxUpdateInfoProcPtr)(pointer, DMXUpdateType, WindowPtr);
typedef int (*dmxFunctionsProcPtr)(pointer, DMXFunctionType);
typedef void (*dmxGrabButtonProcPtr)(DevicePtr,
DevicePtr,
WindowPtr,
WindowPtr,
int,
int,
CursorPtr);
typedef void (*dmxUngrabButtonProcPtr)(DevicePtr,
DevicePtr,
WindowPtr,
int,
int);
typedef void (*dmxGrabPointerProcPtr) (DevicePtr,
WindowPtr,
WindowPtr,
CursorPtr);
typedef void (*dmxUngrabPointerProcPtr) (DevicePtr,
WindowPtr);
typedef void (*dmxKBCtrlProcPtr)(DevicePtr, KeybdCtrl *ctrl);
typedef void (*dmxMCtrlProcPtr)(DevicePtr, PtrCtrl *ctrl);
@ -223,6 +241,10 @@ typedef struct _DMXLocalInputInfo {
dmxFunctionsProcPtr functions;
dmxUpdateInfoProcPtr update_info; /**< Update window layout
* information */
dmxGrabButtonProcPtr grab_button; /**< Grab button */
dmxUngrabButtonProcPtr ungrab_button; /**< Ungrab button */
dmxGrabPointerProcPtr grab_pointer; /**< Grab pointer */
dmxUngrabPointerProcPtr ungrab_pointer; /**< Ungrab pointer */
dmxMCtrlProcPtr mCtrl; /**< Pointer control */
dmxKBCtrlProcPtr kCtrl; /**< Keyboard control */
@ -268,6 +290,7 @@ typedef struct _DMXLocalInputInfo {
long attached; /**< the master device this device
* is attached to */
XDevice *device;
char state[32]; /**< Key/Button state */
} DMXLocalInputInfoRec;