xserver: Branch 'master' - 10 commits

Keith Packard keithp at kemper.freedesktop.org
Mon Nov 5 17:14:19 PST 2012


 Xi/chgdctl.c    |    5 +
 Xi/exevents.c   |   12 +++-
 dix/devices.c   |    8 +--
 xfixes/cursor.c |  145 ++++++++++++++++++++++++++++++++++++++++++--------------
 xkb/maprules.c  |    1 
 5 files changed, 129 insertions(+), 42 deletions(-)

New commits:
commit 011f8458805e443ac9130865d2840a929a00cabf
Merge: 54ba26c... b4e44b2...
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Nov 5 17:16:07 2012 -0800

    Merge remote-tracking branch 'whot/for-keith'

commit b4e44b285ed0eee1d06514215a4b01d54f40094b
Author: Carlos Garnacho <carlosg at gnome.org>
Date:   Wed Oct 31 19:29:45 2012 +0100

    Xi: Set modifier mask on touch events
    
    Button mask should be out-of-band with the emulated
    pointer events as touch devices don't truly have
    "buttons". Even though, it's handy to have the modifier
    mask from the paired keyboard on touch events.
    
    Signed-off-by: Carlos Garnacho <carlosg at gnome.org>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 5cf873c..106da3a 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1559,6 +1559,7 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev)
     uint32_t touchid;
     int type = ev->any.type;
     int emulate_pointer = ! !(ev->device_event.flags & TOUCH_POINTER_EMULATED);
+    DeviceIntPtr kbd;
 
     if (!t)
         return;
@@ -1618,6 +1619,10 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev)
     if (emulate_pointer && IsMaster(dev))
         CheckMotion(&ev->device_event, dev);
 
+    kbd = GetMaster(dev, KEYBOARD_OR_FLOAT);
+    event_set_state(NULL, kbd, &ev->device_event);
+    ev->device_event.corestate = event_get_corestate(NULL, kbd);
+
     /* Make sure we have a valid window trace for event delivery; must be
      * called after event type mutation. Touch end events are always processed
      * in order to end touch records. */
commit 863f32c930d71073ee5f78452b78bd459d024867
Author: Carlos Garnacho <carlosg at gnome.org>
Date:   Wed Oct 31 19:32:57 2012 +0100

    Xi: Update the device after delivering the emulated pointer event(#56558)
    
    Ensure emulated pointer events contain the state that applies before the
    event was processed, so the device state must be updated after delivering
    such emulated events.
    
    Co-authored-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Carlos Garnacho <carlosg at gnome.org>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 4cbeb37..5cf873c 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1568,9 +1568,6 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev)
     else
         touchid = ev->device_event.touchid;
 
-    if (emulate_pointer)
-        UpdateDeviceState(dev, &ev->device_event);
-
     if (type == ET_TouchBegin) {
         ti = TouchBeginTouch(dev, ev->device_event.sourceid, touchid,
                              emulate_pointer);
@@ -1617,6 +1614,7 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev)
      * events which _only_ emulate motion just work normally */
     if (emulate_pointer && ev->any.type != ET_TouchUpdate)
         DeliverEmulatedMotionEvent(dev, ti, ev);
+
     if (emulate_pointer && IsMaster(dev))
         CheckMotion(&ev->device_event, dev);
 
@@ -1641,6 +1639,9 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev)
         if (ev->any.type == ET_TouchEnd)
             TouchEndTouch(dev, ti);
     }
