xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

getevents.c (71438B)


      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  */
     81 InternalEvent *InputEventList = NULL;
     82 
     83 /**
     84  * Pick some arbitrary size for Xi motion history.
     85  */
     86 int
     87 GetMotionHistorySize(void)
     88 {
     89     return MOTION_HISTORY_SIZE;
     90 }
     91 
     92 void
     93 set_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 
    101 void
    102 set_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 
    110 Bool
    111 button_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 
    123 void
    124 set_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 
    132 void
    133 set_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 
    141 Bool
    142 key_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 
    154 static Bool
    155 key_autorepeats(DeviceIntPtr pDev, int key_code)
    156 {
    157     return ! !(pDev->kbdfeed->ctrl.autoRepeats[key_code >> 3] &
    158                (1 << (key_code & 7)));
    159 }
    160 
    161 static void
    162 init_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 
    172 static void
    173 init_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 
    210 static void
    211 set_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 
    234 static void
    235 set_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 
    253 void
    254 CreateClassesChangedEvent(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  */
    298 static double
    299 rescaleValuatorAxis(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  */
    331 static void
    332 updateSlaveDeviceCoords(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  */
    364 void
    365 AllocateMotionHistory(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  */
    408 int
    409 GetMotionHistory(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  */
    542 static void
    543 updateMotionHistory(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  */
    621 int
    622 GetMaximumEventsNum(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  */
    637 static void
    638 clipAxis(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  */
    660 static void
    661 clipValuators(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  */
    686 InternalEvent *
    687 UpdateFromMaster(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  */
    717 static void
    718 clipAbsolute(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 
    733 static void
    734 add_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 
    756 static void
    757 scale_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  */
    785 static void
    786 moveRelative(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  */
    827 static void
    828 accelPointer(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  */
    844 static void
    845 scale_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  */
    883 static ScreenPtr
    884 scale_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  */
    944 static ScreenPtr
    945 positionSprite(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  */
   1002 static void
   1003 updateHistory(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 
   1016 static void
   1017 queueEventList(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 
   1025 static void
   1026 event_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  */
   1045 void
   1046 QueueKeyboardEvents(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  */
   1064 int
   1065 GetKeyboardEvents(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  */
   1145 InternalEvent *
   1146 InitEventList(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  */
   1159 void
   1160 FreeEventList(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  */
   1169 static void
   1170 transform(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 
   1179 static void
   1180 transformRelative(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  */
   1208 static void
   1209 transformAbsolute(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 
   1249 static void
   1250 storeLastValuators(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  */
   1284 void
   1285 QueuePointerEvents(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  */
   1341 static int
   1342 fill_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  */
   1510 static int
   1511 emulate_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  */
   1612 int
   1613 GetPointerEvents(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  */
   1737 void
   1738 QueueProximityEvents(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  */
   1755 int
   1756 GetProximityEvents(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 
   1809 int
   1810 GetTouchOwnershipEvents(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  */
   1845 void
   1846 QueueTouchEvents(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  */
   1873 int
   1874 GetTouchEvents(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 
   2041 void
   2042 GetDixTouchEnd(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  */
   2078 void
   2079 PostSyntheticMotion(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 
   2105 void
   2106 InitGestureEvent(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  */
   2154 int
   2155 GetGestureEvents(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 
   2210 void
   2211 QueueGesturePinchEvents(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 
   2226 void
   2227 QueueGestureSwipeEvents(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 }