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
GetMotionHistorySize(void)87 GetMotionHistorySize(void)
88 {
89     return MOTION_HISTORY_SIZE;
90 }
91 
92 void
set_button_down(DeviceIntPtr pDev,int button,int type)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
set_button_up(DeviceIntPtr pDev,int button,int type)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
button_is_down(DeviceIntPtr pDev,int button,int type)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
set_key_down(DeviceIntPtr pDev,int key_code,int type)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
set_key_up(DeviceIntPtr pDev,int key_code,int type)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
key_is_down(DeviceIntPtr pDev,int key_code,int type)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
key_autorepeats(DeviceIntPtr pDev,int key_code)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
init_touch_ownership(DeviceIntPtr dev,TouchOwnershipEvent * event,Time ms)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
init_raw(DeviceIntPtr dev,RawDeviceEvent * event,Time ms,int type,int detail)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
set_raw_valuators(RawDeviceEvent * event,ValuatorMask * mask,BOOL use_unaccel,double * data)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
set_valuators(DeviceIntPtr dev,DeviceEvent * event,ValuatorMask * mask)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
CreateClassesChangedEvent(InternalEvent * event,DeviceIntPtr master,DeviceIntPtr slave,int flags)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
rescaleValuatorAxis(double coord,AxisInfoPtr from,AxisInfoPtr to,double defmin,double defmax)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
updateSlaveDeviceCoords(DeviceIntPtr master,DeviceIntPtr pDev)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
AllocateMotionHistory(DeviceIntPtr pDev)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
GetMotionHistory(DeviceIntPtr pDev,xTimecoord ** buff,unsigned long start,unsigned long stop,ScreenPtr pScreen,BOOL core)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
updateMotionHistory(DeviceIntPtr pDev,CARD32 ms,ValuatorMask * mask,double * valuators)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
GetMaximumEventsNum(void)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
clipAxis(DeviceIntPtr pDev,int axisNum,double * val)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
clipValuators(DeviceIntPtr pDev,ValuatorMask * mask)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 *
UpdateFromMaster(InternalEvent * events,DeviceIntPtr dev,int type,int * num_events)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
clipAbsolute(DeviceIntPtr dev,ValuatorMask * mask)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
add_to_scroll_valuator(DeviceIntPtr dev,ValuatorMask * mask,int valuator,double value)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
scale_for_device_resolution(DeviceIntPtr dev,ValuatorMask * mask)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
moveRelative(DeviceIntPtr dev,int flags,ValuatorMask * mask)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
accelPointer(DeviceIntPtr dev,ValuatorMask * valuators,CARD32 ms)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
scale_from_screen(DeviceIntPtr dev,ValuatorMask * mask,int flags)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
scale_to_desktop(DeviceIntPtr dev,ValuatorMask * mask,double * devx,double * devy,double * screenx,double * screeny)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
positionSprite(DeviceIntPtr dev,int mode,ValuatorMask * mask,double * devx,double * devy,double * screenx,double * screeny,int * nevents,InternalEvent * events)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
updateHistory(DeviceIntPtr dev,ValuatorMask * mask,CARD32 ms)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
queueEventList(DeviceIntPtr device,InternalEvent * events,int nevents)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
event_set_root_coordinates(DeviceEvent * event,double x,double y)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
QueueKeyboardEvents(DeviceIntPtr device,int type,int keycode)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
GetKeyboardEvents(InternalEvent * events,DeviceIntPtr pDev,int type,int key_code)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 #if 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 *
InitEventList(int num_events)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
FreeEventList(InternalEvent * list,int num_events)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
transform(struct pixman_f_transform * m,double * x,double * y)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
transformRelative(DeviceIntPtr dev,ValuatorMask * mask)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
transformAbsolute(DeviceIntPtr dev,ValuatorMask * mask)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
storeLastValuators(DeviceIntPtr dev,ValuatorMask * mask,int xaxis,int yaxis,double devx,double devy)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
QueuePointerEvents(DeviceIntPtr device,int type,int buttons,int flags,const ValuatorMask * mask)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 elsewere 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
fill_pointer_events(InternalEvent * events,DeviceIntPtr pDev,int type,int buttons,CARD32 ms,int flags,const ValuatorMask * mask_in)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 = 1;
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         set_raw_valuators(raw, &mask, TRUE, raw->valuators.data_raw);
1390     }
1391 
1392     valuator_mask_drop_unaccelerated(&mask);
1393 
1394     /* valuators are in driver-native format (rel or abs) */
1395 
1396     if (flags & POINTER_ABSOLUTE) {
1397         if (flags & (POINTER_SCREEN | POINTER_DESKTOP)) {    /* valuators are in screen/desktop coords */
1398             sx = valuator_mask_get(&mask, 0);
1399             sy = valuator_mask_get(&mask, 1);
1400             scale_from_screen(pDev, &mask, flags);
1401         }
1402 
1403         transformAbsolute(pDev, &mask);
1404         clipAbsolute(pDev, &mask);
1405         if ((flags & POINTER_NORAW) == 0 && raw)
1406             set_raw_valuators(raw, &mask, FALSE, raw->valuators.data);
1407     }
1408     else {
1409         transformRelative(pDev, &mask);
1410 
1411         if (flags & POINTER_ACCELERATE)
1412             accelPointer(pDev, &mask, ms);
1413         if ((flags & POINTER_NORAW) == 0 && raw)
1414             set_raw_valuators(raw, &mask, FALSE, raw->valuators.data);
1415 
1416         moveRelative(pDev, flags, &mask);
1417     }
1418 
1419     /* valuators are in device coordinate system in absolute coordinates */
1420     scale_to_desktop(pDev, &mask, &devx, &devy, &screenx, &screeny);
1421 
1422     /* #53037 XWarpPointer's scaling back and forth between screen and
1423        device may leave us with rounding errors. End result is that the
1424        pointer doesn't end up on the pixel it should.
1425        Avoid this by forcing screenx/screeny back to what the input
1426        coordinates were.
1427      */
1428     if (flags & POINTER_SCREEN) {
1429         scr = miPointerGetScreen(pDev);
1430         screenx = sx + scr->x;
1431         screeny = sy + scr->y;
1432     }
1433 
1434     scr = positionSprite(pDev, (flags & POINTER_ABSOLUTE) ? Absolute : Relative,
1435                          &mask, &devx, &devy, &screenx, &screeny,
1436                          &num_barrier_events, events);
1437     num_events += num_barrier_events;
1438     events += num_barrier_events;
1439 
1440     /* screenx, screeny are in desktop coordinates,
1441        mask is in device coordinates per-screen (the event data)
1442        devx/devy is in device coordinate desktop-wide */
1443     updateHistory(pDev, &mask, ms);
1444 
1445     clipValuators(pDev, &mask);
1446 
1447     storeLastValuators(pDev, &mask, 0, 1, devx, devy);
1448 
1449     /* Update the MD's co-ordinates, which are always in desktop space. */
1450     if (!IsMaster(pDev) && !IsFloating(pDev)) {
1451         DeviceIntPtr master = GetMaster(pDev, MASTER_POINTER);
1452 
1453         master->last.valuators[0] = screenx;
1454         master->last.valuators[1] = screeny;
1455     }
1456 
1457     event = &events->device_event;
1458     init_device_event(event, pDev, ms, EVENT_SOURCE_NORMAL);
1459 
1460     if (type == MotionNotify) {
1461         event->type = ET_Motion;
1462         event->detail.button = 0;
1463     }
1464     else {
1465         if (type == ButtonPress) {
1466             event->type = ET_ButtonPress;
1467             set_button_down(pDev, buttons, BUTTON_POSTED);
1468         }
1469         else if (type == ButtonRelease) {
1470             event->type = ET_ButtonRelease;
1471             set_button_up(pDev, buttons, BUTTON_POSTED);
1472         }
1473         event->detail.button = buttons;
1474     }
1475 
1476     /* root_x and root_y must be in per-screen co-ordinates */
1477     event_set_root_coordinates(event, screenx - scr->x, screeny - scr->y);
1478 
1479     if (flags & POINTER_EMULATED) {
1480         if (raw)
1481             raw->flags = XIPointerEmulated;
1482         event->flags = XIPointerEmulated;
1483     }
1484 
1485     set_valuators(pDev, event, &mask);
1486 
1487     return num_events;
1488 }
1489 
1490 /**
1491  * Generate events for each scroll axis that changed between before/after
1492  * for the device.
1493  *
1494  * @param events The pointer to the event list to fill the events
1495  * @param dev The device to generate the events for
1496  * @param type The real type of the event
1497  * @param axis The axis number to generate events for
1498  * @param mask State before this event in absolute coords
1499  * @param[in,out] last Last scroll state posted in absolute coords (modified
1500  * in-place)
1501  * @param ms Current time in ms
1502  * @param max_events Max number of events to be generated
1503  * @return The number of events generated
1504  */
1505 static int
emulate_scroll_button_events(InternalEvent * events,DeviceIntPtr dev,int type,int axis,const ValuatorMask * mask,ValuatorMask * last,CARD32 ms,int max_events)1506 emulate_scroll_button_events(InternalEvent *events,
1507                              DeviceIntPtr dev,
1508                              int type,
1509                              int axis,
1510                              const ValuatorMask *mask,
1511                              ValuatorMask *last, CARD32 ms, int max_events)
1512 {
1513     AxisInfoPtr ax;
1514     double delta;
1515     double incr;
1516     int num_events = 0;
1517     double total;
1518     int b;
1519     int flags = 0;
1520 
1521     if (dev->valuator->axes[axis].scroll.type == SCROLL_TYPE_NONE)
1522         return 0;
1523 
1524     if (!valuator_mask_isset(mask, axis))
1525         return 0;
1526 
1527     ax = &dev->valuator->axes[axis];
1528     incr = ax->scroll.increment;
1529 
1530     BUG_WARN_MSG(incr == 0, "for device %s\n", dev->name);
1531     if (incr == 0)
1532         return 0;
1533 
1534     if (type != ButtonPress && type != ButtonRelease)
1535         flags |= POINTER_EMULATED;
1536 
1537     if (!valuator_mask_isset(last, axis))
1538         valuator_mask_set_double(last, axis, 0);
1539 
1540     delta =
1541         valuator_mask_get_double(mask, axis) - valuator_mask_get_double(last,
1542                                                                         axis);
1543     total = delta;
1544     b = (ax->scroll.type == SCROLL_TYPE_VERTICAL) ? 5 : 7;
1545 
1546     if ((incr > 0 && delta < 0) || (incr < 0 && delta > 0))
1547         b--;                    /* we're scrolling up or left → button 4 or 6 */
1548 
1549     while (fabs(delta) >= fabs(incr)) {
1550         int nev_tmp;
1551 
1552         if (delta > 0)
1553             delta -= fabs(incr);
1554         else if (delta < 0)
1555             delta += fabs(incr);
1556 
1557         /* fill_pointer_events() generates four events: one normal and one raw
1558          * event for button press and button release.
1559          * We may get a bigger scroll delta than we can generate events
1560          * for. In that case, we keep decreasing delta, but skip events.
1561          */
1562         if (num_events + 4 < max_events) {
1563             if (type != ButtonRelease) {
1564                 nev_tmp = fill_pointer_events(events, dev, ButtonPress, b, ms,
1565                                               flags, NULL);
1566                 events += nev_tmp;
1567                 num_events += nev_tmp;
1568             }
1569             if (type != ButtonPress) {
1570                 nev_tmp = fill_pointer_events(events, dev, ButtonRelease, b, ms,
1571                                               flags, NULL);
1572                 events += nev_tmp;
1573                 num_events += nev_tmp;
1574             }
1575         }
1576     }
1577 
1578     /* We emulated, update last.scroll */
1579     if (total != delta) {
1580         total -= delta;
1581         valuator_mask_set_double(last, axis,
1582                                  valuator_mask_get_double(last, axis) + total);
1583     }
1584 
1585     return num_events;
1586 }
1587 
1588 
1589 /**
1590  * Generate a complete series of InternalEvents (filled into the EventList)
1591  * representing pointer motion, or button presses.  If the device is a slave
1592  * device, also potentially generate a DeviceClassesChangedEvent to update
1593  * the master device.
1594  *
1595  * events is not NULL-terminated; the return value is the number of events.
1596  * The DDX is responsible for allocating the event structure in the first
1597  * place via InitEventList() and GetMaximumEventsNum(), and for freeing it.
1598  *
1599  * In the generated events rootX/Y will be in absolute screen coords and
1600  * the valuator information in the absolute or relative device coords.
1601  *
1602  * last.valuators[x] of the device is always in absolute device coords.
1603  * last.valuators[x] of the master device is in absolute screen coords.
1604  *
1605  * master->last.valuators[x] for x > 2 is undefined.
1606  */
1607 int
GetPointerEvents(InternalEvent * events,DeviceIntPtr pDev,int type,int buttons,int flags,const ValuatorMask * mask_in)1608 GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
1609                  int buttons, int flags, const ValuatorMask *mask_in)
1610 {
1611     CARD32 ms = GetTimeInMillis();
1612     int num_events = 0, nev_tmp;
1613     ValuatorMask mask;
1614     ValuatorMask scroll;
1615     int i;
1616     int realtype = type;
1617 
1618 #if XSERVER_DTRACE
1619     if (XSERVER_INPUT_EVENT_ENABLED()) {
1620         XSERVER_INPUT_EVENT(pDev->id, type, buttons, flags,
1621                             mask_in ? mask_in->last_bit + 1 : 0,
1622                             mask_in ? mask_in->mask : NULL,
1623                             mask_in ? mask_in->valuators : NULL);
1624     }
1625 #endif
1626 
1627     BUG_RETURN_VAL(buttons >= MAX_BUTTONS, 0);
1628 
1629     /* refuse events from disabled devices */
1630     if (!pDev->enabled)
1631         return 0;
1632 
1633     if (!miPointerGetScreen(pDev))
1634         return 0;
1635 
1636     events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT,
1637                               &num_events);
1638 
1639     valuator_mask_copy(&mask, mask_in);
1640 
1641     /* Turn a scroll button press into a smooth-scrolling event if
1642      * necessary. This only needs to cater for the XIScrollFlagPreferred
1643      * axis (if more than one scrolling axis is present) */
1644     if (type == ButtonPress) {
1645         double adj;
1646         int axis;
1647         int h_scroll_axis = -1;
1648         int v_scroll_axis = -1;
1649 
1650         if (pDev->valuator) {
1651             h_scroll_axis = pDev->valuator->h_scroll_axis;
1652             v_scroll_axis = pDev->valuator->v_scroll_axis;
1653         }
1654 
1655         /* Up is negative on valuators, down positive */
1656         switch (buttons) {
1657         case 4:
1658             adj = -1.0;
1659             axis = v_scroll_axis;
1660             break;
1661         case 5:
1662             adj = 1.0;
1663             axis = v_scroll_axis;
1664             break;
1665         case 6:
1666             adj = -1.0;
1667             axis = h_scroll_axis;
1668             break;
1669         case 7:
1670             adj = 1.0;
1671             axis = h_scroll_axis;
1672             break;
1673         default:
1674             adj = 0.0;
1675             axis = -1;
1676             break;
1677         }
1678 
1679         if (adj != 0.0 && axis != -1) {
1680             adj *= pDev->valuator->axes[axis].scroll.increment;
1681             if (!valuator_mask_isset(&mask, axis))
1682                 valuator_mask_set(&mask, axis, 0);
1683             add_to_scroll_valuator(pDev, &mask, axis, adj);
1684             type = MotionNotify;
1685             buttons = 0;
1686             flags |= POINTER_EMULATED;
1687         }
1688     }
1689 
1690     /* First fill out the original event set, with smooth-scrolling axes. */
1691     nev_tmp = fill_pointer_events(events, pDev, type, buttons, ms, flags,
1692                                   &mask);
1693     events += nev_tmp;
1694     num_events += nev_tmp;
1695 
1696     valuator_mask_zero(&scroll);
1697 
1698     /* Now turn the smooth-scrolling axes back into emulated button presses
1699      * for legacy clients, based on the integer delta between before and now */
1700     for (i = 0; i < valuator_mask_size(&mask); i++) {
1701         if ( !pDev->valuator || (i >= pDev->valuator->numAxes))
1702             break;
1703 
1704         if (!valuator_mask_isset(&mask, i))
1705             continue;
1706 
1707         valuator_mask_set_double(&scroll, i, pDev->last.valuators[i]);
1708 
1709         nev_tmp =
1710             emulate_scroll_button_events(events, pDev, realtype, i, &scroll,
1711                                          pDev->last.scroll, ms,
1712                                          GetMaximumEventsNum() - num_events);
1713         events += nev_tmp;
1714         num_events += nev_tmp;
1715     }
1716 
1717     return num_events;
1718 }
1719 
1720 /**
1721  * Generate internal events representing this proximity event and enqueue
1722  * them on the event queue.
1723  *
1724  * This function is not reentrant. Disable signals before calling.
1725  *
1726  * @param device The device to generate the event for
1727  * @param type Event type, one of ProximityIn or ProximityOut
1728  * @param keycode Key code of the pressed/released key
1729  * @param mask Valuator mask for valuators present for this event.
1730  *
1731  */
1732 void
QueueProximityEvents(DeviceIntPtr device,int type,const ValuatorMask * mask)1733 QueueProximityEvents(DeviceIntPtr device, int type, const ValuatorMask *mask)
1734 {
1735     int nevents;
1736 
1737     nevents = GetProximityEvents(InputEventList, device, type, mask);
1738     queueEventList(device, InputEventList, nevents);
1739 }
1740 
1741 /**
1742  * Generate ProximityIn/ProximityOut InternalEvents, accompanied by
1743  * valuators.
1744  *
1745  * The DDX is responsible for allocating the events in the first place via
1746  * InitEventList(), and for freeing it.
1747  *
1748  * @return the number of events written into events.
1749  */
1750 int
GetProximityEvents(InternalEvent * events,DeviceIntPtr pDev,int type,const ValuatorMask * mask_in)1751 GetProximityEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
1752                    const ValuatorMask *mask_in)
1753 {
1754     int num_events = 1, i;
1755     DeviceEvent *event;
1756     ValuatorMask mask;
1757 
1758 #if XSERVER_DTRACE
1759     if (XSERVER_INPUT_EVENT_ENABLED()) {
1760         XSERVER_INPUT_EVENT(pDev->id, type, 0, 0,
1761                             mask_in ? mask_in->last_bit + 1 : 0,
1762                             mask_in ? mask_in->mask : NULL,
1763                             mask_in ? mask_in->valuators : NULL);
1764     }
1765 #endif
1766 
1767     /* refuse events from disabled devices */
1768     if (!pDev->enabled)
1769         return 0;
1770 
1771     /* Sanity checks. */
1772     if ((type != ProximityIn && type != ProximityOut) || !mask_in)
1773         return 0;
1774     if (!pDev->valuator || !pDev->proximity)
1775         return 0;
1776 
1777     valuator_mask_copy(&mask, mask_in);
1778 
1779     /* ignore relative axes for proximity. */
1780     for (i = 0; i < valuator_mask_size(&mask); i++) {
1781         if (valuator_mask_isset(&mask, i) &&
1782             valuator_get_mode(pDev, i) == Relative)
1783             valuator_mask_unset(&mask, i);
1784     }
1785 
1786     /* FIXME: posting proximity events with relative valuators only results
1787      * in an empty event, EventToXI() will fail to convert → no event sent
1788      * to client. */
1789 
1790     events =
1791         UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
1792 
1793     event = &events->device_event;
1794     init_device_event(event, pDev, GetTimeInMillis(), EVENT_SOURCE_NORMAL);
1795     event->type = (type == ProximityIn) ? ET_ProximityIn : ET_ProximityOut;
1796 
1797     clipValuators(pDev, &mask);
1798 
1799     set_valuators(pDev, event, &mask);
1800 
1801     return num_events;
1802 }
1803 
1804 int
GetTouchOwnershipEvents(InternalEvent * events,DeviceIntPtr pDev,TouchPointInfoPtr ti,uint8_t reason,XID resource,uint32_t flags)1805 GetTouchOwnershipEvents(InternalEvent *events, DeviceIntPtr pDev,
1806                         TouchPointInfoPtr ti, uint8_t reason, XID resource,
1807                         uint32_t flags)
1808 {
1809     TouchClassPtr t = pDev->touch;
1810     TouchOwnershipEvent *event;
1811     CARD32 ms = GetTimeInMillis();
1812 
1813     if (!pDev->enabled || !t || !ti)
1814         return 0;
1815 
1816     event = &events->touch_ownership_event;
1817     init_touch_ownership(pDev, event, ms);
1818 
1819     event->touchid = ti->client_id;
1820     event->sourceid = ti->sourceid;
1821     event->resource = resource;
1822     event->flags = flags;
1823     event->reason = reason;
1824 
1825     return 1;
1826 }
1827 
1828 /**
1829  * Generate internal events representing this touch event and enqueue them
1830  * on the event queue.
1831  *
1832  * This function is not reentrant. Disable signals before calling.
1833  *
1834  * @param device The device to generate the event for
1835  * @param type Event type, one of XI_TouchBegin, XI_TouchUpdate, XI_TouchEnd
1836  * @param touchid Touch point ID
1837  * @param flags Event modification flags
1838  * @param mask Valuator mask for valuators present for this event.
1839  */
1840 void
QueueTouchEvents(DeviceIntPtr device,int type,uint32_t ddx_touchid,int flags,const ValuatorMask * mask)1841 QueueTouchEvents(DeviceIntPtr device, int type,
1842                  uint32_t ddx_touchid, int flags, const ValuatorMask *mask)
1843 {
1844     int nevents;
1845 
1846     nevents =
1847         GetTouchEvents(InputEventList, device, ddx_touchid, type, flags, mask);
1848     queueEventList(device, InputEventList, nevents);
1849 }
1850 
1851 /**
1852  * Get events for a touch. Generates a TouchBegin event if end is not set and
1853  * the touch id is not active. Generates a TouchUpdate event if end is not set
1854  * and the touch id is active. Generates a TouchEnd event if end is set and the
1855  * touch id is active.
1856  *
1857  * events is not NULL-terminated; the return value is the number of events.
1858  * The DDX is responsible for allocating the event structure in the first
1859  * place via GetMaximumEventsNum(), and for freeing it.
1860  *
1861  * @param[out] events The list of events generated
1862  * @param dev The device to generate the events for
1863  * @param ddx_touchid The touch ID as assigned by the DDX
1864  * @param type XI_TouchBegin, XI_TouchUpdate or XI_TouchEnd
1865  * @param flags Event flags
1866  * @param mask_in Valuator information for this event
1867  */
1868 int
GetTouchEvents(InternalEvent * events,DeviceIntPtr dev,uint32_t ddx_touchid,uint16_t type,uint32_t flags,const ValuatorMask * mask_in)1869 GetTouchEvents(InternalEvent *events, DeviceIntPtr dev, uint32_t ddx_touchid,
1870                uint16_t type, uint32_t flags, const ValuatorMask *mask_in)
1871 {
1872     ScreenPtr scr = dev->spriteInfo->sprite->hotPhys.pScreen;
1873     TouchClassPtr t = dev->touch;
1874     ValuatorClassPtr v = dev->valuator;
1875     DeviceEvent *event;
1876     CARD32 ms = GetTimeInMillis();
1877     ValuatorMask mask;
1878     double screenx = 0.0, screeny = 0.0;        /* desktop coordinate system */
1879     double devx = 0.0, devy = 0.0;      /* desktop-wide in device coords */
1880     int i;
1881     int num_events = 0;
1882     RawDeviceEvent *raw;
1883     DDXTouchPointInfoPtr ti;
1884     int need_rawevent = TRUE;
1885     Bool emulate_pointer = FALSE;
1886     int client_id = 0;
1887 
1888 #if XSERVER_DTRACE
1889     if (XSERVER_INPUT_EVENT_ENABLED()) {
1890         XSERVER_INPUT_EVENT(dev->id, type, ddx_touchid, flags,
1891                             mask_in ? mask_in->last_bit + 1 : 0,
1892                             mask_in ? mask_in->mask : NULL,
1893                             mask_in ? mask_in->valuators : NULL);
1894     }
1895 #endif
1896 
1897     if (!dev->enabled || !t || !v)
1898         return 0;
1899 
1900     /* Find and/or create the DDX touch info */
1901 
1902     ti = TouchFindByDDXID(dev, ddx_touchid, (type == XI_TouchBegin));
1903     if (!ti) {
1904         ErrorFSigSafe("[dix] %s: unable to %s touch point %u\n", dev->name,
1905                       type == XI_TouchBegin ? "begin" : "find", ddx_touchid);
1906         return 0;
1907     }
1908     client_id = ti->client_id;
1909 
1910     emulate_pointer = ti->emulate_pointer;
1911 
1912     if (!IsMaster(dev))
1913         events =
1914             UpdateFromMaster(events, dev, DEVCHANGE_POINTER_EVENT, &num_events);
1915 
1916     valuator_mask_copy(&mask, mask_in);
1917 
1918     if (need_rawevent) {
1919         raw = &events->raw_event;
1920         events++;
1921         num_events++;
1922         init_raw(dev, raw, ms, type, client_id);
1923         set_raw_valuators(raw, &mask, TRUE, raw->valuators.data_raw);
1924     }
1925 
1926     event = &events->device_event;
1927     num_events++;
1928 
1929     init_device_event(event, dev, ms, EVENT_SOURCE_NORMAL);
1930 
1931     switch (type) {
1932     case XI_TouchBegin:
1933         event->type = ET_TouchBegin;
1934         /* If we're starting a touch, we must have x & y co-ordinates. */
1935         if (!mask_in ||
1936             !valuator_mask_isset(mask_in, 0) ||
1937             !valuator_mask_isset(mask_in, 1)) {
1938             ErrorFSigSafe("%s: Attempted to start touch without x/y "
1939                           "(driver bug)\n", dev->name);
1940             return 0;
1941         }
1942         break;
1943     case XI_TouchUpdate:
1944         event->type = ET_TouchUpdate;
1945         if (!mask_in || valuator_mask_num_valuators(mask_in) <= 0) {
1946             ErrorFSigSafe("%s: TouchUpdate with no valuators? Driver bug\n",
1947                           dev->name);
1948         }
1949         break;
1950     case XI_TouchEnd:
1951         event->type = ET_TouchEnd;
1952         /* We can end the DDX touch here, since we don't use the active
1953          * field below */
1954         TouchEndDDXTouch(dev, ti);
1955         break;
1956     default:
1957         return 0;
1958     }
1959 
1960     /* Get our screen event co-ordinates (root_x/root_y/event_x/event_y):
1961      * these come from the touchpoint in Absolute mode, or the sprite in
1962      * Relative. */
1963     if (t->mode == XIDirectTouch) {
1964         for (i = 0; i < max(valuator_mask_size(&mask), 2); i++) {
1965             double val;
1966 
1967             if (valuator_mask_fetch_double(&mask, i, &val))
1968                 valuator_mask_set_double(ti->valuators, i, val);
1969             /* If the device doesn't post new X and Y axis values,
1970              * use the last values posted.
1971              */
1972             else if (i < 2 &&
1973                 valuator_mask_fetch_double(ti->valuators, i, &val))
1974                 valuator_mask_set_double(&mask, i, val);
1975         }
1976 
1977         transformAbsolute(dev, &mask);
1978         clipAbsolute(dev, &mask);
1979     }
1980     else {
1981         screenx = dev->spriteInfo->sprite->hotPhys.x;
1982         screeny = dev->spriteInfo->sprite->hotPhys.y;
1983     }
1984     if (need_rawevent)
1985         set_raw_valuators(raw, &mask, FALSE, raw->valuators.data);
1986 
1987     /* Indirect device touch coordinates are not used for cursor positioning.
1988      * They are merely informational, and are provided in device coordinates.
1989      * The device sprite is used for positioning instead, and it is already
1990      * scaled. */
1991     if (t->mode == XIDirectTouch)
1992         scr = scale_to_desktop(dev, &mask, &devx, &devy, &screenx, &screeny);
1993     if (emulate_pointer)
1994         scr = positionSprite(dev, Absolute, &mask,
1995                              &devx, &devy, &screenx, &screeny, NULL, NULL);
1996 
1997     /* see fill_pointer_events for coordinate systems */
1998     if (emulate_pointer)
1999         updateHistory(dev, &mask, ms);
2000 
2001     clipValuators(dev, &mask);
2002 
2003     if (emulate_pointer)
2004         storeLastValuators(dev, &mask, 0, 1, devx, devy);
2005 
2006     /* Update the MD's co-ordinates, which are always in desktop space. */
2007     if (emulate_pointer && !IsMaster(dev) && !IsFloating(dev)) {
2008 	    DeviceIntPtr master = GetMaster(dev, MASTER_POINTER);
2009 
2010 	    master->last.valuators[0] = screenx;
2011 	    master->last.valuators[1] = screeny;
2012     }
2013 
2014     event->root = scr->root->drawable.id;
2015 
2016     event_set_root_coordinates(event, screenx - scr->x, screeny - scr->y);
2017     event->touchid = client_id;
2018     event->flags = flags;
2019 
2020     if (emulate_pointer) {
2021         event->flags |= TOUCH_POINTER_EMULATED;
2022         event->detail.button = 1;
2023     }
2024 
2025     set_valuators(dev, event, &mask);
2026     for (i = 0; i < v->numAxes; i++) {
2027         if (valuator_mask_isset(&mask, i))
2028             v->axisVal[i] = valuator_mask_get(&mask, i);
2029     }
2030 
2031     return num_events;
2032 }
2033 
2034 void
GetDixTouchEnd(InternalEvent * ievent,DeviceIntPtr dev,TouchPointInfoPtr ti,uint32_t flags)2035 GetDixTouchEnd(InternalEvent *ievent, DeviceIntPtr dev, TouchPointInfoPtr ti,
2036                uint32_t flags)
2037 {
2038     ScreenPtr scr = dev->spriteInfo->sprite->hotPhys.pScreen;
2039     DeviceEvent *event = &ievent->device_event;
2040     CARD32 ms = GetTimeInMillis();
2041 
2042     BUG_WARN(!dev->enabled);
2043 
2044     init_device_event(event, dev, ms, EVENT_SOURCE_NORMAL);
2045 
2046     event->sourceid = ti->sourceid;
2047     event->type = ET_TouchEnd;
2048 
2049     event->root = scr->root->drawable.id;
2050 
2051     /* Get screen event coordinates from the sprite.  Is this really the best
2052      * we can do? */
2053     event_set_root_coordinates(event,
2054                                dev->last.valuators[0] - scr->x,
2055                                dev->last.valuators[1] - scr->y);
2056     event->touchid = ti->client_id;
2057     event->flags = flags;
2058 
2059     if (flags & TOUCH_POINTER_EMULATED) {
2060         event->flags |= TOUCH_POINTER_EMULATED;
2061         event->detail.button = 1;
2062     }
2063 }
2064 
2065 /**
2066  * Synthesize a single motion event for the core pointer.
2067  *
2068  * Used in cursor functions, e.g. when cursor confinement changes, and we need
2069  * to shift the pointer to get it inside the new bounds.
2070  */
2071 void
PostSyntheticMotion(DeviceIntPtr pDev,int x,int y,int screen,unsigned long time)2072 PostSyntheticMotion(DeviceIntPtr pDev,
2073                     int x, int y, int screen, unsigned long time)
2074 {
2075     DeviceEvent ev;
2076 
2077 #ifdef PANORAMIX
2078     /* Translate back to the sprite screen since processInputProc
2079        will translate from sprite screen to screen 0 upon reentry
2080        to the DIX layer. */
2081     if (!noPanoramiXExtension) {
2082         x += screenInfo.screens[0]->x - screenInfo.screens[screen]->x;
2083         y += screenInfo.screens[0]->y - screenInfo.screens[screen]->y;
2084     }
2085 #endif
2086 
2087     memset(&ev, 0, sizeof(DeviceEvent));
2088     init_device_event(&ev, pDev, time, EVENT_SOURCE_NORMAL);
2089     ev.root_x = x;
2090     ev.root_y = y;
2091     ev.type = ET_Motion;
2092     ev.time = time;
2093 
2094     /* FIXME: MD/SD considerations? */
2095     (*pDev->public.processInputProc) ((InternalEvent *) &ev, pDev);
2096 }
2097