diff options
author | donal.k.fellows@manchester.ac.uk <dkf> | 2010-01-02 11:07:55 (GMT) |
---|---|---|
committer | donal.k.fellows@manchester.ac.uk <dkf> | 2010-01-02 11:07:55 (GMT) |
commit | e01c3ab9fb93de2ebed0d3b8d146295491c76c63 (patch) | |
tree | 74ec102e33450a1e4e9ce197bebd5e9082d2738f /generic | |
parent | 95a043659c4ea250050b4a72f30054e152b6b716 (diff) | |
download | tk-e01c3ab9fb93de2ebed0d3b8d146295491c76c63.zip tk-e01c3ab9fb93de2ebed0d3b8d146295491c76c63.tar.gz tk-e01c3ab9fb93de2ebed0d3b8d146295491c76c63.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 | 18 |
2 files changed, 76 insertions, 16 deletions
diff --git a/generic/tkEvent.c b/generic/tkEvent.c index 36f1c3a..fd5c129 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.40 2010/01/01 22:50:27 dkf Exp $ + * RCS: @(#) $Id: tkEvent.c,v 1.41 2010/01/02 11:07:56 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); @@ -1229,7 +1230,7 @@ Tk_HandleEvent( */ if (InvokeGenericHandlers(tsdPtr, eventPtr)) { - goto releaseUserData; + goto releaseEventResources; } if (RefreshKeyboardMappingIfNeeded(eventPtr)) { @@ -1237,14 +1238,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; } /* @@ -1258,7 +1259,7 @@ Tk_HandleEvent( if ((winPtr->flags & TK_ALREADY_DEAD) && (eventPtr->type != DestroyNotify)) { - goto releaseUserData; + goto releaseEventResources; } if (winPtr->mainPtr != NULL) { @@ -1382,18 +1383,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); } /* @@ -1755,17 +1749,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 a9062ec..73297d8 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.116 2010/01/01 22:50:27 dkf Exp $ + * RCS: $Id: tkInt.h,v 1.117 2010/01/02 11:07:56 dkf Exp $ */ #ifndef _TKINT @@ -824,6 +824,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; + +/* * Flags passed to TkpMakeMenuWindow's 'transient' argument. */ |