Bug Summary

File:xkb/xkbActions.c
Location:line 773, column 14
Description:Access to field 'flags' results in a dereference of a null pointer (loaded from variable 'pMsg')

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