[PATCH 6/6] Input: Allow EventToCore to return multiple events

Daniel Stone daniel at fooishbar.org
Tue Feb 15 03:28:02 PST 2011


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 at fooishbar.org>
---
 dix/eventconvert.c     |   37 ++++++++++++++++++++-----
 dix/events.c           |   57 +++++++++++++++++++---------------------
 include/eventconvert.h |    2 +-
 record/record.c        |    9 ++++--
 test/input.c           |   68 +++++++++++++++++++++++++++--------------------
 5 files changed, 102 insertions(+), 71 deletions(-)

diff --git a/dix/eventconvert.c b/dix/eventconvert.c
index 7b894f0..8976919 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -97,8 +97,12 @@ EventIsKeyRepeat(xEvent *event)
  * @return Success or the matching error code.
  */
 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)
     {
         case ET_Motion:
@@ -108,7 +112,10 @@ EventToCore(InternalEvent *event, xEvent *core)
                  * present */
                 if (!BitIsOn(e->valuators.mask, 0) &&
                     !BitIsOn(e->valuators.mask, 1))
-                    return BadMatch;
+                {
+                    ret = BadMatch;
+                    goto out;
+                }
             }
             /* fallthrough */
         case ET_ButtonPress:
@@ -119,9 +126,15 @@ EventToCore(InternalEvent *event, xEvent *core)
                 DeviceEvent *e = &event->device_event;
 
                 if (e->detail.key > 0xFF)
-                    return BadMatch;
-
-                memset(core, 0, sizeof(xEvent));
+                {
+                    ret = BadMatch;
+                    goto out;
+                }
+
+                core = calloc(1, sizeof(*core));
+                if (!core)
+                    return BadAlloc;
+                count = 1;
                 core->u.u.type = e->type - ET_KeyPress + KeyPress;
                 core->u.u.detail = e->detail.key & 0xFF;
                 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.state = e->corestate;
                 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;
         case ET_ProximityIn:
@@ -139,13 +155,18 @@ EventToCore(InternalEvent *event, xEvent *core)
         case ET_RawButtonPress:
         case ET_RawButtonRelease:
         case ET_RawMotion:
-            return BadMatch;
+            ret = BadMatch;
+            goto out;
         default:
             /* XXX: */
             ErrorF("[dix] EventToCore: Not implemented yet \n");
-            return BadImplementation;
+            ret = BadImplementation;
     }
