summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorTakao Fujiwara <tfujiwar@redhat.com>2024-04-12 10:21:41 +0900
committerTakao Fujiwara <tfujiwar@redhat.com>2024-04-12 10:21:41 +0900
commit13e9ac4d458069c81d795f6b4842814d30431b4b (patch)
treeebec3b4e4e7b2182fc68da97e436b341d639d2f3 /modules
parenta465588218c1643eedc35b3c24409cb775454eee (diff)
ximcp: Unmark to fabricate key events with XKeyEvent serial
_XimProtoKeypressFilter() and _XimProtoKeyreleaseFilter() can receive XKeyEvent from both the typing on the keyboard and the callback of XIM_FORWARD_EVENT. If the filter functions unmark to fabricate XKeyEvent from the typing on the keyboard during receiving XKeyEvent from the callback of XIM_FORWARD_EVENT with typing keys very quickly likes an bar code scanner (or evemu-play), XIM server cannot receive some key events and it causes the key typing order to get scrambled. Now XIM client saves the serial in XKeyEvent and the filter functions unmark to fabricate XKeyEvent from the callback of XIM_FORWARD_EVENT only. This and 024d229f are same patches but the regression issues will be fixed by the later patches. Closes: #198 Fixes: 024d229f ("ximcp: Unmark to fabricate key events with XKeyEvent serial") Part-of: <https://gitlab.freedesktop.org/xorg/lib/libx11/-/merge_requests/246>
Diffstat (limited to 'modules')
-rw-r--r--modules/im/ximcp/imDefFlt.c8
-rw-r--r--modules/im/ximcp/imDefIm.c1
-rw-r--r--modules/im/ximcp/imDefLkup.c58
3 files changed, 58 insertions, 9 deletions
diff --git a/modules/im/ximcp/imDefFlt.c b/modules/im/ximcp/imDefFlt.c
index 44cc6884..834b9db4 100644
--- a/modules/im/ximcp/imDefFlt.c
+++ b/modules/im/ximcp/imDefFlt.c
@@ -142,9 +142,9 @@ _XimProtoKeypressFilter(
{
Xim im = (Xim)ic->core.im;
- if (IS_FABRICATED(im)) {
+ if (_XimIsFabricatedSerial(im, ev->serial)) {
_XimPendingFilter(ic);
- UNMARK_FABRICATED(im);
+ _XimUnfabricateSerial(im, ev->serial);
return NOTFILTERD;
}
@@ -203,9 +203,9 @@ _XimProtoKeyreleaseFilter(
{
Xim im = (Xim)ic->core.im;
- if (IS_FABRICATED(im)) {
+ if (_XimIsFabricatedSerial(im, ev->serial)) {
_XimPendingFilter(ic);
- UNMARK_FABRICATED(im);
+ _XimUnfabricateSerial(im, ev->serial);
return NOTFILTERD;
}
diff --git a/modules/im/ximcp/imDefIm.c b/modules/im/ximcp/imDefIm.c
index fe4d18ba..ac7f1195 100644
--- a/modules/im/ximcp/imDefIm.c
+++ b/modules/im/ximcp/imDefIm.c
@@ -430,6 +430,7 @@ _XimPreConnect(
return False;
im->private.proto.im_window = im_window;
+ im->private.proto.fabricated_serial = 0;
return True;
}
diff --git a/modules/im/ximcp/imDefLkup.c b/modules/im/ximcp/imDefLkup.c
index dd1adf53..5192e8c1 100644
--- a/modules/im/ximcp/imDefLkup.c
+++ b/modules/im/ximcp/imDefLkup.c
@@ -341,6 +341,54 @@ _XimForwardEvent(
return _XimForwardEventCore(ic, ev, sync);
}
+Bool
+_XimFabricateSerial(
+ Xim im,
+ unsigned long serial)
+{
+ if (!serial)
+ return False;
+ if (serial == im->private.proto.fabricated_serial) {
+ fprintf(stderr, "%s,%d: The key event is already fabricated.\n", __FILE__, __LINE__);
+ return False;
+ }
+ if (im->private.proto.fabricated_serial)
+ fprintf(stderr, "%s,%d: Tried to fabricate a wrong key event.\n", __FILE__, __LINE__);
+
+ MARK_FABRICATED(im);
+ im->private.proto.fabricated_serial = serial;
+ return True;
+}
+
+Bool
+_XimUnfabricateSerial(
+ Xim im,
+ unsigned long serial)
+{
+ if (!serial)
+ return False;
+ if (!im->private.proto.fabricated_serial) {
+ fprintf(stderr, "%s,%d: The key event is already unfabricated.\n", __FILE__, __LINE__);
+ return False;
+ }
+ if (serial != im->private.proto.fabricated_serial)
+ fprintf(stderr, "%s,%d: Tried to unfabricate a wrong key event.\n", __FILE__, __LINE__);
+
+ im->private.proto.fabricated_serial = 0;
+ UNMARK_FABRICATED(im);
+ return True;
+}
+
+Bool
+_XimIsFabricatedSerial(
+ Xim im,
+ unsigned long serial)
+{
+ if (!serial)
+ return False;
+ return (serial == im->private.proto.fabricated_serial);
+}
+
static void
_XimProcEvent(
Display *d,
@@ -355,7 +403,7 @@ _XimProcEvent(
ev->xany.serial |= serial << 16;
ev->xany.send_event = False;
ev->xany.display = d;
- MARK_FABRICATED(ic->core.im);
+ _XimFabricateSerial((Xim)ic->core.im, ev->xany.serial);
return;
}
@@ -704,10 +752,6 @@ _XimCommitRecv(
(void)_XimRespSyncReply(ic, flag);
- if (ic->private.proto.registed_filter_event
- & (KEYPRESS_MASK | KEYRELEASE_MASK))
- MARK_FABRICATED(im);
-
bzero(&ev, sizeof(ev)); /* uninitialized : found when running kterm under valgrind */
ev.type = KeyPress;
@@ -719,6 +763,10 @@ _XimCommitRecv(
ev.time = 0L;
ev.serial = LastKnownRequestProcessed(im->core.display);
+
+ if (ic->private.proto.registed_filter_event
+ & (KEYPRESS_MASK | KEYRELEASE_MASK))
+ _XimFabricateSerial(im, ev.serial);
/* FIXME :
I wish there were COMMENTs (!) about the data passed around.
*/