]> git.ipfire.org Git - people/ms/ipfire-3.x.git/blame - xorg-x11-server/patches/xserver-1.8.2-XTEST-PointerKeys-fixes.patch
mesa: Update to 9.0.2.
[people/ms/ipfire-3.x.git] / xorg-x11-server / patches / xserver-1.8.2-XTEST-PointerKeys-fixes.patch
CommitLineData
313ed234
SS
1From deab888bb3bb2a56963da50ff551bd66fbd858a1 Mon Sep 17 00:00:00 2001
2From: Peter Hutterer <peter.hutterer@who-t.net>
3Date: Tue, 29 Jun 2010 13:49:27 +1000
4Subject: [PATCH 1/5] xkb: Mark switch case fallthrough with comment.
5
6Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
7---
8 xkb/xkbActions.c | 2 ++
9 1 files changed, 2 insertions(+), 0 deletions(-)
10
11diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
12index 4c7bce2..6a7f36d 100644
13--- a/xkb/xkbActions.c
14+++ b/xkb/xkbActions.c
15@@ -625,6 +625,8 @@ _XkbFilterPointerBtn( XkbSrvInfoPtr xkbi,
16 break;
17 }
18 xkbi->lockedPtrButtons&= ~(1<<button);
19+
20+ /* fallthrough */
21 case XkbSA_PtrBtn:
22 XkbDDXFakeDeviceButton(xkbi->device, 0, button);
23 break;
24--
251.7.1
26
27From 50b6311dbd2594acc36d6856fdde8623459f1374 Mon Sep 17 00:00:00 2001
28From: Peter Hutterer <peter.hutterer@who-t.net>
29Date: Tue, 29 Jun 2010 12:12:53 +1000
30Subject: [PATCH 2/5] xkb: merge lockedPtrButtons state from all attached SDs.
31MIME-Version: 1.0
32Content-Type: text/plain; charset=UTF-8
33Content-Transfer-Encoding: 8bit
34
35Problem:
36lockedPtrButtons keeps the state of the buttons locked by a PointerKeys button
37press. Unconditionally clearing the bits may cause stuck buttons in this
38sequence of events:
39
401. type Shift + NumLock to enable PointerKeys
412. type 0/Ins on keypad to emulate Button 1 press
42 → button1 press event to client
433. press and release button 1 on physical mouse
44 → button1 release event to client
45
46Button 1 on the MD is now stuck and cannot be released.
47
48Cause:
49XKB PointerKeys button events are posted through the XTEST pointer device.
50Once a press is generated, the XTEST device's button is down. The DIX merges
51the button state of all attached SDs, hence the MD will have a button down
52while the XTEST device has a button down.
53
54PointerKey button events are only generated on the master device to avoid
55duplicate events (see XkbFakeDeviceButton()). If the MD has the
56lockedPtrButtons bit cleared by a release event on a physical device, no
57such event is generated when a keyboard device triggers the PointerKey
58ButtonRelease trigger. Since the event - if generated - is posted through
59the XTEST pointer device, lack of a generated ButtonRelease event on the
60XTEST pointer device means the button is never released, resulting in the
61stuck button observed above.
62
63Solution:
64This patch merges the MD's lockedPtrButtons with the one of all attached
65slave devices on release events. Thus, as long as one attached keyboard has
66a lockedPtrButtons bit set, this bit is kept in the MD. Once a PointerKey
67button is released on all keyboards, the matching release event is emulated
68from the MD through the XTEST pointer device, thus also releasing the button
69in the DIX.
70
71Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
72---
73 include/xkbsrv.h | 3 +++
74 xkb/xkbAccessX.c | 18 +++++++++++++++++-
75 xkb/xkbActions.c | 8 ++++++++
76 xkb/xkbUtils.c | 26 ++++++++++++++++++++++++++
77 4 files changed, 54 insertions(+), 1 deletions(-)
78
79diff --git a/include/xkbsrv.h b/include/xkbsrv.h
80index c0cd501..f0db0e4 100644
81--- a/include/xkbsrv.h
82+++ b/include/xkbsrv.h
83@@ -933,6 +933,9 @@ extern int XkbGetEffectiveGroup(
84 XkbStatePtr /* xkbstate */,
85 CARD8 /* keycode */);
86
87+extern void XkbMergeLockedPtrBtns(
88+ DeviceIntPtr /* master */);
89+
90 #include "xkbfile.h"
91 #include "xkbrules.h"
92
93diff --git a/xkb/xkbAccessX.c b/xkb/xkbAccessX.c
94index be1dcee..e3fdc06 100644
95--- a/xkb/xkbAccessX.c
96+++ b/xkb/xkbAccessX.c
97@@ -707,8 +707,24 @@ DeviceEvent *event = &ev->device_event;
98 changed |= XkbPointerButtonMask;
99 }
100 else if (event->type == ET_ButtonRelease) {
101- if (xkbi)
102+ if (xkbi) {
103 xkbi->lockedPtrButtons&= ~(1 << (event->detail.key & 0x7));
104+
105+ /* Merge this MD's lockedPtrButtons with the one of all
106+ * attached slave devices.
107+ * The DIX uses a merged button state for MDs, not
108+ * releasing buttons until the last SD has released
109+ * thenm. If we unconditionally clear the
110+ * lockedPtrButtons bit on the MD, a PointerKeys button
111+ * release on the SD keyboard won't generate the required fake button
112+ * event on the XTEST pointer, thus never processing the
113+ * button event in the DIX and the XTEST pointer's
114+ * buttons stay down - result is a stuck button.
115+ */
116+ if (IsMaster(dev))
117+ XkbMergeLockedPtrBtns(dev);
118+ }
119+
120 changed |= XkbPointerButtonMask;
121 }
122
123diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
124index 6a7f36d..ab52b6a 100644
125--- a/xkb/xkbActions.c
126+++ b/xkb/xkbActions.c
127@@ -626,6 +626,14 @@ _XkbFilterPointerBtn( XkbSrvInfoPtr xkbi,
128 }
129 xkbi->lockedPtrButtons&= ~(1<<button);
130
131+ if (IsMaster(xkbi->device))
132+ {
133+ XkbMergeLockedPtrBtns(xkbi->device);
134+ /* One SD still has lock set, don't post event */
135+ if ((xkbi->lockedPtrButtons & (1 << button)) != 0)
136+ break;
137+ }
138+
139 /* fallthrough */
140 case XkbSA_PtrBtn:
141 XkbDDXFakeDeviceButton(xkbi->device, 0, button);
142diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c
143index b1e0e55..d7d1935 100644
144--- a/xkb/xkbUtils.c
145+++ b/xkb/xkbUtils.c
146@@ -2190,3 +2190,29 @@ XkbGetEffectiveGroup(XkbSrvInfoPtr xkbi, XkbStatePtr xkbState, CARD8 keycode)
147
148 return effectiveGroup;
149 }
150+
151+/* Merge the lockedPtrButtons from all attached SDs for the given master
152+ * device into the MD's state.
153+ */
154+void
155+XkbMergeLockedPtrBtns(DeviceIntPtr master)
156+{
157+ DeviceIntPtr d = inputInfo.devices;
158+ XkbSrvInfoPtr xkbi = NULL;
159+
160+ if (!IsMaster(master))
161+ return;
162+
163+ if (!master->key)
164+ return;
165+
166+ xkbi = master->key->xkbInfo;
167+ xkbi->lockedPtrButtons = 0;
168+
169+ for (; d; d = d->next) {
170+ if (IsMaster(d) || GetMaster(d, MASTER_KEYBOARD) != master || !d->key)
171+ continue;
172+
173+ xkbi->lockedPtrButtons |= d->key->xkbInfo->lockedPtrButtons;
174+ }
175+}
176--
1771.7.1
178
179From 4a4224f5d786035af88c251a9ee177217e8f77fd Mon Sep 17 00:00:00 2001
180From: Peter Hutterer <peter.hutterer@who-t.net>
181Date: Wed, 14 Apr 2010 10:54:29 +1000
182Subject: [PATCH 3/5] xkb: rename XkbFakeDeviceButton and XkbFakeDeviceMotion, move into xkbActions.c
183
184The name XkbDDXFakeDeviceButton and XkbDDXFakeDeviceMotion is somewhat
185misleading, there's no DDX involved in the game at all anymore.
186
187This removes XkbFakeDeviceMotion and XkbFakeDeviceButton from the API where
188it arguably shouldn't have been in the first place.
189
190Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
191Reviewed-by: Daniel Stone <daniel@fooishbar.org>
192Reviewed-by: Dan Nicholson <dbn.lists@gmail.com>
193---
194 include/xkbsrv.h | 13 -------
195 xkb/Makefile.am | 4 +--
196 xkb/ddxDevBtn.c | 69 --------------------------------------
197 xkb/ddxFakeMtn.c | 64 -----------------------------------
198 xkb/xkbActions.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++-------
199 5 files changed, 85 insertions(+), 162 deletions(-)
200 delete mode 100644 xkb/ddxDevBtn.c
201 delete mode 100644 xkb/ddxFakeMtn.c
202
203diff --git a/include/xkbsrv.h b/include/xkbsrv.h
204index f0db0e4..d1cbd1a 100644
205--- a/include/xkbsrv.h
206+++ b/include/xkbsrv.h
207@@ -768,19 +768,6 @@ extern _X_EXPORT void XkbDDXUpdateDeviceIndicators(
208 CARD32 /* newState */
209 );
210
211-extern _X_EXPORT void XkbDDXFakePointerMotion(
212- DeviceIntPtr /* dev */,
213- unsigned int /* flags */,
214- int /* x */,
215- int /* y */
216-);
217-
218-extern _X_EXPORT void XkbDDXFakeDeviceButton(
219- DeviceIntPtr /* dev */,
220- Bool /* press */,
221- int /* button */
222-);
223-
224 extern _X_EXPORT int XkbDDXTerminateServer(
225 DeviceIntPtr /* dev */,
226 KeyCode /* key */,
227diff --git a/xkb/Makefile.am b/xkb/Makefile.am
228index e54ce59..fb3ccbf 100644
229--- a/xkb/Makefile.am
230+++ b/xkb/Makefile.am
231@@ -5,11 +5,9 @@ AM_CFLAGS = $(DIX_CFLAGS)
232 DDX_SRCS = \
233 ddxBeep.c \
234 ddxCtrls.c \
235- ddxFakeMtn.c \
236 ddxLEDs.c \
237 ddxLoad.c \
238- ddxList.c \
239- ddxDevBtn.c
240+ ddxList.c
241
242 DIX_SRCS = \
243 xkb.c \
244diff --git a/xkb/ddxDevBtn.c b/xkb/ddxDevBtn.c
245deleted file mode 100644
246index b8a1255..0000000
247--- a/xkb/ddxDevBtn.c
248+++ /dev/null
249@@ -1,69 +0,0 @@
250-/************************************************************
251-Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
252-
253-Permission to use, copy, modify, and distribute this
254-software and its documentation for any purpose and without
255-fee is hereby granted, provided that the above copyright
256-notice appear in all copies and that both that copyright
257-notice and this permission notice appear in supporting
258-documentation, and that the name of Silicon Graphics not be
259-used in advertising or publicity pertaining to distribution
260-of the software without specific prior written permission.
261-Silicon Graphics makes no representation about the suitability
262-of this software for any purpose. It is provided "as is"
263-without any express or implied warranty.
264-
265-SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
266-SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
267-AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
268-GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
269-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
270-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
271-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
272-THE USE OR PERFORMANCE OF THIS SOFTWARE.
273-
274-********************************************************/
275-
276-#ifdef HAVE_DIX_CONFIG_H
277-#include <dix-config.h>
278-#endif
279-
280-#include "inputstr.h"
281-#include <xkbsrv.h>
282-#include "mi.h"
283-
284-void
285-XkbDDXFakeDeviceButton(DeviceIntPtr dev,Bool press,int button)
286-{
287- EventListPtr events;
288- int nevents, i;
289- DeviceIntPtr ptr;
290-
291- /* If dev is a slave device, and the SD is attached, do nothing. If we'd
292- * post through the attached master pointer we'd get duplicate events.
293- *
294- * if dev is a master keyboard, post through the XTEST device
295- *
296- * if dev is a floating slave, post through the device itself.
297- */
298-
299- if (IsMaster(dev))
300- ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER));
301- else if (!dev->u.master)
302- ptr = dev;
303- else
304- return;
305-
306- events = InitEventList(GetMaximumEventsNum());
307- OsBlockSignals();
308- nevents = GetPointerEvents(events, ptr,
309- press ? ButtonPress : ButtonRelease, button,
310- 0 /* flags */, 0 /* first */,
311- 0 /* num_val */, NULL);
312- OsReleaseSignals();
313-
314- for (i = 0; i < nevents; i++)
315- mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL);
316-
317- FreeEventList(events, GetMaximumEventsNum());
318-}
319diff --git a/xkb/ddxFakeMtn.c b/xkb/ddxFakeMtn.c
320deleted file mode 100644
321index b383716..0000000
322--- a/xkb/ddxFakeMtn.c
323+++ /dev/null
324@@ -1,64 +0,0 @@
325-/************************************************************
326-Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
327-
328-Permission to use, copy, modify, and distribute this
329-software and its documentation for any purpose and without
330-fee is hereby granted, provided that the above copyright
331-notice appear in all copies and that both that copyright
332-notice and this permission notice appear in supporting
333-documentation, and that the name of Silicon Graphics not be
334-used in advertising or publicity pertaining to distribution
335-of the software without specific prior written permission.
336-Silicon Graphics makes no representation about the suitability
337-of this software for any purpose. It is provided "as is"
338-without any express or implied warranty.
339-
340-SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
341-SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
342-AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
343-GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
344-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
345-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
346-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
347-THE USE OR PERFORMANCE OF THIS SOFTWARE.
348-
349-********************************************************/
350-
351-#ifdef HAVE_DIX_CONFIG_H
352-#include <dix-config.h>
353-#endif
354-
355-#include "inputstr.h"
356-#include <xkbsrv.h>
357-#include "mi.h"
358-
359-void
360-XkbDDXFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y)
361-{
362- EventListPtr events;
363- int nevents, i;
364- DeviceIntPtr ptr;
365- int gpe_flags = 0;
366-
367- if (!dev->u.master)
368- ptr = dev;
369- else
370- ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER));
371-
372- if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY)
373- gpe_flags = POINTER_ABSOLUTE;
374- else
375- gpe_flags = POINTER_RELATIVE;
376-
377- events = InitEventList(GetMaximumEventsNum());
378- OsBlockSignals();
379- nevents = GetPointerEvents(events, ptr,
380- MotionNotify, 0,
381- gpe_flags, 0, 2, (int[]){x, y});
382- OsReleaseSignals();
383-
384- for (i = 0; i < nevents; i++)
385- mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL);
386-
387- FreeEventList(events, GetMaximumEventsNum());
388-}
389diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
390index ab52b6a..2817e39 100644
391--- a/xkb/xkbActions.c
392+++ b/xkb/xkbActions.c
393@@ -40,11 +40,15 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
394 #include <xkbsrv.h>
395 #include "xkb.h"
396 #include <ctype.h>
397+#include "mi.h"
398 #define EXTENSION_EVENT_BASE 64
399
400 static int xkbDevicePrivateKeyIndex;
401 DevPrivateKey xkbDevicePrivateKey = &xkbDevicePrivateKeyIndex;
402
403+static void XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button);
404+static void XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y);
405+
406 void
407 xkbUnwrapProc(DeviceIntPtr device, DeviceHandleProc proc,
408 pointer data)
409@@ -479,7 +483,7 @@ int dx,dy;
410 dx= xkbi->mouseKeysDX;
411 dy= xkbi->mouseKeysDY;
412 }
413- XkbDDXFakePointerMotion(xkbi->device, xkbi->mouseKeysFlags,dx,dy);
414+ XkbFakePointerMotion(xkbi->device, xkbi->mouseKeysFlags,dx,dy);
415 return xkbi->desc->ctrls->mk_interval;
416 }
417
418@@ -507,7 +511,7 @@ Bool accel;
419 accel= ((pAction->ptr.flags&XkbSA_NoAcceleration)==0);
420 x= XkbPtrActionX(&pAction->ptr);
421 y= XkbPtrActionY(&pAction->ptr);
422- XkbDDXFakePointerMotion(xkbi->device, pAction->ptr.flags,x,y);
423+ XkbFakePointerMotion(xkbi->device, pAction->ptr.flags,x,y);
424 AccessXCancelRepeatKey(xkbi,keycode);
425 xkbi->mouseKeysAccel= accel&&
426 (xkbi->desc->ctrls->enabled_ctrls&XkbMouseKeysAccelMask);
427@@ -554,7 +558,7 @@ _XkbFilterPointerBtn( XkbSrvInfoPtr xkbi,
428 ((pAction->btn.flags&XkbSA_LockNoLock)==0)) {
429 xkbi->lockedPtrButtons|= (1<<button);
430 AccessXCancelRepeatKey(xkbi,keycode);
431- XkbDDXFakeDeviceButton(xkbi->device, 1, button);
432+ XkbFakeDeviceButton(xkbi->device, 1, button);
433 filter->upAction.type= XkbSA_NoAction;
434 }
435 break;
436@@ -565,12 +569,12 @@ _XkbFilterPointerBtn( XkbSrvInfoPtr xkbi,
437 if (pAction->btn.count>0) {
438 nClicks= pAction->btn.count;
439 for (i=0;i<nClicks;i++) {
440- XkbDDXFakeDeviceButton(xkbi->device, 1, button);
441- XkbDDXFakeDeviceButton(xkbi->device, 0, button);
442+ XkbFakeDeviceButton(xkbi->device, 1, button);
443+ XkbFakeDeviceButton(xkbi->device, 0, button);
444 }
445 filter->upAction.type= XkbSA_NoAction;
446 }
447- else XkbDDXFakeDeviceButton(xkbi->device, 1, button);
448+ else XkbFakeDeviceButton(xkbi->device, 1, button);
449 }
450 break;
451 case XkbSA_SetPtrDflt:
452@@ -636,7 +640,7 @@ _XkbFilterPointerBtn( XkbSrvInfoPtr xkbi,
453
454 /* fallthrough */
455 case XkbSA_PtrBtn:
456- XkbDDXFakeDeviceButton(xkbi->device, 0, button);
457+ XkbFakeDeviceButton(xkbi->device, 0, button);
458 break;
459 }
460 filter->active = 0;
461@@ -974,7 +978,7 @@ int button;
462 if ((pAction->devbtn.flags&XkbSA_LockNoLock)||
463 BitIsOn(dev->button->down, button))
464 return 0;
465- XkbDDXFakeDeviceButton(dev,TRUE,button);
466+ XkbFakeDeviceButton(dev,TRUE,button);
467 filter->upAction.type= XkbSA_NoAction;
468 break;
469 case XkbSA_DeviceBtn:
470@@ -982,12 +986,12 @@ int button;
471 int nClicks,i;
472 nClicks= pAction->btn.count;
473 for (i=0;i<nClicks;i++) {
474- XkbDDXFakeDeviceButton(dev,TRUE,button);
475- XkbDDXFakeDeviceButton(dev,FALSE,button);
476+ XkbFakeDeviceButton(dev,TRUE,button);
477+ XkbFakeDeviceButton(dev,FALSE,button);
478 }
479 filter->upAction.type= XkbSA_NoAction;
480 }
481- else XkbDDXFakeDeviceButton(dev,TRUE,button);
482+ else XkbFakeDeviceButton(dev,TRUE,button);
483 break;
484 }
485 }
486@@ -1006,10 +1010,10 @@ int button;
487 if ((filter->upAction.devbtn.flags&XkbSA_LockNoUnlock)||
488 !BitIsOn(dev->button->down, button))
489 return 0;
490- XkbDDXFakeDeviceButton(dev,FALSE,button);
491+ XkbFakeDeviceButton(dev,FALSE,button);
492 break;
493 case XkbSA_DeviceBtn:
494- XkbDDXFakeDeviceButton(dev,FALSE,button);
495+ XkbFakeDeviceButton(dev,FALSE,button);
496 break;
497 }
498 filter->active = 0;
499@@ -1326,3 +1330,70 @@ xkbStateNotify sn;
500 return;
501 }
502
503+static void
504+XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y)
505+{
506+ EventListPtr events;
507+ int nevents, i;
508+ DeviceIntPtr ptr;
509+ int gpe_flags = 0;
510+
511+ if (!dev->u.master)
512+ ptr = dev;
513+ else
514+ ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER));
515+
516+ if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY)
517+ gpe_flags = POINTER_ABSOLUTE;
518+ else
519+ gpe_flags = POINTER_RELATIVE;
520+
521+ events = InitEventList(GetMaximumEventsNum());
522+ OsBlockSignals();
523+ nevents = GetPointerEvents(events, ptr,
524+ MotionNotify, 0,
525+ gpe_flags, 0, 2, (int[]){x, y});
526+ OsReleaseSignals();
527+
528+ for (i = 0; i < nevents; i++)
529+ mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL);
530+
531+ FreeEventList(events, GetMaximumEventsNum());
532+}
533+
534+static void
535+XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button)
536+{
537+ EventListPtr events;
538+ int nevents, i;
539+ DeviceIntPtr ptr;
540+
541+ /* If dev is a slave device, and the SD is attached, do nothing. If we'd
542+ * post through the attached master pointer we'd get duplicate events.
543+ *
544+ * if dev is a master keyboard, post through the XTEST device
545+ *
546+ * if dev is a floating slave, post through the device itself.
547+ */
548+
549+ if (IsMaster(dev))
550+ ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER));
551+ else if (!dev->u.master)
552+ ptr = dev;
553+ else
554+ return;
555+
556+ events = InitEventList(GetMaximumEventsNum());
557+ OsBlockSignals();
558+ nevents = GetPointerEvents(events, ptr,
559+ press ? ButtonPress : ButtonRelease, button,
560+ 0 /* flags */, 0 /* first */,
561+ 0 /* num_val */, NULL);
562+ OsReleaseSignals();
563+
564+
565+ for (i = 0; i < nevents; i++)
566+ mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL);
567+
568+ FreeEventList(events, GetMaximumEventsNum());
569+}
570--
5711.7.1
572
573From dcb46252f959893f1934232698e2ae26390a8a5b Mon Sep 17 00:00:00 2001
574From: Peter Hutterer <peter.hutterer@who-t.net>
575Date: Tue, 29 Jun 2010 15:24:51 +1000
576Subject: [PATCH 4/5] xkb: emulate PointerKeys events only on the master device.
577
578This patch replicates the behaviour for button events. Only generate a
579PointerKeys motion event on the master device, not on the slave device.
580Fixes the current issue of PointerKey motion events generating key events as
581well.
582
583Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
584---
585 xkb/xkbActions.c | 9 ++++-----
586 1 files changed, 4 insertions(+), 5 deletions(-)
587
588diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
589index 2817e39..391c375 100644
590--- a/xkb/xkbActions.c
591+++ b/xkb/xkbActions.c
592@@ -496,9 +496,6 @@ _XkbFilterPointerMove( XkbSrvInfoPtr xkbi,
593 int x,y;
594 Bool accel;
595
596- if (xkbi->device == inputInfo.keyboard)
597- return 0;
598-
599 if (filter->keycode==0) { /* initial press */
600 filter->keycode = keycode;
601 filter->active = 1;
602@@ -1338,10 +1335,12 @@ XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y)
603 DeviceIntPtr ptr;
604 int gpe_flags = 0;
605
606- if (!dev->u.master)
607+ if (IsMaster(dev))
608+ ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER));
609+ else if (!dev->u.master)
610 ptr = dev;
611 else
612- ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER));
613+ return;
614
615 if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY)
616 gpe_flags = POINTER_ABSOLUTE;
617--
6181.7.1
619
620From 40941fb2e9ae763add7b74850e8a0471ac754db6 Mon Sep 17 00:00:00 2001
621From: Peter Hutterer <peter.hutterer@who-t.net>
622Date: Thu, 1 Jul 2010 12:44:57 +1000
623Subject: [PATCH 5/5] xkb: release XTEST pointer buttons on physical releases. (#28808)
624
625If a button release event is posted for the MD pointer, post a release event
626through the matching XTEST device. This way, a client who posts a button
627press through the XTEST extension cannot inadvertedly lock the button.
628
629This behaviour is required for historical reasons, until server 1.7 the core
630pointer would release a button press on physical events, regardless of the
631XTEST state. Clients seem to rely on this behaviour, causing seemingly stuck
632grabs.
633
634The merged behaviour is kept for multiple keyboard PointerKey events, if two
635physical keyboards hold the button down as a result of PointerKey actions,
636the button is not released until the last keyboard releases the button.
637
638X.Org Bug 28808 <http://bugs.freedesktop.org/show_bug.cgi?id=28808>
639
640Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
641---
642 include/xkbsrv.h | 6 ++++++
643 xkb/xkbAccessX.c | 23 ++++++++++-------------
644 xkb/xkbActions.c | 4 ++--
645 3 files changed, 18 insertions(+), 15 deletions(-)
646
647diff --git a/include/xkbsrv.h b/include/xkbsrv.h
648index d1cbd1a..a96ca56 100644
649--- a/include/xkbsrv.h
650+++ b/include/xkbsrv.h
651@@ -923,6 +923,12 @@ extern int XkbGetEffectiveGroup(
652 extern void XkbMergeLockedPtrBtns(
653 DeviceIntPtr /* master */);
654
655+extern void XkbFakeDeviceButton(
656+ DeviceIntPtr /* dev */,
657+ int /* press */,
658+ int /* button */);
659+
660+
661 #include "xkbfile.h"
662 #include "xkbrules.h"
663
664diff --git a/xkb/xkbAccessX.c b/xkb/xkbAccessX.c
665index e3fdc06..d3f9652 100644
666--- a/xkb/xkbAccessX.c
667+++ b/xkb/xkbAccessX.c
668@@ -710,19 +710,16 @@ DeviceEvent *event = &ev->device_event;
669 if (xkbi) {
670 xkbi->lockedPtrButtons&= ~(1 << (event->detail.key & 0x7));
671
672- /* Merge this MD's lockedPtrButtons with the one of all
673- * attached slave devices.
674- * The DIX uses a merged button state for MDs, not
675- * releasing buttons until the last SD has released
676- * thenm. If we unconditionally clear the
677- * lockedPtrButtons bit on the MD, a PointerKeys button
678- * release on the SD keyboard won't generate the required fake button
679- * event on the XTEST pointer, thus never processing the
680- * button event in the DIX and the XTEST pointer's
681- * buttons stay down - result is a stuck button.
682- */
683- if (IsMaster(dev))
684- XkbMergeLockedPtrBtns(dev);
685+ if (IsMaster(dev))
686+ {
687+ DeviceIntPtr source;
688+ int rc;
689+ rc = dixLookupDevice(&source, event->sourceid, serverClient, DixWriteAccess);
690+ if (rc != Success)
691+ ErrorF("[xkb] bad sourceid '%d' on button release event.\n", event->sourceid);
692+ else if (!IsXTestDevice(source, GetMaster(dev, MASTER_POINTER)))
693+ XkbFakeDeviceButton(dev, FALSE, event->detail.key);
694+ }
695 }
696
697 changed |= XkbPointerButtonMask;
698diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
699index 391c375..5d40199 100644
700--- a/xkb/xkbActions.c
701+++ b/xkb/xkbActions.c
702@@ -46,7 +46,7 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
703 static int xkbDevicePrivateKeyIndex;
704 DevPrivateKey xkbDevicePrivateKey = &xkbDevicePrivateKeyIndex;
705
706-static void XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button);
707+void XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button);
708 static void XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y);
709
710 void
711@@ -1360,7 +1360,7 @@ XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y)
712 FreeEventList(events, GetMaximumEventsNum());
713 }
714
715-static void
716+void
717 XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button)
718 {
719 EventListPtr events;
720--
7211.7.1
722
723From 7273832bcdc6f43e9a5a8fdbb56844466efb710a Mon Sep 17 00:00:00 2001
724From: Peter Hutterer <peter.hutterer@who-t.net>
725Date: Fri, 23 Jul 2010 11:46:30 +1000
726Subject: [PATCH 1/3] xkb: post-fix PointerKeys button events with a DeviceChangedEvent.
727
728commit 14327858391ebe929b806efb53ad79e789361883
729 xkb: release XTEST pointer buttons on physical releases. (#28808)
730revealed a bug with the XTEST/PointerKeys interaction.
731
732Events resulting from PointerKeys are injected into the event processing
733stream, not appended to the event queue. The events generated for the fake
734button press include a DeviceChangedEvent (DCE), a raw button event and the
735button event itself. The DCE causes the master to switch classes to the
736attached XTEST pointer device.
737
738Once the fake button is processed, normal event processing continues with
739events in the EQ. The master still contains the XTEST classes, causing some
740events to be dropped if e.g. the number of valuators of the event in the
741queue exceeds the XTEST device's number of valuators.
742
743Example: the EQ contains the following events, processed one-by-one, left to
744right.
745
746[DCE (dev)][Btn down][Btn up][Motion][Motion][...]
747 ^ XkbFakeDeviceButton injects [DCE (XTEST)][Btn up]
748
749Thus the event sequence processed looks like this:
750
751[DCE (dev)][Btn down][Btn up][DCE (XTEST)][Btn up][Motion][Motion][...]
752
753The first DCE causes the master to switch to the device. The button up event
754injects a DCE to the XTEST device, causing the following Motion events to be
755processed with the master still being on XTEST classes.
756
757This patch post-fixes the injected event sequence with a DCE to restore the
758classes of the original slave device, resulting in an event sequence like
759this:
760[DCE (dev)][Btn down][Btn up][DCE (XTEST)][Btn up][DCE (dev)][Motion][Motion]
761
762Note that this is a simplified description. The event sequence injected by
763the PointerKeys code is injected for the master device only and the matching
764slave device that caused the injection has already finished processing on
765the slave. Furthermore, the injection happens as part of the the XKB layer,
766before the unwrapping of the processInputProc takes us into the DIX where
767the DCE is actually handled.
768
769Bug reproducible with a device that reports more than 2 valuators. Simply
770cause button releases on the device and wait for a "too many valuators"
771warning message.
772
773Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
774---
775 xkb/xkbActions.c | 26 +++++++++++++++++++-------
776 1 files changed, 19 insertions(+), 7 deletions(-)
777
778diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
779index 5d40199..2afd46d 100644
780--- a/xkb/xkbActions.c
781+++ b/xkb/xkbActions.c
782@@ -1365,34 +1365,46 @@ XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button)
783 {
784 EventListPtr events;
785 int nevents, i;
786- DeviceIntPtr ptr;
787+ DeviceIntPtr ptr, mpointer, lastSlave;
788
789 /* If dev is a slave device, and the SD is attached, do nothing. If we'd
790 * post through the attached master pointer we'd get duplicate events.
791 *
792 * if dev is a master keyboard, post through the XTEST device
793- *
794 * if dev is a floating slave, post through the device itself.
795+ *
796+ * The event is injected into the event processing, not the EQ. Thus,
797+ * ensure that we restore the master after the event sequence to the
798+ * original set of classes. Otherwise, the master remains on the XTEST
799+ * classes and drops events that don't fit into the XTEST layout (e.g.
800+ * events with more than 2 valuators).
801+ * To do so, we remember the lastSlave that posted through the master
802+ * and add a DeviceChangedEvent to the end of the list.
803 */
804
805- if (IsMaster(dev))
806- ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER));
807- else if (!dev->u.master)
808+ if (IsMaster(dev)) {
809+ mpointer = GetMaster(dev, MASTER_POINTER);
810+ lastSlave = mpointer->u.lastSlave;
811+ ptr = GetXTestDevice(mpointer);
812+ } else if (!dev->u.master)
813 ptr = dev;
814 else
815 return;
816
817- events = InitEventList(GetMaximumEventsNum());
818+ events = InitEventList(GetMaximumEventsNum() + 1);
819 OsBlockSignals();
820 nevents = GetPointerEvents(events, ptr,
821 press ? ButtonPress : ButtonRelease, button,
822 0 /* flags */, 0 /* first */,
823 0 /* num_val */, NULL);
824+ if (IsMaster(dev) && (lastSlave && lastSlave != ptr))
825+ CreateClassesChangedEvent(&events[nevents++], mpointer,
826+ lastSlave, DEVCHANGE_POINTER_EVENT);
827 OsReleaseSignals();
828
829
830 for (i = 0; i < nevents; i++)
831 mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL);
832
833- FreeEventList(events, GetMaximumEventsNum());
834+ FreeEventList(events, GetMaximumEventsNum() + 1);
835 }
836--
8371.7.2
838
839From 817e031a996a5f5aa16fc789d7e570cc589d96cb Mon Sep 17 00:00:00 2001
840From: Peter Hutterer <peter.hutterer@who-t.net>
841Date: Wed, 28 Jul 2010 14:24:59 +1000
842Subject: [PATCH 3/3] Xi: reset the unused classes pointer after copying
843
844After copying the unused_classes into the device, reset the original
845pointer. Otherwise we have two pointers pointing to the same field and both
846get freed on device removal.
847
848Some classes already have this behaviour since 51c8fd69.
849
850Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
851---
852 Xi/exevents.c | 6 ++++++
853 1 files changed, 6 insertions(+), 0 deletions(-)
854
855diff --git a/Xi/exevents.c b/Xi/exevents.c
856index 566b0ef..a6160dd 100644
857--- a/Xi/exevents.c
858+++ b/Xi/exevents.c
859@@ -227,6 +227,7 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
860 classes = dixLookupPrivate(&to->devPrivates,
861 UnusedClassesPrivateKey);
862 to->intfeed = classes->intfeed;
863+ classes->intfeed = NULL;
864 }
865
866 i = &to->intfeed;
867@@ -263,6 +264,7 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
868 classes = dixLookupPrivate(&to->devPrivates,
869 UnusedClassesPrivateKey);
870 to->stringfeed = classes->stringfeed;
871+ classes->stringfeed = NULL;
872 }
873
874 s = &to->stringfeed;
875@@ -299,6 +301,7 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
876 classes = dixLookupPrivate(&to->devPrivates,
877 UnusedClassesPrivateKey);
878 to->bell = classes->bell;
879+ classes->bell = NULL;
880 }
881
882 b = &to->bell;
883@@ -336,6 +339,7 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
884 classes = dixLookupPrivate(&to->devPrivates,
885 UnusedClassesPrivateKey);
886 to->leds = classes->leds;
887+ classes->leds = NULL;
888 }
889
890 l = &to->leds;
891@@ -387,6 +391,7 @@ DeepCopyKeyboardClasses(DeviceIntPtr from, DeviceIntPtr to)
892 to->kbdfeed = classes->kbdfeed;
893 if (!to->kbdfeed)
894 InitKeyboardDeviceStruct(to, NULL, NULL, NULL);
895+ classes->kbdfeed = NULL;
896 }
897
898 k = &to->kbdfeed;
899@@ -517,6 +522,7 @@ DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to)
900 classes = dixLookupPrivate(&to->devPrivates,
901 UnusedClassesPrivateKey);
902 to->ptrfeed = classes->ptrfeed;
903+ classes->ptrfeed = NULL;
904 }
905
906 p = &to->ptrfeed;
907--
9081.7.2
909