summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2010-01-02 10:43:25 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2010-01-02 10:43:25 (GMT)
commita8f810f189c1948ce32cf32178f71013a85762c2 (patch)
tree53a45c4d70540a15b2d1bb2508e567ad721e65b6 /generic
parent1e85ca777ce26da8f7247f965272c9b9f670049c (diff)
downloadtk-a8f810f189c1948ce32cf32178f71013a85762c2.zip
tk-a8f810f189c1948ce32cf32178f71013a85762c2.tar.gz
tk-a8f810f189c1948ce32cf32178f71013a85762c2.tar.bz2
Fix [Bug 1373712] and [Bug 1924761].
Diffstat (limited to 'generic')
-rw-r--r--generic/tkEvent.c74
-rw-r--r--generic/tkInt.h23
2 files changed, 78 insertions, 19 deletions
diff --git a/generic/tkEvent.c b/generic/tkEvent.c
index d298f46..cd129a0 100644
--- a/generic/tkEvent.c
+++ b/generic/tkEvent.c
@@ -12,7 +12,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkEvent.c,v 1.35.2.3 2010/01/01 23:03:42 dkf Exp $
+ * RCS: @(#) $Id: tkEvent.c,v 1.35.2.4 2010/01/02 10:43:26 dkf Exp $
*/
#include "tkInt.h"
@@ -193,6 +193,7 @@ TCL_DECLARE_MUTEX(exitMutex)
* Prototypes for functions that are only referenced locally within this file.
*/
+static void CleanUpTkEvent(XEvent *eventPtr);
static void DelayedMotionProc(ClientData clientData);
static int GetButtonMask(unsigned int Button);
static unsigned long GetEventMaskFromXEvent(XEvent *eventPtr);
@@ -1235,7 +1236,7 @@ Tk_HandleEvent(
*/
if (InvokeGenericHandlers(tsdPtr, eventPtr)) {
- goto releaseUserData;
+ goto releaseEventResources;
}
if (RefreshKeyboardMappingIfNeeded(eventPtr)) {
@@ -1243,14 +1244,14 @@ Tk_HandleEvent(
* We are done with a MappingNotify event.
*/
- goto releaseUserData;
+ goto releaseEventResources;
}
mask = GetEventMaskFromXEvent(eventPtr);
winPtr = GetTkWindowFromXEvent(eventPtr);
if (winPtr == NULL) {
- goto releaseUserData;
+ goto releaseEventResources;
}
/*
@@ -1264,7 +1265,7 @@ Tk_HandleEvent(
if ((winPtr->flags & TK_ALREADY_DEAD)
&& (eventPtr->type != DestroyNotify)) {
- goto releaseUserData;
+ goto releaseEventResources;
}
if (winPtr->mainPtr != NULL) {
@@ -1388,18 +1389,11 @@ Tk_HandleEvent(
* Release the user_data from the event (if it is a virtual event and the
* field was non-NULL in the first place.) Note that this is done using a
* Tcl_Obj interface, and we set the field back to NULL afterwards out of
- * paranoia.
+ * paranoia. Also clean up any cached %A substitutions from key events.
*/
- releaseUserData:
- if (eventPtr->type == VirtualEvent) {
- XVirtualEvent *vePtr = (XVirtualEvent *) eventPtr;
-
- if (vePtr->user_data != NULL) {
- Tcl_DecrRefCount(vePtr->user_data);
- vePtr->user_data = NULL;
- }
- }
+ releaseEventResources:
+ CleanUpTkEvent(eventPtr);
}
/*
@@ -1761,17 +1755,67 @@ WindowEventProc(
* even though we didn't do anything at all.
*/
+ CleanUpTkEvent(&wevPtr->event);
return 1;
}
}
}
Tk_HandleEvent(&wevPtr->event);
+ CleanUpTkEvent(&wevPtr->event);
return 1;
}
/*
*----------------------------------------------------------------------
*
+ * CleanUpTkEvent --
+ *
+ * This function is called to remove and deallocate any information in
+ * the event which is not directly in the event structure itself. It may
+ * be called multiple times per event, so it takes care to set the
+ * cleared pointer fields to NULL afterwards.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Makes the event no longer have any external resources.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+CleanUpTkEvent(
+ XEvent *eventPtr)
+{
+ switch (eventPtr->type) {
+ case KeyPress:
+ case KeyRelease: {
+ TkKeyEvent *kePtr = (TkKeyEvent *) eventPtr;
+
+ if (kePtr->charValuePtr != NULL) {
+ ckfree(kePtr->charValuePtr);
+ kePtr->charValuePtr = NULL;
+ kePtr->charValueLen = 0;
+ }
+ break;
+ }
+
+ case VirtualEvent: {
+ XVirtualEvent *vePtr = (XVirtualEvent *) eventPtr;
+
+ if (vePtr->user_data != NULL) {
+ Tcl_DecrRefCount(vePtr->user_data);
+ vePtr->user_data = NULL;
+ }
+ break;
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* DelayedMotionProc --
*
* This function is invoked as an idle handler when a mouse motion event
diff --git a/generic/tkInt.h b/generic/tkInt.h
index 9cec9ab..cb6c7d9 100644
--- a/generic/tkInt.h
+++ b/generic/tkInt.h
@@ -11,7 +11,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: $Id: tkInt.h,v 1.82.2.5 2010/01/01 23:03:42 dkf Exp $
+ * RCS: $Id: tkInt.h,v 1.82.2.6 2010/01/02 10:43:26 dkf Exp $
*/
#ifndef _TKINT
@@ -853,6 +853,22 @@ typedef struct TkWindow {
} TkWindow;
/*
+ * Real definition of some events. Note that these events come from outside
+ * but have internally generated pieces added to them.
+ */
+
+typedef struct {
+ XKeyEvent keyEvent; /* The real event from X11. */
+ char *charValuePtr; /* A pointer to a string that holds the key's
+ * %A substitution text (before backslash
+ * adding), or NULL if that has not been
+ * computed yet. If non-NULL, this string was
+ * allocated with ckalloc(). */
+ int charValueLen; /* Length of string in charValuePtr when that
+ * is non-NULL. */
+} TkKeyEvent;
+
+/*
* The following structure is used as a two way map between integers and
* strings, usually to map between an internal C representation and the
* strings used in Tcl.
@@ -1113,9 +1129,8 @@ MODULE_SCOPE int Tk_WmObjCmd(ClientData clientData, Tcl_Interp *interp,
int objc, Tcl_Obj *const objv[]);
MODULE_SCOPE int Tk_GetDoublePixelsFromObj(Tcl_Interp *interp,
- Tk_Window tkwin,
- Tcl_Obj *objPtr,
- double *doublePtr);
+ Tk_Window tkwin, Tcl_Obj *objPtr,
+ double *doublePtr);
MODULE_SCOPE void TkEventInit(void);
MODULE_SCOPE void TkRegisterObjTypes(void);