diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2010-01-02 10:43:25 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2010-01-02 10:43:25 (GMT) |
commit | a8f810f189c1948ce32cf32178f71013a85762c2 (patch) | |
tree | 53a45c4d70540a15b2d1bb2508e567ad721e65b6 /generic | |
parent | 1e85ca777ce26da8f7247f965272c9b9f670049c (diff) | |
download | tk-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.c | 74 | ||||
-rw-r--r-- | generic/tkInt.h | 23 |
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); |