summaryrefslogtreecommitdiff
path: root/dix
diff options
context:
space:
mode:
Diffstat (limited to 'dix')
-rw-r--r--dix/devices.c6
-rw-r--r--dix/events.c43
-rw-r--r--dix/getevents.c61
-rw-r--r--dix/grabs.c5
-rw-r--r--dix/touch.c40
5 files changed, 103 insertions, 52 deletions
diff --git a/dix/devices.c b/dix/devices.c
index fd4916a3a..7d7888ea1 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -514,6 +514,12 @@ DisableAllDevices(void)
{
DeviceIntPtr dev, tmp;
+ /* Disable slave devices first, excluding XTest devices */
+ nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) {
+ if (!IsXTestDevice(dev, NULL) && !IsMaster(dev))
+ DisableDevice(dev, FALSE);
+ }
+ /* Disable XTest devices */
nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) {
if (!IsMaster(dev))
DisableDevice(dev, FALSE);
diff --git a/dix/events.c b/dix/events.c
index ddb5b343d..a43c99ac9 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1435,6 +1435,7 @@ UpdateTouchesForGrab(DeviceIntPtr mouse)
ti->listeners[0].type = LISTENER_POINTER_GRAB;
else
ti->listeners[0].type = LISTENER_GRAB;
+ ti->listeners[0].grab = grab;
}
}
}
@@ -1503,11 +1504,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(mouse->deviceGrab.grab->xi2mask, mouse, XI_TouchBegin))
+ ti->listeners[0].state = LISTENER_HAS_END;
+ TouchListenerAcceptReject(mouse, ti, 0, XIRejectTouch);
+ }
+ }
+
TouchRemovePointerGrab(mouse);
mouse->valuator->motionHintWindow = NullWindow;
@@ -1531,15 +1548,6 @@ DeactivatePointerGrab(DeviceIntPtr mouse)
ReattachToOldMaster(mouse);
ComputeFreezes();
-
- /* If an explicit grab was deactivated, we must remove it from the head of
- * all the touches' listener lists. */
- for (i = 0; mouse->touch && i < mouse->touch->num_touches; i++) {
- TouchPointInfoPtr ti = mouse->touch->touches + i;
-
- if (ti->active && TouchResourceIsOwner(ti, grab_resource))
- TouchListenerAcceptReject(mouse, ti, 0, XIRejectTouch);
- }
}
/**
@@ -2224,7 +2232,7 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
* @return TRUE if the event should be discarded, FALSE otherwise.
*/
static BOOL
-FilterRawEvents(const ClientPtr client, const GrabPtr grab)
+FilterRawEvents(const ClientPtr client, const GrabPtr grab, WindowPtr root)
{
XIClientPtr client_xi_version;
int cmp;
@@ -2240,7 +2248,10 @@ FilterRawEvents(const ClientPtr client, const GrabPtr grab)
client_xi_version->minor_version, 2, 0);
/* XI 2.0: if device is grabbed, skip
XI 2.1: if device is grabbed by us, skip, we've already delivered */
- return (cmp == 0) ? TRUE : SameClient(grab, client);
+ if (cmp == 0)
+ return TRUE;
+
+ return (grab->window != root) ? FALSE : SameClient(grab, client);
}
/**
@@ -2293,7 +2304,7 @@ DeliverRawEvent(RawDeviceEvent *ev, DeviceIntPtr device)
*/
ic.next = NULL;
- if (!FilterRawEvents(rClient(&ic), grab))
+ if (!FilterRawEvents(rClient(&ic), grab, root))
DeliverEventToInputClients(device, &ic, root, xi, 1,
filter, NULL, &c, &m);
}
@@ -4550,6 +4561,7 @@ DeviceEnterLeaveEvent(DeviceIntPtr mouse,
{
GrabPtr grab = mouse->deviceGrab.grab;
xXIEnterEvent *event;
+ WindowPtr focus;
int filter;
int btlen, len, i;
DeviceIntPtr kbd;
@@ -4591,6 +4603,11 @@ DeviceEnterLeaveEvent(DeviceIntPtr mouse,
event->group.locked_group = kbd->key->xkbInfo->state.locked_group;
}
+ focus = (kbd) ? kbd->focus->win : None;
+ if ((focus != NoneWin) &&
+ ((pWin == focus) || (focus == PointerRootWin) || IsParent(focus, pWin)))
+ event->focus = TRUE;
+
FixUpEventFromWindow(mouse->spriteInfo->sprite, (xEvent *) event, pWin,
None, FALSE);
@@ -5027,7 +5044,7 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev,
grab = grabInfo->grab;
if (grab && grab->grabtype != grabtype)
*status = AlreadyGrabbed;
- if (grab && !SameClient(grab, client))
+ else if (grab && !SameClient(grab, client))
*status = AlreadyGrabbed;
else if ((!pWin->realized) ||
(confineTo &&
diff --git a/dix/getevents.c b/dix/getevents.c
index 8b4379d1c..707678352 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -787,11 +787,33 @@ add_to_scroll_valuator(DeviceIntPtr dev, ValuatorMask *mask, int valuator, doubl
* @param[in,out] mask Valuator data for this event, modified in-place.
*/
static void
-moveRelative(DeviceIntPtr dev, ValuatorMask *mask)
+moveRelative(DeviceIntPtr dev, int flags, ValuatorMask *mask)
{
int i;
Bool clip_xy = IsMaster(dev) || !IsFloating(dev);
+ /* for abs devices in relative mode, we've just scaled wrong, since we
+ mapped the device's shape into the screen shape. Undo this. */
+ if ((flags & POINTER_ABSOLUTE) == 0 && dev->valuator &&
+ dev->valuator->axes[0].min_value < dev->valuator->axes[0].max_value) {
+
+ double ratio = 1.0 * screenInfo.width/screenInfo.height;
+
+ if (ratio > 1.0) {
+ double y;
+ if (valuator_mask_fetch_double(mask, 1, &y)) {
+ y *= ratio;
+ valuator_mask_set_double(mask, 1, y);
+ }
+ } else {
+ double x;
+ if (valuator_mask_fetch_double(mask, 0, &x)) {
+ x *= ratio;
+ valuator_mask_set_double(mask, 0, x);
+ }
+ }
+ }
+
/* calc other axes, clip, drop back into valuators */
for (i = 0; i < valuator_mask_size(mask); i++) {
double val = dev->last.valuators[i];
@@ -844,14 +866,14 @@ scale_from_screen(DeviceIntPtr dev, ValuatorMask *mask)
scaled = valuator_mask_get_double(mask, 0) + scr->x;
scaled = rescaleValuatorAxis(scaled,
NULL, dev->valuator->axes + 0,
- 0, scr->width);
+ screenInfo.x, screenInfo.width);
valuator_mask_set_double(mask, 0, scaled);
}
if (valuator_mask_isset(mask, 1)) {
scaled = valuator_mask_get_double(mask, 1) + scr->y;
scaled = rescaleValuatorAxis(scaled,
NULL, dev->valuator->axes + 1,
- 0, scr->height);
+ screenInfo.y, screenInfo.height);
valuator_mask_set_double(mask, 1, scaled);
}
}
@@ -1387,7 +1409,7 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
if ((flags & POINTER_NORAW) == 0)
set_raw_valuators(raw, &mask, raw->valuators.data);
- moveRelative(pDev, &mask);
+ moveRelative(pDev, flags, &mask);
}
/* valuators are in device coordinate system in absolute coordinates */
@@ -1951,32 +1973,27 @@ GetTouchEvents(InternalEvent *events, DeviceIntPtr dev, uint32_t ddx_touchid,
default:
return 0;
}
- if (t->mode == XIDirectTouch && !(flags & TOUCH_CLIENT_ID)) {
- if (!valuator_mask_isset(&mask, 0))
- valuator_mask_set_double(&mask, 0,
- valuator_mask_get_double(touchpoint.ti->
- valuators, 0));
- if (!valuator_mask_isset(&mask, 1))
- valuator_mask_set_double(&mask, 1,
- valuator_mask_get_double(touchpoint.ti->
- valuators, 1));
- }
/* Get our screen event co-ordinates (root_x/root_y/event_x/event_y):
* these come from the touchpoint in Absolute mode, or the sprite in
* Relative. */
if (t->mode == XIDirectTouch) {
- transformAbsolute(dev, &mask);
-
if (!(flags & TOUCH_CLIENT_ID)) {
- for (i = 0; i < valuator_mask_size(&mask); i++) {
- double val;
-
- if (valuator_mask_fetch_double(&mask, i, &val))
- valuator_mask_set_double(touchpoint.ti->valuators, i, val);
- }
+ for (i = 0; i < max(valuator_mask_size(&mask), 2); i++) {
+ double val;
+
+ if (valuator_mask_fetch_double(&mask, i, &val))
+ valuator_mask_set_double(touchpoint.ti->valuators, i, val);
+ /* If the device doesn't post new X and Y axis values,
+ * use the last values posted.
+ */
+ else if (i < 2 &&
+ valuator_mask_fetch_double(touchpoint.ti->valuators, i, &val))
+ valuator_mask_set_double(&mask, i, val);
+ }
}
+ transformAbsolute(dev, &mask);
clipAbsolute(dev, &mask);
}
else {
diff --git a/dix/grabs.c b/dix/grabs.c
index 55bf64f2c..d55a69cf0 100644
--- a/dix/grabs.c
+++ b/dix/grabs.c
@@ -219,7 +219,10 @@ CreateGrab(int client, DeviceIntPtr device, DeviceIntPtr modDevice,
grab->resource = FakeClientID(client);
grab->device = device;
grab->window = window;
- grab->eventMask = mask->core; /* same for XI */
+ if (grabtype == CORE || grabtype == XI)
+ grab->eventMask = mask->core; /* same for XI */
+ else
+ grab->eventMask = 0;
grab->deviceMask = 0;
grab->ownerEvents = param->ownerEvents;
grab->keyboardMode = param->this_device_mode;
diff --git a/dix/touch.c b/dix/touch.c
index 5f77be575..2b30b7df0 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -682,15 +682,20 @@ TouchResourceIsOwner(TouchPointInfoPtr ti, XID resource)
* Add the resource to this touch's listeners.
*/
void
-TouchAddListener(TouchPointInfoPtr ti, XID resource, enum InputLevel level,
- enum TouchListenerType type, enum TouchListenerState state,
- WindowPtr window)
+TouchAddListener(TouchPointInfoPtr ti, XID resource, int resource_type,
+ enum InputLevel level, enum TouchListenerType type,
+ enum TouchListenerState state, WindowPtr window,
+ GrabPtr grab)
{
ti->listeners[ti->num_listeners].listener = resource;
+ ti->listeners[ti->num_listeners].resource_type = resource_type;
ti->listeners[ti->num_listeners].level = level;
ti->listeners[ti->num_listeners].state = state;
ti->listeners[ti->num_listeners].type = type;
ti->listeners[ti->num_listeners].window = window;
+ ti->listeners[ti->num_listeners].grab = grab;
+ if (grab)
+ ti->num_grabs++;
ti->num_listeners++;
}
@@ -709,6 +714,11 @@ TouchRemoveListener(TouchPointInfoPtr ti, XID resource)
if (ti->listeners[i].listener == resource) {
int j;
+ if (ti->listeners[i].grab) {
+ ti->listeners[i].grab = NULL;
+ ti->num_grabs--;
+ }
+
for (j = i; j < ti->num_listeners - 1; j++)
ti->listeners[j] = ti->listeners[j + 1];
ti->num_listeners--;
@@ -739,9 +749,9 @@ TouchAddGrabListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
type = LISTENER_POINTER_GRAB;
}
- TouchAddListener(ti, grab->resource, grab->grabtype,
- type, LISTENER_AWAITING_BEGIN, grab->window);
- ti->num_grabs++;
+ /* grab listeners are always RT_NONE since we keep the grab pointer */
+ TouchAddListener(ti, grab->resource, RT_NONE, grab->grabtype,
+ type, LISTENER_AWAITING_BEGIN, grab->window, grab);
}
/**
@@ -796,8 +806,8 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
if (!xi2mask_isset(iclients->xi2mask, dev, XI_TouchOwnership))
TouchEventHistoryAllocate(ti);
- TouchAddListener(ti, iclients->resource, XI2,
- type, LISTENER_AWAITING_BEGIN, win);
+ TouchAddListener(ti, iclients->resource, RT_INPUTCLIENT, XI2,
+ type, LISTENER_AWAITING_BEGIN, win, NULL);
return TRUE;
}
}
@@ -811,9 +821,9 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
continue;
TouchEventHistoryAllocate(ti);
- TouchAddListener(ti, iclients->resource, XI,
+ TouchAddListener(ti, iclients->resource, RT_INPUTCLIENT, XI,
LISTENER_POINTER_REGULAR, LISTENER_AWAITING_BEGIN,
- win);
+ win, NULL);
return TRUE;
}
}
@@ -826,9 +836,9 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
/* window owner */
if (IsMaster(dev) && (win->eventMask & core_filter)) {
TouchEventHistoryAllocate(ti);
- TouchAddListener(ti, win->drawable.id, CORE,
+ TouchAddListener(ti, win->drawable.id, RT_WINDOW, CORE,
LISTENER_POINTER_REGULAR, LISTENER_AWAITING_BEGIN,
- win);
+ win, NULL);
return TRUE;
}
@@ -838,8 +848,8 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
continue;
TouchEventHistoryAllocate(ti);
- TouchAddListener(ti, oclients->resource, CORE,
- type, LISTENER_AWAITING_BEGIN, win);
+ TouchAddListener(ti, oclients->resource, RT_OTHERCLIENT, CORE,
+ type, LISTENER_AWAITING_BEGIN, win, NULL);
return TRUE;
}
}
@@ -994,8 +1004,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;