mirror of
https://gitlab.freedesktop.org/xorg/xserver.git
synced 2025-12-22 22:00:06 +01:00
Keep track of input focus and pointer location.
This commit is contained in:
parent
f2d45e1153
commit
b27fbaf53e
2 changed files with 123 additions and 9 deletions
|
|
@ -47,11 +47,12 @@
|
||||||
#include <X11/keysym.h>
|
#include <X11/keysym.h>
|
||||||
#include <xcb/xinput.h>
|
#include <xcb/xinput.h>
|
||||||
|
|
||||||
#define DMX_KEYBOARD_EVENT_MASK \
|
#define DMX_KEYBOARD_EVENT_MASK \
|
||||||
(KeyPressMask | KeyReleaseMask | KeymapStateMask)
|
(KeyPressMask | KeyReleaseMask | KeymapStateMask | FocusChangeMask)
|
||||||
|
|
||||||
#define DMX_POINTER_EVENT_MASK \
|
#define DMX_POINTER_EVENT_MASK \
|
||||||
(ButtonPressMask | ButtonReleaseMask | PointerMotionMask)
|
(ButtonPressMask | ButtonReleaseMask | PointerMotionMask | \
|
||||||
|
LeaveWindowMask)
|
||||||
|
|
||||||
static EventListPtr dmxEvents = NULL;
|
static EventListPtr dmxEvents = NULL;
|
||||||
|
|
||||||
|
|
@ -555,6 +556,27 @@ typedef struct dmx_xcb_input_extended_grab_device_request_t {
|
||||||
uint16_t generic_event_count;
|
uint16_t generic_event_count;
|
||||||
} dmx_xcb_input_extended_grab_device_request_t;
|
} dmx_xcb_input_extended_grab_device_request_t;
|
||||||
|
|
||||||
|
#define DMX_XCB_INPUT_DEVICE_LEAVE_NOTIFY 17
|
||||||
|
|
||||||
|
typedef struct dmx_xcb_input_device_state_notify_event_t {
|
||||||
|
uint8_t response_type;
|
||||||
|
uint8_t detail;
|
||||||
|
uint16_t sequence;
|
||||||
|
xcb_timestamp_t time;
|
||||||
|
xcb_window_t root;
|
||||||
|
xcb_window_t event;
|
||||||
|
xcb_window_t child;
|
||||||
|
int16_t root_x;
|
||||||
|
int16_t root_y;
|
||||||
|
int16_t event_x;
|
||||||
|
int16_t event_y;
|
||||||
|
uint16_t state;
|
||||||
|
uint8_t mode;
|
||||||
|
uint8_t device_id;
|
||||||
|
} dmx_xcb_input_device_state_notify_event_t;
|
||||||
|
|
||||||
|
typedef xcb_input_focus_in_event_t dmx_xcb_input_focus_out_event_t;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dmxDeviceGrabKeyboard (DeviceIntPtr pDevice,
|
dmxDeviceGrabKeyboard (DeviceIntPtr pDevice,
|
||||||
WindowPtr pWindow)
|
WindowPtr pWindow)
|
||||||
|
|
@ -802,6 +824,23 @@ dmxDevicePointerReplyCheck (DeviceIntPtr pDevice,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dmxDevicePointerActivate (DeviceIntPtr pDevice)
|
||||||
|
{
|
||||||
|
dmxDevicePrivPtr pDevPriv = DMX_GET_DEVICE_PRIV (pDevice);
|
||||||
|
|
||||||
|
if (pDevPriv->active)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pDevPriv->active = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dmxDevicePointerDeactivate (DeviceIntPtr pDevice)
|
||||||
|
{
|
||||||
|
DMX_GET_DEVICE_PRIV (pDevice)->active = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dmxUpdateSpriteFromEvent (DeviceIntPtr pDevice,
|
dmxUpdateSpriteFromEvent (DeviceIntPtr pDevice,
|
||||||
xcb_window_t event,
|
xcb_window_t event,
|
||||||
|
|
@ -859,6 +898,7 @@ dmxUpdateSpriteFromEvent (DeviceIntPtr pDevice,
|
||||||
y += pWin->drawable.y;
|
y += pWin->drawable.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dmxDevicePointerActivate (pDevice);
|
||||||
dmxEndFakeMotion (&dmxScreen->input);
|
dmxEndFakeMotion (&dmxScreen->input);
|
||||||
dmxBEDnDSpriteUpdate (pScreen, event, rootX, rootY);
|
dmxBEDnDSpriteUpdate (pScreen, event, rootX, rootY);
|
||||||
dmxUpdateSpritePosition (pDevice, x, y);
|
dmxUpdateSpritePosition (pDevice, x, y);
|
||||||
|
|
@ -901,6 +941,13 @@ dmxDevicePointerEventCheck (DeviceIntPtr pDevice,
|
||||||
xbutton->detail,
|
xbutton->detail,
|
||||||
type);
|
type);
|
||||||
} break;
|
} break;
|
||||||
|
case XCB_LEAVE_NOTIFY: {
|
||||||
|
xcb_leave_notify_event_t *xcrossing =
|
||||||
|
(xcb_leave_notify_event_t *) event;
|
||||||
|
|
||||||
|
if (xcrossing->detail != XCB_NOTIFY_DETAIL_INFERIOR)
|
||||||
|
dmxDevicePointerDeactivate (pButtonDev);
|
||||||
|
} break;
|
||||||
default:
|
default:
|
||||||
if (id < 0)
|
if (id < 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
@ -983,6 +1030,16 @@ dmxDevicePointerEventCheck (DeviceIntPtr pDevice,
|
||||||
memcpy (&pDevPriv->keysbuttons[4], xstate->buttons, 28);
|
memcpy (&pDevPriv->keysbuttons[4], xstate->buttons, 28);
|
||||||
dmxUpdateButtonState (pButtonDev, pDevPriv->keysbuttons);
|
dmxUpdateButtonState (pButtonDev, pDevPriv->keysbuttons);
|
||||||
} break;
|
} break;
|
||||||
|
case DMX_XCB_INPUT_DEVICE_LEAVE_NOTIFY: {
|
||||||
|
dmx_xcb_input_device_state_notify_event_t *xcrossing =
|
||||||
|
(dmx_xcb_input_device_state_notify_event_t *) event;
|
||||||
|
|
||||||
|
if (id != (xcrossing->device_id & DEVICE_BITS))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (xcrossing->detail != XCB_NOTIFY_DETAIL_INFERIOR)
|
||||||
|
dmxDevicePointerDeactivate (pButtonDev);
|
||||||
|
} break;
|
||||||
default:
|
default:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
@ -991,6 +1048,23 @@ dmxDevicePointerEventCheck (DeviceIntPtr pDevice,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dmxDeviceKeyboardActivate (DeviceIntPtr pDevice)
|
||||||
|
{
|
||||||
|
dmxDevicePrivPtr pDevPriv = DMX_GET_DEVICE_PRIV (pDevice);
|
||||||
|
|
||||||
|
if (pDevPriv->active)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pDevPriv->active = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dmxDeviceKeyboardDeactivate (DeviceIntPtr pDevice)
|
||||||
|
{
|
||||||
|
DMX_GET_DEVICE_PRIV (pDevice)->active = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dmxUpdateKeyStateFromEvent (DeviceIntPtr pDevice,
|
dmxUpdateKeyStateFromEvent (DeviceIntPtr pDevice,
|
||||||
xcb_window_t event,
|
xcb_window_t event,
|
||||||
|
|
@ -1106,6 +1180,18 @@ dmxDeviceKeyboardEventCheck (DeviceIntPtr pDevice,
|
||||||
xmapping->first_keycode,
|
xmapping->first_keycode,
|
||||||
xmapping->count);
|
xmapping->count);
|
||||||
} break;
|
} break;
|
||||||
|
case XCB_FOCUS_IN: {
|
||||||
|
xcb_focus_in_event_t *xfocus = (xcb_focus_in_event_t *) event;
|
||||||
|
|
||||||
|
if (xfocus->detail != XCB_NOTIFY_DETAIL_INFERIOR)
|
||||||
|
dmxDeviceKeyboardActivate (pKeyDev);
|
||||||
|
} break;
|
||||||
|
case XCB_FOCUS_OUT: {
|
||||||
|
xcb_focus_out_event_t *xfocus = (xcb_focus_out_event_t *) event;
|
||||||
|
|
||||||
|
if (xfocus->detail != XCB_NOTIFY_DETAIL_INFERIOR)
|
||||||
|
dmxDeviceKeyboardDeactivate (pKeyDev);
|
||||||
|
} break;
|
||||||
default:
|
default:
|
||||||
if (id < 0)
|
if (id < 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
@ -1184,6 +1270,26 @@ dmxDeviceKeyboardEventCheck (DeviceIntPtr pDevice,
|
||||||
xmapping->first_keycode,
|
xmapping->first_keycode,
|
||||||
xmapping->count);
|
xmapping->count);
|
||||||
} break;
|
} break;
|
||||||
|
case XCB_INPUT_FOCUS_IN: {
|
||||||
|
xcb_input_focus_in_event_t *xfocus =
|
||||||
|
(xcb_input_focus_in_event_t *) event;
|
||||||
|
|
||||||
|
if (id != (xfocus->device_id & DEVICE_BITS))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (xfocus->detail != XCB_NOTIFY_DETAIL_INFERIOR)
|
||||||
|
dmxDeviceKeyboardActivate (pKeyDev);
|
||||||
|
} break;
|
||||||
|
case XCB_INPUT_FOCUS_OUT: {
|
||||||
|
dmx_xcb_input_focus_out_event_t *xfocus =
|
||||||
|
(dmx_xcb_input_focus_out_event_t *) event;
|
||||||
|
|
||||||
|
if (id != (xfocus->device_id & DEVICE_BITS))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (xfocus->detail != XCB_NOTIFY_DETAIL_INFERIOR)
|
||||||
|
dmxDeviceKeyboardDeactivate (pKeyDev);
|
||||||
|
} break;
|
||||||
default:
|
default:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
@ -1333,7 +1439,7 @@ dmxKeyboardOn (DeviceIntPtr pDevice)
|
||||||
|
|
||||||
if (pDevPriv->deviceId >= 0)
|
if (pDevPriv->deviceId >= 0)
|
||||||
{
|
{
|
||||||
XEventClass cls[3];
|
XEventClass cls[5];
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
pDevPriv->device = XOpenDevice (dmxScreen->beDisplay,
|
pDevPriv->device = XOpenDevice (dmxScreen->beDisplay,
|
||||||
|
|
@ -1349,10 +1455,12 @@ dmxKeyboardOn (DeviceIntPtr pDevice)
|
||||||
DeviceKeyPress (pDevPriv->device, type, cls[0]);
|
DeviceKeyPress (pDevPriv->device, type, cls[0]);
|
||||||
DeviceKeyRelease (pDevPriv->device, type, cls[1]);
|
DeviceKeyRelease (pDevPriv->device, type, cls[1]);
|
||||||
DeviceStateNotify (pDevPriv->device, type, cls[2]);
|
DeviceStateNotify (pDevPriv->device, type, cls[2]);
|
||||||
|
DeviceFocusIn (pDevPriv->device, type, cls[3]);
|
||||||
|
DeviceFocusOut (pDevPriv->device, type, cls[4]);
|
||||||
|
|
||||||
XLIB_PROLOGUE (dmxScreen);
|
XLIB_PROLOGUE (dmxScreen);
|
||||||
XSelectExtensionEvent (dmxScreen->beDisplay, dmxScreen->rootWin,
|
XSelectExtensionEvent (dmxScreen->beDisplay, dmxScreen->rootWin,
|
||||||
cls, 3);
|
cls, 5);
|
||||||
XLIB_EPILOGUE (dmxScreen);
|
XLIB_EPILOGUE (dmxScreen);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -1483,11 +1591,12 @@ static int
|
||||||
dmxPointerOn (DeviceIntPtr pDevice)
|
dmxPointerOn (DeviceIntPtr pDevice)
|
||||||
{
|
{
|
||||||
dmxDevicePrivPtr pDevPriv = DMX_GET_DEVICE_PRIV (pDevice);
|
dmxDevicePrivPtr pDevPriv = DMX_GET_DEVICE_PRIV (pDevice);
|
||||||
DMXScreenInfo *dmxScreen = (DMXScreenInfo *) pDevPriv->dmxInput;
|
DMXInputInfo *dmxInput = pDevPriv->dmxInput;
|
||||||
|
DMXScreenInfo *dmxScreen = (DMXScreenInfo *) dmxInput;
|
||||||
|
|
||||||
if (pDevPriv->deviceId >= 0)
|
if (pDevPriv->deviceId >= 0)
|
||||||
{
|
{
|
||||||
XEventClass cls[5];
|
XEventClass cls[6];
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
pDevPriv->device = XOpenDevice (dmxScreen->beDisplay,
|
pDevPriv->device = XOpenDevice (dmxScreen->beDisplay,
|
||||||
|
|
@ -1505,9 +1614,12 @@ dmxPointerOn (DeviceIntPtr pDevice)
|
||||||
DeviceButtonPressGrab (pDevPriv->device, type, cls[3]);
|
DeviceButtonPressGrab (pDevPriv->device, type, cls[3]);
|
||||||
DeviceStateNotify (pDevPriv->device, type, cls[4]);
|
DeviceStateNotify (pDevPriv->device, type, cls[4]);
|
||||||
|
|
||||||
|
cls[5] = (pDevPriv->device->device_id << 8) |
|
||||||
|
(dmxInput->eventBase + DMX_XCB_INPUT_DEVICE_LEAVE_NOTIFY);
|
||||||
|
|
||||||
XLIB_PROLOGUE (dmxScreen);
|
XLIB_PROLOGUE (dmxScreen);
|
||||||
XSelectExtensionEvent (dmxScreen->beDisplay, dmxScreen->rootWin,
|
XSelectExtensionEvent (dmxScreen->beDisplay, dmxScreen->rootWin,
|
||||||
cls, 5);
|
cls, 6);
|
||||||
XLIB_EPILOGUE (dmxScreen);
|
XLIB_EPILOGUE (dmxScreen);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -1665,6 +1777,7 @@ dmxAddInputDevice (DMXInputInfo *dmxInput,
|
||||||
pDevPriv->masterId = masterId;
|
pDevPriv->masterId = masterId;
|
||||||
pDevPriv->device = NULL;
|
pDevPriv->device = NULL;
|
||||||
pDevPriv->fakeGrab = xFalse;
|
pDevPriv->fakeGrab = xFalse;
|
||||||
|
pDevPriv->active = xFalse;
|
||||||
pDevPriv->EventCheck = EventCheck;
|
pDevPriv->EventCheck = EventCheck;
|
||||||
pDevPriv->ReplyCheck = ReplyCheck;
|
pDevPriv->ReplyCheck = ReplyCheck;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ typedef struct _dmxDevicePriv {
|
||||||
KeyCode *keycode;
|
KeyCode *keycode;
|
||||||
xcb_void_cookie_t grab;
|
xcb_void_cookie_t grab;
|
||||||
Bool fakeGrab;
|
Bool fakeGrab;
|
||||||
|
Bool active;
|
||||||
|
|
||||||
Bool (*EventCheck) (DeviceIntPtr, xcb_generic_event_t *);
|
Bool (*EventCheck) (DeviceIntPtr, xcb_generic_event_t *);
|
||||||
Bool (*ReplyCheck) (DeviceIntPtr, unsigned int, xcb_generic_reply_t *);
|
Bool (*ReplyCheck) (DeviceIntPtr, unsigned int, xcb_generic_reply_t *);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue