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

This commit is contained in:
Keith Packard 2012-11-05 17:16:07 -08:00
commit 011f845880
5 changed files with 128 additions and 41 deletions

View File

@ -187,7 +187,10 @@ ProcXChangeDeviceControl(ClientPtr client)
case DEVICE_ENABLE: case DEVICE_ENABLE:
e = (xDeviceEnableCtl *) &stuff[1]; 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 (status == Success) {
if (e->enable) if (e->enable)

View File

@ -1559,6 +1559,7 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev)
uint32_t touchid; uint32_t touchid;
int type = ev->any.type; int type = ev->any.type;
int emulate_pointer = ! !(ev->device_event.flags & TOUCH_POINTER_EMULATED); int emulate_pointer = ! !(ev->device_event.flags & TOUCH_POINTER_EMULATED);
DeviceIntPtr kbd;
if (!t) if (!t)
return; return;
@ -1568,9 +1569,6 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev)
else else
touchid = ev->device_event.touchid; touchid = ev->device_event.touchid;
if (emulate_pointer)
UpdateDeviceState(dev, &ev->device_event);
if (type == ET_TouchBegin) { if (type == ET_TouchBegin) {
ti = TouchBeginTouch(dev, ev->device_event.sourceid, touchid, ti = TouchBeginTouch(dev, ev->device_event.sourceid, touchid,
emulate_pointer); emulate_pointer);
@ -1617,9 +1615,14 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev)
* events which _only_ emulate motion just work normally */ * events which _only_ emulate motion just work normally */
if (emulate_pointer && ev->any.type != ET_TouchUpdate) if (emulate_pointer && ev->any.type != ET_TouchUpdate)
DeliverEmulatedMotionEvent(dev, ti, ev); DeliverEmulatedMotionEvent(dev, ti, ev);
if (emulate_pointer && IsMaster(dev)) if (emulate_pointer && IsMaster(dev))
CheckMotion(&ev->device_event, 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 /* Make sure we have a valid window trace for event delivery; must be
* called after event type mutation. Touch end events are always processed * called after event type mutation. Touch end events are always processed
* in order to end touch records. */ * in order to end touch records. */
@ -1641,6 +1644,9 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev)
if (ev->any.type == ET_TouchEnd) if (ev->any.type == ET_TouchEnd)
TouchEndTouch(dev, ti); TouchEndTouch(dev, ti);
} }
if (emulate_pointer)
UpdateDeviceState(dev, &ev->device_event);
} }
/** /**

View File

@ -145,9 +145,11 @@ DeviceSetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop,
if (prop->format != 8 || prop->type != XA_INTEGER || prop->size != 1) if (prop->format != 8 || prop->type != XA_INTEGER || prop->size != 1)
return BadValue; return BadValue;
/* Don't allow disabling of VCP/VCK */ /* Don't allow disabling of VCP/VCK or XTest devices */
if ((dev == inputInfo.pointer ||dev == if ((dev == inputInfo.pointer ||
inputInfo.keyboard) &&!(*(CARD8 *) prop->data)) dev == inputInfo.keyboard ||
IsXTestDevice(dev, NULL))
&&!(*(CARD8 *) prop->data))
return BadAccess; return BadAccess;
if (!checkonly) { if (!checkonly) {

View File

@ -56,6 +56,7 @@
#include "windowstr.h" #include "windowstr.h"
#include "xace.h" #include "xace.h"
#include "list.h" #include "list.h"
#include "exglobals.h"
static RESTYPE CursorClientType; static RESTYPE CursorClientType;
static RESTYPE CursorHideCountType; static RESTYPE CursorHideCountType;
@ -118,6 +119,8 @@ struct PointerBarrierClient {
ScreenPtr screen; ScreenPtr screen;
struct PointerBarrier barrier; struct PointerBarrier barrier;
struct xorg_list entry; struct xorg_list entry;
int num_devices;
int *device_ids; /* num_devices */
}; };
/* /*
@ -196,7 +199,7 @@ CursorCloseScreen(ScreenPtr pScreen)
Bool ret; Bool ret;
_X_UNUSED CloseScreenProcPtr close_proc; _X_UNUSED CloseScreenProcPtr close_proc;
_X_UNUSED DisplayCursorProcPtr display_proc; _X_UNUSED DisplayCursorProcPtr display_proc;
ConstrainCursorHarderProcPtr constrain_proc; _X_UNUSED ConstrainCursorHarderProcPtr constrain_proc;
Unwrap(cs, pScreen, CloseScreen, close_proc); Unwrap(cs, pScreen, CloseScreen, close_proc);
Unwrap(cs, pScreen, DisplayCursor, display_proc); Unwrap(cs, pScreen, DisplayCursor, display_proc);
@ -1132,6 +1135,31 @@ barrier_is_blocking(const struct PointerBarrier * barrier,
return rc; 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. * 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. * @return The barrier nearest to the movement origin that blocks this movement.
*/ */
static struct PointerBarrier * 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) int x1, int y1, int x2, int y2)
{ {
struct PointerBarrierClient *c; struct PointerBarrierClient *c;
@ -1157,6 +1186,9 @@ barrier_find_nearest(CursorScreenPtr cs, int dir,
if (!barrier_is_blocking_direction(b, dir)) if (!barrier_is_blocking_direction(b, dir))
continue; continue;
if (!barrier_blocks_device(c, dev))
continue;
if (barrier_is_blocking(b, x1, y1, x2, y2, &distance)) { if (barrier_is_blocking(b, x1, y1, x2, y2, &distance)) {
if (min_distance > distance) { if (min_distance > distance) {
min_distance = distance; min_distance = distance;
@ -1204,6 +1236,7 @@ CursorConstrainCursorHarder(DeviceIntPtr dev, ScreenPtr screen, int mode,
mode == Relative) { mode == Relative) {
int ox, oy; int ox, oy;
int dir; int dir;
int i;
struct PointerBarrier *nearest = NULL; struct PointerBarrier *nearest = NULL;
/* where are we coming from */ /* where are we coming from */
@ -1218,8 +1251,12 @@ CursorConstrainCursorHarder(DeviceIntPtr dev, ScreenPtr screen, int mode,
*/ */
dir = barrier_get_direction(ox, oy, *x, *y); dir = barrier_get_direction(ox, oy, *x, *y);
nearest = barrier_find_nearest(cs, dir, ox, oy, *x, *y); #define MAX_BARRIERS 2
if (nearest) { for (i = 0; i < MAX_BARRIERS; i++) {
nearest = barrier_find_nearest(cs, dev, dir, ox, oy, *x, *y);
if (!nearest)
break;
barrier_clamp_to_barrier(nearest, dir, x, y); barrier_clamp_to_barrier(nearest, dir, x, y);
if (barrier_is_vertical(nearest)) { if (barrier_is_vertical(nearest)) {
@ -1230,11 +1267,6 @@ CursorConstrainCursorHarder(DeviceIntPtr dev, ScreenPtr screen, int mode,
dir &= ~(BarrierNegativeY | BarrierPositiveY); dir &= ~(BarrierNegativeY | BarrierPositiveY);
oy = *y; oy = *y;
} }
nearest = barrier_find_nearest(cs, dir, ox, oy, *x, *y);
if (nearest) {
barrier_clamp_to_barrier(nearest, dir, x, y);
}
} }
} }
@ -1245,28 +1277,67 @@ CursorConstrainCursorHarder(DeviceIntPtr dev, ScreenPtr screen, int mode,
} }
} }
static struct PointerBarrierClient * static int
CreatePointerBarrierClient(ScreenPtr screen, ClientPtr client, CreatePointerBarrierClient(ScreenPtr screen, ClientPtr client,
xXFixesCreatePointerBarrierReq * stuff) xXFixesCreatePointerBarrierReq * stuff,
PointerBarrierClientPtr *client_out)
{ {
CursorScreenPtr cs = GetCursorScreen(screen); CursorScreenPtr cs = GetCursorScreen(screen);
struct PointerBarrierClient *ret = malloc(sizeof(*ret)); int err;
int size;
int i;
CARD16 *in_devices;
struct PointerBarrierClient *ret;
if (ret) { size = sizeof(*ret) + sizeof(int) * stuff->num_devices;
ret->screen = screen; ret = malloc(size);
ret->barrier.x1 = min(stuff->x1, stuff->x2);
ret->barrier.x2 = max(stuff->x1, stuff->x2); *client_out = NULL;
ret->barrier.y1 = min(stuff->y1, stuff->y2);
ret->barrier.y2 = max(stuff->y1, stuff->y2); if (!ret) {
ret->barrier.directions = stuff->directions & 0x0f; return BadAlloc;
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);
} }
return ret; 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);
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;
error:
free(ret);
return err;
} }
int int
@ -1279,7 +1350,7 @@ ProcXFixesCreatePointerBarrier(ClientPtr client)
REQUEST(xXFixesCreatePointerBarrierReq); REQUEST(xXFixesCreatePointerBarrierReq);
REQUEST_SIZE_MATCH(xXFixesCreatePointerBarrierReq); REQUEST_FIXED_SIZE(xXFixesCreatePointerBarrierReq, pad_to_int32(stuff->num_devices));
LEGAL_NEW_RESOURCE(stuff->barrier, client); LEGAL_NEW_RESOURCE(stuff->barrier, client);
err = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess); err = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
@ -1288,10 +1359,6 @@ ProcXFixesCreatePointerBarrier(ClientPtr client)
return err; return err;
} }
/* This sure does need fixing. */
if (stuff->num_devices)
return BadImplementation;
b.x1 = stuff->x1; b.x1 = stuff->x1;
b.x2 = stuff->x2; b.x2 = stuff->x2;
b.y1 = stuff->y1; b.y1 = stuff->y1;
@ -1304,9 +1371,9 @@ ProcXFixesCreatePointerBarrier(ClientPtr client)
if (barrier_is_horizontal(&b) && barrier_is_vertical(&b)) if (barrier_is_horizontal(&b) && barrier_is_vertical(&b))
return BadValue; return BadValue;
if (!(barrier = CreatePointerBarrierClient(pWin->drawable.pScreen, if ((err = CreatePointerBarrierClient(pWin->drawable.pScreen,
client, stuff))) client, stuff, &barrier)))
return BadAlloc; return err;
if (!AddResource(stuff->barrier, PointerBarrierType, &barrier->barrier)) if (!AddResource(stuff->barrier, PointerBarrierType, &barrier->barrier))
return BadAlloc; return BadAlloc;
@ -1318,9 +1385,13 @@ int
SProcXFixesCreatePointerBarrier(ClientPtr client) SProcXFixesCreatePointerBarrier(ClientPtr client)
{ {
REQUEST(xXFixesCreatePointerBarrierReq); REQUEST(xXFixesCreatePointerBarrierReq);
int i;
CARD16 *in_devices = (CARD16 *) &stuff[1];
swaps(&stuff->length); 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->barrier);
swapl(&stuff->window); swapl(&stuff->window);
swaps(&stuff->x1); swaps(&stuff->x1);
@ -1328,6 +1399,10 @@ SProcXFixesCreatePointerBarrier(ClientPtr client)
swaps(&stuff->x2); swaps(&stuff->x2);
swaps(&stuff->y2); swaps(&stuff->y2);
swapl(&stuff->directions); swapl(&stuff->directions);
for (i = 0; i < stuff->num_devices; i++) {
swaps(in_devices + i);
}
return ProcXFixesVector[stuff->xfixesReqType] (client); return ProcXFixesVector[stuff->xfixesReqType] (client);
} }

View File

@ -864,6 +864,7 @@ XkbRF_GetComponents(XkbRF_RulesPtr rules,
XkbRF_CheckApplyRules(rules, &mdefs, names, XkbRF_Append); XkbRF_CheckApplyRules(rules, &mdefs, names, XkbRF_Append);
XkbRF_ApplyPartialMatches(rules, names); XkbRF_ApplyPartialMatches(rules, names);
XkbRF_CheckApplyRules(rules, &mdefs, names, XkbRF_Option); XkbRF_CheckApplyRules(rules, &mdefs, names, XkbRF_Option);
XkbRF_ApplyPartialMatches(rules, names);
if (names->keycodes) if (names->keycodes)
names->keycodes = XkbRF_SubstituteVars(names->keycodes, &mdefs); names->keycodes = XkbRF_SubstituteVars(names->keycodes, &mdefs);