2 * Copyright © 2006 Nokia Corporation
3 * Copyright © 2006-2007 Daniel Stone
4 * Copyright © 2008 Red Hat, Inc.
5 * Copyright © 2011 The Chromium Authors
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:
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
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.
26 * Authors: Daniel Stone <daniel@fooishbar.org>
27 * Peter Hutterer <peter.hutterer@who-t.net>
30 #ifdef HAVE_DIX_CONFIG_H
31 #include <dix-config.h>
35 #include <X11/keysym.h>
36 #include <X11/Xproto.h>
43 #include "scrnintstr.h"
44 #include "cursorstr.h"
45 #include "dixstruct.h"
47 #include "dixevents.h"
48 #include "mipointer.h"
50 #include "eventconvert.h"
51 #include "inpututils.h"
53 #include "windowstr.h"
55 #include <X11/extensions/XKBproto.h>
59 #include "panoramiX.h"
60 #include "panoramiXsrv.h"
63 #include <X11/extensions/XI.h>
64 #include <X11/extensions/XI2.h>
65 #include <X11/extensions/XIproto.h>
67 #include "exglobals.h"
69 #include "extnsionst.h"
70 #include "listdev.h" /* for sizing up DeviceClassesChangedEvent */
73 #include <sys/types.h>
74 typedef const char *string
;
75 #include <Xserver-dtrace.h>
78 /* Number of motion history events to store. */
79 #define MOTION_HISTORY_SIZE 256
82 * InputEventList is the storage for input events generated by
83 * QueuePointerEvents, QueueKeyboardEvents, and QueueProximityEvents.
84 * This list is allocated on startup by the DIX.
86 InternalEvent
*InputEventList
= NULL
;
89 * Pick some arbitrary size for Xi motion history.
92 GetMotionHistorySize(void)
94 return MOTION_HISTORY_SIZE
;
98 set_button_down(DeviceIntPtr pDev
, int button
, int type
)
100 if (type
== BUTTON_PROCESSED
)
101 SetBit(pDev
->button
->down
, button
);
103 SetBit(pDev
->button
->postdown
, button
);
107 set_button_up(DeviceIntPtr pDev
, int button
, int type
)
109 if (type
== BUTTON_PROCESSED
)
110 ClearBit(pDev
->button
->down
, button
);
112 ClearBit(pDev
->button
->postdown
, button
);
116 button_is_down(DeviceIntPtr pDev
, int button
, int type
)
120 if (type
& BUTTON_PROCESSED
)
121 ret
= ret
|| BitIsOn(pDev
->button
->down
, button
);
122 if (type
& BUTTON_POSTED
)
123 ret
= ret
|| BitIsOn(pDev
->button
->postdown
, button
);
129 set_key_down(DeviceIntPtr pDev
, int key_code
, int type
)
131 if (type
== KEY_PROCESSED
)
132 SetBit(pDev
->key
->down
, key_code
);
134 SetBit(pDev
->key
->postdown
, key_code
);
138 set_key_up(DeviceIntPtr pDev
, int key_code
, int type
)
140 if (type
== KEY_PROCESSED
)
141 ClearBit(pDev
->key
->down
, key_code
);
143 ClearBit(pDev
->key
->postdown
, key_code
);
147 key_is_down(DeviceIntPtr pDev
, int key_code
, int type
)
151 if (type
& KEY_PROCESSED
)
152 ret
= ret
|| BitIsOn(pDev
->key
->down
, key_code
);
153 if (type
& KEY_POSTED
)
154 ret
= ret
|| BitIsOn(pDev
->key
->postdown
, key_code
);
160 key_autorepeats(DeviceIntPtr pDev
, int key_code
)
162 return ! !(pDev
->kbdfeed
->ctrl
.autoRepeats
[key_code
>> 3] &
163 (1 << (key_code
& 7)));
167 init_touch_ownership(DeviceIntPtr dev
, TouchOwnershipEvent
*event
, Time ms
)
169 memset(event
, 0, sizeof(TouchOwnershipEvent
));
170 event
->header
= ET_Internal
;
171 event
->type
= ET_TouchOwnership
;
172 event
->length
= sizeof(TouchOwnershipEvent
);
174 event
->deviceid
= dev
->id
;
178 init_raw(DeviceIntPtr dev
, RawDeviceEvent
*event
, Time ms
, int type
, int detail
)
180 memset(event
, 0, sizeof(RawDeviceEvent
));
181 event
->header
= ET_Internal
;
182 event
->length
= sizeof(RawDeviceEvent
);
185 event
->type
= ET_RawMotion
;
188 event
->type
= ET_RawButtonPress
;
191 event
->type
= ET_RawButtonRelease
;
194 event
->type
= ET_RawKeyPress
;
197 event
->type
= ET_RawKeyRelease
;
200 event
->type
= ET_RawTouchBegin
;
203 event
->type
= ET_RawTouchUpdate
;
206 event
->type
= ET_RawTouchEnd
;
210 event
->deviceid
= dev
->id
;
211 event
->sourceid
= dev
->id
;
212 event
->detail
.button
= detail
;
216 set_raw_valuators(RawDeviceEvent
*event
, ValuatorMask
*mask
, double *data
)
220 for (i
= 0; i
< valuator_mask_size(mask
); i
++) {
221 if (valuator_mask_isset(mask
, i
)) {
222 SetBit(event
->valuators
.mask
, i
);
223 data
[i
] = valuator_mask_get_double(mask
, i
);
229 set_valuators(DeviceIntPtr dev
, DeviceEvent
*event
, ValuatorMask
*mask
)
233 /* Set the data to the previous value for unset absolute axes. The values
234 * may be used when sent as part of an XI 1.x valuator event. */
235 for (i
= 0; i
< valuator_mask_size(mask
); i
++) {
236 if (valuator_mask_isset(mask
, i
)) {
237 SetBit(event
->valuators
.mask
, i
);
238 if (valuator_get_mode(dev
, i
) == Absolute
)
239 SetBit(event
->valuators
.mode
, i
);
240 event
->valuators
.data
[i
] = valuator_mask_get_double(mask
, i
);
243 event
->valuators
.data
[i
] = dev
->valuator
->axisVal
[i
];
248 CreateClassesChangedEvent(InternalEvent
*event
,
249 DeviceIntPtr master
, DeviceIntPtr slave
, int flags
)
252 DeviceChangedEvent
*dce
;
253 CARD32 ms
= GetTimeInMillis();
255 dce
= &event
->changed_event
;
256 memset(dce
, 0, sizeof(DeviceChangedEvent
));
257 dce
->deviceid
= slave
->id
;
258 dce
->masterid
= master
? master
->id
: 0;
259 dce
->header
= ET_Internal
;
260 dce
->length
= sizeof(DeviceChangedEvent
);
261 dce
->type
= ET_DeviceChanged
;
264 dce
->sourceid
= slave
->id
;
267 dce
->buttons
.num_buttons
= slave
->button
->numButtons
;
268 for (i
= 0; i
< dce
->buttons
.num_buttons
; i
++)
269 dce
->buttons
.names
[i
] = slave
->button
->labels
[i
];
271 if (slave
->valuator
) {
272 dce
->num_valuators
= slave
->valuator
->numAxes
;
273 for (i
= 0; i
< dce
->num_valuators
; i
++) {
274 dce
->valuators
[i
].min
= slave
->valuator
->axes
[i
].min_value
;
275 dce
->valuators
[i
].max
= slave
->valuator
->axes
[i
].max_value
;
276 dce
->valuators
[i
].resolution
= slave
->valuator
->axes
[i
].resolution
;
277 dce
->valuators
[i
].mode
= slave
->valuator
->axes
[i
].mode
;
278 dce
->valuators
[i
].name
= slave
->valuator
->axes
[i
].label
;
279 dce
->valuators
[i
].scroll
= slave
->valuator
->axes
[i
].scroll
;
280 dce
->valuators
[i
].value
= slave
->valuator
->axisVal
[i
];
284 dce
->keys
.min_keycode
= slave
->key
->xkbInfo
->desc
->min_key_code
;
285 dce
->keys
.max_keycode
= slave
->key
->xkbInfo
->desc
->max_key_code
;
290 * Rescale the coord between the two axis ranges.
293 rescaleValuatorAxis(double coord
, AxisInfoPtr from
, AxisInfoPtr to
,
294 double defmin
, double defmax
)
296 double fmin
= defmin
, fmax
= defmax
;
297 double tmin
= defmin
, tmax
= defmax
;
299 if (from
&& from
->min_value
< from
->max_value
) {
300 fmin
= from
->min_value
;
301 fmax
= from
->max_value
+ 1;
303 if (to
&& to
->min_value
< to
->max_value
) {
304 tmin
= to
->min_value
;
305 tmax
= to
->max_value
+ 1;
308 if (fmin
== tmin
&& fmax
== tmax
)
311 if (fmax
== fmin
) /* avoid division by 0 */
314 return (coord
- fmin
) * (tmax
- tmin
) / (fmax
- fmin
) + tmin
;
318 * Update all coordinates when changing to a different SD
319 * to ensure that relative reporting will work as expected
320 * without loss of precision.
322 * pDev->last.valuators will be in absolute device coordinates after this
326 updateSlaveDeviceCoords(DeviceIntPtr master
, DeviceIntPtr pDev
)
329 DeviceIntPtr lastSlave
;
331 /* master->last.valuators[0]/[1] is in desktop-wide coords and the actual
332 * position of the pointer */
333 pDev
->last
.valuators
[0] = master
->last
.valuators
[0];
334 pDev
->last
.valuators
[1] = master
->last
.valuators
[1];
339 /* scale back to device coordinates */
340 if (pDev
->valuator
->numAxes
> 0) {
341 pDev
->last
.valuators
[0] = rescaleValuatorAxis(pDev
->last
.valuators
[0],
343 pDev
->valuator
->axes
+ 0,
347 if (pDev
->valuator
->numAxes
> 1) {
348 pDev
->last
.valuators
[1] = rescaleValuatorAxis(pDev
->last
.valuators
[1],
350 pDev
->valuator
->axes
+ 1,
355 /* calculate the other axis as well based on info from the old
356 * slave-device. If the old slave had less axes than this one,
357 * last.valuators is reset to 0.
359 if ((lastSlave
= master
->last
.slave
) && lastSlave
->valuator
) {
360 for (i
= 2; i
< pDev
->valuator
->numAxes
; i
++) {
361 if (i
>= lastSlave
->valuator
->numAxes
) {
362 pDev
->last
.valuators
[i
] = 0;
363 valuator_mask_set_double(pDev
->last
.scroll
, i
, 0);
366 double val
= pDev
->last
.valuators
[i
];
368 val
= rescaleValuatorAxis(val
, lastSlave
->valuator
->axes
+ i
,
369 pDev
->valuator
->axes
+ i
, 0, 0);
370 pDev
->last
.valuators
[i
] = val
;
371 valuator_mask_set_double(pDev
->last
.scroll
, i
, val
);
379 * Allocate the motion history buffer.
382 AllocateMotionHistory(DeviceIntPtr pDev
)
386 free(pDev
->valuator
->motion
);
388 if (pDev
->valuator
->numMotionEvents
< 1)
391 /* An MD must have a motion history size large enough to keep all
392 * potential valuators, plus the respective range of the valuators.
393 * 3 * INT32 for (min_val, max_val, curr_val))
396 size
= sizeof(INT32
) * 3 * MAX_VALUATORS
;
398 ValuatorClassPtr v
= pDev
->valuator
;
401 /* XI1 doesn't understand mixed mode devices */
402 for (numAxes
= 0; numAxes
< v
->numAxes
; numAxes
++)
403 if (valuator_get_mode(pDev
, numAxes
) != valuator_get_mode(pDev
, 0))
405 size
= sizeof(INT32
) * numAxes
;
408 size
+= sizeof(Time
);
410 pDev
->valuator
->motion
= calloc(pDev
->valuator
->numMotionEvents
, size
);
411 pDev
->valuator
->first_motion
= 0;
412 pDev
->valuator
->last_motion
= 0;
413 if (!pDev
->valuator
->motion
)
414 ErrorF("[dix] %s: Failed to alloc motion history (%d bytes).\n",
415 pDev
->name
, size
* pDev
->valuator
->numMotionEvents
);
419 * Dump the motion history between start and stop into the supplied buffer.
420 * Only records the event for a given screen in theory, but in practice, we
421 * sort of ignore this.
423 * If core is set, we only generate x/y, in INT16, scaled to screen coords.
426 GetMotionHistory(DeviceIntPtr pDev
, xTimecoord
** buff
, unsigned long start
,
427 unsigned long stop
, ScreenPtr pScreen
, BOOL core
)
429 char *ibuff
= NULL
, *obuff
;
434 /* The size of a single motion event. */
436 AxisInfo from
, *to
; /* for scaling */
437 INT32
*ocbuf
, *icbuf
; /* pointer to coordinates for copying */
439 AxisInfo core_axis
= { 0 };
441 if (!pDev
->valuator
|| !pDev
->valuator
->numMotionEvents
)
444 if (core
&& !pScreen
)
448 size
= (sizeof(INT32
) * 3 * MAX_VALUATORS
) + sizeof(Time
);
450 size
= (sizeof(INT32
) * pDev
->valuator
->numAxes
) + sizeof(Time
);
452 *buff
= malloc(size
* pDev
->valuator
->numMotionEvents
);
455 obuff
= (char *) *buff
;
457 for (i
= pDev
->valuator
->first_motion
;
458 i
!= pDev
->valuator
->last_motion
;
459 i
= (i
+ 1) % pDev
->valuator
->numMotionEvents
) {
460 /* We index the input buffer by which element we're accessing, which
461 * is not monotonic, and the output buffer by how many events we've
463 ibuff
= (char *) pDev
->valuator
->motion
+ (i
* size
);
464 memcpy(¤t
, ibuff
, sizeof(Time
));
466 if (current
> stop
) {
469 else if (current
>= start
) {
471 memcpy(obuff
, ibuff
, sizeof(Time
)); /* copy timestamp */
473 icbuf
= (INT32
*) (ibuff
+ sizeof(Time
));
474 corebuf
= (INT16
*) (obuff
+ sizeof(Time
));
476 /* fetch x coordinate + range */
477 memcpy(&from
.min_value
, icbuf
++, sizeof(INT32
));
478 memcpy(&from
.max_value
, icbuf
++, sizeof(INT32
));
479 memcpy(&coord
, icbuf
++, sizeof(INT32
));
481 /* scale to screen coords */
483 to
->max_value
= pScreen
->width
;
485 rescaleValuatorAxis(coord
, &from
, to
, 0, pScreen
->width
);
487 memcpy(corebuf
, &coord
, sizeof(INT16
));
490 /* fetch y coordinate + range */
491 memcpy(&from
.min_value
, icbuf
++, sizeof(INT32
));
492 memcpy(&from
.max_value
, icbuf
++, sizeof(INT32
));
493 memcpy(&coord
, icbuf
++, sizeof(INT32
));
495 to
->max_value
= pScreen
->height
;
497 rescaleValuatorAxis(coord
, &from
, to
, 0, pScreen
->height
);
498 memcpy(corebuf
, &coord
, sizeof(INT16
));
501 else if (IsMaster(pDev
)) {
502 memcpy(obuff
, ibuff
, sizeof(Time
)); /* copy timestamp */
504 ocbuf
= (INT32
*) (obuff
+ sizeof(Time
));
505 icbuf
= (INT32
*) (ibuff
+ sizeof(Time
));
506 for (j
= 0; j
< MAX_VALUATORS
; j
++) {
507 if (j
>= pDev
->valuator
->numAxes
)
510 /* fetch min/max/coordinate */
511 memcpy(&from
.min_value
, icbuf
++, sizeof(INT32
));
512 memcpy(&from
.max_value
, icbuf
++, sizeof(INT32
));
513 memcpy(&coord
, icbuf
++, sizeof(INT32
));
516 pDev
->valuator
->numAxes
) ? &pDev
->valuator
->
519 /* x/y scaled to screen if no range is present */
520 if (j
== 0 && (from
.max_value
< from
.min_value
))
521 from
.max_value
= pScreen
->width
;
522 else if (j
== 1 && (from
.max_value
< from
.min_value
))
523 from
.max_value
= pScreen
->height
;
525 /* scale from stored range into current range */
526 coord
= rescaleValuatorAxis(coord
, &from
, to
, 0, 0);
527 memcpy(ocbuf
, &coord
, sizeof(INT32
));
532 memcpy(obuff
, ibuff
, size
);
534 /* don't advance by size here. size may be different to the
535 * actually written size if the MD has less valuators than MAX */
537 obuff
+= sizeof(INT32
) + sizeof(Time
);
540 (sizeof(INT32
) * pDev
->valuator
->numAxes
) + sizeof(Time
);
549 * Update the motion history for a specific device, with the list of
552 * Layout of the history buffer:
553 * for SDs: [time] [val0] [val1] ... [valn]
554 * for MDs: [time] [min_val0] [max_val0] [val0] [min_val1] ... [valn]
556 * For events that have some valuators unset:
557 * min_val == max_val == val == 0.
560 updateMotionHistory(DeviceIntPtr pDev
, CARD32 ms
, ValuatorMask
*mask
,
563 char *buff
= (char *) pDev
->valuator
->motion
;
567 if (!pDev
->valuator
->numMotionEvents
)
571 if (IsMaster(pDev
)) {
572 buff
+= ((sizeof(INT32
) * 3 * MAX_VALUATORS
) + sizeof(CARD32
)) *
575 memcpy(buff
, &ms
, sizeof(Time
));
576 buff
+= sizeof(Time
);
578 memset(buff
, 0, sizeof(INT32
) * 3 * MAX_VALUATORS
);
580 for (i
= 0; i
< v
->numAxes
; i
++) {
583 /* XI1 doesn't support mixed mode devices */
584 if (valuator_get_mode(pDev
, i
) != valuator_get_mode(pDev
, 0))
586 if (valuator_mask_size(mask
) <= i
|| !valuator_mask_isset(mask
, i
)) {
587 buff
+= 3 * sizeof(INT32
);
590 memcpy(buff
, &v
->axes
[i
].min_value
, sizeof(INT32
));
591 buff
+= sizeof(INT32
);
592 memcpy(buff
, &v
->axes
[i
].max_value
, sizeof(INT32
));
593 buff
+= sizeof(INT32
);
595 memcpy(buff
, &val
, sizeof(INT32
));
596 buff
+= sizeof(INT32
);
601 buff
+= ((sizeof(INT32
) * pDev
->valuator
->numAxes
) + sizeof(CARD32
)) *
602 pDev
->valuator
->last_motion
;
604 memcpy(buff
, &ms
, sizeof(Time
));
605 buff
+= sizeof(Time
);
607 memset(buff
, 0, sizeof(INT32
) * pDev
->valuator
->numAxes
);
609 for (i
= 0; i
< MAX_VALUATORS
; i
++) {
612 if (valuator_mask_size(mask
) <= i
|| !valuator_mask_isset(mask
, i
)) {
613 buff
+= sizeof(INT32
);
617 memcpy(buff
, &val
, sizeof(INT32
));
618 buff
+= sizeof(INT32
);
622 pDev
->valuator
->last_motion
= (pDev
->valuator
->last_motion
+ 1) %
623 pDev
->valuator
->numMotionEvents
;
624 /* If we're wrapping around, just keep the circular buffer going. */
625 if (pDev
->valuator
->first_motion
== pDev
->valuator
->last_motion
)
626 pDev
->valuator
->first_motion
= (pDev
->valuator
->first_motion
+ 1) %
627 pDev
->valuator
->numMotionEvents
;
633 * Returns the maximum number of events GetKeyboardEvents
634 * and GetPointerEvents will ever return.
636 * This MUST be absolutely constant, from init until exit.
639 GetMaximumEventsNum(void)
643 * One possible device changed event
644 * Lots of possible separate button scroll events (horiz + vert)
645 * Lots of possible separate raw button scroll events (horiz + vert)
651 * Clip an axis to its bounds, which are declared in the call to
652 * InitValuatorAxisClassStruct.
655 clipAxis(DeviceIntPtr pDev
, int axisNum
, double *val
)
659 if (axisNum
>= pDev
->valuator
->numAxes
)
662 axis
= pDev
->valuator
->axes
+ axisNum
;
664 /* If a value range is defined, clip. If not, do nothing */
665 if (axis
->max_value
<= axis
->min_value
)
668 if (*val
< axis
->min_value
)
669 *val
= axis
->min_value
;
670 if (*val
> axis
->max_value
)
671 *val
= axis
->max_value
;
675 * Clip every axis in the list of valuators to its bounds.
678 clipValuators(DeviceIntPtr pDev
, ValuatorMask
*mask
)
682 for (i
= 0; i
< valuator_mask_size(mask
); i
++)
683 if (valuator_mask_isset(mask
, i
)) {
684 double val
= valuator_mask_get_double(mask
, i
);
686 clipAxis(pDev
, i
, &val
);
687 valuator_mask_set_double(mask
, i
, val
);
692 * Create the DCCE event (does not update the master's device state yet, this
693 * is done in the event processing).
694 * Pull in the coordinates from the MD if necessary.
696 * @param events Pointer to a pre-allocated event array.
697 * @param dev The slave device that generated an event.
698 * @param type Either DEVCHANGE_POINTER_EVENT and/or DEVCHANGE_KEYBOARD_EVENT
699 * @param num_events The current number of events, returns the number of
700 * events if a DCCE was generated.
701 * @return The updated @events pointer.
704 UpdateFromMaster(InternalEvent
*events
, DeviceIntPtr dev
, int type
,
711 (type
& DEVCHANGE_POINTER_EVENT
) ? MASTER_POINTER
:
714 if (master
&& master
->last
.slave
!= dev
) {
715 CreateClassesChangedEvent(events
, master
, dev
,
716 type
| DEVCHANGE_SLAVE_SWITCH
);
717 if (IsPointerDevice(master
)) {
718 updateSlaveDeviceCoords(master
, dev
);
719 master
->last
.numValuators
= dev
->last
.numValuators
;
721 master
->last
.slave
= dev
;
729 * Move the device's pointer to the position given in the valuators.
731 * @param dev The device whose pointer is to be moved.
732 * @param mask Valuator data for this event.
735 clipAbsolute(DeviceIntPtr dev
, ValuatorMask
*mask
)
739 for (i
= 0; i
< valuator_mask_size(mask
); i
++) {
742 if (!valuator_mask_isset(mask
, i
))
744 val
= valuator_mask_get_double(mask
, i
);
745 clipAxis(dev
, i
, &val
);
746 valuator_mask_set_double(mask
, i
, val
);
751 add_to_scroll_valuator(DeviceIntPtr dev
, ValuatorMask
*mask
, int valuator
, double value
)
755 if (!valuator_mask_fetch_double(mask
, valuator
, &v
))
758 /* protect against scrolling overflow. INT_MAX for double, because
759 * we'll eventually write this as 32.32 fixed point */
760 if ((value
> 0 && v
> INT_MAX
- value
) || (value
< 0 && v
< INT_MIN
- value
)) {
763 /* reset last.scroll to avoid a button storm */
764 valuator_mask_set_double(dev
->last
.scroll
, valuator
, 0);
769 valuator_mask_set_double(mask
, valuator
, v
);
774 scale_for_device_resolution(DeviceIntPtr dev
, ValuatorMask
*mask
)
777 ValuatorClassPtr v
= dev
->valuator
;
778 int xrange
= v
->axes
[0].max_value
- v
->axes
[0].min_value
+ 1;
779 int yrange
= v
->axes
[1].max_value
- v
->axes
[1].min_value
+ 1;
781 double screen_ratio
= 1.0 * screenInfo
.width
/screenInfo
.height
;
782 double device_ratio
= 1.0 * xrange
/yrange
;
783 double resolution_ratio
= 1.0;
786 if (!valuator_mask_fetch_double(mask
, 1, &y
))
789 if (v
->axes
[0].resolution
!= 0 && v
->axes
[1].resolution
!= 0)
790 resolution_ratio
= 1.0 * v
->axes
[0].resolution
/v
->axes
[1].resolution
;
792 ratio
= device_ratio
/resolution_ratio
/screen_ratio
;
793 valuator_mask_set_double(mask
, 1, y
/ ratio
);
797 * Move the device's pointer by the values given in @valuators.
799 * @param dev The device whose pointer is to be moved.
800 * @param[in,out] mask Valuator data for this event, modified in-place.
803 moveRelative(DeviceIntPtr dev
, int flags
, ValuatorMask
*mask
)
806 Bool clip_xy
= IsMaster(dev
) || !IsFloating(dev
);
807 ValuatorClassPtr v
= dev
->valuator
;
809 /* for abs devices in relative mode, we've just scaled wrong, since we
810 mapped the device's shape into the screen shape. Undo this. */
811 if ((flags
& POINTER_ABSOLUTE
) == 0 && v
&& v
->numAxes
> 1 &&
812 v
->axes
[0].min_value
< v
->axes
[0].max_value
&&
813 v
->axes
[1].min_value
< v
->axes
[1].max_value
) {
814 scale_for_device_resolution(dev
, mask
);
817 /* calc other axes, clip, drop back into valuators */
818 for (i
= 0; i
< valuator_mask_size(mask
); i
++) {
819 double val
= dev
->last
.valuators
[i
];
821 if (!valuator_mask_isset(mask
, i
))
824 add_to_scroll_valuator(dev
, mask
, i
, val
);
826 /* x & y need to go over the limits to cross screens if the SD
827 * isn't currently attached; otherwise, clip to screen bounds. */
828 if (valuator_get_mode(dev
, i
) == Absolute
&&
829 ((i
!= 0 && i
!= 1) || clip_xy
)) {
830 val
= valuator_mask_get_double(mask
, i
);
831 clipAxis(dev
, i
, &val
);
832 valuator_mask_set_double(mask
, i
, val
);
838 * Accelerate the data in valuators based on the device's acceleration scheme.
840 * @param dev The device which's pointer is to be moved.
841 * @param valuators Valuator mask
842 * @param ms Current time.
845 accelPointer(DeviceIntPtr dev
, ValuatorMask
*valuators
, CARD32 ms
)
847 if (dev
->valuator
->accelScheme
.AccelSchemeProc
)
848 dev
->valuator
->accelScheme
.AccelSchemeProc(dev
, valuators
, ms
);
852 * Scale from absolute screen coordinates to absolute coordinates in the
853 * device's coordinate range.
855 * @param dev The device to scale for.
856 * @param[in, out] mask The mask in desktop/screen coordinates, modified in place
857 * to contain device coordinate range.
858 * @param flags If POINTER_SCREEN is set, mask is in per-screen coordinates.
859 * Otherwise, mask is in desktop coords.
862 scale_from_screen(DeviceIntPtr dev
, ValuatorMask
*mask
, int flags
)
865 ScreenPtr scr
= miPointerGetScreen(dev
);
867 if (valuator_mask_isset(mask
, 0)) {
868 scaled
= valuator_mask_get_double(mask
, 0);
869 if (flags
& POINTER_SCREEN
)
871 scaled
= rescaleValuatorAxis(scaled
,
872 NULL
, dev
->valuator
->axes
+ 0,
873 screenInfo
.x
, screenInfo
.width
);
874 valuator_mask_set_double(mask
, 0, scaled
);
876 if (valuator_mask_isset(mask
, 1)) {
877 scaled
= valuator_mask_get_double(mask
, 1);
878 if (flags
& POINTER_SCREEN
)
880 scaled
= rescaleValuatorAxis(scaled
,
881 NULL
, dev
->valuator
->axes
+ 1,
882 screenInfo
.y
, screenInfo
.height
);
883 valuator_mask_set_double(mask
, 1, scaled
);
888 * Scale from (absolute) device to screen coordinates here,
890 * The coordinates provided are always absolute. see fill_pointer_events for
891 * information on coordinate systems.
893 * @param dev The device to be moved.
894 * @param mask Mask of axis values for this event
895 * @param[out] devx x desktop-wide coordinate in device coordinate system
896 * @param[out] devy y desktop-wide coordinate in device coordinate system
897 * @param[out] screenx x coordinate in desktop coordinate system
898 * @param[out] screeny y coordinate in desktop coordinate system
901 scale_to_desktop(DeviceIntPtr dev
, ValuatorMask
*mask
,
902 double *devx
, double *devy
, double *screenx
, double *screeny
)
904 ScreenPtr scr
= miPointerGetScreen(dev
);
907 BUG_WARN(dev
->valuator
&& dev
->valuator
->numAxes
< 2);
908 if (!dev
->valuator
|| dev
->valuator
->numAxes
< 2) {
909 /* if we have no axes, last.valuators must be in screen coords
911 *devx
= *screenx
= dev
->last
.valuators
[0];
912 *devy
= *screeny
= dev
->last
.valuators
[1];
916 if (valuator_mask_isset(mask
, 0))
917 x
= valuator_mask_get_double(mask
, 0);
919 x
= dev
->last
.valuators
[0];
920 if (valuator_mask_isset(mask
, 1))
921 y
= valuator_mask_get_double(mask
, 1);
923 y
= dev
->last
.valuators
[1];
925 /* scale x&y to desktop coordinates */
926 *screenx
= rescaleValuatorAxis(x
, dev
->valuator
->axes
+ 0, NULL
,
927 screenInfo
.x
, screenInfo
.width
);
928 *screeny
= rescaleValuatorAxis(y
, dev
->valuator
->axes
+ 1, NULL
,
929 screenInfo
.y
, screenInfo
.height
);
938 * If we have HW cursors, this actually moves the visible sprite. If not, we
939 * just do all the screen crossing, etc.
941 * We use the screen coordinates here, call miPointerSetPosition() and then
942 * scale back into device coordinates (if needed). miPSP will change x/y if
943 * the screen was crossed.
945 * The coordinates provided are always absolute. The parameter mode
946 * specifies whether it was relative or absolute movement that landed us at
947 * those coordinates. see fill_pointer_events for information on coordinate
950 * @param dev The device to be moved.
951 * @param mode Movement mode (Absolute or Relative)
952 * @param[out] mask Mask of axis values for this event, returns the
953 * per-screen device coordinates after confinement
954 * @param[in,out] devx x desktop-wide coordinate in device coordinate system
955 * @param[in,out] devy y desktop-wide coordinate in device coordinate system
956 * @param[in,out] screenx x coordinate in desktop coordinate system
957 * @param[in,out] screeny y coordinate in desktop coordinate system
958 * @param[out] nevents Number of barrier events added to events
959 * @param[in,out] events List of events barrier events are added to
962 positionSprite(DeviceIntPtr dev
, int mode
, ValuatorMask
*mask
,
963 double *devx
, double *devy
, double *screenx
, double *screeny
,
964 int *nevents
, InternalEvent
* events
)
966 ScreenPtr scr
= miPointerGetScreen(dev
);
969 if (!dev
->valuator
|| dev
->valuator
->numAxes
< 2)
975 /* miPointerSetPosition takes care of crossing screens for us, as well as
976 * clipping to the current screen. Coordinates returned are in desktop
978 scr
= miPointerSetPosition(dev
, mode
, screenx
, screeny
, nevents
, events
);
980 /* If we were constrained, rescale x/y from the screen coordinates so
981 * the device valuators reflect the correct position. For screen
982 * crossing this doesn't matter much, the coords would be 0 or max.
984 if (tmpx
!= *screenx
)
985 *devx
= rescaleValuatorAxis(*screenx
, NULL
, dev
->valuator
->axes
+ 0,
986 screenInfo
.x
, screenInfo
.width
);
988 if (tmpy
!= *screeny
)
989 *devy
= rescaleValuatorAxis(*screeny
, NULL
, dev
->valuator
->axes
+ 1,
990 screenInfo
.y
, screenInfo
.height
);
992 /* Recalculate the per-screen device coordinates */
993 if (valuator_mask_isset(mask
, 0)) {
996 x
= rescaleValuatorAxis(*screenx
- scr
->x
, NULL
,
997 dev
->valuator
->axes
+ 0, 0, scr
->width
);
998 valuator_mask_set_double(mask
, 0, x
);
1000 if (valuator_mask_isset(mask
, 1)) {
1003 y
= rescaleValuatorAxis(*screeny
- scr
->y
, NULL
,
1004 dev
->valuator
->axes
+ 1, 0, scr
->height
);
1005 valuator_mask_set_double(mask
, 1, y
);
1012 * Update the motion history for the device and (if appropriate) for its
1014 * @param dev Slave device to update.
1015 * @param mask Bit mask of valid valuators to append to history.
1016 * @param num Total number of valuators to append to history.
1017 * @param ms Current time
1020 updateHistory(DeviceIntPtr dev
, ValuatorMask
*mask
, CARD32 ms
)
1025 updateMotionHistory(dev
, ms
, mask
, dev
->last
.valuators
);
1026 if (!IsMaster(dev
) && !IsFloating(dev
)) {
1027 DeviceIntPtr master
= GetMaster(dev
, MASTER_POINTER
);
1029 updateMotionHistory(master
, ms
, mask
, dev
->last
.valuators
);
1034 queueEventList(DeviceIntPtr device
, InternalEvent
*events
, int nevents
)
1038 for (i
= 0; i
< nevents
; i
++)
1039 mieqEnqueue(device
, &events
[i
]);
1043 event_set_root_coordinates(DeviceEvent
*event
, double x
, double y
)
1045 event
->root_x
= trunc(x
);
1046 event
->root_y
= trunc(y
);
1047 event
->root_x_frac
= x
- trunc(x
);
1048 event
->root_y_frac
= y
- trunc(y
);
1052 * Generate internal events representing this keyboard event and enqueue
1053 * them on the event queue.
1055 * This function is not reentrant. Disable signals before calling.
1057 * FIXME: flags for relative/abs motion?
1059 * @param device The device to generate the event for
1060 * @param type Event type, one of KeyPress or KeyRelease
1061 * @param keycode Key code of the pressed/released key
1062 * @param mask Valuator mask for valuators present for this event.
1066 QueueKeyboardEvents(DeviceIntPtr device
, int type
,
1067 int keycode
, const ValuatorMask
*mask
)
1071 nevents
= GetKeyboardEvents(InputEventList
, device
, type
, keycode
, mask
);
1072 queueEventList(device
, InputEventList
, nevents
);
1076 * Returns a set of InternalEvents for KeyPress/KeyRelease, optionally
1077 * also with valuator events.
1079 * The DDX is responsible for allocating the event list in the first
1080 * place via InitEventList(), and for freeing it.
1082 * @return the number of events written into events.
1085 GetKeyboardEvents(InternalEvent
*events
, DeviceIntPtr pDev
, int type
,
1086 int key_code
, const ValuatorMask
*mask_in
)
1091 RawDeviceEvent
*raw
;
1095 if (XSERVER_INPUT_EVENT_ENABLED()) {
1096 XSERVER_INPUT_EVENT(pDev
->id
, type
, key_code
, 0,
1097 mask_in
? mask_in
->last_bit
+ 1 : 0,
1098 mask_in
? mask_in
->mask
: NULL
,
1099 mask_in
? mask_in
->valuators
: NULL
);
1103 /* refuse events from disabled devices */
1107 if (!events
|| !pDev
->key
|| !pDev
->focus
|| !pDev
->kbdfeed
||
1108 (type
!= KeyPress
&& type
!= KeyRelease
) ||
1109 (key_code
< 8 || key_code
> 255))
1112 if (mask_in
&& valuator_mask_size(mask_in
) > 1) {
1113 ErrorF("[dix] the server does not handle valuator masks with "
1114 "keyboard events. This is a bug. You may fix it.\n");
1120 UpdateFromMaster(events
, pDev
, DEVCHANGE_KEYBOARD_EVENT
, &num_events
);
1122 /* Handle core repeating, via press/release/press/release. */
1123 if (type
== KeyPress
&& key_is_down(pDev
, key_code
, KEY_POSTED
)) {
1124 /* If autorepeating is disabled either globally or just for that key,
1125 * or we have a modifier, don't generate a repeat event. */
1126 if (!pDev
->kbdfeed
->ctrl
.autoRepeat
||
1127 !key_autorepeats(pDev
, key_code
) ||
1128 pDev
->key
->xkbInfo
->desc
->map
->modmap
[key_code
])
1132 ms
= GetTimeInMillis();
1134 raw
= &events
->raw_event
;
1138 valuator_mask_copy(&mask
, mask_in
);
1140 init_raw(pDev
, raw
, ms
, type
, key_code
);
1141 set_raw_valuators(raw
, &mask
, raw
->valuators
.data_raw
);
1143 clipValuators(pDev
, &mask
);
1145 set_raw_valuators(raw
, &mask
, raw
->valuators
.data
);
1147 event
= &events
->device_event
;
1148 init_device_event(event
, pDev
, ms
);
1149 event
->detail
.key
= key_code
;
1151 if (type
== KeyPress
) {
1152 event
->type
= ET_KeyPress
;
1153 set_key_down(pDev
, key_code
, KEY_POSTED
);
1155 else if (type
== KeyRelease
) {
1156 event
->type
= ET_KeyRelease
;
1157 set_key_up(pDev
, key_code
, KEY_POSTED
);
1160 clipValuators(pDev
, &mask
);
1162 set_valuators(pDev
, event
, &mask
);
1164 if (!IsFloating(pDev
)) {
1165 DeviceIntPtr master
= GetMaster(pDev
, MASTER_POINTER
);
1167 event_set_root_coordinates(event
,
1168 master
->last
.valuators
[0],
1169 master
->last
.valuators
[1]);
1176 * Initialize an event array large enough for num_events arrays.
1177 * This event list is to be passed into GetPointerEvents() and
1178 * GetKeyboardEvents().
1180 * @param num_events Number of elements in list.
1183 InitEventList(int num_events
)
1185 InternalEvent
*events
= calloc(num_events
, sizeof(InternalEvent
));
1191 * Free an event list.
1193 * @param list The list to be freed.
1194 * @param num_events Number of elements in list.
1197 FreeEventList(InternalEvent
*list
, int num_events
)
1203 * Transform vector x/y according to matrix m and drop the rounded coords
1207 transform(struct pixman_f_transform
*m
, double *x
, double *y
)
1209 struct pixman_f_vector p
= {.v
= {*x
, *y
, 1} };
1210 pixman_f_transform_point(m
, &p
);
1217 transformRelative(DeviceIntPtr dev
, ValuatorMask
*mask
)
1219 double x
= 0, y
= 0;
1221 valuator_mask_fetch_double(mask
, 0, &x
);
1222 valuator_mask_fetch_double(mask
, 1, &y
);
1224 transform(&dev
->relative_transform
, &x
, &y
);
1227 valuator_mask_set_double(mask
, 0, x
);
1229 valuator_mask_unset(mask
, 0);
1232 valuator_mask_set_double(mask
, 1, y
);
1234 valuator_mask_unset(mask
, 1);
1238 * Apply the device's transformation matrix to the valuator mask and replace
1239 * the scaled values in mask. This transformation only applies to valuators
1240 * 0 and 1, others will be untouched.
1242 * @param dev The device the valuators came from
1243 * @param[in,out] mask The valuator mask.
1246 transformAbsolute(DeviceIntPtr dev
, ValuatorMask
*mask
)
1248 double x
, y
, ox
, oy
;
1251 has_x
= valuator_mask_fetch_double(mask
, 0, &ox
);
1252 has_y
= valuator_mask_fetch_double(mask
, 1, &oy
);
1254 if (!has_x
&& !has_y
)
1257 if (!has_x
|| !has_y
) {
1258 struct pixman_f_transform invert
;
1260 /* undo transformation from last event */
1261 ox
= dev
->last
.valuators
[0];
1262 oy
= dev
->last
.valuators
[1];
1264 pixman_f_transform_invert(&invert
, &dev
->scale_and_transform
);
1265 transform(&invert
, &ox
, &oy
);
1271 if (valuator_mask_isset(mask
, 0))
1272 ox
= x
= valuator_mask_get_double(mask
, 0);
1274 if (valuator_mask_isset(mask
, 1))
1275 oy
= y
= valuator_mask_get_double(mask
, 1);
1277 transform(&dev
->scale_and_transform
, &x
, &y
);
1279 if (valuator_mask_isset(mask
, 0) || ox
!= x
)
1280 valuator_mask_set_double(mask
, 0, x
);
1282 if (valuator_mask_isset(mask
, 1) || oy
!= y
)
1283 valuator_mask_set_double(mask
, 1, y
);
1287 storeLastValuators(DeviceIntPtr dev
, ValuatorMask
*mask
,
1288 int xaxis
, int yaxis
, double devx
, double devy
)
1292 /* store desktop-wide in last.valuators */
1293 if (valuator_mask_isset(mask
, xaxis
))
1294 dev
->last
.valuators
[0] = devx
;
1295 if (valuator_mask_isset(mask
, yaxis
))
1296 dev
->last
.valuators
[1] = devy
;
1298 for (i
= 0; i
< valuator_mask_size(mask
); i
++) {
1299 if (i
== xaxis
|| i
== yaxis
)
1302 if (valuator_mask_isset(mask
, i
))
1303 dev
->last
.valuators
[i
] = valuator_mask_get_double(mask
, i
);
1309 * Generate internal events representing this pointer event and enqueue them
1310 * on the event queue.
1312 * This function is not reentrant. Disable signals before calling.
1314 * @param device The device to generate the event for
1315 * @param type Event type, one of ButtonPress, ButtonRelease, MotionNotify
1316 * @param buttons Button number of the buttons modified. Must be 0 for
1318 * @param flags Event modification flags
1319 * @param mask Valuator mask for valuators present for this event.
1322 QueuePointerEvents(DeviceIntPtr device
, int type
,
1323 int buttons
, int flags
, const ValuatorMask
*mask
)
1328 GetPointerEvents(InputEventList
, device
, type
, buttons
, flags
, mask
);
1329 queueEventList(device
, InputEventList
, nevents
);
1333 * Helper function for GetPointerEvents, which only generates motion and
1334 * raw motion events for the slave device: does not update the master device.
1336 * Should not be called by anyone other than GetPointerEvents.
1338 * We use several different coordinate systems and need to switch between
1339 * the three in fill_pointer_events, positionSprite and
1340 * miPointerSetPosition. "desktop" refers to the width/height of all
1341 * screenInfo.screens[n]->width/height added up. "screen" is ScreenRec, not
1344 * Coordinate systems:
1345 * - relative events have a mask_in in relative coordinates, mapped to
1346 * pixels. These events are mapped to the current position±delta.
1347 * - absolute events have a mask_in in absolute device coordinates in
1348 * device-specific range. This range is mapped to the desktop.
1349 * - POINTER_SCREEN absolute events (x86WarpCursor) are in screen-relative
1350 * screen coordinate range.
1351 * - rootx/rooty in events must be be relative to the current screen's
1352 * origin (screen coordinate system)
1353 * - XI2 valuators must be relative to the current screen's origin. On
1354 * the protocol the device min/max range maps to the current screen.
1356 * For screen switching we need to get the desktop coordinates for each
1357 * event, then map that to the respective position on each screen and
1358 * position the cursor there.
1359 * The device's last.valuator[] stores the last position in desktop-wide
1360 * coordinates (in device range for slave devices, desktop range for master
1363 * screen-relative device coordinates requires scaling: A device coordinate
1364 * x/y of range [n..m] that maps to positions Sx/Sy on Screen S must be
1365 * rescaled to match Sx/Sy for [n..m]. In the simplest example, x of (m/2-1)
1366 * is the last coordinate on the first screen and must be rescaled for the
1367 * event to be m. XI2 clients that do their own coordinate mapping would
1368 * otherwise interpret the position of the device elsewere to the cursor.
1369 * However, this scaling leads to losses:
1370 * if we have two ScreenRecs we scale from e.g. [0..44704] (Wacom I4) to
1371 * [0..2048[. that gives us 2047.954 as desktop coord, or the per-screen
1372 * coordinate 1023.954. Scaling that back into the device coordinate range
1373 * gives us 44703. So off by one device unit. It's a bug, but we'll have to
1374 * live with it because with all this scaling, we just cannot win.
1376 * @return the number of events written into events.
1379 fill_pointer_events(InternalEvent
*events
, DeviceIntPtr pDev
, int type
,
1380 int buttons
, CARD32 ms
, int flags
,
1381 const ValuatorMask
*mask_in
)
1385 RawDeviceEvent
*raw
;
1386 double screenx
= 0.0, screeny
= 0.0; /* desktop coordinate system */
1387 double devx
= 0.0, devy
= 0.0; /* desktop-wide in device coords */
1388 int sx
, sy
; /* for POINTER_SCREEN */
1391 int num_barrier_events
= 0;
1395 if (!pDev
->valuator
) {
1396 ErrorF("[dix] motion events from device %d without valuators\n",
1400 if (!mask_in
|| valuator_mask_num_valuators(mask_in
) <= 0)
1405 if (!pDev
->button
|| !buttons
)
1407 if (mask_in
&& valuator_mask_size(mask_in
) > 0 && !pDev
->valuator
) {
1409 ("[dix] button event with valuator from device %d without valuators\n",
1418 valuator_mask_copy(&mask
, mask_in
);
1420 if ((flags
& POINTER_NORAW
) == 0) {
1421 raw
= &events
->raw_event
;
1425 init_raw(pDev
, raw
, ms
, type
, buttons
);
1426 set_raw_valuators(raw
, &mask
, raw
->valuators
.data_raw
);
1429 /* valuators are in driver-native format (rel or abs) */
1431 if (flags
& POINTER_ABSOLUTE
) {
1432 if (flags
& (POINTER_SCREEN
| POINTER_DESKTOP
)) { /* valuators are in screen/desktop coords */
1433 sx
= valuator_mask_get(&mask
, 0);
1434 sy
= valuator_mask_get(&mask
, 1);
1435 scale_from_screen(pDev
, &mask
, flags
);
1438 transformAbsolute(pDev
, &mask
);
1439 clipAbsolute(pDev
, &mask
);
1440 if ((flags
& POINTER_NORAW
) == 0)
1441 set_raw_valuators(raw
, &mask
, raw
->valuators
.data
);
1444 transformRelative(pDev
, &mask
);
1446 if (flags
& POINTER_ACCELERATE
)
1447 accelPointer(pDev
, &mask
, ms
);
1448 if ((flags
& POINTER_NORAW
) == 0)
1449 set_raw_valuators(raw
, &mask
, raw
->valuators
.data
);
1451 moveRelative(pDev
, flags
, &mask
);
1454 /* valuators are in device coordinate system in absolute coordinates */
1455 scale_to_desktop(pDev
, &mask
, &devx
, &devy
, &screenx
, &screeny
);
1457 /* #53037 XWarpPointer's scaling back and forth between screen and
1458 device may leave us with rounding errors. End result is that the
1459 pointer doesn't end up on the pixel it should.
1460 Avoid this by forcing screenx/screeny back to what the input
1463 if (flags
& POINTER_SCREEN
) {
1464 scr
= miPointerGetScreen(pDev
);
1465 screenx
= sx
+ scr
->x
;
1466 screeny
= sy
+ scr
->y
;
1469 scr
= positionSprite(pDev
, (flags
& POINTER_ABSOLUTE
) ? Absolute
: Relative
,
1470 &mask
, &devx
, &devy
, &screenx
, &screeny
,
1471 &num_barrier_events
, events
);
1472 num_events
+= num_barrier_events
;
1473 events
+= num_barrier_events
;
1475 /* screenx, screeny are in desktop coordinates,
1476 mask is in device coordinates per-screen (the event data)
1477 devx/devy is in device coordinate desktop-wide */
1478 updateHistory(pDev
, &mask
, ms
);
1480 clipValuators(pDev
, &mask
);
1482 storeLastValuators(pDev
, &mask
, 0, 1, devx
, devy
);
1484 /* Update the MD's co-ordinates, which are always in desktop space. */
1485 if (!IsMaster(pDev
) && !IsFloating(pDev
)) {
1486 DeviceIntPtr master
= GetMaster(pDev
, MASTER_POINTER
);
1488 master
->last
.valuators
[0] = screenx
;
1489 master
->last
.valuators
[1] = screeny
;
1492 event
= &events
->device_event
;
1493 init_device_event(event
, pDev
, ms
);
1495 if (type
== MotionNotify
) {
1496 event
->type
= ET_Motion
;
1497 event
->detail
.button
= 0;
1500 if (type
== ButtonPress
) {
1501 event
->type
= ET_ButtonPress
;
1502 set_button_down(pDev
, buttons
, BUTTON_POSTED
);
1504 else if (type
== ButtonRelease
) {
1505 event
->type
= ET_ButtonRelease
;
1506 set_button_up(pDev
, buttons
, BUTTON_POSTED
);
1508 event
->detail
.button
= buttons
;
1511 /* root_x and root_y must be in per-screen co-ordinates */
1512 event_set_root_coordinates(event
, screenx
- scr
->x
, screeny
- scr
->y
);
1514 if (flags
& POINTER_EMULATED
) {
1515 raw
->flags
= XIPointerEmulated
;
1516 event
->flags
= XIPointerEmulated
;
1519 set_valuators(pDev
, event
, &mask
);
1525 * Generate events for each scroll axis that changed between before/after
1528 * @param events The pointer to the event list to fill the events
1529 * @param dev The device to generate the events for
1530 * @param type The real type of the event
1531 * @param axis The axis number to generate events for
1532 * @param mask State before this event in absolute coords
1533 * @param[in,out] last Last scroll state posted in absolute coords (modified
1535 * @param ms Current time in ms
1536 * @param max_events Max number of events to be generated
1537 * @return The number of events generated
1540 emulate_scroll_button_events(InternalEvent
*events
,
1544 const ValuatorMask
*mask
,
1545 ValuatorMask
*last
, CARD32 ms
, int max_events
)
1555 if (dev
->valuator
->axes
[axis
].scroll
.type
== SCROLL_TYPE_NONE
)
1558 if (!valuator_mask_isset(mask
, axis
))
1561 ax
= &dev
->valuator
->axes
[axis
];
1562 incr
= ax
->scroll
.increment
;
1564 if (type
!= ButtonPress
&& type
!= ButtonRelease
)
1565 flags
|= POINTER_EMULATED
;
1567 if (!valuator_mask_isset(last
, axis
))
1568 valuator_mask_set_double(last
, axis
, 0);
1571 valuator_mask_get_double(mask
, axis
) - valuator_mask_get_double(last
,
1574 b
= (ax
->scroll
.type
== SCROLL_TYPE_VERTICAL
) ? 5 : 7;
1576 if ((incr
> 0 && delta
< 0) || (incr
< 0 && delta
> 0))
1577 b
--; /* we're scrolling up or left → button 4 or 6 */
1579 while (fabs(delta
) >= fabs(incr
)) {
1583 delta
-= fabs(incr
);
1585 delta
+= fabs(incr
);
1587 /* fill_pointer_events() generates four events: one normal and one raw
1588 * event for button press and button release.
1589 * We may get a bigger scroll delta than we can generate events
1590 * for. In that case, we keep decreasing delta, but skip events.
1592 if (num_events
+ 4 < max_events
) {
1593 if (type
!= ButtonRelease
) {
1594 nev_tmp
= fill_pointer_events(events
, dev
, ButtonPress
, b
, ms
,
1597 num_events
+= nev_tmp
;
1599 if (type
!= ButtonPress
) {
1600 nev_tmp
= fill_pointer_events(events
, dev
, ButtonRelease
, b
, ms
,
1603 num_events
+= nev_tmp
;
1608 /* We emulated, update last.scroll */
1609 if (total
!= delta
) {
1611 valuator_mask_set_double(last
, axis
,
1612 valuator_mask_get_double(last
, axis
) + total
);
1620 * Generate a complete series of InternalEvents (filled into the EventList)
1621 * representing pointer motion, or button presses. If the device is a slave
1622 * device, also potentially generate a DeviceClassesChangedEvent to update
1623 * the master device.
1625 * events is not NULL-terminated; the return value is the number of events.
1626 * The DDX is responsible for allocating the event structure in the first
1627 * place via InitEventList() and GetMaximumEventsNum(), and for freeing it.
1629 * In the generated events rootX/Y will be in absolute screen coords and
1630 * the valuator information in the absolute or relative device coords.
1632 * last.valuators[x] of the device is always in absolute device coords.
1633 * last.valuators[x] of the master device is in absolute screen coords.
1635 * master->last.valuators[x] for x > 2 is undefined.
1638 GetPointerEvents(InternalEvent
*events
, DeviceIntPtr pDev
, int type
,
1639 int buttons
, int flags
, const ValuatorMask
*mask_in
)
1641 CARD32 ms
= GetTimeInMillis();
1642 int num_events
= 0, nev_tmp
;
1644 ValuatorMask scroll
;
1646 int realtype
= type
;
1649 if (XSERVER_INPUT_EVENT_ENABLED()) {
1650 XSERVER_INPUT_EVENT(pDev
->id
, type
, buttons
, flags
,
1651 mask_in
? mask_in
->last_bit
+ 1 : 0,
1652 mask_in
? mask_in
->mask
: NULL
,
1653 mask_in
? mask_in
->valuators
: NULL
);
1657 BUG_RETURN_VAL(buttons
>= MAX_BUTTONS
, 0);
1659 /* refuse events from disabled devices */
1663 if (!miPointerGetScreen(pDev
))
1666 events
= UpdateFromMaster(events
, pDev
, DEVCHANGE_POINTER_EVENT
,
1669 valuator_mask_copy(&mask
, mask_in
);
1671 /* Turn a scroll button press into a smooth-scrolling event if
1672 * necessary. This only needs to cater for the XIScrollFlagPreferred
1673 * axis (if more than one scrolling axis is present) */
1674 if (type
== ButtonPress
) {
1677 int h_scroll_axis
= -1;
1678 int v_scroll_axis
= -1;
1680 if (pDev
->valuator
) {
1681 h_scroll_axis
= pDev
->valuator
->h_scroll_axis
;
1682 v_scroll_axis
= pDev
->valuator
->v_scroll_axis
;
1685 /* Up is negative on valuators, down positive */
1689 axis
= v_scroll_axis
;
1693 axis
= v_scroll_axis
;
1697 axis
= h_scroll_axis
;
1701 axis
= h_scroll_axis
;
1709 if (adj
!= 0.0 && axis
!= -1) {
1710 adj
*= pDev
->valuator
->axes
[axis
].scroll
.increment
;
1711 if (!valuator_mask_isset(&mask
, axis
))
1712 valuator_mask_set(&mask
, axis
, 0);
1713 add_to_scroll_valuator(pDev
, &mask
, axis
, adj
);
1714 type
= MotionNotify
;
1716 flags
|= POINTER_EMULATED
;
1720 /* First fill out the original event set, with smooth-scrolling axes. */
1721 nev_tmp
= fill_pointer_events(events
, pDev
, type
, buttons
, ms
, flags
,
1724 num_events
+= nev_tmp
;
1726 valuator_mask_zero(&scroll
);
1728 /* Now turn the smooth-scrolling axes back into emulated button presses
1729 * for legacy clients, based on the integer delta between before and now */
1730 for (i
= 0; i
< valuator_mask_size(&mask
); i
++) {
1731 if ( !pDev
->valuator
|| (i
>= pDev
->valuator
->numAxes
))
1734 if (!valuator_mask_isset(&mask
, i
))
1737 valuator_mask_set_double(&scroll
, i
, pDev
->last
.valuators
[i
]);
1740 emulate_scroll_button_events(events
, pDev
, realtype
, i
, &scroll
,
1741 pDev
->last
.scroll
, ms
,
1742 GetMaximumEventsNum() - num_events
);
1744 num_events
+= nev_tmp
;
1751 * Generate internal events representing this proximity event and enqueue
1752 * them on the event queue.
1754 * This function is not reentrant. Disable signals before calling.
1756 * @param device The device to generate the event for
1757 * @param type Event type, one of ProximityIn or ProximityOut
1758 * @param keycode Key code of the pressed/released key
1759 * @param mask Valuator mask for valuators present for this event.
1763 QueueProximityEvents(DeviceIntPtr device
, int type
, const ValuatorMask
*mask
)
1767 nevents
= GetProximityEvents(InputEventList
, device
, type
, mask
);
1768 queueEventList(device
, InputEventList
, nevents
);
1772 * Generate ProximityIn/ProximityOut InternalEvents, accompanied by
1775 * The DDX is responsible for allocating the events in the first place via
1776 * InitEventList(), and for freeing it.
1778 * @return the number of events written into events.
1781 GetProximityEvents(InternalEvent
*events
, DeviceIntPtr pDev
, int type
,
1782 const ValuatorMask
*mask_in
)
1784 int num_events
= 1, i
;
1789 if (XSERVER_INPUT_EVENT_ENABLED()) {
1790 XSERVER_INPUT_EVENT(pDev
->id
, type
, 0, 0,
1791 mask_in
? mask_in
->last_bit
+ 1 : 0,
1792 mask_in
? mask_in
->mask
: NULL
,
1793 mask_in
? mask_in
->valuators
: NULL
);
1797 /* refuse events from disabled devices */
1801 /* Sanity checks. */
1802 if ((type
!= ProximityIn
&& type
!= ProximityOut
) || !mask_in
)
1804 if (!pDev
->valuator
|| !pDev
->proximity
)
1807 valuator_mask_copy(&mask
, mask_in
);
1809 /* ignore relative axes for proximity. */
1810 for (i
= 0; i
< valuator_mask_size(&mask
); i
++) {
1811 if (valuator_mask_isset(&mask
, i
) &&
1812 valuator_get_mode(pDev
, i
) == Relative
)
1813 valuator_mask_unset(&mask
, i
);
1816 /* FIXME: posting proximity events with relative valuators only results
1817 * in an empty event, EventToXI() will fail to convert → no event sent
1821 UpdateFromMaster(events
, pDev
, DEVCHANGE_POINTER_EVENT
, &num_events
);
1823 event
= &events
->device_event
;
1824 init_device_event(event
, pDev
, GetTimeInMillis());
1825 event
->type
= (type
== ProximityIn
) ? ET_ProximityIn
: ET_ProximityOut
;
1827 clipValuators(pDev
, &mask
);
1829 set_valuators(pDev
, event
, &mask
);
1835 GetTouchOwnershipEvents(InternalEvent
*events
, DeviceIntPtr pDev
,
1836 TouchPointInfoPtr ti
, uint8_t reason
, XID resource
,
1839 TouchClassPtr t
= pDev
->touch
;
1840 TouchOwnershipEvent
*event
;
1841 CARD32 ms
= GetTimeInMillis();
1843 if (!pDev
->enabled
|| !t
|| !ti
)
1846 event
= &events
->touch_ownership_event
;
1847 init_touch_ownership(pDev
, event
, ms
);
1849 event
->touchid
= ti
->client_id
;
1850 event
->sourceid
= ti
->sourceid
;
1851 event
->resource
= resource
;
1852 event
->flags
= flags
;
1853 event
->reason
= reason
;
1859 * Generate internal events representing this touch event and enqueue them
1860 * on the event queue.
1862 * This function is not reentrant. Disable signals before calling.
1864 * @param device The device to generate the event for
1865 * @param type Event type, one of XI_TouchBegin, XI_TouchUpdate, XI_TouchEnd
1866 * @param touchid Touch point ID
1867 * @param flags Event modification flags
1868 * @param mask Valuator mask for valuators present for this event.
1871 QueueTouchEvents(DeviceIntPtr device
, int type
,
1872 uint32_t ddx_touchid
, int flags
, const ValuatorMask
*mask
)
1877 GetTouchEvents(InputEventList
, device
, ddx_touchid
, type
, flags
, mask
);
1878 queueEventList(device
, InputEventList
, nevents
);
1882 * Get events for a touch. Generates a TouchBegin event if end is not set and
1883 * the touch id is not active. Generates a TouchUpdate event if end is not set
1884 * and the touch id is active. Generates a TouchEnd event if end is set and the
1885 * touch id is active.
1887 * events is not NULL-terminated; the return value is the number of events.
1888 * The DDX is responsible for allocating the event structure in the first
1889 * place via GetMaximumEventsNum(), and for freeing it.
1891 * @param[out] events The list of events generated
1892 * @param dev The device to generate the events for
1893 * @param ddx_touchid The touch ID as assigned by the DDX
1894 * @param type XI_TouchBegin, XI_TouchUpdate or XI_TouchEnd
1895 * @param flags Event flags
1896 * @param mask_in Valuator information for this event
1899 GetTouchEvents(InternalEvent
*events
, DeviceIntPtr dev
, uint32_t ddx_touchid
,
1900 uint16_t type
, uint32_t flags
, const ValuatorMask
*mask_in
)
1902 ScreenPtr scr
= dev
->spriteInfo
->sprite
->hotPhys
.pScreen
;
1903 TouchClassPtr t
= dev
->touch
;
1904 ValuatorClassPtr v
= dev
->valuator
;
1906 CARD32 ms
= GetTimeInMillis();
1908 double screenx
= 0.0, screeny
= 0.0; /* desktop coordinate system */
1909 double devx
= 0.0, devy
= 0.0; /* desktop-wide in device coords */
1912 RawDeviceEvent
*raw
;
1913 DDXTouchPointInfoPtr ti
;
1914 int need_rawevent
= TRUE
;
1915 Bool emulate_pointer
= FALSE
;
1919 if (XSERVER_INPUT_EVENT_ENABLED()) {
1920 XSERVER_INPUT_EVENT(dev
->id
, type
, ddx_touchid
, flags
,
1921 mask_in
? mask_in
->last_bit
+ 1 : 0,
1922 mask_in
? mask_in
->mask
: NULL
,
1923 mask_in
? mask_in
->valuators
: NULL
);
1927 if (!dev
->enabled
|| !t
|| !v
)
1930 /* Find and/or create the DDX touch info */
1932 ti
= TouchFindByDDXID(dev
, ddx_touchid
, (type
== XI_TouchBegin
));
1934 ErrorFSigSafe("[dix] %s: unable to %s touch point %u\n", dev
->name
,
1935 type
== XI_TouchBegin
? "begin" : "find", ddx_touchid
);
1938 client_id
= ti
->client_id
;
1940 emulate_pointer
= ti
->emulate_pointer
;
1944 UpdateFromMaster(events
, dev
, DEVCHANGE_POINTER_EVENT
, &num_events
);
1946 valuator_mask_copy(&mask
, mask_in
);
1948 if (need_rawevent
) {
1949 raw
= &events
->raw_event
;
1952 init_raw(dev
, raw
, ms
, type
, client_id
);
1953 set_raw_valuators(raw
, &mask
, raw
->valuators
.data_raw
);
1956 event
= &events
->device_event
;
1959 init_device_event(event
, dev
, ms
);
1963 event
->type
= ET_TouchBegin
;
1964 /* If we're starting a touch, we must have x & y co-ordinates. */
1966 !valuator_mask_isset(mask_in
, 0) ||
1967 !valuator_mask_isset(mask_in
, 1)) {
1968 ErrorFSigSafe("%s: Attempted to start touch without x/y "
1969 "(driver bug)\n", dev
->name
);
1973 case XI_TouchUpdate
:
1974 event
->type
= ET_TouchUpdate
;
1975 if (!mask_in
|| valuator_mask_num_valuators(mask_in
) <= 0) {
1976 ErrorFSigSafe("%s: TouchUpdate with no valuators? Driver bug\n",
1981 event
->type
= ET_TouchEnd
;
1982 /* We can end the DDX touch here, since we don't use the active
1984 TouchEndDDXTouch(dev
, ti
);
1990 /* Get our screen event co-ordinates (root_x/root_y/event_x/event_y):
1991 * these come from the touchpoint in Absolute mode, or the sprite in
1993 if (t
->mode
== XIDirectTouch
) {
1994 for (i
= 0; i
< max(valuator_mask_size(&mask
), 2); i
++) {
1997 if (valuator_mask_fetch_double(&mask
, i
, &val
))
1998 valuator_mask_set_double(ti
->valuators
, i
, val
);
1999 /* If the device doesn't post new X and Y axis values,
2000 * use the last values posted.
2003 valuator_mask_fetch_double(ti
->valuators
, i
, &val
))
2004 valuator_mask_set_double(&mask
, i
, val
);
2007 transformAbsolute(dev
, &mask
);
2008 clipAbsolute(dev
, &mask
);
2011 screenx
= dev
->spriteInfo
->sprite
->hotPhys
.x
;
2012 screeny
= dev
->spriteInfo
->sprite
->hotPhys
.y
;
2015 set_raw_valuators(raw
, &mask
, raw
->valuators
.data
);
2017 /* Indirect device touch coordinates are not used for cursor positioning.
2018 * They are merely informational, and are provided in device coordinates.
2019 * The device sprite is used for positioning instead, and it is already
2021 if (t
->mode
== XIDirectTouch
)
2022 scr
= scale_to_desktop(dev
, &mask
, &devx
, &devy
, &screenx
, &screeny
);
2023 if (emulate_pointer
)
2024 scr
= positionSprite(dev
, Absolute
, &mask
,
2025 &devx
, &devy
, &screenx
, &screeny
, NULL
, NULL
);
2027 /* see fill_pointer_events for coordinate systems */
2028 if (emulate_pointer
)
2029 updateHistory(dev
, &mask
, ms
);
2031 clipValuators(dev
, &mask
);
2033 if (emulate_pointer
)
2034 storeLastValuators(dev
, &mask
, 0, 1, devx
, devy
);
2036 /* Update the MD's co-ordinates, which are always in desktop space. */
2037 if (emulate_pointer
&& !IsMaster(dev
) && !IsFloating(dev
)) {
2038 DeviceIntPtr master
= GetMaster(dev
, MASTER_POINTER
);
2040 master
->last
.valuators
[0] = screenx
;
2041 master
->last
.valuators
[1] = screeny
;
2044 event
->root
= scr
->root
->drawable
.id
;
2046 event_set_root_coordinates(event
, screenx
, screeny
);
2047 event
->touchid
= client_id
;
2048 event
->flags
= flags
;
2050 if (emulate_pointer
) {
2051 event
->flags
|= TOUCH_POINTER_EMULATED
;
2052 event
->detail
.button
= 1;
2055 set_valuators(dev
, event
, &mask
);
2056 for (i
= 0; i
< v
->numAxes
; i
++) {
2057 if (valuator_mask_isset(&mask
, i
))
2058 v
->axisVal
[i
] = valuator_mask_get(&mask
, i
);
2065 GetDixTouchEnd(InternalEvent
*ievent
, DeviceIntPtr dev
, TouchPointInfoPtr ti
,
2068 ScreenPtr scr
= dev
->spriteInfo
->sprite
->hotPhys
.pScreen
;
2069 DeviceEvent
*event
= &ievent
->device_event
;
2070 CARD32 ms
= GetTimeInMillis();
2072 BUG_WARN(!dev
->enabled
);
2074 init_device_event(event
, dev
, ms
);
2076 event
->sourceid
= ti
->sourceid
;
2077 event
->type
= ET_TouchEnd
;
2079 event
->root
= scr
->root
->drawable
.id
;
2081 /* Get screen event coordinates from the sprite. Is this really the best
2083 event_set_root_coordinates(event
,
2084 dev
->last
.valuators
[0],
2085 dev
->last
.valuators
[1]);
2086 event
->touchid
= ti
->client_id
;
2087 event
->flags
= flags
;
2089 if (flags
& TOUCH_POINTER_EMULATED
) {
2090 event
->flags
|= TOUCH_POINTER_EMULATED
;
2091 event
->detail
.button
= 1;
2096 * Synthesize a single motion event for the core pointer.
2098 * Used in cursor functions, e.g. when cursor confinement changes, and we need
2099 * to shift the pointer to get it inside the new bounds.
2102 PostSyntheticMotion(DeviceIntPtr pDev
,
2103 int x
, int y
, int screen
, unsigned long time
)
2108 /* Translate back to the sprite screen since processInputProc
2109 will translate from sprite screen to screen 0 upon reentry
2110 to the DIX layer. */
2111 if (!noPanoramiXExtension
) {
2112 x
+= screenInfo
.screens
[0]->x
- screenInfo
.screens
[screen
]->x
;
2113 y
+= screenInfo
.screens
[0]->y
- screenInfo
.screens
[screen
]->y
;
2117 memset(&ev
, 0, sizeof(DeviceEvent
));
2118 init_device_event(&ev
, pDev
, time
);
2121 ev
.type
= ET_Motion
;
2124 /* FIXME: MD/SD considerations? */
2125 (*pDev
->public.processInputProc
) ((InternalEvent
*) &ev
, pDev
);