2 * Copyright © 2006 Nokia Corporation
3 * Copyright © 2006-2007 Daniel Stone
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
24 * Author: Daniel Stone <daniel@fooishbar.org>
27 #ifdef HAVE_DIX_CONFIG_H
28 #include <dix-config.h>
32 #include <X11/keysym.h>
35 #include <X11/Xproto.h>
40 #include "scrnintstr.h"
41 #include "cursorstr.h"
42 #include "dixstruct.h"
44 #include "dixevents.h"
45 #include "mipointer.h"
48 #include <X11/extensions/XKBproto.h>
50 extern Bool
XkbCopyKeymap(XkbDescPtr src
, XkbDescPtr dst
, Bool sendNotifies
);
54 #include "panoramiX.h"
55 #include "panoramiXsrv.h"
58 #include <X11/extensions/XI.h>
59 #include <X11/extensions/XIproto.h>
60 #include "exglobals.h"
62 #include "exglobals.h"
63 #include "extnsionst.h"
66 /* Maximum number of valuators, divided by six, rounded up, to get number
68 #define MAX_VALUATOR_EVENTS 6
70 /* Number of motion history events to store. */
71 #define MOTION_HISTORY_SIZE 256
75 * Pick some arbitrary size for Xi motion history.
78 GetMotionHistorySize(void)
80 return MOTION_HISTORY_SIZE
;
84 set_key_down(DeviceIntPtr pDev
, int key_code
)
86 pDev
->key
->postdown
[key_code
>> 3] |= (1 << (key_code
& 7));
90 set_key_up(DeviceIntPtr pDev
, int key_code
)
92 pDev
->key
->postdown
[key_code
>> 3] &= ~(1 << (key_code
& 7));
96 key_is_down(DeviceIntPtr pDev
, int key_code
)
98 return pDev
->key
->postdown
[key_code
>> 3] >> (key_code
& 7);
102 * Allocate the motion history buffer.
105 AllocateMotionHistory(DeviceIntPtr pDev
)
107 if (pDev
->valuator
->motion
)
108 xfree(pDev
->valuator
->motion
);
110 if (pDev
->valuator
->numMotionEvents
< 1)
113 pDev
->valuator
->motion
= xalloc(((sizeof(INT32
) * pDev
->valuator
->numAxes
) +
115 pDev
->valuator
->numMotionEvents
);
116 pDev
->valuator
->first_motion
= 0;
117 pDev
->valuator
->last_motion
= 0;
122 * Dump the motion history between start and stop into the supplied buffer.
123 * Only records the event for a given screen in theory, but in practice, we
124 * sort of ignore this.
127 GetMotionHistory(DeviceIntPtr pDev
, xTimecoord
*buff
, unsigned long start
,
128 unsigned long stop
, ScreenPtr pScreen
)
130 char *ibuff
= NULL
, *obuff
= (char *) buff
;
133 /* The size of a single motion event. */
134 int size
= (sizeof(INT32
) * pDev
->valuator
->numAxes
) + sizeof(Time
);
136 if (!pDev
->valuator
|| !pDev
->valuator
->numMotionEvents
)
139 for (i
= pDev
->valuator
->first_motion
;
140 i
!= pDev
->valuator
->last_motion
;
141 i
= (i
+ 1) % pDev
->valuator
->numMotionEvents
) {
142 /* We index the input buffer by which element we're accessing, which
143 * is not monotonic, and the output buffer by how many events we've
145 ibuff
= (char *) pDev
->valuator
->motion
+ (i
* size
);
146 memcpy(¤t
, ibuff
, sizeof(Time
));
148 if (current
> stop
) {
151 else if (current
>= start
) {
152 memcpy(obuff
, ibuff
, size
);
163 * Update the motion history for a specific device, with the list of
167 updateMotionHistory(DeviceIntPtr pDev
, CARD32 ms
, int first_valuator
,
168 int num_valuators
, int *valuators
)
170 char *buff
= (char *) pDev
->valuator
->motion
;
172 if (!pDev
->valuator
->numMotionEvents
)
175 buff
+= ((sizeof(INT32
) * pDev
->valuator
->numAxes
) + sizeof(CARD32
)) *
176 pDev
->valuator
->last_motion
;
177 memcpy(buff
, &ms
, sizeof(Time
));
179 buff
+= sizeof(Time
);
180 bzero(buff
, sizeof(INT32
) * pDev
->valuator
->numAxes
);
182 buff
+= sizeof(INT32
) * first_valuator
;
183 memcpy(buff
, valuators
, sizeof(INT32
) * num_valuators
);
185 pDev
->valuator
->last_motion
= (pDev
->valuator
->last_motion
+ 1) %
186 pDev
->valuator
->numMotionEvents
;
188 /* If we're wrapping around, just keep the circular buffer going. */
189 if (pDev
->valuator
->first_motion
== pDev
->valuator
->last_motion
)
190 pDev
->valuator
->first_motion
= (pDev
->valuator
->first_motion
+ 1) %
191 pDev
->valuator
->numMotionEvents
;
198 * Returns the maximum number of events GetKeyboardEvents,
199 * GetKeyboardValuatorEvents, and GetPointerEvents will ever return.
201 * Should be used in DIX as:
202 * xEvent *events = xcalloc(sizeof(xEvent), GetMaximumEventsNum());
205 GetMaximumEventsNum(void) {
206 /* Two base events -- core and device, plus valuator events. Multiply
207 * by two if we're doing key repeats. */
208 int ret
= 2 + MAX_VALUATOR_EVENTS
;
219 /* Originally a part of xf86PostMotionEvent; modifies valuators
222 acceleratePointer(DeviceIntPtr pDev
, int first_valuator
, int num_valuators
,
227 int *px
= NULL
, *py
= NULL
;
229 if (!num_valuators
|| !valuators
)
232 if (first_valuator
== 0) {
236 if (first_valuator
<= 1 && num_valuators
>= (2 - first_valuator
)) {
237 dy
= valuators
[1 - first_valuator
];
238 py
= &valuators
[1 - first_valuator
];
244 if (pDev
->ptrfeed
&& pDev
->ptrfeed
->ctrl
.num
) {
245 /* modeled from xf86Events.c */
246 if (pDev
->ptrfeed
->ctrl
.threshold
) {
247 if ((abs(dx
) + abs(dy
)) >= pDev
->ptrfeed
->ctrl
.threshold
) {
248 pDev
->valuator
->dxremaind
= ((float)dx
*
249 (float)(pDev
->ptrfeed
->ctrl
.num
)) /
250 (float)(pDev
->ptrfeed
->ctrl
.den
) +
251 pDev
->valuator
->dxremaind
;
253 *px
= (int)pDev
->valuator
->dxremaind
;
254 pDev
->valuator
->dxremaind
= pDev
->valuator
->dxremaind
-
258 pDev
->valuator
->dyremaind
= ((float)dy
*
259 (float)(pDev
->ptrfeed
->ctrl
.num
)) /
260 (float)(pDev
->ptrfeed
->ctrl
.den
) +
261 pDev
->valuator
->dyremaind
;
263 *py
= (int)pDev
->valuator
->dyremaind
;
264 pDev
->valuator
->dyremaind
= pDev
->valuator
->dyremaind
-
270 mult
= pow((float)dx
* (float)dx
+ (float)dy
* (float)dy
,
271 ((float)(pDev
->ptrfeed
->ctrl
.num
) /
272 (float)(pDev
->ptrfeed
->ctrl
.den
) - 1.0) /
275 pDev
->valuator
->dxremaind
= mult
* (float)dx
+
276 pDev
->valuator
->dxremaind
;
277 *px
= (int)pDev
->valuator
->dxremaind
;
278 pDev
->valuator
->dxremaind
= pDev
->valuator
->dxremaind
-
282 pDev
->valuator
->dyremaind
= mult
* (float)dy
+
283 pDev
->valuator
->dyremaind
;
284 *py
= (int)pDev
->valuator
->dyremaind
;
285 pDev
->valuator
->dyremaind
= pDev
->valuator
->dyremaind
-
294 * Clip an axis to its bounds, which are declared in the call to
295 * InitValuatorAxisClassStruct.
298 clipAxis(DeviceIntPtr pDev
, int axisNum
, int *val
)
300 AxisInfoPtr axes
= pDev
->valuator
->axes
+ axisNum
;
302 if (*val
< axes
->min_value
)
303 *val
= axes
->min_value
;
304 if (axes
->max_value
>= 0 && *val
> axes
->max_value
)
305 *val
= axes
->max_value
;
309 * Clip every axis in the list of valuators to its bounds.
312 clipValuators(DeviceIntPtr pDev
, int first_valuator
, int num_valuators
,
315 AxisInfoPtr axes
= pDev
->valuator
->axes
+ first_valuator
;
318 for (i
= 0; i
< num_valuators
; i
++, axes
++)
319 clipAxis(pDev
, i
+ first_valuator
, &(valuators
[i
]));
324 * Fills events with valuator events for pDev, as given by the other
327 * FIXME: Need to fix ValuatorClassRec to store all the valuators as
328 * last posted, not just x and y; otherwise relative non-x/y
329 * valuators, though a very narrow use case, will be broken.
332 getValuatorEvents(xEvent
*events
, DeviceIntPtr pDev
, int first_valuator
,
333 int num_valuators
, int *valuators
) {
334 deviceValuator
*xv
= (deviceValuator
*) events
;
335 int i
= 0, final_valuator
= first_valuator
+ num_valuators
;
337 for (i
= first_valuator
; i
< final_valuator
; i
+= 6, xv
++, events
++) {
338 xv
->type
= DeviceValuator
;
339 xv
->first_valuator
= i
;
340 xv
->num_valuators
= num_valuators
;
341 xv
->deviceid
= pDev
->id
;
342 switch (final_valuator
- i
) {
344 xv
->valuator5
= valuators
[i
+ 5];
346 xv
->valuator4
= valuators
[i
+ 4];
348 xv
->valuator3
= valuators
[i
+ 3];
350 xv
->valuator2
= valuators
[i
+ 2];
352 xv
->valuator1
= valuators
[i
+ 1];
354 xv
->valuator0
= valuators
[i
];
357 if (i
+ 6 < final_valuator
)
358 xv
->deviceid
|= MORE_EVENTS
;
366 * Convenience wrapper around GetKeyboardValuatorEvents, that takes no
370 GetKeyboardEvents(xEvent
*events
, DeviceIntPtr pDev
, int type
, int key_code
) {
371 return GetKeyboardValuatorEvents(events
, pDev
, type
, key_code
, 0, 0, NULL
);
376 * Returns a set of keyboard events for KeyPress/KeyRelease, optionally
377 * also with valuator events. Handles Xi and XKB.
379 * events is not NULL-terminated; the return value is the number of events.
380 * The DDX is responsible for allocating the event structure in the first
381 * place via GetMaximumEventsNum(), and for freeing it.
383 * This function does not change the core keymap to that of the device;
384 * that is done by SwitchCoreKeyboard, which is called from
385 * mieqProcessInputEvents. If replacing that function, take care to call
386 * SetCoreKeyboard before processInputProc, so keymaps are altered to suit.
388 * Note that this function recurses! If called for non-XKB, a repeating
389 * key press will trigger a matching KeyRelease, as well as the
393 GetKeyboardValuatorEvents(xEvent
*events
, DeviceIntPtr pDev
, int type
,
394 int key_code
, int first_valuator
,
395 int num_valuators
, int *valuators
) {
398 KeySym
*map
= pDev
->key
->curKeySyms
.map
;
399 KeySym sym
= map
[key_code
* pDev
->key
->curKeySyms
.mapWidth
];
400 deviceKeyButtonPointer
*kbp
= NULL
;
405 if (type
!= KeyPress
&& type
!= KeyRelease
)
408 if (!pDev
->key
|| !pDev
->focus
|| !pDev
->kbdfeed
||
409 (pDev
->coreEvents
&& !inputInfo
.keyboard
->key
))
412 if (pDev
->coreEvents
)
418 if ((num_valuators
/ 6) + 1 > MAX_VALUATOR_EVENTS
)
419 num_valuators
= MAX_VALUATOR_EVENTS
;
420 numEvents
+= (num_valuators
/ 6) + 1;
432 if (type
== KeyRelease
)
434 else if (type
== KeyPress
&& key_is_down(pDev
, key_code
))
439 /* Handle core repeating, via press/release/press/release.
440 * FIXME: In theory, if you're repeating with two keyboards in non-XKB,
441 * you could get unbalanced events here. */
442 if (type
== KeyPress
&& key_is_down(pDev
, key_code
)) {
443 if (!pDev
->kbdfeed
->ctrl
.autoRepeat
||
444 pDev
->key
->modifierMap
[key_code
] ||
445 !(pDev
->kbdfeed
->ctrl
.autoRepeats
[key_code
>> 3]
446 & (1 << (key_code
& 7))))
453 numEvents
+= GetKeyboardValuatorEvents(events
, pDev
,
454 KeyRelease
, key_code
,
455 first_valuator
, num_valuators
,
461 ms
= GetTimeInMillis();
463 if (pDev
->coreEvents
) {
464 events
->u
.keyButtonPointer
.time
= ms
;
465 events
->u
.u
.type
= type
;
466 events
->u
.u
.detail
= key_code
;
467 if (type
== KeyPress
)
468 set_key_down(inputInfo
.keyboard
, key_code
);
469 else if (type
== KeyRelease
)
470 set_key_up(inputInfo
.keyboard
, key_code
);
474 kbp
= (deviceKeyButtonPointer
*) events
;
476 kbp
->deviceid
= pDev
->id
;
477 kbp
->detail
= key_code
;
478 if (type
== KeyPress
) {
479 kbp
->type
= DeviceKeyPress
;
480 set_key_down(pDev
, key_code
);
482 else if (type
== KeyRelease
) {
483 kbp
->type
= DeviceKeyRelease
;
484 set_key_up(pDev
, key_code
);
489 kbp
->deviceid
|= MORE_EVENTS
;
490 clipValuators(pDev
, first_valuator
, num_valuators
, valuators
);
491 events
= getValuatorEvents(events
, pDev
, first_valuator
,
492 num_valuators
, valuators
);
500 * Generate a series of xEvents (returned in xE) representing pointer
501 * motion, or button presses. Xi and XKB-aware.
503 * events is not NULL-terminated; the return value is the number of events.
504 * The DDX is responsible for allocating the event structure in the first
505 * place via GetMaximumEventsNum(), and for freeing it.
508 GetPointerEvents(xEvent
*events
, DeviceIntPtr pDev
, int type
, int buttons
,
509 int flags
, int first_valuator
, int num_valuators
,
511 int num_events
= 0, final_valuator
= 0;
513 deviceKeyButtonPointer
*kbp
= NULL
;
514 /* Thanks to a broken lib, we _always_ have to chase DeviceMotionNotifies
515 * with DeviceValuators. */
516 Bool sendValuators
= (type
== MotionNotify
|| flags
& POINTER_ABSOLUTE
);
517 DeviceIntPtr cp
= inputInfo
.pointer
;
519 Bool coreOnly
= (pDev
== inputInfo
.pointer
);
522 if (type
!= MotionNotify
&& type
!= ButtonPress
&& type
!= ButtonRelease
)
525 if ((type
== ButtonPress
|| type
== ButtonRelease
) && !pDev
->button
)
528 /* FIXME: I guess it should, in theory, be possible to post button events
529 * from devices without valuators. */
533 if (!coreOnly
&& pDev
->coreEvents
)
538 if (type
== MotionNotify
&& num_valuators
<= 0)
541 /* Do we need to send a DeviceValuator event? */
542 if (!coreOnly
&& sendValuators
) {
543 if ((((num_valuators
- 1) / 6) + 1) > MAX_VALUATOR_EVENTS
)
544 num_valuators
= MAX_VALUATOR_EVENTS
* 6;
545 num_events
+= ((num_valuators
- 1) / 6) + 1;
548 final_valuator
= num_valuators
+ first_valuator
;
551 if (first_valuator
< 0 || final_valuator
> pDev
->valuator
->numAxes
)
554 ms
= GetTimeInMillis();
556 /* Set x and y based on whether this is absolute or relative, and
557 * accelerate if we need to. */
558 if (flags
& POINTER_ABSOLUTE
) {
559 if (num_valuators
>= 1 && first_valuator
== 0) {
563 if (pDev
->coreEvents
)
564 x
= cp
->valuator
->lastx
;
566 x
= pDev
->valuator
->lastx
;
569 if (first_valuator
<= 1 && num_valuators
>= (2 - first_valuator
)) {
570 y
= valuators
[1 - first_valuator
];
573 if (pDev
->coreEvents
)
574 y
= cp
->valuator
->lasty
;
576 y
= pDev
->valuator
->lasty
;
580 if (flags
& POINTER_ACCELERATE
)
581 acceleratePointer(pDev
, first_valuator
, num_valuators
,
584 if (pDev
->coreEvents
) {
585 if (first_valuator
== 0 && num_valuators
>= 1)
586 x
= cp
->valuator
->lastx
+ valuators
[0];
588 x
= cp
->valuator
->lastx
;
590 if (first_valuator
<= 1 && num_valuators
>= (2 - first_valuator
))
591 y
= cp
->valuator
->lasty
+ valuators
[1 - first_valuator
];
593 y
= cp
->valuator
->lasty
;
596 if (first_valuator
== 0 && num_valuators
>= 1)
597 x
= pDev
->valuator
->lastx
+ valuators
[0];
599 x
= pDev
->valuator
->lastx
;
601 if (first_valuator
<= 1 && num_valuators
>= (2 - first_valuator
))
602 y
= pDev
->valuator
->lasty
+ valuators
[1 - first_valuator
];
604 y
= pDev
->valuator
->lasty
;
608 /* Clip both x and y to the defined limits (usually co-ord space limit). */
609 clipAxis(pDev
, 0, &x
);
610 clipAxis(pDev
, 1, &y
);
612 /* This takes care of crossing screens for us, as well as clipping
613 * to the current screen. Right now, we only have one history buffer,
614 * so we don't set this for both the device and core.*/
615 miPointerSetPosition(pDev
, &x
, &y
, ms
);
617 /* Drop x and y back into the valuators list, if they were originally
619 if (first_valuator
== 0 && num_valuators
>= 1)
621 if (first_valuator
<= 1 && num_valuators
>= (2 - first_valuator
))
622 valuators
[1 - first_valuator
] = y
;
624 updateMotionHistory(pDev
, ms
, first_valuator
, num_valuators
, valuators
);
626 if (pDev
->coreEvents
) {
627 cp
->valuator
->lastx
= x
;
628 cp
->valuator
->lasty
= y
;
630 pDev
->valuator
->lastx
= x
;
631 pDev
->valuator
->lasty
= y
;
633 /* for some reason inputInfo.pointer does not have coreEvents set */
634 if (coreOnly
|| pDev
->coreEvents
) {
635 events
->u
.u
.type
= type
;
636 events
->u
.keyButtonPointer
.time
= ms
;
637 events
->u
.keyButtonPointer
.rootX
= x
;
638 events
->u
.keyButtonPointer
.rootY
= y
;
640 if (type
== ButtonPress
|| type
== ButtonRelease
) {
641 /* We hijack SetPointerMapping to work on all core-sending
642 * devices, so we use the device-specific map here instead of
644 events
->u
.u
.detail
= pDev
->button
->map
[buttons
];
647 events
->u
.u
.detail
= 0;
654 kbp
= (deviceKeyButtonPointer
*) events
;
656 kbp
->deviceid
= pDev
->id
;
658 if (type
== MotionNotify
) {
659 kbp
->type
= DeviceMotionNotify
;
662 if (type
== ButtonPress
)
663 kbp
->type
= DeviceButtonPress
;
664 else if (type
== ButtonRelease
)
665 kbp
->type
= DeviceButtonRelease
;
666 kbp
->detail
= pDev
->button
->map
[buttons
];
674 kbp
->deviceid
|= MORE_EVENTS
;
675 clipValuators(pDev
, first_valuator
, num_valuators
, valuators
);
676 events
= getValuatorEvents(events
, pDev
, first_valuator
,
677 num_valuators
, valuators
);
686 * Post ProximityIn/ProximityOut events, accompanied by valuators.
688 * events is not NULL-terminated; the return value is the number of events.
689 * The DDX is responsible for allocating the event structure in the first
690 * place via GetMaximumEventsNum(), and for freeing it.
693 GetProximityEvents(xEvent
*events
, DeviceIntPtr pDev
, int type
,
694 int first_valuator
, int num_valuators
, int *valuators
)
697 deviceKeyButtonPointer
*kbp
= (deviceKeyButtonPointer
*) events
;
700 if (type
!= ProximityIn
&& type
!= ProximityOut
)
706 /* Do we need to send a DeviceValuator event? */
707 if ((pDev
->valuator
->mode
& 1) == Relative
)
711 if ((((num_valuators
- 1) / 6) + 1) > MAX_VALUATOR_EVENTS
)
712 num_valuators
= MAX_VALUATOR_EVENTS
* 6;
713 num_events
+= ((num_valuators
- 1) / 6) + 1;
717 if (first_valuator
< 0 ||
718 (num_valuators
+ first_valuator
) > pDev
->valuator
->numAxes
)
722 kbp
->deviceid
= pDev
->id
;
724 kbp
->time
= GetTimeInMillis();
727 kbp
->deviceid
|= MORE_EVENTS
;
729 clipValuators(pDev
, first_valuator
, num_valuators
, valuators
);
730 events
= getValuatorEvents(events
, pDev
, first_valuator
,
731 num_valuators
, valuators
);
739 * Note that pDev was the last device to send a core event. This function
740 * copies the complete keymap from the originating device to the core
741 * device, and makes sure the appropriate notifications are generated.
743 * Call this just before processInputProc.
746 SwitchCoreKeyboard(DeviceIntPtr pDev
)
748 KeyClassPtr ckeyc
= inputInfo
.keyboard
->key
;
751 if (inputInfo
.keyboard
->devPrivates
[CoreDevicePrivatesIndex
].ptr
!= pDev
) {
752 memcpy(ckeyc
->modifierMap
, pDev
->key
->modifierMap
, MAP_LENGTH
);
753 if (ckeyc
->modifierKeyMap
)
754 xfree(ckeyc
->modifierKeyMap
);
755 ckeyc
->modifierKeyMap
= xalloc(8 * pDev
->key
->maxKeysPerModifier
);
756 memcpy(ckeyc
->modifierKeyMap
, pDev
->key
->modifierKeyMap
,
757 (8 * pDev
->key
->maxKeysPerModifier
));
759 ckeyc
->maxKeysPerModifier
= pDev
->key
->maxKeysPerModifier
;
760 ckeyc
->curKeySyms
.minKeyCode
= pDev
->key
->curKeySyms
.minKeyCode
;
761 ckeyc
->curKeySyms
.maxKeyCode
= pDev
->key
->curKeySyms
.maxKeyCode
;
762 SetKeySymsMap(&ckeyc
->curKeySyms
, &pDev
->key
->curKeySyms
);
765 * Copy state from the extended keyboard to core. If you omit this,
766 * holding Ctrl on keyboard one, and pressing Q on keyboard two, will
767 * cause your app to quit. This feels wrong to me, hence the below
770 * XXX: If you synthesise core modifier events, the state will get
771 * clobbered here. You'll have to work out something sensible
772 * to fix that. Good luck.
775 #define KEYBOARD_MASK (ShiftMask | LockMask | ControlMask | Mod1Mask | \
776 Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask)
777 ckeyc
->state
&= ~(KEYBOARD_MASK
);
778 ckeyc
->state
|= (pDev
->key
->state
& KEYBOARD_MASK
);
780 for (i
= 0; i
< 8; i
++)
781 ckeyc
->modifierKeyCount
[i
] = pDev
->key
->modifierKeyCount
[i
];
784 if (!noXkbExtension
&& pDev
->key
->xkbInfo
&& pDev
->key
->xkbInfo
->desc
) {
785 if (!XkbCopyKeymap(pDev
->key
->xkbInfo
->desc
, ckeyc
->xkbInfo
->desc
,
787 FatalError("Couldn't pivot keymap from device to core!\n");
791 SendMappingNotify(MappingKeyboard
, ckeyc
->curKeySyms
.minKeyCode
,
792 (ckeyc
->curKeySyms
.maxKeyCode
-
793 ckeyc
->curKeySyms
.minKeyCode
),
795 inputInfo
.keyboard
->devPrivates
[CoreDevicePrivatesIndex
].ptr
= pDev
;
801 * Note that pDev was the last function to send a core pointer event.
804 * Call this just before processInputProc.
807 SwitchCorePointer(DeviceIntPtr pDev
)
809 if (inputInfo
.pointer
->devPrivates
[CoreDevicePrivatesIndex
].ptr
!= pDev
)
810 inputInfo
.pointer
->devPrivates
[CoreDevicePrivatesIndex
].ptr
= pDev
;
815 * Synthesize a single motion event for the core pointer.
817 * Used in cursor functions, e.g. when cursor confinement changes, and we need
818 * to shift the pointer to get it inside the new bounds.
821 PostSyntheticMotion(int x
, int y
, int screen
, unsigned long time
)
826 /* Translate back to the sprite screen since processInputProc
827 will translate from sprite screen to screen 0 upon reentry
829 if (!noPanoramiXExtension
) {
830 x
+= panoramiXdataPtr
[0].x
- panoramiXdataPtr
[screen
].x
;
831 y
+= panoramiXdataPtr
[0].y
- panoramiXdataPtr
[screen
].y
;
835 memset(&xE
, 0, sizeof(xEvent
));
836 xE
.u
.u
.type
= MotionNotify
;
837 xE
.u
.keyButtonPointer
.rootX
= x
;
838 xE
.u
.keyButtonPointer
.rootY
= y
;
839 xE
.u
.keyButtonPointer
.time
= time
;
841 (*inputInfo
.pointer
->public.processInputProc
)(&xE
, inputInfo
.pointer
, 1);