Bug Summary

File:xkb/xkbActions.c
Location:line 372, column 50
Description:Dereference of null pointer

Annotated Source Code

1/************************************************************
2Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
3
4Permission to use, copy, modify, and distribute this
5software and its documentation for any purpose and without
6fee is hereby granted, provided that the above copyright
7notice appear in all copies and that both that copyright
8notice and this permission notice appear in supporting
9documentation, and that the name of Silicon Graphics not be
10used in advertising or publicity pertaining to distribution
11of the software without specific prior written permission.
12Silicon Graphics makes no representation about the suitability
13of this software for any purpose. It is provided "as is"
14without any express or implied warranty.
15
16SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
23THE USE OR PERFORMANCE OF THIS SOFTWARE.
24
25********************************************************/
26
27#ifdef HAVE_DIX_CONFIG_H1
28#include <dix-config.h>
29#endif
30
31#include <stdio.h>
32#include <math.h>
33#include <X11/X.h>
34#include <X11/Xproto.h>
35#include <X11/keysym.h>
36#include "misc.h"
37#include "inputstr.h"
38#include "exevents.h"
39#include "eventstr.h"
40#include <xkbsrv.h>
41#include "xkb.h"
42#include <ctype.h>
43#include "mi.h"
44#include "mipointer.h"
45#include "inpututils.h"
46#define EXTENSION_EVENT_BASE64 64
47
48DevPrivateKeyRec xkbDevicePrivateKeyRec;
49
50static void XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags, int x,
51 int y);
52
53void
54xkbUnwrapProc(DeviceIntPtr device, DeviceHandleProc proc, void *data)
55{
56 xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device)((xkbDeviceInfoPtr)dixLookupPrivate(&(device)->devPrivates
, (&xkbDevicePrivateKeyRec)))
;
57 ProcessInputProc backupproc;
58
59 if (xkbPrivPtr->unwrapProc)
60 xkbPrivPtr->unwrapProc = NULL((void*)0);
61
62 UNWRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, backupproc)backupproc = device->public.realInputProc; if (device->
public.processInputProc == device->public.realInputProc) device
->public.processInputProc = xkbPrivPtr->realInputProc; device
->public.realInputProc = xkbPrivPtr->realInputProc; device
->unwrapProc = xkbPrivPtr->unwrapProc;
;
63 proc(device, data);
64 COND_WRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, backupproc, xkbUnwrapProc)if (device->public.processInputProc == device->public.realInputProc
) device->public.processInputProc = backupproc; xkbPrivPtr
->processInputProc = xkbPrivPtr->realInputProc = device
->public.realInputProc; device->public.realInputProc = backupproc
; xkbPrivPtr->unwrapProc = device->unwrapProc; device->
unwrapProc = xkbUnwrapProc;
;
65}
66
67Bool
68XkbInitPrivates(void)
69{
70 return dixRegisterPrivateKey(&xkbDevicePrivateKeyRec, PRIVATE_DEVICE,
71 sizeof(xkbDeviceInfoRec));
72}
73
74void
75XkbSetExtension(DeviceIntPtr device, ProcessInputProc proc)
76{
77 xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device)((xkbDeviceInfoPtr)dixLookupPrivate(&(device)->devPrivates
, (&xkbDevicePrivateKeyRec)))
;
78
79 WRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, proc, xkbUnwrapProc)device->public.processInputProc = proc; xkbPrivPtr->processInputProc
= xkbPrivPtr->realInputProc = device->public.realInputProc
; device->public.realInputProc = proc; xkbPrivPtr->unwrapProc
= device->unwrapProc; device->unwrapProc = xkbUnwrapProc
;
;
80}
81
82/***====================================================================***/
83
84static XkbAction
85_FixUpAction(XkbDescPtr xkb, XkbAction *act)
86{
87 static XkbAction fake;
88
89 if (XkbIsPtrAction(act)(((act)->type>=0x07)&&((act)->type<=0x0a)
)
&&
90 (!(xkb->ctrls->enabled_ctrls & XkbMouseKeysMask(1L << 4)))) {
91 fake.type = XkbSA_NoAction0x00;
92 return fake;
93 }
94 if (xkb->ctrls->enabled_ctrls & XkbStickyKeysMask(1L << 3)) {
95 if (act->any.type == XkbSA_SetMods0x01) {
96 fake.mods.type = XkbSA_LatchMods0x02;
97 fake.mods.mask = act->mods.mask;
98 if (XkbAX_NeedOption(xkb->ctrls, XkbAX_LatchToLockMask)((xkb->ctrls)->ax_options&((1L << 7))))
99 fake.mods.flags = XkbSA_ClearLocks(1L << 0) | XkbSA_LatchToLock(1L << 1);
100 else
101 fake.mods.flags = XkbSA_ClearLocks(1L << 0);
102 return fake;
103 }
104 if (act->any.type == XkbSA_SetGroup0x04) {
105 fake.group.type = XkbSA_LatchGroup0x05;
106 if (XkbAX_NeedOption(xkb->ctrls, XkbAX_LatchToLockMask)((xkb->ctrls)->ax_options&((1L << 7))))
107 fake.group.flags = XkbSA_ClearLocks(1L << 0) | XkbSA_LatchToLock(1L << 1);
108 else
109 fake.group.flags = XkbSA_ClearLocks(1L << 0);
110 XkbSASetGroup(&fake.group, XkbSAGroup(&act->group))((&fake.group)->group_XXX=((((int) (((&act->group
)->group_XXX) & 0x80 ? (((&act->group)->group_XXX
) | (~0xff)) : (((&act->group)->group_XXX) & 0x7f
))))))
;
111 return fake;
112 }
113 }
114 return *act;
115}
116
117static XkbAction
118XkbGetKeyAction(XkbSrvInfoPtr xkbi, XkbStatePtr xkbState, CARD8 key)
119{
120 int effectiveGroup;
121 int col;
122 XkbDescPtr xkb;
123 XkbKeyTypePtr type;
124 XkbAction *pActs;
125 static XkbAction fake;
126
127 xkb = xkbi->desc;
128 if (!XkbKeyHasActions(xkb, key)(!!(xkb)->server->key_acts[(key)]) || !XkbKeycodeInRange(xkb, key)((key) >= (xkb)->min_key_code && (key) <= (xkb
)->max_key_code)
) {
129 fake.type = XkbSA_NoAction0x00;
130 return fake;
131 }
132 pActs = XkbKeyActionsPtr(xkb, key)((&((xkb)->server)->acts[((xkb)->server)->key_acts
[((key))]]))
;
133 col = 0;
134
135 effectiveGroup = XkbGetEffectiveGroup(xkbi, xkbState, key);
136 if (effectiveGroup != XkbGroup1Index0)
137 col += (effectiveGroup * XkbKeyGroupsWidth(xkb, key)((((xkb)->map)->key_sym_map[((key))].width)));
138
139 type = XkbKeyKeyType(xkb, key, effectiveGroup)((&((xkb)->map)->types[((((xkb)->map))->key_sym_map
[(((key)))].kt_index[(((effectiveGroup))) & 0x3])]))
;
140 if (type->map != NULL((void*)0)) {
141 register unsigned i, mods;
142 register XkbKTMapEntryPtr entry;
143
144 mods = xkbState->mods & type->mods.mask;
145 for (entry = type->map, i = 0; i < type->map_count; i++, entry++) {
146 if ((entry->active) && (entry->mods.mask == mods)) {
147 col += entry->level;
148 break;
149 }
150 }
151 }
152 if (pActs[col].any.type == XkbSA_NoAction0x00)
153 return pActs[col];
154 fake = _FixUpAction(xkb, &pActs[col]);
155 return fake;
156}
157
158static XkbAction
159XkbGetButtonAction(DeviceIntPtr kbd, DeviceIntPtr dev, int button)
160{
161 XkbAction fake;
162
163 if ((dev->button) && (dev->button->xkb_acts)) {
164 if (dev->button->xkb_acts[button - 1].any.type != XkbSA_NoAction0x00) {
165 fake = _FixUpAction(kbd->key->xkbInfo->desc,
166 &dev->button->xkb_acts[button - 1]);
167 return fake;
168 }
169 }
170 fake.any.type = XkbSA_NoAction0x00;
171 return fake;
172}
173
174/***====================================================================***/
175
176#define SYNTHETIC_KEYCODE1 1
177#define BTN_ACT_FLAG0x100 0x100
178
179static int
180_XkbFilterSetState(XkbSrvInfoPtr xkbi,
181 XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
182{
183 if (filter->keycode == 0) { /* initial press */
184 AccessXCancelRepeatKey(xkbi, keycode);
185 filter->keycode = keycode;
186 filter->active = 1;
187 filter->filterOthers = ((pAction->mods.mask & XkbSA_ClearLocks(1L << 0)) != 0);
188 filter->priv = 0;
189 filter->filter = _XkbFilterSetState;
190 if (pAction->type == XkbSA_SetMods0x01) {
191 filter->upAction = *pAction;
192 xkbi->setMods = pAction->mods.mask;
193 }
194 else {
195 xkbi->groupChange = XkbSAGroup(&pAction->group)(((int) (((&pAction->group)->group_XXX) & 0x80 ?
(((&pAction->group)->group_XXX) | (~0xff)) : (((&
pAction->group)->group_XXX) & 0x7f))))
;
196 if (pAction->group.flags & XkbSA_GroupAbsolute(1L << 2))
197 xkbi->groupChange -= xkbi->state.base_group;
198 filter->upAction = *pAction;
199 XkbSASetGroup(&filter->upAction.group, xkbi->groupChange)((&filter->upAction.group)->group_XXX=(xkbi->groupChange
))
;
200 }
201 }
202 else if (filter->keycode == keycode) {
203 if (filter->upAction.type == XkbSA_SetMods0x01) {
204 xkbi->clearMods = filter->upAction.mods.mask;
205 if (filter->upAction.mods.flags & XkbSA_ClearLocks(1L << 0)) {
206 xkbi->state.locked_mods &= ~filter->upAction.mods.mask;
207 }
208 }
209 else {
210 if (filter->upAction.group.flags & XkbSA_ClearLocks(1L << 0)) {
211 xkbi->state.locked_group = 0;
212 }
213 xkbi->groupChange = -XkbSAGroup(&filter->upAction.group)(((int) (((&filter->upAction.group)->group_XXX) &
0x80 ? (((&filter->upAction.group)->group_XXX) | (
~0xff)) : (((&filter->upAction.group)->group_XXX) &
0x7f))))
;
214 }
215 filter->active = 0;
216 }
217 else {
218 filter->upAction.mods.flags &= ~XkbSA_ClearLocks(1L << 0);
219 filter->filterOthers = 0;
220 }
221 return 1;
222}
223
224#define LATCH_KEY_DOWN1 1
225#define LATCH_PENDING2 2
226
227static int
228_XkbFilterLatchState(XkbSrvInfoPtr xkbi,
229 XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
230{
231
232 if (filter->keycode == 0) { /* initial press */
233 AccessXCancelRepeatKey(xkbi,keycode);
234 filter->keycode = keycode;
235 filter->active = 1;
236 filter->filterOthers = 1;
237 filter->priv = LATCH_KEY_DOWN1;
238 filter->filter = _XkbFilterLatchState;
239 if (pAction->type == XkbSA_LatchMods0x02) {
240 filter->upAction = *pAction;
241 xkbi->setMods = pAction->mods.mask;
242 }
243 else {
244 xkbi->groupChange = XkbSAGroup(&pAction->group)(((int) (((&pAction->group)->group_XXX) & 0x80 ?
(((&pAction->group)->group_XXX) | (~0xff)) : (((&
pAction->group)->group_XXX) & 0x7f))))
;
245 if (pAction->group.flags & XkbSA_GroupAbsolute(1L << 2))
246 xkbi->groupChange -= xkbi->state.base_group;
247 filter->upAction = *pAction;
248 XkbSASetGroup(&filter->upAction.group, xkbi->groupChange)((&filter->upAction.group)->group_XXX=(xkbi->groupChange
))
;
249 }
250 }
251 else if (pAction && (filter->priv == LATCH_PENDING2)) {
252 if (((1 << pAction->type) & XkbSA_BreakLatch((1<<0x00)|(1<<0x08)|(1<<0x09)| (1<<0x0c
)|(1<<0x0d)|(1<<0x0e)| (1<<0x0f)|(1<<
0x10)| (1<<0x11)|(1<<0x12)|(1<<0x13))
) != 0) {
253 filter->active = 0;
254 /* If one latch is broken, all latches are broken, so it's no use
255 to find out which particular latch this filter tracks. */
256 xkbi->state.latched_mods = 0;
257 xkbi->state.latched_group = 0;
258 }
259 }
260 else if (filter->keycode == keycode && filter->priv != LATCH_PENDING2){
261 /* The test above for LATCH_PENDING skips subsequent releases of the
262 key after it has been released first time and the latch became
263 pending. */
264 XkbControlsPtr ctrls = xkbi->desc->ctrls;
265 int needBeep = ((ctrls->enabled_ctrls & XkbStickyKeysMask(1L << 3)) &&
266 XkbAX_NeedFeedback(ctrls, XkbAX_StickyKeysFBMask)((((ctrls))->enabled_ctrls&(1L << 8)) &&
(((ctrls))->ax_options&(((1L << 5)))))
);
267
268 if (filter->upAction.type == XkbSA_LatchMods0x02) {
269 unsigned char mask = filter->upAction.mods.mask;
270 unsigned char common;
271
272 xkbi->clearMods = mask;
273
274 /* ClearLocks */
275 common = mask & xkbi->state.locked_mods;
276 if ((filter->upAction.mods.flags & XkbSA_ClearLocks(1L << 0)) && common) {
277 mask &= ~common;
278 xkbi->state.locked_mods &= ~common;
279 if (needBeep)
280 XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_UNLOCK11,
281 XkbStickyKeysMask(1L << 3));
282 }
283 /* LatchToLock */
284 common = mask & xkbi->state.latched_mods;
285 if ((filter->upAction.mods.flags & XkbSA_LatchToLock(1L << 1)) && common) {
286 unsigned char newlocked;
287
288 mask &= ~common;
289 newlocked = common & ~xkbi->state.locked_mods;
290 if(newlocked){
291 xkbi->state.locked_mods |= newlocked;
292 if (needBeep)
293 XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LOCK10,
294 XkbStickyKeysMask(1L << 3));
295
296 }
297 xkbi->state.latched_mods &= ~common;
298 }
299 /* Latch remaining modifiers, if any. */
300 if (mask) {
301 xkbi->state.latched_mods |= mask;
302 filter->priv = LATCH_PENDING2;
303 if (needBeep)
304 XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LATCH9,
305 XkbStickyKeysMask(1L << 3));
306 }
307 }
308 else {
309 xkbi->groupChange = -XkbSAGroup(&filter->upAction.group)(((int) (((&filter->upAction.group)->group_XXX) &
0x80 ? (((&filter->upAction.group)->group_XXX) | (
~0xff)) : (((&filter->upAction.group)->group_XXX) &
0x7f))))
;
310 /* ClearLocks */
311 if ((filter->upAction.group.flags & XkbSA_ClearLocks(1L << 0)) &&
312 (xkbi->state.locked_group)) {
313 xkbi->state.locked_group = 0;
314 if (needBeep)
315 XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_UNLOCK11,
316 XkbStickyKeysMask(1L << 3));
317 }
318 /* LatchToLock */
319 else if ((filter->upAction.group.flags & XkbSA_LatchToLock(1L << 1))
320 && (xkbi->state.latched_group)) {
321 xkbi->state.locked_group += XkbSAGroup(&filter->upAction.group)(((int) (((&filter->upAction.group)->group_XXX) &
0x80 ? (((&filter->upAction.group)->group_XXX) | (
~0xff)) : (((&filter->upAction.group)->group_XXX) &
0x7f))))
;
322 xkbi->state.latched_group -= XkbSAGroup(&filter->upAction.group)(((int) (((&filter->upAction.group)->group_XXX) &
0x80 ? (((&filter->upAction.group)->group_XXX) | (
~0xff)) : (((&filter->upAction.group)->group_XXX) &
0x7f))))
;
323 if(XkbSAGroup(&filter->upAction.group)(((int) (((&filter->upAction.group)->group_XXX) &
0x80 ? (((&filter->upAction.group)->group_XXX) | (
~0xff)) : (((&filter->upAction.group)->group_XXX) &
0x7f))))
&& needBeep)
324 XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LOCK10,
325 XkbStickyKeysMask(1L << 3));
326 }
327 /* Latch group */
328 else if(XkbSAGroup(&filter->upAction.group)(((int) (((&filter->upAction.group)->group_XXX) &
0x80 ? (((&filter->upAction.group)->group_XXX) | (
~0xff)) : (((&filter->upAction.group)->group_XXX) &
0x7f))))
){
329 xkbi->state.latched_group += XkbSAGroup(&filter->upAction.group)(((int) (((&filter->upAction.group)->group_XXX) &
0x80 ? (((&filter->upAction.group)->group_XXX) | (
~0xff)) : (((&filter->upAction.group)->group_XXX) &
0x7f))))
;
330 filter->priv = LATCH_PENDING2;
331 if (needBeep)
332 XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LATCH9,
333 XkbStickyKeysMask(1L << 3));
334 }
335 }
336
337 if (filter->priv != LATCH_PENDING2)
338 filter->active = 0;
339 }
340 else if (pAction && (filter->priv == LATCH_KEY_DOWN1)) {
341 /* Latch was broken before it became pending: degrade to a
342 SetMods/SetGroup. */
343 if (filter->upAction.type == XkbSA_LatchMods0x02)
344 filter->upAction.type = XkbSA_SetMods0x01;
345 else
346 filter->upAction.type = XkbSA_SetGroup0x04;
347 filter->filter = _XkbFilterSetState;
348 filter->priv = 0;
349 return filter->filter(xkbi, filter, keycode, pAction);
350 }
351 return 1;
352}
353
354static int
355_XkbFilterLockState(XkbSrvInfoPtr xkbi,
356 XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
357{
358 if (filter->keycode == 0) /* initial press */
1
Taking true branch
359 AccessXCancelRepeatKey(xkbi, keycode);
360
361 if (pAction && (pAction->type == XkbSA_LockGroup0x06)) {
2
Assuming pointer value is null
362 if (pAction->group.flags & XkbSA_GroupAbsolute(1L << 2))
363 xkbi->state.locked_group = XkbSAGroup(&pAction->group)(((int) (((&pAction->group)->group_XXX) & 0x80 ?
(((&pAction->group)->group_XXX) | (~0xff)) : (((&
pAction->group)->group_XXX) & 0x7f))))
;
364 else
365 xkbi->state.locked_group += XkbSAGroup(&pAction->group)(((int) (((&pAction->group)->group_XXX) & 0x80 ?
(((&pAction->group)->group_XXX) | (~0xff)) : (((&
pAction->group)->group_XXX) & 0x7f))))
;
366 return 1;
367 }
368 if (filter->keycode == 0) { /* initial press */
3
Taking true branch
369 filter->keycode = keycode;
370 filter->active = 1;
371 filter->filterOthers = 0;
372 filter->priv = xkbi->state.locked_mods & pAction->mods.mask;
4
Dereference of null pointer
373 filter->filter = _XkbFilterLockState;
374 filter->upAction = *pAction;
375 if (!(filter->upAction.mods.flags & XkbSA_LockNoLock(1L << 0)))
376 xkbi->state.locked_mods |= pAction->mods.mask;
377 xkbi->setMods = pAction->mods.mask;
378 }
379 else if (filter->keycode == keycode) {
380 filter->active = 0;
381 xkbi->clearMods = filter->upAction.mods.mask;
382 if (!(filter->upAction.mods.flags & XkbSA_LockNoUnlock(1L << 1)))
383 xkbi->state.locked_mods &= ~filter->priv;
384 }
385 return 1;
386}
387
388#define ISO_KEY_DOWN0 0
389#define NO_ISO_LOCK1 1
390
391static int
392_XkbFilterISOLock(XkbSrvInfoPtr xkbi,
393 XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
394{
395
396 if (filter->keycode == 0) { /* initial press */
397 CARD8 flags = pAction->iso.flags;
398
399 filter->keycode = keycode;
400 filter->active = 1;
401 filter->filterOthers = 1;
402 filter->priv = ISO_KEY_DOWN0;
403 filter->upAction = *pAction;
404 filter->filter = _XkbFilterISOLock;
405 if (flags & XkbSA_ISODfltIsGroup(1L << 7)) {
406 xkbi->groupChange = XkbSAGroup(&pAction->iso)(((int) (((&pAction->iso)->group_XXX) & 0x80 ? (
((&pAction->iso)->group_XXX) | (~0xff)) : (((&pAction
->iso)->group_XXX) & 0x7f))))
;
407 xkbi->setMods = 0;
408 }
409 else {
410 xkbi->setMods = pAction->iso.mask;
411 xkbi->groupChange = 0;
412 }
413 if ((!(flags & XkbSA_ISONoAffectMods(1L << 6))) && (xkbi->state.base_mods)) {
414 filter->priv = NO_ISO_LOCK1;
415 xkbi->state.locked_mods ^= xkbi->state.base_mods;
416 }
417 if ((!(flags & XkbSA_ISONoAffectGroup(1L << 5))) && (xkbi->state.base_group)) {
418/* 6/22/93 (ef) -- lock groups if group key is down first */
419 }
420 if (!(flags & XkbSA_ISONoAffectPtr(1L << 4))) {
421/* 6/22/93 (ef) -- lock mouse buttons if they're down */
422 }
423 }
424 else if (filter->keycode == keycode) {
425 CARD8 flags = filter->upAction.iso.flags;
426
427 if (flags & XkbSA_ISODfltIsGroup(1L << 7)) {
428 xkbi->groupChange = -XkbSAGroup(&filter->upAction.iso)(((int) (((&filter->upAction.iso)->group_XXX) &
0x80 ? (((&filter->upAction.iso)->group_XXX) | (~0xff
)) : (((&filter->upAction.iso)->group_XXX) & 0x7f
))))
;
429 xkbi->clearMods = 0;
430 if (filter->priv == ISO_KEY_DOWN0)
431 xkbi->state.locked_group += XkbSAGroup(&filter->upAction.iso)(((int) (((&filter->upAction.iso)->group_XXX) &
0x80 ? (((&filter->upAction.iso)->group_XXX) | (~0xff
)) : (((&filter->upAction.iso)->group_XXX) & 0x7f
))))
;
432 }
433 else {
434 xkbi->clearMods = filter->upAction.iso.mask;
435 xkbi->groupChange = 0;
436 if (filter->priv == ISO_KEY_DOWN0)
437 xkbi->state.locked_mods ^= filter->upAction.iso.mask;
438 }
439 filter->active = 0;
440 }
441 else if (pAction) {
442 CARD8 flags = filter->upAction.iso.flags;
443
444 switch (pAction->type) {
445 case XkbSA_SetMods0x01:
446 case XkbSA_LatchMods0x02:
447 if (!(flags & XkbSA_ISONoAffectMods(1L << 6))) {
448 pAction->type = XkbSA_LockMods0x03;
449 filter->priv = NO_ISO_LOCK1;
450 }
451 break;
452 case XkbSA_SetGroup0x04:
453 case XkbSA_LatchGroup0x05:
454 if (!(flags & XkbSA_ISONoAffectGroup(1L << 5))) {
455 pAction->type = XkbSA_LockGroup0x06;
456 filter->priv = NO_ISO_LOCK1;
457 }
458 break;
459 case XkbSA_PtrBtn0x08:
460 if (!(flags & XkbSA_ISONoAffectPtr(1L << 4))) {
461 pAction->type = XkbSA_LockPtrBtn0x09;
462 filter->priv = NO_ISO_LOCK1;
463 }
464 break;
465 case XkbSA_SetControls0x0e:
466 if (!(flags & XkbSA_ISONoAffectCtrls(1L << 3))) {
467 pAction->type = XkbSA_LockControls0x0f;
468 filter->priv = NO_ISO_LOCK1;
469 }
470 break;
471 }
472 }
473 return 1;
474}
475
476static CARD32
477_XkbPtrAccelExpire(OsTimerPtr timer, CARD32 now, void *arg)
478{
479 XkbSrvInfoPtr xkbi = (XkbSrvInfoPtr) arg;
480 XkbControlsPtr ctrls = xkbi->desc->ctrls;
481 int dx, dy;
482
483 if (xkbi->mouseKey == 0)
484 return 0;
485
486 if (xkbi->mouseKeysAccel) {
487 if ((xkbi->mouseKeysCounter) < ctrls->mk_time_to_max) {
488 double step;
489
490 xkbi->mouseKeysCounter++;
491 step = xkbi->mouseKeysCurveFactor *
492 pow((double) xkbi->mouseKeysCounter, xkbi->mouseKeysCurve);
493 if (xkbi->mouseKeysDX < 0)
494 dx = floor(((double) xkbi->mouseKeysDX) * step);
495 else
496 dx = ceil(((double) xkbi->mouseKeysDX) * step);
497 if (xkbi->mouseKeysDY < 0)
498 dy = floor(((double) xkbi->mouseKeysDY) * step);
499 else
500 dy = ceil(((double) xkbi->mouseKeysDY) * step);
501 }
502 else {
503 dx = xkbi->mouseKeysDX * ctrls->mk_max_speed;
504 dy = xkbi->mouseKeysDY * ctrls->mk_max_speed;
505 }
506 if (xkbi->mouseKeysFlags & XkbSA_MoveAbsoluteX(1L << 1))
507 dx = xkbi->mouseKeysDX;
508 if (xkbi->mouseKeysFlags & XkbSA_MoveAbsoluteY(1L << 2))
509 dy = xkbi->mouseKeysDY;
510 }
511 else {
512 dx = xkbi->mouseKeysDX;
513 dy = xkbi->mouseKeysDY;
514 }
515 XkbFakePointerMotion(xkbi->device, xkbi->mouseKeysFlags, dx, dy);
516 return xkbi->desc->ctrls->mk_interval;
517}
518
519static int
520_XkbFilterPointerMove(XkbSrvInfoPtr xkbi,
521 XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
522{
523 int x, y;
524 Bool accel;
525
526 if (filter->keycode == 0) { /* initial press */
527 filter->keycode = keycode;
528 filter->active = 1;
529 filter->filterOthers = 0;
530 filter->priv = 0;
531 filter->filter = _XkbFilterPointerMove;
532 filter->upAction = *pAction;
533 xkbi->mouseKeysCounter = 0;
534 xkbi->mouseKey = keycode;
535 accel = ((pAction->ptr.flags & XkbSA_NoAcceleration(1L << 0)) == 0);
536 x = XkbPtrActionX(&pAction->ptr)(((short)((((&pAction->ptr)->high_XXX)<<8)|((
&pAction->ptr)->low_XXX))))
;
537 y = XkbPtrActionY(&pAction->ptr)(((short)((((&pAction->ptr)->high_YYY)<<8)|((
&pAction->ptr)->low_YYY))))
;
538 XkbFakePointerMotion(xkbi->device, pAction->ptr.flags, x, y);
539 AccessXCancelRepeatKey(xkbi, keycode);
540 xkbi->mouseKeysAccel = accel &&
541 (xkbi->desc->ctrls->enabled_ctrls & XkbMouseKeysAccelMask(1L << 5));
542 xkbi->mouseKeysFlags = pAction->ptr.flags;
543 xkbi->mouseKeysDX = XkbPtrActionX(&pAction->ptr)(((short)((((&pAction->ptr)->high_XXX)<<8)|((
&pAction->ptr)->low_XXX))))
;
544 xkbi->mouseKeysDY = XkbPtrActionY(&pAction->ptr)(((short)((((&pAction->ptr)->high_YYY)<<8)|((
&pAction->ptr)->low_YYY))))
;
545 xkbi->mouseKeyTimer = TimerSet(xkbi->mouseKeyTimer, 0,
546 xkbi->desc->ctrls->mk_delay,
547 _XkbPtrAccelExpire, (void *) xkbi);
548 }
549 else if (filter->keycode == keycode) {
550 filter->active = 0;
551 if (xkbi->mouseKey == keycode) {
552 xkbi->mouseKey = 0;
553 xkbi->mouseKeyTimer = TimerSet(xkbi->mouseKeyTimer, 0, 0,
554 NULL((void*)0), NULL((void*)0));
555 }
556 }
557 return 0;
558}
559
560static int
561_XkbFilterPointerBtn(XkbSrvInfoPtr xkbi,
562 XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
563{
564 if (filter->keycode == 0) { /* initial press */
565 int button = pAction->btn.button;
566
567 if (button == XkbSA_UseDfltButton0)
568 button = xkbi->desc->ctrls->mk_dflt_btn;
569
570 filter->keycode = keycode;
571 filter->active = 1;
572 filter->filterOthers = 0;
573 filter->priv = 0;
574 filter->filter = _XkbFilterPointerBtn;
575 filter->upAction = *pAction;
576 filter->upAction.btn.button = button;
577 switch (pAction->type) {
578 case XkbSA_LockPtrBtn0x09:
579 if (((xkbi->lockedPtrButtons & (1 << button)) == 0) &&
580 ((pAction->btn.flags & XkbSA_LockNoLock(1L << 0)) == 0)) {
581 xkbi->lockedPtrButtons |= (1 << button);
582 AccessXCancelRepeatKey(xkbi, keycode);
583 XkbFakeDeviceButton(xkbi->device, 1, button);
584 filter->upAction.type = XkbSA_NoAction0x00;
585 }
586 break;
587 case XkbSA_PtrBtn0x08:
588 {
589 register int i, nClicks;
590
591 AccessXCancelRepeatKey(xkbi, keycode);
592 if (pAction->btn.count > 0) {
593 nClicks = pAction->btn.count;
594 for (i = 0; i < nClicks; i++) {
595 XkbFakeDeviceButton(xkbi->device, 1, button);
596 XkbFakeDeviceButton(xkbi->device, 0, button);
597 }
598 filter->upAction.type = XkbSA_NoAction0x00;
599 }
600 else
601 XkbFakeDeviceButton(xkbi->device, 1, button);
602 }
603 break;
604 case XkbSA_SetPtrDflt0x0a:
605 {
606 XkbControlsPtr ctrls = xkbi->desc->ctrls;
607 XkbControlsRec old;
608 xkbControlsNotify cn;
609
610 old = *ctrls;
611 AccessXCancelRepeatKey(xkbi, keycode);
612 switch (pAction->dflt.affect) {
613 case XkbSA_AffectDfltBtn1:
614 if (pAction->dflt.flags & XkbSA_DfltBtnAbsolute(1L << 2))
615 ctrls->mk_dflt_btn = XkbSAPtrDfltValue(&pAction->dflt)(((int) (((&pAction->dflt)->valueXXX) & 0x80 ? (
((&pAction->dflt)->valueXXX) | (~0xff)) : (((&pAction
->dflt)->valueXXX) & 0x7f))))
;
616 else {
617 ctrls->mk_dflt_btn += XkbSAPtrDfltValue(&pAction->dflt)(((int) (((&pAction->dflt)->valueXXX) & 0x80 ? (
((&pAction->dflt)->valueXXX) | (~0xff)) : (((&pAction
->dflt)->valueXXX) & 0x7f))))
;
618 if (ctrls->mk_dflt_btn > 5)
619 ctrls->mk_dflt_btn = 5;
620 else if (ctrls->mk_dflt_btn < 1)
621 ctrls->mk_dflt_btn = 1;
622 }
623 break;
624 default:
625 ErrorF
626 ("Attempt to change unknown pointer default (%d) ignored\n",
627 pAction->dflt.affect);
628 break;
629 }
630 if (XkbComputeControlsNotify(xkbi->device,
631 &old, xkbi->desc->ctrls, &cn, FALSE0)) {
632 cn.keycode = keycode;
633 /* XXX: what about DeviceKeyPress? */
634 cn.eventType = KeyPress2;
635 cn.requestMajor = 0;
636 cn.requestMinor = 0;
637 XkbSendControlsNotify(xkbi->device, &cn);
638 }
639 }
640 break;
641 }
642 return 0;
643 }
644 else if (filter->keycode == keycode) {
645 int button = filter->upAction.btn.button;
646
647 switch (filter->upAction.type) {
648 case XkbSA_LockPtrBtn0x09:
649 if (((filter->upAction.btn.flags & XkbSA_LockNoUnlock(1L << 1)) != 0) ||
650 ((xkbi->lockedPtrButtons & (1 << button)) == 0)) {
651 break;
652 }
653 xkbi->lockedPtrButtons &= ~(1 << button);
654
655 if (IsMaster(xkbi->device)) {
656 XkbMergeLockedPtrBtns(xkbi->device);
657 /* One SD still has lock set, don't post event */
658 if ((xkbi->lockedPtrButtons & (1 << button)) != 0)
659 break;
660 }
661
662 /* fallthrough */
663 case XkbSA_PtrBtn0x08:
664 XkbFakeDeviceButton(xkbi->device, 0, button);
665 break;
666 }
667 filter->active = 0;
668 return 0;
669 }
670 return 1;
671}
672
673static int
674_XkbFilterControls(XkbSrvInfoPtr xkbi,
675 XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
676{
677 XkbControlsRec old;
678 XkbControlsPtr ctrls;
679 DeviceIntPtr kbd;
680 unsigned int change;
681 XkbEventCauseRec cause;
682
683 kbd = xkbi->device;
684 ctrls = xkbi->desc->ctrls;
685 old = *ctrls;
686 if (filter->keycode == 0) { /* initial press */
687 AccessXCancelRepeatKey(xkbi, keycode);
688 filter->keycode = keycode;
689 filter->active = 1;
690 filter->filterOthers = 0;
691 change = XkbActionCtrls(&pAction->ctrls)((((unsigned int)(&pAction->ctrls)->ctrls3)<<
24)| (((unsigned int)(&pAction->ctrls)->ctrls2)<<
16)| (((unsigned int)(&pAction->ctrls)->ctrls1)<<
8)| ((unsigned int) (&pAction->ctrls)->ctrls0))
;
692 filter->priv = change;
693 filter->filter = _XkbFilterControls;
694 filter->upAction = *pAction;
695
696 if (pAction->type == XkbSA_LockControls0x0f) {
697 filter->priv = (ctrls->enabled_ctrls & change);
698 change &= ~ctrls->enabled_ctrls;
699 }
700
701 if (change) {
702 xkbControlsNotify cn;
703 XkbSrvLedInfoPtr sli;
704
705 ctrls->enabled_ctrls |= change;
706 if (XkbComputeControlsNotify(kbd, &old, ctrls, &cn, FALSE0)) {
707 cn.keycode = keycode;
708 /* XXX: what about DeviceKeyPress? */
709 cn.eventType = KeyPress2;
710 cn.requestMajor = 0;
711 cn.requestMinor = 0;
712 XkbSendControlsNotify(kbd, &cn);
713 }
714
715 XkbSetCauseKey(&cause, keycode, KeyPress){ (&cause)->kc= (keycode),(&cause)->event= (2),
(&cause)->mjr= (&cause)->mnr= 0; (&cause)->
client= ((void*)0); }
;
716
717 /* If sticky keys were disabled, clear all locks and latches */
718 if ((old.enabled_ctrls & XkbStickyKeysMask(1L << 3)) &&
719 (!(ctrls->enabled_ctrls & XkbStickyKeysMask(1L << 3)))) {
720 XkbClearAllLatchesAndLocks(kbd, xkbi, FALSE0, &cause);
721 }
722 sli = XkbFindSrvLedInfo(kbd, XkbDfltXIClass0x0300, XkbDfltXIId0x0400, 0);
723 XkbUpdateIndicators(kbd, sli->usesControls, TRUE1, NULL((void*)0), &cause);
724 if (XkbAX_NeedFeedback(ctrls, XkbAX_FeatureFBMask)((((ctrls))->enabled_ctrls&(1L << 8)) &&
(((ctrls))->ax_options&(((1L << 2)))))
)
725 XkbDDXAccessXBeep(kbd, _BEEP_FEATURE_ON1, change);
726 }
727 }
728 else if (filter->keycode == keycode) {
729 change = filter->priv;
730 if (change) {
731 xkbControlsNotify cn;
732 XkbSrvLedInfoPtr sli;
733
734 ctrls->enabled_ctrls &= ~change;
735 if (XkbComputeControlsNotify(kbd, &old, ctrls, &cn, FALSE0)) {
736 cn.keycode = keycode;
737 cn.eventType = KeyRelease3;
738 cn.requestMajor = 0;
739 cn.requestMinor = 0;
740 XkbSendControlsNotify(kbd, &cn);
741 }
742
743 XkbSetCauseKey(&cause, keycode, KeyRelease){ (&cause)->kc= (keycode),(&cause)->event= (3),
(&cause)->mjr= (&cause)->mnr= 0; (&cause)->
client= ((void*)0); }
;
744 /* If sticky keys were disabled, clear all locks and latches */
745 if ((old.enabled_ctrls & XkbStickyKeysMask(1L << 3)) &&
746 (!(ctrls->enabled_ctrls & XkbStickyKeysMask(1L << 3)))) {
747 XkbClearAllLatchesAndLocks(kbd, xkbi, FALSE0, &cause);
748 }
749 sli = XkbFindSrvLedInfo(kbd, XkbDfltXIClass0x0300, XkbDfltXIId0x0400, 0);
750 XkbUpdateIndicators(kbd, sli->usesControls, TRUE1, NULL((void*)0), &cause);
751 if (XkbAX_NeedFeedback(ctrls, XkbAX_FeatureFBMask)((((ctrls))->enabled_ctrls&(1L << 8)) &&
(((ctrls))->ax_options&(((1L << 2)))))
)
752 XkbDDXAccessXBeep(kbd, _BEEP_FEATURE_OFF2, change);
753 }
754 filter->keycode = 0;
755 filter->active = 0;
756 }
757 return 1;
758}
759
760static int
761_XkbFilterActionMessage(XkbSrvInfoPtr xkbi,
762 XkbFilterPtr filter,
763 unsigned keycode, XkbAction *pAction)
764{
765 XkbMessageAction *pMsg;
766 DeviceIntPtr kbd;
767
768 if ((filter->keycode != 0) && (filter->keycode != keycode))
769 return 1;
770
771 /* This can happen if the key repeats, and the state (modifiers or group)
772 changes meanwhile. */
773 if ((filter->keycode == keycode) && pAction &&
774 (pAction->type != XkbSA_ActionMessage0x10))
775 return 1;
776
777 kbd = xkbi->device;
778 if (filter->keycode == 0) { /* initial press */
779 pMsg = &pAction->msg;
780 if ((pMsg->flags & XkbSA_MessageOnRelease(1L << 1)) ||
781 ((pMsg->flags & XkbSA_MessageGenKeyEvent(1L << 2)) == 0)) {
782 filter->keycode = keycode;
783 filter->active = 1;
784 filter->filterOthers = 0;
785 filter->priv = 0;
786 filter->filter = _XkbFilterActionMessage;
787 filter->upAction = *pAction;
788 }
789 if (pMsg->flags & XkbSA_MessageOnPress(1L << 0)) {
790 xkbActionMessage msg;
791
792 msg.keycode = keycode;
793 msg.press = 1;
794 msg.keyEventFollows =
795 ((pMsg->flags & XkbSA_MessageGenKeyEvent(1L << 2)) != 0);
796 memcpy((char *) msg.message, (char *) pMsg->message,__builtin___memcpy_chk ((char *) msg.message, (char *) pMsg->
message, 6, __builtin_object_size ((char *) msg.message, 0))
797 XkbActionMessageLength)__builtin___memcpy_chk ((char *) msg.message, (char *) pMsg->
message, 6, __builtin_object_size ((char *) msg.message, 0))
;
798 XkbSendActionMessage(kbd, &msg);
799 }
800 return ((pAction->msg.flags & XkbSA_MessageGenKeyEvent(1L << 2)) != 0);
801 }
802 else if (filter->keycode == keycode) {
803 pMsg = &filter->upAction.msg;
804 if (pAction == NULL((void*)0)) {
805 if (pMsg->flags & XkbSA_MessageOnRelease(1L << 1)) {
806 xkbActionMessage msg;
807
808 msg.keycode = keycode;
809 msg.press = 0;
810 msg.keyEventFollows =
811 ((pMsg->flags & XkbSA_MessageGenKeyEvent(1L << 2)) != 0);
812 memcpy((char *) msg.message, (char *) pMsg->message,__builtin___memcpy_chk ((char *) msg.message, (char *) pMsg->
message, 6, __builtin_object_size ((char *) msg.message, 0))
813 XkbActionMessageLength)__builtin___memcpy_chk ((char *) msg.message, (char *) pMsg->
message, 6, __builtin_object_size ((char *) msg.message, 0))
;
814 XkbSendActionMessage(kbd, &msg);
815 }
816 filter->keycode = 0;
817 filter->active = 0;
818 return ((pMsg->flags & XkbSA_MessageGenKeyEvent(1L << 2)) != 0);
819 } else if (memcmp(pMsg, pAction, 8) == 0) {
820 /* Repeat: If we send the same message, avoid multiple messages
821 on release from piling up. */
822 filter->keycode = 0;
823 filter->active = 0;
824 }
825 }
826 return 1;
827}
828
829static int
830_XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
831 XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
832{
833 DeviceEvent ev;
834 int x, y;
835 XkbStateRec old, old_prev;
836 unsigned mods, mask;
837 xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device)((xkbDeviceInfoPtr)dixLookupPrivate(&(xkbi->device)->
devPrivates, (&xkbDevicePrivateKeyRec)))
;
838 ProcessInputProc backupproc;
839
840 if ((filter->keycode != 0) && (filter->keycode != keycode))
841 return 1;
842
843 /* This can happen if the key repeats, and the state (modifiers or group)
844 changes meanwhile. */
845 if ((filter->keycode == keycode) && pAction &&
846 (pAction->type != XkbSA_RedirectKey0x11))
847 return 1;
848
849 /* never actually used uninitialised, but gcc isn't smart enough
850 * to work that out. */
851 memset(&old, 0, sizeof(old))__builtin___memset_chk (&old, 0, sizeof(old), __builtin_object_size
(&old, 0))
;
852 memset(&old_prev, 0, sizeof(old_prev))__builtin___memset_chk (&old_prev, 0, sizeof(old_prev), __builtin_object_size
(&old_prev, 0))
;
853 memset(&ev, 0, sizeof(ev))__builtin___memset_chk (&ev, 0, sizeof(ev), __builtin_object_size
(&ev, 0))
;
854
855 GetSpritePosition(xkbi->device, &x, &y);
856 ev.header = ET_Internal;
857 ev.length = sizeof(DeviceEvent);
858 ev.time = GetTimeInMillis();
859 ev.root_x = x;
860 ev.root_y = y;
861 /* redirect actions do not work across devices, therefore the following is
862 * correct: */
863 ev.deviceid = xkbi->device->id;
864 /* filter->priv must be set up by the caller for the initial press. */
865 ev.sourceid = filter->priv;
866
867 if (filter->keycode == 0) { /* initial press */
868 if ((pAction->redirect.new_key < xkbi->desc->min_key_code) ||
869 (pAction->redirect.new_key > xkbi->desc->max_key_code)) {
870 return 1;
871 }
872 filter->keycode = keycode;
873 filter->active = 1;
874 filter->filterOthers = 0;
875 filter->filter = _XkbFilterRedirectKey;
876 filter->upAction = *pAction;
877
878 ev.type = ET_KeyPress;
879 ev.detail.key = pAction->redirect.new_key;
880
881 mask = XkbSARedirectVModsMask(&pAction->redirect)((((unsigned int)(&pAction->redirect)->vmods_mask1)
<<8)| ((unsigned int)(&pAction->redirect)->vmods_mask0
))
;
882 mods = XkbSARedirectVMods(&pAction->redirect)((((unsigned int)(&pAction->redirect)->vmods1)<<
8)| ((unsigned int)(&pAction->redirect)->vmods0))
;
883 if (mask)
884 XkbVirtualModsToRealSrvXkbVirtualModsToReal(xkbi->desc, mask, &mask);
885 if (mods)
886 XkbVirtualModsToRealSrvXkbVirtualModsToReal(xkbi->desc, mods, &mods);
887 mask |= pAction->redirect.mods_mask;
888 mods |= pAction->redirect.mods;
889
890 if (mask || mods) {
891 old = xkbi->state;
892 old_prev = xkbi->prev_state;
893 xkbi->state.base_mods &= ~mask;
894 xkbi->state.base_mods |= (mods & mask);
895 xkbi->state.latched_mods &= ~mask;
896 xkbi->state.latched_mods |= (mods & mask);
897 xkbi->state.locked_mods &= ~mask;
898 xkbi->state.locked_mods |= (mods & mask);
899 XkbComputeDerivedState(xkbi);
900 xkbi->prev_state = xkbi->state;
901 }
902
903 UNWRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc)backupproc = xkbi->device->public.realInputProc; if (xkbi
->device->public.processInputProc == xkbi->device->
public.realInputProc) xkbi->device->public.processInputProc
= xkbPrivPtr->realInputProc; xkbi->device->public.realInputProc
= xkbPrivPtr->realInputProc; xkbi->device->unwrapProc
= xkbPrivPtr->unwrapProc;
;
904 xkbi->device->public.processInputProc((InternalEvent *) &ev,
905 xkbi->device);
906 COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc,if (xkbi->device->public.processInputProc == xkbi->device
->public.realInputProc) xkbi->device->public.processInputProc
= backupproc; xkbPrivPtr->processInputProc = xkbPrivPtr->
realInputProc = xkbi->device->public.realInputProc; xkbi
->device->public.realInputProc = backupproc; xkbPrivPtr
->unwrapProc = xkbi->device->unwrapProc; xkbi->device
->unwrapProc = xkbUnwrapProc;
907 xkbUnwrapProc)if (xkbi->device->public.processInputProc == xkbi->device
->public.realInputProc) xkbi->device->public.processInputProc
= backupproc; xkbPrivPtr->processInputProc = xkbPrivPtr->
realInputProc = xkbi->device->public.realInputProc; xkbi
->device->public.realInputProc = backupproc; xkbPrivPtr
->unwrapProc = xkbi->device->unwrapProc; xkbi->device
->unwrapProc = xkbUnwrapProc;
;
908
909 if (mask || mods) {
910 xkbi->state = old;
911 xkbi->prev_state = old_prev;
912 }
913 return 0;
914 }
915 else {
916 /* If it is a key release, or we redirect to another key, release the
917 previous new_key. Otherwise, repeat. */
918 ev.detail.key = filter->upAction.redirect.new_key;
919 if (pAction == NULL((void*)0) || ev.detail.key != pAction->redirect.new_key) {
920 ev.type = ET_KeyRelease;
921 filter->active = 0;
922 }
923 else {
924 ev.type = ET_KeyPress;
925 ev.key_repeat = TRUE1;
926 }
927
928 mask = XkbSARedirectVModsMask(&filter->upAction.redirect)((((unsigned int)(&filter->upAction.redirect)->vmods_mask1
)<<8)| ((unsigned int)(&filter->upAction.redirect
)->vmods_mask0))
;
929 mods = XkbSARedirectVMods(&filter->upAction.redirect)((((unsigned int)(&filter->upAction.redirect)->vmods1
)<<8)| ((unsigned int)(&filter->upAction.redirect
)->vmods0))
;
930 if (mask)
931 XkbVirtualModsToRealSrvXkbVirtualModsToReal(xkbi->desc, mask, &mask);
932 if (mods)
933 XkbVirtualModsToRealSrvXkbVirtualModsToReal(xkbi->desc, mods, &mods);
934 mask |= filter->upAction.redirect.mods_mask;
935 mods |= filter->upAction.redirect.mods;
936
937 if (mask || mods) {
938 old = xkbi->state;
939 old_prev = xkbi->prev_state;
940 xkbi->state.base_mods &= ~mask;
941 xkbi->state.base_mods |= (mods & mask);
942 xkbi->state.latched_mods &= ~mask;
943 xkbi->state.latched_mods |= (mods & mask);
944 xkbi->state.locked_mods &= ~mask;
945 xkbi->state.locked_mods |= (mods & mask);
946 XkbComputeDerivedState(xkbi);
947 xkbi->prev_state = xkbi->state;
948 }
949
950 UNWRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc)backupproc = xkbi->device->public.realInputProc; if (xkbi
->device->public.processInputProc == xkbi->device->
public.realInputProc) xkbi->device->public.processInputProc
= xkbPrivPtr->realInputProc; xkbi->device->public.realInputProc
= xkbPrivPtr->realInputProc; xkbi->device->unwrapProc
= xkbPrivPtr->unwrapProc;
;
951 xkbi->device->public.processInputProc((InternalEvent *) &ev,
952 xkbi->device);
953 COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc,if (xkbi->device->public.processInputProc == xkbi->device
->public.realInputProc) xkbi->device->public.processInputProc
= backupproc; xkbPrivPtr->processInputProc = xkbPrivPtr->
realInputProc = xkbi->device->public.realInputProc; xkbi
->device->public.realInputProc = backupproc; xkbPrivPtr
->unwrapProc = xkbi->device->unwrapProc; xkbi->device
->unwrapProc = xkbUnwrapProc;
954 xkbUnwrapProc)if (xkbi->device->public.processInputProc == xkbi->device
->public.realInputProc) xkbi->device->public.processInputProc
= backupproc; xkbPrivPtr->processInputProc = xkbPrivPtr->
realInputProc = xkbi->device->public.realInputProc; xkbi
->device->public.realInputProc = backupproc; xkbPrivPtr
->unwrapProc = xkbi->device->unwrapProc; xkbi->device
->unwrapProc = xkbUnwrapProc;
;
955
956 if (mask || mods) {
957 xkbi->state = old;
958 xkbi->prev_state = old_prev;
959 }
960
961 /* We return 1 in case we have sent a release event because the new_key
962 has changed. Then, subsequently, we will call this function again
963 with the same pAction, which will create the press for the new
964 new_key. */
965 return (pAction && ev.detail.key != pAction->redirect.new_key);
966 }
967}
968
969static int
970_XkbFilterSwitchScreen(XkbSrvInfoPtr xkbi,
971 XkbFilterPtr filter,
972 unsigned keycode, XkbAction *pAction)
973{
974 DeviceIntPtr dev = xkbi->device;
975
976 if (dev == inputInfo.keyboard)
977 return 0;
978
979 if (filter->keycode == 0) { /* initial press */
980 filter->keycode = keycode;
981 filter->active = 1;
982 filter->filterOthers = 0;
983 filter->filter = _XkbFilterSwitchScreen;
984 AccessXCancelRepeatKey(xkbi, keycode);
985 XkbDDXSwitchScreen(dev, keycode, pAction);
986 return 0;
987 }
988 else if (filter->keycode == keycode) {
989 filter->active = 0;
990 return 0;
991 }
992 return 1;
993}
994
995static int
996_XkbFilterXF86Private(XkbSrvInfoPtr xkbi,
997 XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
998{
999 DeviceIntPtr dev = xkbi->device;
1000
1001 if (dev == inputInfo.keyboard)
1002 return 0;
1003
1004 if (filter->keycode == 0) { /* initial press */
1005 filter->keycode = keycode;
1006 filter->active = 1;
1007 filter->filterOthers = 0;
1008 filter->filter = _XkbFilterXF86Private;
1009 XkbDDXPrivate(dev, keycode, pAction);
1010 return 0;
1011 }
1012 else if (filter->keycode == keycode) {
1013 filter->active = 0;
1014 return 0;
1015 }
1016 return 1;
1017}
1018
1019static int
1020_XkbFilterDeviceBtn(XkbSrvInfoPtr xkbi,
1021 XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
1022{
1023 if (xkbi->device == inputInfo.keyboard)
1024 return 0;
1025
1026 if (filter->keycode == 0) { /* initial press */
1027 DeviceIntPtr dev;
1028 int button;
1029
1030 _XkbLookupButtonDevice(&dev, pAction->devbtn.device, serverClient,
1031 DixUnknownAccess0, &button);
1032 if (!dev || !dev->public.on)
1033 return 1;
1034
1035 button = pAction->devbtn.button;
1036 if ((button < 1) || (button > dev->button->numButtons))
1037 return 1;
1038
1039 filter->keycode = keycode;
1040 filter->active = 1;
1041 filter->filterOthers = 0;
1042 filter->priv = 0;
1043 filter->filter = _XkbFilterDeviceBtn;
1044 filter->upAction = *pAction;
1045 switch (pAction->type) {
1046 case XkbSA_LockDeviceBtn0x13:
1047 if ((pAction->devbtn.flags & XkbSA_LockNoLock(1L << 0)) ||
1048 BitIsOn(dev->button->down, button)(!!(((const BYTE *) (dev->button->down))[(button)>>
3] & (1 << ((button) & 7))))
)
1049 return 0;
1050 XkbFakeDeviceButton(dev, TRUE1, button);
1051 filter->upAction.type = XkbSA_NoAction0x00;
1052 break;
1053 case XkbSA_DeviceBtn0x12:
1054 if (pAction->devbtn.count > 0) {
1055 int nClicks, i;
1056
1057 nClicks = pAction->btn.count;
1058 for (i = 0; i < nClicks; i++) {
1059 XkbFakeDeviceButton(dev, TRUE1, button);
1060 XkbFakeDeviceButton(dev, FALSE0, button);
1061 }
1062 filter->upAction.type = XkbSA_NoAction0x00;
1063 }
1064 else
1065 XkbFakeDeviceButton(dev, TRUE1, button);
1066 break;
1067 }
1068 }
1069 else if (filter->keycode == keycode) {
1070 DeviceIntPtr dev;
1071 int button;
1072
1073 filter->active = 0;
1074 _XkbLookupButtonDevice(&dev, filter->upAction.devbtn.device,
1075 serverClient, DixUnknownAccess0, &button);
1076 if (!dev || !dev->public.on)
1077 return 1;
1078
1079 button = filter->upAction.btn.button;
1080 switch (filter->upAction.type) {
1081 case XkbSA_LockDeviceBtn0x13:
1082 if ((filter->upAction.devbtn.flags & XkbSA_LockNoUnlock(1L << 1)) ||
1083 !BitIsOn(dev->button->down, button)(!!(((const BYTE *) (dev->button->down))[(button)>>
3] & (1 << ((button) & 7))))
)
1084 return 0;
1085 XkbFakeDeviceButton(dev, FALSE0, button);
1086 break;
1087 case XkbSA_DeviceBtn0x12:
1088 XkbFakeDeviceButton(dev, FALSE0, button);
1089 break;
1090 }
1091 filter->active = 0;
1092 }
1093 return 0;
1094}
1095
1096static XkbFilterPtr
1097_XkbNextFreeFilter(XkbSrvInfoPtr xkbi)
1098{
1099 register int i;
1100
1101 if (xkbi->szFilters == 0) {
1102 xkbi->szFilters = 4;
1103 xkbi->filters = calloc(xkbi->szFilters, sizeof(XkbFilterRec));
1104 /* 6/21/93 (ef) -- XXX! deal with allocation failure */
1105 }
1106 for (i = 0; i < xkbi->szFilters; i++) {
1107 if (!xkbi->filters[i].active) {
1108 xkbi->filters[i].keycode = 0;
1109 return &xkbi->filters[i];
1110 }
1111 }
1112 xkbi->szFilters *= 2;
1113 xkbi->filters = reallocarrayxreallocarray(xkbi->filters,
1114 xkbi->szFilters, sizeof(XkbFilterRec));
1115 /* 6/21/93 (ef) -- XXX! deal with allocation failure */
1116 memset(&xkbi->filters[xkbi->szFilters / 2], 0,__builtin___memset_chk (&xkbi->filters[xkbi->szFilters
/ 2], 0, (xkbi->szFilters / 2) * sizeof(XkbFilterRec), __builtin_object_size
(&xkbi->filters[xkbi->szFilters / 2], 0))
1117 (xkbi->szFilters / 2) * sizeof(XkbFilterRec))__builtin___memset_chk (&xkbi->filters[xkbi->szFilters
/ 2], 0, (xkbi->szFilters / 2) * sizeof(XkbFilterRec), __builtin_object_size
(&xkbi->filters[xkbi->szFilters / 2], 0))
;
1118 return &xkbi->filters[xkbi->szFilters / 2];
1119}
1120
1121static int
1122_XkbApplyFilters(XkbSrvInfoPtr xkbi, unsigned kc, XkbAction *pAction)
1123{
1124 register int i, send;
1125
1126 send = 1;
1127 for (i = 0; i < xkbi->szFilters; i++) {
1128 if ((xkbi->filters[i].active) && (xkbi->filters[i].filter))
1129 send =
1130 ((*xkbi->filters[i].filter) (xkbi, &xkbi->filters[i], kc,
1131 pAction)
1132 && send);
1133 }
1134 return send;
1135}
1136
1137static int
1138_XkbEnsureStateChange(XkbSrvInfoPtr xkbi)
1139{
1140 Bool genStateNotify = FALSE0;
1141
1142 /* The state may change, so if we're not in the middle of sending a state
1143 * notify, prepare for it */
1144 if ((xkbi->flags & _XkbStateNotifyInProgress(1<<0)) == 0) {
1145 xkbi->prev_state = xkbi->state;
1146 xkbi->flags |= _XkbStateNotifyInProgress(1<<0);
1147 genStateNotify = TRUE1;
1148 }
1149
1150 return genStateNotify;
1151}
1152
1153static void
1154_XkbApplyState(DeviceIntPtr dev, Bool genStateNotify, int evtype, int key)
1155{
1156 XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
1157 int changed;
1158
1159 XkbComputeDerivedState(xkbi);
1160
1161 changed = XkbStateChangedFlags(&xkbi->prev_state, &xkbi->state);
1162 if (genStateNotify) {
1163 if (changed) {
1164 xkbStateNotify sn;
1165
1166 sn.keycode = key;
1167 sn.eventType = evtype;
1168 sn.requestMajor = sn.requestMinor = 0;
1169 sn.changed = changed;
1170 XkbSendStateNotify(dev, &sn);
1171 }
1172 xkbi->flags &= ~_XkbStateNotifyInProgress(1<<0);
1173 }
1174
1175 changed = XkbIndicatorsToUpdate(dev, changed, FALSE0);
1176 if (changed) {
1177 XkbEventCauseRec cause;
1178 XkbSetCauseKey(&cause, key, evtype){ (&cause)->kc= (key),(&cause)->event= (evtype)
, (&cause)->mjr= (&cause)->mnr= 0; (&cause)
->client= ((void*)0); }
;
1179 XkbUpdateIndicators(dev, changed, FALSE0, NULL((void*)0), &cause);
1180 }
1181}
1182
1183void
1184XkbPushLockedStateToSlaves(DeviceIntPtr master, int evtype, int key)
1185{
1186 DeviceIntPtr dev;
1187 Bool genStateNotify;
1188
1189 nt_list_for_each_entry(dev, inputInfo.devices, next)for (dev = inputInfo.devices; dev; dev = (dev)->next) {
1190 if (!dev->key || GetMaster(dev, MASTER_KEYBOARD2) != master)
1191 continue;
1192
1193 genStateNotify = _XkbEnsureStateChange(dev->key->xkbInfo);
1194
1195 dev->key->xkbInfo->state.locked_mods =
1196 master->key->xkbInfo->state.locked_mods;
1197
1198 _XkbApplyState(dev, genStateNotify, evtype, key);
1199 }
1200}
1201
1202void
1203XkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent *event)
1204{
1205 int key, bit, i;
1206 XkbSrvInfoPtr xkbi;
1207 KeyClassPtr keyc;
1208 int sendEvent;
1209 Bool genStateNotify;
1210 XkbAction act;
1211 XkbFilterPtr filter;
1212 Bool keyEvent;
1213 Bool pressEvent;
1214 ProcessInputProc backupproc;
1215
1216 xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev)((xkbDeviceInfoPtr)dixLookupPrivate(&(dev)->devPrivates
, (&xkbDevicePrivateKeyRec)))
;
1217
1218 keyc = kbd->key;
1219 xkbi = keyc->xkbInfo;
1220 key = event->detail.key;
1221
1222 genStateNotify = _XkbEnsureStateChange(xkbi);
1223
1224 xkbi->clearMods = xkbi->setMods = 0;
1225 xkbi->groupChange = 0;
1226
1227 sendEvent = 1;
1228 keyEvent = ((event->type == ET_KeyPress) || (event->type == ET_KeyRelease));
1229 pressEvent = ((event->type == ET_KeyPress) ||
1230 (event->type == ET_ButtonPress));
1231
1232 if (pressEvent) {
1233 if (keyEvent)
1234 act = XkbGetKeyAction(xkbi, &xkbi->state, key);
1235 else {
1236 act = XkbGetButtonAction(kbd, dev, key);
1237 key |= BTN_ACT_FLAG0x100;
1238 }
1239 sendEvent = _XkbApplyFilters(xkbi, key, &act);
1240 if (sendEvent) {
1241 switch (act.type) {
1242 case XkbSA_SetMods0x01:
1243 case XkbSA_SetGroup0x04:
1244 filter = _XkbNextFreeFilter(xkbi);
1245 sendEvent = _XkbFilterSetState(xkbi, filter, key, &act);
1246 break;
1247 case XkbSA_LatchMods0x02:
1248 case XkbSA_LatchGroup0x05:
1249 filter = _XkbNextFreeFilter(xkbi);
1250 sendEvent = _XkbFilterLatchState(xkbi, filter, key, &act);
1251 break;
1252 case XkbSA_LockMods0x03:
1253 case XkbSA_LockGroup0x06:
1254 filter = _XkbNextFreeFilter(xkbi);
1255 sendEvent = _XkbFilterLockState(xkbi, filter, key, &act);
1256 break;
1257 case XkbSA_ISOLock0x0b:
1258 filter = _XkbNextFreeFilter(xkbi);
1259 sendEvent = _XkbFilterISOLock(xkbi, filter, key, &act);
1260 break;
1261 case XkbSA_MovePtr0x07:
1262 filter = _XkbNextFreeFilter(xkbi);
1263 sendEvent = _XkbFilterPointerMove(xkbi, filter, key, &act);
1264 break;
1265 case XkbSA_PtrBtn0x08:
1266 case XkbSA_LockPtrBtn0x09:
1267 case XkbSA_SetPtrDflt0x0a:
1268 filter = _XkbNextFreeFilter(xkbi);
1269 sendEvent = _XkbFilterPointerBtn(xkbi, filter, key, &act);
1270 break;
1271 case XkbSA_Terminate0x0c:
1272 sendEvent = XkbDDXTerminateServer(dev, key, &act);
1273 break;
1274 case XkbSA_SwitchScreen0x0d:
1275 filter = _XkbNextFreeFilter(xkbi);
1276 sendEvent = _XkbFilterSwitchScreen(xkbi, filter, key, &act);
1277 break;
1278 case XkbSA_SetControls0x0e:
1279 case XkbSA_LockControls0x0f:
1280 filter = _XkbNextFreeFilter(xkbi);
1281 sendEvent = _XkbFilterControls(xkbi, filter, key, &act);
1282 break;
1283 case XkbSA_ActionMessage0x10:
1284 filter = _XkbNextFreeFilter(xkbi);
1285 sendEvent = _XkbFilterActionMessage(xkbi, filter, key, &act);
1286 break;
1287 case XkbSA_RedirectKey0x11:
1288 filter = _XkbNextFreeFilter(xkbi);
1289 /* redirect actions must create a new DeviceEvent. The
1290 * source device id for this event cannot be obtained from
1291 * xkbi, so we pass it here explicitly. The field deviceid
1292 * equals to xkbi->device->id. */
1293 filter->priv = event->sourceid;
1294 sendEvent = _XkbFilterRedirectKey(xkbi, filter, key, &act);
1295 break;
1296 case XkbSA_DeviceBtn0x12:
1297 case XkbSA_LockDeviceBtn0x13:
1298 filter = _XkbNextFreeFilter(xkbi);
1299 sendEvent = _XkbFilterDeviceBtn(xkbi, filter, key, &act);
1300 break;
1301 case XkbSA_XFree86Private0x86:
1302 filter = _XkbNextFreeFilter(xkbi);
1303 sendEvent = _XkbFilterXF86Private(xkbi, filter, key, &act);
1304 break;
1305 }
1306 }
1307 }
1308 else {
1309 if (!keyEvent)
1310 key |= BTN_ACT_FLAG0x100;
1311 sendEvent = _XkbApplyFilters(xkbi, key, NULL((void*)0));
1312 }
1313
1314 if (xkbi->groupChange != 0)
1315 xkbi->state.base_group += xkbi->groupChange;
1316 if (xkbi->setMods) {
1317 for (i = 0, bit = 1; xkbi->setMods; i++, bit <<= 1) {
1318 if (xkbi->setMods & bit) {
1319 keyc->modifierKeyCount[i]++;
1320 xkbi->state.base_mods |= bit;
1321 xkbi->setMods &= ~bit;
1322 }
1323 }
1324 }
1325 if (xkbi->clearMods) {
1326 for (i = 0, bit = 1; xkbi->clearMods; i++, bit <<= 1) {
1327 if (xkbi->clearMods & bit) {
1328 keyc->modifierKeyCount[i]--;
1329 if (keyc->modifierKeyCount[i] <= 0) {
1330 xkbi->state.base_mods &= ~bit;
1331 keyc->modifierKeyCount[i] = 0;
1332 }
1333 xkbi->clearMods &= ~bit;
1334 }
1335 }
1336 }
1337
1338 if (sendEvent) {
1339 DeviceIntPtr tmpdev;
1340
1341 if (keyEvent)
1342 tmpdev = dev;
1343 else
1344 tmpdev = GetMaster(dev, POINTER_OR_FLOAT6);
1345
1346 UNWRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr, backupproc)backupproc = tmpdev->public.realInputProc; if (tmpdev->
public.processInputProc == tmpdev->public.realInputProc) tmpdev
->public.processInputProc = xkbPrivPtr->realInputProc; tmpdev
->public.realInputProc = xkbPrivPtr->realInputProc; tmpdev
->unwrapProc = xkbPrivPtr->unwrapProc;
;
1347 dev->public.processInputProc((InternalEvent *) event, tmpdev);
1348 COND_WRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr,if (tmpdev->public.processInputProc == tmpdev->public.realInputProc
) tmpdev->public.processInputProc = backupproc; xkbPrivPtr
->processInputProc = xkbPrivPtr->realInputProc = tmpdev
->public.realInputProc; tmpdev->public.realInputProc = backupproc
; xkbPrivPtr->unwrapProc = tmpdev->unwrapProc; tmpdev->
unwrapProc = xkbUnwrapProc;
1349 backupproc, xkbUnwrapProc)if (tmpdev->public.processInputProc == tmpdev->public.realInputProc
) tmpdev->public.processInputProc = backupproc; xkbPrivPtr
->processInputProc = xkbPrivPtr->realInputProc = tmpdev
->public.realInputProc; tmpdev->public.realInputProc = backupproc
; xkbPrivPtr->unwrapProc = tmpdev->unwrapProc; tmpdev->
unwrapProc = xkbUnwrapProc;
;
1350 }
1351 else if (keyEvent) {
1352 FixKeyState(event, dev);
1353 }
1354
1355 _XkbApplyState(dev, genStateNotify, event->type, key);
1356 XkbPushLockedStateToSlaves(dev, event->type, key);
1357}
1358
1359int
1360XkbLatchModifiersSrvXkbLatchModifiers(DeviceIntPtr pXDev, CARD8 mask, CARD8 latches)
1361{
1362 XkbSrvInfoPtr xkbi;
1363 XkbFilterPtr filter;
1364 XkbAction act;
1365 unsigned clear;
1366
1367 if (pXDev && pXDev->key && pXDev->key->xkbInfo) {
1368 xkbi = pXDev->key->xkbInfo;
1369 clear = (mask & (~latches));
1370 xkbi->state.latched_mods &= ~clear;
1371 /* Clear any pending latch to locks.
1372 */
1373 act.type = XkbSA_NoAction0x00;
1374 _XkbApplyFilters(xkbi, SYNTHETIC_KEYCODE1, &act);
1375 act.type = XkbSA_LatchMods0x02;
1376 act.mods.flags = 0;
1377 act.mods.mask = mask & latches;
1378 filter = _XkbNextFreeFilter(xkbi);
1379 _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE1, &act);
1380 _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE1,
1381 (XkbAction *) NULL((void*)0));
1382 return Success0;
1383 }
1384 return BadValue2;
1385}
1386
1387int
1388XkbLatchGroupSrvXkbLatchGroup(DeviceIntPtr pXDev, int group)
1389{
1390 XkbSrvInfoPtr xkbi;
1391 XkbFilterPtr filter;
1392 XkbAction act;
1393
1394 if (pXDev && pXDev->key && pXDev->key->xkbInfo) {
1395 xkbi = pXDev->key->xkbInfo;
1396 act.type = XkbSA_LatchGroup0x05;
1397 act.group.flags = 0;
1398 XkbSASetGroup(&act.group, group)((&act.group)->group_XXX=(group));
1399 filter = _XkbNextFreeFilter(xkbi);
1400 _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE1, &act);
1401 _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE1,
1402 (XkbAction *) NULL((void*)0));
1403 return Success0;
1404 }
1405 return BadValue2;
1406}
1407
1408/***====================================================================***/
1409
1410void
1411XkbClearAllLatchesAndLocks(DeviceIntPtr dev,
1412 XkbSrvInfoPtr xkbi,
1413 Bool genEv, XkbEventCausePtr cause)
1414{
1415 XkbStateRec os;
1416 xkbStateNotify sn;
1417
1418 sn.changed = 0;
1419 os = xkbi->state;
1420 if (os.latched_mods) { /* clear all latches */
1421 XkbLatchModifiersSrvXkbLatchModifiers(dev, ~0, 0);
1422 sn.changed |= XkbModifierLatchMask(1L << 2);
1423 }
1424 if (os.latched_group) {
1425 XkbLatchGroupSrvXkbLatchGroup(dev, 0);
1426 sn.changed |= XkbGroupLatchMask(1L << 6);
1427 }
1428 if (os.locked_mods) {
1429 xkbi->state.locked_mods = 0;
1430 sn.changed |= XkbModifierLockMask(1L << 3);
1431 }
1432 if (os.locked_group) {
1433 xkbi->state.locked_group = 0;
1434 sn.changed |= XkbGroupLockMask(1L << 7);
1435 }
1436 if (genEv && sn.changed) {
1437 CARD32 changed;
1438
1439 XkbComputeDerivedState(xkbi);
1440 sn.keycode = cause->kc;
1441 sn.eventType = cause->event;
1442 sn.requestMajor = cause->mjr;
1443 sn.requestMinor = cause->mnr;
1444 sn.changed = XkbStateChangedFlags(&os, &xkbi->state);
1445 XkbSendStateNotify(dev, &sn);
1446 changed = XkbIndicatorsToUpdate(dev, sn.changed, FALSE0);
1447 if (changed) {
1448 XkbUpdateIndicators(dev, changed, TRUE1, NULL((void*)0), cause);
1449 }
1450 }
1451 return;
1452}
1453
1454/*
1455 * The event is injected into the event processing, not the EQ. Thus,
1456 * ensure that we restore the master after the event sequence to the
1457 * original set of classes. Otherwise, the master remains on the XTEST
1458 * classes and drops events that don't fit into the XTEST layout (e.g.
1459 * events with more than 2 valuators).
1460 *
1461 * FIXME: EQ injection in the processing stage is not designed for, so this
1462 * is a rather awkward hack. The event list returned by GetPointerEvents()
1463 * and friends is always prefixed with a DCE if the last _posted_ device was
1464 * different. For normal events, this sequence then resets the master during
1465 * the processing stage. Since we inject the PointerKey events in the
1466 * processing stage though, we need to manually reset to restore the
1467 * previous order, because the events already in the EQ must be sent for the
1468 * right device.
1469 * So we post-fix the event list we get from GPE with a DCE back to the
1470 * previous slave device.
1471 *
1472 * First one on drinking island wins!
1473 */
1474static void
1475InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags,
1476 ValuatorMask *mask)
1477{
1478 ScreenPtr pScreen;
1479 InternalEvent *events;
1480 int nevents, i;
1481 DeviceIntPtr ptr, mpointer, lastSlave = NULL((void*)0);
1482 Bool saveWait;
1483
1484 if (IsMaster(dev)) {
1485 mpointer = GetMaster(dev, MASTER_POINTER1);
1486 lastSlave = mpointer->lastSlave;
1487 ptr = GetXTestDevice(mpointer);
1488 }
1489 else if (IsFloating(dev))
1490 ptr = dev;
1491 else
1492 return;
1493
1494 events = InitEventList(GetMaximumEventsNum() + 1);
1495 OsBlockSignals();
1496 pScreen = miPointerGetScreen(ptr);
1497 saveWait = miPointerSetWaitForUpdate(pScreen, FALSE0);
1498 nevents = GetPointerEvents(events, ptr, type, button, flags, mask);
1499 if (IsMaster(dev) && (lastSlave && lastSlave != ptr))
1500 UpdateFromMaster(&events[nevents], lastSlave, DEVCHANGE_POINTER_EVENT0x4,
1501 &nevents);
1502 miPointerSetWaitForUpdate(pScreen, saveWait);
1503 OsReleaseSignals();
1504
1505 for (i = 0; i < nevents; i++)
1506 mieqProcessDeviceEvent(ptr, &events[i], NULL((void*)0));
1507
1508 FreeEventList(events, GetMaximumEventsNum());
1509
1510}
1511
1512static void
1513XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags, int x, int y)
1514{
1515 ValuatorMask mask;
1516 int gpe_flags = 0;
1517
1518 /* ignore attached SDs */
1519 if (!IsMaster(dev) && !IsFloating(dev))
1520 return;
1521
1522 if (flags & XkbSA_MoveAbsoluteX(1L << 1) || flags & XkbSA_MoveAbsoluteY(1L << 2))
1523 gpe_flags = POINTER_ABSOLUTE(1 << 2);
1524 else
1525 gpe_flags = POINTER_RELATIVE(1 << 1);
1526
1527 valuator_mask_set_range(&mask, 0, 2, (int[]) {
1528 x, y});
1529
1530 InjectPointerKeyEvents(dev, MotionNotify6, 0, gpe_flags, &mask);
1531}
1532
1533void
1534XkbFakeDeviceButton(DeviceIntPtr dev, Bool press, int button)
1535{
1536 DeviceIntPtr ptr;
1537 int down;
1538
1539 /* If dev is a slave device, and the SD is attached, do nothing. If we'd
1540 * post through the attached master pointer we'd get duplicate events.
1541 *
1542 * if dev is a master keyboard, post through the XTEST device
1543 *
1544 * if dev is a floating slave, post through the device itself.
1545 */
1546
1547 if (IsMaster(dev)) {
1548 DeviceIntPtr mpointer = GetMaster(dev, MASTER_POINTER1);
1549
1550 ptr = GetXTestDevice(mpointer);
1551 }
1552 else if (IsFloating(dev))
1553 ptr = dev;
1554 else
1555 return;
1556
1557 down = button_is_down(ptr, button, BUTTON_PROCESSED1);
1558 if (press == down)
1559 return;
1560
1561 InjectPointerKeyEvents(dev, press ? ButtonPress4 : ButtonRelease5,
1562 button, 0, NULL((void*)0));
1563}