From 100a2ad6da4ba90f8d489c7a2ed3f3f0ac879a6f Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Sun, 30 May 2021 13:26:40 +0300 Subject: [PATCH] dix: Implement gesture event submission code path --- dix/getevents.c | 136 +++++++++++++++++++++++++++++++++++++++++++ dix/inpututils.c | 15 +++++ include/input.h | 27 +++++++++ include/inpututils.h | 1 + 4 files changed, 179 insertions(+) diff --git a/dix/getevents.c b/dix/getevents.c index 5dceec39b..368e0fb2a 100644 --- a/dix/getevents.c +++ b/dix/getevents.c @@ -2099,3 +2099,139 @@ PostSyntheticMotion(DeviceIntPtr pDev, /* FIXME: MD/SD considerations? */ (*pDev->public.processInputProc) ((InternalEvent *) &ev, pDev); } + +void +InitGestureEvent(InternalEvent *ievent, DeviceIntPtr dev, CARD32 ms, + int type, uint16_t num_touches, uint32_t flags, + double delta_x, double delta_y, + double delta_unaccel_x, double delta_unaccel_y, + double scale, double delta_angle) +{ + ScreenPtr scr = dev->spriteInfo->sprite->hotPhys.pScreen; + GestureEvent *event = &ievent->gesture_event; + double screenx = 0.0, screeny = 0.0; /* desktop coordinate system */ + + init_gesture_event(event, dev, ms); + + screenx = dev->spriteInfo->sprite->hotPhys.x; + screeny = dev->spriteInfo->sprite->hotPhys.y; + + event->type = type; + event->root = scr->root->drawable.id; + event->root_x = screenx - scr->x; + event->root_y = screeny - scr->y; + event->num_touches = num_touches; + event->flags = flags; + + event->delta_x = delta_x; + event->delta_y = delta_y; + event->delta_unaccel_x = delta_unaccel_x; + event->delta_unaccel_y = delta_unaccel_y; + event->scale = scale; + event->delta_angle = delta_angle; +} + +/** + * Get events for a pinch or swipe gesture. + * + * events is not NULL-terminated; the return value is the number of events. + * The DDX is responsible for allocating the event structure in the first + * place via GetMaximumEventsNum(), and for freeing it. + * + * @param[out] events The list of events generated + * @param dev The device to generate the events for + * @param type XI_Gesture{Pinch,Swipe}{Begin,Update,End} + * @prama num_touches The number of touches in the gesture + * @param flags Event flags + * @param delta_x,delta_y accelerated relative motion delta + * @param delta_unaccel_x,delta_unaccel_y unaccelerated relative motion delta + * @param scale (valid only to pinch events) absolute scale of a pinch gesture + * @param delta_angle (valid only to pinch events) the ange delta in degrees between the last and + * the current pinch event. + */ +int +GetGestureEvents(InternalEvent *events, DeviceIntPtr dev, + uint16_t type, uint16_t num_touches, uint32_t flags, + double delta_x, double delta_y, + double delta_unaccel_x, double delta_unaccel_y, + double scale, double delta_angle) + +{ + GestureClassPtr g = dev->gesture; + CARD32 ms = GetTimeInMillis(); + enum EventType evtype; + int num_events = 0; + uint32_t evflags = 0; + + if (!dev->enabled || !g) + return 0; + + if (!IsMaster(dev)) + events = UpdateFromMaster(events, dev, DEVCHANGE_POINTER_EVENT, + &num_events); + + switch (type) { + case XI_GesturePinchBegin: + evtype = ET_GesturePinchBegin; + break; + case XI_GesturePinchUpdate: + evtype = ET_GesturePinchUpdate; + break; + case XI_GesturePinchEnd: + evtype = ET_GesturePinchEnd; + if (flags & XIGesturePinchEventCancelled) + evflags |= GESTURE_CANCELLED; + break; + case XI_GestureSwipeBegin: + evtype = ET_GestureSwipeBegin; + break; + case XI_GestureSwipeUpdate: + evtype = ET_GestureSwipeUpdate; + break; + case XI_GestureSwipeEnd: + evtype = ET_GestureSwipeEnd; + if (flags & XIGestureSwipeEventCancelled) + evflags |= GESTURE_CANCELLED; + break; + default: + return 0; + } + + InitGestureEvent(events, dev, ms, evtype, num_touches, evflags, + delta_x, delta_y, delta_unaccel_x, delta_unaccel_y, + scale, delta_angle); + num_events++; + + return num_events; +} + +void +QueueGesturePinchEvents(DeviceIntPtr dev, uint16_t type, + uint16_t num_touches, uint32_t flags, + double delta_x, double delta_y, + double delta_unaccel_x, + double delta_unaccel_y, + double scale, double delta_angle) +{ + int nevents; + nevents = GetGestureEvents(InputEventList, dev, type, num_touches, flags, + delta_x, delta_y, + delta_unaccel_x, delta_unaccel_y, + scale, delta_angle); + queueEventList(dev, InputEventList, nevents); +} + +void +QueueGestureSwipeEvents(DeviceIntPtr dev, uint16_t type, + uint16_t num_touches, uint32_t flags, + double delta_x, double delta_y, + double delta_unaccel_x, + double delta_unaccel_y) +{ + int nevents; + nevents = GetGestureEvents(InputEventList, dev, type, num_touches, flags, + delta_x, delta_y, + delta_unaccel_x, delta_unaccel_y, + 0.0, 0.0); + queueEventList(dev, InputEventList, nevents); +} diff --git a/dix/inpututils.c b/dix/inpututils.c index b60ffff0d..6906f997b 100644 --- a/dix/inpututils.c +++ b/dix/inpututils.c @@ -746,6 +746,21 @@ init_device_event(DeviceEvent *event, DeviceIntPtr dev, Time ms, event->source_type = source_type; } +/** + * Initializes the given gesture event to zero (or default values), + * for the given device. + */ +void +init_gesture_event(GestureEvent *event, DeviceIntPtr dev, Time ms) +{ + memset(event, 0, sizeof(GestureEvent)); + event->header = ET_Internal; + event->length = sizeof(GestureEvent); + event->time = ms; + event->deviceid = dev->id; + event->sourceid = dev->id; +} + int event_get_corestate(DeviceIntPtr mouse, DeviceIntPtr kbd) { diff --git a/include/input.h b/include/input.h index d607e6b97..c19e74969 100644 --- a/include/input.h +++ b/include/input.h @@ -496,6 +496,33 @@ void QueueTouchEvents(DeviceIntPtr device, uint32_t ddx_touchid, int flags, const ValuatorMask *mask); +void InitGestureEvent(InternalEvent *ievent, DeviceIntPtr dev, CARD32 ms, + int type, uint16_t num_touches, uint32_t flags, + double delta_x, double delta_y, + double delta_unaccel_x, double delta_unaccel_y, + double scale, double delta_angle); + +int GetGestureEvents(InternalEvent *events, DeviceIntPtr dev, + uint16_t type, uint16_t num_touches, uint32_t flags, + double delta_x, double delta_y, + double delta_unaccel_x, + double delta_unaccel_y, + double scale, double delta_angle); + + +void QueueGesturePinchEvents(DeviceIntPtr dev, uint16_t type, + uint16_t num_touches, uint32_t flags, + double delta_x, double delta_y, + double delta_unaccel_x, + double delta_unaccel_y, + double scale, double delta_angle); + +void QueueGestureSwipeEvents(DeviceIntPtr dev, uint16_t type, + uint16_t num_touches, uint32_t flags, + double delta_x, double delta_y, + double delta_unaccel_x, + double delta_unaccel_y); + extern int GetTouchOwnershipEvents(InternalEvent *events, DeviceIntPtr pDev, TouchPointInfoPtr ti, diff --git a/include/inpututils.h b/include/inpututils.h index 2dfe122c9..489e1d9b7 100644 --- a/include/inpututils.h +++ b/include/inpututils.h @@ -46,6 +46,7 @@ struct _ValuatorMask { extern void verify_internal_event(const InternalEvent *ev); extern void init_device_event(DeviceEvent *event, DeviceIntPtr dev, Time ms, enum DeviceEventSource event_source); +extern void init_gesture_event(GestureEvent *event, DeviceIntPtr dev, Time ms); extern int event_get_corestate(DeviceIntPtr mouse, DeviceIntPtr kbd); extern void event_set_state(DeviceIntPtr mouse, DeviceIntPtr kbd, DeviceEvent *event);