diff options
author | fvogel <fvogelnew1@free.fr> | 2017-03-06 18:24:38 (GMT) |
---|---|---|
committer | fvogel <fvogelnew1@free.fr> | 2017-03-06 18:24:38 (GMT) |
commit | e98430e7e070536bd9d5ccb44afa4976b735ff65 (patch) | |
tree | 15779675471fdc625c17330f72e4c676f065d928 /generic | |
parent | ee16a52044d53a25664ecc7f02b042e3fb638baf (diff) | |
parent | 05fb5c3c424e8c68a0cf14a68d2f32570b2d5d69 (diff) | |
download | tk-e98430e7e070536bd9d5ccb44afa4976b735ff65.zip tk-e98430e7e070536bd9d5ccb44afa4976b735ff65.tar.gz tk-e98430e7e070536bd9d5ccb44afa4976b735ff65.tar.bz2 |
merge trunk
Diffstat (limited to 'generic')
43 files changed, 718 insertions, 1147 deletions
diff --git a/generic/tk.decls b/generic/tk.decls index 9ceb3af..eaaa063 100644 --- a/generic/tk.decls +++ b/generic/tk.decls @@ -326,7 +326,7 @@ declare 75 { declare 76 { void Tk_FreeTextLayout(Tk_TextLayout textLayout) } -declare 77 { +declare 77 deprecated { void Tk_FreeXId(Display *display, XID xid) } declare 78 { diff --git a/generic/tk.h b/generic/tk.h index 9403f31..1cb10e2 100644 --- a/generic/tk.h +++ b/generic/tk.h @@ -105,6 +105,10 @@ extern "C" { #ifdef BUILD_tk #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLEXPORT +#else +# ifndef TCL_STORAGE_CLASS +# define TCL_STORAGE_CLASS DLLIMPORT +# endif #endif /* @@ -414,7 +418,9 @@ typedef enum { #define TK_CONFIG_COLOR_ONLY (1 << 1) #define TK_CONFIG_MONO_ONLY (1 << 2) #define TK_CONFIG_DONT_SET_DEFAULT (1 << 3) -#define TK_CONFIG_OPTION_SPECIFIED (1 << 4) +#if !defined(TK_NO_DEPRECATED) || defined(BUILD_tk) +# define TK_CONFIG_OPTION_SPECIFIED (1 << 4) +#endif #define TK_CONFIG_USER_BIT 0x100 #endif /* __NO_OLD_CONFIG */ @@ -746,9 +752,10 @@ typedef XActivateDeactivateEvent XDeactivateEvent; (((Tk_FakeWin *) (tkwin))->flags & TK_WM_MANAGEABLE) #define Tk_ReqWidth(tkwin) (((Tk_FakeWin *) (tkwin))->reqWidth) #define Tk_ReqHeight(tkwin) (((Tk_FakeWin *) (tkwin))->reqHeight) -/* Tk_InternalBorderWidth is deprecated */ +#ifndef TK_NO_DEPRECATED #define Tk_InternalBorderWidth(tkwin) \ (((Tk_FakeWin *) (tkwin))->internalBorderLeft) +#endif /* !TK_NO_DEPRECATED */ #define Tk_InternalBorderLeft(tkwin) \ (((Tk_FakeWin *) (tkwin))->internalBorderLeft) #define Tk_InternalBorderRight(tkwin) \ @@ -814,6 +821,9 @@ typedef struct Tk_FakeWin { int minReqWidth; int minReqHeight; char *dummy20; /* geometryMaster */ +#ifdef TK_USE_INPUT_METHODS + int dummy21; +#endif /* TK_USE_INPUT_METHODS */ } Tk_FakeWin; /* diff --git a/generic/tkBind.c b/generic/tkBind.c index acc4e43..8a6fc56 100644 --- a/generic/tkBind.c +++ b/generic/tkBind.c @@ -1260,6 +1260,16 @@ Tk_BindEvent( } } + /* + * Ignore event types which are not in flagArray and all zeroes there. + * Most notably, NoExpose events can fill the ring buffer and disturb + * (thus masking out) event sequences of interest. + */ + + if ((eventPtr->type >= TK_LASTEVENT) || !flagArray[eventPtr->type]) { + return; + } + dispPtr = ((TkWindow *) tkwin)->dispPtr; bindInfoPtr = winPtr->mainPtr->bindInfo; @@ -3460,7 +3470,7 @@ HandleEventGenerate( Tcl_DoWhenIdle(DoWarp, dispPtr); dispPtr->flags |= TK_DISPLAY_IN_WARP; } - dispPtr->warpWindow = Tk_IdToWindow(Tk_Display(mainWin), + dispPtr->warpWindow = Tk_IdToWindow(dispPtr->display, event.general.xmotion.window); dispPtr->warpMainwin = mainWin; dispPtr->warpX = event.general.xmotion.x; diff --git a/generic/tkCanvUtil.c b/generic/tkCanvUtil.c index cbbc2b4..09ce98c 100644 --- a/generic/tkCanvUtil.c +++ b/generic/tkCanvUtil.c @@ -1136,7 +1136,9 @@ Tk_ConfigOutlineGC( if (mask && (dash->number != 0)) { gcValues->line_style = LineOnOffDash; gcValues->dash_offset = outline->offset; - if (dash->number > 0) { + if ((unsigned int)ABS(dash->number) > sizeof(char *)) { + gcValues->dashes = dash->pattern.pt[0]; + } else if (dash->number != 0) { gcValues->dashes = dash->pattern.array[0]; } else { gcValues->dashes = (char) (4 * width + 0.5); @@ -1340,7 +1342,9 @@ Tk_ResetOutlineGC( if ((dash->number > 2) || (dash->number < -1) || (dash->number==2 && (dash->pattern.array[0] != dash->pattern.array[1])) || ((dash->number == -1) && (dash->pattern.array[0] != ','))) { - if (dash->number > 0) { + if ((unsigned int)ABS(dash->number) > sizeof(char *)) { + dashList = dash->pattern.pt[0]; + } else if (dash->number != 0) { dashList = dash->pattern.array[0]; } else { dashList = (char) (4 * width + 0.5); diff --git a/generic/tkCmds.c b/generic/tkCmds.c index 6196b17..93c1fb0 100644 --- a/generic/tkCmds.c +++ b/generic/tkCmds.c @@ -2068,14 +2068,13 @@ TkGetDisplayOf( * present. */ { const char *string; - int length; if (objc < 1) { return 0; } - string = Tcl_GetStringFromObj(objv[0], &length); - if ((length >= 2) && - (strncmp(string, "-displayof", (unsigned) length) == 0)) { + string = Tcl_GetString(objv[0]); + if ((objv[0]->length >= 2) && + (strncmp(string, "-displayof", objv[0]->length) == 0)) { if (objc < 2) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "value for \"-displayof\" missing", -1)); diff --git a/generic/tkConfig.c b/generic/tkConfig.c index 9c159e6..093bd35 100644 --- a/generic/tkConfig.c +++ b/generic/tkConfig.c @@ -91,7 +91,7 @@ typedef struct TkOption { */ typedef struct OptionTable { - int refCount; /* Counts the number of uses of this table + size_t refCount; /* Counts the number of uses of this table * (the number of times Tk_CreateOptionTable * has returned it). This can be greater than * 1 if it is shared along several option @@ -103,7 +103,7 @@ typedef struct OptionTable { * templates, this points to the table * corresponding to the next template in the * chain. */ - int numOptions; /* The number of items in the options array + size_t numOptions; /* The number of items in the options array * below. */ Option options[1]; /* Information about the individual options in * the table. This must be the last field in @@ -177,7 +177,7 @@ Tk_CreateOptionTable( OptionTable *tablePtr; const Tk_OptionSpec *specPtr, *specPtr2; Option *optionPtr; - int numOptions, i; + size_t numOptions, i; ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); @@ -330,10 +330,9 @@ Tk_DeleteOptionTable( { OptionTable *tablePtr = (OptionTable *) optionTable; Option *optionPtr; - int count; + size_t count; - tablePtr->refCount--; - if (tablePtr->refCount > 0) { + if (tablePtr->refCount-- > 1) { return; } @@ -978,7 +977,7 @@ GetOption( Option *bestPtr, *optionPtr; OptionTable *tablePtr2; const char *p1, *p2; - int count; + size_t count; /* * Search through all of the option tables in the chain to find the best @@ -1539,7 +1538,7 @@ Tk_FreeConfigOptions( { OptionTable *tablePtr; Option *optionPtr; - int count; + size_t count; Tcl_Obj **oldPtrPtr, *oldPtr; char *oldInternalPtr; const Tk_OptionSpec *specPtr; @@ -1733,7 +1732,7 @@ Tk_GetOptionInfo( Tcl_Obj *resultPtr; OptionTable *tablePtr = (OptionTable *) optionTable; Option *optionPtr; - int count; + size_t count; /* * If information is only wanted for a single configuration spec, then @@ -2096,9 +2095,9 @@ TkDebugConfig( if (tablePtr == (OptionTable *) Tcl_GetHashValue(hashEntryPtr)) { for ( ; tablePtr != NULL; tablePtr = tablePtr->nextPtr) { Tcl_ListObjAppendElement(NULL, objPtr, - Tcl_NewIntObj(tablePtr->refCount)); + Tcl_NewWideIntObj(tablePtr->refCount)); Tcl_ListObjAppendElement(NULL, objPtr, - Tcl_NewIntObj(tablePtr->numOptions)); + Tcl_NewWideIntObj(tablePtr->numOptions)); Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj( tablePtr->options[0].specPtr->optionName, -1)); } diff --git a/generic/tkConsole.c b/generic/tkConsole.c index 8bfbe9b..57e8364 100644 --- a/generic/tkConsole.c +++ b/generic/tkConsole.c @@ -24,7 +24,7 @@ typedef struct ConsoleInfo { Tcl_Interp *consoleInterp; /* Interpreter displaying the console. */ Tcl_Interp *interp; /* Interpreter controlled by console. */ - int refCount; + size_t refCount; } ConsoleInfo; /* @@ -223,7 +223,7 @@ Tk_InitConsoleChannels( * Ensure that we are getting a compatible version of Tcl. */ - if (Tcl_InitStubs(interp, "8.6", 0) == NULL) { + if (Tcl_InitStubs(interp, "8.6-", 0) == NULL) { return; } @@ -452,7 +452,7 @@ Tk_CreateConsoleWindow( if (mainWindow) { Tk_DeleteEventHandler(mainWindow, StructureNotifyMask, ConsoleEventProc, info); - if (--info->refCount <= 0) { + if (info->refCount-- <= 1) { ckfree(info); } } @@ -592,7 +592,7 @@ ConsoleClose( ConsoleInfo *info = data->info; if (info) { - if (--info->refCount <= 0) { + if (info->refCount-- <= 1) { /* * Assuming the Tcl_Interp * fields must already be NULL. */ @@ -881,7 +881,7 @@ InterpDeleteProc( Tcl_DeleteThreadExitHandler(DeleteConsoleInterp, info->consoleInterp); info->consoleInterp = NULL; } - if (--info->refCount <= 0) { + if (info->refCount-- <= 1) { ckfree(info); } } @@ -912,7 +912,7 @@ ConsoleDeleteProc( if (info->consoleInterp) { Tcl_DeleteInterp(info->consoleInterp); } - if (--info->refCount <= 0) { + if (info->refCount-- <= 1) { ckfree(info); } } @@ -949,7 +949,7 @@ ConsoleEventProc( Tcl_EvalEx(consoleInterp, "tk::ConsoleExit", -1, TCL_EVAL_GLOBAL); } - if (--info->refCount <= 0) { + if (info->refCount-- <= 1) { ckfree(info); } } diff --git a/generic/tkDecls.h b/generic/tkDecls.h index eaaaf6c..3b72706 100644 --- a/generic/tkDecls.h +++ b/generic/tkDecls.h @@ -17,6 +17,12 @@ #define TCL_STORAGE_CLASS DLLEXPORT #endif +#if defined(TK_NO_DEPRECATED) && defined(BUILD_tk) +# define TK_DEPRECATED MODULE_SCOPE +#else +# define TK_DEPRECATED EXTERN +#endif + /* * WARNING: This file is automatically generated by the tools/genStubs.tcl * script. Any modifications to the function declarations below should be made @@ -281,7 +287,7 @@ EXTERN void Tk_FreePixmap(Display *display, Pixmap pixmap); /* 76 */ EXTERN void Tk_FreeTextLayout(Tk_TextLayout textLayout); /* 77 */ -EXTERN void Tk_FreeXId(Display *display, XID xid); +TK_DEPRECATED void Tk_FreeXId(Display *display, XID xid); /* 78 */ EXTERN GC Tk_GCForColor(XColor *colorPtr, Drawable drawable); /* 79 */ diff --git a/generic/tkEntry.c b/generic/tkEntry.c index 5681e47..acfdd31 100644 --- a/generic/tkEntry.c +++ b/generic/tkEntry.c @@ -1926,8 +1926,8 @@ EntryComputeGeometry( */ if (entryPtr->showChar != NULL) { - Tcl_UniChar ch; - char buf[TCL_UTF_MAX]; + int ch; + char buf[6]; int size; /* @@ -1937,15 +1937,16 @@ EntryComputeGeometry( * resulting string. */ - Tcl_UtfToUniChar(entryPtr->showChar, &ch); - size = Tcl_UniCharToUtf(ch, buf); + TkUtfToUniChar(entryPtr->showChar, &ch); + size = TkUniCharToUtf(ch, buf); entryPtr->numDisplayBytes = entryPtr->numChars * size; p = ckalloc(entryPtr->numDisplayBytes + 1); entryPtr->displayString = p; for (i = entryPtr->numChars; --i >= 0; ) { - p += Tcl_UniCharToUtf(ch, p); + memcpy(p, buf, size); + p += size; } *p = '\0'; } @@ -3413,7 +3414,7 @@ ExpandPercents( * list element. */ int number, length; register const char *string; - Tcl_UniChar ch; + int ch; char numStorage[2*TCL_INTEGER_SPACE]; while (1) { @@ -3446,7 +3447,7 @@ ExpandPercents( before++; /* skip over % */ if (*before != '\0') { - before += Tcl_UtfToUniChar(before, &ch); + before += TkUtfToUniChar(before, &ch); } else { ch = '%'; } @@ -3466,7 +3467,7 @@ ExpandPercents( string = Tk_PathName(entryPtr->tkwin); break; default: - length = Tcl_UniCharToUtf(ch, numStorage); + length = TkUniCharToUtf(ch, numStorage); numStorage[length] = '\0'; string = numStorage; break; @@ -3526,7 +3527,7 @@ ExpandPercents( string = Tk_PathName(entryPtr->tkwin); break; default: - length = Tcl_UniCharToUtf(ch, numStorage); + length = TkUniCharToUtf(ch, numStorage); numStorage[length] = '\0'; string = numStorage; break; diff --git a/generic/tkEvent.c b/generic/tkEvent.c index 95aeda1..d058e7c 100644 --- a/generic/tkEvent.c +++ b/generic/tkEvent.c @@ -356,6 +356,7 @@ CreateXIC( /* XCreateIC failed. */ return; } + winPtr->ximGeneration = dispPtr->ximGeneration; /* * Adjust the window's event mask if the IM requires it. @@ -1288,6 +1289,14 @@ Tk_HandleEvent( */ #ifdef TK_USE_INPUT_METHODS + /* + * If the XIC has been invalidated, it must be recreated. + */ + if (winPtr->dispPtr->ximGeneration != winPtr->ximGeneration) { + winPtr->flags &= ~TK_CHECKED_IC; + winPtr->inputContext = NULL; + } + if ((winPtr->dispPtr->flags & TK_DISPLAY_USE_IM)) { if (!(winPtr->flags & (TK_CHECKED_IC|TK_ALREADY_DEAD))) { winPtr->flags |= TK_CHECKED_IC; @@ -1295,7 +1304,9 @@ Tk_HandleEvent( CreateXIC(winPtr); } } - if (eventPtr->type == FocusIn && winPtr->inputContext != NULL) { + if ((eventPtr->type == FocusIn) && + (winPtr->dispPtr->inputMethod != NULL) && + (winPtr->inputContext != NULL)) { XSetICFocus(winPtr->inputContext); } } diff --git a/generic/tkFont.c b/generic/tkFont.c index 1ffac16..a00c627 100644 --- a/generic/tkFont.c +++ b/generic/tkFont.c @@ -41,7 +41,7 @@ typedef struct TkFontInfo { */ typedef struct NamedFont { - int refCount; /* Number of users of named font. */ + size_t refCount; /* Number of users of named font. */ int deletePending; /* Non-zero if font should be deleted when * last reference goes away. */ TkFontAttributes fa; /* Desired attributes for named font. */ @@ -562,17 +562,19 @@ Tk_FontObjCmd( */ if (charPtr != NULL) { - if (Tcl_GetCharLength(charPtr) != 1) { + const char *string = Tcl_GetString(charPtr); + int len = TkUtfToUniChar(string, &uniChar); + + if (len != charPtr->length) { resultPtr = Tcl_NewStringObj( "expected a single character but got \"", -1); - Tcl_AppendLimitedToObj(resultPtr, Tcl_GetString(charPtr), + Tcl_AppendLimitedToObj(resultPtr, string, -1, 40, "..."); Tcl_AppendToObj(resultPtr, "\"", -1); Tcl_SetObjResult(interp, resultPtr); Tcl_SetErrorCode(interp, "TK", "VALUE", "FONT_SAMPLE", NULL); return TCL_ERROR; } - uniChar = Tcl_GetUniChar(charPtr, 0); } /* @@ -1432,8 +1434,7 @@ Tk_FreeFont( */ nfPtr = Tcl_GetHashValue(fontPtr->namedHashPtr); - nfPtr->refCount--; - if ((nfPtr->refCount == 0) && nfPtr->deletePending) { + if ((nfPtr->refCount-- <= 1) && nfPtr->deletePending) { Tcl_DeleteHashEntry(fontPtr->namedHashPtr); ckfree(nfPtr); } @@ -1694,7 +1695,7 @@ Tk_PostscriptFontName( } else if (strcasecmp(family, "ZapfDingbats") == 0) { family = "ZapfDingbats"; } else { - Tcl_UniChar ch; + int ch; /* * Inline, capitalize the first letter of each word, lowercase the @@ -1712,14 +1713,14 @@ Tk_PostscriptFontName( src++; upper = 1; } - src += Tcl_UtfToUniChar(src, &ch); + src += TkUtfToUniChar(src, &ch); if (upper) { - ch = (Tcl_UniChar) Tcl_UniCharToUpper(ch); + ch = Tcl_UniCharToUpper(ch); upper = 0; } else { - ch = (Tcl_UniChar) Tcl_UniCharToLower(ch); + ch = Tcl_UniCharToLower(ch); } - dest += Tcl_UniCharToUtf(ch, dest); + dest += TkUniCharToUtf(ch, dest); } *dest = '\0'; Tcl_DStringSetLength(dsPtr, dest - Tcl_DStringValue(dsPtr)); @@ -3249,7 +3250,7 @@ Tk_TextLayoutToPostscript( int i, j, len; const char *p, *glyphname; char uindex[5], c, *ps; - Tcl_UniChar ch; + int ch; Tcl_AppendToObj(psObj, "[(", -1); for (i = 0; i < layoutPtr->numChunks; i++, chunkPtr++) { @@ -3272,7 +3273,7 @@ Tk_TextLayoutToPostscript( * international postscript fonts. */ - p += Tcl_UtfToUniChar(p, &ch); + p += TkUtfToUniChar(p, &ch); if ((ch == '(') || (ch == ')') || (ch == '\\') || (ch < 0x20)) { /* * Tricky point: the "03" is necessary in the sprintf below, @@ -3298,6 +3299,9 @@ Tk_TextLayoutToPostscript( * use the full glyph name. */ + if (ch > 0xffff) { + goto noMapping; + } sprintf(uindex, "%04X", ch); /* endianness? */ glyphname = Tcl_GetVar2(interp, "::tk::psglyphs", uindex, 0); if (glyphname) { @@ -3318,6 +3322,7 @@ Tk_TextLayoutToPostscript( * No known mapping for the character into the space of * PostScript glyphs. Ignore it. :-( */ +noMapping: ; #ifdef TK_DEBUG_POSTSCRIPT_OUTPUT fprintf(stderr, "Warning: no mapping to PostScript " diff --git a/generic/tkGC.c b/generic/tkGC.c index c424e30..55e5774 100644 --- a/generic/tkGC.c +++ b/generic/tkGC.c @@ -23,7 +23,7 @@ typedef struct { GC gc; /* Graphics context. */ Display *display; /* Display to which gc belongs. */ - int refCount; /* Number of active uses of gc. */ + size_t refCount; /* Number of active uses of gc. */ Tcl_HashEntry *valueHashPtr;/* Entry in valueTable (needed when deleting * this structure). */ } TkGC; @@ -312,8 +312,7 @@ Tk_FreeGC( Tcl_Panic("Tk_FreeGC received unknown gc argument"); } gcPtr = Tcl_GetHashValue(idHashPtr); - gcPtr->refCount--; - if (gcPtr->refCount == 0) { + if (gcPtr->refCount-- <= 1) { XFreeGC(gcPtr->display, gcPtr->gc); Tcl_DeleteHashEntry(gcPtr->valueHashPtr); Tcl_DeleteHashEntry(idHashPtr); diff --git a/generic/tkGrid.c b/generic/tkGrid.c index 2a88b76..62c9c59 100644 --- a/generic/tkGrid.c +++ b/generic/tkGrid.c @@ -3314,6 +3314,9 @@ ConfigureSlaves( } if (slavePtr->masterPtr != NULL && slavePtr->masterPtr != masterPtr) { + if (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin)) { + Tk_UnmaintainGeometry(slavePtr->tkwin, slavePtr->masterPtr->tkwin); + } Unlink(slavePtr); slavePtr->masterPtr = NULL; } diff --git a/generic/tkImgBmap.c b/generic/tkImgBmap.c index 0906673..1a9a86e 100644 --- a/generic/tkImgBmap.c +++ b/generic/tkImgBmap.c @@ -49,7 +49,7 @@ typedef struct BitmapMaster { */ typedef struct BitmapInstance { - int refCount; /* Number of instances that share this data + size_t refCount; /* Number of instances that share this data * structure. */ BitmapMaster *masterPtr; /* Pointer to master for image. */ Tk_Window tkwin; /* Window in which the instances will be @@ -951,8 +951,7 @@ ImgBmapFree( BitmapInstance *instancePtr = clientData; BitmapInstance *prevPtr; - instancePtr->refCount--; - if (instancePtr->refCount > 0) { + if (instancePtr->refCount-- > 1) { return; } diff --git a/generic/tkImgPNG.c b/generic/tkImgPNG.c index c6e3029..6e64afa 100644 --- a/generic/tkImgPNG.c +++ b/generic/tkImgPNG.c @@ -2245,10 +2245,10 @@ ApplyAlpha( p += offset; if (16 == pngPtr->bitDepth) { - register int channel; + register unsigned int channel; while (p < endPtr) { - channel = (unsigned char) + channel = (unsigned int) (((p[0] << 8) | p[1]) * pngPtr->alpha); *p++ = (unsigned char) (channel >> 8); diff --git a/generic/tkImgPhInstance.c b/generic/tkImgPhInstance.c index bd152f2..98aaeab 100644 --- a/generic/tkImgPhInstance.c +++ b/generic/tkImgPhInstance.c @@ -721,8 +721,7 @@ TkImgPhotoFree( PhotoInstance *instancePtr = clientData; ColorTable *colorPtr; - instancePtr->refCount -= 1; - if (instancePtr->refCount > 0) { + if (instancePtr->refCount-- > 1) { return; } diff --git a/generic/tkImgPhoto.c b/generic/tkImgPhoto.c index 3e03f3d..1bd0142 100644 --- a/generic/tkImgPhoto.c +++ b/generic/tkImgPhoto.c @@ -409,7 +409,8 @@ ImgPhotoCmd( Tk_PhotoImageBlock block; Tk_Window tkwin; Tk_PhotoImageFormat *imageFormat; - int imageWidth, imageHeight, matched, length, oldformat = 0; + size_t length; + int imageWidth, imageHeight, matched, oldformat = 0; Tcl_Channel chan; Tk_PhotoHandle srcHandle; ThreadSpecificData *tsdPtr = @@ -446,12 +447,13 @@ ImgPhotoCmd( Tcl_WrongNumArgs(interp, 2, objv, "option"); return TCL_ERROR; } - arg = Tcl_GetStringFromObj(objv[2], &length); - if (strncmp(arg,"-data", (unsigned) length) == 0) { + arg = Tcl_GetString(objv[2]); + length = objv[2]->length; + if (strncmp(arg,"-data", length) == 0) { if (masterPtr->dataString) { Tcl_SetObjResult(interp, masterPtr->dataString); } - } else if (strncmp(arg,"-format", (unsigned) length) == 0) { + } else if (strncmp(arg,"-format", length) == 0) { if (masterPtr->format) { Tcl_SetObjResult(interp, masterPtr->format); } @@ -495,9 +497,10 @@ ImgPhotoCmd( return TCL_OK; } else if (objc == 3) { - const char *arg = Tcl_GetStringFromObj(objv[2], &length); + const char *arg = Tcl_GetString(objv[2]); - if (length > 1 && !strncmp(arg, "-data", (unsigned) length)) { + length = objv[2]->length; + if (length > 1 && !strncmp(arg, "-data", length)) { Tcl_AppendResult(interp, "-data {} {} {}", NULL); if (masterPtr->dataString) { /* @@ -511,7 +514,7 @@ ImgPhotoCmd( } return TCL_OK; } else if (length > 1 && - !strncmp(arg, "-format", (unsigned) length)) { + !strncmp(arg, "-format", length)) { Tcl_AppendResult(interp, "-format {} {} {}", NULL); if (masterPtr->format) { /* @@ -1489,7 +1492,8 @@ ParseSubcommandOptions( * TK_PHOTO_COMPOSITE_* constants. */ NULL }; - int index, c, bit, currentBit, length; + size_t length; + int index, c, bit, currentBit; int values[4], numValues, maxValues, argIndex; const char *option, *expandedOption, *needed; const char *const *listPtr; @@ -1501,7 +1505,8 @@ ParseSubcommandOptions( * optPtr->name. */ - expandedOption = option = Tcl_GetStringFromObj(objv[index], &length); + expandedOption = option = Tcl_GetString(objv[index]); + length = objv[index]->length; if (option[0] != '-') { if (optPtr->name == NULL) { optPtr->name = objv[index]; @@ -1519,7 +1524,7 @@ ParseSubcommandOptions( currentBit = 1; for (listPtr = optionNames; *listPtr != NULL; ++listPtr) { if ((c == *listPtr[0]) - && (strncmp(option, *listPtr, (size_t) length) == 0)) { + && (strncmp(option, *listPtr, length) == 0)) { expandedOption = *listPtr; if (bit != 0) { goto unknownOrAmbiguousOption; @@ -1535,7 +1540,11 @@ ParseSubcommandOptions( */ if (!(allowedOptions & bit)) { - goto unknownOrAmbiguousOption; + if (optPtr->name != NULL) { + goto unknownOrAmbiguousOption; + } + optPtr->name = objv[index]; + continue; } /* @@ -1765,7 +1774,8 @@ ImgPhotoConfigureMaster( const char *oldFileString, *oldPaletteString; Tcl_Obj *oldData, *data = NULL, *oldFormat, *format = NULL; Tcl_Obj *tempdata, *tempformat; - int length, i, j, result, imageWidth, imageHeight, oldformat; + size_t length; + int i, j, result, imageWidth, imageHeight, oldformat; double oldGamma; Tcl_Channel chan; Tk_PhotoImageFormat *imageFormat; @@ -1773,10 +1783,11 @@ ImgPhotoConfigureMaster( args = ckalloc((objc + 1) * sizeof(char *)); for (i = 0, j = 0; i < objc; i++,j++) { - args[j] = Tcl_GetStringFromObj(objv[i], &length); + args[j] = Tcl_GetString(objv[i]); + length = objv[i]->length; if ((length > 1) && (args[j][0] == '-')) { if ((args[j][1] == 'd') && - !strncmp(args[j], "-data", (size_t) length)) { + !strncmp(args[j], "-data", length)) { if (++i < objc) { data = objv[i]; j--; @@ -1789,7 +1800,7 @@ ImgPhotoConfigureMaster( return TCL_ERROR; } } else if ((args[j][1] == 'f') && - !strncmp(args[j], "-format", (size_t) length)) { + !strncmp(args[j], "-format", length)) { if (++i < objc) { format = objv[i]; j--; @@ -1852,9 +1863,10 @@ ImgPhotoConfigureMaster( * Force into ByteArray format, which most (all) image handlers will * use anyway. Empty length means ignore the -data option. */ + int bytesize; - (void) Tcl_GetByteArrayFromObj(data, &length); - if (length) { + (void) Tcl_GetByteArrayFromObj(data, &bytesize); + if (bytesize) { Tcl_IncrRefCount(data); } else { data = NULL; @@ -1870,8 +1882,8 @@ ImgPhotoConfigureMaster( * object. */ - (void) Tcl_GetStringFromObj(format, &length); - if (length) { + (void) Tcl_GetString(format); + if (format->length) { Tcl_IncrRefCount(format); } else { format = NULL; diff --git a/generic/tkImgPhoto.h b/generic/tkImgPhoto.h index 36bc6cb..45fac88 100644 --- a/generic/tkImgPhoto.h +++ b/generic/tkImgPhoto.h @@ -201,7 +201,7 @@ struct PhotoInstance { * this particular colormap. */ PhotoInstance *nextPtr; /* Pointer to the next instance in the list of * instances associated with this master. */ - int refCount; /* Number of instances using this structure. */ + size_t refCount; /* Number of instances using this structure. */ Tk_Uid palette; /* Palette for these particular instances. */ double gamma; /* Gamma value for these instances. */ Tk_Uid defaultPalette; /* Default palette to use if a palette is not diff --git a/generic/tkInt.decls b/generic/tkInt.decls index 586b407..a13d8d7 100644 --- a/generic/tkInt.decls +++ b/generic/tkInt.decls @@ -1422,28 +1422,76 @@ declare 106 win { # New in Tk 8.6 declare 107 win { - int XFlush(Display *display) + int XFlush(Display *display) } declare 108 win { - int XGrabServer(Display *display) + int XGrabServer(Display *display) } declare 109 win { - int XUngrabServer(Display *display) + int XUngrabServer(Display *display) } declare 110 win { - int XFree(void *data) + int XFree(void *data) } declare 111 win { - int XNoOp(Display *display) + int XNoOp(Display *display) } declare 112 win { - XAfterFunction XSynchronize(Display *display, Bool onoff) + XAfterFunction XSynchronize(Display *display, Bool onoff) } declare 113 win { - int XSync(Display *display, Bool discard) + int XSync(Display *display, Bool discard) } declare 114 win { - VisualID XVisualIDFromVisual(Visual *visual) + VisualID XVisualIDFromVisual(Visual *visual) +} + +# For tktreectrl +declare 120 win { + int XOffsetRegion(Region rgn, int dx, int dy) +} +declare 121 win { + int XUnionRegion(Region srca, Region srcb, Region dr_return) +} + +# For 3dcanvas +declare 122 win { + Window XCreateWindow(Display *display, Window parent, int x, int y, + unsigned int width, unsigned int height, + unsigned int border_width, int depth, unsigned int clazz, + Visual *visual, unsigned long value_mask, + XSetWindowAttributes *attributes) +} + +# Various, e.g. for stub-enabled BLT +declare 129 win { + int XLowerWindow(Display *d, Window w) +} +declare 130 win { + int XFillArcs(Display *d, Drawable dr, GC gc, XArc *a, int n) +} +declare 131 win { + int XDrawArcs(Display *d, Drawable dr, GC gc, XArc *a, int n) +} +declare 132 win { + int XDrawRectangles(Display *d, Drawable dr, GC gc, XRectangle *r, int n) +} +declare 133 win { + int XDrawSegments(Display *d, Drawable dr, GC gc, XSegment *s, int n) +} +declare 134 win { + int XDrawPoint(Display *d, Drawable dr, GC gc, int x, int y) +} +declare 135 win { + int XDrawPoints(Display *d, Drawable dr, GC gc, XPoint *p, int n, int m) +} +declare 136 win { + int XReparentWindow(Display *d, Window w, Window p, int x, int y) +} +declare 137 win { + int XPutImage(Display *d, Drawable dr, GC gc, XImage *im, + int sx, int sy, int dx, int dy, + unsigned int w, unsigned int h) } ################################ @@ -1725,7 +1773,7 @@ declare 79 aqua { XTextProperty *text_prop_return) } declare 80 aqua { - void XDrawSegments(Display *display, Drawable d, GC gc, + int XDrawSegments(Display *display, Drawable d, GC gc, XSegment *segments, int nsegments) } declare 81 aqua { @@ -1743,10 +1791,10 @@ declare 84 aqua { void XClearWindow(Display *d, Window w) } declare 85 aqua { - void XDrawPoint(Display *display, Drawable d, GC gc, int x, int y) + int XDrawPoint(Display *display, Drawable d, GC gc, int x, int y) } declare 86 aqua { - void XDrawPoints(Display *display, Drawable d, GC gc, XPoint *points, + int XDrawPoints(Display *display, Drawable d, GC gc, XPoint *points, int npoints, int mode) } declare 87 aqua { diff --git a/generic/tkInt.h b/generic/tkInt.h index 0b502e4..3138ffc 100644 --- a/generic/tkInt.h +++ b/generic/tkInt.h @@ -478,7 +478,7 @@ typedef struct TkDisplay { #endif /* TK_USE_INPUT_METHODS */ Tcl_HashTable winTable; /* Maps from X window ids to TkWindow ptrs. */ - int refCount; /* Reference count of how many Tk applications + size_t refCount; /* Reference count of how many Tk applications * are using this display. Used to clean up * the display when we no longer have any Tk * applications using it. */ @@ -508,6 +508,9 @@ typedef struct TkDisplay { int iconDataSize; /* Size of default iconphoto image data. */ unsigned char *iconDataPtr; /* Default iconphoto image data, if set. */ +#ifdef TK_USE_INPUT_METHODS + int ximGeneration; /* Used to invalidate XIC */ +#endif /* TK_USE_INPUT_METHODS */ } TkDisplay; /* @@ -579,7 +582,7 @@ typedef struct TkEventHandler { */ typedef struct TkMainInfo { - int refCount; /* Number of windows whose "mainPtr" fields + size_t refCount; /* Number of windows whose "mainPtr" fields * point here. When this becomes zero, can * free up the structure (the reference count * is zero because windows can get deleted in @@ -809,6 +812,9 @@ typedef struct TkWindow { int minReqWidth; /* Minimum requested width. */ int minReqHeight; /* Minimum requested height. */ char *geometryMaster; +#ifdef TK_USE_INPUT_METHODS + int ximGeneration; /* Used to invalidate XIC */ +#endif /* TK_USE_INPUT_METHODS */ } TkWindow; /* @@ -1232,6 +1238,14 @@ MODULE_SCOPE Status TkParseColor (Display * display, MODULE_SCOPE void TkUnixSetXftClipRegion(TkRegion clipRegion); #endif +#if TCL_UTF_MAX > 4 +# define TkUtfToUniChar Tcl_UtfToUniChar +# define TkUniCharToUtf Tcl_UniCharToUtf +#else + MODULE_SCOPE int TkUtfToUniChar(const char *, int *); + MODULE_SCOPE int TkUniCharToUtf(int, char *); +#endif + /* * Unsupported commands. */ diff --git a/generic/tkIntXlibDecls.h b/generic/tkIntXlibDecls.h index 6ac7ccb..67b7c39 100644 --- a/generic/tkIntXlibDecls.h +++ b/generic/tkIntXlibDecls.h @@ -23,11 +23,25 @@ # include <tcl.h> #endif +#ifndef EXTERN +# define EXTERN extern TCL_STORAGE_CLASS +#endif + +/* Some (older) versions of X11/Xutil.h have a wrong signature of those + two functions, so move them out of the way temporarly. */ +#define XOffsetRegion _XOffsetRegion +#define XUnionRegion _XUnionRegion #include "X11/Xutil.h" +#undef XOffsetRegion +#undef XUnionRegion #ifdef BUILD_tk -#undef TCL_STORAGE_CLASS -#define TCL_STORAGE_CLASS DLLEXPORT +# undef TCL_STORAGE_CLASS +# define TCL_STORAGE_CLASS DLLEXPORT +#else +# ifndef TCL_STORAGE_CLASS +# define TCL_STORAGE_CLASS DLLIMPORT +# endif #endif typedef int (*XAfterFunction) ( /* WARNING, this type not in Xlib spec */ @@ -356,6 +370,57 @@ EXTERN XAfterFunction XSynchronize(Display *display, Bool onoff); EXTERN int XSync(Display *display, Bool discard); /* 114 */ EXTERN VisualID XVisualIDFromVisual(Visual *visual); +/* Slot 115 is reserved */ +/* Slot 116 is reserved */ +/* Slot 117 is reserved */ +/* Slot 118 is reserved */ +/* Slot 119 is reserved */ +/* 120 */ +EXTERN int XOffsetRegion(Region rgn, int dx, int dy); +/* 121 */ +EXTERN int XUnionRegion(Region srca, Region srcb, + Region dr_return); +/* 122 */ +EXTERN Window XCreateWindow(Display *display, Window parent, int x, + int y, unsigned int width, + unsigned int height, + unsigned int border_width, int depth, + unsigned int clazz, Visual *visual, + unsigned long value_mask, + XSetWindowAttributes *attributes); +/* Slot 123 is reserved */ +/* Slot 124 is reserved */ +/* Slot 125 is reserved */ +/* Slot 126 is reserved */ +/* Slot 127 is reserved */ +/* Slot 128 is reserved */ +/* 129 */ +EXTERN int XLowerWindow(Display *d, Window w); +/* 130 */ +EXTERN int XFillArcs(Display *d, Drawable dr, GC gc, XArc *a, + int n); +/* 131 */ +EXTERN int XDrawArcs(Display *d, Drawable dr, GC gc, XArc *a, + int n); +/* 132 */ +EXTERN int XDrawRectangles(Display *d, Drawable dr, GC gc, + XRectangle *r, int n); +/* 133 */ +EXTERN int XDrawSegments(Display *d, Drawable dr, GC gc, + XSegment *s, int n); +/* 134 */ +EXTERN int XDrawPoint(Display *d, Drawable dr, GC gc, int x, + int y); +/* 135 */ +EXTERN int XDrawPoints(Display *d, Drawable dr, GC gc, + XPoint *p, int n, int m); +/* 136 */ +EXTERN int XReparentWindow(Display *d, Window w, Window p, + int x, int y); +/* 137 */ +EXTERN int XPutImage(Display *d, Drawable dr, GC gc, XImage *im, + int sx, int sy, int dx, int dy, + unsigned int w, unsigned int h); #endif /* WIN */ #ifdef MAC_OSX_TK /* AQUA */ /* 0 */ @@ -584,7 +649,7 @@ EXTERN void XSetWMClientMachine(Display *display, Window w, EXTERN Status XStringListToTextProperty(char **list, int count, XTextProperty *text_prop_return); /* 80 */ -EXTERN void XDrawSegments(Display *display, Drawable d, GC gc, +EXTERN int XDrawSegments(Display *display, Drawable d, GC gc, XSegment *segments, int nsegments); /* 81 */ EXTERN void XForceScreenSaver(Display *display, int mode); @@ -598,10 +663,10 @@ EXTERN int XFillRectangle(Display *display, Drawable d, GC gc, /* 84 */ EXTERN void XClearWindow(Display *d, Window w); /* 85 */ -EXTERN void XDrawPoint(Display *display, Drawable d, GC gc, +EXTERN int XDrawPoint(Display *display, Drawable d, GC gc, int x, int y); /* 86 */ -EXTERN void XDrawPoints(Display *display, Drawable d, GC gc, +EXTERN int XDrawPoints(Display *display, Drawable d, GC gc, XPoint *points, int npoints, int mode); /* 87 */ EXTERN int XWarpPointer(Display *display, Window src_w, @@ -742,6 +807,29 @@ typedef struct TkIntXlibStubs { XAfterFunction (*xSynchronize) (Display *display, Bool onoff); /* 112 */ int (*xSync) (Display *display, Bool discard); /* 113 */ VisualID (*xVisualIDFromVisual) (Visual *visual); /* 114 */ + void (*reserved115)(void); + void (*reserved116)(void); + void (*reserved117)(void); + void (*reserved118)(void); + void (*reserved119)(void); + int (*xOffsetRegion) (Region rgn, int dx, int dy); /* 120 */ + int (*xUnionRegion) (Region srca, Region srcb, Region dr_return); /* 121 */ + Window (*xCreateWindow) (Display *display, Window parent, int x, int y, unsigned int width, unsigned int height, unsigned int border_width, int depth, unsigned int clazz, Visual *visual, unsigned long value_mask, XSetWindowAttributes *attributes); /* 122 */ + void (*reserved123)(void); + void (*reserved124)(void); + void (*reserved125)(void); + void (*reserved126)(void); + void (*reserved127)(void); + void (*reserved128)(void); + int (*xLowerWindow) (Display *d, Window w); /* 129 */ + int (*xFillArcs) (Display *d, Drawable dr, GC gc, XArc *a, int n); /* 130 */ + int (*xDrawArcs) (Display *d, Drawable dr, GC gc, XArc *a, int n); /* 131 */ + int (*xDrawRectangles) (Display *d, Drawable dr, GC gc, XRectangle *r, int n); /* 132 */ + int (*xDrawSegments) (Display *d, Drawable dr, GC gc, XSegment *s, int n); /* 133 */ + int (*xDrawPoint) (Display *d, Drawable dr, GC gc, int x, int y); /* 134 */ + int (*xDrawPoints) (Display *d, Drawable dr, GC gc, XPoint *p, int n, int m); /* 135 */ + int (*xReparentWindow) (Display *d, Window w, Window p, int x, int y); /* 136 */ + int (*xPutImage) (Display *d, Drawable dr, GC gc, XImage *im, int sx, int sy, int dx, int dy, unsigned int w, unsigned int h); /* 137 */ #endif /* WIN */ #ifdef MAC_OSX_TK /* AQUA */ int (*xSetDashes) (Display *display, GC gc, int dash_offset, _Xconst char *dash_list, int n); /* 0 */ @@ -824,13 +912,13 @@ typedef struct TkIntXlibStubs { XVisualInfo * (*xGetVisualInfo) (Display *display, long vinfo_mask, XVisualInfo *vinfo_template, int *nitems_return); /* 77 */ void (*xSetWMClientMachine) (Display *display, Window w, XTextProperty *text_prop); /* 78 */ Status (*xStringListToTextProperty) (char **list, int count, XTextProperty *text_prop_return); /* 79 */ - void (*xDrawSegments) (Display *display, Drawable d, GC gc, XSegment *segments, int nsegments); /* 80 */ + int (*xDrawSegments) (Display *display, Drawable d, GC gc, XSegment *segments, int nsegments); /* 80 */ void (*xForceScreenSaver) (Display *display, int mode); /* 81 */ int (*xDrawLine) (Display *d, Drawable dr, GC g, int x1, int y1, int x2, int y2); /* 82 */ int (*xFillRectangle) (Display *display, Drawable d, GC gc, int x, int y, unsigned int width, unsigned int height); /* 83 */ void (*xClearWindow) (Display *d, Window w); /* 84 */ - void (*xDrawPoint) (Display *display, Drawable d, GC gc, int x, int y); /* 85 */ - void (*xDrawPoints) (Display *display, Drawable d, GC gc, XPoint *points, int npoints, int mode); /* 86 */ + int (*xDrawPoint) (Display *display, Drawable d, GC gc, int x, int y); /* 85 */ + int (*xDrawPoints) (Display *display, Drawable d, GC gc, XPoint *points, int npoints, int mode); /* 86 */ int (*xWarpPointer) (Display *display, Window src_w, Window dest_w, int src_x, int src_y, unsigned int src_width, unsigned int src_height, int dest_x, int dest_y); /* 87 */ void (*xQueryColor) (Display *display, Colormap colormap, XColor *def_in_out); /* 88 */ void (*xQueryColors) (Display *display, Colormap colormap, XColor *defs_in_out, int ncolors); /* 89 */ @@ -1081,6 +1169,41 @@ extern const TkIntXlibStubs *tkIntXlibStubsPtr; (tkIntXlibStubsPtr->xSync) /* 113 */ #define XVisualIDFromVisual \ (tkIntXlibStubsPtr->xVisualIDFromVisual) /* 114 */ +/* Slot 115 is reserved */ +/* Slot 116 is reserved */ +/* Slot 117 is reserved */ +/* Slot 118 is reserved */ +/* Slot 119 is reserved */ +#define XOffsetRegion \ + (tkIntXlibStubsPtr->xOffsetRegion) /* 120 */ +#define XUnionRegion \ + (tkIntXlibStubsPtr->xUnionRegion) /* 121 */ +#define XCreateWindow \ + (tkIntXlibStubsPtr->xCreateWindow) /* 122 */ +/* Slot 123 is reserved */ +/* Slot 124 is reserved */ +/* Slot 125 is reserved */ +/* Slot 126 is reserved */ +/* Slot 127 is reserved */ +/* Slot 128 is reserved */ +#define XLowerWindow \ + (tkIntXlibStubsPtr->xLowerWindow) /* 129 */ +#define XFillArcs \ + (tkIntXlibStubsPtr->xFillArcs) /* 130 */ +#define XDrawArcs \ + (tkIntXlibStubsPtr->xDrawArcs) /* 131 */ +#define XDrawRectangles \ + (tkIntXlibStubsPtr->xDrawRectangles) /* 132 */ +#define XDrawSegments \ + (tkIntXlibStubsPtr->xDrawSegments) /* 133 */ +#define XDrawPoint \ + (tkIntXlibStubsPtr->xDrawPoint) /* 134 */ +#define XDrawPoints \ + (tkIntXlibStubsPtr->xDrawPoints) /* 135 */ +#define XReparentWindow \ + (tkIntXlibStubsPtr->xReparentWindow) /* 136 */ +#define XPutImage \ + (tkIntXlibStubsPtr->xPutImage) /* 137 */ #endif /* WIN */ #ifdef MAC_OSX_TK /* AQUA */ #define XSetDashes \ diff --git a/generic/tkMain.c b/generic/tkMain.c index 1b21223..87a3cf7 100644 --- a/generic/tkMain.c +++ b/generic/tkMain.c @@ -196,7 +196,7 @@ Tk_MainEx( * Ensure that we are getting a compatible version of Tcl. */ - if (Tcl_InitStubs(interp, "8.6", 0) == NULL) { + if (Tcl_InitStubs(interp, "8.6-", 0) == NULL) { if (Tcl_InitStubs(interp, "8.1", 0) == NULL) { abort(); } else { diff --git a/generic/tkObj.c b/generic/tkObj.c index 7c09656..90fedbc 100644 --- a/generic/tkObj.c +++ b/generic/tkObj.c @@ -153,8 +153,19 @@ GetTypeCache(void) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (tsdPtr->doubleTypePtr == NULL) { - tsdPtr->doubleTypePtr = Tcl_GetObjType("double"); - tsdPtr->intTypePtr = Tcl_GetObjType("int"); + /* Smart initialization of doubleTypePtr/intTypePtr without + * hash-table lookup or creating complete Tcl_Obj's */ + Tcl_Obj obj; + obj.length = 3; + obj.bytes = (char *)"0.0"; + obj.typePtr = NULL; + Tcl_GetDoubleFromObj(NULL, &obj, &obj.internalRep.doubleValue); + tsdPtr->doubleTypePtr = obj.typePtr; + obj.bytes += 2; + obj.length = 1; + obj.typePtr = NULL; + Tcl_GetLongFromObj(NULL, &obj, &obj.internalRep.longValue); + tsdPtr->intTypePtr = obj.typePtr; } return tsdPtr; } diff --git a/generic/tkPack.c b/generic/tkPack.c index 88a4b2d..8257b43 100644 --- a/generic/tkPack.c +++ b/generic/tkPack.c @@ -122,8 +122,10 @@ static int ConfigureSlaves(Tcl_Interp *interp, Tk_Window tkwin, int objc, Tcl_Obj *const objv[]); static void DestroyPacker(void *memPtr); static Packer * GetPacker(Tk_Window tkwin); +#ifndef TK_NO_DEPRECATED static int PackAfter(Tcl_Interp *interp, Packer *prevPtr, Packer *masterPtr, int objc,Tcl_Obj *const objv[]); +#endif /* !TK_NO_DEPRECATED */ static void PackStructureProc(ClientData clientData, XEvent *eventPtr); static void Unlink(Packer *packPtr); @@ -197,11 +199,14 @@ Tk_PackObjCmd( Tk_Window tkwin = clientData; const char *argv2; static const char *const optionStrings[] = { - /* after, append, before and unpack are deprecated */ +#ifndef TK_NO_DEPRECATED "after", "append", "before", "unpack", +#endif /* !TK_NO_DEPRECATED */ "configure", "forget", "info", "propagate", "slaves", NULL }; enum options { +#ifndef TK_NO_DEPRECATED PACK_AFTER, PACK_APPEND, PACK_BEFORE, PACK_UNPACK, +#endif /* !TK_NO_DEPRECATED */ PACK_CONFIGURE, PACK_FORGET, PACK_INFO, PACK_PROPAGATE, PACK_SLAVES }; int index; @@ -219,6 +224,7 @@ Tk_PackObjCmd( if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings, sizeof(char *), "option", 0, &index) != TCL_OK) { +#ifndef TK_NO_DEPRECATED /* * Call it again without the deprecated ones to get a proper error * message. This works well since there can't be any ambiguity between @@ -228,11 +234,13 @@ Tk_PackObjCmd( Tcl_ResetResult(interp); Tcl_GetIndexFromObjStruct(interp, objv[1], &optionStrings[4], sizeof(char *), "option", 0, &index); +#endif /* TK_NO_DEPRECATED */ return TCL_ERROR; } argv2 = Tcl_GetString(objv[2]); switch ((enum options) index) { +#ifndef TK_NO_DEPRECATED case PACK_AFTER: { Packer *prevPtr; Tk_Window tkwin2; @@ -297,6 +305,7 @@ Tk_PackObjCmd( } return PackAfter(interp, prevPtr, masterPtr, objc-3, objv+3); } +#endif /* !TK_NO_DEPRECATED */ case PACK_CONFIGURE: if (argv2[0] != '.') { Tcl_SetObjResult(interp, Tcl_ObjPrintf( @@ -458,6 +467,7 @@ Tk_PackObjCmd( Tcl_SetObjResult(interp, resultObj); break; } +#ifndef TK_NO_DEPRECATED case PACK_UNPACK: { Tk_Window tkwin2; Packer *packPtr; @@ -481,6 +491,7 @@ Tk_PackObjCmd( } break; } +#endif /* !TK_NO_DEPRECATED */ } return TCL_OK; @@ -1087,6 +1098,7 @@ GetPacker( *------------------------------------------------------------------------ */ +#ifndef TK_NO_DEPRECATED static int PackAfter( Tcl_Interp *interp, /* Interpreter for error reporting. */ @@ -1307,6 +1319,7 @@ PackAfter( } return TCL_OK; } +#endif /* !TK_NO_DEPRECATED */ /* *---------------------------------------------------------------------- diff --git a/generic/tkPanedWindow.c b/generic/tkPanedWindow.c index f350d0a..4bfc695 100644 --- a/generic/tkPanedWindow.c +++ b/generic/tkPanedWindow.c @@ -1484,10 +1484,10 @@ DisplayPanedWindow( */ if (horizontal) { - sashHeight = Tk_Height(tkwin) - (2 * Tk_InternalBorderWidth(tkwin)); + sashHeight = Tk_Height(tkwin) - (2 * Tk_InternalBorderLeft(tkwin)); sashWidth = pwPtr->sashWidth; } else { - sashWidth = Tk_Width(tkwin) - (2 * Tk_InternalBorderWidth(tkwin)); + sashWidth = Tk_Width(tkwin) - (2 * Tk_InternalBorderLeft(tkwin)); sashHeight = pwPtr->sashWidth; } @@ -1754,7 +1754,7 @@ ArrangePanes( */ paneDynSize = paneDynMinSize = 0; - internalBW = Tk_InternalBorderWidth(pwPtr->tkwin); + internalBW = Tk_InternalBorderLeft(pwPtr->tkwin); pwHeight = Tk_Height(pwPtr->tkwin) - (2 * internalBW); pwWidth = Tk_Width(pwPtr->tkwin) - (2 * internalBW); x = y = internalBW; @@ -2184,7 +2184,7 @@ ComputeGeometry( pwPtr->flags |= REQUESTED_RELAYOUT; - x = y = internalBw = Tk_InternalBorderWidth(pwPtr->tkwin); + x = y = internalBw = Tk_InternalBorderLeft(pwPtr->tkwin); reqWidth = reqHeight = 0; /* @@ -2890,7 +2890,7 @@ PanedWindowProxyCommand( return TCL_ERROR; } - internalBW = Tk_InternalBorderWidth(pwPtr->tkwin); + internalBW = Tk_InternalBorderLeft(pwPtr->tkwin); if (pwPtr->orient == ORIENT_HORIZONTAL) { if (x < 0) { x = 0; @@ -2899,10 +2899,10 @@ PanedWindowProxyCommand( if (x > pwWidth) { x = pwWidth; } - y = Tk_InternalBorderWidth(pwPtr->tkwin); + y = Tk_InternalBorderLeft(pwPtr->tkwin); sashWidth = pwPtr->sashWidth; sashHeight = Tk_Height(pwPtr->tkwin) - - (2 * Tk_InternalBorderWidth(pwPtr->tkwin)); + (2 * Tk_InternalBorderLeft(pwPtr->tkwin)); } else { if (y < 0) { y = 0; @@ -2911,10 +2911,10 @@ PanedWindowProxyCommand( if (y > pwHeight) { y = pwHeight; } - x = Tk_InternalBorderWidth(pwPtr->tkwin); + x = Tk_InternalBorderLeft(pwPtr->tkwin); sashHeight = pwPtr->sashWidth; sashWidth = Tk_Width(pwPtr->tkwin) - - (2 * Tk_InternalBorderWidth(pwPtr->tkwin)); + (2 * Tk_InternalBorderLeft(pwPtr->tkwin)); } if (sashWidth < 1) { @@ -3053,7 +3053,7 @@ PanedWindowIdentifyCoords( } else { sashHeight = Tk_ReqHeight(pwPtr->tkwin); } - sashHeight -= 2 * Tk_InternalBorderWidth(pwPtr->tkwin); + sashHeight -= 2 * Tk_InternalBorderLeft(pwPtr->tkwin); if (pwPtr->showHandle && pwPtr->handleSize > pwPtr->sashWidth) { sashWidth = pwPtr->handleSize; lpad = (pwPtr->handleSize - pwPtr->sashWidth) / 2; @@ -3081,7 +3081,7 @@ PanedWindowIdentifyCoords( } else { sashWidth = Tk_ReqWidth(pwPtr->tkwin); } - sashWidth -= 2 * Tk_InternalBorderWidth(pwPtr->tkwin); + sashWidth -= 2 * Tk_InternalBorderLeft(pwPtr->tkwin); lpad = rpad = 0; } diff --git a/generic/tkScrollbar.c b/generic/tkScrollbar.c index 5017d30..9c1ceb8 100644 --- a/generic/tkScrollbar.c +++ b/generic/tkScrollbar.c @@ -179,10 +179,12 @@ Tk_ScrollbarObjCmd( scrollPtr->sliderLast = 0; scrollPtr->activeField = 0; scrollPtr->activeRelief = TK_RELIEF_RAISED; +#ifndef TK_NO_DEPRECATED scrollPtr->totalUnits = 0; scrollPtr->windowUnits = 0; scrollPtr->firstUnit = 0; scrollPtr->lastUnit = 0; +#endif /* TK_NO_DEPRECATED */ scrollPtr->firstFraction = 0.0; scrollPtr->lastFraction = 0.0; scrollPtr->cursor = None; @@ -377,10 +379,13 @@ ScrollbarWidgetObjCmd( Tcl_WrongNumArgs(interp, 1, objv, "get"); goto error; } +#ifndef TK_NO_DEPRECATED if (scrollPtr->flags & NEW_STYLE_COMMANDS) { +#endif /* TK_NO_DEPRECATED */ resObjs[0] = Tcl_NewDoubleObj(scrollPtr->firstFraction); resObjs[1] = Tcl_NewDoubleObj(scrollPtr->lastFraction); Tcl_SetObjResult(interp, Tcl_NewListObj(2, resObjs)); +#ifndef TK_NO_DEPRECATED } else { resObjs[0] = Tcl_NewIntObj(scrollPtr->totalUnits); resObjs[1] = Tcl_NewIntObj(scrollPtr->windowUnits); @@ -388,6 +393,7 @@ ScrollbarWidgetObjCmd( resObjs[3] = Tcl_NewIntObj(scrollPtr->lastUnit); Tcl_SetObjResult(interp, Tcl_NewListObj(4, resObjs)); } +#endif /* TK_NO_DEPRECATED */ break; } case COMMAND_IDENTIFY: { @@ -413,8 +419,6 @@ ScrollbarWidgetObjCmd( break; } case COMMAND_SET: { - int totalUnits, windowUnits, firstUnit, lastUnit; - if (objc == 4) { double first, last; @@ -438,8 +442,10 @@ ScrollbarWidgetObjCmd( } else { scrollPtr->lastFraction = last; } +#ifndef TK_NO_DEPRECATED scrollPtr->flags |= NEW_STYLE_COMMANDS; } else if (objc == 6) { + int totalUnits, windowUnits, firstUnit, lastUnit; if (Tcl_GetIntFromObj(interp, objv[2], &totalUnits) != TCL_OK) { goto error; } @@ -477,10 +483,9 @@ ScrollbarWidgetObjCmd( scrollPtr->lastFraction = ((double) (lastUnit+1))/totalUnits; } scrollPtr->flags &= ~NEW_STYLE_COMMANDS; +#endif /* !TK_NO_DEPRECATED */ } else { Tcl_WrongNumArgs(interp, 1, objv, "set firstFraction lastFraction"); - Tcl_AppendResult(interp, " or \"", Tcl_GetString(objv[0]), - " set totalUnits windowUnits firstUnit lastUnit\"", NULL); goto error; } TkpComputeScrollbarGeometry(scrollPtr); diff --git a/generic/tkScrollbar.h b/generic/tkScrollbar.h index b0cd085..66b12b8 100644 --- a/generic/tkScrollbar.h +++ b/generic/tkScrollbar.h @@ -96,6 +96,7 @@ typedef struct TkScrollbar { * the NEW_STYLE_COMMANDS flag is 0. */ +#ifndef TK_NO_DEPRECATED int totalUnits; /* Total dimension of application, in units. * Valid only if the NEW_STYLE_COMMANDS flag * isn't set. */ @@ -108,6 +109,9 @@ typedef struct TkScrollbar { int lastUnit; /* Index of last unit visible in window. * Valid only if the NEW_STYLE_COMMANDS flag * isn't set. */ +#else + int dummy1,dummy2,dummy3,dummy4; /* sizeof(TkScrollbar) should not depend on TK_NO_DEPRECATED */ +#endif /* TK_NO_DEPRECATED */ double firstFraction; /* Position of first visible thing in window, * specified as a fraction between 0 and * 1.0. */ @@ -153,7 +157,9 @@ typedef struct TkScrollbar { */ #define REDRAW_PENDING 1 +#ifndef TK_NO_DEPRECATED #define NEW_STYLE_COMMANDS 2 +#endif /* TK_NO_DEPRECATED */ #define GOT_FOCUS 4 /* diff --git a/generic/tkSelect.c b/generic/tkSelect.c index ab9018a..74b3964 100644 --- a/generic/tkSelect.c +++ b/generic/tkSelect.c @@ -26,7 +26,7 @@ typedef struct { int charOffset; /* The offset of the next char to retrieve. */ int byteOffset; /* The expected byte offset of the next * chunk. */ - char buffer[TCL_UTF_MAX]; /* A buffer to hold part of a UTF character + char buffer[4]; /* A buffer to hold part of a UTF character * that is split across chunks. */ char command[1]; /* Command to invoke. Actual space is * allocated as large as necessary. This must diff --git a/generic/tkStubInit.c b/generic/tkStubInit.c index 21e6a68..7f5b3be 100644 --- a/generic/tkStubInit.c +++ b/generic/tkStubInit.c @@ -40,6 +40,10 @@ MODULE_SCOPE const TkStubs tkStubs; #undef Tk_MainEx #undef Tk_FreeXId + +#ifdef TK_NO_DEPRECATED +#define Tk_FreeXId 0 +#else static void doNothing(void) { @@ -47,6 +51,7 @@ doNothing(void) } #define Tk_FreeXId ((void (*)(Display *, XID)) doNothing) +#endif #ifdef _WIN32 @@ -71,6 +76,9 @@ TkCreateXEventSource(void) # define TkUnixContainerId 0 # define TkUnixDoOneXEvent 0 # define TkUnixSetMenubar 0 +# define XCreateWindow 0 +# define XOffsetRegion 0 +# define XUnionRegion 0 # define TkWmCleanup (void (*)(TkDisplay *)) TkpSync # define TkSendCleanup (void (*)(TkDisplay *)) TkpSync # define TkpTestsendCmd 0 @@ -707,6 +715,29 @@ static const TkIntXlibStubs tkIntXlibStubs = { XSynchronize, /* 112 */ XSync, /* 113 */ XVisualIDFromVisual, /* 114 */ + 0, /* 115 */ + 0, /* 116 */ + 0, /* 117 */ + 0, /* 118 */ + 0, /* 119 */ + XOffsetRegion, /* 120 */ + XUnionRegion, /* 121 */ + XCreateWindow, /* 122 */ + 0, /* 123 */ + 0, /* 124 */ + 0, /* 125 */ + 0, /* 126 */ + 0, /* 127 */ + 0, /* 128 */ + XLowerWindow, /* 129 */ + XFillArcs, /* 130 */ + XDrawArcs, /* 131 */ + XDrawRectangles, /* 132 */ + XDrawSegments, /* 133 */ + XDrawPoint, /* 134 */ + XDrawPoints, /* 135 */ + XReparentWindow, /* 136 */ + XPutImage, /* 137 */ #endif /* WIN */ #ifdef MAC_OSX_TK /* AQUA */ XSetDashes, /* 0 */ diff --git a/generic/tkTest.c b/generic/tkTest.c index faba89d..1f801be 100644 --- a/generic/tkTest.c +++ b/generic/tkTest.c @@ -227,7 +227,7 @@ Tktest_Init( { static int initialized = 0; - if (Tcl_InitStubs(interp, "8.6", 0) == NULL) { + if (Tcl_InitStubs(interp, "8.6-", 0) == NULL) { return TCL_ERROR; } if (Tk_InitStubs(interp, TK_VERSION, 0) == NULL) { @@ -452,7 +452,7 @@ TestcursorObjCmd( * A standard Tcl result. * * Side effects: - * All the intepreters created by previous calls to "testnewapp" get + * All the interpreters created by previous calls to "testnewapp" get * deleted. * *---------------------------------------------------------------------- diff --git a/generic/tkText.c b/generic/tkText.c index bea4c62..4f25222 100644 --- a/generic/tkText.c +++ b/generic/tkText.c @@ -547,7 +547,7 @@ CreateWidget( Tcl_InitHashTable(&sharedPtr->windowTable, TCL_STRING_KEYS); Tcl_InitHashTable(&sharedPtr->imageTable, TCL_STRING_KEYS); sharedPtr->undoStack = TkUndoInitStack(interp,0); - sharedPtr->undo = 1; + sharedPtr->undo = 0; sharedPtr->isDirty = 0; sharedPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL; sharedPtr->autoSeparators = 1; @@ -1570,8 +1570,7 @@ TextWidgetObjCmd( } done: - textPtr->refCount--; - if (textPtr->refCount == 0) { + if (textPtr->refCount-- <= 1) { ckfree(textPtr); } return result; @@ -1964,9 +1963,7 @@ DestroyText( * portion of the text widget. */ - sharedTextPtr->refCount--; - - if (sharedTextPtr->refCount > 0) { + if (sharedTextPtr->refCount-- > 1) { TkBTreeRemoveClient(sharedTextPtr->tree, textPtr); /* @@ -2042,13 +2039,12 @@ DestroyText( } textPtr->tkwin = NULL; - textPtr->refCount--; Tcl_DeleteCommandFromToken(textPtr->interp, textPtr->widgetCmd); if (textPtr->afterSyncCmd){ Tcl_DecrRefCount(textPtr->afterSyncCmd); textPtr->afterSyncCmd = NULL; } - if (textPtr->refCount == 0) { + if (textPtr->refCount-- <= 1) { ckfree(textPtr); } } @@ -2774,6 +2770,9 @@ TextPushUndoAction( { TkUndoSubAtom *iAtom, *dAtom; int canUndo, canRedo; + char lMarkName[20] = "tk::undoMarkL"; + char rMarkName[20] = "tk::undoMarkR"; + char stringUndoMarkId[7] = ""; /* * Create the helpers. @@ -2784,6 +2783,10 @@ TextPushUndoAction( Tcl_Obj *markSet2InsertObj = NULL; Tcl_Obj *insertCmdObj = Tcl_NewObj(); Tcl_Obj *deleteCmdObj = Tcl_NewObj(); + Tcl_Obj *markSetLUndoMarkCmdObj = Tcl_NewObj(); + Tcl_Obj *markSetRUndoMarkCmdObj = NULL; + Tcl_Obj *markGravityLUndoMarkCmdObj = Tcl_NewObj(); + Tcl_Obj *markGravityRUndoMarkCmdObj = NULL; /* * Get the index positions. @@ -2833,6 +2836,40 @@ TextPushUndoAction( Tcl_ListObjAppendElement(NULL, deleteCmdObj, index1Obj); Tcl_ListObjAppendElement(NULL, deleteCmdObj, index2Obj); + Tcl_ListObjAppendElement(NULL, markSetLUndoMarkCmdObj, + Tcl_NewStringObj(Tk_PathName(textPtr->tkwin), -1)); + Tcl_ListObjAppendElement(NULL, markSetLUndoMarkCmdObj, + Tcl_NewStringObj("mark", 4)); + Tcl_ListObjAppendElement(NULL, markSetLUndoMarkCmdObj, + Tcl_NewStringObj("set", 3)); + markSetRUndoMarkCmdObj = Tcl_DuplicateObj(markSetLUndoMarkCmdObj); + textPtr->sharedTextPtr->undoMarkId++; + sprintf(stringUndoMarkId, "%d", textPtr->sharedTextPtr->undoMarkId); + strcat(lMarkName, stringUndoMarkId); + strcat(rMarkName, stringUndoMarkId); + Tcl_ListObjAppendElement(NULL, markSetLUndoMarkCmdObj, + Tcl_NewStringObj(lMarkName, -1)); + Tcl_ListObjAppendElement(NULL, markSetRUndoMarkCmdObj, + Tcl_NewStringObj(rMarkName, -1)); + Tcl_ListObjAppendElement(NULL, markSetLUndoMarkCmdObj, index1Obj); + Tcl_ListObjAppendElement(NULL, markSetRUndoMarkCmdObj, index2Obj); + + Tcl_ListObjAppendElement(NULL, markGravityLUndoMarkCmdObj, + Tcl_NewStringObj(Tk_PathName(textPtr->tkwin), -1)); + Tcl_ListObjAppendElement(NULL, markGravityLUndoMarkCmdObj, + Tcl_NewStringObj("mark", 4)); + Tcl_ListObjAppendElement(NULL, markGravityLUndoMarkCmdObj, + Tcl_NewStringObj("gravity", 7)); + markGravityRUndoMarkCmdObj = Tcl_DuplicateObj(markGravityLUndoMarkCmdObj); + Tcl_ListObjAppendElement(NULL, markGravityLUndoMarkCmdObj, + Tcl_NewStringObj(lMarkName, -1)); + Tcl_ListObjAppendElement(NULL, markGravityRUndoMarkCmdObj, + Tcl_NewStringObj(rMarkName, -1)); + Tcl_ListObjAppendElement(NULL, markGravityLUndoMarkCmdObj, + Tcl_NewStringObj("left", 4)); + Tcl_ListObjAppendElement(NULL, markGravityRUndoMarkCmdObj, + Tcl_NewStringObj("right", 5)); + /* * Note: we don't wish to use textPtr->widgetCmd in these callbacks * because if we delete the textPtr, but peers still exist, we will then @@ -2850,11 +2887,19 @@ TextPushUndoAction( insertCmdObj, NULL); TkUndoMakeCmdSubAtom(NULL, markSet2InsertObj, iAtom); TkUndoMakeCmdSubAtom(NULL, seeInsertObj, iAtom); + TkUndoMakeCmdSubAtom(NULL, markSetLUndoMarkCmdObj, iAtom); + TkUndoMakeCmdSubAtom(NULL, markSetRUndoMarkCmdObj, iAtom); + TkUndoMakeCmdSubAtom(NULL, markGravityLUndoMarkCmdObj, iAtom); + TkUndoMakeCmdSubAtom(NULL, markGravityRUndoMarkCmdObj, iAtom); dAtom = TkUndoMakeSubAtom(&TextUndoRedoCallback, textPtr->sharedTextPtr, deleteCmdObj, NULL); TkUndoMakeCmdSubAtom(NULL, markSet1InsertObj, dAtom); TkUndoMakeCmdSubAtom(NULL, seeInsertObj, dAtom); + TkUndoMakeCmdSubAtom(NULL, markSetLUndoMarkCmdObj, dAtom); + TkUndoMakeCmdSubAtom(NULL, markSetRUndoMarkCmdObj, dAtom); + TkUndoMakeCmdSubAtom(NULL, markGravityLUndoMarkCmdObj, dAtom); + TkUndoMakeCmdSubAtom(NULL, markGravityRUndoMarkCmdObj, dAtom); Tcl_DecrRefCount(seeInsertObj); Tcl_DecrRefCount(index1Obj); @@ -4459,7 +4504,7 @@ TkTextGetTabs( Tcl_Obj **objv; TkTextTabArray *tabArrayPtr; TkTextTab *tabPtr; - Tcl_UniChar ch; + int ch; double prevStop, lastStop; /* * Map these strings to TkTextTabAlign values. @@ -4566,7 +4611,7 @@ TkTextGetTabs( * There may be a more efficient way of getting this. */ - Tcl_UtfToUniChar(Tcl_GetString(objv[i+1]), &ch); + TkUtfToUniChar(Tcl_GetString(objv[i+1]), &ch); if (!Tcl_UniCharIsAlpha(ch)) { continue; } @@ -5069,6 +5114,8 @@ TextEditUndo( TkText *textPtr) /* Overall information about text widget. */ { int status; + Tcl_Obj *cmdObj; + int code; if (!textPtr->sharedTextPtr->undo) { return TCL_OK; @@ -5092,6 +5139,22 @@ TextEditUndo( } textPtr->sharedTextPtr->undo = 1; + /* + * Convert undo/redo temporary marks set by TkUndoRevert() into + * indices left in the interp result. + */ + + cmdObj = Tcl_ObjPrintf("::tk::TextUndoRedoProcessMarks %s", + Tk_PathName(textPtr->tkwin)); + Tcl_IncrRefCount(cmdObj); + code = Tcl_EvalObjEx(textPtr->interp, cmdObj, TCL_EVAL_GLOBAL); + if (code != TCL_OK) { + Tcl_AddErrorInfo(textPtr->interp, + "\n (on undoing)"); + Tcl_BackgroundException(textPtr->interp, code); + } + Tcl_DecrRefCount(cmdObj); + return status; } @@ -5117,6 +5180,8 @@ TextEditRedo( TkText *textPtr) /* Overall information about text widget. */ { int status; + Tcl_Obj *cmdObj; + int code; if (!textPtr->sharedTextPtr->undo) { return TCL_OK; @@ -5139,6 +5204,23 @@ TextEditRedo( textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL; } textPtr->sharedTextPtr->undo = 1; + + /* + * Convert undo/redo temporary marks set by TkUndoApply() into + * indices left in the interp result. + */ + + cmdObj = Tcl_ObjPrintf("::tk::TextUndoRedoProcessMarks %s", + Tk_PathName(textPtr->tkwin)); + Tcl_IncrRefCount(cmdObj); + code = Tcl_EvalObjEx(textPtr->interp, cmdObj, TCL_EVAL_GLOBAL); + if (code != TCL_OK) { + Tcl_AddErrorInfo(textPtr->interp, + "\n (on undoing)"); + Tcl_BackgroundException(textPtr->interp, code); + } + Tcl_DecrRefCount(cmdObj); + return status; } @@ -5526,7 +5608,7 @@ RunAfterSyncCmd( * The widget has been deleted. Don't do anything. */ - if (--textPtr->refCount == 0) { + if (textPtr->refCount-- <= 1) { ckfree((char *) textPtr); } return; @@ -5880,7 +5962,7 @@ SearchCore( CLANG_ASSERT(pattern); do { - Tcl_UniChar ch; + int ch; const char *p; int lastFullLine = lastOffset; @@ -6110,7 +6192,7 @@ SearchCore( } } else { firstOffset = p - startOfLine + - Tcl_UtfToUniChar(startOfLine+matchOffset,&ch); + TkUtfToUniChar(startOfLine+matchOffset,&ch); } } } while (searchSpecPtr->all); diff --git a/generic/tkText.h b/generic/tkText.h index 5d88784..430c96b 100644 --- a/generic/tkText.h +++ b/generic/tkText.h @@ -580,6 +580,8 @@ typedef struct TkSharedText { * statements. */ int autoSeparators; /* Non-zero means the separators will be * inserted automatically. */ + int undoMarkId; /* Counts undo marks temporarily used during + undo and redo operations. */ int isDirty; /* Flag indicating the 'dirtyness' of the * text widget. If the flag is not zero, * unsaved modifications have been applied to diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c index 5faab36..0958986 100644 --- a/generic/tkTextDisp.c +++ b/generic/tkTextDisp.c @@ -3005,7 +3005,7 @@ AsyncUpdateLineMetrics( * The widget has been deleted, or is not mapped. Don't do anything. */ - if (--textPtr->refCount == 0) { + if (textPtr->refCount-- <= 1) { ckfree(textPtr); } return; @@ -3080,8 +3080,7 @@ AsyncUpdateLineMetrics( GenerateWidgetViewSyncEvent(textPtr, 1); - textPtr->refCount--; - if (textPtr->refCount == 0) { + if (textPtr->refCount-- <= 1) { ckfree(textPtr); } return; @@ -4163,7 +4162,7 @@ DisplayText( textPtr->refCount++; dInfoPtr->flags &= ~REPICK_NEEDED; TkTextPickCurrent(textPtr, &textPtr->pickEvent); - if (--textPtr->refCount == 0) { + if (textPtr->refCount-- <= 1) { ckfree(textPtr); goto end; } @@ -4299,8 +4298,9 @@ DisplayText( if (TkScrollWindow(textPtr->tkwin, dInfoPtr->scrollGC, dInfoPtr->x, oldY, dInfoPtr->maxX-dInfoPtr->x, height, 0, y-oldY, damageRgn)) { +#ifndef MAC_OSX_TK TextInvalidateRegion(textPtr, damageRgn); - +#endif } numCopies++; TkDestroyRegion(damageRgn); @@ -6752,7 +6752,7 @@ AsyncUpdateYScrollbar( GetYView(textPtr->interp, textPtr, 1); } - if (--textPtr->refCount == 0) { + if (textPtr->refCount-- <= 1) { ckfree(textPtr); } } @@ -7542,6 +7542,9 @@ TkTextCharLayoutProc( * (b) at least one pixel of the character is visible, we have not * already exceeded the character limit, and the next character is a * white space character. + * In the specific case of 'word' wrapping mode however, include all space + * characters following the characters that fit in the space we've got, + * even if no pixel of them is visible. */ p = segPtr->body.chars + byteOffset; @@ -7581,8 +7584,8 @@ TkTextCharLayoutProc( if (bytesThatFit < maxBytes) { if ((bytesThatFit == 0) && noCharsYet) { - Tcl_UniChar ch; - int chLen = Tcl_UtfToUniChar(p, &ch); + int ch; + int chLen = TkUtfToUniChar(p, &ch); #if TK_LAYOUT_WITH_BASE_CHUNKS bytesThatFit = CharChunkMeasureChars(chunkPtr, line, @@ -7604,6 +7607,21 @@ TkTextCharLayoutProc( nextX = maxX; bytesThatFit++; } + if (wrapMode == TEXT_WRAPMODE_WORD) { + while (p[bytesThatFit] == ' ') { + /* + * Space characters that would go at the beginning of the + * next line are allocated to the current line. This gives + * the effect of trimming white spaces that would otherwise + * be seen at the beginning of wrapped lines. + * Note that testing for '\t' is useless here because the + * chunk always includes at most one trailing \t, see + * LayoutDLine. + */ + + bytesThatFit++; + } + } if (p[bytesThatFit] == '\n') { /* * A newline character takes up no space, so if the previous @@ -7801,7 +7819,7 @@ CharChunkMeasureChars( MeasureChars(tkfont, chars, charsLen, 0, bstart, 0, -1, 0, &widthUntilStart); - xDisplacement = startX - widthUntilStart - chunkPtr->x; + xDisplacement = startX - widthUntilStart - ciPtr->baseChunkPtr->x; } fit = MeasureChars(tkfont, chars, charsLen, 0, bend, @@ -8775,7 +8793,7 @@ FinalizeBaseChunk( #if TK_DRAW_IN_CONTEXT newwidth = 0; CharChunkMeasureChars(chunkPtr, NULL, 0, 0, -1, 0, -1, 0, &newwidth); - if (newwidth != chunkPtr->width) { + if (newwidth < chunkPtr->width) { widthAdjust += newwidth - chunkPtr->width; chunkPtr->width = newwidth; } @@ -8963,13 +8981,13 @@ RemoveFromBaseChunk( bciPtr = baseCharChunkPtr->clientData; +#ifdef DEBUG_LAYOUT_WITH_BASE_CHUNKS if ((ciPtr->baseOffset + ciPtr->numBytes) != Tcl_DStringLength(&bciPtr->baseChars)) { -#ifdef DEBUG_LAYOUT_WITH_BASE_CHUNKS fprintf(stderr,"RemoveFromBaseChunk called with wrong chunk " "(not last)\n"); -#endif } +#endif Tcl_DStringSetLength(&bciPtr->baseChars, ciPtr->baseOffset); diff --git a/generic/tkTextIndex.c b/generic/tkTextIndex.c index 92ca03b..cfe230c 100644 --- a/generic/tkTextIndex.c +++ b/generic/tkTextIndex.c @@ -87,7 +87,7 @@ FreeTextIndexInternalRep( TkTextIndex *indexPtr = GET_TEXTINDEX(indexObjPtr); if (indexPtr->textPtr != NULL) { - if (--indexPtr->textPtr->refCount == 0) { + if (indexPtr->textPtr->refCount-- <= 1) { /* * The text widget has been deleted and we need to free it now. */ @@ -2298,9 +2298,9 @@ StartEnd( int chSize = 1; if (segPtr->typePtr == &tkTextCharType) { - Tcl_UniChar ch; + int ch; - chSize = Tcl_UtfToUniChar(segPtr->body.chars + offset, &ch); + chSize = TkUtfToUniChar(segPtr->body.chars + offset, &ch); if (!Tcl_UniCharIsWordChar(ch)) { break; } @@ -2343,9 +2343,9 @@ StartEnd( int chSize = 1; if (segPtr->typePtr == &tkTextCharType) { - Tcl_UniChar ch; - Tcl_UtfToUniChar(segPtr->body.chars + offset, &ch); + int ch; + TkUtfToUniChar(segPtr->body.chars + offset, &ch); if (!Tcl_UniCharIsWordChar(ch)) { break; } diff --git a/generic/tkTextTag.c b/generic/tkTextTag.c index a212615..d9329f5 100644 --- a/generic/tkTextTag.c +++ b/generic/tkTextTag.c @@ -30,7 +30,7 @@ static const char *const wrapStrings[] = { /* * The 'TkTextTabStyle' enum in tkText.h is used to define a type for the * -tabstyle option of the Text widget. These values are used as indices into - * the string table below. Tags are allowed an empty wrap value, but the + * the string table below. Tags are allowed an empty tabstyle value, but the * widget as a whole is not. */ @@ -1258,8 +1258,7 @@ TkTextFreeTag( if (textPtr != tagPtr->textPtr) { Tcl_Panic("Tag being deleted from wrong widget"); } - textPtr->refCount--; - if (textPtr->refCount == 0) { + if (textPtr->refCount-- <= 1) { ckfree(textPtr); } tagPtr->textPtr = NULL; @@ -1522,7 +1521,7 @@ TkTextBindProc( } done: - if (--textPtr->refCount == 0) { + if (textPtr->refCount-- <= 1) { ckfree(textPtr); } } diff --git a/generic/tkUtil.c b/generic/tkUtil.c index d4c4d2d..d89282f 100644 --- a/generic/tkUtil.c +++ b/generic/tkUtil.c @@ -1192,6 +1192,86 @@ TkSendVirtualEvent( Tk_QueueWindowEvent(&event.general, TCL_QUEUE_TAIL); } + +#if TCL_UTF_MAX <= 4 +/* + *--------------------------------------------------------------------------- + * + * TkUtfToUniChar -- + * + * Almost the same as Tcl_UtfToUniChar but using int instead of Tcl_UniChar. + * This function is capable of collapsing a upper/lower surrogate pair to a + * single unicode character. So, up to 6 bytes might be consumed. + * + * Results: + * *chPtr is filled with the Tcl_UniChar, and the return value is the + * number of bytes from the UTF-8 string that were consumed. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + +int +TkUtfToUniChar( + const char *src, /* The UTF-8 string. */ + int *chPtr) /* Filled with the Tcl_UniChar represented by + * the UTF-8 string. */ +{ + Tcl_UniChar uniChar = 0; + + int len = Tcl_UtfToUniChar(src, &uniChar); + if ((uniChar & 0xfc00) == 0xd800) { + Tcl_UniChar high = uniChar; + /* This can only happen if Tcl is compiled with TCL_UTF_MAX=4, + * or when a high surrogate character is detected in UTF-8 form */ + int len2 = Tcl_UtfToUniChar(src+len, &uniChar); + if ((uniChar & 0xfc00) == 0xdc00) { + *chPtr = (((high & 0x3ff) << 10) | (uniChar & 0x3ff)) + 0x10000; + len += len2; + } else { + *chPtr = high; + } + } else { + *chPtr = uniChar; + } + return len; +} + +/* + *--------------------------------------------------------------------------- + * + * TkUniCharToUtf -- + * + * Almost the same as Tcl_UniCharToUtf but producing surrogates if + * TCL_UTF_MAX==3. So, up to 6 bytes might be produced. + * + * Results: + * *buf is filled with the UTF-8 string, and the return value is the + * number of bytes produced. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + +int TkUniCharToUtf(int ch, char *buf) +{ + int size = Tcl_UniCharToUtf(ch, buf); + if ((ch > 0xffff) && (ch <= 0x10ffff) && (size < 4)) { + /* Hey, this is wrong, we must be running TCL_UTF_MAX==3 + * The best thing we can do is spit out 2 surrogates */ + ch -= 0x10000; + size = Tcl_UniCharToUtf(((ch >> 10) | 0xd800), buf); + size += Tcl_UniCharToUtf(((ch & 0x3ff) | 0xdc00), buf+size); + } + return size; +} + + +#endif /* * Local Variables: * mode: c diff --git a/generic/tkVisual.c b/generic/tkVisual.c index 8b0c155..6f6816d 100644 --- a/generic/tkVisual.c +++ b/generic/tkVisual.c @@ -46,7 +46,7 @@ static const VisualDictionary visualNames[] = { struct TkColormap { Colormap colormap; /* X's identifier for the colormap. */ Visual *visual; /* Visual for which colormap was allocated. */ - int refCount; /* How many uses of the colormap are still + size_t refCount; /* How many uses of the colormap are still * outstanding (calls to Tk_GetColormap minus * calls to Tk_FreeColormap). */ int shareable; /* 0 means this colormap was allocated by a @@ -137,7 +137,7 @@ Tk_GetVisual( for (cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL; cmapPtr = cmapPtr->nextPtr) { if (cmapPtr->colormap == *colormapPtr) { - cmapPtr->refCount += 1; + cmapPtr->refCount++; break; } } @@ -324,7 +324,7 @@ Tk_GetVisual( cmapPtr = cmapPtr->nextPtr) { if (cmapPtr->shareable && (cmapPtr->visual == visual)) { *colormapPtr = cmapPtr->colormap; - cmapPtr->refCount += 1; + cmapPtr->refCount++; goto done; } } @@ -427,7 +427,7 @@ Tk_GetColormap( for (cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL; cmapPtr = cmapPtr->nextPtr) { if (cmapPtr->colormap == colormap) { - cmapPtr->refCount += 1; + cmapPtr->refCount++; } } return colormap; @@ -476,8 +476,7 @@ Tk_FreeColormap( for (prevPtr = NULL, cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL; prevPtr = cmapPtr, cmapPtr = cmapPtr->nextPtr) { if (cmapPtr->colormap == colormap) { - cmapPtr->refCount -= 1; - if (cmapPtr->refCount == 0) { + if (cmapPtr->refCount-- <= 1) { XFreeColormap(display, colormap); if (prevPtr == NULL) { dispPtr->cmapPtr = cmapPtr->nextPtr; @@ -534,7 +533,7 @@ Tk_PreserveColormap( for (cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL; cmapPtr = cmapPtr->nextPtr) { if (cmapPtr->colormap == colormap) { - cmapPtr->refCount += 1; + cmapPtr->refCount++; return; } } diff --git a/generic/tkWindow.c b/generic/tkWindow.c index 5855b7c..ed57280 100644 --- a/generic/tkWindow.c +++ b/generic/tkWindow.c @@ -355,6 +355,9 @@ CreateTopLevelWindow( * Set the flags specified in the call. */ +#ifdef TK_USE_INPUT_METHODS + winPtr->ximGeneration = 0; +#endif /*TK_USE_INPUT_METHODS*/ winPtr->flags |= flags; /* @@ -650,6 +653,7 @@ TkAllocWindow( winPtr->flags = 0; winPtr->handlerList = NULL; #ifdef TK_USE_INPUT_METHODS + winPtr->ximGeneration = 0; winPtr->inputContext = NULL; #endif /* TK_USE_INPUT_METHODS */ winPtr->tagPtr = NULL; @@ -943,7 +947,7 @@ TkCreateMainWindow( } /* - * Set variables for the intepreter. + * Set variables for the interpreter. */ Tcl_SetVar2(interp, "tk_patchLevel", NULL, TK_PATCH_LEVEL, TCL_GLOBAL_ONLY); @@ -1442,10 +1446,11 @@ Tk_DestroyWindow( UnlinkWindow(winPtr); TkEventDeadWindow(winPtr); #ifdef TK_USE_INPUT_METHODS - if (winPtr->inputContext != NULL) { + if (winPtr->inputContext != NULL && + winPtr->ximGeneration == winPtr->dispPtr->ximGeneration) { XDestroyIC(winPtr->inputContext); - winPtr->inputContext = NULL; } + winPtr->inputContext = NULL; #endif /* TK_USE_INPUT_METHODS */ if (winPtr->tagPtr != NULL) { TkFreeBindingTags(winPtr); @@ -1479,8 +1484,7 @@ Tk_DestroyWindow( winPtr->mainPtr->deletionEpoch++; } - winPtr->mainPtr->refCount--; - if (winPtr->mainPtr->refCount == 0) { + if (winPtr->mainPtr->refCount-- <= 1) { register const TkCmd *cmdPtr; /* @@ -3041,7 +3045,7 @@ Initialize( * Ensure that we are getting a compatible version of Tcl. */ - if (Tcl_InitStubs(interp, "8.6", 0) == NULL) { + if (Tcl_InitStubs(interp, "8.6-", 0) == NULL) { return TCL_ERROR; } diff --git a/generic/ttk/ttkButton.c b/generic/ttk/ttkButton.c index bc44f25..c00754b 100644 --- a/generic/ttk/ttkButton.c +++ b/generic/ttk/ttkButton.c @@ -136,6 +136,15 @@ BaseCleanup(void *recordPtr) TtkFreeImageSpec(basePtr->base.imageSpec); } +static void +BaseImageChanged( + ClientData clientData, int x, int y, int width, int height, + int imageWidth, int imageHeight) +{ + Base *basePtr = (Base *)clientData; + TtkResizeWidget(&basePtr->core); +} + static int BaseConfigure(Tcl_Interp *interp, void *recordPtr, int mask) { Base *basePtr = recordPtr; @@ -149,8 +158,8 @@ static int BaseConfigure(Tcl_Interp *interp, void *recordPtr, int mask) } if (basePtr->base.imageObj) { - imageSpec = TtkGetImageSpec( - interp, basePtr->core.tkwin, basePtr->base.imageObj); + imageSpec = TtkGetImageSpecEx( + interp, basePtr->core.tkwin, basePtr->base.imageObj, BaseImageChanged, basePtr); if (!imageSpec) { goto error; } diff --git a/generic/ttk/ttkEntry.c b/generic/ttk/ttkEntry.c index f395649..a25574a 100644 --- a/generic/ttk/ttkEntry.c +++ b/generic/ttk/ttkEntry.c @@ -282,15 +282,16 @@ static char *EntryDisplayString(const char *showChar, int numChars) { char *displayString, *p; int size; - Tcl_UniChar ch; - char buf[TCL_UTF_MAX]; + int ch; + char buf[6]; - Tcl_UtfToUniChar(showChar, &ch); - size = Tcl_UniCharToUtf(ch, buf); + TkUtfToUniChar(showChar, &ch); + size = TkUniCharToUtf(ch, buf); p = displayString = ckalloc(numChars * size + 1); while (numChars--) { - p += Tcl_UniCharToUtf(ch, p); + memcpy(p, buf, size); + p += size; } *p = '\0'; @@ -405,7 +406,7 @@ ExpandPercents( int number, length; const char *string; int stringLength; - Tcl_UniChar ch; + int ch; char numStorage[2*TCL_INTEGER_SPACE]; while (*template) { @@ -429,7 +430,7 @@ ExpandPercents( */ ++template; /* skip over % */ if (*template != '\0') { - template += Tcl_UtfToUniChar(template, &ch); + template += TkUtfToUniChar(template, &ch); } else { ch = '%'; } @@ -479,7 +480,7 @@ ExpandPercents( string = Tk_PathName(entryPtr->core.tkwin); break; default: - length = Tcl_UniCharToUtf(ch, numStorage); + length = TkUniCharToUtf(ch, numStorage); numStorage[length] = '\0'; string = numStorage; break; diff --git a/generic/ttk/ttkGenStubs.tcl b/generic/ttk/ttkGenStubs.tcl deleted file mode 100644 index 8047e3f..0000000 --- a/generic/ttk/ttkGenStubs.tcl +++ /dev/null @@ -1,963 +0,0 @@ -# ttkGenStubs.tcl -- -# -# This script generates a set of stub files for a given -# interface. -# -# -# Copyright (c) 1998-1999 by Scriptics Corporation. -# Copyright (c) 2007 Daniel A. Steffen <das@users.sourceforge.net> -# -# See the file "license.terms" for information on usage and redistribution -# of this file, and for a DISCLAIMER OF ALL WARRANTIES. -# -# SOURCE: tcl/tools/genStubs.tcl, revision 1.44 -# -# CHANGES: -# + Second argument to "declare" is used as a status guard -# instead of a platform guard. -# + Allow trailing semicolon in function declarations -# - -namespace eval genStubs { - # libraryName -- - # - # The name of the entire library. This value is used to compute - # the USE_*_STUBS macro and the name of the init file. - - variable libraryName "UNKNOWN" - - # interfaces -- - # - # An array indexed by interface name that is used to maintain - # the set of valid interfaces. The value is empty. - - array set interfaces {} - - # curName -- - # - # The name of the interface currently being defined. - - variable curName "UNKNOWN" - - # scspec -- - # - # Storage class specifier for external function declarations. - # Normally "EXTERN", may be set to something like XYZAPI - # - variable scspec "EXTERN" - - # epoch, revision -- - # - # The epoch and revision numbers of the interface currently being defined. - # (@@@TODO: should be an array mapping interface names -> numbers) - # - - variable epoch {} - variable revision 0 - - # hooks -- - # - # An array indexed by interface name that contains the set of - # subinterfaces that should be defined for a given interface. - - array set hooks {} - - # stubs -- - # - # This three dimensional array is indexed first by interface name, - # second by field name, and third by a numeric offset or the - # constant "lastNum". The lastNum entry contains the largest - # numeric offset used for a given interface. - # - # Field "decl,$i" contains the C function specification that - # should be used for the given entry in the stub table. The spec - # consists of a list in the form returned by parseDecl. - # Other fields TBD later. - - array set stubs {} - - # outDir -- - # - # The directory where the generated files should be placed. - - variable outDir . -} - -# genStubs::library -- -# -# This function is used in the declarations file to set the name -# of the library that the interfaces are associated with (e.g. "tcl"). -# This value will be used to define the inline conditional macro. -# -# Arguments: -# name The library name. -# -# Results: -# None. - -proc genStubs::library {name} { - variable libraryName $name -} - -# genStubs::interface -- -# -# This function is used in the declarations file to set the name -# of the interface currently being defined. -# -# Arguments: -# name The name of the interface. -# -# Results: -# None. - -proc genStubs::interface {name} { - variable curName $name - variable interfaces - variable stubs - - set interfaces($name) {} - set stubs($name,lastNum) 0 - return -} - -# genStubs::scspec -- -# -# Define the storage class macro used for external function declarations. -# Typically, this will be a macro like XYZAPI or EXTERN that -# expands to either DLLIMPORT or DLLEXPORT, depending on whether -# -DBUILD_XYZ has been set. -# -proc genStubs::scspec {value} { - variable scspec $value -} - -# genStubs::epoch -- -# -# Define the epoch number for this library. The epoch -# should be incrememented when a release is made that -# contains incompatible changes to the public API. -# -proc genStubs::epoch {value} { - variable epoch $value -} - -# genStubs::hooks -- -# -# This function defines the subinterface hooks for the current -# interface. -# -# Arguments: -# names The ordered list of interfaces that are reachable through the -# hook vector. -# -# Results: -# None. - -proc genStubs::hooks {names} { - variable curName - variable hooks - - set hooks($curName) $names - return -} - -# genStubs::declare -- -# -# This function is used in the declarations file to declare a new -# interface entry. -# -# Arguments: -# index The index number of the interface. -# status Status of the interface: one of "current", -# "deprecated", or "obsolete". -# decl The C function declaration, or {} for an undefined -# entry. -# -# Results: -# None. - -proc genStubs::declare {args} { - variable stubs - variable curName - variable revision - - incr revision - if {[llength $args] == 2} { - lassign $args index decl - set status current - } elseif {[llength $args] == 3} { - lassign $args index status decl - } else { - puts stderr "wrong # args: declare $args" - return - } - - # Check for duplicate declarations, then add the declaration and - # bump the lastNum counter if necessary. - - if {[info exists stubs($curName,decl,$index)]} { - puts stderr "Duplicate entry: $index" - } - regsub -all "\[ \t\n\]+" [string trim $decl] " " decl - set decl [parseDecl $decl] - - set stubs($curName,status,$index) $status - set stubs($curName,decl,$index) $decl - - if {$index > $stubs($curName,lastNum)} { - set stubs($curName,lastNum) $index - } - return -} - -# genStubs::export -- -# -# This function is used in the declarations file to declare a symbol -# that is exported from the library but is not in the stubs table. -# -# Arguments: -# decl The C function declaration, or {} for an undefined -# entry. -# -# Results: -# None. - -proc genStubs::export {args} { - if {[llength $args] != 1} { - puts stderr "wrong # args: export $args" - } - return -} - -# genStubs::rewriteFile -- -# -# This function replaces the machine generated portion of the -# specified file with new contents. It looks for the !BEGIN! and -# !END! comments to determine where to place the new text. -# -# Arguments: -# file The name of the file to modify. -# text The new text to place in the file. -# -# Results: -# None. - -proc genStubs::rewriteFile {file text} { - if {![file exists $file]} { - puts stderr "Cannot find file: $file" - return - } - set in [open ${file} r] - set out [open ${file}.new w] - fconfigure $out -translation lf - - while {![eof $in]} { - set line [gets $in] - if {[string match "*!BEGIN!*" $line]} { - break - } - puts $out $line - } - puts $out "/* !BEGIN!: Do not edit below this line. */" - puts $out $text - while {![eof $in]} { - set line [gets $in] - if {[string match "*!END!*" $line]} { - break - } - } - puts $out "/* !END!: Do not edit above this line. */" - puts -nonewline $out [read $in] - close $in - close $out - file rename -force ${file}.new ${file} - return -} - -# genStubs::addPlatformGuard -- -# -# Wrap a string inside a platform #ifdef. -# -# Arguments: -# plat Platform to test. -# -# Results: -# Returns the original text inside an appropriate #ifdef. - -proc genStubs::addPlatformGuard {plat iftxt {eltxt {}}} { - set text "" - switch $plat { - win { - append text "#ifdef _WIN32 /* WIN */\n${iftxt}" - if {$eltxt ne ""} { - append text "#else /* WIN */\n${eltxt}" - } - append text "#endif /* WIN */\n" - } - unix { - append text "#if !defined(_WIN32) && !defined(MAC_OSX_TCL)\ - /* UNIX */\n${iftxt}" - if {$eltxt ne ""} { - append text "#else /* UNIX */\n${eltxt}" - } - append text "#endif /* UNIX */\n" - } - macosx { - append text "#ifdef MAC_OSX_TCL /* MACOSX */\n${iftxt}" - if {$eltxt ne ""} { - append text "#else /* MACOSX */\n${eltxt}" - } - append text "#endif /* MACOSX */\n" - } - aqua { - append text "#ifdef MAC_OSX_TK /* AQUA */\n${iftxt}" - if {$eltxt ne ""} { - append text "#else /* AQUA */\n${eltxt}" - } - append text "#endif /* AQUA */\n" - } - x11 { - append text "#if !(defined(_WIN32) || defined(MAC_OSX_TK))\ - /* X11 */\n${iftxt}" - if {$eltxt ne ""} { - append text "#else /* X11 */\n${eltxt}" - } - append text "#endif /* X11 */\n" - } - default { - append text "${iftxt}${eltxt}" - } - } - return $text -} - -# genStubs::emitSlots -- -# -# Generate the stub table slots for the given interface. If there -# are no generic slots, then one table is generated for each -# platform, otherwise one table is generated for all platforms. -# -# Arguments: -# name The name of the interface being emitted. -# textVar The variable to use for output. -# -# Results: -# None. - -proc genStubs::emitSlots {name textVar} { - upvar $textVar text - - forAllStubs $name makeSlot noGuard text {" void (*reserved$i)(void);\n"} - return -} - -# genStubs::parseDecl -- -# -# Parse a C function declaration into its component parts. -# -# Arguments: -# decl The function declaration. -# -# Results: -# Returns a list of the form {returnType name args}. The args -# element consists of a list of type/name pairs, or a single -# element "void". If the function declaration is malformed -# then an error is displayed and the return value is {}. - -proc genStubs::parseDecl {decl} { - if {![regexp {^(.*)\((.*)\);?$} $decl all prefix args]} { - set prefix $decl - set args {} - } - set prefix [string trim $prefix] - if {![regexp {^(.+[ ][*]*)([^ *]+)$} $prefix all rtype fname]} { - puts stderr "Bad return type: $decl" - return - } - set rtype [string trim $rtype] - if {$args eq ""} { - return [list $rtype $fname {}] - } - foreach arg [split $args ,] { - lappend argList [string trim $arg] - } - if {![string compare [lindex $argList end] "..."]} { - set args TCL_VARARGS - foreach arg [lrange $argList 0 end-1] { - set argInfo [parseArg $arg] - if {[llength $argInfo] == 2 || [llength $argInfo] == 3} { - lappend args $argInfo - } else { - puts stderr "Bad argument: '$arg' in '$decl'" - return - } - } - } else { - set args {} - foreach arg $argList { - set argInfo [parseArg $arg] - if {![string compare $argInfo "void"]} { - lappend args "void" - break - } elseif {[llength $argInfo] == 2 || [llength $argInfo] == 3} { - lappend args $argInfo - } else { - puts stderr "Bad argument: '$arg' in '$decl'" - return - } - } - } - return [list $rtype $fname $args] -} - -# genStubs::parseArg -- -# -# This function parses a function argument into a type and name. -# -# Arguments: -# arg The argument to parse. -# -# Results: -# Returns a list of type and name with an optional third array -# indicator. If the argument is malformed, returns "". - -proc genStubs::parseArg {arg} { - if {![regexp {^(.+[ ][*]*)([^][ *]+)(\[\])?$} $arg all type name array]} { - if {$arg eq "void"} { - return $arg - } else { - return - } - } - set result [list [string trim $type] $name] - if {$array ne ""} { - lappend result $array - } - return $result -} - -# genStubs::makeDecl -- -# -# Generate the prototype for a function. -# -# Arguments: -# name The interface name. -# decl The function declaration. -# index The slot index for this function. -# -# Results: -# Returns the formatted declaration string. - -proc genStubs::makeDecl {name decl index} { - variable scspec - lassign $decl rtype fname args - - append text "/* $index */\n" - set line "$scspec $rtype" - set count [expr {2 - ([string length $line] / 8)}] - append line [string range "\t\t\t" 0 $count] - set pad [expr {24 - [string length $line]}] - if {$pad <= 0} { - append line " " - set pad 0 - } - if {$args eq ""} { - append line $fname - append text $line - append text ";\n" - return $text - } - append line $fname - - set arg1 [lindex $args 0] - switch -exact $arg1 { - void { - append line "(void)" - } - TCL_VARARGS { - set sep "(" - foreach arg [lrange $args 1 end] { - append line $sep - set next {} - append next [lindex $arg 0] - if {[string index $next end] ne "*"} { - append next " " - } - append next [lindex $arg 1] [lindex $arg 2] - if {[string length $line] + [string length $next] \ - + $pad > 76} { - append text [string trimright $line] \n - set line "\t\t\t\t" - set pad 28 - } - append line $next - set sep ", " - } - append line ", ...)" - } - default { - set sep "(" - foreach arg $args { - append line $sep - set next {} - append next [lindex $arg 0] - if {[string index $next end] ne "*"} { - append next " " - } - append next [lindex $arg 1] [lindex $arg 2] - if {[string length $line] + [string length $next] \ - + $pad > 76} { - append text [string trimright $line] \n - set line "\t\t\t\t" - set pad 28 - } - append line $next - set sep ", " - } - append line ")" - } - } - return "$text$line;\n" -} - -# genStubs::makeMacro -- -# -# Generate the inline macro for a function. -# -# Arguments: -# name The interface name. -# decl The function declaration. -# index The slot index for this function. -# -# Results: -# Returns the formatted macro definition. - -proc genStubs::makeMacro {name decl index} { - lassign $decl rtype fname args - - set lfname [string tolower [string index $fname 0]] - append lfname [string range $fname 1 end] - - set text "#define $fname \\\n\t(" - if {$args eq ""} { - append text "*" - } - append text "${name}StubsPtr->$lfname)" - append text " /* $index */\n" - return $text -} - -# genStubs::makeSlot -- -# -# Generate the stub table entry for a function. -# -# Arguments: -# name The interface name. -# decl The function declaration. -# index The slot index for this function. -# -# Results: -# Returns the formatted table entry. - -proc genStubs::makeSlot {name decl index} { - lassign $decl rtype fname args - - set lfname [string tolower [string index $fname 0]] - append lfname [string range $fname 1 end] - - set text " " - if {$args eq ""} { - append text $rtype " *" $lfname "; /* $index */\n" - return $text - } - if {[string range $rtype end-8 end] eq "__stdcall"} { - append text [string trim [string range $rtype 0 end-9]] " (__stdcall *" $lfname ") " - } else { - append text $rtype " (*" $lfname ") " - } - set arg1 [lindex $args 0] - switch -exact $arg1 { - void { - append text "(void)" - } - TCL_VARARGS { - set sep "(" - foreach arg [lrange $args 1 end] { - append text $sep [lindex $arg 0] - if {[string index $text end] ne "*"} { - append text " " - } - append text [lindex $arg 1] [lindex $arg 2] - set sep ", " - } - append text ", ...)" - } - default { - set sep "(" - foreach arg $args { - append text $sep [lindex $arg 0] - if {[string index $text end] ne "*"} { - append text " " - } - append text [lindex $arg 1] [lindex $arg 2] - set sep ", " - } - append text ")" - } - } - - append text "; /* $index */\n" - return $text -} - -# genStubs::makeInit -- -# -# Generate the prototype for a function. -# -# Arguments: -# name The interface name. -# decl The function declaration. -# index The slot index for this function. -# -# Results: -# Returns the formatted declaration string. - -proc genStubs::makeInit {name decl index} { - if {[lindex $decl 2] eq ""} { - append text " &" [lindex $decl 1] ", /* " $index " */\n" - } else { - append text " " [lindex $decl 1] ", /* " $index " */\n" - } - return $text -} - -# genStubs::forAllStubs -- -# -# This function iterates over all of the slots and invokes -# a callback for each slot. The result of the callback is then -# placed inside appropriate guards. -# -# Arguments: -# name The interface name. -# slotProc The proc to invoke to handle the slot. It will -# have the interface name, the declaration, and -# the index appended. -# guardProc The proc to invoke to add guards. It will have -# the slot status and text appended. -# textVar The variable to use for output. -# skipString The string to emit if a slot is skipped. This -# string will be subst'ed in the loop so "$i" can -# be used to substitute the index value. -# -# Results: -# None. - -proc genStubs::forAllStubs {name slotProc guardProc textVar - {skipString {"/* Slot $i is reserved */\n"}}} { - variable stubs - upvar $textVar text - - set lastNum $stubs($name,lastNum) - - for {set i 0} {$i <= $lastNum} {incr i} { - if {[info exists stubs($name,decl,$i)]} { - append text [$guardProc $stubs($name,status,$i) \ - [$slotProc $name $stubs($name,decl,$i) $i]] - } else { - eval {append text} $skipString - } - } -} - -proc genStubs::noGuard {status text} { return $text } - -proc genStubs::addGuard {status text} { - variable libraryName - set upName [string toupper $libraryName] - - switch -- $status { - current { - # No change - } - deprecated { - set text [ifdeffed "${upName}_DEPRECATED" $text] - } - obsolete { - set text "" - } - default { - puts stderr "Unrecognized status code $status" - } - } - return $text -} - -proc genStubs::ifdeffed {macro text} { - join [list "#ifdef $macro" $text "#endif" ""] \n -} - -# genStubs::emitDeclarations -- -# -# This function emits the function declarations for this interface. -# -# Arguments: -# name The interface name. -# textVar The variable to use for output. -# -# Results: -# None. - -proc genStubs::emitDeclarations {name textVar} { - upvar $textVar text - - append text "\n/*\n * Exported function declarations:\n */\n\n" - forAllStubs $name makeDecl noGuard text - return -} - -# genStubs::emitMacros -- -# -# This function emits the inline macros for an interface. -# -# Arguments: -# name The name of the interface being emitted. -# textVar The variable to use for output. -# -# Results: -# None. - -proc genStubs::emitMacros {name textVar} { - variable libraryName - upvar $textVar text - - set upName [string toupper $libraryName] - append text "\n#if defined(USE_${upName}_STUBS)\n" - append text "\n/*\n * Inline function declarations:\n */\n\n" - - forAllStubs $name makeMacro addGuard text - - append text "\n#endif /* defined(USE_${upName}_STUBS) */\n" - return -} - -# genStubs::emitHeader -- -# -# This function emits the body of the <name>Decls.h file for -# the specified interface. -# -# Arguments: -# name The name of the interface being emitted. -# -# Results: -# None. - -proc genStubs::emitHeader {name} { - variable outDir - variable hooks - variable epoch - variable revision - - set capName [string toupper [string index $name 0]] - append capName [string range $name 1 end] - - if {$epoch ne ""} { - set CAPName [string toupper $name] - append text "\n" - append text "#define ${CAPName}_STUBS_EPOCH $epoch\n" - append text "#define ${CAPName}_STUBS_REVISION $revision\n" - } - - append text "\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n" - - emitDeclarations $name text - - if {[info exists hooks($name)]} { - append text "\ntypedef struct {\n" - foreach hook $hooks($name) { - set capHook [string toupper [string index $hook 0]] - append capHook [string range $hook 1 end] - append text " const struct ${capHook}Stubs *${hook}Stubs;\n" - } - append text "} ${capName}StubHooks;\n" - } - append text "\ntypedef struct ${capName}Stubs {\n" - append text " int magic;\n" - if {$epoch ne ""} { - append text " int epoch;\n" - append text " int revision;\n" - } - if {[info exists hooks($name)]} { - append text " const ${capName}StubHooks *hooks;\n\n" - } else { - append text " void *hooks;\n\n" - } - - emitSlots $name text - - append text "} ${capName}Stubs;\n\n" - - append text "extern const ${capName}Stubs *${name}StubsPtr;\n\n" - append text "#ifdef __cplusplus\n}\n#endif\n" - - emitMacros $name text - - rewriteFile [file join $outDir ${name}Decls.h] $text - return -} - -# genStubs::emitInit -- -# -# Generate the table initializers for an interface. -# -# Arguments: -# name The name of the interface to initialize. -# textVar The variable to use for output. -# -# Results: -# Returns the formatted output. - -proc genStubs::emitInit {name textVar} { - variable hooks - variable interfaces - variable epoch - upvar $textVar text - set root 1 - - set capName [string toupper [string index $name 0]] - append capName [string range $name 1 end] - - if {[info exists hooks($name)]} { - append text "\nstatic const ${capName}StubHooks ${name}StubHooks = \{\n" - set sep " " - foreach sub $hooks($name) { - append text $sep "&${sub}Stubs" - set sep ",\n " - } - append text "\n\};\n" - } - foreach intf [array names interfaces] { - if {[info exists hooks($intf)]} { - if {[lsearch -exact $hooks($intf) $name] >= 0} { - set root 0 - break - } - } - } - - append text "\n" - if {!$root} { - append text "static " - } - append text "const ${capName}Stubs ${name}Stubs = \{\n TCL_STUB_MAGIC,\n" - if {$epoch ne ""} { - set CAPName [string toupper $name] - append text " ${CAPName}_STUBS_EPOCH,\n" - append text " ${CAPName}_STUBS_REVISION,\n" - } - if {[info exists hooks($name)]} { - append text " &${name}StubHooks,\n" - } else { - append text " 0,\n" - } - - forAllStubs $name makeInit noGuard text {" 0, /* $i */\n"} - - append text "\};\n" - return -} - -# genStubs::emitInits -- -# -# This function emits the body of the <name>StubInit.c file for -# the specified interface. -# -# Arguments: -# name The name of the interface being emitted. -# -# Results: -# None. - -proc genStubs::emitInits {} { - variable hooks - variable outDir - variable libraryName - variable interfaces - - # Assuming that dependencies only go one level deep, we need to emit - # all of the leaves first to avoid needing forward declarations. - - set leaves {} - set roots {} - foreach name [lsort [array names interfaces]] { - if {[info exists hooks($name)]} { - lappend roots $name - } else { - lappend leaves $name - } - } - foreach name $leaves { - emitInit $name text - } - foreach name $roots { - emitInit $name text - } - - rewriteFile [file join $outDir ${libraryName}StubInit.c] $text -} - -# genStubs::init -- -# -# This is the main entry point. -# -# Arguments: -# None. -# -# Results: -# None. - -proc genStubs::init {} { - global argv argv0 - variable outDir - variable interfaces - - if {[llength $argv] < 2} { - puts stderr "usage: $argv0 outDir declFile ?declFile...?" - exit 1 - } - - set outDir [lindex $argv 0] - - foreach file [lrange $argv 1 end] { - source $file - } - - foreach name [lsort [array names interfaces]] { - puts "Emitting $name" - emitHeader $name - } - - emitInits -} - -# lassign -- -# -# This function emulates the TclX lassign command. -# -# Arguments: -# valueList A list containing the values to be assigned. -# args The list of variables to be assigned. -# -# Results: -# Returns any values that were not assigned to variables. - -if {[string length [namespace which lassign]] == 0} { - proc lassign {valueList args} { - if {[llength $args] == 0} { - error "wrong # args: should be \"lassign list varName ?varName ...?\"" - } - uplevel [list foreach $args $valueList {break}] - return [lrange $valueList [llength $args] end] - } -} - -genStubs::init diff --git a/generic/ttk/ttkImage.c b/generic/ttk/ttkImage.c index a5a3a52..e403e2d 100644 --- a/generic/ttk/ttkImage.c +++ b/generic/ttk/ttkImage.c @@ -25,6 +25,8 @@ struct TtkImageSpec { int mapCount; /* #state-specific overrides */ Ttk_StateSpec *states; /* array[mapCount] of states ... */ Tk_Image *images; /* ... per-state images to use */ + Tk_ImageChangedProc *imageChanged; + ClientData imageChangedClientData; }; /* NullImageChanged -- @@ -34,15 +36,41 @@ static void NullImageChanged(ClientData clientData, int x, int y, int width, int height, int imageWidth, int imageHeight) { /* No-op */ } +/* ImageSpecImageChanged -- + * Image changes should trigger a repaint. + */ +static void ImageSpecImageChanged(ClientData clientData, + int x, int y, int width, int height, int imageWidth, int imageHeight) +{ + Ttk_ImageSpec *imageSpec = (Ttk_ImageSpec *)clientData; + if (imageSpec->imageChanged != NULL) { + imageSpec->imageChanged(imageSpec->imageChangedClientData, + x, y, width, height, + imageWidth, imageHeight); + } +} + /* TtkGetImageSpec -- * Constructs a Ttk_ImageSpec * from a Tcl_Obj *. * Result must be released using TtkFreeImageSpec. * - * TODO: Need a variant of this that takes a user-specified ImageChanged proc */ Ttk_ImageSpec * TtkGetImageSpec(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr) { + return TtkGetImageSpecEx(interp, tkwin, objPtr, NULL, NULL); +} + +/* TtkGetImageSpecEx -- + * Constructs a Ttk_ImageSpec * from a Tcl_Obj *. + * Result must be released using TtkFreeImageSpec. + * imageChangedProc will be called when not NULL when + * the image changes to allow widgets to repaint. + */ +Ttk_ImageSpec * +TtkGetImageSpecEx(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, + Tk_ImageChangedProc *imageChangedProc, ClientData imageChangedClientData) +{ Ttk_ImageSpec *imageSpec = 0; int i = 0, n = 0, objc; Tcl_Obj **objv; @@ -52,6 +80,8 @@ TtkGetImageSpec(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr) imageSpec->mapCount = 0; imageSpec->states = 0; imageSpec->images = 0; + imageSpec->imageChanged = imageChangedProc; + imageSpec->imageChangedClientData = imageChangedClientData; if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { goto error; @@ -74,7 +104,7 @@ TtkGetImageSpec(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr) /* Get base image: */ imageSpec->baseImage = Tk_GetImage( - interp, tkwin, Tcl_GetString(objv[0]), NullImageChanged, NULL); + interp, tkwin, Tcl_GetString(objv[0]), ImageSpecImageChanged, imageSpec); if (!imageSpec->baseImage) { goto error; } diff --git a/generic/ttk/ttkTheme.h b/generic/ttk/ttkTheme.h index 7bf2a7f..9251dea 100644 --- a/generic/ttk/ttkTheme.h +++ b/generic/ttk/ttkTheme.h @@ -372,6 +372,8 @@ MODULE_SCOPE void Ttk_RegisterNamedColor(Ttk_ResourceCache, const char *, XColor typedef struct TtkImageSpec Ttk_ImageSpec; TTKAPI Ttk_ImageSpec *TtkGetImageSpec(Tcl_Interp *, Tk_Window, Tcl_Obj *); +TTKAPI Ttk_ImageSpec *TtkGetImageSpecEx(Tcl_Interp *, Tk_Window, Tcl_Obj *, + Tk_ImageChangedProc *, ClientData); TTKAPI void TtkFreeImageSpec(Ttk_ImageSpec *); TTKAPI Tk_Image TtkSelectImage(Ttk_ImageSpec *, Ttk_State); |