+
+    if (emulate_pointer)
+        UpdateDeviceState(dev, &ev->device_event);
 }
 
 /**
commit 9a536820f6174befb22431bab375ef1af0a1ec29
Author: Jasper St. Pierre <jstpierre at mecheye.net>
Date:   Sat Nov 3 20:23:46 2012 -0400

    cursor: Fix up implementation for per-device barriers
    
    Support multiple mast devices being specified as a parameter to the
    barrier. This should implement all parts of the XFixes specification,
    minus the existing non-specification detail where specifying no devices
    is the same as specifying XIAllDevices.
    
    Signed-off-by: Jasper St. Pierre <jstpierre at mecheye.net>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/xfixes/cursor.c b/xfixes/cursor.c
index 45b07c3..7c223dd 100644
--- a/xfixes/cursor.c
+++ b/xfixes/cursor.c
@@ -56,6 +56,7 @@
 #include "windowstr.h"
 #include "xace.h"
 #include "list.h"
+#include "exglobals.h"
 
 static RESTYPE CursorClientType;
 static RESTYPE CursorHideCountType;
@@ -118,6 +119,8 @@ struct PointerBarrierClient {
     ScreenPtr screen;
     struct PointerBarrier barrier;
     struct xorg_list entry;
+    int num_devices;
+    int *device_ids; /* num_devices */
 };
 
 /*
@@ -1132,6 +1135,31 @@ barrier_is_blocking(const struct PointerBarrier * barrier,
     return rc;
 }
 
+static BOOL
+barrier_blocks_device(struct PointerBarrierClient *client,
+                      DeviceIntPtr dev)
+{
+    int i;
+    int master_id;
+
+    /* Clients with no devices are treated as
+     * if they specified XIAllDevices. */
+    if (client->num_devices == 0)
+        return TRUE;
+
+    master_id = GetMaster(dev, POINTER_OR_FLOAT)->id;
+
+    for (i = 0; i < client->num_devices; i++) {
+        int device_id = client->device_ids[i];
+        if (device_id == XIAllDevices ||
+            device_id == XIAllMasterDevices ||
+            device_id == master_id)
+            return TRUE;
+    }
+
+    return FALSE;
+}
+
 /**
  * Find the nearest barrier that is blocking movement from x1/y1 to x2/y2.
  *
@@ -1143,7 +1171,8 @@ barrier_is_blocking(const struct PointerBarrier * barrier,
  * @return The barrier nearest to the movement origin that blocks this movement.
  */
 static struct PointerBarrier *
