2004-06-30 20:06:56 +00:00
|
|
|
/*
|
|
|
|
|
* Copyright 2001-2003 Red Hat Inc., Durham, North Carolina.
|
|
|
|
|
*
|
|
|
|
|
* All Rights Reserved.
|
|
|
|
|
*
|
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining
|
|
|
|
|
* a copy of this software and associated documentation files (the
|
|
|
|
|
* "Software"), to deal in the Software without restriction, including
|
|
|
|
|
* without limitation on the rights to use, copy, modify, merge,
|
|
|
|
|
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
|
|
|
* and to permit persons to whom the Software is furnished to do so,
|
|
|
|
|
* subject to the following conditions:
|
|
|
|
|
*
|
|
|
|
|
* The above copyright notice and this permission notice (including the
|
|
|
|
|
* next paragraph) shall be included in all copies or substantial
|
|
|
|
|
* portions of the Software.
|
|
|
|
|
*
|
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
|
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
|
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
|
|
|
* NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
|
|
|
|
|
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
|
|
|
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
|
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
|
|
* SOFTWARE.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Authors:
|
|
|
|
|
* David H. Dawes <dawes@xfree86.org>
|
|
|
|
|
* Kevin E. Martin <kem@redhat.com>
|
|
|
|
|
* Rickard E. (Rik) Faith <faith@redhat.com>
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/** \file
|
|
|
|
|
* These routines support taking input from devices on the backend
|
|
|
|
|
* (output) displays. \see dmxcommon.c. */
|
|
|
|
|
|
2005-07-12 00:52:48 +00:00
|
|
|
#ifdef HAVE_DMX_CONFIG_H
|
|
|
|
|
#include <dmx-config.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
2004-06-30 20:06:56 +00:00
|
|
|
#define DMX_BACKEND_DEBUG 0
|
|
|
|
|
|
|
|
|
|
#include "dmxinputinit.h"
|
|
|
|
|
#include "dmxbackend.h"
|
|
|
|
|
#include "dmxcommon.h"
|
|
|
|
|
#include "dmxconsole.h"
|
|
|
|
|
#include "dmxcursor.h"
|
2008-07-30 15:54:17 -04:00
|
|
|
#include "dmxwindow.h"
|
2004-06-30 20:06:56 +00:00
|
|
|
#include "dmxprop.h"
|
|
|
|
|
#include "dmxsync.h"
|
2008-08-01 21:53:25 -04:00
|
|
|
#include "dmxscrinit.h"
|
2008-06-03 18:18:04 -04:00
|
|
|
#include "dmxxlibio.h"
|
2004-06-30 20:06:56 +00:00
|
|
|
#include "dmxcb.h" /* For dmxGlobalWidth and dmxGlobalHeight */
|
|
|
|
|
#include "dmxevents.h" /* For dmxGetGlobalPosition */
|
|
|
|
|
#include "ChkNotMaskEv.h"
|
|
|
|
|
|
|
|
|
|
#include "inputstr.h"
|
|
|
|
|
#include "input.h"
|
2005-07-12 00:52:48 +00:00
|
|
|
#include <X11/keysym.h>
|
2008-07-31 15:00:31 -04:00
|
|
|
#include <xcb/xinput.h>
|
2008-06-24 12:18:22 -04:00
|
|
|
#include "mi.h"
|
2004-06-30 20:06:56 +00:00
|
|
|
#include "mipointer.h"
|
|
|
|
|
#include "scrnintstr.h"
|
|
|
|
|
#include "windowstr.h"
|
|
|
|
|
|
2008-06-24 12:18:22 -04:00
|
|
|
static EventListPtr dmxEvents = NULL;
|
|
|
|
|
|
2004-06-30 20:06:56 +00:00
|
|
|
/* Private area for backend devices. */
|
|
|
|
|
typedef struct _myPrivate {
|
|
|
|
|
DMX_COMMON_PRIVATE;
|
|
|
|
|
int myScreen;
|
|
|
|
|
DMXScreenInfo *grabbedScreen;
|
|
|
|
|
|
|
|
|
|
int lastX, lastY;
|
|
|
|
|
int centerX, centerY;
|
|
|
|
|
int relative;
|
|
|
|
|
int newscreen;
|
|
|
|
|
int initialized;
|
|
|
|
|
DevicePtr mou, kbd;
|
|
|
|
|
int entered;
|
|
|
|
|
int offX, offY;
|
|
|
|
|
} myPrivate;
|
|
|
|
|
|
|
|
|
|
#if DMX_BACKEND_DEBUG
|
|
|
|
|
#define DMXDBG0(f) dmxLog(dmxDebug,f)
|
|
|
|
|
#define DMXDBG1(f,a) dmxLog(dmxDebug,f,a)
|
|
|
|
|
#define DMXDBG2(f,a,b) dmxLog(dmxDebug,f,a,b)
|
|
|
|
|
#define DMXDBG3(f,a,b,c) dmxLog(dmxDebug,f,a,b,c)
|
|
|
|
|
#define DMXDBG4(f,a,b,c,d) dmxLog(dmxDebug,f,a,b,c,d)
|
|
|
|
|
#define DMXDBG5(f,a,b,c,d,e) dmxLog(dmxDebug,f,a,b,c,d,e)
|
|
|
|
|
#define DMXDBG6(f,a,b,c,d,e,g) dmxLog(dmxDebug,f,a,b,c,d,e,g)
|
|
|
|
|
#define DMXDBG7(f,a,b,c,d,e,g,h) dmxLog(dmxDebug,f,a,b,c,d,e,g,h)
|
|
|
|
|
#define DMXDBG8(f,a,b,c,d,e,g,h,i) dmxLog(dmxDebug,f,a,b,c,d,e,g,h,i)
|
|
|
|
|
#define DMXDBG9(f,a,b,c,d,e,g,h,i,j) dmxLog(dmxDebug,f,a,b,c,d,e,g,h,i,j)
|
|
|
|
|
#else
|
|
|
|
|
#define DMXDBG0(f)
|
|
|
|
|
#define DMXDBG1(f,a)
|
|
|
|
|
#define DMXDBG2(f,a,b)
|
|
|
|
|
#define DMXDBG3(f,a,b,c)
|
|
|
|
|
#define DMXDBG4(f,a,b,c,d)
|
|
|
|
|
#define DMXDBG5(f,a,b,c,d,e)
|
|
|
|
|
#define DMXDBG6(f,a,b,c,d,e,g)
|
|
|
|
|
#define DMXDBG7(f,a,b,c,d,e,g,h)
|
|
|
|
|
#define DMXDBG8(f,a,b,c,d,e,g,h,i)
|
|
|
|
|
#define DMXDBG9(f,a,b,c,d,e,g,h,i,j)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/** Create and return a private data structure. */
|
|
|
|
|
pointer dmxBackendCreatePrivate(DeviceIntPtr pDevice)
|
|
|
|
|
{
|
|
|
|
|
GETDMXLOCALFROMPDEVICE;
|
2008-10-08 16:25:59 -04:00
|
|
|
myPrivate *priv = calloc(1, sizeof(*priv));
|
2004-06-30 20:06:56 +00:00
|
|
|
priv->dmxLocal = dmxLocal;
|
|
|
|
|
return priv;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Destroy the private data structure. No checking is performed to
|
|
|
|
|
* verify that the structure was actually created by
|
|
|
|
|
* #dmxBackendCreatePrivate. */
|
|
|
|
|
void dmxBackendDestroyPrivate(pointer private)
|
|
|
|
|
{
|
2008-10-08 16:25:59 -04:00
|
|
|
if (private) free(private);
|
2004-06-30 20:06:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void *dmxBackendTestScreen(DMXScreenInfo *dmxScreen, void *closure)
|
|
|
|
|
{
|
|
|
|
|
long target = (long)closure;
|
|
|
|
|
|
|
|
|
|
if (dmxScreen->index == target) return dmxScreen;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return non-zero if screen and priv->myScreen are on the same physical
|
|
|
|
|
* backend display (1 if they are the same screen, 2 if they are
|
|
|
|
|
* different screens). Since this is a common operation, the results
|
|
|
|
|
* are cached. The cache is invalidated if \a priv is NULL (this should
|
|
|
|
|
* be done with each server generation and reconfiguration). */
|
|
|
|
|
static int dmxBackendSameDisplay(myPrivate *priv, long screen)
|
|
|
|
|
{
|
|
|
|
|
static myPrivate *oldpriv = NULL;
|
|
|
|
|
static int oldscreen = -1;
|
|
|
|
|
static int retcode = 0;
|
|
|
|
|
|
|
|
|
|
if (priv == oldpriv && screen == oldscreen) return retcode;
|
|
|
|
|
if (!priv) { /* Invalidate cache */
|
|
|
|
|
oldpriv = NULL;
|
|
|
|
|
oldscreen = -1;
|
|
|
|
|
retcode = 0;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (screen == priv->myScreen) retcode = 1;
|
|
|
|
|
else if (screen < 0 || screen >= dmxNumScreens) retcode = 0;
|
|
|
|
|
else if (dmxPropertyIterate(priv->be,
|
|
|
|
|
dmxBackendTestScreen,
|
|
|
|
|
(void *)screen)) retcode = 2;
|
|
|
|
|
else retcode = 0;
|
|
|
|
|
|
|
|
|
|
oldpriv = priv;
|
|
|
|
|
oldscreen = screen;
|
|
|
|
|
return retcode;
|
|
|
|
|
}
|
|
|
|
|
|
2008-06-24 12:18:22 -04:00
|
|
|
static void *dmxBackendTestWindow(DMXScreenInfo *dmxScreen, void *closure)
|
2004-06-30 20:06:56 +00:00
|
|
|
{
|
2008-06-24 12:18:22 -04:00
|
|
|
Window win = (Window)(long)closure;
|
|
|
|
|
if (dmxScreen->scrnWin == win) return dmxScreen;
|
2004-06-30 20:06:56 +00:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2008-06-24 12:18:22 -04:00
|
|
|
void dmxBackendUpdatePosition(pointer private, int x, int y)
|
2004-06-30 20:06:56 +00:00
|
|
|
{
|
2008-06-24 12:18:22 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static DeviceIntPtr
|
2008-07-20 23:17:09 -04:00
|
|
|
dmxGetButtonDevice (DMXInputInfo *dmxInput,
|
|
|
|
|
XID deviceId)
|
2008-06-24 12:18:22 -04:00
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < dmxInput->numDevs; i++)
|
|
|
|
|
if (dmxInput->devs[i]->pDevice->button)
|
2008-07-20 23:17:09 -04:00
|
|
|
if (deviceId < 0 || dmxInput->devs[i]->deviceId == deviceId)
|
|
|
|
|
return dmxInput->devs[i]->pDevice;
|
2008-06-24 12:18:22 -04:00
|
|
|
|
2004-06-30 20:06:56 +00:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2008-06-24 12:18:22 -04:00
|
|
|
static DeviceIntPtr
|
|
|
|
|
dmxGetPairedButtonDevice (DMXInputInfo *dmxInput,
|
2008-07-20 23:17:09 -04:00
|
|
|
DeviceIntPtr pDevice)
|
2004-06-30 20:06:56 +00:00
|
|
|
{
|
2008-07-20 23:17:09 -04:00
|
|
|
GETDMXLOCALFROMPDEVICE;
|
|
|
|
|
|
|
|
|
|
return dmxGetButtonDevice (dmxInput, dmxLocal->attached);
|
2004-06-30 20:06:56 +00:00
|
|
|
}
|
|
|
|
|
|
2008-06-24 12:18:22 -04:00
|
|
|
static DeviceIntPtr
|
2008-07-20 23:17:09 -04:00
|
|
|
dmxGetKeyboardDevice (DMXInputInfo *dmxInput,
|
|
|
|
|
XID deviceId)
|
2004-06-30 20:06:56 +00:00
|
|
|
{
|
2008-06-24 12:18:22 -04:00
|
|
|
int i;
|
2004-06-30 20:06:56 +00:00
|
|
|
|
2008-06-24 12:18:22 -04:00
|
|
|
for (i = 0; i < dmxInput->numDevs; i++)
|
|
|
|
|
if (dmxInput->devs[i]->pDevice->key)
|
2008-07-20 23:17:09 -04:00
|
|
|
if (deviceId < 0 || dmxInput->devs[i]->deviceId == deviceId)
|
|
|
|
|
return dmxInput->devs[i]->pDevice;
|
2008-06-24 12:18:22 -04:00
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static DeviceIntPtr
|
|
|
|
|
dmxGetPairedKeyboardDevice (DMXInputInfo *dmxInput,
|
2008-07-20 23:17:09 -04:00
|
|
|
DeviceIntPtr pDevice)
|
2008-06-24 12:18:22 -04:00
|
|
|
{
|
2008-07-20 23:17:09 -04:00
|
|
|
GETDMXLOCALFROMPDEVICE;
|
|
|
|
|
|
|
|
|
|
return dmxGetKeyboardDevice (dmxInput, dmxLocal->attached);
|
2008-06-24 12:18:22 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
2008-07-21 12:01:09 -04:00
|
|
|
if (button > 0 && button <= 255)
|
2008-06-24 12:18:22 -04:00
|
|
|
{
|
|
|
|
|
GETDMXLOCALFROMPDEVICE;
|
|
|
|
|
|
|
|
|
|
switch (type) {
|
2008-07-31 15:00:31 -04:00
|
|
|
case XCB_BUTTON_PRESS:
|
2008-07-21 12:01:09 -04:00
|
|
|
dmxLocal->state[button >> 3] |= 1 << (button & 7);
|
2008-06-24 12:18:22 -04:00
|
|
|
break;
|
2008-07-31 15:00:31 -04:00
|
|
|
case XCB_BUTTON_RELEASE:
|
2008-07-21 12:01:09 -04:00
|
|
|
dmxLocal->state[button >> 3] &= ~(1 << (button & 7));
|
2008-06-24 12:18:22 -04:00
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
2004-06-30 20:06:56 +00:00
|
|
|
}
|
2008-07-21 12:01:09 -04:00
|
|
|
|
2008-06-24 12:18:22 -04:00
|
|
|
return nEvents;
|
2004-06-30 20:06:56 +00:00
|
|
|
}
|
|
|
|
|
|
2008-06-24 12:18:22 -04:00
|
|
|
static int
|
|
|
|
|
dmxKeyEvent (DeviceIntPtr pDevice,
|
|
|
|
|
int key,
|
|
|
|
|
int type)
|
2004-06-30 20:06:56 +00:00
|
|
|
{
|
2008-06-24 12:18:22 -04:00
|
|
|
int i, nEvents;
|
|
|
|
|
|
|
|
|
|
GetEventList (&dmxEvents);
|
|
|
|
|
nEvents = GetKeyboardEvents (dmxEvents, pDevice, type, key);
|
|
|
|
|
for (i = 0; i < nEvents; i++)
|
|
|
|
|
mieqEnqueue (pDevice, dmxEvents[i].event);
|
|
|
|
|
|
2008-07-21 12:01:09 -04:00
|
|
|
if (key > 0 && key <= 255)
|
2008-06-24 12:18:22 -04:00
|
|
|
{
|
|
|
|
|
GETDMXLOCALFROMPDEVICE;
|
|
|
|
|
|
|
|
|
|
switch (type) {
|
2008-07-31 15:00:31 -04:00
|
|
|
case XCB_KEY_PRESS:
|
2008-07-21 12:01:09 -04:00
|
|
|
dmxLocal->state[key >> 3] |= 1 << (key & 7);
|
2008-06-24 12:18:22 -04:00
|
|
|
break;
|
2008-07-31 15:00:31 -04:00
|
|
|
case XCB_KEY_RELEASE:
|
2008-07-21 12:01:09 -04:00
|
|
|
dmxLocal->state[key >> 3] &= ~(1 << (key & 7));
|
2008-06-24 12:18:22 -04:00
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-06-30 20:06:56 +00:00
|
|
|
|
2008-06-24 12:18:22 -04:00
|
|
|
return nEvents;
|
2004-06-30 20:06:56 +00:00
|
|
|
}
|
|
|
|
|
|
2008-06-24 12:18:22 -04:00
|
|
|
static int
|
2008-07-21 12:01:09 -04:00
|
|
|
dmxUpdateButtonState (DeviceIntPtr pDevice,
|
|
|
|
|
const char *buttons)
|
2004-06-30 20:06:56 +00:00
|
|
|
{
|
2008-07-21 12:01:09 -04:00
|
|
|
int i, j, nEvents = 0;
|
2008-06-24 12:18:22 -04:00
|
|
|
|
|
|
|
|
GETDMXLOCALFROMPDEVICE;
|
|
|
|
|
|
2008-07-21 12:01:09 -04:00
|
|
|
for (i = 0; i < 32; i++)
|
2008-06-24 12:18:22 -04:00
|
|
|
{
|
2008-07-21 12:01:09 -04:00
|
|
|
if (!(dmxLocal->state[i] ^ buttons[i]))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
for (j = 0; j < 8; j++)
|
2008-06-24 12:18:22 -04:00
|
|
|
{
|
2008-07-21 12:01:09 -04:00
|
|
|
/* button is down, but shouldn't be */
|
|
|
|
|
if ((dmxLocal->state[i] & (1 << j)) && !(buttons[i] & (1 << j)))
|
|
|
|
|
nEvents += dmxButtonEvent (pDevice,
|
|
|
|
|
(i << 3) + j,
|
|
|
|
|
pDevice->last.valuators[0],
|
|
|
|
|
pDevice->last.valuators[1],
|
2008-07-31 15:00:31 -04:00
|
|
|
XCB_BUTTON_RELEASE);
|
2008-07-21 12:01:09 -04:00
|
|
|
|
|
|
|
|
/* button should be down, but isn't */
|
|
|
|
|
if (!(dmxLocal->state[i] & (1 << j)) && (buttons[i] & (1 << j)))
|
|
|
|
|
nEvents += dmxButtonEvent (pDevice,
|
|
|
|
|
(i << 3) + j,
|
|
|
|
|
pDevice->last.valuators[0],
|
|
|
|
|
pDevice->last.valuators[1],
|
2008-07-31 15:00:31 -04:00
|
|
|
XCB_BUTTON_PRESS);
|
2008-07-21 12:01:09 -04:00
|
|
|
}
|
|
|
|
|
}
|
2008-06-24 12:18:22 -04:00
|
|
|
|
2008-07-21 12:01:09 -04:00
|
|
|
return nEvents;
|
|
|
|
|
}
|
2008-06-24 12:18:22 -04:00
|
|
|
|
2008-07-21 12:01:09 -04:00
|
|
|
static int
|
|
|
|
|
dmxUpdateKeyState (DeviceIntPtr pDevice,
|
|
|
|
|
const char *keys)
|
|
|
|
|
{
|
|
|
|
|
int i, j, nEvents = 0;
|
2008-06-24 12:18:22 -04:00
|
|
|
|
2008-07-21 12:01:09 -04:00
|
|
|
GETDMXLOCALFROMPDEVICE;
|
2008-06-24 12:18:22 -04:00
|
|
|
|
2008-07-21 12:01:09 -04:00
|
|
|
for (i = 0; i < 32; i++)
|
|
|
|
|
{
|
|
|
|
|
if (!(dmxLocal->state[i] ^ keys[i]))
|
|
|
|
|
continue;
|
2008-06-24 12:18:22 -04:00
|
|
|
|
2008-07-21 12:01:09 -04:00
|
|
|
for (j = 0; j < 8; j++)
|
2008-06-24 12:18:22 -04:00
|
|
|
{
|
2008-07-21 12:01:09 -04:00
|
|
|
/* key is down, but shouldn't be */
|
|
|
|
|
if ((dmxLocal->state[i] & (1 << j)) && !(keys[i] & (1 << j)))
|
|
|
|
|
nEvents += dmxKeyEvent (pDevice,
|
|
|
|
|
(i << 3) + j,
|
2008-07-31 15:00:31 -04:00
|
|
|
XCB_KEY_RELEASE);
|
2008-07-21 12:01:09 -04:00
|
|
|
|
|
|
|
|
/* key should be down, but isn't */
|
|
|
|
|
if (!(dmxLocal->state[i] & (1 << j)) && (keys[i] & (1 << j)))
|
|
|
|
|
nEvents += dmxKeyEvent (pDevice,
|
|
|
|
|
(i << 3) + j,
|
2008-07-31 15:00:31 -04:00
|
|
|
XCB_KEY_PRESS);
|
2008-06-24 12:18:22 -04:00
|
|
|
}
|
2004-06-30 20:06:56 +00:00
|
|
|
}
|
|
|
|
|
|
2008-06-24 12:18:22 -04:00
|
|
|
return nEvents;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
2008-07-21 12:01:09 -04:00
|
|
|
dmxChangeButtonState (DeviceIntPtr pDevice,
|
|
|
|
|
int button,
|
|
|
|
|
int how)
|
2008-06-24 12:18:22 -04:00
|
|
|
{
|
2008-07-21 12:01:09 -04:00
|
|
|
int nEvents = 0;
|
2008-06-24 12:18:22 -04:00
|
|
|
|
2008-07-21 12:01:09 -04:00
|
|
|
if (button > 0 && button <= 255)
|
|
|
|
|
{
|
|
|
|
|
char buttons[32];
|
|
|
|
|
|
|
|
|
|
GETDMXLOCALFROMPDEVICE;
|
|
|
|
|
|
|
|
|
|
memcpy (buttons, dmxLocal->state, sizeof (buttons));
|
|
|
|
|
|
|
|
|
|
switch (how) {
|
2008-07-31 15:00:31 -04:00
|
|
|
case XCB_BUTTON_PRESS:
|
2008-07-21 12:01:09 -04:00
|
|
|
buttons[button >> 3] |= 1 << (button & 7);
|
|
|
|
|
break;
|
2008-07-31 15:00:31 -04:00
|
|
|
case XCB_BUTTON_RELEASE:
|
2008-07-21 12:01:09 -04:00
|
|
|
buttons[button >> 3] &= ~(1 << (button & 7));
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dmxUpdateButtonState (pDevice, buttons);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nEvents;
|
2008-06-24 12:18:22 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
2008-07-21 12:01:09 -04:00
|
|
|
dmxChangeKeyState (DeviceIntPtr pDevice,
|
|
|
|
|
int key,
|
|
|
|
|
int how)
|
2008-06-24 12:18:22 -04:00
|
|
|
{
|
2008-07-21 12:01:09 -04:00
|
|
|
int nEvents = 0;
|
2008-06-24 12:18:22 -04:00
|
|
|
|
2008-07-21 12:01:09 -04:00
|
|
|
if (key > 0 && key <= 255)
|
|
|
|
|
{
|
|
|
|
|
char keys[32];
|
2008-06-24 12:18:22 -04:00
|
|
|
|
2008-07-21 12:01:09 -04:00
|
|
|
GETDMXLOCALFROMPDEVICE;
|
2008-06-24 12:18:22 -04:00
|
|
|
|
2008-07-21 12:01:09 -04:00
|
|
|
memcpy (keys, dmxLocal->state, sizeof (keys));
|
2008-06-24 12:18:22 -04:00
|
|
|
|
2008-07-21 12:01:09 -04:00
|
|
|
switch (how) {
|
2008-07-31 15:00:31 -04:00
|
|
|
case XCB_KEY_PRESS:
|
2008-07-21 12:01:09 -04:00
|
|
|
keys[key >> 3] |= 1 << (key & 7);
|
|
|
|
|
break;
|
2008-07-31 15:00:31 -04:00
|
|
|
case XCB_KEY_RELEASE:
|
2008-07-21 12:01:09 -04:00
|
|
|
keys[key >> 3] &= ~(1 << (key & 7));
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dmxUpdateKeyState (pDevice, keys);
|
2004-06-30 20:06:56 +00:00
|
|
|
}
|
2008-06-24 12:18:22 -04:00
|
|
|
|
|
|
|
|
return nEvents;
|
2004-06-30 20:06:56 +00:00
|
|
|
}
|
|
|
|
|
|
2008-07-21 12:01:09 -04:00
|
|
|
static int
|
|
|
|
|
dmxUpdateSpritePosition (DeviceIntPtr pDevice,
|
|
|
|
|
int x,
|
|
|
|
|
int y)
|
|
|
|
|
{
|
|
|
|
|
if (x == pDevice->last.valuators[0] && y == pDevice->last.valuators[1])
|
|
|
|
|
return 0;
|
|
|
|
|
|
2008-07-31 15:00:31 -04:00
|
|
|
return dmxButtonEvent (pDevice, 0, x, y, XCB_MOTION_NOTIFY);
|
2008-07-21 12:01:09 -04:00
|
|
|
}
|
|
|
|
|
|
2008-07-31 15:00:31 -04:00
|
|
|
Bool
|
|
|
|
|
dmxBackendPointerEventCheck (DevicePtr pDev,
|
|
|
|
|
xcb_generic_event_t *event)
|
2004-06-30 20:06:56 +00:00
|
|
|
{
|
|
|
|
|
GETPRIVFROMPDEV;
|
|
|
|
|
GETDMXINPUTFROMPRIV;
|
2008-07-31 15:00:31 -04:00
|
|
|
DeviceIntPtr pButtonDev = (DeviceIntPtr) pDev;
|
|
|
|
|
int reltype, type = event->response_type & 0x7f;
|
|
|
|
|
int id = dmxLocal->deviceId;
|
|
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
case XCB_MOTION_NOTIFY: {
|
|
|
|
|
xcb_motion_notify_event_t *xmotion =
|
|
|
|
|
(xcb_motion_notify_event_t *) event;
|
|
|
|
|
|
|
|
|
|
dmxUpdateSpritePosition (pButtonDev,
|
|
|
|
|
xmotion->event_x,
|
|
|
|
|
xmotion->event_y);
|
|
|
|
|
} break;
|
|
|
|
|
case XCB_BUTTON_PRESS:
|
|
|
|
|
case XCB_BUTTON_RELEASE: {
|
|
|
|
|
xcb_button_press_event_t *xbutton =
|
|
|
|
|
(xcb_button_press_event_t *) event;
|
|
|
|
|
|
|
|
|
|
dmxUpdateSpritePosition (pButtonDev,
|
|
|
|
|
xbutton->event_x,
|
|
|
|
|
xbutton->event_y);
|
|
|
|
|
dmxChangeButtonState (pButtonDev,
|
|
|
|
|
xbutton->detail,
|
|
|
|
|
type);
|
|
|
|
|
} break;
|
|
|
|
|
default:
|
|
|
|
|
if (id < 0)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
reltype = type - dmxInput->eventBase;
|
|
|
|
|
|
|
|
|
|
switch (reltype) {
|
|
|
|
|
case XCB_INPUT_DEVICE_VALUATOR: {
|
|
|
|
|
xcb_input_device_valuator_event_t *xvaluator =
|
|
|
|
|
(xcb_input_device_valuator_event_t *) event;
|
|
|
|
|
|
|
|
|
|
if (id != (xvaluator->device_id & DEVICE_BITS))
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
/* eat valuator events */
|
|
|
|
|
} break;
|
|
|
|
|
case XCB_INPUT_DEVICE_MOTION_NOTIFY: {
|
|
|
|
|
xcb_input_device_button_release_event_t *xmotion =
|
|
|
|
|
(xcb_input_device_button_release_event_t *) event;
|
|
|
|
|
|
|
|
|
|
dmxUpdateSpritePosition (pButtonDev,
|
|
|
|
|
xmotion->event_x,
|
|
|
|
|
xmotion->event_y);
|
|
|
|
|
} break;
|
|
|
|
|
case XCB_INPUT_DEVICE_BUTTON_RELEASE:
|
|
|
|
|
case XCB_INPUT_DEVICE_BUTTON_PRESS: {
|
|
|
|
|
xcb_input_device_key_press_event_t *xbutton =
|
|
|
|
|
(xcb_input_device_key_press_event_t *) event;
|
|
|
|
|
|
|
|
|
|
if (id != (xbutton->device_id & DEVICE_BITS))
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
dmxUpdateSpritePosition (pButtonDev,
|
|
|
|
|
xbutton->event_x,
|
|
|
|
|
xbutton->event_y);
|
|
|
|
|
dmxChangeButtonState (pButtonDev,
|
|
|
|
|
xbutton->detail, XCB_BUTTON_RELEASE +
|
|
|
|
|
(reltype -
|
|
|
|
|
XCB_INPUT_DEVICE_BUTTON_RELEASE));
|
|
|
|
|
} break;
|
|
|
|
|
case XCB_INPUT_DEVICE_STATE_NOTIFY: {
|
|
|
|
|
xcb_input_device_state_notify_event_t *xstate =
|
|
|
|
|
(xcb_input_device_state_notify_event_t *) event;
|
|
|
|
|
|
|
|
|
|
if (id != (xstate->device_id & DEVICE_BITS))
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
if (!(xstate->classes_reported & (1 << ButtonClass)))
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
memset (dmxLocal->keysbuttons, 0, 32);
|
|
|
|
|
|
|
|
|
|
if (xstate->response_type & MORE_EVENTS)
|
2008-06-03 18:18:04 -04:00
|
|
|
{
|
2008-07-31 15:00:31 -04:00
|
|
|
memcpy (dmxLocal->keysbuttons, xstate->buttons, 4);
|
2008-06-03 18:18:04 -04:00
|
|
|
}
|
2008-07-31 15:00:31 -04:00
|
|
|
else
|
2008-06-03 18:18:04 -04:00
|
|
|
{
|
2008-07-31 15:00:31 -04:00
|
|
|
memcpy (dmxLocal->keysbuttons, xstate->buttons, 4);
|
|
|
|
|
dmxUpdateButtonState (pButtonDev,
|
|
|
|
|
dmxLocal->keysbuttons);
|
2008-06-03 18:18:04 -04:00
|
|
|
}
|
2008-07-31 15:00:31 -04:00
|
|
|
} break;
|
|
|
|
|
case XCB_INPUT_DEVICE_BUTTON_STATE_NOTIFY: {
|
|
|
|
|
xcb_input_device_button_state_notify_event_t *xstate =
|
|
|
|
|
(xcb_input_device_button_state_notify_event_t *) event;
|
|
|
|
|
|
|
|
|
|
if (id != (xstate->device_id & DEVICE_BITS))
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
memcpy (&dmxLocal->keysbuttons[4], xstate->buttons, 28);
|
|
|
|
|
dmxUpdateButtonState (pButtonDev, dmxLocal->keysbuttons);
|
|
|
|
|
} break;
|
2004-06-30 20:06:56 +00:00
|
|
|
default:
|
2008-07-31 15:00:31 -04:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-01 21:53:25 -04:00
|
|
|
/* not in xcb-xinput yet */
|
|
|
|
|
#define DMX_XCB_INPUT_EXTENDED_GRAB_DEVICE 45
|
|
|
|
|
|
|
|
|
|
typedef struct dmx_xcb_input_extended_grab_device_request_t {
|
|
|
|
|
uint8_t major_opcode;
|
|
|
|
|
uint8_t minor_opcode;
|
|
|
|
|
uint16_t length;
|
|
|
|
|
xcb_window_t grab_window;
|
|
|
|
|
xcb_timestamp_t time;
|
|
|
|
|
uint8_t deviceid;
|
|
|
|
|
uint8_t device_mode;
|
|
|
|
|
uint8_t owner_events;
|
|
|
|
|
uint8_t pad0;
|
|
|
|
|
xcb_window_t confine_to;
|
|
|
|
|
xcb_cursor_t cursor;
|
|
|
|
|
uint16_t event_count;
|
|
|
|
|
uint16_t generic_event_count;
|
|
|
|
|
} dmx_xcb_input_extended_grab_device_request_t;
|
|
|
|
|
|
|
|
|
|
Bool
|
|
|
|
|
dmxBackendPointerReplyCheck (DevicePtr pDev,
|
|
|
|
|
unsigned int request,
|
|
|
|
|
xcb_generic_reply_t *reply)
|
|
|
|
|
{
|
|
|
|
|
GETDMXLOCALFROMPDEV;
|
|
|
|
|
|
|
|
|
|
if (request == dmxLocal->grab.sequence)
|
|
|
|
|
{
|
|
|
|
|
xcb_grab_status_t status = XCB_GRAB_STATUS_FROZEN;
|
|
|
|
|
|
|
|
|
|
if (reply->response_type == 1)
|
|
|
|
|
{
|
|
|
|
|
if (dmxLocal->deviceId >= 0)
|
|
|
|
|
{
|
|
|
|
|
xcb_input_grab_device_reply_t *xgrab =
|
|
|
|
|
(xcb_input_grab_device_reply_t *) reply;
|
|
|
|
|
|
|
|
|
|
status = xgrab->status;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
xcb_grab_pointer_reply_t *xgrab =
|
|
|
|
|
(xcb_grab_pointer_reply_t *) reply;
|
|
|
|
|
|
|
|
|
|
status = xgrab->status;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (status == XCB_GRAB_STATUS_SUCCESS)
|
|
|
|
|
{
|
|
|
|
|
/* TODO: track state of grabs */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dmxLocal->grab.sequence = 0;
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-07-31 15:00:31 -04:00
|
|
|
Bool
|
|
|
|
|
dmxBackendKeyboardEventCheck (DevicePtr pDev,
|
|
|
|
|
xcb_generic_event_t *event)
|
|
|
|
|
{
|
|
|
|
|
GETPRIVFROMPDEV;
|
|
|
|
|
GETDMXINPUTFROMPRIV;
|
|
|
|
|
DeviceIntPtr pKeyDev = (DeviceIntPtr) pDev;
|
|
|
|
|
DeviceIntPtr pButtonDev;
|
|
|
|
|
int reltype, type = event->response_type & 0x7f;
|
|
|
|
|
int id = dmxLocal->deviceId;
|
|
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
case XCB_KEY_PRESS:
|
|
|
|
|
case XCB_KEY_RELEASE: {
|
|
|
|
|
xcb_key_press_event_t *xkey = (xcb_key_press_event_t *) event;
|
|
|
|
|
|
|
|
|
|
pButtonDev = dmxGetPairedButtonDevice (dmxInput, pKeyDev);
|
|
|
|
|
if (pButtonDev)
|
|
|
|
|
dmxUpdateSpritePosition (pButtonDev, xkey->event_x, xkey->event_y);
|
|
|
|
|
|
|
|
|
|
dmxChangeKeyState (pKeyDev,
|
|
|
|
|
xkey->detail,
|
|
|
|
|
type);
|
|
|
|
|
} break;
|
|
|
|
|
case XCB_KEYMAP_NOTIFY: {
|
|
|
|
|
xcb_keymap_notify_event_t *xkeymap =
|
|
|
|
|
(xcb_keymap_notify_event_t *) event;
|
|
|
|
|
char state[32];
|
|
|
|
|
|
2008-08-01 21:53:25 -04:00
|
|
|
state[0] = 0;
|
|
|
|
|
memcpy (&state[1], xkeymap->keys, 31);
|
2008-07-31 15:00:31 -04:00
|
|
|
|
|
|
|
|
dmxUpdateKeyState (pKeyDev, state);
|
|
|
|
|
} break;
|
|
|
|
|
default:
|
|
|
|
|
if (id < 0)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
reltype = type - dmxInput->eventBase;
|
|
|
|
|
|
|
|
|
|
switch (reltype) {
|
|
|
|
|
case XCB_INPUT_DEVICE_VALUATOR: {
|
|
|
|
|
xcb_input_device_valuator_event_t *xvaluator =
|
|
|
|
|
(xcb_input_device_valuator_event_t *) event;
|
|
|
|
|
|
|
|
|
|
if (id != (xvaluator->device_id & DEVICE_BITS))
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
/* eat valuator events */
|
|
|
|
|
} break;
|
|
|
|
|
case XCB_INPUT_DEVICE_KEY_PRESS:
|
|
|
|
|
case XCB_INPUT_DEVICE_KEY_RELEASE: {
|
|
|
|
|
xcb_input_device_key_press_event_t *xkey =
|
|
|
|
|
(xcb_input_device_key_press_event_t *) event;
|
|
|
|
|
|
|
|
|
|
if (id != (xkey->device_id & DEVICE_BITS))
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
pButtonDev = dmxGetPairedButtonDevice (dmxInput, pKeyDev);
|
|
|
|
|
if (pButtonDev)
|
|
|
|
|
dmxUpdateSpritePosition (pButtonDev,
|
|
|
|
|
xkey->event_x,
|
|
|
|
|
xkey->event_y);
|
|
|
|
|
|
|
|
|
|
dmxChangeKeyState (pKeyDev,
|
|
|
|
|
xkey->detail, XCB_KEY_PRESS +
|
|
|
|
|
(reltype - XCB_INPUT_DEVICE_KEY_PRESS));
|
|
|
|
|
} break;
|
|
|
|
|
case XCB_INPUT_DEVICE_STATE_NOTIFY: {
|
|
|
|
|
xcb_input_device_state_notify_event_t *xstate =
|
|
|
|
|
(xcb_input_device_state_notify_event_t *) event;
|
|
|
|
|
|
|
|
|
|
if (id != (xstate->device_id & DEVICE_BITS))
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
if (!(xstate->classes_reported & (1 << KeyClass)))
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
memset (dmxLocal->keysbuttons, 0, 32);
|
|
|
|
|
|
|
|
|
|
if (xstate->response_type & MORE_EVENTS)
|
2008-07-21 12:01:09 -04:00
|
|
|
{
|
2008-07-31 15:00:31 -04:00
|
|
|
memcpy (dmxLocal->keysbuttons, xstate->keys, 4);
|
2008-07-21 12:01:09 -04:00
|
|
|
}
|
2008-07-31 15:00:31 -04:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
memcpy (dmxLocal->keysbuttons, xstate->keys, 4);
|
|
|
|
|
dmxUpdateKeyState (pKeyDev, dmxLocal->keysbuttons);
|
|
|
|
|
}
|
|
|
|
|
} break;
|
|
|
|
|
case XCB_INPUT_DEVICE_KEY_STATE_NOTIFY: {
|
|
|
|
|
xcb_input_device_key_state_notify_event_t *xstate =
|
|
|
|
|
(xcb_input_device_key_state_notify_event_t *) event;
|
|
|
|
|
|
|
|
|
|
if (id != (xstate->device_id & DEVICE_BITS))
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
memcpy (&dmxLocal->keysbuttons[4], xstate->keys, 28);
|
|
|
|
|
dmxUpdateKeyState (pKeyDev, dmxLocal->keysbuttons);
|
|
|
|
|
} break;
|
|
|
|
|
default:
|
|
|
|
|
return FALSE;
|
2004-06-30 20:06:56 +00:00
|
|
|
}
|
|
|
|
|
}
|
2008-07-31 15:00:31 -04:00
|
|
|
|
|
|
|
|
return TRUE;
|
2004-06-30 20:06:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Called after input events are processed from the DMX queue. No
|
|
|
|
|
* event processing actually takes place here, but this is a convenient
|
|
|
|
|
* place to update the pointer. */
|
|
|
|
|
void dmxBackendProcessInput(pointer private)
|
|
|
|
|
{
|
|
|
|
|
GETPRIVFROMPRIVATE;
|
|
|
|
|
|
|
|
|
|
DMXDBG6("dmxBackendProcessInput: myScreen=%d relative=%d"
|
|
|
|
|
" last=%d,%d center=%d,%d\n",
|
|
|
|
|
priv->myScreen, priv->relative,
|
|
|
|
|
priv->lastX, priv->lastY,
|
|
|
|
|
priv->centerX, priv->centerY);
|
|
|
|
|
|
|
|
|
|
if (priv->relative
|
|
|
|
|
&& !dmxInput->console
|
|
|
|
|
&& (priv->lastX != priv->centerX || priv->lastY != priv->centerY)) {
|
|
|
|
|
DMXDBG4(" warping pointer from last=%d,%d to center=%d,%d\n",
|
|
|
|
|
priv->lastX, priv->lastY, priv->centerX, priv->centerY);
|
|
|
|
|
priv->lastX = priv->centerX;
|
|
|
|
|
priv->lastY = priv->centerY;
|
2008-06-03 18:18:04 -04:00
|
|
|
XLIB_PROLOGUE (&dmxScreens[priv->myScreen]);
|
2004-06-30 20:06:56 +00:00
|
|
|
XWarpPointer(priv->display, None, priv->window,
|
|
|
|
|
0, 0, 0, 0, priv->lastX, priv->lastY);
|
2008-06-03 18:18:04 -04:00
|
|
|
XLIB_EPILOGUE (&dmxScreens[priv->myScreen]);
|
2004-06-30 20:06:56 +00:00
|
|
|
dmxSync(&dmxScreens[priv->myScreen], TRUE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2008-07-30 15:54:17 -04:00
|
|
|
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];
|
2008-08-01 21:53:25 -04:00
|
|
|
Window window = (DMX_GET_WINDOW_PRIV (pWindow))->window;
|
2008-07-30 15:54:17 -04:00
|
|
|
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)
|
|
|
|
|
{
|
2008-08-01 21:53:25 -04:00
|
|
|
int id = dmxLocal->deviceId;
|
|
|
|
|
int modId = 0;
|
2008-07-30 15:54:17 -04:00
|
|
|
|
|
|
|
|
if (pModDev)
|
2008-08-01 21:53:25 -04:00
|
|
|
modId = ((DMXLocalInputInfoPtr) pModDev->devicePrivate)->deviceId;
|
2008-07-30 15:54:17 -04:00
|
|
|
|
|
|
|
|
/* this is really useless as XGrabDeviceButton doesn't allow us
|
|
|
|
|
to specify a confineTo window or cursor */
|
2008-08-01 21:53:25 -04:00
|
|
|
xcb_input_grab_device_button (dmxScreen->connection,
|
|
|
|
|
window,
|
|
|
|
|
id,
|
|
|
|
|
modId,
|
|
|
|
|
0,
|
|
|
|
|
modifiers,
|
|
|
|
|
XCB_GRAB_MODE_ASYNC,
|
|
|
|
|
XCB_GRAB_MODE_ASYNC,
|
|
|
|
|
button,
|
|
|
|
|
TRUE,
|
|
|
|
|
NULL);
|
2008-07-30 15:54:17 -04:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2008-08-01 21:53:25 -04:00
|
|
|
xcb_grab_button (dmxScreen->connection,
|
|
|
|
|
TRUE,
|
|
|
|
|
window,
|
|
|
|
|
0,
|
|
|
|
|
XCB_GRAB_MODE_ASYNC,
|
|
|
|
|
XCB_GRAB_MODE_ASYNC,
|
|
|
|
|
confineTo,
|
|
|
|
|
cursor,
|
|
|
|
|
button,
|
|
|
|
|
modifiers);
|
2008-07-30 15:54:17 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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];
|
2008-08-01 21:53:25 -04:00
|
|
|
Window window = (DMX_GET_WINDOW_PRIV (pWindow))->window;
|
2008-07-30 15:54:17 -04:00
|
|
|
|
|
|
|
|
if (dmxLocal->deviceId >= 0)
|
|
|
|
|
{
|
2008-08-01 21:53:25 -04:00
|
|
|
int id = dmxLocal->deviceId;
|
|
|
|
|
int modId = 0;
|
2008-07-30 15:54:17 -04:00
|
|
|
|
|
|
|
|
if (pModDev)
|
2008-08-01 21:53:25 -04:00
|
|
|
modId = ((DMXLocalInputInfoPtr) pModDev->devicePrivate)->deviceId;
|
|
|
|
|
|
|
|
|
|
xcb_input_ungrab_device_button (dmxScreen->connection,
|
|
|
|
|
window,
|
|
|
|
|
modifiers,
|
|
|
|
|
modId,
|
|
|
|
|
button,
|
|
|
|
|
id);
|
2008-07-30 15:54:17 -04:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2008-08-01 21:53:25 -04:00
|
|
|
xcb_ungrab_button (dmxScreen->connection,
|
|
|
|
|
button,
|
|
|
|
|
window,
|
|
|
|
|
modifiers);
|
2008-07-30 15:54:17 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void dmxBackendGrabPointer(DevicePtr pDev,
|
|
|
|
|
WindowPtr pWindow,
|
|
|
|
|
WindowPtr pConfineTo,
|
|
|
|
|
CursorPtr pCursor)
|
|
|
|
|
{
|
|
|
|
|
GETPRIVFROMPDEV;
|
|
|
|
|
GETDMXINPUTFROMPRIV;
|
|
|
|
|
ScreenPtr pScreen = screenInfo.screens[dmxInput->scrnIdx];
|
|
|
|
|
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
2008-08-01 21:53:25 -04:00
|
|
|
Window window = (DMX_GET_WINDOW_PRIV (pWindow))->window;
|
2008-07-30 15:54:17 -04:00
|
|
|
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)
|
|
|
|
|
{
|
2008-08-01 21:53:25 -04:00
|
|
|
dmx_xcb_input_extended_grab_device_request_t grab = {
|
|
|
|
|
.grab_window = window,
|
|
|
|
|
.deviceid = dmxLocal->deviceId,
|
|
|
|
|
.device_mode = XCB_GRAB_MODE_ASYNC,
|
|
|
|
|
.owner_events = TRUE,
|
|
|
|
|
.confine_to = confineTo,
|
|
|
|
|
.cursor = cursor
|
|
|
|
|
};
|
|
|
|
|
xcb_protocol_request_t request = {
|
|
|
|
|
1,
|
|
|
|
|
&xcb_input_id,
|
|
|
|
|
DMX_XCB_INPUT_EXTENDED_GRAB_DEVICE,
|
|
|
|
|
FALSE
|
|
|
|
|
};
|
|
|
|
|
struct iovec vector = { &grab, sizeof (grab) };
|
|
|
|
|
|
|
|
|
|
dmxLocal->grab.sequence =
|
|
|
|
|
xcb_send_request (dmxScreen->connection,
|
|
|
|
|
0,
|
|
|
|
|
&vector,
|
|
|
|
|
&request);
|
2008-07-30 15:54:17 -04:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2008-08-01 21:53:25 -04:00
|
|
|
dmxLocal->grab.sequence =
|
|
|
|
|
xcb_grab_pointer (dmxScreen->connection,
|
|
|
|
|
TRUE,
|
|
|
|
|
window,
|
|
|
|
|
0,
|
|
|
|
|
XCB_GRAB_MODE_ASYNC,
|
|
|
|
|
XCB_GRAB_MODE_ASYNC,
|
|
|
|
|
confineTo,
|
|
|
|
|
cursor,
|
|
|
|
|
0).sequence;
|
2008-07-30 15:54:17 -04:00
|
|
|
}
|
2008-08-01 21:53:25 -04:00
|
|
|
|
|
|
|
|
dmxAddSequence (&dmxScreen->request, dmxLocal->grab.sequence);
|
2008-07-30 15:54:17 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void dmxBackendUngrabPointer(DevicePtr pDev,
|
|
|
|
|
WindowPtr pWindow)
|
|
|
|
|
{
|
|
|
|
|
GETPRIVFROMPDEV;
|
|
|
|
|
GETDMXINPUTFROMPRIV;
|
|
|
|
|
ScreenPtr pScreen = screenInfo.screens[dmxInput->scrnIdx];
|
|
|
|
|
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
|
|
|
|
|
|
|
|
|
if (dmxLocal->deviceId >= 0)
|
|
|
|
|
{
|
2008-08-01 21:53:25 -04:00
|
|
|
xcb_input_ungrab_device (dmxScreen->connection,
|
|
|
|
|
0,
|
|
|
|
|
dmxLocal->deviceId);
|
2008-07-30 15:54:17 -04:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2008-08-01 21:53:25 -04:00
|
|
|
xcb_ungrab_pointer (dmxScreen->connection, 0);
|
2008-07-30 15:54:17 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2004-06-30 20:06:56 +00:00
|
|
|
static DMXScreenInfo *dmxBackendInitPrivate(DevicePtr pDev)
|
|
|
|
|
{
|
|
|
|
|
GETPRIVFROMPDEV;
|
|
|
|
|
DMXInputInfo *dmxInput = &dmxInputs[dmxLocal->inputIdx];
|
|
|
|
|
DMXScreenInfo *dmxScreen;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
/* Fill in myPrivate */
|
|
|
|
|
for (i = 0,dmxScreen = &dmxScreens[0]; i<dmxNumScreens; i++,dmxScreen++) {
|
2008-07-21 12:01:09 -04:00
|
|
|
if ((dmxInput->scrnIdx == -1 &&
|
|
|
|
|
dmxPropertySameDisplay (dmxScreen, dmxInput->name)) ||
|
|
|
|
|
dmxInput->scrnIdx == i) {
|
2004-06-30 20:06:56 +00:00
|
|
|
priv->display = dmxScreen->beDisplay;
|
|
|
|
|
priv->window = dmxScreen->scrnWin;
|
|
|
|
|
priv->be = dmxScreen;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (i >= dmxNumScreens)
|
|
|
|
|
dmxLog(dmxFatal,
|
|
|
|
|
"%s is not an existing backend display - cannot initialize\n",
|
|
|
|
|
dmxInput->name);
|
|
|
|
|
|
|
|
|
|
return dmxScreen;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Re-initialized the backend device described by \a pDev (after a
|
|
|
|
|
* reconfig). */
|
|
|
|
|
void dmxBackendLateReInit(DevicePtr pDev)
|
|
|
|
|
{
|
|
|
|
|
int x, y;
|
|
|
|
|
|
|
|
|
|
DMXDBG1("dmxBackendLateReInit miPointerCurrentScreen() = %p\n",
|
|
|
|
|
miPointerCurrentScreen());
|
|
|
|
|
|
|
|
|
|
dmxBackendSameDisplay(NULL, 0); /* Invalidate cache */
|
|
|
|
|
dmxBackendInitPrivate(pDev);
|
|
|
|
|
dmxGetGlobalPosition(&x, &y);
|
|
|
|
|
dmxInvalidateGlobalPosition(); /* To force event processing */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Initialized the backend device described by \a pDev. */
|
|
|
|
|
void dmxBackendInit(DevicePtr pDev)
|
|
|
|
|
{
|
|
|
|
|
GETPRIVFROMPDEV;
|
|
|
|
|
DMXScreenInfo *dmxScreen;
|
|
|
|
|
|
|
|
|
|
dmxBackendSameDisplay(NULL, 0); /* Invalidate cache */
|
|
|
|
|
|
|
|
|
|
if (dmxLocal->type == DMX_LOCAL_MOUSE) priv->mou = pDev;
|
|
|
|
|
if (dmxLocal->type == DMX_LOCAL_KEYBOARD) priv->kbd = pDev;
|
|
|
|
|
if (priv->initialized++) return; /* Only do once for mouse/keyboard pair */
|
|
|
|
|
|
|
|
|
|
dmxScreen = dmxBackendInitPrivate(pDev);
|
|
|
|
|
|
|
|
|
|
/* Finish initialization using computed values or constants. */
|
2008-08-10 10:26:08 -04:00
|
|
|
priv->eventMask = StructureNotifyMask;
|
2004-06-30 20:06:56 +00:00
|
|
|
priv->myScreen = dmxScreen->index;
|
2008-08-10 10:26:08 -04:00
|
|
|
priv->lastX = 0;
|
|
|
|
|
priv->lastY = 0;
|
2004-06-30 20:06:56 +00:00
|
|
|
priv->relative = 0;
|
|
|
|
|
priv->newscreen = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Get information about the backend pointer (for initialization). */
|
|
|
|
|
void dmxBackendMouGetInfo(DevicePtr pDev, DMXLocalInitInfoPtr info)
|
|
|
|
|
{
|
2007-04-02 12:41:30 -06:00
|
|
|
const DMXScreenInfo *dmxScreen = dmxBackendInitPrivate(pDev);
|
|
|
|
|
|
2004-06-30 20:06:56 +00:00
|
|
|
info->buttonClass = 1;
|
|
|
|
|
dmxCommonMouGetMap(pDev, info->map, &info->numButtons);
|
|
|
|
|
info->valuatorClass = 1;
|
|
|
|
|
info->numRelAxes = 2;
|
|
|
|
|
info->minval[0] = 0;
|
2007-04-02 12:41:30 -06:00
|
|
|
info->minval[1] = 0;
|
|
|
|
|
info->maxval[0] = dmxScreen->beWidth;
|
|
|
|
|
info->maxval[1] = dmxScreen->beHeight;
|
2004-06-30 20:06:56 +00:00
|
|
|
info->res[0] = 1;
|
|
|
|
|
info->minres[0] = 0;
|
|
|
|
|
info->maxres[0] = 1;
|
|
|
|
|
info->ptrFeedbackClass = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Get information about the backend keyboard (for initialization). */
|
|
|
|
|
void dmxBackendKbdGetInfo(DevicePtr pDev, DMXLocalInitInfoPtr info)
|
|
|
|
|
{
|
|
|
|
|
dmxCommonKbdGetInfo(pDev, info);
|
|
|
|
|
info->keyboard = 1;
|
|
|
|
|
info->keyClass = 1;
|
|
|
|
|
dmxCommonKbdGetMap(pDev, &info->keySyms, info->modMap);
|
|
|
|
|
info->freemap = 1;
|
|
|
|
|
info->focusClass = 1;
|
|
|
|
|
info->kbdFeedbackClass = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Process #DMXFunctionType functions. The only function handled here
|
|
|
|
|
* is to acknowledge a pending server shutdown. */
|
|
|
|
|
int dmxBackendFunctions(pointer private, DMXFunctionType function)
|
|
|
|
|
{
|
|
|
|
|
switch (function) {
|
|
|
|
|
case DMX_FUNCTION_TERMINATE:
|
|
|
|
|
return 1;
|
|
|
|
|
default:
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
2008-06-24 12:18:22 -04:00
|
|
|
|
|
|
|
|
void dmxBackendKbdOff(DevicePtr pDev)
|
|
|
|
|
{
|
2008-07-21 12:01:09 -04:00
|
|
|
char state[32];
|
|
|
|
|
|
|
|
|
|
memset (state, 0, sizeof (state));
|
|
|
|
|
|
|
|
|
|
dmxUpdateKeyState ((DeviceIntPtr) pDev, state);
|
|
|
|
|
dmxUpdateButtonState ((DeviceIntPtr) pDev, state);
|
|
|
|
|
|
2008-06-24 12:18:22 -04:00
|
|
|
dmxCommonKbdOff (pDev);
|
|
|
|
|
}
|