Merge remote-tracking branch 'whot/for-keith'
I've looked at these patches, but I can't say I've actually reviewed them...
This commit is contained in:
commit
6d508b8185
|
@ -1409,7 +1409,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
|
|||
ptrev->device_event.corestate = event_get_corestate(dev, kbd);
|
||||
|
||||
if (grab) {
|
||||
/* this side-steps the usual activation mechansims, but... */
|
||||
/* this side-steps the usual activation mechanisms, but... */
|
||||
if (ev->any.type == ET_TouchBegin && !dev->deviceGrab.grab)
|
||||
ActivatePassiveGrab(dev, grab, ptrev, ev); /* also delivers the event */
|
||||
else {
|
||||
|
@ -1566,6 +1566,19 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev)
|
|||
else
|
||||
ti = TouchFindByClientID(dev, touchid);
|
||||
|
||||
/* Active pointer grab */
|
||||
if (emulate_pointer && dev->deviceGrab.grab && !dev->deviceGrab.fromPassiveGrab &&
|
||||
(dev->deviceGrab.grab->grabtype == CORE ||
|
||||
dev->deviceGrab.grab->grabtype == XI ||
|
||||
!xi2mask_isset(dev->deviceGrab.grab->xi2mask, dev, XI_TouchBegin)))
|
||||
{
|
||||
/* Active pointer grab on touch point and we get a TouchEnd - claim this
|
||||
* touchpoint accepted, otherwise clients waiting for ownership will
|
||||
* wait on this touchpoint until this client ungrabs, or the cows come
|
||||
* home, whichever is earlier */
|
||||
if (ti && type == ET_TouchEnd)
|
||||
TouchListenerAcceptReject(dev, ti, 0, XIAcceptTouch);
|
||||
else if (!ti && type != ET_TouchBegin) {
|
||||
/* Under the following circumstances we create a new touch record for an
|
||||
* existing touch:
|
||||
*
|
||||
|
@ -1576,11 +1589,6 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev)
|
|||
* This allows for an explicit grab to receive pointer events for an already
|
||||
* active touch.
|
||||
*/
|
||||
if (!ti && type != ET_TouchBegin && emulate_pointer &&
|
||||
dev->deviceGrab.grab && !dev->deviceGrab.fromPassiveGrab &&
|
||||
(dev->deviceGrab.grab->grabtype == CORE ||
|
||||
dev->deviceGrab.grab->grabtype == XI ||
|
||||
!xi2mask_isset(dev->deviceGrab.grab->xi2mask, dev, XI_TouchBegin))) {
|
||||
ti = TouchBeginTouch(dev, ev->device_event.sourceid, touchid,
|
||||
emulate_pointer);
|
||||
if (!ti) {
|
||||
|
@ -1593,6 +1601,7 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev)
|
|||
TouchBuildSprite(dev, ti, ev);
|
||||
TouchSetupListeners(dev, ti, ev);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ti) {
|
||||
DebugF("[Xi] %s: Failed to get event %d for touchpoint %d\n",
|
||||
|
|
|
@ -36,6 +36,57 @@
|
|||
|
||||
#include "xiselectev.h"
|
||||
|
||||
/**
|
||||
* Ruleset:
|
||||
* - if A has XIAllDevices, B may select on device X
|
||||
* - If A has XIAllDevices, B may select on XIAllMasterDevices
|
||||
* - If A has XIAllMasterDevices, B may select on device X
|
||||
* - If A has XIAllMasterDevices, B may select on XIAllDevices
|
||||
* - if A has device X, B may select on XIAllDevices/XIAllMasterDevices
|
||||
*/
|
||||
static int check_for_touch_selection_conflicts(ClientPtr B, WindowPtr win, int deviceid)
|
||||
{
|
||||
OtherInputMasks *inputMasks = wOtherInputMasks(win);
|
||||
InputClients *A = NULL;
|
||||
|
||||
if (inputMasks)
|
||||
A = inputMasks->inputClients;
|
||||
for (; A; A = A->next) {
|
||||
DeviceIntPtr tmp;
|
||||
|
||||
if (CLIENT_ID(A->resource) == B->index)
|
||||
continue;
|
||||
|
||||
if (deviceid == XIAllDevices)
|
||||
tmp = inputInfo.all_devices;
|
||||
else if (deviceid == XIAllMasterDevices)
|
||||
tmp = inputInfo.all_master_devices;
|
||||
else
|
||||
dixLookupDevice(&tmp, deviceid, serverClient, DixReadAccess);
|
||||
if (!tmp)
|
||||
return BadImplementation; /* this shouldn't happen */
|
||||
|
||||
/* A has XIAllDevices */
|
||||
if (xi2mask_isset_for_device(A->xi2mask, inputInfo.all_devices, XI_TouchBegin)) {
|
||||
if (deviceid == XIAllDevices)
|
||||
return BadAccess;
|
||||
}
|
||||
|
||||
/* A has XIAllMasterDevices */
|
||||
if (xi2mask_isset_for_device(A->xi2mask, inputInfo.all_master_devices, XI_TouchBegin)) {
|
||||
if (deviceid == XIAllMasterDevices)
|
||||
return BadAccess;
|
||||
}
|
||||
|
||||
/* A has this device */
|
||||
if (xi2mask_isset_for_device(A->xi2mask, tmp, XI_TouchBegin))
|
||||
return BadAccess;
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check the given mask (in len bytes) for invalid mask bits.
|
||||
* Invalid mask bits are any bits above XI2LastEvent.
|
||||
|
@ -169,30 +220,11 @@ ProcXISelectEvents(ClientPtr client)
|
|||
* same devices, including master devices.
|
||||
* XXX: This breaks if a device goes from floating to attached. */
|
||||
if (BitIsOn(bits, XI_TouchBegin)) {
|
||||
OtherInputMasks *inputMasks = wOtherInputMasks(win);
|
||||
InputClients *iclient = NULL;
|
||||
|
||||
if (inputMasks)
|
||||
iclient = inputMasks->inputClients;
|
||||
for (; iclient; iclient = iclient->next) {
|
||||
DeviceIntPtr tmp;
|
||||
|
||||
if (CLIENT_ID(iclient->resource) == client->index)
|
||||
continue;
|
||||
|
||||
if (evmask->deviceid == XIAllDevices)
|
||||
tmp = inputInfo.all_devices;
|
||||
else if (evmask->deviceid == XIAllMasterDevices)
|
||||
tmp = inputInfo.all_master_devices;
|
||||
else
|
||||
dixLookupDevice(&tmp, evmask->deviceid, serverClient,
|
||||
DixReadAccess);
|
||||
if (!tmp)
|
||||
return BadImplementation; /* this shouldn't happen */
|
||||
|
||||
if (xi2mask_isset(iclient->xi2mask, tmp, XI_TouchBegin))
|
||||
return BadAccess;
|
||||
}
|
||||
rc = check_for_touch_selection_conflicts(client,
|
||||
win,
|
||||
evmask->deviceid);
|
||||
if (rc != Success)
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
16
dix/events.c
16
dix/events.c
|
@ -1503,11 +1503,27 @@ DeactivatePointerGrab(DeviceIntPtr mouse)
|
|||
{
|
||||
GrabPtr grab = mouse->deviceGrab.grab;
|
||||
DeviceIntPtr dev;
|
||||
Bool wasPassive = mouse->deviceGrab.fromPassiveGrab;
|
||||
Bool wasImplicit = (mouse->deviceGrab.fromPassiveGrab &&
|
||||
mouse->deviceGrab.implicitGrab);
|
||||
XID grab_resource = grab->resource;
|
||||
int i;
|
||||
|
||||
/* If an explicit grab was deactivated, we must remove it from the head of
|
||||
* all the touches' listener lists. */
|
||||
for (i = 0; !wasPassive && mouse->touch && i < mouse->touch->num_touches; i++) {
|
||||
TouchPointInfoPtr ti = mouse->touch->touches + i;
|
||||
if (ti->active && TouchResourceIsOwner(ti, grab_resource)) {
|
||||
/* Rejecting will generate a TouchEnd, but we must not
|
||||
emulate a ButtonRelease here. So pretend the listener
|
||||
already has the end event */
|
||||
if (grab->grabtype == CORE || grab->grabtype == XI ||
|
||||
!xi2mask_isset(dev->deviceGrab.grab->xi2mask, dev, XI_TouchBegin))
|
||||
ti->listeners[0].state = LISTENER_HAS_END;
|
||||
TouchListenerAcceptReject(mouse, ti, 0, XIRejectTouch);
|
||||
}
|
||||
}
|
||||
|
||||
TouchRemovePointerGrab(mouse);
|
||||
|
||||
mouse->valuator->motionHintWindow = NullWindow;
|
||||
|
|
|
@ -1015,6 +1015,21 @@ xi2mask_free(XI2Mask **mask)
|
|||
*mask = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the bit for event type is set for this device only.
|
||||
*
|
||||
* @return TRUE if the bit is set, FALSE otherwise
|
||||
*/
|
||||
Bool
|
||||
xi2mask_isset_for_device(XI2Mask *mask, const DeviceIntPtr dev, int event_type)
|
||||
{
|
||||
BUG_WARN(dev->id < 0);
|
||||
BUG_WARN(dev->id >= mask->nmasks);
|
||||
BUG_WARN(bits_to_bytes(event_type + 1) > mask->mask_size);
|
||||
|
||||
return BitIsOn(mask->masks[dev->id], event_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the bit for event type is set for this device, or the
|
||||
* XIAllDevices/XIAllMasterDevices (if applicable) is set.
|
||||
|
@ -1026,15 +1041,12 @@ xi2mask_isset(XI2Mask *mask, const DeviceIntPtr dev, int event_type)
|
|||
{
|
||||
int set = 0;
|
||||
|
||||
BUG_WARN(dev->id < 0);
|
||||
BUG_WARN(dev->id >= mask->nmasks);
|
||||
BUG_WARN(bits_to_bytes(event_type + 1) > mask->mask_size);
|
||||
|
||||
set = ! !BitIsOn(mask->masks[XIAllDevices], event_type);
|
||||
if (!set)
|
||||
set = ! !BitIsOn(mask->masks[dev->id], event_type);
|
||||
if (!set && IsMaster(dev))
|
||||
set = ! !BitIsOn(mask->masks[XIAllMasterDevices], event_type);
|
||||
if (xi2mask_isset_for_device(mask, inputInfo.all_devices, event_type))
|
||||
set = 1;
|
||||
else if (xi2mask_isset_for_device(mask, dev, event_type))
|
||||
set = 1;
|
||||
else if (IsMaster(dev) && xi2mask_isset_for_device(mask, inputInfo.all_master_devices, event_type))
|
||||
set = 1;
|
||||
|
||||
return set;
|
||||
}
|
||||
|
|
|
@ -915,6 +915,8 @@ TouchRemovePointerGrab(DeviceIntPtr dev)
|
|||
ti = TouchFindByClientID(dev, ev->touchid);
|
||||
if (!ti)
|
||||
return;
|
||||
|
||||
/* FIXME: missing a bit of code here... */
|
||||
}
|
||||
|
||||
/* As touch grabs don't turn into active grabs with their own resources, we
|
||||
|
@ -987,8 +989,6 @@ TouchListenerAcceptReject(DeviceIntPtr dev, TouchPointInfoPtr ti, int listener,
|
|||
for (i = 0; i < nev; i++)
|
||||
mieqProcessDeviceEvent(dev, events + i, NULL);
|
||||
|
||||
ProcessInputEvents();
|
||||
|
||||
FreeEventList(events, GetMaximumEventsNum());
|
||||
|
||||
return nev ? Success : BadMatch;
|
||||
|
|
|
@ -57,6 +57,7 @@ XI2Mask *xi2mask_new(void);
|
|||
XI2Mask *xi2mask_new_with_size(size_t, size_t); /* don't use it */
|
||||
void xi2mask_free(XI2Mask **mask);
|
||||
Bool xi2mask_isset(XI2Mask *mask, const DeviceIntPtr dev, int event_type);
|
||||
Bool xi2mask_isset_for_device(XI2Mask *mask, const DeviceIntPtr dev, int event_type);
|
||||
void xi2mask_set(XI2Mask *mask, int deviceid, int event_type);
|
||||
void xi2mask_zero(XI2Mask *mask, int deviceid);
|
||||
void xi2mask_merge(XI2Mask *dest, const XI2Mask *source);
|
||||
|
|
|
@ -36,8 +36,14 @@ xi2mask_test(void)
|
|||
XI2Mask *xi2mask = NULL, *mergemask = NULL;
|
||||
unsigned char *mask;
|
||||
DeviceIntRec dev;
|
||||
DeviceIntRec all_devices, all_master_devices;
|
||||
int i;
|
||||
|
||||
all_devices.id = XIAllDevices;
|
||||
inputInfo.all_devices = &all_devices;
|
||||
all_master_devices.id = XIAllMasterDevices;
|
||||
inputInfo.all_master_devices = &all_master_devices;
|
||||
|
||||
/* size >= nmasks * 2 for the test cases below */
|
||||
xi2mask = xi2mask_new_with_size(MAXDEVICES + 2, (MAXDEVICES + 2) * 2);
|
||||
assert(xi2mask);
|
||||
|
|
|
@ -74,7 +74,7 @@ ProcXFixesQueryVersion(ClientPtr client)
|
|||
|
||||
if (version_compare(stuff->majorVersion, stuff->minorVersion,
|
||||
SERVER_XFIXES_MAJOR_VERSION,
|
||||
SERVER_XFIXES_MAJOR_VERSION) < 0) {
|
||||
SERVER_XFIXES_MINOR_VERSION) < 0) {
|
||||
rep.majorVersion = stuff->majorVersion;
|
||||
rep.minorVersion = stuff->minorVersion;
|
||||
}
|
||||
|
|
|
@ -723,9 +723,6 @@ ProcessPointerEvent(InternalEvent *ev, DeviceIntPtr mouse)
|
|||
changed |= XkbPointerButtonMask;
|
||||
}
|
||||
else if (event->type == ET_ButtonRelease) {
|
||||
if (xkbi) {
|
||||
xkbi->lockedPtrButtons &= ~(1 << (event->detail.key & 0x7));
|
||||
|
||||
if (IsMaster(dev)) {
|
||||
DeviceIntPtr source;
|
||||
int rc;
|
||||
|
@ -735,11 +732,18 @@ ProcessPointerEvent(InternalEvent *ev, DeviceIntPtr mouse)
|
|||
if (rc != Success)
|
||||
ErrorF("[xkb] bad sourceid '%d' on button release event.\n",
|
||||
event->sourceid);
|
||||
else if (!IsXTestDevice(source, GetMaster(dev, MASTER_POINTER)))
|
||||
else if (!IsXTestDevice(source, GetMaster(dev, MASTER_POINTER))) {
|
||||
DeviceIntPtr xtest_device;
|
||||
|
||||
xtest_device = GetXTestDevice(GetMaster(dev, MASTER_POINTER));
|
||||
if (button_is_down(xtest_device, ev->device_event.detail.button, BUTTON_PROCESSED))
|
||||
XkbFakeDeviceButton(dev, FALSE, event->detail.key);
|
||||
}
|
||||
}
|
||||
|
||||
if (xkbi)
|
||||
xkbi->lockedPtrButtons &= ~(1 << (event->detail.key & 0x7));
|
||||
|
||||
changed |= XkbPointerButtonMask;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user