summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Reveman <davidr@novell.com>2008-11-11 11:34:57 -0500
committerDavid Reveman <davidr@novell.com>2008-11-11 11:34:57 -0500
commit5946cdf71abc7e2f1390e4badea93b0a8e086045 (patch)
tree79dfd34f9ebbfda5d59bd88e9fac34c5bac3e95f
parentb27fbaf53e4ba0ac7bc3da78bd6b1d26349d9f7c (diff)
Fix input device grab handling.
- only try to grab back-end server devices when they are active - try to establish existing grab when device becomes active
-rw-r--r--hw/dmx/dmxinput.c141
-rw-r--r--hw/dmx/dmxinput.h1
2 files changed, 123 insertions, 19 deletions
diff --git a/hw/dmx/dmxinput.c b/hw/dmx/dmxinput.c
index 776282051..3964b1536 100644
--- a/hw/dmx/dmxinput.c
+++ b/hw/dmx/dmxinput.c
@@ -44,6 +44,11 @@
#include "XIstubs.h"
#include "xace.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
#include <X11/keysym.h>
#include <xcb/xinput.h>
@@ -585,6 +590,9 @@ dmxDeviceGrabKeyboard (DeviceIntPtr pDevice,
DMXScreenInfo *dmxScreen = (DMXScreenInfo *) pDevPriv->dmxInput;
Window window = (DMX_GET_WINDOW_PRIV (pWindow))->window;
+ if (pDevPriv->grabStatus != XCB_GRAB_STATUS_SUCCESS && !pDevPriv->active)
+ return;
+
if (pDevPriv->deviceId >= 0)
{
dmx_xcb_input_extended_grab_device_request_t grab = {
@@ -649,6 +657,8 @@ dmxDeviceUngrabKeyboard (DeviceIntPtr pDevice)
{
xcb_ungrab_keyboard (dmxScreen->connection, 0);
}
+
+ pDevPriv->grabStatus = !XCB_GRAB_STATUS_SUCCESS;
}
static Bool
@@ -660,8 +670,6 @@ dmxDeviceKeyboardReplyCheck (DeviceIntPtr pDevice,
if (request == pDevPriv->grab.sequence)
{
- xcb_grab_status_t status = XCB_GRAB_STATUS_FROZEN;
-
if (reply)
{
if (pDevPriv->deviceId >= 0)
@@ -669,22 +677,17 @@ dmxDeviceKeyboardReplyCheck (DeviceIntPtr pDevice,
xcb_input_grab_device_reply_t *xgrab =
(xcb_input_grab_device_reply_t *) reply;
- status = xgrab->status;
+ pDevPriv->grabStatus = xgrab->status;
}
else
{
xcb_grab_keyboard_reply_t *xgrab =
(xcb_grab_keyboard_reply_t *) reply;
- status = xgrab->status;
+ pDevPriv->grabStatus = xgrab->status;
}
}
- if (status == XCB_GRAB_STATUS_SUCCESS)
- {
- /* TODO: track state of grabs */
- }
-
pDevPriv->grab.sequence = 0;
return TRUE;
}
@@ -705,6 +708,9 @@ dmxDeviceGrabPointer (DeviceIntPtr pDevice,
Window confineTo = None;
Cursor cursor = None;
+ if (pDevPriv->grabStatus != XCB_GRAB_STATUS_SUCCESS && !pDevPriv->active)
+ return;
+
if (pConfineTo)
confineTo = (DMX_GET_WINDOW_PRIV (pConfineTo))->window;
@@ -781,6 +787,8 @@ dmxDeviceUngrabPointer (DeviceIntPtr pDevice)
{
xcb_ungrab_pointer (dmxScreen->connection, 0);
}
+
+ pDevPriv->grabStatus = !XCB_GRAB_STATUS_SUCCESS;
}
static Bool
@@ -792,8 +800,6 @@ dmxDevicePointerReplyCheck (DeviceIntPtr pDevice,
if (request == pDevPriv->grab.sequence)
{
- xcb_grab_status_t status = XCB_GRAB_STATUS_FROZEN;
-
if (reply->response_type == 1)
{
if (pDevPriv->deviceId >= 0)
@@ -801,22 +807,17 @@ dmxDevicePointerReplyCheck (DeviceIntPtr pDevice,
xcb_input_grab_device_reply_t *xgrab =
(xcb_input_grab_device_reply_t *) reply;
- status = xgrab->status;
+ pDevPriv->grabStatus = xgrab->status;
}
else
{
xcb_grab_pointer_reply_t *xgrab =
(xcb_grab_pointer_reply_t *) reply;
- status = xgrab->status;
+ pDevPriv->grabStatus = xgrab->status;
}
}
- if (status == XCB_GRAB_STATUS_SUCCESS)
- {
- /* TODO: track state of grabs */
- }
-
pDevPriv->grab.sequence = 0;
return TRUE;
}
@@ -828,11 +829,70 @@ static void
dmxDevicePointerActivate (DeviceIntPtr pDevice)
{
dmxDevicePrivPtr pDevPriv = DMX_GET_DEVICE_PRIV (pDevice);
+ DMXScreenInfo *dmxScreen = (DMXScreenInfo *) pDevPriv->dmxInput;
if (pDevPriv->active)
return;
pDevPriv->active = TRUE;
+
+ if (pDevPriv->grabStatus != XCB_GRAB_STATUS_SUCCESS &&
+ pDevPriv->grab.sequence == 0)
+ {
+ DeviceIntPtr pMaster = pDevice;
+
+ if (!pDevice->isMaster && pDevice->u.master)
+ pMaster = pDevice->u.master;
+
+ if (pMaster->deviceGrab.grab)
+ {
+ GrabPtr pGrab = pMaster->deviceGrab.grab;
+ WindowPtr pWin, pConfineTo = NULL;
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension)
+ {
+ PanoramiXRes *win, *confineToWin = NULL;
+ int i = dmxScreen->index;
+
+ 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;
+
+ if (dixLookupWindow (&pWin,
+ win->info[i].id,
+ serverClient,
+ DixGetAttrAccess) != Success)
+ return;
+
+ if (confineToWin)
+ if (dixLookupWindow (&pConfineTo,
+ confineToWin->info[i].id,
+ serverClient,
+ DixGetAttrAccess) != Success)
+ return;
+ }
+ else
+#endif
+ {
+ pWin = pGrab->window;
+ pConfineTo = pGrab->confineTo;
+ }
+
+ dmxDeviceGrabPointer (pDevice,
+ pWin,
+ pConfineTo,
+ pGrab->cursor);
+ }
+ }
}
static void
@@ -898,10 +958,10 @@ dmxUpdateSpriteFromEvent (DeviceIntPtr pDevice,
y += pWin->drawable.y;
}
- dmxDevicePointerActivate (pDevice);
dmxEndFakeMotion (&dmxScreen->input);
dmxBEDnDSpriteUpdate (pScreen, event, rootX, rootY);
dmxUpdateSpritePosition (pDevice, x, y);
+ dmxDevicePointerActivate (pDevice);
}
static Bool
@@ -1052,11 +1112,53 @@ static void
dmxDeviceKeyboardActivate (DeviceIntPtr pDevice)
{
dmxDevicePrivPtr pDevPriv = DMX_GET_DEVICE_PRIV (pDevice);
+ DMXScreenInfo *dmxScreen = (DMXScreenInfo *) pDevPriv->dmxInput;
if (pDevPriv->active)
return;
pDevPriv->active = TRUE;
+
+ if (pDevPriv->grabStatus != XCB_GRAB_STATUS_SUCCESS &&
+ pDevPriv->grab.sequence == 0)
+ {
+ DeviceIntPtr pMaster = pDevice;
+
+ if (!pDevice->isMaster && pDevice->u.master)
+ pMaster = pDevice->u.master;
+
+ if (pMaster->deviceGrab.grab)
+ {
+ GrabPtr pGrab = pMaster->deviceGrab.grab;
+ WindowPtr pWin;
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension)
+ {
+ PanoramiXRes *win;
+ int i = dmxScreen->index;
+
+ if (!(win = (PanoramiXRes *)
+ SecurityLookupIDByType(
+ serverClient, pGrab->window->drawable.id, XRT_WINDOW,
+ DixGetAttrAccess)))
+ return;
+
+ if (dixLookupWindow (&pWin,
+ win->info[i].id,
+ serverClient,
+ DixGetAttrAccess) != Success)
+ return;
+ }
+ else
+#endif
+ {
+ pWin = pGrab->window;
+ }
+
+ dmxDeviceGrabKeyboard (pDevice, pWin);
+ }
+ }
}
static void
@@ -1777,6 +1879,7 @@ dmxAddInputDevice (DMXInputInfo *dmxInput,
pDevPriv->masterId = masterId;
pDevPriv->device = NULL;
pDevPriv->fakeGrab = xFalse;
+ pDevPriv->grabStatus = !XCB_GRAB_STATUS_SUCCESS;
pDevPriv->active = xFalse;
pDevPriv->EventCheck = EventCheck;
pDevPriv->ReplyCheck = ReplyCheck;
diff --git a/hw/dmx/dmxinput.h b/hw/dmx/dmxinput.h
index 42ae3beb2..b0f217aa5 100644
--- a/hw/dmx/dmxinput.h
+++ b/hw/dmx/dmxinput.h
@@ -39,6 +39,7 @@ typedef struct _dmxDevicePriv {
KeySymsRec keySyms;
KeyCode *keycode;
xcb_void_cookie_t grab;
+ int grabStatus;
Bool fakeGrab;
Bool active;