Input: Allow EventToCore to return multiple events

Some event types (notably Expose and GraphicsExpose) require multiple
events, a la XI 1.x.  Bring the EventToCore API in line with EventToXI's
and allow it to generate multiple events.

Signed-off-by: Daniel Stone <daniel@fooishbar.org>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Daniel Stone 2011-02-15 11:28:02 +00:00 committed by Peter Hutterer
parent ea71495ada
commit 46b4979601
5 changed files with 102 additions and 71 deletions

View File

@ -97,8 +97,12 @@ EventIsKeyRepeat(xEvent *event)
* @return Success or the matching error code. * @return Success or the matching error code.
*/ */
int int
EventToCore(InternalEvent *event, xEvent *core) EventToCore(InternalEvent *event, xEvent **core_out, int *count_out)
{ {
xEvent *core = NULL;
int count = 0;
int ret = BadImplementation;
switch(event->any.type) switch(event->any.type)
{ {
case ET_Motion: case ET_Motion:
@ -108,7 +112,10 @@ EventToCore(InternalEvent *event, xEvent *core)
* present */ * present */
if (!BitIsOn(e->valuators.mask, 0) && if (!BitIsOn(e->valuators.mask, 0) &&
!BitIsOn(e->valuators.mask, 1)) !BitIsOn(e->valuators.mask, 1))
return BadMatch; {
ret = BadMatch;
goto out;
}
} }
/* fallthrough */ /* fallthrough */
case ET_ButtonPress: case ET_ButtonPress:
@ -119,9 +126,15 @@ EventToCore(InternalEvent *event, xEvent *core)
DeviceEvent *e = &event->device_event; DeviceEvent *e = &event->device_event;
if (e->detail.key > 0xFF) if (e->detail.key > 0xFF)
return BadMatch; {
ret = BadMatch;
goto out;
}
memset(core, 0, sizeof(xEvent)); core = calloc(1, sizeof(*core));
if (!core)
return BadAlloc;
count = 1;
core->u.u.type = e->type - ET_KeyPress + KeyPress; core->u.u.type = e->type - ET_KeyPress + KeyPress;
core->u.u.detail = e->detail.key & 0xFF; core->u.u.detail = e->detail.key & 0xFF;
core->u.keyButtonPointer.time = e->time; core->u.keyButtonPointer.time = e->time;
@ -129,7 +142,10 @@ EventToCore(InternalEvent *event, xEvent *core)
core->u.keyButtonPointer.rootY = e->root_y; core->u.keyButtonPointer.rootY = e->root_y;
core->u.keyButtonPointer.state = e->corestate; core->u.keyButtonPointer.state = e->corestate;
core->u.keyButtonPointer.root = e->root; core->u.keyButtonPointer.root = e->root;
EventSetKeyRepeatFlag(core, (e->type == ET_KeyPress && e->key_repeat)); EventSetKeyRepeatFlag(core,
(e->type == ET_KeyPress &&
e->key_repeat));
ret = Success;
} }
break; break;
case ET_ProximityIn: case ET_ProximityIn:
@ -139,13 +155,18 @@ EventToCore(InternalEvent *event, xEvent *core)
case ET_RawButtonPress: case ET_RawButtonPress:
case ET_RawButtonRelease: case ET_RawButtonRelease:
case ET_RawMotion: case ET_RawMotion:
return BadMatch; ret = BadMatch;
goto out;
default: default:
/* XXX: */ /* XXX: */
ErrorF("[dix] EventToCore: Not implemented yet \n"); ErrorF("[dix] EventToCore: Not implemented yet \n");
return BadImplementation; ret = BadImplementation;
} }
return Success;
out:
*core_out = core;
*count_out = count;
return ret;
} }
/** /**

View File

@ -2366,8 +2366,7 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
Window child = None; Window child = None;
Mask filter; Mask filter;
int deliveries = 0; int deliveries = 0;
xEvent core; xEvent *xE = NULL, *core = NULL;
xEvent *xE = NULL;
int rc, mask, count = 0; int rc, mask, count = 0;
CHECKEVENT(event); CHECKEVENT(event);
@ -2417,13 +2416,13 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
/* Core event */ /* Core event */
if ((mask & EVENT_CORE_MASK) && IsMaster(dev) && dev->coreEvents) if ((mask & EVENT_CORE_MASK) && IsMaster(dev) && dev->coreEvents)
{ {
rc = EventToCore(event, &core); rc = EventToCore(event, &core, &count);
if (rc == Success) { if (rc == Success) {
if (XaceHook(XACE_SEND_ACCESS, NULL, dev, pWin, &core, 1) == Success) { if (XaceHook(XACE_SEND_ACCESS, NULL, dev, pWin, core, count) == Success) {
filter = GetEventFilter(dev, &core); filter = GetEventFilter(dev, core);
FixUpEventFromWindow(pSprite, &core, pWin, child, FALSE); FixUpEventFromWindow(pSprite, core, pWin, child, FALSE);
deliveries = DeliverEventsToWindow(dev, pWin, &core, 1, deliveries = DeliverEventsToWindow(dev, pWin, core,
filter, grab); count, filter, grab);
if (deliveries > 0) if (deliveries > 0)
goto unwind; goto unwind;
} }
@ -2445,6 +2444,7 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
} }
unwind: unwind:
free(core);
free(xE); free(xE);
return deliveries; return deliveries;
} }
@ -3460,7 +3460,6 @@ CheckPassiveGrabsOnWindow(
{ {
int rc, count = 0; int rc, count = 0;
xEvent *xE = NULL; xEvent *xE = NULL;
xEvent core;
event->corestate &= 0x1f00; event->corestate &= 0x1f00;
event->corestate |= tempGrab.modifiersDetail.exact & (~0x1f00); event->corestate |= tempGrab.modifiersDetail.exact & (~0x1f00);
@ -3512,7 +3511,7 @@ CheckPassiveGrabsOnWindow(
if (match & CORE_MATCH) if (match & CORE_MATCH)
{ {
rc = EventToCore((InternalEvent*)event, &core); rc = EventToCore((InternalEvent*)event, &xE, &count);
if (rc != Success) if (rc != Success)
{ {
if (rc != BadMatch) if (rc != BadMatch)
@ -3520,8 +3519,6 @@ CheckPassiveGrabsOnWindow(
"(%d, %d).\n", device->name, event->type, rc); "(%d, %d).\n", device->name, event->type, rc);
continue; continue;
} }
xE = &core;
count = 1;
} else if (match & XI2_MATCH) } else if (match & XI2_MATCH)
{ {
rc = EventToXI2((InternalEvent*)event, &xE); rc = EventToXI2((InternalEvent*)event, &xE);
@ -3551,6 +3548,7 @@ CheckPassiveGrabsOnWindow(
{ {
FixUpEventFromWindow(pSprite, xE, grab->window, None, TRUE); FixUpEventFromWindow(pSprite, xE, grab->window, None, TRUE);
/* XXX: XACE? */
TryClientEvents(rClient(grab), device, xE, count, TryClientEvents(rClient(grab), device, xE, count,
GetEventFilter(device, xE), GetEventFilter(device, xE),
GetEventFilter(device, xE), grab); GetEventFilter(device, xE), grab);
@ -3564,8 +3562,7 @@ CheckPassiveGrabsOnWindow(
grabinfo->sync.state = FROZEN_WITH_EVENT; grabinfo->sync.state = FROZEN_WITH_EVENT;
} }
if (match & (XI_MATCH | XI2_MATCH)) free(xE);
free(xE); /* on core match xE == &core */
return grab; return grab;
} }
} }
@ -3682,8 +3679,7 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
DeviceIntPtr ptr; DeviceIntPtr ptr;
WindowPtr focus = keybd->focus->win; WindowPtr focus = keybd->focus->win;
BOOL sendCore = (IsMaster(keybd) && keybd->coreEvents); BOOL sendCore = (IsMaster(keybd) && keybd->coreEvents);
xEvent core; xEvent *core = NULL, *xE = NULL, *xi2 = NULL;
xEvent *xE = NULL, *xi2 = NULL;
int count, rc; int count, rc;
int deliveries = 0; int deliveries = 0;
@ -3737,13 +3733,13 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
if (sendCore) if (sendCore)
{ {
rc = EventToCore(event, &core); rc = EventToCore(event, &core, &count);
if (rc == Success) { if (rc == Success) {
if (XaceHook(XACE_SEND_ACCESS, NULL, keybd, focus, &core, 1) == Success) { if (XaceHook(XACE_SEND_ACCESS, NULL, keybd, focus, core, count) == Success) {
FixUpEventFromWindow(keybd->spriteInfo->sprite, &core, focus, FixUpEventFromWindow(keybd->spriteInfo->sprite, core, focus,
None, FALSE); None, FALSE);
deliveries = DeliverEventsToWindow(keybd, focus, &core, 1, deliveries = DeliverEventsToWindow(keybd, focus, core, count,
GetEventFilter(keybd, &core), GetEventFilter(keybd, core),
NullGrab); NullGrab);
} }
} else if (rc != BadMatch) } else if (rc != BadMatch)
@ -3752,6 +3748,7 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
} }
unwind: unwind:
free(core);
free(xE); free(xE);
free(xi2); free(xi2);
return; return;
@ -3777,6 +3774,7 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
int rc, count = 0; int rc, count = 0;
xEvent *xi = NULL; xEvent *xi = NULL;
xEvent *xi2 = NULL; xEvent *xi2 = NULL;
xEvent *core = NULL;
grabinfo = &thisDev->deviceGrab; grabinfo = &thisDev->deviceGrab;
grab = grabinfo->grab; grab = grabinfo->grab;
@ -3826,22 +3824,20 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
/* try core event */ /* try core event */
if (sendCore && grab->grabtype == GRABTYPE_CORE) if (sendCore && grab->grabtype == GRABTYPE_CORE)
{ {
xEvent core; rc = EventToCore(event, &core, &count);
rc = EventToCore(event, &core);
if (rc == Success) if (rc == Success)
{ {
FixUpEventFromWindow(pSprite, &core, grab->window, None, TRUE); FixUpEventFromWindow(pSprite, core, grab->window, None, TRUE);
if (XaceHook(XACE_SEND_ACCESS, 0, thisDev, if (XaceHook(XACE_SEND_ACCESS, 0, thisDev,
grab->window, &core, 1) || grab->window, core, count) ||
XaceHook(XACE_RECEIVE_ACCESS, rClient(grab), XaceHook(XACE_RECEIVE_ACCESS, rClient(grab),
grab->window, &core, 1)) grab->window, core, count))
deliveries = 1; /* don't send, but pretend we did */ deliveries = 1; /* don't send, but pretend we did */
else if (!IsInterferingGrab(rClient(grab), thisDev, &core)) else if (!IsInterferingGrab(rClient(grab), thisDev, core))
{ {
deliveries = TryClientEvents(rClient(grab), thisDev, deliveries = TryClientEvents(rClient(grab), thisDev,
&core, 1, mask, core, count, mask,
GetEventFilter(thisDev, &core), GetEventFilter(thisDev, core),
grab); grab);
} }
} else if (rc != BadMatch) } else if (rc != BadMatch)
@ -3931,6 +3927,7 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
} }
} }
free(core);
free(xi); free(xi);
free(xi2); free(xi2);
} }