-barrier_find_nearest(CursorScreenPtr cs, int dir,
+barrier_find_nearest(CursorScreenPtr cs, DeviceIntPtr dev,
+                     int dir,
                      int x1, int y1, int x2, int y2)
 {
     struct PointerBarrierClient *c;
@@ -1157,6 +1186,9 @@ barrier_find_nearest(CursorScreenPtr cs, int dir,
         if (!barrier_is_blocking_direction(b, dir))
             continue;
 
+        if (!barrier_blocks_device(c, dev))
+            continue;
+
         if (barrier_is_blocking(b, x1, y1, x2, y2, &distance)) {
             if (min_distance > distance) {
                 min_distance = distance;
@@ -1221,7 +1253,7 @@ CursorConstrainCursorHarder(DeviceIntPtr dev, ScreenPtr screen, int mode,
 
 #define MAX_BARRIERS 2
         for (i = 0; i < MAX_BARRIERS; i++) {
-            nearest = barrier_find_nearest(cs, dir, ox, oy, *x, *y);
+            nearest = barrier_find_nearest(cs, dev, dir, ox, oy, *x, *y);
             if (!nearest)
                 break;
 
@@ -1251,7 +1283,14 @@ CreatePointerBarrierClient(ScreenPtr screen, ClientPtr client,
                            PointerBarrierClientPtr *client_out)
 {
     CursorScreenPtr cs = GetCursorScreen(screen);
-    struct PointerBarrierClient *ret = malloc(sizeof(*ret));
+    int err;
+    int size;
+    int i;
+    CARD16 *in_devices;
+    struct PointerBarrierClient *ret;
+
+    size = sizeof(*ret) + sizeof(int) * stuff->num_devices;
+    ret = malloc(size);
 
     *client_out = NULL;
 
@@ -1260,6 +1299,28 @@ CreatePointerBarrierClient(ScreenPtr screen, ClientPtr client,
     }
 
     ret->screen = screen;
+    ret->num_devices = stuff->num_devices;
+
+    in_devices = (CARD16 *) &stuff[1];
+    for (i = 0; i < stuff->num_devices; i++) {
+        int device_id = in_devices[i];
+        DeviceIntPtr device;
+
+        if ((err = dixLookupDevice (&device, device_id,
+                                    client, DixReadAccess))) {
+            client->errorValue = device_id;
+            goto error;
+        }
+
+        if (!IsMaster (device)) {
+            client->errorValue = device_id;
+            err = BadDevice;
+            goto error;
+        }
+
+        ret->device_ids[i] = device_id;
+    }
+
     ret->barrier.x1 = min(stuff->x1, stuff->x2);
     ret->barrier.x2 = max(stuff->x1, stuff->x2);
     ret->barrier.y1 = min(stuff->y1, stuff->y2);
@@ -1273,6 +1334,10 @@ CreatePointerBarrierClient(ScreenPtr screen, ClientPtr client,
 
     *client_out = ret;
     return Success;
+
+ error:
+    free(ret);
+    return err;
 }
 
 int
@@ -1294,10 +1359,6 @@ ProcXFixesCreatePointerBarrier(ClientPtr client)
         return err;
     }
 
-    /* This sure does need fixing. */
-    if (stuff->num_devices)
-        return BadImplementation;
-
     b.x1 = stuff->x1;
     b.x2 = stuff->x2;
     b.y1 = stuff->y1;
commit 944213bbc7099f1e0238f39973653d459efdc2c9
Author: Jasper St. Pierre <jstpierre at mecheye.net>
Date:   Sat Nov 3 20:23:45 2012 -0400

    cursor: Clean up barrier finding code a bit
    
    The current code manually unrolls the loop, by finding a barrier,
    clamping it, and then repeaing the code. Since we want to modify
    both passes of the loop to support device-specific barriers, make
    it into an actual loop.
    
    Signed-off-by: Jasper St. Pierre <jstpierre at mecheye.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/xfixes/cursor.c b/xfixes/cursor.c
index f66bd68..45b07c3 100644
--- a/xfixes/cursor.c
+++ b/xfixes/cursor.c
@@ -1204,6 +1204,7 @@ CursorConstrainCursorHarder(DeviceIntPtr dev, ScreenPtr screen, int mode,
         mode == Relative) {
         int ox, oy;
         int dir;
+        int i;
         struct PointerBarrier *nearest = NULL;
 
         /* where are we coming from */
@@ -1218,8 +1219,12 @@ CursorConstrainCursorHarder(DeviceIntPtr dev, ScreenPtr screen, int mode,
          */
         dir = barrier_get_direction(ox, oy, *x, *y);
 
-        nearest = barrier_find_nearest(cs, dir, ox, oy, *x, *y);
-        if (nearest) {
+#define MAX_BARRIERS 2
+        for (i = 0; i < MAX_BARRIERS; i++) {
+            nearest = barrier_find_nearest(cs, dir, ox, oy, *x, *y);
+            if (!nearest)
+                break;
+
             barrier_clamp_to_barrier(nearest, dir, x, y);
 
             if (barrier_is_vertical(nearest)) {
@@ -1230,11 +1235,6 @@ CursorConstrainCursorHarder(DeviceIntPtr dev, ScreenPtr screen, int mode,
                 dir &= ~(BarrierNegativeY | BarrierPositiveY);
                 oy = *y;
             }
-
-            nearest = barrier_find_nearest(cs, dir, ox, oy, *x, *y);
-            if (nearest) {
-                barrier_clamp_to_barrier(nearest, dir, x, y);
-            }
         }
     }
 
commit 1536bc2d213713af45541a15b5e49c552d8d0592
Author: Jasper St. Pierre <jstpierre at mecheye.net>
Date:   Sat Nov 3 20:23:44 2012 -0400

    cursor: Clean up pointer barrier creation code a tiny bit
    
    This will make it much simpler when we add more error paths to the code
    that constructs pointer barrier clients.
    
    Signed-off-by: Jasper St. Pierre <jstpierre at mecheye.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/xfixes/cursor.c b/xfixes/cursor.c
index 75b0374..f66bd68 100644
--- a/xfixes/cursor.c
+++ b/xfixes/cursor.c
@@ -1245,28 +1245,34 @@ CursorConstrainCursorHarder(DeviceIntPtr dev, ScreenPtr screen, int mode,
     }
 }
 
-static struct PointerBarrierClient *
+static int
 CreatePointerBarrierClient(ScreenPtr screen, ClientPtr client,
-                           xXFixesCreatePointerBarrierReq * stuff)
+                           xXFixesCreatePointerBarrierReq * stuff,
+                           PointerBarrierClientPtr *client_out)
 {
     CursorScreenPtr cs = GetCursorScreen(screen);
     struct PointerBarrierClient *ret = malloc(sizeof(*ret));
 
-    if (ret) {
-        ret->screen = screen;
-        ret->barrier.x1 = min(stuff->x1, stuff->x2);
-        ret->barrier.x2 = max(stuff->x1, stuff->x2);
-        ret->barrier.y1 = min(stuff->y1, stuff->y2);
-        ret->barrier.y2 = max(stuff->y1, stuff->y2);
-        ret->barrier.directions = stuff->directions & 0x0f;
-        if (barrier_is_horizontal(&ret->barrier))
-            ret->barrier.directions &= ~(BarrierPositiveX | BarrierNegativeX);
-        if (barrier_is_vertical(&ret->barrier))
-            ret->barrier.directions &= ~(BarrierPositiveY | BarrierNegativeY);
-        xorg_list_add(&ret->entry, &cs->barriers);
+    *client_out = NULL;
+
+    if (!ret) {
+        return BadAlloc;
     }
 
-    return ret;
+    ret->screen = screen;
+    ret->barrier.x1 = min(stuff->x1, stuff->x2);
+    ret->barrier.x2 = max(stuff->x1, stuff->x2);
+    ret->barrier.y1 = min(stuff->y1, stuff->y2);
+    ret->barrier.y2 = max(stuff->y1, stuff->y2);
+    ret->barrier.directions = stuff->directions & 0x0f;
+    if (barrier_is_horizontal(&ret->barrier))
+        ret->barrier.directions &= ~(BarrierPositiveX | BarrierNegativeX);
+    if (barrier_is_vertical(&ret->barrier))
+        ret->barrier.directions &= ~(BarrierPositiveY | BarrierNegativeY);
+    xorg_list_add(&ret->entry, &cs->barriers);
+
+    *client_out = ret;
+    return Success;
 }
 
 int
@@ -1304,9 +1310,9 @@ ProcXFixesCreatePointerBarrier(ClientPtr client)
     if (barrier_is_horizontal(&b) && barrier_is_vertical(&b))
         return BadValue;
 
-    if (!(barrier = CreatePointerBarrierClient(pWin->drawable.pScreen,
-                                               client, stuff)))
-        return BadAlloc;
+    if ((err = CreatePointerBarrierClient(pWin->drawable.pScreen,
+                                          client, stuff, &barrier)))
+        return err;
 
     if (!AddResource(stuff->barrier, PointerBarrierType, &barrier->barrier))
         return BadAlloc;
commit 04c885de715a7c989e48fc8cf2e61db2b401de2d
Author: Jasper St. Pierre <jstpierre at mecheye.net>
Date:   Sat Nov 3 20:23:43 2012 -0400

    cursor: CreatePointerBarrier has a variable request length
    
    Support this, and swap the devices in the SProc as well. Don't
    actually do anything with the devices just yet -- specifying any
    should still emit a BadImplementation.
    
    Based on a patch by Peter Hutterer <peter.hutterer at who-t.net>
    
    Signed-off-by: Jasper St. Pierre <jstpierre at mecheye.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/xfixes/cursor.c b/xfixes/cursor.c
index c45da27..75b0374 100644
--- a/xfixes/cursor.c
+++ b/xfixes/cursor.c
@@ -1279,7 +1279,7 @@ ProcXFixesCreatePointerBarrier(ClientPtr client)
 
     REQUEST(xXFixesCreatePointerBarrierReq);
 
-    REQUEST_SIZE_MATCH(xXFixesCreatePointerBarrierReq);
+    REQUEST_FIXED_SIZE(xXFixesCreatePointerBarrierReq, pad_to_int32(stuff->num_devices));
     LEGAL_NEW_RESOURCE(stuff->barrier, client);
 
     err = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
@@ -1318,9 +1318,13 @@ int
 SProcXFixesCreatePointerBarrier(ClientPtr client)
 {
     REQUEST(xXFixesCreatePointerBarrierReq);
+    int i;
+    CARD16 *in_devices = (CARD16 *) &stuff[1];
 
     swaps(&stuff->length);
-    REQUEST_SIZE_MATCH(xXFixesCreatePointerBarrierReq);
+    swaps(&stuff->num_devices);
+    REQUEST_FIXED_SIZE(xXFixesCreatePointerBarrierReq, pad_to_int32(stuff->num_devices));
+
     swapl(&stuff->barrier);
     swapl(&stuff->window);
     swaps(&stuff->x1);
@@ -1328,6 +1332,10 @@ SProcXFixesCreatePointerBarrier(ClientPtr client)
     swaps(&stuff->x2);
     swaps(&stuff->y2);
     swapl(&stuff->directions);
+    for (i = 0; i < stuff->num_devices; i++) {
+        swaps(in_devices + i);
+    }
+
     return ProcXFixesVector[stuff->xfixesReqType] (client);
 }
 
commit d74b63f95fc622afe83c53580f1b55346d55fa7a
Author: Jasper St. Pierre <jstpierre at mecheye.net>
Date:   Sat Nov 3 20:23:42 2012 -0400

    cursor: Fix a minor unused variable warning
    
    Signed-off-by: Jasper St. Pierre <jstpierre at mecheye.net>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/xfixes/cursor.c b/xfixes/cursor.c
index 4eee592..c45da27 100644
--- a/xfixes/cursor.c
+++ b/xfixes/cursor.c
@@ -196,7 +196,7 @@ CursorCloseScreen(ScreenPtr pScreen)
     Bool ret;
     _X_UNUSED CloseScreenProcPtr close_proc;
     _X_UNUSED DisplayCursorProcPtr display_proc;
-    ConstrainCursorHarderProcPtr constrain_proc;
+    _X_UNUSED ConstrainCursorHarderProcPtr constrain_proc;
 
     Unwrap(cs, pScreen, CloseScreen, close_proc);
     Unwrap(cs, pScreen, DisplayCursor, display_proc);
commit aad65415bff12c6860c19beac42e4165e598a40f
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Oct 11 13:02:27 2012 +1000

    dix: don't allow disabling XTest devices
    
    Disabling a XTest device followed by an XTest API call crashes the server.
    This could be fixed elsewhere but disabled devices must not send events
    anyway. The use-case for disabled XTest devices is somewhat limited, so
    simply disallow disabling the devices.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/Xi/chgdctl.c b/Xi/chgdctl.c
index 7daf584..31d3a57 100644
--- a/Xi/chgdctl.c
+++ b/Xi/chgdctl.c
@@ -187,7 +187,10 @@ ProcXChangeDeviceControl(ClientPtr client)
     case DEVICE_ENABLE:
         e = (xDeviceEnableCtl *) &stuff[1];
 
-        status = ChangeDeviceControl(client, dev, (xDeviceCtl *) e);
+        if (IsXTestDevice(dev, NULL))
+            status = !Success;
+        else
+            status = ChangeDeviceControl(client, dev, (xDeviceCtl *) e);
 
         if (status == Success) {
             if (e->enable)
diff --git a/dix/devices.c b/dix/devices.c
index fd4916a..613323f 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -145,9 +145,11 @@ DeviceSetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop,
         if (prop->format != 8 || prop->type != XA_INTEGER || prop->size != 1)
             return BadValue;
 
-        /* Don't allow disabling of VCP/VCK */
-        if ((dev == inputInfo.pointer ||dev ==
-             inputInfo.keyboard) &&!(*(CARD8 *) prop->data))
+        /* Don't allow disabling of VCP/VCK or XTest devices */
+        if ((dev == inputInfo.pointer ||
+             dev == inputInfo.keyboard ||
+             IsXTestDevice(dev, NULL))
+            &&!(*(CARD8 *) prop->data))
             return BadAccess;
 
         if (!checkonly) {
commit 5b7384a3154a95a805b040e1910e276b52aada96
Author: Alexey Ten (Lynn) <alexeyten at gmail.com>
Date:   Tue Oct 23 12:32:31 2012 +0400

    Apply partial matches for option (#25873)
    
    Rules which match star (*) and option, like one below, should be applied
    
    layout[2] option    = symbols
    *         misc:typo = +typo(base)
    
    This is port of patch from #19563 (https://bugs.freedesktop.org/19563)
    because here we have own copy of maprules.c
    
    X.Org Bug 25873 <http://bugs.freedesktop.org/show_bug.cgi?id=25873>
    
    Signed-off-by: Alexey Ten (Lynn) <alexeyten at gmail.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/xkb/maprules.c b/xkb/maprules.c
index c6900ec..5462763 100644
--- a/xkb/maprules.c
+++ b/xkb/maprules.c
@@ -864,6 +864,7 @@ XkbRF_GetComponents(XkbRF_RulesPtr rules,
     XkbRF_CheckApplyRules(rules, &mdefs, names, XkbRF_Append);
     XkbRF_ApplyPartialMatches(rules, names);
     XkbRF_CheckApplyRules(rules, &mdefs, names, XkbRF_Option);
+    XkbRF_ApplyPartialMatches(rules, names);
 
     if (names->keycodes)
         names->keycodes = XkbRF_SubstituteVars(names->keycodes, &mdefs);


More information about the xorg-commit mailing list