[PATCH 5/5] cursor: Fix up implementation for per-device barriers

Peter Hutterer peter.hutterer at who-t.net
Sun Nov 4 16:14:20 PST 2012


On Sat, Nov 03, 2012 at 08:23:46PM -0400, Jasper St. Pierre wrote:
> From: "Jasper St. Pierre" <jstpierre at mecheye.net>
> 
> 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>
> ---
>  xfixes/cursor.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++------
>  1 file changed, 68 insertions(+), 7 deletions(-)
> 
> diff --git a/xfixes/cursor.c b/xfixes/cursor.c
> index 45b07c3..7ca48c8 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[0]; /* num_devices */

We usually just use a int*, even if it is allocated just after the struct. I
can see why [0] is beneficial here, but let's stick with consistency here.
And iirc that's a gnu-ism anyway.

I've changed this locally, patches applied otherwise. thanks

Cheers,
   Peter

>  };
>  
>  /*
> @@ -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;
> -- 
> 1.7.12.1
> 
> _______________________________________________
> xorg-devel at lists.x.org: X.Org development
> Archives: http://lists.x.org/archives/xorg-devel
> Info: http://lists.x.org/mailman/listinfo/xorg-devel
> 


More information about the xorg-devel mailing list