View File

@ -30,7 +30,7 @@
#define FP1616(integral, frac) ((integral) * (1 << 16) + (frac) * (1 << 16)) #define FP1616(integral, frac) ((integral) * (1 << 16) + (frac) * (1 << 16))
_X_EXPORT int EventToCore(InternalEvent *event, xEvent *core); _X_EXPORT int EventToCore(InternalEvent *event, xEvent **core, int *count);
_X_EXPORT int EventToXI(InternalEvent *ev, xEvent **xi, int *count); _X_EXPORT int EventToXI(InternalEvent *ev, xEvent **xi, int *count);
_X_EXPORT int EventToXI2(InternalEvent *ev, xEvent **xi); _X_EXPORT int EventToXI2(InternalEvent *ev, xEvent **xi);
_X_INTERNAL int GetCoreType(InternalEvent* ev); _X_INTERNAL int GetCoreType(InternalEvent* ev);

View File

@ -804,6 +804,7 @@ RecordADeviceEvent(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
RecordContextPtr pContext; RecordContextPtr pContext;
RecordClientsAndProtocolPtr pRCAP; RecordClientsAndProtocolPtr pRCAP;
int eci; /* enabled context index */ int eci; /* enabled context index */
int count;
for (eci = 0; eci < numEnabledContexts; eci++) for (eci = 0; eci < numEnabledContexts; eci++)
{ {
@ -818,9 +819,11 @@ RecordADeviceEvent(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
/* TODO check return values */ /* TODO check return values */
if (IsMaster(pei->device)) if (IsMaster(pei->device))
{ {
xEvent xE; xEvent *core_events;
EventToCore(pei->event, &xE); EventToCore(pei->event, &core_events, &count);
RecordSendProtocolEvents(pRCAP, pContext, &xE, 1); RecordSendProtocolEvents(pRCAP, pContext, core_events,
count);
free(core_events);
} }
EventToXI(pei->event, &xi_events, &count); EventToXI(pei->event, &xi_events, &count);

View File

@ -148,29 +148,32 @@ static void dix_check_grab_values(void)
static void dix_event_to_core(int type) static void dix_event_to_core(int type)
{ {
DeviceEvent ev; DeviceEvent ev;
xEvent core; xEvent *core;
int time; int time;
int x, y; int x, y;
int rc; int rc;
int state; int state;
int detail; int detail;
int count;
const int ROOT_WINDOW_ID = 0x100; const int ROOT_WINDOW_ID = 0x100;
/* EventToCore memsets the event to 0 */ /* EventToCore memsets the event to 0 */
#define test_event() \ #define test_event() \
g_assert(rc == Success); \ g_assert(rc == Success); \
g_assert(core.u.u.type == type); \ g_assert(core); \
g_assert(core.u.u.detail == detail); \ g_assert(count == 1); \
g_assert(core.u.keyButtonPointer.time == time); \ g_assert(core->u.u.type == type); \
g_assert(core.u.keyButtonPointer.rootX == x); \ g_assert(core->u.u.detail == detail); \
g_assert(core.u.keyButtonPointer.rootY == y); \ g_assert(core->u.keyButtonPointer.time == time); \
g_assert(core.u.keyButtonPointer.state == state); \ g_assert(core->u.keyButtonPointer.rootX == x); \
g_assert(core.u.keyButtonPointer.eventX == 0); \ g_assert(core->u.keyButtonPointer.rootY == y); \
g_assert(core.u.keyButtonPointer.eventY == 0); \ g_assert(core->u.keyButtonPointer.state == state); \
g_assert(core.u.keyButtonPointer.root == ROOT_WINDOW_ID); \ g_assert(core->u.keyButtonPointer.eventX == 0); \
g_assert(core.u.keyButtonPointer.event == 0); \ g_assert(core->u.keyButtonPointer.eventY == 0); \
g_assert(core.u.keyButtonPointer.child == 0); \ g_assert(core->u.keyButtonPointer.root == ROOT_WINDOW_ID); \
g_assert(core.u.keyButtonPointer.sameScreen == FALSE); g_assert(core->u.keyButtonPointer.event == 0); \
g_assert(core->u.keyButtonPointer.child == 0); \
g_assert(core->u.keyButtonPointer.sameScreen == FALSE);
x = 0; x = 0;
y = 0; y = 0;
@ -191,30 +194,33 @@ static void dix_event_to_core(int type)
ev.type = type; ev.type = type;
ev.detail.key = 0; ev.detail.key = 0;
rc = EventToCore((InternalEvent*)&ev, &core); rc = EventToCore((InternalEvent*)&ev, &core, &count);
test_event(); test_event();
x = 1; x = 1;
y = 2; y = 2;
ev.root_x = x; ev.root_x = x;
ev.root_y = y; ev.root_y = y;
rc = EventToCore((InternalEvent*)&ev, &core); rc = EventToCore((InternalEvent*)&ev, &core, &count);
test_event(); test_event();
x = 0x7FFF; x = 0x7FFF;
y = 0x7FFF; y = 0x7FFF;
ev.root_x = x; ev.root_x = x;
ev.root_y = y; ev.root_y = y;
rc = EventToCore((InternalEvent*)&ev, &core); rc = EventToCore((InternalEvent*)&ev, &core, &count);
test_event(); test_event();
x = 0x8000; /* too high */ x = 0x8000; /* too high */
y = 0x8000; /* too high */ y = 0x8000; /* too high */
ev.root_x = x; ev.root_x = x;
ev.root_y = y; ev.root_y = y;
rc = EventToCore((InternalEvent*)&ev, &core); rc = EventToCore((InternalEvent*)&ev, &core, &count);
g_assert(core.u.keyButtonPointer.rootX != x); g_assert(rc == Success);
g_assert(core.u.keyButtonPointer.rootY != y); g_assert(core);
g_assert(count == 1);
g_assert(core->u.keyButtonPointer.rootX != x);
g_assert(core->u.keyButtonPointer.rootY != y);
x = 0x7FFF; x = 0x7FFF;
y = 0x7FFF; y = 0x7FFF;
@ -222,36 +228,39 @@ static void dix_event_to_core(int type)
ev.root_y = y; ev.root_y = y;
time = 0; time = 0;
ev.time = time; ev.time = time;
rc = EventToCore((InternalEvent*)&ev, &core); rc = EventToCore((InternalEvent*)&ev, &core, &count);
test_event(); test_event();
detail = 1; detail = 1;
ev.detail.key = detail; ev.detail.key = detail;
rc = EventToCore((InternalEvent*)&ev, &core); rc = EventToCore((InternalEvent*)&ev, &core, &count);
test_event(); test_event();
detail = 0xFF; /* highest value */ detail = 0xFF; /* highest value */
ev.detail.key = detail; ev.detail.key = detail;
rc = EventToCore((InternalEvent*)&ev, &core); rc = EventToCore((InternalEvent*)&ev, &core, &count);
test_event(); test_event();
detail = 0xFFF; /* too big */ detail = 0xFFF; /* too big */
ev.detail.key = detail; ev.detail.key = detail;
rc = EventToCore((InternalEvent*)&ev, &core); rc = EventToCore((InternalEvent*)&ev, &core, &count);
g_assert(rc == BadMatch); g_assert(rc == BadMatch);
detail = 0xFF; /* too big */ detail = 0xFF; /* too big */
ev.detail.key = detail; ev.detail.key = detail;
state = 0xFFFF; /* highest value */ state = 0xFFFF; /* highest value */
ev.corestate = state; ev.corestate = state;
rc = EventToCore((InternalEvent*)&ev, &core); rc = EventToCore((InternalEvent*)&ev, &core, &count);
test_event(); test_event();
state = 0x10000; /* too big */ state = 0x10000; /* too big */
ev.corestate = state; ev.corestate = state;
rc = EventToCore((InternalEvent*)&ev, &core); rc = EventToCore((InternalEvent*)&ev, &core, &count);
g_assert(core.u.keyButtonPointer.state != state); g_assert(rc == Success);
g_assert(core.u.keyButtonPointer.state == (state & 0xFFFF)); g_assert(core);
g_assert(count == 1);
g_assert(core->u.keyButtonPointer.state != state);
g_assert(core->u.keyButtonPointer.state == (state & 0xFFFF));
#undef test_event #undef test_event
} }
@ -259,14 +268,15 @@ static void dix_event_to_core(int type)
static void dix_event_to_core_fail(int evtype, int expected_rc) static void dix_event_to_core_fail(int evtype, int expected_rc)
{ {
DeviceEvent ev; DeviceEvent ev;
xEvent core; xEvent *core;
int rc; int rc;
int count;
ev.header = 0xFF; ev.header = 0xFF;
ev.length = sizeof(DeviceEvent); ev.length = sizeof(DeviceEvent);
ev.type = evtype; ev.type = evtype;
rc = EventToCore((InternalEvent*)&ev, &core); rc = EventToCore((InternalEvent*)&ev, &core, &count);
g_assert(rc == expected_rc); g_assert(rc == expected_rc);
} }