From c8ab85ecfd0e2802bb98ab00e67b9acaa01a5577 Mon Sep 17 00:00:00 2001 From: nijtmans Date: Mon, 17 May 2010 08:43:58 +0000 Subject: [Patch #2999920]: Optimize Internal Virtual event string operations [Bug #2987995]: Tk_getOpenFile returns garbage under described circumstances --- ChangeLog | 7 +++++++ generic/tkBind.c | 21 +++++++-------------- win/tkWinDialog.c | 26 +++++++++++++++++++++++--- 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3685d96..0882f38 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-05-17 Jan Nijtmans + + * generic/tkBind.c [Patch #2999920]: Optimize Internal Virtual event + string operations + * win/tkWinDialog.c [Bug #2987995]: Tk_getOpenFile returns garbage under + described circumstances + 2010-05-11 Jan Nijtmans * doc/RestrictEv.3 Consistent use of variable names in RestrictEvent diff --git a/generic/tkBind.c b/generic/tkBind.c index 27e9a3b..fff2196 100644 --- a/generic/tkBind.c +++ b/generic/tkBind.c @@ -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: tkBind.c,v 1.63 2010/05/10 20:58:18 nijtmans Exp $ + * RCS: @(#) $Id: tkBind.c,v 1.64 2010/05/17 08:44:00 nijtmans Exp $ */ #include "tkInt.h" @@ -3199,9 +3199,7 @@ GetAllVirtualEvents( hPtr = Tcl_FirstHashEntry(&vetPtr->nameTable, &search); for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { Tcl_DStringSetLength(&ds, 0); - Tcl_DStringAppend(&ds, "<<", 2); Tcl_DStringAppend(&ds, Tcl_GetHashKey(hPtr->tablePtr, hPtr), -1); - Tcl_DStringAppend(&ds, ">>", 2); Tcl_AppendElement(interp, Tcl_DStringValue(&ds)); } @@ -3919,7 +3917,6 @@ GetVirtualEventUid( Tcl_Interp *interp, char *virtString) { - Tk_Uid uid; size_t length; length = strlen(virtString); @@ -3930,11 +3927,8 @@ GetVirtualEventUid( "\" is badly formed", NULL); return NULL; } - virtString[length - 2] = '\0'; - uid = Tk_GetUid(virtString + 2); - virtString[length - 2] = '>'; - return uid; + return Tk_GetUid(virtString); } /* @@ -4140,7 +4134,7 @@ ParseEventDescription( * event string. */ unsigned long *eventMaskPtr)/* Filled with event mask of matched event. */ { - char *p; + char *p, c; unsigned long eventMask; int count, eventFlags; #define FIELD_SIZE 48 @@ -4227,11 +4221,12 @@ ParseEventDescription( count = 0; goto done; } - *p = '\0'; + c = p[2]; + p[2] = '\0'; patPtr->eventType = VirtualEvent; eventMask = VirtualEventMask; - patPtr->detail.name = Tk_GetUid(field); - *p = '>'; + patPtr->detail.name = Tk_GetUid(field - 2); + p[2] = c; p += 2; goto end; @@ -4446,9 +4441,7 @@ GetPatternString( */ if (patPtr->eventType == VirtualEvent) { - Tcl_DStringAppend(dsPtr, "<<", 2); Tcl_DStringAppend(dsPtr, patPtr->detail.name, -1); - Tcl_DStringAppend(dsPtr, ">>", 2); continue; } diff --git a/win/tkWinDialog.c b/win/tkWinDialog.c index 041aea8..8ac95bf 100644 --- a/win/tkWinDialog.c +++ b/win/tkWinDialog.c @@ -8,7 +8,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkWinDialog.c,v 1.73 2010/04/20 19:57:46 nijtmans Exp $ + * RCS: @(#) $Id: tkWinDialog.c,v 1.74 2010/05/17 08:44:00 nijtmans Exp $ * */ @@ -996,7 +996,17 @@ OFNHookProcW( } else if (uMsg == WM_NOTIFY) { OFNOTIFYW *notifyPtr = (OFNOTIFYW *) lParam; - if (notifyPtr->hdr.code == CDN_FILEOK) { + /* + * This is weird... or not. The CDN_FILEOK is NOT sent when the selection + * exceeds declared buffer size (the nMaxFile member of the OPENFILENAMEW + * struct passed to GetOpenFileNameW function). So, we have to rely on + * the most recent CDN_SELCHANGE then. Unfortunately this means, that + * gathering the selected filenames happens twice when they fit into the + * declared buffer. Luckily, it's not frequent operation so it should + * not incur any noticeable delay. See [tktoolkit-Bugs-2987995] + */ + if (notifyPtr->hdr.code == CDN_FILEOK || + notifyPtr->hdr.code == CDN_SELCHANGE) { int dirsize, selsize; WCHAR *buffer; int buffersize; @@ -1531,7 +1541,17 @@ OFNHookProcA( } else if (uMsg == WM_NOTIFY) { OFNOTIFY *notifyPtr = (OFNOTIFY *) lParam; - if (notifyPtr->hdr.code == CDN_FILEOK) { + /* + * This is weird... or not. The CDN_FILEOK is NOT sent when the selection + * exceeds declared buffer size (the nMaxFile member of the OPENFILENAMEW + * struct passed to GetOpenFileNameW function). So, we have to rely on + * the most recent CDN_SELCHANGE then. Unfortunately this means, that + * gathering the selected filenames happens twice when they fit into the + * declared buffer. Luckily, it's not frequent operation so it should + * not incur any noticeable delay. See [tktoolkit-Bugs-2987995] + */ + if (notifyPtr->hdr.code == CDN_FILEOK || + notifyPtr->hdr.code == CDN_SELCHANGE) { int dirsize, selsize; char *buffer; int buffersize; -- cgit v0.12