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. */ diff --git a/src/xlibi18n/XimintP.h b/src/xlibi18n/XimintP.h index 674da029..2a51e2ed 100644 --- a/src/xlibi18n/XimintP.h +++ b/src/xlibi18n/XimintP.h @@ -149,6 +149,8 @@ typedef struct _XimProtoPrivateRec { XimTransRegDispatcher register_dispatcher; XimTransCallDispatcher call_dispatcher; XPointer spec; + + unsigned long fabricated_serial; } XimProtoPrivateRec; /* @@ -307,4 +309,19 @@ typedef struct _XicProtoPrivateRec { #define XIM_MAXIMNAMELEN 64 #define XIM_MAXLCNAMELEN 64 +Bool +_XimFabricateSerial( + Xim im, + unsigned long serial); + +Bool +_XimUnfabricateSerial( + Xim im, + unsigned long serial); + +Bool +_XimIsFabricatedSerial( + Xim im, + unsigned long serial); + #endif /* _XIMINTP_H */