Xi: fix per-device barrier handling
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: Jasper St. Pierre <jstpierre@mecheye.net>
This commit is contained in:
parent
cc10ac8f0e
commit
f71c2f895c
235
Xi/xibarriers.c
235
Xi/xibarriers.c
|
@ -67,19 +67,28 @@ static DevPrivateKeyRec BarrierScreenPrivateKeyRec;
|
||||||
|
|
||||||
typedef struct PointerBarrierClient *PointerBarrierClientPtr;
|
typedef struct PointerBarrierClient *PointerBarrierClientPtr;
|
||||||
|
|
||||||
|
struct PointerBarrierDevice {
|
||||||
|
struct xorg_list entry;
|
||||||
|
int deviceid;
|
||||||
|
Time last_timestamp;
|
||||||
|
int barrier_event_id;
|
||||||
|
int release_event_id;
|
||||||
|
Bool hit;
|
||||||
|
Bool seen;
|
||||||
|
};
|
||||||
|
|
||||||
struct PointerBarrierClient {
|
struct PointerBarrierClient {
|
||||||
XID id;
|
XID id;
|
||||||
ScreenPtr screen;
|
ScreenPtr screen;
|
||||||
WindowPtr window;
|
WindowPtr window;
|
||||||
struct PointerBarrier barrier;
|
struct PointerBarrier barrier;
|
||||||
struct xorg_list entry;
|
struct xorg_list entry;
|
||||||
|
/* num_devices/device_ids are devices the barrier applies to */
|
||||||
int num_devices;
|
int num_devices;
|
||||||
int *device_ids; /* num_devices */
|
int *device_ids; /* num_devices */
|
||||||
Time last_timestamp;
|
|
||||||
int barrier_event_id;
|
/* per_device keeps track of devices actually blocked by barriers */
|
||||||
int release_event_id;
|
struct xorg_list per_device;
|
||||||
Bool hit;
|
|
||||||
Bool seen;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _BarrierScreen {
|
typedef struct _BarrierScreen {
|
||||||
|
@ -90,6 +99,47 @@ typedef struct _BarrierScreen {
|
||||||
#define GetBarrierScreenIfSet(s) GetBarrierScreen(s)
|
#define GetBarrierScreenIfSet(s) GetBarrierScreen(s)
|
||||||
#define SetBarrierScreen(s,p) dixSetPrivate(&(s)->devPrivates, BarrierScreenPrivateKey, p)
|
#define SetBarrierScreen(s,p) dixSetPrivate(&(s)->devPrivates, BarrierScreenPrivateKey, p)
|
||||||
|
|
||||||
|
static struct PointerBarrierDevice *AllocBarrierDevice(void)
|
||||||
|
{
|
||||||
|
struct PointerBarrierDevice *pbd = NULL;
|
||||||
|
|
||||||
|
pbd = malloc(sizeof(struct PointerBarrierDevice));
|
||||||
|
if (!pbd)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
pbd->deviceid = -1; /* must be set by caller */
|
||||||
|
pbd->barrier_event_id = 1;
|
||||||
|
pbd->release_event_id = 0;
|
||||||
|
pbd->hit = FALSE;
|
||||||
|
pbd->seen = FALSE;
|
||||||
|
xorg_list_init(&pbd->entry);
|
||||||
|
|
||||||
|
return pbd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FreePointerBarrierClient(struct PointerBarrierClient *c)
|
||||||
|
{
|
||||||
|
struct PointerBarrierDevice *pbd = NULL, *tmp = NULL;
|
||||||
|
|
||||||
|
xorg_list_for_each_entry_safe(pbd, tmp, &c->per_device, entry) {
|
||||||
|
free(pbd);
|
||||||
|
}
|
||||||
|
free(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct PointerBarrierDevice *GetBarrierDevice(struct PointerBarrierClient *c, int deviceid)
|
||||||
|
{
|
||||||
|
struct PointerBarrierDevice *pbd = NULL;
|
||||||
|
|
||||||
|
xorg_list_for_each_entry(pbd, &c->per_device, entry) {
|
||||||
|
if (pbd->deviceid == deviceid)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
BUG_WARN(!pbd);
|
||||||
|
return pbd;
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL
|
static BOOL
|
||||||
barrier_is_horizontal(const struct PointerBarrier *barrier)
|
barrier_is_horizontal(const struct PointerBarrier *barrier)
|
||||||
{
|
{
|
||||||
|
@ -283,9 +333,11 @@ barrier_find_nearest(BarrierScreenPtr cs, DeviceIntPtr dev,
|
||||||
|
|
||||||
xorg_list_for_each_entry(c, &cs->barriers, entry) {
|
xorg_list_for_each_entry(c, &cs->barriers, entry) {
|
||||||
struct PointerBarrier *b = &c->barrier;
|
struct PointerBarrier *b = &c->barrier;
|
||||||
|
struct PointerBarrierDevice *pbd;
|
||||||
double distance;
|
double distance;
|
||||||
|
|
||||||
if (c->seen)
|
pbd = GetBarrierDevice(c, dev->id);
|
||||||
|
if (pbd->seen)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!barrier_is_blocking_direction(b, dir))
|
if (!barrier_is_blocking_direction(b, dir))
|
||||||
|
@ -358,6 +410,7 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
|
||||||
.root = screen->root->drawable.id,
|
.root = screen->root->drawable.id,
|
||||||
};
|
};
|
||||||
InternalEvent *barrier_events = events;
|
InternalEvent *barrier_events = events;
|
||||||
|
DeviceIntPtr master;
|
||||||
|
|
||||||
if (nevents)
|
if (nevents)
|
||||||
*nevents = 0;
|
*nevents = 0;
|
||||||
|
@ -365,6 +418,13 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
|
||||||
if (xorg_list_is_empty(&cs->barriers) || IsFloating(dev))
|
if (xorg_list_is_empty(&cs->barriers) || IsFloating(dev))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is only called for slave devices, but pointer-barriers
|
||||||
|
* are for master-devices only. Flip the device to the master here,
|
||||||
|
* continue with that.
|
||||||
|
*/
|
||||||
|
master = GetMaster(dev, MASTER_POINTER);
|
||||||
|
|
||||||
/* How this works:
|
/* How this works:
|
||||||
* Given the origin and the movement vector, get the nearest barrier
|
* Given the origin and the movement vector, get the nearest barrier
|
||||||
* to the origin that is blocking the movement.
|
* to the origin that is blocking the movement.
|
||||||
|
@ -375,16 +435,19 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
|
||||||
dir = barrier_get_direction(current_x, current_y, x, y);
|
dir = barrier_get_direction(current_x, current_y, x, y);
|
||||||
|
|
||||||
while (dir != 0) {
|
while (dir != 0) {
|
||||||
c = barrier_find_nearest(cs, dev, dir, current_x, current_y, x, y);
|
struct PointerBarrierDevice *pbd;
|
||||||
|
|
||||||
|
c = barrier_find_nearest(cs, master, dir, current_x, current_y, x, y);
|
||||||
if (!c)
|
if (!c)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
nearest = &c->barrier;
|
nearest = &c->barrier;
|
||||||
|
|
||||||
c->seen = TRUE;
|
pbd = GetBarrierDevice(c, master->id);
|
||||||
c->hit = TRUE;
|
pbd->seen = TRUE;
|
||||||
|
pbd->hit = TRUE;
|
||||||
|
|
||||||
if (c->barrier_event_id == c->release_event_id)
|
if (pbd->barrier_event_id == pbd->release_event_id)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ev.type = ET_BarrierHit;
|
ev.type = ET_BarrierHit;
|
||||||
|
@ -400,12 +463,12 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
|
||||||
}
|
}
|
||||||
|
|
||||||
ev.flags = 0;
|
ev.flags = 0;
|
||||||
ev.event_id = c->barrier_event_id;
|
ev.event_id = pbd->barrier_event_id;
|
||||||
ev.barrierid = c->id;
|
ev.barrierid = c->id;
|
||||||
|
|
||||||
ev.dt = ms - c->last_timestamp;
|
ev.dt = ms - pbd->last_timestamp;
|
||||||
ev.window = c->window->drawable.id;
|
ev.window = c->window->drawable.id;
|
||||||
c->last_timestamp = ms;
|
pbd->last_timestamp = ms;
|
||||||
|
|
||||||
/* root x/y is filled in later */
|
/* root x/y is filled in later */
|
||||||
|
|
||||||
|
@ -415,28 +478,31 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
|
||||||
}
|
}
|
||||||
|
|
||||||
xorg_list_for_each_entry(c, &cs->barriers, entry) {
|
xorg_list_for_each_entry(c, &cs->barriers, entry) {
|
||||||
|
struct PointerBarrierDevice *pbd;
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
c->seen = FALSE;
|
|
||||||
if (!c->hit)
|
pbd = GetBarrierDevice(c, master->id);
|
||||||
|
pbd->seen = FALSE;
|
||||||
|
if (!pbd->hit)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (barrier_inside_hit_box(&c->barrier, x, y))
|
if (barrier_inside_hit_box(&c->barrier, x, y))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
c->hit = FALSE;
|
pbd->hit = FALSE;
|
||||||
|
|
||||||
ev.type = ET_BarrierLeave;
|
ev.type = ET_BarrierLeave;
|
||||||
|
|
||||||
if (c->barrier_event_id == c->release_event_id)
|
if (pbd->barrier_event_id == pbd->release_event_id)
|
||||||
flags |= XIBarrierPointerReleased;
|
flags |= XIBarrierPointerReleased;
|
||||||
|
|
||||||
ev.flags = flags;
|
ev.flags = flags;
|
||||||
ev.event_id = c->barrier_event_id;
|
ev.event_id = pbd->barrier_event_id;
|
||||||
ev.barrierid = c->id;
|
ev.barrierid = c->id;
|
||||||
|
|
||||||
ev.dt = ms - c->last_timestamp;
|
ev.dt = ms - pbd->last_timestamp;
|
||||||
ev.window = c->window->drawable.id;
|
ev.window = c->window->drawable.id;
|
||||||
c->last_timestamp = ms;
|
pbd->last_timestamp = ms;
|
||||||
|
|
||||||
/* root x/y is filled in later */
|
/* root x/y is filled in later */
|
||||||
|
|
||||||
|
@ -446,7 +512,7 @@ input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
|
||||||
|
|
||||||
/* If we've left the hit box, this is the
|
/* If we've left the hit box, this is the
|
||||||
* start of a new event ID. */
|
* start of a new event ID. */
|
||||||
c->barrier_event_id++;
|
pbd->barrier_event_id++;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -479,6 +545,7 @@ CreatePointerBarrierClient(ClientPtr client,
|
||||||
int i;
|
int i;
|
||||||
struct PointerBarrierClient *ret;
|
struct PointerBarrierClient *ret;
|
||||||
CARD16 *in_devices;
|
CARD16 *in_devices;
|
||||||
|
DeviceIntPtr dev;
|
||||||
|
|
||||||
size = sizeof(*ret) + sizeof(DeviceIntPtr) * stuff->num_devices;
|
size = sizeof(*ret) + sizeof(DeviceIntPtr) * stuff->num_devices;
|
||||||
ret = malloc(size);
|
ret = malloc(size);
|
||||||
|
@ -487,6 +554,8 @@ CreatePointerBarrierClient(ClientPtr client,
|
||||||
return BadAlloc;
|
return BadAlloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xorg_list_init(&ret->per_device);
|
||||||
|
|
||||||
err = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
|
err = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
|
||||||
if (err != Success) {
|
if (err != Success) {
|
||||||
client->errorValue = stuff->window;
|
client->errorValue = stuff->window;
|
||||||
|
@ -524,11 +593,25 @@ CreatePointerBarrierClient(ClientPtr client,
|
||||||
ret->device_ids[i] = device_id;
|
ret->device_ids[i] = device_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Alloc one per master pointer, they're the ones that can be blocked */
|
||||||
|
xorg_list_init(&ret->per_device);
|
||||||
|
nt_list_for_each_entry(dev, inputInfo.devices, next) {
|
||||||
|
struct PointerBarrierDevice *pbd;
|
||||||
|
|
||||||
|
if (dev->type != MASTER_POINTER)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
pbd = AllocBarrierDevice();
|
||||||
|
if (!pbd) {
|
||||||
|
err = BadAlloc;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
pbd->deviceid = dev->id;
|
||||||
|
|
||||||
|
xorg_list_add(&pbd->entry, &ret->per_device);
|
||||||
|
}
|
||||||
|
|
||||||
ret->id = stuff->barrier;
|
ret->id = stuff->barrier;
|
||||||
ret->barrier_event_id = 1;
|
|
||||||
ret->release_event_id = 0;
|
|
||||||
ret->hit = FALSE;
|
|
||||||
ret->seen = FALSE;
|
|
||||||
ret->barrier.x1 = stuff->x1;
|
ret->barrier.x1 = stuff->x1;
|
||||||
ret->barrier.x2 = stuff->x2;
|
ret->barrier.x2 = stuff->x2;
|
||||||
ret->barrier.y1 = stuff->y1;
|
ret->barrier.y1 = stuff->y1;
|
||||||
|
@ -547,7 +630,7 @@ CreatePointerBarrierClient(ClientPtr client,
|
||||||
|
|
||||||
error:
|
error:
|
||||||
*client_out = NULL;
|
*client_out = NULL;
|
||||||
free(ret);
|
FreePointerBarrierClient(ret);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -556,13 +639,15 @@ BarrierFreeBarrier(void *data, XID id)
|
||||||
{
|
{
|
||||||
struct PointerBarrierClient *c;
|
struct PointerBarrierClient *c;
|
||||||
Time ms = GetTimeInMillis();
|
Time ms = GetTimeInMillis();
|
||||||
|
DeviceIntPtr dev = NULL;
|
||||||
|
ScreenPtr screen;
|
||||||
|
|
||||||
c = container_of(data, struct PointerBarrierClient, barrier);
|
c = container_of(data, struct PointerBarrierClient, barrier);
|
||||||
|
screen = c->screen;
|
||||||
|
|
||||||
/* FIXME: this is really broken for multidevice */
|
for (dev = inputInfo.devices; dev; dev = dev->next) {
|
||||||
if (c->hit) {
|
struct PointerBarrierDevice *pbd;
|
||||||
DeviceIntPtr dev = NULL;
|
int root_x, root_y;
|
||||||
ScreenPtr screen = c->screen;
|
|
||||||
BarrierEvent ev = {
|
BarrierEvent ev = {
|
||||||
.header = ET_Internal,
|
.header = ET_Internal,
|
||||||
.type = ET_BarrierLeave,
|
.type = ET_BarrierLeave,
|
||||||
|
@ -577,36 +662,79 @@ BarrierFreeBarrier(void *data, XID id)
|
||||||
.dy = 0,
|
.dy = 0,
|
||||||
/* .root_x */
|
/* .root_x */
|
||||||
/* .root_y */
|
/* .root_y */
|
||||||
.dt = ms - c->last_timestamp,
|
/* .dt */
|
||||||
.event_id = c->barrier_event_id,
|
/* .event_id */
|
||||||
.flags = XIBarrierPointerReleased,
|
.flags = XIBarrierPointerReleased,
|
||||||
};
|
};
|
||||||
|
|
||||||
for (dev = inputInfo.devices; dev; dev = dev->next) {
|
|
||||||
int root_x, root_y;
|
|
||||||
|
|
||||||
if (dev->type != MASTER_POINTER)
|
if (dev->type != MASTER_POINTER)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!barrier_blocks_device(c, dev))
|
pbd = GetBarrierDevice(c, dev->id);
|
||||||
continue;
|
if (!pbd->hit)
|
||||||
|
continue;
|
||||||
|
|
||||||
ev.deviceid = dev->id;
|
ev.deviceid = dev->id;
|
||||||
|
ev.event_id = pbd->barrier_event_id,
|
||||||
|
ev.dt = ms - pbd->last_timestamp,
|
||||||
|
|
||||||
GetSpritePosition(dev, &root_x, &root_y);
|
GetSpritePosition(dev, &root_x, &root_y);
|
||||||
ev.root_x = root_x;
|
ev.root_x = root_x;
|
||||||
ev.root_y = root_y;
|
ev.root_y = root_y;
|
||||||
|
|
||||||
mieqEnqueue(dev, (InternalEvent *) &ev);
|
mieqEnqueue(dev, (InternalEvent *) &ev);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xorg_list_del(&c->entry);
|
xorg_list_del(&c->entry);
|
||||||
|
|
||||||
free(c);
|
FreePointerBarrierClient(c);
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void add_master_func(pointer res, XID id, pointer devid)
|
||||||
|
{
|
||||||
|
struct PointerBarrier *b;
|
||||||
|
struct PointerBarrierClient *barrier;
|
||||||
|
struct PointerBarrierDevice *pbd;
|
||||||
|
int *deviceid = devid;
|
||||||
|
|
||||||
|
b = res;
|
||||||
|
barrier = container_of(b, struct PointerBarrierClient, barrier);
|
||||||
|
|
||||||
|
|
||||||
|
pbd = AllocBarrierDevice();
|
||||||
|
pbd->deviceid = *deviceid;
|
||||||
|
|
||||||
|
xorg_list_add(&pbd->entry, &barrier->per_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void remove_master_func(pointer res, XID id, pointer devid)
|
||||||
|
{
|
||||||
|
struct PointerBarrierDevice *pbd;
|
||||||
|
struct PointerBarrierClient *barrier;
|
||||||
|
struct PointerBarrier *b;
|
||||||
|
int *deviceid = devid;
|
||||||
|
|
||||||
|
b = res;
|
||||||
|
barrier = container_of(b, struct PointerBarrierClient, barrier);
|
||||||
|
|
||||||
|
pbd = GetBarrierDevice(barrier, *deviceid);
|
||||||
|
xorg_list_del(&pbd->entry);
|
||||||
|
free(pbd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void XIBarrierNewMasterDevice(ClientPtr client, int deviceid)
|
||||||
|
{
|
||||||
|
FindClientResourcesByType(client, PointerBarrierType, add_master_func, &deviceid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void XIBarrierRemoveMasterDevice(ClientPtr client, int deviceid)
|
||||||
|
{
|
||||||
|
/* FIXME: send LeaveNotify */
|
||||||
|
FindClientResourcesByType(client, PointerBarrierType, remove_master_func, &deviceid);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
XICreatePointerBarrier(ClientPtr client,
|
XICreatePointerBarrier(ClientPtr client,
|
||||||
xXFixesCreatePointerBarrierReq * stuff)
|
xXFixesCreatePointerBarrierReq * stuff)
|
||||||
|
@ -698,14 +826,19 @@ ProcXIBarrierReleasePointer(ClientPtr client)
|
||||||
|
|
||||||
info = (xXIBarrierReleasePointerInfo*) &stuff[1];
|
info = (xXIBarrierReleasePointerInfo*) &stuff[1];
|
||||||
for (i = 0; i < stuff->num_barriers; i++, info++) {
|
for (i = 0; i < stuff->num_barriers; i++, info++) {
|
||||||
|
struct PointerBarrierDevice *pbd;
|
||||||
|
DeviceIntPtr dev;
|
||||||
CARD32 barrier_id, event_id;
|
CARD32 barrier_id, event_id;
|
||||||
_X_UNUSED CARD32 device_id;
|
_X_UNUSED CARD32 device_id;
|
||||||
|
|
||||||
barrier_id = info->barrier;
|
barrier_id = info->barrier;
|
||||||
event_id = info->eventid;
|
event_id = info->eventid;
|
||||||
|
|
||||||
/* FIXME: per-device releases */
|
err = dixLookupDevice(&dev, info->deviceid, client, DixReadAccess);
|
||||||
device_id = info->deviceid;
|
if (err != Success) {
|
||||||
|
client->errorValue = BadDevice;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
err = dixLookupResourceByType((void **) &b, barrier_id,
|
err = dixLookupResourceByType((void **) &b, barrier_id,
|
||||||
PointerBarrierType, client, DixReadAccess);
|
PointerBarrierType, client, DixReadAccess);
|
||||||
|
@ -717,9 +850,13 @@ ProcXIBarrierReleasePointer(ClientPtr client)
|
||||||
if (CLIENT_ID(barrier_id) != client->index)
|
if (CLIENT_ID(barrier_id) != client->index)
|
||||||
return BadAccess;
|
return BadAccess;
|
||||||
|
|
||||||
|
|
||||||
barrier = container_of(b, struct PointerBarrierClient, barrier);
|
barrier = container_of(b, struct PointerBarrierClient, barrier);
|
||||||
if (barrier->barrier_event_id == event_id)
|
|
||||||
barrier->release_event_id = event_id;
|
pbd = GetBarrierDevice(barrier, dev->id);
|
||||||
|
|
||||||
|
if (pbd->barrier_event_id == event_id)
|
||||||
|
pbd->release_event_id = event_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Success;
|
return Success;
|
||||||
|
|
|
@ -42,4 +42,7 @@ XIBarrierInit(void);
|
||||||
int SProcXIBarrierReleasePointer(ClientPtr client);
|
int SProcXIBarrierReleasePointer(ClientPtr client);
|
||||||
int ProcXIBarrierReleasePointer(ClientPtr client);
|
int ProcXIBarrierReleasePointer(ClientPtr client);
|
||||||
|
|
||||||
|
void XIBarrierNewMasterDevice(ClientPtr client, int deviceid);
|
||||||
|
void XIBarrierRemoveMasterDevice(ClientPtr client, int deviceid);
|
||||||
|
|
||||||
#endif /* _XIBARRIERS_H_ */
|
#endif /* _XIBARRIERS_H_ */
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
#include "xkbsrv.h"
|
#include "xkbsrv.h"
|
||||||
|
|
||||||
#include "xichangehierarchy.h"
|
#include "xichangehierarchy.h"
|
||||||
|
#include "xibarriers.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send the current state of the device hierarchy to all clients.
|
* Send the current state of the device hierarchy to all clients.
|
||||||
|
@ -189,6 +190,8 @@ add_master(ClientPtr client, xXIAddMasterInfo * c, int flags[MAXDEVICES])
|
||||||
flags[XTestptr->id] |= XISlaveAttached;
|
flags[XTestptr->id] |= XISlaveAttached;
|
||||||
flags[XTestkeybd->id] |= XISlaveAttached;
|
flags[XTestkeybd->id] |= XISlaveAttached;
|
||||||
|
|
||||||
|
XIBarrierNewMasterDevice(client, ptr->id);
|
||||||
|
|
||||||
unwind:
|
unwind:
|
||||||
free(name);
|
free(name);
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -293,6 +296,8 @@ remove_master(ClientPtr client, xXIRemoveMasterInfo * r, int flags[MAXDEVICES])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XIBarrierRemoveMasterDevice(client, ptr->id);
|
||||||
|
|
||||||
/* disable the remove the devices, XTest devices must be done first
|
/* disable the remove the devices, XTest devices must be done first
|
||||||
else the sprites they rely on will be destroyed */
|
else the sprites they rely on will be destroyed */
|
||||||
DisableDevice(XTestptr, FALSE);
|
DisableDevice(XTestptr, FALSE);
|
||||||
|
@ -313,6 +318,7 @@ remove_master(ClientPtr client, xXIRemoveMasterInfo * r, int flags[MAXDEVICES])
|
||||||
flags[keybd->id] |= XIMasterRemoved;
|
flags[keybd->id] |= XIMasterRemoved;
|
||||||
flags[ptr->id] |= XIMasterRemoved;
|
flags[ptr->id] |= XIMasterRemoved;
|
||||||
|
|
||||||
|
|
||||||
unwind:
|
unwind:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue