|
|
542d25d |
From deab888bb3bb2a56963da50ff551bd66fbd858a1 Mon Sep 17 00:00:00 2001
|
|
|
542d25d |
From: Peter Hutterer <peter.hutterer@who-t.net>
|
|
|
542d25d |
Date: Tue, 29 Jun 2010 13:49:27 +1000
|
|
|
542d25d |
Subject: [PATCH 1/5] xkb: Mark switch case fallthrough with comment.
|
|
|
542d25d |
|
|
|
542d25d |
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
|
|
542d25d |
---
|
|
|
542d25d |
xkb/xkbActions.c | 2 ++
|
|
|
542d25d |
1 files changed, 2 insertions(+), 0 deletions(-)
|
|
|
542d25d |
|
|
|
542d25d |
diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
|
|
|
542d25d |
index 4c7bce2..6a7f36d 100644
|
|
|
542d25d |
--- a/xkb/xkbActions.c
|
|
|
542d25d |
+++ b/xkb/xkbActions.c
|
|
|
542d25d |
@@ -625,6 +625,8 @@ _XkbFilterPointerBtn( XkbSrvInfoPtr xkbi,
|
|
|
542d25d |
break;
|
|
|
542d25d |
}
|
|
|
542d25d |
xkbi->lockedPtrButtons&= ~(1<
|
|
|
542d25d |
+
|
|
|
542d25d |
+ /* fallthrough */
|
|
|
542d25d |
case XkbSA_PtrBtn:
|
|
|
542d25d |
XkbDDXFakeDeviceButton(xkbi->device, 0, button);
|
|
|
542d25d |
break;
|
|
|
542d25d |
--
|
|
|
542d25d |
1.7.1
|
|
|
542d25d |
|
|
|
542d25d |
From 50b6311dbd2594acc36d6856fdde8623459f1374 Mon Sep 17 00:00:00 2001
|
|
|
542d25d |
From: Peter Hutterer <peter.hutterer@who-t.net>
|
|
|
542d25d |
Date: Tue, 29 Jun 2010 12:12:53 +1000
|
|
|
542d25d |
Subject: [PATCH 2/5] xkb: merge lockedPtrButtons state from all attached SDs.
|
|
|
542d25d |
MIME-Version: 1.0
|
|
|
542d25d |
Content-Type: text/plain; charset=UTF-8
|
|
|
542d25d |
Content-Transfer-Encoding: 8bit
|
|
|
542d25d |
|
|
|
542d25d |
Problem:
|
|
|
542d25d |
lockedPtrButtons keeps the state of the buttons locked by a PointerKeys button
|
|
|
542d25d |
press. Unconditionally clearing the bits may cause stuck buttons in this
|
|
|
542d25d |
sequence of events:
|
|
|
542d25d |
|
|
|
542d25d |
1. type Shift + NumLock to enable PointerKeys
|
|
|
542d25d |
2. type 0/Ins on keypad to emulate Button 1 press
|
|
|
542d25d |
→ button1 press event to client
|
|
|
542d25d |
3. press and release button 1 on physical mouse
|
|
|
542d25d |
→ button1 release event to client
|
|
|
542d25d |
|
|
|
542d25d |
Button 1 on the MD is now stuck and cannot be released.
|
|
|
542d25d |
|
|
|
542d25d |
Cause:
|
|
|
542d25d |
XKB PointerKeys button events are posted through the XTEST pointer device.
|
|
|
542d25d |
Once a press is generated, the XTEST device's button is down. The DIX merges
|
|
|
542d25d |
the button state of all attached SDs, hence the MD will have a button down
|
|
|
542d25d |
while the XTEST device has a button down.
|
|
|
542d25d |
|
|
|
542d25d |
PointerKey button events are only generated on the master device to avoid
|
|
|
542d25d |
duplicate events (see XkbFakeDeviceButton()). If the MD has the
|
|
|
542d25d |
lockedPtrButtons bit cleared by a release event on a physical device, no
|
|
|
542d25d |
such event is generated when a keyboard device triggers the PointerKey
|
|
|
542d25d |
ButtonRelease trigger. Since the event - if generated - is posted through
|
|
|
542d25d |
the XTEST pointer device, lack of a generated ButtonRelease event on the
|
|
|
542d25d |
XTEST pointer device means the button is never released, resulting in the
|
|
|
542d25d |
stuck button observed above.
|
|
|
542d25d |
|
|
|
542d25d |
Solution:
|
|
|
542d25d |
This patch merges the MD's lockedPtrButtons with the one of all attached
|
|
|
542d25d |
slave devices on release events. Thus, as long as one attached keyboard has
|
|
|
542d25d |
a lockedPtrButtons bit set, this bit is kept in the MD. Once a PointerKey
|
|
|
542d25d |
button is released on all keyboards, the matching release event is emulated
|
|
|
542d25d |
from the MD through the XTEST pointer device, thus also releasing the button
|
|
|
542d25d |
in the DIX.
|
|
|
542d25d |
|
|
|
542d25d |
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
|
|
542d25d |
---
|
|
|
542d25d |
include/xkbsrv.h | 3 +++
|
|
|
542d25d |
xkb/xkbAccessX.c | 18 +++++++++++++++++-
|
|
|
542d25d |
xkb/xkbActions.c | 8 ++++++++
|
|
|
542d25d |
xkb/xkbUtils.c | 26 ++++++++++++++++++++++++++
|
|
|
542d25d |
4 files changed, 54 insertions(+), 1 deletions(-)
|
|
|
542d25d |
|
|
|
542d25d |
diff --git a/include/xkbsrv.h b/include/xkbsrv.h
|
|
|
542d25d |
index c0cd501..f0db0e4 100644
|
|
|
542d25d |
--- a/include/xkbsrv.h
|
|
|
542d25d |
+++ b/include/xkbsrv.h
|
|
|
542d25d |
@@ -933,6 +933,9 @@ extern int XkbGetEffectiveGroup(
|
|
|
542d25d |
XkbStatePtr /* xkbstate */,
|
|
|
542d25d |
CARD8 /* keycode */);
|
|
|
542d25d |
|
|
|
542d25d |
+extern void XkbMergeLockedPtrBtns(
|
|
|
542d25d |
+ DeviceIntPtr /* master */);
|
|
|
542d25d |
+
|
|
|
542d25d |
#include "xkbfile.h"
|
|
|
542d25d |
#include "xkbrules.h"
|
|
|
542d25d |
|
|
|
542d25d |
diff --git a/xkb/xkbAccessX.c b/xkb/xkbAccessX.c
|
|
|
542d25d |
index be1dcee..e3fdc06 100644
|
|
|
542d25d |
--- a/xkb/xkbAccessX.c
|
|
|
542d25d |
+++ b/xkb/xkbAccessX.c
|
|
|
542d25d |
@@ -707,8 +707,24 @@ DeviceEvent *event = &ev->device_event;
|
|
|
542d25d |
changed |= XkbPointerButtonMask;
|
|
|
542d25d |
}
|
|
|
542d25d |
else if (event->type == ET_ButtonRelease) {
|
|
|
542d25d |
- if (xkbi)
|
|
|
542d25d |
+ if (xkbi) {
|
|
|
542d25d |
xkbi->lockedPtrButtons&= ~(1 << (event->detail.key & 0x7));
|
|
|
542d25d |
+
|
|
|
542d25d |
+ /* Merge this MD's lockedPtrButtons with the one of all
|
|
|
542d25d |
+ * attached slave devices.
|
|
|
542d25d |
+ * The DIX uses a merged button state for MDs, not
|
|
|
542d25d |
+ * releasing buttons until the last SD has released
|
|
|
542d25d |
+ * thenm. If we unconditionally clear the
|
|
|
542d25d |
+ * lockedPtrButtons bit on the MD, a PointerKeys button
|
|
|
542d25d |
+ * release on the SD keyboard won't generate the required fake button
|
|
|
542d25d |
+ * event on the XTEST pointer, thus never processing the
|
|
|
542d25d |
+ * button event in the DIX and the XTEST pointer's
|
|
|
542d25d |
+ * buttons stay down - result is a stuck button.
|
|
|
542d25d |
+ */
|
|
|
542d25d |
+ if (IsMaster(dev))
|
|
|
542d25d |
+ XkbMergeLockedPtrBtns(dev);
|
|
|
542d25d |
+ }
|
|
|
542d25d |
+
|
|
|
542d25d |
changed |= XkbPointerButtonMask;
|
|
|
542d25d |
}
|
|
|
542d25d |
|
|
|
542d25d |
diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
|
|
|
542d25d |
index 6a7f36d..ab52b6a 100644
|
|
|
542d25d |
--- a/xkb/xkbActions.c
|
|
|
542d25d |
+++ b/xkb/xkbActions.c
|
|
|
542d25d |
@@ -626,6 +626,14 @@ _XkbFilterPointerBtn( XkbSrvInfoPtr xkbi,
|
|
|
542d25d |
}
|
|
|
542d25d |
xkbi->lockedPtrButtons&= ~(1<
|
|
|
542d25d |
|
|
|
542d25d |
+ if (IsMaster(xkbi->device))
|
|
|
542d25d |
+ {
|
|
|
542d25d |
+ XkbMergeLockedPtrBtns(xkbi->device);
|
|
|
542d25d |
+ /* One SD still has lock set, don't post event */
|
|
|
542d25d |
+ if ((xkbi->lockedPtrButtons & (1 << button)) != 0)
|
|
|
542d25d |
+ break;
|
|
|
542d25d |
+ }
|
|
|
542d25d |
+
|
|
|
542d25d |
/* fallthrough */
|
|
|
542d25d |
case XkbSA_PtrBtn:
|
|
|
542d25d |
XkbDDXFakeDeviceButton(xkbi->device, 0, button);
|
|
|
542d25d |
diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c
|
|
|
542d25d |
index b1e0e55..d7d1935 100644
|
|
|
542d25d |
--- a/xkb/xkbUtils.c
|
|
|
542d25d |
+++ b/xkb/xkbUtils.c
|
|
|
542d25d |
@@ -2190,3 +2190,29 @@ XkbGetEffectiveGroup(XkbSrvInfoPtr xkbi, XkbStatePtr xkbState, CARD8 keycode)
|
|
|
542d25d |
|
|
|
542d25d |
return effectiveGroup;
|
|
|
542d25d |
}
|
|
|
542d25d |
+
|
|
|
542d25d |
+/* Merge the lockedPtrButtons from all attached SDs for the given master
|
|
|
542d25d |
+ * device into the MD's state.
|
|
|
542d25d |
+ */
|
|
|
542d25d |
+void
|
|
|
542d25d |
+XkbMergeLockedPtrBtns(DeviceIntPtr master)
|
|
|
542d25d |
+{
|
|
|
542d25d |
+ DeviceIntPtr d = inputInfo.devices;
|
|
|
542d25d |
+ XkbSrvInfoPtr xkbi = NULL;
|
|
|
542d25d |
+
|
|
|
542d25d |
+ if (!IsMaster(master))
|
|
|
542d25d |
+ return;
|
|
|
542d25d |
+
|
|
|
542d25d |
+ if (!master->key)
|
|
|
542d25d |
+ return;
|
|
|
542d25d |
+
|
|
|
542d25d |
+ xkbi = master->key->xkbInfo;
|
|
|
542d25d |
+ xkbi->lockedPtrButtons = 0;
|
|
|
542d25d |
+
|
|
|
542d25d |
+ for (; d; d = d->next) {
|
|
|
542d25d |
+ if (IsMaster(d) || GetMaster(d, MASTER_KEYBOARD) != master || !d->key)
|
|
|
542d25d |
+ continue;
|
|
|
542d25d |
+
|
|
|
542d25d |
+ xkbi->lockedPtrButtons |= d->key->xkbInfo->lockedPtrButtons;
|
|
|
542d25d |
+ }
|
|
|
542d25d |
+}
|
|
|
542d25d |
--
|
|
|
542d25d |
1.7.1
|
|
|
542d25d |
|
|
|
542d25d |
From 4a4224f5d786035af88c251a9ee177217e8f77fd Mon Sep 17 00:00:00 2001
|
|
|
542d25d |
From: Peter Hutterer <peter.hutterer@who-t.net>
|
|
|
542d25d |
Date: Wed, 14 Apr 2010 10:54:29 +1000
|
|
|
542d25d |
Subject: [PATCH 3/5] xkb: rename XkbFakeDeviceButton and XkbFakeDeviceMotion, move into xkbActions.c
|
|
|
542d25d |
|
|
|
542d25d |
The name XkbDDXFakeDeviceButton and XkbDDXFakeDeviceMotion is somewhat
|
|
|
542d25d |
misleading, there's no DDX involved in the game at all anymore.
|
|
|
542d25d |
|
|
|
542d25d |
This removes XkbFakeDeviceMotion and XkbFakeDeviceButton from the API where
|
|
|
542d25d |
it arguably shouldn't have been in the first place.
|
|
|
542d25d |
|
|
|
542d25d |
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
|
|
542d25d |
Reviewed-by: Daniel Stone <daniel@fooishbar.org>
|
|
|
542d25d |
Reviewed-by: Dan Nicholson <dbn.lists@gmail.com>
|
|
|
542d25d |
---
|
|
|
542d25d |
include/xkbsrv.h | 13 -------
|
|
|
542d25d |
xkb/Makefile.am | 4 +--
|
|
|
542d25d |
xkb/ddxDevBtn.c | 69 --------------------------------------
|
|
|
542d25d |
xkb/ddxFakeMtn.c | 64 -----------------------------------
|
|
|
542d25d |
xkb/xkbActions.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++-------
|
|
|
542d25d |
5 files changed, 85 insertions(+), 162 deletions(-)
|
|
|
542d25d |
delete mode 100644 xkb/ddxDevBtn.c
|
|
|
542d25d |
delete mode 100644 xkb/ddxFakeMtn.c
|
|
|
542d25d |
|
|
|
542d25d |
diff --git a/include/xkbsrv.h b/include/xkbsrv.h
|
|
|
542d25d |
index f0db0e4..d1cbd1a 100644
|
|
|
542d25d |
--- a/include/xkbsrv.h
|
|
|
542d25d |
+++ b/include/xkbsrv.h
|
|
|
542d25d |
@@ -768,19 +768,6 @@ extern _X_EXPORT void XkbDDXUpdateDeviceIndicators(
|
|
|
542d25d |
CARD32 /* newState */
|
|
|
542d25d |
);
|
|
|
542d25d |
|
|
|
542d25d |
-extern _X_EXPORT void XkbDDXFakePointerMotion(
|
|
|
542d25d |
- DeviceIntPtr /* dev */,
|
|
|
542d25d |
- unsigned int /* flags */,
|
|
|
542d25d |
- int /* x */,
|
|
|
542d25d |
- int /* y */
|
|
|
542d25d |
-);
|
|
|
542d25d |
-
|
|
|
542d25d |
-extern _X_EXPORT void XkbDDXFakeDeviceButton(
|
|
|
542d25d |
- DeviceIntPtr /* dev */,
|
|
|
542d25d |
- Bool /* press */,
|
|
|
542d25d |
- int /* button */
|
|
|
542d25d |
-);
|
|
|
542d25d |
-
|
|
|
542d25d |
extern _X_EXPORT int XkbDDXTerminateServer(
|
|
|
542d25d |
DeviceIntPtr /* dev */,
|
|
|
542d25d |
KeyCode /* key */,
|
|
|
542d25d |
diff --git a/xkb/Makefile.am b/xkb/Makefile.am
|
|
|
542d25d |
index e54ce59..fb3ccbf 100644
|
|
|
542d25d |
--- a/xkb/Makefile.am
|
|
|
542d25d |
+++ b/xkb/Makefile.am
|
|
|
542d25d |
@@ -5,11 +5,9 @@ AM_CFLAGS = $(DIX_CFLAGS)
|
|
|
542d25d |
DDX_SRCS = \
|
|
|
542d25d |
ddxBeep.c \
|
|
|
542d25d |
ddxCtrls.c \
|
|
|
542d25d |
- ddxFakeMtn.c \
|
|
|
542d25d |
ddxLEDs.c \
|
|
|
542d25d |
ddxLoad.c \
|
|
|
542d25d |
- ddxList.c \
|
|
|
542d25d |
- ddxDevBtn.c
|
|
|
542d25d |
+ ddxList.c
|
|
|
542d25d |
|
|
|
542d25d |
DIX_SRCS = \
|
|
|
542d25d |
xkb.c \
|
|
|
542d25d |
diff --git a/xkb/ddxDevBtn.c b/xkb/ddxDevBtn.c
|
|
|
542d25d |
deleted file mode 100644
|
|
|
542d25d |
index b8a1255..0000000
|
|
|
542d25d |
--- a/xkb/ddxDevBtn.c
|
|
|
542d25d |
+++ /dev/null
|
|
|
542d25d |
@@ -1,69 +0,0 @@
|
|
|
542d25d |
-/************************************************************
|
|
|
542d25d |
-Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
|
|
|
542d25d |
-
|
|
|
542d25d |
-Permission to use, copy, modify, and distribute this
|
|
|
542d25d |
-software and its documentation for any purpose and without
|
|
|
542d25d |
-fee is hereby granted, provided that the above copyright
|
|
|
542d25d |
-notice appear in all copies and that both that copyright
|
|
|
542d25d |
-notice and this permission notice appear in supporting
|
|
|
542d25d |
-documentation, and that the name of Silicon Graphics not be
|
|
|
542d25d |
-used in advertising or publicity pertaining to distribution
|
|
|
542d25d |
-of the software without specific prior written permission.
|
|
|
542d25d |
-Silicon Graphics makes no representation about the suitability
|
|
|
542d25d |
-of this software for any purpose. It is provided "as is"
|
|
|
542d25d |
-without any express or implied warranty.
|
|
|
542d25d |
-
|
|
|
542d25d |
-SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
|
|
542d25d |
-SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
|
542d25d |
-AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
|
|
542d25d |
-GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
|
|
542d25d |
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
|
|
542d25d |
-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
|
|
542d25d |
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
|
|
542d25d |
-THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
542d25d |
-
|
|
|
542d25d |
-********************************************************/
|
|
|
542d25d |
-
|
|
|
542d25d |
-#ifdef HAVE_DIX_CONFIG_H
|
|
|
542d25d |
-#include <dix-config.h>
|
|
|
542d25d |
-#endif
|
|
|
542d25d |
-
|
|
|
542d25d |
-#include "inputstr.h"
|
|
|
542d25d |
-#include <xkbsrv.h>
|
|
|
542d25d |
-#include "mi.h"
|
|
|
542d25d |
-
|
|
|
542d25d |
-void
|
|
|
542d25d |
-XkbDDXFakeDeviceButton(DeviceIntPtr dev,Bool press,int button)
|
|
|
542d25d |
-{
|
|
|
542d25d |
- EventListPtr events;
|
|
|
542d25d |
- int nevents, i;
|
|
|
542d25d |
- DeviceIntPtr ptr;
|
|
|
542d25d |
-
|
|
|
542d25d |
- /* If dev is a slave device, and the SD is attached, do nothing. If we'd
|
|
|
542d25d |
- * post through the attached master pointer we'd get duplicate events.
|
|
|
542d25d |
- *
|
|
|
542d25d |
- * if dev is a master keyboard, post through the XTEST device
|
|
|
542d25d |
- *
|
|
|
542d25d |
- * if dev is a floating slave, post through the device itself.
|
|
|
542d25d |
- */
|
|
|
542d25d |
-
|
|
|
542d25d |
- if (IsMaster(dev))
|
|
|
542d25d |
- ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER));
|
|
|
542d25d |
- else if (!dev->u.master)
|
|
|
542d25d |
- ptr = dev;
|
|
|
542d25d |
- else
|
|
|
542d25d |
- return;
|
|
|
542d25d |
-
|
|
|
542d25d |
- events = InitEventList(GetMaximumEventsNum());
|
|
|
542d25d |
- OsBlockSignals();
|
|
|
542d25d |
- nevents = GetPointerEvents(events, ptr,
|
|
|
542d25d |
- press ? ButtonPress : ButtonRelease, button,
|
|
|
542d25d |
- 0 /* flags */, 0 /* first */,
|
|
|
542d25d |
- 0 /* num_val */, NULL);
|
|
|
542d25d |
- OsReleaseSignals();
|
|
|
542d25d |
-
|
|
|
542d25d |
- for (i = 0; i < nevents; i++)
|
|
|
542d25d |
- mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL);
|
|
|
542d25d |
-
|
|
|
542d25d |
- FreeEventList(events, GetMaximumEventsNum());
|
|
|
542d25d |
-}
|
|
|
542d25d |
diff --git a/xkb/ddxFakeMtn.c b/xkb/ddxFakeMtn.c
|
|
|
542d25d |
deleted file mode 100644
|
|
|
542d25d |
index b383716..0000000
|
|
|
542d25d |
--- a/xkb/ddxFakeMtn.c
|
|
|
542d25d |
+++ /dev/null
|
|
|
542d25d |
@@ -1,64 +0,0 @@
|
|
|
542d25d |
-/************************************************************
|
|
|
542d25d |
-Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
|
|
|
542d25d |
-
|
|
|
542d25d |
-Permission to use, copy, modify, and distribute this
|
|
|
542d25d |
-software and its documentation for any purpose and without
|
|
|
542d25d |
-fee is hereby granted, provided that the above copyright
|
|
|
542d25d |
-notice appear in all copies and that both that copyright
|
|
|
542d25d |
-notice and this permission notice appear in supporting
|
|
|
542d25d |
-documentation, and that the name of Silicon Graphics not be
|
|
|
542d25d |
-used in advertising or publicity pertaining to distribution
|
|
|
542d25d |
-of the software without specific prior written permission.
|
|
|
542d25d |
-Silicon Graphics makes no representation about the suitability
|
|
|
542d25d |
-of this software for any purpose. It is provided "as is"
|
|
|
542d25d |
-without any express or implied warranty.
|
|
|
542d25d |
-
|
|
|
542d25d |
-SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
|
|
542d25d |
-SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
|
542d25d |
-AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
|
|
542d25d |
-GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
|
|
542d25d |
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
|
|
542d25d |
-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
|
|
542d25d |
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
|
|
542d25d |
-THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
542d25d |
-
|
|
|
542d25d |
-********************************************************/
|
|
|
542d25d |
-
|
|
|
542d25d |
-#ifdef HAVE_DIX_CONFIG_H
|
|
|
542d25d |
-#include <dix-config.h>
|
|
|
542d25d |
-#endif
|
|
|
542d25d |
-
|
|
|
542d25d |
-#include "inputstr.h"
|
|
|
542d25d |
-#include <xkbsrv.h>
|
|
|
542d25d |
-#include "mi.h"
|
|
|
542d25d |
-
|
|
|
542d25d |
-void
|
|
|
542d25d |
-XkbDDXFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y)
|
|
|
542d25d |
-{
|
|
|
542d25d |
- EventListPtr events;
|
|
|
542d25d |
- int nevents, i;
|
|
|
542d25d |
- DeviceIntPtr ptr;
|
|
|
542d25d |
- int gpe_flags = 0;
|
|
|
542d25d |
-
|
|
|
542d25d |
- if (!dev->u.master)
|
|
|
542d25d |
- ptr = dev;
|
|
|
542d25d |
- else
|
|
|
542d25d |
- ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER));
|
|
|
542d25d |
-
|
|
|
542d25d |
- if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY)
|
|
|
542d25d |
- gpe_flags = POINTER_ABSOLUTE;
|
|
|
542d25d |
- else
|
|
|
542d25d |
- gpe_flags = POINTER_RELATIVE;
|
|
|
542d25d |
-
|
|
|
542d25d |
- events = InitEventList(GetMaximumEventsNum());
|
|
|
542d25d |
- OsBlockSignals();
|
|
|
542d25d |
- nevents = GetPointerEvents(events, ptr,
|
|
|
542d25d |
- MotionNotify, 0,
|
|
|
542d25d |
- gpe_flags, 0, 2, (int[]){x, y});
|
|
|
542d25d |
- OsReleaseSignals();
|
|
|
542d25d |
-
|
|
|
542d25d |
- for (i = 0; i < nevents; i++)
|
|
|
542d25d |
- mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL);
|
|
|
542d25d |
-
|
|
|
542d25d |
- FreeEventList(events, GetMaximumEventsNum());
|
|
|
542d25d |
-}
|
|
|
542d25d |
diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
|
|
|
542d25d |
index ab52b6a..2817e39 100644
|
|
|
542d25d |
--- a/xkb/xkbActions.c
|
|
|
542d25d |
+++ b/xkb/xkbActions.c
|
|
|
542d25d |
@@ -40,11 +40,15 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
542d25d |
#include <xkbsrv.h>
|
|
|
542d25d |
#include "xkb.h"
|
|
|
542d25d |
#include <ctype.h>
|
|
|
542d25d |
+#include "mi.h"
|
|
|
542d25d |
#define EXTENSION_EVENT_BASE 64
|
|
|
542d25d |
|
|
|
542d25d |
static int xkbDevicePrivateKeyIndex;
|
|
|
542d25d |
DevPrivateKey xkbDevicePrivateKey = &xkbDevicePrivateKeyIndex;
|
|
|
542d25d |
|
|
|
542d25d |
+static void XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button);
|
|
|
542d25d |
+static void XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y);
|
|
|
542d25d |
+
|
|
|
542d25d |
void
|
|
|
542d25d |
xkbUnwrapProc(DeviceIntPtr device, DeviceHandleProc proc,
|
|
|
542d25d |
pointer data)
|
|
|
542d25d |
@@ -479,7 +483,7 @@ int dx,dy;
|
|
|
542d25d |
dx= xkbi->mouseKeysDX;
|
|
|
542d25d |
dy= xkbi->mouseKeysDY;
|
|
|
542d25d |
}
|
|
|
542d25d |
- XkbDDXFakePointerMotion(xkbi->device, xkbi->mouseKeysFlags,dx,dy);
|
|
|
542d25d |
+ XkbFakePointerMotion(xkbi->device, xkbi->mouseKeysFlags,dx,dy);
|
|
|
542d25d |
return xkbi->desc->ctrls->mk_interval;
|
|
|
542d25d |
}
|
|
|
542d25d |
|
|
|
542d25d |
@@ -507,7 +511,7 @@ Bool accel;
|
|
|
542d25d |
accel= ((pAction->ptr.flags&XkbSA_NoAcceleration)==0);
|
|
|
542d25d |
x= XkbPtrActionX(&pAction->ptr);
|
|
|
542d25d |
y= XkbPtrActionY(&pAction->ptr);
|
|
|
542d25d |
- XkbDDXFakePointerMotion(xkbi->device, pAction->ptr.flags,x,y);
|
|
|
542d25d |
+ XkbFakePointerMotion(xkbi->device, pAction->ptr.flags,x,y);
|
|
|
542d25d |
AccessXCancelRepeatKey(xkbi,keycode);
|
|
|
542d25d |
xkbi->mouseKeysAccel= accel&&
|
|
|
542d25d |
(xkbi->desc->ctrls->enabled_ctrls&XkbMouseKeysAccelMask);
|
|
|
542d25d |
@@ -554,7 +558,7 @@ _XkbFilterPointerBtn( XkbSrvInfoPtr xkbi,
|
|
|
542d25d |
((pAction->btn.flags&XkbSA_LockNoLock)==0)) {
|
|
|
542d25d |
xkbi->lockedPtrButtons|= (1<
|
|
|
542d25d |
AccessXCancelRepeatKey(xkbi,keycode);
|
|
|
542d25d |
- XkbDDXFakeDeviceButton(xkbi->device, 1, button);
|
|
|
542d25d |
+ XkbFakeDeviceButton(xkbi->device, 1, button);
|
|
|
542d25d |
filter->upAction.type= XkbSA_NoAction;
|
|
|
542d25d |
}
|
|
|
542d25d |
break;
|
|
|
542d25d |
@@ -565,12 +569,12 @@ _XkbFilterPointerBtn( XkbSrvInfoPtr xkbi,
|
|
|
542d25d |
if (pAction->btn.count>0) {
|
|
|
542d25d |
nClicks= pAction->btn.count;
|
|
|
542d25d |
for (i=0;i
|
|
|
542d25d |
- XkbDDXFakeDeviceButton(xkbi->device, 1, button);
|
|
|
542d25d |
- XkbDDXFakeDeviceButton(xkbi->device, 0, button);
|
|
|
542d25d |
+ XkbFakeDeviceButton(xkbi->device, 1, button);
|
|
|
542d25d |
+ XkbFakeDeviceButton(xkbi->device, 0, button);
|
|
|
542d25d |
}
|
|
|
542d25d |
filter->upAction.type= XkbSA_NoAction;
|
|
|
542d25d |
}
|
|
|
542d25d |
- else XkbDDXFakeDeviceButton(xkbi->device, 1, button);
|
|
|
542d25d |
+ else XkbFakeDeviceButton(xkbi->device, 1, button);
|
|
|
542d25d |
}
|
|
|
542d25d |
break;
|
|
|
542d25d |
case XkbSA_SetPtrDflt:
|
|
|
542d25d |
@@ -636,7 +640,7 @@ _XkbFilterPointerBtn( XkbSrvInfoPtr xkbi,
|
|
|
542d25d |
|
|
|
542d25d |
/* fallthrough */
|
|
|
542d25d |
case XkbSA_PtrBtn:
|
|
|
542d25d |
- XkbDDXFakeDeviceButton(xkbi->device, 0, button);
|
|
|
542d25d |
+ XkbFakeDeviceButton(xkbi->device, 0, button);
|
|
|
542d25d |
break;
|
|
|
542d25d |
}
|
|
|
542d25d |
filter->active = 0;
|
|
|
542d25d |
@@ -974,7 +978,7 @@ int button;
|
|
|
542d25d |
if ((pAction->devbtn.flags&XkbSA_LockNoLock)||
|
|
|
542d25d |
BitIsOn(dev->button->down, button))
|
|
|
542d25d |
return 0;
|
|
|
542d25d |
- XkbDDXFakeDeviceButton(dev,TRUE,button);
|
|
|
542d25d |
+ XkbFakeDeviceButton(dev,TRUE,button);
|
|
|
542d25d |
filter->upAction.type= XkbSA_NoAction;
|
|
|
542d25d |
break;
|
|
|
542d25d |
case XkbSA_DeviceBtn:
|
|
|
542d25d |
@@ -982,12 +986,12 @@ int button;
|
|
|
542d25d |
int nClicks,i;
|
|
|
542d25d |
nClicks= pAction->btn.count;
|
|
|
542d25d |
for (i=0;i
|
|
|
542d25d |
- XkbDDXFakeDeviceButton(dev,TRUE,button);
|
|
|
542d25d |
- XkbDDXFakeDeviceButton(dev,FALSE,button);
|
|
|
542d25d |
+ XkbFakeDeviceButton(dev,TRUE,button);
|
|
|
542d25d |
+ XkbFakeDeviceButton(dev,FALSE,button);
|
|
|
542d25d |
}
|
|
|
542d25d |
filter->upAction.type= XkbSA_NoAction;
|
|
|
542d25d |
}
|
|
|
542d25d |
- else XkbDDXFakeDeviceButton(dev,TRUE,button);
|
|
|
542d25d |
+ else XkbFakeDeviceButton(dev,TRUE,button);
|
|
|
542d25d |
break;
|
|
|
542d25d |
}
|
|
|
542d25d |
}
|
|
|
542d25d |
@@ -1006,10 +1010,10 @@ int button;
|
|
|
542d25d |
if ((filter->upAction.devbtn.flags&XkbSA_LockNoUnlock)||
|
|
|
542d25d |
!BitIsOn(dev->button->down, button))
|
|
|
542d25d |
return 0;
|
|
|
542d25d |
- XkbDDXFakeDeviceButton(dev,FALSE,button);
|
|
|
542d25d |
+ XkbFakeDeviceButton(dev,FALSE,button);
|
|
|
542d25d |
break;
|
|
|
542d25d |
case XkbSA_DeviceBtn:
|
|
|
542d25d |
- XkbDDXFakeDeviceButton(dev,FALSE,button);
|
|
|
542d25d |
+ XkbFakeDeviceButton(dev,FALSE,button);
|
|
|
542d25d |
break;
|
|
|
542d25d |
}
|
|
|
542d25d |
filter->active = 0;
|
|
|
542d25d |
@@ -1326,3 +1330,70 @@ xkbStateNotify sn;
|
|
|
542d25d |
return;
|
|
|
542d25d |
}
|
|
|
542d25d |
|
|
|
542d25d |
+static void
|
|
|
542d25d |
+XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y)
|
|
|
542d25d |
+{
|
|
|
542d25d |
+ EventListPtr events;
|
|
|
542d25d |
+ int nevents, i;
|
|
|
542d25d |
+ DeviceIntPtr ptr;
|
|
|
542d25d |
+ int gpe_flags = 0;
|
|
|
542d25d |
+
|
|
|
542d25d |
+ if (!dev->u.master)
|
|
|
542d25d |
+ ptr = dev;
|
|
|
542d25d |
+ else
|
|
|
542d25d |
+ ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER));
|
|
|
542d25d |
+
|
|
|
542d25d |
+ if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY)
|
|
|
542d25d |
+ gpe_flags = POINTER_ABSOLUTE;
|
|
|
542d25d |
+ else
|
|
|
542d25d |
+ gpe_flags = POINTER_RELATIVE;
|
|
|
542d25d |
+
|
|
|
542d25d |
+ events = InitEventList(GetMaximumEventsNum());
|
|
|
542d25d |
+ OsBlockSignals();
|
|
|
542d25d |
+ nevents = GetPointerEvents(events, ptr,
|
|
|
542d25d |
+ MotionNotify, 0,
|
|
|
542d25d |
+ gpe_flags, 0, 2, (int[]){x, y});
|
|
|
542d25d |
+ OsReleaseSignals();
|
|
|
542d25d |
+
|
|
|
542d25d |
+ for (i = 0; i < nevents; i++)
|
|
|
542d25d |
+ mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL);
|
|
|
542d25d |
+
|
|
|
542d25d |
+ FreeEventList(events, GetMaximumEventsNum());
|
|
|
542d25d |
+}
|
|
|
542d25d |
+
|
|
|
542d25d |
+static void
|
|
|
542d25d |
+XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button)
|
|
|
542d25d |
+{
|
|
|
542d25d |
+ EventListPtr events;
|
|
|
542d25d |
+ int nevents, i;
|
|
|
542d25d |
+ DeviceIntPtr ptr;
|
|
|
542d25d |
+
|
|
|
542d25d |
+ /* If dev is a slave device, and the SD is attached, do nothing. If we'd
|
|
|
542d25d |
+ * post through the attached master pointer we'd get duplicate events.
|
|
|
542d25d |
+ *
|
|
|
542d25d |
+ * if dev is a master keyboard, post through the XTEST device
|
|
|
542d25d |
+ *
|
|
|
542d25d |
+ * if dev is a floating slave, post through the device itself.
|
|
|
542d25d |
+ */
|
|
|
542d25d |
+
|
|
|
542d25d |
+ if (IsMaster(dev))
|
|
|
542d25d |
+ ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER));
|
|
|
542d25d |
+ else if (!dev->u.master)
|
|
|
542d25d |
+ ptr = dev;
|
|
|
542d25d |
+ else
|
|
|
542d25d |
+ return;
|
|
|
542d25d |
+
|
|
|
542d25d |
+ events = InitEventList(GetMaximumEventsNum());
|
|
|
542d25d |
+ OsBlockSignals();
|
|
|
542d25d |
+ nevents = GetPointerEvents(events, ptr,
|
|
|
542d25d |
+ press ? ButtonPress : ButtonRelease, button,
|
|
|
542d25d |
+ 0 /* flags */, 0 /* first */,
|
|
|
542d25d |
+ 0 /* num_val */, NULL);
|
|
|
542d25d |
+ OsReleaseSignals();
|
|
|
542d25d |
+
|
|
|
542d25d |
+
|
|
|
542d25d |
+ for (i = 0; i < nevents; i++)
|
|
|
542d25d |
+ mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL);
|
|
|
542d25d |
+
|
|
|
542d25d |
+ FreeEventList(events, GetMaximumEventsNum());
|
|
|
542d25d |
+}
|
|
|
542d25d |
--
|
|
|
542d25d |
1.7.1
|
|
|
542d25d |
|
|
|
542d25d |
From dcb46252f959893f1934232698e2ae26390a8a5b Mon Sep 17 00:00:00 2001
|
|
|
542d25d |
From: Peter Hutterer <peter.hutterer@who-t.net>
|
|
|
542d25d |
Date: Tue, 29 Jun 2010 15:24:51 +1000
|
|
|
542d25d |
Subject: [PATCH 4/5] xkb: emulate PointerKeys events only on the master device.
|
|
|
542d25d |
|
|
|
542d25d |
This patch replicates the behaviour for button events. Only generate a
|
|
|
542d25d |
PointerKeys motion event on the master device, not on the slave device.
|
|
|
542d25d |
Fixes the current issue of PointerKey motion events generating key events as
|
|
|
542d25d |
well.
|
|
|
542d25d |
|
|
|
542d25d |
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
|
|
542d25d |
---
|
|
|
542d25d |
xkb/xkbActions.c | 9 ++++-----
|
|
|
542d25d |
1 files changed, 4 insertions(+), 5 deletions(-)
|
|
|
542d25d |
|
|
|
542d25d |
diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
|
|
|
542d25d |
index 2817e39..391c375 100644
|
|
|
542d25d |
--- a/xkb/xkbActions.c
|
|
|
542d25d |
+++ b/xkb/xkbActions.c
|
|
|
542d25d |
@@ -496,9 +496,6 @@ _XkbFilterPointerMove( XkbSrvInfoPtr xkbi,
|
|
|
542d25d |
int x,y;
|
|
|
542d25d |
Bool accel;
|
|
|
542d25d |
|
|
|
542d25d |
- if (xkbi->device == inputInfo.keyboard)
|
|
|
542d25d |
- return 0;
|
|
|
542d25d |
-
|
|
|
542d25d |
if (filter->keycode==0) { /* initial press */
|
|
|
542d25d |
filter->keycode = keycode;
|
|
|
542d25d |
filter->active = 1;
|
|
|
542d25d |
@@ -1338,10 +1335,12 @@ XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y)
|
|
|
542d25d |
DeviceIntPtr ptr;
|
|
|
542d25d |
int gpe_flags = 0;
|
|
|
542d25d |
|
|
|
542d25d |
- if (!dev->u.master)
|
|
|
542d25d |
+ if (IsMaster(dev))
|
|
|
542d25d |
+ ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER));
|
|
|
542d25d |
+ else if (!dev->u.master)
|
|
|
542d25d |
ptr = dev;
|
|
|
542d25d |
else
|
|
|
542d25d |
- ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER));
|
|
|
542d25d |
+ return;
|
|
|
542d25d |
|
|
|
542d25d |
if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY)
|
|
|
542d25d |
gpe_flags = POINTER_ABSOLUTE;
|
|
|
542d25d |
--
|
|
|
542d25d |
1.7.1
|
|
|
542d25d |
|
|
|
542d25d |
From 40941fb2e9ae763add7b74850e8a0471ac754db6 Mon Sep 17 00:00:00 2001
|
|
|
542d25d |
From: Peter Hutterer <peter.hutterer@who-t.net>
|
|
|
542d25d |
Date: Thu, 1 Jul 2010 12:44:57 +1000
|
|
|
542d25d |
Subject: [PATCH 5/5] xkb: release XTEST pointer buttons on physical releases. (#28808)
|
|
|
542d25d |
|
|
|
542d25d |
If a button release event is posted for the MD pointer, post a release event
|
|
|
542d25d |
through the matching XTEST device. This way, a client who posts a button
|
|
|
542d25d |
press through the XTEST extension cannot inadvertedly lock the button.
|
|
|
542d25d |
|
|
|
542d25d |
This behaviour is required for historical reasons, until server 1.7 the core
|
|
|
542d25d |
pointer would release a button press on physical events, regardless of the
|
|
|
542d25d |
XTEST state. Clients seem to rely on this behaviour, causing seemingly stuck
|
|
|
542d25d |
grabs.
|
|
|
542d25d |
|
|
|
542d25d |
The merged behaviour is kept for multiple keyboard PointerKey events, if two
|
|
|
542d25d |
physical keyboards hold the button down as a result of PointerKey actions,
|
|
|
542d25d |
the button is not released until the last keyboard releases the button.
|
|
|
542d25d |
|
|
|
542d25d |
X.Org Bug 28808 <http://bugs.freedesktop.org/show_bug.cgi?id=28808>
|
|
|
542d25d |
|
|
|
542d25d |
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
|
|
542d25d |
---
|
|
|
542d25d |
include/xkbsrv.h | 6 ++++++
|
|
|
542d25d |
xkb/xkbAccessX.c | 23 ++++++++++-------------
|
|
|
542d25d |
xkb/xkbActions.c | 4 ++--
|
|
|
542d25d |
3 files changed, 18 insertions(+), 15 deletions(-)
|
|
|
542d25d |
|
|
|
542d25d |
diff --git a/include/xkbsrv.h b/include/xkbsrv.h
|
|
|
542d25d |
index d1cbd1a..a96ca56 100644
|
|
|
542d25d |
--- a/include/xkbsrv.h
|
|
|
542d25d |
+++ b/include/xkbsrv.h
|
|
|
542d25d |
@@ -923,6 +923,12 @@ extern int XkbGetEffectiveGroup(
|
|
|
542d25d |
extern void XkbMergeLockedPtrBtns(
|
|
|
542d25d |
DeviceIntPtr /* master */);
|
|
|
542d25d |
|
|
|
542d25d |
+extern void XkbFakeDeviceButton(
|
|
|
542d25d |
+ DeviceIntPtr /* dev */,
|
|
|
542d25d |
+ int /* press */,
|
|
|
542d25d |
+ int /* button */);
|
|
|
542d25d |
+
|
|
|
542d25d |
+
|
|
|
542d25d |
#include "xkbfile.h"
|
|
|
542d25d |
#include "xkbrules.h"
|
|
|
542d25d |
|
|
|
542d25d |
diff --git a/xkb/xkbAccessX.c b/xkb/xkbAccessX.c
|
|
|
542d25d |
index e3fdc06..d3f9652 100644
|
|
|
542d25d |
--- a/xkb/xkbAccessX.c
|
|
|
542d25d |
+++ b/xkb/xkbAccessX.c
|
|
|
542d25d |
@@ -710,19 +710,16 @@ DeviceEvent *event = &ev->device_event;
|
|
|
542d25d |
if (xkbi) {
|
|
|
542d25d |
xkbi->lockedPtrButtons&= ~(1 << (event->detail.key & 0x7));
|
|
|
542d25d |
|
|
|
542d25d |
- /* Merge this MD's lockedPtrButtons with the one of all
|
|
|
542d25d |
- * attached slave devices.
|
|
|
542d25d |
- * The DIX uses a merged button state for MDs, not
|
|
|
542d25d |
- * releasing buttons until the last SD has released
|
|
|
542d25d |
- * thenm. If we unconditionally clear the
|
|
|
542d25d |
- * lockedPtrButtons bit on the MD, a PointerKeys button
|
|
|
542d25d |
- * release on the SD keyboard won't generate the required fake button
|
|
|
542d25d |
- * event on the XTEST pointer, thus never processing the
|
|
|
542d25d |
- * button event in the DIX and the XTEST pointer's
|
|
|
542d25d |
- * buttons stay down - result is a stuck button.
|
|
|
542d25d |
- */
|
|
|
542d25d |
- if (IsMaster(dev))
|
|
|
542d25d |
- XkbMergeLockedPtrBtns(dev);
|
|
|
542d25d |
+ if (IsMaster(dev))
|
|
|
542d25d |
+ {
|
|
|
542d25d |
+ DeviceIntPtr source;
|
|
|
542d25d |
+ int rc;
|
|
|
542d25d |
+ rc = dixLookupDevice(&source, event->sourceid, serverClient, DixWriteAccess);
|
|
|
542d25d |
+ if (rc != Success)
|
|
|
542d25d |
+ ErrorF("[xkb] bad sourceid '%d' on button release event.\n", event->sourceid);
|
|
|
542d25d |
+ else if (!IsXTestDevice(source, GetMaster(dev, MASTER_POINTER)))
|
|
|
542d25d |
+ XkbFakeDeviceButton(dev, FALSE, event->detail.key);
|
|
|
542d25d |
+ }
|
|
|
542d25d |
}
|
|
|
542d25d |
|
|
|
542d25d |
changed |= XkbPointerButtonMask;
|
|
|
542d25d |
diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
|
|
|
542d25d |
index 391c375..5d40199 100644
|
|
|
542d25d |
--- a/xkb/xkbActions.c
|
|
|
542d25d |
+++ b/xkb/xkbActions.c
|
|
|
542d25d |
@@ -46,7 +46,7 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
542d25d |
static int xkbDevicePrivateKeyIndex;
|
|
|
542d25d |
DevPrivateKey xkbDevicePrivateKey = &xkbDevicePrivateKeyIndex;
|
|
|
542d25d |
|
|
|
542d25d |
-static void XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button);
|
|
|
542d25d |
+void XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button);
|
|
|
542d25d |
static void XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y);
|
|
|
542d25d |
|
|
|
542d25d |
void
|
|
|
542d25d |
@@ -1360,7 +1360,7 @@ XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y)
|
|
|
542d25d |
FreeEventList(events, GetMaximumEventsNum());
|
|
|
542d25d |
}
|
|
|
542d25d |
|
|
|
542d25d |
-static void
|
|
|
542d25d |
+void
|
|
|
542d25d |
XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button)
|
|
|
542d25d |
{
|
|
|
542d25d |
EventListPtr events;
|
|
|
542d25d |
--
|
|
|
542d25d |
1.7.1
|
|
|
542d25d |
|
|
Peter Hutterer |
8be23b2 |
From 7273832bcdc6f43e9a5a8fdbb56844466efb710a Mon Sep 17 00:00:00 2001
|
|
Peter Hutterer |
8be23b2 |
From: Peter Hutterer <peter.hutterer@who-t.net>
|
|
Peter Hutterer |
8be23b2 |
Date: Fri, 23 Jul 2010 11:46:30 +1000
|
|
Peter Hutterer |
8be23b2 |
Subject: [PATCH 1/3] xkb: post-fix PointerKeys button events with a DeviceChangedEvent.
|
|
Peter Hutterer |
8be23b2 |
|
|
Peter Hutterer |
8be23b2 |
commit 14327858391ebe929b806efb53ad79e789361883
|
|
Peter Hutterer |
8be23b2 |
xkb: release XTEST pointer buttons on physical releases. (#28808)
|
|
Peter Hutterer |
8be23b2 |
revealed a bug with the XTEST/PointerKeys interaction.
|
|
Peter Hutterer |
8be23b2 |
|
|
Peter Hutterer |
8be23b2 |
Events resulting from PointerKeys are injected into the event processing
|
|
Peter Hutterer |
8be23b2 |
stream, not appended to the event queue. The events generated for the fake
|
|
Peter Hutterer |
8be23b2 |
button press include a DeviceChangedEvent (DCE), a raw button event and the
|
|
Peter Hutterer |
8be23b2 |
button event itself. The DCE causes the master to switch classes to the
|
|
Peter Hutterer |
8be23b2 |
attached XTEST pointer device.
|
|
Peter Hutterer |
8be23b2 |
|
|
Peter Hutterer |
8be23b2 |
Once the fake button is processed, normal event processing continues with
|
|
Peter Hutterer |
8be23b2 |
events in the EQ. The master still contains the XTEST classes, causing some
|
|
Peter Hutterer |
8be23b2 |
events to be dropped if e.g. the number of valuators of the event in the
|
|
Peter Hutterer |
8be23b2 |
queue exceeds the XTEST device's number of valuators.
|
|
Peter Hutterer |
8be23b2 |
|
|
Peter Hutterer |
8be23b2 |
Example: the EQ contains the following events, processed one-by-one, left to
|
|
Peter Hutterer |
8be23b2 |
right.
|
|
Peter Hutterer |
8be23b2 |
|
|
Peter Hutterer |
8be23b2 |
[DCE (dev)][Btn down][Btn up][Motion][Motion][...]
|
|
Peter Hutterer |
8be23b2 |
^ XkbFakeDeviceButton injects [DCE (XTEST)][Btn up]
|
|
Peter Hutterer |
8be23b2 |
|
|
Peter Hutterer |
8be23b2 |
Thus the event sequence processed looks like this:
|
|
Peter Hutterer |
8be23b2 |
|
|
Peter Hutterer |
8be23b2 |
[DCE (dev)][Btn down][Btn up][DCE (XTEST)][Btn up][Motion][Motion][...]
|
|
Peter Hutterer |
8be23b2 |
|
|
Peter Hutterer |
8be23b2 |
The first DCE causes the master to switch to the device. The button up event
|
|
Peter Hutterer |
8be23b2 |
injects a DCE to the XTEST device, causing the following Motion events to be
|
|
Peter Hutterer |
8be23b2 |
processed with the master still being on XTEST classes.
|
|
Peter Hutterer |
8be23b2 |
|
|
Peter Hutterer |
8be23b2 |
This patch post-fixes the injected event sequence with a DCE to restore the
|
|
Peter Hutterer |
8be23b2 |
classes of the original slave device, resulting in an event sequence like
|
|
Peter Hutterer |
8be23b2 |
this:
|
|
Peter Hutterer |
8be23b2 |
[DCE (dev)][Btn down][Btn up][DCE (XTEST)][Btn up][DCE (dev)][Motion][Motion]
|
|
Peter Hutterer |
8be23b2 |
|
|
Peter Hutterer |
8be23b2 |
Note that this is a simplified description. The event sequence injected by
|
|
Peter Hutterer |
8be23b2 |
the PointerKeys code is injected for the master device only and the matching
|
|
Peter Hutterer |
8be23b2 |
slave device that caused the injection has already finished processing on
|
|
Peter Hutterer |
8be23b2 |
the slave. Furthermore, the injection happens as part of the the XKB layer,
|
|
Peter Hutterer |
8be23b2 |
before the unwrapping of the processInputProc takes us into the DIX where
|
|
Peter Hutterer |
8be23b2 |
the DCE is actually handled.
|
|
Peter Hutterer |
8be23b2 |
|
|
Peter Hutterer |
8be23b2 |
Bug reproducible with a device that reports more than 2 valuators. Simply
|
|
Peter Hutterer |
8be23b2 |
cause button releases on the device and wait for a "too many valuators"
|
|
Peter Hutterer |
8be23b2 |
warning message.
|
|
Peter Hutterer |
8be23b2 |
|
|
Peter Hutterer |
8be23b2 |
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
|
Peter Hutterer |
8be23b2 |
---
|
|
Peter Hutterer |
8be23b2 |
xkb/xkbActions.c | 26 +++++++++++++++++++-------
|
|
Peter Hutterer |
8be23b2 |
1 files changed, 19 insertions(+), 7 deletions(-)
|
|
Peter Hutterer |
8be23b2 |
|
|
Peter Hutterer |
8be23b2 |
diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
|
|
Peter Hutterer |
8be23b2 |
index 5d40199..2afd46d 100644
|
|
Peter Hutterer |
8be23b2 |
--- a/xkb/xkbActions.c
|
|
Peter Hutterer |
8be23b2 |
+++ b/xkb/xkbActions.c
|
|
Peter Hutterer |
8be23b2 |
@@ -1365,34 +1365,46 @@ XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button)
|
|
Peter Hutterer |
8be23b2 |
{
|
|
Peter Hutterer |
8be23b2 |
EventListPtr events;
|
|
Peter Hutterer |
8be23b2 |
int nevents, i;
|
|
Peter Hutterer |
8be23b2 |
- DeviceIntPtr ptr;
|
|
Peter Hutterer |
8be23b2 |
+ DeviceIntPtr ptr, mpointer, lastSlave;
|
|
Peter Hutterer |
8be23b2 |
|
|
Peter Hutterer |
8be23b2 |
/* If dev is a slave device, and the SD is attached, do nothing. If we'd
|
|
Peter Hutterer |
8be23b2 |
* post through the attached master pointer we'd get duplicate events.
|
|
Peter Hutterer |
8be23b2 |
*
|
|
Peter Hutterer |
8be23b2 |
* if dev is a master keyboard, post through the XTEST device
|
|
Peter Hutterer |
8be23b2 |
- *
|
|
Peter Hutterer |
8be23b2 |
* if dev is a floating slave, post through the device itself.
|
|
Peter Hutterer |
8be23b2 |
+ *
|
|
Peter Hutterer |
8be23b2 |
+ * The event is injected into the event processing, not the EQ. Thus,
|
|
Peter Hutterer |
8be23b2 |
+ * ensure that we restore the master after the event sequence to the
|
|
Peter Hutterer |
8be23b2 |
+ * original set of classes. Otherwise, the master remains on the XTEST
|
|
Peter Hutterer |
8be23b2 |
+ * classes and drops events that don't fit into the XTEST layout (e.g.
|
|
Peter Hutterer |
8be23b2 |
+ * events with more than 2 valuators).
|
|
Peter Hutterer |
8be23b2 |
+ * To do so, we remember the lastSlave that posted through the master
|
|
Peter Hutterer |
8be23b2 |
+ * and add a DeviceChangedEvent to the end of the list.
|
|
Peter Hutterer |
8be23b2 |
*/
|
|
Peter Hutterer |
8be23b2 |
|
|
Peter Hutterer |
8be23b2 |
- if (IsMaster(dev))
|
|
Peter Hutterer |
8be23b2 |
- ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER));
|
|
Peter Hutterer |
8be23b2 |
- else if (!dev->u.master)
|
|
Peter Hutterer |
8be23b2 |
+ if (IsMaster(dev)) {
|
|
Peter Hutterer |
8be23b2 |
+ mpointer = GetMaster(dev, MASTER_POINTER);
|
|
Peter Hutterer |
8be23b2 |
+ lastSlave = mpointer->u.lastSlave;
|
|
Peter Hutterer |
8be23b2 |
+ ptr = GetXTestDevice(mpointer);
|
|
Peter Hutterer |
8be23b2 |
+ } else if (!dev->u.master)
|
|
Peter Hutterer |
8be23b2 |
ptr = dev;
|
|
Peter Hutterer |
8be23b2 |
else
|
|
Peter Hutterer |
8be23b2 |
return;
|
|
Peter Hutterer |
8be23b2 |
|
|
Peter Hutterer |
8be23b2 |
- events = InitEventList(GetMaximumEventsNum());
|
|
Peter Hutterer |
8be23b2 |
+ events = InitEventList(GetMaximumEventsNum() + 1);
|
|
Peter Hutterer |
8be23b2 |
OsBlockSignals();
|
|
Peter Hutterer |
8be23b2 |
nevents = GetPointerEvents(events, ptr,
|
|
Peter Hutterer |
8be23b2 |
press ? ButtonPress : ButtonRelease, button,
|
|
Peter Hutterer |
8be23b2 |
0 /* flags */, 0 /* first */,
|
|
Peter Hutterer |
8be23b2 |
0 /* num_val */, NULL);
|
|
Peter Hutterer |
8be23b2 |
+ if (IsMaster(dev) && (lastSlave && lastSlave != ptr))
|
|
Peter Hutterer |
8be23b2 |
+ CreateClassesChangedEvent(&events[nevents++], mpointer,
|
|
Peter Hutterer |
8be23b2 |
+ lastSlave, DEVCHANGE_POINTER_EVENT);
|
|
Peter Hutterer |
8be23b2 |
OsReleaseSignals();
|
|
Peter Hutterer |
8be23b2 |
|
|
Peter Hutterer |
8be23b2 |
|
|
Peter Hutterer |
8be23b2 |
for (i = 0; i < nevents; i++)
|
|
Peter Hutterer |
8be23b2 |
mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL);
|
|
Peter Hutterer |
8be23b2 |
|
|
Peter Hutterer |
8be23b2 |
- FreeEventList(events, GetMaximumEventsNum());
|
|
Peter Hutterer |
8be23b2 |
+ FreeEventList(events, GetMaximumEventsNum() + 1);
|
|
Peter Hutterer |
8be23b2 |
}
|
|
Peter Hutterer |
8be23b2 |
--
|
|
Peter Hutterer |
8be23b2 |
1.7.2
|
|
Peter Hutterer |
8be23b2 |
|
|
Peter Hutterer |
8be23b2 |
From 817e031a996a5f5aa16fc789d7e570cc589d96cb Mon Sep 17 00:00:00 2001
|
|
Peter Hutterer |
8be23b2 |
From: Peter Hutterer <peter.hutterer@who-t.net>
|
|
Peter Hutterer |
8be23b2 |
Date: Wed, 28 Jul 2010 14:24:59 +1000
|
|
Peter Hutterer |
8be23b2 |
Subject: [PATCH 3/3] Xi: reset the unused classes pointer after copying
|
|
Peter Hutterer |
8be23b2 |
|
|
Peter Hutterer |
8be23b2 |
After copying the unused_classes into the device, reset the original
|
|
Peter Hutterer |
8be23b2 |
pointer. Otherwise we have two pointers pointing to the same field and both
|
|
Peter Hutterer |
8be23b2 |
get freed on device removal.
|
|
Peter Hutterer |
8be23b2 |
|
|
Peter Hutterer |
8be23b2 |
Some classes already have this behaviour since 51c8fd69.
|
|
Peter Hutterer |
8be23b2 |
|
|
Peter Hutterer |
8be23b2 |
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
|
Peter Hutterer |
8be23b2 |
---
|
|
Peter Hutterer |
8be23b2 |
Xi/exevents.c | 6 ++++++
|
|
Peter Hutterer |
8be23b2 |
1 files changed, 6 insertions(+), 0 deletions(-)
|
|
Peter Hutterer |
8be23b2 |
|
|
Peter Hutterer |
8be23b2 |
diff --git a/Xi/exevents.c b/Xi/exevents.c
|
|
Peter Hutterer |
8be23b2 |
index 566b0ef..a6160dd 100644
|
|
Peter Hutterer |
8be23b2 |
--- a/Xi/exevents.c
|
|
Peter Hutterer |
8be23b2 |
+++ b/Xi/exevents.c
|
|
Peter Hutterer |
8be23b2 |
@@ -227,6 +227,7 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
|
|
Peter Hutterer |
8be23b2 |
classes = dixLookupPrivate(&to->devPrivates,
|
|
Peter Hutterer |
8be23b2 |
UnusedClassesPrivateKey);
|
|
Peter Hutterer |
8be23b2 |
to->intfeed = classes->intfeed;
|
|
Peter Hutterer |
8be23b2 |
+ classes->intfeed = NULL;
|
|
Peter Hutterer |
8be23b2 |
}
|
|
Peter Hutterer |
8be23b2 |
|
|
Peter Hutterer |
8be23b2 |
i = &to->intfeed;
|
|
Peter Hutterer |
8be23b2 |
@@ -263,6 +264,7 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
|
|
Peter Hutterer |
8be23b2 |
classes = dixLookupPrivate(&to->devPrivates,
|
|
Peter Hutterer |
8be23b2 |
UnusedClassesPrivateKey);
|
|
Peter Hutterer |
8be23b2 |
to->stringfeed = classes->stringfeed;
|
|
Peter Hutterer |
8be23b2 |
+ classes->stringfeed = NULL;
|
|
Peter Hutterer |
8be23b2 |
}
|
|
Peter Hutterer |
8be23b2 |
|
|
Peter Hutterer |
8be23b2 |
s = &to->stringfeed;
|
|
Peter Hutterer |
8be23b2 |
@@ -299,6 +301,7 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
|
|
Peter Hutterer |
8be23b2 |
classes = dixLookupPrivate(&to->devPrivates,
|
|
Peter Hutterer |
8be23b2 |
UnusedClassesPrivateKey);
|
|
Peter Hutterer |
8be23b2 |
to->bell = classes->bell;
|
|
Peter Hutterer |
8be23b2 |
+ classes->bell = NULL;
|
|
Peter Hutterer |
8be23b2 |
}
|
|
Peter Hutterer |
8be23b2 |
|
|
Peter Hutterer |
8be23b2 |
b = &to->bell;
|
|
Peter Hutterer |
8be23b2 |
@@ -336,6 +339,7 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
|
|
Peter Hutterer |
8be23b2 |
classes = dixLookupPrivate(&to->devPrivates,
|
|
Peter Hutterer |
8be23b2 |
UnusedClassesPrivateKey);
|
|
Peter Hutterer |
8be23b2 |
to->leds = classes->leds;
|
|
Peter Hutterer |
8be23b2 |
+ classes->leds = NULL;
|
|
Peter Hutterer |
8be23b2 |
}
|
|
Peter Hutterer |
8be23b2 |
|
|
Peter Hutterer |
8be23b2 |
l = &to->leds;
|
|
Peter Hutterer |
8be23b2 |
@@ -387,6 +391,7 @@ DeepCopyKeyboardClasses(DeviceIntPtr from, DeviceIntPtr to)
|
|
Peter Hutterer |
8be23b2 |
to->kbdfeed = classes->kbdfeed;
|
|
Peter Hutterer |
8be23b2 |
if (!to->kbdfeed)
|
|
Peter Hutterer |
8be23b2 |
InitKeyboardDeviceStruct(to, NULL, NULL, NULL);
|
|
Peter Hutterer |
8be23b2 |
+ classes->kbdfeed = NULL;
|
|
Peter Hutterer |
8be23b2 |
}
|
|
Peter Hutterer |
8be23b2 |
|
|
Peter Hutterer |
8be23b2 |
k = &to->kbdfeed;
|
|
Peter Hutterer |
8be23b2 |
@@ -517,6 +522,7 @@ DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to)
|
|
Peter Hutterer |
8be23b2 |
classes = dixLookupPrivate(&to->devPrivates,
|
|
Peter Hutterer |
8be23b2 |
UnusedClassesPrivateKey);
|
|
Peter Hutterer |
8be23b2 |
to->ptrfeed = classes->ptrfeed;
|
|
Peter Hutterer |
8be23b2 |
+ classes->ptrfeed = NULL;
|
|
Peter Hutterer |
8be23b2 |
}
|
|
Peter Hutterer |
8be23b2 |
|
|
Peter Hutterer |
8be23b2 |
p = &to->ptrfeed;
|
|
Peter Hutterer |
8be23b2 |
--
|
|
Peter Hutterer |
8be23b2 |
1.7.2
|
|
Peter Hutterer |
8be23b2 |
|