-    return Success;
+
+out:
+    *core_out = core;
+    *count_out = count;
+    return ret;
 }
 
 /**
diff --git a/dix/events.c b/dix/events.c
index 0dbe6e6..2a79c9a 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2366,8 +2366,7 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
     Window child = None;
     Mask filter;
     int deliveries = 0;
-    xEvent core;
-    xEvent *xE = NULL;
+    xEvent *xE = NULL, *core = NULL;
     int rc, mask, count = 0;
 
     CHECKEVENT(event);
@@ -2417,13 +2416,13 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
             /* Core event */
             if ((mask & EVENT_CORE_MASK) && IsMaster(dev) && dev->coreEvents)
             {
-                rc = EventToCore(event, &core);
+                rc = EventToCore(event, &core, &count);
                 if (rc == Success) {
-                    if (XaceHook(XACE_SEND_ACCESS, NULL, dev, pWin, &core, 1) == Success) {
-                        filter = GetEventFilter(dev, &core);
-                        FixUpEventFromWindow(pSprite, &core, pWin, child, FALSE);
-                        deliveries = DeliverEventsToWindow(dev, pWin, &core, 1,
-                                                           filter, grab);
+                    if (XaceHook(XACE_SEND_ACCESS, NULL, dev, pWin, core, count) == Success) {
+                        filter = GetEventFilter(dev, core);
+                        FixUpEventFromWindow(pSprite, core, pWin, child, FALSE);
+                        deliveries = DeliverEventsToWindow(dev, pWin, core,
+                                                           count, filter, grab);
                         if (deliveries > 0)
                             goto unwind;
                     }
@@ -2445,6 +2444,7 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
     }
 
 unwind:
+    free(core);
     free(xE);
     return deliveries;
 }
@@ -3460,7 +3460,6 @@ CheckPassiveGrabsOnWindow(
 	{
             int rc, count = 0;
             xEvent *xE = NULL;
-            xEvent core;
 
             event->corestate &= 0x1f00;
             event->corestate |= tempGrab.modifiersDetail.exact & (~0x1f00);
@@ -3512,7 +3511,7 @@ CheckPassiveGrabsOnWindow(
 
             if (match & CORE_MATCH)
             {
-                rc = EventToCore((InternalEvent*)event, &core);
+                rc = EventToCore((InternalEvent*)event, &xE, &count);
                 if (rc != Success)
                 {
                     if (rc != BadMatch)
@@ -3520,8 +3519,6 @@ CheckPassiveGrabsOnWindow(
                                 "(%d, %d).\n", device->name, event->type, rc);
                     continue;
                 }
-                xE = &core;
-                count = 1;
             } else if (match & XI2_MATCH)
             {
                 rc = EventToXI2((InternalEvent*)event, &xE);
@@ -3551,6 +3548,7 @@ CheckPassiveGrabsOnWindow(
             {
                 FixUpEventFromWindow(pSprite, xE, grab->window, None, TRUE);
 
+                /* XXX: XACE? */
                 TryClientEvents(rClient(grab), device, xE, count,
                                        GetEventFilter(device, xE),
                                        GetEventFilter(device, xE), grab);
@@ -3564,8 +3562,7 @@ CheckPassiveGrabsOnWindow(
 		grabinfo->sync.state = FROZEN_WITH_EVENT;
             }
 
-            if (match & (XI_MATCH | XI2_MATCH))
-                free(xE); /* on core match xE == &core */
+            free(xE);
 	    return grab;
 	}
     }
@@ -3682,8 +3679,7 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
     DeviceIntPtr ptr;
     WindowPtr focus = keybd->focus->win;
     BOOL sendCore = (IsMaster(keybd) && keybd->coreEvents);
-    xEvent core;
-    xEvent *xE = NULL, *xi2 = NULL;
+    xEvent *core = NULL, *xE = NULL, *xi2 = NULL;
     int count, rc;
     int deliveries = 0;
 
@@ -3737,13 +3733,13 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
 
     if (sendCore)
     {
-        rc = EventToCore(event, &core);
+        rc = EventToCore(event, &core, &count);
         if (rc == Success) {
-            if (XaceHook(XACE_SEND_ACCESS, NULL, keybd, focus, &core, 1) == Success) {
-                FixUpEventFromWindow(keybd->spriteInfo->sprite, &core, focus,
+            if (XaceHook(XACE_SEND_ACCESS, NULL, keybd, focus, core, count) == Success) {
+                FixUpEventFromWindow(keybd->spriteInfo->sprite, core, focus,
                                      None, FALSE);
-                deliveries = DeliverEventsToWindow(keybd, focus, &core, 1,
-                                                   GetEventFilter(keybd, &core),
+                deliveries = DeliverEventsToWindow(keybd, focus, core, count,
+                                                   GetEventFilter(keybd, core),
                                                    NullGrab);
             }
         } else if (rc != BadMatch)
@@ -3752,6 +3748,7 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
     }
 
 unwind:
+    free(core);
     free(xE);
     free(xi2);
     return;
@@ -3777,6 +3774,7 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
     int rc, count = 0;
     xEvent *xi = NULL;
     xEvent *xi2 = NULL;
+    xEvent *core = NULL;
 
     grabinfo = &thisDev->deviceGrab;
     grab = grabinfo->grab;
@@ -3826,22 +3824,20 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
         /* try core event */
         if (sendCore && grab->grabtype == GRABTYPE_CORE)
         {
-            xEvent core;
-
-            rc = EventToCore(event, &core);
+            rc = EventToCore(event, &core, &count);
             if (rc == Success)
             {
-                FixUpEventFromWindow(pSprite, &core, grab->window, None, TRUE);
+                FixUpEventFromWindow(pSprite, core, grab->window, None, TRUE);
                 if (XaceHook(XACE_SEND_ACCESS, 0, thisDev,
-                            grab->window, &core, 1) ||
+                            grab->window, core, count) ||
                         XaceHook(XACE_RECEIVE_ACCESS, rClient(grab),
-                            grab->window, &core, 1))
+                            grab->window, core, count))
                     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,
-                            &core, 1, mask,
-                            GetEventFilter(thisDev, &core),
+                            core, count, mask,
+                            GetEventFilter(thisDev, core),
                             grab);
                 }
             } else if (rc != BadMatch)
@@ -3931,6 +3927,7 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
 	}
     }
 
+    free(core);
     free(xi);
     free(xi2);
 }
diff --git a/include/eventconvert.h b/include/eventconvert.h
index b1196a0..b000abc 100644
--- a/include/eventconvert.h
+++ b/include/eventconvert.h
@@ -30,7 +30,7 @@
 
 #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 EventToXI2(InternalEvent *ev, xEvent **xi);
 _X_INTERNAL int GetCoreType(InternalEvent* ev);
diff --git a/record/record.c b/record/record.c
index 6a93d7a..1168c43 100644
--- a/record/record.c
+++ b/record/record.c
@@ -804,6 +804,7 @@ RecordADeviceEvent(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
     RecordContextPtr pContext;
     RecordClientsAndProtocolPtr pRCAP;
     int eci; /* enabled context index */
+    int count;
 
     for (eci = 0; eci < numEnabledContexts; eci++)
     {
@@ -818,9 +819,11 @@ RecordADeviceEvent(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
 		/* TODO check return values */
 		if (IsMaster(pei->device))
 		{
-		    xEvent xE;
-		    EventToCore(pei->event, &xE);
-		    RecordSendProtocolEvents(pRCAP, pContext, &xE, 1);
+		    xEvent *core_events;
+		    EventToCore(pei->event, &core_events, &count);
+		    RecordSendProtocolEvents(pRCAP, pContext, core_events,
+                                             count);
+		    free(core_events);
 		}
 
 		EventToXI(pei->event, &xi_events, &count);
diff --git a/test/input.c b/test/input.c
index 879e14f..e7300a1 100644
--- a/test/input.c
+++ b/test/input.c
@@ -148,29 +148,32 @@ static void dix_check_grab_values(void)
 static void dix_event_to_core(int type)
 {
     DeviceEvent ev;
-    xEvent core;
+    xEvent *core;
     int time;
     int x, y;
     int rc;
     int state;
     int detail;
+    int count;
     const int ROOT_WINDOW_ID = 0x100;
 
     /* EventToCore memsets the event to 0 */
 #define test_event() \
     g_assert(rc == Success); \
-    g_assert(core.u.u.type == type); \
-    g_assert(core.u.u.detail == detail); \
-    g_assert(core.u.keyButtonPointer.time == time); \
-    g_assert(core.u.keyButtonPointer.rootX == x); \
-    g_assert(core.u.keyButtonPointer.rootY == y); \
-    g_assert(core.u.keyButtonPointer.state == state); \
-    g_assert(core.u.keyButtonPointer.eventX == 0); \
-    g_assert(core.u.keyButtonPointer.eventY == 0); \
-    g_assert(core.u.keyButtonPointer.root == ROOT_WINDOW_ID); \
-    g_assert(core.u.keyButtonPointer.event == 0); \
-    g_assert(core.u.keyButtonPointer.child == 0); \
-    g_assert(core.u.keyButtonPointer.sameScreen == FALSE);
+    g_assert(core); \
+    g_assert(count == 1); \
+    g_assert(core->u.u.type == type); \
+    g_assert(core->u.u.detail == detail); \
+    g_assert(core->u.keyButtonPointer.time == time); \
+    g_assert(core->u.keyButtonPointer.rootX == x); \
+    g_assert(core->u.keyButtonPointer.rootY == y); \
+    g_assert(core->u.keyButtonPointer.state == state); \
+    g_assert(core->u.keyButtonPointer.eventX == 0); \
+    g_assert(core->u.keyButtonPointer.eventY == 0); \
+    g_assert(core->u.keyButtonPointer.root == ROOT_WINDOW_ID); \
+    g_assert(core->u.keyButtonPointer.event == 0); \
+    g_assert(core->u.keyButtonPointer.child == 0); \
+    g_assert(core->u.keyButtonPointer.sameScreen == FALSE);
 
     x = 0;
     y = 0;
@@ -191,30 +194,33 @@ static void dix_event_to_core(int type)
 
     ev.type = type;
     ev.detail.key = 0;
-    rc = EventToCore((InternalEvent*)&ev, &core);
+    rc = EventToCore((InternalEvent*)&ev, &core, &count);
     test_event();
 
     x = 1;
     y = 2;
     ev.root_x = x;
     ev.root_y = y;
-    rc = EventToCore((InternalEvent*)&ev, &core);
+    rc = EventToCore((InternalEvent*)&ev, &core, &count);
     test_event();
 
     x = 0x7FFF;
     y = 0x7FFF;
     ev.root_x = x;
     ev.root_y = y;
-    rc = EventToCore((InternalEvent*)&ev, &core);
+    rc = EventToCore((InternalEvent*)&ev, &core, &count);
     test_event();
 
     x = 0x8000; /* too high */
     y = 0x8000; /* too high */
     ev.root_x = x;
     ev.root_y = y;
-    rc = EventToCore((InternalEvent*)&ev, &core);
-    g_assert(core.u.keyButtonPointer.rootX != x);
-    g_assert(core.u.keyButtonPointer.rootY != y);
+    rc = EventToCore((InternalEvent*)&ev, &core, &count);
+    g_assert(rc == Success);
+    g_assert(core);
+    g_assert(count == 1);
+    g_assert(core->u.keyButtonPointer.rootX != x);
+    g_assert(core->u.keyButtonPointer.rootY != y);
 
     x = 0x7FFF;
     y = 0x7FFF;
@@ -222,36 +228,39 @@ static void dix_event_to_core(int type)
     ev.root_y = y;
     time = 0;
     ev.time = time;
-    rc = EventToCore((InternalEvent*)&ev, &core);
+    rc = EventToCore((InternalEvent*)&ev, &core, &count);
     test_event();
 
     detail = 1;
     ev.detail.key = detail;
-    rc = EventToCore((InternalEvent*)&ev, &core);
+    rc = EventToCore((InternalEvent*)&ev, &core, &count);
     test_event();
 
     detail = 0xFF; /* highest value */
     ev.detail.key = detail;
-    rc = EventToCore((InternalEvent*)&ev, &core);
+    rc = EventToCore((InternalEvent*)&ev, &core, &count);
     test_event();
 
     detail = 0xFFF; /* too big */
     ev.detail.key = detail;
-    rc = EventToCore((InternalEvent*)&ev, &core);
+    rc = EventToCore((InternalEvent*)&ev, &core, &count);
     g_assert(rc == BadMatch);
 
     detail = 0xFF; /* too big */
     ev.detail.key = detail;
     state = 0xFFFF; /* highest value */
     ev.corestate = state;
-    rc = EventToCore((InternalEvent*)&ev, &core);
+    rc = EventToCore((InternalEvent*)&ev, &core, &count);
     test_event();
 
     state = 0x10000; /* too big */
     ev.corestate = state;
-    rc = EventToCore((InternalEvent*)&ev, &core);
-    g_assert(core.u.keyButtonPointer.state != state);
-    g_assert(core.u.keyButtonPointer.state == (state & 0xFFFF));
+    rc = EventToCore((InternalEvent*)&ev, &core, &count);
+    g_assert(rc == Success);
+    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
 }
@@ -259,14 +268,15 @@ static void dix_event_to_core(int type)
 static void dix_event_to_core_fail(int evtype, int expected_rc)
 {
     DeviceEvent ev;
-    xEvent core;
+    xEvent *core;
     int rc;
+    int count;
 
     ev.header   = 0xFF;
     ev.length   = sizeof(DeviceEvent);
 
     ev.type     = evtype;
-    rc = EventToCore((InternalEvent*)&ev, &core);
+    rc = EventToCore((InternalEvent*)&ev, &core, &count);
     g_assert(rc == expected_rc);
 }
 
-- 
1.7.2.3



More information about the xorg-devel mailing list