diff --git a/Xi/exevents.c b/Xi/exevents.c index 94b9983bd..217baa956 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -1524,7 +1524,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, g = AllocGrab(devgrab); BUG_WARN(!g); - *dev->deviceGrab.sync.event = *ev; + CopyPartialInternalEvent(dev->deviceGrab.sync.event, ev); /* The listener array has a sequence of grabs and then one event * selection. Implicit grab activation occurs through delivering an diff --git a/dix/events.c b/dix/events.c index 341c746d4..28d7d177c 100644 --- a/dix/events.c +++ b/dix/events.c @@ -467,6 +467,20 @@ WindowXI2MaskIsset(DeviceIntPtr dev, WindowPtr win, xEvent *ev) return xi2mask_isset(inputMasks->xi2mask, dev, evtype); } +/** + * When processing events we operate on InternalEvent pointers. They may actually refer to a + * an instance of DeviceEvent, GestureEvent or any other event that comprises the InternalEvent + * union. This works well in practice because we always look into event type before doing anything, + * except in the case of copying the event. Any copying of InternalEvent should use this function + * instead of doing *dst_event = *src_event whenever it's not clear whether source event actually + * points to full InternalEvent instance. + */ +void +CopyPartialInternalEvent(InternalEvent* dst_event, const InternalEvent* src_event) +{ + memcpy(dst_event, src_event, src_event->any.length); +} + Mask GetEventMask(DeviceIntPtr dev, xEvent *event, InputClients * other) { @@ -3873,7 +3887,7 @@ void ActivateGrabNoDelivery(DeviceIntPtr dev, GrabPtr grab, if (grabinfo->sync.state == FROZEN_NO_EVENT) grabinfo->sync.state = FROZEN_WITH_EVENT; - *grabinfo->sync.event = *real_event; + CopyPartialInternalEvent(grabinfo->sync.event, real_event); } static BOOL @@ -4455,7 +4469,7 @@ FreezeThisEventIfNeededForSyncGrab(DeviceIntPtr thisDev, InternalEvent *event) case FREEZE_NEXT_EVENT: grabinfo->sync.state = FROZEN_WITH_EVENT; FreezeThaw(thisDev, TRUE); - *grabinfo->sync.event = *event; + CopyPartialInternalEvent(grabinfo->sync.event, event); break; } } diff --git a/include/input.h b/include/input.h index b1aef3663..cdb5d5a90 100644 --- a/include/input.h +++ b/include/input.h @@ -676,6 +676,7 @@ extern void GestureEmitGestureEndToOwner(DeviceIntPtr dev, GestureInfoPtr gi); extern void ProcessGestureEvent(InternalEvent *ev, DeviceIntPtr dev); /* misc event helpers */ +extern void CopyPartialInternalEvent(InternalEvent* dst_event, const InternalEvent* src_event); extern Mask GetEventMask(DeviceIntPtr dev, xEvent *ev, InputClientsPtr clients); extern Mask GetEventFilter(DeviceIntPtr dev, xEvent *event); extern Bool WindowXI2MaskIsset(DeviceIntPtr dev, WindowPtr win, xEvent *ev);