1/*
2 * Copyright © 2006 Nokia Corporation
3 * Copyright © 2006-2007 Daniel Stone
4 * Copyright © 2008 Red Hat, Inc.
5 * Copyright © 2011 The Chromium Authors
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
25 *
26 * Authors: Daniel Stone <daniel@fooishbar.org>
27 *          Peter Hutterer <peter.hutterer@who-t.net>
28 */
29
30#ifdef HAVE_DIX_CONFIG_H
31#include <dix-config.h>
32#endif
33
34#include <X11/X.h>
35#include <X11/keysym.h>
36#include <X11/Xproto.h>
37#include <math.h>
38#include <limits.h>
39
40#include "misc.h"
41#include "resource.h"
42#include "inputstr.h"
43#include "scrnintstr.h"
44#include "cursorstr.h"
45#include "dixstruct.h"
46#include "globals.h"
47#include "dixevents.h"
48#include "mipointer.h"
49#include "eventstr.h"
50#include "eventconvert.h"
51#include "inpututils.h"
52#include "mi.h"
53#include "windowstr.h"
54
55#include <X11/extensions/XKBproto.h>
56#include "xkbsrv.h"
57
58#ifdef PANORAMIX
59#include "panoramiX.h"
60#include "panoramiXsrv.h"
61#endif
62
63#include <X11/extensions/XI.h>
64#include <X11/extensions/XI2.h>
65#include <X11/extensions/XIproto.h>
66#include <pixman.h>
67#include "exglobals.h"
68#include "exevents.h"
69#include "extnsionst.h"
70#include "listdev.h"            /* for sizing up DeviceClassesChangedEvent */
71#include "probes.h"
72
73/* Number of motion history events to store. */
74#define MOTION_HISTORY_SIZE 256
75
76/**
77 * InputEventList is the storage for input events generated by
78 * QueuePointerEvents, QueueKeyboardEvents, and QueueProximityEvents.
79 * This list is allocated on startup by the DIX.
80 */
81InternalEvent *InputEventList = NULL;
82
83/**
84 * Pick some arbitrary size for Xi motion history.
85 */
86int
87GetMotionHistorySize(void)
88{
89    return MOTION_HISTORY_SIZE;
90}
91
92void
93set_button_down(DeviceIntPtr pDev, int button, int type)
94{
95    if (type == BUTTON_PROCESSED)
96        SetBit(pDev->button->down, button);
97    else
98        SetBit(pDev->button->postdown, button);
99}
100
101void
102set_button_up(DeviceIntPtr pDev, int button, int type)
103{
104    if (type == BUTTON_PROCESSED)
105        ClearBit(pDev->button->down, button);
106    else
107        ClearBit(pDev->button->postdown, button);
108}
109
110Bool
111button_is_down(DeviceIntPtr pDev, int button, int type)
112{
113    Bool ret = FALSE;
114
115    if (type & BUTTON_PROCESSED)
116        ret = ret || BitIsOn(pDev->button->down, button);
117    if (type & BUTTON_POSTED)
118        ret = ret || BitIsOn(pDev->button->postdown, button);
119
120    return ret;
121}
122
123void
124set_key_down(DeviceIntPtr pDev, int key_code, int type)
125{
126    if (type == KEY_PROCESSED)
127        SetBit(pDev->key->down, key_code);
128    else
129        SetBit(pDev->key->postdown, key_code);
130}
131
132void
133set_key_up(DeviceIntPtr pDev, int key_code, int type)
134{
135    if (type == KEY_PROCESSED)
136        ClearBit(pDev->key->down, key_code);
137    else
138        ClearBit(pDev->key->postdown, key_code);
139}
140
141Bool
142key_is_down(DeviceIntPtr pDev, int key_code, int type)
143{
144    Bool ret = FALSE;
145
146    if (type & KEY_PROCESSED)
147        ret = ret || BitIsOn(pDev->key->down, key_code);
148    if (type & KEY_POSTED)
149        ret = ret || BitIsOn(pDev->key->postdown, key_code);
150
151    return ret;
152}
153
154static Bool
155key_autorepeats(DeviceIntPtr pDev, int key_code)
156{
157    return ! !(pDev->kbdfeed->ctrl.autoRepeats[key_code >> 3] &
158               (1 << (key_code & 7)));
159}
160
161static void
162init_touch_ownership(DeviceIntPtr dev, TouchOwnershipEvent *event, Time ms)
163{
164    memset(event, 0, sizeof(TouchOwnershipEvent));
165    event->header = ET_Internal;
166    event->type = ET_TouchOwnership;
167    event->length = sizeof(TouchOwnershipEvent);
168    event->time = ms;
169    event->deviceid = dev->id;
170}
171
172static void
173init_raw(DeviceIntPtr dev, RawDeviceEvent *event, Time ms, int type, int detail)
174{
175    memset(event, 0, sizeof(RawDeviceEvent));
176    event->header = ET_Internal;
177    event->length = sizeof(RawDeviceEvent);
178    switch (type) {
179    case MotionNotify:
180        event->type = ET_RawMotion;
181        break;
182    case ButtonPress:
183        event->type = ET_RawButtonPress;
184        break;
185    case ButtonRelease:
186        event->type = ET_RawButtonRelease;
187        break;
188    case KeyPress:
189        event->type = ET_RawKeyPress;
190        break;
191    case KeyRelease:
192        event->type = ET_RawKeyRelease;
193        break;
194    case XI_TouchBegin:
195        event->type = ET_RawTouchBegin;
196        break;
197    case XI_TouchUpdate:
198        event->type = ET_RawTouchUpdate;
199        break;
200    case XI_TouchEnd:
201        event->type = ET_RawTouchEnd;
202        break;
203    }
204    event->time = ms;
205    event->deviceid = dev->id;
206    event->sourceid = dev->id;
207    event->detail.button = detail;
208}
209
210static void
211set_raw_valuators(RawDeviceEvent *event, ValuatorMask *mask,
212                  BOOL use_unaccel, double *data)
213{
214    int i;
215
216    use_unaccel = use_unaccel && valuator_mask_has_unaccelerated(mask);
217
218    for (i = 0; i < valuator_mask_size(mask); i++) {
219        if (valuator_mask_isset(mask, i)) {
220            double v;
221
222            SetBit(event->valuators.mask, i);
223
224            if (use_unaccel)
225                v = valuator_mask_get_unaccelerated(mask, i);
226            else
227                v = valuator_mask_get_double(mask, i);
228
229            data[i] = v;
230        }
231    }
232}
233
234static void
235set_valuators(DeviceIntPtr dev, DeviceEvent *event, ValuatorMask *mask)
236{
237    int i;
238
239    /* Set the data to the previous value for unset absolute axes. The values
240     * may be used when sent as part of an XI 1.x valuator event. */
241    for (i = 0; i < valuator_mask_size(mask); i++) {
242        if (valuator_mask_isset(mask, i)) {
243            SetBit(event->valuators.mask, i);
244            if (valuator_get_mode(dev, i) == Absolute)
245                SetBit(event->valuators.mode, i);
246            event->valuators.data[i] = valuator_mask_get_double(mask, i);
247        }
248        else
249            event->valuators.data[i] = dev->valuator->axisVal[i];
250    }
251}
252
253void
254CreateClassesChangedEvent(InternalEvent *event,
255                          DeviceIntPtr master, DeviceIntPtr slave, int flags)
256{
257    int i;
258    DeviceChangedEvent *dce;
259    CARD32 ms = GetTimeInMillis();
260
261    dce = &event->changed_event;
262    memset(dce, 0, sizeof(DeviceChangedEvent));
263    dce->deviceid = slave->id;
264    dce->masterid = master ? master->id : 0;
265    dce->header = ET_Internal;
266    dce->length = sizeof(DeviceChangedEvent);
267    dce->type = ET_DeviceChanged;
268    dce->time = ms;
269    dce->flags = flags;
270    dce->sourceid = slave->id;
271
272    if (slave->button) {
273        dce->buttons.num_buttons = slave->button->numButtons;
274        for (i = 0; i < dce->buttons.num_buttons; i++)
275            dce->buttons.names[i] = slave->button->labels[i];
276    }
277    if (slave->valuator) {
278        dce->num_valuators = slave->valuator->numAxes;
279        for (i = 0; i < dce->num_valuators; i++) {
280            dce->valuators[i].min = slave->valuator->axes[i].min_value;
281            dce->valuators[i].max = slave->valuator->axes[i].max_value;
282            dce->valuators[i].resolution = slave->valuator->axes[i].resolution;
283            dce->valuators[i].mode = slave->valuator->axes[i].mode;
284            dce->valuators[i].name = slave->valuator->axes[i].label;
285            dce->valuators[i].scroll = slave->valuator->axes[i].scroll;
286            dce->valuators[i].value = slave->valuator->axisVal[i];
287        }
288    }
289    if (slave->key) {
290        dce->keys.min_keycode = slave->key->xkbInfo->desc->min_key_code;
291        dce->keys.max_keycode = slave->key->xkbInfo->desc->max_key_code;
292    }
293}
294
295/**
296 * Rescale the coord between the two axis ranges.
297 */
298static double
299rescaleValuatorAxis(double coord, AxisInfoPtr from, AxisInfoPtr to,
300                    double defmin, double defmax)
301{
302    double fmin = defmin, fmax = defmax;
303    double tmin = defmin, tmax = defmax;
304
305    if (from && from->min_value < from->max_value) {
306        fmin = from->min_value;
307        fmax = from->max_value + 1;
308    }
309    if (to && to->min_value < to->max_value) {
310        tmin = to->min_value;
311        tmax = to->max_value + 1;
312    }
313
314    if (fmin == tmin && fmax == tmax)
315        return coord;
316
317    if (fmax == fmin)           /* avoid division by 0 */
318        return 0.0;
319
320    return (coord - fmin) * (tmax - tmin) / (fmax - fmin) + tmin;
321}
322
323/**
324 * Update all coordinates when changing to a different SD
325 * to ensure that relative reporting will work as expected
326 * without loss of precision.
327 *
328 * pDev->last.valuators will be in absolute device coordinates after this
329 * function.
330 */
331static void
332updateSlaveDeviceCoords(DeviceIntPtr master, DeviceIntPtr pDev)
333{
334    /* master->last.valuators[0]/[1] is in desktop-wide coords and the actual
335     * position of the pointer */
336    pDev->last.valuators[0] = master->last.valuators[0];
337    pDev->last.valuators[1] = master->last.valuators[1];
338
339    if (!pDev->valuator)
340        return;
341
342    /* scale back to device coordinates */
343    if (pDev->valuator->numAxes > 0) {
344        pDev->last.valuators[0] = rescaleValuatorAxis(pDev->last.valuators[0],
345                                                      NULL,
346                                                      pDev->valuator->axes + 0,
347                                                      screenInfo.x,
348                                                      screenInfo.width);
349    }
350    if (pDev->valuator->numAxes > 1) {
351        pDev->last.valuators[1] = rescaleValuatorAxis(pDev->last.valuators[1],
352                                                      NULL,
353                                                      pDev->valuator->axes + 1,
354                                                      screenInfo.y,
355                                                      screenInfo.height);
356    }
357
358    /* other axes are left as-is */
359}
360
361/**
362 * Allocate the motion history buffer.
363 */
364void
365AllocateMotionHistory(DeviceIntPtr pDev)
366{
367    int size;
368
369    free(pDev->valuator->motion);
370
371    if (pDev->valuator->numMotionEvents < 1)
372        return;
373
374    /* An MD must have a motion history size large enough to keep all
375     * potential valuators, plus the respective range of the valuators.
376     * 3 * INT32 for (min_val, max_val, curr_val))
377     */
378    if (IsMaster(pDev))
379        size = sizeof(INT32) * 3 * MAX_VALUATORS;
380    else {
381        ValuatorClassPtr v = pDev->valuator;
382        int numAxes;
383
384        /* XI1 doesn't understand mixed mode devices */
385        for (numAxes = 0; numAxes < v->numAxes; numAxes++)
386            if (valuator_get_mode(pDev, numAxes) != valuator_get_mode(pDev, 0))
387                break;
388        size = sizeof(INT32) * numAxes;
389    }
390
391    size += sizeof(Time);
392
393    pDev->valuator->motion = calloc(pDev->valuator->numMotionEvents, size);
394    pDev->valuator->first_motion = 0;
395    pDev->valuator->last_motion = 0;
396    if (!pDev->valuator->motion)
397        ErrorF("[dix] %s: Failed to alloc motion history (%d bytes).\n",
398               pDev->name, size * pDev->valuator->numMotionEvents);
399}
400
401/**
402 * Dump the motion history between start and stop into the supplied buffer.
403 * Only records the event for a given screen in theory, but in practice, we
404 * sort of ignore this.
405 *
406 * If core is set, we only generate x/y, in INT16, scaled to screen coords.
407 */
408int
409GetMotionHistory(DeviceIntPtr pDev, xTimecoord ** buff, unsigned long start,
410                 unsigned long stop, ScreenPtr pScreen, BOOL core)
411{
412    char *ibuff = NULL, *obuff;
413    int i = 0, ret = 0;
414    int j, coord;
415    Time current;
416
417    /* The size of a single motion event. */
418    int size;
419    AxisInfo from, *to;         /* for scaling */
420    INT32 *ocbuf, *icbuf;       /* pointer to coordinates for copying */
421    INT16 *corebuf;
422    AxisInfo core_axis = { 0 };
423
424    if (!pDev->valuator || !pDev->valuator->numMotionEvents)
425        return 0;
426
427    if (core && !pScreen)
428        return 0;
429
430    if (IsMaster(pDev))
431        size = (sizeof(INT32) * 3 * MAX_VALUATORS) + sizeof(Time);
432    else
433        size = (sizeof(INT32) * pDev->valuator->numAxes) + sizeof(Time);
434
435    *buff = malloc(size * pDev->valuator->numMotionEvents);
436    if (!(*buff))
437        return 0;
438    obuff = (char *) *buff;
439
440    for (i = pDev->valuator->first_motion;
441         i != pDev->valuator->last_motion;
442         i = (i + 1) % pDev->valuator->numMotionEvents) {
443        /* We index the input buffer by which element we're accessing, which
444         * is not monotonic, and the output buffer by how many events we've
445         * written so far. */
446        ibuff = (char *) pDev->valuator->motion + (i * size);
447        memcpy(&current, ibuff, sizeof(Time));
448
449        if (current > stop) {
450            return ret;
451        }
452        else if (current >= start) {
453            if (core) {
454                memcpy(obuff, ibuff, sizeof(Time));     /* copy timestamp */
455
456                icbuf = (INT32 *) (ibuff + sizeof(Time));
457                corebuf = (INT16 *) (obuff + sizeof(Time));
458
459                /* fetch x coordinate + range */
460                memcpy(&from.min_value, icbuf++, sizeof(INT32));
461                memcpy(&from.max_value, icbuf++, sizeof(INT32));
462                memcpy(&coord, icbuf++, sizeof(INT32));
463
464                /* scale to screen coords */
465                to = &core_axis;
466                to->max_value = pScreen->width;
467                coord =
468                    rescaleValuatorAxis(coord, &from, to, 0, pScreen->width);
469
470                memcpy(corebuf, &coord, sizeof(INT16));
471                corebuf++;
472
473                /* fetch y coordinate + range */
474                memcpy(&from.min_value, icbuf++, sizeof(INT32));
475                memcpy(&from.max_value, icbuf++, sizeof(INT32));
476                memcpy(&coord, icbuf++, sizeof(INT32));
477
478                to->max_value = pScreen->height;
479                coord =
480                    rescaleValuatorAxis(coord, &from, to, 0, pScreen->height);
481                memcpy(corebuf, &coord, sizeof(INT16));
482
483            }
484            else if (IsMaster(pDev)) {
485                memcpy(obuff, ibuff, sizeof(Time));     /* copy timestamp */
486
487                ocbuf = (INT32 *) (obuff + sizeof(Time));
488                icbuf = (INT32 *) (ibuff + sizeof(Time));
489                for (j = 0; j < MAX_VALUATORS; j++) {
490                    if (j >= pDev->valuator->numAxes)
491                        break;
492
493                    /* fetch min/max/coordinate */
494                    memcpy(&from.min_value, icbuf++, sizeof(INT32));
495                    memcpy(&from.max_value, icbuf++, sizeof(INT32));
496                    memcpy(&coord, icbuf++, sizeof(INT32));
497
498                    to = (j <
499                          pDev->valuator->numAxes) ? &pDev->valuator->
500                        axes[j] : NULL;
501
502                    /* x/y scaled to screen if no range is present */
503                    if (j == 0 && (from.max_value < from.min_value))
504                        from.max_value = pScreen->width;
505                    else if (j == 1 && (from.max_value < from.min_value))
506                        from.max_value = pScreen->height;
507
508                    /* scale from stored range into current range */
509                    coord = rescaleValuatorAxis(coord, &from, to, 0, 0);
510                    memcpy(ocbuf, &coord, sizeof(INT32));
511                    ocbuf++;
512                }
513            }
514            else
515                memcpy(obuff, ibuff, size);
516
517            /* don't advance by size here. size may be different to the
518             * actually written size if the MD has less valuators than MAX */
519            if (core)
520                obuff += sizeof(INT32) + sizeof(Time);
521            else
522                obuff +=
523                    (sizeof(INT32) * pDev->valuator->numAxes) + sizeof(Time);
524            ret++;
525        }
526    }
527
528    return ret;
529}
530
531/**
532 * Update the motion history for a specific device, with the list of
533 * valuators.
534 *
535 * Layout of the history buffer:
536 *   for SDs: [time] [val0] [val1] ... [valn]
537 *   for MDs: [time] [min_val0] [max_val0] [val0] [min_val1] ... [valn]
538 *
539 * For events that have some valuators unset:
540 *      min_val == max_val == val == 0.
541 */
542static void
543updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, ValuatorMask *mask,
544                    double *valuators)
545{
546    char *buff = (char *) pDev->valuator->motion;
547    ValuatorClassPtr v;
548    int i;
549
550    if (!pDev->valuator->numMotionEvents)
551        return;
552
553    v = pDev->valuator;
554    if (IsMaster(pDev)) {
555        buff += ((sizeof(INT32) * 3 * MAX_VALUATORS) + sizeof(CARD32)) *
556            v->last_motion;
557
558        memcpy(buff, &ms, sizeof(Time));
559        buff += sizeof(Time);
560
561        memset(buff, 0, sizeof(INT32) * 3 * MAX_VALUATORS);
562
563        for (i = 0; i < v->numAxes; i++) {
564            int val;
565
566            /* XI1 doesn't support mixed mode devices */
567            if (valuator_get_mode(pDev, i) != valuator_get_mode(pDev, 0))
568                break;
569            if (valuator_mask_size(mask) <= i || !valuator_mask_isset(mask, i)) {
570                buff += 3 * sizeof(INT32);
571                continue;
572            }
573            memcpy(buff, &v->axes[i].min_value, sizeof(INT32));
574            buff += sizeof(INT32);
575            memcpy(buff, &v->axes[i].max_value, sizeof(INT32));
576            buff += sizeof(INT32);
577            val = valuators[i];
578            memcpy(buff, &val, sizeof(INT32));
579            buff += sizeof(INT32);
580        }
581    }
582    else {
583
584        buff += ((sizeof(INT32) * pDev->valuator->numAxes) + sizeof(CARD32)) *
585            pDev->valuator->last_motion;
586
587        memcpy(buff, &ms, sizeof(Time));
588        buff += sizeof(Time);
589
590        memset(buff, 0, sizeof(INT32) * pDev->valuator->numAxes);
591
592        for (i = 0; i < MAX_VALUATORS; i++) {
593            int val;
594
595            if (valuator_mask_size(mask) <= i || !valuator_mask_isset(mask, i)) {
596                buff += sizeof(INT32);
597                continue;
598            }
599            val = valuators[i];
600            memcpy(buff, &val, sizeof(INT32));
601            buff += sizeof(INT32);
602        }
603    }
604
605    pDev->valuator->last_motion = (pDev->valuator->last_motion + 1) %
606        pDev->valuator->numMotionEvents;
607    /* If we're wrapping around, just keep the circular buffer going. */
608    if (pDev->valuator->first_motion == pDev->valuator->last_motion)
609        pDev->valuator->first_motion = (pDev->valuator->first_motion + 1) %
610            pDev->valuator->numMotionEvents;
611
612    return;
613}
614
615/**
616 * Returns the maximum number of events GetKeyboardEvents
617 * and GetPointerEvents will ever return.
618 *
619 * This MUST be absolutely constant, from init until exit.
620 */
621int
622GetMaximumEventsNum(void)
623{
624    /* One raw event
625     * One device event
626     * One possible device changed event
627     * Lots of possible separate button scroll events (horiz + vert)
628     * Lots of possible separate raw button scroll events (horiz + vert)
629     */
630    return 100;
631}
632
633/**
634 * Clip an axis to its bounds, which are declared in the call to
635 * InitValuatorAxisClassStruct.
636 */
637static void
638clipAxis(DeviceIntPtr pDev, int axisNum, double *val)
639{
640    AxisInfoPtr axis;
641
642    if (axisNum >= pDev->valuator->numAxes)
643        return;
644
645    axis = pDev->valuator->axes + axisNum;
646
647    /* If a value range is defined, clip. If not, do nothing */
648    if (axis->max_value <= axis->min_value)
649        return;
650
651    if (*val < axis->min_value)
652        *val = axis->min_value;
653    if (*val > axis->max_value)
654        *val = axis->max_value;
655}
656
657/**
658 * Clip every axis in the list of valuators to its bounds.
659 */
660static void
661clipValuators(DeviceIntPtr pDev, ValuatorMask *mask)
662{
663    int i;
664
665    for (i = 0; i < valuator_mask_size(mask); i++)
666        if (valuator_mask_isset(mask, i)) {
667            double val = valuator_mask_get_double(mask, i);
668
669            clipAxis(pDev, i, &val);
670            valuator_mask_set_double(mask, i, val);
671        }
672}
673
674/**
675 * Create the DCCE event (does not update the master's device state yet, this
676 * is done in the event processing).
677 * Pull in the coordinates from the MD if necessary.
678 *
679 * @param events Pointer to a pre-allocated event array.
680 * @param dev The slave device that generated an event.
681 * @param type Either DEVCHANGE_POINTER_EVENT and/or DEVCHANGE_KEYBOARD_EVENT
682 * @param num_events The current number of events, returns the number of
683 *        events if a DCCE was generated.
684 * @return The updated @events pointer.
685 */
686InternalEvent *
687UpdateFromMaster(InternalEvent *events, DeviceIntPtr dev, int type,
688                 int *num_events)
689{
690    DeviceIntPtr master;
691
692    master =
693        GetMaster(dev,
694                  (type & DEVCHANGE_POINTER_EVENT) ? MASTER_POINTER :
695                  MASTER_KEYBOARD);
696
697    if (master && master->last.slave != dev) {
698        CreateClassesChangedEvent(events, master, dev,
699                                  type | DEVCHANGE_SLAVE_SWITCH);
700        if (IsPointerDevice(master)) {
701            updateSlaveDeviceCoords(master, dev);
702            master->last.numValuators = dev->last.numValuators;
703        }
704        master->last.slave = dev;
705        (*num_events)++;
706        events++;
707    }
708    return events;
709}
710
711/**
712 * Move the device's pointer to the position given in the valuators.
713 *
714 * @param dev The device whose pointer is to be moved.
715 * @param mask Valuator data for this event.
716 */
717static void
718clipAbsolute(DeviceIntPtr dev, ValuatorMask *mask)
719{
720    int i;
721
722    for (i = 0; i < valuator_mask_size(mask); i++) {
723        double val;
724
725        if (!valuator_mask_isset(mask, i))
726            continue;
727        val = valuator_mask_get_double(mask, i);
728        clipAxis(dev, i, &val);
729        valuator_mask_set_double(mask, i, val);
730    }
731}
732
733static void
734add_to_scroll_valuator(DeviceIntPtr dev, ValuatorMask *mask, int valuator, double value)
735{
736    double v;
737
738    if (!valuator_mask_fetch_double(mask, valuator, &v))
739        return;
740
741    /* protect against scrolling overflow. INT_MAX for double, because
742     * we'll eventually write this as 32.32 fixed point */
743    if ((value > 0 && v > INT_MAX - value) || (value < 0 && v < INT_MIN - value)) {
744        v = 0;
745
746        /* reset last.scroll to avoid a button storm */
747        valuator_mask_set_double(dev->last.scroll, valuator, 0);
748    }
749    else
750        v += value;
751
752    valuator_mask_set_double(mask, valuator, v);
753}
754
755
756static void
757scale_for_device_resolution(DeviceIntPtr dev, ValuatorMask *mask)
758{
759    double y;
760    ValuatorClassPtr v = dev->valuator;
761    int xrange = v->axes[0].max_value - v->axes[0].min_value + 1;
762    int yrange = v->axes[1].max_value - v->axes[1].min_value + 1;
763
764    double screen_ratio = 1.0 * screenInfo.width/screenInfo.height;
765    double device_ratio = 1.0 * xrange/yrange;
766    double resolution_ratio = 1.0;
767    double ratio;
768
769    if (!valuator_mask_fetch_double(mask, 1, &y))
770        return;
771
772    if (v->axes[0].resolution != 0 && v->axes[1].resolution != 0)
773        resolution_ratio = 1.0 * v->axes[0].resolution/v->axes[1].resolution;
774
775    ratio = device_ratio/resolution_ratio/screen_ratio;
776    valuator_mask_set_double(mask, 1, y / ratio);
777}
778
779/**
780 * Move the device's pointer by the values given in @valuators.
781 *
782 * @param dev The device whose pointer is to be moved.
783 * @param[in,out] mask Valuator data for this event, modified in-place.
784 */
785static void
786moveRelative(DeviceIntPtr dev, int flags, ValuatorMask *mask)
787{
788    int i;
789    Bool clip_xy = IsMaster(dev) || !IsFloating(dev);
790    ValuatorClassPtr v = dev->valuator;
791
792    /* for abs devices in relative mode, we've just scaled wrong, since we
793       mapped the device's shape into the screen shape. Undo this. */
794    if ((flags & POINTER_ABSOLUTE) == 0 && v && v->numAxes > 1 &&
795        v->axes[0].min_value < v->axes[0].max_value &&
796        v->axes[1].min_value < v->axes[1].max_value) {
797        scale_for_device_resolution(dev, mask);
798    }
799
800    /* calc other axes, clip, drop back into valuators */
801    for (i = 0; i < valuator_mask_size(mask); i++) {
802        double val = dev->last.valuators[i];
803
804        if (!valuator_mask_isset(mask, i))
805            continue;
806
807        add_to_scroll_valuator(dev, mask, i, val);
808
809        /* x & y need to go over the limits to cross screens if the SD
810         * isn't currently attached; otherwise, clip to screen bounds. */
811        if (valuator_get_mode(dev, i) == Absolute &&
812            ((i != 0 && i != 1) || clip_xy)) {
813            val = valuator_mask_get_double(mask, i);
814            clipAxis(dev, i, &val);
815            valuator_mask_set_double(mask, i, val);
816        }
817    }
818}
819
820/**
821 * Accelerate the data in valuators based on the device's acceleration scheme.
822 *
823 * @param dev The device which's pointer is to be moved.
824 * @param valuators Valuator mask
825 * @param ms Current time.
826 */
827static void
828accelPointer(DeviceIntPtr dev, ValuatorMask *valuators, CARD32 ms)
829{
830    if (dev->valuator->accelScheme.AccelSchemeProc)
831        dev->valuator->accelScheme.AccelSchemeProc(dev, valuators, ms);
832}
833
834/**
835 * Scale from absolute screen coordinates to absolute coordinates in the
836 * device's coordinate range.
837 *
838 * @param dev The device to scale for.
839 * @param[in, out] mask The mask in desktop/screen coordinates, modified in place
840 * to contain device coordinate range.
841 * @param flags If POINTER_SCREEN is set, mask is in per-screen coordinates.
842 *              Otherwise, mask is in desktop coords.
843 */
844static void
845scale_from_screen(DeviceIntPtr dev, ValuatorMask *mask, int flags)
846{
847    double scaled;
848    ScreenPtr scr = miPointerGetScreen(dev);
849
850    if (valuator_mask_isset(mask, 0)) {
851        scaled = valuator_mask_get_double(mask, 0);
852        if (flags & POINTER_SCREEN)
853            scaled += scr->x;
854        scaled = rescaleValuatorAxis(scaled,
855                                     NULL, dev->valuator->axes + 0,
856                                     screenInfo.x, screenInfo.width);
857        valuator_mask_set_double(mask, 0, scaled);
858    }
859    if (valuator_mask_isset(mask, 1)) {
860        scaled = valuator_mask_get_double(mask, 1);
861        if (flags & POINTER_SCREEN)
862            scaled += scr->y;
863        scaled = rescaleValuatorAxis(scaled,
864                                     NULL, dev->valuator->axes + 1,
865                                     screenInfo.y, screenInfo.height);
866        valuator_mask_set_double(mask, 1, scaled);
867    }
868}
869
870/**
871 * Scale from (absolute) device to screen coordinates here,
872 *
873 * The coordinates provided are always absolute. see fill_pointer_events for
874 * information on coordinate systems.
875 *
876 * @param dev The device to be moved.
877 * @param mask Mask of axis values for this event
878 * @param[out] devx x desktop-wide coordinate in device coordinate system
879 * @param[out] devy y desktop-wide coordinate in device coordinate system
880 * @param[out] screenx x coordinate in desktop coordinate system
881 * @param[out] screeny y coordinate in desktop coordinate system
882 */
883static ScreenPtr
884scale_to_desktop(DeviceIntPtr dev, ValuatorMask *mask,
885                 double *devx, double *devy, double *screenx, double *screeny)
886{
887    ScreenPtr scr = miPointerGetScreen(dev);
888    double x, y;
889
890    BUG_WARN(dev->valuator && dev->valuator->numAxes < 2);
891    if (!dev->valuator || dev->valuator->numAxes < 2) {
892        /* if we have no axes, last.valuators must be in screen coords
893         * anyway */
894        *devx = *screenx = dev->last.valuators[0];
895        *devy = *screeny = dev->last.valuators[1];
896        return scr;
897    }
898
899    if (valuator_mask_isset(mask, 0))
900        x = valuator_mask_get_double(mask, 0);
901    else
902        x = dev->last.valuators[0];
903    if (valuator_mask_isset(mask, 1))
904        y = valuator_mask_get_double(mask, 1);
905    else
906        y = dev->last.valuators[1];
907
908    /* scale x&y to desktop coordinates */
909    *screenx = rescaleValuatorAxis(x, dev->valuator->axes + 0, NULL,
910                                   screenInfo.x, screenInfo.width);
911    *screeny = rescaleValuatorAxis(y, dev->valuator->axes + 1, NULL,
912                                   screenInfo.y, screenInfo.height);
913
914    *devx = x;
915    *devy = y;
916
917    return scr;
918}
919
920/**
921 * If we have HW cursors, this actually moves the visible sprite. If not, we
922 * just do all the screen crossing, etc.
923 *
924 * We use the screen coordinates here, call miPointerSetPosition() and then
925 * scale back into device coordinates (if needed). miPSP will change x/y if
926 * the screen was crossed.
927 *
928 * The coordinates provided are always absolute. The parameter mode
929 * specifies whether it was relative or absolute movement that landed us at
930 * those coordinates. see fill_pointer_events for information on coordinate
931 * systems.
932 *
933 * @param dev The device to be moved.
934 * @param mode Movement mode (Absolute or Relative)
935 * @param[out] mask Mask of axis values for this event, returns the
936 * per-screen device coordinates after confinement
937 * @param[in,out] devx x desktop-wide coordinate in device coordinate system
938 * @param[in,out] devy y desktop-wide coordinate in device coordinate system
939 * @param[in,out] screenx x coordinate in desktop coordinate system
940 * @param[in,out] screeny y coordinate in desktop coordinate system
941 * @param[out] nevents Number of barrier events added to events
942 * @param[in,out] events List of events barrier events are added to
943 */
944static ScreenPtr
945positionSprite(DeviceIntPtr dev, int mode, ValuatorMask *mask,
946               double *devx, double *devy, double *screenx, double *screeny,
947               int *nevents, InternalEvent* events)
948{
949    ScreenPtr scr = miPointerGetScreen(dev);
950    double tmpx, tmpy;
951
952    if (!dev->valuator || dev->valuator->numAxes < 2)
953        return scr;
954
955    tmpx = *screenx;
956    tmpy = *screeny;
957
958    /* miPointerSetPosition takes care of crossing screens for us, as well as
959     * clipping to the current screen. Coordinates returned are in desktop
960     * coord system */
961    scr = miPointerSetPosition(dev, mode, screenx, screeny, nevents, events);
962
963    /* If we were constrained, rescale x/y from the screen coordinates so
964     * the device valuators reflect the correct position. For screen
965     * crossing this doesn't matter much, the coords would be 0 or max.
966     */
967    if (tmpx != *screenx)
968        *devx = rescaleValuatorAxis(*screenx, NULL, dev->valuator->axes + 0,
969                                    screenInfo.x, screenInfo.width);
970
971    if (tmpy != *screeny)
972        *devy = rescaleValuatorAxis(*screeny, NULL, dev->valuator->axes + 1,
973                                    screenInfo.y, screenInfo.height);
974
975    /* Recalculate the per-screen device coordinates */
976    if (valuator_mask_isset(mask, 0)) {
977        double x;
978
979        x = rescaleValuatorAxis(*screenx - scr->x, NULL,
980                                dev->valuator->axes + 0, 0, scr->width);
981        valuator_mask_set_double(mask, 0, x);
982    }
983    if (valuator_mask_isset(mask, 1)) {
984        double y;
985
986        y = rescaleValuatorAxis(*screeny - scr->y, NULL,
987                                dev->valuator->axes + 1, 0, scr->height);
988        valuator_mask_set_double(mask, 1, y);
989    }
990
991    return scr;
992}
993
994/**
995 * Update the motion history for the device and (if appropriate) for its
996 * master device.
997 * @param dev Slave device to update.
998 * @param mask Bit mask of valid valuators to append to history.
999 * @param num Total number of valuators to append to history.
1000 * @param ms Current time
1001 */
1002static void
1003updateHistory(DeviceIntPtr dev, ValuatorMask *mask, CARD32 ms)
1004{
1005    if (!dev->valuator)
1006        return;
1007
1008    updateMotionHistory(dev, ms, mask, dev->last.valuators);
1009    if (!IsMaster(dev) && !IsFloating(dev)) {
1010        DeviceIntPtr master = GetMaster(dev, MASTER_POINTER);
1011
1012        updateMotionHistory(master, ms, mask, dev->last.valuators);
1013    }
1014}
1015
1016static void
1017queueEventList(DeviceIntPtr device, InternalEvent *events, int nevents)
1018{
1019    int i;
1020
1021    for (i = 0; i < nevents; i++)
1022        mieqEnqueue(device, &events[i]);
1023}
1024
1025static void
1026event_set_root_coordinates(DeviceEvent *event, double x, double y)
1027{
1028    event->root_x = trunc(x);
1029    event->root_y = trunc(y);
1030    event->root_x_frac = x - trunc(x);
1031    event->root_y_frac = y - trunc(y);
1032}
1033
1034/**
1035 * Generate internal events representing this keyboard event and enqueue
1036 * them on the event queue.
1037 *
1038 * This function is not reentrant. Disable signals before calling.
1039 *
1040 * @param device The device to generate the event for
1041 * @param type Event type, one of KeyPress or KeyRelease
1042 * @param keycode Key code of the pressed/released key
1043 *
1044 */
1045void
1046QueueKeyboardEvents(DeviceIntPtr device, int type,
1047                    int keycode)
1048{
1049    int nevents;
1050
1051    nevents = GetKeyboardEvents(InputEventList, device, type, keycode);
1052    queueEventList(device, InputEventList, nevents);
1053}
1054
1055/**
1056 * Returns a set of InternalEvents for KeyPress/KeyRelease, optionally
1057 * also with valuator events.
1058 *
1059 * The DDX is responsible for allocating the event list in the first
1060 * place via InitEventList(), and for freeing it.
1061 *
1062 * @return the number of events written into events.
1063 */
1064int
1065GetKeyboardEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
1066                  int key_code)
1067{
1068    int num_events = 0;
1069    CARD32 ms = 0;
1070    DeviceEvent *event;
1071    RawDeviceEvent *raw;
1072    enum DeviceEventSource source_type = EVENT_SOURCE_NORMAL;
1073
1074#ifdef XSERVER_DTRACE
1075    if (XSERVER_INPUT_EVENT_ENABLED()) {
1076        XSERVER_INPUT_EVENT(pDev->id, type, key_code, 0, 0,
1077                            NULL, NULL);
1078    }
1079#endif
1080
1081    if (type == EnterNotify) {
1082        source_type = EVENT_SOURCE_FOCUS;
1083        type = KeyPress;
1084    } else if (type == LeaveNotify) {
1085        source_type = EVENT_SOURCE_FOCUS;
1086        type = KeyRelease;
1087    }
1088
1089    /* refuse events from disabled devices */
1090    if (!pDev->enabled)
1091        return 0;
1092
1093    if (!events || !pDev->key || !pDev->focus || !pDev->kbdfeed ||
1094        (type != KeyPress && type != KeyRelease) ||
1095        (key_code < 8 || key_code > 255))
1096        return 0;
1097
1098    num_events = 1;
1099
1100    events =
1101        UpdateFromMaster(events, pDev, DEVCHANGE_KEYBOARD_EVENT, &num_events);
1102
1103    /* Handle core repeating, via press/release/press/release. */
1104    if (type == KeyPress && key_is_down(pDev, key_code, KEY_POSTED)) {
1105        /* If autorepeating is disabled either globally or just for that key,
1106         * or we have a modifier, don't generate a repeat event. */
1107        if (!pDev->kbdfeed->ctrl.autoRepeat ||
1108            !key_autorepeats(pDev, key_code) ||
1109            pDev->key->xkbInfo->desc->map->modmap[key_code])
1110            return 0;
1111    }
1112
1113    ms = GetTimeInMillis();
1114
1115    if (source_type == EVENT_SOURCE_NORMAL) {
1116        raw = &events->raw_event;
1117        init_raw(pDev, raw, ms, type, key_code);
1118        events++;
1119        num_events++;
1120    }
1121
1122    event = &events->device_event;
1123    init_device_event(event, pDev, ms, source_type);
1124    event->detail.key = key_code;
1125
1126    if (type == KeyPress) {
1127        event->type = ET_KeyPress;
1128        set_key_down(pDev, key_code, KEY_POSTED);
1129    }
1130    else if (type == KeyRelease) {
1131        event->type = ET_KeyRelease;
1132        set_key_up(pDev, key_code, KEY_POSTED);
1133    }
1134
1135    return num_events;
1136}
1137
1138/**
1139 * Initialize an event array large enough for num_events arrays.
1140 * This event list is to be passed into GetPointerEvents() and
1141 * GetKeyboardEvents().
1142 *
1143 * @param num_events Number of elements in list.
1144 */
1145InternalEvent *
1146InitEventList(int num_events)
1147{
1148    InternalEvent *events = calloc(num_events, sizeof(InternalEvent));
1149
1150    return events;
1151}
1152
1153/**
1154 * Free an event list.
1155 *
1156 * @param list The list to be freed.
1157 * @param num_events Number of elements in list.
1158 */
1159void
1160FreeEventList(InternalEvent *list, int num_events)
1161{
1162    free(list);
1163}
1164
1165/**
1166 * Transform vector x/y according to matrix m and drop the rounded coords
1167 * back into x/y.
1168 */
1169static void
1170transform(struct pixman_f_transform *m, double *x, double *y)
1171{
1172    struct pixman_f_vector p = {.v = {*x, *y, 1} };
1173    pixman_f_transform_point(m, &p);
1174
1175    *x = p.v[0];
1176    *y = p.v[1];
1177}
1178
1179static void
1180transformRelative(DeviceIntPtr dev, ValuatorMask *mask)
1181{
1182    double x = 0, y = 0;
1183
1184    valuator_mask_fetch_double(mask, 0, &x);
1185    valuator_mask_fetch_double(mask, 1, &y);
1186
1187    transform(&dev->relative_transform, &x, &y);
1188
1189    if (x)
1190        valuator_mask_set_double(mask, 0, x);
1191    else
1192        valuator_mask_unset(mask, 0);
1193
1194    if (y)
1195        valuator_mask_set_double(mask, 1, y);
1196    else
1197        valuator_mask_unset(mask, 1);
1198}
1199
1200/**
1201 * Apply the device's transformation matrix to the valuator mask and replace
1202 * the scaled values in mask. This transformation only applies to valuators
1203 * 0 and 1, others will be untouched.
1204 *
1205 * @param dev The device the valuators came from
1206 * @param[in,out] mask The valuator mask.
1207 */
1208static void
1209transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask)
1210{
1211    double x, y, ox = 0.0, oy = 0.0;
1212    int has_x, has_y;
1213
1214    has_x = valuator_mask_isset(mask, 0);
1215    has_y = valuator_mask_isset(mask, 1);
1216
1217    if (!has_x && !has_y)
1218        return;
1219
1220    if (!has_x || !has_y) {
1221        struct pixman_f_transform invert;
1222
1223        /* undo transformation from last event */
1224        ox = dev->last.valuators[0];
1225        oy = dev->last.valuators[1];
1226
1227        pixman_f_transform_invert(&invert, &dev->scale_and_transform);
1228        transform(&invert, &ox, &oy);
1229    }
1230
1231    if (has_x)
1232        ox = valuator_mask_get_double(mask, 0);
1233
1234    if (has_y)
1235        oy = valuator_mask_get_double(mask, 1);
1236
1237    x = ox;
1238    y = oy;
1239
1240    transform(&dev->scale_and_transform, &x, &y);
1241
1242    if (has_x || ox != x)
1243        valuator_mask_set_double(mask, 0, x);
1244
1245    if (has_y || oy != y)
1246        valuator_mask_set_double(mask, 1, y);
1247}
1248
1249static void
1250storeLastValuators(DeviceIntPtr dev, ValuatorMask *mask,
1251                   int xaxis, int yaxis, double devx, double devy)
1252{
1253    int i;
1254
1255    /* store desktop-wide in last.valuators */
1256    if (valuator_mask_isset(mask, xaxis))
1257        dev->last.valuators[0] = devx;
1258    if (valuator_mask_isset(mask, yaxis))
1259        dev->last.valuators[1] = devy;
1260
1261    for (i = 0; i < valuator_mask_size(mask); i++) {
1262        if (i == xaxis || i == yaxis)
1263            continue;
1264
1265        if (valuator_mask_isset(mask, i))
1266            dev->last.valuators[i] = valuator_mask_get_double(mask, i);
1267    }
1268
1269}
1270
1271/**
1272 * Generate internal events representing this pointer event and enqueue them
1273 * on the event queue.
1274 *
1275 * This function is not reentrant. Disable signals before calling.
1276 *
1277 * @param device The device to generate the event for
1278 * @param type Event type, one of ButtonPress, ButtonRelease, MotionNotify
1279 * @param buttons Button number of the buttons modified. Must be 0 for
1280 * MotionNotify
1281 * @param flags Event modification flags
1282 * @param mask Valuator mask for valuators present for this event.
1283 */
1284void
1285QueuePointerEvents(DeviceIntPtr device, int type,
1286                   int buttons, int flags, const ValuatorMask *mask)
1287{
1288    int nevents;
1289
1290    nevents =
1291        GetPointerEvents(InputEventList, device, type, buttons, flags, mask);
1292    queueEventList(device, InputEventList, nevents);
1293}
1294
1295/**
1296 * Helper function for GetPointerEvents, which only generates motion and
1297 * raw motion events for the slave device: does not update the master device.
1298 *
1299 * Should not be called by anyone other than GetPointerEvents.
1300 *
1301 * We use several different coordinate systems and need to switch between
1302 * the three in fill_pointer_events, positionSprite and
1303 * miPointerSetPosition. "desktop" refers to the width/height of all
1304 * screenInfo.screens[n]->width/height added up. "screen" is ScreenRec, not
1305 * output.
1306 *
1307 * Coordinate systems:
1308 * - relative events have a mask_in in relative coordinates, mapped to
1309 *   pixels. These events are mapped to the current position±delta.
1310 * - absolute events have a mask_in in absolute device coordinates in
1311 *   device-specific range. This range is mapped to the desktop.
1312 * - POINTER_SCREEN absolute events (x86WarpCursor) are in screen-relative
1313 *   screen coordinate range.
1314 * - rootx/rooty in events must be be relative to the current screen's
1315 *   origin (screen coordinate system)
1316 * - XI2 valuators must be relative to the current screen's origin. On
1317 *   the protocol the device min/max range maps to the current screen.
1318 *
1319 * For screen switching we need to get the desktop coordinates for each
1320 * event, then map that to the respective position on each screen and
1321 * position the cursor there.
1322 * The device's last.valuator[] stores the last position in desktop-wide
1323 * coordinates (in device range for slave devices, desktop range for master
1324 * devices).
1325 *
1326 * screen-relative device coordinates requires scaling: A device coordinate
1327 * x/y of range [n..m] that maps to positions Sx/Sy on Screen S must be
1328 * rescaled to match Sx/Sy for [n..m]. In the simplest example, x of (m/2-1)
1329 * is the last coordinate on the first screen and must be rescaled for the
1330 * event to be m. XI2 clients that do their own coordinate mapping would
1331 * otherwise interpret the position of the device elsewhere to the cursor.
1332 * However, this scaling leads to losses:
1333 * if we have two ScreenRecs we scale from e.g. [0..44704]  (Wacom I4) to
1334 * [0..2048[. that gives us 2047.954 as desktop coord, or the per-screen
1335 * coordinate 1023.954. Scaling that back into the device coordinate range
1336 * gives us 44703. So off by one device unit. It's a bug, but we'll have to
1337 * live with it because with all this scaling, we just cannot win.
1338 *
1339 * @return the number of events written into events.
1340 */
1341static int
1342fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
1343                    int buttons, CARD32 ms, int flags,
1344                    const ValuatorMask *mask_in)
1345{
1346    int num_events = 0;
1347    DeviceEvent *event;
1348    RawDeviceEvent *raw = NULL;
1349    double screenx = 0.0, screeny = 0.0;        /* desktop coordinate system */
1350    double devx = 0.0, devy = 0.0;      /* desktop-wide in device coords */
1351    int sx = 0, sy = 0;                 /* for POINTER_SCREEN */
1352    ValuatorMask mask;
1353    ScreenPtr scr;
1354    int num_barrier_events = 0;
1355
1356    switch (type) {
1357    case MotionNotify:
1358        if (!pDev->valuator) {
1359            ErrorF("[dix] motion events from device %d without valuators\n",
1360                   pDev->id);
1361            return 0;
1362        }
1363        if (!mask_in || valuator_mask_num_valuators(mask_in) <= 0)
1364            return 0;
1365        break;
1366    case ButtonPress:
1367    case ButtonRelease:
1368        if (!pDev->button || !buttons)
1369            return 0;
1370        if (mask_in && valuator_mask_size(mask_in) > 0 && !pDev->valuator) {
1371            ErrorF
1372                ("[dix] button event with valuator from device %d without valuators\n",
1373                 pDev->id);
1374            return 0;
1375        }
1376        break;
1377    default:
1378        return 0;
1379    }
1380
1381    valuator_mask_copy(&mask, mask_in);
1382
1383    if ((flags & POINTER_NORAW) == 0) {
1384        raw = &events->raw_event;
1385        events++;
1386        num_events++;
1387
1388        init_raw(pDev, raw, ms, type, buttons);
1389
1390        if (flags & POINTER_EMULATED)
1391            raw->flags = XIPointerEmulated;
1392
1393        set_raw_valuators(raw, &mask, TRUE, raw->valuators.data_raw);
1394    }
1395
1396    valuator_mask_drop_unaccelerated(&mask);
1397
1398    /* valuators are in driver-native format (rel or abs) */
1399
1400    if (flags & POINTER_ABSOLUTE) {
1401        if (flags & (POINTER_SCREEN | POINTER_DESKTOP)) {    /* valuators are in screen/desktop coords */
1402            sx = valuator_mask_get(&mask, 0);
1403            sy = valuator_mask_get(&mask, 1);
1404            scale_from_screen(pDev, &mask, flags);
1405        }
1406
1407        transformAbsolute(pDev, &mask);
1408        clipAbsolute(pDev, &mask);
1409        if ((flags & POINTER_NORAW) == 0 && raw)
1410            set_raw_valuators(raw, &mask, FALSE, raw->valuators.data);
1411    }
1412    else {
1413        transformRelative(pDev, &mask);
1414
1415        if (flags & POINTER_ACCELERATE)
1416            accelPointer(pDev, &mask, ms);
1417        if ((flags & POINTER_NORAW) == 0 && raw)
1418            set_raw_valuators(raw, &mask, FALSE, raw->valuators.data);
1419
1420        moveRelative(pDev, flags, &mask);
1421    }
1422
1423    /* valuators are in device coordinate system in absolute coordinates */
1424    scale_to_desktop(pDev, &mask, &devx, &devy, &screenx, &screeny);
1425
1426    /* #53037 XWarpPointer's scaling back and forth between screen and
1427       device may leave us with rounding errors. End result is that the
1428       pointer doesn't end up on the pixel it should.
1429       Avoid this by forcing screenx/screeny back to what the input
1430       coordinates were.
1431     */
1432    if (flags & POINTER_SCREEN) {
1433        scr = miPointerGetScreen(pDev);
1434        screenx = sx + scr->x;
1435        screeny = sy + scr->y;
1436    }
1437
1438    scr = positionSprite(pDev, (flags & POINTER_ABSOLUTE) ? Absolute : Relative,
1439                         &mask, &devx, &devy, &screenx, &screeny,
1440                         &num_barrier_events, events);
1441    num_events += num_barrier_events;
1442    events += num_barrier_events;
1443
1444    /* screenx, screeny are in desktop coordinates,
1445       mask is in device coordinates per-screen (the event data)
1446       devx/devy is in device coordinate desktop-wide */
1447    updateHistory(pDev, &mask, ms);
1448
1449    clipValuators(pDev, &mask);
1450
1451    storeLastValuators(pDev, &mask, 0, 1, devx, devy);
1452
1453    /* Update the MD's coordinates, which are always in desktop space. */
1454    if (!IsMaster(pDev) && !IsFloating(pDev)) {
1455        DeviceIntPtr master = GetMaster(pDev, MASTER_POINTER);
1456
1457        master->last.valuators[0] = screenx;
1458        master->last.valuators[1] = screeny;
1459    }
1460
1461    if ((flags & POINTER_RAWONLY) == 0) {
1462        num_events++;
1463
1464        event = &events->device_event;
1465        init_device_event(event, pDev, ms, EVENT_SOURCE_NORMAL);
1466
1467        if (type == MotionNotify) {
1468            event->type = ET_Motion;
1469            event->detail.button = 0;
1470        }
1471        else {
1472            if (type == ButtonPress) {
1473                event->type = ET_ButtonPress;
1474                set_button_down(pDev, buttons, BUTTON_POSTED);
1475            }
1476            else if (type == ButtonRelease) {
1477                event->type = ET_ButtonRelease;
1478                set_button_up(pDev, buttons, BUTTON_POSTED);
1479            }
1480            event->detail.button = buttons;
1481        }
1482
1483        /* root_x and root_y must be in per-screen coordinates */
1484        event_set_root_coordinates(event, screenx - scr->x, screeny - scr->y);
1485
1486        if (flags & POINTER_EMULATED)
1487            event->flags = XIPointerEmulated;
1488
1489        set_valuators(pDev, event, &mask);
1490    }
1491
1492    return num_events;
1493}
1494
1495/**
1496 * Generate events for each scroll axis that changed between before/after
1497 * for the device.
1498 *
1499 * @param events The pointer to the event list to fill the events
1500 * @param dev The device to generate the events for
1501 * @param type The real type of the event
1502 * @param axis The axis number to generate events for
1503 * @param mask State before this event in absolute coords
1504 * @param[in,out] last Last scroll state posted in absolute coords (modified
1505 * in-place)
1506 * @param ms Current time in ms
1507 * @param max_events Max number of events to be generated
1508 * @return The number of events generated
1509 */
1510static int
1511emulate_scroll_button_events(InternalEvent *events,
1512                             DeviceIntPtr dev,
1513                             int type,
1514                             int axis,
1515                             const ValuatorMask *mask,
1516                             ValuatorMask *last, CARD32 ms, int max_events)
1517{
1518    AxisInfoPtr ax;
1519    double delta;
1520    double incr;
1521    int num_events = 0;
1522    double total;
1523    int b;
1524    int flags = 0;
1525
1526    if (dev->valuator->axes[axis].scroll.type == SCROLL_TYPE_NONE)
1527        return 0;
1528
1529    if (!valuator_mask_isset(mask, axis))
1530        return 0;
1531
1532    ax = &dev->valuator->axes[axis];
1533    incr = ax->scroll.increment;
1534
1535    BUG_WARN_MSG(incr == 0, "for device %s\n", dev->name);
1536    if (incr == 0)
1537        return 0;
1538
1539    if (type != ButtonPress && type != ButtonRelease)
1540        flags |= POINTER_EMULATED;
1541
1542    if (!valuator_mask_isset(last, axis))
1543        valuator_mask_set_double(last, axis, 0);
1544
1545    delta =
1546        valuator_mask_get_double(mask, axis) - valuator_mask_get_double(last,
1547                                                                        axis);
1548    total = delta;
1549    b = (ax->scroll.type == SCROLL_TYPE_VERTICAL) ? 5 : 7;
1550
1551    if ((incr > 0 && delta < 0) || (incr < 0 && delta > 0))
1552        b--;                    /* we're scrolling up or left → button 4 or 6 */
1553
1554    while (fabs(delta) >= fabs(incr)) {
1555        int nev_tmp;
1556
1557        if (delta > 0)
1558            delta -= fabs(incr);
1559        else if (delta < 0)
1560            delta += fabs(incr);
1561
1562        /* fill_pointer_events() generates four events: one normal and one raw
1563         * event for button press and button release.
1564         * We may get a bigger scroll delta than we can generate events
1565         * for. In that case, we keep decreasing delta, but skip events.
1566         */
1567        if (num_events + 4 < max_events) {
1568            if (type != ButtonRelease) {
1569                nev_tmp = fill_pointer_events(events, dev, ButtonPress, b, ms,
1570                                              flags, NULL);
1571                events += nev_tmp;
1572                num_events += nev_tmp;
1573            }
1574            if (type != ButtonPress) {
1575                nev_tmp = fill_pointer_events(events, dev, ButtonRelease, b, ms,
1576                                              flags, NULL);
1577                events += nev_tmp;
1578                num_events += nev_tmp;
1579            }
1580        }
1581    }
1582
1583    /* We emulated, update last.scroll */
1584    if (total != delta) {
1585        total -= delta;
1586        valuator_mask_set_double(last, axis,
1587                                 valuator_mask_get_double(last, axis) + total);
1588    }
1589
1590    return num_events;
1591}
1592
1593
1594/**
1595 * Generate a complete series of InternalEvents (filled into the EventList)
1596 * representing pointer motion, or button presses.  If the device is a slave
1597 * device, also potentially generate a DeviceClassesChangedEvent to update
1598 * the master device.
1599 *
1600 * events is not NULL-terminated; the return value is the number of events.
1601 * The DDX is responsible for allocating the event structure in the first
1602 * place via InitEventList() and GetMaximumEventsNum(), and for freeing it.
1603 *
1604 * In the generated events rootX/Y will be in absolute screen coords and
1605 * the valuator information in the absolute or relative device coords.
1606 *
1607 * last.valuators[x] of the device is always in absolute device coords.
1608 * last.valuators[x] of the master device is in absolute screen coords.
1609 *
1610 * master->last.valuators[x] for x > 2 is undefined.
1611 */
1612int
1613GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
1614                 int buttons, int flags, const ValuatorMask *mask_in)
1615{
1616    CARD32 ms = GetTimeInMillis();
1617    int num_events = 0, nev_tmp;
1618    ValuatorMask mask;
1619    ValuatorMask scroll;
1620    int i;
1621    int realtype = type;
1622
1623#ifdef XSERVER_DTRACE
1624    if (XSERVER_INPUT_EVENT_ENABLED()) {
1625        XSERVER_INPUT_EVENT(pDev->id, type, buttons, flags,
1626                            mask_in ? mask_in->last_bit + 1 : 0,
1627                            mask_in ? mask_in->mask : NULL,
1628                            mask_in ? mask_in->valuators : NULL);
1629    }
1630#endif
1631
1632    BUG_RETURN_VAL(buttons >= MAX_BUTTONS, 0);
1633
1634    /* refuse events from disabled devices */
1635    if (!pDev->enabled)
1636        return 0;
1637
1638    if (!miPointerGetScreen(pDev))
1639        return 0;
1640
1641    events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT,
1642                              &num_events);
1643
1644    valuator_mask_copy(&mask, mask_in);
1645
1646    /* Turn a scroll button press into a smooth-scrolling event if
1647     * necessary. This only needs to cater for the XIScrollFlagPreferred
1648     * axis (if more than one scrolling axis is present) */
1649    if (type == ButtonPress) {
1650        double adj;
1651        int axis;
1652        int h_scroll_axis = -1;
1653        int v_scroll_axis = -1;
1654
1655        if (pDev->valuator) {
1656            h_scroll_axis = pDev->valuator->h_scroll_axis;
1657            v_scroll_axis = pDev->valuator->v_scroll_axis;
1658        }
1659
1660        /* Up is negative on valuators, down positive */
1661        switch (buttons) {
1662        case 4:
1663            adj = -1.0;
1664            axis = v_scroll_axis;
1665            break;
1666        case 5:
1667            adj = 1.0;
1668            axis = v_scroll_axis;
1669            break;
1670        case 6:
1671            adj = -1.0;
1672            axis = h_scroll_axis;
1673            break;
1674        case 7:
1675            adj = 1.0;
1676            axis = h_scroll_axis;
1677            break;
1678        default:
1679            adj = 0.0;
1680            axis = -1;
1681            break;
1682        }
1683
1684        if (adj != 0.0 && axis != -1) {
1685            adj *= pDev->valuator->axes[axis].scroll.increment;
1686            if (!valuator_mask_isset(&mask, axis))
1687                valuator_mask_set(&mask, axis, 0);
1688            add_to_scroll_valuator(pDev, &mask, axis, adj);
1689            type = MotionNotify;
1690            buttons = 0;
1691            flags |= POINTER_EMULATED;
1692        }
1693    }
1694
1695    /* First fill out the original event set, with smooth-scrolling axes. */
1696    nev_tmp = fill_pointer_events(events, pDev, type, buttons, ms, flags,
1697                                  &mask);
1698    events += nev_tmp;
1699    num_events += nev_tmp;
1700
1701    valuator_mask_zero(&scroll);
1702
1703    /* Now turn the smooth-scrolling axes back into emulated button presses
1704     * for legacy clients, based on the integer delta between before and now */
1705    for (i = 0; i < valuator_mask_size(&mask); i++) {
1706        if ( !pDev->valuator || (i >= pDev->valuator->numAxes))
1707            break;
1708
1709        if (!valuator_mask_isset(&mask, i))
1710            continue;
1711
1712        valuator_mask_set_double(&scroll, i, pDev->last.valuators[i]);
1713
1714        nev_tmp =
1715            emulate_scroll_button_events(events, pDev, realtype, i, &scroll,
1716                                         pDev->last.scroll, ms,
1717                                         GetMaximumEventsNum() - num_events);
1718        events += nev_tmp;
1719        num_events += nev_tmp;
1720    }
1721
1722    return num_events;
1723}
1724
1725/**
1726 * Generate internal events representing this proximity event and enqueue
1727 * them on the event queue.
1728 *
1729 * This function is not reentrant. Disable signals before calling.
1730 *
1731 * @param device The device to generate the event for
1732 * @param type Event type, one of ProximityIn or ProximityOut
1733 * @param keycode Key code of the pressed/released key
1734 * @param mask Valuator mask for valuators present for this event.
1735 *
1736 */
1737void
1738QueueProximityEvents(DeviceIntPtr device, int type, const ValuatorMask *mask)
1739{
1740    int nevents;
1741
1742    nevents = GetProximityEvents(InputEventList, device, type, mask);
1743    queueEventList(device, InputEventList, nevents);
1744}
1745
1746/**
1747 * Generate ProximityIn/ProximityOut InternalEvents, accompanied by
1748 * valuators.
1749 *
1750 * The DDX is responsible for allocating the events in the first place via
1751 * InitEventList(), and for freeing it.
1752 *
1753 * @return the number of events written into events.
1754 */
1755int
1756GetProximityEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
1757                   const ValuatorMask *mask_in)
1758{
1759    int num_events = 1, i;
1760    DeviceEvent *event;
1761    ValuatorMask mask;
1762
1763#ifdef XSERVER_DTRACE
1764    if (XSERVER_INPUT_EVENT_ENABLED()) {
1765        XSERVER_INPUT_EVENT(pDev->id, type, 0, 0,
1766                            mask_in ? mask_in->last_bit + 1 : 0,
1767                            mask_in ? mask_in->mask : NULL,
1768                            mask_in ? mask_in->valuators : NULL);
1769    }
1770#endif
1771
1772    /* refuse events from disabled devices */
1773    if (!pDev->enabled)
1774        return 0;
1775
1776    /* Sanity checks. */
1777    if ((type != ProximityIn && type != ProximityOut) || !mask_in)
1778        return 0;
1779    if (!pDev->valuator || !pDev->proximity)
1780        return 0;
1781
1782    valuator_mask_copy(&mask, mask_in);
1783
1784    /* ignore relative axes for proximity. */
1785    for (i = 0; i < valuator_mask_size(&mask); i++) {
1786        if (valuator_mask_isset(&mask, i) &&
1787            valuator_get_mode(pDev, i) == Relative)
1788            valuator_mask_unset(&mask, i);
1789    }
1790
1791    /* FIXME: posting proximity events with relative valuators only results
1792     * in an empty event, EventToXI() will fail to convert → no event sent
1793     * to client. */
1794
1795    events =
1796        UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
1797
1798    event = &events->device_event;
1799    init_device_event(event, pDev, GetTimeInMillis(), EVENT_SOURCE_NORMAL);
1800    event->type = (type == ProximityIn) ? ET_ProximityIn : ET_ProximityOut;
1801
1802    clipValuators(pDev, &mask);
1803
1804    set_valuators(pDev, event, &mask);
1805
1806    return num_events;
1807}
1808
1809int
1810GetTouchOwnershipEvents(InternalEvent *events, DeviceIntPtr pDev,
1811                        TouchPointInfoPtr ti, uint8_t reason, XID resource,
1812                        uint32_t flags)
1813{
1814    TouchClassPtr t = pDev->touch;
1815    TouchOwnershipEvent *event;
1816    CARD32 ms = GetTimeInMillis();
1817
1818    if (!pDev->enabled || !t || !ti)
1819        return 0;
1820
1821    event = &events->touch_ownership_event;
1822    init_touch_ownership(pDev, event, ms);
1823
1824    event->touchid = ti->client_id;
1825    event->sourceid = ti->sourceid;
1826    event->resource = resource;
1827    event->flags = flags;
1828    event->reason = reason;
1829
1830    return 1;
1831}
1832
1833/**
1834 * Generate internal events representing this touch event and enqueue them
1835 * on the event queue.
1836 *
1837 * This function is not reentrant. Disable signals before calling.
1838 *
1839 * @param device The device to generate the event for
1840 * @param type Event type, one of XI_TouchBegin, XI_TouchUpdate, XI_TouchEnd
1841 * @param touchid Touch point ID
1842 * @param flags Event modification flags
1843 * @param mask Valuator mask for valuators present for this event.
1844 */
1845void
1846QueueTouchEvents(DeviceIntPtr device, int type,
1847                 uint32_t ddx_touchid, int flags, const ValuatorMask *mask)
1848{
1849    int nevents;
1850
1851    nevents =
1852        GetTouchEvents(InputEventList, device, ddx_touchid, type, flags, mask);
1853    queueEventList(device, InputEventList, nevents);
1854}
1855
1856/**
1857 * Get events for a touch. Generates a TouchBegin event if end is not set and
1858 * the touch id is not active. Generates a TouchUpdate event if end is not set
1859 * and the touch id is active. Generates a TouchEnd event if end is set and the
1860 * touch id is active.
1861 *
1862 * events is not NULL-terminated; the return value is the number of events.
1863 * The DDX is responsible for allocating the event structure in the first
1864 * place via GetMaximumEventsNum(), and for freeing it.
1865 *
1866 * @param[out] events The list of events generated
1867 * @param dev The device to generate the events for
1868 * @param ddx_touchid The touch ID as assigned by the DDX
1869 * @param type XI_TouchBegin, XI_TouchUpdate or XI_TouchEnd
1870 * @param flags Event flags
1871 * @param mask_in Valuator information for this event
1872 */
1873int
1874GetTouchEvents(InternalEvent *events, DeviceIntPtr dev, uint32_t ddx_touchid,
1875               uint16_t type, uint32_t flags, const ValuatorMask *mask_in)
1876{
1877    ScreenPtr scr;
1878    TouchClassPtr t = dev->touch;
1879    ValuatorClassPtr v = dev->valuator;
1880    DeviceEvent *event;
1881    CARD32 ms = GetTimeInMillis();
1882    ValuatorMask mask;
1883    double screenx = 0.0, screeny = 0.0;        /* desktop coordinate system */
1884    double devx = 0.0, devy = 0.0;      /* desktop-wide in device coords */
1885    int i;
1886    int num_events = 0;
1887    RawDeviceEvent *raw;
1888    DDXTouchPointInfoPtr ti;
1889    int need_rawevent = TRUE;
1890    Bool emulate_pointer = FALSE;
1891    int client_id = 0;
1892
1893#ifdef XSERVER_DTRACE
1894    if (XSERVER_INPUT_EVENT_ENABLED()) {
1895        XSERVER_INPUT_EVENT(dev->id, type, ddx_touchid, flags,
1896                            mask_in ? mask_in->last_bit + 1 : 0,
1897                            mask_in ? mask_in->mask : NULL,
1898                            mask_in ? mask_in->valuators : NULL);
1899    }
1900#endif
1901
1902    if (!dev->enabled || !t || !v)
1903        return 0;
1904
1905    /* Find and/or create the DDX touch info */
1906
1907    ti = TouchFindByDDXID(dev, ddx_touchid, (type == XI_TouchBegin));
1908    if (!ti) {
1909        ErrorFSigSafe("[dix] %s: unable to %s touch point %u\n", dev->name,
1910                      type == XI_TouchBegin ? "begin" : "find", ddx_touchid);
1911        return 0;
1912    }
1913    client_id = ti->client_id;
1914
1915    emulate_pointer = ti->emulate_pointer;
1916
1917    if (!IsMaster(dev))
1918        events =
1919            UpdateFromMaster(events, dev, DEVCHANGE_POINTER_EVENT, &num_events);
1920
1921    valuator_mask_copy(&mask, mask_in);
1922
1923    if (need_rawevent) {
1924        raw = &events->raw_event;
1925        events++;
1926        num_events++;
1927        init_raw(dev, raw, ms, type, client_id);
1928        set_raw_valuators(raw, &mask, TRUE, raw->valuators.data_raw);
1929    }
1930
1931    event = &events->device_event;
1932    num_events++;
1933
1934    init_device_event(event, dev, ms, EVENT_SOURCE_NORMAL);
1935
1936    switch (type) {
1937    case XI_TouchBegin:
1938        event->type = ET_TouchBegin;
1939        /* If we're starting a touch, we must have x & y coordinates. */
1940        if (!mask_in ||
1941            !valuator_mask_isset(mask_in, 0) ||
1942            !valuator_mask_isset(mask_in, 1)) {
1943            ErrorFSigSafe("%s: Attempted to start touch without x/y "
1944                          "(driver bug)\n", dev->name);
1945            return 0;
1946        }
1947        break;
1948    case XI_TouchUpdate:
1949        event->type = ET_TouchUpdate;
1950        if (!mask_in || valuator_mask_num_valuators(mask_in) <= 0) {
1951            ErrorFSigSafe("%s: TouchUpdate with no valuators? Driver bug\n",
1952                          dev->name);
1953        }
1954        break;
1955    case XI_TouchEnd:
1956        event->type = ET_TouchEnd;
1957        /* We can end the DDX touch here, since we don't use the active
1958         * field below */
1959        TouchEndDDXTouch(dev, ti);
1960        break;
1961    default:
1962        return 0;
1963    }
1964
1965    /* Get our screen event coordinates (root_x/root_y/event_x/event_y):
1966     * these come from the touchpoint in Absolute mode, or the sprite in
1967     * Relative. */
1968    if (t->mode == XIDirectTouch) {
1969        for (i = 0; i < max(valuator_mask_size(&mask), 2); i++) {
1970            double val;
1971
1972            if (valuator_mask_fetch_double(&mask, i, &val))
1973                valuator_mask_set_double(ti->valuators, i, val);
1974            /* If the device doesn't post new X and Y axis values,
1975             * use the last values posted.
1976             */
1977            else if (i < 2 &&
1978                valuator_mask_fetch_double(ti->valuators, i, &val))
1979                valuator_mask_set_double(&mask, i, val);
1980        }
1981
1982        transformAbsolute(dev, &mask);
1983        clipAbsolute(dev, &mask);
1984    }
1985    else {
1986        screenx = dev->spriteInfo->sprite->hotPhys.x;
1987        screeny = dev->spriteInfo->sprite->hotPhys.y;
1988    }
1989    if (need_rawevent)
1990        set_raw_valuators(raw, &mask, FALSE, raw->valuators.data);
1991
1992    scr = dev->spriteInfo->sprite->hotPhys.pScreen;
1993
1994    /* Indirect device touch coordinates are not used for cursor positioning.
1995     * They are merely informational, and are provided in device coordinates.
1996     * The device sprite is used for positioning instead, and it is already
1997     * scaled. */
1998    if (t->mode == XIDirectTouch)
1999        scr = scale_to_desktop(dev, &mask, &devx, &devy, &screenx, &screeny);
2000    if (emulate_pointer)
2001        scr = positionSprite(dev, Absolute, &mask,
2002                             &devx, &devy, &screenx, &screeny, NULL, NULL);
2003
2004    /* see fill_pointer_events for coordinate systems */
2005    if (emulate_pointer)
2006        updateHistory(dev, &mask, ms);
2007
2008    clipValuators(dev, &mask);
2009
2010    if (emulate_pointer)
2011        storeLastValuators(dev, &mask, 0, 1, devx, devy);
2012
2013    /* Update the MD's coordinates, which are always in desktop space. */
2014    if (emulate_pointer && !IsMaster(dev) && !IsFloating(dev)) {
2015	    DeviceIntPtr master = GetMaster(dev, MASTER_POINTER);
2016
2017	    master->last.valuators[0] = screenx;
2018	    master->last.valuators[1] = screeny;
2019    }
2020
2021    event->root = scr->root->drawable.id;
2022
2023    event_set_root_coordinates(event, screenx - scr->x, screeny - scr->y);
2024    event->touchid = client_id;
2025    event->flags = flags;
2026
2027    if (emulate_pointer) {
2028        event->flags |= TOUCH_POINTER_EMULATED;
2029        event->detail.button = 1;
2030    }
2031
2032    set_valuators(dev, event, &mask);
2033    for (i = 0; i < v->numAxes; i++) {
2034        if (valuator_mask_isset(&mask, i))
2035            v->axisVal[i] = valuator_mask_get(&mask, i);
2036    }
2037
2038    return num_events;
2039}
2040
2041void
2042GetDixTouchEnd(InternalEvent *ievent, DeviceIntPtr dev, TouchPointInfoPtr ti,
2043               uint32_t flags)
2044{
2045    ScreenPtr scr = dev->spriteInfo->sprite->hotPhys.pScreen;
2046    DeviceEvent *event = &ievent->device_event;
2047    CARD32 ms = GetTimeInMillis();
2048
2049    BUG_WARN(!dev->enabled);
2050
2051    init_device_event(event, dev, ms, EVENT_SOURCE_NORMAL);
2052
2053    event->sourceid = ti->sourceid;
2054    event->type = ET_TouchEnd;
2055
2056    event->root = scr->root->drawable.id;
2057
2058    /* Get screen event coordinates from the sprite.  Is this really the best
2059     * we can do? */
2060    event_set_root_coordinates(event,
2061                               dev->last.valuators[0] - scr->x,
2062                               dev->last.valuators[1] - scr->y);
2063    event->touchid = ti->client_id;
2064    event->flags = flags;
2065
2066    if (flags & TOUCH_POINTER_EMULATED) {
2067        event->flags |= TOUCH_POINTER_EMULATED;
2068        event->detail.button = 1;
2069    }
2070}
2071
2072/**
2073 * Synthesize a single motion event for the core pointer.
2074 *
2075 * Used in cursor functions, e.g. when cursor confinement changes, and we need
2076 * to shift the pointer to get it inside the new bounds.
2077 */
2078void
2079PostSyntheticMotion(DeviceIntPtr pDev,
2080                    int x, int y, int screen, unsigned long time)
2081{
2082    DeviceEvent ev;
2083
2084#ifdef PANORAMIX
2085    /* Translate back to the sprite screen since processInputProc
2086       will translate from sprite screen to screen 0 upon reentry
2087       to the DIX layer. */
2088    if (!noPanoramiXExtension) {
2089        x += screenInfo.screens[0]->x - screenInfo.screens[screen]->x;
2090        y += screenInfo.screens[0]->y - screenInfo.screens[screen]->y;
2091    }
2092#endif
2093
2094    memset(&ev, 0, sizeof(DeviceEvent));
2095    init_device_event(&ev, pDev, time, EVENT_SOURCE_NORMAL);
2096    ev.root_x = x;
2097    ev.root_y = y;
2098    ev.type = ET_Motion;
2099    ev.time = time;
2100
2101    /* FIXME: MD/SD considerations? */
2102    (*pDev->public.processInputProc) ((InternalEvent *) &ev, pDev);
2103}
2104
2105void
2106InitGestureEvent(InternalEvent *ievent, DeviceIntPtr dev, CARD32 ms,
2107                 int type, uint16_t num_touches, uint32_t flags,
2108                 double delta_x, double delta_y,
2109                 double delta_unaccel_x, double delta_unaccel_y,
2110                 double scale, double delta_angle)
2111{
2112    ScreenPtr scr = dev->spriteInfo->sprite->hotPhys.pScreen;
2113    GestureEvent *event = &ievent->gesture_event;
2114    double screenx = 0.0, screeny = 0.0;        /* desktop coordinate system */
2115
2116    init_gesture_event(event, dev, ms);
2117
2118    screenx = dev->spriteInfo->sprite->hotPhys.x;
2119    screeny = dev->spriteInfo->sprite->hotPhys.y;
2120
2121    event->type = type;
2122    event->root = scr->root->drawable.id;
2123    event->root_x = screenx - scr->x;
2124    event->root_y = screeny - scr->y;
2125    event->num_touches = num_touches;
2126    event->flags = flags;
2127
2128    event->delta_x = delta_x;
2129    event->delta_y = delta_y;
2130    event->delta_unaccel_x = delta_unaccel_x;
2131    event->delta_unaccel_y = delta_unaccel_y;
2132    event->scale = scale;
2133    event->delta_angle = delta_angle;
2134}
2135
2136/**
2137 * Get events for a pinch or swipe gesture.
2138 *
2139 * events is not NULL-terminated; the return value is the number of events.
2140 * The DDX is responsible for allocating the event structure in the first
2141 * place via GetMaximumEventsNum(), and for freeing it.
2142 *
2143 * @param[out] events The list of events generated
2144 * @param dev The device to generate the events for
2145 * @param type XI_Gesture{Pinch,Swipe}{Begin,Update,End}
2146 * @prama num_touches The number of touches in the gesture
2147 * @param flags Event flags
2148 * @param delta_x,delta_y accelerated relative motion delta
2149 * @param delta_unaccel_x,delta_unaccel_y unaccelerated relative motion delta
2150 * @param scale (valid only to pinch events) absolute scale of a pinch gesture
2151 * @param delta_angle (valid only to pinch events) the ange delta in degrees between the last and
2152 *        the current pinch event.
2153 */
2154int
2155GetGestureEvents(InternalEvent *events, DeviceIntPtr dev,
2156                 uint16_t type, uint16_t num_touches, uint32_t flags,
2157                 double delta_x, double delta_y,
2158                 double delta_unaccel_x, double delta_unaccel_y,
2159                 double scale, double delta_angle)
2160
2161{
2162    GestureClassPtr g = dev->gesture;
2163    CARD32 ms = GetTimeInMillis();
2164    enum EventType evtype;
2165    int num_events = 0;
2166    uint32_t evflags = 0;
2167
2168    if (!dev->enabled || !g)
2169        return 0;
2170
2171    if (!IsMaster(dev))
2172        events = UpdateFromMaster(events, dev, DEVCHANGE_POINTER_EVENT,
2173                                  &num_events);
2174
2175    switch (type) {
2176    case XI_GesturePinchBegin:
2177        evtype = ET_GesturePinchBegin;
2178        break;
2179    case XI_GesturePinchUpdate:
2180        evtype = ET_GesturePinchUpdate;
2181        break;
2182    case XI_GesturePinchEnd:
2183        evtype = ET_GesturePinchEnd;
2184        if (flags & XIGesturePinchEventCancelled)
2185            evflags |= GESTURE_CANCELLED;
2186        break;
2187    case XI_GestureSwipeBegin:
2188        evtype = ET_GestureSwipeBegin;
2189        break;
2190    case XI_GestureSwipeUpdate:
2191        evtype = ET_GestureSwipeUpdate;
2192        break;
2193    case XI_GestureSwipeEnd:
2194        evtype = ET_GestureSwipeEnd;
2195        if (flags & XIGestureSwipeEventCancelled)
2196            evflags |= GESTURE_CANCELLED;
2197        break;
2198    default:
2199        return 0;
2200    }
2201
2202    InitGestureEvent(events, dev, ms, evtype, num_touches, evflags,
2203                     delta_x, delta_y, delta_unaccel_x, delta_unaccel_y,
2204                     scale, delta_angle);
2205    num_events++;
2206
2207    return num_events;
2208}
2209
2210void
2211QueueGesturePinchEvents(DeviceIntPtr dev, uint16_t type,
2212                        uint16_t num_touches, uint32_t flags,
2213                        double delta_x, double delta_y,
2214                        double delta_unaccel_x,
2215                        double delta_unaccel_y,
2216                        double scale, double delta_angle)
2217{
2218    int nevents;
2219    nevents = GetGestureEvents(InputEventList, dev, type, num_touches, flags,
2220                               delta_x, delta_y,
2221                               delta_unaccel_x, delta_unaccel_y,
2222                               scale, delta_angle);
2223    queueEventList(dev, InputEventList, nevents);
2224}
2225
2226void
2227QueueGestureSwipeEvents(DeviceIntPtr dev, uint16_t type,
2228                        uint16_t num_touches, uint32_t flags,
2229                        double delta_x, double delta_y,
2230                        double delta_unaccel_x,
2231                        double delta_unaccel_y)
2232{
2233    int nevents;
2234    nevents = GetGestureEvents(InputEventList, dev, type, num_touches, flags,
2235                               delta_x, delta_y,
2236                               delta_unaccel_x, delta_unaccel_y,
2237                               0.0, 0.0);
2238    queueEventList(dev, InputEventList, nevents);
2239}
2240