diff options
Diffstat (limited to 'generic')
138 files changed, 23798 insertions, 19740 deletions
diff --git a/generic/default.h b/generic/default.h index 6156f4d..e6ef132 100644 --- a/generic/default.h +++ b/generic/default.h @@ -14,8 +14,7 @@ #ifndef _DEFAULT #define _DEFAULT -#if defined(__WIN32__) || defined(_WIN32) || \ - defined(__MINGW32__) +#ifdef _WIN32 # include "tkWinDefault.h" #else # if defined(MAC_OSX_TK) diff --git a/generic/tk.decls b/generic/tk.decls index 2825111..9ceb3af 100644 --- a/generic/tk.decls +++ b/generic/tk.decls @@ -20,6 +20,7 @@ library tk interface tk hooks {tkPlat tkInt tkIntPlat tkIntXlib} +scspec EXTERN # Declare each of the functions in the public Tk interface. Note that # the an index should never be reused for a different function in order @@ -104,7 +105,7 @@ declare 18 { Tk_Window tkwin, const char *value, char *widgRec, int offset) } declare 19 { - char *Tk_CanvasTagsPrintProc(ClientData clientData, Tk_Window tkwin, + CONST86 char *Tk_CanvasTagsPrintProc(ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr) } declare 20 { @@ -127,24 +128,24 @@ declare 24 { } declare 25 { int Tk_ClipboardAppend(Tcl_Interp *interp, Tk_Window tkwin, - Atom target, Atom format, char *buffer) + Atom target, Atom format, const char *buffer) } declare 26 { int Tk_ClipboardClear(Tcl_Interp *interp, Tk_Window tkwin) } declare 27 { int Tk_ConfigureInfo(Tcl_Interp *interp, - Tk_Window tkwin, Tk_ConfigSpec *specs, + Tk_Window tkwin, const Tk_ConfigSpec *specs, char *widgRec, const char *argvName, int flags) } declare 28 { int Tk_ConfigureValue(Tcl_Interp *interp, - Tk_Window tkwin, Tk_ConfigSpec *specs, + Tk_Window tkwin, const Tk_ConfigSpec *specs, char *widgRec, const char *argvName, int flags) } declare 29 { int Tk_ConfigureWidget(Tcl_Interp *interp, - Tk_Window tkwin, Tk_ConfigSpec *specs, + Tk_Window tkwin, const Tk_ConfigSpec *specs, int argc, CONST84 char **argv, char *widgRec, int flags) } @@ -164,7 +165,7 @@ declare 32 { declare 33 { unsigned long Tk_CreateBinding(Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object, - const char *eventStr, const char *command, int append) + const char *eventStr, const char *script, int append) } declare 34 { Tk_BindingTable Tk_CreateBindingTable(Tcl_Interp *interp) @@ -183,13 +184,13 @@ declare 37 { void Tk_CreateGenericHandler(Tk_GenericProc *proc, ClientData clientData) } declare 38 { - void Tk_CreateImageType(Tk_ImageType *typePtr) + void Tk_CreateImageType(const Tk_ImageType *typePtr) } declare 39 { void Tk_CreateItemType(Tk_ItemType *typePtr) } declare 40 { - void Tk_CreatePhotoImageFormat(Tk_PhotoImageFormat *formatPtr) + void Tk_CreatePhotoImageFormat(const Tk_PhotoImageFormat *formatPtr) } declare 41 { void Tk_CreateSelHandler(Tk_Window tkwin, @@ -207,7 +208,7 @@ declare 43 { } declare 44 { int Tk_DefineBitmap(Tcl_Interp *interp, const char *name, - const char *source, int width, int height) + const void *source, int width, int height) } declare 45 { void Tk_DefineCursor(Tk_Window window, Tk_Cursor cursor) @@ -316,7 +317,7 @@ declare 73 { void Tk_FreeImage(Tk_Image image) } declare 74 { - void Tk_FreeOptions(Tk_ConfigSpec *specs, + void Tk_FreeOptions(const Tk_ConfigSpec *specs, char *widgRec, Display *display, int needFlags) } declare 75 { @@ -359,7 +360,7 @@ declare 85 { } declare 86 { Pixmap Tk_GetBitmapFromData(Tcl_Interp *interp, - Tk_Window tkwin, const char *source, int width, int height) + Tk_Window tkwin, const void *source, int width, int height) } declare 87 { int Tk_GetCapStyle(Tcl_Interp *interp, const char *str, int *capPtr) @@ -403,7 +404,7 @@ declare 97 { } declare 98 { ClientData Tk_GetImageMasterData(Tcl_Interp *interp, - const char *name, Tk_ImageType **typePtrPtr) + const char *name, CONST86 Tk_ImageType **typePtrPtr) } declare 99 { Tk_ItemType *Tk_GetItemTypes(void) @@ -561,7 +562,7 @@ declare 142 { declare 143 { int Tk_ParseArgv(Tcl_Interp *interp, Tk_Window tkwin, int *argcPtr, CONST84 char **argv, - Tk_ArgvInfo *argTable, int flags) + const Tk_ArgvInfo *argTable, int flags) } declare 144 { void Tk_PhotoPutBlock_NoComposite(Tk_PhotoHandle handle, @@ -824,7 +825,7 @@ declare 216 { int Tk_CreateConsoleWindow(Tcl_Interp *interp) } declare 217 { - void Tk_CreateSmoothMethod(Tcl_Interp *interp, Tk_SmoothMethod *method) + void Tk_CreateSmoothMethod(Tcl_Interp *interp, const Tk_SmoothMethod *method) } #declare 218 { # void Tk_CreateCanvasVisitor(Tcl_Interp *interp, void *typePtr) @@ -923,7 +924,7 @@ declare 241 { } declare 242 { void Tk_SetClassProcs(Tk_Window tkwin, - Tk_ClassProcs *procs, ClientData instanceData) + const Tk_ClassProcs *procs, ClientData instanceData) } # New in 8.4a4 @@ -1062,13 +1063,10 @@ declare 271 { # Developers who need to produce a file [load]able into legacy interps must # build against legacy sources. declare 272 { - void Tk_CreateOldImageType(Tk_ImageType *typePtr) + void Tk_CreateOldImageType(const Tk_ImageType *typePtr) } declare 273 { - void Tk_CreateOldPhotoImageFormat(Tk_PhotoImageFormat *formatPtr) -} -declare 275 { - void TkUnusedStubEntry(void) + void Tk_CreateOldPhotoImageFormat(const Tk_PhotoImageFormat *formatPtr) } # Define the platform specific public Tk interface. These functions are @@ -1147,31 +1145,9 @@ declare 10 aqua { # Public functions that are not accessible via the stubs table. export { - const char *Tk_InitStubs(Tcl_Interp *interp, const char *version, - int exact) -} -export { const char *Tk_PkgInitStubsCheck(Tcl_Interp *interp, const char *version, int exact) } - -# Global variables that need to be exported from the tcl shared library. - -export { - TkStubs *tkStubsPtr (fool checkstubs) -} -export { - TkPlatStubs *tkPlatStubsPtr (fool checkstubs) -} -export { - TkIntStubs *tkIntStubsPtr (fool checkstubs) -} -export { - TkIntPlatStubs *tkIntPlatStubsPtr (fool checkstubs) -} -export { - TkIntXlibStubs *tkIntXlibStubsPtr (fool checkstubs) -} # Local Variables: # mode: tcl diff --git a/generic/tk.h b/generic/tk.h index 2a3d602..d5f876e 100644 --- a/generic/tk.h +++ b/generic/tk.h @@ -17,18 +17,35 @@ #define _TK #include <tcl.h> -#if (TCL_MAJOR_VERSION != 8) || (TCL_MINOR_VERSION < 5) -# error Tk 8.5 must be compiled with tcl.h from Tcl 8.5 or better +#if (TCL_MAJOR_VERSION != 8) || (TCL_MINOR_VERSION < 6) +# error Tk 8.6 must be compiled with tcl.h from Tcl 8.6 or better #endif -#ifndef _ANSI_ARGS_ -# ifndef NO_PROTOTYPES -# define _ANSI_ARGS_(x) x -# else -# define _ANSI_ARGS_(x) () -# endif +#ifndef CONST84 +# define CONST84 const +# define CONST84_RETURN const #endif - +#ifndef CONST86 +# define CONST86 CONST84 +#endif +#ifndef EXTERN +# define EXTERN extern TCL_STORAGE_CLASS +#endif + +/* + * Utility macros: STRINGIFY takes an argument and wraps it in "" (double + * quotation marks), JOIN joins two arguments. + */ + +#ifndef STRINGIFY +# define STRINGIFY(x) STRINGIFY1(x) +# define STRINGIFY1(x) #x +#endif +#ifndef JOIN +# define JOIN(a,b) JOIN1(a,b) +# define JOIN1(a,b) a##b +#endif + /* * For C++ compilers, use extern "C" */ @@ -45,8 +62,7 @@ extern "C" { * unix/configure.in (2 LOC Major, 2 LOC minor, 1 LOC patch) * win/configure.in (as above) * README (sections 0 and 1) - * macosx/Wish.xcode/project.pbxproj (not patchlevel) 1 LOC - * macosx/Wish-Common.xcconfig (not patchlevel) 1 LOC + * macosx/Tk-Common.xcconfig (not patchlevel) 1 LOC * win/README (not patchlevel) * unix/README (not patchlevel) * unix/tk.spec (1 LOC patch) @@ -57,13 +73,13 @@ extern "C" { */ #define TK_MAJOR_VERSION 8 -#define TK_MINOR_VERSION 5 +#define TK_MINOR_VERSION 6 #define TK_RELEASE_LEVEL TCL_FINAL_RELEASE -#define TK_RELEASE_SERIAL 19 - -#define TK_VERSION "8.5" -#define TK_PATCH_LEVEL "8.5.19" +#define TK_RELEASE_SERIAL 9 +#define TK_VERSION "8.6" +#define TK_PATCH_LEVEL "8.6.9" + /* * A special definition used to allow this header file to be included from * windows or mac resource files so that they can obtain version information. @@ -190,7 +206,7 @@ typedef struct Tk_OptionSpec { * the record. */ int flags; /* Any combination of the values defined * below. */ - ClientData clientData; /* An alternate place to put option-specific + const void *clientData; /* An alternate place to put option-specific * data. Used for the monochrome default value * for colors, etc. */ int typeMask; /* An arbitrary bit mask defined by the class @@ -216,15 +232,15 @@ typedef struct Tk_OptionSpec { * option config code to handle a custom option. */ -typedef int (Tk_CustomOptionSetProc) _ANSI_ARGS_((ClientData clientData, +typedef int (Tk_CustomOptionSetProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj **value, char *widgRec, - int offset, char *saveInternalPtr, int flags)); -typedef Tcl_Obj *(Tk_CustomOptionGetProc) _ANSI_ARGS_((ClientData clientData, - Tk_Window tkwin, char *widgRec, int offset)); -typedef void (Tk_CustomOptionRestoreProc) _ANSI_ARGS_((ClientData clientData, - Tk_Window tkwin, char *internalPtr, char *saveInternalPtr)); -typedef void (Tk_CustomOptionFreeProc) _ANSI_ARGS_((ClientData clientData, - Tk_Window tkwin, char *internalPtr)); + int offset, char *saveInternalPtr, int flags); +typedef Tcl_Obj *(Tk_CustomOptionGetProc) (ClientData clientData, + Tk_Window tkwin, char *widgRec, int offset); +typedef void (Tk_CustomOptionRestoreProc) (ClientData clientData, + Tk_Window tkwin, char *internalPtr, char *saveInternalPtr); +typedef void (Tk_CustomOptionFreeProc) (ClientData clientData, Tk_Window tkwin, + char *internalPtr); typedef struct Tk_ObjCustomOption { const char *name; /* Name of the custom option. */ @@ -318,12 +334,10 @@ typedef struct Tk_SavedOptions { #ifndef __NO_OLD_CONFIG -typedef int (Tk_OptionParseProc) _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, Tk_Window tkwin, CONST84 char *value, char *widgRec, - int offset)); -typedef char *(Tk_OptionPrintProc) _ANSI_ARGS_((ClientData clientData, - Tk_Window tkwin, char *widgRec, int offset, - Tcl_FreeProc **freeProcPtr)); +typedef int (Tk_OptionParseProc) (ClientData clientData, Tcl_Interp *interp, + Tk_Window tkwin, CONST84 char *value, char *widgRec, int offset); +typedef CONST86 char *(Tk_OptionPrintProc) (ClientData clientData, + Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); typedef struct Tk_CustomOption { Tk_OptionParseProc *parseProc; @@ -348,7 +362,7 @@ typedef struct Tk_ConfigSpec { int type; /* Type of option, such as TK_CONFIG_COLOR; * see definitions below. Last option in table * must have type TK_CONFIG_END. */ - char *argvName; /* Switch used to specify option in argv. NULL + CONST86 char *argvName; /* Switch used to specify option in argv. NULL * means this spec is part of a group. */ Tk_Uid dbName; /* Name for option in option database. */ Tk_Uid dbClass; /* Class for option in database. */ @@ -360,7 +374,8 @@ typedef struct Tk_ConfigSpec { int specFlags; /* Any combination of the values defined * below; other bits are used internally by * tkConfig.c. */ - Tk_CustomOption *customPtr; /* If type is TK_CONFIG_CUSTOM then this is a + CONST86 Tk_CustomOption *customPtr; + /* If type is TK_CONFIG_CUSTOM then this is a * pointer to info about how to parse and * print the option. Otherwise it is * irrelevant. */ @@ -408,14 +423,14 @@ typedef enum { */ typedef struct { - char *key; /* The key string that flags the option in the + CONST86 char *key; /* The key string that flags the option in the * argv array. */ int type; /* Indicates option type; see below. */ char *src; /* Value to be used in setting dst; usage * depends on type. */ char *dst; /* Address of value to be modified; usage * depends on type. */ - char *help; /* Documentation message describing this + CONST86 char *help; /* Documentation message describing this * option. */ } Tk_ArgvInfo; @@ -554,11 +569,10 @@ typedef struct Tk_FontMetrics { * behavior. */ -typedef Window (Tk_ClassCreateProc) _ANSI_ARGS_((Tk_Window tkwin, - Window parent, ClientData instanceData)); -typedef void (Tk_ClassWorldChangedProc) _ANSI_ARGS_((ClientData instanceData)); -typedef void (Tk_ClassModalProc) _ANSI_ARGS_((Tk_Window tkwin, - XEvent *eventPtr)); +typedef Window (Tk_ClassCreateProc) (Tk_Window tkwin, Window parent, + ClientData instanceData); +typedef void (Tk_ClassWorldChangedProc) (ClientData instanceData); +typedef void (Tk_ClassModalProc) (Tk_Window tkwin, XEvent *eventPtr); typedef struct Tk_ClassProcs { unsigned int size; @@ -599,10 +613,8 @@ typedef struct Tk_ClassProcs { * the geometry manager to carry out certain functions. */ -typedef void (Tk_GeomRequestProc) _ANSI_ARGS_((ClientData clientData, - Tk_Window tkwin)); -typedef void (Tk_GeomLostSlaveProc) _ANSI_ARGS_((ClientData clientData, - Tk_Window tkwin)); +typedef void (Tk_GeomRequestProc) (ClientData clientData, Tk_Window tkwin); +typedef void (Tk_GeomLostSlaveProc) (ClientData clientData, Tk_Window tkwin); typedef struct Tk_GeomMgr { const char *name; /* Name of the geometry manager (command used @@ -664,7 +676,7 @@ typedef struct { * request. */ Display *display; /* Display the event was read from. */ Window event; /* Window on which event was requested. */ - Window root; /* Root window that the event occured on. */ + Window root; /* Root window that the event occurred on. */ Window subwindow; /* Child window. */ Time time; /* Milliseconds. */ int x, y; /* Pointer x, y coordinates in event @@ -801,6 +813,11 @@ typedef struct Tk_FakeWin { int internalBorderBottom; int minReqWidth; int minReqHeight; +#ifdef TK_USE_INPUT_METHODS + int dummy20; +#endif /* TK_USE_INPUT_METHODS */ + char *dummy21; /* geomMgrName */ + Tk_Window dummy22; /* maintainerPtr */ } Tk_FakeWin; /* @@ -843,9 +860,6 @@ typedef struct Tk_FakeWin { * embedded application), and both the containing * and embedded halves are associated with * windows in this particular process. - * TK_DEFER_MODAL: 1 means that this window has deferred a modal - * loop until all of the bindings for the current - * event have been invoked. * TK_WRAPPER: 1 means that this window is the extra wrapper * window created around a toplevel to hold the * menubar under Unix. See tkUnixWm.c for more @@ -882,7 +896,6 @@ typedef struct Tk_FakeWin { #define TK_EMBEDDED 0x100 #define TK_CONTAINER 0x200 #define TK_BOTH_HALVES 0x400 -#define TK_DEFER_MODAL 0x800 #define TK_WRAPPER 0x1000 #define TK_REPARENTED 0x2000 #define TK_ANONYMOUS_WINDOW 0x4000 @@ -906,13 +919,11 @@ typedef enum { } Tk_State; typedef struct Tk_SmoothMethod { - char *name; - int (*coordProc) _ANSI_ARGS_((Tk_Canvas canvas, - double *pointPtr, int numPoints, int numSteps, - XPoint xPoints[], double dblPoints[])); - void (*postscriptProc) _ANSI_ARGS_((Tcl_Interp *interp, - Tk_Canvas canvas, double *coordPtr, - int numPoints, int numSteps)); + CONST86 char *name; + int (*coordProc) (Tk_Canvas canvas, double *pointPtr, int numPoints, + int numSteps, XPoint xPoints[], double dblPoints[]); + void (*postscriptProc) (Tcl_Interp *interp, Tk_Canvas canvas, + double *coordPtr, int numPoints, int numSteps); } Tk_SmoothMethod; /* @@ -981,66 +992,69 @@ typedef struct Tk_Item { */ #ifdef USE_OLD_CANVAS -typedef int Tk_ItemCreateProc _ANSI_ARGS_((Tcl_Interp *interp, - Tk_Canvas canvas, Tk_Item *itemPtr, int argc, - char **argv)); -typedef int Tk_ItemConfigureProc _ANSI_ARGS_((Tcl_Interp *interp, - Tk_Canvas canvas, Tk_Item *itemPtr, int argc, - char **argv, int flags)); -typedef int Tk_ItemCoordProc _ANSI_ARGS_((Tcl_Interp *interp, - Tk_Canvas canvas, Tk_Item *itemPtr, int argc, - char **argv)); +typedef int (Tk_ItemCreateProc)(Tcl_Interp *interp, Tk_Canvas canvas, + Tk_Item *itemPtr, int argc, char **argv); +typedef int (Tk_ItemConfigureProc)(Tcl_Interp *interp, Tk_Canvas canvas, + Tk_Item *itemPtr, int argc, char **argv, int flags); +typedef int (Tk_ItemCoordProc)(Tcl_Interp *interp, Tk_Canvas canvas, + Tk_Item *itemPtr, int argc, char **argv); #else -typedef int Tk_ItemCreateProc _ANSI_ARGS_((Tcl_Interp *interp, - Tk_Canvas canvas, Tk_Item *itemPtr, int argc, - Tcl_Obj *const objv[])); -typedef int Tk_ItemConfigureProc _ANSI_ARGS_((Tcl_Interp *interp, - Tk_Canvas canvas, Tk_Item *itemPtr, int argc, - Tcl_Obj *const objv[], int flags)); -typedef int Tk_ItemCoordProc _ANSI_ARGS_((Tcl_Interp *interp, - Tk_Canvas canvas, Tk_Item *itemPtr, int argc, - Tcl_Obj *const argv[])); -#endif -typedef void Tk_ItemDeleteProc _ANSI_ARGS_((Tk_Canvas canvas, - Tk_Item *itemPtr, Display *display)); -typedef void Tk_ItemDisplayProc _ANSI_ARGS_((Tk_Canvas canvas, - Tk_Item *itemPtr, Display *display, Drawable dst, - int x, int y, int width, int height)); -typedef double Tk_ItemPointProc _ANSI_ARGS_((Tk_Canvas canvas, - Tk_Item *itemPtr, double *pointPtr)); -typedef int Tk_ItemAreaProc _ANSI_ARGS_((Tk_Canvas canvas, - Tk_Item *itemPtr, double *rectPtr)); -typedef int Tk_ItemPostscriptProc _ANSI_ARGS_((Tcl_Interp *interp, - Tk_Canvas canvas, Tk_Item *itemPtr, int prepass)); -typedef void Tk_ItemScaleProc _ANSI_ARGS_((Tk_Canvas canvas, - Tk_Item *itemPtr, double originX, double originY, - double scaleX, double scaleY)); -typedef void Tk_ItemTranslateProc _ANSI_ARGS_((Tk_Canvas canvas, - Tk_Item *itemPtr, double deltaX, double deltaY)); -typedef int Tk_ItemIndexProc _ANSI_ARGS_((Tcl_Interp *interp, - Tk_Canvas canvas, Tk_Item *itemPtr, char *indexString, - int *indexPtr)); -typedef void Tk_ItemCursorProc _ANSI_ARGS_((Tk_Canvas canvas, - Tk_Item *itemPtr, int index)); -typedef int Tk_ItemSelectionProc _ANSI_ARGS_((Tk_Canvas canvas, - Tk_Item *itemPtr, int offset, char *buffer, - int maxBytes)); -typedef void Tk_ItemInsertProc _ANSI_ARGS_((Tk_Canvas canvas, - Tk_Item *itemPtr, int beforeThis, char *string)); -typedef void Tk_ItemDCharsProc _ANSI_ARGS_((Tk_Canvas canvas, - Tk_Item *itemPtr, int first, int last)); +typedef int (Tk_ItemCreateProc)(Tcl_Interp *interp, Tk_Canvas canvas, + Tk_Item *itemPtr, int argc, Tcl_Obj *const objv[]); +typedef int (Tk_ItemConfigureProc)(Tcl_Interp *interp, Tk_Canvas canvas, + Tk_Item *itemPtr, int argc, Tcl_Obj *const objv[], + int flags); +typedef int (Tk_ItemCoordProc)(Tcl_Interp *interp, Tk_Canvas canvas, + Tk_Item *itemPtr, int argc, Tcl_Obj *const argv[]); +#endif /* USE_OLD_CANVAS */ +typedef void (Tk_ItemDeleteProc)(Tk_Canvas canvas, Tk_Item *itemPtr, + Display *display); +typedef void (Tk_ItemDisplayProc)(Tk_Canvas canvas, Tk_Item *itemPtr, + Display *display, Drawable dst, int x, int y, int width, + int height); +typedef double (Tk_ItemPointProc)(Tk_Canvas canvas, Tk_Item *itemPtr, + double *pointPtr); +typedef int (Tk_ItemAreaProc)(Tk_Canvas canvas, Tk_Item *itemPtr, + double *rectPtr); +typedef int (Tk_ItemPostscriptProc)(Tcl_Interp *interp, Tk_Canvas canvas, + Tk_Item *itemPtr, int prepass); +typedef void (Tk_ItemScaleProc)(Tk_Canvas canvas, Tk_Item *itemPtr, + double originX, double originY, double scaleX, + double scaleY); +typedef void (Tk_ItemTranslateProc)(Tk_Canvas canvas, Tk_Item *itemPtr, + double deltaX, double deltaY); +#ifdef USE_OLD_CANVAS +typedef int (Tk_ItemIndexProc)(Tcl_Interp *interp, Tk_Canvas canvas, + Tk_Item *itemPtr, char *indexString, int *indexPtr); +#else +typedef int (Tk_ItemIndexProc)(Tcl_Interp *interp, Tk_Canvas canvas, + Tk_Item *itemPtr, Tcl_Obj *indexString, int *indexPtr); +#endif /* USE_OLD_CANVAS */ +typedef void (Tk_ItemCursorProc)(Tk_Canvas canvas, Tk_Item *itemPtr, + int index); +typedef int (Tk_ItemSelectionProc)(Tk_Canvas canvas, Tk_Item *itemPtr, + int offset, char *buffer, int maxBytes); +#ifdef USE_OLD_CANVAS +typedef void (Tk_ItemInsertProc)(Tk_Canvas canvas, Tk_Item *itemPtr, + int beforeThis, char *string); +#else +typedef void (Tk_ItemInsertProc)(Tk_Canvas canvas, Tk_Item *itemPtr, + int beforeThis, Tcl_Obj *string); +#endif /* USE_OLD_CANVAS */ +typedef void (Tk_ItemDCharsProc)(Tk_Canvas canvas, Tk_Item *itemPtr, + int first, int last); #ifndef __NO_OLD_CONFIG typedef struct Tk_ItemType { - char *name; /* The name of this type of item, such as + CONST86 char *name; /* The name of this type of item, such as * "line". */ int itemSize; /* Total amount of space needed for item's * record. */ Tk_ItemCreateProc *createProc; /* Procedure to create a new item of this * type. */ - Tk_ConfigSpec *configSpecs; /* Pointer to array of configuration specs for + CONST86 Tk_ConfigSpec *configSpecs; /* Pointer to array of configuration specs for * this type. Used for returning configuration * info. */ Tk_ItemConfigureProc *configProc; @@ -1089,7 +1103,14 @@ typedef struct Tk_ItemType { char *reserved4; } Tk_ItemType; -#endif +/* + * Flag (used in the alwaysRedraw field) to say whether an item supports + * point-level manipulation like the line and polygon items. + */ + +#define TK_MOVABLE_POINTS 2 + +#endif /* __NO_OLD_CONFIG */ /* * The following structure provides information about the selection and the @@ -1154,7 +1175,7 @@ typedef struct Tk_TSOffset { } Tk_TSOffset; /* - * Bit fields in Tk_Offset->flags: + * Bit fields in Tk_TSOffset->flags: */ #define TK_OFFSET_INDEX 1 @@ -1175,9 +1196,9 @@ typedef struct Tk_Outline { Tk_Dash dash; /* Dash pattern. */ Tk_Dash activeDash; /* Dash pattern if state is active. */ Tk_Dash disabledDash; /* Dash pattern if state is disabled. */ - VOID *reserved1; /* Reserved for future expansion. */ - VOID *reserved2; - VOID *reserved3; + void *reserved1; /* Reserved for future expansion. */ + void *reserved2; + void *reserved3; Tk_TSOffset tsoffset; /* Stipple offset for outline. */ XColor *color; /* Outline color. */ XColor *activeColor; /* Outline color if state is active. */ @@ -1199,28 +1220,25 @@ typedef struct Tk_Outline { typedef struct Tk_ImageType Tk_ImageType; #ifdef USE_OLD_IMAGE -typedef int (Tk_ImageCreateProc) _ANSI_ARGS_((Tcl_Interp *interp, - char *name, int argc, char **argv, Tk_ImageType *typePtr, - Tk_ImageMaster master, ClientData *masterDataPtr)); +typedef int (Tk_ImageCreateProc) (Tcl_Interp *interp, char *name, int argc, + char **argv, Tk_ImageType *typePtr, Tk_ImageMaster master, + ClientData *masterDataPtr); #else -typedef int (Tk_ImageCreateProc) _ANSI_ARGS_((Tcl_Interp *interp, - char *name, int objc, Tcl_Obj *const objv[], Tk_ImageType *typePtr, - Tk_ImageMaster master, ClientData *masterDataPtr)); -#endif -typedef ClientData (Tk_ImageGetProc) _ANSI_ARGS_((Tk_Window tkwin, - ClientData masterData)); -typedef void (Tk_ImageDisplayProc) _ANSI_ARGS_((ClientData instanceData, - Display *display, Drawable drawable, int imageX, int imageY, - int width, int height, int drawableX, int drawableY)); -typedef void (Tk_ImageFreeProc) _ANSI_ARGS_((ClientData instanceData, - Display *display)); -typedef void (Tk_ImageDeleteProc) _ANSI_ARGS_((ClientData masterData)); -typedef void (Tk_ImageChangedProc) _ANSI_ARGS_((ClientData clientData, - int x, int y, int width, int height, int imageWidth, - int imageHeight)); -typedef int (Tk_ImagePostscriptProc) _ANSI_ARGS_((ClientData clientData, +typedef int (Tk_ImageCreateProc) (Tcl_Interp *interp, CONST86 char *name, int objc, + Tcl_Obj *const objv[], CONST86 Tk_ImageType *typePtr, Tk_ImageMaster master, + ClientData *masterDataPtr); +#endif /* USE_OLD_IMAGE */ +typedef ClientData (Tk_ImageGetProc) (Tk_Window tkwin, ClientData masterData); +typedef void (Tk_ImageDisplayProc) (ClientData instanceData, Display *display, + Drawable drawable, int imageX, int imageY, int width, int height, + int drawableX, int drawableY); +typedef void (Tk_ImageFreeProc) (ClientData instanceData, Display *display); +typedef void (Tk_ImageDeleteProc) (ClientData masterData); +typedef void (Tk_ImageChangedProc) (ClientData clientData, int x, int y, + int width, int height, int imageWidth, int imageHeight); +typedef int (Tk_ImagePostscriptProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, Tk_PostscriptInfo psinfo, - int x, int y, int width, int height, int prepass)); + int x, int y, int width, int height, int prepass); /* * The following structure represents a particular type of image (bitmap, xpm @@ -1231,7 +1249,7 @@ typedef int (Tk_ImagePostscriptProc) _ANSI_ARGS_((ClientData clientData, */ struct Tk_ImageType { - char *name; /* Name of image type. */ + CONST86 char *name; /* Name of image type. */ Tk_ImageCreateProc *createProc; /* Procedure to call to create a new image of * this type. */ @@ -1305,41 +1323,36 @@ typedef struct Tk_PhotoImageBlock { typedef struct Tk_PhotoImageFormat Tk_PhotoImageFormat; #ifdef USE_OLD_IMAGE -typedef int (Tk_ImageFileMatchProc) _ANSI_ARGS_((Tcl_Channel chan, - char *fileName, char *formatString, int *widthPtr, int *heightPtr)); -typedef int (Tk_ImageStringMatchProc) _ANSI_ARGS_((char *string, - char *formatString, int *widthPtr, int *heightPtr)); -typedef int (Tk_ImageFileReadProc) _ANSI_ARGS_((Tcl_Interp *interp, - Tcl_Channel chan, char *fileName, char *formatString, - Tk_PhotoHandle imageHandle, int destX, int destY, - int width, int height, int srcX, int srcY)); -typedef int (Tk_ImageStringReadProc) _ANSI_ARGS_((Tcl_Interp *interp, - char *string, char *formatString, Tk_PhotoHandle imageHandle, - int destX, int destY, int width, int height, int srcX, int srcY)); -typedef int (Tk_ImageFileWriteProc) _ANSI_ARGS_((Tcl_Interp *interp, - char *fileName, char *formatString, Tk_PhotoImageBlock *blockPtr)); -typedef int (Tk_ImageStringWriteProc) _ANSI_ARGS_((Tcl_Interp *interp, - Tcl_DString *dataPtr, char *formatString, - Tk_PhotoImageBlock *blockPtr)); +typedef int (Tk_ImageFileMatchProc) (Tcl_Channel chan, char *fileName, + char *formatString, int *widthPtr, int *heightPtr); +typedef int (Tk_ImageStringMatchProc) (char *string, char *formatString, + int *widthPtr, int *heightPtr); +typedef int (Tk_ImageFileReadProc) (Tcl_Interp *interp, Tcl_Channel chan, + char *fileName, char *formatString, Tk_PhotoHandle imageHandle, + int destX, int destY, int width, int height, int srcX, int srcY); +typedef int (Tk_ImageStringReadProc) (Tcl_Interp *interp, char *string, + char *formatString, Tk_PhotoHandle imageHandle, int destX, int destY, + int width, int height, int srcX, int srcY); +typedef int (Tk_ImageFileWriteProc) (Tcl_Interp *interp, char *fileName, + char *formatString, Tk_PhotoImageBlock *blockPtr); +typedef int (Tk_ImageStringWriteProc) (Tcl_Interp *interp, + Tcl_DString *dataPtr, char *formatString, Tk_PhotoImageBlock *blockPtr); #else -typedef int (Tk_ImageFileMatchProc) _ANSI_ARGS_((Tcl_Channel chan, - const char *fileName, Tcl_Obj *format, int *widthPtr, - int *heightPtr, Tcl_Interp *interp)); -typedef int (Tk_ImageStringMatchProc) _ANSI_ARGS_((Tcl_Obj *dataObj, - Tcl_Obj *format, int *widthPtr, int *heightPtr, - Tcl_Interp *interp)); -typedef int (Tk_ImageFileReadProc) _ANSI_ARGS_((Tcl_Interp *interp, - Tcl_Channel chan, const char *fileName, Tcl_Obj *format, - Tk_PhotoHandle imageHandle, int destX, int destY, - int width, int height, int srcX, int srcY)); -typedef int (Tk_ImageStringReadProc) _ANSI_ARGS_((Tcl_Interp *interp, - Tcl_Obj *dataObj, Tcl_Obj *format, Tk_PhotoHandle imageHandle, - int destX, int destY, int width, int height, int srcX, int srcY)); -typedef int (Tk_ImageFileWriteProc) _ANSI_ARGS_((Tcl_Interp *interp, - const char *fileName, Tcl_Obj *format, Tk_PhotoImageBlock *blockPtr)); -typedef int (Tk_ImageStringWriteProc) _ANSI_ARGS_((Tcl_Interp *interp, - Tcl_Obj *format, Tk_PhotoImageBlock *blockPtr)); -#endif +typedef int (Tk_ImageFileMatchProc) (Tcl_Channel chan, const char *fileName, + Tcl_Obj *format, int *widthPtr, int *heightPtr, Tcl_Interp *interp); +typedef int (Tk_ImageStringMatchProc) (Tcl_Obj *dataObj, Tcl_Obj *format, + int *widthPtr, int *heightPtr, Tcl_Interp *interp); +typedef int (Tk_ImageFileReadProc) (Tcl_Interp *interp, Tcl_Channel chan, + const char *fileName, Tcl_Obj *format, Tk_PhotoHandle imageHandle, + int destX, int destY, int width, int height, int srcX, int srcY); +typedef int (Tk_ImageStringReadProc) (Tcl_Interp *interp, Tcl_Obj *dataObj, + Tcl_Obj *format, Tk_PhotoHandle imageHandle, int destX, int destY, + int width, int height, int srcX, int srcY); +typedef int (Tk_ImageFileWriteProc) (Tcl_Interp *interp, const char *fileName, + Tcl_Obj *format, Tk_PhotoImageBlock *blockPtr); +typedef int (Tk_ImageStringWriteProc) (Tcl_Interp *interp, Tcl_Obj *format, + Tk_PhotoImageBlock *blockPtr); +#endif /* USE_OLD_IMAGE */ /* * The following structure represents a particular file format for storing @@ -1348,7 +1361,7 @@ typedef int (Tk_ImageStringWriteProc) _ANSI_ARGS_((Tcl_Interp *interp, */ struct Tk_PhotoImageFormat { - char *name; /* Name of image file format */ + CONST86 char *name; /* Name of image file format */ Tk_ImageFileMatchProc *fileMatchProc; /* Procedure to call to determine whether an * image file matches this format. */ @@ -1394,41 +1407,41 @@ struct Tk_PhotoImageFormat { * declare widget elements. */ -typedef void (Tk_GetElementSizeProc) _ANSI_ARGS_((ClientData clientData, - char *recordPtr, const Tk_OptionSpec **optionsPtr, Tk_Window tkwin, - int width, int height, int inner, int *widthPtr, int *heightPtr)); -typedef void (Tk_GetElementBoxProc) _ANSI_ARGS_((ClientData clientData, - char *recordPtr, const Tk_OptionSpec **optionsPtr, Tk_Window tkwin, - int x, int y, int width, int height, int inner, int *xPtr, int *yPtr, - int *widthPtr, int *heightPtr)); -typedef int (Tk_GetElementBorderWidthProc) _ANSI_ARGS_((ClientData clientData, - char *recordPtr, const Tk_OptionSpec **optionsPtr, Tk_Window tkwin)); -typedef void (Tk_DrawElementProc) _ANSI_ARGS_((ClientData clientData, - char *recordPtr, const Tk_OptionSpec **optionsPtr, Tk_Window tkwin, - Drawable d, int x, int y, int width, int height, int state)); +typedef void (Tk_GetElementSizeProc) (ClientData clientData, char *recordPtr, + const Tk_OptionSpec **optionsPtr, Tk_Window tkwin, int width, + int height, int inner, int *widthPtr, int *heightPtr); +typedef void (Tk_GetElementBoxProc) (ClientData clientData, char *recordPtr, + const Tk_OptionSpec **optionsPtr, Tk_Window tkwin, int x, int y, + int width, int height, int inner, int *xPtr, int *yPtr, int *widthPtr, + int *heightPtr); +typedef int (Tk_GetElementBorderWidthProc) (ClientData clientData, + char *recordPtr, const Tk_OptionSpec **optionsPtr, Tk_Window tkwin); +typedef void (Tk_DrawElementProc) (ClientData clientData, char *recordPtr, + const Tk_OptionSpec **optionsPtr, Tk_Window tkwin, Drawable d, int x, + int y, int width, int height, int state); typedef struct Tk_ElementOptionSpec { - char *name; /* Name of the required option. */ - Tk_OptionType type; /* Accepted option type. TK_OPTION_END means - * any. */ + char *name; /* Name of the required option. */ + Tk_OptionType type; /* Accepted option type. TK_OPTION_END means + * any. */ } Tk_ElementOptionSpec; typedef struct Tk_ElementSpec { - int version; /* Version of the style support. */ - char *name; /* Name of element. */ + int version; /* Version of the style support. */ + char *name; /* Name of element. */ Tk_ElementOptionSpec *options; - /* List of required options. Last one's name - * must be NULL. */ + /* List of required options. Last one's name + * must be NULL. */ Tk_GetElementSizeProc *getSize; - /* Compute the external (resp. internal) size - * of the element from its desired internal - * (resp. external) size. */ + /* Compute the external (resp. internal) size + * of the element from its desired internal + * (resp. external) size. */ Tk_GetElementBoxProc *getBox; - /* Compute the inscribed or bounding boxes - * within a given area. */ + /* Compute the inscribed or bounding boxes + * within a given area. */ Tk_GetElementBorderWidthProc *getBorderWidth; - /* Return the element's internal border width. - * Mostly useful for widgets. */ + /* Return the element's internal border width. + * Mostly useful for widgets. */ Tk_DrawElementProc *draw; /* Draw the element in the given bounding * box. */ } Tk_ElementSpec; @@ -1487,13 +1500,17 @@ typedef struct Tk_ElementSpec { #define Tk_Release Tcl_Release /* Removed Tk_Main, use macro instead */ -#define Tk_Main(argc, argv, proc) \ - Tk_MainEx(argc, argv, proc, Tcl_CreateInterp()) - -const char * Tk_InitStubs _ANSI_ARGS_((Tcl_Interp *interp, - const char *version, int exact)); -EXTERN const char * Tk_PkgInitStubsCheck _ANSI_ARGS_((Tcl_Interp *interp, - const char *version, int exact)); +#if defined(_WIN32) || defined(__CYGWIN__) +#define Tk_Main(argc, argv, proc) Tk_MainEx(argc, argv, proc, \ + (Tcl_FindExecutable(0), (Tcl_CreateInterp)())) +#else +#define Tk_Main(argc, argv, proc) Tk_MainEx(argc, argv, proc, \ + (Tcl_FindExecutable(argv[0]), (Tcl_CreateInterp)())) +#endif +const char * Tk_InitStubs(Tcl_Interp *interp, const char *version, + int exact); +EXTERN const char * Tk_PkgInitStubsCheck(Tcl_Interp *interp, + const char *version, int exact); #ifndef USE_TK_STUBS #define Tk_InitStubs(interp, version, exact) \ @@ -1510,21 +1527,17 @@ EXTERN const char * Tk_PkgInitStubsCheck _ANSI_ARGS_((Tcl_Interp *interp, *---------------------------------------------------------------------- */ -typedef int (Tk_ErrorProc) _ANSI_ARGS_((ClientData clientData, - XErrorEvent *errEventPtr)); -typedef void (Tk_EventProc) _ANSI_ARGS_((ClientData clientData, - XEvent *eventPtr)); -typedef int (Tk_GenericProc) _ANSI_ARGS_((ClientData clientData, - XEvent *eventPtr)); -typedef int (Tk_ClientMessageProc) _ANSI_ARGS_((Tk_Window tkwin, - XEvent *eventPtr)); -typedef int (Tk_GetSelProc) _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, char *portion)); -typedef void (Tk_LostSelProc) _ANSI_ARGS_((ClientData clientData)); -typedef Tk_RestrictAction (Tk_RestrictProc) _ANSI_ARGS_(( - ClientData clientData, XEvent *eventPtr)); -typedef int (Tk_SelectionProc) _ANSI_ARGS_((ClientData clientData, - int offset, char *buffer, int maxBytes)); +typedef int (Tk_ErrorProc) (ClientData clientData, XErrorEvent *errEventPtr); +typedef void (Tk_EventProc) (ClientData clientData, XEvent *eventPtr); +typedef int (Tk_GenericProc) (ClientData clientData, XEvent *eventPtr); +typedef int (Tk_ClientMessageProc) (Tk_Window tkwin, XEvent *eventPtr); +typedef int (Tk_GetSelProc) (ClientData clientData, Tcl_Interp *interp, + CONST86 char *portion); +typedef void (Tk_LostSelProc) (ClientData clientData); +typedef Tk_RestrictAction (Tk_RestrictProc) (ClientData clientData, + XEvent *eventPtr); +typedef int (Tk_SelectionProc) (ClientData clientData, int offset, + char *buffer, int maxBytes); /* *---------------------------------------------------------------------- diff --git a/generic/tk3d.c b/generic/tk3d.c index 4697415..bcc5673 100644 --- a/generic/tk3d.c +++ b/generic/tk3d.c @@ -19,7 +19,7 @@ * by Tk_GetReliefFromObj. */ -static CONST char *reliefStrings[] = { +static const char *const reliefStrings[] = { "flat", "groove", "raised", "ridge", "solid", "sunken", NULL }; @@ -30,6 +30,7 @@ static CONST char *reliefStrings[] = { static void BorderInit(TkDisplay *dispPtr); static void DupBorderObjProc(Tcl_Obj *srcObjPtr, Tcl_Obj *dupObjPtr); +static void FreeBorderObj(Tcl_Obj *objPtr); static void FreeBorderObjProc(Tcl_Obj *objPtr); static int Intersect(XPoint *a1Ptr, XPoint *a2Ptr, XPoint *b1Ptr, XPoint *b2Ptr, XPoint *iPtr); @@ -45,7 +46,7 @@ static void ShiftLine(XPoint *p1Ptr, XPoint *p2Ptr, * is set. */ -Tcl_ObjType tkBorderObjType = { +const Tcl_ObjType tkBorderObjType = { "border", /* name */ FreeBorderObjProc, /* freeIntRepProc */ DupBorderObjProc, /* dupIntRepProc */ @@ -71,8 +72,8 @@ Tcl_ObjType tkBorderObjType = { * Side effects: * The border is added to an internal database with a reference count. * For each call to this function, there should eventually be a call to - * FreeBorderObjProc so that the database is cleaned up when borders - * aren't in use anymore. + * FreeBorderObj so that the database is cleaned up when borders aren't + * in use anymore. * *---------------------------------------------------------------------- */ @@ -89,7 +90,7 @@ Tk_Alloc3DBorderFromObj( if (objPtr->typePtr != &tkBorderObjType) { InitBorderObj(objPtr); } - borderPtr = (TkBorder *) objPtr->internalRep.twoPtrValue.ptr1; + borderPtr = objPtr->internalRep.twoPtrValue.ptr1; /* * If the object currently points to a TkBorder, see if it's the one we @@ -103,7 +104,7 @@ Tk_Alloc3DBorderFromObj( * longer in use. Clear the reference. */ - FreeBorderObjProc(objPtr); + FreeBorderObj(objPtr); borderPtr = NULL; } else if ((Tk_Screen(tkwin) == borderPtr->screen) && (Tk_Colormap(tkwin) == borderPtr->colormap)) { @@ -116,9 +117,7 @@ Tk_Alloc3DBorderFromObj( * The object didn't point to the border that we wanted. Search the list * of borders with the same name to see if one of the others is the right * one. - */ - - /* + * * If the cached value is NULL, either the object type was not a color * going in, or the object is a color type but had previously been freed. * @@ -128,16 +127,16 @@ Tk_Alloc3DBorderFromObj( */ if (borderPtr != NULL) { - TkBorder *firstBorderPtr = - (TkBorder *) Tcl_GetHashValue(borderPtr->hashPtr); - FreeBorderObjProc(objPtr); + TkBorder *firstBorderPtr = Tcl_GetHashValue(borderPtr->hashPtr); + + FreeBorderObj(objPtr); for (borderPtr = firstBorderPtr ; borderPtr != NULL; borderPtr = borderPtr->nextPtr) { if ((Tk_Screen(tkwin) == borderPtr->screen) - && (Tk_Colormap(tkwin) == borderPtr->colormap)) { + && (Tk_Colormap(tkwin) == borderPtr->colormap)) { borderPtr->resourceRefCount++; borderPtr->objRefCount++; - objPtr->internalRep.twoPtrValue.ptr1 = (void *) borderPtr; + objPtr->internalRep.twoPtrValue.ptr1 = borderPtr; return (Tk_3DBorder) borderPtr; } } @@ -149,7 +148,7 @@ Tk_Alloc3DBorderFromObj( borderPtr = (TkBorder *) Tk_Get3DBorder(interp, tkwin, Tcl_GetString(objPtr)); - objPtr->internalRep.twoPtrValue.ptr1 = (void *) borderPtr; + objPtr->internalRep.twoPtrValue.ptr1 = borderPtr; if (borderPtr != NULL) { borderPtr->objRefCount++; } @@ -201,7 +200,7 @@ Tk_Get3DBorder( hashPtr = Tcl_CreateHashEntry(&dispPtr->borderTable, colorName, &isNew); if (!isNew) { - existingBorderPtr = (TkBorder *) Tcl_GetHashValue(hashPtr); + existingBorderPtr = Tcl_GetHashValue(hashPtr); for (borderPtr = existingBorderPtr; borderPtr != NULL; borderPtr = borderPtr->nextPtr) { if ((Tk_Screen(tkwin) == borderPtr->screen) @@ -318,7 +317,7 @@ Tk_Draw3DRectangle( *-------------------------------------------------------------- */ -CONST char * +const char * Tk_NameOf3DBorder( Tk_3DBorder border) /* Token for border. */ { @@ -426,7 +425,7 @@ Tk_Free3DBorder( return; } - prevPtr = (TkBorder *) Tcl_GetHashValue(borderPtr->hashPtr); + prevPtr = Tcl_GetHashValue(borderPtr->hashPtr); TkpFreeBorder(borderPtr); if (borderPtr->bgColorPtr != NULL) { Tk_FreeColor(borderPtr->bgColorPtr); @@ -462,7 +461,7 @@ Tk_Free3DBorder( prevPtr->nextPtr = borderPtr->nextPtr; } if (borderPtr->objRefCount == 0) { - ckfree((char *) borderPtr); + ckfree(borderPtr); } } @@ -494,13 +493,13 @@ Tk_Free3DBorderFromObj( Tcl_Obj *objPtr) /* The Tcl_Obj * to be freed. */ { Tk_Free3DBorder(Tk_Get3DBorderFromObj(tkwin, objPtr)); - FreeBorderObjProc(objPtr); + FreeBorderObj(objPtr); } /* *--------------------------------------------------------------------------- * - * FreeBorderObjProc -- + * FreeBorderObjProc, FreeBorderObj -- * * This proc is called to release an object reference to a border. Called * when the object's internal rep is released or when the cached @@ -520,13 +519,21 @@ static void FreeBorderObjProc( Tcl_Obj *objPtr) /* The object we are releasing. */ { - TkBorder *borderPtr = (TkBorder *) objPtr->internalRep.twoPtrValue.ptr1; + FreeBorderObj(objPtr); + objPtr->typePtr = NULL; +} + +static void +FreeBorderObj( + Tcl_Obj *objPtr) /* The object we are releasing. */ +{ + TkBorder *borderPtr = objPtr->internalRep.twoPtrValue.ptr1; if (borderPtr != NULL) { borderPtr->objRefCount--; if ((borderPtr->objRefCount == 0) && (borderPtr->resourceRefCount == 0)) { - ckfree((char *) borderPtr); + ckfree(borderPtr); } objPtr->internalRep.twoPtrValue.ptr1 = NULL; } @@ -555,10 +562,10 @@ DupBorderObjProc( Tcl_Obj *srcObjPtr, /* The object we are copying from. */ Tcl_Obj *dupObjPtr) /* The object we are copying to. */ { - TkBorder *borderPtr = (TkBorder *) srcObjPtr->internalRep.twoPtrValue.ptr1; + TkBorder *borderPtr = srcObjPtr->internalRep.twoPtrValue.ptr1; dupObjPtr->typePtr = srcObjPtr->typePtr; - dupObjPtr->internalRep.twoPtrValue.ptr1 = (void *) borderPtr; + dupObjPtr->internalRep.twoPtrValue.ptr1 = borderPtr; if (borderPtr != NULL) { borderPtr->objRefCount++; @@ -617,8 +624,8 @@ Tk_GetReliefFromObj( * from. */ int *resultPtr) /* Where to place the answer. */ { - return Tcl_GetIndexFromObj(interp, objPtr, reliefStrings, "relief", 0, - resultPtr); + return Tcl_GetIndexFromObjStruct(interp, objPtr, reliefStrings, + sizeof(char *), "relief", 0, resultPtr); } /* @@ -643,7 +650,7 @@ Tk_GetReliefFromObj( int Tk_GetRelief( Tcl_Interp *interp, /* For error messages. */ - CONST char *name, /* Name of a relief type. */ + const char *name, /* Name of a relief type. */ int *reliefPtr) /* Where to store converted relief. */ { char c; @@ -655,22 +662,21 @@ Tk_GetRelief( *reliefPtr = TK_RELIEF_FLAT; } else if ((c == 'g') && (strncmp(name, "groove", length) == 0) && (length >= 2)) { - *reliefPtr = TK_RELIEF_GROOVE; + *reliefPtr = TK_RELIEF_GROOVE; } else if ((c == 'r') && (strncmp(name, "raised", length) == 0) && (length >= 2)) { *reliefPtr = TK_RELIEF_RAISED; } else if ((c == 'r') && (strncmp(name, "ridge", length) == 0)) { - *reliefPtr = TK_RELIEF_RIDGE; + *reliefPtr = TK_RELIEF_RIDGE; } else if ((c == 's') && (strncmp(name, "solid", length) == 0)) { *reliefPtr = TK_RELIEF_SOLID; } else if ((c == 's') && (strncmp(name, "sunken", length) == 0)) { *reliefPtr = TK_RELIEF_SUNKEN; } else { - char buf[200]; - - sprintf(buf, "bad relief type \"%.50s\": must be %s", - name, "flat, groove, raised, ridge, solid, or sunken"); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_SetObjResult(interp, + Tcl_ObjPrintf("bad relief \"%.50s\": must be %s", + name, "flat, groove, raised, ridge, solid, or sunken")); + Tcl_SetErrorCode(interp, "TK", "VALUE", "RELIEF", NULL); return TCL_ERROR; } return TCL_OK; @@ -692,7 +698,7 @@ Tk_GetRelief( *-------------------------------------------------------------- */ -CONST char * +const char * Tk_NameOfRelief( int relief) /* One of TK_RELIEF_FLAT, TK_RELIEF_RAISED, or * TK_RELIEF_SUNKEN. */ @@ -768,9 +774,8 @@ Tk_Draw3DPolygon( */ if ((leftRelief == TK_RELIEF_GROOVE) || (leftRelief == TK_RELIEF_RIDGE)) { - int halfWidth; + int halfWidth = borderWidth/2; - halfWidth = borderWidth/2; Tk_Draw3DPolygon(tkwin, drawable, border, pointPtr, numPoints, halfWidth, (leftRelief == TK_RELIEF_GROOVE) ? TK_RELIEF_RAISED : TK_RELIEF_SUNKEN); @@ -980,8 +985,8 @@ Tk_Fill3DRectangle( if ((width > doubleBorder) && (height > doubleBorder)) { XFillRectangle(Tk_Display(tkwin), drawable, borderPtr->bgGC, x + borderWidth, y + borderWidth, - (unsigned int) (width - doubleBorder), - (unsigned int) (height - doubleBorder)); + (unsigned) (width - doubleBorder), + (unsigned) (height - doubleBorder)); } if (borderWidth) { Tk_Draw3DRectangle(tkwin, drawable, border, x, y, width, @@ -1083,19 +1088,18 @@ ShiftLine( XPoint *p3Ptr) /* Store coords of point on new line here. */ { int dx, dy, dxNeg, dyNeg; - - /* - * The table below is used for a quick approximation in computing the new - * point. An index into the table is 128 times the slope of the original - * line (the slope must always be between 0 and 1). The value of the table - * entry is 128 times the amount to displace the new line in y for each - * unit of perpendicular distance. In other words, the table maps from the - * tangent of an angle to the inverse of its cosine. If the slope of the - * original line is greater than 1, then the displacement is done in x - * rather than in y. - */ - - static int shiftTable[129]; + static int shiftTable[129]; /* Used for a quick approximation in computing + * the new point. An index into the table is + * 128 times the slope of the original line + * (the slope must always be between 0 and 1). + * The value of the table entry is 128 times + * the amount to displace the new line in y + * for each unit of perpendicular distance. In + * other words, the table maps from the + * tangent of an angle to the inverse of its + * cosine. If the slope of the original line + * is greater than 1, then the displacement is + * done in x rather than in y. */ /* * Initialize the table if this is the first time it is used. @@ -1249,7 +1253,7 @@ Tk_Get3DBorderFromObj( * cached in the internal representation of the Tcl_Obj. Check it out... */ - borderPtr = (TkBorder *) objPtr->internalRep.twoPtrValue.ptr1; + borderPtr = objPtr->internalRep.twoPtrValue.ptr1; if ((borderPtr != NULL) && (borderPtr->resourceRefCount > 0) && (Tk_Screen(tkwin) == borderPtr->screen) @@ -1277,12 +1281,12 @@ Tk_Get3DBorderFromObj( if (hashPtr == NULL) { goto error; } - for (borderPtr = (TkBorder *) Tcl_GetHashValue(hashPtr); - (borderPtr != NULL); borderPtr = borderPtr->nextPtr) { + for (borderPtr = Tcl_GetHashValue(hashPtr); borderPtr != NULL; + borderPtr = borderPtr->nextPtr) { if ((Tk_Screen(tkwin) == borderPtr->screen) && (Tk_Colormap(tkwin) == borderPtr->colormap)) { - FreeBorderObjProc(objPtr); - objPtr->internalRep.twoPtrValue.ptr1 = (void *) borderPtr; + FreeBorderObj(objPtr); + objPtr->internalRep.twoPtrValue.ptr1 = borderPtr; borderPtr->objRefCount++; return (Tk_3DBorder) borderPtr; } @@ -1329,7 +1333,7 @@ InitBorderObj( Tcl_GetString(objPtr); typePtr = objPtr->typePtr; if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) { - (*typePtr->freeIntRepProc)(objPtr); + typePtr->freeIntRepProc(objPtr); } objPtr->typePtr = &tkBorderObjType; objPtr->internalRep.twoPtrValue.ptr1 = NULL; @@ -1358,22 +1362,23 @@ Tcl_Obj * TkDebugBorder( Tk_Window tkwin, /* The window in which the border will be used * (not currently used). */ - char *name) /* Name of the desired color. */ + const char *name) /* Name of the desired color. */ { - TkBorder *borderPtr; Tcl_HashEntry *hashPtr; - Tcl_Obj *resultPtr, *objPtr; + Tcl_Obj *resultPtr; TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; resultPtr = Tcl_NewObj(); hashPtr = Tcl_FindHashEntry(&dispPtr->borderTable, name); if (hashPtr != NULL) { - borderPtr = (TkBorder *) Tcl_GetHashValue(hashPtr); + TkBorder *borderPtr = Tcl_GetHashValue(hashPtr); + if (borderPtr == NULL) { Tcl_Panic("TkDebugBorder found empty hash table entry"); } for ( ; (borderPtr != NULL); borderPtr = borderPtr->nextPtr) { - objPtr = Tcl_NewObj(); + Tcl_Obj *objPtr = Tcl_NewObj(); + Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewIntObj(borderPtr->resourceRefCount)); Tcl_ListObjAppendElement(NULL, objPtr, diff --git a/generic/tk3d.h b/generic/tk3d.h index 30a35c5..ec7f7c7 100644 --- a/generic/tk3d.h +++ b/generic/tk3d.h @@ -12,12 +12,7 @@ #ifndef _TK3D #define _TK3D -#include <tkInt.h> - -#ifdef BUILD_tk -# undef TCL_STORAGE_CLASS -# define TCL_STORAGE_CLASS DLLEXPORT -#endif +#include "tkInt.h" /* * One of the following data structures is allocated for each 3-D border @@ -40,9 +35,8 @@ typedef struct TkBorder { * no longer valid and it isn't present in * borderTable: it is being kept around only * because there are objects referring to it. - * The structure is freed when - * resourceRefCount and objRefCount are both - * 0. */ + * The structure is freed when objRefCount and + * resourceRefCount are both 0. */ int objRefCount; /* The number of Tcl objects that reference * this structure. */ XColor *bgColorPtr; /* Background color (intensity between @@ -88,7 +82,4 @@ MODULE_SCOPE TkBorder *TkpGetBorder(void); MODULE_SCOPE void TkpGetShadows(TkBorder *borderPtr, Tk_Window tkwin); MODULE_SCOPE void TkpFreeBorder(TkBorder *borderPtr); -# undef TCL_STORAGE_CLASS -# define TCL_STORAGE_CLASS DLLIMPORT - #endif /* _TK3D */ diff --git a/generic/tkArgv.c b/generic/tkArgv.c index a338e45..6c2c5c5 100644 --- a/generic/tkArgv.c +++ b/generic/tkArgv.c @@ -18,7 +18,7 @@ * every application. */ -static Tk_ArgvInfo defaultTable[] = { +static const Tk_ArgvInfo defaultTable[] = { {"-help", TK_ARGV_HELP, NULL, NULL, "Print summary of command-line options and abort"}, {NULL, TK_ARGV_END, NULL, NULL, NULL} @@ -28,7 +28,7 @@ static Tk_ArgvInfo defaultTable[] = { * Forward declarations for functions defined in this file: */ -static void PrintUsage(Tcl_Interp *interp, Tk_ArgvInfo *argTable, +static void PrintUsage(Tcl_Interp *interp, const Tk_ArgvInfo *argTable, int flags); /* @@ -61,17 +61,17 @@ Tk_ParseArgv( * means ignore Tk option specs. */ int *argcPtr, /* Number of arguments in argv. Modified to * hold # args left in argv at end. */ - CONST char **argv, /* Array of arguments. Modified to hold those + const char **argv, /* Array of arguments. Modified to hold those * that couldn't be processed here. */ - Tk_ArgvInfo *argTable, /* Array of option descriptions */ + const Tk_ArgvInfo *argTable, /* Array of option descriptions */ int flags) /* Or'ed combination of various flag bits, * such as TK_ARGV_NO_DEFAULTS. */ { - register Tk_ArgvInfo *infoPtr; + register const Tk_ArgvInfo *infoPtr; /* Pointer to the current entry in the table * of argument descriptions. */ - Tk_ArgvInfo *matchPtr; /* Descriptor that matches current argument. */ - CONST char *curArg; /* Current argument */ + const Tk_ArgvInfo *matchPtr;/* Descriptor that matches current argument. */ + const char *curArg; /* Current argument */ register char c; /* Second character of current arg (used for * quick check for matching; use 2nd char. * because first char. will almost always be @@ -83,6 +83,7 @@ Tk_ParseArgv( * than srcIndex). */ int argc; /* # arguments in argv still to process. */ size_t length; /* Number of characters in current argument. */ + char *endPtr; /* Used for identifying junk in arguments. */ int i; if (flags & TK_ARGV_DONT_SKIP_FIRST_ARG) { @@ -139,8 +140,10 @@ Tk_ParseArgv( continue; } if (matchPtr != NULL) { - Tcl_AppendResult(interp, "ambiguous option \"", curArg, - "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "ambiguous option \"%s\"", curArg)); + Tcl_SetErrorCode(interp, "TK", "ARG", "AMBIGUOUS", curArg, + NULL); return TCL_ERROR; } matchPtr = infoPtr; @@ -153,8 +156,10 @@ Tk_ParseArgv( */ if (flags & TK_ARGV_NO_LEFTOVERS) { - Tcl_AppendResult(interp, "unrecognized argument \"", - curArg, "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "unrecognized argument \"%s\"", curArg)); + Tcl_SetErrorCode(interp, "TK", "ARG", "UNRECOGNIZED", curArg, + NULL); return TCL_ERROR; } argv[dstIndex] = curArg; @@ -175,25 +180,23 @@ Tk_ParseArgv( case TK_ARGV_INT: if (argc == 0) { goto missingArg; - } else { - char *endPtr; - - *((int *) infoPtr->dst) = strtol(argv[srcIndex], &endPtr, 0); - if ((endPtr == argv[srcIndex]) || (*endPtr != 0)) { - Tcl_AppendResult(interp,"expected integer argument for \"", - infoPtr->key, "\" but got \"", argv[srcIndex], - "\"", NULL); - return TCL_ERROR; - } - srcIndex++; - argc--; } + *((int *) infoPtr->dst) = strtol(argv[srcIndex], &endPtr, 0); + if ((endPtr == argv[srcIndex]) || (*endPtr != 0)) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "expected %s argument for \"%s\" but got \"%s\"", + "integer", infoPtr->key, argv[srcIndex])); + Tcl_SetErrorCode(interp, "TK", "ARG", "INTEGER", curArg,NULL); + return TCL_ERROR; + } + srcIndex++; + argc--; break; case TK_ARGV_STRING: if (argc == 0) { goto missingArg; } - *((CONST char **)infoPtr->dst) = argv[srcIndex]; + *((const char **) infoPtr->dst) = argv[srcIndex]; srcIndex++; argc--; break; @@ -201,7 +204,7 @@ Tk_ParseArgv( if (argc == 0) { goto missingArg; } - *((Tk_Uid *)infoPtr->dst) = Tk_GetUid(argv[srcIndex]); + *((Tk_Uid *) infoPtr->dst) = Tk_GetUid(argv[srcIndex]); srcIndex++; argc--; break; @@ -211,37 +214,35 @@ Tk_ParseArgv( case TK_ARGV_FLOAT: if (argc == 0) { goto missingArg; - } else { - char *endPtr; - - *((double *) infoPtr->dst) = strtod(argv[srcIndex], &endPtr); - if ((endPtr == argv[srcIndex]) || (*endPtr != 0)) { - Tcl_AppendResult(interp, "expected floating-point ", - "argument for \"", infoPtr->key, "\" but got \"", - argv[srcIndex], "\"", NULL); - return TCL_ERROR; - } - srcIndex++; - argc--; } + *((double *) infoPtr->dst) = strtod(argv[srcIndex], &endPtr); + if ((endPtr == argv[srcIndex]) || (*endPtr != 0)) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "expected %s argument for \"%s\" but got \"%s\"", + "floating-point", infoPtr->key, argv[srcIndex])); + Tcl_SetErrorCode(interp, "TK", "ARG", "FLOAT", curArg, NULL); + return TCL_ERROR; + } + srcIndex++; + argc--; break; case TK_ARGV_FUNC: { - typedef int (ArgvFunc)(char *, char *, CONST char *); + typedef int (ArgvFunc)(char *, const char *, const char *); ArgvFunc *handlerProc = (ArgvFunc *) infoPtr->src; - if ((*handlerProc)(infoPtr->dst, infoPtr->key, argv[srcIndex])) { + if (handlerProc(infoPtr->dst, infoPtr->key, argv[srcIndex])) { srcIndex++; argc--; } break; } case TK_ARGV_GENFUNC: { - typedef int (ArgvGenFunc)(char *, Tcl_Interp *, char *, int, - CONST char **); + typedef int (ArgvGenFunc)(char *, Tcl_Interp *, const char *, int, + const char **); ArgvGenFunc *handlerProc = (ArgvGenFunc *) infoPtr->src; - argc = (*handlerProc)(infoPtr->dst, interp, infoPtr->key, - argc, argv+srcIndex); + argc = handlerProc(infoPtr->dst, interp, infoPtr->key, argc, + argv+srcIndex); if (argc < 0) { return TCL_ERROR; } @@ -249,6 +250,7 @@ Tk_ParseArgv( } case TK_ARGV_HELP: PrintUsage(interp, argTable, flags); + Tcl_SetErrorCode(interp, "TK", "ARG", "HELP", NULL); return TCL_ERROR; case TK_ARGV_CONST_OPTION: Tk_AddOption(tkwin, infoPtr->dst, infoPtr->src, @@ -265,8 +267,11 @@ Tk_ParseArgv( break; case TK_ARGV_OPTION_NAME_VALUE: if (argc < 2) { - Tcl_AppendResult(interp, "\"", curArg, - "\" option requires two following arguments", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "\"%s\" option requires two following arguments", + curArg)); + Tcl_SetErrorCode(interp, "TK", "ARG", "NAME_VALUE", curArg, + NULL); return TCL_ERROR; } Tk_AddOption(tkwin, argv[srcIndex], argv[srcIndex+1], @@ -274,14 +279,12 @@ Tk_ParseArgv( srcIndex += 2; argc -= 2; break; - default: { - char buf[64 + TCL_INTEGER_SPACE]; - - sprintf(buf, "bad argument type %d in Tk_ArgvInfo", infoPtr->type); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + default: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad argument type %d in Tk_ArgvInfo", infoPtr->type)); + Tcl_SetErrorCode(interp, "TK", "API_ABUSE", NULL); return TCL_ERROR; } - } } /* @@ -301,8 +304,9 @@ Tk_ParseArgv( return TCL_OK; missingArg: - Tcl_AppendResult(interp, "\"", curArg, - "\" option requires an additional argument", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "\"%s\" option requires an additional argument", curArg)); + Tcl_SetErrorCode(interp, "TK", "ARG", "MISSING", curArg, NULL); return TCL_ERROR; } @@ -328,15 +332,15 @@ static void PrintUsage( Tcl_Interp *interp, /* Place information in this interp's result * area. */ - Tk_ArgvInfo *argTable, /* Array of command-specific argument + const Tk_ArgvInfo *argTable,/* Array of command-specific argument * descriptions. */ int flags) /* If the TK_ARGV_NO_DEFAULTS bit is set in * this word, then don't generate information * for default options. */ { - register Tk_ArgvInfo *infoPtr; + register const Tk_ArgvInfo *infoPtr; size_t width, i, numSpaces; - char tmp[TCL_DOUBLE_SPACE]; + Tcl_Obj *message; /* * First, compute the width of the widest option key, so that we can make @@ -348,6 +352,7 @@ PrintUsage( for (infoPtr = i ? defaultTable : argTable; infoPtr->type != TK_ARGV_END; infoPtr++) { size_t length; + if (infoPtr->key == NULL) { continue; } @@ -358,35 +363,35 @@ PrintUsage( } } - Tcl_AppendResult(interp, "Command-specific options:", NULL); + message = Tcl_NewStringObj("Command-specific options:", -1); for (i = 0; ; i++) { for (infoPtr = i ? defaultTable : argTable; infoPtr->type != TK_ARGV_END; infoPtr++) { if ((infoPtr->type == TK_ARGV_HELP) && (infoPtr->key == NULL)) { - Tcl_AppendResult(interp, "\n", infoPtr->help, NULL); + Tcl_AppendPrintfToObj(message, "\n%s", infoPtr->help); continue; } - Tcl_AppendResult(interp, "\n ", infoPtr->key, ":", NULL); + Tcl_AppendPrintfToObj(message, "\n %s:", infoPtr->key); numSpaces = width + 1 - strlen(infoPtr->key); while (numSpaces-- > 0) { - Tcl_AppendResult(interp, " ", NULL); + Tcl_AppendToObj(message, " ", 1); } - Tcl_AppendResult(interp, infoPtr->help, NULL); + Tcl_AppendToObj(message, infoPtr->help, -1); switch (infoPtr->type) { case TK_ARGV_INT: - sprintf(tmp, "%d", *((int *) infoPtr->dst)); - Tcl_AppendResult(interp, "\n\t\tDefault value: ", tmp, NULL); + Tcl_AppendPrintfToObj(message, "\n\t\tDefault value: %d", + *((int *) infoPtr->dst)); break; case TK_ARGV_FLOAT: - Tcl_PrintDouble(NULL, *((double *) infoPtr->dst), tmp); - Tcl_AppendResult(interp, "\n\t\tDefault value: ", tmp, NULL); + Tcl_AppendPrintfToObj(message, "\n\t\tDefault value: %f", + *((double *) infoPtr->dst)); break; case TK_ARGV_STRING: { char *string = *((char **) infoPtr->dst); if (string != NULL) { - Tcl_AppendResult(interp, "\n\t\tDefault value: \"", string, - "\"", NULL); + Tcl_AppendPrintfToObj(message, + "\n\t\tDefault value: \"%s\"", string); } break; } @@ -398,8 +403,9 @@ PrintUsage( if ((flags & TK_ARGV_NO_DEFAULTS) || (i > 0)) { break; } - Tcl_AppendResult(interp, "\nGeneric options for all commands:", NULL); + Tcl_AppendToObj(message, "\nGeneric options for all commands:", -1); } + Tcl_SetObjResult(interp, message); } /* diff --git a/generic/tkAtom.c b/generic/tkAtom.c index fe1b5b3..2491fb2 100644 --- a/generic/tkAtom.c +++ b/generic/tkAtom.c @@ -20,7 +20,7 @@ * those found in xatom.h */ -static const char *atomNameArray[] = { +static const char *const atomNameArray[] = { "PRIMARY", "SECONDARY", "ARC", "ATOM", "BITMAP", "CARDINAL", "COLORMAP", "CURSOR", "CUT_BUFFER0", @@ -76,10 +76,10 @@ Atom Tk_InternAtom( Tk_Window tkwin, /* Window token; map name to atom for this * window's display. */ - CONST char *name) /* Name to turn into atom. */ + const char *name) /* Name to turn into atom. */ { - register TkDisplay *dispPtr; - register Tcl_HashEntry *hPtr; + TkDisplay *dispPtr; + Tcl_HashEntry *hPtr; int isNew; dispPtr = ((TkWindow *) tkwin)->dispPtr; @@ -97,7 +97,7 @@ Tk_InternAtom( hPtr2 = Tcl_CreateHashEntry(&dispPtr->atomTable, INT2PTR(atom), &isNew); Tcl_SetHashValue(hPtr2, Tcl_GetHashKey(&dispPtr->nameTable, hPtr)); } - return (Atom) PTR2INT(Tcl_GetHashValue(hPtr)); + return (Atom)PTR2INT(Tcl_GetHashValue(hPtr)); } /* @@ -121,14 +121,14 @@ Tk_InternAtom( *-------------------------------------------------------------- */ -CONST char * +const char * Tk_GetAtomName( Tk_Window tkwin, /* Window token; map atom to name relative to * this window's display. */ Atom atom) /* Atom whose name is wanted. */ { - register TkDisplay *dispPtr; - register Tcl_HashEntry *hPtr; + TkDisplay *dispPtr; + Tcl_HashEntry *hPtr; dispPtr = ((TkWindow *) tkwin)->dispPtr; if (!dispPtr->atomInit) { @@ -137,23 +137,22 @@ Tk_GetAtomName( hPtr = Tcl_FindHashEntry(&dispPtr->atomTable, INT2PTR(atom)); if (hPtr == NULL) { - char *name; + const char *name; Tk_ErrorHandler handler; - int isNew, mustFree; + int isNew; + char *mustFree = NULL; handler = Tk_CreateErrorHandler(dispPtr->display, BadAtom, -1, -1, - NULL, (ClientData) NULL); - name = XGetAtomName(dispPtr->display, atom); - mustFree = 1; + NULL, NULL); + name = mustFree = XGetAtomName(dispPtr->display, atom); if (name == NULL) { name = "?bad atom?"; - mustFree = 0; } Tk_DeleteErrorHandler(handler); hPtr = Tcl_CreateHashEntry(&dispPtr->nameTable, name, &isNew); Tcl_SetHashValue(hPtr, INT2PTR(atom)); if (mustFree) { - XFree(name); + XFree(mustFree); } name = Tcl_GetHashKey(&dispPtr->nameTable, hPtr); hPtr = Tcl_CreateHashEntry(&dispPtr->atomTable, INT2PTR(atom), &isNew); @@ -180,7 +179,7 @@ Tk_GetAtomName( static void AtomInit( - register TkDisplay *dispPtr)/* Display to initialize. */ + TkDisplay *dispPtr)/* Display to initialize. */ { Tcl_HashEntry *hPtr; Atom atom; diff --git a/generic/tkBind.c b/generic/tkBind.c index 98c491a..e0971ba 100644 --- a/generic/tkBind.c +++ b/generic/tkBind.c @@ -14,7 +14,7 @@ #include "tkInt.h" -#ifdef __WIN32__ +#ifdef _WIN32 #include "tkWinInt.h" #elif defined(MAC_OSX_TK) #include "tkMacOSXInt.h" @@ -29,13 +29,10 @@ * * Init/Free this package. * - * Tcl "bind" command (actually located in tkCmds.c). - * "bind" command implementation. - * "bind" implementation helpers. + * Tcl "bind" command (actually located in tkCmds.c) core implementation, plus + * helpers. * - * Tcl "event" command. - * "event" command implementation. - * "event" implementation helpers. + * Tcl "event" command implementation, plus helpers. * * Package-specific common helpers. * @@ -78,8 +75,21 @@ typedef union { * EVENT_BUFFER_SIZE too much, shift multi-clicks will be lost. */ -#define EVENT_BUFFER_SIZE 30 -typedef struct BindingTable { +/* + * NOTE: The changes which were needed to make Tk work on OSX 10.14 (Mojave) + * also demand that the event ring be a bit bigger. It might be wise to + * augment the current double-click pattern matching by adding a new + * DoubleClick modifier bit which could be set based on the clickCount of the + * Apple NSEvent object. + */ + +#ifndef TK_MAC_OSX + #define EVENT_BUFFER_SIZE 90 +#else + #define EVENT_BUFFER_SIZE 30 +#endif + +typedef struct Tk_BindingTable_ { XEvent eventRing[EVENT_BUFFER_SIZE]; /* Circular queue of recent events (higher * indices are for more recent events). */ @@ -108,12 +118,12 @@ typedef struct BindingTable { * * A virtual event is usually never part of the event stream, but instead is * synthesized inline by matching low-level events. However, a virtual event - * may be generated by platform-specific code or by Tcl scripts. In that case, + * may be generated by platform-specific code or by Tcl commands. In that case, * no lookup of the virtual event will need to be done using this table, * because the virtual event is actually in the event stream. */ -typedef struct VirtualEventTable { +typedef struct { Tcl_HashTable patternTable; /* Used to map from a physical event to a list * of patterns that may match that event. Keys * are PatternTableKey structs, values are @@ -140,7 +150,7 @@ typedef struct VirtualEventTable { * tables and virtual event tables. */ -typedef struct PatternTableKey { +typedef struct { ClientData object; /* For binding table, identifies the binding * tag of the object (or class of objects) * relative to which the event occurred. For @@ -156,7 +166,7 @@ typedef struct PatternTableKey { * events as part of the process of converting X events into Tcl commands. */ -typedef struct TkPattern { +typedef struct { int eventType; /* Type of X event, e.g. ButtonPress. */ int needMods; /* Mask of modifiers that must be present (0 * means no modifiers are required). */ @@ -193,21 +203,10 @@ typedef struct TkPattern { typedef struct PatSeq { int numPats; /* Number of patterns in sequence (usually * 1). */ - TkBindEvalProc *eventProc; /* The function that will be invoked on the - * clientData when this pattern sequence - * matches. */ - TkBindFreeProc *freeProc; /* The function that will be invoked to - * release the clientData when this pattern - * sequence is freed. */ - ClientData clientData; /* Arbitray data passed to eventProc and - * freeProc when sequence matches. */ + char *script; /* Binding script to evaluate when sequence + * matches (ckalloc()ed) */ int flags; /* Miscellaneous flag values; see below for * definitions. */ - int refCount; /* Number of times that this binding is in the - * midst of executing. If greater than 1, then - * a recursive invocation is happening. Only - * when this is zero can the binding actually - * be freed. */ struct PatSeq *nextSeqPtr; /* Next in list of all pattern sequences that * have the same initial pattern. NULL means * end of list. */ @@ -238,16 +237,9 @@ typedef struct PatSeq { * must occur with nearby X and Y mouse coordinates and * close in time. This is typically used to restrict * multiple button presses. - * MARKED_DELETED 1 means that this binding has been marked as deleted - * and removed from the binding table, but its memory - * could not be released because it was already queued - * for execution. When the binding is actually about to - * be executed, this flag will be checked and the binding - * skipped if set. */ #define PAT_NEARBY 0x1 -#define MARKED_DELETED 0x2 /* * Constants that define how close together two events must be in milliseconds @@ -275,7 +267,7 @@ typedef struct VirtualOwners { * to associate a virtual event with all the physical events that can trigger * it. */ -typedef struct PhysicalsOwned { +typedef struct { int numOwned; /* Number of physical events owned. */ PatSeq *patSeqs[1]; /* Array of pointers to physical event * patterns. Enough space will actually be @@ -285,7 +277,7 @@ typedef struct PhysicalsOwned { /* * One of the following structures exists for each interpreter. This structure * keeps track of the current display and screen in the interpreter, so that a - * script can be invoked whenever the display/screen changes (the script does + * command can be invoked whenever the display/screen changes (the command does * things like point tk::Priv at a display-specific structure). */ @@ -298,44 +290,17 @@ typedef struct { } ScreenInfo; /* - * The following structure is used to keep track of all the C bindings that - * are awaiting invocation and whether the window they refer to has been - * destroyed. If the window is destroyed, then all pending callbacks for that - * window will be cancelled. The Tcl bindings will still all be invoked, - * however. - */ - -typedef struct PendingBinding { - struct PendingBinding *nextPtr; - /* Next in chain of pending bindings, in case - * a recursive binding evaluation is in - * progress. */ - Tk_Window tkwin; /* The window that the following bindings - * depend upon. */ - int deleted; /* Set to non-zero by window cleanup code if - * tkwin is deleted. */ - PatSeq *matchArray[5]; /* Array of pending C bindings. The actual - * size of this depends on how many C bindings - * matched the event passed to Tk_BindEvent. - * THIS FIELD MUST BE THE LAST IN THE - * STRUCTURE. */ -} PendingBinding; - -/* * The following structure keeps track of all the information local to the * binding package on a per interpreter basis. */ -typedef struct BindInfo { +typedef struct TkBindInfo_ { VirtualEventTable virtualEventTable; /* The virtual events that exist in this * interpreter. */ ScreenInfo screenInfo; /* Keeps track of the current display and * screen, so it can be restored after a * binding has executed. */ - PendingBinding *pendingList;/* The list of pending C bindings, kept in - * case a C or Tcl binding causes the target - * window to be deleted. */ int deleted; /* 1 the application has been deleted but the * structure has been preserved. */ } BindInfo; @@ -352,10 +317,10 @@ typedef struct BindInfo { #ifdef REDO_KEYSYM_LOOKUP typedef struct { - char *name; /* Name of keysym. */ + const char *name; /* Name of keysym. */ KeySym value; /* Numeric identifier for keysym. */ } KeySymInfo; -static KeySymInfo keyArray[] = { +static const KeySymInfo keyArray[] = { #ifndef lint #include "ks_names.h" #endif @@ -381,7 +346,7 @@ TCL_DECLARE_MUTEX(bindMutex) */ typedef struct { - char *name; /* Name of modifier. */ + const char *name; /* Name of modifier. */ int mask; /* Button/modifier mask value, such as * Button1Mask. */ int flags; /* Various flags; see below for @@ -405,7 +370,7 @@ typedef struct { #define QUADRUPLE 4 #define MULT_CLICKS 7 -static ModInfo modArray[] = { +static const ModInfo modArray[] = { {"Control", ControlMask, 0}, {"Shift", ShiftMask, 0}, {"Lock", LockMask, 0}, @@ -450,7 +415,7 @@ static Tcl_HashTable modTable; */ typedef struct { - char *name; /* Name of event. */ + const char *name; /* Name of event. */ int type; /* Event type for X, such as ButtonPress. */ int eventMask; /* Mask bits (for XSelectInput) for this event * type. */ @@ -463,7 +428,7 @@ typedef struct { * unless you've asked about button events. */ -static EventInfo eventArray[] = { +static const EventInfo eventArray[] = { {"Key", KeyPress, KeyPressMask}, {"KeyPress", KeyPress, KeyPressMask}, {"KeyRelease", KeyRelease, KeyPressMask|KeyReleaseMask}, @@ -535,7 +500,7 @@ static Tcl_HashTable eventTable; #define KEY_BUTTON_MOTION_VIRTUAL (KEY|BUTTON|MOTION|VIRTUAL) #define KEY_BUTTON_MOTION_CROSSING (KEY|BUTTON|MOTION|VIRTUAL|CROSSING) -static int flagArray[TK_LASTEVENT] = { +static const int flagArray[TK_LASTEVENT] = { /* Not used */ 0, /* Not used */ 0, /* KeyPress */ KEY, @@ -654,15 +619,14 @@ static void ChangeScreen(Tcl_Interp *interp, char *dispName, int screenIndex); static int CreateVirtualEvent(Tcl_Interp *interp, VirtualEventTable *vetPtr, char *virtString, - char *eventString); + const char *eventString); static int DeleteVirtualEvent(Tcl_Interp *interp, VirtualEventTable *vetPtr, char *virtString, - char *eventString); + const char *eventString); static void DeleteVirtualEventTable(VirtualEventTable *vetPtr); static void ExpandPercents(TkWindow *winPtr, const char *before, XEvent *eventPtr,KeySym keySym, unsigned int scriptCount, Tcl_DString *dsPtr); -static void FreeTclBinding(ClientData clientData); static PatSeq * FindSequence(Tcl_Interp *interp, Tcl_HashTable *patternTablePtr, ClientData object, const char *eventString, int create, @@ -670,9 +634,9 @@ static PatSeq * FindSequence(Tcl_Interp *interp, static void GetAllVirtualEvents(Tcl_Interp *interp, VirtualEventTable *vetPtr); static char * GetField(char *p, char *copy, int size); -static void GetPatternString(PatSeq *psPtr, Tcl_DString *dsPtr); +static Tcl_Obj * GetPatternObj(PatSeq *psPtr); static int GetVirtualEvent(Tcl_Interp *interp, - VirtualEventTable *vetPtr, char *virtString); + VirtualEventTable *vetPtr, Tcl_Obj *virtName); static Tk_Uid GetVirtualEventUid(Tcl_Interp *interp, char *virtString); static int HandleEventGenerate(Tcl_Interp *interp, Tk_Window main, @@ -688,15 +652,6 @@ static int ParseEventDescription(Tcl_Interp *interp, const char **eventStringPtr, TkPattern *patPtr, unsigned long *eventMaskPtr); static void DoWarp(ClientData clientData); - -/* - * The following define is used as a short circuit for the callback function - * to evaluate a TclBinding. The actual evaluation of the binding is handled - * inline, because special things have to be done with a Tcl binding before - * evaluation time. - */ - -#define EvalTclBinding ((TkBindEvalProc *) 1) /* *--------------------------------------------------------------------------- @@ -735,11 +690,11 @@ TkBindInit( Tcl_MutexLock(&bindMutex); if (!initialized) { Tcl_HashEntry *hPtr; - ModInfo *modPtr; - EventInfo *eiPtr; + const ModInfo *modPtr; + const EventInfo *eiPtr; int newEntry; #ifdef REDO_KEYSYM_LOOKUP - KeySymInfo *kPtr; + const KeySymInfo *kPtr; Tcl_InitHashTable(&keySymTable, TCL_STRING_KEYS); Tcl_InitHashTable(&nameTable, TCL_ONE_WORD_KEYS); @@ -772,14 +727,13 @@ TkBindInit( mainPtr->bindingTable = Tk_CreateBindingTable(mainPtr->interp); - bindInfoPtr = (BindInfo *) ckalloc(sizeof(BindInfo)); + bindInfoPtr = ckalloc(sizeof(BindInfo)); InitVirtualEventTable(&bindInfoPtr->virtualEventTable); bindInfoPtr->screenInfo.curDispPtr = NULL; bindInfoPtr->screenInfo.curScreenIndex = -1; bindInfoPtr->screenInfo.bindingDepth = 0; - bindInfoPtr->pendingList = NULL; bindInfoPtr->deleted = 0; - mainPtr->bindInfo = (TkBindInfo) bindInfoPtr; + mainPtr->bindInfo = bindInfoPtr; TkpInitializeMenuBindings(mainPtr->interp, mainPtr->bindingTable); } @@ -810,10 +764,10 @@ TkBindFree( Tk_DeleteBindingTable(mainPtr->bindingTable); mainPtr->bindingTable = NULL; - bindInfoPtr = (BindInfo *) mainPtr->bindInfo; + bindInfoPtr = mainPtr->bindInfo; DeleteVirtualEventTable(&bindInfoPtr->virtualEventTable); bindInfoPtr->deleted = 1; - Tcl_EventuallyFree((ClientData) bindInfoPtr, TCL_DYNAMIC); + Tcl_EventuallyFree(bindInfoPtr, TCL_DYNAMIC); mainPtr->bindInfo = NULL; } @@ -840,14 +794,13 @@ Tk_CreateBindingTable( * table: commands are executed in this * interpreter. */ { - BindingTable *bindPtr; + BindingTable *bindPtr = ckalloc(sizeof(BindingTable)); int i; /* * Create and initialize a new binding table. */ - bindPtr = (BindingTable *) ckalloc(sizeof(BindingTable)); for (i = 0; i < EVENT_BUFFER_SIZE; i++) { bindPtr->eventRing[i].type = -1; } @@ -856,7 +809,7 @@ Tk_CreateBindingTable( sizeof(PatternTableKey)/sizeof(int)); Tcl_InitHashTable(&bindPtr->objectTable, TCL_ONE_WORD_KEYS); bindPtr->interp = interp; - return (Tk_BindingTable) bindPtr; + return bindPtr; } /* @@ -878,10 +831,8 @@ Tk_CreateBindingTable( void Tk_DeleteBindingTable( - Tk_BindingTable bindingTable) - /* Token for the binding table to destroy. */ + Tk_BindingTable bindPtr) /* Token for the binding table to destroy. */ { - BindingTable *bindPtr = (BindingTable *) bindingTable; PatSeq *psPtr, *nextPtr; Tcl_HashEntry *hPtr; Tcl_HashSearch search; @@ -892,16 +843,10 @@ Tk_DeleteBindingTable( for (hPtr = Tcl_FirstHashEntry(&bindPtr->patternTable, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - for (psPtr = (PatSeq *) Tcl_GetHashValue(hPtr); - psPtr != NULL; psPtr = nextPtr) { + for (psPtr = Tcl_GetHashValue(hPtr); psPtr != NULL; psPtr = nextPtr) { nextPtr = psPtr->nextSeqPtr; - psPtr->flags |= MARKED_DELETED; - if (psPtr->refCount == 0) { - if (psPtr->freeProc != NULL) { - (*psPtr->freeProc)(psPtr->clientData); - } - ckfree((char *) psPtr); - } + ckfree(psPtr->script); + ckfree(psPtr); } } @@ -911,7 +856,7 @@ Tk_DeleteBindingTable( Tcl_DeleteHashTable(&bindPtr->patternTable); Tcl_DeleteHashTable(&bindPtr->objectTable); - ckfree((char *) bindPtr); + ckfree(bindPtr); } /* @@ -941,13 +886,12 @@ Tk_DeleteBindingTable( unsigned long Tk_CreateBinding( Tcl_Interp *interp, /* Used for error reporting. */ - Tk_BindingTable bindingTable, - /* Table in which to create binding. */ + Tk_BindingTable bindPtr, /* Table in which to create binding. */ ClientData object, /* Token for object with which binding is * associated. */ const char *eventString, /* String describing event sequence that * triggers binding. */ - const char *command, /* Contains Tcl command to execute when + const char *script, /* Contains Tcl script to execute when * binding triggers. */ int append) /* 0 means replace any existing binding for * eventString; 1 means append to that @@ -956,12 +900,11 @@ Tk_CreateBinding( * string, the existing binding will always be * replaced. */ { - BindingTable *bindPtr = (BindingTable *) bindingTable; PatSeq *psPtr; unsigned long eventMask; char *newStr, *oldStr; - if (!*command) { + if (!*script) { /* Silently ignore empty scripts -- see SF#3006842 */ return 1; } @@ -970,7 +913,7 @@ Tk_CreateBinding( if (psPtr == NULL) { return 0; } - if (psPtr->eventProc == NULL) { + if (psPtr->script == NULL) { int isNew; Tcl_HashEntry *hPtr; @@ -985,120 +928,29 @@ Tk_CreateBinding( if (isNew) { psPtr->nextObjPtr = NULL; } else { - psPtr->nextObjPtr = (PatSeq *) Tcl_GetHashValue(hPtr); + psPtr->nextObjPtr = Tcl_GetHashValue(hPtr); } Tcl_SetHashValue(hPtr, psPtr); - } else if (psPtr->eventProc != EvalTclBinding) { - /* - * Free existing procedural binding. - */ - - if (psPtr->freeProc != NULL) { - (*psPtr->freeProc)(psPtr->clientData); - } - psPtr->clientData = NULL; - append = 0; } - oldStr = (char *) psPtr->clientData; + oldStr = psPtr->script; if ((append != 0) && (oldStr != NULL)) { - size_t length; + size_t length1 = strlen(oldStr), length2 = strlen(script); - length = strlen(oldStr) + strlen(command) + 2; - newStr = (char *) ckalloc((unsigned) length); - sprintf(newStr, "%s\n%s", oldStr, command); + newStr = ckalloc(length1 + length2 + 2); + memcpy(newStr, oldStr, length1); + newStr[length1] = '\n'; + memcpy(newStr+length1+1, script, length2+1); } else { - newStr = (char *) ckalloc((unsigned) strlen(command) + 1); - strcpy(newStr, command); + size_t length = strlen(script); + + newStr = ckalloc(length + 1); + memcpy(newStr, script, length+1); } if (oldStr != NULL) { ckfree(oldStr); } - psPtr->eventProc = EvalTclBinding; - psPtr->freeProc = FreeTclBinding; - psPtr->clientData = (ClientData) newStr; - return eventMask; -} - -/* - *--------------------------------------------------------------------------- - * - * TkCreateBindingProcedure -- - * - * Add a C binding to a binding table, so that future calls to - * Tk_BindEvent may callback the function in the binding. - * - * Results: - - * The return value is 0 if an error occurred while setting up the - * binding. In this case, an error message will be left in the interp's - * result. If all went well then the return value is a mask of the event - * types that must be made available to Tk_BindEvent in order to properly - * detect when this binding triggers. This value can be used to determine - * what events to select for in a window, for example. - * - * Side effects: - * Any existing binding on the same event sequence will be replaced. - * - *--------------------------------------------------------------------------- - */ - -unsigned long -TkCreateBindingProcedure( - Tcl_Interp *interp, /* Used for error reporting. */ - Tk_BindingTable bindingTable, - /* Table in which to create binding. */ - ClientData object, /* Token for object with which binding is - * associated. */ - const char *eventString, /* String describing event sequence that - * triggers binding. */ - TkBindEvalProc *eventProc, /* Function to invoke when binding triggers. - * Must not be NULL. */ - TkBindFreeProc *freeProc, /* Function to invoke when binding is freed. - * May be NULL for no function. */ - ClientData clientData) /* Arbitrary ClientData to pass to eventProc - * and freeProc. */ -{ - BindingTable *bindPtr = (BindingTable *) bindingTable; - PatSeq *psPtr; - unsigned long eventMask; - - psPtr = FindSequence(interp, &bindPtr->patternTable, object, eventString, - 1, 1, &eventMask); - if (psPtr == NULL) { - return 0; - } - if (psPtr->eventProc == NULL) { - int isNew; - Tcl_HashEntry *hPtr; - - /* - * This pattern sequence was just created. Link the pattern into the - * list associated with the object, so that if the object goes away, - * these bindings will all automatically be deleted. - */ - - hPtr = Tcl_CreateHashEntry(&bindPtr->objectTable, (char *) object, - &isNew); - if (isNew) { - psPtr->nextObjPtr = NULL; - } else { - psPtr->nextObjPtr = (PatSeq *) Tcl_GetHashValue(hPtr); - } - Tcl_SetHashValue(hPtr, psPtr); - } else { - /* - * Free existing callback. - */ - - if (psPtr->freeProc != NULL) { - (*psPtr->freeProc)(psPtr->clientData); - } - } - - psPtr->eventProc = eventProc; - psPtr->freeProc = freeProc; - psPtr->clientData = clientData; + psPtr->script = newStr; return eventMask; } @@ -1123,14 +975,12 @@ TkCreateBindingProcedure( int Tk_DeleteBinding( Tcl_Interp *interp, /* Used for error reporting. */ - Tk_BindingTable bindingTable, - /* Table in which to delete binding. */ + Tk_BindingTable bindPtr, /* Table in which to delete binding. */ ClientData object, /* Token for object with which binding is * associated. */ const char *eventString) /* String describing event sequence that * triggers binding. */ { - BindingTable *bindPtr = (BindingTable *) bindingTable; PatSeq *psPtr, *prevPtr; unsigned long eventMask; Tcl_HashEntry *hPtr; @@ -1151,7 +1001,7 @@ Tk_DeleteBinding( if (hPtr == NULL) { Tcl_Panic("Tk_DeleteBinding couldn't find object table entry"); } - prevPtr = (PatSeq *) Tcl_GetHashValue(hPtr); + prevPtr = Tcl_GetHashValue(hPtr); if (prevPtr == psPtr) { Tcl_SetHashValue(hPtr, psPtr->nextObjPtr); } else { @@ -1165,7 +1015,7 @@ Tk_DeleteBinding( } } } - prevPtr = (PatSeq *) Tcl_GetHashValue(psPtr->hPtr); + prevPtr = Tcl_GetHashValue(psPtr->hPtr); if (prevPtr == psPtr) { if (psPtr->nextSeqPtr == NULL) { Tcl_DeleteHashEntry(psPtr->hPtr); @@ -1184,13 +1034,8 @@ Tk_DeleteBinding( } } - psPtr->flags |= MARKED_DELETED; - if (psPtr->refCount == 0) { - if (psPtr->freeProc != NULL) { - (*psPtr->freeProc)(psPtr->clientData); - } - ckfree((char *) psPtr); - } + ckfree(psPtr->script); + ckfree(psPtr); return TCL_OK; } @@ -1199,10 +1044,10 @@ Tk_DeleteBinding( * * Tk_GetBinding -- * - * Return the command associated with a given event string. + * Return the script associated with a given event string. * * Results: - * The return value is a pointer to the command string associated with + * The return value is a pointer to the script associated with * eventString for object in the domain given by bindingTable. If there * is no binding for eventString, or if eventString is improperly formed, * then NULL is returned and an error message is left in the interp's @@ -1218,14 +1063,12 @@ Tk_DeleteBinding( const char * Tk_GetBinding( Tcl_Interp *interp, /* Interpreter for error reporting. */ - Tk_BindingTable bindingTable, - /* Table in which to look for binding. */ + Tk_BindingTable bindPtr, /* Table in which to look for binding. */ ClientData object, /* Token for object with which binding is * associated. */ const char *eventString) /* String describing event sequence that * triggers binding. */ { - BindingTable *bindPtr = (BindingTable *) bindingTable; PatSeq *psPtr; unsigned long eventMask; @@ -1234,10 +1077,7 @@ Tk_GetBinding( if (psPtr == NULL) { return NULL; } - if (psPtr->eventProc == EvalTclBinding) { - return (const char *) psPtr->clientData; - } - return ""; + return psPtr->script; } /* @@ -1263,32 +1103,29 @@ Tk_GetBinding( void Tk_GetAllBindings( Tcl_Interp *interp, /* Interpreter returning result or error. */ - Tk_BindingTable bindingTable, - /* Table in which to look for bindings. */ + Tk_BindingTable bindPtr, /* Table in which to look for bindings. */ ClientData object) /* Token for object. */ { - BindingTable *bindPtr = (BindingTable *) bindingTable; PatSeq *psPtr; Tcl_HashEntry *hPtr; - Tcl_DString ds; + Tcl_Obj *resultObj; hPtr = Tcl_FindHashEntry(&bindPtr->objectTable, (char *) object); if (hPtr == NULL) { return; } - Tcl_DStringInit(&ds); - for (psPtr = (PatSeq *) Tcl_GetHashValue(hPtr); psPtr != NULL; + + resultObj = Tcl_NewObj(); + for (psPtr = Tcl_GetHashValue(hPtr); psPtr != NULL; psPtr = psPtr->nextObjPtr) { /* * For each binding, output information about each of the patterns in * its sequence. */ - Tcl_DStringSetLength(&ds, 0); - GetPatternString(psPtr, &ds); - Tcl_AppendElement(interp, Tcl_DStringValue(&ds)); + Tcl_ListObjAppendElement(NULL, resultObj, GetPatternObj(psPtr)); } - Tcl_DStringFree(&ds); + Tcl_SetObjResult(interp, resultObj); } /* @@ -1310,11 +1147,9 @@ Tk_GetAllBindings( void Tk_DeleteAllBindings( - Tk_BindingTable bindingTable, - /* Table in which to delete bindings. */ + Tk_BindingTable bindPtr, /* Table in which to delete bindings. */ ClientData object) /* Token for object. */ { - BindingTable *bindPtr = (BindingTable *) bindingTable; PatSeq *psPtr, *prevPtr; PatSeq *nextPtr; Tcl_HashEntry *hPtr; @@ -1323,7 +1158,7 @@ Tk_DeleteAllBindings( if (hPtr == NULL) { return; } - for (psPtr = (PatSeq *) Tcl_GetHashValue(hPtr); psPtr != NULL; + for (psPtr = Tcl_GetHashValue(hPtr); psPtr != NULL; psPtr = nextPtr) { nextPtr = psPtr->nextObjPtr; @@ -1333,7 +1168,7 @@ Tk_DeleteAllBindings( * hash entry too. */ - prevPtr = (PatSeq *) Tcl_GetHashValue(psPtr->hPtr); + prevPtr = Tcl_GetHashValue(psPtr->hPtr); if (prevPtr == psPtr) { if (psPtr->nextSeqPtr == NULL) { Tcl_DeleteHashEntry(psPtr->hPtr); @@ -1351,14 +1186,8 @@ Tk_DeleteAllBindings( } } } - psPtr->flags |= MARKED_DELETED; - - if (psPtr->refCount == 0) { - if (psPtr->freeProc != NULL) { - (*psPtr->freeProc)(psPtr->clientData); - } - ckfree((char *) psPtr); - } + ckfree(psPtr->script); + ckfree(psPtr); } Tcl_DeleteHashEntry(hPtr); } @@ -1378,27 +1207,19 @@ Tk_DeleteAllBindings( * None. * * Side effects: - * Depends on the command associated with the matching binding. + * Depends on the script associated with the matching binding. * - * All Tcl bindings scripts for each object are accumulated before the + * All Tcl binding scripts for each object are accumulated before the * first binding is evaluated. If the action of a Tcl binding is to * change or delete a binding, or delete the window associated with the * binding, all the original Tcl binding scripts will still fire. - * Contrast this with C binding functions. If a pending C binding (one - * that hasn't fired yet, but is queued to be fired for this window) is - * deleted, it will not be called, and if it is changed, then the new - * binding function will be called. If the window itself is deleted, no - * further C binding functions will be called for this window. When both - * Tcl binding scripts and C binding functions are interleaved, the above - * rules still apply. * *--------------------------------------------------------------------------- */ void Tk_BindEvent( - Tk_BindingTable bindingTable, - /* Table in which to look for bindings. */ + Tk_BindingTable bindPtr, /* Table in which to look for bindings. */ XEvent *eventPtr, /* What actually happened. */ Tk_Window tkwin, /* Window on display where event occurred * (needed in order to locate display @@ -1407,24 +1228,21 @@ Tk_BindEvent( ClientData *objectPtr) /* Array of one or more objects to check for a * matching binding. */ { - BindingTable *bindPtr; TkDisplay *dispPtr; ScreenInfo *screenPtr; BindInfo *bindInfoPtr; TkDisplay *oldDispPtr; XEvent *ringPtr; PatSeq *vMatchDetailList, *vMatchNoDetailList; - int flags, oldScreen, i, deferModal; - unsigned int matchCount, matchSpace; + int flags, oldScreen; unsigned int scriptCount; Tcl_Interp *interp; - Tcl_DString scripts, savedResult; + Tcl_DString scripts; + Tcl_InterpState interpState; Detail detail; char *p, *end; - PendingBinding staticPending, *pendingPtr; TkWindow *winPtr = (TkWindow *) tkwin; PatternTableKey key; - Tk_ClassModalProc *modalProc; /* * Ignore events on windows that don't have names: these are windows like @@ -1455,9 +1273,18 @@ Tk_BindEvent( } } - bindPtr = (BindingTable *) bindingTable; + /* + * 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 = (BindInfo *) winPtr->mainPtr->bindInfo; + bindInfoPtr = winPtr->mainPtr->bindInfo; /* * Add the new event to the ring of saved events for the binding table. @@ -1517,7 +1344,7 @@ Tk_BindEvent( } } ringPtr = &bindPtr->eventRing[bindPtr->curEvent]; - memcpy((void *) ringPtr, (void *) eventPtr, sizeof(XEvent)); + memcpy(ringPtr, eventPtr, sizeof(XEvent)); detail.clientData = 0; flags = flagArray[ringPtr->type]; if (flags & KEY) { @@ -1551,14 +1378,14 @@ Tk_BindEvent( hPtr = Tcl_FindHashEntry(veptPtr, (char *) &key); if (hPtr != NULL) { - vMatchDetailList = (PatSeq *) Tcl_GetHashValue(hPtr); + vMatchDetailList = Tcl_GetHashValue(hPtr); } if (key.detail.clientData != 0) { key.detail.clientData = 0; hPtr = Tcl_FindHashEntry(veptPtr, (char *) &key); if (hPtr != NULL) { - vMatchNoDetailList = (PatSeq *) Tcl_GetHashValue(hPtr); + vMatchNoDetailList = Tcl_GetHashValue(hPtr); } } } @@ -1567,14 +1394,10 @@ Tk_BindEvent( * Loop over all the binding tags, finding the binding script or callback * for each one. Append all of the binding scripts, with %-sequences * expanded, to "scripts", with null characters separating the scripts for - * each object. Append all the callbacks to the array of pending - * callbacks. + * each object. */ - pendingPtr = &staticPending; - matchCount = 0; scriptCount = 0; - matchSpace = sizeof(staticPending.matchArray) / sizeof(PatSeq *); Tcl_DStringInit(&scripts); for ( ; numObjects > 0; numObjects--, objectPtr++) { @@ -1594,9 +1417,8 @@ Tk_BindEvent( key.detail = detail; hPtr = Tcl_FindHashEntry(&bindPtr->patternTable, (char *) &key); if (hPtr != NULL) { - matchPtr = MatchPatterns(dispPtr, bindPtr, - (PatSeq *) Tcl_GetHashValue(hPtr), matchPtr, NULL, - &sourcePtr); + matchPtr = MatchPatterns(dispPtr, bindPtr, Tcl_GetHashValue(hPtr), + matchPtr, NULL, &sourcePtr); } if (vMatchDetailList != NULL) { @@ -1614,47 +1436,18 @@ Tk_BindEvent( hPtr = Tcl_FindHashEntry(&bindPtr->patternTable, (char *) &key); if (hPtr != NULL) { matchPtr = MatchPatterns(dispPtr, bindPtr, - (PatSeq *) Tcl_GetHashValue(hPtr), matchPtr, NULL, - &sourcePtr); + Tcl_GetHashValue(hPtr), matchPtr, NULL, &sourcePtr); } if (vMatchNoDetailList != NULL) { matchPtr = MatchPatterns(dispPtr, bindPtr, vMatchNoDetailList, matchPtr, objectPtr, &sourcePtr); } - } if (matchPtr != NULL) { - if (sourcePtr->eventProc == NULL) { - Tcl_Panic("Tk_BindEvent: missing command"); - } - if (sourcePtr->eventProc == EvalTclBinding) { - ExpandPercents(winPtr, (char *) sourcePtr->clientData, - eventPtr, detail.keySym, scriptCount++, &scripts); - } else { - if (matchCount >= matchSpace) { - PendingBinding *newPtr; - unsigned int oldSize, newSize; - - oldSize = sizeof(staticPending) - - sizeof(staticPending.matchArray) - + matchSpace * sizeof(PatSeq*); - matchSpace *= 2; - newSize = sizeof(staticPending) - - sizeof(staticPending.matchArray) - + matchSpace * sizeof(PatSeq*); - newPtr = (PendingBinding *) ckalloc(newSize); - memcpy((void *) newPtr, (void *) pendingPtr, oldSize); - if (pendingPtr != &staticPending) { - ckfree((char *) pendingPtr); - } - pendingPtr = newPtr; - } - sourcePtr->refCount++; - pendingPtr->matchArray[matchCount] = sourcePtr; - matchCount++; - } + ExpandPercents(winPtr, sourcePtr->script, eventPtr, + detail.keySym, scriptCount++, &scripts); /* * A "" is added to the scripts string to separate the various @@ -1686,14 +1479,13 @@ Tk_BindEvent( */ interp = bindPtr->interp; - Tcl_DStringInit(&savedResult); /* * Save information about the current screen, then invoke a script if the * screen has changed. */ - Tcl_DStringGetResult(interp, &savedResult); + interpState = Tcl_SaveInterpState(interp, TCL_OK); screenPtr = &bindInfoPtr->screenInfo; oldDispPtr = screenPtr->curDispPtr; oldScreen = screenPtr->curScreenIndex; @@ -1704,40 +1496,18 @@ Tk_BindEvent( ChangeScreen(interp, dispPtr->name, screenPtr->curScreenIndex); } - if (matchCount > 0) { - /* - * Remember the list of pending C binding callbacks, so we can mark - * them as deleted and not call them if the act of evaluating a C or - * Tcl binding deletes a C binding callback or even the whole window. - */ - - pendingPtr->nextPtr = bindInfoPtr->pendingList; - pendingPtr->tkwin = tkwin; - pendingPtr->deleted = 0; - bindInfoPtr->pendingList = pendingPtr; - } - - /* - * Save the current value of the TK_DEFER_MODAL flag so we can restore it - * at the end of the loop. Clear the flag so we can detect any recursive - * requests for a modal loop. - */ - - flags = winPtr->flags; - winPtr->flags &= ~TK_DEFER_MODAL; - p = Tcl_DStringValue(&scripts); end = p + Tcl_DStringLength(&scripts); - i = 0; /* - * Be carefule when dereferencing screenPtr or bindInfoPtr. If we evaluate + * Be careful when dereferencing screenPtr or bindInfoPtr. If we evaluate * something that destroys ".", bindInfoPtr would have been freed, but we * can tell that by first checking to see if winPtr->mainPtr == NULL. */ - Tcl_Preserve((ClientData) bindInfoPtr); + Tcl_Preserve(bindInfoPtr); while (p < end) { + int len = (int) strlen(p); int code; if (!bindInfoPtr->deleted) { @@ -1745,31 +1515,8 @@ Tk_BindEvent( } Tcl_AllowExceptions(interp); - if (*p == '\0') { - PatSeq *psPtr; - - psPtr = pendingPtr->matchArray[i]; - i++; - code = TCL_OK; - if ((pendingPtr->deleted == 0) - && ((psPtr->flags & MARKED_DELETED) == 0)) { - code = (*psPtr->eventProc)(psPtr->clientData, interp, eventPtr, - tkwin, detail.keySym); - } - psPtr->refCount--; - if ((psPtr->refCount == 0) && (psPtr->flags & MARKED_DELETED)) { - if (psPtr->freeProc != NULL) { - (*psPtr->freeProc)(psPtr->clientData); - } - ckfree((char *) psPtr); - } - } else { - int len = (int) strlen(p); - - code = Tcl_EvalEx(interp, p, len, TCL_EVAL_GLOBAL); - p += len; - } - p++; + code = Tcl_EvalEx(interp, p, len, TCL_EVAL_GLOBAL); + p += len + 1; if (!bindInfoPtr->deleted) { screenPtr->bindingDepth--; @@ -1783,29 +1530,12 @@ Tk_BindEvent( break; } else { Tcl_AddErrorInfo(interp, "\n (command bound to event)"); - Tcl_BackgroundError(interp); + Tcl_BackgroundException(interp, code); break; } } } - if (matchCount > 0 && !pendingPtr->deleted) { - /* - * Restore the original modal flag value and invoke the modal loop if - * needed. - */ - - deferModal = winPtr->flags & TK_DEFER_MODAL; - winPtr->flags = (winPtr->flags & (unsigned int) ~TK_DEFER_MODAL) - | (flags & TK_DEFER_MODAL); - if (deferModal) { - modalProc = Tk_GetClassProc(winPtr->classProcsPtr, modalProc); - if (modalProc != NULL) { - (*modalProc)(tkwin, eventPtr); - } - } - } - if (!bindInfoPtr->deleted && (screenPtr->bindingDepth != 0) && ((oldDispPtr != screenPtr->curDispPtr) || (oldScreen != screenPtr->curScreenIndex))) { @@ -1818,74 +1548,10 @@ Tk_BindEvent( screenPtr->curScreenIndex = oldScreen; ChangeScreen(interp, oldDispPtr->name, oldScreen); } - Tcl_DStringResult(interp, &savedResult); + (void) Tcl_RestoreInterpState(interp, interpState); Tcl_DStringFree(&scripts); - if (matchCount > 0) { - if (!bindInfoPtr->deleted) { - /* - * Delete the pending list from the list of pending scripts for - * this window. - */ - - PendingBinding **curPtrPtr; - - for (curPtrPtr = &bindInfoPtr->pendingList; ; ) { - if (*curPtrPtr == pendingPtr) { - *curPtrPtr = pendingPtr->nextPtr; - break; - } - curPtrPtr = &(*curPtrPtr)->nextPtr; - } - } - if (pendingPtr != &staticPending) { - ckfree((char *) pendingPtr); - } - } - Tcl_Release((ClientData) bindInfoPtr); -} - -/* - *--------------------------------------------------------------------------- - * - * TkBindDeadWindow -- - * - * This function is invoked when it is determined that a window is dead. - * It cleans up bind-related information about the window - * - * Results: - * None. - * - * Side effects: - * Any pending C bindings for this window are cancelled. - * - *--------------------------------------------------------------------------- - */ - -void -TkBindDeadWindow( - TkWindow *winPtr) /* The window that is being deleted. */ -{ - BindInfo *bindInfoPtr; - PendingBinding *curPtr; - - /* - * Certain special windows like those used for send and clipboard have no - * mainPtr. - */ - - if (winPtr->mainPtr == NULL) { - return; - } - - bindInfoPtr = (BindInfo *) winPtr->mainPtr->bindInfo; - curPtr = bindInfoPtr->pendingList; - while (curPtr != NULL) { - if (curPtr->tkwin == (Tk_Window) winPtr) { - curPtr->deleted = 1; - } - curPtr = curPtr->nextPtr; - } + Tcl_Release(bindInfoPtr); } /* @@ -1924,6 +1590,7 @@ TkBindDeadWindow( * *---------------------------------------------------------------------- */ + static PatSeq * MatchPatterns( TkDisplay *dispPtr, /* Display from which the event came. */ @@ -2084,9 +1751,10 @@ MatchPatterns( } if (psPtr->flags & PAT_NEARBY) { XEvent *firstPtr = &bindPtr->eventRing[bindPtr->curEvent]; - int timeDiff; + long timeDiff; - timeDiff = (Time) firstPtr->xkey.time - eventPtr->xkey.time; + timeDiff = ((long)firstPtr->xkey.time - + (long)eventPtr->xkey.time); if ((firstPtr->xkey.x_root < (eventPtr->xkey.x_root - NEARBY_PIXELS)) || (firstPtr->xkey.x_root @@ -2147,7 +1815,7 @@ MatchPatterns( * virtual event's definition. */ - PatSeq *virtMatchPtr = (PatSeq *) Tcl_GetHashValue(hPtr); + PatSeq *virtMatchPtr = Tcl_GetHashValue(hPtr); if ((virtMatchPtr->numPats != 1) || (virtMatchPtr->nextSeqPtr != NULL)) { @@ -2538,7 +2206,7 @@ ExpandPercents( goto doNumber; case 'K': if ((flags & KEY) && (eventPtr->type != MouseWheelEvent)) { - char *name = TkKeysymToString(keySym); + const char *name = TkKeysymToString(keySym); if (name != NULL) { string = name; @@ -2589,13 +2257,19 @@ ExpandPercents( } case 'X': if (flags & KEY_BUTTON_MOTION_CROSSING) { + number = eventPtr->xkey.x_root; + Tk_IdToWindow(eventPtr->xany.display, + eventPtr->xany.window); goto doNumber; } goto doString; case 'Y': if (flags & KEY_BUTTON_MOTION_CROSSING) { + number = eventPtr->xkey.y_root; + Tk_IdToWindow(eventPtr->xany.display, + eventPtr->xany.window); goto doNumber; } goto doString; @@ -2650,23 +2324,18 @@ ChangeScreen( char *dispName, /* Name of new display. */ int screenIndex) /* Index of new screen. */ { - Tcl_DString cmd; + Tcl_Obj *cmdObj = Tcl_ObjPrintf("::tk::ScreenChanged %s.%d", + dispName, screenIndex); int code; - char screen[TCL_INTEGER_SPACE]; - - Tcl_DStringInit(&cmd); - Tcl_DStringAppend(&cmd, "tk::ScreenChanged ", 18); - Tcl_DStringAppend(&cmd, dispName, -1); - sprintf(screen, ".%d", screenIndex); - Tcl_DStringAppend(&cmd, screen, -1); - code = Tcl_EvalEx(interp, Tcl_DStringValue(&cmd), Tcl_DStringLength(&cmd), - TCL_EVAL_GLOBAL); - Tcl_DStringFree(&cmd); + + Tcl_IncrRefCount(cmdObj); + code = Tcl_EvalObjEx(interp, cmdObj, TCL_EVAL_GLOBAL); if (code != TCL_OK) { Tcl_AddErrorInfo(interp, "\n (changing screen in event binding)"); - Tcl_BackgroundError(interp); + Tcl_BackgroundException(interp, code); } + Tcl_DecrRefCount(cmdObj); } /* @@ -2693,11 +2362,13 @@ Tk_EventObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - int index; - Tk_Window tkwin; - VirtualEventTable *vetPtr; - TkBindInfo bindInfo; - static const char *optionStrings[] = { + int index, i; + char *name; + const char *event; + Tk_Window tkwin = clientData; + TkBindInfo bindInfo = ((TkWindow *) tkwin)->mainPtr->bindInfo; + VirtualEventTable *vetPtr = &bindInfo->virtualEventTable; + static const char *const optionStrings[] = { "add", "delete", "generate", "info", NULL }; @@ -2705,24 +2376,18 @@ Tk_EventObjCmd( EVENT_ADD, EVENT_DELETE, EVENT_GENERATE, EVENT_INFO }; - tkwin = (Tk_Window) clientData; - bindInfo = ((TkWindow *) tkwin)->mainPtr->bindInfo; - vetPtr = &((BindInfo *) bindInfo)->virtualEventTable; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "option ?arg?"); return TCL_ERROR; } - if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0, - &index) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings, + sizeof(char *), "option", 0, &index) != TCL_OK) { return TCL_ERROR; } switch ((enum options) index) { - case EVENT_ADD: { - int i; - char *name, *event; - + case EVENT_ADD: if (objc < 4) { Tcl_WrongNumArgs(interp, 2, objv, "virtual sequence ?sequence ...?"); @@ -2736,14 +2401,9 @@ Tk_EventObjCmd( } } break; - } - case EVENT_DELETE: { - int i; - char *name, *event; - + case EVENT_DELETE: if (objc < 3) { - Tcl_WrongNumArgs(interp, 2, objv, - "virtual ?sequence sequence ...?"); + Tcl_WrongNumArgs(interp, 2, objv, "virtual ?sequence ...?"); return TCL_ERROR; } name = Tcl_GetString(objv[2]); @@ -2757,10 +2417,10 @@ Tk_EventObjCmd( } } break; - } case EVENT_GENERATE: if (objc < 4) { - Tcl_WrongNumArgs(interp, 2, objv, "window event ?options?"); + Tcl_WrongNumArgs(interp, 2, objv, + "window event ?-option value ...?"); return TCL_ERROR; } return HandleEventGenerate(interp, tkwin, objc - 2, objv + 2); @@ -2769,7 +2429,7 @@ Tk_EventObjCmd( GetAllVirtualEvents(interp, vetPtr); return TCL_OK; } else if (objc == 3) { - return GetVirtualEvent(interp, vetPtr, Tcl_GetString(objv[2])); + return GetVirtualEvent(interp, vetPtr, objv[2]); } else { Tcl_WrongNumArgs(interp, 2, objv, "?virtual?"); return TCL_ERROR; @@ -2832,18 +2492,18 @@ DeleteVirtualEventTable( hPtr = Tcl_FirstHashEntry(&vetPtr->patternTable, &search); for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - psPtr = (PatSeq *) Tcl_GetHashValue(hPtr); + psPtr = Tcl_GetHashValue(hPtr); for ( ; psPtr != NULL; psPtr = nextPtr) { nextPtr = psPtr->nextSeqPtr; - ckfree((char *) psPtr->voPtr); - ckfree((char *) psPtr); + ckfree(psPtr->voPtr); + ckfree(psPtr); } } Tcl_DeleteHashTable(&vetPtr->patternTable); hPtr = Tcl_FirstHashEntry(&vetPtr->nameTable, &search); for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - ckfree((char *) Tcl_GetHashValue(hPtr)); + ckfree(Tcl_GetHashValue(hPtr)); } Tcl_DeleteHashTable(&vetPtr->nameTable); } @@ -2873,7 +2533,7 @@ CreateVirtualEvent( Tcl_Interp *interp, /* Used for error reporting. */ VirtualEventTable *vetPtr, /* Table in which to augment virtual event. */ char *virtString, /* Name of new virtual event. */ - char *eventString) /* String describing physical event that + const char *eventString) /* String describing physical event that * triggers virtual event. */ { PatSeq *psPtr; @@ -2909,9 +2569,9 @@ CreateVirtualEvent( * Make virtual event own the physical event. */ - poPtr = (PhysicalsOwned *) Tcl_GetHashValue(vhPtr); + poPtr = Tcl_GetHashValue(vhPtr); if (poPtr == NULL) { - poPtr = (PhysicalsOwned *) ckalloc(sizeof(PhysicalsOwned)); + poPtr = ckalloc(sizeof(PhysicalsOwned)); poPtr->numOwned = 0; } else { /* @@ -2926,10 +2586,10 @@ CreateVirtualEvent( return TCL_OK; } } - poPtr = (PhysicalsOwned *) ckrealloc((char *) poPtr, - sizeof(PhysicalsOwned) + poPtr->numOwned * sizeof(PatSeq *)); + poPtr = ckrealloc(poPtr, sizeof(PhysicalsOwned) + + poPtr->numOwned * sizeof(PatSeq *)); } - Tcl_SetHashValue(vhPtr, (ClientData) poPtr); + Tcl_SetHashValue(vhPtr, poPtr); poPtr->patSeqs[poPtr->numOwned] = psPtr; poPtr->numOwned++; @@ -2939,11 +2599,10 @@ CreateVirtualEvent( voPtr = psPtr->voPtr; if (voPtr == NULL) { - voPtr = (VirtualOwners *) ckalloc(sizeof(VirtualOwners)); + voPtr = ckalloc(sizeof(VirtualOwners)); voPtr->numOwners = 0; } else { - voPtr = (VirtualOwners *) ckrealloc((char *) voPtr, - sizeof(VirtualOwners) + voPtr = ckrealloc(voPtr, sizeof(VirtualOwners) + voPtr->numOwners * sizeof(Tcl_HashEntry *)); } psPtr->voPtr = voPtr; @@ -2982,7 +2641,7 @@ DeleteVirtualEvent( VirtualEventTable *vetPtr, /* Table in which to delete event. */ char *virtString, /* String describing event sequence that * triggers binding. */ - char *eventString) /* The event sequence that should be deleted, + const char *eventString) /* The event sequence that should be deleted, * or NULL to delete all event sequences for * the entire virtual event. */ { @@ -3001,7 +2660,7 @@ DeleteVirtualEvent( if (vhPtr == NULL) { return TCL_OK; } - poPtr = (PhysicalsOwned *) Tcl_GetHashValue(vhPtr); + poPtr = Tcl_GetHashValue(vhPtr); eventPSPtr = NULL; if (eventString != NULL) { @@ -3016,7 +2675,7 @@ DeleteVirtualEvent( eventPSPtr = FindSequence(interp, &vetPtr->patternTable, NULL, eventString, 0, 0, &eventMask); if (eventPSPtr == NULL) { - const char *string = Tcl_GetStringResult(interp); + const char *string = Tcl_GetString(Tcl_GetObjResult(interp)); return (string[0] != '\0') ? TCL_ERROR : TCL_OK; } @@ -3050,7 +2709,7 @@ DeleteVirtualEvent( * from physical->virtual map. */ - PatSeq *prevPtr = (PatSeq *) Tcl_GetHashValue(psPtr->hPtr); + PatSeq *prevPtr = Tcl_GetHashValue(psPtr->hPtr); if (prevPtr == psPtr) { if (psPtr->nextSeqPtr == NULL) { @@ -3070,8 +2729,8 @@ DeleteVirtualEvent( } } } - ckfree((char *) psPtr->voPtr); - ckfree((char *) psPtr); + ckfree(psPtr->voPtr); + ckfree(psPtr); } else { /* * This physical event still triggers some other virtual @@ -3108,7 +2767,7 @@ DeleteVirtualEvent( * itself should be deleted. */ - ckfree((char *) poPtr); + ckfree(poPtr); Tcl_DeleteHashEntry(vhPtr); } return TCL_OK; @@ -3140,15 +2799,15 @@ static int GetVirtualEvent( Tcl_Interp *interp, /* Interpreter for reporting. */ VirtualEventTable *vetPtr, /* Table in which to look for event. */ - char *virtString) /* String describing virtual event. */ + Tcl_Obj *virtName) /* String describing virtual event. */ { Tcl_HashEntry *vhPtr; - Tcl_DString ds; int iPhys; PhysicalsOwned *poPtr; Tk_Uid virtUid; + Tcl_Obj *resultObj; - virtUid = GetVirtualEventUid(interp, virtString); + virtUid = GetVirtualEventUid(interp, Tcl_GetString(virtName)); if (virtUid == NULL) { return TCL_ERROR; } @@ -3158,15 +2817,13 @@ GetVirtualEvent( return TCL_OK; } - Tcl_DStringInit(&ds); - - poPtr = (PhysicalsOwned *) Tcl_GetHashValue(vhPtr); + resultObj = Tcl_NewObj(); + poPtr = Tcl_GetHashValue(vhPtr); for (iPhys = 0; iPhys < poPtr->numOwned; iPhys++) { - Tcl_DStringSetLength(&ds, 0); - GetPatternString(poPtr->patSeqs[iPhys], &ds); - Tcl_AppendElement(interp, Tcl_DStringValue(&ds)); + Tcl_ListObjAppendElement(NULL, resultObj, + GetPatternObj(poPtr->patSeqs[iPhys])); } - Tcl_DStringFree(&ds); + Tcl_SetObjResult(interp, resultObj); return TCL_OK; } @@ -3196,20 +2853,15 @@ GetAllVirtualEvents( { Tcl_HashEntry *hPtr; Tcl_HashSearch search; - Tcl_DString ds; - - Tcl_DStringInit(&ds); + Tcl_Obj *resultObj; + resultObj = Tcl_NewObj(); hPtr = Tcl_FirstHashEntry(&vetPtr->nameTable, &search); for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - Tcl_DStringSetLength(&ds, 0); - Tcl_DStringAppend(&ds, "<<", 2); - Tcl_DStringAppend(&ds, Tcl_GetHashKey(hPtr->tablePtr, hPtr), -1); - Tcl_DStringAppend(&ds, ">>", 2); - Tcl_AppendElement(interp, Tcl_DStringValue(&ds)); + Tcl_ListObjAppendElement(NULL, resultObj, Tcl_ObjPrintf( + "<<%s>>", (char *) Tcl_GetHashKey(hPtr->tablePtr, hPtr))); } - - Tcl_DStringFree(&ds); + Tcl_SetObjResult(interp, resultObj); } /* @@ -3240,7 +2892,7 @@ GetAllVirtualEvents( * Any other fields in eventPtr which are not specified by the pattern * string or the optional arguments, are set to 0. * - * The event may be handled sychronously or asynchronously, depending on + * The event may be handled synchronously or asynchronously, depending on * the value specified by the optional "-when" option. The default * setting is synchronous. * @@ -3256,7 +2908,7 @@ HandleEventGenerate( { union {XEvent general; XVirtualEvent virtual;} event; const char *p; - char *name, *windowName; + const char *name, *windowName; int count, flags, synch, i, number, warp; Tcl_QueuePosition pos; TkPattern pat; @@ -3264,7 +2916,8 @@ HandleEventGenerate( TkWindow *mainPtr; unsigned long eventMask; Tcl_Obj *userDataObj; - static const char *fieldStrings[] = { + + static const char *const fieldStrings[] = { "-when", "-above", "-borderwidth", "-button", "-count", "-data", "-delta", "-detail", "-focus", "-height", @@ -3295,8 +2948,11 @@ HandleEventGenerate( mainPtr = (TkWindow *) mainWin; if ((tkwin == NULL) || (mainPtr->mainPtr != ((TkWindow *) tkwin)->mainPtr)) { - Tcl_AppendResult(interp, "window id \"", Tcl_GetString(objv[0]), - "\" doesn't exist in this application", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "window id \"%s\" doesn't exist in this application", + Tcl_GetString(objv[0]))); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "WINDOW", + Tcl_GetString(objv[0]), NULL); return TCL_ERROR; } @@ -3310,17 +2966,19 @@ HandleEventGenerate( return TCL_ERROR; } if (count != 1) { - Tcl_SetResult(interp, "Double or Triple modifier not allowed", - TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "Double or Triple modifier not allowed", -1)); + Tcl_SetErrorCode(interp, "TK", "EVENT", "BAD_MODIFIER", NULL); return TCL_ERROR; } if (*p != '\0') { - Tcl_SetResult(interp, "only one event specification allowed", - TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "only one event specification allowed", -1)); + Tcl_SetErrorCode(interp, "TK", "EVENT", "MULTIPLE", NULL); return TCL_ERROR; } - memset((void *) &event, 0, sizeof(event)); + memset(&event, 0, sizeof(event)); event.general.xany.type = pat.eventType; event.general.xany.serial = NextRequest(Tk_Display(tkwin)); event.general.xany.send_event = False; @@ -3360,6 +3018,11 @@ HandleEventGenerate( event.general.xkey.y_root = -1; } + if (event.general.xany.type == FocusIn + || event.general.xany.type == FocusOut) { + event.general.xany.send_event = GENERATED_FOCUS_EVENT_MAGIC; + } + /* * Process the remaining arguments to fill in additional fields of the * event. @@ -3375,8 +3038,8 @@ HandleEventGenerate( optionPtr = objv[i]; valuePtr = objv[i + 1]; - if (Tcl_GetIndexFromObj(interp, optionPtr, fieldStrings, "option", - TCL_EXACT, &index) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, optionPtr, fieldStrings, + sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) { return TCL_ERROR; } if (objc & 1) { @@ -3387,8 +3050,9 @@ HandleEventGenerate( * is missing. */ - Tcl_AppendResult(interp, "value for \"", Tcl_GetString(optionPtr), - "\" missing", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "value for \"%s\" missing", Tcl_GetString(optionPtr))); + Tcl_SetErrorCode(interp, "TK", "EVENT", "MISSING_VALUE", NULL); return TCL_ERROR; } @@ -3524,20 +3188,24 @@ HandleEventGenerate( break; case EVENT_KEYSYM: { KeySym keysym; - char *value; + const char *value; value = Tcl_GetString(valuePtr); keysym = TkStringToKeysym(value); if (keysym == NoSymbol) { - Tcl_AppendResult(interp, "unknown keysym \"", value, "\"", + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "unknown keysym \"%s\"", value)); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "KEYSYM", value, NULL); return TCL_ERROR; } TkpSetKeycodeAndState(tkwin, keysym, &event.general); if (event.general.xkey.keycode == 0) { - Tcl_AppendResult(interp, "no keycode for keysym \"", value, - "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "no keycode for keysym \"%s\"", value)); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "KEYCODE", value, + NULL); return TCL_ERROR; } if (!(flags & KEY) @@ -3679,9 +3347,9 @@ HandleEventGenerate( return TCL_ERROR; } if (flags & KEY_BUTTON_MOTION_CROSSING) { - event.general.xkey.time = (Time) number; + event.general.xkey.time = number; } else if (flags & PROP) { - event.general.xproperty.time = (Time) number; + event.general.xproperty.time = number; } else { goto badopt; } @@ -3712,7 +3380,7 @@ HandleEventGenerate( if (Tk_GetPixelsFromObj(interp,tkwin,valuePtr,&number) != TCL_OK) { return TCL_ERROR; } - if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { + if (flags & KEY_BUTTON_MOTION_CROSSING) { event.general.xkey.x = number; /* @@ -3766,12 +3434,22 @@ HandleEventGenerate( continue; badopt: - Tcl_AppendResult(interp, name, " event doesn't accept \"", - Tcl_GetString(optionPtr), "\" option", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "%s event doesn't accept \"%s\" option", + name, Tcl_GetString(optionPtr))); + Tcl_SetErrorCode(interp, "TK", "EVENT", "BAD_OPTION", NULL); return TCL_ERROR; } + + /* + * Don't generate events for windows that don't exist yet. + */ + + if (!event.general.xany.window) { + goto done; + } + if (userDataObj != NULL) { - XVirtualEvent *vePtr = (XVirtualEvent *) &event; /* * Must be virtual event to set that variable to non-NULL. Now we want @@ -3780,7 +3458,7 @@ HandleEventGenerate( * refcount will be decremented once the event has been processed. */ - vePtr->user_data = userDataObj; + event.virtual.user_data = userDataObj; Tcl_IncrRefCount(userDataObj); } @@ -3802,14 +3480,29 @@ HandleEventGenerate( if ((warp != 0) && Tk_IsMapped(tkwin)) { TkDisplay *dispPtr = TkGetDisplay(event.general.xmotion.display); + Tk_Window warpWindow = Tk_IdToWindow(dispPtr->display, + event.general.xmotion.window); + if (!(dispPtr->flags & TK_DISPLAY_IN_WARP)) { - Tcl_DoWhenIdle(DoWarp, (ClientData) dispPtr); + Tcl_DoWhenIdle(DoWarp, dispPtr); dispPtr->flags |= TK_DISPLAY_IN_WARP; } - dispPtr->warpWindow = event.general.xany.window; - dispPtr->warpX = event.general.xkey.x; - dispPtr->warpY = event.general.xkey.y; + + if (warpWindow != dispPtr->warpWindow) { + if (warpWindow) { + Tcl_Preserve(warpWindow); + } + if (dispPtr->warpWindow) { + Tcl_Release(dispPtr->warpWindow); + } + dispPtr->warpWindow = warpWindow; + } + dispPtr->warpMainwin = mainWin; + dispPtr->warpX = event.general.xmotion.x; + dispPtr->warpY = event.general.xmotion.y; } + + done: Tcl_ResetResult(interp); return TCL_OK; } @@ -3821,32 +3514,38 @@ NameToWindow( Tcl_Obj *objPtr, /* Contains name or id string of window. */ Tk_Window *tkwinPtr) /* Filled with token for window. */ { - char *name; + const char *name = Tcl_GetString(objPtr); Tk_Window tkwin; - Window id; - name = Tcl_GetString(objPtr); if (name[0] == '.') { tkwin = Tk_NameToWindow(interp, name, mainWin); if (tkwin == NULL) { return TCL_ERROR; } - *tkwinPtr = tkwin; } else { + Window id; + /* * Check for the winPtr being valid, even if it looks ok to * TkpScanWindowId. [Bug #411307] */ - if ((TkpScanWindowId(NULL, name, &id) != TCL_OK) || - ((*tkwinPtr = Tk_IdToWindow(Tk_Display(mainWin), id)) - == NULL)) { - Tcl_AppendResult(interp, "bad window name/identifier \"", - name, "\"", NULL); - return TCL_ERROR; + if (TkpScanWindowId(NULL, name, &id) != TCL_OK) { + goto badWindow; + } + tkwin = Tk_IdToWindow(Tk_Display(mainWin), id); + if (tkwin == NULL) { + goto badWindow; } } + *tkwinPtr = tkwin; return TCL_OK; + + badWindow: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad window name/identifier \"%s\"", name)); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "WINDOW_ID", name, NULL); + return TCL_ERROR; } /* @@ -3864,15 +3563,32 @@ NameToWindow( * *------------------------------------------------------------------------- */ + static void DoWarp( ClientData clientData) { - TkDisplay *dispPtr = (TkDisplay *) clientData; + TkDisplay *dispPtr = clientData; + + /* + * DoWarp was scheduled only if the window was mapped. It needs to be + * still mapped at the time the present idle callback is executed. Also + * one needs to guard against window destruction in the meantime. + * Finally, the case warpWindow == NULL is special in that it means + * the whole screen. + */ - XWarpPointer(dispPtr->display, None, (Window) dispPtr->warpWindow, - 0, 0, 0, 0, (int) dispPtr->warpX, (int) dispPtr->warpY); - XForceScreenSaver(dispPtr->display, ScreenSaverReset); + if ((dispPtr->warpWindow == NULL) || + (Tk_IsMapped(dispPtr->warpWindow) + && (Tk_WindowId(dispPtr->warpWindow) != None))) { + TkpWarpPointer(dispPtr); + XForceScreenSaver(dispPtr->display, ScreenSaverReset); + } + + if (dispPtr->warpWindow) { + Tcl_Release(dispPtr->warpWindow); + dispPtr->warpWindow = NULL; + } dispPtr->flags &= ~TK_DISPLAY_IN_WARP; } @@ -3908,8 +3624,9 @@ GetVirtualEventUid( if (length < 5 || virtString[0] != '<' || virtString[1] != '<' || virtString[length - 2] != '>' || virtString[length - 1] != '>') { - Tcl_AppendResult(interp, "virtual event \"", virtString, - "\" is badly formed", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "virtual event \"%s\" is badly formed", virtString)); + Tcl_SetErrorCode(interp, "TK", "EVENT", "VIRTUAL", "MALFORMED", NULL); return NULL; } virtString[length - 2] = '\0'; @@ -4001,9 +3718,11 @@ FindSequence( if (eventMask & VirtualEventMask) { if (allowVirtual == 0) { - Tcl_SetResult(interp, + Tcl_SetObjResult(interp, Tcl_NewStringObj( "virtual event not allowed in definition of another virtual event", - TCL_STATIC); + -1)); + Tcl_SetErrorCode(interp, "TK", "EVENT", "VIRTUAL", "INNER", + NULL); return NULL; } virtualFound = 1; @@ -4029,12 +3748,16 @@ FindSequence( */ if (numPats == 0) { - Tcl_SetResult(interp, "no events specified in binding", TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "no events specified in binding", -1)); + Tcl_SetErrorCode(interp, "TK", "EVENT", "NO_EVENTS", NULL); return NULL; } if ((numPats > 1) && (virtualFound != 0)) { - Tcl_SetResult(interp, "virtual events may not be composed", - TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "virtual events may not be composed", -1)); + Tcl_SetErrorCode(interp, "TK", "EVENT", "VIRTUAL", "COMPOSITION", + NULL); return NULL; } @@ -4046,12 +3769,11 @@ FindSequence( hPtr = Tcl_CreateHashEntry(patternTablePtr, (char *) &key, &isNew); sequenceSize = numPats*sizeof(TkPattern); if (!isNew) { - for (psPtr = (PatSeq *) Tcl_GetHashValue(hPtr); psPtr != NULL; + for (psPtr = Tcl_GetHashValue(hPtr); psPtr != NULL; psPtr = psPtr->nextSeqPtr) { if ((numPats == psPtr->numPats) && ((flags & PAT_NEARBY) == (psPtr->flags & PAT_NEARBY)) - && (memcmp((char *) patPtr, (char *) psPtr->pats, - sequenceSize) == 0)) { + && (memcmp(patPtr, psPtr->pats, sequenceSize) == 0)) { goto done; } } @@ -4071,21 +3793,17 @@ FindSequence( return NULL; } - psPtr = (PatSeq *) ckalloc((unsigned) (sizeof(PatSeq) - + (numPats-1)*sizeof(TkPattern))); + psPtr = ckalloc(sizeof(PatSeq) + (numPats-1)*sizeof(TkPattern)); psPtr->numPats = numPats; - psPtr->eventProc = NULL; - psPtr->freeProc = NULL; - psPtr->clientData = NULL; + psPtr->script = NULL; psPtr->flags = flags; - psPtr->refCount = 0; - psPtr->nextSeqPtr = (PatSeq *) Tcl_GetHashValue(hPtr); + psPtr->nextSeqPtr = Tcl_GetHashValue(hPtr); psPtr->hPtr = hPtr; psPtr->voPtr = NULL; psPtr->nextObjPtr = NULL; Tcl_SetHashValue(hPtr, psPtr); - memcpy((void *) psPtr->pats, (void *) patPtr, sequenceSize); + memcpy(psPtr->pats, patPtr, sequenceSize); done: *maskPtr = eventMask; @@ -4157,10 +3875,9 @@ ParseEventDescription( if (isprint(UCHAR(*p))) { patPtr->detail.keySym = *p; } else { - char buf[64]; - - sprintf(buf, "bad ASCII character 0x%x", (unsigned char) *p); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad ASCII character 0x%x", UCHAR(*p))); + Tcl_SetErrorCode(interp, "TK", "EVENT", "BAD_CHAR", NULL); count = 0; goto done; } @@ -4201,14 +3918,18 @@ ParseEventDescription( p = strchr(field, '>'); if (p == field) { - Tcl_SetResult(interp, "virtual event \"<<>>\" is badly formed", - TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "virtual event \"<<>>\" is badly formed", -1)); + Tcl_SetErrorCode(interp, "TK", "EVENT", "VIRTUAL", "MALFORMED", + NULL); count = 0; goto done; } if ((p == NULL) || (p[1] != '>')) { - Tcl_SetResult(interp, "missing \">\" in virtual binding", - TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "missing \">\" in virtual binding", -1)); + Tcl_SetErrorCode(interp, "TK", "EVENT", "VIRTUAL", "MALFORMED", + NULL); count = 0; goto done; } @@ -4239,7 +3960,7 @@ ParseEventDescription( if (hPtr == NULL) { break; } - modPtr = (ModInfo *) Tcl_GetHashValue(hPtr); + modPtr = Tcl_GetHashValue(hPtr); patPtr->needMods |= modPtr->mask; if (modPtr->flags & MULT_CLICKS) { int i = modPtr->flags & MULT_CLICKS; @@ -4257,7 +3978,7 @@ ParseEventDescription( eventFlags = 0; hPtr = Tcl_FindHashEntry(&eventTable, field); if (hPtr != NULL) { - EventInfo *eiPtr = (EventInfo *) Tcl_GetHashValue(hPtr); + const EventInfo *eiPtr = Tcl_GetHashValue(hPtr); patPtr->eventType = eiPtr->type; eventFlags = flagArray[eiPtr->type]; @@ -4274,9 +3995,11 @@ ParseEventDescription( eventMask = ButtonPressMask; } else if (eventFlags & KEY) { goto getKeysym; - } else if ((eventFlags & BUTTON) == 0) { - Tcl_AppendResult(interp, "specified button \"", field, - "\" for non-button event", NULL); + } else if (!(eventFlags & BUTTON)) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "specified button \"%s\" for non-button event", + field)); + Tcl_SetErrorCode(interp, "TK", "EVENT", "NON_BUTTON", NULL); count = 0; goto done; } @@ -4286,24 +4009,28 @@ ParseEventDescription( getKeysym: patPtr->detail.keySym = TkStringToKeysym(field); if (patPtr->detail.keySym == NoSymbol) { - Tcl_AppendResult(interp, "bad event type or keysym \"", - field, "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad event type or keysym \"%s\"", field)); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "KEYSYM", field, + NULL); count = 0; goto done; } if (eventFlags == 0) { patPtr->eventType = KeyPress; eventMask = KeyPressMask; - } else if ((eventFlags & KEY) == 0) { - Tcl_AppendResult(interp, "specified keysym \"", field, - "\" for non-key event", NULL); + } else if (!(eventFlags & KEY)) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "specified keysym \"%s\" for non-key event", field)); + Tcl_SetErrorCode(interp, "TK", "EVENT", "NON_KEY", NULL); count = 0; goto done; } } } else if (eventFlags == 0) { - Tcl_SetResult(interp, "no event type or button # or keysym", - TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "no event type or button # or keysym", -1)); + Tcl_SetErrorCode(interp, "TK", "EVENT", "UNMODIFIABLE", NULL); count = 0; goto done; } @@ -4315,14 +4042,16 @@ ParseEventDescription( while (*p != '\0') { p++; if (*p == '>') { - Tcl_SetResult(interp, - "extra characters after detail in binding", - TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "extra characters after detail in binding", -1)); + Tcl_SetErrorCode(interp, "TK", "EVENT", "PAST_DETAIL", NULL); count = 0; goto done; } } - Tcl_SetResult(interp, "missing \">\" in binding", TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "missing \">\" in binding", -1)); + Tcl_SetErrorCode(interp, "TK", "EVENT", "MALFORMED", NULL); count = 0; goto done; } @@ -4377,31 +4106,30 @@ GetField( /* *--------------------------------------------------------------------------- * - * GetPatternString -- + * GetPatternObj -- * * Produce a string version of the given event, for displaying to the * user. * * Results: - * The string is left in dsPtr. + * The string is returned as a Tcl_Obj. * * Side effects: - * It is the caller's responsibility to initialize the DString before and - * to free it after calling this function. + * It is the caller's responsibility to arrange for the object to be + * released; it starts with a refCount of zero. * *--------------------------------------------------------------------------- */ -static void -GetPatternString( - PatSeq *psPtr, - Tcl_DString *dsPtr) +static Tcl_Obj * +GetPatternObj( + PatSeq *psPtr) { TkPattern *patPtr; - char c, buffer[TCL_INTEGER_SPACE]; int patsLeft, needMods; - ModInfo *modPtr; - EventInfo *eiPtr; + const ModInfo *modPtr; + const EventInfo *eiPtr; + Tcl_Obj *patternObj = Tcl_NewObj(); /* * The order of the patterns in the sequence is backwards from the order @@ -4415,14 +4143,15 @@ GetPatternString( */ if ((patPtr->eventType == KeyPress) - && ((psPtr->flags & PAT_NEARBY) == 0) + && !(psPtr->flags & PAT_NEARBY) && (patPtr->needMods == 0) && (patPtr->detail.keySym < 128) && isprint(UCHAR(patPtr->detail.keySym)) && (patPtr->detail.keySym != '<') && (patPtr->detail.keySym != ' ')) { - c = (char) patPtr->detail.keySym; - Tcl_DStringAppend(dsPtr, &c, 1); + char c = (char) patPtr->detail.keySym; + + Tcl_AppendToObj(patternObj, &c, 1); continue; } @@ -4431,9 +4160,7 @@ GetPatternString( */ if (patPtr->eventType == VirtualEvent) { - Tcl_DStringAppend(dsPtr, "<<", 2); - Tcl_DStringAppend(dsPtr, patPtr->detail.name, -1); - Tcl_DStringAppend(dsPtr, ">>", 2); + Tcl_AppendPrintfToObj(patternObj, "<<%s>>", patPtr->detail.name); continue; } @@ -4443,27 +4170,26 @@ GetPatternString( * or button detail. */ - Tcl_DStringAppend(dsPtr, "<", 1); + Tcl_AppendToObj(patternObj, "<", 1); if ((psPtr->flags & PAT_NEARBY) && (patsLeft > 1) - && (memcmp((char *) patPtr, (char *) (patPtr-1), - sizeof(TkPattern)) == 0)) { + && (memcmp(patPtr, patPtr-1, sizeof(TkPattern)) == 0)) { patsLeft--; patPtr--; - if ((patsLeft > 1) && (memcmp((char *) patPtr, - (char *) (patPtr-1), sizeof(TkPattern)) == 0)) { + if ((patsLeft > 1) && + (memcmp(patPtr, patPtr-1, sizeof(TkPattern)) == 0)) { patsLeft--; patPtr--; - if ((patsLeft > 1) && (memcmp((char *) patPtr, - (char *) (patPtr-1), sizeof(TkPattern)) == 0)) { - patsLeft--; - patPtr--; - Tcl_DStringAppend(dsPtr, "Quadruple-", 10); - } else { - Tcl_DStringAppend(dsPtr, "Triple-", 7); - } + if ((patsLeft > 1) && + (memcmp(patPtr, patPtr-1, sizeof(TkPattern)) == 0)) { + patsLeft--; + patPtr--; + Tcl_AppendToObj(patternObj, "Quadruple-", 10); + } else { + Tcl_AppendToObj(patternObj, "Triple-", 7); + } } else { - Tcl_DStringAppend(dsPtr, "Double-", 7); + Tcl_AppendToObj(patternObj, "Double-", 7); } } @@ -4471,16 +4197,15 @@ GetPatternString( needMods != 0; modPtr++) { if (modPtr->mask & needMods) { needMods &= ~modPtr->mask; - Tcl_DStringAppend(dsPtr, modPtr->name, -1); - Tcl_DStringAppend(dsPtr, "-", 1); + Tcl_AppendPrintfToObj(patternObj, "%s-", modPtr->name); } } for (eiPtr = eventArray; eiPtr->name != NULL; eiPtr++) { if (eiPtr->type == patPtr->eventType) { - Tcl_DStringAppend(dsPtr, eiPtr->name, -1); + Tcl_AppendToObj(patternObj, eiPtr->name, -1); if (patPtr->detail.clientData != 0) { - Tcl_DStringAppend(dsPtr, "-", 1); + Tcl_AppendToObj(patternObj, "-", 1); } break; } @@ -4489,43 +4214,20 @@ GetPatternString( if (patPtr->detail.clientData != 0) { if ((patPtr->eventType == KeyPress) || (patPtr->eventType == KeyRelease)) { - char *string = TkKeysymToString(patPtr->detail.keySym); + const char *string = TkKeysymToString(patPtr->detail.keySym); + if (string != NULL) { - Tcl_DStringAppend(dsPtr, string, -1); + Tcl_AppendToObj(patternObj, string, -1); } } else { - sprintf(buffer, "%d", patPtr->detail.button); - Tcl_DStringAppend(dsPtr, buffer, -1); + Tcl_AppendPrintfToObj(patternObj, "%d", patPtr->detail.button); } } - Tcl_DStringAppend(dsPtr, ">", 1); + Tcl_AppendToObj(patternObj, ">", 1); } -} - -/* - *--------------------------------------------------------------------------- - * - * EvalTclBinding -- - * - * The function that is invoked by Tk_BindEvent when a Tcl binding is - * fired. - * - * Results: - * A standard Tcl result code, the result of globally evaluating the - * percent-substitued binding string. - * - * Side effects: - * Normal side effects due to eval. - * - *--------------------------------------------------------------------------- - */ -static void -FreeTclBinding( - ClientData clientData) -{ - ckfree((char *) clientData); + return patternObj; } /* @@ -4547,7 +4249,7 @@ FreeTclBinding( KeySym TkStringToKeysym( - char *name) /* Name of a keysym. */ + const char *name) /* Name of a keysym. */ { #ifdef REDO_KEYSYM_LOOKUP Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&keySymTable, name); @@ -4583,7 +4285,7 @@ TkStringToKeysym( *---------------------------------------------------------------------- */ -char * +const char * TkKeysymToString( KeySym keysym) { @@ -4591,7 +4293,7 @@ TkKeysymToString( Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&nameTable, (char *)keysym); if (hPtr != NULL) { - return (char *) Tcl_GetHashValue(hPtr); + return Tcl_GetHashValue(hPtr); } #endif /* REDO_KEYSYM_LOOKUP */ @@ -4601,50 +4303,42 @@ TkKeysymToString( /* *---------------------------------------------------------------------- * - * TkCopyAndGlobalEval -- + * TkpGetBindingXEvent -- * - * This function makes a copy of a script then calls Tcl_EvalEx to - * evaluate it. It's used in situations where the execution of a command - * may cause the original command string to be reallocated. + * This function returns the XEvent associated with the currently + * executing binding. This function can only be invoked while a binding + * is executing. * * Results: - * Returns the result of evaluating script, including both a standard Tcl - * completion code and a string in the interp's result. + * Returns a pointer to the XEvent that caused the current binding code + * to be run. * * Side effects: - * Any; depends on script. + * None. * *---------------------------------------------------------------------- */ -int -TkCopyAndGlobalEval( - Tcl_Interp *interp, /* Interpreter in which to evaluate script. */ - char *script) /* Script to evaluate. */ +XEvent * +TkpGetBindingXEvent( + Tcl_Interp *interp) /* Interpreter. */ { - Tcl_DString buffer; - int code; + TkWindow *winPtr = (TkWindow *) Tk_MainWindow(interp); + BindingTable *bindPtr = winPtr->mainPtr->bindingTable; - Tcl_DStringInit(&buffer); - Tcl_DStringAppend(&buffer, script, -1); - code = Tcl_EvalEx(interp, Tcl_DStringValue(&buffer), - Tcl_DStringLength(&buffer), TCL_EVAL_GLOBAL); - Tcl_DStringFree(&buffer); - return code; + return &(bindPtr->eventRing[bindPtr->curEvent]); } /* *---------------------------------------------------------------------- * - * TkpGetBindingXEvent -- + * TkpCancelWarp -- * - * This function returns the XEvent associated with the currently - * executing binding. This function can only be invoked while a binding - * is executing. + * This function cancels an outstanding pointer warp and + * is called during tear down of the display. * * Results: - * Returns a pointer to the XEvent that caused the current binding code - * to be run. + * None. * * Side effects: * None. @@ -4652,14 +4346,14 @@ TkCopyAndGlobalEval( *---------------------------------------------------------------------- */ -XEvent * -TkpGetBindingXEvent( - Tcl_Interp *interp) /* Interpreter. */ +void +TkpCancelWarp( + TkDisplay *dispPtr) { - TkWindow *winPtr = (TkWindow *) Tk_MainWindow(interp); - BindingTable *bindPtr = (BindingTable *) winPtr->mainPtr->bindingTable; - - return &(bindPtr->eventRing[bindPtr->curEvent]); + if (dispPtr->flags & TK_DISPLAY_IN_WARP) { + Tcl_CancelIdleCall(DoWarp, dispPtr); + dispPtr->flags &= ~TK_DISPLAY_IN_WARP; + } } /* diff --git a/generic/tkBitmap.c b/generic/tkBitmap.c index f7df546..88f3e2b 100644 --- a/generic/tkBitmap.c +++ b/generic/tkBitmap.c @@ -108,6 +108,7 @@ static void BitmapInit(TkDisplay *dispPtr); static void DupBitmapObjProc(Tcl_Obj *srcObjPtr, Tcl_Obj *dupObjPtr); static void FreeBitmap(TkBitmap *bitmapPtr); +static void FreeBitmapObj(Tcl_Obj *objPtr); static void FreeBitmapObjProc(Tcl_Obj *objPtr); static TkBitmap * GetBitmap(Tcl_Interp *interp, Tk_Window tkwin, const char *name); @@ -120,7 +121,7 @@ static void InitBitmapObj(Tcl_Obj *objPtr); * field of the Tcl_Obj points to a TkBitmap object. */ -Tcl_ObjType tkBitmapObjType = { +const Tcl_ObjType tkBitmapObjType = { "bitmap", /* name */ FreeBitmapObjProc, /* freeIntRepProc */ DupBitmapObjProc, /* dupIntRepProc */ @@ -166,7 +167,7 @@ Tk_AllocBitmapFromObj( if (objPtr->typePtr != &tkBitmapObjType) { InitBitmapObj(objPtr); } - bitmapPtr = (TkBitmap *) objPtr->internalRep.twoPtrValue.ptr1; + bitmapPtr = objPtr->internalRep.twoPtrValue.ptr1; /* * If the object currently points to a TkBitmap, see if it's the one we @@ -180,7 +181,7 @@ Tk_AllocBitmapFromObj( * longer in use. Clear the reference. */ - FreeBitmapObjProc(objPtr); + FreeBitmapObj(objPtr); bitmapPtr = NULL; } else if ((Tk_Display(tkwin) == bitmapPtr->display) && (Tk_ScreenNumber(tkwin) == bitmapPtr->screenNum)) { @@ -196,16 +197,16 @@ Tk_AllocBitmapFromObj( */ if (bitmapPtr != NULL) { - TkBitmap *firstBitmapPtr = (TkBitmap *) - Tcl_GetHashValue(bitmapPtr->nameHashPtr); - FreeBitmapObjProc(objPtr); + TkBitmap *firstBitmapPtr = Tcl_GetHashValue(bitmapPtr->nameHashPtr); + + FreeBitmapObj(objPtr); for (bitmapPtr = firstBitmapPtr; bitmapPtr != NULL; bitmapPtr = bitmapPtr->nextPtr) { if ((Tk_Display(tkwin) == bitmapPtr->display) && (Tk_ScreenNumber(tkwin) == bitmapPtr->screenNum)) { bitmapPtr->resourceRefCount++; bitmapPtr->objRefCount++; - objPtr->internalRep.twoPtrValue.ptr1 = (void *) bitmapPtr; + objPtr->internalRep.twoPtrValue.ptr1 = bitmapPtr; return bitmapPtr->bitmap; } } @@ -216,7 +217,7 @@ Tk_AllocBitmapFromObj( */ bitmapPtr = GetBitmap(interp, tkwin, Tcl_GetString(objPtr)); - objPtr->internalRep.twoPtrValue.ptr1 = (void *) bitmapPtr; + objPtr->internalRep.twoPtrValue.ptr1 = bitmapPtr; if (bitmapPtr == NULL) { return None; } @@ -306,7 +307,7 @@ GetBitmap( Pixmap bitmap; int isNew, width = 0, height = 0, dummy2; TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (!dispPtr->bitmapInit) { @@ -316,11 +317,11 @@ GetBitmap( nameHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapNameTable, string, &isNew); if (!isNew) { - existingBitmapPtr = (TkBitmap *) Tcl_GetHashValue(nameHashPtr); + existingBitmapPtr = Tcl_GetHashValue(nameHashPtr); for (bitmapPtr = existingBitmapPtr; bitmapPtr != NULL; bitmapPtr = bitmapPtr->nextPtr) { - if ( (Tk_Display(tkwin) == bitmapPtr->display) && - (Tk_ScreenNumber(tkwin) == bitmapPtr->screenNum) ) { + if ((Tk_Display(tkwin) == bitmapPtr->display) && + (Tk_ScreenNumber(tkwin) == bitmapPtr->screenNum)) { bitmapPtr->resourceRefCount++; return bitmapPtr; } @@ -341,8 +342,10 @@ GetBitmap( int result; if (Tcl_IsSafe(interp)) { - Tcl_AppendResult(interp, "can't specify bitmap with '@' in a", - " safe interpreter", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "can't specify bitmap with '@' in a safe interpreter", + -1)); + Tcl_SetErrorCode(interp, "TK", "SAFE", "BITMAP_FILE", NULL); goto error; } @@ -362,8 +365,9 @@ GetBitmap( &bitmap, &dummy2, &dummy2); if (result != BitmapSuccess) { if (interp != NULL) { - Tcl_AppendResult(interp, "error reading bitmap file \"", - string, "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "error reading bitmap file \"%s\"", string)); + Tcl_SetErrorCode(interp, "TK", "BITMAP", "FILE_ERROR", NULL); } Tcl_DStringFree(&buffer); goto error; @@ -383,13 +387,15 @@ GetBitmap( if (bitmap == None) { if (interp != NULL) { - Tcl_AppendResult(interp, "bitmap \"", string, - "\" not defined", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bitmap \"%s\" not defined", string)); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "BITMAP", string, + NULL); } goto error; } } else { - predefPtr = (TkPredefBitmap *) Tcl_GetHashValue(predefHashPtr); + predefPtr = Tcl_GetHashValue(predefHashPtr); width = predefPtr->width; height = predefPtr->height; if (predefPtr->native) { @@ -410,7 +416,7 @@ GetBitmap( * Add information about this bitmap to our database. */ - bitmapPtr = (TkBitmap *) ckalloc(sizeof(TkBitmap)); + bitmapPtr = ckalloc(sizeof(TkBitmap)); bitmapPtr->bitmap = bitmap; bitmapPtr->width = width; bitmapPtr->height = height; @@ -461,14 +467,14 @@ Tk_DefineBitmap( Tcl_Interp *interp, /* Interpreter to use for error reporting. */ const char *name, /* Name to use for bitmap. Must not already be * defined as a bitmap. */ - const char *source, /* Address of bits for bitmap. */ + const void *source, /* Address of bits for bitmap. */ int width, /* Width of bitmap. */ int height) /* Height of bitmap. */ { int isNew; Tcl_HashEntry *predefHashPtr; TkPredefBitmap *predefPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* @@ -486,11 +492,12 @@ Tk_DefineBitmap( predefHashPtr = Tcl_CreateHashEntry(&tsdPtr->predefBitmapTable, name, &isNew); if (!isNew) { - Tcl_AppendResult(interp, "bitmap \"", name, "\" is already defined", - NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bitmap \"%s\" is already defined", name)); + Tcl_SetErrorCode(interp, "TK", "BITMAP", "EXISTS", NULL); return TCL_ERROR; } - predefPtr = (TkPredefBitmap *) ckalloc(sizeof(TkPredefBitmap)); + predefPtr = ckalloc(sizeof(TkPredefBitmap)); predefPtr->source = source; predefPtr->width = width; predefPtr->height = height; @@ -533,7 +540,7 @@ Tk_NameOfBitmap( if (idHashPtr == NULL) { goto unknown; } - bitmapPtr = (TkBitmap *) Tcl_GetHashValue(idHashPtr); + bitmapPtr = Tcl_GetHashValue(idHashPtr); return bitmapPtr->nameHashPtr->key.string; } @@ -575,7 +582,7 @@ Tk_SizeOfBitmap( if (idHashPtr == NULL) { goto unknownBitmap; } - bitmapPtr = (TkBitmap *) Tcl_GetHashValue(idHashPtr); + bitmapPtr = Tcl_GetHashValue(idHashPtr); *widthPtr = bitmapPtr->width; *heightPtr = bitmapPtr->height; } @@ -612,7 +619,7 @@ FreeBitmap( Tk_FreePixmap(bitmapPtr->display, bitmapPtr->bitmap); Tcl_DeleteHashEntry(bitmapPtr->idHashPtr); - prevPtr = (TkBitmap *) Tcl_GetHashValue(bitmapPtr->nameHashPtr); + prevPtr = Tcl_GetHashValue(bitmapPtr->nameHashPtr); if (prevPtr == bitmapPtr) { if (bitmapPtr->nextPtr == NULL) { Tcl_DeleteHashEntry(bitmapPtr->nameHashPtr); @@ -626,7 +633,7 @@ FreeBitmap( prevPtr->nextPtr = bitmapPtr->nextPtr; } if (bitmapPtr->objRefCount == 0) { - ckfree((char *) bitmapPtr); + ckfree(bitmapPtr); } } @@ -664,7 +671,7 @@ Tk_FreeBitmap( if (idHashPtr == NULL) { Tcl_Panic("Tk_FreeBitmap received unknown bitmap argument"); } - FreeBitmap((TkBitmap *) Tcl_GetHashValue(idHashPtr)); + FreeBitmap(Tcl_GetHashValue(idHashPtr)); } /* @@ -700,7 +707,7 @@ Tk_FreeBitmapFromObj( /* *--------------------------------------------------------------------------- * - * FreeBitmapObjProc -- + * FreeBitmapObjProc, FreeBitmapObj -- * * This proc is called to release an object reference to a bitmap. * Called when the object's internal rep is released or when the cached @@ -720,13 +727,21 @@ static void FreeBitmapObjProc( Tcl_Obj *objPtr) /* The object we are releasing. */ { - TkBitmap *bitmapPtr = (TkBitmap *) objPtr->internalRep.twoPtrValue.ptr1; + FreeBitmapObj(objPtr); + objPtr->typePtr = NULL; +} + +static void +FreeBitmapObj( + Tcl_Obj *objPtr) /* The object we are releasing. */ +{ + TkBitmap *bitmapPtr = objPtr->internalRep.twoPtrValue.ptr1; if (bitmapPtr != NULL) { bitmapPtr->objRefCount--; if ((bitmapPtr->objRefCount == 0) && (bitmapPtr->resourceRefCount == 0)) { - ckfree((char *) bitmapPtr); + ckfree(bitmapPtr); } objPtr->internalRep.twoPtrValue.ptr1 = NULL; } @@ -755,10 +770,10 @@ DupBitmapObjProc( Tcl_Obj *srcObjPtr, /* The object we are copying from. */ Tcl_Obj *dupObjPtr) /* The object we are copying to. */ { - TkBitmap *bitmapPtr = (TkBitmap *) srcObjPtr->internalRep.twoPtrValue.ptr1; + TkBitmap *bitmapPtr = srcObjPtr->internalRep.twoPtrValue.ptr1; dupObjPtr->typePtr = srcObjPtr->typePtr; - dupObjPtr->internalRep.twoPtrValue.ptr1 = (void *) bitmapPtr; + dupObjPtr->internalRep.twoPtrValue.ptr1 = bitmapPtr; if (bitmapPtr != NULL) { bitmapPtr->objRefCount++; @@ -796,7 +811,7 @@ Pixmap Tk_GetBitmapFromData( Tcl_Interp *interp, /* Interpreter to use for error reporting. */ Tk_Window tkwin, /* Window in which bitmap will be used. */ - const char *source, /* Bitmap data for bitmap shape. */ + const void *source, /* Bitmap data for bitmap shape. */ int width, int height) /* Dimensions of bitmap. */ { DataKey nameKey; @@ -805,7 +820,7 @@ Tk_GetBitmapFromData( char string[16 + TCL_INTEGER_SPACE]; char *name; TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (!tsdPtr->initialized) { @@ -818,7 +833,7 @@ Tk_GetBitmapFromData( dataHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapDataTable, (char *) &nameKey, &isNew); if (!isNew) { - name = (char *) Tcl_GetHashValue(dataHashPtr); + name = Tcl_GetHashValue(dataHashPtr); } else { dispPtr->bitmapAutoNumber++; sprintf(string, "_tk%d", dispPtr->bitmapAutoNumber); @@ -896,14 +911,14 @@ GetBitmapFromObj( InitBitmapObj(objPtr); } - bitmapPtr = (TkBitmap *) objPtr->internalRep.twoPtrValue.ptr1; + bitmapPtr = objPtr->internalRep.twoPtrValue.ptr1; if (bitmapPtr != NULL) { if ((bitmapPtr->resourceRefCount > 0) && (Tk_Display(tkwin) == bitmapPtr->display)) { return bitmapPtr; } hashPtr = bitmapPtr->nameHashPtr; - FreeBitmapObjProc(objPtr); + FreeBitmapObj(objPtr); } else { hashPtr = Tcl_FindHashEntry(&dispPtr->bitmapNameTable, Tcl_GetString(objPtr)); @@ -917,10 +932,10 @@ GetBitmapFromObj( * more TkBitmap structures. See if any of them will work. */ - for (bitmapPtr = (TkBitmap *) Tcl_GetHashValue(hashPtr); - bitmapPtr != NULL; bitmapPtr = bitmapPtr->nextPtr) { + for (bitmapPtr = Tcl_GetHashValue(hashPtr); bitmapPtr != NULL; + bitmapPtr = bitmapPtr->nextPtr) { if (Tk_Display(tkwin) == bitmapPtr->display) { - objPtr->internalRep.twoPtrValue.ptr1 = (void *) bitmapPtr; + objPtr->internalRep.twoPtrValue.ptr1 = bitmapPtr; bitmapPtr->objRefCount++; return bitmapPtr; } @@ -965,7 +980,7 @@ InitBitmapObj( Tcl_GetString(objPtr); typePtr = objPtr->typePtr; if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) { - (*typePtr->freeIntRepProc)(objPtr); + typePtr->freeIntRepProc(objPtr); } objPtr->typePtr = &tkBitmapObjType; objPtr->internalRep.twoPtrValue.ptr1 = NULL; @@ -997,7 +1012,7 @@ BitmapInit( * or NULL if unavailable. */ { Tcl_Interp *dummy; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* @@ -1010,25 +1025,25 @@ BitmapInit( dummy = Tcl_CreateInterp(); Tcl_InitHashTable(&tsdPtr->predefBitmapTable, TCL_STRING_KEYS); - Tk_DefineBitmap(dummy, "error", (char *) error_bits, + Tk_DefineBitmap(dummy, "error", error_bits, error_width, error_height); - Tk_DefineBitmap(dummy, "gray75", (char *) gray75_bits, + Tk_DefineBitmap(dummy, "gray75", gray75_bits, gray75_width, gray75_height); - Tk_DefineBitmap(dummy, "gray50", (char *) gray50_bits, + Tk_DefineBitmap(dummy, "gray50", gray50_bits, gray50_width, gray50_height); - Tk_DefineBitmap(dummy, "gray25", (char *) gray25_bits, + Tk_DefineBitmap(dummy, "gray25", gray25_bits, gray25_width, gray25_height); - Tk_DefineBitmap(dummy, "gray12", (char *) gray12_bits, + Tk_DefineBitmap(dummy, "gray12", gray12_bits, gray12_width, gray12_height); - Tk_DefineBitmap(dummy, "hourglass", (char *) hourglass_bits, + Tk_DefineBitmap(dummy, "hourglass", hourglass_bits, hourglass_width, hourglass_height); - Tk_DefineBitmap(dummy, "info", (char *) info_bits, + Tk_DefineBitmap(dummy, "info", info_bits, info_width, info_height); - Tk_DefineBitmap(dummy, "questhead", (char *) questhead_bits, + Tk_DefineBitmap(dummy, "questhead", questhead_bits, questhead_width, questhead_height); - Tk_DefineBitmap(dummy, "question", (char *) question_bits, + Tk_DefineBitmap(dummy, "question", question_bits, question_width, question_height); - Tk_DefineBitmap(dummy, "warning", (char *) warning_bits, + Tk_DefineBitmap(dummy, "warning", warning_bits, warning_width, warning_height); TkpDefineNativeBitmaps(); @@ -1089,7 +1104,7 @@ TkReadBitmapFile( { char *data; - data = TkGetBitmapData(NULL, NULL, (char *) filename, + data = TkGetBitmapData(NULL, NULL, filename, (int *) width_return, (int *) height_return, x_hot_return, y_hot_return); if (data == NULL) { @@ -1125,7 +1140,7 @@ Tcl_Obj * TkDebugBitmap( Tk_Window tkwin, /* The window in which the bitmap will be used * (not currently used). */ - char *name) /* Name of the desired color. */ + const char *name) /* Name of the desired color. */ { TkBitmap *bitmapPtr; Tcl_HashEntry *hashPtr; @@ -1135,7 +1150,7 @@ TkDebugBitmap( resultPtr = Tcl_NewObj(); hashPtr = Tcl_FindHashEntry(&dispPtr->bitmapNameTable, name); if (hashPtr != NULL) { - bitmapPtr = (TkBitmap *) Tcl_GetHashValue(hashPtr); + bitmapPtr = Tcl_GetHashValue(hashPtr); if (bitmapPtr == NULL) { Tcl_Panic("TkDebugBitmap found empty hash table entry"); } @@ -1175,7 +1190,7 @@ TkDebugBitmap( Tcl_HashTable * TkGetBitmapPredefTable(void) { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); return &tsdPtr->predefBitmapTable; diff --git a/generic/tkBusy.c b/generic/tkBusy.c new file mode 100644 index 0000000..7bd6262 --- /dev/null +++ b/generic/tkBusy.c @@ -0,0 +1,931 @@ +/* + * tkBusy.c -- + * + * This file provides functions that implement busy for Tk. + * + * Copyright 1993-1998 Lucent Technologies, Inc. + * + * The "busy" command was created by George Howlett. Adapted for + * integration into Tk by Jos Decoster and Donal K. Fellows. + * + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ + +#include "tkInt.h" +#include "tkBusy.h" +#include "default.h" + +/* + * Things about the busy system that may be configured. Note that on some + * platforms this may or may not have an effect. + */ + +static const Tk_OptionSpec busyOptionSpecs[] = { + {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", + DEF_BUSY_CURSOR, -1, Tk_Offset(Busy, cursor), + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0} +}; + +/* + * Forward declarations of functions defined in this file. + */ + +static void BusyEventProc(ClientData clientData, + XEvent *eventPtr); +static void BusyGeometryProc(ClientData clientData, + Tk_Window tkwin); +static void BusyCustodyProc(ClientData clientData, + Tk_Window tkwin); +static int ConfigureBusy(Tcl_Interp *interp, Busy *busyPtr, + int objc, Tcl_Obj *const objv[]); +static Busy * CreateBusy(Tcl_Interp *interp, Tk_Window tkRef); +static void DestroyBusy(void *dataPtr); +static void DoConfigureNotify(Tk_FakeWin *winPtr); +static inline Tk_Window FirstChild(Tk_Window parent); +static Busy * GetBusy(Tcl_Interp *interp, + Tcl_HashTable *busyTablePtr, + Tcl_Obj *const windowObj); +static int HoldBusy(Tcl_HashTable *busyTablePtr, + Tcl_Interp *interp, Tcl_Obj *const windowObj, + int configObjc, Tcl_Obj *const configObjv[]); +static void MakeTransparentWindowExist(Tk_Window tkwin, + Window parent); +static inline Tk_Window NextChild(Tk_Window tkwin); +static void RefWinEventProc(ClientData clientData, + register XEvent *eventPtr); +static inline void SetWindowInstanceData(Tk_Window tkwin, + ClientData instanceData); + +/* + * The "busy" geometry manager definition. + */ + +static Tk_GeomMgr busyMgrInfo = { + "busy", /* Name of geometry manager used by winfo */ + BusyGeometryProc, /* Procedure to for new geometry requests */ + BusyCustodyProc, /* Procedure when window is taken away */ +}; + +/* + * Helper functions, need to check if a Tcl/Tk alternative already exists. + */ + +static inline Tk_Window +FirstChild( + Tk_Window parent) +{ + struct TkWindow *parentPtr = (struct TkWindow *) parent; + + return (Tk_Window) parentPtr->childList; +} + +static inline Tk_Window +NextChild( + Tk_Window tkwin) +{ + struct TkWindow *winPtr = (struct TkWindow *) tkwin; + + if (winPtr == NULL) { + return NULL; + } + return (Tk_Window) winPtr->nextPtr; +} + +static inline void +SetWindowInstanceData( + Tk_Window tkwin, + ClientData instanceData) +{ + struct TkWindow *winPtr = (struct TkWindow *) tkwin; + + winPtr->instanceData = instanceData; +} + +/* + *---------------------------------------------------------------------- + * + * BusyCustodyProc -- + * + * This procedure is invoked when the busy window has been stolen by + * another geometry manager. The information and memory associated with + * the busy window is released. I don't know why anyone would try to pack + * a busy window, but this should keep everything sane, if it is. + * + * Results: + * None. + * + * Side effects: + * The Busy structure is freed at the next idle point. + * + *---------------------------------------------------------------------- + */ + +/* ARGSUSED */ +static void +BusyCustodyProc( + ClientData clientData, /* Information about the busy window. */ + Tk_Window tkwin) /* Not used. */ +{ + Busy *busyPtr = clientData; + + Tk_DeleteEventHandler(busyPtr->tkBusy, StructureNotifyMask, BusyEventProc, + busyPtr); + TkpHideBusyWindow(busyPtr); + busyPtr->tkBusy = NULL; + Tcl_EventuallyFree(busyPtr, (Tcl_FreeProc *)DestroyBusy); +} + +/* + *---------------------------------------------------------------------- + * + * BusyGeometryProc -- + * + * This procedure is invoked by Tk_GeometryRequest for busy windows. + * Busy windows never request geometry, so it's unlikely that this + * function will ever be called;it exists simply as a place holder for + * the GeomProc in the Geometry Manager structure. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +/* ARGSUSED */ +static void +BusyGeometryProc( + ClientData clientData, /* Information about window that got new + * preferred geometry. */ + Tk_Window tkwin) /* Other Tk-related information about the + * window. */ +{ + /* Should never get here */ +} + +/* + *---------------------------------------------------------------------- + * + * DoConfigureNotify -- + * + * Generate a ConfigureNotify event describing the current configuration + * of a window. + * + * Results: + * None. + * + * Side effects: + * An event is generated and processed by Tk_HandleEvent. + * + *---------------------------------------------------------------------- + */ + +static void +DoConfigureNotify( + Tk_FakeWin *winPtr) /* Window whose configuration was just + * changed. */ +{ + XEvent event; + + event.type = ConfigureNotify; + event.xconfigure.serial = LastKnownRequestProcessed(winPtr->display); + event.xconfigure.send_event = False; + event.xconfigure.display = winPtr->display; + event.xconfigure.event = winPtr->window; + event.xconfigure.window = winPtr->window; + event.xconfigure.x = winPtr->changes.x; + event.xconfigure.y = winPtr->changes.y; + event.xconfigure.width = winPtr->changes.width; + event.xconfigure.height = winPtr->changes.height; + event.xconfigure.border_width = winPtr->changes.border_width; + if (winPtr->changes.stack_mode == Above) { + event.xconfigure.above = winPtr->changes.sibling; + } else { + event.xconfigure.above = None; + } + event.xconfigure.override_redirect = winPtr->atts.override_redirect; + Tk_HandleEvent(&event); +} + +/* + *---------------------------------------------------------------------- + * + * RefWinEventProc -- + * + * This procedure is invoked by the Tk dispatcher for the following + * events on the reference window. If the reference and parent windows + * are the same, only the first event is important. + * + * 1) ConfigureNotify The reference window has been resized or + * moved. Move and resize the busy window to be + * the same size and position of the reference + * window. + * + * 2) DestroyNotify The reference window was destroyed. Destroy + * the busy window and the free resources used. + * + * 3) MapNotify The reference window was (re)shown. Map the + * busy window again. + * + * 4) UnmapNotify The reference window was hidden. Unmap the + * busy window. + * + * Results: + * None. + * + * Side effects: + * When the reference window gets deleted, internal structures get + * cleaned up. When it gets resized, the busy window is resized + * accordingly. If it's displayed, the busy window is displayed. And when + * it's hidden, the busy window is unmapped. + * + *---------------------------------------------------------------------- + */ + +static void +RefWinEventProc( + ClientData clientData, /* Busy window record */ + register XEvent *eventPtr) /* Event which triggered call to routine */ +{ + register Busy *busyPtr = clientData; + + switch (eventPtr->type) { + case ReparentNotify: + case DestroyNotify: + /* + * Arrange for the busy structure to be removed at a proper time. + */ + + Tcl_EventuallyFree(busyPtr, (Tcl_FreeProc *)DestroyBusy); + break; + + case ConfigureNotify: + if ((busyPtr->width != Tk_Width(busyPtr->tkRef)) || + (busyPtr->height != Tk_Height(busyPtr->tkRef)) || + (busyPtr->x != Tk_X(busyPtr->tkRef)) || + (busyPtr->y != Tk_Y(busyPtr->tkRef))) { + int x, y; + + busyPtr->width = Tk_Width(busyPtr->tkRef); + busyPtr->height = Tk_Height(busyPtr->tkRef); + busyPtr->x = Tk_X(busyPtr->tkRef); + busyPtr->y = Tk_Y(busyPtr->tkRef); + + x = y = 0; + + if (busyPtr->tkParent != busyPtr->tkRef) { + Tk_Window tkwin; + + for (tkwin = busyPtr->tkRef; (tkwin != NULL) && + (!Tk_IsTopLevel(tkwin)); tkwin = Tk_Parent(tkwin)) { + if (tkwin == busyPtr->tkParent) { + break; + } + x += Tk_X(tkwin) + Tk_Changes(tkwin)->border_width; + y += Tk_Y(tkwin) + Tk_Changes(tkwin)->border_width; + } + } + if (busyPtr->tkBusy != NULL) { + Tk_MoveResizeWindow(busyPtr->tkBusy, x, y, busyPtr->width, + busyPtr->height); + TkpShowBusyWindow(busyPtr); + } + } + break; + + case MapNotify: + if (busyPtr->tkParent != busyPtr->tkRef) { + TkpShowBusyWindow(busyPtr); + } + break; + + case UnmapNotify: + if (busyPtr->tkParent != busyPtr->tkRef) { + TkpHideBusyWindow(busyPtr); + } + break; + } +} + +/* + *---------------------------------------------------------------------- + * + * DestroyBusy -- + * + * This procedure is called from the Tk event dispatcher. It releases X + * resources and memory used by the busy window and updates the internal + * hash table. + * + * Results: + * None. + * + * Side effects: + * Memory and resources are released and the Tk event handler is removed. + * + *---------------------------------------------------------------------- + */ + +static void +DestroyBusy( + void *data) /* Busy window structure record */ +{ + register Busy *busyPtr = data; + + if (busyPtr->hashPtr != NULL) { + Tcl_DeleteHashEntry(busyPtr->hashPtr); + } + Tk_DeleteEventHandler(busyPtr->tkRef, StructureNotifyMask, + RefWinEventProc, busyPtr); + + if (busyPtr->tkBusy != NULL) { + Tk_FreeConfigOptions(data, busyPtr->optionTable, busyPtr->tkBusy); + Tk_DeleteEventHandler(busyPtr->tkBusy, StructureNotifyMask, + BusyEventProc, busyPtr); + Tk_ManageGeometry(busyPtr->tkBusy, NULL, busyPtr); + Tk_DestroyWindow(busyPtr->tkBusy); + } + ckfree(data); +} + +/* + *---------------------------------------------------------------------- + * + * BusyEventProc -- + * + * This procedure is invoked by the Tk dispatcher for events on the busy + * window itself. We're only concerned with destroy events. + * + * It might be necessary (someday) to watch resize events. Right now, I + * don't think there's any point in it. + * + * Results: + * None. + * + * Side effects: + * When a busy window is destroyed, all internal structures associated + * with it released at the next idle point. + * + *---------------------------------------------------------------------- + */ + +static void +BusyEventProc( + ClientData clientData, /* Busy window record */ + XEvent *eventPtr) /* Event which triggered call to routine */ +{ + Busy *busyPtr = clientData; + + if (eventPtr->type == DestroyNotify) { + busyPtr->tkBusy = NULL; + Tcl_EventuallyFree(busyPtr, (Tcl_FreeProc *)DestroyBusy); + } +} + +/* + *---------------------------------------------------------------------- + * + * MakeTransparentWindowExist -- + * + * Similar to Tk_MakeWindowExist but instead creates a transparent window + * to block for user events from sibling windows. + * + * Differences from Tk_MakeWindowExist. + * + * 1. This is always a "busy" window. There's never a platform-specific + * class procedure to execute instead. + * 2. The window is transparent and never will contain children, so + * colormap information is irrelevant. + * + * Results: + * None. + * + * Side effects: + * When the procedure returns, the internal window associated with tkwin + * is guaranteed to exist. This may require the window's ancestors to be + * created too. + * + *---------------------------------------------------------------------- + */ + +static void +MakeTransparentWindowExist( + Tk_Window tkwin, /* Token for window. */ + Window parent) /* Parent window. */ +{ + TkWindow *winPtr = (TkWindow *) tkwin; + Tcl_HashEntry *hPtr; + int notUsed; + TkDisplay *dispPtr; + + if (winPtr->window != None) { + return; /* Window already exists. */ + } + + /* + * Create a transparent window and put it on top. + */ + + TkpMakeTransparentWindowExist(tkwin, parent); + + if (winPtr->window == None) { + return; /* Platform didn't make Window. */ + } + + dispPtr = winPtr->dispPtr; + hPtr = Tcl_CreateHashEntry(&dispPtr->winTable, (char *) winPtr->window, + ¬Used); + Tcl_SetHashValue(hPtr, winPtr); + winPtr->dirtyAtts = 0; + winPtr->dirtyChanges = 0; + + if (!(winPtr->flags & TK_TOP_HIERARCHY)) { + TkWindow *winPtr2; + + /* + * If any siblings higher up in the stacking order have already been + * created then move this window to its rightful position in the + * stacking order. + * + * NOTE: this code ignores any changes anyone might have made to the + * sibling and stack_mode field of the window's attributes, so it + * really isn't safe for these to be manipulated except by calling + * Tk_RestackWindow. + */ + + for (winPtr2 = winPtr->nextPtr; winPtr2 != NULL; + winPtr2 = winPtr2->nextPtr) { + if ((winPtr2->window != None) && + !(winPtr2->flags & (TK_TOP_HIERARCHY|TK_REPARENTED))) { + XWindowChanges changes; + + changes.sibling = winPtr2->window; + changes.stack_mode = Below; + XConfigureWindow(winPtr->display, winPtr->window, + CWSibling | CWStackMode, &changes); + break; + } + } + } + + /* + * Issue a ConfigureNotify event if there were deferred configuration + * changes (but skip it if the window is being deleted; the + * ConfigureNotify event could cause problems if we're being called from + * Tk_DestroyWindow under some conditions). + */ + + if ((winPtr->flags & TK_NEED_CONFIG_NOTIFY) + && !(winPtr->flags & TK_ALREADY_DEAD)) { + winPtr->flags &= ~TK_NEED_CONFIG_NOTIFY; + DoConfigureNotify((Tk_FakeWin *) tkwin); + } +} + +/* + *---------------------------------------------------------------------- + * + * CreateBusy -- + * + * Creates a child transparent window that obscures its parent window + * thereby effectively blocking device events. The size and position of + * the busy window is exactly that of the reference window. + * + * We want to create sibling to the window to be blocked. If the busy + * window is a child of the window to be blocked, Enter/Leave events can + * sneak through. Futhermore under WIN32, messages of transparent windows + * are sent directly to the parent. The only exception to this are + * toplevels, since we can't make a sibling. Fortunately, toplevel + * windows rarely receive events that need blocking. + * + * Results: + * Returns a pointer to the new busy window structure. + * + * Side effects: + * When the busy window is eventually displayed, it will screen device + * events (in the area of the reference window) from reaching its parent + * window and its children. User feed back can be achieved by changing + * the cursor. + * + *---------------------------------------------------------------------- + */ + +static Busy * +CreateBusy( + Tcl_Interp *interp, /* Interpreter to report error to */ + Tk_Window tkRef) /* Window hosting the busy window */ +{ + Busy *busyPtr; + size_t length; + int x, y; + const char *fmt; + char *name; + Tk_Window tkBusy, tkChild, tkParent; + Window parent; + Tk_FakeWin *winPtr; + + busyPtr = ckalloc(sizeof(Busy)); + x = y = 0; + length = strlen(Tk_Name(tkRef)); + name = ckalloc(length + 6); + if (Tk_IsTopLevel(tkRef)) { + fmt = "_Busy"; /* Child */ + tkParent = tkRef; + } else { + Tk_Window tkwin; + + fmt = "%s_Busy"; /* Sibling */ + tkParent = Tk_Parent(tkRef); + for (tkwin = tkRef; (tkwin != NULL) && !Tk_IsTopLevel(tkwin); + tkwin = Tk_Parent(tkwin)) { + if (tkwin == tkParent) { + break; + } + x += Tk_X(tkwin) + Tk_Changes(tkwin)->border_width; + y += Tk_Y(tkwin) + Tk_Changes(tkwin)->border_width; + } + } + for (tkChild = FirstChild(tkParent); tkChild != NULL; + tkChild = NextChild(tkChild)) { + Tk_MakeWindowExist(tkChild); + } + sprintf(name, fmt, Tk_Name(tkRef)); + tkBusy = Tk_CreateWindow(interp, tkParent, name, NULL); + ckfree(name); + + if (tkBusy == NULL) { + return NULL; + } + Tk_MakeWindowExist(tkRef); + busyPtr->display = Tk_Display(tkRef); + busyPtr->interp = interp; + busyPtr->tkRef = tkRef; + busyPtr->tkParent = tkParent; + busyPtr->tkBusy = tkBusy; + busyPtr->width = Tk_Width(tkRef); + busyPtr->height = Tk_Height(tkRef); + busyPtr->x = Tk_X(tkRef); + busyPtr->y = Tk_Y(tkRef); + busyPtr->cursor = NULL; + Tk_SetClass(tkBusy, "Busy"); + busyPtr->optionTable = Tk_CreateOptionTable(interp, busyOptionSpecs); + if (Tk_InitOptions(interp, (char *) busyPtr, busyPtr->optionTable, + tkBusy) != TCL_OK) { + Tk_DestroyWindow(tkBusy); + return NULL; + } + SetWindowInstanceData(tkBusy, busyPtr); + winPtr = (Tk_FakeWin *) tkRef; + + TkpCreateBusy(winPtr, tkRef, &parent, tkParent, busyPtr); + + MakeTransparentWindowExist(tkBusy, parent); + + Tk_MoveResizeWindow(tkBusy, x, y, busyPtr->width, busyPtr->height); + + /* + * Only worry if the busy window is destroyed. + */ + + Tk_CreateEventHandler(tkBusy, StructureNotifyMask, BusyEventProc, + busyPtr); + + /* + * Indicate that the busy window's geometry is being managed. This will + * also notify us if the busy window is ever packed. + */ + + Tk_ManageGeometry(tkBusy, &busyMgrInfo, busyPtr); + if (busyPtr->cursor != NULL) { + Tk_DefineCursor(tkBusy, busyPtr->cursor); + } + + /* + * Track the reference window to see if it is resized or destroyed. + */ + + Tk_CreateEventHandler(tkRef, StructureNotifyMask, RefWinEventProc, + busyPtr); + return busyPtr; +} + +/* + *---------------------------------------------------------------------- + * + * ConfigureBusy -- + * + * This procedure is called from the Tk event dispatcher. It releases X + * resources and memory used by the busy window and updates the internal + * hash table. + * + * Results: + * None. + * + * Side effects: + * Memory and resources are released and the Tk event handler is removed. + * + *---------------------------------------------------------------------- + */ + +static int +ConfigureBusy( + Tcl_Interp *interp, + Busy *busyPtr, + int objc, + Tcl_Obj *const objv[]) +{ + Tk_Cursor oldCursor = busyPtr->cursor; + + if (Tk_SetOptions(interp, (char *) busyPtr, busyPtr->optionTable, objc, + objv, busyPtr->tkBusy, NULL, NULL) != TCL_OK) { + return TCL_ERROR; + } + if (busyPtr->cursor != oldCursor) { + if (busyPtr->cursor == NULL) { + Tk_UndefineCursor(busyPtr->tkBusy); + } else { + Tk_DefineCursor(busyPtr->tkBusy, busyPtr->cursor); + } + } + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * GetBusy -- + * + * Returns the busy window structure associated with the reference + * window, keyed by its path name. The clientData argument is the main + * window of the interpreter, used to search for the reference window in + * its own window hierarchy. + * + * Results: + * If path name represents a reference window with a busy window, a + * pointer to the busy window structure is returned. Otherwise, NULL is + * returned and an error message is left in interp->result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static Busy * +GetBusy( + Tcl_Interp *interp, /* Interpreter to look up main window of. */ + Tcl_HashTable *busyTablePtr,/* Busy hash table */ + Tcl_Obj *const windowObj) /* Path name of parent window */ +{ + Tcl_HashEntry *hPtr; + Tk_Window tkwin; + + if (TkGetWindowFromObj(interp, Tk_MainWindow(interp), windowObj, + &tkwin) != TCL_OK) { + return NULL; + } + hPtr = Tcl_FindHashEntry(busyTablePtr, (char *) tkwin); + if (hPtr == NULL) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't find busy window \"%s\"", Tcl_GetString(windowObj))); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "BUSY", + Tcl_GetString(windowObj), NULL); + return NULL; + } + return Tcl_GetHashValue(hPtr); +} + +/* + *---------------------------------------------------------------------- + * + * HoldBusy -- + * + * Creates (if necessary) and maps a busy window, thereby preventing + * device events from being be received by the parent window and its + * children. + * + * Results: + * Returns a standard TCL result. If path name represents a busy window, + * it is unmapped and TCL_OK is returned. Otherwise, TCL_ERROR is + * returned and an error message is left in interp->result. + * + * Side effects: + * The busy window is created and displayed, blocking events from the + * parent window and its children. + * + *---------------------------------------------------------------------- + */ + +static int +HoldBusy( + Tcl_HashTable *busyTablePtr,/* Busy hash table. */ + Tcl_Interp *interp, /* Interpreter to report errors to. */ + Tcl_Obj *const windowObj, /* Window name. */ + int configObjc, /* Option pairs. */ + Tcl_Obj *const configObjv[]) +{ + Tk_Window tkwin; + Tcl_HashEntry *hPtr; + Busy *busyPtr; + int isNew, result; + + if (TkGetWindowFromObj(interp, Tk_MainWindow(interp), windowObj, + &tkwin) != TCL_OK) { + return TCL_ERROR; + } + hPtr = Tcl_CreateHashEntry(busyTablePtr, (char *) tkwin, &isNew); + if (isNew) { + busyPtr = CreateBusy(interp, tkwin); + if (busyPtr == NULL) { + return TCL_ERROR; + } + Tcl_SetHashValue(hPtr, busyPtr); + busyPtr->hashPtr = hPtr; + } else { + busyPtr = Tcl_GetHashValue(hPtr); + } + + busyPtr->tablePtr = busyTablePtr; + result = ConfigureBusy(interp, busyPtr, configObjc, configObjv); + + /* + * Don't map the busy window unless the reference window is also currently + * displayed. + */ + + if (Tk_IsMapped(busyPtr->tkRef)) { + TkpShowBusyWindow(busyPtr); + } else { + TkpHideBusyWindow(busyPtr); + } + return result; +} + +/* + *---------------------------------------------------------------------- + * + * Tk_BusyObjCmd -- + * + * This function is invoked to process the "tk busy" Tcl command. See the + * user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +int +Tk_BusyObjCmd( + ClientData clientData, /* Main window associated with interpreter. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ +{ + Tk_Window tkwin = clientData; + Tcl_HashTable *busyTablePtr = &((TkWindow *) tkwin)->mainPtr->busyTable; + Busy *busyPtr; + Tcl_Obj *objPtr; + int index, result = TCL_OK; + static const char *const optionStrings[] = { + "cget", "configure", "current", "forget", "hold", "status", NULL + }; + enum options { + BUSY_CGET, BUSY_CONFIGURE, BUSY_CURRENT, BUSY_FORGET, BUSY_HOLD, + BUSY_STATUS + }; + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "options ?arg arg ...?"); + return TCL_ERROR; + } + + /* + * [tk busy <window>] command shortcut. + */ + + if (Tcl_GetString(objv[1])[0] == '.') { + if (objc%2 == 1) { + Tcl_WrongNumArgs(interp, 1, objv, "window ?option value ...?"); + return TCL_ERROR; + } + return HoldBusy(busyTablePtr, interp, objv[1], objc-2, objv+2); + } + + if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings, + sizeof(char *), "option", 0, &index) != TCL_OK) { + return TCL_ERROR; + } + switch ((enum options) index) { + case BUSY_CGET: + if (objc != 4) { + Tcl_WrongNumArgs(interp, 2, objv, "window option"); + return TCL_ERROR; + } + busyPtr = GetBusy(interp, busyTablePtr, objv[2]); + if (busyPtr == NULL) { + return TCL_ERROR; + } + Tcl_Preserve(busyPtr); + objPtr = Tk_GetOptionValue(interp, (char *) busyPtr, + busyPtr->optionTable, objv[3], busyPtr->tkBusy); + if (objPtr == NULL) { + result = TCL_ERROR; + } else { + Tcl_SetObjResult(interp, objPtr); + } + Tcl_Release(busyPtr); + return result; + + case BUSY_CONFIGURE: + if (objc < 3) { + Tcl_WrongNumArgs(interp, 2, objv, "window ?option? ?value ...?"); + return TCL_ERROR; + } + busyPtr = GetBusy(interp, busyTablePtr, objv[2]); + if (busyPtr == NULL) { + return TCL_ERROR; + } + Tcl_Preserve(busyPtr); + if (objc <= 4) { + objPtr = Tk_GetOptionInfo(interp, (char *) busyPtr, + busyPtr->optionTable, (objc == 4) ? objv[3] : NULL, + busyPtr->tkBusy); + if (objPtr == NULL) { + result = TCL_ERROR; + } else { + Tcl_SetObjResult(interp, objPtr); + } + } else { + result = ConfigureBusy(interp, busyPtr, objc-3, objv+3); + } + Tcl_Release(busyPtr); + return result; + + case BUSY_CURRENT: { + Tcl_HashEntry *hPtr; + Tcl_HashSearch cursor; + const char *pattern = (objc == 3 ? Tcl_GetString(objv[2]) : NULL); + + objPtr = Tcl_NewObj(); + for (hPtr = Tcl_FirstHashEntry(busyTablePtr, &cursor); hPtr != NULL; + hPtr = Tcl_NextHashEntry(&cursor)) { + busyPtr = Tcl_GetHashValue(hPtr); + if (pattern == NULL || + Tcl_StringMatch(Tk_PathName(busyPtr->tkRef), pattern)) { + Tcl_ListObjAppendElement(interp, objPtr, + TkNewWindowObj(busyPtr->tkRef)); + } + } + Tcl_SetObjResult(interp, objPtr); + return TCL_OK; + } + + case BUSY_FORGET: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "window"); + return TCL_ERROR; + } + busyPtr = GetBusy(interp, busyTablePtr, objv[2]); + if (busyPtr == NULL) { + return TCL_ERROR; + } + TkpHideBusyWindow(busyPtr); + Tcl_EventuallyFree(busyPtr, (Tcl_FreeProc *)DestroyBusy); + return TCL_OK; + + case BUSY_HOLD: + if (objc < 3 || objc%2 != 1) { + Tcl_WrongNumArgs(interp, 2, objv, "window ?option value ...?"); + return TCL_ERROR; + } + return HoldBusy(busyTablePtr, interp, objv[2], objc-3, objv+3); + + case BUSY_STATUS: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "window"); + return TCL_ERROR; + } + Tcl_SetObjResult(interp, Tcl_NewBooleanObj( + GetBusy(interp, busyTablePtr, objv[2]) != NULL)); + return TCL_OK; + } + + Tcl_Panic("unhandled option: %d", index); + return TCL_ERROR; /* Unreachable */ +} + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/generic/tkBusy.h b/generic/tkBusy.h new file mode 100644 index 0000000..9e6b69b --- /dev/null +++ b/generic/tkBusy.h @@ -0,0 +1,41 @@ +/* + * tkBusy.h -- + * + * This file defines the type of the structure describing a busy window. + * + * Copyright 1993-1998 Lucent Technologies, Inc. + * + * The "busy" command was created by George Howlett. Adapted for + * integration into Tk by Jos Decoster and Donal K. Fellows. + * + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ + +typedef struct Busy { + Display *display; /* Display of busy window */ + Tcl_Interp *interp; /* Interpreter where "busy" command was + * created. It's used to key the searches in + * the window hierarchy. See the "windows" + * command. */ + Tk_Window tkBusy; /* Busy window: Transparent window used to + * block delivery of events to windows + * underneath it. */ + Tk_Window tkParent; /* Parent window of the busy window. It may be + * the reference window (if the reference is a + * toplevel) or a mutual ancestor of the + * reference window */ + Tk_Window tkRef; /* Reference window of the busy window. It is + * used to manage the size and position of the + * busy window. */ + int x, y; /* Position of the reference window */ + int width, height; /* Size of the reference window. Retained to + * know if the reference window has been + * reconfigured to a new size. */ + int menuBar; /* Menu bar flag. */ + Tk_Cursor cursor; /* Cursor for the busy window. */ + Tcl_HashEntry *hashPtr; /* Used the delete the busy window entry out + * of the global hash table. */ + Tcl_HashTable *tablePtr; + Tk_OptionTable optionTable; +} Busy; diff --git a/generic/tkButton.c b/generic/tkButton.c index 0de949c..0d760b0 100644 --- a/generic/tkButton.c +++ b/generic/tkButton.c @@ -71,19 +71,19 @@ char tkDefLabelPady[TCL_INTEGER_SPACE] = DEF_LABCHKRAD_PADY; static const Tk_OptionSpec labelOptionSpecs[] = { {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground", DEF_BUTTON_ACTIVE_BG_COLOR, -1, Tk_Offset(TkButton, activeBorder), - 0, (ClientData) DEF_BUTTON_ACTIVE_BG_MONO, 0}, + 0, DEF_BUTTON_ACTIVE_BG_MONO, 0}, {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background", DEF_BUTTON_ACTIVE_FG_COLOR, -1, Tk_Offset(TkButton, activeFg), - TK_OPTION_NULL_OK, (ClientData) DEF_BUTTON_ACTIVE_FG_MONO, 0}, + TK_OPTION_NULL_OK, DEF_BUTTON_ACTIVE_FG_MONO, 0}, {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", DEF_BUTTON_ANCHOR, -1, Tk_Offset(TkButton, anchor), 0, 0, 0}, {TK_OPTION_BORDER, "-background", "background", "Background", DEF_BUTTON_BG_COLOR, -1, Tk_Offset(TkButton, normalBorder), - 0, (ClientData) DEF_BUTTON_BG_MONO, 0}, + 0, DEF_BUTTON_BG_MONO, 0}, {TK_OPTION_SYNONYM, "-bd", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-borderwidth", 0}, + NULL, 0, -1, 0, "-borderwidth", 0}, {TK_OPTION_SYNONYM, "-bg", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-background", 0}, + NULL, 0, -1, 0, "-background", 0}, {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap", DEF_BUTTON_BITMAP, -1, Tk_Offset(TkButton, bitmap), TK_OPTION_NULL_OK, 0, 0}, @@ -92,7 +92,7 @@ static const Tk_OptionSpec labelOptionSpecs[] = { Tk_Offset(TkButton, borderWidth), 0, 0, 0}, {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound", DEF_BUTTON_COMPOUND, -1, Tk_Offset(TkButton, compound), 0, - (ClientData) compoundStrings, 0}, + compoundStrings, 0}, {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", DEF_BUTTON_CURSOR, -1, Tk_Offset(TkButton, cursor), TK_OPTION_NULL_OK, 0, 0}, @@ -101,7 +101,7 @@ static const Tk_OptionSpec labelOptionSpecs[] = { -1, Tk_Offset(TkButton, disabledFg), TK_OPTION_NULL_OK, (ClientData) DEF_BUTTON_DISABLED_FG_MONO, 0}, {TK_OPTION_SYNONYM, "-fg", "foreground", NULL, - NULL, 0, -1, 0, (ClientData) "-foreground", 0}, + NULL, 0, -1, 0, "-foreground", 0}, {TK_OPTION_FONT, "-font", "font", "Font", DEF_BUTTON_FONT, -1, Tk_Offset(TkButton, tkfont), 0, 0, 0}, {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground", @@ -134,7 +134,7 @@ static const Tk_OptionSpec labelOptionSpecs[] = { DEF_LABCHKRAD_RELIEF, -1, Tk_Offset(TkButton, relief), 0, 0, 0}, {TK_OPTION_STRING_TABLE, "-state", "state", "State", DEF_BUTTON_STATE, -1, Tk_Offset(TkButton, state), - 0, (ClientData) stateStrings, 0}, + 0, stateStrings, 0}, {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", DEF_LABEL_TAKE_FOCUS, Tk_Offset(TkButton, takeFocusPtr), -1, TK_OPTION_NULL_OK, 0, 0}, @@ -150,25 +150,25 @@ static const Tk_OptionSpec labelOptionSpecs[] = { {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength", DEF_BUTTON_WRAP_LENGTH, Tk_Offset(TkButton, wrapLengthPtr), Tk_Offset(TkButton, wrapLength), 0, 0, 0}, - {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0} + {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0} }; static const Tk_OptionSpec buttonOptionSpecs[] = { {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground", DEF_BUTTON_ACTIVE_BG_COLOR, -1, Tk_Offset(TkButton, activeBorder), - 0, (ClientData) DEF_BUTTON_ACTIVE_BG_MONO, 0}, + 0, DEF_BUTTON_ACTIVE_BG_MONO, 0}, {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background", DEF_BUTTON_ACTIVE_FG_COLOR, -1, Tk_Offset(TkButton, activeFg), - TK_OPTION_NULL_OK, (ClientData) DEF_BUTTON_ACTIVE_FG_MONO, 0}, + TK_OPTION_NULL_OK, DEF_BUTTON_ACTIVE_FG_MONO, 0}, {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", DEF_BUTTON_ANCHOR, -1, Tk_Offset(TkButton, anchor), 0, 0, 0}, {TK_OPTION_BORDER, "-background", "background", "Background", DEF_BUTTON_BG_COLOR, -1, Tk_Offset(TkButton, normalBorder), - 0, (ClientData) DEF_BUTTON_BG_MONO, 0}, + 0, DEF_BUTTON_BG_MONO, 0}, {TK_OPTION_SYNONYM, "-bd", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-borderwidth", 0}, + NULL, 0, -1, 0, "-borderwidth", 0}, {TK_OPTION_SYNONYM, "-bg", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-background", 0}, + NULL, 0, -1, 0, "-background", 0}, {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap", DEF_BUTTON_BITMAP, -1, Tk_Offset(TkButton, bitmap), TK_OPTION_NULL_OK, 0, 0}, @@ -180,19 +180,19 @@ static const Tk_OptionSpec buttonOptionSpecs[] = { TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound", DEF_BUTTON_COMPOUND, -1, Tk_Offset(TkButton, compound), 0, - (ClientData) compoundStrings, 0}, + compoundStrings, 0}, {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", DEF_BUTTON_CURSOR, -1, Tk_Offset(TkButton, cursor), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING_TABLE, "-default", "default", "Default", DEF_BUTTON_DEFAULT, -1, Tk_Offset(TkButton, defaultState), - 0, (ClientData) defaultStrings, 0}, + 0, defaultStrings, 0}, {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground", "DisabledForeground", DEF_BUTTON_DISABLED_FG_COLOR, -1, Tk_Offset(TkButton, disabledFg), TK_OPTION_NULL_OK, (ClientData) DEF_BUTTON_DISABLED_FG_MONO, 0}, {TK_OPTION_SYNONYM, "-fg", "foreground", NULL, - NULL, 0, -1, 0, (ClientData) "-foreground", 0}, + NULL, 0, -1, 0, "-foreground", 0}, {TK_OPTION_FONT, "-font", "font", "Font", DEF_BUTTON_FONT, -1, Tk_Offset(TkButton, tkfont), 0, 0, 0}, {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground", @@ -235,7 +235,7 @@ static const Tk_OptionSpec buttonOptionSpecs[] = { 0, 0, 0}, {TK_OPTION_STRING_TABLE, "-state", "state", "State", DEF_BUTTON_STATE, -1, Tk_Offset(TkButton, state), - 0, (ClientData) stateStrings, 0}, + 0, stateStrings, 0}, {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", DEF_BUTTON_TAKE_FOCUS, Tk_Offset(TkButton, takeFocusPtr), -1, TK_OPTION_NULL_OK, 0, 0}, @@ -257,19 +257,19 @@ static const Tk_OptionSpec buttonOptionSpecs[] = { static const Tk_OptionSpec checkbuttonOptionSpecs[] = { {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground", DEF_BUTTON_ACTIVE_BG_COLOR, -1, Tk_Offset(TkButton, activeBorder), - 0, (ClientData) DEF_BUTTON_ACTIVE_BG_MONO, 0}, + 0, DEF_BUTTON_ACTIVE_BG_MONO, 0}, {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background", DEF_CHKRAD_ACTIVE_FG_COLOR, -1, Tk_Offset(TkButton, activeFg), - TK_OPTION_NULL_OK, (ClientData) DEF_BUTTON_ACTIVE_FG_MONO, 0}, + TK_OPTION_NULL_OK, DEF_BUTTON_ACTIVE_FG_MONO, 0}, {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", DEF_BUTTON_ANCHOR, -1, Tk_Offset(TkButton, anchor), 0, 0, 0}, {TK_OPTION_BORDER, "-background", "background", "Background", DEF_BUTTON_BG_COLOR, -1, Tk_Offset(TkButton, normalBorder), - 0, (ClientData) DEF_BUTTON_BG_MONO, 0}, + 0, DEF_BUTTON_BG_MONO, 0}, {TK_OPTION_SYNONYM, "-bd", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-borderwidth", 0}, + NULL, 0, -1, 0, "-borderwidth", 0}, {TK_OPTION_SYNONYM, "-bg", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-background", 0}, + NULL, 0, -1, 0, "-background", 0}, {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap", DEF_BUTTON_BITMAP, -1, Tk_Offset(TkButton, bitmap), TK_OPTION_NULL_OK, 0, 0}, @@ -281,7 +281,7 @@ static const Tk_OptionSpec checkbuttonOptionSpecs[] = { TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound", DEF_BUTTON_COMPOUND, -1, Tk_Offset(TkButton, compound), 0, - (ClientData) compoundStrings, 0}, + compoundStrings, 0}, {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", DEF_BUTTON_CURSOR, -1, Tk_Offset(TkButton, cursor), TK_OPTION_NULL_OK, 0, 0}, @@ -290,7 +290,7 @@ static const Tk_OptionSpec checkbuttonOptionSpecs[] = { -1, Tk_Offset(TkButton, disabledFg), TK_OPTION_NULL_OK, (ClientData) DEF_BUTTON_DISABLED_FG_MONO, 0}, {TK_OPTION_SYNONYM, "-fg", "foreground", NULL, - NULL, 0, -1, 0, (ClientData) "-foreground", 0}, + NULL, 0, -1, 0, "-foreground", 0}, {TK_OPTION_FONT, "-font", "font", "Font", DEF_BUTTON_FONT, -1, Tk_Offset(TkButton, tkfont), 0, 0, 0}, {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground", @@ -334,13 +334,13 @@ static const Tk_OptionSpec checkbuttonOptionSpecs[] = { DEF_LABCHKRAD_RELIEF, -1, Tk_Offset(TkButton, relief), 0, 0, 0}, {TK_OPTION_BORDER, "-selectcolor", "selectColor", "Background", DEF_BUTTON_SELECT_COLOR, -1, Tk_Offset(TkButton, selectBorder), - TK_OPTION_NULL_OK, (ClientData) DEF_BUTTON_SELECT_MONO, 0}, + TK_OPTION_NULL_OK, DEF_BUTTON_SELECT_MONO, 0}, {TK_OPTION_STRING, "-selectimage", "selectImage", "SelectImage", DEF_BUTTON_SELECT_IMAGE, Tk_Offset(TkButton, selectImagePtr), -1, TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING_TABLE, "-state", "state", "State", DEF_BUTTON_STATE, -1, Tk_Offset(TkButton, state), - 0, (ClientData) stateStrings, 0}, + 0, stateStrings, 0}, {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", DEF_BUTTON_TAKE_FOCUS, Tk_Offset(TkButton, takeFocusPtr), -1, TK_OPTION_NULL_OK, 0, 0}, @@ -370,19 +370,19 @@ static const Tk_OptionSpec checkbuttonOptionSpecs[] = { static const Tk_OptionSpec radiobuttonOptionSpecs[] = { {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground", DEF_BUTTON_ACTIVE_BG_COLOR, -1, Tk_Offset(TkButton, activeBorder), - 0, (ClientData) DEF_BUTTON_ACTIVE_BG_MONO, 0}, + 0, DEF_BUTTON_ACTIVE_BG_MONO, 0}, {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background", DEF_CHKRAD_ACTIVE_FG_COLOR, -1, Tk_Offset(TkButton, activeFg), - TK_OPTION_NULL_OK, (ClientData) DEF_BUTTON_ACTIVE_FG_MONO, 0}, + TK_OPTION_NULL_OK, DEF_BUTTON_ACTIVE_FG_MONO, 0}, {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", DEF_BUTTON_ANCHOR, -1, Tk_Offset(TkButton, anchor), 0, 0, 0}, {TK_OPTION_BORDER, "-background", "background", "Background", DEF_BUTTON_BG_COLOR, -1, Tk_Offset(TkButton, normalBorder), - 0, (ClientData) DEF_BUTTON_BG_MONO, 0}, + 0, DEF_BUTTON_BG_MONO, 0}, {TK_OPTION_SYNONYM, "-bd", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-borderwidth", 0}, + NULL, 0, -1, 0, "-borderwidth", 0}, {TK_OPTION_SYNONYM, "-bg", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-background", 0}, + NULL, 0, -1, 0, "-background", 0}, {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap", DEF_BUTTON_BITMAP, -1, Tk_Offset(TkButton, bitmap), TK_OPTION_NULL_OK, 0, 0}, @@ -394,7 +394,7 @@ static const Tk_OptionSpec radiobuttonOptionSpecs[] = { TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound", DEF_BUTTON_COMPOUND, -1, Tk_Offset(TkButton, compound), 0, - (ClientData) compoundStrings, 0}, + compoundStrings, 0}, {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", DEF_BUTTON_CURSOR, -1, Tk_Offset(TkButton, cursor), TK_OPTION_NULL_OK, 0, 0}, @@ -403,7 +403,7 @@ static const Tk_OptionSpec radiobuttonOptionSpecs[] = { -1, Tk_Offset(TkButton, disabledFg), TK_OPTION_NULL_OK, (ClientData) DEF_BUTTON_DISABLED_FG_MONO, 0}, {TK_OPTION_SYNONYM, "-fg", "foreground", NULL, - NULL, 0, -1, 0, (ClientData) "-foreground", 0}, + NULL, 0, -1, 0, "-foreground", 0}, {TK_OPTION_FONT, "-font", "font", "Font", DEF_BUTTON_FONT, -1, Tk_Offset(TkButton, tkfont), 0, 0, 0}, {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground", @@ -444,13 +444,13 @@ static const Tk_OptionSpec radiobuttonOptionSpecs[] = { DEF_LABCHKRAD_RELIEF, -1, Tk_Offset(TkButton, relief), 0, 0, 0}, {TK_OPTION_BORDER, "-selectcolor", "selectColor", "Background", DEF_BUTTON_SELECT_COLOR, -1, Tk_Offset(TkButton, selectBorder), - TK_OPTION_NULL_OK, (ClientData) DEF_BUTTON_SELECT_MONO, 0}, + TK_OPTION_NULL_OK, DEF_BUTTON_SELECT_MONO, 0}, {TK_OPTION_STRING, "-selectimage", "selectImage", "SelectImage", DEF_BUTTON_SELECT_IMAGE, Tk_Offset(TkButton, selectImagePtr), -1, TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING_TABLE, "-state", "state", "State", DEF_BUTTON_STATE, -1, Tk_Offset(TkButton, state), - 0, (ClientData) stateStrings, 0}, + 0, stateStrings, 0}, {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", DEF_BUTTON_TAKE_FOCUS, Tk_Offset(TkButton, takeFocusPtr), -1, TK_OPTION_NULL_OK, 0, 0}, @@ -497,7 +497,7 @@ static const Tk_OptionSpec *const optionSpecs[] = { * enumerated type used to dispatch the widget command. */ -static const char *commandNames[][8] = { +static const char *const commandNames[][8] = { {"cget", "configure", NULL}, {"cget", "configure", "flash", "invoke", NULL}, {"cget", "configure", "deselect", "flash", "invoke", "select", @@ -508,7 +508,7 @@ enum command { COMMAND_CGET, COMMAND_CONFIGURE, COMMAND_DESELECT, COMMAND_FLASH, COMMAND_INVOKE, COMMAND_SELECT, COMMAND_TOGGLE }; -static enum command map[][8] = { +static const enum command map[][8] = { {COMMAND_CGET, COMMAND_CONFIGURE}, {COMMAND_CGET, COMMAND_CONFIGURE, COMMAND_FLASH, COMMAND_INVOKE}, {COMMAND_CGET, COMMAND_CONFIGURE, COMMAND_DESELECT, COMMAND_FLASH, @@ -639,7 +639,7 @@ ButtonCreate( TkButton *butPtr; Tk_OptionTable optionTable; Tk_Window tkwin; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (!tsdPtr->defaultsInitialized) { @@ -648,7 +648,7 @@ ButtonCreate( } if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?"); + Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?"); return TCL_ERROR; } @@ -672,7 +672,7 @@ ButtonCreate( Tk_SetClass(tkwin, classNames[type]); butPtr = TkpCreateButton(tkwin); - Tk_SetClassProcs(tkwin, &tkpButtonProcs, (ClientData) butPtr); + Tk_SetClassProcs(tkwin, &tkpButtonProcs, butPtr); /* * Initialize the data structure for the button. @@ -682,7 +682,7 @@ ButtonCreate( butPtr->display = Tk_Display(tkwin); butPtr->interp = interp; butPtr->widgetCmd = Tcl_CreateObjCommand(interp, Tk_PathName(tkwin), - ButtonWidgetObjCmd, (ClientData) butPtr, ButtonCmdDeletedProc); + ButtonWidgetObjCmd, butPtr, ButtonCmdDeletedProc); butPtr->type = type; butPtr->optionTable = optionTable; butPtr->textPtr = NULL; @@ -747,7 +747,7 @@ ButtonCreate( Tk_CreateEventHandler(butPtr->tkwin, ExposureMask|StructureNotifyMask|FocusChangeMask, - ButtonEventProc, (ClientData) butPtr); + ButtonEventProc, butPtr); if (Tk_InitOptions(interp, (char *) butPtr, optionTable, tkwin) != TCL_OK) { @@ -759,8 +759,7 @@ ButtonCreate( return TCL_ERROR; } - Tcl_SetStringObj(Tcl_GetObjResult(interp), Tk_PathName(butPtr->tkwin), - -1); + Tcl_SetObjResult(interp, TkNewWindowObj(butPtr->tkwin)); return TCL_OK; } @@ -789,21 +788,21 @@ ButtonWidgetObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument values. */ { - TkButton *butPtr = (TkButton *) clientData; + TkButton *butPtr = clientData; int index; int result; Tcl_Obj *objPtr; if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?"); + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); return TCL_ERROR; } - result = Tcl_GetIndexFromObj(interp, objv[1], commandNames[butPtr->type], - "option", 0, &index); + result = Tcl_GetIndexFromObjStruct(interp, objv[1], commandNames[butPtr->type], + sizeof(char *), "option", 0, &index); if (result != TCL_OK) { return result; } - Tcl_Preserve((ClientData) butPtr); + Tcl_Preserve(butPtr); switch (map[butPtr->type][index]) { case COMMAND_CGET: @@ -815,9 +814,8 @@ ButtonWidgetObjCmd( butPtr->optionTable, objv[2], butPtr->tkwin); if (objPtr == NULL) { goto error; - } else { - Tcl_SetObjResult(interp, objPtr); } + Tcl_SetObjResult(interp, objPtr); break; case COMMAND_CONFIGURE: @@ -827,9 +825,8 @@ ButtonWidgetObjCmd( butPtr->tkwin); if (objPtr == NULL) { goto error; - } else { - Tcl_SetObjResult(interp, objPtr); } + Tcl_SetObjResult(interp, objPtr); } else { result = ConfigureButton(interp, butPtr, objc-2, objv+2); } @@ -872,7 +869,7 @@ ButtonWidgetObjCmd( Tk_SetBackgroundFromBorder(butPtr->tkwin, butPtr->normalBorder); } - TkpDisplayButton((ClientData) butPtr); + TkpDisplayButton(butPtr); /* * Special note: must cancel any existing idle handler for @@ -880,9 +877,15 @@ ButtonWidgetObjCmd( * TkpDisplayButton cleared the REDRAW_PENDING flag. */ - Tcl_CancelIdleCall(TkpDisplayButton, (ClientData) butPtr); + Tcl_CancelIdleCall(TkpDisplayButton, butPtr); XFlush(butPtr->display); + #ifndef MAC_OSX_TK + /* + * On the mac you can not sleep in a display proc, and the + * flash command doesn't do anything anyway. + */ Tcl_Sleep(50); + #endif } } break; @@ -922,11 +925,11 @@ ButtonWidgetObjCmd( } break; } - Tcl_Release((ClientData) butPtr); + Tcl_Release(butPtr); return result; error: - Tcl_Release((ClientData) butPtr); + Tcl_Release(butPtr); return TCL_ERROR; } @@ -955,7 +958,7 @@ DestroyButton( TkpDestroyButton(butPtr); if (butPtr->flags & REDRAW_PENDING) { - Tcl_CancelIdleCall(TkpDisplayButton, (ClientData) butPtr); + Tcl_CancelIdleCall(TkpDisplayButton, butPtr); } /* @@ -965,9 +968,9 @@ DestroyButton( Tcl_DeleteCommandFromToken(butPtr->interp, butPtr->widgetCmd); if (butPtr->textVarNamePtr != NULL) { - Tcl_UntraceVar(butPtr->interp, Tcl_GetString(butPtr->textVarNamePtr), - TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - ButtonTextVarProc, (ClientData) butPtr); + Tcl_UntraceVar2(butPtr->interp, Tcl_GetString(butPtr->textVarNamePtr), + NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + ButtonTextVarProc, butPtr); } if (butPtr->image != NULL) { Tk_FreeImage(butPtr->image); @@ -1000,14 +1003,14 @@ DestroyButton( Tk_FreeTextLayout(butPtr->textLayout); } if (butPtr->selVarNamePtr != NULL) { - Tcl_UntraceVar(butPtr->interp, Tcl_GetString(butPtr->selVarNamePtr), - TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - ButtonVarProc, (ClientData) butPtr); + Tcl_UntraceVar2(butPtr->interp, Tcl_GetString(butPtr->selVarNamePtr), + NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + ButtonVarProc, butPtr); } Tk_FreeConfigOptions((char *) butPtr, butPtr->optionTable, butPtr->tkwin); butPtr->tkwin = NULL; - Tcl_EventuallyFree((ClientData) butPtr, TCL_DYNAMIC); + Tcl_EventuallyFree(butPtr, TCL_DYNAMIC); } /* @@ -1048,14 +1051,14 @@ ConfigureButton( */ if (butPtr->textVarNamePtr != NULL) { - Tcl_UntraceVar(interp, Tcl_GetString(butPtr->textVarNamePtr), - TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - ButtonTextVarProc, (ClientData) butPtr); + Tcl_UntraceVar2(interp, Tcl_GetString(butPtr->textVarNamePtr), + NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + ButtonTextVarProc, butPtr); } if (butPtr->selVarNamePtr != NULL) { - Tcl_UntraceVar(interp, Tcl_GetString(butPtr->selVarNamePtr), - TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - ButtonVarProc, (ClientData) butPtr); + Tcl_UntraceVar2(interp, Tcl_GetString(butPtr->selVarNamePtr), + NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + ButtonVarProc, butPtr); } /* @@ -1172,7 +1175,7 @@ ConfigureButton( */ if ((butPtr->type == TYPE_RADIO_BUTTON) && - (*Tcl_GetString(butPtr->onValuePtr) == 0)) { + (*Tcl_GetString(butPtr->onValuePtr) == '\0')) { butPtr->flags |= SELECTED; } } @@ -1187,7 +1190,7 @@ ConfigureButton( if (butPtr->imagePtr != NULL) { image = Tk_GetImage(butPtr->interp, butPtr->tkwin, Tcl_GetString(butPtr->imagePtr), ButtonImageProc, - (ClientData) butPtr); + butPtr); if (image == NULL) { continue; } @@ -1201,7 +1204,7 @@ ConfigureButton( if (butPtr->selectImagePtr != NULL) { image = Tk_GetImage(butPtr->interp, butPtr->tkwin, Tcl_GetString(butPtr->selectImagePtr), - ButtonSelectImageProc, (ClientData) butPtr); + ButtonSelectImageProc, butPtr); if (image == NULL) { continue; } @@ -1215,7 +1218,7 @@ ConfigureButton( if (butPtr->tristateImagePtr != NULL) { image = Tk_GetImage(butPtr->interp, butPtr->tkwin, Tcl_GetString(butPtr->tristateImagePtr), - ButtonTristateImageProc, (ClientData) butPtr); + ButtonTristateImageProc, butPtr); if (image == NULL) { continue; } @@ -1300,17 +1303,17 @@ ConfigureButton( */ if (butPtr->textVarNamePtr != NULL) { - Tcl_TraceVar(interp, Tcl_GetString(butPtr->textVarNamePtr), - TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - ButtonTextVarProc, (ClientData) butPtr); + Tcl_TraceVar2(interp, Tcl_GetString(butPtr->textVarNamePtr), + NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + ButtonTextVarProc, butPtr); } if (butPtr->selVarNamePtr != NULL) { - Tcl_TraceVar(interp, Tcl_GetString(butPtr->selVarNamePtr), - TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - ButtonVarProc, (ClientData) butPtr); + Tcl_TraceVar2(interp, Tcl_GetString(butPtr->selVarNamePtr), + NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + ButtonVarProc, butPtr); } - TkButtonWorldChanged((ClientData) butPtr); + TkButtonWorldChanged(butPtr); if (error) { Tcl_SetObjResult(interp, errorResult); Tcl_DecrRefCount(errorResult); @@ -1345,9 +1348,7 @@ TkButtonWorldChanged( XGCValues gcValues; GC newGC; unsigned long mask; - TkButton *butPtr; - - butPtr = (TkButton *) instanceData; + TkButton *butPtr = instanceData; /* * Recompute GCs. @@ -1430,7 +1431,7 @@ TkButtonWorldChanged( */ if (Tk_IsMapped(butPtr->tkwin) && !(butPtr->flags & REDRAW_PENDING)) { - Tcl_DoWhenIdle(TkpDisplayButton, (ClientData) butPtr); + Tcl_DoWhenIdle(TkpDisplayButton, butPtr); butPtr->flags |= REDRAW_PENDING; } } @@ -1458,7 +1459,7 @@ ButtonEventProc( ClientData clientData, /* Information about window. */ XEvent *eventPtr) /* Information about event. */ { - TkButton *butPtr = (TkButton *) clientData; + TkButton *butPtr = clientData; if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) { goto redraw; } else if (eventPtr->type == ConfigureNotify) { @@ -1489,7 +1490,7 @@ ButtonEventProc( redraw: if ((butPtr->tkwin != NULL) && !(butPtr->flags & REDRAW_PENDING)) { - Tcl_DoWhenIdle(TkpDisplayButton, (ClientData) butPtr); + Tcl_DoWhenIdle(TkpDisplayButton, butPtr); butPtr->flags |= REDRAW_PENDING; } } @@ -1516,7 +1517,7 @@ static void ButtonCmdDeletedProc( ClientData clientData) /* Pointer to widget record for widget. */ { - TkButton *butPtr = (TkButton *) clientData; + TkButton *butPtr = clientData; /* * This function could be invoked either because the window was destroyed @@ -1611,23 +1612,40 @@ ButtonVarProc( const char *name2, /* Second part of variable name. */ int flags) /* Information about what happened. */ { - register TkButton *butPtr = (TkButton *) clientData; - char *name, *value; + register TkButton *butPtr = clientData; + const char *value; Tcl_Obj *valuePtr; - name = Tcl_GetString(butPtr->selVarNamePtr); - /* * If the variable is being unset, then just re-establish the trace unless * the whole interpreter is going away. */ if (flags & TCL_TRACE_UNSETS) { - butPtr->flags &= ~SELECTED; - butPtr->flags &= ~TRISTATED; - if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) { - Tcl_TraceVar(interp, name, - TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + butPtr->flags &= ~(SELECTED | TRISTATED); + if (!Tcl_InterpDeleted(interp)) { + ClientData probe = NULL; + + do { + probe = Tcl_VarTraceInfo(interp, + Tcl_GetString(butPtr->selVarNamePtr), + TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + ButtonVarProc, probe); + if (probe == (ClientData)butPtr) { + break; + } + } while (probe); + if (probe) { + /* + * We were able to fetch the unset trace for our + * selVarNamePtr, which means it is not unset and not + * the cause of this unset trace. Instead some outdated + * former variable must be, and we should ignore it. + */ + goto redisplay; + } + Tcl_TraceVar2(interp, Tcl_GetString(butPtr->selVarNamePtr), + NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, ButtonVarProc, clientData); } goto redisplay; @@ -1638,7 +1656,8 @@ ButtonVarProc( * button. */ - valuePtr = Tcl_GetVar2Ex(interp, name, NULL, TCL_GLOBAL_ONLY); + valuePtr = Tcl_ObjGetVar2(interp, butPtr->selVarNamePtr, NULL, + TCL_GLOBAL_ONLY); if (valuePtr == NULL) { value = Tcl_GetString(butPtr->tristateValuePtr); } else { @@ -1650,7 +1669,7 @@ ButtonVarProc( } butPtr->flags |= SELECTED; butPtr->flags &= ~TRISTATED; - } else if (butPtr->offValuePtr + } else if (butPtr->offValuePtr && strcmp(value, Tcl_GetString(butPtr->offValuePtr)) == 0) { if (!(butPtr->flags & (SELECTED | TRISTATED))) { return NULL; @@ -1671,7 +1690,7 @@ ButtonVarProc( redisplay: if ((butPtr->tkwin != NULL) && Tk_IsMapped(butPtr->tkwin) && !(butPtr->flags & REDRAW_PENDING)) { - Tcl_DoWhenIdle(TkpDisplayButton, (ClientData) butPtr); + Tcl_DoWhenIdle(TkpDisplayButton, butPtr); butPtr->flags |= REDRAW_PENDING; } return NULL; @@ -1703,33 +1722,58 @@ ButtonTextVarProc( const char *name2, /* Not used. */ int flags) /* Information about what happened. */ { - TkButton *butPtr = (TkButton *) clientData; - char *name; + TkButton *butPtr = clientData; Tcl_Obj *valuePtr; if (butPtr->flags & BUTTON_DELETED) { return NULL; } - name = Tcl_GetString(butPtr->textVarNamePtr); - /* * If the variable is unset, then immediately recreate it unless the whole * interpreter is going away. */ if (flags & TCL_TRACE_UNSETS) { - if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) { - Tcl_SetVar2Ex(interp, name, NULL, butPtr->textPtr, - TCL_GLOBAL_ONLY); - Tcl_TraceVar(interp, name, - TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + if (!Tcl_InterpDeleted(interp) && butPtr->textVarNamePtr != NULL) { + + /* + * An unset trace on some variable brought us here, but is it + * the variable we have stored in butPtr->textVarNamePtr ? + */ + + ClientData probe = NULL; + + do { + probe = Tcl_VarTraceInfo(interp, + Tcl_GetString(butPtr->textVarNamePtr), + TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + ButtonTextVarProc, probe); + if (probe == (ClientData)butPtr) { + break; + } + } while (probe); + if (probe) { + /* + * We were able to fetch the unset trace for our + * textVarNamePtr, which means it is not unset and not + * the cause of this unset trace. Instead some outdated + * former textvariable must be, and we should ignore it. + */ + return NULL; + } + + Tcl_ObjSetVar2(interp, butPtr->textVarNamePtr, NULL, + butPtr->textPtr, TCL_GLOBAL_ONLY); + Tcl_TraceVar2(interp, Tcl_GetString(butPtr->textVarNamePtr), + NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, ButtonTextVarProc, clientData); } return NULL; } - valuePtr = Tcl_GetVar2Ex(interp, name, NULL, TCL_GLOBAL_ONLY); + valuePtr = Tcl_ObjGetVar2(interp, butPtr->textVarNamePtr, NULL, + TCL_GLOBAL_ONLY); if (valuePtr == NULL) { valuePtr = Tcl_NewObj(); } @@ -1740,7 +1784,7 @@ ButtonTextVarProc( if ((butPtr->tkwin != NULL) && Tk_IsMapped(butPtr->tkwin) && !(butPtr->flags & REDRAW_PENDING)) { - Tcl_DoWhenIdle(TkpDisplayButton, (ClientData) butPtr); + Tcl_DoWhenIdle(TkpDisplayButton, butPtr); butPtr->flags |= REDRAW_PENDING; } return NULL; @@ -1773,12 +1817,12 @@ ButtonImageProc( * <= 0). */ int imgWidth, int imgHeight)/* New dimensions of image. */ { - register TkButton *butPtr = (TkButton *) clientData; + register TkButton *butPtr = clientData; if (butPtr->tkwin != NULL) { TkpComputeButtonGeometry(butPtr); if (Tk_IsMapped(butPtr->tkwin) && !(butPtr->flags & REDRAW_PENDING)) { - Tcl_DoWhenIdle(TkpDisplayButton, (ClientData) butPtr); + Tcl_DoWhenIdle(TkpDisplayButton, butPtr); butPtr->flags |= REDRAW_PENDING; } } @@ -1811,16 +1855,22 @@ ButtonSelectImageProc( * <= 0). */ int imgWidth, int imgHeight)/* New dimensions of image. */ { - register TkButton *butPtr = (TkButton *) clientData; + register TkButton *butPtr = clientData; +#ifdef MAC_OSX_TK + if (butPtr->tkwin != NULL) { + TkpComputeButtonGeometry(butPtr); + } +#else /* * Don't recompute geometry: it's controlled by the primary image. */ +#endif if ((butPtr->flags & SELECTED) && (butPtr->tkwin != NULL) && Tk_IsMapped(butPtr->tkwin) && !(butPtr->flags & REDRAW_PENDING)) { - Tcl_DoWhenIdle(TkpDisplayButton, (ClientData) butPtr); + Tcl_DoWhenIdle(TkpDisplayButton, butPtr); butPtr->flags |= REDRAW_PENDING; } } @@ -1852,16 +1902,22 @@ ButtonTristateImageProc( * <= 0). */ int imgWidth, int imgHeight)/* New dimensions of image. */ { - register TkButton *butPtr = (TkButton *) clientData; + register TkButton *butPtr = clientData; +#ifdef MAC_OSX_TK + if (butPtr->tkwin != NULL) { + TkpComputeButtonGeometry(butPtr); + } +#else /* * Don't recompute geometry: it's controlled by the primary image. */ +#endif if ((butPtr->flags & TRISTATED) && (butPtr->tkwin != NULL) && Tk_IsMapped(butPtr->tkwin) && !(butPtr->flags & REDRAW_PENDING)) { - Tcl_DoWhenIdle(TkpDisplayButton, (ClientData) butPtr); + Tcl_DoWhenIdle(TkpDisplayButton, butPtr); butPtr->flags |= REDRAW_PENDING; } } diff --git a/generic/tkButton.h b/generic/tkButton.h index d669b02..7e04fb9 100644 --- a/generic/tkButton.h +++ b/generic/tkButton.h @@ -292,7 +292,7 @@ typedef struct { * and button/label defaults, for use in optionSpecs. */ -MODULE_SCOPE Tk_ClassProcs tkpButtonProcs; +MODULE_SCOPE const Tk_ClassProcs tkpButtonProcs; MODULE_SCOPE char tkDefButtonHighlightWidth[TCL_INTEGER_SPACE]; MODULE_SCOPE char tkDefButtonPadx[TCL_INTEGER_SPACE]; MODULE_SCOPE char tkDefButtonPady[TCL_INTEGER_SPACE]; diff --git a/generic/tkCanvArc.c b/generic/tkCanvArc.c index 55012a8..d9f0461 100644 --- a/generic/tkCanvArc.c +++ b/generic/tkCanvArc.c @@ -10,7 +10,6 @@ * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ -#include <stdio.h> #include "tkInt.h" #include "tkCanvas.h" @@ -79,48 +78,42 @@ typedef struct ArcItem { */ static int StyleParseProc(ClientData clientData, Tcl_Interp *interp, - Tk_Window tkwin, CONST char *value, + Tk_Window tkwin, const char *value, char *widgRec, int offset); -static char * StylePrintProc(ClientData clientData, Tk_Window tkwin, +static const char * StylePrintProc(ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); -static Tk_CustomOption stateOption = { - (Tk_OptionParseProc *) TkStateParseProc, - TkStatePrintProc, (ClientData) 2 +static const Tk_CustomOption stateOption = { + TkStateParseProc, TkStatePrintProc, INT2PTR(2) }; -static Tk_CustomOption styleOption = { - (Tk_OptionParseProc *) StyleParseProc, - StylePrintProc, (ClientData) NULL +static const Tk_CustomOption styleOption = { + StyleParseProc, StylePrintProc, NULL }; -static Tk_CustomOption tagsOption = { - (Tk_OptionParseProc *) Tk_CanvasTagsParseProc, - Tk_CanvasTagsPrintProc, (ClientData) NULL +static const Tk_CustomOption tagsOption = { + Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL }; -static Tk_CustomOption dashOption = { - (Tk_OptionParseProc *) TkCanvasDashParseProc, - TkCanvasDashPrintProc, (ClientData) NULL +static const Tk_CustomOption dashOption = { + TkCanvasDashParseProc, TkCanvasDashPrintProc, NULL }; -static Tk_CustomOption offsetOption = { - (Tk_OptionParseProc *) TkOffsetParseProc, - TkOffsetPrintProc, (ClientData) (TK_OFFSET_RELATIVE) +static const Tk_CustomOption offsetOption = { + TkOffsetParseProc, TkOffsetPrintProc, INT2PTR(TK_OFFSET_RELATIVE) }; -static Tk_CustomOption pixelOption = { - (Tk_OptionParseProc *) TkPixelParseProc, - TkPixelPrintProc, (ClientData) NULL +static const Tk_CustomOption pixelOption = { + TkPixelParseProc, TkPixelPrintProc, NULL }; -static Tk_ConfigSpec configSpecs[] = { +static const Tk_ConfigSpec configSpecs[] = { {TK_CONFIG_CUSTOM, "-activedash", NULL, NULL, NULL, Tk_Offset(ArcItem, outline.activeDash), TK_CONFIG_NULL_OK, &dashOption}, {TK_CONFIG_COLOR, "-activefill", NULL, NULL, - NULL, Tk_Offset(ArcItem, activeFillColor), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(ArcItem, activeFillColor), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_COLOR, "-activeoutline", NULL, NULL, - NULL, Tk_Offset(ArcItem, outline.activeColor), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(ArcItem, outline.activeColor), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_BITMAP, "-activeoutlinestipple", NULL, NULL, - NULL, Tk_Offset(ArcItem, outline.activeStipple), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(ArcItem, outline.activeStipple), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_BITMAP, "-activestipple", NULL, NULL, - NULL, Tk_Offset(ArcItem, activeFillStipple), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(ArcItem, activeFillStipple), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_CUSTOM, "-activewidth", NULL, NULL, "0.0", Tk_Offset(ArcItem, outline.activeWidth), TK_CONFIG_DONT_SET_DEFAULT, &pixelOption}, @@ -128,41 +121,41 @@ static Tk_ConfigSpec configSpecs[] = { NULL, Tk_Offset(ArcItem, outline.dash), TK_CONFIG_NULL_OK, &dashOption}, {TK_CONFIG_PIXELS, "-dashoffset", NULL, NULL, - "0", Tk_Offset(ArcItem, outline.offset), TK_CONFIG_DONT_SET_DEFAULT}, + "0", Tk_Offset(ArcItem, outline.offset), TK_CONFIG_DONT_SET_DEFAULT, NULL}, {TK_CONFIG_CUSTOM, "-disableddash", NULL, NULL, NULL, Tk_Offset(ArcItem, outline.disabledDash), TK_CONFIG_NULL_OK, &dashOption}, {TK_CONFIG_COLOR, "-disabledfill", NULL, NULL, - NULL, Tk_Offset(ArcItem, disabledFillColor), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(ArcItem, disabledFillColor), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_COLOR, "-disabledoutline", NULL, NULL, - NULL, Tk_Offset(ArcItem, outline.disabledColor), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(ArcItem, outline.disabledColor), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_BITMAP, "-disabledoutlinestipple", NULL, NULL, - NULL, Tk_Offset(ArcItem, outline.disabledStipple), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(ArcItem, outline.disabledStipple), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_BITMAP, "-disabledstipple", NULL, NULL, - NULL, Tk_Offset(ArcItem, disabledFillStipple), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(ArcItem, disabledFillStipple), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_CUSTOM, "-disabledwidth", NULL, NULL, "0.0", Tk_Offset(ArcItem, outline.disabledWidth), TK_CONFIG_DONT_SET_DEFAULT, &pixelOption}, {TK_CONFIG_DOUBLE, "-extent", NULL, NULL, - "90", Tk_Offset(ArcItem, extent), TK_CONFIG_DONT_SET_DEFAULT}, + "90", Tk_Offset(ArcItem, extent), TK_CONFIG_DONT_SET_DEFAULT, NULL}, {TK_CONFIG_COLOR, "-fill", NULL, NULL, - NULL, Tk_Offset(ArcItem, fillColor), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(ArcItem, fillColor), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_CUSTOM, "-offset", NULL, NULL, "0,0", Tk_Offset(ArcItem, tsoffset), TK_CONFIG_DONT_SET_DEFAULT, &offsetOption}, {TK_CONFIG_COLOR, "-outline", NULL, NULL, - "black", Tk_Offset(ArcItem, outline.color), TK_CONFIG_NULL_OK}, + "black", Tk_Offset(ArcItem, outline.color), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_CUSTOM, "-outlineoffset", NULL, NULL, "0,0", Tk_Offset(ArcItem, outline.tsoffset), TK_CONFIG_DONT_SET_DEFAULT, &offsetOption}, {TK_CONFIG_BITMAP, "-outlinestipple", NULL, NULL, - NULL, Tk_Offset(ArcItem, outline.stipple), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(ArcItem, outline.stipple), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_DOUBLE, "-start", NULL, NULL, - "0", Tk_Offset(ArcItem, start), TK_CONFIG_DONT_SET_DEFAULT}, + "0", Tk_Offset(ArcItem, start), TK_CONFIG_DONT_SET_DEFAULT, NULL}, {TK_CONFIG_CUSTOM, "-state", NULL, NULL, NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption}, {TK_CONFIG_BITMAP, "-stipple", NULL, NULL, - NULL, Tk_Offset(ArcItem, fillStipple), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(ArcItem, fillStipple), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_CUSTOM, "-style", NULL, NULL, NULL, Tk_Offset(ArcItem, style), TK_CONFIG_DONT_SET_DEFAULT, &styleOption}, @@ -171,7 +164,7 @@ static Tk_ConfigSpec configSpecs[] = { {TK_CONFIG_CUSTOM, "-width", NULL, NULL, "1.0", Tk_Offset(ArcItem, outline.width), TK_CONFIG_DONT_SET_DEFAULT, &pixelOption}, - {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} + {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL} }; /* @@ -181,17 +174,17 @@ static Tk_ConfigSpec configSpecs[] = { static void ComputeArcBbox(Tk_Canvas canvas, ArcItem *arcPtr); static int ConfigureArc(Tcl_Interp *interp, Tk_Canvas canvas, Tk_Item *itemPtr, int objc, - Tcl_Obj *CONST objv[], int flags); + Tcl_Obj *const objv[], int flags); static int CreateArc(Tcl_Interp *interp, Tk_Canvas canvas, struct Tk_Item *itemPtr, - int objc, Tcl_Obj *CONST objv[]); + int objc, Tcl_Obj *const objv[]); static void DeleteArc(Tk_Canvas canvas, Tk_Item *itemPtr, Display *display); static void DisplayArc(Tk_Canvas canvas, Tk_Item *itemPtr, Display *display, Drawable dst, int x, int y, int width, int height); static int ArcCoords(Tcl_Interp *interp, Tk_Canvas canvas, - Tk_Item *itemPtr, int objc, Tcl_Obj *CONST objv[]); + Tk_Item *itemPtr, int objc, Tcl_Obj *const objv[]); static int ArcToArea(Tk_Canvas canvas, Tk_Item *itemPtr, double *rectPtr); static double ArcToPoint(Tk_Canvas canvas, @@ -239,11 +232,8 @@ Tk_ItemType tkArcType = { NULL, /* insertProc */ NULL, /* dTextProc */ NULL, /* nextPtr */ + NULL, 0, NULL, NULL }; - -#ifndef PI -#define PI 3.14159265358979323846 -#endif /* *-------------------------------------------------------------- @@ -271,13 +261,13 @@ CreateArc( Tk_Item *itemPtr, /* Record to hold new item; header has been * initialized by caller. */ int objc, /* Number of arguments in objv. */ - Tcl_Obj *CONST objv[]) /* Arguments describing arc. */ + Tcl_Obj *const objv[]) /* Arguments describing arc. */ { ArcItem *arcPtr = (ArcItem *) itemPtr; int i; if (objc == 0) { - Tcl_Panic("canvas did not pass any coords\n"); + Tcl_Panic("canvas did not pass any coords"); } /* @@ -307,7 +297,7 @@ CreateArc( */ for (i = 1; i < objc; i++) { - char *arg = Tcl_GetString(objv[i]); + const char *arg = Tcl_GetString(objv[i]); if ((arg[0] == '-') && (arg[1] >= 'a') && (arg[1] <= 'z')) { break; @@ -349,32 +339,28 @@ ArcCoords( Tk_Item *itemPtr, /* Item whose coordinates are to be read or * modified. */ int objc, /* Number of coordinates supplied in objv. */ - Tcl_Obj *CONST objv[]) /* Array of coordinates: x1, y1, x2, y2, ... */ + Tcl_Obj *const objv[]) /* Array of coordinates: x1, y1, x2, y2, ... */ { ArcItem *arcPtr = (ArcItem *) itemPtr; if (objc == 0) { - Tcl_Obj *obj = Tcl_NewObj(); - Tcl_Obj *subobj = Tcl_NewDoubleObj(arcPtr->bbox[0]); - - Tcl_ListObjAppendElement(interp, obj, subobj); - subobj = Tcl_NewDoubleObj(arcPtr->bbox[1]); - Tcl_ListObjAppendElement(interp, obj, subobj); - subobj = Tcl_NewDoubleObj(arcPtr->bbox[2]); - Tcl_ListObjAppendElement(interp, obj, subobj); - subobj = Tcl_NewDoubleObj(arcPtr->bbox[3]); - Tcl_ListObjAppendElement(interp, obj, subobj); - Tcl_SetObjResult(interp, obj); + Tcl_Obj *objs[4]; + + objs[0] = Tcl_NewDoubleObj(arcPtr->bbox[0]); + objs[1] = Tcl_NewDoubleObj(arcPtr->bbox[1]); + objs[2] = Tcl_NewDoubleObj(arcPtr->bbox[2]); + objs[3] = Tcl_NewDoubleObj(arcPtr->bbox[3]); + Tcl_SetObjResult(interp, Tcl_NewListObj(4, objs)); } else if ((objc == 1)||(objc == 4)) { if (objc==1) { if (Tcl_ListObjGetElements(interp, objv[0], &objc, (Tcl_Obj ***) &objv) != TCL_OK) { return TCL_ERROR; } else if (objc != 4) { - char buf[64 + TCL_INTEGER_SPACE]; - - sprintf(buf, "wrong # coordinates: expected 4, got %d", objc); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "wrong # coordinates: expected 4, got %d", objc)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "ARC", + NULL); return TCL_ERROR; } } @@ -390,10 +376,9 @@ ArcCoords( } ComputeArcBbox(canvas, arcPtr); } else { - char buf[64 + TCL_INTEGER_SPACE]; - - sprintf(buf, "wrong # coordinates: expected 0 or 4, got %d", objc); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "wrong # coordinates: expected 0 or 4, got %d", objc)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "ARC", NULL); return TCL_ERROR; } return TCL_OK; @@ -424,7 +409,7 @@ ConfigureArc( Tk_Canvas canvas, /* Canvas containing itemPtr. */ Tk_Item *itemPtr, /* Arc item to reconfigure. */ int objc, /* Number of elements in objv. */ - Tcl_Obj *CONST objv[], /* Arguments describing things to configure. */ + Tcl_Obj *const objv[], /* Arguments describing things to configure. */ int flags) /* Flags to pass to Tk_ConfigureWidget. */ { ArcItem *arcPtr = (ArcItem *) itemPtr; @@ -440,7 +425,7 @@ ConfigureArc( tkwin = Tk_CanvasTkwin(canvas); if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc, - (CONST char **) objv, (char *) arcPtr, flags|TK_CONFIG_OBJS)) { + (const char **) objv, (char *) arcPtr, flags|TK_CONFIG_OBJS)) { return TCL_ERROR; } @@ -501,7 +486,7 @@ ConfigureArc( arcPtr->outline.gc = newGC; if(state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } if (state==TK_STATE_HIDDEN) { ComputeArcBbox(canvas, arcPtr); @@ -510,7 +495,7 @@ ConfigureArc( color = arcPtr->fillColor; stipple = arcPtr->fillStipple; - if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { + if (Canvas(canvas)->currentItemPtr == itemPtr) { if (arcPtr->activeFillColor!=NULL) { color = arcPtr->activeFillColor; } @@ -598,7 +583,7 @@ DeleteArc( Tk_DeleteOutline(display, &(arcPtr->outline)); if (arcPtr->numOutlinePoints != 0) { - ckfree((char *) arcPtr->outlinePtr); + ckfree(arcPtr->outlinePtr); } if (arcPtr->fillColor != NULL) { Tk_FreeColor(arcPtr->fillColor); @@ -651,7 +636,7 @@ ComputeArcBbox( Tk_State state = arcPtr->header.state; if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } width = arcPtr->outline.width; @@ -662,7 +647,7 @@ ComputeArcBbox( arcPtr->header.x1 = arcPtr->header.x2 = arcPtr->header.y1 = arcPtr->header.y2 = -1; return; - } else if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *) arcPtr) { + } else if (Canvas(canvas)->currentItemPtr == (Tk_Item *) arcPtr) { if (arcPtr->outline.activeWidth>width) { width = arcPtr->outline.activeWidth; } @@ -794,7 +779,7 @@ DisplayArc( Pixmap stipple; if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } lineWidth = arcPtr->outline.width; if (lineWidth < 1.0) { @@ -802,7 +787,7 @@ DisplayArc( } dashnumber = arcPtr->outline.dash.number; stipple = arcPtr->fillStipple; - if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { + if (Canvas(canvas)->currentItemPtr == itemPtr) { if (arcPtr->outline.activeWidth>lineWidth) { lineWidth = arcPtr->outline.activeWidth; } @@ -970,11 +955,11 @@ ArcToPoint( Tk_State state = itemPtr->state; if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } width = (double) arcPtr->outline.width; - if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { + if (Canvas(canvas)->currentItemPtr == itemPtr) { if (arcPtr->outline.activeWidth>width) { width = (double) arcPtr->outline.activeWidth; } @@ -1146,10 +1131,10 @@ ArcToArea( Tk_State state = itemPtr->state; if(state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } width = (double) arcPtr->outline.width; - if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { + if (Canvas(canvas)->currentItemPtr == itemPtr) { if (arcPtr->outline.activeWidth>width) { width = (double) arcPtr->outline.activeWidth; } @@ -1461,14 +1446,13 @@ ComputeArcOutline( */ if (arcPtr->numOutlinePoints == 0) { - arcPtr->outlinePtr = (double *) ckalloc((unsigned) - (26 * sizeof(double))); + arcPtr->outlinePtr = ckalloc(26 * sizeof(double)); arcPtr->numOutlinePoints = 22; } outlinePtr = arcPtr->outlinePtr; if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } /* @@ -1526,7 +1510,7 @@ ComputeArcOutline( */ width = arcPtr->outline.width; - if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *) arcPtr) { + if (Canvas(canvas)->currentItemPtr == (Tk_Item *) arcPtr) { if (arcPtr->outline.activeWidth>arcPtr->outline.width) { width = arcPtr->outline.activeWidth; } @@ -1834,13 +1818,14 @@ ArcToPostscript( * being created. */ { ArcItem *arcPtr = (ArcItem *) itemPtr; - char buffer[400]; double y1, y2, ang1, ang2; XColor *color; Pixmap stipple; XColor *fillColor; Pixmap fillStipple; Tk_State state = itemPtr->state; + Tcl_Obj *psObj; + Tcl_InterpState interpState; y1 = Tk_CanvasPsY(canvas, arcPtr->bbox[1]); y2 = Tk_CanvasPsY(canvas, arcPtr->bbox[3]); @@ -1852,13 +1837,13 @@ ArcToPostscript( } if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } color = arcPtr->outline.color; stipple = arcPtr->outline.stipple; fillColor = arcPtr->fillColor; fillStipple = arcPtr->fillStipple; - if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { + if (Canvas(canvas)->currentItemPtr == itemPtr) { if (arcPtr->outline.activeColor!=NULL) { color = arcPtr->outline.activeColor; } @@ -1887,37 +1872,51 @@ ArcToPostscript( } /* + * Make our working space. + */ + + psObj = Tcl_NewObj(); + interpState = Tcl_SaveInterpState(interp, TCL_OK); + + /* * If the arc is filled, output Postscript for the interior region of the * arc. */ if (arcPtr->fillGC != NULL) { - sprintf(buffer, "matrix currentmatrix\n%.15g %.15g translate %.15g %.15g scale\n", + Tcl_AppendPrintfToObj(psObj, + "matrix currentmatrix\n" + "%.15g %.15g translate %.15g %.15g scale\n", (arcPtr->bbox[0] + arcPtr->bbox[2])/2, (y1 + y2)/2, (arcPtr->bbox[2] - arcPtr->bbox[0])/2, (y1 - y2)/2); - Tcl_AppendResult(interp, buffer, NULL); - if (arcPtr->style == CHORD_STYLE) { - sprintf(buffer, "0 0 1 %.15g %.15g arc closepath\nsetmatrix\n", - ang1, ang2); - } else { - sprintf(buffer, - "0 0 moveto 0 0 1 %.15g %.15g arc closepath\nsetmatrix\n", - ang1, ang2); + + if (arcPtr->style != CHORD_STYLE) { + Tcl_AppendToObj(psObj, "0 0 moveto ", -1); } - Tcl_AppendResult(interp, buffer, NULL); + Tcl_AppendPrintfToObj(psObj, + "0 0 1 %.15g %.15g arc closepath\nsetmatrix\n", + ang1, ang2); + + Tcl_ResetResult(interp); if (Tk_CanvasPsColor(interp, canvas, fillColor) != TCL_OK) { - return TCL_ERROR; + goto error; } + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); + if (fillStipple != None) { - Tcl_AppendResult(interp, "clip ", NULL); + Tcl_AppendToObj(psObj, "clip ", -1); + + Tcl_ResetResult(interp); if (Tk_CanvasPsStipple(interp, canvas, fillStipple) != TCL_OK) { - return TCL_ERROR; + goto error; } + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); + if (arcPtr->outline.gc != NULL) { - Tcl_AppendResult(interp, "grestore gsave\n", NULL); + Tcl_AppendToObj(psObj, "grestore gsave\n", -1); } } else { - Tcl_AppendResult(interp, "fill\n", NULL); + Tcl_AppendToObj(psObj, "fill\n", -1); } } @@ -1926,57 +1925,86 @@ ArcToPostscript( */ if (arcPtr->outline.gc != NULL) { - sprintf(buffer, "matrix currentmatrix\n%.15g %.15g translate %.15g %.15g scale\n", + Tcl_AppendPrintfToObj(psObj, + "matrix currentmatrix\n" + "%.15g %.15g translate %.15g %.15g scale\n", (arcPtr->bbox[0] + arcPtr->bbox[2])/2, (y1 + y2)/2, (arcPtr->bbox[2] - arcPtr->bbox[0])/2, (y1 - y2)/2); - Tcl_AppendResult(interp, buffer, NULL); - sprintf(buffer, "0 0 1 %.15g %.15g", ang1, ang2); - Tcl_AppendResult(interp, buffer, - " arc\nsetmatrix\n0 setlinecap\n", NULL); - if (Tk_CanvasPsOutline(canvas, itemPtr, &(arcPtr->outline)) != TCL_OK){ - return TCL_ERROR; + Tcl_AppendPrintfToObj(psObj, + "0 0 1 %.15g %.15g arc\nsetmatrix\n0 setlinecap\n", + ang1, ang2); + + Tcl_ResetResult(interp); + if (Tk_CanvasPsOutline(canvas, itemPtr, &arcPtr->outline) != TCL_OK) { + goto error; } + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); + if (arcPtr->style != ARC_STYLE) { - Tcl_AppendResult(interp, "grestore gsave\n", NULL); + Tcl_AppendToObj(psObj, "grestore gsave\n", -1); + + Tcl_ResetResult(interp); if (arcPtr->style == CHORD_STYLE) { Tk_CanvasPsPath(interp, canvas, arcPtr->outlinePtr, CHORD_OUTLINE_PTS); } else { Tk_CanvasPsPath(interp, canvas, arcPtr->outlinePtr, PIE_OUTLINE1_PTS); - if (Tk_CanvasPsColor(interp, canvas, color) - != TCL_OK) { - return TCL_ERROR; + if (Tk_CanvasPsColor(interp, canvas, color) != TCL_OK) { + goto error; } + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); + if (stipple != None) { - Tcl_AppendResult(interp, "clip ", NULL); - if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK){ - return TCL_ERROR; + Tcl_AppendToObj(psObj, "clip ", -1); + + Tcl_ResetResult(interp); + if (Tk_CanvasPsStipple(interp, canvas, stipple) !=TCL_OK){ + goto error; } + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); } else { - Tcl_AppendResult(interp, "fill\n", NULL); + Tcl_AppendToObj(psObj, "fill\n", -1); } - Tcl_AppendResult(interp, "grestore gsave\n", NULL); + Tcl_AppendToObj(psObj, "grestore gsave\n", -1); + + Tcl_ResetResult(interp); Tk_CanvasPsPath(interp, canvas, arcPtr->outlinePtr + 2*PIE_OUTLINE1_PTS, PIE_OUTLINE2_PTS); } - if (Tk_CanvasPsColor(interp, canvas, color) - != TCL_OK) { - return TCL_ERROR; + if (Tk_CanvasPsColor(interp, canvas, color) != TCL_OK) { + goto error; } + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); + if (stipple != None) { - Tcl_AppendResult(interp, "clip ", NULL); + Tcl_AppendToObj(psObj, "clip ", -1); + + Tcl_ResetResult(interp); if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK) { - return TCL_ERROR; + goto error; } + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); } else { - Tcl_AppendResult(interp, "fill\n", NULL); + Tcl_AppendToObj(psObj, "fill\n", -1); } } } + /* + * Plug the accumulated postscript back into the result. + */ + + (void) Tcl_RestoreInterpState(interp, interpState); + Tcl_AppendObjToObj(Tcl_GetObjResult(interp), psObj); + Tcl_DecrRefCount(psObj); return TCL_OK; + + error: + Tcl_DiscardInterpState(interpState); + Tcl_DecrRefCount(psObj); + return TCL_ERROR; } /* @@ -2002,7 +2030,7 @@ StyleParseProc( ClientData clientData, /* some flags.*/ Tcl_Interp *interp, /* Used for reporting errors. */ Tk_Window tkwin, /* Window containing canvas widget. */ - CONST char *value, /* Value of option. */ + const char *value, /* Value of option. */ char *widgRec, /* Pointer to record for item. */ int offset) /* Offset into item. */ { @@ -2032,8 +2060,10 @@ StyleParseProc( return TCL_OK; } - Tcl_AppendResult(interp, "bad -style option \"", value, - "\": must be arc, chord, or pieslice", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad -style option \"%s\": must be arc, chord, or pieslice", + value)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "ARC_STYLE", NULL); *stylePtr = PIESLICE_STYLE; return TCL_ERROR; } @@ -2059,7 +2089,7 @@ StyleParseProc( *-------------------------------------------------------------- */ -static char * +static const char * StylePrintProc( ClientData clientData, /* Ignored. */ Tk_Window tkwin, /* Ignored. */ diff --git a/generic/tkCanvBmap.c b/generic/tkCanvBmap.c index fd8532f..b9de07b 100644 --- a/generic/tkCanvBmap.c +++ b/generic/tkCanvBmap.c @@ -10,7 +10,6 @@ * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ -#include <stdio.h> #include "tkInt.h" #include "tkCanvas.h" @@ -41,45 +40,43 @@ typedef struct BitmapItem { * Information used for parsing configuration specs: */ -static Tk_CustomOption stateOption = { - (Tk_OptionParseProc *) TkStateParseProc, - TkStatePrintProc, (ClientData) 2 +static const Tk_CustomOption stateOption = { + TkStateParseProc, TkStatePrintProc, INT2PTR(2) }; -static Tk_CustomOption tagsOption = { - (Tk_OptionParseProc *) Tk_CanvasTagsParseProc, - Tk_CanvasTagsPrintProc, (ClientData) NULL +static const Tk_CustomOption tagsOption = { + Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL }; -static Tk_ConfigSpec configSpecs[] = { +static const Tk_ConfigSpec configSpecs[] = { {TK_CONFIG_COLOR, "-activebackground", NULL, NULL, - NULL, Tk_Offset(BitmapItem, activeBgColor), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(BitmapItem, activeBgColor), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_BITMAP, "-activebitmap", NULL, NULL, - NULL, Tk_Offset(BitmapItem, activeBitmap), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(BitmapItem, activeBitmap), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_COLOR, "-activeforeground", NULL, NULL, - NULL, Tk_Offset(BitmapItem, activeFgColor), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(BitmapItem, activeFgColor), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_ANCHOR, "-anchor", NULL, NULL, - "center", Tk_Offset(BitmapItem, anchor), TK_CONFIG_DONT_SET_DEFAULT}, + "center", Tk_Offset(BitmapItem, anchor), TK_CONFIG_DONT_SET_DEFAULT, NULL}, {TK_CONFIG_COLOR, "-background", NULL, NULL, - NULL, Tk_Offset(BitmapItem, bgColor), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(BitmapItem, bgColor), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_BITMAP, "-bitmap", NULL, NULL, - NULL, Tk_Offset(BitmapItem, bitmap), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(BitmapItem, bitmap), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_COLOR, "-disabledbackground", NULL, NULL, NULL, Tk_Offset(BitmapItem, disabledBgColor), - TK_CONFIG_NULL_OK}, + TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_BITMAP, "-disabledbitmap", NULL, NULL, NULL, Tk_Offset(BitmapItem, disabledBitmap), - TK_CONFIG_NULL_OK}, + TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_COLOR, "-disabledforeground", NULL, NULL, NULL, Tk_Offset(BitmapItem, disabledFgColor), - TK_CONFIG_NULL_OK}, + TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_COLOR, "-foreground", NULL, NULL, - "black", Tk_Offset(BitmapItem, fgColor), 0}, + "black", Tk_Offset(BitmapItem, fgColor), 0, NULL}, {TK_CONFIG_CUSTOM, "-state", NULL, NULL, NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption}, {TK_CONFIG_CUSTOM, "-tags", NULL, NULL, NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, - {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} + {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL} }; /* @@ -88,7 +85,7 @@ static Tk_ConfigSpec configSpecs[] = { static int BitmapCoords(Tcl_Interp *interp, Tk_Canvas canvas, Tk_Item *itemPtr, int objc, - Tcl_Obj *CONST objv[]); + Tcl_Obj *const objv[]); static int BitmapToArea(Tk_Canvas canvas, Tk_Item *itemPtr, double *rectPtr); static double BitmapToPoint(Tk_Canvas canvas, @@ -99,10 +96,10 @@ static void ComputeBitmapBbox(Tk_Canvas canvas, BitmapItem *bmapPtr); static int ConfigureBitmap(Tcl_Interp *interp, Tk_Canvas canvas, Tk_Item *itemPtr, int objc, - Tcl_Obj *CONST objv[], int flags); + Tcl_Obj *const objv[], int flags); static int TkcCreateBitmap(Tcl_Interp *interp, Tk_Canvas canvas, struct Tk_Item *itemPtr, - int objc, Tcl_Obj *CONST objv[]); + int objc, Tcl_Obj *const objv[]); static void DeleteBitmap(Tk_Canvas canvas, Tk_Item *itemPtr, Display *display); static void DisplayBitmap(Tk_Canvas canvas, @@ -140,6 +137,7 @@ Tk_ItemType tkBitmapType = { NULL, /* insertProc */ NULL, /* dTextProc */ NULL, /* nextPtr */ + NULL, 0, NULL, NULL }; /* @@ -168,13 +166,13 @@ TkcCreateBitmap( Tk_Item *itemPtr, /* Record to hold new item; header has been * initialized by caller. */ int objc, /* Number of arguments in objv. */ - Tcl_Obj *CONST objv[]) /* Arguments describing rectangle. */ + Tcl_Obj *const objv[]) /* Arguments describing rectangle. */ { BitmapItem *bmapPtr = (BitmapItem *) itemPtr; int i; if (objc == 0) { - Tcl_Panic("canvas did not pass any coords\n"); + Tcl_Panic("canvas did not pass any coords"); } /* @@ -201,7 +199,7 @@ TkcCreateBitmap( if (objc == 1) { i = 1; } else { - char *arg = Tcl_GetString(objv[1]); + const char *arg = Tcl_GetString(objv[1]); i = 2; if ((arg[0] == '-') && (arg[1] >= 'a') && (arg[1] <= 'z')) { i = 1; @@ -244,17 +242,15 @@ BitmapCoords( Tk_Item *itemPtr, /* Item whose coordinates are to be read or * modified. */ int objc, /* Number of coordinates supplied in objv. */ - Tcl_Obj *CONST objv[]) /* Array of coordinates: x1, y1, x2, y2, ... */ + Tcl_Obj *const objv[]) /* Array of coordinates: x1, y1, x2, y2, ... */ { BitmapItem *bmapPtr = (BitmapItem *) itemPtr; if (objc == 0) { Tcl_Obj *obj = Tcl_NewObj(); - Tcl_Obj *subobj = Tcl_NewDoubleObj(bmapPtr->x); - Tcl_ListObjAppendElement(interp, obj, subobj); - subobj = Tcl_NewDoubleObj(bmapPtr->y); - Tcl_ListObjAppendElement(interp, obj, subobj); + Tcl_ListObjAppendElement(NULL, obj, Tcl_NewDoubleObj(bmapPtr->x)); + Tcl_ListObjAppendElement(NULL, obj, Tcl_NewDoubleObj(bmapPtr->y)); Tcl_SetObjResult(interp, obj); } else if (objc < 3) { if (objc == 1) { @@ -262,10 +258,10 @@ BitmapCoords( (Tcl_Obj ***) &objv) != TCL_OK) { return TCL_ERROR; } else if (objc != 2) { - char buf[64 + TCL_INTEGER_SPACE]; - - sprintf(buf, "wrong # coordinates: expected 2, got %d", objc); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "wrong # coordinates: expected 2, got %d", objc)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "BITMAP", + NULL); return TCL_ERROR; } } @@ -277,10 +273,9 @@ BitmapCoords( } ComputeBitmapBbox(canvas, bmapPtr); } else { - char buf[64 + TCL_INTEGER_SPACE]; - - sprintf(buf, "wrong # coordinates: expected 0 or 2, got %d", objc); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "wrong # coordinates: expected 0 or 2, got %d", objc)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "BITMAP", NULL); return TCL_ERROR; } return TCL_OK; @@ -310,7 +305,7 @@ ConfigureBitmap( Tk_Canvas canvas, /* Canvas containing itemPtr. */ Tk_Item *itemPtr, /* Bitmap item to reconfigure. */ int objc, /* Number of elements in objv. */ - Tcl_Obj *CONST objv[], /* Arguments describing things to configure. */ + Tcl_Obj *const objv[], /* Arguments describing things to configure. */ int flags) /* Flags to pass to Tk_ConfigureWidget. */ { BitmapItem *bmapPtr = (BitmapItem *) itemPtr; @@ -325,7 +320,7 @@ ConfigureBitmap( tkwin = Tk_CanvasTkwin(canvas); if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc, - (CONST char **) objv, (char *) bmapPtr, flags|TK_CONFIG_OBJS)) { + (const char **) objv, (char *) bmapPtr, flags|TK_CONFIG_OBJS)) { return TCL_ERROR; } @@ -345,7 +340,7 @@ ConfigureBitmap( } if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } if (state == TK_STATE_HIDDEN) { ComputeBitmapBbox(canvas, bmapPtr); @@ -354,7 +349,7 @@ ConfigureBitmap( fgColor = bmapPtr->fgColor; bgColor = bmapPtr->bgColor; bitmap = bmapPtr->bitmap; - if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { + if (Canvas(canvas)->currentItemPtr == itemPtr) { if (bmapPtr->activeFgColor!=NULL) { fgColor = bmapPtr->activeFgColor; } @@ -486,10 +481,10 @@ ComputeBitmapBbox( Tk_State state = bmapPtr->header.state; if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } bitmap = bmapPtr->bitmap; - if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *)bmapPtr) { + if (Canvas(canvas)->currentItemPtr == (Tk_Item *)bmapPtr) { if (bmapPtr->activeBitmap!=None) { bitmap = bmapPtr->activeBitmap; } @@ -596,10 +591,10 @@ DisplayBitmap( */ if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } bitmap = bmapPtr->bitmap; - if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { + if (Canvas(canvas)->currentItemPtr == itemPtr) { if (bmapPtr->activeBitmap!=None) { bitmap = bmapPtr->activeBitmap; } @@ -855,19 +850,20 @@ BitmapToPostscript( double x, y; int width, height, rowsAtOnce, rowsThisTime; int curRow; - char buffer[100 + TCL_DOUBLE_SPACE * 2 + TCL_INTEGER_SPACE * 4]; XColor *fgColor; XColor *bgColor; Pixmap bitmap; Tk_State state = itemPtr->state; + Tcl_Obj *psObj; + Tcl_InterpState interpState; if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } fgColor = bmapPtr->fgColor; bgColor = bmapPtr->bgColor; bitmap = bmapPtr->bitmap; - if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { + if (Canvas(canvas)->currentItemPtr == itemPtr) { if (bmapPtr->activeFgColor!=NULL) { fgColor = bmapPtr->activeFgColor; } @@ -915,18 +911,29 @@ BitmapToPostscript( } /* + * Make our working space. + */ + + psObj = Tcl_NewObj(); + interpState = Tcl_SaveInterpState(interp, TCL_OK); + + /* * Color the background, if there is one. */ if (bgColor != NULL) { - sprintf(buffer, - "%.15g %.15g moveto %d 0 rlineto 0 %d rlineto %d %s\n", - x, y, width, height, -width, "0 rlineto closepath"); - Tcl_AppendResult(interp, buffer, NULL); + Tcl_AppendPrintfToObj(psObj, + "%.15g %.15g moveto %d 0 rlineto 0 %d rlineto " + "%d 0 rlineto closepath\n", + x, y, width, height, -width); + + Tcl_ResetResult(interp); if (Tk_CanvasPsColor(interp, canvas, bgColor) != TCL_OK) { - return TCL_ERROR; + goto error; } - Tcl_AppendResult(interp, "fill\n", NULL); + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); + + Tcl_AppendToObj(psObj, "fill\n", -1); } /* @@ -937,37 +944,61 @@ BitmapToPostscript( */ if (fgColor != NULL) { + Tcl_ResetResult(interp); if (Tk_CanvasPsColor(interp, canvas, fgColor) != TCL_OK) { - return TCL_ERROR; + goto error; } + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); + if (width > 60000) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "can't generate Postscript", - " for bitmaps more than 60000 pixels wide", NULL); - return TCL_ERROR; + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "can't generate Postscript for bitmaps more than 60000" + " pixels wide", -1)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "PS", "MEMLIMIT", NULL); + goto error; } + rowsAtOnce = 60000/width; if (rowsAtOnce < 1) { rowsAtOnce = 1; } - sprintf(buffer, "%.15g %.15g translate\n", x, y+height); - Tcl_AppendResult(interp, buffer, NULL); + + Tcl_AppendPrintfToObj(psObj, "%.15g %.15g translate\n", x, y+height); + for (curRow = 0; curRow < height; curRow += rowsAtOnce) { rowsThisTime = rowsAtOnce; if (rowsThisTime > (height - curRow)) { rowsThisTime = height - curRow; } - sprintf(buffer, "0 -%.15g translate\n%d %d true matrix {\n", + + Tcl_AppendPrintfToObj(psObj, + "0 -%.15g translate\n%d %d true matrix {\n", (double) rowsThisTime, width, rowsThisTime); - Tcl_AppendResult(interp, buffer, NULL); + + Tcl_ResetResult(interp); if (Tk_CanvasPsBitmap(interp, canvas, bitmap, 0, curRow, width, rowsThisTime) != TCL_OK) { - return TCL_ERROR; + goto error; } - Tcl_AppendResult(interp, "\n} imagemask\n", NULL); + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); + + Tcl_AppendToObj(psObj, "\n} imagemask\n", -1); } } + + /* + * Plug the accumulated postscript back into the result. + */ + + (void) Tcl_RestoreInterpState(interp, interpState); + Tcl_AppendObjToObj(Tcl_GetObjResult(interp), psObj); + Tcl_DecrRefCount(psObj); return TCL_OK; + + error: + Tcl_DiscardInterpState(interpState); + Tcl_DecrRefCount(psObj); + return TCL_ERROR; } /* diff --git a/generic/tkCanvImg.c b/generic/tkCanvImg.c index 81971c1..70b9c79 100644 --- a/generic/tkCanvImg.c +++ b/generic/tkCanvImg.c @@ -10,7 +10,6 @@ * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ -#include <stdio.h> #include "tkInt.h" #include "tkCanvas.h" @@ -44,29 +43,27 @@ typedef struct ImageItem { * Information used for parsing configuration specs: */ -static Tk_CustomOption stateOption = { - (Tk_OptionParseProc *) TkStateParseProc, - TkStatePrintProc, (ClientData) 2 +static const Tk_CustomOption stateOption = { + TkStateParseProc, TkStatePrintProc, INT2PTR(2) }; -static Tk_CustomOption tagsOption = { - (Tk_OptionParseProc *) Tk_CanvasTagsParseProc, - Tk_CanvasTagsPrintProc, (ClientData) NULL +static const Tk_CustomOption tagsOption = { + Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL }; -static Tk_ConfigSpec configSpecs[] = { +static const Tk_ConfigSpec configSpecs[] = { {TK_CONFIG_STRING, "-activeimage", NULL, NULL, - NULL, Tk_Offset(ImageItem, activeImageString), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(ImageItem, activeImageString), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_ANCHOR, "-anchor", NULL, NULL, - "center", Tk_Offset(ImageItem, anchor), TK_CONFIG_DONT_SET_DEFAULT}, + "center", Tk_Offset(ImageItem, anchor), TK_CONFIG_DONT_SET_DEFAULT, NULL}, {TK_CONFIG_STRING, "-disabledimage", NULL, NULL, - NULL, Tk_Offset(ImageItem, disabledImageString), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(ImageItem, disabledImageString), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_STRING, "-image", NULL, NULL, - NULL, Tk_Offset(ImageItem, imageString), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(ImageItem, imageString), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_CUSTOM, "-state", NULL, NULL, NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption}, {TK_CONFIG_CUSTOM, "-tags", NULL, NULL, NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, - {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} + {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL} }; /* @@ -78,7 +75,7 @@ static void ImageChangedProc(ClientData clientData, int imgHeight); static int ImageCoords(Tcl_Interp *interp, Tk_Canvas canvas, Tk_Item *itemPtr, int argc, - Tcl_Obj *CONST argv[]); + Tcl_Obj *const argv[]); static int ImageToArea(Tk_Canvas canvas, Tk_Item *itemPtr, double *rectPtr); static double ImageToPoint(Tk_Canvas canvas, @@ -88,10 +85,10 @@ static int ImageToPostscript(Tcl_Interp *interp, static void ComputeImageBbox(Tk_Canvas canvas, ImageItem *imgPtr); static int ConfigureImage(Tcl_Interp *interp, Tk_Canvas canvas, Tk_Item *itemPtr, int argc, - Tcl_Obj *CONST argv[], int flags); + Tcl_Obj *const argv[], int flags); static int CreateImage(Tcl_Interp *interp, Tk_Canvas canvas, struct Tk_Item *itemPtr, - int argc, Tcl_Obj *CONST argv[]); + int argc, Tcl_Obj *const argv[]); static void DeleteImage(Tk_Canvas canvas, Tk_Item *itemPtr, Display *display); static void DisplayImage(Tk_Canvas canvas, @@ -129,6 +126,7 @@ Tk_ItemType tkImageType = { NULL, /* insertProc */ NULL, /* dTextProc */ NULL, /* nextPtr */ + NULL, 0, NULL, NULL }; /* @@ -157,13 +155,13 @@ CreateImage( Tk_Item *itemPtr, /* Record to hold new item; header has been * initialized by caller. */ int objc, /* Number of arguments in objv. */ - Tcl_Obj *CONST objv[]) /* Arguments describing rectangle. */ + Tcl_Obj *const objv[]) /* Arguments describing rectangle. */ { ImageItem *imgPtr = (ImageItem *) itemPtr; int i; if (objc == 0) { - Tcl_Panic("canvas did not pass any coords\n"); + Tcl_Panic("canvas did not pass any coords"); } /* @@ -187,7 +185,7 @@ CreateImage( if (objc == 1) { i = 1; } else { - char *arg = Tcl_GetString(objv[1]); + const char *arg = Tcl_GetString(objv[1]); i = 2; if ((arg[0] == '-') && (arg[1] >= 'a') && (arg[1] <= 'z')) { i = 1; @@ -229,42 +227,40 @@ ImageCoords( Tk_Item *itemPtr, /* Item whose coordinates are to be read or * modified. */ int objc, /* Number of coordinates supplied in objv. */ - Tcl_Obj *CONST objv[]) /* Array of coordinates: x1, y1, x2, y2, ... */ + Tcl_Obj *const objv[]) /* Array of coordinates: x1, y1, x2, y2, ... */ { ImageItem *imgPtr = (ImageItem *) itemPtr; if (objc == 0) { - Tcl_Obj *obj = Tcl_NewObj(); + Tcl_Obj *objs[2]; - Tcl_Obj *subobj = Tcl_NewDoubleObj(imgPtr->x); - Tcl_ListObjAppendElement(interp, obj, subobj); - subobj = Tcl_NewDoubleObj(imgPtr->y); - Tcl_ListObjAppendElement(interp, obj, subobj); - Tcl_SetObjResult(interp, obj); + objs[0] = Tcl_NewDoubleObj(imgPtr->x); + objs[1] = Tcl_NewDoubleObj(imgPtr->y); + Tcl_SetObjResult(interp, Tcl_NewListObj(2, objs)); } else if (objc < 3) { if (objc==1) { if (Tcl_ListObjGetElements(interp, objv[0], &objc, (Tcl_Obj ***) &objv) != TCL_OK) { return TCL_ERROR; } else if (objc != 2) { - char buf[64]; - - sprintf(buf, "wrong # coordinates: expected 2, got %d", objc); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "wrong # coordinates: expected 2, got %d", objc)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "IMAGE", + NULL); return TCL_ERROR; } } - if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0], &imgPtr->x) != TCL_OK) + if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0], + &imgPtr->x) != TCL_OK) || (Tk_CanvasGetCoordFromObj(interp, canvas, objv[1], &imgPtr->y) != TCL_OK)) { return TCL_ERROR; } ComputeImageBbox(canvas, imgPtr); } else { - char buf[64]; - - sprintf(buf, "wrong # coordinates: expected 0 or 2, got %d", objc); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "wrong # coordinates: expected 0 or 2, got %d", objc)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "IMAGE", NULL); return TCL_ERROR; } return TCL_OK; @@ -294,7 +290,7 @@ ConfigureImage( Tk_Canvas canvas, /* Canvas containing itemPtr. */ Tk_Item *itemPtr, /* Image item to reconfigure. */ int objc, /* Number of elements in objv. */ - Tcl_Obj *CONST objv[], /* Arguments describing things to configure. */ + Tcl_Obj *const objv[], /* Arguments describing things to configure. */ int flags) /* Flags to pass to Tk_ConfigureWidget. */ { ImageItem *imgPtr = (ImageItem *) itemPtr; @@ -303,7 +299,7 @@ ConfigureImage( tkwin = Tk_CanvasTkwin(canvas); if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc, - (CONST char **) objv, (char *) imgPtr, flags|TK_CONFIG_OBJS)) { + (const char **) objv, (char *) imgPtr, flags|TK_CONFIG_OBJS)) { return TCL_ERROR; } @@ -321,7 +317,7 @@ ConfigureImage( } if (imgPtr->imageString != NULL) { image = Tk_GetImage(interp, tkwin, imgPtr->imageString, - ImageChangedProc, (ClientData) imgPtr); + ImageChangedProc, imgPtr); if (image == NULL) { return TCL_ERROR; } @@ -334,7 +330,7 @@ ConfigureImage( imgPtr->image = image; if (imgPtr->activeImageString != NULL) { image = Tk_GetImage(interp, tkwin, imgPtr->activeImageString, - ImageChangedProc, (ClientData) imgPtr); + ImageChangedProc, imgPtr); if (image == NULL) { return TCL_ERROR; } @@ -347,7 +343,7 @@ ConfigureImage( imgPtr->activeImage = image; if (imgPtr->disabledImageString != NULL) { image = Tk_GetImage(interp, tkwin, imgPtr->disabledImageString, - ImageChangedProc, (ClientData) imgPtr); + ImageChangedProc, imgPtr); if (image == NULL) { return TCL_ERROR; } @@ -437,10 +433,10 @@ ComputeImageBbox( Tk_State state = imgPtr->header.state; if(state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } image = imgPtr->image; - if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *)imgPtr) { + if (Canvas(canvas)->currentItemPtr == (Tk_Item *)imgPtr) { if (imgPtr->activeImage != NULL) { image = imgPtr->activeImage; } @@ -540,11 +536,11 @@ DisplayImage( Tk_State state = itemPtr->state; if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } image = imgPtr->image; - if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { + if (Canvas(canvas)->currentItemPtr == itemPtr) { if (imgPtr->activeImage != NULL) { image = imgPtr->activeImage; } @@ -697,21 +693,19 @@ ImageToPostscript( * information; 0 means final Postscript is * being created.*/ { - ImageItem *imgPtr = (ImageItem *)itemPtr; + ImageItem *imgPtr = (ImageItem *) itemPtr; Tk_Window canvasWin = Tk_CanvasTkwin(canvas); - - char buffer[256]; double x, y; int width, height; Tk_Image image; Tk_State state = itemPtr->state; - if(state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + if (state == TK_STATE_NULL) { + state = Canvas(canvas)->canvas_state; } image = imgPtr->image; - if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { + if (Canvas(canvas)->currentItemPtr == itemPtr) { if (imgPtr->activeImage != NULL) { image = imgPtr->activeImage; } @@ -750,8 +744,14 @@ ImageToPostscript( } if (!prepass) { - sprintf(buffer, "%.15g %.15g", x, y); - Tcl_AppendResult(interp, buffer, " translate\n", NULL); + Tcl_Obj *psObj = Tcl_GetObjResult(interp); + + if (Tcl_IsShared(psObj)) { + psObj = Tcl_DuplicateObj(psObj); + Tcl_SetObjResult(interp, psObj); + } + + Tcl_AppendPrintfToObj(psObj, "%.15g %.15g translate\n", x, y); } return Tk_PostscriptImage(image, interp, canvasWin, @@ -851,7 +851,7 @@ ImageChangedProc( * 0). */ int imgWidth, int imgHeight)/* New dimensions of image. */ { - ImageItem *imgPtr = (ImageItem *) clientData; + ImageItem *imgPtr = clientData; /* * If the image's size changed and it's not anchored at its northwest diff --git a/generic/tkCanvLine.c b/generic/tkCanvLine.c index 0294aa8..b6c845d 100644 --- a/generic/tkCanvLine.c +++ b/generic/tkCanvLine.c @@ -11,7 +11,6 @@ * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ -#include <stdio.h> #include "tkInt.h" #include "tkCanvas.h" @@ -23,7 +22,7 @@ typedef enum { ARROWS_NONE, ARROWS_FIRST, ARROWS_LAST, ARROWS_BOTH } Arrows; -typedef struct LineItem { +typedef struct LineItem { Tk_Item header; /* Generic stuff that's the same for all * types. MUST BE FIRST IN STRUCTURE. */ Tk_Outline outline; /* Outline structure */ @@ -59,7 +58,7 @@ typedef struct LineItem { * point in line (PTS_IN_ARROW points, first * of which is tip). Malloc'ed. NULL means no * arrowhead at last point. */ - Tk_SmoothMethod *smooth; /* Non-zero means draw line smoothed (i.e. + const Tk_SmoothMethod *smooth; /* Non-zero means draw line smoothed (i.e. * with Bezier splines). */ int splineSteps; /* Number of steps in each spline segment. */ } LineItem; @@ -76,15 +75,15 @@ typedef struct LineItem { static int ArrowheadPostscript(Tcl_Interp *interp, Tk_Canvas canvas, LineItem *linePtr, - double *arrowPtr); + double *arrowPtr, Tcl_Obj *psObj); static void ComputeLineBbox(Tk_Canvas canvas, LineItem *linePtr); static int ConfigureLine(Tcl_Interp *interp, Tk_Canvas canvas, Tk_Item *itemPtr, int objc, - Tcl_Obj *CONST objv[], int flags); + Tcl_Obj *const objv[], int flags); static int ConfigureArrows(Tk_Canvas canvas, LineItem *linePtr); static int CreateLine(Tcl_Interp *interp, Tk_Canvas canvas, struct Tk_Item *itemPtr, - int objc, Tcl_Obj *CONST objv[]); + int objc, Tcl_Obj *const objv[]); static void DeleteLine(Tk_Canvas canvas, Tk_Item *itemPtr, Display *display); static void DisplayLine(Tk_Canvas canvas, @@ -95,7 +94,7 @@ static int GetLineIndex(Tcl_Interp *interp, Tcl_Obj *obj, int *indexPtr); static int LineCoords(Tcl_Interp *interp, Tk_Canvas canvas, Tk_Item *itemPtr, - int objc, Tcl_Obj *CONST objv[]); + int objc, Tcl_Obj *const objv[]); static void LineDeleteCoords(Tk_Canvas canvas, Tk_Item *itemPtr, int first, int last); static void LineInsert(Tk_Canvas canvas, @@ -108,14 +107,14 @@ static int LineToPostscript(Tcl_Interp *interp, Tk_Canvas canvas, Tk_Item *itemPtr, int prepass); static int ArrowParseProc(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, - CONST char *value, char *recordPtr, int offset); -static char * ArrowPrintProc(ClientData clientData, + const char *value, char *recordPtr, int offset); +static const char * ArrowPrintProc(ClientData clientData, Tk_Window tkwin, char *recordPtr, int offset, Tcl_FreeProc **freeProcPtr); static int ParseArrowShape(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, - CONST char *value, char *recordPtr, int offset); -static char * PrintArrowShape(ClientData clientData, + const char *value, char *recordPtr, int offset); +static const char * PrintArrowShape(ClientData clientData, Tk_Window tkwin, char *recordPtr, int offset, Tcl_FreeProc **freeProcPtr); static void ScaleLine(Tk_Canvas canvas, @@ -123,84 +122,77 @@ static void ScaleLine(Tk_Canvas canvas, double scaleX, double scaleY); static void TranslateLine(Tk_Canvas canvas, Tk_Item *itemPtr, double deltaX, double deltaY); - + /* * Information used for parsing configuration specs. If you change any of the * default strings, be sure to change the corresponding default values in * CreateLine. */ -static Tk_CustomOption arrowShapeOption = { - (Tk_OptionParseProc *) ParseArrowShape, - PrintArrowShape, (ClientData) NULL +static const Tk_CustomOption arrowShapeOption = { + ParseArrowShape, PrintArrowShape, NULL }; -static Tk_CustomOption arrowOption = { - (Tk_OptionParseProc *) ArrowParseProc, - ArrowPrintProc, (ClientData) NULL +static const Tk_CustomOption arrowOption = { + ArrowParseProc, ArrowPrintProc, NULL }; -static Tk_CustomOption smoothOption = { - (Tk_OptionParseProc *) TkSmoothParseProc, - TkSmoothPrintProc, (ClientData) NULL +static const Tk_CustomOption smoothOption = { + TkSmoothParseProc, TkSmoothPrintProc, NULL }; -static Tk_CustomOption stateOption = { - (Tk_OptionParseProc *) TkStateParseProc, - TkStatePrintProc, (ClientData) 2 +static const Tk_CustomOption stateOption = { + TkStateParseProc, TkStatePrintProc, INT2PTR(2) }; -static Tk_CustomOption tagsOption = { - (Tk_OptionParseProc *) Tk_CanvasTagsParseProc, - Tk_CanvasTagsPrintProc, (ClientData) NULL +static const Tk_CustomOption tagsOption = { + Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL }; -static Tk_CustomOption dashOption = { - (Tk_OptionParseProc *) TkCanvasDashParseProc, - TkCanvasDashPrintProc, (ClientData) NULL +static const Tk_CustomOption dashOption = { + TkCanvasDashParseProc, TkCanvasDashPrintProc, NULL }; -static Tk_CustomOption offsetOption = { - (Tk_OptionParseProc *) TkOffsetParseProc, - TkOffsetPrintProc, - (ClientData) (TK_OFFSET_RELATIVE|TK_OFFSET_INDEX) +static const Tk_CustomOption offsetOption = { + TkOffsetParseProc, TkOffsetPrintProc, + INT2PTR(TK_OFFSET_RELATIVE|TK_OFFSET_INDEX) }; -static Tk_CustomOption pixelOption = { - (Tk_OptionParseProc *) TkPixelParseProc, - TkPixelPrintProc, (ClientData) NULL +static const Tk_CustomOption pixelOption = { + TkPixelParseProc, TkPixelPrintProc, NULL }; -static Tk_ConfigSpec configSpecs[] = { +static const Tk_ConfigSpec configSpecs[] = { {TK_CONFIG_CUSTOM, "-activedash", NULL, NULL, NULL, Tk_Offset(LineItem, outline.activeDash), TK_CONFIG_NULL_OK, &dashOption}, {TK_CONFIG_COLOR, "-activefill", NULL, NULL, - NULL, Tk_Offset(LineItem, outline.activeColor), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(LineItem, outline.activeColor), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_BITMAP, "-activestipple", NULL, NULL, - NULL, Tk_Offset(LineItem, outline.activeStipple), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(LineItem, outline.activeStipple), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_CUSTOM, "-activewidth", NULL, NULL, "0.0", Tk_Offset(LineItem, outline.activeWidth), TK_CONFIG_DONT_SET_DEFAULT, &pixelOption}, {TK_CONFIG_CUSTOM, "-arrow", NULL, NULL, - "none", Tk_Offset(LineItem, arrow), TK_CONFIG_DONT_SET_DEFAULT, &arrowOption}, + "none", Tk_Offset(LineItem, arrow), + TK_CONFIG_DONT_SET_DEFAULT, &arrowOption}, {TK_CONFIG_CUSTOM, "-arrowshape", NULL, NULL, "8 10 3", Tk_Offset(LineItem, arrowShapeA), TK_CONFIG_DONT_SET_DEFAULT, &arrowShapeOption}, {TK_CONFIG_CAP_STYLE, "-capstyle", NULL, NULL, - "butt", Tk_Offset(LineItem, capStyle), TK_CONFIG_DONT_SET_DEFAULT}, + "butt", Tk_Offset(LineItem, capStyle), TK_CONFIG_DONT_SET_DEFAULT, NULL}, {TK_CONFIG_COLOR, "-fill", NULL, NULL, - "black", Tk_Offset(LineItem, outline.color), TK_CONFIG_NULL_OK}, + "black", Tk_Offset(LineItem, outline.color), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_CUSTOM, "-dash", NULL, NULL, NULL, Tk_Offset(LineItem, outline.dash), TK_CONFIG_NULL_OK, &dashOption}, {TK_CONFIG_PIXELS, "-dashoffset", NULL, NULL, - "0", Tk_Offset(LineItem, outline.offset), TK_CONFIG_DONT_SET_DEFAULT}, + "0", Tk_Offset(LineItem, outline.offset), TK_CONFIG_DONT_SET_DEFAULT, NULL}, {TK_CONFIG_CUSTOM, "-disableddash", NULL, NULL, NULL, Tk_Offset(LineItem, outline.disabledDash), TK_CONFIG_NULL_OK, &dashOption}, {TK_CONFIG_COLOR, "-disabledfill", NULL, NULL, - NULL, Tk_Offset(LineItem, outline.disabledColor), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(LineItem, outline.disabledColor), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_BITMAP, "-disabledstipple", NULL, NULL, - NULL, Tk_Offset(LineItem, outline.disabledStipple), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(LineItem, outline.disabledStipple), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_CUSTOM, "-disabledwidth", NULL, NULL, "0.0", Tk_Offset(LineItem, outline.disabledWidth), TK_CONFIG_DONT_SET_DEFAULT, &pixelOption}, {TK_CONFIG_JOIN_STYLE, "-joinstyle", NULL, NULL, - "round", Tk_Offset(LineItem, joinStyle), TK_CONFIG_DONT_SET_DEFAULT}, + "round", Tk_Offset(LineItem, joinStyle), TK_CONFIG_DONT_SET_DEFAULT, NULL}, {TK_CONFIG_CUSTOM, "-offset", NULL, NULL, "0,0", Tk_Offset(LineItem, outline.tsoffset), TK_CONFIG_DONT_SET_DEFAULT, &offsetOption}, @@ -208,17 +200,17 @@ static Tk_ConfigSpec configSpecs[] = { "0", Tk_Offset(LineItem, smooth), TK_CONFIG_DONT_SET_DEFAULT, &smoothOption}, {TK_CONFIG_INT, "-splinesteps", NULL, NULL, - "12", Tk_Offset(LineItem, splineSteps), TK_CONFIG_DONT_SET_DEFAULT}, + "12", Tk_Offset(LineItem, splineSteps), TK_CONFIG_DONT_SET_DEFAULT, NULL}, {TK_CONFIG_CUSTOM, "-state", NULL, NULL, NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption}, {TK_CONFIG_BITMAP, "-stipple", NULL, NULL, - NULL, Tk_Offset(LineItem, outline.stipple), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(LineItem, outline.stipple), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_CUSTOM, "-tags", NULL, NULL, NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, {TK_CONFIG_CUSTOM, "-width", NULL, NULL, "1.0", Tk_Offset(LineItem, outline.width), TK_CONFIG_DONT_SET_DEFAULT, &pixelOption}, - {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} + {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL} }; /* @@ -235,18 +227,19 @@ Tk_ItemType tkLineType = { LineCoords, /* coordProc */ DeleteLine, /* deleteProc */ DisplayLine, /* displayProc */ - TK_CONFIG_OBJS, /* flags */ + TK_CONFIG_OBJS | TK_MOVABLE_POINTS, /* flags */ LineToPoint, /* pointProc */ LineToArea, /* areaProc */ LineToPostscript, /* postscriptProc */ ScaleLine, /* scaleProc */ TranslateLine, /* translateProc */ - (Tk_ItemIndexProc *) GetLineIndex, /* indexProc */ + GetLineIndex, /* indexProc */ NULL, /* icursorProc */ NULL, /* selectionProc */ - (Tk_ItemInsertProc *) LineInsert, /* insertProc */ + LineInsert, /* insertProc */ LineDeleteCoords, /* dTextProc */ NULL, /* nextPtr */ + NULL, 0, NULL, NULL }; /* @@ -283,13 +276,13 @@ CreateLine( Tk_Item *itemPtr, /* Record to hold new item; header has been * initialized by caller. */ int objc, /* Number of arguments in objv. */ - Tcl_Obj *CONST objv[]) /* Arguments describing line. */ + Tcl_Obj *const objv[]) /* Arguments describing line. */ { LineItem *linePtr = (LineItem *) itemPtr; int i; if (objc == 0) { - Tcl_Panic("canvas did not pass any coords\n"); + Tcl_Panic("canvas did not pass any coords"); } /* @@ -297,7 +290,7 @@ CreateLine( * proper cleanup after errors during the the remainder of this function. */ - Tk_CreateOutline(&(linePtr->outline)); + Tk_CreateOutline(&linePtr->outline); linePtr->canvas = canvas; linePtr->numPoints = 0; linePtr->coordPtr = NULL; @@ -320,7 +313,7 @@ CreateLine( */ for (i = 1; i < objc; i++) { - char *arg = Tcl_GetString(objv[i]); + const char *arg = Tcl_GetString(objv[i]); if ((arg[0] == '-') && (arg[1] >= 'a') && (arg[1] <= 'z')) { break; @@ -362,7 +355,7 @@ LineCoords( Tk_Item *itemPtr, /* Item whose coordinates are to be read or * modified. */ int objc, /* Number of coordinates supplied in objv. */ - Tcl_Obj *CONST objv[]) /* Array of coordinates: x1, y1, x2, y2, ... */ + Tcl_Obj *const objv[]) /* Array of coordinates: x1, y1, x2, y2, ... */ { LineItem *linePtr = (LineItem *) itemPtr; int i, numPoints; @@ -398,55 +391,52 @@ LineCoords( } } if (objc & 1) { - char buf[64 + TCL_INTEGER_SPACE]; - - sprintf(buf, "wrong # coordinates: expected an even number, got %d", - objc); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "wrong # coordinates: expected an even number, got %d", + objc)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "LINE", NULL); return TCL_ERROR; } else if (objc < 4) { - char buf[64 + TCL_INTEGER_SPACE]; - - sprintf(buf, "wrong # coordinates: expected at least 4, got %d", objc); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "wrong # coordinates: expected at least 4, got %d", objc)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "LINE", NULL); return TCL_ERROR; - } else { - numPoints = objc/2; - if (linePtr->numPoints != numPoints) { - coordPtr = (double *) - ckalloc((unsigned) (sizeof(double) * objc)); - if (linePtr->coordPtr != NULL) { - ckfree((char *) linePtr->coordPtr); - } - linePtr->coordPtr = coordPtr; - linePtr->numPoints = numPoints; - } - coordPtr = linePtr->coordPtr; - for (i = 0; i <objc; i++) { - if (Tk_CanvasGetCoordFromObj(interp, canvas, objv[i], - coordPtr++) != TCL_OK) { - return TCL_ERROR; - } - } - - /* - * Update arrowheads by throwing away any existing arrow-head - * information and calling ConfigureArrows to recompute it. - */ + } - if (linePtr->firstArrowPtr != NULL) { - ckfree((char *) linePtr->firstArrowPtr); - linePtr->firstArrowPtr = NULL; - } - if (linePtr->lastArrowPtr != NULL) { - ckfree((char *) linePtr->lastArrowPtr); - linePtr->lastArrowPtr = NULL; + numPoints = objc/2; + if (linePtr->numPoints != numPoints) { + coordPtr = ckalloc(sizeof(double) * objc); + if (linePtr->coordPtr != NULL) { + ckfree(linePtr->coordPtr); } - if (linePtr->arrow != ARROWS_NONE) { - ConfigureArrows(canvas, linePtr); + linePtr->coordPtr = coordPtr; + linePtr->numPoints = numPoints; + } + coordPtr = linePtr->coordPtr; + for (i = 0; i < objc ; i++) { + if (Tk_CanvasGetCoordFromObj(interp, canvas, objv[i], + coordPtr++) != TCL_OK) { + return TCL_ERROR; } - ComputeLineBbox(canvas, linePtr); } + + /* + * Update arrowheads by throwing away any existing arrow-head information + * and calling ConfigureArrows to recompute it. + */ + + if (linePtr->firstArrowPtr != NULL) { + ckfree(linePtr->firstArrowPtr); + linePtr->firstArrowPtr = NULL; + } + if (linePtr->lastArrowPtr != NULL) { + ckfree(linePtr->lastArrowPtr); + linePtr->lastArrowPtr = NULL; + } + if (linePtr->arrow != ARROWS_NONE) { + ConfigureArrows(canvas, linePtr); + } + ComputeLineBbox(canvas, linePtr); return TCL_OK; } @@ -474,8 +464,8 @@ ConfigureLine( Tcl_Interp *interp, /* Used for error reporting. */ Tk_Canvas canvas, /* Canvas containing itemPtr. */ Tk_Item *itemPtr, /* Line item to reconfigure. */ - int objc, /* Number of elements in objv. */ - Tcl_Obj *CONST objv[], /* Arguments describing things to configure. */ + int objc, /* Number of elements in objv. */ + Tcl_Obj *const objv[], /* Arguments describing things to configure. */ int flags) /* Flags to pass to Tk_ConfigureWidget. */ { LineItem *linePtr = (LineItem *) itemPtr; @@ -487,7 +477,7 @@ ConfigureLine( tkwin = Tk_CanvasTkwin(canvas); if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc, - (CONST char **) objv, (char *) linePtr, flags|TK_CONFIG_OBJS)) { + (const char **) objv, (char *) linePtr, flags|TK_CONFIG_OBJS)) { return TCL_ERROR; } @@ -498,8 +488,8 @@ ConfigureLine( state = itemPtr->state; - if(state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + if (state == TK_STATE_NULL) { + state = Canvas(canvas)->canvas_state; } if (linePtr->outline.activeWidth > linePtr->outline.width || @@ -510,8 +500,7 @@ ConfigureLine( } else { itemPtr->redraw_flags &= ~TK_ITEM_STATE_DEPENDANT; } - mask = Tk_ConfigOutlineGC(&gcValues, canvas, itemPtr, - &(linePtr->outline)); + mask = Tk_ConfigOutlineGC(&gcValues, canvas, itemPtr, &linePtr->outline); if (mask) { if (linePtr->arrow == ARROWS_NONE) { gcValues.cap_style = linePtr->capStyle; @@ -522,9 +511,10 @@ ConfigureLine( newGC = Tk_GetGC(tkwin, mask, &gcValues); #ifdef MAC_OSX_TK /* - * Mac OS X CG drawing needs access to linewidth even for - * arrow fills (as linewidth controls antialiasing). + * Mac OS X CG drawing needs access to linewidth even for arrow fills + * (as linewidth controls antialiasing). */ + mask |= GCLineWidth; #else gcValues.line_width = 0; @@ -552,7 +542,7 @@ ConfigureLine( linePtr->splineSteps = 100; } - if ((!linePtr->numPoints) || (state==TK_STATE_HIDDEN)) { + if ((!linePtr->numPoints) || (state == TK_STATE_HIDDEN)) { ComputeLineBbox(canvas, linePtr); return TCL_OK; } @@ -566,7 +556,7 @@ ConfigureLine( && (linePtr->arrow != ARROWS_BOTH)) { linePtr->coordPtr[0] = linePtr->firstArrowPtr[0]; linePtr->coordPtr[1] = linePtr->firstArrowPtr[1]; - ckfree((char *) linePtr->firstArrowPtr); + ckfree(linePtr->firstArrowPtr); linePtr->firstArrowPtr = NULL; } if ((linePtr->lastArrowPtr != NULL) && (linePtr->arrow != ARROWS_LAST) @@ -576,7 +566,7 @@ ConfigureLine( i = 2*(linePtr->numPoints-1); linePtr->coordPtr[i] = linePtr->lastArrowPtr[0]; linePtr->coordPtr[i+1] = linePtr->lastArrowPtr[1]; - ckfree((char *) linePtr->lastArrowPtr); + ckfree(linePtr->lastArrowPtr); linePtr->lastArrowPtr = NULL; } if (linePtr->arrow != ARROWS_NONE) { @@ -617,18 +607,18 @@ DeleteLine( { LineItem *linePtr = (LineItem *) itemPtr; - Tk_DeleteOutline(display, &(linePtr->outline)); + Tk_DeleteOutline(display, &linePtr->outline); if (linePtr->coordPtr != NULL) { - ckfree((char *) linePtr->coordPtr); + ckfree(linePtr->coordPtr); } if (linePtr->arrowGC != NULL) { Tk_FreeGC(display, linePtr->arrowGC); } if (linePtr->firstArrowPtr != NULL) { - ckfree((char *) linePtr->firstArrowPtr); + ckfree(linePtr->firstArrowPtr); } if (linePtr->lastArrowPtr != NULL) { - ckfree((char *) linePtr->lastArrowPtr); + ckfree(linePtr->lastArrowPtr); } } @@ -660,11 +650,11 @@ ComputeLineBbox( Tk_State state = linePtr->header.state; Tk_TSOffset *tsoffset; - if(state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + if (state == TK_STATE_NULL) { + state = Canvas(canvas)->canvas_state; } - if (!(linePtr->numPoints) || (state==TK_STATE_HIDDEN)) { + if (!(linePtr->numPoints) || (state == TK_STATE_HIDDEN)) { linePtr->header.x1 = -1; linePtr->header.x2 = -1; linePtr->header.y1 = -1; @@ -673,18 +663,18 @@ ComputeLineBbox( } width = linePtr->outline.width; - if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *)linePtr) { - if (linePtr->outline.activeWidth>width) { + if (Canvas(canvas)->currentItemPtr == (Tk_Item *)linePtr) { + if (linePtr->outline.activeWidth > width) { width = linePtr->outline.activeWidth; } - } else if (state==TK_STATE_DISABLED) { - if (linePtr->outline.disabledWidth>0) { + } else if (state == TK_STATE_DISABLED) { + if (linePtr->outline.disabledWidth > 0) { width = linePtr->outline.disabledWidth; } } coordPtr = linePtr->coordPtr; - linePtr->header.x1 = linePtr->header.x2 = (int) *coordPtr; + linePtr->header.x1 = linePtr->header.x2 = (int) coordPtr[0]; linePtr->header.y1 = linePtr->header.y2 = (int) coordPtr[1]; /* @@ -692,8 +682,8 @@ ComputeLineBbox( * all directions by the line's width to take care of butting or rounded * corners and projecting or rounded caps. This expansion is an * overestimate (worst-case is square root of two over two) but it's - * simple. eDon't do anything special for curves. This causes an - * additional overestimate in the bounding box, but is faster. + * simple. Don't do anything special for curves. This causes an additional + * overestimate in the bounding box, but is faster. */ for (i = 1, coordPtr = linePtr->coordPtr+2; i < linePtr->numPoints; @@ -715,16 +705,20 @@ ComputeLineBbox( tsoffset = &linePtr->outline.tsoffset; if (tsoffset->flags & TK_OFFSET_INDEX) { - double *coordPtr = linePtr->coordPtr + (tsoffset->flags & ~TK_OFFSET_INDEX); + double *coordPtr = linePtr->coordPtr + + (tsoffset->flags & ~TK_OFFSET_INDEX); + if (tsoffset->flags <= 0) { coordPtr = linePtr->coordPtr; - if ((linePtr->arrow == ARROWS_FIRST) || (linePtr->arrow == ARROWS_BOTH)) { + if ((linePtr->arrow == ARROWS_FIRST) + || (linePtr->arrow == ARROWS_BOTH)) { coordPtr = linePtr->firstArrowPtr; } } if (tsoffset->flags > (linePtr->numPoints * 2)) { coordPtr = linePtr->coordPtr + (linePtr->numPoints * 2); - if ((linePtr->arrow == ARROWS_LAST) || (linePtr->arrow == ARROWS_BOTH)) { + if ((linePtr->arrow == ARROWS_LAST) + || (linePtr->arrow == ARROWS_BOTH)) { coordPtr = linePtr->lastArrowPtr; } } @@ -753,7 +747,7 @@ ComputeLineBbox( linePtr->header.y1 -= intWidth; linePtr->header.y2 += intWidth; - if (linePtr->numPoints==1) { + if (linePtr->numPoints == 1) { linePtr->header.x1 -= 1; linePtr->header.x2 += 1; linePtr->header.y1 -= 1; @@ -851,14 +845,14 @@ DisplayLine( } if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } linewidth = linePtr->outline.width; - if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { + if (Canvas(canvas)->currentItemPtr == itemPtr) { if (linePtr->outline.activeWidth != linewidth) { linewidth = linePtr->outline.activeWidth; } - } else if (state==TK_STATE_DISABLED) { + } else if (state == TK_STATE_DISABLED) { if (linePtr->outline.disabledWidth != linewidth) { linewidth = linePtr->outline.disabledWidth; } @@ -880,14 +874,14 @@ DisplayLine( if (numPoints <= MAX_STATIC_POINTS) { pointPtr = staticPoints; } else { - pointPtr = (XPoint *)ckalloc((unsigned)(numPoints * 3*sizeof(XPoint))); + pointPtr = ckalloc(numPoints * 3 * sizeof(XPoint)); } if ((linePtr->smooth) && (linePtr->numPoints > 2)) { numPoints = linePtr->smooth->coordProc(canvas, linePtr->coordPtr, linePtr->numPoints, linePtr->splineSteps, pointPtr, NULL); } else { - numPoints = TkCanvTranslatePath((TkCanvas*)canvas, numPoints, + numPoints = TkCanvTranslatePath((TkCanvas *) canvas, numPoints, linePtr->coordPtr, 0, pointPtr); } @@ -898,23 +892,25 @@ DisplayLine( * read-only. */ - if (Tk_ChangeOutlineGC(canvas, itemPtr, &(linePtr->outline))) { - Tk_CanvasSetOffset(canvas, linePtr->arrowGC, &linePtr->outline.tsoffset); + if (Tk_ChangeOutlineGC(canvas, itemPtr, &linePtr->outline)) { + Tk_CanvasSetOffset(canvas, linePtr->arrowGC, + &linePtr->outline.tsoffset); } - if (numPoints>1) { + if (numPoints > 1) { XDrawLines(display, drawable, linePtr->outline.gc, pointPtr, numPoints, - CoordModeOrigin); + CoordModeOrigin); } else { int intwidth = (int) (linewidth + 0.5); - if (intwidth<1) { - intwidth=1; + + if (intwidth < 1) { + intwidth = 1; } XFillArc(display, drawable, linePtr->outline.gc, pointPtr->x - intwidth/2, pointPtr->y - intwidth/2, - (unsigned int)intwidth+1, (unsigned int)intwidth+1, 0, 64*360); + (unsigned) intwidth+1, (unsigned) intwidth+1, 0, 64*360); } if (pointPtr != staticPoints) { - ckfree((char *) pointPtr); + ckfree(pointPtr); } /* @@ -929,7 +925,7 @@ DisplayLine( TkFillPolygon(canvas, linePtr->lastArrowPtr, PTS_IN_ARROW, display, drawable, linePtr->arrowGC, NULL); } - if (Tk_ResetOutlineGC(canvas, itemPtr, &(linePtr->outline))) { + if (Tk_ResetOutlineGC(canvas, itemPtr, &linePtr->outline)) { XSetTSOrigin(display, linePtr->arrowGC, 0, 0); } } @@ -965,7 +961,7 @@ LineInsert( Tcl_Obj **objv; if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } if (!obj || (Tcl_ListObjGetElements(NULL, obj, &objc, &objv) != TCL_OK) @@ -987,16 +983,15 @@ LineInsert( linePtr->coordPtr[length-2] = linePtr->lastArrowPtr[0]; linePtr->coordPtr[length-1] = linePtr->lastArrowPtr[1]; } - newCoordPtr = (double *) - ckalloc(sizeof(double) * (unsigned)(length + objc)); + newCoordPtr = ckalloc(sizeof(double) * (length + objc)); for (i=0; i<beforeThis; i++) { newCoordPtr[i] = linePtr->coordPtr[i]; } for (i=0; i<objc; i++) { if (Tcl_GetDoubleFromObj(NULL, objv[i], &newCoordPtr[i + beforeThis]) != TCL_OK) { - Tcl_ResetResult(((TkCanvas *)canvas)->interp); - ckfree((char *) newCoordPtr); + Tcl_ResetResult(Canvas(canvas)->interp); + ckfree(newCoordPtr); return; } } @@ -1005,13 +1000,13 @@ LineInsert( newCoordPtr[i+objc] = linePtr->coordPtr[i]; } if (linePtr->coordPtr) { - ckfree((char *) linePtr->coordPtr); + ckfree(linePtr->coordPtr); } linePtr->coordPtr = newCoordPtr; - length += objc; + length += objc ; linePtr->numPoints = length / 2; - if ((length>3) && (state != TK_STATE_HIDDEN)) { + if ((length > 3) && (state != TK_STATE_HIDDEN)) { /* * This is some optimizing code that will result that only the part of * the polygon that changed (and the objects that are overlapping with @@ -1023,19 +1018,25 @@ LineInsert( itemPtr->redraw_flags |= TK_ITEM_DONT_REDRAW; - if (beforeThis>0) {beforeThis -= 2; objc+=2; } - if ((beforeThis+objc)<length) objc+=2; + if (beforeThis > 0) { + beforeThis -= 2; + objc += 2; + } + if (beforeThis+objc < length) { + objc += 2; + } if (linePtr->smooth) { - if(beforeThis>0) { - beforeThis-=2; objc+=2; + if (beforeThis > 0) { + beforeThis -= 2; + objc += 2; } - if((beforeThis+objc+2)<length) { - objc+=2; + if (beforeThis+objc+2 < length) { + objc += 2; } } itemPtr->x1 = itemPtr->x2 = (int) linePtr->coordPtr[beforeThis]; itemPtr->y1 = itemPtr->y2 = (int) linePtr->coordPtr[beforeThis+1]; - if ((linePtr->firstArrowPtr != NULL) && (beforeThis<1)) { + if ((linePtr->firstArrowPtr != NULL) && (beforeThis < 1)) { /* * Include old first arrow. */ @@ -1045,7 +1046,7 @@ LineInsert( TkIncludePoint(itemPtr, coordPtr); } } - if ((linePtr->lastArrowPtr != NULL) && ((beforeThis+objc)>=length)) { + if ((linePtr->lastArrowPtr != NULL) && (beforeThis+objc >= length)) { /* * Include old last arrow. */ @@ -1055,18 +1056,18 @@ LineInsert( TkIncludePoint(itemPtr, coordPtr); } } - coordPtr = linePtr->coordPtr+beforeThis+2; + coordPtr = linePtr->coordPtr + beforeThis + 2; for (i=2; i<objc; i+=2) { TkIncludePoint(itemPtr, coordPtr); - coordPtr+=2; + coordPtr += 2; } } if (linePtr->firstArrowPtr != NULL) { - ckfree((char *) linePtr->firstArrowPtr); + ckfree(linePtr->firstArrowPtr); linePtr->firstArrowPtr = NULL; } if (linePtr->lastArrowPtr != NULL) { - ckfree((char *) linePtr->lastArrowPtr); + ckfree(linePtr->lastArrowPtr); linePtr->lastArrowPtr = NULL; } if (linePtr->arrow != ARROWS_NONE) { @@ -1077,7 +1078,7 @@ LineInsert( double width; int intWidth; - if ((linePtr->firstArrowPtr != NULL) && (beforeThis>2)) { + if ((linePtr->firstArrowPtr != NULL) && (beforeThis > 2)) { /* * Include new first arrow. */ @@ -1098,12 +1099,12 @@ LineInsert( } } width = linePtr->outline.width; - if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { - if (linePtr->outline.activeWidth>width) { + if (Canvas(canvas)->currentItemPtr == itemPtr) { + if (linePtr->outline.activeWidth > width) { width = linePtr->outline.activeWidth; } - } else if (state==TK_STATE_DISABLED) { - if (linePtr->outline.disabledWidth>0) { + } else if (state == TK_STATE_DISABLED) { + if (linePtr->outline.disabledWidth > 0) { width = linePtr->outline.disabledWidth; } } @@ -1111,8 +1112,10 @@ LineInsert( if (intWidth < 1) { intWidth = 1; } - itemPtr->x1 -= intWidth; itemPtr->y1 -= intWidth; - itemPtr->x2 += intWidth; itemPtr->y2 += intWidth; + itemPtr->x1 -= intWidth; + itemPtr->y1 -= intWidth; + itemPtr->x2 += intWidth; + itemPtr->y2 += intWidth; Tk_CanvasEventuallyRedraw(canvas, itemPtr->x1, itemPtr->y1, itemPtr->x2, itemPtr->y2); } @@ -1151,7 +1154,7 @@ LineDeleteCoords( Tk_State state = itemPtr->state; if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } first &= -2; @@ -1191,7 +1194,7 @@ LineDeleteCoords( } } - if (!(first1 < 2) && (last1 >= length-2)) { + if ((first1 >= 2) || (last1 < length-2)) { /* * This is some optimizing code that will result that only the part of * the line that changed (and the objects that are overlapping with @@ -1237,11 +1240,11 @@ LineDeleteCoords( } linePtr->numPoints -= count/2; if (linePtr->firstArrowPtr != NULL) { - ckfree((char *) linePtr->firstArrowPtr); + ckfree(linePtr->firstArrowPtr); linePtr->firstArrowPtr = NULL; } if (linePtr->lastArrowPtr != NULL) { - ckfree((char *) linePtr->lastArrowPtr); + ckfree(linePtr->lastArrowPtr); linePtr->lastArrowPtr = NULL; } if (linePtr->arrow != ARROWS_NONE) { @@ -1272,11 +1275,11 @@ LineDeleteCoords( } } width = linePtr->outline.width; - if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { + if (Canvas(canvas)->currentItemPtr == itemPtr) { if (linePtr->outline.activeWidth > width) { width = linePtr->outline.activeWidth; } - } else if (state==TK_STATE_DISABLED) { + } else if (state == TK_STATE_DISABLED) { if (linePtr->outline.disabledWidth > 0) { width = linePtr->outline.disabledWidth; } @@ -1340,17 +1343,17 @@ LineToPoint( * which to do the check. */ - if(state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + if (state == TK_STATE_NULL) { + state = Canvas(canvas)->canvas_state; } width = linePtr->outline.width; - if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { - if (linePtr->outline.activeWidth>width) { + if (Canvas(canvas)->currentItemPtr == itemPtr) { + if (linePtr->outline.activeWidth > width) { width = linePtr->outline.activeWidth; } - } else if (state==TK_STATE_DISABLED) { - if (linePtr->outline.disabledWidth>0) { + } else if (state == TK_STATE_DISABLED) { + if (linePtr->outline.disabledWidth > 0) { width = linePtr->outline.disabledWidth; } } @@ -1361,8 +1364,7 @@ LineToPoint( if (numPoints <= MAX_STATIC_POINTS) { linePoints = staticSpace; } else { - linePoints = (double *) ckalloc((unsigned) - (2*numPoints*sizeof(double))); + linePoints = ckalloc(2 * numPoints * sizeof(double)); } numPoints = linePtr->smooth->coordProc(canvas, linePtr->coordPtr, linePtr->numPoints, linePtr->splineSteps, NULL, linePoints); @@ -1375,12 +1377,14 @@ LineToPoint( width = 1.0; } - if (!numPoints || itemPtr->state==TK_STATE_HIDDEN) { + if (!numPoints || itemPtr->state == TK_STATE_HIDDEN) { return bestDist; } else if (numPoints == 1) { bestDist = hypot(linePoints[0]-pointPtr[0], linePoints[1]-pointPtr[1]) - width/2.0; - if (bestDist < 0) bestDist = 0; + if (bestDist < 0) { + bestDist = 0; + } return bestDist; } @@ -1519,7 +1523,7 @@ LineToPoint( done: if ((linePoints != staticSpace) && (linePoints != linePtr->coordPtr)) { - ckfree((char *) linePoints); + ckfree(linePoints); } return bestDist; } @@ -1556,23 +1560,23 @@ LineToArea( double radius, width; Tk_State state = itemPtr->state; - if(state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + if (state == TK_STATE_NULL) { + state = Canvas(canvas)->canvas_state; } width = linePtr->outline.width; - if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { - if (linePtr->outline.activeWidth>width) { + if (Canvas(canvas)->currentItemPtr == itemPtr) { + if (linePtr->outline.activeWidth > width) { width = linePtr->outline.activeWidth; } - } else if (state==TK_STATE_DISABLED) { - if (linePtr->outline.disabledWidth>0) { + } else if (state == TK_STATE_DISABLED) { + if (linePtr->outline.disabledWidth > 0) { width = linePtr->outline.disabledWidth; } } radius = (width+1.0)/2.0; - if ((state==TK_STATE_HIDDEN) || !linePtr->numPoints) { + if ((state == TK_STATE_HIDDEN) || !linePtr->numPoints) { return -1; } else if (linePtr->numPoints == 1) { double oval[4]; @@ -1595,8 +1599,7 @@ LineToArea( if (numPoints <= MAX_STATIC_POINTS) { linePoints = staticSpace; } else { - linePoints = (double *) ckalloc((unsigned) - (2*numPoints*sizeof(double))); + linePoints = ckalloc(2 * numPoints * sizeof(double)); } numPoints = linePtr->smooth->coordProc(canvas, linePtr->coordPtr, linePtr->numPoints, linePtr->splineSteps, NULL, linePoints); @@ -1609,13 +1612,12 @@ LineToArea( * Check the segments of the line. */ - if (width < 1.0) { + if (width < 1.0) { width = 1.0; } - result = TkThickPolyLineToArea(linePoints, numPoints, - width, linePtr->capStyle, linePtr->joinStyle, - rectPtr); + result = TkThickPolyLineToArea(linePoints, numPoints, width, + linePtr->capStyle, linePtr->joinStyle, rectPtr); if (result == 0) { goto done; } @@ -1643,7 +1645,7 @@ LineToArea( done: if ((linePoints != staticSpace) && (linePoints != linePtr->coordPtr)) { - ckfree((char *) linePoints); + ckfree(linePoints); } return result; } @@ -1688,7 +1690,7 @@ ScaleLine( if (linePtr->firstArrowPtr != NULL) { linePtr->coordPtr[0] = linePtr->firstArrowPtr[0]; linePtr->coordPtr[1] = linePtr->firstArrowPtr[1]; - ckfree((char *) linePtr->firstArrowPtr); + ckfree(linePtr->firstArrowPtr); linePtr->firstArrowPtr = NULL; } if (linePtr->lastArrowPtr != NULL) { @@ -1697,7 +1699,7 @@ ScaleLine( i = 2*(linePtr->numPoints-1); linePtr->coordPtr[i] = linePtr->lastArrowPtr[0]; linePtr->coordPtr[i+1] = linePtr->lastArrowPtr[1]; - ckfree((char *) linePtr->lastArrowPtr); + ckfree(linePtr->lastArrowPtr); linePtr->lastArrowPtr = NULL; } for (i = 0, coordPtr = linePtr->coordPtr; i < linePtr->numPoints; @@ -1741,27 +1743,19 @@ GetLineIndex( int *indexPtr) /* Where to store converted index. */ { LineItem *linePtr = (LineItem *) itemPtr; - int length; - char *string = Tcl_GetStringFromObj(obj, &length); + const char *string = Tcl_GetString(obj); if (string[0] == 'e') { - if (strncmp(string, "end", (unsigned) length) == 0) { + if (strncmp(string, "end", obj->length) == 0) { *indexPtr = 2*linePtr->numPoints; } else { - /* - * Some of the paths here leave messages in interp->result, so we - * have to clear it out before storing our own message. - */ - - badIndex: - Tcl_SetResult(interp, NULL, TCL_STATIC); - Tcl_AppendResult(interp, "bad index \"", string, "\"", NULL); - return TCL_ERROR; + goto badIndex; } } else if (string[0] == '@') { int i; - double x ,y, bestDist, dist, *coordPtr; - char *end, *p; + double x, y, bestDist, dist, *coordPtr; + char *end; + const char *p; p = string+1; x = strtod(p, &end); @@ -1776,9 +1770,9 @@ GetLineIndex( bestDist = 1.0e36; coordPtr = linePtr->coordPtr; *indexPtr = 0; - for(i=0; i<linePtr->numPoints; i++) { + for (i=0; i<linePtr->numPoints; i++) { dist = hypot(coordPtr[0] - x, coordPtr[1] - y); - if (dist<bestDist) { + if (dist < bestDist) { bestDist = dist; *indexPtr = 2*i; } @@ -1788,7 +1782,7 @@ GetLineIndex( if (Tcl_GetIntFromObj(interp, obj, indexPtr) != TCL_OK) { goto badIndex; } - *indexPtr &= -2; /* if index is odd, make it even */ + *indexPtr &= -2; /* If index is odd, make it even. */ if (*indexPtr < 0){ *indexPtr = 0; } else if (*indexPtr > (2*linePtr->numPoints)) { @@ -1796,6 +1790,17 @@ GetLineIndex( } } return TCL_OK; + + /* + * Some of the paths here leave messages in interp->result, so we have to + * clear it out before storing our own message. + */ + + badIndex: + Tcl_ResetResult(interp); + Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad index \"%s\"", string)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "ITEM_INDEX", "LINE", NULL); + return TCL_ERROR; } /* @@ -1873,7 +1878,7 @@ ParseArrowShape( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Used for error reporting. */ Tk_Window tkwin, /* Not used. */ - CONST char *value, /* Textual specification of arrow shape. */ + const char *value, /* Textual specification of arrow shape. */ char *recordPtr, /* Pointer to item record in which to store * arrow information. */ int offset) /* Offset of shape information in widget @@ -1882,23 +1887,15 @@ ParseArrowShape( LineItem *linePtr = (LineItem *) recordPtr; double a, b, c; int argc; - CONST char **argv = NULL; + const char **argv = NULL; if (offset != Tk_Offset(LineItem, arrowShapeA)) { Tcl_Panic("ParseArrowShape received bogus offset"); } if (Tcl_SplitList(interp, (char *) value, &argc, &argv) != TCL_OK) { - syntaxError: - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "bad arrow shape \"", value, - "\": must be list with three numbers", NULL); - if (argv != NULL) { - ckfree((char *) argv); - } - return TCL_ERROR; - } - if (argc != 3) { + goto syntaxError; + } else if (argc != 3) { goto syntaxError; } if ((Tk_CanvasGetCoord(interp, linePtr->canvas, argv[0], &a) != TCL_OK) @@ -1908,11 +1905,23 @@ ParseArrowShape( != TCL_OK)) { goto syntaxError; } - linePtr->arrowShapeA = (float)a; - linePtr->arrowShapeB = (float)b; - linePtr->arrowShapeC = (float)c; - ckfree((char *) argv); + + linePtr->arrowShapeA = (float) a; + linePtr->arrowShapeB = (float) b; + linePtr->arrowShapeC = (float) c; + ckfree(argv); return TCL_OK; + + syntaxError: + Tcl_ResetResult(interp); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad arrow shape \"%s\": must be list with three numbers", + value)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "ARROW_SHAPE", NULL); + if (argv != NULL) { + ckfree(argv); + } + return TCL_ERROR; } /* @@ -1933,7 +1942,7 @@ ParseArrowShape( */ /* ARGSUSED */ -static char * +static const char * PrintArrowShape( ClientData clientData, /* Not used. */ Tk_Window tkwin, /* Window associated with linePtr's widget. */ @@ -1944,16 +1953,14 @@ PrintArrowShape( * string here. */ { LineItem *linePtr = (LineItem *) recordPtr; - char *buffer; + char *buffer = ckalloc(120); - buffer = (char *) ckalloc(120); sprintf(buffer, "%.5g %.5g %.5g", linePtr->arrowShapeA, linePtr->arrowShapeB, linePtr->arrowShapeC); *freeProcPtr = TCL_DYNAMIC; return buffer; } - /* *-------------------------------------------------------------- * @@ -1977,7 +1984,7 @@ ArrowParseProc( ClientData clientData, /* some flags.*/ Tcl_Interp *interp, /* Used for reporting errors. */ Tk_Window tkwin, /* Window containing canvas widget. */ - CONST char *value, /* Value of option. */ + const char *value, /* Value of option. */ char *widgRec, /* Pointer to record for item. */ int offset) /* Offset into item. */ { @@ -1986,7 +1993,7 @@ ArrowParseProc( register Arrows *arrowPtr = (Arrows *) (widgRec + offset); - if(value == NULL || *value == 0) { + if (value == NULL || *value == 0) { *arrowPtr = ARROWS_NONE; return TCL_OK; } @@ -2011,8 +2018,10 @@ ArrowParseProc( return TCL_OK; } - Tcl_AppendResult(interp, "bad arrow spec \"", value, - "\": must be none, first, last, or both", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad arrow spec \"%s\": must be none, first, last, or both", + value)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "ARROW", NULL); *arrowPtr = ARROWS_NONE; return TCL_ERROR; } @@ -2038,7 +2047,7 @@ ArrowParseProc( *-------------------------------------------------------------- */ -static char * +static const char * ArrowPrintProc( ClientData clientData, /* Ignored. */ Tk_Window tkwin, /* Window containing canvas widget. */ @@ -2102,21 +2111,21 @@ ConfigureArrows( double width; Tk_State state = linePtr->header.state; - if (linePtr->numPoints <2) { + if (linePtr->numPoints < 2) { return TCL_OK; } - if(state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + if (state == TK_STATE_NULL) { + state = Canvas(canvas)->canvas_state; } width = linePtr->outline.width; - if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *)linePtr) { - if (linePtr->outline.activeWidth>width) { + if (Canvas(canvas)->currentItemPtr == (Tk_Item *)linePtr) { + if (linePtr->outline.activeWidth > width) { width = linePtr->outline.activeWidth; } - } else if (state==TK_STATE_DISABLED) { - if (linePtr->outline.disabledWidth>0) { + } else if (state == TK_STATE_DISABLED) { + if (linePtr->outline.disabledWidth > 0) { width = linePtr->outline.disabledWidth; } } @@ -2143,8 +2152,7 @@ ConfigureArrows( if (linePtr->arrow != ARROWS_LAST) { poly = linePtr->firstArrowPtr; if (poly == NULL) { - poly = (double *) ckalloc((unsigned) - (2*PTS_IN_ARROW*sizeof(double))); + poly = ckalloc(2 * PTS_IN_ARROW * sizeof(double)); poly[0] = poly[10] = linePtr->coordPtr[0]; poly[1] = poly[11] = linePtr->coordPtr[1]; linePtr->firstArrowPtr = poly; @@ -2188,8 +2196,7 @@ ConfigureArrows( coordPtr = linePtr->coordPtr + 2*(linePtr->numPoints-2); poly = linePtr->lastArrowPtr; if (poly == NULL) { - poly = (double *) - ckalloc((unsigned) (2*PTS_IN_ARROW*sizeof(double))); + poly = ckalloc(2 * PTS_IN_ARROW * sizeof(double)); poly[0] = poly[10] = coordPtr[2]; poly[1] = poly[11] = coordPtr[3]; linePtr->lastArrowPtr = poly; @@ -2251,129 +2258,150 @@ LineToPostscript( * being created. */ { LineItem *linePtr = (LineItem *) itemPtr; - char buffer[64 + 4*TCL_INTEGER_SPACE]; - char *style; - + int style; double width; XColor *color; Pixmap stipple; Tk_State state = itemPtr->state; + Tcl_Obj *psObj; + Tcl_InterpState interpState; - if(state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + if (state == TK_STATE_NULL) { + state = Canvas(canvas)->canvas_state; } width = linePtr->outline.width; color = linePtr->outline.color; stipple = linePtr->outline.stipple; - if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { - if (linePtr->outline.activeWidth>width) { + if (Canvas(canvas)->currentItemPtr == itemPtr) { + if (linePtr->outline.activeWidth > width) { width = linePtr->outline.activeWidth; } - if (linePtr->outline.activeColor!=NULL) { + if (linePtr->outline.activeColor != NULL) { color = linePtr->outline.activeColor; } - if (linePtr->outline.activeStipple!=None) { + if (linePtr->outline.activeStipple != None) { stipple = linePtr->outline.activeStipple; } - } else if (state==TK_STATE_DISABLED) { - if (linePtr->outline.disabledWidth>0) { + } else if (state == TK_STATE_DISABLED) { + if (linePtr->outline.disabledWidth > 0) { width = linePtr->outline.disabledWidth; } - if (linePtr->outline.disabledColor!=NULL) { + if (linePtr->outline.disabledColor != NULL) { color = linePtr->outline.disabledColor; } - if (linePtr->outline.disabledStipple!=None) { + if (linePtr->outline.disabledStipple != None) { stipple = linePtr->outline.disabledStipple; } } - if (color == NULL || linePtr->numPoints<1 || linePtr->coordPtr==NULL) { + if (color == NULL || linePtr->numPoints < 1 || linePtr->coordPtr == NULL){ return TCL_OK; } - if (linePtr->numPoints==1) { - sprintf(buffer, "%.15g %.15g translate %.15g %.15g", + /* + * Make our working space. + */ + + psObj = Tcl_NewObj(); + interpState = Tcl_SaveInterpState(interp, TCL_OK); + + /* + * Check if we're just doing a "pixel". + */ + + if (linePtr->numPoints == 1) { + Tcl_AppendToObj(psObj, "matrix currentmatrix\n", -1); + Tcl_AppendPrintfToObj(psObj, "%.15g %.15g translate %.15g %.15g", linePtr->coordPtr[0], Tk_CanvasPsY(canvas, linePtr->coordPtr[1]), width/2.0, width/2.0); - Tcl_AppendResult(interp, "matrix currentmatrix\n",buffer, - " scale 1 0 moveto 0 0 1 0 360 arc\nsetmatrix\n", NULL); + Tcl_AppendToObj(psObj, + " scale 1 0 moveto 0 0 1 0 360 arc\nsetmatrix\n", -1); + + Tcl_ResetResult(interp); if (Tk_CanvasPsColor(interp, canvas, color) != TCL_OK) { - return TCL_ERROR; + goto error; } + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); + if (stipple != None) { - Tcl_AppendResult(interp, "clip ", NULL); + Tcl_AppendToObj(psObj, "clip ", -1); + Tcl_ResetResult(interp); if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK) { - return TCL_ERROR; + goto error; } + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); } else { - Tcl_AppendResult(interp, "fill\n", NULL); + Tcl_AppendToObj(psObj, "fill\n", -1); } - return TCL_OK; + goto done; } + /* * Generate a path for the line's center-line (do this differently for * straight lines and smoothed lines). */ + Tcl_ResetResult(interp); if ((!linePtr->smooth) || (linePtr->numPoints < 3)) { Tk_CanvasPsPath(interp, canvas, linePtr->coordPtr, linePtr->numPoints); + } else if ((stipple == None) && linePtr->smooth->postscriptProc) { + linePtr->smooth->postscriptProc(interp, canvas, linePtr->coordPtr, + linePtr->numPoints, linePtr->splineSteps); } else { - if ((stipple == None) && linePtr->smooth->postscriptProc) { - linePtr->smooth->postscriptProc(interp, canvas, - linePtr->coordPtr, linePtr->numPoints, linePtr->splineSteps); - } else { - /* - * Special hack: Postscript printers don't appear to be able to - * turn a path drawn with "curveto"s into a clipping path without - * exceeding resource limits, so TkMakeBezierPostscript won't work - * for stippled curves. Instead, generate all of the intermediate - * points here and output them into the Postscript file with - * "lineto"s instead. - */ + /* + * Special hack: Postscript printers don't appear to be able to turn a + * path drawn with "curveto"s into a clipping path without exceeding + * resource limits, so TkMakeBezierPostscript won't work for stippled + * curves. Instead, generate all of the intermediate points here and + * output them into the Postscript file with "lineto"s instead. + */ - double staticPoints[2*MAX_STATIC_POINTS]; - double *pointPtr; - int numPoints; + double staticPoints[2*MAX_STATIC_POINTS]; + double *pointPtr; + int numPoints; - numPoints = linePtr->smooth->coordProc(canvas, NULL, - linePtr->numPoints, linePtr->splineSteps, NULL, NULL); - pointPtr = staticPoints; - if (numPoints > MAX_STATIC_POINTS) { - pointPtr = (double *) ckalloc((unsigned) - (numPoints * 2 * sizeof(double))); - } - numPoints = linePtr->smooth->coordProc(canvas, linePtr->coordPtr, - linePtr->numPoints, linePtr->splineSteps, NULL, pointPtr); - Tk_CanvasPsPath(interp, canvas, pointPtr, numPoints); - if (pointPtr != staticPoints) { - ckfree((char *) pointPtr); - } + numPoints = linePtr->smooth->coordProc(canvas, NULL, + linePtr->numPoints, linePtr->splineSteps, NULL, NULL); + pointPtr = staticPoints; + if (numPoints > MAX_STATIC_POINTS) { + pointPtr = ckalloc(numPoints * 2 * sizeof(double)); + } + numPoints = linePtr->smooth->coordProc(canvas, linePtr->coordPtr, + linePtr->numPoints, linePtr->splineSteps, NULL, pointPtr); + Tk_CanvasPsPath(interp, canvas, pointPtr, numPoints); + if (pointPtr != staticPoints) { + ckfree(pointPtr); } } + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); /* * Set other line-drawing parameters and stroke out the line. */ - style = "0 setlinecap\n"; if (linePtr->capStyle == CapRound) { - style = "1 setlinecap\n"; + style = 1; } else if (linePtr->capStyle == CapProjecting) { - style = "2 setlinecap\n"; + style = 2; + } else { + style = 0; } - Tcl_AppendResult(interp, style, NULL); - style = "0 setlinejoin\n"; + Tcl_AppendPrintfToObj(psObj, "%d setlinecap\n", style); if (linePtr->joinStyle == JoinRound) { - style = "1 setlinejoin\n"; + style = 1; } else if (linePtr->joinStyle == JoinBevel) { - style = "2 setlinejoin\n"; + style = 2; + } else { + style = 0; } - Tcl_AppendResult(interp, style, NULL); + Tcl_AppendPrintfToObj(psObj, "%d setlinejoin\n", style); - if (Tk_CanvasPsOutline(canvas, itemPtr, &(linePtr->outline)) != TCL_OK) { - return TCL_ERROR; + Tcl_ResetResult(interp); + if (Tk_CanvasPsOutline(canvas, itemPtr, &linePtr->outline) != TCL_OK) { + goto error; } + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); /* * Output polygons for the arrowheads, if there are any. @@ -2381,23 +2409,37 @@ LineToPostscript( if (linePtr->firstArrowPtr != NULL) { if (stipple != None) { - Tcl_AppendResult(interp, "grestore gsave\n", NULL); + Tcl_AppendToObj(psObj, "grestore gsave\n", -1); } if (ArrowheadPostscript(interp, canvas, linePtr, - linePtr->firstArrowPtr) != TCL_OK) { - return TCL_ERROR; + linePtr->firstArrowPtr, psObj) != TCL_OK) { + goto error; } } if (linePtr->lastArrowPtr != NULL) { if (stipple != None) { - Tcl_AppendResult(interp, "grestore gsave\n", NULL); + Tcl_AppendToObj(psObj, "grestore gsave\n", -1); } if (ArrowheadPostscript(interp, canvas, linePtr, - linePtr->lastArrowPtr) != TCL_OK) { - return TCL_ERROR; + linePtr->lastArrowPtr, psObj) != TCL_OK) { + goto error; } } + + /* + * Plug the accumulated postscript back into the result. + */ + + done: + (void) Tcl_RestoreInterpState(interp, interpState); + Tcl_AppendObjToObj(Tcl_GetObjResult(interp), psObj); + Tcl_DecrRefCount(psObj); return TCL_OK; + + error: + Tcl_DiscardInterpState(interpState); + Tcl_DecrRefCount(psObj); + return TCL_ERROR; } /* @@ -2412,7 +2454,7 @@ LineToPostscript( * The return value is a standard Tcl result. If an error occurs in * generating Postscript then an error message is left in the interp's * result, replacing whatever used to be there. If no error occurs, then - * Postscript for the arrowhead is appended to the result. + * Postscript for the arrowhead is appended to the given object. * * Side effects: * None. @@ -2422,39 +2464,47 @@ LineToPostscript( static int ArrowheadPostscript( - Tcl_Interp *interp, /* Leave Postscript or error message here. */ + Tcl_Interp *interp, /* Leave error message here; non-error results + * will be discarded by caller. */ Tk_Canvas canvas, /* Information about overall canvas. */ LineItem *linePtr, /* Line item for which Postscript is being * generated. */ - double *arrowPtr) /* Pointer to first of five points describing + double *arrowPtr, /* Pointer to first of five points describing * arrowhead polygon. */ + Tcl_Obj *psObj) /* Append postscript to this object. */ { Pixmap stipple; Tk_State state = linePtr->header.state; - if(state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + if (state == TK_STATE_NULL) { + state = Canvas(canvas)->canvas_state; } stipple = linePtr->outline.stipple; - if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *)linePtr) { + if (Canvas(canvas)->currentItemPtr == (Tk_Item *) linePtr) { if (linePtr->outline.activeStipple!=None) { stipple = linePtr->outline.activeStipple; } - } else if (state==TK_STATE_DISABLED) { + } else if (state == TK_STATE_DISABLED) { if (linePtr->outline.activeStipple!=None) { stipple = linePtr->outline.disabledStipple; } } + Tcl_ResetResult(interp); Tk_CanvasPsPath(interp, canvas, arrowPtr, PTS_IN_ARROW); + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); + if (stipple != None) { - Tcl_AppendResult(interp, "clip ", NULL); + Tcl_AppendToObj(psObj, "clip ", -1); + + Tcl_ResetResult(interp); if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK) { return TCL_ERROR; } + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); } else { - Tcl_AppendResult(interp, "fill\n", NULL); + Tcl_AppendToObj(psObj, "fill\n", -1); } return TCL_OK; } diff --git a/generic/tkCanvPoly.c b/generic/tkCanvPoly.c index 7171e9f..6a8f865 100644 --- a/generic/tkCanvPoly.c +++ b/generic/tkCanvPoly.c @@ -11,7 +11,6 @@ * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ -#include <stdio.h> #include "tkInt.h" #include "tkCanvas.h" @@ -44,7 +43,7 @@ typedef struct PolygonItem { Pixmap disabledFillStipple; /* Stipple bitmap for filling polygon if state * is disabled. */ GC fillGC; /* Graphics context for filling polygon. */ - Tk_SmoothMethod *smooth; /* Non-zero means draw shape smoothed (i.e. + const Tk_SmoothMethod *smooth; /* Non-zero means draw shape smoothed (i.e. * with Bezier splines). */ int splineSteps; /* Number of steps in each spline segment. */ int autoClosed; /* Zero means the given polygon was closed, @@ -55,45 +54,39 @@ typedef struct PolygonItem { * Information used for parsing configuration specs: */ -static Tk_CustomOption smoothOption = { - (Tk_OptionParseProc *) TkSmoothParseProc, - TkSmoothPrintProc, (ClientData) NULL +static const Tk_CustomOption smoothOption = { + TkSmoothParseProc, TkSmoothPrintProc, NULL }; -static Tk_CustomOption stateOption = { - (Tk_OptionParseProc *) TkStateParseProc, - TkStatePrintProc, (ClientData) 2 +static const Tk_CustomOption stateOption = { + TkStateParseProc, TkStatePrintProc, INT2PTR(2) }; -static Tk_CustomOption tagsOption = { - (Tk_OptionParseProc *) Tk_CanvasTagsParseProc, - Tk_CanvasTagsPrintProc, (ClientData) NULL +static const Tk_CustomOption tagsOption = { + Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL }; -static Tk_CustomOption dashOption = { - (Tk_OptionParseProc *) TkCanvasDashParseProc, - TkCanvasDashPrintProc, (ClientData) NULL +static const Tk_CustomOption dashOption = { + TkCanvasDashParseProc, TkCanvasDashPrintProc, NULL }; -static Tk_CustomOption offsetOption = { - (Tk_OptionParseProc *) TkOffsetParseProc, - TkOffsetPrintProc, - (ClientData) (TK_OFFSET_RELATIVE|TK_OFFSET_INDEX) +static const Tk_CustomOption offsetOption = { + TkOffsetParseProc, TkOffsetPrintProc, + INT2PTR(TK_OFFSET_RELATIVE|TK_OFFSET_INDEX) }; -static Tk_CustomOption pixelOption = { - (Tk_OptionParseProc *) TkPixelParseProc, - TkPixelPrintProc, (ClientData) NULL +static const Tk_CustomOption pixelOption = { + TkPixelParseProc, TkPixelPrintProc, NULL }; -static Tk_ConfigSpec configSpecs[] = { +static const Tk_ConfigSpec configSpecs[] = { {TK_CONFIG_CUSTOM, "-activedash", NULL, NULL, NULL, Tk_Offset(PolygonItem, outline.activeDash), TK_CONFIG_NULL_OK, &dashOption}, {TK_CONFIG_COLOR, "-activefill", NULL, NULL, - NULL, Tk_Offset(PolygonItem, activeFillColor), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(PolygonItem, activeFillColor), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_COLOR, "-activeoutline", NULL, NULL, - NULL, Tk_Offset(PolygonItem, outline.activeColor), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(PolygonItem, outline.activeColor), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_BITMAP, "-activeoutlinestipple", NULL, NULL, NULL, Tk_Offset(PolygonItem, outline.activeStipple), - TK_CONFIG_NULL_OK}, + TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_BITMAP, "-activestipple", NULL, NULL, - NULL, Tk_Offset(PolygonItem, activeFillStipple), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(PolygonItem, activeFillStipple), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_CUSTOM, "-activewidth", NULL, NULL, "0.0", Tk_Offset(PolygonItem, outline.activeWidth), TK_CONFIG_DONT_SET_DEFAULT, &pixelOption}, @@ -102,52 +95,52 @@ static Tk_ConfigSpec configSpecs[] = { TK_CONFIG_NULL_OK, &dashOption}, {TK_CONFIG_PIXELS, "-dashoffset", NULL, NULL, "0", Tk_Offset(PolygonItem, outline.offset), - TK_CONFIG_DONT_SET_DEFAULT}, + TK_CONFIG_DONT_SET_DEFAULT, NULL}, {TK_CONFIG_CUSTOM, "-disableddash", NULL, NULL, NULL, Tk_Offset(PolygonItem, outline.disabledDash), TK_CONFIG_NULL_OK, &dashOption}, {TK_CONFIG_COLOR, "-disabledfill", NULL, NULL, - NULL, Tk_Offset(PolygonItem, disabledFillColor), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(PolygonItem, disabledFillColor), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_COLOR, "-disabledoutline", NULL, NULL, NULL, Tk_Offset(PolygonItem, outline.disabledColor), - TK_CONFIG_NULL_OK}, + TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_BITMAP, "-disabledoutlinestipple", NULL, NULL, NULL, Tk_Offset(PolygonItem, outline.disabledStipple), - TK_CONFIG_NULL_OK}, + TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_BITMAP, "-disabledstipple", NULL, NULL, - NULL, Tk_Offset(PolygonItem, disabledFillStipple), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(PolygonItem, disabledFillStipple), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_CUSTOM, "-disabledwidth", NULL, NULL, "0.0", Tk_Offset(PolygonItem, outline.disabledWidth), TK_CONFIG_DONT_SET_DEFAULT, &pixelOption}, {TK_CONFIG_COLOR, "-fill", NULL, NULL, - "black", Tk_Offset(PolygonItem, fillColor), TK_CONFIG_NULL_OK}, + "black", Tk_Offset(PolygonItem, fillColor), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_JOIN_STYLE, "-joinstyle", NULL, NULL, - "round", Tk_Offset(PolygonItem, joinStyle), TK_CONFIG_DONT_SET_DEFAULT}, + "round", Tk_Offset(PolygonItem, joinStyle), TK_CONFIG_DONT_SET_DEFAULT, NULL}, {TK_CONFIG_CUSTOM, "-offset", NULL, NULL, "0,0", Tk_Offset(PolygonItem, tsoffset), TK_CONFIG_NULL_OK, &offsetOption}, {TK_CONFIG_COLOR, "-outline", NULL, NULL, - NULL, Tk_Offset(PolygonItem, outline.color), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(PolygonItem, outline.color), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_CUSTOM, "-outlineoffset", NULL, NULL, "0,0", Tk_Offset(PolygonItem, outline.tsoffset), TK_CONFIG_NULL_OK, &offsetOption}, {TK_CONFIG_BITMAP, "-outlinestipple", NULL, NULL, - NULL, Tk_Offset(PolygonItem, outline.stipple), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(PolygonItem, outline.stipple), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_CUSTOM, "-smooth", NULL, NULL, "0", Tk_Offset(PolygonItem, smooth), TK_CONFIG_DONT_SET_DEFAULT, &smoothOption}, {TK_CONFIG_INT, "-splinesteps", NULL, NULL, - "12", Tk_Offset(PolygonItem, splineSteps), TK_CONFIG_DONT_SET_DEFAULT}, + "12", Tk_Offset(PolygonItem, splineSteps), TK_CONFIG_DONT_SET_DEFAULT, NULL}, {TK_CONFIG_CUSTOM, "-state", NULL, NULL, NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption}, {TK_CONFIG_BITMAP, "-stipple", NULL, NULL, - NULL, Tk_Offset(PolygonItem, fillStipple), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(PolygonItem, fillStipple), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_CUSTOM, "-tags", NULL, NULL, NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, {TK_CONFIG_CUSTOM, "-width", NULL, NULL, "1.0", Tk_Offset(PolygonItem, outline.width), TK_CONFIG_DONT_SET_DEFAULT, &pixelOption}, - {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} + {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL} }; /* @@ -158,10 +151,10 @@ static void ComputePolygonBbox(Tk_Canvas canvas, PolygonItem *polyPtr); static int ConfigurePolygon(Tcl_Interp *interp, Tk_Canvas canvas, Tk_Item *itemPtr, int objc, - Tcl_Obj *CONST objv[], int flags); + Tcl_Obj *const objv[], int flags); static int CreatePolygon(Tcl_Interp *interp, Tk_Canvas canvas, struct Tk_Item *itemPtr, - int objc, Tcl_Obj *CONST objv[]); + int objc, Tcl_Obj *const objv[]); static void DeletePolygon(Tk_Canvas canvas, Tk_Item *itemPtr, Display *display); static void DisplayPolygon(Tk_Canvas canvas, @@ -172,7 +165,7 @@ static int GetPolygonIndex(Tcl_Interp *interp, Tcl_Obj *obj, int *indexPtr); static int PolygonCoords(Tcl_Interp *interp, Tk_Canvas canvas, Tk_Item *itemPtr, - int objc, Tcl_Obj *CONST objv[]); + int objc, Tcl_Obj *const objv[]); static void PolygonDeleteCoords(Tk_Canvas canvas, Tk_Item *itemPtr, int first, int last); static void PolygonInsert(Tk_Canvas canvas, @@ -203,18 +196,19 @@ Tk_ItemType tkPolygonType = { PolygonCoords, /* coordProc */ DeletePolygon, /* deleteProc */ DisplayPolygon, /* displayProc */ - TK_CONFIG_OBJS, /* flags */ + TK_CONFIG_OBJS | TK_MOVABLE_POINTS, /* flags */ PolygonToPoint, /* pointProc */ PolygonToArea, /* areaProc */ PolygonToPostscript, /* postscriptProc */ ScalePolygon, /* scaleProc */ TranslatePolygon, /* translateProc */ - (Tk_ItemIndexProc *) GetPolygonIndex,/* indexProc */ + GetPolygonIndex, /* indexProc */ NULL, /* icursorProc */ NULL, /* selectionProc */ - (Tk_ItemInsertProc *) PolygonInsert,/* insertProc */ + PolygonInsert, /* insertProc */ PolygonDeleteCoords, /* dTextProc */ NULL, /* nextPtr */ + NULL, 0, NULL, NULL }; /* @@ -251,13 +245,13 @@ CreatePolygon( Tk_Item *itemPtr, /* Record to hold new item; header has been * initialized by caller. */ int objc, /* Number of arguments in objv. */ - Tcl_Obj *CONST objv[]) /* Arguments describing polygon. */ + Tcl_Obj *const objv[]) /* Arguments describing polygon. */ { PolygonItem *polyPtr = (PolygonItem *) itemPtr; int i; if (objc == 0) { - Tcl_Panic("canvas did not pass any coords\n"); + Tcl_Panic("canvas did not pass any coords"); } /* @@ -265,7 +259,7 @@ CreatePolygon( * errors during the the remainder of this function. */ - Tk_CreateOutline(&(polyPtr->outline)); + Tk_CreateOutline(&polyPtr->outline); polyPtr->numPoints = 0; polyPtr->pointsAllocated = 0; polyPtr->coordPtr = NULL; @@ -291,7 +285,8 @@ CreatePolygon( */ for (i = 0; i < objc; i++) { - char *arg = Tcl_GetString(objv[i]); + const char *arg = Tcl_GetString(objv[i]); + if ((arg[0] == '-') && (arg[1] >= 'a') && (arg[1] <= 'z')) { break; } @@ -334,7 +329,7 @@ PolygonCoords( Tk_Item *itemPtr, /* Item whose coordinates are to be read or * modified. */ int objc, /* Number of coordinates supplied in objv. */ - Tcl_Obj *CONST objv[]) /* Array of coordinates: x1, y1, x2, y2, ... */ + Tcl_Obj *const objv[]) /* Array of coordinates: x1, y1, x2, y2, ... */ { PolygonItem *polyPtr = (PolygonItem *) itemPtr; int i, numPoints; @@ -361,50 +356,49 @@ PolygonCoords( } } if (objc & 1) { - char buf[64 + TCL_INTEGER_SPACE]; - - sprintf(buf, "wrong # coordinates: expected an even number, got %d", - objc); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "wrong # coordinates: expected an even number, got %d", + objc)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "POLYGON", NULL); return TCL_ERROR; - } else { - numPoints = objc/2; - if (polyPtr->pointsAllocated <= numPoints) { - if (polyPtr->coordPtr != NULL) { - ckfree((char *) polyPtr->coordPtr); - } - - /* - * One extra point gets allocated here, because we always add - * another point to close the polygon. - */ + } - polyPtr->coordPtr = (double *) ckalloc((unsigned) - (sizeof(double) * (objc+2))); - polyPtr->pointsAllocated = numPoints+1; - } - for (i = objc-1; i >= 0; i--) { - if (Tk_CanvasGetCoordFromObj(interp, canvas, objv[i], - &polyPtr->coordPtr[i]) != TCL_OK) { - return TCL_ERROR; - } + numPoints = objc/2; + if (polyPtr->pointsAllocated <= numPoints) { + if (polyPtr->coordPtr != NULL) { + ckfree(polyPtr->coordPtr); } - polyPtr->numPoints = numPoints; - polyPtr->autoClosed = 0; /* - * Close the polygon if it isn't already closed. + * One extra point gets allocated here, because we always add + * another point to close the polygon. */ - if (objc>2 && ((polyPtr->coordPtr[objc-2] != polyPtr->coordPtr[0]) - || (polyPtr->coordPtr[objc-1] != polyPtr->coordPtr[1]))) { - polyPtr->autoClosed = 1; - polyPtr->numPoints++; - polyPtr->coordPtr[objc] = polyPtr->coordPtr[0]; - polyPtr->coordPtr[objc+1] = polyPtr->coordPtr[1]; + polyPtr->coordPtr = ckalloc(sizeof(double) * (objc+2)); + polyPtr->pointsAllocated = numPoints+1; + } + for (i = objc-1; i >= 0; i--) { + if (Tk_CanvasGetCoordFromObj(interp, canvas, objv[i], + &polyPtr->coordPtr[i]) != TCL_OK) { + return TCL_ERROR; } - ComputePolygonBbox(canvas, polyPtr); } + polyPtr->numPoints = numPoints; + polyPtr->autoClosed = 0; + + /* + * Close the polygon if it isn't already closed. + */ + + if (objc>2 && ((polyPtr->coordPtr[objc-2] != polyPtr->coordPtr[0]) + || (polyPtr->coordPtr[objc-1] != polyPtr->coordPtr[1]))) { + polyPtr->autoClosed = 1; + polyPtr->numPoints++; + polyPtr->coordPtr[objc] = polyPtr->coordPtr[0]; + polyPtr->coordPtr[objc+1] = polyPtr->coordPtr[1]; + } + + ComputePolygonBbox(canvas, polyPtr); return TCL_OK; } @@ -433,7 +427,7 @@ ConfigurePolygon( Tk_Canvas canvas, /* Canvas containing itemPtr. */ Tk_Item *itemPtr, /* Polygon item to reconfigure. */ int objc, /* Number of elements in objv. */ - Tcl_Obj *CONST objv[], /* Arguments describing things to configure. */ + Tcl_Obj *const objv[], /* Arguments describing things to configure. */ int flags) /* Flags to pass to Tk_ConfigureWidget. */ { PolygonItem *polyPtr = (PolygonItem *) itemPtr; @@ -447,7 +441,7 @@ ConfigurePolygon( tkwin = Tk_CanvasTkwin(canvas); if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc, - (CONST char **) objv, (char *) polyPtr, flags|TK_CONFIG_OBJS)) { + (const char **) objv, (char *) polyPtr, flags|TK_CONFIG_OBJS)) { return TCL_ERROR; } @@ -469,15 +463,15 @@ ConfigurePolygon( itemPtr->redraw_flags &= ~TK_ITEM_STATE_DEPENDANT; } - if(state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + if (state == TK_STATE_NULL) { + state = Canvas(canvas)->canvas_state; } - if (state==TK_STATE_HIDDEN) { + if (state == TK_STATE_HIDDEN) { ComputePolygonBbox(canvas, polyPtr); return TCL_OK; } - mask = Tk_ConfigOutlineGC(&gcValues, canvas, itemPtr, &(polyPtr->outline)); + mask = Tk_ConfigOutlineGC(&gcValues, canvas, itemPtr, &polyPtr->outline); if (mask) { gcValues.cap_style = CapRound; gcValues.join_style = polyPtr->joinStyle; @@ -493,18 +487,18 @@ ConfigurePolygon( color = polyPtr->fillColor; stipple = polyPtr->fillStipple; - if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { - if (polyPtr->activeFillColor!=NULL) { + if (Canvas(canvas)->currentItemPtr == itemPtr) { + if (polyPtr->activeFillColor != NULL) { color = polyPtr->activeFillColor; } - if (polyPtr->activeFillStipple!=None) { + if (polyPtr->activeFillStipple != None) { stipple = polyPtr->activeFillStipple; } - } else if (state==TK_STATE_DISABLED) { - if (polyPtr->disabledFillColor!=NULL) { + } else if (state == TK_STATE_DISABLED) { + if (polyPtr->disabledFillColor != NULL) { color = polyPtr->disabledFillColor; } - if (polyPtr->disabledFillStipple!=None) { + if (polyPtr->disabledFillStipple != None) { stipple = polyPtr->disabledFillStipple; } } @@ -574,9 +568,9 @@ DeletePolygon( { PolygonItem *polyPtr = (PolygonItem *) itemPtr; - Tk_DeleteOutline(display,&(polyPtr->outline)); + Tk_DeleteOutline(display, &polyPtr->outline); if (polyPtr->coordPtr != NULL) { - ckfree((char *) polyPtr->coordPtr); + ckfree(polyPtr->coordPtr); } if (polyPtr->fillColor != NULL) { Tk_FreeColor(polyPtr->fillColor); @@ -629,21 +623,22 @@ ComputePolygonBbox( Tk_State state = polyPtr->header.state; Tk_TSOffset *tsoffset; - if(state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + if (state == TK_STATE_NULL) { + state = Canvas(canvas)->canvas_state; } width = polyPtr->outline.width; - if (polyPtr->coordPtr == NULL || (polyPtr->numPoints < 1) || (state==TK_STATE_HIDDEN)) { + if (polyPtr->coordPtr == NULL || (polyPtr->numPoints < 1) + || (state == TK_STATE_HIDDEN)) { polyPtr->header.x1 = polyPtr->header.x2 = - polyPtr->header.y1 = polyPtr->header.y2 = -1; + polyPtr->header.y1 = polyPtr->header.y2 = -1; return; } - if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *)polyPtr) { - if (polyPtr->outline.activeWidth>width) { + if (Canvas(canvas)->currentItemPtr == (Tk_Item *) polyPtr) { + if (polyPtr->outline.activeWidth > width) { width = polyPtr->outline.activeWidth; } - } else if (state==TK_STATE_DISABLED) { - if (polyPtr->outline.disabledWidth>0.0) { + } else if (state == TK_STATE_DISABLED) { + if (polyPtr->outline.disabledWidth > 0.0) { width = polyPtr->outline.disabledWidth; } } @@ -669,6 +664,7 @@ ComputePolygonBbox( tsoffset = &polyPtr->tsoffset; if (tsoffset->flags & TK_OFFSET_INDEX) { int index = tsoffset->flags & ~TK_OFFSET_INDEX; + if (tsoffset->flags == INT_MAX) { index = (polyPtr->numPoints - polyPtr->autoClosed) * 2; if (index < 0) { @@ -676,7 +672,7 @@ ComputePolygonBbox( } } index %= (polyPtr->numPoints - polyPtr->autoClosed) * 2; - if (index <0) { + if (index < 0) { index += (polyPtr->numPoints - polyPtr->autoClosed) * 2; } tsoffset->xoffset = (int) (polyPtr->coordPtr[index] + 0.5); @@ -708,7 +704,7 @@ ComputePolygonBbox( index = (polyPtr->numPoints - 1) * 2; } index %= (polyPtr->numPoints - 1) * 2; - if (index <0) { + if (index < 0) { index += (polyPtr->numPoints - 1) * 2; } tsoffset->xoffset = (int) (polyPtr->coordPtr[index] + 0.5); @@ -717,21 +713,23 @@ ComputePolygonBbox( if (tsoffset->flags & TK_OFFSET_LEFT) { tsoffset->xoffset = polyPtr->header.x1; } else if (tsoffset->flags & TK_OFFSET_CENTER) { - tsoffset->xoffset = (polyPtr->header.x1 + polyPtr->header.x2)/2; + tsoffset->xoffset = + (polyPtr->header.x1 + polyPtr->header.x2) / 2; } else if (tsoffset->flags & TK_OFFSET_RIGHT) { tsoffset->xoffset = polyPtr->header.x2; } if (tsoffset->flags & TK_OFFSET_TOP) { tsoffset->yoffset = polyPtr->header.y1; } else if (tsoffset->flags & TK_OFFSET_MIDDLE) { - tsoffset->yoffset = (polyPtr->header.y1 + polyPtr->header.y2)/2; + tsoffset->yoffset = + (polyPtr->header.y1 + polyPtr->header.y2) / 2; } else if (tsoffset->flags & TK_OFFSET_BOTTOM) { tsoffset->yoffset = polyPtr->header.y2; } } } - i = (int) ((width+1.5)/2.0); + i = (int) ((width+1.5) / 2.0); polyPtr->header.x1 -= i; polyPtr->header.x2 += i; polyPtr->header.y1 -= i; @@ -748,19 +746,17 @@ ComputePolygonBbox( int j; coordPtr = polyPtr->coordPtr; - if (polyPtr->numPoints>3) { + if (polyPtr->numPoints > 3) { if (TkGetMiterPoints(coordPtr+2*(polyPtr->numPoints-2), - coordPtr, coordPtr+2, width, - miter, miter+2)) { + coordPtr, coordPtr+2, width, miter, miter+2)) { for (j = 0; j < 4; j += 2) { TkIncludePoint((Tk_Item *) polyPtr, miter+j); } } - } + } for (i = polyPtr->numPoints ; i >= 3; i--, coordPtr += 2) { - - if (TkGetMiterPoints(coordPtr, coordPtr+2, coordPtr+4, - width, miter, miter+2)) { + if (TkGetMiterPoints(coordPtr, coordPtr+2, coordPtr+4, width, + miter, miter+2)) { for (j = 0; j < 4; j += 2) { TkIncludePoint((Tk_Item *) polyPtr, miter+j); } @@ -827,7 +823,7 @@ TkFillPolygon( if (numPoints <= MAX_STATIC_POINTS) { pointPtr = staticPoints; } else { - pointPtr = (XPoint *) ckalloc((unsigned) (numPoints * sizeof(XPoint))); + pointPtr = ckalloc(numPoints * sizeof(XPoint)); } for (i=0, pPtr=pointPtr ; i<numPoints; i+=1, coordPtr+=2, pPtr++) { @@ -840,16 +836,16 @@ TkFillPolygon( * allocated. */ - if (gc != NULL && numPoints>3) { + if (gc != NULL && numPoints > 3) { XFillPolygon(display, drawable, gc, pointPtr, numPoints, Complex, CoordModeOrigin); } if (outlineGC != NULL) { - XDrawLines(display, drawable, outlineGC, pointPtr, - numPoints, CoordModeOrigin); + XDrawLines(display, drawable, outlineGC, pointPtr, numPoints, + CoordModeOrigin); } if (pointPtr != staticPoints) { - ckfree((char *) pointPtr); + ckfree(pointPtr); } } @@ -892,17 +888,17 @@ DisplayPolygon( } if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } - if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { - if (polyPtr->outline.activeWidth>linewidth) { + if (Canvas(canvas)->currentItemPtr == itemPtr) { + if (polyPtr->outline.activeWidth > linewidth) { linewidth = polyPtr->outline.activeWidth; } if (polyPtr->activeFillStipple != None) { stipple = polyPtr->activeFillStipple; } - } else if (state==TK_STATE_DISABLED) { - if (polyPtr->outline.disabledWidth>0.0) { + } else if (state == TK_STATE_DISABLED) { + if (polyPtr->outline.disabledWidth > 0.0) { linewidth = polyPtr->outline.disabledWidth; } if (polyPtr->disabledFillStipple != None) { @@ -917,10 +913,11 @@ DisplayPolygon( if ((stipple != None) && (polyPtr->fillGC != NULL)) { Tk_TSOffset *tsoffset = &polyPtr->tsoffset; - int w=0; int h=0; + int w = 0, h = 0; int flags = tsoffset->flags; - if (!(flags & TK_OFFSET_INDEX) && (flags & (TK_OFFSET_CENTER|TK_OFFSET_MIDDLE))) { + if (!(flags & TK_OFFSET_INDEX) + && (flags & (TK_OFFSET_CENTER|TK_OFFSET_MIDDLE))) { Tk_SizeOfBitmap(display, stipple, &w, &h); if (flags & TK_OFFSET_CENTER) { w /= 2; @@ -939,20 +936,20 @@ DisplayPolygon( tsoffset->xoffset += w; tsoffset->yoffset += h; } - Tk_ChangeOutlineGC(canvas, itemPtr, &(polyPtr->outline)); + Tk_ChangeOutlineGC(canvas, itemPtr, &polyPtr->outline); - if(polyPtr->numPoints < 3) { - short x,y; + if (polyPtr->numPoints < 3) { + short x, y; int intLineWidth = (int) (linewidth + 0.5); if (intLineWidth < 1) { intLineWidth = 1; } Tk_CanvasDrawableCoords(canvas, polyPtr->coordPtr[0], - polyPtr->coordPtr[1], &x,&y); + polyPtr->coordPtr[1], &x, &y); XFillArc(display, drawable, polyPtr->outline.gc, x - intLineWidth/2, y - intLineWidth/2, - (unsigned int)intLineWidth+1, (unsigned int)intLineWidth+1, + (unsigned) intLineWidth+1, (unsigned) intLineWidth+1, 0, 64*360); } else if (!polyPtr->smooth || polyPtr->numPoints < 4) { TkFillPolygon(canvas, polyPtr->coordPtr, polyPtr->numPoints, @@ -972,8 +969,7 @@ DisplayPolygon( if (numPoints <= MAX_STATIC_POINTS) { pointPtr = staticPoints; } else { - pointPtr = (XPoint *) ckalloc((unsigned) - (numPoints * sizeof(XPoint))); + pointPtr = ckalloc(numPoints * sizeof(XPoint)); } numPoints = polyPtr->smooth->coordProc(canvas, polyPtr->coordPtr, polyPtr->numPoints, polyPtr->splineSteps, pointPtr, NULL); @@ -986,10 +982,10 @@ DisplayPolygon( numPoints, CoordModeOrigin); } if (pointPtr != staticPoints) { - ckfree((char *) pointPtr); + ckfree(pointPtr); } } - Tk_ResetOutlineGC(canvas, itemPtr, &(polyPtr->outline)); + Tk_ResetOutlineGC(canvas, itemPtr, &polyPtr->outline); if ((stipple != None) && (polyPtr->fillGC != NULL)) { XSetTSOrigin(display, polyPtr->fillGC, 0, 0); } @@ -1026,7 +1022,7 @@ PolygonInsert( Tk_State state = itemPtr->state; if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } if (!obj || (Tcl_ListObjGetElements(NULL, obj, &objc, &objv) != TCL_OK) @@ -1034,21 +1030,20 @@ PolygonInsert( return; } length = 2*(polyPtr->numPoints - polyPtr->autoClosed); - while (beforeThis>length) { + while (beforeThis > length) { beforeThis -= length; } - while (beforeThis<0) { + while (beforeThis < 0) { beforeThis += length; } - newCoordPtr = (double *) - ckalloc(sizeof(double) * (unsigned)(length + 2 + objc)); + newCoordPtr = ckalloc(sizeof(double) * (length + 2 + objc)); for (i=0; i<beforeThis; i++) { newCoordPtr[i] = polyPtr->coordPtr[i]; } for (i=0; i<objc; i++) { if (Tcl_GetDoubleFromObj(NULL, objv[i], &newCoordPtr[i+beforeThis]) != TCL_OK){ - ckfree((char *) newCoordPtr); + ckfree(newCoordPtr); return; } } @@ -1057,7 +1052,7 @@ PolygonInsert( newCoordPtr[i+objc] = polyPtr->coordPtr[i]; } if (polyPtr->coordPtr) { - ckfree((char *) polyPtr->coordPtr); + ckfree(polyPtr->coordPtr); } length += objc; polyPtr->coordPtr = newCoordPtr; @@ -1084,7 +1079,7 @@ PolygonInsert( newCoordPtr[length] = newCoordPtr[0]; newCoordPtr[length+1] = newCoordPtr[1]; - if (((length-objc)>3) && (state != TK_STATE_HIDDEN)) { + if ((length-objc > 3) && (state != TK_STATE_HIDDEN)) { /* * This is some optimizing code that will result that only the part of * the polygon that changed (and the objects that are overlapping with @@ -1096,6 +1091,7 @@ PolygonInsert( double width; int j; + itemPtr->redraw_flags |= TK_ITEM_DONT_REDRAW; /* @@ -1107,10 +1103,11 @@ PolygonInsert( itemPtr->x1 = itemPtr->x2 = (int) polyPtr->coordPtr[beforeThis]; itemPtr->y1 = itemPtr->y2 = (int) polyPtr->coordPtr[beforeThis+1]; - beforeThis-=2; objc+=4; + beforeThis -= 2; + objc += 4; if (polyPtr->smooth) { - beforeThis-=2; - objc+=4; + beforeThis -= 2; + objc += 4; } /* @@ -1119,25 +1116,27 @@ PolygonInsert( for (i=beforeThis; i<beforeThis+objc; i+=2) { j = i; - if (j<0) { + if (j < 0) { j += length; - } else if (j>=length) { + } else if (j >= length) { j -= length; } TkIncludePoint(itemPtr, polyPtr->coordPtr+j); } width = polyPtr->outline.width; - if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { + if (Canvas(canvas)->currentItemPtr == itemPtr) { if (polyPtr->outline.activeWidth > width) { width = polyPtr->outline.activeWidth; } - } else if (state==TK_STATE_DISABLED) { + } else if (state == TK_STATE_DISABLED) { if (polyPtr->outline.disabledWidth > 0.0) { width = polyPtr->outline.disabledWidth; } } - itemPtr->x1 -= (int) width; itemPtr->y1 -= (int) width; - itemPtr->x2 += (int) width; itemPtr->y2 += (int) width; + itemPtr->x1 -= (int) width; + itemPtr->y1 -= (int) width; + itemPtr->x2 += (int) width; + itemPtr->y2 += (int) width; Tk_CanvasEventuallyRedraw(canvas, itemPtr->x1, itemPtr->y1, itemPtr->x2, itemPtr->y2); } @@ -1173,16 +1172,16 @@ PolygonDeleteCoords( int count, i; int length = 2*(polyPtr->numPoints - polyPtr->autoClosed); - while (first>=length) { + while (first >= length) { first -= length; } - while (first<0) { + while (first < 0) { first += length; } - while (last>=length) { + while (last >= length) { last -= length; } - while (last<0) { + while (last < 0) { last += length; } @@ -1190,26 +1189,26 @@ PolygonDeleteCoords( last &= -2; count = last + 2 - first; - if (count<=0) { + if (count <= 0) { count += length; } if (count >= length) { polyPtr->numPoints = 0; if (polyPtr->coordPtr != NULL) { - ckfree((char *) polyPtr->coordPtr); + ckfree(polyPtr->coordPtr); polyPtr->coordPtr = NULL; } ComputePolygonBbox(canvas, polyPtr); return; } - if (last>=first) { - for(i=last+2; i<length; i++) { + if (last >= first) { + for (i=last+2; i<length; i++) { polyPtr->coordPtr[i-count] = polyPtr->coordPtr[i]; } } else { - for(i=last; i<=first; i++) { + for (i=last; i<=first; i++) { polyPtr->coordPtr[i-last] = polyPtr->coordPtr[i]; } } @@ -1262,15 +1261,15 @@ PolygonToPoint( bestDist = 1.0e36; if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } width = polyPtr->outline.width; - if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { - if (polyPtr->outline.activeWidth>width) { + if (Canvas(canvas)->currentItemPtr == itemPtr) { + if (polyPtr->outline.activeWidth > width) { width = polyPtr->outline.activeWidth; } - } else if (state==TK_STATE_DISABLED) { - if (polyPtr->outline.disabledWidth>0.0) { + } else if (state == TK_STATE_DISABLED) { + if (polyPtr->outline.disabledWidth > 0.0) { width = polyPtr->outline.disabledWidth; } } @@ -1281,26 +1280,23 @@ PolygonToPoint( * against which to do the check. */ - if ((polyPtr->smooth) && (polyPtr->numPoints>2)) { + if ((polyPtr->smooth) && (polyPtr->numPoints > 2)) { numPoints = polyPtr->smooth->coordProc(canvas, NULL, - polyPtr->numPoints, polyPtr->splineSteps, NULL, - NULL); + polyPtr->numPoints, polyPtr->splineSteps, NULL, NULL); if (numPoints <= MAX_STATIC_POINTS) { polyPoints = staticSpace; } else { - polyPoints = (double *) ckalloc((unsigned) - (2*numPoints*sizeof(double))); + polyPoints = ckalloc(2 * numPoints * sizeof(double)); } numPoints = polyPtr->smooth->coordProc(canvas, polyPtr->coordPtr, - polyPtr->numPoints, polyPtr->splineSteps, NULL, - polyPoints); + polyPtr->numPoints, polyPtr->splineSteps, NULL, polyPoints); } else { numPoints = polyPtr->numPoints; polyPoints = polyPtr->coordPtr; } bestDist = TkPolygonToPoint(polyPoints, numPoints, pointPtr); - if (bestDist<=0.0) { + if (bestDist <= 0.0) { goto donepoint; } if ((polyPtr->outline.gc != NULL) && (polyPtr->joinStyle == JoinRound)) { @@ -1350,16 +1346,16 @@ PolygonToPoint( */ if (count == numPoints) { - TkGetButtPoints(coordPtr+2, coordPtr, (double) width, - 0, poly, poly+2); + TkGetButtPoints(coordPtr+2, coordPtr, (double) width, 0, poly, + poly+2); } else if ((polyPtr->joinStyle == JoinMiter) && !changedMiterToBevel) { poly[0] = poly[6]; poly[1] = poly[7]; poly[2] = poly[4]; poly[3] = poly[5]; } else { - TkGetButtPoints(coordPtr+2, coordPtr, (double) width, 0, - poly, poly+2); + TkGetButtPoints(coordPtr+2, coordPtr, (double) width, 0, poly, + poly+2); /* * If this line uses beveled joints, then check the distance to a @@ -1382,8 +1378,8 @@ PolygonToPoint( } } if (count == 2) { - TkGetButtPoints(coordPtr, coordPtr+2, (double) width, - 0, poly+4, poly+6); + TkGetButtPoints(coordPtr, coordPtr+2, (double) width, 0, poly+4, + poly+6); } else if (polyPtr->joinStyle == JoinMiter) { if (TkGetMiterPoints(coordPtr, coordPtr+2, coordPtr+4, (double) width, poly+4, poly+6) == 0) { @@ -1392,8 +1388,8 @@ PolygonToPoint( poly+4, poly+6); } } else { - TkGetButtPoints(coordPtr, coordPtr+2, (double) width, 0, - poly+4, poly+6); + TkGetButtPoints(coordPtr, coordPtr+2, (double) width, 0, poly+4, + poly+6); } poly[8] = poly[0]; poly[9] = poly[1]; @@ -1407,8 +1403,8 @@ PolygonToPoint( } donepoint: - if ((polyPoints != staticSpace) && polyPoints != polyPtr->coordPtr) { - ckfree((char *) polyPoints); + if (polyPoints != staticSpace && polyPoints != polyPtr->coordPtr) { + ckfree(polyPoints); } return bestDist; } @@ -1459,16 +1455,16 @@ PolygonToArea( Tk_State state = itemPtr->state; if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } width = polyPtr->outline.width; - if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { - if (polyPtr->outline.activeWidth>width) { + if (Canvas(canvas)->currentItemPtr == itemPtr) { + if (polyPtr->outline.activeWidth > width) { width = polyPtr->outline.activeWidth; } - } else if (state==TK_STATE_DISABLED) { - if (polyPtr->outline.disabledWidth>0.0) { + } else if (state == TK_STATE_DISABLED) { + if (polyPtr->outline.disabledWidth > 0.0) { width = polyPtr->outline.disabledWidth; } } @@ -1476,9 +1472,9 @@ PolygonToArea( radius = width/2.0; inside = -1; - if ((state==TK_STATE_HIDDEN) || polyPtr->numPoints<2) { + if ((state == TK_STATE_HIDDEN) || polyPtr->numPoints < 2) { return -1; - } else if (polyPtr->numPoints <3) { + } else if (polyPtr->numPoints < 3) { double oval[4]; oval[0] = polyPtr->coordPtr[0]-radius; @@ -1499,8 +1495,7 @@ PolygonToArea( if (numPoints <= MAX_STATIC_POINTS) { polyPoints = staticSpace; } else { - polyPoints = (double *) - ckalloc((unsigned) (2*numPoints*sizeof(double))); + polyPoints = ckalloc(2 * numPoints * sizeof(double)); } numPoints = polyPtr->smooth->coordProc(canvas, polyPtr->coordPtr, polyPtr->numPoints, polyPtr->splineSteps, NULL, polyPoints); @@ -1516,7 +1511,7 @@ PolygonToArea( */ inside = TkPolygonToArea(polyPoints, numPoints, rectPtr); - if (inside==0) { + if (inside == 0) { goto donearea; } @@ -1585,8 +1580,8 @@ PolygonToArea( if (count == 2) { TkGetButtPoints(coordPtr, coordPtr+2, width, 0, poly+4, poly+6); } else if (polyPtr->joinStyle == JoinMiter) { - if (TkGetMiterPoints(coordPtr, coordPtr+2, coordPtr+4, - width, poly+4, poly+6) == 0) { + if (TkGetMiterPoints(coordPtr, coordPtr+2, coordPtr+4, width, + poly+4, poly+6) == 0) { changedMiterToBevel = 1; TkGetButtPoints(coordPtr, coordPtr+2, width,0, poly+4, poly+6); } @@ -1603,7 +1598,7 @@ PolygonToArea( donearea: if ((polyPoints != staticSpace) && (polyPoints != polyPtr->coordPtr)) { - ckfree((char *) polyPoints); + ckfree(polyPoints); } return inside; } @@ -1678,27 +1673,18 @@ GetPolygonIndex( int *indexPtr) /* Where to store converted index. */ { PolygonItem *polyPtr = (PolygonItem *) itemPtr; - int length; - char *string = Tcl_GetStringFromObj(obj, &length); + const char *string = Tcl_GetString(obj); if (string[0] == 'e') { - if (strncmp(string, "end", (unsigned)length) == 0) { - *indexPtr = 2*(polyPtr->numPoints - polyPtr->autoClosed); - } else { - /* - * Some of the paths here leave messages in interp->result, so we - * have to clear it out before storing our own message. - */ - - badIndex: - Tcl_SetResult(interp, NULL, TCL_STATIC); - Tcl_AppendResult(interp, "bad index \"", string, "\"", NULL); - return TCL_ERROR; + if (strncmp(string, "end", obj->length) != 0) { + goto badIndex; } + *indexPtr = 2*(polyPtr->numPoints - polyPtr->autoClosed); } else if (string[0] == '@') { int i; - double x ,y, bestDist, dist, *coordPtr; - char *end, *p; + double x, y, bestDist, dist, *coordPtr; + char *end; + const char *p; p = string+1; x = strtod(p, &end); @@ -1713,9 +1699,9 @@ GetPolygonIndex( bestDist = 1.0e36; coordPtr = polyPtr->coordPtr; *indexPtr = 0; - for(i=0; i<(polyPtr->numPoints-1); i++) { + for (i=0; i<polyPtr->numPoints-1; i++) { dist = hypot(coordPtr[0] - x, coordPtr[1] - y); - if (dist<bestDist) { + if (dist < bestDist) { bestDist = dist; *indexPtr = 2*i; } @@ -1728,17 +1714,25 @@ GetPolygonIndex( goto badIndex; } *indexPtr &= -2; /* if odd, make it even */ - if (count) { - if (*indexPtr > 0) { - *indexPtr = ((*indexPtr - 2) % count) + 2; - } else { - *indexPtr = -((-(*indexPtr)) % count); - } - } else { + if (!count) { *indexPtr = 0; + } else if (*indexPtr > 0) { + *indexPtr = ((*indexPtr - 2) % count) + 2; + } else { + *indexPtr = -((-(*indexPtr)) % count); } } return TCL_OK; + + /* + * Some of the paths here leave messages in interp->result, so we have to + * clear it out before storing our own message. + */ + + badIndex: + Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad index \"%s\"", string)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "ITEM_INDEX", "POLY", NULL); + return TCL_ERROR; } /* @@ -1806,89 +1800,120 @@ PolygonToPostscript( * being created. */ { PolygonItem *polyPtr = (PolygonItem *) itemPtr; - char *style; + int style; XColor *color; XColor *fillColor; Pixmap stipple; Pixmap fillStipple; Tk_State state = itemPtr->state; double width; + Tcl_Obj *psObj; + Tcl_InterpState interpState; - if (polyPtr->numPoints<2 || polyPtr->coordPtr==NULL) { + if (polyPtr->numPoints < 2 || polyPtr->coordPtr == NULL) { return TCL_OK; } - if(state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + if (state == TK_STATE_NULL) { + state = Canvas(canvas)->canvas_state; } width = polyPtr->outline.width; color = polyPtr->outline.color; stipple = polyPtr->fillStipple; fillColor = polyPtr->fillColor; fillStipple = polyPtr->fillStipple; - if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { - if (polyPtr->outline.activeWidth>width) { + if (Canvas(canvas)->currentItemPtr == itemPtr) { + if (polyPtr->outline.activeWidth > width) { width = polyPtr->outline.activeWidth; } - if (polyPtr->outline.activeColor!=NULL) { + if (polyPtr->outline.activeColor != NULL) { color = polyPtr->outline.activeColor; } - if (polyPtr->outline.activeStipple!=None) { + if (polyPtr->outline.activeStipple != None) { stipple = polyPtr->outline.activeStipple; } - if (polyPtr->activeFillColor!=NULL) { + if (polyPtr->activeFillColor != NULL) { fillColor = polyPtr->activeFillColor; } - if (polyPtr->activeFillStipple!=None) { + if (polyPtr->activeFillStipple != None) { fillStipple = polyPtr->activeFillStipple; } - } else if (state==TK_STATE_DISABLED) { - if (polyPtr->outline.disabledWidth>0.0) { + } else if (state == TK_STATE_DISABLED) { + if (polyPtr->outline.disabledWidth > 0.0) { width = polyPtr->outline.disabledWidth; } - if (polyPtr->outline.disabledColor!=NULL) { + if (polyPtr->outline.disabledColor != NULL) { color = polyPtr->outline.disabledColor; } - if (polyPtr->outline.disabledStipple!=None) { + if (polyPtr->outline.disabledStipple != None) { stipple = polyPtr->outline.disabledStipple; } - if (polyPtr->disabledFillColor!=NULL) { + if (polyPtr->disabledFillColor != NULL) { fillColor = polyPtr->disabledFillColor; } - if (polyPtr->disabledFillStipple!=None) { + if (polyPtr->disabledFillStipple != None) { fillStipple = polyPtr->disabledFillStipple; } } - if (polyPtr->numPoints==2) { - char string[128]; + + /* + * Make our working space. + */ + + psObj = Tcl_NewObj(); + interpState = Tcl_SaveInterpState(interp, TCL_OK); + + if (polyPtr->numPoints == 2) { if (color == NULL) { - return TCL_OK; + goto done; } - sprintf(string, "%.15g %.15g translate %.15g %.15g", - polyPtr->coordPtr[0], Tk_CanvasPsY(canvas, polyPtr->coordPtr[1]), + /* + * Create a point by using a small circle. (Printer pixels are too + * tiny to be used directly...) + */ + + Tcl_AppendPrintfToObj(psObj, + "matrix currentmatrix\n" /* save state */ + "%.15g %.15g translate " /* go to drawing location */ + "%.15g %.15g scale " /* scale the drawing */ + "1 0 moveto " /* correct for origin */ + "0 0 1 0 360 arc\n" /* make the circle */ + "setmatrix\n", /* restore state */ + polyPtr->coordPtr[0], + Tk_CanvasPsY(canvas, polyPtr->coordPtr[1]), width/2.0, width/2.0); - Tcl_AppendResult(interp, "matrix currentmatrix\n",string, - " scale 1 0 moveto 0 0 1 0 360 arc\nsetmatrix\n", NULL); + + /* + * Color it in. + */ + + Tcl_ResetResult(interp); if (Tk_CanvasPsColor(interp, canvas, color) != TCL_OK) { - return TCL_ERROR; + goto error; } + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); + if (stipple != None) { - Tcl_AppendResult(interp, "clip ", NULL); + Tcl_AppendToObj(psObj, "clip ", -1); + + Tcl_ResetResult(interp); if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK) { - return TCL_ERROR; + goto error; } + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); } else { - Tcl_AppendResult(interp, "fill\n", NULL); + Tcl_AppendToObj(psObj, "fill\n", -1); } - return TCL_OK; + goto done; } /* * Fill the area of the polygon. */ - if (fillColor != NULL && polyPtr->numPoints>3) { + if (fillColor != NULL && polyPtr->numPoints > 3) { + Tcl_ResetResult(interp); if (!polyPtr->smooth || !polyPtr->smooth->postscriptProc) { Tk_CanvasPsPath(interp, canvas, polyPtr->coordPtr, polyPtr->numPoints); @@ -1897,18 +1922,24 @@ PolygonToPostscript( polyPtr->numPoints, polyPtr->splineSteps); } if (Tk_CanvasPsColor(interp, canvas, fillColor) != TCL_OK) { - return TCL_ERROR; + goto error; } + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); + if (fillStipple != None) { - Tcl_AppendResult(interp, "eoclip ", NULL); + Tcl_AppendToObj(psObj, "eoclip ", -1); + + Tcl_ResetResult(interp); if (Tk_CanvasPsStipple(interp, canvas, fillStipple) != TCL_OK) { - return TCL_ERROR; + goto error; } + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); + if (color != NULL) { - Tcl_AppendResult(interp, "grestore gsave\n", NULL); + Tcl_AppendToObj(psObj, "grestore gsave\n", -1); } } else { - Tcl_AppendResult(interp, "eofill\n", NULL); + Tcl_AppendToObj(psObj, "eofill\n", -1); } } @@ -1917,6 +1948,7 @@ PolygonToPostscript( */ if (color != NULL) { + Tcl_ResetResult(interp); if (!polyPtr->smooth || !polyPtr->smooth->postscriptProc) { Tk_CanvasPsPath(interp, canvas, polyPtr->coordPtr, polyPtr->numPoints); @@ -1924,21 +1956,38 @@ PolygonToPostscript( polyPtr->smooth->postscriptProc(interp, canvas, polyPtr->coordPtr, polyPtr->numPoints, polyPtr->splineSteps); } + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); if (polyPtr->joinStyle == JoinRound) { - style = "1"; + style = 1; } else if (polyPtr->joinStyle == JoinBevel) { - style = "2"; + style = 2; } else { - style = "0"; + style = 0; } - Tcl_AppendResult(interp, style," setlinejoin 1 setlinecap\n", NULL); - if (Tk_CanvasPsOutline(canvas, itemPtr, - &(polyPtr->outline)) != TCL_OK) { - return TCL_ERROR; + Tcl_AppendPrintfToObj(psObj, "%d setlinejoin 1 setlinecap\n", style); + + Tcl_ResetResult(interp); + if (Tk_CanvasPsOutline(canvas, itemPtr, &polyPtr->outline) != TCL_OK){ + goto error; } + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); } + + /* + * Plug the accumulated postscript back into the result. + */ + + done: + (void) Tcl_RestoreInterpState(interp, interpState); + Tcl_AppendObjToObj(Tcl_GetObjResult(interp), psObj); + Tcl_DecrRefCount(psObj); return TCL_OK; + + error: + Tcl_DiscardInterpState(interpState); + Tcl_DecrRefCount(psObj); + return TCL_ERROR; } /* diff --git a/generic/tkCanvPs.c b/generic/tkCanvPs.c index ac8f105..2bfdcc5 100644 --- a/generic/tkCanvPs.c +++ b/generic/tkCanvPs.c @@ -41,7 +41,6 @@ typedef struct TkColormapData { /* Hold color information for a window */ */ typedef struct TkPostscriptInfo { - Tk_Window tkwin; /* The canvas being printed. */ int x, y, width, height; /* Area to print, in canvas pixel * coordinates. */ int x2, y2; /* x+width and y+height. */ @@ -72,7 +71,7 @@ typedef struct TkPostscriptInfo { * NULL means return Postscript info as * result. Malloc'ed. */ char *channelName; /* If -channel is specified, the name of the - * channel to use. */ + * channel to use. */ Tcl_Channel chan; /* Open channel corresponding to fileName. */ Tcl_HashTable fontTable; /* Hash table containing names of all font * families used in output. The hash table @@ -81,7 +80,11 @@ typedef struct TkPostscriptInfo { * pre-pass that collects font information, so * the Postscript generated isn't relevant. */ int prolog; /* Non-zero means output should contain the - * prolog definitions in the header. */ + * standard prolog in the header. Generated in + * library/mkpsenc.tcl, stored in the variable + * ::tk::ps_preamable [sic]. */ + Tk_Window tkwin; /* Window to get font pixel/point transform + * from. */ } TkPostscriptInfo; /* @@ -89,40 +92,40 @@ typedef struct TkPostscriptInfo { * canvas "postscript" command and fill in TkPostscriptInfo structures. */ -static Tk_ConfigSpec configSpecs[] = { +static const Tk_ConfigSpec configSpecs[] = { {TK_CONFIG_STRING, "-colormap", NULL, NULL, - "", Tk_Offset(TkPostscriptInfo, colorVar), 0}, + "", Tk_Offset(TkPostscriptInfo, colorVar), 0, NULL}, {TK_CONFIG_STRING, "-colormode", NULL, NULL, - "", Tk_Offset(TkPostscriptInfo, colorMode), 0}, + "", Tk_Offset(TkPostscriptInfo, colorMode), 0, NULL}, {TK_CONFIG_STRING, "-file", NULL, NULL, - "", Tk_Offset(TkPostscriptInfo, fileName), 0}, + "", Tk_Offset(TkPostscriptInfo, fileName), 0, NULL}, {TK_CONFIG_STRING, "-channel", NULL, NULL, - "", Tk_Offset(TkPostscriptInfo, channelName), 0}, + "", Tk_Offset(TkPostscriptInfo, channelName), 0, NULL}, {TK_CONFIG_STRING, "-fontmap", NULL, NULL, - "", Tk_Offset(TkPostscriptInfo, fontVar), 0}, + "", Tk_Offset(TkPostscriptInfo, fontVar), 0, NULL}, {TK_CONFIG_PIXELS, "-height", NULL, NULL, - "", Tk_Offset(TkPostscriptInfo, height), 0}, + "", Tk_Offset(TkPostscriptInfo, height), 0, NULL}, {TK_CONFIG_ANCHOR, "-pageanchor", NULL, NULL, - "", Tk_Offset(TkPostscriptInfo, pageAnchor), 0}, + "", Tk_Offset(TkPostscriptInfo, pageAnchor), 0, NULL}, {TK_CONFIG_STRING, "-pageheight", NULL, NULL, - "", Tk_Offset(TkPostscriptInfo, pageHeightString), 0}, + "", Tk_Offset(TkPostscriptInfo, pageHeightString), 0, NULL}, {TK_CONFIG_STRING, "-pagewidth", NULL, NULL, - "", Tk_Offset(TkPostscriptInfo, pageWidthString), 0}, + "", Tk_Offset(TkPostscriptInfo, pageWidthString), 0, NULL}, {TK_CONFIG_STRING, "-pagex", NULL, NULL, - "", Tk_Offset(TkPostscriptInfo, pageXString), 0}, + "", Tk_Offset(TkPostscriptInfo, pageXString), 0, NULL}, {TK_CONFIG_STRING, "-pagey", NULL, NULL, - "", Tk_Offset(TkPostscriptInfo, pageYString), 0}, + "", Tk_Offset(TkPostscriptInfo, pageYString), 0, NULL}, {TK_CONFIG_BOOLEAN, "-prolog", NULL, NULL, - "", Tk_Offset(TkPostscriptInfo, prolog), 0}, + "", Tk_Offset(TkPostscriptInfo, prolog), 0, NULL}, {TK_CONFIG_BOOLEAN, "-rotate", NULL, NULL, - "", Tk_Offset(TkPostscriptInfo, rotate), 0}, + "", Tk_Offset(TkPostscriptInfo, rotate), 0, NULL}, {TK_CONFIG_PIXELS, "-width", NULL, NULL, - "", Tk_Offset(TkPostscriptInfo, width), 0}, + "", Tk_Offset(TkPostscriptInfo, width), 0, NULL}, {TK_CONFIG_PIXELS, "-x", NULL, NULL, - "", Tk_Offset(TkPostscriptInfo, x), 0}, + "", Tk_Offset(TkPostscriptInfo, x), 0, NULL}, {TK_CONFIG_PIXELS, "-y", NULL, NULL, - "", Tk_Offset(TkPostscriptInfo, y), 0}, - {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} + "", Tk_Offset(TkPostscriptInfo, y), 0, NULL}, + {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL} }; /* @@ -131,6 +134,10 @@ static Tk_ConfigSpec configSpecs[] = { static int GetPostscriptPoints(Tcl_Interp *interp, char *string, double *doublePtr); +static void PostscriptBitmap(Tk_Window tkwin, Pixmap bitmap, + int startX, int startY, int width, int height, + Tcl_Obj *psObj); +static inline Tcl_Obj * GetPostscriptBuffer(Tcl_Interp *interp); /* *-------------------------------------------------------------- @@ -156,7 +163,7 @@ TkCanvPostscriptCmd( TkCanvas *canvasPtr, /* Information about canvas widget. */ Tcl_Interp *interp, /* Current interpreter. */ int argc, /* Number of arguments. */ - CONST char **argv) /* Argument strings. Caller has already parsed + const char **argv) /* Argument strings. Caller has already parsed * this command enough to know that argv[1] is * "postscript". */ { @@ -165,15 +172,15 @@ TkCanvPostscriptCmd( int result; Tk_Item *itemPtr; #define STRING_LENGTH 400 - char string[STRING_LENGTH+1]; - CONST char *p; + const char *p; time_t now; size_t length; Tk_Window tkwin = canvasPtr->tkwin; Tcl_HashSearch search; Tcl_HashEntry *hPtr; Tcl_DString buffer; - char psenccmd[] = "::tk::ensure_psenc_is_loaded"; + Tcl_Obj *preambleObj; + Tcl_Obj *psObj; int deltaX = 0, deltaY = 0; /* Offset of lower-left corner of area to be * marked up, measured in canvas units from * the positioning point on the page (reflects @@ -181,17 +188,31 @@ TkCanvPostscriptCmd( * only to stop compiler warnings. */ /* - * Initialize the data structure describing Postscript generation, then - * process all the arguments to fill the data structure in. + * Get the generic preamble. We only ever bother with the ASCII encoding; + * the others just make life too complicated and never actually worked as + * such. */ - result = Tcl_EvalEx(interp,psenccmd,-1,TCL_EVAL_GLOBAL); + result = Tcl_EvalEx(interp, "::tk::ensure_psenc_is_loaded", -1, 0); if (result != TCL_OK) { - return result; + return result; + } + preambleObj = Tcl_GetVar2Ex(interp, "::tk::ps_preamble", NULL, + TCL_LEAVE_ERR_MSG); + if (preambleObj == NULL) { + return TCL_ERROR; } + Tcl_IncrRefCount(preambleObj); + Tcl_ResetResult(interp); + psObj = Tcl_NewObj(); + + /* + * Initialize the data structure describing Postscript generation, then + * process all the arguments to fill the data structure in. + */ + oldInfoPtr = canvasPtr->psInfo; canvasPtr->psInfo = (Tk_PostscriptInfo) psInfoPtr; - psInfo.tkwin = canvasPtr->tkwin; psInfo.x = canvasPtr->xOrigin; psInfo.y = canvasPtr->yOrigin; psInfo.width = -1; @@ -214,6 +235,7 @@ TkCanvPostscriptCmd( psInfo.chan = NULL; psInfo.prepass = 0; psInfo.prolog = 1; + psInfo.tkwin = tkwin; Tcl_InitHashTable(&psInfo.fontTable, TCL_STRING_KEYS); result = Tk_ConfigureWidget(interp, tkwin, configSpecs, argc-2, argv+2, (char *) &psInfo, TK_CONFIG_ARGV_ONLY); @@ -304,35 +326,40 @@ TkCanvPostscriptCmd( } else if (strncmp(psInfo.colorMode, "color", length) == 0) { psInfo.colorLevel = 2; } else { - Tcl_AppendResult(interp, "bad color mode \"", psInfo.colorMode, - "\": must be monochrome, gray, or color", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad color mode \"%s\": must be monochrome, gray, or color", + psInfo.colorMode)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "PS", "COLORMODE", NULL); + result = TCL_ERROR; goto cleanup; } } if (psInfo.fileName != NULL) { - /* - * Check that -file and -channel are not both specified. - */ - - if (psInfo.channelName != NULL) { - Tcl_AppendResult(interp, "can't specify both -file", - " and -channel", NULL); - result = TCL_ERROR; - goto cleanup; - } - - /* - * Check that we are not in a safe interpreter. If we are, disallow - * the -file specification. - */ - - if (Tcl_IsSafe(interp)) { - Tcl_AppendResult(interp, "can't specify -file in a", - " safe interpreter", NULL); - result = TCL_ERROR; - goto cleanup; - } + /* + * Check that -file and -channel are not both specified. + */ + + if (psInfo.channelName != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "can't specify both -file and -channel", -1)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "PS", "USAGE", NULL); + result = TCL_ERROR; + goto cleanup; + } + + /* + * Check that we are not in a safe interpreter. If we are, disallow + * the -file specification. + */ + + if (Tcl_IsSafe(interp)) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "can't specify -file in a safe interpreter", -1)); + Tcl_SetErrorCode(interp, "TK", "SAFE", "PS_FILE", NULL); + result = TCL_ERROR; + goto cleanup; + } p = Tcl_TranslateFileName(interp, psInfo.fileName, &buffer); if (p == NULL) { @@ -346,24 +373,26 @@ TkCanvPostscriptCmd( } if (psInfo.channelName != NULL) { - int mode; - - /* - * Check that the channel is found in this interpreter and that it is - * open for writing. - */ - - psInfo.chan = Tcl_GetChannel(interp, psInfo.channelName, &mode); - if (psInfo.chan == (Tcl_Channel) NULL) { - result = TCL_ERROR; - goto cleanup; - } - if ((mode & TCL_WRITABLE) == 0) { - Tcl_AppendResult(interp, "channel \"", psInfo.channelName, - "\" wasn't opened for writing", NULL); - result = TCL_ERROR; - goto cleanup; - } + int mode; + + /* + * Check that the channel is found in this interpreter and that it is + * open for writing. + */ + + psInfo.chan = Tcl_GetChannel(interp, psInfo.channelName, &mode); + if (psInfo.chan == (Tcl_Channel) NULL) { + result = TCL_ERROR; + goto cleanup; + } + if (!(mode & TCL_WRITABLE)) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "channel \"%s\" wasn't opened for writing", + psInfo.channelName)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "PS", "UNWRITABLE",NULL); + result = TCL_ERROR; + goto cleanup; + } } /* @@ -384,7 +413,7 @@ TkCanvPostscriptCmd( if (itemPtr->typePtr->postscriptProc == NULL) { continue; } - result = (*itemPtr->typePtr->postscriptProc)(interp, + result = itemPtr->typePtr->postscriptProc(interp, (Tk_Canvas) canvasPtr, itemPtr, 1); Tcl_ResetResult(interp); if (result != TCL_OK) { @@ -394,6 +423,7 @@ TkCanvPostscriptCmd( * can happen later that don't happen now, so we still have to * check for errors later anyway). */ + break; } } @@ -404,24 +434,27 @@ TkCanvPostscriptCmd( */ if (psInfo.prolog) { - Tcl_AppendResult(interp, "%!PS-Adobe-3.0 EPSF-3.0\n", - "%%Creator: Tk Canvas Widget\n", NULL); + Tcl_AppendToObj(psObj, + "%!PS-Adobe-3.0 EPSF-3.0\n" + "%%Creator: Tk Canvas Widget\n", -1); + #ifdef HAVE_PW_GECOS if (!Tcl_IsSafe(interp)) { struct passwd *pwPtr = getpwuid(getuid()); /* INTL: Native. */ - Tcl_AppendResult(interp, "%%For: ", - (pwPtr != NULL) ? pwPtr->pw_gecos : "Unknown", "\n", NULL); + Tcl_AppendPrintfToObj(psObj, + "%%%%For: %s\n", (pwPtr ? pwPtr->pw_gecos : "Unknown")); endpwent(); } #endif /* HAVE_PW_GECOS */ - Tcl_AppendResult(interp, "%%Title: Window ", Tk_PathName(tkwin), "\n", - NULL); + Tcl_AppendPrintfToObj(psObj, + "%%%%Title: Window %s\n", Tk_PathName(tkwin)); time(&now); - Tcl_AppendResult(interp, "%%CreationDate: ", - ctime(&now), NULL); /* INTL: Native. */ + Tcl_AppendPrintfToObj(psObj, + "%%%%CreationDate: %s", ctime(&now)); /* INTL: Native. */ if (!psInfo.rotate) { - sprintf(string, "%d %d %d %d", + Tcl_AppendPrintfToObj(psObj, + "%%%%BoundingBox: %d %d %d %d\n", (int) (psInfo.pageX + psInfo.scale*deltaX), (int) (psInfo.pageY + psInfo.scale*deltaY), (int) (psInfo.pageX + psInfo.scale*(deltaX + psInfo.width) @@ -429,51 +462,60 @@ TkCanvPostscriptCmd( (int) (psInfo.pageY + psInfo.scale*(deltaY + psInfo.height) + 1.0)); } else { - sprintf(string, "%d %d %d %d", + Tcl_AppendPrintfToObj(psObj, + "%%%%BoundingBox: %d %d %d %d\n", (int) (psInfo.pageX - psInfo.scale*(deltaY+psInfo.height)), (int) (psInfo.pageY + psInfo.scale*deltaX), (int) (psInfo.pageX - psInfo.scale*deltaY + 1.0), (int) (psInfo.pageY + psInfo.scale*(deltaX + psInfo.width) + 1.0)); } - Tcl_AppendResult(interp, "%%BoundingBox: ", string, "\n", NULL); - Tcl_AppendResult(interp, "%%Pages: 1\n", - "%%DocumentData: Clean7Bit\n", NULL); - Tcl_AppendResult(interp, "%%Orientation: ", - psInfo.rotate ? "Landscape\n" : "Portrait\n", NULL); - p = "%%DocumentNeededResources: font "; + Tcl_AppendPrintfToObj(psObj, + "%%%%Pages: 1\n" + "%%%%DocumentData: Clean7Bit\n" + "%%%%Orientation: %s\n", + psInfo.rotate ? "Landscape" : "Portrait"); + p = "%%%%DocumentNeededResources: font %s\n"; for (hPtr = Tcl_FirstHashEntry(&psInfo.fontTable, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - Tcl_AppendResult(interp, p, - Tcl_GetHashKey(&psInfo.fontTable, hPtr), "\n", NULL); - p = "%%+ font "; + Tcl_AppendPrintfToObj(psObj, p, + Tcl_GetHashKey(&psInfo.fontTable, hPtr)); + p = "%%%%+ font %s\n"; } - Tcl_AppendResult(interp, "%%EndComments\n\n", NULL); + Tcl_AppendToObj(psObj, "%%EndComments\n\n", -1); /* * Insert the prolog */ - Tcl_AppendResult(interp, Tcl_GetVar(interp,"::tk::ps_preamable", - TCL_GLOBAL_ONLY), NULL); + Tcl_AppendObjToObj(psObj, preambleObj); if (psInfo.chan != NULL) { - Tcl_Write(psInfo.chan, Tcl_GetStringResult(interp), -1); - Tcl_ResetResult(canvasPtr->interp); + if (Tcl_WriteObj(psInfo.chan, psObj) == -1) { + channelWriteFailed: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "problem writing postscript data to channel: %s", + Tcl_PosixError(interp))); + result = TCL_ERROR; + goto cleanup; + } + Tcl_DecrRefCount(psObj); + psObj = Tcl_NewObj(); } /* * Document setup: set the color level and include fonts. */ - sprintf(string, "/CL %d def\n", psInfo.colorLevel); - Tcl_AppendResult(interp, "%%BeginSetup\n", string, NULL); + Tcl_AppendPrintfToObj(psObj, + "%%%%BeginSetup\n/CL %d def\n", psInfo.colorLevel); for (hPtr = Tcl_FirstHashEntry(&psInfo.fontTable, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - Tcl_AppendResult(interp, "%%IncludeResource: font ", - Tcl_GetHashKey(&psInfo.fontTable, hPtr), "\n", NULL); + Tcl_AppendPrintfToObj(psObj, + "%%%%IncludeResource: font %s\n", + (char *) Tcl_GetHashKey(&psInfo.fontTable, hPtr)); } - Tcl_AppendResult(interp, "%%EndSetup\n\n", NULL); + Tcl_AppendToObj(psObj, "%%EndSetup\n\n", -1); /* * Page setup: move to page positioning point, rotate if needed, set @@ -481,18 +523,19 @@ TkCanvPostscriptCmd( * region. */ - Tcl_AppendResult(interp, "%%Page: 1 1\n", "save\n", NULL); - sprintf(string, "%.1f %.1f translate\n", psInfo.pageX, psInfo.pageY); - Tcl_AppendResult(interp, string, NULL); + Tcl_AppendToObj(psObj, "%%Page: 1 1\nsave\n", -1); + Tcl_AppendPrintfToObj(psObj, + "%.1f %.1f translate\n", psInfo.pageX, psInfo.pageY); if (psInfo.rotate) { - Tcl_AppendResult(interp, "90 rotate\n", NULL); + Tcl_AppendToObj(psObj, "90 rotate\n", -1); } - sprintf(string, "%.4g %.4g scale\n", psInfo.scale, psInfo.scale); - Tcl_AppendResult(interp, string, NULL); - sprintf(string, "%d %d translate\n", deltaX - psInfo.x, deltaY); - Tcl_AppendResult(interp, string, NULL); - sprintf(string, - "%d %.15g moveto %d %.15g lineto %d %.15g lineto %d %.15g", + Tcl_AppendPrintfToObj(psObj, + "%.4g %.4g scale\n", psInfo.scale, psInfo.scale); + Tcl_AppendPrintfToObj(psObj, + "%d %d translate\n", deltaX - psInfo.x, deltaY); + Tcl_AppendPrintfToObj(psObj, + "%d %.15g moveto %d %.15g lineto %d %.15g lineto %d %.15g " + "lineto closepath clip newpath\n", psInfo.x, Tk_PostscriptY((double)psInfo.y, (Tk_PostscriptInfo)psInfoPtr), psInfo.x2, Tk_PostscriptY((double)psInfo.y, @@ -501,12 +544,13 @@ TkCanvPostscriptCmd( (Tk_PostscriptInfo)psInfoPtr), psInfo.x, Tk_PostscriptY((double)psInfo.y2, (Tk_PostscriptInfo)psInfoPtr)); - Tcl_AppendResult(interp, string, - " lineto closepath clip newpath\n", NULL); - } - if (psInfo.chan != NULL) { - Tcl_Write(psInfo.chan, Tcl_GetStringResult(interp), -1); - Tcl_ResetResult(canvasPtr->interp); + if (psInfo.chan != NULL) { + if (Tcl_WriteObj(psInfo.chan, psObj) == -1) { + goto channelWriteFailed; + } + Tcl_DecrRefCount(psObj); + psObj = Tcl_NewObj(); + } } /* @@ -527,21 +571,27 @@ TkCanvPostscriptCmd( if (itemPtr->state == TK_STATE_HIDDEN) { continue; } - Tcl_AppendResult(interp, "gsave\n", NULL); - result = (*itemPtr->typePtr->postscriptProc)(interp, + + Tcl_ResetResult(interp); + result = itemPtr->typePtr->postscriptProc(interp, (Tk_Canvas) canvasPtr, itemPtr, 0); if (result != TCL_OK) { - char msg[64 + TCL_INTEGER_SPACE]; - - sprintf(msg, "\n (generating Postscript for item %d)", - itemPtr->id); - Tcl_AddErrorInfo(interp, msg); + Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf( + "\n (generating Postscript for item %d)", + itemPtr->id)); goto cleanup; } - Tcl_AppendResult(interp, "grestore\n", NULL); + + Tcl_AppendToObj(psObj, "gsave\n", -1); + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); + Tcl_AppendToObj(psObj, "grestore\n", -1); + if (psInfo.chan != NULL) { - Tcl_Write(psInfo.chan, Tcl_GetStringResult(interp), -1); - Tcl_ResetResult(interp); + if (Tcl_WriteObj(psInfo.chan, psObj) == -1) { + goto channelWriteFailed; + } + Tcl_DecrRefCount(psObj); + psObj = Tcl_NewObj(); } } @@ -551,12 +601,22 @@ TkCanvPostscriptCmd( */ if (psInfo.prolog) { - Tcl_AppendResult(interp, "restore showpage\n\n", - "%%Trailer\nend\n%%EOF\n", NULL); + Tcl_AppendToObj(psObj, + "restore showpage\n\n" + "%%Trailer\n" + "end\n" + "%%EOF\n", -1); + + if (psInfo.chan != NULL) { + if (Tcl_WriteObj(psInfo.chan, psObj) == -1) { + goto channelWriteFailed; + } + } } - if (psInfo.chan != NULL) { - Tcl_Write(psInfo.chan, Tcl_GetStringResult(interp), -1); - Tcl_ResetResult(canvasPtr->interp); + + if (psInfo.chan == NULL) { + Tcl_SetObjResult(interp, psObj); + psObj = Tcl_NewObj(); } /* @@ -592,13 +652,28 @@ TkCanvPostscriptCmd( Tcl_Close(interp, psInfo.chan); } if (psInfo.channelName != NULL) { - ckfree(psInfo.channelName); + ckfree(psInfo.channelName); } Tcl_DeleteHashTable(&psInfo.fontTable); canvasPtr->psInfo = (Tk_PostscriptInfo) oldInfoPtr; + Tcl_DecrRefCount(preambleObj); + Tcl_DecrRefCount(psObj); return result; } +static inline Tcl_Obj * +GetPostscriptBuffer( + Tcl_Interp *interp) +{ + Tcl_Obj *psObj = Tcl_GetObjResult(interp); + + if (Tcl_IsShared(psObj)) { + psObj = Tcl_DuplicateObj(psObj); + Tcl_SetObjResult(interp, psObj); + } + return psObj; +} + /* *-------------------------------------------------------------- * @@ -627,9 +702,7 @@ Tk_PostscriptColor( XColor *colorPtr) /* Information about color. */ { TkPostscriptInfo *psInfoPtr = (TkPostscriptInfo *) psInfo; - int tmp; double red, green, blue; - char string[200]; if (psInfoPtr->prepass) { return TCL_OK; @@ -641,12 +714,12 @@ Tk_PostscriptColor( */ if (psInfoPtr->colorVar != NULL) { - CONST char *cmdString; - - cmdString = Tcl_GetVar2(interp, psInfoPtr->colorVar, + const char *cmdString = Tcl_GetVar2(interp, psInfoPtr->colorVar, Tk_NameOfColor(colorPtr), 0); + if (cmdString != NULL) { - Tcl_AppendResult(interp, cmdString, "\n", NULL); + Tcl_AppendPrintfToObj(GetPostscriptBuffer(interp), + "%s\n", cmdString); return TCL_OK; } } @@ -663,15 +736,12 @@ Tk_PostscriptColor( * per color, but most diplays use at least 8 bits. */ - tmp = colorPtr->red; - red = ((double) (tmp >> 8))/255.0; - tmp = colorPtr->green; - green = ((double) (tmp >> 8))/255.0; - tmp = colorPtr->blue; - blue = ((double) (tmp >> 8))/255.0; - sprintf(string, "%.3f %.3f %.3f setrgbcolor AdjustColor\n", + red = ((double) (((int) colorPtr->red) >> 8))/255.0; + green = ((double) (((int) colorPtr->green) >> 8))/255.0; + blue = ((double) (((int) colorPtr->blue) >> 8))/255.0; + Tcl_AppendPrintfToObj(GetPostscriptBuffer(interp), + "%.3f %.3f %.3f setrgbcolor AdjustColor\n", red, green, blue); - Tcl_AppendResult(interp, string, NULL); return TCL_OK; } @@ -705,9 +775,9 @@ Tk_PostscriptFont( * be printed. */ { TkPostscriptInfo *psInfoPtr = (TkPostscriptInfo *) psInfo; - char pointString[TCL_INTEGER_SPACE]; Tcl_DString ds; int i, points; + const char *fontname; /* * First, look up the font's name in the font map, if there is one. If @@ -716,35 +786,31 @@ Tk_PostscriptFont( */ if (psInfoPtr->fontVar != NULL) { - CONST char *name = Tk_NameOfFont(tkfont); + const char *name = Tk_NameOfFont(tkfont); Tcl_Obj **objv; int objc; double size; Tcl_Obj *list = Tcl_GetVar2Ex(interp, psInfoPtr->fontVar, name, 0); if (list != NULL) { - CONST char *fontname; - if (Tcl_ListObjGetElements(interp, list, &objc, &objv) != TCL_OK || objc != 2 - || Tcl_GetString(objv[0])[0]=='\0' + || (fontname = Tcl_GetString(objv[0]))[0] == '\0' + || strchr(fontname, ' ') != NULL || Tcl_GetDoubleFromObj(interp, objv[1], &size) != TCL_OK || size <= 0) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "bad font map entry for \"", name, - "\": \"", Tcl_GetString(list), "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad font map entry for \"%s\": \"%s\"", + name, Tcl_GetString(list))); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "PS", "FONTMAP", + NULL); return TCL_ERROR; } - fontname = Tcl_GetString(objv[0]); - sprintf(pointString, "%d", (int)size); - - Tcl_AppendResult(interp, "/", fontname, " findfont ", - pointString, " scalefont ", NULL); - if (strncasecmp(fontname, "Symbol", 7) != 0) { - Tcl_AppendResult(interp, "ISOEncode ", NULL); - } - Tcl_AppendResult(interp, "setfont\n", NULL); + Tcl_AppendPrintfToObj(GetPostscriptBuffer(interp), + "/%s findfont %d scalefont%s setfont\n", + fontname, (int) size, + strncasecmp(fontname, "Symbol", 7) ? " ISOEncode" : ""); Tcl_CreateHashEntry(&psInfoPtr->fontTable, fontname, &i); return TCL_OK; } @@ -756,13 +822,11 @@ Tk_PostscriptFont( Tcl_DStringInit(&ds); points = Tk_PostscriptFontName(tkfont, &ds); - sprintf(pointString, "%d", TkFontGetPoints(psInfoPtr->tkwin, points)); - Tcl_AppendResult(interp, "/", Tcl_DStringValue(&ds), " findfont ", - pointString, " scalefont ", NULL); - if (strncasecmp(Tcl_DStringValue(&ds), "Symbol", 7) != 0) { - Tcl_AppendResult(interp, "ISOEncode ", NULL); - } - Tcl_AppendResult(interp, "setfont\n", NULL); + fontname = Tcl_DStringValue(&ds); + Tcl_AppendPrintfToObj(GetPostscriptBuffer(interp), + "/%s findfont %d scalefont%s setfont\n", + fontname, (int)(TkFontGetPoints(psInfoPtr->tkwin, points) + 0.5), + strncasecmp(fontname, "Symbol", 7) ? " ISOEncode" : ""); Tcl_CreateHashEntry(&psInfoPtr->fontTable, Tcl_DStringValue(&ds), &i); Tcl_DStringFree(&ds); @@ -800,18 +864,32 @@ Tk_PostscriptBitmap( int width, int height) /* Height of rectangular region. */ { TkPostscriptInfo *psInfoPtr = (TkPostscriptInfo *) psInfo; + + if (psInfoPtr->prepass) { + return TCL_OK; + } + + PostscriptBitmap(tkwin, bitmap, startX, startY, width, height, + GetPostscriptBuffer(interp)); + return TCL_OK; +} + +static void +PostscriptBitmap( + Tk_Window tkwin, + Pixmap bitmap, /* Bitmap for which to generate Postscript. */ + int startX, int startY, /* Coordinates of upper-left corner of + * rectangular region to output. */ + int width, int height, /* Height of rectangular region. */ + Tcl_Obj *psObj) /* Where to append the postscript. */ +{ XImage *imagePtr; int charsInLine, x, y, lastX, lastY, value, mask; unsigned int totalWidth, totalHeight; - char string[100]; Window dummyRoot; int dummyX, dummyY; unsigned dummyBorderwidth, dummyDepth; - if (psInfoPtr->prepass) { - return TCL_OK; - } - /* * The following call should probably be a call to Tk_SizeOfBitmap * instead, but it seems that we are occasionally invoked by custom item @@ -825,7 +903,8 @@ Tk_PostscriptBitmap( (unsigned int *) &totalHeight, &dummyBorderwidth, &dummyDepth); imagePtr = XGetImage(Tk_Display(tkwin), bitmap, 0, 0, totalWidth, totalHeight, 1, XYPixmap); - Tcl_AppendResult(interp, "<", NULL); + + Tcl_AppendToObj(psObj, "<", -1); mask = 0x80; value = 0; charsInLine = 0; @@ -838,28 +917,26 @@ Tk_PostscriptBitmap( } mask >>= 1; if (mask == 0) { - sprintf(string, "%02x", value); - Tcl_AppendResult(interp, string, NULL); + Tcl_AppendPrintfToObj(psObj, "%02x", value); mask = 0x80; value = 0; charsInLine += 2; if (charsInLine >= 60) { - Tcl_AppendResult(interp, "\n", NULL); + Tcl_AppendToObj(psObj, "\n", -1); charsInLine = 0; } } } if (mask != 0x80) { - sprintf(string, "%02x", value); - Tcl_AppendResult(interp, string, NULL); + Tcl_AppendPrintfToObj(psObj, "%02x", value); mask = 0x80; value = 0; charsInLine += 2; } } - Tcl_AppendResult(interp, ">", NULL); + Tcl_AppendToObj(psObj, ">", -1); + XDestroyImage(imagePtr); - return TCL_OK; } /* @@ -894,10 +971,10 @@ Tk_PostscriptStipple( { TkPostscriptInfo *psInfoPtr = (TkPostscriptInfo *) psInfo; int width, height; - char string[TCL_INTEGER_SPACE * 2]; Window dummyRoot; int dummyX, dummyY; unsigned dummyBorderwidth, dummyDepth; + Tcl_Obj *psObj; if (psInfoPtr->prepass) { return TCL_OK; @@ -914,13 +991,11 @@ Tk_PostscriptStipple( XGetGeometry(Tk_Display(tkwin), bitmap, &dummyRoot, (int *) &dummyX, (int *) &dummyY, (unsigned *) &width, (unsigned *) &height, &dummyBorderwidth, &dummyDepth); - sprintf(string, "%d %d ", width, height); - Tcl_AppendResult(interp, string, NULL); - if (Tk_PostscriptBitmap(interp, tkwin, psInfo, bitmap, 0, 0, - width, height) != TCL_OK) { - return TCL_ERROR; - } - Tcl_AppendResult(interp, " StippleFill\n", NULL); + + psObj = GetPostscriptBuffer(interp); + Tcl_AppendPrintfToObj(psObj, "%d %d ", width, height); + PostscriptBitmap(tkwin, bitmap, 0, 0, width, height, psObj); + Tcl_AppendToObj(psObj, " StippleFill\n", -1); return TCL_OK; } @@ -980,19 +1055,19 @@ Tk_PostscriptPath( int numPoints) /* Number of points at *coordPtr. */ { TkPostscriptInfo *psInfoPtr = (TkPostscriptInfo *) psInfo; - char buffer[200]; + Tcl_Obj *psObj; if (psInfoPtr->prepass) { return; } - sprintf(buffer, "%.15g %.15g moveto\n", coordPtr[0], - Tk_PostscriptY(coordPtr[1], psInfo)); - Tcl_AppendResult(interp, buffer, NULL); + + psObj = GetPostscriptBuffer(interp); + Tcl_AppendPrintfToObj(psObj, "%.15g %.15g moveto\n", + coordPtr[0], Tk_PostscriptY(coordPtr[1], psInfo)); for (numPoints--, coordPtr += 2; numPoints > 0; numPoints--, coordPtr += 2) { - sprintf(buffer, "%.15g %.15g lineto\n", coordPtr[0], - Tk_PostscriptY(coordPtr[1], psInfo)); - Tcl_AppendResult(interp, buffer, NULL); + Tcl_AppendPrintfToObj(psObj, "%.15g %.15g lineto\n", + coordPtr[0], Tk_PostscriptY(coordPtr[1], psInfo)); } } @@ -1063,7 +1138,8 @@ GetPostscriptPoints( return TCL_OK; error: - Tcl_AppendResult(interp, "bad distance \"", string, "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad distance \"%s\"", string)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "PS", "POINTS", NULL); return TCL_ERROR; } @@ -1092,7 +1168,7 @@ GetPostscriptPoints( *-------------------------------------------------------------- */ -#ifdef WIN32 +#ifdef _WIN32 #include <windows.h> /* @@ -1102,15 +1178,15 @@ GetPostscriptPoints( #define GetBValue(rgb) ((BYTE)((rgb)>>16)) */ -#else /* !WIN32 */ +#else /* !_WIN32 */ #define GetRValue(rgb) ((rgb & cdata->red_mask) >> cdata->red_shift) #define GetGValue(rgb) ((rgb & cdata->green_mask) >> cdata->green_shift) #define GetBValue(rgb) ((rgb & cdata->blue_mask) >> cdata->blue_shift) -#endif /* WIN32 */ +#endif /* _WIN32 */ -#if defined(WIN32) || defined(MAC_OSX_TK) +#if defined(_WIN32) || defined(MAC_OSX_TK) static void TkImageGetColor( TkColormapData *cdata, /* Colormap data */ @@ -1122,7 +1198,7 @@ TkImageGetColor( *green = (double) GetGValue(pixel) / 255.0; *blue = (double) GetBValue(pixel) / 255.0; } -#else /* ! (WIN32 || MAC_OSX_TK) */ +#else /* ! (_WIN32 || MAC_OSX_TK) */ static void TkImageGetColor( TkColormapData *cdata, /* Colormap data */ @@ -1144,7 +1220,7 @@ TkImageGetColor( *blue = cdata->colors[pixel].blue / 65535.0; } } -#endif /* WIN32 || MAC_OSX_TK */ +#endif /* _WIN32 || MAC_OSX_TK */ /* *-------------------------------------------------------------- @@ -1177,15 +1253,15 @@ TkPostscriptImage( int width, int height) /* Width and height of area */ { TkPostscriptInfo *psInfoPtr = (TkPostscriptInfo *) psInfo; - char buffer[256]; int xx, yy, band, maxRows; double red, green, blue; - int bytesPerLine=0, maxWidth=0; + int bytesPerLine = 0, maxWidth = 0; int level = psInfoPtr->colorLevel; Colormap cmap; int i, ncolors; Visual *visual; TkColormapData cdata; + Tcl_Obj *psObj; if (psInfoPtr->prepass) { return TCL_OK; @@ -1200,7 +1276,7 @@ TkPostscriptImage( */ ncolors = visual->map_entries; - cdata.colors = (XColor *) ckalloc(sizeof(XColor) * ncolors); + cdata.colors = ckalloc(sizeof(XColor) * ncolors); cdata.ncolors = ncolors; if (visual->class == DirectColor || visual->class == TrueColor) { @@ -1249,7 +1325,7 @@ TkPostscriptImage( * monochrome screen, use gray or monochrome mode instead. */ - if (!cdata.color && level == 2) { + if (!cdata.color && level >= 2) { level = 1; } @@ -1266,20 +1342,21 @@ TkPostscriptImage( switch (level) { case 0: bytesPerLine = (width + 7) / 8; maxWidth = 240000; break; case 1: bytesPerLine = width; maxWidth = 60000; break; - case 2: bytesPerLine = 3 * width; maxWidth = 20000; break; + default: bytesPerLine = 3 * width; maxWidth = 20000; break; } if (bytesPerLine > 60000) { Tcl_ResetResult(interp); - sprintf(buffer, - "Can't generate Postscript for images more than %d pixels wide", - maxWidth); - Tcl_AppendResult(interp, buffer, NULL); - ckfree((char *) cdata.colors); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't generate Postscript for images more than %d pixels wide", + maxWidth)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "PS", "MEMLIMIT", NULL); + ckfree(cdata.colors); return TCL_ERROR; } maxRows = 60000 / bytesPerLine; + psObj = GetPostscriptBuffer(interp); for (band = height-1; band >= 0; band -= maxRows) { int rows = (band >= maxRows) ? maxRows : band + 1; @@ -1287,16 +1364,13 @@ TkPostscriptImage( switch (level) { case 0: - sprintf(buffer, "%d %d 1 matrix {\n<", width, rows); - Tcl_AppendResult(interp, buffer, NULL); + Tcl_AppendPrintfToObj(psObj, "%d %d 1 matrix {\n<", width, rows); break; case 1: - sprintf(buffer, "%d %d 8 matrix {\n<", width, rows); - Tcl_AppendResult(interp, buffer, NULL); + Tcl_AppendPrintfToObj(psObj, "%d %d 8 matrix {\n<", width, rows); break; - case 2: - sprintf(buffer, "%d %d 8 matrix {\n<", width, rows); - Tcl_AppendResult(interp, buffer, NULL); + default: + Tcl_AppendPrintfToObj(psObj, "%d %d 8 matrix {\n<", width, rows); break; } for (yy = band; yy > band - rows; yy--) { @@ -1318,22 +1392,20 @@ TkPostscriptImage( } mask >>= 1; if (mask == 0) { - sprintf(buffer, "%02X", data); - Tcl_AppendResult(interp, buffer, NULL); + Tcl_AppendPrintfToObj(psObj, "%02X", data); lineLen += 2; if (lineLen > 60) { lineLen = 0; - Tcl_AppendResult(interp, "\n", NULL); + Tcl_AppendToObj(psObj, "\n", -1); } - mask=0x80; - data=0x00; + mask = 0x80; + data = 0x00; } } if ((width % 8) != 0) { - sprintf(buffer, "%02X", data); - Tcl_AppendResult(interp, buffer, NULL); - mask=0x80; - data=0x00; + Tcl_AppendPrintfToObj(psObj, "%02X", data); + mask = 0x80; + data = 0x00; } break; } @@ -1346,17 +1418,17 @@ TkPostscriptImage( for (xx = x; xx < x+width; xx ++) { TkImageGetColor(&cdata, XGetPixel(ximage, xx, yy), &red, &green, &blue); - sprintf(buffer, "%02X", (int) floor(0.5 + 255.0 * + Tcl_AppendPrintfToObj(psObj, "%02X", + (int) floor(0.5 + 255.0 * (0.30 * red + 0.59 * green + 0.11 * blue))); - Tcl_AppendResult(interp, buffer, NULL); lineLen += 2; if (lineLen > 60) { lineLen = 0; - Tcl_AppendResult(interp, "\n", NULL); + Tcl_AppendToObj(psObj, "\n", -1); } } break; - case 2: + default: /* * Finally, color mode. Here, just output the red, green, and * blue values directly. @@ -1365,15 +1437,14 @@ TkPostscriptImage( for (xx = x; xx < x+width; xx++) { TkImageGetColor(&cdata, XGetPixel(ximage, xx, yy), &red, &green, &blue); - sprintf(buffer, "%02X%02X%02X", + Tcl_AppendPrintfToObj(psObj, "%02X%02X%02X", (int) floor(0.5 + 255.0 * red), (int) floor(0.5 + 255.0 * green), (int) floor(0.5 + 255.0 * blue)); - Tcl_AppendResult(interp, buffer, NULL); lineLen += 6; if (lineLen > 60) { lineLen = 0; - Tcl_AppendResult(interp, "\n", NULL); + Tcl_AppendToObj(psObj, "\n", -1); } } break; @@ -1381,15 +1452,13 @@ TkPostscriptImage( } switch (level) { case 0: case 1: - sprintf(buffer, ">\n} image\n"); break; - case 2: - sprintf(buffer, ">\n} false 3 colorimage\n"); break; + Tcl_AppendToObj(psObj, ">\n} image\n", -1); break; + default: + Tcl_AppendToObj(psObj, ">\n} false 3 colorimage\n", -1); break; } - Tcl_AppendResult(interp, buffer, NULL); - sprintf(buffer, "0 %d translate\n", rows); - Tcl_AppendResult(interp, buffer, NULL); + Tcl_AppendPrintfToObj(psObj, "0 %d translate\n", rows); } - ckfree((char *) cdata.colors); + ckfree(cdata.colors); return TCL_OK; } @@ -1423,153 +1492,32 @@ Tk_PostscriptPhoto( { TkPostscriptInfo *psInfoPtr = (TkPostscriptInfo *) psInfo; int colorLevel = psInfoPtr->colorLevel; - static int codeIncluded = 0; - + const char *displayOperation, *decode; unsigned char *pixelPtr; - char buffer[256], cspace[40], decode[40]; - int bpc; - int xx, yy, lineLen; + int bpc, xx, yy, lineLen, alpha; float red, green, blue; - int alpha; - int bytesPerLine=0, maxWidth=0; - + int bytesPerLine = 0, maxWidth = 0; unsigned char opaque = 255; unsigned char *alphaPtr; int alphaOffset, alphaPitch, alphaIncr; + Tcl_Obj *psObj; if (psInfoPtr->prepass) { - codeIncluded = 0; return TCL_OK; } - /* - * Define the "TkPhoto" function, which is a modified version of the - * original "transparentimage" function posted by ian@five-d.com (Ian - * Kemmish) to comp.lang.postscript. For a monochrome colorLevel this is a - * slightly different version that uses the imagemask command instead of - * image. - */ - - if (!codeIncluded && (colorLevel != 0)) { + if (colorLevel != 0) { /* * Color and gray-scale code. */ - codeIncluded = !0; - Tcl_AppendResult(interp, - "/TkPhoto { \n", - " gsave \n", - " 32 dict begin \n", - " /tinteger exch def \n", - " /transparent 1 string def \n", - " transparent 0 tinteger put \n", - " /olddict exch def \n", - " olddict /DataSource get dup type /filetype ne { \n", - " olddict /DataSource 3 -1 roll \n", - " 0 () /SubFileDecode filter put \n", - " } { \n", - " pop \n", - " } ifelse \n", - " /newdict olddict maxlength dict def \n", - " olddict newdict copy pop \n", - " /w newdict /Width get def \n", - " /crpp newdict /Decode get length 2 idiv def \n", - " /str w string def \n", - " /pix w crpp mul string def \n", - " /substrlen 2 w log 2 log div floor exp cvi def \n", - " /substrs [ \n", - " { \n", - " substrlen string \n", - " 0 1 substrlen 1 sub { \n", - " 1 index exch tinteger put \n", - " } for \n", - " /substrlen substrlen 2 idiv def \n", - " substrlen 0 eq {exit} if \n", - " } loop \n", - " ] def \n", - " /h newdict /Height get def \n", - " 1 w div 1 h div matrix scale \n", - " olddict /ImageMatrix get exch matrix concatmatrix \n", - " matrix invertmatrix concat \n", - " newdict /Height 1 put \n", - " newdict /DataSource pix put \n", - " /mat [w 0 0 h 0 0] def \n", - " newdict /ImageMatrix mat put \n", - " 0 1 h 1 sub { \n", - " mat 5 3 -1 roll neg put \n", - " olddict /DataSource get str readstring pop pop \n", - " /tail str def \n", - " /x 0 def \n", - " olddict /DataSource get pix readstring pop pop \n", - " { \n", - " tail transparent search dup /done exch not def \n", - " {exch pop exch pop} if \n", - " /w1 exch length def \n", - " w1 0 ne { \n", - " newdict /DataSource ", - " pix x crpp mul w1 crpp mul getinterval put \n", - " newdict /Width w1 put \n", - " mat 4 x neg put \n", - " /x x w1 add def \n", - " newdict image \n", - " /tail tail w1 tail length w1 sub getinterval def \n", - " } if \n", - " done {exit} if \n", - " tail substrs { \n", - " anchorsearch {pop} if \n", - " } forall \n", - " /tail exch def \n", - " tail length 0 eq {exit} if \n", - " /x w tail length sub def \n", - " } loop \n", - " } for \n", - " end \n", - " grestore \n", - "} bind def \n\n\n", NULL); - } else if (!codeIncluded && (colorLevel == 0)) { + displayOperation = "TkPhotoColor"; + } else { /* * Monochrome-only code */ - codeIncluded = !0; - Tcl_AppendResult(interp, - "/TkPhoto { \n", - " gsave \n", - " 32 dict begin \n", - " /dummyInteger exch def \n", - " /olddict exch def \n", - " olddict /DataSource get dup type /filetype ne { \n", - " olddict /DataSource 3 -1 roll \n", - " 0 () /SubFileDecode filter put \n", - " } { \n", - " pop \n", - " } ifelse \n", - " /newdict olddict maxlength dict def \n", - " olddict newdict copy pop \n", - " /w newdict /Width get def \n", - " /pix w 7 add 8 idiv string def \n", - " /h newdict /Height get def \n", - " 1 w div 1 h div matrix scale \n", - " olddict /ImageMatrix get exch matrix concatmatrix \n", - " matrix invertmatrix concat \n", - " newdict /Height 1 put \n", - " newdict /DataSource pix put \n", - " /mat [w 0 0 h 0 0] def \n", - " newdict /ImageMatrix mat put \n", - " 0 1 h 1 sub { \n", - " mat 5 3 -1 roll neg put \n", - " 0.000 0.000 0.000 setrgbcolor \n", - " olddict /DataSource get pix readstring pop pop \n", - " newdict /DataSource pix put \n", - " newdict imagemask \n", - " 1.000 1.000 1.000 setrgbcolor \n", - " olddict /DataSource get pix readstring pop pop \n", - " newdict /DataSource pix put \n", - " newdict imagemask \n", - " } for \n", - " end \n", - " grestore \n", - "} bind def \n\n\n", NULL); + displayOperation = "TkPhotoMono"; } /* @@ -1581,14 +1529,14 @@ Tk_PostscriptPhoto( switch (colorLevel) { case 0: bytesPerLine = (width + 7) / 8; maxWidth = 240000; break; case 1: bytesPerLine = width; maxWidth = 60000; break; - case 2: bytesPerLine = 3 * width; maxWidth = 20000; break; + default: bytesPerLine = 3 * width; maxWidth = 20000; break; } if (bytesPerLine > 60000) { Tcl_ResetResult(interp); - sprintf(buffer, - "Can't generate Postscript for images more than %d pixels wide", - maxWidth); - Tcl_AppendResult(interp, buffer, NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't generate Postscript for images more than %d pixels wide", + maxWidth)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "PS", "MEMLIMIT", NULL); return TCL_ERROR; } @@ -1596,35 +1544,32 @@ Tk_PostscriptPhoto( * Set up the postscript code except for the image-data stream. */ + psObj = GetPostscriptBuffer(interp); switch (colorLevel) { case 0: - strcpy(cspace, "/DeviceGray"); - strcpy(decode, "[1 0]"); + Tcl_AppendToObj(psObj, "/DeviceGray setcolorspace\n\n", -1); + decode = "1 0"; bpc = 1; break; case 1: - strcpy(cspace, "/DeviceGray"); - strcpy(decode, "[0 1]"); + Tcl_AppendToObj(psObj, "/DeviceGray setcolorspace\n\n", -1); + decode = "0 1"; bpc = 8; break; default: - strcpy(cspace, "/DeviceRGB"); - strcpy(decode, "[0 1 0 1 0 1]"); + Tcl_AppendToObj(psObj, "/DeviceRGB setcolorspace\n\n", -1); + decode = "0 1 0 1 0 1"; bpc = 8; break; } - - Tcl_AppendResult(interp, cspace, " setcolorspace\n\n", NULL); - - sprintf(buffer, " /Width %d\n /Height %d\n /BitsPerComponent %d\n", - width, height, bpc); - Tcl_AppendResult(interp, "<<\n /ImageType 1\n", buffer, - " /DataSource currentfile /ASCIIHexDecode filter\n", NULL); - - sprintf(buffer, " /ImageMatrix [1 0 0 -1 0 %d]\n", height); - Tcl_AppendResult(interp, buffer, " /Decode ", decode, - "\n>>\n1 TkPhoto\n", NULL); + Tcl_AppendPrintfToObj(psObj, + "<<\n /ImageType 1\n" + " /Width %d\n /Height %d\n /BitsPerComponent %d\n" + " /DataSource currentfile\n /ASCIIHexDecode filter\n" + " /ImageMatrix [1 0 0 -1 0 %d]\n /Decode [%s]\n>>\n" + "1 %s\n", + width, height, bpc, height, decode, displayOperation); /* * Check the PhotoImageBlock information. We assume that: @@ -1684,20 +1629,18 @@ Tk_PostscriptPhoto( } mask >>= 1; if (mask == 0) { - sprintf(buffer, "%02X", data); - Tcl_AppendResult(interp, buffer, NULL); + Tcl_AppendPrintfToObj(psObj, "%02X", data); lineLen += 2; if (lineLen >= 60) { lineLen = 0; - Tcl_AppendResult(interp, "\n", NULL); + Tcl_AppendToObj(psObj, "\n", -1); } mask = 0x80; data = 0x00; } } if ((width % 8) != 0) { - sprintf(buffer, "%02X", data); - Tcl_AppendResult(interp, buffer, NULL); + Tcl_AppendPrintfToObj(psObj, "%02X", data); mask = 0x80; data = 0x00; } @@ -1725,20 +1668,18 @@ Tk_PostscriptPhoto( } mask >>= 1; if (mask == 0) { - sprintf(buffer, "%02X", data); - Tcl_AppendResult(interp, buffer, NULL); + Tcl_AppendPrintfToObj(psObj, "%02X", data); lineLen += 2; if (lineLen >= 60) { lineLen = 0; - Tcl_AppendResult(interp, "\n", NULL); + Tcl_AppendToObj(psObj, "\n", -1); } mask = 0x80; data = 0x00; } } if ((width % 8) != 0) { - sprintf(buffer, "%02X", data); - Tcl_AppendResult(interp, buffer, NULL); + Tcl_AppendPrintfToObj(psObj, "%02X", data); mask = 0x80; data = 0x00; } @@ -1753,12 +1694,11 @@ Tk_PostscriptPhoto( for (xx = 0; xx < width; xx ++) { alpha = *(alphaPtr + (yy * alphaPitch) + (xx * alphaIncr) + alphaOffset); - sprintf(buffer, "%02X", alpha | 0x01); - Tcl_AppendResult(interp, buffer, NULL); + Tcl_AppendPrintfToObj(psObj, "%02X", alpha | 0x01); lineLen += 2; if (lineLen >= 60) { lineLen = 0; - Tcl_AppendResult(interp, "\n", NULL); + Tcl_AppendToObj(psObj, "\n", -1); } } @@ -1775,13 +1715,12 @@ Tk_PostscriptPhoto( green = pixelPtr[blockPtr->offset[1]]; blue = pixelPtr[blockPtr->offset[2]]; - sprintf(buffer, "%02X", (int) floor(0.5 + + Tcl_AppendPrintfToObj(psObj, "%02X", (int) floor(0.5 + ( 0.3086 * red + 0.6094 * green + 0.0820 * blue))); - Tcl_AppendResult(interp, buffer, NULL); lineLen += 2; if (lineLen >= 60) { lineLen = 0; - Tcl_AppendResult(interp, "\n", NULL); + Tcl_AppendToObj(psObj, "\n", -1); } } break; @@ -1795,12 +1734,11 @@ Tk_PostscriptPhoto( for (xx = 0; xx < width; xx ++) { alpha = *(alphaPtr + (yy * alphaPitch) + (xx * alphaIncr) + alphaOffset); - sprintf(buffer, "%02X", alpha | 0x01); - Tcl_AppendResult(interp, buffer, NULL); + Tcl_AppendPrintfToObj(psObj, "%02X", alpha | 0x01); lineLen += 2; if (lineLen >= 60) { lineLen = 0; - Tcl_AppendResult(interp, "\n", NULL); + Tcl_AppendToObj(psObj, "\n", -1); } } @@ -1813,22 +1751,25 @@ Tk_PostscriptPhoto( pixelPtr = blockPtr->pixelPtr + (yy * blockPtr->pitch) + (xx * blockPtr->pixelSize); - sprintf(buffer, "%02X%02X%02X", + Tcl_AppendPrintfToObj(psObj, "%02X%02X%02X", pixelPtr[blockPtr->offset[0]], pixelPtr[blockPtr->offset[1]], pixelPtr[blockPtr->offset[2]]); - Tcl_AppendResult(interp, buffer, NULL); lineLen += 6; if (lineLen >= 60) { lineLen = 0; - Tcl_AppendResult(interp, "\n", NULL); + Tcl_AppendToObj(psObj, "\n", -1); } } break; } } - Tcl_AppendResult(interp, ">\n", NULL); + /* + * The end-of-data marker. + */ + + Tcl_AppendToObj(psObj, ">\n", -1); return TCL_OK; } diff --git a/generic/tkCanvText.c b/generic/tkCanvText.c index 717184a..279e548 100644 --- a/generic/tkCanvText.c +++ b/generic/tkCanvText.c @@ -10,7 +10,6 @@ * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ -#include <stdio.h> #include "tkInt.h" #include "tkCanvas.h" #include "default.h" @@ -55,6 +54,8 @@ typedef struct TextItem { * means no word-wrap. */ int underline; /* Index of character to put underline beneath * or -1 for no underlining. */ + double angle; /* What angle, in degrees, to draw the text + * at. */ /* * Fields whose values are derived from the current values of the @@ -64,70 +65,69 @@ typedef struct TextItem { int numChars; /* Length of text in characters. */ int numBytes; /* Length of text in bytes. */ Tk_TextLayout textLayout; /* Cached text layout information. */ - int leftEdge; /* Pixel location of the left edge of the text - * item; where the left border of the text - * layout is drawn. */ - int rightEdge; /* Pixel just to right of right edge of area - * of text item. Used for selecting up to end - * of line. */ + int actualWidth; /* Width of text as computed. Used to make + * selections of wrapped text display + * right. */ + double drawOrigin[2]; /* Where we start drawing from. */ GC gc; /* Graphics context for drawing text. */ GC selTextGC; /* Graphics context for selected text. */ GC cursorOffGC; /* If not None, this gives a graphics context * to use to draw the insertion cursor when * it's off. Used if the selection and * insertion cursor colors are the same. */ + double sine; /* Sine of angle field. */ + double cosine; /* Cosine of angle field. */ } TextItem; /* * Information used for parsing configuration specs: */ -static Tk_CustomOption stateOption = { - (Tk_OptionParseProc *) TkStateParseProc, - TkStatePrintProc, (ClientData) 2 +static const Tk_CustomOption stateOption = { + TkStateParseProc, TkStatePrintProc, INT2PTR(2) }; -static Tk_CustomOption tagsOption = { - (Tk_OptionParseProc *) Tk_CanvasTagsParseProc, - Tk_CanvasTagsPrintProc, (ClientData) NULL +static const Tk_CustomOption tagsOption = { + Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL }; -static Tk_CustomOption offsetOption = { - (Tk_OptionParseProc *) TkOffsetParseProc, - TkOffsetPrintProc, (ClientData) (TK_OFFSET_RELATIVE) +static const Tk_CustomOption offsetOption = { + TkOffsetParseProc, TkOffsetPrintProc, INT2PTR(TK_OFFSET_RELATIVE) }; -static Tk_ConfigSpec configSpecs[] = { +static const Tk_ConfigSpec configSpecs[] = { {TK_CONFIG_COLOR, "-activefill", NULL, NULL, - NULL, Tk_Offset(TextItem, activeColor), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(TextItem, activeColor), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_BITMAP, "-activestipple", NULL, NULL, - NULL, Tk_Offset(TextItem, activeStipple), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(TextItem, activeStipple), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_ANCHOR, "-anchor", NULL, NULL, - "center", Tk_Offset(TextItem, anchor), TK_CONFIG_DONT_SET_DEFAULT}, + "center", Tk_Offset(TextItem, anchor), TK_CONFIG_DONT_SET_DEFAULT, NULL}, + {TK_CONFIG_DOUBLE, "-angle", NULL, NULL, + "0.0", Tk_Offset(TextItem, angle), TK_CONFIG_DONT_SET_DEFAULT, NULL}, {TK_CONFIG_COLOR, "-disabledfill", NULL, NULL, - NULL, Tk_Offset(TextItem, disabledColor), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(TextItem, disabledColor), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_BITMAP, "-disabledstipple", NULL, NULL, - NULL, Tk_Offset(TextItem, disabledStipple), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(TextItem, disabledStipple), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_COLOR, "-fill", NULL, NULL, - "black", Tk_Offset(TextItem, color), TK_CONFIG_NULL_OK}, + "black", Tk_Offset(TextItem, color), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_FONT, "-font", NULL, NULL, - DEF_CANVTEXT_FONT, Tk_Offset(TextItem, tkfont), 0}, + DEF_CANVTEXT_FONT, Tk_Offset(TextItem, tkfont), 0, NULL}, {TK_CONFIG_JUSTIFY, "-justify", NULL, NULL, - "left", Tk_Offset(TextItem, justify), TK_CONFIG_DONT_SET_DEFAULT}, + "left", Tk_Offset(TextItem, justify), TK_CONFIG_DONT_SET_DEFAULT, NULL}, {TK_CONFIG_CUSTOM, "-offset", NULL, NULL, "0,0", Tk_Offset(TextItem, tsoffset), TK_CONFIG_DONT_SET_DEFAULT, &offsetOption}, {TK_CONFIG_CUSTOM, "-state", NULL, NULL, NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption}, {TK_CONFIG_BITMAP, "-stipple", NULL, NULL, - NULL, Tk_Offset(TextItem, stipple), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(TextItem, stipple), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_CUSTOM, "-tags", NULL, NULL, NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, {TK_CONFIG_STRING, "-text", NULL, NULL, - "", Tk_Offset(TextItem, text), 0}, + "", Tk_Offset(TextItem, text), 0, NULL}, {TK_CONFIG_INT, "-underline", NULL, NULL, - "-1", Tk_Offset(TextItem, underline), 0}, + "-1", Tk_Offset(TextItem, underline), 0, NULL}, {TK_CONFIG_PIXELS, "-width", NULL, NULL, - "0", Tk_Offset(TextItem, width), TK_CONFIG_DONT_SET_DEFAULT}, - {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} + "0", Tk_Offset(TextItem, width), TK_CONFIG_DONT_SET_DEFAULT, NULL}, + {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL} }; /* @@ -137,10 +137,10 @@ static Tk_ConfigSpec configSpecs[] = { static void ComputeTextBbox(Tk_Canvas canvas, TextItem *textPtr); static int ConfigureText(Tcl_Interp *interp, Tk_Canvas canvas, Tk_Item *itemPtr, int argc, - Tcl_Obj *CONST objv[], int flags); + Tcl_Obj *const objv[], int flags); static int CreateText(Tcl_Interp *interp, Tk_Canvas canvas, struct Tk_Item *itemPtr, - int argc, Tcl_Obj *CONST objv[]); + int argc, Tcl_Obj *const objv[]); static void DeleteText(Tk_Canvas canvas, Tk_Item *itemPtr, Display *display); static void DisplayCanvText(Tk_Canvas canvas, @@ -159,11 +159,11 @@ static void SetTextCursor(Tk_Canvas canvas, Tk_Item *itemPtr, int index); static int TextCoords(Tcl_Interp *interp, Tk_Canvas canvas, Tk_Item *itemPtr, - int argc, Tcl_Obj *CONST objv[]); + int argc, Tcl_Obj *const objv[]); static void TextDeleteChars(Tk_Canvas canvas, Tk_Item *itemPtr, int first, int last); static void TextInsert(Tk_Canvas canvas, - Tk_Item *itemPtr, int beforeThis, char *string); + Tk_Item *itemPtr, int beforeThis, Tcl_Obj *obj); static int TextToArea(Tk_Canvas canvas, Tk_Item *itemPtr, double *rectPtr); static double TextToPoint(Tk_Canvas canvas, @@ -193,13 +193,16 @@ Tk_ItemType tkTextType = { TextToPostscript, /* postscriptProc */ ScaleText, /* scaleProc */ TranslateText, /* translateProc */ - (Tk_ItemIndexProc *) GetTextIndex,/* indexProc */ + GetTextIndex, /* indexProc */ SetTextCursor, /* icursorProc */ GetSelText, /* selectionProc */ TextInsert, /* insertProc */ TextDeleteChars, /* dTextProc */ NULL, /* nextPtr */ + NULL, 0, NULL, NULL }; + +#define ROUND(d) ((int) floor((d) + 0.5)) /* *-------------------------------------------------------------- @@ -226,13 +229,13 @@ CreateText( Tk_Item *itemPtr, /* Record to hold new item; header has been * initialized by caller. */ int objc, /* Number of arguments in objv. */ - Tcl_Obj *CONST objv[]) /* Arguments describing rectangle. */ + Tcl_Obj *const objv[]) /* Arguments describing rectangle. */ { TextItem *textPtr = (TextItem *) itemPtr; int i; if (objc == 0) { - Tcl_Panic("canvas did not pass any coords\n"); + Tcl_Panic("canvas did not pass any coords"); } /* @@ -259,15 +262,18 @@ CreateText( textPtr->text = NULL; textPtr->width = 0; textPtr->underline = -1; + textPtr->angle = 0.0; textPtr->numChars = 0; textPtr->numBytes = 0; textPtr->textLayout = NULL; - textPtr->leftEdge = 0; - textPtr->rightEdge = 0; + textPtr->actualWidth = 0; + textPtr->drawOrigin[0] = textPtr->drawOrigin[1] = 0.0; textPtr->gc = NULL; textPtr->selTextGC = NULL; textPtr->cursorOffGC = NULL; + textPtr->sine = 0.0; + textPtr->cosine = 1.0; /* * Process the arguments to fill in the item record. Only 1 (list) or 2 (x @@ -277,7 +283,7 @@ CreateText( if (objc == 1) { i = 1; } else { - char *arg = Tcl_GetString(objv[1]); + const char *arg = Tcl_GetString(objv[1]); i = 2; if ((arg[0] == '-') && (arg[1] >= 'a') && (arg[1] <= 'z')) { @@ -320,45 +326,44 @@ TextCoords( Tk_Item *itemPtr, /* Item whose coordinates are to be read or * modified. */ int objc, /* Number of coordinates supplied in objv. */ - Tcl_Obj *CONST objv[]) /* Array of coordinates: x1, y1, x2, y2, ... */ + Tcl_Obj *const objv[]) /* Array of coordinates: x1, y1, x2, y2, ... */ { TextItem *textPtr = (TextItem *) itemPtr; if (objc == 0) { Tcl_Obj *obj = Tcl_NewObj(); - Tcl_Obj *subobj = Tcl_NewDoubleObj(textPtr->x); + Tcl_ListObjAppendElement(interp, obj, subobj); subobj = Tcl_NewDoubleObj(textPtr->y); Tcl_ListObjAppendElement(interp, obj, subobj); Tcl_SetObjResult(interp, obj); - } else if (objc < 3) { - if (objc==1) { - if (Tcl_ListObjGetElements(interp, objv[0], &objc, - (Tcl_Obj ***) &objv) != TCL_OK) { - return TCL_ERROR; - } else if (objc != 2) { - char buf[64 + TCL_INTEGER_SPACE]; - - sprintf(buf, "wrong # coordinates: expected 2, got %d", objc); - Tcl_SetResult(interp, buf, TCL_VOLATILE); - return TCL_ERROR; - } - } - if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0], - &textPtr->x) != TCL_OK) - || (Tk_CanvasGetCoordFromObj(interp, canvas, objv[1], - &textPtr->y) != TCL_OK)) { + return TCL_OK; + } else if (objc > 2) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "wrong # coordinates: expected 0 or 2, got %d", objc)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "TEXT", NULL); + return TCL_ERROR; + } + + if (objc == 1) { + if (Tcl_ListObjGetElements(interp, objv[0], &objc, + (Tcl_Obj ***) &objv) != TCL_OK) { + return TCL_ERROR; + } else if (objc != 2) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "wrong # coordinates: expected 2, got %d", objc)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "TEXT", NULL); return TCL_ERROR; } - ComputeTextBbox(canvas, textPtr); - } else { - char buf[64 + TCL_INTEGER_SPACE]; - - sprintf(buf, "wrong # coordinates: expected 0 or 2, got %d", objc); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + } + if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0], + &textPtr->x) != TCL_OK) + || (Tk_CanvasGetCoordFromObj(interp, canvas, objv[1], + &textPtr->y) != TCL_OK)) { return TCL_ERROR; } + ComputeTextBbox(canvas, textPtr); return TCL_OK; } @@ -387,7 +392,7 @@ ConfigureText( Tk_Canvas canvas, /* Canvas containing itemPtr. */ Tk_Item *itemPtr, /* Rectangle item to reconfigure. */ int objc, /* Number of elements in objv. */ - Tcl_Obj *CONST objv[], /* Arguments describing things to configure. */ + Tcl_Obj *const objv[], /* Arguments describing things to configure. */ int flags) /* Flags to pass to Tk_ConfigureWidget. */ { TextItem *textPtr = (TextItem *) itemPtr; @@ -403,7 +408,7 @@ ConfigureText( tkwin = Tk_CanvasTkwin(canvas); if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc, - (CONST char **) objv, (char *) textPtr, flags|TK_CONFIG_OBJS)) { + (const char **) objv, (char *) textPtr, flags|TK_CONFIG_OBJS)) { return TCL_ERROR; } @@ -420,24 +425,24 @@ ConfigureText( itemPtr->redraw_flags &= ~TK_ITEM_STATE_DEPENDANT; } - if(state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + if (state == TK_STATE_NULL) { + state = Canvas(canvas)->canvas_state; } color = textPtr->color; stipple = textPtr->stipple; - if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { - if (textPtr->activeColor!=NULL) { + if (Canvas(canvas)->currentItemPtr == itemPtr) { + if (textPtr->activeColor != NULL) { color = textPtr->activeColor; } - if (textPtr->activeStipple!=None) { + if (textPtr->activeStipple != None) { stipple = textPtr->activeStipple; } - } else if (state==TK_STATE_DISABLED) { - if (textPtr->disabledColor!=NULL) { + } else if (state == TK_STATE_DISABLED) { + if (textPtr->disabledColor != NULL) { color = textPtr->disabledColor; } - if (textPtr->disabledStipple!=None) { + if (textPtr->disabledStipple != None) { stipple = textPtr->disabledStipple; } } @@ -493,7 +498,6 @@ ConfigureText( } textPtr->cursorOffGC = newGC; - /* * If the text was changed, move the selection and insertion indices to * keep them inside the item. @@ -519,6 +523,22 @@ ConfigureText( textPtr->insertPos = textPtr->numChars; } + /* + * Restrict so that 0.0 <= angle < 360.0, and then recompute the cached + * sine and cosine of the angle. Note that fmod() can produce negative + * results, and we try to avoid negative zero as well. + */ + + textPtr->angle = fmod(textPtr->angle, 360.0); + if (textPtr->angle < 0.0) { + textPtr->angle += 360.0; + } + if (textPtr->angle == 0.0) { + textPtr->angle = 0.0; + } + textPtr->sine = sin(textPtr->angle * PI/180.0); + textPtr->cosine = cos(textPtr->angle * PI/180.0); + ComputeTextBbox(canvas, textPtr); return TCL_OK; } @@ -609,11 +629,12 @@ ComputeTextBbox( TextItem *textPtr) /* Item whose bbox is to be recomputed. */ { Tk_CanvasTextInfo *textInfoPtr; - int leftX, topY, width, height, fudge; + int leftX, topY, width, height, fudge, i; Tk_State state = textPtr->header.state; + double x[4], y[4], dx[4], dy[4], sinA, cosA, tmp; - if(state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + if (state == TK_STATE_NULL) { + state = Canvas(canvas)->canvas_state; } Tk_FreeTextLayout(textPtr->textLayout); @@ -630,8 +651,11 @@ ComputeTextBbox( * bounding box for the text item. */ - leftX = (int) floor(textPtr->x + 0.5); - topY = (int) floor(textPtr->y + 0.5); + leftX = ROUND(textPtr->x); + topY = ROUND(textPtr->y); + for (i=0 ; i<4 ; i++) { + dx[i] = dy[i] = 0.0; + } switch (textPtr->anchor) { case TK_ANCHOR_NW: case TK_ANCHOR_N: @@ -642,12 +666,18 @@ ComputeTextBbox( case TK_ANCHOR_CENTER: case TK_ANCHOR_E: topY -= height / 2; + for (i=0 ; i<4 ; i++) { + dy[i] = -height / 2; + } break; case TK_ANCHOR_SW: case TK_ANCHOR_S: case TK_ANCHOR_SE: topY -= height; + for (i=0 ; i<4 ; i++) { + dy[i] = -height; + } break; } switch (textPtr->anchor) { @@ -660,17 +690,27 @@ ComputeTextBbox( case TK_ANCHOR_CENTER: case TK_ANCHOR_S: leftX -= width / 2; + for (i=0 ; i<4 ; i++) { + dx[i] = -width / 2; + } break; case TK_ANCHOR_NE: case TK_ANCHOR_E: case TK_ANCHOR_SE: leftX -= width; + for (i=0 ; i<4 ; i++) { + dx[i] = -width; + } break; } - textPtr->leftEdge = leftX; - textPtr->rightEdge = leftX + width; + textPtr->actualWidth = width; + + sinA = textPtr->sine; + cosA = textPtr->cosine; + textPtr->drawOrigin[0] = textPtr->x + dx[0]*cosA + dy[0]*sinA; + textPtr->drawOrigin[1] = textPtr->y + dy[0]*cosA - dx[0]*sinA; /* * Last of all, update the bounding box for the item. The item's bounding @@ -683,10 +723,50 @@ ComputeTextBbox( if (textInfoPtr->selBorderWidth > fudge) { fudge = textInfoPtr->selBorderWidth; } - textPtr->header.x1 = leftX - fudge; - textPtr->header.y1 = topY; - textPtr->header.x2 = leftX + width + fudge; - textPtr->header.y2 = topY + height; + + /* + * Apply the rotation before computing the bounding box. + */ + + dx[0] -= fudge; + dx[1] += width + fudge; + dx[2] += width + fudge; + dy[2] += height; + dx[3] -= fudge; + dy[3] += height; + for (i=0 ; i<4 ; i++) { + x[i] = textPtr->x + dx[i] * cosA + dy[i] * sinA; + y[i] = textPtr->y + dy[i] * cosA - dx[i] * sinA; + } + + /* + * Convert to a rectilinear bounding box. + */ + + for (i=1,tmp=x[0] ; i<4 ; i++) { + if (x[i] < tmp) { + tmp = x[i]; + } + } + textPtr->header.x1 = ROUND(tmp); + for (i=1,tmp=y[0] ; i<4 ; i++) { + if (y[i] < tmp) { + tmp = y[i]; + } + } + textPtr->header.y1 = ROUND(tmp); + for (i=1,tmp=x[0] ; i<4 ; i++) { + if (x[i] > tmp) { + tmp = x[i]; + } + } + textPtr->header.x2 = ROUND(tmp); + for (i=1,tmp=y[0] ; i<4 ; i++) { + if (y[i] > tmp) { + tmp = y[i]; + } + } + textPtr->header.y2 = ROUND(tmp); } /* @@ -726,16 +806,16 @@ DisplayCanvText( textPtr = (TextItem *) itemPtr; textInfoPtr = textPtr->textInfoPtr; - if(state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + if (state == TK_STATE_NULL) { + state = Canvas(canvas)->canvas_state; } stipple = textPtr->stipple; - if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { - if (textPtr->activeStipple!=None) { + if (Canvas(canvas)->currentItemPtr == itemPtr) { + if (textPtr->activeStipple != None) { stipple = textPtr->activeStipple; } - } else if (state==TK_STATE_DISABLED) { - if (textPtr->disabledStipple!=None) { + } else if (state == TK_STATE_DISABLED) { + if (textPtr->disabledStipple != None) { stipple = textPtr->disabledStipple; } } @@ -756,6 +836,8 @@ DisplayCanvText( selFirstChar = -1; selLastChar = 0; /* lint. */ + Tk_CanvasDrawableCoords(canvas, textPtr->drawOrigin[0], + textPtr->drawOrigin[1], &drawableX, &drawableY); if (textInfoPtr->selItemPtr == itemPtr) { selFirstChar = textInfoPtr->selectFirst; @@ -786,20 +868,30 @@ DisplayCanvText( x = xFirst; height = hFirst; for (y = yFirst ; y <= yLast; y += height) { + int dx1, dy1, dx2, dy2; + double s = textPtr->sine, c = textPtr->cosine; + XPoint points[4]; + if (y == yLast) { width = xLast + wLast - x; } else { - width = textPtr->rightEdge - textPtr->leftEdge - x; + width = textPtr->actualWidth - x; } - Tk_CanvasDrawableCoords(canvas, - (double) (textPtr->leftEdge + x - - textInfoPtr->selBorderWidth), - (double) (textPtr->header.y1 + y), - &drawableX, &drawableY); - Tk_Fill3DRectangle(Tk_CanvasTkwin(canvas), drawable, - textInfoPtr->selBorder, drawableX, drawableY, - width + 2 * textInfoPtr->selBorderWidth, - height, textInfoPtr->selBorderWidth, TK_RELIEF_RAISED); + dx1 = x - textInfoPtr->selBorderWidth; + dy1 = y; + dx2 = width + 2 * textInfoPtr->selBorderWidth; + dy2 = height; + points[0].x = (short)(drawableX + dx1*c + dy1*s); + points[0].y = (short)(drawableY + dy1*c - dx1*s); + points[1].x = (short)(drawableX + (dx1+dx2)*c + dy1*s); + points[1].y = (short)(drawableY + dy1*c - (dx1+dx2)*s); + points[2].x = (short)(drawableX + (dx1+dx2)*c + (dy1+dy2)*s); + points[2].y = (short)(drawableY + (dy1+dy2)*c - (dx1+dx2)*s); + points[3].x = (short)(drawableX + dx1*c + (dy1+dy2)*s); + points[3].y = (short)(drawableY + (dy1+dy2)*c - dx1*s); + Tk_Fill3DPolygon(Tk_CanvasTkwin(canvas), drawable, + textInfoPtr->selBorder, points, 4, + textInfoPtr->selBorderWidth, TK_RELIEF_RAISED); x = 0; } } @@ -817,18 +909,28 @@ DisplayCanvText( if ((textInfoPtr->focusItemPtr == itemPtr) && (textInfoPtr->gotFocus)) { if (Tk_CharBbox(textPtr->textLayout, textPtr->insertPos, &x, &y, NULL, &height)) { - Tk_CanvasDrawableCoords(canvas, - (double) (textPtr->leftEdge + x - - (textInfoPtr->insertWidth / 2)), - (double) (textPtr->header.y1 + y), - &drawableX, &drawableY); - Tk_SetCaretPos(Tk_CanvasTkwin(canvas), drawableX, drawableY, + int dx1, dy1, dx2, dy2; + double s = textPtr->sine, c = textPtr->cosine; + XPoint points[4]; + + dx1 = x - (textInfoPtr->insertWidth / 2); + dy1 = y; + dx2 = textInfoPtr->insertWidth; + dy2 = height; + points[0].x = (short)(drawableX + dx1*c + dy1*s); + points[0].y = (short)(drawableY + dy1*c - dx1*s); + points[1].x = (short)(drawableX + (dx1+dx2)*c + dy1*s); + points[1].y = (short)(drawableY + dy1*c - (dx1+dx2)*s); + points[2].x = (short)(drawableX + (dx1+dx2)*c + (dy1+dy2)*s); + points[2].y = (short)(drawableY + (dy1+dy2)*c - (dx1+dx2)*s); + points[3].x = (short)(drawableX + dx1*c + (dy1+dy2)*s); + points[3].y = (short)(drawableY + (dy1+dy2)*c - dx1*s); + + Tk_SetCaretPos(Tk_CanvasTkwin(canvas), points[0].x, points[0].y, height); if (textInfoPtr->cursorOn) { - Tk_Fill3DRectangle(Tk_CanvasTkwin(canvas), drawable, - textInfoPtr->insertBorder, - drawableX, drawableY, - textInfoPtr->insertWidth, height, + Tk_Fill3DPolygon(Tk_CanvasTkwin(canvas), drawable, + textInfoPtr->insertBorder, points, 4, textInfoPtr->insertBorderWidth, TK_RELIEF_RAISED); } else if (textPtr->cursorOffGC != NULL) { /* @@ -838,10 +940,8 @@ DisplayCanvText( * where both may be drawn in the same color. */ - XFillRectangle(display, drawable, textPtr->cursorOffGC, - drawableX, drawableY, - (unsigned) textInfoPtr->insertWidth, - (unsigned) height); + XFillPolygon(display, drawable, textPtr->cursorOffGC, + points, 4, Convex, CoordModeOrigin); } } } @@ -856,23 +956,24 @@ DisplayCanvText( * anti-aliasing colors would blend together. */ - Tk_CanvasDrawableCoords(canvas, (double) textPtr->leftEdge, - (double) textPtr->header.y1, &drawableX, &drawableY); - if ((selFirstChar >= 0) && (textPtr->selTextGC != textPtr->gc)) { - Tk_DrawTextLayout(display, drawable, textPtr->gc, textPtr->textLayout, - drawableX, drawableY, 0, selFirstChar); - Tk_DrawTextLayout(display, drawable, textPtr->selTextGC, - textPtr->textLayout, drawableX, drawableY, selFirstChar, - selLastChar + 1); - Tk_DrawTextLayout(display, drawable, textPtr->gc, textPtr->textLayout, - drawableX, drawableY, selLastChar + 1, -1); + TkDrawAngledTextLayout(display, drawable, textPtr->gc, + textPtr->textLayout, drawableX, drawableY, textPtr->angle, + 0, selFirstChar); + TkDrawAngledTextLayout(display, drawable, textPtr->selTextGC, + textPtr->textLayout, drawableX, drawableY, textPtr->angle, + selFirstChar, selLastChar + 1); + TkDrawAngledTextLayout(display, drawable, textPtr->gc, + textPtr->textLayout, drawableX, drawableY, textPtr->angle, + selLastChar + 1, -1); } else { - Tk_DrawTextLayout(display, drawable, textPtr->gc, textPtr->textLayout, - drawableX, drawableY, 0, -1); + TkDrawAngledTextLayout(display, drawable, textPtr->gc, + textPtr->textLayout, drawableX, drawableY, textPtr->angle, + 0, -1); } - Tk_UnderlineTextLayout(display, drawable, textPtr->gc, textPtr->textLayout, - drawableX, drawableY, textPtr->underline); + TkUnderlineAngledTextLayout(display, drawable, textPtr->gc, + textPtr->textLayout, drawableX, drawableY, textPtr->angle, + textPtr->underline); if (stipple != None) { XSetTSOrigin(display, textPtr->gc, 0, 0); @@ -880,7 +981,7 @@ DisplayCanvText( } /* - *-------------------------------------------------------------- + *---------------------------------------------------------------------- * * TextInsert -- * @@ -893,7 +994,7 @@ DisplayCanvText( * The text in the given item is modified. The cursor and selection * positions are also modified to reflect the insertion. * - *-------------------------------------------------------------- + *---------------------------------------------------------------------- */ static void @@ -902,14 +1003,15 @@ TextInsert( Tk_Item *itemPtr, /* Text item to be modified. */ int index, /* Character index before which string is to * be inserted. */ - char *string) /* New characters to be inserted. */ + Tcl_Obj *obj) /* New characters to be inserted. */ { TextItem *textPtr = (TextItem *) itemPtr; int byteIndex, byteCount, charsAdded; char *newStr, *text; + const char *string; Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr; - string = Tcl_GetStringFromObj((Tcl_Obj *) string, &byteCount); + string = Tcl_GetStringFromObj(obj, &byteCount); text = textPtr->text; @@ -925,7 +1027,7 @@ TextInsert( return; } - newStr = (char *) ckalloc((unsigned) textPtr->numBytes + byteCount + 1); + newStr = ckalloc(textPtr->numBytes + byteCount + 1); memcpy(newStr, text, (size_t) byteIndex); strcpy(newStr + byteIndex, string); strcpy(newStr + byteIndex + byteCount, text + byteIndex); @@ -1006,7 +1108,7 @@ TextDeleteChars( byteCount = Tcl_UtfAtIndex(text + byteIndex, charsRemoved) - (text + byteIndex); - newStr = (char *) ckalloc((unsigned) (textPtr->numBytes + 1 - byteCount)); + newStr = ckalloc(textPtr->numBytes + 1 - byteCount); memcpy(newStr, text, (size_t) byteIndex); strcpy(newStr + byteIndex, text + byteIndex + byteCount); @@ -1082,15 +1184,17 @@ TextToPoint( { TextItem *textPtr; Tk_State state = itemPtr->state; - double value; + double value, px, py; if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } textPtr = (TextItem *) itemPtr; + px = pointPtr[0] - textPtr->drawOrigin[0]; + py = pointPtr[1] - textPtr->drawOrigin[1]; value = (double) Tk_DistanceToTextLayout(textPtr->textLayout, - (int) pointPtr[0] - textPtr->leftEdge, - (int) pointPtr[1] - textPtr->header.y1); + (int) (px*textPtr->cosine - py*textPtr->sine), + (int) (py*textPtr->cosine + px*textPtr->sine)); if ((state == TK_STATE_HIDDEN) || (textPtr->color == NULL) || (textPtr->text == NULL) || (*textPtr->text == 0)) { @@ -1130,15 +1234,16 @@ TextToArea( Tk_State state = itemPtr->state; if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } textPtr = (TextItem *) itemPtr; - return Tk_IntersectTextLayout(textPtr->textLayout, - (int) (rectPtr[0] + 0.5) - textPtr->leftEdge, - (int) (rectPtr[1] + 0.5) - textPtr->header.y1, + return TkIntersectAngledTextLayout(textPtr->textLayout, + (int) ((rectPtr[0] + 0.5) - textPtr->drawOrigin[0]), + (int) ((rectPtr[1] + 0.5) - textPtr->drawOrigin[1]), (int) (rectPtr[2] - rectPtr[0] + 0.5), - (int) (rectPtr[3] - rectPtr[1] + 0.5)); + (int) (rectPtr[3] - rectPtr[1] + 0.5), + textPtr->angle); } /* @@ -1242,7 +1347,7 @@ GetTextIndex( int c; TkCanvas *canvasPtr = (TkCanvas *) canvas; Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr; - char *string = Tcl_GetStringFromObj(obj, &length); + const char *string = Tcl_GetStringFromObj(obj, &length); c = string[0]; @@ -1254,21 +1359,26 @@ GetTextIndex( } else if ((c == 's') && (length >= 5) && (strncmp(string, "sel.first", (unsigned) length) == 0)) { if (textInfoPtr->selItemPtr != itemPtr) { - Tcl_SetResult(interp, "selection isn't in item", TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "selection isn't in item", -1)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "UNSELECTED", NULL); return TCL_ERROR; } *indexPtr = textInfoPtr->selectFirst; } else if ((c == 's') && (length >= 5) && (strncmp(string, "sel.last", (unsigned) length) == 0)) { if (textInfoPtr->selItemPtr != itemPtr) { - Tcl_SetResult(interp, "selection isn't in item", TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "selection isn't in item", -1)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "UNSELECTED", NULL); return TCL_ERROR; } *indexPtr = textInfoPtr->selectLast; } else if (c == '@') { int x, y; - double tmp; - char *end, *p; + double tmp, c = textPtr->cosine, s = textPtr->sine; + char *end; + const char *p; p = string+1; tmp = strtod(p, &end); @@ -1282,11 +1392,12 @@ GetTextIndex( goto badIndex; } y = (int) ((tmp < 0) ? tmp - 0.5 : tmp + 0.5); + x += canvasPtr->scrollX1 - (int) textPtr->drawOrigin[0]; + y += canvasPtr->scrollY1 - (int) textPtr->drawOrigin[1]; *indexPtr = Tk_PointToChar(textPtr->textLayout, - x + canvasPtr->scrollX1 - textPtr->leftEdge, - y + canvasPtr->scrollY1 - textPtr->header.y1); + (int) (x*c - y*s), (int) (y*c + x*s)); } else if (Tcl_GetIntFromObj(NULL, obj, indexPtr) == TCL_OK) { - if (*indexPtr < 0){ + if (*indexPtr < 0) { *indexPtr = 0; } else if (*indexPtr > textPtr->numChars) { *indexPtr = textPtr->numChars; @@ -1298,8 +1409,8 @@ GetTextIndex( */ badIndex: - Tcl_SetResult(interp, NULL, TCL_STATIC); - Tcl_AppendResult(interp, "bad index \"", string, "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad index \"%s\"", string)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "ITEM_INDEX", "TEXT", NULL); return TCL_ERROR; } return TCL_OK; @@ -1375,7 +1486,7 @@ GetSelText( TextItem *textPtr = (TextItem *) itemPtr; int byteCount; char *text; - CONST char *selStart, *selEnd; + const char *selStart, *selEnd; Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr; if ((textInfoPtr->selectFirst < 0) || @@ -1427,59 +1538,73 @@ TextToPostscript( * being created. */ { TextItem *textPtr = (TextItem *) itemPtr; - int x, y; + double x, y; Tk_FontMetrics fm; - char *justify; - char buffer[500]; + const char *justify; XColor *color; Pixmap stipple; Tk_State state = itemPtr->state; + Tcl_Obj *psObj; + Tcl_InterpState interpState; if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } color = textPtr->color; stipple = textPtr->stipple; if (state == TK_STATE_HIDDEN || textPtr->color == NULL || textPtr->text == NULL || *textPtr->text == 0) { return TCL_OK; - } else if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { - if (textPtr->activeColor!=NULL) { + } else if (Canvas(canvas)->currentItemPtr == itemPtr) { + if (textPtr->activeColor != NULL) { color = textPtr->activeColor; } - if (textPtr->activeStipple!=None) { + if (textPtr->activeStipple != None) { stipple = textPtr->activeStipple; } - } else if (state==TK_STATE_DISABLED) { - if (textPtr->disabledColor!=NULL) { + } else if (state == TK_STATE_DISABLED) { + if (textPtr->disabledColor != NULL) { color = textPtr->disabledColor; } - if (textPtr->disabledStipple!=None) { + if (textPtr->disabledStipple != None) { stipple = textPtr->disabledStipple; } } + /* + * Make our working space. + */ + + psObj = Tcl_NewObj(); + interpState = Tcl_SaveInterpState(interp, TCL_OK); + + /* + * Generate postscript. + */ + + Tcl_ResetResult(interp); if (Tk_CanvasPsFont(interp, canvas, textPtr->tkfont) != TCL_OK) { - return TCL_ERROR; + goto error; } + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); + if (prepass != 0) { - return TCL_OK; + goto done; } + + Tcl_ResetResult(interp); if (Tk_CanvasPsColor(interp, canvas, color) != TCL_OK) { - return TCL_ERROR; + goto error; } + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); + if (stipple != None) { - Tcl_AppendResult(interp, "/StippleText {\n ", NULL); + Tcl_ResetResult(interp); Tk_CanvasPsStipple(interp, canvas, stipple); - Tcl_AppendResult(interp, "} bind def\n", NULL); + Tcl_AppendPrintfToObj(psObj, "/StippleText {\n %s} bind def\n", + Tcl_GetString(Tcl_GetObjResult(interp))); } - sprintf(buffer, "%.15g %.15g [\n", textPtr->x, - Tk_CanvasPsY(canvas, textPtr->y)); - Tcl_AppendResult(interp, buffer, NULL); - - Tk_TextLayoutToPostscript(interp, textPtr->textLayout); - x = 0; y = 0; justify = NULL; /* lint. */ switch (textPtr->anchor) { case TK_ANCHOR_NW: x = 0; y = 0; break; @@ -1499,17 +1624,31 @@ TextToPostscript( } Tk_GetFontMetrics(textPtr->tkfont, &fm); - sprintf(buffer, "] %d ", fm.linespace); - Tcl_AppendResult(interp, buffer, NULL); - Tcl_PrintDouble(NULL, x / -2.0, buffer); - Tcl_AppendResult(interp, buffer, NULL); - Tcl_PrintDouble(NULL, y / 2.0, buffer); - Tcl_AppendResult(interp, " ", buffer, NULL); - sprintf(buffer, " %s %s DrawText\n", - justify, ((stipple == None) ? "false" : "true")); - Tcl_AppendResult(interp, buffer, NULL); + Tcl_AppendPrintfToObj(psObj, "%.15g %.15g %.15g [\n", + textPtr->angle, textPtr->x, Tk_CanvasPsY(canvas, textPtr->y)); + Tcl_ResetResult(interp); + Tk_TextLayoutToPostscript(interp, textPtr->textLayout); + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); + Tcl_AppendPrintfToObj(psObj, + "] %d %g %g %s %s DrawText\n", + fm.linespace, x / -2.0, y / 2.0, justify, + ((stipple == None) ? "false" : "true")); + + /* + * Plug the accumulated postscript back into the result. + */ + + done: + (void) Tcl_RestoreInterpState(interp, interpState); + Tcl_AppendObjToObj(Tcl_GetObjResult(interp), psObj); + Tcl_DecrRefCount(psObj); return TCL_OK; + + error: + Tcl_DiscardInterpState(interpState); + Tcl_DecrRefCount(psObj); + return TCL_ERROR; } /* diff --git a/generic/tkCanvUtil.c b/generic/tkCanvUtil.c index d051e27..6ce671d 100644 --- a/generic/tkCanvUtil.c +++ b/generic/tkCanvUtil.c @@ -25,13 +25,13 @@ typedef struct SmoothAssocData { * option. */ } SmoothAssocData; -Tk_SmoothMethod tkBezierSmoothMethod = { +const Tk_SmoothMethod tkBezierSmoothMethod = { "true", TkMakeBezierCurve, (void (*) (Tcl_Interp *interp, Tk_Canvas canvas, double *coordPtr, int numPoints, int numSteps)) TkMakeBezierPostscript, }; -static Tk_SmoothMethod tkRawSmoothMethod = { +static const Tk_SmoothMethod tkRawSmoothMethod = { "raw", TkMakeRawCurve, (void (*) (Tcl_Interp *interp, Tk_Canvas canvas, double *coordPtr, @@ -45,13 +45,27 @@ static Tk_SmoothMethod tkRawSmoothMethod = { static void SmoothMethodCleanupProc(ClientData clientData, Tcl_Interp *interp); static SmoothAssocData *InitSmoothMethods(Tcl_Interp *interp); -static int DashConvert(char *l, CONST char *p, int n, +static int DashConvert(char *l, const char *p, int n, double width); static void TranslateAndAppendCoords(TkCanvas *canvPtr, double x, double y, XPoint *outArr, int numOut); +static inline Tcl_Obj * GetPostscriptBuffer(Tcl_Interp *interp); #define ABS(a) ((a>=0)?(a):(-(a))) +static inline Tcl_Obj * +GetPostscriptBuffer( + Tcl_Interp *interp) +{ + Tcl_Obj *psObj = Tcl_GetObjResult(interp); + + if (Tcl_IsShared(psObj)) { + psObj = Tcl_DuplicateObj(psObj); + Tcl_SetObjResult(interp, psObj); + } + return psObj; +} + /* *---------------------------------------------------------------------- * @@ -73,8 +87,7 @@ Tk_Window Tk_CanvasTkwin( Tk_Canvas canvas) /* Token for the canvas. */ { - TkCanvas *canvasPtr = (TkCanvas *) canvas; - return canvasPtr->tkwin; + return Canvas(canvas)->tkwin; } /* @@ -106,10 +119,9 @@ Tk_CanvasDrawableCoords( short *drawableXPtr, /* Screen coordinates are stored here. */ short *drawableYPtr) { - TkCanvas *canvasPtr = (TkCanvas *) canvas; double tmp; - tmp = x - canvasPtr->drawableXOrigin; + tmp = x - Canvas(canvas)->drawableXOrigin; if (tmp > 0) { tmp += 0.5; } else { @@ -123,7 +135,7 @@ Tk_CanvasDrawableCoords( *drawableXPtr = (short) tmp; } - tmp = y - canvasPtr->drawableYOrigin; + tmp = y - Canvas(canvas)->drawableYOrigin; if (tmp > 0) { tmp += 0.5; } else { @@ -166,10 +178,9 @@ Tk_CanvasWindowCoords( short *screenXPtr, /* Screen coordinates are stored here. */ short *screenYPtr) { - TkCanvas *canvasPtr = (TkCanvas *) canvas; double tmp; - tmp = x - canvasPtr->xOrigin; + tmp = x - Canvas(canvas)->xOrigin; if (tmp > 0) { tmp += 0.5; } else { @@ -183,7 +194,7 @@ Tk_CanvasWindowCoords( *screenXPtr = (short) tmp; } - tmp = y - canvasPtr->yOrigin; + tmp = y - Canvas(canvas)->yOrigin; if (tmp > 0) { tmp += 0.5; } else { @@ -222,17 +233,15 @@ int Tk_CanvasGetCoord( Tcl_Interp *interp, /* Interpreter for error reporting. */ Tk_Canvas canvas, /* Canvas to which coordinate applies. */ - CONST char *string, /* Describes coordinate (any screen coordinate + const char *string, /* Describes coordinate (any screen coordinate * form may be used here). */ double *doublePtr) /* Place to store converted coordinate. */ { - TkCanvas *canvasPtr = (TkCanvas *) canvas; - - if (Tk_GetScreenMM(canvasPtr->interp, canvasPtr->tkwin, string, + if (Tk_GetScreenMM(Canvas(canvas)->interp, Canvas(canvas)->tkwin, string, doublePtr) != TCL_OK) { return TCL_ERROR; } - *doublePtr *= canvasPtr->pixelsPerMM; + *doublePtr *= Canvas(canvas)->pixelsPerMM; return TCL_OK; } @@ -264,9 +273,7 @@ Tk_CanvasGetCoordFromObj( * form may be used here). */ double *doublePtr) /* Place to store converted coordinate. */ { - TkCanvas *canvasPtr = (TkCanvas *) canvas; - - return Tk_GetDoublePixelsFromObj(canvasPtr->interp, canvasPtr->tkwin, obj, doublePtr); + return Tk_GetDoublePixelsFromObj(Canvas(canvas)->interp, Canvas(canvas)->tkwin, obj, doublePtr); } /* @@ -294,10 +301,9 @@ Tk_CanvasSetStippleOrigin( * to draw a stippled pattern as part of * redisplaying the canvas. */ { - TkCanvas *canvasPtr = (TkCanvas *) canvas; - - XSetTSOrigin(canvasPtr->display, gc, -canvasPtr->drawableXOrigin, - -canvasPtr->drawableYOrigin); + XSetTSOrigin(Canvas(canvas)->display, gc, + -Canvas(canvas)->drawableXOrigin, + -Canvas(canvas)->drawableYOrigin); } /* @@ -326,7 +332,7 @@ Tk_CanvasSetOffset( * redisplaying the canvas. */ Tk_TSOffset *offset) /* Offset (may be NULL pointer)*/ { - TkCanvas *canvasPtr = (TkCanvas *) canvas; + register TkCanvas *canvasPtr = Canvas(canvas); int flags = 0; int x = - canvasPtr->drawableXOrigin; int y = - canvasPtr->drawableYOrigin; @@ -370,7 +376,7 @@ Tk_CanvasTextInfo * Tk_CanvasGetTextInfo( Tk_Canvas canvas) /* Token for the canvas widget. */ { - return &((TkCanvas *) canvas)->textInfo; + return &Canvas(canvas)->textInfo; } /* @@ -396,13 +402,13 @@ Tk_CanvasTagsParseProc( ClientData clientData, /* Not used.*/ Tcl_Interp *interp, /* Used for reporting errors. */ Tk_Window tkwin, /* Window containing canvas widget. */ - CONST char *value, /* Value of option (list of tag names). */ + const char *value, /* Value of option (list of tag names). */ char *widgRec, /* Pointer to record for item. */ int offset) /* Offset into item (ignored). */ { register Tk_Item *itemPtr = (Tk_Item *) widgRec; int argc, i; - CONST char **argv; + const char **argv; Tk_Uid *newPtr; /* @@ -418,12 +424,12 @@ Tk_CanvasTagsParseProc( */ if (itemPtr->tagSpace < argc) { - newPtr = (Tk_Uid *) ckalloc((unsigned) (argc * sizeof(Tk_Uid))); + newPtr = ckalloc(argc * sizeof(Tk_Uid)); for (i = itemPtr->numTags-1; i >= 0; i--) { newPtr[i] = itemPtr->tagPtr[i]; } if (itemPtr->tagPtr != itemPtr->staticTagSpace) { - ckfree((char *) itemPtr->tagPtr); + ckfree(itemPtr->tagPtr); } itemPtr->tagPtr = newPtr; itemPtr->tagSpace = argc; @@ -432,7 +438,7 @@ Tk_CanvasTagsParseProc( for (i = 0; i < argc; i++) { itemPtr->tagPtr[i] = Tk_GetUid(argv[i]); } - ckfree((char *) argv); + ckfree(argv); return TCL_OK; } @@ -458,7 +464,7 @@ Tk_CanvasTagsParseProc( *-------------------------------------------------------------- */ -char * +const char * Tk_CanvasTagsPrintProc( ClientData clientData, /* Ignored. */ Tk_Window tkwin, /* Window containing canvas widget. */ @@ -476,10 +482,10 @@ Tk_CanvasTagsPrintProc( } if (itemPtr->numTags == 1) { *freeProcPtr = NULL; - return (char *) itemPtr->tagPtr[0]; + return (const char *) itemPtr->tagPtr[0]; } *freeProcPtr = TCL_DYNAMIC; - return Tcl_Merge(itemPtr->numTags, (CONST char **) itemPtr->tagPtr); + return Tcl_Merge(itemPtr->numTags, (const char **) itemPtr->tagPtr); } /* @@ -505,11 +511,11 @@ TkCanvasDashParseProc( ClientData clientData, /* Not used.*/ Tcl_Interp *interp, /* Used for reporting errors. */ Tk_Window tkwin, /* Window containing canvas widget. */ - CONST char *value, /* Value of option. */ + const char *value, /* Value of option. */ char *widgRec, /* Pointer to record for item. */ int offset) /* Offset into item. */ { - return Tk_GetDash(interp, value, (Tk_Dash *)(widgRec+offset)); + return Tk_GetDash(interp, value, (Tk_Dash *) (widgRec+offset)); } /* @@ -534,7 +540,7 @@ TkCanvasDashParseProc( *-------------------------------------------------------------- */ -char * +const char * TkCanvasDashPrintProc( ClientData clientData, /* Ignored. */ Tk_Window tkwin, /* Window containing canvas widget. */ @@ -545,14 +551,13 @@ TkCanvasDashPrintProc( * for return string. */ { Tk_Dash *dash = (Tk_Dash *) (widgRec+offset); - char *buffer; - char *p; + char *buffer, *p; int i = dash->number; if (i < 0) { i = -i; *freeProcPtr = TCL_DYNAMIC; - buffer = (char *) ckalloc((unsigned int) (i+1)); + buffer = ckalloc(i + 1); p = (i > (int)sizeof(char *)) ? dash->pattern.pt : dash->pattern.array; memcpy(buffer, p, (unsigned int) i); buffer[i] = 0; @@ -561,12 +566,12 @@ TkCanvasDashPrintProc( *freeProcPtr = NULL; return ""; } - buffer = (char *)ckalloc((unsigned int) (4*i)); + buffer = ckalloc(4 * i); *freeProcPtr = TCL_DYNAMIC; p = (i > (int)sizeof(char *)) ? dash->pattern.pt : dash->pattern.array; sprintf(buffer, "%d", *p++ & 0xff); - while(--i) { + while (--i) { sprintf(buffer+strlen(buffer), " %d", *p++ & 0xff); } return buffer; @@ -597,21 +602,18 @@ InitSmoothMethods( { SmoothAssocData *methods, *ptr; - methods = (SmoothAssocData *) ckalloc(sizeof(SmoothAssocData)); + methods = ckalloc(sizeof(SmoothAssocData)); methods->smooth.name = tkRawSmoothMethod.name; methods->smooth.coordProc = tkRawSmoothMethod.coordProc; methods->smooth.postscriptProc = tkRawSmoothMethod.postscriptProc; - methods->nextPtr = (SmoothAssocData *) ckalloc(sizeof(SmoothAssocData)); - - ptr = methods->nextPtr; + ptr = methods->nextPtr = ckalloc(sizeof(SmoothAssocData)); ptr->smooth.name = tkBezierSmoothMethod.name; ptr->smooth.coordProc = tkBezierSmoothMethod.coordProc; ptr->smooth.postscriptProc = tkBezierSmoothMethod.postscriptProc; ptr->nextPtr = NULL; - Tcl_SetAssocData(interp, "smoothMethod", SmoothMethodCleanupProc, - (ClientData) methods); + Tcl_SetAssocData(interp, "smoothMethod", SmoothMethodCleanupProc,methods); return methods; } @@ -636,11 +638,10 @@ InitSmoothMethods( void Tk_CreateSmoothMethod( Tcl_Interp *interp, - Tk_SmoothMethod *smooth) + const Tk_SmoothMethod *smooth) { SmoothAssocData *methods, *typePtr2, *prevPtr, *ptr; - methods = (SmoothAssocData *) Tcl_GetAssocData(interp, "smoothMethod", - NULL); + methods = Tcl_GetAssocData(interp, "smoothMethod", NULL); /* * Initialize if we were not previously initialized. @@ -662,17 +663,16 @@ Tk_CreateSmoothMethod( } else { prevPtr->nextPtr = typePtr2->nextPtr; } - ckfree((char *) typePtr2); + ckfree(typePtr2); break; } } - ptr = (SmoothAssocData *) ckalloc(sizeof(SmoothAssocData)); + ptr = ckalloc(sizeof(SmoothAssocData)); ptr->smooth.name = smooth->name; ptr->smooth.coordProc = smooth->coordProc; ptr->smooth.postscriptProc = smooth->postscriptProc; ptr->nextPtr = methods; - Tcl_SetAssocData(interp, "smoothMethod", SmoothMethodCleanupProc, - (ClientData) ptr); + Tcl_SetAssocData(interp, "smoothMethod", SmoothMethodCleanupProc, ptr); } /* @@ -698,11 +698,12 @@ SmoothMethodCleanupProc( * interpreter. */ Tcl_Interp *interp) /* Interpreter that is being deleted. */ { - SmoothAssocData *ptr, *methods = (SmoothAssocData *) clientData; + SmoothAssocData *ptr, *methods = clientData; while (methods != NULL) { - methods = (ptr = methods)->nextPtr; - ckfree((char *) ptr); + ptr = methods; + methods = methods->nextPtr; + ckfree(ptr); } } /* @@ -725,16 +726,16 @@ SmoothMethodCleanupProc( int TkSmoothParseProc( - ClientData clientData, /* some flags.*/ + ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* Used for reporting errors. */ Tk_Window tkwin, /* Window containing canvas widget. */ - CONST char *value, /* Value of option. */ + const char *value, /* Value of option. */ char *widgRec, /* Pointer to record for item. */ int offset) /* Offset into item. */ { - register Tk_SmoothMethod **smoothPtr = - (Tk_SmoothMethod **) (widgRec + offset); - Tk_SmoothMethod *smooth = NULL; + register const Tk_SmoothMethod **smoothPtr = + (const Tk_SmoothMethod **) (widgRec + offset); + const Tk_SmoothMethod *smooth = NULL; int b; size_t length; SmoothAssocData *methods; @@ -744,8 +745,7 @@ TkSmoothParseProc( return TCL_OK; } length = strlen(value); - methods = (SmoothAssocData *) Tcl_GetAssocData(interp, "smoothMethod", - NULL); + methods = Tcl_GetAssocData(interp, "smoothMethod", NULL); /* * Not initialized yet; fix that now. @@ -770,8 +770,10 @@ TkSmoothParseProc( while (methods != NULL) { if (strncmp(value, methods->smooth.name, length) == 0) { if (smooth != NULL) { - Tcl_AppendResult(interp, "ambiguous smooth method \"", value, - "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "ambiguous smooth method \"%s\"", value)); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "SMOOTH", value, + NULL); return TCL_ERROR; } smooth = &methods->smooth; @@ -814,7 +816,7 @@ TkSmoothParseProc( *-------------------------------------------------------------- */ -char * +const char * TkSmoothPrintProc( ClientData clientData, /* Ignored. */ Tk_Window tkwin, /* Window containing canvas widget. */ @@ -824,10 +826,10 @@ TkSmoothPrintProc( * information about how to reclaim storage * for return string. */ { - register Tk_SmoothMethod **smoothPtr = - (Tk_SmoothMethod **) (widgRec + offset); + register const Tk_SmoothMethod *smoothPtr = + * (Tk_SmoothMethod **) (widgRec + offset); - return (*smoothPtr) ? (*smoothPtr)->name : "0"; + return smoothPtr ? smoothPtr->name : "0"; } /* *-------------------------------------------------------------- @@ -850,15 +852,15 @@ TkSmoothPrintProc( int Tk_GetDash( Tcl_Interp *interp, /* Used for error reporting. */ - CONST char *value, /* Textual specification of dash list. */ + const char *value, /* Textual specification of dash list. */ Tk_Dash *dash) /* Pointer to record in which to store dash * information. */ { int argc, i; - CONST char **largv, **argv = NULL; + const char **largv, **argv = NULL; char *pt; - if ((value==NULL) || (*value==0) ) { + if ((value == NULL) || (*value == '\0')) { dash->number = 0; return TCL_OK; } @@ -870,17 +872,16 @@ Tk_GetDash( switch (*value) { case '.': case ',': case '-': case '_': i = DashConvert(NULL, value, -1, 0.0); - if (i>0) { - i = strlen(value); - } else { + if (i <= 0) { goto badDashList; } - if (i > (int)sizeof(char *)) { - dash->pattern.pt = pt = (char *) ckalloc(strlen(value)); + i = strlen(value); + if (i > (int) sizeof(char *)) { + dash->pattern.pt = pt = ckalloc(strlen(value)); } else { pt = dash->pattern.array; } - memcpy(pt,value, (unsigned int) i); + memcpy(pt, value, (unsigned) i); dash->number = -i; return TCL_OK; } @@ -890,23 +891,23 @@ Tk_GetDash( goto badDashList; } - if ((unsigned int)ABS(dash->number) > sizeof(char *)) { - ckfree((char *) dash->pattern.pt); + if ((unsigned) ABS(dash->number) > sizeof(char *)) { + ckfree(dash->pattern.pt); } - if (argc > (int)sizeof(char *)) { - dash->pattern.pt = pt = (char *) ckalloc((unsigned int) argc); + if (argc > (int) sizeof(char *)) { + dash->pattern.pt = pt = ckalloc(argc); } else { pt = dash->pattern.array; } dash->number = argc; largv = argv; - while (argc>0) { + while (argc > 0) { if (Tcl_GetInt(interp, *largv, &i) != TCL_OK || i < 1 || i>255) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, - "expected integer in the range 1..255 but got \"", - *largv, "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "expected integer in the range 1..255 but got \"%s\"", + *largv)); + Tcl_SetErrorCode(interp, "TK", "VALUE", "DASH", NULL); goto syntaxError; } *pt++ = i; @@ -915,7 +916,7 @@ Tk_GetDash( } if (argv != NULL) { - ckfree((char *) argv); + ckfree(argv); } return TCL_OK; @@ -924,15 +925,16 @@ Tk_GetDash( */ badDashList: - Tcl_AppendResult(interp, "bad dash list \"", value, - "\": must be a list of integers or a format like \"-..\"", - NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad dash list \"%s\": must be a list of integers or a format like \"-..\"", + value)); + Tcl_SetErrorCode(interp, "TK", "VALUE", "DASH", NULL); syntaxError: if (argv != NULL) { - ckfree((char *) argv); + ckfree(argv); } - if ((unsigned int)ABS(dash->number) > sizeof(char *)) { - ckfree((char *) dash->pattern.pt); + if ((unsigned) ABS(dash->number) > sizeof(char *)) { + ckfree(dash->pattern.pt); } dash->number = 0; return TCL_ERROR; @@ -1003,14 +1005,14 @@ Tk_DeleteOutline( if (outline->gc != NULL) { Tk_FreeGC(display, outline->gc); } - if ((unsigned int)ABS(outline->dash.number) > sizeof(char *)) { - ckfree((char *) outline->dash.pattern.pt); + if ((unsigned) ABS(outline->dash.number) > sizeof(char *)) { + ckfree(outline->dash.pattern.pt); } - if ((unsigned int)ABS(outline->activeDash.number) > sizeof(char *)) { - ckfree((char *) outline->activeDash.pattern.pt); + if ((unsigned) ABS(outline->activeDash.number) > sizeof(char *)) { + ckfree(outline->activeDash.pattern.pt); } - if ((unsigned int)ABS(outline->disabledDash.number) > sizeof(char *)) { - ckfree((char *) outline->disabledDash.pattern.pt); + if ((unsigned) ABS(outline->disabledDash.number) > sizeof(char *)) { + ckfree(outline->disabledDash.pattern.pt); } if (outline->color != NULL) { Tk_FreeColor(outline->color); @@ -1087,9 +1089,9 @@ Tk_ConfigOutlineGC( color = outline->color; stipple = outline->stipple; if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } - if (((TkCanvas *)canvas)->currentItemPtr == item) { + if (Canvas(canvas)->currentItemPtr == item) { if (outline->activeWidth>width) { width = outline->activeWidth; } @@ -1170,7 +1172,7 @@ Tk_ChangeOutlineGC( Tk_Item *item, Tk_Outline *outline) { - CONST char *p; + const char *p; double width; Tk_Dash *dash; XColor *color; @@ -1185,9 +1187,9 @@ Tk_ChangeOutlineGC( color = outline->color; stipple = outline->stipple; if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } - if (((TkCanvas *)canvas)->currentItemPtr == item) { + if (Canvas(canvas)->currentItemPtr == item) { if (outline->activeWidth > width) { width = outline->activeWidth; } @@ -1224,25 +1226,25 @@ Tk_ChangeOutlineGC( int i = -dash->number; p = (i > (int)sizeof(char *)) ? dash->pattern.pt : dash->pattern.array; - q = (char *) ckalloc(2*(unsigned int)i); + q = ckalloc(2 * i); i = DashConvert(q, p, i, width); - XSetDashes(((TkCanvas *)canvas)->display, outline->gc, - outline->offset, q, i); + XSetDashes(Canvas(canvas)->display, outline->gc, outline->offset, q,i); ckfree(q); } else if (dash->number>2 || (dash->number==2 && (dash->pattern.array[0]!=dash->pattern.array[1]))) { - p = (dash->number > (int)sizeof(char *)) + p = (dash->number > (int) sizeof(char *)) ? dash->pattern.pt : dash->pattern.array; - XSetDashes(((TkCanvas *)canvas)->display, outline->gc, - outline->offset, p, dash->number); + XSetDashes(Canvas(canvas)->display, outline->gc, outline->offset, p, + dash->number); } if (stipple!=None) { - int w=0; int h=0; + int w = 0; int h = 0; Tk_TSOffset *tsoffset = &outline->tsoffset; int flags = tsoffset->flags; + if (!(flags & TK_OFFSET_INDEX) && (flags & (TK_OFFSET_CENTER|TK_OFFSET_MIDDLE))) { - Tk_SizeOfBitmap(((TkCanvas *)canvas)->display, stipple, &w, &h); + Tk_SizeOfBitmap(Canvas(canvas)->display, stipple, &w, &h); if (flags & TK_OFFSET_CENTER) { w /= 2; } else { @@ -1270,9 +1272,9 @@ Tk_ChangeOutlineGC( * * Tk_ResetOutlineGC * - * Restores the GC to the situation before Tk_ChangeDashGC() was called. - * This function should be called just after the dashed item is drawn, - * because the GC is supposed to be read-only. + * Restores the GC to the situation before Tk_ChangeOutlineGC() was + * called. This function should be called just after the dashed item is + * drawn, because the GC is supposed to be read-only. * * Results: * 1 if there is a stipple pattern, and 0 otherwise. @@ -1304,9 +1306,9 @@ Tk_ResetOutlineGC( color = outline->color; stipple = outline->stipple; if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } - if (((TkCanvas *)canvas)->currentItemPtr == item) { + if (Canvas(canvas)->currentItemPtr == item) { if (outline->activeWidth>width) { width = outline->activeWidth; } @@ -1347,11 +1349,11 @@ Tk_ResetOutlineGC( } else { dashList = (char) (4 * width + 0.5); } - XSetDashes(((TkCanvas *)canvas)->display, outline->gc, - outline->offset, &dashList , 1); + XSetDashes(Canvas(canvas)->display, outline->gc, outline->offset, + &dashList , 1); } if (stipple != None) { - XSetTSOrigin(((TkCanvas *)canvas)->display, outline->gc, 0, 0); + XSetTSOrigin(Canvas(canvas)->display, outline->gc, 0, 0); return 1; } return 0; @@ -1381,33 +1383,27 @@ Tk_CanvasPsOutline( Tk_Item *item, Tk_Outline *outline) { - char string[41]; char pattern[11]; int i; - char *ptr; - char *str = string; - char *lptr = pattern; - Tcl_Interp *interp = ((TkCanvas *)canvas)->interp; - double width; - Tk_Dash *dash; - XColor *color; - Pixmap stipple; + char *ptr, *lptr = pattern; + Tcl_Interp *interp = Canvas(canvas)->interp; + double width = outline->width; + Tk_Dash *dash = &outline->dash; + XColor *color = outline->color; + Pixmap stipple = outline->stipple; Tk_State state = item->state; + Tcl_Obj *psObj = GetPostscriptBuffer(interp); - width = outline->width; - dash = &(outline->dash); - color = outline->color; - stipple = outline->stipple; if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } - if (((TkCanvas *)canvas)->currentItemPtr == item) { + if (Canvas(canvas)->currentItemPtr == item) { if (outline->activeWidth > width) { width = outline->activeWidth; } if (outline->activeDash.number > 0) { - dash = &(outline->activeDash); + dash = &outline->activeDash; } if (outline->activeColor != NULL) { color = outline->activeColor; @@ -1420,7 +1416,7 @@ Tk_CanvasPsOutline( width = outline->disabledWidth; } if (outline->disabledDash.number > 0) { - dash = &(outline->disabledDash); + dash = &outline->disabledDash; } if (outline->disabledColor != NULL) { color = outline->disabledColor; @@ -1429,66 +1425,65 @@ Tk_CanvasPsOutline( stipple = outline->disabledStipple; } } - sprintf(string, "%.15g setlinewidth\n", width); - Tcl_AppendResult(interp, string, NULL); - if (dash->number > 10) { - str = (char *)ckalloc((unsigned int) (1 + 4*dash->number)); - } else if (dash->number < -5) { - str = (char *)ckalloc((unsigned int) (1 - 8*dash->number)); - lptr = (char *)ckalloc((unsigned int) (1 - 2*dash->number)); - } - ptr = ((unsigned int)ABS(dash->number) > sizeof(char *)) ? + Tcl_AppendPrintfToObj(psObj, "%.15g setlinewidth\n", width); + + ptr = ((unsigned) ABS(dash->number) > sizeof(char *)) ? dash->pattern.pt : dash->pattern.array; + Tcl_AppendToObj(psObj, "[", -1); if (dash->number > 0) { - char *ptr0 = ptr; + Tcl_Obj *converted; + char *p = ptr; - sprintf(str, "[%d", *ptr++ & 0xff); - i = dash->number-1; - while (i--) { - sprintf(str+strlen(str), " %d", *ptr++ & 0xff); + converted = Tcl_ObjPrintf("%d", *p++ & 0xff); + for (i = dash->number-1 ; i>0 ; i--) { + Tcl_AppendPrintfToObj(converted, " %d", *p++ & 0xff); } - Tcl_AppendResult(interp, str, NULL); - if (dash->number&1) { - Tcl_AppendResult(interp, " ", str+1, NULL); + Tcl_AppendObjToObj(psObj, converted); + if (dash->number & 1) { + Tcl_AppendToObj(psObj, " ", -1); + Tcl_AppendObjToObj(psObj, converted); } - sprintf(str, "] %d setdash\n", outline->offset); - Tcl_AppendResult(interp, str, NULL); - ptr = ptr0; + Tcl_DecrRefCount(converted); + Tcl_AppendPrintfToObj(psObj, "] %d setdash\n", outline->offset); } else if (dash->number < 0) { - if ((i = DashConvert(lptr, ptr, -dash->number, width)) != 0) { - char *lptr0 = lptr; + if (dash->number < -5) { + lptr = ckalloc(1 - 2*dash->number); + } + i = DashConvert(lptr, ptr, -dash->number, width); + if (i > 0) { + char *p = lptr; - sprintf(str, "[%d", *lptr++ & 0xff); - while (--i) { - sprintf(str+strlen(str), " %d", *lptr++ & 0xff); + Tcl_AppendPrintfToObj(psObj, "%d", *p++ & 0xff); + for (; --i>0 ;) { + Tcl_AppendPrintfToObj(psObj, " %d", *p++ & 0xff); } - Tcl_AppendResult(interp, str, NULL); - sprintf(str, "] %d setdash\n", outline->offset); - Tcl_AppendResult(interp, str, NULL); - lptr = lptr0; + Tcl_AppendPrintfToObj(psObj, "] %d setdash\n", outline->offset); } else { - Tcl_AppendResult(interp, "[] 0 setdash\n", NULL); + Tcl_AppendToObj(psObj, "] 0 setdash\n", -1); + } + if (lptr != pattern) { + ckfree(lptr); } } else { - Tcl_AppendResult(interp, "[] 0 setdash\n", NULL); - } - if (str != string) { - ckfree(str); - } - if (lptr != pattern) { - ckfree(lptr); + Tcl_AppendToObj(psObj, "] 0 setdash\n", -1); } + if (Tk_CanvasPsColor(interp, canvas, color) != TCL_OK) { return TCL_ERROR; } + + /* + * Note that psObj might hold an invalid reference now. + */ + if (stipple != None) { - Tcl_AppendResult(interp, "StrokeClip ", NULL); + Tcl_AppendToObj(GetPostscriptBuffer(interp), "StrokeClip ", -1); if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK) { return TCL_ERROR; } } else { - Tcl_AppendResult(interp, "stroke\n", NULL); + Tcl_AppendToObj(GetPostscriptBuffer(interp), "stroke\n", -1); } return TCL_OK; @@ -1516,7 +1511,7 @@ static int DashConvert( char *l, /* Must be at least 2*n chars long, or NULL to * indicate "just check syntax". */ - CONST char *p, /* String to parse. */ + const char *p, /* String to parse. */ int n, /* Length of string to parse, or -1 to * indicate that strlen() should be used. */ double width) /* Width of line. */ @@ -1524,7 +1519,7 @@ DashConvert( int result = 0; int size, intWidth; - if (n<0) { + if (n < 0) { n = strlen(p); } intWidth = (int) (width + 0.5); @@ -1664,10 +1659,6 @@ TkCanvTranslatePath( double *a, *b, *t; /* Pointers to parts of the temporary * storage */ int i, j; /* Loop counters */ -#ifndef NDEBUG - int maxOutput; /* Maximum number of outputs that we will - * allow */ -#endif double limit[4]; /* Boundries at which clipping occurs */ double staticSpace[480]; /* Temp space from the stack */ @@ -1708,7 +1699,7 @@ TkCanvTranslatePath( double x, y; x = coordArr[i*2]; - y = coordArr[i*2+1]; + y = coordArr[i*2 + 1]; if (x<lft || x>rgh || y<top || y>btm) { break; } @@ -1726,10 +1717,10 @@ TkCanvTranslatePath( * b[]. Initialize a[] to be equal to coordArr[]. */ - if (numVertex*12 <= (int)(sizeof(staticSpace)/sizeof(staticSpace[0]))) { + if (numVertex*12 <= (int) (sizeof(staticSpace) / sizeof(double))) { tempArr = staticSpace; } else { - tempArr = (double *)ckalloc(numVertex*12*sizeof(tempArr[0])); + tempArr = ckalloc(numVertex * 12 * sizeof(double)); } for (i=0; i<numVertex*2; i++){ tempArr[i] = coordArr[i]; @@ -1762,12 +1753,9 @@ TkCanvTranslatePath( * This is the loop that makes the four passes through the data. */ -#ifndef NDEBUG - maxOutput = numVertex*3; -#endif - for (j=0; j<4; j++){ + for (j=0; j<4; j++) { double xClip = limit[j]; - int inside = a[0]<xClip; + int inside = a[0] < xClip; double priorY = a[1]; numOutput = 0; @@ -1776,9 +1764,9 @@ TkCanvTranslatePath( * rotated by 90 degrees clockwise. */ - for (i=0; i<numVertex; i++){ + for (i=0; i<numVertex; i++) { double x = a[i*2]; - double y = a[i*2+1]; + double y = a[i*2 + 1]; if (x >= xClip) { /* @@ -1796,13 +1784,13 @@ TkCanvTranslatePath( double x0, y0, yN; assert(i > 0); - x0 = a[i*2-2]; - y0 = a[i*2-1]; + x0 = a[i*2 - 2]; + y0 = a[i*2 - 1]; yN = y0 + (y - y0)*(xClip-x0)/(x-x0); b[numOutput*2] = -yN; - b[numOutput*2+1] = xClip; + b[numOutput*2 + 1] = xClip; numOutput++; - assert(numOutput <= maxOutput); + assert(numOutput <= numVertex*3); priorY = yN; inside = 0; } else if (i == 0) { @@ -1821,8 +1809,10 @@ TkCanvTranslatePath( /* * The current vertex is to the left of xClip */ + if (!inside) { - /* If the current vertex is on the left of xClip and one + /* + * If the current vertex is on the left of xClip and one * or more prior vertices where to the right, then we have * to draw a line segment along xClip that extends from * the spot where we first crossed from left to right to @@ -1832,21 +1822,21 @@ TkCanvTranslatePath( double x0, y0, yN; assert(i > 0); - x0 = a[i*2-2]; - y0 = a[i*2-1]; + x0 = a[i*2 - 2]; + y0 = a[i*2 - 1]; yN = y0 + (y - y0)*(xClip-x0)/(x-x0); if (yN != priorY) { b[numOutput*2] = -yN; - b[numOutput*2+1] = xClip; + b[numOutput*2 + 1] = xClip; numOutput++; - assert(numOutput <= maxOutput); + assert(numOutput <= numVertex*3); } inside = 1; } b[numOutput*2] = -y; - b[numOutput*2+1] = x; + b[numOutput*2 + 1] = x; numOutput++; - assert(numOutput <= maxOutput); + assert(numOutput <= numVertex*3); } } @@ -1865,11 +1855,11 @@ TkCanvTranslatePath( * XPoints and translate the origin for the drawable. */ - for (i=0; i<numVertex; i++){ + for (i=0; i<numVertex; i++) { TranslateAndAppendCoords(canvPtr, a[i*2], a[i*2+1], outArr, i); } if (tempArr != staticSpace) { - ckfree((char *) tempArr); + ckfree(tempArr); } return numOutput; } diff --git a/generic/tkCanvWind.c b/generic/tkCanvWind.c index b62859c..f73546f 100644 --- a/generic/tkCanvWind.c +++ b/generic/tkCanvWind.c @@ -10,7 +10,6 @@ * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ -#include <stdio.h> #include "tkInt.h" #include "tkCanvas.h" @@ -38,29 +37,27 @@ typedef struct WindowItem { * Information used for parsing configuration specs: */ -static Tk_CustomOption stateOption = { - (Tk_OptionParseProc *) TkStateParseProc, - TkStatePrintProc, (ClientData) 2 +static const Tk_CustomOption stateOption = { + TkStateParseProc, TkStatePrintProc, INT2PTR(2) }; -static Tk_CustomOption tagsOption = { - (Tk_OptionParseProc *) Tk_CanvasTagsParseProc, - Tk_CanvasTagsPrintProc, (ClientData) NULL +static const Tk_CustomOption tagsOption = { + Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL }; -static Tk_ConfigSpec configSpecs[] = { +static const Tk_ConfigSpec configSpecs[] = { {TK_CONFIG_ANCHOR, "-anchor", NULL, NULL, - "center", Tk_Offset(WindowItem, anchor), TK_CONFIG_DONT_SET_DEFAULT}, + "center", Tk_Offset(WindowItem, anchor), TK_CONFIG_DONT_SET_DEFAULT, NULL}, {TK_CONFIG_PIXELS, "-height", NULL, NULL, - "0", Tk_Offset(WindowItem, height), TK_CONFIG_DONT_SET_DEFAULT}, + "0", Tk_Offset(WindowItem, height), TK_CONFIG_DONT_SET_DEFAULT, NULL}, {TK_CONFIG_CUSTOM, "-state", NULL, NULL, NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption}, {TK_CONFIG_CUSTOM, "-tags", NULL, NULL, NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, {TK_CONFIG_PIXELS, "-width", NULL, NULL, - "0", Tk_Offset(WindowItem, width), TK_CONFIG_DONT_SET_DEFAULT}, + "0", Tk_Offset(WindowItem, width), TK_CONFIG_DONT_SET_DEFAULT, NULL}, {TK_CONFIG_WINDOW, "-window", NULL, NULL, - NULL, Tk_Offset(WindowItem, tkwin), TK_CONFIG_NULL_OK}, - {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} + NULL, Tk_Offset(WindowItem, tkwin), TK_CONFIG_NULL_OK, NULL}, + {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL} }; /* @@ -71,10 +68,10 @@ static void ComputeWindowBbox(Tk_Canvas canvas, WindowItem *winItemPtr); static int ConfigureWinItem(Tcl_Interp *interp, Tk_Canvas canvas, Tk_Item *itemPtr, int objc, - Tcl_Obj *CONST objv[], int flags); + Tcl_Obj *const objv[], int flags); static int CreateWinItem(Tcl_Interp *interp, Tk_Canvas canvas, struct Tk_Item *itemPtr, - int objc, Tcl_Obj *CONST objv[]); + int objc, Tcl_Obj *const objv[]); static void DeleteWinItem(Tk_Canvas canvas, Tk_Item *itemPtr, Display *display); static void DisplayWinItem(Tk_Canvas canvas, @@ -87,7 +84,7 @@ static void TranslateWinItem(Tk_Canvas canvas, Tk_Item *itemPtr, double deltaX, double deltaY); static int WinItemCoords(Tcl_Interp *interp, Tk_Canvas canvas, Tk_Item *itemPtr, int objc, - Tcl_Obj *CONST objv[]); + Tcl_Obj *const objv[]); static void WinItemLostSlaveProc(ClientData clientData, Tk_Window tkwin); static void WinItemRequestProc(ClientData clientData, @@ -133,6 +130,7 @@ Tk_ItemType tkWindowType = { NULL, /* insertProc */ NULL, /* dTextProc */ NULL, /* nextPtr */ + NULL, 0, NULL, NULL }; /* @@ -172,13 +170,13 @@ CreateWinItem( Tk_Item *itemPtr, /* Record to hold new item; header has been * initialized by caller. */ int objc, /* Number of arguments in objv. */ - Tcl_Obj *CONST objv[]) /* Arguments describing window. */ + Tcl_Obj *const objv[]) /* Arguments describing window. */ { WindowItem *winItemPtr = (WindowItem *) itemPtr; int i; if (objc == 0) { - Tcl_Panic("canvas did not pass any coords\n"); + Tcl_Panic("canvas did not pass any coords"); } /* @@ -199,7 +197,8 @@ CreateWinItem( if (objc == 1) { i = 1; } else { - char *arg = Tcl_GetString(objv[1]); + const char *arg = Tcl_GetString(objv[1]); + i = 2; if ((arg[0] == '-') && (arg[1] >= 'a') && (arg[1] <= 'z')) { i = 1; @@ -242,27 +241,26 @@ WinItemCoords( Tk_Item *itemPtr, /* Item whose coordinates are to be read or * modified. */ int objc, /* Number of coordinates supplied in objv. */ - Tcl_Obj *CONST objv[]) /* Array of coordinates: x1, y1, x2, y2, ... */ + Tcl_Obj *const objv[]) /* Array of coordinates: x1, y1, x2, y2, ... */ { WindowItem *winItemPtr = (WindowItem *) itemPtr; if (objc == 0) { - Tcl_Obj *obj = Tcl_NewObj(); - Tcl_Obj *subobj = Tcl_NewDoubleObj(winItemPtr->x); - Tcl_ListObjAppendElement(interp, obj, subobj); - subobj = Tcl_NewDoubleObj(winItemPtr->y); - Tcl_ListObjAppendElement(interp, obj, subobj); - Tcl_SetObjResult(interp, obj); + Tcl_Obj *objs[2]; + + objs[0] = Tcl_NewDoubleObj(winItemPtr->x); + objs[1] = Tcl_NewDoubleObj(winItemPtr->y); + Tcl_SetObjResult(interp, Tcl_NewListObj(2, objs)); } else if (objc < 3) { if (objc==1) { if (Tcl_ListObjGetElements(interp, objv[0], &objc, (Tcl_Obj ***) &objv) != TCL_OK) { return TCL_ERROR; } else if (objc != 2) { - char buf[64 + TCL_INTEGER_SPACE]; - - sprintf(buf, "wrong # coordinates: expected 2, got %d", objc); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "wrong # coordinates: expected 2, got %d", objc)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "WINDOW", + NULL); return TCL_ERROR; } } @@ -273,10 +271,9 @@ WinItemCoords( } ComputeWindowBbox(canvas, winItemPtr); } else { - char buf[64 + TCL_INTEGER_SPACE]; - - sprintf(buf, "wrong # coordinates: expected 0 or 2, got %d", objc); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "wrong # coordinates: expected 0 or 2, got %d", objc)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "WINDOW", NULL); return TCL_ERROR; } return TCL_OK; @@ -306,7 +303,7 @@ ConfigureWinItem( Tk_Canvas canvas, /* Canvas containing itemPtr. */ Tk_Item *itemPtr, /* Window item to reconfigure. */ int objc, /* Number of elements in objv. */ - Tcl_Obj *CONST objv[], /* Arguments describing things to configure. */ + Tcl_Obj *const objv[], /* Arguments describing things to configure. */ int flags) /* Flags to pass to Tk_ConfigureWidget. */ { WindowItem *winItemPtr = (WindowItem *) itemPtr; @@ -316,7 +313,7 @@ ConfigureWinItem( oldWindow = winItemPtr->tkwin; canvasTkwin = Tk_CanvasTkwin(canvas); if (TCL_OK != Tk_ConfigureWidget(interp, canvasTkwin, configSpecs, objc, - (CONST char **) objv, (char *) winItemPtr, flags|TK_CONFIG_OBJS)) { + (const char **) objv, (char *) winItemPtr, flags|TK_CONFIG_OBJS)) { return TCL_ERROR; } @@ -327,8 +324,8 @@ ConfigureWinItem( if (oldWindow != winItemPtr->tkwin) { if (oldWindow != NULL) { Tk_DeleteEventHandler(oldWindow, StructureNotifyMask, - WinItemStructureProc, (ClientData) winItemPtr); - Tk_ManageGeometry(oldWindow, NULL, (ClientData) NULL); + WinItemStructureProc, winItemPtr); + Tk_ManageGeometry(oldWindow, NULL, NULL); Tk_UnmaintainGeometry(oldWindow, canvasTkwin); Tk_UnmapWindow(oldWindow); } @@ -343,30 +340,23 @@ ConfigureWinItem( */ parent = Tk_Parent(winItemPtr->tkwin); - for (ancestor = canvasTkwin; ; - ancestor = Tk_Parent(ancestor)) { + for (ancestor = canvasTkwin ;; ancestor = Tk_Parent(ancestor)) { if (ancestor == parent) { break; } - if (((Tk_FakeWin *) (ancestor))->flags & TK_TOP_HIERARCHY) { - badWindow: - Tcl_AppendResult(interp, "can't use ", - Tk_PathName(winItemPtr->tkwin), - " in a window item of this canvas", NULL); - winItemPtr->tkwin = NULL; - return TCL_ERROR; + if (((Tk_FakeWin *) ancestor)->flags & TK_TOP_HIERARCHY) { + goto badWindow; } } - if (((Tk_FakeWin *) (winItemPtr->tkwin))->flags & TK_TOP_HIERARCHY) { + if (((Tk_FakeWin *) winItemPtr->tkwin)->flags & TK_TOP_HIERARCHY){ goto badWindow; } if (winItemPtr->tkwin == canvasTkwin) { goto badWindow; } Tk_CreateEventHandler(winItemPtr->tkwin, StructureNotifyMask, - WinItemStructureProc, (ClientData) winItemPtr); - Tk_ManageGeometry(winItemPtr->tkwin, &canvasGeomType, - (ClientData) winItemPtr); + WinItemStructureProc, winItemPtr); + Tk_ManageGeometry(winItemPtr->tkwin, &canvasGeomType, winItemPtr); } } if ((winItemPtr->tkwin != NULL) @@ -379,8 +369,15 @@ ConfigureWinItem( } ComputeWindowBbox(canvas, winItemPtr); - return TCL_OK; + + badWindow: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't use %s in a window item of this canvas", + Tk_PathName(winItemPtr->tkwin))); + Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "HIERARCHY", NULL); + winItemPtr->tkwin = NULL; + return TCL_ERROR; } /* @@ -411,9 +408,8 @@ DeleteWinItem( if (winItemPtr->tkwin != NULL) { Tk_DeleteEventHandler(winItemPtr->tkwin, StructureNotifyMask, - WinItemStructureProc, (ClientData) winItemPtr); - Tk_ManageGeometry(winItemPtr->tkwin, NULL, - (ClientData) NULL); + WinItemStructureProc, winItemPtr); + Tk_ManageGeometry(winItemPtr->tkwin, NULL, NULL); if (canvasTkwin != Tk_Parent(winItemPtr->tkwin)) { Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin); } @@ -451,7 +447,7 @@ ComputeWindowBbox( y = (int) (winItemPtr->y + ((winItemPtr->y >= 0) ? 0.5 : - 0.5)); if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } if ((winItemPtr->tkwin == NULL) || (state == TK_STATE_HIDDEN)) { /* @@ -576,7 +572,7 @@ DisplayWinItem( return; } if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } /* @@ -757,8 +753,7 @@ xerrorhandler( { return 0; } -#endif - +#endif /* X_GetImage */ /* *-------------------------------------------------------------- @@ -788,8 +783,7 @@ WinItemToPostscript( * information; 0 means final Postscript is * being created. */ { - WindowItem *winItemPtr = (WindowItem *)itemPtr; - + WindowItem *winItemPtr = (WindowItem *) itemPtr; double x, y; int width, height; Tk_Window tkwin = winItemPtr->tkwin; @@ -832,45 +826,44 @@ CanvasPsWindow( double x, double y, /* origin of window. */ int width, int height) /* width/height of window. */ { - char buffer[256]; XImage *ximage; int result; - Tcl_DString buffer1, buffer2; #ifdef X_GetImage Tk_ErrorHandler handle; #endif + Tcl_Obj *cmdObj, *psObj; + Tcl_InterpState interpState = Tcl_SaveInterpState(interp, TCL_OK); - sprintf(buffer, "\n%%%% %s item (%s, %d x %d)\n%.15g %.15g translate\n", + /* + * Locate the subwindow within the wider window. + */ + + psObj = Tcl_ObjPrintf( + "\n%%%% %s item (%s, %d x %d)\n" /* Comment */ + "%.15g %.15g translate\n", /* Position */ Tk_Class(tkwin), Tk_PathName(tkwin), width, height, x, y); - Tcl_AppendResult(interp, buffer, NULL); /* * First try if the widget has its own "postscript" command. If it exists, * this will produce much better postscript than when a pixmap is used. */ - Tcl_DStringInit(&buffer1); - Tcl_DStringInit(&buffer2); - Tcl_DStringGetResult(interp, &buffer2); - sprintf(buffer, "%s postscript -prolog 0\n", Tk_PathName(tkwin)); - result = Tcl_Eval(interp, buffer); - Tcl_DStringGetResult(interp, &buffer1); - Tcl_DStringResult(interp, &buffer2); - Tcl_DStringFree(&buffer2); + Tcl_ResetResult(interp); + cmdObj = Tcl_ObjPrintf("%s postscript -prolog 0", Tk_PathName(tkwin)); + Tcl_IncrRefCount(cmdObj); + result = Tcl_EvalObjEx(interp, cmdObj, 0); + Tcl_DecrRefCount(cmdObj); if (result == TCL_OK) { - Tcl_AppendResult(interp, "50 dict begin\nsave\ngsave\n", NULL); - sprintf(buffer, "0 %d moveto %d 0 rlineto 0 -%d rlineto -%d", - height, width, height, width); - Tcl_AppendResult(interp, buffer, NULL); - Tcl_AppendResult(interp, " 0 rlineto closepath\n", + Tcl_AppendPrintfToObj(psObj, + "50 dict begin\nsave\ngsave\n" + "0 %d moveto %d 0 rlineto 0 -%d rlineto -%d 0 rlineto closepath\n" "1.000 1.000 1.000 setrgbcolor AdjustColor\nfill\ngrestore\n", - Tcl_DStringValue(&buffer1), "\nrestore\nend\n\n\n", NULL); - Tcl_DStringFree(&buffer1); - - return result; + height, width, height, width); + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); + Tcl_AppendToObj(psObj, "\nrestore\nend\n\n\n", -1); + goto done; } - Tcl_DStringFree(&buffer1); /* * If the window is off the screen it will generate a BadMatch/XError. We @@ -879,7 +872,7 @@ CanvasPsWindow( #ifdef X_GetImage handle = Tk_CreateErrorHandler(Tk_Display(tkwin), BadMatch, - X_GetImage, -1, xerrorhandler, (ClientData) tkwin); + X_GetImage, -1, xerrorhandler, tkwin); #endif /* @@ -888,20 +881,34 @@ CanvasPsWindow( */ ximage = XGetImage(Tk_Display(tkwin), Tk_WindowId(tkwin), 0, 0, - (unsigned int)width, (unsigned int)height, AllPlanes, ZPixmap); + (unsigned) width, (unsigned) height, AllPlanes, ZPixmap); #ifdef X_GetImage Tk_DeleteErrorHandler(handle); #endif if (ximage == NULL) { - return TCL_OK; + result = TCL_OK; + } else { + Tcl_ResetResult(interp); + result = TkPostscriptImage(interp, tkwin, Canvas(canvas)->psInfo, + ximage, 0, 0, width, height); + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); + XDestroyImage(ximage); } - result = TkPostscriptImage(interp, tkwin, - ((TkCanvas *)canvas)->psInfo, ximage, 0, 0, width, height); + /* + * Plug the accumulated postscript back into the result. + */ - XDestroyImage(ximage); + done: + if (result == TCL_OK) { + (void) Tcl_RestoreInterpState(interp, interpState); + Tcl_AppendObjToObj(Tcl_GetObjResult(interp), psObj); + } else { + Tcl_DiscardInterpState(interpState); + } + Tcl_DecrRefCount(psObj); return result; } @@ -1000,7 +1007,7 @@ WinItemStructureProc( ClientData clientData, /* Pointer to record describing window item. */ XEvent *eventPtr) /* Describes what just happened. */ { - WindowItem *winItemPtr = (WindowItem *) clientData; + WindowItem *winItemPtr = clientData; if (eventPtr->type == DestroyNotify) { winItemPtr->tkwin = NULL; @@ -1030,7 +1037,7 @@ WinItemRequestProc( ClientData clientData, /* Pointer to record for window item. */ Tk_Window tkwin) /* Window that changed its desired size. */ { - WindowItem *winItemPtr = (WindowItem *) clientData; + WindowItem *winItemPtr = clientData; ComputeWindowBbox(winItemPtr->canvas, winItemPtr); @@ -1067,11 +1074,11 @@ WinItemLostSlaveProc( * was stolen away. */ Tk_Window tkwin) /* Tk's handle for the slave window. */ { - WindowItem *winItemPtr = (WindowItem *) clientData; + WindowItem *winItemPtr = clientData; Tk_Window canvasTkwin = Tk_CanvasTkwin(winItemPtr->canvas); Tk_DeleteEventHandler(winItemPtr->tkwin, StructureNotifyMask, - WinItemStructureProc, (ClientData) winItemPtr); + WinItemStructureProc, winItemPtr); if (canvasTkwin != Tk_Parent(winItemPtr->tkwin)) { Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin); } diff --git a/generic/tkCanvas.c b/generic/tkCanvas.c index dbb927b..414c6fb 100644 --- a/generic/tkCanvas.c +++ b/generic/tkCanvas.c @@ -75,7 +75,7 @@ typedef struct TagSearch { * return NULL. */ int type; /* Search type (see #defs below) */ int id; /* Item id for searches by id */ - char *string; /* Tag expression string */ + const char *string; /* Tag expression string */ int stringIndex; /* Current position in string scan */ int stringLength; /* Length of tag expression string */ char *rewritebuffer; /* Tag string (after removing escapes) */ @@ -100,112 +100,109 @@ typedef struct TagSearch { * Custom option for handling "-state" and "-offset" */ -static Tk_CustomOption stateOption = { - (Tk_OptionParseProc *) TkStateParseProc, - TkStatePrintProc, - (ClientData) NULL /* only "normal" and "disabled" */ +static const Tk_CustomOption stateOption = { + TkStateParseProc, TkStatePrintProc, + NULL /* Only "normal" and "disabled". */ }; -static Tk_CustomOption offsetOption = { - (Tk_OptionParseProc *) TkOffsetParseProc, - TkOffsetPrintProc, - (ClientData) TK_OFFSET_RELATIVE +static const Tk_CustomOption offsetOption = { + TkOffsetParseProc, TkOffsetPrintProc, INT2PTR(TK_OFFSET_RELATIVE) }; /* * Information used for argv parsing. */ -static Tk_ConfigSpec configSpecs[] = { +static const Tk_ConfigSpec configSpecs[] = { {TK_CONFIG_BORDER, "-background", "background", "Background", DEF_CANVAS_BG_COLOR, Tk_Offset(TkCanvas, bgBorder), - TK_CONFIG_COLOR_ONLY}, + TK_CONFIG_COLOR_ONLY, NULL}, {TK_CONFIG_BORDER, "-background", "background", "Background", DEF_CANVAS_BG_MONO, Tk_Offset(TkCanvas, bgBorder), - TK_CONFIG_MONO_ONLY}, - {TK_CONFIG_SYNONYM, "-bd", "borderWidth", NULL, NULL, 0, 0}, - {TK_CONFIG_SYNONYM, "-bg", "background", NULL, NULL, 0, 0}, + TK_CONFIG_MONO_ONLY, NULL}, + {TK_CONFIG_SYNONYM, "-bd", "borderWidth", NULL, NULL, 0, 0, NULL}, + {TK_CONFIG_SYNONYM, "-bg", "background", NULL, NULL, 0, 0, NULL}, {TK_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", - DEF_CANVAS_BORDER_WIDTH, Tk_Offset(TkCanvas, borderWidth), 0}, + DEF_CANVAS_BORDER_WIDTH, Tk_Offset(TkCanvas, borderWidth), 0, NULL}, {TK_CONFIG_DOUBLE, "-closeenough", "closeEnough", "CloseEnough", - DEF_CANVAS_CLOSE_ENOUGH, Tk_Offset(TkCanvas, closeEnough), 0}, + DEF_CANVAS_CLOSE_ENOUGH, Tk_Offset(TkCanvas, closeEnough), 0, NULL}, {TK_CONFIG_BOOLEAN, "-confine", "confine", "Confine", - DEF_CANVAS_CONFINE, Tk_Offset(TkCanvas, confine), 0}, + DEF_CANVAS_CONFINE, Tk_Offset(TkCanvas, confine), 0, NULL}, {TK_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor", - DEF_CANVAS_CURSOR, Tk_Offset(TkCanvas, cursor), TK_CONFIG_NULL_OK}, + DEF_CANVAS_CURSOR, Tk_Offset(TkCanvas, cursor), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_PIXELS, "-height", "height", "Height", - DEF_CANVAS_HEIGHT, Tk_Offset(TkCanvas, height), 0}, + DEF_CANVAS_HEIGHT, Tk_Offset(TkCanvas, height), 0, NULL}, {TK_CONFIG_COLOR, "-highlightbackground", "highlightBackground", "HighlightBackground", DEF_CANVAS_HIGHLIGHT_BG, - Tk_Offset(TkCanvas, highlightBgColorPtr), 0}, + Tk_Offset(TkCanvas, highlightBgColorPtr), 0, NULL}, {TK_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", - DEF_CANVAS_HIGHLIGHT, Tk_Offset(TkCanvas, highlightColorPtr), 0}, + DEF_CANVAS_HIGHLIGHT, Tk_Offset(TkCanvas, highlightColorPtr), 0, NULL}, {TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness", "HighlightThickness", - DEF_CANVAS_HIGHLIGHT_WIDTH, Tk_Offset(TkCanvas, highlightWidth), 0}, + DEF_CANVAS_HIGHLIGHT_WIDTH, Tk_Offset(TkCanvas, highlightWidth), 0, NULL}, {TK_CONFIG_BORDER, "-insertbackground", "insertBackground", "Foreground", - DEF_CANVAS_INSERT_BG, Tk_Offset(TkCanvas, textInfo.insertBorder), 0}, + DEF_CANVAS_INSERT_BG, Tk_Offset(TkCanvas, textInfo.insertBorder), 0, NULL}, {TK_CONFIG_PIXELS, "-insertborderwidth", "insertBorderWidth", "BorderWidth", DEF_CANVAS_INSERT_BD_COLOR, - Tk_Offset(TkCanvas, textInfo.insertBorderWidth), TK_CONFIG_COLOR_ONLY}, + Tk_Offset(TkCanvas, textInfo.insertBorderWidth), TK_CONFIG_COLOR_ONLY, NULL}, {TK_CONFIG_PIXELS, "-insertborderwidth", "insertBorderWidth", "BorderWidth", DEF_CANVAS_INSERT_BD_MONO, - Tk_Offset(TkCanvas, textInfo.insertBorderWidth), TK_CONFIG_MONO_ONLY}, + Tk_Offset(TkCanvas, textInfo.insertBorderWidth), TK_CONFIG_MONO_ONLY, NULL}, {TK_CONFIG_INT, "-insertofftime", "insertOffTime", "OffTime", - DEF_CANVAS_INSERT_OFF_TIME, Tk_Offset(TkCanvas, insertOffTime), 0}, + DEF_CANVAS_INSERT_OFF_TIME, Tk_Offset(TkCanvas, insertOffTime), 0, NULL}, {TK_CONFIG_INT, "-insertontime", "insertOnTime", "OnTime", - DEF_CANVAS_INSERT_ON_TIME, Tk_Offset(TkCanvas, insertOnTime), 0}, + DEF_CANVAS_INSERT_ON_TIME, Tk_Offset(TkCanvas, insertOnTime), 0, NULL}, {TK_CONFIG_PIXELS, "-insertwidth", "insertWidth", "InsertWidth", - DEF_CANVAS_INSERT_WIDTH, Tk_Offset(TkCanvas, textInfo.insertWidth), 0}, + DEF_CANVAS_INSERT_WIDTH, Tk_Offset(TkCanvas, textInfo.insertWidth), 0, NULL}, {TK_CONFIG_CUSTOM, "-offset", "offset", "Offset", "0,0", Tk_Offset(TkCanvas, tsoffset),TK_CONFIG_DONT_SET_DEFAULT, &offsetOption}, {TK_CONFIG_RELIEF, "-relief", "relief", "Relief", - DEF_CANVAS_RELIEF, Tk_Offset(TkCanvas, relief), 0}, + DEF_CANVAS_RELIEF, Tk_Offset(TkCanvas, relief), 0, NULL}, {TK_CONFIG_STRING, "-scrollregion", "scrollRegion", "ScrollRegion", DEF_CANVAS_SCROLL_REGION, Tk_Offset(TkCanvas, regionString), - TK_CONFIG_NULL_OK}, + TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_BORDER, "-selectbackground", "selectBackground", "Foreground", DEF_CANVAS_SELECT_COLOR, Tk_Offset(TkCanvas, textInfo.selBorder), - TK_CONFIG_COLOR_ONLY}, + TK_CONFIG_COLOR_ONLY, NULL}, {TK_CONFIG_BORDER, "-selectbackground", "selectBackground", "Foreground", DEF_CANVAS_SELECT_MONO, Tk_Offset(TkCanvas, textInfo.selBorder), - TK_CONFIG_MONO_ONLY}, + TK_CONFIG_MONO_ONLY, NULL}, {TK_CONFIG_PIXELS, "-selectborderwidth", "selectBorderWidth", "BorderWidth", DEF_CANVAS_SELECT_BD_COLOR, - Tk_Offset(TkCanvas, textInfo.selBorderWidth), TK_CONFIG_COLOR_ONLY}, + Tk_Offset(TkCanvas, textInfo.selBorderWidth), TK_CONFIG_COLOR_ONLY, NULL}, {TK_CONFIG_PIXELS, "-selectborderwidth", "selectBorderWidth", "BorderWidth", DEF_CANVAS_SELECT_BD_MONO, Tk_Offset(TkCanvas, textInfo.selBorderWidth), - TK_CONFIG_MONO_ONLY}, + TK_CONFIG_MONO_ONLY, NULL}, {TK_CONFIG_COLOR, "-selectforeground", "selectForeground", "Background", DEF_CANVAS_SELECT_FG_COLOR, Tk_Offset(TkCanvas, textInfo.selFgColorPtr), - TK_CONFIG_COLOR_ONLY|TK_CONFIG_NULL_OK}, + TK_CONFIG_COLOR_ONLY|TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_COLOR, "-selectforeground", "selectForeground", "Background", DEF_CANVAS_SELECT_FG_MONO, Tk_Offset(TkCanvas, textInfo.selFgColorPtr), - TK_CONFIG_MONO_ONLY|TK_CONFIG_NULL_OK}, + TK_CONFIG_MONO_ONLY|TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_CUSTOM, "-state", "state", "State", "normal", Tk_Offset(TkCanvas, canvas_state), TK_CONFIG_DONT_SET_DEFAULT, &stateOption}, {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus", DEF_CANVAS_TAKE_FOCUS, Tk_Offset(TkCanvas, takeFocus), - TK_CONFIG_NULL_OK}, + TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_PIXELS, "-width", "width", "Width", - DEF_CANVAS_WIDTH, Tk_Offset(TkCanvas, width), 0}, + DEF_CANVAS_WIDTH, Tk_Offset(TkCanvas, width), 0, NULL}, {TK_CONFIG_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand", DEF_CANVAS_X_SCROLL_CMD, Tk_Offset(TkCanvas, xScrollCmd), - TK_CONFIG_NULL_OK}, + TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_PIXELS, "-xscrollincrement", "xScrollIncrement", "ScrollIncrement", DEF_CANVAS_X_SCROLL_INCREMENT, Tk_Offset(TkCanvas, xScrollIncrement), - 0}, + 0, NULL}, {TK_CONFIG_STRING, "-yscrollcommand", "yScrollCommand", "ScrollCommand", DEF_CANVAS_Y_SCROLL_CMD, Tk_Offset(TkCanvas, yScrollCmd), - TK_CONFIG_NULL_OK}, + TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_PIXELS, "-yscrollincrement", "yScrollIncrement", "ScrollIncrement", DEF_CANVAS_Y_SCROLL_INCREMENT, Tk_Offset(TkCanvas, yScrollIncrement), - 0}, - {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} + 0, NULL}, + {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL} }; /* @@ -213,8 +210,9 @@ static Tk_ConfigSpec configSpecs[] = { * protected by typeListMutex. */ -static Tk_ItemType *typeList = NULL; /* NULL means initialization hasn't - * been done yet. */ +static Tk_ItemType *typeList = NULL; + /* NULL means initialization hasn't been done + * yet. */ TCL_DECLARE_MUTEX(typeListMutex) #ifndef USE_OLD_TAG_SEARCH @@ -264,32 +262,31 @@ static void CanvasSetOrigin(TkCanvas *canvasPtr, static void CanvasUpdateScrollbars(TkCanvas *canvasPtr); static int CanvasWidgetCmd(ClientData clientData, Tcl_Interp *interp, int argc, - Tcl_Obj *CONST *argv); -static void CanvasWorldChanged( - ClientData instanceData); + Tcl_Obj *const *argv); +static void CanvasWorldChanged(ClientData instanceData); static int ConfigureCanvas(Tcl_Interp *interp, TkCanvas *canvasPtr, int argc, - Tcl_Obj *CONST *argv, int flags); + Tcl_Obj *const *argv, int flags); static void DestroyCanvas(char *memPtr); static void DisplayCanvas(ClientData clientData); -static void DoItem(Tcl_Interp *interp, +static void DoItem(Tcl_Obj *accumObj, Tk_Item *itemPtr, Tk_Uid tag); -static void EventuallyRedrawItem(Tk_Canvas canvas, +static void EventuallyRedrawItem(TkCanvas *canvasPtr, Tk_Item *itemPtr); #ifdef USE_OLD_TAG_SEARCH static int FindItems(Tcl_Interp *interp, TkCanvas *canvasPtr, - int argc, Tcl_Obj *CONST *argv, + int argc, Tcl_Obj *const *argv, Tcl_Obj *newTagObj, int first); #else /* USE_OLD_TAG_SEARCH */ static int FindItems(Tcl_Interp *interp, TkCanvas *canvasPtr, - int argc, Tcl_Obj *CONST *argv, + int argc, Tcl_Obj *const *argv, Tcl_Obj *newTagObj, int first, TagSearch **searchPtrPtr); #endif /* USE_OLD_TAG_SEARCH */ static int FindArea(Tcl_Interp *interp, TkCanvas *canvasPtr, - Tcl_Obj *CONST *argv, Tk_Uid uid, int enclosed); + Tcl_Obj *const *argv, Tk_Uid uid, int enclosed); static double GridAlign(double coord, double spacing); -static CONST char** TkGetStringsFromObjs(int argc, Tcl_Obj *CONST *objv); +static const char** TkGetStringsFromObjs(int argc, Tcl_Obj *const *objv); static void InitCanvas(void); #ifdef USE_OLD_TAG_SEARCH static Tk_Item * NextItem(TagSearch *searchPtr); @@ -323,9 +320,11 @@ static Tk_Item * TagSearchNext(TagSearch *searchPtr); * that can be invoked from generic window code. */ -static Tk_ClassProcs canvasClass = { +static const Tk_ClassProcs canvasClass = { sizeof(Tk_ClassProcs), /* size */ CanvasWorldChanged, /* worldChangedProc */ + NULL, /* createProc */ + NULL /* modalProc */ }; /* @@ -334,10 +333,14 @@ static Tk_ClassProcs canvasClass = { #ifdef USE_OLD_TAG_SEARCH #define FIRST_CANVAS_ITEM_MATCHING(objPtr,searchPtrPtr,errorExitClause) \ - (itemPtr) = StartTagSearch(canvasPtr,(objPtr),&search) + itemPtr = StartTagSearch(canvasPtr,(objPtr),&search) #define FOR_EVERY_CANVAS_ITEM_MATCHING(objPtr,searchPtrPtr,errorExitClause) \ - for ((itemPtr) = StartTagSearch(canvasPtr, (objPtr), &search); \ - (itemPtr) != NULL; (itemPtr) = NextItem(&search)) + for (itemPtr = StartTagSearch(canvasPtr, (objPtr), &search); \ + itemPtr != NULL; itemPtr = NextItem(&search)) +#define FIND_ITEMS(objPtr, n) \ + FindItems(interp, canvasPtr, objc, objv, (objPtr), (n)) +#define RELINK_ITEMS(objPtr, itemPtr) \ + RelinkItems(canvasPtr, (objPtr), (itemPtr)) #else /* USE_OLD_TAG_SEARCH */ #define FIRST_CANVAS_ITEM_MATCHING(objPtr,searchPtrPtr,errorExitClause) \ if ((result=TagSearchScan(canvasPtr,(objPtr),(searchPtrPtr))) != TCL_OK){ \ @@ -350,8 +353,266 @@ static Tk_ClassProcs canvasClass = { } \ for (itemPtr = TagSearchFirst(*(searchPtrPtr)); \ itemPtr != NULL; itemPtr = TagSearchNext(*(searchPtrPtr))) +#define FIND_ITEMS(objPtr, n) \ + FindItems(interp, canvasPtr, objc, objv, (objPtr), (n), &searchPtr) +#define RELINK_ITEMS(objPtr, itemPtr) \ + result = RelinkItems(canvasPtr, (objPtr), (itemPtr), &searchPtr) #endif /* USE_OLD_TAG_SEARCH */ + +/* + * ---------------------------------------------------------------------- + * + * AlwaysRedraw, ItemConfigure, ItemCoords, etc. -- + * + * Helper functions that make access to canvas item functions simpler. + * Note that these are all inline functions. + * + * ---------------------------------------------------------------------- + */ + +static inline int +AlwaysRedraw( + Tk_Item *itemPtr) +{ + return itemPtr->typePtr->alwaysRedraw & 1; +} + +static inline int +ItemConfigure( + TkCanvas *canvasPtr, + Tk_Item *itemPtr, + int objc, + Tcl_Obj *const objv[]) +{ + Tcl_Interp *interp = canvasPtr->interp; + int result; + + if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) { + result = itemPtr->typePtr->configProc(interp, (Tk_Canvas) canvasPtr, + itemPtr, objc, objv, TK_CONFIG_ARGV_ONLY); + } else { + const char **args = TkGetStringsFromObjs(objc, objv); + + result = itemPtr->typePtr->configProc(interp, (Tk_Canvas) canvasPtr, + itemPtr, objc, (Tcl_Obj **) args, TK_CONFIG_ARGV_ONLY); + if (args != NULL) { + ckfree(args); + } + } + return result; +} + +static inline int +ItemConfigInfo( + TkCanvas *canvasPtr, + Tk_Item *itemPtr, + Tcl_Obj *fieldName) +{ + return Tk_ConfigureInfo(canvasPtr->interp, canvasPtr->tkwin, + itemPtr->typePtr->configSpecs, (char *) itemPtr, + (fieldName ? Tcl_GetString(fieldName) : NULL), 0); +} + +static inline int +ItemConfigValue( + TkCanvas *canvasPtr, + Tk_Item *itemPtr, + Tcl_Obj *fieldName) +{ + return Tk_ConfigureValue(canvasPtr->interp, canvasPtr->tkwin, + itemPtr->typePtr->configSpecs, (char *) itemPtr, + Tcl_GetString(fieldName), 0); +} +static inline int +ItemCoords( + TkCanvas *canvasPtr, + Tk_Item *itemPtr, + int objc, + Tcl_Obj *const objv[]) +{ + Tcl_Interp *interp = canvasPtr->interp; + int result; + + if (itemPtr->typePtr->coordProc == NULL) { + result = TCL_OK; + } else if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) { + result = itemPtr->typePtr->coordProc(interp, (Tk_Canvas) canvasPtr, + itemPtr, objc, objv); + } else { + const char **args = TkGetStringsFromObjs(objc, objv); + + result = itemPtr->typePtr->coordProc(interp, (Tk_Canvas) canvasPtr, + itemPtr, objc, (Tcl_Obj **) args); + if (args != NULL) { + ckfree(args); + } + } + return result; +} + +static inline int +ItemCreate( + TkCanvas *canvasPtr, + Tk_Item *itemPtr, /* Warning: incomplete! typePtr field must be + * set by this point. */ + int objc, + Tcl_Obj *const objv[]) +{ + Tcl_Interp *interp = canvasPtr->interp; + int result; + + if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) { + result = itemPtr->typePtr->createProc(interp, (Tk_Canvas) canvasPtr, + itemPtr, objc-3, objv+3); + } else { + const char **args = TkGetStringsFromObjs(objc-3, objv+3); + + result = itemPtr->typePtr->createProc(interp, (Tk_Canvas) canvasPtr, + itemPtr, objc-3, (Tcl_Obj **) args); + if (args != NULL) { + ckfree(args); + } + } + return result; +} + +static inline void +ItemCursor( + TkCanvas *canvasPtr, + Tk_Item *itemPtr, + int index) +{ + itemPtr->typePtr->icursorProc((Tk_Canvas) canvasPtr, itemPtr, index); +} + +static inline void +ItemDelChars( + TkCanvas *canvasPtr, + Tk_Item *itemPtr, + int first, + int last) +{ + itemPtr->typePtr->dCharsProc((Tk_Canvas) canvasPtr, itemPtr, first, last); +} + +static inline void +ItemDelete( + TkCanvas *canvasPtr, + Tk_Item *itemPtr) +{ + itemPtr->typePtr->deleteProc((Tk_Canvas) canvasPtr, itemPtr, + canvasPtr->display); +} + +static inline void +ItemDisplay( + TkCanvas *canvasPtr, + Tk_Item *itemPtr, + Pixmap pixmap, + int screenX1, int screenY1, + int width, int height) +{ + itemPtr->typePtr->displayProc((Tk_Canvas) canvasPtr, itemPtr, + canvasPtr->display, pixmap, screenX1, screenY1, width, height); +} + +static inline int +ItemIndex( + TkCanvas *canvasPtr, + Tk_Item *itemPtr, + Tcl_Obj *objPtr, + int *indexPtr) +{ + Tcl_Interp *interp = canvasPtr->interp; + + if (itemPtr->typePtr->indexProc == NULL) { + return TCL_OK; + } else if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) { + return itemPtr->typePtr->indexProc(interp, (Tk_Canvas) canvasPtr, + itemPtr, objPtr, indexPtr); + } else { + return itemPtr->typePtr->indexProc(interp, (Tk_Canvas) canvasPtr, + itemPtr, (Tcl_Obj *) Tcl_GetString(objPtr), indexPtr); + } +} + +static inline void +ItemInsert( + TkCanvas *canvasPtr, + Tk_Item *itemPtr, + int beforeThis, + Tcl_Obj *toInsert) +{ + if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) { + itemPtr->typePtr->insertProc((Tk_Canvas) canvasPtr, itemPtr, + beforeThis, toInsert); + } else { + itemPtr->typePtr->insertProc((Tk_Canvas) canvasPtr, itemPtr, + beforeThis, (Tcl_Obj *) Tcl_GetString(toInsert)); + } +} + +static inline int +ItemOverlap( + TkCanvas *canvasPtr, + Tk_Item *itemPtr, + double rect[]) +{ + return itemPtr->typePtr->areaProc((Tk_Canvas) canvasPtr, itemPtr, rect); +} + +static inline double +ItemPoint( + TkCanvas *canvasPtr, + Tk_Item *itemPtr, + double coords[], + double halo) +{ + double dist; + + dist = itemPtr->typePtr->pointProc((Tk_Canvas) canvasPtr, itemPtr, + coords) - halo; + return (dist < 0.0) ? 0.0 : dist; +} + +static inline void +ItemScale( + TkCanvas *canvasPtr, + Tk_Item *itemPtr, + double xOrigin, double yOrigin, + double xScale, double yScale) +{ + itemPtr->typePtr->scaleProc((Tk_Canvas) canvasPtr, itemPtr, + xOrigin, yOrigin, xScale, yScale); +} + +static inline int +ItemSelection( + TkCanvas *canvasPtr, + Tk_Item *itemPtr, + int offset, + char *buffer, + int maxBytes) +{ + if (itemPtr == NULL || itemPtr->typePtr->selectionProc == NULL) { + return -1; + } + + return itemPtr->typePtr->selectionProc((Tk_Canvas) canvasPtr, itemPtr, + offset, buffer, maxBytes); +} + +static inline void +ItemTranslate( + TkCanvas *canvasPtr, + Tk_Item *itemPtr, + double xDelta, + double yDelta) +{ + itemPtr->typePtr->translateProc((Tk_Canvas) canvasPtr, itemPtr, + xDelta, yDelta); +} /* *-------------------------------------------------------------- @@ -375,9 +636,9 @@ Tk_CanvasObjCmd( ClientData clientData, /* Main window associated with interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int argc, /* Number of arguments. */ - Tcl_Obj *CONST argv[]) /* Argument objects. */ + Tcl_Obj *const argv[]) /* Argument objects. */ { - Tk_Window tkwin = (Tk_Window) clientData; + Tk_Window tkwin = clientData; TkCanvas *canvasPtr; Tk_Window newWin; @@ -386,7 +647,7 @@ Tk_CanvasObjCmd( } if (argc < 2) { - Tcl_WrongNumArgs(interp, 1, argv, "pathName ?options?"); + Tcl_WrongNumArgs(interp, 1, argv, "pathName ?-option value ...?"); return TCL_ERROR; } @@ -401,13 +662,13 @@ Tk_CanvasObjCmd( * pointers). */ - canvasPtr = (TkCanvas *) ckalloc(sizeof(TkCanvas)); + canvasPtr = ckalloc(sizeof(TkCanvas)); canvasPtr->tkwin = newWin; canvasPtr->display = Tk_Display(newWin); canvasPtr->interp = interp; canvasPtr->widgetCmd = Tcl_CreateObjCommand(interp, - Tk_PathName(canvasPtr->tkwin), CanvasWidgetCmd, - (ClientData) canvasPtr, CanvasCmdDeletedProc); + Tk_PathName(canvasPtr->tkwin), CanvasWidgetCmd, canvasPtr, + CanvasCmdDeletedProc); canvasPtr->firstItemPtr = NULL; canvasPtr->lastItemPtr = NULL; canvasPtr->borderWidth = 0; @@ -480,21 +741,21 @@ Tk_CanvasObjCmd( Tcl_InitHashTable(&canvasPtr->idTable, TCL_ONE_WORD_KEYS); Tk_SetClass(canvasPtr->tkwin, "Canvas"); - Tk_SetClassProcs(canvasPtr->tkwin, &canvasClass, (ClientData) canvasPtr); + Tk_SetClassProcs(canvasPtr->tkwin, &canvasClass, canvasPtr); Tk_CreateEventHandler(canvasPtr->tkwin, ExposureMask|StructureNotifyMask|FocusChangeMask, - CanvasEventProc, (ClientData) canvasPtr); + CanvasEventProc, canvasPtr); Tk_CreateEventHandler(canvasPtr->tkwin, KeyPressMask|KeyReleaseMask |ButtonPressMask|ButtonReleaseMask|EnterWindowMask |LeaveWindowMask|PointerMotionMask|VirtualEventMask, - CanvasBindProc, (ClientData) canvasPtr); + CanvasBindProc, canvasPtr); Tk_CreateSelHandler(canvasPtr->tkwin, XA_PRIMARY, XA_STRING, - CanvasFetchSelection, (ClientData) canvasPtr, XA_STRING); + CanvasFetchSelection, canvasPtr, XA_STRING); if (ConfigureCanvas(interp, canvasPtr, argc-2, argv+2, 0) != TCL_OK) { goto error; } - Tcl_SetResult(interp, Tk_PathName(canvasPtr->tkwin), TCL_STATIC); + Tcl_SetObjResult(interp, TkNewWindowObj(canvasPtr->tkwin)); return TCL_OK; error: @@ -525,9 +786,9 @@ CanvasWidgetCmd( ClientData clientData, /* Information about canvas widget. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { - TkCanvas *canvasPtr = (TkCanvas *) clientData; + TkCanvas *canvasPtr = clientData; int c, result; Tk_Item *itemPtr = NULL; /* Initialization needed only to prevent * compiler warning. */ @@ -539,15 +800,16 @@ CanvasWidgetCmd( #endif /* USE_OLD_TAG_SEARCH */ int index; - static CONST char *optionStrings[] = { + static const char *const optionStrings[] = { "addtag", "bbox", "bind", "canvasx", "canvasy", "cget", "configure", "coords", "create", "dchars", "delete", "dtag", "find", "focus", "gettags", "icursor", - "index", "insert", "itemcget", "itemconfigure", - "lower", "move", "postscript", "raise", - "scale", "scan", "select", "type", - "xview", "yview", + "imove", "index", "insert", "itemcget", + "itemconfigure", + "lower", "move", "moveto", "postscript", + "raise", "rchars", "scale", "scan", + "select", "type", "xview", "yview", NULL }; enum options { @@ -555,35 +817,32 @@ CanvasWidgetCmd( CANV_CANVASY, CANV_CGET, CANV_CONFIGURE, CANV_COORDS, CANV_CREATE, CANV_DCHARS, CANV_DELETE, CANV_DTAG, CANV_FIND, CANV_FOCUS, CANV_GETTAGS, CANV_ICURSOR, - CANV_INDEX, CANV_INSERT, CANV_ITEMCGET, CANV_ITEMCONFIGURE, - CANV_LOWER, CANV_MOVE, CANV_POSTSCRIPT,CANV_RAISE, - CANV_SCALE, CANV_SCAN, CANV_SELECT, CANV_TYPE, - CANV_XVIEW, CANV_YVIEW + CANV_IMOVE, CANV_INDEX, CANV_INSERT, CANV_ITEMCGET, + CANV_ITEMCONFIGURE, + CANV_LOWER, CANV_MOVE, CANV_MOVETO, CANV_POSTSCRIPT, + CANV_RAISE, CANV_RCHARS, CANV_SCALE, CANV_SCAN, + CANV_SELECT, CANV_TYPE, CANV_XVIEW, CANV_YVIEW }; if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?"); + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0, &index) != TCL_OK) { return TCL_ERROR; } - Tcl_Preserve((ClientData) canvasPtr); + Tcl_Preserve(canvasPtr); result = TCL_OK; switch ((enum options) index) { case CANV_ADDTAG: if (objc < 4) { - Tcl_WrongNumArgs(interp, 2, objv, "tag searchCommand ?arg arg ...?"); + Tcl_WrongNumArgs(interp, 2, objv, "tag searchCommand ?arg ...?"); result = TCL_ERROR; goto done; } -#ifdef USE_OLD_TAG_SEARCH - result = FindItems(interp, canvasPtr, objc, objv, objv[2], 3); -#else /* USE_OLD_TAG_SEARCH */ - result = FindItems(interp, canvasPtr, objc, objv, objv[2], 3, &searchPtr); -#endif /* USE_OLD_TAG_SEARCH */ + result = FIND_ITEMS(objv[2], 3); break; case CANV_BBOX: { @@ -627,10 +886,13 @@ CanvasWidgetCmd( } } if (gotAny) { - char buf[TCL_INTEGER_SPACE * 4]; + Tcl_Obj *resultObjs[4]; - sprintf(buf, "%d %d %d %d", x1, y1, x2, y2); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + resultObjs[0] = Tcl_NewIntObj(x1); + resultObjs[1] = Tcl_NewIntObj(y1); + resultObjs[2] = Tcl_NewIntObj(x2); + resultObjs[3] = Tcl_NewIntObj(y2); + Tcl_SetObjResult(interp, Tcl_NewListObj(4, resultObjs)); } break; } @@ -648,7 +910,7 @@ CanvasWidgetCmd( * tag). */ - object = 0; + object = NULL; #ifdef USE_OLD_TAG_SEARCH if (isdigit(UCHAR(Tcl_GetString(objv[2])[0]))) { int id; @@ -661,19 +923,21 @@ CanvasWidgetCmd( } entryPtr = Tcl_FindHashEntry(&canvasPtr->idTable, (char *) id); if (entryPtr != NULL) { - itemPtr = (Tk_Item *) Tcl_GetHashValue(entryPtr); - object = (ClientData) itemPtr; + itemPtr = Tcl_GetHashValue(entryPtr); + object = itemPtr; } - if (object == 0) { - Tcl_AppendResult(interp, "item \"", Tcl_GetString(objv[2]), - "\" doesn't exist", NULL); + if (object == NULL) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "item \"%s\" doesn't exist", Tcl_GetString(objv[2]))); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "CANVAS_ITEM", + Tcl_GetString(objv[2]), NULL); result = TCL_ERROR; goto done; } } else { - bindByTag: - object = (ClientData) Tk_GetUid(Tcl_GetString(objv[2])); + bindByTag: + object = Tk_GetUid(Tcl_GetString(objv[2])); } #else /* USE_OLD_TAG_SEARCH */ result = TagSearchScan(canvasPtr, objv[2], &searchPtr); @@ -686,13 +950,15 @@ CanvasWidgetCmd( entryPtr = Tcl_FindHashEntry(&canvasPtr->idTable, (char *) INT2PTR(searchPtr->id)); if (entryPtr != NULL) { - itemPtr = (Tk_Item *) Tcl_GetHashValue(entryPtr); - object = (ClientData) itemPtr; + itemPtr = Tcl_GetHashValue(entryPtr); + object = itemPtr; } if (object == 0) { - Tcl_AppendResult(interp, "item \"", Tcl_GetString(objv[2]), - "\" doesn't exist", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "item \"%s\" doesn't exist", Tcl_GetString(objv[2]))); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "CANVAS_ITEM", + Tcl_GetString(objv[2]), NULL); result = TCL_ERROR; goto done; } @@ -712,7 +978,7 @@ CanvasWidgetCmd( if (objc == 5) { int append = 0; unsigned long mask; - char* argv4 = Tcl_GetString(objv[4]); + const char *argv4 = Tcl_GetString(objv[4]); if (argv4[0] == 0) { result = Tk_DeleteBinding(interp, canvasPtr->bindingTable, @@ -768,22 +1034,20 @@ CanvasWidgetCmd( |KeyReleaseMask|PointerMotionMask|VirtualEventMask)) { Tk_DeleteBinding(interp, canvasPtr->bindingTable, object, Tcl_GetString(objv[3])); - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "requested illegal events; ", - "only key, button, motion, enter, leave, and virtual ", - "events may be used", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "requested illegal events; only key, button, motion," + " enter, leave, and virtual events may be used", -1)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "BAD_EVENTS", NULL); result = TCL_ERROR; goto done; } } else if (objc == 4) { - CONST char *command; + const char *command; command = Tk_GetBinding(interp, canvasPtr->bindingTable, object, Tcl_GetString(objv[3])); if (command == NULL) { - CONST char *string; - - string = Tcl_GetStringResult(interp); + const char *string = Tcl_GetString(Tcl_GetObjResult(interp)); /* * Ignore missing binding errors. This is a special hack that @@ -794,11 +1058,10 @@ CanvasWidgetCmd( if (string[0] != '\0') { result = TCL_ERROR; goto done; - } else { - Tcl_ResetResult(interp); } + Tcl_ResetResult(interp); } else { - Tcl_SetResult(interp, (char *) command, TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj(command, -1)); } } else { Tk_GetAllBindings(interp, canvasPtr->bindingTable, object); @@ -808,20 +1071,20 @@ CanvasWidgetCmd( case CANV_CANVASX: { int x; double grid; - char buf[TCL_DOUBLE_SPACE]; if ((objc < 3) || (objc > 4)) { Tcl_WrongNumArgs(interp, 2, objv, "screenx ?gridspacing?"); result = TCL_ERROR; goto done; } - if (Tk_GetPixelsFromObj(interp, canvasPtr->tkwin, objv[2], &x) != TCL_OK) { + if (Tk_GetPixelsFromObj(interp, canvasPtr->tkwin, objv[2], + &x) != TCL_OK) { result = TCL_ERROR; goto done; } if (objc == 4) { - if (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, objv[3], - &grid) != TCL_OK) { + if (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, + objv[3], &grid) != TCL_OK) { result = TCL_ERROR; goto done; } @@ -829,21 +1092,20 @@ CanvasWidgetCmd( grid = 0.0; } x += canvasPtr->xOrigin; - Tcl_PrintDouble(interp, GridAlign((double) x, grid), buf); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_NewDoubleObj(GridAlign((double)x,grid))); break; } case CANV_CANVASY: { int y; double grid; - char buf[TCL_DOUBLE_SPACE]; if ((objc < 3) || (objc > 4)) { Tcl_WrongNumArgs(interp, 2, objv, "screeny ?gridspacing?"); result = TCL_ERROR; goto done; } - if (Tk_GetPixelsFromObj(interp, canvasPtr->tkwin, objv[2], &y) != TCL_OK) { + if (Tk_GetPixelsFromObj(interp, canvasPtr->tkwin, objv[2], + &y) != TCL_OK) { result = TCL_ERROR; goto done; } @@ -857,8 +1119,7 @@ CanvasWidgetCmd( grid = 0.0; } y += canvasPtr->yOrigin; - Tcl_PrintDouble(interp, GridAlign((double) y, grid), buf); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_NewDoubleObj(GridAlign((double)y,grid))); break; } case CANV_CGET: @@ -891,78 +1152,152 @@ CanvasWidgetCmd( FIRST_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done); if (itemPtr != NULL) { if (objc != 3) { - EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr); - } - if (itemPtr->typePtr->coordProc != NULL) { - if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) { - result = (*itemPtr->typePtr->coordProc)(interp, - (Tk_Canvas) canvasPtr, itemPtr, objc-3, objv+3); - } else { - CONST char **args = TkGetStringsFromObjs(objc-3, objv+3); - result = (*itemPtr->typePtr->coordProc)(interp, - (Tk_Canvas) canvasPtr, itemPtr, objc-3, - (Tcl_Obj **) args); - if (args != NULL) { - ckfree((char *) args); - } - } + EventuallyRedrawItem(canvasPtr, itemPtr); } + result = ItemCoords(canvasPtr, itemPtr, objc-3, objv+3); if (objc != 3) { - EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr); + EventuallyRedrawItem(canvasPtr, itemPtr); } } break; + case CANV_IMOVE: { + double ignored; + Tcl_Obj *tmpObj; + + if (objc != 6) { + Tcl_WrongNumArgs(interp, 2, objv, "tagOrId index x y"); + result = TCL_ERROR; + goto done; + } + if (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, + objv[4], &ignored) != TCL_OK + || Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, + objv[5], &ignored) != TCL_OK) { + result = TCL_ERROR; + goto done; + } + + /* + * Make a temporary object here that we can reuse for all the + * modifications in the loop. + */ + + tmpObj = Tcl_NewListObj(2, objv+4); + + FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto doneImove) { + int index; + int x1, x2, y1, y2; + int dontRedraw1, dontRedraw2; + + /* + * The TK_MOVABLE_POINTS flag should only be set for types that + * support the same semantics of index, dChars and insert methods + * as lines and canvases. + */ + + if (itemPtr == NULL || + !(itemPtr->typePtr->alwaysRedraw & TK_MOVABLE_POINTS)) { + continue; + } + + result = ItemIndex(canvasPtr, itemPtr, objv[3], &index); + if (result != TCL_OK) { + break; + } + + /* + * Redraw both item's old and new areas: it's possible that a + * replace could result in a new area larger than the old area. + * Except if the dCharsProc or insertProc sets the + * TK_ITEM_DONT_REDRAW flag, nothing more needs to be done. + */ + + x1 = itemPtr->x1; y1 = itemPtr->y1; + x2 = itemPtr->x2; y2 = itemPtr->y2; + + itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW; + ItemDelChars(canvasPtr, itemPtr, index, index); + dontRedraw1 = itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW; + + itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW; + ItemInsert(canvasPtr, itemPtr, index, tmpObj); + dontRedraw2 = itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW; + + if (!(dontRedraw1 && dontRedraw2)) { + Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr, + x1, y1, x2, y2); + EventuallyRedrawItem(canvasPtr, itemPtr); + } + itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW; + } + + doneImove: + Tcl_DecrRefCount(tmpObj); + break; + } case CANV_CREATE: { Tk_ItemType *typePtr; Tk_ItemType *matchPtr = NULL; Tk_Item *itemPtr; - char buf[TCL_INTEGER_SPACE]; int isNew = 0; Tcl_HashEntry *entryPtr; - char *arg; - int length; + const char *arg; + size_t length; if (objc < 3) { - Tcl_WrongNumArgs(interp, 2, objv, "type coords ?arg arg ...?"); + Tcl_WrongNumArgs(interp, 2, objv, "type coords ?arg ...?"); result = TCL_ERROR; goto done; } - arg = Tcl_GetStringFromObj(objv[2], &length); + arg = Tcl_GetString(objv[2]); + length = objv[2]->length; c = arg[0]; + + /* + * Lock because the list of types is a global resource that could be + * updated by another thread. That's fairly unlikely, but not + * impossible. + */ + Tcl_MutexLock(&typeListMutex); - for (typePtr = typeList; typePtr != NULL; typePtr = typePtr->nextPtr) { + for (typePtr = typeList; typePtr != NULL; typePtr = typePtr->nextPtr){ if ((c == typePtr->name[0]) - && (strncmp(arg, typePtr->name, (unsigned)length) == 0)) { + && (!strncmp(arg, typePtr->name, length))) { if (matchPtr != NULL) { Tcl_MutexUnlock(&typeListMutex); - badType: - Tcl_AppendResult(interp, - "unknown or ambiguous item type \"",arg,"\"",NULL); - result = TCL_ERROR; - goto done; + goto badType; } matchPtr = typePtr; } } + /* - * Can unlock now because we no longer look at the fields of - * the matched item type that are potentially modified by - * other threads. + * Can unlock now because we no longer look at the fields of the + * matched item type that are potentially modified by other threads. */ + Tcl_MutexUnlock(&typeListMutex); if (matchPtr == NULL) { - goto badType; + badType: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "unknown or ambiguous item type \"%s\"", arg)); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "CANVAS_ITEM_TYPE", arg, + NULL); + result = TCL_ERROR; + goto done; } if (objc < 4) { /* * Allow more specific error return. */ - Tcl_WrongNumArgs(interp, 3, objv, "coords ?arg arg ...?"); + + Tcl_WrongNumArgs(interp, 3, objv, "coords ?arg ...?"); result = TCL_ERROR; goto done; } + typePtr = matchPtr; - itemPtr = (Tk_Item *) ckalloc((unsigned) typePtr->itemSize); + itemPtr = ckalloc(typePtr->itemSize); itemPtr->id = canvasPtr->nextId; canvasPtr->nextId++; itemPtr->tagPtr = itemPtr->staticTagSpace; @@ -971,22 +1306,13 @@ CanvasWidgetCmd( itemPtr->typePtr = typePtr; itemPtr->state = TK_STATE_NULL; itemPtr->redraw_flags = 0; - if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) { - result = (*typePtr->createProc)(interp, (Tk_Canvas) canvasPtr, - itemPtr, objc-3, objv+3); - } else { - CONST char **args = TkGetStringsFromObjs(objc-3, objv+3); - result = (*typePtr->createProc)(interp, (Tk_Canvas) canvasPtr, - itemPtr, objc-3, (Tcl_Obj **) args); - if (args != NULL) { - ckfree((char *) args); - } - } - if (result != TCL_OK) { - ckfree((char *) itemPtr); + + if (ItemCreate(canvasPtr, itemPtr, objc, objv) != TCL_OK) { + ckfree(itemPtr); result = TCL_ERROR; goto done; } + itemPtr->nextPtr = NULL; entryPtr = Tcl_CreateHashEntry(&canvasPtr->idTable, (char *) INT2PTR(itemPtr->id), &isNew); @@ -1001,15 +1327,14 @@ CanvasWidgetCmd( } canvasPtr->lastItemPtr = itemPtr; itemPtr->redraw_flags |= FORCE_REDRAW; - EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr); + EventuallyRedrawItem(canvasPtr, itemPtr); canvasPtr->flags |= REPICK_NEEDED; - sprintf(buf, "%d", itemPtr->id); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_NewIntObj(itemPtr->id)); break; } case CANV_DCHARS: { int first, last; - int x1,x2,y1,y2; + int x1, x2, y1, y2; if ((objc != 4) && (objc != 5)) { Tcl_WrongNumArgs(interp, 2, objv, "tagOrId first ?last?"); @@ -1021,28 +1346,12 @@ CanvasWidgetCmd( || (itemPtr->typePtr->dCharsProc == NULL)) { continue; } - if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) { - result = itemPtr->typePtr->indexProc(interp, - (Tk_Canvas) canvasPtr, itemPtr, (char *) objv[3], - &first); - } else { - result = itemPtr->typePtr->indexProc(interp, - (Tk_Canvas) canvasPtr, itemPtr, Tcl_GetString(objv[3]), - &first); - } + result = ItemIndex(canvasPtr, itemPtr, objv[3], &first); if (result != TCL_OK) { goto done; } if (objc == 5) { - if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) { - result = itemPtr->typePtr->indexProc(interp, - (Tk_Canvas) canvasPtr, itemPtr, (char *) objv[4], - &last); - } else { - result = itemPtr->typePtr->indexProc(interp, - (Tk_Canvas) canvasPtr, itemPtr, - Tcl_GetString(objv[4]), &last); - } + result = ItemIndex(canvasPtr, itemPtr, objv[4], &last); if (result != TCL_OK) { goto done; } @@ -1053,19 +1362,18 @@ CanvasWidgetCmd( /* * Redraw both item's old and new areas: it's possible that a * delete could result in a new area larger than the old area. - * Except if the insertProc sets the TK_ITEM_DONT_REDRAW flag, + * Except if the dCharsProc sets the TK_ITEM_DONT_REDRAW flag, * nothing more needs to be done. */ x1 = itemPtr->x1; y1 = itemPtr->y1; x2 = itemPtr->x2; y2 = itemPtr->y2; itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW; - (*itemPtr->typePtr->dCharsProc)((Tk_Canvas) canvasPtr, - itemPtr, first, last); + ItemDelChars(canvasPtr, itemPtr, first, last); if (!(itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW)) { Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr, x1, y1, x2, y2); - EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr); + EventuallyRedrawItem(canvasPtr, itemPtr); } itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW; } @@ -1077,15 +1385,13 @@ CanvasWidgetCmd( for (i = 2; i < objc; i++) { FOR_EVERY_CANVAS_ITEM_MATCHING(objv[i], &searchPtr, goto done) { - EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr); + EventuallyRedrawItem(canvasPtr, itemPtr); if (canvasPtr->bindingTable != NULL) { - Tk_DeleteAllBindings(canvasPtr->bindingTable, - (ClientData) itemPtr); + Tk_DeleteAllBindings(canvasPtr->bindingTable, itemPtr); } - (*itemPtr->typePtr->deleteProc)((Tk_Canvas) canvasPtr, itemPtr, - canvasPtr->display); + ItemDelete(canvasPtr, itemPtr); if (itemPtr->tagPtr != itemPtr->staticTagSpace) { - ckfree((char *) itemPtr->tagPtr); + ckfree(itemPtr->tagPtr); } entryPtr = Tcl_FindHashEntry(&canvasPtr->idTable, (char *) INT2PTR(itemPtr->id)); @@ -1105,7 +1411,7 @@ CanvasWidgetCmd( if (canvasPtr->lastItemPtr == itemPtr) { canvasPtr->lastItemPtr = itemPtr->prevPtr; } - ckfree((char *) itemPtr); + ckfree(itemPtr); if (itemPtr == canvasPtr->currentItemPtr) { canvasPtr->currentItemPtr = NULL; canvasPtr->flags |= REPICK_NEEDED; @@ -1154,16 +1460,11 @@ CanvasWidgetCmd( } case CANV_FIND: if (objc < 3) { - Tcl_WrongNumArgs(interp, 2, objv, "searchCommand ?arg arg ...?"); + Tcl_WrongNumArgs(interp, 2, objv, "searchCommand ?arg ...?"); result = TCL_ERROR; goto done; } -#ifdef USE_OLD_TAG_SEARCH - result = FindItems(interp, canvasPtr, objc, objv, NULL, 2); -#else /* USE_OLD_TAG_SEARCH */ - result = FindItems(interp, canvasPtr, objc, objv, NULL, 2, - &searchPtr); -#endif /* USE_OLD_TAG_SEARCH */ + result = FIND_ITEMS(NULL, 2); break; case CANV_FOCUS: if (objc > 3) { @@ -1174,15 +1475,12 @@ CanvasWidgetCmd( itemPtr = canvasPtr->textInfo.focusItemPtr; if (objc == 2) { if (itemPtr != NULL) { - char buf[TCL_INTEGER_SPACE]; - - sprintf(buf, "%d", itemPtr->id); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_NewIntObj(itemPtr->id)); } goto done; } - if ((itemPtr != NULL) && (canvasPtr->textInfo.gotFocus)) { - EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr); + if (canvasPtr->textInfo.gotFocus) { + EventuallyRedrawItem(canvasPtr, itemPtr); } if (Tcl_GetString(objv[2])[0] == 0) { canvasPtr->textInfo.focusItemPtr = NULL; @@ -1198,7 +1496,7 @@ CanvasWidgetCmd( } canvasPtr->textInfo.focusItemPtr = itemPtr; if (canvasPtr->textInfo.gotFocus) { - EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr); + EventuallyRedrawItem(canvasPtr, itemPtr); } break; case CANV_GETTAGS: @@ -1210,9 +1508,13 @@ CanvasWidgetCmd( FIRST_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done); if (itemPtr != NULL) { int i; + Tcl_Obj *resultObj = Tcl_NewObj(); + for (i = 0; i < itemPtr->numTags; i++) { - Tcl_AppendElement(interp, (char *) itemPtr->tagPtr[i]); + Tcl_ListObjAppendElement(NULL, resultObj, + Tcl_NewStringObj(itemPtr->tagPtr[i], -1)); } + Tcl_SetObjResult(interp, resultObj); } break; case CANV_ICURSOR: { @@ -1228,30 +1530,20 @@ CanvasWidgetCmd( || (itemPtr->typePtr->icursorProc == NULL)) { goto done; } - if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) { - result = itemPtr->typePtr->indexProc(interp, - (Tk_Canvas) canvasPtr, itemPtr, (char *) objv[3], - &index); - } else { - result = itemPtr->typePtr->indexProc(interp, - (Tk_Canvas) canvasPtr, itemPtr, Tcl_GetString(objv[3]), - &index); - } + result = ItemIndex(canvasPtr, itemPtr, objv[3], &index); if (result != TCL_OK) { goto done; } - (*itemPtr->typePtr->icursorProc)((Tk_Canvas) canvasPtr, itemPtr, - index); + ItemCursor(canvasPtr, itemPtr, index); if ((itemPtr == canvasPtr->textInfo.focusItemPtr) && (canvasPtr->textInfo.cursorOn)) { - EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr); + EventuallyRedrawItem(canvasPtr, itemPtr); } } break; } case CANV_INDEX: { int index; - char buf[TCL_INTEGER_SPACE]; if (objc != 4) { Tcl_WrongNumArgs(interp, 2, objv, "tagOrId string"); @@ -1264,28 +1556,23 @@ CanvasWidgetCmd( } } if (itemPtr == NULL) { - Tcl_AppendResult(interp, "can't find an indexable item \"", - Tcl_GetString(objv[2]), "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't find an indexable item \"%s\"", + Tcl_GetString(objv[2]))); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "INDEXABLE_ITEM", NULL); result = TCL_ERROR; goto done; } - if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) { - result = itemPtr->typePtr->indexProc(interp, (Tk_Canvas) canvasPtr, - itemPtr, (char *) objv[3], &index); - } else { - result = itemPtr->typePtr->indexProc(interp, (Tk_Canvas) canvasPtr, - itemPtr, Tcl_GetString(objv[3]), &index); - } + result = ItemIndex(canvasPtr, itemPtr, objv[3], &index); if (result != TCL_OK) { goto done; } - sprintf(buf, "%d", index); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_NewIntObj(index)); break; } case CANV_INSERT: { int beforeThis; - int x1,x2,y1,y2; + int x1, x2, y1, y2; if (objc != 5) { Tcl_WrongNumArgs(interp, 2, objv, "tagOrId beforeThis string"); @@ -1297,15 +1584,7 @@ CanvasWidgetCmd( || (itemPtr->typePtr->insertProc == NULL)) { continue; } - if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) { - result = itemPtr->typePtr->indexProc(interp, - (Tk_Canvas) canvasPtr, itemPtr, (char *) objv[3], - &beforeThis); - } else { - result = itemPtr->typePtr->indexProc(interp, - (Tk_Canvas) canvasPtr, itemPtr, Tcl_GetString(objv[3]), - &beforeThis); - } + result = ItemIndex(canvasPtr, itemPtr, objv[3], &beforeThis); if (result != TCL_OK) { goto done; } @@ -1320,17 +1599,11 @@ CanvasWidgetCmd( x1 = itemPtr->x1; y1 = itemPtr->y1; x2 = itemPtr->x2; y2 = itemPtr->y2; itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW; - if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) { - (*itemPtr->typePtr->insertProc)((Tk_Canvas) canvasPtr, - itemPtr, beforeThis, (char *) objv[4]); - } else { - (*itemPtr->typePtr->insertProc)((Tk_Canvas) canvasPtr, - itemPtr, beforeThis, Tcl_GetString(objv[4])); - } + ItemInsert(canvasPtr, itemPtr, beforeThis, objv[4]); if (!(itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW)) { Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr, x1, y1, x2, y2); - EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr); + EventuallyRedrawItem(canvasPtr, itemPtr); } itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW; } @@ -1344,42 +1617,24 @@ CanvasWidgetCmd( } FIRST_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done); if (itemPtr != NULL) { - result = Tk_ConfigureValue(canvasPtr->interp, canvasPtr->tkwin, - itemPtr->typePtr->configSpecs, (char *) itemPtr, - Tcl_GetString(objv[3]), 0); + result = ItemConfigValue(canvasPtr, itemPtr, objv[3]); } break; case CANV_ITEMCONFIGURE: if (objc < 3) { - Tcl_WrongNumArgs(interp, 2, objv, "tagOrId ?option value ...?"); + Tcl_WrongNumArgs(interp, 2, objv, "tagOrId ?-option value ...?"); result = TCL_ERROR; goto done; } FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) { if (objc == 3) { - result = Tk_ConfigureInfo(canvasPtr->interp, canvasPtr->tkwin, - itemPtr->typePtr->configSpecs, (char *) itemPtr, - NULL, 0); + result = ItemConfigInfo(canvasPtr, itemPtr, NULL); } else if (objc == 4) { - result = Tk_ConfigureInfo(canvasPtr->interp, canvasPtr->tkwin, - itemPtr->typePtr->configSpecs, (char *) itemPtr, - Tcl_GetString(objv[3]), 0); + result = ItemConfigInfo(canvasPtr, itemPtr, objv[3]); } else { - EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr); - if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) { - result = (*itemPtr->typePtr->configProc)(interp, - (Tk_Canvas) canvasPtr, itemPtr, objc-3, objv+3, - TK_CONFIG_ARGV_ONLY); - } else { - CONST char **args = TkGetStringsFromObjs(objc-3, objv+3); - result = (*itemPtr->typePtr->configProc)(interp, - (Tk_Canvas) canvasPtr, itemPtr, objc-3, - (Tcl_Obj **) args, TK_CONFIG_ARGV_ONLY); - if (args != NULL) { - ckfree((char *) args); - } - } - EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr); + EventuallyRedrawItem(canvasPtr, itemPtr); + result = ItemConfigure(canvasPtr, itemPtr, objc-3, objv+3); + EventuallyRedrawItem(canvasPtr, itemPtr); canvasPtr->flags |= REPICK_NEEDED; } if ((result != TCL_OK) || (objc < 5)) { @@ -1405,18 +1660,16 @@ CanvasWidgetCmd( } else { FIRST_CANVAS_ITEM_MATCHING(objv[3], &searchPtr, goto done); if (itemPtr == NULL) { - Tcl_AppendResult(interp, "tag \"", Tcl_GetString(objv[3]), - "\" doesn't match any items", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "tagOrId \"%s\" doesn't match any items", + Tcl_GetString(objv[3]))); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "ITEM", NULL); result = TCL_ERROR; goto done; } itemPtr = itemPtr->prevPtr; } -#ifdef USE_OLD_TAG_SEARCH - RelinkItems(canvasPtr, objv[2], itemPtr); -#else /* USE_OLD_TAG_SEARCH */ - result = RelinkItems(canvasPtr, objv[2], itemPtr, &searchPtr); -#endif /* USE_OLD_TAG_SEARCH */ + RELINK_ITEMS(objv[2], itemPtr); break; } case CANV_MOVE: { @@ -1434,20 +1687,82 @@ CanvasWidgetCmd( goto done; } FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) { - EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr); - (void) (*itemPtr->typePtr->translateProc)((Tk_Canvas) canvasPtr, - itemPtr, xAmount, yAmount); - EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr); + EventuallyRedrawItem(canvasPtr, itemPtr); + ItemTranslate(canvasPtr, itemPtr, xAmount, yAmount); + EventuallyRedrawItem(canvasPtr, itemPtr); canvasPtr->flags |= REPICK_NEEDED; } break; } + case CANV_MOVETO: { + int xBlank, yBlank; + double xAmount, yAmount; + double oldX = 0, oldY = 0, newX, newY; + + if (objc != 5) { + Tcl_WrongNumArgs(interp, 2, objv, "tagOrId x y"); + result = TCL_ERROR; + goto done; + } + + xBlank = 0; + if (Tcl_GetString(objv[3])[0] == '\0') { + xBlank = 1; + } else if (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, + objv[3], &newX) != TCL_OK) { + result = TCL_ERROR; + goto done; + } + + yBlank = 0; + if (Tcl_GetString(objv[4])[0] == '\0') { + yBlank = 1; + } else if (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, + objv[4], &newY) != TCL_OK) { + result = TCL_ERROR; + goto done; + } + + FIRST_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done); + if (itemPtr != NULL) { + oldX = itemPtr->x1; + oldY = itemPtr->y1; + + /* + * Calculate the displacement. + */ + + if (xBlank) { + xAmount = 0; + } else { + xAmount = newX - oldX; + } + + if (yBlank) { + yAmount = 0; + } else { + yAmount = newY - oldY; + } + + /* + * Move the object(s). + */ + + FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) { + EventuallyRedrawItem(canvasPtr, itemPtr); + ItemTranslate(canvasPtr, itemPtr, xAmount, yAmount); + EventuallyRedrawItem(canvasPtr, itemPtr); + canvasPtr->flags |= REPICK_NEEDED; + } + } + break; + } case CANV_POSTSCRIPT: { - CONST char **args = TkGetStringsFromObjs(objc, objv); + const char **args = TkGetStringsFromObjs(objc, objv); result = TkCanvPostscriptCmd(canvasPtr, interp, objc, args); if (args != NULL) { - ckfree((char *) args); + ckfree(args); } break; } @@ -1472,24 +1787,75 @@ CanvasWidgetCmd( prevPtr = itemPtr; } if (prevPtr == NULL) { - Tcl_AppendResult(interp, "tagOrId \"", Tcl_GetString(objv[3]), - "\" doesn't match any items", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "tagOrId \"%s\" doesn't match any items", + Tcl_GetString(objv[3]))); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "ITEM", NULL); result = TCL_ERROR; goto done; } } -#ifdef USE_OLD_TAG_SEARCH - RelinkItems(canvasPtr, objv[2], prevPtr); -#else /* USE_OLD_TAG_SEARCH */ - result = RelinkItems(canvasPtr, objv[2], prevPtr, &searchPtr); -#endif /* USE_OLD_TAG_SEARCH */ + RELINK_ITEMS(objv[2], prevPtr); + break; + } + case CANV_RCHARS: { + int first, last; + int x1, x2, y1, y2; + int dontRedraw1, dontRedraw2; + + if (objc != 6) { + Tcl_WrongNumArgs(interp, 2, objv, "tagOrId first last string"); + result = TCL_ERROR; + goto done; + } + FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) { + if ((itemPtr->typePtr->indexProc == NULL) + || (itemPtr->typePtr->dCharsProc == NULL) + || (itemPtr->typePtr->insertProc == NULL)) { + continue; + } + result = ItemIndex(canvasPtr, itemPtr, objv[3], &first); + if (result != TCL_OK) { + goto done; + } + result = ItemIndex(canvasPtr, itemPtr, objv[4], &last); + if (result != TCL_OK) { + goto done; + } + + /* + * Redraw both item's old and new areas: it's possible that a + * replace could result in a new area larger than the old area. + * Except if the dCharsProc or insertProc sets the + * TK_ITEM_DONT_REDRAW flag, nothing more needs to be done. + */ + + x1 = itemPtr->x1; y1 = itemPtr->y1; + x2 = itemPtr->x2; y2 = itemPtr->y2; + + itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW; + ItemDelChars(canvasPtr, itemPtr, first, last); + dontRedraw1 = itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW; + + itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW; + ItemInsert(canvasPtr, itemPtr, first, objv[5]); + dontRedraw2 = itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW; + + if (!(dontRedraw1 && dontRedraw2)) { + Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr, + x1, y1, x2, y2); + EventuallyRedrawItem(canvasPtr, itemPtr); + } + itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW; + } break; } case CANV_SCALE: { double xOrigin, yOrigin, xScale, yScale; if (objc != 7) { - Tcl_WrongNumArgs(interp, 2, objv, "tagOrId xOrigin yOrigin xScale yScale"); + Tcl_WrongNumArgs(interp, 2, objv, + "tagOrId xOrigin yOrigin xScale yScale"); result = TCL_ERROR; goto done; } @@ -1497,28 +1863,29 @@ CanvasWidgetCmd( objv[3], &xOrigin) != TCL_OK) || (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, objv[4], &yOrigin) != TCL_OK) - || (Tcl_GetDoubleFromObj(interp, objv[5], &xScale) != TCL_OK) - || (Tcl_GetDoubleFromObj(interp, objv[6], &yScale) != TCL_OK)) { + || (Tcl_GetDoubleFromObj(interp, objv[5], &xScale)!=TCL_OK) + || (Tcl_GetDoubleFromObj(interp, objv[6], &yScale)!=TCL_OK)) { result = TCL_ERROR; goto done; } if ((xScale == 0.0) || (yScale == 0.0)) { - Tcl_SetResult(interp, "scale factor cannot be zero", TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "scale factor cannot be zero", -1)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "BAD_SCALE", NULL); result = TCL_ERROR; goto done; } FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) { - EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr); - (void) (*itemPtr->typePtr->scaleProc)((Tk_Canvas) canvasPtr, - itemPtr, xOrigin, yOrigin, xScale, yScale); - EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr); + EventuallyRedrawItem(canvasPtr, itemPtr); + ItemScale(canvasPtr, itemPtr, xOrigin, yOrigin, xScale, yScale); + EventuallyRedrawItem(canvasPtr, itemPtr); canvasPtr->flags |= REPICK_NEEDED; } break; } case CANV_SCAN: { int x, y, gain = 10; - static CONST char *optionStrings[] = { + static const char *const optionStrings[] = { "mark", "dragto", NULL }; @@ -1562,7 +1929,7 @@ CanvasWidgetCmd( } case CANV_SELECT: { int index, optionindex; - static CONST char *optionStrings[] = { + static const char *const optionStrings[] = { "adjust", "clear", "from", "item", "to", NULL }; enum options { @@ -1582,23 +1949,17 @@ CanvasWidgetCmd( } } if (itemPtr == NULL) { - Tcl_AppendResult(interp, - "can't find an indexable and selectable item \"", - Tcl_GetString(objv[3]), "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't find an indexable and selectable item \"%s\"", + Tcl_GetString(objv[3]))); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "SELECTABLE_ITEM", + NULL); result = TCL_ERROR; goto done; } } if (objc == 5) { - if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) { - result = itemPtr->typePtr->indexProc(interp, - (Tk_Canvas) canvasPtr, itemPtr, (char *) objv[4], - &index); - } else { - result = itemPtr->typePtr->indexProc(interp, - (Tk_Canvas) canvasPtr, itemPtr, Tcl_GetString(objv[4]), - &index); - } + result = ItemIndex(canvasPtr, itemPtr, objv[4], &index); if (result != TCL_OK) { goto done; } @@ -1633,12 +1994,8 @@ CanvasWidgetCmd( result = TCL_ERROR; goto done; } - if (canvasPtr->textInfo.selItemPtr != NULL) { - EventuallyRedrawItem((Tk_Canvas) canvasPtr, - canvasPtr->textInfo.selItemPtr); - canvasPtr->textInfo.selItemPtr = NULL; - } - goto done; + EventuallyRedrawItem(canvasPtr, canvasPtr->textInfo.selItemPtr); + canvasPtr->textInfo.selItemPtr = NULL; break; case CANV_FROM: if (objc != 5) { @@ -1679,14 +2036,16 @@ CanvasWidgetCmd( } FIRST_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done); if (itemPtr != NULL) { - Tcl_SetResult(interp, itemPtr->typePtr->name, TCL_STATIC); + Tcl_SetObjResult(interp, + Tcl_NewStringObj(itemPtr->typePtr->name, -1)); } break; case CANV_XVIEW: { int count, type; - int newX = 0; /* Initialization needed only to prevent - * gcc warnings. */ + int newX = 0; /* Initialization needed only to prevent gcc + * warnings. */ double fraction; + const char **args; if (objc == 2) { Tcl_SetObjResult(interp, ScrollFractions( @@ -1694,45 +2053,45 @@ CanvasWidgetCmd( canvasPtr->xOrigin + Tk_Width(canvasPtr->tkwin) - canvasPtr->inset, canvasPtr->scrollX1, canvasPtr->scrollX2)); - } else { - CONST char **args = TkGetStringsFromObjs(objc, objv); - type = Tk_GetScrollInfo(interp, objc, args, &fraction, &count); - if (args != NULL) { - ckfree((char *) args); - } - switch (type) { - case TK_SCROLL_ERROR: - result = TCL_ERROR; - goto done; - case TK_SCROLL_MOVETO: - newX = canvasPtr->scrollX1 - canvasPtr->inset - + (int) (fraction * (canvasPtr->scrollX2 - - canvasPtr->scrollX1) + 0.5); - break; - case TK_SCROLL_PAGES: - newX = (int) (canvasPtr->xOrigin + count * .9 + break; + } + + args = TkGetStringsFromObjs(objc, objv); + type = Tk_GetScrollInfo(interp, objc, args, &fraction, &count); + if (args != NULL) { + ckfree(args); + } + switch (type) { + case TK_SCROLL_ERROR: + result = TCL_ERROR; + goto done; + case TK_SCROLL_MOVETO: + newX = canvasPtr->scrollX1 - canvasPtr->inset + + (int) (fraction * (canvasPtr->scrollX2 + - canvasPtr->scrollX1) + 0.5); + break; + case TK_SCROLL_PAGES: + newX = (int) (canvasPtr->xOrigin + count * .9 + * (Tk_Width(canvasPtr->tkwin) - 2*canvasPtr->inset)); + break; + case TK_SCROLL_UNITS: + if (canvasPtr->xScrollIncrement > 0) { + newX = canvasPtr->xOrigin + count*canvasPtr->xScrollIncrement; + } else { + newX = (int) (canvasPtr->xOrigin + count * .1 * (Tk_Width(canvasPtr->tkwin) - 2*canvasPtr->inset)); - break; - case TK_SCROLL_UNITS: - if (canvasPtr->xScrollIncrement > 0) { - newX = canvasPtr->xOrigin - + count*canvasPtr->xScrollIncrement; - } else { - newX = (int) (canvasPtr->xOrigin + count * .1 - * (Tk_Width(canvasPtr->tkwin) - - 2*canvasPtr->inset)); - } - break; } - CanvasSetOrigin(canvasPtr, newX, canvasPtr->yOrigin); + break; } + CanvasSetOrigin(canvasPtr, newX, canvasPtr->yOrigin); break; } case CANV_YVIEW: { int count, type; - int newY = 0; /* Initialization needed only to prevent - * gcc warnings. */ + int newY = 0; /* Initialization needed only to prevent gcc + * warnings. */ double fraction; + const char **args; if (objc == 2) { Tcl_SetObjResult(interp, ScrollFractions( @@ -1740,39 +2099,36 @@ CanvasWidgetCmd( canvasPtr->yOrigin + Tk_Height(canvasPtr->tkwin) - canvasPtr->inset, canvasPtr->scrollY1, canvasPtr->scrollY2)); - } else { - CONST char **args = TkGetStringsFromObjs(objc, objv); - type = Tk_GetScrollInfo(interp, objc, args, &fraction, &count); - if (args != NULL) { - ckfree((char *) args); - } - switch (type) { - case TK_SCROLL_ERROR: - result = TCL_ERROR; - goto done; - case TK_SCROLL_MOVETO: - newY = canvasPtr->scrollY1 - canvasPtr->inset - + (int) (fraction*(canvasPtr->scrollY2 - - canvasPtr->scrollY1) + 0.5); - break; - case TK_SCROLL_PAGES: - newY = (int) (canvasPtr->yOrigin + count * .9 - * (Tk_Height(canvasPtr->tkwin) - - 2*canvasPtr->inset)); - break; - case TK_SCROLL_UNITS: - if (canvasPtr->yScrollIncrement > 0) { - newY = canvasPtr->yOrigin - + count*canvasPtr->yScrollIncrement; - } else { - newY = (int) (canvasPtr->yOrigin + count * .1 - * (Tk_Height(canvasPtr->tkwin) - - 2*canvasPtr->inset)); - } - break; + break; + } + + args = TkGetStringsFromObjs(objc, objv); + type = Tk_GetScrollInfo(interp, objc, args, &fraction, &count); + if (args != NULL) { + ckfree(args); + } + switch (type) { + case TK_SCROLL_ERROR: + result = TCL_ERROR; + goto done; + case TK_SCROLL_MOVETO: + newY = canvasPtr->scrollY1 - canvasPtr->inset + (int) ( + fraction*(canvasPtr->scrollY2-canvasPtr->scrollY1) + 0.5); + break; + case TK_SCROLL_PAGES: + newY = (int) (canvasPtr->yOrigin + count * .9 + * (Tk_Height(canvasPtr->tkwin) - 2*canvasPtr->inset)); + break; + case TK_SCROLL_UNITS: + if (canvasPtr->yScrollIncrement > 0) { + newY = canvasPtr->yOrigin + count*canvasPtr->yScrollIncrement; + } else { + newY = (int) (canvasPtr->yOrigin + count * .1 + * (Tk_Height(canvasPtr->tkwin) - 2*canvasPtr->inset)); } - CanvasSetOrigin(canvasPtr, canvasPtr->xOrigin, newY); + break; } + CanvasSetOrigin(canvasPtr, canvasPtr->xOrigin, newY); break; } } @@ -1781,7 +2137,7 @@ CanvasWidgetCmd( #ifndef USE_OLD_TAG_SEARCH TagSearchDestroy(searchPtr); #endif /* not USE_OLD_TAG_SEARCH */ - Tcl_Release((ClientData) canvasPtr); + Tcl_Release(canvasPtr); return result; } @@ -1820,12 +2176,11 @@ DestroyCanvas( for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL; itemPtr = canvasPtr->firstItemPtr) { canvasPtr->firstItemPtr = itemPtr->nextPtr; - (*itemPtr->typePtr->deleteProc)((Tk_Canvas) canvasPtr, itemPtr, - canvasPtr->display); + ItemDelete(canvasPtr, itemPtr); if (itemPtr->tagPtr != itemPtr->staticTagSpace) { - ckfree((char *) itemPtr->tagPtr); + ckfree(itemPtr->tagPtr); } - ckfree((char *) itemPtr); + ckfree(itemPtr); } /* @@ -1851,7 +2206,7 @@ DestroyCanvas( } Tk_FreeOptions(configSpecs, (char *) canvasPtr, canvasPtr->display, 0); canvasPtr->tkwin = NULL; - ckfree((char *) canvasPtr); + ckfree(canvasPtr); } /* @@ -1880,7 +2235,7 @@ ConfigureCanvas( TkCanvas *canvasPtr, /* Information about widget; may or may not * already have values for some fields. */ int objc, /* Number of valid entries in objv. */ - Tcl_Obj *CONST objv[], /* Argument objects. */ + Tcl_Obj *const objv[], /* Argument objects. */ int flags) /* Flags to pass to Tk_ConfigureWidget. */ { XGCValues gcValues; @@ -1888,7 +2243,7 @@ ConfigureCanvas( Tk_State old_canvas_state=canvasPtr->canvas_state; if (Tk_ConfigureWidget(interp, canvasPtr->tkwin, configSpecs, - objc, (CONST char **) objv, (char *) canvasPtr, + objc, (const char **) objv, (char *) canvasPtr, flags|TK_CONFIG_OBJS) != TCL_OK) { return TCL_ERROR; } @@ -1936,7 +2291,7 @@ ConfigureCanvas( } } - /* + /* * Reset the desired dimensions for the window. */ @@ -1962,18 +2317,19 @@ ConfigureCanvas( canvasPtr->scrollY2 = 0; if (canvasPtr->regionString != NULL) { int argc2; - CONST char **argv2; + const char **argv2; if (Tcl_SplitList(canvasPtr->interp, canvasPtr->regionString, &argc2, &argv2) != TCL_OK) { return TCL_ERROR; } if (argc2 != 4) { - Tcl_AppendResult(interp, "bad scrollRegion \"", - canvasPtr->regionString, "\"", NULL); - badRegion: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad scrollRegion \"%s\"", canvasPtr->regionString)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "SCROLL_REGION", NULL); + badRegion: ckfree(canvasPtr->regionString); - ckfree((char *) argv2); + ckfree(argv2); canvasPtr->regionString = NULL; return TCL_ERROR; } @@ -1987,7 +2343,7 @@ ConfigureCanvas( argv2[3], &canvasPtr->scrollY2) != TCL_OK)) { goto badRegion; } - ckfree((char *) argv2); + ckfree(argv2); } flags = canvasPtr->tsoffset.flags; @@ -2021,7 +2377,7 @@ ConfigureCanvas( } /* - *--------------------------------------------------------------------------- + *---------------------------------------------------------------------- * * CanvasWorldChanged -- * @@ -2037,24 +2393,19 @@ ConfigureCanvas( * side effect of causing all the items to recompute their geometry and * to be redisplayed. * - *--------------------------------------------------------------------------- + *---------------------------------------------------------------------- */ static void CanvasWorldChanged( ClientData instanceData) /* Information about widget. */ { - TkCanvas *canvasPtr; + TkCanvas *canvasPtr = instanceData; Tk_Item *itemPtr; - int result; - canvasPtr = (TkCanvas *) instanceData; itemPtr = canvasPtr->firstItemPtr; for ( ; itemPtr != NULL; itemPtr = itemPtr->nextPtr) { - result = (*itemPtr->typePtr->configProc)(canvasPtr->interp, - (Tk_Canvas) canvasPtr, itemPtr, 0, NULL, - TK_CONFIG_ARGV_ONLY); - if (result != TCL_OK) { + if (ItemConfigure(canvasPtr, itemPtr, 0, NULL) != TCL_OK) { Tcl_ResetResult(canvasPtr->interp); } } @@ -2066,7 +2417,7 @@ CanvasWorldChanged( } /* - *-------------------------------------------------------------- + *---------------------------------------------------------------------- * * DisplayCanvas -- * @@ -2080,14 +2431,14 @@ CanvasWorldChanged( * Side effects: * Information appears on the screen. * - *-------------------------------------------------------------- + *---------------------------------------------------------------------- */ static void DisplayCanvas( ClientData clientData) /* Information about widget. */ { - TkCanvas *canvasPtr = (TkCanvas *) clientData; + TkCanvas *canvasPtr = clientData; Tk_Window tkwin = canvasPtr->tkwin; Tk_Item *itemPtr; Pixmap pixmap; @@ -2120,11 +2471,11 @@ DisplayCanvas( */ while (canvasPtr->flags & REPICK_NEEDED) { - Tcl_Preserve((ClientData) canvasPtr); + Tcl_Preserve(canvasPtr); canvasPtr->flags &= ~REPICK_NEEDED; PickCurrentItem(canvasPtr, &canvasPtr->pickEvent); tkwin = canvasPtr->tkwin; - Tcl_Release((ClientData) canvasPtr); + Tcl_Release(canvasPtr); if (tkwin == NULL) { return; } @@ -2137,13 +2488,14 @@ DisplayCanvas( */ for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL; - itemPtr = itemPtr->nextPtr) { + itemPtr = itemPtr->nextPtr) { if (itemPtr->redraw_flags & FORCE_REDRAW) { itemPtr->redraw_flags &= ~FORCE_REDRAW; - EventuallyRedrawItem((Tk_Canvas)canvasPtr, itemPtr); + EventuallyRedrawItem(canvasPtr, itemPtr); itemPtr->redraw_flags &= ~FORCE_REDRAW; } } + /* * Compute the intersection between the area that needs redrawing and the * area that's visible on the screen. @@ -2241,7 +2593,7 @@ DisplayCanvas( || (itemPtr->y1 >= screenY2) || (itemPtr->x2 < screenX1) || (itemPtr->y2 < screenY1)) { - if (!(itemPtr->typePtr->alwaysRedraw & 1) + if (!AlwaysRedraw(itemPtr) || (itemPtr->x1 >= canvasPtr->redrawX2) || (itemPtr->y1 >= canvasPtr->redrawY2) || (itemPtr->x2 < canvasPtr->redrawX1) @@ -2250,12 +2602,11 @@ DisplayCanvas( } } if (itemPtr->state == TK_STATE_HIDDEN || - (itemPtr->state == TK_STATE_NULL && - canvasPtr->canvas_state == TK_STATE_HIDDEN)) { + (itemPtr->state == TK_STATE_NULL && + canvasPtr->canvas_state == TK_STATE_HIDDEN)) { continue; } - (*itemPtr->typePtr->displayProc)((Tk_Canvas) canvasPtr, itemPtr, - canvasPtr->display, pixmap, screenX1, screenY1, width, + ItemDisplay(canvasPtr, itemPtr, pixmap, screenX1, screenY1, width, height); } @@ -2319,7 +2670,7 @@ DisplayCanvas( } /* - *-------------------------------------------------------------- + *---------------------------------------------------------------------- * * CanvasEventProc -- * @@ -2330,10 +2681,10 @@ DisplayCanvas( * None. * * Side effects: - * When the window gets deleted, internal structures get cleaned up. - * When it gets exposed, it is redisplayed. + * When the window gets deleted, internal structures get cleaned up. When + * it gets exposed, it is redisplayed. * - *-------------------------------------------------------------- + *---------------------------------------------------------------------- */ static void @@ -2341,7 +2692,7 @@ CanvasEventProc( ClientData clientData, /* Information about window. */ XEvent *eventPtr) /* Information about event. */ { - TkCanvas *canvasPtr = (TkCanvas *) clientData; + TkCanvas *canvasPtr = clientData; if (eventPtr->type == Expose) { int x, y; @@ -2366,10 +2717,9 @@ CanvasEventProc( canvasPtr->widgetCmd); } if (canvasPtr->flags & REDRAW_PENDING) { - Tcl_CancelIdleCall(DisplayCanvas, (ClientData) canvasPtr); + Tcl_CancelIdleCall(DisplayCanvas, canvasPtr); } - Tcl_EventuallyFree((ClientData) canvasPtr, - (Tcl_FreeProc *) DestroyCanvas); + Tcl_EventuallyFree(canvasPtr, (Tcl_FreeProc *) DestroyCanvas); } else if (eventPtr->type == ConfigureNotify) { canvasPtr->flags |= UPDATE_SCROLLBARS; @@ -2403,9 +2753,8 @@ CanvasEventProc( for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL; itemPtr = itemPtr->nextPtr) { - if (itemPtr->typePtr->alwaysRedraw & 1) { - (*itemPtr->typePtr->displayProc)((Tk_Canvas) canvasPtr, - itemPtr, canvasPtr->display, None, 0, 0, 0, 0); + if (AlwaysRedraw(itemPtr)) { + ItemDisplay(canvasPtr, itemPtr, None, 0, 0, 0, 0); } } } @@ -2433,7 +2782,7 @@ static void CanvasCmdDeletedProc( ClientData clientData) /* Pointer to widget record for widget. */ { - TkCanvas *canvasPtr = (TkCanvas *) clientData; + TkCanvas *canvasPtr = clientData; Tk_Window tkwin = canvasPtr->tkwin; /* @@ -2450,7 +2799,7 @@ CanvasCmdDeletedProc( } /* - *-------------------------------------------------------------- + *---------------------------------------------------------------------- * * Tk_CanvasEventuallyRedraw -- * @@ -2463,7 +2812,7 @@ CanvasCmdDeletedProc( * Side effects: * The screen will eventually be refreshed. * - *-------------------------------------------------------------- + *---------------------------------------------------------------------- */ void @@ -2474,7 +2823,7 @@ Tk_CanvasEventuallyRedraw( int x2, int y2) /* Lower right corner of area to redraw. * Pixels on edge are not redrawn. */ { - TkCanvas *canvasPtr = (TkCanvas *) canvas; + TkCanvas *canvasPtr = Canvas(canvas); /* * If tkwin is NULL, the canvas has been destroyed, so we can't really @@ -2512,13 +2861,13 @@ Tk_CanvasEventuallyRedraw( canvasPtr->flags |= BBOX_NOT_EMPTY; } if (!(canvasPtr->flags & REDRAW_PENDING)) { - Tcl_DoWhenIdle(DisplayCanvas, (ClientData) canvasPtr); + Tcl_DoWhenIdle(DisplayCanvas, canvasPtr); canvasPtr->flags |= REDRAW_PENDING; } } /* - *-------------------------------------------------------------- + *---------------------------------------------------------------------- * * EventuallyRedrawItem -- * @@ -2531,21 +2880,24 @@ Tk_CanvasEventuallyRedraw( * Side effects: * The screen will eventually be refreshed. * - *-------------------------------------------------------------- + *---------------------------------------------------------------------- */ static void EventuallyRedrawItem( - Tk_Canvas canvas, /* Information about widget. */ - Tk_Item *itemPtr) /* Item to be redrawn. */ + TkCanvas *canvasPtr, /* Information about widget. */ + Tk_Item *itemPtr) /* Item to be redrawn. May be NULL, in which + * case nothing happens. */ { - TkCanvas *canvasPtr = (TkCanvas *) canvas; + if (itemPtr == NULL) { + return; + } if ((itemPtr->x1 >= itemPtr->x2) || (itemPtr->y1 >= itemPtr->y2) || (itemPtr->x2 < canvasPtr->xOrigin) || (itemPtr->y2 < canvasPtr->yOrigin) || - (itemPtr->x1 >= canvasPtr->xOrigin + Tk_Width(canvasPtr->tkwin)) || - (itemPtr->y1 >= canvasPtr->yOrigin + Tk_Height(canvasPtr->tkwin))) { - if (!(itemPtr->typePtr->alwaysRedraw & 1)) { + (itemPtr->x1 >= canvasPtr->xOrigin+Tk_Width(canvasPtr->tkwin)) || + (itemPtr->y1 >= canvasPtr->yOrigin+Tk_Height(canvasPtr->tkwin))) { + if (!AlwaysRedraw(itemPtr)) { return; } } @@ -2573,13 +2925,13 @@ EventuallyRedrawItem( itemPtr->redraw_flags |= FORCE_REDRAW; } if (!(canvasPtr->flags & REDRAW_PENDING)) { - Tcl_DoWhenIdle(DisplayCanvas, (ClientData) canvasPtr); + Tcl_DoWhenIdle(DisplayCanvas, canvasPtr); canvasPtr->flags |= REDRAW_PENDING; } } /* - *-------------------------------------------------------------- + *---------------------------------------------------------------------- * * Tk_CreateItemType -- * @@ -2595,7 +2947,7 @@ EventuallyRedrawItem( * commands). If there was already a type with the same name as in * typePtr, it is replaced with the new type. * - *-------------------------------------------------------------- + *---------------------------------------------------------------------- */ void @@ -2735,11 +3087,8 @@ StartTagSearch( Tk_Uid uid; char *tag = Tcl_GetString(tagObj); int count; - TkWindow *tkwin; - TkDisplay *dispPtr; - - tkwin = (TkWindow *) canvasPtr->tkwin; - dispPtr = tkwin->dispPtr; + TkWindow *tkwin = (TkWindow *) canvasPtr->tkwin; + TkDisplay *dispPtr = tkwin->dispPtr; /* * Initialize the search. @@ -2767,9 +3116,9 @@ StartTagSearch( if ((itemPtr == NULL) || (itemPtr->id != id) || (lastPtr == NULL) || (lastPtr->nextPtr != itemPtr)) { dispPtr->numSlowSearches++; - entryPtr = Tcl_FindHashEntry(&canvasPtr->idTable, (char *) id); + entryPtr = Tcl_FindHashEntry(&canvasPtr->idTable, (char*) id); if (entryPtr != NULL) { - itemPtr = (Tk_Item *)Tcl_GetHashValue(entryPtr); + itemPtr = Tcl_GetHashValue(entryPtr); lastPtr = itemPtr->prevPtr; } else { lastPtr = itemPtr = NULL; @@ -2925,7 +3274,7 @@ NextItem( static SearchUids * GetStaticUids(void) { - SearchUids *searchUids = (SearchUids *) + SearchUids *searchUids = Tcl_GetThreadData(&dataKey, sizeof(SearchUids)); if (searchUids->allUid == NULL) { @@ -2961,10 +3310,10 @@ static void TagSearchExprInit( TagSearchExpr **exprPtrPtr) { - TagSearchExpr* expr = *exprPtrPtr; + TagSearchExpr *expr = *exprPtrPtr; - if (! expr) { - expr = (TagSearchExpr *) ckalloc(sizeof(TagSearchExpr)); + if (expr == NULL) { + expr = ckalloc(sizeof(TagSearchExpr)); expr->allocated = 0; expr->uids = NULL; expr->next = NULL; @@ -2993,11 +3342,11 @@ static void TagSearchExprDestroy( TagSearchExpr *expr) { - if (expr) { + if (expr != NULL) { if (expr->uids) { - ckfree((char *)expr->uids); + ckfree(expr->uids); } - ckfree((char *)expr); + ckfree(expr); } } @@ -3030,7 +3379,7 @@ TagSearchScan( TagSearch **searchPtrPtr) /* Record describing tag search; will be * initialized here. */ { - char *tag = Tcl_GetString(tagObj); + const char *tag = Tcl_GetString(tagObj); int i; TagSearch *searchPtr; @@ -3038,14 +3387,14 @@ TagSearchScan( * Initialize the search. */ - if (*searchPtrPtr) { + if (*searchPtrPtr != NULL) { searchPtr = *searchPtrPtr; } else { /* * Allocate primary search struct on first call. */ - *searchPtrPtr = searchPtr = (TagSearch *) ckalloc(sizeof(TagSearch)); + *searchPtrPtr = searchPtr = ckalloc(sizeof(TagSearch)); searchPtr->expr = NULL; /* @@ -3055,7 +3404,7 @@ TagSearchScan( searchPtr->rewritebufferAllocated = 100; searchPtr->rewritebuffer = ckalloc(searchPtr->rewritebufferAllocated); } - TagSearchExprInit(&(searchPtr->expr)); + TagSearchExprInit(&searchPtr->expr); /* * How long is the tagOrId? @@ -3067,7 +3416,7 @@ TagSearchScan( * Make sure there is enough buffer to hold rewritten tags. */ - if ((unsigned int)searchPtr->stringLength >= + if ((unsigned) searchPtr->stringLength >= searchPtr->rewritebufferAllocated) { searchPtr->rewritebufferAllocated = searchPtr->stringLength + 100; searchPtr->rewritebuffer = @@ -3105,6 +3454,7 @@ TagSearchScan( * kept forever, but this should be thought of as a cache rather than as a * memory leak. */ + searchPtr->expr->uid = Tk_GetUid(tag); /* @@ -3116,8 +3466,8 @@ TagSearchScan( } /* - * Pre-scan tag for at least one unquoted "&&" "||" "^" "!" - * if not found then use string as simple tag + * Pre-scan tag for at least one unquoted "&&" "||" "^" "!"; if not found + * then use string as simple tag. */ for (i = 0; i < searchPtr->stringLength ; i++) { @@ -3194,12 +3544,12 @@ TagSearchScan( static void TagSearchDestroy( - TagSearch *searchPtr) /* Record describing tag search */ + TagSearch *searchPtr) /* Record describing tag search. */ { if (searchPtr) { TagSearchExprDestroy(searchPtr->expr); - ckfree((char *)searchPtr->rewritebuffer); - ckfree((char *)searchPtr); + ckfree(searchPtr->rewritebuffer); + ckfree(searchPtr); } } @@ -3225,15 +3575,15 @@ TagSearchDestroy( static int TagSearchScanExpr( Tcl_Interp *interp, /* Current interpreter. */ - TagSearch *searchPtr, /* Search data */ - TagSearchExpr *expr) /* compiled expression result */ + TagSearch *searchPtr, /* Search data. */ + TagSearchExpr *expr) /* Compiled expression result. */ { int looking_for_tag; /* When true, scanner expects next char(s) to - * be a tag, else operand expected */ - int found_tag; /* One or more tags found */ - int found_endquote; /* For quoted tag string parsing */ - int negate_result; /* Pending negation of next tag value */ - char *tag; /* Tag from tag expression string */ + * be a tag, else operand expected. */ + int found_tag; /* One or more tags found. */ + int found_endquote; /* For quoted tag string parsing. */ + int negate_result; /* Pending negation of next tag value. */ + char *tag; /* Tag from tag expression string. */ char c; SearchUids *searchUids; /* Collection of uids for basic search * expression terms. */ @@ -3252,36 +3602,34 @@ TagSearchScanExpr( if (expr->index >= expr->allocated-1) { expr->allocated += 15; if (expr->uids) { - expr->uids = (Tk_Uid *) - ckrealloc((char *)(expr->uids), - (expr->allocated)*sizeof(Tk_Uid)); + expr->uids = ckrealloc(expr->uids, + expr->allocated * sizeof(Tk_Uid)); } else { - expr->uids = (Tk_Uid *) - ckalloc((expr->allocated)*sizeof(Tk_Uid)); + expr->uids = ckalloc(expr->allocated * sizeof(Tk_Uid)); } } if (looking_for_tag) { - switch (c) { - case ' ': /* ignore unquoted whitespace */ + case ' ': /* Ignore unquoted whitespace */ case '\t': case '\n': case '\r': break; - case '!': /* negate next tag or subexpr */ + case '!': /* Negate next tag or subexpr */ if (looking_for_tag > 1) { - Tcl_AppendResult(interp, - "Too many '!' in tag search expression", - NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "too many '!' in tag search expression", -1)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "SEARCH", + "COMPLEXITY", NULL); return TCL_ERROR; } looking_for_tag++; negate_result = 1; break; - case '(': /* scan (negated) subexpr recursively */ + case '(': /* Scan (negated) subexpr recursively */ if (negate_result) { expr->uids[expr->index++] = searchUids->negparenUid; negate_result = 0; @@ -3300,7 +3648,7 @@ TagSearchScanExpr( found_tag = 1; break; - case '"': /* quoted tag string */ + case '"': /* Quoted tag string */ if (negate_result) { expr->uids[expr->index++] = searchUids->negtagvalUid; negate_result = 0; @@ -3320,16 +3668,19 @@ TagSearchScanExpr( } *tag++ = c; } - if (! found_endquote) { - Tcl_AppendResult(interp, - "Missing endquote in tag search expression", - NULL); + if (!found_endquote) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "missing endquote in tag search expression", -1)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "SEARCH", + "ENDQUOTE", NULL); return TCL_ERROR; } - if (! (tag - searchPtr->rewritebuffer)) { - Tcl_AppendResult(interp, - "Null quoted tag string in tag search expression", - NULL); + if (!(tag - searchPtr->rewritebuffer)) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "null quoted tag string in tag search expression", + -1)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "SEARCH", + "EMPTY", NULL); return TCL_ERROR; } *tag++ = '\0'; @@ -3339,16 +3690,17 @@ TagSearchScanExpr( found_tag = 1; break; - case '&': /* illegal chars when looking for tag */ + case '&': /* Illegal chars when looking for tag */ case '|': case '^': case ')': - Tcl_AppendResult(interp, - "Unexpected operator in tag search expression", - NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "unexpected operator in tag search expression", -1)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "SEARCH", + "UNEXPECTED", NULL); return TCL_ERROR; - default: /* unquoted tag string */ + default: /* Unquoted tag string */ if (negate_result) { expr->uids[expr->index++] = searchUids->negtagvalUid; negate_result = 0; @@ -3395,50 +3747,54 @@ TagSearchScanExpr( found_tag = 1; } - } else { /* ! looking_for_tag */ + } else { /* ! looking_for_tag */ switch (c) { - case ' ': /* ignore whitespace */ + case ' ': /* Ignore whitespace */ case '\t': case '\n': case '\r': break; - case '&': /* AND operator */ + case '&': /* AND operator */ c = searchPtr->string[searchPtr->stringIndex++]; if (c != '&') { - Tcl_AppendResult(interp, - "Singleton '&' in tag search expression", - NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "singleton '&' in tag search expression", -1)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "SEARCH", + "INCOMPLETE_OP", NULL); return TCL_ERROR; } expr->uids[expr->index++] = searchUids->andUid; looking_for_tag = 1; break; - case '|': /* OR operator */ + case '|': /* OR operator */ c = searchPtr->string[searchPtr->stringIndex++]; if (c != '|') { - Tcl_AppendResult(interp, - "Singleton '|' in tag search expression", - NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "singleton '|' in tag search expression", -1)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "SEARCH", + "INCOMPLETE_OP", NULL); return TCL_ERROR; } expr->uids[expr->index++] = searchUids->orUid; looking_for_tag = 1; break; - case '^' : /* XOR operator */ + case '^': /* XOR operator */ expr->uids[expr->index++] = searchUids->xorUid; looking_for_tag = 1; break; - case ')' : /* end subexpression */ + case ')': /* End subexpression */ expr->uids[expr->index++] = searchUids->endparenUid; goto breakwhile; - default: /* syntax error */ - Tcl_AppendResult(interp, - "Invalid boolean operator in tag search expression", + default: /* syntax error */ + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "invalid boolean operator in tag search expression", + -1)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "SEARCH", "BAD_OP", NULL); return TCL_ERROR; } @@ -3446,10 +3802,12 @@ TagSearchScanExpr( } breakwhile: - if (found_tag && ! looking_for_tag) { + if (found_tag && !looking_for_tag) { return TCL_OK; } - Tcl_AppendResult(interp, "Missing tag in tag search expression", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "missing tag in tag search expression", -1)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "SEARCH", "NO_TAG", NULL); return TCL_ERROR; } @@ -3486,7 +3844,7 @@ TagSearchEvalExpr( * expression terms. */ searchUids = GetStaticUids(); - result = 0; /* just to keep the compiler quiet */ + result = 0; /* Just to keep the compiler quiet. */ negate_result = 0; looking_for_tag = 1; @@ -3521,7 +3879,7 @@ TagSearchEvalExpr( result = 0; /* - * set result 1 if tag is found in item's tags + * set result 1 if tag is found in item's tags. */ for (tagPtr = itemPtr->tagPtr, count = itemPtr->numTags; @@ -3534,30 +3892,26 @@ TagSearchEvalExpr( } else if (uid == searchUids->parenUid) { /* - * Evaluate subexpressions with recursion + * Evaluate subexpressions with recursion. */ result = TagSearchEvalExpr(expr, itemPtr); } else if (uid == searchUids->negparenUid) { - negate_result = ! negate_result; + negate_result = !negate_result; /* - * Evaluate subexpressions with recursion + * Evaluate subexpressions with recursion. */ result = TagSearchEvalExpr(expr, itemPtr); -/* - * } else { - * assert(0); - */ } if (negate_result) { result = ! result; negate_result = 0; } looking_for_tag = 0; - } else { /* ! looking_for_tag */ + } else { /* ! looking_for_tag */ if (((uid == searchUids->andUid) && (!result)) || ((uid == searchUids->orUid) && result)) { /* @@ -3599,16 +3953,12 @@ TagSearchEvalExpr( } else if (uid == searchUids->endparenUid) { return result; -/* - * } else { - * assert(0); - */ } looking_for_tag = 1; } } /* - * assert(! looking_for_tag); + * assert(!looking_for_tag); */ return result; } @@ -3667,7 +4017,7 @@ TagSearchFirst( entryPtr = Tcl_FindHashEntry(&searchPtr->canvasPtr->idTable, (char *) INT2PTR(searchPtr->id)); if (entryPtr != NULL) { - itemPtr = (Tk_Item *)Tcl_GetHashValue(entryPtr); + itemPtr = Tcl_GetHashValue(entryPtr); lastPtr = itemPtr->prevPtr; } else { lastPtr = itemPtr = NULL; @@ -3697,7 +4047,7 @@ TagSearchFirst( uid = searchPtr->expr->uid; for (lastPtr = NULL, itemPtr = searchPtr->canvasPtr->firstItemPtr; - itemPtr != NULL; lastPtr = itemPtr, itemPtr = itemPtr->nextPtr) { + itemPtr != NULL; lastPtr=itemPtr, itemPtr=itemPtr->nextPtr) { for (tagPtr = itemPtr->tagPtr, count = itemPtr->numTags; count > 0; tagPtr++, count--) { if (*tagPtr == uid) { @@ -3708,7 +4058,6 @@ TagSearchFirst( } } } else { - /* * None of the above. Search for an item matching the tag expression. */ @@ -3839,23 +4188,23 @@ TagSearchNext( * DoItem -- * * This is a utility function called by FindItems. It either adds - * itemPtr's id to the result forming in interp, or it adds a new tag to + * itemPtr's id to the list being constructed, or it adds a new tag to * itemPtr, depending on the value of tag. * * Results: * None. * * Side effects: - * If tag is NULL then itemPtr's id is added as a list element to the - * interp's result; otherwise tag is added to itemPtr's list of tags. + * If tag is NULL then itemPtr's id is added as an element to the + * supplied object; otherwise tag is added to itemPtr's list of tags. * *-------------------------------------------------------------- */ static void DoItem( - Tcl_Interp *interp, /* Interpreter in which to (possibly) record - * item id. */ + Tcl_Obj *accumObj, /* Object in which to (possibly) record item + * id. */ Tk_Item *itemPtr, /* Item to (possibly) modify. */ Tk_Uid tag) /* Tag to add to those already present for * item, or NULL. */ @@ -3868,10 +4217,7 @@ DoItem( */ if (tag == NULL) { - char msg[TCL_INTEGER_SPACE]; - - sprintf(msg, "%d", itemPtr->id); - Tcl_AppendElement(interp, msg); + Tcl_ListObjAppendElement(NULL, accumObj, Tcl_NewIntObj(itemPtr->id)); return; } @@ -3890,12 +4236,11 @@ DoItem( Tk_Uid *newTagPtr; itemPtr->tagSpace += 5; - newTagPtr = (Tk_Uid *) - ckalloc((unsigned) (itemPtr->tagSpace * sizeof(Tk_Uid))); + newTagPtr = ckalloc(itemPtr->tagSpace * sizeof(Tk_Uid)); memcpy((void *) newTagPtr, itemPtr->tagPtr, itemPtr->numTags * sizeof(Tk_Uid)); if (itemPtr->tagPtr != itemPtr->staticTagSpace) { - ckfree((char *) itemPtr->tagPtr); + ckfree(itemPtr->tagPtr); } itemPtr->tagPtr = newTagPtr; tagPtr = &itemPtr->tagPtr[itemPtr->numTags]; @@ -3938,7 +4283,7 @@ FindItems( TkCanvas *canvasPtr, /* Canvas whose items are to be searched. */ int objc, /* Number of entries in argv. Must be greater * than zero. */ - Tcl_Obj *CONST *objv, /* Arguments that describe what items to + Tcl_Obj *const *objv, /* Arguments that describe what items to * search for (see user doc on "find" and * "addtag" options). */ Tcl_Obj *newTag, /* If non-NULL, gives new tag to set on all @@ -3959,7 +4304,8 @@ FindItems( Tk_Item *itemPtr; Tk_Uid uid; int index, result; - static CONST char *optionStrings[] = { + Tcl_Obj *resultObj; + static const char *const optionStrings[] = { "above", "all", "below", "closest", "enclosed", "overlapping", "withtag", NULL }; @@ -3990,7 +4336,9 @@ FindItems( lastPtr = itemPtr; } if ((lastPtr != NULL) && (lastPtr->nextPtr != NULL)) { - DoItem(interp, lastPtr->nextPtr, uid); + resultObj = Tcl_NewObj(); + DoItem(resultObj, lastPtr->nextPtr, uid); + Tcl_SetObjResult(interp, resultObj); } break; } @@ -4000,10 +4348,12 @@ FindItems( return TCL_ERROR; } + resultObj = Tcl_NewObj(); for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL; itemPtr = itemPtr->nextPtr) { - DoItem(interp, itemPtr, uid); + DoItem(resultObj, itemPtr, uid); } + Tcl_SetObjResult(interp, resultObj); break; case CANV_BELOW: @@ -4013,10 +4363,10 @@ FindItems( } FIRST_CANVAS_ITEM_MATCHING(objv[first+1], searchPtrPtr, return TCL_ERROR); - if (itemPtr != NULL) { - if (itemPtr->prevPtr != NULL) { - DoItem(interp, itemPtr->prevPtr, uid); - } + if ((itemPtr != NULL) && (itemPtr->prevPtr != NULL)) { + resultObj = Tcl_NewObj(); + DoItem(resultObj, itemPtr->prevPtr, uid); + Tcl_SetObjResult(interp, resultObj); } break; case CANV_CLOSEST: { @@ -4029,19 +4379,20 @@ FindItems( Tcl_WrongNumArgs(interp, first+1, objv, "x y ?halo? ?start?"); return TCL_ERROR; } - if ((Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, objv[first+1], - &coords[0]) != TCL_OK) || (Tk_CanvasGetCoordFromObj(interp, - (Tk_Canvas) canvasPtr, objv[first+2], &coords[1]) != TCL_OK)) { + if (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, + objv[first+1], &coords[0]) != TCL_OK + || Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, + objv[first+2], &coords[1]) != TCL_OK) { return TCL_ERROR; } if (objc > first+3) { - if (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, objv[first+3], - &halo) != TCL_OK) { + if (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, + objv[first+3], &halo) != TCL_OK) { return TCL_ERROR; } if (halo < 0.0) { - Tcl_AppendResult(interp, "can't have negative halo value \"", - Tcl_GetString(objv[3]), "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't have negative halo value \"%f\"", halo)); return TCL_ERROR; } } else { @@ -4078,11 +4429,7 @@ FindItems( if (itemPtr == NULL) { return TCL_OK; } - closestDist = (*itemPtr->typePtr->pointProc)((Tk_Canvas) canvasPtr, - itemPtr, coords) - halo; - if (closestDist < 0.0) { - closestDist = 0.0; - } + closestDist = ItemPoint(canvasPtr, itemPtr, coords, halo); while (1) { double newDist; @@ -4109,7 +4456,9 @@ FindItems( itemPtr = canvasPtr->firstItemPtr; } if (itemPtr == startPtr) { - DoItem(interp, closestPtr, uid); + resultObj = Tcl_NewObj(); + DoItem(resultObj, closestPtr, uid); + Tcl_SetObjResult(interp, resultObj); return TCL_OK; } if (itemPtr->state == TK_STATE_HIDDEN || @@ -4121,11 +4470,7 @@ FindItems( || (itemPtr->y1 >= y2) || (itemPtr->y2 <= y1)) { continue; } - newDist = (*itemPtr->typePtr->pointProc)((Tk_Canvas) canvasPtr, - itemPtr, coords) - halo; - if (newDist < 0.0) { - newDist = 0.0; - } + newDist = ItemPoint(canvasPtr, itemPtr, coords, halo); if (newDist <= closestDist) { closestDist = newDist; break; @@ -4151,10 +4496,16 @@ FindItems( Tcl_WrongNumArgs(interp, first+1, objv, "tagOrId"); return TCL_ERROR; } + resultObj = Tcl_NewObj(); FOR_EVERY_CANVAS_ITEM_MATCHING(objv[first+1], searchPtrPtr, - return TCL_ERROR) { - DoItem(interp, itemPtr, uid); + goto badWithTagSearch) { + DoItem(resultObj, itemPtr, uid); } + Tcl_SetObjResult(interp, resultObj); + return TCL_OK; + badWithTagSearch: + Tcl_DecrRefCount(resultObj); + return TCL_ERROR; } return TCL_OK; } @@ -4186,7 +4537,7 @@ FindArea( Tcl_Interp *interp, /* Interpreter for error reporting and result * storing. */ TkCanvas *canvasPtr, /* Canvas whose items are to be searched. */ - Tcl_Obj *CONST *objv, /* Array of four arguments that give the + Tcl_Obj *const *objv, /* Array of four arguments that give the * coordinates of the rectangular area to * search. */ Tk_Uid uid, /* If non-NULL, gives new tag to set on all @@ -4199,14 +4550,15 @@ FindArea( double rect[4], tmp; int x1, y1, x2, y2; Tk_Item *itemPtr; + Tcl_Obj *resultObj; if ((Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, objv[0], &rect[0]) != TCL_OK) - || (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, objv[1], + || (Tk_CanvasGetCoordFromObj(interp,(Tk_Canvas)canvasPtr,objv[1], &rect[1]) != TCL_OK) - || (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, objv[2], + || (Tk_CanvasGetCoordFromObj(interp,(Tk_Canvas)canvasPtr,objv[2], &rect[2]) != TCL_OK) - || (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr, objv[3], + || (Tk_CanvasGetCoordFromObj(interp,(Tk_Canvas)canvasPtr,objv[3], &rect[3]) != TCL_OK)) { return TCL_ERROR; } @@ -4222,25 +4574,27 @@ FindArea( * item-specific code except for items that are close. */ - x1 = (int) (rect[0]-1.0); - y1 = (int) (rect[1]-1.0); - x2 = (int) (rect[2]+1.0); - y2 = (int) (rect[3]+1.0); + x1 = (int) (rect[0] - 1.0); + y1 = (int) (rect[1] - 1.0); + x2 = (int) (rect[2] + 1.0); + y2 = (int) (rect[3] + 1.0); + resultObj = Tcl_NewObj(); for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL; itemPtr = itemPtr->nextPtr) { - if (itemPtr->state == TK_STATE_HIDDEN || (itemPtr->state == TK_STATE_NULL && - canvasPtr->canvas_state == TK_STATE_HIDDEN)) { + if (itemPtr->state == TK_STATE_HIDDEN || + (itemPtr->state == TK_STATE_NULL + && canvasPtr->canvas_state == TK_STATE_HIDDEN)) { continue; } if ((itemPtr->x1 >= x2) || (itemPtr->x2 <= x1) || (itemPtr->y1 >= y2) || (itemPtr->y2 <= y1)) { continue; } - if ((*itemPtr->typePtr->areaProc)((Tk_Canvas) canvasPtr, itemPtr, rect) - >= enclosed) { - DoItem(interp, itemPtr, uid); + if (ItemOverlap(canvasPtr, itemPtr, rect) >= enclosed) { + DoItem(resultObj, itemPtr, uid); } } + Tcl_SetObjResult(interp, resultObj); return TCL_OK; } @@ -4329,7 +4683,7 @@ RelinkItems( lastMovePtr->nextPtr = itemPtr; } lastMovePtr = itemPtr; - EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr); + EventuallyRedrawItem(canvasPtr, itemPtr); canvasPtr->flags |= REPICK_NEEDED; } @@ -4392,9 +4746,10 @@ CanvasBindProc( ClientData clientData, /* Pointer to canvas structure. */ XEvent *eventPtr) /* Pointer to X event that just happened. */ { - TkCanvas *canvasPtr = (TkCanvas *) clientData; + TkCanvas *canvasPtr = clientData; + int mask; - Tcl_Preserve((ClientData) canvasPtr); + Tcl_Preserve(canvasPtr); /* * This code below keeps track of the current modifier state in @@ -4402,9 +4757,9 @@ CanvasBindProc( * current item while buttons are down. */ - if ((eventPtr->type == ButtonPress) || (eventPtr->type == ButtonRelease)) { - int mask; - + switch (eventPtr->type) { + case ButtonPress: + case ButtonRelease: switch (eventPtr->xbutton.button) { case Button1: mask = Button1Mask; @@ -4458,20 +4813,21 @@ CanvasBindProc( PickCurrentItem(canvasPtr, eventPtr); eventPtr->xbutton.state ^= mask; } - goto done; - } else if ((eventPtr->type == EnterNotify) - || (eventPtr->type == LeaveNotify)) { + break; + case EnterNotify: + case LeaveNotify: canvasPtr->state = eventPtr->xcrossing.state; PickCurrentItem(canvasPtr, eventPtr); - goto done; - } else if (eventPtr->type == MotionNotify) { + break; + case MotionNotify: canvasPtr->state = eventPtr->xmotion.state; PickCurrentItem(canvasPtr, eventPtr); + /* fallthrough */ + default: + CanvasDoEvent(canvasPtr, eventPtr); } - CanvasDoEvent(canvasPtr, eventPtr); - done: - Tcl_Release((ClientData) canvasPtr); + Tcl_Release(canvasPtr); } /* @@ -4553,11 +4909,11 @@ PickCurrentItem( canvasPtr->pickEvent.xcrossing.y_root = eventPtr->xmotion.y_root; canvasPtr->pickEvent.xcrossing.mode = NotifyNormal; canvasPtr->pickEvent.xcrossing.detail = NotifyNonlinear; - canvasPtr->pickEvent.xcrossing.same_screen - = eventPtr->xmotion.same_screen; + canvasPtr->pickEvent.xcrossing.same_screen = + eventPtr->xmotion.same_screen; canvasPtr->pickEvent.xcrossing.focus = False; canvasPtr->pickEvent.xcrossing.state = eventPtr->xmotion.state; - } else { + } else { canvasPtr->pickEvent = *eventPtr; } } @@ -4589,7 +4945,7 @@ PickCurrentItem( if ((canvasPtr->newCurrentPtr == canvasPtr->currentItemPtr) && !(canvasPtr->flags & LEFT_GRABBED_ITEM)) { /* - * Nothing to do: the current item hasn't changed. + * Nothing to do: the current item hasn't changed. */ return; @@ -4652,7 +5008,7 @@ PickCurrentItem( * deleted. */ } - if ((canvasPtr->newCurrentPtr != canvasPtr->currentItemPtr) && buttonDown) { + if ((canvasPtr->newCurrentPtr!=canvasPtr->currentItemPtr) && buttonDown) { canvasPtr->flags |= LEFT_GRABBED_ITEM; return; } @@ -4668,10 +5024,8 @@ PickCurrentItem( canvasPtr->currentItemPtr = canvasPtr->newCurrentPtr; if (prevItemPtr != NULL && prevItemPtr != canvasPtr->currentItemPtr && (prevItemPtr->redraw_flags & TK_ITEM_STATE_DEPENDANT)) { - EventuallyRedrawItem((Tk_Canvas) canvasPtr, prevItemPtr); - (*prevItemPtr->typePtr->configProc)(canvasPtr->interp, - (Tk_Canvas) canvasPtr, prevItemPtr, 0, NULL, - TK_CONFIG_ARGV_ONLY); + EventuallyRedrawItem(canvasPtr, prevItemPtr); + ItemConfigure(canvasPtr, prevItemPtr, 0, NULL); } if (canvasPtr->currentItemPtr != NULL) { XEvent event; @@ -4680,14 +5034,11 @@ PickCurrentItem( DoItem(NULL, canvasPtr->currentItemPtr, Tk_GetUid("current")); #else /* USE_OLD_TAG_SEARCH */ DoItem(NULL, canvasPtr->currentItemPtr, searchUids->currentUid); -#endif /* USE_OLD_TAG_SEA */ - if ((canvasPtr->currentItemPtr->redraw_flags & TK_ITEM_STATE_DEPENDANT && - prevItemPtr != canvasPtr->currentItemPtr)) { - (*canvasPtr->currentItemPtr->typePtr->configProc)(canvasPtr->interp, - (Tk_Canvas) canvasPtr, canvasPtr->currentItemPtr, 0, NULL, - TK_CONFIG_ARGV_ONLY); - EventuallyRedrawItem((Tk_Canvas) canvasPtr, - canvasPtr->currentItemPtr); +#endif /* USE_OLD_TAG_SEARCH */ + if ((canvasPtr->currentItemPtr->redraw_flags & TK_ITEM_STATE_DEPENDANT + && prevItemPtr != canvasPtr->currentItemPtr)) { + ItemConfigure(canvasPtr, canvasPtr->currentItemPtr, 0, NULL); + EventuallyRedrawItem(canvasPtr, canvasPtr->currentItemPtr); } event = canvasPtr->pickEvent; event.type = EnterNotify; @@ -4733,8 +5084,10 @@ CanvasFindClosest( bestPtr = NULL; for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL; itemPtr = itemPtr->nextPtr) { - if (itemPtr->state == TK_STATE_HIDDEN || itemPtr->state==TK_STATE_DISABLED || - (itemPtr->state == TK_STATE_NULL && (canvasPtr->canvas_state == TK_STATE_HIDDEN || + if (itemPtr->state == TK_STATE_HIDDEN || + itemPtr->state==TK_STATE_DISABLED || + (itemPtr->state == TK_STATE_NULL && + (canvasPtr->canvas_state == TK_STATE_HIDDEN || canvasPtr->canvas_state == TK_STATE_DISABLED))) { continue; } @@ -4742,8 +5095,7 @@ CanvasFindClosest( || (itemPtr->y1 > y2) || (itemPtr->y2 < y1)) { continue; } - if ((*itemPtr->typePtr->pointProc)((Tk_Canvas) canvasPtr, - itemPtr, coords) <= canvasPtr->closeEnough) { + if (ItemPoint(canvasPtr,itemPtr,coords,0) <= canvasPtr->closeEnough) { bestPtr = itemPtr; } } @@ -4840,8 +5192,7 @@ CanvasDoEvent( if (numObjects <= NUM_STATIC) { objectPtr = staticObjects; } else { - objectPtr = (ClientData *) ckalloc((unsigned) - (numObjects * sizeof(ClientData))); + objectPtr = ckalloc(numObjects * sizeof(ClientData)); } #ifdef USE_OLD_TAG_SEARCH objectPtr[0] = (ClientData) Tk_GetUid("all"); @@ -4851,7 +5202,7 @@ CanvasDoEvent( for (i = itemPtr->numTags-1; i >= 0; i--) { objectPtr[i+1] = (ClientData) itemPtr->tagPtr[i]; } - objectPtr[itemPtr->numTags+1] = (ClientData) itemPtr; + objectPtr[itemPtr->numTags+1] = itemPtr; #ifndef USE_OLD_TAG_SEARCH /* @@ -4878,7 +5229,7 @@ CanvasDoEvent( numObjects, objectPtr); } if (objectPtr != staticObjects) { - ckfree((char *) objectPtr); + ckfree(objectPtr); } } @@ -4904,7 +5255,7 @@ static void CanvasBlinkProc( ClientData clientData) /* Pointer to record describing entry. */ { - TkCanvas *canvasPtr = (TkCanvas *) clientData; + TkCanvas *canvasPtr = clientData; if (!canvasPtr->textInfo.gotFocus || (canvasPtr->insertOffTime == 0)) { return; @@ -4912,18 +5263,13 @@ CanvasBlinkProc( if (canvasPtr->textInfo.cursorOn) { canvasPtr->textInfo.cursorOn = 0; canvasPtr->insertBlinkHandler = Tcl_CreateTimerHandler( - canvasPtr->insertOffTime, CanvasBlinkProc, - (ClientData) canvasPtr); + canvasPtr->insertOffTime, CanvasBlinkProc, canvasPtr); } else { canvasPtr->textInfo.cursorOn = 1; canvasPtr->insertBlinkHandler = Tcl_CreateTimerHandler( - canvasPtr->insertOnTime, CanvasBlinkProc, - (ClientData) canvasPtr); - } - if (canvasPtr->textInfo.focusItemPtr != NULL) { - EventuallyRedrawItem((Tk_Canvas) canvasPtr, - canvasPtr->textInfo.focusItemPtr); + canvasPtr->insertOnTime, CanvasBlinkProc, canvasPtr); } + EventuallyRedrawItem(canvasPtr, canvasPtr->textInfo.focusItemPtr); } /* @@ -4956,22 +5302,18 @@ CanvasFocusProc( canvasPtr->textInfo.cursorOn = 1; if (canvasPtr->insertOffTime != 0) { canvasPtr->insertBlinkHandler = Tcl_CreateTimerHandler( - canvasPtr->insertOffTime, CanvasBlinkProc, - (ClientData) canvasPtr); + canvasPtr->insertOffTime, CanvasBlinkProc, canvasPtr); } } else { canvasPtr->textInfo.gotFocus = 0; canvasPtr->textInfo.cursorOn = 0; canvasPtr->insertBlinkHandler = (Tcl_TimerToken) NULL; } - if (canvasPtr->textInfo.focusItemPtr != NULL) { - EventuallyRedrawItem((Tk_Canvas) canvasPtr, - canvasPtr->textInfo.focusItemPtr); - } + EventuallyRedrawItem(canvasPtr, canvasPtr->textInfo.focusItemPtr); if (canvasPtr->highlightWidth > 0) { canvasPtr->flags |= REDRAW_BORDERS; if (!(canvasPtr->flags & REDRAW_PENDING)) { - Tcl_DoWhenIdle(DisplayCanvas, (ClientData) canvasPtr); + Tcl_DoWhenIdle(DisplayCanvas, canvasPtr); canvasPtr->flags |= REDRAW_PENDING; } } @@ -5014,10 +5356,9 @@ CanvasSelectTo( if (canvasPtr->textInfo.selItemPtr == NULL) { Tk_OwnSelection(canvasPtr->tkwin, XA_PRIMARY, CanvasLostSelection, - (ClientData) canvasPtr); + canvasPtr); } else if (canvasPtr->textInfo.selItemPtr != itemPtr) { - EventuallyRedrawItem((Tk_Canvas) canvasPtr, - canvasPtr->textInfo.selItemPtr); + EventuallyRedrawItem(canvasPtr, canvasPtr->textInfo.selItemPtr); } canvasPtr->textInfo.selItemPtr = itemPtr; @@ -5035,7 +5376,7 @@ CanvasSelectTo( if ((canvasPtr->textInfo.selectFirst != oldFirst) || (canvasPtr->textInfo.selectLast != oldLast) || (itemPtr != oldSelPtr)) { - EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr); + EventuallyRedrawItem(canvasPtr, itemPtr); } } @@ -5070,16 +5411,9 @@ CanvasFetchSelection( * not including terminating NULL * character. */ { - TkCanvas *canvasPtr = (TkCanvas *) clientData; + TkCanvas *canvasPtr = clientData; - if (canvasPtr->textInfo.selItemPtr == NULL) { - return -1; - } - if (canvasPtr->textInfo.selItemPtr->typePtr->selectionProc == NULL) { - return -1; - } - return (*canvasPtr->textInfo.selItemPtr->typePtr->selectionProc)( - (Tk_Canvas) canvasPtr, canvasPtr->textInfo.selItemPtr, offset, + return ItemSelection(canvasPtr, canvasPtr->textInfo.selItemPtr, offset, buffer, maxBytes); } @@ -5105,12 +5439,9 @@ static void CanvasLostSelection( ClientData clientData) /* Information about entry widget. */ { - TkCanvas *canvasPtr = (TkCanvas *) clientData; + TkCanvas *canvasPtr = clientData; - if (canvasPtr->textInfo.selItemPtr != NULL) { - EventuallyRedrawItem((Tk_Canvas) canvasPtr, - canvasPtr->textInfo.selItemPtr); - } + EventuallyRedrawItem(canvasPtr, canvasPtr->textInfo.selItemPtr); canvasPtr->textInfo.selItemPtr = NULL; } @@ -5227,6 +5558,7 @@ CanvasUpdateScrollbars( int xOrigin, yOrigin, inset, width, height; int scrollX1, scrollX2, scrollY1, scrollY2; char *xScrollCmd, *yScrollCmd; + Tcl_DString buf; /* * Save all the relevant values from the canvasPtr, because it might be @@ -5234,14 +5566,14 @@ CanvasUpdateScrollbars( */ interp = canvasPtr->interp; - Tcl_Preserve((ClientData) interp); + Tcl_Preserve(interp); xScrollCmd = canvasPtr->xScrollCmd; if (xScrollCmd != NULL) { - Tcl_Preserve((ClientData) xScrollCmd); + Tcl_Preserve(xScrollCmd); } yScrollCmd = canvasPtr->yScrollCmd; if (yScrollCmd != NULL) { - Tcl_Preserve((ClientData) yScrollCmd); + Tcl_Preserve(yScrollCmd); } xOrigin = canvasPtr->xOrigin; yOrigin = canvasPtr->yOrigin; @@ -5256,29 +5588,39 @@ CanvasUpdateScrollbars( if (canvasPtr->xScrollCmd != NULL) { Tcl_Obj *fractions = ScrollFractions(xOrigin + inset, xOrigin + width - inset, scrollX1, scrollX2); - result = Tcl_VarEval(interp, xScrollCmd, " ", Tcl_GetString(fractions), - NULL); + + Tcl_DStringInit(&buf); + Tcl_DStringAppend(&buf, xScrollCmd, -1); + Tcl_DStringAppend(&buf, " ", -1); + Tcl_DStringAppend(&buf, Tcl_GetString(fractions), -1); + result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, 0); + Tcl_DStringFree(&buf); Tcl_DecrRefCount(fractions); if (result != TCL_OK) { - Tcl_BackgroundError(interp); + Tcl_BackgroundException(interp, result); } Tcl_ResetResult(interp); - Tcl_Release((ClientData) xScrollCmd); + Tcl_Release(xScrollCmd); } if (yScrollCmd != NULL) { Tcl_Obj *fractions = ScrollFractions(yOrigin + inset, yOrigin + height - inset, scrollY1, scrollY2); - result = Tcl_VarEval(interp, yScrollCmd, " ", Tcl_GetString(fractions), - NULL); + + Tcl_DStringInit(&buf); + Tcl_DStringAppend(&buf, yScrollCmd, -1); + Tcl_DStringAppend(&buf, " ", -1); + Tcl_DStringAppend(&buf, Tcl_GetString(fractions), -1); + result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, 0); + Tcl_DStringFree(&buf); Tcl_DecrRefCount(fractions); if (result != TCL_OK) { - Tcl_BackgroundError(interp); + Tcl_BackgroundException(interp, result); } Tcl_ResetResult(interp); - Tcl_Release((ClientData) yScrollCmd); + Tcl_Release(yScrollCmd); } - Tcl_Release((ClientData) interp); + Tcl_Release(interp); } /* @@ -5344,11 +5686,11 @@ CanvasSetOrigin( * Adjust the origin if necessary to keep as much as possible of the * canvas in the view. The variables left, right, etc. keep track of how * much extra space there is on each side of the view before it will stick - * out past the scroll region. If one side sticks out past the edge of - * the scroll region, adjust the view to bring that side back to the edge - * of the scrollregion (but don't move it so much that the other side - * sticks out now). If scroll increments are in effect, be sure to adjust - * only by full increments. + * out past the scroll region. If one side sticks out past the edge of the + * scroll region, adjust the view to bring that side back to the edge of + * the scrollregion (but don't move it so much that the other side sticks + * out now). If scroll increments are in effect, be sure to adjust only by + * full increments. */ if ((canvasPtr->confine) && (canvasPtr->regionString != NULL)) { @@ -5427,17 +5769,18 @@ CanvasSetOrigin( */ /* ARGSUSED */ -static CONST char ** +static const char ** TkGetStringsFromObjs( int objc, - Tcl_Obj *CONST objv[]) + Tcl_Obj *const objv[]) { register int i; - CONST char **argv; + const char **argv; + if (objc <= 0) { return NULL; } - argv = (CONST char **) ckalloc((objc+1) * sizeof(char *)); + argv = ckalloc((objc+1) * sizeof(char *)); for (i = 0; i < objc; i++) { argv[i] = Tcl_GetString(objv[i]); } @@ -5473,8 +5816,7 @@ Tk_CanvasPsColor( Tk_Canvas canvas, /* Information about canvas. */ XColor *colorPtr) /* Information about color. */ { - return Tk_PostscriptColor(interp, ((TkCanvas *) canvas)->psInfo, - colorPtr); + return Tk_PostscriptColor(interp, Canvas(canvas)->psInfo, colorPtr); } /* @@ -5507,7 +5849,7 @@ Tk_CanvasPsFont( Tk_Font tkfont) /* Information about font in which text is to * be printed. */ { - return Tk_PostscriptFont(interp, ((TkCanvas *) canvas)->psInfo, tkfont); + return Tk_PostscriptFont(interp, Canvas(canvas)->psInfo, tkfont); } /* @@ -5540,9 +5882,8 @@ Tk_CanvasPsBitmap( * rectangular region to output. */ int width, int height) /* Size of rectangular region. */ { - return Tk_PostscriptBitmap(interp, ((TkCanvas *) canvas)->tkwin, - ((TkCanvas *) canvas)->psInfo, bitmap, startX, startY, - width, height); + return Tk_PostscriptBitmap(interp, Canvas(canvas)->tkwin, + Canvas(canvas)->psInfo, bitmap, startX, startY, width, height); } /* @@ -5574,8 +5915,8 @@ Tk_CanvasPsStipple( Tk_Canvas canvas, /* Information about canvas. */ Pixmap bitmap) /* Bitmap to use for stippling. */ { - return Tk_PostscriptStipple(interp, ((TkCanvas *) canvas)->tkwin, - ((TkCanvas *) canvas)->psInfo, bitmap); + return Tk_PostscriptStipple(interp, Canvas(canvas)->tkwin, + Canvas(canvas)->psInfo, bitmap); } /* @@ -5601,7 +5942,7 @@ Tk_CanvasPsY( * is being generated. */ double y) /* Y-coordinate in canvas coords. */ { - return Tk_PostscriptY(y, ((TkCanvas *) canvas)->psInfo); + return Tk_PostscriptY(y, Canvas(canvas)->psInfo); } /* @@ -5631,8 +5972,7 @@ Tk_CanvasPsPath( * coordinates giving points for path. */ int numPoints) /* Number of points at *coordPtr. */ { - Tk_PostscriptPath(interp, ((TkCanvas *) canvas)->psInfo, - coordPtr, numPoints); + Tk_PostscriptPath(interp, Canvas(canvas)->psInfo, coordPtr, numPoints); } /* diff --git a/generic/tkCanvas.h b/generic/tkCanvas.h index 5e784e3..e2221a8 100644 --- a/generic/tkCanvas.h +++ b/generic/tkCanvas.h @@ -291,7 +291,7 @@ typedef struct TkCanvas { */ MODULE_SCOPE int TkCanvPostscriptCmd(TkCanvas *canvasPtr, - Tcl_Interp *interp, int argc, CONST char **argv); + Tcl_Interp *interp, int argc, const char **argv); MODULE_SCOPE int TkCanvTranslatePath(TkCanvas *canvPtr, int numVertex, double *coordPtr, int closed, XPoint *outPtr); @@ -303,4 +303,10 @@ MODULE_SCOPE Tk_ItemType tkArcType, tkBitmapType, tkImageType, tkLineType; MODULE_SCOPE Tk_ItemType tkOvalType, tkPolygonType; MODULE_SCOPE Tk_ItemType tkRectangleType, tkTextType, tkWindowType; +/* + * Convenience macro. + */ + +#define Canvas(canvas) ((TkCanvas *) (canvas)) + #endif /* _TKCANVAS */ diff --git a/generic/tkClipboard.c b/generic/tkClipboard.c index c6748a1..b902625 100644 --- a/generic/tkClipboard.c +++ b/generic/tkClipboard.c @@ -27,7 +27,7 @@ static int ClipboardWindowHandler(ClientData clientData, int offset, char *buffer, int maxBytes); static void ClipboardLostSel(ClientData clientData); static int ClipboardGetProc(ClientData clientData, - Tcl_Interp *interp, char *portion); + Tcl_Interp *interp, const char *portion); /* *---------------------------------------------------------------------- @@ -56,7 +56,7 @@ ClipboardHandler( char *buffer, /* Place to store converted selection. */ int maxBytes) /* Maximum # of bytes to store at buffer. */ { - TkClipboardTarget *targetPtr = (TkClipboardTarget*) clientData; + TkClipboardTarget *targetPtr = clientData; TkClipboardBuffer *cbPtr; char *srcPtr, *destPtr; size_t count = 0; @@ -134,9 +134,9 @@ ClipboardAppHandler( char *buffer, /* Place to store converted selection. */ int maxBytes) /* Maximum # of bytes to store at buffer. */ { - TkDisplay *dispPtr = (TkDisplay *) clientData; + TkDisplay *dispPtr = clientData; size_t length; - CONST char *p; + const char *p; p = dispPtr->clipboardAppPtr->winPtr->nameUid; length = strlen(p); @@ -205,7 +205,7 @@ static void ClipboardLostSel( ClientData clientData) /* Pointer to TkDisplay structure. */ { - TkDisplay *dispPtr = (TkDisplay*) clientData; + TkDisplay *dispPtr = clientData; dispPtr->clipboardActive = 0; } @@ -267,12 +267,12 @@ Tk_ClipboardClear( cbPtr = nextCbPtr) { ckfree(cbPtr->buffer); nextCbPtr = cbPtr->nextPtr; - ckfree((char *) cbPtr); + ckfree(cbPtr); } nextTargetPtr = targetPtr->nextPtr; Tk_DeleteSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom, targetPtr->type); - ckfree((char *) targetPtr); + ckfree(targetPtr); } dispPtr->clipTargetPtr = NULL; @@ -282,7 +282,7 @@ Tk_ClipboardClear( if (!dispPtr->clipboardActive) { Tk_OwnSelection(dispPtr->clipWindow, dispPtr->clipboardAtom, - ClipboardLostSel, (ClientData) dispPtr); + ClipboardLostSel, dispPtr); dispPtr->clipboardActive = 1; } dispPtr->clipboardAppPtr = winPtr->mainPtr; @@ -324,7 +324,7 @@ Tk_ClipboardAppend( * clipboard item, e.g. STRING or LENGTH. */ Atom format, /* Format in which the selection information * should be returned to the requestor. */ - char* buffer) /* NULL terminated string containing the data + const char *buffer) /* NULL terminated string containing the data * to be added to the clipboard. */ { TkWindow *winPtr = (TkWindow *) tkwin; @@ -341,7 +341,7 @@ Tk_ClipboardAppend( Tk_ClipboardClear(interp, tkwin); } else if (!dispPtr->clipboardActive) { Tk_OwnSelection(dispPtr->clipWindow, dispPtr->clipboardAtom, - ClipboardLostSel, (ClientData) dispPtr); + ClipboardLostSel, dispPtr); dispPtr->clipboardActive = 1; } @@ -358,19 +358,21 @@ Tk_ClipboardAppend( } } if (targetPtr == NULL) { - targetPtr = (TkClipboardTarget*) ckalloc(sizeof(TkClipboardTarget)); + targetPtr = ckalloc(sizeof(TkClipboardTarget)); targetPtr->type = type; targetPtr->format = format; targetPtr->firstBufferPtr = targetPtr->lastBufferPtr = NULL; targetPtr->nextPtr = dispPtr->clipTargetPtr; dispPtr->clipTargetPtr = targetPtr; Tk_CreateSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom, - type, ClipboardHandler, (ClientData) targetPtr, format); + type, ClipboardHandler, targetPtr, format); } else if (targetPtr->format != format) { - Tcl_AppendResult(interp, "format \"", Tk_GetAtomName(tkwin, format), - "\" does not match current format \"", - Tk_GetAtomName(tkwin, targetPtr->format),"\" for ", - Tk_GetAtomName(tkwin, type), NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "format \"%s\" does not match current format \"%s\" for %s", + Tk_GetAtomName(tkwin, format), + Tk_GetAtomName(tkwin, targetPtr->format), + Tk_GetAtomName(tkwin, type))); + Tcl_SetErrorCode(interp, "TK", "CLIPBOARD", "FORMAT_MISMATCH", NULL); return TCL_ERROR; } @@ -378,7 +380,7 @@ Tk_ClipboardAppend( * Append a new buffer to the buffer chain. */ - cbPtr = (TkClipboardBuffer*) ckalloc(sizeof(TkClipboardBuffer)); + cbPtr = ckalloc(sizeof(TkClipboardBuffer)); cbPtr->nextPtr = NULL; if (targetPtr->lastBufferPtr != NULL) { targetPtr->lastBufferPtr->nextPtr = cbPtr; @@ -388,10 +390,10 @@ Tk_ClipboardAppend( targetPtr->lastBufferPtr = cbPtr; cbPtr->length = strlen(buffer); - cbPtr->buffer = (char *) ckalloc((unsigned) (cbPtr->length + 1)); + cbPtr->buffer = ckalloc(cbPtr->length + 1); strcpy(cbPtr->buffer, buffer); - TkSelUpdateClipboard((TkWindow*)(dispPtr->clipWindow), targetPtr); + TkSelUpdateClipboard((TkWindow *) dispPtr->clipWindow, targetPtr); return TCL_OK; } @@ -418,17 +420,17 @@ Tk_ClipboardObjCmd( ClientData clientData, /* Main window associated with interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument strings. */ + Tcl_Obj *const objv[]) /* Argument strings. */ { Tk_Window tkwin = (Tk_Window) clientData; - char *path = NULL; + const char *path = NULL; Atom selection; - static CONST char *optionStrings[] = { "append", "clear", "get", NULL }; + static const char *const optionStrings[] = { "append", "clear", "get", NULL }; enum options { CLIPBOARD_APPEND, CLIPBOARD_CLEAR, CLIPBOARD_GET }; int index, i; if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?"); + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); return TCL_ERROR; } @@ -440,10 +442,10 @@ Tk_ClipboardObjCmd( switch ((enum options) index) { case CLIPBOARD_APPEND: { Atom target, format; - char *targetName = NULL; - char *formatName = NULL; - char *string; - static CONST char *appendOptionStrings[] = { + const char *targetName = NULL; + const char *formatName = NULL; + const char *string; + static const char *const appendOptionStrings[] = { "-displayof", "-format", "-type", NULL }; enum appendOptions { APPEND_DISPLAYOF, APPEND_FORMAT, APPEND_TYPE }; @@ -474,8 +476,9 @@ Tk_ClipboardObjCmd( i++; if (i >= objc) { - Tcl_AppendResult(interp, "value for \"", string, - "\" missing", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "value for \"%s\" missing", string)); + Tcl_SetErrorCode(interp, "TK", "CLIPBOARD", "VALUE", NULL); return TCL_ERROR; } switch ((enum appendOptions) subIndex) { @@ -491,7 +494,7 @@ Tk_ClipboardObjCmd( } } if (objc - i != 1) { - Tcl_WrongNumArgs(interp, 2, objv, "?options? data"); + Tcl_WrongNumArgs(interp, 2, objv, "?-option value ...? data"); return TCL_ERROR; } if (path != NULL) { @@ -514,7 +517,7 @@ Tk_ClipboardObjCmd( Tcl_GetString(objv[i])); } case CLIPBOARD_CLEAR: { - static CONST char *clearOptionStrings[] = { "-displayof", NULL }; + static const char *const clearOptionStrings[] = { "-displayof", NULL }; enum clearOptions { CLEAR_DISPLAYOF }; int subIndex; @@ -542,11 +545,11 @@ Tk_ClipboardObjCmd( } case CLIPBOARD_GET: { Atom target; - char *targetName = NULL; + const char *targetName = NULL; Tcl_DString selBytes; int result; - char *string; - static CONST char *getOptionStrings[] = { + const char *string; + static const char *const getOptionStrings[] = { "-displayof", "-type", NULL }; enum getOptions { APPEND_DISPLAYOF, APPEND_TYPE }; @@ -563,8 +566,9 @@ Tk_ClipboardObjCmd( } i++; if (i >= objc) { - Tcl_AppendResult(interp, "value for \"", string, - "\" missing", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "value for \"%s\" missing", string)); + Tcl_SetErrorCode(interp, "TK", "CLIPBOARD", "VALUE", NULL); return TCL_ERROR; } switch ((enum getOptions) subIndex) { @@ -585,7 +589,7 @@ Tk_ClipboardObjCmd( selection = Tk_InternAtom(tkwin, "CLIPBOARD"); if (objc - i > 1) { - Tcl_WrongNumArgs(interp, 2, objv, "?options?"); + Tcl_WrongNumArgs(interp, 2, objv, "?-option value ...?"); return TCL_ERROR; } else if (objc - i == 1) { target = Tk_InternAtom(tkwin, Tcl_GetString(objv[i])); @@ -597,7 +601,7 @@ Tk_ClipboardObjCmd( Tcl_DStringInit(&selBytes); result = Tk_GetSelection(interp, tkwin, selection, target, - ClipboardGetProc, (ClientData) &selBytes); + ClipboardGetProc, &selBytes); if (result == TCL_OK) { Tcl_DStringResult(interp, &selBytes); } else { @@ -647,8 +651,9 @@ TkClipInit( dispPtr->clipWindow = (Tk_Window) TkAllocWindow(dispPtr, DefaultScreen(dispPtr->display), NULL); - Tcl_Preserve((ClientData) dispPtr->clipWindow); - ((TkWindow *) dispPtr->clipWindow)->flags |= TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED; + Tcl_Preserve(dispPtr->clipWindow); + ((TkWindow *) dispPtr->clipWindow)->flags |= + TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED; TkWmNewWindow((TkWindow *) dispPtr->clipWindow); atts.override_redirect = True; Tk_ChangeWindowAttributes(dispPtr->clipWindow, CWOverrideRedirect, &atts); @@ -670,11 +675,9 @@ TkClipInit( */ Tk_CreateSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom, - dispPtr->applicationAtom, ClipboardAppHandler, - (ClientData) dispPtr, XA_STRING); + dispPtr->applicationAtom, ClipboardAppHandler, dispPtr,XA_STRING); Tk_CreateSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom, - dispPtr->windowAtom, ClipboardWindowHandler, - (ClientData) dispPtr, XA_STRING); + dispPtr->windowAtom, ClipboardWindowHandler, dispPtr, XA_STRING); return TCL_OK; } @@ -703,12 +706,11 @@ ClipboardGetProc( * selection. */ Tcl_Interp *interp, /* Interpreter used for error reporting (not * used). */ - char *portion) /* New information to be appended. */ + const char *portion) /* New information to be appended. */ { Tcl_DStringAppend((Tcl_DString *) clientData, portion, -1); return TCL_OK; } - /* * Local Variables: diff --git a/generic/tkCmds.c b/generic/tkCmds.c index 2010b6e..a64d2e1 100644 --- a/generic/tkCmds.c +++ b/generic/tkCmds.c @@ -14,7 +14,7 @@ #include "tkInt.h" -#if defined(WIN32) +#if defined(_WIN32) #include "tkWinInt.h" #elif defined(MAC_OSX_TK) #include "tkMacOSXInt.h" @@ -34,6 +34,42 @@ static void WaitVisibilityProc(ClientData clientData, XEvent *eventPtr); static void WaitWindowProc(ClientData clientData, XEvent *eventPtr); +static int AppnameCmd(ClientData dummy, Tcl_Interp *interp, + int objc, Tcl_Obj *const *objv); +static int CaretCmd(ClientData dummy, Tcl_Interp *interp, + int objc, Tcl_Obj *const *objv); +static int InactiveCmd(ClientData dummy, Tcl_Interp *interp, + int objc, Tcl_Obj *const *objv); +static int ScalingCmd(ClientData dummy, Tcl_Interp *interp, + int objc, Tcl_Obj *const *objv); +static int UseinputmethodsCmd(ClientData dummy, + Tcl_Interp *interp, int objc, + Tcl_Obj *const *objv); +static int WindowingsystemCmd(ClientData dummy, + Tcl_Interp *interp, int objc, + Tcl_Obj *const *objv); + +#if defined(_WIN32) || defined(MAC_OSX_TK) +MODULE_SCOPE const TkEnsemble tkFontchooserEnsemble[]; +#else +#define tkFontchooserEnsemble NULL +#endif + +/* + * Table of tk subcommand names and implementations. + */ + +static const TkEnsemble tkCmdMap[] = { + {"appname", AppnameCmd, NULL }, + {"busy", Tk_BusyObjCmd, NULL }, + {"caret", CaretCmd, NULL }, + {"inactive", InactiveCmd, NULL }, + {"scaling", ScalingCmd, NULL }, + {"useinputmethods", UseinputmethodsCmd, NULL }, + {"windowingsystem", WindowingsystemCmd, NULL }, + {"fontchooser", NULL, tkFontchooserEnsemble}, + {NULL, NULL, NULL} +}; /* *---------------------------------------------------------------------- @@ -59,12 +95,13 @@ Tk_BellObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - static const char *bellOptions[] = { + static const char *const bellOptions[] = { "-displayof", "-nice", NULL }; enum options { TK_BELL_DISPLAYOF, TK_BELL_NICE }; - Tk_Window tkwin = (Tk_Window) clientData; + Tk_Window tkwin = clientData; int i, index, nice = 0; + Tk_ErrorHandler handler; if (objc > 4) { wrongArgs: @@ -73,8 +110,8 @@ Tk_BellObjCmd( } for (i = 1; i < objc; i++) { - if (Tcl_GetIndexFromObj(interp, objv[i], bellOptions, "option", 0, - &index) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[i], bellOptions, + sizeof(char *), "option", 0, &index) != TCL_OK) { return TCL_ERROR; } switch ((enum options) index) { @@ -92,11 +129,13 @@ Tk_BellObjCmd( break; } } + handler = Tk_CreateErrorHandler(Tk_Display(tkwin), -1, -1, -1, NULL, NULL); XBell(Tk_Display(tkwin), 0); if (!nice) { XForceScreenSaver(Tk_Display(tkwin), ScreenSaverReset); } XFlush(Tk_Display(tkwin)); + Tk_DeleteErrorHandler(handler); return TCL_OK; } @@ -124,10 +163,10 @@ Tk_BindObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - Tk_Window tkwin = (Tk_Window) clientData; + Tk_Window tkwin = clientData; TkWindow *winPtr; ClientData object; - char *string; + const char *string; if ((objc < 2) || (objc > 4)) { Tcl_WrongNumArgs(interp, 1, objv, "window ?pattern? ?command?"); @@ -148,7 +187,7 @@ Tk_BindObjCmd( } object = (ClientData) winPtr->pathName; } else { - winPtr = (TkWindow *) clientData; + winPtr = clientData; object = (ClientData) Tk_GetUid(string); } @@ -162,9 +201,8 @@ Tk_BindObjCmd( if (objc == 4) { int append = 0; unsigned long mask; - char *sequence, *script; - sequence = Tcl_GetString(objv[2]); - script = Tcl_GetString(objv[3]); + const char *sequence = Tcl_GetString(objv[2]); + const char *script = Tcl_GetString(objv[3]); /* * If the script is null, just delete the binding. @@ -198,7 +236,7 @@ Tk_BindObjCmd( Tcl_ResetResult(interp); return TCL_OK; } - Tcl_SetResult(interp, (char *) command, TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj(command, -1)); } else { Tk_GetAllBindings(interp, winPtr->mainPtr->bindingTable, object); } @@ -247,8 +285,7 @@ TkBindEventProc( */ if (winPtr->numTags > MAX_OBJS) { - objPtr = (ClientData *) ckalloc((unsigned) - (winPtr->numTags * sizeof(ClientData))); + objPtr = ckalloc(winPtr->numTags * sizeof(ClientData)); } for (i = 0; i < winPtr->numTags; i++) { p = winPtr->tagPtr[i]; @@ -282,7 +319,7 @@ TkBindEventProc( Tk_BindEvent(winPtr->mainPtr->bindingTable, eventPtr, (Tk_Window) winPtr, count, objPtr); if (objPtr != objects) { - ckfree((char *) objPtr); + ckfree(objPtr); } } @@ -310,10 +347,10 @@ Tk_BindtagsObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - Tk_Window tkwin = (Tk_Window) clientData; + Tk_Window tkwin = clientData; TkWindow *winPtr, *winPtr2; int i, length; - char *p; + const char *p; Tcl_Obj *listPtr, **tags; if ((objc < 2) || (objc > 3)) { @@ -328,24 +365,24 @@ Tk_BindtagsObjCmd( if (objc == 2) { listPtr = Tcl_NewObj(); if (winPtr->numTags == 0) { - Tcl_ListObjAppendElement(interp, listPtr, + Tcl_ListObjAppendElement(NULL, listPtr, Tcl_NewStringObj(winPtr->pathName, -1)); - Tcl_ListObjAppendElement(interp, listPtr, + Tcl_ListObjAppendElement(NULL, listPtr, Tcl_NewStringObj(winPtr->classUid, -1)); winPtr2 = winPtr; while ((winPtr2 != NULL) && !(Tk_TopWinHierarchy(winPtr2))) { winPtr2 = winPtr2->parentPtr; } if ((winPtr != winPtr2) && (winPtr2 != NULL)) { - Tcl_ListObjAppendElement(interp, listPtr, + Tcl_ListObjAppendElement(NULL, listPtr, Tcl_NewStringObj(winPtr2->pathName, -1)); } - Tcl_ListObjAppendElement(interp, listPtr, + Tcl_ListObjAppendElement(NULL, listPtr, Tcl_NewStringObj("all", -1)); } else { for (i = 0; i < winPtr->numTags; i++) { - Tcl_ListObjAppendElement(interp, listPtr, - Tcl_NewStringObj((char *)winPtr->tagPtr[i], -1)); + Tcl_ListObjAppendElement(NULL, listPtr, + Tcl_NewStringObj((char *) winPtr->tagPtr[i], -1)); } } Tcl_SetObjResult(interp, listPtr); @@ -362,8 +399,7 @@ Tk_BindtagsObjCmd( } winPtr->numTags = length; - winPtr->tagPtr = (ClientData *) ckalloc((unsigned) - (length * sizeof(ClientData))); + winPtr->tagPtr = ckalloc(length * sizeof(ClientData)); for (i = 0; i < length; i++) { p = Tcl_GetString(tags[i]); if (p[0] == '.') { @@ -376,7 +412,7 @@ Tk_BindtagsObjCmd( * is one. */ - copy = (char *) ckalloc((unsigned) (strlen(p) + 1)); + copy = ckalloc(strlen(p) + 1); strcpy(copy, p); winPtr->tagPtr[i] = (ClientData) copy; } else { @@ -422,7 +458,7 @@ TkFreeBindingTags( ckfree((char *)p); } } - ckfree((char *) winPtr->tagPtr); + ckfree(winPtr->tagPtr); winPtr->numTags = 0; winPtr->tagPtr = NULL; } @@ -452,7 +488,7 @@ Tk_DestroyObjCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { Tk_Window window; - Tk_Window tkwin = (Tk_Window) clientData; + Tk_Window tkwin = clientData; int i; for (i = 1; i < objc; i++) { @@ -499,7 +535,7 @@ Tk_LowerObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - Tk_Window mainwin = (Tk_Window) clientData; + Tk_Window mainwin = clientData; Tk_Window tkwin, other; if ((objc != 2) && (objc != 3)) { @@ -520,9 +556,15 @@ Tk_LowerObjCmd( } } if (Tk_RestackWindow(tkwin, Below, other) != TCL_OK) { - Tcl_AppendResult(interp, "can't lower \"", Tcl_GetString(objv[1]), - "\" below \"", (other ? Tcl_GetString(objv[2]) : ""), - "\"", NULL); + if (other) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't lower \"%s\" below \"%s\"", + Tcl_GetString(objv[1]), Tcl_GetString(objv[2]))); + } else { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't lower \"%s\" to bottom", Tcl_GetString(objv[1]))); + } + Tcl_SetErrorCode(interp, "TK", "RESTACK", "LOWER", NULL); return TCL_ERROR; } return TCL_OK; @@ -553,7 +595,7 @@ Tk_RaiseObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - Tk_Window mainwin = (Tk_Window) clientData; + Tk_Window mainwin = clientData; Tk_Window tkwin, other; if ((objc != 2) && (objc != 3)) { @@ -574,21 +616,56 @@ Tk_RaiseObjCmd( } } if (Tk_RestackWindow(tkwin, Above, other) != TCL_OK) { - Tcl_AppendResult(interp, "can't raise \"", Tcl_GetString(objv[1]), - "\" above \"", (other ? Tcl_GetString(objv[2]) : ""), - "\"", NULL); + if (other) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't raise \"%s\" above \"%s\"", + Tcl_GetString(objv[1]), Tcl_GetString(objv[2]))); + } else { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't raise \"%s\" to top", Tcl_GetString(objv[1]))); + } + Tcl_SetErrorCode(interp, "TK", "RESTACK", "RAISE", NULL); return TCL_ERROR; } return TCL_OK; } /* + * ---------------------------------------------------------------------- + * + * TkInitTkCmd -- + * + * Set up the tk ensemble. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * None. + * + * ---------------------------------------------------------------------- + */ + +int +TkInitTkCmd( + Tcl_Interp *interp, + ClientData clientData) +{ + TkMakeEnsemble(interp, "::", "tk", clientData, tkCmdMap); +#if defined(_WIN32) || defined(MAC_OSX_TK) + TkInitFontchooser(interp, clientData); +#endif + return TCL_OK; +} + +/* *---------------------------------------------------------------------- * - * Tk_TkObjCmd -- + * AppnameCmd, CaretCmd, ScalingCmd, UseinputmethodsCmd, + * WindowingsystemCmd, InactiveCmd -- * - * This function is invoked to process the "tk" Tcl command. See the user - * documentation for details on what it does. + * These functions are invoked to process the "tk" ensemble subcommands. + * See the user documentation for details on what they do. * * Results: * A standard Tcl result. @@ -600,286 +677,299 @@ Tk_RaiseObjCmd( */ int -Tk_TkObjCmd( +AppnameCmd( ClientData clientData, /* Main window associated with interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { + Tk_Window tkwin = clientData; + TkWindow *winPtr; + const char *string; + + if (Tcl_IsSafe(interp)) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "appname not accessible in a safe interpreter", -1)); + Tcl_SetErrorCode(interp, "TK", "SAFE", "APPLICATION", NULL); + return TCL_ERROR; + } + + winPtr = (TkWindow *) tkwin; + + if (objc > 2) { + Tcl_WrongNumArgs(interp, 1, objv, "?newName?"); + return TCL_ERROR; + } + if (objc == 2) { + string = Tcl_GetString(objv[1]); + winPtr->nameUid = Tk_GetUid(Tk_SetAppName(tkwin, string)); + } + Tcl_SetObjResult(interp, Tcl_NewStringObj(winPtr->nameUid, -1)); + return TCL_OK; +} + +int +CaretCmd( + ClientData clientData, /* Main window associated with interpreter. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ +{ + Tk_Window tkwin = clientData; int index; - Tk_Window tkwin; - static const char *optionStrings[] = { - "appname", "caret", "scaling", "useinputmethods", - "windowingsystem", "inactive", NULL + Tcl_Obj *objPtr; + TkCaret *caretPtr; + Tk_Window window; + static const char *const caretStrings[] = { + "-x", "-y", "-height", NULL }; - enum options { - TK_APPNAME, TK_CARET, TK_SCALING, TK_USE_IM, - TK_WINDOWINGSYSTEM, TK_INACTIVE + enum caretOptions { + TK_CARET_X, TK_CARET_Y, TK_CARET_HEIGHT }; - tkwin = (Tk_Window) clientData; - - if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "option ?arg?"); + if ((objc < 2) || ((objc > 3) && !!(objc & 1))) { + Tcl_WrongNumArgs(interp, 1, objv, + "window ?-x x? ?-y y? ?-height height?"); return TCL_ERROR; } - if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0, - &index) != TCL_OK) { + window = Tk_NameToWindow(interp, Tcl_GetString(objv[1]), tkwin); + if (window == NULL) { return TCL_ERROR; } + caretPtr = &(((TkWindow *) window)->dispPtr->caret); + if (objc == 2) { + /* + * Return all the current values + */ - switch ((enum options) index) { - case TK_APPNAME: { - TkWindow *winPtr; - char *string; - - if (Tcl_IsSafe(interp)) { - Tcl_SetResult(interp, - "appname not accessible in a safe interpreter", - TCL_STATIC); - return TCL_ERROR; - } + objPtr = Tcl_NewObj(); + Tcl_ListObjAppendElement(interp, objPtr, + Tcl_NewStringObj("-height", 7)); + Tcl_ListObjAppendElement(interp, objPtr, + Tcl_NewIntObj(caretPtr->height)); + Tcl_ListObjAppendElement(interp, objPtr, + Tcl_NewStringObj("-x", 2)); + Tcl_ListObjAppendElement(interp, objPtr, + Tcl_NewIntObj(caretPtr->x)); + Tcl_ListObjAppendElement(interp, objPtr, + Tcl_NewStringObj("-y", 2)); + Tcl_ListObjAppendElement(interp, objPtr, + Tcl_NewIntObj(caretPtr->y)); + Tcl_SetObjResult(interp, objPtr); + } else if (objc == 3) { + int value; - winPtr = (TkWindow *) tkwin; + /* + * Return the current value of the selected option + */ - if (objc > 3) { - Tcl_WrongNumArgs(interp, 2, objv, "?newName?"); + if (Tcl_GetIndexFromObj(interp, objv[2], caretStrings, + "caret option", 0, &index) != TCL_OK) { return TCL_ERROR; } - if (objc == 3) { - string = Tcl_GetString(objv[2]); - winPtr->nameUid = Tk_GetUid(Tk_SetAppName(tkwin, string)); + if (index == TK_CARET_X) { + value = caretPtr->x; + } else if (index == TK_CARET_Y) { + value = caretPtr->y; + } else /* if (index == TK_CARET_HEIGHT) -- last case */ { + value = caretPtr->height; } - Tcl_AppendResult(interp, winPtr->nameUid, NULL); - break; - } - case TK_CARET: { - Tcl_Obj *objPtr; - TkCaret *caretPtr; - Tk_Window window; - static const char *caretStrings[] = { - "-x", "-y", "-height", NULL - }; - enum caretOptions { - TK_CARET_X, TK_CARET_Y, TK_CARET_HEIGHT - }; - - if ((objc < 3) || ((objc > 4) && !(objc & 1))) { - Tcl_WrongNumArgs(interp, 2, objv, - "window ?-x x? ?-y y? ?-height height?"); - return TCL_ERROR; - } - window = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin); - if (window == NULL) { - return TCL_ERROR; - } - caretPtr = &(((TkWindow *) window)->dispPtr->caret); - if (objc == 3) { - /* - * Return all the current values - */ - - objPtr = Tcl_NewObj(); - Tcl_ListObjAppendElement(interp, objPtr, - Tcl_NewStringObj("-height", 7)); - Tcl_ListObjAppendElement(interp, objPtr, - Tcl_NewIntObj(caretPtr->height)); - Tcl_ListObjAppendElement(interp, objPtr, - Tcl_NewStringObj("-x", 2)); - Tcl_ListObjAppendElement(interp, objPtr, - Tcl_NewIntObj(caretPtr->x)); - Tcl_ListObjAppendElement(interp, objPtr, - Tcl_NewStringObj("-y", 2)); - Tcl_ListObjAppendElement(interp, objPtr, - Tcl_NewIntObj(caretPtr->y)); - Tcl_SetObjResult(interp, objPtr); - } else if (objc == 4) { - int value; - - /* - * Return the current value of the selected option - */ + Tcl_SetObjResult(interp, Tcl_NewIntObj(value)); + } else { + int i, value, x = 0, y = 0, height = -1; - if (Tcl_GetIndexFromObj(interp, objv[3], caretStrings, - "caret option", 0, &index) != TCL_OK) { + for (i = 2; i < objc; i += 2) { + if ((Tcl_GetIndexFromObj(interp, objv[i], caretStrings, + "caret option", 0, &index) != TCL_OK) || + Tcl_GetIntFromObj(interp,objv[i+1],&value) != TCL_OK) { return TCL_ERROR; } if (index == TK_CARET_X) { - value = caretPtr->x; + x = value; } else if (index == TK_CARET_Y) { - value = caretPtr->y; + y = value; } else /* if (index == TK_CARET_HEIGHT) -- last case */ { - value = caretPtr->height; - } - Tcl_SetIntObj(Tcl_GetObjResult(interp), value); - } else { - int i, value, x = 0, y = 0, height = -1; - - for (i = 3; i < objc; i += 2) { - if ((Tcl_GetIndexFromObj(interp, objv[i], caretStrings, - "caret option", 0, &index) != TCL_OK) || - Tcl_GetIntFromObj(interp,objv[i+1],&value) != TCL_OK) { - return TCL_ERROR; - } - if (index == TK_CARET_X) { - x = value; - } else if (index == TK_CARET_Y) { - y = value; - } else /* if (index == TK_CARET_HEIGHT) -- last case */ { - height = value; - } - } - if (height < 0) { - height = Tk_Height(window); + height = value; } - Tk_SetCaretPos(window, x, y, height); } - break; + if (height < 0) { + height = Tk_Height(window); + } + Tk_SetCaretPos(window, x, y, height); + } + return TCL_OK; +} + +int +ScalingCmd( + ClientData clientData, /* Main window associated with interpreter. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ +{ + Tk_Window tkwin = clientData; + Screen *screenPtr; + int skip, width, height; + double d; + + if (Tcl_IsSafe(interp)) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "scaling not accessible in a safe interpreter", -1)); + Tcl_SetErrorCode(interp, "TK", "SAFE", "SCALING", NULL); + return TCL_ERROR; } - case TK_SCALING: { - Screen *screenPtr; - int skip, width, height; - double d; - if (Tcl_IsSafe(interp)) { - Tcl_SetResult(interp, - "scaling not accessible in a safe interpreter", - TCL_STATIC); + skip = TkGetDisplayOf(interp, objc - 1, objv + 1, &tkwin); + if (skip < 0) { + return TCL_ERROR; + } + screenPtr = Tk_Screen(tkwin); + if (objc - skip == 1) { + d = 25.4 / 72; + d *= WidthOfScreen(screenPtr); + d /= WidthMMOfScreen(screenPtr); + Tcl_SetObjResult(interp, Tcl_NewDoubleObj(d)); + } else if (objc - skip == 2) { + if (Tcl_GetDoubleFromObj(interp, objv[1+skip], &d) != TCL_OK) { return TCL_ERROR; } - - skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin); - if (skip < 0) { - return TCL_ERROR; + d = (25.4 / 72) / d; + width = (int) (d * WidthOfScreen(screenPtr) + 0.5); + if (width <= 0) { + width = 1; } - screenPtr = Tk_Screen(tkwin); - if (objc - skip == 2) { - d = 25.4 / 72; - d *= WidthOfScreen(screenPtr); - d /= WidthMMOfScreen(screenPtr); - Tcl_SetDoubleObj(Tcl_GetObjResult(interp), d); - } else if (objc - skip == 3) { - if (Tcl_GetDoubleFromObj(interp, objv[2+skip], &d) != TCL_OK) { - return TCL_ERROR; - } - d = (25.4 / 72) / d; - width = (int) (d * WidthOfScreen(screenPtr) + 0.5); - if (width <= 0) { - width = 1; - } - height = (int) (d * HeightOfScreen(screenPtr) + 0.5); - if (height <= 0) { - height = 1; - } - WidthMMOfScreen(screenPtr) = width; - HeightMMOfScreen(screenPtr) = height; - } else { - Tcl_WrongNumArgs(interp, 2, objv, - "?-displayof window? ?factor?"); - return TCL_ERROR; + height = (int) (d * HeightOfScreen(screenPtr) + 0.5); + if (height <= 0) { + height = 1; } - break; + WidthMMOfScreen(screenPtr) = width; + HeightMMOfScreen(screenPtr) = height; + } else { + Tcl_WrongNumArgs(interp, 1, objv, "?-displayof window? ?factor?"); + return TCL_ERROR; } - case TK_USE_IM: { - TkDisplay *dispPtr; - int skip; + return TCL_OK; +} - if (Tcl_IsSafe(interp)) { - Tcl_SetResult(interp, - "useinputmethods not accessible in a safe interpreter", - TCL_STATIC); - return TCL_ERROR; - } +int +UseinputmethodsCmd( + ClientData clientData, /* Main window associated with interpreter. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ +{ + Tk_Window tkwin = clientData; + TkDisplay *dispPtr; + int skip; - skip = TkGetDisplayOf(interp, objc-2, objv+2, &tkwin); - if (skip < 0) { - return TCL_ERROR; - } - dispPtr = ((TkWindow *) tkwin)->dispPtr; - if ((objc - skip) == 3) { - /* - * In the case where TK_USE_INPUT_METHODS is not defined, this - * will be ignored and we will always return 0. That will indicate - * to the user that input methods are just not available. - */ + if (Tcl_IsSafe(interp)) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "useinputmethods not accessible in a safe interpreter", -1)); + Tcl_SetErrorCode(interp, "TK", "SAFE", "INPUT_METHODS", NULL); + return TCL_ERROR; + } - int boolVal; + skip = TkGetDisplayOf(interp, objc-1, objv+1, &tkwin); + if (skip < 0) { + return TCL_ERROR; + } + dispPtr = ((TkWindow *) tkwin)->dispPtr; + if ((objc - skip) == 2) { + /* + * In the case where TK_USE_INPUT_METHODS is not defined, this + * will be ignored and we will always return 0. That will indicate + * to the user that input methods are just not available. + */ - if (Tcl_GetBooleanFromObj(interp, objv[2+skip], - &boolVal) != TCL_OK) { - return TCL_ERROR; - } -#ifdef TK_USE_INPUT_METHODS - if (boolVal) { - dispPtr->flags |= TK_DISPLAY_USE_IM; - } else { - dispPtr->flags &= ~TK_DISPLAY_USE_IM; - } -#endif /* TK_USE_INPUT_METHODS */ - } else if ((objc - skip) != 2) { - Tcl_WrongNumArgs(interp, 2, objv, - "?-displayof window? ?boolean?"); + int boolVal; + + if (Tcl_GetBooleanFromObj(interp, objv[1+skip], + &boolVal) != TCL_OK) { return TCL_ERROR; } - Tcl_SetBooleanObj(Tcl_GetObjResult(interp), - (int) (dispPtr->flags & TK_DISPLAY_USE_IM)); - break; +#ifdef TK_USE_INPUT_METHODS + if (boolVal) { + dispPtr->flags |= TK_DISPLAY_USE_IM; + } else { + dispPtr->flags &= ~TK_DISPLAY_USE_IM; + } +#endif /* TK_USE_INPUT_METHODS */ + } else if ((objc - skip) != 1) { + Tcl_WrongNumArgs(interp, 1, objv, + "?-displayof window? ?boolean?"); + return TCL_ERROR; } - case TK_WINDOWINGSYSTEM: { - const char *windowingsystem; + Tcl_SetObjResult(interp, + Tcl_NewBooleanObj(dispPtr->flags & TK_DISPLAY_USE_IM)); + return TCL_OK; +} - if (objc != 2) { - Tcl_WrongNumArgs(interp, 2, objv, NULL); - return TCL_ERROR; - } -#if defined(WIN32) - windowingsystem = "win32"; +int +WindowingsystemCmd( + ClientData clientData, /* Main window associated with interpreter. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ +{ + const char *windowingsystem; + + if (objc != 1) { + Tcl_WrongNumArgs(interp, 1, objv, NULL); + return TCL_ERROR; + } +#if defined(_WIN32) + windowingsystem = "win32"; #elif defined(MAC_OSX_TK) - windowingsystem = "aqua"; + windowingsystem = "aqua"; #else - windowingsystem = "x11"; + windowingsystem = "x11"; #endif - Tcl_SetStringObj(Tcl_GetObjResult(interp), windowingsystem, -1); - break; - } - case TK_INACTIVE: { - int skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin); + Tcl_SetObjResult(interp, Tcl_NewStringObj(windowingsystem, -1)); + return TCL_OK; +} - if (skip < 0) { +int +InactiveCmd( + ClientData clientData, /* Main window associated with interpreter. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ +{ + Tk_Window tkwin = clientData; + int skip = TkGetDisplayOf(interp, objc - 1, objv + 1, &tkwin); + + if (skip < 0) { + return TCL_ERROR; + } + if (objc - skip == 1) { + long inactive; + + inactive = (Tcl_IsSafe(interp) ? -1 : + Tk_GetUserInactiveTime(Tk_Display(tkwin))); + Tcl_SetObjResult(interp, Tcl_NewLongObj(inactive)); + } else if (objc - skip == 2) { + const char *string; + + string = Tcl_GetString(objv[objc-1]); + if (strcmp(string, "reset") != 0) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad option \"%s\": must be reset", string)); + Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "option", + string, NULL); return TCL_ERROR; } - if (objc - skip == 2) { - long inactive; - - inactive = (Tcl_IsSafe(interp) ? -1 : - Tk_GetUserInactiveTime(Tk_Display(tkwin))); - Tcl_SetObjResult(interp, Tcl_NewLongObj(inactive)); - - } else if (objc - skip == 3) { - char *string; - - string = Tcl_GetString(objv[objc-1]); - if (strcmp(string, "reset") != 0) { - Tcl_Obj *msg = Tcl_NewStringObj("bad option \"", -1); - - Tcl_AppendStringsToObj(msg, string, "\": must be reset", NULL); - Tcl_SetObjResult(interp, msg); - return TCL_ERROR; - } - if (Tcl_IsSafe(interp)) { - Tcl_SetResult(interp, - "resetting the user inactivity timer " - "is not allowed in a safe interpreter", TCL_STATIC); - return TCL_ERROR; - } - Tk_ResetUserInactiveTime(Tk_Display(tkwin)); - Tcl_ResetResult(interp); - } else { - Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window? ?reset?"); + if (Tcl_IsSafe(interp)) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "resetting the user inactivity timer " + "is not allowed in a safe interpreter", -1)); + Tcl_SetErrorCode(interp, "TK", "SAFE", "INACTIVITY_TIMER", NULL); return TCL_ERROR; } - break; - } + Tk_ResetUserInactiveTime(Tk_Display(tkwin)); + Tcl_ResetResult(interp); + } else { + Tcl_WrongNumArgs(interp, 1, objv, "?-displayof window? ?reset?"); + return TCL_ERROR; } return TCL_OK; } @@ -909,9 +999,10 @@ Tk_TkwaitObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - Tk_Window tkwin = (Tk_Window) clientData; + Tk_Window tkwin = clientData; int done, index; - static const char *optionStrings[] = { + int code = TCL_OK; + static const char *const optionStrings[] = { "variable", "visibility", "window", NULL }; enum options { @@ -930,18 +1021,22 @@ Tk_TkwaitObjCmd( switch ((enum options) index) { case TKWAIT_VARIABLE: - if (Tcl_TraceVar(interp, Tcl_GetString(objv[2]), - TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - WaitVariableProc, (ClientData) &done) != TCL_OK) { + if (Tcl_TraceVar2(interp, Tcl_GetString(objv[2]), + NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + WaitVariableProc, &done) != TCL_OK) { return TCL_ERROR; } done = 0; while (!done) { + if (Tcl_Canceled(interp, TCL_LEAVE_ERR_MSG) == TCL_ERROR) { + code = TCL_ERROR; + break; + } Tcl_DoOneEvent(0); } - Tcl_UntraceVar(interp, Tcl_GetString(objv[2]), - TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - WaitVariableProc, (ClientData) &done); + Tcl_UntraceVar2(interp, Tcl_GetString(objv[2]), + NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + WaitVariableProc, &done); break; case TKWAIT_VISIBILITY: { @@ -953,25 +1048,31 @@ Tk_TkwaitObjCmd( } Tk_CreateEventHandler(window, VisibilityChangeMask|StructureNotifyMask, - WaitVisibilityProc, (ClientData) &done); + WaitVisibilityProc, &done); done = 0; while (!done) { + if (Tcl_Canceled(interp, TCL_LEAVE_ERR_MSG) == TCL_ERROR) { + code = TCL_ERROR; + break; + } Tcl_DoOneEvent(0); } - if (done != 1) { + if ((done != 0) && (done != 1)) { /* * Note that we do not delete the event handler because it was * deleted automatically when the window was destroyed. */ Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "window \"", Tcl_GetString(objv[2]), - "\" was deleted before its visibility changed", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "window \"%s\" was deleted before its visibility changed", + Tcl_GetString(objv[2]))); + Tcl_SetErrorCode(interp, "TK", "WAIT", "PREMATURE", NULL); return TCL_ERROR; } Tk_DeleteEventHandler(window, VisibilityChangeMask|StructureNotifyMask, - WaitVisibilityProc, (ClientData) &done); + WaitVisibilityProc, &done); break; } @@ -983,28 +1084,40 @@ Tk_TkwaitObjCmd( return TCL_ERROR; } Tk_CreateEventHandler(window, StructureNotifyMask, - WaitWindowProc, (ClientData) &done); + WaitWindowProc, &done); done = 0; while (!done) { + if (Tcl_Canceled(interp, TCL_LEAVE_ERR_MSG) == TCL_ERROR) { + code = TCL_ERROR; + break; + } Tcl_DoOneEvent(0); } /* - * Note: there's no need to delete the event handler. It was deleted - * automatically when the window was destroyed. + * Note: normally there's no need to delete the event handler. It was + * deleted automatically when the window was destroyed; however, if + * the wait operation was canceled, we need to delete it. */ + if (done == 0) { + Tk_DeleteEventHandler(window, StructureNotifyMask, + WaitWindowProc, &done); + } break; } } /* * Clear out the interpreter's result, since it may have been set by event - * handlers. + * handlers. This is skipped if an error occurred above, such as the wait + * operation being canceled. */ + if (code == TCL_OK) Tcl_ResetResult(interp); - return TCL_OK; + + return code; } /* ARGSUSED */ @@ -1016,7 +1129,7 @@ WaitVariableProc( const char *name2, /* Second part of variable name. */ int flags) /* Information about what happened. */ { - int *donePtr = (int *) clientData; + int *donePtr = clientData; *donePtr = 1; return NULL; @@ -1028,12 +1141,11 @@ WaitVisibilityProc( ClientData clientData, /* Pointer to integer to set to 1. */ XEvent *eventPtr) /* Information about event (not used). */ { - int *donePtr = (int *) clientData; + int *donePtr = clientData; if (eventPtr->type == VisibilityNotify) { *donePtr = 1; - } - if (eventPtr->type == DestroyNotify) { + } else if (eventPtr->type == DestroyNotify) { *donePtr = 2; } } @@ -1043,7 +1155,7 @@ WaitWindowProc( ClientData clientData, /* Pointer to integer to set to 1. */ XEvent *eventPtr) /* Information about event. */ { - int *donePtr = (int *) clientData; + int *donePtr = clientData; if (eventPtr->type == DestroyNotify) { *donePtr = 1; @@ -1075,9 +1187,10 @@ Tk_UpdateObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - static const char *updateOptions[] = {"idletasks", NULL}; + static const char *const updateOptions[] = {"idletasks", NULL}; int flags, index; TkDisplay *dispPtr; + int code = TCL_OK; if (objc == 1) { flags = TCL_DONT_WAIT; @@ -1102,12 +1215,35 @@ Tk_UpdateObjCmd( while (1) { while (Tcl_DoOneEvent(flags) != 0) { - /* Empty loop body */ + if (Tcl_Canceled(interp, TCL_LEAVE_ERR_MSG) == TCL_ERROR) { + code = TCL_ERROR; + break; + } } + + /* + * If event processing was canceled proceed no further. + */ + + if (code == TCL_ERROR) + break; + for (dispPtr = TkGetDisplayList(); dispPtr != NULL; dispPtr = dispPtr->nextPtr) { XSync(dispPtr->display, False); } + + /* + * Check again if event processing has been canceled because the inner + * loop (above) may not have checked (i.e. no events were processed and + * the loop body was skipped). + */ + + if (Tcl_Canceled(interp, TCL_LEAVE_ERR_MSG) == TCL_ERROR) { + code = TCL_ERROR; + break; + } + if (Tcl_DoOneEvent(flags) == 0) { break; } @@ -1115,11 +1251,14 @@ Tk_UpdateObjCmd( /* * Must clear the interpreter's result because event handlers could have - * executed commands. + * executed commands. This is skipped if an error occurred above, such as + * the wait operation being canceled. */ + if (code == TCL_OK) Tcl_ResetResult(interp); - return TCL_OK; + + return code; } /* @@ -1147,10 +1286,9 @@ Tk_WinfoObjCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { int index, x, y, width, height, useX, useY, class, skip; - char *string; + const char *string; TkWindow *winPtr; - Tk_Window tkwin; - Tcl_Obj *resultPtr; + Tk_Window tkwin = clientData; static const TkStateMap visualMap[] = { {PseudoColor, "pseudocolor"}, @@ -1161,7 +1299,7 @@ Tk_WinfoObjCmd( {StaticGray, "staticgray"}, {-1, NULL} }; - static const char *optionStrings[] = { + static const char *const optionStrings[] = { "cells", "children", "class", "colormapfull", "depth", "geometry", "height", "id", "ismapped", "manager", "name", "parent", @@ -1200,8 +1338,6 @@ Tk_WinfoObjCmd( WIN_VISUALSAVAILABLE }; - tkwin = (Tk_Window) clientData; - if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "option ?arg?"); return TCL_ERROR; @@ -1223,14 +1359,14 @@ Tk_WinfoObjCmd( } } winPtr = (TkWindow *) tkwin; - resultPtr = Tcl_GetObjResult(interp); switch ((enum options) index) { case WIN_CELLS: - Tcl_SetIntObj(resultPtr, Tk_Visual(tkwin)->map_entries); + Tcl_SetObjResult(interp, + Tcl_NewIntObj(Tk_Visual(tkwin)->map_entries)); break; case WIN_CHILDREN: { - Tcl_Obj *strPtr; + Tcl_Obj *strPtr, *resultPtr = Tcl_NewObj(); winPtr = winPtr->childList; for ( ; winPtr != NULL; winPtr = winPtr->nextPtr) { @@ -1239,57 +1375,50 @@ Tk_WinfoObjCmd( Tcl_ListObjAppendElement(NULL, resultPtr, strPtr); } } + Tcl_SetObjResult(interp, resultPtr); break; } case WIN_CLASS: - Tcl_SetStringObj(resultPtr, Tk_Class(tkwin), -1); + Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_Class(tkwin), -1)); break; case WIN_COLORMAPFULL: - Tcl_SetBooleanObj(resultPtr, - TkpCmapStressed(tkwin, Tk_Colormap(tkwin))); + Tcl_SetObjResult(interp, + Tcl_NewBooleanObj(TkpCmapStressed(tkwin,Tk_Colormap(tkwin)))); break; case WIN_DEPTH: - Tcl_SetIntObj(resultPtr, Tk_Depth(tkwin)); + Tcl_SetObjResult(interp, Tcl_NewIntObj(Tk_Depth(tkwin))); break; - case WIN_GEOMETRY: { - char buf[16 + TCL_INTEGER_SPACE * 4]; - - sprintf(buf, "%dx%d+%d+%d", Tk_Width(tkwin), Tk_Height(tkwin), - Tk_X(tkwin), Tk_Y(tkwin)); - Tcl_SetStringObj(resultPtr, buf, -1); + case WIN_GEOMETRY: + Tcl_SetObjResult(interp, Tcl_ObjPrintf("%dx%d+%d+%d", + Tk_Width(tkwin), Tk_Height(tkwin), Tk_X(tkwin), Tk_Y(tkwin))); break; - } case WIN_HEIGHT: - Tcl_SetIntObj(resultPtr, Tk_Height(tkwin)); + Tcl_SetObjResult(interp, Tcl_NewIntObj(Tk_Height(tkwin))); break; case WIN_ID: { char buf[TCL_INTEGER_SPACE]; Tk_MakeWindowExist(tkwin); TkpPrintWindowId(buf, Tk_WindowId(tkwin)); - - /* - * interp result may have changed, refetch it - */ - - resultPtr = Tcl_GetObjResult(interp); - Tcl_SetStringObj(resultPtr, buf, -1); + Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1)); break; } case WIN_ISMAPPED: - Tcl_SetBooleanObj(resultPtr, (int) Tk_IsMapped(tkwin)); + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(Tk_IsMapped(tkwin))); break; case WIN_MANAGER: if (winPtr->geomMgrPtr != NULL) { - Tcl_SetStringObj(resultPtr, winPtr->geomMgrPtr->name, -1); + Tcl_SetObjResult(interp, + Tcl_NewStringObj(winPtr->geomMgrPtr->name, -1)); } break; case WIN_NAME: - Tcl_SetStringObj(resultPtr, Tk_Name(tkwin), -1); + Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_Name(tkwin), -1)); break; case WIN_PARENT: if (winPtr->parentPtr != NULL) { - Tcl_SetStringObj(resultPtr, winPtr->parentPtr->pathName, -1); + Tcl_SetObjResult(interp, + Tcl_NewStringObj(winPtr->parentPtr->pathName, -1)); } break; case WIN_POINTERX: @@ -1313,54 +1442,58 @@ Tk_WinfoObjCmd( TkGetPointerCoords((Tk_Window) winPtr, &x, &y); } if (useX & useY) { - char buf[TCL_INTEGER_SPACE * 2]; + Tcl_Obj *xyObj[2]; - sprintf(buf, "%d %d", x, y); - Tcl_SetStringObj(resultPtr, buf, -1); + xyObj[0] = Tcl_NewIntObj(x); + xyObj[1] = Tcl_NewIntObj(y); + Tcl_SetObjResult(interp, Tcl_NewListObj(2, xyObj)); } else if (useX) { - Tcl_SetIntObj(resultPtr, x); + Tcl_SetObjResult(interp, Tcl_NewIntObj(x)); } else { - Tcl_SetIntObj(resultPtr, y); + Tcl_SetObjResult(interp, Tcl_NewIntObj(y)); } break; case WIN_REQHEIGHT: - Tcl_SetIntObj(resultPtr, Tk_ReqHeight(tkwin)); + Tcl_SetObjResult(interp, Tcl_NewIntObj(Tk_ReqHeight(tkwin))); break; case WIN_REQWIDTH: - Tcl_SetIntObj(resultPtr, Tk_ReqWidth(tkwin)); + Tcl_SetObjResult(interp, Tcl_NewIntObj(Tk_ReqWidth(tkwin))); break; case WIN_ROOTX: Tk_GetRootCoords(tkwin, &x, &y); - Tcl_SetIntObj(resultPtr, x); + Tcl_SetObjResult(interp, Tcl_NewIntObj(x)); break; case WIN_ROOTY: Tk_GetRootCoords(tkwin, &x, &y); - Tcl_SetIntObj(resultPtr, y); + Tcl_SetObjResult(interp, Tcl_NewIntObj(y)); break; - case WIN_SCREEN: { - char buf[TCL_INTEGER_SPACE]; - - sprintf(buf, "%d", Tk_ScreenNumber(tkwin)); - Tcl_AppendStringsToObj(resultPtr, Tk_DisplayName(tkwin),".",buf, NULL); + case WIN_SCREEN: + Tcl_SetObjResult(interp, Tcl_ObjPrintf("%s.%d", + Tk_DisplayName(tkwin), Tk_ScreenNumber(tkwin))); break; - } case WIN_SCREENCELLS: - Tcl_SetIntObj(resultPtr, CellsOfScreen(Tk_Screen(tkwin))); + Tcl_SetObjResult(interp, + Tcl_NewIntObj(CellsOfScreen(Tk_Screen(tkwin)))); break; case WIN_SCREENDEPTH: - Tcl_SetIntObj(resultPtr, DefaultDepthOfScreen(Tk_Screen(tkwin))); + Tcl_SetObjResult(interp, + Tcl_NewIntObj(DefaultDepthOfScreen(Tk_Screen(tkwin)))); break; case WIN_SCREENHEIGHT: - Tcl_SetIntObj(resultPtr, HeightOfScreen(Tk_Screen(tkwin))); + Tcl_SetObjResult(interp, + Tcl_NewIntObj(HeightOfScreen(Tk_Screen(tkwin)))); break; case WIN_SCREENWIDTH: - Tcl_SetIntObj(resultPtr, WidthOfScreen(Tk_Screen(tkwin))); + Tcl_SetObjResult(interp, + Tcl_NewIntObj(WidthOfScreen(Tk_Screen(tkwin)))); break; case WIN_SCREENMMHEIGHT: - Tcl_SetIntObj(resultPtr, HeightMMOfScreen(Tk_Screen(tkwin))); + Tcl_SetObjResult(interp, + Tcl_NewIntObj(HeightMMOfScreen(Tk_Screen(tkwin)))); break; case WIN_SCREENMMWIDTH: - Tcl_SetIntObj(resultPtr, WidthMMOfScreen(Tk_Screen(tkwin))); + Tcl_SetObjResult(interp, + Tcl_NewIntObj(WidthMMOfScreen(Tk_Screen(tkwin)))); break; case WIN_SCREENVISUAL: class = DefaultVisualOfScreen(Tk_Screen(tkwin))->class; @@ -1371,7 +1504,7 @@ Tk_WinfoObjCmd( case WIN_TOPLEVEL: winPtr = GetTopHierarchy(tkwin); if (winPtr != NULL) { - Tcl_SetStringObj(resultPtr, winPtr->pathName, -1); + Tcl_SetObjResult(interp, Tcl_NewStringObj(winPtr->pathName, -1)); } break; case WIN_VIEWABLE: { @@ -1387,7 +1520,7 @@ Tk_WinfoObjCmd( } } - Tcl_SetBooleanObj(resultPtr, viewable); + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(viewable)); break; } case WIN_VISUAL: @@ -1398,40 +1531,36 @@ Tk_WinfoObjCmd( if (string == NULL) { string = "unknown"; } - Tcl_SetStringObj(resultPtr, string, -1); + Tcl_SetObjResult(interp, Tcl_NewStringObj(string, -1)); break; - case WIN_VISUALID: { - char buf[TCL_INTEGER_SPACE]; - - sprintf(buf, "0x%x", - (unsigned int) XVisualIDFromVisual(Tk_Visual(tkwin))); - Tcl_SetStringObj(resultPtr, buf, -1); + case WIN_VISUALID: + Tcl_SetObjResult(interp, Tcl_ObjPrintf("0x%x", (unsigned) + XVisualIDFromVisual(Tk_Visual(tkwin)))); break; - } case WIN_VROOTHEIGHT: Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height); - Tcl_SetIntObj(resultPtr, height); + Tcl_SetObjResult(interp, Tcl_NewIntObj(height)); break; case WIN_VROOTWIDTH: Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height); - Tcl_SetIntObj(resultPtr, width); + Tcl_SetObjResult(interp, Tcl_NewIntObj(width)); break; case WIN_VROOTX: Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height); - Tcl_SetIntObj(resultPtr, x); + Tcl_SetObjResult(interp, Tcl_NewIntObj(x)); break; case WIN_VROOTY: Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height); - Tcl_SetIntObj(resultPtr, y); + Tcl_SetObjResult(interp, Tcl_NewIntObj(y)); break; case WIN_WIDTH: - Tcl_SetIntObj(resultPtr, Tk_Width(tkwin)); + Tcl_SetObjResult(interp, Tcl_NewIntObj(Tk_Width(tkwin))); break; case WIN_X: - Tcl_SetIntObj(resultPtr, Tk_X(tkwin)); + Tcl_SetObjResult(interp, Tcl_NewIntObj(Tk_X(tkwin))); break; case WIN_Y: - Tcl_SetIntObj(resultPtr, Tk_Y(tkwin)); + Tcl_SetObjResult(interp, Tcl_NewIntObj(Tk_Y(tkwin))); break; /* @@ -1449,7 +1578,8 @@ Tk_WinfoObjCmd( } objv += skip; string = Tcl_GetString(objv[2]); - Tcl_SetLongObj(resultPtr, (long) Tk_InternAtom(tkwin, string)); + Tcl_SetObjResult(interp, + Tcl_NewLongObj((long) Tk_InternAtom(tkwin, string))); break; case WIN_ATOMNAME: { const char *name; @@ -1469,12 +1599,13 @@ Tk_WinfoObjCmd( } name = Tk_GetAtomName(tkwin, (Atom) id); if (strcmp(name, "?bad atom?") == 0) { - string = Tcl_GetString(objv[2]); - Tcl_AppendStringsToObj(resultPtr, - "no atom exists with id \"", string, "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "no atom exists with id \"%s\"", Tcl_GetString(objv[2]))); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "ATOM", + Tcl_GetString(objv[2]), NULL); return TCL_ERROR; } - Tcl_SetStringObj(resultPtr, name, -1); + Tcl_SetObjResult(interp, Tcl_NewStringObj(name, -1)); break; } case WIN_CONTAINING: @@ -1498,7 +1629,7 @@ Tk_WinfoObjCmd( } tkwin = Tk_CoordsToWindow(x, y, tkwin); if (tkwin != NULL) { - Tcl_SetStringObj(resultPtr, Tk_PathName(tkwin), -1); + Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(tkwin),-1)); } break; case WIN_INTERPS: @@ -1526,11 +1657,13 @@ Tk_WinfoObjCmd( if (TkpScanWindowId(interp, string, &id) != TCL_OK) { return TCL_ERROR; } - winPtr = (TkWindow *)Tk_IdToWindow(Tk_Display(tkwin), id); + winPtr = (TkWindow *) Tk_IdToWindow(Tk_Display(tkwin), id); if ((winPtr == NULL) || (winPtr->mainPtr != ((TkWindow *) tkwin)->mainPtr)) { - Tcl_AppendStringsToObj(resultPtr, "window id \"", string, - "\" doesn't exist in this application", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "window id \"%s\" doesn't exist in this application", + string)); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "WINDOW", string, NULL); return TCL_ERROR; } @@ -1542,7 +1675,7 @@ Tk_WinfoObjCmd( tkwin = (Tk_Window) winPtr; if (Tk_PathName(tkwin) != NULL) { - Tcl_SetStringObj(resultPtr, Tk_PathName(tkwin), -1); + Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(tkwin),-1)); } break; } @@ -1561,13 +1694,12 @@ Tk_WinfoObjCmd( string = Tcl_GetString(objv[2]); winPtr = (TkWindow *) Tk_NameToWindow(interp, string, tkwin); Tcl_ResetResult(interp); - resultPtr = Tcl_GetObjResult(interp); alive = 1; if ((winPtr == NULL) || (winPtr->flags & TK_ALREADY_DEAD)) { alive = 0; } - Tcl_SetBooleanObj(resultPtr, alive); + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(alive)); break; } case WIN_FPIXELS: { @@ -1577,9 +1709,7 @@ Tk_WinfoObjCmd( Tcl_WrongNumArgs(interp, 2, objv, "window number"); return TCL_ERROR; } - string = Tcl_GetString(objv[2]); - tkwin = Tk_NameToWindow(interp, string, tkwin); - if (tkwin == NULL) { + if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin) != TCL_OK) { return TCL_ERROR; } string = Tcl_GetString(objv[3]); @@ -1588,7 +1718,7 @@ Tk_WinfoObjCmd( } pixels = mm * WidthOfScreen(Tk_Screen(tkwin)) / WidthMMOfScreen(Tk_Screen(tkwin)); - Tcl_SetDoubleObj(resultPtr, pixels); + Tcl_SetObjResult(interp, Tcl_NewDoubleObj(pixels)); break; } case WIN_PIXELS: { @@ -1598,47 +1728,40 @@ Tk_WinfoObjCmd( Tcl_WrongNumArgs(interp, 2, objv, "window number"); return TCL_ERROR; } - string = Tcl_GetString(objv[2]); - tkwin = Tk_NameToWindow(interp, string, tkwin); - if (tkwin == NULL) { + if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin) != TCL_OK) { return TCL_ERROR; } string = Tcl_GetString(objv[3]); if (Tk_GetPixels(interp, tkwin, string, &pixels) != TCL_OK) { return TCL_ERROR; } - Tcl_SetIntObj(resultPtr, pixels); + Tcl_SetObjResult(interp, Tcl_NewIntObj(pixels)); break; } case WIN_RGB: { XColor *colorPtr; - char buf[TCL_INTEGER_SPACE * 3]; if (objc != 4) { Tcl_WrongNumArgs(interp, 2, objv, "window colorName"); return TCL_ERROR; } - string = Tcl_GetString(objv[2]); - tkwin = Tk_NameToWindow(interp, string, tkwin); - if (tkwin == NULL) { + if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin) != TCL_OK) { return TCL_ERROR; } - string = Tcl_GetString(objv[3]); - colorPtr = Tk_GetColor(interp, tkwin, string); + colorPtr = Tk_GetColor(interp, tkwin, Tcl_GetString(objv[3])); if (colorPtr == NULL) { return TCL_ERROR; } - sprintf(buf, "%d %d %d", colorPtr->red, colorPtr->green, - colorPtr->blue); + Tcl_SetObjResult(interp, Tcl_ObjPrintf("%d %d %d", + colorPtr->red, colorPtr->green, colorPtr->blue)); Tk_FreeColor(colorPtr); - Tcl_SetStringObj(resultPtr, buf, -1); break; } case WIN_VISUALSAVAILABLE: { XVisualInfo template, *visInfoPtr; int count, i; int includeVisualId; - Tcl_Obj *strPtr; + Tcl_Obj *strPtr, *resultPtr; char buf[16 + TCL_INTEGER_SPACE]; char visualIdString[TCL_INTEGER_SPACE]; @@ -1652,9 +1775,7 @@ Tk_WinfoObjCmd( return TCL_ERROR; } - string = Tcl_GetString(objv[2]); - tkwin = Tk_NameToWindow(interp, string, tkwin); - if (tkwin == NULL) { + if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin) != TCL_OK) { return TCL_ERROR; } @@ -1662,10 +1783,12 @@ Tk_WinfoObjCmd( visInfoPtr = XGetVisualInfo(Tk_Display(tkwin), VisualScreenMask, &template, &count); if (visInfoPtr == NULL) { - Tcl_SetStringObj(resultPtr, - "can't find any visuals for screen", -1); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "can't find any visuals for screen", -1)); + Tcl_SetErrorCode(interp, "TK", "VISUAL", "NONE", NULL); return TCL_ERROR; } + resultPtr = Tcl_NewObj(); for (i = 0; i < count; i++) { string = TkFindStateString(visualMap, visInfoPtr[i].class); if (string == NULL) { @@ -1675,12 +1798,13 @@ Tk_WinfoObjCmd( } if (includeVisualId) { sprintf(visualIdString, " 0x%x", - (unsigned int) visInfoPtr[i].visualid); + (unsigned) visInfoPtr[i].visualid); strcat(buf, visualIdString); } strPtr = Tcl_NewStringObj(buf, -1); Tcl_ListObjAppendElement(NULL, resultPtr, strPtr); } + Tcl_SetObjResult(interp, resultPtr); XFree((char *) visInfoPtr); break; } @@ -1717,7 +1841,7 @@ Tk_WmObjCmd( Tk_Window tkwin; TkWindow *winPtr; - static const char *optionStrings[] = { + static const char *const optionStrings[] = { "aspect", "client", "command", "deiconify", "focusmodel", "frame", "geometry", "grid", "group", "iconbitmap", "iconify", "iconmask", @@ -1756,8 +1880,8 @@ Tk_WmObjCmd( return TCL_ERROR; } if (objc == 2) { - Tcl_SetObjResult(interp, - Tcl_NewBooleanObj(dispPtr->flags & TK_DISPLAY_WM_TRACING)); + Tcl_SetObjResult(interp, Tcl_NewBooleanObj( + dispPtr->flags & TK_DISPLAY_WM_TRACING)); return TCL_OK; } if (Tcl_GetBooleanFromObj(interp, objv[2], &wmTracing) != TCL_OK) { @@ -1782,8 +1906,10 @@ Tk_WmObjCmd( return TCL_ERROR; } if (!(winPtr->flags & TK_TOP_LEVEL)) { - Tcl_AppendResult(interp, "window \"", winPtr->pathName, - "\" isn't a top-level window", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "window \"%s\" isn't a top-level window", winPtr->pathName)); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "TOPLEVEL", winPtr->pathName, + NULL); return TCL_ERROR; } @@ -1897,7 +2023,7 @@ Tk_WmObjCmd( updateGeom: if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) { - Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr); + Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr); wmPtr->flags |= WM_UPDATE_PENDING; } return TCL_OK; @@ -1944,7 +2070,7 @@ TkGetDisplayOf( * unmodified if "-displayof" argument was not * present. */ { - char *string; + const char *string; int length; if (objc < 1) { @@ -1954,8 +2080,9 @@ TkGetDisplayOf( if ((length >= 2) && (strncmp(string, "-displayof", (unsigned) length) == 0)) { if (objc < 2) { - Tcl_SetStringObj(Tcl_GetObjResult(interp), - "value for \"-displayof\" missing", -1); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "value for \"-displayof\" missing", -1)); + Tcl_SetErrorCode(interp, "TK", "NO_VALUE", "DISPLAYOF", NULL); return -1; } *tkwinPtr = Tk_NameToWindow(interp, Tcl_GetString(objv[1]), *tkwinPtr); @@ -1970,7 +2097,7 @@ TkGetDisplayOf( /* *---------------------------------------------------------------------- * - * TkDeadAppCmd -- + * TkDeadAppObjCmd -- * * If an application has been deleted then all Tk commands will be * re-bound to this function. @@ -1987,14 +2114,15 @@ TkGetDisplayOf( /* ARGSUSED */ int -TkDeadAppCmd( +TkDeadAppObjCmd( ClientData clientData, /* Dummy. */ Tcl_Interp *interp, /* Current interpreter. */ - int argc, /* Number of arguments. */ - const char **argv) /* Argument strings. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument strings. */ { - Tcl_AppendResult(interp, "can't invoke \"", argv[0], - "\" command: application has been destroyed", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't invoke \"%s\" command: application has been destroyed", + Tcl_GetString(objv[0]))); return TCL_ERROR; } diff --git a/generic/tkColor.c b/generic/tkColor.c index bd14f87..ccb9914 100644 --- a/generic/tkColor.c +++ b/generic/tkColor.c @@ -42,6 +42,7 @@ static Tcl_ThreadDataKey dataKey; static void ColorInit(TkDisplay *dispPtr); static void DupColorObjProc(Tcl_Obj *srcObjPtr,Tcl_Obj *dupObjPtr); +static void FreeColorObj(Tcl_Obj *objPtr); static void FreeColorObjProc(Tcl_Obj *objPtr); static void InitColorObj(Tcl_Obj *objPtr); @@ -51,7 +52,7 @@ static void InitColorObj(Tcl_Obj *objPtr); * of the Tcl_Obj points to a TkColor object. */ -Tcl_ObjType tkColorObjType = { +const Tcl_ObjType tkColorObjType = { "color", /* name */ FreeColorObjProc, /* freeIntRepProc */ DupColorObjProc, /* dupIntRepProc */ @@ -111,7 +112,7 @@ Tk_AllocColorFromObj( * longer in use. Clear the reference. */ - FreeColorObjProc(objPtr); + FreeColorObj(objPtr); tkColPtr = NULL; } else if ((Tk_Screen(tkwin) == tkColPtr->screen) && (Tk_Colormap(tkwin) == tkColPtr->colormap)) { @@ -129,14 +130,14 @@ Tk_AllocColorFromObj( if (tkColPtr != NULL) { TkColor *firstColorPtr = Tcl_GetHashValue(tkColPtr->hashPtr); - FreeColorObjProc(objPtr); + FreeColorObj(objPtr); for (tkColPtr = firstColorPtr; tkColPtr != NULL; tkColPtr = tkColPtr->nextPtr) { if ((Tk_Screen(tkwin) == tkColPtr->screen) && (Tk_Colormap(tkwin) == tkColPtr->colormap)) { tkColPtr->resourceRefCount++; tkColPtr->objRefCount++; - objPtr->internalRep.twoPtrValue.ptr1 = (void *) tkColPtr; + objPtr->internalRep.twoPtrValue.ptr1 = tkColPtr; return (XColor *) tkColPtr; } } @@ -147,7 +148,7 @@ Tk_AllocColorFromObj( */ tkColPtr = (TkColor *) Tk_GetColor(interp, tkwin, Tcl_GetString(objPtr)); - objPtr->internalRep.twoPtrValue.ptr1 = (void *) tkColPtr; + objPtr->internalRep.twoPtrValue.ptr1 = tkColPtr; if (tkColPtr != NULL) { tkColPtr->objRefCount++; } @@ -223,11 +224,13 @@ Tk_GetColor( if (tkColPtr == NULL) { if (interp != NULL) { if (*name == '#') { - Tcl_AppendResult(interp, "invalid color name \"", name, - "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "invalid color name \"%s\"", name)); + Tcl_SetErrorCode(interp, "TK", "VALUE", "COLOR", NULL); } else { - Tcl_AppendResult(interp, "unknown color name \"", name, - "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "unknown color name \"%s\"", name)); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "COLOR", name, NULL); } } if (isNew) { @@ -356,7 +359,7 @@ Tk_GetColorByValue( *-------------------------------------------------------------- */ -CONST char * +const char * Tk_NameOfColor( XColor *colorPtr) /* Color whose name is desired. */ { @@ -365,11 +368,30 @@ Tk_NameOfColor( if (tkColPtr->magic==COLOR_MAGIC && tkColPtr->type==TK_COLOR_BY_NAME) { return tkColPtr->hashPtr->key.string; } else { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); sprintf(tsdPtr->rgbString, "#%04x%04x%04x", colorPtr->red, colorPtr->green, colorPtr->blue); + + /* + * If the string has the form #RSRSTUTUVWVW (where equal letters + * denote equal hexdigits) then this is equivalent to #RSTUVW. Then + * output the shorter form. + */ + + if ((tsdPtr->rgbString[1] == tsdPtr->rgbString[3]) + && (tsdPtr->rgbString[2] == tsdPtr->rgbString[4]) + && (tsdPtr->rgbString[5] == tsdPtr->rgbString[7]) + && (tsdPtr->rgbString[6] == tsdPtr->rgbString[8]) + && (tsdPtr->rgbString[9] == tsdPtr->rgbString[11]) + && (tsdPtr->rgbString[10] == tsdPtr->rgbString[12])) { + tsdPtr->rgbString[3] = tsdPtr->rgbString[5]; + tsdPtr->rgbString[4] = tsdPtr->rgbString[6]; + tsdPtr->rgbString[5] = tsdPtr->rgbString[9]; + tsdPtr->rgbString[6] = tsdPtr->rgbString[10]; + tsdPtr->rgbString[7] = '\0'; + } return tsdPtr->rgbString; } } @@ -496,7 +518,7 @@ Tk_FreeColor( */ if (tkColPtr->objRefCount == 0) { - ckfree((char *) tkColPtr); + ckfree(tkColPtr); } } @@ -528,13 +550,13 @@ Tk_FreeColorFromObj( Tcl_Obj *objPtr) /* The Tcl_Obj * to be freed. */ { Tk_FreeColor(Tk_GetColorFromObj(tkwin, objPtr)); - FreeColorObjProc(objPtr); + FreeColorObj(objPtr); } /* *--------------------------------------------------------------------------- * - * FreeColorObjProc -- + * FreeColorObjProc, FreeColorObj -- * * This proc is called to release an object reference to a color. Called * when the object's internal rep is released or when the cached tkColPtr @@ -554,13 +576,21 @@ static void FreeColorObjProc( Tcl_Obj *objPtr) /* The object we are releasing. */ { - TkColor *tkColPtr = (TkColor *) objPtr->internalRep.twoPtrValue.ptr1; + FreeColorObj(objPtr); + objPtr->typePtr = NULL; +} + +static void +FreeColorObj( + Tcl_Obj *objPtr) /* The object we are releasing. */ +{ + TkColor *tkColPtr = objPtr->internalRep.twoPtrValue.ptr1; if (tkColPtr != NULL) { tkColPtr->objRefCount--; if ((tkColPtr->objRefCount == 0) && (tkColPtr->resourceRefCount == 0)) { - ckfree((char *) tkColPtr); + ckfree(tkColPtr); } objPtr->internalRep.twoPtrValue.ptr1 = NULL; } @@ -589,10 +619,10 @@ DupColorObjProc( Tcl_Obj *srcObjPtr, /* The object we are copying from. */ Tcl_Obj *dupObjPtr) /* The object we are copying to. */ { - TkColor *tkColPtr = (TkColor *) srcObjPtr->internalRep.twoPtrValue.ptr1; + TkColor *tkColPtr = srcObjPtr->internalRep.twoPtrValue.ptr1; dupObjPtr->typePtr = srcObjPtr->typePtr; - dupObjPtr->internalRep.twoPtrValue.ptr1 = (void *) tkColPtr; + dupObjPtr->internalRep.twoPtrValue.ptr1 = tkColPtr; if (tkColPtr != NULL) { tkColPtr->objRefCount++; @@ -639,7 +669,7 @@ Tk_GetColorFromObj( * map. If it is, we are done. */ - tkColPtr = (TkColor *) objPtr->internalRep.twoPtrValue.ptr1; + tkColPtr = objPtr->internalRep.twoPtrValue.ptr1; if ((tkColPtr != NULL) && (tkColPtr->resourceRefCount > 0) && (Tk_Screen(tkwin) == tkColPtr->screen) @@ -669,8 +699,8 @@ Tk_GetColorFromObj( (tkColPtr != NULL); tkColPtr = tkColPtr->nextPtr) { if ((Tk_Screen(tkwin) == tkColPtr->screen) && (Tk_Colormap(tkwin) == tkColPtr->colormap)) { - FreeColorObjProc(objPtr); - objPtr->internalRep.twoPtrValue.ptr1 = (void *) tkColPtr; + FreeColorObj(objPtr); + objPtr->internalRep.twoPtrValue.ptr1 = tkColPtr; tkColPtr->objRefCount++; return (XColor *) tkColPtr; } @@ -715,7 +745,7 @@ InitColorObj( Tcl_GetString(objPtr); typePtr = objPtr->typePtr; if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) { - (*typePtr->freeIntRepProc)(objPtr); + typePtr->freeIntRepProc(objPtr); } objPtr->typePtr = &tkColorObjType; objPtr->internalRep.twoPtrValue.ptr1 = NULL; @@ -772,7 +802,7 @@ Tcl_Obj * TkDebugColor( Tk_Window tkwin, /* The window in which the color will be used * (not currently used). */ - char *name) /* Name of the desired color. */ + const char *name) /* Name of the desired color. */ { Tcl_HashEntry *hashPtr; Tcl_Obj *resultPtr; @@ -799,30 +829,30 @@ TkDebugColor( return resultPtr; } -#ifndef __WIN32__ +#ifndef _WIN32 /* This function is not necessary for Win32, * since XParseColor already does the right thing */ #undef XParseColor -CONST char *CONST tkWebColors[20] = { +const char *const tkWebColors[20] = { /* 'a' */ "qua\0#0000ffffffff", /* 'b' */ NULL, /* 'c' */ "rimson\0#dcdc14143c3c", /* 'd' */ NULL, /* 'e' */ NULL, /* 'f' */ "uchsia\0#ffff0000ffff", - /* 'g' */ NULL, + /* 'g' */ "reen\0#000080800000", /* 'h' */ NULL, /* 'i' */ "ndigo\0#4b4b00008282", /* 'j' */ NULL, /* 'k' */ NULL, /* 'l' */ "ime\0#0000ffff0000", - /* 'm' */ NULL, + /* 'm' */ "aroon\0#808000000000", /* 'n' */ NULL, /* 'o' */ "live\0#808080800000", - /* 'p' */ NULL, + /* 'p' */ "urple\0#808000008080", /* 'q' */ NULL, /* 'r' */ NULL, /* 's' */ "ilver\0#c0c0c0c0c0c0", @@ -883,25 +913,31 @@ TkParseColor( } goto done; } else if (((*name - 'A') & 0xdf) < sizeof(tkWebColors)/sizeof(tkWebColors[0])) { - const char *p = tkWebColors[((*name - 'A') & 0x1f)]; - if (p) { - const char *q = name; - while (!((*p - *(++q)) & 0xdf)) { - if (!*p++) { - name = p; - goto done; + if (!((name[0] - 'G') & 0xdf) && !((name[1] - 'R') & 0xdf) + && !((name[2] - 'A') & 0xdb) && !((name[3] - 'Y') & 0xdf) + && !name[4]) { + name = "#808080808080"; + goto done; + } else { + const char *p = tkWebColors[((*name - 'A') & 0x1f)]; + if (p) { + const char *q = name; + while (!((*p - *(++q)) & 0xdf)) { + if (!*p++) { + name = p; + goto done; + } } } } } if (strlen(name) > 99) { - /* Don't bother to parse this. [Bug 2809525]*/ return 0; } done: return XParseColor(display, map, name, color); } -#endif /* __WIN32__ */ +#endif /* _WIN32 */ /* * Local Variables: * mode: c diff --git a/generic/tkColor.h b/generic/tkColor.h index 12c6662..54e8cdc 100644 --- a/generic/tkColor.h +++ b/generic/tkColor.h @@ -12,12 +12,7 @@ #ifndef _TKCOLOR #define _TKCOLOR -#include <tkInt.h> - -#ifdef BUILD_tk -#undef TCL_STORAGE_CLASS -#define TCL_STORAGE_CLASS DLLEXPORT -#endif +#include "tkInt.h" /* * One of the following data structures is used to keep track of each color @@ -77,7 +72,4 @@ MODULE_SCOPE void TkpFreeColor(TkColor *tkColPtr); MODULE_SCOPE TkColor * TkpGetColor(Tk_Window tkwin, Tk_Uid name); MODULE_SCOPE TkColor * TkpGetColorByValue(Tk_Window tkwin, XColor *colorPtr); -#undef TCL_STORAGE_CLASS -#define TCL_STORAGE_CLASS DLLIMPORT - #endif /* _TKCOLOR */ diff --git a/generic/tkConfig.c b/generic/tkConfig.c index d586787..d3c8aad 100644 --- a/generic/tkConfig.c +++ b/generic/tkConfig.c @@ -27,11 +27,16 @@ #include "tkFont.h" /* - * The following definition is an AssocData key used to keep track of all of - * the option tables that have been created for an interpreter. + * The following definition keeps track of all of + * the option tables that have been created for a thread. */ -#define OPTION_HASH_KEY "TkOptionTable" +typedef struct ThreadSpecificData { + int initialized; /* 0 means table below needs initializing. */ + Tcl_HashTable hashTable; +} ThreadSpecificData; +static Tcl_ThreadDataKey dataKey; + /* * The following two structures are used along with Tk_OptionSpec structures @@ -63,7 +68,7 @@ typedef struct TkOption { struct TkOption *synonymPtr; /* For synonym options, this points to the * master entry. */ - struct Tk_ObjCustomOption *custom; + const struct Tk_ObjCustomOption *custom; /* For TK_OPTION_CUSTOM. */ } extra; int flags; /* Miscellaneous flag values; see below for @@ -113,8 +118,6 @@ typedef struct OptionTable { static int DoObjConfig(Tcl_Interp *interp, char *recordPtr, Option *optionPtr, Tcl_Obj *valuePtr, Tk_Window tkwin, Tk_SavedOption *savePtr); -static void DestroyOptionHashTable(ClientData clientData, - Tcl_Interp *interp); static void FreeResources(Option *optionPtr, Tcl_Obj *objPtr, char *internalPtr, Tk_Window tkwin); static Tcl_Obj * GetConfigList(char *recordPtr, @@ -125,7 +128,8 @@ static Option * GetOption(const char *name, OptionTable *tablePtr); static Option * GetOptionFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, OptionTable *tablePtr); static int ObjectIsEmpty(Tcl_Obj *objPtr); -static int SetOptionFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); +static void FreeOptionInternalRep(Tcl_Obj *objPtr); +static void DupOptionInternalRep(Tcl_Obj *, Tcl_Obj *); /* * The structure below defines an object type that is used to cache the result @@ -134,12 +138,12 @@ static int SetOptionFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); * the internalPtr2 field points to the entry that matched. */ -Tcl_ObjType tkOptionObjType = { +static const Tcl_ObjType optionObjType = { "option", /* name */ - NULL, /* freeIntRepProc */ - NULL, /* dupIntRepProc */ + FreeOptionInternalRep, /* freeIntRepProc */ + DupOptionInternalRep, /* dupIntRepProc */ NULL, /* updateStringProc */ - SetOptionFromAny /* setFromAnyProc */ + NULL /* setFromAnyProc */ }; /* @@ -168,31 +172,26 @@ Tk_CreateOptionTable( /* Static information about the configuration * options. */ { - Tcl_HashTable *hashTablePtr; Tcl_HashEntry *hashEntryPtr; int newEntry; OptionTable *tablePtr; const Tk_OptionSpec *specPtr, *specPtr2; Option *optionPtr; int numOptions, i; + ThreadSpecificData *tsdPtr = + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* - * We use an AssocData value in the interpreter to keep a hash table of - * all the option tables we've created for this application. This is used - * for two purposes. First, it allows us to share the tables (e.g. in - * several chains) and second, we use the deletion callback for the - * AssocData to delete all the option tables when the interpreter is - * deleted. The code below finds the hash table or creates a new one if it + * We use an TSD in the thread to keep a hash table of + * all the option tables we've created for this application. This is + * used for allowing us to share the tables (e.g. in several chains). + * The code below finds the hash table or creates a new one if it * doesn't already exist. */ - hashTablePtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, OPTION_HASH_KEY, - NULL); - if (hashTablePtr == NULL) { - hashTablePtr = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); - Tcl_InitHashTable(hashTablePtr, TCL_ONE_WORD_KEYS); - Tcl_SetAssocData(interp, OPTION_HASH_KEY, DestroyOptionHashTable, - (ClientData) hashTablePtr); + if (!tsdPtr->initialized) { + Tcl_InitHashTable(&tsdPtr->hashTable, TCL_ONE_WORD_KEYS); + tsdPtr->initialized = 1; } /* @@ -200,10 +199,10 @@ Tk_CreateOptionTable( * reuse the existing table. */ - hashEntryPtr = Tcl_CreateHashEntry(hashTablePtr, (char *) templatePtr, + hashEntryPtr = Tcl_CreateHashEntry(&tsdPtr->hashTable, (char *) templatePtr, &newEntry); if (!newEntry) { - tablePtr = (OptionTable *) Tcl_GetHashValue(hashEntryPtr); + tablePtr = Tcl_GetHashValue(hashEntryPtr); tablePtr->refCount++; return (Tk_OptionTable) tablePtr; } @@ -217,8 +216,7 @@ Tk_CreateOptionTable( for (specPtr = templatePtr; specPtr->type != TK_OPTION_END; specPtr++) { numOptions++; } - tablePtr = (OptionTable *) (ckalloc(sizeof(OptionTable) - + (numOptions * sizeof(Option)))); + tablePtr = ckalloc(sizeof(OptionTable) + (numOptions * sizeof(Option))); tablePtr->refCount = 1; tablePtr->hashEntryPtr = hashEntryPtr; tablePtr->nextPtr = NULL; @@ -268,7 +266,7 @@ Tk_CreateOptionTable( || (specPtr->type == TK_OPTION_BORDER)) && (specPtr->clientData != NULL)) { optionPtr->extra.monoColorPtr = - Tcl_NewStringObj((char *) specPtr->clientData, -1); + Tcl_NewStringObj(specPtr->clientData, -1); Tcl_IncrRefCount(optionPtr->extra.monoColorPtr); } @@ -276,8 +274,8 @@ Tk_CreateOptionTable( /* * Get the custom parsing, etc., functions. */ - optionPtr->extra.custom = - (Tk_ObjCustomOption *) specPtr->clientData; + + optionPtr->extra.custom = specPtr->clientData; } } if (((specPtr->type == TK_OPTION_STRING) @@ -301,8 +299,8 @@ Tk_CreateOptionTable( */ if (specPtr->clientData != NULL) { - tablePtr->nextPtr = (OptionTable *) Tk_CreateOptionTable(interp, - (Tk_OptionSpec *) specPtr->clientData); + tablePtr->nextPtr = (OptionTable *) + Tk_CreateOptionTable(interp, specPtr->clientData); } return (Tk_OptionTable) tablePtr; @@ -355,60 +353,7 @@ Tk_DeleteOptionTable( } } Tcl_DeleteHashEntry(tablePtr->hashEntryPtr); - ckfree((char *) tablePtr); -} - -/* - *---------------------------------------------------------------------- - * - * DestroyOptionHashTable -- - * - * This function is the deletion callback associated with the AssocData - * entry created by Tk_CreateOptionTable. It is invoked when an - * interpreter is deleted, and deletes all of the option tables - * associated with that interpreter. - * - * Results: - * None. - * - * Side effects: - * The option hash table is destroyed along with all of the OptionTable - * structures that it refers to. - * - *---------------------------------------------------------------------- - */ - -static void -DestroyOptionHashTable( - ClientData clientData, /* The hash table we are destroying */ - Tcl_Interp *interp) /* The interpreter we are destroying */ -{ - Tcl_HashTable *hashTablePtr = (Tcl_HashTable *) clientData; - Tcl_HashSearch search; - Tcl_HashEntry *hashEntryPtr; - OptionTable *tablePtr; - - for (hashEntryPtr = Tcl_FirstHashEntry(hashTablePtr, &search); - hashEntryPtr != NULL; - hashEntryPtr = Tcl_NextHashEntry(&search)) { - tablePtr = (OptionTable *) Tcl_GetHashValue(hashEntryPtr); - - /* - * The following statements do two tricky things: - * 1. They ensure that the option table is deleted, even if there are - * outstanding references to it. - * 2. They ensure that Tk_DeleteOptionTable doesn't delete other - * tables chained from this one; we'll do it when we come across - * the hash table entry for the chained table (in fact, the chained - * table may already have been deleted). - */ - - tablePtr->refCount = 1; - tablePtr->nextPtr = NULL; - Tk_DeleteOptionTable((Tk_OptionTable) tablePtr); - } - Tcl_DeleteHashTable(hashTablePtr); - ckfree((char *) hashTablePtr); + ckfree(tablePtr); } /* @@ -710,7 +655,8 @@ DoObjConfig( break; } case TK_OPTION_STRING: { - char *newStr, *value; + char *newStr; + const char *value; int length; if (nullOK && ObjectIsEmpty(valuePtr)) { @@ -719,7 +665,7 @@ DoObjConfig( if (internalPtr != NULL) { if (valuePtr != NULL) { value = Tcl_GetStringFromObj(valuePtr, &length); - newStr = ckalloc((unsigned) (length + 1)); + newStr = ckalloc(length + 1); strcpy(newStr, value); } else { newStr = NULL; @@ -732,8 +678,8 @@ DoObjConfig( case TK_OPTION_STRING_TABLE: { int newValue; - if (Tcl_GetIndexFromObj(interp, valuePtr, - (const char **) optionPtr->specPtr->clientData, + if (Tcl_GetIndexFromObjStruct(interp, valuePtr, + optionPtr->specPtr->clientData, sizeof(char *), optionPtr->specPtr->optionName+1, 0, &newValue) != TCL_OK) { return TCL_ERROR; } @@ -930,7 +876,7 @@ DoObjConfig( break; } case TK_OPTION_CUSTOM: { - Tk_ObjCustomOption *custom = optionPtr->extra.custom; + const Tk_ObjCustomOption *custom = optionPtr->extra.custom; if (custom->setProc(custom->clientData, interp, tkwin, &valuePtr, recordPtr, optionPtr->specPtr->internalOffset, @@ -940,16 +886,13 @@ DoObjConfig( break; } - { - char buf[40+TCL_INTEGER_SPACE]; - default: - sprintf(buf, "bad config table: unknown type %d", - optionPtr->specPtr->type); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad config table: unknown type %d", + optionPtr->specPtr->type)); + Tcl_SetErrorCode(interp, "TK", "BAD_CONFIG", NULL); return TCL_ERROR; } - } /* * Release resources associated with the old value, if we're not returning @@ -994,16 +937,13 @@ static int ObjectIsEmpty( Tcl_Obj *objPtr) /* Object to test. May be NULL. */ { - int length; - if (objPtr == NULL) { return 1; } - if (objPtr->bytes != NULL) { - return (objPtr->length == 0); + if (objPtr->bytes == NULL) { + Tcl_GetString(objPtr); } - Tcl_GetStringFromObj(objPtr, &length); - return (length == 0); + return (objPtr->length == 0); } /* @@ -1121,13 +1061,13 @@ GetOptionFromObj( OptionTable *tablePtr) /* Table in which to look up objPtr. */ { Option *bestPtr; - char *name; + const char *name; /* * First, check to see if the object already has the answer cached. */ - if (objPtr->typePtr == &tkOptionObjType) { + if (objPtr->typePtr == &optionObjType) { if (objPtr->internalRep.twoPtrValue.ptr1 == (void *) tablePtr) { return (Option *) objPtr->internalRep.twoPtrValue.ptr2; } @@ -1149,12 +1089,15 @@ GetOptionFromObj( } objPtr->internalRep.twoPtrValue.ptr1 = (void *) tablePtr; objPtr->internalRep.twoPtrValue.ptr2 = (void *) bestPtr; - objPtr->typePtr = &tkOptionObjType; + objPtr->typePtr = &optionObjType; + tablePtr->refCount++; return bestPtr; error: if (interp != NULL) { - Tcl_AppendResult(interp, "unknown option \"", name, "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "unknown option \"%s\"", name)); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "OPTION", name, NULL); } return NULL; } @@ -1199,32 +1142,55 @@ TkGetOptionSpec( /* *---------------------------------------------------------------------- * - * SetOptionFromAny -- + * FreeOptionInternalRep -- * - * This function is called to convert a Tcl object to option internal - * form. However, this doesn't make sense (need to have a table of - * options in order to do the conversion) so the function always - * generates an error. + * Part of the option Tcl object type implementation. Frees the storage + * associated with a option object's internal representation unless it + * is still in use. * * Results: - * The return value is always TCL_ERROR, and an error message is left in - * interp's result if interp isn't NULL. + * None. * * Side effects: - * None. + * The option object's internal rep is marked invalid and its memory + * gets freed unless it is still in use somewhere. In that case the + * cleanup is delayed until the last reference goes away. * *---------------------------------------------------------------------- */ -static int -SetOptionFromAny( - Tcl_Interp *interp, /* Used for error reporting if not NULL. */ - register Tcl_Obj *objPtr) /* The object to convert. */ +static void +FreeOptionInternalRep( + register Tcl_Obj *objPtr) /* Object whose internal rep to free. */ { - Tcl_AppendToObj(Tcl_GetObjResult(interp), - "can't convert value to option except via GetOptionFromObj API", - -1); - return TCL_ERROR; + register Tk_OptionTable tablePtr = (Tk_OptionTable) objPtr->internalRep.twoPtrValue.ptr1; + + Tk_DeleteOptionTable(tablePtr); + objPtr->typePtr = NULL; + objPtr->internalRep.twoPtrValue.ptr1 = NULL; + objPtr->internalRep.twoPtrValue.ptr2 = NULL; +} + +/* + *--------------------------------------------------------------------------- + * + * DupOptionInternalRep -- + * + * When a cached option object is duplicated, this is called to update the + * internal reps. + * + *--------------------------------------------------------------------------- + */ + +static void +DupOptionInternalRep( + Tcl_Obj *srcObjPtr, /* The object we are copying from. */ + Tcl_Obj *dupObjPtr) /* The object we are copying to. */ +{ + register OptionTable *tablePtr = (OptionTable *) srcObjPtr->internalRep.twoPtrValue.ptr1; + tablePtr->refCount++; + dupObjPtr->typePtr = srcObjPtr->typePtr; + dupObjPtr->internalRep = srcObjPtr->internalRep; } /* @@ -1304,9 +1270,10 @@ Tk_SetOptions( if (objc < 2) { if (interp != NULL) { - Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), - "value for \"", Tcl_GetStringFromObj(*objv, NULL), - "\" missing", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "value for \"%s\" missing", + Tcl_GetString(*objv))); + Tcl_SetErrorCode(interp, "TK", "VALUE_MISSING", NULL); goto error; } } @@ -1317,7 +1284,7 @@ Tk_SetOptions( * more space. */ - newSavePtr = (Tk_SavedOptions *) ckalloc(sizeof(Tk_SavedOptions)); + newSavePtr = ckalloc(sizeof(Tk_SavedOptions)); newSavePtr->recordPtr = recordPtr; newSavePtr->tkwin = tkwin; newSavePtr->numItems = 0; @@ -1328,11 +1295,9 @@ Tk_SetOptions( if (DoObjConfig(interp, recordPtr, optionPtr, objv[1], tkwin, (savePtr != NULL) ? &lastSavePtr->items[lastSavePtr->numItems] : NULL) != TCL_OK) { - char msg[100]; - - sprintf(msg, "\n (processing \"%.40s\" option)", - Tcl_GetStringFromObj(*objv, NULL)); - Tcl_AddErrorInfo(interp, msg); + Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf( + "\n (processing \"%.40s\" option)", + Tcl_GetString(*objv))); goto error; } if (savePtr != NULL) { @@ -1393,7 +1358,7 @@ Tk_RestoreSavedOptions( if (savePtr->nextPtr != NULL) { Tk_RestoreSavedOptions(savePtr->nextPtr); - ckfree((char *) savePtr->nextPtr); + ckfree(savePtr->nextPtr); savePtr->nextPtr = NULL; } for (i = savePtr->numItems - 1; i >= 0; i--) { @@ -1433,6 +1398,7 @@ Tk_RestoreSavedOptions( if (specPtr->internalOffset >= 0) { register char *ptr = (char *) &savePtr->items[i].internalForm; + CLANG_ASSERT(internalPtr); switch (specPtr->type) { case TK_OPTION_BOOLEAN: *((int *) internalPtr) = *((int *) ptr); @@ -1484,7 +1450,7 @@ Tk_RestoreSavedOptions( *((Tk_Window *) internalPtr) = *((Tk_Window *) ptr); break; case TK_OPTION_CUSTOM: { - Tk_ObjCustomOption *custom = optionPtr->extra.custom; + const Tk_ObjCustomOption *custom = optionPtr->extra.custom; if (custom->restoreProc != NULL) { custom->restoreProc(custom->clientData, savePtr->tkwin, @@ -1527,7 +1493,7 @@ Tk_FreeSavedOptions( if (savePtr->nextPtr != NULL) { Tk_FreeSavedOptions(savePtr->nextPtr); - ckfree((char *) savePtr->nextPtr); + ckfree(savePtr->nextPtr); } for (count = savePtr->numItems, savedOptionPtr = &savePtr->items[savePtr->numItems-1]; @@ -1709,7 +1675,7 @@ FreeResources( } break; case TK_OPTION_CUSTOM: { - Tk_ObjCustomOption *custom = optionPtr->extra.custom; + const Tk_ObjCustomOption *custom = optionPtr->extra.custom; if (internalFormExists && custom->freeProc != NULL) { custom->freeProc(custom->clientData, tkwin, internalPtr); } @@ -1729,7 +1695,6 @@ FreeResources( * single option or all the configuration options in a table. * * Results: - * This function normally returns a pointer to an object. If namePtr * isn't NULL, then the result object is a list with five elements: the * option's name, its database name, database class, default value, and @@ -2000,7 +1965,7 @@ GetObjectForOption( break; } case TK_OPTION_CUSTOM: { - Tk_ObjCustomOption *custom = optionPtr->extra.custom; + const Tk_ObjCustomOption *custom = optionPtr->extra.custom; objPtr = custom->getProc(custom->clientData, tkwin, recordPtr, optionPtr->specPtr->internalOffset); @@ -2106,15 +2071,14 @@ TkDebugConfig( * interpreter anymore. */ { OptionTable *tablePtr = (OptionTable *) table; - Tcl_HashTable *hashTablePtr; Tcl_HashEntry *hashEntryPtr; Tcl_HashSearch search; Tcl_Obj *objPtr; + ThreadSpecificData *tsdPtr = + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); objPtr = Tcl_NewObj(); - hashTablePtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, OPTION_HASH_KEY, - NULL); - if (hashTablePtr == NULL) { + if (!tablePtr || !tsdPtr->initialized) { return objPtr; } @@ -2123,7 +2087,7 @@ TkDebugConfig( * want still is valid. */ - for (hashEntryPtr = Tcl_FirstHashEntry(hashTablePtr, &search); + for (hashEntryPtr = Tcl_FirstHashEntry(&tsdPtr->hashTable, &search); hashEntryPtr != NULL; hashEntryPtr = Tcl_NextHashEntry(&search)) { if (tablePtr == (OptionTable *) Tcl_GetHashValue(hashEntryPtr)) { diff --git a/generic/tkConsole.c b/generic/tkConsole.c index 2cd2632..a6a8cbf 100644 --- a/generic/tkConsole.c +++ b/generic/tkConsole.c @@ -11,7 +11,7 @@ * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ -#include "tk.h" +#include "tkInt.h" /* * Each console is associated with an instance of the ConsoleInfo struct. @@ -46,25 +46,25 @@ typedef struct ChannelData { static int ConsoleClose(ClientData instanceData, Tcl_Interp *interp); static void ConsoleDeleteProc(ClientData clientData); static void ConsoleEventProc(ClientData clientData, XEvent *eventPtr); -static int ConsoleHandle(ClientData instanceData, - int direction, ClientData *handlePtr); -static int ConsoleInput(ClientData instanceData, - char *buf, int toRead, int *errorCode); +static int ConsoleHandle(ClientData instanceData, int direction, + ClientData *handlePtr); +static int ConsoleInput(ClientData instanceData, char *buf, int toRead, + int *errorCode); static int ConsoleObjCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *CONST objv[]); -static int ConsoleOutput(ClientData instanceData, - CONST char *buf, int toWrite, int *errorCode); + int objc, Tcl_Obj *const objv[]); +static int ConsoleOutput(ClientData instanceData, const char *buf, + int toWrite, int *errorCode); static void ConsoleWatch(ClientData instanceData, int mask); static void DeleteConsoleInterp(ClientData clientData); static void InterpDeleteProc(ClientData clientData, Tcl_Interp *interp); static int InterpreterObjCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *CONST objv[]); + int objc, Tcl_Obj *const objv[]); /* * This structure describes the channel type structure for file based IO: */ -static Tcl_ChannelType consoleChannelType = { +static const Tcl_ChannelType consoleChannelType = { "console", /* Type name. */ TCL_CHANNEL_VERSION_4, /* v4 channel */ ConsoleClose, /* Close proc. */ @@ -84,7 +84,7 @@ static Tcl_ChannelType consoleChannelType = { NULL }; -#ifdef __WIN32__ +#ifdef _WIN32 #include <windows.h> /* @@ -166,7 +166,7 @@ ShouldUseConsoleChannel( */ if (fileType == FILE_TYPE_CHAR) { - dcb.DCBlength = sizeof( DCB ) ; + dcb.DCBlength = sizeof(DCB); if (!GetConsoleMode(handle, &consoleParams) && !GetCommState(handle, &dcb)) { /* @@ -223,13 +223,16 @@ Tk_InitConsoleChannels( * Ensure that we are getting a compatible version of Tcl. */ - if (Tcl_InitStubs(interp, "8.5.0", 0) == NULL) { + if (Tcl_InitStubs(interp, "8.6", 0) == NULL) { return; } - consoleInitPtr = Tcl_GetThreadData(&consoleInitKey, (int)sizeof(int)); + consoleInitPtr = Tcl_GetThreadData(&consoleInitKey, (int) sizeof(int)); if (*consoleInitPtr) { - /* We've already initialized console channels in this thread. */ + /* + * We've already initialized console channels in this thread. + */ + return; } *consoleInitPtr = 1; @@ -240,74 +243,69 @@ Tk_InitConsoleChannels( if (!(doIn || doOut || doErr)) { /* - * No std channels should be tied to the console; - * Thus, no need to create the console + * No std channels should be tied to the console; thus, no need to + * create the console. */ + return; } /* - * At least one std channel wants to be tied to the console, - * so create the interp for it to live in. + * At least one std channel wants to be tied to the console, so create the + * interp for it to live in. */ - info = (ConsoleInfo *) ckalloc(sizeof(ConsoleInfo)); + info = ckalloc(sizeof(ConsoleInfo)); info->consoleInterp = NULL; info->interp = NULL; info->refCount = 0; if (doIn) { - ChannelData *data = (ChannelData *) ckalloc(sizeof(ChannelData)); + ChannelData *data = ckalloc(sizeof(ChannelData)); + data->info = info; data->info->refCount++; data->type = TCL_STDIN; consoleChannel = Tcl_CreateChannel(&consoleChannelType, "console0", - (ClientData) data, TCL_READABLE); + data, TCL_READABLE); if (consoleChannel != NULL) { - Tcl_SetChannelOption(NULL, consoleChannel, - "-translation", "lf"); - Tcl_SetChannelOption(NULL, consoleChannel, - "-buffering", "none"); - Tcl_SetChannelOption(NULL, consoleChannel, - "-encoding", "utf-8"); + Tcl_SetChannelOption(NULL, consoleChannel, "-translation", "lf"); + Tcl_SetChannelOption(NULL, consoleChannel, "-buffering", "none"); + Tcl_SetChannelOption(NULL, consoleChannel, "-encoding", "utf-8"); } Tcl_SetStdChannel(consoleChannel, TCL_STDIN); Tcl_RegisterChannel(NULL, consoleChannel); } if (doOut) { - ChannelData *data = (ChannelData *) ckalloc(sizeof(ChannelData)); + ChannelData *data = ckalloc(sizeof(ChannelData)); + data->info = info; data->info->refCount++; data->type = TCL_STDOUT; consoleChannel = Tcl_CreateChannel(&consoleChannelType, "console1", - (ClientData) data, TCL_WRITABLE); + data, TCL_WRITABLE); if (consoleChannel != NULL) { - Tcl_SetChannelOption(NULL, consoleChannel, - "-translation", "lf"); - Tcl_SetChannelOption(NULL, consoleChannel, - "-buffering", "none"); - Tcl_SetChannelOption(NULL, consoleChannel, - "-encoding", "utf-8"); + Tcl_SetChannelOption(NULL, consoleChannel, "-translation", "lf"); + Tcl_SetChannelOption(NULL, consoleChannel, "-buffering", "none"); + Tcl_SetChannelOption(NULL, consoleChannel, "-encoding", "utf-8"); } Tcl_SetStdChannel(consoleChannel, TCL_STDOUT); Tcl_RegisterChannel(NULL, consoleChannel); } if (doErr) { - ChannelData *data = (ChannelData *) ckalloc(sizeof(ChannelData)); + ChannelData *data = ckalloc(sizeof(ChannelData)); + data->info = info; data->info->refCount++; data->type = TCL_STDERR; consoleChannel = Tcl_CreateChannel(&consoleChannelType, "console2", - (ClientData) data, TCL_WRITABLE); + data, TCL_WRITABLE); if (consoleChannel != NULL) { - Tcl_SetChannelOption(NULL, consoleChannel, - "-translation", "lf"); - Tcl_SetChannelOption(NULL, consoleChannel, - "-buffering", "none"); - Tcl_SetChannelOption(NULL, consoleChannel, - "-encoding", "utf-8"); + Tcl_SetChannelOption(NULL, consoleChannel, "-translation", "lf"); + Tcl_SetChannelOption(NULL, consoleChannel, "-buffering", "none"); + Tcl_SetChannelOption(NULL, consoleChannel, "-encoding", "utf-8"); } Tcl_SetStdChannel(consoleChannel, TCL_STDERR); Tcl_RegisterChannel(NULL, consoleChannel); @@ -320,7 +318,7 @@ Tk_InitConsoleChannels( * Tk_CreateConsoleWindow -- * * Initialize the console. This code actually creates a new application - * and associated interpreter. This effectivly hides the implementation + * and associated interpreter. This effectively hides the implementation * from the main application. * * Results: @@ -346,9 +344,13 @@ Tk_CreateConsoleWindow( /* Init an interp with Tcl and Tk */ Tcl_Interp *consoleInterp = Tcl_CreateInterp(); if (Tcl_Init(consoleInterp) != TCL_OK) { + Tcl_Obj *result_obj = Tcl_GetObjResult(consoleInterp); + Tcl_SetObjResult(interp, result_obj); goto error; } if (Tk_Init(consoleInterp) != TCL_OK) { + Tcl_Obj *result_obj = Tcl_GetObjResult(consoleInterp); + Tcl_SetObjResult(interp, result_obj); goto error; } @@ -368,55 +370,60 @@ Tk_CreateConsoleWindow( } if (haveConsoleChannel) { - ChannelData *data = (ChannelData *)Tcl_GetChannelInstanceData(chan); + ChannelData *data = (ChannelData *) Tcl_GetChannelInstanceData(chan); info = data->info; if (info->consoleInterp) { - /* New ConsoleInfo for a new console window */ - info = (ConsoleInfo *) ckalloc(sizeof(ConsoleInfo)); + /* + * New ConsoleInfo for a new console window. + */ + + info = ckalloc(sizeof(ConsoleInfo)); info->refCount = 0; - /* Update any console channels to make use of the new console */ + /* + * Update any console channels to make use of the new console. + */ + if (Tcl_GetChannelType(chan = Tcl_GetStdChannel(TCL_STDIN)) == &consoleChannelType) { - data = (ChannelData *)Tcl_GetChannelInstanceData(chan); + data = (ChannelData *) Tcl_GetChannelInstanceData(chan); data->info->refCount--; data->info = info; data->info->refCount++; } if (Tcl_GetChannelType(chan = Tcl_GetStdChannel(TCL_STDOUT)) == &consoleChannelType) { - data = (ChannelData *)Tcl_GetChannelInstanceData(chan); + data = (ChannelData *) Tcl_GetChannelInstanceData(chan); data->info->refCount--; data->info = info; data->info->refCount++; } if (Tcl_GetChannelType(chan = Tcl_GetStdChannel(TCL_STDERR)) == &consoleChannelType) { - data = (ChannelData *)Tcl_GetChannelInstanceData(chan); + data = (ChannelData *) Tcl_GetChannelInstanceData(chan); data->info->refCount--; data->info = info; data->info->refCount++; } } } else { - info = (ConsoleInfo *) ckalloc(sizeof(ConsoleInfo)); + info = ckalloc(sizeof(ConsoleInfo)); info->refCount = 0; } info->consoleInterp = consoleInterp; info->interp = interp; - Tcl_CallWhenDeleted(consoleInterp, InterpDeleteProc, (ClientData) info); + Tcl_CallWhenDeleted(consoleInterp, InterpDeleteProc, info); info->refCount++; - Tcl_CreateThreadExitHandler(DeleteConsoleInterp, - (ClientData) consoleInterp); + Tcl_CreateThreadExitHandler(DeleteConsoleInterp, consoleInterp); /* * Add console commands to the interp */ - token = Tcl_CreateObjCommand(interp, "console", ConsoleObjCmd, - (ClientData) info, ConsoleDeleteProc); + token = Tcl_CreateObjCommand(interp, "console", ConsoleObjCmd, info, + ConsoleDeleteProc); info->refCount++; /* @@ -425,16 +432,16 @@ Tk_CreateConsoleWindow( * handler takes care of us. */ Tcl_CreateObjCommand(consoleInterp, "consoleinterp", InterpreterObjCmd, - (ClientData) info, NULL); + info, NULL); mainWindow = Tk_MainWindow(interp); if (mainWindow) { Tk_CreateEventHandler(mainWindow, StructureNotifyMask, - ConsoleEventProc, (ClientData) info); + ConsoleEventProc, info); info->refCount++; } - Tcl_Preserve((ClientData) consoleInterp); + Tcl_Preserve(consoleInterp); result = Tcl_EvalEx(consoleInterp, "source $tk_library/console.tcl", -1, TCL_EVAL_GLOBAL); if (result == TCL_ERROR) { @@ -442,22 +449,22 @@ Tk_CreateConsoleWindow( Tcl_GetReturnOptions(consoleInterp, result)); Tcl_SetObjResult(interp, Tcl_GetObjResult(consoleInterp)); } - Tcl_Release((ClientData) consoleInterp); + Tcl_Release(consoleInterp); if (result == TCL_ERROR) { Tcl_DeleteCommandFromToken(interp, token); mainWindow = Tk_MainWindow(interp); if (mainWindow) { Tk_DeleteEventHandler(mainWindow, StructureNotifyMask, - ConsoleEventProc, (ClientData) info); + ConsoleEventProc, info); if (--info->refCount <= 0) { - ckfree((char *) info); + ckfree(info); } } goto error; } return TCL_OK; - error: + error: Tcl_AddErrorInfo(interp, "\n (creating console window)"); if (!Tcl_InterpDeleted(consoleInterp)) { Tcl_DeleteInterp(consoleInterp); @@ -486,11 +493,11 @@ Tk_CreateConsoleWindow( static int ConsoleOutput( ClientData instanceData, /* Indicates which device to use. */ - CONST char *buf, /* The data buffer. */ + const char *buf, /* The data buffer. */ int toWrite, /* How many bytes to write? */ int *errorCode) /* Where to store error code. */ { - ChannelData *data = (ChannelData *)instanceData; + ChannelData *data = instanceData; ConsoleInfo *info = data->info; *errorCode = 0; @@ -509,7 +516,7 @@ ConsoleOutput( * Assumption is utf-8 Tcl_Encoding is reliably present. */ - CONST char *bytes + const char *bytes = Tcl_ExternalToUtfDString(utf8, buf, toWrite, &ds); int numBytes = Tcl_DStringLength(&ds); Tcl_Obj *cmd = Tcl_NewStringObj("tk::ConsoleOutput", -1); @@ -585,16 +592,19 @@ ConsoleClose( ClientData instanceData, /* Unused. */ Tcl_Interp *interp) /* Unused. */ { - ChannelData *data = (ChannelData *)instanceData; + ChannelData *data = instanceData; ConsoleInfo *info = data->info; if (info) { if (--info->refCount <= 0) { - /* Assuming the Tcl_Interp * fields must already be NULL */ - ckfree((char *) info); + /* + * Assuming the Tcl_Interp * fields must already be NULL. + */ + + ckfree(info); } } - ckfree((char *) data); + ckfree(data); return 0; } @@ -677,21 +687,22 @@ ConsoleObjCmd( ClientData clientData, /* Access to the console interp */ Tcl_Interp *interp, /* Current interpreter */ int objc, /* Number of arguments */ - Tcl_Obj *CONST objv[]) /* Argument objects */ + Tcl_Obj *const objv[]) /* Argument objects */ { int index, result; - static CONST char *options[] = {"eval", "hide", "show", "title", NULL}; + static const char *const options[] = { + "eval", "hide", "show", "title", NULL}; enum option {CON_EVAL, CON_HIDE, CON_SHOW, CON_TITLE}; Tcl_Obj *cmd = NULL; - ConsoleInfo *info = (ConsoleInfo *) clientData; + ConsoleInfo *info = clientData; Tcl_Interp *consoleInterp = info->consoleInterp; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "option ?arg?"); return TCL_ERROR; } - if (Tcl_GetIndexFromObj(interp, objv[1], options, "option", 0, &index) - != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[1], options, + sizeof(char *), "option", 0, &index) != TCL_OK) { return TCL_ERROR; } @@ -727,18 +738,22 @@ ConsoleObjCmd( Tcl_ListObjAppendElement(NULL, cmd, objv[2]); } break; + default: + CLANG_ASSERT(0); } Tcl_IncrRefCount(cmd); if (consoleInterp && !Tcl_InterpDeleted(consoleInterp)) { - Tcl_Preserve((ClientData) consoleInterp); + Tcl_Preserve(consoleInterp); result = Tcl_EvalObjEx(consoleInterp, cmd, TCL_EVAL_GLOBAL); Tcl_SetReturnOptions(interp, Tcl_GetReturnOptions(consoleInterp, result)); Tcl_SetObjResult(interp, Tcl_GetObjResult(consoleInterp)); - Tcl_Release((ClientData) consoleInterp); + Tcl_Release(consoleInterp); } else { - Tcl_AppendResult(interp, "no active console interp", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "no active console interp", -1)); + Tcl_SetErrorCode(interp, "TK", "CONSOLE", "NONE", NULL); result = TCL_ERROR; } Tcl_DecrRefCount(cmd); @@ -764,20 +779,20 @@ InterpreterObjCmd( ClientData clientData, /* */ Tcl_Interp *interp, /* Current interpreter */ int objc, /* Number of arguments */ - Tcl_Obj *CONST objv[]) /* Argument objects */ + Tcl_Obj *const objv[]) /* Argument objects */ { int index, result = TCL_OK; - static CONST char *options[] = {"eval", "record", NULL}; + static const char *const options[] = {"eval", "record", NULL}; enum option {OTHER_EVAL, OTHER_RECORD}; - ConsoleInfo *info = (ConsoleInfo *) clientData; + ConsoleInfo *info = clientData; Tcl_Interp *otherInterp = info->interp; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "option arg"); return TCL_ERROR; } - if (Tcl_GetIndexFromObj(interp, objv[1], options, "option", 0, &index) - != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[1], options, + sizeof(char *), "option", 0, &index) != TCL_OK) { return TCL_ERROR; } @@ -787,32 +802,38 @@ InterpreterObjCmd( } if ((otherInterp == NULL) || Tcl_InterpDeleted(otherInterp)) { - Tcl_AppendResult(interp, "no active master interp", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "no active master interp", -1)); + Tcl_SetErrorCode(interp, "TK", "CONSOLE", "NO_INTERP", NULL); return TCL_ERROR; } - Tcl_Preserve((ClientData) otherInterp); + Tcl_Preserve(otherInterp); switch ((enum option) index) { case OTHER_EVAL: result = Tcl_EvalObjEx(otherInterp, objv[2], TCL_EVAL_GLOBAL); + /* * TODO: Should exceptions be filtered here? */ + Tcl_SetReturnOptions(interp, Tcl_GetReturnOptions(otherInterp, result)); Tcl_SetObjResult(interp, Tcl_GetObjResult(otherInterp)); break; case OTHER_RECORD: Tcl_RecordAndEvalObj(otherInterp, objv[2], TCL_EVAL_GLOBAL); + /* - * By not setting result, we discard any exceptions or errors here - * and always return TCL_OK. All the caller wants is the - * interp result to display, whether that's result or error message. + * By not setting result, we discard any exceptions or errors here and + * always return TCL_OK. All the caller wants is the interp result to + * display, whether that's result or error message. */ + Tcl_SetObjResult(interp, Tcl_GetObjResult(otherInterp)); break; } - Tcl_Release((ClientData) otherInterp); + Tcl_Release(otherInterp); return result; } @@ -821,8 +842,8 @@ InterpreterObjCmd( * * DeleteConsoleInterp -- * - * Thread exit handler to destroy a console interp when the - * thread it lives in gets torn down. + * Thread exit handler to destroy a console interp when the thread it + * lives in gets torn down. * *---------------------------------------------------------------------- */ @@ -831,7 +852,8 @@ static void DeleteConsoleInterp( ClientData clientData) { - Tcl_Interp *interp = (Tcl_Interp *)clientData; + Tcl_Interp *interp = clientData; + Tcl_DeleteInterp(interp); } @@ -840,8 +862,8 @@ DeleteConsoleInterp( * * InterpDeleteProc -- * - * React when the interp in which the console is displayed is deleted - * for any reason. + * React when the interp in which the console is displayed is deleted for + * any reason. * * Results: * None. @@ -857,15 +879,14 @@ InterpDeleteProc( ClientData clientData, Tcl_Interp *interp) { - ConsoleInfo *info = (ConsoleInfo *) clientData; + ConsoleInfo *info = clientData; if (info->consoleInterp == interp) { - Tcl_DeleteThreadExitHandler(DeleteConsoleInterp, - (ClientData) info->consoleInterp); + Tcl_DeleteThreadExitHandler(DeleteConsoleInterp, info->consoleInterp); info->consoleInterp = NULL; } if (--info->refCount <= 0) { - ckfree((char *) info); + ckfree(info); } } @@ -890,13 +911,13 @@ static void ConsoleDeleteProc( ClientData clientData) { - ConsoleInfo *info = (ConsoleInfo *) clientData; + ConsoleInfo *info = clientData; if (info->consoleInterp) { Tcl_DeleteInterp(info->consoleInterp); } if (--info->refCount <= 0) { - ckfree((char *) info); + ckfree(info); } } @@ -925,7 +946,7 @@ ConsoleEventProc( XEvent *eventPtr) { if (eventPtr->type == DestroyNotify) { - ConsoleInfo *info = (ConsoleInfo *) clientData; + ConsoleInfo *info = clientData; Tcl_Interp *consoleInterp = info->consoleInterp; if (consoleInterp && !Tcl_InterpDeleted(consoleInterp)) { @@ -933,7 +954,7 @@ ConsoleEventProc( } if (--info->refCount <= 0) { - ckfree((char *) info); + ckfree(info); } } } diff --git a/generic/tkCursor.c b/generic/tkCursor.c index e5b5df5..ff66d17 100644 --- a/generic/tkCursor.c +++ b/generic/tkCursor.c @@ -23,8 +23,8 @@ */ typedef struct { - CONST char *source; /* Cursor bits. */ - CONST char *mask; /* Mask bits. */ + const char *source; /* Cursor bits. */ + const char *mask; /* Mask bits. */ int width, height; /* Dimensions of cursor (and data and * mask). */ int xHot, yHot; /* Location of cursor hot-spot. */ @@ -40,9 +40,10 @@ static void CursorInit(TkDisplay *dispPtr); static void DupCursorObjProc(Tcl_Obj *srcObjPtr, Tcl_Obj *dupObjPtr); static void FreeCursor(TkCursor *cursorPtr); +static void FreeCursorObj(Tcl_Obj *objPtr); static void FreeCursorObjProc(Tcl_Obj *objPtr); -static TkCursor * TkcGetCursor(Tcl_Interp *interp, - Tk_Window tkwin, CONST char *name); +static TkCursor * TkcGetCursor(Tcl_Interp *interp, Tk_Window tkwin, + const char *name); static TkCursor * GetCursorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr); static void InitCursorObj(Tcl_Obj *objPtr); @@ -54,7 +55,7 @@ static void InitCursorObj(Tcl_Obj *objPtr); * option is set. */ -Tcl_ObjType tkCursorObjType = { +Tcl_ObjType const tkCursorObjType = { "cursor", /* name */ FreeCursorObjProc, /* freeIntRepProc */ DupCursorObjProc, /* dupIntRepProc */ @@ -99,7 +100,7 @@ Tk_AllocCursorFromObj( if (objPtr->typePtr != &tkCursorObjType) { InitCursorObj(objPtr); } - cursorPtr = (TkCursor *) objPtr->internalRep.twoPtrValue.ptr1; + cursorPtr = objPtr->internalRep.twoPtrValue.ptr1; /* * If the object currently points to a TkCursor, see if it's the one we @@ -113,7 +114,7 @@ Tk_AllocCursorFromObj( * longer in use. Clear the reference. */ - FreeCursorObjProc(objPtr); + FreeCursorObj(objPtr); cursorPtr = NULL; } else if (Tk_Display(tkwin) == cursorPtr->display) { cursorPtr->resourceRefCount++; @@ -128,15 +129,15 @@ Tk_AllocCursorFromObj( */ if (cursorPtr != NULL) { - TkCursor *firstCursorPtr = (TkCursor *) - Tcl_GetHashValue(cursorPtr->hashPtr); - FreeCursorObjProc(objPtr); + TkCursor *firstCursorPtr = Tcl_GetHashValue(cursorPtr->hashPtr); + + FreeCursorObj(objPtr); for (cursorPtr = firstCursorPtr; cursorPtr != NULL; cursorPtr = cursorPtr->nextPtr) { if (Tk_Display(tkwin) == cursorPtr->display) { cursorPtr->resourceRefCount++; cursorPtr->objRefCount++; - objPtr->internalRep.twoPtrValue.ptr1 = (void *) cursorPtr; + objPtr->internalRep.twoPtrValue.ptr1 = cursorPtr; return cursorPtr->cursor; } } @@ -147,7 +148,7 @@ Tk_AllocCursorFromObj( */ cursorPtr = TkcGetCursor(interp, tkwin, Tcl_GetString(objPtr)); - objPtr->internalRep.twoPtrValue.ptr1 = (void *) cursorPtr; + objPtr->internalRep.twoPtrValue.ptr1 = cursorPtr; if (cursorPtr == NULL) { return NULL; } @@ -187,6 +188,7 @@ Tk_GetCursor( * details on legal syntax. */ { TkCursor *cursorPtr = TkcGetCursor(interp, tkwin, string); + if (cursorPtr == NULL) { return NULL; } @@ -223,7 +225,7 @@ static TkCursor * TkcGetCursor( Tcl_Interp *interp, /* Interpreter to use for error reporting. */ Tk_Window tkwin, /* Window in which cursor will be used. */ - CONST char *string) /* Description of cursor. See manual entry for + const char *string) /* Description of cursor. See manual entry for * details on legal syntax. */ { Tcl_HashEntry *nameHashPtr; @@ -237,9 +239,9 @@ TkcGetCursor( } nameHashPtr = Tcl_CreateHashEntry(&dispPtr->cursorNameTable, - string, &isNew); + string, &isNew); if (!isNew) { - existingCursorPtr = (TkCursor *) Tcl_GetHashValue(nameHashPtr); + existingCursorPtr = Tcl_GetHashValue(nameHashPtr); for (cursorPtr = existingCursorPtr; cursorPtr != NULL; cursorPtr = cursorPtr->nextPtr) { if (Tk_Display(tkwin) == cursorPtr->display) { @@ -271,7 +273,7 @@ TkcGetCursor( cursorPtr->hashPtr = nameHashPtr; cursorPtr->nextPtr = existingCursorPtr; cursorPtr->idHashPtr = Tcl_CreateHashEntry(&dispPtr->cursorIdTable, - (char *) cursorPtr->cursor, &isNew); + (char *) cursorPtr->cursor, &isNew); if (!isNew) { Tcl_Panic("cursor already registered in Tk_GetCursor"); } @@ -309,8 +311,8 @@ Tk_Cursor Tk_GetCursorFromData( Tcl_Interp *interp, /* Interpreter to use for error reporting. */ Tk_Window tkwin, /* Window in which cursor will be used. */ - CONST char *source, /* Bitmap data for cursor shape. */ - CONST char *mask, /* Bitmap data for cursor mask. */ + const char *source, /* Bitmap data for cursor shape. */ + const char *mask, /* Bitmap data for cursor mask. */ int width, int height, /* Dimensions of cursor. */ int xHot, int yHot, /* Location of hot-spot in cursor. */ Tk_Uid fg, /* Foreground color for cursor. */ @@ -337,9 +339,9 @@ Tk_GetCursorFromData( dataKey.bg = bg; dataKey.display = Tk_Display(tkwin); dataHashPtr = Tcl_CreateHashEntry(&dispPtr->cursorDataTable, - (char *) &dataKey, &isNew); + (char *) &dataKey, &isNew); if (!isNew) { - cursorPtr = (TkCursor *) Tcl_GetHashValue(dataHashPtr); + cursorPtr = Tcl_GetHashValue(dataHashPtr); cursorPtr->resourceRefCount++; return cursorPtr->cursor; } @@ -350,11 +352,15 @@ Tk_GetCursorFromData( */ if (TkParseColor(dataKey.display, Tk_Colormap(tkwin), fg, &fgColor) == 0) { - Tcl_AppendResult(interp, "invalid color name \"", fg, "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "invalid color name \"%s\"", fg)); + Tcl_SetErrorCode(interp, "TK", "VALUE", "CURSOR", "COLOR", NULL); goto error; } if (TkParseColor(dataKey.display, Tk_Colormap(tkwin), bg, &bgColor) == 0) { - Tcl_AppendResult(interp, "invalid color name \"", bg, "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "invalid color name \"%s\"", bg)); + Tcl_SetErrorCode(interp, "TK", "VALUE", "CURSOR", "COLOR", NULL); goto error; } @@ -370,7 +376,7 @@ Tk_GetCursorFromData( cursorPtr->hashPtr = dataHashPtr; cursorPtr->objRefCount = 0; cursorPtr->idHashPtr = Tcl_CreateHashEntry(&dispPtr->cursorIdTable, - (char *) cursorPtr->cursor, &isNew); + (char *) cursorPtr->cursor, &isNew); cursorPtr->nextPtr = NULL; if (!isNew) { @@ -405,7 +411,7 @@ Tk_GetCursorFromData( *-------------------------------------------------------------- */ -CONST char * +const char * Tk_NameOfCursor( Display *display, /* Display for which cursor was allocated. */ Tk_Cursor cursor) /* Identifier for cursor whose name is @@ -426,7 +432,7 @@ Tk_NameOfCursor( if (idHashPtr == NULL) { goto printid; } - cursorPtr = (TkCursor *) Tcl_GetHashValue(idHashPtr); + cursorPtr = Tcl_GetHashValue(idHashPtr); if (cursorPtr->otherTable != &dispPtr->cursorNameTable) { goto printid; } @@ -463,7 +469,7 @@ FreeCursor( } Tcl_DeleteHashEntry(cursorPtr->idHashPtr); - prevPtr = (TkCursor *) Tcl_GetHashValue(cursorPtr->hashPtr); + prevPtr = Tcl_GetHashValue(cursorPtr->hashPtr); if (prevPtr == cursorPtr) { if (cursorPtr->nextPtr == NULL) { Tcl_DeleteHashEntry(cursorPtr->hashPtr); @@ -478,7 +484,7 @@ FreeCursor( } TkpFreeCursor(cursorPtr); if (cursorPtr->objRefCount == 0) { - ckfree((char *) cursorPtr); + ckfree(cursorPtr); } } @@ -516,7 +522,7 @@ Tk_FreeCursor( if (idHashPtr == NULL) { Tcl_Panic("Tk_FreeCursor received unknown cursor argument"); } - FreeCursor((TkCursor *) Tcl_GetHashValue(idHashPtr)); + FreeCursor(Tcl_GetHashValue(idHashPtr)); } /* @@ -547,13 +553,13 @@ Tk_FreeCursorFromObj( Tcl_Obj *objPtr) /* The Tcl_Obj * to be freed. */ { FreeCursor(GetCursorFromObj(tkwin, objPtr)); - FreeCursorObjProc(objPtr); + FreeCursorObj(objPtr); } /* *--------------------------------------------------------------------------- * - * FreeCursorFromObjProc -- + * FreeCursorObjProc, FreeCursorObj -- * * This proc is called to release an object reference to a cursor. * Called when the object's internal rep is released or when the cached @@ -573,13 +579,21 @@ static void FreeCursorObjProc( Tcl_Obj *objPtr) /* The object we are releasing. */ { - TkCursor *cursorPtr = (TkCursor *) objPtr->internalRep.twoPtrValue.ptr1; + FreeCursorObj(objPtr); + objPtr->typePtr = NULL; +} + +static void +FreeCursorObj( + Tcl_Obj *objPtr) /* The object we are releasing. */ +{ + TkCursor *cursorPtr = objPtr->internalRep.twoPtrValue.ptr1; if (cursorPtr != NULL) { cursorPtr->objRefCount--; if ((cursorPtr->objRefCount == 0) && (cursorPtr->resourceRefCount == 0)) { - ckfree((char *) cursorPtr); + ckfree(cursorPtr); } objPtr->internalRep.twoPtrValue.ptr1 = NULL; } @@ -608,10 +622,10 @@ DupCursorObjProc( Tcl_Obj *srcObjPtr, /* The object we are copying from. */ Tcl_Obj *dupObjPtr) /* The object we are copying to. */ { - TkCursor *cursorPtr = (TkCursor *) srcObjPtr->internalRep.twoPtrValue.ptr1; + TkCursor *cursorPtr = srcObjPtr->internalRep.twoPtrValue.ptr1; dupObjPtr->typePtr = srcObjPtr->typePtr; - dupObjPtr->internalRep.twoPtrValue.ptr1 = (void *) cursorPtr; + dupObjPtr->internalRep.twoPtrValue.ptr1 = cursorPtr; if (cursorPtr != NULL) { cursorPtr->objRefCount++; @@ -693,7 +707,7 @@ GetCursorFromObj( * cached is the one that is needed. */ - cursorPtr = (TkCursor *) objPtr->internalRep.twoPtrValue.ptr1; + cursorPtr = objPtr->internalRep.twoPtrValue.ptr1; if ((cursorPtr != NULL) && (Tk_Display(tkwin) == cursorPtr->display)) { return cursorPtr; } @@ -708,11 +722,11 @@ GetCursorFromObj( if (hashPtr == NULL) { goto error; } - for (cursorPtr = (TkCursor *) Tcl_GetHashValue(hashPtr); + for (cursorPtr = Tcl_GetHashValue(hashPtr); cursorPtr != NULL; cursorPtr = cursorPtr->nextPtr) { if (Tk_Display(tkwin) == cursorPtr->display) { - FreeCursorObjProc(objPtr); - objPtr->internalRep.twoPtrValue.ptr1 = (void *) cursorPtr; + FreeCursorObj(objPtr); + objPtr->internalRep.twoPtrValue.ptr1 = cursorPtr; cursorPtr->objRefCount++; return cursorPtr; } @@ -757,7 +771,7 @@ InitCursorObj( Tcl_GetString(objPtr); typePtr = objPtr->typePtr; if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) { - (*typePtr->freeIntRepProc)(objPtr); + typePtr->freeIntRepProc(objPtr); } objPtr->typePtr = &tkCursorObjType; objPtr->internalRep.twoPtrValue.ptr1 = NULL; @@ -830,7 +844,7 @@ Tcl_Obj * TkDebugCursor( Tk_Window tkwin, /* The window in which the cursor will be used * (not currently used). */ - char *name) /* Name of the desired color. */ + const char *name) /* Name of the desired color. */ { TkCursor *cursorPtr; Tcl_HashEntry *hashPtr; @@ -843,7 +857,7 @@ TkDebugCursor( resultPtr = Tcl_NewObj(); hashPtr = Tcl_FindHashEntry(&dispPtr->cursorNameTable, name); if (hashPtr != NULL) { - cursorPtr = (TkCursor *) Tcl_GetHashValue(hashPtr); + cursorPtr = Tcl_GetHashValue(hashPtr); if (cursorPtr == NULL) { Tcl_Panic("TkDebugCursor found empty hash table entry"); } diff --git a/generic/tkDecls.h b/generic/tkDecls.h index 00a3dde..64c32cd 100644 --- a/generic/tkDecls.h +++ b/generic/tkDecls.h @@ -33,1679 +33,859 @@ extern "C" { * Exported function declarations: */ -#ifndef Tk_MainLoop_TCL_DECLARED -#define Tk_MainLoop_TCL_DECLARED /* 0 */ EXTERN void Tk_MainLoop(void); -#endif -#ifndef Tk_3DBorderColor_TCL_DECLARED -#define Tk_3DBorderColor_TCL_DECLARED /* 1 */ EXTERN XColor * Tk_3DBorderColor(Tk_3DBorder border); -#endif -#ifndef Tk_3DBorderGC_TCL_DECLARED -#define Tk_3DBorderGC_TCL_DECLARED /* 2 */ EXTERN GC Tk_3DBorderGC(Tk_Window tkwin, Tk_3DBorder border, int which); -#endif -#ifndef Tk_3DHorizontalBevel_TCL_DECLARED -#define Tk_3DHorizontalBevel_TCL_DECLARED /* 3 */ EXTERN void Tk_3DHorizontalBevel(Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, int x, int y, int width, int height, int leftIn, int rightIn, int topBevel, int relief); -#endif -#ifndef Tk_3DVerticalBevel_TCL_DECLARED -#define Tk_3DVerticalBevel_TCL_DECLARED /* 4 */ EXTERN void Tk_3DVerticalBevel(Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, int x, int y, int width, int height, int leftBevel, int relief); -#endif -#ifndef Tk_AddOption_TCL_DECLARED -#define Tk_AddOption_TCL_DECLARED /* 5 */ -EXTERN void Tk_AddOption(Tk_Window tkwin, CONST char *name, - CONST char *value, int priority); -#endif -#ifndef Tk_BindEvent_TCL_DECLARED -#define Tk_BindEvent_TCL_DECLARED +EXTERN void Tk_AddOption(Tk_Window tkwin, const char *name, + const char *value, int priority); /* 6 */ EXTERN void Tk_BindEvent(Tk_BindingTable bindingTable, XEvent *eventPtr, Tk_Window tkwin, int numObjects, ClientData *objectPtr); -#endif -#ifndef Tk_CanvasDrawableCoords_TCL_DECLARED -#define Tk_CanvasDrawableCoords_TCL_DECLARED /* 7 */ EXTERN void Tk_CanvasDrawableCoords(Tk_Canvas canvas, double x, double y, short *drawableXPtr, short *drawableYPtr); -#endif -#ifndef Tk_CanvasEventuallyRedraw_TCL_DECLARED -#define Tk_CanvasEventuallyRedraw_TCL_DECLARED /* 8 */ EXTERN void Tk_CanvasEventuallyRedraw(Tk_Canvas canvas, int x1, int y1, int x2, int y2); -#endif -#ifndef Tk_CanvasGetCoord_TCL_DECLARED -#define Tk_CanvasGetCoord_TCL_DECLARED /* 9 */ EXTERN int Tk_CanvasGetCoord(Tcl_Interp *interp, - Tk_Canvas canvas, CONST char *str, + Tk_Canvas canvas, const char *str, double *doublePtr); -#endif -#ifndef Tk_CanvasGetTextInfo_TCL_DECLARED -#define Tk_CanvasGetTextInfo_TCL_DECLARED /* 10 */ EXTERN Tk_CanvasTextInfo * Tk_CanvasGetTextInfo(Tk_Canvas canvas); -#endif -#ifndef Tk_CanvasPsBitmap_TCL_DECLARED -#define Tk_CanvasPsBitmap_TCL_DECLARED /* 11 */ EXTERN int Tk_CanvasPsBitmap(Tcl_Interp *interp, Tk_Canvas canvas, Pixmap bitmap, int x, int y, int width, int height); -#endif -#ifndef Tk_CanvasPsColor_TCL_DECLARED -#define Tk_CanvasPsColor_TCL_DECLARED /* 12 */ EXTERN int Tk_CanvasPsColor(Tcl_Interp *interp, Tk_Canvas canvas, XColor *colorPtr); -#endif -#ifndef Tk_CanvasPsFont_TCL_DECLARED -#define Tk_CanvasPsFont_TCL_DECLARED /* 13 */ EXTERN int Tk_CanvasPsFont(Tcl_Interp *interp, Tk_Canvas canvas, Tk_Font font); -#endif -#ifndef Tk_CanvasPsPath_TCL_DECLARED -#define Tk_CanvasPsPath_TCL_DECLARED /* 14 */ EXTERN void Tk_CanvasPsPath(Tcl_Interp *interp, Tk_Canvas canvas, double *coordPtr, int numPoints); -#endif -#ifndef Tk_CanvasPsStipple_TCL_DECLARED -#define Tk_CanvasPsStipple_TCL_DECLARED /* 15 */ EXTERN int Tk_CanvasPsStipple(Tcl_Interp *interp, Tk_Canvas canvas, Pixmap bitmap); -#endif -#ifndef Tk_CanvasPsY_TCL_DECLARED -#define Tk_CanvasPsY_TCL_DECLARED /* 16 */ EXTERN double Tk_CanvasPsY(Tk_Canvas canvas, double y); -#endif -#ifndef Tk_CanvasSetStippleOrigin_TCL_DECLARED -#define Tk_CanvasSetStippleOrigin_TCL_DECLARED /* 17 */ EXTERN void Tk_CanvasSetStippleOrigin(Tk_Canvas canvas, GC gc); -#endif -#ifndef Tk_CanvasTagsParseProc_TCL_DECLARED -#define Tk_CanvasTagsParseProc_TCL_DECLARED /* 18 */ EXTERN int Tk_CanvasTagsParseProc(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, - CONST char *value, char *widgRec, int offset); -#endif -#ifndef Tk_CanvasTagsPrintProc_TCL_DECLARED -#define Tk_CanvasTagsPrintProc_TCL_DECLARED + const char *value, char *widgRec, int offset); /* 19 */ -EXTERN char * Tk_CanvasTagsPrintProc(ClientData clientData, +EXTERN CONST86 char * Tk_CanvasTagsPrintProc(ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); -#endif -#ifndef Tk_CanvasTkwin_TCL_DECLARED -#define Tk_CanvasTkwin_TCL_DECLARED /* 20 */ EXTERN Tk_Window Tk_CanvasTkwin(Tk_Canvas canvas); -#endif -#ifndef Tk_CanvasWindowCoords_TCL_DECLARED -#define Tk_CanvasWindowCoords_TCL_DECLARED /* 21 */ EXTERN void Tk_CanvasWindowCoords(Tk_Canvas canvas, double x, double y, short *screenXPtr, short *screenYPtr); -#endif -#ifndef Tk_ChangeWindowAttributes_TCL_DECLARED -#define Tk_ChangeWindowAttributes_TCL_DECLARED /* 22 */ EXTERN void Tk_ChangeWindowAttributes(Tk_Window tkwin, unsigned long valueMask, XSetWindowAttributes *attsPtr); -#endif -#ifndef Tk_CharBbox_TCL_DECLARED -#define Tk_CharBbox_TCL_DECLARED /* 23 */ EXTERN int Tk_CharBbox(Tk_TextLayout layout, int index, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr); -#endif -#ifndef Tk_ClearSelection_TCL_DECLARED -#define Tk_ClearSelection_TCL_DECLARED /* 24 */ EXTERN void Tk_ClearSelection(Tk_Window tkwin, Atom selection); -#endif -#ifndef Tk_ClipboardAppend_TCL_DECLARED -#define Tk_ClipboardAppend_TCL_DECLARED /* 25 */ EXTERN int Tk_ClipboardAppend(Tcl_Interp *interp, Tk_Window tkwin, Atom target, Atom format, - char *buffer); -#endif -#ifndef Tk_ClipboardClear_TCL_DECLARED -#define Tk_ClipboardClear_TCL_DECLARED + const char *buffer); /* 26 */ EXTERN int Tk_ClipboardClear(Tcl_Interp *interp, Tk_Window tkwin); -#endif -#ifndef Tk_ConfigureInfo_TCL_DECLARED -#define Tk_ConfigureInfo_TCL_DECLARED /* 27 */ EXTERN int Tk_ConfigureInfo(Tcl_Interp *interp, Tk_Window tkwin, - Tk_ConfigSpec *specs, char *widgRec, - CONST char *argvName, int flags); -#endif -#ifndef Tk_ConfigureValue_TCL_DECLARED -#define Tk_ConfigureValue_TCL_DECLARED + const Tk_ConfigSpec *specs, char *widgRec, + const char *argvName, int flags); /* 28 */ EXTERN int Tk_ConfigureValue(Tcl_Interp *interp, - Tk_Window tkwin, Tk_ConfigSpec *specs, - char *widgRec, CONST char *argvName, + Tk_Window tkwin, const Tk_ConfigSpec *specs, + char *widgRec, const char *argvName, int flags); -#endif -#ifndef Tk_ConfigureWidget_TCL_DECLARED -#define Tk_ConfigureWidget_TCL_DECLARED /* 29 */ EXTERN int Tk_ConfigureWidget(Tcl_Interp *interp, - Tk_Window tkwin, Tk_ConfigSpec *specs, + Tk_Window tkwin, const Tk_ConfigSpec *specs, int argc, CONST84 char **argv, char *widgRec, int flags); -#endif -#ifndef Tk_ConfigureWindow_TCL_DECLARED -#define Tk_ConfigureWindow_TCL_DECLARED /* 30 */ EXTERN void Tk_ConfigureWindow(Tk_Window tkwin, unsigned int valueMask, XWindowChanges *valuePtr); -#endif -#ifndef Tk_ComputeTextLayout_TCL_DECLARED -#define Tk_ComputeTextLayout_TCL_DECLARED /* 31 */ -EXTERN Tk_TextLayout Tk_ComputeTextLayout(Tk_Font font, CONST char *str, +EXTERN Tk_TextLayout Tk_ComputeTextLayout(Tk_Font font, const char *str, int numChars, int wrapLength, Tk_Justify justify, int flags, int *widthPtr, int *heightPtr); -#endif -#ifndef Tk_CoordsToWindow_TCL_DECLARED -#define Tk_CoordsToWindow_TCL_DECLARED /* 32 */ EXTERN Tk_Window Tk_CoordsToWindow(int rootX, int rootY, Tk_Window tkwin); -#endif -#ifndef Tk_CreateBinding_TCL_DECLARED -#define Tk_CreateBinding_TCL_DECLARED /* 33 */ EXTERN unsigned long Tk_CreateBinding(Tcl_Interp *interp, Tk_BindingTable bindingTable, - ClientData object, CONST char *eventStr, - CONST char *command, int append); -#endif -#ifndef Tk_CreateBindingTable_TCL_DECLARED -#define Tk_CreateBindingTable_TCL_DECLARED + ClientData object, const char *eventStr, + const char *script, int append); /* 34 */ EXTERN Tk_BindingTable Tk_CreateBindingTable(Tcl_Interp *interp); -#endif -#ifndef Tk_CreateErrorHandler_TCL_DECLARED -#define Tk_CreateErrorHandler_TCL_DECLARED /* 35 */ EXTERN Tk_ErrorHandler Tk_CreateErrorHandler(Display *display, int errNum, int request, int minorCode, Tk_ErrorProc *errorProc, ClientData clientData); -#endif -#ifndef Tk_CreateEventHandler_TCL_DECLARED -#define Tk_CreateEventHandler_TCL_DECLARED /* 36 */ EXTERN void Tk_CreateEventHandler(Tk_Window token, unsigned long mask, Tk_EventProc *proc, ClientData clientData); -#endif -#ifndef Tk_CreateGenericHandler_TCL_DECLARED -#define Tk_CreateGenericHandler_TCL_DECLARED /* 37 */ EXTERN void Tk_CreateGenericHandler(Tk_GenericProc *proc, ClientData clientData); -#endif -#ifndef Tk_CreateImageType_TCL_DECLARED -#define Tk_CreateImageType_TCL_DECLARED /* 38 */ -EXTERN void Tk_CreateImageType(Tk_ImageType *typePtr); -#endif -#ifndef Tk_CreateItemType_TCL_DECLARED -#define Tk_CreateItemType_TCL_DECLARED +EXTERN void Tk_CreateImageType(const Tk_ImageType *typePtr); /* 39 */ EXTERN void Tk_CreateItemType(Tk_ItemType *typePtr); -#endif -#ifndef Tk_CreatePhotoImageFormat_TCL_DECLARED -#define Tk_CreatePhotoImageFormat_TCL_DECLARED /* 40 */ EXTERN void Tk_CreatePhotoImageFormat( - Tk_PhotoImageFormat *formatPtr); -#endif -#ifndef Tk_CreateSelHandler_TCL_DECLARED -#define Tk_CreateSelHandler_TCL_DECLARED + const Tk_PhotoImageFormat *formatPtr); /* 41 */ EXTERN void Tk_CreateSelHandler(Tk_Window tkwin, Atom selection, Atom target, Tk_SelectionProc *proc, ClientData clientData, Atom format); -#endif -#ifndef Tk_CreateWindow_TCL_DECLARED -#define Tk_CreateWindow_TCL_DECLARED /* 42 */ EXTERN Tk_Window Tk_CreateWindow(Tcl_Interp *interp, Tk_Window parent, - CONST char *name, CONST char *screenName); -#endif -#ifndef Tk_CreateWindowFromPath_TCL_DECLARED -#define Tk_CreateWindowFromPath_TCL_DECLARED + const char *name, const char *screenName); /* 43 */ EXTERN Tk_Window Tk_CreateWindowFromPath(Tcl_Interp *interp, - Tk_Window tkwin, CONST char *pathName, - CONST char *screenName); -#endif -#ifndef Tk_DefineBitmap_TCL_DECLARED -#define Tk_DefineBitmap_TCL_DECLARED + Tk_Window tkwin, const char *pathName, + const char *screenName); /* 44 */ -EXTERN int Tk_DefineBitmap(Tcl_Interp *interp, CONST char *name, - CONST char *source, int width, int height); -#endif -#ifndef Tk_DefineCursor_TCL_DECLARED -#define Tk_DefineCursor_TCL_DECLARED +EXTERN int Tk_DefineBitmap(Tcl_Interp *interp, const char *name, + const void *source, int width, int height); /* 45 */ EXTERN void Tk_DefineCursor(Tk_Window window, Tk_Cursor cursor); -#endif -#ifndef Tk_DeleteAllBindings_TCL_DECLARED -#define Tk_DeleteAllBindings_TCL_DECLARED /* 46 */ EXTERN void Tk_DeleteAllBindings(Tk_BindingTable bindingTable, ClientData object); -#endif -#ifndef Tk_DeleteBinding_TCL_DECLARED -#define Tk_DeleteBinding_TCL_DECLARED /* 47 */ EXTERN int Tk_DeleteBinding(Tcl_Interp *interp, Tk_BindingTable bindingTable, - ClientData object, CONST char *eventStr); -#endif -#ifndef Tk_DeleteBindingTable_TCL_DECLARED -#define Tk_DeleteBindingTable_TCL_DECLARED + ClientData object, const char *eventStr); /* 48 */ EXTERN void Tk_DeleteBindingTable(Tk_BindingTable bindingTable); -#endif -#ifndef Tk_DeleteErrorHandler_TCL_DECLARED -#define Tk_DeleteErrorHandler_TCL_DECLARED /* 49 */ EXTERN void Tk_DeleteErrorHandler(Tk_ErrorHandler handler); -#endif -#ifndef Tk_DeleteEventHandler_TCL_DECLARED -#define Tk_DeleteEventHandler_TCL_DECLARED /* 50 */ EXTERN void Tk_DeleteEventHandler(Tk_Window token, unsigned long mask, Tk_EventProc *proc, ClientData clientData); -#endif -#ifndef Tk_DeleteGenericHandler_TCL_DECLARED -#define Tk_DeleteGenericHandler_TCL_DECLARED /* 51 */ EXTERN void Tk_DeleteGenericHandler(Tk_GenericProc *proc, ClientData clientData); -#endif -#ifndef Tk_DeleteImage_TCL_DECLARED -#define Tk_DeleteImage_TCL_DECLARED /* 52 */ -EXTERN void Tk_DeleteImage(Tcl_Interp *interp, CONST char *name); -#endif -#ifndef Tk_DeleteSelHandler_TCL_DECLARED -#define Tk_DeleteSelHandler_TCL_DECLARED +EXTERN void Tk_DeleteImage(Tcl_Interp *interp, const char *name); /* 53 */ EXTERN void Tk_DeleteSelHandler(Tk_Window tkwin, Atom selection, Atom target); -#endif -#ifndef Tk_DestroyWindow_TCL_DECLARED -#define Tk_DestroyWindow_TCL_DECLARED /* 54 */ EXTERN void Tk_DestroyWindow(Tk_Window tkwin); -#endif -#ifndef Tk_DisplayName_TCL_DECLARED -#define Tk_DisplayName_TCL_DECLARED /* 55 */ EXTERN CONST84_RETURN char * Tk_DisplayName(Tk_Window tkwin); -#endif -#ifndef Tk_DistanceToTextLayout_TCL_DECLARED -#define Tk_DistanceToTextLayout_TCL_DECLARED /* 56 */ EXTERN int Tk_DistanceToTextLayout(Tk_TextLayout layout, int x, int y); -#endif -#ifndef Tk_Draw3DPolygon_TCL_DECLARED -#define Tk_Draw3DPolygon_TCL_DECLARED /* 57 */ EXTERN void Tk_Draw3DPolygon(Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, XPoint *pointPtr, int numPoints, int borderWidth, int leftRelief); -#endif -#ifndef Tk_Draw3DRectangle_TCL_DECLARED -#define Tk_Draw3DRectangle_TCL_DECLARED /* 58 */ EXTERN void Tk_Draw3DRectangle(Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, int x, int y, int width, int height, int borderWidth, int relief); -#endif -#ifndef Tk_DrawChars_TCL_DECLARED -#define Tk_DrawChars_TCL_DECLARED /* 59 */ EXTERN void Tk_DrawChars(Display *display, Drawable drawable, - GC gc, Tk_Font tkfont, CONST char *source, + GC gc, Tk_Font tkfont, const char *source, int numBytes, int x, int y); -#endif -#ifndef Tk_DrawFocusHighlight_TCL_DECLARED -#define Tk_DrawFocusHighlight_TCL_DECLARED /* 60 */ EXTERN void Tk_DrawFocusHighlight(Tk_Window tkwin, GC gc, int width, Drawable drawable); -#endif -#ifndef Tk_DrawTextLayout_TCL_DECLARED -#define Tk_DrawTextLayout_TCL_DECLARED /* 61 */ EXTERN void Tk_DrawTextLayout(Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, int firstChar, int lastChar); -#endif -#ifndef Tk_Fill3DPolygon_TCL_DECLARED -#define Tk_Fill3DPolygon_TCL_DECLARED /* 62 */ EXTERN void Tk_Fill3DPolygon(Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, XPoint *pointPtr, int numPoints, int borderWidth, int leftRelief); -#endif -#ifndef Tk_Fill3DRectangle_TCL_DECLARED -#define Tk_Fill3DRectangle_TCL_DECLARED /* 63 */ EXTERN void Tk_Fill3DRectangle(Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, int x, int y, int width, int height, int borderWidth, int relief); -#endif -#ifndef Tk_FindPhoto_TCL_DECLARED -#define Tk_FindPhoto_TCL_DECLARED /* 64 */ EXTERN Tk_PhotoHandle Tk_FindPhoto(Tcl_Interp *interp, - CONST char *imageName); -#endif -#ifndef Tk_FontId_TCL_DECLARED -#define Tk_FontId_TCL_DECLARED + const char *imageName); /* 65 */ EXTERN Font Tk_FontId(Tk_Font font); -#endif -#ifndef Tk_Free3DBorder_TCL_DECLARED -#define Tk_Free3DBorder_TCL_DECLARED /* 66 */ EXTERN void Tk_Free3DBorder(Tk_3DBorder border); -#endif -#ifndef Tk_FreeBitmap_TCL_DECLARED -#define Tk_FreeBitmap_TCL_DECLARED /* 67 */ EXTERN void Tk_FreeBitmap(Display *display, Pixmap bitmap); -#endif -#ifndef Tk_FreeColor_TCL_DECLARED -#define Tk_FreeColor_TCL_DECLARED /* 68 */ EXTERN void Tk_FreeColor(XColor *colorPtr); -#endif -#ifndef Tk_FreeColormap_TCL_DECLARED -#define Tk_FreeColormap_TCL_DECLARED /* 69 */ EXTERN void Tk_FreeColormap(Display *display, Colormap colormap); -#endif -#ifndef Tk_FreeCursor_TCL_DECLARED -#define Tk_FreeCursor_TCL_DECLARED /* 70 */ EXTERN void Tk_FreeCursor(Display *display, Tk_Cursor cursor); -#endif -#ifndef Tk_FreeFont_TCL_DECLARED -#define Tk_FreeFont_TCL_DECLARED /* 71 */ EXTERN void Tk_FreeFont(Tk_Font f); -#endif -#ifndef Tk_FreeGC_TCL_DECLARED -#define Tk_FreeGC_TCL_DECLARED /* 72 */ EXTERN void Tk_FreeGC(Display *display, GC gc); -#endif -#ifndef Tk_FreeImage_TCL_DECLARED -#define Tk_FreeImage_TCL_DECLARED /* 73 */ EXTERN void Tk_FreeImage(Tk_Image image); -#endif -#ifndef Tk_FreeOptions_TCL_DECLARED -#define Tk_FreeOptions_TCL_DECLARED /* 74 */ -EXTERN void Tk_FreeOptions(Tk_ConfigSpec *specs, char *widgRec, - Display *display, int needFlags); -#endif -#ifndef Tk_FreePixmap_TCL_DECLARED -#define Tk_FreePixmap_TCL_DECLARED +EXTERN void Tk_FreeOptions(const Tk_ConfigSpec *specs, + char *widgRec, Display *display, + int needFlags); /* 75 */ EXTERN void Tk_FreePixmap(Display *display, Pixmap pixmap); -#endif -#ifndef Tk_FreeTextLayout_TCL_DECLARED -#define Tk_FreeTextLayout_TCL_DECLARED /* 76 */ EXTERN void Tk_FreeTextLayout(Tk_TextLayout textLayout); -#endif -#ifndef Tk_FreeXId_TCL_DECLARED -#define Tk_FreeXId_TCL_DECLARED /* 77 */ EXTERN void Tk_FreeXId(Display *display, XID xid); -#endif -#ifndef Tk_GCForColor_TCL_DECLARED -#define Tk_GCForColor_TCL_DECLARED /* 78 */ EXTERN GC Tk_GCForColor(XColor *colorPtr, Drawable drawable); -#endif -#ifndef Tk_GeometryRequest_TCL_DECLARED -#define Tk_GeometryRequest_TCL_DECLARED /* 79 */ EXTERN void Tk_GeometryRequest(Tk_Window tkwin, int reqWidth, int reqHeight); -#endif -#ifndef Tk_Get3DBorder_TCL_DECLARED -#define Tk_Get3DBorder_TCL_DECLARED /* 80 */ EXTERN Tk_3DBorder Tk_Get3DBorder(Tcl_Interp *interp, Tk_Window tkwin, Tk_Uid colorName); -#endif -#ifndef Tk_GetAllBindings_TCL_DECLARED -#define Tk_GetAllBindings_TCL_DECLARED /* 81 */ EXTERN void Tk_GetAllBindings(Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object); -#endif -#ifndef Tk_GetAnchor_TCL_DECLARED -#define Tk_GetAnchor_TCL_DECLARED /* 82 */ -EXTERN int Tk_GetAnchor(Tcl_Interp *interp, CONST char *str, +EXTERN int Tk_GetAnchor(Tcl_Interp *interp, const char *str, Tk_Anchor *anchorPtr); -#endif -#ifndef Tk_GetAtomName_TCL_DECLARED -#define Tk_GetAtomName_TCL_DECLARED /* 83 */ EXTERN CONST84_RETURN char * Tk_GetAtomName(Tk_Window tkwin, Atom atom); -#endif -#ifndef Tk_GetBinding_TCL_DECLARED -#define Tk_GetBinding_TCL_DECLARED /* 84 */ EXTERN CONST84_RETURN char * Tk_GetBinding(Tcl_Interp *interp, Tk_BindingTable bindingTable, - ClientData object, CONST char *eventStr); -#endif -#ifndef Tk_GetBitmap_TCL_DECLARED -#define Tk_GetBitmap_TCL_DECLARED + ClientData object, const char *eventStr); /* 85 */ EXTERN Pixmap Tk_GetBitmap(Tcl_Interp *interp, Tk_Window tkwin, - CONST char *str); -#endif -#ifndef Tk_GetBitmapFromData_TCL_DECLARED -#define Tk_GetBitmapFromData_TCL_DECLARED + const char *str); /* 86 */ EXTERN Pixmap Tk_GetBitmapFromData(Tcl_Interp *interp, - Tk_Window tkwin, CONST char *source, + Tk_Window tkwin, const void *source, int width, int height); -#endif -#ifndef Tk_GetCapStyle_TCL_DECLARED -#define Tk_GetCapStyle_TCL_DECLARED /* 87 */ -EXTERN int Tk_GetCapStyle(Tcl_Interp *interp, CONST char *str, +EXTERN int Tk_GetCapStyle(Tcl_Interp *interp, const char *str, int *capPtr); -#endif -#ifndef Tk_GetColor_TCL_DECLARED -#define Tk_GetColor_TCL_DECLARED /* 88 */ EXTERN XColor * Tk_GetColor(Tcl_Interp *interp, Tk_Window tkwin, Tk_Uid name); -#endif -#ifndef Tk_GetColorByValue_TCL_DECLARED -#define Tk_GetColorByValue_TCL_DECLARED /* 89 */ EXTERN XColor * Tk_GetColorByValue(Tk_Window tkwin, XColor *colorPtr); -#endif -#ifndef Tk_GetColormap_TCL_DECLARED -#define Tk_GetColormap_TCL_DECLARED /* 90 */ EXTERN Colormap Tk_GetColormap(Tcl_Interp *interp, Tk_Window tkwin, - CONST char *str); -#endif -#ifndef Tk_GetCursor_TCL_DECLARED -#define Tk_GetCursor_TCL_DECLARED + const char *str); /* 91 */ EXTERN Tk_Cursor Tk_GetCursor(Tcl_Interp *interp, Tk_Window tkwin, Tk_Uid str); -#endif -#ifndef Tk_GetCursorFromData_TCL_DECLARED -#define Tk_GetCursorFromData_TCL_DECLARED /* 92 */ EXTERN Tk_Cursor Tk_GetCursorFromData(Tcl_Interp *interp, - Tk_Window tkwin, CONST char *source, - CONST char *mask, int width, int height, + Tk_Window tkwin, const char *source, + const char *mask, int width, int height, int xHot, int yHot, Tk_Uid fg, Tk_Uid bg); -#endif -#ifndef Tk_GetFont_TCL_DECLARED -#define Tk_GetFont_TCL_DECLARED /* 93 */ EXTERN Tk_Font Tk_GetFont(Tcl_Interp *interp, Tk_Window tkwin, - CONST char *str); -#endif -#ifndef Tk_GetFontFromObj_TCL_DECLARED -#define Tk_GetFontFromObj_TCL_DECLARED + const char *str); /* 94 */ EXTERN Tk_Font Tk_GetFontFromObj(Tk_Window tkwin, Tcl_Obj *objPtr); -#endif -#ifndef Tk_GetFontMetrics_TCL_DECLARED -#define Tk_GetFontMetrics_TCL_DECLARED /* 95 */ EXTERN void Tk_GetFontMetrics(Tk_Font font, Tk_FontMetrics *fmPtr); -#endif -#ifndef Tk_GetGC_TCL_DECLARED -#define Tk_GetGC_TCL_DECLARED /* 96 */ EXTERN GC Tk_GetGC(Tk_Window tkwin, unsigned long valueMask, XGCValues *valuePtr); -#endif -#ifndef Tk_GetImage_TCL_DECLARED -#define Tk_GetImage_TCL_DECLARED /* 97 */ EXTERN Tk_Image Tk_GetImage(Tcl_Interp *interp, Tk_Window tkwin, - CONST char *name, + const char *name, Tk_ImageChangedProc *changeProc, ClientData clientData); -#endif -#ifndef Tk_GetImageMasterData_TCL_DECLARED -#define Tk_GetImageMasterData_TCL_DECLARED /* 98 */ EXTERN ClientData Tk_GetImageMasterData(Tcl_Interp *interp, - CONST char *name, Tk_ImageType **typePtrPtr); -#endif -#ifndef Tk_GetItemTypes_TCL_DECLARED -#define Tk_GetItemTypes_TCL_DECLARED + const char *name, + CONST86 Tk_ImageType **typePtrPtr); /* 99 */ EXTERN Tk_ItemType * Tk_GetItemTypes(void); -#endif -#ifndef Tk_GetJoinStyle_TCL_DECLARED -#define Tk_GetJoinStyle_TCL_DECLARED /* 100 */ -EXTERN int Tk_GetJoinStyle(Tcl_Interp *interp, CONST char *str, +EXTERN int Tk_GetJoinStyle(Tcl_Interp *interp, const char *str, int *joinPtr); -#endif -#ifndef Tk_GetJustify_TCL_DECLARED -#define Tk_GetJustify_TCL_DECLARED /* 101 */ -EXTERN int Tk_GetJustify(Tcl_Interp *interp, CONST char *str, +EXTERN int Tk_GetJustify(Tcl_Interp *interp, const char *str, Tk_Justify *justifyPtr); -#endif -#ifndef Tk_GetNumMainWindows_TCL_DECLARED -#define Tk_GetNumMainWindows_TCL_DECLARED /* 102 */ EXTERN int Tk_GetNumMainWindows(void); -#endif -#ifndef Tk_GetOption_TCL_DECLARED -#define Tk_GetOption_TCL_DECLARED /* 103 */ -EXTERN Tk_Uid Tk_GetOption(Tk_Window tkwin, CONST char *name, - CONST char *className); -#endif -#ifndef Tk_GetPixels_TCL_DECLARED -#define Tk_GetPixels_TCL_DECLARED +EXTERN Tk_Uid Tk_GetOption(Tk_Window tkwin, const char *name, + const char *className); /* 104 */ EXTERN int Tk_GetPixels(Tcl_Interp *interp, Tk_Window tkwin, - CONST char *str, int *intPtr); -#endif -#ifndef Tk_GetPixmap_TCL_DECLARED -#define Tk_GetPixmap_TCL_DECLARED + const char *str, int *intPtr); /* 105 */ EXTERN Pixmap Tk_GetPixmap(Display *display, Drawable d, int width, int height, int depth); -#endif -#ifndef Tk_GetRelief_TCL_DECLARED -#define Tk_GetRelief_TCL_DECLARED /* 106 */ -EXTERN int Tk_GetRelief(Tcl_Interp *interp, CONST char *name, +EXTERN int Tk_GetRelief(Tcl_Interp *interp, const char *name, int *reliefPtr); -#endif -#ifndef Tk_GetRootCoords_TCL_DECLARED -#define Tk_GetRootCoords_TCL_DECLARED /* 107 */ EXTERN void Tk_GetRootCoords(Tk_Window tkwin, int *xPtr, int *yPtr); -#endif -#ifndef Tk_GetScrollInfo_TCL_DECLARED -#define Tk_GetScrollInfo_TCL_DECLARED /* 108 */ EXTERN int Tk_GetScrollInfo(Tcl_Interp *interp, int argc, CONST84 char **argv, double *dblPtr, int *intPtr); -#endif -#ifndef Tk_GetScreenMM_TCL_DECLARED -#define Tk_GetScreenMM_TCL_DECLARED /* 109 */ EXTERN int Tk_GetScreenMM(Tcl_Interp *interp, Tk_Window tkwin, - CONST char *str, double *doublePtr); -#endif -#ifndef Tk_GetSelection_TCL_DECLARED -#define Tk_GetSelection_TCL_DECLARED + const char *str, double *doublePtr); /* 110 */ EXTERN int Tk_GetSelection(Tcl_Interp *interp, Tk_Window tkwin, Atom selection, Atom target, Tk_GetSelProc *proc, ClientData clientData); -#endif -#ifndef Tk_GetUid_TCL_DECLARED -#define Tk_GetUid_TCL_DECLARED /* 111 */ -EXTERN Tk_Uid Tk_GetUid(CONST char *str); -#endif -#ifndef Tk_GetVisual_TCL_DECLARED -#define Tk_GetVisual_TCL_DECLARED +EXTERN Tk_Uid Tk_GetUid(const char *str); /* 112 */ EXTERN Visual * Tk_GetVisual(Tcl_Interp *interp, Tk_Window tkwin, - CONST char *str, int *depthPtr, + const char *str, int *depthPtr, Colormap *colormapPtr); -#endif -#ifndef Tk_GetVRootGeometry_TCL_DECLARED -#define Tk_GetVRootGeometry_TCL_DECLARED /* 113 */ EXTERN void Tk_GetVRootGeometry(Tk_Window tkwin, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr); -#endif -#ifndef Tk_Grab_TCL_DECLARED -#define Tk_Grab_TCL_DECLARED /* 114 */ EXTERN int Tk_Grab(Tcl_Interp *interp, Tk_Window tkwin, int grabGlobal); -#endif -#ifndef Tk_HandleEvent_TCL_DECLARED -#define Tk_HandleEvent_TCL_DECLARED /* 115 */ EXTERN void Tk_HandleEvent(XEvent *eventPtr); -#endif -#ifndef Tk_IdToWindow_TCL_DECLARED -#define Tk_IdToWindow_TCL_DECLARED /* 116 */ EXTERN Tk_Window Tk_IdToWindow(Display *display, Window window); -#endif -#ifndef Tk_ImageChanged_TCL_DECLARED -#define Tk_ImageChanged_TCL_DECLARED /* 117 */ EXTERN void Tk_ImageChanged(Tk_ImageMaster master, int x, int y, int width, int height, int imageWidth, int imageHeight); -#endif -#ifndef Tk_Init_TCL_DECLARED -#define Tk_Init_TCL_DECLARED /* 118 */ EXTERN int Tk_Init(Tcl_Interp *interp); -#endif -#ifndef Tk_InternAtom_TCL_DECLARED -#define Tk_InternAtom_TCL_DECLARED /* 119 */ -EXTERN Atom Tk_InternAtom(Tk_Window tkwin, CONST char *name); -#endif -#ifndef Tk_IntersectTextLayout_TCL_DECLARED -#define Tk_IntersectTextLayout_TCL_DECLARED +EXTERN Atom Tk_InternAtom(Tk_Window tkwin, const char *name); /* 120 */ EXTERN int Tk_IntersectTextLayout(Tk_TextLayout layout, int x, int y, int width, int height); -#endif -#ifndef Tk_MaintainGeometry_TCL_DECLARED -#define Tk_MaintainGeometry_TCL_DECLARED /* 121 */ EXTERN void Tk_MaintainGeometry(Tk_Window slave, Tk_Window master, int x, int y, int width, int height); -#endif -#ifndef Tk_MainWindow_TCL_DECLARED -#define Tk_MainWindow_TCL_DECLARED /* 122 */ EXTERN Tk_Window Tk_MainWindow(Tcl_Interp *interp); -#endif -#ifndef Tk_MakeWindowExist_TCL_DECLARED -#define Tk_MakeWindowExist_TCL_DECLARED /* 123 */ EXTERN void Tk_MakeWindowExist(Tk_Window tkwin); -#endif -#ifndef Tk_ManageGeometry_TCL_DECLARED -#define Tk_ManageGeometry_TCL_DECLARED /* 124 */ EXTERN void Tk_ManageGeometry(Tk_Window tkwin, - CONST Tk_GeomMgr *mgrPtr, + const Tk_GeomMgr *mgrPtr, ClientData clientData); -#endif -#ifndef Tk_MapWindow_TCL_DECLARED -#define Tk_MapWindow_TCL_DECLARED /* 125 */ EXTERN void Tk_MapWindow(Tk_Window tkwin); -#endif -#ifndef Tk_MeasureChars_TCL_DECLARED -#define Tk_MeasureChars_TCL_DECLARED /* 126 */ -EXTERN int Tk_MeasureChars(Tk_Font tkfont, CONST char *source, +EXTERN int Tk_MeasureChars(Tk_Font tkfont, const char *source, int numBytes, int maxPixels, int flags, int *lengthPtr); -#endif -#ifndef Tk_MoveResizeWindow_TCL_DECLARED -#define Tk_MoveResizeWindow_TCL_DECLARED /* 127 */ EXTERN void Tk_MoveResizeWindow(Tk_Window tkwin, int x, int y, int width, int height); -#endif -#ifndef Tk_MoveWindow_TCL_DECLARED -#define Tk_MoveWindow_TCL_DECLARED /* 128 */ EXTERN void Tk_MoveWindow(Tk_Window tkwin, int x, int y); -#endif -#ifndef Tk_MoveToplevelWindow_TCL_DECLARED -#define Tk_MoveToplevelWindow_TCL_DECLARED /* 129 */ EXTERN void Tk_MoveToplevelWindow(Tk_Window tkwin, int x, int y); -#endif -#ifndef Tk_NameOf3DBorder_TCL_DECLARED -#define Tk_NameOf3DBorder_TCL_DECLARED /* 130 */ EXTERN CONST84_RETURN char * Tk_NameOf3DBorder(Tk_3DBorder border); -#endif -#ifndef Tk_NameOfAnchor_TCL_DECLARED -#define Tk_NameOfAnchor_TCL_DECLARED /* 131 */ EXTERN CONST84_RETURN char * Tk_NameOfAnchor(Tk_Anchor anchor); -#endif -#ifndef Tk_NameOfBitmap_TCL_DECLARED -#define Tk_NameOfBitmap_TCL_DECLARED /* 132 */ EXTERN CONST84_RETURN char * Tk_NameOfBitmap(Display *display, Pixmap bitmap); -#endif -#ifndef Tk_NameOfCapStyle_TCL_DECLARED -#define Tk_NameOfCapStyle_TCL_DECLARED /* 133 */ EXTERN CONST84_RETURN char * Tk_NameOfCapStyle(int cap); -#endif -#ifndef Tk_NameOfColor_TCL_DECLARED -#define Tk_NameOfColor_TCL_DECLARED /* 134 */ EXTERN CONST84_RETURN char * Tk_NameOfColor(XColor *colorPtr); -#endif -#ifndef Tk_NameOfCursor_TCL_DECLARED -#define Tk_NameOfCursor_TCL_DECLARED /* 135 */ EXTERN CONST84_RETURN char * Tk_NameOfCursor(Display *display, Tk_Cursor cursor); -#endif -#ifndef Tk_NameOfFont_TCL_DECLARED -#define Tk_NameOfFont_TCL_DECLARED /* 136 */ EXTERN CONST84_RETURN char * Tk_NameOfFont(Tk_Font font); -#endif -#ifndef Tk_NameOfImage_TCL_DECLARED -#define Tk_NameOfImage_TCL_DECLARED /* 137 */ EXTERN CONST84_RETURN char * Tk_NameOfImage(Tk_ImageMaster imageMaster); -#endif -#ifndef Tk_NameOfJoinStyle_TCL_DECLARED -#define Tk_NameOfJoinStyle_TCL_DECLARED /* 138 */ EXTERN CONST84_RETURN char * Tk_NameOfJoinStyle(int join); -#endif -#ifndef Tk_NameOfJustify_TCL_DECLARED -#define Tk_NameOfJustify_TCL_DECLARED /* 139 */ EXTERN CONST84_RETURN char * Tk_NameOfJustify(Tk_Justify justify); -#endif -#ifndef Tk_NameOfRelief_TCL_DECLARED -#define Tk_NameOfRelief_TCL_DECLARED /* 140 */ EXTERN CONST84_RETURN char * Tk_NameOfRelief(int relief); -#endif -#ifndef Tk_NameToWindow_TCL_DECLARED -#define Tk_NameToWindow_TCL_DECLARED /* 141 */ EXTERN Tk_Window Tk_NameToWindow(Tcl_Interp *interp, - CONST char *pathName, Tk_Window tkwin); -#endif -#ifndef Tk_OwnSelection_TCL_DECLARED -#define Tk_OwnSelection_TCL_DECLARED + const char *pathName, Tk_Window tkwin); /* 142 */ EXTERN void Tk_OwnSelection(Tk_Window tkwin, Atom selection, Tk_LostSelProc *proc, ClientData clientData); -#endif -#ifndef Tk_ParseArgv_TCL_DECLARED -#define Tk_ParseArgv_TCL_DECLARED /* 143 */ EXTERN int Tk_ParseArgv(Tcl_Interp *interp, Tk_Window tkwin, int *argcPtr, CONST84 char **argv, - Tk_ArgvInfo *argTable, int flags); -#endif -#ifndef Tk_PhotoPutBlock_NoComposite_TCL_DECLARED -#define Tk_PhotoPutBlock_NoComposite_TCL_DECLARED + const Tk_ArgvInfo *argTable, int flags); /* 144 */ EXTERN void Tk_PhotoPutBlock_NoComposite(Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height); -#endif -#ifndef Tk_PhotoPutZoomedBlock_NoComposite_TCL_DECLARED -#define Tk_PhotoPutZoomedBlock_NoComposite_TCL_DECLARED /* 145 */ EXTERN void Tk_PhotoPutZoomedBlock_NoComposite( Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY); -#endif -#ifndef Tk_PhotoGetImage_TCL_DECLARED -#define Tk_PhotoGetImage_TCL_DECLARED /* 146 */ EXTERN int Tk_PhotoGetImage(Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr); -#endif -#ifndef Tk_PhotoBlank_TCL_DECLARED -#define Tk_PhotoBlank_TCL_DECLARED /* 147 */ EXTERN void Tk_PhotoBlank(Tk_PhotoHandle handle); -#endif -#ifndef Tk_PhotoExpand_Panic_TCL_DECLARED -#define Tk_PhotoExpand_Panic_TCL_DECLARED /* 148 */ EXTERN void Tk_PhotoExpand_Panic(Tk_PhotoHandle handle, int width, int height); -#endif -#ifndef Tk_PhotoGetSize_TCL_DECLARED -#define Tk_PhotoGetSize_TCL_DECLARED /* 149 */ EXTERN void Tk_PhotoGetSize(Tk_PhotoHandle handle, int *widthPtr, int *heightPtr); -#endif -#ifndef Tk_PhotoSetSize_Panic_TCL_DECLARED -#define Tk_PhotoSetSize_Panic_TCL_DECLARED /* 150 */ EXTERN void Tk_PhotoSetSize_Panic(Tk_PhotoHandle handle, int width, int height); -#endif -#ifndef Tk_PointToChar_TCL_DECLARED -#define Tk_PointToChar_TCL_DECLARED /* 151 */ EXTERN int Tk_PointToChar(Tk_TextLayout layout, int x, int y); -#endif -#ifndef Tk_PostscriptFontName_TCL_DECLARED -#define Tk_PostscriptFontName_TCL_DECLARED /* 152 */ EXTERN int Tk_PostscriptFontName(Tk_Font tkfont, Tcl_DString *dsPtr); -#endif -#ifndef Tk_PreserveColormap_TCL_DECLARED -#define Tk_PreserveColormap_TCL_DECLARED /* 153 */ EXTERN void Tk_PreserveColormap(Display *display, Colormap colormap); -#endif -#ifndef Tk_QueueWindowEvent_TCL_DECLARED -#define Tk_QueueWindowEvent_TCL_DECLARED /* 154 */ EXTERN void Tk_QueueWindowEvent(XEvent *eventPtr, Tcl_QueuePosition position); -#endif -#ifndef Tk_RedrawImage_TCL_DECLARED -#define Tk_RedrawImage_TCL_DECLARED /* 155 */ EXTERN void Tk_RedrawImage(Tk_Image image, int imageX, int imageY, int width, int height, Drawable drawable, int drawableX, int drawableY); -#endif -#ifndef Tk_ResizeWindow_TCL_DECLARED -#define Tk_ResizeWindow_TCL_DECLARED /* 156 */ EXTERN void Tk_ResizeWindow(Tk_Window tkwin, int width, int height); -#endif -#ifndef Tk_RestackWindow_TCL_DECLARED -#define Tk_RestackWindow_TCL_DECLARED /* 157 */ EXTERN int Tk_RestackWindow(Tk_Window tkwin, int aboveBelow, Tk_Window other); -#endif -#ifndef Tk_RestrictEvents_TCL_DECLARED -#define Tk_RestrictEvents_TCL_DECLARED /* 158 */ EXTERN Tk_RestrictProc * Tk_RestrictEvents(Tk_RestrictProc *proc, ClientData arg, ClientData *prevArgPtr); -#endif -#ifndef Tk_SafeInit_TCL_DECLARED -#define Tk_SafeInit_TCL_DECLARED /* 159 */ EXTERN int Tk_SafeInit(Tcl_Interp *interp); -#endif -#ifndef Tk_SetAppName_TCL_DECLARED -#define Tk_SetAppName_TCL_DECLARED /* 160 */ -EXTERN CONST char * Tk_SetAppName(Tk_Window tkwin, CONST char *name); -#endif -#ifndef Tk_SetBackgroundFromBorder_TCL_DECLARED -#define Tk_SetBackgroundFromBorder_TCL_DECLARED +EXTERN const char * Tk_SetAppName(Tk_Window tkwin, const char *name); /* 161 */ EXTERN void Tk_SetBackgroundFromBorder(Tk_Window tkwin, Tk_3DBorder border); -#endif -#ifndef Tk_SetClass_TCL_DECLARED -#define Tk_SetClass_TCL_DECLARED /* 162 */ -EXTERN void Tk_SetClass(Tk_Window tkwin, CONST char *className); -#endif -#ifndef Tk_SetGrid_TCL_DECLARED -#define Tk_SetGrid_TCL_DECLARED +EXTERN void Tk_SetClass(Tk_Window tkwin, const char *className); /* 163 */ EXTERN void Tk_SetGrid(Tk_Window tkwin, int reqWidth, int reqHeight, int gridWidth, int gridHeight); -#endif -#ifndef Tk_SetInternalBorder_TCL_DECLARED -#define Tk_SetInternalBorder_TCL_DECLARED /* 164 */ EXTERN void Tk_SetInternalBorder(Tk_Window tkwin, int width); -#endif -#ifndef Tk_SetWindowBackground_TCL_DECLARED -#define Tk_SetWindowBackground_TCL_DECLARED /* 165 */ EXTERN void Tk_SetWindowBackground(Tk_Window tkwin, unsigned long pixel); -#endif -#ifndef Tk_SetWindowBackgroundPixmap_TCL_DECLARED -#define Tk_SetWindowBackgroundPixmap_TCL_DECLARED /* 166 */ EXTERN void Tk_SetWindowBackgroundPixmap(Tk_Window tkwin, Pixmap pixmap); -#endif -#ifndef Tk_SetWindowBorder_TCL_DECLARED -#define Tk_SetWindowBorder_TCL_DECLARED /* 167 */ EXTERN void Tk_SetWindowBorder(Tk_Window tkwin, unsigned long pixel); -#endif -#ifndef Tk_SetWindowBorderWidth_TCL_DECLARED -#define Tk_SetWindowBorderWidth_TCL_DECLARED /* 168 */ EXTERN void Tk_SetWindowBorderWidth(Tk_Window tkwin, int width); -#endif -#ifndef Tk_SetWindowBorderPixmap_TCL_DECLARED -#define Tk_SetWindowBorderPixmap_TCL_DECLARED /* 169 */ EXTERN void Tk_SetWindowBorderPixmap(Tk_Window tkwin, Pixmap pixmap); -#endif -#ifndef Tk_SetWindowColormap_TCL_DECLARED -#define Tk_SetWindowColormap_TCL_DECLARED /* 170 */ EXTERN void Tk_SetWindowColormap(Tk_Window tkwin, Colormap colormap); -#endif -#ifndef Tk_SetWindowVisual_TCL_DECLARED -#define Tk_SetWindowVisual_TCL_DECLARED /* 171 */ EXTERN int Tk_SetWindowVisual(Tk_Window tkwin, Visual *visual, int depth, Colormap colormap); -#endif -#ifndef Tk_SizeOfBitmap_TCL_DECLARED -#define Tk_SizeOfBitmap_TCL_DECLARED /* 172 */ EXTERN void Tk_SizeOfBitmap(Display *display, Pixmap bitmap, int *widthPtr, int *heightPtr); -#endif -#ifndef Tk_SizeOfImage_TCL_DECLARED -#define Tk_SizeOfImage_TCL_DECLARED /* 173 */ EXTERN void Tk_SizeOfImage(Tk_Image image, int *widthPtr, int *heightPtr); -#endif -#ifndef Tk_StrictMotif_TCL_DECLARED -#define Tk_StrictMotif_TCL_DECLARED /* 174 */ EXTERN int Tk_StrictMotif(Tk_Window tkwin); -#endif -#ifndef Tk_TextLayoutToPostscript_TCL_DECLARED -#define Tk_TextLayoutToPostscript_TCL_DECLARED /* 175 */ EXTERN void Tk_TextLayoutToPostscript(Tcl_Interp *interp, Tk_TextLayout layout); -#endif -#ifndef Tk_TextWidth_TCL_DECLARED -#define Tk_TextWidth_TCL_DECLARED /* 176 */ -EXTERN int Tk_TextWidth(Tk_Font font, CONST char *str, +EXTERN int Tk_TextWidth(Tk_Font font, const char *str, int numBytes); -#endif -#ifndef Tk_UndefineCursor_TCL_DECLARED -#define Tk_UndefineCursor_TCL_DECLARED /* 177 */ EXTERN void Tk_UndefineCursor(Tk_Window window); -#endif -#ifndef Tk_UnderlineChars_TCL_DECLARED -#define Tk_UnderlineChars_TCL_DECLARED /* 178 */ EXTERN void Tk_UnderlineChars(Display *display, Drawable drawable, GC gc, Tk_Font tkfont, - CONST char *source, int x, int y, + const char *source, int x, int y, int firstByte, int lastByte); -#endif -#ifndef Tk_UnderlineTextLayout_TCL_DECLARED -#define Tk_UnderlineTextLayout_TCL_DECLARED /* 179 */ EXTERN void Tk_UnderlineTextLayout(Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, int underline); -#endif -#ifndef Tk_Ungrab_TCL_DECLARED -#define Tk_Ungrab_TCL_DECLARED /* 180 */ EXTERN void Tk_Ungrab(Tk_Window tkwin); -#endif -#ifndef Tk_UnmaintainGeometry_TCL_DECLARED -#define Tk_UnmaintainGeometry_TCL_DECLARED /* 181 */ EXTERN void Tk_UnmaintainGeometry(Tk_Window slave, Tk_Window master); -#endif -#ifndef Tk_UnmapWindow_TCL_DECLARED -#define Tk_UnmapWindow_TCL_DECLARED /* 182 */ EXTERN void Tk_UnmapWindow(Tk_Window tkwin); -#endif -#ifndef Tk_UnsetGrid_TCL_DECLARED -#define Tk_UnsetGrid_TCL_DECLARED /* 183 */ EXTERN void Tk_UnsetGrid(Tk_Window tkwin); -#endif -#ifndef Tk_UpdatePointer_TCL_DECLARED -#define Tk_UpdatePointer_TCL_DECLARED /* 184 */ EXTERN void Tk_UpdatePointer(Tk_Window tkwin, int x, int y, int state); -#endif -#ifndef Tk_AllocBitmapFromObj_TCL_DECLARED -#define Tk_AllocBitmapFromObj_TCL_DECLARED /* 185 */ EXTERN Pixmap Tk_AllocBitmapFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr); -#endif -#ifndef Tk_Alloc3DBorderFromObj_TCL_DECLARED -#define Tk_Alloc3DBorderFromObj_TCL_DECLARED /* 186 */ EXTERN Tk_3DBorder Tk_Alloc3DBorderFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr); -#endif -#ifndef Tk_AllocColorFromObj_TCL_DECLARED -#define Tk_AllocColorFromObj_TCL_DECLARED /* 187 */ EXTERN XColor * Tk_AllocColorFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr); -#endif -#ifndef Tk_AllocCursorFromObj_TCL_DECLARED -#define Tk_AllocCursorFromObj_TCL_DECLARED /* 188 */ EXTERN Tk_Cursor Tk_AllocCursorFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr); -#endif -#ifndef Tk_AllocFontFromObj_TCL_DECLARED -#define Tk_AllocFontFromObj_TCL_DECLARED /* 189 */ EXTERN Tk_Font Tk_AllocFontFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr); -#endif -#ifndef Tk_CreateOptionTable_TCL_DECLARED -#define Tk_CreateOptionTable_TCL_DECLARED /* 190 */ EXTERN Tk_OptionTable Tk_CreateOptionTable(Tcl_Interp *interp, - CONST Tk_OptionSpec *templatePtr); -#endif -#ifndef Tk_DeleteOptionTable_TCL_DECLARED -#define Tk_DeleteOptionTable_TCL_DECLARED + const Tk_OptionSpec *templatePtr); /* 191 */ EXTERN void Tk_DeleteOptionTable(Tk_OptionTable optionTable); -#endif -#ifndef Tk_Free3DBorderFromObj_TCL_DECLARED -#define Tk_Free3DBorderFromObj_TCL_DECLARED /* 192 */ EXTERN void Tk_Free3DBorderFromObj(Tk_Window tkwin, Tcl_Obj *objPtr); -#endif -#ifndef Tk_FreeBitmapFromObj_TCL_DECLARED -#define Tk_FreeBitmapFromObj_TCL_DECLARED /* 193 */ EXTERN void Tk_FreeBitmapFromObj(Tk_Window tkwin, Tcl_Obj *objPtr); -#endif -#ifndef Tk_FreeColorFromObj_TCL_DECLARED -#define Tk_FreeColorFromObj_TCL_DECLARED /* 194 */ EXTERN void Tk_FreeColorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr); -#endif -#ifndef Tk_FreeConfigOptions_TCL_DECLARED -#define Tk_FreeConfigOptions_TCL_DECLARED /* 195 */ EXTERN void Tk_FreeConfigOptions(char *recordPtr, Tk_OptionTable optionToken, Tk_Window tkwin); -#endif -#ifndef Tk_FreeSavedOptions_TCL_DECLARED -#define Tk_FreeSavedOptions_TCL_DECLARED /* 196 */ EXTERN void Tk_FreeSavedOptions(Tk_SavedOptions *savePtr); -#endif -#ifndef Tk_FreeCursorFromObj_TCL_DECLARED -#define Tk_FreeCursorFromObj_TCL_DECLARED /* 197 */ EXTERN void Tk_FreeCursorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr); -#endif -#ifndef Tk_FreeFontFromObj_TCL_DECLARED -#define Tk_FreeFontFromObj_TCL_DECLARED /* 198 */ EXTERN void Tk_FreeFontFromObj(Tk_Window tkwin, Tcl_Obj *objPtr); -#endif -#ifndef Tk_Get3DBorderFromObj_TCL_DECLARED -#define Tk_Get3DBorderFromObj_TCL_DECLARED /* 199 */ EXTERN Tk_3DBorder Tk_Get3DBorderFromObj(Tk_Window tkwin, Tcl_Obj *objPtr); -#endif -#ifndef Tk_GetAnchorFromObj_TCL_DECLARED -#define Tk_GetAnchorFromObj_TCL_DECLARED /* 200 */ EXTERN int Tk_GetAnchorFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Tk_Anchor *anchorPtr); -#endif -#ifndef Tk_GetBitmapFromObj_TCL_DECLARED -#define Tk_GetBitmapFromObj_TCL_DECLARED /* 201 */ EXTERN Pixmap Tk_GetBitmapFromObj(Tk_Window tkwin, Tcl_Obj *objPtr); -#endif -#ifndef Tk_GetColorFromObj_TCL_DECLARED -#define Tk_GetColorFromObj_TCL_DECLARED /* 202 */ EXTERN XColor * Tk_GetColorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr); -#endif -#ifndef Tk_GetCursorFromObj_TCL_DECLARED -#define Tk_GetCursorFromObj_TCL_DECLARED /* 203 */ EXTERN Tk_Cursor Tk_GetCursorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr); -#endif -#ifndef Tk_GetOptionInfo_TCL_DECLARED -#define Tk_GetOptionInfo_TCL_DECLARED /* 204 */ EXTERN Tcl_Obj * Tk_GetOptionInfo(Tcl_Interp *interp, char *recordPtr, Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin); -#endif -#ifndef Tk_GetOptionValue_TCL_DECLARED -#define Tk_GetOptionValue_TCL_DECLARED /* 205 */ EXTERN Tcl_Obj * Tk_GetOptionValue(Tcl_Interp *interp, char *recordPtr, Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin); -#endif -#ifndef Tk_GetJustifyFromObj_TCL_DECLARED -#define Tk_GetJustifyFromObj_TCL_DECLARED /* 206 */ EXTERN int Tk_GetJustifyFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Tk_Justify *justifyPtr); -#endif -#ifndef Tk_GetMMFromObj_TCL_DECLARED -#define Tk_GetMMFromObj_TCL_DECLARED /* 207 */ EXTERN int Tk_GetMMFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, double *doublePtr); -#endif -#ifndef Tk_GetPixelsFromObj_TCL_DECLARED -#define Tk_GetPixelsFromObj_TCL_DECLARED /* 208 */ EXTERN int Tk_GetPixelsFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, int *intPtr); -#endif -#ifndef Tk_GetReliefFromObj_TCL_DECLARED -#define Tk_GetReliefFromObj_TCL_DECLARED /* 209 */ EXTERN int Tk_GetReliefFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *resultPtr); -#endif -#ifndef Tk_GetScrollInfoObj_TCL_DECLARED -#define Tk_GetScrollInfoObj_TCL_DECLARED /* 210 */ EXTERN int Tk_GetScrollInfoObj(Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[], double *dblPtr, + Tcl_Obj *const objv[], double *dblPtr, int *intPtr); -#endif -#ifndef Tk_InitOptions_TCL_DECLARED -#define Tk_InitOptions_TCL_DECLARED /* 211 */ EXTERN int Tk_InitOptions(Tcl_Interp *interp, char *recordPtr, Tk_OptionTable optionToken, Tk_Window tkwin); -#endif -#ifndef Tk_MainEx_TCL_DECLARED -#define Tk_MainEx_TCL_DECLARED /* 212 */ EXTERN void Tk_MainEx(int argc, char **argv, Tcl_AppInitProc *appInitProc, Tcl_Interp *interp); -#endif -#ifndef Tk_RestoreSavedOptions_TCL_DECLARED -#define Tk_RestoreSavedOptions_TCL_DECLARED /* 213 */ EXTERN void Tk_RestoreSavedOptions(Tk_SavedOptions *savePtr); -#endif -#ifndef Tk_SetOptions_TCL_DECLARED -#define Tk_SetOptions_TCL_DECLARED /* 214 */ EXTERN int Tk_SetOptions(Tcl_Interp *interp, char *recordPtr, Tk_OptionTable optionTable, int objc, - Tcl_Obj *CONST objv[], Tk_Window tkwin, + Tcl_Obj *const objv[], Tk_Window tkwin, Tk_SavedOptions *savePtr, int *maskPtr); -#endif -#ifndef Tk_InitConsoleChannels_TCL_DECLARED -#define Tk_InitConsoleChannels_TCL_DECLARED /* 215 */ EXTERN void Tk_InitConsoleChannels(Tcl_Interp *interp); -#endif -#ifndef Tk_CreateConsoleWindow_TCL_DECLARED -#define Tk_CreateConsoleWindow_TCL_DECLARED /* 216 */ EXTERN int Tk_CreateConsoleWindow(Tcl_Interp *interp); -#endif -#ifndef Tk_CreateSmoothMethod_TCL_DECLARED -#define Tk_CreateSmoothMethod_TCL_DECLARED /* 217 */ EXTERN void Tk_CreateSmoothMethod(Tcl_Interp *interp, - Tk_SmoothMethod *method); -#endif + const Tk_SmoothMethod *method); /* Slot 218 is reserved */ /* Slot 219 is reserved */ -#ifndef Tk_GetDash_TCL_DECLARED -#define Tk_GetDash_TCL_DECLARED /* 220 */ -EXTERN int Tk_GetDash(Tcl_Interp *interp, CONST char *value, +EXTERN int Tk_GetDash(Tcl_Interp *interp, const char *value, Tk_Dash *dash); -#endif -#ifndef Tk_CreateOutline_TCL_DECLARED -#define Tk_CreateOutline_TCL_DECLARED /* 221 */ EXTERN void Tk_CreateOutline(Tk_Outline *outline); -#endif -#ifndef Tk_DeleteOutline_TCL_DECLARED -#define Tk_DeleteOutline_TCL_DECLARED /* 222 */ EXTERN void Tk_DeleteOutline(Display *display, Tk_Outline *outline); -#endif -#ifndef Tk_ConfigOutlineGC_TCL_DECLARED -#define Tk_ConfigOutlineGC_TCL_DECLARED /* 223 */ EXTERN int Tk_ConfigOutlineGC(XGCValues *gcValues, Tk_Canvas canvas, Tk_Item *item, Tk_Outline *outline); -#endif -#ifndef Tk_ChangeOutlineGC_TCL_DECLARED -#define Tk_ChangeOutlineGC_TCL_DECLARED /* 224 */ EXTERN int Tk_ChangeOutlineGC(Tk_Canvas canvas, Tk_Item *item, Tk_Outline *outline); -#endif -#ifndef Tk_ResetOutlineGC_TCL_DECLARED -#define Tk_ResetOutlineGC_TCL_DECLARED /* 225 */ EXTERN int Tk_ResetOutlineGC(Tk_Canvas canvas, Tk_Item *item, Tk_Outline *outline); -#endif -#ifndef Tk_CanvasPsOutline_TCL_DECLARED -#define Tk_CanvasPsOutline_TCL_DECLARED /* 226 */ EXTERN int Tk_CanvasPsOutline(Tk_Canvas canvas, Tk_Item *item, Tk_Outline *outline); -#endif -#ifndef Tk_SetTSOrigin_TCL_DECLARED -#define Tk_SetTSOrigin_TCL_DECLARED /* 227 */ EXTERN void Tk_SetTSOrigin(Tk_Window tkwin, GC gc, int x, int y); -#endif -#ifndef Tk_CanvasGetCoordFromObj_TCL_DECLARED -#define Tk_CanvasGetCoordFromObj_TCL_DECLARED /* 228 */ EXTERN int Tk_CanvasGetCoordFromObj(Tcl_Interp *interp, Tk_Canvas canvas, Tcl_Obj *obj, double *doublePtr); -#endif -#ifndef Tk_CanvasSetOffset_TCL_DECLARED -#define Tk_CanvasSetOffset_TCL_DECLARED /* 229 */ EXTERN void Tk_CanvasSetOffset(Tk_Canvas canvas, GC gc, Tk_TSOffset *offset); -#endif -#ifndef Tk_DitherPhoto_TCL_DECLARED -#define Tk_DitherPhoto_TCL_DECLARED /* 230 */ EXTERN void Tk_DitherPhoto(Tk_PhotoHandle handle, int x, int y, int width, int height); -#endif -#ifndef Tk_PostscriptBitmap_TCL_DECLARED -#define Tk_PostscriptBitmap_TCL_DECLARED /* 231 */ EXTERN int Tk_PostscriptBitmap(Tcl_Interp *interp, Tk_Window tkwin, Tk_PostscriptInfo psInfo, Pixmap bitmap, int startX, int startY, int width, int height); -#endif -#ifndef Tk_PostscriptColor_TCL_DECLARED -#define Tk_PostscriptColor_TCL_DECLARED /* 232 */ EXTERN int Tk_PostscriptColor(Tcl_Interp *interp, Tk_PostscriptInfo psInfo, XColor *colorPtr); -#endif -#ifndef Tk_PostscriptFont_TCL_DECLARED -#define Tk_PostscriptFont_TCL_DECLARED /* 233 */ EXTERN int Tk_PostscriptFont(Tcl_Interp *interp, Tk_PostscriptInfo psInfo, Tk_Font font); -#endif -#ifndef Tk_PostscriptImage_TCL_DECLARED -#define Tk_PostscriptImage_TCL_DECLARED /* 234 */ EXTERN int Tk_PostscriptImage(Tk_Image image, Tcl_Interp *interp, Tk_Window tkwin, Tk_PostscriptInfo psinfo, int x, int y, int width, int height, int prepass); -#endif -#ifndef Tk_PostscriptPath_TCL_DECLARED -#define Tk_PostscriptPath_TCL_DECLARED /* 235 */ EXTERN void Tk_PostscriptPath(Tcl_Interp *interp, Tk_PostscriptInfo psInfo, double *coordPtr, int numPoints); -#endif -#ifndef Tk_PostscriptStipple_TCL_DECLARED -#define Tk_PostscriptStipple_TCL_DECLARED /* 236 */ EXTERN int Tk_PostscriptStipple(Tcl_Interp *interp, Tk_Window tkwin, Tk_PostscriptInfo psInfo, Pixmap bitmap); -#endif -#ifndef Tk_PostscriptY_TCL_DECLARED -#define Tk_PostscriptY_TCL_DECLARED /* 237 */ EXTERN double Tk_PostscriptY(double y, Tk_PostscriptInfo psInfo); -#endif -#ifndef Tk_PostscriptPhoto_TCL_DECLARED -#define Tk_PostscriptPhoto_TCL_DECLARED /* 238 */ EXTERN int Tk_PostscriptPhoto(Tcl_Interp *interp, Tk_PhotoImageBlock *blockPtr, Tk_PostscriptInfo psInfo, int width, int height); -#endif -#ifndef Tk_CreateClientMessageHandler_TCL_DECLARED -#define Tk_CreateClientMessageHandler_TCL_DECLARED /* 239 */ EXTERN void Tk_CreateClientMessageHandler( Tk_ClientMessageProc *proc); -#endif -#ifndef Tk_DeleteClientMessageHandler_TCL_DECLARED -#define Tk_DeleteClientMessageHandler_TCL_DECLARED /* 240 */ EXTERN void Tk_DeleteClientMessageHandler( Tk_ClientMessageProc *proc); -#endif -#ifndef Tk_CreateAnonymousWindow_TCL_DECLARED -#define Tk_CreateAnonymousWindow_TCL_DECLARED /* 241 */ EXTERN Tk_Window Tk_CreateAnonymousWindow(Tcl_Interp *interp, - Tk_Window parent, CONST char *screenName); -#endif -#ifndef Tk_SetClassProcs_TCL_DECLARED -#define Tk_SetClassProcs_TCL_DECLARED + Tk_Window parent, const char *screenName); /* 242 */ EXTERN void Tk_SetClassProcs(Tk_Window tkwin, - Tk_ClassProcs *procs, + const Tk_ClassProcs *procs, ClientData instanceData); -#endif -#ifndef Tk_SetInternalBorderEx_TCL_DECLARED -#define Tk_SetInternalBorderEx_TCL_DECLARED /* 243 */ EXTERN void Tk_SetInternalBorderEx(Tk_Window tkwin, int left, int right, int top, int bottom); -#endif -#ifndef Tk_SetMinimumRequestSize_TCL_DECLARED -#define Tk_SetMinimumRequestSize_TCL_DECLARED /* 244 */ EXTERN void Tk_SetMinimumRequestSize(Tk_Window tkwin, int minWidth, int minHeight); -#endif -#ifndef Tk_SetCaretPos_TCL_DECLARED -#define Tk_SetCaretPos_TCL_DECLARED /* 245 */ EXTERN void Tk_SetCaretPos(Tk_Window tkwin, int x, int y, int height); -#endif -#ifndef Tk_PhotoPutBlock_Panic_TCL_DECLARED -#define Tk_PhotoPutBlock_Panic_TCL_DECLARED /* 246 */ EXTERN void Tk_PhotoPutBlock_Panic(Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int compRule); -#endif -#ifndef Tk_PhotoPutZoomedBlock_Panic_TCL_DECLARED -#define Tk_PhotoPutZoomedBlock_Panic_TCL_DECLARED /* 247 */ EXTERN void Tk_PhotoPutZoomedBlock_Panic(Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY, int compRule); -#endif -#ifndef Tk_CollapseMotionEvents_TCL_DECLARED -#define Tk_CollapseMotionEvents_TCL_DECLARED /* 248 */ EXTERN int Tk_CollapseMotionEvents(Display *display, int collapse); -#endif -#ifndef Tk_RegisterStyleEngine_TCL_DECLARED -#define Tk_RegisterStyleEngine_TCL_DECLARED /* 249 */ -EXTERN Tk_StyleEngine Tk_RegisterStyleEngine(CONST char *name, +EXTERN Tk_StyleEngine Tk_RegisterStyleEngine(const char *name, Tk_StyleEngine parent); -#endif -#ifndef Tk_GetStyleEngine_TCL_DECLARED -#define Tk_GetStyleEngine_TCL_DECLARED /* 250 */ -EXTERN Tk_StyleEngine Tk_GetStyleEngine(CONST char *name); -#endif -#ifndef Tk_RegisterStyledElement_TCL_DECLARED -#define Tk_RegisterStyledElement_TCL_DECLARED +EXTERN Tk_StyleEngine Tk_GetStyleEngine(const char *name); /* 251 */ EXTERN int Tk_RegisterStyledElement(Tk_StyleEngine engine, Tk_ElementSpec *templatePtr); -#endif -#ifndef Tk_GetElementId_TCL_DECLARED -#define Tk_GetElementId_TCL_DECLARED /* 252 */ -EXTERN int Tk_GetElementId(CONST char *name); -#endif -#ifndef Tk_CreateStyle_TCL_DECLARED -#define Tk_CreateStyle_TCL_DECLARED +EXTERN int Tk_GetElementId(const char *name); /* 253 */ -EXTERN Tk_Style Tk_CreateStyle(CONST char *name, +EXTERN Tk_Style Tk_CreateStyle(const char *name, Tk_StyleEngine engine, ClientData clientData); -#endif -#ifndef Tk_GetStyle_TCL_DECLARED -#define Tk_GetStyle_TCL_DECLARED /* 254 */ -EXTERN Tk_Style Tk_GetStyle(Tcl_Interp *interp, CONST char *name); -#endif -#ifndef Tk_FreeStyle_TCL_DECLARED -#define Tk_FreeStyle_TCL_DECLARED +EXTERN Tk_Style Tk_GetStyle(Tcl_Interp *interp, const char *name); /* 255 */ EXTERN void Tk_FreeStyle(Tk_Style style); -#endif -#ifndef Tk_NameOfStyle_TCL_DECLARED -#define Tk_NameOfStyle_TCL_DECLARED /* 256 */ -EXTERN CONST char * Tk_NameOfStyle(Tk_Style style); -#endif -#ifndef Tk_AllocStyleFromObj_TCL_DECLARED -#define Tk_AllocStyleFromObj_TCL_DECLARED +EXTERN const char * Tk_NameOfStyle(Tk_Style style); /* 257 */ EXTERN Tk_Style Tk_AllocStyleFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr); -#endif -#ifndef Tk_GetStyleFromObj_TCL_DECLARED -#define Tk_GetStyleFromObj_TCL_DECLARED /* 258 */ EXTERN Tk_Style Tk_GetStyleFromObj(Tcl_Obj *objPtr); -#endif -#ifndef Tk_FreeStyleFromObj_TCL_DECLARED -#define Tk_FreeStyleFromObj_TCL_DECLARED /* 259 */ EXTERN void Tk_FreeStyleFromObj(Tcl_Obj *objPtr); -#endif -#ifndef Tk_GetStyledElement_TCL_DECLARED -#define Tk_GetStyledElement_TCL_DECLARED /* 260 */ EXTERN Tk_StyledElement Tk_GetStyledElement(Tk_Style style, int elementId, Tk_OptionTable optionTable); -#endif -#ifndef Tk_GetElementSize_TCL_DECLARED -#define Tk_GetElementSize_TCL_DECLARED /* 261 */ EXTERN void Tk_GetElementSize(Tk_Style style, Tk_StyledElement element, char *recordPtr, Tk_Window tkwin, int width, int height, int inner, int *widthPtr, int *heightPtr); -#endif -#ifndef Tk_GetElementBox_TCL_DECLARED -#define Tk_GetElementBox_TCL_DECLARED /* 262 */ EXTERN void Tk_GetElementBox(Tk_Style style, Tk_StyledElement element, char *recordPtr, Tk_Window tkwin, int x, int y, int width, int height, int inner, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr); -#endif -#ifndef Tk_GetElementBorderWidth_TCL_DECLARED -#define Tk_GetElementBorderWidth_TCL_DECLARED /* 263 */ EXTERN int Tk_GetElementBorderWidth(Tk_Style style, Tk_StyledElement element, char *recordPtr, Tk_Window tkwin); -#endif -#ifndef Tk_DrawElement_TCL_DECLARED -#define Tk_DrawElement_TCL_DECLARED /* 264 */ EXTERN void Tk_DrawElement(Tk_Style style, Tk_StyledElement element, char *recordPtr, Tk_Window tkwin, Drawable d, int x, int y, int width, int height, int state); -#endif -#ifndef Tk_PhotoExpand_TCL_DECLARED -#define Tk_PhotoExpand_TCL_DECLARED /* 265 */ EXTERN int Tk_PhotoExpand(Tcl_Interp *interp, Tk_PhotoHandle handle, int width, int height); -#endif -#ifndef Tk_PhotoPutBlock_TCL_DECLARED -#define Tk_PhotoPutBlock_TCL_DECLARED /* 266 */ EXTERN int Tk_PhotoPutBlock(Tcl_Interp *interp, Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int compRule); -#endif -#ifndef Tk_PhotoPutZoomedBlock_TCL_DECLARED -#define Tk_PhotoPutZoomedBlock_TCL_DECLARED /* 267 */ EXTERN int Tk_PhotoPutZoomedBlock(Tcl_Interp *interp, Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY, int compRule); -#endif -#ifndef Tk_PhotoSetSize_TCL_DECLARED -#define Tk_PhotoSetSize_TCL_DECLARED /* 268 */ EXTERN int Tk_PhotoSetSize(Tcl_Interp *interp, Tk_PhotoHandle handle, int width, int height); -#endif -#ifndef Tk_GetUserInactiveTime_TCL_DECLARED -#define Tk_GetUserInactiveTime_TCL_DECLARED /* 269 */ EXTERN long Tk_GetUserInactiveTime(Display *dpy); -#endif -#ifndef Tk_ResetUserInactiveTime_TCL_DECLARED -#define Tk_ResetUserInactiveTime_TCL_DECLARED /* 270 */ EXTERN void Tk_ResetUserInactiveTime(Display *dpy); -#endif -#ifndef Tk_Interp_TCL_DECLARED -#define Tk_Interp_TCL_DECLARED /* 271 */ EXTERN Tcl_Interp * Tk_Interp(Tk_Window tkwin); -#endif -#ifndef Tk_CreateOldImageType_TCL_DECLARED -#define Tk_CreateOldImageType_TCL_DECLARED /* 272 */ -EXTERN void Tk_CreateOldImageType(Tk_ImageType *typePtr); -#endif -#ifndef Tk_CreateOldPhotoImageFormat_TCL_DECLARED -#define Tk_CreateOldPhotoImageFormat_TCL_DECLARED +EXTERN void Tk_CreateOldImageType(const Tk_ImageType *typePtr); /* 273 */ EXTERN void Tk_CreateOldPhotoImageFormat( - Tk_PhotoImageFormat *formatPtr); -#endif -/* Slot 274 is reserved */ -#ifndef TkUnusedStubEntry_TCL_DECLARED -#define TkUnusedStubEntry_TCL_DECLARED -/* 275 */ -EXTERN void TkUnusedStubEntry(void); -#endif + const Tk_PhotoImageFormat *formatPtr); -typedef struct TkStubHooks { - struct TkPlatStubs *tkPlatStubs; - struct TkIntStubs *tkIntStubs; - struct TkIntPlatStubs *tkIntPlatStubs; - struct TkIntXlibStubs *tkIntXlibStubs; +typedef struct { + const struct TkPlatStubs *tkPlatStubs; + const struct TkIntStubs *tkIntStubs; + const struct TkIntPlatStubs *tkIntPlatStubs; + const struct TkIntXlibStubs *tkIntXlibStubs; } TkStubHooks; typedef struct TkStubs { int magic; - struct TkStubHooks *hooks; + const TkStubHooks *hooks; void (*tk_MainLoop) (void); /* 0 */ XColor * (*tk_3DBorderColor) (Tk_3DBorder border); /* 1 */ GC (*tk_3DBorderGC) (Tk_Window tkwin, Tk_3DBorder border, int which); /* 2 */ void (*tk_3DHorizontalBevel) (Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, int x, int y, int width, int height, int leftIn, int rightIn, int topBevel, int relief); /* 3 */ void (*tk_3DVerticalBevel) (Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, int x, int y, int width, int height, int leftBevel, int relief); /* 4 */ - void (*tk_AddOption) (Tk_Window tkwin, CONST char *name, CONST char *value, int priority); /* 5 */ + void (*tk_AddOption) (Tk_Window tkwin, const char *name, const char *value, int priority); /* 5 */ void (*tk_BindEvent) (Tk_BindingTable bindingTable, XEvent *eventPtr, Tk_Window tkwin, int numObjects, ClientData *objectPtr); /* 6 */ void (*tk_CanvasDrawableCoords) (Tk_Canvas canvas, double x, double y, short *drawableXPtr, short *drawableYPtr); /* 7 */ void (*tk_CanvasEventuallyRedraw) (Tk_Canvas canvas, int x1, int y1, int x2, int y2); /* 8 */ - int (*tk_CanvasGetCoord) (Tcl_Interp *interp, Tk_Canvas canvas, CONST char *str, double *doublePtr); /* 9 */ + int (*tk_CanvasGetCoord) (Tcl_Interp *interp, Tk_Canvas canvas, const char *str, double *doublePtr); /* 9 */ Tk_CanvasTextInfo * (*tk_CanvasGetTextInfo) (Tk_Canvas canvas); /* 10 */ int (*tk_CanvasPsBitmap) (Tcl_Interp *interp, Tk_Canvas canvas, Pixmap bitmap, int x, int y, int width, int height); /* 11 */ int (*tk_CanvasPsColor) (Tcl_Interp *interp, Tk_Canvas canvas, XColor *colorPtr); /* 12 */ @@ -1714,53 +894,53 @@ typedef struct TkStubs { int (*tk_CanvasPsStipple) (Tcl_Interp *interp, Tk_Canvas canvas, Pixmap bitmap); /* 15 */ double (*tk_CanvasPsY) (Tk_Canvas canvas, double y); /* 16 */ void (*tk_CanvasSetStippleOrigin) (Tk_Canvas canvas, GC gc); /* 17 */ - int (*tk_CanvasTagsParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, CONST char *value, char *widgRec, int offset); /* 18 */ - char * (*tk_CanvasTagsPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 19 */ + int (*tk_CanvasTagsParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 18 */ + CONST86 char * (*tk_CanvasTagsPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 19 */ Tk_Window (*tk_CanvasTkwin) (Tk_Canvas canvas); /* 20 */ void (*tk_CanvasWindowCoords) (Tk_Canvas canvas, double x, double y, short *screenXPtr, short *screenYPtr); /* 21 */ void (*tk_ChangeWindowAttributes) (Tk_Window tkwin, unsigned long valueMask, XSetWindowAttributes *attsPtr); /* 22 */ int (*tk_CharBbox) (Tk_TextLayout layout, int index, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr); /* 23 */ void (*tk_ClearSelection) (Tk_Window tkwin, Atom selection); /* 24 */ - int (*tk_ClipboardAppend) (Tcl_Interp *interp, Tk_Window tkwin, Atom target, Atom format, char *buffer); /* 25 */ + int (*tk_ClipboardAppend) (Tcl_Interp *interp, Tk_Window tkwin, Atom target, Atom format, const char *buffer); /* 25 */ int (*tk_ClipboardClear) (Tcl_Interp *interp, Tk_Window tkwin); /* 26 */ - int (*tk_ConfigureInfo) (Tcl_Interp *interp, Tk_Window tkwin, Tk_ConfigSpec *specs, char *widgRec, CONST char *argvName, int flags); /* 27 */ - int (*tk_ConfigureValue) (Tcl_Interp *interp, Tk_Window tkwin, Tk_ConfigSpec *specs, char *widgRec, CONST char *argvName, int flags); /* 28 */ - int (*tk_ConfigureWidget) (Tcl_Interp *interp, Tk_Window tkwin, Tk_ConfigSpec *specs, int argc, CONST84 char **argv, char *widgRec, int flags); /* 29 */ + int (*tk_ConfigureInfo) (Tcl_Interp *interp, Tk_Window tkwin, const Tk_ConfigSpec *specs, char *widgRec, const char *argvName, int flags); /* 27 */ + int (*tk_ConfigureValue) (Tcl_Interp *interp, Tk_Window tkwin, const Tk_ConfigSpec *specs, char *widgRec, const char *argvName, int flags); /* 28 */ + int (*tk_ConfigureWidget) (Tcl_Interp *interp, Tk_Window tkwin, const Tk_ConfigSpec *specs, int argc, CONST84 char **argv, char *widgRec, int flags); /* 29 */ void (*tk_ConfigureWindow) (Tk_Window tkwin, unsigned int valueMask, XWindowChanges *valuePtr); /* 30 */ - Tk_TextLayout (*tk_ComputeTextLayout) (Tk_Font font, CONST char *str, int numChars, int wrapLength, Tk_Justify justify, int flags, int *widthPtr, int *heightPtr); /* 31 */ + Tk_TextLayout (*tk_ComputeTextLayout) (Tk_Font font, const char *str, int numChars, int wrapLength, Tk_Justify justify, int flags, int *widthPtr, int *heightPtr); /* 31 */ Tk_Window (*tk_CoordsToWindow) (int rootX, int rootY, Tk_Window tkwin); /* 32 */ - unsigned long (*tk_CreateBinding) (Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object, CONST char *eventStr, CONST char *command, int append); /* 33 */ + unsigned long (*tk_CreateBinding) (Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object, const char *eventStr, const char *script, int append); /* 33 */ Tk_BindingTable (*tk_CreateBindingTable) (Tcl_Interp *interp); /* 34 */ Tk_ErrorHandler (*tk_CreateErrorHandler) (Display *display, int errNum, int request, int minorCode, Tk_ErrorProc *errorProc, ClientData clientData); /* 35 */ void (*tk_CreateEventHandler) (Tk_Window token, unsigned long mask, Tk_EventProc *proc, ClientData clientData); /* 36 */ void (*tk_CreateGenericHandler) (Tk_GenericProc *proc, ClientData clientData); /* 37 */ - void (*tk_CreateImageType) (Tk_ImageType *typePtr); /* 38 */ + void (*tk_CreateImageType) (const Tk_ImageType *typePtr); /* 38 */ void (*tk_CreateItemType) (Tk_ItemType *typePtr); /* 39 */ - void (*tk_CreatePhotoImageFormat) (Tk_PhotoImageFormat *formatPtr); /* 40 */ + void (*tk_CreatePhotoImageFormat) (const Tk_PhotoImageFormat *formatPtr); /* 40 */ void (*tk_CreateSelHandler) (Tk_Window tkwin, Atom selection, Atom target, Tk_SelectionProc *proc, ClientData clientData, Atom format); /* 41 */ - Tk_Window (*tk_CreateWindow) (Tcl_Interp *interp, Tk_Window parent, CONST char *name, CONST char *screenName); /* 42 */ - Tk_Window (*tk_CreateWindowFromPath) (Tcl_Interp *interp, Tk_Window tkwin, CONST char *pathName, CONST char *screenName); /* 43 */ - int (*tk_DefineBitmap) (Tcl_Interp *interp, CONST char *name, CONST char *source, int width, int height); /* 44 */ + Tk_Window (*tk_CreateWindow) (Tcl_Interp *interp, Tk_Window parent, const char *name, const char *screenName); /* 42 */ + Tk_Window (*tk_CreateWindowFromPath) (Tcl_Interp *interp, Tk_Window tkwin, const char *pathName, const char *screenName); /* 43 */ + int (*tk_DefineBitmap) (Tcl_Interp *interp, const char *name, const void *source, int width, int height); /* 44 */ void (*tk_DefineCursor) (Tk_Window window, Tk_Cursor cursor); /* 45 */ void (*tk_DeleteAllBindings) (Tk_BindingTable bindingTable, ClientData object); /* 46 */ - int (*tk_DeleteBinding) (Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object, CONST char *eventStr); /* 47 */ + int (*tk_DeleteBinding) (Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object, const char *eventStr); /* 47 */ void (*tk_DeleteBindingTable) (Tk_BindingTable bindingTable); /* 48 */ void (*tk_DeleteErrorHandler) (Tk_ErrorHandler handler); /* 49 */ void (*tk_DeleteEventHandler) (Tk_Window token, unsigned long mask, Tk_EventProc *proc, ClientData clientData); /* 50 */ void (*tk_DeleteGenericHandler) (Tk_GenericProc *proc, ClientData clientData); /* 51 */ - void (*tk_DeleteImage) (Tcl_Interp *interp, CONST char *name); /* 52 */ + void (*tk_DeleteImage) (Tcl_Interp *interp, const char *name); /* 52 */ void (*tk_DeleteSelHandler) (Tk_Window tkwin, Atom selection, Atom target); /* 53 */ void (*tk_DestroyWindow) (Tk_Window tkwin); /* 54 */ CONST84_RETURN char * (*tk_DisplayName) (Tk_Window tkwin); /* 55 */ int (*tk_DistanceToTextLayout) (Tk_TextLayout layout, int x, int y); /* 56 */ void (*tk_Draw3DPolygon) (Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, XPoint *pointPtr, int numPoints, int borderWidth, int leftRelief); /* 57 */ void (*tk_Draw3DRectangle) (Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, int x, int y, int width, int height, int borderWidth, int relief); /* 58 */ - void (*tk_DrawChars) (Display *display, Drawable drawable, GC gc, Tk_Font tkfont, CONST char *source, int numBytes, int x, int y); /* 59 */ + void (*tk_DrawChars) (Display *display, Drawable drawable, GC gc, Tk_Font tkfont, const char *source, int numBytes, int x, int y); /* 59 */ void (*tk_DrawFocusHighlight) (Tk_Window tkwin, GC gc, int width, Drawable drawable); /* 60 */ void (*tk_DrawTextLayout) (Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, int firstChar, int lastChar); /* 61 */ void (*tk_Fill3DPolygon) (Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, XPoint *pointPtr, int numPoints, int borderWidth, int leftRelief); /* 62 */ void (*tk_Fill3DRectangle) (Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, int x, int y, int width, int height, int borderWidth, int relief); /* 63 */ - Tk_PhotoHandle (*tk_FindPhoto) (Tcl_Interp *interp, CONST char *imageName); /* 64 */ + Tk_PhotoHandle (*tk_FindPhoto) (Tcl_Interp *interp, const char *imageName); /* 64 */ Font (*tk_FontId) (Tk_Font font); /* 65 */ void (*tk_Free3DBorder) (Tk_3DBorder border); /* 66 */ void (*tk_FreeBitmap) (Display *display, Pixmap bitmap); /* 67 */ @@ -1770,7 +950,7 @@ typedef struct TkStubs { void (*tk_FreeFont) (Tk_Font f); /* 71 */ void (*tk_FreeGC) (Display *display, GC gc); /* 72 */ void (*tk_FreeImage) (Tk_Image image); /* 73 */ - void (*tk_FreeOptions) (Tk_ConfigSpec *specs, char *widgRec, Display *display, int needFlags); /* 74 */ + void (*tk_FreeOptions) (const Tk_ConfigSpec *specs, char *widgRec, Display *display, int needFlags); /* 74 */ void (*tk_FreePixmap) (Display *display, Pixmap pixmap); /* 75 */ void (*tk_FreeTextLayout) (Tk_TextLayout textLayout); /* 76 */ void (*tk_FreeXId) (Display *display, XID xid); /* 77 */ @@ -1778,51 +958,51 @@ typedef struct TkStubs { void (*tk_GeometryRequest) (Tk_Window tkwin, int reqWidth, int reqHeight); /* 79 */ Tk_3DBorder (*tk_Get3DBorder) (Tcl_Interp *interp, Tk_Window tkwin, Tk_Uid colorName); /* 80 */ void (*tk_GetAllBindings) (Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object); /* 81 */ - int (*tk_GetAnchor) (Tcl_Interp *interp, CONST char *str, Tk_Anchor *anchorPtr); /* 82 */ + int (*tk_GetAnchor) (Tcl_Interp *interp, const char *str, Tk_Anchor *anchorPtr); /* 82 */ CONST84_RETURN char * (*tk_GetAtomName) (Tk_Window tkwin, Atom atom); /* 83 */ - CONST84_RETURN char * (*tk_GetBinding) (Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object, CONST char *eventStr); /* 84 */ - Pixmap (*tk_GetBitmap) (Tcl_Interp *interp, Tk_Window tkwin, CONST char *str); /* 85 */ - Pixmap (*tk_GetBitmapFromData) (Tcl_Interp *interp, Tk_Window tkwin, CONST char *source, int width, int height); /* 86 */ - int (*tk_GetCapStyle) (Tcl_Interp *interp, CONST char *str, int *capPtr); /* 87 */ + CONST84_RETURN char * (*tk_GetBinding) (Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object, const char *eventStr); /* 84 */ + Pixmap (*tk_GetBitmap) (Tcl_Interp *interp, Tk_Window tkwin, const char *str); /* 85 */ + Pixmap (*tk_GetBitmapFromData) (Tcl_Interp *interp, Tk_Window tkwin, const void *source, int width, int height); /* 86 */ + int (*tk_GetCapStyle) (Tcl_Interp *interp, const char *str, int *capPtr); /* 87 */ XColor * (*tk_GetColor) (Tcl_Interp *interp, Tk_Window tkwin, Tk_Uid name); /* 88 */ XColor * (*tk_GetColorByValue) (Tk_Window tkwin, XColor *colorPtr); /* 89 */ - Colormap (*tk_GetColormap) (Tcl_Interp *interp, Tk_Window tkwin, CONST char *str); /* 90 */ + Colormap (*tk_GetColormap) (Tcl_Interp *interp, Tk_Window tkwin, const char *str); /* 90 */ Tk_Cursor (*tk_GetCursor) (Tcl_Interp *interp, Tk_Window tkwin, Tk_Uid str); /* 91 */ - Tk_Cursor (*tk_GetCursorFromData) (Tcl_Interp *interp, Tk_Window tkwin, CONST char *source, CONST char *mask, int width, int height, int xHot, int yHot, Tk_Uid fg, Tk_Uid bg); /* 92 */ - Tk_Font (*tk_GetFont) (Tcl_Interp *interp, Tk_Window tkwin, CONST char *str); /* 93 */ + Tk_Cursor (*tk_GetCursorFromData) (Tcl_Interp *interp, Tk_Window tkwin, const char *source, const char *mask, int width, int height, int xHot, int yHot, Tk_Uid fg, Tk_Uid bg); /* 92 */ + Tk_Font (*tk_GetFont) (Tcl_Interp *interp, Tk_Window tkwin, const char *str); /* 93 */ Tk_Font (*tk_GetFontFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 94 */ void (*tk_GetFontMetrics) (Tk_Font font, Tk_FontMetrics *fmPtr); /* 95 */ GC (*tk_GetGC) (Tk_Window tkwin, unsigned long valueMask, XGCValues *valuePtr); /* 96 */ - Tk_Image (*tk_GetImage) (Tcl_Interp *interp, Tk_Window tkwin, CONST char *name, Tk_ImageChangedProc *changeProc, ClientData clientData); /* 97 */ - ClientData (*tk_GetImageMasterData) (Tcl_Interp *interp, CONST char *name, Tk_ImageType **typePtrPtr); /* 98 */ + Tk_Image (*tk_GetImage) (Tcl_Interp *interp, Tk_Window tkwin, const char *name, Tk_ImageChangedProc *changeProc, ClientData clientData); /* 97 */ + ClientData (*tk_GetImageMasterData) (Tcl_Interp *interp, const char *name, CONST86 Tk_ImageType **typePtrPtr); /* 98 */ Tk_ItemType * (*tk_GetItemTypes) (void); /* 99 */ - int (*tk_GetJoinStyle) (Tcl_Interp *interp, CONST char *str, int *joinPtr); /* 100 */ - int (*tk_GetJustify) (Tcl_Interp *interp, CONST char *str, Tk_Justify *justifyPtr); /* 101 */ + int (*tk_GetJoinStyle) (Tcl_Interp *interp, const char *str, int *joinPtr); /* 100 */ + int (*tk_GetJustify) (Tcl_Interp *interp, const char *str, Tk_Justify *justifyPtr); /* 101 */ int (*tk_GetNumMainWindows) (void); /* 102 */ - Tk_Uid (*tk_GetOption) (Tk_Window tkwin, CONST char *name, CONST char *className); /* 103 */ - int (*tk_GetPixels) (Tcl_Interp *interp, Tk_Window tkwin, CONST char *str, int *intPtr); /* 104 */ + Tk_Uid (*tk_GetOption) (Tk_Window tkwin, const char *name, const char *className); /* 103 */ + int (*tk_GetPixels) (Tcl_Interp *interp, Tk_Window tkwin, const char *str, int *intPtr); /* 104 */ Pixmap (*tk_GetPixmap) (Display *display, Drawable d, int width, int height, int depth); /* 105 */ - int (*tk_GetRelief) (Tcl_Interp *interp, CONST char *name, int *reliefPtr); /* 106 */ + int (*tk_GetRelief) (Tcl_Interp *interp, const char *name, int *reliefPtr); /* 106 */ void (*tk_GetRootCoords) (Tk_Window tkwin, int *xPtr, int *yPtr); /* 107 */ int (*tk_GetScrollInfo) (Tcl_Interp *interp, int argc, CONST84 char **argv, double *dblPtr, int *intPtr); /* 108 */ - int (*tk_GetScreenMM) (Tcl_Interp *interp, Tk_Window tkwin, CONST char *str, double *doublePtr); /* 109 */ + int (*tk_GetScreenMM) (Tcl_Interp *interp, Tk_Window tkwin, const char *str, double *doublePtr); /* 109 */ int (*tk_GetSelection) (Tcl_Interp *interp, Tk_Window tkwin, Atom selection, Atom target, Tk_GetSelProc *proc, ClientData clientData); /* 110 */ - Tk_Uid (*tk_GetUid) (CONST char *str); /* 111 */ - Visual * (*tk_GetVisual) (Tcl_Interp *interp, Tk_Window tkwin, CONST char *str, int *depthPtr, Colormap *colormapPtr); /* 112 */ + Tk_Uid (*tk_GetUid) (const char *str); /* 111 */ + Visual * (*tk_GetVisual) (Tcl_Interp *interp, Tk_Window tkwin, const char *str, int *depthPtr, Colormap *colormapPtr); /* 112 */ void (*tk_GetVRootGeometry) (Tk_Window tkwin, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr); /* 113 */ int (*tk_Grab) (Tcl_Interp *interp, Tk_Window tkwin, int grabGlobal); /* 114 */ void (*tk_HandleEvent) (XEvent *eventPtr); /* 115 */ Tk_Window (*tk_IdToWindow) (Display *display, Window window); /* 116 */ void (*tk_ImageChanged) (Tk_ImageMaster master, int x, int y, int width, int height, int imageWidth, int imageHeight); /* 117 */ int (*tk_Init) (Tcl_Interp *interp); /* 118 */ - Atom (*tk_InternAtom) (Tk_Window tkwin, CONST char *name); /* 119 */ + Atom (*tk_InternAtom) (Tk_Window tkwin, const char *name); /* 119 */ int (*tk_IntersectTextLayout) (Tk_TextLayout layout, int x, int y, int width, int height); /* 120 */ void (*tk_MaintainGeometry) (Tk_Window slave, Tk_Window master, int x, int y, int width, int height); /* 121 */ Tk_Window (*tk_MainWindow) (Tcl_Interp *interp); /* 122 */ void (*tk_MakeWindowExist) (Tk_Window tkwin); /* 123 */ - void (*tk_ManageGeometry) (Tk_Window tkwin, CONST Tk_GeomMgr *mgrPtr, ClientData clientData); /* 124 */ + void (*tk_ManageGeometry) (Tk_Window tkwin, const Tk_GeomMgr *mgrPtr, ClientData clientData); /* 124 */ void (*tk_MapWindow) (Tk_Window tkwin); /* 125 */ - int (*tk_MeasureChars) (Tk_Font tkfont, CONST char *source, int numBytes, int maxPixels, int flags, int *lengthPtr); /* 126 */ + int (*tk_MeasureChars) (Tk_Font tkfont, const char *source, int numBytes, int maxPixels, int flags, int *lengthPtr); /* 126 */ void (*tk_MoveResizeWindow) (Tk_Window tkwin, int x, int y, int width, int height); /* 127 */ void (*tk_MoveWindow) (Tk_Window tkwin, int x, int y); /* 128 */ void (*tk_MoveToplevelWindow) (Tk_Window tkwin, int x, int y); /* 129 */ @@ -1837,9 +1017,9 @@ typedef struct TkStubs { CONST84_RETURN char * (*tk_NameOfJoinStyle) (int join); /* 138 */ CONST84_RETURN char * (*tk_NameOfJustify) (Tk_Justify justify); /* 139 */ CONST84_RETURN char * (*tk_NameOfRelief) (int relief); /* 140 */ - Tk_Window (*tk_NameToWindow) (Tcl_Interp *interp, CONST char *pathName, Tk_Window tkwin); /* 141 */ + Tk_Window (*tk_NameToWindow) (Tcl_Interp *interp, const char *pathName, Tk_Window tkwin); /* 141 */ void (*tk_OwnSelection) (Tk_Window tkwin, Atom selection, Tk_LostSelProc *proc, ClientData clientData); /* 142 */ - int (*tk_ParseArgv) (Tcl_Interp *interp, Tk_Window tkwin, int *argcPtr, CONST84 char **argv, Tk_ArgvInfo *argTable, int flags); /* 143 */ + int (*tk_ParseArgv) (Tcl_Interp *interp, Tk_Window tkwin, int *argcPtr, CONST84 char **argv, const Tk_ArgvInfo *argTable, int flags); /* 143 */ void (*tk_PhotoPutBlock_NoComposite) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height); /* 144 */ void (*tk_PhotoPutZoomedBlock_NoComposite) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY); /* 145 */ int (*tk_PhotoGetImage) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr); /* 146 */ @@ -1856,9 +1036,9 @@ typedef struct TkStubs { int (*tk_RestackWindow) (Tk_Window tkwin, int aboveBelow, Tk_Window other); /* 157 */ Tk_RestrictProc * (*tk_RestrictEvents) (Tk_RestrictProc *proc, ClientData arg, ClientData *prevArgPtr); /* 158 */ int (*tk_SafeInit) (Tcl_Interp *interp); /* 159 */ - CONST char * (*tk_SetAppName) (Tk_Window tkwin, CONST char *name); /* 160 */ + const char * (*tk_SetAppName) (Tk_Window tkwin, const char *name); /* 160 */ void (*tk_SetBackgroundFromBorder) (Tk_Window tkwin, Tk_3DBorder border); /* 161 */ - void (*tk_SetClass) (Tk_Window tkwin, CONST char *className); /* 162 */ + void (*tk_SetClass) (Tk_Window tkwin, const char *className); /* 162 */ void (*tk_SetGrid) (Tk_Window tkwin, int reqWidth, int reqHeight, int gridWidth, int gridHeight); /* 163 */ void (*tk_SetInternalBorder) (Tk_Window tkwin, int width); /* 164 */ void (*tk_SetWindowBackground) (Tk_Window tkwin, unsigned long pixel); /* 165 */ @@ -1872,9 +1052,9 @@ typedef struct TkStubs { void (*tk_SizeOfImage) (Tk_Image image, int *widthPtr, int *heightPtr); /* 173 */ int (*tk_StrictMotif) (Tk_Window tkwin); /* 174 */ void (*tk_TextLayoutToPostscript) (Tcl_Interp *interp, Tk_TextLayout layout); /* 175 */ - int (*tk_TextWidth) (Tk_Font font, CONST char *str, int numBytes); /* 176 */ + int (*tk_TextWidth) (Tk_Font font, const char *str, int numBytes); /* 176 */ void (*tk_UndefineCursor) (Tk_Window window); /* 177 */ - void (*tk_UnderlineChars) (Display *display, Drawable drawable, GC gc, Tk_Font tkfont, CONST char *source, int x, int y, int firstByte, int lastByte); /* 178 */ + void (*tk_UnderlineChars) (Display *display, Drawable drawable, GC gc, Tk_Font tkfont, const char *source, int x, int y, int firstByte, int lastByte); /* 178 */ void (*tk_UnderlineTextLayout) (Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, int underline); /* 179 */ void (*tk_Ungrab) (Tk_Window tkwin); /* 180 */ void (*tk_UnmaintainGeometry) (Tk_Window slave, Tk_Window master); /* 181 */ @@ -1886,7 +1066,7 @@ typedef struct TkStubs { XColor * (*tk_AllocColorFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr); /* 187 */ Tk_Cursor (*tk_AllocCursorFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr); /* 188 */ Tk_Font (*tk_AllocFontFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr); /* 189 */ - Tk_OptionTable (*tk_CreateOptionTable) (Tcl_Interp *interp, CONST Tk_OptionSpec *templatePtr); /* 190 */ + Tk_OptionTable (*tk_CreateOptionTable) (Tcl_Interp *interp, const Tk_OptionSpec *templatePtr); /* 190 */ void (*tk_DeleteOptionTable) (Tk_OptionTable optionTable); /* 191 */ void (*tk_Free3DBorderFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 192 */ void (*tk_FreeBitmapFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 193 */ @@ -1906,17 +1086,17 @@ typedef struct TkStubs { int (*tk_GetMMFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, double *doublePtr); /* 207 */ int (*tk_GetPixelsFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, int *intPtr); /* 208 */ int (*tk_GetReliefFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int *resultPtr); /* 209 */ - int (*tk_GetScrollInfoObj) (Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], double *dblPtr, int *intPtr); /* 210 */ + int (*tk_GetScrollInfoObj) (Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], double *dblPtr, int *intPtr); /* 210 */ int (*tk_InitOptions) (Tcl_Interp *interp, char *recordPtr, Tk_OptionTable optionToken, Tk_Window tkwin); /* 211 */ void (*tk_MainEx) (int argc, char **argv, Tcl_AppInitProc *appInitProc, Tcl_Interp *interp); /* 212 */ void (*tk_RestoreSavedOptions) (Tk_SavedOptions *savePtr); /* 213 */ - int (*tk_SetOptions) (Tcl_Interp *interp, char *recordPtr, Tk_OptionTable optionTable, int objc, Tcl_Obj *CONST objv[], Tk_Window tkwin, Tk_SavedOptions *savePtr, int *maskPtr); /* 214 */ + int (*tk_SetOptions) (Tcl_Interp *interp, char *recordPtr, Tk_OptionTable optionTable, int objc, Tcl_Obj *const objv[], Tk_Window tkwin, Tk_SavedOptions *savePtr, int *maskPtr); /* 214 */ void (*tk_InitConsoleChannels) (Tcl_Interp *interp); /* 215 */ int (*tk_CreateConsoleWindow) (Tcl_Interp *interp); /* 216 */ - void (*tk_CreateSmoothMethod) (Tcl_Interp *interp, Tk_SmoothMethod *method); /* 217 */ - VOID *reserved218; - VOID *reserved219; - int (*tk_GetDash) (Tcl_Interp *interp, CONST char *value, Tk_Dash *dash); /* 220 */ + void (*tk_CreateSmoothMethod) (Tcl_Interp *interp, const Tk_SmoothMethod *method); /* 217 */ + void (*reserved218)(void); + void (*reserved219)(void); + int (*tk_GetDash) (Tcl_Interp *interp, const char *value, Tk_Dash *dash); /* 220 */ void (*tk_CreateOutline) (Tk_Outline *outline); /* 221 */ void (*tk_DeleteOutline) (Display *display, Tk_Outline *outline); /* 222 */ int (*tk_ConfigOutlineGC) (XGCValues *gcValues, Tk_Canvas canvas, Tk_Item *item, Tk_Outline *outline); /* 223 */ @@ -1937,22 +1117,22 @@ typedef struct TkStubs { int (*tk_PostscriptPhoto) (Tcl_Interp *interp, Tk_PhotoImageBlock *blockPtr, Tk_PostscriptInfo psInfo, int width, int height); /* 238 */ void (*tk_CreateClientMessageHandler) (Tk_ClientMessageProc *proc); /* 239 */ void (*tk_DeleteClientMessageHandler) (Tk_ClientMessageProc *proc); /* 240 */ - Tk_Window (*tk_CreateAnonymousWindow) (Tcl_Interp *interp, Tk_Window parent, CONST char *screenName); /* 241 */ - void (*tk_SetClassProcs) (Tk_Window tkwin, Tk_ClassProcs *procs, ClientData instanceData); /* 242 */ + Tk_Window (*tk_CreateAnonymousWindow) (Tcl_Interp *interp, Tk_Window parent, const char *screenName); /* 241 */ + void (*tk_SetClassProcs) (Tk_Window tkwin, const Tk_ClassProcs *procs, ClientData instanceData); /* 242 */ void (*tk_SetInternalBorderEx) (Tk_Window tkwin, int left, int right, int top, int bottom); /* 243 */ void (*tk_SetMinimumRequestSize) (Tk_Window tkwin, int minWidth, int minHeight); /* 244 */ void (*tk_SetCaretPos) (Tk_Window tkwin, int x, int y, int height); /* 245 */ void (*tk_PhotoPutBlock_Panic) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int compRule); /* 246 */ void (*tk_PhotoPutZoomedBlock_Panic) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY, int compRule); /* 247 */ int (*tk_CollapseMotionEvents) (Display *display, int collapse); /* 248 */ - Tk_StyleEngine (*tk_RegisterStyleEngine) (CONST char *name, Tk_StyleEngine parent); /* 249 */ - Tk_StyleEngine (*tk_GetStyleEngine) (CONST char *name); /* 250 */ + Tk_StyleEngine (*tk_RegisterStyleEngine) (const char *name, Tk_StyleEngine parent); /* 249 */ + Tk_StyleEngine (*tk_GetStyleEngine) (const char *name); /* 250 */ int (*tk_RegisterStyledElement) (Tk_StyleEngine engine, Tk_ElementSpec *templatePtr); /* 251 */ - int (*tk_GetElementId) (CONST char *name); /* 252 */ - Tk_Style (*tk_CreateStyle) (CONST char *name, Tk_StyleEngine engine, ClientData clientData); /* 253 */ - Tk_Style (*tk_GetStyle) (Tcl_Interp *interp, CONST char *name); /* 254 */ + int (*tk_GetElementId) (const char *name); /* 252 */ + Tk_Style (*tk_CreateStyle) (const char *name, Tk_StyleEngine engine, ClientData clientData); /* 253 */ + Tk_Style (*tk_GetStyle) (Tcl_Interp *interp, const char *name); /* 254 */ void (*tk_FreeStyle) (Tk_Style style); /* 255 */ - CONST char * (*tk_NameOfStyle) (Tk_Style style); /* 256 */ + const char * (*tk_NameOfStyle) (Tk_Style style); /* 256 */ Tk_Style (*tk_AllocStyleFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr); /* 257 */ Tk_Style (*tk_GetStyleFromObj) (Tcl_Obj *objPtr); /* 258 */ void (*tk_FreeStyleFromObj) (Tcl_Obj *objPtr); /* 259 */ @@ -1968,1128 +1148,586 @@ typedef struct TkStubs { long (*tk_GetUserInactiveTime) (Display *dpy); /* 269 */ void (*tk_ResetUserInactiveTime) (Display *dpy); /* 270 */ Tcl_Interp * (*tk_Interp) (Tk_Window tkwin); /* 271 */ - void (*tk_CreateOldImageType) (Tk_ImageType *typePtr); /* 272 */ - void (*tk_CreateOldPhotoImageFormat) (Tk_PhotoImageFormat *formatPtr); /* 273 */ - VOID *reserved274; - void (*tkUnusedStubEntry) (void); /* 275 */ + void (*tk_CreateOldImageType) (const Tk_ImageType *typePtr); /* 272 */ + void (*tk_CreateOldPhotoImageFormat) (const Tk_PhotoImageFormat *formatPtr); /* 273 */ } TkStubs; -extern TkStubs *tkStubsPtr; +extern const TkStubs *tkStubsPtr; #ifdef __cplusplus } #endif -#if defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS) +#if defined(USE_TK_STUBS) /* * Inline function declarations: */ -#ifndef Tk_MainLoop #define Tk_MainLoop \ (tkStubsPtr->tk_MainLoop) /* 0 */ -#endif -#ifndef Tk_3DBorderColor #define Tk_3DBorderColor \ (tkStubsPtr->tk_3DBorderColor) /* 1 */ -#endif -#ifndef Tk_3DBorderGC #define Tk_3DBorderGC \ (tkStubsPtr->tk_3DBorderGC) /* 2 */ -#endif -#ifndef Tk_3DHorizontalBevel #define Tk_3DHorizontalBevel \ (tkStubsPtr->tk_3DHorizontalBevel) /* 3 */ -#endif -#ifndef Tk_3DVerticalBevel #define Tk_3DVerticalBevel \ (tkStubsPtr->tk_3DVerticalBevel) /* 4 */ -#endif -#ifndef Tk_AddOption #define Tk_AddOption \ (tkStubsPtr->tk_AddOption) /* 5 */ -#endif -#ifndef Tk_BindEvent #define Tk_BindEvent \ (tkStubsPtr->tk_BindEvent) /* 6 */ -#endif -#ifndef Tk_CanvasDrawableCoords #define Tk_CanvasDrawableCoords \ (tkStubsPtr->tk_CanvasDrawableCoords) /* 7 */ -#endif -#ifndef Tk_CanvasEventuallyRedraw #define Tk_CanvasEventuallyRedraw \ (tkStubsPtr->tk_CanvasEventuallyRedraw) /* 8 */ -#endif -#ifndef Tk_CanvasGetCoord #define Tk_CanvasGetCoord \ (tkStubsPtr->tk_CanvasGetCoord) /* 9 */ -#endif -#ifndef Tk_CanvasGetTextInfo #define Tk_CanvasGetTextInfo \ (tkStubsPtr->tk_CanvasGetTextInfo) /* 10 */ -#endif -#ifndef Tk_CanvasPsBitmap #define Tk_CanvasPsBitmap \ (tkStubsPtr->tk_CanvasPsBitmap) /* 11 */ -#endif -#ifndef Tk_CanvasPsColor #define Tk_CanvasPsColor \ (tkStubsPtr->tk_CanvasPsColor) /* 12 */ -#endif -#ifndef Tk_CanvasPsFont #define Tk_CanvasPsFont \ (tkStubsPtr->tk_CanvasPsFont) /* 13 */ -#endif -#ifndef Tk_CanvasPsPath #define Tk_CanvasPsPath \ (tkStubsPtr->tk_CanvasPsPath) /* 14 */ -#endif -#ifndef Tk_CanvasPsStipple #define Tk_CanvasPsStipple \ (tkStubsPtr->tk_CanvasPsStipple) /* 15 */ -#endif -#ifndef Tk_CanvasPsY #define Tk_CanvasPsY \ (tkStubsPtr->tk_CanvasPsY) /* 16 */ -#endif -#ifndef Tk_CanvasSetStippleOrigin #define Tk_CanvasSetStippleOrigin \ (tkStubsPtr->tk_CanvasSetStippleOrigin) /* 17 */ -#endif -#ifndef Tk_CanvasTagsParseProc #define Tk_CanvasTagsParseProc \ (tkStubsPtr->tk_CanvasTagsParseProc) /* 18 */ -#endif -#ifndef Tk_CanvasTagsPrintProc #define Tk_CanvasTagsPrintProc \ (tkStubsPtr->tk_CanvasTagsPrintProc) /* 19 */ -#endif -#ifndef Tk_CanvasTkwin #define Tk_CanvasTkwin \ (tkStubsPtr->tk_CanvasTkwin) /* 20 */ -#endif -#ifndef Tk_CanvasWindowCoords #define Tk_CanvasWindowCoords \ (tkStubsPtr->tk_CanvasWindowCoords) /* 21 */ -#endif -#ifndef Tk_ChangeWindowAttributes #define Tk_ChangeWindowAttributes \ (tkStubsPtr->tk_ChangeWindowAttributes) /* 22 */ -#endif -#ifndef Tk_CharBbox #define Tk_CharBbox \ (tkStubsPtr->tk_CharBbox) /* 23 */ -#endif -#ifndef Tk_ClearSelection #define Tk_ClearSelection \ (tkStubsPtr->tk_ClearSelection) /* 24 */ -#endif -#ifndef Tk_ClipboardAppend #define Tk_ClipboardAppend \ (tkStubsPtr->tk_ClipboardAppend) /* 25 */ -#endif -#ifndef Tk_ClipboardClear #define Tk_ClipboardClear \ (tkStubsPtr->tk_ClipboardClear) /* 26 */ -#endif -#ifndef Tk_ConfigureInfo #define Tk_ConfigureInfo \ (tkStubsPtr->tk_ConfigureInfo) /* 27 */ -#endif -#ifndef Tk_ConfigureValue #define Tk_ConfigureValue \ (tkStubsPtr->tk_ConfigureValue) /* 28 */ -#endif -#ifndef Tk_ConfigureWidget #define Tk_ConfigureWidget \ (tkStubsPtr->tk_ConfigureWidget) /* 29 */ -#endif -#ifndef Tk_ConfigureWindow #define Tk_ConfigureWindow \ (tkStubsPtr->tk_ConfigureWindow) /* 30 */ -#endif -#ifndef Tk_ComputeTextLayout #define Tk_ComputeTextLayout \ (tkStubsPtr->tk_ComputeTextLayout) /* 31 */ -#endif -#ifndef Tk_CoordsToWindow #define Tk_CoordsToWindow \ (tkStubsPtr->tk_CoordsToWindow) /* 32 */ -#endif -#ifndef Tk_CreateBinding #define Tk_CreateBinding \ (tkStubsPtr->tk_CreateBinding) /* 33 */ -#endif -#ifndef Tk_CreateBindingTable #define Tk_CreateBindingTable \ (tkStubsPtr->tk_CreateBindingTable) /* 34 */ -#endif -#ifndef Tk_CreateErrorHandler #define Tk_CreateErrorHandler \ (tkStubsPtr->tk_CreateErrorHandler) /* 35 */ -#endif -#ifndef Tk_CreateEventHandler #define Tk_CreateEventHandler \ (tkStubsPtr->tk_CreateEventHandler) /* 36 */ -#endif -#ifndef Tk_CreateGenericHandler #define Tk_CreateGenericHandler \ (tkStubsPtr->tk_CreateGenericHandler) /* 37 */ -#endif -#ifndef Tk_CreateImageType #define Tk_CreateImageType \ (tkStubsPtr->tk_CreateImageType) /* 38 */ -#endif -#ifndef Tk_CreateItemType #define Tk_CreateItemType \ (tkStubsPtr->tk_CreateItemType) /* 39 */ -#endif -#ifndef Tk_CreatePhotoImageFormat #define Tk_CreatePhotoImageFormat \ (tkStubsPtr->tk_CreatePhotoImageFormat) /* 40 */ -#endif -#ifndef Tk_CreateSelHandler #define Tk_CreateSelHandler \ (tkStubsPtr->tk_CreateSelHandler) /* 41 */ -#endif -#ifndef Tk_CreateWindow #define Tk_CreateWindow \ (tkStubsPtr->tk_CreateWindow) /* 42 */ -#endif -#ifndef Tk_CreateWindowFromPath #define Tk_CreateWindowFromPath \ (tkStubsPtr->tk_CreateWindowFromPath) /* 43 */ -#endif -#ifndef Tk_DefineBitmap #define Tk_DefineBitmap \ (tkStubsPtr->tk_DefineBitmap) /* 44 */ -#endif -#ifndef Tk_DefineCursor #define Tk_DefineCursor \ (tkStubsPtr->tk_DefineCursor) /* 45 */ -#endif -#ifndef Tk_DeleteAllBindings #define Tk_DeleteAllBindings \ (tkStubsPtr->tk_DeleteAllBindings) /* 46 */ -#endif -#ifndef Tk_DeleteBinding #define Tk_DeleteBinding \ (tkStubsPtr->tk_DeleteBinding) /* 47 */ -#endif -#ifndef Tk_DeleteBindingTable #define Tk_DeleteBindingTable \ (tkStubsPtr->tk_DeleteBindingTable) /* 48 */ -#endif -#ifndef Tk_DeleteErrorHandler #define Tk_DeleteErrorHandler \ (tkStubsPtr->tk_DeleteErrorHandler) /* 49 */ -#endif -#ifndef Tk_DeleteEventHandler #define Tk_DeleteEventHandler \ (tkStubsPtr->tk_DeleteEventHandler) /* 50 */ -#endif -#ifndef Tk_DeleteGenericHandler #define Tk_DeleteGenericHandler \ (tkStubsPtr->tk_DeleteGenericHandler) /* 51 */ -#endif -#ifndef Tk_DeleteImage #define Tk_DeleteImage \ (tkStubsPtr->tk_DeleteImage) /* 52 */ -#endif -#ifndef Tk_DeleteSelHandler #define Tk_DeleteSelHandler \ (tkStubsPtr->tk_DeleteSelHandler) /* 53 */ -#endif -#ifndef Tk_DestroyWindow #define Tk_DestroyWindow \ (tkStubsPtr->tk_DestroyWindow) /* 54 */ -#endif -#ifndef Tk_DisplayName #define Tk_DisplayName \ (tkStubsPtr->tk_DisplayName) /* 55 */ -#endif -#ifndef Tk_DistanceToTextLayout #define Tk_DistanceToTextLayout \ (tkStubsPtr->tk_DistanceToTextLayout) /* 56 */ -#endif -#ifndef Tk_Draw3DPolygon #define Tk_Draw3DPolygon \ (tkStubsPtr->tk_Draw3DPolygon) /* 57 */ -#endif -#ifndef Tk_Draw3DRectangle #define Tk_Draw3DRectangle \ (tkStubsPtr->tk_Draw3DRectangle) /* 58 */ -#endif -#ifndef Tk_DrawChars #define Tk_DrawChars \ (tkStubsPtr->tk_DrawChars) /* 59 */ -#endif -#ifndef Tk_DrawFocusHighlight #define Tk_DrawFocusHighlight \ (tkStubsPtr->tk_DrawFocusHighlight) /* 60 */ -#endif -#ifndef Tk_DrawTextLayout #define Tk_DrawTextLayout \ (tkStubsPtr->tk_DrawTextLayout) /* 61 */ -#endif -#ifndef Tk_Fill3DPolygon #define Tk_Fill3DPolygon \ (tkStubsPtr->tk_Fill3DPolygon) /* 62 */ -#endif -#ifndef Tk_Fill3DRectangle #define Tk_Fill3DRectangle \ (tkStubsPtr->tk_Fill3DRectangle) /* 63 */ -#endif -#ifndef Tk_FindPhoto #define Tk_FindPhoto \ (tkStubsPtr->tk_FindPhoto) /* 64 */ -#endif -#ifndef Tk_FontId #define Tk_FontId \ (tkStubsPtr->tk_FontId) /* 65 */ -#endif -#ifndef Tk_Free3DBorder #define Tk_Free3DBorder \ (tkStubsPtr->tk_Free3DBorder) /* 66 */ -#endif -#ifndef Tk_FreeBitmap #define Tk_FreeBitmap \ (tkStubsPtr->tk_FreeBitmap) /* 67 */ -#endif -#ifndef Tk_FreeColor #define Tk_FreeColor \ (tkStubsPtr->tk_FreeColor) /* 68 */ -#endif -#ifndef Tk_FreeColormap #define Tk_FreeColormap \ (tkStubsPtr->tk_FreeColormap) /* 69 */ -#endif -#ifndef Tk_FreeCursor #define Tk_FreeCursor \ (tkStubsPtr->tk_FreeCursor) /* 70 */ -#endif -#ifndef Tk_FreeFont #define Tk_FreeFont \ (tkStubsPtr->tk_FreeFont) /* 71 */ -#endif -#ifndef Tk_FreeGC #define Tk_FreeGC \ (tkStubsPtr->tk_FreeGC) /* 72 */ -#endif -#ifndef Tk_FreeImage #define Tk_FreeImage \ (tkStubsPtr->tk_FreeImage) /* 73 */ -#endif -#ifndef Tk_FreeOptions #define Tk_FreeOptions \ (tkStubsPtr->tk_FreeOptions) /* 74 */ -#endif -#ifndef Tk_FreePixmap #define Tk_FreePixmap \ (tkStubsPtr->tk_FreePixmap) /* 75 */ -#endif -#ifndef Tk_FreeTextLayout #define Tk_FreeTextLayout \ (tkStubsPtr->tk_FreeTextLayout) /* 76 */ -#endif -#ifndef Tk_FreeXId #define Tk_FreeXId \ (tkStubsPtr->tk_FreeXId) /* 77 */ -#endif -#ifndef Tk_GCForColor #define Tk_GCForColor \ (tkStubsPtr->tk_GCForColor) /* 78 */ -#endif -#ifndef Tk_GeometryRequest #define Tk_GeometryRequest \ (tkStubsPtr->tk_GeometryRequest) /* 79 */ -#endif -#ifndef Tk_Get3DBorder #define Tk_Get3DBorder \ (tkStubsPtr->tk_Get3DBorder) /* 80 */ -#endif -#ifndef Tk_GetAllBindings #define Tk_GetAllBindings \ (tkStubsPtr->tk_GetAllBindings) /* 81 */ -#endif -#ifndef Tk_GetAnchor #define Tk_GetAnchor \ (tkStubsPtr->tk_GetAnchor) /* 82 */ -#endif -#ifndef Tk_GetAtomName #define Tk_GetAtomName \ (tkStubsPtr->tk_GetAtomName) /* 83 */ -#endif -#ifndef Tk_GetBinding #define Tk_GetBinding \ (tkStubsPtr->tk_GetBinding) /* 84 */ -#endif -#ifndef Tk_GetBitmap #define Tk_GetBitmap \ (tkStubsPtr->tk_GetBitmap) /* 85 */ -#endif -#ifndef Tk_GetBitmapFromData #define Tk_GetBitmapFromData \ (tkStubsPtr->tk_GetBitmapFromData) /* 86 */ -#endif -#ifndef Tk_GetCapStyle #define Tk_GetCapStyle \ (tkStubsPtr->tk_GetCapStyle) /* 87 */ -#endif -#ifndef Tk_GetColor #define Tk_GetColor \ (tkStubsPtr->tk_GetColor) /* 88 */ -#endif -#ifndef Tk_GetColorByValue #define Tk_GetColorByValue \ (tkStubsPtr->tk_GetColorByValue) /* 89 */ -#endif -#ifndef Tk_GetColormap #define Tk_GetColormap \ (tkStubsPtr->tk_GetColormap) /* 90 */ -#endif -#ifndef Tk_GetCursor #define Tk_GetCursor \ (tkStubsPtr->tk_GetCursor) /* 91 */ -#endif -#ifndef Tk_GetCursorFromData #define Tk_GetCursorFromData \ (tkStubsPtr->tk_GetCursorFromData) /* 92 */ -#endif -#ifndef Tk_GetFont #define Tk_GetFont \ (tkStubsPtr->tk_GetFont) /* 93 */ -#endif -#ifndef Tk_GetFontFromObj #define Tk_GetFontFromObj \ (tkStubsPtr->tk_GetFontFromObj) /* 94 */ -#endif -#ifndef Tk_GetFontMetrics #define Tk_GetFontMetrics \ (tkStubsPtr->tk_GetFontMetrics) /* 95 */ -#endif -#ifndef Tk_GetGC #define Tk_GetGC \ (tkStubsPtr->tk_GetGC) /* 96 */ -#endif -#ifndef Tk_GetImage #define Tk_GetImage \ (tkStubsPtr->tk_GetImage) /* 97 */ -#endif -#ifndef Tk_GetImageMasterData #define Tk_GetImageMasterData \ (tkStubsPtr->tk_GetImageMasterData) /* 98 */ -#endif -#ifndef Tk_GetItemTypes #define Tk_GetItemTypes \ (tkStubsPtr->tk_GetItemTypes) /* 99 */ -#endif -#ifndef Tk_GetJoinStyle #define Tk_GetJoinStyle \ (tkStubsPtr->tk_GetJoinStyle) /* 100 */ -#endif -#ifndef Tk_GetJustify #define Tk_GetJustify \ (tkStubsPtr->tk_GetJustify) /* 101 */ -#endif -#ifndef Tk_GetNumMainWindows #define Tk_GetNumMainWindows \ (tkStubsPtr->tk_GetNumMainWindows) /* 102 */ -#endif -#ifndef Tk_GetOption #define Tk_GetOption \ (tkStubsPtr->tk_GetOption) /* 103 */ -#endif -#ifndef Tk_GetPixels #define Tk_GetPixels \ (tkStubsPtr->tk_GetPixels) /* 104 */ -#endif -#ifndef Tk_GetPixmap #define Tk_GetPixmap \ (tkStubsPtr->tk_GetPixmap) /* 105 */ -#endif -#ifndef Tk_GetRelief #define Tk_GetRelief \ (tkStubsPtr->tk_GetRelief) /* 106 */ -#endif -#ifndef Tk_GetRootCoords #define Tk_GetRootCoords \ (tkStubsPtr->tk_GetRootCoords) /* 107 */ -#endif -#ifndef Tk_GetScrollInfo #define Tk_GetScrollInfo \ (tkStubsPtr->tk_GetScrollInfo) /* 108 */ -#endif -#ifndef Tk_GetScreenMM #define Tk_GetScreenMM \ (tkStubsPtr->tk_GetScreenMM) /* 109 */ -#endif -#ifndef Tk_GetSelection #define Tk_GetSelection \ (tkStubsPtr->tk_GetSelection) /* 110 */ -#endif -#ifndef Tk_GetUid #define Tk_GetUid \ (tkStubsPtr->tk_GetUid) /* 111 */ -#endif -#ifndef Tk_GetVisual #define Tk_GetVisual \ (tkStubsPtr->tk_GetVisual) /* 112 */ -#endif -#ifndef Tk_GetVRootGeometry #define Tk_GetVRootGeometry \ (tkStubsPtr->tk_GetVRootGeometry) /* 113 */ -#endif -#ifndef Tk_Grab #define Tk_Grab \ (tkStubsPtr->tk_Grab) /* 114 */ -#endif -#ifndef Tk_HandleEvent #define Tk_HandleEvent \ (tkStubsPtr->tk_HandleEvent) /* 115 */ -#endif -#ifndef Tk_IdToWindow #define Tk_IdToWindow \ (tkStubsPtr->tk_IdToWindow) /* 116 */ -#endif -#ifndef Tk_ImageChanged #define Tk_ImageChanged \ (tkStubsPtr->tk_ImageChanged) /* 117 */ -#endif -#ifndef Tk_Init #define Tk_Init \ (tkStubsPtr->tk_Init) /* 118 */ -#endif -#ifndef Tk_InternAtom #define Tk_InternAtom \ (tkStubsPtr->tk_InternAtom) /* 119 */ -#endif -#ifndef Tk_IntersectTextLayout #define Tk_IntersectTextLayout \ (tkStubsPtr->tk_IntersectTextLayout) /* 120 */ -#endif -#ifndef Tk_MaintainGeometry #define Tk_MaintainGeometry \ (tkStubsPtr->tk_MaintainGeometry) /* 121 */ -#endif -#ifndef Tk_MainWindow #define Tk_MainWindow \ (tkStubsPtr->tk_MainWindow) /* 122 */ -#endif -#ifndef Tk_MakeWindowExist #define Tk_MakeWindowExist \ (tkStubsPtr->tk_MakeWindowExist) /* 123 */ -#endif -#ifndef Tk_ManageGeometry #define Tk_ManageGeometry \ (tkStubsPtr->tk_ManageGeometry) /* 124 */ -#endif -#ifndef Tk_MapWindow #define Tk_MapWindow \ (tkStubsPtr->tk_MapWindow) /* 125 */ -#endif -#ifndef Tk_MeasureChars #define Tk_MeasureChars \ (tkStubsPtr->tk_MeasureChars) /* 126 */ -#endif -#ifndef Tk_MoveResizeWindow #define Tk_MoveResizeWindow \ (tkStubsPtr->tk_MoveResizeWindow) /* 127 */ -#endif -#ifndef Tk_MoveWindow #define Tk_MoveWindow \ (tkStubsPtr->tk_MoveWindow) /* 128 */ -#endif -#ifndef Tk_MoveToplevelWindow #define Tk_MoveToplevelWindow \ (tkStubsPtr->tk_MoveToplevelWindow) /* 129 */ -#endif -#ifndef Tk_NameOf3DBorder #define Tk_NameOf3DBorder \ (tkStubsPtr->tk_NameOf3DBorder) /* 130 */ -#endif -#ifndef Tk_NameOfAnchor #define Tk_NameOfAnchor \ (tkStubsPtr->tk_NameOfAnchor) /* 131 */ -#endif -#ifndef Tk_NameOfBitmap #define Tk_NameOfBitmap \ (tkStubsPtr->tk_NameOfBitmap) /* 132 */ -#endif -#ifndef Tk_NameOfCapStyle #define Tk_NameOfCapStyle \ (tkStubsPtr->tk_NameOfCapStyle) /* 133 */ -#endif -#ifndef Tk_NameOfColor #define Tk_NameOfColor \ (tkStubsPtr->tk_NameOfColor) /* 134 */ -#endif -#ifndef Tk_NameOfCursor #define Tk_NameOfCursor \ (tkStubsPtr->tk_NameOfCursor) /* 135 */ -#endif -#ifndef Tk_NameOfFont #define Tk_NameOfFont \ (tkStubsPtr->tk_NameOfFont) /* 136 */ -#endif -#ifndef Tk_NameOfImage #define Tk_NameOfImage \ (tkStubsPtr->tk_NameOfImage) /* 137 */ -#endif -#ifndef Tk_NameOfJoinStyle #define Tk_NameOfJoinStyle \ (tkStubsPtr->tk_NameOfJoinStyle) /* 138 */ -#endif -#ifndef Tk_NameOfJustify #define Tk_NameOfJustify \ (tkStubsPtr->tk_NameOfJustify) /* 139 */ -#endif -#ifndef Tk_NameOfRelief #define Tk_NameOfRelief \ (tkStubsPtr->tk_NameOfRelief) /* 140 */ -#endif -#ifndef Tk_NameToWindow #define Tk_NameToWindow \ (tkStubsPtr->tk_NameToWindow) /* 141 */ -#endif -#ifndef Tk_OwnSelection #define Tk_OwnSelection \ (tkStubsPtr->tk_OwnSelection) /* 142 */ -#endif -#ifndef Tk_ParseArgv #define Tk_ParseArgv \ (tkStubsPtr->tk_ParseArgv) /* 143 */ -#endif -#ifndef Tk_PhotoPutBlock_NoComposite #define Tk_PhotoPutBlock_NoComposite \ (tkStubsPtr->tk_PhotoPutBlock_NoComposite) /* 144 */ -#endif -#ifndef Tk_PhotoPutZoomedBlock_NoComposite #define Tk_PhotoPutZoomedBlock_NoComposite \ (tkStubsPtr->tk_PhotoPutZoomedBlock_NoComposite) /* 145 */ -#endif -#ifndef Tk_PhotoGetImage #define Tk_PhotoGetImage \ (tkStubsPtr->tk_PhotoGetImage) /* 146 */ -#endif -#ifndef Tk_PhotoBlank #define Tk_PhotoBlank \ (tkStubsPtr->tk_PhotoBlank) /* 147 */ -#endif -#ifndef Tk_PhotoExpand_Panic #define Tk_PhotoExpand_Panic \ (tkStubsPtr->tk_PhotoExpand_Panic) /* 148 */ -#endif -#ifndef Tk_PhotoGetSize #define Tk_PhotoGetSize \ (tkStubsPtr->tk_PhotoGetSize) /* 149 */ -#endif -#ifndef Tk_PhotoSetSize_Panic #define Tk_PhotoSetSize_Panic \ (tkStubsPtr->tk_PhotoSetSize_Panic) /* 150 */ -#endif -#ifndef Tk_PointToChar #define Tk_PointToChar \ (tkStubsPtr->tk_PointToChar) /* 151 */ -#endif -#ifndef Tk_PostscriptFontName #define Tk_PostscriptFontName \ (tkStubsPtr->tk_PostscriptFontName) /* 152 */ -#endif -#ifndef Tk_PreserveColormap #define Tk_PreserveColormap \ (tkStubsPtr->tk_PreserveColormap) /* 153 */ -#endif -#ifndef Tk_QueueWindowEvent #define Tk_QueueWindowEvent \ (tkStubsPtr->tk_QueueWindowEvent) /* 154 */ -#endif -#ifndef Tk_RedrawImage #define Tk_RedrawImage \ (tkStubsPtr->tk_RedrawImage) /* 155 */ -#endif -#ifndef Tk_ResizeWindow #define Tk_ResizeWindow \ (tkStubsPtr->tk_ResizeWindow) /* 156 */ -#endif -#ifndef Tk_RestackWindow #define Tk_RestackWindow \ (tkStubsPtr->tk_RestackWindow) /* 157 */ -#endif -#ifndef Tk_RestrictEvents #define Tk_RestrictEvents \ (tkStubsPtr->tk_RestrictEvents) /* 158 */ -#endif -#ifndef Tk_SafeInit #define Tk_SafeInit \ (tkStubsPtr->tk_SafeInit) /* 159 */ -#endif -#ifndef Tk_SetAppName #define Tk_SetAppName \ (tkStubsPtr->tk_SetAppName) /* 160 */ -#endif -#ifndef Tk_SetBackgroundFromBorder #define Tk_SetBackgroundFromBorder \ (tkStubsPtr->tk_SetBackgroundFromBorder) /* 161 */ -#endif -#ifndef Tk_SetClass #define Tk_SetClass \ (tkStubsPtr->tk_SetClass) /* 162 */ -#endif -#ifndef Tk_SetGrid #define Tk_SetGrid \ (tkStubsPtr->tk_SetGrid) /* 163 */ -#endif -#ifndef Tk_SetInternalBorder #define Tk_SetInternalBorder \ (tkStubsPtr->tk_SetInternalBorder) /* 164 */ -#endif -#ifndef Tk_SetWindowBackground #define Tk_SetWindowBackground \ (tkStubsPtr->tk_SetWindowBackground) /* 165 */ -#endif -#ifndef Tk_SetWindowBackgroundPixmap #define Tk_SetWindowBackgroundPixmap \ (tkStubsPtr->tk_SetWindowBackgroundPixmap) /* 166 */ -#endif -#ifndef Tk_SetWindowBorder #define Tk_SetWindowBorder \ (tkStubsPtr->tk_SetWindowBorder) /* 167 */ -#endif -#ifndef Tk_SetWindowBorderWidth #define Tk_SetWindowBorderWidth \ (tkStubsPtr->tk_SetWindowBorderWidth) /* 168 */ -#endif -#ifndef Tk_SetWindowBorderPixmap #define Tk_SetWindowBorderPixmap \ (tkStubsPtr->tk_SetWindowBorderPixmap) /* 169 */ -#endif -#ifndef Tk_SetWindowColormap #define Tk_SetWindowColormap \ (tkStubsPtr->tk_SetWindowColormap) /* 170 */ -#endif -#ifndef Tk_SetWindowVisual #define Tk_SetWindowVisual \ (tkStubsPtr->tk_SetWindowVisual) /* 171 */ -#endif -#ifndef Tk_SizeOfBitmap #define Tk_SizeOfBitmap \ (tkStubsPtr->tk_SizeOfBitmap) /* 172 */ -#endif -#ifndef Tk_SizeOfImage #define Tk_SizeOfImage \ (tkStubsPtr->tk_SizeOfImage) /* 173 */ -#endif -#ifndef Tk_StrictMotif #define Tk_StrictMotif \ (tkStubsPtr->tk_StrictMotif) /* 174 */ -#endif -#ifndef Tk_TextLayoutToPostscript #define Tk_TextLayoutToPostscript \ (tkStubsPtr->tk_TextLayoutToPostscript) /* 175 */ -#endif -#ifndef Tk_TextWidth #define Tk_TextWidth \ (tkStubsPtr->tk_TextWidth) /* 176 */ -#endif -#ifndef Tk_UndefineCursor #define Tk_UndefineCursor \ (tkStubsPtr->tk_UndefineCursor) /* 177 */ -#endif -#ifndef Tk_UnderlineChars #define Tk_UnderlineChars \ (tkStubsPtr->tk_UnderlineChars) /* 178 */ -#endif -#ifndef Tk_UnderlineTextLayout #define Tk_UnderlineTextLayout \ (tkStubsPtr->tk_UnderlineTextLayout) /* 179 */ -#endif -#ifndef Tk_Ungrab #define Tk_Ungrab \ (tkStubsPtr->tk_Ungrab) /* 180 */ -#endif -#ifndef Tk_UnmaintainGeometry #define Tk_UnmaintainGeometry \ (tkStubsPtr->tk_UnmaintainGeometry) /* 181 */ -#endif -#ifndef Tk_UnmapWindow #define Tk_UnmapWindow \ (tkStubsPtr->tk_UnmapWindow) /* 182 */ -#endif -#ifndef Tk_UnsetGrid #define Tk_UnsetGrid \ (tkStubsPtr->tk_UnsetGrid) /* 183 */ -#endif -#ifndef Tk_UpdatePointer #define Tk_UpdatePointer \ (tkStubsPtr->tk_UpdatePointer) /* 184 */ -#endif -#ifndef Tk_AllocBitmapFromObj #define Tk_AllocBitmapFromObj \ (tkStubsPtr->tk_AllocBitmapFromObj) /* 185 */ -#endif -#ifndef Tk_Alloc3DBorderFromObj #define Tk_Alloc3DBorderFromObj \ (tkStubsPtr->tk_Alloc3DBorderFromObj) /* 186 */ -#endif -#ifndef Tk_AllocColorFromObj #define Tk_AllocColorFromObj \ (tkStubsPtr->tk_AllocColorFromObj) /* 187 */ -#endif -#ifndef Tk_AllocCursorFromObj #define Tk_AllocCursorFromObj \ (tkStubsPtr->tk_AllocCursorFromObj) /* 188 */ -#endif -#ifndef Tk_AllocFontFromObj #define Tk_AllocFontFromObj \ (tkStubsPtr->tk_AllocFontFromObj) /* 189 */ -#endif -#ifndef Tk_CreateOptionTable #define Tk_CreateOptionTable \ (tkStubsPtr->tk_CreateOptionTable) /* 190 */ -#endif -#ifndef Tk_DeleteOptionTable #define Tk_DeleteOptionTable \ (tkStubsPtr->tk_DeleteOptionTable) /* 191 */ -#endif -#ifndef Tk_Free3DBorderFromObj #define Tk_Free3DBorderFromObj \ (tkStubsPtr->tk_Free3DBorderFromObj) /* 192 */ -#endif -#ifndef Tk_FreeBitmapFromObj #define Tk_FreeBitmapFromObj \ (tkStubsPtr->tk_FreeBitmapFromObj) /* 193 */ -#endif -#ifndef Tk_FreeColorFromObj #define Tk_FreeColorFromObj \ (tkStubsPtr->tk_FreeColorFromObj) /* 194 */ -#endif -#ifndef Tk_FreeConfigOptions #define Tk_FreeConfigOptions \ (tkStubsPtr->tk_FreeConfigOptions) /* 195 */ -#endif -#ifndef Tk_FreeSavedOptions #define Tk_FreeSavedOptions \ (tkStubsPtr->tk_FreeSavedOptions) /* 196 */ -#endif -#ifndef Tk_FreeCursorFromObj #define Tk_FreeCursorFromObj \ (tkStubsPtr->tk_FreeCursorFromObj) /* 197 */ -#endif -#ifndef Tk_FreeFontFromObj #define Tk_FreeFontFromObj \ (tkStubsPtr->tk_FreeFontFromObj) /* 198 */ -#endif -#ifndef Tk_Get3DBorderFromObj #define Tk_Get3DBorderFromObj \ (tkStubsPtr->tk_Get3DBorderFromObj) /* 199 */ -#endif -#ifndef Tk_GetAnchorFromObj #define Tk_GetAnchorFromObj \ (tkStubsPtr->tk_GetAnchorFromObj) /* 200 */ -#endif -#ifndef Tk_GetBitmapFromObj #define Tk_GetBitmapFromObj \ (tkStubsPtr->tk_GetBitmapFromObj) /* 201 */ -#endif -#ifndef Tk_GetColorFromObj #define Tk_GetColorFromObj \ (tkStubsPtr->tk_GetColorFromObj) /* 202 */ -#endif -#ifndef Tk_GetCursorFromObj #define Tk_GetCursorFromObj \ (tkStubsPtr->tk_GetCursorFromObj) /* 203 */ -#endif -#ifndef Tk_GetOptionInfo #define Tk_GetOptionInfo \ (tkStubsPtr->tk_GetOptionInfo) /* 204 */ -#endif -#ifndef Tk_GetOptionValue #define Tk_GetOptionValue \ (tkStubsPtr->tk_GetOptionValue) /* 205 */ -#endif -#ifndef Tk_GetJustifyFromObj #define Tk_GetJustifyFromObj \ (tkStubsPtr->tk_GetJustifyFromObj) /* 206 */ -#endif -#ifndef Tk_GetMMFromObj #define Tk_GetMMFromObj \ (tkStubsPtr->tk_GetMMFromObj) /* 207 */ -#endif -#ifndef Tk_GetPixelsFromObj #define Tk_GetPixelsFromObj \ (tkStubsPtr->tk_GetPixelsFromObj) /* 208 */ -#endif -#ifndef Tk_GetReliefFromObj #define Tk_GetReliefFromObj \ (tkStubsPtr->tk_GetReliefFromObj) /* 209 */ -#endif -#ifndef Tk_GetScrollInfoObj #define Tk_GetScrollInfoObj \ (tkStubsPtr->tk_GetScrollInfoObj) /* 210 */ -#endif -#ifndef Tk_InitOptions #define Tk_InitOptions \ (tkStubsPtr->tk_InitOptions) /* 211 */ -#endif -#ifndef Tk_MainEx #define Tk_MainEx \ (tkStubsPtr->tk_MainEx) /* 212 */ -#endif -#ifndef Tk_RestoreSavedOptions #define Tk_RestoreSavedOptions \ (tkStubsPtr->tk_RestoreSavedOptions) /* 213 */ -#endif -#ifndef Tk_SetOptions #define Tk_SetOptions \ (tkStubsPtr->tk_SetOptions) /* 214 */ -#endif -#ifndef Tk_InitConsoleChannels #define Tk_InitConsoleChannels \ (tkStubsPtr->tk_InitConsoleChannels) /* 215 */ -#endif -#ifndef Tk_CreateConsoleWindow #define Tk_CreateConsoleWindow \ (tkStubsPtr->tk_CreateConsoleWindow) /* 216 */ -#endif -#ifndef Tk_CreateSmoothMethod #define Tk_CreateSmoothMethod \ (tkStubsPtr->tk_CreateSmoothMethod) /* 217 */ -#endif /* Slot 218 is reserved */ /* Slot 219 is reserved */ -#ifndef Tk_GetDash #define Tk_GetDash \ (tkStubsPtr->tk_GetDash) /* 220 */ -#endif -#ifndef Tk_CreateOutline #define Tk_CreateOutline \ (tkStubsPtr->tk_CreateOutline) /* 221 */ -#endif -#ifndef Tk_DeleteOutline #define Tk_DeleteOutline \ (tkStubsPtr->tk_DeleteOutline) /* 222 */ -#endif -#ifndef Tk_ConfigOutlineGC #define Tk_ConfigOutlineGC \ (tkStubsPtr->tk_ConfigOutlineGC) /* 223 */ -#endif -#ifndef Tk_ChangeOutlineGC #define Tk_ChangeOutlineGC \ (tkStubsPtr->tk_ChangeOutlineGC) /* 224 */ -#endif -#ifndef Tk_ResetOutlineGC #define Tk_ResetOutlineGC \ (tkStubsPtr->tk_ResetOutlineGC) /* 225 */ -#endif -#ifndef Tk_CanvasPsOutline #define Tk_CanvasPsOutline \ (tkStubsPtr->tk_CanvasPsOutline) /* 226 */ -#endif -#ifndef Tk_SetTSOrigin #define Tk_SetTSOrigin \ (tkStubsPtr->tk_SetTSOrigin) /* 227 */ -#endif -#ifndef Tk_CanvasGetCoordFromObj #define Tk_CanvasGetCoordFromObj \ (tkStubsPtr->tk_CanvasGetCoordFromObj) /* 228 */ -#endif -#ifndef Tk_CanvasSetOffset #define Tk_CanvasSetOffset \ (tkStubsPtr->tk_CanvasSetOffset) /* 229 */ -#endif -#ifndef Tk_DitherPhoto #define Tk_DitherPhoto \ (tkStubsPtr->tk_DitherPhoto) /* 230 */ -#endif -#ifndef Tk_PostscriptBitmap #define Tk_PostscriptBitmap \ (tkStubsPtr->tk_PostscriptBitmap) /* 231 */ -#endif -#ifndef Tk_PostscriptColor #define Tk_PostscriptColor \ (tkStubsPtr->tk_PostscriptColor) /* 232 */ -#endif -#ifndef Tk_PostscriptFont #define Tk_PostscriptFont \ (tkStubsPtr->tk_PostscriptFont) /* 233 */ -#endif -#ifndef Tk_PostscriptImage #define Tk_PostscriptImage \ (tkStubsPtr->tk_PostscriptImage) /* 234 */ -#endif -#ifndef Tk_PostscriptPath #define Tk_PostscriptPath \ (tkStubsPtr->tk_PostscriptPath) /* 235 */ -#endif -#ifndef Tk_PostscriptStipple #define Tk_PostscriptStipple \ (tkStubsPtr->tk_PostscriptStipple) /* 236 */ -#endif -#ifndef Tk_PostscriptY #define Tk_PostscriptY \ (tkStubsPtr->tk_PostscriptY) /* 237 */ -#endif -#ifndef Tk_PostscriptPhoto #define Tk_PostscriptPhoto \ (tkStubsPtr->tk_PostscriptPhoto) /* 238 */ -#endif -#ifndef Tk_CreateClientMessageHandler #define Tk_CreateClientMessageHandler \ (tkStubsPtr->tk_CreateClientMessageHandler) /* 239 */ -#endif -#ifndef Tk_DeleteClientMessageHandler #define Tk_DeleteClientMessageHandler \ (tkStubsPtr->tk_DeleteClientMessageHandler) /* 240 */ -#endif -#ifndef Tk_CreateAnonymousWindow #define Tk_CreateAnonymousWindow \ (tkStubsPtr->tk_CreateAnonymousWindow) /* 241 */ -#endif -#ifndef Tk_SetClassProcs #define Tk_SetClassProcs \ (tkStubsPtr->tk_SetClassProcs) /* 242 */ -#endif -#ifndef Tk_SetInternalBorderEx #define Tk_SetInternalBorderEx \ (tkStubsPtr->tk_SetInternalBorderEx) /* 243 */ -#endif -#ifndef Tk_SetMinimumRequestSize #define Tk_SetMinimumRequestSize \ (tkStubsPtr->tk_SetMinimumRequestSize) /* 244 */ -#endif -#ifndef Tk_SetCaretPos #define Tk_SetCaretPos \ (tkStubsPtr->tk_SetCaretPos) /* 245 */ -#endif -#ifndef Tk_PhotoPutBlock_Panic #define Tk_PhotoPutBlock_Panic \ (tkStubsPtr->tk_PhotoPutBlock_Panic) /* 246 */ -#endif -#ifndef Tk_PhotoPutZoomedBlock_Panic #define Tk_PhotoPutZoomedBlock_Panic \ (tkStubsPtr->tk_PhotoPutZoomedBlock_Panic) /* 247 */ -#endif -#ifndef Tk_CollapseMotionEvents #define Tk_CollapseMotionEvents \ (tkStubsPtr->tk_CollapseMotionEvents) /* 248 */ -#endif -#ifndef Tk_RegisterStyleEngine #define Tk_RegisterStyleEngine \ (tkStubsPtr->tk_RegisterStyleEngine) /* 249 */ -#endif -#ifndef Tk_GetStyleEngine #define Tk_GetStyleEngine \ (tkStubsPtr->tk_GetStyleEngine) /* 250 */ -#endif -#ifndef Tk_RegisterStyledElement #define Tk_RegisterStyledElement \ (tkStubsPtr->tk_RegisterStyledElement) /* 251 */ -#endif -#ifndef Tk_GetElementId #define Tk_GetElementId \ (tkStubsPtr->tk_GetElementId) /* 252 */ -#endif -#ifndef Tk_CreateStyle #define Tk_CreateStyle \ (tkStubsPtr->tk_CreateStyle) /* 253 */ -#endif -#ifndef Tk_GetStyle #define Tk_GetStyle \ (tkStubsPtr->tk_GetStyle) /* 254 */ -#endif -#ifndef Tk_FreeStyle #define Tk_FreeStyle \ (tkStubsPtr->tk_FreeStyle) /* 255 */ -#endif -#ifndef Tk_NameOfStyle #define Tk_NameOfStyle \ (tkStubsPtr->tk_NameOfStyle) /* 256 */ -#endif -#ifndef Tk_AllocStyleFromObj #define Tk_AllocStyleFromObj \ (tkStubsPtr->tk_AllocStyleFromObj) /* 257 */ -#endif -#ifndef Tk_GetStyleFromObj #define Tk_GetStyleFromObj \ (tkStubsPtr->tk_GetStyleFromObj) /* 258 */ -#endif -#ifndef Tk_FreeStyleFromObj #define Tk_FreeStyleFromObj \ (tkStubsPtr->tk_FreeStyleFromObj) /* 259 */ -#endif -#ifndef Tk_GetStyledElement #define Tk_GetStyledElement \ (tkStubsPtr->tk_GetStyledElement) /* 260 */ -#endif -#ifndef Tk_GetElementSize #define Tk_GetElementSize \ (tkStubsPtr->tk_GetElementSize) /* 261 */ -#endif -#ifndef Tk_GetElementBox #define Tk_GetElementBox \ (tkStubsPtr->tk_GetElementBox) /* 262 */ -#endif -#ifndef Tk_GetElementBorderWidth #define Tk_GetElementBorderWidth \ (tkStubsPtr->tk_GetElementBorderWidth) /* 263 */ -#endif -#ifndef Tk_DrawElement #define Tk_DrawElement \ (tkStubsPtr->tk_DrawElement) /* 264 */ -#endif -#ifndef Tk_PhotoExpand #define Tk_PhotoExpand \ (tkStubsPtr->tk_PhotoExpand) /* 265 */ -#endif -#ifndef Tk_PhotoPutBlock #define Tk_PhotoPutBlock \ (tkStubsPtr->tk_PhotoPutBlock) /* 266 */ -#endif -#ifndef Tk_PhotoPutZoomedBlock #define Tk_PhotoPutZoomedBlock \ (tkStubsPtr->tk_PhotoPutZoomedBlock) /* 267 */ -#endif -#ifndef Tk_PhotoSetSize #define Tk_PhotoSetSize \ (tkStubsPtr->tk_PhotoSetSize) /* 268 */ -#endif -#ifndef Tk_GetUserInactiveTime #define Tk_GetUserInactiveTime \ (tkStubsPtr->tk_GetUserInactiveTime) /* 269 */ -#endif -#ifndef Tk_ResetUserInactiveTime #define Tk_ResetUserInactiveTime \ (tkStubsPtr->tk_ResetUserInactiveTime) /* 270 */ -#endif -#ifndef Tk_Interp #define Tk_Interp \ (tkStubsPtr->tk_Interp) /* 271 */ -#endif -#ifndef Tk_CreateOldImageType #define Tk_CreateOldImageType \ (tkStubsPtr->tk_CreateOldImageType) /* 272 */ -#endif -#ifndef Tk_CreateOldPhotoImageFormat #define Tk_CreateOldPhotoImageFormat \ (tkStubsPtr->tk_CreateOldPhotoImageFormat) /* 273 */ -#endif -/* Slot 274 is reserved */ -#ifndef TkUnusedStubEntry -#define TkUnusedStubEntry \ - (tkStubsPtr->tkUnusedStubEntry) /* 275 */ -#endif -#endif /* defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS) */ +#endif /* defined(USE_TK_STUBS) */ /* !END!: Do not edit above this line. */ +/* Functions that don't belong in the stub table */ +#undef Tk_MainEx +#undef Tk_Init +#undef Tk_SafeInit +#undef Tk_CreateConsoleWindow + +#if defined(_WIN32) && defined(UNICODE) +# define Tk_MainEx Tk_MainExW + EXTERN void Tk_MainExW(int argc, wchar_t **argv, + Tcl_AppInitProc *appInitProc, Tcl_Interp *interp); +#endif + #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT -#undef TkUnusedStubEntry - #endif /* _TKDECLS */ - diff --git a/generic/tkEntry.c b/generic/tkEntry.c index f35d2b7..a7bc5a0 100644 --- a/generic/tkEntry.c +++ b/generic/tkEntry.c @@ -64,11 +64,11 @@ enum validateType { static const Tk_OptionSpec entryOptSpec[] = { {TK_OPTION_BORDER, "-background", "background", "Background", DEF_ENTRY_BG_COLOR, -1, Tk_Offset(Entry, normalBorder), - 0, (ClientData) DEF_ENTRY_BG_MONO, 0}, + 0, DEF_ENTRY_BG_MONO, 0}, {TK_OPTION_SYNONYM, "-bd", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-borderwidth", 0}, + NULL, 0, -1, 0, "-borderwidth", 0}, {TK_OPTION_SYNONYM, "-bg", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-background", 0}, + NULL, 0, -1, 0, "-background", 0}, {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", DEF_ENTRY_BORDER_WIDTH, -1, Tk_Offset(Entry, borderWidth), 0, 0, 0}, {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", @@ -85,7 +85,7 @@ static const Tk_OptionSpec entryOptSpec[] = { "ExportSelection", DEF_ENTRY_EXPORT_SELECTION, -1, Tk_Offset(Entry, exportSelection), 0, 0, 0}, {TK_OPTION_SYNONYM, "-fg", "foreground", NULL, - NULL, 0, -1, 0, (ClientData) "-foreground", 0}, + NULL, 0, -1, 0, "-foreground", 0}, {TK_OPTION_FONT, "-font", "font", "Font", DEF_ENTRY_FONT, -1, Tk_Offset(Entry, tkfont), 0, 0, 0}, {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground", @@ -115,7 +115,7 @@ static const Tk_OptionSpec entryOptSpec[] = { DEF_ENTRY_INVALIDCMD, -1, Tk_Offset(Entry, invalidCmd), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_SYNONYM, "-invcmd", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-invalidcommand", 0}, + NULL, 0, -1, 0, "-invalidcommand", 0}, {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify", DEF_ENTRY_JUSTIFY, -1, Tk_Offset(Entry, justify), 0, 0, 0}, {TK_OPTION_BORDER, "-readonlybackground", "readonlyBackground", @@ -126,20 +126,20 @@ static const Tk_OptionSpec entryOptSpec[] = { DEF_ENTRY_RELIEF, -1, Tk_Offset(Entry, relief), 0, 0, 0}, {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground", DEF_ENTRY_SELECT_COLOR, -1, Tk_Offset(Entry, selBorder), - 0, (ClientData) DEF_ENTRY_SELECT_MONO, 0}, + 0, DEF_ENTRY_SELECT_MONO, 0}, {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth", "BorderWidth", DEF_ENTRY_SELECT_BD_COLOR, -1, Tk_Offset(Entry, selBorderWidth), - 0, (ClientData) DEF_ENTRY_SELECT_BD_MONO, 0}, + 0, DEF_ENTRY_SELECT_BD_MONO, 0}, {TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background", DEF_ENTRY_SELECT_FG_COLOR, -1, Tk_Offset(Entry, selFgColorPtr), - TK_OPTION_NULL_OK, (ClientData) DEF_ENTRY_SELECT_FG_MONO, 0}, + TK_OPTION_NULL_OK, DEF_ENTRY_SELECT_FG_MONO, 0}, {TK_OPTION_STRING, "-show", "show", "Show", DEF_ENTRY_SHOW, -1, Tk_Offset(Entry, showChar), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING_TABLE, "-state", "state", "State", DEF_ENTRY_STATE, -1, Tk_Offset(Entry, state), - 0, (ClientData) stateStrings, 0}, + 0, stateStrings, 0}, {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", DEF_ENTRY_TAKE_FOCUS, -1, Tk_Offset(Entry, takeFocus), TK_OPTION_NULL_OK, 0, 0}, @@ -148,11 +148,11 @@ static const Tk_OptionSpec entryOptSpec[] = { TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING_TABLE, "-validate", "validate", "Validate", DEF_ENTRY_VALIDATE, -1, Tk_Offset(Entry, validate), - 0, (ClientData) validateStrings, 0}, + 0, validateStrings, 0}, {TK_OPTION_STRING, "-validatecommand", "validateCommand","ValidateCommand", NULL, -1, Tk_Offset(Entry, validateCmd), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_SYNONYM, "-vcmd", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-validatecommand", 0}, + NULL, 0, -1, 0, "-validatecommand", 0}, {TK_OPTION_INT, "-width", "width", "Width", DEF_ENTRY_WIDTH, -1, Tk_Offset(Entry, prefWidth), 0, 0, 0}, {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand", @@ -181,19 +181,19 @@ static const Tk_OptionSpec entryOptSpec[] = { static const Tk_OptionSpec sbOptSpec[] = { {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Background", DEF_BUTTON_ACTIVE_BG_COLOR, -1, Tk_Offset(Spinbox, activeBorder), - 0, (ClientData) DEF_BUTTON_ACTIVE_BG_MONO, 0}, + 0, DEF_BUTTON_ACTIVE_BG_MONO, 0}, {TK_OPTION_BORDER, "-background", "background", "Background", DEF_ENTRY_BG_COLOR, -1, Tk_Offset(Entry, normalBorder), - 0, (ClientData) DEF_ENTRY_BG_MONO, 0}, + 0, DEF_ENTRY_BG_MONO, 0}, {TK_OPTION_SYNONYM, "-bd", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-borderwidth", 0}, + NULL, 0, -1, 0, "-borderwidth", 0}, {TK_OPTION_SYNONYM, "-bg", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-background", 0}, + NULL, 0, -1, 0, "-background", 0}, {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", DEF_ENTRY_BORDER_WIDTH, -1, Tk_Offset(Entry, borderWidth), 0, 0, 0}, {TK_OPTION_BORDER, "-buttonbackground", "Button.background", "Background", DEF_BUTTON_BG_COLOR, -1, Tk_Offset(Spinbox, buttonBorder), - 0, (ClientData) DEF_BUTTON_BG_MONO, 0}, + 0, DEF_BUTTON_BG_MONO, 0}, {TK_OPTION_CURSOR, "-buttoncursor", "Button.cursor", "Cursor", DEF_BUTTON_CURSOR, -1, Tk_Offset(Spinbox, bCursor), TK_OPTION_NULL_OK, 0, 0}, @@ -218,7 +218,7 @@ static const Tk_OptionSpec sbOptSpec[] = { "ExportSelection", DEF_ENTRY_EXPORT_SELECTION, -1, Tk_Offset(Entry, exportSelection), 0, 0, 0}, {TK_OPTION_SYNONYM, "-fg", "foreground", NULL, - NULL, 0, -1, 0, (ClientData) "-foreground", 0}, + NULL, 0, -1, 0, "-foreground", 0}, {TK_OPTION_FONT, "-font", "font", "Font", DEF_ENTRY_FONT, -1, Tk_Offset(Entry, tkfont), 0, 0, 0}, {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground", @@ -255,7 +255,7 @@ static const Tk_OptionSpec sbOptSpec[] = { DEF_ENTRY_INVALIDCMD, -1, Tk_Offset(Entry, invalidCmd), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_SYNONYM, "-invcmd", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-invalidcommand", 0}, + NULL, 0, -1, 0, "-invalidcommand", 0}, {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify", DEF_ENTRY_JUSTIFY, -1, Tk_Offset(Entry, justify), 0, 0, 0}, {TK_OPTION_RELIEF, "-relief", "relief", "Relief", @@ -272,17 +272,17 @@ static const Tk_OptionSpec sbOptSpec[] = { 0, 0, 0}, {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground", DEF_ENTRY_SELECT_COLOR, -1, Tk_Offset(Entry, selBorder), - 0, (ClientData) DEF_ENTRY_SELECT_MONO, 0}, + 0, DEF_ENTRY_SELECT_MONO, 0}, {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth", "BorderWidth", DEF_ENTRY_SELECT_BD_COLOR, -1, Tk_Offset(Entry, selBorderWidth), - 0, (ClientData) DEF_ENTRY_SELECT_BD_MONO, 0}, + 0, DEF_ENTRY_SELECT_BD_MONO, 0}, {TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background", DEF_ENTRY_SELECT_FG_COLOR, -1, Tk_Offset(Entry, selFgColorPtr), - TK_OPTION_NULL_OK, (ClientData) DEF_ENTRY_SELECT_FG_MONO, 0}, + TK_OPTION_NULL_OK, DEF_ENTRY_SELECT_FG_MONO, 0}, {TK_OPTION_STRING_TABLE, "-state", "state", "State", DEF_ENTRY_STATE, -1, Tk_Offset(Entry, state), - 0, (ClientData) stateStrings, 0}, + 0, stateStrings, 0}, {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", DEF_ENTRY_TAKE_FOCUS, -1, Tk_Offset(Entry, takeFocus), TK_OPTION_NULL_OK, 0, 0}, @@ -293,14 +293,14 @@ static const Tk_OptionSpec sbOptSpec[] = { DEF_SPINBOX_TO, -1, Tk_Offset(Spinbox, toValue), 0, 0, 0}, {TK_OPTION_STRING_TABLE, "-validate", "validate", "Validate", DEF_ENTRY_VALIDATE, -1, Tk_Offset(Entry, validate), - 0, (ClientData) validateStrings, 0}, + 0, validateStrings, 0}, {TK_OPTION_STRING, "-validatecommand", "validateCommand","ValidateCommand", NULL, -1, Tk_Offset(Entry, validateCmd), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING, "-values", "values", "Values", DEF_SPINBOX_VALUES, -1, Tk_Offset(Spinbox, valueStr), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_SYNONYM, "-vcmd", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-validatecommand", 0}, + NULL, 0, -1, 0, "-validatecommand", 0}, {TK_OPTION_INT, "-width", "width", "Width", DEF_ENTRY_WIDTH, -1, Tk_Offset(Entry, prefWidth), 0, 0, 0}, {TK_OPTION_BOOLEAN, "-wrap", "wrap", "Wrap", @@ -317,7 +317,7 @@ static const Tk_OptionSpec sbOptSpec[] = { * dispatch the entry widget command. */ -static const char *entryCmdNames[] = { +static const char *const entryCmdNames[] = { "bbox", "cget", "configure", "delete", "get", "icursor", "index", "insert", "scan", "selection", "validate", "xview", NULL }; @@ -328,7 +328,7 @@ enum entryCmd { COMMAND_SCAN, COMMAND_SELECTION, COMMAND_VALIDATE, COMMAND_XVIEW }; -static const char *selCmdNames[] = { +static const char *const selCmdNames[] = { "adjust", "clear", "from", "present", "range", "to", NULL }; @@ -343,7 +343,7 @@ enum selCmd { * dispatch the spinbox widget command. */ -static const char *sbCmdNames[] = { +static const char *const sbCmdNames[] = { "bbox", "cget", "configure", "delete", "get", "icursor", "identify", "index", "insert", "invoke", "scan", "selection", "set", "validate", "xview", NULL @@ -356,7 +356,7 @@ enum sbCmd { SB_CMD_SET, SB_CMD_VALIDATE, SB_CMD_XVIEW }; -static const char *sbSelCmdNames[] = { +static const char *const sbSelCmdNames[] = { "adjust", "clear", "element", "from", "present", "range", "to", NULL }; @@ -374,7 +374,7 @@ enum sbselCmd { * modify them, you must modify the strings here. */ -static const char *selElementNames[] = { +static const char *const selElementNames[] = { "none", "buttondown", "buttonup", NULL, "entry" }; @@ -392,7 +392,7 @@ static const char *selElementNames[] = { static int ConfigureEntry(Tcl_Interp *interp, Entry *entryPtr, int objc, Tcl_Obj *const objv[]); static int DeleteChars(Entry *entryPtr, int index, int count); -static void DestroyEntry(char *memPtr); +static void DestroyEntry(void *memPtr); static void DisplayEntry(ClientData clientData); static void EntryBlinkProc(ClientData clientData); static void EntryCmdDeletedProc(ClientData clientData); @@ -412,8 +412,8 @@ static char * EntryTextVarProc(ClientData clientData, const char *name2, int flags); static void EntryUpdateScrollbar(Entry *entryPtr); static int EntryValidate(Entry *entryPtr, char *cmd); -static int EntryValidateChange(Entry *entryPtr, char *change, - const char *newStr, int index, int type); +static int EntryValidateChange(Entry *entryPtr, const char *change, + const char *newStr, int index, int type); static void ExpandPercents(Entry *entryPtr, const char *before, const char *change, const char *newStr, int index, int type, Tcl_DString *dsPtr); @@ -426,8 +426,8 @@ static int EntryWidgetObjCmd(ClientData clientData, Tcl_Obj *const objv[]); static void EntryWorldChanged(ClientData instanceData); static int GetEntryIndex(Tcl_Interp *interp, Entry *entryPtr, - char *string, int *indexPtr); -static int InsertChars(Entry *entryPtr, int index, char *string); + const char *string, int *indexPtr); +static int InsertChars(Entry *entryPtr, int index, const char *string); /* * These forward declarations are the spinbox specific ones: @@ -446,11 +446,12 @@ static int ComputeFormat(Spinbox *sbPtr); * that can be invoked from generic window code. */ -static Tk_ClassProcs entryClass = { +static const Tk_ClassProcs entryClass = { sizeof(Tk_ClassProcs), /* size */ EntryWorldChanged, /* worldChangedProc */ + NULL, /* createProc */ + NULL /* modalProc */ }; - /* *-------------------------------------------------------------- @@ -482,7 +483,7 @@ Tk_EntryObjCmd( char *tmp; if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?"); + Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?"); return TCL_ERROR; } @@ -506,18 +507,18 @@ Tk_EntryObjCmd( * initialized as memset covers the rest. */ - entryPtr = (Entry *) ckalloc(sizeof(Entry)); + entryPtr = ckalloc(sizeof(Entry)); memset(entryPtr, 0, sizeof(Entry)); entryPtr->tkwin = tkwin; entryPtr->display = Tk_Display(tkwin); entryPtr->interp = interp; entryPtr->widgetCmd = Tcl_CreateObjCommand(interp, - Tk_PathName(entryPtr->tkwin), EntryWidgetObjCmd, - (ClientData) entryPtr, EntryCmdDeletedProc); + Tk_PathName(entryPtr->tkwin), EntryWidgetObjCmd, entryPtr, + EntryCmdDeletedProc); entryPtr->optionTable = optionTable; entryPtr->type = TK_ENTRY; - tmp = (char *) ckalloc(1); + tmp = ckalloc(1); tmp[0] = '\0'; entryPtr->string = tmp; entryPtr->selectFirst = -1; @@ -541,15 +542,15 @@ Tk_EntryObjCmd( * otherwise Tk might free it while we still need it. */ - Tcl_Preserve((ClientData) entryPtr->tkwin); + Tcl_Preserve(entryPtr->tkwin); Tk_SetClass(entryPtr->tkwin, "Entry"); - Tk_SetClassProcs(entryPtr->tkwin, &entryClass, (ClientData) entryPtr); + Tk_SetClassProcs(entryPtr->tkwin, &entryClass, entryPtr); Tk_CreateEventHandler(entryPtr->tkwin, ExposureMask|StructureNotifyMask|FocusChangeMask, - EntryEventProc, (ClientData) entryPtr); + EntryEventProc, entryPtr); Tk_CreateSelHandler(entryPtr->tkwin, XA_PRIMARY, XA_STRING, - EntryFetchSelection, (ClientData) entryPtr, XA_STRING); + EntryFetchSelection, entryPtr, XA_STRING); if ((Tk_InitOptions(interp, (char *) entryPtr, optionTable, tkwin) != TCL_OK) || @@ -558,7 +559,7 @@ Tk_EntryObjCmd( return TCL_ERROR; } - Tcl_SetResult(interp, Tk_PathName(entryPtr->tkwin), TCL_STATIC); + Tcl_SetObjResult(interp, TkNewWindowObj(entryPtr->tkwin)); return TCL_OK; } @@ -587,12 +588,12 @@ EntryWidgetObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - Entry *entryPtr = (Entry *) clientData; + Entry *entryPtr = clientData; int cmdIndex, selIndex, result; Tcl_Obj *objPtr; if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?"); + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); return TCL_ERROR; } @@ -601,17 +602,17 @@ EntryWidgetObjCmd( * valid command names. */ - result = Tcl_GetIndexFromObj(interp, objv[1], entryCmdNames, - "option", 0, &cmdIndex); + result = Tcl_GetIndexFromObj(interp, objv[1], entryCmdNames, "option", 0, + &cmdIndex); if (result != TCL_OK) { return result; } - Tcl_Preserve((ClientData) entryPtr); + Tcl_Preserve(entryPtr); switch ((enum entryCmd) cmdIndex) { case COMMAND_BBOX: { int index, x, y, width, height; - char buf[TCL_INTEGER_SPACE * 4]; + Tcl_Obj *bbox[4]; if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "index"); @@ -625,9 +626,11 @@ EntryWidgetObjCmd( index--; } Tk_CharBbox(entryPtr->textLayout, index, &x, &y, &width, &height); - sprintf(buf, "%d %d %d %d", x + entryPtr->layoutX, - y + entryPtr->layoutY, width, height); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + bbox[0] = Tcl_NewIntObj(x + entryPtr->layoutX); + bbox[1] = Tcl_NewIntObj(y + entryPtr->layoutY); + bbox[2] = Tcl_NewIntObj(width); + bbox[3] = Tcl_NewIntObj(height); + Tcl_SetObjResult(interp, Tcl_NewListObj(4, bbox)); break; } @@ -641,9 +644,8 @@ EntryWidgetObjCmd( entryPtr->optionTable, objv[2], entryPtr->tkwin); if (objPtr == NULL) { goto error; - } else { - Tcl_SetObjResult(interp, objPtr); } + Tcl_SetObjResult(interp, objPtr); break; case COMMAND_CONFIGURE: @@ -654,9 +656,8 @@ EntryWidgetObjCmd( entryPtr->tkwin); if (objPtr == NULL) { goto error; - } else { - Tcl_SetObjResult(interp, objPtr); } + Tcl_SetObjResult(interp, objPtr); } else { result = ConfigureEntry(interp, entryPtr, objc-2, objv+2); } @@ -693,7 +694,7 @@ EntryWidgetObjCmd( Tcl_WrongNumArgs(interp, 2, objv, NULL); goto error; } - Tcl_SetStringObj(Tcl_GetObjResult(interp), entryPtr->string, -1); + Tcl_SetObjResult(interp, Tcl_NewStringObj(entryPtr->string, -1)); break; case COMMAND_ICURSOR: @@ -745,7 +746,7 @@ EntryWidgetObjCmd( case COMMAND_SCAN: { int x; - char *minorCmd; + const char *minorCmd; if (objc != 4) { Tcl_WrongNumArgs(interp, 2, objv, "mark|dragto x"); @@ -764,9 +765,11 @@ EntryWidgetObjCmd( && (strncmp(minorCmd, "dragto", strlen(minorCmd)) == 0)) { EntryScanTo(entryPtr, x); } else { - Tcl_AppendResult(interp, "bad scan option \"", - Tcl_GetString(objv[2]), "\": must be mark or dragto", - NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad scan option \"%s\": must be mark or dragto", + minorCmd)); + Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "scan option", + minorCmd, NULL); goto error; } break; @@ -860,7 +863,7 @@ EntryWidgetObjCmd( goto error; } Tcl_SetObjResult(interp, - Tcl_NewBooleanObj((entryPtr->selectFirst >= 0))); + Tcl_NewBooleanObj(entryPtr->selectFirst >= 0)); goto done; case SELECTION_RANGE: @@ -884,9 +887,10 @@ EntryWidgetObjCmd( entryPtr->selectLast = index2; } if (!(entryPtr->flags & GOT_SELECTION) - && (entryPtr->exportSelection)) { + && (entryPtr->exportSelection) + && (!Tcl_IsSafe(entryPtr->interp))) { Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, - EntryLostSelection, (ClientData) entryPtr); + EntryLostSelection, entryPtr); entryPtr->flags |= GOT_SELECTION; } EventuallyRedraw(entryPtr); @@ -921,7 +925,7 @@ EntryWidgetObjCmd( if (entryPtr->validate != VALIDATE_NONE) { entryPtr->validate = selIndex; } - Tcl_SetObjResult(interp, Tcl_NewBooleanObj((code == TCL_OK))); + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(code == TCL_OK)); break; } @@ -930,13 +934,12 @@ EntryWidgetObjCmd( if (objc == 2) { double first, last; - char buf[TCL_DOUBLE_SPACE]; + Tcl_Obj *span[2]; EntryVisibleRange(entryPtr, &first, &last); - Tcl_PrintDouble(NULL, first, buf); - Tcl_SetResult(interp, buf, TCL_VOLATILE); - Tcl_PrintDouble(NULL, last, buf); - Tcl_AppendResult(interp, " ", buf, NULL); + span[0] = Tcl_NewDoubleObj(first); + span[1] = Tcl_NewDoubleObj(last); + Tcl_SetObjResult(interp, Tcl_NewListObj(2, span)); goto done; } else if (objc == 3) { if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]), @@ -986,11 +989,11 @@ EntryWidgetObjCmd( } done: - Tcl_Release((ClientData) entryPtr); + Tcl_Release(entryPtr); return result; error: - Tcl_Release((ClientData) entryPtr); + Tcl_Release(entryPtr); return TCL_ERROR; } @@ -1014,9 +1017,9 @@ EntryWidgetObjCmd( static void DestroyEntry( - char *memPtr) /* Info about entry widget. */ + void *memPtr) /* Info about entry widget. */ { - Entry *entryPtr = (Entry *) memPtr; + Entry *entryPtr = memPtr; /* * Free up all the stuff that requires special handling, then let @@ -1025,9 +1028,9 @@ DestroyEntry( ckfree((char *)entryPtr->string); if (entryPtr->textVarName != NULL) { - Tcl_UntraceVar(entryPtr->interp, entryPtr->textVarName, - TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - EntryTextVarProc, (ClientData) entryPtr); + Tcl_UntraceVar2(entryPtr->interp, entryPtr->textVarName, + NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + EntryTextVarProc, entryPtr); entryPtr->flags &= ~ENTRY_VAR_TRACED; } if (entryPtr->textGC != NULL) { @@ -1054,10 +1057,10 @@ DestroyEntry( Tk_FreeTextLayout(entryPtr->textLayout); Tk_FreeConfigOptions((char *) entryPtr, entryPtr->optionTable, entryPtr->tkwin); - Tcl_Release((ClientData) entryPtr->tkwin); + Tcl_Release(entryPtr->tkwin); entryPtr->tkwin = NULL; - ckfree((char *) entryPtr); + ckfree(entryPtr); } /* @@ -1109,9 +1112,9 @@ ConfigureEntry( if ((entryPtr->textVarName != NULL) && (entryPtr->flags & ENTRY_VAR_TRACED)) { - Tcl_UntraceVar(interp, entryPtr->textVarName, + Tcl_UntraceVar2(interp, entryPtr->textVarName, NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - EntryTextVarProc, (ClientData) entryPtr); + EntryTextVarProc, entryPtr); entryPtr->flags &= ~ENTRY_VAR_TRACED; } @@ -1120,12 +1123,12 @@ ConfigureEntry( * value. */ - oldExport = entryPtr->exportSelection; + oldExport = (entryPtr->exportSelection) && (!Tcl_IsSafe(entryPtr->interp)); if (entryPtr->type == TK_SPINBOX) { - oldValues = sbPtr->valueStr; - oldFormat = sbPtr->reqFormat; - oldFrom = sbPtr->fromValue; - oldTo = sbPtr->toValue; + oldValues = sbPtr->valueStr; + oldFormat = sbPtr->reqFormat; + oldFrom = sbPtr->fromValue; + oldTo = sbPtr->toValue; } for (error = 0; error <= 1; error++) { @@ -1174,9 +1177,11 @@ ConfigureEntry( if (entryPtr->type == TK_SPINBOX) { if (sbPtr->fromValue > sbPtr->toValue) { - Tcl_SetResult(interp, + Tcl_SetObjResult(interp, Tcl_NewStringObj( "-to value must be greater than -from value", - TCL_VOLATILE); + -1)); + Tcl_SetErrorCode(interp, "TK", "SPINBOX", "RANGE_SANITY", + NULL); continue; } @@ -1193,9 +1198,12 @@ ConfigureEntry( formatLen = strlen(fmt); if ((fmt[0] != '%') || (fmt[formatLen-1] != 'f')) { - badFormatOpt: - Tcl_AppendResult(interp, "bad spinbox format specifier \"", - sbPtr->reqFormat, "\"", NULL); + badFormatOpt: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad spinbox format specifier \"%s\"", + sbPtr->reqFormat)); + Tcl_SetErrorCode(interp, "TK", "SPINBOX", "FORMAT_SANITY", + NULL); continue; } if ((sscanf(fmt, "%%%d.%d%[f]", &min, &max, fbuf) == 3) @@ -1269,10 +1277,11 @@ ConfigureEntry( */ if (entryPtr->exportSelection && (!oldExport) + && (!Tcl_IsSafe(entryPtr->interp)) && (entryPtr->selectFirst != -1) && !(entryPtr->flags & GOT_SELECTION)) { Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, EntryLostSelection, - (ClientData) entryPtr); + entryPtr); entryPtr->flags |= GOT_SELECTION; } @@ -1302,7 +1311,7 @@ ConfigureEntry( if (entryPtr->textVarName != NULL) { const char *value; - value = Tcl_GetVar(interp, entryPtr->textVarName, TCL_GLOBAL_ONLY); + value = Tcl_GetVar2(interp, entryPtr->textVarName, NULL, TCL_GLOBAL_ONLY); if (value == NULL) { /* @@ -1356,12 +1365,10 @@ ConfigureEntry( if (sscanf(entryPtr->string, "%lf", &dvalue) <= 0) { /* Scan failure */ dvalue = sbPtr->fromValue; - } else { - if (dvalue > sbPtr->toValue) { - dvalue = sbPtr->toValue; - } else if (dvalue < sbPtr->fromValue) { - dvalue = sbPtr->fromValue; - } + } else if (dvalue > sbPtr->toValue) { + dvalue = sbPtr->toValue; + } else if (dvalue < sbPtr->fromValue) { + dvalue = sbPtr->fromValue; } sprintf(sbPtr->formatBuf, sbPtr->valueFormat, dvalue); @@ -1381,16 +1388,16 @@ ConfigureEntry( if ((entryPtr->textVarName != NULL) && !(entryPtr->flags & ENTRY_VAR_TRACED)) { - code = Tcl_TraceVar(interp, entryPtr->textVarName, - TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - EntryTextVarProc, (ClientData) entryPtr); + code = Tcl_TraceVar2(interp, entryPtr->textVarName, + NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + EntryTextVarProc, entryPtr); if (code != TCL_OK) { return TCL_ERROR; } entryPtr->flags |= ENTRY_VAR_TRACED; } - EntryWorldChanged((ClientData) entryPtr); + EntryWorldChanged(entryPtr); if (error) { Tcl_SetObjResult(interp, errorResult); Tcl_DecrRefCount(errorResult); @@ -1427,7 +1434,7 @@ EntryWorldChanged( unsigned long mask; Tk_3DBorder border; XColor *colorPtr; - Entry *entryPtr = (Entry *) instanceData; + Entry *entryPtr = instanceData; entryPtr->avgWidth = Tk_TextWidth(entryPtr->tkfont, "0", 1); if (entryPtr->avgWidth == 0) { @@ -1451,8 +1458,8 @@ EntryWorldChanged( * the background may be overridden. */ - border = entryPtr->normalBorder; - colorPtr = entryPtr->fgColorPtr; + border = entryPtr->normalBorder; + colorPtr = entryPtr->fgColorPtr; switch (entryPtr->state) { case STATE_DISABLED: if (entryPtr->disabledBorder != NULL) { @@ -1579,7 +1586,7 @@ static void DisplayEntry( ClientData clientData) /* Information about window. */ { - Entry *entryPtr = (Entry *) clientData; + Entry *entryPtr = clientData; Tk_Window tkwin = entryPtr->tkwin; int baseY, selStartX, selEndX, cursorX; int showSelection, xBound; @@ -1606,14 +1613,14 @@ DisplayEntry( * side-effect of destroying or unmapping the entry widget. */ - Tcl_Preserve((ClientData) entryPtr); + Tcl_Preserve(entryPtr); EntryUpdateScrollbar(entryPtr); if ((entryPtr->flags & ENTRY_DELETED) || !Tk_IsMapped(tkwin)) { - Tcl_Release((ClientData) entryPtr); + Tcl_Release(entryPtr); return; } - Tcl_Release((ClientData) entryPtr); + Tcl_Release(entryPtr); } #ifndef TK_NO_DOUBLE_BUFFERING @@ -1684,7 +1691,7 @@ DisplayEntry( baseY - fm.ascent - entryPtr->selBorderWidth, (selEndX - selStartX) + 2*entryPtr->selBorderWidth, (fm.ascent + fm.descent) + 2*entryPtr->selBorderWidth, - entryPtr->selBorderWidth, + entryPtr->selBorderWidth, #ifndef MAC_OSX_TK TK_RELIEF_RAISED #else @@ -1919,8 +1926,8 @@ EntryComputeGeometry( */ if (entryPtr->showChar != NULL) { - Tcl_UniChar ch; - char buf[TCL_UTF_MAX]; + int ch; + char buf[6]; int size; /* @@ -1930,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 = (char *) ckalloc((unsigned) (entryPtr->numDisplayBytes + 1)); + 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'; } @@ -1998,12 +2006,10 @@ EntryComputeGeometry( height = fm.linespace + 2*entryPtr->inset + 2*(YPAD-XPAD); if (entryPtr->prefWidth > 0) { width = entryPtr->prefWidth*entryPtr->avgWidth + 2*entryPtr->inset; + } else if (totalLength == 0) { + width = entryPtr->avgWidth + 2*entryPtr->inset; } else { - if (totalLength == 0) { - width = entryPtr->avgWidth + 2*entryPtr->inset; - } else { - width = totalLength + 2*entryPtr->inset; - } + width = totalLength + 2*entryPtr->inset; } /* @@ -2037,7 +2043,7 @@ InsertChars( Entry *entryPtr, /* Entry that is to get the new elements. */ int index, /* Add the new elements before this character * index. */ - char *value) /* New characters to add (NULL-terminated + const char *value) /* New characters to add (NULL-terminated * string). */ { ptrdiff_t byteIndex; @@ -2054,7 +2060,7 @@ InsertChars( } newByteCount = entryPtr->numBytes + byteCount + 1; - newStr = (char *) ckalloc((unsigned) newByteCount); + newStr = ckalloc(newByteCount); memcpy(newStr, string, byteIndex); strcpy(newStr + byteIndex, value); strcpy(newStr + byteIndex + byteCount, string + byteIndex); @@ -2155,11 +2161,11 @@ DeleteChars( byteCount = Tcl_UtfAtIndex(string + byteIndex, count) - (string+byteIndex); newByteCount = entryPtr->numBytes + 1 - byteCount; - newStr = (char *) ckalloc((unsigned) newByteCount); + newStr = ckalloc(newByteCount); memcpy(newStr, string, (size_t) byteIndex); strcpy(newStr + byteIndex, string + byteIndex + byteCount); - toDelete = (char *) ckalloc((unsigned) (byteCount + 1)); + toDelete = ckalloc(byteCount + 1); memcpy(toDelete, string + byteIndex, (size_t) byteCount); toDelete[byteCount] = '\0'; @@ -2263,8 +2269,8 @@ EntryValueChanged( if (entryPtr->textVarName == NULL) { newValue = NULL; } else { - newValue = Tcl_SetVar(entryPtr->interp, entryPtr->textVarName, - entryPtr->string, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG); + newValue = Tcl_SetVar2(entryPtr->interp, entryPtr->textVarName, + NULL, entryPtr->string, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG); } if ((newValue != NULL) && (strcmp(newValue, entryPtr->string) != 0)) { @@ -2345,7 +2351,7 @@ EntrySetValue( * during validation */ - char *tmp = (char *) ckalloc((unsigned) (valueLen + 1)); + char *tmp = ckalloc(valueLen + 1); strcpy(tmp, value); value = tmp; @@ -2374,7 +2380,7 @@ EntrySetValue( if (malloced) { entryPtr->string = value; } else { - char *tmp = (char *) ckalloc((unsigned) (valueLen + 1)); + char *tmp = ckalloc(valueLen + 1); strcpy(tmp, value); entryPtr->string = tmp; @@ -2434,10 +2440,10 @@ EntryEventProc( ClientData clientData, /* Information about window. */ XEvent *eventPtr) /* Information about event. */ { - Entry *entryPtr = (Entry *) clientData; + Entry *entryPtr = clientData; if ((entryPtr->type == TK_SPINBOX) && (eventPtr->type == MotionNotify)) { - Spinbox *sbPtr = (Spinbox *) clientData; + Spinbox *sbPtr = clientData; int elem; elem = GetSpinboxElement(sbPtr, eventPtr->xmotion.x, @@ -2474,15 +2480,15 @@ EntryEventProc( if (entryPtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayEntry, clientData); } - Tcl_EventuallyFree(clientData, DestroyEntry); + Tcl_EventuallyFree(clientData, (Tcl_FreeProc *) DestroyEntry); } break; case ConfigureNotify: - Tcl_Preserve((ClientData) entryPtr); + Tcl_Preserve(entryPtr); entryPtr->flags |= UPDATE_SCROLLBAR; EntryComputeGeometry(entryPtr); EventuallyRedraw(entryPtr); - Tcl_Release((ClientData) entryPtr); + Tcl_Release(entryPtr); break; case FocusIn: case FocusOut: @@ -2515,7 +2521,7 @@ static void EntryCmdDeletedProc( ClientData clientData) /* Pointer to widget record for widget. */ { - Entry *entryPtr = (Entry *) clientData; + Entry *entryPtr = clientData; /* * This function could be invoked either because the window was destroyed @@ -2554,40 +2560,41 @@ GetEntryIndex( Tcl_Interp *interp, /* For error messages. */ Entry *entryPtr, /* Entry for which the index is being * specified. */ - char *string, /* Specifies character in entryPtr. */ + const char *string, /* Specifies character in entryPtr. */ int *indexPtr) /* Where to store converted character index */ { size_t length; length = strlen(string); - if (string[0] == 'a') { - if (strncmp(string, "anchor", length) == 0) { - *indexPtr = entryPtr->selectAnchor; - } else { - badIndex: - - Tcl_AppendResult(interp, "bad ", - (entryPtr->type == TK_ENTRY) ? "entry" : "spinbox", - " index \"", string, "\"", NULL); - return TCL_ERROR; + switch (string[0]) { + case 'a': + if (strncmp(string, "anchor", length) != 0) { + goto badIndex; } - } else if (string[0] == 'e') { - if (strncmp(string, "end", length) == 0) { - *indexPtr = entryPtr->numChars; - } else { + *indexPtr = entryPtr->selectAnchor; + break; + case 'e': + if (strncmp(string, "end", length) != 0) { goto badIndex; } - } else if (string[0] == 'i') { - if (strncmp(string, "insert", length) == 0) { - *indexPtr = entryPtr->insertPos; - } else { + *indexPtr = entryPtr->numChars; + break; + case 'i': + if (strncmp(string, "insert", length) != 0) { goto badIndex; } - } else if (string[0] == 's') { + *indexPtr = entryPtr->insertPos; + break; + case 's': if (entryPtr->selectFirst < 0) { - Tcl_AppendResult(interp, "selection isn't in widget ", - Tk_PathName(entryPtr->tkwin), NULL); + Tcl_ResetResult(interp); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "selection isn't in widget %s", + Tk_PathName(entryPtr->tkwin))); + Tcl_SetErrorCode(interp, "TK", + (entryPtr->type == TK_ENTRY) ? "ENTRY" : "SPINBOX", + "NO_SELECTION", NULL); return TCL_ERROR; } if (length < 5) { @@ -2600,7 +2607,8 @@ GetEntryIndex( } else { goto badIndex; } - } else if (string[0] == '@') { + break; + case '@': { int x, roundUp, maxWidth; if (Tcl_GetInt(NULL, string + 1, &x) != TCL_OK) { @@ -2611,7 +2619,7 @@ GetEntryIndex( } roundUp = 0; maxWidth = Tk_Width(entryPtr->tkwin) - entryPtr->inset - - entryPtr->xWidth - 1; + - entryPtr->xWidth - 1; if (x > maxWidth) { x = maxWidth; roundUp = 1; @@ -2629,7 +2637,9 @@ GetEntryIndex( if (roundUp && (*indexPtr < entryPtr->numChars)) { *indexPtr += 1; } - } else { + break; + } + default: if (Tcl_GetInt(NULL, string, indexPtr) != TCL_OK) { goto badIndex; } @@ -2640,6 +2650,14 @@ GetEntryIndex( } } return TCL_OK; + + badIndex: + Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad %s index \"%s\"", + (entryPtr->type == TK_ENTRY) ? "entry" : "spinbox", string)); + Tcl_SetErrorCode(interp, "TK", + (entryPtr->type == TK_ENTRY) ? "ENTRY" : "SPINBOX", + "BAD_INDEX", NULL); + return TCL_ERROR; } /* @@ -2729,9 +2747,10 @@ EntrySelectTo( * Grab the selection if we don't own it already. */ - if (!(entryPtr->flags & GOT_SELECTION) && (entryPtr->exportSelection)) { + if (!(entryPtr->flags & GOT_SELECTION) && (entryPtr->exportSelection) + && (!Tcl_IsSafe(entryPtr->interp))) { Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, EntryLostSelection, - (ClientData) entryPtr); + entryPtr); entryPtr->flags |= GOT_SELECTION; } @@ -2791,12 +2810,13 @@ EntryFetchSelection( int maxBytes) /* Maximum number of bytes to place at buffer, * not including terminating NUL character. */ { - Entry *entryPtr = (Entry *) clientData; + Entry *entryPtr = clientData; int byteCount; const char *string; const char *selStart, *selEnd; - if ((entryPtr->selectFirst < 0) || !(entryPtr->exportSelection)) { + if ((entryPtr->selectFirst < 0) || (!entryPtr->exportSelection) + || Tcl_IsSafe(entryPtr->interp)) { return -1; } string = entryPtr->displayString; @@ -2814,7 +2834,7 @@ EntryFetchSelection( buffer[byteCount] = '\0'; return byteCount; } - + /* *---------------------------------------------------------------------- * @@ -2837,7 +2857,7 @@ static void EntryLostSelection( ClientData clientData) /* Information about entry widget. */ { - Entry *entryPtr = (Entry *) clientData; + Entry *entryPtr = clientData; entryPtr->flags &= ~GOT_SELECTION; @@ -2849,7 +2869,8 @@ EntryLostSelection( */ if (TkpAlwaysShowSelection(entryPtr->tkwin) - && (entryPtr->selectFirst >= 0) && entryPtr->exportSelection) { + && (entryPtr->selectFirst >= 0) && entryPtr->exportSelection + && (!Tcl_IsSafe(entryPtr->interp))) { entryPtr->selectFirst = -1; entryPtr->selectLast = -1; EventuallyRedraw(entryPtr); @@ -2891,7 +2912,7 @@ EventuallyRedraw( if (!(entryPtr->flags & REDRAW_PENDING)) { entryPtr->flags |= REDRAW_PENDING; - Tcl_DoWhenIdle(DisplayEntry, (ClientData) entryPtr); + Tcl_DoWhenIdle(DisplayEntry, entryPtr); } } @@ -2972,27 +2993,33 @@ EntryUpdateScrollbar( int code; double first, last; Tcl_Interp *interp; + Tcl_DString buf; if (entryPtr->scrollCmd == NULL) { return; } interp = entryPtr->interp; - Tcl_Preserve((ClientData) interp); + Tcl_Preserve(interp); EntryVisibleRange(entryPtr, &first, &last); Tcl_PrintDouble(NULL, first, firstStr); Tcl_PrintDouble(NULL, last, lastStr); - code = Tcl_VarEval(interp, entryPtr->scrollCmd, " ", firstStr, " ", - lastStr, NULL); + Tcl_DStringInit(&buf); + Tcl_DStringAppend(&buf, entryPtr->scrollCmd, -1); + Tcl_DStringAppend(&buf, " ", -1); + Tcl_DStringAppend(&buf, firstStr, -1); + Tcl_DStringAppend(&buf, " ", -1); + Tcl_DStringAppend(&buf, lastStr, -1); + code = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, 0); + Tcl_DStringFree(&buf); if (code != TCL_OK) { - Tcl_AddErrorInfo(interp, - "\n (horizontal scrolling command executed by "); - Tcl_AddErrorInfo(interp, Tk_PathName(entryPtr->tkwin)); - Tcl_AddErrorInfo(interp, ")"); - Tcl_BackgroundError(interp); + Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf( + "\n (horizontal scrolling command executed by %s)", + Tk_PathName(entryPtr->tkwin))); + Tcl_BackgroundException(interp, code); } - Tcl_SetResult(interp, NULL, TCL_STATIC); - Tcl_Release((ClientData) interp); + Tcl_ResetResult(interp); + Tcl_Release(interp); } /* @@ -3017,7 +3044,7 @@ static void EntryBlinkProc( ClientData clientData) /* Pointer to record describing entry. */ { - Entry *entryPtr = (Entry *) clientData; + Entry *entryPtr = clientData; if ((entryPtr->state == STATE_DISABLED) || (entryPtr->state == STATE_READONLY) || @@ -3027,11 +3054,11 @@ EntryBlinkProc( if (entryPtr->flags & CURSOR_ON) { entryPtr->flags &= ~CURSOR_ON; entryPtr->insertBlinkHandler = Tcl_CreateTimerHandler( - entryPtr->insertOffTime, EntryBlinkProc, (ClientData) entryPtr); + entryPtr->insertOffTime, EntryBlinkProc, entryPtr); } else { entryPtr->flags |= CURSOR_ON; entryPtr->insertBlinkHandler = Tcl_CreateTimerHandler( - entryPtr->insertOnTime, EntryBlinkProc, (ClientData) entryPtr); + entryPtr->insertOnTime, EntryBlinkProc, entryPtr); } EventuallyRedraw(entryPtr); } @@ -3065,23 +3092,22 @@ EntryFocusProc( entryPtr->flags |= GOT_FOCUS | CURSOR_ON; if (entryPtr->insertOffTime != 0) { entryPtr->insertBlinkHandler = Tcl_CreateTimerHandler( - entryPtr->insertOnTime, EntryBlinkProc, - (ClientData) entryPtr); + entryPtr->insertOnTime, EntryBlinkProc, entryPtr); } if (entryPtr->validate == VALIDATE_ALL || - entryPtr->validate == VALIDATE_FOCUS || - entryPtr->validate == VALIDATE_FOCUSIN) { - EntryValidateChange(entryPtr, NULL, - entryPtr->string, -1, VALIDATE_FOCUSIN); + entryPtr->validate == VALIDATE_FOCUS || + entryPtr->validate == VALIDATE_FOCUSIN) { + EntryValidateChange(entryPtr, NULL, entryPtr->string, -1, + VALIDATE_FOCUSIN); } } else { entryPtr->flags &= ~(GOT_FOCUS | CURSOR_ON); - entryPtr->insertBlinkHandler = (Tcl_TimerToken) NULL; + entryPtr->insertBlinkHandler = NULL; if (entryPtr->validate == VALIDATE_ALL || - entryPtr->validate == VALIDATE_FOCUS || - entryPtr->validate == VALIDATE_FOCUSOUT) { - EntryValidateChange(entryPtr, NULL, - entryPtr->string, -1, VALIDATE_FOCUSOUT); + entryPtr->validate == VALIDATE_FOCUS || + entryPtr->validate == VALIDATE_FOCUSOUT) { + EntryValidateChange(entryPtr, NULL, entryPtr->string, -1, + VALIDATE_FOCUSOUT); } } EventuallyRedraw(entryPtr); @@ -3113,7 +3139,7 @@ EntryTextVarProc( const char *name2, /* Not used. */ int flags) /* Information about what happened. */ { - Entry *entryPtr = (Entry *) clientData; + Entry *entryPtr = clientData; const char *value; if (entryPtr->flags & ENTRY_DELETED) { @@ -3129,14 +3155,34 @@ EntryTextVarProc( */ if (flags & TCL_TRACE_UNSETS) { - if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) { - Tcl_SetVar(interp, entryPtr->textVarName, entryPtr->string, - TCL_GLOBAL_ONLY); - Tcl_TraceVar(interp, entryPtr->textVarName, + if (!Tcl_InterpDeleted(interp) && entryPtr->textVarName) { + ClientData probe = NULL; + + do { + probe = Tcl_VarTraceInfo(interp, + entryPtr->textVarName, + TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + EntryTextVarProc, probe); + if (probe == (ClientData)entryPtr) { + break; + } + } while (probe); + if (probe) { + /* + * We were able to fetch the unset trace for our + * textVarName, which means it is not unset and not + * the cause of this unset trace. Instead some outdated + * former variable must be, and we should ignore it. + */ + return NULL; + } + Tcl_SetVar2(interp, entryPtr->textVarName, NULL, + entryPtr->string, TCL_GLOBAL_ONLY); + Tcl_TraceVar2(interp, entryPtr->textVarName, NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, EntryTextVarProc, clientData); entryPtr->flags |= ENTRY_VAR_TRACED; - } + } return NULL; } @@ -3146,7 +3192,7 @@ EntryTextVarProc( * value because we changed it because someone typed in the entry). */ - value = Tcl_GetVar(interp, entryPtr->textVarName, TCL_GLOBAL_ONLY); + value = Tcl_GetVar2(interp, entryPtr->textVarName, NULL, TCL_GLOBAL_ONLY); if (value == NULL) { value = ""; } @@ -3191,10 +3237,10 @@ EntryValidate( */ if (code != TCL_OK && code != TCL_RETURN) { - Tcl_AddErrorInfo(interp, "\n\t(in validation command executed by "); - Tcl_AddErrorInfo(interp, Tk_PathName(entryPtr->tkwin)); - Tcl_AddErrorInfo(interp, ")"); - Tcl_BackgroundError(interp); + Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf( + "\n (in validation command executed by %s)", + Tk_PathName(entryPtr->tkwin))); + Tcl_BackgroundException(interp, code); return TCL_ERROR; } @@ -3205,13 +3251,13 @@ EntryValidate( if (Tcl_GetBooleanFromObj(interp, Tcl_GetObjResult(interp), &bool) != TCL_OK) { Tcl_AddErrorInfo(interp, - "\nvalid boolean not returned by validation command"); - Tcl_BackgroundError(interp); - Tcl_SetResult(interp, NULL, 0); + "\n (invalid boolean result from validation command)"); + Tcl_BackgroundException(interp, TCL_ERROR); + Tcl_ResetResult(interp); return TCL_ERROR; } - Tcl_SetResult(interp, NULL, 0); + Tcl_ResetResult(interp); return (bool ? TCL_OK : TCL_BREAK); } @@ -3237,7 +3283,7 @@ EntryValidate( static int EntryValidateChange( register Entry *entryPtr, /* Entry that needs validation. */ - char *change, /* Characters to be added/deleted + const char *change, /* Characters to be added/deleted * (NUL-terminated string). */ const char *newValue, /* Potential new value of entry string */ int index, /* index of insert/delete, -1 otherwise */ @@ -3320,16 +3366,19 @@ EntryValidateChange( if (varValidate) { entryPtr->validate = VALIDATE_NONE; } else if (entryPtr->invalidCmd != NULL) { + int result; + Tcl_DStringInit(&script); ExpandPercents(entryPtr, entryPtr->invalidCmd, change, newValue, index, type, &script); Tcl_DStringAppend(&script, "", 1); p = Tcl_DStringValue(&script); - if (Tcl_EvalEx(entryPtr->interp, p, -1, - TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT) != TCL_OK) { + result = Tcl_EvalEx(entryPtr->interp, p, -1, + TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT); + if (result != TCL_OK) { Tcl_AddErrorInfo(entryPtr->interp, - "\n\t(in invalidcommand executed by entry)"); - Tcl_BackgroundError(entryPtr->interp); + "\n (in invalidcommand executed by entry)"); + Tcl_BackgroundException(entryPtr->interp, result); code = TCL_ERROR; entryPtr->validate = VALIDATE_NONE; } @@ -3388,7 +3437,7 @@ ExpandPercents( * list element. */ int number, length; register const char *string; - Tcl_UniChar ch; + int ch; char numStorage[2*TCL_INTEGER_SPACE]; while (1) { @@ -3421,7 +3470,7 @@ ExpandPercents( before++; /* skip over % */ if (*before != '\0') { - before += Tcl_UtfToUniChar(before, &ch); + before += TkUtfToUniChar(before, &ch); } else { ch = '%'; } @@ -3441,7 +3490,7 @@ ExpandPercents( string = Tk_PathName(entryPtr->tkwin); break; default: - length = Tcl_UniCharToUtf(ch, numStorage); + length = TkUniCharToUtf(ch, numStorage); numStorage[length] = '\0'; string = numStorage; break; @@ -3501,7 +3550,7 @@ ExpandPercents( string = Tk_PathName(entryPtr->tkwin); break; default: - length = Tcl_UniCharToUtf(ch, numStorage); + length = TkUniCharToUtf(ch, numStorage); numStorage[length] = '\0'; string = numStorage; break; @@ -3549,7 +3598,7 @@ Tk_SpinboxObjCmd( char *tmp; if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?"); + Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?"); return TCL_ERROR; } @@ -3573,7 +3622,7 @@ Tk_SpinboxObjCmd( * initialized as memset covers the rest. */ - sbPtr = (Spinbox *) ckalloc(sizeof(Spinbox)); + sbPtr = ckalloc(sizeof(Spinbox)); entryPtr = (Entry *) sbPtr; memset(sbPtr, 0, sizeof(Spinbox)); @@ -3581,11 +3630,11 @@ Tk_SpinboxObjCmd( entryPtr->display = Tk_Display(tkwin); entryPtr->interp = interp; entryPtr->widgetCmd = Tcl_CreateObjCommand(interp, - Tk_PathName(entryPtr->tkwin), SpinboxWidgetObjCmd, - (ClientData) sbPtr, EntryCmdDeletedProc); + Tk_PathName(entryPtr->tkwin), SpinboxWidgetObjCmd, sbPtr, + EntryCmdDeletedProc); entryPtr->optionTable = optionTable; entryPtr->type = TK_SPINBOX; - tmp = (char *) ckalloc(1); + tmp = ckalloc(1); tmp[0] = '\0'; entryPtr->string = tmp; entryPtr->selectFirst = -1; @@ -3612,7 +3661,7 @@ Tk_SpinboxObjCmd( sbPtr->fromValue = 0.0; sbPtr->toValue = 100.0; sbPtr->increment = 1.0; - sbPtr->formatBuf = (char *) ckalloc(TCL_DOUBLE_SPACE); + sbPtr->formatBuf = ckalloc(TCL_DOUBLE_SPACE); sbPtr->bdRelief = TK_RELIEF_FLAT; sbPtr->buRelief = TK_RELIEF_FLAT; @@ -3621,15 +3670,15 @@ Tk_SpinboxObjCmd( * otherwise Tk might free it while we still need it. */ - Tcl_Preserve((ClientData) entryPtr->tkwin); + Tcl_Preserve(entryPtr->tkwin); Tk_SetClass(entryPtr->tkwin, "Spinbox"); - Tk_SetClassProcs(entryPtr->tkwin, &entryClass, (ClientData) entryPtr); + Tk_SetClassProcs(entryPtr->tkwin, &entryClass, entryPtr); Tk_CreateEventHandler(entryPtr->tkwin, PointerMotionMask|ExposureMask|StructureNotifyMask|FocusChangeMask, - EntryEventProc, (ClientData) entryPtr); + EntryEventProc, entryPtr); Tk_CreateSelHandler(entryPtr->tkwin, XA_PRIMARY, XA_STRING, - EntryFetchSelection, (ClientData) entryPtr, XA_STRING); + EntryFetchSelection, entryPtr, XA_STRING); if (Tk_InitOptions(interp, (char *) sbPtr, optionTable, tkwin) != TCL_OK) { @@ -3640,10 +3689,10 @@ Tk_SpinboxObjCmd( goto error; } - Tcl_SetResult(interp, Tk_PathName(entryPtr->tkwin), TCL_STATIC); + Tcl_SetObjResult(interp, TkNewWindowObj(entryPtr->tkwin)); return TCL_OK; - error: + error: Tk_DestroyWindow(entryPtr->tkwin); return TCL_ERROR; } @@ -3673,13 +3722,13 @@ SpinboxWidgetObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - Entry *entryPtr = (Entry *) clientData; - Spinbox *sbPtr = (Spinbox *) clientData; + Entry *entryPtr = clientData; + Spinbox *sbPtr = clientData; int cmdIndex, selIndex, result; Tcl_Obj *objPtr; if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?"); + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); return TCL_ERROR; } @@ -3694,11 +3743,11 @@ SpinboxWidgetObjCmd( return result; } - Tcl_Preserve((ClientData) entryPtr); + Tcl_Preserve(entryPtr); switch ((enum sbCmd) cmdIndex) { case SB_CMD_BBOX: { int index, x, y, width, height; - char buf[TCL_INTEGER_SPACE * 4]; + Tcl_Obj *bbox[4]; if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "index"); @@ -3711,11 +3760,12 @@ SpinboxWidgetObjCmd( if ((index == entryPtr->numChars) && (index > 0)) { index--; } - Tk_CharBbox(entryPtr->textLayout, index, &x, &y, - &width, &height); - sprintf(buf, "%d %d %d %d", x + entryPtr->layoutX, - y + entryPtr->layoutY, width, height); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tk_CharBbox(entryPtr->textLayout, index, &x, &y, &width, &height); + bbox[0] = Tcl_NewIntObj(x + entryPtr->layoutX); + bbox[1] = Tcl_NewIntObj(y + entryPtr->layoutY); + bbox[2] = Tcl_NewIntObj(width); + bbox[3] = Tcl_NewIntObj(height); + Tcl_SetObjResult(interp, Tcl_NewListObj(4, bbox)); break; } @@ -3729,22 +3779,19 @@ SpinboxWidgetObjCmd( entryPtr->optionTable, objv[2], entryPtr->tkwin); if (objPtr == NULL) { goto error; - } else { - Tcl_SetObjResult(interp, objPtr); } + Tcl_SetObjResult(interp, objPtr); break; case SB_CMD_CONFIGURE: if (objc <= 3) { objPtr = Tk_GetOptionInfo(interp, (char *) entryPtr, - entryPtr->optionTable, - (objc == 3) ? objv[2] : NULL, + entryPtr->optionTable, (objc == 3) ? objv[2] : NULL, entryPtr->tkwin); if (objPtr == NULL) { goto error; - } else { - Tcl_SetObjResult(interp, objPtr); } + Tcl_SetObjResult(interp, objPtr); } else { result = ConfigureEntry(interp, entryPtr, objc-2, objv+2); } @@ -3783,7 +3830,7 @@ SpinboxWidgetObjCmd( Tcl_WrongNumArgs(interp, 2, objv, NULL); goto error; } - Tcl_SetStringObj(Tcl_GetObjResult(interp), entryPtr->string, -1); + Tcl_SetObjResult(interp, Tcl_NewStringObj(entryPtr->string, -1)); break; case SB_CMD_ICURSOR: @@ -3811,8 +3858,8 @@ SpinboxWidgetObjCmd( } elem = GetSpinboxElement(sbPtr, x, y); if (elem != SEL_NONE) { - Tcl_SetStringObj(Tcl_GetObjResult(interp), - selElementNames[elem], -1); + Tcl_SetObjResult(interp, + Tcl_NewStringObj(selElementNames[elem], -1)); } break; } @@ -3871,7 +3918,7 @@ SpinboxWidgetObjCmd( case SB_CMD_SCAN: { int x; - char *minorCmd; + const char *minorCmd; if (objc != 4) { Tcl_WrongNumArgs(interp, 2, objv, "mark|dragto x"); @@ -3890,9 +3937,11 @@ SpinboxWidgetObjCmd( && (strncmp(minorCmd, "dragto", strlen(minorCmd)) == 0)) { EntryScanTo(entryPtr, x); } else { - Tcl_AppendResult(interp, "bad scan option \"", - Tcl_GetString(objv[2]), "\": must be mark or dragto", - NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad scan option \"%s\": must be mark or dragto", + minorCmd)); + Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "scan option", + minorCmd, NULL); goto error; } break; @@ -3985,8 +4034,8 @@ SpinboxWidgetObjCmd( Tcl_WrongNumArgs(interp, 3, objv, NULL); goto error; } - Tcl_SetObjResult(interp, - Tcl_NewBooleanObj((entryPtr->selectFirst >= 0))); + Tcl_SetObjResult(interp, Tcl_NewBooleanObj( + entryPtr->selectFirst >= 0)); goto done; case SB_SEL_RANGE: @@ -4010,9 +4059,10 @@ SpinboxWidgetObjCmd( entryPtr->selectLast = index2; } if (!(entryPtr->flags & GOT_SELECTION) - && (entryPtr->exportSelection)) { + && entryPtr->exportSelection + && (!Tcl_IsSafe(entryPtr->interp))) { Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, - EntryLostSelection, (ClientData) entryPtr); + EntryLostSelection, entryPtr); entryPtr->flags |= GOT_SELECTION; } EventuallyRedraw(entryPtr); @@ -4036,8 +4086,8 @@ SpinboxWidgetObjCmd( goto error; } if (objc == 3) { - Tcl_SetStringObj(Tcl_GetObjResult(interp), - selElementNames[sbPtr->selElement], -1); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + selElementNames[sbPtr->selElement], -1)); } else { int lastElement = sbPtr->selElement; @@ -4068,7 +4118,7 @@ SpinboxWidgetObjCmd( goto error; } } - Tcl_SetStringObj(Tcl_GetObjResult(interp), entryPtr->string, -1); + Tcl_SetObjResult(interp, Tcl_NewStringObj(entryPtr->string, -1)); break; } @@ -4086,7 +4136,8 @@ SpinboxWidgetObjCmd( if (entryPtr->validate != VALIDATE_NONE) { entryPtr->validate = selIndex; } - Tcl_SetObjResult(interp, Tcl_NewBooleanObj((code == TCL_OK))); + + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(code == TCL_OK)); break; } @@ -4095,13 +4146,12 @@ SpinboxWidgetObjCmd( if (objc == 2) { double first, last; - char buf[TCL_DOUBLE_SPACE]; + Tcl_Obj *span[2]; EntryVisibleRange(entryPtr, &first, &last); - Tcl_PrintDouble(NULL, first, buf); - Tcl_SetResult(interp, buf, TCL_VOLATILE); - Tcl_PrintDouble(NULL, last, buf); - Tcl_AppendResult(interp, " ", buf, NULL); + span[0] = Tcl_NewDoubleObj(first); + span[1] = Tcl_NewDoubleObj(last); + Tcl_SetObjResult(interp, Tcl_NewListObj(2, span)); goto done; } else if (objc == 3) { if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]), @@ -4152,11 +4202,11 @@ SpinboxWidgetObjCmd( } done: - Tcl_Release((ClientData) entryPtr); + Tcl_Release(entryPtr); return result; error: - Tcl_Release((ClientData) entryPtr); + Tcl_Release(entryPtr); return TCL_ERROR; } @@ -4225,7 +4275,7 @@ SpinboxInvoke( * "down" button. */ { Entry *entryPtr = (Entry *) sbPtr; - char *type; + const char *type; int code, up; Tcl_DString script; @@ -4256,7 +4306,7 @@ SpinboxInvoke( */ int i, listc, elemLen, length = entryPtr->numChars; - char *bytes; + const char *bytes; Tcl_Obj **listv; Tcl_ListObjGetElements(interp, sbPtr->listObj, &listc, &listv); @@ -4353,8 +4403,9 @@ SpinboxInvoke( Tcl_DStringFree(&script); if (code != TCL_OK) { - Tcl_AddErrorInfo(interp, "\n\t(in command executed by spinbox)"); - Tcl_BackgroundError(interp); + Tcl_AddErrorInfo(interp, + "\n (in command executed by spinbox)"); + Tcl_BackgroundException(interp, code); /* * Yes, it's an error, but a bg one, so we return OK @@ -4363,7 +4414,7 @@ SpinboxInvoke( return TCL_OK; } - Tcl_SetResult(interp, NULL, 0); + Tcl_ResetResult(interp); } return TCL_OK; diff --git a/generic/tkEntry.h b/generic/tkEntry.h index da06408..6b1bf87 100644 --- a/generic/tkEntry.h +++ b/generic/tkEntry.h @@ -6,7 +6,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * Copyright (c) 2002 Apple Computer, Inc. + * Copyright (c) 2002 Apple Inc. */ #ifndef _TKENTRY @@ -16,11 +16,6 @@ #include "tkInt.h" #endif -#ifdef BUILD_tk -#undef TCL_STORAGE_CLASS -#define TCL_STORAGE_CLASS DLLEXPORT -#endif - enum EntryType { TK_ENTRY, TK_SPINBOX }; @@ -48,7 +43,7 @@ typedef struct { * Fields that are set by widget commands other than "configure". */ - CONST char *string; /* Pointer to storage for string; + const char *string; /* Pointer to storage for string; * NULL-terminated; malloc-ed. */ int insertPos; /* Character index before which next typed * character will be inserted. */ @@ -138,7 +133,7 @@ typedef struct { * configuration settings above. */ - CONST char *displayString; /* String to use when displaying. This may be + const char *displayString; /* String to use when displaying. This may be * a pointer to string, or a pointer to * malloced memory with the same character * length as string but whose characters are @@ -300,7 +295,4 @@ MODULE_SCOPE int TkpDrawEntryBorderAndFocus(Entry *entryPtr, Drawable d, int isSpinbox); MODULE_SCOPE int TkpDrawSpinboxButtons(Spinbox *sbPtr, Drawable d); -#undef TCL_STORAGE_CLASS -#define TCL_STORAGE_CLASS DLLIMPORT - #endif /* _TKENTRY */ diff --git a/generic/tkError.c b/generic/tkError.c index 6617c37..277d7f0 100644 --- a/generic/tkError.c +++ b/generic/tkError.c @@ -82,8 +82,8 @@ Tk_CreateErrorHandler( * errors. */ ClientData clientData) /* Arbitrary value to pass to errorProc. */ { - register TkErrorHandler *errorPtr; - register TkDisplay *dispPtr; + TkErrorHandler *errorPtr; + TkDisplay *dispPtr; /* * Find the display. If Tk doesn't know about this display then it's an @@ -107,7 +107,7 @@ Tk_CreateErrorHandler( * Create the handler record. */ - errorPtr = (TkErrorHandler *) ckalloc(sizeof(TkErrorHandler)); + errorPtr = ckalloc(sizeof(TkErrorHandler)); errorPtr->dispPtr = dispPtr; errorPtr->firstRequest = NextRequest(display); errorPtr->lastRequest = (unsigned) -1; @@ -147,8 +147,8 @@ Tk_DeleteErrorHandler( Tk_ErrorHandler handler) /* Token for handler to delete; was previous * return value from Tk_CreateErrorHandler. */ { - register TkErrorHandler *errorPtr = (TkErrorHandler *) handler; - register TkDisplay *dispPtr = errorPtr->dispPtr; + TkErrorHandler *errorPtr = (TkErrorHandler *) handler; + TkDisplay *dispPtr = errorPtr->dispPtr; errorPtr->lastRequest = NextRequest(dispPtr->display) - 1; @@ -166,12 +166,20 @@ Tk_DeleteErrorHandler( dispPtr->deleteCount += 1; if (dispPtr->deleteCount >= 10) { - register TkErrorHandler *prevPtr; + TkErrorHandler *prevPtr; TkErrorHandler *nextPtr; - int lastSerial; + int lastSerial = LastKnownRequestProcessed(dispPtr->display); + /* + * Last chance to catch errors for this handler: if no event/error + * processing took place to follow up the end of this error handler + * we need a round trip with the X server now. + */ + + if (errorPtr->lastRequest > (unsigned long) lastSerial) { + XSync(dispPtr->display, False); + } dispPtr->deleteCount = 0; - lastSerial = LastKnownRequestProcessed(dispPtr->display); errorPtr = dispPtr->errorPtr; for (prevPtr = NULL; errorPtr != NULL; errorPtr = nextPtr) { nextPtr = errorPtr->nextPtr; @@ -182,7 +190,7 @@ Tk_DeleteErrorHandler( } else { prevPtr->nextPtr = nextPtr; } - ckfree((char *) errorPtr); + ckfree(errorPtr); continue; } prevPtr = errorPtr; @@ -213,11 +221,11 @@ Tk_DeleteErrorHandler( static int ErrorProc( Display *display, /* Display for which error occurred. */ - register XErrorEvent *errEventPtr) + XErrorEvent *errEventPtr) /* Information about error. */ { - register TkDisplay *dispPtr; - register TkErrorHandler *errorPtr; + TkDisplay *dispPtr; + TkErrorHandler *errorPtr; /* * See if we know anything about the display. If not, then invoke the @@ -246,8 +254,8 @@ ErrorProc( && (errorPtr->lastRequest < errEventPtr->serial))) { continue; } - if (errorPtr->errorProc == NULL || (*errorPtr->errorProc)( - errorPtr->clientData, errEventPtr) == 0) { + if (errorPtr->errorProc == NULL || + errorPtr->errorProc(errorPtr->clientData, errEventPtr) == 0) { return 0; } } @@ -269,8 +277,7 @@ ErrorProc( if (errEventPtr->error_code == BadWindow) { Window w = (Window) errEventPtr->resourceid; - if (Tk_IdToWindow(display, w) != NULL - || TkpWindowWasRecentlyDeleted(w, dispPtr)) { + if (Tk_IdToWindow(display, w) != NULL) { return 0; } } @@ -280,7 +287,7 @@ ErrorProc( */ couldntHandle: - return (*defaultHandler)(display, errEventPtr); + return defaultHandler(display, errEventPtr); } /* diff --git a/generic/tkEvent.c b/generic/tkEvent.c index 0dd13dc..891f667 100644 --- a/generic/tkEvent.c +++ b/generic/tkEvent.c @@ -73,7 +73,7 @@ typedef struct TkWindowEvent { * Array of event masks corresponding to each X event: */ -static unsigned long realEventMasks[MappingNotify+1] = { +static const unsigned long realEventMasks[MappingNotify+1] = { 0, 0, KeyPressMask, /* KeyPress */ @@ -114,7 +114,7 @@ static unsigned long realEventMasks[MappingNotify+1] = { 0 /* Mapping Notify */ }; -static unsigned long virtualEventMasks[TK_LASTEVENT-VirtualEvent] = { +static const unsigned long virtualEventMasks[TK_LASTEVENT-VirtualEvent] = { VirtualEventMask, /* VirtualEvents */ ActivateMask, /* ActivateNotify */ ActivateMask, /* DeactivateNotify */ @@ -245,16 +245,10 @@ InvokeFocusHandlers( } /* - * MouseWheel events are not focus specific on Mac OS X. + * Only key-related events are directed according to the focus. */ -#ifdef MAC_OSX_TK -#define FOCUS_DIRECTED_EVENT_MASK (KeyPressMask|KeyReleaseMask) -#else -#define FOCUS_DIRECTED_EVENT_MASK (KeyPressMask|KeyReleaseMask|MouseWheelMask) -#endif - - if (mask & FOCUS_DIRECTED_EVENT_MASK) { + if (mask & (KeyPressMask|KeyReleaseMask)) { (*winPtrPtr)->dispPtr->lastEventTime = eventPtr->xkey.time; *winPtrPtr = TkFocusKeyEvent(*winPtrPtr, eventPtr); if (*winPtrPtr == NULL) { @@ -326,7 +320,7 @@ InvokeMouseHandlers( *---------------------------------------------------------------------- */ -#if defined(TK_USE_INPUT_METHODS) +#ifdef TK_USE_INPUT_METHODS static void CreateXIC( TkWindow *winPtr) @@ -357,12 +351,13 @@ CreateXIC( XFree(preedit_attlist); } - + if (winPtr->inputContext == NULL) { /* XCreateIC failed. */ - return; + return; } - + winPtr->ximGeneration = dispPtr->ximGeneration; + /* * Adjust the window's event mask if the IM requires it. */ @@ -668,7 +663,7 @@ InvokeClientMessageHandlers( if (tmpPtr == NULL) { tsdPtr->lastCmPtr = prevPtr; } - (void) ckfree((char *) curPtr); + ckfree(curPtr); curPtr = tmpPtr; continue; } @@ -730,7 +725,7 @@ InvokeGenericHandlers( if (tmpPtr == NULL) { tsdPtr->lastGenericPtr = prevPtr; } - (void) ckfree((char *) curPtr); + ckfree(curPtr); curPtr = tmpPtr; continue; } @@ -738,7 +733,7 @@ InvokeGenericHandlers( int done; tsdPtr->handlersActive++; - done = (*curPtr->proc)(curPtr->clientData, eventPtr); + done = curPtr->proc(curPtr->clientData, eventPtr); tsdPtr->handlersActive--; if (done) { return done; @@ -794,7 +789,7 @@ Tk_CreateEventHandler( * No event handlers defined at all, so must create. */ - handlerPtr = (TkEventHandler *) ckalloc(sizeof(TkEventHandler)); + handlerPtr = ckalloc(sizeof(TkEventHandler)); winPtr->handlerList = handlerPtr; } else { int found = 0; @@ -825,8 +820,7 @@ Tk_CreateEventHandler( * No event handler matched, so create a new one. */ - handlerPtr->nextPtr = (TkEventHandler *) - ckalloc(sizeof(TkEventHandler)); + handlerPtr->nextPtr = ckalloc(sizeof(TkEventHandler)); handlerPtr = handlerPtr->nextPtr; } @@ -873,7 +867,7 @@ Tk_DeleteEventHandler( register InProgress *ipPtr; TkEventHandler *prevPtr; register TkWindow *winPtr = (TkWindow *) token; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* @@ -912,7 +906,7 @@ Tk_DeleteEventHandler( } else { prevPtr->nextPtr = handlerPtr->nextPtr; } - ckfree((char *) handlerPtr); + ckfree(handlerPtr); /* * No need to call XSelectInput: Tk always selects on all events for all @@ -945,10 +939,10 @@ Tk_CreateGenericHandler( ClientData clientData) /* One-word value to pass to proc. */ { GenericHandler *handlerPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - handlerPtr = (GenericHandler *) ckalloc(sizeof(GenericHandler)); + handlerPtr = ckalloc(sizeof(GenericHandler)); handlerPtr->proc = proc; handlerPtr->clientData = clientData; @@ -986,7 +980,7 @@ Tk_DeleteGenericHandler( ClientData clientData) { GenericHandler * handler; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); for (handler=tsdPtr->genericList ; handler ; handler=handler->nextPtr) { @@ -1019,7 +1013,7 @@ Tk_CreateClientMessageHandler( Tk_ClientMessageProc *proc) /* Function to call on event. */ { GenericHandler *handlerPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* @@ -1027,7 +1021,7 @@ Tk_CreateClientMessageHandler( * with an extra clientData field we'll never use. */ - handlerPtr = (GenericHandler *) ckalloc(sizeof(GenericHandler)); + handlerPtr = ckalloc(sizeof(GenericHandler)); handlerPtr->proc = (Tk_GenericProc *) proc; handlerPtr->clientData = NULL; /* never used */ @@ -1065,7 +1059,7 @@ Tk_DeleteClientMessageHandler( Tk_ClientMessageProc *proc) { GenericHandler * handler; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); for (handler=tsdPtr->cmList ; handler!=NULL ; handler=handler->nextPtr) { @@ -1096,7 +1090,7 @@ Tk_DeleteClientMessageHandler( void TkEventInit(void) { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); tsdPtr->handlersActive = 0; @@ -1131,9 +1125,8 @@ TkXErrorHandler( ClientData clientData, /* Pointer to flag we set. */ XErrorEvent *errEventPtr) /* X error info. */ { - int *error; + int *error = clientData; - error = (int *) clientData; *error = 1; return 0; } @@ -1174,7 +1167,7 @@ ParentXId( gotXError = 0; handler = Tk_CreateErrorHandler(display, -1, -1, -1, - TkXErrorHandler, (ClientData) (&gotXError)); + TkXErrorHandler, &gotXError); /* * Get the parent window. @@ -1224,7 +1217,7 @@ Tk_HandleEvent( unsigned long mask; InProgress ip; Tcl_Interp *interp = NULL; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); UpdateButtonEventState(eventPtr); @@ -1278,7 +1271,7 @@ Tk_HandleEvent( * code. */ - Tcl_Preserve((ClientData) interp); + Tcl_Preserve(interp); result = ((InvokeFocusHandlers(&winPtr, mask, eventPtr)) || (InvokeMouseHandlers(winPtr, mask, eventPtr))); @@ -1296,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; @@ -1303,11 +1304,13 @@ 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); } } -#endif +#endif /*TK_USE_INPUT_METHODS*/ /* * For events where it hasn't already been done, update the current time @@ -1338,15 +1341,15 @@ Tk_HandleEvent( Tk_InternAtom((Tk_Window) winPtr, "WM_PROTOCOLS")) { TkWmProtocolEventProc(winPtr, eventPtr); } else { - InvokeClientMessageHandlers(tsdPtr, (Tk_Window)winPtr, + InvokeClientMessageHandlers(tsdPtr, (Tk_Window) winPtr, eventPtr); } } } else { for (handlerPtr = winPtr->handlerList; handlerPtr != NULL; ) { - if ((handlerPtr->mask & mask) != 0) { + if (handlerPtr->mask & mask) { ip.nextHandler = handlerPtr->nextPtr; - (*(handlerPtr->proc))(handlerPtr->clientData, eventPtr); + handlerPtr->proc(handlerPtr->clientData, eventPtr); handlerPtr = ip.nextHandler; } else { handlerPtr = handlerPtr->nextPtr; @@ -1380,7 +1383,7 @@ Tk_HandleEvent( releaseInterpreter: if (interp != NULL) { - Tcl_Release((ClientData) interp); + Tcl_Release(interp); } /* @@ -1418,7 +1421,7 @@ TkEventDeadWindow( { register TkEventHandler *handlerPtr; register InProgress *ipPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* @@ -1439,7 +1442,7 @@ TkEventDeadWindow( ipPtr->winPtr = NULL; } } - ckfree((char *) handlerPtr); + ckfree(handlerPtr); } } @@ -1467,7 +1470,7 @@ TkCurrentTime( TkDisplay *dispPtr) /* Display for which the time is desired. */ { register XEvent *eventPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (tsdPtr->pendingPtr == NULL) { @@ -1521,7 +1524,7 @@ Tk_RestrictEvents( * argument. */ { Tk_RestrictProc *prev; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); prev = tsdPtr->restrictProc; @@ -1614,7 +1617,7 @@ Tk_QueueWindowEvent( */ if (!(dispPtr->flags & TK_DISPLAY_COLLAPSE_MOTION_EVENTS)) { - wevPtr = (TkWindowEvent *) ckalloc(sizeof(TkWindowEvent)); + wevPtr = ckalloc(sizeof(TkWindowEvent)); wevPtr->header.proc = WindowEventProc; wevPtr->event = *eventPtr; Tcl_QueueEvent(&wevPtr->header, position); @@ -1642,11 +1645,11 @@ Tk_QueueWindowEvent( Tcl_QueueEvent(&dispPtr->delayedMotionPtr->header, position); dispPtr->delayedMotionPtr = NULL; - Tcl_CancelIdleCall(DelayedMotionProc, (ClientData) dispPtr); + Tcl_CancelIdleCall(DelayedMotionProc, dispPtr); } } - wevPtr = (TkWindowEvent *) ckalloc(sizeof(TkWindowEvent)); + wevPtr = ckalloc(sizeof(TkWindowEvent)); wevPtr->header.proc = WindowEventProc; wevPtr->event = *eventPtr; if ((eventPtr->type == MotionNotify) && (position == TCL_QUEUE_TAIL)) { @@ -1660,7 +1663,7 @@ Tk_QueueWindowEvent( Tcl_Panic("Tk_QueueWindowEvent found unexpected delayed motion event"); } dispPtr->delayedMotionPtr = wevPtr; - Tcl_DoWhenIdle(DelayedMotionProc, (ClientData) dispPtr); + Tcl_DoWhenIdle(DelayedMotionProc, dispPtr); } else { Tcl_QueueEvent(&wevPtr->header, position); } @@ -1736,14 +1739,14 @@ WindowEventProc( { TkWindowEvent *wevPtr = (TkWindowEvent *) evPtr; Tk_RestrictAction result; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (!(flags & TCL_WINDOW_EVENTS)) { return 0; } if (tsdPtr->restrictProc != NULL) { - result = (*tsdPtr->restrictProc)(tsdPtr->restrictArg, &wevPtr->event); + result = tsdPtr->restrictProc(tsdPtr->restrictArg, &wevPtr->event); if (result != TK_PROCESS_EVENT) { if (result == TK_DEFER_EVENT) { return 0; @@ -1835,7 +1838,7 @@ DelayedMotionProc( ClientData clientData) /* Pointer to display containing a delayed * motion event to be serviced. */ { - TkDisplay *dispPtr = (TkDisplay *) clientData; + TkDisplay *dispPtr = clientData; if (dispPtr->delayedMotionPtr == NULL) { Tcl_Panic("DelayedMotionProc found no delayed mouse motion event"); @@ -1867,7 +1870,7 @@ TkCreateExitHandler( { ExitHandler *exitPtr; - exitPtr = (ExitHandler *) ckalloc(sizeof(ExitHandler)); + exitPtr = ckalloc(sizeof(ExitHandler)); exitPtr->proc = proc; exitPtr->clientData = clientData; Tcl_MutexLock(&exitMutex); @@ -1932,7 +1935,7 @@ TkDeleteExitHandler( } else { prevPtr->nextPtr = exitPtr->nextPtr; } - ckfree((char *) exitPtr); + ckfree(exitPtr); break; } } @@ -1963,10 +1966,10 @@ TkCreateThreadExitHandler( ClientData clientData) /* Arbitrary value to pass to proc. */ { ExitHandler *exitPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - exitPtr = (ExitHandler *) ckalloc(sizeof(ExitHandler)); + exitPtr = ckalloc(sizeof(ExitHandler)); exitPtr->proc = proc; exitPtr->clientData = clientData; @@ -2004,7 +2007,7 @@ TkDeleteThreadExitHandler( ClientData clientData) /* Arbitrary value to pass to proc. */ { ExitHandler *exitPtr, *prevPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); for (prevPtr = NULL, exitPtr = tsdPtr->firstExitPtr; exitPtr != NULL; @@ -2016,7 +2019,7 @@ TkDeleteThreadExitHandler( } else { prevPtr->nextPtr = exitPtr->nextPtr; } - ckfree((char *) exitPtr); + ckfree(exitPtr); return; } } @@ -2065,8 +2068,8 @@ TkFinalize( firstExitPtr = exitPtr->nextPtr; Tcl_MutexUnlock(&exitMutex); - (*exitPtr->proc)(exitPtr->clientData); - ckfree((char *) exitPtr); + exitPtr->proc(exitPtr->clientData); + ckfree(exitPtr); Tcl_MutexLock(&exitMutex); } firstExitPtr = NULL; @@ -2079,7 +2082,7 @@ TkFinalize( * TkFinalizeThread -- * * Runs our private thread exit handlers and removes itself from Tcl. - * This is benificial should we want to protect from dangling pointers + * This is beneficial should we want to protect from dangling pointers * should the Tk shared library be unloaded prior to Tcl which can happen * on Windows should the process be forcefully exiting from an exception * handler. @@ -2098,7 +2101,7 @@ TkFinalizeThread( ClientData clientData) /* Arbitrary value to pass to proc. */ { ExitHandler *exitPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); Tcl_DeleteThreadExitHandler(TkFinalizeThread, NULL); @@ -2115,8 +2118,8 @@ TkFinalizeThread( */ tsdPtr->firstExitPtr = exitPtr->nextPtr; - (*exitPtr->proc)(exitPtr->clientData); - ckfree((char *) exitPtr); + exitPtr->proc(exitPtr->clientData); + ckfree(exitPtr); } } } diff --git a/generic/tkFileFilter.c b/generic/tkFileFilter.c index 547dd9b..8588d70 100644 --- a/generic/tkFileFilter.c +++ b/generic/tkFileFilter.c @@ -13,13 +13,10 @@ #include "tkInt.h" #include "tkFileFilter.h" -static int AddClause(Tcl_Interp *interp, - FileFilter *filterPtr, Tcl_Obj *patternsObj, - Tcl_Obj *ostypesObj, int isWindows); -static void FreeClauses(FileFilter *filterPtr); -static void FreeGlobPatterns(FileFilterClause *clausePtr); -static void FreeMacFileTypes(FileFilterClause *clausePtr); -static FileFilter * GetFilter(FileFilterList *flistPtr, CONST char *name); +static int AddClause(Tcl_Interp *interp, FileFilter *filterPtr, + Tcl_Obj *patternsObj, Tcl_Obj *ostypesObj, + int isWindows); +static FileFilter * GetFilter(FileFilterList *flistPtr, const char *name); /* *---------------------------------------------------------------------- @@ -87,7 +84,7 @@ TkGetFileFilters( int i; if (types == NULL) { - return TCL_OK; + return TCL_OK; } if (Tcl_ListObjGetElements(interp, types, &listObjc, @@ -103,6 +100,7 @@ TkGetFileFilters( * the -filefilters option may have been used more than once in the * command line. */ + TkFreeFileFilters(flistPtr); for (i = 0; i<listObjc; i++) { @@ -122,10 +120,12 @@ TkGetFileFilters( } if (count != 2 && count != 3) { - Tcl_AppendResult(interp, "bad file type \"", - Tcl_GetString(listObjv[i]), "\", ", - "should be \"typeName {extension ?extensions ...?} ", - "?{macType ?macTypes ...?}?\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad file type \"%s\", should be " + "\"typeName {extension ?extensions ...?} " + "?{macType ?macTypes ...?}?\"", + Tcl_GetString(listObjv[i]))); + Tcl_SetErrorCode(interp, "TK", "VALUE", "FILE_TYPE", NULL); return TCL_ERROR; } @@ -160,15 +160,47 @@ void TkFreeFileFilters( FileFilterList *flistPtr) /* List of file filters to free */ { - FileFilter *filterPtr, *toFree; + FileFilter *filterPtr; + FileFilterClause *clausePtr; + GlobPattern *globPtr; + MacFileType *mfPtr; + register void *toFree; /* A pointer that we are about to free. */ + + for (filterPtr = flistPtr->filters; filterPtr != NULL; ) { + for (clausePtr = filterPtr->clauses; clausePtr != NULL; ) { + /* + * Squelch each of the glob patterns. + */ + + for (globPtr = clausePtr->patterns; globPtr != NULL; ) { + ckfree(globPtr->pattern); + toFree = globPtr; + globPtr = globPtr->next; + ckfree(toFree); + } + + /* + * Squelch each of the Mac file type codes. + */ + + for (mfPtr = clausePtr->macTypes; mfPtr != NULL; ) { + toFree = mfPtr; + mfPtr = mfPtr->next; + ckfree(toFree); + } + toFree = clausePtr; + clausePtr = clausePtr->next; + ckfree(toFree); + } + + /* + * Squelch the name of the filter and the overall structure. + */ - filterPtr=flistPtr->filters; - while (filterPtr != NULL) { + ckfree(filterPtr->name); toFree = filterPtr; filterPtr = filterPtr->next; - FreeClauses(toFree); - ckfree((char*)toFree->name); - ckfree((char*)toFree); + ckfree(toFree); } flistPtr->filters = NULL; } @@ -231,7 +263,7 @@ AddClause( for (i=0; i<ostypeCount; i++) { int len; - CONST char *strType = Tcl_GetStringFromObj(ostypeList[i], &len); + const char *strType = Tcl_GetStringFromObj(ostypeList[i], &len); /* * If len is < 4, it is definitely an error. If equal or longer, @@ -259,8 +291,10 @@ AddClause( Tcl_DStringFree(&osTypeDS); } if (len != 4) { - Tcl_AppendResult(interp, "bad Macintosh file type \"", - Tcl_GetString(ostypeList[i]), "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad Macintosh file type \"%s\"", + Tcl_GetString(ostypeList[i]))); + Tcl_SetErrorCode(interp, "TK", "VALUE", "MAC_TYPE", NULL); code = TCL_ERROR; goto done; } @@ -271,10 +305,10 @@ AddClause( * Add the clause into the list of clauses */ - clausePtr = (FileFilterClause*)ckalloc(sizeof(FileFilterClause)); - clausePtr->patterns = NULL; + clausePtr = ckalloc(sizeof(FileFilterClause)); + clausePtr->patterns = NULL; clausePtr->patternsTail = NULL; - clausePtr->macTypes = NULL; + clausePtr->macTypes = NULL; clausePtr->macTypesTail = NULL; if (filterPtr->clauses == NULL) { @@ -287,39 +321,38 @@ AddClause( if (globCount > 0 && globList != NULL) { for (i=0; i<globCount; i++) { - GlobPattern *globPtr = (GlobPattern*)ckalloc(sizeof(GlobPattern)); + GlobPattern *globPtr = ckalloc(sizeof(GlobPattern)); int len; + const char *str = Tcl_GetStringFromObj(globList[i], &len); - CONST char *str = Tcl_GetStringFromObj(globList[i], &len); len = (len + 1) * sizeof(char); - if (str[0] && str[0] != '*') { /* * Prepend a "*" to patterns that do not have a leading "*" */ - globPtr->pattern = (char*)ckalloc((unsigned int) len+1); + globPtr->pattern = ckalloc(len + 1); globPtr->pattern[0] = '*'; strcpy(globPtr->pattern+1, str); } else if (isWindows) { if (strcmp(str, "*") == 0) { - globPtr->pattern = (char*)ckalloc(4 * sizeof(char)); + globPtr->pattern = ckalloc(4); strcpy(globPtr->pattern, "*.*"); } else if (strcmp(str, "") == 0) { /* * An empty string means "match all files with no * extensions" - * BUG: "*." actually matches with all files on Win95 + * TODO: "*." actually matches with all files on Win95 */ - globPtr->pattern = (char *) ckalloc(3 * sizeof(char)); + globPtr->pattern = ckalloc(3); strcpy(globPtr->pattern, "*."); } else { - globPtr->pattern = (char *) ckalloc((unsigned int) len); + globPtr->pattern = ckalloc(len); strcpy(globPtr->pattern, str); } } else { - globPtr->pattern = (char *) ckalloc((unsigned int) len); + globPtr->pattern = ckalloc(len); strcpy(globPtr->pattern, str); } @@ -343,8 +376,8 @@ AddClause( for (i=0; i<ostypeCount; i++) { Tcl_DString osTypeDS; int len; - MacFileType *mfPtr = (MacFileType *) ckalloc(sizeof(MacFileType)); - CONST char *strType = Tcl_GetStringFromObj(ostypeList[i], &len); + MacFileType *mfPtr = ckalloc(sizeof(MacFileType)); + const char *strType = Tcl_GetStringFromObj(ostypeList[i], &len); char *string; /* @@ -399,11 +432,12 @@ static FileFilter * GetFilter( FileFilterList *flistPtr, /* The FileFilterList that contains the newly * created filter */ - CONST char *name) /* Name of the filter. It is usually displayed + const char *name) /* Name of the filter. It is usually displayed * in the "File Types" listbox in the file * dialogs. */ { FileFilter *filterPtr = flistPtr->filters; + size_t len; for (; filterPtr; filterPtr=filterPtr->next) { if (strcmp(filterPtr->name, name) == 0) { @@ -411,11 +445,12 @@ GetFilter( } } - filterPtr = (FileFilter *) ckalloc(sizeof(FileFilter)); + filterPtr = ckalloc(sizeof(FileFilter)); filterPtr->clauses = NULL; filterPtr->clausesTail = NULL; - filterPtr->name = (char *) ckalloc((strlen(name)+1) * sizeof(char)); - strcpy(filterPtr->name, name); + len = strlen(name) + 1; + filterPtr->name = ckalloc(len); + memcpy(filterPtr->name, name, len); if (flistPtr->filters == NULL) { flistPtr->filters = flistPtr->filtersTail = filterPtr; @@ -430,103 +465,6 @@ GetFilter( } /* - *---------------------------------------------------------------------- - * - * FreeClauses -- - * - * Frees the malloc'ed file type clause - * - * Results: - * None. - * - * Side effects: - * The list of clauses in filterPtr->clauses are freed. - * - *---------------------------------------------------------------------- - */ - -static void -FreeClauses( - FileFilter *filterPtr) /* FileFilter whose clauses are to be freed */ -{ - FileFilterClause *clausePtr = filterPtr->clauses; - - while (clausePtr != NULL) { - FileFilterClause *toFree = clausePtr; - clausePtr = clausePtr->next; - - FreeGlobPatterns(toFree); - FreeMacFileTypes(toFree); - ckfree((char *) toFree); - } - filterPtr->clauses = NULL; - filterPtr->clausesTail = NULL; -} - -/* - *---------------------------------------------------------------------- - * - * FreeGlobPatterns -- - * - * Frees the malloc'ed glob patterns in a clause - * - * Results: - * None. - * - * Side effects: - * The list of glob patterns in clausePtr->patterns are freed. - * - *---------------------------------------------------------------------- - */ - -static void -FreeGlobPatterns( - FileFilterClause *clausePtr)/* The clause whose patterns are to be freed*/ -{ - GlobPattern *globPtr = clausePtr->patterns; - - while (globPtr != NULL) { - GlobPattern *toFree = globPtr; - globPtr = globPtr->next; - - ckfree((char *) toFree->pattern); - ckfree((char *) toFree); - } - clausePtr->patterns = NULL; -} - -/* - *---------------------------------------------------------------------- - * - * FreeMacFileTypes -- - * - * Frees the malloc'ed Mac file types in a clause - * - * Results: - * None. - * - * Side effects: - * The list of Mac file types in clausePtr->macTypes are freed. - * - *---------------------------------------------------------------------- - */ - -static void -FreeMacFileTypes( - FileFilterClause *clausePtr)/* The clause whose mac types are to be - * freed */ -{ - MacFileType *mfPtr = clausePtr->macTypes; - - while (mfPtr != NULL) { - MacFileType *toFree = mfPtr; - mfPtr = mfPtr->next; - ckfree((char *) toFree); - } - clausePtr->macTypes = NULL; -} - -/* * Local Variables: * mode: c * c-basic-offset: 4 diff --git a/generic/tkFileFilter.h b/generic/tkFileFilter.h index 24002df..131e423 100644 --- a/generic/tkFileFilter.h +++ b/generic/tkFileFilter.h @@ -15,11 +15,6 @@ #define OSType long -#ifdef BUILD_tk -# undef TCL_STORAGE_CLASS -# define TCL_STORAGE_CLASS DLLEXPORT -#endif - typedef struct GlobPattern { struct GlobPattern *next; /* Chains to the next glob pattern in a glob * pattern list */ @@ -80,6 +75,4 @@ MODULE_SCOPE int TkGetFileFilters(Tcl_Interp *interp, FileFilterList *flistPtr, Tcl_Obj *valuePtr, int isWindows); -# undef TCL_STORAGE_CLASS -# define TCL_STORAGE_CLASS DLLIMPORT -#endif +#endif /* _TK_FILE_FILTER */ diff --git a/generic/tkFocus.c b/generic/tkFocus.c index 85093ee..eae981e 100644 --- a/generic/tkFocus.c +++ b/generic/tkFocus.c @@ -68,14 +68,6 @@ typedef struct TkDisplayFocusInfo { } DisplayFocusInfo; /* - * The following magic value is stored in the "send_event" field of FocusIn - * and FocusOut events that are generated in this file. This allows us to - * separate "real" events coming from the server from those that we generated. - */ - -#define GENERATED_EVENT_MAGIC ((Bool) 0x547321ac) - -/* * Debugging support... */ @@ -116,16 +108,16 @@ Tk_FocusObjCmd( ClientData clientData, /* Main window associated with interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { - static CONST char *focusOptions[] = { + static const char *const focusOptions[] = { "-displayof", "-force", "-lastfor", NULL }; - Tk_Window tkwin = (Tk_Window) clientData; - TkWindow *winPtr = (TkWindow *) clientData; - TkWindow *newPtr, *focusWinPtr, *topLevelPtr; + Tk_Window tkwin = clientData; + TkWindow *winPtr = clientData; + TkWindow *newPtr, *topLevelPtr; ToplevelFocusInfo *tlFocusPtr; - char *windowName; + const char *windowName; int index; /* @@ -133,9 +125,10 @@ Tk_FocusObjCmd( */ if (objc == 1) { - focusWinPtr = TkGetFocusWin(winPtr); - if (focusWinPtr != NULL) { - Tcl_SetResult(interp, focusWinPtr->pathName, TCL_STATIC); + Tk_Window focusWin = (Tk_Window) TkGetFocusWin(winPtr); + + if (focusWin != NULL) { + Tcl_SetObjResult(interp, TkNewWindowObj(focusWin)); } return TCL_OK; } @@ -169,8 +162,8 @@ Tk_FocusObjCmd( * We have a subcommand to parse and act upon. */ - if (Tcl_GetIndexFromObj(interp, objv[1], focusOptions, "option", 0, - &index) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[1], focusOptions, + sizeof(char *), "option", 0, &index) != TCL_OK) { return TCL_ERROR; } if (objc != 3) { @@ -186,7 +179,7 @@ Tk_FocusObjCmd( } newPtr = TkGetFocusWin(newPtr); if (newPtr != NULL) { - Tcl_SetResult(interp, newPtr->pathName, TCL_STATIC); + Tcl_SetObjResult(interp, TkNewWindowObj((Tk_Window) newPtr)); } break; case 1: /* -force */ @@ -212,19 +205,19 @@ Tk_FocusObjCmd( return TCL_ERROR; } for (topLevelPtr = newPtr; topLevelPtr != NULL; - topLevelPtr = topLevelPtr->parentPtr) { + topLevelPtr = topLevelPtr->parentPtr) { if (!(topLevelPtr->flags & TK_TOP_HIERARCHY)) { continue; } for (tlFocusPtr = newPtr->mainPtr->tlFocusPtr; tlFocusPtr != NULL; tlFocusPtr = tlFocusPtr->nextPtr) { if (tlFocusPtr->topLevelPtr == topLevelPtr) { - Tcl_SetResult(interp, - tlFocusPtr->focusWinPtr->pathName, TCL_STATIC); + Tcl_SetObjResult(interp, TkNewWindowObj((Tk_Window) + tlFocusPtr->focusWinPtr)); return TCL_OK; } } - Tcl_SetResult(interp, topLevelPtr->pathName, TCL_STATIC); + Tcl_SetObjResult(interp, TkNewWindowObj((Tk_Window) topLevelPtr)); return TCL_OK; } break; @@ -286,7 +279,7 @@ TkFocusFilterEvent( * pass the event through to Tk bindings. */ - if (eventPtr->xfocus.send_event == GENERATED_EVENT_MAGIC) { + if (eventPtr->xfocus.send_event == GENERATED_FOCUS_EVENT_MAGIC) { eventPtr->xfocus.send_event = 0; return 1; } @@ -389,7 +382,7 @@ TkFocusFilterEvent( * tree, then ignore the event. */ - if (TkGrabState(winPtr) == TK_GRAB_EXCLUDED) { + if (TkGrabState(winPtr) == TK_GRAB_EXCLUDED) { return retValue; } @@ -422,7 +415,7 @@ TkFocusFilterEvent( } } if (tlFocusPtr == NULL) { - tlFocusPtr = (ToplevelFocusInfo *) ckalloc(sizeof(ToplevelFocusInfo)); + tlFocusPtr = ckalloc(sizeof(ToplevelFocusInfo)); tlFocusPtr->topLevelPtr = tlFocusPtr->focusWinPtr = winPtr; tlFocusPtr->nextPtr = winPtr->mainPtr->tlFocusPtr; winPtr->mainPtr->tlFocusPtr = tlFocusPtr; @@ -496,14 +489,14 @@ TkFocusFilterEvent( } else if (eventPtr->type == LeaveNotify) { /* * If the pointer just left a window for which we automatically - * claimed the focus on enter, move the focus back to the root - * window, where it was before we claimed it above. Note: + * claimed the focus on enter, move the focus back to the root window, + * where it was before we claimed it above. Note: * dispPtr->implicitWinPtr may not be the same as - * displayFocusPtr->focusWinPtr (e.g. because the "focus" command - * was used to redirect the focus after it arrived at - * dispPtr->implicitWinPtr)!! In addition, we generate events - * because the window manager won't give us a FocusOut event when - * we focus on the root. + * displayFocusPtr->focusWinPtr (e.g. because the "focus" command was + * used to redirect the focus after it arrived at + * dispPtr->implicitWinPtr)!! In addition, we generate events because + * the window manager won't give us a FocusOut event when we focus on + * the root. */ if ((dispPtr->implicitWinPtr != NULL) @@ -558,12 +551,17 @@ TkSetFocusWin( return; } + /* + * Get the current focus window with the same display and application + * as winPtr. + */ + displayFocusPtr = FindDisplayFocusInfo(winPtr->mainPtr, winPtr->dispPtr); /* - * If force is set, we should make sure we grab the focus regardless of - * the current focus window since under Windows, we may need to take - * control away from another application. + * Do nothing if the window already has focus and force is not set. If + * force is set, we need to grab the focus, since under Windows or macOS + * this may involve taking control away from another application. */ if (winPtr == displayFocusPtr->focusWinPtr && !force) { @@ -571,14 +569,15 @@ TkSetFocusWin( } /* - * Find the top-level window for winPtr, then find (or create) a record - * for the top-level. Also see whether winPtr and all its ancestors are + * Find the toplevel window for winPtr, then find (or create) a record + * for the toplevel. Also see whether winPtr and all its ancestors are * mapped. */ allMapped = 1; - for (topLevelPtr = winPtr; ; topLevelPtr = topLevelPtr->parentPtr) { + for (topLevelPtr = winPtr; ; topLevelPtr = topLevelPtr->parentPtr) { if (topLevelPtr == NULL) { + /* * The window is being deleted. No point in worrying about giving * it the focus. @@ -595,24 +594,22 @@ TkSetFocusWin( } /* - * If the new focus window isn't mapped, then we can't focus on it (X will - * generate an error, for example). Instead, create an event handler that - * will set the focus to this window once it gets mapped. At the same - * time, delete any old handler that might be around; it's no longer - * relevant. + * If any ancestor of the new focus window isn't mapped, then we can't set + * focus for it (X will generate an error, for example). Instead, create + * an event handler that will set the focus to this window once it gets + * mapped. At the same time, delete any old handler that might be around; + * it's no longer relevant. */ if (displayFocusPtr->focusOnMapPtr != NULL) { - Tk_DeleteEventHandler( - (Tk_Window) displayFocusPtr->focusOnMapPtr, + Tk_DeleteEventHandler((Tk_Window) displayFocusPtr->focusOnMapPtr, StructureNotifyMask, FocusMapProc, - (ClientData) displayFocusPtr->focusOnMapPtr); + displayFocusPtr->focusOnMapPtr); displayFocusPtr->focusOnMapPtr = NULL; } if (!allMapped) { - Tk_CreateEventHandler((Tk_Window) winPtr, - VisibilityChangeMask, FocusMapProc, - (ClientData) winPtr); + Tk_CreateEventHandler((Tk_Window) winPtr, VisibilityChangeMask, + FocusMapProc, winPtr); displayFocusPtr->focusOnMapPtr = winPtr; displayFocusPtr->forceFocus = force; return; @@ -625,35 +622,43 @@ TkSetFocusWin( } } if (tlFocusPtr == NULL) { - tlFocusPtr = (ToplevelFocusInfo *) ckalloc(sizeof(ToplevelFocusInfo)); + tlFocusPtr = ckalloc(sizeof(ToplevelFocusInfo)); tlFocusPtr->topLevelPtr = topLevelPtr; tlFocusPtr->nextPtr = winPtr->mainPtr->tlFocusPtr; winPtr->mainPtr->tlFocusPtr = tlFocusPtr; } tlFocusPtr->focusWinPtr = winPtr; - /* - * Reset the window system's focus window and generate focus events, with - * two special cases: - * - * 1. If the application is embedded and doesn't currently have the focus, - * don't set the focus directly. Instead, see if the embedding code can - * claim the focus from the enclosing container. - * 2. Otherwise, if the application doesn't currently have the focus, - * don't change the window system's focus unless it was already in this - * application or "force" was specified. - */ + if (topLevelPtr->flags & TK_EMBEDDED) { + + /* + * We are assigning focus to an embedded toplevel. The platform + * specific function TkpClaimFocus needs to handle the job of + * assigning focus to the container, since we have no way to find the + * contaiuner. + */ - if ((topLevelPtr->flags & TK_EMBEDDED) - && (displayFocusPtr->focusWinPtr == NULL)) { TkpClaimFocus(topLevelPtr, force); } else if ((displayFocusPtr->focusWinPtr != NULL) || force) { + /* - * Generate events to shift focus between Tk windows. We do this - * regardless of what TkpChangeFocus does with the real X focus so - * that Tk widgets track focus commands when there is no window - * manager. GenerateFocusEvents will set up a serial number marker so - * we discard focus events that are triggered by the ChangeFocus. + * If we are forcing removal of focus from a container hosting a + * toplevel from a different application, clear the focus in that + * application. + */ + + if (force) { + TkWindow *focusPtr = winPtr->dispPtr->focusPtr; + if (focusPtr && focusPtr->mainPtr != winPtr->mainPtr) { + DisplayFocusInfo *displayFocusPtr2 = FindDisplayFocusInfo( + focusPtr->mainPtr, focusPtr->dispPtr); + displayFocusPtr2->focusWinPtr = NULL; + } + } + + /* + * Call the platform specific function TkpChangeFocus to move the + * window manager's focus to a new toplevel. */ serial = TkpChangeFocus(TkpGetWrapperWindow(topLevelPtr), force); @@ -849,7 +854,7 @@ TkFocusDeadWindow( } else { prevPtr->nextPtr = tlFocusPtr->nextPtr; } - ckfree((char *) tlFocusPtr); + ckfree(tlFocusPtr); break; } else if (winPtr == tlFocusPtr->focusWinPtr) { /* @@ -922,7 +927,7 @@ GenerateFocusEvents( } event.xfocus.serial = LastKnownRequestProcessed(winPtr->display); - event.xfocus.send_event = GENERATED_EVENT_MAGIC; + event.xfocus.send_event = GENERATED_FOCUS_EVENT_MAGIC; event.xfocus.display = winPtr->display; event.xfocus.mode = NotifyNormal; TkInOutEvents(&event, sourcePtr, destPtr, FocusOut, FocusIn, @@ -955,7 +960,7 @@ FocusMapProc( ClientData clientData, /* Toplevel window. */ XEvent *eventPtr) /* Information about event. */ { - TkWindow *winPtr = (TkWindow *) clientData; + TkWindow *winPtr = clientData; DisplayFocusInfo *displayFocusPtr; if (eventPtr->type == VisibilityNotify) { @@ -1009,7 +1014,7 @@ FindDisplayFocusInfo( * The record doesn't exist yet. Make a new one. */ - displayFocusPtr = (DisplayFocusInfo *) ckalloc(sizeof(DisplayFocusInfo)); + displayFocusPtr = ckalloc(sizeof(DisplayFocusInfo)); displayFocusPtr->dispPtr = dispPtr; displayFocusPtr->focusWinPtr = NULL; displayFocusPtr->focusOnMapPtr = NULL; @@ -1045,13 +1050,13 @@ TkFocusFree( DisplayFocusInfo *displayFocusPtr = mainPtr->displayFocusPtr; mainPtr->displayFocusPtr = mainPtr->displayFocusPtr->nextPtr; - ckfree((char *) displayFocusPtr); + ckfree(displayFocusPtr); } while (mainPtr->tlFocusPtr != NULL) { ToplevelFocusInfo *tlFocusPtr = mainPtr->tlFocusPtr; mainPtr->tlFocusPtr = mainPtr->tlFocusPtr->nextPtr; - ckfree((char *) tlFocusPtr); + ckfree(tlFocusPtr); } } @@ -1060,8 +1065,8 @@ TkFocusFree( * * TkFocusSplit -- * - * Adjust focus window for a newly managed toplevel, thus splitting - * the toplevel into two toplevels. + * Adjust focus window for a newly managed toplevel, thus splitting the + * toplevel into two toplevels. * * Results: * None. @@ -1073,29 +1078,29 @@ TkFocusFree( */ void -TkFocusSplit(winPtr) - TkWindow *winPtr; /* Window is the new toplevel - * Any focus point at or below window - * must be moved to this new toplevel */ +TkFocusSplit( + TkWindow *winPtr) /* Window is the new toplevel. Any focus point + * at or below window must be moved to this + * new toplevel. */ { ToplevelFocusInfo *tlFocusPtr; - TkWindow *topLevelPtr; - TkWindow *subWinPtr; + TkWindow *topLevelPtr, *subWinPtr; FindDisplayFocusInfo(winPtr->mainPtr, winPtr->dispPtr); /* - * Find the top-level window for winPtr, then find (or create) - * a record for the top-level. Also see whether winPtr and all its - * ancestors are mapped. + * Find the top-level window for winPtr, then find (or create) a record + * for the top-level. Also see whether winPtr and all its ancestors are + * mapped. */ - for (topLevelPtr = winPtr; ; topLevelPtr = topLevelPtr->parentPtr) { + for (topLevelPtr = winPtr; ; topLevelPtr = topLevelPtr->parentPtr) { if (topLevelPtr == NULL) { /* - * The window is being deleted. No point in worrying about - * giving it the focus. + * The window is being deleted. No point in worrying about giving + * it the focus. */ + return; } if (topLevelPtr->flags & TK_TOP_HIERARCHY) { @@ -1103,37 +1108,57 @@ TkFocusSplit(winPtr) } } - /* Search all focus records to find child windows of winPtr */ + /* + * Search all focus records to find child windows of winPtr. + */ + for (tlFocusPtr = winPtr->mainPtr->tlFocusPtr; tlFocusPtr != NULL; - tlFocusPtr = tlFocusPtr->nextPtr) { + tlFocusPtr = tlFocusPtr->nextPtr) { if (tlFocusPtr->topLevelPtr == topLevelPtr) { break; } } if (tlFocusPtr == NULL) { - /* No focus record for this toplevel, nothing to do. */ + /* + * No focus record for this toplevel, nothing to do. + */ + return; } - /* See if current focusWin is child of the new toplevel */ - for (subWinPtr = tlFocusPtr->focusWinPtr; - subWinPtr && subWinPtr != winPtr && subWinPtr != topLevelPtr; - subWinPtr = subWinPtr->parentPtr) {} + /* + * See if current focusWin is child of the new toplevel. + */ + + for (subWinPtr = tlFocusPtr->focusWinPtr; + subWinPtr && subWinPtr != winPtr && subWinPtr != topLevelPtr; + subWinPtr = subWinPtr->parentPtr) { + /* EMPTY */ + } if (subWinPtr == winPtr) { - /* Move focus to new toplevel */ - ToplevelFocusInfo *newTlFocusPtr; + /* + * Move focus to new toplevel. + */ + + ToplevelFocusInfo *newTlFocusPtr = ckalloc(sizeof(ToplevelFocusInfo)); - newTlFocusPtr = (ToplevelFocusInfo *) ckalloc(sizeof(ToplevelFocusInfo)); newTlFocusPtr->topLevelPtr = winPtr; newTlFocusPtr->focusWinPtr = tlFocusPtr->focusWinPtr; newTlFocusPtr->nextPtr = winPtr->mainPtr->tlFocusPtr; winPtr->mainPtr->tlFocusPtr = newTlFocusPtr; - /* Move old toplevel's focus to the toplevel itself */ + + /* + * Move old toplevel's focus to the toplevel itself. + */ + tlFocusPtr->focusWinPtr = topLevelPtr; } - /* If it's not, then let focus progress naturally */ + + /* + * If it's not, then let focus progress naturally. + */ } /* @@ -1153,28 +1178,28 @@ TkFocusSplit(winPtr) */ void -TkFocusJoin(winPtr) - TkWindow *winPtr; /* Window is no longer a toplevel */ +TkFocusJoin( + TkWindow *winPtr) /* Window is no longer a toplevel. */ { - ToplevelFocusInfo *tlFocusPtr; - ToplevelFocusInfo *tmpPtr; + ToplevelFocusInfo *tlFocusPtr, *tmpPtr; /* * Remove old toplevel record */ + if (winPtr && winPtr->mainPtr && winPtr->mainPtr->tlFocusPtr - && winPtr->mainPtr->tlFocusPtr->topLevelPtr == winPtr) { + && winPtr->mainPtr->tlFocusPtr->topLevelPtr == winPtr) { tmpPtr = winPtr->mainPtr->tlFocusPtr; winPtr->mainPtr->tlFocusPtr = tmpPtr->nextPtr; - ckfree((char *)tmpPtr); - } else { + ckfree(tmpPtr); + } else if (winPtr && winPtr->mainPtr) { for (tlFocusPtr = winPtr->mainPtr->tlFocusPtr; tlFocusPtr != NULL; - tlFocusPtr = tlFocusPtr->nextPtr) { + tlFocusPtr = tlFocusPtr->nextPtr) { if (tlFocusPtr->nextPtr && - tlFocusPtr->nextPtr->topLevelPtr == winPtr) { + tlFocusPtr->nextPtr->topLevelPtr == winPtr) { tmpPtr = tlFocusPtr->nextPtr; tlFocusPtr->nextPtr = tmpPtr->nextPtr; - ckfree((char *)tmpPtr); + ckfree(tmpPtr); break; } } diff --git a/generic/tkFont.c b/generic/tkFont.c index 7ff1ae9..86fdd87 100644 --- a/generic/tkFont.c +++ b/generic/tkFont.c @@ -163,7 +163,7 @@ static const TkStateMap xlfdSetwidthMap[] = { * configuring a set of font attributes. */ -static const char *fontOpt[] = { +static const char *const fontOpt[] = { "-family", "-size", "-weight", @@ -188,27 +188,27 @@ static const char *fontOpt[] = { * the alias list are also automatically tried. */ -static char *timesAliases[] = { +static const char *const timesAliases[] = { "Times", /* Unix. */ "Times New Roman", /* Windows. */ "New York", /* Mac. */ NULL }; -static char *helveticaAliases[] = { +static const char *const helveticaAliases[] = { "Helvetica", /* Unix. */ "Arial", /* Windows. */ "Geneva", /* Mac. */ NULL }; -static char *courierAliases[] = { +static const char *const courierAliases[] = { "Courier", /* Unix and Mac. */ "Courier New", /* Windows. */ NULL }; -static char *minchoAliases[] = { +static const char *const minchoAliases[] = { "mincho", /* Unix. */ "\357\274\255\357\274\263 \346\230\216\346\234\235", /* Windows (MS mincho). */ @@ -217,7 +217,7 @@ static char *minchoAliases[] = { NULL }; -static char *gothicAliases[] = { +static const char *const gothicAliases[] = { "gothic", /* Unix. */ "\357\274\255\357\274\263 \343\202\264\343\202\267\343\203\203\343\202\257", /* Windows (MS goshikku). */ @@ -226,7 +226,7 @@ static char *gothicAliases[] = { NULL }; -static char *dingbatsAliases[] = { +static const char *const dingbatsAliases[] = { "dingbats", "zapfdingbats", "itc zapfdingbats", /* Unix. */ /* Windows. */ @@ -234,7 +234,7 @@ static char *dingbatsAliases[] = { NULL }; -static char **fontAliases[] = { +static const char *const *const fontAliases[] = { timesAliases, helveticaAliases, courierAliases, @@ -250,7 +250,7 @@ static char **fontAliases[] = { * be examined also. */ -static char *systemClass[] = { +static const char *const systemClass[] = { "fixed", /* Unix. */ /* Windows. */ "chicago", "osaka", "sistemny", @@ -258,7 +258,7 @@ static char *systemClass[] = { NULL }; -static char *serifClass[] = { +static const char *const serifClass[] = { "times", "palatino", "mincho", /* All platforms. */ "song ti", /* Unix. */ @@ -268,7 +268,7 @@ static char *serifClass[] = { NULL }; -static char *sansClass[] = { +static const char *const sansClass[] = { "helvetica", "gothic", /* All platforms. */ /* Unix. */ "ms sans serif", "traditional arabic", @@ -277,7 +277,7 @@ static char *sansClass[] = { NULL }; -static char *monoClass[] = { +static const char *const monoClass[] = { "courier", "gothic", /* All platforms. */ "fangsong ti", /* Unix. */ "simplified arabic fixed", /* Windows. */ @@ -285,11 +285,11 @@ static char *monoClass[] = { NULL }; -static char *symbolClass[] = { +static const char *const symbolClass[] = { "symbol", "dingbats", "wingdings", NULL }; -static char **fontFallbacks[] = { +static const char *const *const fontFallbacks[] = { systemClass, serifClass, sansClass, @@ -304,7 +304,7 @@ static char **fontFallbacks[] = { * found, all font families in the system are examined. */ -static char *globalFontClass[] = { +static const char *const globalFontClass[] = { "symbol", /* All platforms. */ /* Unix. */ "lucida sans unicode", /* Windows. */ @@ -325,6 +325,7 @@ static int ConfigAttributesObj(Tcl_Interp *interp, TkFontAttributes *faPtr); static void DupFontObjProc(Tcl_Obj *srcObjPtr, Tcl_Obj *dupObjPtr); static int FieldSpecified(const char *field); +static void FreeFontObj(Tcl_Obj *objPtr); static void FreeFontObjProc(Tcl_Obj *objPtr); static int GetAttributeInfoObj(Tcl_Interp *interp, const TkFontAttributes *faPtr, Tcl_Obj *objPtr); @@ -345,7 +346,7 @@ static void UpdateDependentFonts(TkFontInfo *fiPtr, * font object points to the TkFont structure for the font, or NULL. */ -Tcl_ObjType tkFontObjType = { +const Tcl_ObjType tkFontObjType = { "font", /* name */ FreeFontObjProc, /* freeIntRepProc */ DupFontObjProc, /* dupIntRepProc */ @@ -376,9 +377,8 @@ void TkFontPkgInit( TkMainInfo *mainPtr) /* The application being created. */ { - TkFontInfo *fiPtr; + TkFontInfo *fiPtr = ckalloc(sizeof(TkFontInfo)); - fiPtr = (TkFontInfo *) ckalloc(sizeof(TkFontInfo)); Tcl_InitHashTable(&fiPtr->fontCache, TCL_STRING_KEYS); Tcl_InitHashTable(&fiPtr->namedTable, TCL_STRING_KEYS); fiPtr->mainPtr = mainPtr; @@ -410,21 +410,18 @@ void TkFontPkgFree( TkMainInfo *mainPtr) /* The application being deleted. */ { - TkFontInfo *fiPtr; + TkFontInfo *fiPtr = mainPtr->fontInfoPtr; Tcl_HashEntry *hPtr, *searchPtr; Tcl_HashSearch search; - int fontsLeft; + int fontsLeft = 0; - fiPtr = mainPtr->fontInfoPtr; - - fontsLeft = 0; for (searchPtr = Tcl_FirstHashEntry(&fiPtr->fontCache, &search); searchPtr != NULL; searchPtr = Tcl_NextHashEntry(&search)) { fontsLeft++; #ifdef DEBUG_FONTS fprintf(stderr, "Font %s still in cache.\n", - Tcl_GetHashKey(&fiPtr->fontCache, searchPtr)); + (char *) Tcl_GetHashKey(&fiPtr->fontCache, searchPtr)); #endif } @@ -438,14 +435,14 @@ TkFontPkgFree( hPtr = Tcl_FirstHashEntry(&fiPtr->namedTable, &search); while (hPtr != NULL) { - ckfree((char *) Tcl_GetHashValue(hPtr)); + ckfree(Tcl_GetHashValue(hPtr)); hPtr = Tcl_NextHashEntry(&search); } Tcl_DeleteHashTable(&fiPtr->namedTable); - if (fiPtr->updatePending != 0) { - Tcl_CancelIdleCall(TheWorldHasChanged, (ClientData) fiPtr); + if (fiPtr->updatePending) { + Tcl_CancelIdleCall(TheWorldHasChanged, fiPtr); } - ckfree((char *) fiPtr); + ckfree(fiPtr); } /* @@ -473,9 +470,9 @@ Tk_FontObjCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { int index; - Tk_Window tkwin; - TkFontInfo *fiPtr; - static const char *optionStrings[] = { + Tk_Window tkwin = clientData; + TkFontInfo *fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; + static const char *const optionStrings[] = { "actual", "configure", "create", "delete", "families", "measure", "metrics", "names", NULL @@ -485,9 +482,6 @@ Tk_FontObjCmd( FONT_FAMILIES, FONT_MEASURE, FONT_METRICS, FONT_NAMES }; - tkwin = (Tk_Window) clientData; - fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; - if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "option ?arg?"); return TCL_ERROR; @@ -503,7 +497,7 @@ Tk_FontObjCmd( const char *s; Tk_Font tkfont; Tcl_Obj *optPtr, *charPtr, *resultPtr; - Tcl_UniChar uniChar = 0; + int uniChar = 0; const TkFontAttributes *faPtr; TkFontAttributes fa; @@ -528,7 +522,7 @@ Tk_FontObjCmd( s = Tcl_GetString(objv[n]); if (s[0] == '-' && s[1] != '-') { optPtr = objv[n]; - ++n; + n++; } else { optPtr = NULL; } @@ -540,7 +534,7 @@ Tk_FontObjCmd( if (n < objc) { if (!strcmp(Tcl_GetString(objv[n]), "--")) { - ++n; + n++; } } @@ -550,7 +544,7 @@ Tk_FontObjCmd( if (n < objc) { charPtr = objv[n]; - ++n; + n++; } /* @@ -568,16 +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); } /* @@ -605,47 +602,47 @@ Tk_FontObjCmd( return result; } case FONT_CONFIGURE: { - int result; - char *string; - Tcl_Obj *objPtr; - NamedFont *nfPtr; - Tcl_HashEntry *namedHashPtr; - - if (objc < 3) { - Tcl_WrongNumArgs(interp, 2, objv, "fontname ?options?"); - return TCL_ERROR; - } - string = Tcl_GetString(objv[2]); - namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable, string); + int result; + const char *string; + Tcl_Obj *objPtr; + NamedFont *nfPtr; + Tcl_HashEntry *namedHashPtr; + + if (objc < 3) { + Tcl_WrongNumArgs(interp, 2, objv, "fontname ?-option value ...?"); + return TCL_ERROR; + } + string = Tcl_GetString(objv[2]); + namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable, string); nfPtr = NULL; /* lint. */ - if (namedHashPtr != NULL) { - nfPtr = (NamedFont *) Tcl_GetHashValue(namedHashPtr); - } - if ((namedHashPtr == NULL) || (nfPtr->deletePending != 0)) { - Tcl_AppendResult(interp, "named font \"", string, - "\" doesn't exist", NULL); - return TCL_ERROR; - } - if (objc == 3) { - objPtr = NULL; - } else if (objc == 4) { - objPtr = objv[3]; - } else { - result = ConfigAttributesObj(interp, tkwin, objc - 3, objv + 3, - &nfPtr->fa); - UpdateDependentFonts(fiPtr, tkwin, namedHashPtr); - return result; - } - return GetAttributeInfoObj(interp, &nfPtr->fa, objPtr); - } + if (namedHashPtr != NULL) { + nfPtr = Tcl_GetHashValue(namedHashPtr); + } + if ((namedHashPtr == NULL) || nfPtr->deletePending) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "named font \"%s\" doesn't exist", string)); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "FONT", string, NULL); + return TCL_ERROR; + } + if (objc == 3) { + objPtr = NULL; + } else if (objc == 4) { + objPtr = objv[3]; + } else { + result = ConfigAttributesObj(interp, tkwin, objc - 3, objv + 3, + &nfPtr->fa); + UpdateDependentFonts(fiPtr, tkwin, namedHashPtr); + return result; + } + return GetAttributeInfoObj(interp, &nfPtr->fa, objPtr); + } case FONT_CREATE: { - int skip, i; - char *name; + int skip = 3, i; + const char *name; char buf[16 + TCL_INTEGER_SPACE]; TkFontAttributes fa; Tcl_HashEntry *namedHashPtr; - skip = 3; if (objc < 3) { name = NULL; } else { @@ -677,12 +674,12 @@ Tk_FontObjCmd( if (TkCreateNamedFont(interp, tkwin, name, &fa) != TCL_OK) { return TCL_ERROR; } - Tcl_AppendResult(interp, name, NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj(name, -1)); break; } case FONT_DELETE: { int i, result = TCL_OK; - char *string; + const char *string; /* * Delete the named font. If there are still widgets using this font, @@ -693,16 +690,15 @@ Tk_FontObjCmd( Tcl_WrongNumArgs(interp, 2, objv, "fontname ?fontname ...?"); return TCL_ERROR; } - for (i = 2; i < objc && result == TCL_OK; i++) { + for (i = 2; (i < objc) && (result == TCL_OK); i++) { string = Tcl_GetString(objv[i]); result = TkDeleteNamedFont(interp, tkwin, string); } return result; } case FONT_FAMILIES: { - int skip; + int skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin); - skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin); if (skip < 0) { return TCL_ERROR; } @@ -714,10 +710,9 @@ Tk_FontObjCmd( break; } case FONT_MEASURE: { - char *string; + const char *string; Tk_Font tkfont; int length = 0, skip = 0; - Tcl_Obj *resultPtr; if (objc > 4) { skip = TkGetDisplayOf(interp, objc - 3, objv + 3, &tkwin); @@ -726,7 +721,8 @@ Tk_FontObjCmd( } } if (objc - skip != 4) { - Tcl_WrongNumArgs(interp, 2, objv, "font ?-displayof window? text"); + Tcl_WrongNumArgs(interp, 2, objv, + "font ?-displayof window? text"); return TCL_ERROR; } tkfont = Tk_AllocFontFromObj(interp, tkwin, objv[2]); @@ -734,8 +730,8 @@ Tk_FontObjCmd( return TCL_ERROR; } string = Tcl_GetStringFromObj(objv[3 + skip], &length); - resultPtr = Tcl_GetObjResult(interp); - Tcl_SetIntObj(resultPtr, Tk_TextWidth(tkfont, string, length)); + Tcl_SetObjResult(interp, Tcl_NewIntObj( + Tk_TextWidth(tkfont, string, length))); Tk_FreeFont(tkfont); break; } @@ -743,7 +739,7 @@ Tk_FontObjCmd( Tk_Font tkfont; int skip, index, i; const TkFontMetrics *fmPtr; - static const char *switches[] = { + static const char *const switches[] = { "-ascent", "-descent", "-linespace", "-fixed", NULL }; @@ -764,12 +760,10 @@ Tk_FontObjCmd( objv += skip; fmPtr = GetFontMetrics(tkfont); if (objc == 3) { - char buf[64 + TCL_INTEGER_SPACE * 4]; - - sprintf(buf, "-ascent %d -descent %d -linespace %d -fixed %d", + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "-ascent %d -descent %d -linespace %d -fixed %d", fmPtr->ascent, fmPtr->descent, - fmPtr->ascent + fmPtr->descent, fmPtr->fixed); - Tcl_AppendResult(interp, buf, NULL); + fmPtr->ascent + fmPtr->descent, fmPtr->fixed)); } else { if (Tcl_GetIndexFromObj(interp, objv[3], switches, "metric", 0, &index) != TCL_OK) { @@ -783,33 +777,35 @@ Tk_FontObjCmd( case 2: i = fmPtr->ascent + fmPtr->descent; break; case 3: i = fmPtr->fixed; break; } - Tcl_SetIntObj(Tcl_GetObjResult(interp), i); + Tcl_SetObjResult(interp, Tcl_NewIntObj(i)); } Tk_FreeFont(tkfont); break; } case FONT_NAMES: { - char *string; - NamedFont *nfPtr; Tcl_HashSearch search; Tcl_HashEntry *namedHashPtr; - Tcl_Obj *strPtr, *resultPtr; + Tcl_Obj *resultPtr; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "names"); return TCL_ERROR; } - resultPtr = Tcl_GetObjResult(interp); + resultPtr = Tcl_NewObj(); namedHashPtr = Tcl_FirstHashEntry(&fiPtr->namedTable, &search); while (namedHashPtr != NULL) { - nfPtr = (NamedFont *) Tcl_GetHashValue(namedHashPtr); - if (nfPtr->deletePending == 0) { - string = Tcl_GetHashKey(&fiPtr->namedTable, namedHashPtr); - strPtr = Tcl_NewStringObj(string, -1); - Tcl_ListObjAppendElement(NULL, resultPtr, strPtr); + NamedFont *nfPtr = Tcl_GetHashValue(namedHashPtr); + + if (!nfPtr->deletePending) { + char *string = Tcl_GetHashKey(&fiPtr->namedTable, + namedHashPtr); + + Tcl_ListObjAppendElement(NULL, resultPtr, + Tcl_NewStringObj(string, -1)); } namedHashPtr = Tcl_NextHashEntry(&search); } + Tcl_SetObjResult(interp, resultPtr); break; } } @@ -844,9 +840,8 @@ UpdateDependentFonts( Tcl_HashEntry *cacheHashPtr; Tcl_HashSearch search; TkFont *fontPtr; - NamedFont *nfPtr; + NamedFont *nfPtr = Tcl_GetHashValue(namedHashPtr); - nfPtr = (NamedFont *) Tcl_GetHashValue(namedHashPtr); if (nfPtr->refCount == 0) { /* * Well nobody's using this named font, so don't have to tell any @@ -858,13 +853,13 @@ UpdateDependentFonts( cacheHashPtr = Tcl_FirstHashEntry(&fiPtr->fontCache, &search); while (cacheHashPtr != NULL) { - for (fontPtr = (TkFont *) Tcl_GetHashValue(cacheHashPtr); + for (fontPtr = Tcl_GetHashValue(cacheHashPtr); fontPtr != NULL; fontPtr = fontPtr->nextPtr) { if (fontPtr->namedHashPtr == namedHashPtr) { TkpGetFontFromAttributes(fontPtr, tkwin, &nfPtr->fa); - if (fiPtr->updatePending == 0) { + if (!fiPtr->updatePending) { fiPtr->updatePending = 1; - Tcl_DoWhenIdle(TheWorldHasChanged, (ClientData) fiPtr); + Tcl_DoWhenIdle(TheWorldHasChanged, fiPtr); } } } @@ -876,11 +871,9 @@ static void TheWorldHasChanged( ClientData clientData) /* Info about application's fonts. */ { - TkFontInfo *fiPtr; + TkFontInfo *fiPtr = clientData; - fiPtr = (TkFontInfo *) clientData; fiPtr->updatePending = 0; - RecomputeWidgets(fiPtr->mainPtr->winPtr); } @@ -888,10 +881,11 @@ static void RecomputeWidgets( TkWindow *winPtr) /* Window to which command is sent. */ { - Tk_ClassWorldChangedProc *proc; - proc = Tk_GetClassProc(winPtr->classProcsPtr, worldChangedProc); + Tk_ClassWorldChangedProc *proc = + Tk_GetClassProc(winPtr->classProcsPtr, worldChangedProc); + if (proc != NULL) { - (*proc)(winPtr->instanceData); + proc(winPtr->instanceData); } /* @@ -949,21 +943,19 @@ TkCreateNamedFont( const char *name, /* Name for the new named font. */ TkFontAttributes *faPtr) /* Attributes for the new named font. */ { - TkFontInfo *fiPtr; + TkFontInfo *fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; Tcl_HashEntry *namedHashPtr; int isNew; NamedFont *nfPtr; - fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; - namedHashPtr = Tcl_CreateHashEntry(&fiPtr->namedTable, name, &isNew); - if (!isNew) { - nfPtr = (NamedFont *) Tcl_GetHashValue(namedHashPtr); - if (nfPtr->deletePending == 0) { + nfPtr = Tcl_GetHashValue(namedHashPtr); + if (!nfPtr->deletePending) { if (interp) { - Tcl_AppendResult(interp, "named font \"", name, - "\" already exists", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "named font \"%s\" already exists", name)); + Tcl_SetErrorCode(interp, "TK", "FONT", "EXISTS", NULL); } return TCL_ERROR; } @@ -980,7 +972,7 @@ TkCreateNamedFont( return TCL_OK; } - nfPtr = (NamedFont *) ckalloc(sizeof(NamedFont)); + nfPtr = ckalloc(sizeof(NamedFont)); nfPtr->deletePending = 0; Tcl_SetHashValue(namedHashPtr, nfPtr); nfPtr->fa = *faPtr; @@ -1004,28 +996,27 @@ int TkDeleteNamedFont( Tcl_Interp *interp, /* Interp for error return (can be NULL). */ Tk_Window tkwin, /* A window associated with interp. */ - CONST char *name) /* Name for the new named font. */ + const char *name) /* Name for the new named font. */ { - TkFontInfo *fiPtr; + TkFontInfo *fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; NamedFont *nfPtr; Tcl_HashEntry *namedHashPtr; - fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; - namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable, name); if (namedHashPtr == NULL) { if (interp) { - Tcl_AppendResult(interp, "named font \"", name, - "\" doesn't exist", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "named font \"%s\" doesn't exist", name)); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "FONT", name, NULL); } return TCL_ERROR; } - nfPtr = (NamedFont *) Tcl_GetHashValue(namedHashPtr); + nfPtr = Tcl_GetHashValue(namedHashPtr); if (nfPtr->refCount != 0) { nfPtr->deletePending = 1; } else { Tcl_DeleteHashEntry(namedHashPtr); - ckfree((char *) nfPtr); + ckfree(nfPtr); } return TCL_OK; } @@ -1062,7 +1053,7 @@ Tk_GetFont( Tk_Font tkfont; Tcl_Obj *strPtr; - strPtr = Tcl_NewStringObj((char *) string, -1); + strPtr = Tcl_NewStringObj(string, -1); Tcl_IncrRefCount(strPtr); tkfont = Tk_AllocFontFromObj(interp, tkwin, strPtr); Tcl_DecrRefCount(strPtr); @@ -1098,19 +1089,18 @@ Tk_AllocFontFromObj( Tcl_Obj *objPtr) /* Object describing font, as: named font, * native format, or parseable string. */ { - TkFontInfo *fiPtr; + TkFontInfo *fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; Tcl_HashEntry *cacheHashPtr, *namedHashPtr; TkFont *fontPtr, *firstFontPtr, *oldFontPtr; int isNew, descent; NamedFont *nfPtr; - fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; - if (objPtr->typePtr != &tkFontObjType) { + if (objPtr->typePtr != &tkFontObjType + || objPtr->internalRep.twoPtrValue.ptr2 != fiPtr) { SetFontFromAny(interp, objPtr); } - oldFontPtr = (TkFont *) objPtr->internalRep.twoPtrValue.ptr1; - + oldFontPtr = objPtr->internalRep.twoPtrValue.ptr1; if (oldFontPtr != NULL) { if (oldFontPtr->resourceRefCount == 0) { /* @@ -1118,7 +1108,7 @@ Tk_AllocFontFromObj( * longer in use. Clear the reference. */ - FreeFontObjProc(objPtr); + FreeFontObj(objPtr); oldFontPtr = NULL; } else if (Tk_Screen(tkwin) == oldFontPtr->screen) { oldFontPtr->resourceRefCount++; @@ -1134,18 +1124,19 @@ Tk_AllocFontFromObj( isNew = 0; if (oldFontPtr != NULL) { cacheHashPtr = oldFontPtr->cacheHashPtr; - FreeFontObjProc(objPtr); + FreeFontObj(objPtr); } else { cacheHashPtr = Tcl_CreateHashEntry(&fiPtr->fontCache, Tcl_GetString(objPtr), &isNew); } - firstFontPtr = (TkFont *) Tcl_GetHashValue(cacheHashPtr); + firstFontPtr = Tcl_GetHashValue(cacheHashPtr); for (fontPtr = firstFontPtr; (fontPtr != NULL); fontPtr = fontPtr->nextPtr) { if (Tk_Screen(tkwin) == fontPtr->screen) { fontPtr->resourceRefCount++; fontPtr->objRefCount++; - objPtr->internalRep.twoPtrValue.ptr1 = (void *) fontPtr; + objPtr->internalRep.twoPtrValue.ptr1 = fontPtr; + objPtr->internalRep.twoPtrValue.ptr2 = fiPtr; return (Tk_Font) fontPtr; } } @@ -1161,7 +1152,7 @@ Tk_AllocFontFromObj( * Construct a font based on a named font. */ - nfPtr = (NamedFont *) Tcl_GetHashValue(namedHashPtr); + nfPtr = Tcl_GetHashValue(namedHashPtr); nfPtr->refCount++; fontPtr = TkpGetFontFromAttributes(NULL, tkwin, &nfPtr->fa); @@ -1200,8 +1191,10 @@ Tk_AllocFontFromObj( if (isNew) { Tcl_DeleteHashEntry(cacheHashPtr); } - Tcl_AppendResult(interp, "failed to allocate font due to ", - "internal system font engine problem", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "failed to allocate font due to internal system font engine" + " problem", -1)); + Tcl_SetErrorCode(interp, "TK", "FONT", "INTERNAL_PROBLEM", NULL); return NULL; } @@ -1235,7 +1228,7 @@ Tk_AllocFontFromObj( descent = fontPtr->fm.descent; fontPtr->underlinePos = descent / 2; - fontPtr->underlineHeight = TkFontGetPixels(tkwin, fontPtr->fa.size) / 10; + fontPtr->underlineHeight = (int) (TkFontGetPixels(tkwin, fontPtr->fa.size) / 10 + 0.5); if (fontPtr->underlineHeight == 0) { fontPtr->underlineHeight = 1; } @@ -1253,7 +1246,8 @@ Tk_AllocFontFromObj( } } - objPtr->internalRep.twoPtrValue.ptr1 = (void *) fontPtr; + objPtr->internalRep.twoPtrValue.ptr1 = fontPtr; + objPtr->internalRep.twoPtrValue.ptr2 = fiPtr; return (Tk_Font) fontPtr; } @@ -1278,19 +1272,20 @@ Tk_AllocFontFromObj( Tk_Font Tk_GetFontFromObj( - Tk_Window tkwin, /* The window that the font will be used in. */ + Tk_Window tkwin, /* The window that the font will be used + * in. */ Tcl_Obj *objPtr) /* The object from which to get the font. */ { TkFontInfo *fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; TkFont *fontPtr; Tcl_HashEntry *hashPtr; - if (objPtr->typePtr != &tkFontObjType) { + if (objPtr->typePtr != &tkFontObjType + || objPtr->internalRep.twoPtrValue.ptr2 != fiPtr) { SetFontFromAny(NULL, objPtr); } - fontPtr = (TkFont *) objPtr->internalRep.twoPtrValue.ptr1; - + fontPtr = objPtr->internalRep.twoPtrValue.ptr1; if (fontPtr != NULL) { if (fontPtr->resourceRefCount == 0) { /* @@ -1298,7 +1293,7 @@ Tk_GetFontFromObj( * longer in use. Clear the reference. */ - FreeFontObjProc(objPtr); + FreeFontObj(objPtr); fontPtr = NULL; } else if (Tk_Screen(tkwin) == fontPtr->screen) { return (Tk_Font) fontPtr; @@ -1312,16 +1307,17 @@ Tk_GetFontFromObj( if (fontPtr != NULL) { hashPtr = fontPtr->cacheHashPtr; - FreeFontObjProc(objPtr); + FreeFontObj(objPtr); } else { hashPtr = Tcl_FindHashEntry(&fiPtr->fontCache, Tcl_GetString(objPtr)); } if (hashPtr != NULL) { - for (fontPtr = (TkFont *) Tcl_GetHashValue(hashPtr); fontPtr != NULL; + for (fontPtr = Tcl_GetHashValue(hashPtr); fontPtr != NULL; fontPtr = fontPtr->nextPtr) { if (Tk_Screen(tkwin) == fontPtr->screen) { fontPtr->objRefCount++; - objPtr->internalRep.twoPtrValue.ptr1 = (void *) fontPtr; + objPtr->internalRep.twoPtrValue.ptr1 = fontPtr; + objPtr->internalRep.twoPtrValue.ptr2 = fiPtr; return (Tk_Font) fontPtr; } } @@ -1363,10 +1359,11 @@ SetFontFromAny( Tcl_GetString(objPtr); typePtr = objPtr->typePtr; if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) { - (*typePtr->freeIntRepProc)(objPtr); + typePtr->freeIntRepProc(objPtr); } objPtr->typePtr = &tkFontObjType; objPtr->internalRep.twoPtrValue.ptr1 = NULL; + objPtr->internalRep.twoPtrValue.ptr2 = NULL; return TCL_OK; } @@ -1394,9 +1391,8 @@ const char * Tk_NameOfFont( Tk_Font tkfont) /* Font whose name is desired. */ { - TkFont *fontPtr; + TkFont *fontPtr = (TkFont *) tkfont; - fontPtr = (TkFont *) tkfont; return fontPtr->cacheHashPtr->key.string; } @@ -1421,13 +1417,12 @@ void Tk_FreeFont( Tk_Font tkfont) /* Font to be released. */ { - TkFont *fontPtr, *prevPtr; + TkFont *fontPtr = (TkFont *) tkfont, *prevPtr; NamedFont *nfPtr; - if (tkfont == NULL) { + if (fontPtr == NULL) { return; } - fontPtr = (TkFont *) tkfont; fontPtr->resourceRefCount--; if (fontPtr->resourceRefCount > 0) { return; @@ -1438,15 +1433,15 @@ Tk_FreeFont( * the named font and free it if no-one else is using it. */ - nfPtr = (NamedFont *) Tcl_GetHashValue(fontPtr->namedHashPtr); + nfPtr = Tcl_GetHashValue(fontPtr->namedHashPtr); nfPtr->refCount--; - if ((nfPtr->refCount == 0) && (nfPtr->deletePending != 0)) { + if ((nfPtr->refCount == 0) && nfPtr->deletePending) { Tcl_DeleteHashEntry(fontPtr->namedHashPtr); - ckfree((char *) nfPtr); + ckfree(nfPtr); } } - prevPtr = (TkFont *) Tcl_GetHashValue(fontPtr->cacheHashPtr); + prevPtr = Tcl_GetHashValue(fontPtr->cacheHashPtr); if (prevPtr == fontPtr) { if (fontPtr->nextPtr == NULL) { Tcl_DeleteHashEntry(fontPtr->cacheHashPtr); @@ -1462,7 +1457,7 @@ Tk_FreeFont( TkpDeleteFont(fontPtr); if (fontPtr->objRefCount == 0) { - ckfree((char *) fontPtr); + ckfree(fontPtr); } } @@ -1496,7 +1491,7 @@ Tk_FreeFontFromObj( /* *--------------------------------------------------------------------------- * - * FreeFontObjProc -- + * FreeFontObjProc, FreeFontObj -- * * This proc is called to release an object reference to a font. Called * when the object's internal rep is released or when the cached fontPtr @@ -1516,14 +1511,23 @@ static void FreeFontObjProc( Tcl_Obj *objPtr) /* The object we are releasing. */ { - TkFont *fontPtr = (TkFont *) objPtr->internalRep.twoPtrValue.ptr1; + FreeFontObj(objPtr); + objPtr->typePtr = NULL; +} + +static void +FreeFontObj( + Tcl_Obj *objPtr) /* The object we are releasing. */ +{ + TkFont *fontPtr = objPtr->internalRep.twoPtrValue.ptr1; if (fontPtr != NULL) { fontPtr->objRefCount--; if ((fontPtr->resourceRefCount == 0) && (fontPtr->objRefCount == 0)) { - ckfree((char *) fontPtr); + ckfree(fontPtr); } objPtr->internalRep.twoPtrValue.ptr1 = NULL; + objPtr->internalRep.twoPtrValue.ptr2 = NULL; } } @@ -1550,10 +1554,12 @@ DupFontObjProc( Tcl_Obj *srcObjPtr, /* The object we are copying from. */ Tcl_Obj *dupObjPtr) /* The object we are copying to. */ { - TkFont *fontPtr = (TkFont *) srcObjPtr->internalRep.twoPtrValue.ptr1; + TkFont *fontPtr = srcObjPtr->internalRep.twoPtrValue.ptr1; dupObjPtr->typePtr = srcObjPtr->typePtr; - dupObjPtr->internalRep.twoPtrValue.ptr1 = (void *) fontPtr; + dupObjPtr->internalRep.twoPtrValue.ptr1 = fontPtr; + dupObjPtr->internalRep.twoPtrValue.ptr2 + = srcObjPtr->internalRep.twoPtrValue.ptr2; if (fontPtr != NULL) { fontPtr->objRefCount++; @@ -1584,9 +1590,8 @@ Tk_FontId( Tk_Font tkfont) /* Font that is going to be selected into * GC. */ { - TkFont *fontPtr; + TkFont *fontPtr = (TkFont *) tkfont; - fontPtr = (TkFont *) tkfont; return fontPtr->fid; } @@ -1617,9 +1622,8 @@ Tk_GetFontMetrics( Tk_FontMetrics *fmPtr) /* Pointer to structure in which font metrics * for tkfont will be stored. */ { - TkFont *fontPtr; + TkFont *fontPtr = (TkFont *) tkfont; - fontPtr = (TkFont *) tkfont; fmPtr->ascent = fontPtr->fm.ascent; fmPtr->descent = fontPtr->fm.descent; fmPtr->linespace = fontPtr->fm.ascent + fontPtr->fm.descent; @@ -1659,13 +1663,12 @@ Tk_PostscriptFontName( * which the name of the Postscript font that * corresponds to tkfont will be appended. */ { - TkFont *fontPtr; + TkFont *fontPtr = (TkFont *) tkfont; Tk_Uid family, weightString, slantString; char *src, *dest; int upper, len; len = Tcl_DStringLength(dsPtr); - fontPtr = (TkFont *) tkfont; /* * Convert the case-insensitive Tk_Font family name to the case-sensitive @@ -1693,7 +1696,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 @@ -1711,14 +1714,18 @@ Tk_PostscriptFontName( src++; upper = 1; } - src += Tcl_UtfToUniChar(src, &ch); - if (upper) { - ch = Tcl_UniCharToUpper(ch); - upper = 0; + src += TkUtfToUniChar(src, &ch); + if (ch <= 0xffff) { + if (upper) { + ch = Tcl_UniCharToUpper(ch); + upper = 0; + } else { + ch = Tcl_UniCharToLower(ch); + } } else { - ch = Tcl_UniCharToLower(ch); + upper = 0; } - dest += Tcl_UniCharToUtf(ch, dest); + dest += TkUniCharToUtf(ch, dest); } *dest = '\0'; Tcl_DStringSetLength(dsPtr, dest - Tcl_DStringValue(dsPtr)); @@ -1763,7 +1770,7 @@ Tk_PostscriptFontName( slantString = NULL; if (fontPtr->fa.slant == TK_FS_ROMAN) { - ; + /* Do nothing */ } else if ((strcmp(family, "Helvetica") == 0) || (strcmp(family, "Courier") == 0) || (strcmp(family, "AvantGarde") == 0)) { @@ -1793,7 +1800,7 @@ Tk_PostscriptFontName( } } - return fontPtr->fa.size; + return (int)(fontPtr->fa.size + 0.5); } /* @@ -1891,19 +1898,17 @@ TkUnderlineCharsInContext( int lastByte) /* Index of first byte after the last * character. */ { - TkFont *fontPtr; + TkFont *fontPtr = (TkFont *) tkfont; int startX, endX; - fontPtr = (TkFont *) tkfont; - TkpMeasureCharsInContext(tkfont, string, numBytes, 0, firstByte, -1, 0, &startX); TkpMeasureCharsInContext(tkfont, string, numBytes, 0, lastByte, -1, 0, &endX); XFillRectangle(display, drawable, gc, x + startX, - y + fontPtr->underlinePos, (unsigned int) (endX - startX), - (unsigned int) fontPtr->underlineHeight); + y + fontPtr->underlinePos, (unsigned) (endX - startX), + (unsigned) fontPtr->underlineHeight); } /* @@ -1954,7 +1959,7 @@ Tk_ComputeTextLayout( int *widthPtr, /* Filled with width of string. */ int *heightPtr) /* Filled with height of string. */ { - TkFont *fontPtr; + TkFont *fontPtr = (TkFont *) tkfont; const char *start, *end, *special; int n, y, bytesThisChunk, maxChunks, curLine, layoutHeight; int baseline, height, curX, newX, maxWidth, *lineLengths; @@ -1965,7 +1970,6 @@ Tk_ComputeTextLayout( Tcl_DStringInit(&lineBuffer); - fontPtr = (TkFont *) tkfont; if ((fontPtr == NULL) || (string == NULL)) { if (widthPtr != NULL) { *widthPtr = 0; @@ -1989,8 +1993,8 @@ Tk_ComputeTextLayout( maxChunks = 1; - layoutPtr = (TextLayout *) - ckalloc(sizeof(TextLayout) + (maxChunks-1) * sizeof(LayoutChunk)); + layoutPtr = ckalloc(sizeof(TextLayout) + + (maxChunks-1) * sizeof(LayoutChunk)); layoutPtr->tkfont = tkfont; layoutPtr->string = string; layoutPtr->numChunks = 0; @@ -2154,7 +2158,7 @@ Tk_ComputeTextLayout( * on the next line. Otherwise "Hello" and "Hello\n" are the same height. */ - if ((layoutPtr->numChunks > 0) && ((flags & TK_IGNORE_NEWLINES) == 0)) { + if ((layoutPtr->numChunks > 0) && !(flags & TK_IGNORE_NEWLINES)) { if (layoutPtr->chunks[layoutPtr->numChunks - 1].start[0] == '\n') { chunkPtr = NewChunk(&layoutPtr, &maxChunks, start, 0, curX, curX, baseline); @@ -2243,11 +2247,10 @@ void Tk_FreeTextLayout( Tk_TextLayout textLayout) /* The text layout to be released. */ { - TextLayout *layoutPtr; + TextLayout *layoutPtr = (TextLayout *) textLayout; - layoutPtr = (TextLayout *) textLayout; if (layoutPtr != NULL) { - ckfree((char *) layoutPtr); + ckfree(layoutPtr); } } @@ -2275,7 +2278,8 @@ void Tk_DrawTextLayout( Display *display, /* Display on which to draw. */ Drawable drawable, /* Window or pixmap in which to draw. */ - GC gc, /* Graphics context to use for drawing text. */ + GC gc, /* Graphics context to use for drawing + * text. */ Tk_TextLayout layout, /* Layout information, from a previous call to * Tk_ComputeTextLayout(). */ int x, int y, /* Upper-left hand corner of rectangle in @@ -2287,13 +2291,11 @@ Tk_DrawTextLayout( * draw from the given text item. A number < 0 * means to draw all characters. */ { - TextLayout *layoutPtr; + TextLayout *layoutPtr = (TextLayout *) layout; int i, numDisplayChars, drawX; - const char *firstByte; - const char *lastByte; + const char *firstByte, *lastByte; LayoutChunk *chunkPtr; - layoutPtr = (TextLayout *) layout; if (layoutPtr == NULL) { return; } @@ -2318,9 +2320,78 @@ Tk_DrawTextLayout( numDisplayChars = lastChar; } lastByte = Tcl_UtfAtIndex(chunkPtr->start, numDisplayChars); - Tk_DrawChars(display, drawable, gc, layoutPtr->tkfont, - firstByte, lastByte - firstByte, - x + chunkPtr->x + drawX, y + chunkPtr->y); + Tk_DrawChars(display, drawable, gc, layoutPtr->tkfont, firstByte, + lastByte - firstByte, x+chunkPtr->x+drawX, y+chunkPtr->y); + } + firstChar -= chunkPtr->numChars; + lastChar -= chunkPtr->numChars; + if (lastChar <= 0) { + break; + } + chunkPtr++; + } +} + +void +TkDrawAngledTextLayout( + Display *display, /* Display on which to draw. */ + Drawable drawable, /* Window or pixmap in which to draw. */ + GC gc, /* Graphics context to use for drawing + * text. */ + Tk_TextLayout layout, /* Layout information, from a previous call to + * Tk_ComputeTextLayout(). */ + int x, int y, /* Upper-left hand corner of rectangle in + * which to draw (pixels). */ + double angle, + int firstChar, /* The index of the first character to draw + * from the given text item. 0 specfies the + * beginning. */ + int lastChar) /* The index just after the last character to + * draw from the given text item. A number < 0 + * means to draw all characters. */ +{ + TextLayout *layoutPtr = (TextLayout *) layout; + int i, numDisplayChars, drawX; + const char *firstByte, *lastByte; + LayoutChunk *chunkPtr; + double sinA = sin(angle * PI/180.0), cosA = cos(angle * PI/180.0); + + if (layoutPtr == NULL) { + return; + } + + if (lastChar < 0) { + lastChar = 100000000; + } + chunkPtr = layoutPtr->chunks; + for (i = 0; i < layoutPtr->numChunks; i++) { + numDisplayChars = chunkPtr->numDisplayChars; + if ((numDisplayChars > 0) && (firstChar < numDisplayChars)) { + double dx, dy; + + if (firstChar <= 0) { + drawX = 0; + firstChar = 0; + firstByte = chunkPtr->start; + } else { + firstByte = Tcl_UtfAtIndex(chunkPtr->start, firstChar); + Tk_MeasureChars(layoutPtr->tkfont, chunkPtr->start, + firstByte - chunkPtr->start, -1, 0, &drawX); + } + if (lastChar < numDisplayChars) { + numDisplayChars = lastChar; + } + lastByte = Tcl_UtfAtIndex(chunkPtr->start, numDisplayChars); + dx = cosA * (chunkPtr->x + drawX) + sinA * (chunkPtr->y); + dy = -sinA * (chunkPtr->x + drawX) + cosA * (chunkPtr->y); + if (angle == 0.0) { + Tk_DrawChars(display, drawable, gc, layoutPtr->tkfont, + firstByte, lastByte - firstByte, + (int)(x + dx), (int)(y + dy)); + } else { + TkDrawAngledChars(display, drawable, gc, layoutPtr->tkfont, + firstByte, lastByte - firstByte, x+dx, y+dy, angle); + } } firstChar -= chunkPtr->numChars; lastChar -= chunkPtr->numChars; @@ -2366,18 +2437,79 @@ Tk_UnderlineTextLayout( int underline) /* Index of the single character to underline, * or -1 for no underline. */ { - TextLayout *layoutPtr; - TkFont *fontPtr; int xx, yy, width, height; if ((Tk_CharBbox(layout, underline, &xx, &yy, &width, &height) != 0) && (width != 0)) { - layoutPtr = (TextLayout *) layout; - fontPtr = (TkFont *) layoutPtr->tkfont; + TextLayout *layoutPtr = (TextLayout *) layout; + TkFont *fontPtr = (TkFont *) layoutPtr->tkfont; XFillRectangle(display, drawable, gc, x + xx, y + yy + fontPtr->fm.ascent + fontPtr->underlinePos, - (unsigned int) width, (unsigned int) fontPtr->underlineHeight); + (unsigned) width, (unsigned) fontPtr->underlineHeight); + } +} + +void +TkUnderlineAngledTextLayout( + Display *display, /* Display on which to draw. */ + Drawable drawable, /* Window or pixmap in which to draw. */ + GC gc, /* Graphics context to use for drawing + * text. */ + Tk_TextLayout layout, /* Layout information, from a previous call to + * Tk_ComputeTextLayout(). */ + int x, int y, /* Upper-left hand corner of rectangle in + * which to draw (pixels). */ + double angle, + int underline) /* Index of the single character to underline, + * or -1 for no underline. */ +{ + int xx, yy, width, height; + + if (angle == 0.0) { + Tk_UnderlineTextLayout(display, drawable, gc, layout, x,y, underline); + return; + } + + if ((Tk_CharBbox(layout, underline, &xx, &yy, &width, &height) != 0) + && (width != 0)) { + TextLayout *layoutPtr = (TextLayout *) layout; + TkFont *fontPtr = (TkFont *) layoutPtr->tkfont; + double sinA = sin(angle*PI/180), cosA = cos(angle*PI/180); + double dy = yy + fontPtr->fm.ascent + fontPtr->underlinePos; + XPoint points[5]; + + /* + * Note that we're careful to only round a double value once, which + * minimizes roundoff errors. + */ + + points[0].x = x + ROUND16(xx*cosA + dy*sinA); + points[0].y = y + ROUND16(dy*cosA - xx*sinA); + points[1].x = x + ROUND16(xx*cosA + dy*sinA + width*cosA); + points[1].y = y + ROUND16(dy*cosA - xx*sinA - width*sinA); + if (fontPtr->underlineHeight == 1) { + /* + * Thin underlines look better when rotated when drawn as a line + * rather than a rectangle; the rasterizer copes better. + */ + + XDrawLines(display, drawable, gc, points, 2, CoordModeOrigin); + } else { + points[2].x = x + ROUND16(xx*cosA + dy*sinA + width*cosA + + fontPtr->underlineHeight*sinA); + points[2].y = y + ROUND16(dy*cosA - xx*sinA - width*sinA + + fontPtr->underlineHeight*cosA); + points[3].x = x + ROUND16(xx*cosA + dy*sinA + + fontPtr->underlineHeight*sinA); + points[3].y = y + ROUND16(dy*cosA - xx*sinA + + fontPtr->underlineHeight*cosA); + points[4].x = points[0].x; + points[4].y = points[0].y; + XFillPolygon(display, drawable, gc, points, 5, Complex, + CoordModeOrigin); + XDrawLines(display, drawable, gc, points, 5, CoordModeOrigin); + } } } @@ -2421,7 +2553,7 @@ Tk_PointToChar( * to the upper-left corner of the text * layout. */ { - TextLayout *layoutPtr; + TextLayout *layoutPtr = (TextLayout *) layout; LayoutChunk *chunkPtr, *lastPtr; TkFont *fontPtr; int i, n, dummy, baseline, pos, numChars; @@ -2439,7 +2571,6 @@ Tk_PointToChar( * Find which line contains the point. */ - layoutPtr = (TextLayout *) layout; fontPtr = (TkFont *) layoutPtr->tkfont; lastPtr = chunkPtr = layoutPtr->chunks; numChars = 0; @@ -2486,8 +2617,7 @@ Tk_PointToChar( return numChars; } n = Tk_MeasureChars((Tk_Font) fontPtr, chunkPtr->start, - chunkPtr->numBytes, x - chunkPtr->x, - 0, &dummy); + chunkPtr->numBytes, x - chunkPtr->x, 0, &dummy); return numChars + Tcl_NumUtfChars(chunkPtr->start, n); } numChars += chunkPtr->numChars; @@ -2570,7 +2700,7 @@ Tk_CharBbox( * bounding box for the character specified by * index, if non-NULL. */ { - TextLayout *layoutPtr; + TextLayout *layoutPtr = (TextLayout *) layout; LayoutChunk *chunkPtr; int i, x = 0, w; Tk_Font tkfont; @@ -2581,7 +2711,6 @@ Tk_CharBbox( return 0; } - layoutPtr = (TextLayout *) layout; chunkPtr = layoutPtr->chunks; tkfont = layoutPtr->tkfont; fontPtr = (TkFont *) tkfont; @@ -2682,11 +2811,10 @@ Tk_DistanceToTextLayout( * (in pixels). */ { int i, x1, x2, y1, y2, xDiff, yDiff, dist, minDist, ascent, descent; + TextLayout *layoutPtr = (TextLayout *) layout; LayoutChunk *chunkPtr; - TextLayout *layoutPtr; TkFont *fontPtr; - layoutPtr = (TextLayout *) layout; fontPtr = (TkFont *) layoutPtr->tkfont; ascent = fontPtr->fm.ascent; descent = fontPtr->fm.descent; @@ -2770,7 +2898,7 @@ Tk_IntersectTextLayout( * rectangular area, in pixels. */ { int result, i, x1, y1, x2, y2; - TextLayout *layoutPtr; + TextLayout *layoutPtr = (TextLayout *) layout; LayoutChunk *chunkPtr; TkFont *fontPtr; int left, top, right, bottom; @@ -2782,7 +2910,6 @@ Tk_IntersectTextLayout( * and see if they were all inside or all outside. */ - layoutPtr = (TextLayout *) layout; chunkPtr = layoutPtr->chunks; fontPtr = (TkFont *) layoutPtr->tkfont; @@ -2793,10 +2920,11 @@ Tk_IntersectTextLayout( result = 0; for (i = 0; i < layoutPtr->numChunks; i++) { - if (chunkPtr->start[0] == '\n') { + if ((chunkPtr->start[0] == '\n') || (chunkPtr->numBytes == 0)) { /* - * Newline characters are not counted when computing area - * intersection (but tab characters would still be considered). + * Newline characters and empty chunks are not counted when + * computing area intersection (but tab characters would still be + * considered). */ chunkPtr++; @@ -2830,6 +2958,254 @@ Tk_IntersectTextLayout( /* *--------------------------------------------------------------------------- * + * TkIntersectAngledTextLayout -- + * + * Determines whether a text layout that has been turned by an angle + * about its top-left coordinae lies entirely inside, entirely outside, + * or overlaps a given rectangle. Non-displaying space characters that + * occur at the end of individual lines in the text layout are ignored + * for intersection calculations. + * + * Results: + * The return value is -1 if the text layout is entirely outside of the + * rectangle, 0 if it overlaps, and 1 if it is entirely inside of the + * rectangle. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + +static inline int +PointInQuadrilateral( + double qx[], + double qy[], + double x, + double y) +{ + int i; + + for (i=0 ; i<4 ; i++) { + double sideDX = qx[(i+1)%4] - qx[i]; + double sideDY = qy[(i+1)%4] - qy[i]; + double dx = x - qx[i]; + double dy = y - qy[i]; + + if (sideDX*dy < sideDY*dx) { + return 0; + } + } + return 1; +} + +static inline int +SidesIntersect( + double ax1, double ay1, double ax2, double ay2, + double bx1, double by1, double bx2, double by2) +{ +#if 0 +/* http://www.freelunchdesign.com/cgi-bin/codwiki.pl?DiscussionTopics/CollideMeUpBaby */ + + double a1, b1, c1, a2, b2, c2, r1, r2, r3, r4, denom; + + a1 = ay2 - ay1; + b1 = ax1 - ax2; + c1 = (ax2 * ay1) - (ax1 * ay2); + r3 = (a1 * bx1) + (b1 * by1) + c1; + r4 = (a1 * bx2) + (b1 * by2) + c1; + if ((r3 != 0.0) && (r4 != 0.0) && (r3*r4 > 0.0)) { + return 0; + } + + a2 = by2 - by1; + b2 = bx1 - bx2; + c2 = (bx2 * by1) - (bx1 * by2); + r1 = (a2 * ax1) + (b2 * ay1) + c2; + r2 = (a2 * ax2) + (b2 * ay2) + c2; + if ((r1 != 0.0) && (r2 != 0.0) && (r1*r2 > 0.0)) { + return 0; + } + + denom = (a1 * b2) - (a2 * b1); + return (denom != 0.0); +#else + /* + * A more efficient version. Two line segments intersect if, when seen + * from the perspective of one line, the two endpoints of the other + * segment lie on opposite sides of the line, and vice versa. "Lie on + * opposite sides" is computed by taking the cross products and seeing if + * they are of opposite signs. + */ + + double dx, dy, dx1, dy1; + + dx = ax2 - ax1; + dy = ay2 - ay1; + dx1 = bx1 - ax1; + dy1 = by1 - ay1; + if ((dx*dy1-dy*dx1 > 0.0) == (dx*(by2-ay1)-dy*(bx2-ax1) > 0.0)) { + return 0; + } + dx = bx2 - bx1; + dy = by2 - by1; + if ((dy*dx1-dx*dy1 > 0.0) == (dx*(ay2-by1)-dy*(ax2-bx1) > 0.0)) { + return 0; + } + return 1; +#endif +} + +int +TkIntersectAngledTextLayout( + Tk_TextLayout layout, /* Layout information, from a previous call to + * Tk_ComputeTextLayout(). */ + int x, int y, /* Upper-left hand corner, in pixels, of + * rectangular area to compare with text + * layout. Coordinates are with respect to the + * upper-left hand corner of the text layout + * itself. */ + int width, int height, /* The width and height of the above + * rectangular area, in pixels. */ + double angle) +{ + int i, x1, y1, x2, y2; + TextLayout *layoutPtr; + LayoutChunk *chunkPtr; + TkFont *fontPtr; + double c = cos(angle * PI/180.0), s = sin(angle * PI/180.0); + double rx[4], ry[4]; + + if (angle == 0.0) { + return Tk_IntersectTextLayout(layout, x, y, width, height); + } + + /* + * Compute the coordinates of the rectangle, rotated into text layout + * space. + */ + + rx[0] = x*c - y*s; + ry[0] = y*c + x*s; + rx[1] = (x+width)*c - y*s; + ry[1] = y*c + (x+width)*s; + rx[2] = (x+width)*c - (y+height)*s; + ry[2] = (y+height)*c + (x+width)*s; + rx[3] = x*c - (y+height)*s; + ry[3] = (y+height)*c + x*s; + + /* + * Want to know if all chunks are inside the rectangle, or if there is any + * overlap. First, we check to see if all chunks are inside; if and only + * if they are, we're in the "inside" case. + */ + + layoutPtr = (TextLayout *) layout; + chunkPtr = layoutPtr->chunks; + fontPtr = (TkFont *) layoutPtr->tkfont; + + for (i=0 ; i<layoutPtr->numChunks ; i++,chunkPtr++) { + if (chunkPtr->start[0] == '\n') { + /* + * Newline characters are not counted when computing area + * intersection (but tab characters would still be considered). + */ + + continue; + } + + x1 = chunkPtr->x; + y1 = chunkPtr->y - fontPtr->fm.ascent; + x2 = chunkPtr->x + chunkPtr->displayWidth; + y2 = chunkPtr->y + fontPtr->fm.descent; + if ( !PointInQuadrilateral(rx, ry, x1, y1) || + !PointInQuadrilateral(rx, ry, x2, y1) || + !PointInQuadrilateral(rx, ry, x2, y2) || + !PointInQuadrilateral(rx, ry, x1, y2)) { + goto notInside; + } + } + return 1; + + /* + * Next, check to see if all the points of the rectangle are inside a + * single chunk; if they are, we're in an "overlap" case. + */ + + notInside: + chunkPtr = layoutPtr->chunks; + + for (i=0 ; i<layoutPtr->numChunks ; i++,chunkPtr++) { + double cx[4], cy[4]; + + if (chunkPtr->start[0] == '\n') { + /* + * Newline characters are not counted when computing area + * intersection (but tab characters would still be considered). + */ + + continue; + } + + cx[0] = cx[3] = chunkPtr->x; + cy[0] = cy[1] = chunkPtr->y - fontPtr->fm.ascent; + cx[1] = cx[2] = chunkPtr->x + chunkPtr->displayWidth; + cy[2] = cy[3] = chunkPtr->y + fontPtr->fm.descent; + if ( PointInQuadrilateral(cx, cy, rx[0], ry[0]) && + PointInQuadrilateral(cx, cy, rx[1], ry[1]) && + PointInQuadrilateral(cx, cy, rx[2], ry[2]) && + PointInQuadrilateral(cx, cy, rx[3], ry[3])) { + return 0; + } + } + + /* + * If we're overlapping now, we must be partially in and out of at least + * one chunk. If that is the case, there must be one line segment of the + * rectangle that is touching or crossing a line segment of a chunk. + */ + + chunkPtr = layoutPtr->chunks; + + for (i=0 ; i<layoutPtr->numChunks ; i++,chunkPtr++) { + int j; + + if (chunkPtr->start[0] == '\n') { + /* + * Newline characters are not counted when computing area + * intersection (but tab characters would still be considered). + */ + + continue; + } + + x1 = chunkPtr->x; + y1 = chunkPtr->y - fontPtr->fm.ascent; + x2 = chunkPtr->x + chunkPtr->displayWidth; + y2 = chunkPtr->y + fontPtr->fm.descent; + + for (j=0 ; j<4 ; j++) { + int k = (j+1) % 4; + + if ( SidesIntersect(rx[j],ry[j], rx[k],ry[k], x1,y1, x2,y1) || + SidesIntersect(rx[j],ry[j], rx[k],ry[k], x2,y1, x2,y2) || + SidesIntersect(rx[j],ry[j], rx[k],ry[k], x2,y2, x1,y2) || + SidesIntersect(rx[j],ry[j], rx[k],ry[k], x1,y2, x1,y1)) { + return 0; + } + } + } + + /* + * They must be wholly non-overlapping. + */ + + return -1; +} + +/* + *--------------------------------------------------------------------------- + * * Tk_TextLayoutToPostscript -- * * Outputs the contents of a text layout in Postscript format. The set of @@ -2870,112 +3246,97 @@ Tk_TextLayoutToPostscript( Tcl_Interp *interp, /* Filled with Postscript code. */ Tk_TextLayout layout) /* The layout to be rendered. */ { -#define MAXUSE 128 - char buf[MAXUSE+30], uindex[5] = "\0\0\0\0", one_char[5]; - LayoutChunk *chunkPtr; - int i, j, used, c, baseline, charsize; - Tcl_UniChar ch; - const char *p, *last_p, *glyphname; - TextLayout *layoutPtr; - int bytecount=0; - - layoutPtr = (TextLayout *) layout; - chunkPtr = layoutPtr->chunks; - baseline = chunkPtr->y; - used = 0; - buf[used++] = '['; - buf[used++] = '('; - for (i = 0; i < layoutPtr->numChunks; i++) { + TextLayout *layoutPtr = (TextLayout *) layout; + LayoutChunk *chunkPtr = layoutPtr->chunks; + int baseline = chunkPtr->y; + Tcl_Obj *psObj = Tcl_NewObj(); + int i, j, len; + const char *p, *glyphname; + char uindex[5], c, *ps; + int ch; + + Tcl_AppendToObj(psObj, "[(", -1); + for (i = 0; i < layoutPtr->numChunks; i++, chunkPtr++) { if (baseline != chunkPtr->y) { - buf[used++] = ')'; - buf[used++] = ']'; - buf[used++] = '\n'; - buf[used++] = '['; - buf[used++] = '('; + Tcl_AppendToObj(psObj, ")]\n[(", -1); baseline = chunkPtr->y; } if (chunkPtr->numDisplayChars <= 0) { if (chunkPtr->start[0] == '\t') { - buf[used++] = '\\'; - buf[used++] = 't'; + Tcl_AppendToObj(psObj, "\\t", -1); } - } else { - p = chunkPtr->start; - for (j = 0; j < chunkPtr->numDisplayChars; j++) { + continue; + } + + for (p=chunkPtr->start, j=0; j<chunkPtr->numDisplayChars; j++) { + /* + * INTL: We only handle symbols that have an encoding as a glyph + * from the standard set defined by Adobe. The rest get punted. + * Eventually this should be revised to handle more sophsticiated + * international postscript fonts. + */ + + p += TkUtfToUniChar(p, &ch); + if ((ch == '(') || (ch == ')') || (ch == '\\') || (ch < 0x20)) { /* - * INTL: For now we just treat the characters as binary data - * and display the lower byte. Eventually this should be - * revised to handle international postscript fonts. + * Tricky point: the "03" is necessary in the sprintf below, + * so that a full three digits of octal are always generated. + * Without the "03", a number following this sequence could be + * interpreted by Postscript as part of this sequence. */ - last_p = p; - p += (charsize = Tcl_UtfToUniChar(p,&ch)); - Tcl_UtfToExternal(interp, NULL, last_p, charsize, 0, NULL, - one_char, 4, NULL, &bytecount, NULL); - if (bytecount == 1) { - c = UCHAR(one_char[0]); - /* c = UCHAR( ch & 0xFF) */; - if ((c == '(') || (c == ')') || (c == '\\') || (c < 0x20) - || (c >= UCHAR(0x7f))) { - /* - * Tricky point: the "03" is necessary in the sprintf - * below, so that a full three digits of octal are - * always generated. Without the "03", a number - * following this sequence could be interpreted by - * Postscript as part of this sequence. - */ + Tcl_AppendPrintfToObj(psObj, "\\%03o", ch); + continue; + } else if (ch <= 0x7f) { + /* + * Normal ASCII character. + */ - sprintf(buf + used, "\\%03o", c); - used += 4; - } else { - buf[used++] = c; - } - } else { + c = (char) ch; + Tcl_AppendToObj(psObj, &c, 1); + continue; + } + + /* + * This character doesn't belong to the ASCII character set, so we + * 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) { + ps = Tcl_GetStringFromObj(psObj, &len); + if (ps[len-1] == '(') { /* - * This character doesn't belong to system character set. - * So, we must use full glyph name. + * In-place edit. Ewww! */ - sprintf(uindex, "%04X", ch); /* endianness? */ - glyphname = Tcl_GetVar2(interp,"::tk::psglyphs",uindex,0); - if (glyphname) { - if (used > 0 && buf [used-1] == '(') { - --used; - } else { - buf[used++] = ')'; - } - buf[used++] = '/'; - while ((*glyphname) && (used < (MAXUSE+27))) { - buf[used++] = *glyphname++ ; - } - buf[used++] = '('; - } - - } - if (used >= MAXUSE) { - buf[used] = '\0'; - Tcl_AppendResult(interp, buf, NULL); - used = 0; + ps[len-1] = '/'; + } else { + Tcl_AppendToObj(psObj, ")/", -1); } - } - } - if (used >= MAXUSE) { - /* - * If there are a whole bunch of returns or tabs in a row, then - * buf[] could get filled up. - */ + Tcl_AppendToObj(psObj, glyphname, -1); + Tcl_AppendToObj(psObj, "(", -1); + } else { + /* + * No known mapping for the character into the space of + * PostScript glyphs. Ignore it. :-( + */ +noMapping: ; - buf[used] = '\0'; - Tcl_AppendResult(interp, buf, NULL); - used = 0; +#ifdef TK_DEBUG_POSTSCRIPT_OUTPUT + fprintf(stderr, "Warning: no mapping to PostScript " + "glyphs for \\u%04x\n", ch); +#endif + } } - chunkPtr++; } - buf[used++] = ')'; - buf[used++] = ']'; - buf[used++] = '\n'; - buf[used] = '\0'; - Tcl_AppendResult(interp, buf, NULL); + Tcl_AppendToObj(psObj, ")]\n", -1); + Tcl_AppendObjToObj(Tcl_GetObjResult(interp), psObj); + Tcl_DecrRefCount(psObj); } /* @@ -3011,7 +3372,7 @@ ConfigAttributesObj( { int i, n, index; Tcl_Obj *optionPtr, *valuePtr; - char *value; + const char *value; for (i = 0; i < objc; i += 2) { optionPtr = objv[i]; @@ -3028,8 +3389,10 @@ ConfigAttributesObj( */ if (interp != NULL) { - Tcl_AppendResult(interp, "value for \"", - Tcl_GetString(optionPtr), "\" option missing", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "value for \"%s\" option missing", + Tcl_GetString(optionPtr))); + Tcl_SetErrorCode(interp, "TK", "FONT", "NO_ATTRIBUTE", NULL); } return TCL_ERROR; } @@ -3044,7 +3407,7 @@ ConfigAttributesObj( if (Tcl_GetIntFromObj(interp, valuePtr, &n) != TCL_OK) { return TCL_ERROR; } - faPtr->size = n; + faPtr->size = (double)n; break; case FONT_WEIGHT: n = TkFindStateNumObj(interp, optionPtr, weightMap, valuePtr); @@ -3110,9 +3473,7 @@ GetAttributeInfoObj( { int i, index, start, end; const char *str; - Tcl_Obj *optionPtr, *valuePtr, *resultPtr; - - resultPtr = Tcl_GetObjResult(interp); + Tcl_Obj *valuePtr, *resultPtr = NULL; start = 0; end = FONT_NUMFIELDS; @@ -3126,6 +3487,9 @@ GetAttributeInfoObj( } valuePtr = NULL; + if (objPtr == NULL) { + resultPtr = Tcl_NewObj(); + } for (i = start; i < end; i++) { switch (i) { case FONT_FAMILY: @@ -3134,7 +3498,11 @@ GetAttributeInfoObj( break; case FONT_SIZE: - valuePtr = Tcl_NewIntObj(faPtr->size); + if (faPtr->size >= 0.0) { + valuePtr = Tcl_NewIntObj((int)(faPtr->size + 0.5)); + } else { + valuePtr = Tcl_NewIntObj(-(int)(-faPtr->size + 0.5)); + } break; case FONT_WEIGHT: @@ -3159,10 +3527,11 @@ GetAttributeInfoObj( Tcl_SetObjResult(interp, valuePtr); return TCL_OK; } - optionPtr = Tcl_NewStringObj(fontOpt[i], -1); - Tcl_ListObjAppendElement(NULL, resultPtr, optionPtr); + Tcl_ListObjAppendElement(NULL, resultPtr, + Tcl_NewStringObj(fontOpt[i], -1)); Tcl_ListObjAppendElement(NULL, resultPtr, valuePtr); } + Tcl_SetObjResult(interp, resultPtr); return TCL_OK; } @@ -3204,7 +3573,7 @@ ParseFontNameObj( char *dash; int objc, result, i, n; Tcl_Obj **objv; - char *string; + const char *string; TkInitFontAttributes(faPtr); @@ -3222,7 +3591,7 @@ ParseFontNameObj( } dash = strchr(string + 1, '-'); if ((dash != NULL) - && (!isspace(UCHAR(dash[-1])))) { /* INTL: ISO space */ + && !isspace(UCHAR(dash[-1]))) { /* INTL: ISO space */ goto xlfd; } @@ -3270,8 +3639,9 @@ ParseFontNameObj( if ((Tcl_ListObjGetElements(NULL, objPtr, &objc, &objv) != TCL_OK) || (objc < 1)) { if (interp != NULL) { - Tcl_AppendResult(interp, "font \"", string, "\" doesn't exist", - NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "font \"%s\" doesn't exist", string)); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "FONT", string, NULL); } return TCL_ERROR; } @@ -3281,7 +3651,7 @@ ParseFontNameObj( if (Tcl_GetIntFromObj(interp, objv[1], &n) != TCL_OK) { return TCL_ERROR; } - faPtr->size = n; + faPtr->size = (double)n; } i = 2; @@ -3318,8 +3688,10 @@ ParseFontNameObj( */ if (interp != NULL) { - Tcl_AppendResult(interp, "unknown font style \"", - Tcl_GetString(objv[i]), "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "unknown font style \"%s\"", Tcl_GetString(objv[i]))); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "FONT_STYLE", + Tcl_GetString(objv[i]), NULL); } return TCL_ERROR; } @@ -3367,7 +3739,7 @@ NewChunk( if (layoutPtr->numChunks == maxChunks) { maxChunks *= 2; s = sizeof(TextLayout) + ((maxChunks - 1) * sizeof(LayoutChunk)); - layoutPtr = (TextLayout *) ckrealloc((char *) layoutPtr, s); + layoutPtr = ckrealloc(layoutPtr, s); *layoutPtrPtr = layoutPtr; *maxPtr = maxChunks; @@ -3439,7 +3811,7 @@ TkFontParseXLFD( } Tcl_DStringInit(&ds); - Tcl_DStringAppend(&ds, (char *) str, -1); + Tcl_DStringAppend(&ds, str, -1); src = Tcl_DStringValue(&ds); field[0] = src; @@ -3472,7 +3844,7 @@ TkFontParseXLFD( * parsed set of attributes)". */ - if ((i > XLFD_ADD_STYLE) && (FieldSpecified(field[XLFD_ADD_STYLE]))) { + if ((i > XLFD_ADD_STYLE) && FieldSpecified(field[XLFD_ADD_STYLE])) { if (atoi(field[XLFD_ADD_STYLE]) != 0) { for (j = XLFD_NUMFIELDS - 1; j >= XLFD_ADD_STYLE; j--) { field[j + 1] = field[j]; @@ -3523,7 +3895,7 @@ TkFontParseXLFD( * historical compatibility. */ - faPtr->size = 12; + faPtr->size = 12.0; if (FieldSpecified(field[XLFD_POINT_SIZE])) { if (field[XLFD_POINT_SIZE][0] == '[') { @@ -3537,10 +3909,10 @@ TkFontParseXLFD( * the purpose of, so I ignore them. */ - faPtr->size = atoi(field[XLFD_POINT_SIZE] + 1); + faPtr->size = atof(field[XLFD_POINT_SIZE] + 1); } else if (Tcl_GetInt(NULL, field[XLFD_POINT_SIZE], - &faPtr->size) == TCL_OK) { - faPtr->size /= 10; + &i) == TCL_OK) { + faPtr->size = i/10.0; } else { return TCL_ERROR; } @@ -3562,9 +3934,11 @@ TkFontParseXLFD( * ignore them. */ - faPtr->size = atoi(field[XLFD_PIXEL_SIZE] + 1); + faPtr->size = atof(field[XLFD_PIXEL_SIZE] + 1); } else if (Tcl_GetInt(NULL, field[XLFD_PIXEL_SIZE], - &faPtr->size) != TCL_OK) { + &i) == TCL_OK) { + faPtr->size = (double)i; + } else { return TCL_ERROR; } } @@ -3640,21 +4014,21 @@ FieldSpecified( *--------------------------------------------------------------------------- */ -int +double TkFontGetPixels( Tk_Window tkwin, /* For point->pixel conversion factor. */ - int size) /* Font size. */ + double size) /* Font size. */ { double d; - if (size < 0) { + if (size <= 0.0) { return -size; } d = size * 25.4 / 72.0; d *= WidthOfScreen(Tk_Screen(tkwin)); d /= WidthMMOfScreen(Tk_Screen(tkwin)); - return (int) (d + 0.5); + return d; } /* @@ -3674,21 +4048,21 @@ TkFontGetPixels( *--------------------------------------------------------------------------- */ -int +double TkFontGetPoints( Tk_Window tkwin, /* For pixel->point conversion factor. */ - int size) /* Font size. */ + double size) /* Font size. */ { double d; - if (size >= 0) { + if (size >= 0.0) { return size; } d = -size * 72.0 / 25.4; d *= WidthMMOfScreen(Tk_Screen(tkwin)); d /= WidthOfScreen(Tk_Screen(tkwin)); - return (int) (d + 0.5); + return d; } /* @@ -3701,7 +4075,6 @@ TkFontGetPoints( * platform expects when asking for the font. * * Results: - * As above. The return value is NULL if the font name has no aliases. * * Side effects: @@ -3710,7 +4083,7 @@ TkFontGetPoints( *------------------------------------------------------------------------- */ -char ** +const char *const * TkFontGetAliasList( const char *faceName) /* Font name to test for aliases. */ { @@ -3743,7 +4116,7 @@ TkFontGetAliasList( *------------------------------------------------------------------------- */ -char *** +const char *const *const * TkFontGetFallbacks(void) { return fontFallbacks; @@ -3768,7 +4141,7 @@ TkFontGetFallbacks(void) *------------------------------------------------------------------------- */ -char ** +const char *const * TkFontGetGlobalClass(void) { return globalFontClass; @@ -3791,7 +4164,7 @@ TkFontGetGlobalClass(void) *------------------------------------------------------------------------- */ -char ** +const char *const * TkFontGetSymbolClass(void) { return symbolClass; @@ -3819,7 +4192,7 @@ Tcl_Obj * TkDebugFont( Tk_Window tkwin, /* The window in which the font will be used * (not currently used). */ - char *name) /* Name of the desired color. */ + const char *name) /* Name of the desired color. */ { TkFont *fontPtr; Tcl_HashEntry *hashPtr; @@ -3829,7 +4202,7 @@ TkDebugFont( hashPtr = Tcl_FindHashEntry( &((TkWindow *) tkwin)->mainPtr->fontInfoPtr->fontCache, name); if (hashPtr != NULL) { - fontPtr = (TkFont *) Tcl_GetHashValue(hashPtr); + fontPtr = Tcl_GetHashValue(hashPtr); if (fontPtr == NULL) { Tcl_Panic("TkDebugFont found empty hash table entry"); } @@ -3871,12 +4244,11 @@ TkFontGetFirstTextLayout( Tk_Font *font, char *dst) { - TextLayout *layoutPtr; + TextLayout *layoutPtr = (TextLayout *) layout; LayoutChunk *chunkPtr; int numBytesInChunk; - layoutPtr = (TextLayout *)layout; - if ((layoutPtr==NULL) || (layoutPtr->numChunks==0) + if ((layoutPtr == NULL) || (layoutPtr->numChunks == 0) || (layoutPtr->chunks->numDisplayChars <= 0)) { dst[0] = '\0'; return 0; diff --git a/generic/tkFont.h b/generic/tkFont.h index ef6336c..de479bf 100644 --- a/generic/tkFont.h +++ b/generic/tkFont.h @@ -14,11 +14,6 @@ #ifndef _TKFONT #define _TKFONT -#ifdef BUILD_tk -#undef TCL_STORAGE_CLASS -#define TCL_STORAGE_CLASS DLLEXPORT -#endif - /* * The following structure keeps track of the attributes of a font. It can be * used to keep track of either the desired attributes or the actual @@ -28,7 +23,7 @@ struct TkFontAttributes { Tk_Uid family; /* Font family, or NULL to represent plaform- * specific default system font. */ - int size; /* Pointsize of font, 0 for default size, or + double size; /* Pointsize of font, 0.0 for default size, or * negative number meaning pixel size. */ int weight; /* Weight flag; see below for def'n. */ int slant; /* Slant flag; see below for def'n. */ @@ -187,24 +182,30 @@ typedef struct TkXLFDAttributes { #define XLFD_NUMFIELDS 13 /* Number of fields in XLFD. */ /* + * Helper macro. How to correctly round a double to a short. + */ + +#define ROUND16(x) ((short) floor((x) + 0.5)) + +/* * Low-level API exported by generic code to platform-specific code. */ #define TkInitFontAttributes(fa) memset((fa), 0, sizeof(TkFontAttributes)); #define TkInitXLFDAttributes(xa) memset((xa), 0, sizeof(TkXLFDAttributes)); -MODULE_SCOPE int TkFontParseXLFD(CONST char *string, +MODULE_SCOPE int TkFontParseXLFD(const char *string, TkFontAttributes *faPtr, TkXLFDAttributes *xaPtr); -MODULE_SCOPE char ** TkFontGetAliasList(CONST char *faceName); -MODULE_SCOPE char *** TkFontGetFallbacks(void); -MODULE_SCOPE int TkFontGetPixels(Tk_Window tkwin, int size); -MODULE_SCOPE int TkFontGetPoints(Tk_Window tkwin, int size); -MODULE_SCOPE char ** TkFontGetGlobalClass(void); -MODULE_SCOPE char ** TkFontGetSymbolClass(void); +MODULE_SCOPE const char *const * TkFontGetAliasList(const char *faceName); +MODULE_SCOPE const char *const *const * TkFontGetFallbacks(void); +MODULE_SCOPE double TkFontGetPixels(Tk_Window tkwin, double size); +MODULE_SCOPE double TkFontGetPoints(Tk_Window tkwin, double size); +MODULE_SCOPE const char *const * TkFontGetGlobalClass(void); +MODULE_SCOPE const char *const * TkFontGetSymbolClass(void); MODULE_SCOPE int TkCreateNamedFont(Tcl_Interp *interp, Tk_Window tkwin, - CONST char *name, TkFontAttributes *faPtr); + const char *name, TkFontAttributes *faPtr); MODULE_SCOPE int TkDeleteNamedFont(Tcl_Interp *interp, - Tk_Window tkwin, CONST char *name); + Tk_Window tkwin, const char *name); MODULE_SCOPE int TkFontGetFirstTextLayout(Tk_TextLayout layout, Tk_Font *font, char *dst); @@ -215,12 +216,9 @@ MODULE_SCOPE int TkFontGetFirstTextLayout(Tk_TextLayout layout, MODULE_SCOPE void TkpDeleteFont(TkFont *tkFontPtr); MODULE_SCOPE void TkpFontPkgInit(TkMainInfo *mainPtr); MODULE_SCOPE TkFont * TkpGetFontFromAttributes(TkFont *tkFontPtr, - Tk_Window tkwin, CONST TkFontAttributes *faPtr); + Tk_Window tkwin, const TkFontAttributes *faPtr); MODULE_SCOPE void TkpGetFontFamilies(Tcl_Interp *interp, Tk_Window tkwin); -MODULE_SCOPE TkFont * TkpGetNativeFont(Tk_Window tkwin, CONST char *name); - -#undef TCL_STORAGE_CLASS -#define TCL_STORAGE_CLASS DLLIMPORT +MODULE_SCOPE TkFont * TkpGetNativeFont(Tk_Window tkwin, const char *name); #endif /* _TKFONT */ diff --git a/generic/tkFrame.c b/generic/tkFrame.c index 01621dd..ce7dc8c 100644 --- a/generic/tkFrame.c +++ b/generic/tkFrame.c @@ -162,7 +162,7 @@ enum labelanchor { LABELANCHOR_W, LABELANCHOR_WN, LABELANCHOR_WS }; -static CONST char *labelAnchorStrings[] = { +static const char *const labelAnchorStrings[] = { "e", "en", "es", "n", "ne", "nw", "s", "se", "sw", "w", "wn", "ws", NULL }; @@ -175,9 +175,9 @@ static CONST char *labelAnchorStrings[] = { static const Tk_OptionSpec commonOptSpec[] = { {TK_OPTION_BORDER, "-background", "background", "Background", DEF_FRAME_BG_COLOR, -1, Tk_Offset(Frame, border), - TK_OPTION_NULL_OK, (ClientData) DEF_FRAME_BG_MONO, 0}, + TK_OPTION_NULL_OK, DEF_FRAME_BG_MONO, 0}, {TK_OPTION_SYNONYM, "-bg", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-background", 0}, + NULL, 0, -1, 0, "-background", 0}, {TK_OPTION_STRING, "-colormap", "colormap", "Colormap", DEF_FRAME_COLORMAP, -1, Tk_Offset(Frame, colormapName), TK_OPTION_NULL_OK, 0, 0}, @@ -220,7 +220,7 @@ static const Tk_OptionSpec commonOptSpec[] = { static const Tk_OptionSpec frameOptSpec[] = { {TK_OPTION_SYNONYM, "-bd", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-borderwidth", 0}, + NULL, 0, -1, 0, "-borderwidth", 0}, {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", DEF_FRAME_BORDER_WIDTH, -1, Tk_Offset(Frame, borderWidth), 0, 0, 0}, {TK_OPTION_STRING, "-class", "class", "Class", @@ -228,12 +228,12 @@ static const Tk_OptionSpec frameOptSpec[] = { {TK_OPTION_RELIEF, "-relief", "relief", "Relief", DEF_FRAME_RELIEF, -1, Tk_Offset(Frame, relief), 0, 0, 0}, {TK_OPTION_END, NULL, NULL, NULL, - NULL, 0, 0, 0, (ClientData) commonOptSpec, 0} + NULL, 0, 0, 0, commonOptSpec, 0} }; static const Tk_OptionSpec toplevelOptSpec[] = { {TK_OPTION_SYNONYM, "-bd", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-borderwidth", 0}, + NULL, 0, -1, 0, "-borderwidth", 0}, {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", DEF_FRAME_BORDER_WIDTH, -1, Tk_Offset(Frame, borderWidth), 0, 0, 0}, {TK_OPTION_STRING, "-class", "class", "Class", @@ -250,26 +250,26 @@ static const Tk_OptionSpec toplevelOptSpec[] = { DEF_TOPLEVEL_USE, -1, Tk_Offset(Frame, useThis), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_END, NULL, NULL, NULL, - NULL, 0, 0, 0, (ClientData) commonOptSpec, 0} + NULL, 0, 0, 0, commonOptSpec, 0} }; static const Tk_OptionSpec labelframeOptSpec[] = { {TK_OPTION_SYNONYM, "-bd", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-borderwidth", 0}, + NULL, 0, -1, 0, "-borderwidth", 0}, {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", DEF_LABELFRAME_BORDER_WIDTH, -1, Tk_Offset(Frame, borderWidth), 0, 0, 0}, {TK_OPTION_STRING, "-class", "class", "Class", DEF_LABELFRAME_CLASS, -1, Tk_Offset(Frame, className), 0, 0, 0}, {TK_OPTION_SYNONYM, "-fg", "foreground", NULL, - NULL, 0, -1, 0, (ClientData) "-foreground", 0}, + NULL, 0, -1, 0, "-foreground", 0}, {TK_OPTION_FONT, "-font", "font", "Font", DEF_LABELFRAME_FONT, -1, Tk_Offset(Labelframe, tkfont), 0, 0, 0}, {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground", DEF_LABELFRAME_FG, -1, Tk_Offset(Labelframe, textColorPtr), 0, 0, 0}, {TK_OPTION_STRING_TABLE, "-labelanchor", "labelAnchor", "LabelAnchor", DEF_LABELFRAME_LABELANCHOR, -1, Tk_Offset(Labelframe, labelAnchor), - 0, (ClientData) labelAnchorStrings, 0}, + 0, labelAnchorStrings, 0}, {TK_OPTION_WINDOW, "-labelwidget", "labelWidget", "LabelWidget", NULL, -1, Tk_Offset(Labelframe, labelWin), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_RELIEF, "-relief", "relief", "Relief", @@ -278,24 +278,24 @@ static const Tk_OptionSpec labelframeOptSpec[] = { DEF_LABELFRAME_TEXT, Tk_Offset(Labelframe, textPtr), -1, TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_END, NULL, NULL, NULL, - NULL, 0, 0, 0, (ClientData) commonOptSpec, 0} + NULL, 0, 0, 0, commonOptSpec, 0} }; /* * Class names for widgets, indexed by FrameType. */ -static CONST char *classNames[] = {"Frame", "Toplevel", "Labelframe"}; +static const char *const classNames[] = {"Frame", "Toplevel", "Labelframe"}; /* * The following table maps from FrameType to the option template for that * class of widgets. */ -static const Tk_OptionSpec * const optionSpecs[] = { +static const Tk_OptionSpec *const optionSpecs[] = { frameOptSpec, toplevelOptSpec, - labelframeOptSpec + labelframeOptSpec, }; /* @@ -304,11 +304,11 @@ static const Tk_OptionSpec * const optionSpecs[] = { static void ComputeFrameGeometry(Frame *framePtr); static int ConfigureFrame(Tcl_Interp *interp, Frame *framePtr, - int objc, Tcl_Obj *CONST objv[]); + int objc, Tcl_Obj *const objv[]); static int CreateFrame(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *CONST argv[], - enum FrameType type, char *appName); -static void DestroyFrame(char *memPtr); + int objc, Tcl_Obj *const argv[], + enum FrameType type, const char *appName); +static void DestroyFrame(void *memPtr); static void DestroyFramePartly(Frame *framePtr); static void DisplayFrame(ClientData clientData); static void FrameCmdDeletedProc(ClientData clientData); @@ -322,7 +322,7 @@ static void FrameStructureProc(ClientData clientData, XEvent *eventPtr); static int FrameWidgetObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[]); + Tcl_Obj *const objv[]); static void FrameWorldChanged(ClientData instanceData); static void MapFrame(ClientData clientData); @@ -331,9 +331,11 @@ static void MapFrame(ClientData clientData); * can be invoked from generic window code. */ -static Tk_ClassProcs frameClass = { +static const Tk_ClassProcs frameClass = { sizeof(Tk_ClassProcs), /* size */ - FrameWorldChanged /* worldChangedProc */ + FrameWorldChanged, /* worldChangedProc */ + NULL, /* createProc */ + NULL /* modalProc */ }; /* @@ -371,7 +373,7 @@ Tk_FrameObjCmd( ClientData clientData, /* Either NULL or pointer to option table. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { return CreateFrame(clientData, interp, objc, objv, TYPE_FRAME, NULL); } @@ -381,7 +383,7 @@ Tk_ToplevelObjCmd( ClientData clientData, /* Either NULL or pointer to option table. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { return CreateFrame(clientData, interp, objc, objv, TYPE_TOPLEVEL, NULL); } @@ -391,7 +393,7 @@ Tk_LabelframeObjCmd( ClientData clientData, /* Either NULL or pointer to option table. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { return CreateFrame(clientData, interp, objc, objv, TYPE_LABELFRAME, NULL); } @@ -420,16 +422,16 @@ TkCreateFrame( ClientData clientData, /* Either NULL or pointer to option table. */ Tcl_Interp *interp, /* Current interpreter. */ int argc, /* Number of arguments. */ - char **argv, /* Argument strings. */ + const char *const *argv, /* Argument strings. */ int toplevel, /* Non-zero means create a toplevel window, * zero means create a frame. */ - char *appName) /* Should only be non-NULL if there is no main + const char *appName) /* Should only be non-NULL if there is no main * window associated with the interpreter. * Gives the base name to use for the new * application. */ { int result, i; - Tcl_Obj **objv = (Tcl_Obj **) ckalloc((argc+1) * sizeof(Tcl_Obj **)); + Tcl_Obj **objv = ckalloc((argc+1) * sizeof(Tcl_Obj **)); for (i=0; i<argc; i++) { objv[i] = Tcl_NewStringObj(argv[i], -1); @@ -441,18 +443,41 @@ TkCreateFrame( for (i=0; i<argc; i++) { Tcl_DecrRefCount(objv[i]); } - ckfree((char *) objv); + ckfree(objv); return result; } +int +TkListCreateFrame( + ClientData clientData, /* Either NULL or pointer to option table. */ + Tcl_Interp *interp, /* Current interpreter. */ + Tcl_Obj *listObj, /* List of arguments. */ + int toplevel, /* Non-zero means create a toplevel window, + * zero means create a frame. */ + Tcl_Obj *nameObj) /* Should only be non-NULL if there is no main + * window associated with the interpreter. + * Gives the base name to use for the new + * application. */ +{ + int objc; + Tcl_Obj **objv; + + if (TCL_OK != Tcl_ListObjGetElements(interp, listObj, &objc, &objv)) { + return TCL_ERROR; + } + return CreateFrame(clientData, interp, objc, objv, + toplevel ? TYPE_TOPLEVEL : TYPE_FRAME, + nameObj ? Tcl_GetString(nameObj) : NULL); +} + static int CreateFrame( ClientData clientData, /* NULL. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[], /* Argument objects. */ + Tcl_Obj *const objv[], /* Argument objects. */ enum FrameType type, /* What widget type to create. */ - char *appName) /* Should only be non-NULL if there are no + const char *appName) /* Should only be non-NULL if there are no * Main window associated with the * interpreter. Gives the base name to use for * the new application. */ @@ -461,14 +486,15 @@ CreateFrame( Frame *framePtr; Tk_OptionTable optionTable; Tk_Window newWin; - CONST char *className, *screenName, *visualName, *colormapName, *arg, *useOption; - int i, c, length, depth; + const char *className, *screenName, *visualName, *colormapName; + const char *arg, *useOption; + int i, length, depth; unsigned int mask; Colormap colormap; Visual *visual; if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?"); + Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?"); return TCL_ERROR; } @@ -493,20 +519,19 @@ CreateFrame( if (length < 2) { continue; } - c = arg[1]; - if ((c == 'c') && (length >= 3) + if ((arg[1] == 'c') && (length >= 3) && (strncmp(arg, "-class", (unsigned) length) == 0)) { className = Tcl_GetString(objv[i+1]); - } else if ((c == 'c') + } else if ((arg[1] == 'c') && (length >= 3) && (strncmp(arg, "-colormap", (unsigned) length) == 0)) { colormapName = Tcl_GetString(objv[i+1]); - } else if ((c == 's') && (type == TYPE_TOPLEVEL) + } else if ((arg[1] == 's') && (type == TYPE_TOPLEVEL) && (strncmp(arg, "-screen", (unsigned) length) == 0)) { screenName = Tcl_GetString(objv[i+1]); - } else if ((c == 'u') && (type == TYPE_TOPLEVEL) + } else if ((arg[1] == 'u') && (type == TYPE_TOPLEVEL) && (strncmp(arg, "-use", (unsigned) length) == 0)) { useOption = Tcl_GetString(objv[i+1]); - } else if ((c == 'v') + } else if ((arg[1] == 'v') && (strncmp(arg, "-visual", (unsigned) length) == 0)) { visualName = Tcl_GetString(objv[i+1]); } @@ -545,9 +570,10 @@ CreateFrame( * are being destroyed. Let an error be thrown. */ - Tcl_AppendResult(interp, "unable to create widget \"", - Tcl_GetString(objv[1]), "\"", NULL); - newWin = NULL; + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "unable to create widget \"%s\"", Tcl_GetString(objv[1]))); + Tcl_SetErrorCode(interp, "TK", "APPLICATION_GONE", NULL); + return TCL_ERROR; } else { /* * We were called from Tk_Init; create a new application. @@ -557,13 +583,14 @@ CreateFrame( } if (newWin == NULL) { goto error; - } else { - /* - * Mark Tk frames as suitable candidates for [wm manage] - */ - TkWindow *winPtr = (TkWindow *)newWin; - winPtr->flags |= TK_WM_MANAGEABLE; } + + /* + * Mark Tk frames as suitable candidates for [wm manage]. + */ + + ((TkWindow *) newWin)->flags |= TK_WM_MANAGEABLE; + if (className == NULL) { className = Tk_GetOption(newWin, "class", "Class"); if (className == NULL) { @@ -574,10 +601,9 @@ CreateFrame( if (useOption == NULL) { useOption = Tk_GetOption(newWin, "use", "Use"); } - if ((useOption != NULL) && (*useOption != 0)) { - if (TkpUseWindow(interp, newWin, useOption) != TCL_OK) { - goto error; - } + if ((useOption != NULL) && (*useOption != 0) + && (TkpUseWindow(interp, newWin, useOption) != TCL_OK)) { + goto error; } if (visualName == NULL) { visualName = Tk_GetOption(newWin, "visual", "Visual"); @@ -621,18 +647,17 @@ CreateFrame( */ if (type == TYPE_LABELFRAME) { - framePtr = (Frame *) ckalloc(sizeof(Labelframe)); - memset((void *) framePtr, 0, (sizeof(Labelframe))); + framePtr = ckalloc(sizeof(Labelframe)); + memset(framePtr, 0, sizeof(Labelframe)); } else { - framePtr = (Frame *) ckalloc(sizeof(Frame)); - memset((void *) framePtr, 0, (sizeof(Frame))); - } - framePtr->tkwin = newWin; - framePtr->display = Tk_Display(newWin); - framePtr->interp = interp; - framePtr->widgetCmd = Tcl_CreateObjCommand(interp, - Tk_PathName(newWin), FrameWidgetObjCmd, - (ClientData) framePtr, FrameCmdDeletedProc); + framePtr = ckalloc(sizeof(Frame)); + memset(framePtr, 0, sizeof(Frame)); + } + framePtr->tkwin = newWin; + framePtr->display = Tk_Display(newWin); + framePtr->interp = interp; + framePtr->widgetCmd = Tcl_CreateObjCommand(interp, Tk_PathName(newWin), + FrameWidgetObjCmd, framePtr, FrameCmdDeletedProc); framePtr->optionTable = optionTable; framePtr->type = type; framePtr->colormap = colormap; @@ -641,6 +666,7 @@ CreateFrame( if (framePtr->type == TYPE_LABELFRAME) { Labelframe *labelframePtr = (Labelframe *) framePtr; + labelframePtr->labelAnchor = LABELANCHOR_NW; labelframePtr->textGC = NULL; } @@ -649,31 +675,32 @@ CreateFrame( * Store backreference to frame widget in window structure. */ - Tk_SetClassProcs(newWin, &frameClass, (ClientData) framePtr); + Tk_SetClassProcs(newWin, &frameClass, framePtr); mask = ExposureMask | StructureNotifyMask | FocusChangeMask; if (type == TYPE_TOPLEVEL) { mask |= ActivateMask; } - Tk_CreateEventHandler(newWin, mask, FrameEventProc, (ClientData) framePtr); + Tk_CreateEventHandler(newWin, mask, FrameEventProc, framePtr); if ((Tk_InitOptions(interp, (char *) framePtr, optionTable, newWin) != TCL_OK) || (ConfigureFrame(interp, framePtr, objc-2, objv+2) != TCL_OK)) { goto error; } - if ((framePtr->isContainer)) { - if (framePtr->useThis == NULL) { - TkpMakeContainer(framePtr->tkwin); - } else { - Tcl_AppendResult(interp, "A window cannot have both the -use ", - "and the -container option set.", NULL); + if (framePtr->isContainer) { + if (framePtr->useThis != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "windows cannot have both the -use and the -container" + " option set", -1)); + Tcl_SetErrorCode(interp, "TK", "FRAME", "CONTAINMENT", NULL); goto error; } + TkpMakeContainer(framePtr->tkwin); } if (type == TYPE_TOPLEVEL) { - Tcl_DoWhenIdle(MapFrame, (ClientData) framePtr); + Tcl_DoWhenIdle(MapFrame, framePtr); } - Tcl_SetResult(interp, Tk_PathName(newWin), TCL_STATIC); + Tcl_SetObjResult(interp, TkNewWindowObj(newWin)); return TCL_OK; error: @@ -706,28 +733,28 @@ FrameWidgetObjCmd( ClientData clientData, /* Information about frame widget. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { - static CONST char *frameOptions[] = { + static const char *const frameOptions[] = { "cget", "configure", NULL }; enum options { FRAME_CGET, FRAME_CONFIGURE }; - register Frame *framePtr = (Frame *) clientData; + register Frame *framePtr = clientData; int result = TCL_OK, index; int c, i, length; Tcl_Obj *objPtr; if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?"); + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); return TCL_ERROR; } - if (Tcl_GetIndexFromObj(interp, objv[1], frameOptions, "option", 0, - &index) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[1], frameOptions, + sizeof(char *), "option", 0, &index) != TCL_OK) { return TCL_ERROR; } - Tcl_Preserve((ClientData) framePtr); + Tcl_Preserve(framePtr); switch ((enum options) index) { case FRAME_CGET: if (objc != 3) { @@ -740,22 +767,19 @@ FrameWidgetObjCmd( if (objPtr == NULL) { result = TCL_ERROR; goto done; - } else { - Tcl_SetObjResult(interp, objPtr); } + Tcl_SetObjResult(interp, objPtr); break; case FRAME_CONFIGURE: if (objc <= 3) { objPtr = Tk_GetOptionInfo(interp, (char *) framePtr, - framePtr->optionTable, - (objc == 3) ? objv[2] : NULL, + framePtr->optionTable, (objc == 3) ? objv[2] : NULL, framePtr->tkwin); if (objPtr == NULL) { result = TCL_ERROR; goto done; - } else { - Tcl_SetObjResult(interp, objPtr); } + Tcl_SetObjResult(interp, objPtr); } else { /* * Don't allow the options -class, -colormap, -container, -screen, @@ -763,7 +787,8 @@ FrameWidgetObjCmd( */ for (i = 2; i < objc; i++) { - char *arg = Tcl_GetStringFromObj(objv[i], &length); + const char *arg = Tcl_GetStringFromObj(objv[i], &length); + if (length < 2) { continue; } @@ -783,24 +808,23 @@ FrameWidgetObjCmd( #ifdef SUPPORT_CONFIG_EMBEDDED if (c == 'u') { - CONST char *string = Tcl_GetString(objv[i+1]); + const char *string = Tcl_GetString(objv[i+1]); + if (TkpUseWindow(interp, framePtr->tkwin, string) != TCL_OK) { result = TCL_ERROR; goto done; } - } else { - Tcl_AppendResult(interp, "can't modify ", arg, - " option after widget is created", NULL); - result = TCL_ERROR; - goto done; + continue; } - #else - Tcl_AppendResult(interp, "can't modify ", arg, - " option after widget is created", NULL); - result = TCL_ERROR; - goto done; #endif + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't modify %s option after widget is created", + arg)); + Tcl_SetErrorCode(interp, "TK", "FRAME", "CREATE_ONLY", + NULL); + result = TCL_ERROR; + goto done; } } result = ConfigureFrame(interp, framePtr, objc-2, objv+2); @@ -809,7 +833,7 @@ FrameWidgetObjCmd( } done: - Tcl_Release((ClientData) framePtr); + Tcl_Release(framePtr); return result; } @@ -833,10 +857,10 @@ FrameWidgetObjCmd( static void DestroyFrame( - char *memPtr) /* Info about frame widget. */ + void *memPtr) /* Info about frame widget. */ { - register Frame *framePtr = (Frame *) memPtr; - register Labelframe *labelframePtr = (Labelframe *) memPtr; + register Frame *framePtr = memPtr; + register Labelframe *labelframePtr = memPtr; if (framePtr->type == TYPE_LABELFRAME) { Tk_FreeTextLayout(labelframePtr->textLayout); @@ -847,7 +871,7 @@ DestroyFrame( if (framePtr->colormap != None) { Tk_FreeColormap(framePtr->display, framePtr->colormap); } - ckfree((char *) framePtr); + ckfree(framePtr); } /* @@ -876,8 +900,8 @@ DestroyFramePartly( if (framePtr->type == TYPE_LABELFRAME && labelframePtr->labelWin != NULL) { Tk_DeleteEventHandler(labelframePtr->labelWin, StructureNotifyMask, - FrameStructureProc, (ClientData) framePtr); - Tk_ManageGeometry(labelframePtr->labelWin, NULL, (ClientData) NULL); + FrameStructureProc, framePtr); + Tk_ManageGeometry(labelframePtr->labelWin, NULL, NULL); if (framePtr->tkwin != Tk_Parent(labelframePtr->labelWin)) { Tk_UnmaintainGeometry(labelframePtr->labelWin, framePtr->tkwin); } @@ -915,7 +939,7 @@ ConfigureFrame( register Frame *framePtr, /* Information about widget; may or may not * already have values for some fields. */ int objc, /* Number of valid entries in objv. */ - Tcl_Obj *CONST objv[]) /* Arguments. */ + Tcl_Obj *const objv[]) /* Arguments. */ { Tk_SavedOptions savedOptions; char *oldMenuName; @@ -943,9 +967,8 @@ ConfigureFrame( ckfree(oldMenuName); } return TCL_ERROR; - } else { - Tk_FreeSavedOptions(&savedOptions); } + Tk_FreeSavedOptions(&savedOptions); /* * A few of the options require additional processing. @@ -955,7 +978,7 @@ ConfigureFrame( || ((oldMenuName != NULL) && (framePtr->menuName == NULL)) || ((oldMenuName != NULL) && (framePtr->menuName != NULL) && strcmp(oldMenuName, framePtr->menuName) != 0)) - && framePtr->type == TYPE_TOPLEVEL) { + && framePtr->type == TYPE_TOPLEVEL) { TkSetWindowMenuBar(interp, framePtr->tkwin, oldMenuName, framePtr->menuName); } @@ -989,8 +1012,8 @@ ConfigureFrame( if (oldWindow != labelframePtr->labelWin) { if (oldWindow != NULL) { Tk_DeleteEventHandler(oldWindow, StructureNotifyMask, - FrameStructureProc, (ClientData) framePtr); - Tk_ManageGeometry(oldWindow, NULL, (ClientData) NULL); + FrameStructureProc, framePtr); + Tk_ManageGeometry(oldWindow, NULL, NULL); Tk_UnmaintainGeometry(oldWindow, framePtr->tkwin); Tk_UnmapWindow(oldWindow); } @@ -1011,25 +1034,19 @@ ConfigureFrame( } sibling = ancestor; if (Tk_IsTopLevel(ancestor)) { - badWindow: - Tcl_AppendResult(interp, "can't use ", - Tk_PathName(labelframePtr->labelWin), - " as label in this frame", NULL); - labelframePtr->labelWin = NULL; - return TCL_ERROR; + goto badLabelWindow; } } if (Tk_IsTopLevel(labelframePtr->labelWin)) { - goto badWindow; + goto badLabelWindow; } if (labelframePtr->labelWin == framePtr->tkwin) { - goto badWindow; + goto badLabelWindow; } Tk_CreateEventHandler(labelframePtr->labelWin, - StructureNotifyMask, FrameStructureProc, - (ClientData) framePtr); + StructureNotifyMask, FrameStructureProc, framePtr); Tk_ManageGeometry(labelframePtr->labelWin, &frameGeomType, - (ClientData) framePtr); + framePtr); /* * If the frame is not parent to the label, make sure the @@ -1043,9 +1060,16 @@ ConfigureFrame( } } - FrameWorldChanged((ClientData) framePtr); - + FrameWorldChanged(framePtr); return TCL_OK; + + badLabelWindow: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't use %s as label in this frame", + Tk_PathName(labelframePtr->labelWin))); + Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "HIERARCHY", NULL); + labelframePtr->labelWin = NULL; + return TCL_ERROR; } /* @@ -1070,14 +1094,14 @@ static void FrameWorldChanged( ClientData instanceData) /* Information about widget. */ { - Frame *framePtr = (Frame *) instanceData; - Labelframe *labelframePtr = (Labelframe *) framePtr; + Frame *framePtr = instanceData; + Labelframe *labelframePtr = instanceData; Tk_Window tkwin = framePtr->tkwin; XGCValues gcValues; GC gc; int anyTextLabel, anyWindowLabel; int bWidthLeft, bWidthRight, bWidthTop, bWidthBottom; - char *labelText; + const char *labelText; anyTextLabel = (framePtr->type == TYPE_LABELFRAME) && (labelframePtr->textPtr != NULL) && @@ -1110,14 +1134,17 @@ FrameWorldChanged( if (anyTextLabel) { labelText = Tcl_GetString(labelframePtr->textPtr); Tk_FreeTextLayout(labelframePtr->textLayout); - labelframePtr->textLayout = Tk_ComputeTextLayout(labelframePtr->tkfont, + labelframePtr->textLayout = + Tk_ComputeTextLayout(labelframePtr->tkfont, labelText, -1, 0, TK_JUSTIFY_CENTER, 0, - &labelframePtr->labelReqWidth, &labelframePtr->labelReqHeight); + &labelframePtr->labelReqWidth, + &labelframePtr->labelReqHeight); labelframePtr->labelReqWidth += 2 * LABELSPACING; labelframePtr->labelReqHeight += 2 * LABELSPACING; } else if (anyWindowLabel) { labelframePtr->labelReqWidth = Tk_ReqWidth(labelframePtr->labelWin); - labelframePtr->labelReqHeight = Tk_ReqHeight(labelframePtr->labelWin); + labelframePtr->labelReqHeight = + Tk_ReqHeight(labelframePtr->labelWin); } /* @@ -1210,7 +1237,7 @@ FrameWorldChanged( if (Tk_IsMapped(tkwin)) { if (!(framePtr->flags & REDRAW_PENDING)) { - Tcl_DoWhenIdle(DisplayFrame, (ClientData) framePtr); + Tcl_DoWhenIdle(DisplayFrame, framePtr); } framePtr->flags |= REDRAW_PENDING; } @@ -1247,7 +1274,9 @@ ComputeFrameGeometry( * We have nothing to do here unless there is a label. */ - if (framePtr->type != TYPE_LABELFRAME) return; + if (framePtr->type != TYPE_LABELFRAME) { + return; + } if (labelframePtr->textPtr == NULL && labelframePtr->labelWin == NULL) { return; } @@ -1273,10 +1302,14 @@ ComputeFrameGeometry( if ((labelframePtr->labelAnchor >= LABELANCHOR_N) && (labelframePtr->labelAnchor <= LABELANCHOR_SW)) { maxWidth -= padding; - if (maxWidth < 1) maxWidth = 1; + if (maxWidth < 1) { + maxWidth = 1; + } } else { maxHeight -= padding; - if (maxHeight < 1) maxHeight = 1; + if (maxHeight < 1) { + maxHeight = 1; + } } if (labelframePtr->labelBox.width > maxWidth) { labelframePtr->labelBox.width = maxWidth; @@ -1379,7 +1412,7 @@ static void DisplayFrame( ClientData clientData) /* Information about widget. */ { - register Frame *framePtr = (Frame *) clientData; + register Frame *framePtr = clientData; register Tk_Window tkwin = framePtr->tkwin; int bdX1, bdY1, bdX2, bdY2, hlWidth; Pixmap pixmap; @@ -1416,7 +1449,9 @@ DisplayFrame( * If -background is set to "", no interior is drawn. */ - if (framePtr->border == NULL) return; + if (framePtr->border == NULL) { + return; + } if (framePtr->type != TYPE_LABELFRAME) { /* @@ -1547,7 +1582,8 @@ DisplayFrame( || (labelframePtr->labelBox.height != Tk_Height(labelframePtr->labelWin))) { Tk_MoveResizeWindow(labelframePtr->labelWin, - labelframePtr->labelBox.x, labelframePtr->labelBox.y, + labelframePtr->labelBox.x, + labelframePtr->labelBox.y, labelframePtr->labelBox.width, labelframePtr->labelBox.height); } @@ -1560,7 +1596,6 @@ DisplayFrame( } } - #ifndef TK_NO_DOUBLE_BUFFERING /* * Everything's been redisplayed; now copy the pixmap onto the screen @@ -1602,7 +1637,7 @@ FrameEventProc( ClientData clientData, /* Information about window. */ register XEvent *eventPtr) /* Information about event. */ { - register Frame *framePtr = (Frame *) clientData; + register Frame *framePtr = clientData; if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) { goto redraw; @@ -1636,15 +1671,15 @@ FrameEventProc( Tk_DeleteEventHandler(framePtr->tkwin, ExposureMask|StructureNotifyMask|FocusChangeMask, - FrameEventProc, (ClientData) framePtr); + FrameEventProc, framePtr); framePtr->tkwin = NULL; Tcl_DeleteCommandFromToken(framePtr->interp, framePtr->widgetCmd); } if (framePtr->flags & REDRAW_PENDING) { - Tcl_CancelIdleCall(DisplayFrame, (ClientData) framePtr); + Tcl_CancelIdleCall(DisplayFrame, framePtr); } - Tcl_CancelIdleCall(MapFrame, (ClientData) framePtr); - Tcl_EventuallyFree((ClientData) framePtr, DestroyFrame); + Tcl_CancelIdleCall(MapFrame, framePtr); + Tcl_EventuallyFree(framePtr, (Tcl_FreeProc *) DestroyFrame); } else if (eventPtr->type == FocusIn) { if (eventPtr->xfocus.detail != NotifyInferior) { framePtr->flags |= GOT_FOCUS; @@ -1667,7 +1702,7 @@ FrameEventProc( redraw: if ((framePtr->tkwin != NULL) && !(framePtr->flags & REDRAW_PENDING)) { - Tcl_DoWhenIdle(DisplayFrame, (ClientData) framePtr); + Tcl_DoWhenIdle(DisplayFrame, framePtr); framePtr->flags |= REDRAW_PENDING; } } @@ -1694,7 +1729,7 @@ static void FrameCmdDeletedProc( ClientData clientData) /* Pointer to widget record for widget. */ { - Frame *framePtr = (Frame *) clientData; + Frame *framePtr = clientData; Tk_Window tkwin = framePtr->tkwin; if (framePtr->menuName != NULL) { @@ -1745,7 +1780,7 @@ static void MapFrame( ClientData clientData) /* Pointer to frame structure. */ { - Frame *framePtr = (Frame *) clientData; + Frame *framePtr = clientData; /* * Wait for all other background events to be processed before mapping @@ -1754,7 +1789,7 @@ MapFrame( * doesn't get a false idea of its desired geometry. */ - Tcl_Preserve((ClientData) framePtr); + Tcl_Preserve(framePtr); while (1) { if (Tcl_DoOneEvent(TCL_IDLE_EVENTS) == 0) { break; @@ -1766,12 +1801,12 @@ MapFrame( */ if (framePtr->tkwin == NULL) { - Tcl_Release((ClientData) framePtr); + Tcl_Release(framePtr); return; } } Tk_MapWindow(framePtr->tkwin); - Tcl_Release((ClientData) framePtr); + Tcl_Release(framePtr); } /* @@ -1800,8 +1835,8 @@ TkInstallFrameMenu( TkWindow *winPtr = (TkWindow *) tkwin; if (winPtr->mainPtr != NULL) { - Frame *framePtr; - framePtr = (Frame*) winPtr->instanceData; + Frame *framePtr = winPtr->instanceData; + if (framePtr == NULL) { Tcl_Panic("TkInstallFrameMenu couldn't get frame pointer"); } @@ -1833,7 +1868,7 @@ FrameStructureProc( ClientData clientData, /* Pointer to record describing frame. */ XEvent *eventPtr) /* Describes what just happened. */ { - Labelframe *labelframePtr = (Labelframe *) clientData; + Labelframe *labelframePtr = clientData; if (eventPtr->type == DestroyNotify) { /* @@ -1843,7 +1878,7 @@ FrameStructureProc( if (labelframePtr->frame.type == TYPE_LABELFRAME) { labelframePtr->labelWin = NULL; - FrameWorldChanged((ClientData) labelframePtr); + FrameWorldChanged(labelframePtr); } } } @@ -1871,9 +1906,9 @@ FrameRequestProc( ClientData clientData, /* Pointer to record for frame. */ Tk_Window tkwin) /* Window that changed its desired size. */ { - Frame *framePtr = (Frame *) clientData; + Frame *framePtr = clientData; - FrameWorldChanged((ClientData) framePtr); + FrameWorldChanged(framePtr); } /* @@ -1899,8 +1934,8 @@ FrameLostSlaveProc( * stolen away. */ Tk_Window tkwin) /* Tk's handle for the slave window. */ { - Frame *framePtr = (Frame *) clientData; - Labelframe *labelframePtr = (Labelframe *) clientData; + Frame *framePtr = clientData; + Labelframe *labelframePtr = clientData; /* * This should only happen in a labelframe but it doesn't hurt to be @@ -1909,40 +1944,47 @@ FrameLostSlaveProc( if (labelframePtr->frame.type == TYPE_LABELFRAME) { Tk_DeleteEventHandler(labelframePtr->labelWin, StructureNotifyMask, - FrameStructureProc, (ClientData) labelframePtr); + FrameStructureProc, labelframePtr); if (framePtr->tkwin != Tk_Parent(labelframePtr->labelWin)) { Tk_UnmaintainGeometry(labelframePtr->labelWin, framePtr->tkwin); } Tk_UnmapWindow(labelframePtr->labelWin); labelframePtr->labelWin = NULL; } - FrameWorldChanged((ClientData) framePtr); + FrameWorldChanged(framePtr); } void -TkMapTopFrame (tkwin) - Tk_Window tkwin; +TkMapTopFrame( + Tk_Window tkwin) { - Frame *framePtr = ((TkWindow*)tkwin)->instanceData; + Frame *framePtr = ((TkWindow *) tkwin)->instanceData; Tk_OptionTable optionTable; + if (Tk_IsTopLevel(tkwin) && framePtr->type == TYPE_FRAME) { framePtr->type = TYPE_TOPLEVEL; - Tcl_DoWhenIdle(MapFrame, (ClientData)framePtr); + Tcl_DoWhenIdle(MapFrame, framePtr); if (framePtr->menuName != NULL) { TkSetWindowMenuBar(framePtr->interp, framePtr->tkwin, NULL, - framePtr->menuName); + framePtr->menuName); } } else if (!Tk_IsTopLevel(tkwin) && framePtr->type == TYPE_TOPLEVEL) { framePtr->type = TYPE_FRAME; } else { - /* Not a frame or toplevel, skip it */ + /* + * Not a frame or toplevel, skip it. + */ + return; } + /* - * The option table has already been created so - * the cached pointer will be returned. + * The option table has already been created so the cached pointer will be + * returned. */ - optionTable = Tk_CreateOptionTable(framePtr->interp, optionSpecs[framePtr->type]); + + optionTable = Tk_CreateOptionTable(framePtr->interp, + optionSpecs[framePtr->type]); framePtr->optionTable = optionTable; } @@ -1969,7 +2011,7 @@ TkMapTopFrame (tkwin) Tk_Window TkToplevelWindowForCommand( Tcl_Interp *interp, - CONST char *cmdName) + const char *cmdName) { Tcl_CmdInfo cmdInfo; Frame *framePtr; @@ -1980,7 +2022,7 @@ TkToplevelWindowForCommand( if (cmdInfo.objProc != FrameWidgetObjCmd) { return NULL; } - framePtr = (Frame *) cmdInfo.objClientData; + framePtr = cmdInfo.objClientData; if (framePtr->type != TYPE_TOPLEVEL) { return NULL; } diff --git a/generic/tkGC.c b/generic/tkGC.c index 800e4d3..c424e30 100644 --- a/generic/tkGC.c +++ b/generic/tkGC.c @@ -218,7 +218,7 @@ Tk_GetGC( valueHashPtr = Tcl_CreateHashEntry(&dispPtr->gcValueTable, (char *) &valueKey, &isNew); if (!isNew) { - gcPtr = (TkGC *) Tcl_GetHashValue(valueHashPtr); + gcPtr = Tcl_GetHashValue(valueHashPtr); gcPtr->refCount++; return gcPtr->gc; } @@ -228,7 +228,7 @@ Tk_GetGC( * and add a new structure to the database. */ - gcPtr = (TkGC *) ckalloc(sizeof(TkGC)); + gcPtr = ckalloc(sizeof(TkGC)); /* * Find or make a drawable to use to specify the screen and depth of the @@ -311,14 +311,13 @@ Tk_FreeGC( if (idHashPtr == NULL) { Tcl_Panic("Tk_FreeGC received unknown gc argument"); } - gcPtr = (TkGC *) Tcl_GetHashValue(idHashPtr); + gcPtr = Tcl_GetHashValue(idHashPtr); gcPtr->refCount--; if (gcPtr->refCount == 0) { - Tk_FreeXId(gcPtr->display, (XID) XGContextFromGC(gcPtr->gc)); XFreeGC(gcPtr->display, gcPtr->gc); Tcl_DeleteHashEntry(gcPtr->valueHashPtr); Tcl_DeleteHashEntry(idHashPtr); - ckfree((char *) gcPtr); + ckfree(gcPtr); } } @@ -349,18 +348,12 @@ TkGCCleanup( for (entryPtr = Tcl_FirstHashEntry(&dispPtr->gcIdTable, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { - gcPtr = (TkGC *) Tcl_GetHashValue(entryPtr); - - /* - * This call is not needed, as it is only used on Unix to restore the - * Id to the stack pool, and we don't want to use them anymore. - * Tk_FreeXId(gcPtr->display, (XID) XGContextFromGC(gcPtr->gc)); - */ + gcPtr = Tcl_GetHashValue(entryPtr); XFreeGC(gcPtr->display, gcPtr->gc); Tcl_DeleteHashEntry(gcPtr->valueHashPtr); Tcl_DeleteHashEntry(entryPtr); - ckfree((char *) gcPtr); + ckfree(gcPtr); } Tcl_DeleteHashTable(&dispPtr->gcValueTable); Tcl_DeleteHashTable(&dispPtr->gcIdTable); diff --git a/generic/tkGeometry.c b/generic/tkGeometry.c index 4c8e4f8..5249aaf 100644 --- a/generic/tkGeometry.c +++ b/generic/tkGeometry.c @@ -84,7 +84,7 @@ void Tk_ManageGeometry( Tk_Window tkwin, /* Window whose geometry is to be managed by * proc. */ - CONST Tk_GeomMgr *mgrPtr, /* Static structure describing the geometry + const Tk_GeomMgr *mgrPtr, /* Static structure describing the geometry * manager. This structure must never go * away. */ ClientData clientData) /* Arbitrary one-word argument to pass to @@ -96,7 +96,7 @@ Tk_ManageGeometry( && ((winPtr->geomMgrPtr != mgrPtr) || (winPtr->geomData != clientData)) && (winPtr->geomMgrPtr->lostSlaveProc != NULL)) { - (*winPtr->geomMgrPtr->lostSlaveProc)(winPtr->geomData, tkwin); + winPtr->geomMgrPtr->lostSlaveProc(winPtr->geomData, tkwin); } winPtr->geomMgrPtr = mgrPtr; @@ -152,7 +152,7 @@ Tk_GeometryRequest( winPtr->reqHeight = reqHeight; if ((winPtr->geomMgrPtr != NULL) && (winPtr->geomMgrPtr->requestProc != NULL)) { - (*winPtr->geomMgrPtr->requestProc)(winPtr->geomData, tkwin); + winPtr->geomMgrPtr->requestProc(winPtr->geomData, tkwin); } } @@ -304,6 +304,88 @@ Tk_SetMinimumRequestSize( /* *---------------------------------------------------------------------- * + * TkSetGeometryMaster -- + * + * Set a geometry master for this window. Only one master may own + * a window at any time. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * The geometry master is recorded for the window. + * + *---------------------------------------------------------------------- + */ + +int +TkSetGeometryMaster( + Tcl_Interp *interp, /* Current interpreter, for error. */ + Tk_Window tkwin, /* Window that will have geometry master + * set. */ + const char *master) /* The master identity. */ +{ + register TkWindow *winPtr = (TkWindow *) tkwin; + + if (winPtr->geomMgrName != NULL && + strcmp(winPtr->geomMgrName, master) == 0) { + return TCL_OK; + } + if (winPtr->geomMgrName != NULL) { + if (interp != NULL) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "cannot use geometry manager %s inside %s which already" + " has slaves managed by %s", + master, Tk_PathName(tkwin), winPtr->geomMgrName)); + Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "FIGHT", NULL); + } + return TCL_ERROR; + } + + winPtr->geomMgrName = ckalloc(strlen(master) + 1); + strcpy(winPtr->geomMgrName, master); + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TkFreeGeometryMaster -- + * + * Remove a geometry master for this window. Only one master may own + * a window at any time. + * + * Results: + * None. + * + * Side effects: + * The geometry master is cleared for the window. + * + *---------------------------------------------------------------------- + */ + +void +TkFreeGeometryMaster( + Tk_Window tkwin, /* Window that will have geometry master + * cleared. */ + const char *master) /* The master identity. */ +{ + register TkWindow *winPtr = (TkWindow *) tkwin; + + if (winPtr->geomMgrName != NULL && + strcmp(winPtr->geomMgrName, master) != 0) { + Tcl_Panic("Trying to free %s from geometry manager %s", + winPtr->geomMgrName, master); + } + if (winPtr->geomMgrName != NULL) { + ckfree(winPtr->geomMgrName); + winPtr->geomMgrName = NULL; + } +} + +/* + *---------------------------------------------------------------------- + * * Tk_MaintainGeometry -- * * This procedure is invoked by geometry managers to handle slaves whose @@ -343,6 +425,9 @@ Tk_MaintainGeometry( Tk_Window ancestor, parent; TkDisplay *dispPtr = ((TkWindow *) master)->dispPtr; + ((TkWindow *)slave)->maintainerPtr = (TkWindow *)master; + + ((TkWindow *)slave)->maintainerPtr = (TkWindow *)master; if (master == Tk_Parent(slave)) { /* * If the slave is a direct descendant of the master, don't bother @@ -379,9 +464,9 @@ Tk_MaintainGeometry( hPtr = Tcl_CreateHashEntry(&dispPtr->maintainHashTable, (char *) master, &isNew); if (!isNew) { - masterPtr = (MaintainMaster *) Tcl_GetHashValue(hPtr); + masterPtr = Tcl_GetHashValue(hPtr); } else { - masterPtr = (MaintainMaster *) ckalloc(sizeof(MaintainMaster)); + masterPtr = ckalloc(sizeof(MaintainMaster)); masterPtr->ancestor = master; masterPtr->checkScheduled = 0; masterPtr->slavePtr = NULL; @@ -399,13 +484,13 @@ Tk_MaintainGeometry( goto gotSlave; } } - slavePtr = (MaintainSlave *) ckalloc(sizeof(MaintainSlave)); + slavePtr = ckalloc(sizeof(MaintainSlave)); slavePtr->slave = slave; slavePtr->master = master; slavePtr->nextPtr = masterPtr->slavePtr; masterPtr->slavePtr = slavePtr; Tk_CreateEventHandler(slave, StructureNotifyMask, MaintainSlaveProc, - (ClientData) slavePtr); + slavePtr); /* * Make sure that there are event handlers registered for all the windows @@ -418,7 +503,7 @@ Tk_MaintainGeometry( ancestor = Tk_Parent(ancestor)) { if (ancestor == masterPtr->ancestor) { Tk_CreateEventHandler(ancestor, StructureNotifyMask, - MaintainMasterProc, (ClientData) masterPtr); + MaintainMasterProc, masterPtr); masterPtr->ancestor = Tk_Parent(ancestor); } } @@ -488,6 +573,9 @@ Tk_UnmaintainGeometry( Tk_Window ancestor; TkDisplay *dispPtr = ((TkWindow *) slave)->dispPtr; + ((TkWindow *)slave)->maintainerPtr = NULL; + + ((TkWindow *)slave)->maintainerPtr = NULL; if (master == Tk_Parent(slave)) { /* * If the slave is a direct descendant of the master, @@ -509,7 +597,7 @@ Tk_UnmaintainGeometry( if (hPtr == NULL) { return; } - masterPtr = (MaintainMaster *) Tcl_GetHashValue(hPtr); + masterPtr = Tcl_GetHashValue(hPtr); slavePtr = masterPtr->slavePtr; if (slavePtr->slave == slave) { masterPtr->slavePtr = slavePtr->nextPtr; @@ -526,23 +614,23 @@ Tk_UnmaintainGeometry( } } Tk_DeleteEventHandler(slavePtr->slave, StructureNotifyMask, - MaintainSlaveProc, (ClientData) slavePtr); - ckfree((char *) slavePtr); + MaintainSlaveProc, slavePtr); + ckfree(slavePtr); if (masterPtr->slavePtr == NULL) { if (masterPtr->ancestor != NULL) { for (ancestor = master; ; ancestor = Tk_Parent(ancestor)) { Tk_DeleteEventHandler(ancestor, StructureNotifyMask, - MaintainMasterProc, (ClientData) masterPtr); + MaintainMasterProc, masterPtr); if (ancestor == masterPtr->ancestor) { break; } } } if (masterPtr->checkScheduled) { - Tcl_CancelIdleCall(MaintainCheckProc, (ClientData) masterPtr); + Tcl_CancelIdleCall(MaintainCheckProc, masterPtr); } Tcl_DeleteHashEntry(hPtr); - ckfree((char *) masterPtr); + ckfree(masterPtr); } } @@ -573,7 +661,7 @@ MaintainMasterProc( * master window. */ XEvent *eventPtr) /* Describes what just happened. */ { - MaintainMaster *masterPtr = (MaintainMaster *) clientData; + MaintainMaster *masterPtr = clientData; MaintainSlave *slavePtr; int done; @@ -582,7 +670,7 @@ MaintainMasterProc( || (eventPtr->type == UnmapNotify)) { if (!masterPtr->checkScheduled) { masterPtr->checkScheduled = 1; - Tcl_DoWhenIdle(MaintainCheckProc, (ClientData) masterPtr); + Tcl_DoWhenIdle(MaintainCheckProc, masterPtr); } } else if (eventPtr->type == DestroyNotify) { /* @@ -627,7 +715,7 @@ MaintainSlaveProc( * master-slave pair. */ XEvent *eventPtr) /* Describes what just happened. */ { - MaintainSlave *slavePtr = (MaintainSlave *) clientData; + MaintainSlave *slavePtr = clientData; if (eventPtr->type == DestroyNotify) { Tk_UnmaintainGeometry(slavePtr->slave, slavePtr->master); @@ -659,7 +747,7 @@ MaintainCheckProc( ClientData clientData) /* Pointer to MaintainMaster structure for the * master window. */ { - MaintainMaster *masterPtr = (MaintainMaster *) clientData; + MaintainMaster *masterPtr = clientData; MaintainSlave *slavePtr; Tk_Window ancestor, parent; int x, y, map; diff --git a/generic/tkGet.c b/generic/tkGet.c index 9fc0d50..d58b4a5 100644 --- a/generic/tkGet.c +++ b/generic/tkGet.c @@ -35,10 +35,10 @@ static void FreeUidThreadExitProc(ClientData clientData); * used by Tk_GetAnchorFromObj and Tk_GetJustifyFromObj. */ -static CONST char *anchorStrings[] = { +static const char *const anchorStrings[] = { "n", "ne", "e", "se", "s", "sw", "w", "nw", "center", NULL }; -static CONST char *justifyStrings[] = { +static const char *const justifyStrings[] = { "left", "right", "center", NULL }; @@ -101,7 +101,7 @@ Tk_GetAnchorFromObj( int Tk_GetAnchor( Tcl_Interp *interp, /* Use this for error reporting. */ - CONST char *string, /* String describing a direction. */ + const char *string, /* String describing a direction. */ Tk_Anchor *anchorPtr) /* Where to store Tk_Anchor corresponding to * string. */ { @@ -152,8 +152,10 @@ Tk_GetAnchor( } error: - Tcl_AppendResult(interp, "bad anchor position \"", string, - "\": must be n, ne, e, se, s, sw, w, nw, or center", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad anchor position \"%s\": must be" + " n, ne, e, se, s, sw, w, nw, or center", string)); + Tcl_SetErrorCode(interp, "TK", "VALUE", "ANCHOR", NULL); return TCL_ERROR; } @@ -173,7 +175,7 @@ Tk_GetAnchor( *-------------------------------------------------------------- */ -CONST char * +const char * Tk_NameOfAnchor( Tk_Anchor anchor) /* Anchor for which identifying string is * desired. */ @@ -214,7 +216,7 @@ Tk_NameOfAnchor( int Tk_GetJoinStyle( Tcl_Interp *interp, /* Use this for error reporting. */ - CONST char *string, /* String describing a justification style. */ + const char *string, /* String describing a justification style. */ int *joinPtr) /* Where to store join style corresponding to * string. */ { @@ -237,8 +239,10 @@ Tk_GetJoinStyle( return TCL_OK; } - Tcl_AppendResult(interp, "bad join style \"", string, - "\": must be bevel, miter, or round", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad join style \"%s\": must be bevel, miter, or round", + string)); + Tcl_SetErrorCode(interp, "TK", "VALUE", "JOIN", NULL); return TCL_ERROR; } @@ -258,7 +262,7 @@ Tk_GetJoinStyle( *-------------------------------------------------------------- */ -CONST char * +const char * Tk_NameOfJoinStyle( int join) /* Join style for which identifying string is * desired. */ @@ -293,7 +297,7 @@ Tk_NameOfJoinStyle( int Tk_GetCapStyle( Tcl_Interp *interp, /* Use this for error reporting. */ - CONST char *string, /* String describing a justification style. */ + const char *string, /* String describing a justification style. */ int *capPtr) /* Where to store cap style corresponding to * string. */ { @@ -316,8 +320,10 @@ Tk_GetCapStyle( return TCL_OK; } - Tcl_AppendResult(interp, "bad cap style \"", string, - "\": must be butt, projecting, or round", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad cap style \"%s\": must be butt, projecting, or round", + string)); + Tcl_SetErrorCode(interp, "TK", "VALUE", "CAP", NULL); return TCL_ERROR; } @@ -337,7 +343,7 @@ Tk_GetCapStyle( *-------------------------------------------------------------- */ -CONST char * +const char * Tk_NameOfCapStyle( int cap) /* Cap style for which identifying string is * desired. */ @@ -409,7 +415,7 @@ Tk_GetJustifyFromObj( int Tk_GetJustify( Tcl_Interp *interp, /* Use this for error reporting. */ - CONST char *string, /* String describing a justification style. */ + const char *string, /* String describing a justification style. */ Tk_Justify *justifyPtr) /* Where to store Tk_Justify corresponding to * string. */ { @@ -432,8 +438,10 @@ Tk_GetJustify( return TCL_OK; } - Tcl_AppendResult(interp, "bad justification \"", string, - "\": must be left, right, or center", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad justification \"%s\": must be left, right, or center", + string)); + Tcl_SetErrorCode(interp, "TK", "VALUE", "JUSTIFY", NULL); return TCL_ERROR; } @@ -454,7 +462,7 @@ Tk_GetJustify( *-------------------------------------------------------------- */ -CONST char * +const char * Tk_NameOfJustify( Tk_Justify justify) /* Justification style for which identifying * string is desired. */ @@ -487,8 +495,9 @@ static void FreeUidThreadExitProc( ClientData clientData) /* Not used. */ { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + Tcl_DeleteHashTable(&tsdPtr->uidTable); tsdPtr->initialized = 0; } @@ -517,10 +526,10 @@ FreeUidThreadExitProc( Tk_Uid Tk_GetUid( - CONST char *string) /* String to convert. */ + const char *string) /* String to convert. */ { int dummy; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); Tcl_HashTable *tablePtr = &tsdPtr->uidTable; @@ -559,7 +568,7 @@ Tk_GetScreenMM( Tk_Window tkwin, /* Window whose screen determines conversion * from centimeters and other absolute * units. */ - CONST char *string, /* String describing a screen distance. */ + const char *string, /* String describing a screen distance. */ double *doublePtr) /* Place to store converted result. */ { char *end; @@ -567,9 +576,7 @@ Tk_GetScreenMM( d = strtod(string, &end); if (end == string) { - error: - Tcl_AppendResult(interp, "bad screen distance \"", string, "\"", NULL); - return TCL_ERROR; + goto error; } while ((*end != '\0') && isspace(UCHAR(*end))) { end++; @@ -605,6 +612,12 @@ Tk_GetScreenMM( } *doublePtr = d; return TCL_OK; + + error: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad screen distance \"%s\"", string)); + Tcl_SetErrorCode(interp, "TK", "VALUE", "SCREEN_DISTANCE", NULL); + return TCL_ERROR; } /* @@ -633,7 +646,7 @@ Tk_GetPixels( Tk_Window tkwin, /* Window whose screen determines conversion * from centimeters and other absolute * units. */ - CONST char *string, /* String describing a number of pixels. */ + const char *string, /* String describing a number of pixels. */ int *intPtr) /* Place to store converted result. */ { double d; @@ -658,7 +671,6 @@ Tk_GetPixels( * string. * * Results: - * The return value is a standard Tcl return result. If TCL_OK is * returned, then everything went well and the pixel distance is stored * at *doublePtr; otherwise TCL_ERROR is returned and an error message is @@ -676,7 +688,7 @@ TkGetDoublePixels( Tk_Window tkwin, /* Window whose screen determines conversion * from centimeters and other absolute * units. */ - CONST char *string, /* String describing a number of pixels. */ + const char *string, /* String describing a number of pixels. */ double *doublePtr) /* Place to store converted result. */ { char *end; @@ -684,9 +696,7 @@ TkGetDoublePixels( d = strtod((char *) string, &end); if (end == string) { - error: - Tcl_AppendResult(interp, "bad screen distance \"", string, "\"", NULL); - return TCL_ERROR; + goto error; } while ((*end != '\0') && isspace(UCHAR(*end))) { end++; @@ -725,6 +735,12 @@ TkGetDoublePixels( } *doublePtr = d; return TCL_OK; + + error: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad screen distance \"%s\"", string)); + Tcl_SetErrorCode(interp, "TK", "VALUE", "FRACTIONAL_PIXELS", NULL); + return TCL_ERROR; } /* diff --git a/generic/tkGrab.c b/generic/tkGrab.c index 44a4f8c..21c06a9 100644 --- a/generic/tkGrab.c +++ b/generic/tkGrab.c @@ -12,9 +12,9 @@ #include "tkInt.h" -#ifdef __WIN32__ +#ifdef _WIN32 #include "tkWinInt.h" -#elif !(defined(__WIN32__) || defined(MAC_OSX_TK)) +#elif !defined(MAC_OSX_TK) #include "tkUnixInt.h" #endif @@ -132,7 +132,7 @@ typedef struct NewGrabWinEvent { * we generated. */ -#define GENERATED_EVENT_MAGIC ((Bool) 0x147321ac) +#define GENERATED_GRAB_EVENT_MAGIC ((Bool) 0x147321ac) /* * Mask that selects any of the state bits corresponding to buttons, plus @@ -141,7 +141,7 @@ typedef struct NewGrabWinEvent { #define ALL_BUTTONS \ (Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask) -static unsigned int buttonStates[] = { +static const unsigned int buttonStates[] = { Button1Mask, Button2Mask, Button3Mask, Button4Mask, Button5Mask }; @@ -152,7 +152,7 @@ static unsigned int buttonStates[] = { static void EatGrabEvents(TkDisplay *dispPtr, unsigned int serial); static TkWindow * FindCommonAncestor(TkWindow *winPtr1, TkWindow *winPtr2, int *countPtr1, int *countPtr2); -static Tk_RestrictAction GrabRestrictProc(ClientData arg, XEvent *eventPtr); +static Tk_RestrictProc GrabRestrictProc; static int GrabWinEventProc(Tcl_Event *evPtr, int flags); static void MovePointer2(TkWindow *sourcePtr, TkWindow *destPtr, int mode, int leaveEvents, int EnterEvents); @@ -183,18 +183,18 @@ Tk_GrabObjCmd( ClientData clientData, /* Main window associated with interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { int globalGrab; Tk_Window tkwin; TkDisplay *dispPtr; - char *arg; + const char *arg; int index; int len; - static CONST char *optionStrings[] = { + static const char *const optionStrings[] = { "current", "release", "set", "status", NULL }; - static CONST char *flagStrings[] = { + static const char *const flagStrings[] = { "-global", NULL }; enum options { @@ -205,16 +205,21 @@ Tk_GrabObjCmd( /* * Can't use Tcl_WrongNumArgs here because we want the message to * read: - * wrong # args: should be "cmd ?-global window" or "cmd option - * ?arg arg ...?" + * wrong # args: should be "cmd ?-global? window" or "cmd option + * ?arg ...?" * We can fake it with Tcl_WrongNumArgs if we assume the command name * is "grab", but if it has been aliased, the message will be * incorrect. */ - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "wrong # args: should be \"", - Tcl_GetString(objv[0]), " ?-global? window\" or \"", - Tcl_GetString(objv[0]), " option ?arg arg ...?\"", NULL); + + Tcl_WrongNumArgs(interp, 1, objv, "?-global? window"); + Tcl_AppendResult(interp, " or \"", Tcl_GetString(objv[0]), + " option ?arg ...?\"", NULL); + /* This API not exposed: + * + ((Interp *) interp)->flags |= INTERP_ALTERNATE_WRONG_ARGS; + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); + */ return TCL_ERROR; } @@ -229,7 +234,7 @@ Tk_GrabObjCmd( Tcl_WrongNumArgs(interp, 1, objv, "?-global? window"); return TCL_ERROR; } - tkwin = Tk_NameToWindow(interp, arg, (Tk_Window) clientData); + tkwin = Tk_NameToWindow(interp, arg, clientData); if (tkwin == NULL) { return TCL_ERROR; } @@ -245,8 +250,7 @@ Tk_GrabObjCmd( Tcl_WrongNumArgs(interp, 1, objv, "?-global? window"); return TCL_ERROR; } - tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), - (Tk_Window) clientData); + tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), clientData); if (tkwin == NULL) { return TCL_ERROR; } @@ -272,23 +276,26 @@ Tk_GrabObjCmd( } if (objc == 3) { tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), - (Tk_Window) clientData); + clientData); if (tkwin == NULL) { return TCL_ERROR; } dispPtr = ((TkWindow *) tkwin)->dispPtr; if (dispPtr->eventualGrabWinPtr != NULL) { - Tcl_SetResult(interp, dispPtr->eventualGrabWinPtr->pathName, - TCL_STATIC); + Tcl_SetObjResult(interp, TkNewWindowObj((Tk_Window) + dispPtr->eventualGrabWinPtr)); } } else { + Tcl_Obj *resultObj = Tcl_NewObj(); + for (dispPtr = TkGetDisplayList(); dispPtr != NULL; dispPtr = dispPtr->nextPtr) { if (dispPtr->eventualGrabWinPtr != NULL) { - Tcl_AppendElement(interp, - dispPtr->eventualGrabWinPtr->pathName); + Tcl_ListObjAppendElement(NULL, resultObj, TkNewWindowObj( + (Tk_Window) dispPtr->eventualGrabWinPtr)); } } + Tcl_SetObjResult(interp, resultObj); } return TCL_OK; @@ -298,8 +305,7 @@ Tk_GrabObjCmd( Tcl_WrongNumArgs(interp, 1, objv, "release window"); return TCL_ERROR; } - tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), - (Tk_Window) clientData); + tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), clientData); if (tkwin == NULL) { Tcl_ResetResult(interp); } else { @@ -316,7 +322,7 @@ Tk_GrabObjCmd( if (objc == 3) { globalGrab = 0; tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), - (Tk_Window) clientData); + clientData); } else { globalGrab = 1; @@ -332,7 +338,7 @@ Tk_GrabObjCmd( return TCL_ERROR; } tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[3]), - (Tk_Window) clientData); + clientData); } if (tkwin == NULL) { return TCL_ERROR; @@ -342,24 +348,26 @@ Tk_GrabObjCmd( case GRABCMD_STATUS: { /* [grab status window] */ TkWindow *winPtr; + const char *statusString; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "status window"); return TCL_ERROR; } winPtr = (TkWindow *) Tk_NameToWindow(interp, Tcl_GetString(objv[2]), - (Tk_Window) clientData); + clientData); if (winPtr == NULL) { return TCL_ERROR; } dispPtr = winPtr->dispPtr; if (dispPtr->eventualGrabWinPtr != winPtr) { - Tcl_SetResult(interp, "none", TCL_STATIC); + statusString = "none"; } else if (dispPtr->grabFlags & GRAB_GLOBAL) { - Tcl_SetResult(interp, "global", TCL_STATIC); + statusString = "global"; } else { - Tcl_SetResult(interp, "local", TCL_STATIC); + statusString = "local"; } + Tcl_SetObjResult(interp, Tcl_NewStringObj(statusString, -1)); break; } } @@ -412,10 +420,7 @@ Tk_Grab( return TCL_OK; } if (dispPtr->eventualGrabWinPtr->mainPtr != winPtr->mainPtr) { - alreadyGrabbed: - Tcl_SetResult(interp, "grab failed: another application has grab", - TCL_STATIC); - return TCL_ERROR; + goto alreadyGrabbed; } Tk_Ungrab((Tk_Window) dispPtr->eventualGrabWinPtr); } @@ -437,7 +442,7 @@ Tk_Grab( dispPtr->grabFlags &= ~(GRAB_GLOBAL|GRAB_TEMP_GLOBAL); XQueryPointer(dispPtr->display, winPtr->window, &dummy1, &dummy2, &dummy3, &dummy4, &dummy5, &dummy6, &state); - if ((state & ALL_BUTTONS) != 0) { + if (state & ALL_BUTTONS) { dispPtr->grabFlags |= GRAB_TEMP_GLOBAL; goto setGlobalGrab; } @@ -476,26 +481,7 @@ Tk_Grab( Tcl_Sleep(100); } if (grabResult != 0) { - grabError: - if (grabResult == GrabNotViewable) { - Tcl_SetResult(interp, "grab failed: window not viewable", - TCL_STATIC); - } else if (grabResult == AlreadyGrabbed) { - goto alreadyGrabbed; - } else if (grabResult == GrabFrozen) { - Tcl_SetResult(interp, - "grab failed: keyboard or pointer frozen", TCL_STATIC); - } else if (grabResult == GrabInvalidTime) { - Tcl_SetResult(interp, "grab failed: invalid time", - TCL_STATIC); - } else { - char msg[64 + TCL_INTEGER_SPACE]; - - sprintf(msg, "grab failed for unknown reason (code %d)", - grabResult); - Tcl_AppendResult(interp, msg, NULL); - } - return TCL_ERROR; + goto grabError; } grabResult = XGrabKeyboard(dispPtr->display, Tk_WindowId(tkwin), False, GrabModeAsync, GrabModeAsync, CurrentTime); @@ -543,6 +529,31 @@ Tk_Grab( } QueueGrabWindowChange(dispPtr, winPtr); return TCL_OK; + + grabError: + if (grabResult == GrabNotViewable) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "grab failed: window not viewable", -1)); + Tcl_SetErrorCode(interp, "TK", "GRAB", "UNVIEWABLE", NULL); + } else if (grabResult == AlreadyGrabbed) { + alreadyGrabbed: + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "grab failed: another application has grab", -1)); + Tcl_SetErrorCode(interp, "TK", "GRAB", "GRABBED", NULL); + } else if (grabResult == GrabFrozen) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "grab failed: keyboard or pointer frozen", -1)); + Tcl_SetErrorCode(interp, "TK", "GRAB", "FROZEN", NULL); + } else if (grabResult == GrabInvalidTime) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "grab failed: invalid time", -1)); + Tcl_SetErrorCode(interp, "TK", "GRAB", "BAD_TIME", NULL); + } else { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "grab failed for unknown reason (code %d)", grabResult)); + Tcl_SetErrorCode(interp, "TK", "GRAB", "UNKNOWN", NULL); + } + return TCL_ERROR; } /* @@ -724,7 +735,7 @@ TkPointerEvent( * serverWinPtr. */ - if (eventPtr->xcrossing.send_event != GENERATED_EVENT_MAGIC) { + if (eventPtr->xcrossing.send_event != GENERATED_GRAB_EVENT_MAGIC) { if ((eventPtr->type == LeaveNotify) && (winPtr->flags & TK_TOP_HIERARCHY)) { dispPtr->serverWinPtr = NULL; @@ -843,7 +854,7 @@ TkPointerEvent( } } if (eventPtr->type == ButtonPress) { - if ((eventPtr->xbutton.state & ALL_BUTTONS) == 0) { + if (!(eventPtr->xbutton.state & ALL_BUTTONS)) { if (outsideGrabTree) { TkChangeEventWindow(eventPtr, dispPtr->grabWinPtr); Tk_QueueWindowEvent(eventPtr, TCL_QUEUE_HEAD); @@ -870,8 +881,9 @@ TkPointerEvent( return 1; } } else { - if ((eventPtr->xbutton.state & ALL_BUTTONS) - == buttonStates[eventPtr->xbutton.button - Button1]) { + if (eventPtr->xbutton.button != AnyButton && + ((eventPtr->xbutton.state & ALL_BUTTONS) + == buttonStates[eventPtr->xbutton.button - Button1])) { ReleaseButtonGrab(dispPtr); /* Note 4. */ } } @@ -1153,7 +1165,7 @@ MovePointer2( } event.xcrossing.serial = LastKnownRequestProcessed(winPtr->display); - event.xcrossing.send_event = GENERATED_EVENT_MAGIC; + event.xcrossing.send_event = GENERATED_GRAB_EVENT_MAGIC; event.xcrossing.display = winPtr->display; event.xcrossing.root = RootWindow(winPtr->display, winPtr->screenNum); event.xcrossing.time = TkCurrentTime(winPtr->dispPtr); @@ -1239,17 +1251,18 @@ EatGrabEvents( unsigned int serial) /* Only discard events that have a serial * number at least this great. */ { - Tk_RestrictProc *oldProc; + Tk_RestrictProc *prevProc; GrabInfo info; - ClientData oldArg, dummy; + ClientData prevArg; info.display = dispPtr->display; info.serial = serial; TkpSync(info.display); - oldProc = Tk_RestrictEvents(GrabRestrictProc, (ClientData)&info, &oldArg); + prevProc = Tk_RestrictEvents(GrabRestrictProc, &info, &prevArg); while (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) { + /* EMPTY */ } - Tk_RestrictEvents(oldProc, oldArg, &dummy); + Tk_RestrictEvents(prevProc, prevArg, &prevArg); } /* @@ -1276,7 +1289,7 @@ GrabRestrictProc( ClientData arg, XEvent *eventPtr) { - GrabInfo *info = (GrabInfo *) arg; + GrabInfo *info = arg; int mode, diff; /* @@ -1334,7 +1347,7 @@ QueueGrabWindowChange( { NewGrabWinEvent *grabEvPtr; - grabEvPtr = (NewGrabWinEvent *) ckalloc(sizeof(NewGrabWinEvent)); + grabEvPtr = ckalloc(sizeof(NewGrabWinEvent)); grabEvPtr->header.proc = GrabWinEventProc; grabEvPtr->dispPtr = dispPtr; if (grabWinPtr == NULL) { diff --git a/generic/tkGrid.c b/generic/tkGrid.c index ccdde19..4e0882a 100644 --- a/generic/tkGrid.c +++ b/generic/tkGrid.c @@ -241,10 +241,13 @@ typedef struct UniformGroup { * size. 0 means if this window is a master then * Tk will set its requested size to fit the * needs of its slaves. + * ALLOCED_MASTER 1 means that Grid has allocated itself as + * geometry master for this window. */ #define REQUESTED_RELAYOUT 1 #define DONT_PROPAGATE 2 +#define ALLOCED_MASTER 4 /* * Prototypes for procedures used only in this file: @@ -258,31 +261,31 @@ static void ArrangeGrid(ClientData clientData); static int CheckSlotData(Gridder *masterPtr, int slot, int slotType, int checkOnly); static int ConfigureSlaves(Tcl_Interp *interp, Tk_Window tkwin, - int objc, Tcl_Obj *CONST objv[]); -static void DestroyGrid(char *memPtr); + int objc, Tcl_Obj *const objv[]); +static void DestroyGrid(void *memPtr); static Gridder * GetGrid(Tk_Window tkwin); static int GridAnchorCommand(Tk_Window tkwin, Tcl_Interp *interp, - int objc, Tcl_Obj *CONST objv[]); + int objc, Tcl_Obj *const objv[]); static int GridBboxCommand(Tk_Window tkwin, Tcl_Interp *interp, - int objc, Tcl_Obj *CONST objv[]); + int objc, Tcl_Obj *const objv[]); static int GridForgetRemoveCommand(Tk_Window tkwin, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[]); + Tcl_Obj *const objv[]); static int GridInfoCommand(Tk_Window tkwin, Tcl_Interp *interp, - int objc, Tcl_Obj *CONST objv[]); + int objc, Tcl_Obj *const objv[]); static int GridLocationCommand(Tk_Window tkwin, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[]); + Tcl_Obj *const objv[]); static int GridPropagateCommand(Tk_Window tkwin, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[]); + Tcl_Obj *const objv[]); static int GridRowColumnConfigureCommand(Tk_Window tkwin, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[]); + Tcl_Obj *const objv[]); static int GridSizeCommand(Tk_Window tkwin, Tcl_Interp *interp, - int objc, Tcl_Obj *CONST objv[]); + int objc, Tcl_Obj *const objv[]); static int GridSlavesCommand(Tk_Window tkwin, Tcl_Interp *interp, - int objc, Tcl_Obj *CONST objv[]); + int objc, Tcl_Obj *const objv[]); static void GridStructureProc(ClientData clientData, XEvent *eventPtr); static void GridLostSlaveProc(ClientData clientData, @@ -298,8 +301,8 @@ static int SetSlaveColumn(Tcl_Interp *interp, Gridder *slavePtr, int column, int numCols); static int SetSlaveRow(Tcl_Interp *interp, Gridder *slavePtr, int row, int numRows); -static void StickyToString(int flags, char *result); -static int StringToSticky(char *string); +static Tcl_Obj * StickyToObj(int flags); +static int StringToSticky(const char *string); static void Unlink(Gridder *gridPtr); static const Tk_GeomMgr gridMgrType = { @@ -330,10 +333,10 @@ Tk_GridObjCmd( ClientData clientData, /* Main window associated with interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { - Tk_Window tkwin = (Tk_Window) clientData; - static CONST char *optionStrings[] = { + Tk_Window tkwin = clientData; + static const char *const optionStrings[] = { "anchor", "bbox", "columnconfigure", "configure", "forget", "info", "location", "propagate", "remove", "rowconfigure", "size", "slaves", NULL @@ -346,7 +349,7 @@ Tk_GridObjCmd( int index; if (objc >= 2) { - char *argv1 = Tcl_GetString(objv[1]); + const char *argv1 = Tcl_GetString(objv[1]); if ((argv1[0] == '.') || (argv1[0] == REL_SKIP) || (argv1[0] == REL_VERT)) { @@ -358,8 +361,8 @@ Tk_GridObjCmd( return TCL_ERROR; } - if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0, - &index) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings, + sizeof(char *), "option", 0, &index) != TCL_OK) { return TCL_ERROR; } @@ -399,7 +402,8 @@ Tk_GridObjCmd( } /* This should not happen */ - Tcl_SetResult(interp, "Internal error in grid.", TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj("internal error in grid", -1)); + Tcl_SetErrorCode(interp, "TK", "API_ABUSE", NULL); return TCL_ERROR; } @@ -425,7 +429,7 @@ GridAnchorCommand( Tk_Window tkwin, /* Main window of the application. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { Tk_Window master; Gridder *masterPtr; @@ -444,8 +448,9 @@ GridAnchorCommand( if (objc == 3) { gridPtr = masterPtr->masterDataPtr; - Tcl_SetResult(interp, (char *) Tk_NameOfAnchor(gridPtr == NULL ? - GRID_DEFAULT_ANCHOR : gridPtr->anchor), TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + Tk_NameOfAnchor(gridPtr?gridPtr->anchor:GRID_DEFAULT_ANCHOR), + -1)); return TCL_OK; } @@ -466,7 +471,7 @@ GridAnchorCommand( } if (!(masterPtr->flags & REQUESTED_RELAYOUT)) { masterPtr->flags |= REQUESTED_RELAYOUT; - Tcl_DoWhenIdle(ArrangeGrid, (ClientData) masterPtr); + Tcl_DoWhenIdle(ArrangeGrid, masterPtr); } } return TCL_OK; @@ -493,7 +498,7 @@ GridBboxCommand( Tk_Window tkwin, /* Main window of the application. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { Tk_Window master; Gridder *masterPtr; /* master grid record */ @@ -623,12 +628,12 @@ GridForgetRemoveCommand( Tk_Window tkwin, /* Main window of the application. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { Tk_Window slave; Gridder *slavePtr; int i; - char *string = Tcl_GetString(objv[1]); + const char *string = Tcl_GetString(objv[1]); char c = string[0]; for (i = 2; i < objc; i++) { @@ -659,7 +664,7 @@ GridForgetRemoveCommand( } slavePtr->doubleBw = 2*Tk_Changes(tkwin)->border_width; if (slavePtr->flags & REQUESTED_RELAYOUT) { - Tcl_CancelIdleCall(ArrangeGrid, (ClientData) slavePtr); + Tcl_CancelIdleCall(ArrangeGrid, slavePtr); } slavePtr->flags = 0; slavePtr->sticky = 0; @@ -679,7 +684,7 @@ GridForgetRemoveCommand( Tcl_IncrRefCount(slavePtr->in); } } - Tk_ManageGeometry(slave, NULL, (ClientData) NULL); + Tk_ManageGeometry(slave, NULL, NULL); if (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin)) { Tk_UnmaintainGeometry(slavePtr->tkwin, slavePtr->masterPtr->tkwin); @@ -713,11 +718,11 @@ GridInfoCommand( Tk_Window tkwin, /* Main window of the application. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { register Gridder *slavePtr; Tk_Window slave; - char buffer[64 + TCL_INTEGER_SPACE * 4]; + Tcl_Obj *infoObj; if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "window"); @@ -732,18 +737,24 @@ GridInfoCommand( return TCL_OK; } - Tcl_AppendElement(interp, "-in"); - Tcl_AppendElement(interp, Tk_PathName(slavePtr->masterPtr->tkwin)); - sprintf(buffer, " -column %d -row %d -columnspan %d -rowspan %d", - slavePtr->column, slavePtr->row, - slavePtr->numCols, slavePtr->numRows); - Tcl_AppendResult(interp, buffer, NULL); - TkPrintPadAmount(interp, "ipadx", slavePtr->iPadX/2, slavePtr->iPadX); - TkPrintPadAmount(interp, "ipady", slavePtr->iPadY/2, slavePtr->iPadY); - TkPrintPadAmount(interp, "padx", slavePtr->padLeft, slavePtr->padX); - TkPrintPadAmount(interp, "pady", slavePtr->padTop, slavePtr->padY); - StickyToString(slavePtr->sticky, buffer); - Tcl_AppendResult(interp, " -sticky ", buffer, NULL); + infoObj = Tcl_NewObj(); + Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-in", -1), + TkNewWindowObj(slavePtr->masterPtr->tkwin)); + Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-column", -1), + Tcl_NewIntObj(slavePtr->column)); + Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-row", -1), + Tcl_NewIntObj(slavePtr->row)); + Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-columnspan", -1), + Tcl_NewIntObj(slavePtr->numCols)); + Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-rowspan", -1), + Tcl_NewIntObj(slavePtr->numRows)); + TkAppendPadAmount(infoObj, "-ipadx", slavePtr->iPadX/2, slavePtr->iPadX); + TkAppendPadAmount(infoObj, "-ipady", slavePtr->iPadY/2, slavePtr->iPadY); + TkAppendPadAmount(infoObj, "-padx", slavePtr->padLeft, slavePtr->padX); + TkAppendPadAmount(infoObj, "-pady", slavePtr->padTop, slavePtr->padY); + Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-sticky", -1), + StickyToObj(slavePtr->sticky)); + Tcl_SetObjResult(interp, infoObj); return TCL_OK; } @@ -769,7 +780,7 @@ GridLocationCommand( Tk_Window tkwin, /* Main window of the application. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { Tk_Window master; Gridder *masterPtr; /* Master grid record. */ @@ -809,8 +820,8 @@ GridLocationCommand( */ while (masterPtr->flags & REQUESTED_RELAYOUT) { - Tcl_CancelIdleCall(ArrangeGrid, (ClientData) masterPtr); - ArrangeGrid((ClientData) masterPtr); + Tcl_CancelIdleCall(ArrangeGrid, masterPtr); + ArrangeGrid(masterPtr); } SetGridSize(masterPtr); endX = MAX(gridPtr->columnEnd, gridPtr->columnMax); @@ -862,7 +873,7 @@ GridPropagateCommand( Tk_Window tkwin, /* Main window of the application. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { Tk_Window master; Gridder *masterPtr; @@ -893,8 +904,22 @@ GridPropagateCommand( old = !(masterPtr->flags & DONT_PROPAGATE); if (propagate != old) { if (propagate) { + /* + * If we have slaves, we need to register as geometry master. + */ + + if (masterPtr->slavePtr != NULL) { + if (TkSetGeometryMaster(interp, master, "grid") != TCL_OK) { + return TCL_ERROR; + } + masterPtr->flags |= ALLOCED_MASTER; + } masterPtr->flags &= ~DONT_PROPAGATE; } else { + if (masterPtr->flags & ALLOCED_MASTER) { + TkFreeGeometryMaster(master, "grid"); + masterPtr->flags &= ~ALLOCED_MASTER; + } masterPtr->flags |= DONT_PROPAGATE; } @@ -908,7 +933,7 @@ GridPropagateCommand( } if (!(masterPtr->flags & REQUESTED_RELAYOUT)) { masterPtr->flags |= REQUESTED_RELAYOUT; - Tcl_DoWhenIdle(ArrangeGrid, (ClientData) masterPtr); + Tcl_DoWhenIdle(ArrangeGrid, masterPtr); } } return TCL_OK; @@ -936,7 +961,7 @@ GridRowColumnConfigureCommand( Tk_Window tkwin, /* Main window of the application. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { Tk_Window master, slave; Gridder *masterPtr, *slavePtr; @@ -948,8 +973,8 @@ GridRowColumnConfigureCommand( Tcl_Obj **lObjv; /* array of indices */ int ok; /* temporary TCL result code */ int i, j, first, last; - char *string; - static CONST char *optionStrings[] = { + const char *string; + static const char *const optionStrings[] = { "-minsize", "-pad", "-uniform", "-weight", NULL }; enum options { @@ -959,7 +984,7 @@ GridRowColumnConfigureCommand( Tcl_Obj *listCopy; if (((objc % 2 != 0) && (objc > 6)) || (objc < 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "master index ?-option value...?"); + Tcl_WrongNumArgs(interp, 2, objv, "master index ?-option value ...?"); return TCL_ERROR; } @@ -977,9 +1002,9 @@ GridRowColumnConfigureCommand( string = Tcl_GetString(objv[1]); slotType = (*string == 'c') ? COLUMN : ROW; if (lObjc == 0) { - Tcl_AppendResult(interp, "no ", - (slotType == COLUMN) ? "column" : "row", - " indices specified", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf("no %s indices specified", + (slotType == COLUMN) ? "column" : "row")); + Tcl_SetErrorCode(interp, "TK", "GRID", "NO_INDEX", NULL); Tcl_DecrRefCount(listCopy); return TCL_ERROR; } @@ -990,16 +1015,17 @@ GridRowColumnConfigureCommand( if ((objc == 4) || (objc == 5)) { if (lObjc != 1) { - Tcl_AppendResult(interp, Tcl_GetString(objv[0]), " ", - Tcl_GetString(objv[1]), - ": must specify a single element on retrieval", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "must specify a single element on retrieval", -1)); + Tcl_SetErrorCode(interp, "TK", "GRID", "USAGE", NULL); Tcl_DecrRefCount(listCopy); return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, lObjv[0], &slot) != TCL_OK) { Tcl_AppendResult(interp, - " (when retreiving options only integer indices are " + " (when retrieving options only integer indices are " "allowed)", NULL); + Tcl_SetErrorCode(interp, "TK", "GRID", "INDEX_FORMAT", NULL); Tcl_DecrRefCount(listCopy); return TCL_ERROR; } @@ -1050,25 +1076,25 @@ GridRowColumnConfigureCommand( * returned. */ - if (Tcl_GetIndexFromObj(interp, objv[4], optionStrings, "option", 0, - &index) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[4], optionStrings, + sizeof(char *), "option", 0, &index) != TCL_OK) { Tcl_DecrRefCount(listCopy); return TCL_ERROR; } if (index == ROWCOL_MINSIZE) { - Tcl_SetObjResult(interp, - Tcl_NewIntObj((ok == TCL_OK) ? slotPtr[slot].minSize : 0)); + Tcl_SetObjResult(interp, Tcl_NewIntObj( + (ok == TCL_OK) ? slotPtr[slot].minSize : 0)); } else if (index == ROWCOL_WEIGHT) { - Tcl_SetObjResult(interp, - Tcl_NewIntObj((ok == TCL_OK) ? slotPtr[slot].weight : 0)); + Tcl_SetObjResult(interp, Tcl_NewIntObj( + (ok == TCL_OK) ? slotPtr[slot].weight : 0)); } else if (index == ROWCOL_UNIFORM) { Tk_Uid value = (ok == TCL_OK) ? slotPtr[slot].uniform : ""; - Tcl_SetObjResult(interp, - Tcl_NewStringObj(value == NULL ? "" : value, -1)); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + (value == NULL) ? "" : value, -1)); } else if (index == ROWCOL_PAD) { - Tcl_SetObjResult(interp, - Tcl_NewIntObj((ok == TCL_OK) ? slotPtr[slot].pad : 0)); + Tcl_SetObjResult(interp, Tcl_NewIntObj( + (ok == TCL_OK) ? slotPtr[slot].pad : 0)); } Tcl_DecrRefCount(listCopy); return TCL_OK; @@ -1101,17 +1127,17 @@ GridRowColumnConfigureCommand( slavePtr = GetGrid(slave); if (slavePtr->masterPtr != masterPtr) { - Tcl_AppendResult(interp, Tcl_GetString(objv[0]), " ", - Tcl_GetString(objv[1]), ": the window \"", - Tcl_GetString(lObjv[j]), "\" is not managed by \"", - Tcl_GetString(objv[2]), "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "the window \"%s\" is not managed by \"%s\"", + Tcl_GetString(lObjv[j]), Tcl_GetString(objv[2]))); + Tcl_SetErrorCode(interp, "TK", "GRID", "NOT_MASTER", NULL); Tcl_DecrRefCount(listCopy); return TCL_ERROR; } } else { - Tcl_AppendResult(interp, Tcl_GetString(objv[0]), " ", - Tcl_GetString(objv[1]), ": illegal index \"", - Tcl_GetString(lObjv[j]), "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "illegal index \"%s\"", Tcl_GetString(lObjv[j]))); + Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID_INDEX", NULL); Tcl_DecrRefCount(listCopy); return TCL_ERROR; } @@ -1131,11 +1157,12 @@ GridRowColumnConfigureCommand( for (slot = first; slot <= last; slot++) { ok = CheckSlotData(masterPtr, slot, slotType, /*checkOnly*/ 0); if (ok != TCL_OK) { - Tcl_AppendResult(interp, Tcl_GetString(objv[0]), " ", - Tcl_GetString(objv[1]), ": \"", - Tcl_GetString(lObjv[j]), - "\" is out of range", NULL); - Tcl_DecrRefCount(listCopy); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "\"%s\" is out of range", + Tcl_GetString(lObjv[j]))); + Tcl_SetErrorCode(interp, "TK", "GRID", "INDEX_RANGE", + NULL); + Tcl_DecrRefCount(listCopy); return TCL_ERROR; } slotPtr = (slotType == COLUMN) ? @@ -1148,15 +1175,15 @@ GridRowColumnConfigureCommand( */ for (i = 4; i < objc; i += 2) { - if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings, - "option", 0, &index) != TCL_OK) { - Tcl_DecrRefCount(listCopy); + if (Tcl_GetIndexFromObjStruct(interp, objv[i], optionStrings, + sizeof(char *), "option", 0, &index) != TCL_OK) { + Tcl_DecrRefCount(listCopy); return TCL_ERROR; } if (index == ROWCOL_MINSIZE) { if (Tk_GetPixelsFromObj(interp, master, objv[i+1], &size) != TCL_OK) { - Tcl_DecrRefCount(listCopy); + Tcl_DecrRefCount(listCopy); return TCL_ERROR; } else { slotPtr[slot].minSize = size; @@ -1165,14 +1192,11 @@ GridRowColumnConfigureCommand( int wt; if (Tcl_GetIntFromObj(interp,objv[i+1],&wt)!=TCL_OK) { - Tcl_DecrRefCount(listCopy); + Tcl_DecrRefCount(listCopy); return TCL_ERROR; } else if (wt < 0) { - Tcl_AppendResult(interp, "invalid arg \"", - Tcl_GetString(objv[i]), - "\": should be non-negative", NULL); - Tcl_DecrRefCount(listCopy); - return TCL_ERROR; + Tcl_DecrRefCount(listCopy); + goto negativeIndex; } else { slotPtr[slot].weight = wt; } @@ -1186,14 +1210,11 @@ GridRowColumnConfigureCommand( } else if (index == ROWCOL_PAD) { if (Tk_GetPixelsFromObj(interp, master, objv[i+1], &size) != TCL_OK) { - Tcl_DecrRefCount(listCopy); + Tcl_DecrRefCount(listCopy); return TCL_ERROR; } else if (size < 0) { - Tcl_AppendResult(interp, "invalid arg \"", - Tcl_GetString(objv[i]), - "\": should be non-negative", NULL); - Tcl_DecrRefCount(listCopy); - return TCL_ERROR; + Tcl_DecrRefCount(listCopy); + goto negativeIndex; } else { slotPtr[slot].pad = size; } @@ -1239,9 +1260,16 @@ GridRowColumnConfigureCommand( } if (!(masterPtr->flags & REQUESTED_RELAYOUT)) { masterPtr->flags |= REQUESTED_RELAYOUT; - Tcl_DoWhenIdle(ArrangeGrid, (ClientData) masterPtr); + Tcl_DoWhenIdle(ArrangeGrid, masterPtr); } return TCL_OK; + + negativeIndex: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "invalid arg \"%s\": should be non-negative", + Tcl_GetString(objv[i]))); + Tcl_SetErrorCode(interp, "TK", "GRID", "NEG_INDEX", NULL); + return TCL_ERROR; } /* @@ -1266,7 +1294,7 @@ GridSizeCommand( Tk_Window tkwin, /* Main window of the application. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { Tk_Window master; Gridder *masterPtr; @@ -1317,35 +1345,36 @@ GridSlavesCommand( Tk_Window tkwin, /* Main window of the application. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { Tk_Window master; Gridder *masterPtr; /* master grid record */ Gridder *slavePtr; int i, value, index; int row = -1, column = -1; - static CONST char *optionStrings[] = { + static const char *const optionStrings[] = { "-column", "-row", NULL }; enum options { SLAVES_COLUMN, SLAVES_ROW }; Tcl_Obj *res; if ((objc < 3) || ((objc % 2) == 0)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?-option value...?"); + Tcl_WrongNumArgs(interp, 2, objv, "window ?-option value ...?"); return TCL_ERROR; } for (i = 3; i < objc; i += 2) { - if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings, "option", 0, - &index) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[i], optionStrings, + sizeof(char *), "option", 0, &index) != TCL_OK) { return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, objv[i+1], &value) != TCL_OK) { return TCL_ERROR; } if (value < 0) { - Tcl_AppendResult(interp, Tcl_GetString(objv[i]), - " is an invalid value: should NOT be < 0", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "%d is an invalid value: should NOT be < 0", value)); + Tcl_SetErrorCode(interp, "TK", "GRID", "NEG_INDEX", NULL); return TCL_ERROR; } if (index == SLAVES_COLUMN) { @@ -1363,16 +1392,15 @@ GridSlavesCommand( res = Tcl_NewListObj(0, NULL); for (slavePtr = masterPtr->slavePtr; slavePtr != NULL; slavePtr = slavePtr->nextPtr) { - if (column>=0 && (slavePtr->column > column + if ((column >= 0) && (slavePtr->column > column || slavePtr->column+slavePtr->numCols-1 < column)) { continue; } - if (row>=0 && (slavePtr->row > row || + if ((row >= 0) && (slavePtr->row > row || slavePtr->row+slavePtr->numRows-1 < row)) { continue; } - Tcl_ListObjAppendElement(interp, res, - Tcl_NewStringObj(Tk_PathName(slavePtr->tkwin), -1)); + Tcl_ListObjAppendElement(interp,res, TkNewWindowObj(slavePtr->tkwin)); } Tcl_SetObjResult(interp, res); return TCL_OK; @@ -1403,12 +1431,12 @@ GridReqProc( Tk_Window tkwin) /* Other Tk-related information about the * window. */ { - register Gridder *gridPtr = (Gridder *) clientData; + register Gridder *gridPtr = clientData; gridPtr = gridPtr->masterPtr; if (gridPtr && !(gridPtr->flags & REQUESTED_RELAYOUT)) { gridPtr->flags |= REQUESTED_RELAYOUT; - Tcl_DoWhenIdle(ArrangeGrid, (ClientData) gridPtr); + Tcl_DoWhenIdle(ArrangeGrid, gridPtr); } } @@ -1435,7 +1463,7 @@ GridLostSlaveProc( * stolen away. */ Tk_Window tkwin) /* Tk's handle for the slave window. */ { - register Gridder *slavePtr = (Gridder *) clientData; + register Gridder *slavePtr = clientData; if (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin)) { Tk_UnmaintainGeometry(slavePtr->tkwin, slavePtr->masterPtr->tkwin); @@ -1693,7 +1721,7 @@ ArrangeGrid( ClientData clientData) /* Structure describing master whose slaves * are to be re-layed out. */ { - register Gridder *masterPtr = (Gridder *) clientData; + register Gridder *masterPtr = clientData; register Gridder *slavePtr; GridMaster *slotPtr = masterPtr->masterDataPtr; int abort; @@ -1729,7 +1757,7 @@ ArrangeGrid( } masterPtr->abortPtr = &abort; abort = 0; - Tcl_Preserve((ClientData) masterPtr); + Tcl_Preserve(masterPtr); /* * Call the constraint engine to fill in the row and column offsets. @@ -1756,10 +1784,10 @@ ArrangeGrid( Tk_GeometryRequest(masterPtr->tkwin, width, height); if (width>1 && height>1) { masterPtr->flags |= REQUESTED_RELAYOUT; - Tcl_DoWhenIdle(ArrangeGrid, (ClientData) masterPtr); + Tcl_DoWhenIdle(ArrangeGrid, masterPtr); } masterPtr->abortPtr = NULL; - Tcl_Release((ClientData) masterPtr); + Tcl_Release(masterPtr); return; } @@ -1845,7 +1873,7 @@ ArrangeGrid( } masterPtr->abortPtr = NULL; - Tcl_Release((ClientData) masterPtr); + Tcl_Release(masterPtr); } /* @@ -1928,8 +1956,7 @@ ResolveConstraints( gridCount = MAX(constraintCount, slotCount); if (gridCount >= TYPICAL_SIZE) { - layoutPtr = (GridLayout *) - ckalloc(sizeof(GridLayout) * (1+gridCount)); + layoutPtr = ckalloc(sizeof(GridLayout) * (1+gridCount)); } else { layoutPtr = layoutData; } @@ -2051,12 +2078,12 @@ ResolveConstraints( * sizeof(UniformGroup); size_t newSize = (uniformGroupsAlloced + UNIFORM_PREALLOC) * sizeof(UniformGroup); - UniformGroup *newUG = (UniformGroup *) ckalloc(newSize); + UniformGroup *newUG = ckalloc(newSize); UniformGroup *oldUG = uniformGroupPtr; memcpy(newUG, oldUG, oldSize); if (oldUG != uniformPre) { - ckfree((char *) oldUG); + ckfree(oldUG); } uniformGroupPtr = newUG; uniformGroupsAlloced += UNIFORM_PREALLOC; @@ -2096,7 +2123,7 @@ ResolveConstraints( } if (uniformGroupPtr != uniformPre) { - ckfree((char *) uniformGroupPtr); + ckfree(uniformGroupPtr); } /* @@ -2366,7 +2393,7 @@ ResolveConstraints( --layoutPtr; if (layoutPtr != layoutData) { - ckfree((char *) layoutPtr); + ckfree(layoutPtr); } return requiredSize; } @@ -2412,9 +2439,9 @@ GetGrid( hPtr = Tcl_CreateHashEntry(&dispPtr->gridHashTable, (char*) tkwin, &isNew); if (!isNew) { - return (Gridder *) Tcl_GetHashValue(hPtr); + return Tcl_GetHashValue(hPtr); } - gridPtr = (Gridder *) ckalloc(sizeof(Gridder)); + gridPtr = ckalloc(sizeof(Gridder)); gridPtr->tkwin = tkwin; gridPtr->masterPtr = NULL; gridPtr->masterDataPtr = NULL; @@ -2433,7 +2460,7 @@ GetGrid( gridPtr->padTop = 0; gridPtr->iPadX = 0; gridPtr->iPadY = 0; - gridPtr->doubleBw = 2*Tk_Changes(tkwin)->border_width; + gridPtr->doubleBw = 2 * Tk_Changes(tkwin)->border_width; gridPtr->abortPtr = NULL; gridPtr->flags = 0; gridPtr->sticky = 0; @@ -2442,7 +2469,7 @@ GetGrid( gridPtr->masterDataPtr = NULL; Tcl_SetHashValue(hPtr, gridPtr); Tk_CreateEventHandler(tkwin, StructureNotifyMask, - GridStructureProc, (ClientData) gridPtr); + GridStructureProc, gridPtr); return gridPtr; } @@ -2513,7 +2540,8 @@ SetSlaveColumn( lastCol = ((newColumn >= 0) ? newColumn : 0) + newNumCols; if (lastCol >= MAX_ELEMENT) { - Tcl_SetResult(interp, "Column out of bounds", TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj("column out of bounds",-1)); + Tcl_SetErrorCode(interp, "TK", "GRID", "BAD_COLUMN", NULL); return TCL_ERROR; } @@ -2553,7 +2581,8 @@ SetSlaveRow( lastRow = ((newRow >= 0) ? newRow : 0) + newNumRows; if (lastRow >= MAX_ELEMENT) { - Tcl_SetResult(interp, "Row out of bounds", TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj("row out of bounds", -1)); + Tcl_SetErrorCode(interp, "TK", "GRID", "BAD_ROW", NULL); return TCL_ERROR; } @@ -2622,14 +2651,14 @@ CheckSlotData( int newNumSlot = slot + PREALLOC; size_t oldSize = numSlot * sizeof(SlotInfo); size_t newSize = newNumSlot * sizeof(SlotInfo); - SlotInfo *newSI = (SlotInfo *) ckalloc(newSize); + SlotInfo *newSI = ckalloc(newSize); SlotInfo *oldSI = (slotType == ROW) ? masterPtr->masterDataPtr->rowPtr : masterPtr->masterDataPtr->columnPtr; memcpy(newSI, oldSI, oldSize); memset(newSI+numSlot, 0, newSize - oldSize); - ckfree((char *) oldSI); + ckfree(oldSI); if (slotType == ROW) { masterPtr->masterDataPtr->rowPtr = newSI; masterPtr->masterDataPtr->rowSpace = newNumSlot; @@ -2672,17 +2701,17 @@ InitMasterData( Gridder *masterPtr) { if (masterPtr->masterDataPtr == NULL) { - GridMaster *gridPtr = masterPtr->masterDataPtr = (GridMaster *) + GridMaster *gridPtr = masterPtr->masterDataPtr = ckalloc(sizeof(GridMaster)); size_t size = sizeof(SlotInfo) * TYPICAL_SIZE; gridPtr->columnEnd = 0; gridPtr->columnMax = 0; - gridPtr->columnPtr = (SlotInfo *) ckalloc(size); + gridPtr->columnPtr = ckalloc(size); gridPtr->columnSpace = TYPICAL_SIZE; gridPtr->rowEnd = 0; gridPtr->rowMax = 0; - gridPtr->rowPtr = (SlotInfo *) ckalloc(size); + gridPtr->rowPtr = ckalloc(size); gridPtr->rowSpace = TYPICAL_SIZE; gridPtr->startX = 0; gridPtr->startY = 0; @@ -2736,7 +2765,7 @@ Unlink( } if (!(masterPtr->flags & REQUESTED_RELAYOUT)) { masterPtr->flags |= REQUESTED_RELAYOUT; - Tcl_DoWhenIdle(ArrangeGrid, (ClientData) masterPtr); + Tcl_DoWhenIdle(ArrangeGrid, masterPtr); } if (masterPtr->abortPtr != NULL) { *masterPtr->abortPtr = 1; @@ -2744,6 +2773,16 @@ Unlink( SetGridSize(slavePtr->masterPtr); slavePtr->masterPtr = NULL; + + /* + * If we have emptied this master from slaves it means we are no longer + * handling it and should mark it as free. + */ + + if ((masterPtr->slavePtr == NULL) && (masterPtr->flags & ALLOCED_MASTER)) { + TkFreeGeometryMaster(masterPtr->tkwin, "grid"); + masterPtr->flags &= ~ALLOCED_MASTER; + } } /* @@ -2768,23 +2807,23 @@ Unlink( static void DestroyGrid( - char *memPtr) /* Info about window that is now dead. */ + void *memPtr) /* Info about window that is now dead. */ { - register Gridder *gridPtr = (Gridder *) memPtr; + register Gridder *gridPtr = memPtr; if (gridPtr->masterDataPtr != NULL) { if (gridPtr->masterDataPtr->rowPtr != NULL) { - ckfree((char *) gridPtr->masterDataPtr -> rowPtr); + ckfree(gridPtr->masterDataPtr -> rowPtr); } if (gridPtr->masterDataPtr->columnPtr != NULL) { - ckfree((char *) gridPtr->masterDataPtr -> columnPtr); + ckfree(gridPtr->masterDataPtr -> columnPtr); } - ckfree((char *) gridPtr->masterDataPtr); + ckfree(gridPtr->masterDataPtr); } if (gridPtr->in != NULL) { Tcl_DecrRefCount(gridPtr->in); } - ckfree((char *) gridPtr); + ckfree(gridPtr); } /* @@ -2811,55 +2850,56 @@ GridStructureProc( * eventPtr. */ XEvent *eventPtr) /* Describes what just happened. */ { - register Gridder *gridPtr = (Gridder *) clientData; + register Gridder *gridPtr = clientData; TkDisplay *dispPtr = ((TkWindow *) gridPtr->tkwin)->dispPtr; if (eventPtr->type == ConfigureNotify) { if ((gridPtr->slavePtr != NULL) && !(gridPtr->flags & REQUESTED_RELAYOUT)) { gridPtr->flags |= REQUESTED_RELAYOUT; - Tcl_DoWhenIdle(ArrangeGrid, (ClientData) gridPtr); + Tcl_DoWhenIdle(ArrangeGrid, gridPtr); } if ((gridPtr->masterPtr != NULL) && (gridPtr->doubleBw != 2*Tk_Changes(gridPtr->tkwin)->border_width)) { if (!(gridPtr->masterPtr->flags & REQUESTED_RELAYOUT)) { gridPtr->doubleBw = 2*Tk_Changes(gridPtr->tkwin)->border_width; gridPtr->masterPtr->flags |= REQUESTED_RELAYOUT; - Tcl_DoWhenIdle(ArrangeGrid, (ClientData) gridPtr->masterPtr); + Tcl_DoWhenIdle(ArrangeGrid, gridPtr->masterPtr); } } } else if (eventPtr->type == DestroyNotify) { - register Gridder *gridPtr2, *nextPtr; + register Gridder *slavePtr, *nextPtr; if (gridPtr->masterPtr != NULL) { Unlink(gridPtr); } - for (gridPtr2 = gridPtr->slavePtr; gridPtr2 != NULL; - gridPtr2 = nextPtr) { - Tk_UnmapWindow(gridPtr2->tkwin); - gridPtr2->masterPtr = NULL; - nextPtr = gridPtr2->nextPtr; - gridPtr2->nextPtr = NULL; + for (slavePtr = gridPtr->slavePtr; slavePtr != NULL; + slavePtr = nextPtr) { + Tk_ManageGeometry(slavePtr->tkwin, NULL, NULL); + Tk_UnmapWindow(slavePtr->tkwin); + slavePtr->masterPtr = NULL; + nextPtr = slavePtr->nextPtr; + slavePtr->nextPtr = NULL; } Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->gridHashTable, (char *) gridPtr->tkwin)); if (gridPtr->flags & REQUESTED_RELAYOUT) { - Tcl_CancelIdleCall(ArrangeGrid, (ClientData) gridPtr); + Tcl_CancelIdleCall(ArrangeGrid, gridPtr); } gridPtr->tkwin = NULL; - Tcl_EventuallyFree((ClientData) gridPtr, DestroyGrid); + Tcl_EventuallyFree(gridPtr, (Tcl_FreeProc *)DestroyGrid); } else if (eventPtr->type == MapNotify) { if ((gridPtr->slavePtr != NULL) && !(gridPtr->flags & REQUESTED_RELAYOUT)) { gridPtr->flags |= REQUESTED_RELAYOUT; - Tcl_DoWhenIdle(ArrangeGrid, (ClientData) gridPtr); + Tcl_DoWhenIdle(ArrangeGrid, gridPtr); } } else if (eventPtr->type == UnmapNotify) { - register Gridder *gridPtr2; + register Gridder *slavePtr; - for (gridPtr2 = gridPtr->slavePtr; gridPtr2 != NULL; - gridPtr2 = gridPtr2->nextPtr) { - Tk_UnmapWindow(gridPtr2->tkwin); + for (slavePtr = gridPtr->slavePtr; slavePtr != NULL; + slavePtr = slavePtr->nextPtr) { + Tk_UnmapWindow(slavePtr->tkwin); } } } @@ -2890,7 +2930,7 @@ ConfigureSlaves( Tk_Window tkwin, /* Any window in application containing * slaves. Used to look up slave names. */ int objc, /* Number of elements in argv. */ - Tcl_Obj *CONST objv[]) /* Argument objects: contains one or more + Tcl_Obj *const objv[]) /* Argument objects: contains one or more * window names followed by any number of * "option value" pairs. Caller must make sure * that there is at least one window name. */ @@ -2898,16 +2938,17 @@ ConfigureSlaves( Gridder *masterPtr = NULL; Gridder *slavePtr; Tk_Window other, slave, parent, ancestor; + TkWindow *master; int i, j, tmp; int numWindows; int width; int defaultRow = -1; int defaultColumn = 0; /* Default column number */ int defaultColumnSpan = 1; /* Default number of columns */ - char *lastWindow; /* Use this window to base current row/col + const char *lastWindow; /* Use this window to base current row/col * on */ int numSkip; /* Number of 'x' found */ - static CONST char *optionStrings[] = { + static const char *const optionStrings[] = { "-column", "-columnspan", "-in", "-ipadx", "-ipady", "-padx", "-pady", "-row", "-rowspan", "-sticky", NULL }; @@ -2915,7 +2956,7 @@ ConfigureSlaves( CONF_COLUMN, CONF_COLUMNSPAN, CONF_IN, CONF_IPADX, CONF_IPADY, CONF_PADX, CONF_PADY, CONF_ROW, CONF_ROWSPAN, CONF_STICKY }; int index; - char *string; + const char *string; char firstChar; int positionGiven; @@ -2967,24 +3008,27 @@ ConfigureSlaves( continue; } if (length > 1 && i == 0) { - Tcl_AppendResult(interp, "bad argument \"", string, - "\": must be name of window", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad argument \"%s\": must be name of window", string)); + Tcl_SetErrorCode(interp, "TK", "GRID", "BAD_PARAMETER", NULL); return TCL_ERROR; } if (length > 1 && firstChar == '-') { break; } if (length > 1) { - Tcl_AppendResult(interp, "unexpected parameter, \"", - string, "\", in configure list. ", - "Should be window name or option", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "unexpected parameter \"%s\" in configure list:" + " should be window name or option", string)); + Tcl_SetErrorCode(interp, "TK", "GRID", "BAD_PARAMETER", NULL); return TCL_ERROR; } if ((firstChar == REL_HORIZ) && ((numWindows == 0) || (prevChar == REL_SKIP) || (prevChar == REL_VERT))) { - Tcl_AppendResult(interp, - "Must specify window before shortcut '-'.", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "must specify window before shortcut '-'", -1)); + Tcl_SetErrorCode(interp, "TK", "GRID", "SHORTCUT_USAGE", NULL); return TCL_ERROR; } @@ -2993,14 +3037,18 @@ ConfigureSlaves( continue; } - Tcl_AppendResult(interp, "invalid window shortcut, \"", - string, "\" should be '-', 'x', or '^'", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "invalid window shortcut, \"%s\" should be '-', 'x', or '^'", + string)); + Tcl_SetErrorCode(interp, "TK", "GRID", "SHORTCUT_USAGE", NULL); return TCL_ERROR; } numWindows = i; if ((objc - numWindows) & 1) { - Tcl_AppendResult(interp, "extra option or option with no value", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "extra option or option with no value", -1)); + Tcl_SetErrorCode(interp, "TK", "GRID", "BAD_PARAMETER", NULL); return TCL_ERROR; } @@ -3012,8 +3060,8 @@ ConfigureSlaves( */ for (i = numWindows; i < objc; i += 2) { - if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings, "option", 0, - &index) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[i], optionStrings, + sizeof(char *), "option", 0, &index) != TCL_OK) { return TCL_ERROR; } if (index == CONF_IN) { @@ -3026,10 +3074,10 @@ ConfigureSlaves( } else if (index == CONF_ROW) { if (Tcl_GetIntFromObj(interp, objv[i+1], &tmp) != TCL_OK || tmp < 0) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "bad row value \"", - Tcl_GetString(objv[i+1]), "\": must be ", - "a non-negative integer", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad row value \"%s\": must be a non-negative integer", + Tcl_GetString(objv[i+1]))); + Tcl_SetErrorCode(interp, "TK", "VALUE", "POSITIVE_INT", NULL); return TCL_ERROR; } defaultRow = tmp; @@ -3037,7 +3085,8 @@ ConfigureSlaves( } /* - * If no -row is given, use the first unoccupied row of the master. + * If no -row is given, use the next row after the highest occupied row + * of the master. */ if (defaultRow < 0) { @@ -3079,7 +3128,7 @@ ConfigureSlaves( for (defaultColumnSpan = 1; j + defaultColumnSpan < numWindows; defaultColumnSpan++) { - char *string = Tcl_GetString(objv[j + defaultColumnSpan]); + const char *string = Tcl_GetString(objv[j + defaultColumnSpan]); if (*string != REL_HORIZ) { break; @@ -3091,8 +3140,10 @@ ConfigureSlaves( } if (Tk_TopWinHierarchy(slave)) { - Tcl_AppendResult(interp, "can't manage \"", Tcl_GetString(objv[j]), - "\": it's a top-level window", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't manage \"%s\": it's a top-level window", + Tcl_GetString(objv[j]))); + Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "TOPLEVEL", NULL); return TCL_ERROR; } slavePtr = GetGrid(slave); @@ -3113,15 +3164,16 @@ ConfigureSlaves( */ for (i = numWindows; i < objc; i += 2) { - Tcl_GetIndexFromObj(interp, objv[i], optionStrings, "option", 0, - &index); + Tcl_GetIndexFromObjStruct(interp, objv[i], optionStrings, + sizeof(char *), "option", 0, &index); switch ((enum options) index) { case CONF_COLUMN: if (Tcl_GetIntFromObj(NULL, objv[i+1], &tmp) != TCL_OK || tmp < 0) { - Tcl_AppendResult(interp, "bad column value \"", - Tcl_GetString(objv[i+1]), "\": must be ", - "a non-negative integer", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad column value \"%s\": must be a non-negative integer", + Tcl_GetString(objv[i+1]))); + Tcl_SetErrorCode(interp, "TK", "VALUE", "COLUMN", NULL); return TCL_ERROR; } if (SetSlaveColumn(interp, slavePtr, tmp, -1) != TCL_OK) { @@ -3131,9 +3183,10 @@ ConfigureSlaves( case CONF_COLUMNSPAN: if (Tcl_GetIntFromObj(NULL, objv[i+1], &tmp) != TCL_OK || tmp <= 0) { - Tcl_AppendResult(interp, "bad columnspan value \"", - Tcl_GetString(objv[i+1]), "\": must be ", - "a positive integer", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad columnspan value \"%s\": must be a positive integer", + Tcl_GetString(objv[i+1]))); + Tcl_SetErrorCode(interp, "TK", "VALUE", "SPAN", NULL); return TCL_ERROR; } if (SetSlaveColumn(interp, slavePtr, -1, tmp) != TCL_OK) { @@ -3146,8 +3199,9 @@ ConfigureSlaves( return TCL_ERROR; } if (other == slave) { - Tcl_SetResult(interp, "Window can't be managed in itself", - TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "window can't be managed in itself", -1)); + Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "SELF", NULL); return TCL_ERROR; } positionGiven = 1; @@ -3158,9 +3212,11 @@ ConfigureSlaves( int sticky = StringToSticky(Tcl_GetString(objv[i+1])); if (sticky == -1) { - Tcl_AppendResult(interp, "bad stickyness value \"", - Tcl_GetString(objv[i+1]), "\": must be ", - "a string containing n, e, s, and/or w", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad stickyness value \"%s\": must be" + " a string containing n, e, s, and/or w", + Tcl_GetString(objv[i+1]))); + Tcl_SetErrorCode(interp, "TK", "VALUE", "STICKY", NULL); return TCL_ERROR; } slavePtr->sticky = sticky; @@ -3169,22 +3225,24 @@ ConfigureSlaves( case CONF_IPADX: if ((Tk_GetPixelsFromObj(NULL, slave, objv[i+1], &tmp) != TCL_OK) || (tmp < 0)) { - Tcl_AppendResult(interp, "bad ipadx value \"", - Tcl_GetString(objv[i+1]), "\": must be ", - "positive screen distance", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad ipadx value \"%s\": must be positive screen distance", + Tcl_GetString(objv[i+1]))); + Tcl_SetErrorCode(interp, "TK", "VALUE", "INT_PAD", NULL); return TCL_ERROR; } - slavePtr->iPadX = tmp*2; + slavePtr->iPadX = tmp * 2; break; case CONF_IPADY: if ((Tk_GetPixelsFromObj(NULL, slave, objv[i+1], &tmp) != TCL_OK) || (tmp < 0)) { - Tcl_AppendResult(interp, "bad ipady value \"", - Tcl_GetString(objv[i+1]), "\": must be ", - "positive screen distance", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad ipady value \"%s\": must be positive screen distance", + Tcl_GetString(objv[i+1]))); + Tcl_SetErrorCode(interp, "TK", "VALUE", "INT_PAD", NULL); return TCL_ERROR; } - slavePtr->iPadY = tmp*2; + slavePtr->iPadY = tmp * 2; break; case CONF_PADX: if (TkParsePadAmount(interp, tkwin, objv[i+1], @@ -3201,9 +3259,10 @@ ConfigureSlaves( case CONF_ROW: if (Tcl_GetIntFromObj(NULL, objv[i+1], &tmp) != TCL_OK || tmp < 0) { - Tcl_AppendResult(interp, "bad row value \"", - Tcl_GetString(objv[i+1]), - "\": must be a non-negative integer", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad row value \"%s\": must be a non-negative integer", + Tcl_GetString(objv[i+1]))); + Tcl_SetErrorCode(interp, "TK", "VALUE", "COLUMN", NULL); return TCL_ERROR; } if (SetSlaveRow(interp, slavePtr, tmp, -1) != TCL_OK) { @@ -3213,9 +3272,10 @@ ConfigureSlaves( case CONF_ROWSPAN: if ((Tcl_GetIntFromObj(NULL, objv[i+1], &tmp) != TCL_OK) || tmp <= 0) { - Tcl_AppendResult(interp, "bad rowspan value \"", - Tcl_GetString(objv[i+1]), - "\": must be a positive integer", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad rowspan value \"%s\": must be a positive integer", + Tcl_GetString(objv[i+1]))); + Tcl_SetErrorCode(interp, "TK", "VALUE", "SPAN", NULL); return TCL_ERROR; } if (SetSlaveRow(interp, slavePtr, -1, tmp) != TCL_OK) { @@ -3257,6 +3317,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; } @@ -3280,26 +3343,45 @@ ConfigureSlaves( break; } if (Tk_TopWinHierarchy(ancestor)) { - Tcl_AppendResult(interp, "can't put ", Tcl_GetString(objv[j]), - " inside ", Tk_PathName(masterPtr->tkwin), NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't put %s inside %s", Tcl_GetString(objv[j]), + Tk_PathName(masterPtr->tkwin))); + Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "HIERARCHY", NULL); Unlink(slavePtr); return TCL_ERROR; } } /* - * Try to make sure our master isn't managed by us. + * Check for management loops. */ - if (masterPtr->masterPtr == slavePtr) { - Tcl_AppendResult(interp, "can't put ", Tcl_GetString(objv[j]), - " inside ", Tk_PathName(masterPtr->tkwin), - ", would cause management loop.", NULL); - Unlink(slavePtr); - return TCL_ERROR; - } + for (master = (TkWindow *)masterPtr->tkwin; master != NULL; + master = (TkWindow *)TkGetGeomMaster(master)) { + if (master == (TkWindow *)slave) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't put %s inside %s, would cause management loop", + Tcl_GetString(objv[j]), Tk_PathName(masterPtr->tkwin))); + Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "LOOP", NULL); + Unlink(slavePtr); + return TCL_ERROR; + } + } + if (masterPtr->tkwin != Tk_Parent(slave)) { + ((TkWindow *)slave)->maintainerPtr = (TkWindow *)masterPtr->tkwin; + } - Tk_ManageGeometry(slave, &gridMgrType, (ClientData) slavePtr); + Tk_ManageGeometry(slave, &gridMgrType, slavePtr); + + if (!(masterPtr->flags & DONT_PROPAGATE)) { + if (TkSetGeometryMaster(interp, masterPtr->tkwin, "grid") + != TCL_OK) { + Tk_ManageGeometry(slave, NULL, NULL); + Unlink(slavePtr); + return TCL_ERROR; + } + masterPtr->flags |= ALLOCED_MASTER; + } /* * Assign default position information. @@ -3332,7 +3414,7 @@ ConfigureSlaves( } if (!(masterPtr->flags & REQUESTED_RELAYOUT)) { masterPtr->flags |= REQUESTED_RELAYOUT; - Tcl_DoWhenIdle(ArrangeGrid, (ClientData) masterPtr); + Tcl_DoWhenIdle(ArrangeGrid, masterPtr); } } @@ -3344,8 +3426,8 @@ ConfigureSlaves( numSkip = 0; for (j = 0; j < numWindows; j++) { struct Gridder *otherPtr; - int match; /* Found a match for the ^ */ - int lastRow, lastColumn; /* Implied end of table. */ + int match; /* Found a match for the ^ */ + int lastRow, lastColumn; /* Implied end of table. */ string = Tcl_GetString(objv[j]); firstChar = string[0]; @@ -3362,7 +3444,9 @@ ConfigureSlaves( } if (masterPtr == NULL) { - Tcl_AppendResult(interp, "can't use '^', cant find master", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "can't use '^', cant find master", -1)); + Tcl_SetErrorCode(interp, "TK", "GRID", "SHORTCUT_USAGE", NULL); return TCL_ERROR; } @@ -3371,7 +3455,7 @@ ConfigureSlaves( */ for (width = 1; width + j < numWindows; width++) { - char *string = Tcl_GetString(objv[j+width]); + const char *string = Tcl_GetString(objv[j+width]); if (*string != REL_VERT) { break; @@ -3414,30 +3498,44 @@ ConfigureSlaves( } } if (!match) { - Tcl_AppendResult(interp, "can't find slave to extend with \"^\".", - NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "can't find slave to extend with \"^\"", -1)); + Tcl_SetErrorCode(interp, "TK", "GRID", "SHORTCUT_USAGE", NULL); return TCL_ERROR; } } if (masterPtr == NULL) { - Tcl_AppendResult(interp, "can't determine master window", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "can't determine master window", -1)); + Tcl_SetErrorCode(interp, "TK", "GRID", "SHORTCUT_USAGE", NULL); return TCL_ERROR; } SetGridSize(masterPtr); + + /* + * If we have emptied this master from slaves it means we are no longer + * handling it and should mark it as free. + */ + + if (masterPtr->slavePtr == NULL && masterPtr->flags & ALLOCED_MASTER) { + TkFreeGeometryMaster(masterPtr->tkwin, "grid"); + masterPtr->flags &= ~ALLOCED_MASTER; + } + return TCL_OK; } /* *---------------------------------------------------------------------- * - * StickyToString + * StickyToObj * * Converts the internal boolean combination of "sticky" bits onto a Tcl * list element containing zero or more of n, s, e, or w. * * Results: - * A string is placed into the "result" pointer. + * A new object is returned that holds the sticky representation. * * Side effects: * none. @@ -3445,29 +3543,26 @@ ConfigureSlaves( *---------------------------------------------------------------------- */ -static void -StickyToString( - int flags, /* The sticky flags. */ - char *result) /* Where to put the result. */ +static Tcl_Obj * +StickyToObj( + int flags) /* The sticky flags. */ { int count = 0; - if (flags&STICK_NORTH) { - result[count++] = 'n'; - } - if (flags&STICK_EAST) { - result[count++] = 'e'; + char buffer[4]; + + if (flags & STICK_NORTH) { + buffer[count++] = 'n'; } - if (flags&STICK_SOUTH) { - result[count++] = 's'; + if (flags & STICK_EAST) { + buffer[count++] = 'e'; } - if (flags&STICK_WEST) { - result[count++] = 'w'; + if (flags & STICK_SOUTH) { + buffer[count++] = 's'; } - if (count) { - result[count] = '\0'; - } else { - sprintf(result, "{}"); + if (flags & STICK_WEST) { + buffer[count++] = 'w'; } + return Tcl_NewStringObj(buffer, count); } /* @@ -3490,7 +3585,7 @@ StickyToString( static int StringToSticky( - char *string) + const char *string) { int sticky = 0; char c; diff --git a/generic/tkImage.c b/generic/tkImage.c index 8c70a2e..32e09c0 100644 --- a/generic/tkImage.c +++ b/generic/tkImage.c @@ -15,8 +15,8 @@ /* * Each call to Tk_GetImage returns a pointer to one of the following - * structures, which is used as a token by clients (widgets) that - * display images. + * structures, which is used as a token by clients (widgets) that display + * images. */ typedef struct Image { @@ -106,22 +106,22 @@ static void ImageTypeThreadExitProc( ClientData clientData) /* not used */ { - Tk_ImageType *freePtr; + Tk_ImageType *freePtr; ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); while (tsdPtr->oldImageTypeList != NULL) { freePtr = tsdPtr->oldImageTypeList; tsdPtr->oldImageTypeList = tsdPtr->oldImageTypeList->nextPtr; - ckfree((char *) freePtr); + ckfree(freePtr); } while (tsdPtr->imageTypeList != NULL) { freePtr = tsdPtr->imageTypeList; tsdPtr->imageTypeList = tsdPtr->imageTypeList->nextPtr; - ckfree((char *) freePtr); + ckfree(freePtr); } } - + /* *---------------------------------------------------------------------- * @@ -143,11 +143,12 @@ ImageTypeThreadExitProc( void Tk_CreateOldImageType( - Tk_ImageType *typePtr) /* Structure describing the type. All of the + const Tk_ImageType *typePtr) + /* Structure describing the type. All of the * fields except "nextPtr" must be filled in * by caller. */ { - Tk_ImageType *copyPtr; + Tk_ImageType *copyPtr; ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); @@ -155,7 +156,7 @@ Tk_CreateOldImageType( tsdPtr->initialized = 1; Tcl_CreateThreadExitHandler(ImageTypeThreadExitProc, NULL); } - copyPtr = (Tk_ImageType *) ckalloc(sizeof(Tk_ImageType)); + copyPtr = ckalloc(sizeof(Tk_ImageType)); *copyPtr = *typePtr; copyPtr->nextPtr = tsdPtr->oldImageTypeList; tsdPtr->oldImageTypeList = copyPtr; @@ -163,11 +164,12 @@ Tk_CreateOldImageType( void Tk_CreateImageType( - Tk_ImageType *typePtr) /* Structure describing the type. All of the + const Tk_ImageType *typePtr) + /* Structure describing the type. All of the * fields except "nextPtr" must be filled in * by caller. */ { - Tk_ImageType *copyPtr; + Tk_ImageType *copyPtr; ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); @@ -175,7 +177,7 @@ Tk_CreateImageType( tsdPtr->initialized = 1; Tcl_CreateThreadExitHandler(ImageTypeThreadExitProc, NULL); } - copyPtr = (Tk_ImageType *) ckalloc(sizeof(Tk_ImageType)); + copyPtr = ckalloc(sizeof(Tk_ImageType)); *copyPtr = *typePtr; copyPtr->nextPtr = tsdPtr->imageTypeList; tsdPtr->imageTypeList = copyPtr; @@ -203,9 +205,9 @@ Tk_ImageObjCmd( ClientData clientData, /* Main window associated with interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument strings. */ + Tcl_Obj *const objv[]) /* Argument strings. */ { - static CONST char *imageOptions[] = { + static const char *const imageOptions[] = { "create", "delete", "height", "inuse", "names", "type", "types", "width", NULL }; @@ -213,7 +215,7 @@ Tk_ImageObjCmd( IMAGE_CREATE, IMAGE_DELETE, IMAGE_HEIGHT, IMAGE_INUSE, IMAGE_NAMES, IMAGE_TYPE, IMAGE_TYPES, IMAGE_WIDTH }; - TkWindow *winPtr = (TkWindow *) clientData; + TkWindow *winPtr = clientData; int i, isNew, firstOption, index; Tk_ImageType *typePtr; ImageMaster *masterPtr; @@ -222,8 +224,9 @@ Tk_ImageObjCmd( Tcl_HashSearch search; char idString[16 + TCL_INTEGER_SPACE]; TkDisplay *dispPtr = winPtr->dispPtr; - char *arg, *name; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + const char *arg, *name; + Tcl_Obj *resultObj; + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (objc < 2) { @@ -231,16 +234,18 @@ Tk_ImageObjCmd( return TCL_ERROR; } - if (Tcl_GetIndexFromObj(interp, objv[1], imageOptions, "option", 0, - &index) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[1], imageOptions, + sizeof(char *), "option", 0, &index) != TCL_OK) { return TCL_ERROR; } switch ((enum options) index) { case IMAGE_CREATE: { Tcl_Obj **args; int oldimage = 0; + if (objc < 3) { - Tcl_WrongNumArgs(interp, 2, objv, "type ?name? ?options?"); + Tcl_WrongNumArgs(interp, 2, objv, + "type ?name? ?-option value ...?"); return TCL_ERROR; } @@ -267,8 +272,9 @@ Tk_ImageObjCmd( } } if (typePtr == NULL) { - Tcl_AppendResult(interp, "image type \"", arg, "\" doesn't exist", - NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "image type \"%s\" doesn't exist", arg)); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "IMAGE_TYPE", arg, NULL); return TCL_ERROR; } @@ -277,12 +283,11 @@ Tk_ImageObjCmd( */ if ((objc == 3) || (*(arg = Tcl_GetString(objv[3])) == '-')) { - Tcl_CmdInfo dummy; do { dispPtr->imageId++; sprintf(idString, "image%d", dispPtr->imageId); name = idString; - } while (Tcl_GetCommandInfo(interp, name, &dummy) != 0); + } while (Tcl_FindCommand(interp, name, NULL, 0) != NULL); firstOption = 3; } else { TkWindow *topWin; @@ -299,8 +304,10 @@ Tk_ImageObjCmd( topWin = (TkWindow *) TkToplevelWindowForCommand(interp, name); if (topWin != NULL && winPtr->mainPtr->winPtr == topWin) { - Tcl_AppendResult(interp, "images may not be named the ", - "same as the main window", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "images may not be named the same as the main window", + -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "SMASH_MAIN", NULL); return TCL_ERROR; } } @@ -311,7 +318,7 @@ Tk_ImageObjCmd( hPtr = Tcl_CreateHashEntry(&winPtr->mainPtr->imageTable, name, &isNew); if (isNew) { - masterPtr = (ImageMaster *) ckalloc(sizeof(ImageMaster)); + masterPtr = ckalloc(sizeof(ImageMaster)); masterPtr->typePtr = NULL; masterPtr->masterData = NULL; masterPtr->width = masterPtr->height = 1; @@ -320,7 +327,7 @@ Tk_ImageObjCmd( masterPtr->instancePtr = NULL; masterPtr->deleted = 0; masterPtr->winPtr = winPtr->mainPtr->winPtr; - Tcl_Preserve((ClientData) masterPtr->winPtr); + Tcl_Preserve(masterPtr->winPtr); Tcl_SetHashValue(hPtr, masterPtr); } else { /* @@ -328,17 +335,17 @@ Tk_ImageObjCmd( * from the master. */ - masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr); + masterPtr = Tcl_GetHashValue(hPtr); if (masterPtr->typePtr != NULL) { for (imagePtr = masterPtr->instancePtr; imagePtr != NULL; imagePtr = imagePtr->nextPtr) { - (*masterPtr->typePtr->freeProc)(imagePtr->instanceData, + masterPtr->typePtr->freeProc(imagePtr->instanceData, imagePtr->display); - (*imagePtr->changeProc)(imagePtr->widgetClientData, - 0, 0, masterPtr->width, masterPtr->height, + imagePtr->changeProc(imagePtr->widgetClientData, 0, 0, + masterPtr->width, masterPtr->height, masterPtr->width, masterPtr->height); } - (*masterPtr->typePtr->deleteProc)(masterPtr->masterData); + masterPtr->typePtr->deleteProc(masterPtr->masterData); masterPtr->typePtr = NULL; } masterPtr->deleted = 0; @@ -356,35 +363,34 @@ Tk_ImageObjCmd( if (oldimage) { int i; - args = (Tcl_Obj **) ckalloc((objc+1) * sizeof(char *)); + args = ckalloc((objc+1) * sizeof(char *)); for (i = 0; i < objc; i++) { args[i] = (Tcl_Obj *) Tcl_GetString(objv[i]); } args[objc] = NULL; } - Tcl_Preserve((ClientData) masterPtr); - if ((*typePtr->createProc)(interp, name, objc, args, typePtr, - (Tk_ImageMaster)masterPtr, &masterPtr->masterData) != TCL_OK) { + Tcl_Preserve(masterPtr); + if (typePtr->createProc(interp, name, objc, args, typePtr, + (Tk_ImageMaster)masterPtr, &masterPtr->masterData) != TCL_OK){ EventuallyDeleteImage(masterPtr, 0); - Tcl_Release((ClientData) masterPtr); + Tcl_Release(masterPtr); if (oldimage) { - ckfree((char *) args); + ckfree(args); } return TCL_ERROR; } - Tcl_Release((ClientData) masterPtr); + Tcl_Release(masterPtr); if (oldimage) { - ckfree((char *) args); + ckfree(args); } masterPtr->typePtr = typePtr; for (imagePtr = masterPtr->instancePtr; imagePtr != NULL; imagePtr = imagePtr->nextPtr) { - imagePtr->instanceData = (*typePtr->getProc)(imagePtr->tkwin, + imagePtr->instanceData = typePtr->getProc(imagePtr->tkwin, masterPtr->masterData); } - Tcl_SetResult(interp, - Tcl_GetHashKey(&winPtr->mainPtr->imageTable, hPtr), - TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + Tcl_GetHashKey(&winPtr->mainPtr->imageTable, hPtr), -1)); break; } case IMAGE_DELETE: @@ -394,7 +400,7 @@ Tk_ImageObjCmd( if (hPtr == NULL) { goto alreadyDeleted; } - masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr); + masterPtr = Tcl_GetHashValue(hPtr); if (masterPtr->deleted) { goto alreadyDeleted; } @@ -407,28 +413,34 @@ Tk_ImageObjCmd( return TCL_ERROR; } hPtr = Tcl_FirstHashEntry(&winPtr->mainPtr->imageTable, &search); + resultObj = Tcl_NewObj(); for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr); + masterPtr = Tcl_GetHashValue(hPtr); if (masterPtr->deleted) { continue; } - Tcl_AppendElement(interp, Tcl_GetHashKey( - &winPtr->mainPtr->imageTable, hPtr)); + Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj( + Tcl_GetHashKey(&winPtr->mainPtr->imageTable, hPtr), -1)); } + Tcl_SetObjResult(interp, resultObj); break; case IMAGE_TYPES: if (objc != 2) { Tcl_WrongNumArgs(interp, 2, objv, NULL); return TCL_ERROR; } + resultObj = Tcl_NewObj(); for (typePtr = tsdPtr->imageTypeList; typePtr != NULL; typePtr = typePtr->nextPtr) { - Tcl_AppendElement(interp, typePtr->name); + Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj( + typePtr->name, -1)); } for (typePtr = tsdPtr->oldImageTypeList; typePtr != NULL; typePtr = typePtr->nextPtr) { - Tcl_AppendElement(interp, typePtr->name); + Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj( + typePtr->name, -1)); } + Tcl_SetObjResult(interp, resultObj); break; case IMAGE_HEIGHT: @@ -451,7 +463,7 @@ Tk_ImageObjCmd( if (hPtr == NULL) { goto alreadyDeleted; } - masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr); + masterPtr = Tcl_GetHashValue(hPtr); if (masterPtr->deleted) { goto alreadyDeleted; } @@ -462,19 +474,20 @@ Tk_ImageObjCmd( switch ((enum options) index) { case IMAGE_HEIGHT: - Tcl_SetIntObj(Tcl_GetObjResult(interp), masterPtr->height); + Tcl_SetObjResult(interp, Tcl_NewIntObj(masterPtr->height)); break; case IMAGE_INUSE: - Tcl_SetBooleanObj(Tcl_GetObjResult(interp), - masterPtr->typePtr!=NULL && masterPtr->instancePtr!=NULL); + Tcl_SetObjResult(interp, Tcl_NewBooleanObj( + masterPtr->typePtr && masterPtr->instancePtr)); break; case IMAGE_TYPE: if (masterPtr->typePtr != NULL) { - Tcl_SetResult(interp, masterPtr->typePtr->name, TCL_STATIC); + Tcl_SetObjResult(interp, + Tcl_NewStringObj(masterPtr->typePtr->name, -1)); } break; case IMAGE_WIDTH: - Tcl_SetIntObj(Tcl_GetObjResult(interp), masterPtr->width); + Tcl_SetObjResult(interp, Tcl_NewIntObj(masterPtr->width)); break; default: Tcl_Panic("can't happen"); @@ -484,7 +497,8 @@ Tk_ImageObjCmd( return TCL_OK; alreadyDeleted: - Tcl_AppendResult(interp, "image \"", arg, "\" doesn't exist", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf("image \"%s\" doesn't exist",arg)); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "IMAGE", arg, NULL); return TCL_ERROR; } @@ -527,8 +541,8 @@ Tk_ImageChanged( masterPtr->height = imageHeight; for (imagePtr = masterPtr->instancePtr; imagePtr != NULL; imagePtr = imagePtr->nextPtr) { - (*imagePtr->changeProc)(imagePtr->widgetClientData, x, y, - width, height, imageWidth, imageHeight); + imagePtr->changeProc(imagePtr->widgetClientData, x, y, width, height, + imageWidth, imageHeight); } } @@ -549,7 +563,7 @@ Tk_ImageChanged( *---------------------------------------------------------------------- */ -CONST char * +const char * Tk_NameOfImage( Tk_ImageMaster imageMaster) /* Token for image. */ { @@ -589,7 +603,7 @@ Tk_GetImage( * be found. */ Tk_Window tkwin, /* Token for window in which image will be * used. */ - CONST char *name, /* Name of desired image. */ + const char *name, /* Name of desired image. */ Tk_ImageChangedProc *changeProc, /* Function to invoke when redisplay is needed * because image's pixels or size changed. */ @@ -603,19 +617,19 @@ Tk_GetImage( if (hPtr == NULL) { goto noSuchImage; } - masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr); + masterPtr = Tcl_GetHashValue(hPtr); if (masterPtr->typePtr == NULL) { goto noSuchImage; } if (masterPtr->deleted) { goto noSuchImage; } - imagePtr = (Image *) ckalloc(sizeof(Image)); + imagePtr = ckalloc(sizeof(Image)); imagePtr->tkwin = tkwin; imagePtr->display = Tk_Display(tkwin); imagePtr->masterPtr = masterPtr; imagePtr->instanceData = - (*masterPtr->typePtr->getProc)(tkwin, masterPtr->masterData); + masterPtr->typePtr->getProc(tkwin, masterPtr->masterData); imagePtr->changeProc = changeProc; imagePtr->widgetClientData = clientData; imagePtr->nextPtr = masterPtr->instancePtr; @@ -624,7 +638,9 @@ Tk_GetImage( noSuchImage: if (interp) { - Tcl_AppendResult(interp, "image \"", name, "\" doesn't exist", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "image \"%s\" doesn't exist", name)); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "IMAGE", name, NULL); } return NULL; } @@ -661,7 +677,7 @@ Tk_FreeImage( */ if (masterPtr->typePtr != NULL) { - (*masterPtr->typePtr->freeProc)(imagePtr->instanceData, + masterPtr->typePtr->freeProc(imagePtr->instanceData, imagePtr->display); } prevPtr = masterPtr->instancePtr; @@ -673,7 +689,7 @@ Tk_FreeImage( } prevPtr->nextPtr = imagePtr->nextPtr; } - ckfree((char *) imagePtr); + ckfree(imagePtr); /* * If there are no more instances left for the master, and if the master @@ -684,8 +700,8 @@ Tk_FreeImage( if (masterPtr->hPtr != NULL) { Tcl_DeleteHashEntry(masterPtr->hPtr); } - Tcl_Release((ClientData) masterPtr->winPtr); - ckfree((char *) masterPtr); + Tcl_Release(masterPtr->winPtr); + ckfree(masterPtr); } } @@ -739,9 +755,9 @@ Tk_PostscriptImage( */ if (imagePtr->masterPtr->typePtr->postscriptProc != NULL) { - return (*imagePtr->masterPtr->typePtr->postscriptProc)( - imagePtr->masterPtr->masterData, interp, tkwin, psinfo, - x, y, width, height, prepass); + return imagePtr->masterPtr->typePtr->postscriptProc( + imagePtr->masterPtr->masterData, interp, tkwin, psinfo, + x, y, width, height, prepass); } if (prepass) { @@ -760,15 +776,15 @@ Tk_PostscriptImage( gcValues.foreground = WhitePixelOfScreen(Tk_Screen(tkwin)); newGC = Tk_GetGC(tkwin, GCForeground, &gcValues); if (newGC != NULL) { - XFillRectangle(Tk_Display(tkwin), pmap, newGC, - 0, 0, (unsigned int)width, (unsigned int)height); + XFillRectangle(Tk_Display(tkwin), pmap, newGC, 0, 0, + (unsigned) width, (unsigned) height); Tk_FreeGC(Tk_Display(tkwin), newGC); } Tk_RedrawImage(image, x, y, width, height, pmap, 0, 0); ximage = XGetImage(Tk_Display(tkwin), pmap, 0, 0, - (unsigned int)width, (unsigned int)height, AllPlanes, ZPixmap); + (unsigned) width, (unsigned) height, AllPlanes, ZPixmap); Tk_FreePixmap(Tk_Display(tkwin), pmap); @@ -849,9 +865,9 @@ Tk_RedrawImage( if ((imageY + height) > imagePtr->masterPtr->height) { height = imagePtr->masterPtr->height - imageY; } - (*imagePtr->masterPtr->typePtr->displayProc)( - imagePtr->instanceData, imagePtr->display, drawable, - imageX, imageY, width, height, drawableX, drawableY); + imagePtr->masterPtr->typePtr->displayProc(imagePtr->instanceData, + imagePtr->display, drawable, imageX, imageY, width, height, + drawableX, drawableY); } /* @@ -904,7 +920,7 @@ void Tk_DeleteImage( Tcl_Interp *interp, /* Interpreter in which the image was * created. */ - CONST char *name) /* Name of image. */ + const char *name) /* Name of image. */ { Tcl_HashEntry *hPtr; TkWindow *winPtr; @@ -917,7 +933,7 @@ Tk_DeleteImage( if (hPtr == NULL) { return; } - DeleteImage((ImageMaster *)Tcl_GetHashValue(hPtr)); + DeleteImage(Tcl_GetHashValue(hPtr)); } /* @@ -950,20 +966,19 @@ DeleteImage( if (typePtr != NULL) { for (imagePtr = masterPtr->instancePtr; imagePtr != NULL; imagePtr = imagePtr->nextPtr) { - (*typePtr->freeProc)(imagePtr->instanceData, - imagePtr->display); - (*imagePtr->changeProc)(imagePtr->widgetClientData, 0, 0, + typePtr->freeProc(imagePtr->instanceData, imagePtr->display); + imagePtr->changeProc(imagePtr->widgetClientData, 0, 0, masterPtr->width, masterPtr->height, masterPtr->width, masterPtr->height); } - (*typePtr->deleteProc)(masterPtr->masterData); + typePtr->deleteProc(masterPtr->masterData); } if (masterPtr->instancePtr == NULL) { if (masterPtr->hPtr != NULL) { Tcl_DeleteHashEntry(masterPtr->hPtr); } - Tcl_Release((ClientData) masterPtr->winPtr); - ckfree((char *) masterPtr); + Tcl_Release(masterPtr->winPtr); + ckfree(masterPtr); } else { masterPtr->deleted = 1; } @@ -998,8 +1013,7 @@ EventuallyDeleteImage( } if (!masterPtr->deleted) { masterPtr->deleted = 1; - Tcl_EventuallyFree((ClientData) masterPtr, - (Tcl_FreeProc *)DeleteImage); + Tcl_EventuallyFree(masterPtr, (Tcl_FreeProc *) DeleteImage); } } @@ -1031,7 +1045,7 @@ TkDeleteAllImages( for (hPtr = Tcl_FirstHashEntry(&mainPtr->imageTable, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - EventuallyDeleteImage((ImageMaster *) Tcl_GetHashValue(hPtr), 1); + EventuallyDeleteImage(Tcl_GetHashValue(hPtr), 1); } Tcl_DeleteHashTable(&mainPtr->imageTable); } @@ -1060,21 +1074,21 @@ ClientData Tk_GetImageMasterData( Tcl_Interp *interp, /* Interpreter in which the image was * created. */ - CONST char *name, /* Name of image. */ - Tk_ImageType **typePtrPtr) /* Points to location to fill in with pointer + const char *name, /* Name of image. */ + const Tk_ImageType **typePtrPtr) + /* Points to location to fill in with pointer * to type information for image. */ { + TkWindow *winPtr = (TkWindow *) Tk_MainWindow(interp); Tcl_HashEntry *hPtr; - TkWindow *winPtr; ImageMaster *masterPtr; - winPtr = (TkWindow *) Tk_MainWindow(interp); hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, name); if (hPtr == NULL) { *typePtrPtr = NULL; return NULL; } - masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr); + masterPtr = Tcl_GetHashValue(hPtr); if (masterPtr->deleted) { *typePtrPtr = NULL; return NULL; diff --git a/generic/tkImgBmap.c b/generic/tkImgBmap.c index b5bf49a..f4ee407 100644 --- a/generic/tkImgBmap.c +++ b/generic/tkImgBmap.c @@ -75,8 +75,8 @@ typedef struct BitmapInstance { static int GetByte(Tcl_Channel chan); static int ImgBmapCreate(Tcl_Interp *interp, - char *name, int argc, Tcl_Obj *CONST objv[], - Tk_ImageType *typePtr, Tk_ImageMaster master, + const char *name, int argc, Tcl_Obj *const objv[], + const Tk_ImageType *typePtr, Tk_ImageMaster master, ClientData *clientDataPtr); static ClientData ImgBmapGet(Tk_Window tkwin, ClientData clientData); static void ImgBmapDisplay(ClientData clientData, @@ -98,27 +98,28 @@ Tk_ImageType tkBitmapImageType = { ImgBmapFree, /* freeProc */ ImgBmapDelete, /* deleteProc */ ImgBmapPostscript, /* postscriptProc */ - NULL /* nextPtr */ + NULL, /* nextPtr */ + NULL }; /* * Information used for parsing configuration specs: */ -static Tk_ConfigSpec configSpecs[] = { +static const Tk_ConfigSpec configSpecs[] = { {TK_CONFIG_UID, "-background", NULL, NULL, - "", Tk_Offset(BitmapMaster, bgUid), 0}, + "", Tk_Offset(BitmapMaster, bgUid), 0, NULL}, {TK_CONFIG_STRING, "-data", NULL, NULL, - NULL, Tk_Offset(BitmapMaster, dataString), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(BitmapMaster, dataString), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_STRING, "-file", NULL, NULL, - NULL, Tk_Offset(BitmapMaster, fileString), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(BitmapMaster, fileString), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_UID, "-foreground", NULL, NULL, - "#000000", Tk_Offset(BitmapMaster, fgUid), 0}, + "#000000", Tk_Offset(BitmapMaster, fgUid), 0, NULL}, {TK_CONFIG_STRING, "-maskdata", NULL, NULL, - NULL, Tk_Offset(BitmapMaster, maskDataString), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(BitmapMaster, maskDataString), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_STRING, "-maskfile", NULL, NULL, - NULL, Tk_Offset(BitmapMaster, maskFileString), TK_CONFIG_NULL_OK}, - {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} + NULL, Tk_Offset(BitmapMaster, maskFileString), TK_CONFIG_NULL_OK, NULL}, + {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL} }; /* @@ -129,7 +130,7 @@ static Tk_ConfigSpec configSpecs[] = { #define MAX_WORD_LENGTH 100 typedef struct ParseInfo { - char *string; /* Next character of string data for bitmap, + const char *string; /* Next character of string data for bitmap, * or NULL if bitmap is being read from * file. */ Tcl_Channel chan; /* File containing bitmap data, or NULL if no @@ -145,11 +146,11 @@ typedef struct ParseInfo { */ static int ImgBmapCmd(ClientData clientData, Tcl_Interp *interp, - int argc, Tcl_Obj *CONST objv[]); + int argc, Tcl_Obj *const objv[]); static void ImgBmapCmdDeletedProc(ClientData clientData); static void ImgBmapConfigureInstance(BitmapInstance *instancePtr); static int ImgBmapConfigureMaster(BitmapMaster *masterPtr, - int argc, Tcl_Obj *CONST objv[], int flags); + int argc, Tcl_Obj *const objv[], int flags); static int NextBitmapWord(ParseInfo *parseInfoPtr); /* @@ -173,23 +174,22 @@ static int ImgBmapCreate( Tcl_Interp *interp, /* Interpreter for application containing * image. */ - char *name, /* Name to use for image. */ + const char *name, /* Name to use for image. */ int argc, /* Number of arguments. */ - Tcl_Obj *CONST argv[], /* Argument objects for options (doesn't + Tcl_Obj *const argv[], /* Argument objects for options (doesn't * include image name or type). */ - Tk_ImageType *typePtr, /* Pointer to our type record (not used). */ + const Tk_ImageType *typePtr,/* Pointer to our type record (not used). */ Tk_ImageMaster master, /* Token for image, to be used by us in later * callbacks. */ ClientData *clientDataPtr) /* Store manager's token for image here; it * will be returned in later callbacks. */ { - BitmapMaster *masterPtr; + BitmapMaster *masterPtr = ckalloc(sizeof(BitmapMaster)); - masterPtr = (BitmapMaster *) ckalloc(sizeof(BitmapMaster)); masterPtr->tkMaster = master; masterPtr->interp = interp; masterPtr->imageCmd = Tcl_CreateObjCommand(interp, name, ImgBmapCmd, - (ClientData) masterPtr, ImgBmapCmdDeletedProc); + masterPtr, ImgBmapCmdDeletedProc); masterPtr->width = masterPtr->height = 0; masterPtr->data = NULL; masterPtr->maskData = NULL; @@ -201,10 +201,10 @@ ImgBmapCreate( masterPtr->maskDataString = NULL; masterPtr->instancePtr = NULL; if (ImgBmapConfigureMaster(masterPtr, argc, argv, 0) != TCL_OK) { - ImgBmapDelete((ClientData) masterPtr); + ImgBmapDelete(masterPtr); return TCL_ERROR; } - *clientDataPtr = (ClientData) masterPtr; + *clientDataPtr = masterPtr; return TCL_OK; } @@ -233,26 +233,25 @@ ImgBmapConfigureMaster( BitmapMaster *masterPtr, /* Pointer to data structure describing * overall bitmap image to (reconfigure). */ int objc, /* Number of entries in objv. */ - Tcl_Obj *CONST objv[], /* Pairs of configuration options for image. */ + Tcl_Obj *const objv[], /* Pairs of configuration options for image. */ int flags) /* Flags to pass to Tk_ConfigureWidget, such * as TK_CONFIG_ARGV_ONLY. */ { BitmapInstance *instancePtr; int maskWidth, maskHeight, dummy1, dummy2; + const char **argv = ckalloc((objc+1) * sizeof(char *)); - CONST char **argv = (CONST char **) ckalloc((objc+1) * sizeof(char *)); for (dummy1 = 0; dummy1 < objc; dummy1++) { - argv[dummy1]=Tcl_GetString(objv[dummy1]); + argv[dummy1] = Tcl_GetString(objv[dummy1]); } argv[objc] = NULL; if (Tk_ConfigureWidget(masterPtr->interp, Tk_MainWindow(masterPtr->interp), - configSpecs, objc, argv, (char *) masterPtr, flags) - != TCL_OK) { - ckfree((char *) argv); + configSpecs, objc, argv, (char *) masterPtr, flags) != TCL_OK) { + ckfree(argv); return TCL_ERROR; } - ckfree((char *) argv); + ckfree(argv); /* * Parse the bitmap and/or mask to create binary data. Make sure that the @@ -278,8 +277,10 @@ ImgBmapConfigureMaster( if ((masterPtr->maskFileString != NULL) || (masterPtr->maskDataString != NULL)) { if (masterPtr->data == NULL) { - Tcl_SetResult(masterPtr->interp, "can't have mask without bitmap", - TCL_STATIC); + Tcl_SetObjResult(masterPtr->interp, Tcl_NewStringObj( + "can't have mask without bitmap", -1)); + Tcl_SetErrorCode(masterPtr->interp, "TK", "IMAGE", "BITMAP", + "NO_BITMAP", NULL); return TCL_ERROR; } masterPtr->maskData = TkGetBitmapData(masterPtr->interp, @@ -292,8 +293,10 @@ ImgBmapConfigureMaster( || (maskHeight != masterPtr->height)) { ckfree(masterPtr->maskData); masterPtr->maskData = NULL; - Tcl_SetResult(masterPtr->interp, - "bitmap and mask have different sizes", TCL_STATIC); + Tcl_SetObjResult(masterPtr->interp, Tcl_NewStringObj( + "bitmap and mask have different sizes", -1)); + Tcl_SetErrorCode(masterPtr->interp, "TK", "IMAGE", "BITMAP", + "MASK_SIZE", NULL); return TCL_ERROR; } } @@ -327,7 +330,7 @@ ImgBmapConfigureMaster( * None. * * Side effects: - * Generates errors via Tcl_BackgroundError if there are problems in + * Generates errors via Tcl_BackgroundException if there are problems in * setting up the instance. * *---------------------------------------------------------------------- @@ -442,10 +445,10 @@ ImgBmapConfigureInstance( Tk_FreeGC(Tk_Display(instancePtr->tkwin), instancePtr->gc); } instancePtr->gc = NULL; - Tcl_AddErrorInfo(masterPtr->interp, "\n (while configuring image \""); - Tcl_AddErrorInfo(masterPtr->interp, Tk_NameOfImage(masterPtr->tkMaster)); - Tcl_AddErrorInfo(masterPtr->interp, "\")"); - Tcl_BackgroundError(masterPtr->interp); + Tcl_AppendObjToErrorInfo(masterPtr->interp, Tcl_ObjPrintf( + "\n (while configuring image \"%s\")", Tk_NameOfImage( + masterPtr->tkMaster))); + Tcl_BackgroundException(masterPtr->interp, TCL_ERROR); } /* @@ -473,8 +476,8 @@ ImgBmapConfigureInstance( char * TkGetBitmapData( Tcl_Interp *interp, /* For reporting errors, or NULL. */ - char *string, /* String describing bitmap. May be NULL. */ - char *fileName, /* Name of file containing bitmap description. + const char *string, /* String describing bitmap. May be NULL. */ + const char *fileName, /* Name of file containing bitmap description. * Used only if string is NULL. Must not be * NULL if string is NULL. */ int *widthPtr, int *heightPtr, @@ -482,7 +485,7 @@ TkGetBitmapData( int *hotXPtr, int *hotYPtr) /* Position of hot spot or -1,-1. */ { int width, height, numBytes, hotX, hotY; - CONST char *expandedFileName; + const char *expandedFileName; char *p, *end; ParseInfo pi; char *data = NULL; @@ -491,8 +494,10 @@ TkGetBitmapData( pi.string = string; if (string == NULL) { if ((interp != NULL) && Tcl_IsSafe(interp)) { - Tcl_AppendResult(interp, "can't get bitmap data from a file in a", - " safe interpreter", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "can't get bitmap data from a file in a safe interpreter", + -1)); + Tcl_SetErrorCode(interp, "TK", "SAFE", "BITMAP_FILE", NULL); return NULL; } expandedFileName = Tcl_TranslateFileName(interp, fileName, &buffer); @@ -504,8 +509,9 @@ TkGetBitmapData( if (pi.chan == NULL) { if (interp != NULL) { Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "couldn't read bitmap file \"", - fileName, "\": ", Tcl_PosixError(interp), NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "couldn't read bitmap file \"%s\": %s", + fileName, Tcl_PosixError(interp))); } return NULL; } @@ -594,8 +600,11 @@ TkGetBitmapData( } } else if ((pi.word[0] == '{') && (pi.word[1] == 0)) { if (interp != NULL) { - Tcl_AppendResult(interp, "format error in bitmap data; ", - "looks like it's an obsolete X10 bitmap file", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "format error in bitmap data; looks like it's an" + " obsolete X10 bitmap file", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "BITMAP", "OBSOLETE", + NULL); } goto errorCleanup; } @@ -611,7 +620,7 @@ TkGetBitmapData( goto error; } numBytes = ((width+7)/8) * height; - data = (char *) ckalloc((unsigned) numBytes); + data = ckalloc(numBytes); for (p = data; numBytes > 0; p++, numBytes--) { if (NextBitmapWord(&pi) != TCL_OK) { goto error; @@ -637,7 +646,9 @@ TkGetBitmapData( error: if (interp != NULL) { - Tcl_SetResult(interp, "format error in bitmap data", TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "format error in bitmap data", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "BITMAP", "FORMAT", NULL); } errorCleanup: @@ -674,7 +685,8 @@ NextBitmapWord( ParseInfo *parseInfoPtr) /* Describes what we're reading and where we * are in it. */ { - char *src, *dst; + const char *src; + char *dst; int c; parseInfoPtr->wordLength = 0; @@ -742,18 +754,18 @@ ImgBmapCmd( ClientData clientData, /* Information about the image master. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { - static CONST char *bmapOptions[] = {"cget", "configure", NULL}; - BitmapMaster *masterPtr = (BitmapMaster *) clientData; + static const char *const bmapOptions[] = {"cget", "configure", NULL}; + BitmapMaster *masterPtr = clientData; int index; if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?"); + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); return TCL_ERROR; } - if (Tcl_GetIndexFromObj(interp, objv[1], bmapOptions, "option", 0, - &index) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[1], bmapOptions, + sizeof(char *), "option", 0, &index) != TCL_OK) { return TCL_ERROR; } switch (index) { @@ -807,7 +819,7 @@ ImgBmapGet( ClientData masterData) /* Pointer to our master structure for the * image. */ { - BitmapMaster *masterPtr = (BitmapMaster *) masterData; + BitmapMaster *masterPtr = masterData; BitmapInstance *instancePtr; /* @@ -819,7 +831,7 @@ ImgBmapGet( instancePtr = instancePtr->nextPtr) { if (instancePtr->tkwin == tkwin) { instancePtr->refCount++; - return (ClientData) instancePtr; + return instancePtr; } } @@ -828,7 +840,7 @@ ImgBmapGet( * the image. */ - instancePtr = (BitmapInstance *) ckalloc(sizeof(BitmapInstance)); + instancePtr = ckalloc(sizeof(BitmapInstance)); instancePtr->refCount = 1; instancePtr->masterPtr = masterPtr; instancePtr->tkwin = tkwin; @@ -850,7 +862,7 @@ ImgBmapGet( masterPtr->height); } - return (ClientData) instancePtr; + return instancePtr; } /* @@ -882,7 +894,7 @@ ImgBmapDisplay( /* Coordinates within drawable that correspond * to imageX and imageY. */ { - BitmapInstance *instancePtr = (BitmapInstance *) clientData; + BitmapInstance *instancePtr = clientData; int masking; /* @@ -936,7 +948,7 @@ ImgBmapFree( * instance to be displayed. */ Display *display) /* Display containing window that used image. */ { - BitmapInstance *instancePtr = (BitmapInstance *) clientData; + BitmapInstance *instancePtr = clientData; BitmapInstance *prevPtr; instancePtr->refCount--; @@ -973,7 +985,7 @@ ImgBmapFree( } prevPtr->nextPtr = instancePtr->nextPtr; } - ckfree((char *) instancePtr); + ckfree(instancePtr); } /* @@ -998,7 +1010,7 @@ ImgBmapDelete( ClientData masterData) /* Pointer to BitmapMaster structure for * image. Must not have any more instances. */ { - BitmapMaster *masterPtr = (BitmapMaster *) masterData; + BitmapMaster *masterPtr = masterData; if (masterPtr->instancePtr != NULL) { Tcl_Panic("tried to delete bitmap image when instances still exist"); @@ -1014,7 +1026,7 @@ ImgBmapDelete( ckfree(masterPtr->maskData); } Tk_FreeOptions(configSpecs, (char *) masterPtr, NULL, 0); - ckfree((char *) masterPtr); + ckfree(masterPtr); } /* @@ -1039,7 +1051,7 @@ ImgBmapCmdDeletedProc( ClientData clientData) /* Pointer to BitmapMaster structure for * image. */ { - BitmapMaster *masterPtr = (BitmapMaster *) clientData; + BitmapMaster *masterPtr = clientData; masterPtr->imageCmd = NULL; if (masterPtr->tkMaster != NULL) { @@ -1077,7 +1089,6 @@ GetByte( return buffer; } } - /* *---------------------------------------------------------------------- @@ -1100,28 +1111,22 @@ GetByte( * 3. The postscript coordinate system has been scaled so that the * entire bitmap is one unit squared. * - * Some postscript implementations cannot handle bitmap strings longer - * than about 60k characters. If the bitmap data is that big or bigger, - * then we render it by splitting it into several smaller bitmaps. - * * Results: - * Returns TCL_OK on success. Returns TCL_ERROR and leaves and error - * message in interp->result if there is a problem. + * None. * * Side effects: - * Postscript code is appended to interp->result. + * Postscript code is appended to psObj. * *---------------------------------------------------------------------- */ -static int +static void ImgBmapPsImagemask( - Tcl_Interp *interp, /* Append postscript to this interpreter */ + Tcl_Obj *psObj, /* Append postscript to this buffer. */ int width, int height, /* Width and height of the bitmap in pixels */ - char *data) /* Data for the bitmap */ + char *data) /* Data for the bitmap. */ { int i, j, nBytePerRow; - char buffer[200]; /* * The bit order of bitmaps in Tk is the opposite of the bit order that @@ -1150,29 +1155,20 @@ ImgBmapPsImagemask( 15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223, 63, 191, 127, 255, }; - if (width*height > 60000) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "unable to generate postscript for bitmaps " - "larger than 60000 pixels", NULL); - return TCL_ERROR; - } - - sprintf(buffer, "0 0 moveto %d %d true [%d 0 0 %d 0 %d] {<\n", + Tcl_AppendPrintfToObj(psObj, + "0 0 moveto %d %d true [%d 0 0 %d 0 %d] {<\n", width, height, width, -height, height); - Tcl_AppendResult(interp, buffer, NULL); - nBytePerRow = (width+7)/8; - for(i=0; i<height; i++){ - for(j=0; j<nBytePerRow; j++){ - sprintf(buffer, " %02x", + nBytePerRow = (width + 7) / 8; + for (i=0; i<height; i++) { + for (j=0; j<nBytePerRow; j++) { + Tcl_AppendPrintfToObj(psObj, " %02x", bit_reverse[0xff & data[i*nBytePerRow + j]]); - Tcl_AppendResult(interp, buffer, NULL); } - Tcl_AppendResult(interp, "\n", NULL); + Tcl_AppendToObj(psObj, "\n", -1); } - Tcl_AppendResult(interp, ">} imagemask \n", NULL); - return TCL_OK; + Tcl_AppendToObj(psObj, ">} imagemask \n", -1); } /* @@ -1183,7 +1179,6 @@ ImgBmapPsImagemask( * This procedure generates postscript for rendering a bitmap image. * * Results: - * On success, this routine writes postscript code into interp->result * and returns TCL_OK TCL_ERROR is returned and an error message is left * in interp->result if anything goes wrong. @@ -1203,8 +1198,9 @@ ImgBmapPostscript( int x, int y, int width, int height, int prepass) { - BitmapMaster *masterPtr = (BitmapMaster *) clientData; - char buffer[200]; + BitmapMaster *masterPtr = clientData; + Tcl_InterpState interpState; + Tcl_Obj *psObj; if (prepass) { return TCL_OK; @@ -1214,11 +1210,32 @@ ImgBmapPostscript( * There is nothing to do for bitmaps with zero width or height. */ - if (width<=0 || height<=0 || masterPtr->width<=0 || masterPtr->height<= 0){ + if (width<=0 || height<=0 || masterPtr->width<=0 || masterPtr->height<=0){ return TCL_OK; } /* + * Some postscript implementations cannot handle bitmap strings longer + * than about 60k characters. If the bitmap data is that big or bigger, + * we bail out. + */ + + if (masterPtr->width*masterPtr->height > 60000) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "unable to generate postscript for bitmaps larger than 60000" + " pixels", -1)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "PS", "MEMLIMIT", NULL); + return TCL_ERROR; + } + + /* + * Make our working space. + */ + + psObj = Tcl_NewObj(); + interpState = Tcl_SaveInterpState(interp, TCL_OK); + + /* * Translate the origin of the coordinate system to be the lower-left * corner of the bitmap and adjust the scale of the coordinate system so * that entire bitmap covers one square unit of the page. The calling @@ -1227,13 +1244,11 @@ ImgBmapPostscript( * necessary here. */ - if (x!=0 || y!=0) { - sprintf(buffer, "%d %d moveto\n", x, y); - Tcl_AppendResult(interp, buffer, NULL); + if (x != 0 || y != 0) { + Tcl_AppendPrintfToObj(psObj, "%d %d moveto\n", x, y); } - if (width!=1 || height!=1) { - sprintf(buffer, "%d %d scale\n", width, height); - Tcl_AppendResult(interp, buffer, NULL); + if (width != 1 || height != 1) { + Tcl_AppendPrintfToObj(psObj, "%d %d scale\n", width, height); } /* @@ -1249,16 +1264,19 @@ ImgBmapPostscript( TkParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), masterPtr->bgUid, &color); + Tcl_ResetResult(interp); if (Tk_PostscriptColor(interp, psinfo, &color) != TCL_OK) { - return TCL_ERROR; + goto error; } + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); + if (masterPtr->maskData == NULL) { - Tcl_AppendResult(interp, - "0 0 moveto 1 0 rlineto 0 1 rlineto -1 0 rlineto ", - "closepath fill\n", NULL); - } else if (ImgBmapPsImagemask(interp, masterPtr->width, - masterPtr->height, masterPtr->maskData) != TCL_OK) { - return TCL_ERROR; + Tcl_AppendToObj(psObj, + "0 0 moveto 1 0 rlineto 0 1 rlineto -1 0 rlineto " + "closepath fill\n", -1); + } else { + ImgBmapPsImagemask(psObj, masterPtr->width, masterPtr->height, + masterPtr->maskData); } } @@ -1271,15 +1289,29 @@ ImgBmapPostscript( TkParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), masterPtr->fgUid, &color); + Tcl_ResetResult(interp); if (Tk_PostscriptColor(interp, psinfo, &color) != TCL_OK) { - return TCL_ERROR; - } - if (ImgBmapPsImagemask(interp, masterPtr->width, masterPtr->height, - masterPtr->data) != TCL_OK) { - return TCL_ERROR; + goto error; } + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); + + ImgBmapPsImagemask(psObj, masterPtr->width, masterPtr->height, + masterPtr->data); } + + /* + * Plug the accumulated postscript back into the result. + */ + + (void) Tcl_RestoreInterpState(interp, interpState); + Tcl_AppendObjToObj(Tcl_GetObjResult(interp), psObj); + Tcl_DecrRefCount(psObj); return TCL_OK; + + error: + Tcl_DiscardInterpState(interpState); + Tcl_DecrRefCount(psObj); + return TCL_ERROR; } /* diff --git a/generic/tkImgGIF.c b/generic/tkImgGIF.c index e7f4582..0c32047 100644 --- a/generic/tkImgGIF.c +++ b/generic/tkImgGIF.c @@ -11,7 +11,7 @@ * Copyright (c) Reed Wade (wade@cs.utk.edu), University of Tennessee * Copyright (c) 1995-1997 Sun Microsystems, Inc. * Copyright (c) 1997 Australian National University - * Copyright (c) 2005 Donal K. Fellows + * Copyright (c) 2005-2010 Donal K. Fellows * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. @@ -28,9 +28,6 @@ * | notice appear in supporting documentation. This software is | * | provided "as is" without express or implied warranty. | * +--------------------------------------------------------------------+ - * - * This file also contains code from miGIF. See lower down in file for the - * applicable copyright notice for that portion. */ #include "tkInt.h" @@ -110,6 +107,14 @@ typedef struct { } GIFImageConfig; /* + * Type of a function used to do the writing to a file or buffer when + * serializing in the GIF format. + */ + +typedef int (WriteBytesFunc) (ClientData clientData, const char *bytes, + int byteCount); + +/* * The format record for the GIF file format: */ @@ -128,8 +133,11 @@ static int StringReadGIF(Tcl_Interp *interp, Tcl_Obj *dataObj, int srcX, int srcY); static int FileWriteGIF(Tcl_Interp *interp, const char *filename, Tcl_Obj *format, Tk_PhotoImageBlock *blockPtr); -static int CommonWriteGIF(Tcl_Interp *interp, Tcl_Channel handle, - Tcl_Obj *format, Tk_PhotoImageBlock *blockPtr); +static int StringWriteGIF(Tcl_Interp *interp, Tcl_Obj *format, + Tk_PhotoImageBlock *blockPtr); +static int CommonWriteGIF(Tcl_Interp *interp, ClientData clientData, + WriteBytesFunc *writeProc, Tcl_Obj *format, + Tk_PhotoImageBlock *blockPtr); Tk_PhotoImageFormat tkImgFmtGIF = { "gif", /* name */ @@ -138,7 +146,8 @@ Tk_PhotoImageFormat tkImgFmtGIF = { FileReadGIF, /* fileReadProc */ StringReadGIF, /* stringReadProc */ FileWriteGIF, /* fileWriteProc */ - NULL, /* stringWriteProc */ + StringWriteGIF, /* stringWriteProc */ + NULL }; #define INTERLACE 0x40 @@ -186,6 +195,135 @@ static int Mgetc(MFile *handle); static int char64(int c); static void mInit(unsigned char *string, MFile *handle, int length); + +/* + * Types, defines and variables needed to write and compress a GIF. + */ + +#define LSB(a) ((unsigned char) (((short)(a)) & 0x00FF)) +#define MSB(a) ((unsigned char) (((short)(a)) >> 8)) + +#define GIFBITS 12 +#define HSIZE 5003 /* 80% occupancy */ + +#define DEFAULT_BACKGROUND_VALUE 0xD9 + +typedef struct { + int ssize; + int csize; + int rsize; + unsigned char *pixelOffset; + int pixelSize; + int pixelPitch; + int greenOffset; + int blueOffset; + int alphaOffset; + int num; + unsigned char mapa[MAXCOLORMAPSIZE][3]; +} GifWriterState; + +typedef int (* ifunptr) (GifWriterState *statePtr); + +/* + * Support for compression of GIFs. + */ + +#define MAXCODE(numBits) (((long) 1 << (numBits)) - 1) + +#ifdef SIGNED_COMPARE_SLOW +#define U(x) ((unsigned) (x)) +#else +#define U(x) (x) +#endif + +typedef struct { + int numBits; /* Number of bits/code. */ + long maxCode; /* Maximum code, given numBits. */ + int hashTable[HSIZE]; + unsigned int codeTable[HSIZE]; + long hSize; /* For dynamic table sizing. */ + + /* + * To save much memory, we overlay the table used by compress() with those + * used by decompress(). The tab_prefix table is the same size and type as + * the codeTable. The tab_suffix table needs 2**GIFBITS characters. We get + * this from the beginning of hashTable. The output stack uses the rest of + * hashTable, and contains characters. There is plenty of room for any + * possible stack (stack used to be 8000 characters). + */ + + int freeEntry; /* First unused entry. */ + + /* + * Block compression parameters. After all codes are used up, and + * compression rate changes, start over. + */ + + int clearFlag; + + int offset; + unsigned int inCount; /* Length of input */ + unsigned int outCount; /* # of codes output (for debugging) */ + + /* + * Algorithm: use open addressing double hashing (no chaining) on the + * prefix code / next character combination. We do a variant of Knuth's + * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime + * secondary probe. Here, the modular division first probe is gives way to + * a faster exclusive-or manipulation. Also do block compression with an + * adaptive reset, whereby the code table is cleared when the compression + * ratio decreases, but after the table fills. The variable-length output + * codes are re-sized at this point, and a special CLEAR code is generated + * for the decompressor. Late addition: construct the table according to + * file size for noticeable speed improvement on small files. Please + * direct questions about this implementation to ames!jaw. + */ + + int initialBits; + ClientData destination; + WriteBytesFunc *writeProc; + + int clearCode; + int eofCode; + + unsigned long currentAccumulated; + int currentBits; + + /* + * Number of characters so far in this 'packet' + */ + + int accumulatedByteCount; + + /* + * Define the storage for the packet accumulator + */ + + unsigned char packetAccumulator[256]; +} GIFState_t; + +/* + * Definition of new functions to write GIFs + */ + +static int ColorNumber(GifWriterState *statePtr, + int red, int green, int blue); +static void Compress(int initBits, ClientData handle, + WriteBytesFunc *writeProc, ifunptr readValue, + GifWriterState *statePtr); +static int IsNewColor(GifWriterState *statePtr, + int red, int green, int blue); +static void SaveMap(GifWriterState *statePtr, + Tk_PhotoImageBlock *blockPtr); +static int ReadValue(GifWriterState *statePtr); +static WriteBytesFunc WriteToChannel; +static WriteBytesFunc WriteToByteArray; +static void Output(GIFState_t *statePtr, long code); +static void ClearForBlock(GIFState_t *statePtr); +static void ClearHashTable(GIFState_t *statePtr, int hSize); +static void CharInit(GIFState_t *statePtr); +static void CharOut(GIFState_t *statePtr, int c); +static void FlushChar(GIFState_t *statePtr); /* *---------------------------------------------------------------------- @@ -255,14 +393,15 @@ FileReadGIF( * image being read. */ { int fileWidth, fileHeight, imageWidth, imageHeight; - int nBytes, index = 0, argc = 0, i, result = TCL_ERROR; + unsigned int nBytes; + int index = 0, argc = 0, i, result = TCL_ERROR; Tcl_Obj **objv; unsigned char buf[100]; unsigned char *trashBuffer = NULL; int bitPixel; unsigned char colorMap[MAXCOLORMAPSIZE][4]; int transparent = -1; - static const char *optionStrings[] = { + static const char *const optionStrings[] = { "-index", NULL }; GIFImageConfig gifConf, *gifConfPtr = &gifConf; @@ -272,6 +411,7 @@ FileReadGIF( * source and not a file. */ + memset(colorMap, 0, MAXCOLORMAPSIZE*4); memset(gifConfPtr, 0, sizeof(GIFImageConfig)); if (fileName == INLINE_DATA_BINARY || fileName == INLINE_DATA_BASE64) { gifConfPtr->fromData = fileName; @@ -287,13 +427,16 @@ FileReadGIF( return TCL_ERROR; } for (i = 1; i < argc; i++) { - if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings, "option name", - 0, &nBytes) != TCL_OK) { + int optionIdx; + if (Tcl_GetIndexFromObjStruct(interp, objv[i], optionStrings, + sizeof(char *), "option name", 0, &optionIdx) != TCL_OK) { return TCL_ERROR; } if (i == (argc-1)) { - Tcl_AppendResult(interp, "no value given for \"", - Tcl_GetString(objv[i]), "\" option", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "no value given for \"%s\" option", + Tcl_GetString(objv[i]))); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "OPT_VALUE", NULL); return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, objv[++i], &index) != TCL_OK) { @@ -306,13 +449,15 @@ FileReadGIF( */ if (!ReadGIFHeader(gifConfPtr, chan, &fileWidth, &fileHeight)) { - Tcl_AppendResult(interp, "couldn't read GIF header from file \"", - fileName, "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "couldn't read GIF header from file \"%s\"", fileName)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "HEADER", NULL); return TCL_ERROR; } if ((fileWidth <= 0) || (fileHeight <= 0)) { - Tcl_AppendResult(interp, "GIF image file \"", fileName, - "\" has dimension(s) <= 0", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "GIF image file \"%s\" has dimension(s) <= 0", fileName)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "BOGUS_SIZE", NULL); return TCL_ERROR; } @@ -327,7 +472,9 @@ FileReadGIF( if (BitSet(buf[0], LOCALCOLORMAP)) { /* Global Colormap */ if (!ReadColorMap(gifConfPtr, chan, bitPixel, colorMap)) { - Tcl_AppendResult(interp, "error reading color map", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "error reading color map", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "COLOR_MAP", NULL); return TCL_ERROR; } } @@ -363,14 +510,18 @@ FileReadGIF( * Premature end of image. */ - Tcl_AppendResult(interp, - "premature end of image data for this index", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "premature end of image data for this index", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "PREMATURE_END", + NULL); goto error; } switch (buf[0]) { case GIF_TERMINATOR: - Tcl_AppendResult(interp, "no image data for this index", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "no image data for this index", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "NO_DATA", NULL); goto error; case GIF_EXTENSION: @@ -379,23 +530,29 @@ FileReadGIF( */ if (Fread(gifConfPtr, buf, 1, 1, chan) != 1) { - Tcl_SetResult(interp, + Tcl_SetObjResult(interp, Tcl_NewStringObj( "error reading extension function code in GIF image", - TCL_STATIC); + -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "BAD_EXT", + NULL); goto error; } if (DoExtension(gifConfPtr, chan, buf[0], gifConfPtr->workingBuffer, &transparent) < 0) { - Tcl_SetResult(interp, "error reading extension in GIF image", - TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "error reading extension in GIF image", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "BAD_EXT", + NULL); goto error; } continue; case GIF_START: if (Fread(gifConfPtr, buf, 1, 9, chan) != 9) { - Tcl_SetResult(interp, + Tcl_SetObjResult(interp, Tcl_NewStringObj( "couldn't read left/top/width/height in GIF image", - TCL_STATIC); + -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "DIMENSIONS", + NULL); goto error; } break; @@ -423,7 +580,10 @@ FileReadGIF( if (BitSet(buf[8], LOCALCOLORMAP)) { if (!ReadColorMap(gifConfPtr, chan, bitPixel, colorMap)) { - Tcl_AppendResult(interp, "error reading color map", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "error reading color map", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", + "COLOR_MAP", NULL); goto error; } } @@ -433,8 +593,14 @@ FileReadGIF( */ if (trashBuffer == NULL) { + if (fileWidth > (int)((UINT_MAX/3)/fileHeight)) { + goto error; + } nBytes = fileWidth * fileHeight * 3; - trashBuffer = (unsigned char *) ckalloc((unsigned) nBytes); + trashBuffer = ckalloc(nBytes); + if (trashBuffer) { + memset(trashBuffer, 0, nBytes); + } } /* @@ -470,7 +636,9 @@ FileReadGIF( if (BitSet(buf[8], LOCALCOLORMAP)) { if (!ReadColorMap(gifConfPtr, chan, bitPixel, colorMap)) { - Tcl_AppendResult(interp, "error reading color map", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "error reading color map", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "COLOR_MAP", NULL); goto error; } } @@ -516,22 +684,31 @@ FileReadGIF( block.offset[1] = 1; block.offset[2] = 2; block.offset[3] = (transparent>=0) ? 3 : 0; + if (imageWidth > INT_MAX/block.pixelSize) { + goto error; + } block.pitch = block.pixelSize * imageWidth; + if (imageHeight > (int)(UINT_MAX/block.pitch)) { + goto error; + } nBytes = block.pitch * imageHeight; - block.pixelPtr = (unsigned char *) ckalloc((unsigned) nBytes); + block.pixelPtr = ckalloc(nBytes); + if (block.pixelPtr) { + memset(block.pixelPtr, 0, nBytes); + } if (ReadImage(gifConfPtr, interp, block.pixelPtr, chan, imageWidth, - imageHeight, colorMap, srcX, srcY, BitSet(buf[8],INTERLACE), + imageHeight, colorMap, srcX, srcY, BitSet(buf[8], INTERLACE), transparent) != TCL_OK) { - ckfree((char *) block.pixelPtr); + ckfree(block.pixelPtr); goto error; } if (Tk_PhotoPutBlock(interp, imageHandle, &block, destX, destY, width, height, TK_PHOTO_COMPOSITE_SET) != TCL_OK) { - ckfree((char *) block.pixelPtr); + ckfree(block.pixelPtr); goto error; } - ckfree((char *) block.pixelPtr); + ckfree(block.pixelPtr); } /* @@ -539,7 +716,7 @@ FileReadGIF( * which suits as well). We're done. */ - Tcl_AppendResult(interp, tkImgFmtGIF.name, NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj(tkImgFmtGIF.name, -1)); result = TCL_OK; error: @@ -548,7 +725,7 @@ FileReadGIF( */ if (trashBuffer != NULL) { - ckfree((char *) trashBuffer); + ckfree(trashBuffer); } return result; } @@ -765,19 +942,19 @@ DoExtension( int count; switch (label) { - case 0x01: /* Plain Text Extension */ + case 0x01: /* Plain Text Extension */ break; - case 0xff: /* Application Extension */ + case 0xff: /* Application Extension */ break; - case 0xfe: /* Comment Extension */ + case 0xfe: /* Comment Extension */ do { count = GetDataBlock(gifConfPtr, chan, buf); } while (count > 0); return count; - case 0xf9: /* Graphic Control Extension */ + case 0xf9: /* Graphic Control Extension */ count = GetDataBlock(gifConfPtr, chan, buf); if (count < 0) { return 1; @@ -857,7 +1034,7 @@ ReadImage( int transparent) { unsigned char initialCodeSize; - int xpos = 0, ypos = 0, pass = 0, i; + int xpos = 0, ypos = 0, pass = 0, i, count; register unsigned char *pixelPtr; static const int interlaceStep[] = { 8, 8, 4, 2 }; static const int interlaceStart[] = { 0, 4, 2, 1 }; @@ -873,13 +1050,14 @@ ReadImage( */ if (Fread(gifConfPtr, &initialCodeSize, 1, 1, chan) <= 0) { - Tcl_AppendResult(interp, "error reading GIF image: ", - Tcl_PosixError(interp), NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "error reading GIF image: %s", Tcl_PosixError(interp))); return TCL_ERROR; } if (initialCodeSize > MAX_LWZ_BITS) { - Tcl_SetResult(interp, "malformed image", TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj("malformed image", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "MALFORMED", NULL); return TCL_ERROR; } @@ -1074,6 +1252,25 @@ ReadImage( } pixelPtr = imagePtr + (ypos) * len * ((transparent>=0)?4:3); } + + /* + * Now read until the final zero byte. + * It was observed that there might be 1 length blocks + * (test imgPhoto-14.1) which are not read. + * + * The field "stack" is abused for temporary buffer. it has 4096 bytes + * and we need 256. + * + * Loop until we hit a 0 length block which is the end sign. + */ + while ( 0 < (count = GetDataBlock(gifConfPtr, chan, stack))) + { + if (-1 == count ) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "error reading GIF image: %s", Tcl_PosixError(interp))); + return TCL_ERROR; + } + } return TCL_OK; } @@ -1274,7 +1471,7 @@ Mgetc( handle->data++; } while (c == GIF_SPACE); - if (c>GIF_SPECIAL) { + if (c > GIF_SPECIAL) { handle->state = GIF_DONE; return handle->c; } @@ -1411,8 +1608,8 @@ Fread( * lolo@pcsig22.etsimo.uniovi.es * Date: Fri September 20 1996 * - * Modified for transparency handling (gif89a) and miGIF compression - * by Jan Nijtmans <j.nijtmans@chello.nl> + * Modified for transparency handling (gif89a) + * by Jan Nijtmans <nijtmans@users.sourceforge.net> * *---------------------------------------------------------------------- * FileWriteGIF- @@ -1421,54 +1618,12 @@ Fread( * data from a photo image into a given file * * Results: - * A standard TCL completion code. If TCL_ERROR is returned then an error - * message is left in interp->result. + * A standard TCL completion code. If TCL_ERROR is returned then an + * error message is left in the interp's result. * *---------------------------------------------------------------------- */ -/* - * Types, defines and variables needed to write and compress a GIF. - */ - -typedef int (* ifunptr) (ClientData clientData); - -#define LSB(a) ((unsigned char) (((short)(a)) & 0x00FF)) -#define MSB(a) ((unsigned char) (((short)(a)) >> 8)) - -#define GIFBITS 12 -#define HSIZE 5003 /* 80% occupancy */ - -typedef struct { - int ssize; - int csize; - int rsize; - unsigned char *pixelo; - int pixelSize; - int pixelPitch; - int greenOffset; - int blueOffset; - int alphaOffset; - int num; - unsigned char mapa[MAXCOLORMAPSIZE][3]; -} GifWriterState; - -/* - * Definition of new functions to write GIFs - */ - -static int color(GifWriterState *statePtr, - int red, int green, int blue, - unsigned char mapa[MAXCOLORMAPSIZE][3]); -static void compress(int initBits, Tcl_Channel handle, - ifunptr readValue, ClientData clientData); -static int nuevo(GifWriterState *statePtr, - int red, int green, int blue, - unsigned char mapa[MAXCOLORMAPSIZE][3]); -static void savemap(GifWriterState *statePtr, - Tk_PhotoImageBlock *blockPtr, - unsigned char mapa[MAXCOLORMAPSIZE][3]); -static int ReadValue(ClientData clientData); static int FileWriteGIF( @@ -1490,22 +1645,69 @@ FileWriteGIF( return TCL_ERROR; } - result = CommonWriteGIF(interp, chan, format, blockPtr); + result = CommonWriteGIF(interp, chan, WriteToChannel, format, blockPtr); if (Tcl_Close(interp, chan) == TCL_ERROR) { return TCL_ERROR; } return result; } + +static int +StringWriteGIF( + Tcl_Interp *interp, /* Interpreter to use for reporting errors and + * returning the GIF data. */ + Tcl_Obj *format, + Tk_PhotoImageBlock *blockPtr) +{ + int result; + Tcl_Obj *objPtr = Tcl_NewObj(); + + Tcl_IncrRefCount(objPtr); + result = CommonWriteGIF(interp, objPtr, WriteToByteArray, format, + blockPtr); + if (result == TCL_OK) { + Tcl_SetObjResult(interp, objPtr); + } + Tcl_DecrRefCount(objPtr); + return result; +} + +static int +WriteToChannel( + ClientData clientData, + const char *bytes, + int byteCount) +{ + Tcl_Channel handle = clientData; + + return Tcl_Write(handle, bytes, byteCount); +} + +static int +WriteToByteArray( + ClientData clientData, + const char *bytes, + int byteCount) +{ + Tcl_Obj *objPtr = clientData; + Tcl_Obj *tmpObj = Tcl_NewByteArrayObj((unsigned char *) bytes, byteCount); + + Tcl_IncrRefCount(tmpObj); + Tcl_AppendObjToObj(objPtr, tmpObj); + Tcl_DecrRefCount(tmpObj); + return byteCount; +} static int CommonWriteGIF( Tcl_Interp *interp, - Tcl_Channel handle, + ClientData handle, + WriteBytesFunc *writeProc, Tcl_Obj *format, Tk_PhotoImageBlock *blockPtr) { - GifWriterState state, *statePtr = &state; + GifWriterState state; int resolution; long width, height, x; unsigned char c; @@ -1514,140 +1716,141 @@ CommonWriteGIF( top = 0; left = 0; - memset(statePtr, 0, sizeof(state)); + memset(&state, 0, sizeof(state)); - statePtr->pixelSize = blockPtr->pixelSize; - statePtr->greenOffset = blockPtr->offset[1]-blockPtr->offset[0]; - statePtr->blueOffset = blockPtr->offset[2]-blockPtr->offset[0]; - statePtr->alphaOffset = blockPtr->offset[0]; - if (statePtr->alphaOffset < blockPtr->offset[2]) { - statePtr->alphaOffset = blockPtr->offset[2]; + state.pixelSize = blockPtr->pixelSize; + state.greenOffset = blockPtr->offset[1]-blockPtr->offset[0]; + state.blueOffset = blockPtr->offset[2]-blockPtr->offset[0]; + state.alphaOffset = blockPtr->offset[0]; + if (state.alphaOffset < blockPtr->offset[2]) { + state.alphaOffset = blockPtr->offset[2]; } - if (++statePtr->alphaOffset < statePtr->pixelSize) { - statePtr->alphaOffset -= blockPtr->offset[0]; + if (++state.alphaOffset < state.pixelSize) { + state.alphaOffset -= blockPtr->offset[0]; } else { - statePtr->alphaOffset = 0; + state.alphaOffset = 0; } - Tcl_Write(handle, (char *) (statePtr->alphaOffset ? GIF89a : GIF87a), 6); + writeProc(handle, (char *) (state.alphaOffset ? GIF89a : GIF87a), 6); - for (x=0 ; x<MAXCOLORMAPSIZE ; x++) { - statePtr->mapa[x][CM_RED] = 255; - statePtr->mapa[x][CM_GREEN] = 255; - statePtr->mapa[x][CM_BLUE] = 255; + for (x = 0; x < MAXCOLORMAPSIZE ;x++) { + state.mapa[x][CM_RED] = 255; + state.mapa[x][CM_GREEN] = 255; + state.mapa[x][CM_BLUE] = 255; } width = blockPtr->width; height = blockPtr->height; - statePtr->pixelo = blockPtr->pixelPtr + blockPtr->offset[0]; - statePtr->pixelPitch = blockPtr->pitch; - savemap(statePtr, blockPtr, statePtr->mapa); - if (statePtr->num >= MAXCOLORMAPSIZE) { - Tcl_AppendResult(interp, "too many colors", NULL); + state.pixelOffset = blockPtr->pixelPtr + blockPtr->offset[0]; + state.pixelPitch = blockPtr->pitch; + SaveMap(&state, blockPtr); + if (state.num >= MAXCOLORMAPSIZE) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("too many colors", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "COLORFUL", NULL); return TCL_ERROR; } - if (statePtr->num<2) { - statePtr->num = 2; + if (state.num<2) { + state.num = 2; } c = LSB(width); - Tcl_Write(handle, (char *) &c, 1); + writeProc(handle, (char *) &c, 1); c = MSB(width); - Tcl_Write(handle, (char *) &c, 1); + writeProc(handle, (char *) &c, 1); c = LSB(height); - Tcl_Write(handle, (char *) &c, 1); + writeProc(handle, (char *) &c, 1); c = MSB(height); - Tcl_Write(handle, (char *) &c, 1); + writeProc(handle, (char *) &c, 1); resolution = 0; - while (statePtr->num >> resolution) { + while (state.num >> resolution) { resolution++; } c = 111 + resolution * 17; - Tcl_Write(handle, (char *) &c, 1); + writeProc(handle, (char *) &c, 1); - statePtr->num = 1 << resolution; + state.num = 1 << resolution; /* * Background color */ c = 0; - Tcl_Write(handle, (char *) &c, 1); + writeProc(handle, (char *) &c, 1); /* * Zero for future expansion. */ - Tcl_Write(handle, (char *) &c, 1); + writeProc(handle, (char *) &c, 1); - for (x=0 ; x<statePtr->num ; x++) { - c = statePtr->mapa[x][CM_RED]; - Tcl_Write(handle, (char *) &c, 1); - c = statePtr->mapa[x][CM_GREEN]; - Tcl_Write(handle, (char *) &c, 1); - c = statePtr->mapa[x][CM_BLUE]; - Tcl_Write(handle, (char *) &c, 1); + for (x = 0; x < state.num; x++) { + c = state.mapa[x][CM_RED]; + writeProc(handle, (char *) &c, 1); + c = state.mapa[x][CM_GREEN]; + writeProc(handle, (char *) &c, 1); + c = state.mapa[x][CM_BLUE]; + writeProc(handle, (char *) &c, 1); } /* * Write out extension for transparent colour index, if necessary. */ - if (statePtr->alphaOffset) { + if (state.alphaOffset) { c = GIF_EXTENSION; - Tcl_Write(handle, (char *) &c, 1); - Tcl_Write(handle, "\371\4\1\0\0\0", 7); + writeProc(handle, (char *) &c, 1); + writeProc(handle, "\371\4\1\0\0\0", 7); } c = GIF_START; - Tcl_Write(handle, (char *) &c, 1); + writeProc(handle, (char *) &c, 1); c = LSB(top); - Tcl_Write(handle, (char *) &c, 1); + writeProc(handle, (char *) &c, 1); c = MSB(top); - Tcl_Write(handle, (char *) &c, 1); + writeProc(handle, (char *) &c, 1); c = LSB(left); - Tcl_Write(handle, (char *) &c, 1); + writeProc(handle, (char *) &c, 1); c = MSB(left); - Tcl_Write(handle, (char *) &c, 1); + writeProc(handle, (char *) &c, 1); c = LSB(width); - Tcl_Write(handle, (char *) &c, 1); + writeProc(handle, (char *) &c, 1); c = MSB(width); - Tcl_Write(handle, (char *) &c, 1); + writeProc(handle, (char *) &c, 1); c = LSB(height); - Tcl_Write(handle, (char *) &c, 1); + writeProc(handle, (char *) &c, 1); c = MSB(height); - Tcl_Write(handle, (char *) &c, 1); + writeProc(handle, (char *) &c, 1); c = 0; - Tcl_Write(handle, (char *) &c, 1); + writeProc(handle, (char *) &c, 1); c = resolution; - Tcl_Write(handle, (char *) &c, 1); + writeProc(handle, (char *) &c, 1); - statePtr->ssize = statePtr->rsize = blockPtr->width; - statePtr->csize = blockPtr->height; - compress(resolution+1, handle, ReadValue, (ClientData) statePtr); + state.ssize = state.rsize = blockPtr->width; + state.csize = blockPtr->height; + Compress(resolution+1, handle, writeProc, ReadValue, &state); c = 0; - Tcl_Write(handle, (char *) &c, 1); + writeProc(handle, (char *) &c, 1); c = GIF_TERMINATOR; - Tcl_Write(handle, (char *) &c, 1); + writeProc(handle, (char *) &c, 1); return TCL_OK; } static int -color( +ColorNumber( GifWriterState *statePtr, - int red, int green, int blue, - unsigned char mapa[MAXCOLORMAPSIZE][3]) + int red, int green, int blue) { int x = (statePtr->alphaOffset != 0); - for (; x<=MAXCOLORMAPSIZE ; x++) { - if ((mapa[x][CM_RED] == red) && (mapa[x][CM_GREEN] == green) && - (mapa[x][CM_BLUE] == blue)) { + for (; x <= MAXCOLORMAPSIZE; x++) { + if ((statePtr->mapa[x][CM_RED] == red) && + (statePtr->mapa[x][CM_GREEN] == green) && + (statePtr->mapa[x][CM_BLUE] == blue)) { return x; } } @@ -1655,16 +1858,16 @@ color( } static int -nuevo( +IsNewColor( GifWriterState *statePtr, - int red, int green, int blue, - unsigned char mapa[MAXCOLORMAPSIZE][3]) + int red, int green, int blue) { int x = (statePtr->alphaOffset != 0); for (; x<=statePtr->num ; x++) { - if ((mapa[x][CM_RED] == red) && (mapa[x][CM_GREEN] == green) && - (mapa[x][CM_BLUE] == blue)) { + if ((statePtr->mapa[x][CM_RED] == red) && + (statePtr->mapa[x][CM_GREEN] == green) && + (statePtr->mapa[x][CM_BLUE] == blue)) { return 0; } } @@ -1672,10 +1875,9 @@ nuevo( } static void -savemap( +SaveMap( GifWriterState *statePtr, - Tk_PhotoImageBlock *blockPtr, - unsigned char mapa[MAXCOLORMAPSIZE][3]) + Tk_PhotoImageBlock *blockPtr) { unsigned char *colores; int x, y; @@ -1683,9 +1885,9 @@ savemap( if (statePtr->alphaOffset) { statePtr->num = 0; - mapa[0][CM_RED] = 0xd9; - mapa[0][CM_GREEN] = 0xd9; - mapa[0][CM_BLUE] = 0xd9; + statePtr->mapa[0][CM_RED] = DEFAULT_BACKGROUND_VALUE; + statePtr->mapa[0][CM_GREEN] = DEFAULT_BACKGROUND_VALUE; + statePtr->mapa[0][CM_BLUE] = DEFAULT_BACKGROUND_VALUE; } else { statePtr->num = -1; } @@ -1697,14 +1899,14 @@ savemap( red = colores[0]; green = colores[statePtr->greenOffset]; blue = colores[statePtr->blueOffset]; - if (nuevo(statePtr, red, green, blue, mapa)) { + if (IsNewColor(statePtr, red, green, blue)) { statePtr->num++; if (statePtr->num >= MAXCOLORMAPSIZE) { return; } - mapa[statePtr->num][CM_RED] = red; - mapa[statePtr->num][CM_GREEN] = green; - mapa[statePtr->num][CM_BLUE] = blue; + statePtr->mapa[statePtr->num][CM_RED] = red; + statePtr->mapa[statePtr->num][CM_GREEN] = green; + statePtr->mapa[statePtr->num][CM_BLUE] = blue; } } colores += statePtr->pixelSize; @@ -1714,26 +1916,26 @@ savemap( static int ReadValue( - ClientData clientData) + GifWriterState *statePtr) { - GifWriterState *statePtr = (GifWriterState *) clientData; unsigned int col; if (statePtr->csize == 0) { return EOF; } - if (statePtr->alphaOffset && statePtr->pixelo[statePtr->alphaOffset]==0) { + if (statePtr->alphaOffset + && (statePtr->pixelOffset[statePtr->alphaOffset]==0)) { col = 0; } else { - col = color(statePtr, statePtr->pixelo[0], - statePtr->pixelo[statePtr->greenOffset], - statePtr->pixelo[statePtr->blueOffset], statePtr->mapa); + col = ColorNumber(statePtr, statePtr->pixelOffset[0], + statePtr->pixelOffset[statePtr->greenOffset], + statePtr->pixelOffset[statePtr->blueOffset]); } - statePtr->pixelo += statePtr->pixelSize; + statePtr->pixelOffset += statePtr->pixelSize; if (--statePtr->ssize <= 0) { statePtr->ssize = statePtr->rsize; statePtr->csize--; - statePtr->pixelo += statePtr->pixelPitch + statePtr->pixelOffset += statePtr->pixelPitch - (statePtr->rsize * statePtr->pixelSize); } @@ -1741,501 +1943,308 @@ ReadValue( } /* - *----------------------------------------------------------------------- - * - * miGIF Compression - mouse and ivo's GIF-compatible compression - * - * -run length encoding compression routines- - * - * Copyright (C) 1998 Hutchison Avenue Software Corporation - * http://www.hasc.com - * info@hasc.com - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, provided - * that the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation. This software is provided "AS IS." The Hutchison Avenue - * Software Corporation disclaims all warranties, either express or implied, - * including but not limited to implied warranties of merchantability and - * fitness for a particular purpose, with respect to this code and - * accompanying documentation. - * - * The miGIF compression routines do not, strictly speaking, generate files - * conforming to the GIF spec, since the image data is not LZW-compressed - * (this is the point: in order to avoid transgression of the Unisys patent on - * the LZW algorithm.) However, miGIF generates data streams that any - * reasonably sane LZW decompresser will decompress to what we want. - * - * miGIF compression uses run length encoding. It compresses horizontal runs - * of pixels of the same color. This type of compression gives good results on - * images with many runs, for example images with lines, text and solid shapes - * on a solid-colored background. It gives little or no compression on images - * with few runs, for example digital or scanned photos. + * GIF Image compression - modified 'Compress' * - * der Mouse - * mouse@rodents.montreal.qc.ca - * 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B + * Based on: compress.c - File compression ala IEEE Computer, June 1984. * - * ivo@hasc.com - * - * The Graphics Interchange Format(c) is the Copyright property of CompuServe - * Incorporated. GIF(sm) is a Service Mark property of CompuServe Incorporated. - * - *----------------------------------------------------------------------- + * By Authors: Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas) + * Jim McKie (decvax!mcvax!jim) + * Steve Davies (decvax!vax135!petsd!peora!srd) + * Ken Turkowski (decvax!decwrl!turtlevax!ken) + * James A. Woods (decvax!ihnp4!ames!jaw) + * Joe Orost (decvax!vax135!petsd!joe) */ - -typedef struct { - int runlengthPixel; - int runlengthBaseCode; - int runlengthCount; - int runlengthTablePixel; - int runlengthTableMax; - int justCleared; - int outputBits; - int outputBitsInit; - int outputCount; - int outputBump; - int outputBumpInit; - int outputClear; - int outputClearInit; - int maxOcodes; - int codeClear; - int codeEOF; - unsigned int obuf; - int obits; - Tcl_Channel ofile; - unsigned char oblock[256]; - int oblen; -} miGIFState_t; -/* - * Used only when debugging GIF compression code - */ -/* #define MIGIF_DEBUGGING_ENVARS */ +static void +Compress( + int initialBits, + ClientData handle, + WriteBytesFunc *writeProc, + ifunptr readValue, + GifWriterState *statePtr) +{ + long fcode, ent, disp, hSize, i = 0; + int c, hshift; + GIFState_t state; -#ifdef MIGIF_DEBUGGING_ENVARS + memset(&state, 0, sizeof(state)); -/* - * This debugging code is _absolutely_ not thread-safe. It's also not normally - * enabled either. - */ + /* + * Set up the globals: initialBits - initial number of bits + * outChannel - pointer to output file + */ -static int verboseSet = 0; -static int verbose; -#define MIGIF_VERBOSE (verboseSet?verbose:setVerbose()) -#define DEBUGMSG(printfArgs) if (MIGIF_VERBOSE) { printf printfArgs; } + state.initialBits = initialBits; + state.destination = handle; + state.writeProc = writeProc; -static int -setVerbose(void) -{ - verbose = !!getenv("MIGIF_VERBOSE"); - verboseSet = 1; - return verbose; -} + /* + * Set up the necessary values. + */ -static const char * -binformat( - unsigned int v, - int nbits) -{ - static char bufs[8][64]; - static int bhand = 0; - unsigned int bit; - int bno; - char *bp; - - bhand--; - if (bhand < 0) { - bhand = (sizeof(bufs) / sizeof(bufs[0])) - 1; - } - bp = &bufs[bhand][0]; - for (bno=nbits-1,bit=((unsigned int)1)<<bno ; bno>=0 ; bno--,bit>>=1) { - *bp++ = (v & bit) ? '1' : '0'; - if (((bno&3) == 0) && (bno != 0)) { - *bp++ = '.'; - } + state.offset = 0; + state.hSize = HSIZE; + state.outCount = 0; + state.clearFlag = 0; + state.inCount = 1; + state.maxCode = MAXCODE(state.numBits = state.initialBits); + state.clearCode = 1 << (initialBits - 1); + state.eofCode = state.clearCode + 1; + state.freeEntry = state.clearCode + 2; + CharInit(&state); + + ent = readValue(statePtr); + + hshift = 0; + for (fcode = (long) state.hSize; fcode < 65536L; fcode *= 2L) { + hshift++; } - *bp = '\0'; - return &bufs[bhand][0]; -} -#else /* !MIGIF_DEBUGGING_ENVARS */ -#define DEBUGMSG(printfArgs) /* do nothing */ -#endif - -static void -writeBlock( - miGIFState_t *statePtr) -{ - unsigned char c; + hshift = 8 - hshift; /* Set hash code range bound */ -#ifdef MIGIF_DEBUGGING_ENVARS - if (MIGIF_VERBOSE) { - int i; - printf("writeBlock %d:", statePtr->oblen); - for (i=0 ; i<statePtr->oblen ; i++) { - printf(" %02x", statePtr->oblock[i]); + hSize = state.hSize; + ClearHashTable(&state, (int) hSize); /* Clear hash table */ + + Output(&state, (long) state.clearCode); + + while (U(c = readValue(statePtr)) != U(EOF)) { + state.inCount++; + + fcode = (long) (((long) c << GIFBITS) + ent); + i = ((long)c << hshift) ^ ent; /* XOR hashing */ + + if (state.hashTable[i] == fcode) { + ent = state.codeTable[i]; + continue; + } else if ((long) state.hashTable[i] < 0) { /* Empty slot */ + goto nomatch; + } + + disp = hSize - i; /* Secondary hash (after G. Knott) */ + if (i == 0) { + disp = 1; + } + + probe: + if ((i -= disp) < 0) { + i += hSize; + } + + if (state.hashTable[i] == fcode) { + ent = state.codeTable[i]; + continue; + } + if ((long) state.hashTable[i] > 0) { + goto probe; + } + + nomatch: + Output(&state, (long) ent); + state.outCount++; + ent = c; + if (U(state.freeEntry) < U((long)1 << GIFBITS)) { + state.codeTable[i] = state.freeEntry++; /* code -> hashtable */ + state.hashTable[i] = fcode; + } else { + ClearForBlock(&state); } - printf("\n"); - } -#endif - c = statePtr->oblen; - Tcl_Write(statePtr->ofile, (char *) &c, 1); - Tcl_Write(statePtr->ofile, (char *) &statePtr->oblock[0], statePtr->oblen); - statePtr->oblen = 0; -} - -static void -blockOut( - miGIFState_t *statePtr, - unsigned c) -{ - DEBUGMSG(("blockOut %s\n", binformat(c, 8))); - statePtr->oblock[statePtr->oblen++] = (unsigned char) c; - if (statePtr->oblen >= 255) { - writeBlock(statePtr); - } -} - -static void -blockFlush( - miGIFState_t *statePtr) -{ - DEBUGMSG(("blockFlush\n")); - if (statePtr->oblen > 0) { - writeBlock(statePtr); - } -} - -static void -output( - miGIFState_t *statePtr, - int val) -{ - DEBUGMSG(("output %s [%s %d %d]\n", binformat(val, statePtr->outputBits), - binformat(statePtr->obuf, statePtr->obits), statePtr->obits, - statePtr->outputBits)); - statePtr->obuf |= val << statePtr->obits; - statePtr->obits += statePtr->outputBits; - while (statePtr->obits >= 8) { - blockOut(statePtr, statePtr->obuf & 0xff); - statePtr->obuf >>= 8; - statePtr->obits -= 8; - } - DEBUGMSG(("output leaving [%s %d]\n", - binformat(statePtr->obuf, statePtr->obits), statePtr->obits)); -} - -static void -outputFlush( - miGIFState_t *statePtr) -{ - DEBUGMSG(("outputFlush\n")); - if (statePtr->obits > 0) { - blockOut(statePtr, statePtr->obuf); } - blockFlush(statePtr); -} - -static void -didClear( - miGIFState_t *statePtr) -{ - DEBUGMSG(("didClear\n")); - statePtr->outputBits = statePtr->outputBitsInit; - statePtr->outputBump = statePtr->outputBumpInit; - statePtr->outputClear = statePtr->outputClearInit; - statePtr->outputCount = 0; - statePtr->runlengthTableMax = 0; - statePtr->justCleared = 1; + + /* + * Put out the final code. + */ + + Output(&state, (long) ent); + state.outCount++; + Output(&state, (long) state.eofCode); } +/***************************************************************** + * Output -- + * Output the given code. + * + * Inputs: + * code: A numBits-bit integer. If == -1, then EOF. This assumes that + * numBits =< (long) wordsize - 1. + * Outputs: + * Outputs code to the file. + * Assumptions: + * Chars are 8 bits long. + * Algorithm: + * Maintain a GIFBITS character long buffer (so that 8 codes will fit in + * it exactly). Use the VAX insv instruction to insert each code in turn. + * When the buffer fills up empty it and start over. + */ + static void -outputPlain( - miGIFState_t *statePtr, - int c) +Output( + GIFState_t *statePtr, + long code) { - DEBUGMSG(("outputPlain %s\n", binformat(c, statePtr->outputBits))); - statePtr->justCleared = 0; - output(statePtr, c); - statePtr->outputCount++; - if (statePtr->outputCount >= statePtr->outputBump) { - statePtr->outputBits++; - statePtr->outputBump += 1 << (statePtr->outputBits - 1); - } - if (statePtr->outputCount >= statePtr->outputClear) { - output(statePtr, statePtr->codeClear); - didClear(statePtr); + static const unsigned long masks[] = { + 0x0000, + 0x0001, 0x0003, 0x0007, 0x000F, + 0x001F, 0x003F, 0x007F, 0x00FF, + 0x01FF, 0x03FF, 0x07FF, 0x0FFF, + 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF + }; + + statePtr->currentAccumulated &= masks[statePtr->currentBits]; + if (statePtr->currentBits > 0) { + statePtr->currentAccumulated |= ((long) code << statePtr->currentBits); + } else { + statePtr->currentAccumulated = code; } -} - -static unsigned int -isqrt( - unsigned int x) -{ - unsigned int r; - unsigned int v; + statePtr->currentBits += statePtr->numBits; - if (x < 2) { - return x; + while (statePtr->currentBits >= 8) { + CharOut(statePtr, (unsigned) (statePtr->currentAccumulated & 0xff)); + statePtr->currentAccumulated >>= 8; + statePtr->currentBits -= 8; } - for (v=x,r=1 ; v ; v>>=2,r<<=1); - while (1) { - v = ((x / r) + r) / 2; - if (v==r || v==r+1) { - return r; + + /* + * If the next entry is going to be too big for the code size, then + * increase it, if possible. + */ + + if ((statePtr->freeEntry > statePtr->maxCode) || statePtr->clearFlag) { + if (statePtr->clearFlag) { + statePtr->maxCode = MAXCODE( + statePtr->numBits = statePtr->initialBits); + statePtr->clearFlag = 0; + } else { + statePtr->numBits++; + if (statePtr->numBits == GIFBITS) { + statePtr->maxCode = (long)1 << GIFBITS; + } else { + statePtr->maxCode = MAXCODE(statePtr->numBits); + } } - r = v; } -} - -static int -computeTriangleCount( - unsigned int count, - unsigned int nrepcodes) -{ - unsigned int perrep; - unsigned int cost; - cost = 0; - perrep = (nrepcodes * (nrepcodes+1)) / 2; - while (count >= perrep) { - cost += nrepcodes; - count -= perrep; - } - if (count > 0) { - unsigned int n = isqrt(count); + if (code == statePtr->eofCode) { + /* + * At EOF, write the rest of the buffer. + */ - while (n*(n+1) >= 2*count) { - n--; - } - while (n*(n+1) < 2*count) { - n++; + while (statePtr->currentBits > 0) { + CharOut(statePtr, + (unsigned) (statePtr->currentAccumulated & 0xff)); + statePtr->currentAccumulated >>= 8; + statePtr->currentBits -= 8; } - cost += n; - } - return (int) cost + 1; -} - -static void -maxOutputClear( - miGIFState_t *statePtr) -{ - statePtr->outputClear = statePtr->maxOcodes; -} - -static void -resetOutputClear( - miGIFState_t *statePtr) -{ - statePtr->outputClear = statePtr->outputClearInit; - if (statePtr->outputCount >= statePtr->outputClear) { - output(statePtr, statePtr->codeClear); - didClear(statePtr); + FlushChar(statePtr); } } +/* + * Clear out the hash table + */ + static void -runlengthFlushFromClear( - miGIFState_t *statePtr, - int count) +ClearForBlock( /* Table clear for block compress. */ + GIFState_t *statePtr) { - int n; - - DEBUGMSG(("runlengthFlushFromClear %d\n", count)); - maxOutputClear(statePtr); - statePtr->runlengthTablePixel = statePtr->runlengthPixel; - n = 1; - while (count > 0) { - if (n == 1) { - statePtr->runlengthTableMax = 1; - outputPlain(statePtr, statePtr->runlengthPixel); - count--; - } else if (count >= n) { - statePtr->runlengthTableMax = n; - outputPlain(statePtr, statePtr->runlengthBaseCode+n-2); - count -= n; - } else if (count == 1) { - statePtr->runlengthTableMax++; - outputPlain(statePtr, statePtr->runlengthPixel); - count = 0; - } else { - statePtr->runlengthTableMax++; - outputPlain(statePtr, statePtr->runlengthBaseCode+count-2); - count = 0; - } - if (statePtr->outputCount == 0) { - n = 1; - } else { - n++; - } - } - resetOutputClear(statePtr); - DEBUGMSG(("runlengthFlushFromClear leaving tableMax=%d\n", - statePtr->runlengthTableMax)); + ClearHashTable(statePtr, (int) statePtr->hSize); + statePtr->freeEntry = statePtr->clearCode + 2; + statePtr->clearFlag = 1; + + Output(statePtr, (long) statePtr->clearCode); } static void -runlengthFlushClearOrRep( - miGIFState_t *statePtr, - int count) +ClearHashTable( /* Reset code table. */ + GIFState_t *statePtr, + int hSize) { - int withclr; - - DEBUGMSG(("runlengthFlushClearOrRep %d\n", count)); - withclr = computeTriangleCount((unsigned) count, - (unsigned) statePtr->maxOcodes); - if (withclr < count) { - output(statePtr, statePtr->codeClear); - didClear(statePtr); - runlengthFlushFromClear(statePtr, count); - } else { - for (; count>0 ; count--) { - outputPlain(statePtr, statePtr->runlengthPixel); - } + register int *hashTablePtr = statePtr->hashTable + hSize; + register long i; + register long m1 = -1; + + i = hSize - 16; + do { /* might use Sys V memset(3) here */ + *(hashTablePtr-16) = m1; + *(hashTablePtr-15) = m1; + *(hashTablePtr-14) = m1; + *(hashTablePtr-13) = m1; + *(hashTablePtr-12) = m1; + *(hashTablePtr-11) = m1; + *(hashTablePtr-10) = m1; + *(hashTablePtr-9) = m1; + *(hashTablePtr-8) = m1; + *(hashTablePtr-7) = m1; + *(hashTablePtr-6) = m1; + *(hashTablePtr-5) = m1; + *(hashTablePtr-4) = m1; + *(hashTablePtr-3) = m1; + *(hashTablePtr-2) = m1; + *(hashTablePtr-1) = m1; + hashTablePtr -= 16; + } while ((i -= 16) >= 0); + + for (i += 16; i > 0; i--) { + *--hashTablePtr = m1; } } +/* + ***************************************************************************** + * + * GIF Specific routines + * + ***************************************************************************** + */ + +/* + * Set up the 'byte output' routine + */ + static void -runlengthFlushWithTable( - miGIFState_t *statePtr, - int count) +CharInit( + GIFState_t *statePtr) { - int repmax; - int repleft; - int leftover; - - DEBUGMSG(("runlengthFlushWithTable %d\n", count)); - repmax = count / statePtr->runlengthTableMax; - leftover = count % statePtr->runlengthTableMax; - repleft = (leftover ? 1 : 0); - if (statePtr->outputCount+repmax+repleft > statePtr->maxOcodes) { - repmax = statePtr->maxOcodes - statePtr->outputCount; - leftover = count - (repmax * statePtr->runlengthTableMax); - repleft = computeTriangleCount((unsigned) leftover, - (unsigned) statePtr->maxOcodes); - } - DEBUGMSG(("runlengthFlushWithTable repmax=%d leftover=%d repleft=%d\n", - repmax, leftover, repleft)); - if (computeTriangleCount((unsigned) count, (unsigned) statePtr->maxOcodes) - < repmax+repleft) { - output(statePtr, statePtr->codeClear); - didClear(statePtr); - runlengthFlushFromClear(statePtr, count); - return; - } - maxOutputClear(statePtr); - for (; repmax>0 ; repmax--) { - outputPlain(statePtr, - statePtr->runlengthBaseCode + statePtr->runlengthTableMax - 2); - } - if (leftover) { - if (statePtr->justCleared) { - runlengthFlushFromClear(statePtr, leftover); - } else if (leftover == 1) { - outputPlain(statePtr, statePtr->runlengthPixel); - } else { - outputPlain(statePtr, statePtr->runlengthBaseCode + leftover - 2); - } - } - resetOutputClear(statePtr); + statePtr->accumulatedByteCount = 0; + statePtr->currentAccumulated = 0; + statePtr->currentBits = 0; } +/* + * Add a character to the end of the current packet, and if it is 254 + * characters, flush the packet to disk. + */ + static void -runlengthFlush( - miGIFState_t *statePtr) +CharOut( + GIFState_t *statePtr, + int c) { - DEBUGMSG(("runlengthFlush [ %d %d\n", statePtr->runlengthCount, - statePtr->runlengthPixel)); - if (statePtr->runlengthCount == 1) { - outputPlain(statePtr, statePtr->runlengthPixel); - statePtr->runlengthCount = 0; - DEBUGMSG(("runlengthFlush ]\n")); - return; - } - if (statePtr->justCleared) { - runlengthFlushFromClear(statePtr, statePtr->runlengthCount); - } else if ((statePtr->runlengthTableMax < 2) - || (statePtr->runlengthTablePixel != statePtr->runlengthPixel)) { - runlengthFlushClearOrRep(statePtr, statePtr->runlengthCount); - } else { - runlengthFlushWithTable(statePtr, statePtr->runlengthCount); + statePtr->packetAccumulator[statePtr->accumulatedByteCount++] = c; + if (statePtr->accumulatedByteCount >= 254) { + FlushChar(statePtr); } - DEBUGMSG(("runlengthFlush ]\n")); - statePtr->runlengthCount = 0; } +/* + * Flush the packet to disk, and reset the accumulator + */ + static void -compress( - int initBits, - Tcl_Channel handle, - ifunptr readValue, - ClientData clientData) +FlushChar( + GIFState_t *statePtr) { - int c; - miGIFState_t state, *statePtr = &state; - - memset(statePtr, 0, sizeof(state)); - - statePtr->ofile = handle; - statePtr->obuf = 0; - statePtr->obits = 0; - statePtr->oblen = 0; - statePtr->codeClear = 1 << (initBits - 1); - statePtr->codeEOF = statePtr->codeClear + 1; - statePtr->runlengthBaseCode = statePtr->codeEOF + 1; - statePtr->outputBumpInit = (1 << (initBits - 1)) - 1; - - /* - * For images with a lot of runs, making outputClearInit larger will give - * better compression. - */ - - statePtr->outputClearInit = - (initBits <= 3) ? 9 : (statePtr->outputBumpInit-1); -#ifdef MIGIF_DEBUGGING_ENVARS - { - const char *ocienv = getenv("MIGIF_OUT_CLEAR_INIT"); + unsigned char c; - if (ocienv) { - statePtr->outputClearInit = atoi(ocienv); - DEBUGMSG(("[overriding outputClearInit to %d]\n", - statePtr->outputClearInit)); - } - } -#endif - statePtr->outputBitsInit = initBits; - statePtr->maxOcodes = - (1 << GIFBITS) - ((1 << (statePtr->outputBitsInit - 1)) + 3); - didClear(statePtr); - output(statePtr, statePtr->codeClear); - statePtr->runlengthCount = 0; - while (1) { - c = readValue(clientData); - if (statePtr->runlengthCount>0 && statePtr->runlengthPixel!=c) { - runlengthFlush(statePtr); - } - if (c == EOF) { - break; - } - if (statePtr->runlengthPixel == c) { - statePtr->runlengthCount++; - } else { - statePtr->runlengthPixel = c; - statePtr->runlengthCount = 1; - } + if (statePtr->accumulatedByteCount > 0) { + c = statePtr->accumulatedByteCount; + statePtr->writeProc(statePtr->destination, (const char *) &c, 1); + statePtr->writeProc(statePtr->destination, + (const char *) statePtr->packetAccumulator, + statePtr->accumulatedByteCount); + statePtr->accumulatedByteCount = 0; } - output(statePtr, statePtr->codeEOF); - outputFlush(statePtr); } -/* - *----------------------------------------------------------------------- - * - * End of miGIF section - See copyright notice at start of section. - * - *----------------------------------------------------------------------- - */ +/* The End */ /* * Local Variables: diff --git a/generic/tkImgPNG.c b/generic/tkImgPNG.c new file mode 100644 index 0000000..bfb2457 --- /dev/null +++ b/generic/tkImgPNG.c @@ -0,0 +1,3563 @@ +/* + * tkImgPNG.c -- + * + * A Tk photo image file handler for PNG files. + * + * Copyright (c) 2006-2008 Muonics, Inc. + * Copyright (c) 2008 Donal K. Fellows + * + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ + +#include "assert.h" +#include "tkInt.h" + +#define PNG_INT32(a,b,c,d) \ + (((long)(a) << 24) | ((long)(b) << 16) | ((long)(c) << 8) | (long)(d)) +#define PNG_BLOCK_SZ 1024 /* Process up to 1k at a time. */ +#define PNG_MIN(a, b) (((a) < (b)) ? (a) : (b)) + +/* + * Every PNG image starts with the following 8-byte signature. + */ + +#define PNG_SIG_SZ 8 +static const unsigned char pngSignature[] = { + 137, 80, 78, 71, 13, 10, 26, 10 +}; + +static const int startLine[8] = { + 0, 0, 0, 4, 0, 2, 0, 1 +}; + +/* + * Chunk type flags. + */ + +#define PNG_CF_ANCILLARY 0x20000000L /* Non-critical chunk (can ignore). */ +#define PNG_CF_PRIVATE 0x00100000L /* Application-specific chunk. */ +#define PNG_CF_RESERVED 0x00001000L /* Not used. */ +#define PNG_CF_COPYSAFE 0x00000010L /* Opaque data safe for copying. */ + +/* + * Chunk types, not all of which have support implemented. Note that there are + * others in the official extension set which we will never support (as they + * are officially deprecated). + */ + +#define CHUNK_IDAT PNG_INT32('I','D','A','T') /* Pixel data. */ +#define CHUNK_IEND PNG_INT32('I','E','N','D') /* End of Image. */ +#define CHUNK_IHDR PNG_INT32('I','H','D','R') /* Header. */ +#define CHUNK_PLTE PNG_INT32('P','L','T','E') /* Palette. */ + +#define CHUNK_bKGD PNG_INT32('b','K','G','D') /* Background Color */ +#define CHUNK_cHRM PNG_INT32('c','H','R','M') /* Chroma values. */ +#define CHUNK_gAMA PNG_INT32('g','A','M','A') /* Gamma. */ +#define CHUNK_hIST PNG_INT32('h','I','S','T') /* Histogram. */ +#define CHUNK_iCCP PNG_INT32('i','C','C','P') /* Color profile. */ +#define CHUNK_iTXt PNG_INT32('i','T','X','t') /* Internationalized + * text (comments, + * etc.) */ +#define CHUNK_oFFs PNG_INT32('o','F','F','s') /* Image offset. */ +#define CHUNK_pCAL PNG_INT32('p','C','A','L') /* Pixel calibration + * data. */ +#define CHUNK_pHYs PNG_INT32('p','H','Y','s') /* Physical pixel + * dimensions. */ +#define CHUNK_sBIT PNG_INT32('s','B','I','T') /* Significant bits */ +#define CHUNK_sCAL PNG_INT32('s','C','A','L') /* Physical scale. */ +#define CHUNK_sPLT PNG_INT32('s','P','L','T') /* Suggested + * palette. */ +#define CHUNK_sRGB PNG_INT32('s','R','G','B') /* Standard RGB space + * declaration. */ +#define CHUNK_tEXt PNG_INT32('t','E','X','t') /* Plain Latin-1 + * text. */ +#define CHUNK_tIME PNG_INT32('t','I','M','E') /* Time stamp. */ +#define CHUNK_tRNS PNG_INT32('t','R','N','S') /* Transparency. */ +#define CHUNK_zTXt PNG_INT32('z','T','X','t') /* Compressed Latin-1 + * text. */ + +/* + * Color flags. + */ + +#define PNG_COLOR_INDEXED 1 +#define PNG_COLOR_USED 2 +#define PNG_COLOR_ALPHA 4 + +/* + * Actual color types. + */ + +#define PNG_COLOR_GRAY 0 +#define PNG_COLOR_RGB (PNG_COLOR_USED) +#define PNG_COLOR_PLTE (PNG_COLOR_USED | PNG_COLOR_INDEXED) +#define PNG_COLOR_GRAYALPHA (PNG_COLOR_GRAY | PNG_COLOR_ALPHA) +#define PNG_COLOR_RGBA (PNG_COLOR_USED | PNG_COLOR_ALPHA) + +/* + * Compression Methods. + */ + +#define PNG_COMPRESS_DEFLATE 0 + +/* + * Filter Methods. + */ + +#define PNG_FILTMETH_STANDARD 0 + +/* + * Interlacing Methods. + */ + +#define PNG_INTERLACE_NONE 0 +#define PNG_INTERLACE_ADAM7 1 + +/* + * State information, used to store everything about the PNG image being + * currently parsed or created. + */ + +typedef struct { + /* + * PNG data source/destination channel/object/byte array. + */ + + Tcl_Channel channel; /* Channel for from-file reads. */ + Tcl_Obj *objDataPtr; + unsigned char *strDataBuf; /* Raw source data for from-string reads. */ + int strDataLen; /* Length of source data. */ + unsigned char *base64Data; /* base64 encoded string data. */ + unsigned char base64Bits; /* Remaining bits from last base64 read. */ + unsigned char base64State; /* Current state of base64 decoder. */ + double alpha; /* Alpha from -format option. */ + + /* + * Image header information. + */ + + unsigned char bitDepth; /* Number of bits per pixel. */ + unsigned char colorType; /* Grayscale, TrueColor, etc. */ + unsigned char compression; /* Compression Mode (always zlib). */ + unsigned char filter; /* Filter mode (0 - 3). */ + unsigned char interlace; /* Type of interlacing (if any). */ + unsigned char numChannels; /* Number of channels per pixel. */ + unsigned char bytesPerPixel;/* Bytes per pixel in scan line. */ + int bitScale; /* Scale factor for RGB/Gray depths < 8. */ + int currentLine; /* Current line being unfiltered. */ + unsigned char phase; /* Interlacing phase (0..6). */ + Tk_PhotoImageBlock block; + int blockLen; /* Number of bytes in Tk image pixels. */ + + /* + * For containing data read from PLTE (palette) and tRNS (transparency) + * chunks. + */ + + int paletteLen; /* Number of PLTE entries (1..256). */ + int useTRNS; /* Flag to indicate whether there was a + * palette given. */ + struct { + unsigned char red; + unsigned char green; + unsigned char blue; + unsigned char alpha; + } palette[256]; /* Palette RGB/Transparency table. */ + unsigned char transVal[6]; /* Fully-transparent RGB/Gray Value. */ + + /* + * For compressing and decompressing IDAT chunks. + */ + + Tcl_ZlibStream stream; /* Inflating or deflating stream; this one is + * not bound to a Tcl command. */ + Tcl_Obj *lastLineObj; /* Last line of pixels, for unfiltering. */ + Tcl_Obj *thisLineObj; /* Current line of pixels to process. */ + int lineSize; /* Number of bytes in a PNG line. */ + int phaseSize; /* Number of bytes/line in current phase. */ +} PNGImage; + +/* + * Maximum size of various chunks. + */ + +#define PNG_PLTE_MAXSZ 768 /* 3 bytes/RGB entry, 256 entries max */ +#define PNG_TRNS_MAXSZ 256 /* 1-byte alpha, 256 entries max */ + +/* + * Forward declarations of non-global functions defined in this file: + */ + +static void ApplyAlpha(PNGImage *pngPtr); +static int CheckColor(Tcl_Interp *interp, PNGImage *pngPtr); +static inline int CheckCRC(Tcl_Interp *interp, PNGImage *pngPtr, + unsigned long calculated); +static void CleanupPNGImage(PNGImage *pngPtr); +static int DecodeLine(Tcl_Interp *interp, PNGImage *pngPtr); +static int DecodePNG(Tcl_Interp *interp, PNGImage *pngPtr, + Tcl_Obj *fmtObj, Tk_PhotoHandle imageHandle, + int destX, int destY); +static int EncodePNG(Tcl_Interp *interp, + Tk_PhotoImageBlock *blockPtr, PNGImage *pngPtr); +static int FileMatchPNG(Tcl_Channel chan, const char *fileName, + Tcl_Obj *fmtObj, int *widthPtr, int *heightPtr, + Tcl_Interp *interp); +static int FileReadPNG(Tcl_Interp *interp, Tcl_Channel chan, + const char *fileName, Tcl_Obj *fmtObj, + Tk_PhotoHandle imageHandle, int destX, int destY, + int width, int height, int srcX, int srcY); +static int FileWritePNG(Tcl_Interp *interp, const char *filename, + Tcl_Obj *fmtObj, Tk_PhotoImageBlock *blockPtr); +static int InitPNGImage(Tcl_Interp *interp, PNGImage *pngPtr, + Tcl_Channel chan, Tcl_Obj *objPtr, int dir); +static inline unsigned char Paeth(int a, int b, int c); +static int ParseFormat(Tcl_Interp *interp, Tcl_Obj *fmtObj, + PNGImage *pngPtr); +static int ReadBase64(Tcl_Interp *interp, PNGImage *pngPtr, + unsigned char *destPtr, int destSz, + unsigned long *crcPtr); +static int ReadByteArray(Tcl_Interp *interp, PNGImage *pngPtr, + unsigned char *destPtr, int destSz, + unsigned long *crcPtr); +static int ReadData(Tcl_Interp *interp, PNGImage *pngPtr, + unsigned char *destPtr, int destSz, + unsigned long *crcPtr); +static int ReadChunkHeader(Tcl_Interp *interp, PNGImage *pngPtr, + int *sizePtr, unsigned long *typePtr, + unsigned long *crcPtr); +static int ReadIDAT(Tcl_Interp *interp, PNGImage *pngPtr, + int chunkSz, unsigned long crc); +static int ReadIHDR(Tcl_Interp *interp, PNGImage *pngPtr); +static inline int ReadInt32(Tcl_Interp *interp, PNGImage *pngPtr, + unsigned long *resultPtr, unsigned long *crcPtr); +static int ReadPLTE(Tcl_Interp *interp, PNGImage *pngPtr, + int chunkSz, unsigned long crc); +static int ReadTRNS(Tcl_Interp *interp, PNGImage *pngPtr, + int chunkSz, unsigned long crc); +static int SkipChunk(Tcl_Interp *interp, PNGImage *pngPtr, + int chunkSz, unsigned long crc); +static int StringMatchPNG(Tcl_Obj *dataObj, Tcl_Obj *fmtObj, + int *widthPtr, int *heightPtr, + Tcl_Interp *interp); +static int StringReadPNG(Tcl_Interp *interp, Tcl_Obj *dataObj, + Tcl_Obj *fmtObj, Tk_PhotoHandle imageHandle, + int destX, int destY, int width, int height, + int srcX, int srcY); +static int StringWritePNG(Tcl_Interp *interp, Tcl_Obj *fmtObj, + Tk_PhotoImageBlock *blockPtr); +static int UnfilterLine(Tcl_Interp *interp, PNGImage *pngPtr); +static inline int WriteByte(Tcl_Interp *interp, PNGImage *pngPtr, + unsigned char c, unsigned long *crcPtr); +static inline int WriteChunk(Tcl_Interp *interp, PNGImage *pngPtr, + unsigned long chunkType, + const unsigned char *dataPtr, int dataSize); +static int WriteData(Tcl_Interp *interp, PNGImage *pngPtr, + const unsigned char *srcPtr, int srcSz, + unsigned long *crcPtr); +static int WriteExtraChunks(Tcl_Interp *interp, + PNGImage *pngPtr); +static int WriteIHDR(Tcl_Interp *interp, PNGImage *pngPtr, + Tk_PhotoImageBlock *blockPtr); +static int WriteIDAT(Tcl_Interp *interp, PNGImage *pngPtr, + Tk_PhotoImageBlock *blockPtr); +static inline int WriteInt32(Tcl_Interp *interp, PNGImage *pngPtr, + unsigned long l, unsigned long *crcPtr); + +/* + * The format record for the PNG file format: + */ + +Tk_PhotoImageFormat tkImgFmtPNG = { + "png", /* name */ + FileMatchPNG, /* fileMatchProc */ + StringMatchPNG, /* stringMatchProc */ + FileReadPNG, /* fileReadProc */ + StringReadPNG, /* stringReadProc */ + FileWritePNG, /* fileWriteProc */ + StringWritePNG, /* stringWriteProc */ + NULL +}; + +/* + *---------------------------------------------------------------------- + * + * InitPNGImage -- + * + * This function is invoked by each of the Tk image handler procs + * (MatchStringProc, etc.) to initialize state information used during + * the course of encoding or decoding a PNG image. + * + * Results: + * TCL_OK, or TCL_ERROR if initialization failed. + * + * Side effects: + * The reference count of the -data Tcl_Obj*, if any, is incremented. + * + *---------------------------------------------------------------------- + */ + +static int +InitPNGImage( + Tcl_Interp *interp, + PNGImage *pngPtr, + Tcl_Channel chan, + Tcl_Obj *objPtr, + int dir) +{ + memset(pngPtr, 0, sizeof(PNGImage)); + + pngPtr->channel = chan; + pngPtr->alpha = 1.0; + + /* + * If decoding from a -data string object, increment its reference count + * for the duration of the decode and get its length and byte array for + * reading with ReadData(). + */ + + if (objPtr) { + Tcl_IncrRefCount(objPtr); + pngPtr->objDataPtr = objPtr; + pngPtr->strDataBuf = + Tcl_GetByteArrayFromObj(objPtr, &pngPtr->strDataLen); + } + + /* + * Initialize the palette transparency table to fully opaque. + */ + + memset(pngPtr->palette, 255, sizeof(pngPtr->palette)); + + /* + * Initialize Zlib inflate/deflate stream. + */ + + if (Tcl_ZlibStreamInit(NULL, dir, TCL_ZLIB_FORMAT_ZLIB, + TCL_ZLIB_COMPRESS_DEFAULT, NULL, &pngPtr->stream) != TCL_OK) { + if (interp) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "zlib initialization failed", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "ZLIB_INIT", NULL); + } + if (objPtr) { + Tcl_DecrRefCount(objPtr); + } + return TCL_ERROR; + } + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * CleanupPNGImage -- + * + * This function is invoked by each of the Tk image handler procs + * (MatchStringProc, etc.) prior to returning to Tcl in order to clean up + * any allocated memory and call other cleanup handlers such as zlib's + * inflateEnd/deflateEnd. + * + * Results: + * None. + * + * Side effects: + * The reference count of the -data Tcl_Obj*, if any, is decremented. + * Buffers are freed, streams are closed. The PNGImage should not be used + * for any purpose without being reinitialized post-cleanup. + * + *---------------------------------------------------------------------- + */ + +static void +CleanupPNGImage( + PNGImage *pngPtr) +{ + /* + * Don't need the object containing the -data value anymore. + */ + + if (pngPtr->objDataPtr) { + Tcl_DecrRefCount(pngPtr->objDataPtr); + } + + /* + * Discard pixel buffer. + */ + + if (pngPtr->stream) { + Tcl_ZlibStreamClose(pngPtr->stream); + } + + if (pngPtr->block.pixelPtr) { + ckfree(pngPtr->block.pixelPtr); + } + if (pngPtr->thisLineObj) { + Tcl_DecrRefCount(pngPtr->thisLineObj); + } + if (pngPtr->lastLineObj) { + Tcl_DecrRefCount(pngPtr->lastLineObj); + } + + memset(pngPtr, 0, sizeof(PNGImage)); +} + +/* + *---------------------------------------------------------------------- + * + * ReadBase64 -- + * + * This function is invoked to read the specified number of bytes from + * base-64 encoded image data. + * + * Note: It would be better if the Tk_PhotoImage stuff handled this by + * creating a channel from the -data value, which would take care of + * base64 decoding and made the data readable as if it were coming from a + * file. + * + * Results: + * TCL_OK, or TCL_ERROR if an I/O error occurs. + * + * Side effects: + * The file position will change. The running CRC is updated if a pointer + * to it is provided. + * + *---------------------------------------------------------------------- + */ + +static int +ReadBase64( + Tcl_Interp *interp, + PNGImage *pngPtr, + unsigned char *destPtr, + int destSz, + unsigned long *crcPtr) +{ + static const unsigned char from64[] = { + 0x82, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x80, 0x80, + 0x83, 0x80, 0x80, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, + 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x80, + 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x3e, + 0x83, 0x83, 0x83, 0x3f, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, + 0x3b, 0x3c, 0x3d, 0x83, 0x83, 0x83, 0x81, 0x83, 0x83, 0x83, 0x00, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, + 0x32, 0x33, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, + 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, + 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, + 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, + 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, + 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, + 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, + 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, + 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, + 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, + 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, + 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, + 0x83, 0x83 + }; + + /* + * Definitions for the base-64 decoder. + */ + +#define PNG64_SPECIAL 0x80 /* Flag bit */ +#define PNG64_SPACE 0x80 /* Whitespace */ +#define PNG64_PAD 0x81 /* Padding */ +#define PNG64_DONE 0x82 /* End of data */ +#define PNG64_BAD 0x83 /* Ooooh, naughty! */ + + while (destSz && pngPtr->strDataLen) { + unsigned char c = 0; + unsigned char c64 = from64[*pngPtr->strDataBuf++]; + + pngPtr->strDataLen--; + + if (PNG64_SPACE == c64) { + continue; + } + + if (c64 & PNG64_SPECIAL) { + c = (unsigned char) pngPtr->base64Bits; + } else { + switch (pngPtr->base64State++) { + case 0: + pngPtr->base64Bits = c64 << 2; + continue; + case 1: + c = (unsigned char) (pngPtr->base64Bits | (c64 >> 4)); + pngPtr->base64Bits = (c64 & 0xF) << 4; + break; + case 2: + c = (unsigned char) (pngPtr->base64Bits | (c64 >> 2)); + pngPtr->base64Bits = (c64 & 0x3) << 6; + break; + case 3: + c = (unsigned char) (pngPtr->base64Bits | c64); + pngPtr->base64State = 0; + pngPtr->base64Bits = 0; + break; + } + } + + if (crcPtr) { + *crcPtr = Tcl_ZlibCRC32(*crcPtr, &c, 1); + } + + if (destPtr) { + *destPtr++ = c; + } + + destSz--; + + if (c64 & PNG64_SPECIAL) { + break; + } + } + + if (destSz) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "unexpected end of image data", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EARLY_END", NULL); + return TCL_ERROR; + } + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * ReadByteArray -- + * + * This function is invoked to read the specified number of bytes from a + * non-base64-encoded byte array provided via the -data option. + * + * Note: It would be better if the Tk_PhotoImage stuff handled this by + * creating a channel from the -data value and made the data readable as + * if it were coming from a file. + * + * Results: + * TCL_OK, or TCL_ERROR if an I/O error occurs. + * + * Side effects: + * The file position will change. The running CRC is updated if a pointer + * to it is provided. + * + *---------------------------------------------------------------------- + */ + +static int +ReadByteArray( + Tcl_Interp *interp, + PNGImage *pngPtr, + unsigned char *destPtr, + int destSz, + unsigned long *crcPtr) +{ + /* + * Check to make sure the number of requested bytes are available. + */ + + if (pngPtr->strDataLen < destSz) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "unexpected end of image data", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EARLY_END", NULL); + return TCL_ERROR; + } + + while (destSz) { + int blockSz = PNG_MIN(destSz, PNG_BLOCK_SZ); + + memcpy(destPtr, pngPtr->strDataBuf, blockSz); + + pngPtr->strDataBuf += blockSz; + pngPtr->strDataLen -= blockSz; + + if (crcPtr) { + *crcPtr = Tcl_ZlibCRC32(*crcPtr, destPtr, blockSz); + } + + destPtr += blockSz; + destSz -= blockSz; + } + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * ReadData -- + * + * This function is invoked to read the specified number of bytes from + * the image file or data. It is a wrapper around the choice of byte + * array Tcl_Obj or Tcl_Channel which depends on whether the image data + * is coming from a file or -data. + * + * Results: + * TCL_OK, or TCL_ERROR if an I/O error occurs. + * + * Side effects: + * The file position will change. The running CRC is updated if a pointer + * to it is provided. + * + *---------------------------------------------------------------------- + */ + +static int +ReadData( + Tcl_Interp *interp, + PNGImage *pngPtr, + unsigned char *destPtr, + int destSz, + unsigned long *crcPtr) +{ + if (pngPtr->base64Data) { + return ReadBase64(interp, pngPtr, destPtr, destSz, crcPtr); + } else if (pngPtr->strDataBuf) { + return ReadByteArray(interp, pngPtr, destPtr, destSz, crcPtr); + } + + while (destSz) { + int blockSz = PNG_MIN(destSz, PNG_BLOCK_SZ); + + blockSz = Tcl_Read(pngPtr->channel, (char *)destPtr, blockSz); + if (blockSz < 0) { + /* TODO: failure info... */ + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "channel read failed: %s", Tcl_PosixError(interp))); + return TCL_ERROR; + } + + /* + * Update CRC, pointer, and remaining count if anything was read. + */ + + if (blockSz) { + if (crcPtr) { + *crcPtr = Tcl_ZlibCRC32(*crcPtr, destPtr, blockSz); + } + + destPtr += blockSz; + destSz -= blockSz; + } + + /* + * Check for EOF before all desired data was read. + */ + + if (destSz && Tcl_Eof(pngPtr->channel)) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "unexpected end of file", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EOF", NULL); + return TCL_ERROR; + } + } + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * ReadInt32 -- + * + * This function is invoked to read a 32-bit integer in network byte + * order from the image data and return the value in host byte order. + * This is used, for example, to read the 32-bit CRC value for a chunk + * stored in the image file for comparison with the calculated CRC value. + * + * Results: + * TCL_OK, or TCL_ERROR if an I/O error occurs. + * + * Side effects: + * The file position will change. The running CRC is updated if a pointer + * to it is provided. + * + *---------------------------------------------------------------------- + */ + +static inline int +ReadInt32( + Tcl_Interp *interp, + PNGImage *pngPtr, + unsigned long *resultPtr, + unsigned long *crcPtr) +{ + unsigned char p[4]; + + if (ReadData(interp, pngPtr, p, 4, crcPtr) == TCL_ERROR) { + return TCL_ERROR; + } + + *resultPtr = PNG_INT32(p[0], p[1], p[2], p[3]); + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * CheckCRC -- + * + * This function is reads the final 4-byte integer CRC from a chunk and + * compares it to the running CRC calculated over the chunk type and data + * fields. + * + * Results: + * TCL_OK, or TCL_ERROR if an I/O error or CRC mismatch occurs. + * + * Side effects: + * The file position will change. + * + *---------------------------------------------------------------------- + */ + +static inline int +CheckCRC( + Tcl_Interp *interp, + PNGImage *pngPtr, + unsigned long calculated) +{ + unsigned long chunked; + + /* + * Read the CRC field at the end of the chunk. + */ + + if (ReadInt32(interp, pngPtr, &chunked, NULL) == TCL_ERROR) { + return TCL_ERROR; + } + + /* + * Compare the read CRC to what we calculate to make sure they match. + */ + + if (calculated != chunked) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("CRC check failed", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "CRC", NULL); + return TCL_ERROR; + } + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * SkipChunk -- + * + * This function is used to skip a PNG chunk that is not used by this + * implementation. Given the input stream has had the chunk length and + * chunk type fields already read, this function will read the number of + * bytes indicated by the chunk length, plus four for the CRC, and will + * verify that CRC is correct for the skipped data. + * + * Results: + * TCL_OK, or TCL_ERROR if an I/O error or CRC mismatch occurs. + * + * Side effects: + * The file position will change. + * + *---------------------------------------------------------------------- + */ + +static int +SkipChunk( + Tcl_Interp *interp, + PNGImage *pngPtr, + int chunkSz, + unsigned long crc) +{ + unsigned char buffer[PNG_BLOCK_SZ]; + + /* + * Skip data in blocks until none is left. Read up to PNG_BLOCK_SZ bytes + * at a time, rather than trusting the claimed chunk size, which may not + * be trustworthy. + */ + + while (chunkSz) { + int blockSz = PNG_MIN(chunkSz, PNG_BLOCK_SZ); + + if (ReadData(interp, pngPtr, buffer, blockSz, &crc) == TCL_ERROR) { + return TCL_ERROR; + } + + chunkSz -= blockSz; + } + + if (CheckCRC(interp, pngPtr, crc) == TCL_ERROR) { + return TCL_ERROR; + } + + return TCL_OK; +} + +/* + * 4.3. Summary of standard chunks + * + * This table summarizes some properties of the standard chunk types. + * + * Critical chunks (must appear in this order, except PLTE is optional): + * + * Name Multiple Ordering constraints OK? + * + * IHDR No Must be first + * PLTE No Before IDAT + * IDAT Yes Multiple IDATs must be consecutive + * IEND No Must be last + * + * Ancillary chunks (need not appear in this order): + * + * Name Multiple Ordering constraints OK? + * + * cHRM No Before PLTE and IDAT + * gAMA No Before PLTE and IDAT + * iCCP No Before PLTE and IDAT + * sBIT No Before PLTE and IDAT + * sRGB No Before PLTE and IDAT + * bKGD No After PLTE; before IDAT + * hIST No After PLTE; before IDAT + * tRNS No After PLTE; before IDAT + * pHYs No Before IDAT + * sPLT Yes Before IDAT + * tIME No None + * iTXt Yes None + * tEXt Yes None + * zTXt Yes None + * + * [From the PNG specification.] + */ + +/* + *---------------------------------------------------------------------- + * + * ReadChunkHeader -- + * + * This function is used at the start of each chunk to extract the + * four-byte chunk length and four-byte chunk type fields. It will + * continue reading until it finds a chunk type that is handled by this + * implementation, checking the CRC of any chunks it skips. + * + * Results: + * TCL_OK, or TCL_ERROR if an I/O error occurs or an unknown critical + * chunk type is encountered. + * + * Side effects: + * The file position will change. The running CRC is updated. + * + *---------------------------------------------------------------------- + */ + +static int +ReadChunkHeader( + Tcl_Interp *interp, + PNGImage *pngPtr, + int *sizePtr, + unsigned long *typePtr, + unsigned long *crcPtr) +{ + unsigned long chunkType = 0; + int chunkSz = 0; + unsigned long crc = 0; + + /* + * Continue until finding a chunk type that is handled. + */ + + while (!chunkType) { + unsigned long temp; + unsigned char pc[4]; + int i; + + /* + * Read the 4-byte length field for the chunk. The length field is not + * included in the CRC calculation, so the running CRC must be reset + * afterward. Limit chunk lengths to INT_MAX, to align with the + * maximum size for Tcl_Read, Tcl_GetByteArrayFromObj, etc. + */ + + if (ReadData(interp, pngPtr, pc, 4, NULL) == TCL_ERROR) { + return TCL_ERROR; + } + + temp = PNG_INT32(pc[0], pc[1], pc[2], pc[3]); + + if (temp > INT_MAX) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "chunk size is out of supported range on this architecture", + -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "OUTSIZE", NULL); + return TCL_ERROR; + } + + chunkSz = (int) temp; + crc = Tcl_ZlibCRC32(0, NULL, 0); + + /* + * Read the 4-byte chunk type. + */ + + if (ReadData(interp, pngPtr, pc, 4, &crc) == TCL_ERROR) { + return TCL_ERROR; + } + + /* + * Convert it to a host-order integer for simple comparison. + */ + + chunkType = PNG_INT32(pc[0], pc[1], pc[2], pc[3]); + + /* + * Check to see if this is a known/supported chunk type. Note that the + * PNG specs require non-critical (i.e., ancillary) chunk types that + * are not recognized to be ignored, rather than be treated as an + * error. It does, however, recommend that an unknown critical chunk + * type be treated as a failure. + * + * This switch/loop acts as a filter of sorts for undesired chunk + * types. The chunk type should still be checked elsewhere for + * determining it is in the correct order. + */ + + switch (chunkType) { + /* + * These chunk types are required and/or supported. + */ + + case CHUNK_IDAT: + case CHUNK_IEND: + case CHUNK_IHDR: + case CHUNK_PLTE: + case CHUNK_tRNS: + break; + + /* + * These chunk types are part of the standard, but are not used by + * this implementation (at least not yet). Note that these are all + * ancillary chunks (lowercase first letter). + */ + + case CHUNK_bKGD: + case CHUNK_cHRM: + case CHUNK_gAMA: + case CHUNK_hIST: + case CHUNK_iCCP: + case CHUNK_iTXt: + case CHUNK_oFFs: + case CHUNK_pCAL: + case CHUNK_pHYs: + case CHUNK_sBIT: + case CHUNK_sCAL: + case CHUNK_sPLT: + case CHUNK_sRGB: + case CHUNK_tEXt: + case CHUNK_tIME: + case CHUNK_zTXt: + /* + * TODO: might want to check order here. + */ + + if (SkipChunk(interp, pngPtr, chunkSz, crc) == TCL_ERROR) { + return TCL_ERROR; + } + + chunkType = 0; + break; + + default: + /* + * Unknown chunk type. If it's critical, we can't continue. + */ + + if (!(chunkType & PNG_CF_ANCILLARY)) { + if (chunkType & PNG_INT32(128,128,128,128)) { + /* + * No nice ASCII conversion; shouldn't happen either, but + * we'll be doubly careful. + */ + + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "encountered an unsupported critical chunk type", + -1)); + } else { + char typeString[5]; + + typeString[0] = (char) ((chunkType >> 24) & 255); + typeString[1] = (char) ((chunkType >> 16) & 255); + typeString[2] = (char) ((chunkType >> 8) & 255); + typeString[3] = (char) (chunkType & 255); + typeString[4] = '\0'; + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "encountered an unsupported critical chunk type" + " \"%s\"", typeString)); + } + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", + "UNSUPPORTED_CRITICAL", NULL); + return TCL_ERROR; + } + + /* + * Check to see if the chunk type has legal bytes. + */ + + for (i=0 ; i<4 ; i++) { + if ((pc[i] < 65) || (pc[i] > 122) || + ((pc[i] > 90) && (pc[i] < 97))) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "invalid chunk type", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", + "INVALID_CHUNK", NULL); + return TCL_ERROR; + } + } + + /* + * It seems to be an otherwise legally labelled ancillary chunk + * that we don't want, so skip it after at least checking its CRC. + */ + + if (SkipChunk(interp, pngPtr, chunkSz, crc) == TCL_ERROR) { + return TCL_ERROR; + } + + chunkType = 0; + } + } + + /* + * Found a known chunk type that's handled, albiet possibly not in the + * right order. Send back the chunk type (for further checking or + * handling), the chunk size and the current CRC for the rest of the + * calculation. + */ + + *typePtr = chunkType; + *sizePtr = chunkSz; + *crcPtr = crc; + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * CheckColor -- + * + * Do validation on color type, depth, and related information, and + * calculates storage requirements and offsets based on image dimensions + * and color. + * + * Results: + * TCL_OK, or TCL_ERROR if color information is invalid or some other + * failure occurs. + * + * Side effects: + * None + * + *---------------------------------------------------------------------- + */ + +static int +CheckColor( + Tcl_Interp *interp, + PNGImage *pngPtr) +{ + int offset; + + /* + * Verify the color type is valid and the bit depth is allowed. + */ + + switch (pngPtr->colorType) { + case PNG_COLOR_GRAY: + pngPtr->numChannels = 1; + if ((1 != pngPtr->bitDepth) && (2 != pngPtr->bitDepth) && + (4 != pngPtr->bitDepth) && (8 != pngPtr->bitDepth) && + (16 != pngPtr->bitDepth)) { + goto unsupportedDepth; + } + break; + + case PNG_COLOR_RGB: + pngPtr->numChannels = 3; + if ((8 != pngPtr->bitDepth) && (16 != pngPtr->bitDepth)) { + goto unsupportedDepth; + } + break; + + case PNG_COLOR_PLTE: + pngPtr->numChannels = 1; + if ((1 != pngPtr->bitDepth) && (2 != pngPtr->bitDepth) && + (4 != pngPtr->bitDepth) && (8 != pngPtr->bitDepth)) { + goto unsupportedDepth; + } + break; + + case PNG_COLOR_GRAYALPHA: + pngPtr->numChannels = 2; + if ((8 != pngPtr->bitDepth) && (16 != pngPtr->bitDepth)) { + goto unsupportedDepth; + } + break; + + case PNG_COLOR_RGBA: + pngPtr->numChannels = 4; + if ((8 != pngPtr->bitDepth) && (16 != pngPtr->bitDepth)) { + unsupportedDepth: + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "bit depth is not allowed for given color type", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_DEPTH", NULL); + return TCL_ERROR; + } + break; + + default: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "unknown color type field %d", pngPtr->colorType)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "UNKNOWN_COLOR", NULL); + return TCL_ERROR; + } + + /* + * Set up the Tk photo block's pixel size and channel offsets. offset + * array elements should already be 0 from the memset during InitPNGImage. + */ + + offset = (pngPtr->bitDepth > 8) ? 2 : 1; + + if (pngPtr->colorType & PNG_COLOR_USED) { + pngPtr->block.pixelSize = offset * 4; + pngPtr->block.offset[1] = offset; + pngPtr->block.offset[2] = offset * 2; + pngPtr->block.offset[3] = offset * 3; + } else { + pngPtr->block.pixelSize = offset * 2; + pngPtr->block.offset[3] = offset; + } + + /* + * Calculate the block pitch, which is the number of bytes per line in the + * image, given image width and depth of color. Make sure that it it isn't + * larger than Tk can handle. + */ + + if (pngPtr->block.width > INT_MAX / pngPtr->block.pixelSize) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "image pitch is out of supported range on this architecture", + -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "PITCH", NULL); + return TCL_ERROR; + } + + pngPtr->block.pitch = pngPtr->block.pixelSize * pngPtr->block.width; + + /* + * Calculate the total size of the image as represented to Tk given pitch + * and image height. Make sure that it isn't larger than Tk can handle. + */ + + if (pngPtr->block.height > INT_MAX / pngPtr->block.pitch) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "image total size is out of supported range on this architecture", + -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "SIZE", NULL); + return TCL_ERROR; + } + + pngPtr->blockLen = pngPtr->block.height * pngPtr->block.pitch; + + /* + * Determine number of bytes per pixel in the source for later use. + */ + + switch (pngPtr->colorType) { + case PNG_COLOR_GRAY: + pngPtr->bytesPerPixel = (pngPtr->bitDepth > 8) ? 2 : 1; + break; + case PNG_COLOR_RGB: + pngPtr->bytesPerPixel = (pngPtr->bitDepth > 8) ? 6 : 3; + break; + case PNG_COLOR_PLTE: + pngPtr->bytesPerPixel = 1; + break; + case PNG_COLOR_GRAYALPHA: + pngPtr->bytesPerPixel = (pngPtr->bitDepth > 8) ? 4 : 2; + break; + case PNG_COLOR_RGBA: + pngPtr->bytesPerPixel = (pngPtr->bitDepth > 8) ? 8 : 4; + break; + default: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "unknown color type %d", pngPtr->colorType)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "UNKNOWN_COLOR", NULL); + return TCL_ERROR; + } + + /* + * Calculate scale factor for bit depths less than 8, in order to adjust + * them to a minimum of 8 bits per pixel in the Tk image. + */ + + if (pngPtr->bitDepth < 8) { + pngPtr->bitScale = 255 / (int)(pow(2, pngPtr->bitDepth) - 1); + } else { + pngPtr->bitScale = 1; + } + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * ReadIHDR -- + * + * This function reads the PNG header from the beginning of a PNG file + * and returns the dimensions of the image. + * + * Results: + * The return value is 1 if file "f" appears to start with a valid PNG + * header, 0 otherwise. If the header is valid, then *widthPtr and + * *heightPtr are modified to hold the dimensions of the image. + * + * Side effects: + * The access position in f advances. + * + *---------------------------------------------------------------------- + */ + +static int +ReadIHDR( + Tcl_Interp *interp, + PNGImage *pngPtr) +{ + unsigned char sigBuf[PNG_SIG_SZ]; + unsigned long chunkType; + int chunkSz; + unsigned long crc; + unsigned long width, height; + int mismatch; + + /* + * Read the appropriate number of bytes for the PNG signature. + */ + + if (ReadData(interp, pngPtr, sigBuf, PNG_SIG_SZ, NULL) == TCL_ERROR) { + return TCL_ERROR; + } + + /* + * Compare the read bytes to the expected signature. + */ + + mismatch = memcmp(sigBuf, pngSignature, PNG_SIG_SZ); + + /* + * If reading from string, reset position and try base64 decode. + */ + + if (mismatch && pngPtr->strDataBuf) { + pngPtr->strDataBuf = Tcl_GetByteArrayFromObj(pngPtr->objDataPtr, + &pngPtr->strDataLen); + pngPtr->base64Data = pngPtr->strDataBuf; + + if (ReadData(interp, pngPtr, sigBuf, PNG_SIG_SZ, NULL) == TCL_ERROR) { + return TCL_ERROR; + } + + mismatch = memcmp(sigBuf, pngSignature, PNG_SIG_SZ); + } + + if (mismatch) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "data stream does not have a PNG signature", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "NO_SIG", NULL); + return TCL_ERROR; + } + + if (ReadChunkHeader(interp, pngPtr, &chunkSz, &chunkType, + &crc) == TCL_ERROR) { + return TCL_ERROR; + } + + /* + * Read in the IHDR (header) chunk for width, height, etc. + * + * The first chunk in the file must be the IHDR (headr) chunk. + */ + + if (chunkType != CHUNK_IHDR) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "expected IHDR chunk type", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "NO_IHDR", NULL); + return TCL_ERROR; + } + + if (chunkSz != 13) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "invalid IHDR chunk size", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_IHDR", NULL); + return TCL_ERROR; + } + + /* + * Read and verify the image width and height to be sure Tk can handle its + * dimensions. The PNG specification does not permit zero-width or + * zero-height images. + */ + + if (ReadInt32(interp, pngPtr, &width, &crc) == TCL_ERROR) { + return TCL_ERROR; + } + + if (ReadInt32(interp, pngPtr, &height, &crc) == TCL_ERROR) { + return TCL_ERROR; + } + + if (!width || !height || (width > INT_MAX) || (height > INT_MAX)) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "image dimensions are invalid or beyond architecture limits", + -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "DIMENSIONS", NULL); + return TCL_ERROR; + } + + /* + * Set height and width for the Tk photo block. + */ + + pngPtr->block.width = (int) width; + pngPtr->block.height = (int) height; + + /* + * Read and the Bit Depth and Color Type. + */ + + if (ReadData(interp, pngPtr, &pngPtr->bitDepth, 1, &crc) == TCL_ERROR) { + return TCL_ERROR; + } + + if (ReadData(interp, pngPtr, &pngPtr->colorType, 1, &crc) == TCL_ERROR) { + return TCL_ERROR; + } + + /* + * Verify that the color type is valid, the bit depth is allowed for the + * color type, and calculate the number of channels and pixel depth (bits + * per pixel * channels). Also set up offsets and sizes in the Tk photo + * block for the pixel data. + */ + + if (CheckColor(interp, pngPtr) == TCL_ERROR) { + return TCL_ERROR; + } + + /* + * Only one compression method is currently defined by the standard. + */ + + if (ReadData(interp, pngPtr, &pngPtr->compression, 1, &crc) == TCL_ERROR) { + return TCL_ERROR; + } + + if (pngPtr->compression != PNG_COMPRESS_DEFLATE) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "unknown compression method %d", pngPtr->compression)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_COMPRESS", NULL); + return TCL_ERROR; + } + + /* + * Only one filter method is currently defined by the standard; the method + * has five actual filter types associated with it. + */ + + if (ReadData(interp, pngPtr, &pngPtr->filter, 1, &crc) == TCL_ERROR) { + return TCL_ERROR; + } + + if (pngPtr->filter != PNG_FILTMETH_STANDARD) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "unknown filter method %d", pngPtr->filter)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_FILTER", NULL); + return TCL_ERROR; + } + + if (ReadData(interp, pngPtr, &pngPtr->interlace, 1, &crc) == TCL_ERROR) { + return TCL_ERROR; + } + + switch (pngPtr->interlace) { + case PNG_INTERLACE_NONE: + case PNG_INTERLACE_ADAM7: + break; + + default: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "unknown interlace method %d", pngPtr->interlace)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_INTERLACE", NULL); + return TCL_ERROR; + } + + return CheckCRC(interp, pngPtr, crc); +} + +/* + *---------------------------------------------------------------------- + * + * ReadPLTE -- + * + * This function reads the PLTE (indexed color palette) chunk data from + * the PNG file and populates the palette table in the PNGImage + * structure. + * + * Results: + * TCL_OK, or TCL_ERROR if an I/O error occurs or the PLTE chunk is + * invalid. + * + * Side effects: + * The access position in f advances. + * + *---------------------------------------------------------------------- + */ + +static int +ReadPLTE( + Tcl_Interp *interp, + PNGImage *pngPtr, + int chunkSz, + unsigned long crc) +{ + unsigned char buffer[PNG_PLTE_MAXSZ]; + int i, c; + + /* + * This chunk is mandatory for color type 3 and forbidden for 2 and 6. + */ + + switch (pngPtr->colorType) { + case PNG_COLOR_GRAY: + case PNG_COLOR_GRAYALPHA: + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "PLTE chunk type forbidden for grayscale", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "PLTE_UNEXPECTED", + NULL); + return TCL_ERROR; + + default: + break; + } + + /* + * The palette chunk contains from 1 to 256 palette entries. Each entry + * consists of a 3-byte RGB value. It must therefore contain a non-zero + * multiple of 3 bytes, up to 768. + */ + + if (!chunkSz || (chunkSz > PNG_PLTE_MAXSZ) || (chunkSz % 3)) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "invalid palette chunk size", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_PLTE", NULL); + return TCL_ERROR; + } + + /* + * Read the palette contents and stash them for later, possibly. + */ + + if (ReadData(interp, pngPtr, buffer, chunkSz, &crc) == TCL_ERROR) { + return TCL_ERROR; + } + + if (CheckCRC(interp, pngPtr, crc) == TCL_ERROR) { + return TCL_ERROR; + } + + /* + * Stash away the palette entries and entry count for later mapping each + * pixel's palette index to its color. + */ + + for (i=0, c=0 ; c<chunkSz ; i++) { + pngPtr->palette[i].red = buffer[c++]; + pngPtr->palette[i].green = buffer[c++]; + pngPtr->palette[i].blue = buffer[c++]; + } + + pngPtr->paletteLen = i; + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * ReadTRNS -- + * + * This function reads the tRNS (transparency) chunk data from the PNG + * file and populates the alpha field of the palette table in the + * PNGImage structure or the single color transparency, as appropriate + * for the color type. + * + * Results: + * TCL_OK, or TCL_ERROR if an I/O error occurs or the tRNS chunk is + * invalid. + * + * Side effects: + * The access position in f advances. + * + *---------------------------------------------------------------------- + */ + +static int +ReadTRNS( + Tcl_Interp *interp, + PNGImage *pngPtr, + int chunkSz, + unsigned long crc) +{ + unsigned char buffer[PNG_TRNS_MAXSZ]; + int i; + + if (pngPtr->colorType & PNG_COLOR_ALPHA) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "tRNS chunk not allowed color types with a full alpha channel", + -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "INVALID_TRNS", NULL); + return TCL_ERROR; + } + + /* + * For indexed color, there is up to one single-byte transparency value + * per palette entry (thus a max of 256). + */ + + if (chunkSz > PNG_TRNS_MAXSZ) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "invalid tRNS chunk size", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_TRNS", NULL); + return TCL_ERROR; + } + + /* + * Read in the raw transparency information. + */ + + if (ReadData(interp, pngPtr, buffer, chunkSz, &crc) == TCL_ERROR) { + return TCL_ERROR; + } + + if (CheckCRC(interp, pngPtr, crc) == TCL_ERROR) { + return TCL_ERROR; + } + + switch (pngPtr->colorType) { + case PNG_COLOR_GRAYALPHA: + case PNG_COLOR_RGBA: + break; + + case PNG_COLOR_PLTE: + /* + * The number of tRNS entries must be less than or equal to the number + * of PLTE entries, and consists of a single-byte alpha level for the + * corresponding PLTE entry. + */ + + if (chunkSz > pngPtr->paletteLen) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "size of tRNS chunk is too large for the palette", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "TRNS_SIZE", NULL); + return TCL_ERROR; + } + + for (i=0 ; i<chunkSz ; i++) { + pngPtr->palette[i].alpha = buffer[i]; + } + break; + + case PNG_COLOR_GRAY: + /* + * Grayscale uses a single 2-byte gray level, which we'll store in + * palette index 0, since we're not using the palette. + */ + + if (chunkSz != 2) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "invalid tRNS chunk size - must 2 bytes for grayscale", + -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_TRNS", NULL); + return TCL_ERROR; + } + + /* + * According to the PNG specs, if the bit depth is less than 16, then + * only the lower byte is used. + */ + + if (16 == pngPtr->bitDepth) { + pngPtr->transVal[0] = buffer[0]; + pngPtr->transVal[1] = buffer[1]; + } else { + pngPtr->transVal[0] = buffer[1]; + } + pngPtr->useTRNS = 1; + break; + + case PNG_COLOR_RGB: + /* + * TrueColor uses a single RRGGBB triplet. + */ + + if (chunkSz != 6) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "invalid tRNS chunk size - must 6 bytes for RGB", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_TRNS", NULL); + return TCL_ERROR; + } + + /* + * According to the PNG specs, if the bit depth is less than 16, then + * only the lower byte is used. But the tRNS chunk still contains two + * bytes per channel. + */ + + if (16 == pngPtr->bitDepth) { + memcpy(pngPtr->transVal, buffer, 6); + } else { + pngPtr->transVal[0] = buffer[1]; + pngPtr->transVal[1] = buffer[3]; + pngPtr->transVal[2] = buffer[5]; + } + pngPtr->useTRNS = 1; + break; + } + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * Paeth -- + * + * Utility function for applying the Paeth filter to a pixel. The Paeth + * filter is a linear function of the pixel to be filtered and the pixels + * to the left, above, and above-left of the pixel to be unfiltered. + * + * Results: + * Result of the Paeth function for the left, above, and above-left + * pixels. + * + * Side effects: + * None + * + *---------------------------------------------------------------------- + */ + +static inline unsigned char +Paeth( + int a, + int b, + int c) +{ + int pa = abs(b - c); + int pb = abs(a - c); + int pc = abs(a + b - c - c); + + if ((pa <= pb) && (pa <= pc)) { + return (unsigned char) a; + } + + if (pb <= pc) { + return (unsigned char) b; + } + + return (unsigned char) c; +} + +/* + *---------------------------------------------------------------------- + * + * UnfilterLine -- + * + * Applies the filter algorithm specified in first byte of a line to the + * line of pixels being read from a PNG image. + * + * PNG specifies four filter algorithms (Sub, Up, Average, and Paeth) + * that combine a pixel's value with those of other pixels in the same + * and/or previous lines. Filtering is intended to make an image more + * compressible. + * + * Results: + * TCL_OK, or TCL_ERROR if the filter type is not recognized. + * + * Side effects: + * Pixel data in thisLineObj are modified. + * + *---------------------------------------------------------------------- + */ + +static int +UnfilterLine( + Tcl_Interp *interp, + PNGImage *pngPtr) +{ + unsigned char *thisLine = + Tcl_GetByteArrayFromObj(pngPtr->thisLineObj, NULL); + unsigned char *lastLine = + Tcl_GetByteArrayFromObj(pngPtr->lastLineObj, NULL); + +#define PNG_FILTER_NONE 0 +#define PNG_FILTER_SUB 1 +#define PNG_FILTER_UP 2 +#define PNG_FILTER_AVG 3 +#define PNG_FILTER_PAETH 4 + + switch (*thisLine) { + case PNG_FILTER_NONE: /* Nothing to do */ + break; + case PNG_FILTER_SUB: { /* Sub(x) = Raw(x) - Raw(x-bpp) */ + unsigned char *rawBpp = thisLine + 1; + unsigned char *raw = rawBpp + pngPtr->bytesPerPixel; + unsigned char *end = thisLine + pngPtr->phaseSize; + + while (raw < end) { + *raw++ += *rawBpp++; + } + break; + } + case PNG_FILTER_UP: /* Up(x) = Raw(x) - Prior(x) */ + if (pngPtr->currentLine > startLine[pngPtr->phase]) { + unsigned char *prior = lastLine + 1; + unsigned char *raw = thisLine + 1; + unsigned char *end = thisLine + pngPtr->phaseSize; + + while (raw < end) { + *raw++ += *prior++; + } + } + break; + case PNG_FILTER_AVG: + /* Avg(x) = Raw(x) - floor((Raw(x-bpp)+Prior(x))/2) */ + if (pngPtr->currentLine > startLine[pngPtr->phase]) { + unsigned char *prior = lastLine + 1; + unsigned char *rawBpp = thisLine + 1; + unsigned char *raw = rawBpp; + unsigned char *end = thisLine + pngPtr->phaseSize; + unsigned char *end2 = raw + pngPtr->bytesPerPixel; + + while ((raw < end2) && (raw < end)) { + *raw++ += *prior++ / 2; + } + + while (raw < end) { + *raw++ += (unsigned char) + (((int) *rawBpp++ + (int) *prior++) / 2); + } + } else { + unsigned char *rawBpp = thisLine + 1; + unsigned char *raw = rawBpp + pngPtr->bytesPerPixel; + unsigned char *end = thisLine + pngPtr->phaseSize; + + while (raw < end) { + *raw++ += *rawBpp++ / 2; + } + } + break; + case PNG_FILTER_PAETH: + /* Paeth(x) = Raw(x) - PaethPredictor(Raw(x-bpp), Prior(x), Prior(x-bpp)) */ + if (pngPtr->currentLine > startLine[pngPtr->phase]) { + unsigned char *priorBpp = lastLine + 1; + unsigned char *prior = priorBpp; + unsigned char *rawBpp = thisLine + 1; + unsigned char *raw = rawBpp; + unsigned char *end = thisLine + pngPtr->phaseSize; + unsigned char *end2 = rawBpp + pngPtr->bytesPerPixel; + + while ((raw < end) && (raw < end2)) { + *raw++ += *prior++; + } + + while (raw < end) { + *raw++ += Paeth(*rawBpp++, *prior++, *priorBpp++); + } + } else { + unsigned char *rawBpp = thisLine + 1; + unsigned char *raw = rawBpp + pngPtr->bytesPerPixel; + unsigned char *end = thisLine + pngPtr->phaseSize; + + while (raw < end) { + *raw++ += *rawBpp++; + } + } + break; + default: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "invalid filter type %d", *thisLine)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_FILTER", NULL); + return TCL_ERROR; + } + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * DecodeLine -- + * + * Unfilters a line of pixels from the PNG source data and decodes the + * data into the Tk_PhotoImageBlock for later copying into the Tk image. + * + * Results: + * TCL_OK, or TCL_ERROR if the filter type is not recognized. + * + * Side effects: + * Pixel data in thisLine and block are modified and state information + * updated. + * + *---------------------------------------------------------------------- + */ + +static int +DecodeLine( + Tcl_Interp *interp, + PNGImage *pngPtr) +{ + unsigned char *pixelPtr = pngPtr->block.pixelPtr; + int colNum = 0; /* Current pixel column */ + unsigned char chan = 0; /* Current channel (0..3) = (R, G, B, A) */ + unsigned char readByte = 0; /* Current scan line byte */ + int haveBits = 0; /* Number of bits remaining in current byte */ + unsigned char pixBits = 0; /* Extracted bits for current channel */ + int shifts = 0; /* Number of channels extracted from byte */ + int offset = 0; /* Current offset into pixelPtr */ + int colStep = 1; /* Column increment each pass */ + int pixStep = 0; /* extra pixelPtr increment each pass */ + unsigned char lastPixel[6]; + unsigned char *p = Tcl_GetByteArrayFromObj(pngPtr->thisLineObj, NULL); + + p++; + if (UnfilterLine(interp, pngPtr) == TCL_ERROR) { + return TCL_ERROR; + } + if (pngPtr->currentLine >= pngPtr->block.height) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "PNG image data overflow")); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "DATA_OVERFLOW", NULL); + return TCL_ERROR; + } + + + if (pngPtr->interlace) { + switch (pngPtr->phase) { + case 1: /* Phase 1: */ + colStep = 8; /* 1 pixel per block of 8 per line */ + break; /* Start at column 0 */ + case 2: /* Phase 2: */ + colStep = 8; /* 1 pixels per block of 8 per line */ + colNum = 4; /* Start at column 4 */ + break; + case 3: /* Phase 3: */ + colStep = 4; /* 2 pixels per block of 8 per line */ + break; /* Start at column 0 */ + case 4: /* Phase 4: */ + colStep = 4; /* 2 pixels per block of 8 per line */ + colNum = 2; /* Start at column 2 */ + break; + case 5: /* Phase 5: */ + colStep = 2; /* 4 pixels per block of 8 per line */ + break; /* Start at column 0 */ + case 6: /* Phase 6: */ + colStep = 2; /* 4 pixels per block of 8 per line */ + colNum = 1; /* Start at column 1 */ + break; + /* Phase 7: */ + /* 8 pixels per block of 8 per line */ + /* Start at column 0 */ + } + } + + /* + * Calculate offset into pixelPtr for the first pixel of the line. + */ + + offset = pngPtr->currentLine * pngPtr->block.pitch; + + /* + * Adjust up for the starting pixel of the line. + */ + + offset += colNum * pngPtr->block.pixelSize; + + /* + * Calculate the extra number of bytes to skip between columns. + */ + + pixStep = (colStep - 1) * pngPtr->block.pixelSize; + + for ( ; colNum < pngPtr->block.width ; colNum += colStep) { + if (haveBits < (pngPtr->bitDepth * pngPtr->numChannels)) { + haveBits = 0; + } + + for (chan = 0 ; chan < pngPtr->numChannels ; chan++) { + if (!haveBits) { + shifts = 0; + readByte = *p++; + haveBits += 8; + } + + if (16 == pngPtr->bitDepth) { + pngPtr->block.pixelPtr[offset++] = readByte; + + if (pngPtr->useTRNS) { + lastPixel[chan * 2] = readByte; + } + + readByte = *p++; + + if (pngPtr->useTRNS) { + lastPixel[(chan * 2) + 1] = readByte; + } + + pngPtr->block.pixelPtr[offset++] = readByte; + + haveBits = 0; + continue; + } + + switch (pngPtr->bitDepth) { + case 1: + pixBits = (unsigned char)((readByte >> (7-shifts)) & 0x01); + break; + case 2: + pixBits = (unsigned char)((readByte >> (6-shifts*2)) & 0x03); + break; + case 4: + pixBits = (unsigned char)((readByte >> (4-shifts*4)) & 0x0f); + break; + case 8: + pixBits = readByte; + break; + } + + if (PNG_COLOR_PLTE == pngPtr->colorType) { + pixelPtr[offset++] = pngPtr->palette[pixBits].red; + pixelPtr[offset++] = pngPtr->palette[pixBits].green; + pixelPtr[offset++] = pngPtr->palette[pixBits].blue; + pixelPtr[offset++] = pngPtr->palette[pixBits].alpha; + chan += 2; + } else { + pixelPtr[offset++] = (unsigned char) + (pixBits * pngPtr->bitScale); + + if (pngPtr->useTRNS) { + lastPixel[chan] = pixBits; + } + } + + haveBits -= pngPtr->bitDepth; + shifts++; + } + + /* + * Apply boolean transparency via tRNS data if necessary (where + * necessary means a tRNS chunk was provided and we're not using an + * alpha channel or indexed alpha). + */ + + if ((PNG_COLOR_PLTE != pngPtr->colorType) && + !(pngPtr->colorType & PNG_COLOR_ALPHA)) { + unsigned char alpha; + + if (pngPtr->useTRNS) { + if (memcmp(lastPixel, pngPtr->transVal, + pngPtr->bytesPerPixel) == 0) { + alpha = 0x00; + } else { + alpha = 0xff; + } + } else { + alpha = 0xff; + } + + pixelPtr[offset++] = alpha; + + if (16 == pngPtr->bitDepth) { + pixelPtr[offset++] = alpha; + } + } + + offset += pixStep; + } + + if (pngPtr->interlace) { + /* Skip lines */ + + switch (pngPtr->phase) { + case 1: case 2: case 3: + pngPtr->currentLine += 8; + break; + case 4: case 5: + pngPtr->currentLine += 4; + break; + case 6: case 7: + pngPtr->currentLine += 2; + break; + } + + /* + * Start the next phase if there are no more lines to do. + */ + + if (pngPtr->currentLine >= pngPtr->block.height) { + unsigned long pixels = 0; + + while ((!pixels || (pngPtr->currentLine >= pngPtr->block.height)) + && (pngPtr->phase < 7)) { + pngPtr->phase++; + + switch (pngPtr->phase) { + case 2: + pixels = (pngPtr->block.width + 3) >> 3; + pngPtr->currentLine = 0; + break; + case 3: + pixels = (pngPtr->block.width + 3) >> 2; + pngPtr->currentLine = 4; + break; + case 4: + pixels = (pngPtr->block.width + 1) >> 2; + pngPtr->currentLine = 0; + break; + case 5: + pixels = (pngPtr->block.width + 1) >> 1; + pngPtr->currentLine = 2; + break; + case 6: + pixels = pngPtr->block.width >> 1; + pngPtr->currentLine = 0; + break; + case 7: + pngPtr->currentLine = 1; + pixels = pngPtr->block.width; + break; + } + } + + if (16 == pngPtr->bitDepth) { + pngPtr->phaseSize = 1 + (pngPtr->numChannels * pixels * 2); + } else { + pngPtr->phaseSize = 1 + ((pngPtr->numChannels * pixels * + pngPtr->bitDepth + 7) >> 3); + } + } + } else { + pngPtr->currentLine++; + } + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * ReadIDAT -- + * + * This function reads the IDAT (pixel data) chunk from the PNG file to + * build the image. It will continue reading until all IDAT chunks have + * been processed or an error occurs. + * + * Results: + * TCL_OK, or TCL_ERROR if an I/O error occurs or an IDAT chunk is + * invalid. + * + * Side effects: + * The access position in f advances. Memory may be allocated by zlib + * through PNGZAlloc. + * + *---------------------------------------------------------------------- + */ + +static int +ReadIDAT( + Tcl_Interp *interp, + PNGImage *pngPtr, + int chunkSz, + unsigned long crc) +{ + /* + * Process IDAT contents until there is no more in this chunk. + */ + + while (chunkSz && !Tcl_ZlibStreamEof(pngPtr->stream)) { + int len1, len2; + + /* + * Read another block of input into the zlib stream if data remains. + */ + + if (chunkSz) { + Tcl_Obj *inputObj = NULL; + int blockSz = PNG_MIN(chunkSz, PNG_BLOCK_SZ); + unsigned char *inputPtr = NULL; + + /* + * Check for end of zlib stream. + */ + + if (Tcl_ZlibStreamEof(pngPtr->stream)) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "extra data after end of zlib stream", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EXTRA_DATA", + NULL); + return TCL_ERROR; + } + + inputObj = Tcl_NewObj(); + Tcl_IncrRefCount(inputObj); + inputPtr = Tcl_SetByteArrayLength(inputObj, blockSz); + + /* + * Read the next bit of IDAT chunk data, up to read buffer size. + */ + + if (ReadData(interp, pngPtr, inputPtr, blockSz, + &crc) == TCL_ERROR) { + Tcl_DecrRefCount(inputObj); + return TCL_ERROR; + } + + chunkSz -= blockSz; + + Tcl_ZlibStreamPut(pngPtr->stream, inputObj, TCL_ZLIB_NO_FLUSH); + Tcl_DecrRefCount(inputObj); + } + + /* + * Inflate, processing each output buffer's worth as a line of pixels, + * until we cannot fill the buffer any more. + */ + + getNextLine: + Tcl_GetByteArrayFromObj(pngPtr->thisLineObj, &len1); + if (Tcl_ZlibStreamGet(pngPtr->stream, pngPtr->thisLineObj, + pngPtr->phaseSize - len1) == TCL_ERROR) { + return TCL_ERROR; + } + Tcl_GetByteArrayFromObj(pngPtr->thisLineObj, &len2); + + if (len2 == pngPtr->phaseSize) { + if (pngPtr->phase > 7) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "extra data after final scan line of final phase", + -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EXTRA_DATA", + NULL); + return TCL_ERROR; + } + + if (DecodeLine(interp, pngPtr) == TCL_ERROR) { + return TCL_ERROR; + } + + /* + * Swap the current/last lines so that we always have the last + * line processed available, which is necessary for filtering. + */ + + { + Tcl_Obj *temp = pngPtr->lastLineObj; + + pngPtr->lastLineObj = pngPtr->thisLineObj; + pngPtr->thisLineObj = temp; + } + Tcl_SetByteArrayLength(pngPtr->thisLineObj, 0); + + /* + * Try to read another line of pixels out of the buffer + * immediately, but don't allow write past end of block. + */ + + if (pngPtr->currentLine < pngPtr->block.height) { + goto getNextLine; + } + + } + + /* + * Got less than a whole buffer-load of pixels. Either we're going to + * be getting more data from the next IDAT, or we've done what we can + * here. + */ + } + + /* + * Ensure that if we've got to the end of the compressed data, we've + * also got to the end of the compressed stream. This sanity check is + * enforced by most PNG readers. + */ + + if (chunkSz != 0) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "compressed data after stream finalize in PNG data", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EXTRA_DATA", NULL); + return TCL_ERROR; + } + + return CheckCRC(interp, pngPtr, crc); +} + +/* + *---------------------------------------------------------------------- + * + * ApplyAlpha -- + * + * Applies an overall alpha value to a complete image that has been read. + * This alpha value is specified using the -format option to [image + * create photo]. + * + * Results: + * N/A + * + * Side effects: + * The access position in f may change. + * + *---------------------------------------------------------------------- + */ + +static void +ApplyAlpha( + PNGImage *pngPtr) +{ + if (pngPtr->alpha != 1.0) { + register unsigned char *p = pngPtr->block.pixelPtr; + unsigned char *endPtr = p + pngPtr->blockLen; + int offset = pngPtr->block.offset[3]; + + p += offset; + + if (16 == pngPtr->bitDepth) { + register unsigned int channel; + + while (p < endPtr) { + channel = (unsigned int) + (((p[0] << 8) | p[1]) * pngPtr->alpha); + + *p++ = (unsigned char) (channel >> 8); + *p++ = (unsigned char) (channel & 0xff); + + p += offset; + } + } else { + while (p < endPtr) { + p[0] = (unsigned char) (pngPtr->alpha * p[0]); + p += 1 + offset; + } + } + } +} + +/* + *---------------------------------------------------------------------- + * + * ParseFormat -- + * + * This function parses the -format string that can be specified to the + * [image create photo] command to extract options for postprocessing of + * loaded images. Currently, this just allows specifying and applying an + * overall alpha value to the loaded image (for example, to make it + * entirely 50% as transparent as the actual image file). + * + * Results: + * TCL_OK, or TCL_ERROR if the format specification is invalid. + * + * Side effects: + * None + * + *---------------------------------------------------------------------- + */ + +static int +ParseFormat( + Tcl_Interp *interp, + Tcl_Obj *fmtObj, + PNGImage *pngPtr) +{ + Tcl_Obj **objv = NULL; + int objc = 0; + static const char *const fmtOptions[] = { + "-alpha", NULL + }; + enum fmtOptions { + OPT_ALPHA + }; + + /* + * Extract elements of format specification as a list. + */ + + if (fmtObj && + Tcl_ListObjGetElements(interp, fmtObj, &objc, &objv) != TCL_OK) { + return TCL_ERROR; + } + + for (; objc>0 ; objc--, objv++) { + int optIndex; + + /* + * Ignore the "png" part of the format specification. + */ + + if (!strcasecmp(Tcl_GetString(objv[0]), "png")) { + continue; + } + + if (Tcl_GetIndexFromObjStruct(interp, objv[0], fmtOptions, + sizeof(char *), "option", 0, &optIndex) == TCL_ERROR) { + return TCL_ERROR; + } + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "value"); + return TCL_ERROR; + } + + objc--; + objv++; + + switch ((enum fmtOptions) optIndex) { + case OPT_ALPHA: + if (Tcl_GetDoubleFromObj(interp, objv[0], + &pngPtr->alpha) == TCL_ERROR) { + return TCL_ERROR; + } + + if ((pngPtr->alpha < 0.0) || (pngPtr->alpha > 1.0)) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "-alpha value must be between 0.0 and 1.0", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_ALPHA", + NULL); + return TCL_ERROR; + } + break; + } + } + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * DecodePNG -- + * + * This function handles the entirety of reading a PNG file (or data) + * from the first byte to the last. + * + * Results: + * TCL_OK, or TCL_ERROR if an I/O error occurs or any problems are + * detected in the PNG file. + * + * Side effects: + * The access position in f advances. Memory may be allocated and image + * dimensions and contents may change. + * + *---------------------------------------------------------------------- + */ + +static int +DecodePNG( + Tcl_Interp *interp, + PNGImage *pngPtr, + Tcl_Obj *fmtObj, + Tk_PhotoHandle imageHandle, + int destX, + int destY) +{ + unsigned long chunkType; + int chunkSz; + unsigned long crc; + + /* + * Parse the PNG signature and IHDR (header) chunk. + */ + + if (ReadIHDR(interp, pngPtr) == TCL_ERROR) { + return TCL_ERROR; + } + + /* + * Extract alpha value from -format object, if specified. + */ + + if (ParseFormat(interp, fmtObj, pngPtr) == TCL_ERROR) { + return TCL_ERROR; + } + + /* + * The next chunk may either be a PLTE (Palette) chunk or the first of at + * least one IDAT (data) chunks. It could also be one of a number of + * ancillary chunks, but those are skipped for us by the switch in + * ReadChunkHeader(). + * + * PLTE is mandatory for color type 3 and forbidden for 2 and 6 + */ + + if (ReadChunkHeader(interp, pngPtr, &chunkSz, &chunkType, + &crc) == TCL_ERROR) { + return TCL_ERROR; + } + + if (CHUNK_PLTE == chunkType) { + /* + * Finish parsing the PLTE chunk. + */ + + if (ReadPLTE(interp, pngPtr, chunkSz, crc) == TCL_ERROR) { + return TCL_ERROR; + } + + /* + * Begin the next chunk. + */ + + if (ReadChunkHeader(interp, pngPtr, &chunkSz, &chunkType, + &crc) == TCL_ERROR) { + return TCL_ERROR; + } + } else if (PNG_COLOR_PLTE == pngPtr->colorType) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "PLTE chunk required for indexed color", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "NEED_PLTE", NULL); + return TCL_ERROR; + } + + /* + * The next chunk may be a tRNS (palette transparency) chunk, depending on + * the color type. It must come after the PLTE chunk and before the IDAT + * chunk, but can be present if there is no PLTE chunk because it can be + * used for Grayscale and TrueColor in lieu of an alpha channel. + */ + + if (CHUNK_tRNS == chunkType) { + /* + * Finish parsing the tRNS chunk. + */ + + if (ReadTRNS(interp, pngPtr, chunkSz, crc) == TCL_ERROR) { + return TCL_ERROR; + } + + /* + * Begin the next chunk. + */ + + if (ReadChunkHeader(interp, pngPtr, &chunkSz, &chunkType, + &crc) == TCL_ERROR) { + return TCL_ERROR; + } + } + + /* + * Other ancillary chunk types could appear here, but for now we're only + * interested in IDAT. The others should have been skipped. + */ + + if (chunkType != CHUNK_IDAT) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "at least one IDAT chunk is required", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "NEED_IDAT", NULL); + return TCL_ERROR; + } + + /* + * Expand the photo size (if not set by the user) to provide enough space + * for the image being parsed. It does not matter if width or height wrap + * to negative here: Tk will not shrink the image. + */ + + if (Tk_PhotoExpand(interp, imageHandle, destX + pngPtr->block.width, + destY + pngPtr->block.height) == TCL_ERROR) { + return TCL_ERROR; + } + + /* + * A scan line consists of one byte for a filter type, plus the number of + * bits per color sample times the number of color samples per pixel. + */ + + if (pngPtr->block.width > ((INT_MAX - 1) / (pngPtr->numChannels * 2))) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "line size is out of supported range on this architecture", + -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "LINE_SIZE", NULL); + return TCL_ERROR; + } + + if (16 == pngPtr->bitDepth) { + pngPtr->lineSize = 1 + (pngPtr->numChannels * pngPtr->block.width*2); + } else { + pngPtr->lineSize = 1 + ((pngPtr->numChannels * pngPtr->block.width) / + (8 / pngPtr->bitDepth)); + if (pngPtr->block.width % (8 / pngPtr->bitDepth)) { + pngPtr->lineSize++; + } + } + + /* + * Allocate space for decoding the scan lines. + */ + + pngPtr->lastLineObj = Tcl_NewObj(); + Tcl_IncrRefCount(pngPtr->lastLineObj); + pngPtr->thisLineObj = Tcl_NewObj(); + Tcl_IncrRefCount(pngPtr->thisLineObj); + + pngPtr->block.pixelPtr = attemptckalloc(pngPtr->blockLen); + if (!pngPtr->block.pixelPtr) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "memory allocation failed", -1)); + Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL); + return TCL_ERROR; + } + + /* + * Determine size of the first phase if interlaced. Phase size should + * always be <= line size, so probably not necessary to check for + * arithmetic overflow here: should be covered by line size check. + */ + + if (pngPtr->interlace) { + /* + * Only one pixel per block of 8 per line in the first phase. + */ + + unsigned int pixels = (pngPtr->block.width + 7) >> 3; + + pngPtr->phase = 1; + if (16 == pngPtr->bitDepth) { + pngPtr->phaseSize = 1 + pngPtr->numChannels*pixels*2; + } else { + pngPtr->phaseSize = 1 + + ((pngPtr->numChannels*pixels*pngPtr->bitDepth + 7) >> 3); + } + } else { + pngPtr->phaseSize = pngPtr->lineSize; + } + + /* + * All of the IDAT (data) chunks must be consecutive. + */ + + while (CHUNK_IDAT == chunkType) { + if (ReadIDAT(interp, pngPtr, chunkSz, crc) == TCL_ERROR) { + return TCL_ERROR; + } + + if (ReadChunkHeader(interp, pngPtr, &chunkSz, &chunkType, + &crc) == TCL_ERROR) { + return TCL_ERROR; + } + } + + /* + * Ensure that we've got to the end of the compressed stream now that + * there are no more IDAT segments. This sanity check is enforced by most + * PNG readers. + */ + + if (!Tcl_ZlibStreamEof(pngPtr->stream)) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "unfinalized data stream in PNG data", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EXTRA_DATA", NULL); + return TCL_ERROR; + } + + /* + * Now skip the remaining chunks which we're also not interested in. + */ + + while (CHUNK_IEND != chunkType) { + if (SkipChunk(interp, pngPtr, chunkSz, crc) == TCL_ERROR) { + return TCL_ERROR; + } + + if (ReadChunkHeader(interp, pngPtr, &chunkSz, &chunkType, + &crc) == TCL_ERROR) { + return TCL_ERROR; + } + } + + /* + * Got the IEND (end of image) chunk. Do some final checks... + */ + + if (chunkSz) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "IEND chunk contents must be empty", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_IEND", NULL); + return TCL_ERROR; + } + + /* + * Check the CRC on the IEND chunk. + */ + + if (CheckCRC(interp, pngPtr, crc) == TCL_ERROR) { + return TCL_ERROR; + } + + /* + * TODO: verify that nothing else comes after the IEND chunk, or do we + * really care? + */ + +#if 0 + if (ReadData(interp, pngPtr, &c, 1, NULL) != TCL_ERROR) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "extra data following IEND chunk", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "BAD_IEND", NULL); + return TCL_ERROR; + } +#endif + + /* + * Apply overall image alpha if specified. + */ + + ApplyAlpha(pngPtr); + + /* + * Copy the decoded image block into the Tk photo image. + */ + + if (Tk_PhotoPutBlock(interp, imageHandle, &pngPtr->block, destX, destY, + pngPtr->block.width, pngPtr->block.height, + TK_PHOTO_COMPOSITE_SET) == TCL_ERROR) { + return TCL_ERROR; + } + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * FileMatchPNG -- + * + * This function is invoked by the photo image type to see if a file + * contains image data in PNG format. + * + * Results: + * The return value is 1 if the first characters in file f look like PNG + * data, and 0 otherwise. + * + * Side effects: + * The access position in f may change. + * + *---------------------------------------------------------------------- + */ + +static int +FileMatchPNG( + Tcl_Channel chan, + const char *fileName, + Tcl_Obj *fmtObj, + int *widthPtr, + int *heightPtr, + Tcl_Interp *interp) +{ + PNGImage png; + int match = 0; + + InitPNGImage(NULL, &png, chan, NULL, TCL_ZLIB_STREAM_INFLATE); + + if (ReadIHDR(interp, &png) == TCL_OK) { + *widthPtr = png.block.width; + *heightPtr = png.block.height; + match = 1; + } + + CleanupPNGImage(&png); + + return match; +} + +/* + *---------------------------------------------------------------------- + * + * FileReadPNG -- + * + * This function is called by the photo image type to read PNG format + * data from a file and write it into a given photo image. + * + * Results: + * A standard TCL completion code. If TCL_ERROR is returned then an error + * message is left in the interp's result. + * + * Side effects: + * The access position in file f is changed, and new data is added to the + * image given by imageHandle. + * + *---------------------------------------------------------------------- + */ + +static int +FileReadPNG( + Tcl_Interp *interp, + Tcl_Channel chan, + const char *fileName, + Tcl_Obj *fmtObj, + Tk_PhotoHandle imageHandle, + int destX, + int destY, + int width, + int height, + int srcX, + int srcY) +{ + PNGImage png; + int result = TCL_ERROR; + + result = InitPNGImage(interp, &png, chan, NULL, TCL_ZLIB_STREAM_INFLATE); + + if (TCL_OK == result) { + result = DecodePNG(interp, &png, fmtObj, imageHandle, destX, destY); + } + + CleanupPNGImage(&png); + return result; +} + +/* + *---------------------------------------------------------------------- + * + * StringMatchPNG -- + * + * This function is invoked by the photo image type to see if an object + * contains image data in PNG format. + * + * Results: + * The return value is 1 if the first characters in the data are like PNG + * data, and 0 otherwise. + * + * Side effects: + * The size of the image is placed in widthPre and heightPtr. + * + *---------------------------------------------------------------------- + */ + +static int +StringMatchPNG( + Tcl_Obj *pObjData, + Tcl_Obj *fmtObj, + int *widthPtr, + int *heightPtr, + Tcl_Interp *interp) +{ + PNGImage png; + int match = 0; + + InitPNGImage(NULL, &png, NULL, pObjData, TCL_ZLIB_STREAM_INFLATE); + + png.strDataBuf = Tcl_GetByteArrayFromObj(pObjData, &png.strDataLen); + + if (ReadIHDR(interp, &png) == TCL_OK) { + *widthPtr = png.block.width; + *heightPtr = png.block.height; + match = 1; + } + + CleanupPNGImage(&png); + return match; +} + +/* + *---------------------------------------------------------------------- + * + * StringReadPNG -- + * + * This function is called by the photo image type to read PNG format + * data from an object and give it to the photo image. + * + * Results: + * A standard TCL completion code. If TCL_ERROR is returned then an error + * message is left in the interp's result. + * + * Side effects: + * New data is added to the image given by imageHandle. + * + *---------------------------------------------------------------------- + */ + +static int +StringReadPNG( + Tcl_Interp *interp, + Tcl_Obj *pObjData, + Tcl_Obj *fmtObj, + Tk_PhotoHandle imageHandle, + int destX, + int destY, + int width, + int height, + int srcX, + int srcY) +{ + PNGImage png; + int result = TCL_ERROR; + + result = InitPNGImage(interp, &png, NULL, pObjData, + TCL_ZLIB_STREAM_INFLATE); + + if (TCL_OK == result) { + result = DecodePNG(interp, &png, fmtObj, imageHandle, destX, destY); + } + + CleanupPNGImage(&png); + return result; +} + +/* + *---------------------------------------------------------------------- + * + * WriteData -- + * + * This function writes a bytes from a buffer out to the PNG image. + * + * Results: + * TCL_OK, or TCL_ERROR if the write fails. + * + * Side effects: + * File or buffer will be modified. + * + *---------------------------------------------------------------------- + */ + +static int +WriteData( + Tcl_Interp *interp, + PNGImage *pngPtr, + const unsigned char *srcPtr, + int srcSz, + unsigned long *crcPtr) +{ + if (!srcPtr || !srcSz) { + return TCL_OK; + } + + if (crcPtr) { + *crcPtr = Tcl_ZlibCRC32(*crcPtr, srcPtr, srcSz); + } + + /* + * TODO: is Tcl_AppendObjToObj faster here? i.e., does Tcl join the + * objects immediately or store them in a multi-object rep? + */ + + if (pngPtr->objDataPtr) { + int objSz; + unsigned char *destPtr; + + Tcl_GetByteArrayFromObj(pngPtr->objDataPtr, &objSz); + + if (objSz > INT_MAX - srcSz) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "image too large to store completely in byte array", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "TOO_LARGE", NULL); + return TCL_ERROR; + } + + destPtr = Tcl_SetByteArrayLength(pngPtr->objDataPtr, objSz + srcSz); + + if (!destPtr) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "memory allocation failed", -1)); + Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL); + return TCL_ERROR; + } + + memcpy(destPtr+objSz, srcPtr, srcSz); + } else if (Tcl_Write(pngPtr->channel, (const char *) srcPtr, srcSz) < 0) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "write to channel failed: %s", Tcl_PosixError(interp))); + return TCL_ERROR; + } + + return TCL_OK; +} + +static inline int +WriteByte( + Tcl_Interp *interp, + PNGImage *pngPtr, + unsigned char c, + unsigned long *crcPtr) +{ + return WriteData(interp, pngPtr, &c, 1, crcPtr); +} + +/* + *---------------------------------------------------------------------- + * + * WriteInt32 -- + * + * This function writes a 32-bit integer value out to the PNG image as + * four bytes in network byte order. + * + * Results: + * TCL_OK, or TCL_ERROR if the write fails. + * + * Side effects: + * File or buffer will be modified. + * + *---------------------------------------------------------------------- + */ + +static inline int +WriteInt32( + Tcl_Interp *interp, + PNGImage *pngPtr, + unsigned long l, + unsigned long *crcPtr) +{ + unsigned char pc[4]; + + pc[0] = (unsigned char) ((l & 0xff000000) >> 24); + pc[1] = (unsigned char) ((l & 0x00ff0000) >> 16); + pc[2] = (unsigned char) ((l & 0x0000ff00) >> 8); + pc[3] = (unsigned char) ((l & 0x000000ff) >> 0); + + return WriteData(interp, pngPtr, pc, 4, crcPtr); +} + +/* + *---------------------------------------------------------------------- + * + * WriteChunk -- + * + * Writes a complete chunk to the PNG image, including chunk type, + * length, contents, and CRC. + * + * Results: + * TCL_OK, or TCL_ERROR if the write fails. + * + * Side effects: + * None + * + *---------------------------------------------------------------------- + */ + +static inline int +WriteChunk( + Tcl_Interp *interp, + PNGImage *pngPtr, + unsigned long chunkType, + const unsigned char *dataPtr, + int dataSize) +{ + unsigned long crc = Tcl_ZlibCRC32(0, NULL, 0); + int result = TCL_OK; + + /* + * Write the length field for the chunk. + */ + + result = WriteInt32(interp, pngPtr, dataSize, NULL); + + /* + * Write the Chunk Type. + */ + + if (TCL_OK == result) { + result = WriteInt32(interp, pngPtr, chunkType, &crc); + } + + /* + * Write the contents (if any). + */ + + if (TCL_OK == result) { + result = WriteData(interp, pngPtr, dataPtr, dataSize, &crc); + } + + /* + * Write out the CRC at the end of the chunk. + */ + + if (TCL_OK == result) { + result = WriteInt32(interp, pngPtr, crc, NULL); + } + + return result; +} + +/* + *---------------------------------------------------------------------- + * + * WriteIHDR -- + * + * This function writes the PNG header at the beginning of a PNG file, + * which includes information such as dimensions and color type. + * + * Results: + * TCL_OK, or TCL_ERROR if the write fails. + * + * Side effects: + * File or buffer will be modified. + * + *---------------------------------------------------------------------- + */ + +static int +WriteIHDR( + Tcl_Interp *interp, + PNGImage *pngPtr, + Tk_PhotoImageBlock *blockPtr) +{ + unsigned long crc = Tcl_ZlibCRC32(0, NULL, 0); + int result = TCL_OK; + + /* + * The IHDR (header) chunk has a fixed size of 13 bytes. + */ + + result = WriteInt32(interp, pngPtr, 13, NULL); + + /* + * Write the IHDR Chunk Type. + */ + + if (TCL_OK == result) { + result = WriteInt32(interp, pngPtr, CHUNK_IHDR, &crc); + } + + /* + * Write the image width, height. + */ + + if (TCL_OK == result) { + result = WriteInt32(interp, pngPtr, (unsigned long) blockPtr->width, + &crc); + } + + if (TCL_OK == result) { + result = WriteInt32(interp, pngPtr, (unsigned long) blockPtr->height, + &crc); + } + + /* + * Write bit depth. Although the PNG format supports 16 bits per channel, + * Tk supports only 8 in the internal representation, which blockPtr + * points to. + */ + + if (TCL_OK == result) { + result = WriteByte(interp, pngPtr, 8, &crc); + } + + /* + * Write out the color type, previously determined. + */ + + if (TCL_OK == result) { + result = WriteByte(interp, pngPtr, pngPtr->colorType, &crc); + } + + /* + * Write compression method (only one method is defined). + */ + + if (TCL_OK == result) { + result = WriteByte(interp, pngPtr, PNG_COMPRESS_DEFLATE, &crc); + } + + /* + * Write filter method (only one method is defined). + */ + + if (TCL_OK == result) { + result = WriteByte(interp, pngPtr, PNG_FILTMETH_STANDARD, &crc); + } + + /* + * Write interlace method as not interlaced. + * + * TODO: support interlace through -format? + */ + + if (TCL_OK == result) { + result = WriteByte(interp, pngPtr, PNG_INTERLACE_NONE, &crc); + } + + /* + * Write out the CRC at the end of the chunk. + */ + + if (TCL_OK == result) { + result = WriteInt32(interp, pngPtr, crc, NULL); + } + + return result; +} + +/* + *---------------------------------------------------------------------- + * + * WriteIDAT -- + * + * Writes the IDAT (data) chunk to the PNG image, containing the pixel + * channel data. Currently, image lines are not filtered and writing + * interlaced pixels is not supported. + * + * Results: + * TCL_OK, or TCL_ERROR if the write fails. + * + * Side effects: + * None + * + *---------------------------------------------------------------------- + */ + +static int +WriteIDAT( + Tcl_Interp *interp, + PNGImage *pngPtr, + Tk_PhotoImageBlock *blockPtr) +{ + int rowNum, flush = TCL_ZLIB_NO_FLUSH, outputSize, result; + Tcl_Obj *outputObj; + unsigned char *outputBytes; + + /* + * Filter and compress each row one at a time. + */ + + for (rowNum=0 ; rowNum < blockPtr->height ; rowNum++) { + int colNum; + unsigned char *srcPtr, *destPtr; + + srcPtr = blockPtr->pixelPtr + (rowNum * blockPtr->pitch); + destPtr = Tcl_SetByteArrayLength(pngPtr->thisLineObj, + pngPtr->lineSize); + + /* + * TODO: use Paeth filtering. + */ + + *destPtr++ = PNG_FILTER_NONE; + + /* + * Copy each pixel into the destination buffer after the filter type + * before filtering. + */ + + for (colNum = 0 ; colNum < blockPtr->width ; colNum++) { + /* + * Copy red or gray channel. + */ + + *destPtr++ = srcPtr[blockPtr->offset[0]]; + + /* + * If not grayscale, copy the green and blue channels. + */ + + if (pngPtr->colorType & PNG_COLOR_USED) { + *destPtr++ = srcPtr[blockPtr->offset[1]]; + *destPtr++ = srcPtr[blockPtr->offset[2]]; + } + + /* + * Copy the alpha channel, if used. + */ + + if (pngPtr->colorType & PNG_COLOR_ALPHA) { + *destPtr++ = srcPtr[blockPtr->offset[3]]; + } + + /* + * Point to the start of the next pixel. + */ + + srcPtr += blockPtr->pixelSize; + } + + /* + * Compress the line of pixels into the destination. If this is the + * last line, finalize the compressor at the same time. Note that this + * can't be just a flush; that leads to a file that some PNG readers + * choke on. [Bug 2984787] + */ + + if (rowNum + 1 == blockPtr->height) { + flush = TCL_ZLIB_FINALIZE; + } + if (Tcl_ZlibStreamPut(pngPtr->stream, pngPtr->thisLineObj, + flush) != TCL_OK) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "deflate() returned error", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "DEFLATE", NULL); + return TCL_ERROR; + } + + /* + * Swap line buffers to keep the last around for filtering next. + */ + + { + Tcl_Obj *temp = pngPtr->lastLineObj; + + pngPtr->lastLineObj = pngPtr->thisLineObj; + pngPtr->thisLineObj = temp; + } + } + + /* + * Now get the compressed data and write it as one big IDAT chunk. + */ + + outputObj = Tcl_NewObj(); + (void) Tcl_ZlibStreamGet(pngPtr->stream, outputObj, -1); + outputBytes = Tcl_GetByteArrayFromObj(outputObj, &outputSize); + result = WriteChunk(interp, pngPtr, CHUNK_IDAT, outputBytes, outputSize); + Tcl_DecrRefCount(outputObj); + return result; +} + +/* + *---------------------------------------------------------------------- + * + * WriteExtraChunks -- + * + * Writes an sBIT and a tEXt chunks to the PNG image, describing a bunch + * of not very important metadata that many readers seem to need anyway. + * + * Results: + * TCL_OK, or TCL_ERROR if the write fails. + * + * Side effects: + * None + * + *---------------------------------------------------------------------- + */ + +static int +WriteExtraChunks( + Tcl_Interp *interp, + PNGImage *pngPtr) +{ + static const unsigned char sBIT_contents[] = { + 8, 8, 8, 8 + }; + int sBIT_length = 4; + Tcl_DString buf; + + /* + * Each byte of each channel is always significant; we always write RGBA + * images with 8 bits per channel as that is what the photo image's basic + * data model is. + */ + + switch (pngPtr->colorType) { + case PNG_COLOR_GRAY: + sBIT_length = 1; + break; + case PNG_COLOR_GRAYALPHA: + sBIT_length = 2; + break; + case PNG_COLOR_RGB: + case PNG_COLOR_PLTE: + sBIT_length = 3; + break; + case PNG_COLOR_RGBA: + sBIT_length = 4; + break; + } + if (WriteChunk(interp, pngPtr, CHUNK_sBIT, sBIT_contents, sBIT_length) + != TCL_OK) { + return TCL_ERROR; + } + + /* + * Say that it is Tk that made the PNG. Note that we *need* the NUL at the + * end of "Software" to be transferred; do *not* change the length + * parameter to -1 there! + */ + + Tcl_DStringInit(&buf); + Tcl_DStringAppend(&buf, "Software", 9); + Tcl_DStringAppend(&buf, "Tk Toolkit v", -1); + Tcl_DStringAppend(&buf, TK_PATCH_LEVEL, -1); + if (WriteChunk(interp, pngPtr, CHUNK_tEXt, + (unsigned char *) Tcl_DStringValue(&buf), + Tcl_DStringLength(&buf)) != TCL_OK) { + Tcl_DStringFree(&buf); + return TCL_ERROR; + } + Tcl_DStringFree(&buf); + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * EncodePNG -- + * + * This function handles the entirety of writing a PNG file (or data) + * from the first byte to the last. No effort is made to optimize the + * image data for best compression. + * + * Results: + * TCL_OK, or TCL_ERROR if an I/O or memory error occurs. + * + * Side effects: + * None + * + *---------------------------------------------------------------------- + */ + +static int +EncodePNG( + Tcl_Interp *interp, + Tk_PhotoImageBlock *blockPtr, + PNGImage *pngPtr) +{ + int greenOffset, blueOffset, alphaOffset; + + /* + * Determine appropriate color type based on color usage (e.g., only red + * and maybe alpha channel = grayscale). + * + * TODO: Check whether this is doing any good; Tk might just be pushing + * full RGBA data all the time through here, even though the actual image + * doesn't need it... + */ + + greenOffset = blockPtr->offset[1] - blockPtr->offset[0]; + blueOffset = blockPtr->offset[2] - blockPtr->offset[0]; + alphaOffset = blockPtr->offset[3]; + if ((alphaOffset >= blockPtr->pixelSize) || (alphaOffset < 0)) { + alphaOffset = 0; + } else { + alphaOffset -= blockPtr->offset[0]; + } + + if ((greenOffset != 0) || (blueOffset != 0)) { + if (alphaOffset) { + pngPtr->colorType = PNG_COLOR_RGBA; + pngPtr->bytesPerPixel = 4; + } else { + pngPtr->colorType = PNG_COLOR_RGB; + pngPtr->bytesPerPixel = 3; + } + } else { + if (alphaOffset) { + pngPtr->colorType = PNG_COLOR_GRAYALPHA; + pngPtr->bytesPerPixel = 2; + } else { + pngPtr->colorType = PNG_COLOR_GRAY; + pngPtr->bytesPerPixel = 1; + } + } + + /* + * Allocate buffers for lines for filtering and compressed data. + */ + + pngPtr->lineSize = 1 + (pngPtr->bytesPerPixel * blockPtr->width); + pngPtr->blockLen = pngPtr->lineSize * blockPtr->height; + + if ((blockPtr->width > (INT_MAX - 1) / (pngPtr->bytesPerPixel)) || + (blockPtr->height > INT_MAX / pngPtr->lineSize)) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "image is too large to encode pixel data", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "TOO_LARGE", NULL); + return TCL_ERROR; + } + + pngPtr->lastLineObj = Tcl_NewObj(); + Tcl_IncrRefCount(pngPtr->lastLineObj); + pngPtr->thisLineObj = Tcl_NewObj(); + Tcl_IncrRefCount(pngPtr->thisLineObj); + + /* + * Write out the PNG Signature that all PNGs begin with. + */ + + if (WriteData(interp, pngPtr, pngSignature, PNG_SIG_SZ, + NULL) == TCL_ERROR) { + return TCL_ERROR; + } + + /* + * Write out the IHDR (header) chunk containing image dimensions, color + * type, etc. + */ + + if (WriteIHDR(interp, pngPtr, blockPtr) == TCL_ERROR) { + return TCL_ERROR; + } + + /* + * Write out the extra chunks containing metadata that is of interest to + * other programs more than us. + */ + + if (WriteExtraChunks(interp, pngPtr) == TCL_ERROR) { + return TCL_ERROR; + } + + /* + * Write out the image pixels in the IDAT (data) chunk. + */ + + if (WriteIDAT(interp, pngPtr, blockPtr) == TCL_ERROR) { + return TCL_ERROR; + } + + /* + * Write out the IEND chunk that all PNGs end with. + */ + + return WriteChunk(interp, pngPtr, CHUNK_IEND, NULL, 0); +} + +/* + *---------------------------------------------------------------------- + * + * FileWritePNG -- + * + * This function is called by the photo image type to write PNG format + * data to a file. + * + * Results: + * A standard TCL completion code. If TCL_ERROR is returned then an error + * message is left in the interp's result. + * + * Side effects: + * The specified file is overwritten. + * + *---------------------------------------------------------------------- + */ + +static int +FileWritePNG( + Tcl_Interp *interp, + const char *filename, + Tcl_Obj *fmtObj, + Tk_PhotoImageBlock *blockPtr) +{ + Tcl_Channel chan; + PNGImage png; + int result = TCL_ERROR; + + /* + * Open a Tcl file channel where the image data will be stored. Tk ought + * to take care of this, and just provide a channel, but it doesn't. + */ + + chan = Tcl_OpenFileChannel(interp, filename, "w", 0644); + + if (!chan) { + return TCL_ERROR; + } + + /* + * Initalize PNGImage instance for encoding. + */ + + if (InitPNGImage(interp, &png, chan, NULL, + TCL_ZLIB_STREAM_DEFLATE) == TCL_ERROR) { + goto cleanup; + } + + /* + * Set the translation mode to binary so that CR and LF are not to the + * platform's EOL sequence. + */ + + if (Tcl_SetChannelOption(interp, chan, "-translation", + "binary") != TCL_OK) { + goto cleanup; + } + + /* + * Write the raw PNG data out to the file. + */ + + result = EncodePNG(interp, blockPtr, &png); + + cleanup: + Tcl_Close(interp, chan); + CleanupPNGImage(&png); + return result; +} + +/* + *---------------------------------------------------------------------- + * + * StringWritePNG -- + * + * This function is called by the photo image type to write PNG format + * data to a Tcl object and return it in the result. + * + * Results: + * A standard TCL completion code. If TCL_ERROR is returned then an error + * message is left in the interp's result. + * + * Side effects: + * None + * + *---------------------------------------------------------------------- + */ + +static int +StringWritePNG( + Tcl_Interp *interp, + Tcl_Obj *fmtObj, + Tk_PhotoImageBlock *blockPtr) +{ + Tcl_Obj *resultObj = Tcl_NewObj(); + PNGImage png; + int result = TCL_ERROR; + + /* + * Initalize PNGImage instance for encoding. + */ + + if (InitPNGImage(interp, &png, NULL, resultObj, + TCL_ZLIB_STREAM_DEFLATE) == TCL_ERROR) { + goto cleanup; + } + + /* + * Write the raw PNG data into the prepared Tcl_Obj buffer. Set the result + * back to the interpreter if successful. + */ + + result = EncodePNG(interp, blockPtr, &png); + + if (TCL_OK == result) { + Tcl_SetObjResult(interp, png.objDataPtr); + } + + cleanup: + CleanupPNGImage(&png); + return result; +} + +/* + * Local Variables: + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/generic/tkImgPPM.c b/generic/tkImgPPM.c index ddd16b2..6f084f0 100644 --- a/generic/tkImgPPM.c +++ b/generic/tkImgPPM.c @@ -34,14 +34,14 @@ * The format record for the PPM file format: */ -static int FileMatchPPM(Tcl_Channel chan, CONST char *fileName, +static int FileMatchPPM(Tcl_Channel chan, const char *fileName, Tcl_Obj *format, int *widthPtr, int *heightPtr, Tcl_Interp *interp); static int FileReadPPM(Tcl_Interp *interp, Tcl_Channel chan, - CONST char *fileName, Tcl_Obj *format, + const char *fileName, Tcl_Obj *format, Tk_PhotoHandle imageHandle, int destX, int destY, int width, int height, int srcX, int srcY); -static int FileWritePPM(Tcl_Interp *interp, CONST char *fileName, +static int FileWritePPM(Tcl_Interp *interp, const char *fileName, Tcl_Obj *format, Tk_PhotoImageBlock *blockPtr); static int StringWritePPM(Tcl_Interp *interp, Tcl_Obj *format, Tk_PhotoImageBlock *blockPtr); @@ -60,6 +60,7 @@ Tk_PhotoImageFormat tkImgFmtPPM = { StringReadPPM, /* stringReadProc */ FileWritePPM, /* fileWriteProc */ StringWritePPM, /* stringWriteProc */ + NULL }; /* @@ -93,7 +94,7 @@ static int ReadPPMStringHeader(Tcl_Obj *dataObj, int *widthPtr, static int FileMatchPPM( Tcl_Channel chan, /* The image file, open for reading. */ - CONST char *fileName, /* The name of the image file. */ + const char *fileName, /* The name of the image file. */ Tcl_Obj *format, /* User-specified format string, or NULL. */ int *widthPtr, int *heightPtr, /* The dimensions of the image are returned @@ -129,7 +130,7 @@ static int FileReadPPM( Tcl_Interp *interp, /* Interpreter to use for reporting errors. */ Tcl_Channel chan, /* The image file, open for reading. */ - CONST char *fileName, /* The name of the image file. */ + const char *fileName, /* The name of the image file. */ Tcl_Obj *format, /* User-specified format string, or NULL. */ Tk_PhotoHandle imageHandle, /* The photo image to write into. */ int destX, int destY, /* Coordinates of top-left pixel in photo @@ -146,21 +147,22 @@ FileReadPPM( type = ReadPPMFileHeader(chan, &fileWidth, &fileHeight, &maxIntensity); if (type == 0) { - Tcl_AppendResult(interp, "couldn't read raw PPM header from file \"", - fileName, "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "couldn't read raw PPM header from file \"%s\"", fileName)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "NO_HEADER", NULL); return TCL_ERROR; } if ((fileWidth <= 0) || (fileHeight <= 0)) { - Tcl_AppendResult(interp, "PPM image file \"", fileName, - "\" has dimension(s) <= 0", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "PPM image file \"%s\" has dimension(s) <= 0", fileName)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "DIMENSIONS", NULL); return TCL_ERROR; } if ((maxIntensity <= 0) || (maxIntensity > 0xffff)) { - char buffer[TCL_INTEGER_SPACE]; - - sprintf(buffer, "%d", maxIntensity); - Tcl_AppendResult(interp, "PPM image file \"", fileName, - "\" has bad maximum intensity value ", buffer, NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "PPM image file \"%s\" has bad maximum intensity value %d", + fileName, maxIntensity)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "INTENSITY", NULL); return TCL_ERROR; } else if (maxIntensity > 0x00ff) { bytesPerChannel = 2; @@ -209,7 +211,7 @@ FileReadPPM( nLines = 1; } nBytes = nLines * block.pitch; - pixelPtr = (unsigned char *) ckalloc((unsigned) nBytes); + pixelPtr = ckalloc(nBytes); block.pixelPtr = pixelPtr + srcX * block.pixelSize; for (h = height; h > 0; h -= nLines) { @@ -219,11 +221,13 @@ FileReadPPM( } count = Tcl_Read(chan, (char *) pixelPtr, nBytes); if (count != nBytes) { - Tcl_AppendResult(interp, "error reading PPM image file \"", - fileName, "\": ", - Tcl_Eof(chan) ? "not enough data" : Tcl_PosixError(interp), - NULL); - ckfree((char *) pixelPtr); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "error reading PPM image file \"%s\": %s", fileName, + Tcl_Eof(chan)?"not enough data":Tcl_PosixError(interp))); + if (Tcl_Eof(chan)) { + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "EOF", NULL); + } + ckfree(pixelPtr); return TCL_ERROR; } if (maxIntensity < 0x00ff) { @@ -245,13 +249,13 @@ FileReadPPM( block.height = nLines; if (Tk_PhotoPutBlock(interp, imageHandle, &block, destX, destY, width, nLines, TK_PHOTO_COMPOSITE_SET) != TCL_OK) { - ckfree((char *) pixelPtr); + ckfree(pixelPtr); return TCL_ERROR; } destY += nLines; } - ckfree((char *) pixelPtr); + ckfree(pixelPtr); return TCL_OK; } @@ -276,7 +280,7 @@ FileReadPPM( static int FileWritePPM( Tcl_Interp *interp, - CONST char *fileName, + const char *fileName, Tcl_Obj *format, Tk_PhotoImageBlock *blockPtr) { @@ -335,8 +339,8 @@ FileWritePPM( chan = NULL; writeerror: - Tcl_AppendResult(interp, "error writing \"", fileName, "\": ", - Tcl_PosixError(interp), NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf("error writing \"%s\": %s", + fileName, Tcl_PosixError(interp))); if (chan != NULL) { Tcl_Close(NULL, chan); } @@ -492,22 +496,22 @@ StringReadPPM( type = ReadPPMStringHeader(dataObj, &fileWidth, &fileHeight, &maxIntensity, &dataBuffer, &dataSize); if (type == 0) { - Tcl_AppendResult(interp, "couldn't read raw PPM header from string", - NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "couldn't read raw PPM header from string", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "NO_HEADER", NULL); return TCL_ERROR; } if ((fileWidth <= 0) || (fileHeight <= 0)) { - Tcl_AppendResult(interp, "PPM image data has dimension(s) <= 0", - NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "PPM image data has dimension(s) <= 0", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "DIMENSIONS", NULL); return TCL_ERROR; } if ((maxIntensity <= 0) || (maxIntensity > 0xffff)) { - char buffer[TCL_INTEGER_SPACE]; - - sprintf(buffer, "%d", maxIntensity); - Tcl_AppendResult(interp, - "PPM image data has bad maximum intensity value ", buffer, - NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "PPM image data has bad maximum intensity value %d", + maxIntensity)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "INTENSITY", NULL); return TCL_ERROR; } else if (maxIntensity > 0x00ff) { bytesPerChannel = 2; @@ -550,7 +554,9 @@ StringReadPPM( */ if (block.pitch*height > dataSize) { - Tcl_AppendResult(interp, "truncated PPM data", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "truncated PPM data", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "TRUNCATED", NULL); return TCL_ERROR; } block.pixelPtr = dataBuffer + srcX * block.pixelSize; @@ -572,7 +578,7 @@ StringReadPPM( nLines = 1; } nBytes = nLines * block.pitch; - pixelPtr = (unsigned char *) ckalloc((unsigned) nBytes); + pixelPtr = ckalloc(nBytes); block.pixelPtr = pixelPtr + srcX * block.pixelSize; for (h = height; h > 0; h -= nLines) { @@ -583,8 +589,10 @@ StringReadPPM( nBytes = nLines * block.pitch; } if (dataSize < nBytes) { - ckfree((char *) pixelPtr); - Tcl_AppendResult(interp, "truncated PPM data", NULL); + ckfree(pixelPtr); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "truncated PPM data", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "TRUNCATED", NULL); return TCL_ERROR; } if (maxIntensity < 0x00ff) { @@ -605,13 +613,13 @@ StringReadPPM( block.height = nLines; if (Tk_PhotoPutBlock(interp, imageHandle, &block, destX, destY, width, nLines, TK_PHOTO_COMPOSITE_SET) != TCL_OK) { - ckfree((char *) pixelPtr); + ckfree(pixelPtr); return TCL_ERROR; } destY += nLines; } - ckfree((char *) pixelPtr); + ckfree(pixelPtr); return TCL_OK; } diff --git a/generic/tkImgPhInstance.c b/generic/tkImgPhInstance.c new file mode 100644 index 0000000..72ebcb8 --- /dev/null +++ b/generic/tkImgPhInstance.c @@ -0,0 +1,1997 @@ +/* + * tkImgPhInstance.c -- + * + * Implements the rendering of images of type "photo" for Tk. Photo + * images are stored in full color (32 bits per pixel including alpha + * channel) and displayed using dithering if necessary. + * + * Copyright (c) 1994 The Australian National University. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. + * Copyright (c) 2002-2008 Donal K. Fellows + * Copyright (c) 2003 ActiveState Corporation. + * + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * Author: Paul Mackerras (paulus@cs.anu.edu.au), + * Department of Computer Science, + * Australian National University. + */ + +#include "tkImgPhoto.h" +#ifdef MAC_OSX_TK +#define TKPUTIMAGE_CAN_BLEND +#endif + +/* + * Declaration for internal Xlib function used here: + */ + +extern int _XInitImageFuncPtrs(XImage *image); + +/* + * Forward declarations + */ + +#ifndef TKPUTIMAGE_CAN_BLEND +static void BlendComplexAlpha(XImage *bgImg, PhotoInstance *iPtr, + int xOffset, int yOffset, int width, int height); +#endif +static int IsValidPalette(PhotoInstance *instancePtr, + const char *palette); +static int CountBits(pixel mask); +static void GetColorTable(PhotoInstance *instancePtr); +static void FreeColorTable(ColorTable *colorPtr, int force); +static void AllocateColors(ColorTable *colorPtr); +static void DisposeColorTable(ClientData clientData); +static int ReclaimColors(ColorTableId *id, int numColors); + +/* + * Hash table used to hash from (display, colormap, palette, gamma) to + * ColorTable address. + */ + +static Tcl_HashTable imgPhotoColorHash; +static int imgPhotoColorHashInitialized; +#define N_COLOR_HASH (sizeof(ColorTableId) / sizeof(int)) + +/* + *---------------------------------------------------------------------- + * + * TkImgPhotoConfigureInstance -- + * + * This function is called to create displaying information for a photo + * image instance based on the configuration information in the master. + * It is invoked both when new instances are created and when the master + * is reconfigured. + * + * Results: + * None. + * + * Side effects: + * Generates errors via Tcl_BackgroundException if there are problems in + * setting up the instance. + * + *---------------------------------------------------------------------- + */ + +void +TkImgPhotoConfigureInstance( + PhotoInstance *instancePtr) /* Instance to reconfigure. */ +{ + PhotoMaster *masterPtr = instancePtr->masterPtr; + XImage *imagePtr; + int bitsPerPixel; + ColorTable *colorTablePtr; + XRectangle validBox; + + /* + * If the -palette configuration option has been set for the master, use + * the value specified for our palette, but only if it is a valid palette + * for our windows. Use the gamma value specified the master. + */ + + if ((masterPtr->palette && masterPtr->palette[0]) + && IsValidPalette(instancePtr, masterPtr->palette)) { + instancePtr->palette = masterPtr->palette; + } else { + instancePtr->palette = instancePtr->defaultPalette; + } + instancePtr->gamma = masterPtr->gamma; + + /* + * If we don't currently have a color table, or if the one we have no + * longer applies (e.g. because our palette or gamma has changed), get a + * new one. + */ + + colorTablePtr = instancePtr->colorTablePtr; + if ((colorTablePtr == NULL) + || (instancePtr->colormap != colorTablePtr->id.colormap) + || (instancePtr->palette != colorTablePtr->id.palette) + || (instancePtr->gamma != colorTablePtr->id.gamma)) { + /* + * Free up our old color table, and get a new one. + */ + + if (colorTablePtr != NULL) { + colorTablePtr->liveRefCount -= 1; + FreeColorTable(colorTablePtr, 0); + } + GetColorTable(instancePtr); + + /* + * Create a new XImage structure for sending data to the X server, if + * necessary. + */ + + if (instancePtr->colorTablePtr->flags & BLACK_AND_WHITE) { + bitsPerPixel = 1; + } else { + bitsPerPixel = instancePtr->visualInfo.depth; + } + + if ((instancePtr->imagePtr == NULL) + || (instancePtr->imagePtr->bits_per_pixel != bitsPerPixel)) { + if (instancePtr->imagePtr != NULL) { + XDestroyImage(instancePtr->imagePtr); + } + imagePtr = XCreateImage(instancePtr->display, + instancePtr->visualInfo.visual, (unsigned) bitsPerPixel, + (bitsPerPixel > 1? ZPixmap: XYBitmap), 0, NULL, + 1, 1, 32, 0); + instancePtr->imagePtr = imagePtr; + + /* + * We create images using the local host's endianness, rather than + * the endianness of the server; otherwise we would have to + * byte-swap any 16 or 32 bit values that we store in the image + * if the server's endianness is different from ours. + */ + + if (imagePtr != NULL) { +#ifdef WORDS_BIGENDIAN + imagePtr->byte_order = MSBFirst; +#else + imagePtr->byte_order = LSBFirst; +#endif + _XInitImageFuncPtrs(imagePtr); + } + } + } + + /* + * If the user has specified a width and/or height for the master which is + * different from our current width/height, set the size to the values + * specified by the user. If we have no pixmap, we do this also, since it + * has the side effect of allocating a pixmap for us. + */ + + if ((instancePtr->pixels == None) || (instancePtr->error == NULL) + || (instancePtr->width != masterPtr->width) + || (instancePtr->height != masterPtr->height)) { + TkImgPhotoInstanceSetSize(instancePtr); + } + + /* + * Redither this instance if necessary. + */ + + if ((masterPtr->flags & IMAGE_CHANGED) + || (instancePtr->colorTablePtr != colorTablePtr)) { + TkClipBox(masterPtr->validRegion, &validBox); + if ((validBox.width > 0) && (validBox.height > 0)) { + TkImgDitherInstance(instancePtr, validBox.x, validBox.y, + validBox.width, validBox.height); + } + } +} + +/* + *---------------------------------------------------------------------- + * + * TkImgPhotoGet -- + * + * This function is called for each use of a photo image in a widget. + * + * Results: + * The return value is a token for the instance, which is passed back to + * us in calls to TkImgPhotoDisplay and ImgPhotoFree. + * + * Side effects: + * A data structure is set up for the instance (or, an existing instance + * is re-used for the new one). + * + *---------------------------------------------------------------------- + */ + +ClientData +TkImgPhotoGet( + Tk_Window tkwin, /* Window in which the instance will be + * used. */ + ClientData masterData) /* Pointer to our master structure for the + * image. */ +{ + PhotoMaster *masterPtr = masterData; + PhotoInstance *instancePtr; + Colormap colormap; + int mono, nRed, nGreen, nBlue, numVisuals; + XVisualInfo visualInfo, *visInfoPtr; + char buf[TCL_INTEGER_SPACE * 3]; + XColor *white, *black; + XGCValues gcValues; + + /* + * Table of "best" choices for palette for PseudoColor displays with + * between 3 and 15 bits/pixel. + */ + + static const int paletteChoice[13][3] = { + /* #red, #green, #blue */ + {2, 2, 2, /* 3 bits, 8 colors */}, + {2, 3, 2, /* 4 bits, 12 colors */}, + {3, 4, 2, /* 5 bits, 24 colors */}, + {4, 5, 3, /* 6 bits, 60 colors */}, + {5, 6, 4, /* 7 bits, 120 colors */}, + {7, 7, 4, /* 8 bits, 198 colors */}, + {8, 10, 6, /* 9 bits, 480 colors */}, + {10, 12, 8, /* 10 bits, 960 colors */}, + {14, 15, 9, /* 11 bits, 1890 colors */}, + {16, 20, 12, /* 12 bits, 3840 colors */}, + {20, 24, 16, /* 13 bits, 7680 colors */}, + {26, 30, 20, /* 14 bits, 15600 colors */}, + {32, 32, 30, /* 15 bits, 30720 colors */} + }; + + /* + * See if there is already an instance for windows using the same + * colormap. If so then just re-use it. + */ + + colormap = Tk_Colormap(tkwin); + for (instancePtr = masterPtr->instancePtr; instancePtr != NULL; + instancePtr = instancePtr->nextPtr) { + if ((colormap == instancePtr->colormap) + && (Tk_Display(tkwin) == instancePtr->display)) { + /* + * Re-use this instance. + */ + + if (instancePtr->refCount == 0) { + /* + * We are resurrecting this instance. + */ + + Tcl_CancelIdleCall(TkImgDisposeInstance, instancePtr); + if (instancePtr->colorTablePtr != NULL) { + FreeColorTable(instancePtr->colorTablePtr, 0); + } + GetColorTable(instancePtr); + } + instancePtr->refCount++; + return instancePtr; + } + } + + /* + * The image isn't already in use in a window with the same colormap. Make + * a new instance of the image. + */ + + instancePtr = ckalloc(sizeof(PhotoInstance)); + instancePtr->masterPtr = masterPtr; + instancePtr->display = Tk_Display(tkwin); + instancePtr->colormap = Tk_Colormap(tkwin); + Tk_PreserveColormap(instancePtr->display, instancePtr->colormap); + instancePtr->refCount = 1; + instancePtr->colorTablePtr = NULL; + instancePtr->pixels = None; + instancePtr->error = NULL; + instancePtr->width = 0; + instancePtr->height = 0; + instancePtr->imagePtr = 0; + instancePtr->nextPtr = masterPtr->instancePtr; + masterPtr->instancePtr = instancePtr; + + /* + * Obtain information about the visual and decide on the default palette. + */ + + visualInfo.screen = Tk_ScreenNumber(tkwin); + visualInfo.visualid = XVisualIDFromVisual(Tk_Visual(tkwin)); + visInfoPtr = XGetVisualInfo(Tk_Display(tkwin), + VisualScreenMask | VisualIDMask, &visualInfo, &numVisuals); + if (visInfoPtr == NULL) { + Tcl_Panic("TkImgPhotoGet couldn't find visual for window"); + } + + nRed = 2; + nGreen = nBlue = 0; + mono = 1; + instancePtr->visualInfo = *visInfoPtr; + switch (visInfoPtr->class) { + case DirectColor: + case TrueColor: + nRed = 1 << CountBits(visInfoPtr->red_mask); + nGreen = 1 << CountBits(visInfoPtr->green_mask); + nBlue = 1 << CountBits(visInfoPtr->blue_mask); + mono = 0; + break; + case PseudoColor: + case StaticColor: + if (visInfoPtr->depth > 15) { + nRed = 32; + nGreen = 32; + nBlue = 32; + mono = 0; + } else if (visInfoPtr->depth >= 3) { + const int *ip = paletteChoice[visInfoPtr->depth - 3]; + + nRed = ip[0]; + nGreen = ip[1]; + nBlue = ip[2]; + mono = 0; + } + break; + case GrayScale: + case StaticGray: + nRed = 1 << visInfoPtr->depth; + break; + } + XFree((char *) visInfoPtr); + + if (mono) { + sprintf(buf, "%d", nRed); + } else { + sprintf(buf, "%d/%d/%d", nRed, nGreen, nBlue); + } + instancePtr->defaultPalette = Tk_GetUid(buf); + + /* + * Make a GC with background = black and foreground = white. + */ + + white = Tk_GetColor(masterPtr->interp, tkwin, "white"); + black = Tk_GetColor(masterPtr->interp, tkwin, "black"); + gcValues.foreground = (white != NULL)? white->pixel: + WhitePixelOfScreen(Tk_Screen(tkwin)); + gcValues.background = (black != NULL)? black->pixel: + BlackPixelOfScreen(Tk_Screen(tkwin)); + Tk_FreeColor(white); + Tk_FreeColor(black); + gcValues.graphics_exposures = False; + instancePtr->gc = Tk_GetGC(tkwin, + GCForeground|GCBackground|GCGraphicsExposures, &gcValues); + + /* + * Set configuration options and finish the initialization of the + * instance. This will also dither the image if necessary. + */ + + TkImgPhotoConfigureInstance(instancePtr); + + /* + * If this is the first instance, must set the size of the image. + */ + + if (instancePtr->nextPtr == NULL) { + Tk_ImageChanged(masterPtr->tkMaster, 0, 0, 0, 0, + masterPtr->width, masterPtr->height); + } + + return instancePtr; +} + +/* + *---------------------------------------------------------------------- + * + * BlendComplexAlpha -- + * + * This function is called when an image with partially transparent + * pixels must be drawn over another image. It blends the photo data onto + * a local copy of the surface that we are drawing on, *including* the + * pixels drawn by everything that should be drawn underneath the image. + * + * Much of this code has hard-coded values in for speed because this + * routine is performance critical for complex image drawing. + * + * Results: + * None. + * + * Side effects: + * Background image passed in gets drawn over with image data. + * + * Notes: + * This should work on all platforms that set mask and shift data + * properly from the visualInfo. RGB is really only a 24+ bpp version + * whereas RGB15 is the correct version and works for 15bpp+, but it + * slower, so it's only used for 15bpp+. + * + * Note that Win32 pre-defines those operations that we really need. + * + * Note that on MacOS, if the background comes from a Retina display + * then it will be twice as wide and twice as high as the photoimage. + * + *---------------------------------------------------------------------- + */ +#ifndef TKPUTIMAGE_CAN_BLEND +#ifndef _WIN32 +#define GetRValue(rgb) (UCHAR(((rgb) & red_mask) >> red_shift)) +#define GetGValue(rgb) (UCHAR(((rgb) & green_mask) >> green_shift)) +#define GetBValue(rgb) (UCHAR(((rgb) & blue_mask) >> blue_shift)) +#define RGB(r, g, b) ((unsigned)( \ + (UCHAR(r) << red_shift) | \ + (UCHAR(g) << green_shift) | \ + (UCHAR(b) << blue_shift) )) +#define RGB15(r, g, b) ((unsigned)( \ + (((r) * red_mask / 255) & red_mask) | \ + (((g) * green_mask / 255) & green_mask) | \ + (((b) * blue_mask / 255) & blue_mask) )) +#endif /* !_WIN32 */ + +static void +BlendComplexAlpha( + XImage *bgImg, /* Background image to draw on. */ + PhotoInstance *iPtr, /* Image instance to draw. */ + int xOffset, int yOffset, /* X & Y offset into image instance to + * draw. */ + int width, int height) /* Width & height of image to draw. */ +{ + int x, y, line; + unsigned long pixel; + unsigned char r, g, b, alpha, unalpha, *masterPtr; + unsigned char *alphaAr = iPtr->masterPtr->pix32; + + /* + * This blending is an integer version of the Source-Over compositing rule + * (see Porter&Duff, "Compositing Digital Images", proceedings of SIGGRAPH + * 1984) that has been hard-coded (for speed) to work with targetting a + * solid surface. + * + * The 'unalpha' field must be 255-alpha; it is separated out to encourage + * more efficient compilation. + */ + +#define ALPHA_BLEND(bgPix, imgPix, alpha, unalpha) \ + ((bgPix * unalpha + imgPix * alpha) / 255) + + /* + * We have to get the mask and shift info from the visual on non-Win32 so + * that the macros Get*Value(), RGB() and RGB15() work correctly. This + * might be cached for better performance. + */ + +#ifndef _WIN32 + unsigned long red_mask, green_mask, blue_mask; + unsigned long red_shift, green_shift, blue_shift; + Visual *visual = iPtr->visualInfo.visual; + + red_mask = visual->red_mask; + green_mask = visual->green_mask; + blue_mask = visual->blue_mask; + red_shift = 0; + green_shift = 0; + blue_shift = 0; + while ((0x0001 & (red_mask >> red_shift)) == 0) { + red_shift++; + } + while ((0x0001 & (green_mask >> green_shift)) == 0) { + green_shift++; + } + while ((0x0001 & (blue_mask >> blue_shift)) == 0) { + blue_shift++; + } +#endif /* !_WIN32 */ + + /* + * Only UNIX requires the special case for <24bpp. It varies with 3 extra + * shifts and uses RGB15. The 24+bpp version could also then be further + * optimized. + */ + +#if !defined(_WIN32) + if (bgImg->depth < 24) { + unsigned char red_mlen, green_mlen, blue_mlen; + + red_mlen = 8 - CountBits(red_mask >> red_shift); + green_mlen = 8 - CountBits(green_mask >> green_shift); + blue_mlen = 8 - CountBits(blue_mask >> blue_shift); + for (y = 0; y < height; y++) { + line = (y + yOffset) * iPtr->masterPtr->width; + for (x = 0; x < width; x++) { + masterPtr = alphaAr + ((line + x + xOffset) * 4); + alpha = masterPtr[3]; + + /* + * Ignore pixels that are fully transparent + */ + + if (alpha) { + /* + * We could perhaps be more efficient than XGetPixel for + * 24 and 32 bit displays, but this seems "fast enough". + */ + + r = masterPtr[0]; + g = masterPtr[1]; + b = masterPtr[2]; + if (alpha != 255) { + /* + * Only blend pixels that have some transparency + */ + + unsigned char ra, ga, ba; + + pixel = XGetPixel(bgImg, x, y); + ra = GetRValue(pixel) << red_mlen; + ga = GetGValue(pixel) << green_mlen; + ba = GetBValue(pixel) << blue_mlen; + unalpha = 255 - alpha; /* Calculate once. */ + r = ALPHA_BLEND(ra, r, alpha, unalpha); + g = ALPHA_BLEND(ga, g, alpha, unalpha); + b = ALPHA_BLEND(ba, b, alpha, unalpha); + } + XPutPixel(bgImg, x, y, RGB15(r, g, b)); + } + } + } + return; + } +#endif /* !_WIN32 */ + + for (y = 0; y < height; y++) { + line = (y + yOffset) * iPtr->masterPtr->width; + for (x = 0; x < width; x++) { + masterPtr = alphaAr + ((line + x + xOffset) * 4); + alpha = masterPtr[3]; + + /* + * Ignore pixels that are fully transparent + */ + + if (alpha) { + /* + * We could perhaps be more efficient than XGetPixel for 24 + * and 32 bit displays, but this seems "fast enough". + */ + + r = masterPtr[0]; + g = masterPtr[1]; + b = masterPtr[2]; + if (alpha != 255) { + /* + * Only blend pixels that have some transparency + */ + + unsigned char ra, ga, ba; + + pixel = XGetPixel(bgImg, x, y); + ra = GetRValue(pixel); + ga = GetGValue(pixel); + ba = GetBValue(pixel); + unalpha = 255 - alpha; /* Calculate once. */ + r = ALPHA_BLEND(ra, r, alpha, unalpha); + g = ALPHA_BLEND(ga, g, alpha, unalpha); + b = ALPHA_BLEND(ba, b, alpha, unalpha); + } + XPutPixel(bgImg, x, y, RGB(r, g, b)); + } + } + } +#undef ALPHA_BLEND +} +#endif /* TKPUTIMAGE_CAN_BLEND */ + +/* + *---------------------------------------------------------------------- + * + * TkImgPhotoDisplay -- + * + * This function is invoked to draw a photo image. + * + * Results: + * None. + * + * Side effects: + * A portion of the image gets rendered in a pixmap or window. + * + *---------------------------------------------------------------------- + */ + +void +TkImgPhotoDisplay( + ClientData clientData, /* Pointer to PhotoInstance structure for + * instance to be displayed. */ + Display *display, /* Display on which to draw image. */ + Drawable drawable, /* Pixmap or window in which to draw image. */ + int imageX, int imageY, /* Upper-left corner of region within image to + * draw. */ + int width, int height, /* Dimensions of region within image to + * draw. */ + int drawableX,int drawableY)/* Coordinates within drawable that correspond + * to imageX and imageY. */ +{ + PhotoInstance *instancePtr = clientData; +#ifndef TKPUTIMAGE_CAN_BLEND + XVisualInfo visInfo = instancePtr->visualInfo; +#endif + + /* + * If there's no pixmap, it means that an error occurred while creating + * the image instance so it can't be displayed. + */ + + if (instancePtr->pixels == None) { + return; + } + +#ifdef TKPUTIMAGE_CAN_BLEND + /* + * If TkPutImage can handle RGBA Ximages directly there is + * no need to call XGetImage or to do the Porter-Duff compositing by hand. + */ + + unsigned char *rgbaPixels = instancePtr->masterPtr->pix32; + XImage *photo = XCreateImage(display, NULL, 32, ZPixmap, 0, (char*)rgbaPixels, + (unsigned int)instancePtr->width, + (unsigned int)instancePtr->height, + 0, (unsigned int)(4 * instancePtr->width)); + TkPutImage(NULL, 0, display, drawable, instancePtr->gc, + photo, imageX, imageY, drawableX, drawableY, + (unsigned int) width, (unsigned int) height); + photo->data = NULL; + XDestroyImage(photo); +#else + + if ((instancePtr->masterPtr->flags & COMPLEX_ALPHA) + && visInfo.depth >= 15 + && (visInfo.class == DirectColor || visInfo.class == TrueColor)) { + Tk_ErrorHandler handler; + XImage *bgImg = NULL; + + /* + * Create an error handler to suppress the case where the input was + * not properly constrained, which can cause an X error. [Bug 979239] + */ + + handler = Tk_CreateErrorHandler(display, -1, -1, -1, NULL, NULL); + + /* + * Pull the current background from the display to blend with + */ + + bgImg = XGetImage(display, drawable, drawableX, drawableY, + (unsigned int)width, (unsigned int)height, AllPlanes, ZPixmap); + if (bgImg == NULL) { + Tk_DeleteErrorHandler(handler); + /* We failed to get the image, so draw without blending alpha. + * It's the best we can do. + */ + goto fallBack; + } + + BlendComplexAlpha(bgImg, instancePtr, imageX, imageY, width, height); + + /* + * Color info is unimportant as we only do this operation for depth >= + * 15. + */ + + TkPutImage(NULL, 0, display, drawable, instancePtr->gc, + bgImg, 0, 0, drawableX, drawableY, + (unsigned int) width, (unsigned int) height); + XDestroyImage(bgImg); + Tk_DeleteErrorHandler(handler); + } else { + /* + * masterPtr->region describes which parts of the image contain valid + * data. We set this region as the clip mask for the gc, setting its + * origin appropriately, and use it when drawing the image. + */ + + fallBack: + TkSetRegion(display, instancePtr->gc, + instancePtr->masterPtr->validRegion); + XSetClipOrigin(display, instancePtr->gc, drawableX - imageX, + drawableY - imageY); + XCopyArea(display, instancePtr->pixels, drawable, instancePtr->gc, + imageX, imageY, (unsigned) width, (unsigned) height, + drawableX, drawableY); + XSetClipMask(display, instancePtr->gc, None); + XSetClipOrigin(display, instancePtr->gc, 0, 0); + } + XFlush(display); +#endif +} + +/* + *---------------------------------------------------------------------- + * + * TkImgPhotoFree -- + * + * This function is called when a widget ceases to use a particular + * instance of an image. We don't actually get rid of the instance until + * later because we may be about to get this instance again. + * + * Results: + * None. + * + * Side effects: + * Internal data structures get cleaned up, later. + * + *---------------------------------------------------------------------- + */ + +void +TkImgPhotoFree( + ClientData clientData, /* Pointer to PhotoInstance structure for + * instance to be displayed. */ + Display *display) /* Display containing window that used + * image. */ +{ + PhotoInstance *instancePtr = clientData; + ColorTable *colorPtr; + + if (instancePtr->refCount-- > 1) { + return; + } + + /* + * There are no more uses of the image within this widget. Decrement the + * count of live uses of its color table, so that its colors can be + * reclaimed if necessary, and set up an idle call to free the instance + * structure. + */ + + colorPtr = instancePtr->colorTablePtr; + if (colorPtr != NULL) { + colorPtr->liveRefCount -= 1; + } + + Tcl_DoWhenIdle(TkImgDisposeInstance, instancePtr); +} + +/* + *---------------------------------------------------------------------- + * + * TkImgPhotoInstanceSetSize -- + * + * This function reallocates the instance pixmap and dithering error + * array for a photo instance, as necessary, to change the image's size + * to `width' x `height' pixels. + * + * Results: + * None. + * + * Side effects: + * Storage gets reallocated, here and in the X server. + * + *---------------------------------------------------------------------- + */ + +void +TkImgPhotoInstanceSetSize( + PhotoInstance *instancePtr) /* Instance whose size is to be changed. */ +{ + PhotoMaster *masterPtr; + schar *newError, *errSrcPtr, *errDestPtr; + int h, offset; + XRectangle validBox; + Pixmap newPixmap; + + masterPtr = instancePtr->masterPtr; + TkClipBox(masterPtr->validRegion, &validBox); + + if ((instancePtr->width != masterPtr->width) + || (instancePtr->height != masterPtr->height) + || (instancePtr->pixels == None)) { + newPixmap = Tk_GetPixmap(instancePtr->display, + RootWindow(instancePtr->display, + instancePtr->visualInfo.screen), + (masterPtr->width > 0) ? masterPtr->width: 1, + (masterPtr->height > 0) ? masterPtr->height: 1, + instancePtr->visualInfo.depth); + if (!newPixmap) { + Tcl_Panic("Fail to create pixmap with Tk_GetPixmap in TkImgPhotoInstanceSetSize"); + } + + /* + * The following is a gross hack needed to properly support colormaps + * under Windows. Before the pixels can be copied to the pixmap, the + * relevent colormap must be associated with the drawable. Normally we + * can infer this association from the window that was used to create + * the pixmap. However, in this case we're using the root window, so + * we have to be more explicit. + */ + + TkSetPixmapColormap(newPixmap, instancePtr->colormap); + + if (instancePtr->pixels != None) { + /* + * Copy any common pixels from the old pixmap and free it. + */ + + XCopyArea(instancePtr->display, instancePtr->pixels, newPixmap, + instancePtr->gc, validBox.x, validBox.y, + validBox.width, validBox.height, validBox.x, validBox.y); + Tk_FreePixmap(instancePtr->display, instancePtr->pixels); + } + instancePtr->pixels = newPixmap; + } + + if ((instancePtr->width != masterPtr->width) + || (instancePtr->height != masterPtr->height) + || (instancePtr->error == NULL)) { + if (masterPtr->height > 0 && masterPtr->width > 0) { + /* + * TODO: use attemptckalloc() here once there is a strategy that + * will allow us to recover from failure. Right now, there's no + * such possibility. + */ + + newError = ckalloc(masterPtr->height * masterPtr->width + * 3 * sizeof(schar)); + + /* + * Zero the new array so that we don't get bogus error values + * propagating into areas we dither later. + */ + + if ((instancePtr->error != NULL) + && ((instancePtr->width == masterPtr->width) + || (validBox.width == masterPtr->width))) { + if (validBox.y > 0) { + memset(newError, 0, (size_t) + validBox.y * masterPtr->width * 3 * sizeof(schar)); + } + h = validBox.y + validBox.height; + if (h < masterPtr->height) { + memset(newError + h*masterPtr->width*3, 0, + (size_t) (masterPtr->height - h) + * masterPtr->width * 3 * sizeof(schar)); + } + } else { + memset(newError, 0, (size_t) + masterPtr->height * masterPtr->width *3*sizeof(schar)); + } + } else { + newError = NULL; + } + + if (instancePtr->error != NULL) { + /* + * Copy the common area over to the new array and free the old + * array. + */ + + if (masterPtr->width == instancePtr->width) { + offset = validBox.y * masterPtr->width * 3; + memcpy(newError + offset, instancePtr->error + offset, + (size_t) (validBox.height + * masterPtr->width * 3 * sizeof(schar))); + + } else if (validBox.width > 0 && validBox.height > 0) { + errDestPtr = newError + + (validBox.y * masterPtr->width + validBox.x) * 3; + errSrcPtr = instancePtr->error + + (validBox.y * instancePtr->width + validBox.x) * 3; + + for (h = validBox.height; h > 0; --h) { + memcpy(errDestPtr, errSrcPtr, + validBox.width * 3 * sizeof(schar)); + errDestPtr += masterPtr->width * 3; + errSrcPtr += instancePtr->width * 3; + } + } + ckfree(instancePtr->error); + } + + instancePtr->error = newError; + } + + instancePtr->width = masterPtr->width; + instancePtr->height = masterPtr->height; +} + +/* + *---------------------------------------------------------------------- + * + * IsValidPalette -- + * + * This function is called to check whether a value given for the + * -palette option is valid for a particular instance of a photo image. + * + * Results: + * A boolean value: 1 if the palette is acceptable, 0 otherwise. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static int +IsValidPalette( + PhotoInstance *instancePtr, /* Instance to which the palette specification + * is to be applied. */ + const char *palette) /* Palette specification string. */ +{ + int nRed, nGreen, nBlue, mono, numColors; + char *endp; + + /* + * First parse the specification: it must be of the form %d or %d/%d/%d. + */ + + nRed = strtol(palette, &endp, 10); + if ((endp == palette) || ((*endp != 0) && (*endp != '/')) + || (nRed < 2) || (nRed > 256)) { + return 0; + } + + if (*endp == 0) { + mono = 1; + nGreen = nBlue = nRed; + } else { + palette = endp + 1; + nGreen = strtol(palette, &endp, 10); + if ((endp == palette) || (*endp != '/') || (nGreen < 2) + || (nGreen > 256)) { + return 0; + } + palette = endp + 1; + nBlue = strtol(palette, &endp, 10); + if ((endp == palette) || (*endp != 0) || (nBlue < 2) + || (nBlue > 256)) { + return 0; + } + mono = 0; + } + + switch (instancePtr->visualInfo.class) { + case DirectColor: + case TrueColor: + if ((nRed > (1 << CountBits(instancePtr->visualInfo.red_mask))) + || (nGreen>(1<<CountBits(instancePtr->visualInfo.green_mask))) + || (nBlue>(1<<CountBits(instancePtr->visualInfo.blue_mask)))) { + return 0; + } + break; + case PseudoColor: + case StaticColor: + numColors = nRed; + if (!mono) { + numColors *= nGreen * nBlue; + } + if (numColors > (1 << instancePtr->visualInfo.depth)) { + return 0; + } + break; + case GrayScale: + case StaticGray: + if (!mono || (nRed > (1 << instancePtr->visualInfo.depth))) { + return 0; + } + break; + } + + return 1; +} + +/* + *---------------------------------------------------------------------- + * + * CountBits -- + * + * This function counts how many bits are set to 1 in `mask'. + * + * Results: + * The integer number of bits. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static int +CountBits( + pixel mask) /* Value to count the 1 bits in. */ +{ + int n; + + for (n=0 ; mask!=0 ; mask&=mask-1) { + n++; + } + return n; +} + +/* + *---------------------------------------------------------------------- + * + * GetColorTable -- + * + * This function is called to allocate a table of colormap information + * for an instance of a photo image. Only one such table is allocated for + * all photo instances using the same display, colormap, palette and + * gamma values, so that the application need only request a set of + * colors from the X server once for all such photo widgets. This + * function maintains a hash table to find previously-allocated + * ColorTables. + * + * Results: + * None. + * + * Side effects: + * A new ColorTable may be allocated and placed in the hash table, and + * have colors allocated for it. + * + *---------------------------------------------------------------------- + */ + +static void +GetColorTable( + PhotoInstance *instancePtr) /* Instance needing a color table. */ +{ + ColorTable *colorPtr; + Tcl_HashEntry *entry; + ColorTableId id; + int isNew; + + /* + * Look for an existing ColorTable in the hash table. + */ + + memset(&id, 0, sizeof(id)); + id.display = instancePtr->display; + id.colormap = instancePtr->colormap; + id.palette = instancePtr->palette; + id.gamma = instancePtr->gamma; + if (!imgPhotoColorHashInitialized) { + Tcl_InitHashTable(&imgPhotoColorHash, N_COLOR_HASH); + imgPhotoColorHashInitialized = 1; + } + entry = Tcl_CreateHashEntry(&imgPhotoColorHash, (char *) &id, &isNew); + + if (!isNew) { + /* + * Re-use the existing entry. + */ + + colorPtr = Tcl_GetHashValue(entry); + } else { + /* + * No color table currently available; need to make one. + */ + + colorPtr = ckalloc(sizeof(ColorTable)); + + /* + * The following line of code should not normally be needed due to the + * assignment in the following line. However, it compensates for bugs + * in some compilers (HP, for example) where sizeof(ColorTable) is 24 + * but the assignment only copies 20 bytes, leaving 4 bytes + * uninitialized; these cause problems when using the id for lookups + * in imgPhotoColorHash, and can result in core dumps. + */ + + memset(&colorPtr->id, 0, sizeof(ColorTableId)); + colorPtr->id = id; + Tk_PreserveColormap(colorPtr->id.display, colorPtr->id.colormap); + colorPtr->flags = 0; + colorPtr->refCount = 0; + colorPtr->liveRefCount = 0; + colorPtr->numColors = 0; + colorPtr->visualInfo = instancePtr->visualInfo; + colorPtr->pixelMap = NULL; + Tcl_SetHashValue(entry, colorPtr); + } + + colorPtr->refCount++; + colorPtr->liveRefCount++; + instancePtr->colorTablePtr = colorPtr; + if (colorPtr->flags & DISPOSE_PENDING) { + Tcl_CancelIdleCall(DisposeColorTable, colorPtr); + colorPtr->flags &= ~DISPOSE_PENDING; + } + + /* + * Allocate colors for this color table if necessary. + */ + + if ((colorPtr->numColors == 0) && !(colorPtr->flags & BLACK_AND_WHITE)) { + AllocateColors(colorPtr); + } +} + +/* + *---------------------------------------------------------------------- + * + * FreeColorTable -- + * + * This function is called when an instance ceases using a color table. + * + * Results: + * None. + * + * Side effects: + * If no other instances are using this color table, a when-idle handler + * is registered to free up the color table and the colors allocated for + * it. + * + *---------------------------------------------------------------------- + */ + +static void +FreeColorTable( + ColorTable *colorPtr, /* Pointer to the color table which is no + * longer required by an instance. */ + int force) /* Force free to happen immediately. */ +{ + colorPtr->refCount--; + if (colorPtr->refCount > 0) { + return; + } + + if (force) { + if (colorPtr->flags & DISPOSE_PENDING) { + Tcl_CancelIdleCall(DisposeColorTable, colorPtr); + colorPtr->flags &= ~DISPOSE_PENDING; + } + DisposeColorTable(colorPtr); + } else if (!(colorPtr->flags & DISPOSE_PENDING)) { + Tcl_DoWhenIdle(DisposeColorTable, colorPtr); + colorPtr->flags |= DISPOSE_PENDING; + } +} + +/* + *---------------------------------------------------------------------- + * + * AllocateColors -- + * + * This function allocates the colors required by a color table, and sets + * up the fields in the color table data structure which are used in + * dithering. + * + * Results: + * None. + * + * Side effects: + * Colors are allocated from the X server. Fields in the color table data + * structure are updated. + * + *---------------------------------------------------------------------- + */ + +static void +AllocateColors( + ColorTable *colorPtr) /* Pointer to the color table requiring colors + * to be allocated. */ +{ + int i, r, g, b, rMult, mono; + int numColors, nRed, nGreen, nBlue; + double fr, fg, fb, igam; + XColor *colors; + unsigned long *pixels; + + /* + * 16-bit intensity value for i/n of full intensity. + */ +#define CFRAC(i, n) ((i) * 65535 / (n)) + + /* As for CFRAC, but apply exponent of g. */ +#define CGFRAC(i, n, g) ((int)(65535 * pow((double)(i) / (n), (g)))) + + /* + * First parse the palette specification to get the required number of + * shades of each primary. + */ + + mono = sscanf(colorPtr->id.palette, "%d/%d/%d", &nRed, &nGreen, &nBlue) + <= 1; + igam = 1.0 / colorPtr->id.gamma; + + /* + * Each time around this loop, we reduce the number of colors we're trying + * to allocate until we succeed in allocating all of the colors we need. + */ + + for (;;) { + /* + * If we are using 1 bit/pixel, we don't need to allocate any colors + * (we just use the foreground and background colors in the GC). + */ + + if (mono && (nRed <= 2)) { + colorPtr->flags |= BLACK_AND_WHITE; + return; + } + + /* + * Calculate the RGB coordinates of the colors we want to allocate and + * store them in *colors. + */ + + if ((colorPtr->visualInfo.class == DirectColor) + || (colorPtr->visualInfo.class == TrueColor)) { + + /* + * Direct/True Color: allocate shades of red, green, blue + * independently. + */ + + if (mono) { + numColors = nGreen = nBlue = nRed; + } else { + numColors = MAX(MAX(nRed, nGreen), nBlue); + } + colors = ckalloc(numColors * sizeof(XColor)); + + for (i = 0; i < numColors; ++i) { + if (igam == 1.0) { + colors[i].red = CFRAC(i, nRed - 1); + colors[i].green = CFRAC(i, nGreen - 1); + colors[i].blue = CFRAC(i, nBlue - 1); + } else { + colors[i].red = CGFRAC(i, nRed - 1, igam); + colors[i].green = CGFRAC(i, nGreen - 1, igam); + colors[i].blue = CGFRAC(i, nBlue - 1, igam); + } + } + } else { + /* + * PseudoColor, StaticColor, GrayScale or StaticGray visual: we + * have to allocate each color in the color cube separately. + */ + + numColors = (mono) ? nRed: (nRed * nGreen * nBlue); + colors = ckalloc(numColors * sizeof(XColor)); + + if (!mono) { + /* + * Color display using a PseudoColor or StaticColor visual. + */ + + i = 0; + for (r = 0; r < nRed; ++r) { + for (g = 0; g < nGreen; ++g) { + for (b = 0; b < nBlue; ++b) { + if (igam == 1.0) { + colors[i].red = CFRAC(r, nRed - 1); + colors[i].green = CFRAC(g, nGreen - 1); + colors[i].blue = CFRAC(b, nBlue - 1); + } else { + colors[i].red = CGFRAC(r, nRed - 1, igam); + colors[i].green = CGFRAC(g, nGreen - 1, igam); + colors[i].blue = CGFRAC(b, nBlue - 1, igam); + } + i++; + } + } + } + } else { + /* + * Monochrome display - allocate the shades of gray we want. + */ + + for (i = 0; i < numColors; ++i) { + if (igam == 1.0) { + r = CFRAC(i, numColors - 1); + } else { + r = CGFRAC(i, numColors - 1, igam); + } + colors[i].red = colors[i].green = colors[i].blue = r; + } + } + } + + /* + * Now try to allocate the colors we've calculated. + */ + + pixels = ckalloc(numColors * sizeof(unsigned long)); + for (i = 0; i < numColors; ++i) { + if (!XAllocColor(colorPtr->id.display, colorPtr->id.colormap, + &colors[i])) { + /* + * Can't get all the colors we want in the default colormap; + * first try freeing colors from other unused color tables. + */ + + if (!ReclaimColors(&colorPtr->id, numColors - i) + || !XAllocColor(colorPtr->id.display, + colorPtr->id.colormap, &colors[i])) { + /* + * Still can't allocate the color. + */ + + break; + } + } + pixels[i] = colors[i].pixel; + } + + /* + * If we didn't get all of the colors, reduce the resolution of the + * color cube, free the ones we got, and try again. + */ + + if (i >= numColors) { + break; + } + XFreeColors(colorPtr->id.display, colorPtr->id.colormap, pixels, i, 0); + ckfree(colors); + ckfree(pixels); + + if (!mono) { + if ((nRed == 2) && (nGreen == 2) && (nBlue == 2)) { + /* + * Fall back to 1-bit monochrome display. + */ + + mono = 1; + } else { + /* + * Reduce the number of shades of each primary to about 3/4 of + * the previous value. This should reduce the total number of + * colors required to about half the previous value for + * PseudoColor displays. + */ + + nRed = (nRed * 3 + 2) / 4; + nGreen = (nGreen * 3 + 2) / 4; + nBlue = (nBlue * 3 + 2) / 4; + } + } else { + /* + * Reduce the number of shades of gray to about 1/2. + */ + + nRed = nRed / 2; + } + } + + /* + * We have allocated all of the necessary colors: fill in various fields + * of the ColorTable record. + */ + + if (!mono) { + colorPtr->flags |= COLOR_WINDOW; + + /* + * The following is a hairy hack. We only want to index into the + * pixelMap on colormap displays. However, if the display is on + * Windows, then we actually want to store the index not the value + * since we will be passing the color table into the TkPutImage call. + */ + +#ifndef _WIN32 + if ((colorPtr->visualInfo.class != DirectColor) + && (colorPtr->visualInfo.class != TrueColor)) { + colorPtr->flags |= MAP_COLORS; + } +#endif /* _WIN32 */ + } + + colorPtr->numColors = numColors; + colorPtr->pixelMap = pixels; + + /* + * Set up quantization tables for dithering. + */ + + rMult = nGreen * nBlue; + for (i = 0; i < 256; ++i) { + r = (i * (nRed - 1) + 127) / 255; + if (mono) { + fr = (double) colors[r].red / 65535.0; + if (colorPtr->id.gamma != 1.0 ) { + fr = pow(fr, colorPtr->id.gamma); + } + colorPtr->colorQuant[0][i] = (int)(fr * 255.99); + colorPtr->redValues[i] = colors[r].pixel; + } else { + g = (i * (nGreen - 1) + 127) / 255; + b = (i * (nBlue - 1) + 127) / 255; + if ((colorPtr->visualInfo.class == DirectColor) + || (colorPtr->visualInfo.class == TrueColor)) { + colorPtr->redValues[i] = + colors[r].pixel & colorPtr->visualInfo.red_mask; + colorPtr->greenValues[i] = + colors[g].pixel & colorPtr->visualInfo.green_mask; + colorPtr->blueValues[i] = + colors[b].pixel & colorPtr->visualInfo.blue_mask; + } else { + r *= rMult; + g *= nBlue; + colorPtr->redValues[i] = r; + colorPtr->greenValues[i] = g; + colorPtr->blueValues[i] = b; + } + fr = (double) colors[r].red / 65535.0; + fg = (double) colors[g].green / 65535.0; + fb = (double) colors[b].blue / 65535.0; + if (colorPtr->id.gamma != 1.0) { + fr = pow(fr, colorPtr->id.gamma); + fg = pow(fg, colorPtr->id.gamma); + fb = pow(fb, colorPtr->id.gamma); + } + colorPtr->colorQuant[0][i] = (int)(fr * 255.99); + colorPtr->colorQuant[1][i] = (int)(fg * 255.99); + colorPtr->colorQuant[2][i] = (int)(fb * 255.99); + } + } + + ckfree(colors); +} + +/* + *---------------------------------------------------------------------- + * + * DisposeColorTable -- + * + * Release a color table and its associated resources. + * + * Results: + * None. + * + * Side effects: + * The colors in the argument color table are freed, as is the color + * table structure itself. The color table is removed from the hash table + * which is used to locate color tables. + * + *---------------------------------------------------------------------- + */ + +static void +DisposeColorTable( + ClientData clientData) /* Pointer to the ColorTable whose + * colors are to be released. */ +{ + ColorTable *colorPtr = clientData; + Tcl_HashEntry *entry; + + if (colorPtr->pixelMap != NULL) { + if (colorPtr->numColors > 0) { + XFreeColors(colorPtr->id.display, colorPtr->id.colormap, + colorPtr->pixelMap, colorPtr->numColors, 0); + Tk_FreeColormap(colorPtr->id.display, colorPtr->id.colormap); + } + ckfree(colorPtr->pixelMap); + } + + entry = Tcl_FindHashEntry(&imgPhotoColorHash, (char *) &colorPtr->id); + if (entry == NULL) { + Tcl_Panic("DisposeColorTable couldn't find hash entry"); + } + Tcl_DeleteHashEntry(entry); + + ckfree(colorPtr); +} + +/* + *---------------------------------------------------------------------- + * + * ReclaimColors -- + * + * This function is called to try to free up colors in the colormap used + * by a color table. It looks for other color tables with the same + * colormap and with a zero live reference count, and frees their colors. + * It only does so if there is the possibility of freeing up at least + * `numColors' colors. + * + * Results: + * The return value is TRUE if any colors were freed, FALSE otherwise. + * + * Side effects: + * ColorTables which are not currently in use may lose their color + * allocations. + * + *---------------------------------------------------------------------- + */ + +static int +ReclaimColors( + ColorTableId *id, /* Pointer to information identifying + * the color table which needs more colors. */ + int numColors) /* Number of colors required. */ +{ + Tcl_HashSearch srch; + Tcl_HashEntry *entry; + ColorTable *colorPtr; + int nAvail = 0; + + /* + * First scan through the color hash table to get an upper bound on how + * many colors we might be able to free. + */ + + entry = Tcl_FirstHashEntry(&imgPhotoColorHash, &srch); + while (entry != NULL) { + colorPtr = Tcl_GetHashValue(entry); + if ((colorPtr->id.display == id->display) + && (colorPtr->id.colormap == id->colormap) + && (colorPtr->liveRefCount == 0 )&& (colorPtr->numColors != 0) + && ((colorPtr->id.palette != id->palette) + || (colorPtr->id.gamma != id->gamma))) { + /* + * We could take this guy's colors off him. + */ + + nAvail += colorPtr->numColors; + } + entry = Tcl_NextHashEntry(&srch); + } + + /* + * nAvail is an (over)estimate of the number of colors we could free. + */ + + if (nAvail < numColors) { + return 0; + } + + /* + * Scan through a second time freeing colors. + */ + + entry = Tcl_FirstHashEntry(&imgPhotoColorHash, &srch); + while ((entry != NULL) && (numColors > 0)) { + colorPtr = Tcl_GetHashValue(entry); + if ((colorPtr->id.display == id->display) + && (colorPtr->id.colormap == id->colormap) + && (colorPtr->liveRefCount == 0) && (colorPtr->numColors != 0) + && ((colorPtr->id.palette != id->palette) + || (colorPtr->id.gamma != id->gamma))) { + /* + * Free the colors that this ColorTable has. + */ + + XFreeColors(colorPtr->id.display, colorPtr->id.colormap, + colorPtr->pixelMap, colorPtr->numColors, 0); + numColors -= colorPtr->numColors; + colorPtr->numColors = 0; + ckfree(colorPtr->pixelMap); + colorPtr->pixelMap = NULL; + } + + entry = Tcl_NextHashEntry(&srch); + } + return 1; /* We freed some colors. */ +} + +/* + *---------------------------------------------------------------------- + * + * TkImgDisposeInstance -- + * + * This function is called to finally free up an instance of a photo + * image which is no longer required. + * + * Results: + * None. + * + * Side effects: + * The instance data structure and the resources it references are freed. + * + *---------------------------------------------------------------------- + */ + +void +TkImgDisposeInstance( + ClientData clientData) /* Pointer to the instance whose resources are + * to be released. */ +{ + PhotoInstance *instancePtr = clientData; + PhotoInstance *prevPtr; + + if (instancePtr->pixels != None) { + Tk_FreePixmap(instancePtr->display, instancePtr->pixels); + } + if (instancePtr->gc != NULL) { + Tk_FreeGC(instancePtr->display, instancePtr->gc); + } + if (instancePtr->imagePtr != NULL) { + XDestroyImage(instancePtr->imagePtr); + } + if (instancePtr->error != NULL) { + ckfree(instancePtr->error); + } + if (instancePtr->colorTablePtr != NULL) { + FreeColorTable(instancePtr->colorTablePtr, 1); + } + + if (instancePtr->masterPtr->instancePtr == instancePtr) { + instancePtr->masterPtr->instancePtr = instancePtr->nextPtr; + } else { + for (prevPtr = instancePtr->masterPtr->instancePtr; + prevPtr->nextPtr != instancePtr; prevPtr = prevPtr->nextPtr) { + /* Empty loop body. */ + } + prevPtr->nextPtr = instancePtr->nextPtr; + } + Tk_FreeColormap(instancePtr->display, instancePtr->colormap); + ckfree(instancePtr); +} + +/* + *---------------------------------------------------------------------- + * + * TkImgDitherInstance -- + * + * This function is called to update an area of an instance's pixmap by + * dithering the corresponding area of the master. + * + * Results: + * None. + * + * Side effects: + * The instance's pixmap gets updated. + * + *---------------------------------------------------------------------- + */ + +void +TkImgDitherInstance( + PhotoInstance *instancePtr, /* The instance to be updated. */ + int xStart, int yStart, /* Coordinates of the top-left pixel in the + * block to be dithered. */ + int width, int height) /* Dimensions of the block to be dithered. */ +{ + PhotoMaster *masterPtr = instancePtr->masterPtr; + ColorTable *colorPtr = instancePtr->colorTablePtr; + XImage *imagePtr; + int nLines, bigEndian, i, c, x, y, xEnd, doDithering = 1; + int bitsPerPixel, bytesPerLine, lineLength; + unsigned char *srcLinePtr; + schar *errLinePtr; + pixel firstBit, word, mask; + + /* + * Turn dithering off in certain cases where it is not needed (TrueColor, + * DirectColor with many colors). + */ + + if ((colorPtr->visualInfo.class == DirectColor) + || (colorPtr->visualInfo.class == TrueColor)) { + int nRed, nGreen, nBlue, result; + + result = sscanf(colorPtr->id.palette, "%d/%d/%d", &nRed, + &nGreen, &nBlue); + if ((nRed >= 256) + && ((result == 1) || ((nGreen >= 256) && (nBlue >= 256)))) { + doDithering = 0; + } + } + + /* + * First work out how many lines to do at a time, then how many bytes + * we'll need for pixel storage, and allocate it. + */ + + nLines = (MAX_PIXELS + width - 1) / width; + if (nLines < 1) { + nLines = 1; + } + if (nLines > height ) { + nLines = height; + } + + imagePtr = instancePtr->imagePtr; + if (imagePtr == NULL) { + return; /* We must be really tight on memory. */ + } + bitsPerPixel = imagePtr->bits_per_pixel; + bytesPerLine = ((bitsPerPixel * width + 31) >> 3) & ~3; + imagePtr->width = width; + imagePtr->height = nLines; + imagePtr->bytes_per_line = bytesPerLine; + + /* + * TODO: use attemptckalloc() here once we have some strategy for + * recovering from the failure. + */ + + imagePtr->data = ckalloc(imagePtr->bytes_per_line * nLines); + bigEndian = imagePtr->bitmap_bit_order == MSBFirst; + firstBit = bigEndian? (1 << (imagePtr->bitmap_unit - 1)): 1; + + lineLength = masterPtr->width * 3; + srcLinePtr = masterPtr->pix32 + (yStart * masterPtr->width + xStart) * 4; + errLinePtr = instancePtr->error + yStart * lineLength + xStart * 3; + xEnd = xStart + width; + + /* + * Loop over the image, doing at most nLines lines before updating the + * screen image. + */ + + for (; height > 0; height -= nLines) { + unsigned char *dstLinePtr = (unsigned char *) imagePtr->data; + int yEnd; + + if (nLines > height) { + nLines = height; + } + yEnd = yStart + nLines; + for (y = yStart; y < yEnd; ++y) { + unsigned char *srcPtr = srcLinePtr; + schar *errPtr = errLinePtr; + unsigned char *destBytePtr = dstLinePtr; + pixel *destLongPtr = (pixel *) dstLinePtr; + + if (colorPtr->flags & COLOR_WINDOW) { + /* + * Color window. We dither the three components independently, + * using Floyd-Steinberg dithering, which propagates errors + * from the quantization of pixels to the pixels below and to + * the right. + */ + + for (x = xStart; x < xEnd; ++x) { + int col[3]; + + if (doDithering) { + for (i = 0; i < 3; ++i) { + /* + * Compute the error propagated into this pixel + * for this component. If e[x,y] is the array of + * quantization error values, we compute + * 7/16 * e[x-1,y] + 1/16 * e[x-1,y-1] + * + 5/16 * e[x,y-1] + 3/16 * e[x+1,y-1] + * and round it to an integer. + * + * The expression ((c + 2056) >> 4) - 128 computes + * round(c / 16), and works correctly on machines + * without a sign-extending right shift. + */ + + c = (x > 0) ? errPtr[-3] * 7: 0; + if (y > 0) { + if (x > 0) { + c += errPtr[-lineLength-3]; + } + c += errPtr[-lineLength] * 5; + if ((x + 1) < masterPtr->width) { + c += errPtr[-lineLength+3] * 3; + } + } + + /* + * Add the propagated error to the value of this + * component, quantize it, and store the + * quantization error. + */ + + c = ((c + 2056) >> 4) - 128 + *srcPtr++; + if (c < 0) { + c = 0; + } else if (c > 255) { + c = 255; + } + col[i] = colorPtr->colorQuant[i][c]; + *errPtr++ = c - col[i]; + } + } else { + /* + * Output is virtually continuous in this case, so + * don't bother dithering. + */ + + col[0] = *srcPtr++; + col[1] = *srcPtr++; + col[2] = *srcPtr++; + } + srcPtr++; + + /* + * Translate the quantized component values into an X + * pixel value, and store it in the image. + */ + + i = colorPtr->redValues[col[0]] + + colorPtr->greenValues[col[1]] + + colorPtr->blueValues[col[2]]; + if (colorPtr->flags & MAP_COLORS) { + i = colorPtr->pixelMap[i]; + } + switch (bitsPerPixel) { + case NBBY: + *destBytePtr++ = i; + break; +#ifndef _WIN32 + /* + * This case is not valid for Windows because the + * image format is different from the pixel format in + * Win32. Eventually we need to fix the image code in + * Tk to use the Windows native image ordering. This + * would speed up the image code for all of the common + * sizes. + */ + + case NBBY * sizeof(pixel): + *destLongPtr++ = i; + break; +#endif + default: + XPutPixel(imagePtr, x - xStart, y - yStart, + (unsigned) i); + } + } + + } else if (bitsPerPixel > 1) { + /* + * Multibit monochrome window. The operation here is similar + * to the color window case above, except that there is only + * one component. If the master image is in color, use the + * luminance computed as + * 0.344 * red + 0.5 * green + 0.156 * blue. + */ + + for (x = xStart; x < xEnd; ++x) { + c = (x > 0) ? errPtr[-1] * 7: 0; + if (y > 0) { + if (x > 0) { + c += errPtr[-lineLength-1]; + } + c += errPtr[-lineLength] * 5; + if (x + 1 < masterPtr->width) { + c += errPtr[-lineLength+1] * 3; + } + } + c = ((c + 2056) >> 4) - 128; + + if (masterPtr->flags & COLOR_IMAGE) { + c += (unsigned) (srcPtr[0] * 11 + srcPtr[1] * 16 + + srcPtr[2] * 5 + 16) >> 5; + } else { + c += srcPtr[0]; + } + srcPtr += 4; + + if (c < 0) { + c = 0; + } else if (c > 255) { + c = 255; + } + i = colorPtr->colorQuant[0][c]; + *errPtr++ = c - i; + i = colorPtr->redValues[i]; + switch (bitsPerPixel) { + case NBBY: + *destBytePtr++ = i; + break; +#ifndef _WIN32 + /* + * This case is not valid for Windows because the + * image format is different from the pixel format in + * Win32. Eventually we need to fix the image code in + * Tk to use the Windows native image ordering. This + * would speed up the image code for all of the common + * sizes. + */ + + case NBBY * sizeof(pixel): + *destLongPtr++ = i; + break; +#endif + default: + XPutPixel(imagePtr, x - xStart, y - yStart, + (unsigned) i); + } + } + } else { + /* + * 1-bit monochrome window. This is similar to the multibit + * monochrome case above, except that the quantization is + * simpler (we only have black = 0 and white = 255), and we + * produce an XY-Bitmap. + */ + + word = 0; + mask = firstBit; + for (x = xStart; x < xEnd; ++x) { + /* + * If we have accumulated a whole word, store it in the + * image and start a new word. + */ + + if (mask == 0) { + *destLongPtr++ = word; + mask = firstBit; + word = 0; + } + + c = (x > 0) ? errPtr[-1] * 7: 0; + if (y > 0) { + if (x > 0) { + c += errPtr[-lineLength-1]; + } + c += errPtr[-lineLength] * 5; + if (x + 1 < masterPtr->width) { + c += errPtr[-lineLength+1] * 3; + } + } + c = ((c + 2056) >> 4) - 128; + + if (masterPtr->flags & COLOR_IMAGE) { + c += (unsigned)(srcPtr[0] * 11 + srcPtr[1] * 16 + + srcPtr[2] * 5 + 16) >> 5; + } else { + c += srcPtr[0]; + } + srcPtr += 4; + + if (c < 0) { + c = 0; + } else if (c > 255) { + c = 255; + } + if (c >= 128) { + word |= mask; + *errPtr++ = c - 255; + } else { + *errPtr++ = c; + } + mask = bigEndian? (mask >> 1): (mask << 1); + } + *destLongPtr = word; + } + srcLinePtr += masterPtr->width * 4; + errLinePtr += lineLength; + dstLinePtr += bytesPerLine; + } + + /* + * Update the pixmap for this instance with the block of pixels that + * we have just computed. + */ + + TkPutImage(colorPtr->pixelMap, colorPtr->numColors, + instancePtr->display, instancePtr->pixels, + instancePtr->gc, imagePtr, 0, 0, xStart, yStart, + (unsigned) width, (unsigned) nLines); + yStart = yEnd; + } + + ckfree(imagePtr->data); + imagePtr->data = NULL; +} + +/* + *---------------------------------------------------------------------- + * + * TkImgResetDither -- + * + * This function is called to eliminate the content of a photo instance's + * dither error buffer. It's called when the overall image is blanked. + * + * Results: + * None. + * + * Side effects: + * The instance's dither buffer gets cleared. + * + *---------------------------------------------------------------------- + */ + +void +TkImgResetDither( + PhotoInstance *instancePtr) +{ + if (instancePtr->error) { + memset(instancePtr->error, 0, + /*(size_t)*/ (instancePtr->masterPtr->width + * instancePtr->masterPtr->height * 3 * sizeof(schar))); + } +} + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/generic/tkImgPhoto.c b/generic/tkImgPhoto.c index 56217c4..26f1f26 100644 --- a/generic/tkImgPhoto.c +++ b/generic/tkImgPhoto.c @@ -18,209 +18,7 @@ * Australian National University. */ -#include "tkInt.h" -#include <ctype.h> - -#ifdef __WIN32__ -#include "tkWinInt.h" -#elif defined(__CYGWIN__) -#include "tkUnixInt.h" -#endif - -/* - * Declaration for internal Xlib function used here: - */ - -extern int _XInitImageFuncPtrs(XImage *image); - -/* - * A signed 8-bit integral type. If chars are unsigned and the compiler isn't - * an ANSI one, then we have to use short instead (which wastes space) to get - * signed behavior. - */ - -#if defined(__STDC__) || defined(_AIX) - typedef signed char schar; -#else -# ifndef __CHAR_UNSIGNED__ - typedef char schar; -# else - typedef short schar; -# endif -#endif - -/* - * An unsigned 32-bit integral type, used for pixel values. We use int rather - * than long here to accommodate those systems where longs are 64 bits. - */ - -typedef unsigned int pixel; - -/* - * The maximum number of pixels to transmit to the server in a single - * XPutImage call. - */ - -#define MAX_PIXELS 65536 - -/* - * The set of colors required to display a photo image in a window depends on: - * - the visual used by the window - * - the palette, which specifies how many levels of each primary color to - * use, and - * - the gamma value for the image. - * - * Pixel values allocated for specific colors are valid only for the colormap - * in which they were allocated. Sets of pixel values allocated for displaying - * photos are re-used in other windows if possible, that is, if the display, - * colormap, palette and gamma values match. A hash table is used to locate - * these sets of pixel values, using the following data structure as key: - */ - -typedef struct { - Display *display; /* Qualifies the colormap resource ID. */ - Colormap colormap; /* Colormap that the windows are using. */ - double gamma; /* Gamma exponent value for images. */ - Tk_Uid palette; /* Specifies how many shades of each primary - * we want to allocate. */ -} ColorTableId; - -/* - * For a particular (display, colormap, palette, gamma) combination, a data - * structure of the following type is used to store the allocated pixel values - * and other information: - */ - -typedef struct ColorTable { - ColorTableId id; /* Information used in selecting this color - * table. */ - int flags; /* See below. */ - int refCount; /* Number of instances using this map. */ - int liveRefCount; /* Number of instances which are actually in - * use, using this map. */ - int numColors; /* Number of colors allocated for this map. */ - - XVisualInfo visualInfo; /* Information about the visual for windows - * using this color table. */ - - pixel redValues[256]; /* Maps 8-bit values of red intensity to a - * pixel value or index in pixelMap. */ - pixel greenValues[256]; /* Ditto for green intensity. */ - pixel blueValues[256]; /* Ditto for blue intensity. */ - unsigned long *pixelMap; /* Actual pixel values allocated. */ - - unsigned char colorQuant[3][256]; - /* Maps 8-bit intensities to quantized - * intensities. The first index is 0 for red, - * 1 for green, 2 for blue. */ -} ColorTable; - -/* - * Bit definitions for the flags field of a ColorTable. - * BLACK_AND_WHITE: 1 means only black and white colors are - * available. - * COLOR_WINDOW: 1 means a full 3-D color cube has been - * allocated. - * DISPOSE_PENDING: 1 means a call to DisposeColorTable has been - * scheduled as an idle handler, but it hasn't - * been invoked yet. - * MAP_COLORS: 1 means pixel values should be mapped through - * pixelMap. - */ - -#ifdef COLOR_WINDOW -#undef COLOR_WINDOW -#endif - -#define BLACK_AND_WHITE 1 -#define COLOR_WINDOW 2 -#define DISPOSE_PENDING 4 -#define MAP_COLORS 8 - -/* - * Definition of the data associated with each photo image master. - */ - -typedef struct PhotoMaster { - Tk_ImageMaster tkMaster; /* Tk's token for image master. NULL means the - * image is being deleted. */ - Tcl_Interp *interp; /* Interpreter associated with the application - * using this image. */ - Tcl_Command imageCmd; /* Token for image command (used to delete it - * when the image goes away). NULL means the - * image command has already been deleted. */ - int flags; /* Sundry flags, defined below. */ - int width, height; /* Dimensions of image. */ - int userWidth, userHeight; /* User-declared image dimensions. */ - Tk_Uid palette; /* User-specified default palette for - * instances of this image. */ - double gamma; /* Display gamma value to correct for. */ - char *fileString; /* Name of file to read into image. */ - Tcl_Obj *dataString; /* Object to use as contents of image. */ - Tcl_Obj *format; /* User-specified format of data in image file - * or string value. */ - unsigned char *pix32; /* Local storage for 32-bit image. */ - int ditherX, ditherY; /* Location of first incorrectly dithered - * pixel in image. */ - TkRegion validRegion; /* Tk region indicating which parts of the - * image have valid image data. */ - struct PhotoInstance *instancePtr; - /* First in the list of instances associated - * with this master. */ -} PhotoMaster; - -/* - * Bit definitions for the flags field of a PhotoMaster. - * COLOR_IMAGE: 1 means that the image has different color - * components. - * IMAGE_CHANGED: 1 means that the instances of this image need - * to be redithered. - * COMPLEX_ALPHA: 1 means that the instances of this image have - * alpha values that aren't 0 or 255, and so need - * the copy-merge-replace renderer . - */ - -#define COLOR_IMAGE 1 -#define IMAGE_CHANGED 2 -#define COMPLEX_ALPHA 4 - -/* - * Flag to OR with the compositing rule to indicate that the source, despite - * having an alpha channel, has simple alpha. - */ - -#define SOURCE_IS_SIMPLE_ALPHA_PHOTO 0x10000000 - -/* - * The following data structure represents all of the instances of a photo - * image in windows on a given screen that are using the same colormap. - */ - -typedef struct PhotoInstance { - PhotoMaster *masterPtr; /* Pointer to master for image. */ - Display *display; /* Display for windows using this instance. */ - Colormap colormap; /* The image may only be used in windows with - * this particular colormap. */ - struct PhotoInstance *nextPtr; - /* Pointer to the next instance in the list of - * instances associated with this master. */ - int 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 - * specified for the master. */ - ColorTable *colorTablePtr; /* Pointer to information about colors - * allocated for image display in windows like - * this one. */ - Pixmap pixels; /* X pixmap containing dithered image. */ - int width, height; /* Dimensions of the pixmap. */ - schar *error; /* Error image, used in dithering. */ - XImage *imagePtr; /* Image structure for converted pixels. */ - XVisualInfo visualInfo; /* Information about the visual that these - * windows are using. */ - GC gc; /* Graphics context for writing images to the - * pixmap. */ -} PhotoInstance; +#include "tkImgPhoto.h" /* * The following data structure is used to return information from @@ -301,16 +99,10 @@ static const char *const optionNames[] = { * Functions used in the type record for photo images. */ -static int ImgPhotoCreate(Tcl_Interp *interp, char *name, - int objc, Tcl_Obj *CONST objv[], - Tk_ImageType *typePtr, Tk_ImageMaster master, +static int ImgPhotoCreate(Tcl_Interp *interp, const char *name, + int objc, Tcl_Obj *const objv[], + const Tk_ImageType *typePtr, Tk_ImageMaster master, ClientData *clientDataPtr); -static ClientData ImgPhotoGet(Tk_Window tkwin, ClientData clientData); -static void ImgPhotoDisplay(ClientData clientData, - Display *display, Drawable drawable, - int imageX, int imageY, int width, int height, - int drawableX, int drawableY); -static void ImgPhotoFree(ClientData clientData, Display *display); static void ImgPhotoDelete(ClientData clientData); static int ImgPhotoPostscript(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, @@ -324,12 +116,13 @@ static int ImgPhotoPostscript(ClientData clientData, Tk_ImageType tkPhotoImageType = { "photo", /* name */ ImgPhotoCreate, /* createProc */ - ImgPhotoGet, /* getProc */ - ImgPhotoDisplay, /* displayProc */ - ImgPhotoFree, /* freeProc */ + TkImgPhotoGet, /* getProc */ + TkImgPhotoDisplay, /* displayProc */ + TkImgPhotoFree, /* freeProc */ ImgPhotoDelete, /* deleteProc */ ImgPhotoPostscript, /* postscriptProc */ - NULL /* nextPtr */ + NULL, /* nextPtr */ + NULL }; typedef struct ThreadSpecificData { @@ -340,7 +133,7 @@ typedef struct ThreadSpecificData { /* Pointer to the first in the list of known * photo image formats.*/ int initialized; /* Set to 1 if we've initialized the - * strucuture. */ + * structure. */ } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; @@ -357,45 +150,27 @@ static Tcl_ThreadDataKey dataKey; * Information used for parsing configuration specifications: */ -static Tk_ConfigSpec configSpecs[] = { +static const Tk_ConfigSpec configSpecs[] = { {TK_CONFIG_STRING, "-file", NULL, NULL, - NULL, Tk_Offset(PhotoMaster, fileString), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(PhotoMaster, fileString), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_DOUBLE, "-gamma", NULL, NULL, - DEF_PHOTO_GAMMA, Tk_Offset(PhotoMaster, gamma), 0}, + DEF_PHOTO_GAMMA, Tk_Offset(PhotoMaster, gamma), 0, NULL}, {TK_CONFIG_INT, "-height", NULL, NULL, - DEF_PHOTO_HEIGHT, Tk_Offset(PhotoMaster, userHeight), 0}, + DEF_PHOTO_HEIGHT, Tk_Offset(PhotoMaster, userHeight), 0, NULL}, {TK_CONFIG_UID, "-palette", NULL, NULL, - DEF_PHOTO_PALETTE, Tk_Offset(PhotoMaster, palette), 0}, + DEF_PHOTO_PALETTE, Tk_Offset(PhotoMaster, palette), 0, NULL}, {TK_CONFIG_INT, "-width", NULL, NULL, - DEF_PHOTO_WIDTH, Tk_Offset(PhotoMaster, userWidth), 0}, - {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} + DEF_PHOTO_WIDTH, Tk_Offset(PhotoMaster, userWidth), 0, NULL}, + {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL} }; /* - * Hash table used to hash from (display, colormap, palette, gamma) to - * ColorTable address. - */ - -static Tcl_HashTable imgPhotoColorHash; -static int imgPhotoColorHashInitialized; -#define N_COLOR_HASH (sizeof(ColorTableId) / sizeof(int)) - -/* - * Implementation of the Porter-Duff Source-Over compositing rule. - */ - -#define PD_SRC_OVER(srcColor,srcAlpha,dstColor,dstAlpha) \ - (srcColor*srcAlpha/255) + dstAlpha*(255-srcAlpha)/255*dstColor/255 -#define PD_SRC_OVER_ALPHA(srcAlpha,dstAlpha) \ - (srcAlpha + (255-srcAlpha)*dstAlpha/255) - -/* * Forward declarations */ static void PhotoFormatThreadExitProc(ClientData clientData); static int ImgPhotoCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *CONST objv[]); + int objc, Tcl_Obj *const objv[]); static int ParseSubcommandOptions( struct SubcommandOptions *optPtr, Tcl_Interp *interp, int allowedOptions, @@ -404,47 +179,24 @@ static void ImgPhotoCmdDeletedProc(ClientData clientData); static int ImgPhotoConfigureMaster(Tcl_Interp *interp, PhotoMaster *masterPtr, int objc, Tcl_Obj *const objv[], int flags); -static void ImgPhotoConfigureInstance(PhotoInstance *instancePtr); static int ToggleComplexAlphaIfNeeded(PhotoMaster *mPtr); -static void ImgPhotoBlendComplexAlpha(XImage *bgImg, - PhotoInstance *iPtr, int xOffset, int yOffset, - int width, int height); static int ImgPhotoSetSize(PhotoMaster *masterPtr, int width, int height); -static void ImgPhotoInstanceSetSize(PhotoInstance *instancePtr); static int ImgStringWrite(Tcl_Interp *interp, Tcl_Obj *formatString, Tk_PhotoImageBlock *blockPtr); static char * ImgGetPhoto(PhotoMaster *masterPtr, Tk_PhotoImageBlock *blockPtr, struct SubcommandOptions *optPtr); -static int IsValidPalette(PhotoInstance *instancePtr, - const char *palette); -static int CountBits(pixel mask); -static void GetColorTable(PhotoInstance *instancePtr); -static void FreeColorTable(ColorTable *colorPtr, int force); -static void AllocateColors(ColorTable *colorPtr); -static void DisposeColorTable(ClientData clientData); -static void DisposeInstance(ClientData clientData); -static int ReclaimColors(ColorTableId *id, int numColors); static int MatchFileFormat(Tcl_Interp *interp, Tcl_Channel chan, - char *fileName, Tcl_Obj *formatString, + const char *fileName, Tcl_Obj *formatString, Tk_PhotoImageFormat **imageFormatPtr, int *widthPtr, int *heightPtr, int *oldformat); static int MatchStringFormat(Tcl_Interp *interp, Tcl_Obj *data, Tcl_Obj *formatString, Tk_PhotoImageFormat **imageFormatPtr, int *widthPtr, int *heightPtr, int *oldformat); -static Tcl_ObjCmdProc * PhotoOptionFind(Tcl_Interp *interp, Tcl_Obj *obj); -static void DitherInstance(PhotoInstance *instancePtr, int x, - int y, int width, int height); -static void PhotoOptionCleanupProc(ClientData clientData, - Tcl_Interp *interp); - -#undef MIN -#define MIN(a, b) ((a) < (b)? (a): (b)) -#undef MAX -#define MAX(a, b) ((a) > (b)? (a): (b)) +static const char * GetExtension(const char *path); /* *---------------------------------------------------------------------- @@ -467,19 +219,19 @@ PhotoFormatThreadExitProc( ClientData clientData) /* not used */ { Tk_PhotoImageFormat *freePtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); while (tsdPtr->oldFormatList != NULL) { freePtr = tsdPtr->oldFormatList; tsdPtr->oldFormatList = tsdPtr->oldFormatList->nextPtr; - ckfree((char *) freePtr); + ckfree(freePtr); } while (tsdPtr->formatList != NULL) { freePtr = tsdPtr->formatList; tsdPtr->formatList = tsdPtr->formatList->nextPtr; - ckfree((char *) freePtr->name); - ckfree((char *) freePtr); + ckfree((char *)freePtr->name); + ckfree(freePtr); } } @@ -504,20 +256,20 @@ PhotoFormatThreadExitProc( void Tk_CreateOldPhotoImageFormat( - Tk_PhotoImageFormat *formatPtr) + const Tk_PhotoImageFormat *formatPtr) /* Structure describing the format. All of the * fields except "nextPtr" must be filled in * by caller. */ { Tk_PhotoImageFormat *copyPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (!tsdPtr->initialized) { tsdPtr->initialized = 1; Tcl_CreateThreadExitHandler(PhotoFormatThreadExitProc, NULL); } - copyPtr = (Tk_PhotoImageFormat *) ckalloc(sizeof(Tk_PhotoImageFormat)); + copyPtr = ckalloc(sizeof(Tk_PhotoImageFormat)); *copyPtr = *formatPtr; copyPtr->nextPtr = tsdPtr->oldFormatList; tsdPtr->oldFormatList = copyPtr; @@ -525,20 +277,20 @@ Tk_CreateOldPhotoImageFormat( void Tk_CreatePhotoImageFormat( - Tk_PhotoImageFormat *formatPtr) + const Tk_PhotoImageFormat *formatPtr) /* Structure describing the format. All of the * fields except "nextPtr" must be filled in * by caller. */ { Tk_PhotoImageFormat *copyPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (!tsdPtr->initialized) { tsdPtr->initialized = 1; Tcl_CreateThreadExitHandler(PhotoFormatThreadExitProc, NULL); } - copyPtr = (Tk_PhotoImageFormat *) ckalloc(sizeof(Tk_PhotoImageFormat)); + copyPtr = ckalloc(sizeof(Tk_PhotoImageFormat)); *copyPtr = *formatPtr; if (isupper((unsigned char) *formatPtr->name)) { copyPtr->nextPtr = tsdPtr->oldFormatList; @@ -574,11 +326,11 @@ static int ImgPhotoCreate( Tcl_Interp *interp, /* Interpreter for application containing * image. */ - char *name, /* Name to use for image. */ + const char *name, /* Name to use for image. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[], /* Argument objects for options (doesn't + Tcl_Obj *const objv[], /* Argument objects for options (doesn't * include image name or type). */ - Tk_ImageType *typePtr, /* Pointer to our type record (not used). */ + const Tk_ImageType *typePtr,/* Pointer to our type record (not used). */ Tk_ImageMaster master, /* Token for image, to be used by us in later * callbacks. */ ClientData *clientDataPtr) /* Store manager's token for image here; it @@ -590,12 +342,12 @@ ImgPhotoCreate( * Allocate and initialize the photo image master record. */ - masterPtr = (PhotoMaster *) ckalloc(sizeof(PhotoMaster)); + masterPtr = ckalloc(sizeof(PhotoMaster)); memset(masterPtr, 0, sizeof(PhotoMaster)); masterPtr->tkMaster = master; masterPtr->interp = interp; masterPtr->imageCmd = Tcl_CreateObjCommand(interp, name, ImgPhotoCmd, - (ClientData) masterPtr, ImgPhotoCmdDeletedProc); + masterPtr, ImgPhotoCmdDeletedProc); masterPtr->palette = NULL; masterPtr->pix32 = NULL; masterPtr->instancePtr = NULL; @@ -606,11 +358,11 @@ ImgPhotoCreate( */ if (ImgPhotoConfigureMaster(interp, masterPtr, objc, objv, 0) != TCL_OK) { - ImgPhotoDelete((ClientData) masterPtr); + ImgPhotoDelete(masterPtr); return TCL_ERROR; } - *clientDataPtr = (ClientData) masterPtr; + *clientDataPtr = masterPtr; return TCL_OK; } @@ -637,9 +389,9 @@ ImgPhotoCmd( ClientData clientData, /* Information about photo master. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { - static const char *photoOptions[] = { + static const char *const photoOptions[] = { "blank", "cget", "configure", "copy", "data", "get", "put", "read", "redither", "transparency", "write", NULL }; @@ -649,7 +401,7 @@ ImgPhotoCmd( PHOTO_WRITE }; - PhotoMaster *masterPtr = (PhotoMaster *) clientData; + PhotoMaster *masterPtr = clientData; int result, index, x, y, width, height, dataWidth, dataHeight, listObjc; struct SubcommandOptions options; Tcl_Obj **listObjv, **srcObjv; @@ -657,25 +409,21 @@ 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 = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?"); + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(interp, objv[1], photoOptions, "option", 0, &index) != TCL_OK) { - Tcl_ObjCmdProc *proc; - proc = PhotoOptionFind(interp, objv[1]); - if (proc == NULL) { - return TCL_ERROR; - } - return proc(clientData, interp, objc, objv); + return TCL_ERROR; } switch ((enum PhotoOptions) index) { @@ -693,18 +441,19 @@ ImgPhotoCmd( } case PHOTO_CGET: { - char *arg; + const char *arg; if (objc != 3) { 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); } @@ -748,22 +497,31 @@ ImgPhotoCmd( return TCL_OK; } else if (objc == 3) { - 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) { - Tcl_ListObjAppendElement(interp, Tcl_GetObjResult(interp), + /* + * TODO: Modifying result is bad! + */ + + Tcl_ListObjAppendElement(NULL, Tcl_GetObjResult(interp), masterPtr->dataString); } else { Tcl_AppendResult(interp, " {}", NULL); } return TCL_OK; } else if (length > 1 && - !strncmp(arg, "-format", (unsigned) length)) { + !strncmp(arg, "-format", length)) { Tcl_AppendResult(interp, "-format {} {} {}", NULL); if (masterPtr->format) { - Tcl_ListObjAppendElement(interp, Tcl_GetObjResult(interp), + /* + * TODO: Modifying result is bad! + */ + + Tcl_ListObjAppendElement(NULL, Tcl_GetObjResult(interp), masterPtr->format); } else { Tcl_AppendResult(interp, " {}", NULL); @@ -773,9 +531,10 @@ ImgPhotoCmd( return Tk_ConfigureInfo(interp, Tk_MainWindow(interp), configSpecs, (char *) masterPtr, arg, 0); } + } else { + return ImgPhotoConfigureMaster(interp, masterPtr, objc-2, objv+2, + TK_CONFIG_ARGV_ONLY); } - return ImgPhotoConfigureMaster(interp, masterPtr, objc-2, objv+2, - TK_CONFIG_ARGV_ONLY); case PHOTO_COPY: /* @@ -806,17 +565,24 @@ ImgPhotoCmd( srcHandle = Tk_FindPhoto(interp, Tcl_GetString(options.name)); if (srcHandle == NULL) { - Tcl_AppendResult(interp, "image \"", - Tcl_GetString(options.name), "\" doesn't", - " exist or is not a photo image", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "image \"%s\" doesn't exist or is not a photo image", + Tcl_GetString(options.name))); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO", + Tcl_GetString(options.name), NULL); return TCL_ERROR; } Tk_PhotoGetImage(srcHandle, &block); if ((options.fromX2 > block.width) || (options.fromY2 > block.height) || (options.fromX2 > block.width) || (options.fromY2 > block.height)) { - Tcl_AppendResult(interp, "coordinates for -from option extend ", - "outside source image", NULL); + if (options.background) { + Tk_FreeColor(options.background); + } + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "coordinates for -from option extend outside source image", + -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_FROM", NULL); return TCL_ERROR; } @@ -862,19 +628,6 @@ ImgPhotoCmd( } /* - * Set the destination image size if the -shrink option was specified. - */ - - if (options.options & OPT_SHRINK) { - if (ImgPhotoSetSize(masterPtr, options.toX2, - options.toY2) != TCL_OK) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, TK_PHOTO_ALLOC_FAILURE_MESSAGE, NULL); - return TCL_ERROR; - } - } - - /* * Copy the image data over using Tk_PhotoPutZoomedBlock. */ @@ -882,12 +635,38 @@ ImgPhotoCmd( + options.fromY * block.pitch; block.width = options.fromX2 - options.fromX; block.height = options.fromY2 - options.fromY; - return Tk_PhotoPutZoomedBlock(interp, (Tk_PhotoHandle) masterPtr, + result = Tk_PhotoPutZoomedBlock(interp, (Tk_PhotoHandle) masterPtr, &block, options.toX, options.toY, options.toX2 - options.toX, options.toY2 - options.toY, options.zoomX, options.zoomY, options.subsampleX, options.subsampleY, options.compositingRule); + /* + * Set the destination image size if the -shrink option was specified. + * This has to be done _after_ copying the data. Otherwise, if source + * and destination are the same image, block.pixelPtr would point to + * an invalid memory block (bug [5239fd749b]). + */ + + if (options.options & OPT_SHRINK) { + if (ImgPhotoSetSize(masterPtr, options.toX2, + options.toY2) != TCL_OK) { + if (options.background) { + Tk_FreeColor(options.background); + } + Tcl_SetObjResult(interp, Tcl_NewStringObj( + TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1)); + Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL); + return TCL_ERROR; + } + } + Tk_ImageChanged(masterPtr->tkMaster, 0, 0, 0, 0, + masterPtr->width, masterPtr->height); + if (options.background) { + Tk_FreeColor(options.background); + } + return result; + case PHOTO_DATA: { char *data; @@ -909,15 +688,16 @@ ImgPhotoCmd( return TCL_ERROR; } if ((options.name != NULL) || (index < objc)) { - Tcl_WrongNumArgs(interp, 2, objv, "?options?"); + Tcl_WrongNumArgs(interp, 2, objv, "?-option value ...?"); return TCL_ERROR; } if ((options.fromX > masterPtr->width) || (options.fromY > masterPtr->height) || (options.fromX2 > masterPtr->width) || (options.fromY2 > masterPtr->height)) { - Tcl_AppendResult(interp, "coordinates for -from option extend ", - "outside image", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "coordinates for -from option extend outside image", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_FROM", NULL); return TCL_ERROR; } @@ -925,7 +705,7 @@ ImgPhotoCmd( * Fill in default values for unspecified parameters. */ - if (((options.options & OPT_FROM) == 0) || (options.fromX2 < 0)) { + if (!(options.options & OPT_FROM) || (options.fromX2 < 0)) { options.fromX2 = masterPtr->width; options.fromY2 = masterPtr->height; } @@ -963,9 +743,12 @@ ImgPhotoCmd( } } if (stringWriteProc == NULL) { - Tcl_AppendResult(interp, "image string format \"", - Tcl_GetString(options.format), "\" is ", - (matched ? "not supported" : "unknown"), NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "image string format \"%s\" is %s", + Tcl_GetString(options.format), + (matched ? "not supported" : "unknown"))); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO_FORMAT", + Tcl_GetString(options.format), NULL); return TCL_ERROR; } } else { @@ -980,23 +763,25 @@ ImgPhotoCmd( if (oldformat) { Tcl_DString buffer; + typedef int (*OldStringWriteProc)(Tcl_Interp *interp, + Tcl_DString *dataPtr, const char *formatString, + Tk_PhotoImageBlock *blockPtr); Tcl_DStringInit(&buffer); - result = ((int (*) (Tcl_Interp *interp, - Tcl_DString *dataPtr, char *formatString, - Tk_PhotoImageBlock *blockPtr)) stringWriteProc) - (interp, &buffer, Tcl_GetString(options.format), &block); + result = ((OldStringWriteProc) stringWriteProc)(interp, &buffer, + Tcl_GetString(options.format), &block); if (result == TCL_OK) { Tcl_DStringResult(interp, &buffer); } else { Tcl_DStringFree(&buffer); } } else { - - result = ((int (*) (Tcl_Interp *interp, + typedef int (*NewStringWriteProc)(Tcl_Interp *interp, Tcl_Obj *formatString, Tk_PhotoImageBlock *blockPtr, - void *dummy)) stringWriteProc) - (interp, options.format, &block, NULL); + void *dummy); + + result = ((NewStringWriteProc) stringWriteProc)(interp, + options.format, &block, NULL); } if (options.background) { Tk_FreeColor(options.background); @@ -1012,7 +797,7 @@ ImgPhotoCmd( * photo get command - first parse and check parameters. */ - char string[TCL_INTEGER_SPACE * 3]; + Tcl_Obj *channels[3]; if (objc != 4) { Tcl_WrongNumArgs(interp, 2, objv, "x y"); @@ -1024,8 +809,11 @@ ImgPhotoCmd( } if ((x < 0) || (x >= masterPtr->width) || (y < 0) || (y >= masterPtr->height)) { - Tcl_AppendResult(interp, Tcl_GetString(objv[0]), " get: ", - "coordinates out of range", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "%s get: coordinates out of range", + Tcl_GetString(objv[0]))); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "COORDINATES", + NULL); return TCL_ERROR; } @@ -1034,9 +822,10 @@ ImgPhotoCmd( */ pixelPtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4; - sprintf(string, "%d %d %d", pixelPtr[0], pixelPtr[1], - pixelPtr[2]); - Tcl_AppendResult(interp, string, NULL); + channels[0] = Tcl_NewIntObj(pixelPtr[0]); + channels[1] = Tcl_NewIntObj(pixelPtr[1]); + channels[2] = Tcl_NewIntObj(pixelPtr[2]); + Tcl_SetObjResult(interp, Tcl_NewListObj(3, channels)); return TCL_OK; } @@ -1053,7 +842,7 @@ ImgPhotoCmd( return TCL_ERROR; } if ((options.name == NULL) || (index < objc)) { - Tcl_WrongNumArgs(interp, 2, objv, "data ?options?"); + Tcl_WrongNumArgs(interp, 2, objv, "data ?-option value ...?"); return TCL_ERROR; } @@ -1062,7 +851,7 @@ ImgPhotoCmd( &imageHeight, &oldformat) == TCL_OK) { Tcl_Obj *format, *data; - if (((options.options & OPT_TO) == 0) || (options.toX2 < 0)) { + if (!(options.options & OPT_TO) || (options.toX2 < 0)) { options.toX2 = options.toX + imageWidth; options.toY2 = options.toY + imageHeight; } @@ -1080,10 +869,9 @@ ImgPhotoCmd( } data = (Tcl_Obj *) Tcl_GetString(data); } - if ((*imageFormat->stringReadProc)(interp, data, - format, (Tk_PhotoHandle) masterPtr, - options.toX, options.toY, imageWidth, imageHeight, - 0, 0) != TCL_OK) { + if (imageFormat->stringReadProc(interp, data, format, + (Tk_PhotoHandle) masterPtr, options.toX, options.toY, + imageWidth, imageHeight, 0, 0) != TCL_OK) { return TCL_ERROR; } masterPtr->flags |= IMAGE_CHANGED; @@ -1116,17 +904,32 @@ ImgPhotoCmd( break; } dataWidth = listObjc; - pixelPtr = (unsigned char *) - ckalloc((unsigned) dataWidth * dataHeight * 3); + /* + * Memory allocation overflow protection. + * May not be able to trigger/ demo / test this. + */ + + if (dataWidth > (int)((UINT_MAX/3) / dataHeight)) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "photo image dimensions exceed Tcl memory limits", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", + "OVERFLOW", NULL); + break; + } + + pixelPtr = ckalloc(dataWidth * dataHeight * 3); block.pixelPtr = pixelPtr; } else if (listObjc != dataWidth) { - Tcl_AppendResult(interp, "all elements of color list must", - " have the same number of elements", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "all elements of color list must have the same" + " number of elements", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", + "NON_RECTANGULAR", NULL); break; } for (x = 0; x < dataWidth; ++x) { - char *colorString = Tcl_GetString(listObjv[x]); + const char *colorString = Tcl_GetString(listObjv[x]); XColor color; int tmpr, tmpg, tmpb; @@ -1164,8 +967,9 @@ ImgPhotoCmd( if (!TkParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), colorString, &color)) { - Tcl_AppendResult(interp, "can't parse color \"", - colorString, "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't parse color \"%s\"", colorString)); + Tcl_SetErrorCode(interp, "TK", "VALUE", "COLOR", NULL); break; } *pixelPtr++ = color.red >> 8; @@ -1178,7 +982,7 @@ ImgPhotoCmd( } if (y < dataHeight || dataHeight == 0 || dataWidth == 0) { if (block.pixelPtr != NULL) { - ckfree((char *) block.pixelPtr); + ckfree(block.pixelPtr); } if (y < dataHeight) { return TCL_ERROR; @@ -1203,11 +1007,11 @@ ImgPhotoCmd( block.offset[1] = 1; block.offset[2] = 2; block.offset[3] = 0; - result = Tk_PhotoPutBlock(interp, (ClientData)masterPtr, &block, + result = Tk_PhotoPutBlock(interp, masterPtr, &block, options.toX, options.toY, options.toX2 - options.toX, options.toY2 - options.toY, TK_PHOTO_COMPOSITE_SET); - ckfree((char *) block.pixelPtr); + ckfree(block.pixelPtr); return result; case PHOTO_READ: { @@ -1227,7 +1031,7 @@ ImgPhotoCmd( return TCL_ERROR; } if ((options.name == NULL) || (index < objc)) { - Tcl_WrongNumArgs(interp, 2, objv, "fileName ?options?"); + Tcl_WrongNumArgs(interp, 2, objv, "fileName ?-option value ...?"); return TCL_ERROR; } @@ -1236,8 +1040,9 @@ ImgPhotoCmd( */ if (Tcl_IsSafe(interp)) { - Tcl_AppendResult(interp, "can't get image from a file in a", - " safe interpreter", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "can't get image from a file in a safe interpreter", -1)); + Tcl_SetErrorCode(interp, "TK", "SAFE", "PHOTO_FILE", NULL); return TCL_ERROR; } @@ -1275,12 +1080,14 @@ ImgPhotoCmd( if ((options.fromX > imageWidth) || (options.fromY > imageHeight) || (options.fromX2 > imageWidth) || (options.fromY2 > imageHeight)) { - Tcl_AppendResult(interp, "coordinates for -from option extend ", - "outside source image", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "coordinates for -from option extend outside source image", + -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_FROM", NULL); Tcl_Close(NULL, chan); return TCL_ERROR; } - if (((options.options & OPT_FROM) == 0) || (options.fromX2 < 0)) { + if (!(options.options & OPT_FROM) || (options.fromX2 < 0)) { width = imageWidth - options.fromX; height = imageHeight - options.fromY; } else { @@ -1296,7 +1103,9 @@ ImgPhotoCmd( if (ImgPhotoSetSize(masterPtr, options.toX + width, options.toY + height) != TCL_OK) { Tcl_ResetResult(interp); - Tcl_AppendResult(interp, TK_PHOTO_ALLOC_FAILURE_MESSAGE, NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1)); + Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL); return TCL_ERROR; } } @@ -1310,7 +1119,7 @@ ImgPhotoCmd( if (oldformat && format) { format = (Tcl_Obj *) Tcl_GetString(format); } - result = (*imageFormat->fileReadProc)(interp, chan, + result = imageFormat->fileReadProc(interp, chan, Tcl_GetString(options.name), format, (Tk_PhotoHandle) masterPtr, options.toX, options.toY, width, height, options.fromX, options.fromY); @@ -1356,7 +1165,7 @@ ImgPhotoCmd( return TCL_OK; case PHOTO_TRANS: { - static const char *photoTransOptions[] = { + static const char *const photoTransOptions[] = { "get", "set", NULL }; enum transOptions { @@ -1364,7 +1173,7 @@ ImgPhotoCmd( }; if (objc < 3) { - Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?"); + Tcl_WrongNumArgs(interp, 2, objv, "option ?arg ...?"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(interp, objv[2], photoTransOptions, "option", @@ -1386,9 +1195,12 @@ ImgPhotoCmd( return TCL_ERROR; } if ((x < 0) || (x >= masterPtr->width) - || (y < 0) || (y >= masterPtr->height)) { - Tcl_AppendResult(interp, Tcl_GetString(objv[0]), - " transparency get: coordinates out of range", NULL); + || (y < 0) || (y >= masterPtr->height)) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "%s transparency get: coordinates out of range", + Tcl_GetString(objv[0]))); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "COORDINATES", + NULL); return TCL_ERROR; } @@ -1403,8 +1215,8 @@ ImgPhotoCmd( TkClipBox(testRegion, &testBox); TkDestroyRegion(testRegion); - Tcl_SetBooleanObj(Tcl_GetObjResult(interp), - (testBox.width==0 && testBox.height==0)); + Tcl_SetObjResult(interp, Tcl_NewBooleanObj( + testBox.width==0 && testBox.height==0)); return TCL_OK; } @@ -1424,8 +1236,11 @@ ImgPhotoCmd( } if ((x < 0) || (x >= masterPtr->width) || (y < 0) || (y >= masterPtr->height)) { - Tcl_AppendResult(interp, Tcl_GetString(objv[0]), - " transparency set: coordinates out of range", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "%s transparency set: coordinates out of range", + Tcl_GetString(objv[0]))); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "COORDINATES", + NULL); return TCL_ERROR; } @@ -1479,15 +1294,18 @@ ImgPhotoCmd( case PHOTO_WRITE: { char *data; + const char *fmtString; Tcl_Obj *format; + int usedExt; /* * Prevent file system access in safe interpreters. */ if (Tcl_IsSafe(interp)) { - Tcl_AppendResult(interp, "can't write image to a file in a", - " safe interpreter", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "can't write image to a file in a safe interpreter", -1)); + Tcl_SetErrorCode(interp, "TK", "SAFE", "PHOTO_FILE", NULL); return TCL_ERROR; } @@ -1505,26 +1323,36 @@ ImgPhotoCmd( return TCL_ERROR; } if ((options.name == NULL) || (index < objc)) { - Tcl_WrongNumArgs(interp, 2, objv, "fileName ?options?"); + Tcl_WrongNumArgs(interp, 2, objv, "fileName ?-option value ...?"); return TCL_ERROR; } if ((options.fromX > masterPtr->width) || (options.fromY > masterPtr->height) || (options.fromX2 > masterPtr->width) || (options.fromY2 > masterPtr->height)) { - Tcl_AppendResult(interp, "coordinates for -from option extend ", - "outside image", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "coordinates for -from option extend outside image", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_FROM", NULL); return TCL_ERROR; } /* - * Fill in default values for unspecified parameters. + * Fill in default values for unspecified parameters. Note that a + * missing -format flag results in us having a guess from the file + * extension. [Bug 2983824] */ if (!(options.options & OPT_FROM) || (options.fromX2 < 0)) { options.fromX2 = masterPtr->width; options.fromY2 = masterPtr->height; } + if (options.format == NULL) { + fmtString = GetExtension(Tcl_GetString(options.name)); + usedExt = (fmtString != NULL); + } else { + fmtString = Tcl_GetString(options.format); + usedExt = 0; + } /* * Search for an appropriate image file format handler, and give an @@ -1532,11 +1360,12 @@ ImgPhotoCmd( */ matched = 0; + redoFormatLookup: for (imageFormat = tsdPtr->formatList; imageFormat != NULL; imageFormat = imageFormat->nextPtr) { - if ((options.format == NULL) - || (strncasecmp(Tcl_GetString(options.format), - imageFormat->name, strlen(imageFormat->name)) == 0)) { + if ((fmtString == NULL) + || (strncasecmp(fmtString, imageFormat->name, + strlen(imageFormat->name)) == 0)) { matched = 1; if (imageFormat->fileWriteProc != NULL) { break; @@ -1547,9 +1376,9 @@ ImgPhotoCmd( oldformat = 1; for (imageFormat = tsdPtr->oldFormatList; imageFormat != NULL; imageFormat = imageFormat->nextPtr) { - if ((options.format == NULL) - || (strncasecmp(Tcl_GetString(options.format), - imageFormat->name, strlen(imageFormat->name)) == 0)) { + if ((fmtString == NULL) + || (strncasecmp(fmtString, imageFormat->name, + strlen(imageFormat->name)) == 0)) { matched = 1; if (imageFormat->fileWriteProc != NULL) { break; @@ -1557,19 +1386,32 @@ ImgPhotoCmd( } } } + if (usedExt && !matched) { + /* + * If we didn't find one and we're using file extensions as the + * basis for the guessing, go back and look again without + * prejudice. Supports old broken code. + */ + + usedExt = 0; + fmtString = NULL; + goto redoFormatLookup; + } if (imageFormat == NULL) { - if (options.format == NULL) { - Tcl_AppendResult(interp, "no available image file format ", - "has file writing capability", NULL); + if (fmtString == NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "no available image file format has file writing" + " capability", -1)); } else if (!matched) { - Tcl_AppendResult(interp, "image file format \"", - Tcl_GetString(options.format), - "\" is unknown", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "image file format \"%s\" is unknown", fmtString)); } else { - Tcl_AppendResult(interp, "image file format \"", - Tcl_GetString(options.format), - "\" has no file writing capability", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "image file format \"%s\" has no file writing capability", + fmtString)); } + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO_FORMAT", + fmtString, NULL); return TCL_ERROR; } @@ -1582,7 +1424,7 @@ ImgPhotoCmd( if (oldformat && format) { format = (Tcl_Obj *) Tcl_GetString(options.format); } - result = (*imageFormat->fileWriteProc)(interp, + result = imageFormat->fileWriteProc(interp, Tcl_GetString(options.name), format, &block); if (options.background) { Tk_FreeColor(options.background); @@ -1601,6 +1443,36 @@ ImgPhotoCmd( /* *---------------------------------------------------------------------- * + * GetExtension -- + * + * Return the extension part of a path, or NULL if there is no extension. + * The returned string will be a substring of the argument string, so + * should not be ckfree()d directly. No side effects. + * + *---------------------------------------------------------------------- + */ + +static const char * +GetExtension( + const char *path) +{ + char c; + const char *extension = NULL; + + for (; (c=*path++) != '\0' ;) { + if (c == '.') { + extension = path; + } + } + if (extension != NULL && extension[0] == '\0') { + extension = NULL; + } + return extension; +} + +/* + *---------------------------------------------------------------------- + * * ParseSubcommandOptions -- * * This function is invoked to process one of the options which may be @@ -1630,10 +1502,17 @@ ParseSubcommandOptions( int objc, /* Number of arguments in objv[]. */ Tcl_Obj *const objv[]) /* Arguments to be parsed. */ { - int index, c, bit, currentBit, length; + static const char *const compositingRules[] = { + "overlay", "set", /* Note that these must match the + * TK_PHOTO_COMPOSITE_* constants. */ + NULL + }; + size_t length; + int index, c, bit, currentBit; int values[4], numValues, maxValues, argIndex; - char *option; + const char *option, *expandedOption, *needed; const char *const *listPtr; + Tcl_Obj *msgObj; for (index = *optIndexPtr; index < objc; *optIndexPtr = ++index) { /* @@ -1641,7 +1520,8 @@ ParseSubcommandOptions( * optPtr->name. */ - 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]; @@ -1659,10 +1539,10 @@ 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) { - bit = 0; /* An ambiguous option. */ - break; + goto unknownOrAmbiguousOption; } bit = currentBit; } @@ -1674,28 +1554,12 @@ ParseSubcommandOptions( * in the interpreter and return. */ - if ((allowedOptions & bit) == 0) { - if (optPtr->name == NULL) { - optPtr->name = objv[index]; - continue; + if (!(allowedOptions & bit)) { + if (optPtr->name != NULL) { + goto unknownOrAmbiguousOption; } - Tcl_AppendResult(interp, "unrecognized option \"", - Tcl_GetString(objv[index]), - "\": must be ", NULL); - bit = 1; - for (listPtr = optionNames; *listPtr != NULL; ++listPtr) { - if ((allowedOptions & bit) != 0) { - if ((allowedOptions & (bit - 1)) != 0) { - Tcl_AppendResult(interp, ", ", NULL); - if ((allowedOptions & ~((bit << 1) - 1)) == 0) { - Tcl_AppendResult(interp, "or ", NULL); - } - } - Tcl_AppendResult(interp, *listPtr, NULL); - } - bit <<= 1; - } - return TCL_ERROR; + optPtr->name = objv[index]; + continue; } /* @@ -1708,16 +1572,13 @@ ParseSubcommandOptions( * The -background option takes a single XColor value. */ - if (index + 1 < objc) { - *optIndexPtr = ++index; - optPtr->background = Tk_GetColor(interp, Tk_MainWindow(interp), - Tk_GetUid(Tcl_GetString(objv[index]))); - if (!optPtr->background) { - return TCL_ERROR; - } - } else { - Tcl_AppendResult(interp, "the \"-background\" option ", - "requires a value", NULL); + if (index + 1 >= objc) { + goto oneValueRequired; + } + *optIndexPtr = ++index; + optPtr->background = Tk_GetColor(interp, Tk_MainWindow(interp), + Tk_GetUid(Tcl_GetString(objv[index]))); + if (!optPtr->background) { return TCL_ERROR; } } else if (bit == OPT_FORMAT) { @@ -1726,45 +1587,31 @@ ParseSubcommandOptions( * parsing this is outside the scope of this function. */ - if (index + 1 < objc) { - *optIndexPtr = ++index; - optPtr->format = objv[index]; - } else { - Tcl_AppendResult(interp, "the \"-format\" option ", - "requires a value", NULL); - return TCL_ERROR; + if (index + 1 >= objc) { + goto oneValueRequired; } + *optIndexPtr = ++index; + optPtr->format = objv[index]; } else if (bit == OPT_COMPOSITE) { /* * The -compositingrule option takes a single value from a * well-known set. */ - if (index + 1 < objc) { - /* - * Note that these must match the TK_PHOTO_COMPOSITE_* - * constants. - */ - - static const char *compositingRules[] = { - "overlay", "set", NULL - }; - - index++; - if (Tcl_GetIndexFromObj(interp, objv[index], compositingRules, - "compositing rule", 0, &optPtr->compositingRule) - != TCL_OK) { - return TCL_ERROR; - } - *optIndexPtr = index; - } else { - Tcl_AppendResult(interp, "the \"-compositingrule\" option ", - "requires a value", NULL); + if (index + 1 >= objc) { + goto oneValueRequired; + } + index++; + if (Tcl_GetIndexFromObj(interp, objv[index], compositingRules, + "compositing rule", 0, &optPtr->compositingRule) + != TCL_OK) { return TCL_ERROR; } + *optIndexPtr = index; } else if ((bit != OPT_SHRINK) && (bit != OPT_GRAYSCALE)) { - char *val; - maxValues = ((bit == OPT_FROM) || (bit == OPT_TO))? 4: 2; + const char *val; + + maxValues = ((bit == OPT_FROM) || (bit == OPT_TO)) ? 4 : 2; argIndex = index + 1; for (numValues = 0; numValues < maxValues; ++numValues) { if (argIndex >= objc) { @@ -1780,14 +1627,11 @@ ParseSubcommandOptions( } else { break; } - ++argIndex; + argIndex++; } if (numValues == 0) { - Tcl_AppendResult(interp, "the \"", option, "\" option ", - "requires one ", maxValues == 2? "or two": "to four", - " integer values", NULL); - return TCL_ERROR; + goto manyValuesRequired; } *optIndexPtr = (index += numValues); @@ -1811,9 +1655,8 @@ ParseSubcommandOptions( case OPT_FROM: if ((values[0] < 0) || (values[1] < 0) || ((numValues > 2) && ((values[2] < 0) || (values[3] < 0)))) { - Tcl_AppendResult(interp, "value(s) for the -from", - " option must be non-negative", NULL); - return TCL_ERROR; + needed = "non-negative"; + goto numberOutOfRange; } if (numValues <= 2) { optPtr->fromX = values[0]; @@ -1834,9 +1677,8 @@ ParseSubcommandOptions( case OPT_TO: if ((values[0] < 0) || (values[1] < 0) || ((numValues > 2) && ((values[2] < 0) || (values[3] < 0)))) { - Tcl_AppendResult(interp, "value(s) for the -to", - " option must be non-negative", NULL); - return TCL_ERROR; + needed = "non-negative"; + goto numberOutOfRange; } if (numValues <= 2) { optPtr->toX = values[0]; @@ -1852,9 +1694,8 @@ ParseSubcommandOptions( break; case OPT_ZOOM: if ((values[0] <= 0) || (values[1] <= 0)) { - Tcl_AppendResult(interp, "value(s) for the -zoom", - " option must be positive", NULL); - return TCL_ERROR; + needed = "positive"; + goto numberOutOfRange; } optPtr->zoomX = values[0]; optPtr->zoomY = values[1]; @@ -1868,8 +1709,50 @@ ParseSubcommandOptions( optPtr->options |= bit; } - return TCL_OK; + + /* + * Exception generation. + */ + + oneValueRequired: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "the \"%s\" option requires a value", expandedOption)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "MISSING_VALUE", NULL); + return TCL_ERROR; + + manyValuesRequired: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "the \"%s\" option requires one %s integer values", + expandedOption, (maxValues == 2) ? "or two": "to four")); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "MISSING_VALUE", NULL); + return TCL_ERROR; + + numberOutOfRange: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "value(s) for the %s option must be %s", expandedOption, needed)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_VALUE", NULL); + return TCL_ERROR; + + unknownOrAmbiguousOption: + msgObj = Tcl_ObjPrintf("unrecognized option \"%s\": must be ", option); + bit = 1; + for (listPtr = optionNames; *listPtr != NULL; ++listPtr) { + if (allowedOptions & bit) { + if (allowedOptions & (bit - 1)) { + if (allowedOptions & ~((bit << 1) - 1)) { + Tcl_AppendToObj(msgObj, ", ", -1); + } else { + Tcl_AppendToObj(msgObj, ", or ", -1); + } + } + Tcl_AppendToObj(msgObj, *listPtr, -1); + } + bit <<= 1; + } + Tcl_SetObjResult(interp, msgObj); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_OPTION", NULL); + return TCL_ERROR; } /* @@ -1906,34 +1789,42 @@ 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; const char **args; - args = (const char **) ckalloc((objc + 1) * sizeof(char *)); + 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--; } else { - Tcl_AppendResult(interp, - "value for \"-data\" missing", NULL); + ckfree(args); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "value for \"-data\" missing", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", + "MISSING_VALUE", NULL); 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--; } else { - Tcl_AppendResult(interp, - "value for \"-format\" missing", NULL); + ckfree(args); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "value for \"-format\" missing", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", + "MISSING_VALUE", NULL); return TCL_ERROR; } } @@ -1969,10 +1860,10 @@ ImgPhotoConfigureMaster( if (Tk_ConfigureWidget(interp, Tk_MainWindow(interp), configSpecs, j, args, (char *) masterPtr, flags) != TCL_OK) { - ckfree((char *) args); + ckfree(args); goto errorExit; } - ckfree((char *) args); + ckfree(args); /* * Regard the empty string for -file, -data or -format as the null value. @@ -1987,9 +1878,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; @@ -2005,8 +1897,8 @@ ImgPhotoConfigureMaster( * object. */ - (void) Tcl_GetStringFromObj(format, &length); - if (length) { + (void) Tcl_GetString(format); + if (format->length) { Tcl_IncrRefCount(format); } else { format = NULL; @@ -2023,8 +1915,9 @@ ImgPhotoConfigureMaster( if (ImgPhotoSetSize(masterPtr, masterPtr->width, masterPtr->height) != TCL_OK) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, TK_PHOTO_ALLOC_FAILURE_MESSAGE, NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1)); + Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL); goto errorExit; } @@ -2036,15 +1929,16 @@ ImgPhotoConfigureMaster( if ((masterPtr->fileString != NULL) && ((masterPtr->fileString != oldFileString) || (masterPtr->format != oldFormat))) { - /* * Prevent file system access in a safe interpreter. */ if (Tcl_IsSafe(interp)) { Tcl_ResetResult(interp); - Tcl_AppendResult(interp, - "can't get image from a file in a safe interpreter", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "can't get image from a file in a safe interpreter", + -1)); + Tcl_SetErrorCode(interp, "TK", "SAFE", "PHOTO_FILE", NULL); goto errorExit; } @@ -2068,15 +1962,16 @@ ImgPhotoConfigureMaster( result = ImgPhotoSetSize(masterPtr, imageWidth, imageHeight); if (result != TCL_OK) { Tcl_Close(NULL, chan); - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, TK_PHOTO_ALLOC_FAILURE_MESSAGE, NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1)); + Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL); goto errorExit; } tempformat = masterPtr->format; if (oldformat && tempformat) { tempformat = (Tcl_Obj *) Tcl_GetString(tempformat); } - result = (*imageFormat->fileReadProc)(interp, chan, + result = imageFormat->fileReadProc(interp, chan, masterPtr->fileString, tempformat, (Tk_PhotoHandle) masterPtr, 0, 0, imageWidth, imageHeight, 0, 0); Tcl_Close(NULL, chan); @@ -2098,8 +1993,9 @@ ImgPhotoConfigureMaster( goto errorExit; } if (ImgPhotoSetSize(masterPtr, imageWidth, imageHeight) != TCL_OK) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, TK_PHOTO_ALLOC_FAILURE_MESSAGE, NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1)); + Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL); goto errorExit; } tempformat = masterPtr->format; @@ -2110,9 +2006,9 @@ ImgPhotoConfigureMaster( } tempdata = (Tcl_Obj *) Tcl_GetString(tempdata); } - if ((*imageFormat->stringReadProc)(interp, tempdata, - tempformat, (Tk_PhotoHandle) masterPtr, - 0, 0, imageWidth, imageHeight, 0, 0) != TCL_OK) { + if (imageFormat->stringReadProc(interp, tempdata, tempformat, + (Tk_PhotoHandle) masterPtr, 0, 0, imageWidth, imageHeight, + 0, 0) != TCL_OK) { goto errorExit; } @@ -2141,7 +2037,7 @@ ImgPhotoConfigureMaster( for (instancePtr = masterPtr->instancePtr; instancePtr != NULL; instancePtr = instancePtr->nextPtr) { - ImgPhotoConfigureInstance(instancePtr); + TkImgPhotoConfigureInstance(instancePtr); } /* @@ -2176,333 +2072,6 @@ ImgPhotoConfigureMaster( /* *---------------------------------------------------------------------- * - * ImgPhotoConfigureInstance -- - * - * This function is called to create displaying information for a photo - * image instance based on the configuration information in the master. - * It is invoked both when new instances are created and when the master - * is reconfigured. - * - * Results: - * None. - * - * Side effects: - * Generates errors via Tcl_BackgroundError if there are problems in - * setting up the instance. - * - *---------------------------------------------------------------------- - */ - -static void -ImgPhotoConfigureInstance( - PhotoInstance *instancePtr) /* Instance to reconfigure. */ -{ - PhotoMaster *masterPtr = instancePtr->masterPtr; - XImage *imagePtr; - int bitsPerPixel; - ColorTable *colorTablePtr; - XRectangle validBox; - - /* - * If the -palette configuration option has been set for the master, use - * the value specified for our palette, but only if it is a valid palette - * for our windows. Use the gamma value specified the master. - */ - - if ((masterPtr->palette && masterPtr->palette[0]) - && IsValidPalette(instancePtr, masterPtr->palette)) { - instancePtr->palette = masterPtr->palette; - } else { - instancePtr->palette = instancePtr->defaultPalette; - } - instancePtr->gamma = masterPtr->gamma; - - /* - * If we don't currently have a color table, or if the one we have no - * longer applies (e.g. because our palette or gamma has changed), get a - * new one. - */ - - colorTablePtr = instancePtr->colorTablePtr; - if ((colorTablePtr == NULL) - || (instancePtr->colormap != colorTablePtr->id.colormap) - || (instancePtr->palette != colorTablePtr->id.palette) - || (instancePtr->gamma != colorTablePtr->id.gamma)) { - /* - * Free up our old color table, and get a new one. - */ - - if (colorTablePtr != NULL) { - colorTablePtr->liveRefCount -= 1; - FreeColorTable(colorTablePtr, 0); - } - GetColorTable(instancePtr); - - /* - * Create a new XImage structure for sending data to the X server, if - * necessary. - */ - - if (instancePtr->colorTablePtr->flags & BLACK_AND_WHITE) { - bitsPerPixel = 1; - } else { - bitsPerPixel = instancePtr->visualInfo.depth; - } - - if ((instancePtr->imagePtr == NULL) - || (instancePtr->imagePtr->bits_per_pixel != bitsPerPixel)) { - if (instancePtr->imagePtr != NULL) { - XDestroyImage(instancePtr->imagePtr); - } - imagePtr = XCreateImage(instancePtr->display, - instancePtr->visualInfo.visual, (unsigned) bitsPerPixel, - (bitsPerPixel > 1? ZPixmap: XYBitmap), 0, NULL, - 1, 1, 32, 0); - instancePtr->imagePtr = imagePtr; - - /* - * We create images using the local host's endianness, rather than - * the endianness of the server; otherwise we would have to - * byte-swap any 16 or 32 bit values that we store in the image - * if the server's endianness is different from ours. - */ - - if (imagePtr != NULL) { -#ifdef WORDS_BIGENDIAN - imagePtr->byte_order = MSBFirst; -#else - imagePtr->byte_order = LSBFirst; -#endif - _XInitImageFuncPtrs(imagePtr); - } - } - } - - /* - * If the user has specified a width and/or height for the master which is - * different from our current width/height, set the size to the values - * specified by the user. If we have no pixmap, we do this also, since it - * has the side effect of allocating a pixmap for us. - */ - - if ((instancePtr->pixels == None) || (instancePtr->error == NULL) - || (instancePtr->width != masterPtr->width) - || (instancePtr->height != masterPtr->height)) { - ImgPhotoInstanceSetSize(instancePtr); - } - - /* - * Redither this instance if necessary. - */ - - if ((masterPtr->flags & IMAGE_CHANGED) - || (instancePtr->colorTablePtr != colorTablePtr)) { - TkClipBox(masterPtr->validRegion, &validBox); - if ((validBox.width > 0) && (validBox.height > 0)) { - DitherInstance(instancePtr, validBox.x, validBox.y, - validBox.width, validBox.height); - } - } -} - -/* - *---------------------------------------------------------------------- - * - * ImgPhotoGet -- - * - * This function is called for each use of a photo image in a widget. - * - * Results: - * The return value is a token for the instance, which is passed back to - * us in calls to ImgPhotoDisplay and ImgPhotoFree. - * - * Side effects: - * A data structure is set up for the instance (or, an existing instance - * is re-used for the new one). - * - *---------------------------------------------------------------------- - */ - -static ClientData -ImgPhotoGet( - Tk_Window tkwin, /* Window in which the instance will be - * used. */ - ClientData masterData) /* Pointer to our master structure for the - * image. */ -{ - PhotoMaster *masterPtr = (PhotoMaster *) masterData; - PhotoInstance *instancePtr; - Colormap colormap; - int mono, nRed, nGreen, nBlue, numVisuals; - XVisualInfo visualInfo, *visInfoPtr; - char buf[TCL_INTEGER_SPACE * 3]; - XColor *white, *black; - XGCValues gcValues; - - /* - * Table of "best" choices for palette for PseudoColor displays with - * between 3 and 15 bits/pixel. - */ - - static const int paletteChoice[13][3] = { - /* #red, #green, #blue */ - {2, 2, 2, /* 3 bits, 8 colors */}, - {2, 3, 2, /* 4 bits, 12 colors */}, - {3, 4, 2, /* 5 bits, 24 colors */}, - {4, 5, 3, /* 6 bits, 60 colors */}, - {5, 6, 4, /* 7 bits, 120 colors */}, - {7, 7, 4, /* 8 bits, 198 colors */}, - {8, 10, 6, /* 9 bits, 480 colors */}, - {10, 12, 8, /* 10 bits, 960 colors */}, - {14, 15, 9, /* 11 bits, 1890 colors */}, - {16, 20, 12, /* 12 bits, 3840 colors */}, - {20, 24, 16, /* 13 bits, 7680 colors */}, - {26, 30, 20, /* 14 bits, 15600 colors */}, - {32, 32, 30, /* 15 bits, 30720 colors */} - }; - - /* - * See if there is already an instance for windows using the same - * colormap. If so then just re-use it. - */ - - colormap = Tk_Colormap(tkwin); - for (instancePtr = masterPtr->instancePtr; instancePtr != NULL; - instancePtr = instancePtr->nextPtr) { - if ((colormap == instancePtr->colormap) - && (Tk_Display(tkwin) == instancePtr->display)) { - /* - * Re-use this instance. - */ - - if (instancePtr->refCount == 0) { - /* - * We are resurrecting this instance. - */ - - Tcl_CancelIdleCall(DisposeInstance, (ClientData) instancePtr); - if (instancePtr->colorTablePtr != NULL) { - FreeColorTable(instancePtr->colorTablePtr, 0); - } - GetColorTable(instancePtr); - } - instancePtr->refCount++; - return (ClientData) instancePtr; - } - } - - /* - * The image isn't already in use in a window with the same colormap. Make - * a new instance of the image. - */ - - instancePtr = (PhotoInstance *) ckalloc(sizeof(PhotoInstance)); - instancePtr->masterPtr = masterPtr; - instancePtr->display = Tk_Display(tkwin); - instancePtr->colormap = Tk_Colormap(tkwin); - Tk_PreserveColormap(instancePtr->display, instancePtr->colormap); - instancePtr->refCount = 1; - instancePtr->colorTablePtr = NULL; - instancePtr->pixels = None; - instancePtr->error = NULL; - instancePtr->width = 0; - instancePtr->height = 0; - instancePtr->imagePtr = 0; - instancePtr->nextPtr = masterPtr->instancePtr; - masterPtr->instancePtr = instancePtr; - - /* - * Obtain information about the visual and decide on the default palette. - */ - - visualInfo.screen = Tk_ScreenNumber(tkwin); - visualInfo.visualid = XVisualIDFromVisual(Tk_Visual(tkwin)); - visInfoPtr = XGetVisualInfo(Tk_Display(tkwin), - VisualScreenMask | VisualIDMask, &visualInfo, &numVisuals); - if (visInfoPtr == NULL) { - Tcl_Panic("ImgPhotoGet couldn't find visual for window"); - } - - nRed = 2; - nGreen = nBlue = 0; - mono = 1; - instancePtr->visualInfo = *visInfoPtr; - switch (visInfoPtr->class) { - case DirectColor: - case TrueColor: - nRed = 1 << CountBits(visInfoPtr->red_mask); - nGreen = 1 << CountBits(visInfoPtr->green_mask); - nBlue = 1 << CountBits(visInfoPtr->blue_mask); - mono = 0; - break; - case PseudoColor: - case StaticColor: - if (visInfoPtr->depth > 15) { - nRed = 32; - nGreen = 32; - nBlue = 32; - mono = 0; - } else if (visInfoPtr->depth >= 3) { - const int *ip = paletteChoice[visInfoPtr->depth - 3]; - - nRed = ip[0]; - nGreen = ip[1]; - nBlue = ip[2]; - mono = 0; - } - break; - case GrayScale: - case StaticGray: - nRed = 1 << visInfoPtr->depth; - break; - } - XFree((char *) visInfoPtr); - - if (mono) { - sprintf(buf, "%d", nRed); - } else { - sprintf(buf, "%d/%d/%d", nRed, nGreen, nBlue); - } - instancePtr->defaultPalette = Tk_GetUid(buf); - - /* - * Make a GC with background = black and foreground = white. - */ - - white = Tk_GetColor(masterPtr->interp, tkwin, "white"); - black = Tk_GetColor(masterPtr->interp, tkwin, "black"); - gcValues.foreground = (white != NULL)? white->pixel: - WhitePixelOfScreen(Tk_Screen(tkwin)); - gcValues.background = (black != NULL)? black->pixel: - BlackPixelOfScreen(Tk_Screen(tkwin)); - Tk_FreeColor(white); - Tk_FreeColor(black); - gcValues.graphics_exposures = False; - instancePtr->gc = Tk_GetGC(tkwin, - GCForeground|GCBackground|GCGraphicsExposures, &gcValues); - - /* - * Set configuration options and finish the initialization of the - * instance. This will also dither the image if necessary. - */ - - ImgPhotoConfigureInstance(instancePtr); - - /* - * If this is the first instance, must set the size of the image. - */ - - if (instancePtr->nextPtr == NULL) { - Tk_ImageChanged(masterPtr->tkMaster, 0, 0, 0, 0, - masterPtr->width, masterPtr->height); - } - - return (ClientData) instancePtr; -} - -/* - *---------------------------------------------------------------------- - * * ToggleComplexAlphaIfNeeded -- * * This function is called when an image is modified to check if any @@ -2522,8 +2091,8 @@ static int ToggleComplexAlphaIfNeeded( PhotoMaster *mPtr) { - size_t len = MAX(mPtr->userWidth, mPtr->width) * - MAX(mPtr->userHeight, mPtr->height) * 4; + size_t len = (size_t)MAX(mPtr->userWidth, mPtr->width) * + (size_t)MAX(mPtr->userHeight, mPtr->height) * 4; unsigned char *c = mPtr->pix32; unsigned char *end = c + len; @@ -2533,6 +2102,9 @@ ToggleComplexAlphaIfNeeded( */ mPtr->flags &= ~COMPLEX_ALPHA; + if (c == NULL) { + return 0; + } c += 3; /* Start at first alpha byte. */ for (; c < end; c += 4) { if (*c && *c != 255) { @@ -2546,351 +2118,6 @@ ToggleComplexAlphaIfNeeded( /* *---------------------------------------------------------------------- * - * ImgPhotoBlendComplexAlpha -- - * - * This function is called when an image with partially transparent - * pixels must be drawn over another image. It blends the photo data onto - * a local copy of the surface that we are drawing on, *including* the - * pixels drawn by everything that should be drawn underneath the image. - * - * Much of this code has hard-coded values in for speed because this - * routine is performance critical for complex image drawing. - * - * Results: - * None. - * - * Side effects: - * Background image passed in gets drawn over with image data. - * - * Notes: - * This should work on all platforms that set mask and shift data - * properly from the visualInfo. RGB is really only a 24+ bpp version - * whereas RGB15 is the correct version and works for 15bpp+, but it - * slower, so it's only used for 15bpp+. - * - * Note that Win32 pre-defines those operations that we really need. - * - *---------------------------------------------------------------------- - */ - -#ifndef __WIN32__ -#define GetRValue(rgb) (UCHAR(((rgb) & red_mask) >> red_shift)) -#define GetGValue(rgb) (UCHAR(((rgb) & green_mask) >> green_shift)) -#define GetBValue(rgb) (UCHAR(((rgb) & blue_mask) >> blue_shift)) -#define RGB(r, g, b) ((unsigned)( \ - (UCHAR(r) << red_shift) | \ - (UCHAR(g) << green_shift) | \ - (UCHAR(b) << blue_shift) )) -#define RGB15(r, g, b) ((unsigned)( \ - (((r) * red_mask / 255) & red_mask) | \ - (((g) * green_mask / 255) & green_mask) | \ - (((b) * blue_mask / 255) & blue_mask) )) -#endif /* !__WIN32__ */ - -static void -ImgPhotoBlendComplexAlpha( - XImage *bgImg, /* Background image to draw on. */ - PhotoInstance *iPtr, /* Image instance to draw. */ - int xOffset, int yOffset, /* X & Y offset into image instance to - * draw. */ - int width, int height) /* Width & height of image to draw. */ -{ - int x, y, line; - unsigned long pixel; - unsigned char r, g, b, alpha, unalpha, *masterPtr; - unsigned char *alphaAr = iPtr->masterPtr->pix32; - - /* - * This blending is an integer version of the Source-Over compositing rule - * (see Porter&Duff, "Compositing Digital Images", proceedings of SIGGRAPH - * 1984) that has been hard-coded (for speed) to work with targetting a - * solid surface. - * - * The 'unalpha' field must be 255-alpha; it is separated out to encourage - * more efficient compilation. - */ - -#define ALPHA_BLEND(bgPix, imgPix, alpha, unalpha) \ - ((bgPix * unalpha + imgPix * alpha) / 255) - - /* - * We have to get the mask and shift info from the visual on non-Win32 so - * that the macros Get*Value(), RGB() and RGB15() work correctly. This - * might be cached for better performance. - */ - -#ifndef __WIN32__ - unsigned long red_mask, green_mask, blue_mask; - unsigned long red_shift, green_shift, blue_shift; - Visual *visual = iPtr->visualInfo.visual; - - red_mask = visual->red_mask; - green_mask = visual->green_mask; - blue_mask = visual->blue_mask; - red_shift = 0; - green_shift = 0; - blue_shift = 0; - while ((0x0001 & (red_mask >> red_shift)) == 0) { - red_shift++; - } - while ((0x0001 & (green_mask >> green_shift)) == 0) { - green_shift++; - } - while ((0x0001 & (blue_mask >> blue_shift)) == 0) { - blue_shift++; - } -#endif /* !__WIN32__ */ - - /* - * Only UNIX requires the special case for <24bpp. It varies with 3 extra - * shifts and uses RGB15. The 24+bpp version could also then be further - * optimized. - */ - -#if !(defined(__WIN32__) || defined(MAC_OSX_TK)) - if (bgImg->depth < 24) { - unsigned char red_mlen, green_mlen, blue_mlen; - - red_mlen = 8 - CountBits(red_mask >> red_shift); - green_mlen = 8 - CountBits(green_mask >> green_shift); - blue_mlen = 8 - CountBits(blue_mask >> blue_shift); - for (y = 0; y < height; y++) { - line = (y + yOffset) * iPtr->masterPtr->width; - for (x = 0; x < width; x++) { - masterPtr = alphaAr + ((line + x + xOffset) * 4); - alpha = masterPtr[3]; - - /* - * Ignore pixels that are fully transparent - */ - - if (alpha) { - /* - * We could perhaps be more efficient than XGetPixel for - * 24 and 32 bit displays, but this seems "fast enough". - */ - - r = masterPtr[0]; - g = masterPtr[1]; - b = masterPtr[2]; - if (alpha != 255) { - /* - * Only blend pixels that have some transparency - */ - - unsigned char ra, ga, ba; - - pixel = XGetPixel(bgImg, x, y); - ra = GetRValue(pixel) << red_mlen; - ga = GetGValue(pixel) << green_mlen; - ba = GetBValue(pixel) << blue_mlen; - unalpha = 255 - alpha; /* Calculate once. */ - r = ALPHA_BLEND(ra, r, alpha, unalpha); - g = ALPHA_BLEND(ga, g, alpha, unalpha); - b = ALPHA_BLEND(ba, b, alpha, unalpha); - } - XPutPixel(bgImg, x, y, RGB15(r, g, b)); - } - } - } - return; - } -#endif /* !__WIN32__ && !MAC_OSX_TK */ - - for (y = 0; y < height; y++) { - line = (y + yOffset) * iPtr->masterPtr->width; - for (x = 0; x < width; x++) { - masterPtr = alphaAr + ((line + x + xOffset) * 4); - alpha = masterPtr[3]; - - /* - * Ignore pixels that are fully transparent - */ - - if (alpha) { - /* - * We could perhaps be more efficient than XGetPixel for 24 - * and 32 bit displays, but this seems "fast enough". - */ - - r = masterPtr[0]; - g = masterPtr[1]; - b = masterPtr[2]; - if (alpha != 255) { - /* - * Only blend pixels that have some transparency - */ - - unsigned char ra, ga, ba; - - pixel = XGetPixel(bgImg, x, y); - ra = GetRValue(pixel); - ga = GetGValue(pixel); - ba = GetBValue(pixel); - unalpha = 255 - alpha; /* Calculate once. */ - r = ALPHA_BLEND(ra, r, alpha, unalpha); - g = ALPHA_BLEND(ga, g, alpha, unalpha); - b = ALPHA_BLEND(ba, b, alpha, unalpha); - } - XPutPixel(bgImg, x, y, RGB(r, g, b)); - } - } - } -#undef ALPHA_BLEND -} - -/* - *---------------------------------------------------------------------- - * - * ImgPhotoDisplay -- - * - * This function is invoked to draw a photo image. - * - * Results: - * None. - * - * Side effects: - * A portion of the image gets rendered in a pixmap or window. - * - *---------------------------------------------------------------------- - */ - -static void -ImgPhotoDisplay( - ClientData clientData, /* Pointer to PhotoInstance structure for - * instance to be displayed. */ - Display *display, /* Display on which to draw image. */ - Drawable drawable, /* Pixmap or window in which to draw image. */ - int imageX, int imageY, /* Upper-left corner of region within image to - * draw. */ - int width, int height, /* Dimensions of region within image to - * draw. */ - int drawableX,int drawableY)/* Coordinates within drawable that correspond - * to imageX and imageY. */ -{ - PhotoInstance *instancePtr = (PhotoInstance *) clientData; - XVisualInfo visInfo = instancePtr->visualInfo; - - /* - * If there's no pixmap, it means that an error occurred while creating - * the image instance so it can't be displayed. - */ - - if (instancePtr->pixels == None) { - return; - } - - if ((instancePtr->masterPtr->flags & COMPLEX_ALPHA) - && visInfo.depth >= 15 - && (visInfo.class == DirectColor || visInfo.class == TrueColor)) { - Tk_ErrorHandler handler; - XImage *bgImg = NULL; - - /* - * Create an error handler to suppress the case where the input was - * not properly constrained, which can cause an X error. [Bug 979239] - */ - - handler = Tk_CreateErrorHandler(display, -1, -1, -1, NULL, - (ClientData) NULL); - - /* - * Pull the current background from the display to blend with - */ - - bgImg = XGetImage(display, drawable, drawableX, drawableY, - (unsigned int)width, (unsigned int)height, AllPlanes, ZPixmap); - if (bgImg == NULL) { - Tk_DeleteErrorHandler(handler); - /* We failed to get the image so draw without blending alpha. It's the best we can do */ - goto fallBack; - } - - ImgPhotoBlendComplexAlpha(bgImg, instancePtr, imageX, imageY, width, - height); - - /* - * Color info is unimportant as we only do this operation for depth >= - * 15. - */ - - TkPutImage(NULL, 0, display, drawable, instancePtr->gc, - bgImg, 0, 0, drawableX, drawableY, - (unsigned int) width, (unsigned int) height); - XDestroyImage(bgImg); - Tk_DeleteErrorHandler(handler); - } else { - /* - * masterPtr->region describes which parts of the image contain valid - * data. We set this region as the clip mask for the gc, setting its - * origin appropriately, and use it when drawing the image. - */ - - fallBack: - TkSetRegion(display, instancePtr->gc, - instancePtr->masterPtr->validRegion); - XSetClipOrigin(display, instancePtr->gc, drawableX - imageX, - drawableY - imageY); - XCopyArea(display, instancePtr->pixels, drawable, instancePtr->gc, - imageX, imageY, (unsigned) width, (unsigned) height, - drawableX, drawableY); - XSetClipMask(display, instancePtr->gc, None); - XSetClipOrigin(display, instancePtr->gc, 0, 0); - } - XFlush(display); -} - -/* - *---------------------------------------------------------------------- - * - * ImgPhotoFree -- - * - * This function is called when a widget ceases to use a particular - * instance of an image. We don't actually get rid of the instance until - * later because we may be about to get this instance again. - * - * Results: - * None. - * - * Side effects: - * Internal data structures get cleaned up, later. - * - *---------------------------------------------------------------------- - */ - -static void -ImgPhotoFree( - ClientData clientData, /* Pointer to PhotoInstance structure for - * instance to be displayed. */ - Display *display) /* Display containing window that used - * image. */ -{ - PhotoInstance *instancePtr = (PhotoInstance *) clientData; - ColorTable *colorPtr; - - instancePtr->refCount -= 1; - if (instancePtr->refCount > 0) { - return; - } - - /* - * There are no more uses of the image within this widget. Decrement the - * count of live uses of its color table, so that its colors can be - * reclaimed if necessary, and set up an idle call to free the instance - * structure. - */ - - colorPtr = instancePtr->colorTablePtr; - if (colorPtr != NULL) { - colorPtr->liveRefCount -= 1; - } - - Tcl_DoWhenIdle(DisposeInstance, (ClientData) instancePtr); -} - -/* - *---------------------------------------------------------------------- - * * ImgPhotoDelete -- * * This function is called by the image code to delete the master @@ -2910,22 +2137,22 @@ ImgPhotoDelete( ClientData masterData) /* Pointer to PhotoMaster structure for image. * Must not have any more instances. */ { - PhotoMaster *masterPtr = (PhotoMaster *) masterData; + PhotoMaster *masterPtr = masterData; PhotoInstance *instancePtr; while ((instancePtr = masterPtr->instancePtr) != NULL) { if (instancePtr->refCount > 0) { Tcl_Panic("tried to delete photo image when instances still exist"); } - Tcl_CancelIdleCall(DisposeInstance, (ClientData) instancePtr); - DisposeInstance((ClientData) instancePtr); + Tcl_CancelIdleCall(TkImgDisposeInstance, instancePtr); + TkImgDisposeInstance(instancePtr); } masterPtr->tkMaster = NULL; if (masterPtr->imageCmd != NULL) { Tcl_DeleteCommandFromToken(masterPtr->interp, masterPtr->imageCmd); } if (masterPtr->pix32 != NULL) { - ckfree((char *) masterPtr->pix32); + ckfree(masterPtr->pix32); } if (masterPtr->validRegion != NULL) { TkDestroyRegion(masterPtr->validRegion); @@ -2937,7 +2164,7 @@ ImgPhotoDelete( Tcl_DecrRefCount(masterPtr->format); } Tk_FreeOptions(configSpecs, (char *) masterPtr, NULL, 0); - ckfree((char *) masterPtr); + ckfree(masterPtr); } /* @@ -2962,7 +2189,7 @@ ImgPhotoCmdDeletedProc( ClientData clientData) /* Pointer to PhotoMaster structure for * image. */ { - PhotoMaster *masterPtr = (PhotoMaster *) clientData; + PhotoMaster *masterPtr = clientData; masterPtr->imageCmd = NULL; if (masterPtr->tkMaster != NULL) { @@ -3021,15 +2248,12 @@ ImgPhotoSetSize( if ((width != masterPtr->width) || (height != masterPtr->height) || (masterPtr->pix32 == NULL)) { - /* - * Not a u-long, but should be one. - */ - - unsigned /*long*/ newPixSize = (unsigned /*long*/) (height * pitch); + unsigned newPixSize; if (pitch && height > (int)(UINT_MAX / pitch)) { return TCL_ERROR; } + newPixSize = height * pitch; /* * Some mallocs() really hate allocating zero bytes. [Bug 619544] @@ -3038,7 +2262,7 @@ ImgPhotoSetSize( if (newPixSize == 0) { newPix32 = NULL; } else { - newPix32 = (unsigned char *) attemptckalloc(newPixSize); + newPix32 = attemptckalloc(newPixSize); if (newPix32 == NULL) { return TCL_ERROR; } @@ -3088,7 +2312,7 @@ ImgPhotoSetSize( memset(newPix32 + h*pitch, 0, ((size_t) (height - h) * pitch)); } } else { - memset(newPix32, 0, ((size_t) height * pitch)); + memset(newPix32, 0, ((size_t)height * pitch)); } if (masterPtr->pix32 != NULL) { @@ -3105,7 +2329,7 @@ ImgPhotoSetSize( offset = validBox.y * pitch; memcpy(newPix32 + offset, masterPtr->pix32 + offset, - ((size_t) validBox.height * pitch)); + ((size_t)validBox.height * pitch)); } else if ((validBox.width > 0) && (validBox.height > 0)) { /* @@ -3116,13 +2340,13 @@ ImgPhotoSetSize( srcPtr = masterPtr->pix32 + (validBox.y * masterPtr->width + validBox.x) * 4; for (h = validBox.height; h > 0; h--) { - memcpy(destPtr, srcPtr, ((size_t) validBox.width * 4)); + memcpy(destPtr, srcPtr, ((size_t)validBox.width * 4)); destPtr += width * 4; srcPtr += masterPtr->width * 4; } } - ckfree((char *) masterPtr->pix32); + ckfree(masterPtr->pix32); } masterPtr->pix32 = newPix32; @@ -3157,7 +2381,7 @@ ImgPhotoSetSize( for (instancePtr = masterPtr->instancePtr; instancePtr != NULL; instancePtr = instancePtr->nextPtr) { - ImgPhotoInstanceSetSize(instancePtr); + TkImgPhotoInstanceSetSize(instancePtr); } return TCL_OK; @@ -3166,867 +2390,6 @@ ImgPhotoSetSize( /* *---------------------------------------------------------------------- * - * ImgPhotoInstanceSetSize -- - * - * This function reallocates the instance pixmap and dithering error - * array for a photo instance, as necessary, to change the image's size - * to `width' x `height' pixels. - * - * Results: - * None. - * - * Side effects: - * Storage gets reallocated, here and in the X server. - * - *---------------------------------------------------------------------- - */ - -static void -ImgPhotoInstanceSetSize( - PhotoInstance *instancePtr) /* Instance whose size is to be changed. */ -{ - PhotoMaster *masterPtr; - schar *newError, *errSrcPtr, *errDestPtr; - int h, offset; - XRectangle validBox; - Pixmap newPixmap; - - masterPtr = instancePtr->masterPtr; - TkClipBox(masterPtr->validRegion, &validBox); - - if ((instancePtr->width != masterPtr->width) - || (instancePtr->height != masterPtr->height) - || (instancePtr->pixels == None)) { - newPixmap = Tk_GetPixmap(instancePtr->display, - RootWindow(instancePtr->display, - instancePtr->visualInfo.screen), - (masterPtr->width > 0) ? masterPtr->width: 1, - (masterPtr->height > 0) ? masterPtr->height: 1, - instancePtr->visualInfo.depth); - if (!newPixmap) { - Tcl_Panic("Fail to create pixmap with Tk_GetPixmap in ImgPhotoInstanceSetSize.\n"); - } - - /* - * The following is a gross hack needed to properly support colormaps - * under Windows. Before the pixels can be copied to the pixmap, the - * relevent colormap must be associated with the drawable. Normally we - * can infer this association from the window that was used to create - * the pixmap. However, in this case we're using the root window, so - * we have to be more explicit. - */ - - TkSetPixmapColormap(newPixmap, instancePtr->colormap); - - if (instancePtr->pixels != None) { - /* - * Copy any common pixels from the old pixmap and free it. - */ - - XCopyArea(instancePtr->display, instancePtr->pixels, newPixmap, - instancePtr->gc, validBox.x, validBox.y, - validBox.width, validBox.height, validBox.x, validBox.y); - Tk_FreePixmap(instancePtr->display, instancePtr->pixels); - } - instancePtr->pixels = newPixmap; - } - - if ((instancePtr->width != masterPtr->width) - || (instancePtr->height != masterPtr->height) - || (instancePtr->error == NULL)) { - - if (masterPtr->height > 0 && masterPtr->width > 0) { - newError = (schar *) ckalloc((unsigned) - masterPtr->height * masterPtr->width * 3 * sizeof(schar)); - - /* - * Zero the new array so that we don't get bogus error values - * propagating into areas we dither later. - */ - - if ((instancePtr->error != NULL) - && ((instancePtr->width == masterPtr->width) - || (validBox.width == masterPtr->width))) { - if (validBox.y > 0) { - memset(newError, 0, (size_t) - validBox.y * masterPtr->width * 3 * sizeof(schar)); - } - h = validBox.y + validBox.height; - if (h < masterPtr->height) { - memset(newError + h*masterPtr->width*3, 0, - (size_t) (masterPtr->height - h) - * masterPtr->width * 3 * sizeof(schar)); - } - } else { - memset(newError, 0, (size_t) - masterPtr->height * masterPtr->width *3*sizeof(schar)); - } - } else { - newError = NULL; - } - - if (instancePtr->error != NULL) { - /* - * Copy the common area over to the new array and free the old - * array. - */ - - if (masterPtr->width == instancePtr->width) { - offset = validBox.y * masterPtr->width * 3; - memcpy(newError + offset, instancePtr->error + offset, - ((size_t) validBox.height - * masterPtr->width * 3 * sizeof(schar))); - - } else if (validBox.width > 0 && validBox.height > 0) { - errDestPtr = newError + - (validBox.y * masterPtr->width + validBox.x) * 3; - errSrcPtr = instancePtr->error + - (validBox.y * instancePtr->width + validBox.x) * 3; - - for (h = validBox.height; h > 0; --h) { - memcpy(errDestPtr, errSrcPtr, - validBox.width * 3 * sizeof(schar)); - errDestPtr += masterPtr->width * 3; - errSrcPtr += instancePtr->width * 3; - } - } - ckfree((char *) instancePtr->error); - } - - instancePtr->error = newError; - } - - instancePtr->width = masterPtr->width; - instancePtr->height = masterPtr->height; -} - -/* - *---------------------------------------------------------------------- - * - * IsValidPalette -- - * - * This function is called to check whether a value given for the - * -palette option is valid for a particular instance of a photo image. - * - * Results: - * A boolean value: 1 if the palette is acceptable, 0 otherwise. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static int -IsValidPalette( - PhotoInstance *instancePtr, /* Instance to which the palette specification - * is to be applied. */ - const char *palette) /* Palette specification string. */ -{ - int nRed, nGreen, nBlue, mono, numColors; - char *endp; - - /* - * First parse the specification: it must be of the form %d or %d/%d/%d. - */ - - nRed = strtol(palette, &endp, 10); - if ((endp == palette) || ((*endp != 0) && (*endp != '/')) - || (nRed < 2) || (nRed > 256)) { - return 0; - } - - if (*endp == 0) { - mono = 1; - nGreen = nBlue = nRed; - } else { - palette = endp + 1; - nGreen = strtol(palette, &endp, 10); - if ((endp == palette) || (*endp != '/') || (nGreen < 2) - || (nGreen > 256)) { - return 0; - } - palette = endp + 1; - nBlue = strtol(palette, &endp, 10); - if ((endp == palette) || (*endp != 0) || (nBlue < 2) - || (nBlue > 256)) { - return 0; - } - mono = 0; - } - - switch (instancePtr->visualInfo.class) { - case DirectColor: - case TrueColor: - if ((nRed > (1 << CountBits(instancePtr->visualInfo.red_mask))) - || (nGreen>(1<<CountBits(instancePtr->visualInfo.green_mask))) - || (nBlue>(1<<CountBits(instancePtr->visualInfo.blue_mask)))) { - return 0; - } - break; - case PseudoColor: - case StaticColor: - numColors = nRed; - if (!mono) { - numColors *= nGreen*nBlue; - } - if (numColors > (1 << instancePtr->visualInfo.depth)) { - return 0; - } - break; - case GrayScale: - case StaticGray: - if (!mono || (nRed > (1 << instancePtr->visualInfo.depth))) { - return 0; - } - break; - } - - return 1; -} - -/* - *---------------------------------------------------------------------- - * - * CountBits -- - * - * This function counts how many bits are set to 1 in `mask'. - * - * Results: - * The integer number of bits. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static int -CountBits( - pixel mask) /* Value to count the 1 bits in. */ -{ - int n; - - for (n=0 ; mask!=0 ; mask&=mask-1) { - n++; - } - return n; -} - -/* - *---------------------------------------------------------------------- - * - * GetColorTable -- - * - * This function is called to allocate a table of colormap information - * for an instance of a photo image. Only one such table is allocated for - * all photo instances using the same display, colormap, palette and - * gamma values, so that the application need only request a set of - * colors from the X server once for all such photo widgets. This - * function maintains a hash table to find previously-allocated - * ColorTables. - * - * Results: - * None. - * - * Side effects: - * A new ColorTable may be allocated and placed in the hash table, and - * have colors allocated for it. - * - *---------------------------------------------------------------------- - */ - -static void -GetColorTable( - PhotoInstance *instancePtr) /* Instance needing a color table. */ -{ - ColorTable *colorPtr; - Tcl_HashEntry *entry; - ColorTableId id; - int isNew; - - /* - * Look for an existing ColorTable in the hash table. - */ - - memset(&id, 0, sizeof(id)); - id.display = instancePtr->display; - id.colormap = instancePtr->colormap; - id.palette = instancePtr->palette; - id.gamma = instancePtr->gamma; - if (!imgPhotoColorHashInitialized) { - Tcl_InitHashTable(&imgPhotoColorHash, N_COLOR_HASH); - imgPhotoColorHashInitialized = 1; - } - entry = Tcl_CreateHashEntry(&imgPhotoColorHash, (char *) &id, &isNew); - - if (!isNew) { - /* - * Re-use the existing entry. - */ - - colorPtr = (ColorTable *) Tcl_GetHashValue(entry); - } else { - /* - * No color table currently available; need to make one. - */ - - colorPtr = (ColorTable *) ckalloc(sizeof(ColorTable)); - - /* - * The following line of code should not normally be needed due to the - * assignment in the following line. However, it compensates for bugs - * in some compilers (HP, for example) where sizeof(ColorTable) is 24 - * but the assignment only copies 20 bytes, leaving 4 bytes - * uninitialized; these cause problems when using the id for lookups - * in imgPhotoColorHash, and can result in core dumps. - */ - - memset(&colorPtr->id, 0, sizeof(ColorTableId)); - colorPtr->id = id; - Tk_PreserveColormap(colorPtr->id.display, colorPtr->id.colormap); - colorPtr->flags = 0; - colorPtr->refCount = 0; - colorPtr->liveRefCount = 0; - colorPtr->numColors = 0; - colorPtr->visualInfo = instancePtr->visualInfo; - colorPtr->pixelMap = NULL; - Tcl_SetHashValue(entry, colorPtr); - } - - colorPtr->refCount++; - colorPtr->liveRefCount++; - instancePtr->colorTablePtr = colorPtr; - if (colorPtr->flags & DISPOSE_PENDING) { - Tcl_CancelIdleCall(DisposeColorTable, (ClientData) colorPtr); - colorPtr->flags &= ~DISPOSE_PENDING; - } - - /* - * Allocate colors for this color table if necessary. - */ - - if ((colorPtr->numColors == 0) - && ((colorPtr->flags & BLACK_AND_WHITE) == 0)) { - AllocateColors(colorPtr); - } -} - -/* - *---------------------------------------------------------------------- - * - * FreeColorTable -- - * - * This function is called when an instance ceases using a color table. - * - * Results: - * None. - * - * Side effects: - * If no other instances are using this color table, a when-idle handler - * is registered to free up the color table and the colors allocated for - * it. - * - *---------------------------------------------------------------------- - */ - -static void -FreeColorTable( - ColorTable *colorPtr, /* Pointer to the color table which is no - * longer required by an instance. */ - int force) /* Force free to happen immediately. */ -{ - colorPtr->refCount--; - if (colorPtr->refCount > 0) { - return; - } - - if (force) { - if ((colorPtr->flags & DISPOSE_PENDING) != 0) { - Tcl_CancelIdleCall(DisposeColorTable, (ClientData) colorPtr); - colorPtr->flags &= ~DISPOSE_PENDING; - } - DisposeColorTable((ClientData) colorPtr); - } else if ((colorPtr->flags & DISPOSE_PENDING) == 0) { - Tcl_DoWhenIdle(DisposeColorTable, (ClientData) colorPtr); - colorPtr->flags |= DISPOSE_PENDING; - } -} - -/* - *---------------------------------------------------------------------- - * - * AllocateColors -- - * - * This function allocates the colors required by a color table, and sets - * up the fields in the color table data structure which are used in - * dithering. - * - * Results: - * None. - * - * Side effects: - * Colors are allocated from the X server. Fields in the color table data - * structure are updated. - * - *---------------------------------------------------------------------- - */ - -static void -AllocateColors( - ColorTable *colorPtr) /* Pointer to the color table requiring colors - * to be allocated. */ -{ - int i, r, g, b, rMult, mono; - int numColors, nRed, nGreen, nBlue; - double fr, fg, fb, igam; - XColor *colors; - unsigned long *pixels; - - /* - * 16-bit intensity value for i/n of full intensity. - */ -#define CFRAC(i, n) ((i) * 65535 / (n)) - - /* As for CFRAC, but apply exponent of g. */ -#define CGFRAC(i, n, g) ((int)(65535 * pow((double)(i) / (n), (g)))) - - /* - * First parse the palette specification to get the required number of - * shades of each primary. - */ - - mono = sscanf(colorPtr->id.palette, "%d/%d/%d", &nRed, &nGreen, &nBlue) - <= 1; - igam = 1.0 / colorPtr->id.gamma; - - /* - * Each time around this loop, we reduce the number of colors we're trying - * to allocate until we succeed in allocating all of the colors we need. - */ - - for (;;) { - /* - * If we are using 1 bit/pixel, we don't need to allocate any colors - * (we just use the foreground and background colors in the GC). - */ - - if (mono && (nRed <= 2)) { - colorPtr->flags |= BLACK_AND_WHITE; - return; - } - - /* - * Calculate the RGB coordinates of the colors we want to allocate and - * store them in *colors. - */ - - if ((colorPtr->visualInfo.class == DirectColor) - || (colorPtr->visualInfo.class == TrueColor)) { - - /* - * Direct/True Color: allocate shades of red, green, blue - * independently. - */ - - if (mono) { - numColors = nGreen = nBlue = nRed; - } else { - numColors = MAX(MAX(nRed, nGreen), nBlue); - } - colors = (XColor *) ckalloc(numColors * sizeof(XColor)); - - for (i = 0; i < numColors; ++i) { - if (igam == 1.0) { - colors[i].red = CFRAC(i, nRed - 1); - colors[i].green = CFRAC(i, nGreen - 1); - colors[i].blue = CFRAC(i, nBlue - 1); - } else { - colors[i].red = CGFRAC(i, nRed - 1, igam); - colors[i].green = CGFRAC(i, nGreen - 1, igam); - colors[i].blue = CGFRAC(i, nBlue - 1, igam); - } - } - } else { - /* - * PseudoColor, StaticColor, GrayScale or StaticGray visual: we - * have to allocate each color in the color cube separately. - */ - - numColors = (mono) ? nRed: (nRed * nGreen * nBlue); - colors = (XColor *) ckalloc(numColors * sizeof(XColor)); - - if (!mono) { - /* - * Color display using a PseudoColor or StaticColor visual. - */ - - i = 0; - for (r = 0; r < nRed; ++r) { - for (g = 0; g < nGreen; ++g) { - for (b = 0; b < nBlue; ++b) { - if (igam == 1.0) { - colors[i].red = CFRAC(r, nRed - 1); - colors[i].green = CFRAC(g, nGreen - 1); - colors[i].blue = CFRAC(b, nBlue - 1); - } else { - colors[i].red = CGFRAC(r, nRed - 1, igam); - colors[i].green = CGFRAC(g, nGreen - 1, igam); - colors[i].blue = CGFRAC(b, nBlue - 1, igam); - } - i++; - } - } - } - } else { - /* - * Monochrome display - allocate the shades of grey we want. - */ - - for (i = 0; i < numColors; ++i) { - if (igam == 1.0) { - r = CFRAC(i, numColors - 1); - } else { - r = CGFRAC(i, numColors - 1, igam); - } - colors[i].red = colors[i].green = colors[i].blue = r; - } - } - } - - /* - * Now try to allocate the colors we've calculated. - */ - - pixels = (unsigned long *) ckalloc(numColors * sizeof(unsigned long)); - for (i = 0; i < numColors; ++i) { - if (!XAllocColor(colorPtr->id.display, colorPtr->id.colormap, - &colors[i])) { - /* - * Can't get all the colors we want in the default colormap; - * first try freeing colors from other unused color tables. - */ - - if (!ReclaimColors(&colorPtr->id, numColors - i) - || !XAllocColor(colorPtr->id.display, - colorPtr->id.colormap, &colors[i])) { - /* - * Still can't allocate the color. - */ - - break; - } - } - pixels[i] = colors[i].pixel; - } - - /* - * If we didn't get all of the colors, reduce the resolution of the - * color cube, free the ones we got, and try again. - */ - - if (i >= numColors) { - break; - } - XFreeColors(colorPtr->id.display, colorPtr->id.colormap, pixels, i, 0); - ckfree((char *) colors); - ckfree((char *) pixels); - - if (!mono) { - if ((nRed == 2) && (nGreen == 2) && (nBlue == 2)) { - /* - * Fall back to 1-bit monochrome display. - */ - - mono = 1; - } else { - /* - * Reduce the number of shades of each primary to about 3/4 of - * the previous value. This should reduce the total number of - * colors required to about half the previous value for - * PseudoColor displays. - */ - - nRed = (nRed * 3 + 2) / 4; - nGreen = (nGreen * 3 + 2) / 4; - nBlue = (nBlue * 3 + 2) / 4; - } - } else { - /* - * Reduce the number of shades of gray to about 1/2. - */ - - nRed = nRed / 2; - } - } - - /* - * We have allocated all of the necessary colors: fill in various fields - * of the ColorTable record. - */ - - if (!mono) { - colorPtr->flags |= COLOR_WINDOW; - - /* - * The following is a hairy hack. We only want to index into the - * pixelMap on colormap displays. However, if the display is on - * Windows, then we actually want to store the index not the value - * since we will be passing the color table into the TkPutImage call. - */ - -#ifndef __WIN32__ - if ((colorPtr->visualInfo.class != DirectColor) - && (colorPtr->visualInfo.class != TrueColor)) { - colorPtr->flags |= MAP_COLORS; - } -#endif /* __WIN32__ */ - } - - colorPtr->numColors = numColors; - colorPtr->pixelMap = pixels; - - /* - * Set up quantization tables for dithering. - */ - - rMult = nGreen * nBlue; - for (i = 0; i < 256; ++i) { - r = (i * (nRed - 1) + 127) / 255; - if (mono) { - fr = (double) colors[r].red / 65535.0; - if (colorPtr->id.gamma != 1.0 ) { - fr = pow(fr, colorPtr->id.gamma); - } - colorPtr->colorQuant[0][i] = (int)(fr * 255.99); - colorPtr->redValues[i] = colors[r].pixel; - } else { - g = (i * (nGreen - 1) + 127) / 255; - b = (i * (nBlue - 1) + 127) / 255; - if ((colorPtr->visualInfo.class == DirectColor) - || (colorPtr->visualInfo.class == TrueColor)) { - colorPtr->redValues[i] = - colors[r].pixel & colorPtr->visualInfo.red_mask; - colorPtr->greenValues[i] = - colors[g].pixel & colorPtr->visualInfo.green_mask; - colorPtr->blueValues[i] = - colors[b].pixel & colorPtr->visualInfo.blue_mask; - } else { - r *= rMult; - g *= nBlue; - colorPtr->redValues[i] = r; - colorPtr->greenValues[i] = g; - colorPtr->blueValues[i] = b; - } - fr = (double) colors[r].red / 65535.0; - fg = (double) colors[g].green / 65535.0; - fb = (double) colors[b].blue / 65535.0; - if (colorPtr->id.gamma != 1.0) { - fr = pow(fr, colorPtr->id.gamma); - fg = pow(fg, colorPtr->id.gamma); - fb = pow(fb, colorPtr->id.gamma); - } - colorPtr->colorQuant[0][i] = (int)(fr * 255.99); - colorPtr->colorQuant[1][i] = (int)(fg * 255.99); - colorPtr->colorQuant[2][i] = (int)(fb * 255.99); - } - } - - ckfree((char *) colors); -} - -/* - *---------------------------------------------------------------------- - * - * DisposeColorTable -- - * - * Release a color table and its associated resources. - * - * Results: - * None. - * - * Side effects: - * The colors in the argument color table are freed, as is the color - * table structure itself. The color table is removed from the hash table - * which is used to locate color tables. - * - *---------------------------------------------------------------------- - */ - -static void -DisposeColorTable( - ClientData clientData) /* Pointer to the ColorTable whose - * colors are to be released. */ -{ - ColorTable *colorPtr = (ColorTable *) clientData; - Tcl_HashEntry *entry; - - if (colorPtr->pixelMap != NULL) { - if (colorPtr->numColors > 0) { - XFreeColors(colorPtr->id.display, colorPtr->id.colormap, - colorPtr->pixelMap, colorPtr->numColors, 0); - Tk_FreeColormap(colorPtr->id.display, colorPtr->id.colormap); - } - ckfree((char *) colorPtr->pixelMap); - } - - entry = Tcl_FindHashEntry(&imgPhotoColorHash, (char *) &colorPtr->id); - if (entry == NULL) { - Tcl_Panic("DisposeColorTable couldn't find hash entry"); - } - Tcl_DeleteHashEntry(entry); - - ckfree((char *) colorPtr); -} - -/* - *---------------------------------------------------------------------- - * - * ReclaimColors -- - * - * This function is called to try to free up colors in the colormap used - * by a color table. It looks for other color tables with the same - * colormap and with a zero live reference count, and frees their colors. - * It only does so if there is the possibility of freeing up at least - * `numColors' colors. - * - * Results: - * The return value is TRUE if any colors were freed, FALSE otherwise. - * - * Side effects: - * ColorTables which are not currently in use may lose their color - * allocations. - * - *---------------------------------------------------------------------- - */ - -static int -ReclaimColors( - ColorTableId *id, /* Pointer to information identifying - * the color table which needs more colors. */ - int numColors) /* Number of colors required. */ -{ - Tcl_HashSearch srch; - Tcl_HashEntry *entry; - ColorTable *colorPtr; - int nAvail = 0; - - /* - * First scan through the color hash table to get an upper bound on how - * many colors we might be able to free. - */ - - entry = Tcl_FirstHashEntry(&imgPhotoColorHash, &srch); - while (entry != NULL) { - colorPtr = (ColorTable *) Tcl_GetHashValue(entry); - if ((colorPtr->id.display == id->display) - && (colorPtr->id.colormap == id->colormap) - && (colorPtr->liveRefCount == 0 )&& (colorPtr->numColors != 0) - && ((colorPtr->id.palette != id->palette) - || (colorPtr->id.gamma != id->gamma))) { - /* - * We could take this guy's colors off him. - */ - - nAvail += colorPtr->numColors; - } - entry = Tcl_NextHashEntry(&srch); - } - - /* - * nAvail is an (over)estimate of the number of colors we could free. - */ - - if (nAvail < numColors) { - return 0; - } - - /* - * Scan through a second time freeing colors. - */ - - entry = Tcl_FirstHashEntry(&imgPhotoColorHash, &srch); - while ((entry != NULL) && (numColors > 0)) { - colorPtr = (ColorTable *) Tcl_GetHashValue(entry); - if ((colorPtr->id.display == id->display) - && (colorPtr->id.colormap == id->colormap) - && (colorPtr->liveRefCount == 0) && (colorPtr->numColors != 0) - && ((colorPtr->id.palette != id->palette) - || (colorPtr->id.gamma != id->gamma))) { - /* - * Free the colors that this ColorTable has. - */ - - XFreeColors(colorPtr->id.display, colorPtr->id.colormap, - colorPtr->pixelMap, colorPtr->numColors, 0); - numColors -= colorPtr->numColors; - colorPtr->numColors = 0; - ckfree((char *) colorPtr->pixelMap); - colorPtr->pixelMap = NULL; - } - - entry = Tcl_NextHashEntry(&srch); - } - return 1; /* We freed some colors. */ -} - -/* - *---------------------------------------------------------------------- - * - * DisposeInstance -- - * - * This function is called to finally free up an instance of a photo - * image which is no longer required. - * - * Results: - * None. - * - * Side effects: - * The instance data structure and the resources it references are freed. - * - *---------------------------------------------------------------------- - */ - -static void -DisposeInstance( - ClientData clientData) /* Pointer to the instance whose resources are - * to be released. */ -{ - PhotoInstance *instancePtr = (PhotoInstance *) clientData; - PhotoInstance *prevPtr; - - if (instancePtr->pixels != None) { - Tk_FreePixmap(instancePtr->display, instancePtr->pixels); - } - if (instancePtr->gc != NULL) { - Tk_FreeGC(instancePtr->display, instancePtr->gc); - } - if (instancePtr->imagePtr != NULL) { - XDestroyImage(instancePtr->imagePtr); - } - if (instancePtr->error != NULL) { - ckfree((char *) instancePtr->error); - } - if (instancePtr->colorTablePtr != NULL) { - FreeColorTable(instancePtr->colorTablePtr, 1); - } - - if (instancePtr->masterPtr->instancePtr == instancePtr) { - instancePtr->masterPtr->instancePtr = instancePtr->nextPtr; - } else { - for (prevPtr = instancePtr->masterPtr->instancePtr; - prevPtr->nextPtr != instancePtr; prevPtr = prevPtr->nextPtr) { - /* Empty loop body. */ - } - prevPtr->nextPtr = instancePtr->nextPtr; - } - Tk_FreeColormap(instancePtr->display, instancePtr->colormap); - ckfree((char *) instancePtr); -} - -/* - *---------------------------------------------------------------------- - * * MatchFileFormat -- * * This function is called to find a photo image file format handler @@ -4050,7 +2413,7 @@ static int MatchFileFormat( Tcl_Interp *interp, /* Interpreter to use for reporting errors. */ Tcl_Channel chan, /* The image file, open for reading. */ - char *fileName, /* The name of the image file. */ + const char *fileName, /* The name of the image file. */ Tcl_Obj *formatObj, /* User-specified format string, or NULL. */ Tk_PhotoImageFormat **imageFormatPtr, /* A pointer to the photo image format record @@ -4062,9 +2425,9 @@ MatchFileFormat( { int matched = 0, useoldformat = 0; Tk_PhotoImageFormat *formatPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - char *formatString = NULL; + const char *formatString = NULL; if (formatObj) { formatString = Tcl_GetString(formatObj); @@ -4084,15 +2447,18 @@ MatchFileFormat( } matched = 1; if (formatPtr->fileMatchProc == NULL) { - Tcl_AppendResult(interp, "-file option isn't supported for ", - formatString, " images", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "-file option isn't supported for %s images", + formatString)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", + "NOT_FILE_FORMAT", NULL); return TCL_ERROR; } } if (formatPtr->fileMatchProc != NULL) { (void) Tcl_Seek(chan, Tcl_LongAsWide(0L), SEEK_SET); - if ((*formatPtr->fileMatchProc)(chan, fileName, formatObj, + if (formatPtr->fileMatchProc(chan, fileName, formatObj, widthPtr, heightPtr, interp)) { if (*widthPtr < 1) { *widthPtr = 1; @@ -4115,14 +2481,17 @@ MatchFileFormat( } matched = 1; if (formatPtr->fileMatchProc == NULL) { - Tcl_AppendResult(interp, "-file option isn't supported", - " for ", formatString, " images", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "-file option isn't supported for %s images", + formatString)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", + "NOT_FILE_FORMAT", NULL); return TCL_ERROR; } } if (formatPtr->fileMatchProc != NULL) { (void) Tcl_Seek(chan, Tcl_LongAsWide(0L), SEEK_SET); - if ((*formatPtr->fileMatchProc)(chan, fileName, (Tcl_Obj *) + if (formatPtr->fileMatchProc(chan, fileName, (Tcl_Obj *) formatString, widthPtr, heightPtr, interp)) { if (*widthPtr < 1) { *widthPtr = 1; @@ -4138,12 +2507,17 @@ MatchFileFormat( if (formatPtr == NULL) { if ((formatObj != NULL) && !matched) { - Tcl_AppendResult(interp, "image file format \"", formatString, - "\" is not supported", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "image file format \"%s\" is not supported", + formatString)); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO_FORMAT", + formatString, NULL); } else { - Tcl_AppendResult(interp, - "couldn't recognize data in image file \"", fileName, "\"", - NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "couldn't recognize data in image file \"%s\"", + fileName)); + Tcl_SetErrorCode(interp, "TK", "PHOTO", "IMAGE", + "UNRECOGNIZED_DATA", NULL); } return TCL_ERROR; } @@ -4191,9 +2565,9 @@ MatchStringFormat( { int matched = 0, useoldformat = 0; Tk_PhotoImageFormat *formatPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - char *formatString = NULL; + const char *formatString = NULL; if (formatObj) { formatString = Tcl_GetString(formatObj); @@ -4213,15 +2587,18 @@ MatchStringFormat( } matched = 1; if (formatPtr->stringMatchProc == NULL) { - Tcl_AppendResult(interp, "-data option isn't supported for ", - formatString, " images", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "-data option isn't supported for %s images", + formatString)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", + "NOT_DATA_FORMAT", NULL); return TCL_ERROR; } } if ((formatPtr->stringMatchProc != NULL) && (formatPtr->stringReadProc != NULL) - && (*formatPtr->stringMatchProc)(data, formatObj, - widthPtr, heightPtr, interp)) { + && formatPtr->stringMatchProc(data, formatObj, + widthPtr, heightPtr, interp)) { break; } } @@ -4237,14 +2614,17 @@ MatchStringFormat( } matched = 1; if (formatPtr->stringMatchProc == NULL) { - Tcl_AppendResult(interp, "-data option isn't supported", - " for ", formatString, " images", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "-data option isn't supported for %s images", + formatString)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", + "NOT_DATA_FORMAT", NULL); return TCL_ERROR; } } if ((formatPtr->stringMatchProc != NULL) && (formatPtr->stringReadProc != NULL) - && (*formatPtr->stringMatchProc)( + && formatPtr->stringMatchProc( (Tcl_Obj *) Tcl_GetString(data), (Tcl_Obj *) formatString, widthPtr, heightPtr, interp)) { @@ -4254,10 +2634,15 @@ MatchStringFormat( } if (formatPtr == NULL) { if ((formatObj != NULL) && !matched) { - Tcl_AppendResult(interp, "image format \"", formatString, - "\" is not supported", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "image format \"%s\" is not supported", formatString)); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO_FORMAT", + formatString, NULL); } else { - Tcl_AppendResult(interp, "couldn't recognize image data", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "couldn't recognize image data", -1)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", + "UNRECOGNIZED_DATA", NULL); } return TCL_ERROR; } @@ -4291,16 +2676,16 @@ Tk_PhotoHandle Tk_FindPhoto( Tcl_Interp *interp, /* Interpreter (application) in which image * exists. */ - CONST char *imageName) /* Name of the desired photo image. */ + const char *imageName) /* Name of the desired photo image. */ { - ClientData clientData; - Tk_ImageType *typePtr; + const Tk_ImageType *typePtr; + ClientData clientData = + Tk_GetImageMasterData(interp, imageName, &typePtr); - clientData = Tk_GetImageMasterData(interp, imageName, &typePtr); if ((typePtr == NULL) || (typePtr->name != tkPhotoImageType.name)) { return NULL; } - return (Tk_PhotoHandle) clientData; + return clientData; } /* @@ -4328,7 +2713,7 @@ Tk_PhotoPutBlock( * messages, or NULL. */ Tk_PhotoHandle handle, /* Opaque handle for the photo image to be * updated. */ - register Tk_PhotoImageBlock *blockPtr, + Tk_PhotoImageBlock *blockPtr, /* Pointer to a structure describing the pixel * data to be copied into the image. */ int x, int y, /* Coordinates of the top-left pixel to be @@ -4338,14 +2723,23 @@ Tk_PhotoPutBlock( int compRule) /* Compositing rule to use when processing * transparent pixels. */ { - register PhotoMaster *masterPtr; + register PhotoMaster *masterPtr = (PhotoMaster *) handle; + Tk_PhotoImageBlock sourceBlock; + unsigned char *memToFree; int xEnd, yEnd, greenOffset, blueOffset, alphaOffset; int wLeft, hLeft, wCopy, hCopy, pitch; unsigned char *srcPtr, *srcLinePtr, *destPtr, *destLinePtr; int sourceIsSimplePhoto = compRule & SOURCE_IS_SIMPLE_ALPHA_PHOTO; XRectangle rect; - masterPtr = (PhotoMaster *) handle; + /* + * Zero-sized blocks never cause any changes. [Bug 3078902] + */ + + if (blockPtr->height == 0 || blockPtr->width == 0) { + return TCL_OK; + } + compRule &= ~SOURCE_IS_SIMPLE_ALPHA_PHOTO; if ((masterPtr->userWidth != 0) && ((x + width) > masterPtr->userWidth)) { @@ -4359,22 +2753,51 @@ Tk_PhotoPutBlock( return TCL_OK; } + /* + * Fix for bug e4336bef5d: + * + * Make a local copy of *blockPtr, as we might have to change some + * of its fields and don't want to interfere with the caller's data. + * + * If source and destination are the same image, create a copy of the + * source data in our local sourceBlock. + * + * To find out, just comparing the pointers is not enough - they might have + * different values and still point to the same block of memory. (e.g. + * if the -from option was passed to [imageName copy]) + */ + sourceBlock = *blockPtr; + memToFree = NULL; + if (sourceBlock.pixelPtr >= masterPtr->pix32 + && sourceBlock.pixelPtr <= masterPtr->pix32 + masterPtr->width + * masterPtr->height * 4) { + sourceBlock.pixelPtr = attemptckalloc(sourceBlock.height + * sourceBlock.pitch); + if (sourceBlock.pixelPtr == NULL) { + if (interp != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1)); + Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL); + } + return TCL_ERROR; + } + memToFree = sourceBlock.pixelPtr; + memcpy(sourceBlock.pixelPtr, blockPtr->pixelPtr, sourceBlock.height + * sourceBlock.pitch); + } + + xEnd = x + width; yEnd = y + height; if ((xEnd > masterPtr->width) || (yEnd > masterPtr->height)) { - int sameSrc = (blockPtr->pixelPtr == masterPtr->pix32); - if (ImgPhotoSetSize(masterPtr, MAX(xEnd, masterPtr->width), MAX(yEnd, masterPtr->height)) == TCL_ERROR) { if (interp != NULL) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, TK_PHOTO_ALLOC_FAILURE_MESSAGE, NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1)); + Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL); } - return TCL_ERROR; - } - if (sameSrc) { - blockPtr->pixelPtr = masterPtr->pix32; - blockPtr->pitch = masterPtr->width * 4; + goto errorExit; } } @@ -4393,14 +2816,14 @@ Tk_PhotoPutBlock( * components, mark it as a color image. */ - greenOffset = blockPtr->offset[1] - blockPtr->offset[0]; - blueOffset = blockPtr->offset[2] - blockPtr->offset[0]; - alphaOffset = blockPtr->offset[3]; - if ((alphaOffset >= blockPtr->pixelSize) || (alphaOffset < 0)) { + greenOffset = sourceBlock.offset[1] - sourceBlock.offset[0]; + blueOffset = sourceBlock.offset[2] - sourceBlock.offset[0]; + alphaOffset = sourceBlock.offset[3]; + if ((alphaOffset >= sourceBlock.pixelSize) || (alphaOffset < 0)) { alphaOffset = 0; sourceIsSimplePhoto = 1; } else { - alphaOffset -= blockPtr->offset[0]; + alphaOffset -= sourceBlock.offset[0]; } if ((greenOffset != 0) || (blueOffset != 0)) { masterPtr->flags |= COLOR_IMAGE; @@ -4420,14 +2843,14 @@ Tk_PhotoPutBlock( * pixelSize == 3 and alphaOffset == 0. Maybe other cases too. */ - if ((blockPtr->pixelSize == 4) + if ((sourceBlock.pixelSize == 4) && (greenOffset == 1) && (blueOffset == 2) && (alphaOffset == 3) - && (width <= blockPtr->width) && (height <= blockPtr->height) + && (width <= sourceBlock.width) && (height <= sourceBlock.height) && ((height == 1) || ((x == 0) && (width == masterPtr->width) - && (blockPtr->pitch == pitch))) + && (sourceBlock.pitch == pitch))) && (compRule == TK_PHOTO_COMPOSITE_SET)) { - memmove(destLinePtr, blockPtr->pixelPtr + blockPtr->offset[0], - ((size_t) height * width * 4)); + memmove(destLinePtr, sourceBlock.pixelPtr + sourceBlock.offset[0], + ((size_t)height * width * 4)); /* * We know there's an alpha offset and we're setting the data, so skip @@ -4442,11 +2865,11 @@ Tk_PhotoPutBlock( */ for (hLeft = height; hLeft > 0;) { - int pixelSize = blockPtr->pixelSize; + int pixelSize = sourceBlock.pixelSize; int compRuleSet = (compRule == TK_PHOTO_COMPOSITE_SET); - srcLinePtr = blockPtr->pixelPtr + blockPtr->offset[0]; - hCopy = MIN(hLeft, blockPtr->height); + srcLinePtr = sourceBlock.pixelPtr + sourceBlock.offset[0]; + hCopy = MIN(hLeft, sourceBlock.height); hLeft -= hCopy; for (; hCopy > 0; --hCopy) { /* @@ -4457,10 +2880,10 @@ Tk_PhotoPutBlock( if ((pixelSize == 4) && (greenOffset == 1) && (blueOffset == 2) && (alphaOffset == 3) - && (width <= blockPtr->width) + && (width <= sourceBlock.width) && compRuleSet) { - memcpy(destLinePtr, srcLinePtr, ((size_t) width * 4)); - srcLinePtr += blockPtr->pitch; + memcpy(destLinePtr, srcLinePtr, ((size_t)width * 4)); + srcLinePtr += sourceBlock.pitch; destLinePtr += pitch; continue; } @@ -4471,7 +2894,7 @@ Tk_PhotoPutBlock( destPtr = destLinePtr; for (wLeft = width; wLeft > 0;) { - wCopy = MIN(wLeft, blockPtr->width); + wCopy = MIN(wLeft, sourceBlock.width); wLeft -= wCopy; srcPtr = srcLinePtr; @@ -4561,7 +2984,7 @@ Tk_PhotoPutBlock( destPtr += 4; } } - srcLinePtr += blockPtr->pitch; + srcLinePtr += sourceBlock.pitch; destLinePtr += pitch; } } @@ -4632,27 +3055,32 @@ Tk_PhotoPutBlock( * Check if display code needs alpha blending... */ - if (!sourceIsSimplePhoto && (width == 1) && (height == 1)) { + if (!sourceIsSimplePhoto && (height == 1)) { /* - * Optimize the single pixel case if we can. This speeds up code that - * builds up large simple-alpha images by single pixels. We don't - * negate COMPLEX_ALPHA in this case. [Bug 1409140] + * Optimize the single span case if we can. This speeds up code that + * builds up large simple-alpha images by scan-lines or individual + * pixels. We don't negate COMPLEX_ALPHA in this case. [Bug 1409140] + * [Patch 1539990] */ if (!(masterPtr->flags & COMPLEX_ALPHA)) { - unsigned char newAlpha; + register int x1; - destLinePtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4; - newAlpha = destLinePtr[3]; + for (x1=x ; x1<x+width ; x1++) { + register unsigned char newAlpha; - if (newAlpha && newAlpha != 255) { - masterPtr->flags |= COMPLEX_ALPHA; + destLinePtr = masterPtr->pix32 + (y*masterPtr->width + x1)*4; + newAlpha = destLinePtr[3]; + if (newAlpha && newAlpha != 255) { + masterPtr->flags |= COMPLEX_ALPHA; + break; + } } } } else if ((alphaOffset != 0) || (masterPtr->flags & COMPLEX_ALPHA)) { /* * Check for partial transparency if alpha pixels are specified, or - * rescan if we already knew such pixels existed. To restrict this + * rescan if we already knew such pixels existed. To restrict this * Toggle to only checking the changed pixels requires knowing where * the alpha pixels are. */ @@ -4672,7 +3100,15 @@ Tk_PhotoPutBlock( Tk_ImageChanged(masterPtr->tkMaster, x, y, width, height, masterPtr->width, masterPtr->height); + + if (memToFree) ckfree(memToFree); + return TCL_OK; + + errorExit: + if (memToFree) ckfree(memToFree); + + return TCL_ERROR; } /* @@ -4699,7 +3135,7 @@ Tk_PhotoPutZoomedBlock( * messages, or NULL. */ Tk_PhotoHandle handle, /* Opaque handle for the photo image to be * updated. */ - register Tk_PhotoImageBlock *blockPtr, + Tk_PhotoImageBlock *blockPtr, /* Pointer to a structure describing the pixel * data to be copied into the image. */ int x, int y, /* Coordinates of the top-left pixel to be @@ -4714,12 +3150,22 @@ Tk_PhotoPutZoomedBlock( * transparent pixels. */ { register PhotoMaster *masterPtr = (PhotoMaster *) handle; + register Tk_PhotoImageBlock sourceBlock; + unsigned char *memToFree; int xEnd, yEnd, greenOffset, blueOffset, alphaOffset; int wLeft, hLeft, wCopy, hCopy, blockWid, blockHt; unsigned char *srcPtr, *srcLinePtr, *srcOrigPtr, *destPtr, *destLinePtr; int pitch, xRepeat, yRepeat, blockXSkip, blockYSkip, sourceIsSimplePhoto; XRectangle rect; + /* + * Zero-sized blocks never cause any changes. [Bug 3078902] + */ + + if (blockPtr->height == 0 || blockPtr->width == 0) { + return TCL_OK; + } + if (zoomX==1 && zoomY==1 && subsampleX==1 && subsampleY==1) { return Tk_PhotoPutBlock(interp, handle, blockPtr, x, y, width, height, compRule); @@ -4742,26 +3188,54 @@ Tk_PhotoPutZoomedBlock( return TCL_OK; } + /* + * Fix for Bug e4336bef5d: + * Make a local copy of *blockPtr, as we might have to change some + * of its fields and don't want to interfere with the caller's data. + * + * If source and destination are the same image, create a copy of the + * source data in our local sourceBlock. + * + * To find out, just comparing the pointers is not enough - they might have + * different values and still point to the same block of memory. (e.g. + * if the -from option was passed to [imageName copy]) + */ + sourceBlock = *blockPtr; + memToFree = NULL; + if (sourceBlock.pixelPtr >= masterPtr->pix32 + && sourceBlock.pixelPtr <= masterPtr->pix32 + masterPtr->width + * masterPtr->height * 4) { + sourceBlock.pixelPtr = attemptckalloc(sourceBlock.height + * sourceBlock.pitch); + if (sourceBlock.pixelPtr == NULL) { + if (interp != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1)); + Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL); + } + return TCL_ERROR; + } + memToFree = sourceBlock.pixelPtr; + memcpy(sourceBlock.pixelPtr, blockPtr->pixelPtr, sourceBlock.height + * sourceBlock.pitch); + } + xEnd = x + width; yEnd = y + height; if ((xEnd > masterPtr->width) || (yEnd > masterPtr->height)) { - int sameSrc = (blockPtr->pixelPtr == masterPtr->pix32); if (ImgPhotoSetSize(masterPtr, MAX(xEnd, masterPtr->width), MAX(yEnd, masterPtr->height)) == TCL_ERROR) { if (interp != NULL) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, TK_PHOTO_ALLOC_FAILURE_MESSAGE, NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1)); + Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL); } - return TCL_ERROR; - } - if (sameSrc) { - blockPtr->pixelPtr = masterPtr->pix32; - blockPtr->pitch = masterPtr->width * 4; + goto errorExit; } } if ((y < masterPtr->ditherY) || ((y == masterPtr->ditherY) - && (x < masterPtr->ditherX))) { + && (x < masterPtr->ditherX))) { /* * The dithering isn't correct past the start of this block. */ @@ -4775,14 +3249,14 @@ Tk_PhotoPutZoomedBlock( * components, mark it as a color image. */ - greenOffset = blockPtr->offset[1] - blockPtr->offset[0]; - blueOffset = blockPtr->offset[2] - blockPtr->offset[0]; - alphaOffset = blockPtr->offset[3]; - if ((alphaOffset >= blockPtr->pixelSize) || (alphaOffset < 0)) { + greenOffset = sourceBlock.offset[1] - sourceBlock.offset[0]; + blueOffset = sourceBlock.offset[2] - sourceBlock.offset[0]; + alphaOffset = sourceBlock.offset[3]; + if ((alphaOffset >= sourceBlock.pixelSize) || (alphaOffset < 0)) { alphaOffset = 0; sourceIsSimplePhoto = 1; } else { - alphaOffset -= blockPtr->offset[0]; + alphaOffset -= sourceBlock.offset[0]; } if ((greenOffset != 0) || (blueOffset != 0)) { masterPtr->flags |= COLOR_IMAGE; @@ -4793,21 +3267,21 @@ Tk_PhotoPutZoomedBlock( * subsampling and zooming. */ - blockXSkip = subsampleX * blockPtr->pixelSize; - blockYSkip = subsampleY * blockPtr->pitch; + blockXSkip = subsampleX * sourceBlock.pixelSize; + blockYSkip = subsampleY * sourceBlock.pitch; if (subsampleX > 0) { - blockWid = ((blockPtr->width + subsampleX - 1) / subsampleX) * zoomX; + blockWid = ((sourceBlock.width + subsampleX - 1) / subsampleX) * zoomX; } else if (subsampleX == 0) { blockWid = width; } else { - blockWid = ((blockPtr->width - subsampleX - 1) / -subsampleX) * zoomX; + blockWid = ((sourceBlock.width - subsampleX - 1) / -subsampleX) * zoomX; } if (subsampleY > 0) { - blockHt = ((blockPtr->height + subsampleY - 1) / subsampleY) * zoomY; + blockHt = ((sourceBlock.height + subsampleY - 1) / subsampleY) * zoomY; } else if (subsampleY == 0) { blockHt = height; } else { - blockHt = ((blockPtr->height - subsampleY - 1) / -subsampleY) * zoomY; + blockHt = ((sourceBlock.height - subsampleY - 1) / -subsampleY) * zoomY; } /* @@ -4815,12 +3289,12 @@ Tk_PhotoPutZoomedBlock( */ destLinePtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4; - srcOrigPtr = blockPtr->pixelPtr + blockPtr->offset[0]; + srcOrigPtr = sourceBlock.pixelPtr + sourceBlock.offset[0]; if (subsampleX < 0) { - srcOrigPtr += (blockPtr->width - 1) * blockPtr->pixelSize; + srcOrigPtr += (sourceBlock.width - 1) * sourceBlock.pixelSize; } if (subsampleY < 0) { - srcOrigPtr += (blockPtr->height - 1) * blockPtr->pitch; + srcOrigPtr += (sourceBlock.height - 1) * sourceBlock.pitch; } pitch = masterPtr->width * 4; @@ -4935,7 +3409,7 @@ Tk_PhotoPutZoomedBlock( if (!sourceIsSimplePhoto && (width == 1) && (height == 1)) { /* * Optimize the single pixel case if we can. This speeds up code that - * builds up large simple-alpha images by single pixels. We don't + * builds up large simple-alpha images by single pixels. We don't * negate COMPLEX_ALPHA in this case. [Bug 1409140] */ if (!(masterPtr->flags & COMPLEX_ALPHA)) { @@ -4951,7 +3425,7 @@ Tk_PhotoPutZoomedBlock( } else if ((alphaOffset != 0) || (masterPtr->flags & COMPLEX_ALPHA)) { /* * Check for partial transparency if alpha pixels are specified, or - * rescan if we already knew such pixels existed. To restrict this + * rescan if we already knew such pixels existed. To restrict this * Toggle to only checking the changed pixels requires knowing where * the alpha pixels are. */ @@ -4970,7 +3444,15 @@ Tk_PhotoPutZoomedBlock( Tk_ImageChanged(masterPtr->tkMaster, x, y, width, height, masterPtr->width, masterPtr->height); + + if (memToFree) ckfree(memToFree); + return TCL_OK; + + errorExit: + if (memToFree) ckfree(memToFree); + + return TCL_ERROR; } /* @@ -5009,7 +3491,7 @@ Tk_DitherPhoto( for (instancePtr = masterPtr->instancePtr; instancePtr != NULL; instancePtr = instancePtr->nextPtr) { - DitherInstance(instancePtr, x, y, width, height); + TkImgDitherInstance(instancePtr, x, y, width, height); } /* @@ -5055,345 +3537,6 @@ Tk_DitherPhoto( /* *---------------------------------------------------------------------- * - * DitherInstance -- - * - * This function is called to update an area of an instance's pixmap by - * dithering the corresponding area of the master. - * - * Results: - * None. - * - * Side effects: - * The instance's pixmap gets updated. - * - *---------------------------------------------------------------------- - */ - -static void -DitherInstance( - PhotoInstance *instancePtr, /* The instance to be updated. */ - int xStart, int yStart, /* Coordinates of the top-left pixel in the - * block to be dithered. */ - int width, int height) /* Dimensions of the block to be dithered. */ -{ - PhotoMaster *masterPtr = instancePtr->masterPtr; - ColorTable *colorPtr = instancePtr->colorTablePtr; - XImage *imagePtr; - int nLines, bigEndian, i, c, x, y, xEnd, doDithering = 1; - int bitsPerPixel, bytesPerLine, lineLength; - unsigned char *srcLinePtr; - schar *errLinePtr; - pixel firstBit, word, mask; - - /* - * Turn dithering off in certain cases where it is not needed (TrueColor, - * DirectColor with many colors). - */ - - if ((colorPtr->visualInfo.class == DirectColor) - || (colorPtr->visualInfo.class == TrueColor)) { - int nRed, nGreen, nBlue, result; - - result = sscanf(colorPtr->id.palette, "%d/%d/%d", &nRed, - &nGreen, &nBlue); - if ((nRed >= 256) - && ((result == 1) || ((nGreen >= 256) && (nBlue >= 256)))) { - doDithering = 0; - } - } - - /* - * First work out how many lines to do at a time, then how many bytes - * we'll need for pixel storage, and allocate it. - */ - - nLines = (MAX_PIXELS + width - 1) / width; - if (nLines < 1) { - nLines = 1; - } - if (nLines > height ) { - nLines = height; - } - - imagePtr = instancePtr->imagePtr; - if (imagePtr == NULL) { - return; /* We must be really tight on memory. */ - } - bitsPerPixel = imagePtr->bits_per_pixel; - bytesPerLine = ((bitsPerPixel * width + 31) >> 3) & ~3; - imagePtr->width = width; - imagePtr->height = nLines; - imagePtr->bytes_per_line = bytesPerLine; - imagePtr->data = (char *) - ckalloc((unsigned) (imagePtr->bytes_per_line * nLines)); - bigEndian = imagePtr->bitmap_bit_order == MSBFirst; - firstBit = bigEndian? (1 << (imagePtr->bitmap_unit - 1)): 1; - - lineLength = masterPtr->width * 3; - srcLinePtr = masterPtr->pix32 + (yStart * masterPtr->width + xStart) * 4; - errLinePtr = instancePtr->error + yStart * lineLength + xStart * 3; - xEnd = xStart + width; - - /* - * Loop over the image, doing at most nLines lines before updating the - * screen image. - */ - - for (; height > 0; height -= nLines) { - unsigned char *dstLinePtr = (unsigned char *) imagePtr->data; - int yEnd; - - if (nLines > height) { - nLines = height; - } - yEnd = yStart + nLines; - for (y = yStart; y < yEnd; ++y) { - unsigned char *srcPtr = srcLinePtr; - schar *errPtr = errLinePtr; - unsigned char *destBytePtr = dstLinePtr; - pixel *destLongPtr = (pixel *) dstLinePtr; - - if (colorPtr->flags & COLOR_WINDOW) { - /* - * Color window. We dither the three components independently, - * using Floyd-Steinberg dithering, which propagates errors - * from the quantization of pixels to the pixels below and to - * the right. - */ - - for (x = xStart; x < xEnd; ++x) { - int col[3]; - - if (doDithering) { - for (i = 0; i < 3; ++i) { - /* - * Compute the error propagated into this pixel - * for this component. If e[x,y] is the array of - * quantization error values, we compute - * 7/16 * e[x-1,y] + 1/16 * e[x-1,y-1] - * + 5/16 * e[x,y-1] + 3/16 * e[x+1,y-1] - * and round it to an integer. - * - * The expression ((c + 2056) >> 4) - 128 computes - * round(c / 16), and works correctly on machines - * without a sign-extending right shift. - */ - - c = (x > 0) ? errPtr[-3] * 7: 0; - if (y > 0) { - if (x > 0) { - c += errPtr[-lineLength-3]; - } - c += errPtr[-lineLength] * 5; - if ((x + 1) < masterPtr->width) { - c += errPtr[-lineLength+3] * 3; - } - } - - /* - * Add the propagated error to the value of this - * component, quantize it, and store the - * quantization error. - */ - - c = ((c + 2056) >> 4) - 128 + *srcPtr++; - if (c < 0) { - c = 0; - } else if (c > 255) { - c = 255; - } - col[i] = colorPtr->colorQuant[i][c]; - *errPtr++ = c - col[i]; - } - } else { - /* - * Output is virtually continuous in this case, so - * don't bother dithering. - */ - - col[0] = *srcPtr++; - col[1] = *srcPtr++; - col[2] = *srcPtr++; - } - srcPtr++; - - /* - * Translate the quantized component values into an X - * pixel value, and store it in the image. - */ - - i = colorPtr->redValues[col[0]] - + colorPtr->greenValues[col[1]] - + colorPtr->blueValues[col[2]]; - if (colorPtr->flags & MAP_COLORS) { - i = colorPtr->pixelMap[i]; - } - switch (bitsPerPixel) { - case NBBY: - *destBytePtr++ = i; - break; -#ifndef __WIN32__ - /* - * This case is not valid for Windows because the - * image format is different from the pixel format in - * Win32. Eventually we need to fix the image code in - * Tk to use the Windows native image ordering. This - * would speed up the image code for all of the common - * sizes. - */ - - case NBBY * sizeof(pixel): - *destLongPtr++ = i; - break; -#endif - default: - XPutPixel(imagePtr, x - xStart, y - yStart, - (unsigned) i); - } - } - - } else if (bitsPerPixel > 1) { - /* - * Multibit monochrome window. The operation here is similar - * to the color window case above, except that there is only - * one component. If the master image is in color, use the - * luminance computed as - * 0.344 * red + 0.5 * green + 0.156 * blue. - */ - - for (x = xStart; x < xEnd; ++x) { - c = (x > 0) ? errPtr[-1] * 7: 0; - if (y > 0) { - if (x > 0) { - c += errPtr[-lineLength-1]; - } - c += errPtr[-lineLength] * 5; - if (x + 1 < masterPtr->width) { - c += errPtr[-lineLength+1] * 3; - } - } - c = ((c + 2056) >> 4) - 128; - - if ((masterPtr->flags & COLOR_IMAGE) == 0) { - c += srcPtr[0]; - } else { - c += (unsigned)(srcPtr[0] * 11 + srcPtr[1] * 16 - + srcPtr[2] * 5 + 16) >> 5; - } - srcPtr += 4; - - if (c < 0) { - c = 0; - } else if (c > 255) { - c = 255; - } - i = colorPtr->colorQuant[0][c]; - *errPtr++ = c - i; - i = colorPtr->redValues[i]; - switch (bitsPerPixel) { - case NBBY: - *destBytePtr++ = i; - break; -#ifndef __WIN32__ - /* - * This case is not valid for Windows because the - * image format is different from the pixel format in - * Win32. Eventually we need to fix the image code in - * Tk to use the Windows native image ordering. This - * would speed up the image code for all of the common - * sizes. - */ - - case NBBY * sizeof(pixel): - *destLongPtr++ = i; - break; -#endif - default: - XPutPixel(imagePtr, x - xStart, y - yStart, - (unsigned) i); - } - } - } else { - /* - * 1-bit monochrome window. This is similar to the multibit - * monochrome case above, except that the quantization is - * simpler (we only have black = 0 and white = 255), and we - * produce an XY-Bitmap. - */ - - word = 0; - mask = firstBit; - for (x = xStart; x < xEnd; ++x) { - /* - * If we have accumulated a whole word, store it in the - * image and start a new word. - */ - - if (mask == 0) { - *destLongPtr++ = word; - mask = firstBit; - word = 0; - } - - c = (x > 0) ? errPtr[-1] * 7: 0; - if (y > 0) { - if (x > 0) { - c += errPtr[-lineLength-1]; - } - c += errPtr[-lineLength] * 5; - if (x + 1 < masterPtr->width) { - c += errPtr[-lineLength+1] * 3; - } - } - c = ((c + 2056) >> 4) - 128; - - if ((masterPtr->flags & COLOR_IMAGE) == 0) { - c += srcPtr[0]; - } else { - c += (unsigned)(srcPtr[0] * 11 + srcPtr[1] * 16 - + srcPtr[2] * 5 + 16) >> 5; - } - srcPtr += 4; - - if (c < 0) { - c = 0; - } else if (c > 255) { - c = 255; - } - if (c >= 128) { - word |= mask; - *errPtr++ = c - 255; - } else { - *errPtr++ = c; - } - mask = bigEndian? (mask >> 1): (mask << 1); - } - *destLongPtr = word; - } - srcLinePtr += masterPtr->width * 4; - errLinePtr += lineLength; - dstLinePtr += bytesPerLine; - } - - /* - * Update the pixmap for this instance with the block of pixels that - * we have just computed. - */ - - TkPutImage(colorPtr->pixelMap, colorPtr->numColors, - instancePtr->display, instancePtr->pixels, - instancePtr->gc, imagePtr, 0, 0, xStart, yStart, - (unsigned) width, (unsigned) nLines); - yStart = yEnd; - } - - ckfree(imagePtr->data); - imagePtr->data = NULL; -} - -/* - *---------------------------------------------------------------------- - * * Tk_PhotoBlank -- * * This function is called to clear an entire photo image. @@ -5433,14 +3576,10 @@ Tk_PhotoBlank( */ memset(masterPtr->pix32, 0, - ((size_t) masterPtr->width * masterPtr->height * 4)); + ((size_t)masterPtr->width * masterPtr->height * 4)); for (instancePtr = masterPtr->instancePtr; instancePtr != NULL; instancePtr = instancePtr->nextPtr) { - if (instancePtr->error) { - memset(instancePtr->error, 0, - ((size_t) masterPtr->width * masterPtr->height - * 3 * sizeof(schar))); - } + TkImgResetDither(instancePtr); } /* @@ -5490,8 +3629,9 @@ Tk_PhotoExpand( if (ImgPhotoSetSize(masterPtr, MAX(width, masterPtr->width), MAX(height, masterPtr->height)) == TCL_ERROR) { if (interp != NULL) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, TK_PHOTO_ALLOC_FAILURE_MESSAGE, NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1)); + Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL); } return TCL_ERROR; } @@ -5564,8 +3704,9 @@ Tk_PhotoSetSize( if (ImgPhotoSetSize(masterPtr, ((width > 0) ? width: masterPtr->width), ((height > 0) ? height: masterPtr->height)) == TCL_ERROR) { if (interp != NULL) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, TK_PHOTO_ALLOC_FAILURE_MESSAGE, NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1)); + Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL); } return TCL_ERROR; } @@ -5680,8 +3821,14 @@ ImgGetPhoto( if ((greenOffset||blueOffset) && !(optPtr->options & OPT_GRAYSCALE)) { newPixelSize += 2; } - data = ckalloc((unsigned int) (newPixelSize * - blockPtr->width * blockPtr->height)); + + if (blockPtr->height > (int)((UINT_MAX/newPixelSize)/blockPtr->width)) { + return NULL; + } + data = attemptckalloc(newPixelSize*blockPtr->width*blockPtr->height); + if (data == NULL) { + return NULL; + } srcPtr = blockPtr->pixelPtr + blockPtr->offset[0]; destPtr = (unsigned char *) data; if (!greenOffset && !blueOffset) { @@ -5776,13 +3923,13 @@ ImgGetPhoto( blockPtr->pixelSize = newPixelSize; blockPtr->pitch = newPixelSize * blockPtr->width; blockPtr->offset[0] = 0; - if (newPixelSize>2) { - blockPtr->offset[1]= 1; - blockPtr->offset[2]= 2; + if (newPixelSize > 2) { + blockPtr->offset[1] = 1; + blockPtr->offset[2] = 2; blockPtr->offset[3]= 3; } else { - blockPtr->offset[1]= 0; - blockPtr->offset[2]= 0; + blockPtr->offset[1] = 0; + blockPtr->offset[2] = 0; blockPtr->offset[3]= 1; } return data; @@ -5813,33 +3960,31 @@ ImgStringWrite( Tcl_Obj *formatString, Tk_PhotoImageBlock *blockPtr) { - int row, col; - char *line, *linePtr; - unsigned char *pixelPtr; int greenOffset, blueOffset; - Tcl_DString data; + Tcl_Obj *data; greenOffset = blockPtr->offset[1] - blockPtr->offset[0]; blueOffset = blockPtr->offset[2] - blockPtr->offset[0]; - Tcl_DStringInit(&data); + data = Tcl_NewObj(); if ((blockPtr->width > 0) && (blockPtr->height > 0)) { - line = (char *) ckalloc((unsigned int) ((8 * blockPtr->width) + 2)); + int row, col; + for (row=0; row<blockPtr->height; row++) { - pixelPtr = blockPtr->pixelPtr + blockPtr->offset[0] + - row * blockPtr->pitch; - linePtr = line; + Tcl_Obj *line = Tcl_NewObj(); + unsigned char *pixelPtr = blockPtr->pixelPtr + blockPtr->offset[0] + + row * blockPtr->pitch; + for (col=0; col<blockPtr->width; col++) { - sprintf(linePtr, " #%02x%02x%02x", *pixelPtr, + Tcl_AppendPrintfToObj(line, "%s#%02x%02x%02x", + col ? " " : "", *pixelPtr, pixelPtr[greenOffset], pixelPtr[blueOffset]); pixelPtr += blockPtr->pixelSize; - linePtr += 8; } - Tcl_DStringAppendElement(&data, line+1); + Tcl_ListObjAppendElement(NULL, data, line); } - ckfree (line); } - Tcl_DStringResult(interp, &data); + Tcl_SetObjResult(interp, data); return TCL_OK; } @@ -5886,150 +4031,6 @@ Tk_PhotoGetImage( } /* - *---------------------------------------------------------------------- - * - * PhotoOptionFind -- - * - * Finds a specific Photo option. - * - * Results: - * None. - * - * Side effects: - * After commands are removed. - * - *---------------------------------------------------------------------- - */ - -typedef struct OptionAssocData { - struct OptionAssocData *nextPtr; - /* Pointer to next OptionAssocData. */ - Tcl_ObjCmdProc *command; /* Command associated with this option. */ - char name[1]; /* Name of option (remaining chars) */ -} OptionAssocData; - -static Tcl_ObjCmdProc * -PhotoOptionFind( - Tcl_Interp *interp, /* Interpreter that is being deleted. */ - Tcl_Obj *obj) /* Name of option to be found. */ -{ - int length; - char *name = Tcl_GetStringFromObj(obj, &length); - char *prevname = NULL; - Tcl_ObjCmdProc *proc = NULL; - OptionAssocData *list = (OptionAssocData *) Tcl_GetAssocData(interp, - "photoOption", NULL); - - while (list != NULL) { - if (strncmp(name, list->name, (unsigned) length) == 0) { - if (proc != NULL) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "ambiguous option \"", name, - "\": must be ", prevname, NULL); - while (list->nextPtr != NULL) { - Tcl_AppendResult(interp, prevname, ", ",NULL); - list = list->nextPtr; - prevname = list->name; - } - Tcl_AppendResult(interp, ", or", prevname, NULL); - return NULL; - } - proc = list->command; - prevname = list->name; - } - list = list->nextPtr; - } - if (proc != NULL) { - Tcl_ResetResult(interp); - } - return proc; -} - -/* - *---------------------------------------------------------------------- - * - * PhotoOptionCleanupProc -- - * - * This function is invoked whenever an interpreter is deleted to cleanup - * the AssocData for "photoVisitor". - * - * Results: - * None. - * - * Side effects: - * Photo Visitor options are removed. - * - *---------------------------------------------------------------------- - */ - -static void -PhotoOptionCleanupProc( - ClientData clientData, /* Points to "photoVisitor" AssocData for the - * interpreter. */ - Tcl_Interp *interp) /* Interpreter that is being deleted. */ -{ - OptionAssocData *list = (OptionAssocData *) clientData; - - while (list != NULL) { - register OptionAssocData *ptr; - - list = (ptr = list)->nextPtr; - ckfree((char *) ptr); - } -} - -/* - *-------------------------------------------------------------- - * - * Tk_CreatePhotoOption -- - * - * This function may be invoked to add a new kind of photo option to the - * core photo command supported by Tk. - * - * Results: - * None. - * - * Side effects: - * From now on, the new option will be useable by the photo command. - * - *-------------------------------------------------------------- - */ - -MODULE_SCOPE void -Tk_CreatePhotoOption( - Tcl_Interp *interp, /* Interpreter. */ - CONST char *name, /* Option name. */ - Tcl_ObjCmdProc *proc) /* Function to execute command. */ -{ - OptionAssocData *typePtr2, *prevPtr, *ptr; - OptionAssocData *list = (OptionAssocData *) - Tcl_GetAssocData(interp, "photoOption", NULL); - - /* - * If there's already a photo option with the given name, remove it. - */ - - for (typePtr2 = list, prevPtr = NULL; typePtr2 != NULL; - prevPtr = typePtr2, typePtr2 = typePtr2->nextPtr) { - if (strcmp(typePtr2->name, name) == 0) { - if (prevPtr == NULL) { - list = typePtr2->nextPtr; - } else { - prevPtr->nextPtr = typePtr2->nextPtr; - } - ckfree((char *) typePtr2); - break; - } - } - ptr = (OptionAssocData *) ckalloc(sizeof(OptionAssocData) + strlen(name)); - strcpy(&(ptr->name[0]), name); - ptr->command = proc; - ptr->nextPtr = list; - Tcl_SetAssocData(interp, "photoOption", PhotoOptionCleanupProc, - (ClientData) ptr); -} - -/* *-------------------------------------------------------------- * * TkPostscriptPhoto -- @@ -6058,7 +4059,7 @@ ImgPhotoPostscript( { Tk_PhotoImageBlock block; - Tk_PhotoGetImage((Tk_PhotoHandle) clientData, &block); + Tk_PhotoGetImage(clientData, &block); block.pixelPtr += y * block.pitch + x * block.pixelSize; return Tk_PostscriptPhoto(interp, &block, psInfo, width, height); diff --git a/generic/tkImgPhoto.h b/generic/tkImgPhoto.h new file mode 100644 index 0000000..36bc6cb --- /dev/null +++ b/generic/tkImgPhoto.h @@ -0,0 +1,262 @@ +/* + * tkImgPhoto.h -- + * + * Declarations for images of type "photo" for Tk. + * + * Copyright (c) 1994 The Australian National University. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. + * Copyright (c) 2002-2008 Donal K. Fellows + * Copyright (c) 2003 ActiveState Corporation. + * + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * Author: Paul Mackerras (paulus@cs.anu.edu.au), + * Department of Computer Science, + * Australian National University. + */ + +#include "tkInt.h" +#ifdef _WIN32 +#include "tkWinInt.h" +#elif defined(__CYGWIN__) +#include "tkUnixInt.h" +#endif + +/* + * Forward declarations of the structures we define. + */ + +typedef struct ColorTableId ColorTableId; +typedef struct ColorTable ColorTable; +typedef struct PhotoInstance PhotoInstance; +typedef struct PhotoMaster PhotoMaster; + +/* + * A signed 8-bit integral type. If chars are unsigned and the compiler isn't + * an ANSI one, then we have to use short instead (which wastes space) to get + * signed behavior. + */ + +#if defined(__STDC__) || defined(_AIX) + typedef signed char schar; +#else +# ifndef __CHAR_UNSIGNED__ + typedef char schar; +# else + typedef short schar; +# endif +#endif + +/* + * An unsigned 32-bit integral type, used for pixel values. We use int rather + * than long here to accommodate those systems where longs are 64 bits. + */ + +typedef unsigned int pixel; + +/* + * The maximum number of pixels to transmit to the server in a single + * XPutImage call. + */ + +#define MAX_PIXELS 65536 + +/* + * The set of colors required to display a photo image in a window depends on: + * - the visual used by the window + * - the palette, which specifies how many levels of each primary color to + * use, and + * - the gamma value for the image. + * + * Pixel values allocated for specific colors are valid only for the colormap + * in which they were allocated. Sets of pixel values allocated for displaying + * photos are re-used in other windows if possible, that is, if the display, + * colormap, palette and gamma values match. A hash table is used to locate + * these sets of pixel values, using the following data structure as key: + */ + +struct ColorTableId { + Display *display; /* Qualifies the colormap resource ID. */ + Colormap colormap; /* Colormap that the windows are using. */ + double gamma; /* Gamma exponent value for images. */ + Tk_Uid palette; /* Specifies how many shades of each primary + * we want to allocate. */ +}; + +/* + * For a particular (display, colormap, palette, gamma) combination, a data + * structure of the following type is used to store the allocated pixel values + * and other information: + */ + +struct ColorTable { + ColorTableId id; /* Information used in selecting this color + * table. */ + int flags; /* See below. */ + int refCount; /* Number of instances using this map. */ + int liveRefCount; /* Number of instances which are actually in + * use, using this map. */ + int numColors; /* Number of colors allocated for this map. */ + + XVisualInfo visualInfo; /* Information about the visual for windows + * using this color table. */ + + pixel redValues[256]; /* Maps 8-bit values of red intensity to a + * pixel value or index in pixelMap. */ + pixel greenValues[256]; /* Ditto for green intensity. */ + pixel blueValues[256]; /* Ditto for blue intensity. */ + unsigned long *pixelMap; /* Actual pixel values allocated. */ + + unsigned char colorQuant[3][256]; + /* Maps 8-bit intensities to quantized + * intensities. The first index is 0 for red, + * 1 for green, 2 for blue. */ +}; + +/* + * Bit definitions for the flags field of a ColorTable. + * BLACK_AND_WHITE: 1 means only black and white colors are + * available. + * COLOR_WINDOW: 1 means a full 3-D color cube has been + * allocated. + * DISPOSE_PENDING: 1 means a call to DisposeColorTable has been + * scheduled as an idle handler, but it hasn't + * been invoked yet. + * MAP_COLORS: 1 means pixel values should be mapped through + * pixelMap. + */ + +#ifdef COLOR_WINDOW +#undef COLOR_WINDOW +#endif + +#define BLACK_AND_WHITE 1 +#define COLOR_WINDOW 2 +#define DISPOSE_PENDING 4 +#define MAP_COLORS 8 + +/* + * Definition of the data associated with each photo image master. + */ + +struct PhotoMaster { + Tk_ImageMaster tkMaster; /* Tk's token for image master. NULL means the + * image is being deleted. */ + Tcl_Interp *interp; /* Interpreter associated with the application + * using this image. */ + Tcl_Command imageCmd; /* Token for image command (used to delete it + * when the image goes away). NULL means the + * image command has already been deleted. */ + int flags; /* Sundry flags, defined below. */ + int width, height; /* Dimensions of image. */ + int userWidth, userHeight; /* User-declared image dimensions. */ + Tk_Uid palette; /* User-specified default palette for + * instances of this image. */ + double gamma; /* Display gamma value to correct for. */ + char *fileString; /* Name of file to read into image. */ + Tcl_Obj *dataString; /* Object to use as contents of image. */ + Tcl_Obj *format; /* User-specified format of data in image file + * or string value. */ + unsigned char *pix32; /* Local storage for 32-bit image. */ + int ditherX, ditherY; /* Location of first incorrectly dithered + * pixel in image. */ + TkRegion validRegion; /* Tk region indicating which parts of the + * image have valid image data. */ + PhotoInstance *instancePtr; /* First in the list of instances associated + * with this master. */ +}; + +/* + * Bit definitions for the flags field of a PhotoMaster. + * COLOR_IMAGE: 1 means that the image has different color + * components. + * IMAGE_CHANGED: 1 means that the instances of this image need + * to be redithered. + * COMPLEX_ALPHA: 1 means that the instances of this image have + * alpha values that aren't 0 or 255, and so need + * the copy-merge-replace renderer . + */ + +#define COLOR_IMAGE 1 +#define IMAGE_CHANGED 2 +#define COMPLEX_ALPHA 4 + +/* + * Flag to OR with the compositing rule to indicate that the source, despite + * having an alpha channel, has simple alpha. + */ + +#define SOURCE_IS_SIMPLE_ALPHA_PHOTO 0x10000000 + +/* + * The following data structure represents all of the instances of a photo + * image in windows on a given screen that are using the same colormap. + */ + +struct PhotoInstance { + PhotoMaster *masterPtr; /* Pointer to master for image. */ + Display *display; /* Display for windows using this instance. */ + Colormap colormap; /* The image may only be used in windows with + * 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. */ + 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 + * specified for the master. */ + ColorTable *colorTablePtr; /* Pointer to information about colors + * allocated for image display in windows like + * this one. */ + Pixmap pixels; /* X pixmap containing dithered image. */ + int width, height; /* Dimensions of the pixmap. */ + schar *error; /* Error image, used in dithering. */ + XImage *imagePtr; /* Image structure for converted pixels. */ + XVisualInfo visualInfo; /* Information about the visual that these + * windows are using. */ + GC gc; /* Graphics context for writing images to the + * pixmap. */ +}; + +/* + * Implementation of the Porter-Duff Source-Over compositing rule. + */ + +#define PD_SRC_OVER(srcColor, srcAlpha, dstColor, dstAlpha) \ + (srcColor*srcAlpha/255) + dstAlpha*(255-srcAlpha)/255*dstColor/255 +#define PD_SRC_OVER_ALPHA(srcAlpha, dstAlpha) \ + (srcAlpha + (255-srcAlpha)*dstAlpha/255) + +#undef MIN +#define MIN(a, b) ((a) < (b)? (a): (b)) +#undef MAX +#define MAX(a, b) ((a) > (b)? (a): (b)) + +/* + * Declarations of functions shared between the different parts of the + * photo image implementation. + */ + +MODULE_SCOPE void TkImgPhotoConfigureInstance( + PhotoInstance *instancePtr); +MODULE_SCOPE void TkImgDisposeInstance(ClientData clientData); +MODULE_SCOPE void TkImgPhotoInstanceSetSize(PhotoInstance *instancePtr); +MODULE_SCOPE ClientData TkImgPhotoGet(Tk_Window tkwin, ClientData clientData); +MODULE_SCOPE void TkImgDitherInstance(PhotoInstance *instancePtr, int x, + int y, int width, int height); +MODULE_SCOPE void TkImgPhotoDisplay(ClientData clientData, + Display *display, Drawable drawable, + int imageX, int imageY, int width, int height, + int drawableX, int drawableY); +MODULE_SCOPE void TkImgPhotoFree(ClientData clientData, + Display *display); +MODULE_SCOPE void TkImgResetDither(PhotoInstance *instancePtr); + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/generic/tkImgUtil.c b/generic/tkImgUtil.c index 8ba6c0e..5487165 100644 --- a/generic/tkImgUtil.c +++ b/generic/tkImgUtil.c @@ -55,7 +55,7 @@ TkAlignImageData( dataWidth += (alignment - (dataWidth % alignment)); } - data = ckalloc((unsigned) dataWidth * image->height); + data = ckalloc(dataWidth * image->height); destPtr = data; for (i = 0; i < image->height; i++) { diff --git a/generic/tkInt.decls b/generic/tkInt.decls index c2d018c..a3e1f98 100644 --- a/generic/tkInt.decls +++ b/generic/tkInt.decls @@ -17,6 +17,7 @@ library tk # Define the unsupported generic interfaces. interface tkInt +scspec EXTERN # Declare each of the functions in the unsupported internal Tcl interface. # These interfaces are allowed to changed between versions. Use at your own @@ -34,9 +35,9 @@ declare 2 { void TkBezierScreenPoints(Tk_Canvas canvas, double control[], int numSteps, XPoint *xPointPtr) } -declare 3 { - void TkBindDeadWindow(TkWindow *winPtr) -} +# +# Slot 3 unused (WAS: TkBindDeadWindow) +# declare 4 { void TkBindEventProc(TkWindow *winPtr, XEvent *eventPtr) } @@ -56,15 +57,10 @@ declare 9 { void TkComputeAnchor(Tk_Anchor anchor, Tk_Window tkwin, int padX, int padY, int innerWidth, int innerHeight, int *xPtr, int *yPtr) } -declare 10 { - int TkCopyAndGlobalEval(Tcl_Interp *interp, char *script) -} -declare 11 { - unsigned long TkCreateBindingProcedure(Tcl_Interp *interp, - Tk_BindingTable bindingTable, ClientData object, - const char *eventString, TkBindEvalProc *evalProc, - TkBindFreeProc *freeProc, ClientData clientData) -} +# +# Slot 10 unused (WAS: TkCopyAndGlobalEval) +# Slot 11 unused (WAS: TkCreateBindingProcedure) +# declare 12 { TkCursor *TkCreateCursorFromData(Tk_Window tkwin, const char *source, const char *mask, int width, int height, @@ -72,11 +68,11 @@ declare 12 { } declare 13 { int TkCreateFrame(ClientData clientData, Tcl_Interp *interp, - int argc, char **argv, int toplevel, char *appName) + int argc, const char *const *argv, int toplevel, const char *appName) } declare 14 { Tk_Window TkCreateMainWindow(Tcl_Interp *interp, - const char *screenName, char *baseName) + const char *screenName, const char *baseName) } declare 15 { Time TkCurrentTime(TkDisplay *dispPtr) @@ -103,7 +99,7 @@ declare 21 { const TkStateMap *mapPtr, const char *strKey) } declare 22 { - char *TkFindStateString(const TkStateMap *mapPtr, int numKey) + CONST86 char *TkFindStateString(const TkStateMap *mapPtr, int numKey) } declare 23 { void TkFocusDeadWindow(TkWindow *winPtr) @@ -129,8 +125,8 @@ declare 29 { void TkpFreeCursor(TkCursor *cursorPtr) } declare 30 { - char *TkGetBitmapData(Tcl_Interp *interp, char *string, - char *fileName, int *widthPtr, int *heightPtr, + char *TkGetBitmapData(Tcl_Interp *interp, const char *string, + const char *fileName, int *widthPtr, int *heightPtr, int *hotXPtr, int *hotYPtr) } declare 31 { @@ -142,7 +138,7 @@ declare 32 { Tk_Window tkwin, Tk_Uid string) } declare 33 { - CONST84_RETURN char *TkGetDefaultScreenName(Tcl_Interp *interp, + const char *TkGetDefaultScreenName(Tcl_Interp *interp, const char *screenName) } declare 34 { @@ -186,7 +182,7 @@ declare 45 { void TkInstallFrameMenu(Tk_Window tkwin) } declare 46 { - char *TkKeysymToString(KeySym keysym) + CONST86 char *TkKeysymToString(KeySym keysym) } declare 47 { int TkLineToArea(double end1Ptr[], double end2Ptr[], double rectPtr[]) @@ -253,7 +249,7 @@ declare 66 { Window TkpMakeWindow(TkWindow *winPtr, Window parent) } declare 67 { - void TkpMenuNotifyToplevelCreate(Tcl_Interp *interp, char *menuName) + void TkpMenuNotifyToplevelCreate(Tcl_Interp *interp, const char *menuName) } declare 68 { TkDisplay *TkpOpenDisplay(const char *display_name) @@ -274,14 +270,14 @@ declare 73 { void TkpRedirectKeyEvent(TkWindow *winPtr, XEvent *eventPtr) } declare 74 { - void TkpSetMainMenubar(Tcl_Interp *interp, Tk_Window tkwin, char *menuName) + void TkpSetMainMenubar(Tcl_Interp *interp, Tk_Window tkwin, const char *menuName) } declare 75 { int TkpUseWindow(Tcl_Interp *interp, Tk_Window tkwin, const char *string) } -declare 76 { - int TkpWindowWasRecentlyDeleted(Window win, TkDisplay *dispPtr) -} +# +# Slot 76 unused (WAS: TkpWindowWasRecentlyDeleted) +# declare 77 { void TkQueueEventForAllChildren(TkWindow *winPtr, XEvent *eventPtr) } @@ -314,10 +310,10 @@ declare 83 { #} declare 85 { void TkSetWindowMenuBar(Tcl_Interp *interp, Tk_Window tkwin, - char *oldMenuName, char *menuName) + const char *oldMenuName, const char *menuName) } declare 86 { - KeySym TkStringToKeysym(char *name) + KeySym TkStringToKeysym(const char *name) } declare 87 { int TkThickPolyLineToArea(double *coordPtr, int numPoints, @@ -358,22 +354,22 @@ declare 97 { # new for 8.1 declare 98 { - Tcl_Obj *TkDebugBitmap(Tk_Window tkwin, char *name) + Tcl_Obj *TkDebugBitmap(Tk_Window tkwin, const char *name) } declare 99 { - Tcl_Obj *TkDebugBorder(Tk_Window tkwin, char *name) + Tcl_Obj *TkDebugBorder(Tk_Window tkwin, const char *name) } declare 100 { - Tcl_Obj *TkDebugCursor(Tk_Window tkwin, char *name) + Tcl_Obj *TkDebugCursor(Tk_Window tkwin, const char *name) } declare 101 { - Tcl_Obj *TkDebugColor(Tk_Window tkwin, char *name) + Tcl_Obj *TkDebugColor(Tk_Window tkwin, const char *name) } declare 102 { Tcl_Obj *TkDebugConfig(Tcl_Interp *interp, Tk_OptionTable table) } declare 103 { - Tcl_Obj *TkDebugFont(Tk_Window tkwin, char *name) + Tcl_Obj *TkDebugFont(Tk_Window tkwin, const char *name) } declare 104 { int TkFindStateNumObj(Tcl_Interp *interp, Tcl_Obj *optionPtr, @@ -393,7 +389,7 @@ declare 108 { Tcl_Obj *objPtr, Tk_Window *windowPtr) } declare 109 { - char *TkpGetString(TkWindow *winPtr, XEvent *eventPtr, Tcl_DString *dsPtr) + CONST86 char *TkpGetString(TkWindow *winPtr, XEvent *eventPtr, Tcl_DString *dsPtr) } declare 110 { void TkpGetSubFonts(Tcl_Interp *interp, Tk_Font tkfont) @@ -429,7 +425,7 @@ declare 119 { TkRegion src, TkRegion dr_return) } declare 121 aqua { - Pixmap TkpCreateNativeBitmap(Display *display, const char *source) + Pixmap TkpCreateNativeBitmap(Display *display, const void *source) } declare 122 aqua { void TkpDefineNativeBitmaps(void) @@ -510,22 +506,71 @@ declare 154 { # entries needed only by tktest: declare 156 { - int TkpTestembedCmd(ClientData clientData, Tcl_Interp *interp, int argc, - const char **argv) + int TkpTestembedCmd(ClientData clientData, Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]) } declare 157 { - int TkpTesttextCmd(ClientData dummy, Tcl_Interp *interp, int argc, - const char **argv) -} - -# Next group of functions exposed due to [Bug 2768945]. Numbers are chosen so -# as to match 8.6 branch/HEAD. + int TkpTesttextCmd(ClientData dummy, Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]) +} +declare 158 { + int TkSelGetSelection(Tcl_Interp *interp, Tk_Window tkwin, + Atom selection, Atom target, Tk_GetSelProc *proc, + ClientData clientData) +} +declare 159 { + int TkTextGetIndex(Tcl_Interp *interp, struct TkText *textPtr, + const char *string, struct TkTextIndex *indexPtr) +} +declare 160 { + int TkTextIndexBackBytes(const struct TkText *textPtr, + const struct TkTextIndex *srcPtr, int count, + struct TkTextIndex *dstPtr) +} +declare 161 { + int TkTextIndexForwBytes(const struct TkText *textPtr, + const struct TkTextIndex *srcPtr, int count, + struct TkTextIndex *dstPtr) +} +declare 162 { + struct TkTextIndex *TkTextMakeByteIndex(TkTextBTree tree, + const struct TkText *textPtr, int lineIndex, + int byteIndex, struct TkTextIndex *indexPtr) +} +declare 163 { + int TkTextPrintIndex(const struct TkText *textPtr, + const struct TkTextIndex *indexPtr, char *string) +} +declare 164 { + struct TkTextSegment *TkTextSetMark(struct TkText *textPtr, + const char *name, struct TkTextIndex *indexPtr) +} +declare 165 { + int TkTextXviewCmd(struct TkText *textPtr, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]) +} +declare 166 { + void TkTextChanged(struct TkSharedText *sharedTextPtr, + struct TkText *textPtr, const struct TkTextIndex *index1Ptr, + const struct TkTextIndex *index2Ptr) +} +declare 167 { + int TkBTreeNumLines(TkTextBTree tree, + const struct TkText *textPtr) +} +declare 168 { + void TkTextInsertDisplayProc(struct TkText *textPtr, + struct TkTextDispChunk *chunkPtr, int x, int y, + int height, int baseline, Display *display, + Drawable dst, int screenY) +} +# Next group of functions exposed due to [Bug 2768945]. declare 169 { int TkStateParseProc(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset) } declare 170 { - char *TkStatePrintProc(ClientData clientData, Tk_Window tkwin, + CONST86 char *TkStatePrintProc(ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr) } declare 171 { @@ -533,7 +578,7 @@ declare 171 { Tk_Window tkwin, const char *value, char *widgRec, int offset) } declare 172 { - char *TkCanvasDashPrintProc(ClientData clientData, Tk_Window tkwin, + CONST86 char *TkCanvasDashPrintProc(ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr) } declare 173 { @@ -541,7 +586,7 @@ declare 173 { Tk_Window tkwin, const char *value, char *widgRec, int offset) } declare 174 { - char *TkOffsetPrintProc(ClientData clientData, Tk_Window tkwin, + CONST86 char *TkOffsetPrintProc(ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr) } declare 175 { @@ -549,7 +594,7 @@ declare 175 { Tk_Window tkwin, const char *value, char *widgRec, int offset) } declare 176 { - char *TkPixelPrintProc(ClientData clientData, Tk_Window tkwin, + CONST86 char *TkPixelPrintProc(ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr) } declare 177 { @@ -557,7 +602,7 @@ declare 177 { Tk_Window tkwin, const char *value, char *widgRec, int offset) } declare 178 { - char *TkOrientPrintProc(ClientData clientData, Tk_Window tkwin, + CONST86 char *TkOrientPrintProc(ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr) } declare 179 { @@ -565,11 +610,29 @@ declare 179 { Tk_Window tkwin, const char *value, char *widgRec, int offset) } declare 180 { - char *TkSmoothPrintProc(ClientData clientData, Tk_Window tkwin, + CONST86 char *TkSmoothPrintProc(ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr) } + +# Angled text API, exposed for Emiliano Gavilán's RBC work. +declare 181 { + void TkDrawAngledTextLayout(Display *display, Drawable drawable, GC gc, + Tk_TextLayout layout, int x, int y, double angle, int firstChar, + int lastChar) +} +declare 182 { + void TkUnderlineAngledTextLayout(Display *display, Drawable drawable, + GC gc, Tk_TextLayout layout, int x, int y, double angle, + int underline) +} +declare 183 { + int TkIntersectAngledTextLayout(Tk_TextLayout layout, int x, int y, + int width, int height, double angle) +} declare 184 { - void TkUnusedStubEntry(void) + void TkDrawAngledChars(Display *display,Drawable drawable, GC gc, + Tk_Font tkfont, const char *source, int numBytes, double x, + double y, double angle) } ############################################################################## @@ -585,12 +648,10 @@ interface tkIntPlat declare 0 x11 { void TkCreateXEventSource(void) } -declare 1 x11 { - void TkFreeWindowId(TkDisplay *dispPtr, Window w) -} -declare 2 x11 { - void TkInitXId(TkDisplay *dispPtr) -} +# +# Slot 1 unused (WAS: TkFreeWindowId) +# Slot 2 unused (WAS: TkInitXId) +# declare 3 x11 { int TkpCmapStressed(Tk_Window tkwin, Colormap colormap) } @@ -615,16 +676,16 @@ declare 9 x11 { declare 10 x11 { void TkSendCleanup(TkDisplay *dispPtr) } -declare 11 x11 { - void TkFreeXId(TkDisplay *dispPtr) -} +# +# Slot 11 unused (WAS: TkFreeXId) +# declare 12 x11 { int TkpWmSetState(TkWindow *winPtr, int state) } # only needed by tktest: declare 13 x11 { - int TkpTestsendCmd(ClientData clientData, Tcl_Interp *interp, int argc, - const char **argv) + int TkpTestsendCmd(ClientData clientData, Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]) } ################################ @@ -780,8 +841,8 @@ declare 44 win { } # only needed by tktest: declare 45 win { - int TkpTestsendCmd(ClientData clientData, Tcl_Interp *interp, int argc, - const char **argv) + int TkpTestsendCmd(ClientData clientData, Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]) } ################################ @@ -793,7 +854,7 @@ declare 0 aqua { # removed duplicates from tkInt table #declare 1 aqua { -# Pixmap TkpCreateNativeBitmap(Display *display, const char *source) +# Pixmap TkpCreateNativeBitmap(Display *display, const void *source) #} # #declare 2 aqua { @@ -922,9 +983,9 @@ declare 38 aqua { declare 39 aqua { void TkSetWMName(TkWindow *winPtr, Tk_Uid titleUid) } -declare 40 aqua { - void TkSuspendClipboard(void) -} +# +# Slot 40 unused (WAS: TkSuspendClipboard) +# declare 41 aqua { int TkMacOSXZoomToplevel(void *whichWindow, short zoomPart) } @@ -948,7 +1009,7 @@ declare 47 aqua { Tk_Window TkMacOSXGetCapture(void) } declare 49 aqua { - Window TkGetTransientMaster(TkWindow *winPtr) + Tk_Window TkGetTransientMaster(TkWindow *winPtr) } declare 50 aqua { int TkGenerateButtonEvent(int x, int y, Window window, unsigned int state) @@ -1359,7 +1420,7 @@ declare 106 win { int x, int y, unsigned int width, unsigned int height) } -# new for 8.4.20+/8.5.12+ Cygwin only +# New in Tk 8.6 declare 107 win { int XFlush(Display *display) } @@ -1385,6 +1446,36 @@ declare 114 win { 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) } @@ -1394,6 +1485,14 @@ declare 134 win { 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) +} ################################ # X functions for Aqua diff --git a/generic/tkInt.h b/generic/tkInt.h index 15a01c5..a80d209 100644 --- a/generic/tkInt.h +++ b/generic/tkInt.h @@ -15,22 +15,17 @@ #ifndef _TKINT #define _TKINT -#ifndef _TK -#include "tk.h" -#endif -#ifndef _TCL -#include "tcl.h" -#endif #ifndef _TKPORT #include "tkPort.h" #endif /* - * Ensure WORDS_BIGENDIAN is defined correcly: + * Ensure WORDS_BIGENDIAN is defined correctly: * Needs to happen here in addition to configure to work with fat compiles on * Darwin (where configure runs only once for multiple architectures). */ +#include <stdio.h> #ifdef HAVE_SYS_TYPES_H # include <sys/types.h> #endif @@ -100,18 +95,11 @@ typedef struct TkpCursor_ *TkpCursor; typedef struct TkRegion_ *TkRegion; typedef struct TkStressedCmap TkStressedCmap; typedef struct TkBindInfo_ *TkBindInfo; - -/* - * Function types. - */ - -typedef int (TkBindEvalProc)(ClientData clientData, Tcl_Interp *interp, - XEvent *eventPtr, Tk_Window tkwin, KeySym keySym); -typedef void (TkBindFreeProc)(ClientData clientData); +typedef struct Busy *TkBusy; /* * One of the following structures is maintained for each cursor in use in the - * system. This structure is used by tkCursor.c and the various system + * system. This structure is used by tkCursor.c and the various system- * specific cursor files. */ @@ -335,6 +323,9 @@ typedef struct TkDisplay { * by that master. */ int geomInit; +#define TkGetGeomMaster(tkwin) (((TkWindow *)tkwin)->maintainerPtr != NULL ? \ + ((TkWindow *)tkwin)->maintainerPtr : ((TkWindow *)tkwin)->parentPtr) + /* * Information used by tkGet.c only: */ @@ -397,10 +388,6 @@ typedef struct TkDisplay { int postCommandGeneration; /* - * Information used by tkOption.c only. - */ - - /* * Information used by tkPack.c only. */ @@ -439,6 +426,7 @@ typedef struct TkDisplay { Atom windowAtom; /* Atom for TK_WINDOW. */ Atom clipboardAtom; /* Atom for CLIPBOARD. */ Atom utf8Atom; /* Atom for UTF8_STRING. */ + Atom atomPairAtom; /* Atom for ATOM_PAIR. */ Tk_Window clipWindow; /* Window used for clipboard ownership and to * retrieve selections between processes. NULL @@ -469,24 +457,6 @@ typedef struct TkDisplay { * application name on each comm window. */ /* - * Information used by tkXId.c only: - */ - - struct TkIdStack *idStackPtr; - /* First in list of chunks of free resource - * identifiers, or NULL if there are no free - * resources. */ - XID (*defaultAllocProc) (Display *display); - /* Default resource allocator for display. */ - struct TkIdStack *windowStackPtr; - /* First in list of chunks of window ids that - * can't be reused right now. */ - Tcl_TimerToken idCleanupScheduled; - /* If set, it means a call to WindowIdCleanup - * has already been scheduled, 0 means it - * hasn't. */ - - /* * Information used by tkUnixWm.c and tkWinWm.c only: */ @@ -495,18 +465,6 @@ typedef struct TkDisplay { /* Points to the foreground window. */ /* - * Information maintained by tkWindow.c for use later on by tkXId.c: - */ - - int destroyCount; /* Number of Tk_DestroyWindow operations in - * progress. */ - unsigned long lastDestroyRequest; - /* Id of most recent XDestroyWindow request; - * can re-use ids in windowStackPtr when - * server has seen this request and event - * queue is empty. */ - - /* * Information used by tkVisual.c only: */ @@ -537,7 +495,9 @@ typedef struct TkDisplay { * display. */ Window mouseButtonWindow; /* Window the button state was set in, added * in Tk 8.4. */ - Window warpWindow; + Tk_Window warpWindow; + Tk_Window warpMainwin; /* For finding the root window for warping + * purposes. */ int warpX; int warpY; @@ -552,6 +512,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; /* @@ -670,6 +633,7 @@ typedef struct TkMainInfo { * ::tk::AlwaysShowSelection variable. */ struct TkMainInfo *nextPtr; /* Next in list of all main windows managed by * this process. */ + Tcl_HashTable busyTable; /* Information used by [tk busy] command. */ } TkMainInfo; /* @@ -679,7 +643,7 @@ typedef struct TkMainInfo { */ typedef struct { - const char *source; /* Bits for bitmap. */ + const void *source; /* Bits for bitmap. */ int width, height; /* Dimensions of bitmap. */ int native; /* 0 means generic (X style) bitmap, 1 means * native style bitmap. */ @@ -804,7 +768,8 @@ typedef struct TkWindow { * Information used by tkGeometry.c for geometry management. */ - const Tk_GeomMgr *geomMgrPtr; /* Information about geometry manager for this + const Tk_GeomMgr *geomMgrPtr; + /* Information about geometry manager for this * window. */ ClientData geomData; /* Argument for geometry manager functions. */ int reqWidth, reqHeight; /* Arguments from last call to @@ -823,13 +788,14 @@ typedef struct TkWindow { struct TkWmInfo *wmInfoPtr; /* For top-level windows (and also for special * Unix menubar and wrapper windows), points * to structure with wm-related info (see - * tkWm.c). For other windows, this is NULL. */ + * tkWm.c). For other windows, this is + * NULL. */ /* * Information used by widget classes. */ - Tk_ClassProcs *classProcsPtr; + const Tk_ClassProcs *classProcsPtr; ClientData instanceData; /* @@ -849,6 +815,14 @@ typedef struct TkWindow { int minReqWidth; /* Minimum requested width. */ int minReqHeight; /* Minimum requested height. */ +#ifdef TK_USE_INPUT_METHODS + int ximGeneration; /* Used to invalidate XIC */ +#endif /* TK_USE_INPUT_METHODS */ + char *geomMgrName; /* Records the name of the geometry manager. */ + struct TkWindow *maintainerPtr; + /* The geometry master for this window. The + * value is NULL if the window has no master or + * if its master is its parent. */ } TkWindow; /* @@ -870,6 +844,25 @@ typedef struct { } TkKeyEvent; /* + * Flags passed to TkpMakeMenuWindow's 'transient' argument. + */ + +#define TK_MAKE_MENU_TEAROFF 0 /* Only non-transient case. */ +#define TK_MAKE_MENU_POPUP 1 +#define TK_MAKE_MENU_DROPDOWN 2 + +/* + * The following structure is used with TkMakeEnsemble to create ensemble + * commands and optionally to create sub-ensembles. + */ + +typedef struct TkEnsemble { + const char *name; + Tcl_ObjCmdProc *proc; + const struct TkEnsemble *subensemble; +} TkEnsemble; + +/* * The following structure is used as a two way map between integers and * strings, usually to map between an internal C representation and the * strings used in Tcl. @@ -897,12 +890,6 @@ typedef struct TkpClipMask { #define TKP_CLIP_REGION 1 /* - * Pointer to first entry in list of all displays currently known. - */ - -extern TkDisplay *tkDisplayList; - -/* * Return values from TkGrabState: */ @@ -949,30 +936,72 @@ extern TkDisplay *tkDisplayList; * be properly registered with Tcl: */ -MODULE_SCOPE Tcl_ObjType tkBorderObjType; -MODULE_SCOPE Tcl_ObjType tkBitmapObjType; -MODULE_SCOPE Tcl_ObjType tkColorObjType; -MODULE_SCOPE Tcl_ObjType tkCursorObjType; -MODULE_SCOPE Tcl_ObjType tkFontObjType; -MODULE_SCOPE Tcl_ObjType tkOptionObjType; -MODULE_SCOPE Tcl_ObjType tkStateKeyObjType; -MODULE_SCOPE Tcl_ObjType tkTextIndexType; +MODULE_SCOPE const Tcl_ObjType tkBorderObjType; +MODULE_SCOPE const Tcl_ObjType tkBitmapObjType; +MODULE_SCOPE const Tcl_ObjType tkColorObjType; +MODULE_SCOPE const Tcl_ObjType tkCursorObjType; +MODULE_SCOPE const Tcl_ObjType tkFontObjType; +MODULE_SCOPE const Tcl_ObjType tkStateKeyObjType; +MODULE_SCOPE const Tcl_ObjType tkTextIndexType; /* * Miscellaneous variables shared among Tk modules but not exported to the * outside world: */ -MODULE_SCOPE Tk_SmoothMethod tkBezierSmoothMethod; +MODULE_SCOPE const Tk_SmoothMethod tkBezierSmoothMethod; MODULE_SCOPE Tk_ImageType tkBitmapImageType; MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtGIF; MODULE_SCOPE void (*tkHandleEventProc) (XEvent* eventPtr); +MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtPNG; MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtPPM; MODULE_SCOPE TkMainInfo *tkMainWindowList; MODULE_SCOPE Tk_ImageType tkPhotoImageType; MODULE_SCOPE Tcl_HashTable tkPredefBitmapTable; -MODULE_SCOPE CONST char *const tkWebColors[20]; +MODULE_SCOPE const char *const tkWebColors[20]; + +/* + * The definition of pi, at least from the perspective of double-precision + * floats. + */ + +#ifndef PI +#ifdef M_PI +#define PI M_PI +#else +#define PI 3.14159265358979323846 +#endif +#endif + +/* + * Support for Clang Static Analyzer <http://clang-analyzer.llvm.org> + */ + +#if defined(PURIFY) && defined(__clang__) +#if __has_feature(attribute_analyzer_noreturn) && \ + !defined(Tcl_Panic) && defined(Tcl_Panic_TCL_DECLARED) +void Tcl_Panic(const char *, ...) __attribute__((analyzer_noreturn)); +#endif +#if !defined(CLANG_ASSERT) +#include <assert.h> +#define CLANG_ASSERT(x) assert(x) +#endif +#elif !defined(CLANG_ASSERT) +#define CLANG_ASSERT(x) +#endif /* PURIFY && __clang__ */ + +/* + * The following magic value is stored in the "send_event" field of FocusIn + * and FocusOut events. This allows us to separate "real" events coming from + * the server from those that we generated. + */ + +#define GENERATED_FOCUS_EVENT_MAGIC ((Bool) 0x547321ac) + +/* + * Exported internals. + */ #include "tkIntDecls.h" @@ -996,6 +1025,9 @@ MODULE_SCOPE int Tk_BindObjCmd(ClientData clientData, MODULE_SCOPE int Tk_BindtagsObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_BusyObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); MODULE_SCOPE int Tk_ButtonObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); @@ -1014,9 +1046,6 @@ MODULE_SCOPE int Tk_ChooseColorObjCmd(ClientData clientData, MODULE_SCOPE int Tk_ChooseDirectoryObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); -MODULE_SCOPE int Tk_ChooseFontObjCmd(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); MODULE_SCOPE int Tk_DestroyObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); @@ -1062,6 +1091,9 @@ MODULE_SCOPE int Tk_ListboxObjCmd(ClientData clientData, MODULE_SCOPE int Tk_LowerObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); +MODULE_SCOPE int Tk_MenuObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); MODULE_SCOPE int Tk_MenubuttonObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); @@ -1092,13 +1124,15 @@ MODULE_SCOPE int Tk_RaiseObjCmd(ClientData clientData, MODULE_SCOPE int Tk_ScaleObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); -MODULE_SCOPE int Tk_ScrollbarCmd(ClientData clientData, - Tcl_Interp *interp, int argc, const char **argv); +MODULE_SCOPE int Tk_ScrollbarObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); MODULE_SCOPE int Tk_SelectionObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); -MODULE_SCOPE int Tk_SendCmd(ClientData clientData, - Tcl_Interp *interp, int argc, const char **argv); +MODULE_SCOPE int Tk_SendObjCmd(ClientData clientData, + Tcl_Interp *interp,int objc, + Tcl_Obj *const objv[]); MODULE_SCOPE int Tk_SendObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); @@ -1108,9 +1142,6 @@ MODULE_SCOPE int Tk_SpinboxObjCmd(ClientData clientData, MODULE_SCOPE int Tk_TextObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); -MODULE_SCOPE int Tk_TkObjCmd(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); MODULE_SCOPE int Tk_TkwaitObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); @@ -1129,12 +1160,15 @@ MODULE_SCOPE int Tk_WmObjCmd(ClientData clientData, Tcl_Interp *interp, MODULE_SCOPE int Tk_GetDoublePixelsFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, double *doublePtr); +MODULE_SCOPE int TkSetGeometryMaster(Tcl_Interp *interp, + Tk_Window tkwin, const char *master); +MODULE_SCOPE void TkFreeGeometryMaster(Tk_Window tkwin, + const char *master); MODULE_SCOPE void TkEventInit(void); MODULE_SCOPE void TkRegisterObjTypes(void); -MODULE_SCOPE int TkCreateMenuCmd(Tcl_Interp *interp); -MODULE_SCOPE int TkDeadAppCmd(ClientData clientData, - Tcl_Interp *interp, int argc, const char **argv); +MODULE_SCOPE int TkDeadAppObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, Tcl_Obj *const argv[]); MODULE_SCOPE int TkCanvasGetCoordObj(Tcl_Interp *interp, Tk_Canvas canvas, Tcl_Obj *obj, double *doublePtr); @@ -1155,8 +1189,8 @@ MODULE_SCOPE void TkpBuildRegionFromAlphaData(TkRegion region, unsigned x, unsigned y, unsigned width, unsigned height, unsigned char *dataPtr, unsigned pixelStride, unsigned lineStride); -MODULE_SCOPE void TkPrintPadAmount(Tcl_Interp *interp, - char *buffer, int pad1, int pad2); +MODULE_SCOPE void TkAppendPadAmount(Tcl_Obj *bufferObj, + const char *buffer, int pad1, int pad2); MODULE_SCOPE int TkParsePadAmount(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, int *pad1Ptr, int *pad2Ptr); @@ -1176,18 +1210,51 @@ MODULE_SCOPE void TkUnderlineCharsInContext(Display *display, const char *string, int numBytes, int x, int y, int firstByte, int lastByte); MODULE_SCOPE void TkpGetFontAttrsForChar(Tk_Window tkwin, Tk_Font tkfont, - Tcl_UniChar c, struct TkFontAttributes *faPtr); -#ifdef __WIN32__ + int c, struct TkFontAttributes *faPtr); +MODULE_SCOPE Tcl_Obj * TkNewWindowObj(Tk_Window tkwin); +MODULE_SCOPE void TkpShowBusyWindow(TkBusy busy); +MODULE_SCOPE void TkpHideBusyWindow(TkBusy busy); +MODULE_SCOPE void TkpMakeTransparentWindowExist(Tk_Window tkwin, + Window parent); +MODULE_SCOPE void TkpCreateBusy(Tk_FakeWin *winPtr, Tk_Window tkRef, + Window *parentPtr, Tk_Window tkParent, + TkBusy busy); +MODULE_SCOPE int TkBackgroundEvalObjv(Tcl_Interp *interp, + int objc, Tcl_Obj *const *objv, int flags); +MODULE_SCOPE void TkSendVirtualEvent(Tk_Window tgtWin, + const char *eventName, Tcl_Obj *detail); +MODULE_SCOPE Tcl_Command TkMakeEnsemble(Tcl_Interp *interp, + const char *nsname, const char *name, + ClientData clientData, const TkEnsemble *map); +MODULE_SCOPE int TkInitTkCmd(Tcl_Interp *interp, + ClientData clientData); +MODULE_SCOPE int TkInitFontchooser(Tcl_Interp *interp, + ClientData clientData); +MODULE_SCOPE void TkpWarpPointer(TkDisplay *dispPtr); +MODULE_SCOPE void TkpCancelWarp(TkDisplay *dispPtr); +MODULE_SCOPE int TkListCreateFrame(ClientData clientData, + Tcl_Interp *interp, Tcl_Obj *listObj, + int toplevel, Tcl_Obj *nameObj); + +#ifdef _WIN32 #define TkParseColor XParseColor #else MODULE_SCOPE Status TkParseColor (Display * display, - Colormap map, CONST char* spec, + Colormap map, const char* spec, XColor * colorPtr); #endif #ifdef HAVE_XFT 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. */ @@ -1196,8 +1263,21 @@ MODULE_SCOPE int TkUnsupported1ObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); -#endif /* _TKINT */ +/* + * For Tktest. + */ +MODULE_SCOPE int SquareObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj * const objv[]); +MODULE_SCOPE int TkOldTestInit(Tcl_Interp *interp); +#if !(defined(_WIN32) || defined(MAC_OSX_TK)) +#define TkplatformtestInit(x) TCL_OK +#else +MODULE_SCOPE int TkplatformtestInit(Tcl_Interp *interp); +#endif +#endif /* _TKINT */ + /* * Local Variables: * mode: c diff --git a/generic/tkIntDecls.h b/generic/tkIntDecls.h index 9dea8d4..b8addbd 100644 --- a/generic/tkIntDecls.h +++ b/generic/tkIntDecls.h @@ -20,6 +20,13 @@ #define TCL_STORAGE_CLASS DLLEXPORT #endif +struct TkText; +typedef struct TkTextBTree_ *TkTextBTree; +struct TkTextDispChunk; +struct TkTextIndex; +struct TkTextSegment; +struct TkSharedText; + /* * WARNING: This file is automatically generated by the tools/genStubs.tcl * script. Any modifications to the function declarations below should be made @@ -36,702 +43,328 @@ extern "C" { * Exported function declarations: */ -#ifndef TkAllocWindow_TCL_DECLARED -#define TkAllocWindow_TCL_DECLARED /* 0 */ EXTERN TkWindow * TkAllocWindow(TkDisplay *dispPtr, int screenNum, TkWindow *parentPtr); -#endif -#ifndef TkBezierPoints_TCL_DECLARED -#define TkBezierPoints_TCL_DECLARED /* 1 */ EXTERN void TkBezierPoints(double control[], int numSteps, double *coordPtr); -#endif -#ifndef TkBezierScreenPoints_TCL_DECLARED -#define TkBezierScreenPoints_TCL_DECLARED /* 2 */ EXTERN void TkBezierScreenPoints(Tk_Canvas canvas, double control[], int numSteps, XPoint *xPointPtr); -#endif -#ifndef TkBindDeadWindow_TCL_DECLARED -#define TkBindDeadWindow_TCL_DECLARED -/* 3 */ -EXTERN void TkBindDeadWindow(TkWindow *winPtr); -#endif -#ifndef TkBindEventProc_TCL_DECLARED -#define TkBindEventProc_TCL_DECLARED +/* Slot 3 is reserved */ /* 4 */ EXTERN void TkBindEventProc(TkWindow *winPtr, XEvent *eventPtr); -#endif -#ifndef TkBindFree_TCL_DECLARED -#define TkBindFree_TCL_DECLARED /* 5 */ EXTERN void TkBindFree(TkMainInfo *mainPtr); -#endif -#ifndef TkBindInit_TCL_DECLARED -#define TkBindInit_TCL_DECLARED /* 6 */ EXTERN void TkBindInit(TkMainInfo *mainPtr); -#endif -#ifndef TkChangeEventWindow_TCL_DECLARED -#define TkChangeEventWindow_TCL_DECLARED /* 7 */ EXTERN void TkChangeEventWindow(XEvent *eventPtr, TkWindow *winPtr); -#endif -#ifndef TkClipInit_TCL_DECLARED -#define TkClipInit_TCL_DECLARED /* 8 */ EXTERN int TkClipInit(Tcl_Interp *interp, TkDisplay *dispPtr); -#endif -#ifndef TkComputeAnchor_TCL_DECLARED -#define TkComputeAnchor_TCL_DECLARED /* 9 */ EXTERN void TkComputeAnchor(Tk_Anchor anchor, Tk_Window tkwin, int padX, int padY, int innerWidth, int innerHeight, int *xPtr, int *yPtr); -#endif -#ifndef TkCopyAndGlobalEval_TCL_DECLARED -#define TkCopyAndGlobalEval_TCL_DECLARED -/* 10 */ -EXTERN int TkCopyAndGlobalEval(Tcl_Interp *interp, char *script); -#endif -#ifndef TkCreateBindingProcedure_TCL_DECLARED -#define TkCreateBindingProcedure_TCL_DECLARED -/* 11 */ -EXTERN unsigned long TkCreateBindingProcedure(Tcl_Interp *interp, - Tk_BindingTable bindingTable, - ClientData object, CONST char *eventString, - TkBindEvalProc *evalProc, - TkBindFreeProc *freeProc, - ClientData clientData); -#endif -#ifndef TkCreateCursorFromData_TCL_DECLARED -#define TkCreateCursorFromData_TCL_DECLARED +/* Slot 10 is reserved */ +/* Slot 11 is reserved */ /* 12 */ EXTERN TkCursor * TkCreateCursorFromData(Tk_Window tkwin, - CONST char *source, CONST char *mask, + const char *source, const char *mask, int width, int height, int xHot, int yHot, XColor fg, XColor bg); -#endif -#ifndef TkCreateFrame_TCL_DECLARED -#define TkCreateFrame_TCL_DECLARED /* 13 */ EXTERN int TkCreateFrame(ClientData clientData, - Tcl_Interp *interp, int argc, char **argv, - int toplevel, char *appName); -#endif -#ifndef TkCreateMainWindow_TCL_DECLARED -#define TkCreateMainWindow_TCL_DECLARED + Tcl_Interp *interp, int argc, + const char *const *argv, int toplevel, + const char *appName); /* 14 */ EXTERN Tk_Window TkCreateMainWindow(Tcl_Interp *interp, - CONST char *screenName, char *baseName); -#endif -#ifndef TkCurrentTime_TCL_DECLARED -#define TkCurrentTime_TCL_DECLARED + const char *screenName, const char *baseName); /* 15 */ EXTERN Time TkCurrentTime(TkDisplay *dispPtr); -#endif -#ifndef TkDeleteAllImages_TCL_DECLARED -#define TkDeleteAllImages_TCL_DECLARED /* 16 */ EXTERN void TkDeleteAllImages(TkMainInfo *mainPtr); -#endif -#ifndef TkDoConfigureNotify_TCL_DECLARED -#define TkDoConfigureNotify_TCL_DECLARED /* 17 */ EXTERN void TkDoConfigureNotify(TkWindow *winPtr); -#endif -#ifndef TkDrawInsetFocusHighlight_TCL_DECLARED -#define TkDrawInsetFocusHighlight_TCL_DECLARED /* 18 */ EXTERN void TkDrawInsetFocusHighlight(Tk_Window tkwin, GC gc, int width, Drawable drawable, int padding); -#endif -#ifndef TkEventDeadWindow_TCL_DECLARED -#define TkEventDeadWindow_TCL_DECLARED /* 19 */ EXTERN void TkEventDeadWindow(TkWindow *winPtr); -#endif -#ifndef TkFillPolygon_TCL_DECLARED -#define TkFillPolygon_TCL_DECLARED /* 20 */ EXTERN void TkFillPolygon(Tk_Canvas canvas, double *coordPtr, int numPoints, Display *display, Drawable drawable, GC gc, GC outlineGC); -#endif -#ifndef TkFindStateNum_TCL_DECLARED -#define TkFindStateNum_TCL_DECLARED /* 21 */ EXTERN int TkFindStateNum(Tcl_Interp *interp, - CONST char *option, CONST TkStateMap *mapPtr, - CONST char *strKey); -#endif -#ifndef TkFindStateString_TCL_DECLARED -#define TkFindStateString_TCL_DECLARED + const char *option, const TkStateMap *mapPtr, + const char *strKey); /* 22 */ -EXTERN char * TkFindStateString(CONST TkStateMap *mapPtr, +EXTERN CONST86 char * TkFindStateString(const TkStateMap *mapPtr, int numKey); -#endif -#ifndef TkFocusDeadWindow_TCL_DECLARED -#define TkFocusDeadWindow_TCL_DECLARED /* 23 */ EXTERN void TkFocusDeadWindow(TkWindow *winPtr); -#endif -#ifndef TkFocusFilterEvent_TCL_DECLARED -#define TkFocusFilterEvent_TCL_DECLARED /* 24 */ EXTERN int TkFocusFilterEvent(TkWindow *winPtr, XEvent *eventPtr); -#endif -#ifndef TkFocusKeyEvent_TCL_DECLARED -#define TkFocusKeyEvent_TCL_DECLARED /* 25 */ EXTERN TkWindow * TkFocusKeyEvent(TkWindow *winPtr, XEvent *eventPtr); -#endif -#ifndef TkFontPkgInit_TCL_DECLARED -#define TkFontPkgInit_TCL_DECLARED /* 26 */ EXTERN void TkFontPkgInit(TkMainInfo *mainPtr); -#endif -#ifndef TkFontPkgFree_TCL_DECLARED -#define TkFontPkgFree_TCL_DECLARED /* 27 */ EXTERN void TkFontPkgFree(TkMainInfo *mainPtr); -#endif -#ifndef TkFreeBindingTags_TCL_DECLARED -#define TkFreeBindingTags_TCL_DECLARED /* 28 */ EXTERN void TkFreeBindingTags(TkWindow *winPtr); -#endif -#ifndef TkpFreeCursor_TCL_DECLARED -#define TkpFreeCursor_TCL_DECLARED /* 29 */ EXTERN void TkpFreeCursor(TkCursor *cursorPtr); -#endif -#ifndef TkGetBitmapData_TCL_DECLARED -#define TkGetBitmapData_TCL_DECLARED /* 30 */ -EXTERN char * TkGetBitmapData(Tcl_Interp *interp, char *string, - char *fileName, int *widthPtr, - int *heightPtr, int *hotXPtr, int *hotYPtr); -#endif -#ifndef TkGetButtPoints_TCL_DECLARED -#define TkGetButtPoints_TCL_DECLARED +EXTERN char * TkGetBitmapData(Tcl_Interp *interp, + const char *string, const char *fileName, + int *widthPtr, int *heightPtr, int *hotXPtr, + int *hotYPtr); /* 31 */ EXTERN void TkGetButtPoints(double p1[], double p2[], double width, int project, double m1[], double m2[]); -#endif -#ifndef TkGetCursorByName_TCL_DECLARED -#define TkGetCursorByName_TCL_DECLARED /* 32 */ EXTERN TkCursor * TkGetCursorByName(Tcl_Interp *interp, Tk_Window tkwin, Tk_Uid string); -#endif -#ifndef TkGetDefaultScreenName_TCL_DECLARED -#define TkGetDefaultScreenName_TCL_DECLARED /* 33 */ -EXTERN CONST84_RETURN char * TkGetDefaultScreenName(Tcl_Interp *interp, - CONST char *screenName); -#endif -#ifndef TkGetDisplay_TCL_DECLARED -#define TkGetDisplay_TCL_DECLARED +EXTERN const char * TkGetDefaultScreenName(Tcl_Interp *interp, + const char *screenName); /* 34 */ EXTERN TkDisplay * TkGetDisplay(Display *display); -#endif -#ifndef TkGetDisplayOf_TCL_DECLARED -#define TkGetDisplayOf_TCL_DECLARED /* 35 */ EXTERN int TkGetDisplayOf(Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[], Tk_Window *tkwinPtr); -#endif -#ifndef TkGetFocusWin_TCL_DECLARED -#define TkGetFocusWin_TCL_DECLARED + Tcl_Obj *const objv[], Tk_Window *tkwinPtr); /* 36 */ EXTERN TkWindow * TkGetFocusWin(TkWindow *winPtr); -#endif -#ifndef TkGetInterpNames_TCL_DECLARED -#define TkGetInterpNames_TCL_DECLARED /* 37 */ EXTERN int TkGetInterpNames(Tcl_Interp *interp, Tk_Window tkwin); -#endif -#ifndef TkGetMiterPoints_TCL_DECLARED -#define TkGetMiterPoints_TCL_DECLARED /* 38 */ EXTERN int TkGetMiterPoints(double p1[], double p2[], double p3[], double width, double m1[], double m2[]); -#endif -#ifndef TkGetPointerCoords_TCL_DECLARED -#define TkGetPointerCoords_TCL_DECLARED /* 39 */ EXTERN void TkGetPointerCoords(Tk_Window tkwin, int *xPtr, int *yPtr); -#endif -#ifndef TkGetServerInfo_TCL_DECLARED -#define TkGetServerInfo_TCL_DECLARED /* 40 */ EXTERN void TkGetServerInfo(Tcl_Interp *interp, Tk_Window tkwin); -#endif -#ifndef TkGrabDeadWindow_TCL_DECLARED -#define TkGrabDeadWindow_TCL_DECLARED /* 41 */ EXTERN void TkGrabDeadWindow(TkWindow *winPtr); -#endif -#ifndef TkGrabState_TCL_DECLARED -#define TkGrabState_TCL_DECLARED /* 42 */ EXTERN int TkGrabState(TkWindow *winPtr); -#endif -#ifndef TkIncludePoint_TCL_DECLARED -#define TkIncludePoint_TCL_DECLARED /* 43 */ EXTERN void TkIncludePoint(Tk_Item *itemPtr, double *pointPtr); -#endif -#ifndef TkInOutEvents_TCL_DECLARED -#define TkInOutEvents_TCL_DECLARED /* 44 */ EXTERN void TkInOutEvents(XEvent *eventPtr, TkWindow *sourcePtr, TkWindow *destPtr, int leaveType, int enterType, Tcl_QueuePosition position); -#endif -#ifndef TkInstallFrameMenu_TCL_DECLARED -#define TkInstallFrameMenu_TCL_DECLARED /* 45 */ EXTERN void TkInstallFrameMenu(Tk_Window tkwin); -#endif -#ifndef TkKeysymToString_TCL_DECLARED -#define TkKeysymToString_TCL_DECLARED /* 46 */ -EXTERN char * TkKeysymToString(KeySym keysym); -#endif -#ifndef TkLineToArea_TCL_DECLARED -#define TkLineToArea_TCL_DECLARED +EXTERN CONST86 char * TkKeysymToString(KeySym keysym); /* 47 */ EXTERN int TkLineToArea(double end1Ptr[], double end2Ptr[], double rectPtr[]); -#endif -#ifndef TkLineToPoint_TCL_DECLARED -#define TkLineToPoint_TCL_DECLARED /* 48 */ EXTERN double TkLineToPoint(double end1Ptr[], double end2Ptr[], double pointPtr[]); -#endif -#ifndef TkMakeBezierCurve_TCL_DECLARED -#define TkMakeBezierCurve_TCL_DECLARED /* 49 */ EXTERN int TkMakeBezierCurve(Tk_Canvas canvas, double *pointPtr, int numPoints, int numSteps, XPoint xPoints[], double dblPoints[]); -#endif -#ifndef TkMakeBezierPostscript_TCL_DECLARED -#define TkMakeBezierPostscript_TCL_DECLARED /* 50 */ EXTERN void TkMakeBezierPostscript(Tcl_Interp *interp, Tk_Canvas canvas, double *pointPtr, int numPoints); -#endif -#ifndef TkOptionClassChanged_TCL_DECLARED -#define TkOptionClassChanged_TCL_DECLARED /* 51 */ EXTERN void TkOptionClassChanged(TkWindow *winPtr); -#endif -#ifndef TkOptionDeadWindow_TCL_DECLARED -#define TkOptionDeadWindow_TCL_DECLARED /* 52 */ EXTERN void TkOptionDeadWindow(TkWindow *winPtr); -#endif -#ifndef TkOvalToArea_TCL_DECLARED -#define TkOvalToArea_TCL_DECLARED /* 53 */ EXTERN int TkOvalToArea(double *ovalPtr, double *rectPtr); -#endif -#ifndef TkOvalToPoint_TCL_DECLARED -#define TkOvalToPoint_TCL_DECLARED /* 54 */ EXTERN double TkOvalToPoint(double ovalPtr[], double width, int filled, double pointPtr[]); -#endif -#ifndef TkpChangeFocus_TCL_DECLARED -#define TkpChangeFocus_TCL_DECLARED /* 55 */ EXTERN int TkpChangeFocus(TkWindow *winPtr, int force); -#endif -#ifndef TkpCloseDisplay_TCL_DECLARED -#define TkpCloseDisplay_TCL_DECLARED /* 56 */ EXTERN void TkpCloseDisplay(TkDisplay *dispPtr); -#endif -#ifndef TkpClaimFocus_TCL_DECLARED -#define TkpClaimFocus_TCL_DECLARED /* 57 */ EXTERN void TkpClaimFocus(TkWindow *topLevelPtr, int force); -#endif -#ifndef TkpDisplayWarning_TCL_DECLARED -#define TkpDisplayWarning_TCL_DECLARED /* 58 */ -EXTERN void TkpDisplayWarning(CONST char *msg, CONST char *title); -#endif -#ifndef TkpGetAppName_TCL_DECLARED -#define TkpGetAppName_TCL_DECLARED +EXTERN void TkpDisplayWarning(const char *msg, const char *title); /* 59 */ EXTERN void TkpGetAppName(Tcl_Interp *interp, Tcl_DString *name); -#endif -#ifndef TkpGetOtherWindow_TCL_DECLARED -#define TkpGetOtherWindow_TCL_DECLARED /* 60 */ EXTERN TkWindow * TkpGetOtherWindow(TkWindow *winPtr); -#endif -#ifndef TkpGetWrapperWindow_TCL_DECLARED -#define TkpGetWrapperWindow_TCL_DECLARED /* 61 */ EXTERN TkWindow * TkpGetWrapperWindow(TkWindow *winPtr); -#endif -#ifndef TkpInit_TCL_DECLARED -#define TkpInit_TCL_DECLARED /* 62 */ EXTERN int TkpInit(Tcl_Interp *interp); -#endif -#ifndef TkpInitializeMenuBindings_TCL_DECLARED -#define TkpInitializeMenuBindings_TCL_DECLARED /* 63 */ EXTERN void TkpInitializeMenuBindings(Tcl_Interp *interp, Tk_BindingTable bindingTable); -#endif -#ifndef TkpMakeContainer_TCL_DECLARED -#define TkpMakeContainer_TCL_DECLARED /* 64 */ EXTERN void TkpMakeContainer(Tk_Window tkwin); -#endif -#ifndef TkpMakeMenuWindow_TCL_DECLARED -#define TkpMakeMenuWindow_TCL_DECLARED /* 65 */ EXTERN void TkpMakeMenuWindow(Tk_Window tkwin, int transient); -#endif -#ifndef TkpMakeWindow_TCL_DECLARED -#define TkpMakeWindow_TCL_DECLARED /* 66 */ EXTERN Window TkpMakeWindow(TkWindow *winPtr, Window parent); -#endif -#ifndef TkpMenuNotifyToplevelCreate_TCL_DECLARED -#define TkpMenuNotifyToplevelCreate_TCL_DECLARED /* 67 */ EXTERN void TkpMenuNotifyToplevelCreate(Tcl_Interp *interp, - char *menuName); -#endif -#ifndef TkpOpenDisplay_TCL_DECLARED -#define TkpOpenDisplay_TCL_DECLARED + const char *menuName); /* 68 */ -EXTERN TkDisplay * TkpOpenDisplay(CONST char *display_name); -#endif -#ifndef TkPointerEvent_TCL_DECLARED -#define TkPointerEvent_TCL_DECLARED +EXTERN TkDisplay * TkpOpenDisplay(const char *display_name); /* 69 */ EXTERN int TkPointerEvent(XEvent *eventPtr, TkWindow *winPtr); -#endif -#ifndef TkPolygonToArea_TCL_DECLARED -#define TkPolygonToArea_TCL_DECLARED /* 70 */ EXTERN int TkPolygonToArea(double *polyPtr, int numPoints, double *rectPtr); -#endif -#ifndef TkPolygonToPoint_TCL_DECLARED -#define TkPolygonToPoint_TCL_DECLARED /* 71 */ EXTERN double TkPolygonToPoint(double *polyPtr, int numPoints, double *pointPtr); -#endif -#ifndef TkPositionInTree_TCL_DECLARED -#define TkPositionInTree_TCL_DECLARED /* 72 */ EXTERN int TkPositionInTree(TkWindow *winPtr, TkWindow *treePtr); -#endif -#ifndef TkpRedirectKeyEvent_TCL_DECLARED -#define TkpRedirectKeyEvent_TCL_DECLARED /* 73 */ EXTERN void TkpRedirectKeyEvent(TkWindow *winPtr, XEvent *eventPtr); -#endif -#ifndef TkpSetMainMenubar_TCL_DECLARED -#define TkpSetMainMenubar_TCL_DECLARED /* 74 */ EXTERN void TkpSetMainMenubar(Tcl_Interp *interp, - Tk_Window tkwin, char *menuName); -#endif -#ifndef TkpUseWindow_TCL_DECLARED -#define TkpUseWindow_TCL_DECLARED + Tk_Window tkwin, const char *menuName); /* 75 */ EXTERN int TkpUseWindow(Tcl_Interp *interp, Tk_Window tkwin, - CONST char *string); -#endif -#ifndef TkpWindowWasRecentlyDeleted_TCL_DECLARED -#define TkpWindowWasRecentlyDeleted_TCL_DECLARED -/* 76 */ -EXTERN int TkpWindowWasRecentlyDeleted(Window win, - TkDisplay *dispPtr); -#endif -#ifndef TkQueueEventForAllChildren_TCL_DECLARED -#define TkQueueEventForAllChildren_TCL_DECLARED + const char *string); +/* Slot 76 is reserved */ /* 77 */ EXTERN void TkQueueEventForAllChildren(TkWindow *winPtr, XEvent *eventPtr); -#endif -#ifndef TkReadBitmapFile_TCL_DECLARED -#define TkReadBitmapFile_TCL_DECLARED /* 78 */ EXTERN int TkReadBitmapFile(Display *display, Drawable d, - CONST char *filename, + const char *filename, unsigned int *width_return, unsigned int *height_return, Pixmap *bitmap_return, int *x_hot_return, int *y_hot_return); -#endif -#ifndef TkScrollWindow_TCL_DECLARED -#define TkScrollWindow_TCL_DECLARED /* 79 */ EXTERN int TkScrollWindow(Tk_Window tkwin, GC gc, int x, int y, int width, int height, int dx, int dy, TkRegion damageRgn); -#endif -#ifndef TkSelDeadWindow_TCL_DECLARED -#define TkSelDeadWindow_TCL_DECLARED /* 80 */ EXTERN void TkSelDeadWindow(TkWindow *winPtr); -#endif -#ifndef TkSelEventProc_TCL_DECLARED -#define TkSelEventProc_TCL_DECLARED /* 81 */ EXTERN void TkSelEventProc(Tk_Window tkwin, XEvent *eventPtr); -#endif -#ifndef TkSelInit_TCL_DECLARED -#define TkSelInit_TCL_DECLARED /* 82 */ EXTERN void TkSelInit(Tk_Window tkwin); -#endif -#ifndef TkSelPropProc_TCL_DECLARED -#define TkSelPropProc_TCL_DECLARED /* 83 */ EXTERN void TkSelPropProc(XEvent *eventPtr); -#endif /* Slot 84 is reserved */ -#ifndef TkSetWindowMenuBar_TCL_DECLARED -#define TkSetWindowMenuBar_TCL_DECLARED /* 85 */ EXTERN void TkSetWindowMenuBar(Tcl_Interp *interp, - Tk_Window tkwin, char *oldMenuName, - char *menuName); -#endif -#ifndef TkStringToKeysym_TCL_DECLARED -#define TkStringToKeysym_TCL_DECLARED + Tk_Window tkwin, const char *oldMenuName, + const char *menuName); /* 86 */ -EXTERN KeySym TkStringToKeysym(char *name); -#endif -#ifndef TkThickPolyLineToArea_TCL_DECLARED -#define TkThickPolyLineToArea_TCL_DECLARED +EXTERN KeySym TkStringToKeysym(const char *name); /* 87 */ EXTERN int TkThickPolyLineToArea(double *coordPtr, int numPoints, double width, int capStyle, int joinStyle, double *rectPtr); -#endif -#ifndef TkWmAddToColormapWindows_TCL_DECLARED -#define TkWmAddToColormapWindows_TCL_DECLARED /* 88 */ EXTERN void TkWmAddToColormapWindows(TkWindow *winPtr); -#endif -#ifndef TkWmDeadWindow_TCL_DECLARED -#define TkWmDeadWindow_TCL_DECLARED /* 89 */ EXTERN void TkWmDeadWindow(TkWindow *winPtr); -#endif -#ifndef TkWmFocusToplevel_TCL_DECLARED -#define TkWmFocusToplevel_TCL_DECLARED /* 90 */ EXTERN TkWindow * TkWmFocusToplevel(TkWindow *winPtr); -#endif -#ifndef TkWmMapWindow_TCL_DECLARED -#define TkWmMapWindow_TCL_DECLARED /* 91 */ EXTERN void TkWmMapWindow(TkWindow *winPtr); -#endif -#ifndef TkWmNewWindow_TCL_DECLARED -#define TkWmNewWindow_TCL_DECLARED /* 92 */ EXTERN void TkWmNewWindow(TkWindow *winPtr); -#endif -#ifndef TkWmProtocolEventProc_TCL_DECLARED -#define TkWmProtocolEventProc_TCL_DECLARED /* 93 */ EXTERN void TkWmProtocolEventProc(TkWindow *winPtr, XEvent *evenvPtr); -#endif -#ifndef TkWmRemoveFromColormapWindows_TCL_DECLARED -#define TkWmRemoveFromColormapWindows_TCL_DECLARED /* 94 */ EXTERN void TkWmRemoveFromColormapWindows(TkWindow *winPtr); -#endif -#ifndef TkWmRestackToplevel_TCL_DECLARED -#define TkWmRestackToplevel_TCL_DECLARED /* 95 */ EXTERN void TkWmRestackToplevel(TkWindow *winPtr, int aboveBelow, TkWindow *otherPtr); -#endif -#ifndef TkWmSetClass_TCL_DECLARED -#define TkWmSetClass_TCL_DECLARED /* 96 */ EXTERN void TkWmSetClass(TkWindow *winPtr); -#endif -#ifndef TkWmUnmapWindow_TCL_DECLARED -#define TkWmUnmapWindow_TCL_DECLARED /* 97 */ EXTERN void TkWmUnmapWindow(TkWindow *winPtr); -#endif -#ifndef TkDebugBitmap_TCL_DECLARED -#define TkDebugBitmap_TCL_DECLARED /* 98 */ -EXTERN Tcl_Obj * TkDebugBitmap(Tk_Window tkwin, char *name); -#endif -#ifndef TkDebugBorder_TCL_DECLARED -#define TkDebugBorder_TCL_DECLARED +EXTERN Tcl_Obj * TkDebugBitmap(Tk_Window tkwin, const char *name); /* 99 */ -EXTERN Tcl_Obj * TkDebugBorder(Tk_Window tkwin, char *name); -#endif -#ifndef TkDebugCursor_TCL_DECLARED -#define TkDebugCursor_TCL_DECLARED +EXTERN Tcl_Obj * TkDebugBorder(Tk_Window tkwin, const char *name); /* 100 */ -EXTERN Tcl_Obj * TkDebugCursor(Tk_Window tkwin, char *name); -#endif -#ifndef TkDebugColor_TCL_DECLARED -#define TkDebugColor_TCL_DECLARED +EXTERN Tcl_Obj * TkDebugCursor(Tk_Window tkwin, const char *name); /* 101 */ -EXTERN Tcl_Obj * TkDebugColor(Tk_Window tkwin, char *name); -#endif -#ifndef TkDebugConfig_TCL_DECLARED -#define TkDebugConfig_TCL_DECLARED +EXTERN Tcl_Obj * TkDebugColor(Tk_Window tkwin, const char *name); /* 102 */ EXTERN Tcl_Obj * TkDebugConfig(Tcl_Interp *interp, Tk_OptionTable table); -#endif -#ifndef TkDebugFont_TCL_DECLARED -#define TkDebugFont_TCL_DECLARED /* 103 */ -EXTERN Tcl_Obj * TkDebugFont(Tk_Window tkwin, char *name); -#endif -#ifndef TkFindStateNumObj_TCL_DECLARED -#define TkFindStateNumObj_TCL_DECLARED +EXTERN Tcl_Obj * TkDebugFont(Tk_Window tkwin, const char *name); /* 104 */ EXTERN int TkFindStateNumObj(Tcl_Interp *interp, - Tcl_Obj *optionPtr, CONST TkStateMap *mapPtr, + Tcl_Obj *optionPtr, const TkStateMap *mapPtr, Tcl_Obj *keyPtr); -#endif -#ifndef TkGetBitmapPredefTable_TCL_DECLARED -#define TkGetBitmapPredefTable_TCL_DECLARED /* 105 */ EXTERN Tcl_HashTable * TkGetBitmapPredefTable(void); -#endif -#ifndef TkGetDisplayList_TCL_DECLARED -#define TkGetDisplayList_TCL_DECLARED /* 106 */ EXTERN TkDisplay * TkGetDisplayList(void); -#endif -#ifndef TkGetMainInfoList_TCL_DECLARED -#define TkGetMainInfoList_TCL_DECLARED /* 107 */ EXTERN TkMainInfo * TkGetMainInfoList(void); -#endif -#ifndef TkGetWindowFromObj_TCL_DECLARED -#define TkGetWindowFromObj_TCL_DECLARED /* 108 */ EXTERN int TkGetWindowFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, Tk_Window *windowPtr); -#endif -#ifndef TkpGetString_TCL_DECLARED -#define TkpGetString_TCL_DECLARED /* 109 */ -EXTERN char * TkpGetString(TkWindow *winPtr, XEvent *eventPtr, +EXTERN CONST86 char * TkpGetString(TkWindow *winPtr, XEvent *eventPtr, Tcl_DString *dsPtr); -#endif -#ifndef TkpGetSubFonts_TCL_DECLARED -#define TkpGetSubFonts_TCL_DECLARED /* 110 */ EXTERN void TkpGetSubFonts(Tcl_Interp *interp, Tk_Font tkfont); -#endif -#ifndef TkpGetSystemDefault_TCL_DECLARED -#define TkpGetSystemDefault_TCL_DECLARED /* 111 */ EXTERN Tcl_Obj * TkpGetSystemDefault(Tk_Window tkwin, - CONST char *dbName, CONST char *className); -#endif -#ifndef TkpMenuThreadInit_TCL_DECLARED -#define TkpMenuThreadInit_TCL_DECLARED + const char *dbName, const char *className); /* 112 */ EXTERN void TkpMenuThreadInit(void); -#endif -#ifndef TkClipBox_TCL_DECLARED -#define TkClipBox_TCL_DECLARED /* 113 */ EXTERN void TkClipBox(TkRegion rgn, XRectangle *rect_return); -#endif -#ifndef TkCreateRegion_TCL_DECLARED -#define TkCreateRegion_TCL_DECLARED /* 114 */ EXTERN TkRegion TkCreateRegion(void); -#endif -#ifndef TkDestroyRegion_TCL_DECLARED -#define TkDestroyRegion_TCL_DECLARED /* 115 */ EXTERN void TkDestroyRegion(TkRegion rgn); -#endif -#ifndef TkIntersectRegion_TCL_DECLARED -#define TkIntersectRegion_TCL_DECLARED /* 116 */ EXTERN void TkIntersectRegion(TkRegion sra, TkRegion srcb, TkRegion dr_return); -#endif -#ifndef TkRectInRegion_TCL_DECLARED -#define TkRectInRegion_TCL_DECLARED /* 117 */ EXTERN int TkRectInRegion(TkRegion rgn, int x, int y, unsigned int width, unsigned int height); -#endif -#ifndef TkSetRegion_TCL_DECLARED -#define TkSetRegion_TCL_DECLARED /* 118 */ EXTERN void TkSetRegion(Display *display, GC gc, TkRegion rgn); -#endif -#ifndef TkUnionRectWithRegion_TCL_DECLARED -#define TkUnionRectWithRegion_TCL_DECLARED /* 119 */ EXTERN void TkUnionRectWithRegion(XRectangle *rect, TkRegion src, TkRegion dr_return); -#endif /* Slot 120 is reserved */ #ifdef MAC_OSX_TK /* AQUA */ -#ifndef TkpCreateNativeBitmap_TCL_DECLARED -#define TkpCreateNativeBitmap_TCL_DECLARED /* 121 */ EXTERN Pixmap TkpCreateNativeBitmap(Display *display, - CONST char *source); -#endif + const void *source); #endif /* AQUA */ #ifdef MAC_OSX_TK /* AQUA */ -#ifndef TkpDefineNativeBitmaps_TCL_DECLARED -#define TkpDefineNativeBitmaps_TCL_DECLARED /* 122 */ EXTERN void TkpDefineNativeBitmaps(void); -#endif #endif /* AQUA */ /* Slot 123 is reserved */ #ifdef MAC_OSX_TK /* AQUA */ -#ifndef TkpGetNativeAppBitmap_TCL_DECLARED -#define TkpGetNativeAppBitmap_TCL_DECLARED /* 124 */ EXTERN Pixmap TkpGetNativeAppBitmap(Display *display, - CONST char *name, int *width, int *height); -#endif + const char *name, int *width, int *height); #endif /* AQUA */ /* Slot 125 is reserved */ /* Slot 126 is reserved */ @@ -743,265 +376,208 @@ EXTERN Pixmap TkpGetNativeAppBitmap(Display *display, /* Slot 132 is reserved */ /* Slot 133 is reserved */ /* Slot 134 is reserved */ -#ifndef TkpDrawHighlightBorder_TCL_DECLARED -#define TkpDrawHighlightBorder_TCL_DECLARED /* 135 */ EXTERN void TkpDrawHighlightBorder(Tk_Window tkwin, GC fgGC, GC bgGC, int highlightWidth, Drawable drawable); -#endif -#ifndef TkSetFocusWin_TCL_DECLARED -#define TkSetFocusWin_TCL_DECLARED /* 136 */ EXTERN void TkSetFocusWin(TkWindow *winPtr, int force); -#endif -#ifndef TkpSetKeycodeAndState_TCL_DECLARED -#define TkpSetKeycodeAndState_TCL_DECLARED /* 137 */ EXTERN void TkpSetKeycodeAndState(Tk_Window tkwin, KeySym keySym, XEvent *eventPtr); -#endif -#ifndef TkpGetKeySym_TCL_DECLARED -#define TkpGetKeySym_TCL_DECLARED /* 138 */ EXTERN KeySym TkpGetKeySym(TkDisplay *dispPtr, XEvent *eventPtr); -#endif -#ifndef TkpInitKeymapInfo_TCL_DECLARED -#define TkpInitKeymapInfo_TCL_DECLARED /* 139 */ EXTERN void TkpInitKeymapInfo(TkDisplay *dispPtr); -#endif -#ifndef TkPhotoGetValidRegion_TCL_DECLARED -#define TkPhotoGetValidRegion_TCL_DECLARED /* 140 */ EXTERN TkRegion TkPhotoGetValidRegion(Tk_PhotoHandle handle); -#endif -#ifndef TkWmStackorderToplevel_TCL_DECLARED -#define TkWmStackorderToplevel_TCL_DECLARED /* 141 */ EXTERN TkWindow ** TkWmStackorderToplevel(TkWindow *parentPtr); -#endif -#ifndef TkFocusFree_TCL_DECLARED -#define TkFocusFree_TCL_DECLARED /* 142 */ EXTERN void TkFocusFree(TkMainInfo *mainPtr); -#endif -#ifndef TkClipCleanup_TCL_DECLARED -#define TkClipCleanup_TCL_DECLARED /* 143 */ EXTERN void TkClipCleanup(TkDisplay *dispPtr); -#endif -#ifndef TkGCCleanup_TCL_DECLARED -#define TkGCCleanup_TCL_DECLARED /* 144 */ EXTERN void TkGCCleanup(TkDisplay *dispPtr); -#endif -#ifndef TkSubtractRegion_TCL_DECLARED -#define TkSubtractRegion_TCL_DECLARED /* 145 */ EXTERN void TkSubtractRegion(TkRegion sra, TkRegion srcb, TkRegion dr_return); -#endif -#ifndef TkStylePkgInit_TCL_DECLARED -#define TkStylePkgInit_TCL_DECLARED /* 146 */ EXTERN void TkStylePkgInit(TkMainInfo *mainPtr); -#endif -#ifndef TkStylePkgFree_TCL_DECLARED -#define TkStylePkgFree_TCL_DECLARED /* 147 */ EXTERN void TkStylePkgFree(TkMainInfo *mainPtr); -#endif -#ifndef TkToplevelWindowForCommand_TCL_DECLARED -#define TkToplevelWindowForCommand_TCL_DECLARED /* 148 */ EXTERN Tk_Window TkToplevelWindowForCommand(Tcl_Interp *interp, - CONST char *cmdName); -#endif -#ifndef TkGetOptionSpec_TCL_DECLARED -#define TkGetOptionSpec_TCL_DECLARED + const char *cmdName); /* 149 */ -EXTERN CONST Tk_OptionSpec * TkGetOptionSpec(CONST char *name, +EXTERN const Tk_OptionSpec * TkGetOptionSpec(const char *name, Tk_OptionTable optionTable); -#endif -#ifndef TkMakeRawCurve_TCL_DECLARED -#define TkMakeRawCurve_TCL_DECLARED /* 150 */ EXTERN int TkMakeRawCurve(Tk_Canvas canvas, double *pointPtr, int numPoints, int numSteps, XPoint xPoints[], double dblPoints[]); -#endif -#ifndef TkMakeRawCurvePostscript_TCL_DECLARED -#define TkMakeRawCurvePostscript_TCL_DECLARED /* 151 */ EXTERN void TkMakeRawCurvePostscript(Tcl_Interp *interp, Tk_Canvas canvas, double *pointPtr, int numPoints); -#endif -#ifndef TkpDrawFrame_TCL_DECLARED -#define TkpDrawFrame_TCL_DECLARED /* 152 */ EXTERN void TkpDrawFrame(Tk_Window tkwin, Tk_3DBorder border, int highlightWidth, int borderWidth, int relief); -#endif -#ifndef TkCreateThreadExitHandler_TCL_DECLARED -#define TkCreateThreadExitHandler_TCL_DECLARED /* 153 */ EXTERN void TkCreateThreadExitHandler(Tcl_ExitProc *proc, ClientData clientData); -#endif -#ifndef TkDeleteThreadExitHandler_TCL_DECLARED -#define TkDeleteThreadExitHandler_TCL_DECLARED /* 154 */ EXTERN void TkDeleteThreadExitHandler(Tcl_ExitProc *proc, ClientData clientData); -#endif /* Slot 155 is reserved */ -#ifndef TkpTestembedCmd_TCL_DECLARED -#define TkpTestembedCmd_TCL_DECLARED /* 156 */ EXTERN int TkpTestembedCmd(ClientData clientData, - Tcl_Interp *interp, int argc, - CONST char **argv); -#endif -#ifndef TkpTesttextCmd_TCL_DECLARED -#define TkpTesttextCmd_TCL_DECLARED + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); /* 157 */ EXTERN int TkpTesttextCmd(ClientData dummy, Tcl_Interp *interp, - int argc, CONST char **argv); -#endif -/* Slot 158 is reserved */ -/* Slot 159 is reserved */ -/* Slot 160 is reserved */ -/* Slot 161 is reserved */ -/* Slot 162 is reserved */ -/* Slot 163 is reserved */ -/* Slot 164 is reserved */ -/* Slot 165 is reserved */ -/* Slot 166 is reserved */ -/* Slot 167 is reserved */ -/* Slot 168 is reserved */ -#ifndef TkStateParseProc_TCL_DECLARED -#define TkStateParseProc_TCL_DECLARED + int objc, Tcl_Obj *const objv[]); +/* 158 */ +EXTERN int TkSelGetSelection(Tcl_Interp *interp, + Tk_Window tkwin, Atom selection, Atom target, + Tk_GetSelProc *proc, ClientData clientData); +/* 159 */ +EXTERN int TkTextGetIndex(Tcl_Interp *interp, + struct TkText *textPtr, const char *string, + struct TkTextIndex *indexPtr); +/* 160 */ +EXTERN int TkTextIndexBackBytes(const struct TkText *textPtr, + const struct TkTextIndex *srcPtr, int count, + struct TkTextIndex *dstPtr); +/* 161 */ +EXTERN int TkTextIndexForwBytes(const struct TkText *textPtr, + const struct TkTextIndex *srcPtr, int count, + struct TkTextIndex *dstPtr); +/* 162 */ +EXTERN struct TkTextIndex * TkTextMakeByteIndex(TkTextBTree tree, + const struct TkText *textPtr, int lineIndex, + int byteIndex, struct TkTextIndex *indexPtr); +/* 163 */ +EXTERN int TkTextPrintIndex(const struct TkText *textPtr, + const struct TkTextIndex *indexPtr, + char *string); +/* 164 */ +EXTERN struct TkTextSegment * TkTextSetMark(struct TkText *textPtr, + const char *name, + struct TkTextIndex *indexPtr); +/* 165 */ +EXTERN int TkTextXviewCmd(struct TkText *textPtr, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +/* 166 */ +EXTERN void TkTextChanged(struct TkSharedText *sharedTextPtr, + struct TkText *textPtr, + const struct TkTextIndex *index1Ptr, + const struct TkTextIndex *index2Ptr); +/* 167 */ +EXTERN int TkBTreeNumLines(TkTextBTree tree, + const struct TkText *textPtr); +/* 168 */ +EXTERN void TkTextInsertDisplayProc(struct TkText *textPtr, + struct TkTextDispChunk *chunkPtr, int x, + int y, int height, int baseline, + Display *display, Drawable dst, int screenY); /* 169 */ EXTERN int TkStateParseProc(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, - CONST char *value, char *widgRec, int offset); -#endif -#ifndef TkStatePrintProc_TCL_DECLARED -#define TkStatePrintProc_TCL_DECLARED + const char *value, char *widgRec, int offset); /* 170 */ -EXTERN char * TkStatePrintProc(ClientData clientData, +EXTERN CONST86 char * TkStatePrintProc(ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); -#endif -#ifndef TkCanvasDashParseProc_TCL_DECLARED -#define TkCanvasDashParseProc_TCL_DECLARED /* 171 */ EXTERN int TkCanvasDashParseProc(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, - CONST char *value, char *widgRec, int offset); -#endif -#ifndef TkCanvasDashPrintProc_TCL_DECLARED -#define TkCanvasDashPrintProc_TCL_DECLARED + const char *value, char *widgRec, int offset); /* 172 */ -EXTERN char * TkCanvasDashPrintProc(ClientData clientData, +EXTERN CONST86 char * TkCanvasDashPrintProc(ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); -#endif -#ifndef TkOffsetParseProc_TCL_DECLARED -#define TkOffsetParseProc_TCL_DECLARED /* 173 */ EXTERN int TkOffsetParseProc(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, - CONST char *value, char *widgRec, int offset); -#endif -#ifndef TkOffsetPrintProc_TCL_DECLARED -#define TkOffsetPrintProc_TCL_DECLARED + const char *value, char *widgRec, int offset); /* 174 */ -EXTERN char * TkOffsetPrintProc(ClientData clientData, +EXTERN CONST86 char * TkOffsetPrintProc(ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); -#endif -#ifndef TkPixelParseProc_TCL_DECLARED -#define TkPixelParseProc_TCL_DECLARED /* 175 */ EXTERN int TkPixelParseProc(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, - CONST char *value, char *widgRec, int offset); -#endif -#ifndef TkPixelPrintProc_TCL_DECLARED -#define TkPixelPrintProc_TCL_DECLARED + const char *value, char *widgRec, int offset); /* 176 */ -EXTERN char * TkPixelPrintProc(ClientData clientData, +EXTERN CONST86 char * TkPixelPrintProc(ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); -#endif -#ifndef TkOrientParseProc_TCL_DECLARED -#define TkOrientParseProc_TCL_DECLARED /* 177 */ EXTERN int TkOrientParseProc(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, - CONST char *value, char *widgRec, int offset); -#endif -#ifndef TkOrientPrintProc_TCL_DECLARED -#define TkOrientPrintProc_TCL_DECLARED + const char *value, char *widgRec, int offset); /* 178 */ -EXTERN char * TkOrientPrintProc(ClientData clientData, +EXTERN CONST86 char * TkOrientPrintProc(ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); -#endif -#ifndef TkSmoothParseProc_TCL_DECLARED -#define TkSmoothParseProc_TCL_DECLARED /* 179 */ EXTERN int TkSmoothParseProc(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, - CONST char *value, char *widgRec, int offset); -#endif -#ifndef TkSmoothPrintProc_TCL_DECLARED -#define TkSmoothPrintProc_TCL_DECLARED + const char *value, char *widgRec, int offset); /* 180 */ -EXTERN char * TkSmoothPrintProc(ClientData clientData, +EXTERN CONST86 char * TkSmoothPrintProc(ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); -#endif -/* Slot 181 is reserved */ -/* Slot 182 is reserved */ -/* Slot 183 is reserved */ -#ifndef TkUnusedStubEntry_TCL_DECLARED -#define TkUnusedStubEntry_TCL_DECLARED +/* 181 */ +EXTERN void TkDrawAngledTextLayout(Display *display, + Drawable drawable, GC gc, + Tk_TextLayout layout, int x, int y, + double angle, int firstChar, int lastChar); +/* 182 */ +EXTERN void TkUnderlineAngledTextLayout(Display *display, + Drawable drawable, GC gc, + Tk_TextLayout layout, int x, int y, + double angle, int underline); +/* 183 */ +EXTERN int TkIntersectAngledTextLayout(Tk_TextLayout layout, + int x, int y, int width, int height, + double angle); /* 184 */ -EXTERN void TkUnusedStubEntry(void); -#endif +EXTERN void TkDrawAngledChars(Display *display, + Drawable drawable, GC gc, Tk_Font tkfont, + const char *source, int numBytes, double x, + double y, double angle); typedef struct TkIntStubs { int magic; - struct TkIntStubHooks *hooks; + void *hooks; TkWindow * (*tkAllocWindow) (TkDisplay *dispPtr, int screenNum, TkWindow *parentPtr); /* 0 */ void (*tkBezierPoints) (double control[], int numSteps, double *coordPtr); /* 1 */ void (*tkBezierScreenPoints) (Tk_Canvas canvas, double control[], int numSteps, XPoint *xPointPtr); /* 2 */ - void (*tkBindDeadWindow) (TkWindow *winPtr); /* 3 */ + void (*reserved3)(void); void (*tkBindEventProc) (TkWindow *winPtr, XEvent *eventPtr); /* 4 */ void (*tkBindFree) (TkMainInfo *mainPtr); /* 5 */ void (*tkBindInit) (TkMainInfo *mainPtr); /* 6 */ void (*tkChangeEventWindow) (XEvent *eventPtr, TkWindow *winPtr); /* 7 */ int (*tkClipInit) (Tcl_Interp *interp, TkDisplay *dispPtr); /* 8 */ void (*tkComputeAnchor) (Tk_Anchor anchor, Tk_Window tkwin, int padX, int padY, int innerWidth, int innerHeight, int *xPtr, int *yPtr); /* 9 */ - int (*tkCopyAndGlobalEval) (Tcl_Interp *interp, char *script); /* 10 */ - unsigned long (*tkCreateBindingProcedure) (Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object, CONST char *eventString, TkBindEvalProc *evalProc, TkBindFreeProc *freeProc, ClientData clientData); /* 11 */ - TkCursor * (*tkCreateCursorFromData) (Tk_Window tkwin, CONST char *source, CONST char *mask, int width, int height, int xHot, int yHot, XColor fg, XColor bg); /* 12 */ - int (*tkCreateFrame) (ClientData clientData, Tcl_Interp *interp, int argc, char **argv, int toplevel, char *appName); /* 13 */ - Tk_Window (*tkCreateMainWindow) (Tcl_Interp *interp, CONST char *screenName, char *baseName); /* 14 */ + void (*reserved10)(void); + void (*reserved11)(void); + TkCursor * (*tkCreateCursorFromData) (Tk_Window tkwin, const char *source, const char *mask, int width, int height, int xHot, int yHot, XColor fg, XColor bg); /* 12 */ + int (*tkCreateFrame) (ClientData clientData, Tcl_Interp *interp, int argc, const char *const *argv, int toplevel, const char *appName); /* 13 */ + Tk_Window (*tkCreateMainWindow) (Tcl_Interp *interp, const char *screenName, const char *baseName); /* 14 */ Time (*tkCurrentTime) (TkDisplay *dispPtr); /* 15 */ void (*tkDeleteAllImages) (TkMainInfo *mainPtr); /* 16 */ void (*tkDoConfigureNotify) (TkWindow *winPtr); /* 17 */ void (*tkDrawInsetFocusHighlight) (Tk_Window tkwin, GC gc, int width, Drawable drawable, int padding); /* 18 */ void (*tkEventDeadWindow) (TkWindow *winPtr); /* 19 */ void (*tkFillPolygon) (Tk_Canvas canvas, double *coordPtr, int numPoints, Display *display, Drawable drawable, GC gc, GC outlineGC); /* 20 */ - int (*tkFindStateNum) (Tcl_Interp *interp, CONST char *option, CONST TkStateMap *mapPtr, CONST char *strKey); /* 21 */ - char * (*tkFindStateString) (CONST TkStateMap *mapPtr, int numKey); /* 22 */ + int (*tkFindStateNum) (Tcl_Interp *interp, const char *option, const TkStateMap *mapPtr, const char *strKey); /* 21 */ + CONST86 char * (*tkFindStateString) (const TkStateMap *mapPtr, int numKey); /* 22 */ void (*tkFocusDeadWindow) (TkWindow *winPtr); /* 23 */ int (*tkFocusFilterEvent) (TkWindow *winPtr, XEvent *eventPtr); /* 24 */ TkWindow * (*tkFocusKeyEvent) (TkWindow *winPtr, XEvent *eventPtr); /* 25 */ @@ -1009,12 +585,12 @@ typedef struct TkIntStubs { void (*tkFontPkgFree) (TkMainInfo *mainPtr); /* 27 */ void (*tkFreeBindingTags) (TkWindow *winPtr); /* 28 */ void (*tkpFreeCursor) (TkCursor *cursorPtr); /* 29 */ - char * (*tkGetBitmapData) (Tcl_Interp *interp, char *string, char *fileName, int *widthPtr, int *heightPtr, int *hotXPtr, int *hotYPtr); /* 30 */ + char * (*tkGetBitmapData) (Tcl_Interp *interp, const char *string, const char *fileName, int *widthPtr, int *heightPtr, int *hotXPtr, int *hotYPtr); /* 30 */ void (*tkGetButtPoints) (double p1[], double p2[], double width, int project, double m1[], double m2[]); /* 31 */ TkCursor * (*tkGetCursorByName) (Tcl_Interp *interp, Tk_Window tkwin, Tk_Uid string); /* 32 */ - CONST84_RETURN char * (*tkGetDefaultScreenName) (Tcl_Interp *interp, CONST char *screenName); /* 33 */ + const char * (*tkGetDefaultScreenName) (Tcl_Interp *interp, const char *screenName); /* 33 */ TkDisplay * (*tkGetDisplay) (Display *display); /* 34 */ - int (*tkGetDisplayOf) (Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], Tk_Window *tkwinPtr); /* 35 */ + int (*tkGetDisplayOf) (Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], Tk_Window *tkwinPtr); /* 35 */ TkWindow * (*tkGetFocusWin) (TkWindow *winPtr); /* 36 */ int (*tkGetInterpNames) (Tcl_Interp *interp, Tk_Window tkwin); /* 37 */ int (*tkGetMiterPoints) (double p1[], double p2[], double p3[], double width, double m1[], double m2[]); /* 38 */ @@ -1025,7 +601,7 @@ typedef struct TkIntStubs { void (*tkIncludePoint) (Tk_Item *itemPtr, double *pointPtr); /* 43 */ void (*tkInOutEvents) (XEvent *eventPtr, TkWindow *sourcePtr, TkWindow *destPtr, int leaveType, int enterType, Tcl_QueuePosition position); /* 44 */ void (*tkInstallFrameMenu) (Tk_Window tkwin); /* 45 */ - char * (*tkKeysymToString) (KeySym keysym); /* 46 */ + CONST86 char * (*tkKeysymToString) (KeySym keysym); /* 46 */ int (*tkLineToArea) (double end1Ptr[], double end2Ptr[], double rectPtr[]); /* 47 */ double (*tkLineToPoint) (double end1Ptr[], double end2Ptr[], double pointPtr[]); /* 48 */ int (*tkMakeBezierCurve) (Tk_Canvas canvas, double *pointPtr, int numPoints, int numSteps, XPoint xPoints[], double dblPoints[]); /* 49 */ @@ -1037,7 +613,7 @@ typedef struct TkIntStubs { int (*tkpChangeFocus) (TkWindow *winPtr, int force); /* 55 */ void (*tkpCloseDisplay) (TkDisplay *dispPtr); /* 56 */ void (*tkpClaimFocus) (TkWindow *topLevelPtr, int force); /* 57 */ - void (*tkpDisplayWarning) (CONST char *msg, CONST char *title); /* 58 */ + void (*tkpDisplayWarning) (const char *msg, const char *title); /* 58 */ void (*tkpGetAppName) (Tcl_Interp *interp, Tcl_DString *name); /* 59 */ TkWindow * (*tkpGetOtherWindow) (TkWindow *winPtr); /* 60 */ TkWindow * (*tkpGetWrapperWindow) (TkWindow *winPtr); /* 61 */ @@ -1046,26 +622,26 @@ typedef struct TkIntStubs { void (*tkpMakeContainer) (Tk_Window tkwin); /* 64 */ void (*tkpMakeMenuWindow) (Tk_Window tkwin, int transient); /* 65 */ Window (*tkpMakeWindow) (TkWindow *winPtr, Window parent); /* 66 */ - void (*tkpMenuNotifyToplevelCreate) (Tcl_Interp *interp, char *menuName); /* 67 */ - TkDisplay * (*tkpOpenDisplay) (CONST char *display_name); /* 68 */ + void (*tkpMenuNotifyToplevelCreate) (Tcl_Interp *interp, const char *menuName); /* 67 */ + TkDisplay * (*tkpOpenDisplay) (const char *display_name); /* 68 */ int (*tkPointerEvent) (XEvent *eventPtr, TkWindow *winPtr); /* 69 */ int (*tkPolygonToArea) (double *polyPtr, int numPoints, double *rectPtr); /* 70 */ double (*tkPolygonToPoint) (double *polyPtr, int numPoints, double *pointPtr); /* 71 */ int (*tkPositionInTree) (TkWindow *winPtr, TkWindow *treePtr); /* 72 */ void (*tkpRedirectKeyEvent) (TkWindow *winPtr, XEvent *eventPtr); /* 73 */ - void (*tkpSetMainMenubar) (Tcl_Interp *interp, Tk_Window tkwin, char *menuName); /* 74 */ - int (*tkpUseWindow) (Tcl_Interp *interp, Tk_Window tkwin, CONST char *string); /* 75 */ - int (*tkpWindowWasRecentlyDeleted) (Window win, TkDisplay *dispPtr); /* 76 */ + void (*tkpSetMainMenubar) (Tcl_Interp *interp, Tk_Window tkwin, const char *menuName); /* 74 */ + int (*tkpUseWindow) (Tcl_Interp *interp, Tk_Window tkwin, const char *string); /* 75 */ + void (*reserved76)(void); void (*tkQueueEventForAllChildren) (TkWindow *winPtr, XEvent *eventPtr); /* 77 */ - int (*tkReadBitmapFile) (Display *display, Drawable d, CONST char *filename, unsigned int *width_return, unsigned int *height_return, Pixmap *bitmap_return, int *x_hot_return, int *y_hot_return); /* 78 */ + int (*tkReadBitmapFile) (Display *display, Drawable d, const char *filename, unsigned int *width_return, unsigned int *height_return, Pixmap *bitmap_return, int *x_hot_return, int *y_hot_return); /* 78 */ int (*tkScrollWindow) (Tk_Window tkwin, GC gc, int x, int y, int width, int height, int dx, int dy, TkRegion damageRgn); /* 79 */ void (*tkSelDeadWindow) (TkWindow *winPtr); /* 80 */ void (*tkSelEventProc) (Tk_Window tkwin, XEvent *eventPtr); /* 81 */ void (*tkSelInit) (Tk_Window tkwin); /* 82 */ void (*tkSelPropProc) (XEvent *eventPtr); /* 83 */ - VOID *reserved84; - void (*tkSetWindowMenuBar) (Tcl_Interp *interp, Tk_Window tkwin, char *oldMenuName, char *menuName); /* 85 */ - KeySym (*tkStringToKeysym) (char *name); /* 86 */ + void (*reserved84)(void); + void (*tkSetWindowMenuBar) (Tcl_Interp *interp, Tk_Window tkwin, const char *oldMenuName, const char *menuName); /* 85 */ + KeySym (*tkStringToKeysym) (const char *name); /* 86 */ int (*tkThickPolyLineToArea) (double *coordPtr, int numPoints, double width, int capStyle, int joinStyle, double *rectPtr); /* 87 */ void (*tkWmAddToColormapWindows) (TkWindow *winPtr); /* 88 */ void (*tkWmDeadWindow) (TkWindow *winPtr); /* 89 */ @@ -1077,20 +653,20 @@ typedef struct TkIntStubs { void (*tkWmRestackToplevel) (TkWindow *winPtr, int aboveBelow, TkWindow *otherPtr); /* 95 */ void (*tkWmSetClass) (TkWindow *winPtr); /* 96 */ void (*tkWmUnmapWindow) (TkWindow *winPtr); /* 97 */ - Tcl_Obj * (*tkDebugBitmap) (Tk_Window tkwin, char *name); /* 98 */ - Tcl_Obj * (*tkDebugBorder) (Tk_Window tkwin, char *name); /* 99 */ - Tcl_Obj * (*tkDebugCursor) (Tk_Window tkwin, char *name); /* 100 */ - Tcl_Obj * (*tkDebugColor) (Tk_Window tkwin, char *name); /* 101 */ + Tcl_Obj * (*tkDebugBitmap) (Tk_Window tkwin, const char *name); /* 98 */ + Tcl_Obj * (*tkDebugBorder) (Tk_Window tkwin, const char *name); /* 99 */ + Tcl_Obj * (*tkDebugCursor) (Tk_Window tkwin, const char *name); /* 100 */ + Tcl_Obj * (*tkDebugColor) (Tk_Window tkwin, const char *name); /* 101 */ Tcl_Obj * (*tkDebugConfig) (Tcl_Interp *interp, Tk_OptionTable table); /* 102 */ - Tcl_Obj * (*tkDebugFont) (Tk_Window tkwin, char *name); /* 103 */ - int (*tkFindStateNumObj) (Tcl_Interp *interp, Tcl_Obj *optionPtr, CONST TkStateMap *mapPtr, Tcl_Obj *keyPtr); /* 104 */ + Tcl_Obj * (*tkDebugFont) (Tk_Window tkwin, const char *name); /* 103 */ + int (*tkFindStateNumObj) (Tcl_Interp *interp, Tcl_Obj *optionPtr, const TkStateMap *mapPtr, Tcl_Obj *keyPtr); /* 104 */ Tcl_HashTable * (*tkGetBitmapPredefTable) (void); /* 105 */ TkDisplay * (*tkGetDisplayList) (void); /* 106 */ TkMainInfo * (*tkGetMainInfoList) (void); /* 107 */ int (*tkGetWindowFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, Tk_Window *windowPtr); /* 108 */ - char * (*tkpGetString) (TkWindow *winPtr, XEvent *eventPtr, Tcl_DString *dsPtr); /* 109 */ + CONST86 char * (*tkpGetString) (TkWindow *winPtr, XEvent *eventPtr, Tcl_DString *dsPtr); /* 109 */ void (*tkpGetSubFonts) (Tcl_Interp *interp, Tk_Font tkfont); /* 110 */ - Tcl_Obj * (*tkpGetSystemDefault) (Tk_Window tkwin, CONST char *dbName, CONST char *className); /* 111 */ + Tcl_Obj * (*tkpGetSystemDefault) (Tk_Window tkwin, const char *dbName, const char *className); /* 111 */ void (*tkpMenuThreadInit) (void); /* 112 */ void (*tkClipBox) (TkRegion rgn, XRectangle *rect_return); /* 113 */ TkRegion (*tkCreateRegion) (void); /* 114 */ @@ -1099,48 +675,48 @@ typedef struct TkIntStubs { int (*tkRectInRegion) (TkRegion rgn, int x, int y, unsigned int width, unsigned int height); /* 117 */ void (*tkSetRegion) (Display *display, GC gc, TkRegion rgn); /* 118 */ void (*tkUnionRectWithRegion) (XRectangle *rect, TkRegion src, TkRegion dr_return); /* 119 */ - VOID *reserved120; -#if !(defined(__WIN32__) || defined(MAC_OSX_TK)) /* X11 */ - VOID *reserved121; + void (*reserved120)(void); +#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */ + void (*reserved121)(void); #endif /* X11 */ -#if defined(__WIN32__) /* WIN */ - VOID *reserved121; +#if defined(_WIN32) /* WIN */ + void (*reserved121)(void); #endif /* WIN */ #ifdef MAC_OSX_TK /* AQUA */ - VOID *reserved121; /* Dummy entry for stubs table backwards compatibility */ - Pixmap (*tkpCreateNativeBitmap) (Display *display, CONST char *source); /* 121 */ + void (*reserved121)(void); /* Dummy entry for stubs table backwards compatibility */ + Pixmap (*tkpCreateNativeBitmap) (Display *display, const void *source); /* 121 */ #endif /* AQUA */ -#if !(defined(__WIN32__) || defined(MAC_OSX_TK)) /* X11 */ - VOID *reserved122; +#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */ + void (*reserved122)(void); #endif /* X11 */ -#if defined(__WIN32__) /* WIN */ - VOID *reserved122; +#if defined(_WIN32) /* WIN */ + void (*reserved122)(void); #endif /* WIN */ #ifdef MAC_OSX_TK /* AQUA */ - VOID *reserved122; /* Dummy entry for stubs table backwards compatibility */ + void (*reserved122)(void); /* Dummy entry for stubs table backwards compatibility */ void (*tkpDefineNativeBitmaps) (void); /* 122 */ #endif /* AQUA */ - VOID *reserved123; -#if !(defined(__WIN32__) || defined(MAC_OSX_TK)) /* X11 */ - VOID *reserved124; + void (*reserved123)(void); +#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */ + void (*reserved124)(void); #endif /* X11 */ -#if defined(__WIN32__) /* WIN */ - VOID *reserved124; +#if defined(_WIN32) /* WIN */ + void (*reserved124)(void); #endif /* WIN */ #ifdef MAC_OSX_TK /* AQUA */ - VOID *reserved124; /* Dummy entry for stubs table backwards compatibility */ - Pixmap (*tkpGetNativeAppBitmap) (Display *display, CONST char *name, int *width, int *height); /* 124 */ + void (*reserved124)(void); /* Dummy entry for stubs table backwards compatibility */ + Pixmap (*tkpGetNativeAppBitmap) (Display *display, const char *name, int *width, int *height); /* 124 */ #endif /* AQUA */ - VOID *reserved125; - VOID *reserved126; - VOID *reserved127; - VOID *reserved128; - VOID *reserved129; - VOID *reserved130; - VOID *reserved131; - VOID *reserved132; - VOID *reserved133; - VOID *reserved134; + void (*reserved125)(void); + void (*reserved126)(void); + void (*reserved127)(void); + void (*reserved128)(void); + void (*reserved129)(void); + void (*reserved130)(void); + void (*reserved131)(void); + void (*reserved132)(void); + void (*reserved133)(void); + void (*reserved134)(void); void (*tkpDrawHighlightBorder) (Tk_Window tkwin, GC fgGC, GC bgGC, int highlightWidth, Drawable drawable); /* 135 */ void (*tkSetFocusWin) (TkWindow *winPtr, int force); /* 136 */ void (*tkpSetKeycodeAndState) (Tk_Window tkwin, KeySym keySym, XEvent *eventPtr); /* 137 */ @@ -1154,553 +730,305 @@ typedef struct TkIntStubs { void (*tkSubtractRegion) (TkRegion sra, TkRegion srcb, TkRegion dr_return); /* 145 */ void (*tkStylePkgInit) (TkMainInfo *mainPtr); /* 146 */ void (*tkStylePkgFree) (TkMainInfo *mainPtr); /* 147 */ - Tk_Window (*tkToplevelWindowForCommand) (Tcl_Interp *interp, CONST char *cmdName); /* 148 */ - CONST Tk_OptionSpec * (*tkGetOptionSpec) (CONST char *name, Tk_OptionTable optionTable); /* 149 */ + Tk_Window (*tkToplevelWindowForCommand) (Tcl_Interp *interp, const char *cmdName); /* 148 */ + const Tk_OptionSpec * (*tkGetOptionSpec) (const char *name, Tk_OptionTable optionTable); /* 149 */ int (*tkMakeRawCurve) (Tk_Canvas canvas, double *pointPtr, int numPoints, int numSteps, XPoint xPoints[], double dblPoints[]); /* 150 */ void (*tkMakeRawCurvePostscript) (Tcl_Interp *interp, Tk_Canvas canvas, double *pointPtr, int numPoints); /* 151 */ void (*tkpDrawFrame) (Tk_Window tkwin, Tk_3DBorder border, int highlightWidth, int borderWidth, int relief); /* 152 */ void (*tkCreateThreadExitHandler) (Tcl_ExitProc *proc, ClientData clientData); /* 153 */ void (*tkDeleteThreadExitHandler) (Tcl_ExitProc *proc, ClientData clientData); /* 154 */ - VOID *reserved155; - int (*tkpTestembedCmd) (ClientData clientData, Tcl_Interp *interp, int argc, CONST char **argv); /* 156 */ - int (*tkpTesttextCmd) (ClientData dummy, Tcl_Interp *interp, int argc, CONST char **argv); /* 157 */ - VOID *reserved158; - VOID *reserved159; - VOID *reserved160; - VOID *reserved161; - VOID *reserved162; - VOID *reserved163; - VOID *reserved164; - VOID *reserved165; - VOID *reserved166; - VOID *reserved167; - VOID *reserved168; - int (*tkStateParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, CONST char *value, char *widgRec, int offset); /* 169 */ - char * (*tkStatePrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 170 */ - int (*tkCanvasDashParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, CONST char *value, char *widgRec, int offset); /* 171 */ - char * (*tkCanvasDashPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 172 */ - int (*tkOffsetParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, CONST char *value, char *widgRec, int offset); /* 173 */ - char * (*tkOffsetPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 174 */ - int (*tkPixelParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, CONST char *value, char *widgRec, int offset); /* 175 */ - char * (*tkPixelPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 176 */ - int (*tkOrientParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, CONST char *value, char *widgRec, int offset); /* 177 */ - char * (*tkOrientPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 178 */ - int (*tkSmoothParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, CONST char *value, char *widgRec, int offset); /* 179 */ - char * (*tkSmoothPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 180 */ - VOID *reserved181; - VOID *reserved182; - VOID *reserved183; - void (*tkUnusedStubEntry) (void); /* 184 */ + void (*reserved155)(void); + int (*tkpTestembedCmd) (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 156 */ + int (*tkpTesttextCmd) (ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 157 */ + int (*tkSelGetSelection) (Tcl_Interp *interp, Tk_Window tkwin, Atom selection, Atom target, Tk_GetSelProc *proc, ClientData clientData); /* 158 */ + int (*tkTextGetIndex) (Tcl_Interp *interp, struct TkText *textPtr, const char *string, struct TkTextIndex *indexPtr); /* 159 */ + int (*tkTextIndexBackBytes) (const struct TkText *textPtr, const struct TkTextIndex *srcPtr, int count, struct TkTextIndex *dstPtr); /* 160 */ + int (*tkTextIndexForwBytes) (const struct TkText *textPtr, const struct TkTextIndex *srcPtr, int count, struct TkTextIndex *dstPtr); /* 161 */ + struct TkTextIndex * (*tkTextMakeByteIndex) (TkTextBTree tree, const struct TkText *textPtr, int lineIndex, int byteIndex, struct TkTextIndex *indexPtr); /* 162 */ + int (*tkTextPrintIndex) (const struct TkText *textPtr, const struct TkTextIndex *indexPtr, char *string); /* 163 */ + struct TkTextSegment * (*tkTextSetMark) (struct TkText *textPtr, const char *name, struct TkTextIndex *indexPtr); /* 164 */ + int (*tkTextXviewCmd) (struct TkText *textPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 165 */ + void (*tkTextChanged) (struct TkSharedText *sharedTextPtr, struct TkText *textPtr, const struct TkTextIndex *index1Ptr, const struct TkTextIndex *index2Ptr); /* 166 */ + int (*tkBTreeNumLines) (TkTextBTree tree, const struct TkText *textPtr); /* 167 */ + void (*tkTextInsertDisplayProc) (struct TkText *textPtr, struct TkTextDispChunk *chunkPtr, int x, int y, int height, int baseline, Display *display, Drawable dst, int screenY); /* 168 */ + int (*tkStateParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 169 */ + CONST86 char * (*tkStatePrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 170 */ + int (*tkCanvasDashParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 171 */ + CONST86 char * (*tkCanvasDashPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 172 */ + int (*tkOffsetParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 173 */ + CONST86 char * (*tkOffsetPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 174 */ + int (*tkPixelParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 175 */ + CONST86 char * (*tkPixelPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 176 */ + int (*tkOrientParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 177 */ + CONST86 char * (*tkOrientPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 178 */ + int (*tkSmoothParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 179 */ + CONST86 char * (*tkSmoothPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 180 */ + void (*tkDrawAngledTextLayout) (Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, double angle, int firstChar, int lastChar); /* 181 */ + void (*tkUnderlineAngledTextLayout) (Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, double angle, int underline); /* 182 */ + int (*tkIntersectAngledTextLayout) (Tk_TextLayout layout, int x, int y, int width, int height, double angle); /* 183 */ + void (*tkDrawAngledChars) (Display *display, Drawable drawable, GC gc, Tk_Font tkfont, const char *source, int numBytes, double x, double y, double angle); /* 184 */ } TkIntStubs; -extern TkIntStubs *tkIntStubsPtr; +extern const TkIntStubs *tkIntStubsPtr; #ifdef __cplusplus } #endif -#if defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS) +#if defined(USE_TK_STUBS) /* * Inline function declarations: */ -#ifndef TkAllocWindow #define TkAllocWindow \ (tkIntStubsPtr->tkAllocWindow) /* 0 */ -#endif -#ifndef TkBezierPoints #define TkBezierPoints \ (tkIntStubsPtr->tkBezierPoints) /* 1 */ -#endif -#ifndef TkBezierScreenPoints #define TkBezierScreenPoints \ (tkIntStubsPtr->tkBezierScreenPoints) /* 2 */ -#endif -#ifndef TkBindDeadWindow -#define TkBindDeadWindow \ - (tkIntStubsPtr->tkBindDeadWindow) /* 3 */ -#endif -#ifndef TkBindEventProc +/* Slot 3 is reserved */ #define TkBindEventProc \ (tkIntStubsPtr->tkBindEventProc) /* 4 */ -#endif -#ifndef TkBindFree #define TkBindFree \ (tkIntStubsPtr->tkBindFree) /* 5 */ -#endif -#ifndef TkBindInit #define TkBindInit \ (tkIntStubsPtr->tkBindInit) /* 6 */ -#endif -#ifndef TkChangeEventWindow #define TkChangeEventWindow \ (tkIntStubsPtr->tkChangeEventWindow) /* 7 */ -#endif -#ifndef TkClipInit #define TkClipInit \ (tkIntStubsPtr->tkClipInit) /* 8 */ -#endif -#ifndef TkComputeAnchor #define TkComputeAnchor \ (tkIntStubsPtr->tkComputeAnchor) /* 9 */ -#endif -#ifndef TkCopyAndGlobalEval -#define TkCopyAndGlobalEval \ - (tkIntStubsPtr->tkCopyAndGlobalEval) /* 10 */ -#endif -#ifndef TkCreateBindingProcedure -#define TkCreateBindingProcedure \ - (tkIntStubsPtr->tkCreateBindingProcedure) /* 11 */ -#endif -#ifndef TkCreateCursorFromData +/* Slot 10 is reserved */ +/* Slot 11 is reserved */ #define TkCreateCursorFromData \ (tkIntStubsPtr->tkCreateCursorFromData) /* 12 */ -#endif -#ifndef TkCreateFrame #define TkCreateFrame \ (tkIntStubsPtr->tkCreateFrame) /* 13 */ -#endif -#ifndef TkCreateMainWindow #define TkCreateMainWindow \ (tkIntStubsPtr->tkCreateMainWindow) /* 14 */ -#endif -#ifndef TkCurrentTime #define TkCurrentTime \ (tkIntStubsPtr->tkCurrentTime) /* 15 */ -#endif -#ifndef TkDeleteAllImages #define TkDeleteAllImages \ (tkIntStubsPtr->tkDeleteAllImages) /* 16 */ -#endif -#ifndef TkDoConfigureNotify #define TkDoConfigureNotify \ (tkIntStubsPtr->tkDoConfigureNotify) /* 17 */ -#endif -#ifndef TkDrawInsetFocusHighlight #define TkDrawInsetFocusHighlight \ (tkIntStubsPtr->tkDrawInsetFocusHighlight) /* 18 */ -#endif -#ifndef TkEventDeadWindow #define TkEventDeadWindow \ (tkIntStubsPtr->tkEventDeadWindow) /* 19 */ -#endif -#ifndef TkFillPolygon #define TkFillPolygon \ (tkIntStubsPtr->tkFillPolygon) /* 20 */ -#endif -#ifndef TkFindStateNum #define TkFindStateNum \ (tkIntStubsPtr->tkFindStateNum) /* 21 */ -#endif -#ifndef TkFindStateString #define TkFindStateString \ (tkIntStubsPtr->tkFindStateString) /* 22 */ -#endif -#ifndef TkFocusDeadWindow #define TkFocusDeadWindow \ (tkIntStubsPtr->tkFocusDeadWindow) /* 23 */ -#endif -#ifndef TkFocusFilterEvent #define TkFocusFilterEvent \ (tkIntStubsPtr->tkFocusFilterEvent) /* 24 */ -#endif -#ifndef TkFocusKeyEvent #define TkFocusKeyEvent \ (tkIntStubsPtr->tkFocusKeyEvent) /* 25 */ -#endif -#ifndef TkFontPkgInit #define TkFontPkgInit \ (tkIntStubsPtr->tkFontPkgInit) /* 26 */ -#endif -#ifndef TkFontPkgFree #define TkFontPkgFree \ (tkIntStubsPtr->tkFontPkgFree) /* 27 */ -#endif -#ifndef TkFreeBindingTags #define TkFreeBindingTags \ (tkIntStubsPtr->tkFreeBindingTags) /* 28 */ -#endif -#ifndef TkpFreeCursor #define TkpFreeCursor \ (tkIntStubsPtr->tkpFreeCursor) /* 29 */ -#endif -#ifndef TkGetBitmapData #define TkGetBitmapData \ (tkIntStubsPtr->tkGetBitmapData) /* 30 */ -#endif -#ifndef TkGetButtPoints #define TkGetButtPoints \ (tkIntStubsPtr->tkGetButtPoints) /* 31 */ -#endif -#ifndef TkGetCursorByName #define TkGetCursorByName \ (tkIntStubsPtr->tkGetCursorByName) /* 32 */ -#endif -#ifndef TkGetDefaultScreenName #define TkGetDefaultScreenName \ (tkIntStubsPtr->tkGetDefaultScreenName) /* 33 */ -#endif -#ifndef TkGetDisplay #define TkGetDisplay \ (tkIntStubsPtr->tkGetDisplay) /* 34 */ -#endif -#ifndef TkGetDisplayOf #define TkGetDisplayOf \ (tkIntStubsPtr->tkGetDisplayOf) /* 35 */ -#endif -#ifndef TkGetFocusWin #define TkGetFocusWin \ (tkIntStubsPtr->tkGetFocusWin) /* 36 */ -#endif -#ifndef TkGetInterpNames #define TkGetInterpNames \ (tkIntStubsPtr->tkGetInterpNames) /* 37 */ -#endif -#ifndef TkGetMiterPoints #define TkGetMiterPoints \ (tkIntStubsPtr->tkGetMiterPoints) /* 38 */ -#endif -#ifndef TkGetPointerCoords #define TkGetPointerCoords \ (tkIntStubsPtr->tkGetPointerCoords) /* 39 */ -#endif -#ifndef TkGetServerInfo #define TkGetServerInfo \ (tkIntStubsPtr->tkGetServerInfo) /* 40 */ -#endif -#ifndef TkGrabDeadWindow #define TkGrabDeadWindow \ (tkIntStubsPtr->tkGrabDeadWindow) /* 41 */ -#endif -#ifndef TkGrabState #define TkGrabState \ (tkIntStubsPtr->tkGrabState) /* 42 */ -#endif -#ifndef TkIncludePoint #define TkIncludePoint \ (tkIntStubsPtr->tkIncludePoint) /* 43 */ -#endif -#ifndef TkInOutEvents #define TkInOutEvents \ (tkIntStubsPtr->tkInOutEvents) /* 44 */ -#endif -#ifndef TkInstallFrameMenu #define TkInstallFrameMenu \ (tkIntStubsPtr->tkInstallFrameMenu) /* 45 */ -#endif -#ifndef TkKeysymToString #define TkKeysymToString \ (tkIntStubsPtr->tkKeysymToString) /* 46 */ -#endif -#ifndef TkLineToArea #define TkLineToArea \ (tkIntStubsPtr->tkLineToArea) /* 47 */ -#endif -#ifndef TkLineToPoint #define TkLineToPoint \ (tkIntStubsPtr->tkLineToPoint) /* 48 */ -#endif -#ifndef TkMakeBezierCurve #define TkMakeBezierCurve \ (tkIntStubsPtr->tkMakeBezierCurve) /* 49 */ -#endif -#ifndef TkMakeBezierPostscript #define TkMakeBezierPostscript \ (tkIntStubsPtr->tkMakeBezierPostscript) /* 50 */ -#endif -#ifndef TkOptionClassChanged #define TkOptionClassChanged \ (tkIntStubsPtr->tkOptionClassChanged) /* 51 */ -#endif -#ifndef TkOptionDeadWindow #define TkOptionDeadWindow \ (tkIntStubsPtr->tkOptionDeadWindow) /* 52 */ -#endif -#ifndef TkOvalToArea #define TkOvalToArea \ (tkIntStubsPtr->tkOvalToArea) /* 53 */ -#endif -#ifndef TkOvalToPoint #define TkOvalToPoint \ (tkIntStubsPtr->tkOvalToPoint) /* 54 */ -#endif -#ifndef TkpChangeFocus #define TkpChangeFocus \ (tkIntStubsPtr->tkpChangeFocus) /* 55 */ -#endif -#ifndef TkpCloseDisplay #define TkpCloseDisplay \ (tkIntStubsPtr->tkpCloseDisplay) /* 56 */ -#endif -#ifndef TkpClaimFocus #define TkpClaimFocus \ (tkIntStubsPtr->tkpClaimFocus) /* 57 */ -#endif -#ifndef TkpDisplayWarning #define TkpDisplayWarning \ (tkIntStubsPtr->tkpDisplayWarning) /* 58 */ -#endif -#ifndef TkpGetAppName #define TkpGetAppName \ (tkIntStubsPtr->tkpGetAppName) /* 59 */ -#endif -#ifndef TkpGetOtherWindow #define TkpGetOtherWindow \ (tkIntStubsPtr->tkpGetOtherWindow) /* 60 */ -#endif -#ifndef TkpGetWrapperWindow #define TkpGetWrapperWindow \ (tkIntStubsPtr->tkpGetWrapperWindow) /* 61 */ -#endif -#ifndef TkpInit #define TkpInit \ (tkIntStubsPtr->tkpInit) /* 62 */ -#endif -#ifndef TkpInitializeMenuBindings #define TkpInitializeMenuBindings \ (tkIntStubsPtr->tkpInitializeMenuBindings) /* 63 */ -#endif -#ifndef TkpMakeContainer #define TkpMakeContainer \ (tkIntStubsPtr->tkpMakeContainer) /* 64 */ -#endif -#ifndef TkpMakeMenuWindow #define TkpMakeMenuWindow \ (tkIntStubsPtr->tkpMakeMenuWindow) /* 65 */ -#endif -#ifndef TkpMakeWindow #define TkpMakeWindow \ (tkIntStubsPtr->tkpMakeWindow) /* 66 */ -#endif -#ifndef TkpMenuNotifyToplevelCreate #define TkpMenuNotifyToplevelCreate \ (tkIntStubsPtr->tkpMenuNotifyToplevelCreate) /* 67 */ -#endif -#ifndef TkpOpenDisplay #define TkpOpenDisplay \ (tkIntStubsPtr->tkpOpenDisplay) /* 68 */ -#endif -#ifndef TkPointerEvent #define TkPointerEvent \ (tkIntStubsPtr->tkPointerEvent) /* 69 */ -#endif -#ifndef TkPolygonToArea #define TkPolygonToArea \ (tkIntStubsPtr->tkPolygonToArea) /* 70 */ -#endif -#ifndef TkPolygonToPoint #define TkPolygonToPoint \ (tkIntStubsPtr->tkPolygonToPoint) /* 71 */ -#endif -#ifndef TkPositionInTree #define TkPositionInTree \ (tkIntStubsPtr->tkPositionInTree) /* 72 */ -#endif -#ifndef TkpRedirectKeyEvent #define TkpRedirectKeyEvent \ (tkIntStubsPtr->tkpRedirectKeyEvent) /* 73 */ -#endif -#ifndef TkpSetMainMenubar #define TkpSetMainMenubar \ (tkIntStubsPtr->tkpSetMainMenubar) /* 74 */ -#endif -#ifndef TkpUseWindow #define TkpUseWindow \ (tkIntStubsPtr->tkpUseWindow) /* 75 */ -#endif -#ifndef TkpWindowWasRecentlyDeleted -#define TkpWindowWasRecentlyDeleted \ - (tkIntStubsPtr->tkpWindowWasRecentlyDeleted) /* 76 */ -#endif -#ifndef TkQueueEventForAllChildren +/* Slot 76 is reserved */ #define TkQueueEventForAllChildren \ (tkIntStubsPtr->tkQueueEventForAllChildren) /* 77 */ -#endif -#ifndef TkReadBitmapFile #define TkReadBitmapFile \ (tkIntStubsPtr->tkReadBitmapFile) /* 78 */ -#endif -#ifndef TkScrollWindow #define TkScrollWindow \ (tkIntStubsPtr->tkScrollWindow) /* 79 */ -#endif -#ifndef TkSelDeadWindow #define TkSelDeadWindow \ (tkIntStubsPtr->tkSelDeadWindow) /* 80 */ -#endif -#ifndef TkSelEventProc #define TkSelEventProc \ (tkIntStubsPtr->tkSelEventProc) /* 81 */ -#endif -#ifndef TkSelInit #define TkSelInit \ (tkIntStubsPtr->tkSelInit) /* 82 */ -#endif -#ifndef TkSelPropProc #define TkSelPropProc \ (tkIntStubsPtr->tkSelPropProc) /* 83 */ -#endif /* Slot 84 is reserved */ -#ifndef TkSetWindowMenuBar #define TkSetWindowMenuBar \ (tkIntStubsPtr->tkSetWindowMenuBar) /* 85 */ -#endif -#ifndef TkStringToKeysym #define TkStringToKeysym \ (tkIntStubsPtr->tkStringToKeysym) /* 86 */ -#endif -#ifndef TkThickPolyLineToArea #define TkThickPolyLineToArea \ (tkIntStubsPtr->tkThickPolyLineToArea) /* 87 */ -#endif -#ifndef TkWmAddToColormapWindows #define TkWmAddToColormapWindows \ (tkIntStubsPtr->tkWmAddToColormapWindows) /* 88 */ -#endif -#ifndef TkWmDeadWindow #define TkWmDeadWindow \ (tkIntStubsPtr->tkWmDeadWindow) /* 89 */ -#endif -#ifndef TkWmFocusToplevel #define TkWmFocusToplevel \ (tkIntStubsPtr->tkWmFocusToplevel) /* 90 */ -#endif -#ifndef TkWmMapWindow #define TkWmMapWindow \ (tkIntStubsPtr->tkWmMapWindow) /* 91 */ -#endif -#ifndef TkWmNewWindow #define TkWmNewWindow \ (tkIntStubsPtr->tkWmNewWindow) /* 92 */ -#endif -#ifndef TkWmProtocolEventProc #define TkWmProtocolEventProc \ (tkIntStubsPtr->tkWmProtocolEventProc) /* 93 */ -#endif -#ifndef TkWmRemoveFromColormapWindows #define TkWmRemoveFromColormapWindows \ (tkIntStubsPtr->tkWmRemoveFromColormapWindows) /* 94 */ -#endif -#ifndef TkWmRestackToplevel #define TkWmRestackToplevel \ (tkIntStubsPtr->tkWmRestackToplevel) /* 95 */ -#endif -#ifndef TkWmSetClass #define TkWmSetClass \ (tkIntStubsPtr->tkWmSetClass) /* 96 */ -#endif -#ifndef TkWmUnmapWindow #define TkWmUnmapWindow \ (tkIntStubsPtr->tkWmUnmapWindow) /* 97 */ -#endif -#ifndef TkDebugBitmap #define TkDebugBitmap \ (tkIntStubsPtr->tkDebugBitmap) /* 98 */ -#endif -#ifndef TkDebugBorder #define TkDebugBorder \ (tkIntStubsPtr->tkDebugBorder) /* 99 */ -#endif -#ifndef TkDebugCursor #define TkDebugCursor \ (tkIntStubsPtr->tkDebugCursor) /* 100 */ -#endif -#ifndef TkDebugColor #define TkDebugColor \ (tkIntStubsPtr->tkDebugColor) /* 101 */ -#endif -#ifndef TkDebugConfig #define TkDebugConfig \ (tkIntStubsPtr->tkDebugConfig) /* 102 */ -#endif -#ifndef TkDebugFont #define TkDebugFont \ (tkIntStubsPtr->tkDebugFont) /* 103 */ -#endif -#ifndef TkFindStateNumObj #define TkFindStateNumObj \ (tkIntStubsPtr->tkFindStateNumObj) /* 104 */ -#endif -#ifndef TkGetBitmapPredefTable #define TkGetBitmapPredefTable \ (tkIntStubsPtr->tkGetBitmapPredefTable) /* 105 */ -#endif -#ifndef TkGetDisplayList #define TkGetDisplayList \ (tkIntStubsPtr->tkGetDisplayList) /* 106 */ -#endif -#ifndef TkGetMainInfoList #define TkGetMainInfoList \ (tkIntStubsPtr->tkGetMainInfoList) /* 107 */ -#endif -#ifndef TkGetWindowFromObj #define TkGetWindowFromObj \ (tkIntStubsPtr->tkGetWindowFromObj) /* 108 */ -#endif -#ifndef TkpGetString #define TkpGetString \ (tkIntStubsPtr->tkpGetString) /* 109 */ -#endif -#ifndef TkpGetSubFonts #define TkpGetSubFonts \ (tkIntStubsPtr->tkpGetSubFonts) /* 110 */ -#endif -#ifndef TkpGetSystemDefault #define TkpGetSystemDefault \ (tkIntStubsPtr->tkpGetSystemDefault) /* 111 */ -#endif -#ifndef TkpMenuThreadInit #define TkpMenuThreadInit \ (tkIntStubsPtr->tkpMenuThreadInit) /* 112 */ -#endif -#ifndef TkClipBox #define TkClipBox \ (tkIntStubsPtr->tkClipBox) /* 113 */ -#endif -#ifndef TkCreateRegion #define TkCreateRegion \ (tkIntStubsPtr->tkCreateRegion) /* 114 */ -#endif -#ifndef TkDestroyRegion #define TkDestroyRegion \ (tkIntStubsPtr->tkDestroyRegion) /* 115 */ -#endif -#ifndef TkIntersectRegion #define TkIntersectRegion \ (tkIntStubsPtr->tkIntersectRegion) /* 116 */ -#endif -#ifndef TkRectInRegion #define TkRectInRegion \ (tkIntStubsPtr->tkRectInRegion) /* 117 */ -#endif -#ifndef TkSetRegion #define TkSetRegion \ (tkIntStubsPtr->tkSetRegion) /* 118 */ -#endif -#ifndef TkUnionRectWithRegion #define TkUnionRectWithRegion \ (tkIntStubsPtr->tkUnionRectWithRegion) /* 119 */ -#endif /* Slot 120 is reserved */ #ifdef MAC_OSX_TK /* AQUA */ -#ifndef TkpCreateNativeBitmap #define TkpCreateNativeBitmap \ (tkIntStubsPtr->tkpCreateNativeBitmap) /* 121 */ -#endif #endif /* AQUA */ #ifdef MAC_OSX_TK /* AQUA */ -#ifndef TkpDefineNativeBitmaps #define TkpDefineNativeBitmaps \ (tkIntStubsPtr->tkpDefineNativeBitmaps) /* 122 */ -#endif #endif /* AQUA */ /* Slot 123 is reserved */ #ifdef MAC_OSX_TK /* AQUA */ -#ifndef TkpGetNativeAppBitmap #define TkpGetNativeAppBitmap \ (tkIntStubsPtr->tkpGetNativeAppBitmap) /* 124 */ -#endif #endif /* AQUA */ /* Slot 125 is reserved */ /* Slot 126 is reserved */ @@ -1712,201 +1040,140 @@ extern TkIntStubs *tkIntStubsPtr; /* Slot 132 is reserved */ /* Slot 133 is reserved */ /* Slot 134 is reserved */ -#ifndef TkpDrawHighlightBorder #define TkpDrawHighlightBorder \ (tkIntStubsPtr->tkpDrawHighlightBorder) /* 135 */ -#endif -#ifndef TkSetFocusWin #define TkSetFocusWin \ (tkIntStubsPtr->tkSetFocusWin) /* 136 */ -#endif -#ifndef TkpSetKeycodeAndState #define TkpSetKeycodeAndState \ (tkIntStubsPtr->tkpSetKeycodeAndState) /* 137 */ -#endif -#ifndef TkpGetKeySym #define TkpGetKeySym \ (tkIntStubsPtr->tkpGetKeySym) /* 138 */ -#endif -#ifndef TkpInitKeymapInfo #define TkpInitKeymapInfo \ (tkIntStubsPtr->tkpInitKeymapInfo) /* 139 */ -#endif -#ifndef TkPhotoGetValidRegion #define TkPhotoGetValidRegion \ (tkIntStubsPtr->tkPhotoGetValidRegion) /* 140 */ -#endif -#ifndef TkWmStackorderToplevel #define TkWmStackorderToplevel \ (tkIntStubsPtr->tkWmStackorderToplevel) /* 141 */ -#endif -#ifndef TkFocusFree #define TkFocusFree \ (tkIntStubsPtr->tkFocusFree) /* 142 */ -#endif -#ifndef TkClipCleanup #define TkClipCleanup \ (tkIntStubsPtr->tkClipCleanup) /* 143 */ -#endif -#ifndef TkGCCleanup #define TkGCCleanup \ (tkIntStubsPtr->tkGCCleanup) /* 144 */ -#endif -#ifndef TkSubtractRegion #define TkSubtractRegion \ (tkIntStubsPtr->tkSubtractRegion) /* 145 */ -#endif -#ifndef TkStylePkgInit #define TkStylePkgInit \ (tkIntStubsPtr->tkStylePkgInit) /* 146 */ -#endif -#ifndef TkStylePkgFree #define TkStylePkgFree \ (tkIntStubsPtr->tkStylePkgFree) /* 147 */ -#endif -#ifndef TkToplevelWindowForCommand #define TkToplevelWindowForCommand \ (tkIntStubsPtr->tkToplevelWindowForCommand) /* 148 */ -#endif -#ifndef TkGetOptionSpec #define TkGetOptionSpec \ (tkIntStubsPtr->tkGetOptionSpec) /* 149 */ -#endif -#ifndef TkMakeRawCurve #define TkMakeRawCurve \ (tkIntStubsPtr->tkMakeRawCurve) /* 150 */ -#endif -#ifndef TkMakeRawCurvePostscript #define TkMakeRawCurvePostscript \ (tkIntStubsPtr->tkMakeRawCurvePostscript) /* 151 */ -#endif -#ifndef TkpDrawFrame #define TkpDrawFrame \ (tkIntStubsPtr->tkpDrawFrame) /* 152 */ -#endif -#ifndef TkCreateThreadExitHandler #define TkCreateThreadExitHandler \ (tkIntStubsPtr->tkCreateThreadExitHandler) /* 153 */ -#endif -#ifndef TkDeleteThreadExitHandler #define TkDeleteThreadExitHandler \ (tkIntStubsPtr->tkDeleteThreadExitHandler) /* 154 */ -#endif /* Slot 155 is reserved */ -#ifndef TkpTestembedCmd #define TkpTestembedCmd \ (tkIntStubsPtr->tkpTestembedCmd) /* 156 */ -#endif -#ifndef TkpTesttextCmd #define TkpTesttextCmd \ (tkIntStubsPtr->tkpTesttextCmd) /* 157 */ -#endif -/* Slot 158 is reserved */ -/* Slot 159 is reserved */ -/* Slot 160 is reserved */ -/* Slot 161 is reserved */ -/* Slot 162 is reserved */ -/* Slot 163 is reserved */ -/* Slot 164 is reserved */ -/* Slot 165 is reserved */ -/* Slot 166 is reserved */ -/* Slot 167 is reserved */ -/* Slot 168 is reserved */ -#ifndef TkStateParseProc +#define TkSelGetSelection \ + (tkIntStubsPtr->tkSelGetSelection) /* 158 */ +#define TkTextGetIndex \ + (tkIntStubsPtr->tkTextGetIndex) /* 159 */ +#define TkTextIndexBackBytes \ + (tkIntStubsPtr->tkTextIndexBackBytes) /* 160 */ +#define TkTextIndexForwBytes \ + (tkIntStubsPtr->tkTextIndexForwBytes) /* 161 */ +#define TkTextMakeByteIndex \ + (tkIntStubsPtr->tkTextMakeByteIndex) /* 162 */ +#define TkTextPrintIndex \ + (tkIntStubsPtr->tkTextPrintIndex) /* 163 */ +#define TkTextSetMark \ + (tkIntStubsPtr->tkTextSetMark) /* 164 */ +#define TkTextXviewCmd \ + (tkIntStubsPtr->tkTextXviewCmd) /* 165 */ +#define TkTextChanged \ + (tkIntStubsPtr->tkTextChanged) /* 166 */ +#define TkBTreeNumLines \ + (tkIntStubsPtr->tkBTreeNumLines) /* 167 */ +#define TkTextInsertDisplayProc \ + (tkIntStubsPtr->tkTextInsertDisplayProc) /* 168 */ #define TkStateParseProc \ (tkIntStubsPtr->tkStateParseProc) /* 169 */ -#endif -#ifndef TkStatePrintProc #define TkStatePrintProc \ (tkIntStubsPtr->tkStatePrintProc) /* 170 */ -#endif -#ifndef TkCanvasDashParseProc #define TkCanvasDashParseProc \ (tkIntStubsPtr->tkCanvasDashParseProc) /* 171 */ -#endif -#ifndef TkCanvasDashPrintProc #define TkCanvasDashPrintProc \ (tkIntStubsPtr->tkCanvasDashPrintProc) /* 172 */ -#endif -#ifndef TkOffsetParseProc #define TkOffsetParseProc \ (tkIntStubsPtr->tkOffsetParseProc) /* 173 */ -#endif -#ifndef TkOffsetPrintProc #define TkOffsetPrintProc \ (tkIntStubsPtr->tkOffsetPrintProc) /* 174 */ -#endif -#ifndef TkPixelParseProc #define TkPixelParseProc \ (tkIntStubsPtr->tkPixelParseProc) /* 175 */ -#endif -#ifndef TkPixelPrintProc #define TkPixelPrintProc \ (tkIntStubsPtr->tkPixelPrintProc) /* 176 */ -#endif -#ifndef TkOrientParseProc #define TkOrientParseProc \ (tkIntStubsPtr->tkOrientParseProc) /* 177 */ -#endif -#ifndef TkOrientPrintProc #define TkOrientPrintProc \ (tkIntStubsPtr->tkOrientPrintProc) /* 178 */ -#endif -#ifndef TkSmoothParseProc #define TkSmoothParseProc \ (tkIntStubsPtr->tkSmoothParseProc) /* 179 */ -#endif -#ifndef TkSmoothPrintProc #define TkSmoothPrintProc \ (tkIntStubsPtr->tkSmoothPrintProc) /* 180 */ -#endif -/* Slot 181 is reserved */ -/* Slot 182 is reserved */ -/* Slot 183 is reserved */ -#ifndef TkUnusedStubEntry -#define TkUnusedStubEntry \ - (tkIntStubsPtr->tkUnusedStubEntry) /* 184 */ -#endif +#define TkDrawAngledTextLayout \ + (tkIntStubsPtr->tkDrawAngledTextLayout) /* 181 */ +#define TkUnderlineAngledTextLayout \ + (tkIntStubsPtr->tkUnderlineAngledTextLayout) /* 182 */ +#define TkIntersectAngledTextLayout \ + (tkIntStubsPtr->tkIntersectAngledTextLayout) /* 183 */ +#define TkDrawAngledChars \ + (tkIntStubsPtr->tkDrawAngledChars) /* 184 */ -#endif /* defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS) */ +#endif /* defined(USE_TK_STUBS) */ /* !END!: Do not edit above this line. */ #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT -#if !defined(__WIN32__) && !defined(__CYGWIN__) && !defined(MAC_OSX_TK) - /* - * These macros are just wrappers for the equivalent X Region calls. + * On X11, these macros are just wrappers for the equivalent X Region calls. */ -# undef TkClipBox -# undef TkCreateRegion -# undef TkDestroyRegion -# undef TkIntersectRegion -# undef TkRectInRegion -# undef TkSetRegion -# undef TkSubtractRegion -# undef TkUnionRectWithRegion +#if !(defined(_WIN32) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */ -# define TkClipBox(rgn, rect) XClipBox((Region) (rgn), (rect)) -# define TkCreateRegion() (TkRegion) XCreateRegion() -# define TkDestroyRegion(rgn) XDestroyRegion((Region) (rgn)) -# define TkIntersectRegion(a, b, r) XIntersectRegion((Region) (a), \ -(Region) (b), (Region) (r)) -# define TkRectInRegion(r, x, y, w, h) XRectInRegion((Region) (r), (x), (y), (w), (h)) -# define TkSetRegion(d, gc, rgn) XSetRegion((d), (gc), (Region) (rgn)) -# define TkSubtractRegion(a, b, r) XSubtractRegion((Region) (a), \ -(Region) (b), (Region) (r)) -# define TkUnionRectWithRegion(rect, src, ret) XUnionRectWithRegion((rect), \ -(Region) (src), (Region) (ret)) -#endif /* !__CYGWIN__*/ +#undef TkClipBox +#undef TkCreateRegion +#undef TkDestroyRegion +#undef TkIntersectRegion +#undef TkRectInRegion +#undef TkSetRegion +#undef TkSubtractRegion +#undef TkUnionRectWithRegion -#undef TkUnusedStubEntry -#if defined(__CYGWIN__) && defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS) -# undef TkBindDeadWindow -# define TkBindDeadWindow(winPtr) /* Removed from Cygwins stub table, just do nothing */ -#endif +#define TkClipBox(rgn, rect) XClipBox((Region) rgn, rect) +#define TkCreateRegion() (TkRegion) XCreateRegion() +#define TkDestroyRegion(rgn) XDestroyRegion((Region) rgn) +#define TkIntersectRegion(a, b, r) XIntersectRegion((Region) a, \ + (Region) b, (Region) r) +#define TkRectInRegion(r, x, y, w, h) XRectInRegion((Region) r, x, y, w, h) +#define TkSetRegion(d, gc, rgn) XSetRegion(d, gc, (Region) rgn) +#define TkSubtractRegion(a, b, r) XSubtractRegion((Region) a, \ + (Region) b, (Region) r) +#define TkUnionRectWithRegion(rect, src, ret) XUnionRectWithRegion(rect, \ + (Region) src, (Region) ret) + +#endif /* UNIX */ #endif /* _TKINTDECLS */ diff --git a/generic/tkIntPlatDecls.h b/generic/tkIntPlatDecls.h index 86127fe..26a5f46 100644 --- a/generic/tkIntPlatDecls.h +++ b/generic/tkIntPlatDecls.h @@ -34,602 +34,274 @@ extern "C" { * Exported function declarations: */ -#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */ -#ifndef TkAlignImageData_TCL_DECLARED -#define TkAlignImageData_TCL_DECLARED +#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ /* 0 */ EXTERN char * TkAlignImageData(XImage *image, int alignment, int bitOrder); -#endif /* Slot 1 is reserved */ -#ifndef TkGenerateActivateEvents_TCL_DECLARED -#define TkGenerateActivateEvents_TCL_DECLARED /* 2 */ EXTERN void TkGenerateActivateEvents(TkWindow *winPtr, int active); -#endif -#ifndef TkpGetMS_TCL_DECLARED -#define TkpGetMS_TCL_DECLARED /* 3 */ EXTERN unsigned long TkpGetMS(void); -#endif -#ifndef TkPointerDeadWindow_TCL_DECLARED -#define TkPointerDeadWindow_TCL_DECLARED /* 4 */ EXTERN void TkPointerDeadWindow(TkWindow *winPtr); -#endif -#ifndef TkpPrintWindowId_TCL_DECLARED -#define TkpPrintWindowId_TCL_DECLARED /* 5 */ EXTERN void TkpPrintWindowId(char *buf, Window window); -#endif -#ifndef TkpScanWindowId_TCL_DECLARED -#define TkpScanWindowId_TCL_DECLARED /* 6 */ EXTERN int TkpScanWindowId(Tcl_Interp *interp, - CONST char *string, Window *idPtr); -#endif -#ifndef TkpSetCapture_TCL_DECLARED -#define TkpSetCapture_TCL_DECLARED + const char *string, Window *idPtr); /* 7 */ EXTERN void TkpSetCapture(TkWindow *winPtr); -#endif -#ifndef TkpSetCursor_TCL_DECLARED -#define TkpSetCursor_TCL_DECLARED /* 8 */ EXTERN void TkpSetCursor(TkpCursor cursor); -#endif -#ifndef TkpWmSetState_TCL_DECLARED -#define TkpWmSetState_TCL_DECLARED /* 9 */ EXTERN int TkpWmSetState(TkWindow *winPtr, int state); -#endif -#ifndef TkSetPixmapColormap_TCL_DECLARED -#define TkSetPixmapColormap_TCL_DECLARED /* 10 */ EXTERN void TkSetPixmapColormap(Pixmap pixmap, Colormap colormap); -#endif -#ifndef TkWinCancelMouseTimer_TCL_DECLARED -#define TkWinCancelMouseTimer_TCL_DECLARED /* 11 */ EXTERN void TkWinCancelMouseTimer(void); -#endif -#ifndef TkWinClipboardRender_TCL_DECLARED -#define TkWinClipboardRender_TCL_DECLARED /* 12 */ EXTERN void TkWinClipboardRender(TkDisplay *dispPtr, UINT format); -#endif -#ifndef TkWinEmbeddedEventProc_TCL_DECLARED -#define TkWinEmbeddedEventProc_TCL_DECLARED /* 13 */ EXTERN LRESULT TkWinEmbeddedEventProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); -#endif -#ifndef TkWinFillRect_TCL_DECLARED -#define TkWinFillRect_TCL_DECLARED /* 14 */ EXTERN void TkWinFillRect(HDC dc, int x, int y, int width, int height, int pixel); -#endif -#ifndef TkWinGetBorderPixels_TCL_DECLARED -#define TkWinGetBorderPixels_TCL_DECLARED /* 15 */ EXTERN COLORREF TkWinGetBorderPixels(Tk_Window tkwin, Tk_3DBorder border, int which); -#endif -#ifndef TkWinGetDrawableDC_TCL_DECLARED -#define TkWinGetDrawableDC_TCL_DECLARED /* 16 */ EXTERN HDC TkWinGetDrawableDC(Display *display, Drawable d, TkWinDCState *state); -#endif -#ifndef TkWinGetModifierState_TCL_DECLARED -#define TkWinGetModifierState_TCL_DECLARED /* 17 */ EXTERN int TkWinGetModifierState(void); -#endif -#ifndef TkWinGetSystemPalette_TCL_DECLARED -#define TkWinGetSystemPalette_TCL_DECLARED /* 18 */ EXTERN HPALETTE TkWinGetSystemPalette(void); -#endif -#ifndef TkWinGetWrapperWindow_TCL_DECLARED -#define TkWinGetWrapperWindow_TCL_DECLARED /* 19 */ EXTERN HWND TkWinGetWrapperWindow(Tk_Window tkwin); -#endif -#ifndef TkWinHandleMenuEvent_TCL_DECLARED -#define TkWinHandleMenuEvent_TCL_DECLARED /* 20 */ EXTERN int TkWinHandleMenuEvent(HWND *phwnd, UINT *pMessage, WPARAM *pwParam, LPARAM *plParam, LRESULT *plResult); -#endif -#ifndef TkWinIndexOfColor_TCL_DECLARED -#define TkWinIndexOfColor_TCL_DECLARED /* 21 */ EXTERN int TkWinIndexOfColor(XColor *colorPtr); -#endif -#ifndef TkWinReleaseDrawableDC_TCL_DECLARED -#define TkWinReleaseDrawableDC_TCL_DECLARED /* 22 */ EXTERN void TkWinReleaseDrawableDC(Drawable d, HDC hdc, TkWinDCState *state); -#endif -#ifndef TkWinResendEvent_TCL_DECLARED -#define TkWinResendEvent_TCL_DECLARED /* 23 */ EXTERN LRESULT TkWinResendEvent(WNDPROC wndproc, HWND hwnd, XEvent *eventPtr); -#endif -#ifndef TkWinSelectPalette_TCL_DECLARED -#define TkWinSelectPalette_TCL_DECLARED /* 24 */ EXTERN HPALETTE TkWinSelectPalette(HDC dc, Colormap colormap); -#endif -#ifndef TkWinSetMenu_TCL_DECLARED -#define TkWinSetMenu_TCL_DECLARED /* 25 */ EXTERN void TkWinSetMenu(Tk_Window tkwin, HMENU hMenu); -#endif -#ifndef TkWinSetWindowPos_TCL_DECLARED -#define TkWinSetWindowPos_TCL_DECLARED /* 26 */ EXTERN void TkWinSetWindowPos(HWND hwnd, HWND siblingHwnd, int pos); -#endif -#ifndef TkWinWmCleanup_TCL_DECLARED -#define TkWinWmCleanup_TCL_DECLARED /* 27 */ EXTERN void TkWinWmCleanup(HINSTANCE hInstance); -#endif -#ifndef TkWinXCleanup_TCL_DECLARED -#define TkWinXCleanup_TCL_DECLARED /* 28 */ EXTERN void TkWinXCleanup(ClientData clientData); -#endif -#ifndef TkWinXInit_TCL_DECLARED -#define TkWinXInit_TCL_DECLARED /* 29 */ EXTERN void TkWinXInit(HINSTANCE hInstance); -#endif -#ifndef TkWinSetForegroundWindow_TCL_DECLARED -#define TkWinSetForegroundWindow_TCL_DECLARED /* 30 */ EXTERN void TkWinSetForegroundWindow(TkWindow *winPtr); -#endif -#ifndef TkWinDialogDebug_TCL_DECLARED -#define TkWinDialogDebug_TCL_DECLARED /* 31 */ EXTERN void TkWinDialogDebug(int debug); -#endif -#ifndef TkWinGetMenuSystemDefault_TCL_DECLARED -#define TkWinGetMenuSystemDefault_TCL_DECLARED /* 32 */ EXTERN Tcl_Obj * TkWinGetMenuSystemDefault(Tk_Window tkwin, - CONST char *dbName, CONST char *className); -#endif -#ifndef TkWinGetPlatformId_TCL_DECLARED -#define TkWinGetPlatformId_TCL_DECLARED + const char *dbName, const char *className); /* 33 */ EXTERN int TkWinGetPlatformId(void); -#endif -#ifndef TkWinSetHINSTANCE_TCL_DECLARED -#define TkWinSetHINSTANCE_TCL_DECLARED /* 34 */ EXTERN void TkWinSetHINSTANCE(HINSTANCE hInstance); -#endif -#ifndef TkWinGetPlatformTheme_TCL_DECLARED -#define TkWinGetPlatformTheme_TCL_DECLARED /* 35 */ EXTERN int TkWinGetPlatformTheme(void); -#endif -#ifndef TkWinChildProc_TCL_DECLARED -#define TkWinChildProc_TCL_DECLARED /* 36 */ EXTERN LRESULT __stdcall TkWinChildProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); -#endif -#ifndef TkCreateXEventSource_TCL_DECLARED -#define TkCreateXEventSource_TCL_DECLARED /* 37 */ EXTERN void TkCreateXEventSource(void); -#endif -#ifndef TkpCmapStressed_TCL_DECLARED -#define TkpCmapStressed_TCL_DECLARED /* 38 */ EXTERN int TkpCmapStressed(Tk_Window tkwin, Colormap colormap); -#endif -#ifndef TkpSync_TCL_DECLARED -#define TkpSync_TCL_DECLARED /* 39 */ EXTERN void TkpSync(Display *display); -#endif -#ifndef TkUnixContainerId_TCL_DECLARED -#define TkUnixContainerId_TCL_DECLARED /* 40 */ EXTERN Window TkUnixContainerId(TkWindow *winPtr); -#endif -#ifndef TkUnixDoOneXEvent_TCL_DECLARED -#define TkUnixDoOneXEvent_TCL_DECLARED /* 41 */ EXTERN int TkUnixDoOneXEvent(Tcl_Time *timePtr); -#endif -#ifndef TkUnixSetMenubar_TCL_DECLARED -#define TkUnixSetMenubar_TCL_DECLARED /* 42 */ EXTERN void TkUnixSetMenubar(Tk_Window tkwin, Tk_Window menubar); -#endif -#ifndef TkWmCleanup_TCL_DECLARED -#define TkWmCleanup_TCL_DECLARED /* 43 */ EXTERN void TkWmCleanup(TkDisplay *dispPtr); -#endif -#ifndef TkSendCleanup_TCL_DECLARED -#define TkSendCleanup_TCL_DECLARED /* 44 */ EXTERN void TkSendCleanup(TkDisplay *dispPtr); -#endif -#ifndef TkpTestsendCmd_TCL_DECLARED -#define TkpTestsendCmd_TCL_DECLARED /* 45 */ EXTERN int TkpTestsendCmd(ClientData clientData, - Tcl_Interp *interp, int argc, - CONST char **argv); -#endif + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); #endif /* WIN */ #ifdef MAC_OSX_TK /* AQUA */ -#ifndef TkGenerateActivateEvents_TCL_DECLARED -#define TkGenerateActivateEvents_TCL_DECLARED /* 0 */ EXTERN void TkGenerateActivateEvents(TkWindow *winPtr, int active); -#endif /* Slot 1 is reserved */ /* Slot 2 is reserved */ -#ifndef TkPointerDeadWindow_TCL_DECLARED -#define TkPointerDeadWindow_TCL_DECLARED /* 3 */ EXTERN void TkPointerDeadWindow(TkWindow *winPtr); -#endif -#ifndef TkpSetCapture_TCL_DECLARED -#define TkpSetCapture_TCL_DECLARED /* 4 */ EXTERN void TkpSetCapture(TkWindow *winPtr); -#endif -#ifndef TkpSetCursor_TCL_DECLARED -#define TkpSetCursor_TCL_DECLARED /* 5 */ EXTERN void TkpSetCursor(TkpCursor cursor); -#endif -#ifndef TkpWmSetState_TCL_DECLARED -#define TkpWmSetState_TCL_DECLARED /* 6 */ EXTERN void TkpWmSetState(TkWindow *winPtr, int state); -#endif -#ifndef TkAboutDlg_TCL_DECLARED -#define TkAboutDlg_TCL_DECLARED /* 7 */ EXTERN void TkAboutDlg(void); -#endif -#ifndef TkMacOSXButtonKeyState_TCL_DECLARED -#define TkMacOSXButtonKeyState_TCL_DECLARED /* 8 */ EXTERN unsigned int TkMacOSXButtonKeyState(void); -#endif -#ifndef TkMacOSXClearMenubarActive_TCL_DECLARED -#define TkMacOSXClearMenubarActive_TCL_DECLARED /* 9 */ EXTERN void TkMacOSXClearMenubarActive(void); -#endif -#ifndef TkMacOSXDispatchMenuEvent_TCL_DECLARED -#define TkMacOSXDispatchMenuEvent_TCL_DECLARED /* 10 */ EXTERN int TkMacOSXDispatchMenuEvent(int menuID, int index); -#endif -#ifndef TkMacOSXInstallCursor_TCL_DECLARED -#define TkMacOSXInstallCursor_TCL_DECLARED /* 11 */ EXTERN void TkMacOSXInstallCursor(int resizeOverride); -#endif -#ifndef TkMacOSXHandleTearoffMenu_TCL_DECLARED -#define TkMacOSXHandleTearoffMenu_TCL_DECLARED /* 12 */ EXTERN void TkMacOSXHandleTearoffMenu(void); -#endif /* Slot 13 is reserved */ -#ifndef TkMacOSXDoHLEvent_TCL_DECLARED -#define TkMacOSXDoHLEvent_TCL_DECLARED /* 14 */ -EXTERN int TkMacOSXDoHLEvent(VOID *theEvent); -#endif +EXTERN int TkMacOSXDoHLEvent(void *theEvent); /* Slot 15 is reserved */ -#ifndef TkMacOSXGetXWindow_TCL_DECLARED -#define TkMacOSXGetXWindow_TCL_DECLARED /* 16 */ -EXTERN Window TkMacOSXGetXWindow(VOID *macWinPtr); -#endif -#ifndef TkMacOSXGrowToplevel_TCL_DECLARED -#define TkMacOSXGrowToplevel_TCL_DECLARED +EXTERN Window TkMacOSXGetXWindow(void *macWinPtr); /* 17 */ -EXTERN int TkMacOSXGrowToplevel(VOID *whichWindow, XPoint start); -#endif -#ifndef TkMacOSXHandleMenuSelect_TCL_DECLARED -#define TkMacOSXHandleMenuSelect_TCL_DECLARED +EXTERN int TkMacOSXGrowToplevel(void *whichWindow, XPoint start); /* 18 */ EXTERN void TkMacOSXHandleMenuSelect(short theMenu, unsigned short theItem, int optionKeyPressed); -#endif /* Slot 19 is reserved */ /* Slot 20 is reserved */ -#ifndef TkMacOSXInvalidateWindow_TCL_DECLARED -#define TkMacOSXInvalidateWindow_TCL_DECLARED /* 21 */ EXTERN void TkMacOSXInvalidateWindow(MacDrawable *macWin, int flag); -#endif -#ifndef TkMacOSXIsCharacterMissing_TCL_DECLARED -#define TkMacOSXIsCharacterMissing_TCL_DECLARED /* 22 */ EXTERN int TkMacOSXIsCharacterMissing(Tk_Font tkfont, unsigned int searchChar); -#endif -#ifndef TkMacOSXMakeRealWindowExist_TCL_DECLARED -#define TkMacOSXMakeRealWindowExist_TCL_DECLARED /* 23 */ EXTERN void TkMacOSXMakeRealWindowExist(TkWindow *winPtr); -#endif -#ifndef TkMacOSXMakeStippleMap_TCL_DECLARED -#define TkMacOSXMakeStippleMap_TCL_DECLARED /* 24 */ -EXTERN VOID * TkMacOSXMakeStippleMap(Drawable d1, Drawable d2); -#endif -#ifndef TkMacOSXMenuClick_TCL_DECLARED -#define TkMacOSXMenuClick_TCL_DECLARED +EXTERN void * TkMacOSXMakeStippleMap(Drawable d1, Drawable d2); /* 25 */ EXTERN void TkMacOSXMenuClick(void); -#endif -#ifndef TkMacOSXRegisterOffScreenWindow_TCL_DECLARED -#define TkMacOSXRegisterOffScreenWindow_TCL_DECLARED /* 26 */ EXTERN void TkMacOSXRegisterOffScreenWindow(Window window, - VOID *portPtr); -#endif -#ifndef TkMacOSXResizable_TCL_DECLARED -#define TkMacOSXResizable_TCL_DECLARED + void *portPtr); /* 27 */ EXTERN int TkMacOSXResizable(TkWindow *winPtr); -#endif -#ifndef TkMacOSXSetHelpMenuItemCount_TCL_DECLARED -#define TkMacOSXSetHelpMenuItemCount_TCL_DECLARED /* 28 */ EXTERN void TkMacOSXSetHelpMenuItemCount(void); -#endif -#ifndef TkMacOSXSetScrollbarGrow_TCL_DECLARED -#define TkMacOSXSetScrollbarGrow_TCL_DECLARED /* 29 */ EXTERN void TkMacOSXSetScrollbarGrow(TkWindow *winPtr, int flag); -#endif -#ifndef TkMacOSXSetUpClippingRgn_TCL_DECLARED -#define TkMacOSXSetUpClippingRgn_TCL_DECLARED /* 30 */ EXTERN void TkMacOSXSetUpClippingRgn(Drawable drawable); -#endif -#ifndef TkMacOSXSetUpGraphicsPort_TCL_DECLARED -#define TkMacOSXSetUpGraphicsPort_TCL_DECLARED /* 31 */ -EXTERN void TkMacOSXSetUpGraphicsPort(GC gc, VOID *destPort); -#endif -#ifndef TkMacOSXUpdateClipRgn_TCL_DECLARED -#define TkMacOSXUpdateClipRgn_TCL_DECLARED +EXTERN void TkMacOSXSetUpGraphicsPort(GC gc, void *destPort); /* 32 */ EXTERN void TkMacOSXUpdateClipRgn(TkWindow *winPtr); -#endif -#ifndef TkMacOSXUnregisterMacWindow_TCL_DECLARED -#define TkMacOSXUnregisterMacWindow_TCL_DECLARED /* 33 */ -EXTERN void TkMacOSXUnregisterMacWindow(VOID *portPtr); -#endif -#ifndef TkMacOSXUseMenuID_TCL_DECLARED -#define TkMacOSXUseMenuID_TCL_DECLARED +EXTERN void TkMacOSXUnregisterMacWindow(void *portPtr); /* 34 */ EXTERN int TkMacOSXUseMenuID(short macID); -#endif -#ifndef TkMacOSXVisableClipRgn_TCL_DECLARED -#define TkMacOSXVisableClipRgn_TCL_DECLARED /* 35 */ EXTERN TkRegion TkMacOSXVisableClipRgn(TkWindow *winPtr); -#endif -#ifndef TkMacOSXWinBounds_TCL_DECLARED -#define TkMacOSXWinBounds_TCL_DECLARED /* 36 */ -EXTERN void TkMacOSXWinBounds(TkWindow *winPtr, VOID *geometry); -#endif -#ifndef TkMacOSXWindowOffset_TCL_DECLARED -#define TkMacOSXWindowOffset_TCL_DECLARED +EXTERN void TkMacOSXWinBounds(TkWindow *winPtr, void *geometry); /* 37 */ -EXTERN void TkMacOSXWindowOffset(VOID *wRef, int *xOffset, +EXTERN void TkMacOSXWindowOffset(void *wRef, int *xOffset, int *yOffset); -#endif -#ifndef TkSetMacColor_TCL_DECLARED -#define TkSetMacColor_TCL_DECLARED /* 38 */ -EXTERN int TkSetMacColor(unsigned long pixel, VOID *macColor); -#endif -#ifndef TkSetWMName_TCL_DECLARED -#define TkSetWMName_TCL_DECLARED +EXTERN int TkSetMacColor(unsigned long pixel, void *macColor); /* 39 */ EXTERN void TkSetWMName(TkWindow *winPtr, Tk_Uid titleUid); -#endif -#ifndef TkSuspendClipboard_TCL_DECLARED -#define TkSuspendClipboard_TCL_DECLARED -/* 40 */ -EXTERN void TkSuspendClipboard(void); -#endif -#ifndef TkMacOSXZoomToplevel_TCL_DECLARED -#define TkMacOSXZoomToplevel_TCL_DECLARED +/* Slot 40 is reserved */ /* 41 */ -EXTERN int TkMacOSXZoomToplevel(VOID *whichWindow, +EXTERN int TkMacOSXZoomToplevel(void *whichWindow, short zoomPart); -#endif -#ifndef Tk_TopCoordsToWindow_TCL_DECLARED -#define Tk_TopCoordsToWindow_TCL_DECLARED /* 42 */ EXTERN Tk_Window Tk_TopCoordsToWindow(Tk_Window tkwin, int rootX, int rootY, int *newX, int *newY); -#endif -#ifndef TkMacOSXContainerId_TCL_DECLARED -#define TkMacOSXContainerId_TCL_DECLARED /* 43 */ EXTERN MacDrawable * TkMacOSXContainerId(TkWindow *winPtr); -#endif -#ifndef TkMacOSXGetHostToplevel_TCL_DECLARED -#define TkMacOSXGetHostToplevel_TCL_DECLARED /* 44 */ EXTERN MacDrawable * TkMacOSXGetHostToplevel(TkWindow *winPtr); -#endif -#ifndef TkMacOSXPreprocessMenu_TCL_DECLARED -#define TkMacOSXPreprocessMenu_TCL_DECLARED /* 45 */ EXTERN void TkMacOSXPreprocessMenu(void); -#endif -#ifndef TkpIsWindowFloating_TCL_DECLARED -#define TkpIsWindowFloating_TCL_DECLARED /* 46 */ -EXTERN int TkpIsWindowFloating(VOID *window); -#endif -#ifndef TkMacOSXGetCapture_TCL_DECLARED -#define TkMacOSXGetCapture_TCL_DECLARED +EXTERN int TkpIsWindowFloating(void *window); /* 47 */ EXTERN Tk_Window TkMacOSXGetCapture(void); -#endif /* Slot 48 is reserved */ -#ifndef TkGetTransientMaster_TCL_DECLARED -#define TkGetTransientMaster_TCL_DECLARED /* 49 */ -EXTERN Window TkGetTransientMaster(TkWindow *winPtr); -#endif -#ifndef TkGenerateButtonEvent_TCL_DECLARED -#define TkGenerateButtonEvent_TCL_DECLARED +EXTERN Tk_Window TkGetTransientMaster(TkWindow *winPtr); /* 50 */ EXTERN int TkGenerateButtonEvent(int x, int y, Window window, unsigned int state); -#endif -#ifndef TkGenWMDestroyEvent_TCL_DECLARED -#define TkGenWMDestroyEvent_TCL_DECLARED /* 51 */ EXTERN void TkGenWMDestroyEvent(Tk_Window tkwin); -#endif -#ifndef TkMacOSXSetDrawingEnabled_TCL_DECLARED -#define TkMacOSXSetDrawingEnabled_TCL_DECLARED /* 52 */ EXTERN void TkMacOSXSetDrawingEnabled(TkWindow *winPtr, int flag); -#endif -#ifndef TkpGetMS_TCL_DECLARED -#define TkpGetMS_TCL_DECLARED /* 53 */ EXTERN unsigned long TkpGetMS(void); -#endif -#ifndef TkMacOSXDrawable_TCL_DECLARED -#define TkMacOSXDrawable_TCL_DECLARED /* 54 */ -EXTERN VOID * TkMacOSXDrawable(Drawable drawable); -#endif -#ifndef TkpScanWindowId_TCL_DECLARED -#define TkpScanWindowId_TCL_DECLARED +EXTERN void * TkMacOSXDrawable(Drawable drawable); /* 55 */ EXTERN int TkpScanWindowId(Tcl_Interp *interp, - CONST char *string, Window *idPtr); -#endif + const char *string, Window *idPtr); #endif /* AQUA */ -#if !(defined(__WIN32__) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */ -#ifndef TkCreateXEventSource_TCL_DECLARED -#define TkCreateXEventSource_TCL_DECLARED +#if !(defined(_WIN32) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */ /* 0 */ EXTERN void TkCreateXEventSource(void); -#endif -#ifndef TkFreeWindowId_TCL_DECLARED -#define TkFreeWindowId_TCL_DECLARED -/* 1 */ -EXTERN void TkFreeWindowId(TkDisplay *dispPtr, Window w); -#endif -#ifndef TkInitXId_TCL_DECLARED -#define TkInitXId_TCL_DECLARED -/* 2 */ -EXTERN void TkInitXId(TkDisplay *dispPtr); -#endif -#ifndef TkpCmapStressed_TCL_DECLARED -#define TkpCmapStressed_TCL_DECLARED +/* Slot 1 is reserved */ +/* Slot 2 is reserved */ /* 3 */ EXTERN int TkpCmapStressed(Tk_Window tkwin, Colormap colormap); -#endif -#ifndef TkpSync_TCL_DECLARED -#define TkpSync_TCL_DECLARED /* 4 */ EXTERN void TkpSync(Display *display); -#endif -#ifndef TkUnixContainerId_TCL_DECLARED -#define TkUnixContainerId_TCL_DECLARED /* 5 */ EXTERN Window TkUnixContainerId(TkWindow *winPtr); -#endif -#ifndef TkUnixDoOneXEvent_TCL_DECLARED -#define TkUnixDoOneXEvent_TCL_DECLARED /* 6 */ EXTERN int TkUnixDoOneXEvent(Tcl_Time *timePtr); -#endif -#ifndef TkUnixSetMenubar_TCL_DECLARED -#define TkUnixSetMenubar_TCL_DECLARED /* 7 */ EXTERN void TkUnixSetMenubar(Tk_Window tkwin, Tk_Window menubar); -#endif -#ifndef TkpScanWindowId_TCL_DECLARED -#define TkpScanWindowId_TCL_DECLARED /* 8 */ EXTERN int TkpScanWindowId(Tcl_Interp *interp, - CONST char *string, Window *idPtr); -#endif -#ifndef TkWmCleanup_TCL_DECLARED -#define TkWmCleanup_TCL_DECLARED + const char *string, Window *idPtr); /* 9 */ EXTERN void TkWmCleanup(TkDisplay *dispPtr); -#endif -#ifndef TkSendCleanup_TCL_DECLARED -#define TkSendCleanup_TCL_DECLARED /* 10 */ EXTERN void TkSendCleanup(TkDisplay *dispPtr); -#endif -#ifndef TkFreeXId_TCL_DECLARED -#define TkFreeXId_TCL_DECLARED -/* 11 */ -EXTERN void TkFreeXId(TkDisplay *dispPtr); -#endif -#ifndef TkpWmSetState_TCL_DECLARED -#define TkpWmSetState_TCL_DECLARED +/* Slot 11 is reserved */ /* 12 */ EXTERN int TkpWmSetState(TkWindow *winPtr, int state); -#endif -#ifndef TkpTestsendCmd_TCL_DECLARED -#define TkpTestsendCmd_TCL_DECLARED /* 13 */ EXTERN int TkpTestsendCmd(ClientData clientData, - Tcl_Interp *interp, int argc, - CONST char **argv); -#endif + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); #endif /* X11 */ typedef struct TkIntPlatStubs { int magic; - struct TkIntPlatStubHooks *hooks; + void *hooks; -#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */ +#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ char * (*tkAlignImageData) (XImage *image, int alignment, int bitOrder); /* 0 */ - VOID *reserved1; + void (*reserved1)(void); void (*tkGenerateActivateEvents) (TkWindow *winPtr, int active); /* 2 */ unsigned long (*tkpGetMS) (void); /* 3 */ void (*tkPointerDeadWindow) (TkWindow *winPtr); /* 4 */ void (*tkpPrintWindowId) (char *buf, Window window); /* 5 */ - int (*tkpScanWindowId) (Tcl_Interp *interp, CONST char *string, Window *idPtr); /* 6 */ + int (*tkpScanWindowId) (Tcl_Interp *interp, const char *string, Window *idPtr); /* 6 */ void (*tkpSetCapture) (TkWindow *winPtr); /* 7 */ void (*tkpSetCursor) (TkpCursor cursor); /* 8 */ int (*tkpWmSetState) (TkWindow *winPtr, int state); /* 9 */ @@ -655,7 +327,7 @@ typedef struct TkIntPlatStubs { void (*tkWinXInit) (HINSTANCE hInstance); /* 29 */ void (*tkWinSetForegroundWindow) (TkWindow *winPtr); /* 30 */ void (*tkWinDialogDebug) (int debug); /* 31 */ - Tcl_Obj * (*tkWinGetMenuSystemDefault) (Tk_Window tkwin, CONST char *dbName, CONST char *className); /* 32 */ + Tcl_Obj * (*tkWinGetMenuSystemDefault) (Tk_Window tkwin, const char *dbName, const char *className); /* 32 */ int (*tkWinGetPlatformId) (void); /* 33 */ void (*tkWinSetHINSTANCE) (HINSTANCE hInstance); /* 34 */ int (*tkWinGetPlatformTheme) (void); /* 35 */ @@ -668,12 +340,12 @@ typedef struct TkIntPlatStubs { void (*tkUnixSetMenubar) (Tk_Window tkwin, Tk_Window menubar); /* 42 */ void (*tkWmCleanup) (TkDisplay *dispPtr); /* 43 */ void (*tkSendCleanup) (TkDisplay *dispPtr); /* 44 */ - int (*tkpTestsendCmd) (ClientData clientData, Tcl_Interp *interp, int argc, CONST char **argv); /* 45 */ + int (*tkpTestsendCmd) (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 45 */ #endif /* WIN */ #ifdef MAC_OSX_TK /* AQUA */ void (*tkGenerateActivateEvents) (TkWindow *winPtr, int active); /* 0 */ - VOID *reserved1; - VOID *reserved2; + void (*reserved1)(void); + void (*reserved2)(void); void (*tkPointerDeadWindow) (TkWindow *winPtr); /* 3 */ void (*tkpSetCapture) (TkWindow *winPtr); /* 4 */ void (*tkpSetCursor) (TkpCursor cursor); /* 5 */ @@ -684,545 +356,312 @@ typedef struct TkIntPlatStubs { int (*tkMacOSXDispatchMenuEvent) (int menuID, int index); /* 10 */ void (*tkMacOSXInstallCursor) (int resizeOverride); /* 11 */ void (*tkMacOSXHandleTearoffMenu) (void); /* 12 */ - VOID *reserved13; - int (*tkMacOSXDoHLEvent) (VOID *theEvent); /* 14 */ - VOID *reserved15; - Window (*tkMacOSXGetXWindow) (VOID *macWinPtr); /* 16 */ - int (*tkMacOSXGrowToplevel) (VOID *whichWindow, XPoint start); /* 17 */ + void (*reserved13)(void); + int (*tkMacOSXDoHLEvent) (void *theEvent); /* 14 */ + void (*reserved15)(void); + Window (*tkMacOSXGetXWindow) (void *macWinPtr); /* 16 */ + int (*tkMacOSXGrowToplevel) (void *whichWindow, XPoint start); /* 17 */ void (*tkMacOSXHandleMenuSelect) (short theMenu, unsigned short theItem, int optionKeyPressed); /* 18 */ - VOID *reserved19; - VOID *reserved20; + void (*reserved19)(void); + void (*reserved20)(void); void (*tkMacOSXInvalidateWindow) (MacDrawable *macWin, int flag); /* 21 */ int (*tkMacOSXIsCharacterMissing) (Tk_Font tkfont, unsigned int searchChar); /* 22 */ void (*tkMacOSXMakeRealWindowExist) (TkWindow *winPtr); /* 23 */ - VOID * (*tkMacOSXMakeStippleMap) (Drawable d1, Drawable d2); /* 24 */ + void * (*tkMacOSXMakeStippleMap) (Drawable d1, Drawable d2); /* 24 */ void (*tkMacOSXMenuClick) (void); /* 25 */ - void (*tkMacOSXRegisterOffScreenWindow) (Window window, VOID *portPtr); /* 26 */ + void (*tkMacOSXRegisterOffScreenWindow) (Window window, void *portPtr); /* 26 */ int (*tkMacOSXResizable) (TkWindow *winPtr); /* 27 */ void (*tkMacOSXSetHelpMenuItemCount) (void); /* 28 */ void (*tkMacOSXSetScrollbarGrow) (TkWindow *winPtr, int flag); /* 29 */ void (*tkMacOSXSetUpClippingRgn) (Drawable drawable); /* 30 */ - void (*tkMacOSXSetUpGraphicsPort) (GC gc, VOID *destPort); /* 31 */ + void (*tkMacOSXSetUpGraphicsPort) (GC gc, void *destPort); /* 31 */ void (*tkMacOSXUpdateClipRgn) (TkWindow *winPtr); /* 32 */ - void (*tkMacOSXUnregisterMacWindow) (VOID *portPtr); /* 33 */ + void (*tkMacOSXUnregisterMacWindow) (void *portPtr); /* 33 */ int (*tkMacOSXUseMenuID) (short macID); /* 34 */ TkRegion (*tkMacOSXVisableClipRgn) (TkWindow *winPtr); /* 35 */ - void (*tkMacOSXWinBounds) (TkWindow *winPtr, VOID *geometry); /* 36 */ - void (*tkMacOSXWindowOffset) (VOID *wRef, int *xOffset, int *yOffset); /* 37 */ - int (*tkSetMacColor) (unsigned long pixel, VOID *macColor); /* 38 */ + void (*tkMacOSXWinBounds) (TkWindow *winPtr, void *geometry); /* 36 */ + void (*tkMacOSXWindowOffset) (void *wRef, int *xOffset, int *yOffset); /* 37 */ + int (*tkSetMacColor) (unsigned long pixel, void *macColor); /* 38 */ void (*tkSetWMName) (TkWindow *winPtr, Tk_Uid titleUid); /* 39 */ - void (*tkSuspendClipboard) (void); /* 40 */ - int (*tkMacOSXZoomToplevel) (VOID *whichWindow, short zoomPart); /* 41 */ + void (*reserved40)(void); + int (*tkMacOSXZoomToplevel) (void *whichWindow, short zoomPart); /* 41 */ Tk_Window (*tk_TopCoordsToWindow) (Tk_Window tkwin, int rootX, int rootY, int *newX, int *newY); /* 42 */ MacDrawable * (*tkMacOSXContainerId) (TkWindow *winPtr); /* 43 */ MacDrawable * (*tkMacOSXGetHostToplevel) (TkWindow *winPtr); /* 44 */ void (*tkMacOSXPreprocessMenu) (void); /* 45 */ - int (*tkpIsWindowFloating) (VOID *window); /* 46 */ + int (*tkpIsWindowFloating) (void *window); /* 46 */ Tk_Window (*tkMacOSXGetCapture) (void); /* 47 */ - VOID *reserved48; - Window (*tkGetTransientMaster) (TkWindow *winPtr); /* 49 */ + void (*reserved48)(void); + Tk_Window (*tkGetTransientMaster) (TkWindow *winPtr); /* 49 */ int (*tkGenerateButtonEvent) (int x, int y, Window window, unsigned int state); /* 50 */ void (*tkGenWMDestroyEvent) (Tk_Window tkwin); /* 51 */ void (*tkMacOSXSetDrawingEnabled) (TkWindow *winPtr, int flag); /* 52 */ unsigned long (*tkpGetMS) (void); /* 53 */ - VOID * (*tkMacOSXDrawable) (Drawable drawable); /* 54 */ - int (*tkpScanWindowId) (Tcl_Interp *interp, CONST char *string, Window *idPtr); /* 55 */ + void * (*tkMacOSXDrawable) (Drawable drawable); /* 54 */ + int (*tkpScanWindowId) (Tcl_Interp *interp, const char *string, Window *idPtr); /* 55 */ #endif /* AQUA */ -#if !(defined(__WIN32__) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */ +#if !(defined(_WIN32) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */ void (*tkCreateXEventSource) (void); /* 0 */ - void (*tkFreeWindowId) (TkDisplay *dispPtr, Window w); /* 1 */ - void (*tkInitXId) (TkDisplay *dispPtr); /* 2 */ + void (*reserved1)(void); + void (*reserved2)(void); int (*tkpCmapStressed) (Tk_Window tkwin, Colormap colormap); /* 3 */ void (*tkpSync) (Display *display); /* 4 */ Window (*tkUnixContainerId) (TkWindow *winPtr); /* 5 */ int (*tkUnixDoOneXEvent) (Tcl_Time *timePtr); /* 6 */ void (*tkUnixSetMenubar) (Tk_Window tkwin, Tk_Window menubar); /* 7 */ - int (*tkpScanWindowId) (Tcl_Interp *interp, CONST char *string, Window *idPtr); /* 8 */ + int (*tkpScanWindowId) (Tcl_Interp *interp, const char *string, Window *idPtr); /* 8 */ void (*tkWmCleanup) (TkDisplay *dispPtr); /* 9 */ void (*tkSendCleanup) (TkDisplay *dispPtr); /* 10 */ - void (*tkFreeXId) (TkDisplay *dispPtr); /* 11 */ + void (*reserved11)(void); int (*tkpWmSetState) (TkWindow *winPtr, int state); /* 12 */ - int (*tkpTestsendCmd) (ClientData clientData, Tcl_Interp *interp, int argc, CONST char **argv); /* 13 */ + int (*tkpTestsendCmd) (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 13 */ #endif /* X11 */ } TkIntPlatStubs; -extern TkIntPlatStubs *tkIntPlatStubsPtr; +extern const TkIntPlatStubs *tkIntPlatStubsPtr; #ifdef __cplusplus } #endif -#if defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS) +#if defined(USE_TK_STUBS) /* * Inline function declarations: */ -#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */ -#ifndef TkAlignImageData +#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ #define TkAlignImageData \ (tkIntPlatStubsPtr->tkAlignImageData) /* 0 */ -#endif /* Slot 1 is reserved */ -#ifndef TkGenerateActivateEvents #define TkGenerateActivateEvents \ (tkIntPlatStubsPtr->tkGenerateActivateEvents) /* 2 */ -#endif -#ifndef TkpGetMS #define TkpGetMS \ (tkIntPlatStubsPtr->tkpGetMS) /* 3 */ -#endif -#ifndef TkPointerDeadWindow #define TkPointerDeadWindow \ (tkIntPlatStubsPtr->tkPointerDeadWindow) /* 4 */ -#endif -#ifndef TkpPrintWindowId #define TkpPrintWindowId \ (tkIntPlatStubsPtr->tkpPrintWindowId) /* 5 */ -#endif -#ifndef TkpScanWindowId #define TkpScanWindowId \ (tkIntPlatStubsPtr->tkpScanWindowId) /* 6 */ -#endif -#ifndef TkpSetCapture #define TkpSetCapture \ (tkIntPlatStubsPtr->tkpSetCapture) /* 7 */ -#endif -#ifndef TkpSetCursor #define TkpSetCursor \ (tkIntPlatStubsPtr->tkpSetCursor) /* 8 */ -#endif -#ifndef TkpWmSetState #define TkpWmSetState \ (tkIntPlatStubsPtr->tkpWmSetState) /* 9 */ -#endif -#ifndef TkSetPixmapColormap #define TkSetPixmapColormap \ (tkIntPlatStubsPtr->tkSetPixmapColormap) /* 10 */ -#endif -#ifndef TkWinCancelMouseTimer #define TkWinCancelMouseTimer \ (tkIntPlatStubsPtr->tkWinCancelMouseTimer) /* 11 */ -#endif -#ifndef TkWinClipboardRender #define TkWinClipboardRender \ (tkIntPlatStubsPtr->tkWinClipboardRender) /* 12 */ -#endif -#ifndef TkWinEmbeddedEventProc #define TkWinEmbeddedEventProc \ (tkIntPlatStubsPtr->tkWinEmbeddedEventProc) /* 13 */ -#endif -#ifndef TkWinFillRect #define TkWinFillRect \ (tkIntPlatStubsPtr->tkWinFillRect) /* 14 */ -#endif -#ifndef TkWinGetBorderPixels #define TkWinGetBorderPixels \ (tkIntPlatStubsPtr->tkWinGetBorderPixels) /* 15 */ -#endif -#ifndef TkWinGetDrawableDC #define TkWinGetDrawableDC \ (tkIntPlatStubsPtr->tkWinGetDrawableDC) /* 16 */ -#endif -#ifndef TkWinGetModifierState #define TkWinGetModifierState \ (tkIntPlatStubsPtr->tkWinGetModifierState) /* 17 */ -#endif -#ifndef TkWinGetSystemPalette #define TkWinGetSystemPalette \ (tkIntPlatStubsPtr->tkWinGetSystemPalette) /* 18 */ -#endif -#ifndef TkWinGetWrapperWindow #define TkWinGetWrapperWindow \ (tkIntPlatStubsPtr->tkWinGetWrapperWindow) /* 19 */ -#endif -#ifndef TkWinHandleMenuEvent #define TkWinHandleMenuEvent \ (tkIntPlatStubsPtr->tkWinHandleMenuEvent) /* 20 */ -#endif -#ifndef TkWinIndexOfColor #define TkWinIndexOfColor \ (tkIntPlatStubsPtr->tkWinIndexOfColor) /* 21 */ -#endif -#ifndef TkWinReleaseDrawableDC #define TkWinReleaseDrawableDC \ (tkIntPlatStubsPtr->tkWinReleaseDrawableDC) /* 22 */ -#endif -#ifndef TkWinResendEvent #define TkWinResendEvent \ (tkIntPlatStubsPtr->tkWinResendEvent) /* 23 */ -#endif -#ifndef TkWinSelectPalette #define TkWinSelectPalette \ (tkIntPlatStubsPtr->tkWinSelectPalette) /* 24 */ -#endif -#ifndef TkWinSetMenu #define TkWinSetMenu \ (tkIntPlatStubsPtr->tkWinSetMenu) /* 25 */ -#endif -#ifndef TkWinSetWindowPos #define TkWinSetWindowPos \ (tkIntPlatStubsPtr->tkWinSetWindowPos) /* 26 */ -#endif -#ifndef TkWinWmCleanup #define TkWinWmCleanup \ (tkIntPlatStubsPtr->tkWinWmCleanup) /* 27 */ -#endif -#ifndef TkWinXCleanup #define TkWinXCleanup \ (tkIntPlatStubsPtr->tkWinXCleanup) /* 28 */ -#endif -#ifndef TkWinXInit #define TkWinXInit \ (tkIntPlatStubsPtr->tkWinXInit) /* 29 */ -#endif -#ifndef TkWinSetForegroundWindow #define TkWinSetForegroundWindow \ (tkIntPlatStubsPtr->tkWinSetForegroundWindow) /* 30 */ -#endif -#ifndef TkWinDialogDebug #define TkWinDialogDebug \ (tkIntPlatStubsPtr->tkWinDialogDebug) /* 31 */ -#endif -#ifndef TkWinGetMenuSystemDefault #define TkWinGetMenuSystemDefault \ (tkIntPlatStubsPtr->tkWinGetMenuSystemDefault) /* 32 */ -#endif -#ifndef TkWinGetPlatformId #define TkWinGetPlatformId \ (tkIntPlatStubsPtr->tkWinGetPlatformId) /* 33 */ -#endif -#ifndef TkWinSetHINSTANCE #define TkWinSetHINSTANCE \ (tkIntPlatStubsPtr->tkWinSetHINSTANCE) /* 34 */ -#endif -#ifndef TkWinGetPlatformTheme #define TkWinGetPlatformTheme \ (tkIntPlatStubsPtr->tkWinGetPlatformTheme) /* 35 */ -#endif -#ifndef TkWinChildProc #define TkWinChildProc \ (tkIntPlatStubsPtr->tkWinChildProc) /* 36 */ -#endif -#ifndef TkCreateXEventSource #define TkCreateXEventSource \ (tkIntPlatStubsPtr->tkCreateXEventSource) /* 37 */ -#endif -#ifndef TkpCmapStressed #define TkpCmapStressed \ (tkIntPlatStubsPtr->tkpCmapStressed) /* 38 */ -#endif -#ifndef TkpSync #define TkpSync \ (tkIntPlatStubsPtr->tkpSync) /* 39 */ -#endif -#ifndef TkUnixContainerId #define TkUnixContainerId \ (tkIntPlatStubsPtr->tkUnixContainerId) /* 40 */ -#endif -#ifndef TkUnixDoOneXEvent #define TkUnixDoOneXEvent \ (tkIntPlatStubsPtr->tkUnixDoOneXEvent) /* 41 */ -#endif -#ifndef TkUnixSetMenubar #define TkUnixSetMenubar \ (tkIntPlatStubsPtr->tkUnixSetMenubar) /* 42 */ -#endif -#ifndef TkWmCleanup #define TkWmCleanup \ (tkIntPlatStubsPtr->tkWmCleanup) /* 43 */ -#endif -#ifndef TkSendCleanup #define TkSendCleanup \ (tkIntPlatStubsPtr->tkSendCleanup) /* 44 */ -#endif -#ifndef TkpTestsendCmd #define TkpTestsendCmd \ (tkIntPlatStubsPtr->tkpTestsendCmd) /* 45 */ -#endif #endif /* WIN */ #ifdef MAC_OSX_TK /* AQUA */ -#ifndef TkGenerateActivateEvents #define TkGenerateActivateEvents \ (tkIntPlatStubsPtr->tkGenerateActivateEvents) /* 0 */ -#endif /* Slot 1 is reserved */ /* Slot 2 is reserved */ -#ifndef TkPointerDeadWindow #define TkPointerDeadWindow \ (tkIntPlatStubsPtr->tkPointerDeadWindow) /* 3 */ -#endif -#ifndef TkpSetCapture #define TkpSetCapture \ (tkIntPlatStubsPtr->tkpSetCapture) /* 4 */ -#endif -#ifndef TkpSetCursor #define TkpSetCursor \ (tkIntPlatStubsPtr->tkpSetCursor) /* 5 */ -#endif -#ifndef TkpWmSetState #define TkpWmSetState \ (tkIntPlatStubsPtr->tkpWmSetState) /* 6 */ -#endif -#ifndef TkAboutDlg #define TkAboutDlg \ (tkIntPlatStubsPtr->tkAboutDlg) /* 7 */ -#endif -#ifndef TkMacOSXButtonKeyState #define TkMacOSXButtonKeyState \ (tkIntPlatStubsPtr->tkMacOSXButtonKeyState) /* 8 */ -#endif -#ifndef TkMacOSXClearMenubarActive #define TkMacOSXClearMenubarActive \ (tkIntPlatStubsPtr->tkMacOSXClearMenubarActive) /* 9 */ -#endif -#ifndef TkMacOSXDispatchMenuEvent #define TkMacOSXDispatchMenuEvent \ (tkIntPlatStubsPtr->tkMacOSXDispatchMenuEvent) /* 10 */ -#endif -#ifndef TkMacOSXInstallCursor #define TkMacOSXInstallCursor \ (tkIntPlatStubsPtr->tkMacOSXInstallCursor) /* 11 */ -#endif -#ifndef TkMacOSXHandleTearoffMenu #define TkMacOSXHandleTearoffMenu \ (tkIntPlatStubsPtr->tkMacOSXHandleTearoffMenu) /* 12 */ -#endif /* Slot 13 is reserved */ -#ifndef TkMacOSXDoHLEvent #define TkMacOSXDoHLEvent \ (tkIntPlatStubsPtr->tkMacOSXDoHLEvent) /* 14 */ -#endif /* Slot 15 is reserved */ -#ifndef TkMacOSXGetXWindow #define TkMacOSXGetXWindow \ (tkIntPlatStubsPtr->tkMacOSXGetXWindow) /* 16 */ -#endif -#ifndef TkMacOSXGrowToplevel #define TkMacOSXGrowToplevel \ (tkIntPlatStubsPtr->tkMacOSXGrowToplevel) /* 17 */ -#endif -#ifndef TkMacOSXHandleMenuSelect #define TkMacOSXHandleMenuSelect \ (tkIntPlatStubsPtr->tkMacOSXHandleMenuSelect) /* 18 */ -#endif /* Slot 19 is reserved */ /* Slot 20 is reserved */ -#ifndef TkMacOSXInvalidateWindow #define TkMacOSXInvalidateWindow \ (tkIntPlatStubsPtr->tkMacOSXInvalidateWindow) /* 21 */ -#endif -#ifndef TkMacOSXIsCharacterMissing #define TkMacOSXIsCharacterMissing \ (tkIntPlatStubsPtr->tkMacOSXIsCharacterMissing) /* 22 */ -#endif -#ifndef TkMacOSXMakeRealWindowExist #define TkMacOSXMakeRealWindowExist \ (tkIntPlatStubsPtr->tkMacOSXMakeRealWindowExist) /* 23 */ -#endif -#ifndef TkMacOSXMakeStippleMap #define TkMacOSXMakeStippleMap \ (tkIntPlatStubsPtr->tkMacOSXMakeStippleMap) /* 24 */ -#endif -#ifndef TkMacOSXMenuClick #define TkMacOSXMenuClick \ (tkIntPlatStubsPtr->tkMacOSXMenuClick) /* 25 */ -#endif -#ifndef TkMacOSXRegisterOffScreenWindow #define TkMacOSXRegisterOffScreenWindow \ (tkIntPlatStubsPtr->tkMacOSXRegisterOffScreenWindow) /* 26 */ -#endif -#ifndef TkMacOSXResizable #define TkMacOSXResizable \ (tkIntPlatStubsPtr->tkMacOSXResizable) /* 27 */ -#endif -#ifndef TkMacOSXSetHelpMenuItemCount #define TkMacOSXSetHelpMenuItemCount \ (tkIntPlatStubsPtr->tkMacOSXSetHelpMenuItemCount) /* 28 */ -#endif -#ifndef TkMacOSXSetScrollbarGrow #define TkMacOSXSetScrollbarGrow \ (tkIntPlatStubsPtr->tkMacOSXSetScrollbarGrow) /* 29 */ -#endif -#ifndef TkMacOSXSetUpClippingRgn #define TkMacOSXSetUpClippingRgn \ (tkIntPlatStubsPtr->tkMacOSXSetUpClippingRgn) /* 30 */ -#endif -#ifndef TkMacOSXSetUpGraphicsPort #define TkMacOSXSetUpGraphicsPort \ (tkIntPlatStubsPtr->tkMacOSXSetUpGraphicsPort) /* 31 */ -#endif -#ifndef TkMacOSXUpdateClipRgn #define TkMacOSXUpdateClipRgn \ (tkIntPlatStubsPtr->tkMacOSXUpdateClipRgn) /* 32 */ -#endif -#ifndef TkMacOSXUnregisterMacWindow #define TkMacOSXUnregisterMacWindow \ (tkIntPlatStubsPtr->tkMacOSXUnregisterMacWindow) /* 33 */ -#endif -#ifndef TkMacOSXUseMenuID #define TkMacOSXUseMenuID \ (tkIntPlatStubsPtr->tkMacOSXUseMenuID) /* 34 */ -#endif -#ifndef TkMacOSXVisableClipRgn #define TkMacOSXVisableClipRgn \ (tkIntPlatStubsPtr->tkMacOSXVisableClipRgn) /* 35 */ -#endif -#ifndef TkMacOSXWinBounds #define TkMacOSXWinBounds \ (tkIntPlatStubsPtr->tkMacOSXWinBounds) /* 36 */ -#endif -#ifndef TkMacOSXWindowOffset #define TkMacOSXWindowOffset \ (tkIntPlatStubsPtr->tkMacOSXWindowOffset) /* 37 */ -#endif -#ifndef TkSetMacColor #define TkSetMacColor \ (tkIntPlatStubsPtr->tkSetMacColor) /* 38 */ -#endif -#ifndef TkSetWMName #define TkSetWMName \ (tkIntPlatStubsPtr->tkSetWMName) /* 39 */ -#endif -#ifndef TkSuspendClipboard -#define TkSuspendClipboard \ - (tkIntPlatStubsPtr->tkSuspendClipboard) /* 40 */ -#endif -#ifndef TkMacOSXZoomToplevel +/* Slot 40 is reserved */ #define TkMacOSXZoomToplevel \ (tkIntPlatStubsPtr->tkMacOSXZoomToplevel) /* 41 */ -#endif -#ifndef Tk_TopCoordsToWindow #define Tk_TopCoordsToWindow \ (tkIntPlatStubsPtr->tk_TopCoordsToWindow) /* 42 */ -#endif -#ifndef TkMacOSXContainerId #define TkMacOSXContainerId \ (tkIntPlatStubsPtr->tkMacOSXContainerId) /* 43 */ -#endif -#ifndef TkMacOSXGetHostToplevel #define TkMacOSXGetHostToplevel \ (tkIntPlatStubsPtr->tkMacOSXGetHostToplevel) /* 44 */ -#endif -#ifndef TkMacOSXPreprocessMenu #define TkMacOSXPreprocessMenu \ (tkIntPlatStubsPtr->tkMacOSXPreprocessMenu) /* 45 */ -#endif -#ifndef TkpIsWindowFloating #define TkpIsWindowFloating \ (tkIntPlatStubsPtr->tkpIsWindowFloating) /* 46 */ -#endif -#ifndef TkMacOSXGetCapture #define TkMacOSXGetCapture \ (tkIntPlatStubsPtr->tkMacOSXGetCapture) /* 47 */ -#endif /* Slot 48 is reserved */ -#ifndef TkGetTransientMaster #define TkGetTransientMaster \ (tkIntPlatStubsPtr->tkGetTransientMaster) /* 49 */ -#endif -#ifndef TkGenerateButtonEvent #define TkGenerateButtonEvent \ (tkIntPlatStubsPtr->tkGenerateButtonEvent) /* 50 */ -#endif -#ifndef TkGenWMDestroyEvent #define TkGenWMDestroyEvent \ (tkIntPlatStubsPtr->tkGenWMDestroyEvent) /* 51 */ -#endif -#ifndef TkMacOSXSetDrawingEnabled #define TkMacOSXSetDrawingEnabled \ (tkIntPlatStubsPtr->tkMacOSXSetDrawingEnabled) /* 52 */ -#endif -#ifndef TkpGetMS #define TkpGetMS \ (tkIntPlatStubsPtr->tkpGetMS) /* 53 */ -#endif -#ifndef TkMacOSXDrawable #define TkMacOSXDrawable \ (tkIntPlatStubsPtr->tkMacOSXDrawable) /* 54 */ -#endif -#ifndef TkpScanWindowId #define TkpScanWindowId \ (tkIntPlatStubsPtr->tkpScanWindowId) /* 55 */ -#endif #endif /* AQUA */ -#if !(defined(__WIN32__) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */ -#ifndef TkCreateXEventSource +#if !(defined(_WIN32) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */ #define TkCreateXEventSource \ (tkIntPlatStubsPtr->tkCreateXEventSource) /* 0 */ -#endif -#ifndef TkFreeWindowId -#define TkFreeWindowId \ - (tkIntPlatStubsPtr->tkFreeWindowId) /* 1 */ -#endif -#ifndef TkInitXId -#define TkInitXId \ - (tkIntPlatStubsPtr->tkInitXId) /* 2 */ -#endif -#ifndef TkpCmapStressed +/* Slot 1 is reserved */ +/* Slot 2 is reserved */ #define TkpCmapStressed \ (tkIntPlatStubsPtr->tkpCmapStressed) /* 3 */ -#endif -#ifndef TkpSync #define TkpSync \ (tkIntPlatStubsPtr->tkpSync) /* 4 */ -#endif -#ifndef TkUnixContainerId #define TkUnixContainerId \ (tkIntPlatStubsPtr->tkUnixContainerId) /* 5 */ -#endif -#ifndef TkUnixDoOneXEvent #define TkUnixDoOneXEvent \ (tkIntPlatStubsPtr->tkUnixDoOneXEvent) /* 6 */ -#endif -#ifndef TkUnixSetMenubar #define TkUnixSetMenubar \ (tkIntPlatStubsPtr->tkUnixSetMenubar) /* 7 */ -#endif -#ifndef TkpScanWindowId #define TkpScanWindowId \ (tkIntPlatStubsPtr->tkpScanWindowId) /* 8 */ -#endif -#ifndef TkWmCleanup #define TkWmCleanup \ (tkIntPlatStubsPtr->tkWmCleanup) /* 9 */ -#endif -#ifndef TkSendCleanup #define TkSendCleanup \ (tkIntPlatStubsPtr->tkSendCleanup) /* 10 */ -#endif -#ifndef TkFreeXId -#define TkFreeXId \ - (tkIntPlatStubsPtr->tkFreeXId) /* 11 */ -#endif -#ifndef TkpWmSetState +/* Slot 11 is reserved */ #define TkpWmSetState \ (tkIntPlatStubsPtr->tkpWmSetState) /* 12 */ -#endif -#ifndef TkpTestsendCmd #define TkpTestsendCmd \ (tkIntPlatStubsPtr->tkpTestsendCmd) /* 13 */ -#endif #endif /* X11 */ -#endif /* defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS) */ +#endif /* defined(USE_TK_STUBS) */ /* !END!: Do not edit above this line. */ #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT -#ifdef __CYGWIN__ - void TkFreeXId(TkDisplay *dispPtr); - void TkFreeWindowId(TkDisplay *dispPtr, Window w); - void TkInitXId(TkDisplay *dispPtr); -#endif - -#ifdef __WIN32__ -#undef TkpCmapStressed -#undef TkpSync -#define TkpCmapStressed(tkwin,colormap) (0) -#define TkpSync(display) -#endif - #endif /* _TKINTPLATDECLS */ diff --git a/generic/tkIntXlibDecls.h b/generic/tkIntXlibDecls.h index a897241..de44068 100644 --- a/generic/tkIntXlibDecls.h +++ b/generic/tkIntXlibDecls.h @@ -19,12 +19,18 @@ * in the generic/tkInt.decls script. */ -#ifdef MAC_TCL -#include "Xutil.h" -#else -#include "X11/Xutil.h" +#ifndef _TCL +# include <tcl.h> #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 @@ -44,1243 +50,640 @@ extern "C" { * Exported function declarations: */ -#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */ -#ifndef XSetDashes_TCL_DECLARED -#define XSetDashes_TCL_DECLARED +#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ /* 0 */ EXTERN int XSetDashes(Display *display, GC gc, int dash_offset, _Xconst char *dash_list, int n); -#endif -#ifndef XGetModifierMapping_TCL_DECLARED -#define XGetModifierMapping_TCL_DECLARED /* 1 */ EXTERN XModifierKeymap * XGetModifierMapping(Display *d); -#endif -#ifndef XCreateImage_TCL_DECLARED -#define XCreateImage_TCL_DECLARED /* 2 */ EXTERN XImage * XCreateImage(Display *d, Visual *v, unsigned int ui1, int i1, int i2, char *cp, unsigned int ui2, unsigned int ui3, int i3, int i4); -#endif -#ifndef XGetImage_TCL_DECLARED -#define XGetImage_TCL_DECLARED /* 3 */ EXTERN XImage * XGetImage(Display *d, Drawable dr, int i1, int i2, unsigned int ui1, unsigned int ui2, unsigned long ul, int i3); -#endif -#ifndef XGetAtomName_TCL_DECLARED -#define XGetAtomName_TCL_DECLARED /* 4 */ EXTERN char * XGetAtomName(Display *d, Atom a); -#endif -#ifndef XKeysymToString_TCL_DECLARED -#define XKeysymToString_TCL_DECLARED /* 5 */ EXTERN char * XKeysymToString(KeySym k); -#endif -#ifndef XCreateColormap_TCL_DECLARED -#define XCreateColormap_TCL_DECLARED /* 6 */ EXTERN Colormap XCreateColormap(Display *d, Window w, Visual *v, int i); -#endif -#ifndef XCreatePixmapCursor_TCL_DECLARED -#define XCreatePixmapCursor_TCL_DECLARED /* 7 */ EXTERN Cursor XCreatePixmapCursor(Display *d, Pixmap p1, Pixmap p2, XColor *x1, XColor *x2, unsigned int ui1, unsigned int ui2); -#endif -#ifndef XCreateGlyphCursor_TCL_DECLARED -#define XCreateGlyphCursor_TCL_DECLARED /* 8 */ EXTERN Cursor XCreateGlyphCursor(Display *d, Font f1, Font f2, unsigned int ui1, unsigned int ui2, XColor _Xconst *x1, XColor _Xconst *x2); -#endif -#ifndef XGContextFromGC_TCL_DECLARED -#define XGContextFromGC_TCL_DECLARED /* 9 */ EXTERN GContext XGContextFromGC(GC g); -#endif -#ifndef XListHosts_TCL_DECLARED -#define XListHosts_TCL_DECLARED /* 10 */ EXTERN XHostAddress * XListHosts(Display *d, int *i, Bool *b); -#endif -#ifndef XKeycodeToKeysym_TCL_DECLARED -#define XKeycodeToKeysym_TCL_DECLARED /* 11 */ EXTERN KeySym XKeycodeToKeysym(Display *d, unsigned int k, int i); -#endif -#ifndef XStringToKeysym_TCL_DECLARED -#define XStringToKeysym_TCL_DECLARED /* 12 */ EXTERN KeySym XStringToKeysym(_Xconst char *c); -#endif -#ifndef XRootWindow_TCL_DECLARED -#define XRootWindow_TCL_DECLARED /* 13 */ EXTERN Window XRootWindow(Display *d, int i); -#endif -#ifndef XSetErrorHandler_TCL_DECLARED -#define XSetErrorHandler_TCL_DECLARED /* 14 */ EXTERN XErrorHandler XSetErrorHandler(XErrorHandler x); -#endif -#ifndef XIconifyWindow_TCL_DECLARED -#define XIconifyWindow_TCL_DECLARED /* 15 */ EXTERN Status XIconifyWindow(Display *d, Window w, int i); -#endif -#ifndef XWithdrawWindow_TCL_DECLARED -#define XWithdrawWindow_TCL_DECLARED /* 16 */ EXTERN Status XWithdrawWindow(Display *d, Window w, int i); -#endif -#ifndef XGetWMColormapWindows_TCL_DECLARED -#define XGetWMColormapWindows_TCL_DECLARED /* 17 */ EXTERN Status XGetWMColormapWindows(Display *d, Window w, Window **wpp, int *ip); -#endif -#ifndef XAllocColor_TCL_DECLARED -#define XAllocColor_TCL_DECLARED /* 18 */ EXTERN Status XAllocColor(Display *d, Colormap c, XColor *xp); -#endif -#ifndef XBell_TCL_DECLARED -#define XBell_TCL_DECLARED /* 19 */ EXTERN int XBell(Display *d, int i); -#endif -#ifndef XChangeProperty_TCL_DECLARED -#define XChangeProperty_TCL_DECLARED /* 20 */ EXTERN int XChangeProperty(Display *d, Window w, Atom a1, Atom a2, int i1, int i2, _Xconst unsigned char *c, int i3); -#endif -#ifndef XChangeWindowAttributes_TCL_DECLARED -#define XChangeWindowAttributes_TCL_DECLARED /* 21 */ EXTERN int XChangeWindowAttributes(Display *d, Window w, unsigned long ul, XSetWindowAttributes *x); -#endif -#ifndef XClearWindow_TCL_DECLARED -#define XClearWindow_TCL_DECLARED /* 22 */ EXTERN int XClearWindow(Display *d, Window w); -#endif -#ifndef XConfigureWindow_TCL_DECLARED -#define XConfigureWindow_TCL_DECLARED /* 23 */ EXTERN int XConfigureWindow(Display *d, Window w, unsigned int i, XWindowChanges *x); -#endif -#ifndef XCopyArea_TCL_DECLARED -#define XCopyArea_TCL_DECLARED /* 24 */ EXTERN int XCopyArea(Display *d, Drawable dr1, Drawable dr2, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4); -#endif -#ifndef XCopyPlane_TCL_DECLARED -#define XCopyPlane_TCL_DECLARED /* 25 */ EXTERN int XCopyPlane(Display *d, Drawable dr1, Drawable dr2, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4, unsigned long ul); -#endif -#ifndef XCreateBitmapFromData_TCL_DECLARED -#define XCreateBitmapFromData_TCL_DECLARED /* 26 */ EXTERN Pixmap XCreateBitmapFromData(Display *display, Drawable d, _Xconst char *data, unsigned int width, unsigned int height); -#endif -#ifndef XDefineCursor_TCL_DECLARED -#define XDefineCursor_TCL_DECLARED /* 27 */ EXTERN int XDefineCursor(Display *d, Window w, Cursor c); -#endif -#ifndef XDeleteProperty_TCL_DECLARED -#define XDeleteProperty_TCL_DECLARED /* 28 */ EXTERN int XDeleteProperty(Display *d, Window w, Atom a); -#endif -#ifndef XDestroyWindow_TCL_DECLARED -#define XDestroyWindow_TCL_DECLARED /* 29 */ EXTERN int XDestroyWindow(Display *d, Window w); -#endif -#ifndef XDrawArc_TCL_DECLARED -#define XDrawArc_TCL_DECLARED /* 30 */ EXTERN int XDrawArc(Display *d, Drawable dr, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4); -#endif -#ifndef XDrawLines_TCL_DECLARED -#define XDrawLines_TCL_DECLARED /* 31 */ EXTERN int XDrawLines(Display *d, Drawable dr, GC g, XPoint *x, int i1, int i2); -#endif -#ifndef XDrawRectangle_TCL_DECLARED -#define XDrawRectangle_TCL_DECLARED /* 32 */ EXTERN int XDrawRectangle(Display *d, Drawable dr, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2); -#endif -#ifndef XFillArc_TCL_DECLARED -#define XFillArc_TCL_DECLARED /* 33 */ EXTERN int XFillArc(Display *d, Drawable dr, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4); -#endif -#ifndef XFillPolygon_TCL_DECLARED -#define XFillPolygon_TCL_DECLARED /* 34 */ EXTERN int XFillPolygon(Display *d, Drawable dr, GC g, XPoint *x, int i1, int i2, int i3); -#endif -#ifndef XFillRectangles_TCL_DECLARED -#define XFillRectangles_TCL_DECLARED /* 35 */ EXTERN int XFillRectangles(Display *d, Drawable dr, GC g, XRectangle *x, int i); -#endif -#ifndef XForceScreenSaver_TCL_DECLARED -#define XForceScreenSaver_TCL_DECLARED /* 36 */ EXTERN int XForceScreenSaver(Display *d, int i); -#endif -#ifndef XFreeColormap_TCL_DECLARED -#define XFreeColormap_TCL_DECLARED /* 37 */ EXTERN int XFreeColormap(Display *d, Colormap c); -#endif -#ifndef XFreeColors_TCL_DECLARED -#define XFreeColors_TCL_DECLARED /* 38 */ EXTERN int XFreeColors(Display *d, Colormap c, unsigned long *ulp, int i, unsigned long ul); -#endif -#ifndef XFreeCursor_TCL_DECLARED -#define XFreeCursor_TCL_DECLARED /* 39 */ EXTERN int XFreeCursor(Display *d, Cursor c); -#endif -#ifndef XFreeModifiermap_TCL_DECLARED -#define XFreeModifiermap_TCL_DECLARED /* 40 */ EXTERN int XFreeModifiermap(XModifierKeymap *x); -#endif -#ifndef XGetGeometry_TCL_DECLARED -#define XGetGeometry_TCL_DECLARED /* 41 */ EXTERN Status XGetGeometry(Display *d, Drawable dr, Window *w, int *i1, int *i2, unsigned int *ui1, unsigned int *ui2, unsigned int *ui3, unsigned int *ui4); -#endif -#ifndef XGetInputFocus_TCL_DECLARED -#define XGetInputFocus_TCL_DECLARED /* 42 */ EXTERN int XGetInputFocus(Display *d, Window *w, int *i); -#endif -#ifndef XGetWindowProperty_TCL_DECLARED -#define XGetWindowProperty_TCL_DECLARED /* 43 */ EXTERN int XGetWindowProperty(Display *d, Window w, Atom a1, long l1, long l2, Bool b, Atom a2, Atom *ap, int *ip, unsigned long *ulp1, unsigned long *ulp2, unsigned char **cpp); -#endif -#ifndef XGetWindowAttributes_TCL_DECLARED -#define XGetWindowAttributes_TCL_DECLARED /* 44 */ EXTERN Status XGetWindowAttributes(Display *d, Window w, XWindowAttributes *x); -#endif -#ifndef XGrabKeyboard_TCL_DECLARED -#define XGrabKeyboard_TCL_DECLARED /* 45 */ EXTERN int XGrabKeyboard(Display *d, Window w, Bool b, int i1, int i2, Time t); -#endif -#ifndef XGrabPointer_TCL_DECLARED -#define XGrabPointer_TCL_DECLARED /* 46 */ EXTERN int XGrabPointer(Display *d, Window w1, Bool b, unsigned int ui, int i1, int i2, Window w2, Cursor c, Time t); -#endif -#ifndef XKeysymToKeycode_TCL_DECLARED -#define XKeysymToKeycode_TCL_DECLARED /* 47 */ EXTERN KeyCode XKeysymToKeycode(Display *d, KeySym k); -#endif -#ifndef XLookupColor_TCL_DECLARED -#define XLookupColor_TCL_DECLARED /* 48 */ EXTERN Status XLookupColor(Display *d, Colormap c1, _Xconst char *c2, XColor *x1, XColor *x2); -#endif -#ifndef XMapWindow_TCL_DECLARED -#define XMapWindow_TCL_DECLARED /* 49 */ EXTERN int XMapWindow(Display *d, Window w); -#endif -#ifndef XMoveResizeWindow_TCL_DECLARED -#define XMoveResizeWindow_TCL_DECLARED /* 50 */ EXTERN int XMoveResizeWindow(Display *d, Window w, int i1, int i2, unsigned int ui1, unsigned int ui2); -#endif -#ifndef XMoveWindow_TCL_DECLARED -#define XMoveWindow_TCL_DECLARED /* 51 */ EXTERN int XMoveWindow(Display *d, Window w, int i1, int i2); -#endif -#ifndef XNextEvent_TCL_DECLARED -#define XNextEvent_TCL_DECLARED /* 52 */ EXTERN int XNextEvent(Display *d, XEvent *x); -#endif -#ifndef XPutBackEvent_TCL_DECLARED -#define XPutBackEvent_TCL_DECLARED /* 53 */ EXTERN int XPutBackEvent(Display *d, XEvent *x); -#endif -#ifndef XQueryColors_TCL_DECLARED -#define XQueryColors_TCL_DECLARED /* 54 */ EXTERN int XQueryColors(Display *d, Colormap c, XColor *x, int i); -#endif -#ifndef XQueryPointer_TCL_DECLARED -#define XQueryPointer_TCL_DECLARED /* 55 */ EXTERN Bool XQueryPointer(Display *d, Window w1, Window *w2, Window *w3, int *i1, int *i2, int *i3, int *i4, unsigned int *ui); -#endif -#ifndef XQueryTree_TCL_DECLARED -#define XQueryTree_TCL_DECLARED /* 56 */ EXTERN Status XQueryTree(Display *d, Window w1, Window *w2, Window *w3, Window **w4, unsigned int *ui); -#endif -#ifndef XRaiseWindow_TCL_DECLARED -#define XRaiseWindow_TCL_DECLARED /* 57 */ EXTERN int XRaiseWindow(Display *d, Window w); -#endif -#ifndef XRefreshKeyboardMapping_TCL_DECLARED -#define XRefreshKeyboardMapping_TCL_DECLARED /* 58 */ EXTERN int XRefreshKeyboardMapping(XMappingEvent *x); -#endif -#ifndef XResizeWindow_TCL_DECLARED -#define XResizeWindow_TCL_DECLARED /* 59 */ EXTERN int XResizeWindow(Display *d, Window w, unsigned int ui1, unsigned int ui2); -#endif -#ifndef XSelectInput_TCL_DECLARED -#define XSelectInput_TCL_DECLARED /* 60 */ EXTERN int XSelectInput(Display *d, Window w, long l); -#endif -#ifndef XSendEvent_TCL_DECLARED -#define XSendEvent_TCL_DECLARED /* 61 */ EXTERN Status XSendEvent(Display *d, Window w, Bool b, long l, XEvent *x); -#endif -#ifndef XSetCommand_TCL_DECLARED -#define XSetCommand_TCL_DECLARED /* 62 */ EXTERN int XSetCommand(Display *d, Window w, char **c, int i); -#endif -#ifndef XSetIconName_TCL_DECLARED -#define XSetIconName_TCL_DECLARED /* 63 */ EXTERN int XSetIconName(Display *d, Window w, _Xconst char *c); -#endif -#ifndef XSetInputFocus_TCL_DECLARED -#define XSetInputFocus_TCL_DECLARED /* 64 */ EXTERN int XSetInputFocus(Display *d, Window w, int i, Time t); -#endif -#ifndef XSetSelectionOwner_TCL_DECLARED -#define XSetSelectionOwner_TCL_DECLARED /* 65 */ EXTERN int XSetSelectionOwner(Display *d, Atom a, Window w, Time t); -#endif -#ifndef XSetWindowBackground_TCL_DECLARED -#define XSetWindowBackground_TCL_DECLARED /* 66 */ EXTERN int XSetWindowBackground(Display *d, Window w, unsigned long ul); -#endif -#ifndef XSetWindowBackgroundPixmap_TCL_DECLARED -#define XSetWindowBackgroundPixmap_TCL_DECLARED /* 67 */ EXTERN int XSetWindowBackgroundPixmap(Display *d, Window w, Pixmap p); -#endif -#ifndef XSetWindowBorder_TCL_DECLARED -#define XSetWindowBorder_TCL_DECLARED /* 68 */ EXTERN int XSetWindowBorder(Display *d, Window w, unsigned long ul); -#endif -#ifndef XSetWindowBorderPixmap_TCL_DECLARED -#define XSetWindowBorderPixmap_TCL_DECLARED /* 69 */ EXTERN int XSetWindowBorderPixmap(Display *d, Window w, Pixmap p); -#endif -#ifndef XSetWindowBorderWidth_TCL_DECLARED -#define XSetWindowBorderWidth_TCL_DECLARED /* 70 */ EXTERN int XSetWindowBorderWidth(Display *d, Window w, unsigned int ui); -#endif -#ifndef XSetWindowColormap_TCL_DECLARED -#define XSetWindowColormap_TCL_DECLARED /* 71 */ EXTERN int XSetWindowColormap(Display *d, Window w, Colormap c); -#endif -#ifndef XTranslateCoordinates_TCL_DECLARED -#define XTranslateCoordinates_TCL_DECLARED /* 72 */ EXTERN Bool XTranslateCoordinates(Display *d, Window w1, Window w2, int i1, int i2, int *i3, int *i4, Window *w3); -#endif -#ifndef XUngrabKeyboard_TCL_DECLARED -#define XUngrabKeyboard_TCL_DECLARED /* 73 */ EXTERN int XUngrabKeyboard(Display *d, Time t); -#endif -#ifndef XUngrabPointer_TCL_DECLARED -#define XUngrabPointer_TCL_DECLARED /* 74 */ EXTERN int XUngrabPointer(Display *d, Time t); -#endif -#ifndef XUnmapWindow_TCL_DECLARED -#define XUnmapWindow_TCL_DECLARED /* 75 */ EXTERN int XUnmapWindow(Display *d, Window w); -#endif -#ifndef XWindowEvent_TCL_DECLARED -#define XWindowEvent_TCL_DECLARED /* 76 */ EXTERN int XWindowEvent(Display *d, Window w, long l, XEvent *x); -#endif -#ifndef XDestroyIC_TCL_DECLARED -#define XDestroyIC_TCL_DECLARED /* 77 */ EXTERN void XDestroyIC(XIC x); -#endif -#ifndef XFilterEvent_TCL_DECLARED -#define XFilterEvent_TCL_DECLARED /* 78 */ EXTERN Bool XFilterEvent(XEvent *x, Window w); -#endif -#ifndef XmbLookupString_TCL_DECLARED -#define XmbLookupString_TCL_DECLARED /* 79 */ EXTERN int XmbLookupString(XIC xi, XKeyPressedEvent *xk, char *c, int i, KeySym *k, Status *s); -#endif -#ifndef TkPutImage_TCL_DECLARED -#define TkPutImage_TCL_DECLARED /* 80 */ EXTERN int TkPutImage(unsigned long *colors, int ncolors, Display *display, Drawable d, GC gc, XImage *image, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height); -#endif /* Slot 81 is reserved */ -#ifndef XParseColor_TCL_DECLARED -#define XParseColor_TCL_DECLARED /* 82 */ EXTERN Status XParseColor(Display *display, Colormap map, _Xconst char *spec, XColor *colorPtr); -#endif -#ifndef XCreateGC_TCL_DECLARED -#define XCreateGC_TCL_DECLARED /* 83 */ EXTERN GC XCreateGC(Display *display, Drawable d, unsigned long valuemask, XGCValues *values); -#endif -#ifndef XFreeGC_TCL_DECLARED -#define XFreeGC_TCL_DECLARED /* 84 */ EXTERN int XFreeGC(Display *display, GC gc); -#endif -#ifndef XInternAtom_TCL_DECLARED -#define XInternAtom_TCL_DECLARED /* 85 */ EXTERN Atom XInternAtom(Display *display, _Xconst char *atom_name, Bool only_if_exists); -#endif -#ifndef XSetBackground_TCL_DECLARED -#define XSetBackground_TCL_DECLARED /* 86 */ EXTERN int XSetBackground(Display *display, GC gc, unsigned long foreground); -#endif -#ifndef XSetForeground_TCL_DECLARED -#define XSetForeground_TCL_DECLARED /* 87 */ EXTERN int XSetForeground(Display *display, GC gc, unsigned long foreground); -#endif -#ifndef XSetClipMask_TCL_DECLARED -#define XSetClipMask_TCL_DECLARED /* 88 */ EXTERN int XSetClipMask(Display *display, GC gc, Pixmap pixmap); -#endif -#ifndef XSetClipOrigin_TCL_DECLARED -#define XSetClipOrigin_TCL_DECLARED /* 89 */ EXTERN int XSetClipOrigin(Display *display, GC gc, int clip_x_origin, int clip_y_origin); -#endif -#ifndef XSetTSOrigin_TCL_DECLARED -#define XSetTSOrigin_TCL_DECLARED /* 90 */ EXTERN int XSetTSOrigin(Display *display, GC gc, int ts_x_origin, int ts_y_origin); -#endif -#ifndef XChangeGC_TCL_DECLARED -#define XChangeGC_TCL_DECLARED /* 91 */ EXTERN int XChangeGC(Display *d, GC gc, unsigned long mask, XGCValues *values); -#endif -#ifndef XSetFont_TCL_DECLARED -#define XSetFont_TCL_DECLARED /* 92 */ EXTERN int XSetFont(Display *display, GC gc, Font font); -#endif -#ifndef XSetArcMode_TCL_DECLARED -#define XSetArcMode_TCL_DECLARED /* 93 */ EXTERN int XSetArcMode(Display *display, GC gc, int arc_mode); -#endif -#ifndef XSetStipple_TCL_DECLARED -#define XSetStipple_TCL_DECLARED /* 94 */ EXTERN int XSetStipple(Display *display, GC gc, Pixmap stipple); -#endif -#ifndef XSetFillRule_TCL_DECLARED -#define XSetFillRule_TCL_DECLARED /* 95 */ EXTERN int XSetFillRule(Display *display, GC gc, int fill_rule); -#endif -#ifndef XSetFillStyle_TCL_DECLARED -#define XSetFillStyle_TCL_DECLARED /* 96 */ EXTERN int XSetFillStyle(Display *display, GC gc, int fill_style); -#endif -#ifndef XSetFunction_TCL_DECLARED -#define XSetFunction_TCL_DECLARED /* 97 */ EXTERN int XSetFunction(Display *display, GC gc, int function); -#endif -#ifndef XSetLineAttributes_TCL_DECLARED -#define XSetLineAttributes_TCL_DECLARED /* 98 */ EXTERN int XSetLineAttributes(Display *display, GC gc, unsigned int line_width, int line_style, int cap_style, int join_style); -#endif -#ifndef _XInitImageFuncPtrs_TCL_DECLARED -#define _XInitImageFuncPtrs_TCL_DECLARED /* 99 */ EXTERN int _XInitImageFuncPtrs(XImage *image); -#endif -#ifndef XCreateIC_TCL_DECLARED -#define XCreateIC_TCL_DECLARED /* 100 */ EXTERN XIC XCreateIC(XIM xim, ...); -#endif -#ifndef XGetVisualInfo_TCL_DECLARED -#define XGetVisualInfo_TCL_DECLARED /* 101 */ EXTERN XVisualInfo * XGetVisualInfo(Display *display, long vinfo_mask, XVisualInfo *vinfo_template, int *nitems_return); -#endif -#ifndef XSetWMClientMachine_TCL_DECLARED -#define XSetWMClientMachine_TCL_DECLARED /* 102 */ EXTERN void XSetWMClientMachine(Display *display, Window w, XTextProperty *text_prop); -#endif -#ifndef XStringListToTextProperty_TCL_DECLARED -#define XStringListToTextProperty_TCL_DECLARED /* 103 */ EXTERN Status XStringListToTextProperty(char **list, int count, XTextProperty *text_prop_return); -#endif -#ifndef XDrawLine_TCL_DECLARED -#define XDrawLine_TCL_DECLARED /* 104 */ EXTERN int XDrawLine(Display *d, Drawable dr, GC g, int x1, int y1, int x2, int y2); -#endif -#ifndef XWarpPointer_TCL_DECLARED -#define XWarpPointer_TCL_DECLARED /* 105 */ EXTERN int XWarpPointer(Display *d, Window s, Window dw, int sx, int sy, unsigned int sw, unsigned int sh, int dx, int dy); -#endif -#ifndef XFillRectangle_TCL_DECLARED -#define XFillRectangle_TCL_DECLARED /* 106 */ EXTERN int XFillRectangle(Display *display, Drawable d, GC gc, int x, int y, unsigned int width, unsigned int height); -#endif -#ifndef XFlush_TCL_DECLARED -#define XFlush_TCL_DECLARED /* 107 */ EXTERN int XFlush(Display *display); -#endif -#ifndef XGrabServer_TCL_DECLARED -#define XGrabServer_TCL_DECLARED /* 108 */ EXTERN int XGrabServer(Display *display); -#endif -#ifndef XUngrabServer_TCL_DECLARED -#define XUngrabServer_TCL_DECLARED /* 109 */ EXTERN int XUngrabServer(Display *display); -#endif -#ifndef XFree_TCL_DECLARED -#define XFree_TCL_DECLARED /* 110 */ -EXTERN int XFree(VOID *data); -#endif -#ifndef XNoOp_TCL_DECLARED -#define XNoOp_TCL_DECLARED +EXTERN int XFree(void *data); /* 111 */ EXTERN int XNoOp(Display *display); -#endif -#ifndef XSynchronize_TCL_DECLARED -#define XSynchronize_TCL_DECLARED /* 112 */ EXTERN XAfterFunction XSynchronize(Display *display, Bool onoff); -#endif -#ifndef XSync_TCL_DECLARED -#define XSync_TCL_DECLARED /* 113 */ EXTERN int XSync(Display *display, Bool discard); -#endif -#ifndef XVisualIDFromVisual_TCL_DECLARED -#define XVisualIDFromVisual_TCL_DECLARED /* 114 */ EXTERN VisualID XVisualIDFromVisual(Visual *visual); -#endif /* Slot 115 is reserved */ /* Slot 116 is reserved */ /* Slot 117 is reserved */ /* Slot 118 is reserved */ /* Slot 119 is reserved */ -/* Slot 120 is reserved */ -/* Slot 121 is reserved */ -/* Slot 122 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 */ -/* Slot 129 is reserved */ -/* Slot 130 is reserved */ -/* Slot 131 is reserved */ -/* Slot 132 is reserved */ -#ifndef XDrawSegments_TCL_DECLARED -#define XDrawSegments_TCL_DECLARED +/* 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); -#endif -#ifndef XDrawPoint_TCL_DECLARED -#define XDrawPoint_TCL_DECLARED /* 134 */ EXTERN int XDrawPoint(Display *d, Drawable dr, GC gc, int x, int y); -#endif -#ifndef XDrawPoints_TCL_DECLARED -#define XDrawPoints_TCL_DECLARED /* 135 */ EXTERN int XDrawPoints(Display *d, Drawable dr, GC gc, XPoint *p, int n, int m); -#endif +/* 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 */ -#ifndef XSetDashes_TCL_DECLARED -#define XSetDashes_TCL_DECLARED /* 0 */ EXTERN int XSetDashes(Display *display, GC gc, int dash_offset, _Xconst char *dash_list, int n); -#endif -#ifndef XGetModifierMapping_TCL_DECLARED -#define XGetModifierMapping_TCL_DECLARED /* 1 */ EXTERN XModifierKeymap * XGetModifierMapping(Display *d); -#endif -#ifndef XCreateImage_TCL_DECLARED -#define XCreateImage_TCL_DECLARED /* 2 */ EXTERN XImage * XCreateImage(Display *d, Visual *v, unsigned int ui1, int i1, int i2, char *cp, unsigned int ui2, unsigned int ui3, int i3, int i4); -#endif -#ifndef XGetImage_TCL_DECLARED -#define XGetImage_TCL_DECLARED /* 3 */ EXTERN XImage * XGetImage(Display *d, Drawable dr, int i1, int i2, unsigned int ui1, unsigned int ui2, unsigned long ul, int i3); -#endif -#ifndef XGetAtomName_TCL_DECLARED -#define XGetAtomName_TCL_DECLARED /* 4 */ EXTERN char * XGetAtomName(Display *d, Atom a); -#endif -#ifndef XKeysymToString_TCL_DECLARED -#define XKeysymToString_TCL_DECLARED /* 5 */ EXTERN char * XKeysymToString(KeySym k); -#endif -#ifndef XCreateColormap_TCL_DECLARED -#define XCreateColormap_TCL_DECLARED /* 6 */ EXTERN Colormap XCreateColormap(Display *d, Window w, Visual *v, int i); -#endif -#ifndef XGContextFromGC_TCL_DECLARED -#define XGContextFromGC_TCL_DECLARED /* 7 */ EXTERN GContext XGContextFromGC(GC g); -#endif -#ifndef XKeycodeToKeysym_TCL_DECLARED -#define XKeycodeToKeysym_TCL_DECLARED /* 8 */ EXTERN KeySym XKeycodeToKeysym(Display *d, KeyCode k, int i); -#endif -#ifndef XStringToKeysym_TCL_DECLARED -#define XStringToKeysym_TCL_DECLARED /* 9 */ EXTERN KeySym XStringToKeysym(_Xconst char *c); -#endif -#ifndef XRootWindow_TCL_DECLARED -#define XRootWindow_TCL_DECLARED /* 10 */ EXTERN Window XRootWindow(Display *d, int i); -#endif -#ifndef XSetErrorHandler_TCL_DECLARED -#define XSetErrorHandler_TCL_DECLARED /* 11 */ EXTERN XErrorHandler XSetErrorHandler(XErrorHandler x); -#endif -#ifndef XAllocColor_TCL_DECLARED -#define XAllocColor_TCL_DECLARED /* 12 */ EXTERN Status XAllocColor(Display *d, Colormap c, XColor *xp); -#endif -#ifndef XBell_TCL_DECLARED -#define XBell_TCL_DECLARED /* 13 */ EXTERN int XBell(Display *d, int i); -#endif -#ifndef XChangeProperty_TCL_DECLARED -#define XChangeProperty_TCL_DECLARED /* 14 */ EXTERN void XChangeProperty(Display *d, Window w, Atom a1, Atom a2, int i1, int i2, _Xconst unsigned char *c, int i3); -#endif -#ifndef XChangeWindowAttributes_TCL_DECLARED -#define XChangeWindowAttributes_TCL_DECLARED /* 15 */ EXTERN void XChangeWindowAttributes(Display *d, Window w, unsigned long ul, XSetWindowAttributes *x); -#endif -#ifndef XConfigureWindow_TCL_DECLARED -#define XConfigureWindow_TCL_DECLARED /* 16 */ EXTERN void XConfigureWindow(Display *d, Window w, unsigned int i, XWindowChanges *x); -#endif -#ifndef XCopyArea_TCL_DECLARED -#define XCopyArea_TCL_DECLARED /* 17 */ EXTERN void XCopyArea(Display *d, Drawable dr1, Drawable dr2, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4); -#endif -#ifndef XCopyPlane_TCL_DECLARED -#define XCopyPlane_TCL_DECLARED /* 18 */ EXTERN void XCopyPlane(Display *d, Drawable dr1, Drawable dr2, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4, unsigned long ul); -#endif -#ifndef XCreateBitmapFromData_TCL_DECLARED -#define XCreateBitmapFromData_TCL_DECLARED /* 19 */ EXTERN Pixmap XCreateBitmapFromData(Display *display, Drawable d, _Xconst char *data, unsigned int width, unsigned int height); -#endif -#ifndef XDefineCursor_TCL_DECLARED -#define XDefineCursor_TCL_DECLARED /* 20 */ EXTERN int XDefineCursor(Display *d, Window w, Cursor c); -#endif -#ifndef XDestroyWindow_TCL_DECLARED -#define XDestroyWindow_TCL_DECLARED /* 21 */ EXTERN void XDestroyWindow(Display *d, Window w); -#endif -#ifndef XDrawArc_TCL_DECLARED -#define XDrawArc_TCL_DECLARED /* 22 */ EXTERN void XDrawArc(Display *d, Drawable dr, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4); -#endif -#ifndef XDrawLines_TCL_DECLARED -#define XDrawLines_TCL_DECLARED /* 23 */ EXTERN int XDrawLines(Display *d, Drawable dr, GC g, XPoint *x, int i1, int i2); -#endif -#ifndef XDrawRectangle_TCL_DECLARED -#define XDrawRectangle_TCL_DECLARED /* 24 */ EXTERN void XDrawRectangle(Display *d, Drawable dr, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2); -#endif -#ifndef XFillArc_TCL_DECLARED -#define XFillArc_TCL_DECLARED /* 25 */ EXTERN void XFillArc(Display *d, Drawable dr, GC g, int i1, int i2, unsigned int ui1, unsigned int ui2, int i3, int i4); -#endif -#ifndef XFillPolygon_TCL_DECLARED -#define XFillPolygon_TCL_DECLARED /* 26 */ EXTERN void XFillPolygon(Display *d, Drawable dr, GC g, XPoint *x, int i1, int i2, int i3); -#endif -#ifndef XFillRectangles_TCL_DECLARED -#define XFillRectangles_TCL_DECLARED /* 27 */ EXTERN int XFillRectangles(Display *d, Drawable dr, GC g, XRectangle *x, int i); -#endif -#ifndef XFreeColormap_TCL_DECLARED -#define XFreeColormap_TCL_DECLARED /* 28 */ EXTERN int XFreeColormap(Display *d, Colormap c); -#endif -#ifndef XFreeColors_TCL_DECLARED -#define XFreeColors_TCL_DECLARED /* 29 */ EXTERN int XFreeColors(Display *d, Colormap c, unsigned long *ulp, int i, unsigned long ul); -#endif -#ifndef XFreeModifiermap_TCL_DECLARED -#define XFreeModifiermap_TCL_DECLARED /* 30 */ EXTERN int XFreeModifiermap(XModifierKeymap *x); -#endif -#ifndef XGetGeometry_TCL_DECLARED -#define XGetGeometry_TCL_DECLARED /* 31 */ EXTERN Status XGetGeometry(Display *d, Drawable dr, Window *w, int *i1, int *i2, unsigned int *ui1, unsigned int *ui2, unsigned int *ui3, unsigned int *ui4); -#endif -#ifndef XGetWindowProperty_TCL_DECLARED -#define XGetWindowProperty_TCL_DECLARED /* 32 */ EXTERN int XGetWindowProperty(Display *d, Window w, Atom a1, long l1, long l2, Bool b, Atom a2, Atom *ap, int *ip, unsigned long *ulp1, unsigned long *ulp2, unsigned char **cpp); -#endif -#ifndef XGrabKeyboard_TCL_DECLARED -#define XGrabKeyboard_TCL_DECLARED /* 33 */ EXTERN int XGrabKeyboard(Display *d, Window w, Bool b, int i1, int i2, Time t); -#endif -#ifndef XGrabPointer_TCL_DECLARED -#define XGrabPointer_TCL_DECLARED /* 34 */ EXTERN int XGrabPointer(Display *d, Window w1, Bool b, unsigned int ui, int i1, int i2, Window w2, Cursor c, Time t); -#endif -#ifndef XKeysymToKeycode_TCL_DECLARED -#define XKeysymToKeycode_TCL_DECLARED /* 35 */ EXTERN KeyCode XKeysymToKeycode(Display *d, KeySym k); -#endif -#ifndef XMapWindow_TCL_DECLARED -#define XMapWindow_TCL_DECLARED /* 36 */ EXTERN void XMapWindow(Display *d, Window w); -#endif -#ifndef XMoveResizeWindow_TCL_DECLARED -#define XMoveResizeWindow_TCL_DECLARED /* 37 */ EXTERN void XMoveResizeWindow(Display *d, Window w, int i1, int i2, unsigned int ui1, unsigned int ui2); -#endif -#ifndef XMoveWindow_TCL_DECLARED -#define XMoveWindow_TCL_DECLARED /* 38 */ EXTERN void XMoveWindow(Display *d, Window w, int i1, int i2); -#endif -#ifndef XQueryPointer_TCL_DECLARED -#define XQueryPointer_TCL_DECLARED /* 39 */ EXTERN Bool XQueryPointer(Display *d, Window w1, Window *w2, Window *w3, int *i1, int *i2, int *i3, int *i4, unsigned int *ui); -#endif -#ifndef XRaiseWindow_TCL_DECLARED -#define XRaiseWindow_TCL_DECLARED /* 40 */ EXTERN void XRaiseWindow(Display *d, Window w); -#endif -#ifndef XRefreshKeyboardMapping_TCL_DECLARED -#define XRefreshKeyboardMapping_TCL_DECLARED /* 41 */ EXTERN void XRefreshKeyboardMapping(XMappingEvent *x); -#endif -#ifndef XResizeWindow_TCL_DECLARED -#define XResizeWindow_TCL_DECLARED /* 42 */ EXTERN void XResizeWindow(Display *d, Window w, unsigned int ui1, unsigned int ui2); -#endif -#ifndef XSelectInput_TCL_DECLARED -#define XSelectInput_TCL_DECLARED /* 43 */ EXTERN void XSelectInput(Display *d, Window w, long l); -#endif -#ifndef XSendEvent_TCL_DECLARED -#define XSendEvent_TCL_DECLARED /* 44 */ EXTERN Status XSendEvent(Display *d, Window w, Bool b, long l, XEvent *x); -#endif -#ifndef XSetIconName_TCL_DECLARED -#define XSetIconName_TCL_DECLARED /* 45 */ EXTERN void XSetIconName(Display *d, Window w, _Xconst char *c); -#endif -#ifndef XSetInputFocus_TCL_DECLARED -#define XSetInputFocus_TCL_DECLARED /* 46 */ EXTERN void XSetInputFocus(Display *d, Window w, int i, Time t); -#endif -#ifndef XSetSelectionOwner_TCL_DECLARED -#define XSetSelectionOwner_TCL_DECLARED /* 47 */ EXTERN int XSetSelectionOwner(Display *d, Atom a, Window w, Time t); -#endif -#ifndef XSetWindowBackground_TCL_DECLARED -#define XSetWindowBackground_TCL_DECLARED /* 48 */ EXTERN void XSetWindowBackground(Display *d, Window w, unsigned long ul); -#endif -#ifndef XSetWindowBackgroundPixmap_TCL_DECLARED -#define XSetWindowBackgroundPixmap_TCL_DECLARED /* 49 */ EXTERN void XSetWindowBackgroundPixmap(Display *d, Window w, Pixmap p); -#endif -#ifndef XSetWindowBorder_TCL_DECLARED -#define XSetWindowBorder_TCL_DECLARED /* 50 */ EXTERN void XSetWindowBorder(Display *d, Window w, unsigned long ul); -#endif -#ifndef XSetWindowBorderPixmap_TCL_DECLARED -#define XSetWindowBorderPixmap_TCL_DECLARED /* 51 */ EXTERN void XSetWindowBorderPixmap(Display *d, Window w, Pixmap p); -#endif -#ifndef XSetWindowBorderWidth_TCL_DECLARED -#define XSetWindowBorderWidth_TCL_DECLARED /* 52 */ EXTERN void XSetWindowBorderWidth(Display *d, Window w, unsigned int ui); -#endif -#ifndef XSetWindowColormap_TCL_DECLARED -#define XSetWindowColormap_TCL_DECLARED /* 53 */ EXTERN void XSetWindowColormap(Display *d, Window w, Colormap c); -#endif -#ifndef XUngrabKeyboard_TCL_DECLARED -#define XUngrabKeyboard_TCL_DECLARED /* 54 */ EXTERN void XUngrabKeyboard(Display *d, Time t); -#endif -#ifndef XUngrabPointer_TCL_DECLARED -#define XUngrabPointer_TCL_DECLARED /* 55 */ EXTERN int XUngrabPointer(Display *d, Time t); -#endif -#ifndef XUnmapWindow_TCL_DECLARED -#define XUnmapWindow_TCL_DECLARED /* 56 */ EXTERN void XUnmapWindow(Display *d, Window w); -#endif -#ifndef TkPutImage_TCL_DECLARED -#define TkPutImage_TCL_DECLARED /* 57 */ EXTERN int TkPutImage(unsigned long *colors, int ncolors, Display *display, Drawable d, GC gc, XImage *image, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height); -#endif -#ifndef XParseColor_TCL_DECLARED -#define XParseColor_TCL_DECLARED /* 58 */ EXTERN Status XParseColor(Display *display, Colormap map, _Xconst char *spec, XColor *colorPtr); -#endif -#ifndef XCreateGC_TCL_DECLARED -#define XCreateGC_TCL_DECLARED /* 59 */ EXTERN GC XCreateGC(Display *display, Drawable d, unsigned long valuemask, XGCValues *values); -#endif -#ifndef XFreeGC_TCL_DECLARED -#define XFreeGC_TCL_DECLARED /* 60 */ EXTERN int XFreeGC(Display *display, GC gc); -#endif -#ifndef XInternAtom_TCL_DECLARED -#define XInternAtom_TCL_DECLARED /* 61 */ EXTERN Atom XInternAtom(Display *display, _Xconst char *atom_name, Bool only_if_exists); -#endif -#ifndef XSetBackground_TCL_DECLARED -#define XSetBackground_TCL_DECLARED /* 62 */ EXTERN int XSetBackground(Display *display, GC gc, unsigned long foreground); -#endif -#ifndef XSetForeground_TCL_DECLARED -#define XSetForeground_TCL_DECLARED /* 63 */ EXTERN int XSetForeground(Display *display, GC gc, unsigned long foreground); -#endif -#ifndef XSetClipMask_TCL_DECLARED -#define XSetClipMask_TCL_DECLARED /* 64 */ EXTERN int XSetClipMask(Display *display, GC gc, Pixmap pixmap); -#endif -#ifndef XSetClipOrigin_TCL_DECLARED -#define XSetClipOrigin_TCL_DECLARED /* 65 */ EXTERN int XSetClipOrigin(Display *display, GC gc, int clip_x_origin, int clip_y_origin); -#endif -#ifndef XSetTSOrigin_TCL_DECLARED -#define XSetTSOrigin_TCL_DECLARED /* 66 */ EXTERN int XSetTSOrigin(Display *display, GC gc, int ts_x_origin, int ts_y_origin); -#endif -#ifndef XChangeGC_TCL_DECLARED -#define XChangeGC_TCL_DECLARED /* 67 */ EXTERN int XChangeGC(Display *d, GC gc, unsigned long mask, XGCValues *values); -#endif -#ifndef XSetFont_TCL_DECLARED -#define XSetFont_TCL_DECLARED /* 68 */ EXTERN int XSetFont(Display *display, GC gc, Font font); -#endif -#ifndef XSetArcMode_TCL_DECLARED -#define XSetArcMode_TCL_DECLARED /* 69 */ EXTERN int XSetArcMode(Display *display, GC gc, int arc_mode); -#endif -#ifndef XSetStipple_TCL_DECLARED -#define XSetStipple_TCL_DECLARED /* 70 */ EXTERN int XSetStipple(Display *display, GC gc, Pixmap stipple); -#endif -#ifndef XSetFillRule_TCL_DECLARED -#define XSetFillRule_TCL_DECLARED /* 71 */ EXTERN int XSetFillRule(Display *display, GC gc, int fill_rule); -#endif -#ifndef XSetFillStyle_TCL_DECLARED -#define XSetFillStyle_TCL_DECLARED /* 72 */ EXTERN int XSetFillStyle(Display *display, GC gc, int fill_style); -#endif -#ifndef XSetFunction_TCL_DECLARED -#define XSetFunction_TCL_DECLARED /* 73 */ EXTERN int XSetFunction(Display *display, GC gc, int function); -#endif -#ifndef XSetLineAttributes_TCL_DECLARED -#define XSetLineAttributes_TCL_DECLARED /* 74 */ EXTERN int XSetLineAttributes(Display *display, GC gc, unsigned int line_width, int line_style, int cap_style, int join_style); -#endif -#ifndef _XInitImageFuncPtrs_TCL_DECLARED -#define _XInitImageFuncPtrs_TCL_DECLARED /* 75 */ EXTERN int _XInitImageFuncPtrs(XImage *image); -#endif -#ifndef XCreateIC_TCL_DECLARED -#define XCreateIC_TCL_DECLARED /* 76 */ EXTERN XIC XCreateIC(void); -#endif -#ifndef XGetVisualInfo_TCL_DECLARED -#define XGetVisualInfo_TCL_DECLARED /* 77 */ EXTERN XVisualInfo * XGetVisualInfo(Display *display, long vinfo_mask, XVisualInfo *vinfo_template, int *nitems_return); -#endif -#ifndef XSetWMClientMachine_TCL_DECLARED -#define XSetWMClientMachine_TCL_DECLARED /* 78 */ EXTERN void XSetWMClientMachine(Display *display, Window w, XTextProperty *text_prop); -#endif -#ifndef XStringListToTextProperty_TCL_DECLARED -#define XStringListToTextProperty_TCL_DECLARED /* 79 */ EXTERN Status XStringListToTextProperty(char **list, int count, XTextProperty *text_prop_return); -#endif -#ifndef XDrawSegments_TCL_DECLARED -#define XDrawSegments_TCL_DECLARED /* 80 */ EXTERN int XDrawSegments(Display *display, Drawable d, GC gc, XSegment *segments, int nsegments); -#endif -#ifndef XForceScreenSaver_TCL_DECLARED -#define XForceScreenSaver_TCL_DECLARED /* 81 */ EXTERN void XForceScreenSaver(Display *display, int mode); -#endif -#ifndef XDrawLine_TCL_DECLARED -#define XDrawLine_TCL_DECLARED /* 82 */ EXTERN int XDrawLine(Display *d, Drawable dr, GC g, int x1, int y1, int x2, int y2); -#endif -#ifndef XFillRectangle_TCL_DECLARED -#define XFillRectangle_TCL_DECLARED /* 83 */ EXTERN int XFillRectangle(Display *display, Drawable d, GC gc, int x, int y, unsigned int width, unsigned int height); -#endif -#ifndef XClearWindow_TCL_DECLARED -#define XClearWindow_TCL_DECLARED /* 84 */ EXTERN void XClearWindow(Display *d, Window w); -#endif -#ifndef XDrawPoint_TCL_DECLARED -#define XDrawPoint_TCL_DECLARED /* 85 */ EXTERN int XDrawPoint(Display *display, Drawable d, GC gc, int x, int y); -#endif -#ifndef XDrawPoints_TCL_DECLARED -#define XDrawPoints_TCL_DECLARED /* 86 */ EXTERN int XDrawPoints(Display *display, Drawable d, GC gc, XPoint *points, int npoints, int mode); -#endif -#ifndef XWarpPointer_TCL_DECLARED -#define XWarpPointer_TCL_DECLARED /* 87 */ EXTERN 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); -#endif -#ifndef XQueryColor_TCL_DECLARED -#define XQueryColor_TCL_DECLARED /* 88 */ EXTERN void XQueryColor(Display *display, Colormap colormap, XColor *def_in_out); -#endif -#ifndef XQueryColors_TCL_DECLARED -#define XQueryColors_TCL_DECLARED /* 89 */ EXTERN void XQueryColors(Display *display, Colormap colormap, XColor *defs_in_out, int ncolors); -#endif -#ifndef XQueryTree_TCL_DECLARED -#define XQueryTree_TCL_DECLARED /* 90 */ EXTERN Status XQueryTree(Display *d, Window w1, Window *w2, Window *w3, Window **w4, unsigned int *ui); -#endif -#ifndef XSync_TCL_DECLARED -#define XSync_TCL_DECLARED /* 91 */ EXTERN int XSync(Display *display, Bool flag); -#endif #endif /* AQUA */ typedef struct TkIntXlibStubs { int magic; - struct TkIntXlibStubHooks *hooks; + void *hooks; -#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */ +#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ int (*xSetDashes) (Display *display, GC gc, int dash_offset, _Xconst char *dash_list, int n); /* 0 */ XModifierKeymap * (*xGetModifierMapping) (Display *d); /* 1 */ XImage * (*xCreateImage) (Display *d, Visual *v, unsigned int ui1, int i1, int i2, char *cp, unsigned int ui2, unsigned int ui3, int i3, int i4); /* 2 */ @@ -1362,7 +765,7 @@ typedef struct TkIntXlibStubs { Bool (*xFilterEvent) (XEvent *x, Window w); /* 78 */ int (*xmbLookupString) (XIC xi, XKeyPressedEvent *xk, char *c, int i, KeySym *k, Status *s); /* 79 */ int (*tkPutImage) (unsigned long *colors, int ncolors, Display *display, Drawable d, GC gc, XImage *image, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height); /* 80 */ - VOID *reserved81; + void (*reserved81)(void); Status (*xParseColor) (Display *display, Colormap map, _Xconst char *spec, XColor *colorPtr); /* 82 */ GC (*xCreateGC) (Display *display, Drawable d, unsigned long valuemask, XGCValues *values); /* 83 */ int (*xFreeGC) (Display *display, GC gc); /* 84 */ @@ -1391,32 +794,34 @@ typedef struct TkIntXlibStubs { int (*xFlush) (Display *display); /* 107 */ int (*xGrabServer) (Display *display); /* 108 */ int (*xUngrabServer) (Display *display); /* 109 */ - int (*xFree) (VOID *data); /* 110 */ + int (*xFree) (void *data); /* 110 */ int (*xNoOp) (Display *display); /* 111 */ XAfterFunction (*xSynchronize) (Display *display, Bool onoff); /* 112 */ int (*xSync) (Display *display, Bool discard); /* 113 */ VisualID (*xVisualIDFromVisual) (Visual *visual); /* 114 */ - VOID *reserved115; - VOID *reserved116; - VOID *reserved117; - VOID *reserved118; - VOID *reserved119; - VOID *reserved120; - VOID *reserved121; - VOID *reserved122; - VOID *reserved123; - VOID *reserved124; - VOID *reserved125; - VOID *reserved126; - VOID *reserved127; - VOID *reserved128; - VOID *reserved129; - VOID *reserved130; - VOID *reserved131; - VOID *reserved132; + 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 */ @@ -1514,944 +919,476 @@ typedef struct TkIntXlibStubs { #endif /* AQUA */ } TkIntXlibStubs; -extern TkIntXlibStubs *tkIntXlibStubsPtr; +extern const TkIntXlibStubs *tkIntXlibStubsPtr; #ifdef __cplusplus } #endif -#if defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS) +#if defined(USE_TK_STUBS) /* * Inline function declarations: */ -#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */ -#ifndef XSetDashes +#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ #define XSetDashes \ (tkIntXlibStubsPtr->xSetDashes) /* 0 */ -#endif -#ifndef XGetModifierMapping #define XGetModifierMapping \ (tkIntXlibStubsPtr->xGetModifierMapping) /* 1 */ -#endif -#ifndef XCreateImage #define XCreateImage \ (tkIntXlibStubsPtr->xCreateImage) /* 2 */ -#endif -#ifndef XGetImage #define XGetImage \ (tkIntXlibStubsPtr->xGetImage) /* 3 */ -#endif -#ifndef XGetAtomName #define XGetAtomName \ (tkIntXlibStubsPtr->xGetAtomName) /* 4 */ -#endif -#ifndef XKeysymToString #define XKeysymToString \ (tkIntXlibStubsPtr->xKeysymToString) /* 5 */ -#endif -#ifndef XCreateColormap #define XCreateColormap \ (tkIntXlibStubsPtr->xCreateColormap) /* 6 */ -#endif -#ifndef XCreatePixmapCursor #define XCreatePixmapCursor \ (tkIntXlibStubsPtr->xCreatePixmapCursor) /* 7 */ -#endif -#ifndef XCreateGlyphCursor #define XCreateGlyphCursor \ (tkIntXlibStubsPtr->xCreateGlyphCursor) /* 8 */ -#endif -#ifndef XGContextFromGC #define XGContextFromGC \ (tkIntXlibStubsPtr->xGContextFromGC) /* 9 */ -#endif -#ifndef XListHosts #define XListHosts \ (tkIntXlibStubsPtr->xListHosts) /* 10 */ -#endif -#ifndef XKeycodeToKeysym #define XKeycodeToKeysym \ (tkIntXlibStubsPtr->xKeycodeToKeysym) /* 11 */ -#endif -#ifndef XStringToKeysym #define XStringToKeysym \ (tkIntXlibStubsPtr->xStringToKeysym) /* 12 */ -#endif -#ifndef XRootWindow #define XRootWindow \ (tkIntXlibStubsPtr->xRootWindow) /* 13 */ -#endif -#ifndef XSetErrorHandler #define XSetErrorHandler \ (tkIntXlibStubsPtr->xSetErrorHandler) /* 14 */ -#endif -#ifndef XIconifyWindow #define XIconifyWindow \ (tkIntXlibStubsPtr->xIconifyWindow) /* 15 */ -#endif -#ifndef XWithdrawWindow #define XWithdrawWindow \ (tkIntXlibStubsPtr->xWithdrawWindow) /* 16 */ -#endif -#ifndef XGetWMColormapWindows #define XGetWMColormapWindows \ (tkIntXlibStubsPtr->xGetWMColormapWindows) /* 17 */ -#endif -#ifndef XAllocColor #define XAllocColor \ (tkIntXlibStubsPtr->xAllocColor) /* 18 */ -#endif -#ifndef XBell #define XBell \ (tkIntXlibStubsPtr->xBell) /* 19 */ -#endif -#ifndef XChangeProperty #define XChangeProperty \ (tkIntXlibStubsPtr->xChangeProperty) /* 20 */ -#endif -#ifndef XChangeWindowAttributes #define XChangeWindowAttributes \ (tkIntXlibStubsPtr->xChangeWindowAttributes) /* 21 */ -#endif -#ifndef XClearWindow #define XClearWindow \ (tkIntXlibStubsPtr->xClearWindow) /* 22 */ -#endif -#ifndef XConfigureWindow #define XConfigureWindow \ (tkIntXlibStubsPtr->xConfigureWindow) /* 23 */ -#endif -#ifndef XCopyArea #define XCopyArea \ (tkIntXlibStubsPtr->xCopyArea) /* 24 */ -#endif -#ifndef XCopyPlane #define XCopyPlane \ (tkIntXlibStubsPtr->xCopyPlane) /* 25 */ -#endif -#ifndef XCreateBitmapFromData #define XCreateBitmapFromData \ (tkIntXlibStubsPtr->xCreateBitmapFromData) /* 26 */ -#endif -#ifndef XDefineCursor #define XDefineCursor \ (tkIntXlibStubsPtr->xDefineCursor) /* 27 */ -#endif -#ifndef XDeleteProperty #define XDeleteProperty \ (tkIntXlibStubsPtr->xDeleteProperty) /* 28 */ -#endif -#ifndef XDestroyWindow #define XDestroyWindow \ (tkIntXlibStubsPtr->xDestroyWindow) /* 29 */ -#endif -#ifndef XDrawArc #define XDrawArc \ (tkIntXlibStubsPtr->xDrawArc) /* 30 */ -#endif -#ifndef XDrawLines #define XDrawLines \ (tkIntXlibStubsPtr->xDrawLines) /* 31 */ -#endif -#ifndef XDrawRectangle #define XDrawRectangle \ (tkIntXlibStubsPtr->xDrawRectangle) /* 32 */ -#endif -#ifndef XFillArc #define XFillArc \ (tkIntXlibStubsPtr->xFillArc) /* 33 */ -#endif -#ifndef XFillPolygon #define XFillPolygon \ (tkIntXlibStubsPtr->xFillPolygon) /* 34 */ -#endif -#ifndef XFillRectangles #define XFillRectangles \ (tkIntXlibStubsPtr->xFillRectangles) /* 35 */ -#endif -#ifndef XForceScreenSaver #define XForceScreenSaver \ (tkIntXlibStubsPtr->xForceScreenSaver) /* 36 */ -#endif -#ifndef XFreeColormap #define XFreeColormap \ (tkIntXlibStubsPtr->xFreeColormap) /* 37 */ -#endif -#ifndef XFreeColors #define XFreeColors \ (tkIntXlibStubsPtr->xFreeColors) /* 38 */ -#endif -#ifndef XFreeCursor #define XFreeCursor \ (tkIntXlibStubsPtr->xFreeCursor) /* 39 */ -#endif -#ifndef XFreeModifiermap #define XFreeModifiermap \ (tkIntXlibStubsPtr->xFreeModifiermap) /* 40 */ -#endif -#ifndef XGetGeometry #define XGetGeometry \ (tkIntXlibStubsPtr->xGetGeometry) /* 41 */ -#endif -#ifndef XGetInputFocus #define XGetInputFocus \ (tkIntXlibStubsPtr->xGetInputFocus) /* 42 */ -#endif -#ifndef XGetWindowProperty #define XGetWindowProperty \ (tkIntXlibStubsPtr->xGetWindowProperty) /* 43 */ -#endif -#ifndef XGetWindowAttributes #define XGetWindowAttributes \ (tkIntXlibStubsPtr->xGetWindowAttributes) /* 44 */ -#endif -#ifndef XGrabKeyboard #define XGrabKeyboard \ (tkIntXlibStubsPtr->xGrabKeyboard) /* 45 */ -#endif -#ifndef XGrabPointer #define XGrabPointer \ (tkIntXlibStubsPtr->xGrabPointer) /* 46 */ -#endif -#ifndef XKeysymToKeycode #define XKeysymToKeycode \ (tkIntXlibStubsPtr->xKeysymToKeycode) /* 47 */ -#endif -#ifndef XLookupColor #define XLookupColor \ (tkIntXlibStubsPtr->xLookupColor) /* 48 */ -#endif -#ifndef XMapWindow #define XMapWindow \ (tkIntXlibStubsPtr->xMapWindow) /* 49 */ -#endif -#ifndef XMoveResizeWindow #define XMoveResizeWindow \ (tkIntXlibStubsPtr->xMoveResizeWindow) /* 50 */ -#endif -#ifndef XMoveWindow #define XMoveWindow \ (tkIntXlibStubsPtr->xMoveWindow) /* 51 */ -#endif -#ifndef XNextEvent #define XNextEvent \ (tkIntXlibStubsPtr->xNextEvent) /* 52 */ -#endif -#ifndef XPutBackEvent #define XPutBackEvent \ (tkIntXlibStubsPtr->xPutBackEvent) /* 53 */ -#endif -#ifndef XQueryColors #define XQueryColors \ (tkIntXlibStubsPtr->xQueryColors) /* 54 */ -#endif -#ifndef XQueryPointer #define XQueryPointer \ (tkIntXlibStubsPtr->xQueryPointer) /* 55 */ -#endif -#ifndef XQueryTree #define XQueryTree \ (tkIntXlibStubsPtr->xQueryTree) /* 56 */ -#endif -#ifndef XRaiseWindow #define XRaiseWindow \ (tkIntXlibStubsPtr->xRaiseWindow) /* 57 */ -#endif -#ifndef XRefreshKeyboardMapping #define XRefreshKeyboardMapping \ (tkIntXlibStubsPtr->xRefreshKeyboardMapping) /* 58 */ -#endif -#ifndef XResizeWindow #define XResizeWindow \ (tkIntXlibStubsPtr->xResizeWindow) /* 59 */ -#endif -#ifndef XSelectInput #define XSelectInput \ (tkIntXlibStubsPtr->xSelectInput) /* 60 */ -#endif -#ifndef XSendEvent #define XSendEvent \ (tkIntXlibStubsPtr->xSendEvent) /* 61 */ -#endif -#ifndef XSetCommand #define XSetCommand \ (tkIntXlibStubsPtr->xSetCommand) /* 62 */ -#endif -#ifndef XSetIconName #define XSetIconName \ (tkIntXlibStubsPtr->xSetIconName) /* 63 */ -#endif -#ifndef XSetInputFocus #define XSetInputFocus \ (tkIntXlibStubsPtr->xSetInputFocus) /* 64 */ -#endif -#ifndef XSetSelectionOwner #define XSetSelectionOwner \ (tkIntXlibStubsPtr->xSetSelectionOwner) /* 65 */ -#endif -#ifndef XSetWindowBackground #define XSetWindowBackground \ (tkIntXlibStubsPtr->xSetWindowBackground) /* 66 */ -#endif -#ifndef XSetWindowBackgroundPixmap #define XSetWindowBackgroundPixmap \ (tkIntXlibStubsPtr->xSetWindowBackgroundPixmap) /* 67 */ -#endif -#ifndef XSetWindowBorder #define XSetWindowBorder \ (tkIntXlibStubsPtr->xSetWindowBorder) /* 68 */ -#endif -#ifndef XSetWindowBorderPixmap #define XSetWindowBorderPixmap \ (tkIntXlibStubsPtr->xSetWindowBorderPixmap) /* 69 */ -#endif -#ifndef XSetWindowBorderWidth #define XSetWindowBorderWidth \ (tkIntXlibStubsPtr->xSetWindowBorderWidth) /* 70 */ -#endif -#ifndef XSetWindowColormap #define XSetWindowColormap \ (tkIntXlibStubsPtr->xSetWindowColormap) /* 71 */ -#endif -#ifndef XTranslateCoordinates #define XTranslateCoordinates \ (tkIntXlibStubsPtr->xTranslateCoordinates) /* 72 */ -#endif -#ifndef XUngrabKeyboard #define XUngrabKeyboard \ (tkIntXlibStubsPtr->xUngrabKeyboard) /* 73 */ -#endif -#ifndef XUngrabPointer #define XUngrabPointer \ (tkIntXlibStubsPtr->xUngrabPointer) /* 74 */ -#endif -#ifndef XUnmapWindow #define XUnmapWindow \ (tkIntXlibStubsPtr->xUnmapWindow) /* 75 */ -#endif -#ifndef XWindowEvent #define XWindowEvent \ (tkIntXlibStubsPtr->xWindowEvent) /* 76 */ -#endif -#ifndef XDestroyIC #define XDestroyIC \ (tkIntXlibStubsPtr->xDestroyIC) /* 77 */ -#endif -#ifndef XFilterEvent #define XFilterEvent \ (tkIntXlibStubsPtr->xFilterEvent) /* 78 */ -#endif -#ifndef XmbLookupString #define XmbLookupString \ (tkIntXlibStubsPtr->xmbLookupString) /* 79 */ -#endif -#ifndef TkPutImage #define TkPutImage \ (tkIntXlibStubsPtr->tkPutImage) /* 80 */ -#endif /* Slot 81 is reserved */ -#ifndef XParseColor #define XParseColor \ (tkIntXlibStubsPtr->xParseColor) /* 82 */ -#endif -#ifndef XCreateGC #define XCreateGC \ (tkIntXlibStubsPtr->xCreateGC) /* 83 */ -#endif -#ifndef XFreeGC #define XFreeGC \ (tkIntXlibStubsPtr->xFreeGC) /* 84 */ -#endif -#ifndef XInternAtom #define XInternAtom \ (tkIntXlibStubsPtr->xInternAtom) /* 85 */ -#endif -#ifndef XSetBackground #define XSetBackground \ (tkIntXlibStubsPtr->xSetBackground) /* 86 */ -#endif -#ifndef XSetForeground #define XSetForeground \ (tkIntXlibStubsPtr->xSetForeground) /* 87 */ -#endif -#ifndef XSetClipMask #define XSetClipMask \ (tkIntXlibStubsPtr->xSetClipMask) /* 88 */ -#endif -#ifndef XSetClipOrigin #define XSetClipOrigin \ (tkIntXlibStubsPtr->xSetClipOrigin) /* 89 */ -#endif -#ifndef XSetTSOrigin #define XSetTSOrigin \ (tkIntXlibStubsPtr->xSetTSOrigin) /* 90 */ -#endif -#ifndef XChangeGC #define XChangeGC \ (tkIntXlibStubsPtr->xChangeGC) /* 91 */ -#endif -#ifndef XSetFont #define XSetFont \ (tkIntXlibStubsPtr->xSetFont) /* 92 */ -#endif -#ifndef XSetArcMode #define XSetArcMode \ (tkIntXlibStubsPtr->xSetArcMode) /* 93 */ -#endif -#ifndef XSetStipple #define XSetStipple \ (tkIntXlibStubsPtr->xSetStipple) /* 94 */ -#endif -#ifndef XSetFillRule #define XSetFillRule \ (tkIntXlibStubsPtr->xSetFillRule) /* 95 */ -#endif -#ifndef XSetFillStyle #define XSetFillStyle \ (tkIntXlibStubsPtr->xSetFillStyle) /* 96 */ -#endif -#ifndef XSetFunction #define XSetFunction \ (tkIntXlibStubsPtr->xSetFunction) /* 97 */ -#endif -#ifndef XSetLineAttributes #define XSetLineAttributes \ (tkIntXlibStubsPtr->xSetLineAttributes) /* 98 */ -#endif -#ifndef _XInitImageFuncPtrs #define _XInitImageFuncPtrs \ (tkIntXlibStubsPtr->_XInitImageFuncPtrs) /* 99 */ -#endif -#ifndef XCreateIC #define XCreateIC \ (tkIntXlibStubsPtr->xCreateIC) /* 100 */ -#endif -#ifndef XGetVisualInfo #define XGetVisualInfo \ (tkIntXlibStubsPtr->xGetVisualInfo) /* 101 */ -#endif -#ifndef XSetWMClientMachine #define XSetWMClientMachine \ (tkIntXlibStubsPtr->xSetWMClientMachine) /* 102 */ -#endif -#ifndef XStringListToTextProperty #define XStringListToTextProperty \ (tkIntXlibStubsPtr->xStringListToTextProperty) /* 103 */ -#endif -#ifndef XDrawLine #define XDrawLine \ (tkIntXlibStubsPtr->xDrawLine) /* 104 */ -#endif -#ifndef XWarpPointer #define XWarpPointer \ (tkIntXlibStubsPtr->xWarpPointer) /* 105 */ -#endif -#ifndef XFillRectangle #define XFillRectangle \ (tkIntXlibStubsPtr->xFillRectangle) /* 106 */ -#endif -#ifndef XFlush #define XFlush \ (tkIntXlibStubsPtr->xFlush) /* 107 */ -#endif -#ifndef XGrabServer #define XGrabServer \ (tkIntXlibStubsPtr->xGrabServer) /* 108 */ -#endif -#ifndef XUngrabServer #define XUngrabServer \ (tkIntXlibStubsPtr->xUngrabServer) /* 109 */ -#endif -#ifndef XFree #define XFree \ (tkIntXlibStubsPtr->xFree) /* 110 */ -#endif -#ifndef XNoOp #define XNoOp \ (tkIntXlibStubsPtr->xNoOp) /* 111 */ -#endif -#ifndef XSynchronize #define XSynchronize \ (tkIntXlibStubsPtr->xSynchronize) /* 112 */ -#endif -#ifndef XSync #define XSync \ (tkIntXlibStubsPtr->xSync) /* 113 */ -#endif -#ifndef XVisualIDFromVisual #define XVisualIDFromVisual \ (tkIntXlibStubsPtr->xVisualIDFromVisual) /* 114 */ -#endif /* Slot 115 is reserved */ /* Slot 116 is reserved */ /* Slot 117 is reserved */ /* Slot 118 is reserved */ /* Slot 119 is reserved */ -/* Slot 120 is reserved */ -/* Slot 121 is reserved */ -/* Slot 122 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 */ -/* Slot 129 is reserved */ -/* Slot 130 is reserved */ -/* Slot 131 is reserved */ -/* Slot 132 is reserved */ -#ifndef XDrawSegments +#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 */ -#endif -#ifndef XDrawPoint #define XDrawPoint \ (tkIntXlibStubsPtr->xDrawPoint) /* 134 */ -#endif -#ifndef XDrawPoints #define XDrawPoints \ (tkIntXlibStubsPtr->xDrawPoints) /* 135 */ -#endif +#define XReparentWindow \ + (tkIntXlibStubsPtr->xReparentWindow) /* 136 */ +#define XPutImage \ + (tkIntXlibStubsPtr->xPutImage) /* 137 */ #endif /* WIN */ #ifdef MAC_OSX_TK /* AQUA */ -#ifndef XSetDashes #define XSetDashes \ (tkIntXlibStubsPtr->xSetDashes) /* 0 */ -#endif -#ifndef XGetModifierMapping #define XGetModifierMapping \ (tkIntXlibStubsPtr->xGetModifierMapping) /* 1 */ -#endif -#ifndef XCreateImage #define XCreateImage \ (tkIntXlibStubsPtr->xCreateImage) /* 2 */ -#endif -#ifndef XGetImage #define XGetImage \ (tkIntXlibStubsPtr->xGetImage) /* 3 */ -#endif -#ifndef XGetAtomName #define XGetAtomName \ (tkIntXlibStubsPtr->xGetAtomName) /* 4 */ -#endif -#ifndef XKeysymToString #define XKeysymToString \ (tkIntXlibStubsPtr->xKeysymToString) /* 5 */ -#endif -#ifndef XCreateColormap #define XCreateColormap \ (tkIntXlibStubsPtr->xCreateColormap) /* 6 */ -#endif -#ifndef XGContextFromGC #define XGContextFromGC \ (tkIntXlibStubsPtr->xGContextFromGC) /* 7 */ -#endif -#ifndef XKeycodeToKeysym #define XKeycodeToKeysym \ (tkIntXlibStubsPtr->xKeycodeToKeysym) /* 8 */ -#endif -#ifndef XStringToKeysym #define XStringToKeysym \ (tkIntXlibStubsPtr->xStringToKeysym) /* 9 */ -#endif -#ifndef XRootWindow #define XRootWindow \ (tkIntXlibStubsPtr->xRootWindow) /* 10 */ -#endif -#ifndef XSetErrorHandler #define XSetErrorHandler \ (tkIntXlibStubsPtr->xSetErrorHandler) /* 11 */ -#endif -#ifndef XAllocColor #define XAllocColor \ (tkIntXlibStubsPtr->xAllocColor) /* 12 */ -#endif -#ifndef XBell #define XBell \ (tkIntXlibStubsPtr->xBell) /* 13 */ -#endif -#ifndef XChangeProperty #define XChangeProperty \ (tkIntXlibStubsPtr->xChangeProperty) /* 14 */ -#endif -#ifndef XChangeWindowAttributes #define XChangeWindowAttributes \ (tkIntXlibStubsPtr->xChangeWindowAttributes) /* 15 */ -#endif -#ifndef XConfigureWindow #define XConfigureWindow \ (tkIntXlibStubsPtr->xConfigureWindow) /* 16 */ -#endif -#ifndef XCopyArea #define XCopyArea \ (tkIntXlibStubsPtr->xCopyArea) /* 17 */ -#endif -#ifndef XCopyPlane #define XCopyPlane \ (tkIntXlibStubsPtr->xCopyPlane) /* 18 */ -#endif -#ifndef XCreateBitmapFromData #define XCreateBitmapFromData \ (tkIntXlibStubsPtr->xCreateBitmapFromData) /* 19 */ -#endif -#ifndef XDefineCursor #define XDefineCursor \ (tkIntXlibStubsPtr->xDefineCursor) /* 20 */ -#endif -#ifndef XDestroyWindow #define XDestroyWindow \ (tkIntXlibStubsPtr->xDestroyWindow) /* 21 */ -#endif -#ifndef XDrawArc #define XDrawArc \ (tkIntXlibStubsPtr->xDrawArc) /* 22 */ -#endif -#ifndef XDrawLines #define XDrawLines \ (tkIntXlibStubsPtr->xDrawLines) /* 23 */ -#endif -#ifndef XDrawRectangle #define XDrawRectangle \ (tkIntXlibStubsPtr->xDrawRectangle) /* 24 */ -#endif -#ifndef XFillArc #define XFillArc \ (tkIntXlibStubsPtr->xFillArc) /* 25 */ -#endif -#ifndef XFillPolygon #define XFillPolygon \ (tkIntXlibStubsPtr->xFillPolygon) /* 26 */ -#endif -#ifndef XFillRectangles #define XFillRectangles \ (tkIntXlibStubsPtr->xFillRectangles) /* 27 */ -#endif -#ifndef XFreeColormap #define XFreeColormap \ (tkIntXlibStubsPtr->xFreeColormap) /* 28 */ -#endif -#ifndef XFreeColors #define XFreeColors \ (tkIntXlibStubsPtr->xFreeColors) /* 29 */ -#endif -#ifndef XFreeModifiermap #define XFreeModifiermap \ (tkIntXlibStubsPtr->xFreeModifiermap) /* 30 */ -#endif -#ifndef XGetGeometry #define XGetGeometry \ (tkIntXlibStubsPtr->xGetGeometry) /* 31 */ -#endif -#ifndef XGetWindowProperty #define XGetWindowProperty \ (tkIntXlibStubsPtr->xGetWindowProperty) /* 32 */ -#endif -#ifndef XGrabKeyboard #define XGrabKeyboard \ (tkIntXlibStubsPtr->xGrabKeyboard) /* 33 */ -#endif -#ifndef XGrabPointer #define XGrabPointer \ (tkIntXlibStubsPtr->xGrabPointer) /* 34 */ -#endif -#ifndef XKeysymToKeycode #define XKeysymToKeycode \ (tkIntXlibStubsPtr->xKeysymToKeycode) /* 35 */ -#endif -#ifndef XMapWindow #define XMapWindow \ (tkIntXlibStubsPtr->xMapWindow) /* 36 */ -#endif -#ifndef XMoveResizeWindow #define XMoveResizeWindow \ (tkIntXlibStubsPtr->xMoveResizeWindow) /* 37 */ -#endif -#ifndef XMoveWindow #define XMoveWindow \ (tkIntXlibStubsPtr->xMoveWindow) /* 38 */ -#endif -#ifndef XQueryPointer #define XQueryPointer \ (tkIntXlibStubsPtr->xQueryPointer) /* 39 */ -#endif -#ifndef XRaiseWindow #define XRaiseWindow \ (tkIntXlibStubsPtr->xRaiseWindow) /* 40 */ -#endif -#ifndef XRefreshKeyboardMapping #define XRefreshKeyboardMapping \ (tkIntXlibStubsPtr->xRefreshKeyboardMapping) /* 41 */ -#endif -#ifndef XResizeWindow #define XResizeWindow \ (tkIntXlibStubsPtr->xResizeWindow) /* 42 */ -#endif -#ifndef XSelectInput #define XSelectInput \ (tkIntXlibStubsPtr->xSelectInput) /* 43 */ -#endif -#ifndef XSendEvent #define XSendEvent \ (tkIntXlibStubsPtr->xSendEvent) /* 44 */ -#endif -#ifndef XSetIconName #define XSetIconName \ (tkIntXlibStubsPtr->xSetIconName) /* 45 */ -#endif -#ifndef XSetInputFocus #define XSetInputFocus \ (tkIntXlibStubsPtr->xSetInputFocus) /* 46 */ -#endif -#ifndef XSetSelectionOwner #define XSetSelectionOwner \ (tkIntXlibStubsPtr->xSetSelectionOwner) /* 47 */ -#endif -#ifndef XSetWindowBackground #define XSetWindowBackground \ (tkIntXlibStubsPtr->xSetWindowBackground) /* 48 */ -#endif -#ifndef XSetWindowBackgroundPixmap #define XSetWindowBackgroundPixmap \ (tkIntXlibStubsPtr->xSetWindowBackgroundPixmap) /* 49 */ -#endif -#ifndef XSetWindowBorder #define XSetWindowBorder \ (tkIntXlibStubsPtr->xSetWindowBorder) /* 50 */ -#endif -#ifndef XSetWindowBorderPixmap #define XSetWindowBorderPixmap \ (tkIntXlibStubsPtr->xSetWindowBorderPixmap) /* 51 */ -#endif -#ifndef XSetWindowBorderWidth #define XSetWindowBorderWidth \ (tkIntXlibStubsPtr->xSetWindowBorderWidth) /* 52 */ -#endif -#ifndef XSetWindowColormap #define XSetWindowColormap \ (tkIntXlibStubsPtr->xSetWindowColormap) /* 53 */ -#endif -#ifndef XUngrabKeyboard #define XUngrabKeyboard \ (tkIntXlibStubsPtr->xUngrabKeyboard) /* 54 */ -#endif -#ifndef XUngrabPointer #define XUngrabPointer \ (tkIntXlibStubsPtr->xUngrabPointer) /* 55 */ -#endif -#ifndef XUnmapWindow #define XUnmapWindow \ (tkIntXlibStubsPtr->xUnmapWindow) /* 56 */ -#endif -#ifndef TkPutImage #define TkPutImage \ (tkIntXlibStubsPtr->tkPutImage) /* 57 */ -#endif -#ifndef XParseColor #define XParseColor \ (tkIntXlibStubsPtr->xParseColor) /* 58 */ -#endif -#ifndef XCreateGC #define XCreateGC \ (tkIntXlibStubsPtr->xCreateGC) /* 59 */ -#endif -#ifndef XFreeGC #define XFreeGC \ (tkIntXlibStubsPtr->xFreeGC) /* 60 */ -#endif -#ifndef XInternAtom #define XInternAtom \ (tkIntXlibStubsPtr->xInternAtom) /* 61 */ -#endif -#ifndef XSetBackground #define XSetBackground \ (tkIntXlibStubsPtr->xSetBackground) /* 62 */ -#endif -#ifndef XSetForeground #define XSetForeground \ (tkIntXlibStubsPtr->xSetForeground) /* 63 */ -#endif -#ifndef XSetClipMask #define XSetClipMask \ (tkIntXlibStubsPtr->xSetClipMask) /* 64 */ -#endif -#ifndef XSetClipOrigin #define XSetClipOrigin \ (tkIntXlibStubsPtr->xSetClipOrigin) /* 65 */ -#endif -#ifndef XSetTSOrigin #define XSetTSOrigin \ (tkIntXlibStubsPtr->xSetTSOrigin) /* 66 */ -#endif -#ifndef XChangeGC #define XChangeGC \ (tkIntXlibStubsPtr->xChangeGC) /* 67 */ -#endif -#ifndef XSetFont #define XSetFont \ (tkIntXlibStubsPtr->xSetFont) /* 68 */ -#endif -#ifndef XSetArcMode #define XSetArcMode \ (tkIntXlibStubsPtr->xSetArcMode) /* 69 */ -#endif -#ifndef XSetStipple #define XSetStipple \ (tkIntXlibStubsPtr->xSetStipple) /* 70 */ -#endif -#ifndef XSetFillRule #define XSetFillRule \ (tkIntXlibStubsPtr->xSetFillRule) /* 71 */ -#endif -#ifndef XSetFillStyle #define XSetFillStyle \ (tkIntXlibStubsPtr->xSetFillStyle) /* 72 */ -#endif -#ifndef XSetFunction #define XSetFunction \ (tkIntXlibStubsPtr->xSetFunction) /* 73 */ -#endif -#ifndef XSetLineAttributes #define XSetLineAttributes \ (tkIntXlibStubsPtr->xSetLineAttributes) /* 74 */ -#endif -#ifndef _XInitImageFuncPtrs #define _XInitImageFuncPtrs \ (tkIntXlibStubsPtr->_XInitImageFuncPtrs) /* 75 */ -#endif -#ifndef XCreateIC #define XCreateIC \ (tkIntXlibStubsPtr->xCreateIC) /* 76 */ -#endif -#ifndef XGetVisualInfo #define XGetVisualInfo \ (tkIntXlibStubsPtr->xGetVisualInfo) /* 77 */ -#endif -#ifndef XSetWMClientMachine #define XSetWMClientMachine \ (tkIntXlibStubsPtr->xSetWMClientMachine) /* 78 */ -#endif -#ifndef XStringListToTextProperty #define XStringListToTextProperty \ (tkIntXlibStubsPtr->xStringListToTextProperty) /* 79 */ -#endif -#ifndef XDrawSegments #define XDrawSegments \ (tkIntXlibStubsPtr->xDrawSegments) /* 80 */ -#endif -#ifndef XForceScreenSaver #define XForceScreenSaver \ (tkIntXlibStubsPtr->xForceScreenSaver) /* 81 */ -#endif -#ifndef XDrawLine #define XDrawLine \ (tkIntXlibStubsPtr->xDrawLine) /* 82 */ -#endif -#ifndef XFillRectangle #define XFillRectangle \ (tkIntXlibStubsPtr->xFillRectangle) /* 83 */ -#endif -#ifndef XClearWindow #define XClearWindow \ (tkIntXlibStubsPtr->xClearWindow) /* 84 */ -#endif -#ifndef XDrawPoint #define XDrawPoint \ (tkIntXlibStubsPtr->xDrawPoint) /* 85 */ -#endif -#ifndef XDrawPoints #define XDrawPoints \ (tkIntXlibStubsPtr->xDrawPoints) /* 86 */ -#endif -#ifndef XWarpPointer #define XWarpPointer \ (tkIntXlibStubsPtr->xWarpPointer) /* 87 */ -#endif -#ifndef XQueryColor #define XQueryColor \ (tkIntXlibStubsPtr->xQueryColor) /* 88 */ -#endif -#ifndef XQueryColors #define XQueryColors \ (tkIntXlibStubsPtr->xQueryColors) /* 89 */ -#endif -#ifndef XQueryTree #define XQueryTree \ (tkIntXlibStubsPtr->xQueryTree) /* 90 */ -#endif -#ifndef XSync #define XSync \ (tkIntXlibStubsPtr->xSync) /* 91 */ -#endif #endif /* AQUA */ -#endif /* defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS) */ +#endif /* defined(USE_TK_STUBS) */ /* !END!: Do not edit above this line. */ #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT -#if defined(__WIN32__) - -#undef XFlush -#undef XGrabServer -#undef XUngrabServer -#undef XFree -#undef XNoOp -#undef XSynchronize -#undef XSync -#undef XVisualIDFromVisual - -#if defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS) -/* - * The following stubs implement various calls that don't do anything - * under Windows. In win32 tclsh 8.4 and 8.5 holds: - * tkIntStubsPtr->tkBindDeadWindow != NULL - * Then the following macros don't do anything. But when running Tcl win32 - * version 8.6 or Cygwin (8.4, 8.5 or 8.6) then the functions are available in - * the stub table. The real function from the stub table will be called, - * even though it might be doing nothing. - */ - -#define XFlush(display) (tkIntStubsPtr->tkBindDeadWindow? 0: tkIntXlibStubsPtr->xFlush(display)) -#define XGrabServer(display) (tkIntStubsPtr->tkBindDeadWindow? 0: tkIntXlibStubsPtr->xGrabServer(display)) -#define XUngrabServer(display) (tkIntStubsPtr->tkBindDeadWindow? 0: tkIntXlibStubsPtr->xUngrabServer(display)) - -/* - * The following functions are implemented as macros under Windows. - */ - - -#define XFree(data) (tkIntStubsPtr->tkBindDeadWindow? ((data)? (ckfree((char *) (data)), 0): 0): tkIntXlibStubsPtr->xFree(data)) -#define XNoOp(display) (tkIntStubsPtr->tkBindDeadWindow? 0: tkIntXlibStubsPtr->xNoOp(display)) -#define XSynchronize(display, bool) (tkIntStubsPtr->tkBindDeadWindow? 0: tkIntXlibStubsPtr->xSynchronize(display, bool)) -#define XSync(display, bool) (tkIntStubsPtr->tkBindDeadWindow? 0: tkIntXlibStubsPtr->xSync(display, bool)) -#define XVisualIDFromVisual(visual) (tkIntStubsPtr->tkBindDeadWindow? ((visual)->visualid): tkIntXlibStubsPtr->xVisualIDFromVisual(visual)) - -#else /* !USE_TK_STUBS */ -/* - * The following stubs implement various calls that don't do anything - * under Windows. - */ - -#define XFlush(display) -#define XGrabServer(display) -#define XUngrabServer(display) - -/* - * The following functions are implemented as macros under Windows. - */ - -#define XFree(data) {if ((data) != NULL) ckfree((char *) (data));} -#define XNoOp(display) {display->request++;} -#define XSynchronize(display, bool) {display->request++;} -#define XSync(display, bool) {display->request++;} -#define XVisualIDFromVisual(visual) (visual->visualid) - -#endif /* !USE_TK_STUBS */ - -#endif /* __WIN32__ */ - #endif /* _TKINTXLIBDECLS */ diff --git a/generic/tkListbox.c b/generic/tkListbox.c index dfd0dd3..d92325f 100644 --- a/generic/tkListbox.c +++ b/generic/tkListbox.c @@ -15,7 +15,7 @@ #include "default.h" #include "tkInt.h" -#ifdef WIN32 +#ifdef _WIN32 #include "tkWinInt.h" #endif @@ -24,7 +24,7 @@ typedef struct { /* Table defining configuration options * available for the listbox. */ Tk_OptionTable itemAttrOptionTable; - /* Table definining configuration options + /* Table defining configuration options * available for listbox items. */ } ListboxOptionTables; @@ -90,14 +90,14 @@ typedef struct { * display. */ int topIndex; /* Index of top-most element visible in * window. */ - int fullLines; /* Number of lines that fit are completely + int fullLines; /* Number of lines that are completely * visible in window. There may be one * additional line at the bottom that is * partially visible. */ int partialLine; /* 0 means that the window holds exactly * fullLines lines. 1 means that there is one * additional line that is partially - * visble. */ + * visible. */ int setGrid; /* Non-zero means pass gridding information to * window manager. */ @@ -114,7 +114,8 @@ typedef struct { int xOffset; /* The left edge of each string in the listbox * is offset to the left by this many pixels * (0 means no offset, positive means there is - * an offset). */ + * an offset). This is x scrolling information + * is not linked to justification. */ /* * Information about what's selected or active, if any. @@ -131,7 +132,7 @@ typedef struct { int active; /* Index of "active" element (the one that has * been selected by keyboard traversal). -1 * means none. */ - int activeStyle; /* style in which to draw the active element. + int activeStyle; /* Style in which to draw the active element. * One of: underline, none, dotbox */ /* @@ -165,9 +166,17 @@ typedef struct { Pixmap gray; /* Pixmap for displaying disabled text. */ int flags; /* Various flag bits: see below for * definitions. */ + Tk_Justify justify; /* Justification. */ } Listbox; /* + * How to encode the keys for the hash tables used to store what items are + * selected and what the attributes are. + */ + +#define KEY(i) ((char *) INT2PTR(i)) + +/* * ItemAttr structures are used to store item configuration information for * the items in a listbox */ @@ -190,7 +199,7 @@ typedef struct { * be updated. * GOT_FOCUS: Non-zero means this widget currently has the * input focus. - * MAXWIDTH_IS_STALE: Stored maxWidth may be out-of-date + * MAXWIDTH_IS_STALE: Stored maxWidth may be out-of-date. * LISTBOX_DELETED: This listbox has been effectively destroyed. */ @@ -231,14 +240,14 @@ static const char *const activeStyleStrings[] = { static const Tk_OptionSpec optionSpecs[] = { {TK_OPTION_STRING_TABLE, "-activestyle", "activeStyle", "ActiveStyle", DEF_LISTBOX_ACTIVE_STYLE, -1, Tk_Offset(Listbox, activeStyle), - 0, (ClientData) activeStyleStrings, 0}, + 0, activeStyleStrings, 0}, {TK_OPTION_BORDER, "-background", "background", "Background", DEF_LISTBOX_BG_COLOR, -1, Tk_Offset(Listbox, normalBorder), - 0, (ClientData) DEF_LISTBOX_BG_MONO, 0}, + 0, DEF_LISTBOX_BG_MONO, 0}, {TK_OPTION_SYNONYM, "-bd", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-borderwidth", 0}, + NULL, 0, -1, 0, "-borderwidth", 0}, {TK_OPTION_SYNONYM, "-bg", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-background", 0}, + NULL, 0, -1, 0, "-background", 0}, {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", DEF_LISTBOX_BORDER_WIDTH, -1, Tk_Offset(Listbox, borderWidth), 0, 0, 0}, @@ -252,7 +261,7 @@ static const Tk_OptionSpec optionSpecs[] = { "ExportSelection", DEF_LISTBOX_EXPORT_SELECTION, -1, Tk_Offset(Listbox, exportSelection), 0, 0, 0}, {TK_OPTION_SYNONYM, "-fg", "foreground", NULL, - NULL, 0, -1, 0, (ClientData) "-foreground", 0}, + NULL, 0, -1, 0, "-foreground", 0}, {TK_OPTION_FONT, "-font", "font", "Font", DEF_LISTBOX_FONT, -1, Tk_Offset(Listbox, tkfont), 0, 0, 0}, {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground", @@ -268,17 +277,19 @@ static const Tk_OptionSpec optionSpecs[] = { {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness", "HighlightThickness", DEF_LISTBOX_HIGHLIGHT_WIDTH, -1, Tk_Offset(Listbox, highlightWidth), 0, 0, 0}, + {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify", + DEF_LISTBOX_JUSTIFY, -1, Tk_Offset(Listbox, justify), 0, 0, 0}, {TK_OPTION_RELIEF, "-relief", "relief", "Relief", DEF_LISTBOX_RELIEF, -1, Tk_Offset(Listbox, relief), 0, 0, 0}, {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground", DEF_LISTBOX_SELECT_COLOR, -1, Tk_Offset(Listbox, selBorder), - 0, (ClientData) DEF_LISTBOX_SELECT_MONO, 0}, + 0, DEF_LISTBOX_SELECT_MONO, 0}, {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth", "BorderWidth", DEF_LISTBOX_SELECT_BD, -1, Tk_Offset(Listbox, selBorderWidth), 0, 0, 0}, {TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background", DEF_LISTBOX_SELECT_FG_COLOR, -1, Tk_Offset(Listbox, selFgColorPtr), - TK_OPTION_NULL_OK, (ClientData) DEF_LISTBOX_SELECT_FG_MONO, 0}, + TK_OPTION_NULL_OK, DEF_LISTBOX_SELECT_FG_MONO, 0}, {TK_OPTION_STRING, "-selectmode", "selectMode", "SelectMode", DEF_LISTBOX_SELECT_MODE, -1, Tk_Offset(Listbox, selectMode), TK_OPTION_NULL_OK, 0, 0}, @@ -286,7 +297,7 @@ static const Tk_OptionSpec optionSpecs[] = { DEF_LISTBOX_SET_GRID, -1, Tk_Offset(Listbox, setGrid), 0, 0, 0}, {TK_OPTION_STRING_TABLE, "-state", "state", "State", DEF_LISTBOX_STATE, -1, Tk_Offset(Listbox, state), - 0, (ClientData) stateStrings, 0}, + 0, stateStrings, 0}, {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", DEF_LISTBOX_TAKE_FOCUS, -1, Tk_Offset(Listbox, takeFocus), TK_OPTION_NULL_OK, 0, 0}, @@ -306,39 +317,39 @@ static const Tk_OptionSpec optionSpecs[] = { /* * The itemAttrOptionSpecs table defines the valid configuration options for - * listbox items + * listbox items. */ static const Tk_OptionSpec itemAttrOptionSpecs[] = { {TK_OPTION_BORDER, "-background", "background", "Background", NULL, -1, Tk_Offset(ItemAttr, border), TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT, - (ClientData) DEF_LISTBOX_BG_MONO, 0}, + DEF_LISTBOX_BG_MONO, 0}, {TK_OPTION_SYNONYM, "-bg", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-background", 0}, + NULL, 0, -1, 0, "-background", 0}, {TK_OPTION_SYNONYM, "-fg", "foreground", NULL, - NULL, 0, -1, 0, (ClientData) "-foreground", 0}, + NULL, 0, -1, 0, "-foreground", 0}, {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground", NULL, -1, Tk_Offset(ItemAttr, fgColor), TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT, 0, 0}, {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground", NULL, -1, Tk_Offset(ItemAttr, selBorder), TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT, - (ClientData) DEF_LISTBOX_SELECT_MONO, 0}, + DEF_LISTBOX_SELECT_MONO, 0}, {TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background", NULL, -1, Tk_Offset(ItemAttr, selFgColor), TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT, - (ClientData) DEF_LISTBOX_SELECT_FG_MONO, 0}, + DEF_LISTBOX_SELECT_FG_MONO, 0}, {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0} }; /* - * The following tables define the listbox widget commands (and sub- commands) + * The following tables define the listbox widget commands (and sub-commands) * and map the indexes into the string tables into enumerated types used to * dispatch the listbox widget command. */ -static const char *commandNames[] = { +static const char *const commandNames[] = { "activate", "bbox", "cget", "configure", "curselection", "delete", "get", "index", "insert", "itemcget", "itemconfigure", "nearest", "scan", "see", "selection", "size", "xview", "yview", NULL @@ -351,21 +362,21 @@ enum command { COMMAND_SIZE, COMMAND_XVIEW, COMMAND_YVIEW }; -static const char *selCommandNames[] = { +static const char *const selCommandNames[] = { "anchor", "clear", "includes", "set", NULL }; enum selcommand { SELECTION_ANCHOR, SELECTION_CLEAR, SELECTION_INCLUDES, SELECTION_SET }; -static const char *scanCommandNames[] = { +static const char *const scanCommandNames[] = { "mark", "dragto", NULL }; enum scancommand { SCAN_MARK, SCAN_DRAGTO }; -static const char *indexNames[] = { +static const char *const indexNames[] = { "active", "anchor", "end", NULL }; enum indices { @@ -385,7 +396,7 @@ static int ConfigureListboxItem(Tcl_Interp *interp, Tcl_Obj *const objv[], int index); static int ListboxDeleteSubCmd(Listbox *listPtr, int first, int last); -static void DestroyListbox(char *memPtr); +static void DestroyListbox(void *memPtr); static void DestroyListboxOptionTables(ClientData clientData, Tcl_Interp *interp); static void DisplayListbox(ClientData clientData); @@ -429,17 +440,18 @@ static char * ListboxListVarProc(ClientData clientData, const char *name2, int flags); static void MigrateHashEntries(Tcl_HashTable *table, int first, int last, int offset); +static int GetMaxOffset(Listbox *listPtr); /* * The structure below defines button class behavior by means of procedures * that can be invoked from generic window code. */ -static Tk_ClassProcs listboxClass = { +static const Tk_ClassProcs listboxClass = { sizeof(Tk_ClassProcs), /* size */ ListboxWorldChanged, /* worldChangedProc */ - NULL, /* createProc */ - NULL /* modalProc */ + NULL, /* createProc */ + NULL /* modalProc */ }; /* @@ -471,7 +483,7 @@ Tk_ListboxObjCmd( ListboxOptionTables *optionTables; if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?"); + Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?"); return TCL_ERROR; } @@ -481,8 +493,7 @@ Tk_ListboxObjCmd( return TCL_ERROR; } - optionTables = (ListboxOptionTables *) - Tcl_GetAssocData(interp, "ListboxOptionTables", NULL); + optionTables = Tcl_GetAssocData(interp, "ListboxOptionTables", NULL); if (optionTables == NULL) { /* * We haven't created the option tables for this widget class yet. Do @@ -490,15 +501,14 @@ Tk_ListboxObjCmd( * command, so future invocations will have access to it. */ - optionTables = (ListboxOptionTables *) - ckalloc(sizeof(ListboxOptionTables)); + optionTables = ckalloc(sizeof(ListboxOptionTables)); /* * Set up an exit handler to free the optionTables struct. */ Tcl_SetAssocData(interp, "ListboxOptionTables", - DestroyListboxOptionTables, (ClientData) optionTables); + DestroyListboxOptionTables, optionTables); /* * Create the listbox option table and the listbox item option table. @@ -516,22 +526,20 @@ Tk_ListboxObjCmd( * already (e.g. resource pointers). */ - listPtr = (Listbox *) ckalloc(sizeof(Listbox)); - memset(listPtr, 0, (sizeof(Listbox))); + listPtr = ckalloc(sizeof(Listbox)); + memset(listPtr, 0, sizeof(Listbox)); listPtr->tkwin = tkwin; listPtr->display = Tk_Display(tkwin); listPtr->interp = interp; listPtr->widgetCmd = Tcl_CreateObjCommand(interp, - Tk_PathName(listPtr->tkwin), ListboxWidgetObjCmd, - (ClientData) listPtr, ListboxCmdDeletedProc); + Tk_PathName(listPtr->tkwin), ListboxWidgetObjCmd, listPtr, + ListboxCmdDeletedProc); listPtr->optionTable = optionTables->listboxOptionTable; listPtr->itemAttrOptionTable = optionTables->itemAttrOptionTable; - listPtr->selection = (Tcl_HashTable *) - ckalloc(sizeof(Tcl_HashTable)); + listPtr->selection = ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(listPtr->selection, TCL_ONE_WORD_KEYS); - listPtr->itemAttrTable = (Tcl_HashTable *) - ckalloc(sizeof(Tcl_HashTable)); + listPtr->itemAttrTable = ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(listPtr->itemAttrTable, TCL_ONE_WORD_KEYS); listPtr->relief = TK_RELIEF_RAISED; listPtr->textGC = NULL; @@ -543,21 +551,22 @@ Tk_ListboxObjCmd( listPtr->cursor = NULL; listPtr->state = STATE_NORMAL; listPtr->gray = None; + listPtr->justify = TK_JUSTIFY_LEFT; /* * Keep a hold of the associated tkwin until we destroy the listbox, * otherwise Tk might free it while we still need it. */ - Tcl_Preserve((ClientData) listPtr->tkwin); + Tcl_Preserve(listPtr->tkwin); Tk_SetClass(listPtr->tkwin, "Listbox"); - Tk_SetClassProcs(listPtr->tkwin, &listboxClass, (ClientData) listPtr); + Tk_SetClassProcs(listPtr->tkwin, &listboxClass, listPtr); Tk_CreateEventHandler(listPtr->tkwin, ExposureMask|StructureNotifyMask|FocusChangeMask, - ListboxEventProc, (ClientData) listPtr); + ListboxEventProc, listPtr); Tk_CreateSelHandler(listPtr->tkwin, XA_PRIMARY, XA_STRING, - ListboxFetchSelection, (ClientData) listPtr, XA_STRING); + ListboxFetchSelection, listPtr, XA_STRING); if (Tk_InitOptions(interp, (char *)listPtr, optionTables->listboxOptionTable, tkwin) != TCL_OK) { Tk_DestroyWindow(listPtr->tkwin); @@ -569,7 +578,7 @@ Tk_ListboxObjCmd( return TCL_ERROR; } - Tcl_SetResult(interp, Tk_PathName(listPtr->tkwin), TCL_STATIC); + Tcl_SetObjResult(interp, TkNewWindowObj(listPtr->tkwin)); return TCL_OK; } @@ -598,18 +607,19 @@ ListboxWidgetObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Arguments as Tcl_Obj's. */ { - register Listbox *listPtr = (Listbox *) clientData; + register Listbox *listPtr = clientData; int cmdIndex, index; int result = TCL_OK; + Tcl_Obj *objPtr; if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?"); + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); return TCL_ERROR; } /* * Parse the command by looking up the second argument in the list of - * valid subcommand names + * valid subcommand names. */ result = Tcl_GetIndexFromObj(interp, objv[1], commandNames, @@ -618,7 +628,7 @@ ListboxWidgetObjCmd( return result; } - Tcl_Preserve((ClientData)listPtr); + Tcl_Preserve(listPtr); /* * The subcommand was valid, so continue processing. @@ -665,9 +675,7 @@ ListboxWidgetObjCmd( result = ListboxBboxSubCmd(interp, listPtr, index); break; - case COMMAND_CGET: { - Tcl_Obj *objPtr; - + case COMMAND_CGET: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "option"); result = TCL_ERROR; @@ -683,11 +691,8 @@ ListboxWidgetObjCmd( Tcl_SetObjResult(interp, objPtr); result = TCL_OK; break; - } - - case COMMAND_CONFIGURE: { - Tcl_Obj *objPtr; + case COMMAND_CONFIGURE: if (objc <= 3) { objPtr = Tk_GetOptionInfo(interp, (char *) listPtr, listPtr->optionTable, @@ -695,18 +700,15 @@ ListboxWidgetObjCmd( if (objPtr == NULL) { result = TCL_ERROR; break; - } else { - Tcl_SetObjResult(interp, objPtr); - result = TCL_OK; } + Tcl_SetObjResult(interp, objPtr); + result = TCL_OK; } else { result = ConfigureListbox(interp, listPtr, objc-2, objv+2); } break; - } case COMMAND_CURSELECTION: { - char indexStringRep[TCL_INTEGER_SPACE]; int i; if (objc != 2) { @@ -723,12 +725,13 @@ ListboxWidgetObjCmd( * selected. */ + objPtr = Tcl_NewObj(); for (i = 0; i < listPtr->nElements; i++) { - if (Tcl_FindHashEntry(listPtr->selection, (char *) INT2PTR(i))) { - sprintf(indexStringRep, "%d", i); - Tcl_AppendElement(interp, indexStringRep); + if (Tcl_FindHashEntry(listPtr->selection, KEY(i))) { + Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewIntObj(i)); } } + Tcl_SetObjResult(interp, objPtr); result = TCL_OK; break; } @@ -821,8 +824,8 @@ ListboxWidgetObjCmd( Tcl_SetObjResult(interp, elemPtrs[first]); } else { - Tcl_SetListObj(Tcl_GetObjResult(interp), (last - first + 1), - &(elemPtrs[first])); + Tcl_SetObjResult(interp, + Tcl_NewListObj(last-first+1, elemPtrs+first)); } result = TCL_OK; break; @@ -844,7 +847,7 @@ ListboxWidgetObjCmd( case COMMAND_INSERT: if (objc < 3) { - Tcl_WrongNumArgs(interp, 2, objv, "index ?element element ...?"); + Tcl_WrongNumArgs(interp, 2, objv, "index ?element ...?"); result = TCL_ERROR; break; } @@ -862,7 +865,6 @@ ListboxWidgetObjCmd( break; case COMMAND_ITEMCGET: { - Tcl_Obj *objPtr; ItemAttr *attrPtr; if (objc != 4) { @@ -877,8 +879,10 @@ ListboxWidgetObjCmd( } if (index < 0 || index >= listPtr->nElements) { - Tcl_AppendResult(interp, "item number \"", - Tcl_GetString(objv[2]), "\" out of range", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "item number \"%s\" out of range", + Tcl_GetString(objv[2]))); + Tcl_SetErrorCode(interp, "TK", "LISTBOX", "ITEM_INDEX", NULL); result = TCL_ERROR; break; } @@ -897,12 +901,11 @@ ListboxWidgetObjCmd( } case COMMAND_ITEMCONFIGURE: { - Tcl_Obj *objPtr; ItemAttr *attrPtr; if (objc < 3) { Tcl_WrongNumArgs(interp, 2, objv, - "index ?option? ?value? ?option value ...?"); + "index ?-option? ?value? ?-option value ...?"); result = TCL_ERROR; break; } @@ -913,8 +916,10 @@ ListboxWidgetObjCmd( } if (index < 0 || index >= listPtr->nElements) { - Tcl_AppendResult(interp, "item number \"", Tcl_GetString(objv[2]), - "\" out of range", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "item number \"%s\" out of range", + Tcl_GetString(objv[2]))); + Tcl_SetErrorCode(interp, "TK", "LISTBOX", "ITEM_INDEX", NULL); result = TCL_ERROR; break; } @@ -927,10 +932,9 @@ ListboxWidgetObjCmd( if (objPtr == NULL) { result = TCL_ERROR; break; - } else { - Tcl_SetObjResult(interp, objPtr); - result = TCL_OK; } + Tcl_SetObjResult(interp, objPtr); + result = TCL_OK; } else { result = ConfigureListboxItem(interp, listPtr, attrPtr, objc-3, objv+3, index); @@ -1012,7 +1016,7 @@ ListboxWidgetObjCmd( } diff = listPtr->topIndex - index; if (diff > 0) { - if (diff <= (listPtr->fullLines/3)) { + if (diff <= listPtr->fullLines / 3) { ChangeListboxView(listPtr, index); } else { ChangeListboxView(listPtr, index - (listPtr->fullLines-1)/2); @@ -1020,7 +1024,7 @@ ListboxWidgetObjCmd( } else { diff = index - (listPtr->topIndex + listPtr->fullLines - 1); if (diff > 0) { - if (diff <= (listPtr->fullLines/3)) { + if (diff <= listPtr->fullLines / 3) { ChangeListboxView(listPtr, listPtr->topIndex + diff); } else { ChangeListboxView(listPtr, index-(listPtr->fullLines-1)/2); @@ -1050,7 +1054,7 @@ ListboxWidgetObjCmd( result = ListboxYviewSubCmd(interp, listPtr, objc, objv); break; } - Tcl_Release((ClientData)listPtr); + Tcl_Release(listPtr); return result; } @@ -1078,6 +1082,7 @@ ListboxBboxSubCmd( Listbox *listPtr, /* Information about the listbox */ int index) /* Index of the element to get bbox info on */ { + register Tk_Window tkwin = listPtr->tkwin; int lastVisibleIndex; /* @@ -1095,9 +1100,8 @@ ListboxBboxSubCmd( */ if ((listPtr->topIndex <= index) && (index < lastVisibleIndex)) { - char buf[TCL_INTEGER_SPACE * 4]; - Tcl_Obj *el; - char *stringRep; + Tcl_Obj *el, *results[4]; + const char *stringRep; int pixelWidth, stringLen, x, y, result; Tk_FontMetrics fm; @@ -1114,11 +1118,22 @@ ListboxBboxSubCmd( Tk_GetFontMetrics(listPtr->tkfont, &fm); pixelWidth = Tk_TextWidth(listPtr->tkfont, stringRep, stringLen); - x = listPtr->inset + listPtr->selBorderWidth - listPtr->xOffset; + if (listPtr->justify == TK_JUSTIFY_LEFT) { + x = (listPtr->inset + listPtr->selBorderWidth) - listPtr->xOffset; + } else if (listPtr->justify == TK_JUSTIFY_RIGHT) { + x = Tk_Width(tkwin) - (listPtr->inset + listPtr->selBorderWidth) + - pixelWidth - listPtr->xOffset + GetMaxOffset(listPtr); + } else { + x = (Tk_Width(tkwin) - pixelWidth)/2 + - listPtr->xOffset + GetMaxOffset(listPtr)/2; + } y = ((index - listPtr->topIndex)*listPtr->lineHeight) + listPtr->inset + listPtr->selBorderWidth; - sprintf(buf, "%d %d %d %d", x, y, pixelWidth, fm.linespace); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + results[0] = Tcl_NewIntObj(x); + results[1] = Tcl_NewIntObj(y); + results[2] = Tcl_NewIntObj(pixelWidth); + results[3] = Tcl_NewIntObj(fm.linespace); + Tcl_SetObjResult(interp, Tcl_NewListObj(4, results)); } return TCL_OK; } @@ -1203,9 +1218,8 @@ ListboxSelectionSubCmd( Tcl_WrongNumArgs(interp, 3, objv, "index"); return TCL_ERROR; } - Tcl_SetObjResult(interp, - Tcl_NewBooleanObj((Tcl_FindHashEntry(listPtr->selection, - (char *) INT2PTR(first)) != NULL))); + Tcl_SetObjResult(interp, Tcl_NewBooleanObj( + Tcl_FindHashEntry(listPtr->selection, KEY(first)) != NULL)); result = TCL_OK; break; case SELECTION_SET: @@ -1238,45 +1252,45 @@ ListboxXviewSubCmd( int objc, /* Number of arguments in the objv array */ Tcl_Obj *const objv[]) /* Array of arguments to the procedure */ { - - int index, count, type, windowWidth, windowUnits; + int index, count, windowWidth, windowUnits; int offset = 0; /* Initialized to stop gcc warnings. */ - double fraction, fraction2; + double fraction; windowWidth = Tk_Width(listPtr->tkwin) - 2*(listPtr->inset + listPtr->selBorderWidth); if (objc == 2) { + Tcl_Obj *results[2]; + if (listPtr->maxWidth == 0) { - Tcl_SetResult(interp, "0.0 1.0", TCL_STATIC); + results[0] = Tcl_NewDoubleObj(0.0); + results[1] = Tcl_NewDoubleObj(1.0); } else { - char buf[TCL_DOUBLE_SPACE]; + double fraction2; - fraction = listPtr->xOffset/((double) listPtr->maxWidth); + fraction = listPtr->xOffset / (double) listPtr->maxWidth; fraction2 = (listPtr->xOffset + windowWidth) - / ((double) listPtr->maxWidth); + / (double) listPtr->maxWidth; if (fraction2 > 1.0) { fraction2 = 1.0; } - Tcl_PrintDouble(NULL, fraction, buf); - Tcl_SetResult(interp, buf, TCL_VOLATILE); - Tcl_PrintDouble(NULL, fraction2, buf); - Tcl_AppendResult(interp, " ", buf, NULL); + results[0] = Tcl_NewDoubleObj(fraction); + results[1] = Tcl_NewDoubleObj(fraction2); } + Tcl_SetObjResult(interp, Tcl_NewListObj(2, results)); } else if (objc == 3) { if (Tcl_GetIntFromObj(interp, objv[2], &index) != TCL_OK) { return TCL_ERROR; } ChangeListboxOffset(listPtr, index*listPtr->xScrollUnit); } else { - type = Tk_GetScrollInfoObj(interp, objc, objv, &fraction, &count); - switch (type) { + switch (Tk_GetScrollInfoObj(interp, objc, objv, &fraction, &count)) { case TK_SCROLL_ERROR: return TCL_ERROR; case TK_SCROLL_MOVETO: offset = (int) (fraction*listPtr->maxWidth + 0.5); break; case TK_SCROLL_PAGES: - windowUnits = windowWidth/listPtr->xScrollUnit; + windowUnits = windowWidth / listPtr->xScrollUnit; if (windowUnits > 2) { offset = listPtr->xOffset + count*listPtr->xScrollUnit*(windowUnits-2); @@ -1316,34 +1330,34 @@ ListboxYviewSubCmd( int objc, /* Number of arguments in the objv array */ Tcl_Obj *const objv[]) /* Array of arguments to the procedure */ { - int index, count, type; - double fraction, fraction2; + int index, count; + double fraction; if (objc == 2) { + Tcl_Obj *results[2]; + if (listPtr->nElements == 0) { - Tcl_SetResult(interp, "0.0 1.0", TCL_STATIC); + results[0] = Tcl_NewDoubleObj(0.0); + results[1] = Tcl_NewDoubleObj(1.0); } else { - char buf[TCL_DOUBLE_SPACE]; + double fraction2, numEls = (double) listPtr->nElements; - fraction = listPtr->topIndex/((double) listPtr->nElements); - fraction2 = (listPtr->topIndex+listPtr->fullLines) - /((double) listPtr->nElements); + fraction = listPtr->topIndex / numEls; + fraction2 = (listPtr->topIndex+listPtr->fullLines) / numEls; if (fraction2 > 1.0) { fraction2 = 1.0; } - Tcl_PrintDouble(NULL, fraction, buf); - Tcl_SetResult(interp, buf, TCL_VOLATILE); - Tcl_PrintDouble(NULL, fraction2, buf); - Tcl_AppendResult(interp, " ", buf, NULL); + results[0] = Tcl_NewDoubleObj(fraction); + results[1] = Tcl_NewDoubleObj(fraction2); } + Tcl_SetObjResult(interp, Tcl_NewListObj(2, results)); } else if (objc == 3) { if (GetListboxIndex(interp, listPtr, objv[2], 0, &index) != TCL_OK) { return TCL_ERROR; } ChangeListboxView(listPtr, index); } else { - type = Tk_GetScrollInfoObj(interp, objc, objv, &fraction, &count); - switch (type) { + switch (Tk_GetScrollInfoObj(interp, objc, objv, &fraction, &count)) { case TK_SCROLL_MOVETO: index = (int) (listPtr->nElements*fraction + 0.5); break; @@ -1394,19 +1408,19 @@ ListboxGetItemAttributes( Tcl_HashEntry *entry; ItemAttr *attrs; - entry = Tcl_CreateHashEntry(listPtr->itemAttrTable, - (char *) INT2PTR(index), &isNew); + entry = Tcl_CreateHashEntry(listPtr->itemAttrTable, KEY(index), &isNew); if (isNew) { - attrs = (ItemAttr *) ckalloc(sizeof(ItemAttr)); + attrs = ckalloc(sizeof(ItemAttr)); attrs->border = NULL; attrs->selBorder = NULL; attrs->fgColor = NULL; attrs->selFgColor = NULL; Tk_InitOptions(interp, (char *)attrs, listPtr->itemAttrOptionTable, listPtr->tkwin); - Tcl_SetHashValue(entry, (ClientData) attrs); + Tcl_SetHashValue(entry, attrs); + } else { + attrs = Tcl_GetHashValue(entry); } - attrs = (ItemAttr *)Tcl_GetHashValue(entry); return attrs; } @@ -1430,9 +1444,9 @@ ListboxGetItemAttributes( static void DestroyListbox( - char *memPtr) /* Info about listbox widget. */ + void *memPtr) /* Info about listbox widget. */ { - register Listbox *listPtr = (Listbox *) memPtr; + register Listbox *listPtr = memPtr; Tcl_HashEntry *entry; Tcl_HashSearch search; @@ -1446,9 +1460,9 @@ DestroyListbox( } if (listPtr->listVarName != NULL) { - Tcl_UntraceVar(listPtr->interp, listPtr->listVarName, + Tcl_UntraceVar2(listPtr->interp, listPtr->listVarName, NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - ListboxListVarProc, (ClientData) listPtr); + ListboxListVarProc, listPtr); } /* @@ -1456,7 +1470,7 @@ DestroyListbox( */ Tcl_DeleteHashTable(listPtr->selection); - ckfree((char *)listPtr->selection); + ckfree(listPtr->selection); /* * Free the item attribute hash table. @@ -1464,10 +1478,10 @@ DestroyListbox( for (entry = Tcl_FirstHashEntry(listPtr->itemAttrTable, &search); entry != NULL; entry = Tcl_NextHashEntry(&search)) { - ckfree((char *)Tcl_GetHashValue(entry)); + ckfree(Tcl_GetHashValue(entry)); } Tcl_DeleteHashTable(listPtr->itemAttrTable); - ckfree((char *)listPtr->itemAttrTable); + ckfree(listPtr->itemAttrTable); /* * Free up all the stuff that requires special handling, then let @@ -1484,11 +1498,11 @@ DestroyListbox( Tk_FreeBitmap(Tk_Display(listPtr->tkwin), listPtr->gray); } - Tk_FreeConfigOptions((char *)listPtr, listPtr->optionTable, + Tk_FreeConfigOptions((char *) listPtr, listPtr->optionTable, listPtr->tkwin); - Tcl_Release((ClientData) listPtr->tkwin); + Tcl_Release(listPtr->tkwin); listPtr->tkwin = NULL; - ckfree((char *) listPtr); + ckfree(listPtr); } /* @@ -1514,7 +1528,7 @@ DestroyListboxOptionTables( ClientData clientData, /* Pointer to the OptionTables struct */ Tcl_Interp *interp) /* Pointer to the calling interp */ { - ckfree((char *) clientData); + ckfree(clientData); return; } @@ -1551,11 +1565,11 @@ ConfigureListbox( Tcl_Obj *errorResult = NULL; int oldExport, error; - oldExport = listPtr->exportSelection; + oldExport = (listPtr->exportSelection) && (!Tcl_IsSafe(listPtr->interp)); if (listPtr->listVarName != NULL) { - Tcl_UntraceVar(interp, listPtr->listVarName, + Tcl_UntraceVar2(interp, listPtr->listVarName, NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - ListboxListVarProc, (ClientData) listPtr); + ListboxListVarProc, listPtr); } for (error = 0; error <= 1; error++) { @@ -1593,13 +1607,14 @@ ConfigureListbox( /* * Claim the selection if we've suddenly started exporting it and - * there is a selection to export. + * there is a selection to export and this interp is unsafe. */ - if (listPtr->exportSelection && !oldExport + if (listPtr->exportSelection && (!oldExport) + && (!Tcl_IsSafe(listPtr->interp)) && (listPtr->numSelected != 0)) { - Tk_OwnSelection(listPtr->tkwin, XA_PRIMARY, ListboxLostSelection, - (ClientData) listPtr); + Tk_OwnSelection(listPtr->tkwin, XA_PRIMARY, + ListboxLostSelection, listPtr); } /* @@ -1646,9 +1661,9 @@ ConfigureListbox( } listPtr->listObj = listVarObj; - Tcl_TraceVar(listPtr->interp, listPtr->listVarName, - TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - ListboxListVarProc, (ClientData) listPtr); + Tcl_TraceVar2(listPtr->interp, listPtr->listVarName, + NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + ListboxListVarProc, listPtr); } else if (listPtr->listObj == NULL) { listPtr->listObj = Tcl_NewObj(); } @@ -1672,10 +1687,9 @@ ConfigureListbox( Tcl_SetObjResult(interp, errorResult); Tcl_DecrRefCount(errorResult); return TCL_ERROR; - } else { - ListboxWorldChanged((ClientData) listPtr); - return TCL_OK; } + ListboxWorldChanged(listPtr); + return TCL_OK; } /* @@ -1752,7 +1766,7 @@ ListboxWorldChanged( XGCValues gcValues; GC gc; unsigned long mask; - Listbox *listPtr = (Listbox *) instanceData; + Listbox *listPtr = instanceData; if (listPtr->state & STATE_NORMAL) { gcValues.foreground = listPtr->fgColorPtr->pixel; @@ -1823,14 +1837,14 @@ static void DisplayListbox( ClientData clientData) /* Information about window. */ { - register Listbox *listPtr = (Listbox *) clientData; + register Listbox *listPtr = clientData; register Tk_Window tkwin = listPtr->tkwin; GC gc; int i, limit, x, y, prevSelected, freeGC, stringLen; Tk_FontMetrics fm; Tcl_Obj *curElement; Tcl_HashEntry *entry; - char *stringRep; + const char *stringRep; ItemAttr *attrs; Tk_3DBorder selectedBg; XGCValues gcValues; @@ -1839,6 +1853,7 @@ DisplayListbox( * or right edge of the listbox is * off-screen. */ Pixmap pixmap; + int textWidth; listPtr->flags &= ~REDRAW_PENDING; if (listPtr->flags & LISTBOX_DELETED) { @@ -1851,23 +1866,23 @@ DisplayListbox( listPtr->flags |= UPDATE_H_SCROLLBAR; } - Tcl_Preserve((ClientData) listPtr); + Tcl_Preserve(listPtr); if (listPtr->flags & UPDATE_V_SCROLLBAR) { ListboxUpdateVScrollbar(listPtr); if ((listPtr->flags & LISTBOX_DELETED) || !Tk_IsMapped(tkwin)) { - Tcl_Release((ClientData) listPtr); + Tcl_Release(listPtr); return; } } if (listPtr->flags & UPDATE_H_SCROLLBAR) { ListboxUpdateHScrollbar(listPtr); if ((listPtr->flags & LISTBOX_DELETED) || !Tk_IsMapped(tkwin)) { - Tcl_Release((ClientData) listPtr); + Tcl_Release(listPtr); return; } } listPtr->flags &= ~(REDRAW_PENDING|UPDATE_V_SCROLLBAR|UPDATE_H_SCROLLBAR); - Tcl_Release((ClientData) listPtr); + Tcl_Release(listPtr); #ifndef TK_NO_DOUBLE_BUFFERING /* @@ -1917,7 +1932,7 @@ DisplayListbox( * special foreground/background colors. */ - entry = Tcl_FindHashEntry(listPtr->itemAttrTable, (char *) INT2PTR(i)); + entry = Tcl_FindHashEntry(listPtr->itemAttrTable, KEY(i)); /* * If the listbox is enabled, items may be drawn differently; they may @@ -1926,7 +1941,7 @@ DisplayListbox( */ if (listPtr->state & STATE_NORMAL) { - if (Tcl_FindHashEntry(listPtr->selection, (char *) INT2PTR(i))) { + if (Tcl_FindHashEntry(listPtr->selection, KEY(i))) { /* * Selected items are drawn differently. */ @@ -1941,7 +1956,7 @@ DisplayListbox( */ if (entry != NULL) { - attrs = (ItemAttr *)Tcl_GetHashValue(entry); + attrs = Tcl_GetHashValue(entry); /* * Default GC has the values from the widget at large. @@ -2008,8 +2023,7 @@ DisplayListbox( } /* Draw bottom bevel */ if (i + 1 == listPtr->nElements || - Tcl_FindHashEntry(listPtr->selection, - (char *) INT2PTR(i + 1)) == NULL ) { + !Tcl_FindHashEntry(listPtr->selection, KEY(i + 1))) { Tk_3DHorizontalBevel(tkwin, pixmap, selectedBg, x-left, y + listPtr->lineHeight - listPtr->selBorderWidth, width+left+right, listPtr->selBorderWidth, 0, 0, 0, @@ -2019,11 +2033,11 @@ DisplayListbox( } else { /* * If there is an item attributes record for this item, draw - * the background box and set the foreground color accordingly + * the background box and set the foreground color accordingly. */ if (entry != NULL) { - attrs = (ItemAttr *)Tcl_GetHashValue(entry); + attrs = Tcl_GetHashValue(entry); gcValues.foreground = listPtr->fgColorPtr->pixel; gcValues.font = Tk_FontId(listPtr->tkfont); gcValues.graphics_exposures = False; @@ -2059,12 +2073,24 @@ DisplayListbox( * Draw the actual text of this item. */ + Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i, &curElement); + stringRep = Tcl_GetStringFromObj(curElement, &stringLen); + textWidth = Tk_TextWidth(listPtr->tkfont, stringRep, stringLen); + Tk_GetFontMetrics(listPtr->tkfont, &fm); y += fm.ascent + listPtr->selBorderWidth; - x = listPtr->inset + listPtr->selBorderWidth - listPtr->xOffset; - Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i, &curElement); - stringRep = Tcl_GetStringFromObj(curElement, &stringLen); - Tk_DrawChars(listPtr->display, pixmap, gc, listPtr->tkfont, + + if (listPtr->justify == TK_JUSTIFY_LEFT) { + x = (listPtr->inset + listPtr->selBorderWidth) - listPtr->xOffset; + } else if (listPtr->justify == TK_JUSTIFY_RIGHT) { + x = Tk_Width(tkwin) - (listPtr->inset + listPtr->selBorderWidth) + - textWidth - listPtr->xOffset + GetMaxOffset(listPtr); + } else { + x = (Tk_Width(tkwin) - textWidth)/2 + - listPtr->xOffset + GetMaxOffset(listPtr)/2; + } + + Tk_DrawChars(listPtr->display, pixmap, gc, listPtr->tkfont, stringRep, stringLen, x, y); /* @@ -2080,7 +2106,7 @@ DisplayListbox( Tk_UnderlineChars(listPtr->display, pixmap, gc, listPtr->tkfont, stringRep, x, y, 0, stringLen); } else if (listPtr->activeStyle == ACTIVE_STYLE_DOTBOX) { -#ifdef WIN32 +#ifdef _WIN32 /* * This provides for exact default look and feel on Windows. */ @@ -2097,7 +2123,7 @@ DisplayListbox( rect.bottom = rect.top + listPtr->lineHeight; DrawFocusRect(dc, &rect); TkWinReleaseDrawableDC(pixmap, dc, &state); -#else /* !WIN32 */ +#else /* !_WIN32 */ /* * Draw a dotted box around the text. */ @@ -2136,7 +2162,7 @@ DisplayListbox( gcValues.line_style = LineSolid; XChangeGC(listPtr->display, gc, GCLineStyle, &gcValues); } -#endif /* WIN32 */ +#endif /* _WIN32 */ } } @@ -2213,7 +2239,7 @@ ListboxComputeGeometry( int width, height, pixelWidth, pixelHeight, textLength, i, result; Tk_FontMetrics fm; Tcl_Obj *element; - char *text; + const char *text; if (fontChanged || maxIsStale) { listPtr->xScrollUnit = Tk_TextWidth(listPtr->tkfont, "0", 1); @@ -2245,7 +2271,7 @@ ListboxComputeGeometry( width = listPtr->width; if (width <= 0) { width = (listPtr->maxWidth + listPtr->xScrollUnit - 1) - /listPtr->xScrollUnit; + / listPtr->xScrollUnit; if (width < 1) { width = 1; } @@ -2299,7 +2325,7 @@ ListboxInsertSubCmd( { int i, oldMaxWidth, pixelWidth, result, length; Tcl_Obj *newListObj; - char *stringRep; + const char *stringRep; oldMaxWidth = listPtr->maxWidth; for (i = 0; i < objc; i++) { @@ -2413,7 +2439,7 @@ ListboxDeleteSubCmd( { int count, i, widthChanged, length, result, pixelWidth; Tcl_Obj *newListObj, *element; - char *stringRep; + const char *stringRep; Tcl_HashEntry *entry; /* @@ -2446,22 +2472,22 @@ ListboxDeleteSubCmd( * Remove selection information. */ - entry = Tcl_FindHashEntry(listPtr->selection, (char *) INT2PTR(i)); + entry = Tcl_FindHashEntry(listPtr->selection, KEY(i)); if (entry != NULL) { listPtr->numSelected--; Tcl_DeleteHashEntry(entry); } - entry = Tcl_FindHashEntry(listPtr->itemAttrTable, (char *) INT2PTR(i)); + entry = Tcl_FindHashEntry(listPtr->itemAttrTable, KEY(i)); if (entry != NULL) { - ckfree((char *)Tcl_GetHashValue(entry)); + ckfree(Tcl_GetHashValue(entry)); Tcl_DeleteHashEntry(entry); } /* * Check width of the element. We only have to check if widthChanged * has not already been set to 1, because we only need one maxWidth - * element to disappear for us to have to recompute the width + * element to disappear for us to have to recompute the width. */ if (widthChanged == 0) { @@ -2584,7 +2610,7 @@ ListboxEventProc( ClientData clientData, /* Information about window. */ XEvent *eventPtr) /* Information about event. */ { - Listbox *listPtr = (Listbox *) clientData; + Listbox *listPtr = clientData; if (eventPtr->type == Expose) { EventuallyRedrawRange(listPtr, @@ -2601,7 +2627,7 @@ ListboxEventProc( if (listPtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayListbox, clientData); } - Tcl_EventuallyFree(clientData, DestroyListbox); + Tcl_EventuallyFree(clientData, (Tcl_FreeProc *) DestroyListbox); } } else if (eventPtr->type == ConfigureNotify) { int vertSpace; @@ -2659,7 +2685,7 @@ static void ListboxCmdDeletedProc( ClientData clientData) /* Pointer to widget record for widget. */ { - Listbox *listPtr = (Listbox *) clientData; + Listbox *listPtr = clientData; /* * This procedure could be invoked either because the window was destroyed @@ -2703,7 +2729,7 @@ GetListboxIndex( int *indexPtr) /* Where to store converted index. */ { int result, index; - char *stringRep; + const char *stringRep; /* * First see if the index is one of the named indices. @@ -2738,25 +2764,24 @@ GetListboxIndex( stringRep = Tcl_GetString(indexObj); if (stringRep[0] == '@') { - /* @x,y index */ + + /* + * @x,y index + */ + int y; - char *start, *end; + const char *start; + char *end; start = stringRep + 1; y = strtol(start, &end, 0); if ((start == end) || (*end != ',')) { - Tcl_AppendResult(interp, "bad listbox index \"", stringRep, - "\": must be active, anchor, end, @x,y, or a number", - NULL); - return TCL_ERROR; + goto badIndex; } start = end+1; y = strtol(start, &end, 0); if ((start == end) || (*end != '\0')) { - Tcl_AppendResult(interp, "bad listbox index \"", stringRep, - "\": must be active, anchor, end, @x,y, or a number", - NULL); - return TCL_ERROR; + goto badIndex; } *indexPtr = NearestListboxElement(listPtr, y); return TCL_OK; @@ -2774,10 +2799,11 @@ GetListboxIndex( * Everything failed, nothing matched. Throw up an error message. */ - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "bad listbox index \"", - Tcl_GetString(indexObj), "\": must be active, anchor, ", - "end, @x,y, or a number", NULL); + badIndex: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad listbox index \"%s\": must be active, anchor, end, @x,y," + " or a number", Tcl_GetString(indexObj))); + Tcl_SetErrorCode(interp, "TK", "VALUE", "LISTBOX_INDEX", NULL); return TCL_ERROR; } @@ -2851,9 +2877,7 @@ ChangeListboxOffset( */ offset += listPtr->xScrollUnit / 2; - maxOffset = listPtr->maxWidth - (Tk_Width(listPtr->tkwin) - - 2*listPtr->inset - 2*listPtr->selBorderWidth) - + listPtr->xScrollUnit - 1; + maxOffset = GetMaxOffset(listPtr); if (offset > maxOffset) { offset = maxOffset; } @@ -2894,9 +2918,7 @@ ListboxScanTo( int newTopIndex, newOffset, maxIndex, maxOffset; maxIndex = listPtr->nElements - listPtr->fullLines; - maxOffset = listPtr->maxWidth + (listPtr->xScrollUnit - 1) - - (Tk_Width(listPtr->tkwin) - 2*listPtr->inset - - 2*listPtr->selBorderWidth - listPtr->xScrollUnit); + maxOffset = GetMaxOffset(listPtr); /* * Compute new top line for screen by amplifying the difference between @@ -2909,7 +2931,7 @@ ListboxScanTo( */ newTopIndex = listPtr->scanMarkYIndex - - (10*(y - listPtr->scanMarkY))/listPtr->lineHeight; + - (10*(y - listPtr->scanMarkY)) / listPtr->lineHeight; if (newTopIndex > maxIndex) { newTopIndex = listPtr->scanMarkYIndex = maxIndex; listPtr->scanMarkY = y; @@ -2961,7 +2983,7 @@ NearestListboxElement( { int index; - index = (y - listPtr->inset)/listPtr->lineHeight; + index = (y - listPtr->inset) / listPtr->lineHeight; if (index >= (listPtr->fullLines + listPtr->partialLine)) { index = listPtr->fullLines + listPtr->partialLine - 1; } @@ -3032,7 +3054,7 @@ ListboxSelect( */ for (i = first; i <= last; i++) { - entry = Tcl_FindHashEntry(listPtr->selection, (char *) INT2PTR(i)); + entry = Tcl_FindHashEntry(listPtr->selection, KEY(i)); if (entry != NULL) { if (!select) { Tcl_DeleteHashEntry(entry); @@ -3043,9 +3065,9 @@ ListboxSelect( } } else { if (select) { - entry = Tcl_CreateHashEntry(listPtr->selection, - (char *) INT2PTR(i), &isNew); - Tcl_SetHashValue(entry, (ClientData) NULL); + entry = Tcl_CreateHashEntry(listPtr->selection, KEY(i), + &isNew); + Tcl_SetHashValue(entry, NULL); listPtr->numSelected++; if (firstRedisplay < 0) { firstRedisplay = i; @@ -3058,9 +3080,10 @@ ListboxSelect( EventuallyRedrawRange(listPtr, first, last); } if ((oldCount == 0) && (listPtr->numSelected > 0) - && (listPtr->exportSelection)) { - Tk_OwnSelection(listPtr->tkwin, XA_PRIMARY, ListboxLostSelection, - (ClientData) listPtr); + && (listPtr->exportSelection) + && (!Tcl_IsSafe(listPtr->interp))) { + Tk_OwnSelection(listPtr->tkwin, XA_PRIMARY, + ListboxLostSelection, listPtr); } return TCL_OK; } @@ -3097,14 +3120,14 @@ ListboxFetchSelection( * not including terminating NULL * character. */ { - register Listbox *listPtr = (Listbox *) clientData; + register Listbox *listPtr = clientData; Tcl_DString selection; int length, count, needNewline, stringLen, i; Tcl_Obj *curElement; - char *stringRep; + const char *stringRep; Tcl_HashEntry *entry; - if (!listPtr->exportSelection) { + if ((!listPtr->exportSelection) || Tcl_IsSafe(listPtr->interp)) { return -1; } @@ -3115,7 +3138,7 @@ ListboxFetchSelection( needNewline = 0; Tcl_DStringInit(&selection); for (i = 0; i < listPtr->nElements; i++) { - entry = Tcl_FindHashEntry(listPtr->selection, (char *) INT2PTR(i)); + entry = Tcl_FindHashEntry(listPtr->selection, KEY(i)); if (entry != NULL) { if (needNewline) { Tcl_DStringAppend(&selection, "\n", 1); @@ -3173,9 +3196,10 @@ static void ListboxLostSelection( ClientData clientData) /* Information about listbox widget. */ { - register Listbox *listPtr = (Listbox *) clientData; + register Listbox *listPtr = clientData; - if ((listPtr->exportSelection) && (listPtr->nElements > 0)) { + if ((listPtr->exportSelection) && (!Tcl_IsSafe(listPtr->interp)) + && (listPtr->nElements > 0)) { ListboxSelect(listPtr, 0, listPtr->nElements-1, 0); GenerateListboxSelectEvent(listPtr); } @@ -3202,16 +3226,7 @@ static void GenerateListboxSelectEvent( Listbox *listPtr) /* Information about widget. */ { - union {XEvent general; XVirtualEvent virtual;} event; - - memset(&event, 0, sizeof(event)); - event.general.xany.type = VirtualEvent; - event.general.xany.serial = NextRequest(Tk_Display(listPtr->tkwin)); - event.general.xany.send_event = False; - event.general.xany.window = Tk_WindowId(listPtr->tkwin); - event.general.xany.display = Tk_Display(listPtr->tkwin); - event.virtual.name = Tk_GetUid("ListboxSelect"); - Tk_HandleEvent(&event.general); + TkSendVirtualEvent(listPtr->tkwin, "ListboxSelect", NULL); } /* @@ -3251,7 +3266,7 @@ EventuallyRedrawRange( return; } listPtr->flags |= REDRAW_PENDING; - Tcl_DoWhenIdle(DisplayListbox, (ClientData) listPtr); + Tcl_DoWhenIdle(DisplayListbox, listPtr); } /* @@ -3278,10 +3293,11 @@ static void ListboxUpdateVScrollbar( register Listbox *listPtr) /* Information about widget. */ { - char firstStr[TCL_DOUBLE_SPACE+1], lastStr[TCL_DOUBLE_SPACE+1]; + char firstStr[TCL_DOUBLE_SPACE], lastStr[TCL_DOUBLE_SPACE]; double first, last; int result; Tcl_Interp *interp; + Tcl_DString buf; if (listPtr->yScrollCmd == NULL) { return; @@ -3297,9 +3313,8 @@ ListboxUpdateVScrollbar( last = 1.0; } } - firstStr[0] = lastStr[0] = ' '; - Tcl_PrintDouble(NULL, first, firstStr+1); - Tcl_PrintDouble(NULL, last, lastStr+1); + Tcl_PrintDouble(NULL, first, firstStr); + Tcl_PrintDouble(NULL, last, lastStr); /* * We must hold onto the interpreter from the listPtr because the data at @@ -3308,12 +3323,18 @@ ListboxUpdateVScrollbar( interp = listPtr->interp; Tcl_Preserve(interp); - result = Tcl_VarEval(interp, listPtr->yScrollCmd, firstStr, lastStr, - NULL); + Tcl_DStringInit(&buf); + Tcl_DStringAppend(&buf, listPtr->yScrollCmd, -1); + Tcl_DStringAppend(&buf, " ", -1); + Tcl_DStringAppend(&buf, firstStr, -1); + Tcl_DStringAppend(&buf, " ", -1); + Tcl_DStringAppend(&buf, lastStr, -1); + result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, 0); + Tcl_DStringFree(&buf); if (result != TCL_OK) { Tcl_AddErrorInfo(interp, "\n (vertical scrolling command executed by listbox)"); - Tcl_BackgroundError(interp); + Tcl_BackgroundException(interp, result); } Tcl_Release(interp); } @@ -3342,31 +3363,30 @@ static void ListboxUpdateHScrollbar( register Listbox *listPtr) /* Information about widget. */ { - char firstStr[TCL_DOUBLE_SPACE+1], lastStr[TCL_DOUBLE_SPACE+1]; + char firstStr[TCL_DOUBLE_SPACE], lastStr[TCL_DOUBLE_SPACE]; int result, windowWidth; double first, last; Tcl_Interp *interp; + Tcl_DString buf; if (listPtr->xScrollCmd == NULL) { return; } - windowWidth = Tk_Width(listPtr->tkwin) - 2*(listPtr->inset - + listPtr->selBorderWidth); + + windowWidth = Tk_Width(listPtr->tkwin) + - 2*(listPtr->inset + listPtr->selBorderWidth); if (listPtr->maxWidth == 0) { first = 0; last = 1.0; } else { - register double maxWide = (double) listPtr->maxWidth; - - first = listPtr->xOffset / maxWide; - last = (listPtr->xOffset + windowWidth) / maxWide; + first = listPtr->xOffset / (double) listPtr->maxWidth; + last = (listPtr->xOffset + windowWidth) / (double) listPtr->maxWidth; if (last > 1.0) { last = 1.0; } } - firstStr[0] = lastStr[0] = ' '; - Tcl_PrintDouble(NULL, first, firstStr+1); - Tcl_PrintDouble(NULL, last, lastStr+1); + Tcl_PrintDouble(NULL, first, firstStr); + Tcl_PrintDouble(NULL, last, lastStr); /* * We must hold onto the interpreter because the data referred to at @@ -3375,12 +3395,18 @@ ListboxUpdateHScrollbar( interp = listPtr->interp; Tcl_Preserve(interp); - result = Tcl_VarEval(interp, listPtr->xScrollCmd, firstStr, lastStr, - NULL); + Tcl_DStringInit(&buf); + Tcl_DStringAppend(&buf, listPtr->xScrollCmd, -1); + Tcl_DStringAppend(&buf, " ", -1); + Tcl_DStringAppend(&buf, firstStr, -1); + Tcl_DStringAppend(&buf, " ", -1); + Tcl_DStringAppend(&buf, lastStr, -1); + result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, 0); + Tcl_DStringFree(&buf); if (result != TCL_OK) { Tcl_AddErrorInfo(interp, "\n (horizontal scrolling command executed by listbox)"); - Tcl_BackgroundError(interp); + Tcl_BackgroundException(interp, result); } Tcl_Release(interp); } @@ -3409,7 +3435,7 @@ ListboxListVarProc( const char *name2, /* Not used. */ int flags) /* Information about what happened. */ { - Listbox *listPtr = (Listbox *)clientData; + Listbox *listPtr = clientData; Tcl_Obj *oldListObj, *varListObj; int oldLength, i; Tcl_HashEntry *entry; @@ -3419,11 +3445,32 @@ ListboxListVarProc( */ if (flags & TCL_TRACE_UNSETS) { - if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) { + + if (!Tcl_InterpDeleted(interp) && listPtr->listVarName) { + ClientData probe = NULL; + + do { + probe = Tcl_VarTraceInfo(interp, + listPtr->listVarName, + TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + ListboxListVarProc, probe); + if (probe == (ClientData)listPtr) { + break; + } + } while (probe); + if (probe) { + /* + * We were able to fetch the unset trace for our + * listVarName, which means it is not unset and not + * the cause of this unset trace. Instead some outdated + * former variable must be, and we should ignore it. + */ + return NULL; + } Tcl_SetVar2Ex(interp, listPtr->listVarName, NULL, listPtr->listObj, TCL_GLOBAL_ONLY); - Tcl_TraceVar(interp, listPtr->listVarName, - TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + Tcl_TraceVar2(interp, listPtr->listVarName, + NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, ListboxListVarProc, clientData); return NULL; } @@ -3461,7 +3508,7 @@ ListboxListVarProc( /* * If the list length has decreased, then we should clean up selection and - * attributes information for elements past the end of the new list + * attributes information for elements past the end of the new list. */ oldLength = listPtr->nElements; @@ -3472,7 +3519,7 @@ ListboxListVarProc( * Clean up selection. */ - entry = Tcl_FindHashEntry(listPtr->selection, (char *) INT2PTR(i)); + entry = Tcl_FindHashEntry(listPtr->selection, KEY(i)); if (entry != NULL) { listPtr->numSelected--; Tcl_DeleteHashEntry(entry); @@ -3482,10 +3529,9 @@ ListboxListVarProc( * Clean up attributes. */ - entry = Tcl_FindHashEntry(listPtr->itemAttrTable, - (char *) INT2PTR(i)); + entry = Tcl_FindHashEntry(listPtr->itemAttrTable, KEY(i)); if (entry != NULL) { - ckfree((char *) Tcl_GetHashValue(entry)); + ckfree(Tcl_GetHashValue(entry)); Tcl_DeleteHashEntry(entry); } } @@ -3557,23 +3603,21 @@ MigrateHashEntries( if (offset > 0) { for (i = last; i >= first; i--) { - entry = Tcl_FindHashEntry(table, (char *) INT2PTR(i)); + entry = Tcl_FindHashEntry(table, KEY(i)); if (entry != NULL) { clientData = Tcl_GetHashValue(entry); Tcl_DeleteHashEntry(entry); - entry = Tcl_CreateHashEntry(table, - (char *) INT2PTR(i + offset), &isNew); + entry = Tcl_CreateHashEntry(table, KEY(i + offset), &isNew); Tcl_SetHashValue(entry, clientData); } } } else { for (i = first; i <= last; i++) { - entry = Tcl_FindHashEntry(table, (char *) INT2PTR(i)); + entry = Tcl_FindHashEntry(table, KEY(i)); if (entry != NULL) { clientData = Tcl_GetHashValue(entry); Tcl_DeleteHashEntry(entry); - entry = Tcl_CreateHashEntry(table, - (char *) INT2PTR(i + offset), &isNew); + entry = Tcl_CreateHashEntry(table, KEY(i + offset), &isNew); Tcl_SetHashValue(entry, clientData); } } @@ -3582,6 +3626,42 @@ MigrateHashEntries( } /* + *---------------------------------------------------------------------- + * + * GetMaxOffset -- + * + * Passing in a listbox pointer, returns the maximum offset for the box, + * i.e. the maximum possible horizontal scrolling value (in pixels). + * + * Results: + * Listbox's maxOffset. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- +*/ +static int GetMaxOffset( + register Listbox *listPtr) +{ + int maxOffset; + + maxOffset = listPtr->maxWidth - + (Tk_Width(listPtr->tkwin) - 2*listPtr->inset - + 2*listPtr->selBorderWidth) + listPtr->xScrollUnit - 1; + if (maxOffset < 0) { + + /* + * Listbox is larger in width than its largest width item. + */ + + maxOffset = 0; + } + maxOffset -= maxOffset % listPtr->xScrollUnit; + + return maxOffset; +} +/* * Local Variables: * mode: c * c-basic-offset: 4 diff --git a/generic/tkMacWinMenu.c b/generic/tkMacWinMenu.c index 9351de1..9449838 100644 --- a/generic/tkMacWinMenu.c +++ b/generic/tkMacWinMenu.c @@ -43,10 +43,10 @@ PreprocessMenu( TkMenu *menuPtr) { int index, result, finished; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - Tcl_Preserve((ClientData) menuPtr); + Tcl_Preserve(menuPtr); /* * First, let's process the post command on ourselves. If this command @@ -91,7 +91,7 @@ PreprocessMenu( } while (!finished); done: - Tcl_Release((ClientData) menuPtr); + Tcl_Release(menuPtr); return result; } @@ -129,7 +129,7 @@ int TkPreprocessMenu( TkMenu *menuPtr) { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); tsdPtr->postCommandGeneration++; diff --git a/generic/tkMain.c b/generic/tkMain.c index 00ac165..b80ce4d 100644 --- a/generic/tkMain.c +++ b/generic/tkMain.c @@ -14,29 +14,96 @@ * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ -#include "tclInt.h" +/** + * On Windows, this file needs to be compiled twice, once with + * TK_ASCII_MAIN defined. This way both Tk_MainEx and Tk_MainExW + * can be implemented, sharing the same source code. + */ +#if defined(TK_ASCII_MAIN) +# ifdef UNICODE +# undef UNICODE +# undef _UNICODE +# else +# define UNICODE +# define _UNICODE +# endif +#endif + #include "tkInt.h" -#ifdef __WIN32__ -#include "tkWinInt.h" -#include "../win/tclWinPort.h" +#include <ctype.h> +#include <stdio.h> +#include <string.h> +#ifdef NO_STDLIB_H +# include "../compat/stdlib.h" +#else +# include <stdlib.h> +#endif + +extern int TkCygwinMainEx(int, char **, Tcl_AppInitProc *, Tcl_Interp *); + +/* + * The default prompt used when the user has not overridden it. + */ + +static const char DEFAULT_PRIMARY_PROMPT[] = "% "; + +/* + * This file can be compiled on Windows in UNICODE mode, as well as + * on all other platforms using the native encoding. This is done + * by using the normal Windows functions like _tcscmp, but on + * platforms which don't have <tchar.h> we have to translate that + * to strcmp here. + */ +#ifdef _WIN32 +/* Little hack to eliminate the need for "tclInt.h" here: + Just copy a small portion of TclIntPlatStubs, just + enough to make it work. See [600b72bfbc] */ +typedef struct { + int magic; + void *hooks; + void (*dummy[16]) (void); /* dummy entries 0-15, not used */ + int (*tclpIsAtty) (int fd); /* 16 */ +} TclIntPlatStubs; +extern const TclIntPlatStubs *tclIntPlatStubsPtr; +# include "tkWinInt.h" +#else +# define TCHAR char +# define TEXT(arg) arg +# define _tcscmp strcmp +# define _tcslen strlen +# define _tcsncmp strncmp #endif + #ifdef MAC_OSX_TK #include "tkMacOSXInt.h" #endif -extern int TkCygwinMainEx(int, char **, Tcl_AppInitProc *, Tcl_Interp *); +/* + * Further on, in UNICODE mode we just use Tcl_NewUnicodeObj, otherwise + * NewNativeObj is needed (which provides proper conversion from native + * encoding to UTF-8). + */ -typedef struct ThreadSpecificData { - Tcl_Interp *interp; /* Interpreter for this thread. */ - Tcl_DString command; /* Used to assemble lines of terminal input - * into Tcl commands. */ - Tcl_DString line; /* Used to read the next line from the - * terminal input. */ - int tty; /* Non-zero means standard input is a - * terminal-like device. Zero means it's a - * file. */ -} ThreadSpecificData; -static Tcl_ThreadDataKey dataKey; +static inline Tcl_Obj * +NewNativeObj( + TCHAR *string, + int length) +{ + Tcl_Obj *obj; + Tcl_DString ds; + +#ifdef UNICODE + if (length > 0) { + length *= sizeof(WCHAR); + } + Tcl_WinTCharToUtf(string, length, &ds); +#else + Tcl_ExternalToUtfDString(NULL, (char *) string, length, &ds); +#endif + obj = Tcl_NewStringObj(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds)); + Tcl_DStringFree(&ds); + return obj; +} /* * Declarations for various library functions and variables (don't want to @@ -46,54 +113,57 @@ static Tcl_ThreadDataKey dataKey; * it will conflict with a declaration elsewhere on some systems. */ -#if defined(__WIN32__) || defined(_WIN32) +#if defined(_WIN32) #define isatty WinIsTty static int WinIsTty(int fd) { HANDLE handle; /* * For now, under Windows, we assume we are not running as a console mode - * app, so we need to use the GUI console. In order to enable this, we - * always claim to be running on a tty. This probably isn't the right - * way to do it. + * app, so we need to use the GUI console. In order to enable this, we + * always claim to be running on a tty. This probably isn't the right way + * to do it. */ #if !defined(STATIC_BUILD) - if (tclStubsPtr->reserved9 && TclpIsAtty) { + if (tclStubsPtr->reserved9 && tclIntPlatStubsPtr->tclpIsAtty) { /* We are running on Cygwin */ - return TclpIsAtty(fd); + return tclIntPlatStubsPtr->tclpIsAtty(fd); } #endif handle = GetStdHandle(STD_INPUT_HANDLE + fd); - - if ((handle == INVALID_HANDLE_VALUE) || (handle == 0) - || (GetFileType(handle) == FILE_TYPE_UNKNOWN)) { - /* - * If it's a bad or closed handle, then it's been connected - * to a wish console window. - */ - - return 1; - } else if (GetFileType(handle) == FILE_TYPE_CHAR) { /* - * A character file handle is a tty by definition. + * If it's a bad or closed handle, then it's been connected to a wish + * console window. A character file handle is a tty by definition. */ - - return 1; - } else { - return 0; - } + return (handle == INVALID_HANDLE_VALUE) || (handle == 0) + || (GetFileType(handle) == FILE_TYPE_UNKNOWN) + || (GetFileType(handle) == FILE_TYPE_CHAR); } #else extern int isatty(int fd); -extern char * strrchr(CONST char *string, int c); #endif +typedef struct InteractiveState { + Tcl_Channel input; /* The standard input channel from which lines + * are read. */ + int tty; /* Non-zero means standard input is a + * terminal-like device. Zero means it's a + * file. */ + Tcl_DString command; /* Used to assemble lines of terminal input + * into Tcl commands. */ + Tcl_DString line; /* Used to read the next line from the + * terminal input. */ + int gotPartial; + Tcl_Interp *interp; /* Interpreter that evaluates interactive + * commands. */ +} InteractiveState; + /* * Forward declarations for functions defined later in this file. */ -static void Prompt(Tcl_Interp *interp, int partial); +static void Prompt(Tcl_Interp *interp, InteractiveState *isPtr); static void StdinProc(ClientData clientData, int mask); /* @@ -105,7 +175,7 @@ static void StdinProc(ClientData clientData, int mask); * * Results: * None. This function never returns (it exits the process when it's - * done. + * done). * * Side effects: * This function initializes the Tk world and then starts interpreting @@ -114,36 +184,36 @@ static void StdinProc(ClientData clientData, int mask); * *---------------------------------------------------------------------- */ + void Tk_MainEx( int argc, /* Number of arguments. */ - char **argv, /* Array of argument strings. */ + TCHAR **argv, /* Array of argument strings. */ Tcl_AppInitProc *appInitProc, /* Application-specific initialization * function to call after most initialization * but before starting to execute commands. */ Tcl_Interp *interp) { - Tcl_Obj *path, *argvPtr; - CONST char *encodingName; + Tcl_Obj *path, *argvPtr, *appName; + const char *encodingName; int code, nullStdin = 0; - Tcl_Channel inChannel, outChannel; - ThreadSpecificData *tsdPtr; - Tcl_DString appName; + Tcl_Channel chan; + InteractiveState is; /* * Ensure that we are getting a compatible version of Tcl. */ - if (Tcl_InitStubs(interp, "8.5.0", 0) == NULL) { + if (Tcl_InitStubs(interp, "8.6", 0) == NULL) { if (Tcl_InitStubs(interp, "8.1", 0) == NULL) { abort(); } else { - Tcl_Panic("%s", Tcl_GetStringResult(interp)); + Tcl_Panic("%s", Tcl_GetString(Tcl_GetObjResult(interp))); } } -#if defined(__WIN32__) && !defined(STATIC_BUILD) +#if defined(_WIN32) && !defined(UNICODE) && !defined(STATIC_BUILD) if (tclStubsPtr->reserved9) { /* We are running win32 Tk under Cygwin, so let's check @@ -160,7 +230,7 @@ Tk_MainEx( int i; for (i = 1; i < argc; ++i) { - if (!strcmp(argv[i], "-display")) { + if (!_tcscmp(argv[i], TEXT("-display"))) { goto loadCygwinTk; } } @@ -168,19 +238,17 @@ Tk_MainEx( } #endif - tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + Tcl_InitMemory(interp); - Tcl_FindExecutable(argv[0]); - tsdPtr->interp = interp; - Tcl_Preserve((ClientData) interp); + is.interp = interp; + is.gotPartial = 0; + Tcl_Preserve(interp); -#if defined(__WIN32__) && !defined(STATIC_BUILD) - if (!tclStubsPtr->reserved9) { - /* Only initialize console when not running under cygwin */ - Tk_InitConsoleChannels(interp); - } -#elif defined(__WIN32__) +#if defined(_WIN32) && !defined(__CYGWIN__) +#if !defined(STATIC_BUILD) + /* If compiled for Win32 but running on Cygwin, don't use console */ + if (!tclStubsPtr->reserved9) +#endif Tk_InitConsoleChannels(interp); #endif @@ -190,10 +258,6 @@ Tk_MainEx( } #endif -#ifdef TCL_MEM_DEBUG - Tcl_InitMemory(interp); -#endif - /* * If the application has not already set a startup script, parse the * first few command line arguments to determine the script path and @@ -205,44 +269,40 @@ Tk_MainEx( /* * Check whether first 3 args (argv[1] - argv[3]) look like - * -encoding ENCODING FILENAME + * -encoding ENCODING FILENAME * or like - * FILENAME + * FILENAME * or like - * -file FILENAME (ancient history support only) + * -file FILENAME (ancient history support only) */ - if ((argc > 3) && (0 == strcmp("-encoding", argv[1])) - && ('-' != argv[3][0])) { - Tcl_SetStartupScript(Tcl_NewStringObj(argv[3], -1), argv[2]); + if ((argc > 3) && (0 == _tcscmp(TEXT("-encoding"), argv[1])) + && (TEXT('-') != argv[3][0])) { + Tcl_Obj *value = NewNativeObj(argv[2], -1); + Tcl_SetStartupScript(NewNativeObj(argv[3], -1), Tcl_GetString(value)); + Tcl_DecrRefCount(value); argc -= 3; argv += 3; - } else if ((argc > 1) && ('-' != argv[1][0])) { - Tcl_SetStartupScript(Tcl_NewStringObj(argv[1], -1), NULL); + } else if ((argc > 1) && (TEXT('-') != argv[1][0])) { + Tcl_SetStartupScript(NewNativeObj(argv[1], -1), NULL); argc--; argv++; - } else if ((argc > 2) && (length = strlen(argv[1])) - && (length > 1) && (0 == strncmp("-file", argv[1], length)) - && ('-' != argv[2][0])) { - Tcl_SetStartupScript(Tcl_NewStringObj(argv[2], -1), NULL); + } else if ((argc > 2) && (length = _tcslen(argv[1])) + && (length > 1) && (0 == _tcsncmp(TEXT("-file"), argv[1], length)) + && (TEXT('-') != argv[2][0])) { + Tcl_SetStartupScript(NewNativeObj(argv[2], -1), NULL); argc -= 2; argv += 2; } } path = Tcl_GetStartupScript(&encodingName); - if (NULL == path) { - Tcl_ExternalToUtfDString(NULL, argv[0], -1, &appName); + if (path == NULL) { + appName = NewNativeObj(argv[0], -1); } else { - int numBytes; - CONST char *pathName = Tcl_GetStringFromObj(path, &numBytes); - - Tcl_ExternalToUtfDString(NULL, pathName, numBytes, &appName); - path = Tcl_NewStringObj(Tcl_DStringValue(&appName), -1); - Tcl_SetStartupScript(path, encodingName); + appName = path; } - Tcl_SetVar(interp, "argv0", Tcl_DStringValue(&appName), TCL_GLOBAL_ONLY); - Tcl_DStringFree(&appName); + Tcl_SetVar2Ex(interp, "argv0", NULL, appName, TCL_GLOBAL_ONLY); argc--; argv++; @@ -250,12 +310,7 @@ Tk_MainEx( argvPtr = Tcl_NewListObj(0, NULL); while (argc--) { - Tcl_DString ds; - - Tcl_ExternalToUtfDString(NULL, *argv++, -1, &ds); - Tcl_ListObjAppendElement(NULL, argvPtr, Tcl_NewStringObj( - Tcl_DStringValue(&ds), Tcl_DStringLength(&ds))); - Tcl_DStringFree(&ds); + Tcl_ListObjAppendElement(NULL, argvPtr, NewNativeObj(*argv++, -1)); } Tcl_SetVar2Ex(interp, "argv", NULL, argvPtr, TCL_GLOBAL_ONLY); @@ -263,32 +318,30 @@ Tk_MainEx( * Set the "tcl_interactive" variable. */ - tsdPtr->tty = isatty(0); - + is.tty = isatty(0); #if defined(MAC_OSX_TK) /* * On TkAqua, if we don't have a TTY and stdin is a special character file * of length 0, (e.g. /dev/null, which is what Finder sets when double * clicking Wish) then use the GUI console. */ - - if (!tsdPtr->tty) { + + if (!is.tty) { struct stat st; nullStdin = fstat(0, &st) || (S_ISCHR(st.st_mode) && !st.st_blocks); } #endif - Tcl_SetVar(interp, "tcl_interactive", - ((path == NULL) && (tsdPtr->tty || nullStdin)) ? "1" : "0", - TCL_GLOBAL_ONLY); + Tcl_SetVar2Ex(interp, "tcl_interactive", NULL, + Tcl_NewIntObj(!path && (is.tty || nullStdin)), TCL_GLOBAL_ONLY); /* * Invoke application-specific initialization. */ - if ((*appInitProc)(interp) != TCL_OK) { - TkpDisplayWarning(Tcl_GetStringResult(interp), - "Application initialization failed"); + if (appInitProc(interp) != TCL_OK) { + TkpDisplayWarning(Tcl_GetString(Tcl_GetObjResult(interp)), + "application-specific initialization failed"); } /* @@ -307,12 +360,12 @@ Tk_MainEx( */ Tcl_AddErrorInfo(interp, ""); - TkpDisplayWarning(Tcl_GetVar(interp, "errorInfo", + TkpDisplayWarning(Tcl_GetVar2(interp, "errorInfo", NULL, TCL_GLOBAL_ONLY), "Error in startup script"); Tcl_DeleteInterp(interp); Tcl_Exit(1); } - tsdPtr->tty = 0; + is.tty = 0; } else { /* @@ -325,22 +378,21 @@ Tk_MainEx( * Establish a channel handler for stdin. */ - inChannel = Tcl_GetStdChannel(TCL_STDIN); - if (inChannel) { - Tcl_CreateChannelHandler(inChannel, TCL_READABLE, StdinProc, - (ClientData) inChannel); + is.input = Tcl_GetStdChannel(TCL_STDIN); + if (is.input) { + Tcl_CreateChannelHandler(is.input, TCL_READABLE, StdinProc, &is); } - if (tsdPtr->tty) { - Prompt(interp, 0); + if (is.tty) { + Prompt(interp, &is); } } - outChannel = Tcl_GetStdChannel(TCL_STDOUT); - if (outChannel) { - Tcl_Flush(outChannel); + chan = Tcl_GetStdChannel(TCL_STDOUT); + if (chan) { + Tcl_Flush(chan); } - Tcl_DStringInit(&tsdPtr->command); - Tcl_DStringInit(&tsdPtr->line); + Tcl_DStringInit(&is.command); + Tcl_DStringInit(&is.line); Tcl_ResetResult(interp); /* @@ -350,7 +402,7 @@ Tk_MainEx( Tk_MainLoop(); Tcl_DeleteInterp(interp); - Tcl_Release((ClientData) interp); + Tcl_Release(interp); Tcl_SetStartupScript(NULL, NULL); Tcl_Exit(0); } @@ -377,37 +429,34 @@ Tk_MainEx( /* ARGSUSED */ static void StdinProc( - ClientData clientData, /* Not used. */ + ClientData clientData, /* The state of interactive cmd line */ int mask) /* Not used. */ { - static int gotPartial = 0; char *cmd; int code, count; - Tcl_Channel chan = (Tcl_Channel) clientData; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - Tcl_Interp *interp = tsdPtr->interp; + InteractiveState *isPtr = clientData; + Tcl_Channel chan = isPtr->input; + Tcl_Interp *interp = isPtr->interp; - count = Tcl_Gets(chan, &tsdPtr->line); + count = Tcl_Gets(chan, &isPtr->line); - if (count < 0 && !gotPartial) { - if (tsdPtr->tty) { + if (count < 0 && !isPtr->gotPartial) { + if (isPtr->tty) { Tcl_Exit(0); } else { - Tcl_DeleteChannelHandler(chan, StdinProc, (ClientData) chan); + Tcl_DeleteChannelHandler(chan, StdinProc, isPtr); } return; } - (void) Tcl_DStringAppend(&tsdPtr->command, Tcl_DStringValue( - &tsdPtr->line), -1); - cmd = Tcl_DStringAppend(&tsdPtr->command, "\n", -1); - Tcl_DStringFree(&tsdPtr->line); + Tcl_DStringAppend(&isPtr->command, Tcl_DStringValue(&isPtr->line), -1); + cmd = Tcl_DStringAppend(&isPtr->command, "\n", -1); + Tcl_DStringFree(&isPtr->line); if (!Tcl_CommandComplete(cmd)) { - gotPartial = 1; + isPtr->gotPartial = 1; goto prompt; } - gotPartial = 0; + isPtr->gotPartial = 0; /* * Disable the stdin channel handler while evaluating the command; @@ -416,18 +465,17 @@ StdinProc( * things, this will trash the text of the command being evaluated. */ - Tcl_CreateChannelHandler(chan, 0, StdinProc, (ClientData) chan); + Tcl_CreateChannelHandler(chan, 0, StdinProc, isPtr); code = Tcl_RecordAndEval(interp, cmd, TCL_EVAL_GLOBAL); - chan = Tcl_GetStdChannel(TCL_STDIN); - if (chan) { - Tcl_CreateChannelHandler(chan, TCL_READABLE, StdinProc, - (ClientData) chan); + isPtr->input = Tcl_GetStdChannel(TCL_STDIN); + if (isPtr->input) { + Tcl_CreateChannelHandler(isPtr->input, TCL_READABLE, StdinProc, isPtr); } - Tcl_DStringFree(&tsdPtr->command); - if (Tcl_GetStringResult(interp)[0] != '\0') { - if ((code != TCL_OK) || (tsdPtr->tty)) { - chan = Tcl_GetStdChannel(TCL_STDOUT); + Tcl_DStringFree(&isPtr->command); + if (Tcl_GetString(Tcl_GetObjResult(interp))[0] != '\0') { + if ((code != TCL_OK) || (isPtr->tty)) { + chan = Tcl_GetStdChannel((code != TCL_OK) ? TCL_STDERR : TCL_STDOUT); if (chan) { Tcl_WriteObj(chan, Tcl_GetObjResult(interp)); Tcl_WriteChars(chan, "\n", 1); @@ -436,12 +484,12 @@ StdinProc( } /* - * Output a prompt. + * If a tty stdin is still around, output a prompt. */ prompt: - if (tsdPtr->tty) { - Prompt(interp, gotPartial); + if (isPtr->tty && (isPtr->input != NULL)) { + Prompt(interp, isPtr); } Tcl_ResetResult(interp); } @@ -466,53 +514,42 @@ StdinProc( static void Prompt( Tcl_Interp *interp, /* Interpreter to use for prompting. */ - int partial) /* Non-zero means there already exists a - * partial command, so use the secondary - * prompt. */ + InteractiveState *isPtr) /* InteractiveState. */ { - Tcl_Obj *promptCmd; + Tcl_Obj *promptCmdPtr; int code; - Tcl_Channel outChannel, errChannel; + Tcl_Channel chan; - promptCmd = Tcl_GetVar2Ex(interp, - partial ? "tcl_prompt2" : "tcl_prompt1", NULL, TCL_GLOBAL_ONLY); - if (promptCmd == NULL) { + promptCmdPtr = Tcl_GetVar2Ex(interp, + isPtr->gotPartial ? "tcl_prompt2" : "tcl_prompt1", NULL, TCL_GLOBAL_ONLY); + if (promptCmdPtr == NULL) { defaultPrompt: - if (!partial) { - /* - * We must check that outChannel is a real channel - it is - * possible that someone has transferred stdout out of this - * interpreter with "interp transfer". - */ - - outChannel = Tcl_GetChannel(interp, "stdout", NULL); - if (outChannel != (Tcl_Channel) NULL) { - Tcl_WriteChars(outChannel, "% ", 2); + if (!isPtr->gotPartial) { + chan = Tcl_GetStdChannel(TCL_STDOUT); + if (chan != NULL) { + Tcl_WriteChars(chan, DEFAULT_PRIMARY_PROMPT, + sizeof(DEFAULT_PRIMARY_PROMPT) - 1); } } } else { - code = Tcl_EvalObjEx(interp, promptCmd, TCL_EVAL_GLOBAL); + code = Tcl_EvalObjEx(interp, promptCmdPtr, TCL_EVAL_GLOBAL); if (code != TCL_OK) { Tcl_AddErrorInfo(interp, "\n (script that generates prompt)"); - - /* - * We must check that errChannel is a real channel - it is - * possible that someone has transferred stderr out of this - * interpreter with "interp transfer". - */ - - errChannel = Tcl_GetChannel(interp, "stderr", NULL); - if (errChannel != (Tcl_Channel) NULL) { - Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp)); - Tcl_WriteChars(errChannel, "\n", 1); + if (Tcl_GetString(Tcl_GetObjResult(interp))[0] != '\0') { + chan = Tcl_GetStdChannel(TCL_STDERR); + if (chan != NULL) { + Tcl_WriteObj(chan, Tcl_GetObjResult(interp)); + Tcl_WriteChars(chan, "\n", 1); + } } goto defaultPrompt; } } - outChannel = Tcl_GetChannel(interp, "stdout", NULL); - if (outChannel != (Tcl_Channel) NULL) { - Tcl_Flush(outChannel); + + chan = Tcl_GetStdChannel(TCL_STDOUT); + if (chan != NULL) { + Tcl_Flush(chan); } } diff --git a/generic/tkMenu.c b/generic/tkMenu.c index 171087a..3a2d987 100644 --- a/generic/tkMenu.c +++ b/generic/tkMenu.c @@ -81,6 +81,10 @@ typedef struct ThreadSpecificData { int menusInitialized; /* Flag indicates whether thread-specific * elements of the Windows Menu module have * been initialized. */ + Tk_OptionTable menuOptionTable; + /* The option table for menus. */ + Tk_OptionTable entryOptionTables[6]; + /* The tables for menu entries. */ } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; @@ -97,9 +101,9 @@ TCL_DECLARE_MUTEX(menuMutex) * to update code in TkpMenuInit that changes the font string entry. */ -const char *tkMenuStateStrings[] = {"active", "normal", "disabled", NULL}; +static const char *const menuStateStrings[] = {"active", "normal", "disabled", NULL}; -static const char *menuEntryTypeStrings[] = { +static const char *const menuEntryTypeStrings[] = { "cascade", "checkbutton", "command", "radiobutton", "separator", NULL }; @@ -108,128 +112,128 @@ static const char *menuEntryTypeStrings[] = { * is used with the "enum compound" declaration in tkMenu.h */ -static const char *compoundStrings[] = { +static const char *const compoundStrings[] = { "bottom", "center", "left", "none", "right", "top", NULL }; static const Tk_OptionSpec tkBasicMenuEntryConfigSpecs[] = { {TK_OPTION_BORDER, "-activebackground", NULL, NULL, DEF_MENU_ENTRY_ACTIVE_BG, Tk_Offset(TkMenuEntry, activeBorderPtr), -1, - TK_OPTION_NULL_OK}, + TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_COLOR, "-activeforeground", NULL, NULL, DEF_MENU_ENTRY_ACTIVE_FG, - Tk_Offset(TkMenuEntry, activeFgPtr), -1, TK_OPTION_NULL_OK}, + Tk_Offset(TkMenuEntry, activeFgPtr), -1, TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_STRING, "-accelerator", NULL, NULL, DEF_MENU_ENTRY_ACCELERATOR, - Tk_Offset(TkMenuEntry, accelPtr), -1, TK_OPTION_NULL_OK}, + Tk_Offset(TkMenuEntry, accelPtr), -1, TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_BORDER, "-background", NULL, NULL, DEF_MENU_ENTRY_BG, - Tk_Offset(TkMenuEntry, borderPtr), -1, TK_OPTION_NULL_OK}, + Tk_Offset(TkMenuEntry, borderPtr), -1, TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_BITMAP, "-bitmap", NULL, NULL, DEF_MENU_ENTRY_BITMAP, - Tk_Offset(TkMenuEntry, bitmapPtr), -1, TK_OPTION_NULL_OK}, + Tk_Offset(TkMenuEntry, bitmapPtr), -1, TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_BOOLEAN, "-columnbreak", NULL, NULL, DEF_MENU_ENTRY_COLUMN_BREAK, - -1, Tk_Offset(TkMenuEntry, columnBreak)}, + -1, Tk_Offset(TkMenuEntry, columnBreak), 0, NULL, 0}, {TK_OPTION_STRING, "-command", NULL, NULL, DEF_MENU_ENTRY_COMMAND, - Tk_Offset(TkMenuEntry, commandPtr), -1, TK_OPTION_NULL_OK}, + Tk_Offset(TkMenuEntry, commandPtr), -1, TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound", DEF_MENU_ENTRY_COMPOUND, -1, Tk_Offset(TkMenuEntry, compound), 0, (ClientData) compoundStrings, 0}, {TK_OPTION_FONT, "-font", NULL, NULL, DEF_MENU_ENTRY_FONT, - Tk_Offset(TkMenuEntry, fontPtr), -1, TK_OPTION_NULL_OK}, + Tk_Offset(TkMenuEntry, fontPtr), -1, TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_COLOR, "-foreground", NULL, NULL, DEF_MENU_ENTRY_FG, - Tk_Offset(TkMenuEntry, fgPtr), -1, TK_OPTION_NULL_OK}, + Tk_Offset(TkMenuEntry, fgPtr), -1, TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_BOOLEAN, "-hidemargin", NULL, NULL, DEF_MENU_ENTRY_HIDE_MARGIN, - -1, Tk_Offset(TkMenuEntry, hideMargin)}, + -1, Tk_Offset(TkMenuEntry, hideMargin), 0, NULL, 0}, {TK_OPTION_STRING, "-image", NULL, NULL, DEF_MENU_ENTRY_IMAGE, - Tk_Offset(TkMenuEntry, imagePtr), -1, TK_OPTION_NULL_OK}, + Tk_Offset(TkMenuEntry, imagePtr), -1, TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_STRING, "-label", NULL, NULL, DEF_MENU_ENTRY_LABEL, - Tk_Offset(TkMenuEntry, labelPtr), -1, 0}, + Tk_Offset(TkMenuEntry, labelPtr), -1, 0, NULL, 0}, {TK_OPTION_STRING_TABLE, "-state", NULL, NULL, DEF_MENU_ENTRY_STATE, -1, Tk_Offset(TkMenuEntry, state), 0, - (ClientData) tkMenuStateStrings}, + (ClientData) menuStateStrings, 0}, {TK_OPTION_INT, "-underline", NULL, NULL, - DEF_MENU_ENTRY_UNDERLINE, -1, Tk_Offset(TkMenuEntry, underline)}, - {TK_OPTION_END} + DEF_MENU_ENTRY_UNDERLINE, -1, Tk_Offset(TkMenuEntry, underline), 0, NULL, 0}, + {TK_OPTION_END, NULL, NULL, NULL, 0, 0, 0, 0, NULL, 0} }; static const Tk_OptionSpec tkSeparatorEntryConfigSpecs[] = { {TK_OPTION_BORDER, "-background", NULL, NULL, DEF_MENU_ENTRY_BG, - Tk_Offset(TkMenuEntry, borderPtr), -1, TK_OPTION_NULL_OK}, - {TK_OPTION_END} + Tk_Offset(TkMenuEntry, borderPtr), -1, TK_OPTION_NULL_OK, NULL, 0}, + {TK_OPTION_END, NULL, NULL, NULL, 0, 0, 0, 0, NULL, 0} }; static const Tk_OptionSpec tkCheckButtonEntryConfigSpecs[] = { {TK_OPTION_BOOLEAN, "-indicatoron", NULL, NULL, DEF_MENU_ENTRY_INDICATOR, - -1, Tk_Offset(TkMenuEntry, indicatorOn)}, + -1, Tk_Offset(TkMenuEntry, indicatorOn), 0, NULL, 0}, {TK_OPTION_STRING, "-offvalue", NULL, NULL, DEF_MENU_ENTRY_OFF_VALUE, - Tk_Offset(TkMenuEntry, offValuePtr), -1}, + Tk_Offset(TkMenuEntry, offValuePtr), -1, 0, NULL, 0}, {TK_OPTION_STRING, "-onvalue", NULL, NULL, DEF_MENU_ENTRY_ON_VALUE, - Tk_Offset(TkMenuEntry, onValuePtr), -1}, + Tk_Offset(TkMenuEntry, onValuePtr), -1, 0, NULL, 0}, {TK_OPTION_COLOR, "-selectcolor", NULL, NULL, DEF_MENU_ENTRY_SELECT, - Tk_Offset(TkMenuEntry, indicatorFgPtr), -1, TK_OPTION_NULL_OK}, + Tk_Offset(TkMenuEntry, indicatorFgPtr), -1, TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_STRING, "-selectimage", NULL, NULL, DEF_MENU_ENTRY_SELECT_IMAGE, - Tk_Offset(TkMenuEntry, selectImagePtr), -1, TK_OPTION_NULL_OK}, + Tk_Offset(TkMenuEntry, selectImagePtr), -1, TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_STRING, "-variable", NULL, NULL, DEF_MENU_ENTRY_CHECK_VARIABLE, - Tk_Offset(TkMenuEntry, namePtr), -1, TK_OPTION_NULL_OK}, + Tk_Offset(TkMenuEntry, namePtr), -1, TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_END, NULL, NULL, NULL, - NULL, 0, -1, 0, (ClientData) tkBasicMenuEntryConfigSpecs} + NULL, 0, -1, 0, tkBasicMenuEntryConfigSpecs, 0} }; static const Tk_OptionSpec tkRadioButtonEntryConfigSpecs[] = { {TK_OPTION_BOOLEAN, "-indicatoron", NULL, NULL, DEF_MENU_ENTRY_INDICATOR, - -1, Tk_Offset(TkMenuEntry, indicatorOn)}, + -1, Tk_Offset(TkMenuEntry, indicatorOn), 0, NULL, 0}, {TK_OPTION_COLOR, "-selectcolor", NULL, NULL, DEF_MENU_ENTRY_SELECT, - Tk_Offset(TkMenuEntry, indicatorFgPtr), -1, TK_OPTION_NULL_OK}, + Tk_Offset(TkMenuEntry, indicatorFgPtr), -1, TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_STRING, "-selectimage", NULL, NULL, DEF_MENU_ENTRY_SELECT_IMAGE, - Tk_Offset(TkMenuEntry, selectImagePtr), -1, TK_OPTION_NULL_OK}, + Tk_Offset(TkMenuEntry, selectImagePtr), -1, TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_STRING, "-value", NULL, NULL, DEF_MENU_ENTRY_VALUE, - Tk_Offset(TkMenuEntry, onValuePtr), -1, TK_OPTION_NULL_OK}, + Tk_Offset(TkMenuEntry, onValuePtr), -1, TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_STRING, "-variable", NULL, NULL, DEF_MENU_ENTRY_RADIO_VARIABLE, - Tk_Offset(TkMenuEntry, namePtr), -1, 0}, + Tk_Offset(TkMenuEntry, namePtr), -1, 0, NULL, 0}, {TK_OPTION_END, NULL, NULL, NULL, - NULL, 0, -1, 0, (ClientData) tkBasicMenuEntryConfigSpecs} + NULL, 0, -1, 0, tkBasicMenuEntryConfigSpecs, 0} }; static const Tk_OptionSpec tkCascadeEntryConfigSpecs[] = { {TK_OPTION_STRING, "-menu", NULL, NULL, DEF_MENU_ENTRY_MENU, - Tk_Offset(TkMenuEntry, namePtr), -1, TK_OPTION_NULL_OK}, + Tk_Offset(TkMenuEntry, namePtr), -1, TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_END, NULL, NULL, NULL, - NULL, 0, -1, 0, (ClientData) tkBasicMenuEntryConfigSpecs} + NULL, 0, -1, 0, tkBasicMenuEntryConfigSpecs, 0} }; static const Tk_OptionSpec tkTearoffEntryConfigSpecs[] = { {TK_OPTION_BORDER, "-background", NULL, NULL, DEF_MENU_ENTRY_BG, - Tk_Offset(TkMenuEntry, borderPtr), -1, TK_OPTION_NULL_OK}, + Tk_Offset(TkMenuEntry, borderPtr), -1, TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_STRING_TABLE, "-state", NULL, NULL, DEF_MENU_ENTRY_STATE, -1, Tk_Offset(TkMenuEntry, state), 0, - (ClientData) tkMenuStateStrings}, - {TK_OPTION_END} + (ClientData) menuStateStrings, 0}, + {TK_OPTION_END, NULL, NULL, NULL, 0, 0, 0, 0, NULL, 0} }; -static const Tk_OptionSpec *const specsArray[] = { +static const Tk_OptionSpec *specsArray[] = { tkCascadeEntryConfigSpecs, tkCheckButtonEntryConfigSpecs, tkBasicMenuEntryConfigSpecs, tkRadioButtonEntryConfigSpecs, tkSeparatorEntryConfigSpecs, tkTearoffEntryConfigSpecs @@ -239,7 +243,7 @@ static const Tk_OptionSpec *const specsArray[] = { * Menu type strings for use with Tcl_GetIndexFromObj. */ -static const char *menuTypeStrings[] = { +static const char *const menuTypeStrings[] = { "normal", "tearoff", "menubar", NULL }; @@ -247,60 +251,60 @@ static const Tk_OptionSpec tkMenuConfigSpecs[] = { {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground", DEF_MENU_ACTIVE_BG_COLOR, Tk_Offset(TkMenu, activeBorderPtr), -1, 0, - (ClientData) DEF_MENU_ACTIVE_BG_MONO}, + (ClientData) DEF_MENU_ACTIVE_BG_MONO, 0}, {TK_OPTION_PIXELS, "-activeborderwidth", "activeBorderWidth", "BorderWidth", DEF_MENU_ACTIVE_BORDER_WIDTH, - Tk_Offset(TkMenu, activeBorderWidthPtr), -1}, + Tk_Offset(TkMenu, activeBorderWidthPtr), -1, 0, NULL, 0}, {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background", DEF_MENU_ACTIVE_FG_COLOR, Tk_Offset(TkMenu, activeFgPtr), -1, 0, - (ClientData) DEF_MENU_ACTIVE_FG_MONO}, + (ClientData) DEF_MENU_ACTIVE_FG_MONO, 0}, {TK_OPTION_BORDER, "-background", "background", "Background", DEF_MENU_BG_COLOR, Tk_Offset(TkMenu, borderPtr), -1, 0, - (ClientData) DEF_MENU_BG_MONO}, + (ClientData) DEF_MENU_BG_MONO, 0}, {TK_OPTION_SYNONYM, "-bd", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-borderwidth"}, + NULL, 0, -1, 0, "-borderwidth", 0}, {TK_OPTION_SYNONYM, "-bg", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-background"}, + NULL, 0, -1, 0, "-background", 0}, {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", DEF_MENU_BORDER_WIDTH, - Tk_Offset(TkMenu, borderWidthPtr), -1, 0}, + Tk_Offset(TkMenu, borderWidthPtr), -1, 0, NULL, 0}, {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", DEF_MENU_CURSOR, - Tk_Offset(TkMenu, cursorPtr), -1, TK_OPTION_NULL_OK}, + Tk_Offset(TkMenu, cursorPtr), -1, TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground", "DisabledForeground", DEF_MENU_DISABLED_FG_COLOR, Tk_Offset(TkMenu, disabledFgPtr), -1, TK_OPTION_NULL_OK, - (ClientData) DEF_MENU_DISABLED_FG_MONO}, + (ClientData) DEF_MENU_DISABLED_FG_MONO, 0}, {TK_OPTION_SYNONYM, "-fg", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-foreground"}, + NULL, 0, -1, 0, "-foreground", 0}, {TK_OPTION_FONT, "-font", "font", "Font", - DEF_MENU_FONT, Tk_Offset(TkMenu, fontPtr), -1}, + DEF_MENU_FONT, Tk_Offset(TkMenu, fontPtr), -1, 0, NULL, 0}, {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground", - DEF_MENU_FG, Tk_Offset(TkMenu, fgPtr), -1}, + DEF_MENU_FG, Tk_Offset(TkMenu, fgPtr), -1, 0, NULL, 0}, {TK_OPTION_STRING, "-postcommand", "postCommand", "Command", DEF_MENU_POST_COMMAND, - Tk_Offset(TkMenu, postCommandPtr), -1, TK_OPTION_NULL_OK}, + Tk_Offset(TkMenu, postCommandPtr), -1, TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_RELIEF, "-relief", "relief", "Relief", - DEF_MENU_RELIEF, Tk_Offset(TkMenu, reliefPtr), -1}, + DEF_MENU_RELIEF, Tk_Offset(TkMenu, reliefPtr), -1, 0, NULL, 0}, {TK_OPTION_COLOR, "-selectcolor", "selectColor", "Background", DEF_MENU_SELECT_COLOR, Tk_Offset(TkMenu, indicatorFgPtr), -1, 0, - (ClientData) DEF_MENU_SELECT_MONO}, + (ClientData) DEF_MENU_SELECT_MONO, 0}, {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", DEF_MENU_TAKE_FOCUS, - Tk_Offset(TkMenu, takeFocusPtr), -1, TK_OPTION_NULL_OK}, + Tk_Offset(TkMenu, takeFocusPtr), -1, TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_BOOLEAN, "-tearoff", "tearOff", "TearOff", - DEF_MENU_TEAROFF, -1, Tk_Offset(TkMenu, tearoff)}, + DEF_MENU_TEAROFF, -1, Tk_Offset(TkMenu, tearoff), 0, NULL, 0}, {TK_OPTION_STRING, "-tearoffcommand", "tearOffCommand", "TearOffCommand", DEF_MENU_TEAROFF_CMD, - Tk_Offset(TkMenu, tearoffCommandPtr), -1, TK_OPTION_NULL_OK}, + Tk_Offset(TkMenu, tearoffCommandPtr), -1, TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_STRING, "-title", "title", "Title", DEF_MENU_TITLE, Tk_Offset(TkMenu, titlePtr), -1, - TK_OPTION_NULL_OK}, + TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_STRING_TABLE, "-type", "type", "Type", DEF_MENU_TYPE, Tk_Offset(TkMenu, menuTypePtr), -1, TK_OPTION_NULL_OK, - (ClientData) menuTypeStrings}, - {TK_OPTION_END} + (ClientData) menuTypeStrings, 0}, + {TK_OPTION_END, NULL, NULL, NULL, 0, 0, 0, 0, NULL, 0} }; /* @@ -308,7 +312,7 @@ static const Tk_OptionSpec tkMenuConfigSpecs[] = { * with MenuWidgetObjCmd. */ -static const char *menuOptions[] = { +static const char *const menuOptions[] = { "activate", "add", "cget", "clone", "configure", "delete", "entrycget", "entryconfigure", "index", "insert", "invoke", "post", "postcascade", "type", "unpost", "xposition", "yposition", NULL @@ -338,9 +342,10 @@ static void DeleteMenuCloneEntries(TkMenu *menuPtr, static void DestroyMenuHashTable(ClientData clientData, Tcl_Interp *interp); static void DestroyMenuInstance(TkMenu *menuPtr); -static void DestroyMenuEntry(char *memPtr); -static int GetIndexFromCoords(Tcl_Interp *interp, TkMenu *menuPtr, - char *string, int *indexPtr); +static void DestroyMenuEntry(void *memPtr); +static int GetIndexFromCoords(Tcl_Interp *interp, + TkMenu *menuPtr, const char *string, + int *indexPtr); static int MenuDoYPosition(Tcl_Interp *interp, TkMenu *menuPtr, Tcl_Obj *objPtr); static int MenuDoXPosition(Tcl_Interp *interp, @@ -348,8 +353,6 @@ static int MenuDoXPosition(Tcl_Interp *interp, static int MenuAddOrInsert(Tcl_Interp *interp, TkMenu *menuPtr, Tcl_Obj *indexPtr, int objc, Tcl_Obj *const objv[]); -static int MenuCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]); static void MenuCmdDeletedProc(ClientData clientData); static TkMenuEntry * MenuNewEntry(TkMenu *menuPtr, int index, int type); static char * MenuVarProc(ClientData clientData, @@ -370,72 +373,17 @@ static void TkMenuCleanup(ClientData unused); * geometry proc to be called. */ -static Tk_ClassProcs menuClass = { +static const Tk_ClassProcs menuClass = { sizeof(Tk_ClassProcs), /* size */ - MenuWorldChanged /* worldChangedProc */ + MenuWorldChanged, /* worldChangedProc */ + NULL, /* createProc */ + NULL /* modalProc */ }; /* *-------------------------------------------------------------- * - * TkCreateMenuCmd -- - * - * Called by Tk at initialization time to create the menu command. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *-------------------------------------------------------------- - */ - -static void -FreeOptionTables( - ClientData clientData, - Tcl_Interp *interp) -{ - ckfree(clientData); -} - -int -TkCreateMenuCmd( - Tcl_Interp *interp) /* Interpreter we are creating the command - * in. */ -{ - TkMenuOptionTables *optionTablesPtr = - (TkMenuOptionTables *) ckalloc(sizeof(TkMenuOptionTables)); - - optionTablesPtr->menuOptionTable = - Tk_CreateOptionTable(interp, tkMenuConfigSpecs); - optionTablesPtr->entryOptionTables[TEAROFF_ENTRY] = - Tk_CreateOptionTable(interp, specsArray[TEAROFF_ENTRY]); - optionTablesPtr->entryOptionTables[COMMAND_ENTRY] = - Tk_CreateOptionTable(interp, specsArray[COMMAND_ENTRY]); - optionTablesPtr->entryOptionTables[CASCADE_ENTRY] = - Tk_CreateOptionTable(interp, specsArray[CASCADE_ENTRY]); - optionTablesPtr->entryOptionTables[SEPARATOR_ENTRY] = - Tk_CreateOptionTable(interp, specsArray[SEPARATOR_ENTRY]); - optionTablesPtr->entryOptionTables[RADIO_BUTTON_ENTRY] = - Tk_CreateOptionTable(interp, specsArray[RADIO_BUTTON_ENTRY]); - optionTablesPtr->entryOptionTables[CHECK_BUTTON_ENTRY] = - Tk_CreateOptionTable(interp, specsArray[CHECK_BUTTON_ENTRY]); - - Tcl_CreateObjCommand(interp, "menu", MenuCmd, optionTablesPtr, 0); - Tcl_CallWhenDeleted(interp, FreeOptionTables, optionTablesPtr); - - if (Tcl_IsSafe(interp)) { - Tcl_HideCommand(interp, "menu", "menu"); - } - - return TCL_OK; -} - -/* - *-------------------------------------------------------------- - * - * MenuCmd -- + * Tk_MenuObjCmd -- * * This function is invoked to process the "menu" Tcl command. See the * user documentation for details on what it does. @@ -449,24 +397,25 @@ TkCreateMenuCmd( *-------------------------------------------------------------- */ -static int -MenuCmd( +int +Tk_MenuObjCmd( ClientData clientData, /* Main window associated with interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument strings. */ { - Tk_Window tkwin = Tk_MainWindow(interp); + Tk_Window tkwin = clientData; Tk_Window newWin; register TkMenu *menuPtr; TkMenuReferences *menuRefPtr; int i, index, toplevel; - char *windowName; - static const char *typeStringList[] = {"-type", NULL}; - TkMenuOptionTables *optionTablesPtr = (TkMenuOptionTables *) clientData; + const char *windowName; + static const char *const typeStringList[] = {"-type", NULL}; + ThreadSpecificData *tsdPtr = + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?"); + Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?"); return TCL_ERROR; } @@ -474,10 +423,10 @@ MenuCmd( toplevel = 1; for (i = 2; i < (objc - 1); i++) { - if (Tcl_GetIndexFromObj(NULL, objv[i], typeStringList, NULL, 0, &index) - != TCL_ERROR) { - if ((Tcl_GetIndexFromObj(NULL, objv[i + 1], menuTypeStrings, NULL, - 0, &index) == TCL_OK) && (index == MENUBAR)) { + if (Tcl_GetIndexFromObjStruct(NULL, objv[i], typeStringList, + sizeof(char *), NULL, 0, &index) != TCL_ERROR) { + if ((Tcl_GetIndexFromObjStruct(NULL, objv[i + 1], menuTypeStrings, + sizeof(char *), NULL, 0, &index) == TCL_OK) && (index == MENUBAR)) { toplevel = 0; } break; @@ -497,28 +446,27 @@ MenuCmd( * Tcl_EventuallyFree is called. */ - menuPtr = (TkMenu *) ckalloc(sizeof(TkMenu)); + menuPtr = ckalloc(sizeof(TkMenu)); memset(menuPtr, 0, sizeof(TkMenu)); menuPtr->tkwin = newWin; menuPtr->display = Tk_Display(newWin); menuPtr->interp = interp; menuPtr->widgetCmd = Tcl_CreateObjCommand(interp, - Tk_PathName(menuPtr->tkwin), MenuWidgetObjCmd, - (ClientData) menuPtr, MenuCmdDeletedProc); + Tk_PathName(menuPtr->tkwin), MenuWidgetObjCmd, menuPtr, + MenuCmdDeletedProc); menuPtr->active = -1; menuPtr->cursorPtr = NULL; menuPtr->masterMenuPtr = menuPtr; menuPtr->menuType = UNKNOWN_TYPE; - menuPtr->optionTablesPtr = optionTablesPtr; TkMenuInitializeDrawingFields(menuPtr); Tk_SetClass(menuPtr->tkwin, "Menu"); - Tk_SetClassProcs(menuPtr->tkwin, &menuClass, (ClientData) menuPtr); + Tk_SetClassProcs(menuPtr->tkwin, &menuClass, menuPtr); Tk_CreateEventHandler(newWin, ExposureMask|StructureNotifyMask|ActivateMask, - TkMenuEventProc, (ClientData) menuPtr); + TkMenuEventProc, menuPtr); if (Tk_InitOptions(interp, (char *) menuPtr, - menuPtr->optionTablesPtr->menuOptionTable, menuPtr->tkwin) + tsdPtr->menuOptionTable, menuPtr->tkwin) != TCL_OK) { Tk_DestroyWindow(menuPtr->tkwin); return TCL_ERROR; @@ -578,7 +526,7 @@ MenuCmd( && ((cascadeListPtr->menuPtr->masterMenuPtr == cascadeListPtr->menuPtr)))) { newObjv[0] = Tcl_NewStringObj("-menu", -1); - newObjv[1] = Tcl_NewStringObj(Tk_PathName(menuPtr->tkwin), -1); + newObjv[1] = Tcl_NewStringObj(Tk_PathName(menuPtr->tkwin),-1); Tcl_IncrRefCount(newObjv[0]); Tcl_IncrRefCount(newObjv[1]); ConfigureMenuEntry(cascadeListPtr, 2, newObjv); @@ -640,7 +588,7 @@ MenuCmd( } } - Tcl_SetResult(interp, Tk_PathName(menuPtr->tkwin), TCL_STATIC); + Tcl_SetObjResult(interp, TkNewWindowObj(menuPtr->tkwin)); return TCL_OK; } @@ -669,20 +617,22 @@ MenuWidgetObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument strings. */ { - register TkMenu *menuPtr = (TkMenu *) clientData; + register TkMenu *menuPtr = clientData; register TkMenuEntry *mePtr; int result = TCL_OK; int option; + ThreadSpecificData *tsdPtr = + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?"); + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); return TCL_ERROR; } - if (Tcl_GetIndexFromObj(interp, objv[1], menuOptions, "option", 0, - &option) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[1], menuOptions, + sizeof(char *), "option", 0, &option) != TCL_OK) { return TCL_ERROR; } - Tcl_Preserve((ClientData) menuPtr); + Tcl_Preserve(menuPtr); switch ((enum options) option) { case MENU_ACTIVATE: { @@ -707,11 +657,11 @@ MenuWidgetObjCmd( } case MENU_ADD: if (objc < 3) { - Tcl_WrongNumArgs(interp, 2, objv, "type ?options?"); + Tcl_WrongNumArgs(interp, 2, objv, "type ?-option value ...?"); goto error; } - if (MenuAddOrInsert(interp, menuPtr, NULL, objc-2, objv+2) != TCL_OK) { + if (MenuAddOrInsert(interp, menuPtr, NULL, objc-2, objv+2) != TCL_OK){ goto error; } break; @@ -723,7 +673,7 @@ MenuWidgetObjCmd( goto error; } resultPtr = Tk_GetOptionValue(interp, (char *) menuPtr, - menuPtr->optionTablesPtr->menuOptionTable, objv[2], + tsdPtr->menuOptionTable, objv[2], menuPtr->tkwin); if (resultPtr == NULL) { goto error; @@ -743,7 +693,7 @@ MenuWidgetObjCmd( if (objc == 2) { resultPtr = Tk_GetOptionInfo(interp, (char *) menuPtr, - menuPtr->optionTablesPtr->menuOptionTable, NULL, + tsdPtr->menuOptionTable, NULL, menuPtr->tkwin); if (resultPtr == NULL) { result = TCL_ERROR; @@ -753,7 +703,7 @@ MenuWidgetObjCmd( } } else if (objc == 3) { resultPtr = Tk_GetOptionInfo(interp, (char *) menuPtr, - menuPtr->optionTablesPtr->menuOptionTable, objv[2], + tsdPtr->menuOptionTable, objv[2], menuPtr->tkwin); if (resultPtr == NULL) { result = TCL_ERROR; @@ -825,10 +775,10 @@ MenuWidgetObjCmd( goto done; } mePtr = menuPtr->entries[index]; - Tcl_Preserve((ClientData) mePtr); + Tcl_Preserve(mePtr); resultPtr = Tk_GetOptionValue(interp, (char *) mePtr, mePtr->optionTable, objv[3], menuPtr->tkwin); - Tcl_Release((ClientData) mePtr); + Tcl_Release(mePtr); if (resultPtr == NULL) { goto error; } @@ -840,7 +790,7 @@ MenuWidgetObjCmd( Tcl_Obj *resultPtr; if (objc < 3) { - Tcl_WrongNumArgs(interp, 2, objv, "index ?option value ...?"); + Tcl_WrongNumArgs(interp, 2, objv, "index ?-option value ...?"); goto error; } if (TkGetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) { @@ -850,7 +800,7 @@ MenuWidgetObjCmd( goto done; } mePtr = menuPtr->entries[index]; - Tcl_Preserve((ClientData) mePtr); + Tcl_Preserve(mePtr); if (objc == 3) { resultPtr = Tk_GetOptionInfo(interp, (char *) mePtr, mePtr->optionTable, NULL, menuPtr->tkwin); @@ -873,7 +823,7 @@ MenuWidgetObjCmd( result = ConfigureMenuCloneEntries(interp, menuPtr, index, objc-3, objv+3); } - Tcl_Release((ClientData) mePtr); + Tcl_Release(mePtr); break; } case MENU_INDEX: { @@ -887,15 +837,16 @@ MenuWidgetObjCmd( goto error; } if (index < 0) { - Tcl_SetResult(interp, "none", TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj("none", -1)); } else { - Tcl_SetIntObj(Tcl_GetObjResult(interp), index); + Tcl_SetObjResult(interp, Tcl_NewIntObj(index)); } break; } case MENU_INSERT: if (objc < 4) { - Tcl_WrongNumArgs(interp, 2, objv, "index type ?options?"); + Tcl_WrongNumArgs(interp, 2, objv, + "index type ?-option value ...?"); goto error; } if (MenuAddOrInsert(interp,menuPtr,objv[2],objc-3,objv+3) != TCL_OK) { @@ -919,32 +870,37 @@ MenuWidgetObjCmd( break; } case MENU_POST: { - int x, y; + int x, y, index = -1; - if (objc != 4) { - Tcl_WrongNumArgs(interp, 2, objv, "x y"); + if (objc != 4 && objc != 5) { + Tcl_WrongNumArgs(interp, 2, objv, "x y ?index?"); goto error; } if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) { goto error; } + if (objc == 5) { + if (TkGetMenuIndex(interp, menuPtr, objv[4], 0, &index) != TCL_OK) { + goto error; + } + } /* - * Tearoff menus are posted differently on Mac and Windows than - * non-tearoffs. TkpPostMenu does not actually map the menu's window - * on those platforms, and popup menus have to be handled specially. - * Also, menubar menues are not intended to be posted (bug 1567681, - * 2160206). + * Tearoff menus are the same as ordinary menus on the Mac and are + * posted differently on Windows than non-tearoffs. TkpPostMenu + * does not actually map the menu's window on those platforms, and + * popup menus have to be handled specially. Also, menubar menus are + * not intended to be posted (bug 1567681, 2160206). */ if (menuPtr->menuType == MENUBAR) { Tcl_AppendResult(interp, "a menubar menu cannot be posted", NULL); return TCL_ERROR; } else if (menuPtr->menuType != TEAROFF_MENU) { - result = TkpPostMenu(interp, menuPtr, x, y); + result = TkpPostMenu(interp, menuPtr, x, y, index); } else { - result = TkPostTearoffMenu(interp, menuPtr, x, y); + result = TkpPostTearoffMenu(interp, menuPtr, x, y, index); } break; } @@ -968,6 +924,7 @@ MenuWidgetObjCmd( } case MENU_TYPE: { int index; + const char *typeStr; if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "index"); @@ -980,11 +937,11 @@ MenuWidgetObjCmd( goto done; } if (menuPtr->entries[index]->type == TEAROFF_ENTRY) { - Tcl_SetResult(interp, "tearoff", TCL_STATIC); + typeStr = "tearoff"; } else { - Tcl_SetStringObj(Tcl_GetObjResult(interp), - menuEntryTypeStrings[menuPtr->entries[index]->type], -1); + typeStr = menuEntryTypeStrings[menuPtr->entries[index]->type]; } + Tcl_SetObjResult(interp, Tcl_NewStringObj(typeStr, -1)); break; } case MENU_UNPOST: @@ -1011,11 +968,11 @@ MenuWidgetObjCmd( break; } done: - Tcl_Release((ClientData) menuPtr); + Tcl_Release(menuPtr); return result; error: - Tcl_Release((ClientData) menuPtr); + Tcl_Release(menuPtr); return TCL_ERROR; } @@ -1054,13 +1011,15 @@ TkInvokeMenu( if (mePtr->state == ENTRY_DISABLED) { goto done; } - Tcl_Preserve((ClientData) mePtr); + + Tcl_Preserve(mePtr); if (mePtr->type == TEAROFF_ENTRY) { Tcl_DString ds; + Tcl_DStringInit(&ds); Tcl_DStringAppend(&ds, "tk::TearOffMenu ", -1); Tcl_DStringAppend(&ds, Tk_PathName(menuPtr->tkwin), -1); - result = Tcl_Eval(interp, Tcl_DStringValue(&ds)); + result = Tcl_EvalEx(interp, Tcl_DStringValue(&ds), -1, 0); Tcl_DStringFree(&ds); } else if ((mePtr->type == CHECK_BUTTON_ENTRY) && (mePtr->namePtr != NULL)) { @@ -1109,7 +1068,8 @@ TkInvokeMenu( result = Tcl_EvalObjEx(interp, commandPtr, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(commandPtr); } - Tcl_Release((ClientData) mePtr); + Tcl_Release(mePtr); + done: return result; } @@ -1142,6 +1102,8 @@ DestroyMenuInstance( Tcl_Obj *newObjv[2]; TkMenu *parentMasterMenuPtr; TkMenuEntry *parentMasterEntryPtr; + ThreadSpecificData *tsdPtr = + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* * If the menu has any cascade menu entries pointing to it, the cascade @@ -1207,7 +1169,7 @@ DestroyMenuInstance( } } } else if (menuPtr->nextInstancePtr != NULL) { - Tcl_Panic("Attempting to delete master menu when there are still clones."); + Tcl_Panic("Attempting to delete master menu when there are still clones"); } /* @@ -1223,17 +1185,18 @@ DestroyMenuInstance( * for menu entries (i+1)...numEntries. */ - DestroyMenuEntry((char *) menuPtr->entries[i]); + DestroyMenuEntry(menuPtr->entries[i]); menuPtr->numEntries = i; } if (menuPtr->entries != NULL) { - ckfree((char *) menuPtr->entries); + ckfree(menuPtr->entries); } TkMenuFreeDrawOptions(menuPtr); Tk_FreeConfigOptions((char *) menuPtr, - menuPtr->optionTablesPtr->menuOptionTable, menuPtr->tkwin); + tsdPtr->menuOptionTable, menuPtr->tkwin); if (menuPtr->tkwin != NULL) { Tk_Window tkwin = menuPtr->tkwin; + menuPtr->tkwin = NULL; Tk_DestroyWindow(tkwin); } @@ -1420,9 +1383,9 @@ UnhookCascadeEntry( static void DestroyMenuEntry( - char *memPtr) /* Pointer to entry to be freed. */ + void *memPtr) /* Pointer to entry to be freed. */ { - register TkMenuEntry *mePtr = (TkMenuEntry *) memPtr; + register TkMenuEntry *mePtr = memPtr; TkMenu *menuPtr = mePtr->menuPtr; if (menuPtr->postedCascade == mePtr) { @@ -1443,13 +1406,13 @@ DestroyMenuEntry( if (mePtr->type == CASCADE_ENTRY) { if (menuPtr->masterMenuPtr != menuPtr) { TkMenu *destroyThis = NULL; + TkMenuReferences *menuRefPtr = mePtr->childMenuRefPtr; + /* * The menu as a whole is a clone. We must delete the clone of the * cascaded menu for the particular entry we are destroying. */ - TkMenuReferences *menuRefPtr = mePtr->childMenuRefPtr; - if (menuRefPtr != NULL) { destroyThis = menuRefPtr->menuPtr; @@ -1488,16 +1451,16 @@ DestroyMenuEntry( if (((mePtr->type == CHECK_BUTTON_ENTRY) || (mePtr->type == RADIO_BUTTON_ENTRY)) && (mePtr->namePtr != NULL)) { - char *varName = Tcl_GetString(mePtr->namePtr); + const char *varName = Tcl_GetString(mePtr->namePtr); - Tcl_UntraceVar(menuPtr->interp, varName, + Tcl_UntraceVar2(menuPtr->interp, varName, NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - MenuVarProc, (ClientData) mePtr); + MenuVarProc, mePtr); } TkpDestroyMenuEntry(mePtr); TkMenuEntryFreeDrawOptions(mePtr); Tk_FreeConfigOptions((char *) mePtr, mePtr->optionTable, menuPtr->tkwin); - ckfree((char *) mePtr); + ckfree(mePtr); } /* @@ -1522,7 +1485,7 @@ static void MenuWorldChanged( ClientData instanceData) /* Information about widget. */ { - TkMenu *menuPtr = (TkMenu *) instanceData; + TkMenu *menuPtr = instanceData; int i; TkMenuConfigureDrawOptions(menuPtr); @@ -1564,25 +1527,26 @@ ConfigureMenu( int i; TkMenu *menuListPtr, *cleanupPtr; int result; + ThreadSpecificData *tsdPtr = + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); for (menuListPtr = menuPtr->masterMenuPtr; menuListPtr != NULL; menuListPtr = menuListPtr->nextInstancePtr) { - menuListPtr->errorStructPtr = (Tk_SavedOptions *) - ckalloc(sizeof(Tk_SavedOptions)); + menuListPtr->errorStructPtr = ckalloc(sizeof(Tk_SavedOptions)); result = Tk_SetOptions(interp, (char *) menuListPtr, - menuListPtr->optionTablesPtr->menuOptionTable, objc, objv, + tsdPtr->menuOptionTable, objc, objv, menuListPtr->tkwin, menuListPtr->errorStructPtr, NULL); if (result != TCL_OK) { for (cleanupPtr = menuPtr->masterMenuPtr; cleanupPtr != menuListPtr; cleanupPtr = cleanupPtr->nextInstancePtr) { Tk_RestoreSavedOptions(cleanupPtr->errorStructPtr); - ckfree((char *) cleanupPtr->errorStructPtr); + ckfree(cleanupPtr->errorStructPtr); cleanupPtr->errorStructPtr = NULL; } if (menuListPtr->errorStructPtr != NULL) { Tk_RestoreSavedOptions(menuListPtr->errorStructPtr); - ckfree((char *) menuListPtr->errorStructPtr); + ckfree(menuListPtr->errorStructPtr); menuListPtr->errorStructPtr = NULL; } return TCL_ERROR; @@ -1596,8 +1560,8 @@ ConfigureMenu( */ if (menuListPtr->menuType == UNKNOWN_TYPE) { - Tcl_GetIndexFromObj(NULL, menuListPtr->menuTypePtr, - menuTypeStrings, NULL, 0, &menuListPtr->menuType); + Tcl_GetIndexFromObjStruct(NULL, menuListPtr->menuTypePtr, + menuTypeStrings, sizeof(char *), NULL, 0, &menuListPtr->menuType); /* * Configure the new window to be either a pop-up menu or a @@ -1608,13 +1572,31 @@ ConfigureMenu( */ if (menuListPtr->menuType == MASTER_MENU) { - TkpMakeMenuWindow(menuListPtr->tkwin, 1); + int typeFlag = TK_MAKE_MENU_POPUP; + Tk_Window tkwin = menuPtr->tkwin; + + /* + * Work out if we are the child of a menubar or a popup. + */ + + while (1) { + Tk_Window parent = Tk_Parent(tkwin); + + if (Tk_Class(parent) != Tk_Class(menuPtr->tkwin)) { + break; + } + tkwin = parent; + } + if (((TkMenu *) tkwin)->menuType == MENUBAR) { + typeFlag = TK_MAKE_MENU_DROPDOWN; + } + + TkpMakeMenuWindow(menuListPtr->tkwin, typeFlag); } else if (menuListPtr->menuType == TEAROFF_MENU) { - TkpMakeMenuWindow(menuListPtr->tkwin, 0); + TkpMakeMenuWindow(menuListPtr->tkwin, TK_MAKE_MENU_TEAROFF); } } - /* * Depending on the -tearOff option, make sure that there is or isn't * an initial tear-off entry at the beginning of the menu. @@ -1625,15 +1607,15 @@ ConfigureMenu( || (menuListPtr->entries[0]->type != TEAROFF_ENTRY)) { if (MenuNewEntry(menuListPtr, 0, TEAROFF_ENTRY) == NULL) { for (cleanupPtr = menuPtr->masterMenuPtr; - cleanupPtr != menuListPtr; - cleanupPtr = cleanupPtr->nextInstancePtr) { + cleanupPtr != menuListPtr; + cleanupPtr = cleanupPtr->nextInstancePtr) { Tk_RestoreSavedOptions(cleanupPtr->errorStructPtr); - ckfree((char *) cleanupPtr->errorStructPtr); + ckfree(cleanupPtr->errorStructPtr); cleanupPtr->errorStructPtr = NULL; } if (menuListPtr->errorStructPtr != NULL) { Tk_RestoreSavedOptions(menuListPtr->errorStructPtr); - ckfree((char *) menuListPtr->errorStructPtr); + ckfree(menuListPtr->errorStructPtr); menuListPtr->errorStructPtr = NULL; } return TCL_ERROR; @@ -1643,8 +1625,7 @@ ConfigureMenu( && (menuListPtr->entries[0]->type == TEAROFF_ENTRY)) { int i; - Tcl_EventuallyFree((ClientData) menuListPtr->entries[0], - DestroyMenuEntry); + Tcl_EventuallyFree(menuListPtr->entries[0], (Tcl_FreeProc *) DestroyMenuEntry); for (i = 0; i < menuListPtr->numEntries - 1; i++) { menuListPtr->entries[i] = menuListPtr->entries[i + 1]; @@ -1652,7 +1633,7 @@ ConfigureMenu( } menuListPtr->numEntries--; if (menuListPtr->numEntries == 0) { - ckfree((char *) menuListPtr->entries); + ckfree(menuListPtr->entries); menuListPtr->entries = NULL; } } @@ -1679,7 +1660,7 @@ ConfigureMenu( for (cleanupPtr = menuPtr->masterMenuPtr; cleanupPtr != NULL; cleanupPtr = cleanupPtr->nextInstancePtr) { Tk_FreeSavedOptions(cleanupPtr->errorStructPtr); - ckfree((char *) cleanupPtr->errorStructPtr); + ckfree(cleanupPtr->errorStructPtr); cleanupPtr->errorStructPtr = NULL; } @@ -1712,7 +1693,7 @@ PostProcessEntry( { TkMenu *menuPtr = mePtr->menuPtr; int index = mePtr->index; - char *name; + const char *name; Tk_Image image; /* @@ -1805,10 +1786,10 @@ PostProcessEntry( */ if (mePtr->imagePtr != NULL) { - char *imageString = Tcl_GetString(mePtr->imagePtr); + const char *imageString = Tcl_GetString(mePtr->imagePtr); image = Tk_GetImage(menuPtr->interp, menuPtr->tkwin, imageString, - TkMenuImageProc, (ClientData) mePtr); + TkMenuImageProc, mePtr); if (image == NULL) { return TCL_ERROR; } @@ -1820,10 +1801,10 @@ PostProcessEntry( } mePtr->image = image; if (mePtr->selectImagePtr != NULL) { - char *selectImageString = Tcl_GetString(mePtr->selectImagePtr); + const char *selectImageString = Tcl_GetString(mePtr->selectImagePtr); image = Tk_GetImage(menuPtr->interp, menuPtr->tkwin, selectImageString, - TkMenuSelectImageProc, (ClientData) mePtr); + TkMenuSelectImageProc, mePtr); if (image == NULL) { return TCL_ERROR; } @@ -1838,7 +1819,7 @@ PostProcessEntry( if ((mePtr->type == CHECK_BUTTON_ENTRY) || (mePtr->type == RADIO_BUTTON_ENTRY)) { Tcl_Obj *valuePtr; - char *name; + const char *name; if (mePtr->namePtr == NULL) { if (mePtr->labelPtr == NULL) { @@ -1872,8 +1853,8 @@ PostProcessEntry( mePtr->entryFlags &= ~ENTRY_SELECTED; if (valuePtr != NULL) { if (mePtr->onValuePtr != NULL) { - char *value = Tcl_GetString(valuePtr); - char *onValue = Tcl_GetString(mePtr->onValuePtr); + const char *value = Tcl_GetString(valuePtr); + const char *onValue = Tcl_GetString(mePtr->onValuePtr); if (strcmp(value, onValue) == 0) { mePtr->entryFlags |= ENTRY_SELECTED; @@ -1888,9 +1869,9 @@ PostProcessEntry( } if (mePtr->namePtr != NULL) { name = Tcl_GetString(mePtr->namePtr); - Tcl_TraceVar(menuPtr->interp, name, - TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - MenuVarProc, (ClientData) mePtr); + Tcl_TraceVar2(menuPtr->interp, name, + NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + MenuVarProc, mePtr); } } @@ -1939,11 +1920,11 @@ ConfigureMenuEntry( if ((mePtr->namePtr != NULL) && ((mePtr->type == CHECK_BUTTON_ENTRY) || (mePtr->type == RADIO_BUTTON_ENTRY))) { - char *name = Tcl_GetString(mePtr->namePtr); + const char *name = Tcl_GetString(mePtr->namePtr); - Tcl_UntraceVar(menuPtr->interp, name, + Tcl_UntraceVar2(menuPtr->interp, name, NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - MenuVarProc, (ClientData) mePtr); + MenuVarProc, mePtr); } result = TCL_OK; @@ -1997,7 +1978,7 @@ ConfigureMenuCloneEntries( int cascadeEntryChanged = 0; TkMenuReferences *oldCascadeMenuRefPtr, *cascadeMenuRefPtr = NULL; Tcl_Obj *oldCascadePtr = NULL; - char *newCascadeName; + const char *newCascadeName; /* * Cascades are kind of tricky here. This is special case #3 in the @@ -2021,7 +2002,7 @@ ConfigureMenuCloneEntries( } if (mePtr->type == CASCADE_ENTRY) { - char *oldCascadeName; + const char *oldCascadeName; if (mePtr->namePtr != NULL) { newCascadeName = Tcl_GetString(mePtr->namePtr); @@ -2074,7 +2055,7 @@ ConfigureMenuCloneEntries( } if (cascadeEntryChanged && (mePtr->namePtr != NULL)) { - if (cascadeMenuRefPtr->menuPtr != NULL) { + if (cascadeMenuRefPtr && cascadeMenuRefPtr->menuPtr != NULL) { Tcl_Obj *newObjv[2]; Tcl_Obj *newCloneNamePtr; Tcl_Obj *pathNamePtr = Tcl_NewStringObj( @@ -2137,7 +2118,7 @@ TkGetMenuIndex( int *indexPtr) /* Where to store converted index. */ { int i; - char *string = Tcl_GetString(objPtr); + const char *string = Tcl_GetString(objPtr); if ((string[0] == 'a') && (strcmp(string, "active") == 0)) { *indexPtr = menuPtr->active; @@ -2176,12 +2157,12 @@ TkGetMenuIndex( *indexPtr = i; goto success; } - Tcl_SetResult(interp, NULL, TCL_STATIC); + Tcl_ResetResult(interp); } for (i = 0; i < menuPtr->numEntries; i++) { Tcl_Obj *labelPtr = menuPtr->entries[i]->labelPtr; - char *label = (labelPtr == NULL) ? NULL : Tcl_GetString(labelPtr); + const char *label = (labelPtr == NULL) ? NULL : Tcl_GetString(labelPtr); if ((label != NULL) && (Tcl_StringMatch(label, string))) { *indexPtr = i; @@ -2189,7 +2170,9 @@ TkGetMenuIndex( } } - Tcl_AppendResult(interp, "bad menu entry index \"", string, "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad menu entry index \"%s\"", string)); + Tcl_SetErrorCode(interp, "TK", "MENU", "INDEX", NULL); return TCL_ERROR; success: @@ -2218,7 +2201,7 @@ static void MenuCmdDeletedProc( ClientData clientData) /* Pointer to widget record for widget. */ { - TkMenu *menuPtr = (TkMenu *) clientData; + TkMenu *menuPtr = clientData; Tk_Window tkwin = menuPtr->tkwin; /* @@ -2267,13 +2250,14 @@ MenuNewEntry( TkMenuEntry *mePtr; TkMenuEntry **newEntries; int i; + ThreadSpecificData *tsdPtr = + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* * Create a new array of entries with an empty slot for the new entry. */ - newEntries = (TkMenuEntry **) ckalloc((unsigned) - ((menuPtr->numEntries+1)*sizeof(TkMenuEntry *))); + newEntries = ckalloc((menuPtr->numEntries+1) * sizeof(TkMenuEntry *)); for (i = 0; i < index; i++) { newEntries[i] = menuPtr->entries[i]; } @@ -2282,14 +2266,14 @@ MenuNewEntry( newEntries[i+1]->index = i + 1; } if (menuPtr->numEntries != 0) { - ckfree((char *) menuPtr->entries); + ckfree(menuPtr->entries); } menuPtr->entries = newEntries; menuPtr->numEntries++; - mePtr = (TkMenuEntry *) ckalloc(sizeof(TkMenuEntry)); + mePtr = ckalloc(sizeof(TkMenuEntry)); menuPtr->entries[index] = mePtr; mePtr->type = type; - mePtr->optionTable = menuPtr->optionTablesPtr->entryOptionTables[type]; + mePtr->optionTable = tsdPtr->entryOptionTables[type]; mePtr->menuPtr = menuPtr; mePtr->labelPtr = NULL; mePtr->labelLength = 0; @@ -2321,14 +2305,14 @@ MenuNewEntry( mePtr->nextCascadePtr = NULL; if (Tk_InitOptions(menuPtr->interp, (char *) mePtr, mePtr->optionTable, menuPtr->tkwin) != TCL_OK) { - ckfree((char *) mePtr); + ckfree(mePtr); return NULL; } TkMenuInitializeEntryDrawingFields(mePtr); if (TkpMenuNewEntry(mePtr) != TCL_OK) { Tk_FreeConfigOptions((char *) mePtr, mePtr->optionTable, menuPtr->tkwin); - ckfree((char *) mePtr); + ckfree(mePtr); return NULL; } @@ -2374,8 +2358,9 @@ MenuAddOrInsert( index = menuPtr->numEntries; } if (index < 0) { - char *indexString = Tcl_GetString(indexPtr); - Tcl_AppendResult(interp, "bad index \"", indexString, "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad index \"%s\"", Tcl_GetString(indexPtr))); + Tcl_SetErrorCode(interp, "TK", "MENU", "INDEX", NULL); return TCL_ERROR; } if (menuPtr->tearoff && (index == 0)) { @@ -2386,8 +2371,8 @@ MenuAddOrInsert( * Figure out the type of the new entry. */ - if (Tcl_GetIndexFromObj(interp, objv[0], menuEntryTypeStrings, - "menu entry type", 0, &type) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[0], menuEntryTypeStrings, + sizeof(char *), "menu entry type", 0, &type) != TCL_OK) { return TCL_ERROR; } @@ -2409,15 +2394,15 @@ MenuAddOrInsert( for (errorMenuPtr = menuPtr->masterMenuPtr; errorMenuPtr != NULL; errorMenuPtr = errorMenuPtr->nextInstancePtr) { - Tcl_EventuallyFree((ClientData) errorMenuPtr->entries[index], - DestroyMenuEntry); + Tcl_EventuallyFree(errorMenuPtr->entries[index], + (Tcl_FreeProc *) DestroyMenuEntry); for (i = index; i < errorMenuPtr->numEntries - 1; i++) { errorMenuPtr->entries[i] = errorMenuPtr->entries[i + 1]; errorMenuPtr->entries[i]->index = i; } errorMenuPtr->numEntries--; if (errorMenuPtr->numEntries == 0) { - ckfree((char *) errorMenuPtr->entries); + ckfree(errorMenuPtr->entries); errorMenuPtr->entries = NULL; } if (errorMenuPtr == menuListPtr) { @@ -2458,7 +2443,7 @@ MenuAddOrInsert( menuRefPtr = TkFindMenuReferencesObj(menuListPtr->interp, newCascadePtr); if (menuRefPtr == NULL) { - Tcl_Panic("CloneMenu failed inside of MenuAddOrInsert."); + Tcl_Panic("CloneMenu failed inside of MenuAddOrInsert"); } newObjv[0] = menuNamePtr; newObjv[1] = newCascadePtr; @@ -2501,21 +2486,26 @@ MenuVarProc( const char *name2, /* Second part of variable's name. */ int flags) /* Describes what just happened. */ { - TkMenuEntry *mePtr = (TkMenuEntry *) clientData; + TkMenuEntry *mePtr = clientData; TkMenu *menuPtr; const char *value; - char *name; - char *onValue; + const char *name, *onValue; - if (flags & TCL_INTERP_DESTROYED) { + if (Tcl_InterpDeleted(interp) || (mePtr->namePtr == NULL)) { /* - * Do nothing if the interpreter is going away. + * Do nothing if the interpreter is going away or we have + * no variable name. */ return NULL; } menuPtr = mePtr->menuPtr; + + if (menuPtr->menuFlags & MENU_DELETION_PENDING) { + return NULL; + } + name = Tcl_GetString(mePtr->namePtr); /* @@ -2523,12 +2513,29 @@ MenuVarProc( */ if (flags & TCL_TRACE_UNSETS) { + ClientData probe = NULL; mePtr->entryFlags &= ~ENTRY_SELECTED; - if (flags & TCL_TRACE_DESTROYED) { - Tcl_TraceVar(interp, name, - TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - MenuVarProc, clientData); - } + + do { + probe = Tcl_VarTraceInfo(interp, name, + TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + MenuVarProc, probe); + if (probe == (ClientData)mePtr) { + break; + } + } while (probe); + if (probe) { + /* + * We were able to fetch the unset trace for our + * namePtr, which means it is not unset and not + * the cause of this unset trace. Instead some outdated + * former variable must be, and we should ignore it. + */ + return NULL; + } + Tcl_TraceVar2(interp, name, NULL, + TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + MenuVarProc, clientData); TkpConfigureMenuEntry(mePtr); TkEventuallyRedrawMenu(menuPtr, NULL); return NULL; @@ -2539,7 +2546,7 @@ MenuVarProc( * entry. */ - value = Tcl_GetVar(interp, name, TCL_GLOBAL_ONLY); + value = Tcl_GetVar2(interp, name, NULL, TCL_GLOBAL_ONLY); if (value == NULL) { value = ""; } @@ -2692,8 +2699,8 @@ CloneMenu( if (newMenuTypePtr == NULL) { menuType = MASTER_MENU; } else { - if (Tcl_GetIndexFromObj(menuPtr->interp, newMenuTypePtr, - menuTypeStrings, "menu type", 0, &menuType) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(menuPtr->interp, newMenuTypePtr, + menuTypeStrings, sizeof(char *), "menu type", 0, &menuType) != TCL_OK) { return TCL_ERROR; } } @@ -2709,7 +2716,7 @@ CloneMenu( for (i = 0; i < 4; i++) { Tcl_IncrRefCount(menuDupCommandArray[i]); } - Tcl_Preserve((ClientData) menuPtr); + Tcl_Preserve(menuPtr); returnResult = Tcl_EvalObjv(menuPtr->interp, 4, menuDupCommandArray, 0); for (i = 0; i < 4; i++) { Tcl_DecrRefCount(menuDupCommandArray[i]); @@ -2755,9 +2762,9 @@ CloneMenu( newObjv[1] = Tcl_NewStringObj(Tk_PathName(newMenuPtr->tkwin), -1); Tcl_IncrRefCount(newObjv[0]); Tcl_IncrRefCount(newObjv[1]); - if (Tk_BindtagsObjCmd((ClientData)newMenuPtr->tkwin, - newMenuPtr->interp, 2, newObjv) == TCL_OK) { - char *windowName; + if (Tk_BindtagsObjCmd(newMenuPtr->tkwin, newMenuPtr->interp, 2, + newObjv) == TCL_OK) { + const char *windowName; Tcl_Obj *bindingsPtr = Tcl_DuplicateObj(Tcl_GetObjResult(newMenuPtr->interp)); Tcl_Obj *elementPtr; @@ -2781,8 +2788,8 @@ CloneMenu( Tcl_ListObjReplace(menuPtr->interp, bindingsPtr, i + 1, 0, 1, &newElementPtr); newObjv[2] = bindingsPtr; - Tk_BindtagsObjCmd((ClientData)newMenuPtr->tkwin, - menuPtr->interp, 3, newObjv); + Tk_BindtagsObjCmd(newMenuPtr->tkwin, menuPtr->interp, 3, + newObjv); break; } } @@ -2834,7 +2841,7 @@ CloneMenu( } else { returnResult = TCL_ERROR; } - Tcl_Release((ClientData) menuPtr); + Tcl_Release(menuPtr); return returnResult; } @@ -2939,11 +2946,12 @@ static int GetIndexFromCoords( Tcl_Interp *interp, /* Interpreter of menu. */ TkMenu *menuPtr, /* The menu we are searching. */ - char *string, /* The @string we are parsing. */ + const char *string, /* The @string we are parsing. */ int *indexPtr) /* The index of the item that matches. */ { int x, y, i; - char *p, *end; + const char *p; + char *end; int x2, borderwidth, max; TkRecomputeMenu(menuPtr); @@ -2967,10 +2975,10 @@ GetIndexFromCoords( *indexPtr = -1; - /* set the width of the final column to the remainder of the window + /* set the width of the final column to the remainder of the window * being aware of windows that may not be mapped yet. */ - max = Tk_IsMapped(menuPtr->tkwin) + max = Tk_IsMapped(menuPtr->tkwin) ? Tk_Width(menuPtr->tkwin) : Tk_ReqWidth(menuPtr->tkwin); max -= borderwidth; @@ -2991,7 +2999,7 @@ GetIndexFromCoords( return TCL_OK; error: - Tcl_SetResult(interp, NULL, TCL_STATIC); + Tcl_ResetResult(interp); return TCL_ERROR; } @@ -3070,10 +3078,9 @@ TkNewMenuName( char *destString; int i; int doDot; - Tcl_CmdInfo cmdInfo; Tcl_HashTable *nameTablePtr = NULL; TkWindow *winPtr = (TkWindow *) menuPtr->tkwin; - char *parentName = Tcl_GetString(parentPtr); + const char *parentName = Tcl_GetString(parentPtr); if (winPtr->mainPtr != NULL) { nameTablePtr = &(winPtr->mainPtr->nameTable); @@ -3110,7 +3117,7 @@ TkNewMenuName( Tcl_DecrRefCount(intPtr); } destString = Tcl_GetString(resultPtr); - if ((Tcl_GetCommandInfo(interp, destString, &cmdInfo) == 0) + if ((Tcl_FindCommand(interp, destString, NULL, 0) == NULL) && ((nameTablePtr == NULL) || (Tcl_FindHashEntry(nameTablePtr, destString) == NULL))) { break; @@ -3142,10 +3149,10 @@ void TkSetWindowMenuBar( Tcl_Interp *interp, /* The interpreter the toplevel lives in. */ Tk_Window tkwin, /* The toplevel window. */ - char *oldMenuName, /* The name of the menubar previously set in + const char *oldMenuName, /* The name of the menubar previously set in * this toplevel. NULL means no menu was set * previously. */ - char *menuName) /* The name of the new menubar that the + const char *menuName) /* The name of the new menubar that the * toplevel needs to be set to. NULL means * that their is no menu now. */ { @@ -3208,7 +3215,7 @@ TkSetWindowMenuBar( } else { prevTopLevelPtr->nextPtr = topLevelListPtr->nextPtr; } - ckfree((char *) topLevelListPtr); + ckfree(topLevelListPtr); TkFreeMenuReferences(menuRefPtr); } } @@ -3248,6 +3255,7 @@ TkSetWindowMenuBar( && (cloneMenuRefPtr->menuPtr != NULL)) { Tcl_Obj *cursorPtr = Tcl_NewStringObj("-cursor", -1); Tcl_Obj *nullPtr = Tcl_NewObj(); + cloneMenuRefPtr->menuPtr->parentTopLevelPtr = tkwin; menuBarPtr = cloneMenuRefPtr->menuPtr; newObjv[0] = cursorPtr; @@ -3273,8 +3281,7 @@ TkSetWindowMenuBar( * menu. */ - topLevelListPtr = (TkMenuTopLevelList *) - ckalloc(sizeof(TkMenuTopLevelList)); + topLevelListPtr = ckalloc(sizeof(TkMenuTopLevelList)); topLevelListPtr->tkwin = tkwin; topLevelListPtr->nextPtr = menuRefPtr->topLevelListPtr; menuRefPtr->topLevelListPtr = topLevelListPtr; @@ -3306,8 +3313,8 @@ DestroyMenuHashTable( ClientData clientData, /* The menu hash table we are destroying. */ Tcl_Interp *interp) /* The interpreter we are destroying. */ { - Tcl_DeleteHashTable((Tcl_HashTable *) clientData); - ckfree((char *) clientData); + Tcl_DeleteHashTable(clientData); + ckfree(clientData); } /* @@ -3332,15 +3339,14 @@ Tcl_HashTable * TkGetMenuHashTable( Tcl_Interp *interp) /* The interp we need the hash table in.*/ { - Tcl_HashTable *menuTablePtr; - - menuTablePtr = (Tcl_HashTable *) + Tcl_HashTable *menuTablePtr = Tcl_GetAssocData(interp, MENU_HASH_KEY, NULL); + if (menuTablePtr == NULL) { - menuTablePtr = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); + menuTablePtr = ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(menuTablePtr, TCL_STRING_KEYS); Tcl_SetAssocData(interp, MENU_HASH_KEY, DestroyMenuHashTable, - (ClientData) menuTablePtr); + menuTablePtr); } return menuTablePtr; } @@ -3369,7 +3375,7 @@ TkGetMenuHashTable( TkMenuReferences * TkCreateMenuReferences( Tcl_Interp *interp, - char *pathName) /* The path of the menu widget. */ + const char *pathName) /* The path of the menu widget. */ { Tcl_HashEntry *hashEntryPtr; TkMenuReferences *menuRefPtr; @@ -3378,14 +3384,14 @@ TkCreateMenuReferences( hashEntryPtr = Tcl_CreateHashEntry(menuTablePtr, pathName, &newEntry); if (newEntry) { - menuRefPtr = (TkMenuReferences *) ckalloc(sizeof(TkMenuReferences)); + menuRefPtr = ckalloc(sizeof(TkMenuReferences)); menuRefPtr->menuPtr = NULL; menuRefPtr->topLevelListPtr = NULL; menuRefPtr->parentEntryPtr = NULL; menuRefPtr->hashEntryPtr = hashEntryPtr; - Tcl_SetHashValue(hashEntryPtr, (char *) menuRefPtr); + Tcl_SetHashValue(hashEntryPtr, menuRefPtr); } else { - menuRefPtr = (TkMenuReferences *) Tcl_GetHashValue(hashEntryPtr); + menuRefPtr = Tcl_GetHashValue(hashEntryPtr); } return menuRefPtr; } @@ -3413,7 +3419,7 @@ TkCreateMenuReferences( TkMenuReferences * TkFindMenuReferences( Tcl_Interp *interp, /* The interp the menu is living in. */ - char *pathName) /* The path of the menu widget. */ + const char *pathName) /* The path of the menu widget. */ { Tcl_HashEntry *hashEntryPtr; TkMenuReferences *menuRefPtr = NULL; @@ -3422,7 +3428,7 @@ TkFindMenuReferences( menuTablePtr = TkGetMenuHashTable(interp); hashEntryPtr = Tcl_FindHashEntry(menuTablePtr, pathName); if (hashEntryPtr != NULL) { - menuRefPtr = (TkMenuReferences *) Tcl_GetHashValue(hashEntryPtr); + menuRefPtr = Tcl_GetHashValue(hashEntryPtr); } return menuRefPtr; } @@ -3452,7 +3458,8 @@ TkFindMenuReferencesObj( Tcl_Interp *interp, /* The interp the menu is living in. */ Tcl_Obj *objPtr) /* The path of the menu widget. */ { - char *pathName = Tcl_GetString(objPtr); + const char *pathName = Tcl_GetString(objPtr); + return TkFindMenuReferences(interp, pathName); } @@ -3483,7 +3490,7 @@ TkFreeMenuReferences( && (menuRefPtr->parentEntryPtr == NULL) && (menuRefPtr->topLevelListPtr == NULL)) { Tcl_DeleteHashEntry(menuRefPtr->hashEntryPtr); - ckfree((char *) menuRefPtr); + ckfree(menuRefPtr); return 1; } return 0; @@ -3520,8 +3527,7 @@ DeleteMenuCloneEntries( for (menuListPtr = menuPtr->masterMenuPtr; menuListPtr != NULL; menuListPtr = menuListPtr->nextInstancePtr) { for (i = last; i >= first; i--) { - Tcl_EventuallyFree((ClientData) menuListPtr->entries[i], - DestroyMenuEntry); + Tcl_EventuallyFree(menuListPtr->entries[i], (Tcl_FreeProc *) DestroyMenuEntry); } for (i = last + 1; i < menuListPtr->numEntries; i++) { j = i - numDeleted; @@ -3530,7 +3536,7 @@ DeleteMenuCloneEntries( } menuListPtr->numEntries -= numDeleted; if (menuListPtr->numEntries == 0) { - ckfree((char *) menuListPtr->entries); + ckfree(menuListPtr->entries); menuListPtr->entries = NULL; } if ((menuListPtr->active >= first) @@ -3587,7 +3593,7 @@ TkMenuCleanup( void TkMenuInit(void) { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (!menusInitialized) { @@ -3606,6 +3612,20 @@ TkMenuInit(void) } if (!tsdPtr->menusInitialized) { TkpMenuThreadInit(); + tsdPtr->menuOptionTable = + Tk_CreateOptionTable(NULL, tkMenuConfigSpecs); + tsdPtr->entryOptionTables[TEAROFF_ENTRY] = + Tk_CreateOptionTable(NULL, specsArray[TEAROFF_ENTRY]); + tsdPtr->entryOptionTables[COMMAND_ENTRY] = + Tk_CreateOptionTable(NULL, specsArray[COMMAND_ENTRY]); + tsdPtr->entryOptionTables[CASCADE_ENTRY] = + Tk_CreateOptionTable(NULL, specsArray[CASCADE_ENTRY]); + tsdPtr->entryOptionTables[SEPARATOR_ENTRY] = + Tk_CreateOptionTable(NULL, specsArray[SEPARATOR_ENTRY]); + tsdPtr->entryOptionTables[RADIO_BUTTON_ENTRY] = + Tk_CreateOptionTable(NULL, specsArray[RADIO_BUTTON_ENTRY]); + tsdPtr->entryOptionTables[CHECK_BUTTON_ENTRY] = + Tk_CreateOptionTable(NULL, specsArray[CHECK_BUTTON_ENTRY]); tsdPtr->menusInitialized = 1; } } diff --git a/generic/tkMenu.h b/generic/tkMenu.h index b1536df..4cc3d1b 100644 --- a/generic/tkMenu.h +++ b/generic/tkMenu.h @@ -25,11 +25,6 @@ #include "default.h" #endif -#ifdef BUILD_tk -# undef TCL_STORAGE_CLASS -# define TCL_STORAGE_CLASS DLLEXPORT -#endif - /* * Dummy types used by the platform menu code. */ @@ -252,8 +247,6 @@ typedef struct TkMenuEntry { * Menu states */ -MODULE_SCOPE const char *tkMenuStateStrings[]; - #define ENTRY_ACTIVE 0 #define ENTRY_NORMAL 1 #define ENTRY_DISABLED 2 @@ -366,10 +359,7 @@ typedef struct TkMenu { /* A pointer to the original menu for this * clone chain. Points back to this structure * if this menu is a master menu. */ - struct TkMenuOptionTables *optionTablesPtr; - /* A pointer to the collection of option - * tables that work with menus and menu - * entries. */ + void *reserved1; /* not used any more. */ Tk_Window parentTopLevelPtr;/* If this menu is a menubar, this is the * toplevel that owns the menu. Only * applicable for menubar clones. */ @@ -438,17 +428,6 @@ typedef struct TkMenuReferences { } TkMenuReferences; /* - * This structure contains all of the option tables that are needed by menus. - */ - -typedef struct TkMenuOptionTables { - Tk_OptionTable menuOptionTable; - /* The option table for menus. */ - Tk_OptionTable entryOptionTables[6]; - /* The tables for menu entries. */ -} TkMenuOptionTables; - -/* * Flag bits for menus: * * REDRAW_PENDING: Non-zero means a DoWhenIdle handler has @@ -505,12 +484,12 @@ typedef struct TkMenuOptionTables { MODULE_SCOPE int TkActivateMenuEntry(TkMenu *menuPtr, int index); MODULE_SCOPE void TkBindMenu(Tk_Window tkwin, TkMenu *menuPtr); MODULE_SCOPE TkMenuReferences*TkCreateMenuReferences(Tcl_Interp *interp, - char *name); + const char *name); MODULE_SCOPE void TkDestroyMenu(TkMenu *menuPtr); MODULE_SCOPE void TkEventuallyRecomputeMenu(TkMenu *menuPtr); MODULE_SCOPE void TkEventuallyRedrawMenu(TkMenu *menuPtr, TkMenuEntry *mePtr); -MODULE_SCOPE TkMenuReferences*TkFindMenuReferences(Tcl_Interp *interp, char *name); +MODULE_SCOPE TkMenuReferences*TkFindMenuReferences(Tcl_Interp *interp, const char *name); MODULE_SCOPE TkMenuReferences*TkFindMenuReferencesObj(Tcl_Interp *interp, Tcl_Obj *namePtr); MODULE_SCOPE int TkFreeMenuReferences(TkMenuReferences *menuRefPtr); @@ -541,7 +520,7 @@ MODULE_SCOPE int TkPostCommand(TkMenu *menuPtr); MODULE_SCOPE int TkPostSubmenu(Tcl_Interp *interp, TkMenu *menuPtr, TkMenuEntry *mePtr); MODULE_SCOPE int TkPostTearoffMenu(Tcl_Interp *interp, TkMenu *menuPtr, - int x, int y); + int x, int y); MODULE_SCOPE int TkPreprocessMenu(TkMenu *menuPtr); MODULE_SCOPE void TkRecomputeMenu(TkMenu *menuPtr); @@ -564,10 +543,9 @@ MODULE_SCOPE void TkpMenuInit(void); MODULE_SCOPE int TkpMenuNewEntry(TkMenuEntry *mePtr); MODULE_SCOPE int TkpNewMenu(TkMenu *menuPtr); MODULE_SCOPE int TkpPostMenu(Tcl_Interp *interp, TkMenu *menuPtr, - int x, int y); + int x, int y, int index); +MODULE_SCOPE int TkpPostTearoffMenu(Tcl_Interp *interp, TkMenu *menuPtr, + int x, int y, int index); MODULE_SCOPE void TkpSetWindowMenuBar(Tk_Window tkwin, TkMenu *menuPtr); -# undef TCL_STORAGE_CLASS -# define TCL_STORAGE_CLASS DLLIMPORT - #endif /* _TKMENU */ diff --git a/generic/tkMenuDraw.c b/generic/tkMenuDraw.c index 37147bd..d91bc11 100644 --- a/generic/tkMenuDraw.c +++ b/generic/tkMenuDraw.c @@ -432,7 +432,7 @@ TkEventuallyRecomputeMenu( { if (!(menuPtr->menuFlags & RESIZE_PENDING)) { menuPtr->menuFlags |= RESIZE_PENDING; - Tcl_DoWhenIdle(ComputeMenuGeometry, (ClientData) menuPtr); + Tcl_DoWhenIdle(ComputeMenuGeometry, menuPtr); } } @@ -458,8 +458,8 @@ TkRecomputeMenu( TkMenu *menuPtr) { if (menuPtr->menuFlags & RESIZE_PENDING) { - Tcl_CancelIdleCall(ComputeMenuGeometry, (ClientData) menuPtr); - ComputeMenuGeometry((ClientData) menuPtr); + Tcl_CancelIdleCall(ComputeMenuGeometry, menuPtr); + ComputeMenuGeometry(menuPtr); } } @@ -475,7 +475,7 @@ TkRecomputeMenu( * None. * * Side effects: - * A when-idle hander is scheduled to do the redisplay, if there isn't + * A when-idle handler is scheduled to do the redisplay, if there isn't * one already scheduled. * *---------------------------------------------------------------------- @@ -503,7 +503,7 @@ TkEventuallyRedrawMenu( || (menuPtr->menuFlags & REDRAW_PENDING)) { return; } - Tcl_DoWhenIdle(DisplayMenu, (ClientData) menuPtr); + Tcl_DoWhenIdle(DisplayMenu, menuPtr); menuPtr->menuFlags |= REDRAW_PENDING; } @@ -530,7 +530,7 @@ static void ComputeMenuGeometry( ClientData clientData) /* Structure describing menu. */ { - TkMenu *menuPtr = (TkMenu *) clientData; + TkMenu *menuPtr = clientData; if (menuPtr->tkwin == NULL) { return; @@ -586,12 +586,12 @@ TkMenuSelectImageProc( * <=0). */ int imgWidth, int imgHeight)/* New dimensions of image. */ { - register TkMenuEntry *mePtr = (TkMenuEntry *) clientData; + register TkMenuEntry *mePtr = clientData; if ((mePtr->entryFlags & ENTRY_SELECTED) && !(mePtr->menuPtr->menuFlags & REDRAW_PENDING)) { mePtr->menuPtr->menuFlags |= REDRAW_PENDING; - Tcl_DoWhenIdle(DisplayMenu, (ClientData) mePtr->menuPtr); + Tcl_DoWhenIdle(DisplayMenu, mePtr->menuPtr); } } @@ -615,7 +615,7 @@ static void DisplayMenu( ClientData clientData) /* Information about widget. */ { - register TkMenu *menuPtr = (TkMenu *) clientData; + register TkMenu *menuPtr = clientData; register TkMenuEntry *mePtr; register Tk_Window tkwin = menuPtr->tkwin; int index, strictMotif; @@ -624,7 +624,6 @@ DisplayMenu( int width; int borderWidth; Tk_3DBorder border; - int activeBorderWidth; int relief; @@ -636,8 +635,6 @@ DisplayMenu( Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr, &borderWidth); border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr); - Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, - menuPtr->activeBorderWidthPtr, &activeBorderWidth); if (menuPtr->menuType == MENUBAR) { Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, borderWidth, @@ -668,28 +665,16 @@ DisplayMenu( } mePtr->entryFlags &= ~ENTRY_NEEDS_REDISPLAY; - if (menuPtr->menuType == MENUBAR) { - width = mePtr->width; - } else { - if (mePtr->entryFlags & ENTRY_LAST_COLUMN) { - width = Tk_Width(menuPtr->tkwin) - mePtr->x - - activeBorderWidth; - } else { - width = mePtr->width + borderWidth; - } - } TkpDrawMenuEntry(mePtr, Tk_WindowId(menuPtr->tkwin), tkfont, - &menuMetrics, mePtr->x, mePtr->y, width, + &menuMetrics, mePtr->x, mePtr->y, mePtr->width, mePtr->height, strictMotif, 1); if ((index > 0) && (menuPtr->menuType != MENUBAR) && mePtr->columnBreak) { mePtr = menuPtr->entries[index - 1]; Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, - mePtr->x, mePtr->y + mePtr->height, - mePtr->width, - Tk_Height(tkwin) - mePtr->y - mePtr->height - - activeBorderWidth, 0, - TK_RELIEF_FLAT); + mePtr->x, mePtr->y + mePtr->height, mePtr->width, + Tk_Height(tkwin) - mePtr->y - mePtr->height - borderWidth, + 0, TK_RELIEF_FLAT); } } @@ -698,19 +683,18 @@ DisplayMenu( if (menuPtr->numEntries == 0) { x = y = borderWidth; - width = Tk_Width(tkwin) - 2 * activeBorderWidth; - height = Tk_Height(tkwin) - 2 * activeBorderWidth; + width = Tk_Width(tkwin) - 2 * borderWidth; + height = Tk_Height(tkwin) - 2 * borderWidth; } else { mePtr = menuPtr->entries[menuPtr->numEntries - 1]; Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, mePtr->x, mePtr->y + mePtr->height, mePtr->width, - Tk_Height(tkwin) - mePtr->y - mePtr->height - - activeBorderWidth, 0, - TK_RELIEF_FLAT); + Tk_Height(tkwin) - mePtr->y - mePtr->height - borderWidth, + 0, TK_RELIEF_FLAT); x = mePtr->x + mePtr->width; y = mePtr->y + mePtr->height; - width = Tk_Width(tkwin) - x - activeBorderWidth; - height = Tk_Height(tkwin) - y - activeBorderWidth; + width = Tk_Width(tkwin) - x - borderWidth; + height = Tk_Height(tkwin) - y - borderWidth; } Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, x, y, width, height, 0, TK_RELIEF_FLAT); @@ -745,7 +729,7 @@ TkMenuEventProc( ClientData clientData, /* Information about window. */ XEvent *eventPtr) /* Information about event. */ { - TkMenu *menuPtr = (TkMenu *) clientData; + TkMenu *menuPtr = clientData; if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) { TkEventuallyRedrawMenu(menuPtr, NULL); @@ -772,14 +756,14 @@ TkMenuEventProc( menuPtr->widgetCmd = NULL; } if (menuPtr->menuFlags & REDRAW_PENDING) { - Tcl_CancelIdleCall(DisplayMenu, (ClientData) menuPtr); + Tcl_CancelIdleCall(DisplayMenu, menuPtr); menuPtr->menuFlags &= ~REDRAW_PENDING; } if (menuPtr->menuFlags & RESIZE_PENDING) { - Tcl_CancelIdleCall(ComputeMenuGeometry, (ClientData) menuPtr); + Tcl_CancelIdleCall(ComputeMenuGeometry, menuPtr); menuPtr->menuFlags &= ~RESIZE_PENDING; } - Tcl_EventuallyFree((ClientData) menuPtr, TCL_DYNAMIC); + Tcl_EventuallyFree(menuPtr, TCL_DYNAMIC); } } @@ -810,11 +794,11 @@ TkMenuImageProc( * <=0). */ int imgWidth, int imgHeight)/* New dimensions of image. */ { - register TkMenu *menuPtr = ((TkMenuEntry *)clientData)->menuPtr; + register TkMenu *menuPtr = ((TkMenuEntry *) clientData)->menuPtr; if ((menuPtr->tkwin != NULL) && !(menuPtr->menuFlags & RESIZE_PENDING)) { menuPtr->menuFlags |= RESIZE_PENDING; - Tcl_DoWhenIdle(ComputeMenuGeometry, (ClientData) menuPtr); + Tcl_DoWhenIdle(ComputeMenuGeometry, menuPtr); } } @@ -823,9 +807,8 @@ TkMenuImageProc( * * TkPostTearoffMenu -- * - * Posts a menu on the screen. Used to post tearoff menus. On Unix, all - * menus are posted this way. Adjusts the menu's position so that it fits - * on the screen, and maps and raises the menu. + * Posts a tearoff menu on the screen. Adjusts the menu's position so + * that it fits on the screen, and maps and raises the menu. * * Results: * Returns a standard Tcl Error. @@ -843,64 +826,7 @@ TkPostTearoffMenu( int x, int y) /* The root X,Y coordinates where we are * posting */ { - int vRootX, vRootY, vRootWidth, vRootHeight; - int result; - - TkActivateMenuEntry(menuPtr, -1); - TkRecomputeMenu(menuPtr); - result = TkPostCommand(menuPtr); - if (result != TCL_OK) { - return result; - } - - /* - * The post commands could have deleted the menu, which means we are dead - * and should go away. - */ - - if (menuPtr->tkwin == NULL) { - return TCL_OK; - } - - /* - * Adjust the position of the menu if necessary to keep it visible on the - * screen. There are two special tricks to make this work right: - * - * 1. If a virtual root window manager is being used then the coordinates - * are in the virtual root window of menuPtr's parent; since the menu - * uses override-redirect mode it will be in the *real* root window for - * the screen, so we have to map the coordinates from the virtual root - * (if any) to the real root. Can't get the virtual root from the menu - * itself (it will never be seen by the wm) so use its parent instead - * (it would be better to have an an option that names a window to use - * for this...). - * 2. The menu may not have been mapped yet, so its current size might be - * the default 1x1. To compute how much space it needs, use its - * requested size, not its actual size. - */ - - Tk_GetVRootGeometry(Tk_Parent(menuPtr->tkwin), &vRootX, &vRootY, - &vRootWidth, &vRootHeight); - vRootWidth -= Tk_ReqWidth(menuPtr->tkwin); - if (x > vRootX + vRootWidth) { - x = vRootX + vRootWidth; - } - if (x < vRootX) { - x = vRootX; - } - vRootHeight -= Tk_ReqHeight(menuPtr->tkwin); - if (y > vRootY + vRootHeight) { - y = vRootY + vRootHeight; - } - if (y < vRootY) { - y = vRootY; - } - Tk_MoveToplevelWindow(menuPtr->tkwin, x, y); - if (!Tk_IsMapped(menuPtr->tkwin)) { - Tk_MapWindow(menuPtr->tkwin); - } - TkWmRestackToplevel((TkWindow *) menuPtr->tkwin, Above, NULL); - return TCL_OK; + return TkpPostTearoffMenu(interp, menuPtr, x, y, -1); } /* diff --git a/generic/tkMenubutton.c b/generic/tkMenubutton.c index 17fd106..2228a2e 100644 --- a/generic/tkMenubutton.c +++ b/generic/tkMenubutton.c @@ -16,6 +16,18 @@ #include "default.h" /* + * The structure below defines menubutton class behavior by means of + * procedures that can be invoked from generic window code. + */ + +static const Tk_ClassProcs menubuttonClass = { + sizeof(Tk_ClassProcs), /* size */ + TkMenuButtonWorldChanged, /* worldChangedProc */ + NULL, /* createProc */ + NULL /* modalProc */ +}; + +/* * The following table defines the legal values for the -direction option. It * is used together with the "enum direction" declaration in tkMenubutton.h. */ @@ -54,13 +66,13 @@ static const Tk_OptionSpec optionSpecs[] = { {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background", DEF_MENUBUTTON_ACTIVE_FG_COLOR, -1, Tk_Offset(TkMenuButton, activeFg), - 0, (ClientData) DEF_MENUBUTTON_ACTIVE_FG_MONO, 0}, + 0, DEF_MENUBUTTON_ACTIVE_FG_MONO, 0}, {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", DEF_MENUBUTTON_ANCHOR, -1, Tk_Offset(TkMenuButton, anchor), 0, 0, 0}, {TK_OPTION_BORDER, "-background", "background", "Background", DEF_MENUBUTTON_BG_COLOR, -1, Tk_Offset(TkMenuButton, normalBorder), - 0, (ClientData) DEF_MENUBUTTON_BG_MONO, 0}, + 0, DEF_MENUBUTTON_BG_MONO, 0}, {TK_OPTION_SYNONYM, "-bd", NULL, NULL, NULL, 0, -1, 0, (ClientData) "-borderwidth", 0}, {TK_OPTION_SYNONYM, "-bg", NULL, NULL, NULL, 0, -1, 0, @@ -76,7 +88,7 @@ static const Tk_OptionSpec optionSpecs[] = { TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING_TABLE, "-direction", "direction", "Direction", DEF_MENUBUTTON_DIRECTION, -1, Tk_Offset(TkMenuButton, direction), - 0, (ClientData) directionStrings, 0}, + 0, directionStrings, 0}, {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground", "DisabledForeground", DEF_MENUBUTTON_DISABLED_FG_COLOR, -1, Tk_Offset(TkMenuButton, disabledFg), TK_OPTION_NULL_OK, @@ -121,10 +133,10 @@ static const Tk_OptionSpec optionSpecs[] = { 0, 0, 0}, {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound", DEF_BUTTON_COMPOUND, -1, Tk_Offset(TkMenuButton, compound), 0, - (ClientData) compoundStrings, 0}, + compoundStrings, 0}, {TK_OPTION_STRING_TABLE, "-state", "state", "State", DEF_MENUBUTTON_STATE, -1, Tk_Offset(TkMenuButton, state), - 0, (ClientData) stateStrings, 0}, + 0, stateStrings, 0}, {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", DEF_MENUBUTTON_TAKE_FOCUS, -1, Tk_Offset(TkMenuButton, takeFocus), TK_OPTION_NULL_OK, 0, 0}, @@ -142,7 +154,7 @@ static const Tk_OptionSpec optionSpecs[] = { {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength", DEF_MENUBUTTON_WRAP_LENGTH, -1, Tk_Offset(TkMenuButton, wrapLength), 0, 0, 0}, - {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0} + {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0} }; /* @@ -151,7 +163,7 @@ static const Tk_OptionSpec optionSpecs[] = { * dispatch the scale widget command. */ -static const char *commandNames[] = { +static const char *const commandNames[] = { "cget", "configure", NULL }; @@ -210,7 +222,7 @@ Tk_MenubuttonObjCmd( Tk_Window tkwin; if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?"); + Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?"); return TCL_ERROR; } @@ -234,18 +246,18 @@ Tk_MenubuttonObjCmd( Tk_SetClass(tkwin, "Menubutton"); mbPtr = TkpCreateMenuButton(tkwin); - Tk_SetClassProcs(tkwin, &tkpMenubuttonClass, (ClientData) mbPtr); + Tk_SetClassProcs(tkwin, &menubuttonClass, mbPtr); /* * Initialize the data structure for the button. */ mbPtr->tkwin = tkwin; - mbPtr->display = Tk_Display (tkwin); + mbPtr->display = Tk_Display(tkwin); mbPtr->interp = interp; mbPtr->widgetCmd = Tcl_CreateObjCommand(interp, - Tk_PathName(mbPtr->tkwin), MenuButtonWidgetObjCmd, - (ClientData) mbPtr, MenuButtonCmdDeletedProc); + Tk_PathName(mbPtr->tkwin), MenuButtonWidgetObjCmd, mbPtr, + MenuButtonCmdDeletedProc); mbPtr->optionTable = optionTable; mbPtr->menuName = NULL; mbPtr->text = NULL; @@ -294,7 +306,7 @@ Tk_MenubuttonObjCmd( Tk_CreateEventHandler(mbPtr->tkwin, ExposureMask|StructureNotifyMask|FocusChangeMask, - MenuButtonEventProc, (ClientData) mbPtr); + MenuButtonEventProc, mbPtr); if (Tk_InitOptions(interp, (char *) mbPtr, optionTable, tkwin) != TCL_OK) { Tk_DestroyWindow(mbPtr->tkwin); @@ -306,7 +318,7 @@ Tk_MenubuttonObjCmd( return TCL_ERROR; } - Tcl_SetStringObj(Tcl_GetObjResult(interp), Tk_PathName(mbPtr->tkwin), -1); + Tcl_SetObjResult(interp, TkNewWindowObj(mbPtr->tkwin)); return TCL_OK; } @@ -335,20 +347,20 @@ MenuButtonWidgetObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - register TkMenuButton *mbPtr = (TkMenuButton *) clientData; + register TkMenuButton *mbPtr = clientData; int result, index; Tcl_Obj *objPtr; if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?"); + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); return TCL_ERROR; } - result = Tcl_GetIndexFromObj(interp, objv[1], commandNames, "option", 0, - &index); + result = Tcl_GetIndexFromObjStruct(interp, objv[1], commandNames, + sizeof(char *), "option", 0, &index); if (result != TCL_OK) { return result; } - Tcl_Preserve((ClientData) mbPtr); + Tcl_Preserve(mbPtr); switch (index) { case COMMAND_CGET: @@ -361,9 +373,8 @@ MenuButtonWidgetObjCmd( mbPtr->optionTable, objv[2], mbPtr->tkwin); if (objPtr == NULL) { goto error; - } else { - Tcl_SetObjResult(interp, objPtr); } + Tcl_SetObjResult(interp, objPtr); break; case COMMAND_CONFIGURE: @@ -373,19 +384,18 @@ MenuButtonWidgetObjCmd( mbPtr->tkwin); if (objPtr == NULL) { goto error; - } else { - Tcl_SetObjResult(interp, objPtr); } + Tcl_SetObjResult(interp, objPtr); } else { result = ConfigureMenuButton(interp, mbPtr, objc-2, objv+2); } break; } - Tcl_Release((ClientData) mbPtr); + Tcl_Release(mbPtr); return result; error: - Tcl_Release((ClientData) mbPtr); + Tcl_Release(mbPtr); return TCL_ERROR; } @@ -416,7 +426,7 @@ DestroyMenuButton( TkpDestroyMenuButton(mbPtr); if (mbPtr->flags & REDRAW_PENDING) { - Tcl_CancelIdleCall(TkpDisplayMenuButton, (ClientData) mbPtr); + Tcl_CancelIdleCall(TkpDisplayMenuButton, mbPtr); } /* @@ -426,9 +436,9 @@ DestroyMenuButton( Tcl_DeleteCommandFromToken(mbPtr->interp, mbPtr->widgetCmd); if (mbPtr->textVarName != NULL) { - Tcl_UntraceVar(mbPtr->interp, mbPtr->textVarName, + Tcl_UntraceVar2(mbPtr->interp, mbPtr->textVarName, NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - MenuButtonTextVarProc, (ClientData) mbPtr); + MenuButtonTextVarProc, mbPtr); } if (mbPtr->image != NULL) { Tk_FreeImage(mbPtr->image); @@ -453,7 +463,7 @@ DestroyMenuButton( } Tk_FreeConfigOptions((char *) mbPtr, mbPtr->optionTable, mbPtr->tkwin); mbPtr->tkwin = NULL; - Tcl_EventuallyFree((ClientData) mbPtr, TCL_DYNAMIC); + Tcl_EventuallyFree(mbPtr, TCL_DYNAMIC); } /* @@ -496,9 +506,9 @@ ConfigureMenuButton( */ if (mbPtr->textVarName != NULL) { - Tcl_UntraceVar(interp, mbPtr->textVarName, + Tcl_UntraceVar2(interp, mbPtr->textVarName, NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - MenuButtonTextVarProc, (ClientData) mbPtr); + MenuButtonTextVarProc, mbPtr); } /* @@ -561,8 +571,7 @@ ConfigureMenuButton( if (mbPtr->imageString != NULL) { image = Tk_GetImage(mbPtr->interp, mbPtr->tkwin, - mbPtr->imageString, MenuButtonImageProc, - (ClientData) mbPtr); + mbPtr->imageString, MenuButtonImageProc, mbPtr); if (image == NULL) { return TCL_ERROR; } @@ -616,23 +625,23 @@ ConfigureMenuButton( */ const char *value; - value = Tcl_GetVar(interp, mbPtr->textVarName, TCL_GLOBAL_ONLY); + value = Tcl_GetVar2(interp, mbPtr->textVarName, NULL, TCL_GLOBAL_ONLY); if (value == NULL) { - Tcl_SetVar(interp, mbPtr->textVarName, mbPtr->text, + Tcl_SetVar2(interp, mbPtr->textVarName, NULL, mbPtr->text, TCL_GLOBAL_ONLY); } else { if (mbPtr->text != NULL) { ckfree(mbPtr->text); } - mbPtr->text = (char *) ckalloc((unsigned) (strlen(value) + 1)); + mbPtr->text = ckalloc(strlen(value) + 1); strcpy(mbPtr->text, value); } - Tcl_TraceVar(interp, mbPtr->textVarName, + Tcl_TraceVar2(interp, mbPtr->textVarName, NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - MenuButtonTextVarProc, (ClientData) mbPtr); + MenuButtonTextVarProc, mbPtr); } - TkMenuButtonWorldChanged((ClientData) mbPtr); + TkMenuButtonWorldChanged(mbPtr); if (error) { Tcl_SetObjResult(interp, errorResult); Tcl_DecrRefCount(errorResult); @@ -666,9 +675,7 @@ TkMenuButtonWorldChanged( XGCValues gcValues; GC gc; unsigned long mask; - TkMenuButton *mbPtr; - - mbPtr = (TkMenuButton *) instanceData; + TkMenuButton *mbPtr = instanceData; gcValues.font = Tk_FontId(mbPtr->tkfont); gcValues.foreground = mbPtr->normalFg->pixel; @@ -741,7 +748,7 @@ TkMenuButtonWorldChanged( */ if (Tk_IsMapped(mbPtr->tkwin) && !(mbPtr->flags & REDRAW_PENDING)) { - Tcl_DoWhenIdle(TkpDisplayMenuButton, (ClientData) mbPtr); + Tcl_DoWhenIdle(TkpDisplayMenuButton, mbPtr); mbPtr->flags |= REDRAW_PENDING; } } @@ -769,7 +776,8 @@ MenuButtonEventProc( ClientData clientData, /* Information about window. */ XEvent *eventPtr) /* Information about event. */ { - TkMenuButton *mbPtr = (TkMenuButton *) clientData; + TkMenuButton *mbPtr = clientData; + if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) { goto redraw; } else if (eventPtr->type == ConfigureNotify) { @@ -800,7 +808,7 @@ MenuButtonEventProc( redraw: if ((mbPtr->tkwin != NULL) && !(mbPtr->flags & REDRAW_PENDING)) { - Tcl_DoWhenIdle(TkpDisplayMenuButton, (ClientData) mbPtr); + Tcl_DoWhenIdle(TkpDisplayMenuButton, mbPtr); mbPtr->flags |= REDRAW_PENDING; } } @@ -827,7 +835,7 @@ static void MenuButtonCmdDeletedProc( ClientData clientData) /* Pointer to widget record for widget. */ { - TkMenuButton *mbPtr = (TkMenuButton *) clientData; + TkMenuButton *mbPtr = clientData; Tk_Window tkwin = mbPtr->tkwin; /* @@ -869,7 +877,7 @@ MenuButtonTextVarProc( const char *name2, /* Second part of variable name. */ int flags) /* Information about what happened. */ { - register TkMenuButton *mbPtr = (TkMenuButton *) clientData; + register TkMenuButton *mbPtr = clientData; const char *value; unsigned len; @@ -879,17 +887,37 @@ MenuButtonTextVarProc( */ if (flags & TCL_TRACE_UNSETS) { - if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) { - Tcl_SetVar(interp, mbPtr->textVarName, mbPtr->text, + if (!Tcl_InterpDeleted(interp) && mbPtr->textVarName) { + ClientData probe = NULL; + + do { + probe = Tcl_VarTraceInfo(interp, + mbPtr->textVarName, + TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + MenuButtonTextVarProc, probe); + if (probe == (ClientData)mbPtr) { + break; + } + } while (probe); + if (probe) { + /* + * We were able to fetch the unset trace for our + * textVarName, which means it is not unset and not + * the cause of this unset trace. Instead some outdated + * former variable must be, and we should ignore it. + */ + return NULL; + } + Tcl_SetVar2(interp, mbPtr->textVarName, NULL, mbPtr->text, TCL_GLOBAL_ONLY); - Tcl_TraceVar(interp, mbPtr->textVarName, + Tcl_TraceVar2(interp, mbPtr->textVarName, NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, MenuButtonTextVarProc, clientData); } return NULL; } - value = Tcl_GetVar(interp, mbPtr->textVarName, TCL_GLOBAL_ONLY); + value = Tcl_GetVar2(interp, mbPtr->textVarName, NULL, TCL_GLOBAL_ONLY); if (value == NULL) { value = ""; } @@ -897,13 +925,13 @@ MenuButtonTextVarProc( ckfree(mbPtr->text); } len = 1 + (unsigned) strlen(value); - mbPtr->text = (char *) ckalloc(len); + mbPtr->text = ckalloc(len); memcpy(mbPtr->text, value, len); TkpComputeMenuButtonGeometry(mbPtr); if ((mbPtr->tkwin != NULL) && Tk_IsMapped(mbPtr->tkwin) && !(mbPtr->flags & REDRAW_PENDING)) { - Tcl_DoWhenIdle(TkpDisplayMenuButton, (ClientData) mbPtr); + Tcl_DoWhenIdle(TkpDisplayMenuButton, mbPtr); mbPtr->flags |= REDRAW_PENDING; } return NULL; @@ -936,12 +964,12 @@ MenuButtonImageProc( * 0). */ int imgWidth, int imgHeight)/* New dimensions of image. */ { - register TkMenuButton *mbPtr = (TkMenuButton *) clientData; + register TkMenuButton *mbPtr = clientData; if (mbPtr->tkwin != NULL) { TkpComputeMenuButtonGeometry(mbPtr); if (Tk_IsMapped(mbPtr->tkwin) && !(mbPtr->flags & REDRAW_PENDING)) { - Tcl_DoWhenIdle(TkpDisplayMenuButton, (ClientData) mbPtr); + Tcl_DoWhenIdle(TkpDisplayMenuButton, mbPtr); mbPtr->flags |= REDRAW_PENDING; } } diff --git a/generic/tkMenubutton.h b/generic/tkMenubutton.h index f190c81..1dbacb3 100644 --- a/generic/tkMenubutton.h +++ b/generic/tkMenubutton.h @@ -21,11 +21,6 @@ #include "tkMenu.h" #endif -#ifdef BUILD_tk -# undef TCL_STORAGE_CLASS -# define TCL_STORAGE_CLASS DLLEXPORT -#endif - /* * Legal values for the "orient" field of TkMenubutton records. */ @@ -209,12 +204,6 @@ typedef struct { #define INDICATOR_HEIGHT 17 /* - * Declaration of variables shared between the files in the button module. - */ - -MODULE_SCOPE Tk_ClassProcs tkpMenubuttonClass; - -/* * Declaration of procedures used in the implementation of the button widget. */ @@ -224,7 +213,4 @@ MODULE_SCOPE void TkpDisplayMenuButton(ClientData clientData); MODULE_SCOPE void TkpDestroyMenuButton(TkMenuButton *mbPtr); MODULE_SCOPE void TkMenuButtonWorldChanged(ClientData instanceData); -# undef TCL_STORAGE_CLASS -# define TCL_STORAGE_CLASS DLLIMPORT - #endif /* _TKMENUBUTTON */ diff --git a/generic/tkMessage.c b/generic/tkMessage.c index 17659ac..1a3c6de 100644 --- a/generic/tkMessage.c +++ b/generic/tkMessage.c @@ -114,11 +114,11 @@ static const Tk_OptionSpec optionSpecs[] = { -1, Tk_Offset(Message, aspect), 0, 0, 0}, {TK_OPTION_BORDER, "-background", "background", "Background", DEF_MESSAGE_BG_COLOR, -1, Tk_Offset(Message, border), 0, - (ClientData) DEF_MESSAGE_BG_MONO, 0}, + DEF_MESSAGE_BG_MONO, 0}, {TK_OPTION_SYNONYM, "-bd", NULL, NULL, NULL, - 0, -1, 0, (ClientData) "-borderwidth", 0}, + 0, -1, 0, "-borderwidth", 0}, {TK_OPTION_SYNONYM, "-bg", NULL, NULL, NULL, - 0, -1, 0, (ClientData) "-background", 0}, + 0, -1, 0, "-background", 0}, {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", DEF_MESSAGE_BORDER_WIDTH, -1, Tk_Offset(Message, borderWidth), 0, 0, 0}, @@ -126,14 +126,14 @@ static const Tk_OptionSpec optionSpecs[] = { DEF_MESSAGE_CURSOR, -1, Tk_Offset(Message, cursor), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_SYNONYM, "-fg", NULL, NULL, NULL, - 0, -1, 0, (ClientData) "-foreground", 0}, + 0, -1, 0, "-foreground", 0}, {TK_OPTION_FONT, "-font", "font", "Font", DEF_MESSAGE_FONT, -1, Tk_Offset(Message, tkfont), 0, 0, 0}, {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground", DEF_MESSAGE_FG, -1, Tk_Offset(Message, fgColorPtr), 0, 0, 0}, {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground", "HighlightBackground", DEF_MESSAGE_HIGHLIGHT_BG, -1, - Tk_Offset(Message, highlightBgColorPtr), 0, 0}, + Tk_Offset(Message, highlightBgColorPtr), 0, 0, 0}, {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", DEF_MESSAGE_HIGHLIGHT, -1, Tk_Offset(Message, highlightColorPtr), 0, 0, 0}, @@ -160,7 +160,7 @@ static const Tk_OptionSpec optionSpecs[] = { TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_PIXELS, "-width", "width", "Width", DEF_MESSAGE_WIDTH, -1, Tk_Offset(Message, width), 0, 0 ,0}, - {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0} + {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0} }; /* @@ -171,15 +171,15 @@ static void MessageCmdDeletedProc(ClientData clientData); static void MessageEventProc(ClientData clientData, XEvent *eventPtr); static char * MessageTextVarProc(ClientData clientData, - Tcl_Interp *interp, CONST char *name1, - CONST char *name2, int flags); + Tcl_Interp *interp, const char *name1, + const char *name2, int flags); static int MessageWidgetObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[]); + Tcl_Obj *const objv[]); static void MessageWorldChanged(ClientData instanceData); static void ComputeMessageGeometry(Message *msgPtr); static int ConfigureMessage(Tcl_Interp *interp, Message *msgPtr, - int objc, Tcl_Obj *CONST objv[], int flags); + int objc, Tcl_Obj *const objv[], int flags); static void DestroyMessage(char *memPtr); static void DisplayMessage(ClientData clientData); @@ -188,9 +188,11 @@ static void DisplayMessage(ClientData clientData); * that can be invoked from generic window code. */ -static Tk_ClassProcs messageClass = { +static const Tk_ClassProcs messageClass = { sizeof(Tk_ClassProcs), /* size */ MessageWorldChanged, /* worldChangedProc */ + NULL, /* createProc */ + NULL /* modalProc */ }; /* @@ -215,14 +217,14 @@ Tk_MessageObjCmd( ClientData clientData, /* NULL. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument strings. */ + Tcl_Obj *const objv[]) /* Argument strings. */ { register Message *msgPtr; Tk_OptionTable optionTable; Tk_Window tkwin; if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?"); + Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?"); return TCL_ERROR; } @@ -239,7 +241,7 @@ Tk_MessageObjCmd( optionTable = Tk_CreateOptionTable(interp, optionSpecs); - msgPtr = (Message *) ckalloc(sizeof(Message)); + msgPtr = ckalloc(sizeof(Message)); memset(msgPtr, 0, (size_t) sizeof(Message)); /* @@ -250,8 +252,8 @@ Tk_MessageObjCmd( msgPtr->display = Tk_Display(tkwin); msgPtr->interp = interp; msgPtr->widgetCmd = Tcl_CreateObjCommand(interp, - Tk_PathName(msgPtr->tkwin), MessageWidgetObjCmd, - (ClientData) msgPtr, MessageCmdDeletedProc); + Tk_PathName(msgPtr->tkwin), MessageWidgetObjCmd, msgPtr, + MessageCmdDeletedProc); msgPtr->optionTable = optionTable; msgPtr->relief = TK_RELIEF_FLAT; msgPtr->textGC = NULL; @@ -261,10 +263,10 @@ Tk_MessageObjCmd( msgPtr->cursor = NULL; Tk_SetClass(msgPtr->tkwin, "Message"); - Tk_SetClassProcs(msgPtr->tkwin, &messageClass, (ClientData) msgPtr); + Tk_SetClassProcs(msgPtr->tkwin, &messageClass, msgPtr); Tk_CreateEventHandler(msgPtr->tkwin, ExposureMask|StructureNotifyMask|FocusChangeMask, - MessageEventProc, (ClientData) msgPtr); + MessageEventProc, msgPtr); if (Tk_InitOptions(interp, (char *)msgPtr, optionTable, tkwin) != TCL_OK) { Tk_DestroyWindow(msgPtr->tkwin); return TCL_ERROR; @@ -275,7 +277,7 @@ Tk_MessageObjCmd( return TCL_ERROR; } - Tcl_SetResult(interp, Tk_PathName(msgPtr->tkwin), TCL_STATIC); + Tcl_SetObjResult(interp, TkNewWindowObj(msgPtr->tkwin)); return TCL_OK; } @@ -302,26 +304,26 @@ MessageWidgetObjCmd( ClientData clientData, /* Information about message widget. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument strings. */ + Tcl_Obj *const objv[]) /* Argument strings. */ { - register Message *msgPtr = (Message *) clientData; - static CONST char *optionStrings[] = { "cget", "configure", NULL }; + register Message *msgPtr = clientData; + static const char *const optionStrings[] = { "cget", "configure", NULL }; enum options { MESSAGE_CGET, MESSAGE_CONFIGURE }; int index; int result = TCL_OK; Tcl_Obj *objPtr; if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?"); + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); return TCL_ERROR; } - if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0, - &index) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings, + sizeof(char *), "option", 0, &index) != TCL_OK) { return TCL_ERROR; } - Tcl_Preserve((ClientData) msgPtr); + Tcl_Preserve(msgPtr); switch ((enum options) index) { case MESSAGE_CGET: @@ -356,7 +358,7 @@ MessageWidgetObjCmd( break; } - Tcl_Release((ClientData) msgPtr); + Tcl_Release(msgPtr); return result; } @@ -388,7 +390,7 @@ DestroyMessage( Tcl_DeleteCommandFromToken(msgPtr->interp, msgPtr->widgetCmd); if (msgPtr->flags & REDRAW_PENDING) { - Tcl_CancelIdleCall(DisplayMessage, (ClientData) msgPtr); + Tcl_CancelIdleCall(DisplayMessage, msgPtr); } /* @@ -403,13 +405,13 @@ DestroyMessage( Tk_FreeTextLayout(msgPtr->textLayout); } if (msgPtr->textVarName != NULL) { - Tcl_UntraceVar(msgPtr->interp, msgPtr->textVarName, + Tcl_UntraceVar2(msgPtr->interp, msgPtr->textVarName, NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - MessageTextVarProc, (ClientData) msgPtr); + MessageTextVarProc, msgPtr); } Tk_FreeConfigOptions((char *) msgPtr, msgPtr->optionTable, msgPtr->tkwin); msgPtr->tkwin = NULL; - ckfree((char *) msgPtr); + ckfree(msgPtr); } /* @@ -438,7 +440,7 @@ ConfigureMessage( register Message *msgPtr, /* Information about widget; may or may not * already have values for some fields. */ int objc, /* Number of valid entries in argv. */ - Tcl_Obj *CONST objv[], /* Arguments. */ + Tcl_Obj *const objv[], /* Arguments. */ int flags) /* Flags to pass to Tk_ConfigureWidget. */ { Tk_SavedOptions savedOptions; @@ -448,9 +450,9 @@ ConfigureMessage( */ if (msgPtr->textVarName != NULL) { - Tcl_UntraceVar(interp, msgPtr->textVarName, + Tcl_UntraceVar2(interp, msgPtr->textVarName, NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - MessageTextVarProc, (ClientData) msgPtr); + MessageTextVarProc, msgPtr); } if (Tk_SetOptions(interp, (char *) msgPtr, msgPtr->optionTable, objc, objv, @@ -466,11 +468,11 @@ ConfigureMessage( */ if (msgPtr->textVarName != NULL) { - CONST char *value; + const char *value; - value = Tcl_GetVar(interp, msgPtr->textVarName, TCL_GLOBAL_ONLY); + value = Tcl_GetVar2(interp, msgPtr->textVarName, NULL, TCL_GLOBAL_ONLY); if (value == NULL) { - Tcl_SetVar(interp, msgPtr->textVarName, msgPtr->string, + Tcl_SetVar2(interp, msgPtr->textVarName, NULL, msgPtr->string, TCL_GLOBAL_ONLY); } else { if (msgPtr->string != NULL) { @@ -478,9 +480,9 @@ ConfigureMessage( } msgPtr->string = strcpy(ckalloc(strlen(value) + 1), value); } - Tcl_TraceVar(interp, msgPtr->textVarName, + Tcl_TraceVar2(interp, msgPtr->textVarName, NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - MessageTextVarProc, (ClientData) msgPtr); + MessageTextVarProc, msgPtr); } /* @@ -496,7 +498,7 @@ ConfigureMessage( } Tk_FreeSavedOptions(&savedOptions); - MessageWorldChanged((ClientData) msgPtr); + MessageWorldChanged(msgPtr); return TCL_OK; } @@ -525,9 +527,7 @@ MessageWorldChanged( XGCValues gcValues; GC gc = NULL; Tk_FontMetrics fm; - Message *msgPtr; - - msgPtr = (Message *) instanceData; + Message *msgPtr = instanceData; if (msgPtr->border != NULL) { Tk_SetBackgroundFromBorder(msgPtr->tkwin, msgPtr->border); @@ -557,7 +557,7 @@ MessageWorldChanged( ComputeMessageGeometry(msgPtr); if ((msgPtr->tkwin != NULL) && Tk_IsMapped(msgPtr->tkwin) && !(msgPtr->flags & REDRAW_PENDING)) { - Tcl_DoWhenIdle(DisplayMessage, (ClientData) msgPtr); + Tcl_DoWhenIdle(DisplayMessage, msgPtr); msgPtr->flags |= REDRAW_PENDING; } } @@ -666,7 +666,7 @@ static void DisplayMessage( ClientData clientData) /* Information about window. */ { - register Message *msgPtr = (Message *) clientData; + register Message *msgPtr = clientData; register Tk_Window tkwin = msgPtr->tkwin; int x, y; int borderWidth = msgPtr->highlightWidth; @@ -742,13 +742,13 @@ MessageEventProc( ClientData clientData, /* Information about window. */ XEvent *eventPtr) /* Information about event. */ { - Message *msgPtr = (Message *) clientData; + Message *msgPtr = clientData; if (((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) || (eventPtr->type == ConfigureNotify)) { goto redraw; } else if (eventPtr->type == DestroyNotify) { - DestroyMessage((char *) clientData); + DestroyMessage(clientData); } else if (eventPtr->type == FocusIn) { if (eventPtr->xfocus.detail != NotifyInferior) { msgPtr->flags |= GOT_FOCUS; @@ -768,7 +768,7 @@ MessageEventProc( redraw: if ((msgPtr->tkwin != NULL) && !(msgPtr->flags & REDRAW_PENDING)) { - Tcl_DoWhenIdle(DisplayMessage, (ClientData) msgPtr); + Tcl_DoWhenIdle(DisplayMessage, msgPtr); msgPtr->flags |= REDRAW_PENDING; } } @@ -795,7 +795,7 @@ static void MessageCmdDeletedProc( ClientData clientData) /* Pointer to widget record for widget. */ { - Message *msgPtr = (Message *) clientData; + Message *msgPtr = clientData; /* * This function could be invoked either because the window was destroyed @@ -831,12 +831,12 @@ static char * MessageTextVarProc( ClientData clientData, /* Information about message. */ Tcl_Interp *interp, /* Interpreter containing variable. */ - CONST char *name1, /* Name of variable. */ - CONST char *name2, /* Second part of variable name. */ + const char *name1, /* Name of variable. */ + const char *name2, /* Second part of variable name. */ int flags) /* Information about what happened. */ { - register Message *msgPtr = (Message *) clientData; - CONST char *value; + register Message *msgPtr = clientData; + const char *value; /* * If the variable is unset, then immediately recreate it unless the whole @@ -844,17 +844,37 @@ MessageTextVarProc( */ if (flags & TCL_TRACE_UNSETS) { - if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) { - Tcl_SetVar(interp, msgPtr->textVarName, msgPtr->string, + if (!Tcl_InterpDeleted(interp) && msgPtr->textVarName) { + ClientData probe = NULL; + + do { + probe = Tcl_VarTraceInfo(interp, + msgPtr->textVarName, + TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + MessageTextVarProc, probe); + if (probe == (ClientData)msgPtr) { + break; + } + } while (probe); + if (probe) { + /* + * We were able to fetch the unset trace for our + * textVarName, which means it is not unset and not + * the cause of this unset trace. Instead some outdated + * former variable must be, and we should ignore it. + */ + return NULL; + } + Tcl_SetVar2(interp, msgPtr->textVarName, NULL, msgPtr->string, TCL_GLOBAL_ONLY); - Tcl_TraceVar(interp, msgPtr->textVarName, + Tcl_TraceVar2(interp, msgPtr->textVarName, NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, MessageTextVarProc, clientData); } return NULL; } - value = Tcl_GetVar(interp, msgPtr->textVarName, TCL_GLOBAL_ONLY); + value = Tcl_GetVar2(interp, msgPtr->textVarName, NULL, TCL_GLOBAL_ONLY); if (value == NULL) { value = ""; } @@ -862,13 +882,13 @@ MessageTextVarProc( ckfree(msgPtr->string); } msgPtr->numChars = Tcl_NumUtfChars(value, -1); - msgPtr->string = (char *) ckalloc((unsigned) (strlen(value) + 1)); + msgPtr->string = ckalloc(strlen(value) + 1); strcpy(msgPtr->string, value); ComputeMessageGeometry(msgPtr); if ((msgPtr->tkwin != NULL) && Tk_IsMapped(msgPtr->tkwin) && !(msgPtr->flags & REDRAW_PENDING)) { - Tcl_DoWhenIdle(DisplayMessage, (ClientData) msgPtr); + Tcl_DoWhenIdle(DisplayMessage, msgPtr); msgPtr->flags |= REDRAW_PENDING; } return NULL; diff --git a/generic/tkObj.c b/generic/tkObj.c index f30742b..46f2da5 100644 --- a/generic/tkObj.c +++ b/generic/tkObj.c @@ -33,8 +33,8 @@ typedef struct PixelRep { (PTR2INT((objPtr)->internalRep.twoPtrValue.ptr1)) #define SET_COMPLEXPIXEL(objPtr, repPtr) \ - (objPtr)->internalRep.twoPtrValue.ptr1 = 0; \ - (objPtr)->internalRep.twoPtrValue.ptr2 = (VOID *) repPtr + (objPtr)->internalRep.twoPtrValue.ptr1 = NULL; \ + (objPtr)->internalRep.twoPtrValue.ptr2 = repPtr #define GET_COMPLEXPIXEL(objPtr) \ ((PixelRep *) (objPtr)->internalRep.twoPtrValue.ptr2) @@ -82,8 +82,8 @@ typedef struct WindowRep { */ static void DupMMInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr); -static void DupPixelInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr); -static void DupWindowInternalRep(Tcl_Obj *srcPtr,Tcl_Obj *copyPtr); +static void DupPixelInternalRep(Tcl_Obj *srcPtr, Tcl_Obj*copyPtr); +static void DupWindowInternalRep(Tcl_Obj *srcPtr,Tcl_Obj*copyPtr); static void FreeMMInternalRep(Tcl_Obj *objPtr); static void FreePixelInternalRep(Tcl_Obj *objPtr); static void FreeWindowInternalRep(Tcl_Obj *objPtr); @@ -99,7 +99,7 @@ static int SetWindowFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); * initial display-independant settings. */ -static Tcl_ObjType pixelObjType = { +static const Tcl_ObjType pixelObjType = { "pixel", /* name */ FreePixelInternalRep, /* freeIntRepProc */ DupPixelInternalRep, /* dupIntRepProc */ @@ -113,7 +113,7 @@ static Tcl_ObjType pixelObjType = { * initial display-independant settings. */ -static Tcl_ObjType mmObjType = { +static const Tcl_ObjType mmObjType = { "mm", /* name */ FreeMMInternalRep, /* freeIntRepProc */ DupMMInternalRep, /* dupIntRepProc */ @@ -126,7 +126,7 @@ static Tcl_ObjType mmObjType = { * Tcl object. */ -static Tcl_ObjType windowObjType = { +static const Tcl_ObjType windowObjType = { "window", /* name */ FreeWindowInternalRep, /* freeIntRepProc */ DupWindowInternalRep, /* dupIntRepProc */ @@ -147,14 +147,25 @@ static Tcl_ObjType windowObjType = { */ static ThreadSpecificData * -GetTypeCache() +GetTypeCache(void) { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = 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; } @@ -192,7 +203,7 @@ GetPixelsFromObjEx( int result, fresh; double d; PixelRep *pixelPtr; - static double bias[] = { + static const double bias[] = { 1.0, 10.0, 25.4, 0.35278 /*25.4 / 72.0*/ }; @@ -371,7 +382,7 @@ FreePixelInternalRep( if (!SIMPLE_PIXELREP(objPtr)) { PixelRep *pixelPtr = GET_COMPLEXPIXEL(objPtr); - ckfree((char *) pixelPtr); + ckfree(pixelPtr); } SET_SIMPLEPIXEL(objPtr, 0); objPtr->typePtr = NULL; @@ -408,7 +419,7 @@ DupPixelInternalRep( PixelRep *oldPtr, *newPtr; oldPtr = GET_COMPLEXPIXEL(srcPtr); - newPtr = (PixelRep *) ckalloc(sizeof(PixelRep)); + newPtr = ckalloc(sizeof(PixelRep)); newPtr->value = oldPtr->value; newPtr->units = oldPtr->units; newPtr->tkwin = oldPtr->tkwin; @@ -442,7 +453,8 @@ SetPixelFromAny( Tcl_Obj *objPtr) /* The object to convert. */ { const Tcl_ObjType *typePtr; - char *string, *rest; + const char *string; + char *rest; double d; int i, units; @@ -482,7 +494,7 @@ SetPixelFromAny( typePtr = objPtr->typePtr; if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) { - (*typePtr->freeIntRepProc)(objPtr); + typePtr->freeIntRepProc(objPtr); } objPtr->typePtr = &pixelObjType; @@ -491,7 +503,7 @@ SetPixelFromAny( if ((units < 0) && (i == d)) { SET_SIMPLEPIXEL(objPtr, i); } else { - PixelRep *pixelPtr = (PixelRep *) ckalloc(sizeof(PixelRep)); + PixelRep *pixelPtr = ckalloc(sizeof(PixelRep)); pixelPtr->value = d; pixelPtr->units = units; @@ -503,16 +515,9 @@ SetPixelFromAny( error: if (interp != NULL) { - /* - * Must copy string before resetting the result in case a caller is - * trying to convert the interpreter's result to pixels. - */ - - char buf[100]; - - sprintf(buf, "bad screen distance \"%.50s\"", string); - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, buf, NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad screen distance \"%.50s\"", string)); + Tcl_SetErrorCode(interp, "TK", "VALUE", "PIXELS", NULL); } return TCL_ERROR; } @@ -548,7 +553,7 @@ Tk_GetMMFromObj( int result; double d; MMRep *mmPtr; - static double bias[] = { + static const double bias[] = { 10.0, 25.4, 1.0, 0.35278 /*25.4 / 72.0*/ }; @@ -559,7 +564,7 @@ Tk_GetMMFromObj( } } - mmPtr = (MMRep *) objPtr->internalRep.twoPtrValue.ptr1; + mmPtr = objPtr->internalRep.twoPtrValue.ptr1; if (mmPtr->tkwin != tkwin) { d = mmPtr->value; if (mmPtr->units == -1) { @@ -598,7 +603,7 @@ static void FreeMMInternalRep( Tcl_Obj *objPtr) /* MM object with internal rep to free. */ { - ckfree((char *) objPtr->internalRep.twoPtrValue.ptr1); + ckfree(objPtr->internalRep.twoPtrValue.ptr1); objPtr->internalRep.twoPtrValue.ptr1 = NULL; objPtr->typePtr = NULL; } @@ -629,13 +634,13 @@ DupMMInternalRep( MMRep *oldPtr, *newPtr; copyPtr->typePtr = srcPtr->typePtr; - oldPtr = (MMRep *) srcPtr->internalRep.twoPtrValue.ptr1; - newPtr = (MMRep *) ckalloc(sizeof(MMRep)); + oldPtr = srcPtr->internalRep.twoPtrValue.ptr1; + newPtr = ckalloc(sizeof(MMRep)); newPtr->value = oldPtr->value; newPtr->units = oldPtr->units; newPtr->tkwin = oldPtr->tkwin; newPtr->returnValue = oldPtr->returnValue; - copyPtr->internalRep.twoPtrValue.ptr1 = (VOID *) newPtr; + copyPtr->internalRep.twoPtrValue.ptr1 = newPtr; } /* @@ -663,18 +668,18 @@ UpdateStringOfMM( { MMRep *mmPtr; char buffer[TCL_DOUBLE_SPACE]; - register int len; + size_t len; - mmPtr = (MMRep *) objPtr->internalRep.twoPtrValue.ptr1; + mmPtr = objPtr->internalRep.twoPtrValue.ptr1; /* assert( mmPtr->units == -1 && objPtr->bytes == NULL ); */ if ((mmPtr->units != -1) || (objPtr->bytes != NULL)) { Tcl_Panic("UpdateStringOfMM: false precondition"); } Tcl_PrintDouble(NULL, mmPtr->value, buffer); - len = (int)strlen(buffer); + len = strlen(buffer); - objPtr->bytes = (char *) ckalloc((unsigned) len + 1); + objPtr->bytes = ckalloc(len + 1); strcpy(objPtr->bytes, buffer); objPtr->length = len; } @@ -705,7 +710,8 @@ SetMMFromAny( { ThreadSpecificData *typeCache = GetTypeCache(); const Tcl_ObjType *typePtr; - char *string, *rest; + const char *string; + char *rest; double d; int units; MMRep *mmPtr; @@ -740,8 +746,9 @@ SetMMFromAny( */ error: - Tcl_AppendResult(interp, "bad screen distance \"", string, - "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad screen distance \"%s\"", string)); + Tcl_SetErrorCode(interp, "TK", "VALUE", "DISTANCE", NULL); return TCL_ERROR; } while ((*rest != '\0') && isspace(UCHAR(*rest))) { @@ -775,18 +782,18 @@ SetMMFromAny( typePtr = objPtr->typePtr; if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) { - (*typePtr->freeIntRepProc)(objPtr); + typePtr->freeIntRepProc(objPtr); } objPtr->typePtr = &mmObjType; - mmPtr = (MMRep *) ckalloc(sizeof(MMRep)); + mmPtr = ckalloc(sizeof(MMRep)); mmPtr->value = d; mmPtr->units = units; mmPtr->tkwin = NULL; mmPtr->returnValue = d; - objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) mmPtr; + objPtr->internalRep.twoPtrValue.ptr1 = mmPtr; return TCL_OK; } @@ -821,19 +828,19 @@ TkGetWindowFromObj( { TkMainInfo *mainPtr = ((TkWindow *) tkwin)->mainPtr; register WindowRep *winPtr; - int result; - result = Tcl_ConvertToType(interp, objPtr, &windowObjType); - if (result != TCL_OK) { - return result; + if (objPtr->typePtr != &windowObjType) { + int result = SetWindowFromAny(interp, objPtr); + if (result != TCL_OK) { + return result; + } } - winPtr = (WindowRep *) objPtr->internalRep.twoPtrValue.ptr1; + winPtr = objPtr->internalRep.twoPtrValue.ptr1; if (winPtr->tkwin == NULL || winPtr->mainPtr == NULL || winPtr->mainPtr != mainPtr - || winPtr->epoch != mainPtr->deletionEpoch) - { + || winPtr->epoch != mainPtr->deletionEpoch) { /* * Cache is invalid. */ @@ -885,18 +892,18 @@ SetWindowFromAny( * Free the old internalRep before setting the new one. */ - (void)Tcl_GetString(objPtr); + Tcl_GetString(objPtr); typePtr = objPtr->typePtr; if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) { - (*typePtr->freeIntRepProc)(objPtr); + typePtr->freeIntRepProc(objPtr); } - winPtr = (WindowRep *) ckalloc(sizeof(WindowRep)); + winPtr = ckalloc(sizeof(WindowRep)); winPtr->tkwin = NULL; winPtr->mainPtr = NULL; winPtr->epoch = 0; - objPtr->internalRep.twoPtrValue.ptr1 = (VOID*)winPtr; + objPtr->internalRep.twoPtrValue.ptr1 = winPtr; objPtr->typePtr = &windowObjType; return TCL_OK; @@ -928,11 +935,11 @@ DupWindowInternalRep( register WindowRep *oldPtr, *newPtr; oldPtr = srcPtr->internalRep.twoPtrValue.ptr1; - newPtr = (WindowRep *) ckalloc(sizeof(WindowRep)); + newPtr = ckalloc(sizeof(WindowRep)); newPtr->tkwin = oldPtr->tkwin; newPtr->mainPtr = oldPtr->mainPtr; newPtr->epoch = oldPtr->epoch; - copyPtr->internalRep.twoPtrValue.ptr1 = (VOID *)newPtr; + copyPtr->internalRep.twoPtrValue.ptr1 = newPtr; copyPtr->typePtr = srcPtr->typePtr; } @@ -958,7 +965,7 @@ static void FreeWindowInternalRep( Tcl_Obj *objPtr) /* Window object with internal rep to free. */ { - ckfree((char *) objPtr->internalRep.twoPtrValue.ptr1); + ckfree(objPtr->internalRep.twoPtrValue.ptr1); objPtr->internalRep.twoPtrValue.ptr1 = NULL; objPtr->typePtr = NULL; } @@ -966,6 +973,40 @@ FreeWindowInternalRep( /* *---------------------------------------------------------------------- * + * TkNewWindowObj -- + * + * This function allocates a new Tcl_Obj that refers to a particular to a + * particular Tk window. + * + * Results: + * A standard Tcl object reference, with refcount 0. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +Tcl_Obj * +TkNewWindowObj( + Tk_Window tkwin) +{ + Tcl_Obj *objPtr = Tcl_NewStringObj(Tk_PathName(tkwin), -1); + TkMainInfo *mainPtr = ((TkWindow *) tkwin)->mainPtr; + register WindowRep *winPtr; + + SetWindowFromAny(NULL, objPtr); + + winPtr = objPtr->internalRep.twoPtrValue.ptr1; + winPtr->tkwin = tkwin; + winPtr->mainPtr = mainPtr; + winPtr->epoch = mainPtr->deletionEpoch; + return objPtr; +} + +/* + *---------------------------------------------------------------------- + * * TkParsePadAmount -- * * This function parses a padding specification and returns the @@ -1004,11 +1045,11 @@ TkParsePadAmount( */ if (specObj->typePtr == &pixelObjType) { - if (Tk_GetPixelsFromObj(interp, tkwin, specObj, &firstInt) != TCL_OK) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "bad pad value \"", - Tcl_GetString(specObj), - "\": must be positive screen distance", NULL); + if (Tk_GetPixelsFromObj(interp, tkwin, specObj, &firstInt) != TCL_OK){ + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad pad value \"%s\": must be positive screen distance", + Tcl_GetString(specObj))); + Tcl_SetErrorCode(interp, "TK", "VALUE", "PADDING", "DIST", NULL); return TCL_ERROR; } secondInt = firstInt; @@ -1024,8 +1065,9 @@ TkParsePadAmount( return TCL_ERROR; } if (objc != 1 && objc != 2) { - Tcl_AppendResult(interp, - "wrong number of parts to pad specification", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "wrong number of parts to pad specification", -1)); + Tcl_SetErrorCode(interp, "TK", "VALUE", "PADDING", "PARTS", NULL); return TCL_ERROR; } @@ -1035,9 +1077,10 @@ TkParsePadAmount( if (Tk_GetPixelsFromObj(interp, tkwin, objv[0], &firstInt) != TCL_OK || (firstInt < 0)) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "bad pad value \"", Tcl_GetString(objv[0]), - "\": must be positive screen distance", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad pad value \"%s\": must be positive screen distance", + Tcl_GetString(objv[0]))); + Tcl_SetErrorCode(interp, "TK", "VALUE", "PADDING", "DIST", NULL); return TCL_ERROR; } @@ -1050,10 +1093,10 @@ TkParsePadAmount( secondInt = firstInt; } else if (Tk_GetPixelsFromObj(interp, tkwin, objv[1], &secondInt) != TCL_OK || (secondInt < 0)) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "bad 2nd pad value \"", - Tcl_GetString(objv[1]), - "\": must be positive screen distance", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad 2nd pad value \"%s\": must be positive screen distance", + Tcl_GetString(objv[1]))); + Tcl_SetErrorCode(interp, "TK", "VALUE", "PADDING", "DIST", NULL); return TCL_ERROR; } @@ -1080,7 +1123,7 @@ TkParsePadAmount( * None * * Side effects: - * All instances of Tcl_ObjType structues used in Tk are registered with + * All instances of Tcl_ObjType structures used in Tk are registered with * Tcl. * *---------------------------------------------------------------------- @@ -1095,7 +1138,6 @@ TkRegisterObjTypes(void) Tcl_RegisterObjType(&tkCursorObjType); Tcl_RegisterObjType(&tkFontObjType); Tcl_RegisterObjType(&mmObjType); - Tcl_RegisterObjType(&tkOptionObjType); Tcl_RegisterObjType(&pixelObjType); Tcl_RegisterObjType(&tkStateKeyObjType); Tcl_RegisterObjType(&windowObjType); diff --git a/generic/tkOldConfig.c b/generic/tkOldConfig.c index 0231014..f20f38f 100644 --- a/generic/tkOldConfig.c +++ b/generic/tkOldConfig.c @@ -12,7 +12,7 @@ * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ -#include "tkPort.h" +#include "tkInt.h" /* * Values for "flags" field of Tk_ConfigSpec structures. Be sure to coordinate @@ -33,12 +33,12 @@ static int DoConfig(Tcl_Interp *interp, Tk_Window tkwin, Tk_ConfigSpec *specPtr, Tk_Uid value, int valueIsUid, char *widgRec); static Tk_ConfigSpec * FindConfigSpec(Tcl_Interp *interp, - Tk_ConfigSpec *specs, CONST char *argvName, + Tk_ConfigSpec *specs, const char *argvName, int needFlags, int hateFlags); static char * FormatConfigInfo(Tcl_Interp *interp, Tk_Window tkwin, - Tk_ConfigSpec *specPtr, char *widgRec); -static CONST char * FormatConfigValue(Tcl_Interp *interp, Tk_Window tkwin, - Tk_ConfigSpec *specPtr, char *widgRec, + const Tk_ConfigSpec *specPtr, char *widgRec); +static const char * FormatConfigValue(Tcl_Interp *interp, Tk_Window tkwin, + const Tk_ConfigSpec *specPtr, char *widgRec, char *buffer, Tcl_FreeProc **freeProcPtr); static Tk_ConfigSpec * GetCachedSpecs(Tcl_Interp *interp, const Tk_ConfigSpec *staticSpecs); @@ -72,9 +72,9 @@ Tk_ConfigureWidget( Tcl_Interp *interp, /* Interpreter for error reporting. */ Tk_Window tkwin, /* Window containing widget (needed to set up * X resources). */ - Tk_ConfigSpec *specs, /* Describes legal options. */ + const Tk_ConfigSpec *specs, /* Describes legal options. */ int argc, /* Number of elements in argv. */ - CONST char **argv, /* Command-line options. */ + const char **argv, /* Command-line options. */ char *widgRec, /* Record whose fields are to be modified. * Values must be properly initialized. */ int flags) /* Used to specify additional flags that must @@ -82,7 +82,7 @@ Tk_ConfigureWidget( * considered. Also, may have * TK_CONFIG_ARGV_ONLY set. */ { - register Tk_ConfigSpec *specPtr; + register Tk_ConfigSpec *specPtr, *staticSpecs; Tk_Uid value; /* Value of option from database. */ int needFlags; /* Specs must contain this set of flags or * else they are not considered. */ @@ -95,7 +95,8 @@ Tk_ConfigureWidget( * we're on our way out of the application */ - Tcl_AppendResult(interp, "NULL main window", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj("NULL main window", -1)); + Tcl_SetErrorCode(interp, "TK", "NO_MAIN_WINDOW", NULL); return TCL_ERROR; } @@ -110,10 +111,10 @@ Tk_ConfigureWidget( * Get the build of the config for this interpreter. */ - specs = GetCachedSpecs(interp, specs); + staticSpecs = GetCachedSpecs(interp, specs); - for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) { - specPtr->specFlags &= ~TK_CONFIG_OPTION_SPECIFIED; + for (specPtr = staticSpecs; specPtr->type != TK_CONFIG_END; specPtr++) { + specPtr->specFlags &= ~TK_CONFIG_OPTION_SPECIFIED; } /* @@ -122,14 +123,14 @@ Tk_ConfigureWidget( */ for ( ; argc > 0; argc -= 2, argv += 2) { - CONST char *arg; + const char *arg; if (flags & TK_CONFIG_OBJS) { - arg = Tcl_GetStringFromObj((Tcl_Obj *) *argv, NULL); + arg = Tcl_GetString((Tcl_Obj *) *argv); } else { arg = *argv; } - specPtr = FindConfigSpec(interp, specs, arg, needFlags, hateFlags); + specPtr = FindConfigSpec(interp, staticSpecs, arg, needFlags, hateFlags); if (specPtr == NULL) { return TCL_ERROR; } @@ -139,7 +140,9 @@ Tk_ConfigureWidget( */ if (argc < 2) { - Tcl_AppendResult(interp, "value for \"", arg, "\" missing", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "value for \"%s\" missing", arg)); + Tcl_SetErrorCode(interp, "TK", "VALUE_MISSING", NULL); return TCL_ERROR; } if (flags & TK_CONFIG_OBJS) { @@ -148,11 +151,8 @@ Tk_ConfigureWidget( arg = argv[1]; } if (DoConfig(interp, tkwin, specPtr, arg, 0, widgRec) != TCL_OK) { - char msg[100]; - - sprintf(msg, "\n (processing \"%.40s\" option)", - specPtr->argvName); - Tcl_AddErrorInfo(interp, msg); + Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf( + "\n (processing \"%.40s\" option)",specPtr->argvName)); return TCL_ERROR; } if (!(flags & TK_CONFIG_ARGV_ONLY)) { @@ -167,7 +167,7 @@ Tk_ConfigureWidget( */ if (!(flags & TK_CONFIG_ARGV_ONLY)) { - for (specPtr=specs; specPtr->type!=TK_CONFIG_END; specPtr++) { + for (specPtr = staticSpecs; specPtr->type != TK_CONFIG_END; specPtr++) { if ((specPtr->specFlags & TK_CONFIG_OPTION_SPECIFIED) || (specPtr->argvName == NULL) || (specPtr->type == TK_CONFIG_SYNONYM)) { @@ -184,12 +184,10 @@ Tk_ConfigureWidget( if (value != NULL) { if (DoConfig(interp, tkwin, specPtr, value, 1, widgRec) != TCL_OK) { - char msg[200]; - - sprintf(msg, "\n (%s \"%.50s\" in widget \"%.50s\")", - "database entry for", - specPtr->dbName, Tk_PathName(tkwin)); - Tcl_AddErrorInfo(interp, msg); + Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf( + "\n (%s \"%.50s\" in widget \"%.50s\")", + "database entry for", specPtr->dbName, + Tk_PathName(tkwin))); return TCL_ERROR; } } else { @@ -202,13 +200,10 @@ Tk_ConfigureWidget( & TK_CONFIG_DONT_SET_DEFAULT)) { if (DoConfig(interp, tkwin, specPtr, value, 1, widgRec) != TCL_OK) { - char msg[200]; - - sprintf(msg, + Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf( "\n (%s \"%.50s\" in widget \"%.50s\")", - "default value for", - specPtr->dbName, Tk_PathName(tkwin)); - Tcl_AddErrorInfo(interp, msg); + "default value for", specPtr->dbName, + Tk_PathName(tkwin))); return TCL_ERROR; } } @@ -243,7 +238,7 @@ FindConfigSpec( Tcl_Interp *interp, /* Used for reporting errors. */ Tk_ConfigSpec *specs, /* Pointer to table of configuration * specifications for a widget. */ - CONST char *argvName, /* Name (suitable for use in a "config" + const char *argvName, /* Name (suitable for use in a "config" * command) identifying particular option. */ int needFlags, /* Flags that must be present in matching * entry. */ @@ -275,15 +270,18 @@ FindConfigSpec( goto gotMatch; } if (matchPtr != NULL) { - Tcl_AppendResult(interp, "ambiguous option \"", argvName, - "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "ambiguous option \"%s\"", argvName)); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "OPTION", argvName,NULL); return NULL; } matchPtr = specPtr; } if (matchPtr == NULL) { - Tcl_AppendResult(interp, "unknown option \"", argvName, "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "unknown option \"%s\"", argvName)); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "OPTION", argvName, NULL); return NULL; } @@ -297,8 +295,11 @@ FindConfigSpec( if (specPtr->type == TK_CONFIG_SYNONYM) { for (specPtr = specs; ; specPtr++) { if (specPtr->type == TK_CONFIG_END) { - Tcl_AppendResult(interp, "couldn't find synonym for option \"", - argvName, "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "couldn't find synonym for option \"%s\"", + argvName)); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "OPTION", argvName, + NULL); return NULL; } if ((specPtr->dbName == matchPtr->dbName) @@ -375,7 +376,7 @@ DoConfig( if (nullValue) { newStr = NULL; } else { - newStr = (char *) ckalloc((unsigned) (strlen(value) + 1)); + newStr = ckalloc(strlen(value) + 1); strcpy(newStr, value); } oldStr = *((char **) ptr); @@ -544,20 +545,17 @@ DoConfig( break; } case TK_CONFIG_CUSTOM: - if ((*specPtr->customPtr->parseProc)( - specPtr->customPtr->clientData, interp, tkwin, value, - widgRec, specPtr->offset) != TCL_OK) { + if (specPtr->customPtr->parseProc(specPtr->customPtr->clientData, + interp, tkwin, value, widgRec, specPtr->offset)!=TCL_OK) { return TCL_ERROR; } break; - default: { - char buf[64 + TCL_INTEGER_SPACE]; - - sprintf(buf, "bad config table: unknown type %d", specPtr->type); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + default: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad config table: unknown type %d", specPtr->type)); + Tcl_SetErrorCode(interp, "TK", "BAD_CONFIG", NULL); return TCL_ERROR; } - } specPtr++; } while ((specPtr->argvName == NULL) && (specPtr->type != TK_CONFIG_END)); return TCL_OK; @@ -595,20 +593,20 @@ int Tk_ConfigureInfo( Tcl_Interp *interp, /* Interpreter for error reporting. */ Tk_Window tkwin, /* Window corresponding to widgRec. */ - Tk_ConfigSpec *specs, /* Describes legal options. */ + const Tk_ConfigSpec *specs, /* Describes legal options. */ char *widgRec, /* Record whose fields contain current values * for options. */ - CONST char *argvName, /* If non-NULL, indicates a single option + const char *argvName, /* If non-NULL, indicates a single option * whose info is to be returned. Otherwise * info is returned for all options. */ int flags) /* Used to specify additional flags that must * be present in config specs for them to be * considered. */ { - register Tk_ConfigSpec *specPtr; + register Tk_ConfigSpec *specPtr, *staticSpecs; int needFlags, hateFlags; char *list; - char *leader = "{"; + const char *leader = "{"; needFlags = flags & ~(TK_CONFIG_USER_BIT - 1); if (Tk_Depth(tkwin) <= 1) { @@ -621,22 +619,23 @@ Tk_ConfigureInfo( * Get the build of the config for this interpreter. */ - specs = GetCachedSpecs(interp, specs); + staticSpecs = GetCachedSpecs(interp, specs); /* * If information is only wanted for a single configuration spec, then * handle that one spec specially. */ - Tcl_SetResult(interp, NULL, TCL_STATIC); + Tcl_ResetResult(interp); if (argvName != NULL) { - specPtr = FindConfigSpec(interp, specs, argvName, needFlags,hateFlags); + specPtr = FindConfigSpec(interp, staticSpecs, argvName, needFlags, + hateFlags); if (specPtr == NULL) { return TCL_ERROR; } - Tcl_SetResult(interp, - FormatConfigInfo(interp, tkwin, specPtr, widgRec), - TCL_DYNAMIC); + list = FormatConfigInfo(interp, tkwin, specPtr, widgRec); + Tcl_SetObjResult(interp, Tcl_NewStringObj(list, -1)); + ckfree(list); return TCL_OK; } @@ -645,7 +644,7 @@ Tk_ConfigureInfo( * information. */ - for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) { + for (specPtr = staticSpecs; specPtr->type != TK_CONFIG_END; specPtr++) { if ((argvName != NULL) && (specPtr->argvName != argvName)) { continue; } @@ -687,13 +686,13 @@ FormatConfigInfo( Tcl_Interp *interp, /* Interpreter to use for things like * floating-point precision. */ Tk_Window tkwin, /* Window corresponding to widget. */ - register Tk_ConfigSpec *specPtr, + register const Tk_ConfigSpec *specPtr, /* Pointer to information describing * option. */ char *widgRec) /* Pointer to record holding current values of * info for widget. */ { - CONST char *argv[6]; + const char *argv[6]; char *result; char buffer[200]; Tcl_FreeProc *freeProc = NULL; @@ -722,9 +721,9 @@ FormatConfigInfo( result = Tcl_Merge(5, argv); if (freeProc != NULL) { if ((freeProc == TCL_DYNAMIC) || (freeProc == (Tcl_FreeProc *) free)) { - ckfree((char *)argv[4]); + ckfree((char *) argv[4]); } else { - (*freeProc)((char *)argv[4]); + freeProc((char *) argv[4]); } } return result; @@ -750,11 +749,11 @@ FormatConfigInfo( *---------------------------------------------------------------------- */ -static CONST char * +static const char * FormatConfigValue( Tcl_Interp *interp, /* Interpreter for use in real conversions. */ Tk_Window tkwin, /* Window corresponding to widget. */ - Tk_ConfigSpec *specPtr, /* Pointer to information describing option. + const Tk_ConfigSpec *specPtr, /* Pointer to information describing option. * Must not point to a synonym option. */ char *widgRec, /* Pointer to record holding current values of * info for widget. */ @@ -764,7 +763,7 @@ FormatConfigValue( * function to free the result, or NULL if * result is static. */ { - CONST char *ptr, *result; + const char *ptr, *result; *freeProcPtr = NULL; ptr = widgRec + specPtr->offset; @@ -873,9 +872,8 @@ FormatConfigValue( break; } case TK_CONFIG_CUSTOM: - result = (*specPtr->customPtr->printProc)( - specPtr->customPtr->clientData, tkwin, widgRec, - specPtr->offset, freeProcPtr); + result = specPtr->customPtr->printProc(specPtr->customPtr->clientData, + tkwin, widgRec, specPtr->offset, freeProcPtr); break; default: result = "?? unknown type ??"; @@ -907,10 +905,10 @@ int Tk_ConfigureValue( Tcl_Interp *interp, /* Interpreter for error reporting. */ Tk_Window tkwin, /* Window corresponding to widgRec. */ - Tk_ConfigSpec *specs, /* Describes legal options. */ + const Tk_ConfigSpec *specs, /* Describes legal options. */ char *widgRec, /* Record whose fields contain current values * for options. */ - CONST char *argvName, /* Gives the command-line name for the option + const char *argvName, /* Gives the command-line name for the option * whose value is to be returned. */ int flags) /* Used to specify additional flags that must * be present in config specs for them to be @@ -919,7 +917,7 @@ Tk_ConfigureValue( Tk_ConfigSpec *specPtr; int needFlags, hateFlags; Tcl_FreeProc *freeProc; - CONST char *result; + const char *result; char buffer[200]; needFlags = flags & ~(TK_CONFIG_USER_BIT - 1); @@ -933,20 +931,20 @@ Tk_ConfigureValue( * Get the build of the config for this interpreter. */ - specs = GetCachedSpecs(interp, specs); + specPtr = GetCachedSpecs(interp, specs); - specPtr = FindConfigSpec(interp, specs, argvName, needFlags, hateFlags); + specPtr = FindConfigSpec(interp, specPtr, argvName, needFlags, hateFlags); if (specPtr == NULL) { return TCL_ERROR; } result = FormatConfigValue(interp, tkwin, specPtr, widgRec, buffer, &freeProc); - Tcl_SetResult(interp, (char *) result, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_NewStringObj(result, -1)); if (freeProc != NULL) { if ((freeProc == TCL_DYNAMIC) || (freeProc == (Tcl_FreeProc *) free)) { - ckfree((char *)result); + ckfree((char *) result); } else { - (*freeProc)((char *)result); + freeProc((char *) result); } } return TCL_OK; @@ -976,7 +974,7 @@ Tk_ConfigureValue( /* ARGSUSED */ void Tk_FreeOptions( - Tk_ConfigSpec *specs, /* Describes legal options. */ + const Tk_ConfigSpec *specs, /* Describes legal options. */ char *widgRec, /* Record whose fields contain current values * for options. */ Display *display, /* X display; needed for freeing some @@ -985,7 +983,7 @@ Tk_FreeOptions( * be present in config specs for them to be * considered. */ { - register Tk_ConfigSpec *specPtr; + register const Tk_ConfigSpec *specPtr; char *ptr; for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) { @@ -1073,13 +1071,13 @@ GetCachedSpecs( * self-initializing code. */ - specCacheTablePtr = (Tcl_HashTable *) + specCacheTablePtr = Tcl_GetAssocData(interp, "tkConfigSpec.threadTable", NULL); if (specCacheTablePtr == NULL) { - specCacheTablePtr = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); + specCacheTablePtr = ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(specCacheTablePtr, TCL_ONE_WORD_KEYS); Tcl_SetAssocData(interp, "tkConfigSpec.threadTable", - DeleteSpecCacheTable, (ClientData) specCacheTablePtr); + DeleteSpecCacheTable, specCacheTablePtr); } /* @@ -1109,9 +1107,9 @@ GetCachedSpecs( * from the master copy. */ - cachedSpecs = (Tk_ConfigSpec *) ckalloc(entrySpace); + cachedSpecs = ckalloc(entrySpace); memcpy(cachedSpecs, staticSpecs, entrySpace); - Tcl_SetHashValue(entryPtr, (ClientData) cachedSpecs); + Tcl_SetHashValue(entryPtr, cachedSpecs); /* * Finally, go through and replace database names, database classes @@ -1133,7 +1131,7 @@ GetCachedSpecs( } } } else { - cachedSpecs = (Tk_ConfigSpec *) Tcl_GetHashValue(entryPtr); + cachedSpecs = Tcl_GetHashValue(entryPtr); } return cachedSpecs; @@ -1161,7 +1159,7 @@ DeleteSpecCacheTable( ClientData clientData, Tcl_Interp *interp) { - Tcl_HashTable *tablePtr = (Tcl_HashTable *) clientData; + Tcl_HashTable *tablePtr = clientData; Tcl_HashEntry *entryPtr; Tcl_HashSearch search; @@ -1171,10 +1169,10 @@ DeleteSpecCacheTable( * Someone else deallocates the Tk_Uids themselves. */ - ckfree((char *) Tcl_GetHashValue(entryPtr)); + ckfree(Tcl_GetHashValue(entryPtr)); } Tcl_DeleteHashTable(tablePtr); - ckfree((char *) tablePtr); + ckfree(tablePtr); } /* diff --git a/generic/tkOldTest.c b/generic/tkOldTest.c index cfbce23..f78ebba 100644 --- a/generic/tkOldTest.c +++ b/generic/tkOldTest.c @@ -16,6 +16,12 @@ */ #define USE_OLD_IMAGE +#ifndef USE_TCL_STUBS +# define USE_TCL_STUBS +#endif +#ifndef USE_TK_STUBS +# define USE_TK_STUBS +#endif #include "tkInt.h" /* @@ -67,16 +73,17 @@ static Tk_ImageType imageType = { ImageFree, /* freeProc */ ImageDelete, /* deleteProc */ NULL, /* postscriptPtr */ - NULL /* nextPtr */ + NULL, /* nextPtr */ + NULL }; /* * Forward declarations for functions defined later in this file: */ -static int ImageCmd(ClientData dummy, - Tcl_Interp *interp, int argc, CONST char **argv); -MODULE_SCOPE int TkOldTestInit(Tcl_Interp *interp); +static int ImageObjCmd(ClientData dummy, + Tcl_Interp *interp, int objc, + Tcl_Obj * const objv[]); /* @@ -142,7 +149,7 @@ ImageCreate( * will be returned in later callbacks. */ { TImageMaster *timPtr; - char *varName; + const char *varName; int i; varName = "log"; @@ -160,17 +167,17 @@ ImageCreate( varName = argv[i+1]; } - timPtr = (TImageMaster *) ckalloc(sizeof(TImageMaster)); + timPtr = ckalloc(sizeof(TImageMaster)); timPtr->master = master; timPtr->interp = interp; timPtr->width = 30; timPtr->height = 15; - timPtr->imageName = (char *) ckalloc((unsigned) (strlen(name) + 1)); + timPtr->imageName = ckalloc(strlen(name) + 1); strcpy(timPtr->imageName, name); - timPtr->varName = (char *) ckalloc((unsigned) (strlen(varName) + 1)); + timPtr->varName = ckalloc(strlen(varName) + 1); strcpy(timPtr->varName, varName); - Tcl_CreateCommand(interp, name, ImageCmd, (ClientData) timPtr, NULL); - *clientDataPtr = (ClientData) timPtr; + Tcl_CreateObjCommand(interp, name, ImageObjCmd, timPtr, NULL); + *clientDataPtr = timPtr; Tk_ImageChanged(master, 0, 0, 30, 15, 30, 15); return TCL_OK; } @@ -178,7 +185,7 @@ ImageCreate( /* *---------------------------------------------------------------------- * - * ImageCmd -- + * ImageObjCmd -- * * This function implements the commands corresponding to individual * images. @@ -194,38 +201,37 @@ ImageCreate( /* ARGSUSED */ static int -ImageCmd( +ImageObjCmd( ClientData clientData, /* Main window for application. */ Tcl_Interp *interp, /* Current interpreter. */ - int argc, /* Number of arguments. */ - CONST char **argv) /* Argument strings. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument strings. */ { - TImageMaster *timPtr = (TImageMaster *) clientData; + TImageMaster *timPtr = clientData; int x, y, width, height; - if (argc < 2) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], "option ?arg arg ...?", NULL); + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); return TCL_ERROR; } - if (strcmp(argv[1], "changed") == 0) { - if (argc != 8) { - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " changed x y width height imageWidth imageHeight", NULL); + if (strcmp(Tcl_GetString(objv[1]), "changed") == 0) { + if (objc != 8) { + Tcl_WrongNumArgs(interp, 1, objv, "changed x y width height" + " imageWidth imageHeight"); return TCL_ERROR; } - if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK) - || (Tcl_GetInt(interp, argv[3], &y) != TCL_OK) - || (Tcl_GetInt(interp, argv[4], &width) != TCL_OK) - || (Tcl_GetInt(interp, argv[5], &height) != TCL_OK) - || (Tcl_GetInt(interp, argv[6], &timPtr->width) != TCL_OK) - || (Tcl_GetInt(interp, argv[7], &timPtr->height) != TCL_OK)) { + if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK) + || (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK) + || (Tcl_GetIntFromObj(interp, objv[4], &width) != TCL_OK) + || (Tcl_GetIntFromObj(interp, objv[5], &height) != TCL_OK) + || (Tcl_GetIntFromObj(interp, objv[6], &timPtr->width) != TCL_OK) + || (Tcl_GetIntFromObj(interp, objv[7], &timPtr->height) != TCL_OK)) { return TCL_ERROR; } Tk_ImageChanged(timPtr->master, x, y, width, height, timPtr->width, timPtr->height); } else { - Tcl_AppendResult(interp, "bad option \"", argv[1], + Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[1]), "\": must be changed", NULL); return TCL_ERROR; } @@ -256,21 +262,21 @@ ImageGet( * used. */ ClientData clientData) /* Pointer to TImageMaster for image. */ { - TImageMaster *timPtr = (TImageMaster *) clientData; + TImageMaster *timPtr = clientData; TImageInstance *instPtr; char buffer[100]; XGCValues gcValues; sprintf(buffer, "%s get", timPtr->imageName); - Tcl_SetVar(timPtr->interp, timPtr->varName, buffer, + Tcl_SetVar2(timPtr->interp, timPtr->varName, NULL, buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT); - instPtr = (TImageInstance *) ckalloc(sizeof(TImageInstance)); + instPtr = ckalloc(sizeof(TImageInstance)); instPtr->masterPtr = timPtr; instPtr->fg = Tk_GetColor(timPtr->interp, tkwin, "#ff0000"); gcValues.foreground = instPtr->fg->pixel; instPtr->gc = Tk_GetGC(tkwin, GCForeground, &gcValues); - return (ClientData) instPtr; + return instPtr; } /* @@ -303,14 +309,14 @@ ImageDisplay( /* Coordinates in drawable corresponding to * imageX and imageY. */ { - TImageInstance *instPtr = (TImageInstance *) clientData; + TImageInstance *instPtr = clientData; char buffer[200 + TCL_INTEGER_SPACE * 6]; sprintf(buffer, "%s display %d %d %d %d %d %d", instPtr->masterPtr->imageName, imageX, imageY, width, height, drawableX, drawableY); - Tcl_SetVar(instPtr->masterPtr->interp, instPtr->masterPtr->varName, buffer, - TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT); + Tcl_SetVar2(instPtr->masterPtr->interp, instPtr->masterPtr->varName, NULL, + buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT); if (width > (instPtr->masterPtr->width - imageX)) { width = instPtr->masterPtr->width - imageX; } @@ -348,15 +354,15 @@ ImageFree( ClientData clientData, /* Pointer to TImageInstance for instance. */ Display *display) /* Display where image was to be drawn. */ { - TImageInstance *instPtr = (TImageInstance *) clientData; + TImageInstance *instPtr = clientData; char buffer[200]; sprintf(buffer, "%s free", instPtr->masterPtr->imageName); - Tcl_SetVar(instPtr->masterPtr->interp, instPtr->masterPtr->varName, buffer, - TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT); + Tcl_SetVar2(instPtr->masterPtr->interp, instPtr->masterPtr->varName, NULL, + buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT); Tk_FreeColor(instPtr->fg); Tk_FreeGC(display, instPtr->gc); - ckfree((char *) instPtr); + ckfree(instPtr); } /* @@ -382,17 +388,17 @@ ImageDelete( * this function is called, no more instances * exist. */ { - TImageMaster *timPtr = (TImageMaster *) clientData; + TImageMaster *timPtr = clientData; char buffer[100]; sprintf(buffer, "%s delete", timPtr->imageName); - Tcl_SetVar(timPtr->interp, timPtr->varName, buffer, + Tcl_SetVar2(timPtr->interp, timPtr->varName, NULL, buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT); Tcl_DeleteCommand(timPtr->interp, timPtr->imageName); ckfree(timPtr->imageName); ckfree(timPtr->varName); - ckfree((char *) timPtr); + ckfree(timPtr); } /* diff --git a/generic/tkOption.c b/generic/tkOption.c index 95b140d..545a9b9 100644 --- a/generic/tkOption.c +++ b/generic/tkOption.c @@ -221,9 +221,9 @@ static int GetDefaultOptions(Tcl_Interp *interp, static ElArray * NewArray(int numEls); static void OptionThreadExitProc(ClientData clientData); static void OptionInit(TkMainInfo *mainPtr); -static int ParsePriority(Tcl_Interp *interp, char *string); +static int ParsePriority(Tcl_Interp *interp, const char *string); static int ReadOptionFile(Tcl_Interp *interp, Tk_Window tkwin, - char *fileName, int priority); + const char *fileName, int priority); static void SetupStacks(TkWindow *winPtr, int leaf); /* @@ -246,8 +246,8 @@ void Tk_AddOption( Tk_Window tkwin, /* Window token; option will be associated * with main window for this window. */ - CONST char *name, /* Multi-element name of option. */ - CONST char *value, /* String value for option. */ + const char *name, /* Multi-element name of option. */ + const char *value, /* String value for option. */ int priority) /* Overall priority level to use for this * option, such as TK_USER_DEFAULT_PRIO or * TK_INTERACTIVE_PRIO. Must be between 0 and @@ -257,13 +257,13 @@ Tk_AddOption( register ElArray **arrayPtrPtr; register Element *elPtr; Element newEl; - register CONST char *p; - CONST char *field; + register const char *p; + const char *field; int count, firstField; ptrdiff_t length; #define TMP_SIZE 100 char tmp[TMP_SIZE+1]; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (winPtr->mainPtr->optionRootPtr == NULL) { @@ -400,8 +400,8 @@ Tk_Uid Tk_GetOption( Tk_Window tkwin, /* Token for window that option is associated * with. */ - CONST char *name, /* Name of option. */ - CONST char *className) /* Class of option. NULL means there is no + const char *name, /* Name of option. */ + const char *className) /* Class of option. NULL means there is no * class for this option: just check for * name. */ { @@ -411,7 +411,7 @@ Tk_GetOption( register int count; StackLevel *levelPtr; int stackDepth[NUM_STACKS]; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* @@ -475,16 +475,16 @@ Tk_GetOption( */ for (elPtr = tsdPtr->stacks[EXACT_LEAF_NAME]->els, - count = stackDepth[EXACT_LEAF_NAME]; count > 0; - elPtr++, count--) { + count = stackDepth[EXACT_LEAF_NAME]; count > 0; + elPtr++, count--) { if ((elPtr->nameUid == nameId) && (elPtr->priority > bestPtr->priority)) { bestPtr = elPtr; } } for (elPtr = tsdPtr->stacks[WILDCARD_LEAF_NAME]->els, - count = stackDepth[WILDCARD_LEAF_NAME]; count > 0; - elPtr++, count--) { + count = stackDepth[WILDCARD_LEAF_NAME]; count > 0; + elPtr++, count--) { if ((elPtr->nameUid == nameId) && (elPtr->priority > bestPtr->priority)) { bestPtr = elPtr; @@ -494,16 +494,16 @@ Tk_GetOption( if (className != NULL) { classId = Tk_GetUid(className); for (elPtr = tsdPtr->stacks[EXACT_LEAF_CLASS]->els, - count = stackDepth[EXACT_LEAF_CLASS]; count > 0; - elPtr++, count--) { + count = stackDepth[EXACT_LEAF_CLASS]; count > 0; + elPtr++, count--) { if ((elPtr->nameUid == classId) && (elPtr->priority > bestPtr->priority)) { bestPtr = elPtr; } } for (elPtr = tsdPtr->stacks[WILDCARD_LEAF_CLASS]->els, - count = stackDepth[WILDCARD_LEAF_CLASS]; count > 0; - elPtr++, count--) { + count = stackDepth[WILDCARD_LEAF_CLASS]; count > 0; + elPtr++, count--) { if ((elPtr->nameUid == classId) && (elPtr->priority > bestPtr->priority)) { bestPtr = elPtr; @@ -523,24 +523,25 @@ Tk_GetOption( Tk_Uid nodeId, winClassId, winNameId; unsigned int classNameLength; register Element *nodePtr, *leafPtr; - static int searchOrder[] = { + static const int searchOrder[] = { EXACT_NODE_NAME, WILDCARD_NODE_NAME, EXACT_NODE_CLASS, WILDCARD_NODE_CLASS, -1 }; - int *currentPtr, currentStack, leafCount; + const int *currentPtr; + int currentStack, leafCount; /* * Extract the masquerade class name from the name field. */ - classNameLength = (unsigned int)(masqName - name); - masqClass = (char *) ckalloc(classNameLength + 1); + classNameLength = (unsigned) (masqName - name); + masqClass = ckalloc(classNameLength + 1); strncpy(masqClass, name, classNameLength); masqClass[classNameLength] = '\0'; winClassId = Tk_GetUid(masqClass); ckfree(masqClass); - winNameId = ((TkWindow *)tkwin)->nameUid; + winNameId = ((TkWindow *) tkwin)->nameUid; levelPtr = &tsdPtr->levels[tsdPtr->curLevel]; @@ -612,17 +613,15 @@ Tk_OptionObjCmd( ClientData clientData, /* Main window associated with interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of Tcl_Obj arguments. */ - Tcl_Obj *CONST objv[]) /* Tcl_Obj arguments. */ + Tcl_Obj *const objv[]) /* Tcl_Obj arguments. */ { - Tk_Window tkwin = (Tk_Window) clientData; + Tk_Window tkwin = clientData; int index, result; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - - static CONST char *optionCmds[] = { + static const char *const optionCmds[] = { "add", "clear", "get", "readfile", NULL }; - enum optionVals { OPTION_ADD, OPTION_CLEAR, OPTION_GET, OPTION_READFILE }; @@ -632,8 +631,8 @@ Tk_OptionObjCmd( return TCL_ERROR; } - result = Tcl_GetIndexFromObj(interp, objv[1], optionCmds, "option", 0, - &index); + result = Tcl_GetIndexFromObjStruct(interp, objv[1], optionCmds, + sizeof(char *), "option", 0, &index); if (result != TCL_OK) { return result; } @@ -642,6 +641,7 @@ Tk_OptionObjCmd( switch ((enum optionVals) index) { case OPTION_ADD: { int priority; + if ((objc != 4) && (objc != 5)) { Tcl_WrongNumArgs(interp, 2, objv, "pattern value ?priority?"); return TCL_ERROR; @@ -661,13 +661,12 @@ Tk_OptionObjCmd( } case OPTION_CLEAR: { - TkMainInfo *mainPtr; + TkMainInfo *mainPtr = ((TkWindow *) tkwin)->mainPtr; if (objc != 2) { Tcl_WrongNumArgs(interp, 2, objv, ""); return TCL_ERROR; } - mainPtr = ((TkWindow *) tkwin)->mainPtr; if (mainPtr->optionRootPtr != NULL) { ClearOptionTree(mainPtr->optionRootPtr); mainPtr->optionRootPtr = NULL; @@ -691,7 +690,7 @@ Tk_OptionObjCmd( value = Tk_GetOption(window, Tcl_GetString(objv[3]), Tcl_GetString(objv[4])); if (value != NULL) { - Tcl_SetResult(interp, (char *)value, TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj(value, -1)); } break; } @@ -741,7 +740,7 @@ void TkOptionDeadWindow( register TkWindow *winPtr) /* Window to be cleaned up. */ { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* @@ -797,7 +796,7 @@ TkOptionClassChanged( { int i, j, *basePtr; ElArray *arrayPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (winPtr->optionLevel == -1) { @@ -852,7 +851,7 @@ TkOptionClassChanged( static int ParsePriority( Tcl_Interp *interp, /* Interpreter to use for error reporting. */ - char *string) /* Describes a priority level, either + const char *string) /* Describes a priority level, either * symbolically or numerically. */ { int priority, c; @@ -878,9 +877,11 @@ ParsePriority( priority = strtoul(string, &end, 0); if ((end == string) || (*end != 0) || (priority < 0) || (priority > 100)) { - Tcl_AppendResult(interp, "bad priority level \"", string, - "\": must be widgetDefault, startupFile, userDefault, ", - "interactive, or a number between 0 and 100", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad priority level \"%s\": must be " + "widgetDefault, startupFile, userDefault, " + "interactive, or a number between 0 and 100", string)); + Tcl_SetErrorCode(interp, "TK", "VALUE", "PRIORITY", NULL); return -1; } } @@ -928,7 +929,6 @@ AddFromString( src = string; lineNum = 1; while (1) { - /* * Skip leading white space and empty lines and comment lines, and * check for the end of the spec. @@ -963,10 +963,9 @@ AddFromString( dst = name = src; while (*src != ':') { if ((*src == '\0') || (*src == '\n')) { - char buf[32 + TCL_INTEGER_SPACE]; - - sprintf(buf, "missing colon on line %d", lineNum); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "missing colon on line %d", lineNum)); + Tcl_SetErrorCode(interp, "TK", "OPTIONDB", "COLON", NULL); return TCL_ERROR; } if ((src[0] == '\\') && (src[1] == '\n')) { @@ -997,11 +996,13 @@ AddFromString( while ((*src == ' ') || (*src == '\t')) { src++; } + if (*src == '\\' && (src[1] == '\t' || src[1] == ' ')) { + src++; + } if (*src == '\0') { - char buf[32 + TCL_INTEGER_SPACE]; - - sprintf(buf, "missing value on line %d", lineNum); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "missing value on line %d", lineNum)); + Tcl_SetErrorCode(interp, "TK", "OPTIONDB", "VALUE", NULL); return TCL_ERROR; } @@ -1013,10 +1014,9 @@ AddFromString( dst = value = src; while (*src != '\n') { if (*src == '\0') { - char buf[32 + TCL_INTEGER_SPACE]; - - sprintf(buf, "missing newline on line %d", lineNum); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "missing newline on line %d", lineNum)); + Tcl_SetErrorCode(interp, "TK", "OPTIONDB", "NEWLINE", NULL); return TCL_ERROR; } if (*src == '\\'){ @@ -1028,7 +1028,7 @@ AddFromString( src += 2; *dst++ = '\n'; continue; - } else if (src[1] == '\t' || src[1] == ' ' || src[1] == '\\') { + } else if (src[1] == '\\') { ++src; } else if (src[1] >= '0' && src[1] <= '3' && src[2] >= '0' && src[2] <= '9' && src[3] >= '0' && src[3] <= '9') { @@ -1076,14 +1076,14 @@ ReadOptionFile( Tcl_Interp *interp, /* Interpreter to use for reporting results. */ Tk_Window tkwin, /* Token for window: options are entered for * this window's main window. */ - char *fileName, /* Name of file containing options. */ + const char *fileName, /* Name of file containing options. */ int priority) /* Priority level to use for options in this * file, such as TK_USER_DEFAULT_PRIO or * TK_INTERACTIVE_PRIO. Must be between 0 and * TK_MAX_PRIO. */ { - CONST char *realName; - char *buffer; + const char *realName; + Tcl_Obj *buffer; int result, bufferSize; Tcl_Channel chan; Tcl_DString newName; @@ -1093,8 +1093,9 @@ ReadOptionFile( */ if (Tcl_IsSafe(interp)) { - Tcl_AppendResult(interp, "can't read options from a file in a", - " safe interpreter", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "can't read options from a file in a safe interpreter", -1)); + Tcl_SetErrorCode(interp, "TK", "SAFE", "OPTION_FILE", NULL); return TCL_ERROR; } @@ -1105,39 +1106,25 @@ ReadOptionFile( chan = Tcl_OpenFileChannel(interp, realName, "r", 0); Tcl_DStringFree(&newName); if (chan == NULL) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "couldn't open \"", fileName, - "\": ", Tcl_PosixError(interp), NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf("couldn't open \"%s\": %s", + fileName, Tcl_PosixError(interp))); return TCL_ERROR; } - /* - * Compute size of file by seeking to the end of the file. This will - * overallocate if we are performing CRLF translation. - */ - - bufferSize = (int) Tcl_Seek(chan, (Tcl_WideInt) 0, SEEK_END); - (void) Tcl_Seek(chan, (Tcl_WideInt) 0, SEEK_SET); - - if (bufferSize < 0) { - Tcl_AppendResult(interp, "error seeking to end of file \"", - fileName, "\":", Tcl_PosixError(interp), NULL); - Tcl_Close(NULL, chan); - return TCL_ERROR; - - } - buffer = (char *) ckalloc((unsigned) bufferSize+1); - bufferSize = Tcl_Read(chan, buffer, bufferSize); + buffer = Tcl_NewObj(); + Tcl_IncrRefCount(buffer); + Tcl_SetChannelOption(NULL, chan, "-encoding", "utf-8"); + bufferSize = Tcl_ReadChars(chan, buffer, -1, 0); if (bufferSize < 0) { - Tcl_AppendResult(interp, "error reading file \"", fileName, "\":", - Tcl_PosixError(interp), NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "error reading file \"%s\": %s", + fileName, Tcl_PosixError(interp))); Tcl_Close(NULL, chan); return TCL_ERROR; } Tcl_Close(NULL, chan); - buffer[bufferSize] = 0; - result = AddFromString(interp, tkwin, buffer, priority); - ckfree(buffer); + result = AddFromString(interp, tkwin, Tcl_GetString(buffer), priority); + Tcl_DecrRefCount(buffer); return result; } @@ -1162,9 +1149,8 @@ static ElArray * NewArray( int numEls) /* How many elements of space to allocate. */ { - register ElArray *arrayPtr; + register ElArray *arrayPtr = ckalloc(EL_ARRAY_SIZE(numEls)); - arrayPtr = (ElArray *) ckalloc(EL_ARRAY_SIZE(numEls)); arrayPtr->arraySize = numEls; arrayPtr->numUsed = 0; arrayPtr->nextToUse = arrayPtr->els; @@ -1198,16 +1184,11 @@ ExtendArray( */ if (arrayPtr->numUsed >= arrayPtr->arraySize) { - register ElArray *newPtr; - - newPtr = (ElArray *) ckalloc(EL_ARRAY_SIZE(2*arrayPtr->arraySize)); - newPtr->arraySize = 2*arrayPtr->arraySize; - newPtr->numUsed = arrayPtr->numUsed; - newPtr->nextToUse = &newPtr->els[newPtr->numUsed]; - memcpy(newPtr->els, arrayPtr->els, - arrayPtr->arraySize * sizeof(Element)); - ckfree((char *) arrayPtr); - arrayPtr = newPtr; + register int newSize = 2*arrayPtr->arraySize; + + arrayPtr = ckrealloc(arrayPtr, EL_ARRAY_SIZE(newSize)); + arrayPtr->arraySize = newSize; + arrayPtr->nextToUse = &arrayPtr->els[arrayPtr->numUsed]; } *arrayPtr->nextToUse = *elPtr; @@ -1242,10 +1223,11 @@ SetupStacks( * being probed. Zero means this is an * ancestor of the desired leaf. */ { - int level, i, *iPtr; + int level, i; + const int *iPtr; register StackLevel *levelPtr; register ElArray *arrayPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* @@ -1257,7 +1239,7 @@ SetupStacks( * differently. */ - static int searchOrder[] = {WILDCARD_NODE_CLASS, WILDCARD_NODE_NAME, + static const int searchOrder[] = {WILDCARD_NODE_CLASS, WILDCARD_NODE_NAME, EXACT_NODE_CLASS, EXACT_NODE_NAME, -1}; if (winPtr->mainPtr->optionRootPtr == NULL) { @@ -1322,13 +1304,12 @@ SetupStacks( */ if (tsdPtr->curLevel >= tsdPtr->numLevels) { - StackLevel *newLevels; + StackLevel *newLevels = + ckalloc(tsdPtr->numLevels * 2 * sizeof(StackLevel)); - newLevels = (StackLevel *) ckalloc((unsigned) - (tsdPtr->numLevels * 2 * sizeof(StackLevel))); memcpy(newLevels, tsdPtr->levels, tsdPtr->numLevels * sizeof(StackLevel)); - ckfree((char *) tsdPtr->levels); + ckfree(tsdPtr->levels); tsdPtr->numLevels *= 2; tsdPtr->levels = newLevels; } @@ -1407,7 +1388,7 @@ ExtendStacks( { register int count; register Element *elPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); for (elPtr = arrayPtr->els, count = arrayPtr->numUsed; @@ -1440,16 +1421,16 @@ static void OptionThreadExitProc( ClientData clientData) /* not used */ { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (tsdPtr->initialized) { int i; for (i = 0; i < NUM_STACKS; i++) { - ckfree((char *) tsdPtr->stacks[i]); + ckfree(tsdPtr->stacks[i]); } - ckfree((char *) tsdPtr->levels); + ckfree(tsdPtr->levels); tsdPtr->initialized = 0; } } @@ -1478,7 +1459,7 @@ OptionInit( { int i; Tcl_Interp *interp; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); Element *defaultMatchPtr = &tsdPtr->defaultMatch; @@ -1493,8 +1474,7 @@ OptionInit( tsdPtr->curLevel = -1; tsdPtr->serial = 0; - tsdPtr->levels = (StackLevel *) - ckalloc((unsigned) (5*sizeof(StackLevel))); + tsdPtr->levels = ckalloc(5 * sizeof(StackLevel)); for (i = 0; i < NUM_STACKS; i++) { tsdPtr->stacks[i] = NewArray(10); tsdPtr->levels[0].bases[i] = 0; @@ -1514,7 +1494,7 @@ OptionInit( mainPtr->optionRootPtr = NewArray(20); interp = Tcl_CreateInterp(); - (void) GetDefaultOptions(interp, mainPtr->winPtr); + GetDefaultOptions(interp, mainPtr->winPtr); Tcl_DeleteInterp(interp); } @@ -1550,7 +1530,7 @@ ClearOptionTree( ClearOptionTree(elPtr->child.arrayPtr); } } - ckfree((char *) arrayPtr); + ckfree(arrayPtr); } /* diff --git a/generic/tkPack.c b/generic/tkPack.c index 47eddd6..9005d7f 100644 --- a/generic/tkPack.c +++ b/generic/tkPack.c @@ -14,14 +14,14 @@ #include "tkInt.h" typedef enum {TOP, BOTTOM, LEFT, RIGHT} Side; -static CONST char *sideNames[] = { +static const char *const sideNames[] = { "top", "bottom", "left", "right", NULL }; -/* For each window that the packer cares about (either because - * the window is managed by the packer or because the window - * has slaves that are managed by the packer), there is a - * structure of the following type: +/* + * For each window that the packer cares about (either because the window is + * managed by the packer or because the window has slaves that are managed by + * the packer), there is a structure of the following type: */ typedef struct Packer { @@ -32,9 +32,9 @@ typedef struct Packer { struct Packer *masterPtr; /* Master window within which this window is * packed (NULL means this window isn't * managed by the packer). */ - struct Packer *nextPtr; /* Next window packed within same master. - * List is priority-ordered: first on list - * gets packed first. */ + struct Packer *nextPtr; /* Next window packed within same master. List + * is priority-ordered: first on list gets + * packed first. */ struct Packer *slavePtr; /* First in list of slaves packed inside this * window (NULL means no packed slaves). */ Side side; /* Side of master against which this window is @@ -87,6 +87,8 @@ typedef struct Packer { * size. 0 means if this window is a master then * Tk will set its requested size to fit the * needs of its slaves. + * ALLOCED_MASTER 1 means that Pack has allocated itself as + * geometry master for this window. */ #define REQUESTED_REPACK 1 @@ -95,6 +97,7 @@ typedef struct Packer { #define EXPAND 8 #define OLD_STYLE 16 #define DONT_PROPAGATE 32 +#define ALLOCED_MASTER 64 /* * The following structure is the official type record for the packer: @@ -116,11 +119,11 @@ static const Tk_GeomMgr packerType = { static void ArrangePacking(ClientData clientData); static int ConfigureSlaves(Tcl_Interp *interp, Tk_Window tkwin, - int objc, Tcl_Obj *CONST objv[]); -static void DestroyPacker(char *memPtr); + int objc, Tcl_Obj *const objv[]); +static void DestroyPacker(void *memPtr); static Packer * GetPacker(Tk_Window tkwin); static int PackAfter(Tcl_Interp *interp, Packer *prevPtr, - Packer *masterPtr, int objc,Tcl_Obj *CONST objv[]); + Packer *masterPtr, int objc,Tcl_Obj *const objv[]); static void PackStructureProc(ClientData clientData, XEvent *eventPtr); static void Unlink(Packer *packPtr); @@ -128,13 +131,13 @@ static int XExpansion(Packer *slavePtr, int cavityWidth); static int YExpansion(Packer *slavePtr, int cavityHeight); /* - *-------------------------------------------------------------- + *------------------------------------------------------------------------ * - * TkPrintPadAmount -- + * TkAppendPadAmount -- * * This function generates a text value that describes one of the -padx, * -pady, -ipadx, or -ipady configuration options. The text value - * generated is appended to the interpreter result. + * generated is appended to the given Tcl_Obj. * * Results: * None. @@ -142,29 +145,33 @@ static int YExpansion(Packer *slavePtr, int cavityHeight); * Side effects: * None. * - *-------------------------------------------------------------- + *------------------------------------------------------------------------ */ void -TkPrintPadAmount( - Tcl_Interp *interp, /* The interpreter into which the result is +TkAppendPadAmount( + Tcl_Obj *bufferObj, /* The interpreter into which the result is * written. */ - char *switchName, /* One of "padx", "pady", "ipadx" or "ipady" */ + const char *switchName, /* One of "padx", "pady", "ipadx" or + * "ipady" */ int halfSpace, /* The left or top padding amount */ int allSpace) /* The total amount of padding */ { - char buffer[60 + 2*TCL_INTEGER_SPACE]; + Tcl_Obj *padding[2]; + if (halfSpace*2 == allSpace) { - sprintf(buffer, " -%.10s %d", switchName, halfSpace); + Tcl_DictObjPut(NULL, bufferObj, Tcl_NewStringObj(switchName, -1), + Tcl_NewIntObj(halfSpace)); } else { - sprintf(buffer, " -%.10s {%d %d}", switchName, halfSpace, - allSpace - halfSpace); + padding[0] = Tcl_NewIntObj(halfSpace); + padding[1] = Tcl_NewIntObj(allSpace - halfSpace); + Tcl_DictObjPut(NULL, bufferObj, Tcl_NewStringObj(switchName, -1), + Tcl_NewListObj(2, padding)); } - Tcl_AppendResult(interp, buffer, NULL); } /* - *-------------------------------------------------------------- + *------------------------------------------------------------------------ * * Tk_PackCmd -- * @@ -177,7 +184,7 @@ TkPrintPadAmount( * Side effects: * See the user documentation. * - *-------------------------------------------------------------- + *------------------------------------------------------------------------ */ int @@ -185,11 +192,11 @@ Tk_PackObjCmd( ClientData clientData, /* Main window associated with interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { - Tk_Window tkwin = (Tk_Window) clientData; - char *argv2; - static CONST char *optionStrings[] = { + Tk_Window tkwin = clientData; + const char *argv2; + static const char *const optionStrings[] = { /* after, append, before and unpack are deprecated */ "after", "append", "before", "unpack", "configure", "forget", "info", "propagate", "slaves", NULL }; @@ -199,7 +206,8 @@ Tk_PackObjCmd( int index; if (objc >= 2) { - char *string = Tcl_GetString(objv[1]); + const char *string = Tcl_GetString(objv[1]); + if (string[0] == '.') { return ConfigureSlaves(interp, tkwin, objc-1, objv+1); } @@ -209,8 +217,8 @@ Tk_PackObjCmd( return TCL_ERROR; } - if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0, - &index) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings, + sizeof(char *), "option", 0, &index) != TCL_OK) { /* * Call it again without the deprecated ones to get a proper error * message. This works well since there can't be any ambiguity between @@ -218,8 +226,8 @@ Tk_PackObjCmd( */ Tcl_ResetResult(interp); - Tcl_GetIndexFromObj(interp, objv[1], &optionStrings[4], "option", 0, - &index); + Tcl_GetIndexFromObjStruct(interp, objv[1], &optionStrings[4], + sizeof(char *), "option", 0, &index); return TCL_ERROR; } @@ -234,8 +242,9 @@ Tk_PackObjCmd( } prevPtr = GetPacker(tkwin2); if (prevPtr->masterPtr == NULL) { - Tcl_AppendResult(interp, "window \"", argv2, - "\" isn't packed", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "window \"%s\" isn't packed", argv2)); + Tcl_SetErrorCode(interp, "TK", "PACK", "NOT_PACKED", NULL); return TCL_ERROR; } return PackAfter(interp, prevPtr, prevPtr->masterPtr, objc-3, objv+3); @@ -267,8 +276,9 @@ Tk_PackObjCmd( } packPtr = GetPacker(tkwin2); if (packPtr->masterPtr == NULL) { - Tcl_AppendResult(interp, "window \"", argv2, - "\" isn't packed", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "window \"%s\" isn't packed", argv2)); + Tcl_SetErrorCode(interp, "TK", "PACK", "NOT_PACKED", NULL); return TCL_ERROR; } masterPtr = packPtr->masterPtr; @@ -289,8 +299,9 @@ Tk_PackObjCmd( } case PACK_CONFIGURE: if (argv2[0] != '.') { - Tcl_AppendResult(interp, "bad argument \"", argv2, - "\": must be name of window", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad argument \"%s\": must be name of window", argv2)); + Tcl_SetErrorCode(interp, "TK", "VALUE", "WINDOW_PATH", NULL); return TCL_ERROR; } return ConfigureSlaves(interp, tkwin, objc-2, objv+2); @@ -305,8 +316,7 @@ Tk_PackObjCmd( } slavePtr = GetPacker(slave); if ((slavePtr != NULL) && (slavePtr->masterPtr != NULL)) { - Tk_ManageGeometry(slave, NULL, - (ClientData) NULL); + Tk_ManageGeometry(slave, NULL, NULL); if (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin)) { Tk_UnmaintainGeometry(slavePtr->tkwin, slavePtr->masterPtr->tkwin); @@ -320,6 +330,7 @@ Tk_PackObjCmd( case PACK_INFO: { register Packer *slavePtr; Tk_Window slave; + Tcl_Obj *infoObj; if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "window"); @@ -330,35 +341,44 @@ Tk_PackObjCmd( } slavePtr = GetPacker(slave); if (slavePtr->masterPtr == NULL) { - Tcl_AppendResult(interp, "window \"", argv2, - "\" isn't packed", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "window \"%s\" isn't packed", argv2)); + Tcl_SetErrorCode(interp, "TK", "PACK", "NOT_PACKED", NULL); return TCL_ERROR; } - Tcl_AppendElement(interp, "-in"); - Tcl_AppendElement(interp, Tk_PathName(slavePtr->masterPtr->tkwin)); - Tcl_AppendElement(interp, "-anchor"); - Tcl_AppendElement(interp, Tk_NameOfAnchor(slavePtr->anchor)); - Tcl_AppendResult(interp, " -expand ", - (slavePtr->flags & EXPAND) ? "1" : "0", " -fill ", NULL); + + infoObj = Tcl_NewObj(); + Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-in", -1), + TkNewWindowObj(slavePtr->masterPtr->tkwin)); + Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-anchor", -1), + Tcl_NewStringObj(Tk_NameOfAnchor(slavePtr->anchor), -1)); + Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-expand", -1), + Tcl_NewBooleanObj(slavePtr->flags & EXPAND)); switch (slavePtr->flags & (FILLX|FILLY)) { case 0: - Tcl_AppendResult(interp, "none", NULL); + Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-fill", -1), + Tcl_NewStringObj("none", -1)); break; case FILLX: - Tcl_AppendResult(interp, "x", NULL); + Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-fill", -1), + Tcl_NewStringObj("x", -1)); break; case FILLY: - Tcl_AppendResult(interp, "y", NULL); + Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-fill", -1), + Tcl_NewStringObj("y", -1)); break; case FILLX|FILLY: - Tcl_AppendResult(interp, "both", NULL); + Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-fill", -1), + Tcl_NewStringObj("both", -1)); break; } - TkPrintPadAmount(interp, "ipadx", slavePtr->iPadX/2, slavePtr->iPadX); - TkPrintPadAmount(interp, "ipady", slavePtr->iPadY/2, slavePtr->iPadY); - TkPrintPadAmount(interp, "padx", slavePtr->padLeft, slavePtr->padX); - TkPrintPadAmount(interp, "pady", slavePtr->padTop, slavePtr->padY); - Tcl_AppendResult(interp, " -side ", sideNames[slavePtr->side], NULL); + TkAppendPadAmount(infoObj, "-ipadx", slavePtr->iPadX/2, slavePtr->iPadX); + TkAppendPadAmount(infoObj, "-ipady", slavePtr->iPadY/2, slavePtr->iPadY); + TkAppendPadAmount(infoObj, "-padx", slavePtr->padLeft,slavePtr->padX); + TkAppendPadAmount(infoObj, "-pady", slavePtr->padTop, slavePtr->padY); + Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-side", -1), + Tcl_NewStringObj(sideNames[slavePtr->side], -1)); + Tcl_SetObjResult(interp, infoObj); break; } case PACK_PROPAGATE: { @@ -383,6 +403,16 @@ Tk_PackObjCmd( return TCL_ERROR; } if (propagate) { + /* + * If we have slaves, we need to register as geometry master. + */ + + if (masterPtr->slavePtr != NULL) { + if (TkSetGeometryMaster(interp, master, "pack") != TCL_OK) { + return TCL_ERROR; + } + masterPtr->flags |= ALLOCED_MASTER; + } masterPtr->flags &= ~DONT_PROPAGATE; /* @@ -395,9 +425,13 @@ Tk_PackObjCmd( } if (!(masterPtr->flags & REQUESTED_REPACK)) { masterPtr->flags |= REQUESTED_REPACK; - Tcl_DoWhenIdle(ArrangePacking, (ClientData) masterPtr); + Tcl_DoWhenIdle(ArrangePacking, masterPtr); } } else { + if (masterPtr->flags & ALLOCED_MASTER) { + TkFreeGeometryMaster(master, "pack"); + masterPtr->flags &= ~ALLOCED_MASTER; + } masterPtr->flags |= DONT_PROPAGATE; } break; @@ -405,6 +439,7 @@ Tk_PackObjCmd( case PACK_SLAVES: { Tk_Window master; Packer *masterPtr, *slavePtr; + Tcl_Obj *resultObj; if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "window"); @@ -413,11 +448,14 @@ Tk_PackObjCmd( if (TkGetWindowFromObj(interp, tkwin, objv[2], &master) != TCL_OK) { return TCL_ERROR; } + resultObj = Tcl_NewObj(); masterPtr = GetPacker(master); for (slavePtr = masterPtr->slavePtr; slavePtr != NULL; slavePtr = slavePtr->nextPtr) { - Tcl_AppendElement(interp, Tk_PathName(slavePtr->tkwin)); + Tcl_ListObjAppendElement(NULL, resultObj, + TkNewWindowObj(slavePtr->tkwin)); } + Tcl_SetObjResult(interp, resultObj); break; } case PACK_UNPACK: { @@ -433,8 +471,7 @@ Tk_PackObjCmd( } packPtr = GetPacker(tkwin2); if ((packPtr != NULL) && (packPtr->masterPtr != NULL)) { - Tk_ManageGeometry(tkwin2, NULL, - (ClientData) NULL); + Tk_ManageGeometry(tkwin2, NULL, NULL); if (packPtr->masterPtr->tkwin != Tk_Parent(packPtr->tkwin)) { Tk_UnmaintainGeometry(packPtr->tkwin, packPtr->masterPtr->tkwin); @@ -450,7 +487,7 @@ Tk_PackObjCmd( } /* - *-------------------------------------------------------------- + *------------------------------------------------------------------------ * * PackReqProc -- * @@ -464,7 +501,7 @@ Tk_PackObjCmd( * Arranges for tkwin, and all its managed siblings, to be re-packed at * the next idle point. * - *-------------------------------------------------------------- + *------------------------------------------------------------------------ */ /* ARGSUSED */ @@ -475,17 +512,17 @@ PackReqProc( Tk_Window tkwin) /* Other Tk-related information about the * window. */ { - register Packer *packPtr = (Packer *) clientData; + register Packer *packPtr = clientData; packPtr = packPtr->masterPtr; if (!(packPtr->flags & REQUESTED_REPACK)) { packPtr->flags |= REQUESTED_REPACK; - Tcl_DoWhenIdle(ArrangePacking, (ClientData) packPtr); + Tcl_DoWhenIdle(ArrangePacking, packPtr); } } /* - *-------------------------------------------------------------- + *------------------------------------------------------------------------ * * PackLostSlaveProc -- * @@ -498,7 +535,7 @@ PackReqProc( * Side effects: * Forgets all packer-related information about the slave. * - *-------------------------------------------------------------- + *------------------------------------------------------------------------ */ /* ARGSUSED */ @@ -508,7 +545,7 @@ PackLostSlaveProc( * stolen away. */ Tk_Window tkwin) /* Tk's handle for the slave window. */ { - register Packer *slavePtr = (Packer *) clientData; + register Packer *slavePtr = clientData; if (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin)) { Tk_UnmaintainGeometry(slavePtr->tkwin, slavePtr->masterPtr->tkwin); @@ -518,7 +555,7 @@ PackLostSlaveProc( } /* - *-------------------------------------------------------------- + *------------------------------------------------------------------------ * * ArrangePacking -- * @@ -533,7 +570,7 @@ PackLostSlaveProc( * Side effects: * The packed slaves of masterPtr may get resized or moved. * - *-------------------------------------------------------------- + *------------------------------------------------------------------------ */ static void @@ -541,7 +578,7 @@ ArrangePacking( ClientData clientData) /* Structure describing master whose slaves * are to be re-layed out. */ { - register Packer *masterPtr = (Packer *) clientData; + register Packer *masterPtr = clientData; register Packer *slavePtr; int cavityX, cavityY, cavityWidth, cavityHeight; /* These variables keep track of the @@ -581,7 +618,7 @@ ArrangePacking( } masterPtr->abortPtr = &abort; abort = 0; - Tcl_Preserve((ClientData) masterPtr); + Tcl_Preserve(masterPtr); /* * Pass #1: scan all the slaves to figure out the total amount of space @@ -650,7 +687,7 @@ ArrangePacking( && !(masterPtr->flags & DONT_PROPAGATE)) { Tk_GeometryRequest(masterPtr->tkwin, maxWidth, maxHeight); masterPtr->flags |= REQUESTED_REPACK; - Tcl_DoWhenIdle(ArrangePacking, (ClientData) masterPtr); + Tcl_DoWhenIdle(ArrangePacking, masterPtr); goto done; } @@ -841,7 +878,7 @@ ArrangePacking( done: masterPtr->abortPtr = NULL; - Tcl_Release((ClientData) masterPtr); + Tcl_Release(masterPtr); } /* @@ -888,9 +925,11 @@ XExpansion( childWidth = Tk_ReqWidth(slavePtr->tkwin) + slavePtr->doubleBw + slavePtr->padX + slavePtr->iPadX; if ((slavePtr->side == TOP) || (slavePtr->side == BOTTOM)) { - curExpand = (cavityWidth - childWidth)/numExpand; - if (curExpand < minExpand) { - minExpand = curExpand; + if (numExpand) { + curExpand = (cavityWidth - childWidth)/numExpand; + if (curExpand < minExpand) { + minExpand = curExpand; + } } } else { cavityWidth -= childWidth; @@ -899,9 +938,11 @@ XExpansion( } } } - curExpand = cavityWidth/numExpand; - if (curExpand < minExpand) { - minExpand = curExpand; + if (numExpand) { + curExpand = cavityWidth/numExpand; + if (curExpand < minExpand) { + minExpand = curExpand; + } } return (minExpand < 0) ? 0 : minExpand; } @@ -943,9 +984,11 @@ YExpansion( childHeight = Tk_ReqHeight(slavePtr->tkwin) + slavePtr->doubleBw + slavePtr->padY + slavePtr->iPadY; if ((slavePtr->side == LEFT) || (slavePtr->side == RIGHT)) { - curExpand = (cavityHeight - childHeight)/numExpand; - if (curExpand < minExpand) { - minExpand = curExpand; + if (numExpand) { + curExpand = (cavityHeight - childHeight)/numExpand; + if (curExpand < minExpand) { + minExpand = curExpand; + } } } else { cavityHeight -= childHeight; @@ -954,15 +997,17 @@ YExpansion( } } } - curExpand = cavityHeight/numExpand; - if (curExpand < minExpand) { - minExpand = curExpand; + if (numExpand) { + curExpand = cavityHeight/numExpand; + if (curExpand < minExpand) { + minExpand = curExpand; + } } return (minExpand < 0) ? 0 : minExpand; } /* - *-------------------------------------------------------------- + *------------------------------------------------------------------------ * * GetPacker -- * @@ -977,7 +1022,7 @@ YExpansion( * A new packer structure may be created. If so, then a callback is set * up to clean things up when the window is deleted. * - *-------------------------------------------------------------- + *------------------------------------------------------------------------ */ static Packer * @@ -1003,9 +1048,9 @@ GetPacker( hPtr = Tcl_CreateHashEntry(&dispPtr->packerHashTable, (char *) tkwin, &isNew); if (!isNew) { - return (Packer *) Tcl_GetHashValue(hPtr); + return Tcl_GetHashValue(hPtr); } - packPtr = (Packer *) ckalloc(sizeof(Packer)); + packPtr = ckalloc(sizeof(Packer)); packPtr->tkwin = tkwin; packPtr->masterPtr = NULL; packPtr->nextPtr = NULL; @@ -1020,12 +1065,12 @@ GetPacker( packPtr->flags = 0; Tcl_SetHashValue(hPtr, packPtr); Tk_CreateEventHandler(tkwin, StructureNotifyMask, - PackStructureProc, (ClientData) packPtr); + PackStructureProc, packPtr); return packPtr; } /* - *-------------------------------------------------------------- + *------------------------------------------------------------------------ * * PackAfter -- * @@ -1039,7 +1084,7 @@ GetPacker( * The geometry of the specified windows may change, both now and again * in the future. * - *-------------------------------------------------------------- + *------------------------------------------------------------------------ */ static int @@ -1050,13 +1095,12 @@ PackAfter( * masterPtr. */ Packer *masterPtr, /* Master in which to pack windows. */ int objc, /* Number of elements in objv. */ - Tcl_Obj *CONST objv[]) /* Array of lists, each containing 2 elements: + Tcl_Obj *const objv[]) /* Array of lists, each containing 2 elements: * window name and side against which to * pack. */ { register Packer *packPtr; Tk_Window tkwin, ancestor, parent; - int length; Tcl_Obj **options; int index, optionCount, c; @@ -1068,9 +1112,10 @@ PackAfter( for ( ; objc > 0; objc -= 2, objv += 2, prevPtr = packPtr) { if (objc < 2) { - Tcl_AppendResult(interp, "wrong # args: window \"", - Tcl_GetString(objv[0]), "\" should be followed by options", - NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "wrong # args: window \"%s\" should be followed by options", + Tcl_GetString(objv[0]))); + Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL); return TCL_ERROR; } @@ -1092,8 +1137,10 @@ PackAfter( } if (((Tk_FakeWin *) (ancestor))->flags & TK_TOP_HIERARCHY) { badWindow: - Tcl_AppendResult(interp, "can't pack ", Tcl_GetString(objv[0]), - " inside ", Tk_PathName(masterPtr->tkwin), NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't pack %s inside %s", Tcl_GetString(objv[0]), + Tk_PathName(masterPtr->tkwin))); + Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "HIERARCHY", NULL); return TCL_ERROR; } } @@ -1122,24 +1169,25 @@ PackAfter( packPtr->flags |= OLD_STYLE; for (index = 0 ; index < optionCount; index++) { Tcl_Obj *curOptPtr = options[index]; - char *curOpt = Tcl_GetStringFromObj(curOptPtr, &length); + const char *curOpt = Tcl_GetString(curOptPtr); + size_t length = curOptPtr->length; c = curOpt[0]; if ((c == 't') - && (strncmp(curOpt, "top", (size_t) length)) == 0) { + && (strncmp(curOpt, "top", length)) == 0) { packPtr->side = TOP; } else if ((c == 'b') - && (strncmp(curOpt, "bottom", (size_t) length)) == 0) { + && (strncmp(curOpt, "bottom", length)) == 0) { packPtr->side = BOTTOM; } else if ((c == 'l') - && (strncmp(curOpt, "left", (size_t) length)) == 0) { + && (strncmp(curOpt, "left", length)) == 0) { packPtr->side = LEFT; } else if ((c == 'r') - && (strncmp(curOpt, "right", (size_t) length)) == 0) { + && (strncmp(curOpt, "right", length)) == 0) { packPtr->side = RIGHT; } else if ((c == 'e') - && (strncmp(curOpt, "expand", (size_t) length)) == 0) { + && (strncmp(curOpt, "expand", length)) == 0) { packPtr->flags |= EXPAND; } else if ((c == 'f') && (strcmp(curOpt, "fill")) == 0) { @@ -1151,8 +1199,10 @@ PackAfter( } else if ((c == 'p') && (strcmp(curOpt, "padx")) == 0) { if (optionCount < (index+2)) { missingPad: - Tcl_AppendResult(interp, "wrong # args: \"", curOpt, - "\" option must be followed by screen distance", + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "wrong # args: \"%s\" option must be" + " followed by screen distance", curOpt)); + Tcl_SetErrorCode(interp, "TK", "OLDPACK", "BAD_PARAMETER", NULL); return TCL_ERROR; } @@ -1179,8 +1229,11 @@ PackAfter( } else if ((c == 'f') && (length > 1) && (strncmp(curOpt, "frame", (size_t) length) == 0)) { if (optionCount < (index+2)) { - Tcl_AppendResult(interp, "wrong # args: \"frame\" ", - "option must be followed by anchor point", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "wrong # args: \"frame\"" + " option must be followed by anchor point", -1)); + Tcl_SetErrorCode(interp, "TK", "OLDPACK", "BAD_PARAMETER", + NULL); return TCL_ERROR; } if (Tk_GetAnchorFromObj(interp, options[index+1], @@ -1189,15 +1242,17 @@ PackAfter( } index++; } else { - Tcl_AppendResult(interp, "bad option \"", curOpt, - "\": should be top, bottom, left, right, expand, ", - "fill, fillx, filly, padx, pady, or frame", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad option \"%s\": should be top, bottom, left," + " right, expand, fill, fillx, filly, padx, pady, or" + " frame", curOpt)); + Tcl_SetErrorCode(interp, "TK", "OLDPACK", "BAD_PARAMETER", + NULL); return TCL_ERROR; } } if (packPtr != prevPtr) { - /* * Unpack this window if it's currently packed. */ @@ -1225,7 +1280,17 @@ PackAfter( packPtr->nextPtr = prevPtr->nextPtr; prevPtr->nextPtr = packPtr; } - Tk_ManageGeometry(tkwin, &packerType, (ClientData) packPtr); + Tk_ManageGeometry(tkwin, &packerType, packPtr); + + if (!(masterPtr->flags & DONT_PROPAGATE)) { + if (TkSetGeometryMaster(interp, masterPtr->tkwin, "pack") + != TCL_OK) { + Tk_ManageGeometry(tkwin, NULL, NULL); + Unlink(packPtr); + return TCL_ERROR; + } + masterPtr->flags |= ALLOCED_MASTER; + } } } @@ -1238,7 +1303,7 @@ PackAfter( } if (!(masterPtr->flags & REQUESTED_REPACK)) { masterPtr->flags |= REQUESTED_REPACK; - Tcl_DoWhenIdle(ArrangePacking, (ClientData) masterPtr); + Tcl_DoWhenIdle(ArrangePacking, masterPtr); } return TCL_OK; } @@ -1284,13 +1349,24 @@ Unlink( } if (!(masterPtr->flags & REQUESTED_REPACK)) { masterPtr->flags |= REQUESTED_REPACK; - Tcl_DoWhenIdle(ArrangePacking, (ClientData) masterPtr); + Tcl_DoWhenIdle(ArrangePacking, masterPtr); } if (masterPtr->abortPtr != NULL) { *masterPtr->abortPtr = 1; } packPtr->masterPtr = NULL; + + /* + * If we have emptied this master from slaves it means we are no longer + * handling it and should mark it as free. + */ + + if ((masterPtr->slavePtr == NULL) && (masterPtr->flags & ALLOCED_MASTER)) { + TkFreeGeometryMaster(masterPtr->tkwin, "pack"); + masterPtr->flags &= ~ALLOCED_MASTER; + } + } /* @@ -1313,11 +1389,12 @@ Unlink( static void DestroyPacker( - char *memPtr) /* Info about packed window that is now + void *memPtr) /* Info about packed window that is now * dead. */ { - register Packer *packPtr = (Packer *) memPtr; - ckfree((char *) packPtr); + register Packer *packPtr = memPtr; + + ckfree(packPtr); } /* @@ -1344,20 +1421,20 @@ PackStructureProc( * eventPtr. */ XEvent *eventPtr) /* Describes what just happened. */ { - register Packer *packPtr = (Packer *) clientData; + register Packer *packPtr = clientData; if (eventPtr->type == ConfigureNotify) { if ((packPtr->slavePtr != NULL) && !(packPtr->flags & REQUESTED_REPACK)) { packPtr->flags |= REQUESTED_REPACK; - Tcl_DoWhenIdle(ArrangePacking, (ClientData) packPtr); + Tcl_DoWhenIdle(ArrangePacking, packPtr); } if ((packPtr->masterPtr != NULL) && (packPtr->doubleBw != 2*Tk_Changes(packPtr->tkwin)->border_width)) { if (!(packPtr->masterPtr->flags & REQUESTED_REPACK)) { packPtr->doubleBw = 2*Tk_Changes(packPtr->tkwin)->border_width; packPtr->masterPtr->flags |= REQUESTED_REPACK; - Tcl_DoWhenIdle(ArrangePacking, (ClientData) packPtr->masterPtr); + Tcl_DoWhenIdle(ArrangePacking, packPtr->masterPtr); } } } else if (eventPtr->type == DestroyNotify) { @@ -1369,8 +1446,7 @@ PackStructureProc( for (slavePtr = packPtr->slavePtr; slavePtr != NULL; slavePtr = nextPtr) { - Tk_ManageGeometry(slavePtr->tkwin, NULL, - (ClientData) NULL); + Tk_ManageGeometry(slavePtr->tkwin, NULL, NULL); Tk_UnmapWindow(slavePtr->tkwin); slavePtr->masterPtr = NULL; nextPtr = slavePtr->nextPtr; @@ -1384,10 +1460,10 @@ PackStructureProc( } if (packPtr->flags & REQUESTED_REPACK) { - Tcl_CancelIdleCall(ArrangePacking, (ClientData) packPtr); + Tcl_CancelIdleCall(ArrangePacking, packPtr); } packPtr->tkwin = NULL; - Tcl_EventuallyFree((ClientData) packPtr, DestroyPacker); + Tcl_EventuallyFree(packPtr, (Tcl_FreeProc *) DestroyPacker); } else if (eventPtr->type == MapNotify) { /* * When a master gets mapped, must redo the geometry computation so @@ -1397,7 +1473,7 @@ PackStructureProc( if ((packPtr->slavePtr != NULL) && !(packPtr->flags & REQUESTED_REPACK)) { packPtr->flags |= REQUESTED_REPACK; - Tcl_DoWhenIdle(ArrangePacking, (ClientData) packPtr); + Tcl_DoWhenIdle(ArrangePacking, packPtr); } } else if (eventPtr->type == UnmapNotify) { register Packer *packPtr2; @@ -1439,16 +1515,17 @@ ConfigureSlaves( Tk_Window tkwin, /* Any window in application containing * slaves. Used to look up slave names. */ int objc, /* Number of elements in argv. */ - Tcl_Obj *CONST objv[]) /* Argument objects: contains one or more + Tcl_Obj *const objv[]) /* Argument objects: contains one or more * window names followed by any number of * "option value" pairs. Caller must make sure * that there is at least one window name. */ { Packer *masterPtr, *slavePtr, *prevPtr, *otherPtr; Tk_Window other, slave, parent, ancestor; + TkWindow *master; int i, j, numWindows, tmp, positionGiven; - char *string; - static CONST char *optionStrings[] = { + const char *string; + static const char *const optionStrings[] = { "-after", "-anchor", "-before", "-expand", "-fill", "-in", "-ipadx", "-ipady", "-padx", "-pady", "-side", NULL }; enum options { @@ -1485,8 +1562,10 @@ ConfigureSlaves( return TCL_ERROR; } if (Tk_TopWinHierarchy(slave)) { - Tcl_AppendResult(interp, "can't pack \"", Tcl_GetString(objv[j]), - "\": it's a top-level window", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't pack \"%s\": it's a top-level window", + Tcl_GetString(objv[j]))); + Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "TOPLEVEL", NULL); return TCL_ERROR; } slavePtr = GetPacker(slave); @@ -1509,13 +1588,14 @@ ConfigureSlaves( for (i = numWindows; i < objc; i+=2) { if ((i+2) > objc) { - Tcl_AppendResult(interp, "extra option \"", - Tcl_GetString(objv[i]), - "\" (option with no value?)", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "extra option \"%s\" (option with no value?)", + Tcl_GetString(objv[i]))); + Tcl_SetErrorCode(interp, "TK", "PACK", "BAD_PARAMETER", NULL); return TCL_ERROR; } - if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings, "option", - 0, &index) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[i], optionStrings, + sizeof(char *), "option", 0, &index) != TCL_OK) { return TCL_ERROR; } @@ -1529,9 +1609,11 @@ ConfigureSlaves( prevPtr = GetPacker(other); if (prevPtr->masterPtr == NULL) { notPacked: - Tcl_AppendResult(interp, "window \"", - Tcl_GetString(objv[i+1]), - "\" isn't packed", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "window \"%s\" isn't packed", + Tcl_GetString(objv[i+1]))); + Tcl_SetErrorCode(interp, "TK", "PACK", "NOT_PACKED", + NULL); return TCL_ERROR; } masterPtr = prevPtr->masterPtr; @@ -1586,8 +1668,10 @@ ConfigureSlaves( } else if (strcmp(string, "both") == 0) { slavePtr->flags |= FILLX|FILLY; } else { - Tcl_AppendResult(interp, "bad fill style \"", string, - "\": must be none, x, y, or both", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad fill style \"%s\": must be " + "none, x, y, or both", string)); + Tcl_SetErrorCode(interp, "TK", "VALUE", "FILL", NULL); return TCL_ERROR; } break; @@ -1609,24 +1693,22 @@ ConfigureSlaves( break; case CONF_IPADX: if ((Tk_GetPixelsFromObj(interp, slave, objv[i+1], &tmp) - != TCL_OK) - || (tmp < 0)) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "bad ipadx value \"", - Tcl_GetString(objv[i+1]), - "\": must be positive screen distance", NULL); + != TCL_OK) || (tmp < 0)) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad ipadx value \"%s\": must be positive screen" + " distance", Tcl_GetString(objv[i+1]))); + Tcl_SetErrorCode(interp, "TK", "VALUE", "INT_PAD", NULL); return TCL_ERROR; } slavePtr->iPadX = tmp * 2; break; case CONF_IPADY: if ((Tk_GetPixelsFromObj(interp, slave, objv[i+1], &tmp) - != TCL_OK) - || (tmp < 0)) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "bad ipady value \"", - Tcl_GetString(objv[i+1]), - "\": must be positive screen distance", NULL); + != TCL_OK) || (tmp < 0)) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad ipady value \"%s\": must be positive screen" + " distance", Tcl_GetString(objv[i+1]))); + Tcl_SetErrorCode(interp, "TK", "VALUE", "INT_PAD", NULL); return TCL_ERROR; } slavePtr->iPadY = tmp * 2; @@ -1644,8 +1726,8 @@ ConfigureSlaves( } break; case CONF_SIDE: - if (Tcl_GetIndexFromObj(interp, objv[i+1], sideNames, "side", - TCL_EXACT, &side) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[i+1], sideNames, + sizeof(char *), "side", TCL_EXACT, &side) != TCL_OK) { return TCL_ERROR; } slavePtr->side = (Side) side; @@ -1703,18 +1785,39 @@ ConfigureSlaves( break; } if (Tk_TopWinHierarchy(ancestor)) { - Tcl_AppendResult(interp, "can't pack ", Tcl_GetString(objv[j]), - " inside ", Tk_PathName(masterPtr->tkwin), NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't pack %s inside %s", Tcl_GetString(objv[j]), + Tk_PathName(masterPtr->tkwin))); + Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "HIERARCHY", NULL); return TCL_ERROR; } } if (slave == masterPtr->tkwin) { - Tcl_AppendResult(interp, "can't pack ", Tcl_GetString(objv[j]), - " inside itself", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't pack %s inside itself", Tcl_GetString(objv[j]))); + Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "SELF", NULL); return TCL_ERROR; } /* + * Check for management loops. + */ + + for (master = (TkWindow *)masterPtr->tkwin; master != NULL; + master = (TkWindow *)TkGetGeomMaster(master)) { + if (master == (TkWindow *)slave) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't put %s inside %s, would cause management loop", + Tcl_GetString(objv[j]), Tk_PathName(masterPtr->tkwin))); + Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "LOOP", NULL); + return TCL_ERROR; + } + } + if (masterPtr->tkwin != Tk_Parent(slave)) { + ((TkWindow *)slave)->maintainerPtr = (TkWindow *)masterPtr->tkwin; + } + + /* * Unpack the slave if it's currently packed, then position it after * prevPtr. */ @@ -1728,6 +1831,7 @@ ConfigureSlaves( } Unlink(slavePtr); } + slavePtr->masterPtr = masterPtr; if (prevPtr == NULL) { slavePtr->nextPtr = masterPtr->slavePtr; @@ -1736,9 +1840,19 @@ ConfigureSlaves( slavePtr->nextPtr = prevPtr->nextPtr; prevPtr->nextPtr = slavePtr; } - Tk_ManageGeometry(slave, &packerType, (ClientData) slavePtr); + Tk_ManageGeometry(slave, &packerType, slavePtr); prevPtr = slavePtr; + if (!(masterPtr->flags & DONT_PROPAGATE)) { + if (TkSetGeometryMaster(interp, masterPtr->tkwin, "pack") + != TCL_OK) { + Tk_ManageGeometry(slave, NULL, NULL); + Unlink(slavePtr); + return TCL_ERROR; + } + masterPtr->flags |= ALLOCED_MASTER; + } + /* * Arrange for the master to be re-packed at the first idle moment. */ @@ -1749,7 +1863,7 @@ ConfigureSlaves( } if (!(masterPtr->flags & REQUESTED_REPACK)) { masterPtr->flags |= REQUESTED_REPACK; - Tcl_DoWhenIdle(ArrangePacking, (ClientData) masterPtr); + Tcl_DoWhenIdle(ArrangePacking, masterPtr); } } return TCL_OK; diff --git a/generic/tkPanedWindow.c b/generic/tkPanedWindow.c index 89afb37..80ddb33 100644 --- a/generic/tkPanedWindow.c +++ b/generic/tkPanedWindow.c @@ -276,11 +276,11 @@ static const Tk_ObjCustomOption stickyOption = { static const Tk_OptionSpec optionSpecs[] = { {TK_OPTION_BORDER, "-background", "background", "Background", DEF_PANEDWINDOW_BG_COLOR, -1, Tk_Offset(PanedWindow, background), 0, - (ClientData) DEF_PANEDWINDOW_BG_MONO}, + DEF_PANEDWINDOW_BG_MONO, 0}, {TK_OPTION_SYNONYM, "-bd", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-borderwidth"}, + NULL, 0, -1, 0, "-borderwidth", 0}, {TK_OPTION_SYNONYM, "-bg", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-background"}, + NULL, 0, -1, 0, "-background", 0}, {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", DEF_PANEDWINDOW_BORDERWIDTH, -1, Tk_Offset(PanedWindow, borderWidth), 0, 0, GEOMETRY}, @@ -301,7 +301,7 @@ static const Tk_OptionSpec optionSpecs[] = { Tk_Offset(PanedWindow, resizeOpaque), 0, 0, 0}, {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient", DEF_PANEDWINDOW_ORIENT, -1, Tk_Offset(PanedWindow, orient), - 0, (ClientData) orientStrings, GEOMETRY}, + 0, orientStrings, GEOMETRY}, {TK_OPTION_BORDER, "-proxybackground", "proxyBackground", "ProxyBackground", 0, -1, Tk_Offset(PanedWindow, proxyBackground), TK_OPTION_NULL_OK, (ClientData) DEF_PANEDWINDOW_BG_MONO}, @@ -331,7 +331,7 @@ static const Tk_OptionSpec optionSpecs[] = { {TK_OPTION_PIXELS, "-width", "width", "Width", DEF_PANEDWINDOW_WIDTH, Tk_Offset(PanedWindow, widthPtr), Tk_Offset(PanedWindow, width), TK_OPTION_NULL_OK, 0, GEOMETRY}, - {TK_OPTION_END} + {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0} }; static const Tk_OptionSpec slaveOptionSpecs[] = { @@ -354,14 +354,14 @@ static const Tk_OptionSpec slaveOptionSpecs[] = { DEF_PANEDWINDOW_PANE_PADY, -1, Tk_Offset(Slave, pady), 0, 0, 0}, {TK_OPTION_CUSTOM, "-sticky", NULL, NULL, DEF_PANEDWINDOW_PANE_STICKY, -1, Tk_Offset(Slave, sticky), 0, - (ClientData) &stickyOption, 0}, + &stickyOption, 0}, {TK_OPTION_STRING_TABLE, "-stretch", "stretch", "Stretch", DEF_PANEDWINDOW_PANE_STRETCH, -1, Tk_Offset(Slave, stretch), 0, (ClientData) stretchStrings, 0}, {TK_OPTION_PIXELS, "-width", NULL, NULL, DEF_PANEDWINDOW_PANE_WIDTH, Tk_Offset(Slave, widthPtr), Tk_Offset(Slave, width), TK_OPTION_NULL_OK, 0, 0}, - {TK_OPTION_END} + {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0} }; /* @@ -394,12 +394,12 @@ Tk_PanedWindowObjCmd( XSetWindowAttributes atts; if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?"); + Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?"); return TCL_ERROR; } tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp), - Tcl_GetStringFromObj(objv[1], NULL), NULL); + Tcl_GetString(objv[1]), NULL); if (tkwin == NULL) { return TCL_ERROR; } @@ -414,14 +414,14 @@ Tk_PanedWindowObjCmd( * easy access to it in the future. */ - pwOpts = (OptionTables *) ckalloc(sizeof(OptionTables)); + pwOpts = ckalloc(sizeof(OptionTables)); /* * Set up an exit handler to free the optionTables struct. */ Tcl_SetAssocData(interp, "PanedWindowOptionTables", - DestroyOptionTables, (ClientData) pwOpts); + DestroyOptionTables, pwOpts); /* * Create the paned window option tables. @@ -437,14 +437,14 @@ Tk_PanedWindowObjCmd( * Allocate and initialize the widget record. */ - pwPtr = (PanedWindow *) ckalloc(sizeof(PanedWindow)); + pwPtr = ckalloc(sizeof(PanedWindow)); memset((void *)pwPtr, 0, (sizeof(PanedWindow))); pwPtr->tkwin = tkwin; pwPtr->display = Tk_Display(tkwin); pwPtr->interp = interp; pwPtr->widgetCmd = Tcl_CreateObjCommand(interp, - Tk_PathName(pwPtr->tkwin), PanedWindowWidgetObjCmd, - (ClientData) pwPtr, PanedWindowCmdDeletedProc); + Tk_PathName(pwPtr->tkwin), PanedWindowWidgetObjCmd, pwPtr, + PanedWindowCmdDeletedProc); pwPtr->optionTable = pwOpts->pwOptions; pwPtr->slaveOpts = pwOpts->slaveOpts; pwPtr->relief = TK_RELIEF_RAISED; @@ -457,7 +457,7 @@ Tk_PanedWindowObjCmd( * otherwise Tk might free it while we still need it. */ - Tcl_Preserve((ClientData) pwPtr->tkwin); + Tcl_Preserve(pwPtr->tkwin); if (Tk_InitOptions(interp, (char *) pwPtr, pwOpts->pwOptions, tkwin) != TCL_OK) { @@ -466,7 +466,7 @@ Tk_PanedWindowObjCmd( } Tk_CreateEventHandler(pwPtr->tkwin, ExposureMask|StructureNotifyMask, - PanedWindowEventProc, (ClientData) pwPtr); + PanedWindowEventProc, pwPtr); /* * Find the toplevel ancestor of the panedwindow, and make a proxy win as @@ -496,7 +496,7 @@ Tk_PanedWindowObjCmd( Tk_SetWindowVisual(pwPtr->proxywin, Tk_Visual(tkwin), Tk_Depth(tkwin), Tk_Colormap(tkwin)); Tk_CreateEventHandler(pwPtr->proxywin, ExposureMask, ProxyWindowEventProc, - (ClientData) pwPtr); + pwPtr); atts.save_under = True; Tk_ChangeWindowAttributes(pwPtr->proxywin, CWSaveUnder, &atts); @@ -506,7 +506,7 @@ Tk_PanedWindowObjCmd( return TCL_ERROR; } - Tcl_SetStringObj(Tcl_GetObjResult(interp), Tk_PathName(pwPtr->tkwin), -1); + Tcl_SetObjResult(interp, TkNewWindowObj(pwPtr->tkwin)); return TCL_OK; } @@ -535,9 +535,9 @@ PanedWindowWidgetObjCmd( int objc, /* Number of arguments. */ Tcl_Obj * const objv[]) /* Argument objects. */ { - PanedWindow *pwPtr = (PanedWindow *) clientData; + PanedWindow *pwPtr = clientData; int result = TCL_OK; - static const char *optionStrings[] = { + static const char *const optionStrings[] = { "add", "cget", "configure", "forget", "identify", "panecget", "paneconfigure", "panes", "proxy", "sash", NULL }; @@ -560,7 +560,7 @@ PanedWindowWidgetObjCmd( return TCL_ERROR; } - Tcl_Preserve((ClientData) pwPtr); + Tcl_Preserve(pwPtr); switch ((enum options) index) { case PW_ADD: @@ -618,16 +618,17 @@ PanedWindowWidgetObjCmd( for (count = 0, i = 2; i < objc; i++) { Tk_Window slave = Tk_NameToWindow(interp, Tcl_GetString(objv[i]), pwPtr->tkwin); + if (slave == NULL) { continue; } slavePtr = GetPane(pwPtr, slave); if ((slavePtr != NULL) && (slavePtr->masterPtr != NULL)) { count++; - Tk_ManageGeometry(slave, NULL, (ClientData)NULL); + Tk_ManageGeometry(slave, NULL, NULL); Tk_UnmaintainGeometry(slavePtr->tkwin, pwPtr->tkwin); Tk_DeleteEventHandler(slavePtr->tkwin, StructureNotifyMask, - SlaveStructureProc, (ClientData) slavePtr); + SlaveStructureProc, slavePtr); Tk_UnmapWindow(slavePtr->tkwin); Unlink(slavePtr); } @@ -672,10 +673,13 @@ PanedWindowWidgetObjCmd( objv[3], tkwin); } } - if (i == pwPtr->numSlaves) { - Tcl_SetResult(interp, "not managed by this window", TCL_STATIC); - } if (resultObj == NULL) { + if (i == pwPtr->numSlaves) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "not managed by this window", -1)); + Tcl_SetErrorCode(interp, "TK", "PANEDWINDOW", "UNMANAGED", + NULL); + } result = TCL_ERROR; } else { Tcl_SetObjResult(interp, resultObj); @@ -723,15 +727,11 @@ PanedWindowWidgetObjCmd( case PW_PANES: resultObj = Tcl_NewObj(); - - Tcl_IncrRefCount(resultObj); - for (i = 0; i < pwPtr->numSlaves; i++) { - Tcl_ListObjAppendElement(interp, resultObj, - Tcl_NewStringObj(Tk_PathName(pwPtr->slaves[i]->tkwin),-1)); + Tcl_ListObjAppendElement(NULL, resultObj, + TkNewWindowObj(pwPtr->slaves[i]->tkwin)); } Tcl_SetObjResult(interp, resultObj); - Tcl_DecrRefCount(resultObj); break; case PW_PROXY: @@ -742,7 +742,7 @@ PanedWindowWidgetObjCmd( result = PanedWindowSashCommand(pwPtr, interp, objc, objv); break; } - Tcl_Release((ClientData) pwPtr); + Tcl_Release(pwPtr); return result; } @@ -775,7 +775,7 @@ ConfigureSlaves( Tk_Window tkwin = NULL, ancestor, parent; Slave *slavePtr, **inserts, **newSlaves; Slave options; - char *arg; + const char *arg; /* * Find the non-window name arguments; these are the configure options for @@ -801,18 +801,19 @@ ConfigureSlaves( * A panedwindow cannot manage itself. */ - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "can't add ", arg, " to itself", - NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't add %s to itself", arg)); + Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "SELF", NULL); return TCL_ERROR; } else if (Tk_IsTopLevel(tkwin)) { /* * A panedwindow cannot manage a toplevel. */ - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "can't add toplevel ", arg, " to ", - Tk_PathName(pwPtr->tkwin), NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't add toplevel %s to %s", arg, + Tk_PathName(pwPtr->tkwin))); + Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "TOPLEVEL", NULL); return TCL_ERROR; } else { /* @@ -826,9 +827,11 @@ ConfigureSlaves( break; } if (Tk_IsTopLevel(ancestor)) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "can't add ", arg, " to ", - Tk_PathName(pwPtr->tkwin), NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't add %s to %s", arg, + Tk_PathName(pwPtr->tkwin))); + Tcl_SetErrorCode(interp, "TK", "GEOMETRY", + "HIERARCHY", NULL); return TCL_ERROR; } } @@ -885,9 +888,10 @@ ConfigureSlaves( */ if (haveLoc && index == -1) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "window \"", Tk_PathName(tkwin), - "\" is not managed by ", Tk_PathName(pwPtr->tkwin), NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "window \"%s\" is not managed by %s", + Tk_PathName(tkwin), Tk_PathName(pwPtr->tkwin))); + Tcl_SetErrorCode(interp, "TK", "PANEDWINDOW", "UNMANAGED", NULL); Tk_FreeConfigOptions((char *) &options, pwPtr->slaveOpts, pwPtr->tkwin); return TCL_ERROR; @@ -899,7 +903,7 @@ ConfigureSlaves( * structures may already have existed, some may be new. */ - inserts = (Slave **)ckalloc(sizeof(Slave *) * (firstOptionArg - 2)); + inserts = ckalloc(sizeof(Slave *) * (firstOptionArg - 2)); insertIndex = 0; /* @@ -966,7 +970,7 @@ ConfigureSlaves( * out with their "natural" dimensions. */ - slavePtr = (Slave *) ckalloc(sizeof(Slave)); + slavePtr = ckalloc(sizeof(Slave)); memset(slavePtr, 0, sizeof(Slave)); Tk_InitOptions(interp, (char *)slavePtr, pwPtr->slaveOpts, pwPtr->tkwin); @@ -995,9 +999,8 @@ ConfigureSlaves( */ Tk_CreateEventHandler(slavePtr->tkwin, StructureNotifyMask, - SlaveStructureProc, (ClientData) slavePtr); - Tk_ManageGeometry(slavePtr->tkwin, &panedWindowMgrType, - (ClientData) slavePtr); + SlaveStructureProc, slavePtr); + Tk_ManageGeometry(slavePtr->tkwin, &panedWindowMgrType, slavePtr); inserts[insertIndex++] = slavePtr; numNewSlaves++; } @@ -1006,8 +1009,8 @@ ConfigureSlaves( * Allocate the new slaves array, then copy the slaves into it, in order. */ - i = sizeof(Slave *) * (pwPtr->numSlaves+numNewSlaves); - newSlaves = (Slave **)ckalloc((unsigned) i); + i = sizeof(Slave *) * (pwPtr->numSlaves + numNewSlaves); + newSlaves = ckalloc(i); memset(newSlaves, 0, (size_t) i); if (index == -1) { /* @@ -1050,8 +1053,8 @@ ConfigureSlaves( * Make the new slaves array the paned window's slave array, and clean up. */ - ckfree((void *)pwPtr->slaves); - ckfree((void *)inserts); + ckfree(pwPtr->slaves); + ckfree(inserts); pwPtr->slaves = newSlaves; /* @@ -1090,7 +1093,7 @@ PanedWindowSashCommand( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - static const char *sashOptionStrings[] = { + static const char *const sashOptionStrings[] = { "coord", "dragto", "mark", "place", NULL }; enum sashOptions { @@ -1110,7 +1113,6 @@ PanedWindowSashCommand( return TCL_ERROR; } - Tcl_ResetResult(interp); switch ((enum sashOptions) index) { case SASH_COORD: if (objc != 4) { @@ -1123,15 +1125,16 @@ PanedWindowSashCommand( } if (!ValidSashIndex(pwPtr, sash)) { - Tcl_ResetResult(interp); - Tcl_SetResult(interp, "invalid sash index", TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "invalid sash index", -1)); + Tcl_SetErrorCode(interp, "TK", "VALUE", "SASH_INDEX", NULL); return TCL_ERROR; } slavePtr = pwPtr->slaves[sash]; coords[0] = Tcl_NewIntObj(slavePtr->sashx); coords[1] = Tcl_NewIntObj(slavePtr->sashy); - Tcl_SetListObj(Tcl_GetObjResult(interp), 2, coords); + Tcl_SetObjResult(interp, Tcl_NewListObj(2, coords)); break; case SASH_MARK: @@ -1145,8 +1148,9 @@ PanedWindowSashCommand( } if (!ValidSashIndex(pwPtr, sash)) { - Tcl_ResetResult(interp); - Tcl_SetResult(interp, "invalid sash index", TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "invalid sash index", -1)); + Tcl_SetErrorCode(interp, "TK", "VALUE", "SASH_INDEX", NULL); return TCL_ERROR; } @@ -1164,7 +1168,7 @@ PanedWindowSashCommand( } else { coords[0] = Tcl_NewIntObj(pwPtr->slaves[sash]->markx); coords[1] = Tcl_NewIntObj(pwPtr->slaves[sash]->marky); - Tcl_SetListObj(Tcl_GetObjResult(interp), 2, coords); + Tcl_SetObjResult(interp, Tcl_NewListObj(2, coords)); } break; @@ -1180,8 +1184,9 @@ PanedWindowSashCommand( } if (!ValidSashIndex(pwPtr, sash)) { - Tcl_ResetResult(interp); - Tcl_SetResult(interp, "invalid sash index", TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "invalid sash index", -1)); + Tcl_SetErrorCode(interp, "TK", "VALUE", "SASH_INDEX", NULL); return TCL_ERROR; } @@ -1252,7 +1257,7 @@ ConfigurePanedWindow( Tk_FreeSavedOptions(&savedOptions); - PanedWindowWorldChanged((ClientData) pwPtr); + PanedWindowWorldChanged(pwPtr); /* * If an option that affects geometry has changed, make a re-layout @@ -1290,7 +1295,7 @@ PanedWindowWorldChanged( { XGCValues gcValues; GC newGC; - PanedWindow *pwPtr = (PanedWindow *) instanceData; + PanedWindow *pwPtr = instanceData; /* * Allocated a graphics context for drawing the paned window widget @@ -1319,7 +1324,7 @@ PanedWindowWorldChanged( */ if (Tk_IsMapped(pwPtr->tkwin) && !(pwPtr->flags & REDRAW_PENDING)) { - Tcl_DoWhenIdle(DisplayPanedWindow, (ClientData) pwPtr); + Tcl_DoWhenIdle(DisplayPanedWindow, pwPtr); pwPtr->flags |= REDRAW_PENDING; } } @@ -1347,29 +1352,33 @@ PanedWindowEventProc( ClientData clientData, /* Information about window. */ XEvent *eventPtr) /* Information about event. */ { - PanedWindow *pwPtr = (PanedWindow *) clientData; + PanedWindow *pwPtr = clientData; int i; if (eventPtr->type == Expose) { if (pwPtr->tkwin != NULL && !(pwPtr->flags & REDRAW_PENDING)) { - Tcl_DoWhenIdle(DisplayPanedWindow, (ClientData) pwPtr); + Tcl_DoWhenIdle(DisplayPanedWindow, pwPtr); pwPtr->flags |= REDRAW_PENDING; } } else if (eventPtr->type == ConfigureNotify) { pwPtr->flags |= REQUESTED_RELAYOUT; if (pwPtr->tkwin != NULL && !(pwPtr->flags & REDRAW_PENDING)) { - Tcl_DoWhenIdle(DisplayPanedWindow, (ClientData) pwPtr); + Tcl_DoWhenIdle(DisplayPanedWindow, pwPtr); pwPtr->flags |= REDRAW_PENDING; } } else if (eventPtr->type == DestroyNotify) { DestroyPanedWindow(pwPtr); } else if (eventPtr->type == UnmapNotify) { for (i = 0; i < pwPtr->numSlaves; i++) { - Tk_UnmapWindow(pwPtr->slaves[i]->tkwin); + if (!pwPtr->slaves[i]->hide) { + Tk_UnmapWindow(pwPtr->slaves[i]->tkwin); + } } } else if (eventPtr->type == MapNotify) { for (i = 0; i < pwPtr->numSlaves; i++) { - Tk_MapWindow(pwPtr->slaves[i]->tkwin); + if (!pwPtr->slaves[i]->hide) { + Tk_MapWindow(pwPtr->slaves[i]->tkwin); + } } } } @@ -1396,7 +1405,7 @@ static void PanedWindowCmdDeletedProc( ClientData clientData) /* Pointer to widget record for widget. */ { - PanedWindow *pwPtr = (PanedWindow *) clientData; + PanedWindow *pwPtr = clientData; /* * This function could be invoked either because the window was destroyed @@ -1433,7 +1442,7 @@ static void DisplayPanedWindow( ClientData clientData) /* Information about window. */ { - PanedWindow *pwPtr = (PanedWindow *) clientData; + PanedWindow *pwPtr = clientData; Slave *slavePtr; Pixmap pixmap; Tk_Window tkwin = pwPtr->tkwin; @@ -1553,10 +1562,10 @@ DestroyPanedWindow( */ if (pwPtr->flags & REDRAW_PENDING) { - Tcl_CancelIdleCall(DisplayPanedWindow, (ClientData) pwPtr); + Tcl_CancelIdleCall(DisplayPanedWindow, pwPtr); } if (pwPtr->flags & RESIZE_PENDING) { - Tcl_CancelIdleCall(ArrangePanes, (ClientData) pwPtr); + Tcl_CancelIdleCall(ArrangePanes, pwPtr); } /* @@ -1568,15 +1577,15 @@ DestroyPanedWindow( for (i = 0; i < pwPtr->numSlaves; i++) { Tk_DeleteEventHandler(pwPtr->slaves[i]->tkwin, StructureNotifyMask, - SlaveStructureProc, (ClientData) pwPtr->slaves[i]); + SlaveStructureProc, pwPtr->slaves[i]); Tk_ManageGeometry(pwPtr->slaves[i]->tkwin, NULL, NULL); - Tk_FreeConfigOptions((char *)pwPtr->slaves[i], pwPtr->slaveOpts, + Tk_FreeConfigOptions((char *) pwPtr->slaves[i], pwPtr->slaveOpts, pwPtr->tkwin); - ckfree((void *)pwPtr->slaves[i]); + ckfree(pwPtr->slaves[i]); pwPtr->slaves[i] = NULL; } if (pwPtr->slaves) { - ckfree((char *) pwPtr->slaves); + ckfree(pwPtr->slaves); } /* @@ -1590,10 +1599,10 @@ DestroyPanedWindow( */ Tk_FreeConfigOptions((char *) pwPtr, pwPtr->optionTable, pwPtr->tkwin); - Tcl_Release((ClientData) pwPtr->tkwin); + Tcl_Release(pwPtr->tkwin); pwPtr->tkwin = NULL; - Tcl_EventuallyFree((ClientData) pwPtr, TCL_DYNAMIC); + Tcl_EventuallyFree(pwPtr, TCL_DYNAMIC); } /* @@ -1621,12 +1630,13 @@ PanedWindowReqProc( Tk_Window tkwin) /* Other Tk-related information about the * window. */ { - Slave *slavePtr = (Slave *) clientData; - PanedWindow *pwPtr = (PanedWindow *) (slavePtr->masterPtr); + Slave *slavePtr = clientData; + PanedWindow *pwPtr = (PanedWindow *) slavePtr->masterPtr; + if (Tk_IsMapped(pwPtr->tkwin)) { if (!(pwPtr->flags & RESIZE_PENDING)) { pwPtr->flags |= RESIZE_PENDING; - Tcl_DoWhenIdle(ArrangePanes, (ClientData) pwPtr); + Tcl_DoWhenIdle(ArrangePanes, pwPtr); } } else { int doubleBw = 2 * Tk_Changes(slavePtr->tkwin)->border_width; @@ -1665,18 +1675,18 @@ PanedWindowLostSlaveProc( * stolen away. */ Tk_Window tkwin) /* Tk's handle for the slave window. */ { - register Slave *slavePtr = (Slave *) clientData; - PanedWindow *pwPtr = (PanedWindow *) (slavePtr->masterPtr); + register Slave *slavePtr = clientData; + PanedWindow *pwPtr = (PanedWindow *) slavePtr->masterPtr; if (pwPtr->tkwin != Tk_Parent(slavePtr->tkwin)) { Tk_UnmaintainGeometry(slavePtr->tkwin, pwPtr->tkwin); } Unlink(slavePtr); Tk_DeleteEventHandler(slavePtr->tkwin, StructureNotifyMask, - SlaveStructureProc, (ClientData) slavePtr); + SlaveStructureProc, slavePtr); Tk_UnmapWindow(slavePtr->tkwin); slavePtr->tkwin = NULL; - ckfree((void *)slavePtr); + ckfree(slavePtr); ComputeGeometry(pwPtr); } @@ -1704,7 +1714,7 @@ ArrangePanes( ClientData clientData) /* Structure describing parent whose slaves * are to be re-layed out. */ { - register PanedWindow *pwPtr = (PanedWindow *) clientData; + register PanedWindow *pwPtr = clientData; register Slave *slavePtr; int i, slaveWidth, slaveHeight, slaveX, slaveY; int paneWidth, paneHeight, paneSize, paneMinSize; @@ -1731,7 +1741,7 @@ ArrangePanes( return; } - Tcl_Preserve((ClientData) pwPtr); + Tcl_Preserve(pwPtr); /* * Find index of first and last visible panes. @@ -1779,10 +1789,18 @@ ArrangePanes( */ if (horizontal) { - paneSize = slavePtr->paneWidth; + if (slavePtr->width > 0) { + paneSize = slavePtr->width; + } else { + paneSize = slavePtr->paneWidth; + } stretchReserve -= paneSize + (2 * slavePtr->padx); } else { - paneSize = slavePtr->paneHeight; + if (slavePtr->height > 0) { + paneSize = slavePtr->height; + } else { + paneSize = slavePtr->paneHeight; + } stretchReserve -= paneSize + (2 * slavePtr->pady); } if (IsStretchable(slavePtr->stretch,i,first,last) @@ -1832,10 +1850,18 @@ ArrangePanes( */ if (horizontal) { - paneSize = slavePtr->paneWidth; + if (slavePtr->width > 0) { + paneSize = slavePtr->width; + } else { + paneSize = slavePtr->paneWidth; + } pwSize = pwWidth; } else { - paneSize = slavePtr->paneHeight; + if (slavePtr->height > 0) { + paneSize = slavePtr->height; + } else { + paneSize = slavePtr->paneHeight; + } pwSize = pwHeight; } if (IsStretchable(slavePtr->stretch, i, first, last)) { @@ -1967,7 +1993,7 @@ ArrangePanes( } sashCount--; } - Tcl_Release((ClientData) pwPtr); + Tcl_Release(pwPtr); } /* @@ -2028,7 +2054,7 @@ Unlink( masterPtr->flags |= REQUESTED_RELAYOUT; if (!(masterPtr->flags & REDRAW_PENDING)) { masterPtr->flags |= REDRAW_PENDING; - Tcl_DoWhenIdle(DisplayPanedWindow, (ClientData) masterPtr); + Tcl_DoWhenIdle(DisplayPanedWindow, masterPtr); } /* @@ -2134,13 +2160,13 @@ SlaveStructureProc( ClientData clientData, /* Pointer to record describing window item. */ XEvent *eventPtr) /* Describes what just happened. */ { - Slave *slavePtr = (Slave *) clientData; + Slave *slavePtr = clientData; PanedWindow *pwPtr = slavePtr->masterPtr; if (eventPtr->type == DestroyNotify) { Unlink(slavePtr); slavePtr->tkwin = NULL; - ckfree((void *)slavePtr); + ckfree(slavePtr); ComputeGeometry(pwPtr); } } @@ -2319,7 +2345,7 @@ ComputeGeometry( Tk_GeometryRequest(pwPtr->tkwin, reqWidth, reqHeight); if (Tk_IsMapped(pwPtr->tkwin) && !(pwPtr->flags & REDRAW_PENDING)) { pwPtr->flags |= REDRAW_PENDING; - Tcl_DoWhenIdle(DisplayPanedWindow, (ClientData) pwPtr); + Tcl_DoWhenIdle(DisplayPanedWindow, pwPtr); } } @@ -2346,8 +2372,7 @@ DestroyOptionTables( ClientData clientData, /* Pointer to the OptionTables struct */ Tcl_Interp *interp) /* Pointer to the calling interp */ { - ckfree((char *)clientData); - return; + ckfree(clientData); } /* @@ -2376,22 +2401,22 @@ GetSticky( * sticky value. */ { int sticky = *(int *)(recordPtr + internalOffset); - static char buffer[5]; - int count = 0; + char buffer[5]; + char *p = &buffer[0]; if (sticky & STICK_NORTH) { - buffer[count++] = 'n'; + *p++ = 'n'; } if (sticky & STICK_EAST) { - buffer[count++] = 'e'; + *p++ = 'e'; } if (sticky & STICK_SOUTH) { - buffer[count++] = 's'; + *p++ = 's'; } if (sticky & STICK_WEST) { - buffer[count++] = 'w'; + *p++ = 'w'; } - buffer[count] = '\0'; + *p = '\0'; return Tcl_NewStringObj(buffer, -1); } @@ -2430,7 +2455,8 @@ SetSticky( int flags) /* Flags for the option, set Tk_SetOptions. */ { int sticky = 0; - char c, *string, *internalPtr; + char c, *internalPtr; + const char *string; internalPtr = ComputeSlotAddress(recordPtr, internalOffset); @@ -2460,10 +2486,11 @@ SetSticky( case ' ': case ',': case '\t': case '\r': case '\n': break; default: - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "bad stickyness value \"", - Tcl_GetString(*value), "\": must be a string ", - "containing zero or more of n, e, s, and w", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad stickyness value \"%s\": must be a string" + " containing zero or more of n, e, s, and w", + Tcl_GetString(*value))); + Tcl_SetErrorCode(interp, "TK", "VALUE", "STICKY", NULL); return TCL_ERROR; } } @@ -2716,7 +2743,7 @@ MoveSash( * None. * * Side effects: - * When the window gets deleted, internal structures get cleaned up. Whena + * When the window gets deleted, internal structures get cleaned up. When * it gets exposed, it is redisplayed. * *-------------------------------------------------------------- @@ -2727,11 +2754,11 @@ ProxyWindowEventProc( ClientData clientData, /* Information about window. */ XEvent *eventPtr) /* Information about event. */ { - PanedWindow *pwPtr = (PanedWindow *) clientData; + PanedWindow *pwPtr = clientData; if (eventPtr->type == Expose) { if (pwPtr->proxywin != NULL &&!(pwPtr->flags & PROXY_REDRAW_PENDING)) { - Tcl_DoWhenIdle(DisplayProxyWindow, (ClientData) pwPtr); + Tcl_DoWhenIdle(DisplayProxyWindow, pwPtr); pwPtr->flags |= PROXY_REDRAW_PENDING; } } @@ -2759,7 +2786,7 @@ static void DisplayProxyWindow( ClientData clientData) /* Information about window. */ { - PanedWindow *pwPtr = (PanedWindow *) clientData; + PanedWindow *pwPtr = clientData; Pixmap pixmap; Tk_Window tkwin = pwPtr->proxywin; pwPtr->flags &= ~PROXY_REDRAW_PENDING; @@ -2822,7 +2849,7 @@ PanedWindowProxyCommand( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - static const char *optionStrings[] = { + static const char *const optionStrings[] = { "coord", "forget", "place", NULL }; enum options { @@ -2851,7 +2878,7 @@ PanedWindowProxyCommand( coords[0] = Tcl_NewIntObj(pwPtr->proxyx); coords[1] = Tcl_NewIntObj(pwPtr->proxyy); - Tcl_SetListObj(Tcl_GetObjResult(interp), 2, coords); + Tcl_SetObjResult(interp, Tcl_NewListObj(2, coords)); break; case PROXY_FORGET: @@ -2906,12 +2933,12 @@ PanedWindowProxyCommand( (2 * Tk_InternalBorderWidth(pwPtr->tkwin)); } - if (sashWidth < 1) { - sashWidth = 1; - } - if (sashHeight < 1) { - sashHeight = 1; - } + if (sashWidth < 1) { + sashWidth = 1; + } + if (sashHeight < 1) { + sashHeight = 1; + } /* * Stash the proxy coordinates for future "proxy coord" calls. @@ -2965,16 +2992,13 @@ static int ObjectIsEmpty( Tcl_Obj *objPtr) /* Object to test. May be NULL. */ { - int length; - if (objPtr == NULL) { return 1; } - if (objPtr->bytes != NULL) { - return (objPtr->length == 0); + if (objPtr->bytes == NULL) { + Tcl_GetString(objPtr); } - Tcl_GetStringFromObj(objPtr, &length); - return (length == 0); + return (objPtr->length == 0); } /* @@ -3032,11 +3056,9 @@ PanedWindowIdentifyCoords( Tcl_Interp *interp, /* Interpreter in which to store result. */ int x, int y) /* Coordinates of the point to identify. */ { - Tcl_Obj *list; int i, sashHeight, sashWidth, thisx, thisy; int found, isHandle, lpad, rpad, tpad, bpad; int first, last; - list = Tcl_NewObj(); if (pwPtr->orient == ORIENT_HORIZONTAL) { if (Tk_IsMapped(pwPtr->tkwin)) { @@ -3112,16 +3134,17 @@ PanedWindowIdentifyCoords( } /* - * Set results. + * Set results. Note that the empty string is the default (this function + * is called inside the implementation of a command). */ if (found != -1) { - Tcl_ListObjAppendElement(interp, list, Tcl_NewIntObj(found)); - Tcl_ListObjAppendElement(interp, list, Tcl_NewStringObj( - (isHandle ? "handle" : "sash"), -1)); - } + Tcl_Obj *list[2]; - Tcl_SetObjResult(interp, list); + list[0] = Tcl_NewIntObj(found); + list[1] = Tcl_NewStringObj((isHandle ? "handle" : "sash"), -1); + Tcl_SetObjResult(interp, Tcl_NewListObj(2, list)); + } return TCL_OK; } diff --git a/generic/tkPlace.c b/generic/tkPlace.c index 19af02c..7aa9b04 100644 --- a/generic/tkPlace.c +++ b/generic/tkPlace.c @@ -24,7 +24,7 @@ * actual window size. */ -static CONST char *borderModeStrings[] = { +static const char *const borderModeStrings[] = { "inside", "outside", "ignore", NULL }; @@ -84,7 +84,7 @@ static const Tk_OptionSpec optionSpecs[] = { {TK_OPTION_ANCHOR, "-anchor", NULL, NULL, "nw", -1, Tk_Offset(Slave, anchor), 0, 0, 0}, {TK_OPTION_STRING_TABLE, "-bordermode", NULL, NULL, "inside", -1, - Tk_Offset(Slave, borderMode), 0, (ClientData) borderModeStrings, 0}, + Tk_Offset(Slave, borderMode), 0, borderModeStrings, 0}, {TK_OPTION_PIXELS, "-height", NULL, NULL, "", Tk_Offset(Slave, heightPtr), Tk_Offset(Slave, height), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_WINDOW, "-in", NULL, NULL, "", -1, Tk_Offset(Slave, inTkwin), @@ -172,7 +172,7 @@ static void SlaveStructureProc(ClientData clientData, XEvent *eventPtr); static int ConfigureSlave(Tcl_Interp *interp, Tk_Window tkwin, Tk_OptionTable table, int objc, - Tcl_Obj *CONST objv[]); + Tcl_Obj *const objv[]); static int PlaceInfoCommand(Tcl_Interp *interp, Tk_Window tkwin); static Slave * CreateSlave(Tk_Window tkwin, Tk_OptionTable table); static void FreeSlave(Slave *slavePtr); @@ -203,17 +203,17 @@ static void UnlinkSlave(Slave *slavePtr); int Tk_PlaceObjCmd( - ClientData clientData, /* NULL. */ + ClientData clientData, /* Interpreter main window. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { + Tk_Window main_win = clientData; Tk_Window tkwin; Slave *slavePtr; - char *string; TkDisplay *dispPtr; Tk_OptionTable optionTable; - static CONST char *optionStrings[] = { + static const char *const optionStrings[] = { "configure", "forget", "info", "slaves", NULL }; enum options { PLACE_CONFIGURE, PLACE_FORGET, PLACE_INFO, PLACE_SLAVES }; @@ -235,10 +235,9 @@ Tk_PlaceObjCmd( * Handle special shortcut where window name is first argument. */ - string = Tcl_GetString(objv[1]); - if (string[0] == '.') { - tkwin = Tk_NameToWindow(interp, string, Tk_MainWindow(interp)); - if (tkwin == NULL) { + if (Tcl_GetString(objv[1])[0] == '.') { + if (TkGetWindowFromObj(interp, main_win, objv[1], + &tkwin) != TCL_OK) { return TCL_ERROR; } @@ -261,9 +260,8 @@ Tk_PlaceObjCmd( * possible additional arguments. */ - tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), - Tk_MainWindow(interp)); - if (tkwin == NULL) { + if (TkGetWindowFromObj(interp, main_win, objv[2], + &tkwin) != TCL_OK) { return TCL_ERROR; } @@ -278,8 +276,8 @@ Tk_PlaceObjCmd( dispPtr->placeInit = 1; } - if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0, - &index) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings, + sizeof(char *), "option", 0, &index) != TCL_OK) { return TCL_ERROR; } @@ -319,8 +317,8 @@ Tk_PlaceObjCmd( Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->slaveTable, (char *) tkwin)); Tk_DeleteEventHandler(tkwin, StructureNotifyMask, SlaveStructureProc, - (ClientData) slavePtr); - Tk_ManageGeometry(tkwin, NULL, (ClientData) NULL); + slavePtr); + Tk_ManageGeometry(tkwin, NULL, NULL); Tk_UnmapWindow(tkwin); FreeSlave(slavePtr); break; @@ -345,8 +343,8 @@ Tk_PlaceObjCmd( for (slavePtr = masterPtr->slavePtr; slavePtr != NULL; slavePtr = slavePtr->nextPtr) { - Tcl_ListObjAppendElement(interp, listPtr, - Tcl_NewStringObj(Tk_PathName(slavePtr->tkwin),-1)); + Tcl_ListObjAppendElement(NULL, listPtr, + TkNewWindowObj(slavePtr->tkwin)); } Tcl_SetObjResult(interp, listPtr); } @@ -386,7 +384,7 @@ CreateSlave( hPtr = Tcl_CreateHashEntry(&dispPtr->slaveTable, (char *) tkwin, &isNew); if (!isNew) { - return (Slave *) Tcl_GetHashValue(hPtr); + return Tcl_GetHashValue(hPtr); } /* @@ -394,7 +392,7 @@ CreateSlave( * populate it with some default values. */ - slavePtr = (Slave *) ckalloc(sizeof(Slave)); + slavePtr = ckalloc(sizeof(Slave)); memset(slavePtr, 0, sizeof(Slave)); slavePtr->tkwin = tkwin; slavePtr->inTkwin = NULL; @@ -403,7 +401,7 @@ CreateSlave( slavePtr->optionTable = table; Tcl_SetHashValue(hPtr, slavePtr); Tk_CreateEventHandler(tkwin, StructureNotifyMask, SlaveStructureProc, - (ClientData) slavePtr); + slavePtr); return slavePtr; } @@ -429,7 +427,7 @@ FreeSlave( { Tk_FreeConfigOptions((char *) slavePtr, slavePtr->optionTable, slavePtr->tkwin); - ckfree((char *) slavePtr); + ckfree(slavePtr); } /* @@ -454,16 +452,14 @@ static Slave * FindSlave( Tk_Window tkwin) /* Token for desired slave. */ { - Tcl_HashEntry *hPtr; - register Slave *slavePtr; + register Tcl_HashEntry *hPtr; TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; hPtr = Tcl_FindHashEntry(&dispPtr->slaveTable, (char *) tkwin); if (hPtr == NULL) { return NULL; } - slavePtr = (Slave *) Tcl_GetHashValue(hPtr); - return slavePtr; + return Tcl_GetHashValue(hPtr); } /* @@ -507,7 +503,7 @@ UnlinkSlave( } } } - + if (masterPtr->abortPtr != NULL) { *masterPtr->abortPtr = 1; } @@ -542,16 +538,16 @@ CreateMaster( hPtr = Tcl_CreateHashEntry(&dispPtr->masterTable, (char *) tkwin, &isNew); if (isNew) { - masterPtr = (Master *) ckalloc(sizeof(Master)); + masterPtr = ckalloc(sizeof(Master)); masterPtr->tkwin = tkwin; masterPtr->slavePtr = NULL; masterPtr->abortPtr = NULL; masterPtr->flags = 0; Tcl_SetHashValue(hPtr, masterPtr); Tk_CreateEventHandler(masterPtr->tkwin, StructureNotifyMask, - MasterStructureProc, (ClientData) masterPtr); + MasterStructureProc, masterPtr); } else { - masterPtr = (Master *) Tcl_GetHashValue(hPtr); + masterPtr = Tcl_GetHashValue(hPtr); } return masterPtr; } @@ -579,16 +575,14 @@ static Master * FindMaster( Tk_Window tkwin) /* Token for desired master. */ { - Tcl_HashEntry *hPtr; - register Master *masterPtr; + register Tcl_HashEntry *hPtr; TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; hPtr = Tcl_FindHashEntry(&dispPtr->masterTable, (char *) tkwin); if (hPtr == NULL) { return NULL; } - masterPtr = (Master *) Tcl_GetHashValue(hPtr); - return masterPtr; + return Tcl_GetHashValue(hPtr); } /* @@ -616,17 +610,20 @@ ConfigureSlave( Tk_Window tkwin, /* Token for the window to manipulate. */ Tk_OptionTable table, /* Token for option table. */ int objc, /* Number of config arguments. */ - Tcl_Obj *CONST objv[]) /* Object values for arguments. */ + Tcl_Obj *const objv[]) /* Object values for arguments. */ { register Master *masterPtr; Tk_SavedOptions savedOptions; int mask; Slave *slavePtr; Tk_Window masterWin = (Tk_Window) NULL; + TkWindow *master; if (Tk_TopWinHierarchy(tkwin)) { - Tcl_AppendResult(interp, "can't use placer on top-level window \"", - Tk_PathName(tkwin), "\"; use wm command instead", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't use placer on top-level window \"%s\"; use " + "wm command instead", Tk_PathName(tkwin))); + Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "TOPLEVEL", NULL); return TCL_ERROR; } @@ -658,7 +655,7 @@ ConfigureSlave( slavePtr->flags |= CHILD_WIDTH; } - if (((mask & IN_MASK) == 0) && (slavePtr->masterPtr != NULL)) { + if (!(mask & IN_MASK) && (slavePtr->masterPtr != NULL)) { /* * If no -in option was passed and the slave is already placed then * just recompute the placement. @@ -684,18 +681,39 @@ ConfigureSlave( break; } if (Tk_TopWinHierarchy(ancestor)) { - Tcl_AppendResult(interp, "can't place ", - Tk_PathName(slavePtr->tkwin), " relative to ", - Tk_PathName(tkwin), NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't place %s relative to %s", + Tk_PathName(slavePtr->tkwin), Tk_PathName(tkwin))); + Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "HIERARCHY", NULL); goto error; } } if (slavePtr->tkwin == tkwin) { - Tcl_AppendResult(interp, "can't place ", - Tk_PathName(slavePtr->tkwin), " relative to itself", - NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't place %s relative to itself", + Tk_PathName(slavePtr->tkwin))); + Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "LOOP", NULL); goto error; } + + /* + * Check for management loops. + */ + + for (master = (TkWindow *)tkwin; master != NULL; + master = (TkWindow *)TkGetGeomMaster(master)) { + if (master == (TkWindow *)slavePtr->tkwin) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't put %s inside %s, would cause management loop", + Tk_PathName(slavePtr->tkwin), Tk_PathName(tkwin))); + Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "LOOP", NULL); + goto error; + } + } + if (tkwin != Tk_Parent(slavePtr->tkwin)) { + ((TkWindow *)slavePtr->tkwin)->maintainerPtr = (TkWindow *)tkwin; + } + if ((slavePtr->masterPtr != NULL) && (slavePtr->masterPtr->tkwin == tkwin)) { /* @@ -730,7 +748,7 @@ ConfigureSlave( slavePtr->masterPtr = masterPtr; slavePtr->nextPtr = masterPtr->slavePtr; masterPtr->slavePtr = slavePtr; - Tk_ManageGeometry(slavePtr->tkwin, &placerType, (ClientData) slavePtr); + Tk_ManageGeometry(slavePtr->tkwin, &placerType, slavePtr); /* * Arrange for the master to be re-arranged at the first idle moment. @@ -741,7 +759,7 @@ ConfigureSlave( if (!(masterPtr->flags & PARENT_RECONFIG_PENDING)) { masterPtr->flags |= PARENT_RECONFIG_PENDING; - Tcl_DoWhenIdle(RecomputePlacement, (ClientData) masterPtr); + Tcl_DoWhenIdle(RecomputePlacement, masterPtr); } return TCL_OK; @@ -777,54 +795,50 @@ PlaceInfoCommand( Tcl_Interp *interp, /* Interp into which to place result. */ Tk_Window tkwin) /* Token for the window to get info on. */ { - char buffer[32 + TCL_INTEGER_SPACE]; Slave *slavePtr; + Tcl_Obj *infoObj; slavePtr = FindSlave(tkwin); if (slavePtr == NULL) { return TCL_OK; } + infoObj = Tcl_NewObj(); if (slavePtr->masterPtr != NULL) { - Tcl_AppendElement(interp, "-in"); - Tcl_AppendElement(interp, Tk_PathName(slavePtr->masterPtr->tkwin)); + Tcl_AppendToObj(infoObj, "-in", -1); + Tcl_ListObjAppendElement(NULL, infoObj, + TkNewWindowObj(slavePtr->masterPtr->tkwin)); + Tcl_AppendToObj(infoObj, " ", -1); } - sprintf(buffer, " -x %d", slavePtr->x); - Tcl_AppendResult(interp, buffer, NULL); - sprintf(buffer, " -relx %.4g", slavePtr->relX); - Tcl_AppendResult(interp, buffer, NULL); - sprintf(buffer, " -y %d", slavePtr->y); - Tcl_AppendResult(interp, buffer, NULL); - sprintf(buffer, " -rely %.4g", slavePtr->relY); - Tcl_AppendResult(interp, buffer, NULL); + Tcl_AppendPrintfToObj(infoObj, + "-x %d -relx %.4g -y %d -rely %.4g", + slavePtr->x, slavePtr->relX, slavePtr->y, slavePtr->relY); if (slavePtr->flags & CHILD_WIDTH) { - sprintf(buffer, " -width %d", slavePtr->width); - Tcl_AppendResult(interp, buffer, NULL); + Tcl_AppendPrintfToObj(infoObj, " -width %d", slavePtr->width); } else { - Tcl_AppendResult(interp, " -width {}", NULL); + Tcl_AppendToObj(infoObj, " -width {}", -1); } if (slavePtr->flags & CHILD_REL_WIDTH) { - sprintf(buffer, " -relwidth %.4g", slavePtr->relWidth); - Tcl_AppendResult(interp, buffer, NULL); + Tcl_AppendPrintfToObj(infoObj, + " -relwidth %.4g", slavePtr->relWidth); } else { - Tcl_AppendResult(interp, " -relwidth {}", NULL); + Tcl_AppendToObj(infoObj, " -relwidth {}", -1); } if (slavePtr->flags & CHILD_HEIGHT) { - sprintf(buffer, " -height %d", slavePtr->height); - Tcl_AppendResult(interp, buffer, NULL); + Tcl_AppendPrintfToObj(infoObj, " -height %d", slavePtr->height); } else { - Tcl_AppendResult(interp, " -height {}", NULL); + Tcl_AppendToObj(infoObj, " -height {}", -1); } if (slavePtr->flags & CHILD_REL_HEIGHT) { - sprintf(buffer, " -relheight %.4g", slavePtr->relHeight); - Tcl_AppendResult(interp, buffer, NULL); + Tcl_AppendPrintfToObj(infoObj, + " -relheight %.4g", slavePtr->relHeight); } else { - Tcl_AppendResult(interp, " -relheight {}", NULL); + Tcl_AppendToObj(infoObj, " -relheight {}", -1); } - Tcl_AppendElement(interp, "-anchor"); - Tcl_AppendElement(interp, Tk_NameOfAnchor(slavePtr->anchor)); - Tcl_AppendElement(interp, "-bordermode"); - Tcl_AppendElement(interp, borderModeStrings[slavePtr->borderMode]); + Tcl_AppendPrintfToObj(infoObj, " -anchor %s -bordermode %s", + Tk_NameOfAnchor(slavePtr->anchor), + borderModeStrings[slavePtr->borderMode]); + Tcl_SetObjResult(interp, infoObj); return TCL_OK; } @@ -849,21 +863,20 @@ static void RecomputePlacement( ClientData clientData) /* Pointer to Master record. */ { - register Master *masterPtr = (Master *) clientData; + register Master *masterPtr = clientData; register Slave *slavePtr; int x, y, width, height, tmp; int masterWidth, masterHeight, masterX, masterY; double x1, y1, x2, y2; - int abort; /* May get set to non-zero to abort this * placement operation. */ masterPtr->flags &= ~PARENT_RECONFIG_PENDING; - + /* * Abort any nested call to RecomputePlacement for this window, since - * we'll do everything necessary here, and set up so this call - * can be aborted if necessary. + * we'll do everything necessary here, and set up so this call can be + * aborted if necessary. */ if (masterPtr->abortPtr != NULL) { @@ -871,13 +884,13 @@ RecomputePlacement( } masterPtr->abortPtr = &abort; abort = 0; - Tcl_Preserve((ClientData) masterPtr); + Tcl_Preserve(masterPtr); /* * Iterate over all the slaves for the master. Each slave's geometry can * be computed independently of the other slaves. Changes to the window's * structure could cause almost anything to happen, including deleting the - * parent or child. If this happens, we'll be told to abort. + * parent or child. If this happens, we'll be told to abort. */ for (slavePtr = masterPtr->slavePtr; slavePtr != NULL && !abort; @@ -1044,7 +1057,7 @@ RecomputePlacement( } masterPtr->abortPtr = NULL; - Tcl_Release((ClientData) masterPtr); + Tcl_Release(masterPtr); } /* @@ -1071,17 +1084,19 @@ MasterStructureProc( * referred to by eventPtr. */ XEvent *eventPtr) /* Describes what just happened. */ { - register Master *masterPtr = (Master *) clientData; + register Master *masterPtr = clientData; register Slave *slavePtr, *nextPtr; TkDisplay *dispPtr = ((TkWindow *) masterPtr->tkwin)->dispPtr; - if (eventPtr->type == ConfigureNotify) { + switch (eventPtr->type) { + case ConfigureNotify: if ((masterPtr->slavePtr != NULL) && !(masterPtr->flags & PARENT_RECONFIG_PENDING)) { masterPtr->flags |= PARENT_RECONFIG_PENDING; - Tcl_DoWhenIdle(RecomputePlacement, (ClientData) masterPtr); + Tcl_DoWhenIdle(RecomputePlacement, masterPtr); } - } else if (eventPtr->type == DestroyNotify) { + return; + case DestroyNotify: for (slavePtr = masterPtr->slavePtr; slavePtr != NULL; slavePtr = nextPtr) { slavePtr->masterPtr = NULL; @@ -1091,14 +1106,15 @@ MasterStructureProc( Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->masterTable, (char *) masterPtr->tkwin)); if (masterPtr->flags & PARENT_RECONFIG_PENDING) { - Tcl_CancelIdleCall(RecomputePlacement, (ClientData) masterPtr); + Tcl_CancelIdleCall(RecomputePlacement, masterPtr); } masterPtr->tkwin = NULL; if (masterPtr->abortPtr != NULL) { *masterPtr->abortPtr = 1; } - Tcl_EventuallyFree((ClientData) masterPtr, TCL_DYNAMIC); - } else if (eventPtr->type == MapNotify) { + Tcl_EventuallyFree(masterPtr, TCL_DYNAMIC); + return; + case MapNotify: /* * When a master gets mapped, must redo the geometry computation so * that all of its slaves get remapped. @@ -1107,9 +1123,10 @@ MasterStructureProc( if ((masterPtr->slavePtr != NULL) && !(masterPtr->flags & PARENT_RECONFIG_PENDING)) { masterPtr->flags |= PARENT_RECONFIG_PENDING; - Tcl_DoWhenIdle(RecomputePlacement, (ClientData) masterPtr); + Tcl_DoWhenIdle(RecomputePlacement, masterPtr); } - } else if (eventPtr->type == UnmapNotify) { + return; + case UnmapNotify: /* * Unmap all of the slaves when the master gets unmapped, so that they * don't keep redisplaying themselves. @@ -1119,6 +1136,7 @@ MasterStructureProc( slavePtr = slavePtr->nextPtr) { Tk_UnmapWindow(slavePtr->tkwin); } + return; } } @@ -1145,7 +1163,7 @@ SlaveStructureProc( * referred to by eventPtr. */ XEvent *eventPtr) /* Describes what just happened. */ { - register Slave *slavePtr = (Slave *) clientData; + register Slave *slavePtr = clientData; TkDisplay *dispPtr = ((TkWindow *) slavePtr->tkwin)->dispPtr; if (eventPtr->type == DestroyNotify) { @@ -1182,11 +1200,17 @@ PlaceRequestProc( ClientData clientData, /* Pointer to our record for slave. */ Tk_Window tkwin) /* Window that changed its desired size. */ { - Slave *slavePtr = (Slave *) clientData; + Slave *slavePtr = clientData; Master *masterPtr; - if (((slavePtr->flags & (CHILD_WIDTH|CHILD_REL_WIDTH)) != 0) - && ((slavePtr->flags & (CHILD_HEIGHT|CHILD_REL_HEIGHT)) != 0)) { + if ((slavePtr->flags & (CHILD_WIDTH|CHILD_REL_WIDTH)) + && (slavePtr->flags & (CHILD_HEIGHT|CHILD_REL_HEIGHT))) { + /* + * Send a ConfigureNotify to indicate that the size change + * request was rejected. + */ + + TkDoConfigureNotify((TkWindow *)(slavePtr->tkwin)); return; } masterPtr = slavePtr->masterPtr; @@ -1195,7 +1219,7 @@ PlaceRequestProc( } if (!(masterPtr->flags & PARENT_RECONFIG_PENDING)) { masterPtr->flags |= PARENT_RECONFIG_PENDING; - Tcl_DoWhenIdle(RecomputePlacement, (ClientData) masterPtr); + Tcl_DoWhenIdle(RecomputePlacement, masterPtr); } } @@ -1223,7 +1247,7 @@ PlaceLostSlaveProc( * stolen away. */ Tk_Window tkwin) /* Tk's handle for the slave window. */ { - register Slave *slavePtr = (Slave *) clientData; + register Slave *slavePtr = clientData; TkDisplay *dispPtr = ((TkWindow *) slavePtr->tkwin)->dispPtr; if (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin)) { @@ -1234,7 +1258,7 @@ PlaceLostSlaveProc( Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->slaveTable, (char *) tkwin)); Tk_DeleteEventHandler(tkwin, StructureNotifyMask, SlaveStructureProc, - (ClientData) slavePtr); + slavePtr); FreeSlave(slavePtr); } diff --git a/generic/tkPlatDecls.h b/generic/tkPlatDecls.h index eb3d74d..1e69c88 100644 --- a/generic/tkPlatDecls.h +++ b/generic/tkPlatDecls.h @@ -23,6 +23,10 @@ * in the generic/tk.decls script. */ +#ifdef __cplusplus +extern "C" { +#endif + /* !BEGIN!: Do not edit below this line. */ #ifdef __cplusplus @@ -33,43 +37,23 @@ extern "C" { * Exported function declarations: */ -#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */ -#ifndef Tk_AttachHWND_TCL_DECLARED -#define Tk_AttachHWND_TCL_DECLARED +#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ /* 0 */ EXTERN Window Tk_AttachHWND(Tk_Window tkwin, HWND hwnd); -#endif -#ifndef Tk_GetHINSTANCE_TCL_DECLARED -#define Tk_GetHINSTANCE_TCL_DECLARED /* 1 */ EXTERN HINSTANCE Tk_GetHINSTANCE(void); -#endif -#ifndef Tk_GetHWND_TCL_DECLARED -#define Tk_GetHWND_TCL_DECLARED /* 2 */ EXTERN HWND Tk_GetHWND(Window window); -#endif -#ifndef Tk_HWNDToWindow_TCL_DECLARED -#define Tk_HWNDToWindow_TCL_DECLARED /* 3 */ EXTERN Tk_Window Tk_HWNDToWindow(HWND hwnd); -#endif -#ifndef Tk_PointerEvent_TCL_DECLARED -#define Tk_PointerEvent_TCL_DECLARED /* 4 */ EXTERN void Tk_PointerEvent(HWND hwnd, int x, int y); -#endif -#ifndef Tk_TranslateWinEvent_TCL_DECLARED -#define Tk_TranslateWinEvent_TCL_DECLARED /* 5 */ EXTERN int Tk_TranslateWinEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result); -#endif #endif /* WIN */ #ifdef MAC_OSX_TK /* AQUA */ -#ifndef Tk_MacOSXSetEmbedHandler_TCL_DECLARED -#define Tk_MacOSXSetEmbedHandler_TCL_DECLARED /* 0 */ EXTERN void Tk_MacOSXSetEmbedHandler( Tk_MacOSXEmbedRegisterWinProc *registerWinProcPtr, @@ -77,65 +61,34 @@ EXTERN void Tk_MacOSXSetEmbedHandler( Tk_MacOSXEmbedMakeContainerExistProc *containerExistProcPtr, Tk_MacOSXEmbedGetClipProc *getClipProc, Tk_MacOSXEmbedGetOffsetInParentProc *getOffsetProc); -#endif -#ifndef Tk_MacOSXTurnOffMenus_TCL_DECLARED -#define Tk_MacOSXTurnOffMenus_TCL_DECLARED /* 1 */ EXTERN void Tk_MacOSXTurnOffMenus(void); -#endif -#ifndef Tk_MacOSXTkOwnsCursor_TCL_DECLARED -#define Tk_MacOSXTkOwnsCursor_TCL_DECLARED /* 2 */ EXTERN void Tk_MacOSXTkOwnsCursor(int tkOwnsIt); -#endif -#ifndef TkMacOSXInitMenus_TCL_DECLARED -#define TkMacOSXInitMenus_TCL_DECLARED /* 3 */ EXTERN void TkMacOSXInitMenus(Tcl_Interp *interp); -#endif -#ifndef TkMacOSXInitAppleEvents_TCL_DECLARED -#define TkMacOSXInitAppleEvents_TCL_DECLARED /* 4 */ EXTERN void TkMacOSXInitAppleEvents(Tcl_Interp *interp); -#endif -#ifndef TkGenWMConfigureEvent_TCL_DECLARED -#define TkGenWMConfigureEvent_TCL_DECLARED /* 5 */ EXTERN void TkGenWMConfigureEvent(Tk_Window tkwin, int x, int y, int width, int height, int flags); -#endif -#ifndef TkMacOSXInvalClipRgns_TCL_DECLARED -#define TkMacOSXInvalClipRgns_TCL_DECLARED /* 6 */ EXTERN void TkMacOSXInvalClipRgns(Tk_Window tkwin); -#endif -#ifndef TkMacOSXGetDrawablePort_TCL_DECLARED -#define TkMacOSXGetDrawablePort_TCL_DECLARED /* 7 */ -EXTERN VOID * TkMacOSXGetDrawablePort(Drawable drawable); -#endif -#ifndef TkMacOSXGetRootControl_TCL_DECLARED -#define TkMacOSXGetRootControl_TCL_DECLARED +EXTERN void * TkMacOSXGetDrawablePort(Drawable drawable); /* 8 */ -EXTERN VOID * TkMacOSXGetRootControl(Drawable drawable); -#endif -#ifndef Tk_MacOSXSetupTkNotifier_TCL_DECLARED -#define Tk_MacOSXSetupTkNotifier_TCL_DECLARED +EXTERN void * TkMacOSXGetRootControl(Drawable drawable); /* 9 */ EXTERN void Tk_MacOSXSetupTkNotifier(void); -#endif -#ifndef Tk_MacOSXIsAppInFront_TCL_DECLARED -#define Tk_MacOSXIsAppInFront_TCL_DECLARED /* 10 */ EXTERN int Tk_MacOSXIsAppInFront(void); -#endif #endif /* AQUA */ typedef struct TkPlatStubs { int magic; - struct TkPlatStubHooks *hooks; + void *hooks; -#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */ +#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ Window (*tk_AttachHWND) (Tk_Window tkwin, HWND hwnd); /* 0 */ HINSTANCE (*tk_GetHINSTANCE) (void); /* 1 */ HWND (*tk_GetHWND) (Window window); /* 2 */ @@ -151,102 +104,72 @@ typedef struct TkPlatStubs { void (*tkMacOSXInitAppleEvents) (Tcl_Interp *interp); /* 4 */ void (*tkGenWMConfigureEvent) (Tk_Window tkwin, int x, int y, int width, int height, int flags); /* 5 */ void (*tkMacOSXInvalClipRgns) (Tk_Window tkwin); /* 6 */ - VOID * (*tkMacOSXGetDrawablePort) (Drawable drawable); /* 7 */ - VOID * (*tkMacOSXGetRootControl) (Drawable drawable); /* 8 */ + void * (*tkMacOSXGetDrawablePort) (Drawable drawable); /* 7 */ + void * (*tkMacOSXGetRootControl) (Drawable drawable); /* 8 */ void (*tk_MacOSXSetupTkNotifier) (void); /* 9 */ int (*tk_MacOSXIsAppInFront) (void); /* 10 */ #endif /* AQUA */ } TkPlatStubs; -extern TkPlatStubs *tkPlatStubsPtr; +extern const TkPlatStubs *tkPlatStubsPtr; #ifdef __cplusplus } #endif -#if defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS) +#if defined(USE_TK_STUBS) /* * Inline function declarations: */ -#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */ -#ifndef Tk_AttachHWND +#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ #define Tk_AttachHWND \ (tkPlatStubsPtr->tk_AttachHWND) /* 0 */ -#endif -#ifndef Tk_GetHINSTANCE #define Tk_GetHINSTANCE \ (tkPlatStubsPtr->tk_GetHINSTANCE) /* 1 */ -#endif -#ifndef Tk_GetHWND #define Tk_GetHWND \ (tkPlatStubsPtr->tk_GetHWND) /* 2 */ -#endif -#ifndef Tk_HWNDToWindow #define Tk_HWNDToWindow \ (tkPlatStubsPtr->tk_HWNDToWindow) /* 3 */ -#endif -#ifndef Tk_PointerEvent #define Tk_PointerEvent \ (tkPlatStubsPtr->tk_PointerEvent) /* 4 */ -#endif -#ifndef Tk_TranslateWinEvent #define Tk_TranslateWinEvent \ (tkPlatStubsPtr->tk_TranslateWinEvent) /* 5 */ -#endif #endif /* WIN */ #ifdef MAC_OSX_TK /* AQUA */ -#ifndef Tk_MacOSXSetEmbedHandler #define Tk_MacOSXSetEmbedHandler \ (tkPlatStubsPtr->tk_MacOSXSetEmbedHandler) /* 0 */ -#endif -#ifndef Tk_MacOSXTurnOffMenus #define Tk_MacOSXTurnOffMenus \ (tkPlatStubsPtr->tk_MacOSXTurnOffMenus) /* 1 */ -#endif -#ifndef Tk_MacOSXTkOwnsCursor #define Tk_MacOSXTkOwnsCursor \ (tkPlatStubsPtr->tk_MacOSXTkOwnsCursor) /* 2 */ -#endif -#ifndef TkMacOSXInitMenus #define TkMacOSXInitMenus \ (tkPlatStubsPtr->tkMacOSXInitMenus) /* 3 */ -#endif -#ifndef TkMacOSXInitAppleEvents #define TkMacOSXInitAppleEvents \ (tkPlatStubsPtr->tkMacOSXInitAppleEvents) /* 4 */ -#endif -#ifndef TkGenWMConfigureEvent #define TkGenWMConfigureEvent \ (tkPlatStubsPtr->tkGenWMConfigureEvent) /* 5 */ -#endif -#ifndef TkMacOSXInvalClipRgns #define TkMacOSXInvalClipRgns \ (tkPlatStubsPtr->tkMacOSXInvalClipRgns) /* 6 */ -#endif -#ifndef TkMacOSXGetDrawablePort #define TkMacOSXGetDrawablePort \ (tkPlatStubsPtr->tkMacOSXGetDrawablePort) /* 7 */ -#endif -#ifndef TkMacOSXGetRootControl #define TkMacOSXGetRootControl \ (tkPlatStubsPtr->tkMacOSXGetRootControl) /* 8 */ -#endif -#ifndef Tk_MacOSXSetupTkNotifier #define Tk_MacOSXSetupTkNotifier \ (tkPlatStubsPtr->tk_MacOSXSetupTkNotifier) /* 9 */ -#endif -#ifndef Tk_MacOSXIsAppInFront #define Tk_MacOSXIsAppInFront \ (tkPlatStubsPtr->tk_MacOSXIsAppInFront) /* 10 */ -#endif #endif /* AQUA */ -#endif /* defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS) */ +#endif /* defined(USE_TK_STUBS) */ /* !END!: Do not edit above this line. */ +#ifdef __cplusplus +} +#endif + #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT diff --git a/generic/tkPointer.c b/generic/tkPointer.c index dd4f7e6..0141b64 100644 --- a/generic/tkPointer.c +++ b/generic/tkPointer.c @@ -14,7 +14,7 @@ #include "tkInt.h" -#ifdef __WIN32__ +#ifdef _WIN32 #include "tkWinInt.h" #endif @@ -30,7 +30,7 @@ #define ALL_BUTTONS \ (Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask) -static unsigned int buttonMasks[] = { +static const unsigned int buttonMasks[] = { Button1Mask, Button2Mask, Button3Mask, Button4Mask, Button5Mask }; #define ButtonMask(b) (buttonMasks[(b)-Button1]) @@ -54,7 +54,7 @@ static Tcl_ThreadDataKey dataKey; static int GenerateEnterLeave(TkWindow *winPtr, int x, int y, int state); -static void InitializeEvent(XEvent* eventPtr, TkWindow *winPtr, +static void InitializeEvent(XEvent *eventPtr, TkWindow *winPtr, int type, int x, int y, int state, int detail); static void UpdateCursor(TkWindow *winPtr); @@ -138,7 +138,7 @@ GenerateEnterLeave( int state) /* State flags. */ { int crossed = 0; /* 1 if mouse crossed a window boundary */ - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); TkWindow *restrictWinPtr = tsdPtr->restrictWinPtr; TkWindow *lastWinPtr = tsdPtr->lastWinPtr; @@ -231,7 +231,7 @@ Tk_UpdatePointer( int x, int y, /* Pointer location in root coords. */ int state) /* Modifier state mask. */ { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); TkWindow *winPtr = (TkWindow *)tkwin; TkWindow *targetWinPtr; @@ -286,7 +286,7 @@ Tk_UpdatePointer( tsdPtr->restrictWinPtr = winPtr; TkpSetCapture(tsdPtr->restrictWinPtr); - } else if ((tsdPtr->lastState & ALL_BUTTONS) == 0) { + } else if (!(tsdPtr->lastState & ALL_BUTTONS)) { /* * Mouse is in a non-button grab, so ensure the button * grab is inside the grab tree. @@ -436,7 +436,7 @@ XGrabPointer( Cursor cursor, Time time) { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); display->request++; @@ -471,7 +471,7 @@ XUngrabPointer( Display *display, Time time) { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); display->request++; @@ -502,7 +502,7 @@ void TkPointerDeadWindow( TkWindow *winPtr) { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (winPtr == tsdPtr->lastWinPtr) { @@ -541,7 +541,7 @@ UpdateCursor( TkWindow *winPtr) { Cursor cursor = None; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* @@ -586,8 +586,8 @@ XDefineCursor( Window w, Cursor cursor) { - TkWindow *winPtr = (TkWindow *)Tk_IdToWindow(display, w); - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + TkWindow *winPtr = (TkWindow *) Tk_IdToWindow(display, w); + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (tsdPtr->cursorWinPtr == winPtr) { diff --git a/generic/tkPort.h b/generic/tkPort.h index 00c49fd..d6db449 100644 --- a/generic/tkPort.h +++ b/generic/tkPort.h @@ -14,16 +14,13 @@ #ifndef _TKPORT #define _TKPORT -#ifndef _TK -#include "tk.h" +#if defined(_WIN32) +# include "tkWinPort.h" #endif -#ifndef _TCL -#include "tcl.h" +#ifndef _TK +# include "tk.h" #endif - -#if defined(__WIN32__) || defined(_WIN32) -# include "tkWinPort.h" -#else +#if !defined(_WIN32) # if defined(MAC_OSX_TK) # include "tkMacOSXPort.h" # else diff --git a/generic/tkRectOval.c b/generic/tkRectOval.c index 55c2a61..359d3ef 100644 --- a/generic/tkRectOval.c +++ b/generic/tkRectOval.c @@ -10,7 +10,6 @@ * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ -#include <stdio.h> #include "tkInt.h" #include "tkCanvas.h" @@ -43,40 +42,35 @@ typedef struct RectOvalItem { * Information used for parsing configuration specs: */ -static Tk_CustomOption stateOption = { - (Tk_OptionParseProc *) TkStateParseProc, - TkStatePrintProc, (ClientData) 2 +static const Tk_CustomOption stateOption = { + TkStateParseProc, TkStatePrintProc, INT2PTR(2) }; -static Tk_CustomOption tagsOption = { - (Tk_OptionParseProc *) Tk_CanvasTagsParseProc, - Tk_CanvasTagsPrintProc, (ClientData) NULL +static const Tk_CustomOption tagsOption = { + Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL }; -static Tk_CustomOption dashOption = { - (Tk_OptionParseProc *) TkCanvasDashParseProc, - TkCanvasDashPrintProc, (ClientData) NULL +static const Tk_CustomOption dashOption = { + TkCanvasDashParseProc, TkCanvasDashPrintProc, NULL }; -static Tk_CustomOption offsetOption = { - (Tk_OptionParseProc *) TkOffsetParseProc, - TkOffsetPrintProc, (ClientData) TK_OFFSET_RELATIVE +static const Tk_CustomOption offsetOption = { + TkOffsetParseProc, TkOffsetPrintProc, INT2PTR(TK_OFFSET_RELATIVE) }; -static Tk_CustomOption pixelOption = { - (Tk_OptionParseProc *) TkPixelParseProc, - TkPixelPrintProc, (ClientData) NULL +static const Tk_CustomOption pixelOption = { + TkPixelParseProc, TkPixelPrintProc, NULL }; -static Tk_ConfigSpec configSpecs[] = { +static const Tk_ConfigSpec configSpecs[] = { {TK_CONFIG_CUSTOM, "-activedash", NULL, NULL, NULL, Tk_Offset(RectOvalItem, outline.activeDash), TK_CONFIG_NULL_OK, &dashOption}, {TK_CONFIG_COLOR, "-activefill", NULL, NULL, - NULL, Tk_Offset(RectOvalItem, activeFillColor), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(RectOvalItem, activeFillColor), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_COLOR, "-activeoutline", NULL, NULL, - NULL, Tk_Offset(RectOvalItem, outline.activeColor), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(RectOvalItem, outline.activeColor), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_BITMAP, "-activeoutlinestipple", NULL, NULL, NULL, Tk_Offset(RectOvalItem, outline.activeStipple), - TK_CONFIG_NULL_OK}, + TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_BITMAP, "-activestipple", NULL, NULL, - NULL, Tk_Offset(RectOvalItem, activeFillStipple), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(RectOvalItem, activeFillStipple), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_CUSTOM, "-activewidth", NULL, NULL, "0.0", Tk_Offset(RectOvalItem, outline.activeWidth), TK_CONFIG_DONT_SET_DEFAULT, &pixelOption}, @@ -85,45 +79,45 @@ static Tk_ConfigSpec configSpecs[] = { TK_CONFIG_NULL_OK, &dashOption}, {TK_CONFIG_PIXELS, "-dashoffset", NULL, NULL, "0", Tk_Offset(RectOvalItem, outline.offset), - TK_CONFIG_DONT_SET_DEFAULT}, + TK_CONFIG_DONT_SET_DEFAULT, NULL}, {TK_CONFIG_CUSTOM, "-disableddash", NULL, NULL, NULL, Tk_Offset(RectOvalItem, outline.disabledDash), TK_CONFIG_NULL_OK, &dashOption}, {TK_CONFIG_COLOR, "-disabledfill", NULL, NULL, - NULL, Tk_Offset(RectOvalItem, disabledFillColor), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(RectOvalItem, disabledFillColor), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_COLOR, "-disabledoutline", NULL, NULL, NULL, Tk_Offset(RectOvalItem, outline.disabledColor), - TK_CONFIG_NULL_OK}, + TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_BITMAP, "-disabledoutlinestipple", NULL, NULL, NULL, Tk_Offset(RectOvalItem, outline.disabledStipple), - TK_CONFIG_NULL_OK}, + TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_BITMAP, "-disabledstipple", NULL, NULL, - NULL, Tk_Offset(RectOvalItem, disabledFillStipple), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(RectOvalItem, disabledFillStipple), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_PIXELS, "-disabledwidth", NULL, NULL, "0.0", Tk_Offset(RectOvalItem, outline.disabledWidth), TK_CONFIG_DONT_SET_DEFAULT, &pixelOption}, {TK_CONFIG_COLOR, "-fill", NULL, NULL, - NULL, Tk_Offset(RectOvalItem, fillColor), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(RectOvalItem, fillColor), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_CUSTOM, "-offset", NULL, NULL, "0,0", Tk_Offset(RectOvalItem, tsoffset), TK_CONFIG_DONT_SET_DEFAULT, &offsetOption}, {TK_CONFIG_COLOR, "-outline", NULL, NULL, - "black", Tk_Offset(RectOvalItem, outline.color), TK_CONFIG_NULL_OK}, + "black", Tk_Offset(RectOvalItem, outline.color), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_CUSTOM, "-outlineoffset", NULL, NULL, "0,0", Tk_Offset(RectOvalItem, outline.tsoffset), TK_CONFIG_DONT_SET_DEFAULT, &offsetOption}, {TK_CONFIG_BITMAP, "-outlinestipple", NULL, NULL, - NULL, Tk_Offset(RectOvalItem, outline.stipple), TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(RectOvalItem, outline.stipple), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_CUSTOM, "-state", NULL, NULL, NULL, Tk_Offset(Tk_Item, state),TK_CONFIG_NULL_OK, &stateOption}, {TK_CONFIG_BITMAP, "-stipple", NULL, NULL, - NULL, Tk_Offset(RectOvalItem, fillStipple),TK_CONFIG_NULL_OK}, + NULL, Tk_Offset(RectOvalItem, fillStipple),TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_CUSTOM, "-tags", NULL, NULL, NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, {TK_CONFIG_CUSTOM, "-width", NULL, NULL, "1.0", Tk_Offset(RectOvalItem, outline.width), TK_CONFIG_DONT_SET_DEFAULT, &pixelOption}, - {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} + {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL} }; /* @@ -133,10 +127,10 @@ static Tk_ConfigSpec configSpecs[] = { static void ComputeRectOvalBbox(Tk_Canvas canvas, RectOvalItem *rectOvalPtr); static int ConfigureRectOval(Tcl_Interp *interp, Tk_Canvas canvas, - Tk_Item *itemPtr, int objc, Tcl_Obj *CONST objv[], + Tk_Item *itemPtr, int objc, Tcl_Obj *const objv[], int flags); static int CreateRectOval(Tcl_Interp *interp, Tk_Canvas canvas, - Tk_Item *itemPtr, int objc, Tcl_Obj *CONST objv[]); + Tk_Item *itemPtr, int objc, Tcl_Obj *const objv[]); static void DeleteRectOval(Tk_Canvas canvas, Tk_Item *itemPtr, Display *display); static void DisplayRectOval(Tk_Canvas canvas, Tk_Item *itemPtr, @@ -147,7 +141,7 @@ static int OvalToArea(Tk_Canvas canvas, Tk_Item *itemPtr, static double OvalToPoint(Tk_Canvas canvas, Tk_Item *itemPtr, double *pointPtr); static int RectOvalCoords(Tcl_Interp *interp, Tk_Canvas canvas, - Tk_Item *itemPtr, int objc, Tcl_Obj *CONST objv[]); + Tk_Item *itemPtr, int objc, Tcl_Obj *const objv[]); static int RectOvalToPostscript(Tcl_Interp *interp, Tk_Canvas canvas, Tk_Item *itemPtr, int prepass); static int RectToArea(Tk_Canvas canvas, Tk_Item *itemPtr, @@ -186,6 +180,7 @@ Tk_ItemType tkRectangleType = { NULL, /* insertProc */ NULL, /* dTextProc */ NULL, /* nextPtr */ + NULL, 0, NULL, NULL }; Tk_ItemType tkOvalType = { @@ -209,6 +204,7 @@ Tk_ItemType tkOvalType = { NULL, /* insertProc */ NULL, /* dTextProc */ NULL, /* nextPtr */ + NULL, 0, NULL, NULL }; /* @@ -238,13 +234,13 @@ CreateRectOval( Tk_Item *itemPtr, /* Record to hold new item; header has been * initialized by caller. */ int objc, /* Number of arguments in objv. */ - Tcl_Obj *CONST objv[]) /* Arguments describing rectangle. */ + Tcl_Obj *const objv[]) /* Arguments describing rectangle. */ { RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr; int i; if (objc == 0) { - Tcl_Panic("canvas did not pass any coords\n"); + Tcl_Panic("canvas did not pass any coords"); } /* @@ -269,7 +265,7 @@ CreateRectOval( */ for (i = 1; i < objc; i++) { - char *arg = Tcl_GetString(objv[i]); + const char *arg = Tcl_GetString(objv[i]); if ((arg[0] == '-') && (arg[1] >= 'a') && (arg[1] <= 'z')) { break; @@ -313,7 +309,7 @@ RectOvalCoords( Tk_Item *itemPtr, /* Item whose coordinates are to be read or * modified. */ int objc, /* Number of coordinates supplied in objv. */ - Tcl_Obj *CONST objv[]) /* Array of coordinates: x1,y1,x2,y2,... */ + Tcl_Obj *const objv[]) /* Array of coordinates: x1,y1,x2,y2,... */ { RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr; @@ -322,17 +318,13 @@ RectOvalCoords( */ if (objc == 0) { - Tcl_Obj *obj = Tcl_NewObj(); - - Tcl_ListObjAppendElement(NULL, obj, - Tcl_NewDoubleObj(rectOvalPtr->bbox[0])); - Tcl_ListObjAppendElement(NULL, obj, - Tcl_NewDoubleObj(rectOvalPtr->bbox[1])); - Tcl_ListObjAppendElement(NULL, obj, - Tcl_NewDoubleObj(rectOvalPtr->bbox[2])); - Tcl_ListObjAppendElement(NULL, obj, - Tcl_NewDoubleObj(rectOvalPtr->bbox[3])); - Tcl_SetObjResult(interp, obj); + Tcl_Obj *bbox[4]; + + bbox[0] = Tcl_NewDoubleObj(rectOvalPtr->bbox[0]); + bbox[1] = Tcl_NewDoubleObj(rectOvalPtr->bbox[1]); + bbox[2] = Tcl_NewDoubleObj(rectOvalPtr->bbox[2]); + bbox[3] = Tcl_NewDoubleObj(rectOvalPtr->bbox[3]); + Tcl_SetObjResult(interp, Tcl_NewListObj(4, bbox)); return TCL_OK; } @@ -352,10 +344,11 @@ RectOvalCoords( */ if (objc != 4) { - char buf[64 + TCL_INTEGER_SPACE]; - - sprintf(buf, "wrong # coordinates: expected 0 or 4, got %d", objc); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "wrong # coordinates: expected 0 or 4, got %d", objc)); + Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", + (rectOvalPtr->header.typePtr == &tkRectangleType + ? "RECTANGLE" : "OVAL"), NULL); return TCL_ERROR; } @@ -402,7 +395,7 @@ ConfigureRectOval( Tk_Canvas canvas, /* Canvas containing itemPtr. */ Tk_Item *itemPtr, /* Rectangle item to reconfigure. */ int objc, /* Number of elements in objv. */ - Tcl_Obj *CONST objv[], /* Arguments describing things to configure. */ + Tcl_Obj *const objv[], /* Arguments describing things to configure. */ int flags) /* Flags to pass to Tk_ConfigureWidget. */ { RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr; @@ -418,7 +411,7 @@ ConfigureRectOval( tkwin = Tk_CanvasTkwin(canvas); if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc, - (CONST char **)objv, (char *) rectOvalPtr, flags|TK_CONFIG_OBJS)) { + (const char **)objv, (char *) rectOvalPtr, flags|TK_CONFIG_OBJS)) { return TCL_ERROR; } state = itemPtr->state; @@ -481,7 +474,7 @@ ConfigureRectOval( rectOvalPtr->outline.gc = newGC; if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } if (state == TK_STATE_HIDDEN) { ComputeRectOvalBbox(canvas, rectOvalPtr); @@ -490,7 +483,7 @@ ConfigureRectOval( color = rectOvalPtr->fillColor; stipple = rectOvalPtr->fillStipple; - if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { + if (Canvas(canvas)->currentItemPtr == itemPtr) { if (rectOvalPtr->activeFillColor!=NULL) { color = rectOvalPtr->activeFillColor; } @@ -519,8 +512,8 @@ ConfigureRectOval( } #ifdef MAC_OSX_TK /* - * Mac OS X CG drawing needs access to the outline linewidth - * even for fills (as linewidth controls antialiasing). + * Mac OS X CG drawing needs access to the outline linewidth even for + * fills (as linewidth controls antialiasing). */ gcValues.line_width = rectOvalPtr->outline.gc != NULL ? rectOvalPtr->outline.gc->line_width : 0; @@ -634,7 +627,7 @@ ComputeRectOvalBbox( Tk_State state = rectOvalPtr->header.state; if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } width = rectOvalPtr->outline.width; @@ -643,7 +636,7 @@ ComputeRectOvalBbox( rectOvalPtr->header.x2 = rectOvalPtr->header.y2 = -1; return; } - if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *)rectOvalPtr) { + if (Canvas(canvas)->currentItemPtr == (Tk_Item *) rectOvalPtr) { if (rectOvalPtr->outline.activeWidth>width) { width = rectOvalPtr->outline.activeWidth; } @@ -677,11 +670,11 @@ ComputeRectOvalBbox( * correct place to solve it, but it works. */ -#ifdef __WIN32__ +#ifdef _WIN32 bloat = 1; #else bloat = 0; -#endif +#endif /* _WIN32 */ } else { #ifdef MAC_OSX_TK /* @@ -693,7 +686,7 @@ ComputeRectOvalBbox( bloat = (int) (width+1.5)/2; #else bloat = (int) (width+1)/2; -#endif +#endif /* MAC_OSX_TK */ } /* @@ -761,15 +754,107 @@ DisplayRectOval( * will die if it isn't. */ - Tk_CanvasDrawableCoords(canvas, rectOvalPtr->bbox[0], rectOvalPtr->bbox[1], + Tk_CanvasDrawableCoords(canvas, rectOvalPtr->bbox[0],rectOvalPtr->bbox[1], &x1, &y1); - Tk_CanvasDrawableCoords(canvas, rectOvalPtr->bbox[2], rectOvalPtr->bbox[3], + Tk_CanvasDrawableCoords(canvas, rectOvalPtr->bbox[2],rectOvalPtr->bbox[3], &x2, &y2); - if (x2 <= x1) { - x2 = x1+1; - } - if (y2 <= y1) { - y2 = y1+1; + if (x2 == x1) { + + /* + * The width of the bounding box corresponds to less than one pixel + * on screen. Adjustment is needed to avoid drawing attempts with zero + * width items (which would draw nothing). The bounding box spans + * either 1 or 2 pixels. Select which pixel will be drawn. + */ + + short ix1 = (short) (rectOvalPtr->bbox[0]); + short ix2 = (short) (rectOvalPtr->bbox[2]); + + if (ix1 == ix2) { + + /* + * x1 and x2 are "within the same pixel". Use this pixel. + * Note: the degenerated case (bbox[0]==bbox[2]) of a completely + * flat box results in arbitrary selection of the pixel at the + * right (with positive coordinate) or left (with negative + * coordinate) of the box. There is no "best choice" here. + */ + + if (ix1 > 0) { + x2 += 1; + } else { + x1 -= 1; + } + } else { + + /* + * (x1,x2) span two pixels. Select the one with the larger + * covered "area". + */ + + if (ix1 > 0) { + if ((rectOvalPtr->bbox[2] - ix2) > (ix2 - rectOvalPtr->bbox[0])) { + x2 += 1; + } else { + x1 -= 1; + } + } else { + if ((rectOvalPtr->bbox[2] - ix1) > (ix1 - rectOvalPtr->bbox[0])) { + x2 += 1; + } else { + x1 -= 1; + } + } + } + } + if (y2 == y1) { + + /* + * The height of the bounding box corresponds to less than one pixel + * on screen. Adjustment is needed to avoid drawing attempts with zero + * height items (which would draw nothing). The bounding box spans + * either 1 or 2 pixels. Select which pixel will be drawn. + */ + + short iy1 = (short) (rectOvalPtr->bbox[1]); + short iy2 = (short) (rectOvalPtr->bbox[3]); + + if (iy1 == iy2) { + + /* + * y1 and y2 are "within the same pixel". Use this pixel. + * Note: the degenerated case (bbox[1]==bbox[3]) of a completely + * flat box results in arbitrary selection of the pixel below + * (with positive coordinate) or above (with negative coordinate) + * the box. There is no "best choice" here. + */ + + if (iy1 > 0) { + y2 += 1; + } else { + y1 -= 1; + } + } else { + + /* + * (y1,y2) span two pixels. Select the one with the larger + * covered "area". + */ + + if (iy1 > 0) { + if ((rectOvalPtr->bbox[3] - iy2) > (iy2 - rectOvalPtr->bbox[1])) { + y2 += 1; + } else { + y1 -= 1; + } + } else { + if ((rectOvalPtr->bbox[3] - iy1) > (iy1 - rectOvalPtr->bbox[1])) { + y2 += 1; + } else { + y1 -= 1; + } + } + } } /* @@ -779,10 +864,10 @@ DisplayRectOval( */ if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } fillStipple = rectOvalPtr->fillStipple; - if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *)rectOvalPtr) { + if (Canvas(canvas)->currentItemPtr == (Tk_Item *) rectOvalPtr) { if (rectOvalPtr->activeFillStipple != None) { fillStipple = rectOvalPtr->activeFillStipple; } @@ -884,11 +969,11 @@ RectToPoint( Tk_State state = itemPtr->state; if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } width = rectPtr->outline.width; - if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { + if (Canvas(canvas)->currentItemPtr == itemPtr) { if (rectPtr->outline.activeWidth>width) { width = rectPtr->outline.activeWidth; } @@ -1004,11 +1089,11 @@ OvalToPoint( Tk_State state = itemPtr->state; if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } width = (double) ovalPtr->outline.width; - if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { + if (Canvas(canvas)->currentItemPtr == itemPtr) { if (ovalPtr->outline.activeWidth>width) { width = (double) ovalPtr->outline.activeWidth; } @@ -1060,16 +1145,16 @@ RectToArea( Tk_State state = itemPtr->state; if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } width = rectPtr->outline.width; - if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { - if (rectPtr->outline.activeWidth>width) { + if (Canvas(canvas)->currentItemPtr == itemPtr) { + if (rectPtr->outline.activeWidth > width) { width = rectPtr->outline.activeWidth; } } else if (state == TK_STATE_DISABLED) { - if (rectPtr->outline.disabledWidth>0) { + if (rectPtr->outline.disabledWidth > 0) { width = rectPtr->outline.disabledWidth; } } @@ -1129,22 +1214,21 @@ OvalToArea( * y1, x2, y2) describing rectangular area. */ { RectOvalItem *ovalPtr = (RectOvalItem *) itemPtr; - double oval[4], halfWidth; + double oval[4], halfWidth, width; int result; - double width; Tk_State state = itemPtr->state; if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } width = ovalPtr->outline.width; - if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { - if (ovalPtr->outline.activeWidth>width) { + if (Canvas(canvas)->currentItemPtr == itemPtr) { + if (ovalPtr->outline.activeWidth > width) { width = ovalPtr->outline.activeWidth; } } else if (state == TK_STATE_DISABLED) { - if (ovalPtr->outline.disabledWidth>0) { + if (ovalPtr->outline.disabledWidth > 0) { width = ovalPtr->outline.disabledWidth; } } @@ -1298,13 +1382,14 @@ RectOvalToPostscript( * information; 0 means final Postscript is * being created. */ { - char pathCmd[500]; + Tcl_Obj *pathObj, *psObj; RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr; double y1, y2; XColor *color; XColor *fillColor; Pixmap fillStipple; Tk_State state = itemPtr->state; + Tcl_InterpState interpState; y1 = Tk_CanvasPsY(canvas, rectOvalPtr->bbox[1]); y2 = Tk_CanvasPsY(canvas, rectOvalPtr->bbox[3]); @@ -1315,23 +1400,34 @@ RectOvalToPostscript( */ if (rectOvalPtr->header.typePtr == &tkRectangleType) { - sprintf(pathCmd, "%.15g %.15g moveto %.15g 0 rlineto 0 %.15g rlineto %.15g 0 rlineto closepath\n", + pathObj = Tcl_ObjPrintf( + "%.15g %.15g moveto " + "%.15g 0 rlineto " + "0 %.15g rlineto " + "%.15g 0 rlineto " + "closepath\n", rectOvalPtr->bbox[0], y1, - rectOvalPtr->bbox[2]-rectOvalPtr->bbox[0], y2-y1, + rectOvalPtr->bbox[2]-rectOvalPtr->bbox[0], + y2-y1, rectOvalPtr->bbox[0]-rectOvalPtr->bbox[2]); } else { - sprintf(pathCmd, "matrix currentmatrix\n%.15g %.15g translate %.15g %.15g scale 1 0 moveto 0 0 1 0 360 arc\nsetmatrix\n", + pathObj = Tcl_ObjPrintf( + "matrix currentmatrix\n" + "%.15g %.15g translate " + "%.15g %.15g scale " + "1 0 moveto 0 0 1 0 360 arc\n" + "setmatrix\n", (rectOvalPtr->bbox[0] + rectOvalPtr->bbox[2])/2, (y1 + y2)/2, (rectOvalPtr->bbox[2] - rectOvalPtr->bbox[0])/2, (y1 - y2)/2); } if (state == TK_STATE_NULL) { - state = ((TkCanvas *)canvas)->canvas_state; + state = Canvas(canvas)->canvas_state; } color = rectOvalPtr->outline.color; fillColor = rectOvalPtr->fillColor; fillStipple = rectOvalPtr->fillStipple; - if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { + if (Canvas(canvas)->currentItemPtr == itemPtr) { if (rectOvalPtr->outline.activeColor!=NULL) { color = rectOvalPtr->outline.activeColor; } @@ -1354,24 +1450,38 @@ RectOvalToPostscript( } /* + * Make our working space. + */ + + psObj = Tcl_NewObj(); + interpState = Tcl_SaveInterpState(interp, TCL_OK); + + /* * First draw the filled area of the rectangle. */ if (fillColor != NULL) { - Tcl_AppendResult(interp, pathCmd, NULL); + Tcl_AppendObjToObj(psObj, pathObj); + + Tcl_ResetResult(interp); if (Tk_CanvasPsColor(interp, canvas, fillColor) != TCL_OK) { - return TCL_ERROR; + goto error; } + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); + if (fillStipple != None) { - Tcl_AppendResult(interp, "clip ", NULL); + Tcl_AppendToObj(psObj, "clip ", -1); + + Tcl_ResetResult(interp); if (Tk_CanvasPsStipple(interp, canvas, fillStipple) != TCL_OK) { - return TCL_ERROR; + goto error; } + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); if (color != NULL) { - Tcl_AppendResult(interp, "grestore gsave\n", NULL); + Tcl_AppendToObj(psObj, "grestore gsave\n", -1); } } else { - Tcl_AppendResult(interp, "fill\n", NULL); + Tcl_AppendToObj(psObj, "fill\n", -1); } } @@ -1380,14 +1490,32 @@ RectOvalToPostscript( */ if (color != NULL) { - Tcl_AppendResult(interp, pathCmd, "0 setlinejoin 2 setlinecap\n", - NULL); + Tcl_AppendObjToObj(psObj, pathObj); + Tcl_AppendToObj(psObj, "0 setlinejoin 2 setlinecap\n", -1); + + Tcl_ResetResult(interp); if (Tk_CanvasPsOutline(canvas, itemPtr, - &(rectOvalPtr->outline))!= TCL_OK) { - return TCL_ERROR; + &rectOvalPtr->outline)!= TCL_OK) { + goto error; } + Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); } + + /* + * Plug the accumulated postscript back into the result. + */ + + (void) Tcl_RestoreInterpState(interp, interpState); + Tcl_AppendObjToObj(Tcl_GetObjResult(interp), psObj); + Tcl_DecrRefCount(psObj); + Tcl_DecrRefCount(pathObj); return TCL_OK; + + error: + Tcl_DiscardInterpState(interpState); + Tcl_DecrRefCount(psObj); + Tcl_DecrRefCount(pathObj); + return TCL_ERROR; } /* diff --git a/generic/tkScale.c b/generic/tkScale.c index 6ab574e..5957b00 100644 --- a/generic/tkScale.c +++ b/generic/tkScale.c @@ -21,6 +21,10 @@ #include "tkInt.h" #include "tkScale.h" +#if defined(_WIN32) +#define snprintf _snprintf +#endif + /* * The following table defines the legal values for the -orient option. It is * used together with the "enum orient" declaration in tkScale.h. @@ -42,17 +46,17 @@ static const char *const stateStrings[] = { static const Tk_OptionSpec optionSpecs[] = { {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground", DEF_SCALE_ACTIVE_BG_COLOR, -1, Tk_Offset(TkScale, activeBorder), - 0, (ClientData) DEF_SCALE_ACTIVE_BG_MONO, 0}, + 0, DEF_SCALE_ACTIVE_BG_MONO, 0}, {TK_OPTION_BORDER, "-background", "background", "Background", DEF_SCALE_BG_COLOR, -1, Tk_Offset(TkScale, bgBorder), - 0, (ClientData) DEF_SCALE_BG_MONO, 0}, + 0, DEF_SCALE_BG_MONO, 0}, {TK_OPTION_DOUBLE, "-bigincrement", "bigIncrement", "BigIncrement", DEF_SCALE_BIG_INCREMENT, -1, Tk_Offset(TkScale, bigIncrement), 0, 0, 0}, {TK_OPTION_SYNONYM, "-bd", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-borderwidth", 0}, + NULL, 0, -1, 0, "-borderwidth", 0}, {TK_OPTION_SYNONYM, "-bg", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-background", 0}, + NULL, 0, -1, 0, "-background", 0}, {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", DEF_SCALE_BORDER_WIDTH, -1, Tk_Offset(TkScale, borderWidth), 0, 0, 0}, @@ -66,7 +70,7 @@ static const Tk_OptionSpec optionSpecs[] = { DEF_SCALE_DIGITS, -1, Tk_Offset(TkScale, digits), 0, 0, 0}, {TK_OPTION_SYNONYM, "-fg", "foreground", NULL, - NULL, 0, -1, 0, (ClientData) "-foreground", 0}, + NULL, 0, -1, 0, "-foreground", 0}, {TK_OPTION_FONT, "-font", "font", "Font", DEF_SCALE_FONT, -1, Tk_Offset(TkScale, tkfont), 0, 0, 0}, {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground", @@ -77,7 +81,7 @@ static const Tk_OptionSpec optionSpecs[] = { {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground", "HighlightBackground", DEF_SCALE_HIGHLIGHT_BG_COLOR, -1, Tk_Offset(TkScale, highlightBorder), - 0, (ClientData) DEF_SCALE_HIGHLIGHT_BG_MONO, 0}, + 0, DEF_SCALE_HIGHLIGHT_BG_MONO, 0}, {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", DEF_SCALE_HIGHLIGHT, -1, Tk_Offset(TkScale, highlightColorPtr), 0, 0, 0}, @@ -91,7 +95,7 @@ static const Tk_OptionSpec optionSpecs[] = { DEF_SCALE_LENGTH, -1, Tk_Offset(TkScale, length), 0, 0, 0}, {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient", DEF_SCALE_ORIENT, -1, Tk_Offset(TkScale, orient), - 0, (ClientData) orientStrings, 0}, + 0, orientStrings, 0}, {TK_OPTION_RELIEF, "-relief", "relief", "Relief", DEF_SCALE_RELIEF, -1, Tk_Offset(TkScale, relief), 0, 0, 0}, {TK_OPTION_INT, "-repeatdelay", "repeatDelay", "RepeatDelay", @@ -114,7 +118,7 @@ static const Tk_OptionSpec optionSpecs[] = { 0, 0, 0}, {TK_OPTION_STRING_TABLE, "-state", "state", "State", DEF_SCALE_STATE, -1, Tk_Offset(TkScale, state), - 0, (ClientData) stateStrings, 0}, + 0, stateStrings, 0}, {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", DEF_SCALE_TAKE_FOCUS, Tk_Offset(TkScale, takeFocusPtr), -1, TK_OPTION_NULL_OK, 0, 0}, @@ -125,7 +129,7 @@ static const Tk_OptionSpec optionSpecs[] = { DEF_SCALE_TO, -1, Tk_Offset(TkScale, toValue), 0, 0, 0}, {TK_OPTION_COLOR, "-troughcolor", "troughColor", "Background", DEF_SCALE_TROUGH_COLOR, -1, Tk_Offset(TkScale, troughColorPtr), - 0, (ClientData) DEF_SCALE_TROUGH_MONO, 0}, + 0, DEF_SCALE_TROUGH_MONO, 0}, {TK_OPTION_STRING, "-variable", "variable", "Variable", DEF_SCALE_VARIABLE, Tk_Offset(TkScale, varNamePtr), -1, TK_OPTION_NULL_OK, 0, 0}, @@ -140,7 +144,7 @@ static const Tk_OptionSpec optionSpecs[] = { * scale widget command. */ -static const char *commandNames[] = { +static const char *const commandNames[] = { "cget", "configure", "coords", "get", "identify", "set", NULL }; @@ -153,11 +157,13 @@ enum command { * Forward declarations for procedures defined later in this file: */ -static void ComputeFormat(TkScale *scalePtr); +static void ComputeFormat(TkScale *scalePtr, int forTicks); static void ComputeScaleGeometry(TkScale *scalePtr); static int ConfigureScale(Tcl_Interp *interp, TkScale *scalePtr, int objc, Tcl_Obj *const objv[]); static void DestroyScale(char *memPtr); +static double MaxTickRoundingError(TkScale *scalePtr, + double tickResolution); static void ScaleCmdDeletedProc(ClientData clientData); static void ScaleEventProc(ClientData clientData, XEvent *eventPtr); @@ -175,14 +181,57 @@ static void ScaleSetVariable(TkScale *scalePtr); * that can be invoked from generic window code. */ -static Tk_ClassProcs scaleClass = { +static const Tk_ClassProcs scaleClass = { sizeof(Tk_ClassProcs), /* size */ ScaleWorldChanged, /* worldChangedProc */ + NULL, /* createProc */ + NULL /* modalProc */ }; /* *-------------------------------------------------------------- * + * ScaleDigit, ScaleMax, ScaleMin, ScaleRound -- + * + * Simple math helper functions, designed to be automatically inlined by + * the compiler most of the time. + * + *-------------------------------------------------------------- + */ + +static inline int +ScaleDigit( + double value) +{ + return (int) floor(log10(fabs(value))); +} + +static inline double +ScaleMax( + double a, + double b) +{ + return (a > b) ? a : b; +} + +static inline double +ScaleMin( + double a, + double b) +{ + return (a < b) ? a : b; +} + +static inline int +ScaleRound( + double value) +{ + return (int) floor(value + 0.5); +} + +/* + *-------------------------------------------------------------- + * * Tk_ScaleObjCmd -- * * This procedure is invoked to process the "scale" Tcl command. See the @@ -209,7 +258,7 @@ Tk_ScaleObjCmd( Tk_Window tkwin; if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?"); + Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?"); return TCL_ERROR; } @@ -240,7 +289,7 @@ Tk_ScaleObjCmd( scalePtr->interp = interp; scalePtr->widgetCmd = Tcl_CreateObjCommand(interp, Tk_PathName(scalePtr->tkwin), ScaleWidgetObjCmd, - (ClientData) scalePtr, ScaleCmdDeletedProc); + scalePtr, ScaleCmdDeletedProc); scalePtr->optionTable = optionTable; scalePtr->orient = ORIENT_VERTICAL; scalePtr->width = 0; @@ -289,10 +338,10 @@ Tk_ScaleObjCmd( scalePtr->takeFocusPtr = NULL; scalePtr->flags = NEVER_SET; - Tk_SetClassProcs(scalePtr->tkwin, &scaleClass, (ClientData) scalePtr); + Tk_SetClassProcs(scalePtr->tkwin, &scaleClass, scalePtr); Tk_CreateEventHandler(scalePtr->tkwin, ExposureMask|StructureNotifyMask|FocusChangeMask, - ScaleEventProc, (ClientData) scalePtr); + ScaleEventProc, scalePtr); if ((Tk_InitOptions(interp, (char *) scalePtr, optionTable, tkwin) != TCL_OK) || @@ -301,7 +350,13 @@ Tk_ScaleObjCmd( return TCL_ERROR; } - Tcl_SetResult(interp, Tk_PathName(scalePtr->tkwin), TCL_STATIC); + /* + * The widget was just created, no command callback must be invoked. + */ + + scalePtr->flags &= ~INVOKE_COMMAND; + + Tcl_SetObjResult(interp, TkNewWindowObj(scalePtr->tkwin)); return TCL_OK; } @@ -330,20 +385,20 @@ ScaleWidgetObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument strings. */ { - TkScale *scalePtr = (TkScale *) clientData; + TkScale *scalePtr = clientData; Tcl_Obj *objPtr; int index, result; if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?"); + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); return TCL_ERROR; } - result = Tcl_GetIndexFromObj(interp, objv[1], commandNames, - "option", 0, &index); + result = Tcl_GetIndexFromObjStruct(interp, objv[1], commandNames, + sizeof(char *), "option", 0, &index); if (result != TCL_OK) { return result; } - Tcl_Preserve((ClientData) scalePtr); + Tcl_Preserve(scalePtr); switch (index) { case COMMAND_CGET: @@ -355,9 +410,8 @@ ScaleWidgetObjCmd( scalePtr->optionTable, objv[2], scalePtr->tkwin); if (objPtr == NULL) { goto error; - } else { - Tcl_SetObjResult(interp, objPtr); } + Tcl_SetObjResult(interp, objPtr); break; case COMMAND_CONFIGURE: if (objc <= 3) { @@ -366,17 +420,16 @@ ScaleWidgetObjCmd( (objc == 3) ? objv[2] : NULL, scalePtr->tkwin); if (objPtr == NULL) { goto error; - } else { - Tcl_SetObjResult(interp, objPtr); } + Tcl_SetObjResult(interp, objPtr); } else { result = ConfigureScale(interp, scalePtr, objc-2, objv+2); } break; case COMMAND_COORDS: { - int x, y ; + int x, y; double value; - char buf[TCL_INTEGER_SPACE * 2]; + Tcl_Obj *coords[2]; if ((objc != 2) && (objc != 3)) { Tcl_WrongNumArgs(interp, 1, objv, "coords ?value?"); @@ -398,14 +451,14 @@ ScaleWidgetObjCmd( y = scalePtr->horizTroughY + scalePtr->width/2 + scalePtr->borderWidth; } - sprintf(buf, "%d %d", x, y); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + coords[0] = Tcl_NewIntObj(x); + coords[1] = Tcl_NewIntObj(y); + Tcl_SetObjResult(interp, Tcl_NewListObj(2, coords)); break; } case COMMAND_GET: { double value; int x, y; - char buf[TCL_DOUBLE_SPACE]; if ((objc != 2) && (objc != 4)) { Tcl_WrongNumArgs(interp, 1, objv, "get ?x y?"); @@ -420,12 +473,12 @@ ScaleWidgetObjCmd( } value = TkScalePixelToValue(scalePtr, x, y); } - sprintf(buf, scalePtr->format, value); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_ObjPrintf(scalePtr->valueFormat, value)); break; } case COMMAND_IDENTIFY: { - int x, y, thing; + int x, y; + const char *zone = ""; if (objc != 4) { Tcl_WrongNumArgs(interp, 1, objv, "identify x y"); @@ -435,18 +488,12 @@ ScaleWidgetObjCmd( || (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) { goto error; } - thing = TkpScaleElement(scalePtr, x,y); - switch (thing) { - case TROUGH1: - Tcl_SetResult(interp, "trough1", TCL_STATIC); - break; - case SLIDER: - Tcl_SetResult(interp, "slider", TCL_STATIC); - break; - case TROUGH2: - Tcl_SetResult(interp, "trough2", TCL_STATIC); - break; + switch (TkpScaleElement(scalePtr, x, y)) { + case TROUGH1: zone = "trough1"; break; + case SLIDER: zone = "slider"; break; + case TROUGH2: zone = "trough2"; break; } + Tcl_SetObjResult(interp, Tcl_NewStringObj(zone, -1)); break; } case COMMAND_SET: { @@ -465,11 +512,11 @@ ScaleWidgetObjCmd( break; } } - Tcl_Release((ClientData) scalePtr); + Tcl_Release(scalePtr); return result; error: - Tcl_Release((ClientData) scalePtr); + Tcl_Release(scalePtr); return TCL_ERROR; } @@ -501,7 +548,7 @@ DestroyScale( Tcl_DeleteCommandFromToken(scalePtr->interp, scalePtr->widgetCmd); if (scalePtr->flags & REDRAW_PENDING) { - Tcl_CancelIdleCall(TkpDisplayScale, (ClientData) scalePtr); + Tcl_CancelIdleCall(TkpDisplayScale, scalePtr); } /* @@ -510,9 +557,9 @@ DestroyScale( */ if (scalePtr->varNamePtr != NULL) { - Tcl_UntraceVar(scalePtr->interp, Tcl_GetString(scalePtr->varNamePtr), - TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - ScaleVarProc, (ClientData) scalePtr); + Tcl_UntraceVar2(scalePtr->interp, Tcl_GetString(scalePtr->varNamePtr), + NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + ScaleVarProc, scalePtr); } if (scalePtr->troughGC != NULL) { Tk_FreeGC(scalePtr->display, scalePtr->troughGC); @@ -567,9 +614,9 @@ ConfigureScale( */ if (scalePtr->varNamePtr != NULL) { - Tcl_UntraceVar(interp, Tcl_GetString(scalePtr->varNamePtr), - TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - ScaleVarProc, (ClientData) scalePtr); + Tcl_UntraceVar2(interp, Tcl_GetString(scalePtr->varNamePtr), + NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + ScaleVarProc, scalePtr); } for (error = 0; error <= 1; error++) { @@ -579,8 +626,8 @@ ConfigureScale( */ if (Tk_SetOptions(interp, (char *) scalePtr, - scalePtr->optionTable, objc, objv, - scalePtr->tkwin, &savedOptions, NULL) != TCL_OK) { + scalePtr->optionTable, objc, objv, scalePtr->tkwin, + &savedOptions, NULL) != TCL_OK) { continue; } } else { @@ -607,7 +654,7 @@ ConfigureScale( TCL_GLOBAL_ONLY); if ((valuePtr != NULL) && (Tcl_GetDoubleFromObj(NULL, valuePtr, &value) == TCL_OK)) { - scalePtr->value = TkRoundToResolution(scalePtr, value); + scalePtr->value = TkRoundValueToResolution(scalePtr, value); } } @@ -616,10 +663,10 @@ ConfigureScale( * orientation and creating GCs. */ - scalePtr->fromValue = TkRoundToResolution(scalePtr, + scalePtr->fromValue = TkRoundValueToResolution(scalePtr, scalePtr->fromValue); - scalePtr->toValue = TkRoundToResolution(scalePtr, scalePtr->toValue); - scalePtr->tickInterval = TkRoundToResolution(scalePtr, + scalePtr->toValue = TkRoundValueToResolution(scalePtr, scalePtr->toValue); + scalePtr->tickInterval = TkRoundIntervalToResolution(scalePtr, scalePtr->tickInterval); /* @@ -632,7 +679,8 @@ ConfigureScale( scalePtr->tickInterval = -scalePtr->tickInterval; } - ComputeFormat(scalePtr); + ComputeFormat(scalePtr, 0); + ComputeFormat(scalePtr, 1); scalePtr->labelLength = scalePtr->label ? (int)strlen(scalePtr->label) : 0; @@ -677,18 +725,18 @@ ConfigureScale( } else { char varString[TCL_DOUBLE_SPACE], scaleString[TCL_DOUBLE_SPACE]; - sprintf(varString, scalePtr->format, varValue); - sprintf(scaleString, scalePtr->format, scalePtr->value); - if (strcmp(varString, scaleString)) { + Tcl_PrintDouble(NULL, varValue, varString); + Tcl_PrintDouble(NULL, scalePtr->value, scaleString); + if (strcmp(varString, scaleString)) { ScaleSetVariable(scalePtr); } } - Tcl_TraceVar(interp, Tcl_GetString(scalePtr->varNamePtr), - TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - ScaleVarProc, (ClientData) scalePtr); + Tcl_TraceVar2(interp, Tcl_GetString(scalePtr->varNamePtr), + NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + ScaleVarProc, scalePtr); } - ScaleWorldChanged((ClientData) scalePtr); + ScaleWorldChanged(scalePtr); if (error) { Tcl_SetObjResult(interp, errorResult); Tcl_DecrRefCount(errorResult); @@ -721,9 +769,7 @@ ScaleWorldChanged( { XGCValues gcValues; GC gc; - TkScale *scalePtr; - - scalePtr = (TkScale *) instanceData; + TkScale *scalePtr = instanceData; gcValues.foreground = scalePtr->troughColorPtr->pixel; gc = Tk_GetGC(scalePtr->tkwin, GCForeground, &gcValues); @@ -757,27 +803,77 @@ ScaleWorldChanged( TkEventuallyRedrawScale(scalePtr, REDRAW_ALL); } + /* + *---------------------------------------------------------------------- + * + * MaxTickRoundingError -- + * + * Given the separation between values that can be displayed on ticks, + * this calculates the maximum magnitude of error for the displayed + * value. Tries to be clever by working out the increment in error + * between ticks rather than testing all of them, so may overestimate + * error if it is greater than 0.25 x the value separation. + * + * Results: + * Maximum error magnitude of tick numbers. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static double +MaxTickRoundingError( + TkScale *scalePtr, /* Information about scale widget. */ + double tickResolution) /* Separation between displayable values. */ +{ + double tickPosn, firstTickError, lastTickError, intervalError; + int tickCount; + + /* + * Compute the error for each tick-related measure. + */ + + tickPosn = scalePtr->fromValue / tickResolution; + firstTickError = tickPosn - ScaleRound(tickPosn); + + tickPosn = scalePtr->tickInterval / tickResolution; + intervalError = tickPosn - ScaleRound(tickPosn); + + tickCount = (int) ((scalePtr->toValue - scalePtr->fromValue) / + scalePtr->tickInterval); /* not including first */ + lastTickError = ScaleMin(0.5, + fabs(firstTickError + tickCount * intervalError)); + + /* + * Compute the maximum cumulative rounding error. + */ + + return ScaleMax(fabs(firstTickError), lastTickError) * tickResolution; +} + /* *---------------------------------------------------------------------- * * ComputeFormat -- * - * This procedure is invoked to recompute the "format" field of a scale's - * widget record, which determines how the value of the scale is - * converted to a string. + * This procedure is invoked to recompute the "valueFormat" or + * "tickFormat" field of a scale's widget record, which determines how + * the value of the scale or one of its ticks is converted to a string. * * Results: * None. * - * Side effects: - * The format field of scalePtr is modified. + * Side effects: The valueFormat or tickFormat field of scalePtr is modified. * *---------------------------------------------------------------------- */ static void ComputeFormat( - TkScale *scalePtr) /* Information about scale widget. */ + TkScale *scalePtr, /* Information about scale widget. */ + int forTicks) /* Do for ticks rather than value */ { double maxValue, x; int mostSigDigit, numDigits, leastSigDigit, afterDecimal; @@ -796,48 +892,73 @@ ComputeFormat( if (maxValue == 0) { maxValue = 1; } - mostSigDigit = (int) floor(log10(maxValue)); + mostSigDigit = ScaleDigit(maxValue); - /* - * If the number of significant digits wasn't specified explicitly, - * compute it. It's the difference between the most significant digit - * needed to represent any number on the scale and the most significant - * digit of the smallest difference between numbers on the scale. In other - * words, display enough digits so that at least one digit will be - * different between any two adjacent positions of the scale. - */ + if (forTicks) { + /* + * Display only enough digits to ensure adjacent ticks have different + * values. + */ - numDigits = scalePtr->digits; - if (numDigits > TCL_MAX_PREC) { - numDigits = 0; - } - if (numDigits <= 0) { - if (scalePtr->resolution > 0) { - /* - * A resolution was specified for the scale, so just use it. - */ + if (scalePtr->tickInterval != 0) { + leastSigDigit = ScaleDigit(scalePtr->tickInterval); - leastSigDigit = (int) floor(log10(scalePtr->resolution)); - } else { /* - * No resolution was specified, so compute the difference in value - * between adjacent pixels and use it for the least significant - * digit. + * Now add more digits until max error is less than + * TICK_VALUES_DISPLAY_ACCURACY intervals */ - x = fabs(scalePtr->fromValue - scalePtr->toValue); - if (scalePtr->length > 0) { - x /= scalePtr->length; + while (MaxTickRoundingError(scalePtr, pow(10, leastSigDigit)) + > fabs(TICK_VALUES_DISPLAY_ACCURACY * scalePtr->tickInterval)) { + --leastSigDigit; } - if (x > 0){ - leastSigDigit = (int) floor(log10(x)); + numDigits = 1 + mostSigDigit - leastSigDigit; + } else { + numDigits = 1; + } + } else { + /* + * If the number of significant digits wasn't specified explicitly, + * compute it. It's the difference between the most significant digit + * needed to represent any number on the scale and the most + * significant digit of the smallest difference between numbers on the + * scale. In other words, display enough digits so that at least one + * digit will be different between any two adjacent positions of the + * scale. + */ + + numDigits = scalePtr->digits; + if (numDigits > TCL_MAX_PREC) { + numDigits = 0; + } + if (numDigits <= 0) { + if (scalePtr->resolution > 0) { + /* + * A resolution was specified for the scale, so just use it. + */ + + leastSigDigit = ScaleDigit(scalePtr->resolution); } else { - leastSigDigit = 0; + /* + * No resolution was specified, so compute the difference in + * value between adjacent pixels and use it for the least + * significant digit. + */ + + x = fabs(scalePtr->fromValue - scalePtr->toValue); + if (scalePtr->length > 0) { + x /= scalePtr->length; + } + if (x > 0) { + leastSigDigit = ScaleDigit(x); + } else { + leastSigDigit = 0; + } + } + numDigits = mostSigDigit - leastSigDigit + 1; + if (numDigits < 1) { + numDigits = 1; } - } - numDigits = mostSigDigit - leastSigDigit + 1; - if (numDigits < 1) { - numDigits = 1; } } @@ -861,10 +982,19 @@ ComputeFormat( if (mostSigDigit < 0) { fDigits++; /* Zero to left of decimal point. */ } - if (fDigits <= eDigits) { - sprintf(scalePtr->format, "%%.%df", afterDecimal); + + if (forTicks) { + if (fDigits <= eDigits) { + sprintf(scalePtr->tickFormat, "%%.%df", afterDecimal); + } else { + sprintf(scalePtr->tickFormat, "%%.%de", numDigits - 1); + } } else { - sprintf(scalePtr->format, "%%.%de", numDigits-1); + if (fDigits <= eDigits) { + sprintf(scalePtr->valueFormat, "%%.%df", afterDecimal); + } else { + sprintf(scalePtr->valueFormat, "%%.%de", numDigits - 1); + } } } @@ -892,7 +1022,7 @@ ComputeScaleGeometry( register TkScale *scalePtr) /* Information about widget. */ { char valueString[TCL_DOUBLE_SPACE]; - int tmp, valuePixels, x, y, extraSpace; + int tmp, valuePixels, tickPixels, x, y, extraSpace; Tk_FontMetrics fm; Tk_GetFontMetrics(scalePtr->tkfont, &fm); @@ -938,28 +1068,53 @@ ComputeScaleGeometry( * whichever length is longer. */ - sprintf(valueString, scalePtr->format, scalePtr->fromValue); + if (snprintf(valueString, TCL_DOUBLE_SPACE, scalePtr->valueFormat, + scalePtr->fromValue) < 0) { + valueString[TCL_DOUBLE_SPACE - 1] = '\0'; + } valuePixels = Tk_TextWidth(scalePtr->tkfont, valueString, -1); - sprintf(valueString, scalePtr->format, scalePtr->toValue); + if (snprintf(valueString, TCL_DOUBLE_SPACE, scalePtr->valueFormat, + scalePtr->toValue) < 0) { + valueString[TCL_DOUBLE_SPACE - 1] = '\0'; + } tmp = Tk_TextWidth(scalePtr->tkfont, valueString, -1); if (valuePixels < tmp) { valuePixels = tmp; } /* + * Now do the same thing for the tick values + */ + + if (snprintf(valueString, TCL_DOUBLE_SPACE, scalePtr->tickFormat, + scalePtr->fromValue) < 0) { + valueString[TCL_DOUBLE_SPACE - 1] = '\0'; + } + tickPixels = Tk_TextWidth(scalePtr->tkfont, valueString, -1); + + if (snprintf(valueString, TCL_DOUBLE_SPACE, scalePtr->tickFormat, + scalePtr->toValue) < 0) { + valueString[TCL_DOUBLE_SPACE - 1] = '\0'; + } + tmp = Tk_TextWidth(scalePtr->tkfont, valueString, -1); + if (tickPixels < tmp) { + tickPixels = tmp; + } + + /* * Assign x-locations to the elements of the scale, working from left to * right. */ x = scalePtr->inset; if ((scalePtr->tickInterval != 0) && (scalePtr->showValue)) { - scalePtr->vertTickRightX = x + SPACING + valuePixels; + scalePtr->vertTickRightX = x + SPACING + tickPixels; scalePtr->vertValueRightX = scalePtr->vertTickRightX + valuePixels + fm.ascent/2; x = scalePtr->vertValueRightX + SPACING; } else if (scalePtr->tickInterval != 0) { - scalePtr->vertTickRightX = x + SPACING + valuePixels; + scalePtr->vertTickRightX = x + SPACING + tickPixels; scalePtr->vertValueRightX = scalePtr->vertTickRightX; x = scalePtr->vertTickRightX + SPACING; } else if (scalePtr->showValue) { @@ -1008,12 +1163,12 @@ ScaleEventProc( ClientData clientData, /* Information about window. */ XEvent *eventPtr) /* Information about event. */ { - TkScale *scalePtr = (TkScale *) clientData; + TkScale *scalePtr = clientData; if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) { TkEventuallyRedrawScale(scalePtr, REDRAW_ALL); } else if (eventPtr->type == DestroyNotify) { - DestroyScale((char *) clientData); + DestroyScale(clientData); } else if (eventPtr->type == ConfigureNotify) { ComputeScaleGeometry(scalePtr); TkEventuallyRedrawScale(scalePtr, REDRAW_ALL); @@ -1056,7 +1211,7 @@ static void ScaleCmdDeletedProc( ClientData clientData) /* Pointer to widget record for widget. */ { - TkScale *scalePtr = (TkScale *) clientData; + TkScale *scalePtr = clientData; Tk_Window tkwin = scalePtr->tkwin; /* @@ -1103,7 +1258,7 @@ TkEventuallyRedrawScale( } if (!(scalePtr->flags & REDRAW_PENDING)) { scalePtr->flags |= REDRAW_PENDING; - Tcl_DoWhenIdle(TkpDisplayScale, (ClientData) scalePtr); + Tcl_DoWhenIdle(TkpDisplayScale, scalePtr); } scalePtr->flags |= what; } @@ -1111,10 +1266,14 @@ TkEventuallyRedrawScale( /* *-------------------------------------------------------------- * - * TkRoundToResolution -- + * TkRoundValueToResolution, TkRoundIntervalToResolution -- * * Round a given floating-point value to the nearest multiple of the * scale's resolution. + * TkRoundValueToResolution rounds an absolute value based on the from + * value as a reference. + * TkRoundIntervalToResolution rounds a relative value without + * reference, i.e. it rounds an interval. * * Results: * The return value is the rounded result. @@ -1126,7 +1285,16 @@ TkEventuallyRedrawScale( */ double -TkRoundToResolution( +TkRoundValueToResolution( + TkScale *scalePtr, /* Information about scale widget. */ + double value) /* Value to round. */ +{ + return TkRoundIntervalToResolution(scalePtr, value - scalePtr->fromValue) + + scalePtr->fromValue; +} + +double +TkRoundIntervalToResolution( TkScale *scalePtr, /* Information about scale widget. */ double value) /* Value to round. */ { @@ -1139,13 +1307,13 @@ TkRoundToResolution( rounded = scalePtr->resolution * tick; rem = value - rounded; if (rem < 0) { - if (rem <= -scalePtr->resolution/2) { - rounded = (tick - 1.0) * scalePtr->resolution; - } + if (rem <= -scalePtr->resolution/2) { + rounded = (tick - 1.0) * scalePtr->resolution; + } } else { - if (rem >= scalePtr->resolution/2) { - rounded = (tick + 1.0) * scalePtr->resolution; - } + if (rem >= scalePtr->resolution/2) { + rounded = (tick + 1.0) * scalePtr->resolution; + } } return rounded; } @@ -1178,8 +1346,8 @@ ScaleVarProc( const char *name2, /* Second part of variable name. */ int flags) /* Information about what happened. */ { - register TkScale *scalePtr = (TkScale *) clientData; - char *resultStr; + register TkScale *scalePtr = clientData; + const char *resultStr; double value; Tcl_Obj *valuePtr; int result; @@ -1190,9 +1358,29 @@ ScaleVarProc( */ if (flags & TCL_TRACE_UNSETS) { - if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) { - Tcl_TraceVar(interp, Tcl_GetString(scalePtr->varNamePtr), - TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + if (!Tcl_InterpDeleted(interp) && scalePtr->varNamePtr) { + ClientData probe = NULL; + + do { + probe = Tcl_VarTraceInfo(interp, + Tcl_GetString(scalePtr->varNamePtr), + TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + ScaleVarProc, probe); + if (probe == (ClientData)scalePtr) { + break; + } + } while (probe); + if (probe) { + /* + * We were able to fetch the unset trace for our + * varNamePtr, which means it is not unset and not + * the cause of this unset trace. Instead some outdated + * former variable must be, and we should ignore it. + */ + return NULL; + } + Tcl_TraceVar2(interp, Tcl_GetString(scalePtr->varNamePtr), + NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, ScaleVarProc, clientData); scalePtr->flags |= NEVER_SET; TkScaleSetValue(scalePtr, scalePtr->value, 1, 0); @@ -1217,7 +1405,7 @@ ScaleVarProc( resultStr = "can't assign non-numeric value to scale variable"; ScaleSetVariable(scalePtr); } else { - scalePtr->value = TkRoundToResolution(scalePtr, value); + scalePtr->value = TkRoundValueToResolution(scalePtr, value); /* * This code is a bit tricky because it sets the scale's value before @@ -1230,7 +1418,7 @@ ScaleVarProc( } TkEventuallyRedrawScale(scalePtr, REDRAW_SLIDER); - return resultStr; + return (char *) resultStr; } /* @@ -1261,7 +1449,7 @@ TkScaleSetValue( int invokeCommand) /* Non-zero means invoked -command option to * notify of new value, 0 means don't. */ { - value = TkRoundToResolution(scalePtr, value); + value = TkRoundValueToResolution(scalePtr, value); if ((value < scalePtr->fromValue) ^ (scalePtr->toValue < scalePtr->fromValue)) { value = scalePtr->fromValue; @@ -1276,7 +1464,14 @@ TkScaleSetValue( return; } scalePtr->value = value; - if (invokeCommand) { + + /* + * Schedule command callback invocation only if there is such a command + * already registered, otherwise the callback would trigger later when + * configuring the widget -command option even if the value did not change. + */ + + if ((invokeCommand) && (scalePtr->command != NULL)) { scalePtr->flags |= INVOKE_COMMAND; } TkEventuallyRedrawScale(scalePtr, REDRAW_SLIDER); @@ -1309,7 +1504,10 @@ ScaleSetVariable( if (scalePtr->varNamePtr != NULL) { char string[TCL_DOUBLE_SPACE]; - sprintf(string, scalePtr->format, scalePtr->value); + if (snprintf(string, TCL_DOUBLE_SPACE, scalePtr->valueFormat, + scalePtr->value) < 0) { + string[TCL_DOUBLE_SPACE - 1] = '\0'; + } scalePtr->flags |= SETTING_VAR; Tcl_ObjSetVar2(scalePtr->interp, scalePtr->varNamePtr, NULL, Tcl_NewStringObj(string, -1), TCL_GLOBAL_ONLY); @@ -1371,7 +1569,7 @@ TkScalePixelToValue( } value = scalePtr->fromValue + value * (scalePtr->toValue - scalePtr->fromValue); - return TkRoundToResolution(scalePtr, value); + return TkRoundValueToResolution(scalePtr, value); } /* @@ -1408,8 +1606,8 @@ TkScaleValueToPixel( if (valueRange == 0) { y = 0; } else { - y = (int) ((value - scalePtr->fromValue) * pixelRange - / valueRange + 0.5); + y = ScaleRound((value - scalePtr->fromValue) * pixelRange + / valueRange); if (y < 0) { y = 0; } else if (y > pixelRange) { diff --git a/generic/tkScale.h b/generic/tkScale.h index 079e02c..e68b786 100644 --- a/generic/tkScale.h +++ b/generic/tkScale.h @@ -18,11 +18,6 @@ #include "tkInt.h" #endif -#ifdef BUILD_tk -# undef TCL_STORAGE_CLASS -# define TCL_STORAGE_CLASS DLLEXPORT -#endif - /* * Legal values for the "orient" field of TkScale records. */ @@ -78,8 +73,10 @@ typedef struct TkScale { * values. 0 means we get to choose the number * based on resolution and/or the range of the * scale. */ - char format[16]; /* Sprintf conversion specifier computed from + char valueFormat[16]; /* Sprintf conversion specifier computed from * digits and other information. */ + char tickFormat[16]; /* Sprintf conversion specifier computed from + * tick interval. */ double bigIncrement; /* Amount to use for large increments to scale * value. (0 means we pick a value). */ char *command; /* Command prefix to use when invoking Tcl @@ -220,11 +217,20 @@ typedef struct TkScale { #define SPACING 2 /* + * The tick values are all displayed with the same number of decimal places. + * This number of decimal places is such that the displayed values are all + * accurate to within the following proportion of a tick interval. + */ + +#define TICK_VALUES_DISPLAY_ACCURACY 0.2 + +/* * Declaration of procedures used in the implementation of the scale widget. */ MODULE_SCOPE void TkEventuallyRedrawScale(TkScale *scalePtr, int what); -MODULE_SCOPE double TkRoundToResolution(TkScale *scalePtr, double value); +MODULE_SCOPE double TkRoundValueToResolution(TkScale *scalePtr, double value); +MODULE_SCOPE double TkRoundIntervalToResolution(TkScale *scalePtr, double value); MODULE_SCOPE TkScale * TkpCreateScale(Tk_Window tkwin); MODULE_SCOPE void TkpDestroyScale(TkScale *scalePtr); MODULE_SCOPE void TkpDisplayScale(ClientData clientData); @@ -234,7 +240,4 @@ MODULE_SCOPE void TkScaleSetValue(TkScale *scalePtr, double value, MODULE_SCOPE double TkScalePixelToValue(TkScale *scalePtr, int x, int y); MODULE_SCOPE int TkScaleValueToPixel(TkScale *scalePtr, double value); -# undef TCL_STORAGE_CLASS -# define TCL_STORAGE_CLASS DLLIMPORT - #endif /* _TKSCALE */ diff --git a/generic/tkScrollbar.c b/generic/tkScrollbar.c index 7e39056..9a85532 100644 --- a/generic/tkScrollbar.c +++ b/generic/tkScrollbar.c @@ -20,10 +20,8 @@ * Custom option for handling "-orient" */ -static Tk_CustomOption orientOption = { - (Tk_OptionParseProc *) TkOrientParseProc, - TkOrientPrintProc, - (ClientData) NULL +static const Tk_CustomOption orientOption = { + TkOrientParseProc, TkOrientPrintProc, NULL }; /* non-const space for "-width" default value for scrollbars */ @@ -33,65 +31,65 @@ char tkDefScrollbarWidth[TCL_INTEGER_SPACE] = DEF_SCROLLBAR_WIDTH; * Information used for argv parsing. */ -static Tk_ConfigSpec configSpecs[] = { +static const Tk_ConfigSpec configSpecs[] = { {TK_CONFIG_BORDER, "-activebackground", "activeBackground", "Foreground", DEF_SCROLLBAR_ACTIVE_BG_COLOR, Tk_Offset(TkScrollbar, activeBorder), - TK_CONFIG_COLOR_ONLY}, + TK_CONFIG_COLOR_ONLY, NULL}, {TK_CONFIG_BORDER, "-activebackground", "activeBackground", "Foreground", DEF_SCROLLBAR_ACTIVE_BG_MONO, Tk_Offset(TkScrollbar, activeBorder), - TK_CONFIG_MONO_ONLY}, + TK_CONFIG_MONO_ONLY, NULL}, {TK_CONFIG_RELIEF, "-activerelief", "activeRelief", "Relief", - DEF_SCROLLBAR_ACTIVE_RELIEF, Tk_Offset(TkScrollbar, activeRelief), 0}, + DEF_SCROLLBAR_ACTIVE_RELIEF, Tk_Offset(TkScrollbar, activeRelief), 0, NULL}, {TK_CONFIG_BORDER, "-background", "background", "Background", DEF_SCROLLBAR_BG_COLOR, Tk_Offset(TkScrollbar, bgBorder), - TK_CONFIG_COLOR_ONLY}, + TK_CONFIG_COLOR_ONLY, NULL}, {TK_CONFIG_BORDER, "-background", "background", "Background", DEF_SCROLLBAR_BG_MONO, Tk_Offset(TkScrollbar, bgBorder), - TK_CONFIG_MONO_ONLY}, - {TK_CONFIG_SYNONYM, "-bd", "borderWidth", NULL, NULL, 0, 0}, - {TK_CONFIG_SYNONYM, "-bg", "background", NULL, NULL, 0, 0}, + TK_CONFIG_MONO_ONLY, NULL}, + {TK_CONFIG_SYNONYM, "-bd", "borderWidth", NULL, NULL, 0, 0, NULL}, + {TK_CONFIG_SYNONYM, "-bg", "background", NULL, NULL, 0, 0, NULL}, {TK_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", - DEF_SCROLLBAR_BORDER_WIDTH, Tk_Offset(TkScrollbar, borderWidth), 0}, + DEF_SCROLLBAR_BORDER_WIDTH, Tk_Offset(TkScrollbar, borderWidth), 0, NULL}, {TK_CONFIG_STRING, "-command", "command", "Command", DEF_SCROLLBAR_COMMAND, Tk_Offset(TkScrollbar, command), - TK_CONFIG_NULL_OK}, + TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor", - DEF_SCROLLBAR_CURSOR, Tk_Offset(TkScrollbar, cursor), TK_CONFIG_NULL_OK}, + DEF_SCROLLBAR_CURSOR, Tk_Offset(TkScrollbar, cursor), TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_PIXELS, "-elementborderwidth", "elementBorderWidth", "BorderWidth", DEF_SCROLLBAR_EL_BORDER_WIDTH, - Tk_Offset(TkScrollbar, elementBorderWidth), 0}, + Tk_Offset(TkScrollbar, elementBorderWidth), 0, NULL}, {TK_CONFIG_COLOR, "-highlightbackground", "highlightBackground", "HighlightBackground", DEF_SCROLLBAR_HIGHLIGHT_BG, - Tk_Offset(TkScrollbar, highlightBgColorPtr), 0}, + Tk_Offset(TkScrollbar, highlightBgColorPtr), 0, NULL}, {TK_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", DEF_SCROLLBAR_HIGHLIGHT, - Tk_Offset(TkScrollbar, highlightColorPtr), 0}, + Tk_Offset(TkScrollbar, highlightColorPtr), 0, NULL}, {TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness", "HighlightThickness", - DEF_SCROLLBAR_HIGHLIGHT_WIDTH, Tk_Offset(TkScrollbar, highlightWidth), 0}, + DEF_SCROLLBAR_HIGHLIGHT_WIDTH, Tk_Offset(TkScrollbar, highlightWidth), 0, NULL}, {TK_CONFIG_BOOLEAN, "-jump", "jump", "Jump", - DEF_SCROLLBAR_JUMP, Tk_Offset(TkScrollbar, jump), 0}, + DEF_SCROLLBAR_JUMP, Tk_Offset(TkScrollbar, jump), 0, NULL}, {TK_CONFIG_CUSTOM, "-orient", "orient", "Orient", DEF_SCROLLBAR_ORIENT, Tk_Offset(TkScrollbar, vertical), 0, &orientOption}, {TK_CONFIG_RELIEF, "-relief", "relief", "Relief", - DEF_SCROLLBAR_RELIEF, Tk_Offset(TkScrollbar, relief), 0}, + DEF_SCROLLBAR_RELIEF, Tk_Offset(TkScrollbar, relief), 0, NULL}, {TK_CONFIG_INT, "-repeatdelay", "repeatDelay", "RepeatDelay", - DEF_SCROLLBAR_REPEAT_DELAY, Tk_Offset(TkScrollbar, repeatDelay), 0}, + DEF_SCROLLBAR_REPEAT_DELAY, Tk_Offset(TkScrollbar, repeatDelay), 0, NULL}, {TK_CONFIG_INT, "-repeatinterval", "repeatInterval", "RepeatInterval", - DEF_SCROLLBAR_REPEAT_INTERVAL, Tk_Offset(TkScrollbar, repeatInterval), 0}, + DEF_SCROLLBAR_REPEAT_INTERVAL, Tk_Offset(TkScrollbar, repeatInterval), 0, NULL}, {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus", DEF_SCROLLBAR_TAKE_FOCUS, Tk_Offset(TkScrollbar, takeFocus), - TK_CONFIG_NULL_OK}, + TK_CONFIG_NULL_OK, NULL}, {TK_CONFIG_COLOR, "-troughcolor", "troughColor", "Background", DEF_SCROLLBAR_TROUGH_COLOR, Tk_Offset(TkScrollbar, troughColorPtr), - TK_CONFIG_COLOR_ONLY}, + TK_CONFIG_COLOR_ONLY, NULL}, {TK_CONFIG_COLOR, "-troughcolor", "troughColor", "Background", DEF_SCROLLBAR_TROUGH_MONO, Tk_Offset(TkScrollbar, troughColorPtr), - TK_CONFIG_MONO_ONLY}, + TK_CONFIG_MONO_ONLY, NULL}, {TK_CONFIG_PIXELS, "-width", "width", "Width", - tkDefScrollbarWidth, Tk_Offset(TkScrollbar, width), 0}, - {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} + tkDefScrollbarWidth, Tk_Offset(TkScrollbar, width), 0, NULL}, + {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL} }; /* @@ -99,16 +97,16 @@ static Tk_ConfigSpec configSpecs[] = { */ static int ConfigureScrollbar(Tcl_Interp *interp, - TkScrollbar *scrollPtr, int argc, - CONST char **argv, int flags); + TkScrollbar *scrollPtr, int objc, + Tcl_Obj *const objv[], int flags); static void ScrollbarCmdDeletedProc(ClientData clientData); -static int ScrollbarWidgetCmd(ClientData clientData, - Tcl_Interp *, int argc, CONST char **argv); +static int ScrollbarWidgetObjCmd(ClientData clientData, + Tcl_Interp *, int objc, Tcl_Obj *const objv[]); /* *-------------------------------------------------------------- * - * Tk_ScrollbarCmd -- + * Tk_ScrollbarObjCmd -- * * This function is invoked to process the "scrollbar" Tcl command. See * the user documentation for details on what it does. @@ -123,23 +121,22 @@ static int ScrollbarWidgetCmd(ClientData clientData, */ int -Tk_ScrollbarCmd( +Tk_ScrollbarObjCmd( ClientData clientData, /* Main window associated with interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ - int argc, /* Number of arguments. */ - CONST char **argv) /* Argument strings. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument strings. */ { - Tk_Window tkwin = (Tk_Window) clientData; + Tk_Window tkwin = clientData; register TkScrollbar *scrollPtr; Tk_Window newWin; - if (argc < 2) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " pathName ?options?\"", NULL); + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?"); return TCL_ERROR; } - newWin = Tk_CreateWindowFromPath(interp, tkwin, argv[1], NULL); + newWin = Tk_CreateWindowFromPath(interp, tkwin, Tcl_GetString(objv[1]), NULL); if (newWin == NULL) { return TCL_ERROR; } @@ -147,7 +144,7 @@ Tk_ScrollbarCmd( Tk_SetClass(newWin, "Scrollbar"); scrollPtr = TkpCreateScrollbar(newWin); - Tk_SetClassProcs(newWin, &tkpScrollbarProcs, (ClientData) scrollPtr); + Tk_SetClassProcs(newWin, &tkpScrollbarProcs, scrollPtr); /* * Initialize fields that won't be initialized by ConfigureScrollbar, or @@ -158,9 +155,9 @@ Tk_ScrollbarCmd( scrollPtr->tkwin = newWin; scrollPtr->display = Tk_Display(newWin); scrollPtr->interp = interp; - scrollPtr->widgetCmd = Tcl_CreateCommand(interp, - Tk_PathName(scrollPtr->tkwin), ScrollbarWidgetCmd, - (ClientData) scrollPtr, ScrollbarCmdDeletedProc); + scrollPtr->widgetCmd = Tcl_CreateObjCommand(interp, + Tk_PathName(scrollPtr->tkwin), ScrollbarWidgetObjCmd, + scrollPtr, ScrollbarCmdDeletedProc); scrollPtr->vertical = 0; scrollPtr->width = 0; scrollPtr->command = NULL; @@ -192,19 +189,19 @@ Tk_ScrollbarCmd( scrollPtr->takeFocus = NULL; scrollPtr->flags = 0; - if (ConfigureScrollbar(interp, scrollPtr, argc-2, argv+2, 0) != TCL_OK) { + if (ConfigureScrollbar(interp, scrollPtr, objc-2, objv+2, 0) != TCL_OK) { Tk_DestroyWindow(scrollPtr->tkwin); return TCL_ERROR; } - Tcl_SetResult(interp, Tk_PathName(scrollPtr->tkwin), TCL_STATIC); + Tcl_SetObjResult(interp, TkNewWindowObj(scrollPtr->tkwin)); return TCL_OK; } /* *-------------------------------------------------------------- * - * ScrollbarWidgetCmd -- + * ScrollbarWidgetObjCmd -- * * This function is invoked to process the Tcl command that corresponds * to a widget managed by this module. See the user documentation for @@ -220,54 +217,65 @@ Tk_ScrollbarCmd( */ static int -ScrollbarWidgetCmd( +ScrollbarWidgetObjCmd( ClientData clientData, /* Information about scrollbar widget. */ Tcl_Interp *interp, /* Current interpreter. */ - int argc, /* Number of arguments. */ - CONST char **argv) /* Argument strings. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument strings. */ { - register TkScrollbar *scrollPtr = (TkScrollbar *) clientData; + register TkScrollbar *scrollPtr = clientData; int result = TCL_OK; - size_t length; - int c; - - if (argc < 2) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " option ?arg arg ...?\"", NULL); + int length, cmdIndex; + static const char *const commandNames[] = { + "activate", "cget", "configure", "delta", "fraction", + "get", "identify", "set", NULL + }; + enum command { + COMMAND_ACTIVATE, COMMAND_CGET, COMMAND_CONFIGURE, COMMAND_DELTA, + COMMAND_FRACTION, COMMAND_GET, COMMAND_IDENTIFY, COMMAND_SET + }; + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); return TCL_ERROR; } - Tcl_Preserve((ClientData) scrollPtr); - c = argv[1][0]; - length = strlen(argv[1]); - if ((c == 'a') && (strncmp(argv[1], "activate", length) == 0)) { - int oldActiveField; - if (argc == 2) { + /* + * Parse the command by looking up the second argument in the list of + * valid subcommand names + */ + + result = Tcl_GetIndexFromObj(interp, objv[1], commandNames, + "option", 0, &cmdIndex); + if (result != TCL_OK) { + return result; + } + Tcl_Preserve(scrollPtr); + switch (cmdIndex) { + case COMMAND_ACTIVATE: { + int oldActiveField, c; + + if (objc == 2) { + const char *zone = ""; + switch (scrollPtr->activeField) { - case TOP_ARROW: - Tcl_SetResult(interp, "arrow1", TCL_STATIC); - break; - case SLIDER: - Tcl_SetResult(interp, "slider", TCL_STATIC); - break; - case BOTTOM_ARROW: - Tcl_SetResult(interp, "arrow2", TCL_STATIC); - break; + case TOP_ARROW: zone = "arrow1"; break; + case SLIDER: zone = "slider"; break; + case BOTTOM_ARROW: zone = "arrow2"; break; } + Tcl_SetObjResult(interp, Tcl_NewStringObj(zone, -1)); goto done; } - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " activate element\"", NULL); + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "activate element"); goto error; } - c = argv[2][0]; - length = strlen(argv[2]); + c = Tcl_GetStringFromObj(objv[2], &length)[0]; oldActiveField = scrollPtr->activeField; - if ((c == 'a') && (strcmp(argv[2], "arrow1") == 0)) { + if ((c == 'a') && (strcmp(Tcl_GetString(objv[2]), "arrow1") == 0)) { scrollPtr->activeField = TOP_ARROW; - } else if ((c == 'a') && (strcmp(argv[2], "arrow2") == 0)) { + } else if ((c == 'a') && (strcmp(Tcl_GetString(objv[2]), "arrow2") == 0)) { scrollPtr->activeField = BOTTOM_ARROW; - } else if ((c == 's') && (strncmp(argv[2], "slider", length) == 0)) { + } else if ((c == 's') && (strncmp(Tcl_GetString(objv[2]), "slider", length) == 0)) { scrollPtr->activeField = SLIDER; } else { scrollPtr->activeField = OUTSIDE; @@ -275,40 +283,40 @@ ScrollbarWidgetCmd( if (oldActiveField != scrollPtr->activeField) { TkScrollbarEventuallyRedraw(scrollPtr); } - } else if ((c == 'c') && (strncmp(argv[1], "cget", length) == 0) - && (length >= 2)) { - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " cget option\"", - NULL); + break; + } + case COMMAND_CGET: { + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "cget option"); goto error; } result = Tk_ConfigureValue(interp, scrollPtr->tkwin, - configSpecs, (char *) scrollPtr, argv[2], 0); - } else if ((c == 'c') && (strncmp(argv[1], "configure", length) == 0) - && (length >= 2)) { - if (argc == 2) { + configSpecs, (char *) scrollPtr, Tcl_GetString(objv[2]), 0); + break; + } + case COMMAND_CONFIGURE: { + if (objc == 2) { result = Tk_ConfigureInfo(interp, scrollPtr->tkwin, configSpecs, (char *) scrollPtr, NULL, 0); - } else if (argc == 3) { + } else if (objc == 3) { result = Tk_ConfigureInfo(interp, scrollPtr->tkwin, - configSpecs, (char *) scrollPtr, argv[2], 0); + configSpecs, (char *) scrollPtr, Tcl_GetString(objv[2]), 0); } else { - result = ConfigureScrollbar(interp, scrollPtr, argc-2, argv+2, - TK_CONFIG_ARGV_ONLY); + result = ConfigureScrollbar(interp, scrollPtr, objc-2, + objv+2, TK_CONFIG_ARGV_ONLY); } - } else if ((c == 'd') && (strncmp(argv[1], "delta", length) == 0)) { + break; + } + case COMMAND_DELTA: { int xDelta, yDelta, pixels, length; double fraction; - char buf[TCL_DOUBLE_SPACE]; - if (argc != 4) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " delta xDelta yDelta\"", NULL); + if (objc != 4) { + Tcl_WrongNumArgs(interp, 1, objv, "delta xDelta yDelta"); goto error; } - if ((Tcl_GetInt(interp, argv[2], &xDelta) != TCL_OK) - || (Tcl_GetInt(interp, argv[3], &yDelta) != TCL_OK)) { + if ((Tcl_GetIntFromObj(interp, objv[2], &xDelta) != TCL_OK) + || (Tcl_GetIntFromObj(interp, objv[3], &yDelta) != TCL_OK)) { goto error; } if (scrollPtr->vertical) { @@ -325,20 +333,19 @@ ScrollbarWidgetCmd( } else { fraction = ((double) pixels / (double) length); } - Tcl_PrintDouble(NULL, fraction, buf); - Tcl_SetResult(interp, buf, TCL_VOLATILE); - } else if ((c == 'f') && (strncmp(argv[1], "fraction", length) == 0)) { + Tcl_SetObjResult(interp, Tcl_NewDoubleObj(fraction)); + break; + } + case COMMAND_FRACTION: { int x, y, pos, length; double fraction; - char buf[TCL_DOUBLE_SPACE]; - if (argc != 4) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " fraction x y\"", NULL); + if (objc != 4) { + Tcl_WrongNumArgs(interp, 1, objv, "fraction x y"); goto error; } - if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK) - || (Tcl_GetInt(interp, argv[3], &y) != TCL_OK)) { + if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK) + || (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) { goto error; } if (scrollPtr->vertical) { @@ -360,68 +367,61 @@ ScrollbarWidgetCmd( } else if (fraction > 1.0) { fraction = 1.0; } - Tcl_PrintDouble(NULL, fraction, buf); - Tcl_SetResult(interp, buf, TCL_VOLATILE); - } else if ((c == 'g') && (strncmp(argv[1], "get", length) == 0)) { - if (argc != 2) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " get\"", NULL); + Tcl_SetObjResult(interp, Tcl_NewDoubleObj(fraction)); + break; + } + case COMMAND_GET: { + Tcl_Obj *resObjs[4]; + + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, "get"); goto error; } if (scrollPtr->flags & NEW_STYLE_COMMANDS) { - char first[TCL_DOUBLE_SPACE], last[TCL_DOUBLE_SPACE]; - - Tcl_PrintDouble(interp, scrollPtr->firstFraction, first); - Tcl_PrintDouble(interp, scrollPtr->lastFraction, last); - Tcl_AppendResult(interp, first, " ", last, NULL); + resObjs[0] = Tcl_NewDoubleObj(scrollPtr->firstFraction); + resObjs[1] = Tcl_NewDoubleObj(scrollPtr->lastFraction); + Tcl_SetObjResult(interp, Tcl_NewListObj(2, resObjs)); } else { - char buf[TCL_INTEGER_SPACE * 4]; - - sprintf(buf, "%d %d %d %d", scrollPtr->totalUnits, - scrollPtr->windowUnits, scrollPtr->firstUnit, - scrollPtr->lastUnit); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + resObjs[0] = Tcl_NewIntObj(scrollPtr->totalUnits); + resObjs[1] = Tcl_NewIntObj(scrollPtr->windowUnits); + resObjs[2] = Tcl_NewIntObj(scrollPtr->firstUnit); + resObjs[3] = Tcl_NewIntObj(scrollPtr->lastUnit); + Tcl_SetObjResult(interp, Tcl_NewListObj(4, resObjs)); } - } else if ((c == 'i') && (strncmp(argv[1], "identify", length) == 0)) { - int x, y, thing; + break; + } + case COMMAND_IDENTIFY: { + int x, y; + const char *zone = ""; - if (argc != 4) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " identify x y\"", NULL); + if (objc != 4) { + Tcl_WrongNumArgs(interp, 1, objv, "identify x y"); goto error; } - if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK) - || (Tcl_GetInt(interp, argv[3], &y) != TCL_OK)) { + if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK) + || (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) { goto error; } - thing = TkpScrollbarPosition(scrollPtr, x,y); - switch (thing) { - case TOP_ARROW: - Tcl_SetResult(interp, "arrow1", TCL_STATIC); - break; - case TOP_GAP: - Tcl_SetResult(interp, "trough1", TCL_STATIC); - break; - case SLIDER: - Tcl_SetResult(interp, "slider", TCL_STATIC); - break; - case BOTTOM_GAP: - Tcl_SetResult(interp, "trough2", TCL_STATIC); - break; - case BOTTOM_ARROW: - Tcl_SetResult(interp, "arrow2", TCL_STATIC); - break; + switch (TkpScrollbarPosition(scrollPtr, x, y)) { + case TOP_ARROW: zone = "arrow1"; break; + case TOP_GAP: zone = "trough1"; break; + case SLIDER: zone = "slider"; break; + case BOTTOM_GAP: zone = "trough2"; break; + case BOTTOM_ARROW: zone = "arrow2"; break; } - } else if ((c == 's') && (strncmp(argv[1], "set", length) == 0)) { + Tcl_SetObjResult(interp, Tcl_NewStringObj(zone, -1)); + break; + } + case COMMAND_SET: { int totalUnits, windowUnits, firstUnit, lastUnit; - if (argc == 4) { + if (objc == 4) { double first, last; - if (Tcl_GetDouble(interp, argv[2], &first) != TCL_OK) { + if (Tcl_GetDoubleFromObj(interp, objv[2], &first) != TCL_OK) { goto error; } - if (Tcl_GetDouble(interp, argv[3], &last) != TCL_OK) { + if (Tcl_GetDoubleFromObj(interp, objv[3], &last) != TCL_OK) { goto error; } if (first < 0) { @@ -439,23 +439,23 @@ ScrollbarWidgetCmd( scrollPtr->lastFraction = last; } scrollPtr->flags |= NEW_STYLE_COMMANDS; - } else if (argc == 6) { - if (Tcl_GetInt(interp, argv[2], &totalUnits) != TCL_OK) { + } else if (objc == 6) { + if (Tcl_GetIntFromObj(interp, objv[2], &totalUnits) != TCL_OK) { goto error; } if (totalUnits < 0) { totalUnits = 0; } - if (Tcl_GetInt(interp, argv[3], &windowUnits) != TCL_OK) { + if (Tcl_GetIntFromObj(interp, objv[3], &windowUnits) != TCL_OK) { goto error; } if (windowUnits < 0) { windowUnits = 0; } - if (Tcl_GetInt(interp, argv[4], &firstUnit) != TCL_OK) { + if (Tcl_GetIntFromObj(interp, objv[4], &firstUnit) != TCL_OK) { goto error; } - if (Tcl_GetInt(interp, argv[5], &lastUnit) != TCL_OK) { + if (Tcl_GetIntFromObj(interp, objv[5], &lastUnit) != TCL_OK) { goto error; } if (totalUnits > 0) { @@ -478,27 +478,23 @@ ScrollbarWidgetCmd( } scrollPtr->flags &= ~NEW_STYLE_COMMANDS; } else { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " set firstFraction lastFraction\" or \"", - argv[0], - " set totalUnits windowUnits firstUnit lastUnit\"", NULL); + 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); TkScrollbarEventuallyRedraw(scrollPtr); - } else { - Tcl_AppendResult(interp, "bad option \"", argv[1], - "\": must be activate, cget, configure, delta, fraction, ", - "get, identify, or set", NULL); - goto error; + break; + } } done: - Tcl_Release((ClientData) scrollPtr); + Tcl_Release(scrollPtr); return result; error: - Tcl_Release((ClientData) scrollPtr); + Tcl_Release(scrollPtr); return TCL_ERROR; } @@ -528,12 +524,12 @@ ConfigureScrollbar( register TkScrollbar *scrollPtr, /* Information about widget; may or may not * already have values for some fields. */ - int argc, /* Number of valid entries in argv. */ - CONST char **argv, /* Arguments. */ + int objc, /* Number of valid entries in argv. */ + Tcl_Obj *const objv[], /* Arguments. */ int flags) /* Flags to pass to Tk_ConfigureWidget. */ { - if (Tk_ConfigureWidget(interp, scrollPtr->tkwin, configSpecs, - argc, argv, (char *) scrollPtr, flags) != TCL_OK) { + if (Tk_ConfigureWidget(interp, scrollPtr->tkwin, configSpecs, objc, + (const char **)objv, (char *) scrollPtr, flags|TK_CONFIG_OBJS) != TCL_OK) { return TCL_ERROR; } @@ -543,7 +539,7 @@ ConfigureScrollbar( */ if (scrollPtr->command != NULL) { - scrollPtr->commandSize = (int)strlen(scrollPtr->command); + scrollPtr->commandSize = (int) strlen(scrollPtr->command); } else { scrollPtr->commandSize = 0; } @@ -588,7 +584,7 @@ TkScrollbarEventProc( ClientData clientData, /* Information about window. */ XEvent *eventPtr) /* Information about event. */ { - TkScrollbar *scrollPtr = (TkScrollbar *) clientData; + TkScrollbar *scrollPtr = clientData; if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) { TkScrollbarEventuallyRedraw(scrollPtr); @@ -600,16 +596,15 @@ TkScrollbarEventProc( scrollPtr->widgetCmd); } if (scrollPtr->flags & REDRAW_PENDING) { - Tcl_CancelIdleCall(TkpDisplayScrollbar, (ClientData) scrollPtr); + Tcl_CancelIdleCall(TkpDisplayScrollbar, scrollPtr); } /* * Free up all the stuff that requires special handling, then let * Tk_FreeOptions handle all the standard option-related stuff. */ - Tk_FreeOptions(configSpecs, (char *) scrollPtr, - scrollPtr->display, 0); - Tcl_EventuallyFree((ClientData) scrollPtr, TCL_DYNAMIC); + Tk_FreeOptions(configSpecs, (char*) scrollPtr, scrollPtr->display, 0); + Tcl_EventuallyFree(scrollPtr, TCL_DYNAMIC); } else if (eventPtr->type == ConfigureNotify) { TkpComputeScrollbarGeometry(scrollPtr); TkScrollbarEventuallyRedraw(scrollPtr); @@ -654,7 +649,7 @@ static void ScrollbarCmdDeletedProc( ClientData clientData) /* Pointer to widget record for widget. */ { - TkScrollbar *scrollPtr = (TkScrollbar *) clientData; + TkScrollbar *scrollPtr = clientData; Tk_Window tkwin = scrollPtr->tkwin; /* @@ -690,11 +685,11 @@ void TkScrollbarEventuallyRedraw( TkScrollbar *scrollPtr) /* Information about widget. */ { - if ((scrollPtr->tkwin == NULL) || (!Tk_IsMapped(scrollPtr->tkwin))) { + if ((scrollPtr->tkwin == NULL) || !Tk_IsMapped(scrollPtr->tkwin)) { return; } - if ((scrollPtr->flags & REDRAW_PENDING) == 0) { - Tcl_DoWhenIdle(TkpDisplayScrollbar, (ClientData) scrollPtr); + if (!(scrollPtr->flags & REDRAW_PENDING)) { + Tcl_DoWhenIdle(TkpDisplayScrollbar, scrollPtr); scrollPtr->flags |= REDRAW_PENDING; } } diff --git a/generic/tkScrollbar.h b/generic/tkScrollbar.h index fa0426f..2d521ae 100644 --- a/generic/tkScrollbar.h +++ b/generic/tkScrollbar.h @@ -161,7 +161,7 @@ typedef struct TkScrollbar { * and default scrollbar width, for use in configSpec. */ -MODULE_SCOPE Tk_ClassProcs tkpScrollbarProcs; +MODULE_SCOPE const Tk_ClassProcs tkpScrollbarProcs; MODULE_SCOPE char tkDefScrollbarWidth[TCL_INTEGER_SPACE]; /* diff --git a/generic/tkSelect.c b/generic/tkSelect.c index 7c96b94..8ba0c5f 100644 --- a/generic/tkSelect.c +++ b/generic/tkSelect.c @@ -26,9 +26,9 @@ 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[4]; /* Command to invoke. Actual space is + char command[1]; /* Command to invoke. Actual space is * allocated as large as necessary. This must * be the last entry in the structure. */ } CommandInfo; @@ -41,9 +41,7 @@ typedef struct { typedef struct LostCommand { Tcl_Interp *interp; /* Interpreter in which to invoke command. */ - char command[4]; /* Command to invoke. Actual space is - * allocated as large as necessary. This must - * be the last entry in the structure. */ + Tcl_Obj *cmdObj; /* Reference to command to invoke. */ } LostCommand; /* @@ -65,7 +63,7 @@ static int HandleTclCommand(ClientData clientData, int offset, char *buffer, int maxBytes); static void LostSelection(ClientData clientData); static int SelGetProc(ClientData clientData, - Tcl_Interp *interp, char *portion); + Tcl_Interp *interp, const char *portion); /* *-------------------------------------------------------------- @@ -141,7 +139,7 @@ Tk_CreateSelHandler( for (selPtr = winPtr->selHandlerList; ; selPtr = selPtr->nextPtr) { if (selPtr == NULL) { - selPtr = (TkSelHandler *) ckalloc(sizeof(TkSelHandler)); + selPtr = ckalloc(sizeof(TkSelHandler)); selPtr->nextPtr = winPtr->selHandlerList; winPtr->selHandlerList = selPtr; break; @@ -154,7 +152,7 @@ Tk_CreateSelHandler( */ if (selPtr->proc == HandleTclCommand) { - ckfree((char *) selPtr->clientData); + ckfree(selPtr->clientData); } break; } @@ -179,7 +177,7 @@ Tk_CreateSelHandler( target = winPtr->dispPtr->utf8Atom; for (selPtr = winPtr->selHandlerList; ; selPtr = selPtr->nextPtr) { if (selPtr == NULL) { - selPtr = (TkSelHandler *) ckalloc(sizeof(TkSelHandler)); + selPtr = ckalloc(sizeof(TkSelHandler)); selPtr->nextPtr = winPtr->selHandlerList; winPtr->selHandlerList = selPtr; selPtr->selection = selection; @@ -192,10 +190,10 @@ Tk_CreateSelHandler( * should make a copy for this selPtr. */ - unsigned cmdInfoLen = sizeof(CommandInfo) + - ((CommandInfo*)clientData)->cmdLength - 3; + unsigned cmdInfoLen = Tk_Offset(CommandInfo, command) + 1 + + ((CommandInfo *)clientData)->cmdLength; - selPtr->clientData = (ClientData)ckalloc(cmdInfoLen); + selPtr->clientData = ckalloc(cmdInfoLen); memcpy(selPtr->clientData, clientData, cmdInfoLen); } else { selPtr->clientData = clientData; @@ -243,7 +241,7 @@ Tk_DeleteSelHandler( TkWindow *winPtr = (TkWindow *) tkwin; register TkSelHandler *selPtr, *prevPtr; register TkSelInProgress *ipPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* @@ -319,10 +317,10 @@ Tk_DeleteSelHandler( * Mark the CommandInfo as deleted and free it if we can. */ - ((CommandInfo*)selPtr->clientData)->interp = NULL; + ((CommandInfo *) selPtr->clientData)->interp = NULL; Tcl_EventuallyFree(selPtr->clientData, TCL_DYNAMIC); } - ckfree((char *) selPtr); + ckfree(selPtr); } /* @@ -384,7 +382,7 @@ Tk_OwnSelection( } } if (infoPtr == NULL) { - infoPtr = (TkSelectionInfo*) ckalloc(sizeof(TkSelectionInfo)); + infoPtr = ckalloc(sizeof(TkSelectionInfo)); infoPtr->selection = selection; infoPtr->nextPtr = dispPtr->selectionInfoPtr; dispPtr->selectionInfoPtr = infoPtr; @@ -399,7 +397,7 @@ Tk_OwnSelection( * memory leak. */ - ckfree((char *) infoPtr->clearData); + ckfree(infoPtr->clearData); } } @@ -433,7 +431,7 @@ Tk_OwnSelection( */ if (clearProc != NULL) { - (*clearProc)(clearData); + clearProc(clearData); } } @@ -492,12 +490,12 @@ Tk_ClearSelection( if (infoPtr != NULL) { clearProc = infoPtr->clearProc; clearData = infoPtr->clearData; - ckfree((char *) infoPtr); + ckfree(infoPtr); } XSetSelectionOwner(winPtr->display, selection, None, CurrentTime); if (clearProc != NULL) { - (*clearProc)(clearData); + clearProc(clearData); } } @@ -558,7 +556,7 @@ Tk_GetSelection( TkWindow *winPtr = (TkWindow *) tkwin; TkDisplay *dispPtr = winPtr->dispPtr; TkSelectionInfo *infoPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (dispPtr->multipleAtom == None) { @@ -602,7 +600,7 @@ Tk_GetSelection( goto cantget; } buffer[count] = 0; - result = (*proc)(clientData, interp, buffer); + result = proc(clientData, interp, buffer); } else { offset = 0; result = TCL_OK; @@ -610,7 +608,7 @@ Tk_GetSelection( ip.nextPtr = tsdPtr->pendingPtr; tsdPtr->pendingPtr = &ip; while (1) { - count = (selPtr->proc)(selPtr->clientData, offset, buffer, + count = selPtr->proc(selPtr->clientData, offset, buffer, TK_SEL_BYTES_AT_ONCE); if ((count < 0) || (ip.selPtr == NULL)) { tsdPtr->pendingPtr = ip.nextPtr; @@ -620,7 +618,7 @@ Tk_GetSelection( Tcl_Panic("selection handler returned too many bytes"); } buffer[count] = '\0'; - result = (*proc)(clientData, interp, buffer); + result = proc(clientData, interp, buffer); if ((result != TCL_OK) || (count < TK_SEL_BYTES_AT_ONCE) || (ip.selPtr == NULL)) { break; @@ -640,9 +638,10 @@ Tk_GetSelection( clientData); cantget: - Tcl_AppendResult(interp, Tk_GetAtomName(tkwin, selection), - " selection doesn't exist or form \"", - Tk_GetAtomName(tkwin, target), "\" not defined", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "%s selection doesn't exist or form \"%s\" not defined", + Tk_GetAtomName(tkwin, selection), + Tk_GetAtomName(tkwin, target))); return TCL_ERROR; } @@ -669,15 +668,16 @@ Tk_SelectionObjCmd( * interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { - Tk_Window tkwin = (Tk_Window) clientData; - char *path = NULL; + Tk_Window tkwin = clientData; + const char *path = NULL; Atom selection; - char *selName = NULL, *string; + const char *selName = NULL; + const char *string; int count, index; Tcl_Obj **objs; - static CONST char *optionStrings[] = { + static const char *const optionStrings[] = { "clear", "get", "handle", "own", NULL }; enum options { @@ -685,7 +685,7 @@ Tk_SelectionObjCmd( }; if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?"); + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); return TCL_ERROR; } @@ -696,7 +696,7 @@ Tk_SelectionObjCmd( switch ((enum options) index) { case SELECTION_CLEAR: { - static CONST char *clearOptionStrings[] = { + static const char *const clearOptionStrings[] = { "-displayof", "-selection", NULL }; enum clearOptions { CLEAR_DISPLAYOF, CLEAR_SELECTION }; @@ -709,8 +709,9 @@ Tk_SelectionObjCmd( break; } if (count < 2) { - Tcl_AppendResult(interp, "value for \"", string, - "\" missing", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "value for \"%s\" missing", string)); + Tcl_SetErrorCode(interp, "TK", "SELECTION", "VALUE", NULL); return TCL_ERROR; } @@ -731,7 +732,7 @@ Tk_SelectionObjCmd( if (count == 1) { path = Tcl_GetString(objs[0]); } else if (count > 1) { - Tcl_WrongNumArgs(interp, 2, objv, "?options?"); + Tcl_WrongNumArgs(interp, 2, objv, "?-option value ...?"); return TCL_ERROR; } if (path != NULL) { @@ -752,10 +753,10 @@ Tk_SelectionObjCmd( case SELECTION_GET: { Atom target; - char *targetName = NULL; + const char *targetName = NULL; Tcl_DString selBytes; int result; - static CONST char *getOptionStrings[] = { + static const char *const getOptionStrings[] = { "-displayof", "-selection", "-type", NULL }; enum getOptions { GET_DISPLAYOF, GET_SELECTION, GET_TYPE }; @@ -768,8 +769,9 @@ Tk_SelectionObjCmd( break; } if (count < 2) { - Tcl_AppendResult(interp, "value for \"", string, - "\" missing", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "value for \"%s\" missing", string)); + Tcl_SetErrorCode(interp, "TK", "SELECTION", "VALUE", NULL); return TCL_ERROR; } @@ -803,7 +805,7 @@ Tk_SelectionObjCmd( selection = XA_PRIMARY; } if (count > 1) { - Tcl_WrongNumArgs(interp, 2, objv, "?options?"); + Tcl_WrongNumArgs(interp, 2, objv, "?-option value ...?"); return TCL_ERROR; } else if (count == 1) { target = Tk_InternAtom(tkwin, Tcl_GetString(objs[0])); @@ -815,7 +817,7 @@ Tk_SelectionObjCmd( Tcl_DStringInit(&selBytes); result = Tk_GetSelection(interp, tkwin, selection, target, - SelGetProc, (ClientData) &selBytes); + SelGetProc, &selBytes); if (result == TCL_OK) { Tcl_DStringResult(interp, &selBytes); } else { @@ -826,11 +828,11 @@ Tk_SelectionObjCmd( case SELECTION_HANDLE: { Atom target, format; - char *targetName = NULL; - char *formatName = NULL; + const char *targetName = NULL; + const char *formatName = NULL; register CommandInfo *cmdInfoPtr; int cmdLength; - static CONST char *handleOptionStrings[] = { + static const char *const handleOptionStrings[] = { "-format", "-selection", "-type", NULL }; enum handleOptions { @@ -845,8 +847,9 @@ Tk_SelectionObjCmd( break; } if (count < 2) { - Tcl_AppendResult(interp, "value for \"", string, - "\" missing", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "value for \"%s\" missing", string)); + Tcl_SetErrorCode(interp, "TK", "SELECTION", "VALUE", NULL); return TCL_ERROR; } @@ -869,7 +872,8 @@ Tk_SelectionObjCmd( } if ((count < 2) || (count > 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "?options? window command"); + Tcl_WrongNumArgs(interp, 2, objv, + "?-option value ...? window command"); return TCL_ERROR; } tkwin = Tk_NameToWindow(interp, Tcl_GetString(objs[0]), tkwin); @@ -900,8 +904,8 @@ Tk_SelectionObjCmd( if (cmdLength == 0) { Tk_DeleteSelHandler(tkwin, selection, target); } else { - cmdInfoPtr = (CommandInfo *) ckalloc((unsigned) ( - sizeof(CommandInfo) - 3 + cmdLength)); + cmdInfoPtr = ckalloc(Tk_Offset(CommandInfo, command) + + 1 + cmdLength); cmdInfoPtr->interp = interp; cmdInfoPtr->charOffset = 0; cmdInfoPtr->byteOffset = 0; @@ -909,16 +913,15 @@ Tk_SelectionObjCmd( cmdInfoPtr->cmdLength = cmdLength; memcpy(cmdInfoPtr->command, string, cmdLength + 1); Tk_CreateSelHandler(tkwin, selection, target, HandleTclCommand, - (ClientData) cmdInfoPtr, format); + cmdInfoPtr, format); } return TCL_OK; } case SELECTION_OWN: { register LostCommand *lostPtr; - char *script = NULL; - int cmdLength; - static CONST char *ownOptionStrings[] = { + Tcl_Obj *commandObj = NULL; + static const char *const ownOptionStrings[] = { "-command", "-displayof", "-selection", NULL }; enum ownOptions { OWN_COMMAND, OWN_DISPLAYOF, OWN_SELECTION }; @@ -931,8 +934,9 @@ Tk_SelectionObjCmd( break; } if (count < 2) { - Tcl_AppendResult(interp, "value for \"", string, - "\" missing", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "value for \"%s\" missing", string)); + Tcl_SetErrorCode(interp, "TK", "SELECTION", "VALUE", NULL); return TCL_ERROR; } @@ -943,7 +947,7 @@ Tk_SelectionObjCmd( switch ((enum ownOptions) ownIndex) { case OWN_COMMAND: - script = Tcl_GetString(objs[1]); + commandObj = objs[1]; break; case OWN_DISPLAYOF: path = Tcl_GetString(objs[1]); @@ -955,7 +959,7 @@ Tk_SelectionObjCmd( } if (count > 2) { - Tcl_WrongNumArgs(interp, 2, objv, "?options? ?window?"); + Tcl_WrongNumArgs(interp, 2, objv, "?-option value ...? ?window?"); return TCL_ERROR; } if (selName != NULL) { @@ -974,7 +978,7 @@ Tk_SelectionObjCmd( if (tkwin == NULL) { return TCL_ERROR; } - winPtr = (TkWindow *)tkwin; + winPtr = (TkWindow *) tkwin; for (infoPtr = winPtr->dispPtr->selectionInfoPtr; infoPtr != NULL; infoPtr = infoPtr->nextPtr) { if (infoPtr->selection == selection) { @@ -988,7 +992,7 @@ Tk_SelectionObjCmd( if ((infoPtr != NULL) && (infoPtr->owner != winPtr->dispPtr->clipWindow)) { - Tcl_SetResult(interp, Tk_PathName(infoPtr->owner), TCL_STATIC); + Tcl_SetObjResult(interp, TkNewWindowObj(infoPtr->owner)); } return TCL_OK; } @@ -998,18 +1002,17 @@ Tk_SelectionObjCmd( return TCL_ERROR; } if (count == 2) { - script = Tcl_GetString(objs[1]); + commandObj = objs[1]; } - if (script == NULL) { - Tk_OwnSelection(tkwin, selection, NULL, (ClientData) NULL); + if (commandObj == NULL) { + Tk_OwnSelection(tkwin, selection, NULL, NULL); return TCL_OK; } - cmdLength = strlen(script); - lostPtr = (LostCommand *) ckalloc((unsigned) (sizeof(LostCommand) - -3 + cmdLength)); + lostPtr = ckalloc(sizeof(LostCommand)); lostPtr->interp = interp; - strcpy(lostPtr->command, script); - Tk_OwnSelection(tkwin, selection, LostSelection, (ClientData) lostPtr); + lostPtr->cmdObj = commandObj; + Tcl_IncrRefCount(commandObj); + Tk_OwnSelection(tkwin, selection, LostSelection, lostPtr); return TCL_OK; } } @@ -1037,7 +1040,7 @@ Tk_SelectionObjCmd( TkSelInProgress * TkSelGetInProgress(void) { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); return tsdPtr->pendingPtr; @@ -1064,7 +1067,7 @@ void TkSelSetInProgress( TkSelInProgress *pendingPtr) { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); tsdPtr->pendingPtr = pendingPtr; @@ -1094,7 +1097,7 @@ TkSelDeadWindow( register TkSelHandler *selPtr; register TkSelInProgress *ipPtr; TkSelectionInfo *infoPtr, *prevPtr, *nextPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* @@ -1117,10 +1120,10 @@ TkSelDeadWindow( * Mark the CommandInfo as deleted and free it when we can. */ - ((CommandInfo*)selPtr->clientData)->interp = NULL; + ((CommandInfo *) selPtr->clientData)->interp = NULL; Tcl_EventuallyFree(selPtr->clientData, TCL_DYNAMIC); } - ckfree((char *) selPtr); + ckfree(selPtr); } /* @@ -1132,9 +1135,9 @@ TkSelDeadWindow( nextPtr = infoPtr->nextPtr; if (infoPtr->owner == (Tk_Window) winPtr) { if (infoPtr->clearProc == LostSelection) { - ckfree((char *) infoPtr->clearData); + ckfree(infoPtr->clearData); } - ckfree((char *) infoPtr); + ckfree(infoPtr); infoPtr = prevPtr; if (prevPtr == NULL) { winPtr->dispPtr->selectionInfoPtr = nextPtr; @@ -1182,6 +1185,7 @@ TkSelInit( dispPtr->applicationAtom = Tk_InternAtom(tkwin, "TK_APPLICATION"); dispPtr->windowAtom = Tk_InternAtom(tkwin, "TK_WINDOW"); dispPtr->clipboardAtom = Tk_InternAtom(tkwin, "CLIPBOARD"); + dispPtr->atomPairAtom = Tk_InternAtom(tkwin, "ATOM_PAIR"); /* * Using UTF8_STRING instead of the XA_UTF8_STRING macro allows us to @@ -1190,7 +1194,7 @@ TkSelInit( * http://www.cl.cam.ac.uk/~mgk25/unicode.html#x11 */ -#if !(defined(__WIN32__) || defined(MAC_OSX_TK)) +#if !defined(_WIN32) dispPtr->utf8Atom = Tk_InternAtom(tkwin, "UTF8_STRING"); #else dispPtr->utf8Atom = (Atom) 0; @@ -1257,9 +1261,9 @@ TkSelClearSelection( */ if (infoPtr->clearProc != NULL) { - (*infoPtr->clearProc)(infoPtr->clearData); + infoPtr->clearProc(infoPtr->clearData); } - ckfree((char *) infoPtr); + ckfree(infoPtr); } } @@ -1288,9 +1292,9 @@ SelGetProc( * selection. */ Tcl_Interp *interp, /* Interpreter used for error reporting (not * used). */ - char *portion) /* New information to be appended. */ + const char *portion) /* New information to be appended. */ { - Tcl_DStringAppend((Tcl_DString *) clientData, portion, -1); + Tcl_DStringAppend(clientData, portion, -1); return TCL_OK; } @@ -1322,16 +1326,14 @@ HandleTclCommand( char *buffer, /* Place to store converted selection. */ int maxBytes) /* Maximum # of bytes to store at buffer. */ { - CommandInfo *cmdInfoPtr = (CommandInfo *) clientData; - int spaceNeeded, length; -#define MAX_STATIC_SIZE 100 - char staticSpace[MAX_STATIC_SIZE]; - char *command, *string; + CommandInfo *cmdInfoPtr = clientData; + int length; + Tcl_Obj *command; + const char *string; Tcl_Interp *interp = cmdInfoPtr->interp; - Tcl_DString oldResult; - Tcl_Obj *objPtr; - int extraBytes, charOffset, count, numChars; - CONST char *p; + Tcl_InterpState savedState; + int extraBytes, charOffset, count, numChars, code; + const char *p; /* * We must also protect the interpreter and the command from being deleted @@ -1339,7 +1341,7 @@ HandleTclCommand( */ Tcl_Preserve(clientData); - Tcl_Preserve((ClientData) interp); + Tcl_Preserve(interp); /* * Compute the proper byte offset in the case where the last chunk split a @@ -1366,24 +1368,24 @@ HandleTclCommand( * the offset and maximum # of bytes. */ - spaceNeeded = cmdInfoPtr->cmdLength + 30; - if (spaceNeeded < MAX_STATIC_SIZE) { - command = staticSpace; - } else { - command = (char *) ckalloc((unsigned) spaceNeeded); - } - sprintf(command, "%s %d %d", cmdInfoPtr->command, charOffset, maxBytes); + command = Tcl_ObjPrintf("%s %d %d", + cmdInfoPtr->command, charOffset, maxBytes); + Tcl_IncrRefCount(command); /* * Execute the command. Be sure to restore the state of the interpreter * after executing the command. */ - Tcl_DStringInit(&oldResult); - Tcl_DStringGetResult(interp, &oldResult); - if (TkCopyAndGlobalEval(interp, command) == TCL_OK) { - objPtr = Tcl_GetObjResult(interp); - string = Tcl_GetStringFromObj(objPtr, &length); + savedState = Tcl_SaveInterpState(interp, TCL_OK); + code = Tcl_EvalObjEx(interp, command, TCL_EVAL_GLOBAL); + Tcl_DecrRefCount(command); + if (code == TCL_OK) { + /* + * TODO: This assumes that bytes are characters; that's not true! + */ + + string = Tcl_GetStringFromObj(Tcl_GetObjResult(interp), &length); count = (length > maxBytes) ? maxBytes : length; memcpy(buffer, string, (size_t) count); buffer[count] = '\0'; @@ -1416,16 +1418,21 @@ HandleTclCommand( } count += extraBytes; } else { - count = -1; - } - Tcl_DStringResult(interp, &oldResult); + /* + * Something went wrong. Log errors as background errors, and silently + * drop everything else. + */ - if (command != staticSpace) { - ckfree(command); + if (code == TCL_ERROR) { + Tcl_AddErrorInfo(interp, "\n (command handling selection)"); + Tcl_BackgroundException(interp, code); + } + count = -1; } + (void) Tcl_RestoreInterpState(interp, savedState); Tcl_Release(clientData); - Tcl_Release((ClientData) interp); + Tcl_Release(interp); return count; } @@ -1490,8 +1497,9 @@ TkSelDefaultSelection( if ((selPtr->selection == infoPtr->selection) && (selPtr->target != dispPtr->applicationAtom) && (selPtr->target != dispPtr->windowAtom)) { - CONST char *atomString = Tk_GetAtomName((Tk_Window) winPtr, + const char *atomString = Tk_GetAtomName((Tk_Window) winPtr, selPtr->target); + Tcl_DStringAppendElement(&ds, atomString); } } @@ -1557,36 +1565,33 @@ static void LostSelection( ClientData clientData) /* Pointer to LostCommand structure. */ { - LostCommand *lostPtr = (LostCommand *) clientData; - Tcl_Obj *objPtr; - Tcl_Interp *interp; + LostCommand *lostPtr = clientData; + Tcl_Interp *interp = lostPtr->interp; + Tcl_InterpState savedState; + int code; - interp = lostPtr->interp; - Tcl_Preserve((ClientData) interp); + Tcl_Preserve(interp); /* * Execute the command. Save the interpreter's result, if any, and restore * it after executing the command. */ - objPtr = Tcl_GetObjResult(interp); - Tcl_IncrRefCount(objPtr); + savedState = Tcl_SaveInterpState(interp, TCL_OK); Tcl_ResetResult(interp); - - if (TkCopyAndGlobalEval(interp, lostPtr->command) != TCL_OK) { - Tcl_BackgroundError(interp); + code = Tcl_EvalObjEx(interp, lostPtr->cmdObj, TCL_EVAL_GLOBAL); + if (code != TCL_OK) { + Tcl_BackgroundException(interp, code); } - - Tcl_SetObjResult(interp, objPtr); - Tcl_DecrRefCount(objPtr); - - Tcl_Release((ClientData) interp); + (void) Tcl_RestoreInterpState(interp, savedState); /* * Free the storage for the command, since we're done with it now. */ - ckfree((char *) lostPtr); + Tcl_DecrRefCount(lostPtr->cmdObj); + ckfree(lostPtr); + Tcl_Release(interp); } /* diff --git a/generic/tkSelect.h b/generic/tkSelect.h index b9d7d2d..74326d0 100644 --- a/generic/tkSelect.h +++ b/generic/tkSelect.h @@ -75,8 +75,7 @@ typedef struct TkSelRetrievalInfo { Atom selection; /* Selection being requested. */ Atom property; /* Property where selection will appear. */ Atom target; /* Desired form for selection. */ - int (*proc) _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, - char *portion)); /* Procedure to call to handle pieces of + Tk_GetSelProc *proc; /* Procedure to call to handle pieces of * selection. */ ClientData clientData; /* Argument for proc. */ int result; /* Initially -1. Set to a Tcl return value @@ -160,9 +159,6 @@ MODULE_SCOPE void TkSelClearSelection(Tk_Window tkwin, XEvent *eventPtr); MODULE_SCOPE int TkSelDefaultSelection(TkSelectionInfo *infoPtr, Atom target, char *buffer, int maxBytes, Atom *typePtr); -MODULE_SCOPE int TkSelGetSelection(Tcl_Interp *interp, Tk_Window tkwin, - Atom selection, Atom target, Tk_GetSelProc *proc, - ClientData clientData); #ifndef TkSelUpdateClipboard MODULE_SCOPE void TkSelUpdateClipboard(TkWindow *winPtr, TkClipboardTarget *targetPtr); diff --git a/generic/tkSquare.c b/generic/tkSquare.c index b8a4fad..e92c03c 100644 --- a/generic/tkSquare.c +++ b/generic/tkSquare.c @@ -16,6 +16,12 @@ #if 0 #define __NO_OLD_CONFIG #endif +#ifndef USE_TCL_STUBS +# define USE_TCL_STUBS +#endif +#ifndef USE_TK_STUBS +# define USE_TK_STUBS +#endif #include "tkInt.h" /* @@ -61,47 +67,44 @@ typedef struct { static const Tk_OptionSpec optionSpecs[] = { {TK_OPTION_BORDER, "-background", "background", "Background", "#d9d9d9", Tk_Offset(Square, bgBorderPtr), -1, 0, - (ClientData) "white"}, + "white", 0}, {TK_OPTION_SYNONYM, "-bd", NULL, NULL, NULL, 0, -1, 0, - (ClientData) "-borderwidth"}, + "-borderwidth", 0}, {TK_OPTION_SYNONYM, "-bg", NULL, NULL, NULL, 0, -1, 0, - (ClientData) "-background"}, + "-background", 0}, {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", - "2", Tk_Offset(Square, borderWidthPtr), -1}, + "2", Tk_Offset(Square, borderWidthPtr), -1, 0, NULL, 0}, {TK_OPTION_BOOLEAN, "-dbl", "doubleBuffer", "DoubleBuffer", - "1", Tk_Offset(Square, doubleBufferPtr), -1}, + "1", Tk_Offset(Square, doubleBufferPtr), -1, 0 , NULL, 0}, {TK_OPTION_SYNONYM, "-fg", NULL, NULL, NULL, 0, -1, 0, - (ClientData) "-foreground"}, + "-foreground", 0}, {TK_OPTION_BORDER, "-foreground", "foreground", "Foreground", "#b03060", Tk_Offset(Square, fgBorderPtr), -1, 0, - (ClientData) "black"}, + "black", 0}, {TK_OPTION_PIXELS, "-posx", "posx", "PosX", "0", - Tk_Offset(Square, xPtr), -1}, + Tk_Offset(Square, xPtr), -1, 0, NULL, 0}, {TK_OPTION_PIXELS, "-posy", "posy", "PosY", "0", - Tk_Offset(Square, yPtr), -1}, + Tk_Offset(Square, yPtr), -1, 0, NULL, 0}, {TK_OPTION_RELIEF, "-relief", "relief", "Relief", - "raised", Tk_Offset(Square, reliefPtr), -1}, + "raised", Tk_Offset(Square, reliefPtr), -1, 0, NULL, 0}, {TK_OPTION_PIXELS, "-size", "size", "Size", "20", - Tk_Offset(Square, sizeObjPtr), -1}, - {TK_OPTION_END} + Tk_Offset(Square, sizeObjPtr), -1, 0, NULL, 0}, + {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0} }; /* * Forward declarations for procedures defined later in this file: */ -int SquareObjCmd(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj * CONST objv[]); static void SquareDeletedProc(ClientData clientData); static int SquareConfigure(Tcl_Interp *interp, Square *squarePtr); -static void SquareDestroy(char *memPtr); +static void SquareDestroy(void *memPtr); static void SquareDisplay(ClientData clientData); static void KeepInWindow(Square *squarePtr); static void SquareObjEventProc(ClientData clientData, XEvent *eventPtr); static int SquareWidgetObjCmd(ClientData clientData, - Tcl_Interp *, int objc, Tcl_Obj * CONST objv[]); + Tcl_Interp *, int objc, Tcl_Obj * const objv[]); /* *-------------------------------------------------------------- @@ -125,14 +128,14 @@ SquareObjCmd( ClientData clientData, /* NULL. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { Square *squarePtr; Tk_Window tkwin; Tk_OptionTable optionTable; if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?"); + Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?"); return TCL_ERROR; } @@ -157,27 +160,27 @@ SquareObjCmd( * just the non-NULL/0 items. */ - squarePtr = (Square *) ckalloc(sizeof(Square)); - memset((void *) squarePtr, 0, (sizeof(Square))); + squarePtr = ckalloc(sizeof(Square)); + memset(squarePtr, 0, sizeof(Square)); squarePtr->tkwin = tkwin; squarePtr->display = Tk_Display(tkwin); squarePtr->interp = interp; squarePtr->widgetCmd = Tcl_CreateObjCommand(interp, - Tk_PathName(squarePtr->tkwin), SquareWidgetObjCmd, - (ClientData) squarePtr, SquareDeletedProc); + Tk_PathName(squarePtr->tkwin), SquareWidgetObjCmd, squarePtr, + SquareDeletedProc); squarePtr->gc = NULL; squarePtr->optionTable = optionTable; if (Tk_InitOptions(interp, (char *) squarePtr, optionTable, tkwin) != TCL_OK) { Tk_DestroyWindow(squarePtr->tkwin); - ckfree((char *) squarePtr); + ckfree(squarePtr); return TCL_ERROR; } Tk_CreateEventHandler(squarePtr->tkwin, ExposureMask|StructureNotifyMask, - SquareObjEventProc, (ClientData) squarePtr); + SquareObjEventProc, squarePtr); if (Tk_SetOptions(interp, (char *) squarePtr, optionTable, objc - 2, objv + 2, tkwin, NULL, NULL) != TCL_OK) { goto error; @@ -218,11 +221,11 @@ SquareWidgetObjCmd( ClientData clientData, /* Information about square widget. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj * CONST objv[]) /* Argument objects. */ + Tcl_Obj * const objv[]) /* Argument objects. */ { - Square *squarePtr = (Square *) clientData; + Square *squarePtr = clientData; int result = TCL_OK; - static CONST char *squareOptions[] = {"cget", "configure", NULL}; + static const char *const squareOptions[] = {"cget", "configure", NULL}; enum { SQUARE_CGET, SQUARE_CONFIGURE }; @@ -234,12 +237,12 @@ SquareWidgetObjCmd( return TCL_ERROR; } - if (Tcl_GetIndexFromObj(interp, objv[1], squareOptions, "command", - 0, &index) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[1], squareOptions, + sizeof(char *), "command", 0, &index) != TCL_OK) { return TCL_ERROR; } - Tcl_Preserve((ClientData) squarePtr); + Tcl_Preserve(squarePtr); switch (index) { case SQUARE_CGET: @@ -277,7 +280,7 @@ SquareWidgetObjCmd( result = SquareConfigure(interp, squarePtr); } if (!squarePtr->updatePending) { - Tcl_DoWhenIdle(SquareDisplay, (ClientData) squarePtr); + Tcl_DoWhenIdle(SquareDisplay, squarePtr); squarePtr->updatePending = 1; } } @@ -285,11 +288,11 @@ SquareWidgetObjCmd( Tcl_SetObjResult(interp, resultObjPtr); } } - Tcl_Release((ClientData) squarePtr); + Tcl_Release(squarePtr); return result; error: - Tcl_Release((ClientData) squarePtr); + Tcl_Release(squarePtr); return TCL_ERROR; } @@ -350,7 +353,7 @@ SquareConfigure( &borderWidth); Tk_SetInternalBorder(squarePtr->tkwin, borderWidth); if (!squarePtr->updatePending) { - Tcl_DoWhenIdle(SquareDisplay, (ClientData) squarePtr); + Tcl_DoWhenIdle(SquareDisplay, squarePtr); squarePtr->updatePending = 1; } KeepInWindow(squarePtr); @@ -380,17 +383,17 @@ SquareObjEventProc( ClientData clientData, /* Information about window. */ XEvent *eventPtr) /* Information about event. */ { - Square *squarePtr = (Square *) clientData; + Square *squarePtr = clientData; if (eventPtr->type == Expose) { if (!squarePtr->updatePending) { - Tcl_DoWhenIdle(SquareDisplay, (ClientData) squarePtr); + Tcl_DoWhenIdle(SquareDisplay, squarePtr); squarePtr->updatePending = 1; } } else if (eventPtr->type == ConfigureNotify) { KeepInWindow(squarePtr); if (!squarePtr->updatePending) { - Tcl_DoWhenIdle(SquareDisplay, (ClientData) squarePtr); + Tcl_DoWhenIdle(SquareDisplay, squarePtr); squarePtr->updatePending = 1; } } else if (eventPtr->type == DestroyNotify) { @@ -405,9 +408,9 @@ SquareObjEventProc( squarePtr->widgetCmd); } if (squarePtr->updatePending) { - Tcl_CancelIdleCall(SquareDisplay, (ClientData) squarePtr); + Tcl_CancelIdleCall(SquareDisplay, squarePtr); } - Tcl_EventuallyFree((ClientData) squarePtr, SquareDestroy); + Tcl_EventuallyFree(squarePtr, (Tcl_FreeProc *) SquareDestroy); } } @@ -433,7 +436,7 @@ static void SquareDeletedProc( ClientData clientData) /* Pointer to widget record for widget. */ { - Square *squarePtr = (Square *) clientData; + Square *squarePtr = clientData; Tk_Window tkwin = squarePtr->tkwin; /* @@ -470,7 +473,7 @@ static void SquareDisplay( ClientData clientData) /* Information about window. */ { - Square *squarePtr = (Square *) clientData; + Square *squarePtr = clientData; Tk_Window tkwin = squarePtr->tkwin; Pixmap pm = None; Drawable d; @@ -551,11 +554,11 @@ SquareDisplay( static void SquareDestroy( - char *memPtr) /* Info about square widget. */ + void *memPtr) /* Info about square widget. */ { - Square *squarePtr = (Square *) memPtr; + Square *squarePtr = memPtr; - ckfree((char *) squarePtr); + ckfree(squarePtr); } /* diff --git a/generic/tkStubInit.c b/generic/tkStubInit.c index 3573db0..7e02302 100644 --- a/generic/tkStubInit.c +++ b/generic/tkStubInit.c @@ -11,13 +11,13 @@ #include "tkInt.h" -#if !(defined(__WIN32__) || defined(MAC_OSX_TK)) +#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* UNIX */ #define UNIX_TK #include "tkUnixInt.h" #endif -#ifdef __WIN32__ +#ifdef _WIN32 #include "tkWinInt.h" #endif @@ -30,71 +30,46 @@ #include "tkPlatDecls.h" #include "tkIntXlibDecls.h" -#define TkUnusedStubEntry NULL +static const TkIntStubs tkIntStubs; +MODULE_SCOPE const TkStubs tkStubs; -#ifdef __WIN32__ +/* + * Remove macro that might interfere with the definition below. + */ + +#undef Tk_MainEx -static int -doNothing(void) +#ifdef _WIN32 + +int +TkpCmapStressed(Tk_Window tkwin, Colormap colormap) { /* dummy implementation, no need to do anything */ return 0; } - -#define TkCreateXEventSource TkPlatCreateXEventSource -static void -TkCreateXEventSource(void) -{ - TkWinXInit(Tk_GetHINSTANCE()); -} - -#undef XFree -#define XFree TkPlatXFree -static int -XFree(void *data) +void +TkpSync(Display *display) { - if (data != NULL) { - ckfree((char *) data); - } - return 0; + /* dummy implementation, no need to do anything */ } -#undef XVisualIDFromVisual -#define XVisualIDFromVisual TkPlatXVisualIDFromVisual -static VisualID -XVisualIDFromVisual(Visual *visual) +void +TkCreateXEventSource(void) { - return visual->visualid; + TkWinXInit(Tk_GetHINSTANCE()); } -/* - * Remove macros that will interfere with the definitions below. - */ -# undef TkpCmapStressed -# undef TkpSync -# undef XFlush -# undef XGrabServer -# undef XUngrabServer -# undef XNoOp -# undef XSynchronize -# undef XSync - -# define TkpCmapStressed (int (*) (Tk_Window, Colormap)) doNothing -# define TkpSync (void (*) (Display *)) doNothing # define TkUnixContainerId 0 # define TkUnixDoOneXEvent 0 # define TkUnixSetMenubar 0 -# define TkWmCleanup (void (*) (TkDisplay *)) doNothing -# define TkSendCleanup (void (*) (TkDisplay *)) doNothing +# define XCreateWindow 0 +# define XOffsetRegion 0 +# define XUnionRegion 0 +# define TkWmCleanup (void (*)(TkDisplay *)) TkpSync +# define TkSendCleanup (void (*)(TkDisplay *)) TkpSync # define TkpTestsendCmd 0 -# define XFlush (int (*) (Display *)) doNothing -# define XGrabServer (int (*) (Display *)) doNothing -# define XUngrabServer (int (*) (Display *)) doNothing -# define XNoOp (int (*) (Display *)) doNothing -# define XSynchronize (XAfterFunction (*) (Display *, Bool)) doNothing -# define XSync (int (*) (Display *, Bool)) doNothing -#else /* !__WIN32__ */ +#else /* !_WIN32 */ /* * Make sure that extensions which call XParseColor through the stub @@ -104,8 +79,6 @@ XVisualIDFromVisual(Visual *visual) # ifdef __CYGWIN__ - TkIntStubs tkIntStubs; - /* * Trick, so we don't have to include <windows.h> here, which in any * case lacks this function anyway. @@ -136,7 +109,7 @@ TkpPrintWindowId( * the hex representation of a pointer. */ Window window) /* Window to be printed into buffer. */ { - sprintf(buf, "%#08lx", (unsigned long) (window)); + sprintf(buf, "%#08lx", (unsigned long) (window)); } int @@ -235,8 +208,6 @@ void TkSubtractRegion (TkRegion a, TkRegion b, TkRegion c) # define TkWinGetPlatformTheme 0 # define TkWinChildProc 0 -# define TkBindDeadWindow 0 /* On purpose not in Cygwin's stub table */ - # elif !defined(MAC_OSX_TK) /* UNIX */ # undef TkClipBox @@ -257,7 +228,7 @@ void TkSubtractRegion (TkRegion a, TkRegion b, TkRegion c) # define TkUnionRectWithRegion (void (*) (XRectangle *, TkRegion, TkRegion)) XUnionRectWithRegion # define TkSubtractRegion (void (*) (TkRegion, TkRegion, TkRegion)) XSubtractRegion # endif -#endif /* !__WIN32__ */ +#endif /* !_WIN32 */ /* * WARNING: The contents of this file is automatically generated by the @@ -267,21 +238,21 @@ void TkSubtractRegion (TkRegion a, TkRegion b, TkRegion c) /* !BEGIN!: Do not edit below this line. */ -TkIntStubs tkIntStubs = { +static const TkIntStubs tkIntStubs = { TCL_STUB_MAGIC, - NULL, + 0, TkAllocWindow, /* 0 */ TkBezierPoints, /* 1 */ TkBezierScreenPoints, /* 2 */ - TkBindDeadWindow, /* 3 */ + 0, /* 3 */ TkBindEventProc, /* 4 */ TkBindFree, /* 5 */ TkBindInit, /* 6 */ TkChangeEventWindow, /* 7 */ TkClipInit, /* 8 */ TkComputeAnchor, /* 9 */ - TkCopyAndGlobalEval, /* 10 */ - TkCreateBindingProcedure, /* 11 */ + 0, /* 10 */ + 0, /* 11 */ TkCreateCursorFromData, /* 12 */ TkCreateFrame, /* 13 */ TkCreateMainWindow, /* 14 */ @@ -346,7 +317,7 @@ TkIntStubs tkIntStubs = { TkpRedirectKeyEvent, /* 73 */ TkpSetMainMenubar, /* 74 */ TkpUseWindow, /* 75 */ - TkpWindowWasRecentlyDeleted, /* 76 */ + 0, /* 76 */ TkQueueEventForAllChildren, /* 77 */ TkReadBitmapFile, /* 78 */ TkScrollWindow, /* 79 */ @@ -354,7 +325,7 @@ TkIntStubs tkIntStubs = { TkSelEventProc, /* 81 */ TkSelInit, /* 82 */ TkSelPropProc, /* 83 */ - NULL, /* 84 */ + 0, /* 84 */ TkSetWindowMenuBar, /* 85 */ TkStringToKeysym, /* 86 */ TkThickPolyLineToArea, /* 87 */ @@ -390,48 +361,48 @@ TkIntStubs tkIntStubs = { TkRectInRegion, /* 117 */ TkSetRegion, /* 118 */ TkUnionRectWithRegion, /* 119 */ - NULL, /* 120 */ -#if !(defined(__WIN32__) || defined(MAC_OSX_TK)) /* X11 */ - NULL, /* 121 */ + 0, /* 120 */ +#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */ + 0, /* 121 */ #endif /* X11 */ -#if defined(__WIN32__) /* WIN */ - NULL, /* 121 */ +#if defined(_WIN32) /* WIN */ + 0, /* 121 */ #endif /* WIN */ #ifdef MAC_OSX_TK /* AQUA */ - NULL, /* 121 */ /* Dummy entry for stubs table backwards compatibility */ + 0, /* 121 */ /* Dummy entry for stubs table backwards compatibility */ TkpCreateNativeBitmap, /* 121 */ #endif /* AQUA */ -#if !(defined(__WIN32__) || defined(MAC_OSX_TK)) /* X11 */ - NULL, /* 122 */ +#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */ + 0, /* 122 */ #endif /* X11 */ -#if defined(__WIN32__) /* WIN */ - NULL, /* 122 */ +#if defined(_WIN32) /* WIN */ + 0, /* 122 */ #endif /* WIN */ #ifdef MAC_OSX_TK /* AQUA */ - NULL, /* 122 */ /* Dummy entry for stubs table backwards compatibility */ + 0, /* 122 */ /* Dummy entry for stubs table backwards compatibility */ TkpDefineNativeBitmaps, /* 122 */ #endif /* AQUA */ - NULL, /* 123 */ -#if !(defined(__WIN32__) || defined(MAC_OSX_TK)) /* X11 */ - NULL, /* 124 */ + 0, /* 123 */ +#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */ + 0, /* 124 */ #endif /* X11 */ -#if defined(__WIN32__) /* WIN */ - NULL, /* 124 */ +#if defined(_WIN32) /* WIN */ + 0, /* 124 */ #endif /* WIN */ #ifdef MAC_OSX_TK /* AQUA */ - NULL, /* 124 */ /* Dummy entry for stubs table backwards compatibility */ + 0, /* 124 */ /* Dummy entry for stubs table backwards compatibility */ TkpGetNativeAppBitmap, /* 124 */ #endif /* AQUA */ - NULL, /* 125 */ - NULL, /* 126 */ - NULL, /* 127 */ - NULL, /* 128 */ - NULL, /* 129 */ - NULL, /* 130 */ - NULL, /* 131 */ - NULL, /* 132 */ - NULL, /* 133 */ - NULL, /* 134 */ + 0, /* 125 */ + 0, /* 126 */ + 0, /* 127 */ + 0, /* 128 */ + 0, /* 129 */ + 0, /* 130 */ + 0, /* 131 */ + 0, /* 132 */ + 0, /* 133 */ + 0, /* 134 */ TkpDrawHighlightBorder, /* 135 */ TkSetFocusWin, /* 136 */ TkpSetKeycodeAndState, /* 137 */ @@ -452,20 +423,20 @@ TkIntStubs tkIntStubs = { TkpDrawFrame, /* 152 */ TkCreateThreadExitHandler, /* 153 */ TkDeleteThreadExitHandler, /* 154 */ - NULL, /* 155 */ + 0, /* 155 */ TkpTestembedCmd, /* 156 */ TkpTesttextCmd, /* 157 */ - NULL, /* 158 */ - NULL, /* 159 */ - NULL, /* 160 */ - NULL, /* 161 */ - NULL, /* 162 */ - NULL, /* 163 */ - NULL, /* 164 */ - NULL, /* 165 */ - NULL, /* 166 */ - NULL, /* 167 */ - NULL, /* 168 */ + TkSelGetSelection, /* 158 */ + TkTextGetIndex, /* 159 */ + TkTextIndexBackBytes, /* 160 */ + TkTextIndexForwBytes, /* 161 */ + TkTextMakeByteIndex, /* 162 */ + TkTextPrintIndex, /* 163 */ + TkTextSetMark, /* 164 */ + TkTextXviewCmd, /* 165 */ + TkTextChanged, /* 166 */ + TkBTreeNumLines, /* 167 */ + TkTextInsertDisplayProc, /* 168 */ TkStateParseProc, /* 169 */ TkStatePrintProc, /* 170 */ TkCanvasDashParseProc, /* 171 */ @@ -478,18 +449,18 @@ TkIntStubs tkIntStubs = { TkOrientPrintProc, /* 178 */ TkSmoothParseProc, /* 179 */ TkSmoothPrintProc, /* 180 */ - NULL, /* 181 */ - NULL, /* 182 */ - NULL, /* 183 */ - TkUnusedStubEntry, /* 184 */ + TkDrawAngledTextLayout, /* 181 */ + TkUnderlineAngledTextLayout, /* 182 */ + TkIntersectAngledTextLayout, /* 183 */ + TkDrawAngledChars, /* 184 */ }; -TkIntPlatStubs tkIntPlatStubs = { +static const TkIntPlatStubs tkIntPlatStubs = { TCL_STUB_MAGIC, - NULL, -#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */ + 0, +#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ TkAlignImageData, /* 0 */ - NULL, /* 1 */ + 0, /* 1 */ TkGenerateActivateEvents, /* 2 */ TkpGetMS, /* 3 */ TkPointerDeadWindow, /* 4 */ @@ -537,8 +508,8 @@ TkIntPlatStubs tkIntPlatStubs = { #endif /* WIN */ #ifdef MAC_OSX_TK /* AQUA */ TkGenerateActivateEvents, /* 0 */ - NULL, /* 1 */ - NULL, /* 2 */ + 0, /* 1 */ + 0, /* 2 */ TkPointerDeadWindow, /* 3 */ TkpSetCapture, /* 4 */ TkpSetCursor, /* 5 */ @@ -549,14 +520,14 @@ TkIntPlatStubs tkIntPlatStubs = { TkMacOSXDispatchMenuEvent, /* 10 */ TkMacOSXInstallCursor, /* 11 */ TkMacOSXHandleTearoffMenu, /* 12 */ - NULL, /* 13 */ + 0, /* 13 */ TkMacOSXDoHLEvent, /* 14 */ - NULL, /* 15 */ + 0, /* 15 */ TkMacOSXGetXWindow, /* 16 */ TkMacOSXGrowToplevel, /* 17 */ TkMacOSXHandleMenuSelect, /* 18 */ - NULL, /* 19 */ - NULL, /* 20 */ + 0, /* 19 */ + 0, /* 20 */ TkMacOSXInvalidateWindow, /* 21 */ TkMacOSXIsCharacterMissing, /* 22 */ TkMacOSXMakeRealWindowExist, /* 23 */ @@ -576,7 +547,7 @@ TkIntPlatStubs tkIntPlatStubs = { TkMacOSXWindowOffset, /* 37 */ TkSetMacColor, /* 38 */ TkSetWMName, /* 39 */ - TkSuspendClipboard, /* 40 */ + 0, /* 40 */ TkMacOSXZoomToplevel, /* 41 */ Tk_TopCoordsToWindow, /* 42 */ TkMacOSXContainerId, /* 43 */ @@ -584,7 +555,7 @@ TkIntPlatStubs tkIntPlatStubs = { TkMacOSXPreprocessMenu, /* 45 */ TkpIsWindowFloating, /* 46 */ TkMacOSXGetCapture, /* 47 */ - NULL, /* 48 */ + 0, /* 48 */ TkGetTransientMaster, /* 49 */ TkGenerateButtonEvent, /* 50 */ TkGenWMDestroyEvent, /* 51 */ @@ -593,10 +564,10 @@ TkIntPlatStubs tkIntPlatStubs = { TkMacOSXDrawable, /* 54 */ TkpScanWindowId, /* 55 */ #endif /* AQUA */ -#if !(defined(__WIN32__) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */ +#if !(defined(_WIN32) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */ TkCreateXEventSource, /* 0 */ - TkFreeWindowId, /* 1 */ - TkInitXId, /* 2 */ + 0, /* 1 */ + 0, /* 2 */ TkpCmapStressed, /* 3 */ TkpSync, /* 4 */ TkUnixContainerId, /* 5 */ @@ -605,16 +576,16 @@ TkIntPlatStubs tkIntPlatStubs = { TkpScanWindowId, /* 8 */ TkWmCleanup, /* 9 */ TkSendCleanup, /* 10 */ - TkFreeXId, /* 11 */ + 0, /* 11 */ TkpWmSetState, /* 12 */ TkpTestsendCmd, /* 13 */ #endif /* X11 */ }; -TkIntXlibStubs tkIntXlibStubs = { +static const TkIntXlibStubs tkIntXlibStubs = { TCL_STUB_MAGIC, - NULL, -#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */ + 0, +#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ XSetDashes, /* 0 */ XGetModifierMapping, /* 1 */ XCreateImage, /* 2 */ @@ -696,7 +667,7 @@ TkIntXlibStubs tkIntXlibStubs = { XFilterEvent, /* 78 */ XmbLookupString, /* 79 */ TkPutImage, /* 80 */ - NULL, /* 81 */ + 0, /* 81 */ XParseColor, /* 82 */ XCreateGC, /* 83 */ XFreeGC, /* 84 */ @@ -730,27 +701,29 @@ TkIntXlibStubs tkIntXlibStubs = { XSynchronize, /* 112 */ XSync, /* 113 */ XVisualIDFromVisual, /* 114 */ - NULL, /* 115 */ - NULL, /* 116 */ - NULL, /* 117 */ - NULL, /* 118 */ - NULL, /* 119 */ - NULL, /* 120 */ - NULL, /* 121 */ - NULL, /* 122 */ - NULL, /* 123 */ - NULL, /* 124 */ - NULL, /* 125 */ - NULL, /* 126 */ - NULL, /* 127 */ - NULL, /* 128 */ - NULL, /* 129 */ - NULL, /* 130 */ - NULL, /* 131 */ - NULL, /* 132 */ + 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 */ @@ -848,10 +821,10 @@ TkIntXlibStubs tkIntXlibStubs = { #endif /* AQUA */ }; -TkPlatStubs tkPlatStubs = { +static const TkPlatStubs tkPlatStubs = { TCL_STUB_MAGIC, - NULL, -#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */ + 0, +#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ Tk_AttachHWND, /* 0 */ Tk_GetHINSTANCE, /* 1 */ Tk_GetHWND, /* 2 */ @@ -874,14 +847,14 @@ TkPlatStubs tkPlatStubs = { #endif /* AQUA */ }; -static TkStubHooks tkStubHooks = { +static const TkStubHooks tkStubHooks = { &tkPlatStubs, &tkIntStubs, &tkIntPlatStubs, &tkIntXlibStubs }; -TkStubs tkStubs = { +const TkStubs tkStubs = { TCL_STUB_MAGIC, &tkStubHooks, Tk_MainLoop, /* 0 */ @@ -1102,8 +1075,8 @@ TkStubs tkStubs = { Tk_InitConsoleChannels, /* 215 */ Tk_CreateConsoleWindow, /* 216 */ Tk_CreateSmoothMethod, /* 217 */ - NULL, /* 218 */ - NULL, /* 219 */ + 0, /* 218 */ + 0, /* 219 */ Tk_GetDash, /* 220 */ Tk_CreateOutline, /* 221 */ Tk_DeleteOutline, /* 222 */ @@ -1158,11 +1131,6 @@ TkStubs tkStubs = { Tk_Interp, /* 271 */ Tk_CreateOldImageType, /* 272 */ Tk_CreateOldPhotoImageFormat, /* 273 */ - NULL, /* 274 */ - TkUnusedStubEntry, /* 275 */ }; /* !END!: Do not edit above this line. */ - -#undef UNIX_TK -#undef MAC_OSX_TK diff --git a/generic/tkStubLib.c b/generic/tkStubLib.c index f605b5d..ea48894 100644 --- a/generic/tkStubLib.c +++ b/generic/tkStubLib.c @@ -13,7 +13,7 @@ #include "tkInt.h" -#ifdef __WIN32__ +#ifdef _WIN32 #include "tkWinInt.h" #endif @@ -21,7 +21,7 @@ #include "tkMacOSXInt.h" #endif -#if !(defined(__WIN32__) || defined(MAC_OSX_TK)) +#if !(defined(_WIN32) || defined(MAC_OSX_TK)) #include "tkUnixInt.h" #endif @@ -29,11 +29,17 @@ #include "tkPlatDecls.h" #include "tkIntXlibDecls.h" -TkStubs *tkStubsPtr = NULL; -TkPlatStubs *tkPlatStubsPtr = NULL; -TkIntStubs *tkIntStubsPtr = NULL; -TkIntPlatStubs *tkIntPlatStubsPtr = NULL; -TkIntXlibStubs *tkIntXlibStubsPtr = NULL; +MODULE_SCOPE const TkStubs *tkStubsPtr; +MODULE_SCOPE const TkPlatStubs *tkPlatStubsPtr; +MODULE_SCOPE const TkIntStubs *tkIntStubsPtr; +MODULE_SCOPE const TkIntPlatStubs *tkIntPlatStubsPtr; +MODULE_SCOPE const TkIntXlibStubs *tkIntXlibStubsPtr; + +const TkStubs *tkStubsPtr = NULL; +const TkPlatStubs *tkPlatStubsPtr = NULL; +const TkIntStubs *tkIntStubsPtr = NULL; +const TkIntPlatStubs *tkIntPlatStubsPtr = NULL; +const TkIntXlibStubs *tkIntXlibStubsPtr = NULL; /* * Use our own isdigit to avoid linking to libc on windows @@ -63,32 +69,32 @@ isDigit(const int c) *---------------------------------------------------------------------- */ #undef Tk_InitStubs -CONST char * +MODULE_SCOPE const char * Tk_InitStubs( Tcl_Interp *interp, - CONST char *version, + const char *version, int exact) { const char *packageName = "Tk"; const char *errMsg = NULL; ClientData clientData = NULL; - CONST char *actualVersion = tclStubsPtr->tcl_PkgRequireEx(interp, + const char *actualVersion = tclStubsPtr->tcl_PkgRequireEx(interp, packageName, version, 0, &clientData); - TkStubs *stubsPtr = (TkStubs *)clientData; + const TkStubs *stubsPtr = clientData; if (actualVersion == NULL) { return NULL; } if (exact) { - CONST char *p = version; + const char *p = version; int count = 0; while (*p) { count += !isDigit(*p++); } if (count == 1) { - CONST char *q = actualVersion; + const char *q = actualVersion; p = version; while (*p && (*p == *q)) { @@ -96,11 +102,11 @@ Tk_InitStubs( } if (*p || isDigit(*q)) { /* Construct error message */ - tclStubsPtr->tcl_PkgRequireEx(interp, "Tk", version, 1, NULL); + tclStubsPtr->tcl_PkgRequireEx(interp, packageName, version, 1, NULL); return NULL; } } else { - actualVersion = tclStubsPtr->tcl_PkgRequireEx(interp, "Tk", + actualVersion = tclStubsPtr->tcl_PkgRequireEx(interp, packageName, version, 1, NULL); if (actualVersion == NULL) { return NULL; diff --git a/generic/tkStyle.c b/generic/tkStyle.c index c2eed8f..e7401df 100644 --- a/generic/tkStyle.c +++ b/generic/tkStyle.c @@ -146,11 +146,11 @@ static int SetStyleFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); /* * The following structure defines the implementation of the "style" Tcl - * object, used for drawing. The internalRep.twoPtrValue.ptr1 field of each style - * object points to the Style structure for the stylefont, or NULL. + * object, used for drawing. The internalRep.twoPtrValue.ptr1 field of each + * style object points to the Style structure for the stylefont, or NULL. */ -static Tcl_ObjType styleObjType = { +static const Tcl_ObjType styleObjType = { "style", /* name */ FreeStyleObjProc, /* freeIntRepProc */ DupStyleObjProc, /* dupIntRepProc */ @@ -180,7 +180,7 @@ void TkStylePkgInit( TkMainInfo *mainPtr) /* The application being created. */ { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (tsdPtr->nbInit != 0) { @@ -208,8 +208,7 @@ TkStylePkgInit( * Create the default system style. */ - Tk_CreateStyle(NULL, (Tk_StyleEngine) tsdPtr->defaultEnginePtr, - (ClientData) 0); + Tk_CreateStyle(NULL, (Tk_StyleEngine) tsdPtr->defaultEnginePtr, NULL); tsdPtr->nbInit++; } @@ -236,7 +235,7 @@ void TkStylePkgFree( TkMainInfo *mainPtr) /* The application being deleted. */ { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); Tcl_HashSearch search; Tcl_HashEntry *entryPtr; @@ -254,7 +253,7 @@ TkStylePkgFree( entryPtr = Tcl_FirstHashEntry(&tsdPtr->styleTable, &search); while (entryPtr != NULL) { - ckfree((char *) Tcl_GetHashValue(entryPtr)); + ckfree(Tcl_GetHashValue(entryPtr)); entryPtr = Tcl_NextHashEntry(&search); } Tcl_DeleteHashTable(&tsdPtr->styleTable); @@ -265,9 +264,9 @@ TkStylePkgFree( entryPtr = Tcl_FirstHashEntry(&tsdPtr->engineTable, &search); while (entryPtr != NULL) { - enginePtr = (StyleEngine *) Tcl_GetHashValue(entryPtr); + enginePtr = Tcl_GetHashValue(entryPtr); FreeStyleEngine(enginePtr); - ckfree((char *) enginePtr); + ckfree(enginePtr); entryPtr = Tcl_NextHashEntry(&search); } Tcl_DeleteHashTable(&tsdPtr->engineTable); @@ -280,7 +279,7 @@ TkStylePkgFree( FreeElement(tsdPtr->elements+i); } Tcl_DeleteHashTable(&tsdPtr->elementTable); - ckfree((char *) tsdPtr->elements); + ckfree(tsdPtr->elements); } /* @@ -308,7 +307,7 @@ Tk_RegisterStyleEngine( Tk_StyleEngine parent) /* The engine's parent. NULL means the default * system engine. */ { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); Tcl_HashEntry *entryPtr; int newEntry; @@ -332,10 +331,10 @@ Tk_RegisterStyleEngine( * Allocate and intitialize a new engine. */ - enginePtr = (StyleEngine *) ckalloc(sizeof(StyleEngine)); + enginePtr = ckalloc(sizeof(StyleEngine)); InitStyleEngine(enginePtr, Tcl_GetHashKey(&tsdPtr->engineTable, entryPtr), (StyleEngine *) parent); - Tcl_SetHashValue(entryPtr, (ClientData) enginePtr); + Tcl_SetHashValue(entryPtr, enginePtr); return (Tk_StyleEngine) enginePtr; } @@ -365,7 +364,7 @@ InitStyleEngine( StyleEngine *parentPtr) /* The engine's parent. NULL means the default * system engine. */ { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); int elementId; @@ -390,7 +389,7 @@ InitStyleEngine( */ if (tsdPtr->nbElements > 0) { - enginePtr->elements = (StyledElement *) ckalloc( + enginePtr->elements = ckalloc( sizeof(StyledElement) * tsdPtr->nbElements); for (elementId = 0; elementId < tsdPtr->nbElements; elementId++) { InitStyledElement(enginePtr->elements+elementId); @@ -420,7 +419,7 @@ static void FreeStyleEngine( StyleEngine *enginePtr) /* The style engine to free. */ { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); int elementId; @@ -431,7 +430,7 @@ FreeStyleEngine( for (elementId = 0; elementId < tsdPtr->nbElements; elementId++) { FreeStyledElement(enginePtr->elements+elementId); } - ckfree((char *) enginePtr->elements); + ckfree(enginePtr->elements); } /* @@ -455,7 +454,7 @@ Tk_GetStyleEngine( const char *name) /* Name of the engine to retrieve. NULL or * empty means the default system engine. */ { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); Tcl_HashEntry *entryPtr; @@ -468,7 +467,7 @@ Tk_GetStyleEngine( return NULL; } - return (Tk_StyleEngine) Tcl_GetHashValue(entryPtr); + return Tcl_GetHashValue(entryPtr); } /* @@ -579,7 +578,7 @@ FreeStyledElement( for (i = 0; i < elementPtr->nbWidgetSpecs; i++) { FreeWidgetSpec(elementPtr->widgetSpecs+i); } - ckfree((char *) elementPtr->widgetSpecs); + ckfree(elementPtr->widgetSpecs); } /* @@ -605,7 +604,7 @@ CreateElement( * created explicitly (being registered) or * implicitly (by a derived element). */ { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); Tcl_HashEntry *entryPtr, *engineEntryPtr; Tcl_HashSearch search; @@ -637,13 +636,13 @@ CreateElement( } elementId = tsdPtr->nbElements++; - Tcl_SetHashValue(entryPtr, (ClientData) INT2PTR(elementId)); + Tcl_SetHashValue(entryPtr, INT2PTR(elementId)); /* * Reallocate element table. */ - tsdPtr->elements = (Element *) ckrealloc((char *) tsdPtr->elements, + tsdPtr->elements = ckrealloc(tsdPtr->elements, sizeof(Element) * tsdPtr->nbElements); InitElement(tsdPtr->elements+elementId, Tcl_GetHashKey(&tsdPtr->elementTable, entryPtr), elementId, @@ -655,10 +654,9 @@ CreateElement( engineEntryPtr = Tcl_FirstHashEntry(&tsdPtr->engineTable, &search); while (engineEntryPtr != NULL) { - enginePtr = (StyleEngine *) Tcl_GetHashValue(engineEntryPtr); + enginePtr = Tcl_GetHashValue(engineEntryPtr); - enginePtr->elements = (StyledElement *) ckrealloc( - (char *) enginePtr->elements, + enginePtr->elements = ckrealloc(enginePtr->elements, sizeof(StyledElement) * tsdPtr->nbElements); InitStyledElement(enginePtr->elements+elementId); @@ -688,7 +686,7 @@ int Tk_GetElementId( const char *name) /* Name of the element. */ { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); Tcl_HashEntry *entryPtr; int genericId = -1; @@ -788,7 +786,7 @@ Tk_RegisterStyledElement( elementPtr = ((StyleEngine *) engine)->elements+elementId; - specPtr = (Tk_ElementSpec *) ckalloc(sizeof(Tk_ElementSpec)); + specPtr = ckalloc(sizeof(Tk_ElementSpec)); specPtr->version = templatePtr->version; specPtr->name = ckalloc(strlen(templatePtr->name)+1); strcpy(specPtr->name, templatePtr->name); @@ -797,7 +795,7 @@ Tk_RegisterStyledElement( srcOptions->name != NULL; nbOptions++, srcOptions++) { /* empty body */ } - specPtr->options = (Tk_ElementOptionSpec *) + specPtr->options = ckalloc(sizeof(Tk_ElementOptionSpec) * (nbOptions+1)); for (srcOptions = templatePtr->options, dstOptions = specPtr->options; /* End condition within loop */; srcOptions++, dstOptions++) { @@ -846,7 +844,7 @@ GetStyledElement( int elementId) /* Unique element ID */ { StyledElement *elementPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); StyleEngine *enginePtr2; @@ -925,7 +923,7 @@ InitWidgetSpec( * Build the widget option list. */ - widgetSpecPtr->optionsPtr = (const Tk_OptionSpec **) + widgetSpecPtr->optionsPtr = ckalloc(sizeof(Tk_OptionSpec *) * nbOptions); for (i = 0, elementOptionPtr = elementPtr->specPtr->options; i < nbOptions; i++, elementOptionPtr++) { @@ -966,7 +964,7 @@ FreeWidgetSpec( StyledWidgetSpec *widgetSpecPtr) /* The widget spec to free. */ { - ckfree((char *) widgetSpecPtr->optionsPtr); + ckfree(widgetSpecPtr->optionsPtr); } /* @@ -1010,8 +1008,7 @@ GetWidgetSpec( */ i = elementPtr->nbWidgetSpecs++; - elementPtr->widgetSpecs = (StyledWidgetSpec *) ckrealloc( - (char *) elementPtr->widgetSpecs, + elementPtr->widgetSpecs = ckrealloc(elementPtr->widgetSpecs, sizeof(StyledWidgetSpec) * elementPtr->nbWidgetSpecs); widgetSpecPtr = elementPtr->widgetSpecs+i; InitWidgetSpec(widgetSpecPtr, elementPtr, optionTable); @@ -1232,7 +1229,7 @@ Tk_CreateStyle( Tk_StyleEngine engine, /* The style engine. */ ClientData clientData) /* Private data passed as is to engine code. */ { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); Tcl_HashEntry *entryPtr; int newEntry; @@ -1256,11 +1253,11 @@ Tk_CreateStyle( * Allocate and intitialize a new style. */ - stylePtr = (Style *) ckalloc(sizeof(Style)); + stylePtr = ckalloc(sizeof(Style)); InitStyle(stylePtr, Tcl_GetHashKey(&tsdPtr->styleTable, entryPtr), - (engine!=NULL ? (StyleEngine *) engine : tsdPtr->defaultEnginePtr), + (engine!=NULL ? (StyleEngine*) engine : tsdPtr->defaultEnginePtr), clientData); - Tcl_SetHashValue(entryPtr, (ClientData) stylePtr); + Tcl_SetHashValue(entryPtr, stylePtr); return (Tk_Style) stylePtr; } @@ -1347,7 +1344,7 @@ Tk_GetStyle( const char *name) /* Name of the style to retrieve. NULL or empty * means the default system style. */ { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); Tcl_HashEntry *entryPtr; Style *stylePtr; @@ -1359,12 +1356,13 @@ Tk_GetStyle( entryPtr = Tcl_FindHashEntry(&tsdPtr->styleTable, (name!=NULL?name:"")); if (entryPtr == NULL) { if (interp != NULL) { - Tcl_AppendResult(interp, "style \"", name, "\" doesn't exist", - NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "style \"%s\" doesn't exist", name)); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "STYLE", name, NULL); } return (Tk_Style) NULL; } - stylePtr = (Style *) Tcl_GetHashValue(entryPtr); + stylePtr = Tcl_GetHashValue(entryPtr); return (Tk_Style) stylePtr; } @@ -1412,7 +1410,7 @@ Tk_AllocStyleFromObj( if (objPtr->typePtr != &styleObjType) { SetStyleFromAny(interp, objPtr); } - stylePtr = (Style *) objPtr->internalRep.twoPtrValue.ptr1; + stylePtr = objPtr->internalRep.twoPtrValue.ptr1; return (Tk_Style) stylePtr; } @@ -1444,7 +1442,7 @@ Tk_GetStyleFromObj( SetStyleFromAny(NULL, objPtr); } - return (Tk_Style) objPtr->internalRep.twoPtrValue.ptr1; + return objPtr->internalRep.twoPtrValue.ptr1; } /* @@ -1495,11 +1493,11 @@ SetStyleFromAny( name = Tcl_GetString(objPtr); typePtr = objPtr->typePtr; if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) { - (*typePtr->freeIntRepProc)(objPtr); + typePtr->freeIntRepProc(objPtr); } objPtr->typePtr = &styleObjType; - objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) Tk_GetStyle(interp, name); + objPtr->internalRep.twoPtrValue.ptr1 = Tk_GetStyle(interp, name); return TCL_OK; } diff --git a/generic/tkTest.c b/generic/tkTest.c index d06769d..44fec0d 100644 --- a/generic/tkTest.c +++ b/generic/tkTest.c @@ -14,16 +14,26 @@ * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ +#undef STATIC_BUILD +#ifndef USE_TCL_STUBS +# define USE_TCL_STUBS +#endif +#ifndef USE_TK_STUBS +# define USE_TK_STUBS +#endif #include "tkInt.h" #include "tkText.h" -#ifdef __WIN32__ +#ifdef _WIN32 #include "tkWinInt.h" #endif #if defined(MAC_OSX_TK) #include "tkMacOSXInt.h" #include "tkScrollbar.h" +#define LOG_DISPLAY TkTestLogDisplay() +#else +#define LOG_DISPLAY 1 #endif #ifdef __UNIX__ @@ -31,6 +41,15 @@ #endif /* + * TCL_STORAGE_CLASS is set unconditionally to DLLEXPORT because the + * Tcltest_Init declaration is in the source file itself, which is only + * accessed when we are building a library. + */ + +#undef TCL_STORAGE_CLASS +#define TCL_STORAGE_CLASS DLLEXPORT +EXTERN int Tktest_Init(Tcl_Interp *interp); +/* * The following data structure represents the master for a test image: */ @@ -59,8 +78,8 @@ typedef struct TImageInstance { */ static int ImageCreate(Tcl_Interp *interp, - char *name, int argc, Tcl_Obj *const objv[], - Tk_ImageType *typePtr, Tk_ImageMaster master, + const char *name, int argc, Tcl_Obj *const objv[], + const Tk_ImageType *typePtr, Tk_ImageMaster master, ClientData *clientDataPtr); static ClientData ImageGet(Tk_Window tkwin, ClientData clientData); static void ImageDisplay(ClientData clientData, @@ -79,7 +98,8 @@ static Tk_ImageType imageType = { ImageFree, /* freeProc */ ImageDelete, /* deleteProc */ NULL, /* postscriptPtr */ - NULL /* nextPtr */ + NULL, /* nextPtr */ + NULL }; /* @@ -96,25 +116,11 @@ typedef struct NewApp { static NewApp *newAppPtr = NULL;/* First in list of all new interpreters. */ /* - * Declaration for the square widget's class command function: - */ - -extern int SquareObjCmd(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj * const objv[]); - -typedef struct CBinding { - Tcl_Interp *interp; - char *command; - char *delete; -} CBinding; - -/* * Header for trivial configuration command items. */ -#define ODD TK_CONFIG_USER_BIT -#define EVEN (TK_CONFIG_USER_BIT << 1) +#define ODD TK_CONFIG_USER_BIT +#define EVEN (TK_CONFIG_USER_BIT << 1) enum { NONE, @@ -136,15 +142,9 @@ typedef struct TrivialCommandHeader { * Forward declarations for functions defined later in this file: */ -static int CBindingEvalProc(ClientData clientData, - Tcl_Interp *interp, XEvent *eventPtr, - Tk_Window tkwin, KeySym keySym); -static void CBindingFreeProc(ClientData clientData); -int Tktest_Init(Tcl_Interp *interp); -static int ImageCmd(ClientData dummy, - Tcl_Interp *interp, int argc, const char **argv); -static int TestcbindCmd(ClientData dummy, - Tcl_Interp *interp, int argc, const char **argv); +static int ImageObjCmd(ClientData dummy, + Tcl_Interp *interp, int objc, + Tcl_Obj * const objv[]); static int TestbitmapObjCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj * const objv[]); @@ -157,20 +157,24 @@ static int TestcolorObjCmd(ClientData dummy, static int TestcursorObjCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj * const objv[]); -static int TestdeleteappsCmd(ClientData dummy, - Tcl_Interp *interp, int argc, const char **argv); +static int TestdeleteappsObjCmd(ClientData dummy, + Tcl_Interp *interp, int objc, + Tcl_Obj * const objv[]); static int TestfontObjCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); -static int TestmakeexistCmd(ClientData dummy, - Tcl_Interp *interp, int argc, const char **argv); -#if !(defined(__WIN32__) || defined(MAC_OSX_TK) || defined(__CYGWIN__)) -static int TestmenubarCmd(ClientData dummy, - Tcl_Interp *interp, int argc, const char **argv); +static int TestmakeexistObjCmd(ClientData dummy, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +#if !(defined(_WIN32) || defined(MAC_OSX_TK) || defined(__CYGWIN__)) +static int TestmenubarObjCmd(ClientData dummy, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); #endif -#if defined(__WIN32__) || defined(MAC_OSX_TK) -static int TestmetricsCmd(ClientData dummy, - Tcl_Interp *interp, int argc, const char **argv); +#if defined(_WIN32) +static int TestmetricsObjCmd(ClientData dummy, + Tcl_Interp *interp, int objc, + Tcl_Obj * const objv[]); #endif static int TestobjconfigObjCmd(ClientData dummy, Tcl_Interp *interp, int objc, @@ -188,11 +192,13 @@ static void CustomOptionRestore(ClientData clientData, char *saveInternalPtr); static void CustomOptionFree(ClientData clientData, Tk_Window tkwin, char *internalPtr); -static int TestpropCmd(ClientData dummy, - Tcl_Interp *interp, int argc, const char **argv); -#if !(defined(__WIN32__) || defined(MAC_OSX_TK) || defined(__CYGWIN__)) -static int TestwrapperCmd(ClientData dummy, - Tcl_Interp *interp, int argc, const char **argv); +static int TestpropObjCmd(ClientData dummy, + Tcl_Interp *interp, int objc, + Tcl_Obj * const objv[]); +#if !(defined(_WIN32) || defined(MAC_OSX_TK) || defined(__CYGWIN__)) +static int TestwrapperObjCmd(ClientData dummy, + Tcl_Interp *interp, int objc, + Tcl_Obj * const objv[]); #endif static void TrivialCmdDeletedProc(ClientData clientData); static int TrivialConfigObjCmd(ClientData dummy, @@ -200,21 +206,6 @@ static int TrivialConfigObjCmd(ClientData dummy, Tcl_Obj * const objv[]); static void TrivialEventProc(ClientData clientData, XEvent *eventPtr); - -/* - * External (platform specific) initialization routine: - */ - -#if !(defined(__WIN32__) || defined(MAC_OSX_TK)) -#define TkplatformtestInit(x) TCL_OK -#else -MODULE_SCOPE int TkplatformtestInit(Tcl_Interp *interp); -#endif - -/* - * External legacy testing initialization routine: - */ -MODULE_SCOPE int TkOldTestInit(Tcl_Interp *interp); /* *---------------------------------------------------------------------- @@ -239,18 +230,22 @@ Tktest_Init( { static int initialized = 0; + if (Tcl_InitStubs(interp, "8.1", 0) == NULL) { + return TCL_ERROR; + } + if (Tk_InitStubs(interp, TK_VERSION, 0) == NULL) { + return TCL_ERROR; + } + /* * Create additional commands for testing Tk. */ - if (Tcl_PkgProvide(interp, "Tktest", TK_VERSION) == TCL_ERROR) { + if (Tcl_PkgProvideEx(interp, "Tktest", TK_PATCH_LEVEL, NULL) == TCL_ERROR) { return TCL_ERROR; } - Tcl_CreateObjCommand(interp, "square", SquareObjCmd, - (ClientData) NULL, NULL); - Tcl_CreateCommand(interp, "testcbind", TestcbindCmd, - (ClientData) Tk_MainWindow(interp), NULL); + Tcl_CreateObjCommand(interp, "square", SquareObjCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testbitmap", TestbitmapObjCmd, (ClientData) Tk_MainWindow(interp), NULL); Tcl_CreateObjCommand(interp, "testborder", TestborderObjCmd, @@ -259,32 +254,32 @@ Tktest_Init( (ClientData) Tk_MainWindow(interp), NULL); Tcl_CreateObjCommand(interp, "testcursor", TestcursorObjCmd, (ClientData) Tk_MainWindow(interp), NULL); - Tcl_CreateCommand(interp, "testdeleteapps", TestdeleteappsCmd, + Tcl_CreateObjCommand(interp, "testdeleteapps", TestdeleteappsObjCmd, (ClientData) Tk_MainWindow(interp), NULL); - Tcl_CreateCommand(interp, "testembed", TkpTestembedCmd, + Tcl_CreateObjCommand(interp, "testembed", TkpTestembedCmd, (ClientData) Tk_MainWindow(interp), NULL); Tcl_CreateObjCommand(interp, "testobjconfig", TestobjconfigObjCmd, (ClientData) Tk_MainWindow(interp), NULL); Tcl_CreateObjCommand(interp, "testfont", TestfontObjCmd, (ClientData) Tk_MainWindow(interp), NULL); - Tcl_CreateCommand(interp, "testmakeexist", TestmakeexistCmd, + Tcl_CreateObjCommand(interp, "testmakeexist", TestmakeexistObjCmd, (ClientData) Tk_MainWindow(interp), NULL); - Tcl_CreateCommand(interp, "testprop", TestpropCmd, + Tcl_CreateObjCommand(interp, "testprop", TestpropObjCmd, (ClientData) Tk_MainWindow(interp), NULL); - Tcl_CreateCommand(interp, "testtext", TkpTesttextCmd, + Tcl_CreateObjCommand(interp, "testtext", TkpTesttextCmd, (ClientData) Tk_MainWindow(interp), NULL); -#if defined(__WIN32__) || defined(MAC_OSX_TK) - Tcl_CreateCommand(interp, "testmetrics", TestmetricsCmd, +#if defined(_WIN32) + Tcl_CreateObjCommand(interp, "testmetrics", TestmetricsObjCmd, (ClientData) Tk_MainWindow(interp), NULL); -#elif !defined(__CYGWIN__) - Tcl_CreateCommand(interp, "testmenubar", TestmenubarCmd, +#elif !defined(__CYGWIN__) && !defined(MAC_OSX_TK) + Tcl_CreateObjCommand(interp, "testmenubar", TestmenubarObjCmd, (ClientData) Tk_MainWindow(interp), NULL); - Tcl_CreateCommand(interp, "testsend", TkpTestsendCmd, + Tcl_CreateObjCommand(interp, "testsend", TkpTestsendCmd, (ClientData) Tk_MainWindow(interp), NULL); - Tcl_CreateCommand(interp, "testwrapper", TestwrapperCmd, + Tcl_CreateObjCommand(interp, "testwrapper", TestwrapperObjCmd, (ClientData) Tk_MainWindow(interp), NULL); -#endif /* __WIN32__ || MAC_OSX_TK */ +#endif /* _WIN32 */ /* * Create test image type. @@ -313,113 +308,6 @@ Tktest_Init( /* *---------------------------------------------------------------------- * - * TestcbindCmd -- - * - * This function implements the "testcbinding" command. It provides a set - * of functions for testing C bindings in tkBind.c. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * Depends on option; see below. - * - *---------------------------------------------------------------------- - */ - -static int -TestcbindCmd( - ClientData clientData, /* Main window for application. */ - Tcl_Interp *interp, /* Current interpreter. */ - int argc, /* Number of arguments. */ - const char **argv) /* Argument strings. */ -{ - TkWindow *winPtr; - Tk_Window tkwin; - ClientData object; - CBinding *cbindPtr; - - - if (argc < 4 || argc > 5) { - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " bindtag pattern command ?deletecommand?", NULL); - return TCL_ERROR; - } - - tkwin = (Tk_Window) clientData; - - if (argv[1][0] == '.') { - winPtr = (TkWindow *) Tk_NameToWindow(interp, argv[1], tkwin); - if (winPtr == NULL) { - return TCL_ERROR; - } - object = (ClientData) winPtr->pathName; - } else { - winPtr = (TkWindow *) clientData; - object = (ClientData) Tk_GetUid(argv[1]); - } - - if (argv[3][0] == '\0') { - return Tk_DeleteBinding(interp, winPtr->mainPtr->bindingTable, - object, argv[2]); - } - - cbindPtr = (CBinding *) ckalloc(sizeof(CBinding)); - cbindPtr->interp = interp; - cbindPtr->command = - strcpy((char *) ckalloc(strlen(argv[3]) + 1), argv[3]); - if (argc == 4) { - cbindPtr->delete = NULL; - } else { - cbindPtr->delete = - strcpy((char *) ckalloc(strlen(argv[4]) + 1), argv[4]); - } - - if (TkCreateBindingProcedure(interp, winPtr->mainPtr->bindingTable, - object, argv[2], CBindingEvalProc, CBindingFreeProc, - (ClientData) cbindPtr) == 0) { - ckfree((char *) cbindPtr->command); - if (cbindPtr->delete != NULL) { - ckfree((char *) cbindPtr->delete); - } - ckfree((char *) cbindPtr); - return TCL_ERROR; - } - return TCL_OK; -} - -static int -CBindingEvalProc( - ClientData clientData, - Tcl_Interp *interp, - XEvent *eventPtr, - Tk_Window tkwin, - KeySym keySym) -{ - CBinding *cbindPtr; - - cbindPtr = (CBinding *) clientData; - - return Tcl_EvalEx(interp, cbindPtr->command, -1, TCL_EVAL_GLOBAL); -} - -static void -CBindingFreeProc( - ClientData clientData) -{ - CBinding *cbindPtr = (CBinding *) clientData; - - if (cbindPtr->delete != NULL) { - Tcl_EvalEx(cbindPtr->interp, cbindPtr->delete, -1, TCL_EVAL_GLOBAL); - ckfree((char *) cbindPtr->delete); - } - ckfree((char *) cbindPtr->command); - ckfree((char *) cbindPtr); -} - -/* - *---------------------------------------------------------------------- - * * TestbitmapObjCmd -- * * This function implements the "testbitmap" command, which is used to @@ -558,7 +446,7 @@ TestcursorObjCmd( /* *---------------------------------------------------------------------- * - * TestdeleteappsCmd -- + * TestdeleteappsObjCmd -- * * This function implements the "testdeleteapps" command. It cleans up * all the interpreters left behind by the "testnewapp" command. @@ -575,18 +463,18 @@ TestcursorObjCmd( /* ARGSUSED */ static int -TestdeleteappsCmd( +TestdeleteappsObjCmd( ClientData clientData, /* Main window for application. */ Tcl_Interp *interp, /* Current interpreter. */ - int argc, /* Number of arguments. */ - const char **argv) /* Argument strings. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument strings. */ { NewApp *nextPtr; while (newAppPtr != NULL) { nextPtr = newAppPtr->nextPtr; Tcl_DeleteInterp(newAppPtr->interp); - ckfree((char *) newAppPtr); + ckfree(newAppPtr); newAppPtr = nextPtr; } @@ -618,12 +506,12 @@ TestobjconfigObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - static const char *options[] = { - "alltypes", "chain1", "chain2", "configerror", "delete", "info", + static const char *const options[] = { + "alltypes", "chain1", "chain2", "chain3", "configerror", "delete", "info", "internal", "new", "notenoughparams", "twowindows", NULL }; enum { - ALL_TYPES, CHAIN1, CHAIN2, CONFIG_ERROR, + ALL_TYPES, CHAIN1, CHAIN2, CHAIN3, CONFIG_ERROR, DEL, /* Can't use DELETE: VC++ compiler barfs. */ INFO, INTERNAL, NEW, NOT_ENOUGH_PARAMS, TWO_WINDOWS }; @@ -637,7 +525,7 @@ TestobjconfigObjCmd( CustomOptionGet, CustomOptionRestore, CustomOptionFree, - (ClientData) 1 + INT2PTR(1) }; Tk_Window mainWin = (Tk_Window) clientData; Tk_Window tkwin; @@ -658,10 +546,10 @@ TestobjconfigObjCmd( } ExtensionWidgetRecord; static const Tk_OptionSpec baseSpecs[] = { {TK_OPTION_STRING, "-one", "one", "One", "one", - Tk_Offset(ExtensionWidgetRecord, base1ObjPtr), -1}, + Tk_Offset(ExtensionWidgetRecord, base1ObjPtr), -1, 0, NULL, 0}, {TK_OPTION_STRING, "-two", "two", "Two", "two", - Tk_Offset(ExtensionWidgetRecord, base2ObjPtr), -1}, - {TK_OPTION_END} + Tk_Offset(ExtensionWidgetRecord, base2ObjPtr), -1, 0, NULL, 0}, + {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0} }; if (objc < 2) { @@ -669,8 +557,8 @@ TestobjconfigObjCmd( return TCL_ERROR; } - if (Tcl_GetIndexFromObj(interp, objv[1], options, "command", 0, &index) - != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[1], options, + sizeof(char *), "command", 0, &index)!= TCL_OK) { return TCL_ERROR; } @@ -697,7 +585,7 @@ TestobjconfigObjCmd( Tcl_Obj *customPtr; } TypesRecord; TypesRecord *recordPtr; - static const char *stringTable[] = { + static const char *const stringTable[] = { "one", "two", "three", "four", NULL }; static const Tk_OptionSpec typesSpecs[] = { @@ -713,10 +601,10 @@ TestobjconfigObjCmd( {TK_OPTION_STRING_TABLE, "-stringtable", "StringTable", "stringTable", "one", Tk_Offset(TypesRecord, stringTablePtr), -1, - TK_CONFIG_NULL_OK, (ClientData) stringTable, 0x10}, + TK_CONFIG_NULL_OK, stringTable, 0x10}, {TK_OPTION_COLOR, "-color", "color", "Color", "red", Tk_Offset(TypesRecord, colorPtr), -1, - TK_CONFIG_NULL_OK, (ClientData) "black", 0x20}, + TK_CONFIG_NULL_OK, "black", 0x20}, {TK_OPTION_FONT, "-font", "font", "Font", "Helvetica 12", Tk_Offset(TypesRecord, fontPtr), -1, TK_CONFIG_NULL_OK, 0, 0x40}, @@ -725,7 +613,7 @@ TestobjconfigObjCmd( TK_CONFIG_NULL_OK, 0, 0x80}, {TK_OPTION_BORDER, "-border", "border", "Border", "blue", Tk_Offset(TypesRecord, borderPtr), -1, - TK_CONFIG_NULL_OK, (ClientData) "white", 0x100}, + TK_CONFIG_NULL_OK, "white", 0x100}, {TK_OPTION_RELIEF, "-relief", "relief", "Relief", "raised", Tk_Offset(TypesRecord, reliefPtr), -1, TK_CONFIG_NULL_OK, 0, 0x200}, @@ -743,10 +631,10 @@ TestobjconfigObjCmd( TK_CONFIG_NULL_OK, 0, 0x2000}, {TK_OPTION_CUSTOM, "-custom", NULL, NULL, "", Tk_Offset(TypesRecord, customPtr), -1, - TK_CONFIG_NULL_OK, (ClientData)&CustomOption, 0x4000}, + TK_CONFIG_NULL_OK, &CustomOption, 0x4000}, {TK_OPTION_SYNONYM, "-synonym", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-color", 0x8000}, - {TK_OPTION_END} + NULL, 0, -1, 0, "-color", 0x8000}, + {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0} }; Tk_OptionTable optionTable; Tk_Window tkwin; @@ -760,7 +648,7 @@ TestobjconfigObjCmd( } Tk_SetClass(tkwin, "Test"); - recordPtr = (TypesRecord *) ckalloc(sizeof(TypesRecord)); + recordPtr = ckalloc(sizeof(TypesRecord)); recordPtr->header.interp = interp; recordPtr->header.optionTable = optionTable; recordPtr->header.tkwin = tkwin; @@ -795,7 +683,7 @@ TestobjconfigObjCmd( } } else { Tk_DestroyWindow(tkwin); - ckfree((char *) recordPtr); + ckfree(recordPtr); } if (result == TCL_OK) { Tcl_SetObjResult(interp, objv[2]); @@ -817,8 +705,7 @@ TestobjconfigObjCmd( optionTable = Tk_CreateOptionTable(interp, baseSpecs); tables[index] = optionTable; - recordPtr = (ExtensionWidgetRecord *) - ckalloc(sizeof(ExtensionWidgetRecord)); + recordPtr = ckalloc(sizeof(ExtensionWidgetRecord)); recordPtr->header.interp = interp; recordPtr->header.optionTable = optionTable; recordPtr->header.tkwin = tkwin; @@ -843,20 +730,21 @@ TestobjconfigObjCmd( break; } - case CHAIN2: { + case CHAIN2: + case CHAIN3: { ExtensionWidgetRecord *recordPtr; static const Tk_OptionSpec extensionSpecs[] = { {TK_OPTION_STRING, "-three", "three", "Three", "three", - Tk_Offset(ExtensionWidgetRecord, extension3ObjPtr), -1}, + Tk_Offset(ExtensionWidgetRecord, extension3ObjPtr), -1, 0, NULL, 0}, {TK_OPTION_STRING, "-four", "four", "Four", "four", - Tk_Offset(ExtensionWidgetRecord, extension4ObjPtr), -1}, + Tk_Offset(ExtensionWidgetRecord, extension4ObjPtr), -1, 0, NULL, 0}, {TK_OPTION_STRING, "-two", "two", "Two", "two and a half", - Tk_Offset(ExtensionWidgetRecord, base2ObjPtr), -1}, + Tk_Offset(ExtensionWidgetRecord, base2ObjPtr), -1, 0, NULL, 0}, {TK_OPTION_STRING, "-oneAgain", "oneAgain", "OneAgain", "one again", - Tk_Offset(ExtensionWidgetRecord, extension5ObjPtr), -1}, + Tk_Offset(ExtensionWidgetRecord, extension5ObjPtr), -1, 0, NULL, 0}, {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, - (ClientData) baseSpecs} + (ClientData) baseSpecs, 0} }; Tk_Window tkwin; Tk_OptionTable optionTable; @@ -870,8 +758,7 @@ TestobjconfigObjCmd( optionTable = Tk_CreateOptionTable(interp, extensionSpecs); tables[index] = optionTable; - recordPtr = (ExtensionWidgetRecord *) ckalloc( - sizeof(ExtensionWidgetRecord)); + recordPtr = ckalloc(sizeof(ExtensionWidgetRecord)); recordPtr->header.interp = interp; recordPtr->header.optionTable = optionTable; recordPtr->header.tkwin = tkwin; @@ -904,8 +791,8 @@ TestobjconfigObjCmd( ErrorWidgetRecord widgetRecord; static const Tk_OptionSpec errorSpecs[] = { {TK_OPTION_INT, "-int", "integer", "Integer", "bogus", - Tk_Offset(ErrorWidgetRecord, intPtr)}, - {TK_OPTION_END} + Tk_Offset(ErrorWidgetRecord, intPtr), 0, 0, NULL, 0}, + {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0} }; Tk_OptionTable optionTable; @@ -921,12 +808,15 @@ TestobjconfigObjCmd( Tcl_WrongNumArgs(interp, 2, objv, "tableName"); return TCL_ERROR; } - if (Tcl_GetIndexFromObj(interp, objv[2], options, "table", 0, - &index) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[2], options, + sizeof(char *), "table", 0, &index) != TCL_OK) { return TCL_ERROR; } if (tables[index] != NULL) { Tk_DeleteOptionTable(tables[index]); + /* Make sure that Tk_DeleteOptionTable() is never done + * twice for the same table. */ + tables[index] = NULL; } break; @@ -935,8 +825,8 @@ TestobjconfigObjCmd( Tcl_WrongNumArgs(interp, 2, objv, "tableName"); return TCL_ERROR; } - if (Tcl_GetIndexFromObj(interp, objv[2], options, "table", 0, - &index) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[2], options, + sizeof(char *), "table", 0, &index) != TCL_OK) { return TCL_ERROR; } Tcl_SetObjResult(interp, TkDebugConfig(interp, tables[index])); @@ -986,10 +876,10 @@ TestobjconfigObjCmd( {TK_OPTION_STRING_TABLE, "-stringtable", "StringTable", "stringTable", "one", -1, Tk_Offset(InternalRecord, index), - TK_CONFIG_NULL_OK, (ClientData) internalStringTable, 0x10}, + TK_CONFIG_NULL_OK, internalStringTable, 0x10}, {TK_OPTION_COLOR, "-color", "color", "Color", "red", -1, Tk_Offset(InternalRecord, colorPtr), - TK_CONFIG_NULL_OK, (ClientData) "black", 0x20}, + TK_CONFIG_NULL_OK, "black", 0x20}, {TK_OPTION_FONT, "-font", "font", "Font", "Helvetica 12", -1, Tk_Offset(InternalRecord, tkfont), TK_CONFIG_NULL_OK, 0, 0x40}, @@ -998,7 +888,7 @@ TestobjconfigObjCmd( TK_CONFIG_NULL_OK, 0, 0x80}, {TK_OPTION_BORDER, "-border", "border", "Border", "blue", -1, Tk_Offset(InternalRecord, border), - TK_CONFIG_NULL_OK, (ClientData) "white", 0x100}, + TK_CONFIG_NULL_OK, "white", 0x100}, {TK_OPTION_RELIEF, "-relief", "relief", "Relief", "raised", -1, Tk_Offset(InternalRecord, relief), TK_CONFIG_NULL_OK, 0, 0x200}, @@ -1019,10 +909,10 @@ TestobjconfigObjCmd( TK_CONFIG_NULL_OK, 0, 0}, {TK_OPTION_CUSTOM, "-custom", NULL, NULL, "", -1, Tk_Offset(InternalRecord, custom), - TK_CONFIG_NULL_OK, (ClientData)&CustomOption, 0x4000}, + TK_CONFIG_NULL_OK, &CustomOption, 0x4000}, {TK_OPTION_SYNONYM, "-synonym", NULL, NULL, - NULL, -1, -1, 0, (ClientData) "-color", 0x8000}, - {TK_OPTION_END} + NULL, -1, -1, 0, "-color", 0x8000}, + {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0} }; Tk_OptionTable optionTable; Tk_Window tkwin; @@ -1036,7 +926,7 @@ TestobjconfigObjCmd( } Tk_SetClass(tkwin, "Test"); - recordPtr = (InternalRecord *) ckalloc(sizeof(InternalRecord)); + recordPtr = ckalloc(sizeof(InternalRecord)); recordPtr->header.interp = interp; recordPtr->header.optionTable = optionTable; recordPtr->header.tkwin = tkwin; @@ -1062,9 +952,9 @@ TestobjconfigObjCmd( if (result == TCL_OK) { recordPtr->header.widgetCmd = Tcl_CreateObjCommand(interp, Tcl_GetString(objv[2]), TrivialConfigObjCmd, - (ClientData) recordPtr, TrivialCmdDeletedProc); + recordPtr, TrivialCmdDeletedProc); Tk_CreateEventHandler(tkwin, StructureNotifyMask, - TrivialEventProc, (ClientData) recordPtr); + TrivialEventProc, recordPtr); result = Tk_SetOptions(interp, (char *) recordPtr, optionTable, objc - 3, objv + 3, tkwin, NULL, NULL); if (result != TCL_OK) { @@ -1072,7 +962,7 @@ TestobjconfigObjCmd( } } else { Tk_DestroyWindow(tkwin); - ckfree((char *) recordPtr); + ckfree(recordPtr); } if (result == TCL_OK) { Tcl_SetObjResult(interp, objv[2]); @@ -1092,24 +982,24 @@ TestobjconfigObjCmd( FiveRecord *recordPtr; static const Tk_OptionSpec smallSpecs[] = { {TK_OPTION_INT, "-one", "one", "One", "1", - Tk_Offset(FiveRecord, one), -1}, + Tk_Offset(FiveRecord, one), -1, 0, NULL, 0}, {TK_OPTION_INT, "-two", "two", "Two", "2", - Tk_Offset(FiveRecord, two), -1}, + Tk_Offset(FiveRecord, two), -1, 0, NULL, 0}, {TK_OPTION_INT, "-three", "three", "Three", "3", - Tk_Offset(FiveRecord, three), -1}, + Tk_Offset(FiveRecord, three), -1, 0, NULL, 0}, {TK_OPTION_INT, "-four", "four", "Four", "4", - Tk_Offset(FiveRecord, four), -1}, + Tk_Offset(FiveRecord, four), -1, 0, NULL, 0}, {TK_OPTION_STRING, "-five", NULL, NULL, NULL, - Tk_Offset(FiveRecord, five), -1}, - {TK_OPTION_END} + Tk_Offset(FiveRecord, five), -1, 0, NULL, 0}, + {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0} }; if (objc < 3) { - Tcl_WrongNumArgs(interp, 1, objv, "new name ?options?"); + Tcl_WrongNumArgs(interp, 1, objv, "new name ?-option value ...?"); return TCL_ERROR; } - recordPtr = (FiveRecord *) ckalloc(sizeof(FiveRecord)); + recordPtr = ckalloc(sizeof(FiveRecord)); recordPtr->header.interp = interp; recordPtr->header.optionTable = Tk_CreateOptionTable(interp, smallSpecs); @@ -1134,7 +1024,7 @@ TestobjconfigObjCmd( } } if (result != TCL_OK) { - ckfree((char *) recordPtr); + ckfree(recordPtr); } break; @@ -1146,8 +1036,8 @@ TestobjconfigObjCmd( NotEnoughRecord record; static const Tk_OptionSpec errorSpecs[] = { {TK_OPTION_INT, "-foo", "foo", "Foo", "0", - Tk_Offset(NotEnoughRecord, fooObjPtr)}, - {TK_OPTION_END} + Tk_Offset(NotEnoughRecord, fooObjPtr), 0, 0, NULL, 0}, + {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0} }; Tcl_Obj *newObjPtr = Tcl_NewStringObj("-foo", -1); Tk_OptionTable optionTable; @@ -1177,8 +1067,8 @@ TestobjconfigObjCmd( SlaveRecord *recordPtr; static const Tk_OptionSpec slaveSpecs[] = { {TK_OPTION_WINDOW, "-window", "window", "Window", ".bar", - Tk_Offset(SlaveRecord, windowPtr), -1, TK_CONFIG_NULL_OK}, - {TK_OPTION_END} + Tk_Offset(SlaveRecord, windowPtr), -1, TK_CONFIG_NULL_OK, NULL, 0}, + {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0} }; Tk_Window tkwin = Tk_CreateWindowFromPath(interp, (Tk_Window) clientData, Tcl_GetString(objv[2]), NULL); @@ -1188,7 +1078,7 @@ TestobjconfigObjCmd( } Tk_SetClass(tkwin, "Test"); - recordPtr = (SlaveRecord *) ckalloc(sizeof(SlaveRecord)); + recordPtr = ckalloc(sizeof(SlaveRecord)); recordPtr->header.interp = interp; recordPtr->header.optionTable = Tk_CreateOptionTable(interp, slaveSpecs); @@ -1205,9 +1095,9 @@ TestobjconfigObjCmd( if (result == TCL_OK) { recordPtr->header.widgetCmd = Tcl_CreateObjCommand(interp, Tcl_GetString(objv[2]), TrivialConfigObjCmd, - (ClientData) recordPtr, TrivialCmdDeletedProc); + recordPtr, TrivialCmdDeletedProc); Tk_CreateEventHandler(tkwin, StructureNotifyMask, - TrivialEventProc, (ClientData) recordPtr); + TrivialEventProc, recordPtr); Tcl_SetObjResult(interp, objv[2]); } else { Tk_FreeConfigOptions((char *) recordPtr, @@ -1216,7 +1106,7 @@ TestobjconfigObjCmd( } if (result != TCL_OK) { Tk_DestroyWindow(tkwin); - ckfree((char *) recordPtr); + ckfree(recordPtr); } } } @@ -1250,7 +1140,7 @@ TrivialConfigObjCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { int result = TCL_OK; - static const char *options[] = { + static const char *const options[] = { "cget", "configure", "csave", NULL }; enum { @@ -1267,8 +1157,8 @@ TrivialConfigObjCmd( return TCL_ERROR; } - if (Tcl_GetIndexFromObj(interp, objv[1], options, "command", 0, - &index) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[1], options, + sizeof(char *), "command", 0, &index) != TCL_OK) { return TCL_ERROR; } @@ -1312,7 +1202,7 @@ TrivialConfigObjCmd( headerPtr->optionTable, objc - 2, objv + 2, tkwin, NULL, &mask); if (result == TCL_OK) { - Tcl_SetIntObj(Tcl_GetObjResult(interp), mask); + Tcl_SetObjResult(interp, Tcl_NewIntObj(mask)); } } break; @@ -1322,7 +1212,7 @@ TrivialConfigObjCmd( tkwin, &saved, &mask); Tk_FreeSavedOptions(&saved); if (result == TCL_OK) { - Tcl_SetIntObj(Tcl_GetObjResult(interp), mask); + Tcl_SetObjResult(interp, Tcl_NewIntObj(mask)); } break; } @@ -1432,7 +1322,7 @@ TestfontObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - static const char *options[] = {"counts", "subfonts", NULL}; + static const char *const options[] = {"counts", "subfonts", NULL}; enum option {COUNTS, SUBFONTS}; int index; Tk_Window tkwin; @@ -1445,8 +1335,8 @@ TestfontObjCmd( return TCL_ERROR; } - if (Tcl_GetIndexFromObj(interp, objv[1], options, "command", 0, &index) - != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[1], options, + sizeof(char *), "command", 0, &index)!= TCL_OK) { return TCL_ERROR; } @@ -1489,18 +1379,18 @@ static int ImageCreate( Tcl_Interp *interp, /* Interpreter for application containing * image. */ - char *name, /* Name to use for image. */ + const char *name, /* Name to use for image. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[], /* Argument strings for options (doesn't * include image name or type). */ - Tk_ImageType *typePtr, /* Pointer to our type record (not used). */ + const Tk_ImageType *typePtr, /* Pointer to our type record (not used). */ Tk_ImageMaster master, /* Token for image, to be used by us in later * callbacks. */ ClientData *clientDataPtr) /* Store manager's token for image here; it * will be returned in later callbacks. */ { TImageMaster *timPtr; - char *varName; + const char *varName; int i; varName = "log"; @@ -1518,17 +1408,17 @@ ImageCreate( varName = Tcl_GetString(objv[i+1]); } - timPtr = (TImageMaster *) ckalloc(sizeof(TImageMaster)); + timPtr = ckalloc(sizeof(TImageMaster)); timPtr->master = master; timPtr->interp = interp; timPtr->width = 30; timPtr->height = 15; - timPtr->imageName = (char *) ckalloc((unsigned) (strlen(name) + 1)); + timPtr->imageName = ckalloc(strlen(name) + 1); strcpy(timPtr->imageName, name); - timPtr->varName = (char *) ckalloc((unsigned) (strlen(varName) + 1)); + timPtr->varName = ckalloc(strlen(varName) + 1); strcpy(timPtr->varName, varName); - Tcl_CreateCommand(interp, name, ImageCmd, (ClientData) timPtr, NULL); - *clientDataPtr = (ClientData) timPtr; + Tcl_CreateObjCommand(interp, name, ImageObjCmd, timPtr, NULL); + *clientDataPtr = timPtr; Tk_ImageChanged(master, 0, 0, 30, 15, 30, 15); return TCL_OK; } @@ -1536,7 +1426,7 @@ ImageCreate( /* *---------------------------------------------------------------------- * - * ImageCmd -- + * ImageObjCmd -- * * This function implements the commands corresponding to individual * images. @@ -1552,38 +1442,37 @@ ImageCreate( /* ARGSUSED */ static int -ImageCmd( +ImageObjCmd( ClientData clientData, /* Main window for application. */ Tcl_Interp *interp, /* Current interpreter. */ - int argc, /* Number of arguments. */ - const char **argv) /* Argument strings. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument strings. */ { TImageMaster *timPtr = (TImageMaster *) clientData; int x, y, width, height; - if (argc < 2) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], "option ?arg arg ...?", NULL); + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); return TCL_ERROR; } - if (strcmp(argv[1], "changed") == 0) { - if (argc != 8) { - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " changed x y width height imageWidth imageHeight", NULL); + if (strcmp(Tcl_GetString(objv[1]), "changed") == 0) { + if (objc != 8) { + Tcl_WrongNumArgs(interp, 1, objv, "changed x y width height" + " imageWidth imageHeight"); return TCL_ERROR; } - if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK) - || (Tcl_GetInt(interp, argv[3], &y) != TCL_OK) - || (Tcl_GetInt(interp, argv[4], &width) != TCL_OK) - || (Tcl_GetInt(interp, argv[5], &height) != TCL_OK) - || (Tcl_GetInt(interp, argv[6], &timPtr->width) != TCL_OK) - || (Tcl_GetInt(interp, argv[7], &timPtr->height) != TCL_OK)) { + if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK) + || (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK) + || (Tcl_GetIntFromObj(interp, objv[4], &width) != TCL_OK) + || (Tcl_GetIntFromObj(interp, objv[5], &height) != TCL_OK) + || (Tcl_GetIntFromObj(interp, objv[6], &timPtr->width) != TCL_OK) + || (Tcl_GetIntFromObj(interp, objv[7], &timPtr->height) != TCL_OK)) { return TCL_ERROR; } Tk_ImageChanged(timPtr->master, x, y, width, height, timPtr->width, timPtr->height); } else { - Tcl_AppendResult(interp, "bad option \"", argv[1], + Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[1]), "\": must be changed", NULL); return TCL_ERROR; } @@ -1620,15 +1509,15 @@ ImageGet( XGCValues gcValues; sprintf(buffer, "%s get", timPtr->imageName); - Tcl_SetVar(timPtr->interp, timPtr->varName, buffer, + Tcl_SetVar2(timPtr->interp, timPtr->varName, NULL, buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT); - instPtr = (TImageInstance *) ckalloc(sizeof(TImageInstance)); + instPtr = ckalloc(sizeof(TImageInstance)); instPtr->masterPtr = timPtr; instPtr->fg = Tk_GetColor(timPtr->interp, tkwin, "#ff0000"); gcValues.foreground = instPtr->fg->pixel; instPtr->gc = Tk_GetGC(tkwin, GCForeground, &gcValues); - return (ClientData) instPtr; + return instPtr; } /* @@ -1664,17 +1553,47 @@ ImageDisplay( TImageInstance *instPtr = (TImageInstance *) clientData; char buffer[200 + TCL_INTEGER_SPACE * 6]; - sprintf(buffer, "%s display %d %d %d %d %d %d", - instPtr->masterPtr->imageName, imageX, imageY, width, height, - drawableX, drawableY); - Tcl_SetVar(instPtr->masterPtr->interp, instPtr->masterPtr->varName, buffer, - TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT); + /* + * The purpose of the test image type is to track the calls to an image + * display proc and record the parameters passed in each call. On macOS + * a display proc must be run inside of the drawRect method of an NSView + * in order for the graphics operations to have any effect. To deal with + * this, whenever a display proc is called outside of any drawRect method + * it schedules a redraw of the NSView by calling [view setNeedsDisplay:YES]. + * This will trigger a later call to the view's drawRect method which will + * run the display proc a second time. + * + * This complicates testing, since it can result in more calls to the display + * proc than are expected by the test. It can also result in an inconsistent + * number of calls unless the test waits until the call to drawRect actually + * occurs before validating its results. + * + * In an attempt to work around this, this display proc only logs those + * calls which occur within a drawRect method. This means that tests must + * be written so as to ensure that the drawRect method is run before + * results are validated. In practice it usually suffices to run update + * idletasks (to run the display proc the first time) followed by update + * (to run the display proc in drawRect). + * + * This also has the consequence that the image changed command will log + * different results on Aqua than on other systems, because when the image + * is redisplayed in the drawRect method the entire image will be drawn, + * not just the changed portion. Tests must account for this. + */ + + if (LOG_DISPLAY) { + sprintf(buffer, "%s display %d %d %d %d", + instPtr->masterPtr->imageName, imageX, imageY, width, height); + Tcl_SetVar2(instPtr->masterPtr->interp, instPtr->masterPtr->varName, + NULL, buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT); + } if (width > (instPtr->masterPtr->width - imageX)) { width = instPtr->masterPtr->width - imageX; } if (height > (instPtr->masterPtr->height - imageY)) { height = instPtr->masterPtr->height - imageY; } + XDrawRectangle(display, drawable, instPtr->gc, drawableX, drawableY, (unsigned) (width-1), (unsigned) (height-1)); XDrawLine(display, drawable, instPtr->gc, drawableX, drawableY, @@ -1710,11 +1629,11 @@ ImageFree( char buffer[200]; sprintf(buffer, "%s free", instPtr->masterPtr->imageName); - Tcl_SetVar(instPtr->masterPtr->interp, instPtr->masterPtr->varName, buffer, - TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT); + Tcl_SetVar2(instPtr->masterPtr->interp, instPtr->masterPtr->varName, NULL, + buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT); Tk_FreeColor(instPtr->fg); Tk_FreeGC(display, instPtr->gc); - ckfree((char *) instPtr); + ckfree(instPtr); } /* @@ -1744,19 +1663,19 @@ ImageDelete( char buffer[100]; sprintf(buffer, "%s delete", timPtr->imageName); - Tcl_SetVar(timPtr->interp, timPtr->varName, buffer, + Tcl_SetVar2(timPtr->interp, timPtr->varName, NULL, buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT); Tcl_DeleteCommand(timPtr->interp, timPtr->imageName); ckfree(timPtr->imageName); ckfree(timPtr->varName); - ckfree((char *) timPtr); + ckfree(timPtr); } /* *---------------------------------------------------------------------- * - * TestmakeexistCmd -- + * TestmakeexistObjCmd -- * * This function implements the "testmakeexist" command. It calls * Tk_MakeWindowExist on each of its arguments to force the windows to be @@ -1773,18 +1692,18 @@ ImageDelete( /* ARGSUSED */ static int -TestmakeexistCmd( +TestmakeexistObjCmd( ClientData clientData, /* Main window for application. */ Tcl_Interp *interp, /* Current interpreter. */ - int argc, /* Number of arguments. */ - const char **argv) /* Argument strings. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument strings. */ { Tk_Window mainWin = (Tk_Window) clientData; int i; Tk_Window tkwin; - for (i = 1; i < argc; i++) { - tkwin = Tk_NameToWindow(interp, argv[i], mainWin); + for (i = 1; i < objc; i++) { + tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[i]), mainWin); if (tkwin == NULL) { return TCL_ERROR; } @@ -1797,7 +1716,7 @@ TestmakeexistCmd( /* *---------------------------------------------------------------------- * - * TestmenubarCmd -- + * TestmenubarObjCmd -- * * This function implements the "testmenubar" command. It is used to test * the Unix facilities for creating space above a toplevel window for a @@ -1813,53 +1732,50 @@ TestmakeexistCmd( */ /* ARGSUSED */ -#if !(defined(__WIN32__) || defined(MAC_OSX_TK) || defined(__CYGWIN__)) +#if !(defined(_WIN32) || defined(MAC_OSX_TK) || defined(__CYGWIN__)) static int -TestmenubarCmd( +TestmenubarObjCmd( ClientData clientData, /* Main window for application. */ Tcl_Interp *interp, /* Current interpreter. */ - int argc, /* Number of arguments. */ - const char **argv) /* Argument strings. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument strings. */ { #ifdef __UNIX__ Tk_Window mainWin = (Tk_Window) clientData; Tk_Window tkwin, menubar; - if (argc < 2) { - Tcl_AppendResult(interp, "wrong # args; must be \"", argv[0], - " option ?arg ...?\"", NULL); + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); return TCL_ERROR; } - if (strcmp(argv[1], "window") == 0) { - if (argc != 4) { - Tcl_AppendResult(interp, "wrong # args; must be \"", argv[0], - "window toplevel menubar\"", NULL); + if (strcmp(Tcl_GetString(objv[1]), "window") == 0) { + if (objc != 4) { + Tcl_WrongNumArgs(interp, 1, objv, "windows toplevel menubar"); return TCL_ERROR; } - tkwin = Tk_NameToWindow(interp, argv[2], mainWin); + tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), mainWin); if (tkwin == NULL) { return TCL_ERROR; } - if (argv[3][0] == 0) { + if (Tcl_GetString(objv[3])[0] == 0) { TkUnixSetMenubar(tkwin, NULL); } else { - menubar = Tk_NameToWindow(interp, argv[3], mainWin); + menubar = Tk_NameToWindow(interp, Tcl_GetString(objv[3]), mainWin); if (menubar == NULL) { return TCL_ERROR; } TkUnixSetMenubar(tkwin, menubar); } } else { - Tcl_AppendResult(interp, "bad option \"", argv[1], + Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[1]), "\": must be window", NULL); return TCL_ERROR; } return TCL_OK; #else - Tcl_SetResult(interp, "testmenubar is supported only under Unix", - TCL_STATIC); + Tcl_AppendResult(interp, "testmenubar is supported only under Unix", NULL); return TCL_ERROR; #endif } @@ -1868,7 +1784,7 @@ TestmenubarCmd( /* *---------------------------------------------------------------------- * - * TestmetricsCmd -- + * TestmetricsObjCmd -- * * This function implements the testmetrics command. It provides a way to * determine the size of various widget components. @@ -1882,53 +1798,28 @@ TestmenubarCmd( *---------------------------------------------------------------------- */ -#if defined(__WIN32__) || defined(MAC_OSX_TK) +#if defined(_WIN32) static int -TestmetricsCmd( +TestmetricsObjCmd( ClientData clientData, /* Main window for application. */ Tcl_Interp *interp, /* Current interpreter. */ - int argc, /* Number of arguments. */ - const char **argv) /* Argument strings. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument strings. */ { char buf[TCL_INTEGER_SPACE]; int val; -#ifdef __WIN32__ - if (argc < 2) { - Tcl_AppendResult(interp, "wrong # args; must be \"", argv[0], - " option ?arg ...?\"", NULL); - return TCL_ERROR; - } -#else - Tk_Window tkwin = (Tk_Window) clientData; - TkWindow *winPtr; - - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args; must be \"", argv[0], - " option window\"", NULL); - return TCL_ERROR; - } - - winPtr = (TkWindow *) Tk_NameToWindow(interp, argv[2], tkwin); - if (winPtr == NULL) { + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); return TCL_ERROR; } -#endif - if (strcmp(argv[1], "cyvscroll") == 0) { -#ifdef __WIN32__ + if (strcmp(Tcl_GetString(objv[1]), "cyvscroll") == 0) { val = GetSystemMetrics(SM_CYVSCROLL); -#else - val = ((TkScrollbar *) winPtr->instanceData)->width; -#endif - } else if (strcmp(argv[1], "cxhscroll") == 0) { -#ifdef __WIN32__ + } else if (strcmp(Tcl_GetString(objv[1]), "cxhscroll") == 0) { val = GetSystemMetrics(SM_CXHSCROLL); -#else - val = ((TkScrollbar *) winPtr->instanceData)->width; -#endif } else { - Tcl_AppendResult(interp, "bad option \"", argv[1], + Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[1]), "\": must be cxhscroll or cyvscroll", NULL); return TCL_ERROR; } @@ -1941,7 +1832,7 @@ TestmetricsCmd( /* *---------------------------------------------------------------------- * - * TestpropCmd -- + * TestpropObjCmd -- * * This function implements the "testprop" command. It fetches and prints * the value of a property on a window. @@ -1957,11 +1848,11 @@ TestmetricsCmd( /* ARGSUSED */ static int -TestpropCmd( +TestpropObjCmd( ClientData clientData, /* Main window for application. */ Tcl_Interp *interp, /* Current interpreter. */ - int argc, /* Number of arguments. */ - const char **argv) /* Argument strings. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument strings. */ { Tk_Window mainWin = (Tk_Window) clientData; int result, actualFormat; @@ -1972,14 +1863,13 @@ TestpropCmd( Window w; char buffer[30]; - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args; must be \"", argv[0], - " window property\"", NULL); + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "window property"); return TCL_ERROR; } - w = strtoul(argv[1], &end, 0); - propName = Tk_InternAtom(mainWin, argv[2]); + w = strtoul(Tcl_GetString(objv[1]), &end, 0); + propName = Tk_InternAtom(mainWin, Tcl_GetString(objv[2])); property = NULL; result = XGetWindowProperty(Tk_Display(mainWin), w, propName, 0, 100000, False, AnyPropertyType, @@ -1992,7 +1882,7 @@ TestpropCmd( *p = '\n'; } } - Tcl_SetResult(interp, (/*!unsigned*/char*)property, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_NewStringObj((/*!unsigned*/char*)property, -1)); } else { for (p = property; length > 0; length--) { if (actualFormat == 32) { @@ -2016,11 +1906,11 @@ TestpropCmd( return TCL_OK; } -#if !(defined(__WIN32__) || defined(MAC_OSX_TK) || defined(__CYGWIN__)) +#if !(defined(_WIN32) || defined(MAC_OSX_TK) || defined(__CYGWIN__)) /* *---------------------------------------------------------------------- * - * TestwrapperCmd -- + * TestwrapperObjCmd -- * * This function implements the "testwrapper" command. It provides a way * from Tcl to determine the extra window Tk adds in between the toplevel @@ -2037,23 +1927,22 @@ TestpropCmd( /* ARGSUSED */ static int -TestwrapperCmd( +TestwrapperObjCmd( ClientData clientData, /* Main window for application. */ Tcl_Interp *interp, /* Current interpreter. */ - int argc, /* Number of arguments. */ - const char **argv) /* Argument strings. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument strings. */ { TkWindow *winPtr, *wrapperPtr; Tk_Window tkwin; - if (argc != 2) { - Tcl_AppendResult(interp, "wrong # args; must be \"", argv[0], - " window\"", NULL); + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, "window"); return TCL_ERROR; } tkwin = (Tk_Window) clientData; - winPtr = (TkWindow *) Tk_NameToWindow(interp, argv[1], tkwin); + winPtr = (TkWindow *) Tk_NameToWindow(interp, Tcl_GetString(objv[1]), tkwin); if (winPtr == NULL) { return TCL_ERROR; } @@ -2063,7 +1952,7 @@ TestwrapperCmd( char buf[TCL_INTEGER_SPACE]; TkpPrintWindowId(buf, Tk_WindowId(wrapperPtr)); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1)); } return TCL_OK; } @@ -2106,7 +1995,7 @@ CustomOptionSet( char *saveInternalPtr, int flags) { - int objEmpty, length; + int objEmpty; char *newStr, *string, *internalPtr; objEmpty = 0; @@ -2123,28 +2012,28 @@ CustomOptionSet( if (value == NULL) { objEmpty = 1; + CLANG_ASSERT(value); } else if ((*value)->bytes != NULL) { objEmpty = ((*value)->length == 0); } else { - Tcl_GetStringFromObj((*value), &length); - objEmpty = (length == 0); + (void)Tcl_GetString(*value); + objEmpty = ((*value)->length == 0); } if ((flags & TK_OPTION_NULL_OK) && objEmpty) { *value = NULL; } else { - string = Tcl_GetStringFromObj((*value), &length); + string = Tcl_GetString(*value); Tcl_UtfToUpper(string); if (strcmp(string, "BAD") == 0) { - Tcl_SetResult(interp, "expected good value, got \"BAD\"", - TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj("expected good value, got \"BAD\"", -1)); return TCL_ERROR; } } if (internalPtr != NULL) { - if ((*value) != NULL) { - string = Tcl_GetStringFromObj((*value), &length); - newStr = ckalloc((size_t) (length + 1)); + if (*value != NULL) { + string = Tcl_GetString(*value); + newStr = ckalloc((*value)->length + 1); strcpy(newStr, string); } else { newStr = NULL; diff --git a/generic/tkText.c b/generic/tkText.c index c8421c3..ab06089 100644 --- a/generic/tkText.c +++ b/generic/tkText.c @@ -73,6 +73,16 @@ static const char *const tabStyleStrings[] = { }; /* + * The 'TkTextInsertUnfocussed' enum in tkText.h is used to define a type for + * the -insertunfocussed option of the Text widget. These values are used as + * indice into the string table below. + */ + +static const char *const insertUnfocussedStrings[] = { + "hollow", "none", "solid", NULL +}; + +/* * The following functions and custom option type are used to define the * "line" option type, and thereby handle the text widget '-startline', * '-endline' configuration options which are of that type. @@ -112,15 +122,16 @@ static const Tk_ObjCustomOption lineOption = { static const Tk_OptionSpec optionSpecs[] = { {TK_OPTION_BOOLEAN, "-autoseparators", "autoSeparators", "AutoSeparators", DEF_TEXT_AUTO_SEPARATORS, -1, - Tk_Offset(TkText, autoSeparators), 0, 0, 0}, + Tk_Offset(TkText, autoSeparators), + TK_OPTION_DONT_SET_DEFAULT, 0, 0}, {TK_OPTION_BORDER, "-background", "background", "Background", DEF_TEXT_BG_COLOR, -1, Tk_Offset(TkText, border), - 0, (ClientData) DEF_TEXT_BG_MONO, 0}, + 0, DEF_TEXT_BG_MONO, 0}, {TK_OPTION_SYNONYM, "-bd", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-borderwidth", + NULL, 0, -1, 0, "-borderwidth", TK_TEXT_LINE_GEOMETRY}, {TK_OPTION_SYNONYM, "-bg", NULL, NULL, - NULL, 0, -1, 0, (ClientData) "-background", 0}, + NULL, 0, -1, 0, "-background", 0}, {TK_OPTION_BOOLEAN, "-blockcursor", "blockCursor", "BlockCursor", DEF_TEXT_BLOCK_CURSOR, -1, Tk_Offset(TkText, insertCursorType), 0, 0, 0}, @@ -132,12 +143,12 @@ static const Tk_OptionSpec optionSpecs[] = { TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_CUSTOM, "-endline", NULL, NULL, NULL, -1, Tk_Offset(TkText, end), TK_OPTION_NULL_OK, - (ClientData) &lineOption, TK_TEXT_LINE_RANGE}, + &lineOption, TK_TEXT_LINE_RANGE}, {TK_OPTION_BOOLEAN, "-exportselection", "exportSelection", "ExportSelection", DEF_TEXT_EXPORT_SELECTION, -1, Tk_Offset(TkText, exportSelection), 0, 0, 0}, {TK_OPTION_SYNONYM, "-fg", "foreground", NULL, - NULL, 0, -1, 0, (ClientData) "-foreground", 0}, + NULL, 0, -1, 0, "-foreground", 0}, {TK_OPTION_FONT, "-font", "font", "Font", DEF_TEXT_FONT, -1, Tk_Offset(TkText, tkfont), 0, 0, TK_TEXT_LINE_GEOMETRY}, @@ -160,7 +171,7 @@ static const Tk_OptionSpec optionSpecs[] = { "Foreground", DEF_TEXT_INACTIVE_SELECT_COLOR, -1, Tk_Offset(TkText, inactiveSelBorder), - TK_OPTION_NULL_OK, (ClientData) DEF_TEXT_SELECT_MONO, 0}, + TK_OPTION_NULL_OK, DEF_TEXT_SELECT_MONO, 0}, {TK_OPTION_BORDER, "-insertbackground", "insertBackground", "Foreground", DEF_TEXT_INSERT_BG, -1, Tk_Offset(TkText, insertBorder), @@ -175,11 +186,16 @@ static const Tk_OptionSpec optionSpecs[] = { {TK_OPTION_INT, "-insertontime", "insertOnTime", "OnTime", DEF_TEXT_INSERT_ON_TIME, -1, Tk_Offset(TkText, insertOnTime), 0, 0, 0}, + {TK_OPTION_STRING_TABLE, + "-insertunfocussed", "insertUnfocussed", "InsertUnfocussed", + DEF_TEXT_INSERT_UNFOCUSSED, -1, Tk_Offset(TkText, insertUnfocussed), + 0, insertUnfocussedStrings, 0}, {TK_OPTION_PIXELS, "-insertwidth", "insertWidth", "InsertWidth", DEF_TEXT_INSERT_WIDTH, -1, Tk_Offset(TkText, insertWidth), 0, 0, 0}, {TK_OPTION_INT, "-maxundo", "maxUndo", "MaxUndo", - DEF_TEXT_MAX_UNDO, -1, Tk_Offset(TkText, maxUndo), 0, 0, 0}, + DEF_TEXT_MAX_UNDO, -1, Tk_Offset(TkText, maxUndo), + TK_OPTION_DONT_SET_DEFAULT, 0, 0}, {TK_OPTION_PIXELS, "-padx", "padX", "Pad", DEF_TEXT_PADX, -1, Tk_Offset(TkText, padX), 0, 0, TK_TEXT_LINE_GEOMETRY}, @@ -189,15 +205,15 @@ static const Tk_OptionSpec optionSpecs[] = { DEF_TEXT_RELIEF, -1, Tk_Offset(TkText, relief), 0, 0, 0}, {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground", DEF_TEXT_SELECT_COLOR, -1, Tk_Offset(TkText, selBorder), - 0, (ClientData) DEF_TEXT_SELECT_MONO, 0}, + 0, DEF_TEXT_SELECT_MONO, 0}, {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth", "BorderWidth", DEF_TEXT_SELECT_BD_COLOR, Tk_Offset(TkText, selBorderWidthPtr), Tk_Offset(TkText, selBorderWidth), - TK_OPTION_NULL_OK, (ClientData) DEF_TEXT_SELECT_BD_MONO, 0}, + TK_OPTION_NULL_OK, DEF_TEXT_SELECT_BD_MONO, 0}, {TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background", DEF_TEXT_SELECT_FG_COLOR, -1, Tk_Offset(TkText, selFgColorPtr), - TK_OPTION_NULL_OK, (ClientData) DEF_TEXT_SELECT_FG_MONO, 0}, + TK_OPTION_NULL_OK, DEF_TEXT_SELECT_FG_MONO, 0}, {TK_OPTION_BOOLEAN, "-setgrid", "setGrid", "SetGrid", DEF_TEXT_SET_GRID, -1, Tk_Offset(TkText, setGrid), 0, 0, 0}, {TK_OPTION_PIXELS, "-spacing1", "spacing1", "Spacing", @@ -211,27 +227,28 @@ static const Tk_OptionSpec optionSpecs[] = { 0, 0 , TK_TEXT_LINE_GEOMETRY }, {TK_OPTION_CUSTOM, "-startline", NULL, NULL, NULL, -1, Tk_Offset(TkText, start), TK_OPTION_NULL_OK, - (ClientData) &lineOption, TK_TEXT_LINE_RANGE}, + &lineOption, TK_TEXT_LINE_RANGE}, {TK_OPTION_STRING_TABLE, "-state", "state", "State", DEF_TEXT_STATE, -1, Tk_Offset(TkText, state), - 0, (ClientData) stateStrings, 0}, + 0, stateStrings, 0}, {TK_OPTION_STRING, "-tabs", "tabs", "Tabs", DEF_TEXT_TABS, Tk_Offset(TkText, tabOptionPtr), -1, TK_OPTION_NULL_OK, 0, TK_TEXT_LINE_GEOMETRY}, {TK_OPTION_STRING_TABLE, "-tabstyle", "tabStyle", "TabStyle", DEF_TEXT_TABSTYLE, -1, Tk_Offset(TkText, tabStyle), - 0, (ClientData) tabStyleStrings, TK_TEXT_LINE_GEOMETRY}, + 0, tabStyleStrings, TK_TEXT_LINE_GEOMETRY}, {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", DEF_TEXT_TAKE_FOCUS, -1, Tk_Offset(TkText, takeFocus), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_BOOLEAN, "-undo", "undo", "Undo", - DEF_TEXT_UNDO, -1, Tk_Offset(TkText, undo), 0, 0 , 0}, + DEF_TEXT_UNDO, -1, Tk_Offset(TkText, undo), + TK_OPTION_DONT_SET_DEFAULT, 0 , 0}, {TK_OPTION_INT, "-width", "width", "Width", DEF_TEXT_WIDTH, -1, Tk_Offset(TkText, width), 0, 0, TK_TEXT_LINE_GEOMETRY}, {TK_OPTION_STRING_TABLE, "-wrap", "wrap", "Wrap", DEF_TEXT_WRAP, -1, Tk_Offset(TkText, wrapMode), - 0, (ClientData) wrapStrings, TK_TEXT_LINE_GEOMETRY}, + 0, wrapStrings, TK_TEXT_LINE_GEOMETRY}, {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand", DEF_TEXT_XSCROLL_COMMAND, -1, Tk_Offset(TkText, xScrollCmd), TK_OPTION_NULL_OK, 0, 0}, @@ -387,6 +404,7 @@ static Tcl_Obj * TextGetText(const TkText *textPtr, const TkTextIndex *index1, const TkTextIndex *index2, int visibleOnly); static void GenerateModifiedEvent(TkText *textPtr); +static void GenerateUndoStackEvent(TkText *textPtr); static void UpdateDirtyFlag(TkSharedText *sharedPtr); static void TextPushUndoAction(TkText *textPtr, Tcl_Obj *undoString, int insert, @@ -412,7 +430,7 @@ static SearchLineIndexProc TextSearchGetLineIndex; * can be invoked from generic window code. */ -static Tk_ClassProcs textClass = { +static const Tk_ClassProcs textClass = { sizeof(Tk_ClassProcs), /* size */ TextWorldChangedCallback, /* worldChangedProc */ NULL, /* createProc */ @@ -443,10 +461,10 @@ Tk_TextObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - Tk_Window tkwin = (Tk_Window) clientData; + Tk_Window tkwin = clientData; if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?"); + Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?"); return TCL_ERROR; } @@ -505,7 +523,7 @@ CreateWidget( * and 'insert', 'current' mark pointers are all NULL to start. */ - textPtr = (TkText *) ckalloc(sizeof(TkText)); + textPtr = ckalloc(sizeof(TkText)); memset(textPtr, 0, sizeof(TkText)); textPtr->tkwin = newWin; @@ -513,10 +531,10 @@ CreateWidget( textPtr->interp = interp; textPtr->widgetCmd = Tcl_CreateObjCommand(interp, Tk_PathName(textPtr->tkwin), TextWidgetObjCmd, - (ClientData) textPtr, TextCmdDeletedProc); + textPtr, TextCmdDeletedProc); if (sharedPtr == NULL) { - sharedPtr = (TkSharedText *) ckalloc(sizeof(TkSharedText)); + sharedPtr = ckalloc(sizeof(TkSharedText)); memset(sharedPtr, 0, sizeof(TkSharedText)); sharedPtr->refCount = 0; @@ -528,7 +546,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; @@ -614,7 +632,7 @@ CreateWidget( */ textPtr->selTagPtr = TkTextCreateTag(textPtr, "sel", NULL); - textPtr->selTagPtr->reliefString = (char *) + textPtr->selTagPtr->reliefString = ckalloc(sizeof(DEF_TEXT_SELECT_RELIEF)); strcpy(textPtr->selTagPtr->reliefString, DEF_TEXT_SELECT_RELIEF); Tk_GetRelief(interp, DEF_TEXT_SELECT_RELIEF, &textPtr->selTagPtr->relief); @@ -629,18 +647,18 @@ CreateWidget( optionTable = Tk_CreateOptionTable(interp, optionSpecs); Tk_SetClass(textPtr->tkwin, "Text"); - Tk_SetClassProcs(textPtr->tkwin, &textClass, (ClientData) textPtr); + Tk_SetClassProcs(textPtr->tkwin, &textClass, textPtr); textPtr->optionTable = optionTable; Tk_CreateEventHandler(textPtr->tkwin, ExposureMask|StructureNotifyMask|FocusChangeMask, - TextEventProc, (ClientData) textPtr); + TextEventProc, textPtr); Tk_CreateEventHandler(textPtr->tkwin, KeyPressMask|KeyReleaseMask |ButtonPressMask|ButtonReleaseMask|EnterWindowMask |LeaveWindowMask|PointerMotionMask|VirtualEventMask, - TkTextBindProc, (ClientData) textPtr); + TkTextBindProc, textPtr); Tk_CreateSelHandler(textPtr->tkwin, XA_PRIMARY, XA_STRING, - TextFetchSelection, (ClientData) textPtr, XA_STRING); + TextFetchSelection, textPtr, XA_STRING); if (Tk_InitOptions(interp, (char *) textPtr, optionTable, textPtr->tkwin) != TCL_OK) { @@ -652,8 +670,7 @@ CreateWidget( return TCL_ERROR; } - Tcl_SetObjResult(interp, - Tcl_NewStringObj(Tk_PathName(textPtr->tkwin),-1)); + Tcl_SetObjResult(interp, TkNewWindowObj(textPtr->tkwin)); return TCL_OK; } @@ -682,31 +699,32 @@ TextWidgetObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - register TkText *textPtr = (TkText *) clientData; + register TkText *textPtr = clientData; int result = TCL_OK; int index; - static const char *optionStrings[] = { + static const char *const optionStrings[] = { "bbox", "cget", "compare", "configure", "count", "debug", "delete", "dlineinfo", "dump", "edit", "get", "image", "index", "insert", - "mark", "peer", "replace", "scan", "search", "see", "tag", "window", - "xview", "yview", NULL + "mark", "peer", "pendingsync", "replace", "scan", "search", + "see", "sync", "tag", "window", "xview", "yview", NULL }; enum options { TEXT_BBOX, TEXT_CGET, TEXT_COMPARE, TEXT_CONFIGURE, TEXT_COUNT, TEXT_DEBUG, TEXT_DELETE, TEXT_DLINEINFO, TEXT_DUMP, TEXT_EDIT, TEXT_GET, TEXT_IMAGE, TEXT_INDEX, TEXT_INSERT, TEXT_MARK, - TEXT_PEER, TEXT_REPLACE, TEXT_SCAN, TEXT_SEARCH, TEXT_SEE, - TEXT_TAG, TEXT_WINDOW, TEXT_XVIEW, TEXT_YVIEW + TEXT_PEER, TEXT_PENDINGSYNC, TEXT_REPLACE, TEXT_SCAN, + TEXT_SEARCH, TEXT_SEE, TEXT_SYNC, TEXT_TAG, TEXT_WINDOW, + TEXT_XVIEW, TEXT_YVIEW }; if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?"); + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); return TCL_ERROR; } - if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0, - &index) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings, + sizeof(char *), "option", 0, &index) != TCL_OK) { return TCL_ERROR; } textPtr->refCount++; @@ -747,13 +765,13 @@ TextWidgetObjCmd( } else { Tcl_Obj *objPtr = Tk_GetOptionValue(interp, (char *) textPtr, textPtr->optionTable, objv[2], textPtr->tkwin); + if (objPtr == NULL) { result = TCL_ERROR; goto done; - } else { - Tcl_SetObjResult(interp, objPtr); - result = TCL_OK; } + Tcl_SetObjResult(interp, objPtr); + result = TCL_OK; } break; case TEXT_COMPARE: { @@ -779,12 +797,7 @@ TextWidgetObjCmd( if ((p[1] == '=') && (p[2] == 0)) { value = (relation <= 0); } else if (p[1] != 0) { - compareError: - Tcl_AppendResult(interp, "bad comparison operator \"", - Tcl_GetString(objv[3]), - "\": must be <, <=, ==, >=, >, or !=", NULL); - result = TCL_ERROR; - goto done; + goto compareError; } } else if (p[0] == '>') { value = (relation > 0); @@ -802,18 +815,26 @@ TextWidgetObjCmd( } Tcl_SetObjResult(interp, Tcl_NewBooleanObj(value)); break; + + compareError: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad comparison operator \"%s\": must be" + " <, <=, ==, >=, >, or !=", Tcl_GetString(objv[3]))); + Tcl_SetErrorCode(interp, "TK", "VALUE", "COMPARISON", NULL); + result = TCL_ERROR; + goto done; } case TEXT_CONFIGURE: if (objc <= 3) { Tcl_Obj *objPtr = Tk_GetOptionInfo(interp, (char *) textPtr, textPtr->optionTable, ((objc == 3) ? objv[2] : NULL), textPtr->tkwin); + if (objPtr == NULL) { result = TCL_ERROR; goto done; - } else { - Tcl_SetObjResult(interp, objPtr); } + Tcl_SetObjResult(interp, objPtr); } else { result = ConfigureText(interp, textPtr, objc-2, objv+2); } @@ -824,7 +845,8 @@ TextWidgetObjCmd( Tcl_Obj *objPtr = NULL; if (objc < 4) { - Tcl_WrongNumArgs(interp, 2, objv, "?options? index1 index2"); + Tcl_WrongNumArgs(interp, 2, objv, + "?-option value ...? index1 index2"); result = TCL_ERROR; goto done; } @@ -841,35 +863,29 @@ TextWidgetObjCmd( } for (i = 2; i < objc-2; i++) { - int value, length; - const char *option = Tcl_GetStringFromObj(objv[i], &length); + int value; + size_t length; + const char *option = Tcl_GetString(objv[i]); char c; + length = objv[i]->length; if (length < 2 || option[0] != '-') { - badOption: - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "bad option \"", - Tcl_GetString(objv[i]), - "\" must be -chars, -displaychars, -displayindices, ", - "-displaylines, -indices, -lines, -update, ", - "-xpixels, or -ypixels", NULL); - result = TCL_ERROR; - goto done; + goto badOption; } c = option[1]; - if (c == 'c' && !strncmp("-chars", option, (unsigned) length)) { + if (c == 'c' && !strncmp("-chars", option, length)) { value = CountIndices(textPtr, indexFromPtr, indexToPtr, COUNT_CHARS); } else if (c == 'd' && (length > 8) - && !strncmp("-displaychars", option, (unsigned) length)) { + && !strncmp("-displaychars", option, length)) { value = CountIndices(textPtr, indexFromPtr, indexToPtr, COUNT_DISPLAY_CHARS); } else if (c == 'd' && (length > 8) - && !strncmp("-displayindices", option,(unsigned)length)) { + && !strncmp("-displayindices", option,length)) { value = CountIndices(textPtr, indexFromPtr, indexToPtr, COUNT_DISPLAY_INDICES); } else if (c == 'd' && (length > 8) - && !strncmp("-displaylines", option, (unsigned) length)) { + && !strncmp("-displaylines", option, length)) { TkTextLine *fromPtr, *lastPtr; TkTextIndex index, index2; @@ -907,43 +923,43 @@ TextWidgetObjCmd( * We're going to count up all display lines in the logical * line of 'indexFromPtr' up to, but not including the logical * line of 'indexToPtr' (except if this line is elided), and - * then subtract off what came in too much from elided lines, - * also subtract off what we didn't want from 'from' and add + * then subtract off what came in too much from elided lines, + * also subtract off what we didn't want from 'from' and add * on what we didn't count from 'to'. */ - while (TkTextIndexCmp(&index,indexToPtr) < 0) { + while (TkTextIndexCmp(&index,indexToPtr) < 0) { value += TkTextUpdateOneLine(textPtr, index.linePtr, - 0, &index, 0); + 0, &index, 0); } - index2 = index; - - /* - * Now we need to adjust the count to: - * - subtract off the number of display lines between - * indexToPtr and index2, since we might have skipped past - * indexToPtr, if we have several logical lines in a - * single display line - * - subtract off the number of display lines overcounted - * in the first logical line - * - add on the number of display lines in the last logical - * line - * This logic is still ok if both indexFromPtr and indexToPtr - * are in the same logical line. - */ - - index = *indexToPtr; - index.byteIndex = 0; - while (TkTextIndexCmp(&index,&index2) < 0) { - value -= TkTextUpdateOneLine(textPtr, index.linePtr, - 0, &index, 0); - } + index2 = index; + + /* + * Now we need to adjust the count to: + * - subtract off the number of display lines between + * indexToPtr and index2, since we might have skipped past + * indexToPtr, if we have several logical lines in a + * single display line + * - subtract off the number of display lines overcounted + * in the first logical line + * - add on the number of display lines in the last logical + * line + * This logic is still ok if both indexFromPtr and indexToPtr + * are in the same logical line. + */ + + index = *indexToPtr; + index.byteIndex = 0; + while (TkTextIndexCmp(&index,&index2) < 0) { + value -= TkTextUpdateOneLine(textPtr, index.linePtr, + 0, &index, 0); + } index.linePtr = indexFromPtr->linePtr; index.byteIndex = 0; while (1) { TkTextFindDisplayLineEnd(textPtr, &index, 1, NULL); - if (TkTextIndexCmp(&index,indexFromPtr) >= 0) { + if (TkTextIndexCmp(&index,indexFromPtr) >= 0) { break; } TkTextIndexForwBytes(textPtr, &index, 1, &index); @@ -955,7 +971,7 @@ TextWidgetObjCmd( index.byteIndex = 0; while (1) { TkTextFindDisplayLineEnd(textPtr, &index, 1, NULL); - if (TkTextIndexCmp(&index,indexToPtr) >= 0) { + if (TkTextIndexCmp(&index,indexToPtr) >= 0) { break; } TkTextIndexForwBytes(textPtr, &index, 1, &index); @@ -967,19 +983,19 @@ TextWidgetObjCmd( value = -value; } } else if (c == 'i' - && !strncmp("-indices", option, (unsigned) length)) { + && !strncmp("-indices", option, length)) { value = CountIndices(textPtr, indexFromPtr, indexToPtr, COUNT_INDICES); } else if (c == 'l' - && !strncmp("-lines", option, (unsigned) length)) { + && !strncmp("-lines", option, length)) { value = TkBTreeLinesTo(textPtr, indexToPtr->linePtr) - TkBTreeLinesTo(textPtr, indexFromPtr->linePtr); } else if (c == 'u' - && !strncmp("-update", option, (unsigned) length)) { + && !strncmp("-update", option, length)) { update = 1; continue; } else if (c == 'x' - && !strncmp("-xpixels", option, (unsigned) length)) { + && !strncmp("-xpixels", option, length)) { int x1, x2; TkTextIndex index; @@ -989,7 +1005,7 @@ TextWidgetObjCmd( TkTextFindDisplayLineEnd(textPtr, &index, 0, &x2); value = x2 - x1; } else if (c == 'y' - && !strncmp("-ypixels", option, (unsigned) length)) { + && !strncmp("-ypixels", option, length)) { if (update) { TkTextUpdateLineMetrics(textPtr, TkBTreeLinesTo(textPtr, indexFromPtr->linePtr), @@ -1033,6 +1049,15 @@ TextWidgetObjCmd( Tcl_SetObjResult(interp, objPtr); } break; + + badOption: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad option \"%s\" must be -chars, -displaychars, " + "-displayindices, -displaylines, -indices, -lines, -update, " + "-xpixels, or -ypixels", Tcl_GetString(objv[i]))); + Tcl_SetErrorCode(interp, "TK", "TEXT", "INDEX_OPTION", NULL); + result = TCL_ERROR; + goto done; } case TEXT_DEBUG: if (objc > 3) { @@ -1101,8 +1126,7 @@ TextWidgetObjCmd( objc -= 2; objv += 2; - indices = (TkTextIndex *) - ckalloc((objc + 1) * sizeof(TkTextIndex)); + indices = ckalloc((objc + 1) * sizeof(TkTextIndex)); /* * First pass verifies that all indices are valid. @@ -1114,7 +1138,7 @@ TextWidgetObjCmd( if (indexPtr == NULL) { result = TCL_ERROR; - ckfree((char *) indices); + ckfree(indices); goto done; } indices[i] = *indexPtr; @@ -1130,15 +1154,15 @@ TextWidgetObjCmd( COUNT_INDICES); objc++; } - useIdx = (char *) ckalloc((unsigned) objc); - memset(useIdx, 0, (unsigned) objc); + useIdx = ckalloc(objc); + memset(useIdx, 0, (size_t) objc); /* * Do a decreasing order sort so that we delete the end ranges * first to maintain index consistency. */ - qsort(indices, (unsigned) objc / 2, + qsort(indices, (size_t) objc / 2, 2 * sizeof(TkTextIndex), TextIndexSortProc); lastStart = NULL; @@ -1194,7 +1218,7 @@ TextWidgetObjCmd( &indices[i+1], 1); } } - ckfree((char *) indices); + ckfree(indices); } } break; @@ -1236,7 +1260,7 @@ TextWidgetObjCmd( Tcl_Obj *objPtr = NULL; int i, found = 0, visible = 0; const char *name; - int length; + size_t length; if (objc < 3) { Tcl_WrongNumArgs(interp, 2, objv, @@ -1252,12 +1276,14 @@ TextWidgetObjCmd( i = 2; if (objc > 3) { - name = Tcl_GetStringFromObj(objv[i], &length); + name = Tcl_GetString(objv[i]); + length = objv[i]->length; if (length > 1 && name[0] == '-') { - if (strncmp("-displaychars", name, (unsigned)length)==0) { + if (strncmp("-displaychars", name, length) == 0) { i++; visible = 1; - name = Tcl_GetStringFromObj(objv[i], &length); + name = Tcl_GetString(objv[i]); + length = objv[i]->length; } if ((i < objc-1) && (length == 2) && !strcmp("--", name)) { i++; @@ -1372,6 +1398,16 @@ TextWidgetObjCmd( case TEXT_PEER: result = TextPeerCmd(textPtr, interp, objc, objv); break; + case TEXT_PENDINGSYNC: { + if (objc != 2) { + Tcl_WrongNumArgs(interp, 2, objv, NULL); + result = TCL_ERROR; + goto done; + } + Tcl_SetObjResult(interp, + Tcl_NewBooleanObj(TkTextPendingsync(textPtr))); + break; + } case TEXT_REPLACE: { const TkTextIndex *indexFromPtr, *indexToPtr; @@ -1392,9 +1428,10 @@ TextWidgetObjCmd( goto done; } if (TkTextIndexCmp(indexFromPtr, indexToPtr) > 0) { - Tcl_AppendResult(interp, "Index \"", Tcl_GetString(objv[3]), - "\" before \"", Tcl_GetString(objv[2]), - "\" in the text", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "index \"%s\" before \"%s\" in the text", + Tcl_GetString(objv[3]), Tcl_GetString(objv[2]))); + Tcl_SetErrorCode(interp, "TK", "TEXT", "INDEX_ORDER", NULL); result = TCL_ERROR; goto done; } @@ -1428,7 +1465,7 @@ TextWidgetObjCmd( * unnecessarily. */ - int deleteInsertOffset, insertLength, j; + int deleteInsertOffset, insertLength, j, indexFromLine, indexFromByteOffset; insertLength = 0; for (j = 4; j < objc; j += 2) { @@ -1446,6 +1483,9 @@ TextWidgetObjCmd( deleteInsertOffset = insertLength; } + indexFromLine = TkBTreeLinesTo(textPtr, indexFromPtr->linePtr); + indexFromByteOffset = indexFromPtr->byteIndex; + result = TextReplaceCmd(textPtr, interp, indexFromPtr, indexToPtr, objc, objv, 0); @@ -1454,7 +1494,11 @@ TextWidgetObjCmd( * Move the insertion position to the correct place. */ - TkTextIndexForwChars(NULL, indexFromPtr, + TkTextIndex indexTmp; + + TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, indexFromLine, + indexFromByteOffset, &indexTmp); + TkTextIndexForwChars(NULL, &indexTmp, deleteInsertOffset, &index, COUNT_INDICES); TkBTreeUnlinkSegment(textPtr->insertMarkPtr, textPtr->insertMarkPtr->body.mark.linePtr); @@ -1485,6 +1529,39 @@ TextWidgetObjCmd( case TEXT_SEE: result = TkTextSeeCmd(textPtr, interp, objc, objv); break; + case TEXT_SYNC: { + if (objc == 4) { + Tcl_Obj *cmd = objv[3]; + const char *option = Tcl_GetString(objv[2]); + if (strncmp(option, "-command", objv[2]->length)) { + Tcl_AppendResult(interp, "wrong option \"", option, "\": should be \"-command\"", NULL); + result = TCL_ERROR; + goto done; + } + Tcl_IncrRefCount(cmd); + if (TkTextPendingsync(textPtr)) { + if (textPtr->afterSyncCmd) { + Tcl_DecrRefCount(textPtr->afterSyncCmd); + } + textPtr->afterSyncCmd = cmd; + } else { + textPtr->afterSyncCmd = cmd; + Tcl_DoWhenIdle(TkTextRunAfterSyncCmd, (ClientData) textPtr); + } + break; + } else if (objc != 2) { + Tcl_WrongNumArgs(interp, 2, objv, "?-command command?"); + result = TCL_ERROR; + goto done; + } + if (textPtr->afterSyncCmd) { + Tcl_DecrRefCount(textPtr->afterSyncCmd); + } + textPtr->afterSyncCmd = NULL; + TkTextUpdateLineMetrics(textPtr, 0, + TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr), -1); + break; + } case TEXT_TAG: result = TkTextTagCmd(textPtr, interp, objc, objv); break; @@ -1500,9 +1577,8 @@ TextWidgetObjCmd( } done: - textPtr->refCount--; - if (textPtr->refCount == 0) { - ckfree((char *) textPtr); + if (textPtr->refCount-- <= 1) { + ckfree(textPtr); } return result; } @@ -1534,11 +1610,11 @@ SharedTextObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - register TkSharedText *sharedPtr = (TkSharedText *) clientData; + register TkSharedText *sharedPtr = clientData; int result = TCL_OK; int index; - static const char *optionStrings[] = { + static const char *const optionStrings[] = { "delete", "insert", NULL }; enum options { @@ -1546,12 +1622,12 @@ SharedTextObjCmd( }; if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?"); + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); return TCL_ERROR; } - if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0, - &index) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings, + sizeof(char *), "option", 0, &index) != TCL_OK) { return TCL_ERROR; } @@ -1643,7 +1719,7 @@ TextPeerCmd( Tk_Window tkwin = textPtr->tkwin; int index; - static const char *peerOptionStrings[] = { + static const char *const peerOptionStrings[] = { "create", "names", NULL }; enum peerOptions { @@ -1651,36 +1727,40 @@ TextPeerCmd( }; if (objc < 3) { - Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?"); + Tcl_WrongNumArgs(interp, 2, objv, "option ?arg ...?"); return TCL_ERROR; } - if (Tcl_GetIndexFromObj(interp, objv[2], peerOptionStrings, - "peer option", 0, &index) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[2], peerOptionStrings, + sizeof(char *), "peer option", 0, &index) != TCL_OK) { return TCL_ERROR; } - switch ((enum peerOptions)index) { + switch ((enum peerOptions) index) { case PEER_CREATE: if (objc < 4) { - Tcl_WrongNumArgs(interp, 3, objv, "pathName ?options?"); + Tcl_WrongNumArgs(interp, 3, objv, "pathName ?-option value ...?"); return TCL_ERROR; } return CreateWidget(textPtr->sharedTextPtr, tkwin, interp, textPtr, objc-2, objv+2); case PEER_NAMES: { TkText *tPtr = textPtr->sharedTextPtr->peers; + Tcl_Obj *peersObj; if (objc > 3) { Tcl_WrongNumArgs(interp, 3, objv, NULL); return TCL_ERROR; } + peersObj = Tcl_NewObj(); while (tPtr != NULL) { if (tPtr != textPtr) { - Tcl_AppendElement(interp, Tk_PathName(tPtr->tkwin)); + Tcl_ListObjAppendElement(NULL, peersObj, + TkNewWindowObj(tPtr->tkwin)); } tPtr = tPtr->next; } + Tcl_SetObjResult(interp, peersObj); } } @@ -1877,10 +1957,10 @@ DestroyText( TkTextDeleteTag(textPtr, textPtr->selTagPtr); TkBTreeUnlinkSegment(textPtr->insertMarkPtr, textPtr->insertMarkPtr->body.mark.linePtr); - ckfree((char *) textPtr->insertMarkPtr); + ckfree(textPtr->insertMarkPtr); TkBTreeUnlinkSegment(textPtr->currentMarkPtr, textPtr->currentMarkPtr->body.mark.linePtr); - ckfree((char *) textPtr->currentMarkPtr); + ckfree(textPtr->currentMarkPtr); /* * Now we've cleaned up everything of relevance to us in the B-tree, so we @@ -1890,9 +1970,7 @@ DestroyText( * portion of the text widget. */ - sharedTextPtr->refCount--; - - if (sharedTextPtr->refCount > 0) { + if (sharedTextPtr->refCount-- > 1) { TkBTreeRemoveClient(sharedTextPtr->tree, textPtr); /* @@ -1902,7 +1980,7 @@ DestroyText( for (hPtr = Tcl_FirstHashEntry(&sharedTextPtr->windowTable, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { TkTextEmbWindowClient *loop; - TkTextSegment *ewPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr); + TkTextSegment *ewPtr = Tcl_GetHashValue(hPtr); loop = ewPtr->body.ew.clients; if (loop->textPtr == textPtr) { @@ -1934,7 +2012,7 @@ DestroyText( for (hPtr = Tcl_FirstHashEntry(&sharedTextPtr->tagTable, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - tagPtr = (TkTextTag *) Tcl_GetHashValue(hPtr); + tagPtr = Tcl_GetHashValue(hPtr); /* * No need to use 'TkTextDeleteTag' since we've already removed @@ -1946,7 +2024,7 @@ DestroyText( Tcl_DeleteHashTable(&sharedTextPtr->tagTable); for (hPtr = Tcl_FirstHashEntry(&sharedTextPtr->markTable, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - ckfree((char *) Tcl_GetHashValue(hPtr)); + ckfree(Tcl_GetHashValue(hPtr)); } Tcl_DeleteHashTable(&sharedTextPtr->markTable); TkUndoFreeStack(sharedTextPtr->undoStack); @@ -1957,21 +2035,24 @@ DestroyText( if (sharedTextPtr->bindingTable != NULL) { Tk_DeleteBindingTable(sharedTextPtr->bindingTable); } - ckfree((char *) sharedTextPtr); + ckfree(sharedTextPtr); } if (textPtr->tabArrayPtr != NULL) { - ckfree((char *) textPtr->tabArrayPtr); + ckfree(textPtr->tabArrayPtr); } if (textPtr->insertBlinkHandler != NULL) { Tcl_DeleteTimerHandler(textPtr->insertBlinkHandler); } textPtr->tkwin = NULL; - textPtr->refCount--; Tcl_DeleteCommandFromToken(textPtr->interp, textPtr->widgetCmd); - if (textPtr->refCount == 0) { - ckfree((char *) textPtr); + if (textPtr->afterSyncCmd){ + Tcl_DecrRefCount(textPtr->afterSyncCmd); + textPtr->afterSyncCmd = NULL; + } + if (textPtr->refCount-- <= 1) { + ckfree(textPtr); } } @@ -2003,7 +2084,7 @@ ConfigureText( Tcl_Obj *const objv[]) /* Argument objects. */ { Tk_SavedOptions savedOptions; - int oldExport = textPtr->exportSelection; + int oldExport = (textPtr->exportSelection) && (!Tcl_IsSafe(textPtr->interp)); int mask = 0; if (Tk_SetOptions(interp, (char *) textPtr, textPtr->optionTable, @@ -2019,7 +2100,7 @@ ConfigureText( textPtr->sharedTextPtr->maxUndo = textPtr->maxUndo; textPtr->sharedTextPtr->autoSeparators = textPtr->autoSeparators; - TkUndoSetDepth(textPtr->sharedTextPtr->undoStack, + TkUndoSetMaxDepth(textPtr->sharedTextPtr->undoStack, textPtr->sharedTextPtr->maxUndo); /* @@ -2051,9 +2132,9 @@ ConfigureText( end = TkBTreeNumLines(textPtr->sharedTextPtr->tree, NULL); } if (start > end) { - Tcl_AppendResult(interp, - "-startline must be less than or equal to -endline", - NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "-startline must be less than or equal to -endline", -1)); + Tcl_SetErrorCode(interp, "TK", "TEXT", "INDEX_ORDER", NULL); Tk_RestoreSavedOptions(&savedOptions); return TCL_ERROR; } @@ -2086,6 +2167,7 @@ ConfigureText( /* Nothing tagged with "sel" */ } else { int line = TkBTreeLinesTo(NULL, search.curIndex.linePtr); + if (line < start) { selChanged = 1; } else { @@ -2116,10 +2198,10 @@ ConfigureText( * Also, clamp the insert and current (unshared) marks to the new * -startline/-endline range limits of the widget. All other (shared) * marks are unchanged. - * The return value of TkTextMarkNameToIndex does not need to be - * checked: "insert" and "current" marks always exist, and the - * purpose of the code below precisely is to move them inside the - * -startline/-endline range. + * The return value of TkTextMarkNameToIndex does not need to be + * checked: "insert" and "current" marks always exist, and the + * purpose of the code below precisely is to move them inside the + * -startline/-endline range. */ textPtr->sharedTextPtr->stateEpoch++; @@ -2158,7 +2240,7 @@ ConfigureText( */ if (textPtr->tabArrayPtr != NULL) { - ckfree((char *) textPtr->tabArrayPtr); + ckfree(textPtr->tabArrayPtr); textPtr->tabArrayPtr = NULL; } if (textPtr->tabOptionPtr != NULL) { @@ -2178,12 +2260,20 @@ ConfigureText( * replaced in the widget record. */ - textPtr->selTagPtr->border = textPtr->selBorder; + if (textPtr->selTagPtr->selBorder == NULL) { + textPtr->selTagPtr->border = textPtr->selBorder; + } else { + textPtr->selTagPtr->selBorder = textPtr->selBorder; + } if (textPtr->selTagPtr->borderWidthPtr != textPtr->selBorderWidthPtr) { textPtr->selTagPtr->borderWidthPtr = textPtr->selBorderWidthPtr; textPtr->selTagPtr->borderWidth = textPtr->selBorderWidth; } - textPtr->selTagPtr->fgColor = textPtr->selFgColorPtr; + if (textPtr->selTagPtr->selFgColor == NULL) { + textPtr->selTagPtr->fgColor = textPtr->selFgColorPtr; + } else { + textPtr->selTagPtr->selFgColor = textPtr->selFgColorPtr; + } textPtr->selTagPtr->affectsDisplay = 0; textPtr->selTagPtr->affectsDisplayGeometry = 0; if ((textPtr->selTagPtr->elideString != NULL) @@ -2202,12 +2292,18 @@ ConfigureText( textPtr->selTagPtr->affectsDisplayGeometry = 1; } if ((textPtr->selTagPtr->border != NULL) + || (textPtr->selTagPtr->selBorder != NULL) || (textPtr->selTagPtr->reliefString != NULL) || (textPtr->selTagPtr->bgStipple != None) || (textPtr->selTagPtr->fgColor != NULL) + || (textPtr->selTagPtr->selFgColor != NULL) || (textPtr->selTagPtr->fgStipple != None) || (textPtr->selTagPtr->overstrikeString != NULL) - || (textPtr->selTagPtr->underlineString != NULL)) { + || (textPtr->selTagPtr->overstrikeColor != NULL) + || (textPtr->selTagPtr->underlineString != NULL) + || (textPtr->selTagPtr->underlineColor != NULL) + || (textPtr->selTagPtr->lMarginColor != NULL) + || (textPtr->selTagPtr->rMarginColor != NULL)) { textPtr->selTagPtr->affectsDisplay = 1; } TkTextRedrawTag(NULL, textPtr, NULL, NULL, textPtr->selTagPtr, 1); @@ -2217,7 +2313,7 @@ ConfigureText( * are tagged characters. */ - if (textPtr->exportSelection && (!oldExport)) { + if (textPtr->exportSelection && (!oldExport) && (!Tcl_IsSafe(textPtr->interp))) { TkTextSearch search; TkTextIndex first, last; @@ -2230,7 +2326,7 @@ ConfigureText( if (TkBTreeCharTagged(&first, textPtr->selTagPtr) || TkBTreeNextTag(&search)) { Tk_OwnSelection(textPtr->tkwin, XA_PRIMARY, TkTextLostSelection, - (ClientData) textPtr); + textPtr); textPtr->flags |= GOT_SELECTION; } } @@ -2241,8 +2337,8 @@ ConfigureText( if (textPtr->flags & GOT_FOCUS) { Tcl_DeleteTimerHandler(textPtr->insertBlinkHandler); - textPtr->insertBlinkHandler = (Tcl_TimerToken) NULL; - TextBlinkProc((ClientData) textPtr); + textPtr->insertBlinkHandler = NULL; + TextBlinkProc(textPtr); } /* @@ -2285,9 +2381,8 @@ static void TextWorldChangedCallback( ClientData instanceData) /* Information about widget. */ { - TkText *textPtr; + TkText *textPtr = instanceData; - textPtr = (TkText *) instanceData; TextWorldChanged(textPtr, TK_TEXT_LINE_GEOMETRY); } @@ -2332,7 +2427,7 @@ TextWorldChanged( textPtr->charHeight = 1; } if (textPtr->charHeight != oldCharHeight) { - TkBTreeClientRangeChanged(textPtr, textPtr->charHeight); + TkBTreeClientRangeChanged(textPtr, textPtr->charHeight); } border = textPtr->borderWidth + textPtr->highlightWidth; Tk_GeometryRequest(textPtr->tkwin, @@ -2377,7 +2472,7 @@ TextEventProc( ClientData clientData, /* Information about window. */ register XEvent *eventPtr) /* Information about event. */ { - register TkText *textPtr = (TkText *) clientData; + register TkText *textPtr = clientData; TkTextIndex index, index2; if (eventPtr->type == Expose) { @@ -2437,12 +2532,11 @@ TextEventProc( textPtr->flags |= GOT_FOCUS | INSERT_ON; if (textPtr->insertOffTime != 0) { textPtr->insertBlinkHandler = Tcl_CreateTimerHandler( - textPtr->insertOnTime, TextBlinkProc, - (ClientData) textPtr); + textPtr->insertOnTime, TextBlinkProc, textPtr); } } else { textPtr->flags &= ~(GOT_FOCUS | INSERT_ON); - textPtr->insertBlinkHandler = (Tcl_TimerToken) NULL; + textPtr->insertBlinkHandler = NULL; } if (textPtr->inactiveSelBorder != textPtr->selBorder) { TkTextRedrawTag(NULL, textPtr, NULL, NULL, textPtr->selTagPtr, @@ -2487,7 +2581,7 @@ static void TextCmdDeletedProc( ClientData clientData) /* Pointer to widget record for widget. */ { - TkText *textPtr = (TkText *) clientData; + TkText *textPtr = clientData; Tk_Window tkwin = textPtr->tkwin; /* @@ -2539,14 +2633,15 @@ InsertChars( * information to add to text. */ int viewUpdate) /* Update the view if set. */ { - int lineIndex, length; + int lineIndex; + size_t length; TkText *tPtr; int *lineAndByteIndex; int resetViewCount; int pixels[2*PIXEL_CLIENTS]; + const char *string = Tcl_GetString(stringPtr); - const char *string = Tcl_GetStringFromObj(stringPtr, &length); - + length = stringPtr->length; if (sharedTextPtr == NULL) { sharedTextPtr = textPtr->sharedTextPtr; } @@ -2572,8 +2667,7 @@ InsertChars( resetViewCount = 0; if (sharedTextPtr->refCount > PIXEL_CLIENTS) { - lineAndByteIndex = (int *) - ckalloc(sizeof(int) * 2 * sharedTextPtr->refCount); + lineAndByteIndex = ckalloc(sizeof(int) * 2 * sharedTextPtr->refCount); } else { lineAndByteIndex = pixels; } @@ -2635,14 +2729,18 @@ InsertChars( resetViewCount += 2; } if (sharedTextPtr->refCount > PIXEL_CLIENTS) { - ckfree((char *) lineAndByteIndex); + ckfree(lineAndByteIndex); } /* - * Invalidate any selection retrievals in progress. + * Invalidate any selection retrievals in progress, and send an event + * that the selection changed if that is the case. */ for (tPtr = sharedTextPtr->peers; tPtr != NULL ; tPtr = tPtr->next) { + if (TkBTreeCharTagged(indexPtr, tPtr->selTagPtr)) { + TkTextSelectionEvent(tPtr); + } tPtr->abortSelections = 1; } @@ -2683,6 +2781,7 @@ TextPushUndoAction( /* Index describing second location. */ { TkUndoSubAtom *iAtom, *dAtom; + int canUndo, canRedo; /* * Create the helpers. @@ -2755,13 +2854,13 @@ TextPushUndoAction( * underlying data shared by all peers. */ - iAtom = TkUndoMakeSubAtom(&TextUndoRedoCallback, - (ClientData)textPtr->sharedTextPtr, insertCmdObj, NULL); + iAtom = TkUndoMakeSubAtom(&TextUndoRedoCallback, textPtr->sharedTextPtr, + insertCmdObj, NULL); TkUndoMakeCmdSubAtom(NULL, markSet2InsertObj, iAtom); TkUndoMakeCmdSubAtom(NULL, seeInsertObj, iAtom); - dAtom = TkUndoMakeSubAtom(&TextUndoRedoCallback, - (ClientData)textPtr->sharedTextPtr, deleteCmdObj, NULL); + dAtom = TkUndoMakeSubAtom(&TextUndoRedoCallback, textPtr->sharedTextPtr, + deleteCmdObj, NULL); TkUndoMakeCmdSubAtom(NULL, markSet1InsertObj, dAtom); TkUndoMakeCmdSubAtom(NULL, seeInsertObj, dAtom); @@ -2769,6 +2868,9 @@ TextPushUndoAction( Tcl_DecrRefCount(index1Obj); Tcl_DecrRefCount(index2Obj); + canUndo = TkUndoCanUndo(textPtr->sharedTextPtr->undoStack); + canRedo = TkUndoCanRedo(textPtr->sharedTextPtr->undoStack); + /* * Depending whether the action is to insert or delete, we provide the * appropriate second and third arguments to TkUndoPushAction. (The first @@ -2780,6 +2882,10 @@ TextPushUndoAction( } else { TkUndoPushAction(textPtr->sharedTextPtr->undoStack, dAtom, iAtom); } + + if (!canUndo || canRedo) { + GenerateUndoStackEvent(textPtr); + } } /* @@ -2810,7 +2916,7 @@ TextUndoRedoCallback( Tcl_Obj *objPtr) /* Arguments of a command to be handled by the * shared text data structure. */ { - TkSharedText *sharedPtr = (TkSharedText *) clientData; + TkSharedText *sharedPtr = clientData; int res, objc; Tcl_Obj **objv; TkText *textPtr; @@ -2875,7 +2981,7 @@ TextUndoRedoCallback( * the Tcl level. */ - return SharedTextObjCmd((ClientData)sharedPtr, interp, objc+1, objv-1); + return SharedTextObjCmd(sharedPtr, interp, objc+1, objv-1); } /* @@ -2944,7 +3050,7 @@ CountIndices( * If 'viewUpdate' is true, we may adjust the window contents' * y-position, and scrollbar setting. * - * If 'viewUpdate' is false, true we can guarantee that textPtr->topIndex + * If 'viewUpdate' is true we can guarantee that textPtr->topIndex * points to a valid TkTextLine after this function returns. However, if * 'viewUpdate' is false, then there is no such guarantee (since * topIndex.linePtr can be garbage). The caller is expected to take @@ -2974,6 +3080,9 @@ DeleteIndexRange( int *lineAndByteIndex; int resetViewCount; int pixels[2*PIXEL_CLIENTS]; + Tcl_HashSearch search; + Tcl_HashEntry *hPtr; + int i; if (sharedTextPtr == NULL) { sharedTextPtr = textPtr->sharedTextPtr; @@ -3034,46 +3143,40 @@ DeleteIndexRange( for (i = 0; i < arraySize; i++) { TkBTreeTag(&index2, &oldIndex2, arrayPtr[i], 0); } - ckfree((char *) arrayPtr); + ckfree(arrayPtr); } } - if (line1 < line2) { - /* - * We are deleting more than one line. For speed, we remove all tags - * from the range first. If we don't do this, the code below can (when - * there are many tags) grow non-linearly in execution time. - */ - - Tcl_HashSearch search; - Tcl_HashEntry *hPtr; - int i; + /* + * For speed, we remove all tags from the range first. If we don't + * do this, the code below can (when there are many tags) grow + * non-linearly in execution time. + */ - for (i=0, hPtr=Tcl_FirstHashEntry(&sharedTextPtr->tagTable, &search); - hPtr != NULL; i++, hPtr = Tcl_NextHashEntry(&search)) { - TkTextTag *tagPtr = (TkTextTag *) Tcl_GetHashValue(hPtr); + for (i=0, hPtr=Tcl_FirstHashEntry(&sharedTextPtr->tagTable, &search); + hPtr != NULL; i++, hPtr = Tcl_NextHashEntry(&search)) { + TkTextTag *tagPtr = Tcl_GetHashValue(hPtr); - TkBTreeTag(&index1, &index2, tagPtr, 0); - } + TkBTreeTag(&index1, &index2, tagPtr, 0); + } - /* - * Special case for the sel tag which is not in the hash table. We - * need to do this once for each peer text widget. - */ + /* + * Special case for the sel tag which is not in the hash table. We + * need to do this once for each peer text widget. + */ - for (tPtr = sharedTextPtr->peers; tPtr != NULL ; - tPtr = tPtr->next) { - if (TkBTreeTag(&index1, &index2, tPtr->selTagPtr, 0)) { - /* - * Send an event that the selection changed. This is - * equivalent to: - * event generate $textWidget <<Selection>> - */ + for (tPtr = sharedTextPtr->peers; tPtr != NULL ; + tPtr = tPtr->next) { + if (TkBTreeTag(&index1, &index2, tPtr->selTagPtr, 0)) { + /* + * Send an event that the selection changed. This is + * equivalent to: + * event generate $textWidget <<Selection>> + */ - TkTextSelectionEvent(textPtr); - tPtr->abortSelections = 1; - } - } + TkTextSelectionEvent(textPtr); + tPtr->abortSelections = 1; + } } /* @@ -3088,8 +3191,7 @@ DeleteIndexRange( resetViewCount = 0; if (sharedTextPtr->refCount > PIXEL_CLIENTS) { - lineAndByteIndex = (int *) - ckalloc(sizeof(int) * 2 * sharedTextPtr->refCount); + lineAndByteIndex = ckalloc(sizeof(int) * 2 * sharedTextPtr->refCount); } else { lineAndByteIndex = pixels; } @@ -3117,11 +3219,11 @@ DeleteIndexRange( resetView = 1; line = line1; byteIndex = tPtr->topIndex.byteIndex; - } else { - /* - * Deletion range starts after the top line. This peers's view - * will not need to be reset. Nothing to do. - */ + } else { + /* + * Deletion range starts after the top line. This peers's view + * will not need to be reset. Nothing to do. + */ } } else if (index2.linePtr == tPtr->topIndex.linePtr) { /* @@ -3138,11 +3240,11 @@ DeleteIndexRange( } else { byteIndex -= (index2.byteIndex - index1.byteIndex); } - } else { - /* - * Deletion range ends before the top line. This peers's view - * will not need to be reset. Nothing to do. - */ + } else { + /* + * Deletion range ends before the top line. This peers's view + * will not need to be reset. Nothing to do. + */ } if (resetView) { lineAndByteIndex[resetViewCount] = line; @@ -3150,7 +3252,7 @@ DeleteIndexRange( } else { lineAndByteIndex[resetViewCount] = -1; } - resetViewCount+=2; + resetViewCount += 2; } /* @@ -3187,50 +3289,50 @@ DeleteIndexRange( TkTextIndex indexTmp; if (tPtr == textPtr) { - if (viewUpdate) { - /* - * line cannot be before -startline of textPtr because - * this line corresponds to an index which is necessarily - * between "1.0" and "end" relative to textPtr. - * Therefore no need to clamp line to the -start/-end - * range. - */ + if (viewUpdate) { + /* + * line cannot be before -startline of textPtr because + * this line corresponds to an index which is necessarily + * between "1.0" and "end" relative to textPtr. + * Therefore no need to clamp line to the -start/-end + * range. + */ TkTextMakeByteIndex(sharedTextPtr->tree, textPtr, line, byteIndex, &indexTmp); TkTextSetYView(tPtr, &indexTmp, 0); } } else { - TkTextMakeByteIndex(sharedTextPtr->tree, tPtr, line, + TkTextMakeByteIndex(sharedTextPtr->tree, tPtr, line, byteIndex, &indexTmp); - /* - * line may be before -startline of tPtr and must be - * clamped to -startline before providing it to - * TkTextSetYView otherwise lines before -startline - * would be displayed. - * There is no need to worry about -endline however, - * because the view will only be reset if the deletion - * involves the TOP line of the screen - */ - - if (tPtr->start != NULL) { - int start; - TkTextIndex indexStart; - - start = TkBTreeLinesTo(NULL, tPtr->start); - TkTextMakeByteIndex(sharedTextPtr->tree, NULL, start, + /* + * line may be before -startline of tPtr and must be + * clamped to -startline before providing it to + * TkTextSetYView otherwise lines before -startline + * would be displayed. + * There is no need to worry about -endline however, + * because the view will only be reset if the deletion + * involves the TOP line of the screen + */ + + if (tPtr->start != NULL) { + int start; + TkTextIndex indexStart; + + start = TkBTreeLinesTo(NULL, tPtr->start); + TkTextMakeByteIndex(sharedTextPtr->tree, NULL, start, 0, &indexStart); - if (TkTextIndexCmp(&indexTmp, &indexStart) < 0) { - indexTmp = indexStart; - } - } + if (TkTextIndexCmp(&indexTmp, &indexStart) < 0) { + indexTmp = indexStart; + } + } TkTextSetYView(tPtr, &indexTmp, 0); } } resetViewCount += 2; } if (sharedTextPtr->refCount > PIXEL_CLIENTS) { - ckfree((char *) lineAndByteIndex); + ckfree(lineAndByteIndex); } if (line1 >= line2) { @@ -3278,13 +3380,13 @@ TextFetchSelection( * not including terminating NULL * character. */ { - register TkText *textPtr = (TkText *) clientData; + register TkText *textPtr = clientData; TkTextIndex eof; int count, chunkSize, offsetInSeg; TkTextSearch search; TkTextSegment *segPtr; - if (!textPtr->exportSelection) { + if ((!textPtr->exportSelection) || Tcl_IsSafe(textPtr->interp)) { return -1; } @@ -3409,12 +3511,12 @@ void TkTextLostSelection( ClientData clientData) /* Information about text widget. */ { - register TkText *textPtr = (TkText *) clientData; + register TkText *textPtr = clientData; if (TkpAlwaysShowSelection(textPtr->tkwin)) { TkTextIndex start, end; - if (!textPtr->exportSelection) { + if ((!textPtr->exportSelection) || Tcl_IsSafe(textPtr->interp)) { return; } @@ -3469,16 +3571,7 @@ TkTextSelectionEvent( * event generate $textWidget <<Selection>> */ - union {XEvent general; XVirtualEvent virtual;} event; - - memset(&event, 0, sizeof(event)); - event.general.xany.type = VirtualEvent; - event.general.xany.serial = NextRequest(Tk_Display(textPtr->tkwin)); - event.general.xany.send_event = False; - event.general.xany.window = Tk_WindowId(textPtr->tkwin); - event.general.xany.display = Tk_Display(textPtr->tkwin); - event.virtual.name = Tk_GetUid("Selection"); - Tk_HandleEvent(&event.general); + TkSendVirtualEvent(textPtr->tkwin, "Selection", NULL); } /* @@ -3503,12 +3596,22 @@ static void TextBlinkProc( ClientData clientData) /* Pointer to record describing text. */ { - register TkText *textPtr = (TkText *) clientData; + register TkText *textPtr = clientData; TkTextIndex index; int x, y, w, h, charWidth; if ((textPtr->state == TK_TEXT_STATE_DISABLED) || !(textPtr->flags & GOT_FOCUS) || (textPtr->insertOffTime == 0)) { + if (!(textPtr->flags & GOT_FOCUS) && + (textPtr->insertUnfocussed != TK_TEXT_INSERT_NOFOCUS_NONE)) { + /* + * The widget doesn't have the focus yet it is configured to + * display the cursor when it doesn't have the focus. Act now! + */ + + textPtr->flags |= INSERT_ON; + goto redrawInsert; + } if ((textPtr->insertOffTime == 0) && !(textPtr->flags & INSERT_ON)) { /* * The widget was configured to have zero offtime while the @@ -3523,11 +3626,11 @@ TextBlinkProc( if (textPtr->flags & INSERT_ON) { textPtr->flags &= ~INSERT_ON; textPtr->insertBlinkHandler = Tcl_CreateTimerHandler( - textPtr->insertOffTime, TextBlinkProc, (ClientData) textPtr); + textPtr->insertOffTime, TextBlinkProc, textPtr); } else { textPtr->flags |= INSERT_ON; textPtr->insertBlinkHandler = Tcl_CreateTimerHandler( - textPtr->insertOnTime, TextBlinkProc, (ClientData) textPtr); + textPtr->insertOnTime, TextBlinkProc, textPtr); } redrawInsert: TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index); @@ -3606,7 +3709,7 @@ TextInsertCmd( for (i = 0; i < numTags; i++) { TkBTreeTag(&index1, &index2, oldTagArrayPtr[i], 0); } - ckfree((char *) oldTagArrayPtr); + ckfree(oldTagArrayPtr); } if (Tcl_ListObjGetElements(interp, objv[j+1], &numTags, &tagNamePtrs) != TCL_OK) { @@ -3654,15 +3757,16 @@ TextSearchCmd( int i, argsLeft, code; SearchSpec searchSpec; - static const char *switchStrings[] = { + static const char *const switchStrings[] = { + "-hidden", "--", "-all", "-backwards", "-count", "-elide", "-exact", "-forwards", - "-hidden", "-nocase", "-nolinestop", "-overlap", "-regexp", - "-strictlimits", NULL + "-nocase", "-nolinestop", "-overlap", "-regexp", "-strictlimits", NULL }; enum SearchSwitches { - SEARCH_END, SEARCH_ALL, SEARCH_BACK, SEARCH_COUNT, SEARCH_ELIDE, - SEARCH_EXACT, SEARCH_FWD, SEARCH_HIDDEN, SEARCH_NOCASE, - SEARCH_NOLINESTOP, SEARCH_OVERLAP, SEARCH_REGEXP, SEARCH_STRICTLIMITS + TK_TEXT_SEARCH_HIDDEN, + TK_TEXT_SEARCH_END, TK_TEXT_SEARCH_ALL, TK_TEXT_SEARCH_BACK, TK_TEXT_SEARCH_COUNT, TK_TEXT_SEARCH_ELIDE, + TK_TEXT_SEARCH_EXACT, TK_TEXT_SEARCH_FWD, TK_TEXT_SEARCH_NOCASE, + TK_TEXT_SEARCH_NOLINESTOP, TK_TEXT_SEARCH_OVERLAP, TK_TEXT_SEARCH_REGEXP, TK_TEXT_SEARCH_STRICTLIMITS }; /* @@ -3683,7 +3787,7 @@ TextSearchCmd( searchSpec.strictLimits = 0; searchSpec.numLines = TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr); - searchSpec.clientData = (ClientData)textPtr; + searchSpec.clientData = textPtr; searchSpec.addLineProc = &TextSearchAddNextLine; searchSpec.foundMatchProc = &TextSearchFoundMatch; searchSpec.lineIndexProc = &TextSearchGetLineIndex; @@ -3694,38 +3798,38 @@ TextSearchCmd( for (i=2 ; i<objc ; i++) { int index; + if (Tcl_GetString(objv[i])[0] != '-') { break; } - if (Tcl_GetIndexFromObj(interp, objv[i], switchStrings, "switch", 0, - &index) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(NULL, objv[i], switchStrings, + sizeof(char *), "switch", 0, &index) != TCL_OK) { /* - * Hide the -hidden option. + * Hide the -hidden option, generating the error description with + * the side effects of T_GIFO. */ - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "bad switch \"", Tcl_GetString(objv[i]), - "\": must be --, -all, -backward, -count, -elide, ", - "-exact, -forward, -nocase, -nolinestop, -overlap, ", - "-regexp, or -strictlimits", NULL); + (void) Tcl_GetIndexFromObjStruct(interp, objv[i], switchStrings+1, + sizeof(char *), "switch", 0, &index); return TCL_ERROR; } switch ((enum SearchSwitches) index) { - case SEARCH_END: + case TK_TEXT_SEARCH_END: i++; goto endOfSwitchProcessing; - case SEARCH_ALL: + case TK_TEXT_SEARCH_ALL: searchSpec.all = 1; break; - case SEARCH_BACK: + case TK_TEXT_SEARCH_BACK: searchSpec.backwards = 1; break; - case SEARCH_COUNT: + case TK_TEXT_SEARCH_COUNT: if (i >= objc-1) { - Tcl_SetResult(interp, "no value given for \"-count\" option", - TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "no value given for \"-count\" option", -1)); + Tcl_SetErrorCode(interp, "TK", "TEXT", "VALUE", NULL); return TCL_ERROR; } i++; @@ -3737,29 +3841,29 @@ TextSearchCmd( searchSpec.varPtr = objv[i]; break; - case SEARCH_ELIDE: - case SEARCH_HIDDEN: + case TK_TEXT_SEARCH_ELIDE: + case TK_TEXT_SEARCH_HIDDEN: searchSpec.searchElide = 1; break; - case SEARCH_EXACT: + case TK_TEXT_SEARCH_EXACT: searchSpec.exact = 1; break; - case SEARCH_FWD: + case TK_TEXT_SEARCH_FWD: searchSpec.backwards = 0; break; - case SEARCH_NOCASE: + case TK_TEXT_SEARCH_NOCASE: searchSpec.noCase = 1; break; - case SEARCH_NOLINESTOP: + case TK_TEXT_SEARCH_NOLINESTOP: searchSpec.noLineStop = 1; break; - case SEARCH_OVERLAP: + case TK_TEXT_SEARCH_OVERLAP: searchSpec.overlap = 1; break; - case SEARCH_STRICTLIMITS: + case TK_TEXT_SEARCH_STRICTLIMITS: searchSpec.strictLimits = 1; break; - case SEARCH_REGEXP: + case TK_TEXT_SEARCH_REGEXP: searchSpec.exact = 0; break; default: @@ -3776,14 +3880,18 @@ TextSearchCmd( } if (searchSpec.noLineStop && searchSpec.exact) { - Tcl_SetResult(interp, "the \"-nolinestop\" option requires the " - "\"-regexp\" option to be present", TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "the \"-nolinestop\" option requires the \"-regexp\" option" + " to be present", -1)); + Tcl_SetErrorCode(interp, "TK", "TEXT", "SEARCH_USAGE", NULL); return TCL_ERROR; } if (searchSpec.overlap && !searchSpec.all) { - Tcl_SetResult(interp, "the \"-overlap\" option requires the " - "\"-all\" option to be present", TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "the \"-overlap\" option requires the \"-all\" option" + " to be present", -1)); + Tcl_SetErrorCode(interp, "TK", "TEXT", "SEARCH_USAGE", NULL); return TCL_ERROR; } @@ -3868,7 +3976,7 @@ TextSearchGetLineIndex( { const TkTextIndex *indexPtr; int line; - TkText *textPtr = (TkText *) searchSpecPtr->clientData; + TkText *textPtr = searchSpecPtr->clientData; indexPtr = TkTextGetIndexFromObj(interp, textPtr, objPtr); if (indexPtr == NULL) { @@ -3933,7 +4041,7 @@ TextSearchIndexInLine( TkTextSegment *segPtr; TkTextIndex curIndex; int index, leftToScan; - TkText *textPtr = (TkText *) searchSpecPtr->clientData; + TkText *textPtr = searchSpecPtr->clientData; index = 0; curIndex.tree = textPtr->sharedTextPtr->tree; @@ -4003,7 +4111,7 @@ TextSearchAddNextLine( TkTextLine *linePtr, *thisLinePtr; TkTextIndex curIndex; TkTextSegment *segPtr; - TkText *textPtr = (TkText *) searchSpecPtr->clientData; + TkText *textPtr = searchSpecPtr->clientData; int nothingYet = 1; /* @@ -4075,12 +4183,13 @@ TextSearchAddNextLine( if (lenPtr != NULL) { if (searchSpecPtr->exact) { - Tcl_GetStringFromObj(theLine, lenPtr); + Tcl_GetString(theLine); + *lenPtr = theLine->length; } else { *lenPtr = Tcl_GetCharLength(theLine); } } - return (ClientData)linePtr; + return linePtr; } /* @@ -4124,7 +4233,7 @@ TextSearchFoundMatch( TkTextIndex curIndex, foundIndex; TkTextSegment *segPtr; TkTextLine *linePtr; - TkText *textPtr = (TkText *) searchSpecPtr->clientData; + TkText *textPtr = searchSpecPtr->clientData; if (lineNum == searchSpecPtr->stopLine) { /* @@ -4175,7 +4284,7 @@ TextSearchFoundMatch( * reached the end of the match or we have reached the end of the line. */ - linePtr = (TkTextLine *)clientData; + linePtr = clientData; if (linePtr == NULL) { linePtr = TkBTreeFindLine(textPtr->sharedTextPtr->tree, textPtr, lineNum); @@ -4355,12 +4464,12 @@ TkTextGetTabs( Tcl_Obj **objv; TkTextTabArray *tabArrayPtr; TkTextTab *tabPtr; - Tcl_UniChar ch; + int ch; double prevStop, lastStop; /* * Map these strings to TkTextTabAlign values. */ - static const char *tabOptionStrings[] = { + static const char *const tabOptionStrings[] = { "left", "right", "center", "numeric", NULL }; @@ -4375,6 +4484,7 @@ TkTextGetTabs( count = 0; for (i = 0; i < objc; i++) { char c = Tcl_GetString(objv[i])[0]; + if ((c != 'l') && (c != 'r') && (c != 'c') && (c != 'n')) { count++; } @@ -4384,8 +4494,8 @@ TkTextGetTabs( * Parse the elements of the list one at a time to fill in the array. */ - tabArrayPtr = (TkTextTabArray *) ckalloc((unsigned) - (sizeof(TkTextTabArray) + (count-1)*sizeof(TkTextTab))); + tabArrayPtr = ckalloc(sizeof(TkTextTabArray) + + (count - 1) * sizeof(TkTextTab)); tabArrayPtr->numTabs = 0; prevStop = 0.0; lastStop = 0.0; @@ -4403,14 +4513,16 @@ TkTextGetTabs( } if (tabPtr->location <= 0) { - Tcl_AppendResult(interp, "tab stop \"", Tcl_GetString(objv[i]), - "\" is not at a positive distance", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "tab stop \"%s\" is not at a positive distance", + Tcl_GetString(objv[i]))); + Tcl_SetErrorCode(interp, "TK", "VALUE", "TAB_STOP", NULL); goto error; } prevStop = lastStop; - if (Tk_GetDoublePixelsFromObj (interp, textPtr->tkwin, objv[i], - &lastStop) != TCL_OK) { + if (Tk_GetDoublePixelsFromObj(interp, textPtr->tkwin, objv[i], + &lastStop) != TCL_OK) { goto error; } @@ -4434,11 +4546,11 @@ TkTextGetTabs( } lastStop = tabPtr->location; #else - Tcl_AppendResult(interp, - "tabs must be monotonically increasing, but \"", - Tcl_GetString(objv[i]), - "\" is smaller than or equal to the previous tab", - NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "tabs must be monotonically increasing, but \"%s\" is " + "smaller than or equal to the previous tab", + Tcl_GetString(objv[i]))); + Tcl_SetErrorCode(interp, "TK", "VALUE", "TAB_STOP", NULL); goto error; #endif /* _TK_ALLOW_DECREASING_TABS */ } @@ -4459,17 +4571,17 @@ 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; } i += 1; - if (Tcl_GetIndexFromObj(interp, objv[i], tabOptionStrings, - "tab alignment", 0, &index) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[i], tabOptionStrings, + sizeof(char *), "tab alignment", 0, &index) != TCL_OK) { goto error; } - tabPtr->alignment = ((TkTextTabAlign)index); + tabPtr->alignment = (TkTextTabAlign) index; } /* @@ -4484,7 +4596,7 @@ TkTextGetTabs( return tabArrayPtr; error: - ckfree((char *) tabArrayPtr); + ckfree(tabArrayPtr); return NULL; } @@ -4530,7 +4642,7 @@ TextDumpCmd( #define TK_DUMP_IMG 0x10 #define TK_DUMP_ALL (TK_DUMP_TEXT|TK_DUMP_MARK|TK_DUMP_TAG| \ TK_DUMP_WIN|TK_DUMP_IMG) - static const char *optStrings[] = { + static const char *const optStrings[] = { "-all", "-command", "-image", "-mark", "-tag", "-text", "-window", NULL }; @@ -4543,8 +4655,8 @@ TextDumpCmd( if (Tcl_GetString(objv[arg])[0] != '-') { break; } - if (Tcl_GetIndexFromObj(interp, objv[arg], optStrings, "option", 0, - &index) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[arg], optStrings, + sizeof(char *), "option", 0, &index) != TCL_OK) { return TCL_ERROR; } switch ((enum opts) index) { @@ -4569,10 +4681,7 @@ TextDumpCmd( case DUMP_CMD: arg++; if (arg >= objc) { - Tcl_AppendResult(interp, "Usage: ", Tcl_GetString(objv[0]), - " dump ?-all -image -text -mark -tag -window? ", - "?-command script? index ?index2?", NULL); - return TCL_ERROR; + goto wrongArgs; } command = objv[arg]; break; @@ -4581,9 +4690,11 @@ TextDumpCmd( } } if (arg >= objc || arg+2 < objc) { - Tcl_AppendResult(interp, "Usage: ", Tcl_GetString(objv[0]), - " dump ?-all -image -text -mark -tag -window? ", - "?-command script? index ?index2?", NULL); + wrongArgs: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "Usage: %s dump ?-all -image -text -mark -tag -window? " + "?-command script? index ?index2?", Tcl_GetString(objv[0]))); + Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL); return TCL_ERROR; } if (what == 0) { @@ -4597,14 +4708,15 @@ TextDumpCmd( if (objc == arg) { TkTextIndexForwChars(NULL, &index1, 1, &index2, COUNT_INDICES); } else { - int length; - char *str; + size_t length; + const char *str; if (TkTextGetObjIndex(interp, textPtr, objv[arg], &index2) != TCL_OK) { return TCL_ERROR; } - str = Tcl_GetStringFromObj(objv[arg], &length); - if (strncmp(str, "end", (unsigned)length) == 0) { + str = Tcl_GetString(objv[arg]); + length = objv[arg]->length; + if (strncmp(str, "end", length) == 0) { atEnd = 1; } } @@ -4637,8 +4749,8 @@ TextDumpCmd( if (lineno == lineend) { break; } - textChanged = DumpLine(interp, textPtr, what, linePtr, 0, 32000000, - lineno, command); + textChanged = DumpLine(interp, textPtr, what, linePtr, 0, + 32000000, lineno, command); if (textChanged) { if (textPtr->flags & DESTROYED) { return TCL_OK; @@ -4747,10 +4859,9 @@ DumpLine( */ int length = last - first; - char *range = ckalloc((length + 1) * sizeof(char)); + char *range = ckalloc(length + 1); - memcpy(range, segPtr->body.chars + first, - length * sizeof(char)); + memcpy(range, segPtr->body.chars + first, length); range[length] = '\0'; TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, @@ -4765,9 +4876,11 @@ DumpLine( segPtr->body.chars + first, command, &index, what); } } else if ((offset >= startByte)) { - if ((what & TK_DUMP_MARK) && (segPtr->typePtr->name[0] == 'm')) { - char *name; - TkTextMark *markPtr = (TkTextMark *) &segPtr->body; + if ((what & TK_DUMP_MARK) + && (segPtr->typePtr == &tkTextLeftMarkType + || segPtr->typePtr == &tkTextRightMarkType)) { + const char *name; + TkTextMark *markPtr = &segPtr->body.mark; if (segPtr == textPtr->insertMarkPtr) { name = "insert"; @@ -4801,18 +4914,18 @@ DumpLine( segPtr->body.toggle.tagPtr->name, command, &index, what); } else if ((what & TK_DUMP_IMG) && - (segPtr->typePtr->name[0] == 'i')) { - TkTextEmbImage *eiPtr = (TkTextEmbImage *)&segPtr->body; - char *name = (eiPtr->name == NULL) ? "" : eiPtr->name; + (segPtr->typePtr == &tkTextEmbImageType)) { + TkTextEmbImage *eiPtr = &segPtr->body.ei; + const char *name = (eiPtr->name == NULL) ? "" : eiPtr->name; TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, lineno, offset, &index); lineChanged = DumpSegment(textPtr, interp, "image", name, command, &index, what); } else if ((what & TK_DUMP_WIN) && - (segPtr->typePtr->name[0] == 'w')) { - TkTextEmbWindow *ewPtr = (TkTextEmbWindow *)&segPtr->body; - char *pathname; + (segPtr->typePtr == &tkTextEmbWindowType)) { + TkTextEmbWindow *ewPtr = &segPtr->body.ew; + const char *pathname; if (ewPtr->tkwin == (Tk_Window) NULL) { pathname = ""; @@ -4825,6 +4938,7 @@ DumpLine( command, &index, what); } } + offset += currentSize; if (lineChanged) { TkTextSegment *newSegPtr; @@ -4842,9 +4956,7 @@ DumpLine( linePtr = TkBTreeFindLine(textPtr->sharedTextPtr->tree, textPtr, lineno); newSegPtr = linePtr->segPtr; - if (segPtr == newSegPtr) { - segPtr = segPtr->nextPtr; - } else { + if (segPtr != newSegPtr) { while ((newOffset < endByte) && (newOffset < offset) && (newSegPtr != NULL)) { newOffset += currentSize; @@ -4866,11 +4978,9 @@ DumpLine( } } segPtr = newSegPtr; - if (segPtr != NULL) { - segPtr = segPtr->nextPtr; - } } - } else { + } + if (segPtr != NULL) { segPtr = segPtr->nextPtr; } } @@ -4909,31 +5019,36 @@ DumpSegment( int what) /* Look for TK_DUMP_INDEX bit. */ { char buffer[TK_POS_CHARS]; + Tcl_Obj *values[3], *tuple; TkTextPrintIndex(textPtr, index, buffer); + values[0] = Tcl_NewStringObj(key, -1); + values[1] = Tcl_NewStringObj(value, -1); + values[2] = Tcl_NewStringObj(buffer, -1); + tuple = Tcl_NewListObj(3, values); if (command == NULL) { - Tcl_AppendElement(interp, key); - Tcl_AppendElement(interp, value); - Tcl_AppendElement(interp, buffer); + Tcl_ListObjAppendList(NULL, Tcl_GetObjResult(interp), tuple); + Tcl_DecrRefCount(tuple); return 0; } else { - const char *argv[4]; - char *list; int oldStateEpoch = TkBTreeEpoch(textPtr->sharedTextPtr->tree); - - argv[0] = key; - argv[1] = value; - argv[2] = buffer; - argv[3] = NULL; - list = Tcl_Merge(3, argv); - Tcl_VarEval(interp, Tcl_GetString(command), " ", list, NULL); - ckfree(list); - if ((textPtr->flags & DESTROYED) || - TkBTreeEpoch(textPtr->sharedTextPtr->tree) != oldStateEpoch) { - return 1; - } else { - return 0; - } + Tcl_DString buf; + int code; + + Tcl_DStringInit(&buf); + Tcl_DStringAppend(&buf, Tcl_GetString(command), -1); + Tcl_DStringAppend(&buf, " ", -1); + Tcl_DStringAppend(&buf, Tcl_GetString(tuple), -1); + code = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, 0); + Tcl_DStringFree(&buf); + if (code != TCL_OK) { + Tcl_AddErrorInfo(interp, + "\n (segment dumping command executed by text)"); + Tcl_BackgroundException(interp, code); + } + Tcl_DecrRefCount(tuple); + return ((textPtr->flags & DESTROYED) || + TkBTreeEpoch(textPtr->sharedTextPtr->tree) != oldStateEpoch); } } @@ -5056,63 +5171,84 @@ TextEditCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - int index; + int index, setModified, oldModified; + int canRedo = 0; + int canUndo = 0; - static const char *editOptionStrings[] = { - "modified", "redo", "reset", "separator", "undo", NULL + static const char *const editOptionStrings[] = { + "canundo", "canredo", "modified", "redo", "reset", "separator", + "undo", NULL }; enum editOptions { - EDIT_MODIFIED, EDIT_REDO, EDIT_RESET, EDIT_SEPARATOR, EDIT_UNDO + EDIT_CANUNDO, EDIT_CANREDO, EDIT_MODIFIED, EDIT_REDO, EDIT_RESET, + EDIT_SEPARATOR, EDIT_UNDO }; if (objc < 3) { - Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?"); + Tcl_WrongNumArgs(interp, 2, objv, "option ?arg ...?"); return TCL_ERROR; } - if (Tcl_GetIndexFromObj(interp, objv[2], editOptionStrings, - "edit option", 0, &index) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[2], editOptionStrings, + sizeof(char *), "edit option", 0, &index) != TCL_OK) { return TCL_ERROR; } switch ((enum editOptions) index) { + case EDIT_CANREDO: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 3, objv, NULL); + return TCL_ERROR; + } + if (textPtr->sharedTextPtr->undo) { + canRedo = TkUndoCanRedo(textPtr->sharedTextPtr->undoStack); + } + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(canRedo)); + break; + case EDIT_CANUNDO: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 3, objv, NULL); + return TCL_ERROR; + } + if (textPtr->sharedTextPtr->undo) { + canUndo = TkUndoCanUndo(textPtr->sharedTextPtr->undoStack); + } + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(canUndo)); + break; case EDIT_MODIFIED: if (objc == 3) { Tcl_SetObjResult(interp, Tcl_NewBooleanObj(textPtr->sharedTextPtr->isDirty)); + return TCL_OK; } else if (objc != 4) { Tcl_WrongNumArgs(interp, 3, objv, "?boolean?"); return TCL_ERROR; - } else { - int setModified, oldModified; - - if (Tcl_GetBooleanFromObj(interp, objv[3], - &setModified) != TCL_OK) { - return TCL_ERROR; - } + } else if (Tcl_GetBooleanFromObj(interp, objv[3], + &setModified) != TCL_OK) { + return TCL_ERROR; + } - /* - * Set or reset the dirty info, and trigger a Modified event. - */ + /* + * Set or reset the dirty info, and trigger a Modified event. + */ - setModified = setModified ? 1 : 0; + setModified = setModified ? 1 : 0; - oldModified = textPtr->sharedTextPtr->isDirty; - textPtr->sharedTextPtr->isDirty = setModified; - if (setModified) { - textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_FIXED; - } else { - textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL; - } + oldModified = textPtr->sharedTextPtr->isDirty; + textPtr->sharedTextPtr->isDirty = setModified; + if (setModified) { + textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_FIXED; + } else { + textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL; + } - /* - * Only issue the <<Modified>> event if the flag actually changed. - * However, degree of modified-ness doesn't matter. [Bug 1799782] - */ + /* + * Only issue the <<Modified>> event if the flag actually changed. + * However, degree of modified-ness doesn't matter. [Bug 1799782] + */ - if ((!oldModified) != (!setModified)) { - GenerateModifiedEvent(textPtr); - } + if ((!oldModified) != (!setModified)) { + GenerateModifiedEvent(textPtr); } break; case EDIT_REDO: @@ -5120,17 +5256,28 @@ TextEditCmd( Tcl_WrongNumArgs(interp, 3, objv, NULL); return TCL_ERROR; } + canUndo = TkUndoCanUndo(textPtr->sharedTextPtr->undoStack); if (TextEditRedo(textPtr)) { - Tcl_AppendResult(interp, "nothing to redo", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj("nothing to redo", -1)); + Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_REDO", NULL); return TCL_ERROR; } + canRedo = TkUndoCanRedo(textPtr->sharedTextPtr->undoStack); + if (!canUndo || !canRedo) { + GenerateUndoStackEvent(textPtr); + } break; case EDIT_RESET: if (objc != 3) { Tcl_WrongNumArgs(interp, 3, objv, NULL); return TCL_ERROR; } + canUndo = TkUndoCanUndo(textPtr->sharedTextPtr->undoStack); + canRedo = TkUndoCanRedo(textPtr->sharedTextPtr->undoStack); TkUndoClearStacks(textPtr->sharedTextPtr->undoStack); + if (canUndo || canRedo) { + GenerateUndoStackEvent(textPtr); + } break; case EDIT_SEPARATOR: if (objc != 3) { @@ -5144,10 +5291,16 @@ TextEditCmd( Tcl_WrongNumArgs(interp, 3, objv, NULL); return TCL_ERROR; } + canRedo = TkUndoCanRedo(textPtr->sharedTextPtr->undoStack); if (TextEditUndo(textPtr)) { - Tcl_AppendResult(interp, "nothing to undo", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj("nothing to undo", -1)); + Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_UNDO", NULL); return TCL_ERROR; } + canUndo = TkUndoCanUndo(textPtr->sharedTextPtr->undoStack); + if (!canRedo || !canUndo) { + GenerateUndoStackEvent(textPtr); + } break; } return TCL_OK; @@ -5205,11 +5358,10 @@ TextGetText( if (TkTextIndexCmp(indexPtr1, indexPtr2) < 0) { while (1) { - int offset, last; - TkTextSegment *segPtr; + int offset; + TkTextSegment *segPtr = TkTextIndexToSeg(&tmpIndex, &offset); + int last = segPtr->size, last2; - segPtr = TkTextIndexToSeg(&tmpIndex, &offset); - last = segPtr->size; if (tmpIndex.linePtr == indexPtr2->linePtr) { /* * The last line that was requested must be handled carefully, @@ -5219,21 +5371,17 @@ TextGetText( if (indexPtr2->byteIndex == tmpIndex.byteIndex) { break; - } else { - int last2 = indexPtr2->byteIndex - tmpIndex.byteIndex - + offset; - - if (last2 < last) { - last = last2; - } } - } - if (segPtr->typePtr == &tkTextCharType) { - if (!visibleOnly || !TkTextIsElided(textPtr,&tmpIndex,NULL)) { - Tcl_AppendToObj(resultPtr, segPtr->body.chars + offset, - last - offset); + last2 = indexPtr2->byteIndex - tmpIndex.byteIndex + offset; + if (last2 < last) { + last = last2; } } + if (segPtr->typePtr == &tkTextCharType && + !(visibleOnly && TkTextIsElided(textPtr,&tmpIndex,NULL))){ + Tcl_AppendToObj(resultPtr, segPtr->body.chars + offset, + last - offset); + } TkTextIndexForwBytes(textPtr, &tmpIndex, last-offset, &tmpIndex); } } @@ -5245,8 +5393,9 @@ TextGetText( * * GenerateModifiedEvent -- * - * Send an event that the text was modified. This is equivalent to + * Send an event that the text was modified. This is equivalent to: * event generate $textWidget <<Modified>> + * for all peers of $textWidget. * * Results: * None @@ -5261,18 +5410,41 @@ static void GenerateModifiedEvent( TkText *textPtr) /* Information about text widget. */ { - union {XEvent general; XVirtualEvent virtual;} event; - - Tk_MakeWindowExist(textPtr->tkwin); - - memset(&event, 0, sizeof(event)); - event.general.xany.type = VirtualEvent; - event.general.xany.serial = NextRequest(Tk_Display(textPtr->tkwin)); - event.general.xany.send_event = False; - event.general.xany.window = Tk_WindowId(textPtr->tkwin); - event.general.xany.display = Tk_Display(textPtr->tkwin); - event.virtual.name = Tk_GetUid("Modified"); - Tk_HandleEvent(&event.general); + for (textPtr = textPtr->sharedTextPtr->peers; textPtr != NULL; + textPtr = textPtr->next) { + Tk_MakeWindowExist(textPtr->tkwin); + TkSendVirtualEvent(textPtr->tkwin, "Modified", NULL); + } +} + +/* + *---------------------------------------------------------------------- + * + * GenerateUndoStackEvent -- + * + * Send an event that the undo or redo stack became empty or unempty. + * This is equivalent to: + * event generate $textWidget <<UndoStack>> + * for all peers of $textWidget. + * + * Results: + * None + * + * Side effects: + * May force the text window (and all peers) into existence. + * + *---------------------------------------------------------------------- + */ + +static void +GenerateUndoStackEvent( + TkText *textPtr) /* Information about text widget. */ +{ + for (textPtr = textPtr->sharedTextPtr->peers; textPtr != NULL; + textPtr = textPtr->next) { + Tk_MakeWindowExist(textPtr->tkwin); + TkSendVirtualEvent(textPtr->tkwin, "UndoStack", NULL); + } } /* @@ -5296,7 +5468,6 @@ UpdateDirtyFlag( TkSharedText *sharedTextPtr)/* Information about text widget. */ { int oldDirtyFlag; - TkText *textPtr; /* * If we've been forced to be dirty, we stay dirty (until explicitly @@ -5327,11 +5498,54 @@ UpdateDirtyFlag( } if (sharedTextPtr->isDirty == 0 || oldDirtyFlag == 0) { - for (textPtr = sharedTextPtr->peers; textPtr != NULL; - textPtr = textPtr->next) { - GenerateModifiedEvent(textPtr); + GenerateModifiedEvent(sharedTextPtr->peers); + } +} + +/* + *---------------------------------------------------------------------- + * + * TkTextRunAfterSyncCmd -- + * + * This function is called by the event loop and executes the command + * scheduled by [.text sync -command $cmd]. + * + * Results: + * None. + * + * Side effects: + * Anything may happen, depending on $cmd contents. + * + *---------------------------------------------------------------------- + */ + +void +TkTextRunAfterSyncCmd( + ClientData clientData) /* Information about text widget. */ +{ + register TkText *textPtr = (TkText *) clientData; + int code; + + if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) { + /* + * The widget has been deleted. Don't do anything. + */ + + if (textPtr->refCount-- <= 1) { + ckfree((char *) textPtr); } + return; + } + + Tcl_Preserve((ClientData) textPtr->interp); + code = Tcl_EvalObjEx(textPtr->interp, textPtr->afterSyncCmd, TCL_EVAL_GLOBAL); + if (code == TCL_ERROR) { + Tcl_AddErrorInfo(textPtr->interp, "\n (text sync)"); + Tcl_BackgroundError(textPtr->interp); } + Tcl_Release((ClientData) textPtr->interp); + Tcl_DecrRefCount(textPtr->afterSyncCmd); + textPtr->afterSyncCmd = NULL; } /* @@ -5371,7 +5585,7 @@ SearchPerform( * for regexp search, utf-8 bytes for exact search). */ - if ((*searchSpecPtr->lineIndexProc)(interp, fromPtr, searchSpecPtr, + if (searchSpecPtr->lineIndexProc(interp, fromPtr, searchSpecPtr, &searchSpecPtr->startLine, &searchSpecPtr->startOffset) != TCL_OK) { return TCL_ERROR; @@ -5383,7 +5597,7 @@ SearchPerform( if (toPtr != NULL) { const TkTextIndex *indexToPtr, *indexFromPtr; - TkText *textPtr = (TkText *) searchSpecPtr->clientData; + TkText *textPtr = searchSpecPtr->clientData; indexToPtr = TkTextGetIndexFromObj(interp, textPtr, toPtr); if (indexToPtr == NULL) { @@ -5397,17 +5611,12 @@ SearchPerform( * wrap when given a negative search range). */ - if (searchSpecPtr->backwards) { - if (TkTextIndexCmp(indexFromPtr, indexToPtr) == -1) { - return TCL_OK; - } - } else { - if (TkTextIndexCmp(indexFromPtr, indexToPtr) == 1) { - return TCL_OK; - } + if (TkTextIndexCmp(indexFromPtr, indexToPtr) == + (searchSpecPtr->backwards ? -1 : 1)) { + return TCL_OK; } - if ((*searchSpecPtr->lineIndexProc)(interp, toPtr, searchSpecPtr, + if (searchSpecPtr->lineIndexProc(interp, toPtr, searchSpecPtr, &searchSpecPtr->stopLine, &searchSpecPtr->stopOffset) != TCL_OK) { return TCL_ERROR; @@ -5542,7 +5751,8 @@ SearchCore( * it has dual purpose. */ - pattern = Tcl_GetStringFromObj(patObj, &matchLength); + pattern = Tcl_GetString(patObj); + matchLength = patObj->length; nl = strchr(pattern, '\n'); /* @@ -5593,8 +5803,8 @@ SearchCore( * this line, which is what 'lastOffset' represents. */ - lineInfo = (*searchSpecPtr->addLineProc)(lineNum, searchSpecPtr, - theLine, &lastOffset, &linesSearched); + lineInfo = searchSpecPtr->addLineProc(lineNum, searchSpecPtr, theLine, + &lastOffset, &linesSearched); if (lineInfo == NULL) { /* @@ -5612,7 +5822,7 @@ SearchCore( firstOffset = 0; } - if (alreadySearchOffset != -1) { + if (alreadySearchOffset >= 0) { if (searchSpecPtr->backwards) { if (alreadySearchOffset < lastOffset) { lastOffset = alreadySearchOffset; @@ -5673,8 +5883,9 @@ SearchCore( int maxExtraLines = 0; const char *startOfLine = Tcl_GetString(theLine); + CLANG_ASSERT(pattern); do { - Tcl_UniChar ch; + int ch; const char *p; int lastFullLine = lastOffset; @@ -5700,17 +5911,17 @@ SearchCore( * match. */ - const char c = pattern[0]; + const char c = matchLength ? pattern[0] : '\0'; - if (alreadySearchOffset != -1) { + if (alreadySearchOffset >= 0) { p = startOfLine + alreadySearchOffset; alreadySearchOffset = -1; } else { p = startOfLine + lastOffset -1; } while (p >= startOfLine + firstOffset) { - if (p[0] == c && !strncmp(p, pattern, - (unsigned)matchLength)) { + if (matchLength == 0 || (p[0] == c && !strncmp( + p, pattern, (size_t) matchLength))) { goto backwardsMatch; } p--; @@ -5739,7 +5950,7 @@ SearchCore( */ p = startOfLine + lastOffset - firstNewLine - 1; - if (strncmp(p, pattern, (unsigned)(firstNewLine + 1))) { + if (strncmp(p, pattern, (unsigned) firstNewLine + 1)) { /* * No match. */ @@ -5778,7 +5989,7 @@ SearchCore( */ if (extraLines > maxExtraLines) { - if ((*searchSpecPtr->addLineProc)(lineNum + if (searchSpecPtr->addLineProc(lineNum + extraLines, searchSpecPtr, theLine, &lastTotal, &extraLines) == NULL) { p = NULL; @@ -5805,7 +6016,7 @@ SearchCore( * result. */ - if (strncmp(p,pattern,(unsigned)matchLength)) { + if (strncmp(p,pattern,(size_t)matchLength)) { p = NULL; } break; @@ -5858,9 +6069,8 @@ SearchCore( matchOffset = p - startOfLine; if (searchSpecPtr->all && - !(*searchSpecPtr->foundMatchProc)(lineNum, - searchSpecPtr, lineInfo, theLine, matchOffset, - matchLength)) { + !searchSpecPtr->foundMatchProc(lineNum, searchSpecPtr, + lineInfo, theLine, matchOffset, matchLength)) { /* * We reached the end of the search. */ @@ -5874,10 +6084,14 @@ SearchCore( if (firstNewLine != -1) { break; } else { - alreadySearchOffset -= matchLength; + alreadySearchOffset -= (matchLength ? matchLength : 1); + if (alreadySearchOffset < 0) { + break; + } } } else { - firstOffset = p - startOfLine + matchLength; + firstOffset = matchLength ? p - startOfLine + matchLength + : p - startOfLine + 1; if (firstOffset >= lastOffset) { /* * Now, we have to be careful not to find @@ -5905,7 +6119,7 @@ SearchCore( } } else { firstOffset = p - startOfLine + - Tcl_UtfToUniChar(startOfLine+matchOffset,&ch); + TkUtfToUniChar(startOfLine+matchOffset,&ch); } } } while (searchSpecPtr->all); @@ -6001,7 +6215,7 @@ SearchCore( */ if (extraLines > maxExtraLines) { - if ((*searchSpecPtr->addLineProc)(lineNum + if (searchSpecPtr->addLineProc(lineNum + extraLines, searchSpecPtr, theLine, &lastTotal, &extraLines) == NULL) { /* @@ -6180,9 +6394,9 @@ SearchCore( if (lastBackwardsLineMatch != -1) { recordBackwardsMatch: - (*searchSpecPtr->foundMatchProc)( - lastBackwardsLineMatch, searchSpecPtr, NULL, - NULL, lastBackwardsMatchOffset, matchLength); + searchSpecPtr->foundMatchProc(lastBackwardsLineMatch, + searchSpecPtr, NULL, NULL, + lastBackwardsMatchOffset, matchLength); lastBackwardsLineMatch = -1; if (!searchSpecPtr->all) { goto searchDone; @@ -6225,13 +6439,13 @@ SearchCore( * matches on the heap. */ - int *newArray = (int *) + int *newArray = ckalloc(4 * matchNum * sizeof(int)); memcpy(newArray, storeMatch, matchNum*sizeof(int)); memcpy(newArray + 2*matchNum, storeLength, matchNum * sizeof(int)); if (storeMatch != smArray) { - ckfree((char *) storeMatch); + ckfree(storeMatch); } matchNum *= 2; storeMatch = newArray; @@ -6247,7 +6461,7 @@ SearchCore( */ if (searchSpecPtr->all && - !(*searchSpecPtr->foundMatchProc)(lineNum, + !searchSpecPtr->foundMatchProc(lineNum, searchSpecPtr, lineInfo, theLine, matchOffset, matchLength)) { /* @@ -6338,7 +6552,7 @@ SearchCore( continue; } } - (*searchSpecPtr->foundMatchProc)(lineNum, searchSpecPtr, + searchSpecPtr->foundMatchProc(lineNum, searchSpecPtr, lineInfo, theLine, matchOffset, matchLength); if (!searchSpecPtr->all) { goto searchDone; @@ -6353,7 +6567,7 @@ SearchCore( * non-all case. */ - (*searchSpecPtr->foundMatchProc)(lineNum, searchSpecPtr, + searchSpecPtr->foundMatchProc(lineNum, searchSpecPtr, lineInfo, theLine, matchOffset, matchLength); } else { lastBackwardsLineMatch = lineNum; @@ -6372,7 +6586,7 @@ SearchCore( if ((lastBackwardsLineMatch == -1) && (matchOffset >= 0) && !searchSpecPtr->all) { - (*searchSpecPtr->foundMatchProc)(lineNum, searchSpecPtr, lineInfo, + searchSpecPtr->foundMatchProc(lineNum, searchSpecPtr, lineInfo, theLine, matchOffset, matchLength); goto searchDone; } @@ -6399,7 +6613,7 @@ SearchCore( if (lastBackwardsLineMatch != -1 && ((lineNum < 0) || (lineNum + 2 < lastBackwardsLineMatch))) { - (*searchSpecPtr->foundMatchProc)(lastBackwardsLineMatch, + searchSpecPtr->foundMatchProc(lastBackwardsLineMatch, searchSpecPtr, NULL, NULL, lastBackwardsMatchOffset, matchLength); lastBackwardsLineMatch = -1; @@ -6445,7 +6659,7 @@ SearchCore( searchDone: if (lastBackwardsLineMatch != -1) { - (*searchSpecPtr->foundMatchProc)(lastBackwardsLineMatch, searchSpecPtr, + searchSpecPtr->foundMatchProc(lastBackwardsLineMatch, searchSpecPtr, NULL, NULL, lastBackwardsMatchOffset, matchLength); } @@ -6461,7 +6675,7 @@ SearchCore( */ if (storeMatch != smArray) { - ckfree((char *) storeMatch); + ckfree(storeMatch); } return code; @@ -6496,9 +6710,8 @@ GetLineStartEnd( if (linePtr == NULL) { return Tcl_NewObj(); - } else { - return Tcl_NewIntObj(1+TkBTreeLinesTo(NULL, linePtr)); } + return Tcl_NewIntObj(1 + TkBTreeLinesTo(NULL, linePtr)); } /* @@ -6611,16 +6824,13 @@ static int ObjectIsEmpty( Tcl_Obj *objPtr) /* Object to test. May be NULL. */ { - int length; - if (objPtr == NULL) { return 1; } - if (objPtr->bytes != NULL) { - return (objPtr->length == 0); + if (objPtr->bytes == NULL) { + Tcl_GetString(objPtr); } - Tcl_GetStringFromObj(objPtr, &length); - return (length == 0); + return (objPtr->length == 0); } /* @@ -6645,8 +6855,8 @@ int TkpTesttextCmd( ClientData clientData, /* Main window for application. */ Tcl_Interp *interp, /* Current interpreter. */ - int argc, /* Number of arguments. */ - const char **argv) /* Argument strings. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument strings. */ { TkText *textPtr; size_t len; @@ -6655,45 +6865,41 @@ TkpTesttextCmd( char buf[64]; Tcl_CmdInfo info; - if (argc < 3) { + if (objc < 3) { return TCL_ERROR; } - if (Tcl_GetCommandInfo(interp, argv[1], &info) == 0) { + if (Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &info) == 0) { return TCL_ERROR; } - if (info.isNativeObjectProc) { - textPtr = (TkText *) info.objClientData; - } else { - textPtr = (TkText *) info.clientData; - } - len = strlen(argv[2]); - if (strncmp(argv[2], "byteindex", len) == 0) { - if (argc != 5) { + textPtr = info.objClientData; + len = strlen(Tcl_GetString(objv[2])); + if (strncmp(Tcl_GetString(objv[2]), "byteindex", len) == 0) { + if (objc != 5) { return TCL_ERROR; } - lineIndex = atoi(argv[3]) - 1; - byteIndex = atoi(argv[4]); + lineIndex = atoi(Tcl_GetString(objv[3])) - 1; + byteIndex = atoi(Tcl_GetString(objv[4])); TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, lineIndex, byteIndex, &index); - } else if (strncmp(argv[2], "forwbytes", len) == 0) { - if (argc != 5) { + } else if (strncmp(Tcl_GetString(objv[2]), "forwbytes", len) == 0) { + if (objc != 5) { return TCL_ERROR; } - if (TkTextGetIndex(interp, textPtr, argv[3], &index) != TCL_OK) { + if (TkTextGetIndex(interp, textPtr, Tcl_GetString(objv[3]), &index) != TCL_OK) { return TCL_ERROR; } - byteOffset = atoi(argv[4]); + byteOffset = atoi(Tcl_GetString(objv[4])); TkTextIndexForwBytes(textPtr, &index, byteOffset, &index); - } else if (strncmp(argv[2], "backbytes", len) == 0) { - if (argc != 5) { + } else if (strncmp(Tcl_GetString(objv[2]), "backbytes", len) == 0) { + if (objc != 5) { return TCL_ERROR; } - if (TkTextGetIndex(interp, textPtr, argv[3], &index) != TCL_OK) { + if (TkTextGetIndex(interp, textPtr, Tcl_GetString(objv[3]), &index) != TCL_OK) { return TCL_ERROR; } - byteOffset = atoi(argv[4]); + byteOffset = atoi(Tcl_GetString(objv[4])); TkTextIndexBackBytes(textPtr, &index, byteOffset, &index); } else { return TCL_ERROR; @@ -6701,9 +6907,7 @@ TkpTesttextCmd( TkTextSetMark(textPtr, "insert", &index); TkTextPrintIndex(textPtr, &index, buf); - sprintf(buf + strlen(buf), " %d", index.byteIndex); - Tcl_AppendResult(interp, buf, NULL); - + Tcl_SetObjResult(interp, Tcl_ObjPrintf("%s %d", buf, index.byteIndex)); return TCL_OK; } diff --git a/generic/tkText.h b/generic/tkText.h index 464bed5..a8a17da 100644 --- a/generic/tkText.h +++ b/generic/tkText.h @@ -21,17 +21,6 @@ #include "tkUndo.h" #endif -#ifdef BUILD_tk -# undef TCL_STORAGE_CLASS -# define TCL_STORAGE_CLASS DLLEXPORT -#endif - -/* - * Opaque types for structures whose guts are only needed by a single file. - */ - -typedef struct TkTextBTree_ *TkTextBTree; - /* * The data structure below defines a single logical line of text (from * newline to newline, not necessarily what appears on one display line of the @@ -179,7 +168,7 @@ typedef struct TkTextSegment { int size; /* Size of this segment (# of bytes of index * space it occupies). */ union { - char chars[4]; /* Characters that make up character info. + char chars[2]; /* Characters that make up character info. * Actual length varies to hold as many * characters as needed.*/ TkTextToggle toggle; /* Information about tag toggle. */ @@ -358,6 +347,9 @@ typedef struct TkTextTag { int lMargin2; /* Left margin for second and later display * lines of each text line, in pixels. Only * valid if lMargin2String is non-NULL. */ + Tk_3DBorder lMarginColor; /* Used for drawing background in left margins. + * This is used for both lmargin1 and lmargin2. + * NULL means no value specified here. */ char *offsetString; /* -offset option string (malloc-ed). NULL * means option not specified. */ int offset; /* Vertical offset of text's baseline from @@ -369,10 +361,18 @@ typedef struct TkTextTag { int overstrike; /* Non-zero means draw horizontal line through * middle of text. Only valid if * overstrikeString is non-NULL. */ + XColor *overstrikeColor; /* Color for the overstrike. NULL means same + * color as foreground. */ char *rMarginString; /* -rmargin option string (malloc-ed). NULL * means option not specified. */ int rMargin; /* Right margin for text, in pixels. Only * valid if rMarginString is non-NULL. */ + Tk_3DBorder rMarginColor; /* Used for drawing background in right margin. + * NULL means no value specified here. */ + Tk_3DBorder selBorder; /* Used for drawing background for selected text. + * NULL means no value specified here. */ + XColor *selFgColor; /* Foreground color for selected text. NULL means + * no value specified here. */ char *spacing1String; /* -spacing1 option string (malloc-ed). NULL * means option not specified. */ int spacing1; /* Extra spacing above first display line for @@ -400,6 +400,8 @@ typedef struct TkTextTag { int underline; /* Non-zero means draw underline underneath * text. Only valid if underlineString is * non-NULL. */ + XColor *underlineColor; /* Color for the underline. NULL means same + * color as foreground. */ TkWrapMode wrapMode; /* How to handle wrap-around for this tag. * Must be TEXT_WRAPMODE_CHAR, * TEXT_WRAPMODE_NONE, TEXT_WRAPMODE_WORD, or @@ -493,7 +495,7 @@ typedef struct TkTextTabArray { } TkTextTabArray; /* - * Enumeration definining the edit modes of the widget. + * Enumeration defining the edit modes of the widget. */ typedef enum { @@ -595,6 +597,17 @@ typedef struct TkSharedText { } TkSharedText; /* + * The following enum is used to define a type for the -insertunfocussed + * option of the Text widget. + */ + +typedef enum { + TK_TEXT_INSERT_NOFOCUS_HOLLOW, + TK_TEXT_INSERT_NOFOCUS_NONE, + TK_TEXT_INSERT_NOFOCUS_SOLID +} TkTextInsertUnfocussed; + +/* * A data structure of the following type is kept for each text widget that * currently exists for this process: */ @@ -726,7 +739,10 @@ typedef struct TkText { Tk_3DBorder insertBorder; /* Used to draw vertical bar for insertion * cursor. */ int insertWidth; /* Total width of insert cursor. */ - int insertBorderWidth; /* Width of 3-D border around insert cursor. */ + int insertBorderWidth; /* Width of 3-D border around insert cursor */ + TkTextInsertUnfocussed insertUnfocussed; + /* How to display the insert cursor when the + * text widget does not have the focus. */ int insertOnTime; /* Number of milliseconds cursor should spend * in "on" state for each blink. */ int insertOffTime; /* Number of milliseconds cursor should spend @@ -782,6 +798,8 @@ typedef struct TkText { * statements. */ int autoSeparators; /* Non-zero means the separators will be * inserted automatically. */ + Tcl_Obj *afterSyncCmd; /* Command to be executed when lines are up to + * date */ } TkText; /* @@ -955,6 +973,8 @@ MODULE_SCOPE const Tk_SegType tkTextLeftMarkType; MODULE_SCOPE const Tk_SegType tkTextRightMarkType; MODULE_SCOPE const Tk_SegType tkTextToggleOnType; MODULE_SCOPE const Tk_SegType tkTextToggleOffType; +MODULE_SCOPE const Tk_SegType tkTextEmbWindowType; +MODULE_SCOPE const Tk_SegType tkTextEmbImageType; /* * Convenience macros for use by B-tree clients which want to access pixel @@ -1006,8 +1026,6 @@ MODULE_SCOPE void TkBTreeLinkSegment(TkTextSegment *segPtr, MODULE_SCOPE TkTextLine *TkBTreeNextLine(const TkText *textPtr, TkTextLine *linePtr); MODULE_SCOPE int TkBTreeNextTag(TkTextSearch *searchPtr); -MODULE_SCOPE int TkBTreeNumLines(TkTextBTree tree, - const TkText *textPtr); MODULE_SCOPE int TkBTreeNumPixels(TkTextBTree tree, const TkText *textPtr); MODULE_SCOPE TkTextLine *TkBTreePreviousLine(TkText *textPtr, @@ -1027,9 +1045,6 @@ MODULE_SCOPE void TkBTreeUnlinkSegment(TkTextSegment *segPtr, MODULE_SCOPE void TkTextBindProc(ClientData clientData, XEvent *eventPtr); MODULE_SCOPE void TkTextSelectionEvent(TkText *textPtr); -MODULE_SCOPE void TkTextChanged(TkSharedText *sharedTextPtr, - TkText *textPtr, const TkTextIndex *index1Ptr, - const TkTextIndex *index2Ptr); MODULE_SCOPE int TkTextIndexBbox(TkText *textPtr, const TkTextIndex *indexPtr, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr, int *charWidthPtr); @@ -1050,22 +1065,17 @@ MODULE_SCOPE TkTextTag *TkTextCreateTag(TkText *textPtr, MODULE_SCOPE void TkTextFreeDInfo(TkText *textPtr); MODULE_SCOPE void TkTextDeleteTag(TkText *textPtr, TkTextTag *tagPtr); MODULE_SCOPE void TkTextFreeTag(TkText *textPtr, TkTextTag *tagPtr); -MODULE_SCOPE int TkTextGetIndex(Tcl_Interp *interp, TkText *textPtr, - const char *string, TkTextIndex *indexPtr); MODULE_SCOPE int TkTextGetObjIndex(Tcl_Interp *interp, TkText *textPtr, Tcl_Obj *idxPtr, TkTextIndex *indexPtr); MODULE_SCOPE int TkTextSharedGetObjIndex(Tcl_Interp *interp, TkSharedText *sharedTextPtr, Tcl_Obj *idxPtr, TkTextIndex *indexPtr); -MODULE_SCOPE const TkTextIndex *TkTextGetIndexFromObj(Tcl_Interp *interp, +MODULE_SCOPE const TkTextIndex *TkTextGetIndexFromObj(Tcl_Interp *interp, TkText *textPtr, Tcl_Obj *objPtr); MODULE_SCOPE TkTextTabArray *TkTextGetTabs(Tcl_Interp *interp, TkText *textPtr, Tcl_Obj *stringPtr); MODULE_SCOPE void TkTextFindDisplayLineEnd(TkText *textPtr, TkTextIndex *indexPtr, int end, int *xOffset); -MODULE_SCOPE int TkTextIndexBackBytes(const TkText *textPtr, - const TkTextIndex *srcPtr, int count, - TkTextIndex *dstPtr); MODULE_SCOPE void TkTextIndexBackChars(const TkText *textPtr, const TkTextIndex *srcPtr, int count, TkTextIndex *dstPtr, TkTextCountType type); @@ -1078,9 +1088,6 @@ MODULE_SCOPE int TkTextIndexCount(const TkText *textPtr, const TkTextIndex *index1Ptr, const TkTextIndex *index2Ptr, TkTextCountType type); -MODULE_SCOPE int TkTextIndexForwBytes(const TkText *textPtr, - const TkTextIndex *srcPtr, int count, - TkTextIndex *dstPtr); MODULE_SCOPE void TkTextIndexForwChars(const TkText *textPtr, const TkTextIndex *srcPtr, int count, TkTextIndex *dstPtr, TkTextCountType type); @@ -1090,10 +1097,6 @@ MODULE_SCOPE int TkTextIndexYPixels(TkText *textPtr, const TkTextIndex *indexPtr); MODULE_SCOPE TkTextSegment *TkTextIndexToSeg(const TkTextIndex *indexPtr, int *offsetPtr); -MODULE_SCOPE void TkTextInsertDisplayProc(TkText *textPtr, - TkTextDispChunk *chunkPtr, int x, int y, - int height, int baseline, Display *display, - Drawable dst, int screenY); MODULE_SCOPE void TkTextLostSelection(ClientData clientData); MODULE_SCOPE TkTextIndex *TkTextMakeCharIndex(TkTextBTree tree, TkText *textPtr, int lineIndex, int charIndex, @@ -1104,9 +1107,6 @@ MODULE_SCOPE void TkTextFreeElideInfo(TkTextElideInfo *infoPtr); MODULE_SCOPE int TkTextIsElided(const TkText *textPtr, const TkTextIndex *indexPtr, TkTextElideInfo *infoPtr); -MODULE_SCOPE TkTextIndex *TkTextMakeByteIndex(TkTextBTree tree, - const TkText *textPtr, int lineIndex, - int byteIndex, TkTextIndex *indexPtr); MODULE_SCOPE int TkTextMakePixelIndex(TkText *textPtr, int pixelIndex, TkTextIndex *indexPtr); MODULE_SCOPE void TkTextInvalidateLineMetrics( @@ -1124,11 +1124,10 @@ MODULE_SCOPE int TkTextMarkNameToIndex(TkText *textPtr, MODULE_SCOPE void TkTextMarkSegToIndex(TkText *textPtr, TkTextSegment *markPtr, TkTextIndex *indexPtr); MODULE_SCOPE void TkTextEventuallyRepick(TkText *textPtr); +MODULE_SCOPE Bool TkTextPendingsync(TkText *textPtr); MODULE_SCOPE void TkTextPickCurrent(TkText *textPtr, XEvent *eventPtr); MODULE_SCOPE void TkTextPixelIndex(TkText *textPtr, int x, int y, TkTextIndex *indexPtr, int *nearest); -MODULE_SCOPE int TkTextPrintIndex(const TkText *textPtr, - const TkTextIndex *indexPtr, char *string); MODULE_SCOPE Tcl_Obj * TkTextNewIndexObj(TkText *textPtr, const TkTextIndex *indexPtr); MODULE_SCOPE void TkTextRedrawRegion(TkText *textPtr, int x, int y, @@ -1144,8 +1143,6 @@ MODULE_SCOPE int TkTextSeeCmd(TkText *textPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); MODULE_SCOPE int TkTextSegToOffset(const TkTextSegment *segPtr, const TkTextLine *linePtr); -MODULE_SCOPE TkTextSegment *TkTextSetMark(TkText *textPtr, - const char *name, TkTextIndex *indexPtr); MODULE_SCOPE void TkTextSetYView(TkText *textPtr, TkTextIndex *indexPtr, int pickPlace); MODULE_SCOPE int TkTextTagCmd(TkText *textPtr, Tcl_Interp *interp, @@ -1158,16 +1155,11 @@ MODULE_SCOPE int TkTextWindowCmd(TkText *textPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); MODULE_SCOPE int TkTextWindowIndex(TkText *textPtr, const char *name, TkTextIndex *indexPtr); -MODULE_SCOPE int TkTextXviewCmd(TkText *textPtr, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]); MODULE_SCOPE int TkTextYviewCmd(TkText *textPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); MODULE_SCOPE void TkTextWinFreeClient(Tcl_HashEntry *hPtr, TkTextEmbWindowClient *client); - -# undef TCL_STORAGE_CLASS -# define TCL_STORAGE_CLASS DLLIMPORT - +MODULE_SCOPE void TkTextRunAfterSyncCmd(ClientData clientData); #endif /* _TKTEXT */ /* diff --git a/generic/tkTextBTree.c b/generic/tkTextBTree.c index 58fc645..81e31dc 100644 --- a/generic/tkTextBTree.c +++ b/generic/tkTextBTree.c @@ -273,9 +273,9 @@ TkBTreeCreate( * of the tree. */ - rootPtr = (Node *) ckalloc(sizeof(Node)); - linePtr = (TkTextLine *) ckalloc(sizeof(TkTextLine)); - linePtr2 = (TkTextLine *) ckalloc(sizeof(TkTextLine)); + rootPtr = ckalloc(sizeof(Node)); + linePtr = ckalloc(sizeof(TkTextLine)); + linePtr2 = ckalloc(sizeof(TkTextLine)); rootPtr->parentPtr = NULL; rootPtr->nextPtr = NULL; @@ -296,7 +296,7 @@ TkBTreeCreate( linePtr->parentPtr = rootPtr; linePtr->nextPtr = linePtr2; - segPtr = (TkTextSegment *) ckalloc(CSEG_SIZE(1)); + segPtr = ckalloc(CSEG_SIZE(1)); linePtr->segPtr = segPtr; segPtr->typePtr = &tkTextCharType; segPtr->nextPtr = NULL; @@ -306,7 +306,7 @@ TkBTreeCreate( linePtr2->parentPtr = rootPtr; linePtr2->nextPtr = NULL; - segPtr = (TkTextSegment *) ckalloc(CSEG_SIZE(1)); + segPtr = ckalloc(CSEG_SIZE(1)); linePtr2->segPtr = segPtr; segPtr->typePtr = &tkTextCharType; segPtr->nextPtr = NULL; @@ -314,7 +314,7 @@ TkBTreeCreate( segPtr->body.chars[0] = '\n'; segPtr->body.chars[1] = 0; - treePtr = (BTree *) ckalloc(sizeof(BTree)); + treePtr = ckalloc(sizeof(BTree)); treePtr->sharedTextPtr = sharedTextPtr; treePtr->rootPtr = rootPtr; treePtr->clients = 0; @@ -478,10 +478,10 @@ TkBTreeDestroy( DestroyNode(treePtr->rootPtr); if (treePtr->startEnd != NULL) { - ckfree((char *) treePtr->startEnd); - ckfree((char *) treePtr->startEndRef); + ckfree(treePtr->startEnd); + ckfree(treePtr->startEndRef); } - ckfree((char *) treePtr); + ckfree(treePtr); } /* @@ -543,7 +543,7 @@ TkBTreeRemoveClient( */ DestroyNode(treePtr->rootPtr); - ckfree((char *) treePtr); + ckfree(treePtr); return; } else if (pixelReference == -1) { /* @@ -632,11 +632,9 @@ AdjustStartEndRefs( i++; } treePtr->startEndCount = count; - treePtr->startEnd = (TkTextLine **) - ckrealloc((char *) treePtr->startEnd, + treePtr->startEnd = ckrealloc(treePtr->startEnd, sizeof(TkTextLine *) * count); - treePtr->startEndRef = (TkText **) - ckrealloc((char *) treePtr->startEndRef, + treePtr->startEndRef = ckrealloc(treePtr->startEndRef, sizeof(TkText *) * count); } if ((action & TEXT_ADD_REFS) @@ -652,11 +650,9 @@ AdjustStartEndRefs( count = treePtr->startEndCount; - treePtr->startEnd = (TkTextLine **) - ckrealloc((char *) treePtr->startEnd, + treePtr->startEnd = ckrealloc(treePtr->startEnd, sizeof(TkTextLine *) * count); - treePtr->startEndRef = (TkText **) - ckrealloc((char *) treePtr->startEndRef, + treePtr->startEndRef = ckrealloc(treePtr->startEndRef, sizeof(TkText *) * count); if (textPtr->start != NULL) { @@ -739,7 +735,7 @@ AdjustPixelClient( *counting = 0; } if (newPixelReferences != treePtr->pixelReferences) { - linePtr->pixels = (int *) ckrealloc((char *) linePtr->pixels, + linePtr->pixels = ckrealloc(linePtr->pixels, sizeof(int) * 2 * newPixelReferences); } @@ -756,7 +752,7 @@ AdjustPixelClient( } } if (newPixelReferences != treePtr->pixelReferences) { - nodePtr->numPixels = (int *) ckrealloc((char *) nodePtr->numPixels, + nodePtr->numPixels = ckrealloc(nodePtr->numPixels, sizeof(int) * newPixelReferences); } nodePtr->numPixels[useReference] = pixelCount; @@ -803,9 +799,10 @@ RemovePixelClient( nodePtr->numPixels[treePtr->pixelReferences-1]; } if (treePtr->pixelReferences == 1) { + ckfree(nodePtr->numPixels); nodePtr->numPixels = NULL; } else { - nodePtr->numPixels = (int *) ckrealloc((char *) nodePtr->numPixels, + nodePtr->numPixels = ckrealloc(nodePtr->numPixels, sizeof(int) * (treePtr->pixelReferences - 1)); } if (nodePtr->level != 0) { @@ -826,7 +823,7 @@ RemovePixelClient( if (treePtr->pixelReferences == 1) { linePtr->pixels = NULL; } else { - linePtr->pixels = (int *) ckrealloc((char *) linePtr->pixels, + linePtr->pixels = ckrealloc(linePtr->pixels, sizeof(int) * 2 * (treePtr->pixelReferences-1)); } linePtr = linePtr->nextPtr; @@ -865,10 +862,10 @@ DestroyNode( while (linePtr->segPtr != NULL) { segPtr = linePtr->segPtr; linePtr->segPtr = segPtr->nextPtr; - (*segPtr->typePtr->deleteProc)(segPtr, linePtr, 1); + segPtr->typePtr->deleteProc(segPtr, linePtr, 1); } - ckfree((char *) linePtr->pixels); - ckfree((char *) linePtr); + ckfree(linePtr->pixels); + ckfree(linePtr); } } else { register Node *childPtr; @@ -880,8 +877,8 @@ DestroyNode( } } DeleteSummaries(nodePtr->summaryPtr); - ckfree((char *) nodePtr->numPixels); - ckfree((char *) nodePtr); + ckfree(nodePtr->numPixels); + ckfree(nodePtr); } /* @@ -910,7 +907,7 @@ DeleteSummaries( while (summaryPtr != NULL) { nextPtr = summaryPtr->nextPtr; - ckfree((char *) summaryPtr); + ckfree(summaryPtr); summaryPtr = nextPtr; } } @@ -1047,8 +1044,7 @@ TkBTreeInsertChars( changeToLineCount = 0; if (treePtr->pixelReferences > PIXEL_CLIENTS) { - changeToPixelCount = (int *) - ckalloc(sizeof(int) * treePtr->pixelReferences); + changeToPixelCount = ckalloc(sizeof(int) * treePtr->pixelReferences); } else { changeToPixelCount = pixels; } @@ -1064,7 +1060,7 @@ TkBTreeInsertChars( } } chunkSize = eol-string; - segPtr = (TkTextSegment *) ckalloc(CSEG_SIZE(chunkSize)); + segPtr = ckalloc(CSEG_SIZE(chunkSize)); segPtr->typePtr = &tkTextCharType; if (curPtr == NULL) { segPtr->nextPtr = linePtr->segPtr; @@ -1086,8 +1082,8 @@ TkBTreeInsertChars( * the remainder of the old line to it. */ - newLinePtr = (TkTextLine *) ckalloc(sizeof(TkTextLine)); - newLinePtr->pixels = (int *) + newLinePtr = ckalloc(sizeof(TkTextLine)); + newLinePtr->pixels = ckalloc(sizeof(int) * 2 * treePtr->pixelReferences); newLinePtr->parentPtr = linePtr->parentPtr; @@ -1147,7 +1143,7 @@ TkBTreeInsertChars( } } if (treePtr->pixelReferences > PIXEL_CLIENTS) { - ckfree((char *) changeToPixelCount); + ckfree(changeToPixelCount); } nodePtr = linePtr->parentPtr; @@ -1205,7 +1201,7 @@ SplitSeg( if (count == 0) { return prevPtr; } - segPtr = (*segPtr->typePtr->splitProc)(segPtr, count); + segPtr = segPtr->typePtr->splitProc(segPtr, count); if (prevPtr == NULL) { indexPtr->linePtr->segPtr = segPtr; } else { @@ -1231,8 +1227,9 @@ SplitSeg( /* * Reached end of the text. */ + } else { + segPtr = linePtr->segPtr; } - segPtr = linePtr->segPtr; } } Tcl_Panic("SplitSeg reached end of line!"); @@ -1280,7 +1277,7 @@ CleanupLine( segPtr != NULL; prevPtrPtr = &(*prevPtrPtr)->nextPtr, segPtr = *prevPtrPtr) { if (segPtr->typePtr->cleanupProc != NULL) { - *prevPtrPtr = (*segPtr->typePtr->cleanupProc)(segPtr, linePtr); + *prevPtrPtr = segPtr->typePtr->cleanupProc(segPtr, linePtr); if (segPtr != *prevPtrPtr) { anyChanges = 1; } @@ -1387,6 +1384,7 @@ TkBTreeDeleteIndexRange( } } changeToLineCount++; + CLANG_ASSERT(curNodePtr); curNodePtr->numChildren--; /* @@ -1417,8 +1415,8 @@ TkBTreeDeleteIndexRange( checkCount++; } } - ckfree((char *) curLinePtr->pixels); - ckfree((char *) curLinePtr); + ckfree(curLinePtr->pixels); + ckfree(curLinePtr); } curLinePtr = nextLinePtr; segPtr = curLinePtr->segPtr; @@ -1442,7 +1440,9 @@ TkBTreeDeleteIndexRange( prevNodePtr->nextPtr = curNodePtr->nextPtr; } parentPtr->numChildren--; - ckfree((char *) curNodePtr); + DeleteSummaries(curNodePtr->summaryPtr); + ckfree(curNodePtr->numPixels); + ckfree(curNodePtr); curNodePtr = parentPtr; } curNodePtr = curLinePtr->parentPtr; @@ -1450,7 +1450,7 @@ TkBTreeDeleteIndexRange( } nextPtr = segPtr->nextPtr; - if ((*segPtr->typePtr->deleteProc)(segPtr, curLinePtr, 0) != 0) { + if (segPtr->typePtr->deleteProc(segPtr, curLinePtr, 0) != 0) { /* * This segment refuses to die. Move it to prevPtr and advance * prevPtr if the segment has left gravity. @@ -1481,7 +1481,7 @@ TkBTreeDeleteIndexRange( for (segPtr = lastPtr; segPtr != NULL; segPtr = segPtr->nextPtr) { if (segPtr->typePtr->lineChangeProc != NULL) { - (*segPtr->typePtr->lineChangeProc)(segPtr, index2Ptr->linePtr); + segPtr->typePtr->lineChangeProc(segPtr, index2Ptr->linePtr); } } curNodePtr = index2Ptr->linePtr->parentPtr; @@ -1537,8 +1537,8 @@ TkBTreeDeleteIndexRange( checkCount++; } } - ckfree((char *) index2Ptr->linePtr->pixels); - ckfree((char *) index2Ptr->linePtr); + ckfree(index2Ptr->linePtr->pixels); + ckfree(index2Ptr->linePtr); Rebalance((BTree *) index2Ptr->tree, curNodePtr); } @@ -1991,7 +1991,7 @@ TkBTreeLinesTo( } } if (textPtr != NULL) { - /* + /* * The index to return must be relative to textPtr, not to the entire * tree. Take care to never return a negative index when linePtr * denotes a line before -startline, or an index larger than the @@ -2157,7 +2157,7 @@ TkBTreeTag( oldState = TkBTreeCharTagged(index1Ptr, tagPtr); if ((add != 0) ^ oldState) { - segPtr = (TkTextSegment *) ckalloc(TSEG_SIZE); + segPtr = ckalloc(TSEG_SIZE); segPtr->typePtr = (add) ? &tkTextToggleOnType : &tkTextToggleOffType; prevPtr = SplitSeg(index1Ptr); if (prevPtr == NULL) { @@ -2202,7 +2202,7 @@ TkBTreeTag( } else { changed = 0; } - ckfree((char *) segPtr); + ckfree(segPtr); /* * The code below is a bit tricky. After deleting a toggle we @@ -2228,7 +2228,7 @@ TkBTreeTag( } } if ((add != 0) ^ oldState) { - segPtr = (TkTextSegment *) ckalloc(TSEG_SIZE); + segPtr = ckalloc(TSEG_SIZE); segPtr->typePtr = (add) ? &tkTextToggleOffType : &tkTextToggleOnType; prevPtr = SplitSeg(index2Ptr); if (prevPtr == NULL) { @@ -2353,7 +2353,7 @@ ChangeNodeToggleCount( } else { prevPtr->nextPtr = summaryPtr->nextPtr; } - ckfree((char *) summaryPtr); + ckfree(summaryPtr); } else { /* * This tag isn't currently in the summary information list. @@ -2372,7 +2372,7 @@ ChangeNodeToggleCount( Node *rootNodePtr = tagPtr->tagRootPtr; - summaryPtr = (Summary *) ckalloc(sizeof(Summary)); + summaryPtr = ckalloc(sizeof(Summary)); summaryPtr->tagPtr = tagPtr; summaryPtr->toggleCount = tagPtr->toggleCount - delta; summaryPtr->nextPtr = rootNodePtr->summaryPtr; @@ -2381,7 +2381,7 @@ ChangeNodeToggleCount( rootLevel = rootNodePtr->level; tagPtr->tagRootPtr = rootNodePtr; } - summaryPtr = (Summary *) ckalloc(sizeof(Summary)); + summaryPtr = ckalloc(sizeof(Summary)); summaryPtr->tagPtr = tagPtr; summaryPtr->toggleCount = delta; summaryPtr->nextPtr = nodePtr->summaryPtr; @@ -2438,7 +2438,7 @@ ChangeNodeToggleCount( } else { prevPtr->nextPtr = summaryPtr->nextPtr; } - ckfree((char *) summaryPtr); + ckfree(summaryPtr); tagPtr->tagRootPtr = node2Ptr; break; } @@ -2487,7 +2487,7 @@ FindTagStart( * level 0 node. */ - while (nodePtr->level > 0) { + while (nodePtr && nodePtr->level > 0) { for (nodePtr = nodePtr->children.nodePtr ; nodePtr != NULL; nodePtr = nodePtr->nextPtr) { for (summaryPtr = nodePtr->summaryPtr ; summaryPtr != NULL; @@ -2501,6 +2501,10 @@ FindTagStart( continue; } + if (nodePtr == NULL) { + return NULL; + } + /* * Work through the lines attached to the level-0 node. */ @@ -2568,7 +2572,7 @@ FindTagEnd( * level 0 node. */ - while (nodePtr->level > 0) { + while (nodePtr && nodePtr->level > 0) { for (lastNodePtr = NULL, nodePtr = nodePtr->children.nodePtr ; nodePtr != NULL; nodePtr = nodePtr->nextPtr) { for (summaryPtr = nodePtr->summaryPtr ; summaryPtr != NULL; @@ -2582,6 +2586,10 @@ FindTagEnd( nodePtr = lastNodePtr; } + if (nodePtr == NULL) { + return NULL; + } + /* * Work through the lines attached to the level-0 node. */ @@ -2951,7 +2959,7 @@ TkBTreeNextTag( } searchPtr->linesLeft -= nodePtr->numLines; if (nodePtr->nextPtr == NULL) { - Tcl_Panic("TkBTreeNextTag found incorrect tag summary info."); + Tcl_Panic("TkBTreeNextTag found incorrect tag summary info"); } } nextChild: @@ -3169,7 +3177,7 @@ TkBTreePrevTag( continue; } if (prevNodePtr == NULL) { - Tcl_Panic("TkBTreePrevTag found incorrect tag summary info."); + Tcl_Panic("TkBTreePrevTag found incorrect tag summary info"); } searchPtr->linesLeft -= linesSkipped; nodePtr = prevNodePtr; @@ -3349,10 +3357,8 @@ TkBTreeGetTags( tagInfo.numTags = 0; tagInfo.arraySize = NUM_TAG_INFOS; - tagInfo.tagPtrs = (TkTextTag **) - ckalloc((unsigned) NUM_TAG_INFOS * sizeof(TkTextTag *)); - tagInfo.counts = (int *) - ckalloc((unsigned) NUM_TAG_INFOS * sizeof(int)); + tagInfo.tagPtrs = ckalloc(NUM_TAG_INFOS * sizeof(TkTextTag *)); + tagInfo.counts = ckalloc(NUM_TAG_INFOS * sizeof(int)); /* * Record tag toggles within the line of indexPtr but preceding indexPtr. @@ -3437,9 +3443,9 @@ TkBTreeGetTags( } } *numTagsPtr = dst; - ckfree((char *) tagInfo.counts); + ckfree(tagInfo.counts); if (dst == 0) { - ckfree((char *) tagInfo.tagPtrs); + ckfree(tagInfo.tagPtrs); return NULL; } return tagInfo.tagPtrs; @@ -3496,8 +3502,7 @@ TkTextIsElided( int elide; if (elideInfo == NULL) { - infoPtr = (TkTextElideInfo *) - ckalloc((unsigned) sizeof(TkTextElideInfo)); + infoPtr = ckalloc(sizeof(TkTextElideInfo)); } else { infoPtr = elideInfo; } @@ -3512,10 +3517,8 @@ TkTextIsElided( */ if (LOTSA_TAGS < infoPtr->numTags) { - infoPtr->tagCnts = (int *) - ckalloc((unsigned) sizeof(int) * infoPtr->numTags); - infoPtr->tagPtrs = (TkTextTag **) - ckalloc((unsigned) sizeof(TkTextTag *) * infoPtr->numTags); + infoPtr->tagCnts = ckalloc(sizeof(int) * infoPtr->numTags); + infoPtr->tagPtrs = ckalloc(sizeof(TkTextTag *) * infoPtr->numTags); } for (i=0; i<infoPtr->numTags; i++) { @@ -3630,11 +3633,11 @@ TkTextIsElided( if (elideInfo == NULL) { if (LOTSA_TAGS < infoPtr->numTags) { - ckfree((char *) infoPtr->tagCnts); - ckfree((char *) infoPtr->tagPtrs); + ckfree(infoPtr->tagCnts); + ckfree(infoPtr->tagPtrs); } - ckfree((char *) infoPtr); + ckfree(infoPtr); } return elide; @@ -3663,8 +3666,8 @@ TkTextFreeElideInfo( * structure. */ { if (LOTSA_TAGS < elideInfo->numTags) { - ckfree((char *) elideInfo->tagCnts); - ckfree((char *) elideInfo->tagPtrs); + ckfree(elideInfo->tagCnts); + ckfree(elideInfo->tagPtrs); } } @@ -3715,16 +3718,15 @@ IncCount( int *newCounts, newSize; newSize = 2 * tagInfoPtr->arraySize; - newTags = (TkTextTag **) - ckalloc((unsigned) newSize * sizeof(TkTextTag *)); + newTags = ckalloc(newSize * sizeof(TkTextTag *)); memcpy(newTags, tagInfoPtr->tagPtrs, tagInfoPtr->arraySize * sizeof(TkTextTag *)); - ckfree((char *) tagInfoPtr->tagPtrs); + ckfree(tagInfoPtr->tagPtrs); tagInfoPtr->tagPtrs = newTags; - newCounts = (int *) ckalloc((unsigned) newSize * sizeof(int)); + newCounts = ckalloc(newSize * sizeof(int)); memcpy(newCounts, tagInfoPtr->counts, tagInfoPtr->arraySize * sizeof(int)); - ckfree((char *) tagInfoPtr->counts); + ckfree(tagInfoPtr->counts); tagInfoPtr->counts = newCounts; tagInfoPtr->arraySize = newSize; } @@ -3772,7 +3774,7 @@ TkBTreeCheck( for (entryPtr=Tcl_FirstHashEntry(&treePtr->sharedTextPtr->tagTable,&search); entryPtr != NULL ; entryPtr = Tcl_NextHashEntry(&search)) { - tagPtr = (TkTextTag *) Tcl_GetHashValue(entryPtr); + tagPtr = Tcl_GetHashValue(entryPtr); nodePtr = tagPtr->tagRootPtr; if (nodePtr == NULL) { if (tagPtr->toggleCount != 0) { @@ -3924,7 +3926,7 @@ CheckNodeConsistency( numChildren = 0; numLines = 0; if (references > PIXEL_CLIENTS) { - numPixels = (int *) ckalloc(sizeof(int) * references); + numPixels = ckalloc(sizeof(int) * references); } else { numPixels = pixels; } @@ -3944,7 +3946,7 @@ CheckNodeConsistency( for (segPtr = linePtr->segPtr; segPtr != NULL; segPtr = segPtr->nextPtr) { if (segPtr->typePtr->checkProc != NULL) { - (*segPtr->typePtr->checkProc)(segPtr, linePtr); + segPtr->typePtr->checkProc(segPtr, linePtr); } if ((segPtr->size == 0) && (!segPtr->typePtr->leftGravity) && (segPtr->nextPtr != NULL) @@ -4013,7 +4015,7 @@ CheckNodeConsistency( } } if (references > PIXEL_CLIENTS) { - ckfree((char *) numPixels); + ckfree(numPixels); } for (summaryPtr = nodePtr->summaryPtr; summaryPtr != NULL; @@ -4112,7 +4114,7 @@ Rebalance( */ if (nodePtr->parentPtr == NULL) { - newPtr = (Node *) ckalloc(sizeof(Node)); + newPtr = ckalloc(sizeof(Node)); newPtr->parentPtr = NULL; newPtr->nextPtr = NULL; newPtr->summaryPtr = NULL; @@ -4120,7 +4122,7 @@ Rebalance( newPtr->children.nodePtr = nodePtr; newPtr->numChildren = 1; newPtr->numLines = nodePtr->numLines; - newPtr->numPixels = (int *) + newPtr->numPixels = ckalloc(sizeof(int) * treePtr->pixelReferences); for (i=0; i<treePtr->pixelReferences; i++) { newPtr->numPixels[i] = nodePtr->numPixels[i]; @@ -4128,8 +4130,8 @@ Rebalance( RecomputeNodeCounts(treePtr, newPtr); treePtr->rootPtr = newPtr; } - newPtr = (Node *) ckalloc(sizeof(Node)); - newPtr->numPixels = (int *) + newPtr = ckalloc(sizeof(Node)); + newPtr->numPixels = ckalloc(sizeof(int) * treePtr->pixelReferences); for (i=0; i<treePtr->pixelReferences; i++) { newPtr->numPixels[i] = 0; @@ -4186,7 +4188,8 @@ Rebalance( treePtr->rootPtr = nodePtr->children.nodePtr; treePtr->rootPtr->parentPtr = NULL; DeleteSummaries(nodePtr->summaryPtr); - ckfree((char *) nodePtr); + ckfree(nodePtr->numPixels); + ckfree(nodePtr); } return; } @@ -4275,7 +4278,8 @@ Rebalance( nodePtr->nextPtr = otherPtr->nextPtr; nodePtr->parentPtr->numChildren--; DeleteSummaries(otherPtr->summaryPtr); - ckfree((char *) otherPtr); + ckfree(otherPtr->numPixels); + ckfree(otherPtr); continue; } @@ -4285,9 +4289,11 @@ Rebalance( */ if (nodePtr->level == 0) { + CLANG_ASSERT(halfwayLinePtr); otherPtr->children.linePtr = halfwayLinePtr->nextPtr; halfwayLinePtr->nextPtr = NULL; } else { + CLANG_ASSERT(halfwayNodePtr); otherPtr->children.nodePtr = halfwayNodePtr->nextPtr; halfwayNodePtr->nextPtr = NULL; } @@ -4371,7 +4377,7 @@ RecomputeNodeCounts( for (summaryPtr = nodePtr->summaryPtr; ; summaryPtr = summaryPtr->nextPtr) { if (summaryPtr == NULL) { - summaryPtr = (Summary *) ckalloc(sizeof(Summary)); + summaryPtr = ckalloc(sizeof(Summary)); summaryPtr->tagPtr = tagPtr; summaryPtr->toggleCount = 1; summaryPtr->nextPtr = nodePtr->summaryPtr; @@ -4399,7 +4405,7 @@ RecomputeNodeCounts( for (summaryPtr = nodePtr->summaryPtr; ; summaryPtr = summaryPtr->nextPtr) { if (summaryPtr == NULL) { - summaryPtr = (Summary *) ckalloc(sizeof(Summary)); + summaryPtr = ckalloc(sizeof(Summary)); summaryPtr->tagPtr = summaryPtr2->tagPtr; summaryPtr->toggleCount = summaryPtr2->toggleCount; summaryPtr->nextPtr = nodePtr->summaryPtr; @@ -4448,11 +4454,11 @@ RecomputeNodeCounts( } if (summaryPtr2 != NULL) { summaryPtr2->nextPtr = summaryPtr->nextPtr; - ckfree((char *) summaryPtr); + ckfree(summaryPtr); summaryPtr = summaryPtr2->nextPtr; } else { nodePtr->summaryPtr = summaryPtr->nextPtr; - ckfree((char *) summaryPtr); + ckfree(summaryPtr); summaryPtr = nodePtr->summaryPtr; } } @@ -4552,9 +4558,8 @@ CharSplitProc( { TkTextSegment *newPtr1, *newPtr2; - newPtr1 = (TkTextSegment *) ckalloc(CSEG_SIZE(index)); - newPtr2 = (TkTextSegment *) ckalloc( - CSEG_SIZE(segPtr->size - index)); + newPtr1 = ckalloc(CSEG_SIZE(index)); + newPtr2 = ckalloc(CSEG_SIZE(segPtr->size - index)); newPtr1->typePtr = &tkTextCharType; newPtr1->nextPtr = newPtr2; newPtr1->size = index; @@ -4565,7 +4570,7 @@ CharSplitProc( newPtr2->size = segPtr->size - index; memcpy(newPtr2->body.chars, segPtr->body.chars + index, newPtr2->size); newPtr2->body.chars[newPtr2->size] = 0; - ckfree((char *) segPtr); + ckfree(segPtr); return newPtr1; } @@ -4600,16 +4605,15 @@ CharCleanupProc( if ((segPtr2 == NULL) || (segPtr2->typePtr != &tkTextCharType)) { return segPtr; } - newPtr = (TkTextSegment *) ckalloc(CSEG_SIZE( - segPtr->size + segPtr2->size)); + newPtr = ckalloc(CSEG_SIZE(segPtr->size + segPtr2->size)); newPtr->typePtr = &tkTextCharType; newPtr->nextPtr = segPtr2->nextPtr; newPtr->size = segPtr->size + segPtr2->size; memcpy(newPtr->body.chars, segPtr->body.chars, segPtr->size); memcpy(newPtr->body.chars + segPtr->size, segPtr2->body.chars, segPtr2->size); newPtr->body.chars[newPtr->size] = 0; - ckfree((char *) segPtr); - ckfree((char *) segPtr2); + ckfree(segPtr); + ckfree(segPtr2); return newPtr; } @@ -4638,7 +4642,7 @@ CharDeleteProc( * deleted, so everything must get cleaned * up. */ { - ckfree((char *) segPtr); + ckfree(segPtr); return 0; } @@ -4714,7 +4718,7 @@ ToggleDeleteProc( * up. */ { if (treeGone) { - ckfree((char *) segPtr); + ckfree(segPtr); return 0; } @@ -4788,9 +4792,9 @@ ToggleCleanupProc( segPtr->body.toggle.tagPtr, -counts); } prevPtr->nextPtr = segPtr2->nextPtr; - ckfree((char *) segPtr2); + ckfree(segPtr2); segPtr2 = segPtr->nextPtr; - ckfree((char *) segPtr); + ckfree(segPtr); return segPtr2; } } diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c index c3874f1..fcefb9a 100644 --- a/generic/tkTextDisp.c +++ b/generic/tkTextDisp.c @@ -16,7 +16,7 @@ #include "tkInt.h" #include "tkText.h" -#ifdef __WIN32__ +#ifdef _WIN32 #include "tkWinInt.h" #elif defined(__CYGWIN__) #include "tkUnixInt.h" @@ -24,6 +24,11 @@ #ifdef MAC_OSX_TK #include "tkMacOSXInt.h" +#define OK_TO_LOG (!TkpAppIsDrawing()) +#define FORCE_DISPLAY(winPtr) TkpDisplayWindow(winPtr) +#else +#define OK_TO_LOG 1 +#define FORCE_DISPLAY(winPtr) #endif /* @@ -136,11 +141,15 @@ typedef struct StyleValues { * line of each text line. */ int lMargin2; /* Left margin, in pixels, for second and * later display lines of each text line. */ + Tk_3DBorder lMarginColor; /* Color of left margins (1 and 2). */ int offset; /* Offset in pixels of baseline, relative to * baseline of line. */ int overstrike; /* Non-zero means draw overstrike through * text. */ + XColor *overstrikeColor; /* Foreground color for overstrike through + * text. */ int rMargin; /* Right margin, in pixels. */ + Tk_3DBorder rMarginColor; /* Color of right margin. */ int spacing1; /* Spacing above first dline in text line. */ int spacing2; /* Spacing between lines of dline. */ int spacing3; /* Spacing below last dline in text line. */ @@ -149,6 +158,8 @@ typedef struct StyleValues { int tabStyle; /* One of TABULAR or WORDPROCESSOR. */ int underline; /* Non-zero means draw underline underneath * text. */ + XColor *underlineColor; /* Foreground color for underline underneath + * text. */ int elide; /* Zero means draw text, otherwise not. */ TkWrapMode wrapMode; /* How to handle wrap-around for this tag. * One of TEXT_WRAPMODE_CHAR, @@ -167,6 +178,8 @@ typedef struct TextStyle { GC bgGC; /* Graphics context for background. None means * use widget background. */ GC fgGC; /* Graphics context for foreground. */ + GC ulGC; /* Graphics context for underline. */ + GC ovGC; /* Graphics context for overstrike. */ StyleValues *sValuePtr; /* Raw information from which GCs were * derived. */ Tcl_HashEntry *hPtr; /* Pointer to entry in styleTable. Used to @@ -195,12 +208,21 @@ typedef struct TextStyle { (fabs((double1)-(double2))*((scaleFactor)+1.0) < 0.3) /* - * Macro to make debugging/testing logging a little easier. + * Macros to make debugging/testing logging a little easier. + * + * On OSX 10.14 Drawing procedures are sometimes run because the system has + * decided to redraw the window. This can corrupt the data that a test is + * trying to collect. So we don't write to the logging variables when the + * drawing procedure is being run that way. Other systems can always log. */ -#define LOG(toVar,what) \ - Tcl_SetVar2(textPtr->interp, toVar, NULL, (what), \ - TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT) +#define LOG(toVar,what) \ + if (OK_TO_LOG) \ + Tcl_SetVar2(textPtr->interp, toVar, NULL, (what), \ + TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT) +#define CLEAR(var) \ + if (OK_TO_LOG) \ + Tcl_SetVar2(interp, var, NULL, "", TCL_GLOBAL_ONLY) /* * The following structure describes one line of the display, which may be @@ -234,6 +256,14 @@ typedef struct DLine { int spaceBelow; /* How much extra space was added to the * bottom of the line because of spacing * options. This is included in height. */ + Tk_3DBorder lMarginColor; /* Background color of the area corresponding + * to the left margin of the display line. */ + int lMarginWidth; /* Pixel width of the area corresponding to + * the left margin. */ + Tk_3DBorder rMarginColor; /* Background color of the area corresponding + * to the right margin of the display line. */ + int rMarginWidth; /* Pixel width of the area corresponding to + * the right margin. */ int length; /* Total length of line, in pixels. */ TkTextDispChunk *chunkPtr; /* Pointer to first chunk in list of all of * those that are displayed on this line of @@ -416,8 +446,8 @@ typedef struct TextDInfo { typedef struct CharInfo { int numBytes; /* Number of bytes to display. */ - char chars[4]; /* UTF characters to display. Actual size will - * be numBytes, not 4. THIS MUST BE THE LAST + char chars[1]; /* UTF characters to display. Actual size will + * be numBytes, not 1. THIS MUST BE THE LAST * FIELD IN THE STRUCTURE. */ } CharInfo; @@ -447,6 +477,7 @@ typedef struct BaseCharInfo { * LayoutDLine(). */ } BaseCharInfo; +/* TODO: Thread safety */ static TkTextDispChunk *baseCharChunkPtr = NULL; #endif /* TK_LAYOUT_WITH_BASE_CHUNKS */ @@ -466,13 +497,15 @@ static TkTextDispChunk *baseCharChunkPtr = NULL; * different character might be under the mouse * cursor now). Need to recompute the current * character before the next redisplay. + * OUT_OF_SYNC 1 means that the last <<WidgetViewSync>> event had + * value 0, indicating that the widget is out of sync. */ #define DINFO_OUT_OF_DATE 1 #define REDRAW_PENDING 2 #define REDRAW_BORDERS 4 #define REPICK_NEEDED 8 - +#define OUT_OF_SYNC 16 /* * Action values for FreeDLines: * @@ -544,23 +577,23 @@ static void DisplayLineBackground(TkText *textPtr, DLine *dlPtr, DLine *prevPtr, Pixmap pixmap); static void DisplayText(ClientData clientData); static DLine * FindDLine(TkText *textPtr, DLine *dlPtr, - CONST TkTextIndex *indexPtr); + const TkTextIndex *indexPtr); static void FreeDLines(TkText *textPtr, DLine *firstPtr, DLine *lastPtr, int action); static void FreeStyle(TkText *textPtr, TextStyle *stylePtr); -static TextStyle * GetStyle(TkText *textPtr, CONST TkTextIndex *indexPtr); +static TextStyle * GetStyle(TkText *textPtr, const TkTextIndex *indexPtr); static void GetXView(Tcl_Interp *interp, TkText *textPtr, int report); static void GetYView(Tcl_Interp *interp, TkText *textPtr, int report); static int GetYPixelCount(TkText *textPtr, DLine *dlPtr); static DLine * LayoutDLine(TkText *textPtr, - CONST TkTextIndex *indexPtr); -static int MeasureChars(Tk_Font tkfont, CONST char *source, + const TkTextIndex *indexPtr); +static int MeasureChars(Tk_Font tkfont, const char *source, int maxBytes, int rangeStart, int rangeLength, int startX, int maxX, int flags, int *nextXPtr); static void MeasureUp(TkText *textPtr, - CONST TkTextIndex *srcPtr, int distance, + const TkTextIndex *srcPtr, int distance, TkTextIndex *dstPtr, int *overlap); static int NextTabStop(Tk_Font tkfont, int x, int tabOrigin); static void UpdateDisplayInfo(TkText *textPtr); @@ -570,8 +603,8 @@ static int SizeOfTab(TkText *textPtr, int tabStyle, TkTextTabArray *tabArrayPtr, int *indexPtr, int x, int maxX); static void TextChanged(TkText *textPtr, - CONST TkTextIndex *index1Ptr, - CONST TkTextIndex *index2Ptr); + const TkTextIndex *index1Ptr, + const TkTextIndex *index2Ptr); static void TextInvalidateRegion(TkText *textPtr, TkRegion region); static void TextRedrawTag(TkText *textPtr, TkTextIndex *index1Ptr, TkTextIndex *index2Ptr, @@ -579,7 +612,7 @@ static void TextRedrawTag(TkText *textPtr, static void TextInvalidateLineMetrics(TkText *textPtr, TkTextLine *linePtr, int lineCount, int action); static int CalculateDisplayLineHeight(TkText *textPtr, - CONST TkTextIndex *indexPtr, int *byteCountPtr, + const TkTextIndex *indexPtr, int *byteCountPtr, int *mergedLinePtr); static void DlineIndexOfX(TkText *textPtr, DLine *dlPtr, int x, TkTextIndex *indexPtr); @@ -587,9 +620,10 @@ static int DlineXOfIndex(TkText *textPtr, DLine *dlPtr, int byteIndex); static int TextGetScrollInfoObj(Tcl_Interp *interp, TkText *textPtr, int objc, - Tcl_Obj *CONST objv[], double *dblPtr, + Tcl_Obj *const objv[], double *dblPtr, int *intPtr); static void AsyncUpdateLineMetrics(ClientData clientData); +static void GenerateWidgetViewSyncEvent(TkText *textPtr, Bool InSync); static void AsyncUpdateYScrollbar(ClientData clientData); static int IsStartOfNotMergedLine(TkText *textPtr, CONST TkTextIndex *indexPtr); @@ -629,7 +663,7 @@ TkTextCreateDInfo( register TextDInfo *dInfoPtr; XGCValues gcValues; - dInfoPtr = (TextDInfo *) ckalloc(sizeof(TextDInfo)); + dInfoPtr = ckalloc(sizeof(TextDInfo)); Tcl_InitHashTable(&dInfoPtr->styleTable, sizeof(StyleValues)/sizeof(int)); dInfoPtr->dLinePtr = NULL; dInfoPtr->copyGC = NULL; @@ -649,7 +683,7 @@ TkTextCreateDInfo( dInfoPtr->scanTotalYScroll = 0; dInfoPtr->scanMarkY = 0; dInfoPtr->dLinesInvalidated = 0; - dInfoPtr->flags = DINFO_OUT_OF_DATE; + dInfoPtr->flags = 0; dInfoPtr->topPixelOffset = 0; dInfoPtr->newTopPixelOffset = 0; dInfoPtr->currentMetricUpdateLine = -1; @@ -701,7 +735,7 @@ TkTextFreeDInfo( } Tk_FreeGC(textPtr->display, dInfoPtr->scrollGC); if (dInfoPtr->flags & REDRAW_PENDING) { - Tcl_CancelIdleCall(DisplayText, (ClientData) textPtr); + Tcl_CancelIdleCall(DisplayText, textPtr); } if (dInfoPtr->lineUpdateTimer != NULL) { Tcl_DeleteTimerHandler(dInfoPtr->lineUpdateTimer); @@ -713,7 +747,7 @@ TkTextFreeDInfo( textPtr->refCount--; dInfoPtr->scrollbarTimer = NULL; } - ckfree((char *) dInfoPtr); + ckfree(dInfoPtr); } /* @@ -737,7 +771,7 @@ TkTextFreeDInfo( static TextStyle * GetStyle( TkText *textPtr, /* Overall information about text widget. */ - CONST TkTextIndex *indexPtr)/* The character in the text for which display + const TkTextIndex *indexPtr)/* The character in the text for which display * information is wanted. */ { TkTextTag **tagPtrs; @@ -746,6 +780,7 @@ GetStyle( TextStyle *stylePtr; Tcl_HashEntry *hPtr; int numTags, isNew, i; + int isSelected; XGCValues gcValues; unsigned long mask; /* @@ -756,6 +791,7 @@ GetStyle( int fgPrio, fontPrio, fgStipplePrio; int underlinePrio, elidePrio, justifyPrio, offsetPrio; int lMargin1Prio, lMargin2Prio, rMarginPrio; + int lMarginColorPrio, rMarginColorPrio; int spacing1Prio, spacing2Prio, spacing3Prio; int overstrikePrio, tabPrio, tabStylePrio, wrapPrio; @@ -770,11 +806,14 @@ GetStyle( fgPrio = fontPrio = fgStipplePrio = -1; underlinePrio = elidePrio = justifyPrio = offsetPrio = -1; lMargin1Prio = lMargin2Prio = rMarginPrio = -1; + lMarginColorPrio = rMarginColorPrio = -1; spacing1Prio = spacing2Prio = spacing3Prio = -1; overstrikePrio = tabPrio = tabStylePrio = wrapPrio = -1; memset(&styleValues, 0, sizeof(StyleValues)); styleValues.relief = TK_RELIEF_FLAT; styleValues.fgColor = textPtr->fgColor; + styleValues.underlineColor = textPtr->fgColor; + styleValues.overstrikeColor = textPtr->fgColor; styleValues.tkfont = textPtr->tkfont; styleValues.justify = TK_JUSTIFY_LEFT; styleValues.spacing1 = textPtr->spacing1; @@ -784,12 +823,22 @@ GetStyle( styleValues.tabStyle = textPtr->tabStyle; styleValues.wrapMode = textPtr->wrapMode; styleValues.elide = 0; + isSelected = 0; + + for (i = 0 ; i < numTags; i++) { + if (textPtr->selTagPtr == tagPtrs[i]) { + isSelected = 1; + break; + } + } for (i = 0 ; i < numTags; i++) { Tk_3DBorder border; + XColor *fgColor; tagPtr = tagPtrs[i]; border = tagPtr->border; + fgColor = tagPtr->fgColor; /* * If this is the selection tag, and inactiveSelBorder is NULL (the @@ -809,6 +858,14 @@ GetStyle( border = textPtr->inactiveSelBorder; } + if ((tagPtr->selBorder != NULL) && (isSelected)) { + border = tagPtr->selBorder; + } + + if ((tagPtr->selFgColor != NULL) && isSelected) { + fgColor = tagPtr->selFgColor; + } + if ((border != NULL) && (tagPtr->priority > borderPrio)) { styleValues.border = border; borderPrio = tagPtr->priority; @@ -832,8 +889,8 @@ GetStyle( styleValues.bgStipple = tagPtr->bgStipple; bgStipplePrio = tagPtr->priority; } - if ((tagPtr->fgColor != NULL) && (tagPtr->priority > fgPrio)) { - styleValues.fgColor = tagPtr->fgColor; + if ((fgColor != NULL) && (tagPtr->priority > fgPrio)) { + styleValues.fgColor = fgColor; fgPrio = tagPtr->priority; } if ((tagPtr->tkfont != NULL) && (tagPtr->priority > fontPrio)) { @@ -860,6 +917,11 @@ GetStyle( styleValues.lMargin2 = tagPtr->lMargin2; lMargin2Prio = tagPtr->priority; } + if ((tagPtr->lMarginColor != NULL) + && (tagPtr->priority > lMarginColorPrio)) { + styleValues.lMarginColor = tagPtr->lMarginColor; + lMarginColorPrio = tagPtr->priority; + } if ((tagPtr->offsetString != NULL) && (tagPtr->priority > offsetPrio)) { styleValues.offset = tagPtr->offset; @@ -869,12 +931,22 @@ GetStyle( && (tagPtr->priority > overstrikePrio)) { styleValues.overstrike = tagPtr->overstrike; overstrikePrio = tagPtr->priority; + if (tagPtr->overstrikeColor != NULL) { + styleValues.overstrikeColor = tagPtr->overstrikeColor; + } else if (fgColor != NULL) { + styleValues.overstrikeColor = fgColor; + } } if ((tagPtr->rMarginString != NULL) && (tagPtr->priority > rMarginPrio)) { styleValues.rMargin = tagPtr->rMargin; rMarginPrio = tagPtr->priority; } + if ((tagPtr->rMarginColor != NULL) + && (tagPtr->priority > rMarginColorPrio)) { + styleValues.rMarginColor = tagPtr->rMarginColor; + rMarginColorPrio = tagPtr->priority; + } if ((tagPtr->spacing1String != NULL) && (tagPtr->priority > spacing1Prio)) { styleValues.spacing1 = tagPtr->spacing1; @@ -904,6 +976,11 @@ GetStyle( && (tagPtr->priority > underlinePrio)) { styleValues.underline = tagPtr->underline; underlinePrio = tagPtr->priority; + if (tagPtr->underlineColor != NULL) { + styleValues.underlineColor = tagPtr->underlineColor; + } else if (fgColor != NULL) { + styleValues.underlineColor = fgColor; + } } if ((tagPtr->elideString != NULL) && (tagPtr->priority > elidePrio)) { @@ -917,7 +994,7 @@ GetStyle( } } if (tagPtrs != NULL) { - ckfree((char *) tagPtrs); + ckfree(tagPtrs); } /* @@ -927,7 +1004,7 @@ GetStyle( hPtr = Tcl_CreateHashEntry(&textPtr->dInfoPtr->styleTable, (char *) &styleValues, &isNew); if (!isNew) { - stylePtr = (TextStyle *) Tcl_GetHashValue(hPtr); + stylePtr = Tcl_GetHashValue(hPtr); stylePtr->refCount++; return stylePtr; } @@ -936,7 +1013,7 @@ GetStyle( * No existing style matched. Make a new one. */ - stylePtr = (TextStyle *) ckalloc(sizeof(TextStyle)); + stylePtr = ckalloc(sizeof(TextStyle)); stylePtr->refCount = 1; if (styleValues.border != NULL) { gcValues.foreground = Tk_3DBorderColor(styleValues.border)->pixel; @@ -960,6 +1037,11 @@ GetStyle( mask |= GCStipple|GCFillStyle; } stylePtr->fgGC = Tk_GetGC(textPtr->tkwin, mask, &gcValues); + mask = GCForeground; + gcValues.foreground = styleValues.underlineColor->pixel; + stylePtr->ulGC = Tk_GetGC(textPtr->tkwin, mask, &gcValues); + gcValues.foreground = styleValues.overstrikeColor->pixel; + stylePtr->ovGC = Tk_GetGC(textPtr->tkwin, mask, &gcValues); stylePtr->sValuePtr = (StyleValues *) Tcl_GetHashKey(&textPtr->dInfoPtr->styleTable, hPtr); stylePtr->hPtr = hPtr; @@ -1000,8 +1082,14 @@ FreeStyle( if (stylePtr->fgGC != NULL) { Tk_FreeGC(textPtr->display, stylePtr->fgGC); } + if (stylePtr->ulGC != NULL) { + Tk_FreeGC(textPtr->display, stylePtr->ulGC); + } + if (stylePtr->ovGC != NULL) { + Tk_FreeGC(textPtr->display, stylePtr->ovGC); + } Tcl_DeleteHashEntry(stylePtr->hPtr); - ckfree((char *) stylePtr); + ckfree(stylePtr); } } @@ -1042,7 +1130,7 @@ FreeStyle( static DLine * LayoutDLine( TkText *textPtr, /* Overall information about text widget. */ - CONST TkTextIndex *indexPtr)/* Beginning of display line. May not + const TkTextIndex *indexPtr)/* Beginning of display line. May not * necessarily point to a character * segment. */ { @@ -1100,7 +1188,7 @@ LayoutDLine( * Create and initialize a new DLine structure. */ - dlPtr = (DLine *) ckalloc(sizeof(DLine)); + dlPtr = ckalloc(sizeof(DLine)); dlPtr->index = *indexPtr; dlPtr->byteCount = 0; dlPtr->y = 0; @@ -1111,6 +1199,10 @@ LayoutDLine( dlPtr->nextPtr = NULL; dlPtr->flags = NEW_LAYOUT | OLD_Y_INVALID; dlPtr->logicalLinesMerged = 0; + dlPtr->lMarginColor = NULL; + dlPtr->lMarginWidth = 0; + dlPtr->rMarginColor = NULL; + dlPtr->rMarginWidth = 0; /* * This is not necessarily totally correct, where we have merged logical @@ -1260,14 +1352,14 @@ LayoutDLine( */ TkTextLine *linePtr = TkBTreeNextLine(NULL, curIndex.linePtr); - if (linePtr != NULL) { - dlPtr->logicalLinesMerged++; - curIndex.byteIndex = 0; - curIndex.linePtr = linePtr; - segPtr = curIndex.linePtr->segPtr; - } else { + if (linePtr == NULL) { break; } + + dlPtr->logicalLinesMerged++; + curIndex.byteIndex = 0; + curIndex.linePtr = linePtr; + segPtr = curIndex.linePtr->segPtr; } } @@ -1331,7 +1423,7 @@ LayoutDLine( * into a single display line. * if (segPtr == NULL && chunkPtr != NULL) { - ckfree((char *) chunkPtr); + ckfree(chunkPtr); chunkPtr = NULL; } */ @@ -1345,7 +1437,7 @@ LayoutDLine( continue; } if (chunkPtr == NULL) { - chunkPtr = (TkTextDispChunk *) ckalloc(sizeof(TkTextDispChunk)); + chunkPtr = ckalloc(sizeof(TkTextDispChunk)); chunkPtr->nextPtr = NULL; chunkPtr->clientData = NULL; } @@ -1385,6 +1477,7 @@ LayoutDLine( x = chunkPtr->stylePtr->sValuePtr->lMargin2; } + dlPtr->lMarginWidth = x; if (wrapMode == TEXT_WRAPMODE_NONE) { maxX = -1; } else { @@ -1454,7 +1547,7 @@ LayoutDLine( code = 1; } else { - code = (*segPtr->typePtr->layoutProc)(textPtr, &curIndex, segPtr, + code = segPtr->typePtr->layoutProc(textPtr, &curIndex, segPtr, byteOffset, maxX-tabSize, maxBytes, noCharsYet, wrapMode, chunkPtr); } @@ -1477,7 +1570,7 @@ LayoutDLine( */ if (chunkPtr != NULL) { - ckfree((char *) chunkPtr); + ckfree(chunkPtr); } break; } @@ -1606,18 +1699,18 @@ LayoutDLine( FreeStyle(textPtr, chunkPtr->stylePtr); breakChunkPtr->nextPtr = chunkPtr->nextPtr; if (chunkPtr->undisplayProc != NULL) { - (*chunkPtr->undisplayProc)(textPtr, chunkPtr); + chunkPtr->undisplayProc(textPtr, chunkPtr); } - ckfree((char *) chunkPtr); + ckfree(chunkPtr); } if (breakByteOffset != breakChunkPtr->numBytes) { if (breakChunkPtr->undisplayProc != NULL) { - (*breakChunkPtr->undisplayProc)(textPtr, breakChunkPtr); + breakChunkPtr->undisplayProc(textPtr, breakChunkPtr); } segPtr = TkTextIndexToSeg(&breakIndex, &byteOffset); - (*segPtr->typePtr->layoutProc)(textPtr, &breakIndex, - segPtr, byteOffset, maxX, breakByteOffset, 0, - wrapMode, breakChunkPtr); + segPtr->typePtr->layoutProc(textPtr, &breakIndex, segPtr, + byteOffset, maxX, breakByteOffset, 0, wrapMode, + breakChunkPtr); #if TK_LAYOUT_WITH_BASE_CHUNKS FinalizeBaseChunk(NULL); #endif /* TK_LAYOUT_WITH_BASE_CHUNKS */ @@ -1696,6 +1789,11 @@ LayoutDLine( } dlPtr->height += dlPtr->spaceAbove + dlPtr->spaceBelow; dlPtr->baseline += dlPtr->spaceAbove; + dlPtr->lMarginColor = sValuePtr->lMarginColor; + dlPtr->rMarginColor = sValuePtr->rMarginColor; + if (wrapMode != TEXT_WRAPMODE_NONE) { + dlPtr->rMarginWidth = rMargin; + } /* * Recompute line length: may have changed because of justification. @@ -2302,13 +2400,13 @@ FreeDLines( for (chunkPtr = firstPtr->chunkPtr; chunkPtr != NULL; chunkPtr = nextChunkPtr) { if (chunkPtr->undisplayProc != NULL) { - (*chunkPtr->undisplayProc)(textPtr, chunkPtr); + chunkPtr->undisplayProc(textPtr, chunkPtr); } FreeStyle(textPtr, chunkPtr->stylePtr); nextChunkPtr = chunkPtr->nextPtr; - ckfree((char *) chunkPtr); + ckfree(chunkPtr); } - ckfree((char *) firstPtr); + ckfree(firstPtr); firstPtr = nextDLinePtr; } if (action != DLINE_FREE_TEMP) { @@ -2382,12 +2480,26 @@ DisplayDLine( Tk_Width(textPtr->tkwin), dlPtr->height, 0, TK_RELIEF_FLAT); /* - * Next, draw background information for the whole line. + * Second, draw background information for the whole line. */ DisplayLineBackground(textPtr, dlPtr, prevPtr, pixmap); /* + * Third, draw the background color of the left and right margins. + */ + if (dlPtr->lMarginColor != NULL) { + Tk_Fill3DRectangle(textPtr->tkwin, pixmap, dlPtr->lMarginColor, 0, y, + dlPtr->lMarginWidth + dInfoPtr->x - dInfoPtr->curXPixelOffset, + dlPtr->height, 0, TK_RELIEF_FLAT); + } + if (dlPtr->rMarginColor != NULL) { + Tk_Fill3DRectangle(textPtr->tkwin, pixmap, dlPtr->rMarginColor, + dInfoPtr->maxX - dlPtr->rMarginWidth + dInfoPtr->curXPixelOffset, + y, dlPtr->rMarginWidth, dlPtr->height, 0, TK_RELIEF_FLAT); + } + + /* * Make another pass through all of the chunks to redraw the insertion * cursor, if it is visible on this line. Must do it here rather than in * the foreground pass below because otherwise a wide insertion cursor @@ -2400,7 +2512,7 @@ DisplayDLine( if (chunkPtr->displayProc == TkTextInsertDisplayProc) { int x = chunkPtr->x + dInfoPtr->x - dInfoPtr->curXPixelOffset; - (*chunkPtr->displayProc)(textPtr, chunkPtr, x, + chunkPtr->displayProc(textPtr, chunkPtr, x, y + dlPtr->spaceAbove, dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow, dlPtr->baseline - dlPtr->spaceAbove, display, pixmap, @@ -2448,7 +2560,7 @@ DisplayDLine( x = -chunkPtr->width; } - (*chunkPtr->displayProc)(textPtr, chunkPtr, x, + chunkPtr->displayProc(textPtr, chunkPtr, x, y + dlPtr->spaceAbove, dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow, dlPtr->baseline - dlPtr->spaceAbove, display, pixmap, dlPtr->y + dlPtr->spaceAbove); @@ -2897,7 +3009,7 @@ static void AsyncUpdateLineMetrics( ClientData clientData) /* Information about widget. */ { - register TkText *textPtr = (TkText *) clientData; + register TkText *textPtr = clientData; TextDInfo *dInfoPtr = textPtr->dInfoPtr; int lineNum; @@ -2909,8 +3021,8 @@ AsyncUpdateLineMetrics( * The widget has been deleted, or is not mapped. Don't do anything. */ - if (--textPtr->refCount == 0) { - ckfree((char *) textPtr); + if (textPtr->refCount-- <= 1) { + ckfree(textPtr); } return; } @@ -2921,6 +3033,11 @@ AsyncUpdateLineMetrics( return; } + /* + * Reify where we end or all hell breaks loose with the calculations when + * we try to update. [Bug 2677890] + */ + lineNum = dInfoPtr->currentMetricUpdateLine; if (dInfoPtr->lastMetricUpdateLine == -1) { dInfoPtr->lastMetricUpdateLine = @@ -2935,6 +3052,8 @@ AsyncUpdateLineMetrics( lineNum = TkTextUpdateLineMetrics(textPtr, lineNum, dInfoPtr->lastMetricUpdateLine, 256); + dInfoPtr->currentMetricUpdateLine = lineNum; + if (tkTextDebug) { char buffer[2 * TCL_INTEGER_SPACE + 1]; @@ -2952,16 +3071,38 @@ AsyncUpdateLineMetrics( /* * We have looped over all lines, so we're done. We must release our * refCount on the widget (the timer token was already set to NULL - * above). + * above). If there is a registered aftersync command, run that first. + * Cancel any pending idle task which would try to run the command + * after the afterSyncCmd pointer had been set to NULL. */ - textPtr->refCount--; - if (textPtr->refCount == 0) { - ckfree((char *) textPtr); + if (textPtr->afterSyncCmd) { + int code; + Tcl_CancelIdleCall(TkTextRunAfterSyncCmd, textPtr); + Tcl_Preserve((ClientData) textPtr->interp); + code = Tcl_EvalObjEx(textPtr->interp, textPtr->afterSyncCmd, + TCL_EVAL_GLOBAL); + if (code == TCL_ERROR) { + Tcl_AddErrorInfo(textPtr->interp, "\n (text sync)"); + Tcl_BackgroundError(textPtr->interp); + } + Tcl_Release((ClientData) textPtr->interp); + Tcl_DecrRefCount(textPtr->afterSyncCmd); + textPtr->afterSyncCmd = NULL; + } + + /* + * Fire the <<WidgetViewSync>> event since the widget view is in sync + * with its internal data (actually it will be after the next trip + * through the event loop, because the widget redraws at idle-time). + */ + GenerateWidgetViewSyncEvent(textPtr, 1); + + if (textPtr->refCount-- <= 1) { + ckfree(textPtr); } return; } - dInfoPtr->currentMetricUpdateLine = lineNum; /* * Re-arm the timer. We already have a refCount on the text widget so no @@ -2969,7 +3110,65 @@ AsyncUpdateLineMetrics( */ dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1, - AsyncUpdateLineMetrics, (ClientData) textPtr); + AsyncUpdateLineMetrics, textPtr); +} + +/* + *---------------------------------------------------------------------- + * + * GenerateWidgetViewSyncEvent -- + * + * Send the <<WidgetViewSync>> event related to the text widget + * line metrics asynchronous update. These events should only + * be sent when the sync status has changed. So this function + * compares the requested state with the state saved in the + * TkText structure, and only generates the event if they are + * different. This means that it is safe to call this function + * at any time when the state is known. + * + * If an event is sent, the effect is equivalent to: + * event generate $textWidget <<WidgetViewSync>> -data $s + * where $s is the sync status: true (when the widget view is in + * sync with its internal data) or false (when it is not). + * + * Results: + * None + * + * Side effects: + * If corresponding bindings are present, they will trigger. + * + *---------------------------------------------------------------------- + */ + +static void +GenerateWidgetViewSyncEvent( + TkText *textPtr, /* Information about text widget. */ + Bool InSync) /* true if becoming in sync, false otherwise */ +{ + Bool NewSyncState = (InSync != 0); /* ensure 0 or 1 value */ + Bool OldSyncState = !(textPtr->dInfoPtr->flags & OUT_OF_SYNC); + + /* + * OSX 10.14 needs to be told to display the window when the Text Widget + * is in sync. (That is, to run DisplayText inside of the drawRect + * method.) Otherwise the screen might not get updated until an event + * like a mouse click is received. But that extra drawing corrupts the + * data that the test suite is trying to collect. + */ + + if (!tkTextDebug) { + FORCE_DISPLAY(textPtr->tkwin); + } + + if (NewSyncState != OldSyncState) { + if (NewSyncState) { + textPtr->dInfoPtr->flags &= ~OUT_OF_SYNC; + } else { + textPtr->dInfoPtr->flags |= OUT_OF_SYNC; + } + TkSendVirtualEvent(textPtr->tkwin, "WidgetViewSync", + Tcl_NewBooleanObj(NewSyncState)); + } } /* @@ -3012,6 +3211,9 @@ TkTextUpdateLineMetrics( TkTextLine *linePtr = NULL; int count = 0; int totalLines = TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr); + int fullUpdateRequested = (lineNum == 0 && + endLine == totalLines && + doThisMuch == -1); if (totalLines == 0) { /* @@ -3022,6 +3224,7 @@ TkTextUpdateLineMetrics( } while (1) { + /* * Get a suitable line. */ @@ -3048,6 +3251,7 @@ TkTextUpdateLineMetrics( */ if (textPtr->dInfoPtr->metricEpoch == -1 && lineNum == endLine) { + /* * We have looped over all lines, so we're done. */ @@ -3070,88 +3274,90 @@ TkTextUpdateLineMetrics( */ if (TkBTreeLinePixelEpoch(textPtr, linePtr) - != textPtr->dInfoPtr->lineMetricUpdateEpoch) { - if (doThisMuch == -1) { - count += 8 * TkTextUpdateOneLine(textPtr, linePtr, 0, - NULL, 0); + == textPtr->dInfoPtr->lineMetricUpdateEpoch) { + + /* + * This line is already up to date. That means there's nothing + * to do here. + */ + + } else if (doThisMuch == -1) { + count += 8 * TkTextUpdateOneLine(textPtr, linePtr, 0,NULL,0); + } else { + TkTextIndex index; + TkTextIndex *indexPtr; + int pixelHeight; + + /* + * If the metric epoch is the same as the widget's epoch, then + * we know that indexPtrs are still valid, and if the cached + * metricIndex (if any) is for the same line as we wish to + * examine, then we are looking at a long line wrapped many + * times, which we will examine in pieces. + */ + + if (textPtr->dInfoPtr->metricEpoch == + textPtr->sharedTextPtr->stateEpoch && + textPtr->dInfoPtr->metricIndex.linePtr==linePtr) { + indexPtr = &textPtr->dInfoPtr->metricIndex; + pixelHeight = textPtr->dInfoPtr->metricPixelHeight; } else { - TkTextIndex index; - TkTextIndex *indexPtr; - int pixelHeight; /* - * If the metric epoch is the same as the widget's epoch, - * then we know that indexPtrs are still valid, and if the - * cached metricIndex (if any) is for the same line as we - * wish to examine, then we are looking at a long line - * wrapped many times, which we will examine in pieces. + * We must reset the partial line height calculation data + * here, so we don't use it when it is out of date. */ - if (textPtr->dInfoPtr->metricEpoch == - textPtr->sharedTextPtr->stateEpoch && - textPtr->dInfoPtr->metricIndex.linePtr==linePtr) { - indexPtr = &textPtr->dInfoPtr->metricIndex; - pixelHeight = textPtr->dInfoPtr->metricPixelHeight; - } else { - /* - * We must reset the partial line height calculation - * data here, so we don't use it when it is out of - * date. - */ + textPtr->dInfoPtr->metricEpoch = -1; + index.tree = textPtr->sharedTextPtr->tree; + index.linePtr = linePtr; + index.byteIndex = 0; + index.textPtr = NULL; + indexPtr = &index; + pixelHeight = 0; + } - textPtr->dInfoPtr->metricEpoch = -1; - index.tree = textPtr->sharedTextPtr->tree; - index.linePtr = linePtr; - index.byteIndex = 0; - index.textPtr = NULL; - indexPtr = &index; - pixelHeight = 0; - } + /* + * Update the line and update the counter, counting 8 for each + * display line we actually re-layout. + */ - /* - * Update the line and update the counter, counting 8 for - * each display line we actually re-layout. - */ + count += 8 * TkTextUpdateOneLine(textPtr, linePtr, + pixelHeight, indexPtr, 1); - count += 8 * TkTextUpdateOneLine(textPtr, linePtr, - pixelHeight, indexPtr, 1); + if (indexPtr->linePtr == linePtr) { - if (indexPtr->linePtr == linePtr) { - /* - * We didn't complete the logical line, because it - * produced very many display lines - it must be a - * long line wrapped many times. So we must cache as - * far as we got for next time around. - */ + /* + * We didn't complete the logical line, because it + * produced very many display lines, which must be because + * it must be a long line wrapped many times. So we must + * cache as far as we got for next time around. + */ - if (pixelHeight == 0) { - /* - * These have already been stored, unless we just - * started the new line. - */ + if (pixelHeight == 0) { - textPtr->dInfoPtr->metricIndex = index; - textPtr->dInfoPtr->metricEpoch = - textPtr->sharedTextPtr->stateEpoch; - } - textPtr->dInfoPtr->metricPixelHeight = - TkBTreeLinePixelCount(textPtr, linePtr); - break; - } else { /* - * We're done with this long line. + * These have already been stored, unless we just + * started the new line. */ - textPtr->dInfoPtr->metricEpoch = -1; + textPtr->dInfoPtr->metricIndex = index; + textPtr->dInfoPtr->metricEpoch = + textPtr->sharedTextPtr->stateEpoch; } + textPtr->dInfoPtr->metricPixelHeight = + TkBTreeLinePixelCount(textPtr, linePtr); + break; } - } else { + /* - * This line is already up to date. That means there's nothing - * to do here. + * We're done with this long line. */ + + textPtr->dInfoPtr->metricEpoch = -1; } } else { + /* * We must never recalculate the height of the last artificial * line. It must stay at zero, and if we recalculate it, it will @@ -3176,13 +3382,17 @@ TkTextUpdateLineMetrics( } } if (doThisMuch == -1) { + /* - * If we were requested to provide a full update, then also update the - * scrollbar. + * If we were requested to update the entire range, then also update + * the scrollbar. */ GetYView(textPtr->interp, textPtr, 1); } + if (fullUpdateRequested) { + GenerateWidgetViewSyncEvent(textPtr, 1); + } return lineNum; } @@ -3350,8 +3560,13 @@ TextInvalidateLineMetrics( if (dInfoPtr->lineUpdateTimer == NULL) { textPtr->refCount++; dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1, - AsyncUpdateLineMetrics, (ClientData) textPtr); + AsyncUpdateLineMetrics, textPtr); } + + /* + * The widget is out of sync: send a <<WidgetViewSync>> event. + */ + GenerateWidgetViewSyncEvent(textPtr, 0); } /* @@ -3400,6 +3615,8 @@ TkTextFindDisplayLineEnd( * of the original index within its display * line. */ { + TkTextIndex index; + if (!end && IsStartOfNotMergedLine(textPtr, indexPtr)) { /* * Nothing to do. @@ -3409,96 +3626,94 @@ TkTextFindDisplayLineEnd( *xOffset = 0; } return; - } else { - TkTextIndex index = *indexPtr; - - index.byteIndex = 0; - index.textPtr = NULL; - - while (1) { - TkTextIndex endOfLastLine; + } - if (TkTextIndexBackBytes(textPtr, &index, 1, &endOfLastLine)) { - /* - * Reached beginning of text. - */ + index = *indexPtr; + index.byteIndex = 0; + index.textPtr = NULL; - break; - } + while (1) { + TkTextIndex endOfLastLine; - if (!TkTextIsElided(textPtr, &endOfLastLine, NULL)) { - /* - * The eol is not elided, so 'index' points to the start of a - * display line (as well as logical line). - */ + if (TkTextIndexBackBytes(textPtr, &index, 1, &endOfLastLine)) { + /* + * Reached beginning of text. + */ - break; - } + break; + } + if (!TkTextIsElided(textPtr, &endOfLastLine, NULL)) { /* - * indexPtr's logical line is actually merged with the previous - * logical line whose eol is elided. Continue searching back to - * get a real line start. + * The eol is not elided, so 'index' points to the start of a + * display line (as well as logical line). */ - index = endOfLastLine; - index.byteIndex = 0; + break; } - while (1) { - DLine *dlPtr; - int byteCount; - TkTextIndex nextLineStart; + /* + * indexPtr's logical line is actually merged with the previous + * logical line whose eol is elided. Continue searching back to get a + * real line start. + */ - dlPtr = LayoutDLine(textPtr, &index); - byteCount = dlPtr->byteCount; + index = endOfLastLine; + index.byteIndex = 0; + } - TkTextIndexForwBytes(textPtr, &index, byteCount, &nextLineStart); + while (1) { + DLine *dlPtr; + int byteCount; + TkTextIndex nextLineStart; + + dlPtr = LayoutDLine(textPtr, &index); + byteCount = dlPtr->byteCount; + + TkTextIndexForwBytes(textPtr, &index, byteCount, &nextLineStart); + + /* + * 'byteCount' goes up to the beginning of the next display line, so + * equality here says we need one more line. We try to perform a quick + * comparison which is valid for the case where the logical line is + * the same, but otherwise fall back on a full TkTextIndexCmp. + */ + if (((index.linePtr == indexPtr->linePtr) + && (index.byteIndex + byteCount > indexPtr->byteIndex)) + || (dlPtr->logicalLinesMerged > 0 + && TkTextIndexCmp(&nextLineStart, indexPtr) > 0)) { /* - * 'byteCount' goes up to the beginning of the next display line, - * so equality here says we need one more line. We try to perform - * a quick comparison which is valid for the case where the - * logical line is the same, but otherwise fall back on a full - * TkTextIndexCmp. + * It's on this display line. */ - if (((index.linePtr == indexPtr->linePtr) - && (index.byteIndex + byteCount > indexPtr->byteIndex)) - || (dlPtr->logicalLinesMerged > 0 - && TkTextIndexCmp(&nextLineStart, indexPtr) > 0)) { + if (xOffset != NULL) { /* - * It's on this display line. + * This call takes a byte index relative to the start of the + * current _display_ line, not logical line. We are about to + * overwrite indexPtr->byteIndex, so we must do this now. */ - if (xOffset != NULL) { - /* - * This call takes a byte index relative to the start of - * the current _display_ line, not logical line. We are - * about to overwrite indexPtr->byteIndex, so we must do - * this now. - */ - - *xOffset = DlineXOfIndex(textPtr, dlPtr, - TkTextIndexCountBytes(textPtr, &dlPtr->index, - indexPtr)); - } - if (end) { - /* - * The index we want is one less than the number of bytes - * in the display line. - */ + *xOffset = DlineXOfIndex(textPtr, dlPtr, + TkTextIndexCountBytes(textPtr, &dlPtr->index, + indexPtr)); + } + if (end) { + /* + * The index we want is one less than the number of bytes in + * the display line. + */ - TkTextIndexBackBytes(textPtr, &nextLineStart, 1, indexPtr); - } else { - *indexPtr = index; - } - FreeDLines(textPtr, dlPtr, NULL, DLINE_FREE_TEMP); - return; + TkTextIndexBackBytes(textPtr, &nextLineStart, 1, indexPtr); + } else { + *indexPtr = index; } FreeDLines(textPtr, dlPtr, NULL, DLINE_FREE_TEMP); - index = nextLineStart; + return; } + + FreeDLines(textPtr, dlPtr, NULL, DLINE_FREE_TEMP); + index = nextLineStart; } } @@ -3540,7 +3755,7 @@ TkTextFindDisplayLineEnd( static int CalculateDisplayLineHeight( TkText *textPtr, /* Widget record for text widget. */ - CONST TkTextIndex *indexPtr,/* The index at the beginning of the display + const TkTextIndex *indexPtr,/* The index at the beginning of the display * line of interest. */ int *byteCountPtr, /* NULL or used to return the number of byte * indices on the given display line. */ @@ -3632,7 +3847,7 @@ CalculateDisplayLineHeight( int TkTextIndexYPixels( TkText *textPtr, /* Widget record for text widget. */ - CONST TkTextIndex *indexPtr)/* The index of which we want the pixel + const TkTextIndex *indexPtr)/* The index of which we want the pixel * distance from top of logical line to top of * index. */ { @@ -3925,7 +4140,7 @@ TkTextUpdateOneLine( if (textPtr->dInfoPtr->scrollbarTimer == NULL) { textPtr->refCount++; textPtr->dInfoPtr->scrollbarTimer = Tcl_CreateTimerHandler(200, - AsyncUpdateYScrollbar, (ClientData) textPtr); + AsyncUpdateYScrollbar, textPtr); } return displayLines; } @@ -3951,7 +4166,7 @@ static void DisplayText( ClientData clientData) /* Information about widget. */ { - register TkText *textPtr = (TkText *) clientData; + register TkText *textPtr = clientData; TextDInfo *dInfoPtr = textPtr->dInfoPtr; register DLine *dlPtr; DLine *prevPtr; @@ -3969,9 +4184,9 @@ DisplayText( TkWindow *winPtr = (TkWindow *)(textPtr->tkwin); MacDrawable *macWin = winPtr->privatePtr; if (macWin && (macWin->flags & TK_DO_NOT_DRAW)){ - dInfoPtr->flags &= ~REDRAW_PENDING; - return; - } + dInfoPtr->flags &= ~REDRAW_PENDING; + return; + } #endif if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) { @@ -3983,10 +4198,10 @@ DisplayText( } interp = textPtr->interp; - Tcl_Preserve((ClientData) interp); + Tcl_Preserve(interp); if (tkTextDebug) { - Tcl_SetVar2(interp, "tk_textRelayout", NULL, "", TCL_GLOBAL_ONLY); + CLEAR("tk_textRelayout"); } if (!Tk_IsMapped(textPtr->tkwin) || (dInfoPtr->maxX <= dInfoPtr->x) @@ -3997,7 +4212,7 @@ DisplayText( } numRedisplays++; if (tkTextDebug) { - Tcl_SetVar2(interp, "tk_textRedraw", NULL, "", TCL_GLOBAL_ONLY); + CLEAR("tk_textRedraw"); } /* @@ -4012,8 +4227,8 @@ DisplayText( textPtr->refCount++; dInfoPtr->flags &= ~REPICK_NEEDED; TkTextPickCurrent(textPtr, &textPtr->pickEvent); - if (--textPtr->refCount == 0) { - ckfree((char *) textPtr); + if (textPtr->refCount-- <= 1) { + ckfree(textPtr); goto end; } if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) { @@ -4093,7 +4308,7 @@ DisplayText( */ if ((y + height) > dInfoPtr->maxY) { - height = dInfoPtr->maxY -y; + height = dInfoPtr->maxY - y; } oldY = dlPtr->oldY; if (y < dInfoPtr->y) { @@ -4124,7 +4339,6 @@ DisplayText( } dlPtr = dlPtr->nextPtr; } - /* * Scan through the lines following the copied ones to see if we are * going to overwrite them with the copy operation. If so, mark them @@ -4149,7 +4363,6 @@ DisplayText( oldY, dInfoPtr->maxX-dInfoPtr->x, height, 0, y-oldY, damageRgn)) { TextInvalidateRegion(textPtr, damageRgn); - } numCopies++; TkDestroyRegion(damageRgn); @@ -4291,11 +4504,38 @@ DisplayText( } dlPtr->oldY = dlPtr->y; dlPtr->flags &= ~(NEW_LAYOUT | OLD_Y_INVALID); +#ifdef MAC_OSX_TK + } else if (dlPtr->chunkPtr != NULL) { + /* + * On macOS we need to redisplay all embedded windows which + * were moved by the call to TkScrollWindows above. This is + * not necessary on Unix or Windows because XScrollWindow will + * have included the bounding rectangles of all of these + * windows in the damage region. The macosx implementation of + * TkScrollWindow does not do this. It simply generates a + * damage region which is the scroll source rectangle minus + * the scroll destination rectangle. This is because there is + * no efficient process available for iterating through the + * subwindows which meet the scrolled area. (On Unix this is + * handled by GraphicsExpose events generated by XCopyArea and + * on Windows by ScrollWindowEx. On macOS the low level + * scrolling is accomplished by calling [view scrollRect:by:]. + * This method does not provide any damage information and, in + * any case, could not be aware of Tk windows which were not + * based on NSView objects. + * + * On the other hand, this loop is already iterating through + * all embedded windows which could possibly have been moved + * by the scrolling. So it is as efficient to redisplay them + * here as it would have been if they had been redisplayed by + * the call to TextInvalidateRegion above. + */ +#else } else if (dlPtr->chunkPtr != NULL && ((dlPtr->y < 0) || (dlPtr->y + dlPtr->height > dInfoPtr->maxY))) { - register TkTextDispChunk *chunkPtr; - /* + * On platforms other than the Mac: + * * It's the first or last DLine which are also overlapping the * top or bottom of the window, but we decided above it wasn't * necessary to display them (we were able to update them by @@ -4309,6 +4549,8 @@ DisplayText( * So, we loop through all the chunks, calling the display * proc of embedded windows only. */ +#endif + register TkTextDispChunk *chunkPtr; for (chunkPtr = dlPtr->chunkPtr; (chunkPtr != NULL); chunkPtr = chunkPtr->nextPtr) { @@ -4331,13 +4573,18 @@ DisplayText( x = -chunkPtr->width; } + if (tkTextDebug) { + char string[TK_POS_CHARS]; + + TkTextPrintIndex(textPtr, &dlPtr->index, string); + LOG("tk_textEmbWinDisplay", string); + } TkTextEmbWinDisplayProc(textPtr, chunkPtr, x, dlPtr->spaceAbove, dlPtr->height-dlPtr->spaceAbove-dlPtr->spaceBelow, dlPtr->baseline - dlPtr->spaceAbove, NULL, None, dlPtr->y + dlPtr->spaceAbove); } - } } #ifndef TK_NO_DOUBLE_BUFFERING @@ -4406,7 +4653,7 @@ DisplayText( } end: - Tcl_Release((ClientData) interp); + Tcl_Release(interp); } /* @@ -4435,7 +4682,7 @@ TkTextEventuallyRepick( dInfoPtr->flags |= REPICK_NEEDED; if (!(dInfoPtr->flags & REDRAW_PENDING)) { dInfoPtr->flags |= REDRAW_PENDING; - Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr); + Tcl_DoWhenIdle(DisplayText, textPtr); } } @@ -4479,7 +4726,7 @@ TkTextRedrawRegion( if (!(dInfoPtr->flags & REDRAW_PENDING)) { dInfoPtr->flags |= REDRAW_PENDING; - Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr); + Tcl_DoWhenIdle(DisplayText, textPtr); } TkDestroyRegion(damageRgn); } @@ -4573,8 +4820,8 @@ void TkTextChanged( TkSharedText *sharedTextPtr,/* Shared widget section, or NULL. */ TkText *textPtr, /* Widget record for text widget, or NULL. */ - CONST TkTextIndex*index1Ptr,/* Index of first character to redisplay. */ - CONST TkTextIndex*index2Ptr)/* Index of character just after last one to + const TkTextIndex*index1Ptr,/* Index of first character to redisplay. */ + const TkTextIndex*index2Ptr)/* Index of character just after last one to * redisplay. */ { if (sharedTextPtr == NULL) { @@ -4591,8 +4838,8 @@ TkTextChanged( static void TextChanged( TkText *textPtr, /* Widget record for text widget, or NULL. */ - CONST TkTextIndex*index1Ptr,/* Index of first character to redisplay. */ - CONST TkTextIndex*index2Ptr)/* Index of character just after last one to + const TkTextIndex*index1Ptr,/* Index of first character to redisplay. */ + const TkTextIndex*index2Ptr)/* Index of character just after last one to * redisplay. */ { TextDInfo *dInfoPtr = textPtr->dInfoPtr; @@ -4618,7 +4865,7 @@ TextChanged( */ if (!(dInfoPtr->flags & REDRAW_PENDING)) { - Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr); + Tcl_DoWhenIdle(DisplayText, textPtr); } dInfoPtr->flags |= REDRAW_PENDING|DINFO_OUT_OF_DATE|REPICK_NEEDED; @@ -4855,7 +5102,7 @@ TextRedrawTag( */ if (!(dInfoPtr->flags & REDRAW_PENDING)) { - Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr); + Tcl_DoWhenIdle(DisplayText, textPtr); } dInfoPtr->flags |= REDRAW_PENDING|DINFO_OUT_OF_DATE|REPICK_NEEDED; @@ -4952,6 +5199,7 @@ TkTextRelayoutWindow( TextDInfo *dInfoPtr = textPtr->dInfoPtr; GC newGC; XGCValues gcValues; + Bool inSync = 1; /* * Schedule the window redisplay. See TkTextChanged for the reason why @@ -4959,7 +5207,8 @@ TkTextRelayoutWindow( */ if (!(dInfoPtr->flags & REDRAW_PENDING)) { - Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr); + Tcl_DoWhenIdle(DisplayText, textPtr); + inSync = 0; } dInfoPtr->flags |= REDRAW_PENDING|REDRAW_BORDERS|DINFO_OUT_OF_DATE |REPICK_NEEDED; @@ -5031,6 +5280,7 @@ TkTextRelayoutWindow( dInfoPtr->yScrollFirst = dInfoPtr->yScrollLast = -1; if (mask & TK_TEXT_LINE_GEOMETRY) { + /* * Set up line metric recalculation. * @@ -5054,8 +5304,11 @@ TkTextRelayoutWindow( if (dInfoPtr->lineUpdateTimer == NULL) { textPtr->refCount++; dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1, - AsyncUpdateLineMetrics, (ClientData) textPtr); + AsyncUpdateLineMetrics, textPtr); + inSync = 0; } + + GenerateWidgetViewSyncEvent(textPtr, inSync); } } @@ -5253,7 +5506,7 @@ TkTextSetYView( scheduleUpdate: if (!(dInfoPtr->flags & REDRAW_PENDING)) { - Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr); + Tcl_DoWhenIdle(DisplayText, textPtr); } dInfoPtr->flags |= REDRAW_PENDING|DINFO_OUT_OF_DATE|REPICK_NEEDED; } @@ -5343,7 +5596,7 @@ TkTextMeasureDown( static void MeasureUp( TkText *textPtr, /* Text widget in which to measure. */ - CONST TkTextIndex *srcPtr, /* Index of character from which to start + const TkTextIndex *srcPtr, /* Index of character from which to start * measuring. */ int distance, /* Vertical distance in pixels measured from * the pixel just below the lowest one in @@ -5462,7 +5715,7 @@ TkTextSeeCmd( TkText *textPtr, /* Information about text widget. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. Someone else has already + Tcl_Obj *const objv[]) /* Argument objects. Someone else has already * parsed this command enough to know that * objv[1] is "see". */ { @@ -5542,7 +5795,7 @@ TkTextSeeCmd( */ if (chunkPtr != NULL) { - (*chunkPtr->bboxProc)(textPtr, chunkPtr, byteCount, + chunkPtr->bboxProc(textPtr, chunkPtr, byteCount, dlPtr->y + dlPtr->spaceAbove, dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow, dlPtr->baseline - dlPtr->spaceAbove, &x, &y, &width, @@ -5551,27 +5804,26 @@ TkTextSeeCmd( oneThird = lineWidth/3; if (delta < 0) { if (delta < -oneThird) { - dInfoPtr->newXPixelOffset = (x - lineWidth/2); + dInfoPtr->newXPixelOffset = x - lineWidth/2; } else { - dInfoPtr->newXPixelOffset -= ((-delta) ); + dInfoPtr->newXPixelOffset += delta; } } else { - delta -= (lineWidth - width); - if (delta > 0) { - if (delta > oneThird) { - dInfoPtr->newXPixelOffset = (x - lineWidth/2); - } else { - dInfoPtr->newXPixelOffset += (delta ); - } - } else { + delta -= lineWidth - width; + if (delta <= 0) { return TCL_OK; } + if (delta > oneThird) { + dInfoPtr->newXPixelOffset = x - lineWidth/2; + } else { + dInfoPtr->newXPixelOffset += delta; + } } } dInfoPtr->flags |= DINFO_OUT_OF_DATE; if (!(dInfoPtr->flags & REDRAW_PENDING)) { dInfoPtr->flags |= REDRAW_PENDING; - Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr); + Tcl_DoWhenIdle(DisplayText, textPtr); } return TCL_OK; } @@ -5599,7 +5851,7 @@ TkTextXviewCmd( TkText *textPtr, /* Information about text widget. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. Someone else has already + Tcl_Obj *const objv[]) /* Argument objects. Someone else has already * parsed this command enough to know that * objv[1] is "xview". */ { @@ -5652,7 +5904,7 @@ TkTextXviewCmd( dInfoPtr->flags |= DINFO_OUT_OF_DATE; if (!(dInfoPtr->flags & REDRAW_PENDING)) { dInfoPtr->flags |= REDRAW_PENDING; - Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr); + Tcl_DoWhenIdle(DisplayText, textPtr); } return TCL_OK; } @@ -5737,7 +5989,7 @@ YScrollByPixels( return; } if (!(dInfoPtr->flags & REDRAW_PENDING)) { - Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr); + Tcl_DoWhenIdle(DisplayText, textPtr); } dInfoPtr->flags |= REDRAW_PENDING|DINFO_OUT_OF_DATE|REPICK_NEEDED; } @@ -5872,7 +6124,7 @@ YScrollByLines( scheduleUpdate: if (!(dInfoPtr->flags & REDRAW_PENDING)) { - Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr); + Tcl_DoWhenIdle(DisplayText, textPtr); } dInfoPtr->flags |= REDRAW_PENDING|DINFO_OUT_OF_DATE|REPICK_NEEDED; } @@ -5900,7 +6152,7 @@ TkTextYviewCmd( TkText *textPtr, /* Information about text widget. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. Someone else has already + Tcl_Obj *const objv[]) /* Argument objects. Someone else has already * parsed this command enough to know that * objv[1] is "yview". */ { @@ -5926,7 +6178,7 @@ TkTextYviewCmd( pickPlace = 0; if (Tcl_GetString(objv[2])[0] == '-') { - register CONST char *switchStr = + register const char *switchStr = Tcl_GetStringFromObj(objv[2], &switchLength); if ((switchLength >= 2) && (strncmp(switchStr, "-pickplace", @@ -6061,6 +6313,32 @@ TkTextYviewCmd( /* *-------------------------------------------------------------- * + * TkTextPendingsync -- + * + * This function checks if any line heights are not up-to-date. + * + * Results: + * Returns a boolean true if it is the case, or false if all line + * heights are up-to-date. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + +Bool +TkTextPendingsync( + TkText *textPtr) /* Information about text widget. */ +{ + TextDInfo *dInfoPtr = textPtr->dInfoPtr; + + return ((dInfoPtr->flags & OUT_OF_SYNC) != 0); +} + +/* + *-------------------------------------------------------------- + * * TkTextScanCmd -- * * This function is invoked to process the "scan" option for the widget @@ -6081,7 +6359,7 @@ TkTextScanCmd( register TkText *textPtr, /* Information about text widget. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. Someone else has already + Tcl_Obj *const objv[]) /* Argument objects. Someone else has already * parsed this command enough to know that * objv[1] is "scan". */ { @@ -6152,7 +6430,7 @@ TkTextScanCmd( dInfoPtr->flags |= DINFO_OUT_OF_DATE; if (!(dInfoPtr->flags & REDRAW_PENDING)) { dInfoPtr->flags |= REDRAW_PENDING; - Tcl_DoWhenIdle(DisplayText, (ClientData) textPtr); + Tcl_DoWhenIdle(DisplayText, textPtr); } } else if (c=='m' && strncmp(Tcl_GetString(objv[2]), "mark", length)==0) { dInfoPtr->scanMarkXPixel = dInfoPtr->newXPixelOffset; @@ -6160,8 +6438,11 @@ TkTextScanCmd( dInfoPtr->scanTotalYScroll = 0; dInfoPtr->scanMarkY = y; } else { - Tcl_AppendResult(interp, "bad scan option \"", Tcl_GetString(objv[2]), - "\": must be mark or dragto", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad scan option \"%s\": must be mark or dragto", + Tcl_GetString(objv[2]))); + Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "scan option", + Tcl_GetString(objv[2]), NULL); return TCL_ERROR; } return TCL_OK; @@ -6234,16 +6515,22 @@ GetXView( if (textPtr->xScrollCmd != NULL) { char buf1[TCL_DOUBLE_SPACE+1]; char buf2[TCL_DOUBLE_SPACE+1]; + Tcl_DString buf; buf1[0] = ' '; buf2[0] = ' '; Tcl_PrintDouble(NULL, first, buf1+1); Tcl_PrintDouble(NULL, last, buf2+1); - code = Tcl_VarEval(interp, textPtr->xScrollCmd, buf1, buf2, NULL); + Tcl_DStringInit(&buf); + Tcl_DStringAppend(&buf, textPtr->xScrollCmd, -1); + Tcl_DStringAppend(&buf, buf1, -1); + Tcl_DStringAppend(&buf, buf2, -1); + code = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, 0); + Tcl_DStringFree(&buf); if (code != TCL_OK) { Tcl_AddErrorInfo(interp, "\n (horizontal scrolling command executed by text)"); - Tcl_BackgroundError(interp); + Tcl_BackgroundException(interp, code); } } } @@ -6362,9 +6649,8 @@ GetYPixelCount( notFirst = 1; } break; - } else { - dlPtr = dlPtr->nextPtr; } + dlPtr = dlPtr->nextPtr; } while (dlPtr->index.linePtr == linePtr); return count; @@ -6514,16 +6800,22 @@ GetYView( if (textPtr->yScrollCmd != NULL) { char buf1[TCL_DOUBLE_SPACE+1]; char buf2[TCL_DOUBLE_SPACE+1]; + Tcl_DString buf; buf1[0] = ' '; buf2[0] = ' '; Tcl_PrintDouble(NULL, first, buf1+1); Tcl_PrintDouble(NULL, last, buf2+1); - code = Tcl_VarEval(interp, textPtr->yScrollCmd, buf1, buf2, NULL); + Tcl_DStringInit(&buf); + Tcl_DStringAppend(&buf, textPtr->yScrollCmd, -1); + Tcl_DStringAppend(&buf, buf1, -1); + Tcl_DStringAppend(&buf, buf2, -1); + code = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, 0); + Tcl_DStringFree(&buf); if (code != TCL_OK) { Tcl_AddErrorInfo(interp, "\n (vertical scrolling command executed by text)"); - Tcl_BackgroundError(interp); + Tcl_BackgroundException(interp, code); } } } @@ -6550,7 +6842,7 @@ static void AsyncUpdateYScrollbar( ClientData clientData) /* Information about widget. */ { - register TkText *textPtr = (TkText *) clientData; + register TkText *textPtr = clientData; textPtr->dInfoPtr->scrollbarTimer = NULL; @@ -6558,8 +6850,8 @@ AsyncUpdateYScrollbar( GetYView(textPtr->interp, textPtr, 1); } - if (--textPtr->refCount == 0) { - ckfree((char *) textPtr); + if (textPtr->refCount-- <= 1) { + ckfree(textPtr); } } @@ -6587,7 +6879,7 @@ FindDLine( TkText *textPtr, /* Widget record for text widget. */ register DLine *dlPtr, /* Pointer to first in list of DLines to * search. */ - CONST TkTextIndex *indexPtr)/* Index of desired character. */ + const TkTextIndex *indexPtr)/* Index of desired character. */ { DLine *dlPtrPrev; TkTextIndex indexPtr2; @@ -6797,25 +7089,26 @@ TkTextPixelIndex( } *indexPtr = textPtr->topIndex; return; - } else { - for (dlPtr = validDlPtr = dInfoPtr->dLinePtr; - y >= (dlPtr->y + dlPtr->height); - dlPtr = dlPtr->nextPtr) { - if (dlPtr->chunkPtr != NULL) { - validDlPtr = dlPtr; - } - if (dlPtr->nextPtr == NULL) { - /* - * Y-coordinate is off the bottom of the displayed text. Use - * the last character on the last line. - */ + } + for (dlPtr = validDlPtr = dInfoPtr->dLinePtr; + y >= (dlPtr->y + dlPtr->height); + dlPtr = dlPtr->nextPtr) { + if (dlPtr->chunkPtr != NULL) { + validDlPtr = dlPtr; + } + if (dlPtr->nextPtr == NULL) { + /* + * Y-coordinate is off the bottom of the displayed text. Use the + * last character on the last line. + */ - x = dInfoPtr->maxX - 1; - nearby = 1; - break; - } + x = dInfoPtr->maxX - 1; + nearby = 1; + break; } - if (dlPtr->chunkPtr == NULL) dlPtr = validDlPtr; + } + if (dlPtr->chunkPtr == NULL) { + dlPtr = validDlPtr; } if (nearest != NULL) { @@ -6913,7 +7206,7 @@ DlineIndexOfX( */ if (chunkPtr->numBytes > 1) { - indexPtr->byteIndex += (*chunkPtr->measureProc)(chunkPtr, x); + indexPtr->byteIndex += chunkPtr->measureProc(chunkPtr, x); } } @@ -6988,7 +7281,7 @@ DlineXOfIndex( int x = 0; if (byteIndex == 0 || chunkPtr == NULL) { - return 0; + return x; } /* @@ -7001,15 +7294,14 @@ DlineXOfIndex( if (byteIndex < chunkPtr->numBytes) { int y, width, height; - (*chunkPtr->bboxProc)(textPtr, chunkPtr, byteIndex, + chunkPtr->bboxProc(textPtr, chunkPtr, byteIndex, dlPtr->y + dlPtr->spaceAbove, dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow, dlPtr->baseline - dlPtr->spaceAbove, &x, &y, &width, &height); break; - } else { - byteIndex -= chunkPtr->numBytes; } + byteIndex -= chunkPtr->numBytes; if (chunkPtr->nextPtr == NULL || byteIndex == 0) { x = chunkPtr->x + chunkPtr->width; break; @@ -7043,7 +7335,7 @@ DlineXOfIndex( int TkTextIndexBbox( TkText *textPtr, /* Widget record for text widget. */ - CONST TkTextIndex *indexPtr,/* Index whose bounding box is desired. */ + const TkTextIndex *indexPtr,/* Index whose bounding box is desired. */ int *xPtr, int *yPtr, /* Filled with index's upper-left * coordinate. */ int *widthPtr, int *heightPtr, @@ -7072,7 +7364,7 @@ TkTextIndexBbox( dlPtr = FindDLine(textPtr, dInfoPtr->dLinePtr, indexPtr); - /* + /* * Two cases shall be trapped here because the logic later really * needs dlPtr to be the display line containing indexPtr: * 1. if no display line contains the desired index (NULL dlPtr) @@ -7110,7 +7402,7 @@ TkTextIndexBbox( * coordinate on the screen. Translate it to reflect horizontal scrolling. */ - (*chunkPtr->bboxProc)(textPtr, chunkPtr, byteCount, + chunkPtr->bboxProc(textPtr, chunkPtr, byteCount, dlPtr->y + dlPtr->spaceAbove, dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow, dlPtr->baseline - dlPtr->spaceAbove, xPtr, yPtr, widthPtr, @@ -7189,7 +7481,7 @@ TkTextIndexBbox( int TkTextDLineInfo( TkText *textPtr, /* Widget record for text widget. */ - CONST TkTextIndex *indexPtr,/* Index of character whose bounding box is + const TkTextIndex *indexPtr,/* Index of character whose bounding box is * desired. */ int *xPtr, int *yPtr, /* Filled with line's upper-left * coordinate. */ @@ -7216,7 +7508,7 @@ TkTextDLineInfo( dlPtr = FindDLine(textPtr, dInfoPtr->dLinePtr, indexPtr); - /* + /* * Two cases shall be trapped here because the logic later really * needs dlPtr to be the display line containing indexPtr: * 1. if no display line contains the desired index (NULL dlPtr) @@ -7348,6 +7640,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; @@ -7356,22 +7651,22 @@ TkTextCharLayoutProc( #if TK_LAYOUT_WITH_BASE_CHUNKS if (baseCharChunkPtr == NULL) { baseCharChunkPtr = chunkPtr; - bciPtr = (BaseCharInfo *) ckalloc(sizeof(BaseCharInfo)); + bciPtr = ckalloc(sizeof(BaseCharInfo)); baseString = &bciPtr->baseChars; Tcl_DStringInit(baseString); bciPtr->width = 0; ciPtr = &bciPtr->ci; } else { - bciPtr = (BaseCharInfo *) baseCharChunkPtr->clientData; - ciPtr = (CharInfo *) ckalloc(sizeof(CharInfo)); + bciPtr = baseCharChunkPtr->clientData; + ciPtr = ckalloc(sizeof(CharInfo)); baseString = &bciPtr->baseChars; } lineOffset = Tcl_DStringLength(baseString); line = Tcl_DStringAppend(baseString,p,maxBytes); - chunkPtr->clientData = (ClientData) ciPtr; + chunkPtr->clientData = ciPtr; ciPtr->baseChunkPtr = baseCharChunkPtr; ciPtr->baseOffset = lineOffset; ciPtr->chars = NULL; @@ -7387,8 +7682,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, @@ -7410,6 +7705,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 @@ -7427,7 +7737,7 @@ TkTextCharLayoutProc( } else { Tcl_DStringSetLength(baseString,lineOffset); } - ckfree((char *) ciPtr); + ckfree(ciPtr); #endif /* TK_LAYOUT_WITH_BASE_CHUNKS */ return 0; } @@ -7453,9 +7763,8 @@ TkTextCharLayoutProc( chunkPtr->breakIndex = -1; #if !TK_LAYOUT_WITH_BASE_CHUNKS - ciPtr = (CharInfo *) - ckalloc((unsigned) bytesThatFit + Tk_Offset(CharInfo, chars) + 1); - chunkPtr->clientData = (ClientData) ciPtr; + ciPtr = ckalloc((Tk_Offset(CharInfo, chars) + 1) + bytesThatFit); + chunkPtr->clientData = ciPtr; memcpy(ciPtr->chars, p, (unsigned) bytesThatFit); #endif /* TK_LAYOUT_WITH_BASE_CHUNKS */ @@ -7493,11 +7802,21 @@ TkTextCharLayoutProc( } else { for (count = bytesThatFit, p += bytesThatFit - 1; count > 0; count--, p--) { - if (UCHAR(*p) < 0x80 && isspace(UCHAR(*p))) { + /* + * Don't use isspace(); effects are unpredictable and can lead to + * odd word-wrapping problems on some platforms. Also don't use + * Tcl_UniCharIsSpace here either, as it identifies non-breaking + * spaces as places to break. What we actually want is only the + * ASCII space characters, so use them explicitly... + */ + + switch (*p) { + case '\t': case '\n': case '\v': case '\f': case '\r': case ' ': chunkPtr->breakIndex = count; - break; + goto checkForNextChunk; } } + checkForNextChunk: if ((bytesThatFit + byteOffset) == segPtr->size) { for (nextPtr = segPtr->nextPtr; nextPtr != NULL; nextPtr = nextPtr->nextPtr) { @@ -7557,7 +7876,7 @@ CharChunkMeasureChars( * here. */ { Tk_Font tkfont = chunkPtr->stylePtr->sValuePtr->tkfont; - CharInfo *ciPtr = (CharInfo *) chunkPtr->clientData; + CharInfo *ciPtr = chunkPtr->clientData; #if !TK_LAYOUT_WITH_BASE_CHUNKS if (chars == NULL) { @@ -7570,7 +7889,7 @@ CharChunkMeasureChars( return MeasureChars(tkfont, chars, charsLen, start, end-start, startX, maxX, flags, nextXPtr); -#else +#else /* TK_LAYOUT_WITH_BASE_CHUNKS */ { int xDisplacement; int fit, bstart = start, bend = end; @@ -7598,7 +7917,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, @@ -7610,7 +7929,7 @@ CharChunkMeasureChars( return fit - bstart; } } -#endif +#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */ } /* @@ -7646,7 +7965,7 @@ CharDisplayProc( int screenY) /* Y-coordinate in text window that * corresponds to y. */ { - CharInfo *ciPtr = (CharInfo *) chunkPtr->clientData; + CharInfo *ciPtr = chunkPtr->clientData; const char *string; TextStyle *stylePtr; StyleValues *sValuePtr; @@ -7664,7 +7983,7 @@ CharDisplayProc( } #if TK_DRAW_IN_CONTEXT - bciPtr = (BaseCharInfo *) ciPtr->baseChunkPtr->clientData; + bciPtr = ciPtr->baseChunkPtr->clientData; numBytes = Tcl_DStringLength(&bciPtr->baseChars); string = Tcl_DStringValue(&bciPtr->baseChars); @@ -7727,7 +8046,7 @@ CharDisplayProc( y + baseline - sValuePtr->offset); if (sValuePtr->underline) { - TkUnderlineCharsInContext(display, dst, stylePtr->fgGC, + TkUnderlineCharsInContext(display, dst, stylePtr->ulGC, sValuePtr->tkfont, string, numBytes, ciPtr->baseChunkPtr->x + xDisplacement, y + baseline - sValuePtr->offset, @@ -7737,7 +8056,7 @@ CharDisplayProc( Tk_FontMetrics fm; Tk_GetFontMetrics(sValuePtr->tkfont, &fm); - TkUnderlineCharsInContext(display, dst, stylePtr->fgGC, + TkUnderlineCharsInContext(display, dst, stylePtr->ovGC, sValuePtr->tkfont, string, numBytes, ciPtr->baseChunkPtr->x + xDisplacement, y + baseline - sValuePtr->offset @@ -7754,7 +8073,7 @@ CharDisplayProc( Tk_DrawChars(display, dst, stylePtr->fgGC, sValuePtr->tkfont, string, numBytes, offsetX, y + baseline - sValuePtr->offset); if (sValuePtr->underline) { - Tk_UnderlineChars(display, dst, stylePtr->fgGC, sValuePtr->tkfont, + Tk_UnderlineChars(display, dst, stylePtr->ulGC, sValuePtr->tkfont, string, offsetX, y + baseline - sValuePtr->offset, 0, numBytes); @@ -7764,7 +8083,7 @@ CharDisplayProc( Tk_FontMetrics fm; Tk_GetFontMetrics(sValuePtr->tkfont, &fm); - Tk_UnderlineChars(display, dst, stylePtr->fgGC, sValuePtr->tkfont, + Tk_UnderlineChars(display, dst, stylePtr->ovGC, sValuePtr->tkfont, string, offsetX, y + baseline - sValuePtr->offset - fm.descent - (fm.ascent * 3) / 10, @@ -7797,7 +8116,7 @@ CharUndisplayProc( TkText *textPtr, /* Overall information about text widget. */ TkTextDispChunk *chunkPtr) /* Chunk that is about to be freed. */ { - CharInfo *ciPtr = (CharInfo *) chunkPtr->clientData; + CharInfo *ciPtr = chunkPtr->clientData; if (ciPtr) { #if TK_LAYOUT_WITH_BASE_CHUNKS @@ -7824,7 +8143,7 @@ CharUndisplayProc( ciPtr->numBytes = 0; #endif /* TK_LAYOUT_WITH_BASE_CHUNKS */ - ckfree((char *) ciPtr); + ckfree(ciPtr); chunkPtr->clientData = NULL; } } @@ -7900,7 +8219,7 @@ CharBboxProc( int *heightPtr) /* Gets filled in with height of character, in * pixels. */ { - CharInfo *ciPtr = (CharInfo *) chunkPtr->clientData; + CharInfo *ciPtr = chunkPtr->clientData; int maxX; maxX = chunkPtr->width + chunkPtr->x; @@ -8063,7 +8382,7 @@ AdjustForTab( if (chunkPtr2->displayProc != CharDisplayProc) { continue; } - ciPtr = (CharInfo *) chunkPtr2->clientData; + ciPtr = chunkPtr2->clientData; for (p = ciPtr->chars, i = 0; i < ciPtr->numBytes; p++, i++) { if (isdigit(UCHAR(*p))) { gotDigit = 1; @@ -8084,23 +8403,23 @@ AdjustForTab( if (decimalChunkPtr != NULL) { int curX; - ciPtr = (CharInfo *) decimalChunkPtr->clientData; + ciPtr = decimalChunkPtr->clientData; CharChunkMeasureChars(decimalChunkPtr, NULL, 0, 0, decimal, decimalChunkPtr->x, -1, 0, &curX); desired = tabX - (curX - x); goto update; - } else { - /* - * There wasn't a decimal point. Right justify the text. - */ + } - width = 0; - for (chunkPtr2 = chunkPtr->nextPtr; chunkPtr2 != NULL; - chunkPtr2 = chunkPtr2->nextPtr) { - width += chunkPtr2->width; - } - desired = tabX - width; + /* + * There wasn't a decimal point. Right justify the text. + */ + + width = 0; + for (chunkPtr2 = chunkPtr->nextPtr; chunkPtr2 != NULL; + chunkPtr2 = chunkPtr2->nextPtr) { + width += chunkPtr2->width; } + desired = tabX - width; /* * Shift all of the chunks to the right so that the left edge is at the @@ -8338,7 +8657,7 @@ NextTabStop( static int MeasureChars( Tk_Font tkfont, /* Font in which to draw characters. */ - CONST char *source, /* Characters to be displayed. Need not be + const char *source, /* Characters to be displayed. Need not be * NULL-terminated. */ int maxBytes, /* Maximum # of bytes to consider from * source. */ @@ -8353,7 +8672,7 @@ MeasureChars( * here. */ { int curX, width, ch; - CONST char *special, *end, *start; + const char *special, *end, *start; ch = 0; /* lint. */ curX = startX; @@ -8400,11 +8719,10 @@ MeasureChars( break; } if (special < end) { - if (ch == '\t') { - start++; - } else { + if (ch != '\t') { break; } + start++; } } @@ -8445,19 +8763,19 @@ TextGetScrollInfoObj( Tcl_Interp *interp, /* Used for error reporting. */ TkText *textPtr, /* Information about the text widget. */ int objc, /* # arguments for command. */ - Tcl_Obj *CONST objv[], /* Arguments for command. */ + Tcl_Obj *const objv[], /* Arguments for command. */ double *dblPtr, /* Filled in with argument "moveto" option, if * any. */ int *intPtr) /* Filled in with number of pages or lines or * pixels to scroll, if any. */ { - static CONST char *subcommands[] = { + static const char *const subcommands[] = { "moveto", "scroll", NULL }; enum viewSubcmds { VIEW_MOVETO, VIEW_SCROLL }; - static CONST char *units[] = { + static const char *const units[] = { "units", "pages", "pixels", NULL }; enum viewUnits { @@ -8465,8 +8783,8 @@ TextGetScrollInfoObj( }; int index; - if (Tcl_GetIndexFromObj(interp, objv[2], subcommands, "option", 0, - &index) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[2], subcommands, + sizeof(char *), "option", 0, &index) != TCL_OK) { return TKTEXT_SCROLL_ERROR; } @@ -8485,8 +8803,8 @@ TextGetScrollInfoObj( Tcl_WrongNumArgs(interp, 3, objv, "number units|pages|pixels"); return TKTEXT_SCROLL_ERROR; } - if (Tcl_GetIndexFromObj(interp, objv[4], units, "argument", 0, - &index) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[4], units, + sizeof(char *), "argument", 0, &index) != TCL_OK) { return TKTEXT_SCROLL_ERROR; } switch ((enum viewUnits) index) { @@ -8564,7 +8882,7 @@ FinalizeBaseChunk( if (chunkPtr->displayProc != CharDisplayProc) { continue; } - ciPtr = (CharInfo *)chunkPtr->clientData; + ciPtr = chunkPtr->clientData; if (ciPtr->baseChunkPtr != baseCharChunkPtr) { break; } @@ -8573,7 +8891,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; } @@ -8581,7 +8899,7 @@ FinalizeBaseChunk( } if (addChunkPtr != NULL) { - ciPtr = (CharInfo *)addChunkPtr->clientData; + ciPtr = addChunkPtr->clientData; ciPtr->chars = baseChars + ciPtr->baseOffset; #if TK_DRAW_IN_CONTEXT @@ -8632,7 +8950,7 @@ FreeBaseChunk( if (chunkPtr->undisplayProc != CharUndisplayProc) { continue; } - ciPtr = (CharInfo *) chunkPtr->clientData; + ciPtr = chunkPtr->clientData; if (ciPtr->baseChunkPtr != baseChunkPtr) { break; } @@ -8641,7 +8959,9 @@ FreeBaseChunk( ciPtr->chars = NULL; } - Tcl_DStringFree(&((BaseCharInfo *) baseChunkPtr->clientData)->baseChars); + if (baseChunkPtr) { + Tcl_DStringFree(&((BaseCharInfo *) baseChunkPtr->clientData)->baseChars); + } } /* @@ -8750,22 +9070,22 @@ RemoveFromBaseChunk( * Reinstitute this base chunk for re-layout. */ - ciPtr = (CharInfo *) chunkPtr->clientData; + ciPtr = chunkPtr->clientData; baseCharChunkPtr = ciPtr->baseChunkPtr; /* * Remove the chunk data from the base chunk data. */ - bciPtr = (BaseCharInfo *) baseCharChunkPtr->clientData; + 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/tkTextImage.c b/generic/tkTextImage.c index bc2b7c4..41dd448 100644 --- a/generic/tkTextImage.c +++ b/generic/tkTextImage.c @@ -54,7 +54,7 @@ static void EmbImageProc(ClientData clientData, int x, int y, * The following structure declares the "embedded image" segment type. */ -static const Tk_SegType tkTextEmbImageType = { +const Tk_SegType tkTextEmbImageType = { "image", /* name */ 0, /* leftGravity */ NULL, /* splitProc */ @@ -69,7 +69,7 @@ static const Tk_SegType tkTextEmbImageType = { * Definitions for alignment values: */ -static const char *alignStrings[] = { +static const char *const alignStrings[] = { "baseline", "bottom", "center", "top", NULL }; @@ -84,7 +84,7 @@ typedef enum { static const Tk_OptionSpec optionSpecs[] = { {TK_OPTION_STRING_TABLE, "-align", NULL, NULL, "center", -1, Tk_Offset(TkTextEmbImage, align), - 0, (ClientData) alignStrings, 0}, + 0, alignStrings, 0}, {TK_OPTION_PIXELS, "-padx", NULL, NULL, "0", -1, Tk_Offset(TkTextEmbImage, padX), 0, 0, 0}, {TK_OPTION_PIXELS, "-pady", NULL, NULL, @@ -95,9 +95,8 @@ static const Tk_OptionSpec optionSpecs[] = { {TK_OPTION_STRING, "-name", NULL, NULL, NULL, -1, Tk_Offset(TkTextEmbImage, imageName), TK_OPTION_NULL_OK, 0, 0}, - {TK_OPTION_END} + {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0} }; - /* *-------------------------------------------------------------- @@ -128,7 +127,7 @@ TkTextImageCmd( int idx; register TkTextSegment *eiPtr; TkTextIndex index; - static const char *optionStrings[] = { + static const char *const optionStrings[] = { "cget", "configure", "create", "names", NULL }; enum opts { @@ -136,11 +135,11 @@ TkTextImageCmd( }; if (objc < 3) { - Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?"); + Tcl_WrongNumArgs(interp, 2, objv, "option ?arg ...?"); return TCL_ERROR; } - if (Tcl_GetIndexFromObj(interp, objv[2], optionStrings, "option", 0, - &idx) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[2], optionStrings, + sizeof(char *), "option", 0, &idx) != TCL_OK) { return TCL_ERROR; } switch ((enum opts) idx) { @@ -156,8 +155,10 @@ TkTextImageCmd( } eiPtr = TkTextIndexToSeg(&index, NULL); if (eiPtr->typePtr != &tkTextEmbImageType) { - Tcl_AppendResult(interp, "no embedded image at index \"", - Tcl_GetString(objv[3]), "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "no embedded image at index \"%s\"", + Tcl_GetString(objv[3]))); + Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_IMAGE", NULL); return TCL_ERROR; } objPtr = Tk_GetOptionValue(interp, (char *) &eiPtr->body.ei, @@ -171,7 +172,7 @@ TkTextImageCmd( } case CMD_CONF: if (objc < 4) { - Tcl_WrongNumArgs(interp, 3, objv, "index ?option value ...?"); + Tcl_WrongNumArgs(interp, 3, objv, "index ?-option value ...?"); return TCL_ERROR; } if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) { @@ -179,14 +180,17 @@ TkTextImageCmd( } eiPtr = TkTextIndexToSeg(&index, NULL); if (eiPtr->typePtr != &tkTextEmbImageType) { - Tcl_AppendResult(interp, "no embedded image at index \"", - Tcl_GetString(objv[3]), "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "no embedded image at index \"%s\"", + Tcl_GetString(objv[3]))); + Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_IMAGE", NULL); return TCL_ERROR; } if (objc <= 5) { Tcl_Obj *objPtr = Tk_GetOptionInfo(interp, (char *) &eiPtr->body.ei, eiPtr->body.ei.optionTable, (objc == 5) ? objv[4] : NULL, textPtr->tkwin); + if (objPtr == NULL) { return TCL_ERROR; } else { @@ -215,7 +219,7 @@ TkTextImageCmd( */ if (objc < 4) { - Tcl_WrongNumArgs(interp, 3, objv, "index ?option value ...?"); + Tcl_WrongNumArgs(interp, 3, objv, "index ?-option value ...?"); return TCL_ERROR; } if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) { @@ -238,7 +242,7 @@ TkTextImageCmd( * Create the new image segment and initialize it. */ - eiPtr = (TkTextSegment *) ckalloc(EI_SEG_SIZE); + eiPtr = ckalloc(EI_SEG_SIZE); eiPtr->typePtr = &tkTextEmbImageType; eiPtr->size = 1; eiPtr->body.ei.sharedTextPtr = textPtr->sharedTextPtr; @@ -273,16 +277,20 @@ TkTextImageCmd( case CMD_NAMES: { Tcl_HashSearch search; Tcl_HashEntry *hPtr; + Tcl_Obj *resultObj; if (objc != 3) { Tcl_WrongNumArgs(interp, 3, objv, NULL); return TCL_ERROR; } + resultObj = Tcl_NewObj(); for (hPtr = Tcl_FirstHashEntry(&textPtr->sharedTextPtr->imageTable, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - Tcl_AppendElement(interp, - Tcl_GetHashKey(&textPtr->sharedTextPtr->markTable, hPtr)); + Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj( + Tcl_GetHashKey(&textPtr->sharedTextPtr->markTable, hPtr), + -1)); } + Tcl_SetObjResult(interp, resultObj); return TCL_OK; } default: @@ -324,11 +332,12 @@ EmbImageConfigure( Tcl_HashEntry *hPtr; Tcl_HashSearch search; char *name; + int dummy; int count = 0; /* The counter for picking a unique name */ int conflict = 0; /* True if we have a name conflict */ - size_t len; /* length of image name */ + size_t len; /* length of image name */ - if (Tk_SetOptions(textPtr->interp, (char*)&eiPtr->body.ei, + if (Tk_SetOptions(textPtr->interp, (char *) &eiPtr->body.ei, eiPtr->body.ei.optionTable, objc, objv, textPtr->tkwin, NULL, NULL) != TCL_OK) { return TCL_ERROR; @@ -343,7 +352,7 @@ EmbImageConfigure( if (eiPtr->body.ei.imageString != NULL) { image = Tk_GetImage(textPtr->interp, textPtr->tkwin, - eiPtr->body.ei.imageString, EmbImageProc, (ClientData) eiPtr); + eiPtr->body.ei.imageString, EmbImageProc, eiPtr); if (image == NULL) { return TCL_ERROR; } @@ -370,9 +379,11 @@ EmbImageConfigure( name = eiPtr->body.ei.imageString; } if (name == NULL) { - Tcl_AppendResult(textPtr->interp, "Either a \"-name\" ", - "or a \"-image\" argument must be provided ", - "to the \"image create\" subcommand.", NULL); + Tcl_SetObjResult(textPtr->interp, Tcl_NewStringObj( + "Either a \"-name\" or a \"-image\" argument must be" + " provided to the \"image create\" subcommand", -1)); + Tcl_SetErrorCode(textPtr->interp, "TK", "TEXT", "IMAGE_CREATE_USAGE", + NULL); return TCL_ERROR; } len = strlen(name); @@ -404,15 +415,11 @@ EmbImageConfigure( Tcl_DStringAppend(&newName, buf, -1); } name = Tcl_DStringValue(&newName); - { - int dummy; - - hPtr = Tcl_CreateHashEntry(&textPtr->sharedTextPtr->imageTable, name, - &dummy); - } + hPtr = Tcl_CreateHashEntry(&textPtr->sharedTextPtr->imageTable, name, + &dummy); Tcl_SetHashValue(hPtr, eiPtr); - Tcl_AppendResult(textPtr->interp, name, NULL); - eiPtr->body.ei.name = ckalloc((unsigned) Tcl_DStringLength(&newName)+1); + Tcl_SetObjResult(textPtr->interp, Tcl_NewStringObj(name, -1)); + eiPtr->body.ei.name = ckalloc(Tcl_DStringLength(&newName) + 1); strcpy(eiPtr->body.ei.name, name); Tcl_DStringFree(&newName); @@ -473,7 +480,7 @@ EmbImageDeleteProc( if (eiPtr->body.ei.name) { ckfree(eiPtr->body.ei.name); } - ckfree((char *) eiPtr); + ckfree(eiPtr); return 0; } @@ -586,7 +593,7 @@ EmbImageLayoutProc( chunkPtr->width = width; chunkPtr->breakIndex = -1; chunkPtr->breakIndex = 1; - chunkPtr->clientData = (ClientData) eiPtr; + chunkPtr->clientData = eiPtr; eiPtr->body.ei.chunkCount += 1; return 1; } @@ -658,7 +665,7 @@ EmbImageDisplayProc( int screenY) /* Y-coordinate in text window that * corresponds to y. */ { - TkTextSegment *eiPtr = (TkTextSegment *) chunkPtr->clientData; + TkTextSegment *eiPtr = chunkPtr->clientData; int lineX, imageX, imageY, width, height; Tk_Image image; @@ -722,7 +729,7 @@ EmbImageBboxProc( int *heightPtr) /* Gets filled in with height of image, in * pixels. */ { - TkTextSegment *eiPtr = (TkTextSegment *) chunkPtr->clientData; + TkTextSegment *eiPtr = chunkPtr->clientData; Tk_Image image; image = eiPtr->body.ei.image; @@ -787,7 +794,7 @@ TkTextImageIndex( if (hPtr == NULL) { return 0; } - eiPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr); + eiPtr = Tcl_GetHashValue(hPtr); indexPtr->tree = textPtr->sharedTextPtr->tree; indexPtr->linePtr = eiPtr->body.ei.linePtr; indexPtr->byteIndex = TkTextSegToOffset(eiPtr, indexPtr->linePtr); @@ -821,7 +828,7 @@ EmbImageProc( int imgWidth, int imgHeight)/* New dimensions of image. */ { - TkTextSegment *eiPtr = (TkTextSegment *) clientData; + TkTextSegment *eiPtr = clientData; TkTextIndex index; index.tree = eiPtr->body.ei.sharedTextPtr->tree; diff --git a/generic/tkTextIndex.c b/generic/tkTextIndex.c index b886975..582e1a8 100644 --- a/generic/tkTextIndex.c +++ b/generic/tkTextIndex.c @@ -33,12 +33,12 @@ * Forward declarations for functions defined later in this file: */ -static CONST char * ForwBack(TkText *textPtr, CONST char *string, +static const char * ForwBack(TkText *textPtr, const char *string, TkTextIndex *indexPtr); -static CONST char * StartEnd(TkText *textPtr, CONST char *string, +static const char * StartEnd(TkText *textPtr, const char *string, TkTextIndex *indexPtr); static int GetIndex(Tcl_Interp *interp, TkSharedText *sharedPtr, - TkText *textPtr, CONST char *string, + TkText *textPtr, const char *string, TkTextIndex *indexPtr, int *canCachePtr); static int IndexCountBytesOrdered(CONST TkText *textPtr, CONST TkTextIndex *indexPtr1, @@ -51,8 +51,6 @@ static int IndexCountBytesOrdered(CONST TkText *textPtr, static void DupTextIndexInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr); static void FreeTextIndexInternalRep(Tcl_Obj *listPtr); -static int SetTextIndexFromAny(Tcl_Interp *interp, - Tcl_Obj *objPtr); static void UpdateStringOfTextIndex(Tcl_Obj *objPtr); /* @@ -64,39 +62,41 @@ static void UpdateStringOfTextIndex(Tcl_Obj *objPtr); #define GET_INDEXEPOCH(objPtr) \ (PTR2INT((objPtr)->internalRep.twoPtrValue.ptr2)) #define SET_TEXTINDEX(objPtr, indexPtr) \ - ((objPtr)->internalRep.twoPtrValue.ptr1 = (VOID *) (indexPtr)) + ((objPtr)->internalRep.twoPtrValue.ptr1 = (void *) (indexPtr)) #define SET_INDEXEPOCH(objPtr, epoch) \ ((objPtr)->internalRep.twoPtrValue.ptr2 = INT2PTR(epoch)) - + /* * Define the 'textindex' object type, which Tk uses to represent indices in * text widgets internally. */ -Tcl_ObjType tkTextIndexType = { +const Tcl_ObjType tkTextIndexType = { "textindex", /* name */ FreeTextIndexInternalRep, /* freeIntRepProc */ DupTextIndexInternalRep, /* dupIntRepProc */ NULL, /* updateStringProc */ - SetTextIndexFromAny /* setFromAnyProc */ + NULL /* setFromAnyProc */ }; - + static void FreeTextIndexInternalRep( Tcl_Obj *indexObjPtr) /* TextIndex object with internal rep to * free. */ { 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. */ - ckfree((char *) (indexPtr->textPtr)); + ckfree(indexPtr->textPtr); } } - ckfree((char *) indexPtr); + ckfree(indexPtr); + indexObjPtr->typePtr = NULL; } static void @@ -107,7 +107,7 @@ DupTextIndexInternalRep( int epoch; TkTextIndex *dupIndexPtr, *indexPtr; - dupIndexPtr = (TkTextIndex *) ckalloc(sizeof(TkTextIndex)); + dupIndexPtr = ckalloc(sizeof(TkTextIndex)); indexPtr = GET_TEXTINDEX(srcPtr); epoch = GET_INDEXEPOCH(srcPtr); @@ -122,7 +122,7 @@ DupTextIndexInternalRep( SET_INDEXEPOCH(copyPtr, epoch); copyPtr->typePtr = &tkTextIndexType; } - + /* * This will not be called except by TkTextNewIndexObj below. This is because * if a TkTextIndex is no longer valid, it is not possible to regenerate the @@ -134,27 +134,15 @@ UpdateStringOfTextIndex( Tcl_Obj *objPtr) { char buffer[TK_POS_CHARS]; - register int len; - - CONST TkTextIndex *indexPtr = GET_TEXTINDEX(objPtr); + size_t len; + const TkTextIndex *indexPtr = GET_TEXTINDEX(objPtr); len = TkTextPrintIndex(indexPtr->textPtr, indexPtr, buffer); - objPtr->bytes = ckalloc((unsigned) len + 1); + objPtr->bytes = ckalloc(len + 1); strcpy(objPtr->bytes, buffer); objPtr->length = len; } - -static int -SetTextIndexFromAny( - Tcl_Interp *interp, /* Used for error reporting if not NULL. */ - Tcl_Obj *objPtr) /* The object to convert. */ -{ - Tcl_AppendToObj(Tcl_GetObjResult(interp), - "can't convert value to textindex except via TkTextGetIndexFromObj API", - -1); - return TCL_ERROR; -} /* *--------------------------------------------------------------------------- @@ -186,9 +174,9 @@ MakeObjIndex( TkText *textPtr, /* Information about text widget. */ Tcl_Obj *objPtr, /* Object containing description of * position. */ - CONST TkTextIndex *origPtr) /* Pointer to index. */ + const TkTextIndex *origPtr) /* Pointer to index. */ { - TkTextIndex *indexPtr = (TkTextIndex *) ckalloc(sizeof(TkTextIndex)); + TkTextIndex *indexPtr = ckalloc(sizeof(TkTextIndex)); indexPtr->tree = origPtr->tree; indexPtr->linePtr = origPtr->linePtr; @@ -205,8 +193,8 @@ MakeObjIndex( } return indexPtr; } - -CONST TkTextIndex * + +const TkTextIndex * TkTextGetIndexFromObj( Tcl_Interp *interp, /* Use this for error reporting. */ TkText *textPtr, /* Information about text widget. */ @@ -245,8 +233,8 @@ TkTextGetIndexFromObj( if (objPtr->bytes == NULL) { objPtr->typePtr->updateStringProc(objPtr); } - if ((objPtr->typePtr->freeIntRepProc) != NULL) { - (*objPtr->typePtr->freeIntRepProc)(objPtr); + if (objPtr->typePtr->freeIntRepProc != NULL) { + objPtr->typePtr->freeIntRepProc(objPtr); } } @@ -274,7 +262,7 @@ TkTextGetIndexFromObj( Tcl_Obj * TkTextNewIndexObj( TkText *textPtr, /* Text widget for this index */ - CONST TkTextIndex *indexPtr)/* Pointer to index. */ + const TkTextIndex *indexPtr)/* Pointer to index. */ { Tcl_Obj *retVal; @@ -388,9 +376,9 @@ TkTextMakePixelIndex( TkTextIndex * TkTextMakeByteIndex( - TkTextBTree tree, /* Tree that lineIndex and byteIndex refer + TkTextBTree tree, /* Tree that lineIndex and byteIndex refer * to. */ - CONST TkText *textPtr, + const TkText *textPtr, int lineIndex, /* Index of desired line (0 means first line * of text). */ int byteIndex, /* Byte index of desired character. */ @@ -398,8 +386,8 @@ TkTextMakeByteIndex( { TkTextSegment *segPtr; int index; - CONST char *p, *start; - Tcl_UniChar ch; + const char *p, *start; + int ch; indexPtr->tree = tree; if (lineIndex < 0) { @@ -442,14 +430,14 @@ TkTextMakeByteIndex( if ((byteIndex > index) && (segPtr->typePtr == &tkTextCharType)) { /* * Prevent UTF-8 character from being split up by ensuring - * that byteIndex falls on a character boundary. If index + * that byteIndex falls on a character boundary. If the index * falls in the middle of a UTF-8 character, it will be * adjusted to the end of that UTF-8 character. */ start = segPtr->body.chars + (byteIndex - index); p = Tcl_UtfPrev(start, segPtr->body.chars); - p += Tcl_UtfToUniChar(p, &ch); + p += TkUtfToUniChar(p, &ch); indexPtr->byteIndex += p - start; } break; @@ -492,7 +480,7 @@ TkTextMakeCharIndex( register TkTextSegment *segPtr; char *p, *start, *end; int index, offset; - Tcl_UniChar ch; + int ch; indexPtr->tree = tree; if (lineIndex < 0) { @@ -539,7 +527,7 @@ TkTextMakeCharIndex( return indexPtr; } charIndex--; - offset = Tcl_UtfToUniChar(p, &ch); + offset = TkUtfToUniChar(p, &ch); index += offset; } } else { @@ -576,7 +564,7 @@ TkTextMakeCharIndex( TkTextSegment * TkTextIndexToSeg( - CONST TkTextIndex *indexPtr,/* Text index. */ + const TkTextIndex *indexPtr,/* Text index. */ int *offsetPtr) /* Where to store offset within segment, or * NULL if offset isn't wanted. */ { @@ -614,10 +602,10 @@ TkTextIndexToSeg( int TkTextSegToOffset( - CONST TkTextSegment *segPtr,/* Segment whose offset is desired. */ - CONST TkTextLine *linePtr) /* Line containing segPtr. */ + const TkTextSegment *segPtr,/* Segment whose offset is desired. */ + const TkTextLine *linePtr) /* Line containing segPtr. */ { - CONST TkTextSegment *segPtr2; + const TkTextSegment *segPtr2; int offset = 0; for (segPtr2 = linePtr->segPtr; segPtr2 != segPtr; @@ -708,7 +696,7 @@ int TkTextGetIndex( Tcl_Interp *interp, /* Use this for error reporting. */ TkText *textPtr, /* Information about text widget. */ - CONST char *string, /* Textual description of position. */ + const char *string, /* Textual description of position. */ TkTextIndex *indexPtr) /* Index structure to fill in. */ { return GetIndex(interp, NULL, textPtr, string, indexPtr, NULL); @@ -742,7 +730,7 @@ GetIndex( Tcl_Interp *interp, /* Use this for error reporting. */ TkSharedText *sharedPtr, TkText *textPtr, /* Information about text widget. */ - CONST char *string, /* Textual description of position. */ + const char *string, /* Textual description of position. */ TkTextIndex *indexPtr, /* Index structure to fill in. */ int *canCachePtr) /* Pointer to integer to store whether we can * cache the index (or NULL). */ @@ -751,7 +739,7 @@ GetIndex( TkTextIndex first, last; int wantLast, result; char c; - CONST char *cp; + const char *cp; Tcl_DString copy; int canCache = 0; @@ -803,7 +791,7 @@ GetIndex( TkTextSearch search; TkTextTag *tagPtr; Tcl_HashEntry *hPtr = NULL; - CONST char *tagName; + const char *tagName; if ((p[1] == 'f') && (strncmp(p+1, "first", 5) == 0)) { wantLast = 0; @@ -828,7 +816,7 @@ GetIndex( hPtr = Tcl_FindHashEntry(&sharedPtr->tagTable, tagName); *p = '.'; if (hPtr != NULL) { - tagPtr = (TkTextTag *) Tcl_GetHashValue(hPtr); + tagPtr = Tcl_GetHashValue(hPtr); } } @@ -843,13 +831,14 @@ GetIndex( if (!TkBTreeCharTagged(&first, tagPtr) && !TkBTreeNextTag(&search)) { if (tagPtr == textPtr->selTagPtr) { tagName = "sel"; - } else { + } else if (hPtr != NULL) { tagName = Tcl_GetHashKey(&sharedPtr->tagTable, hPtr); } - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, - "text doesn't contain any characters tagged with \"", - tagName, "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "text doesn't contain any characters tagged with \"%s\"", + tagName)); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "TEXT_INDEX", tagName, + NULL); Tcl_DStringFree(©); return TCL_ERROR; } @@ -1012,8 +1001,8 @@ GetIndex( error: Tcl_DStringFree(©); - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "bad text index \"", string, "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad text index \"%s\"", string)); + Tcl_SetErrorCode(interp, "TK", "TEXT", "BAD_INDEX", NULL); return TCL_ERROR; } @@ -1037,8 +1026,8 @@ GetIndex( int TkTextPrintIndex( - CONST TkText *textPtr, - CONST TkTextIndex *indexPtr,/* Pointer to index. */ + const TkText *textPtr, + const TkTextIndex *indexPtr,/* Pointer to index. */ char *string) /* Place to store the position. Must have at * least TK_POS_CHARS characters. */ { @@ -1101,8 +1090,8 @@ TkTextPrintIndex( int TkTextIndexCmp( - CONST TkTextIndex*index1Ptr,/* First index. */ - CONST TkTextIndex*index2Ptr)/* Second index. */ + const TkTextIndex*index1Ptr,/* First index. */ + const TkTextIndex*index2Ptr)/* Second index. */ { int line1, line2; @@ -1154,15 +1143,15 @@ TkTextIndexCmp( *--------------------------------------------------------------------------- */ -static CONST char * +static const char * ForwBack( TkText *textPtr, /* Information about text widget. */ - CONST char *string, /* String to parse for additional info about + const char *string, /* String to parse for additional info about * modifier (count and units). Points to "+" * or "-" that starts modifier. */ TkTextIndex *indexPtr) /* Index to update as specified in string. */ { - register CONST char *p, *units; + register const char *p, *units; char *end; int count, lineIndex, modifier; size_t length; @@ -1402,8 +1391,8 @@ ForwBack( int TkTextIndexForwBytes( - CONST TkText *textPtr, - CONST TkTextIndex *srcPtr, /* Source index. */ + const TkText *textPtr, + const TkTextIndex *srcPtr, /* Source index. */ int byteCount, /* How many bytes forward to move. May be * negative. */ TkTextIndex *dstPtr) /* Destination index: gets modified. */ @@ -1474,8 +1463,8 @@ TkTextIndexForwBytes( void TkTextIndexForwChars( - CONST TkText *textPtr, /* Overall information about text widget. */ - CONST TkTextIndex *srcPtr, /* Source index. */ + const TkText *textPtr, /* Overall information about text widget. */ + const TkTextIndex *srcPtr, /* Source index. */ int charCount, /* How many characters forward to move. May * be negative. */ TkTextIndex *dstPtr, /* Destination index: gets modified. */ @@ -1486,7 +1475,7 @@ TkTextIndexForwChars( TkTextElideInfo *infoPtr = NULL; int byteOffset; char *start, *end, *p; - Tcl_UniChar ch; + int ch; int elide = 0; int checkElided = (type & COUNT_DISPLAY); @@ -1495,8 +1484,7 @@ TkTextIndexForwChars( return; } if (checkElided) { - infoPtr = (TkTextElideInfo *) - ckalloc((unsigned) sizeof(TkTextElideInfo)); + infoPtr = ckalloc(sizeof(TkTextElideInfo)); elide = TkTextIsElided(textPtr, srcPtr, infoPtr); } @@ -1586,7 +1574,7 @@ TkTextIndexForwChars( if (segPtr->typePtr == &tkTextCharType) { start = segPtr->body.chars + byteOffset; end = segPtr->body.chars + segPtr->size; - for (p = start; p < end; p += Tcl_UtfToUniChar(p, &ch)) { + for (p = start; p < end; p += TkUtfToUniChar(p, &ch)) { if (charCount == 0) { dstPtr->byteIndex += (p - start); goto forwardCharDone; @@ -1624,7 +1612,7 @@ TkTextIndexForwChars( forwardCharDone: if (infoPtr != NULL) { TkTextFreeElideInfo(infoPtr); - ckfree((char *) infoPtr); + ckfree(infoPtr); } } @@ -1738,11 +1726,11 @@ IndexCountBytesOrdered( int TkTextIndexCount( - CONST TkText *textPtr, /* Overall information about text widget. */ - CONST TkTextIndex *indexPtr1, + const TkText *textPtr, /* Overall information about text widget. */ + const TkTextIndex *indexPtr1, /* Index describing location of character from * which to count. */ - CONST TkTextIndex *indexPtr2, + const TkTextIndex *indexPtr2, /* Index describing location of last character * at which to stop the count. */ TkTextCountType type) /* The kind of indices to count. */ @@ -1764,8 +1752,7 @@ TkTextIndexCount( seg2Ptr = TkTextIndexToSeg(indexPtr2, &maxBytes); if (checkElided) { - infoPtr = (TkTextElideInfo *) - ckalloc((unsigned) sizeof(TkTextElideInfo)); + infoPtr = ckalloc(sizeof(TkTextElideInfo)); elide = TkTextIsElided(textPtr, indexPtr1, infoPtr); } @@ -1905,11 +1892,11 @@ TkTextIndexCount( countDone: if (infoPtr != NULL) { TkTextFreeElideInfo(infoPtr); - ckfree((char *) infoPtr); + ckfree(infoPtr); } return count; } - + /* *--------------------------------------------------------------------------- * @@ -1934,8 +1921,8 @@ TkTextIndexCount( int TkTextIndexBackBytes( - CONST TkText *textPtr, - CONST TkTextIndex *srcPtr, /* Source index. */ + const TkText *textPtr, + const TkTextIndex *srcPtr, /* Source index. */ int byteCount, /* How many bytes backward to move. May be * negative. */ TkTextIndex *dstPtr) /* Destination index: gets modified. */ @@ -2004,8 +1991,8 @@ TkTextIndexBackBytes( void TkTextIndexBackChars( - CONST TkText *textPtr, /* Overall information about text widget. */ - CONST TkTextIndex *srcPtr, /* Source index. */ + const TkText *textPtr, /* Overall information about text widget. */ + const TkTextIndex *srcPtr, /* Source index. */ int charCount, /* How many characters backward to move. May * be negative. */ TkTextIndex *dstPtr, /* Destination index: gets modified. */ @@ -2014,7 +2001,7 @@ TkTextIndexBackChars( TkTextSegment *segPtr, *oldPtr; TkTextElideInfo *infoPtr = NULL; int lineIndex, segSize; - CONST char *p, *start, *end; + const char *p, *start, *end; int elide = 0; int checkElided = (type & COUNT_DISPLAY); @@ -2023,7 +2010,7 @@ TkTextIndexBackChars( return; } if (checkElided) { - infoPtr = (TkTextElideInfo *) ckalloc(sizeof(TkTextElideInfo)); + infoPtr = ckalloc(sizeof(TkTextElideInfo)); elide = TkTextIsElided(textPtr, srcPtr, infoPtr); } @@ -2189,7 +2176,7 @@ TkTextIndexBackChars( backwardCharDone: if (infoPtr != NULL) { TkTextFreeElideInfo(infoPtr); - ckfree((char *) infoPtr); + ckfree(infoPtr); } } @@ -2213,15 +2200,15 @@ TkTextIndexBackChars( *---------------------------------------------------------------------- */ -static CONST char * +static const char * StartEnd( TkText *textPtr, /* Information about text widget. */ - CONST char *string, /* String to parse for additional info about + const char *string, /* String to parse for additional info about * modifier (count and units). Points to first * character of modifier word. */ TkTextIndex *indexPtr) /* Index to modify based on string. */ { - CONST char *p; + const char *p; size_t length; register TkTextSegment *segPtr; int modifier; @@ -2311,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; } @@ -2356,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/tkTextMark.c b/generic/tkTextMark.c index 71a7949..6a41c77 100644 --- a/generic/tkTextMark.c +++ b/generic/tkTextMark.c @@ -13,6 +13,7 @@ #include "tkInt.h" #include "tkText.h" +#include "tk3d.h" /* * Macro that determines the size of a mark segment: @@ -25,6 +26,7 @@ * Forward references for functions defined in this file: */ +static Tcl_Obj * GetMarkName(TkText *textPtr, TkTextSegment *segPtr); static void InsertUndisplayProc(TkText *textPtr, TkTextDispChunk *chunkPtr); static int MarkDeleteProc(TkTextSegment *segPtr, @@ -38,9 +40,9 @@ static int MarkLayoutProc(TkText *textPtr, TkTextIndex *indexPtr, int maxChars, int noCharsYet, TkWrapMode wrapMode, TkTextDispChunk *chunkPtr); static int MarkFindNext(Tcl_Interp *interp, - TkText *textPtr, const char *markName); + TkText *textPtr, Tcl_Obj *markName); static int MarkFindPrev(Tcl_Interp *interp, - TkText *textPtr, const char *markName); + TkText *textPtr, Tcl_Obj *markName); /* @@ -104,7 +106,7 @@ TkTextMarkCmd( TkTextIndex index; const Tk_SegType *newTypePtr; int optionIndex; - static const char *markOptionStrings[] = { + static const char *const markOptionStrings[] = { "gravity", "names", "next", "previous", "set", "unset", NULL }; enum markOptions { @@ -113,11 +115,11 @@ TkTextMarkCmd( }; if (objc < 3) { - Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?"); + Tcl_WrongNumArgs(interp, 2, objv, "option ?arg ...?"); return TCL_ERROR; } - if (Tcl_GetIndexFromObj(interp, objv[2], markOptionStrings, "mark option", - 0, &optionIndex) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[2], markOptionStrings, + sizeof(char *), "mark option", 0, &optionIndex) != TCL_OK) { return TCL_ERROR; } @@ -125,13 +127,13 @@ TkTextMarkCmd( case MARK_GRAVITY: { char c; int length; - char *str; + const char *str; if (objc < 4 || objc > 5) { Tcl_WrongNumArgs(interp, 3, objv, "markName ?gravity?"); return TCL_ERROR; } - str = Tcl_GetStringFromObj(objv[3],&length); + str = Tcl_GetStringFromObj(objv[3], &length); if (length == 6 && !strcmp(str, "insert")) { markPtr = textPtr->insertMarkPtr; } else if (length == 7 && !strcmp(str, "current")) { @@ -139,30 +141,36 @@ TkTextMarkCmd( } else { hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->markTable, str); if (hPtr == NULL) { - Tcl_AppendResult(interp, "there is no mark named \"", - Tcl_GetString(objv[3]), "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "there is no mark named \"%s\"", str)); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "TEXT_MARK", str, + NULL); return TCL_ERROR; } - markPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr); + markPtr = Tcl_GetHashValue(hPtr); } if (objc == 4) { + const char *typeStr; + if (markPtr->typePtr == &tkTextRightMarkType) { - Tcl_SetResult(interp, "right", TCL_STATIC); + typeStr = "right"; } else { - Tcl_SetResult(interp, "left", TCL_STATIC); + typeStr = "left"; } + Tcl_SetObjResult(interp, Tcl_NewStringObj(typeStr, -1)); return TCL_OK; } str = Tcl_GetStringFromObj(objv[4],&length); c = str[0]; - if ((c == 'l') && (strncmp(str, "left", (unsigned)length) == 0)) { + if ((c == 'l') && (strncmp(str, "left", (unsigned) length) == 0)) { newTypePtr = &tkTextLeftMarkType; } else if ((c == 'r') && - (strncmp(str, "right", (unsigned)length) == 0)) { + (strncmp(str, "right", (unsigned) length) == 0)) { newTypePtr = &tkTextRightMarkType; } else { - Tcl_AppendResult(interp, "bad mark gravity \"", str, - "\": must be left or right", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad mark gravity \"%s\": must be left or right", str)); + Tcl_SetErrorCode(interp, "TK", "VALUE", "MARK_GRAVITY", NULL); return TCL_ERROR; } TkTextMarkSegToIndex(textPtr, markPtr, &index); @@ -171,31 +179,39 @@ TkTextMarkCmd( TkBTreeLinkSegment(markPtr, &index); break; } - case MARK_NAMES: + case MARK_NAMES: { + Tcl_Obj *resultObj; + if (objc != 3) { Tcl_WrongNumArgs(interp, 3, objv, NULL); return TCL_ERROR; } - Tcl_AppendElement(interp, "insert"); - Tcl_AppendElement(interp, "current"); + resultObj = Tcl_NewObj(); + Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj( + "insert", -1)); + Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj( + "current", -1)); for (hPtr = Tcl_FirstHashEntry(&textPtr->sharedTextPtr->markTable, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - Tcl_AppendElement(interp, - Tcl_GetHashKey(&textPtr->sharedTextPtr->markTable, hPtr)); + Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj( + Tcl_GetHashKey(&textPtr->sharedTextPtr->markTable, hPtr), + -1)); } + Tcl_SetObjResult(interp, resultObj); break; + } case MARK_NEXT: if (objc != 4) { Tcl_WrongNumArgs(interp, 3, objv, "index"); return TCL_ERROR; } - return MarkFindNext(interp, textPtr, Tcl_GetString(objv[3])); + return MarkFindNext(interp, textPtr, objv[3]); case MARK_PREVIOUS: if (objc != 4) { Tcl_WrongNumArgs(interp, 3, objv, "index"); return TCL_ERROR; } - return MarkFindPrev(interp, textPtr, Tcl_GetString(objv[3])); + return MarkFindPrev(interp, textPtr, objv[3]); case MARK_SET: if (objc != 5) { Tcl_WrongNumArgs(interp, 3, objv, "markName index"); @@ -213,7 +229,7 @@ TkTextMarkCmd( hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->markTable, Tcl_GetString(objv[i])); if (hPtr != NULL) { - markPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr); + markPtr = Tcl_GetHashValue(hPtr); /* * Special case not needed with peer widgets. @@ -225,7 +241,7 @@ TkTextMarkCmd( } TkBTreeUnlinkSegment(markPtr, markPtr->body.mark.linePtr); Tcl_DeleteHashEntry(hPtr); - ckfree((char *) markPtr); + ckfree(markPtr); } } break; @@ -274,7 +290,7 @@ TkTextSetMark( widgetSpecific = 0; hPtr = Tcl_CreateHashEntry(&textPtr->sharedTextPtr->markTable, name, &isNew); - markPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr); + markPtr = Tcl_GetHashValue(hPtr); } if (!isNew) { /* @@ -288,7 +304,7 @@ TkTextSetMark( int nblines; TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index); - TkTextIndexForwChars(NULL,&index, 1, &index2, COUNT_INDICES); + TkTextIndexForwChars(NULL, &index, 1, &index2, COUNT_INDICES); /* * While we wish to redisplay, no heights have changed, so no need @@ -314,7 +330,7 @@ TkTextSetMark( } TkBTreeUnlinkSegment(markPtr, markPtr->body.mark.linePtr); } else { - markPtr = (TkTextSegment *) ckalloc(MSEG_SIZE); + markPtr = ckalloc(MSEG_SIZE); markPtr->typePtr = &tkTextRightMarkType; markPtr->size = 0; markPtr->body.mark.textPtr = textPtr; @@ -338,7 +354,7 @@ TkTextSetMark( if (markPtr == textPtr->insertMarkPtr) { TkTextIndex index2; - TkTextIndexForwChars(NULL,indexPtr, 1, &index2, COUNT_INDICES); + TkTextIndexForwChars(NULL, indexPtr, 1, &index2, COUNT_INDICES); /* * While we wish to redisplay, no heights have changed, so no need to @@ -430,12 +446,13 @@ TkTextMarkNameToIndex( } else if (!strcmp(name, "current")) { segPtr = textPtr->currentMarkPtr; } else { - Tcl_HashEntry *hPtr; - hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->markTable, name); + Tcl_HashEntry *hPtr = + Tcl_FindHashEntry(&textPtr->sharedTextPtr->markTable, name); + if (hPtr == NULL) { return TCL_ERROR; } - segPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr); + segPtr = Tcl_GetHashValue(hPtr); } TkTextMarkSegToIndex(textPtr, segPtr, indexPtr); @@ -578,7 +595,7 @@ MarkLayoutProc( */ chunkPtr->breakIndex = -1; - chunkPtr->clientData = (ClientData) textPtr; + chunkPtr->clientData = textPtr; return 1; } @@ -619,13 +636,13 @@ TkTextInsertDisplayProc( * We have no need for the clientData. */ - /* TkText *textPtr = (TkText *) chunkPtr->clientData; */ + /* TkText *textPtr = chunkPtr->clientData; */ TkTextIndex index; int halfWidth = textPtr->insertWidth/2; int rightSideWidth; int ix = 0, iy = 0, iw = 0, ih = 0, charWidth = 0; - if(textPtr->insertCursorType) { + if (textPtr->insertCursorType) { TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index); TkTextIndexBbox(textPtr, &index, &ix, &iy, &iw, &ih, &charWidth); rightSideWidth = charWidth + halfWidth; @@ -653,14 +670,37 @@ TkTextInsertDisplayProc( * the cursor. */ - if (textPtr->flags & INSERT_ON) { + if (textPtr->flags & GOT_FOCUS) { + if (textPtr->flags & INSERT_ON) { + Tk_Fill3DRectangle(textPtr->tkwin, dst, textPtr->insertBorder, + x - halfWidth, y, charWidth + textPtr->insertWidth, + height, textPtr->insertBorderWidth, TK_RELIEF_RAISED); + } else if (textPtr->selBorder == textPtr->insertBorder) { + Tk_Fill3DRectangle(textPtr->tkwin, dst, textPtr->border, + x - halfWidth, y, charWidth + textPtr->insertWidth, + height, 0, TK_RELIEF_FLAT); + } + } else if (textPtr->insertUnfocussed == TK_TEXT_INSERT_NOFOCUS_HOLLOW) { + if (textPtr->insertBorderWidth < 1) { + /* + * Hack to work around the fact that a "solid" border always + * paints in black. + */ + + TkBorder *borderPtr = (TkBorder *) textPtr->insertBorder; + + XDrawRectangle(Tk_Display(textPtr->tkwin), dst, borderPtr->bgGC, + x - halfWidth, y, charWidth + textPtr->insertWidth - 1, + height - 1); + } else { + Tk_Draw3DRectangle(textPtr->tkwin, dst, textPtr->insertBorder, + x - halfWidth, y, charWidth + textPtr->insertWidth, + height, textPtr->insertBorderWidth, TK_RELIEF_RAISED); + } + } else if (textPtr->insertUnfocussed == TK_TEXT_INSERT_NOFOCUS_SOLID) { Tk_Fill3DRectangle(textPtr->tkwin, dst, textPtr->insertBorder, x - halfWidth, y, charWidth + textPtr->insertWidth, height, textPtr->insertBorderWidth, TK_RELIEF_RAISED); - } else if (textPtr->selBorder == textPtr->insertBorder) { - Tk_Fill3DRectangle(textPtr->tkwin, dst, textPtr->border, - x - halfWidth, y, charWidth + textPtr->insertWidth, height, - 0, TK_RELIEF_FLAT); } } @@ -765,12 +805,13 @@ static int MarkFindNext( Tcl_Interp *interp, /* For error reporting */ TkText *textPtr, /* The widget */ - const char *string) /* The starting index or mark name */ + Tcl_Obj *obj) /* The starting index or mark name */ { TkTextIndex index; Tcl_HashEntry *hPtr; register TkTextSegment *segPtr; int offset; + const char *string = Tcl_GetString(obj); if (!strcmp(string, "insert")) { segPtr = textPtr->insertMarkPtr; @@ -789,7 +830,7 @@ MarkFindNext( * position. */ - segPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr); + segPtr = Tcl_GetHashValue(hPtr); TkTextMarkSegToIndex(textPtr, segPtr, &index); segPtr = segPtr->nextPtr; } else { @@ -798,7 +839,7 @@ MarkFindNext( * right at the index. */ - if (TkTextGetIndex(interp, textPtr, string, &index) != TCL_OK) { + if (TkTextGetObjIndex(interp, textPtr, obj, &index) != TCL_OK) { return TCL_ERROR; } for (offset = 0, segPtr = index.linePtr->segPtr; @@ -818,28 +859,12 @@ MarkFindNext( for ( ; segPtr != NULL ; segPtr = segPtr->nextPtr) { if (segPtr->typePtr == &tkTextRightMarkType || segPtr->typePtr == &tkTextLeftMarkType) { - if (segPtr == textPtr->currentMarkPtr) { - Tcl_SetResult(interp, "current", TCL_STATIC); - } else if (segPtr == textPtr->insertMarkPtr) { - Tcl_SetResult(interp, "insert", TCL_STATIC); - } else if (segPtr->body.mark.hPtr == NULL) { - /* - * Ignore widget-specific marks for the other widgets. - * This is either an insert or a current mark - * (markPtr->body.mark.hPtr actually receives NULL - * for these marks in TkTextSetMark). - * The insert and current marks for textPtr having - * already been tested above, the current segment is - * an insert or current mark from a peer of textPtr, - * which we don't want to return. - */ - continue; - } else { - Tcl_SetResult(interp, - Tcl_GetHashKey(&textPtr->sharedTextPtr->markTable, - segPtr->body.mark.hPtr), TCL_STATIC); + Tcl_Obj *markName = GetMarkName(textPtr, segPtr); + + if (markName != NULL) { + Tcl_SetObjResult(interp, markName); + return TCL_OK; } - return TCL_OK; } } index.linePtr = TkBTreeNextLine(textPtr, index.linePtr); @@ -871,12 +896,13 @@ static int MarkFindPrev( Tcl_Interp *interp, /* For error reporting */ TkText *textPtr, /* The widget */ - const char *string) /* The starting index or mark name */ + Tcl_Obj *obj) /* The starting index or mark name */ { TkTextIndex index; Tcl_HashEntry *hPtr; register TkTextSegment *segPtr, *seg2Ptr, *prevPtr; int offset; + const char *string = Tcl_GetString(obj); if (!strcmp(string, "insert")) { segPtr = textPtr->insertMarkPtr; @@ -893,7 +919,7 @@ MarkFindPrev( * position. */ - segPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr); + segPtr = Tcl_GetHashValue(hPtr); TkTextMarkSegToIndex(textPtr, segPtr, &index); } else { /* @@ -901,7 +927,7 @@ MarkFindPrev( * right at the index. */ - if (TkTextGetIndex(interp, textPtr, string, &index) != TCL_OK) { + if (TkTextGetObjIndex(interp, textPtr, obj, &index) != TCL_OK) { return TCL_ERROR; } for (offset = 0, segPtr = index.linePtr->segPtr; @@ -937,28 +963,11 @@ MarkFindPrev( } } if (prevPtr != NULL) { - if (prevPtr == textPtr->currentMarkPtr) { - Tcl_SetResult(interp, "current", TCL_STATIC); - return TCL_OK; - } else if (prevPtr == textPtr->insertMarkPtr) { - Tcl_SetResult(interp, "insert", TCL_STATIC); - return TCL_OK; - } else if (prevPtr->body.mark.hPtr == NULL) { - /* - * Ignore widget-specific marks for the other widgets. - * This is either an insert or a current mark - * (markPtr->body.mark.hPtr actually receives NULL - * for these marks in TkTextSetMark). - * The insert and current marks for textPtr having - * already been tested above, the current segment is - * an insert or current mark from a peer of textPtr, - * which we don't want to return. - */ - } else { - Tcl_SetResult(interp, - Tcl_GetHashKey(&textPtr->sharedTextPtr->markTable, - prevPtr->body.mark.hPtr), TCL_STATIC); - return TCL_OK; + Tcl_Obj *markName = GetMarkName(textPtr, prevPtr); + + if (markName != NULL) { + Tcl_SetObjResult(interp, markName); + return TCL_OK; } } index.linePtr = TkBTreePreviousLine(textPtr, index.linePtr); @@ -970,6 +979,46 @@ MarkFindPrev( } /* + * ------------------------------------------------------------------------ + * + * GetMarkName -- + * Returns the name of the mark that is the given text segment, or NULL + * if it is unnamed (i.e., a widget-specific mark that isn't "current" or + * "insert"). + * + * ------------------------------------------------------------------------ + */ + +static Tcl_Obj * +GetMarkName( + TkText *textPtr, + TkTextSegment *segPtr) +{ + const char *markName; + + if (segPtr == textPtr->currentMarkPtr) { + markName = "current"; + } else if (segPtr == textPtr->insertMarkPtr) { + markName = "insert"; + } else if (segPtr->body.mark.hPtr == NULL) { + /* + * Ignore widget-specific marks for the other widgets. This is either + * an insert or a current mark (markPtr->body.mark.hPtr actually + * receives NULL for these marks in TkTextSetMark). The insert and + * current marks for textPtr having already been tested above, the + * current segment is an insert or current mark from a peer of + * textPtr, which we don't want to return. + */ + + return NULL; + } else { + markName = Tcl_GetHashKey(&textPtr->sharedTextPtr->markTable, + segPtr->body.mark.hPtr); + } + return Tcl_NewStringObj(markName, -1); +} + +/* * Local Variables: * mode: c * c-basic-offset: 4 diff --git a/generic/tkTextTag.c b/generic/tkTextTag.c index d88825c..13216ca 100644 --- a/generic/tkTextTag.c +++ b/generic/tkTextTag.c @@ -23,18 +23,18 @@ * a whole is not. */ -static const char *wrapStrings[] = { +static const char *const wrapStrings[] = { "char", "none", "word", "", NULL }; /* * 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. */ -static const char *tabStyleStrings[] = { +static const char *const tabStyleStrings[] = { "tabular", "wordprocessor", "", NULL }; @@ -61,15 +61,26 @@ static const Tk_OptionSpec tagOptionSpecs[] = { NULL, -1, Tk_Offset(TkTextTag, lMargin1String), TK_OPTION_NULL_OK,0,0}, {TK_OPTION_STRING, "-lmargin2", NULL, NULL, NULL, -1, Tk_Offset(TkTextTag, lMargin2String), TK_OPTION_NULL_OK,0,0}, + {TK_OPTION_BORDER, "-lmargincolor", NULL, NULL, + NULL, -1, Tk_Offset(TkTextTag, lMarginColor), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING, "-offset", NULL, NULL, NULL, -1, Tk_Offset(TkTextTag, offsetString), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING, "-overstrike", NULL, NULL, NULL, -1, Tk_Offset(TkTextTag, overstrikeString), TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_COLOR, "-overstrikefg", NULL, NULL, + NULL, -1, Tk_Offset(TkTextTag, overstrikeColor), + TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING, "-relief", NULL, NULL, NULL, -1, Tk_Offset(TkTextTag, reliefString), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING, "-rmargin", NULL, NULL, NULL, -1, Tk_Offset(TkTextTag, rMarginString), TK_OPTION_NULL_OK, 0,0}, + {TK_OPTION_BORDER, "-rmargincolor", NULL, NULL, + NULL, -1, Tk_Offset(TkTextTag, rMarginColor), TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_BORDER, "-selectbackground", NULL, NULL, + NULL, -1, Tk_Offset(TkTextTag, selBorder), TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_COLOR, "-selectforeground", NULL, NULL, + NULL, -1, Tk_Offset(TkTextTag, selFgColor), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING, "-spacing1", NULL, NULL, NULL, -1, Tk_Offset(TkTextTag, spacing1String), TK_OPTION_NULL_OK,0,0}, {TK_OPTION_STRING, "-spacing2", NULL, NULL, @@ -80,14 +91,17 @@ static const Tk_OptionSpec tagOptionSpecs[] = { NULL, Tk_Offset(TkTextTag, tabStringPtr), -1, TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING_TABLE, "-tabstyle", NULL, NULL, NULL, -1, Tk_Offset(TkTextTag, tabStyle), - TK_OPTION_NULL_OK, (ClientData) tabStyleStrings, 0}, + TK_OPTION_NULL_OK, tabStyleStrings, 0}, {TK_OPTION_STRING, "-underline", NULL, NULL, NULL, -1, Tk_Offset(TkTextTag, underlineString), TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_COLOR, "-underlinefg", NULL, NULL, + NULL, -1, Tk_Offset(TkTextTag, underlineColor), + TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING_TABLE, "-wrap", NULL, NULL, NULL, -1, Tk_Offset(TkTextTag, wrapMode), - TK_OPTION_NULL_OK, (ClientData) wrapStrings, 0}, - {TK_OPTION_END} + TK_OPTION_NULL_OK, wrapStrings, 0}, + {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0} }; /* @@ -99,8 +113,8 @@ static void ChangeTagPriority(TkText *textPtr, TkTextTag *tagPtr, static TkTextTag * FindTag(Tcl_Interp *interp, TkText *textPtr, Tcl_Obj *tagName); static void SortTags(int numTags, TkTextTag **tagArrayPtr); -static int TagSortProc(CONST VOID *first, CONST VOID *second); -static void TagBindEvent(TkText *textPtr, XEvent *eventPtr, +static int TagSortProc(const void *first, const void *second); +static void TagBindEvent(TkText *textPtr, XEvent *eventPtr, int numTags, TkTextTag **tagArrayPtr); /* @@ -126,11 +140,11 @@ TkTextTagCmd( register TkText *textPtr, /* Information about text widget. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. Someone else has already + Tcl_Obj *const objv[]) /* Argument objects. Someone else has already * parsed this command enough to know that * objv[1] is "tag". */ { - static CONST char *tagOptionStrings[] = { + static const char *const tagOptionStrings[] = { "add", "bind", "cget", "configure", "delete", "lower", "names", "nextrange", "prevrange", "raise", "ranges", "remove", NULL }; @@ -144,12 +158,12 @@ TkTextTagCmd( TkTextIndex index1, index2; if (objc < 3) { - Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?"); + Tcl_WrongNumArgs(interp, 2, objv, "option ?arg ...?"); return TCL_ERROR; } - if (Tcl_GetIndexFromObj(interp, objv[2], tagOptionStrings, - "tag option", 0, &optionIndex) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[2], tagOptionStrings, + sizeof(char *), "tag option", 0, &optionIndex) != TCL_OK) { return TCL_ERROR; } @@ -221,7 +235,7 @@ TkTextTagCmd( if (tagPtr == textPtr->selTagPtr) { /* - * Send an event that the selection changed. This is + * Send an event that the selection changed. This is * equivalent to: * event generate $textWidget <<Selection>> */ @@ -229,9 +243,10 @@ TkTextTagCmd( TkTextSelectionEvent(textPtr); if (addTag && textPtr->exportSelection + && (!Tcl_IsSafe(textPtr->interp)) && !(textPtr->flags & GOT_SELECTION)) { Tk_OwnSelection(textPtr->tkwin, XA_PRIMARY, - TkTextLostSelection, (ClientData) textPtr); + TkTextLostSelection, textPtr); textPtr->flags |= GOT_SELECTION; } textPtr->abortSelections = 1; @@ -259,7 +274,7 @@ TkTextTagCmd( if (objc == 6) { int append = 0; unsigned long mask; - char *fifth = Tcl_GetString(objv[5]); + const char *fifth = Tcl_GetString(objv[5]); if (fifth[0] == 0) { return Tk_DeleteBinding(interp, @@ -284,20 +299,20 @@ TkTextTagCmd( |KeyReleaseMask|PointerMotionMask|VirtualEventMask)) { Tk_DeleteBinding(interp, textPtr->sharedTextPtr->bindingTable, (ClientData) tagPtr->name, Tcl_GetString(objv[4])); - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "requested illegal events; ", - "only key, button, motion, enter, leave, and virtual ", - "events may be used", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "requested illegal events; only key, button, motion," + " enter, leave, and virtual events may be used", -1)); + Tcl_SetErrorCode(interp, "TK", "TEXT", "TAG_BIND_EVENT",NULL); return TCL_ERROR; } } else if (objc == 5) { - CONST char *command; + const char *command; command = Tk_GetBinding(interp, textPtr->sharedTextPtr->bindingTable, (ClientData) tagPtr->name, Tcl_GetString(objv[4])); if (command == NULL) { - CONST char *string = Tcl_GetStringResult(interp); + const char *string = Tcl_GetString(Tcl_GetObjResult(interp)); /* * Ignore missing binding errors. This is a special hack that @@ -310,7 +325,7 @@ TkTextTagCmd( } Tcl_ResetResult(interp); } else { - Tcl_SetResult(interp, (char *) command, TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj(command, -1)); } } else { Tk_GetAllBindings(interp, textPtr->sharedTextPtr->bindingTable, @@ -342,7 +357,7 @@ TkTextTagCmd( if (objc < 4) { Tcl_WrongNumArgs(interp, 3, objv, - "tagName ?option? ?value? ?option value ...?"); + "tagName ?-option? ?value? ?-option value ...?"); return TCL_ERROR; } tagPtr = TkTextCreateTag(textPtr, Tcl_GetString(objv[3]), &newTag); @@ -359,7 +374,7 @@ TkTextTagCmd( } else { int result = TCL_OK; - if (Tk_SetOptions(interp, (char*)tagPtr, tagPtr->optionTable, + if (Tk_SetOptions(interp, (char *) tagPtr, tagPtr->optionTable, objc-4, objv+4, textPtr->tkwin, NULL, NULL) != TCL_OK) { return TCL_ERROR; } @@ -444,7 +459,7 @@ TkTextTagCmd( } } if (tagPtr->tabArrayPtr != NULL) { - ckfree((char *) tagPtr->tabArrayPtr); + ckfree(tagPtr->tabArrayPtr); tagPtr->tabArrayPtr = NULL; } if (tagPtr->tabStringPtr != NULL) { @@ -465,11 +480,14 @@ TkTextTagCmd( &tagPtr->elide) != TCL_OK) { return TCL_ERROR; } - /* Indices are potentially obsolete after changing -elide, - * especially those computed with "display" or "any" - * submodifier, therefore increase the epoch. - */ - textPtr->sharedTextPtr->stateEpoch++; + + /* + * Indices are potentially obsolete after changing -elide, + * especially those computed with "display" or "any" + * submodifier, therefore increase the epoch. + */ + + textPtr->sharedTextPtr->stateEpoch++; } /* @@ -481,10 +499,18 @@ TkTextTagCmd( */ if (tagPtr == textPtr->selTagPtr) { - textPtr->selBorder = tagPtr->border; + if (tagPtr->selBorder == NULL) { + textPtr->selBorder = tagPtr->border; + } else { + textPtr->selBorder = tagPtr->selBorder; + } textPtr->selBorderWidth = tagPtr->borderWidth; textPtr->selBorderWidthPtr = tagPtr->borderWidthPtr; - textPtr->selFgColorPtr = tagPtr->fgColor; + if (tagPtr->selFgColor == NULL) { + textPtr->selFgColorPtr = tagPtr->fgColor; + } else { + textPtr->selFgColorPtr = tagPtr->selFgColor; + } } tagPtr->affectsDisplay = 0; @@ -506,12 +532,18 @@ TkTextTagCmd( tagPtr->affectsDisplayGeometry = 1; } if ((tagPtr->border != NULL) + || (tagPtr->selBorder != NULL) || (tagPtr->reliefString != NULL) || (tagPtr->bgStipple != None) || (tagPtr->fgColor != NULL) + || (tagPtr->selFgColor != NULL) || (tagPtr->fgStipple != None) || (tagPtr->overstrikeString != NULL) - || (tagPtr->underlineString != NULL)) { + || (tagPtr->overstrikeColor != NULL) + || (tagPtr->underlineString != NULL) + || (tagPtr->underlineColor != NULL) + || (tagPtr->lMarginColor != NULL) + || (tagPtr->rMarginColor != NULL)) { tagPtr->affectsDisplay = 1; } if (!newTag) { @@ -552,7 +584,7 @@ TkTextTagCmd( continue; } - tagPtr = (TkTextTag *) Tcl_GetHashValue(hPtr); + tagPtr = Tcl_GetHashValue(hPtr); if (tagPtr == textPtr->selTagPtr) { continue; } @@ -613,12 +645,12 @@ TkTextTagCmd( Tcl_HashSearch search; Tcl_HashEntry *hPtr; - arrayPtr = (TkTextTag **) ckalloc((unsigned) - (textPtr->sharedTextPtr->numTags * sizeof(TkTextTag *))); + arrayPtr = ckalloc(textPtr->sharedTextPtr->numTags + * sizeof(TkTextTag *)); for (i=0, hPtr = Tcl_FirstHashEntry( &textPtr->sharedTextPtr->tagTable, &search); hPtr != NULL; i++, hPtr = Tcl_NextHashEntry(&search)) { - arrayPtr[i] = (TkTextTag *) Tcl_GetHashValue(hPtr); + arrayPtr[i] = Tcl_GetHashValue(hPtr); } /* @@ -647,13 +679,14 @@ TkTextTagCmd( Tcl_NewStringObj(tagPtr->name,-1)); } Tcl_SetObjResult(interp, listObj); - ckfree((char *) arrayPtr); + ckfree(arrayPtr); break; } case TAG_NEXTRANGE: { TkTextIndex last; TkTextSearch tSearch; char position[TK_POS_CHARS]; + Tcl_Obj *resultObj; if ((objc != 5) && (objc != 6)) { Tcl_WrongNumArgs(interp, 3, objv, "tagName index1 ?index2?"); @@ -722,11 +755,15 @@ TkTextTagCmd( if (TkTextIndexCmp(&tSearch.curIndex, &index2) >= 0) { return TCL_OK; } + resultObj = Tcl_NewObj(); TkTextPrintIndex(textPtr, &tSearch.curIndex, position); - Tcl_AppendElement(interp, position); + Tcl_ListObjAppendElement(NULL, resultObj, + Tcl_NewStringObj(position, -1)); TkBTreeNextTag(&tSearch); TkTextPrintIndex(textPtr, &tSearch.curIndex, position); - Tcl_AppendElement(interp, position); + Tcl_ListObjAppendElement(NULL, resultObj, + Tcl_NewStringObj(position, -1)); + Tcl_SetObjResult(interp, resultObj); break; } case TAG_PREVRANGE: { @@ -734,6 +771,7 @@ TkTextTagCmd( TkTextSearch tSearch; char position1[TK_POS_CHARS]; char position2[TK_POS_CHARS]; + Tcl_Obj *resultObj; if ((objc != 5) && (objc != 6)) { Tcl_WrongNumArgs(interp, 3, objv, "tagName index1 ?index2?"); @@ -781,8 +819,7 @@ TkTextTagCmd( TkTextPrintIndex(textPtr, &index2, position1); TkTextPrintIndex(textPtr, &index1, position2); - Tcl_AppendElement(interp, position1); - Tcl_AppendElement(interp, position2); + goto gotPrevIndexPair; } return TCL_OK; } @@ -832,8 +869,14 @@ TkTextTagCmd( } } } - Tcl_AppendElement(interp, position1); - Tcl_AppendElement(interp, position2); + + gotPrevIndexPair: + resultObj = Tcl_NewObj(); + Tcl_ListObjAppendElement(NULL, resultObj, + Tcl_NewStringObj(position1, -1)); + Tcl_ListObjAppendElement(NULL, resultObj, + Tcl_NewStringObj(position2, -1)); + Tcl_SetObjResult(interp, resultObj); break; } case TAG_RAISE: { @@ -892,12 +935,12 @@ TkTextTagCmd( 0, &last); TkBTreeStartSearch(&first, &last, tagPtr, &tSearch); if (TkBTreeCharTagged(&first, tagPtr)) { - Tcl_ListObjAppendElement(interp, listObj, + Tcl_ListObjAppendElement(NULL, listObj, TkTextNewIndexObj(textPtr, &first)); count++; } while (TkBTreeNextTag(&tSearch)) { - Tcl_ListObjAppendElement(interp, listObj, + Tcl_ListObjAppendElement(NULL, listObj, TkTextNewIndexObj(textPtr, &tSearch.curIndex)); count++; } @@ -908,7 +951,7 @@ TkTextTagCmd( * closed. In this case we add the end of the range. */ - Tcl_ListObjAppendElement(interp, listObj, + Tcl_ListObjAppendElement(NULL, listObj, TkTextNewIndexObj(textPtr, &last)); } Tcl_SetObjResult(interp, listObj); @@ -939,25 +982,25 @@ TkTextTagCmd( TkTextTag * TkTextCreateTag( TkText *textPtr, /* Widget in which tag is being used. */ - CONST char *tagName, /* Name of desired tag. */ + const char *tagName, /* Name of desired tag. */ int *newTag) /* If non-NULL, then return 1 if new, or 0 if * already exists. */ { register TkTextTag *tagPtr; Tcl_HashEntry *hPtr = NULL; int isNew; - CONST char *name; + const char *name; if (!strcmp(tagName, "sel")) { - if (textPtr->selTagPtr != NULL) { + if (textPtr->selTagPtr != NULL) { if (newTag != NULL) { - *newTag = 0; + *newTag = 0; } - return textPtr->selTagPtr; - } + return textPtr->selTagPtr; + } if (newTag != NULL) { *newTag = 1; - } + } name = "sel"; } else { hPtr = Tcl_CreateHashEntry(&textPtr->sharedTextPtr->tagTable, @@ -966,7 +1009,7 @@ TkTextCreateTag( *newTag = isNew; } if (!isNew) { - return (TkTextTag *) Tcl_GetHashValue(hPtr); + return Tcl_GetHashValue(hPtr); } name = Tcl_GetHashKey(&textPtr->sharedTextPtr->tagTable, hPtr); } @@ -976,7 +1019,7 @@ TkTextCreateTag( * to it to the hash table entry. */ - tagPtr = (TkTextTag *) ckalloc(sizeof(TkTextTag)); + tagPtr = ckalloc(sizeof(TkTextTag)); tagPtr->name = name; tagPtr->textPtr = NULL; tagPtr->toggleCount = 0; @@ -997,12 +1040,17 @@ TkTextCreateTag( tagPtr->lMargin1 = 0; tagPtr->lMargin2String = NULL; tagPtr->lMargin2 = 0; + tagPtr->lMarginColor = NULL; tagPtr->offsetString = NULL; tagPtr->offset = 0; tagPtr->overstrikeString = NULL; tagPtr->overstrike = 0; + tagPtr->overstrikeColor = NULL; tagPtr->rMarginString = NULL; tagPtr->rMargin = 0; + tagPtr->rMarginColor = NULL; + tagPtr->selBorder = NULL; + tagPtr->selFgColor = NULL; tagPtr->spacing1String = NULL; tagPtr->spacing1 = 0; tagPtr->spacing2String = NULL; @@ -1014,6 +1062,7 @@ TkTextCreateTag( tagPtr->tabStyle = TK_TEXT_TABSTYLE_NONE; tagPtr->underlineString = NULL; tagPtr->underline = 0; + tagPtr->underlineColor = NULL; tagPtr->elideString = NULL; tagPtr->elide = 0; tagPtr->wrapMode = TEXT_WRAPMODE_NULL; @@ -1024,6 +1073,7 @@ TkTextCreateTag( tagPtr->textPtr = textPtr; textPtr->refCount++; } else { + CLANG_ASSERT(hPtr); Tcl_SetHashValue(hPtr, tagPtr); } tagPtr->optionTable = @@ -1055,24 +1105,27 @@ FindTag( * NULL, then don't record an error * message. */ TkText *textPtr, /* Widget in which tag is being used. */ - Tcl_Obj *tagName) /* Name of desired tag. */ + Tcl_Obj *tagName) /* Name of desired tag. */ { Tcl_HashEntry *hPtr; int len; - CONST char *str; + const char *str; str = Tcl_GetStringFromObj(tagName, &len); - if (len == 3 && !strcmp(str,"sel")) { - return textPtr->selTagPtr; + if (len == 3 && !strcmp(str, "sel")) { + return textPtr->selTagPtr; } hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->tagTable, Tcl_GetString(tagName)); if (hPtr != NULL) { - return (TkTextTag *) Tcl_GetHashValue(hPtr); + return Tcl_GetHashValue(hPtr); } if (interp != NULL) { - Tcl_AppendResult(interp, "tag \"", Tcl_GetString(tagName), - "\" isn't defined in text widget", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "tag \"%s\" isn't defined in text widget", + Tcl_GetString(tagName))); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "TEXT_TAG", + Tcl_GetString(tagName), NULL); } return NULL; } @@ -1179,7 +1232,7 @@ TkTextFreeTag( */ if (tagPtr->tabArrayPtr != NULL) { - ckfree((char *) tagPtr->tabArrayPtr); + ckfree(tagPtr->tabArrayPtr); } /* @@ -1206,9 +1259,8 @@ TkTextFreeTag( if (textPtr != tagPtr->textPtr) { Tcl_Panic("Tag being deleted from wrong widget"); } - textPtr->refCount--; - if (textPtr->refCount == 0) { - ckfree((char *) textPtr); + if (textPtr->refCount-- <= 1) { + ckfree(textPtr); } tagPtr->textPtr = NULL; } @@ -1217,7 +1269,7 @@ TkTextFreeTag( * Finally free the tag's memory. */ - ckfree((char *) tagPtr); + ckfree(tagPtr); } /* @@ -1290,8 +1342,8 @@ SortTags( static int TagSortProc( - CONST void *first, - CONST void *second) /* Elements to be compared. */ + const void *first, + const void *second) /* Elements to be compared. */ { TkTextTag *tagPtr1, *tagPtr2; @@ -1360,7 +1412,7 @@ ChangeTagPriority( } for (hPtr = Tcl_FirstHashEntry(&textPtr->sharedTextPtr->tagTable, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - tagPtr2 = (TkTextTag *) Tcl_GetHashValue(hPtr); + tagPtr2 = Tcl_GetHashValue(hPtr); if ((tagPtr2->priority >= low) && (tagPtr2->priority <= high)) { tagPtr2->priority += delta; } @@ -1391,8 +1443,8 @@ TkTextBindProc( ClientData clientData, /* Pointer to canvas structure. */ XEvent *eventPtr) /* Pointer to X event that just happened. */ { - TkText *textPtr = (TkText *) clientData; - int repick = 0; + TkText *textPtr = clientData; + int repick = 0; # define AnyButtonMask \ (Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask) @@ -1436,7 +1488,7 @@ TkTextBindProc( } } else if ((eventPtr->type == EnterNotify) || (eventPtr->type == LeaveNotify)) { - if (eventPtr->xcrossing.state & AnyButtonMask) { + if (eventPtr->xcrossing.state & AnyButtonMask) { textPtr->flags |= BUTTON_DOWN; } else { textPtr->flags &= ~BUTTON_DOWN; @@ -1444,7 +1496,7 @@ TkTextBindProc( TkTextPickCurrent(textPtr, eventPtr); goto done; } else if (eventPtr->type == MotionNotify) { - if (eventPtr->xmotion.state & AnyButtonMask) { + if (eventPtr->xmotion.state & AnyButtonMask) { textPtr->flags |= BUTTON_DOWN; } else { textPtr->flags &= ~BUTTON_DOWN; @@ -1470,8 +1522,8 @@ TkTextBindProc( } done: - if (--textPtr->refCount == 0) { - ckfree((char *) textPtr); + if (textPtr->refCount-- <= 1) { + ckfree(textPtr); } } @@ -1568,7 +1620,7 @@ TkTextPickCurrent( = eventPtr->xmotion.same_screen; textPtr->pickEvent.xcrossing.focus = False; textPtr->pickEvent.xcrossing.state = eventPtr->xmotion.state; - } else { + } else { textPtr->pickEvent = *eventPtr; } } @@ -1603,7 +1655,7 @@ TkTextPickCurrent( SortTags(textPtr->numCurTags, textPtr->curTagArrayPtr); if (numNewTags > 0) { size = numNewTags * sizeof(TkTextTag *); - copyArrayPtr = (TkTextTag **) ckalloc((unsigned) size); + copyArrayPtr = ckalloc(size); memcpy(copyArrayPtr, newArrayPtr, (size_t) size); for (i = 0; i < textPtr->numCurTags; i++) { for (j = 0; j < numNewTags; j++) { @@ -1645,7 +1697,7 @@ TkTextPickCurrent( event.xcrossing.detail = NotifyAncestor; TagBindEvent(textPtr, &event, numOldTags, oldArrayPtr); } - ckfree((char *) oldArrayPtr); + ckfree(oldArrayPtr); } /* @@ -1667,7 +1719,7 @@ TkTextPickCurrent( event.xcrossing.detail = NotifyAncestor; TagBindEvent(textPtr, &event, numNewTags, copyArrayPtr); } - ckfree((char *) copyArrayPtr); + ckfree(copyArrayPtr); } } @@ -1697,9 +1749,9 @@ TagBindEvent( int numTags, /* Number of relevant tags. */ TkTextTag **tagArrayPtr) /* Array of relevant tags. */ { - #define NUM_BIND_TAGS 10 - CONST char *nameArray[NUM_BIND_TAGS]; - CONST char **nameArrPtr; +# define NUM_BIND_TAGS 10 + const char *nameArray[NUM_BIND_TAGS]; + const char **nameArrPtr; int i; /* @@ -1707,7 +1759,7 @@ TagBindEvent( */ if (numTags > NUM_BIND_TAGS) { - nameArrPtr = (CONST char **) ckalloc(numTags * sizeof(CONST char *)); + nameArrPtr = ckalloc(numTags * sizeof(const char *)); } else { nameArrPtr = nameArray; } @@ -1720,6 +1772,7 @@ TagBindEvent( for (i = 0; i < numTags; i++) { TkTextTag *tagPtr = tagArrayPtr[i]; + if (tagPtr != NULL) { nameArrPtr[i] = tagPtr->name; } else { @@ -1736,7 +1789,7 @@ TagBindEvent( textPtr->tkwin, numTags, (ClientData *) nameArrPtr); if (numTags > NUM_BIND_TAGS) { - ckfree((char *) nameArrPtr); + ckfree(nameArrPtr); } } diff --git a/generic/tkTextWind.c b/generic/tkTextWind.c index 5b511d2..c9fc20f 100644 --- a/generic/tkTextWind.c +++ b/generic/tkTextWind.c @@ -63,14 +63,14 @@ static void EmbWinStructureProc(ClientData clientData, XEvent *eventPtr); static void EmbWinUndisplayProc(TkText *textPtr, TkTextDispChunk *chunkPtr); -static TkTextEmbWindowClient* EmbWinGetClient(const TkText *textPtr, +static TkTextEmbWindowClient *EmbWinGetClient(const TkText *textPtr, TkTextSegment *ewPtr); /* * The following structure declares the "embedded window" segment type. */ -static const Tk_SegType tkTextEmbWindowType = { +const Tk_SegType tkTextEmbWindowType = { "window", /* name */ 0, /* leftGravity */ NULL, /* splitProc */ @@ -85,7 +85,7 @@ static const Tk_SegType tkTextEmbWindowType = { * Definitions for alignment values: */ -static const char *alignStrings[] = { +static const char *const alignStrings[] = { "baseline", "bottom", "center", "top", NULL }; @@ -100,7 +100,7 @@ typedef enum { static const Tk_OptionSpec optionSpecs[] = { {TK_OPTION_STRING_TABLE, "-align", NULL, NULL, "center", -1, Tk_Offset(TkTextEmbWindow, align), - 0, (ClientData) alignStrings, 0}, + 0, alignStrings, 0}, {TK_OPTION_STRING, "-create", NULL, NULL, NULL, -1, Tk_Offset(TkTextEmbWindow, create), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_PIXELS, "-padx", NULL, NULL, @@ -111,7 +111,7 @@ static const Tk_OptionSpec optionSpecs[] = { "0", -1, Tk_Offset(TkTextEmbWindow, stretch), 0, 0, 0}, {TK_OPTION_WINDOW, "-window", NULL, NULL, NULL, -1, Tk_Offset(TkTextEmbWindow, tkwin), TK_OPTION_NULL_OK, 0, 0}, - {TK_OPTION_END} + {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0} }; /* @@ -141,7 +141,7 @@ TkTextWindowCmd( * objv[1] is "window". */ { int optionIndex; - static const char *windOptionStrings[] = { + static const char *const windOptionStrings[] = { "cget", "configure", "create", "names", NULL }; enum windOptions { @@ -150,11 +150,11 @@ TkTextWindowCmd( register TkTextSegment *ewPtr; if (objc < 3) { - Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?"); + Tcl_WrongNumArgs(interp, 2, objv, "option ?arg ...?"); return TCL_ERROR; } - if (Tcl_GetIndexFromObj(interp, objv[2], windOptionStrings, - "window option", 0, &optionIndex) != TCL_OK) { + if (Tcl_GetIndexFromObjStruct(interp, objv[2], windOptionStrings, + sizeof(char *), "window option", 0, &optionIndex) != TCL_OK) { return TCL_ERROR; } switch ((enum windOptions) optionIndex) { @@ -173,8 +173,10 @@ TkTextWindowCmd( } ewPtr = TkTextIndexToSeg(&index, NULL); if (ewPtr->typePtr != &tkTextEmbWindowType) { - Tcl_AppendResult(interp, "no embedded window at index \"", - Tcl_GetString(objv[3]), "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "no embedded window at index \"%s\"", + Tcl_GetString(objv[3]))); + Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_WINDOW", NULL); return TCL_ERROR; } @@ -202,7 +204,7 @@ TkTextWindowCmd( TkTextSegment *ewPtr; if (objc < 4) { - Tcl_WrongNumArgs(interp, 3, objv, "index ?option value ...?"); + Tcl_WrongNumArgs(interp, 3, objv, "index ?-option value ...?"); return TCL_ERROR; } if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) { @@ -210,13 +212,15 @@ TkTextWindowCmd( } ewPtr = TkTextIndexToSeg(&index, NULL); if (ewPtr->typePtr != &tkTextEmbWindowType) { - Tcl_AppendResult(interp, "no embedded window at index \"", - Tcl_GetString(objv[3]), "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "no embedded window at index \"%s\"", + Tcl_GetString(objv[3]))); + Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_WINDOW", NULL); return TCL_ERROR; } if (objc <= 5) { TkTextEmbWindowClient *client; - Tcl_Obj* objPtr; + Tcl_Obj *objPtr; /* * Copy over client specific value before querying. @@ -263,7 +267,7 @@ TkTextWindowCmd( */ if (objc < 4) { - Tcl_WrongNumArgs(interp, 3, objv, "index ?option value ...?"); + Tcl_WrongNumArgs(interp, 3, objv, "index ?-option value ...?"); return TCL_ERROR; } if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) { @@ -286,7 +290,7 @@ TkTextWindowCmd( * Create the new window segment and initialize it. */ - ewPtr = (TkTextSegment *) ckalloc(EW_SEG_SIZE); + ewPtr = ckalloc(EW_SEG_SIZE); ewPtr->typePtr = &tkTextEmbWindowType; ewPtr->size = 1; ewPtr->body.ew.sharedTextPtr = textPtr->sharedTextPtr; @@ -298,8 +302,7 @@ TkTextWindowCmd( ewPtr->body.ew.stretch = 0; ewPtr->body.ew.optionTable = Tk_CreateOptionTable(interp, optionSpecs); - client = (TkTextEmbWindowClient *) - ckalloc(sizeof(TkTextEmbWindowClient)); + client = ckalloc(sizeof(TkTextEmbWindowClient)); client->next = NULL; client->textPtr = textPtr; client->tkwin = NULL; @@ -332,16 +335,20 @@ TkTextWindowCmd( case WIND_NAMES: { Tcl_HashSearch search; Tcl_HashEntry *hPtr; + Tcl_Obj *resultObj; if (objc != 3) { Tcl_WrongNumArgs(interp, 3, objv, NULL); return TCL_ERROR; } + resultObj = Tcl_NewObj(); for (hPtr = Tcl_FirstHashEntry(&textPtr->sharedTextPtr->windowTable, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - Tcl_AppendElement(interp, - Tcl_GetHashKey(&textPtr->sharedTextPtr->markTable, hPtr)); + Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj( + Tcl_GetHashKey(&textPtr->sharedTextPtr->markTable, hPtr), + -1)); } + Tcl_SetObjResult(interp, resultObj); break; } } @@ -408,8 +415,8 @@ EmbWinConfigure( &textPtr->sharedTextPtr->windowTable, Tk_PathName(oldWindow))); Tk_DeleteEventHandler(oldWindow, StructureNotifyMask, - EmbWinStructureProc, (ClientData) client); - Tk_ManageGeometry(oldWindow, NULL, (ClientData) NULL); + EmbWinStructureProc, client); + Tk_ManageGeometry(oldWindow, NULL, NULL); if (textPtr->tkwin != Tk_Parent(oldWindow)) { Tk_UnmaintainGeometry(oldWindow, textPtr->tkwin); } else { @@ -437,9 +444,12 @@ EmbWinConfigure( } if (Tk_TopWinHierarchy(ancestor)) { badMaster: - Tcl_AppendResult(textPtr->interp, "can't embed ", - Tk_PathName(ewPtr->body.ew.tkwin), " in ", - Tk_PathName(textPtr->tkwin), NULL); + Tcl_SetObjResult(textPtr->interp, Tcl_ObjPrintf( + "can't embed %s in %s", + Tk_PathName(ewPtr->body.ew.tkwin), + Tk_PathName(textPtr->tkwin))); + Tcl_SetErrorCode(textPtr->interp, "TK", "GEOMETRY", + "HIERARCHY", NULL); ewPtr->body.ew.tkwin = NULL; if (client != NULL) { client->tkwin = NULL; @@ -457,8 +467,7 @@ EmbWinConfigure( * Have to make the new client. */ - client = (TkTextEmbWindowClient *) - ckalloc(sizeof(TkTextEmbWindowClient)); + client = ckalloc(sizeof(TkTextEmbWindowClient)); client->next = ewPtr->body.ew.clients; client->textPtr = textPtr; client->tkwin = NULL; @@ -474,10 +483,9 @@ EmbWinConfigure( * event handler to find out when it is deleted. */ - Tk_ManageGeometry(ewPtr->body.ew.tkwin, &textGeomType, - (ClientData) client); + Tk_ManageGeometry(ewPtr->body.ew.tkwin, &textGeomType, client); Tk_CreateEventHandler(ewPtr->body.ew.tkwin, StructureNotifyMask, - EmbWinStructureProc, (ClientData) client); + EmbWinStructureProc, client); /* * Special trick! Must enter into the hash table *after* calling @@ -518,7 +526,7 @@ EmbWinStructureProc( ClientData clientData, /* Pointer to record describing window item. */ XEvent *eventPtr) /* Describes what just happened. */ { - TkTextEmbWindowClient *client = (TkTextEmbWindowClient*)clientData; + TkTextEmbWindowClient *client = clientData; TkTextSegment *ewPtr = client->parent; TkTextIndex index; Tcl_HashEntry *hPtr; @@ -571,7 +579,7 @@ EmbWinRequestProc( ClientData clientData, /* Pointer to record for window item. */ Tk_Window tkwin) /* Window that changed its desired size. */ { - TkTextEmbWindowClient *client = (TkTextEmbWindowClient*)clientData; + TkTextEmbWindowClient *client = clientData; TkTextSegment *ewPtr = client->parent; TkTextIndex index; @@ -608,15 +616,15 @@ EmbWinLostSlaveProc( Tk_Window tkwin) /* Window that was claimed away by another * geometry manager. */ { - TkTextEmbWindowClient *client = (TkTextEmbWindowClient*)clientData; + TkTextEmbWindowClient *client = clientData; TkTextSegment *ewPtr = client->parent; TkTextIndex index; Tcl_HashEntry *hPtr; TkTextEmbWindowClient *loop; Tk_DeleteEventHandler(client->tkwin, StructureNotifyMask, - EmbWinStructureProc, (ClientData) client); - Tcl_CancelIdleCall(EmbWinDelayedUnmap, (ClientData) client); + EmbWinStructureProc, client); + Tcl_CancelIdleCall(EmbWinDelayedUnmap, client); if (client->textPtr->tkwin != Tk_Parent(tkwin)) { Tk_UnmaintainGeometry(tkwin, client->textPtr->tkwin); } else { @@ -641,7 +649,7 @@ EmbWinLostSlaveProc( } loop->next = client->next; } - ckfree((char *) client); + ckfree(client); index.tree = ewPtr->body.ew.sharedTextPtr->tree; index.linePtr = ewPtr->body.ew.linePtr; @@ -698,16 +706,16 @@ TkTextWinFreeClient( if (client->tkwin != NULL) { Tk_DeleteEventHandler(client->tkwin, StructureNotifyMask, - EmbWinStructureProc, (ClientData) client); + EmbWinStructureProc, client); Tk_DestroyWindow(client->tkwin); } - Tcl_CancelIdleCall(EmbWinDelayedUnmap, (ClientData) client); + Tcl_CancelIdleCall(EmbWinDelayedUnmap, client); /* * Free up this client. */ - ckfree((char *) client); + ckfree(client); } /* @@ -761,7 +769,7 @@ EmbWinDeleteProc( * Free up all memory allocated. */ - ckfree((char *) ewPtr); + ckfree(ewPtr); return 0; } @@ -849,7 +857,8 @@ EmbWinLayoutProc( Tk_Window ancestor; Tcl_HashEntry *hPtr; const char *before, *string; - Tcl_DString name, buf, *dsPtr = NULL; + Tcl_DString buf, *dsPtr = NULL; + Tcl_Obj *nameObj; before = ewPtr->body.ew.create; @@ -908,36 +917,40 @@ EmbWinLayoutProc( code = Tcl_EvalEx(textPtr->interp, ewPtr->body.ew.create, -1, TCL_EVAL_GLOBAL); } if (code != TCL_OK) { - createError: - Tcl_BackgroundError(textPtr->interp); + Tcl_BackgroundException(textPtr->interp, code); goto gotWindow; } - Tcl_DStringInit(&name); - Tcl_DStringAppend(&name, Tcl_GetStringResult(textPtr->interp), -1); + nameObj = Tcl_GetObjResult(textPtr->interp); + Tcl_IncrRefCount(nameObj); Tcl_ResetResult(textPtr->interp); ewPtr->body.ew.tkwin = Tk_NameToWindow(textPtr->interp, - Tcl_DStringValue(&name), textPtr->tkwin); - Tcl_DStringFree(&name); + Tcl_GetString(nameObj), textPtr->tkwin); + Tcl_DecrRefCount(nameObj); if (ewPtr->body.ew.tkwin == NULL) { - goto createError; + Tcl_BackgroundException(textPtr->interp, TCL_ERROR); + goto gotWindow; } + for (ancestor = textPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) { if (ancestor == Tk_Parent(ewPtr->body.ew.tkwin)) { break; } if (Tk_TopWinHierarchy(ancestor)) { - badMaster: - Tcl_AppendResult(textPtr->interp, "can't embed ", - Tk_PathName(ewPtr->body.ew.tkwin), " relative to ", - Tk_PathName(textPtr->tkwin), NULL); - Tcl_BackgroundError(textPtr->interp); - ewPtr->body.ew.tkwin = NULL; - goto gotWindow; + goto badMaster; } } if (Tk_TopWinHierarchy(ewPtr->body.ew.tkwin) || (textPtr->tkwin == ewPtr->body.ew.tkwin)) { - goto badMaster; + badMaster: + Tcl_SetObjResult(textPtr->interp, Tcl_ObjPrintf( + "can't embed %s relative to %s", + Tk_PathName(ewPtr->body.ew.tkwin), + Tk_PathName(textPtr->tkwin))); + Tcl_SetErrorCode(textPtr->interp, "TK", "GEOMETRY", "HIERARCHY", + NULL); + Tcl_BackgroundException(textPtr->interp, TCL_ERROR); + ewPtr->body.ew.tkwin = NULL; + goto gotWindow; } if (client == NULL) { @@ -946,8 +959,7 @@ EmbWinLayoutProc( * now need to add to our client list. */ - client = (TkTextEmbWindowClient *) - ckalloc(sizeof(TkTextEmbWindowClient)); + client = ckalloc(sizeof(TkTextEmbWindowClient)); client->next = ewPtr->body.ew.clients; client->textPtr = textPtr; client->tkwin = NULL; @@ -958,10 +970,9 @@ EmbWinLayoutProc( } client->tkwin = ewPtr->body.ew.tkwin; - Tk_ManageGeometry(client->tkwin, &textGeomType, - (ClientData) client); + Tk_ManageGeometry(client->tkwin, &textGeomType, client); Tk_CreateEventHandler(client->tkwin, StructureNotifyMask, - EmbWinStructureProc, (ClientData) client); + EmbWinStructureProc, client); /* * Special trick! Must enter into the hash table *after* calling @@ -1013,7 +1024,7 @@ EmbWinLayoutProc( chunkPtr->width = width; chunkPtr->breakIndex = -1; chunkPtr->breakIndex = 1; - chunkPtr->clientData = (ClientData) ewPtr; + chunkPtr->clientData = ewPtr; if (client != NULL) { client->chunkCount += 1; } @@ -1089,7 +1100,7 @@ TkTextEmbWinDisplayProc( { int lineX, windowX, windowY, width, height; Tk_Window tkwin; - TkTextSegment *ewPtr = (TkTextSegment*) chunkPtr->clientData; + TkTextSegment *ewPtr = chunkPtr->clientData; TkTextEmbWindowClient *client = EmbWinGetClient(textPtr, ewPtr); if (client == NULL) { @@ -1169,7 +1180,7 @@ EmbWinUndisplayProc( TkText *textPtr, /* Overall information about text widget. */ TkTextDispChunk *chunkPtr) /* Chunk that is about to be freed. */ { - TkTextSegment *ewPtr = (TkTextSegment*) chunkPtr->clientData; + TkTextSegment *ewPtr = chunkPtr->clientData; TkTextEmbWindowClient *client = EmbWinGetClient(textPtr, ewPtr); if (client == NULL) { @@ -1187,7 +1198,7 @@ EmbWinUndisplayProc( */ client->displayed = 0; - Tcl_DoWhenIdle(EmbWinDelayedUnmap, (ClientData) client); + Tcl_DoWhenIdle(EmbWinDelayedUnmap, client); } } @@ -1232,7 +1243,7 @@ EmbWinBboxProc( * pixels. */ { Tk_Window tkwin; - TkTextSegment *ewPtr = (TkTextSegment *) chunkPtr->clientData; + TkTextSegment *ewPtr = chunkPtr->clientData; TkTextEmbWindowClient *client = EmbWinGetClient(textPtr, ewPtr); if (client == NULL) { @@ -1294,7 +1305,7 @@ static void EmbWinDelayedUnmap( ClientData clientData) /* Token for the window to be unmapped. */ { - TkTextEmbWindowClient *client = (TkTextEmbWindowClient*) clientData; + TkTextEmbWindowClient *client = clientData; if (!client->displayed && (client->tkwin != NULL)) { if (client->textPtr->tkwin != Tk_Parent(client->tkwin)) { @@ -1342,7 +1353,7 @@ TkTextWindowIndex( return 0; } - ewPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr); + ewPtr = Tcl_GetHashValue(hPtr); indexPtr->tree = textPtr->sharedTextPtr->tree; indexPtr->linePtr = ewPtr->body.ew.linePtr; indexPtr->byteIndex = TkTextSegToOffset(ewPtr, indexPtr->linePtr); @@ -1373,7 +1384,7 @@ TkTextWindowIndex( *-------------------------------------------------------------- */ -static TkTextEmbWindowClient* +static TkTextEmbWindowClient * EmbWinGetClient( const TkText *textPtr, /* Information about text widget. */ TkTextSegment *ewPtr) /* Segment containing embedded window. */ diff --git a/generic/tkTrig.c b/generic/tkTrig.c index d7439b3..a2bf456 100644 --- a/generic/tkTrig.c +++ b/generic/tkTrig.c @@ -12,7 +12,6 @@ * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ -#include <stdio.h> #include "tkInt.h" #include "tkCanvas.h" @@ -20,9 +19,6 @@ #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #undef MAX #define MAX(a,b) (((a) > (b)) ? (a) : (b)) -#ifndef PI -# define PI 3.14159265358979323846 -#endif /* PI */ /* *-------------------------------------------------------------- @@ -755,7 +751,7 @@ TkOvalToPoint( int TkOvalToArea( - register double *ovalPtr, /* Points to coordinates definining the + register double *ovalPtr, /* Points to coordinates defining the * bounding rectangle for the oval: x1, y1, * x2, y2. X1 must be less than x2 and y1 less * than y2. */ @@ -1379,7 +1375,7 @@ TkMakeBezierPostscript( int closed, i; int numCoords = numPoints*2; double control[8]; - char buffer[200]; + Tcl_Obj *psObj; /* * If the curve is a closed one then generate a special spline that spans @@ -1398,7 +1394,9 @@ TkMakeBezierPostscript( control[5] = 0.833*pointPtr[1] + 0.167*pointPtr[3]; control[6] = 0.5*pointPtr[0] + 0.5*pointPtr[2]; control[7] = 0.5*pointPtr[1] + 0.5*pointPtr[3]; - sprintf(buffer, "%.15g %.15g moveto\n%.15g %.15g %.15g %.15g %.15g %.15g curveto\n", + psObj = Tcl_ObjPrintf( + "%.15g %.15g moveto\n" + "%.15g %.15g %.15g %.15g %.15g %.15g curveto\n", control[0], Tk_CanvasPsY(canvas, control[1]), control[2], Tk_CanvasPsY(canvas, control[3]), control[4], Tk_CanvasPsY(canvas, control[5]), @@ -1407,10 +1405,9 @@ TkMakeBezierPostscript( closed = 0; control[6] = pointPtr[0]; control[7] = pointPtr[1]; - sprintf(buffer, "%.15g %.15g moveto\n", + psObj = Tcl_ObjPrintf("%.15g %.15g moveto\n", control[6], Tk_CanvasPsY(canvas, control[7])); } - Tcl_AppendResult(interp, buffer, NULL); /* * Cycle through all the remaining points in the curve, generating a curve @@ -1436,12 +1433,15 @@ TkMakeBezierPostscript( control[4] = 0.333*control[6] + 0.667*pointPtr[0]; control[5] = 0.333*control[7] + 0.667*pointPtr[1]; - sprintf(buffer, "%.15g %.15g %.15g %.15g %.15g %.15g curveto\n", + Tcl_AppendPrintfToObj(psObj, + "%.15g %.15g %.15g %.15g %.15g %.15g curveto\n", control[2], Tk_CanvasPsY(canvas, control[3]), control[4], Tk_CanvasPsY(canvas, control[5]), control[6], Tk_CanvasPsY(canvas, control[7])); - Tcl_AppendResult(interp, buffer, NULL); } + + Tcl_AppendObjToObj(Tcl_GetObjResult(interp), psObj); + Tcl_DecrRefCount(psObj); } /* @@ -1476,15 +1476,14 @@ TkMakeRawCurvePostscript( { int i; double *segPtr; - char buffer[200]; + Tcl_Obj *psObj; /* * Put the first point into the path. */ - sprintf(buffer, "%.15g %.15g moveto\n", + psObj = Tcl_ObjPrintf("%.15g %.15g moveto\n", pointPtr[0], Tk_CanvasPsY(canvas, pointPtr[1])); - Tcl_AppendResult(interp, buffer, NULL); /* * Loop through all the remaining points in the curve, generating a @@ -1499,19 +1498,19 @@ TkMakeRawCurvePostscript( * neighbouring knots, so this segment is just a straight line. */ - sprintf(buffer, "%.15g %.15g lineto\n", + Tcl_AppendPrintfToObj(psObj, "%.15g %.15g lineto\n", segPtr[6], Tk_CanvasPsY(canvas, segPtr[7])); } else { /* * This is a generic Bezier curve segment. */ - sprintf(buffer, "%.15g %.15g %.15g %.15g %.15g %.15g curveto\n", + Tcl_AppendPrintfToObj(psObj, + "%.15g %.15g %.15g %.15g %.15g %.15g curveto\n", segPtr[2], Tk_CanvasPsY(canvas, segPtr[3]), segPtr[4], Tk_CanvasPsY(canvas, segPtr[5]), segPtr[6], Tk_CanvasPsY(canvas, segPtr[7])); } - Tcl_AppendResult(interp, buffer, NULL); } /* @@ -1536,20 +1535,23 @@ TkMakeRawCurvePostscript( * Straight line. */ - sprintf(buffer, "%.15g %.15g lineto\n", + Tcl_AppendPrintfToObj(psObj, "%.15g %.15g lineto\n", control[6], Tk_CanvasPsY(canvas, control[7])); } else { /* * Bezier curve segment. */ - sprintf(buffer, "%.15g %.15g %.15g %.15g %.15g %.15g curveto\n", + Tcl_AppendPrintfToObj(psObj, + "%.15g %.15g %.15g %.15g %.15g %.15g curveto\n", control[2], Tk_CanvasPsY(canvas, control[3]), control[4], Tk_CanvasPsY(canvas, control[5]), control[6], Tk_CanvasPsY(canvas, control[7])); } - Tcl_AppendResult(interp, buffer, NULL); } + + Tcl_AppendObjToObj(Tcl_GetObjResult(interp), psObj); + Tcl_DecrRefCount(psObj); } /* diff --git a/generic/tkUndo.c b/generic/tkUndo.c index bf2ed7c..c66905d 100644 --- a/generic/tkUndo.c +++ b/generic/tkUndo.c @@ -94,7 +94,7 @@ TkUndoInsertSeparator( TkUndoAtom *separator; if (*stack!=NULL && (*stack)->type!=TK_UNDO_SEPARATOR) { - separator = (TkUndoAtom *) ckalloc(sizeof(TkUndoAtom)); + separator = ckalloc(sizeof(TkUndoAtom)); separator->type = TK_UNDO_SEPARATOR; TkUndoPushStack(stack,separator); return 1; @@ -135,7 +135,7 @@ TkUndoClearStack( if (sub->action != NULL) { Tcl_DecrRefCount(sub->action); } - ckfree((char *)sub); + ckfree(sub); sub = next; } @@ -146,11 +146,11 @@ TkUndoClearStack( if (sub->action != NULL) { Tcl_DecrRefCount(sub->action); } - ckfree((char *)sub); + ckfree(sub); sub = next; } } - ckfree((char *)elem); + ckfree(elem); } *stack = NULL; } @@ -181,7 +181,7 @@ TkUndoPushAction( { TkUndoAtom *atom; - atom = (TkUndoAtom *) ckalloc(sizeof(TkUndoAtom)); + atom = ckalloc(sizeof(TkUndoAtom)); atom->type = TK_UNDO_ACTION; atom->apply = apply; atom->revert = revert; @@ -237,7 +237,7 @@ TkUndoMakeCmdSubAtom( Tcl_Panic("NULL command and actionScript in TkUndoMakeCmdSubAtom"); } - atom = (TkUndoSubAtom *) ckalloc(sizeof(TkUndoSubAtom)); + atom = ckalloc(sizeof(TkUndoSubAtom)); atom->command = command; atom->funcPtr = NULL; atom->clientData = NULL; @@ -299,7 +299,7 @@ TkUndoMakeSubAtom( Tcl_Panic("NULL funcPtr in TkUndoMakeSubAtom"); } - atom = (TkUndoSubAtom *) ckalloc(sizeof(TkUndoSubAtom)); + atom = ckalloc(sizeof(TkUndoSubAtom)); atom->command = NULL; atom->funcPtr = funcPtr; atom->clientData = clientData; @@ -341,7 +341,7 @@ TkUndoInitStack( { TkUndoRedoStack *stack; /* An Undo/Redo stack */ - stack = (TkUndoRedoStack *) ckalloc(sizeof(TkUndoRedoStack)); + stack = ckalloc(sizeof(TkUndoRedoStack)); stack->undoStack = NULL; stack->redoStack = NULL; stack->interp = interp; @@ -353,7 +353,7 @@ TkUndoInitStack( /* *---------------------------------------------------------------------- * - * TkUndoSetDepth -- + * TkUndoSetMaxDepth -- * * Set the maximum depth of stack. * @@ -368,7 +368,7 @@ TkUndoInitStack( */ void -TkUndoSetDepth( +TkUndoSetMaxDepth( TkUndoRedoStack *stack, /* An Undo/Redo stack */ int maxdepth) /* The maximum stack depth */ { @@ -392,6 +392,7 @@ TkUndoSetDepth( prevelem = elem; elem = elem->next; } + CLANG_ASSERT(prevelem); prevelem->next = NULL; while (elem != NULL) { prevelem = elem; @@ -403,7 +404,7 @@ TkUndoSetDepth( if (sub->action != NULL) { Tcl_DecrRefCount(sub->action); } - ckfree((char *)sub); + ckfree(sub); sub = next; } sub = elem->revert; @@ -413,12 +414,12 @@ TkUndoSetDepth( if (sub->action != NULL) { Tcl_DecrRefCount(sub->action); } - ckfree((char *)sub); + ckfree(sub); sub = next; } } elem = elem->next; - ckfree((char *) prevelem); + ckfree(prevelem); } stack->depth = stack->maxdepth; } @@ -471,7 +472,53 @@ TkUndoFreeStack( TkUndoRedoStack *stack) /* An Undo/Redo stack */ { TkUndoClearStacks(stack); - ckfree((char *) stack); + ckfree(stack); +} + +/* + *---------------------------------------------------------------------- + * + * TkUndoCanRedo -- + * + * Returns true if redo is possible, i.e. if the redo stack is not empty. + * + * Results: + * A boolean. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +TkUndoCanRedo( + TkUndoRedoStack *stack) /* An Undo/Redo stack */ +{ + return stack->redoStack != NULL; +} + +/* + *---------------------------------------------------------------------- + * + * TkUndoCanUndo -- + * + * Returns true if undo is possible, i.e. if the undo stack is not empty. + * + * Results: + * A boolean. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +TkUndoCanUndo( + TkUndoRedoStack *stack) /* An Undo/Redo stack */ +{ + return stack->undoStack != NULL; } /* @@ -497,7 +544,7 @@ TkUndoInsertUndoSeparator( { if (TkUndoInsertSeparator(&stack->undoStack)) { stack->depth++; - TkUndoSetDepth(stack, stack->maxdepth); + TkUndoSetMaxDepth(stack, stack->maxdepth); } } @@ -540,7 +587,7 @@ TkUndoRevert( } if (elem->type == TK_UNDO_SEPARATOR) { - ckfree((char *) elem); + ckfree(elem); elem = TkUndoPopStack(&stack->undoStack); } @@ -602,7 +649,7 @@ TkUndoApply( } if (elem->type == TK_UNDO_SEPARATOR) { - ckfree((char *) elem); + ckfree(elem); elem = TkUndoPopStack(&stack->redoStack); } @@ -654,7 +701,7 @@ EvaluateActionList( while (action != NULL) { if (action->funcPtr != NULL) { - result = (*action->funcPtr)(interp, action->clientData, + result = action->funcPtr(interp, action->clientData, action->action); } else if (action->command != NULL) { Tcl_Obj *cmdNameObj, *evalObj; diff --git a/generic/tkUndo.h b/generic/tkUndo.h index b0e2db0..490ede9 100644 --- a/generic/tkUndo.h +++ b/generic/tkUndo.h @@ -16,13 +16,8 @@ #include "tkInt.h" #endif -#ifdef BUILD_tk -# undef TCL_STORAGE_CLASS -# define TCL_STORAGE_CLASS DLLEXPORT -#endif - /* - * Enum definining the types used in an undo stack. + * Enum defining the types used in an undo stack. */ typedef enum { @@ -101,9 +96,11 @@ MODULE_SCOPE void TkUndoClearStack(TkUndoAtom **stack); */ MODULE_SCOPE TkUndoRedoStack *TkUndoInitStack(Tcl_Interp *interp, int maxdepth); -MODULE_SCOPE void TkUndoSetDepth(TkUndoRedoStack *stack, int maxdepth); +MODULE_SCOPE void TkUndoSetMaxDepth(TkUndoRedoStack *stack, int maxdepth); MODULE_SCOPE void TkUndoClearStacks(TkUndoRedoStack *stack); MODULE_SCOPE void TkUndoFreeStack(TkUndoRedoStack *stack); +MODULE_SCOPE int TkUndoCanRedo(TkUndoRedoStack *stack); +MODULE_SCOPE int TkUndoCanUndo(TkUndoRedoStack *stack); MODULE_SCOPE void TkUndoInsertUndoSeparator(TkUndoRedoStack *stack); MODULE_SCOPE TkUndoSubAtom *TkUndoMakeCmdSubAtom(Tcl_Command command, Tcl_Obj *actionScript, TkUndoSubAtom *subAtomList); @@ -115,7 +112,4 @@ MODULE_SCOPE void TkUndoPushAction(TkUndoRedoStack *stack, MODULE_SCOPE int TkUndoRevert(TkUndoRedoStack *stack); MODULE_SCOPE int TkUndoApply(TkUndoRedoStack *stack); -# undef TCL_STORAGE_CLASS -# define TCL_STORAGE_CLASS DLLIMPORT - #endif /* _TKUNDO */ diff --git a/generic/tkUtil.c b/generic/tkUtil.c index bfa5d5c..1942975 100644 --- a/generic/tkUtil.c +++ b/generic/tkUtil.c @@ -18,7 +18,7 @@ * object, used for quickly finding a mapping in a TkStateMap. */ -Tcl_ObjType tkStateKeyObjType = { +const Tcl_ObjType tkStateKeyObjType = { "statekey", /* name */ NULL, /* freeIntRepProc */ NULL, /* dupIntRepProc */ @@ -56,10 +56,11 @@ TkStateParseProc( int c; int flags = PTR2INT(clientData); size_t length; + Tcl_Obj *msgObj; register Tk_State *statePtr = (Tk_State *) (widgRec + offset); - if(value == NULL || *value == 0) { + if (value == NULL || *value == 0) { *statePtr = TK_STATE_NULL; return TCL_OK; } @@ -84,18 +85,20 @@ TkStateParseProc( return TCL_OK; } - Tcl_AppendResult(interp, "bad ", (flags&4)?"-default" : "state", - " value \"", value, "\": must be normal", NULL); - if (flags&1) { - Tcl_AppendResult(interp, ", active", NULL); + msgObj = Tcl_ObjPrintf("bad %s value \"%s\": must be normal", + ((flags & 4) ? "-default" : "state"), value); + if (flags & 1) { + Tcl_AppendToObj(msgObj, ", active", -1); } - if (flags&2) { - Tcl_AppendResult(interp, ", hidden", NULL); + if (flags & 2) { + Tcl_AppendToObj(msgObj, ", hidden", -1); } - if (flags&3) { - Tcl_AppendResult(interp, ",", NULL); + if (flags & 3) { + Tcl_AppendToObj(msgObj, ",", -1); } - Tcl_AppendResult(interp, " or disabled", NULL); + Tcl_AppendToObj(msgObj, " or disabled", -1); + Tcl_SetObjResult(interp, msgObj); + Tcl_SetErrorCode(interp, "TK", "VALUE", "STATE", NULL); *statePtr = TK_STATE_NORMAL; return TCL_ERROR; } @@ -121,7 +124,7 @@ TkStateParseProc( *-------------------------------------------------------------- */ -char * +const char * TkStatePrintProc( ClientData clientData, /* Ignored. */ Tk_Window tkwin, /* Window containing canvas widget. */ @@ -179,7 +182,7 @@ TkOrientParseProc( register int *orientPtr = (int *) (widgRec + offset); - if(value == NULL || *value == 0) { + if (value == NULL || *value == 0) { *orientPtr = 0; return TCL_OK; } @@ -195,8 +198,10 @@ TkOrientParseProc( *orientPtr = 1; return TCL_OK; } - Tcl_AppendResult(interp, "bad orientation \"", value, - "\": must be vertical or horizontal", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad orientation \"%s\": must be vertical or horizontal", + value)); + Tcl_SetErrorCode(interp, "TK", "VALUE", "ORIENTATION", NULL); *orientPtr = 0; return TCL_ERROR; } @@ -222,7 +227,7 @@ TkOrientParseProc( *-------------------------------------------------------------- */ -char * +const char * TkOrientPrintProc( ClientData clientData, /* Ignored. */ Tk_Window tkwin, /* Window containing canvas widget. */ @@ -265,6 +270,7 @@ TkOffsetParseProc( Tk_TSOffset tsoffset; const char *q, *p; int result; + Tcl_Obj *msgObj; if ((value == NULL) || (*value == 0)) { tsoffset.flags = TK_OFFSET_CENTER|TK_OFFSET_MIDDLE; @@ -273,7 +279,7 @@ TkOffsetParseProc( tsoffset.flags = 0; p = value; - switch(value[0]) { + switch (value[0]) { case '#': if (PTR2INT(clientData) & TK_OFFSET_RELATIVE) { tsoffset.flags = TK_OFFSET_RELATIVE; @@ -336,7 +342,13 @@ TkOffsetParseProc( tsoffset.flags = TK_OFFSET_CENTER|TK_OFFSET_MIDDLE; goto goodTSOffset; } - if ((q = strchr(p,',')) == NULL) { + + /* + * Check for an extra offset. + */ + + q = strchr(p, ','); + if (q == NULL) { if (PTR2INT(clientData) & TK_OFFSET_INDEX) { if (Tcl_GetInt(interp, (char *) p, &tsoffset.flags) != TCL_OK) { Tcl_ResetResult(interp); @@ -347,6 +359,7 @@ TkOffsetParseProc( } goto badTSOffset; } + *((char *) q) = 0; result = Tk_GetPixels(interp, tkwin, (char *) p, &tsoffset.xoffset); *((char *) q) = ','; @@ -357,27 +370,28 @@ TkOffsetParseProc( return TCL_ERROR; } - goodTSOffset: /* * Below is a hack to allow the stipple/tile offset to be stored in the * internal tile structure. Most of the times, offsetPtr is a pointer to * an already existing tile structure. However if this structure is not - * already created, we must do it with Tk_GetTile()!!!!; + * already created, we must do it with Tk_GetTile()!!!! */ + goodTSOffset: memcpy(offsetPtr, &tsoffset, sizeof(Tk_TSOffset)); return TCL_OK; badTSOffset: - Tcl_AppendResult(interp, "bad offset \"", value, - "\": expected \"x,y\"", NULL); + msgObj = Tcl_ObjPrintf("bad offset \"%s\": expected \"x,y\"", value); if (PTR2INT(clientData) & TK_OFFSET_RELATIVE) { - Tcl_AppendResult(interp, ", \"#x,y\"", NULL); + Tcl_AppendToObj(msgObj, ", \"#x,y\"", -1); } if (PTR2INT(clientData) & TK_OFFSET_INDEX) { - Tcl_AppendResult(interp, ", <index>", NULL); + Tcl_AppendToObj(msgObj, ", <index>", -1); } - Tcl_AppendResult(interp, ", n, ne, e, se, s, sw, w, nw, or center", NULL); + Tcl_AppendToObj(msgObj, ", n, ne, e, se, s, sw, w, nw, or center", -1); + Tcl_SetObjResult(interp, msgObj); + Tcl_SetErrorCode(interp, "TK", "VALUE", "OFFSET", NULL); return TCL_ERROR; } @@ -394,7 +408,7 @@ TkOffsetParseProc( *---------------------------------------------------------------------- */ -char * +const char * TkOffsetPrintProc( ClientData clientData, /* not used */ Tk_Window tkwin, /* not used */ @@ -409,7 +423,7 @@ TkOffsetPrintProc( if (offsetPtr->flags >= INT_MAX) { return "end"; } - p = (char *) ckalloc(32); + p = ckalloc(32); sprintf(p, "%d", offsetPtr->flags & ~TK_OFFSET_INDEX); *freeProcPtr = TCL_DYNAMIC; return p; @@ -439,7 +453,7 @@ TkOffsetPrintProc( return "se"; } } - q = p = (char *) ckalloc(32); + q = p = ckalloc(32); if (offsetPtr->flags & TK_OFFSET_RELATIVE) { *q++ = '#'; } @@ -461,7 +475,7 @@ TkOffsetPrintProc( int TkPixelParseProc( ClientData clientData, /* If non-NULL, negative values are allowed as - * well */ + * well. */ Tcl_Interp *interp, /* Interpreter to send results back to */ Tk_Window tkwin, /* Window on same display as tile */ const char *value, /* Name of image */ @@ -474,7 +488,9 @@ TkPixelParseProc( result = TkGetDoublePixels(interp, tkwin, value, doublePtr); if ((result == TCL_OK) && (clientData == NULL) && (*doublePtr < 0.0)) { - Tcl_AppendResult(interp, "bad screen distance \"", value, "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad screen distance \"%s\"", value)); + Tcl_SetErrorCode(interp, "TK", "VALUE", "PIXELS", NULL); return TCL_ERROR; } return result; @@ -493,7 +509,7 @@ TkPixelParseProc( *---------------------------------------------------------------------- */ -char * +const char * TkPixelPrintProc( ClientData clientData, /* not used */ Tk_Window tkwin, /* not used */ @@ -502,7 +518,7 @@ TkPixelPrintProc( Tcl_FreeProc **freeProcPtr) /* not used */ { double *doublePtr = (double *) (widgRec + offset); - char *p = (char *) ckalloc(24); + char *p = ckalloc(24); Tcl_PrintDouble(NULL, *doublePtr, p); *freeProcPtr = TCL_DYNAMIC; @@ -637,8 +653,10 @@ Tk_GetScrollInfo( if ((c == 'm') && (strncmp(argv[2], "moveto", length) == 0)) { if (argc != 4) { - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " ", argv[1], " moveto fraction\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "wrong # args: should be \"%s %s %s\"", + argv[0], argv[1], "moveto fraction")); + Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL); return TK_SCROLL_ERROR; } if (Tcl_GetDouble(interp, argv[3], dblPtr) != TCL_OK) { @@ -648,8 +666,10 @@ Tk_GetScrollInfo( } else if ((c == 's') && (strncmp(argv[2], "scroll", length) == 0)) { if (argc != 5) { - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " ", argv[1], " scroll number units|pages\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "wrong # args: should be \"%s %s %s\"", + argv[0], argv[1], "scroll number units|pages")); + Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL); return TK_SCROLL_ERROR; } if (Tcl_GetInt(interp, argv[3], intPtr) != TCL_OK) { @@ -663,12 +683,15 @@ Tk_GetScrollInfo( return TK_SCROLL_UNITS; } - Tcl_AppendResult(interp, "bad argument \"", argv[4], - "\": must be units or pages", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad argument \"%s\": must be units or pages", argv[4])); + Tcl_SetErrorCode(interp, "TK", "VALUE", "SCROLL_UNITS", NULL); return TK_SCROLL_ERROR; } - Tcl_AppendResult(interp, "unknown option \"", argv[2], - "\": must be moveto or scroll", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "unknown option \"%s\": must be moveto or scroll", argv[2])); + Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "option", argv[2], + NULL); return TK_SCROLL_ERROR; } @@ -706,12 +729,11 @@ Tk_GetScrollInfoObj( int *intPtr) /* Filled in with number of pages or lines to * scroll, if any. */ { - int length; - const char *arg; - - arg = Tcl_GetStringFromObj(objv[2], &length); + const char *arg = Tcl_GetString(objv[2]); + size_t length = objv[2]->length; -#define ArgPfxEq(str) ((arg[0]==str[0])&&!strncmp(arg,str,(unsigned)length)) +#define ArgPfxEq(str) \ + ((arg[0] == str[0]) && !strncmp(arg, str, length)) if (ArgPfxEq("moveto")) { if (objc != 4) { @@ -731,19 +753,22 @@ Tk_GetScrollInfoObj( return TK_SCROLL_ERROR; } - arg = Tcl_GetStringFromObj(objv[4], &length); + arg = Tcl_GetString(objv[4]); + length = objv[4]->length; if (ArgPfxEq("pages")) { return TK_SCROLL_PAGES; } else if (ArgPfxEq("units")) { return TK_SCROLL_UNITS; } - Tcl_AppendResult(interp, "bad argument \"", arg, - "\": must be units or pages", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad argument \"%s\": must be units or pages", arg)); + Tcl_SetErrorCode(interp, "TK", "VALUE", "SCROLL_UNITS", NULL); return TK_SCROLL_ERROR; } - Tcl_AppendResult(interp, "unknown option \"", arg, - "\": must be moveto or scroll", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "unknown option \"%s\": must be moveto or scroll", arg)); + Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "option", arg, NULL); return TK_SCROLL_ERROR; } @@ -848,14 +873,14 @@ TkComputeAnchor( *--------------------------------------------------------------------------- */ -char * +const char * TkFindStateString( const TkStateMap *mapPtr, /* The state table. */ int numKey) /* The key to try to find in the table. */ { for (; mapPtr->strKey!=NULL ; mapPtr++) { if (numKey == mapPtr->numKey) { - return (char *) mapPtr->strKey; + return mapPtr->strKey; } } return NULL; @@ -907,14 +932,17 @@ TkFindStateNum( */ if (interp != NULL) { + Tcl_Obj *msgObj; + mPtr = mapPtr; - Tcl_AppendResult(interp, "bad ", option, " value \"", strKey, - "\": must be ", mPtr->strKey, NULL); + msgObj = Tcl_ObjPrintf("bad %s value \"%s\": must be %s", + option, strKey, mPtr->strKey); for (mPtr++; mPtr->strKey != NULL; mPtr++) { - Tcl_AppendResult(interp, - ((mPtr[1].strKey != NULL) ? ", " : ", or "), - mPtr->strKey, NULL); + Tcl_AppendPrintfToObj(msgObj, ",%s %s", + ((mPtr[1].strKey != NULL) ? "" : "or "), mPtr->strKey); } + Tcl_SetObjResult(interp, msgObj); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", option, strKey, NULL); } return mPtr->numKey; } @@ -943,12 +971,12 @@ TkFindStateNumObj( * Not there. Look in the state map. */ - key = Tcl_GetStringFromObj(keyPtr, NULL); + key = Tcl_GetString(keyPtr); for (mPtr = mapPtr; mPtr->strKey != NULL; mPtr++) { if (strcmp(key, mPtr->strKey) == 0) { typePtr = keyPtr->typePtr; if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) { - (*typePtr->freeIntRepProc)(keyPtr); + typePtr->freeIntRepProc(keyPtr); } keyPtr->internalRep.twoPtrValue.ptr1 = (void *) mapPtr; keyPtr->internalRep.twoPtrValue.ptr2 = INT2PTR(mPtr->numKey); @@ -963,19 +991,288 @@ TkFindStateNumObj( */ if (interp != NULL) { + Tcl_Obj *msgObj; + mPtr = mapPtr; - Tcl_AppendResult(interp, "bad ", Tcl_GetString(optionPtr), - " value \"", key, "\": must be ", mPtr->strKey, NULL); + msgObj = Tcl_ObjPrintf( + "bad %s value \"%s\": must be %s", + Tcl_GetString(optionPtr), key, mPtr->strKey); for (mPtr++; mPtr->strKey != NULL; mPtr++) { - Tcl_AppendResult(interp, - ((mPtr[1].strKey != NULL) ? ", " : ", or "), - mPtr->strKey, NULL); + Tcl_AppendPrintfToObj(msgObj, ",%s %s", + ((mPtr[1].strKey != NULL) ? "" : " or"), mPtr->strKey); } + Tcl_SetObjResult(interp, msgObj); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", Tcl_GetString(optionPtr), + key, NULL); } return mPtr->numKey; } /* + * ---------------------------------------------------------------------- + * + * TkBackgroundEvalObjv -- + * + * Evaluate a command while ensuring that we do not affect the + * interpreters state. This is important when evaluating script + * during background tasks. + * + * Results: + * A standard Tcl result code. + * + * Side Effects: + * The interpreters variables and code may be modified by the script + * but the result will not be modified. + * + * ---------------------------------------------------------------------- + */ + +int +TkBackgroundEvalObjv( + Tcl_Interp *interp, + int objc, + Tcl_Obj *const *objv, + int flags) +{ + Tcl_InterpState state; + int n, r = TCL_OK; + + /* + * Record the state of the interpreter. + */ + + Tcl_Preserve(interp); + state = Tcl_SaveInterpState(interp, TCL_OK); + + /* + * Evaluate the command and handle any error. + */ + + for (n = 0; n < objc; ++n) { + Tcl_IncrRefCount(objv[n]); + } + r = Tcl_EvalObjv(interp, objc, objv, flags); + for (n = 0; n < objc; ++n) { + Tcl_DecrRefCount(objv[n]); + } + if (r == TCL_ERROR) { + Tcl_AddErrorInfo(interp, "\n (background event handler)"); + Tcl_BackgroundException(interp, r); + } + + /* + * Restore the state of the interpreter. + */ + + (void) Tcl_RestoreInterpState(interp, state); + Tcl_Release(interp); + + return r; +} + +/* + *---------------------------------------------------------------------- + * + * TkMakeEnsemble -- + * + * Create an ensemble from a table of implementation commands. This may + * be called recursively to create sub-ensembles. + * + * Results: + * Handle for the ensemble, or NULL if creation of it fails. + * + *---------------------------------------------------------------------- + */ + +Tcl_Command +TkMakeEnsemble( + Tcl_Interp *interp, + const char *namespace, + const char *name, + ClientData clientData, + const TkEnsemble map[]) +{ + Tcl_Namespace *namespacePtr = NULL; + Tcl_Command ensemble = NULL; + Tcl_Obj *dictObj = NULL, *nameObj; + Tcl_DString ds; + int i; + + if (map == NULL) { + return NULL; + } + + Tcl_DStringInit(&ds); + + namespacePtr = Tcl_FindNamespace(interp, namespace, NULL, 0); + if (namespacePtr == NULL) { + namespacePtr = Tcl_CreateNamespace(interp, namespace, NULL, NULL); + if (namespacePtr == NULL) { + Tcl_Panic("failed to create namespace \"%s\"", namespace); + } + } + + nameObj = Tcl_NewStringObj(name, -1); + ensemble = Tcl_FindEnsemble(interp, nameObj, 0); + Tcl_DecrRefCount(nameObj); + if (ensemble == NULL) { + ensemble = Tcl_CreateEnsemble(interp, name, namespacePtr, + TCL_ENSEMBLE_PREFIX); + if (ensemble == NULL) { + Tcl_Panic("failed to create ensemble \"%s\"", name); + } + } + + Tcl_DStringSetLength(&ds, 0); + Tcl_DStringAppend(&ds, namespace, -1); + if (!(strlen(namespace) == 2 && namespace[1] == ':')) { + Tcl_DStringAppend(&ds, "::", -1); + } + Tcl_DStringAppend(&ds, name, -1); + + dictObj = Tcl_NewObj(); + for (i = 0; map[i].name != NULL ; ++i) { + Tcl_Obj *nameObj, *fqdnObj; + + nameObj = Tcl_NewStringObj(map[i].name, -1); + fqdnObj = Tcl_NewStringObj(Tcl_DStringValue(&ds), + Tcl_DStringLength(&ds)); + Tcl_AppendStringsToObj(fqdnObj, "::", map[i].name, NULL); + Tcl_DictObjPut(NULL, dictObj, nameObj, fqdnObj); + if (map[i].proc) { + Tcl_CreateObjCommand(interp, Tcl_GetString(fqdnObj), + map[i].proc, clientData, NULL); + } else if (map[i].subensemble) { + TkMakeEnsemble(interp, Tcl_DStringValue(&ds), + map[i].name, clientData, map[i].subensemble); + } + } + + if (ensemble) { + Tcl_SetEnsembleMappingDict(interp, ensemble, dictObj); + } + + Tcl_DStringFree(&ds); + return ensemble; +} + +/* + *---------------------------------------------------------------------- + * + * TkSendVirtualEvent -- + * + * Send a virtual event notification to the specified target window. + * Equivalent to: + * "event generate $target <<$eventName>> -data $detail" + * + * Note that we use Tk_QueueWindowEvent, not Tk_HandleEvent, so this + * routine does not reenter the interpreter. + * + *---------------------------------------------------------------------- + */ + +void +TkSendVirtualEvent( + Tk_Window target, + const char *eventName, + Tcl_Obj *detail) +{ + union {XEvent general; XVirtualEvent virtual;} event; + + memset(&event, 0, sizeof(event)); + event.general.xany.type = VirtualEvent; + event.general.xany.serial = NextRequest(Tk_Display(target)); + event.general.xany.send_event = False; + event.general.xany.window = Tk_WindowId(target); + event.general.xany.display = Tk_Display(target); + event.virtual.name = Tk_GetUid(eventName); + if (detail != NULL) { + event.virtual.user_data = detail; + } + + 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 ((((unsigned)(ch - 0x10000) <= 0xFFFFF)) && (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 * c-basic-offset: 4 diff --git a/generic/tkVisual.c b/generic/tkVisual.c index ec8be11..8b0c155 100644 --- a/generic/tkVisual.c +++ b/generic/tkVisual.c @@ -20,12 +20,12 @@ */ typedef struct VisualDictionary { - char *name; /* Textual name of class. */ + const char *name; /* Textual name of class. */ int minLength; /* Minimum # characters that must be specified * for an unambiguous match. */ int class; /* X symbol for class. */ } VisualDictionary; -static VisualDictionary visualNames[] = { +static const VisualDictionary visualNames[] = { {"best", 1, 0}, {"directcolor", 2, DirectColor}, {"grayscale", 1, GrayScale}, @@ -86,7 +86,7 @@ Visual * Tk_GetVisual( Tcl_Interp *interp, /* Interpreter to use for error reporting. */ Tk_Window tkwin, /* Window in which visual will be used. */ - CONST char *string, /* String describing visual. See manual entry + const char *string, /* String describing visual. See manual entry * for details. */ int *depthPtr, /* The depth of the returned visual is stored * here. */ @@ -101,8 +101,8 @@ Tk_GetVisual( Visual *visual; ptrdiff_t length; int c, numVisuals, prio, bestPrio, i; - CONST char *p; - VisualDictionary *dictPtr; + const char *p; + const VisualDictionary *dictPtr; TkColormap *cmapPtr; TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; @@ -173,9 +173,9 @@ Tk_GetVisual( */ if (Tcl_GetInt(interp, string, &visualId) == TCL_ERROR) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "bad X identifier for visual: \"", - string, "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad X identifier for visual: \"%s\"", string)); + Tcl_SetErrorCode(interp, "TK", "VALUE", "VISUALID", NULL); return NULL; } template.visualid = visualId; @@ -202,12 +202,16 @@ Tk_GetVisual( } } if (template.class == -1) { - Tcl_AppendResult(interp, "unknown or ambiguous visual name \"", - string, "\": class must be ", NULL); + Tcl_Obj *msgObj = Tcl_ObjPrintf( + "unknown or ambiguous visual name \"%s\": class must be ", + string); + for (dictPtr = visualNames; dictPtr->name != NULL; dictPtr++) { - Tcl_AppendResult(interp, dictPtr->name, ", ", NULL); + Tcl_AppendPrintfToObj(msgObj, "%s, ", dictPtr->name); } - Tcl_AppendResult(interp, "or default", NULL); + Tcl_AppendToObj(msgObj, "or default", -1); + Tcl_SetObjResult(interp, msgObj); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "VISUAL", string, NULL); return NULL; } while (isspace(UCHAR(*p))) { @@ -215,10 +219,8 @@ Tk_GetVisual( } if (*p == 0) { template.depth = 10000; - } else { - if (Tcl_GetInt(interp, p, &template.depth) != TCL_OK) { - return NULL; - } + } else if (Tcl_GetInt(interp, p, &template.depth) != TCL_OK) { + return NULL; } if (c == 'b') { mask = 0; @@ -237,8 +239,9 @@ Tk_GetVisual( visInfoList = XGetVisualInfo(Tk_Display(tkwin), mask, &template, &numVisuals); if (visInfoList == NULL) { - Tcl_SetResult(interp, "couldn't find an appropriate visual", - TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "couldn't find an appropriate visual", -1)); + Tcl_SetErrorCode(interp, "TK", "VISUAL", "INAPPROPRIATE", NULL); return NULL; } @@ -301,6 +304,7 @@ Tk_GetVisual( bestPtr = &visInfoList[i]; bestPrio = prio; } + CLANG_ASSERT(bestPtr); *depthPtr = bestPtr->depth; visual = bestPtr->visual; XFree((char *) visInfoList); @@ -324,7 +328,7 @@ Tk_GetVisual( goto done; } } - cmapPtr = (TkColormap *) ckalloc(sizeof(TkColormap)); + cmapPtr = ckalloc(sizeof(TkColormap)); cmapPtr->colormap = XCreateColormap(Tk_Display(tkwin), RootWindowOfScreen(Tk_Screen(tkwin)), visual, AllocNone); @@ -366,7 +370,7 @@ Colormap Tk_GetColormap( Tcl_Interp *interp, /* Interpreter to use for error reporting. */ Tk_Window tkwin, /* Window where colormap will be used. */ - CONST char *string) /* String that identifies colormap: either + const char *string) /* String that identifies colormap: either * "new" or the name of another window. */ { Colormap colormap; @@ -379,7 +383,7 @@ Tk_GetColormap( */ if (strcmp(string, "new") == 0) { - cmapPtr = (TkColormap *) ckalloc(sizeof(TkColormap)); + cmapPtr = ckalloc(sizeof(TkColormap)); cmapPtr->colormap = XCreateColormap(Tk_Display(tkwin), RootWindowOfScreen(Tk_Screen(tkwin)), Tk_Visual(tkwin), AllocNone); @@ -402,13 +406,15 @@ Tk_GetColormap( return None; } if (Tk_Screen(other) != Tk_Screen(tkwin)) { - Tcl_AppendResult(interp, "can't use colormap for ", string, - ": not on same screen", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't use colormap for %s: not on same screen", string)); + Tcl_SetErrorCode(interp, "TK", "COLORMAP", "SCREEN", NULL); return None; } if (Tk_Visual(other) != Tk_Visual(tkwin)) { - Tcl_AppendResult(interp, "can't use colormap for ", string, - ": incompatible visuals", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't use colormap for %s: incompatible visuals", string)); + Tcl_SetErrorCode(interp, "TK", "COLORMAP", "INCOMPATIBLE", NULL); return None; } colormap = Tk_Colormap(other); @@ -478,7 +484,7 @@ Tk_FreeColormap( } else { prevPtr->nextPtr = cmapPtr->nextPtr; } - ckfree((char *) cmapPtr); + ckfree(cmapPtr); } return; } diff --git a/generic/tkWindow.c b/generic/tkWindow.c index 1257e22..917d3bd 100644 --- a/generic/tkWindow.c +++ b/generic/tkWindow.c @@ -14,7 +14,7 @@ #include "tkInt.h" -#ifdef __WIN32__ +#ifdef _WIN32 #include "tkWinInt.h" #elif !defined(MAC_OSX_TK) #include "tkUnixInt.h" @@ -54,12 +54,6 @@ typedef struct ThreadSpecificData { static Tcl_ThreadDataKey dataKey; /* - * The Mutex below is used to lock access to the Tk_Uid structs above. - */ - -TCL_DECLARE_MUTEX(windowMutex) - -/* * Default values for "changes" and "atts" fields of TkWindows. Note that Tk * always requests all events for all windows, except StructureNotify events * on internal windows: these events are generated internally. @@ -97,12 +91,14 @@ static const XSetWindowAttributes defAtts= { #define ISSAFE 1 #define PASSMAINWINDOW 2 -#define NOOBJPROC 4 -#define WINMACONLY 8 +#define WINMACONLY 4 +#define USEINITPROC 8 +typedef int (TkInitProc)(Tcl_Interp *interp, ClientData clientData); typedef struct { - const char *name; /* Name of command. */ - Tcl_ObjCmdProc *objProc; /* Command's object- (or string-) based function. */ + const char *name; /* Name of command. */ + Tcl_ObjCmdProc *objProc; /* Command's object- (or string-) based + * function, or initProc. */ int flags; } TkCmd; @@ -125,10 +121,10 @@ static const TkCmd commands[] = { {"lower", Tk_LowerObjCmd, PASSMAINWINDOW|ISSAFE}, {"option", Tk_OptionObjCmd, PASSMAINWINDOW|ISSAFE}, {"pack", Tk_PackObjCmd, PASSMAINWINDOW|ISSAFE}, - {"place", Tk_PlaceObjCmd, ISSAFE}, + {"place", Tk_PlaceObjCmd, PASSMAINWINDOW|ISSAFE}, {"raise", Tk_RaiseObjCmd, PASSMAINWINDOW|ISSAFE}, {"selection", Tk_SelectionObjCmd, PASSMAINWINDOW}, - {"tk", Tk_TkObjCmd, PASSMAINWINDOW|ISSAFE}, + {"tk", (Tcl_ObjCmdProc *) TkInitTkCmd, USEINITPROC|PASSMAINWINDOW|ISSAFE}, {"tkwait", Tk_TkwaitObjCmd, PASSMAINWINDOW|ISSAFE}, {"update", Tk_UpdateObjCmd, PASSMAINWINDOW|ISSAFE}, {"winfo", Tk_WinfoObjCmd, PASSMAINWINDOW|ISSAFE}, @@ -146,12 +142,13 @@ static const TkCmd commands[] = { {"label", Tk_LabelObjCmd, ISSAFE}, {"labelframe", Tk_LabelframeObjCmd, ISSAFE}, {"listbox", Tk_ListboxObjCmd, ISSAFE}, + {"menu", Tk_MenuObjCmd, PASSMAINWINDOW}, {"menubutton", Tk_MenubuttonObjCmd, ISSAFE}, {"message", Tk_MessageObjCmd, ISSAFE}, {"panedwindow", Tk_PanedWindowObjCmd, ISSAFE}, {"radiobutton", Tk_RadiobuttonObjCmd, ISSAFE}, {"scale", Tk_ScaleObjCmd, ISSAFE}, - {"scrollbar", (Tcl_ObjCmdProc *) Tk_ScrollbarCmd, NOOBJPROC|PASSMAINWINDOW|ISSAFE}, + {"scrollbar", Tk_ScrollbarObjCmd, PASSMAINWINDOW|ISSAFE}, {"spinbox", Tk_SpinboxObjCmd, ISSAFE}, {"text", Tk_TextObjCmd, PASSMAINWINDOW|ISSAFE}, {"toplevel", Tk_ToplevelObjCmd, 0}, @@ -173,7 +170,7 @@ static const TkCmd commands[] = { {"::tk::panedwindow",Tk_PanedWindowObjCmd, ISSAFE}, {"::tk::radiobutton",Tk_RadiobuttonObjCmd, ISSAFE}, {"::tk::scale", Tk_ScaleObjCmd, ISSAFE}, - {"::tk::scrollbar", (Tcl_ObjCmdProc *) Tk_ScrollbarCmd, NOOBJPROC|PASSMAINWINDOW|ISSAFE}, + {"::tk::scrollbar", Tk_ScrollbarObjCmd, PASSMAINWINDOW|ISSAFE}, {"::tk::spinbox", Tk_SpinboxObjCmd, ISSAFE}, {"::tk::text", Tk_TextObjCmd, PASSMAINWINDOW|ISSAFE}, {"::tk::toplevel", Tk_ToplevelObjCmd, 0}, @@ -183,7 +180,7 @@ static const TkCmd commands[] = { * these commands differently (via the script library). */ -#if defined(__WIN32__) || defined(MAC_OSX_TK) +#if defined(_WIN32) || defined(MAC_OSX_TK) {"tk_chooseColor", Tk_ChooseColorObjCmd, PASSMAINWINDOW}, {"tk_chooseDirectory", Tk_ChooseDirectoryObjCmd,WINMACONLY|PASSMAINWINDOW}, {"tk_getOpenFile", Tk_GetOpenFileObjCmd, WINMACONLY|PASSMAINWINDOW}, @@ -195,7 +192,7 @@ static const TkCmd commands[] = { * Misc. */ -#if defined(MAC_OSX_TK) +#ifdef MAC_OSX_TK {"::tk::unsupported::MacWindowStyle", TkUnsupported1ObjCmd, PASSMAINWINDOW|ISSAFE}, #endif @@ -203,52 +200,18 @@ static const TkCmd commands[] = { }; /* - * The variables and table below are used to parse arguments from the "argv" - * variable in Tk_Init. - */ - -static int synchronize = 0; -static char *name = NULL; -static char *display = NULL; -static char *geometry = NULL; -static char *colormap = NULL; -static char *use = NULL; -static char *visual = NULL; -static int rest = 0; - -static Tk_ArgvInfo argTable[] = { - {"-colormap", TK_ARGV_STRING, NULL, (char *) &colormap, - "Colormap for main window"}, - {"-display", TK_ARGV_STRING, NULL, (char *) &display, - "Display to use"}, - {"-geometry", TK_ARGV_STRING, NULL, (char *) &geometry, - "Initial geometry for window"}, - {"-name", TK_ARGV_STRING, NULL, (char *) &name, - "Name to use for application"}, - {"-sync", TK_ARGV_CONSTANT, (char *) 1, (char *) &synchronize, - "Use synchronous mode for display server"}, - {"-visual", TK_ARGV_STRING, NULL, (char *) &visual, - "Visual for main window"}, - {"-use", TK_ARGV_STRING, NULL, (char *) &use, - "Id of window in which to embed application"}, - {"--", TK_ARGV_REST, (char *) 1, (char *) &rest, - "Pass all remaining arguments through to script"}, - {NULL, TK_ARGV_END, NULL, NULL, NULL} -}; - -/* * Forward declarations to functions defined later in this file: */ static Tk_Window CreateTopLevelWindow(Tcl_Interp *interp, - Tk_Window parent, CONST char *name, - CONST char *screenName, unsigned int flags); + Tk_Window parent, const char *name, + const char *screenName, unsigned int flags); static void DeleteWindowsExitProc(ClientData clientData); -static TkDisplay * GetScreen(Tcl_Interp *interp, CONST char *screenName, +static TkDisplay * GetScreen(Tcl_Interp *interp, const char *screenName, int *screenPtr); static int Initialize(Tcl_Interp *interp); static int NameWindow(Tcl_Interp *interp, TkWindow *winPtr, - TkWindow *parentPtr, CONST char *name); + TkWindow *parentPtr, const char *name); static void UnlinkWindow(TkWindow *winPtr); /* @@ -276,6 +239,8 @@ TkCloseDisplay( { TkClipCleanup(dispPtr); + TkpCancelWarp(dispPtr); + if (dispPtr->name != NULL) { ckfree(dispPtr->name); } @@ -288,11 +253,12 @@ TkCloseDisplay( if (dispPtr->errorPtr != NULL) { TkErrorHandler *errorPtr; + for (errorPtr = dispPtr->errorPtr; errorPtr != NULL; errorPtr = dispPtr->errorPtr) { dispPtr->errorPtr = errorPtr->nextPtr; - ckfree((char *) errorPtr); + ckfree(errorPtr); } } @@ -307,7 +273,7 @@ TkCloseDisplay( Tcl_DeleteHashTable(&dispPtr->winTable); - ckfree((char *) dispPtr); + ckfree(dispPtr); /* * There is more to clean up, we leave it at this for the time being. @@ -341,9 +307,9 @@ CreateTopLevelWindow( Tk_Window parent, /* Token for logical parent of new window * (used for naming, options, etc.). May be * NULL. */ - CONST char *name, /* Name for new window; if parent is non-NULL, + const char *name, /* Name for new window; if parent is non-NULL, * must be unique among parent's children. */ - CONST char *screenName, /* Name of screen on which to create window. + const char *screenName, /* Name of screen on which to create window. * NULL means use DISPLAY environment variable * to determine. Empty string means use * parent's screen, or DISPLAY if no @@ -353,7 +319,7 @@ CreateTopLevelWindow( register TkWindow *winPtr; register TkDisplay *dispPtr; int screenId; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (!tsdPtr->initialized) { @@ -371,6 +337,7 @@ CreateTopLevelWindow( */ Tk_CreatePhotoImageFormat(&tkImgFmtGIF); + Tk_CreatePhotoImageFormat(&tkImgFmtPNG); Tk_CreatePhotoImageFormat(&tkImgFmtPPM); } @@ -380,7 +347,7 @@ CreateTopLevelWindow( } else { dispPtr = GetScreen(interp, screenName, &screenId); if (dispPtr == NULL) { - return (Tk_Window) NULL; + return NULL; } } @@ -390,6 +357,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; /* @@ -413,7 +383,7 @@ CreateTopLevelWindow( if (parent != NULL) { if (NameWindow(interp, winPtr, (TkWindow *) parent, name) != TCL_OK) { Tk_DestroyWindow((Tk_Window) winPtr); - return (Tk_Window) NULL; + return NULL; } } TkWmNewWindow(winPtr); @@ -445,15 +415,15 @@ CreateTopLevelWindow( static TkDisplay * GetScreen( Tcl_Interp *interp, /* Place to leave error message. */ - CONST char *screenName, /* Name for screen. NULL or empty means use + const char *screenName, /* Name for screen. NULL or empty means use * DISPLAY envariable. */ int *screenPtr) /* Where to store screen number. */ { register TkDisplay *dispPtr; - CONST char *p; + const char *p; int screenId; size_t length; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* @@ -464,9 +434,9 @@ GetScreen( screenName = TkGetDefaultScreenName(interp, screenName); if (screenName == NULL) { - Tcl_SetResult(interp, - "no display name and no $DISPLAY environment variable", - TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "no display name and no $DISPLAY environment variable", -1)); + Tcl_SetErrorCode(interp, "TK", "NO_DISPLAY", NULL); return NULL; } length = strlen(screenName); @@ -494,9 +464,9 @@ GetScreen( dispPtr = TkpOpenDisplay(screenName); if (dispPtr == NULL) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "couldn't connect to display \"", - screenName, "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "couldn't connect to display \"%s\"", screenName)); + Tcl_SetErrorCode(interp, "TK", "DISPLAY", "CONNECT", NULL); return NULL; } dispPtr->nextPtr = tsdPtr->displayList; /* TkGetDisplayList(); */ @@ -505,7 +475,7 @@ GetScreen( dispPtr->lastEventTime = CurrentTime; dispPtr->bindInfoStale = 1; dispPtr->cursorFont = None; - dispPtr->warpWindow = None; + dispPtr->warpWindow = NULL; dispPtr->multipleAtom = None; /* @@ -517,11 +487,9 @@ GetScreen( Tcl_InitHashTable(&dispPtr->winTable, TCL_ONE_WORD_KEYS); - dispPtr->name = (char *) ckalloc((unsigned) (length+1)); + dispPtr->name = ckalloc(length + 1); strncpy(dispPtr->name, screenName, length); dispPtr->name[length] = '\0'; - - TkInitXId(dispPtr); break; } if ((strncmp(dispPtr->name, screenName, length) == 0) @@ -530,10 +498,9 @@ GetScreen( } } if (screenId >= ScreenCount(dispPtr->display)) { - char buf[32 + TCL_INTEGER_SPACE]; - - sprintf(buf, "bad screen number \"%d\"", screenId); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad screen number \"%d\"", screenId)); + Tcl_SetErrorCode(interp, "TK", "DISPLAY", "SCREEN_NUMBER", NULL); return NULL; } *screenPtr = screenId; @@ -563,7 +530,7 @@ TkGetDisplay( Display *display) /* X's display pointer */ { TkDisplay *dispPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); for (dispPtr = tsdPtr->displayList; dispPtr != NULL; @@ -596,7 +563,7 @@ TkGetDisplay( TkDisplay * TkGetDisplayList(void) { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); return tsdPtr->displayList; @@ -623,7 +590,7 @@ TkGetDisplayList(void) TkMainInfo * TkGetMainInfoList(void) { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); return tsdPtr->mainWindowList; @@ -653,9 +620,8 @@ TkAllocWindow( * inherit visual information. NULL means use * screen defaults instead of inheriting. */ { - register TkWindow *winPtr; + register TkWindow *winPtr = ckalloc(sizeof(TkWindow)); - winPtr = (TkWindow *) ckalloc(sizeof(TkWindow)); winPtr->display = dispPtr->display; winPtr->dispPtr = dispPtr; winPtr->screenNum = screenNum; @@ -689,6 +655,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; @@ -697,6 +664,8 @@ TkAllocWindow( winPtr->selHandlerList = NULL; winPtr->geomMgrPtr = NULL; winPtr->geomData = NULL; + winPtr->geomMgrName = NULL; + winPtr->maintainerPtr = NULL; winPtr->reqWidth = winPtr->reqHeight = 1; winPtr->internalBorderLeft = 0; winPtr->wmInfoPtr = NULL; @@ -735,7 +704,7 @@ NameWindow( register TkWindow *winPtr, /* Window that is to be named and inserted. */ TkWindow *parentPtr, /* Pointer to logical parent for winPtr (used * for naming, options, etc.). */ - CONST char *name) /* Name for winPtr; must be unique among + const char *name) /* Name for winPtr; must be unique among * parentPtr's children. */ { #define FIXED_SIZE 200 @@ -773,24 +742,25 @@ NameWindow( } /* - * For non-anonymous windows, set up the window name. - */ - - winPtr->nameUid = Tk_GetUid(name); - - /* * Don't permit names that start with an upper-case letter: this will just * cause confusion with class names in the option database. */ if (isupper(UCHAR(name[0]))) { - Tcl_AppendResult(interp, - "window name starts with an upper-case letter: \"", - name, "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "window name starts with an upper-case letter: \"%s\"", + name)); + Tcl_SetErrorCode(interp, "TK", "VALUE", "WINDOW", "NOTCLASS", NULL); return TCL_ERROR; } /* + * For non-anonymous windows, set up the window name. + */ + + winPtr->nameUid = Tk_GetUid(name); + + /* * To permit names of arbitrary length, must be prepared to malloc a * buffer to hold the new path name. To run fast in the common case where * names are short, use a fixed-size buffer on the stack. @@ -798,10 +768,10 @@ NameWindow( length1 = strlen(parentPtr->pathName); length2 = strlen(name); - if ((length1+length2+2) <= FIXED_SIZE) { + if ((length1 + length2 + 2) <= FIXED_SIZE) { pathName = staticSpace; } else { - pathName = (char *) ckalloc((unsigned) (length1+length2+2)); + pathName = ckalloc(length1 + length2 + 2); } if (length1 == 1) { pathName[0] = '.'; @@ -817,8 +787,9 @@ NameWindow( ckfree(pathName); } if (!isNew) { - Tcl_AppendResult(interp, "window name \"", name, - "\" already exists in parent", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "window name \"%s\" already exists in parent", name)); + Tcl_SetErrorCode(interp, "TK", "VALUE", "WINDOW", "EXISTS", NULL); return TCL_ERROR; } Tcl_SetHashValue(hPtr, winPtr); @@ -852,10 +823,10 @@ NameWindow( Tk_Window TkCreateMainWindow( Tcl_Interp *interp, /* Interpreter to use for error reporting. */ - CONST char *screenName, /* Name of screen on which to create window. + const char *screenName, /* Name of screen on which to create window. * Empty or NULL string means use DISPLAY * environment variable. */ - char *baseName) /* Base name for application; usually of the + const char *baseName) /* Base name for application; usually of the * form "prog instance". */ { Tk_Window tkwin; @@ -865,7 +836,7 @@ TkCreateMainWindow( register TkWindow *winPtr; register const TkCmd *cmdPtr; ClientData clientData; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* @@ -893,7 +864,7 @@ TkCreateMainWindow( */ winPtr = (TkWindow *) tkwin; - mainPtr = (TkMainInfo *) ckalloc(sizeof(TkMainInfo)); + mainPtr = ckalloc(sizeof(TkMainInfo)); mainPtr->winPtr = winPtr; mainPtr->refCount = 1; mainPtr->interp = interp; @@ -927,6 +898,7 @@ TkCreateMainWindow( hPtr = Tcl_CreateHashEntry(&mainPtr->nameTable, ".", &dummy); Tcl_SetHashValue(hPtr, winPtr); winPtr->pathName = Tcl_GetHashKey(&mainPtr->nameTable, hPtr); + Tcl_InitHashTable(&mainPtr->busyTable, TCL_ONE_WORD_KEYS); /* * We have just created another Tk application; increment the refcount on @@ -950,39 +922,39 @@ TkCreateMainWindow( if (cmdPtr->objProc == NULL) { Tcl_Panic("TkCreateMainWindow: builtin command with NULL string and object procs"); } -#if defined(__WIN32__) && !defined(STATIC_BUILD) + +#if defined(_WIN32) && !defined(STATIC_BUILD) if ((cmdPtr->flags & WINMACONLY) && tclStubsPtr->reserved9) { - /* We are running on Cygwin, so don't use the win32 dialogs */ + /* + * We are running on Cygwin, so don't use the win32 dialogs. + */ + continue; } -#endif +#endif /* _WIN32 && !STATIC_BUILD */ + if (cmdPtr->flags & PASSMAINWINDOW) { - clientData = (ClientData) tkwin; + clientData = tkwin; } else { - clientData = (ClientData) NULL; + clientData = NULL; } - if (cmdPtr->flags & NOOBJPROC) { - Tcl_CreateCommand(interp, cmdPtr->name, - (Tcl_CmdProc *) cmdPtr->objProc, clientData, NULL); + if (cmdPtr->flags & USEINITPROC) { + ((TkInitProc *) cmdPtr->objProc)(interp, clientData); } else { Tcl_CreateObjCommand(interp, cmdPtr->name, cmdPtr->objProc, clientData, NULL); } - if (isSafe) { - if (!(cmdPtr->flags & ISSAFE)) { - Tcl_HideCommand(interp, cmdPtr->name, cmdPtr->name); - } + if (isSafe && !(cmdPtr->flags & ISSAFE)) { + Tcl_HideCommand(interp, cmdPtr->name, cmdPtr->name); } } - TkCreateMenuCmd(interp); - /* * Set variables for the intepreter. */ - Tcl_SetVar(interp, "tk_patchLevel", TK_PATCH_LEVEL, TCL_GLOBAL_ONLY); - Tcl_SetVar(interp, "tk_version", TK_VERSION, TCL_GLOBAL_ONLY); + Tcl_SetVar2(interp, "tk_patchLevel", NULL, TK_PATCH_LEVEL, TCL_GLOBAL_ONLY); + Tcl_SetVar2(interp, "tk_version", NULL, TK_VERSION, TCL_GLOBAL_ONLY); tsdPtr->numMainWindows++; return tkwin; @@ -1016,36 +988,38 @@ Tk_CreateWindow( * the interp's result is assumed to be * initialized by the caller. */ Tk_Window parent, /* Token for parent of new window. */ - CONST char *name, /* Name for new window. Must be unique among + const char *name, /* Name for new window. Must be unique among * parent's children. */ - CONST char *screenName) /* If NULL, new window will be internal on + const char *screenName) /* If NULL, new window will be internal on * same screen as its parent. If non-NULL, * gives name of screen on which to create new * window; window will be a top-level * window. */ { TkWindow *parentPtr = (TkWindow *) parent; - TkWindow *winPtr; - - if ((parentPtr != NULL) && (parentPtr->flags & TK_ALREADY_DEAD)) { - Tcl_AppendResult(interp, - "can't create window: parent has been destroyed", NULL); - return NULL; - } else if ((parentPtr != NULL) && - (parentPtr->flags & TK_CONTAINER)) { - Tcl_AppendResult(interp, - "can't create window: its parent has -container = yes", NULL); - return NULL; - } - if (screenName == NULL) { - winPtr = TkAllocWindow(parentPtr->dispPtr, parentPtr->screenNum, - parentPtr); - if (NameWindow(interp, winPtr, parentPtr, name) != TCL_OK) { - Tk_DestroyWindow((Tk_Window) winPtr); + if (parentPtr) { + if (parentPtr->flags & TK_ALREADY_DEAD) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "can't create window: parent has been destroyed", -1)); + Tcl_SetErrorCode(interp, "TK", "CREATE", "DEAD_PARENT", NULL); return NULL; + } else if (parentPtr->flags & TK_CONTAINER) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "can't create window: its parent has -container = yes", + -1)); + Tcl_SetErrorCode(interp, "TK", "CREATE", "CONTAINER", NULL); + return NULL; + } else if (screenName == NULL) { + TkWindow *winPtr = TkAllocWindow(parentPtr->dispPtr, + parentPtr->screenNum, parentPtr); + + if (NameWindow(interp, winPtr, parentPtr, name) != TCL_OK) { + Tk_DestroyWindow((Tk_Window) winPtr); + return NULL; + } + return (Tk_Window) winPtr; } - return (Tk_Window) winPtr; } return CreateTopLevelWindow(interp, parent, name, screenName, /* flags */ 0); @@ -1080,39 +1054,41 @@ Tk_CreateAnonymousWindow( * the interp's result is assumed to be * initialized by the caller. */ Tk_Window parent, /* Token for parent of new window. */ - CONST char *screenName) /* If NULL, new window will be internal on + const char *screenName) /* If NULL, new window will be internal on * same screen as its parent. If non-NULL, * gives name of screen on which to create new * window; window will be a top-level * window. */ { TkWindow *parentPtr = (TkWindow *) parent; - TkWindow *winPtr; - - if ((parentPtr != NULL) && (parentPtr->flags & TK_ALREADY_DEAD)) { - Tcl_AppendResult(interp, - "can't create window: parent has been destroyed", NULL); - return NULL; - } else if ((parentPtr != NULL) && - (parentPtr->flags & TK_CONTAINER)) { - Tcl_AppendResult(interp, - "can't create window: its parent has -container = yes", NULL); - return NULL; - } - if (screenName == NULL) { - winPtr = TkAllocWindow(parentPtr->dispPtr, parentPtr->screenNum, - parentPtr); - /* - * Add the anonymous window flag now, so that NameWindow will behave - * correctly. - */ - winPtr->flags |= TK_ANONYMOUS_WINDOW; - if (NameWindow(interp, winPtr, parentPtr, NULL) != TCL_OK) { - Tk_DestroyWindow((Tk_Window) winPtr); + if (parentPtr) { + if (parentPtr->flags & TK_ALREADY_DEAD) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "can't create window: parent has been destroyed", -1)); + Tcl_SetErrorCode(interp, "TK", "CREATE", "DEAD_PARENT", NULL); + return NULL; + } else if (parentPtr->flags & TK_CONTAINER) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "can't create window: its parent has -container = yes", + -1)); + Tcl_SetErrorCode(interp, "TK", "CREATE", "CONTAINER", NULL); return NULL; + } else if (screenName == NULL) { + TkWindow *winPtr = TkAllocWindow(parentPtr->dispPtr, + parentPtr->screenNum, parentPtr); + /* + * Add the anonymous window flag now, so that NameWindow will + * behave correctly. + */ + + winPtr->flags |= TK_ANONYMOUS_WINDOW; + if (NameWindow(interp, winPtr, parentPtr, NULL) != TCL_OK) { + Tk_DestroyWindow((Tk_Window) winPtr); + return NULL; + } + return (Tk_Window) winPtr; } - return (Tk_Window) winPtr; } return CreateTopLevelWindow(interp, parent, NULL, screenName, TK_ANONYMOUS_WINDOW); @@ -1147,11 +1123,11 @@ Tk_CreateWindowFromPath( * initialized by the caller. */ Tk_Window tkwin, /* Token for any window in application that is * to contain new window. */ - CONST char *pathName, /* Path name for new window within the + const char *pathName, /* Path name for new window within the * application of tkwin. The parent of this * window must already exist, but the window * itself must not exist. */ - CONST char *screenName) /* If NULL, new window will be on same screen + const char *screenName) /* If NULL, new window will be on same screen * as its parent. If non-NULL, gives name of * screen on which to create new window; * window will be a top-level window. */ @@ -1172,13 +1148,14 @@ Tk_CreateWindowFromPath( p = strrchr(pathName, '.'); if (p == NULL) { - Tcl_AppendResult(interp, "bad window path name \"", pathName, - "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad window path name \"%s\"", pathName)); + Tcl_SetErrorCode(interp, "TK", "VALUE", "WINDOW_PATH", NULL); return NULL; } numChars = (int) (p-pathName); if (numChars > FIXED_SPACE) { - p = (char *) ckalloc((unsigned) (numChars+1)); + p = ckalloc(numChars + 1); } else { p = fixedSpace; } @@ -1202,13 +1179,14 @@ Tk_CreateWindowFromPath( return NULL; } if (((TkWindow *) parent)->flags & TK_ALREADY_DEAD) { - Tcl_AppendResult(interp, - "can't create window: parent has been destroyed", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "can't create window: parent has been destroyed", -1)); + Tcl_SetErrorCode(interp, "TK", "CREATE", "DEAD_PARENT", NULL); return NULL; - } - if (((TkWindow *) parent)->flags & TK_CONTAINER) { - Tcl_AppendResult(interp, - "can't create window: its parent has -container = yes", NULL); + } else if (((TkWindow *) parent)->flags & TK_CONTAINER) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "can't create window: its parent has -container = yes", -1)); + Tcl_SetErrorCode(interp, "TK", "CREATE", "CONTAINER", NULL); return NULL; } @@ -1262,7 +1240,7 @@ Tk_DestroyWindow( TkDisplay *dispPtr = winPtr->dispPtr; XEvent event; TkHalfdeadWindow *halfdeadPtr, *prev_halfdeadPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (winPtr->flags & TK_ALREADY_DEAD) { @@ -1285,7 +1263,7 @@ Tk_DestroyWindow( (tsdPtr->halfdeadWindowList->winPtr == winPtr)) { halfdeadPtr = tsdPtr->halfdeadWindowList; } else { - halfdeadPtr = (TkHalfdeadWindow *) ckalloc(sizeof(TkHalfdeadWindow)); + halfdeadPtr = ckalloc(sizeof(TkHalfdeadWindow)); halfdeadPtr->flags = 0; halfdeadPtr->winPtr = winPtr; halfdeadPtr->nextPtr = tsdPtr->halfdeadWindowList; @@ -1347,12 +1325,11 @@ Tk_DestroyWindow( if (!(halfdeadPtr->flags & HD_DESTROY_COUNT)) { halfdeadPtr->flags |= HD_DESTROY_COUNT; - dispPtr->destroyCount++; } while (winPtr->childList != NULL) { - TkWindow *childPtr; - childPtr = winPtr->childList; + TkWindow *childPtr = winPtr->childList; + childPtr->flags |= TK_DONT_DESTROY_WINDOW; Tk_DestroyWindow((Tk_Window) childPtr); if (winPtr->childList == childPtr) { @@ -1379,8 +1356,8 @@ Tk_DestroyWindow( * deleted, in which case TkpGetOtherWindow will return NULL. */ - TkWindow *childPtr; - childPtr = TkpGetOtherWindow(winPtr); + TkWindow *childPtr = TkpGetOtherWindow(winPtr); + if (childPtr != NULL) { childPtr->flags |= TK_DONT_DESTROY_WINDOW; Tk_DestroyWindow((Tk_Window) childPtr); @@ -1430,7 +1407,7 @@ Tk_DestroyWindow( } else { prev_halfdeadPtr->nextPtr = halfdeadPtr->nextPtr; } - ckfree((char *) halfdeadPtr); + ckfree(halfdeadPtr); break; } prev_halfdeadPtr = halfdeadPtr; @@ -1450,7 +1427,7 @@ Tk_DestroyWindow( TkWmRemoveFromColormapWindows(winPtr); } if (winPtr->window != None) { -#if defined(MAC_OSX_TK) || defined(__WIN32__) +#if defined(MAC_OSX_TK) || defined(_WIN32) XDestroyWindow(winPtr->display, winPtr->window); #else if ((winPtr->flags & TK_TOP_HIERARCHY) @@ -1462,24 +1439,21 @@ Tk_DestroyWindow( * to do an explicit destroy of this X window. */ - dispPtr->lastDestroyRequest = NextRequest(winPtr->display); XDestroyWindow(winPtr->display, winPtr->window); } #endif - TkFreeWindowId(dispPtr, winPtr->window); Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->winTable, (char *) winPtr->window)); winPtr->window = None; } - dispPtr->destroyCount--; UnlinkWindow(winPtr); TkEventDeadWindow(winPtr); - TkBindDeadWindow(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); @@ -1487,10 +1461,14 @@ Tk_DestroyWindow( TkOptionDeadWindow(winPtr); TkSelDeadWindow(winPtr); TkGrabDeadWindow(winPtr); + if (winPtr->geomMgrName != NULL) { + ckfree(winPtr->geomMgrName); + winPtr->geomMgrName = NULL; + } if (winPtr->mainPtr != NULL) { if (winPtr->pathName != NULL) { Tk_DeleteAllBindings(winPtr->mainPtr->bindingTable, - (ClientData) winPtr->pathName); + winPtr->pathName); Tcl_DeleteHashEntry(Tcl_FindHashEntry(&winPtr->mainPtr->nameTable, winPtr->pathName)); @@ -1509,8 +1487,7 @@ Tk_DestroyWindow( winPtr->mainPtr->deletionEpoch++; } - winPtr->mainPtr->refCount--; - if (winPtr->mainPtr->refCount == 0) { + if (winPtr->mainPtr->refCount-- <= 1) { register const TkCmd *cmdPtr; /* @@ -1525,18 +1502,19 @@ Tk_DestroyWindow( */ if ((winPtr->mainPtr->interp != NULL) && - (!Tcl_InterpDeleted(winPtr->mainPtr->interp))) { + !Tcl_InterpDeleted(winPtr->mainPtr->interp)) { for (cmdPtr = commands; cmdPtr->name != NULL; cmdPtr++) { - Tcl_CreateCommand(winPtr->mainPtr->interp, cmdPtr->name, - TkDeadAppCmd, NULL, NULL); + Tcl_CreateObjCommand(winPtr->mainPtr->interp, cmdPtr->name, + TkDeadAppObjCmd, NULL, NULL); } - Tcl_CreateCommand(winPtr->mainPtr->interp, "send", - TkDeadAppCmd, NULL, NULL); + Tcl_CreateObjCommand(winPtr->mainPtr->interp, "send", + TkDeadAppObjCmd, NULL, NULL); Tcl_UnlinkVar(winPtr->mainPtr->interp, "tk_strictMotif"); - Tcl_UnlinkVar(winPtr->mainPtr->interp, + Tcl_UnlinkVar(winPtr->mainPtr->interp, "::tk::AlwaysShowSelection"); } + Tcl_DeleteHashTable(&winPtr->mainPtr->busyTable); Tcl_DeleteHashTable(&winPtr->mainPtr->nameTable); TkBindFree(winPtr->mainPtr); TkDeleteAllImages(winPtr->mainPtr); @@ -1554,14 +1532,14 @@ Tk_DestroyWindow( if (winPtr->flags & TK_EMBEDDED) { XSync(winPtr->display, False); } - ckfree((char *) winPtr->mainPtr); + ckfree(winPtr->mainPtr); /* * If no other applications are using the display, close the * display now and relinquish its data structures. */ -#if !defined(WIN32) && defined(NOT_YET) +#if !defined(_WIN32) && defined(NOT_YET) if (dispPtr->refCount <= 0) { /* * I have disabled this code because on Windows there are @@ -1609,10 +1587,10 @@ Tk_DestroyWindow( TkCloseDisplay(dispPtr); } -#endif +#endif /* !_WIN32 && NOT_YET */ } } - Tcl_EventuallyFree((ClientData) winPtr, TCL_DYNAMIC); + Tcl_EventuallyFree(winPtr, TCL_DYNAMIC); } /* @@ -1719,7 +1697,7 @@ Tk_MakeWindowExist( createProc = Tk_GetClassProc(winPtr->classProcsPtr, createProc); if (createProc != NULL && parent != None) { - winPtr->window = (*createProc)(tkwin, parent, winPtr->instanceData); + winPtr->window = createProc(tkwin, parent, winPtr->instanceData); } else { winPtr->window = TkpMakeWindow(winPtr, parent); } @@ -1747,6 +1725,7 @@ Tk_MakeWindowExist( if ((winPtr2->window != None) && !(winPtr2->flags & (TK_TOP_HIERARCHY|TK_REPARENTED))) { XWindowChanges changes; + changes.sibling = winPtr2->window; changes.stack_mode = Below; XConfigureWindow(winPtr->display, winPtr->window, @@ -1860,7 +1839,7 @@ Tk_ConfigureWindow( winPtr->changes.border_width = valuePtr->border_width; } if (valueMask & (CWSibling|CWStackMode)) { - Tcl_Panic("Can't set sibling or stack mode from Tk_ConfigureWindow."); + Tcl_Panic("Can't set sibling or stack mode from Tk_ConfigureWindow"); } if (winPtr->window != None) { @@ -2247,7 +2226,7 @@ TkDoConfigureNotify( void Tk_SetClass( Tk_Window tkwin, /* Token for window to assign class. */ - CONST char *className) /* New class for tkwin. */ + const char *className) /* New class for tkwin. */ { register TkWindow *winPtr = (TkWindow *) tkwin; @@ -2279,7 +2258,7 @@ Tk_SetClass( void Tk_SetClassProcs( Tk_Window tkwin, /* Token for window to modify. */ - Tk_ClassProcs *procs, /* Class procs structure. */ + const Tk_ClassProcs *procs, /* Class procs structure. */ ClientData instanceData) /* Data to be passed to class functions. */ { register TkWindow *winPtr = (TkWindow *) tkwin; @@ -2311,7 +2290,7 @@ Tk_SetClassProcs( Tk_Window Tk_NameToWindow( Tcl_Interp *interp, /* Where to report errors. */ - CONST char *pathName, /* Path name of window. */ + const char *pathName, /* Path name of window. */ Tk_Window tkwin) /* Token for window: name is assumed to belong * to the same main window as tkwin. */ { @@ -2324,7 +2303,8 @@ Tk_NameToWindow( */ if (interp != NULL) { - Tcl_AppendResult(interp, "NULL main window", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj("NULL main window",-1)); + Tcl_SetErrorCode(interp, "TK", "NO_MAIN_WINDOW", NULL); } return NULL; } @@ -2333,12 +2313,14 @@ Tk_NameToWindow( pathName); if (hPtr == NULL) { if (interp != NULL) { - Tcl_AppendResult(interp, "bad window path name \"", - pathName, "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad window path name \"%s\"", pathName)); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "WINDOW", pathName, + NULL); } return NULL; } - return (Tk_Window) Tcl_GetHashValue(hPtr); + return Tcl_GetHashValue(hPtr); } /* @@ -2376,12 +2358,15 @@ Tk_IdToWindow( break; } } + if (window == None) { + return NULL; + } hPtr = Tcl_FindHashEntry(&dispPtr->winTable, (char *) window); if (hPtr == NULL) { return NULL; } - return (Tk_Window) Tcl_GetHashValue(hPtr); + return Tcl_GetHashValue(hPtr); } /* @@ -2401,7 +2386,7 @@ Tk_IdToWindow( *---------------------------------------------------------------------- */ -CONST char * +const char * Tk_DisplayName( Tk_Window tkwin) /* Window whose display name is desired. */ { @@ -2428,8 +2413,8 @@ Tcl_Interp * Tk_Interp( Tk_Window tkwin) { - if (tkwin != NULL && ((TkWindow *)tkwin)->mainPtr != NULL) { - return ((TkWindow *)tkwin)->mainPtr->interp; + if (tkwin != NULL && ((TkWindow *) tkwin)->mainPtr != NULL) { + return ((TkWindow *) tkwin)->mainPtr->interp; } return NULL; } @@ -2587,9 +2572,8 @@ Tk_RestackWindow( if (winPtr->window != None) { XWindowChanges changes; - unsigned int mask; + unsigned int mask = CWStackMode; - mask = CWStackMode; changes.stack_mode = Above; for (otherPtr = winPtr->nextPtr; otherPtr != NULL; otherPtr = otherPtr->nextPtr) { @@ -2640,8 +2624,7 @@ Tk_MainWindow( return NULL; } #endif - tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); for (mainPtr = tsdPtr->mainWindowList; mainPtr != NULL; mainPtr = mainPtr->nextPtr) { @@ -2649,7 +2632,9 @@ Tk_MainWindow( return (Tk_Window) mainPtr->winPtr; } } - Tcl_SetResult(interp, "this isn't a Tk application", TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "this isn't a Tk application", -1)); + Tcl_SetErrorCode(interp, "TK", "NO_MAIN_WINDOW", NULL); return NULL; } @@ -2709,8 +2694,7 @@ Tk_GetNumMainWindows(void) } #endif - tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); return tsdPtr->numMainWindows; } @@ -2768,7 +2752,7 @@ DeleteWindowsExitProc( { TkDisplay *dispPtr, *nextPtr; Tcl_Interp *interp; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) clientData; + ThreadSpecificData *tsdPtr = clientData; if (tsdPtr == NULL) { return; @@ -2784,11 +2768,11 @@ DeleteWindowsExitProc( while (tsdPtr->halfdeadWindowList != NULL) { interp = tsdPtr->halfdeadWindowList->winPtr->mainPtr->interp; - Tcl_Preserve((ClientData) interp); + Tcl_Preserve(interp); tsdPtr->halfdeadWindowList->flags |= HD_CLEANUP; tsdPtr->halfdeadWindowList->winPtr->flags &= ~TK_ALREADY_DEAD; Tk_DestroyWindow((Tk_Window) tsdPtr->halfdeadWindowList->winPtr); - Tcl_Release((ClientData) interp); + Tcl_Release(interp); } /* @@ -2797,9 +2781,21 @@ DeleteWindowsExitProc( while (tsdPtr->mainWindowList != NULL) { interp = tsdPtr->mainWindowList->interp; - Tcl_Preserve((ClientData) interp); + Tcl_Preserve(interp); Tk_DestroyWindow((Tk_Window) tsdPtr->mainWindowList->winPtr); - Tcl_Release((ClientData) interp); + Tcl_Release(interp); + } + + /* + * Let error handlers catch up before actual close of displays. + * Must be done before tsdPtr->displayList is cleared, otherwise + * ErrorProc() in tkError.c cannot associate the pending X errors + * to the remaining error handlers. + */ + + for (dispPtr = tsdPtr->displayList; dispPtr != NULL; + dispPtr = dispPtr->nextPtr) { + XSync(dispPtr->display, False); } /* @@ -2831,51 +2827,54 @@ DeleteWindowsExitProc( tsdPtr->initialized = 0; } -#if defined(__WIN32__) +#if defined(_WIN32) static HMODULE tkcygwindll = NULL; /* * Run Tk_MainEx from libtk8.?.dll * - * This function is only ever called from wish8.4.exe, the cygwin - * port of Tcl. This means that the system encoding is utf-8, - * so we don't have to do any encoding conversions. + * This function is only ever called from wish8.4.exe, the cygwin port of Tcl. + * This means that the system encoding is utf-8, so we don't have to do any + * encoding conversions. */ + int -TkCygwinMainEx(argc, argv, appInitProc, interp) - int argc; /* Number of arguments. */ - char **argv; /* Array of argument strings. */ - Tcl_AppInitProc *appInitProc; /* Application-specific initialization - * procedure to call after most - * initialization but before starting - * to execute commands. */ - Tcl_Interp *interp; +TkCygwinMainEx( + int argc, /* Number of arguments. */ + char **argv, /* Array of argument strings. */ + Tcl_AppInitProc *appInitProc, + /* Application-specific initialization + * procedure to call after most initialization + * but before starting to execute commands. */ + Tcl_Interp *interp) { - char name[MAX_PATH]; + TCHAR name[MAX_PATH]; int len; - void (*sym)(int, char **, Tcl_AppInitProc *, Tcl_Interp *); + void (*tkmainex)(int, char **, Tcl_AppInitProc *, Tcl_Interp *); /* construct "<path>/libtk8.?.dll", from "<path>/tk8?.dll" */ - len = GetModuleFileName(Tk_GetHINSTANCE(), name, MAX_PATH); - name[len-2] = '.'; - name[len-1] = name[len-5]; - strcpy(name+len, ".dll"); - memcpy(name+len-8, "libtk8", 6); - - tkcygwindll = LoadLibrary(name); - if (!tkcygwindll) { - /* dll is not present */ - return 0; - } - sym = (void (*)(int, char **, Tcl_AppInitProc *, Tcl_Interp *)) GetProcAddress(tkcygwindll, "Tk_MainEx"); - if (!sym) { - return 0; - } - sym(argc, argv, appInitProc, interp); + len = GetModuleFileNameW(Tk_GetHINSTANCE(), name, MAX_PATH); + name[len-2] = TEXT('.'); + name[len-1] = name[len-5]; + _tcscpy(name+len, TEXT(".dll")); + memcpy(name+len-8, TEXT("libtk8"), 6 * sizeof(TCHAR)); + + tkcygwindll = LoadLibrary(name); + if (!tkcygwindll) { + /* dll is not present */ + return 0; + } + tkmainex = (void (*)(int, char **, Tcl_AppInitProc *, Tcl_Interp *)) + GetProcAddress(tkcygwindll, "Tk_MainEx"); + if (!tkmainex) { + return 0; + } + tkmainex(argc, argv, appInitProc, interp); return 1; } -#endif +#endif /* _WIN32 */ + /* *---------------------------------------------------------------------- * @@ -2903,16 +2902,16 @@ int Tk_Init( Tcl_Interp *interp) /* Interpreter to initialize. */ { -#if defined(__WIN32__) +#if defined(_WIN32) if (tkcygwindll) { - int (*sym)(Tcl_Interp *); + int (*tkinit)(Tcl_Interp *); - sym = (int (*)(Tcl_Interp *)) GetProcAddress(tkcygwindll, "Tk_Init"); - if (sym) { - return sym(interp); + tkinit = (int(*)(Tcl_Interp *)) GetProcAddress(tkcygwindll,"Tk_Init"); + if (tkinit) { + return tkinit(interp); } } -#endif +#endif /* _WIN32 */ return Initialize(interp); } @@ -2976,27 +2975,29 @@ Tk_SafeInit( * checked at several places to differentiate the two initialisations. */ -#if defined(__WIN32__) +#if defined(_WIN32) if (tkcygwindll) { - int (*sym)(Tcl_Interp *); + int (*tksafeinit)(Tcl_Interp *); - sym = (int (*)(Tcl_Interp *)) GetProcAddress(tkcygwindll, "Tk_SafeInit"); - if (sym) { - return sym(interp); + tksafeinit = (int (*)(Tcl_Interp *)) + GetProcAddress(tkcygwindll, "Tk_SafeInit"); + if (tksafeinit) { + return tksafeinit(interp); } } -#endif +#endif /* _WIN32 */ return Initialize(interp); } -extern TkStubs tkStubs; +MODULE_SCOPE const TkStubs tkStubs; /* *---------------------------------------------------------------------- * * Initialize -- * - * ???TODO??? + * The core of the initialization code for Tk, called from Tk_Init and + * Tk_SafeInit. * * Results: * A standard Tcl result. Also leaves an error message in the interp's @@ -3009,22 +3010,57 @@ extern TkStubs tkStubs; */ static int +CopyValue( + ClientData dummy, + Tcl_Obj *objPtr, + void *dstPtr) +{ + *(Tcl_Obj **)dstPtr = objPtr; + return 1; +} + +static int Initialize( Tcl_Interp *interp) /* Interpreter to initialize. */ { - char *p; - int argc, code; - CONST char **argv; - char *args[20]; - CONST char *argString = NULL; - Tcl_DString class; + int code = TCL_OK; ThreadSpecificData *tsdPtr; + Tcl_Obj *value = NULL; + Tcl_Obj *cmd; + + Tcl_Obj *nameObj = NULL; + Tcl_Obj *classObj = NULL; + Tcl_Obj *displayObj = NULL; + Tcl_Obj *colorMapObj = NULL; + Tcl_Obj *useObj = NULL; + Tcl_Obj *visualObj = NULL; + Tcl_Obj *geometryObj = NULL; + + int sync = 0; + + const Tcl_ArgvInfo table[] = { + {TCL_ARGV_CONSTANT, "-sync", INT2PTR(1), &sync, + "Use synchronous mode for display server", NULL}, + {TCL_ARGV_FUNC, "-colormap", CopyValue, &colorMapObj, + "Colormap for main window", NULL}, + {TCL_ARGV_FUNC, "-display", CopyValue, &displayObj, + "Display to use", NULL}, + {TCL_ARGV_FUNC, "-geometry", CopyValue, &geometryObj, + "Initial geometry for window", NULL}, + {TCL_ARGV_FUNC, "-name", CopyValue, &nameObj, + "Name to use for application", NULL}, + {TCL_ARGV_FUNC, "-visual", CopyValue, &visualObj, + "Visual for main window", NULL}, + {TCL_ARGV_FUNC, "-use", CopyValue, &useObj, + "Id of window in which to embed application", NULL}, + TCL_ARGV_AUTO_REST, TCL_ARGV_AUTO_HELP, TCL_ARGV_TABLE_END + }; /* * Ensure that we are getting a compatible version of Tcl. */ - if (Tcl_InitStubs(interp, "8.5.0", 0) == NULL) { + if (Tcl_InitStubs(interp, "8.6", 0) == NULL) { return TCL_ERROR; } @@ -3034,28 +3070,10 @@ Initialize( TkRegisterObjTypes(); - tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* - * Start by initializing all the static variables to default acceptable - * values so that no information is leaked from a previous run of this - * code. - */ - - Tcl_MutexLock(&windowMutex); - synchronize = 0; - name = NULL; - display = NULL; - geometry = NULL; - colormap = NULL; - use = NULL; - visual = NULL; - rest = 0; - argv = NULL; - - /* - * We start by resetting the result because it might not be clean + * We start by resetting the result because it might not be clean. */ Tcl_ResetResult(interp); @@ -3066,8 +3084,6 @@ Initialize( * master. */ - Tcl_DString ds; - /* * Step 1 : find the master and construct the interp name (could be a * function if new APIs were ok). We could also construct the path @@ -3077,16 +3093,13 @@ Initialize( Tcl_Interp *master = interp; - while (1) { + while (Tcl_IsSafe(master)) { master = Tcl_GetMaster(master); if (master == NULL) { - Tcl_AppendResult(interp, "NULL master", NULL); - code = TCL_ERROR; - goto done; - } - if (!Tcl_IsSafe(master)) { - /* Found the trusted master. */ - break; + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "no controlling master interpreter", -1)); + Tcl_SetErrorCode(interp, "TK", "SAFE", "NO_MASTER", NULL); + return TCL_ERROR; } } @@ -3096,36 +3109,30 @@ Initialize( code = Tcl_GetInterpPath(master, interp); if (code != TCL_OK) { - Tcl_AppendResult(interp, "error in Tcl_GetInterpPath", NULL); - goto done; + Tcl_Panic("Tcl_GetInterpPath broken!"); } /* - * Build the string to eval. + * Build the command to eval in trusted master. */ - Tcl_DStringInit(&ds); - Tcl_DStringAppendElement(&ds, "::safe::TkInit"); - Tcl_DStringAppendElement(&ds, Tcl_GetStringResult(master)); + cmd = Tcl_NewListObj(2, NULL); + Tcl_ListObjAppendElement(NULL, cmd, + Tcl_NewStringObj("::safe::TkInit", -1)); + Tcl_ListObjAppendElement(NULL, cmd, Tcl_GetObjResult(master)); /* * Step 2 : Eval in the master. The argument is the *reversed* interp * path of the slave. */ - code = Tcl_Eval(master, Tcl_DStringValue(&ds)); + Tcl_IncrRefCount(cmd); + code = Tcl_EvalObjEx(master, cmd, 0); + Tcl_DecrRefCount(cmd); + Tcl_TransferResult(master, code, interp); if (code != TCL_OK) { - /* - * We might want to transfer the error message or not. We don't. - * (No API to do it and maybe security reasons). - */ - - Tcl_DStringFree(&ds); - Tcl_AppendResult(interp, - "not allowed to start Tk by master's safe::TkInit", NULL); - goto done; + return code; } - Tcl_DStringFree(&ds); /* * Use the master's result as argv. Note: We don't use the Obj @@ -3133,7 +3140,7 @@ Initialize( * changing the code below. */ - argString = Tcl_GetStringResult(master); + value = Tcl_GetObjResult(interp); } else { /* * If there is an "argv" variable, get its value, extract out relevant @@ -3141,50 +3148,67 @@ Initialize( * that we used. */ - argString = Tcl_GetVar2(interp, "argv", NULL, TCL_GLOBAL_ONLY); + value = Tcl_GetVar2Ex(interp, "argv", NULL, TCL_GLOBAL_ONLY); } - if (argString != NULL) { - char buffer[TCL_INTEGER_SPACE]; - if (Tcl_SplitList(interp, argString, &argc, &argv) != TCL_OK) { - argError: + if (value) { + int objc; + Tcl_Obj **objv, **rest; + Tcl_Obj *parseList = Tcl_NewListObj(1, NULL); + + Tcl_ListObjAppendElement(NULL, parseList, Tcl_NewObj()); + + Tcl_IncrRefCount(value); + if (TCL_OK != Tcl_ListObjAppendList(interp, parseList, value) || + TCL_OK != Tcl_ListObjGetElements(NULL, parseList, &objc, &objv) || + TCL_OK != Tcl_ParseArgsObjv(interp, table, &objc, objv, &rest)) { Tcl_AddErrorInfo(interp, "\n (processing arguments in argv variable)"); code = TCL_ERROR; - goto done; } - if (Tk_ParseArgv(interp, (Tk_Window) NULL, &argc, argv, - argTable, TK_ARGV_DONT_SKIP_FIRST_ARG|TK_ARGV_NO_DEFAULTS) - != TCL_OK) { - goto argError; + if (code == TCL_OK) { + Tcl_SetVar2Ex(interp, "argv", NULL, + Tcl_NewListObj(objc-1, rest+1), TCL_GLOBAL_ONLY); + Tcl_SetVar2Ex(interp, "argc", NULL, + Tcl_NewIntObj(objc-1), TCL_GLOBAL_ONLY); + ckfree(rest); + } + Tcl_DecrRefCount(parseList); + if (code != TCL_OK) { + goto done; } - p = Tcl_Merge(argc, argv); - Tcl_SetVar2(interp, "argv", NULL, p, TCL_GLOBAL_ONLY); - sprintf(buffer, "%d", argc); - Tcl_SetVar2(interp, "argc", NULL, buffer, TCL_GLOBAL_ONLY); - ckfree(p); } /* * Figure out the application's name and class. */ - Tcl_DStringInit(&class); - if (name == NULL) { - int offset; + /* + * If we got no -name argument, fetch from TkpGetAppName(). + */ - TkpGetAppName(interp, &class); - offset = Tcl_DStringLength(&class)+1; - Tcl_DStringSetLength(&class, 2*offset); - Tcl_DStringAppend(&class, Tcl_DStringValue(&class), offset-1); - name = Tcl_DStringValue(&class) + offset; - } else { - Tcl_DStringAppend(&class, name, -1); + if (nameObj == NULL) { + Tcl_DString nameDS; + + Tcl_DStringInit(&nameDS); + TkpGetAppName(interp, &nameDS); + nameObj = Tcl_NewStringObj(Tcl_DStringValue(&nameDS), + Tcl_DStringLength(&nameDS)); + Tcl_DStringFree(&nameDS); } - p = Tcl_DStringValue(&class); - if (*p) { - Tcl_UtfToTitle(p); + /* + * The -class argument is always the ToTitle of the -name + */ + + { + int numBytes; + const char *bytes = Tcl_GetStringFromObj(nameObj, &numBytes); + + classObj = Tcl_NewStringObj(bytes, numBytes); + + numBytes = Tcl_UtfToTitle(Tcl_GetString(classObj)); + Tcl_SetObjLength(classObj, numBytes); } /* @@ -3192,15 +3216,14 @@ Initialize( * information parsed from argv, if any. */ - args[0] = "toplevel"; - args[1] = "."; - args[2] = "-class"; - args[3] = Tcl_DStringValue(&class); - argc = 4; - if (display != NULL) { - args[argc] = "-screen"; - args[argc+1] = display; - argc += 2; + cmd = Tcl_NewStringObj("toplevel . -class", -1); + + Tcl_ListObjAppendElement(NULL, cmd, classObj); + classObj = NULL; + + if (displayObj) { + Tcl_ListObjAppendElement(NULL, cmd, Tcl_NewStringObj("-screen", -1)); + Tcl_ListObjAppendElement(NULL, cmd, displayObj); /* * If this is the first application for this process, save the display @@ -3209,36 +3232,35 @@ Initialize( */ if (tsdPtr->numMainWindows == 0) { - Tcl_SetVar2(interp, "env", "DISPLAY", display, TCL_GLOBAL_ONLY); + Tcl_SetVar2Ex(interp, "env", "DISPLAY", displayObj, TCL_GLOBAL_ONLY); } + displayObj = NULL; } - if (colormap != NULL) { - args[argc] = "-colormap"; - args[argc+1] = colormap; - argc += 2; - colormap = NULL; + if (colorMapObj) { + Tcl_ListObjAppendElement(NULL, cmd, Tcl_NewStringObj("-colormap", -1)); + Tcl_ListObjAppendElement(NULL, cmd, colorMapObj); + colorMapObj = NULL; } - if (use != NULL) { - args[argc] = "-use"; - args[argc+1] = use; - argc += 2; - use = NULL; + if (useObj) { + Tcl_ListObjAppendElement(NULL, cmd, Tcl_NewStringObj("-use", -1)); + Tcl_ListObjAppendElement(NULL, cmd, useObj); + useObj = NULL; } - if (visual != NULL) { - args[argc] = "-visual"; - args[argc+1] = visual; - argc += 2; - visual = NULL; + if (visualObj) { + Tcl_ListObjAppendElement(NULL, cmd, Tcl_NewStringObj("-visual", -1)); + Tcl_ListObjAppendElement(NULL, cmd, visualObj); + visualObj = NULL; } - args[argc] = NULL; - code = TkCreateFrame((ClientData) NULL, interp, argc, args, 1, name); - Tcl_DStringFree(&class); + code = TkListCreateFrame(NULL, interp, cmd, 1, nameObj); + + Tcl_DecrRefCount(cmd); + if (code != TCL_OK) { goto done; } Tcl_ResetResult(interp); - if (synchronize) { + if (sync) { XSynchronize(Tk_Display(Tk_MainWindow(interp)), True); } @@ -3247,13 +3269,19 @@ Initialize( * geometry into the "geometry" variable. */ - if (geometry != NULL) { - Tcl_SetVar(interp, "geometry", geometry, TCL_GLOBAL_ONLY); - code = Tcl_VarEval(interp, "wm geometry . ", geometry, NULL); + if (geometryObj) { + + Tcl_SetVar2Ex(interp, "geometry", NULL, geometryObj, TCL_GLOBAL_ONLY); + + cmd = Tcl_NewStringObj("wm geometry .", -1); + Tcl_ListObjAppendElement(NULL, cmd, geometryObj); + Tcl_IncrRefCount(cmd); + code = Tcl_EvalObjEx(interp, cmd, 0); + Tcl_DecrRefCount(cmd); + geometryObj = NULL; if (code != TCL_OK) { goto done; } - geometry = NULL; } /* @@ -3275,12 +3303,6 @@ Initialize( Tcl_SetMainLoop(Tk_MainLoop); -#ifndef _WIN32 - /* On Windows, this has no added value. */ -# undef Tk_InitStubs - Tk_InitStubs(interp, TK_VERSION, 1); -#endif - /* * Initialized the themed widget set */ @@ -3296,10 +3318,6 @@ Initialize( * console window interpreter. */ - Tcl_MutexUnlock(&windowMutex); - if (argv != NULL) { - ckfree((char *) argv); - } code = TkpInit(interp); if (code == TCL_OK) { @@ -3313,7 +3331,7 @@ Initialize( * an alternate [tkInit] command before calling Tk_Init(). */ - code = Tcl_Eval(interp, + code = Tcl_EvalEx(interp, "if {[namespace which -command tkInit] eq \"\"} {\n\ proc tkInit {} {\n\ global tk_library tk_version tk_patchLevel\n\ @@ -3321,7 +3339,7 @@ Initialize( tcl_findLibrary tk $tk_version $tk_patchLevel tk.tcl TK_LIBRARY tk_library\n\ }\n\ }\n\ -tkInit"); +tkInit", -1, 0); } if (code == TCL_OK) { /* @@ -3330,14 +3348,12 @@ tkInit"); * specific cleanups take place to avoid panics in finalization. */ - TkCreateThreadExitHandler(DeleteWindowsExitProc, (ClientData) tsdPtr); + TkCreateThreadExitHandler(DeleteWindowsExitProc, tsdPtr); } - return code; - done: - Tcl_MutexUnlock(&windowMutex); - if (argv != NULL) { - ckfree((char *) argv); + if (value) { + Tcl_DecrRefCount(value); + value = NULL; } return code; } @@ -3361,16 +3377,16 @@ tkInit"); *---------------------------------------------------------------------- */ -CONST char * +const char * Tk_PkgInitStubsCheck( Tcl_Interp *interp, - CONST char * version, + const char * version, int exact) { - CONST char *actualVersion = Tcl_PkgRequire(interp, "Tk", version, 0); + const char *actualVersion = Tcl_PkgRequireEx(interp, "Tk", version, 0, NULL); if (exact && actualVersion) { - CONST char *p = version; + const char *p = version; int count = 0; while (*p) { @@ -3379,15 +3395,16 @@ Tk_PkgInitStubsCheck( if (count == 1) { if (0 != strncmp(version, actualVersion, strlen(version))) { /* Construct error message */ - Tcl_PkgPresent(interp, "Tk", version, 1); + Tcl_PkgPresentEx(interp, "Tk", version, 1, NULL); return NULL; } } else { - return Tcl_PkgPresent(interp, "Tk", version, 1); + return Tcl_PkgPresentEx(interp, "Tk", version, 1, NULL); } } return actualVersion; } + /* * Local Variables: * mode: c diff --git a/generic/ttk/ttk.decls b/generic/ttk/ttk.decls index 8b2b50b..e668a2a 100644 --- a/generic/ttk/ttk.decls +++ b/generic/ttk/ttk.decls @@ -3,148 +3,148 @@ interface ttk epoch 0 scspec TTKAPI -declare 0 current { - Ttk_Theme Ttk_GetTheme(Tcl_Interp *interp, const char *name); +declare 0 { + Ttk_Theme Ttk_GetTheme(Tcl_Interp *interp, const char *name) } -declare 1 current { - Ttk_Theme Ttk_GetDefaultTheme(Tcl_Interp *interp); +declare 1 { + Ttk_Theme Ttk_GetDefaultTheme(Tcl_Interp *interp) } -declare 2 current { - Ttk_Theme Ttk_GetCurrentTheme(Tcl_Interp *interp); +declare 2 { + Ttk_Theme Ttk_GetCurrentTheme(Tcl_Interp *interp) } -declare 3 current { +declare 3 { Ttk_Theme Ttk_CreateTheme( - Tcl_Interp *interp, const char *name, Ttk_Theme parent); + Tcl_Interp *interp, const char *name, Ttk_Theme parent) } -declare 4 current { +declare 4 { void Ttk_RegisterCleanup( - Tcl_Interp *interp, void *deleteData, Ttk_CleanupProc *cleanupProc); + Tcl_Interp *interp, void *deleteData, Ttk_CleanupProc *cleanupProc) } -declare 5 current { +declare 5 { int Ttk_RegisterElementSpec( Ttk_Theme theme, const char *elementName, Ttk_ElementSpec *elementSpec, - void *clientData); + void *clientData) } -declare 6 current { +declare 6 { Ttk_ElementClass *Ttk_RegisterElement( Tcl_Interp *interp, Ttk_Theme theme, const char *elementName, Ttk_ElementSpec *elementSpec, - void *clientData); + void *clientData) } -declare 7 current { +declare 7 { int Ttk_RegisterElementFactory( Tcl_Interp *interp, const char *name, Ttk_ElementFactory factoryProc, - void *clientData); + void *clientData) } -declare 8 current { +declare 8 { void Ttk_RegisterLayout( - Ttk_Theme theme, const char *className, Ttk_LayoutSpec layoutSpec); + Ttk_Theme theme, const char *className, Ttk_LayoutSpec layoutSpec) } # # State maps. # -declare 10 current { +declare 10 { int Ttk_GetStateSpecFromObj( - Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_StateSpec *spec_rtn); + Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_StateSpec *spec_rtn) } -declare 11 current { +declare 11 { Tcl_Obj *Ttk_NewStateSpecObj( - unsigned int onbits, unsigned int offbits); + unsigned int onbits, unsigned int offbits) } -declare 12 current { +declare 12 { Ttk_StateMap Ttk_GetStateMapFromObj( - Tcl_Interp *interp, Tcl_Obj *objPtr); + Tcl_Interp *interp, Tcl_Obj *objPtr) } -declare 13 current { +declare 13 { Tcl_Obj *Ttk_StateMapLookup( - Tcl_Interp *interp, Ttk_StateMap map, Ttk_State state); + Tcl_Interp *interp, Ttk_StateMap map, Ttk_State state) } -declare 14 current { +declare 14 { int Ttk_StateTableLookup( - Ttk_StateTable map[], Ttk_State state); + Ttk_StateTable map[], Ttk_State state) } # # Low-level geometry utilities. # -declare 20 current { +declare 20 { int Ttk_GetPaddingFromObj( Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, - Ttk_Padding *pad_rtn); + Ttk_Padding *pad_rtn) } -declare 21 current { +declare 21 { int Ttk_GetBorderFromObj( Tcl_Interp *interp, Tcl_Obj *objPtr, - Ttk_Padding *pad_rtn); + Ttk_Padding *pad_rtn) } -declare 22 current { +declare 22 { int Ttk_GetStickyFromObj( - Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_Sticky *sticky_rtn); + Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_Sticky *sticky_rtn) } -declare 23 current { +declare 23 { Ttk_Padding Ttk_MakePadding( - short l, short t, short r, short b); + short l, short t, short r, short b) } -declare 24 current { +declare 24 { Ttk_Padding Ttk_UniformPadding( - short borderWidth); + short borderWidth) } -declare 25 current { - Ttk_Padding Ttk_AddPadding(Ttk_Padding pad1, Ttk_Padding pad2); +declare 25 { + Ttk_Padding Ttk_AddPadding(Ttk_Padding pad1, Ttk_Padding pad2) } -declare 26 current { +declare 26 { Ttk_Padding Ttk_RelievePadding( - Ttk_Padding padding, int relief, int n); + Ttk_Padding padding, int relief, int n) } -declare 27 current { - Ttk_Box Ttk_MakeBox(int x, int y, int width, int height); +declare 27 { + Ttk_Box Ttk_MakeBox(int x, int y, int width, int height) } -declare 28 current { - int Ttk_BoxContains(Ttk_Box box, int x, int y); +declare 28 { + int Ttk_BoxContains(Ttk_Box box, int x, int y) } -declare 29 current { - Ttk_Box Ttk_PackBox(Ttk_Box *cavity, int w, int h, Ttk_Side side); +declare 29 { + Ttk_Box Ttk_PackBox(Ttk_Box *cavity, int w, int h, Ttk_Side side) } -declare 30 current { - Ttk_Box Ttk_StickBox(Ttk_Box parcel, int w, int h, Ttk_Sticky sticky); +declare 30 { + Ttk_Box Ttk_StickBox(Ttk_Box parcel, int w, int h, Ttk_Sticky sticky) } -declare 31 current { - Ttk_Box Ttk_AnchorBox(Ttk_Box parcel, int w, int h, Tk_Anchor anchor); +declare 31 { + Ttk_Box Ttk_AnchorBox(Ttk_Box parcel, int w, int h, Tk_Anchor anchor) } -declare 32 current { - Ttk_Box Ttk_PadBox(Ttk_Box b, Ttk_Padding p); +declare 32 { + Ttk_Box Ttk_PadBox(Ttk_Box b, Ttk_Padding p) } -declare 33 current { - Ttk_Box Ttk_ExpandBox(Ttk_Box b, Ttk_Padding p); +declare 33 { + Ttk_Box Ttk_ExpandBox(Ttk_Box b, Ttk_Padding p) } -declare 34 current { +declare 34 { Ttk_Box Ttk_PlaceBox( - Ttk_Box *cavity, int w, int h, Ttk_Side side, Ttk_Sticky sticky); + Ttk_Box *cavity, int w, int h, Ttk_Side side, Ttk_Sticky sticky) } -declare 35 current { - Tcl_Obj *Ttk_NewBoxObj(Ttk_Box box); +declare 35 { + Tcl_Obj *Ttk_NewBoxObj(Ttk_Box box) } # # Utilities. # -declare 40 current { - int Ttk_GetOrientFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *orient); +declare 40 { + int Ttk_GetOrientFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *orient) } diff --git a/generic/ttk/ttkBlink.c b/generic/ttk/ttkBlink.c index 7e46fac..706a871 100644 --- a/generic/ttk/ttkBlink.c +++ b/generic/ttk/ttkBlink.c @@ -49,10 +49,10 @@ static void CursorManagerDeleteProc(ClientData clientData, Tcl_Interp *interp) static CursorManager *GetCursorManager(Tcl_Interp *interp) { static const char *cm_key = "ttk::CursorManager"; - CursorManager *cm = (CursorManager *) Tcl_GetAssocData(interp, cm_key,0); + CursorManager *cm = Tcl_GetAssocData(interp, cm_key,0); if (!cm) { - cm = (CursorManager*)ckalloc(sizeof(*cm)); + cm = ckalloc(sizeof(*cm)); cm->timer = 0; cm->owner = 0; cm->onTime = DEF_CURSOR_ON_TIME; diff --git a/generic/ttk/ttkButton.c b/generic/ttk/ttkButton.c index c00754b..68a6293 100644 --- a/generic/ttk/ttkButton.c +++ b/generic/ttk/ttkButton.c @@ -489,12 +489,15 @@ static int CheckbuttonConfigure(Tcl_Interp *interp, void *recordPtr, int mask) { Checkbutton *checkPtr = recordPtr; - Ttk_TraceHandle *vt = Ttk_TraceVariable( - interp, checkPtr->checkbutton.variableObj, - CheckbuttonVariableChanged, checkPtr); - - if (!vt) { - return TCL_ERROR; + Tcl_Obj *varName = checkPtr->checkbutton.variableObj; + Ttk_TraceHandle *vt = NULL; + + if (varName != NULL && *Tcl_GetString(varName) != '\0') { + vt = Ttk_TraceVariable(interp, varName, + CheckbuttonVariableChanged, checkPtr); + if (!vt) { + return TCL_ERROR; + } } if (BaseConfigure(interp, recordPtr, mask) != TCL_OK){ @@ -502,7 +505,9 @@ CheckbuttonConfigure(Tcl_Interp *interp, void *recordPtr, int mask) return TCL_ERROR; } - Ttk_UntraceVariable(checkPtr->checkbutton.variableTrace); + if (checkPtr->checkbutton.variableTrace) { + Ttk_UntraceVariable(checkPtr->checkbutton.variableTrace); + } checkPtr->checkbutton.variableTrace = vt; return TCL_OK; @@ -548,10 +553,13 @@ CheckbuttonInvokeCommand( else newValue = checkPtr->checkbutton.onValueObj; - if (Tcl_ObjSetVar2(interp, - checkPtr->checkbutton.variableObj, NULL, newValue, - TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) - == NULL) + if (checkPtr->checkbutton.variableObj == NULL || + *Tcl_GetString(checkPtr->checkbutton.variableObj) == '\0') + CheckbuttonVariableChanged(checkPtr, Tcl_GetString(newValue)); + else if (Tcl_ObjSetVar2(interp, + checkPtr->checkbutton.variableObj, NULL, newValue, + TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) + == NULL) return TCL_ERROR; if (WidgetDestroyed(corePtr)) diff --git a/generic/ttk/ttkCache.c b/generic/ttk/ttkCache.c index e3aeaba..0ae2372 100644 --- a/generic/ttk/ttkCache.c +++ b/generic/ttk/ttkCache.c @@ -49,7 +49,7 @@ struct Ttk_ResourceCache_ { */ Ttk_ResourceCache Ttk_CreateResourceCache(Tcl_Interp *interp) { - Ttk_ResourceCache cache = (Ttk_ResourceCache)ckalloc(sizeof(*cache)); + Ttk_ResourceCache cache = ckalloc(sizeof(*cache)); cache->tkwin = NULL; /* initialized later */ cache->interp = interp; @@ -160,7 +160,7 @@ void Ttk_FreeResourceCache(Ttk_ResourceCache cache) } Tcl_DeleteHashTable(&cache->namedColors); - ckfree((ClientData)cache); + ckfree(cache); } /* @@ -270,7 +270,7 @@ static Tcl_Obj *Ttk_Use( } else { Tcl_DecrRefCount(cacheObj); Tcl_SetHashValue(entryPtr, NULL); - Tcl_BackgroundError(interp); + Tcl_BackgroundException(interp, TCL_ERROR); return NULL; } } @@ -341,7 +341,7 @@ Tk_Image Ttk_UseImage(Ttk_ResourceCache cache, Tk_Window tkwin, Tcl_Obj *objPtr) Tcl_SetHashValue(entryPtr, image); if (!image) { - Tcl_BackgroundError(cache->interp); + Tcl_BackgroundException(cache->interp, TCL_ERROR); } return image; diff --git a/generic/ttk/ttkClamTheme.c b/generic/ttk/ttkClamTheme.c index 572f630..15ebcb7 100644 --- a/generic/ttk/ttkClamTheme.c +++ b/generic/ttk/ttkClamTheme.c @@ -12,7 +12,7 @@ * off-by-one error in the end point. This is especially apparent with this * theme. Defining this macro as true handles this case. */ -#if defined(WIN32) && !defined(WIN32_XDRAWLINE_HACK) +#if defined(_WIN32) && !defined(WIN32_XDRAWLINE_HACK) # define WIN32_XDRAWLINE_HACK 1 #else # define WIN32_XDRAWLINE_HACK 0 diff --git a/generic/ttk/ttkClassicTheme.c b/generic/ttk/ttkClassicTheme.c index 2fbcd76..e0886f2 100644 --- a/generic/ttk/ttkClassicTheme.c +++ b/generic/ttk/ttkClassicTheme.c @@ -5,9 +5,7 @@ * */ -#include <tk.h> -#include <X11/Xlib.h> -#include <X11/Xutil.h> +#include "tkInt.h" #include "ttkTheme.h" #define DEFAULT_BORDERWIDTH "2" diff --git a/generic/ttk/ttkDecls.h b/generic/ttk/ttkDecls.h index 8473d36..6701724 100644 --- a/generic/ttk/ttkDecls.h +++ b/generic/ttk/ttkDecls.h @@ -13,7 +13,7 @@ extern const char *TtkInitializeStubs( interp, TTK_VERSION, TTK_STUBS_EPOCH, TTK_STUBS_REVISION) #else -#define Ttk_InitStubs(interp) Tcl_PkgRequire(interp, "Ttk", TTK_VERSION, 0) +#define Ttk_InitStubs(interp) Tcl_PkgRequireEx(interp, "Ttk", TTK_VERSION, 0, NULL) #endif @@ -32,36 +32,36 @@ extern "C" { */ /* 0 */ -TTKAPI Ttk_Theme Ttk_GetTheme(Tcl_Interp *interp, CONST char *name); +TTKAPI Ttk_Theme Ttk_GetTheme(Tcl_Interp *interp, const char *name); /* 1 */ TTKAPI Ttk_Theme Ttk_GetDefaultTheme(Tcl_Interp *interp); /* 2 */ TTKAPI Ttk_Theme Ttk_GetCurrentTheme(Tcl_Interp *interp); /* 3 */ -TTKAPI Ttk_Theme Ttk_CreateTheme(Tcl_Interp *interp, CONST char *name, +TTKAPI Ttk_Theme Ttk_CreateTheme(Tcl_Interp *interp, const char *name, Ttk_Theme parent); /* 4 */ TTKAPI void Ttk_RegisterCleanup(Tcl_Interp *interp, - VOID *deleteData, + void *deleteData, Ttk_CleanupProc *cleanupProc); /* 5 */ TTKAPI int Ttk_RegisterElementSpec(Ttk_Theme theme, - CONST char *elementName, + const char *elementName, Ttk_ElementSpec *elementSpec, - VOID *clientData); + void *clientData); /* 6 */ TTKAPI Ttk_ElementClass * Ttk_RegisterElement(Tcl_Interp *interp, - Ttk_Theme theme, CONST char *elementName, + Ttk_Theme theme, const char *elementName, Ttk_ElementSpec *elementSpec, - VOID *clientData); + void *clientData); /* 7 */ TTKAPI int Ttk_RegisterElementFactory(Tcl_Interp *interp, - CONST char *name, + const char *name, Ttk_ElementFactory factoryProc, - VOID *clientData); + void *clientData); /* 8 */ TTKAPI void Ttk_RegisterLayout(Ttk_Theme theme, - CONST char *className, + const char *className, Ttk_LayoutSpec layoutSpec); /* Slot 9 is reserved */ /* 10 */ @@ -137,17 +137,17 @@ typedef struct TtkStubs { int magic; int epoch; int revision; - const struct TtkStubHooks *hooks; + void *hooks; - Ttk_Theme (*ttk_GetTheme) (Tcl_Interp *interp, CONST char *name); /* 0 */ + Ttk_Theme (*ttk_GetTheme) (Tcl_Interp *interp, const char *name); /* 0 */ Ttk_Theme (*ttk_GetDefaultTheme) (Tcl_Interp *interp); /* 1 */ Ttk_Theme (*ttk_GetCurrentTheme) (Tcl_Interp *interp); /* 2 */ - Ttk_Theme (*ttk_CreateTheme) (Tcl_Interp *interp, CONST char *name, Ttk_Theme parent); /* 3 */ - void (*ttk_RegisterCleanup) (Tcl_Interp *interp, VOID *deleteData, Ttk_CleanupProc *cleanupProc); /* 4 */ - int (*ttk_RegisterElementSpec) (Ttk_Theme theme, CONST char *elementName, Ttk_ElementSpec *elementSpec, VOID *clientData); /* 5 */ - Ttk_ElementClass * (*ttk_RegisterElement) (Tcl_Interp *interp, Ttk_Theme theme, CONST char *elementName, Ttk_ElementSpec *elementSpec, VOID *clientData); /* 6 */ - int (*ttk_RegisterElementFactory) (Tcl_Interp *interp, CONST char *name, Ttk_ElementFactory factoryProc, VOID *clientData); /* 7 */ - void (*ttk_RegisterLayout) (Ttk_Theme theme, CONST char *className, Ttk_LayoutSpec layoutSpec); /* 8 */ + Ttk_Theme (*ttk_CreateTheme) (Tcl_Interp *interp, const char *name, Ttk_Theme parent); /* 3 */ + void (*ttk_RegisterCleanup) (Tcl_Interp *interp, void *deleteData, Ttk_CleanupProc *cleanupProc); /* 4 */ + int (*ttk_RegisterElementSpec) (Ttk_Theme theme, const char *elementName, Ttk_ElementSpec *elementSpec, void *clientData); /* 5 */ + Ttk_ElementClass * (*ttk_RegisterElement) (Tcl_Interp *interp, Ttk_Theme theme, const char *elementName, Ttk_ElementSpec *elementSpec, void *clientData); /* 6 */ + int (*ttk_RegisterElementFactory) (Tcl_Interp *interp, const char *name, Ttk_ElementFactory factoryProc, void *clientData); /* 7 */ + void (*ttk_RegisterLayout) (Ttk_Theme theme, const char *className, Ttk_LayoutSpec layoutSpec); /* 8 */ void (*reserved9)(void); int (*ttk_GetStateSpecFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_StateSpec *spec_rtn); /* 10 */ Tcl_Obj * (*ttk_NewStateSpecObj) (unsigned int onbits, unsigned int offbits); /* 11 */ diff --git a/generic/ttk/ttkDefaultTheme.c b/generic/ttk/ttkDefaultTheme.c index d2deee8..89bf028 100644 --- a/generic/ttk/ttkDefaultTheme.c +++ b/generic/ttk/ttkDefaultTheme.c @@ -4,20 +4,19 @@ * Tk alternate theme, intended to match the MSUE and Gtk's (old) default theme */ -#include <math.h> -#include <string.h> - -#include <tkInt.h> -#include <X11/Xlib.h> -#include <X11/Xutil.h> +#include "tkInt.h" #include "ttkTheme.h" -#if defined(WIN32) +#if defined(_WIN32) static const int WIN32_XDRAWLINE_HACK = 1; #else static const int WIN32_XDRAWLINE_HACK = 0; #endif +#if defined(MAC_OSX_TK) + #define IGNORES_VISUAL +#endif + #define BORDERWIDTH 2 #define SCROLLBAR_WIDTH 14 #define MIN_THUMB_SIZE 8 @@ -209,6 +208,9 @@ void TtkFillArrow( ArrowPoints(b, dir, points); XFillPolygon(display, d, gc, points, 3, Convex, CoordModeOrigin); XDrawLines(display, d, gc, points, 4, CoordModeOrigin); + + /* Work around bug [77527326e5] - ttk artifacts on Ubuntu */ + XDrawPoint(display, d, gc, points[2].x, points[2].y); } /*public*/ @@ -218,6 +220,9 @@ void TtkDrawArrow( XPoint points[4]; ArrowPoints(b, dir, points); XDrawLines(display, d, gc, points, 4, CoordModeOrigin); + + /* Work around bug [77527326e5] - ttk artifacts on Ubuntu */ + XDrawPoint(display, d, gc, points[2].x, points[2].y); } /* @@ -504,7 +509,7 @@ static void IndicatorElementDraw( XGCValues gcValues; GC copyGC; unsigned long imgColors[8]; - XImage *img; + XImage *img = NULL; Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &padding); b = Ttk_PadBox(b, padding); @@ -544,15 +549,48 @@ static void IndicatorElementDraw( /* * Create a scratch buffer to store the image: */ - img = XGetImage(display,d, 0, 0, - (unsigned int)spec->width, (unsigned int)spec->height, - AllPlanes, ZPixmap); - if (img == NULL) + +#if defined(IGNORES_VISUAL) + + /* + * Platforms which ignore the VisualInfo can use XCreateImage to get the + * scratch image. This is essential on macOS, where it is not safe to call + * XGetImage in a display procedure. + */ + + img = XCreateImage(display, NULL, 32, ZPixmap, 0, NULL, + (unsigned int)spec->width, (unsigned int)spec->height, + 0, 0); +#else + + /* + * This trick allows creating the scratch XImage without having to + * construct a VisualInfo. + */ + + img = XGetImage(display, d, 0, 0, + (unsigned int)spec->width, (unsigned int)spec->height, + AllPlanes, ZPixmap); +#endif + + if (img == NULL) { + return; + } + +#if defined(IGNORES_VISUAL) + + img->data = ckalloc(img->bytes_per_line * img->height); + if (img->data == NULL) { + XDestroyImage(img); return; + } + +#endif /* - * Create the image, painting it into an XImage one pixel at a time. + * Create the image, painting it into the XImage one pixel at a time. */ + index = Ttk_StateTableLookup(spec->map, state); for (iy=0 ; iy<spec->height ; iy++) { for (ix=0 ; ix<spec->width ; ix++) { @@ -562,18 +600,31 @@ static void IndicatorElementDraw( } /* - * Copy onto our target drawable surface. + * Copy the image onto our target drawable surface. */ + memset(&gcValues, 0, sizeof(gcValues)); copyGC = Tk_GetGC(tkwin, 0, &gcValues); - TkPutImage(NULL, 0, display, d, copyGC, img, 0, 0, b.x, b.y, spec->width, spec->height); /* * Tidy up. */ + Tk_FreeGC(display, copyGC); + + /* + * Protect against the possibility that some future platform might + * not use the Tk memory manager in its implementation of XDestroyImage, + * even though that would be an extremely strange thing to do. + */ + +#if defined(IGNORES_VISUAL) + ckfree(img->data); + img->data = NULL; +#endif + XDestroyImage(img); } @@ -722,8 +773,8 @@ static void MenubuttonArrowElementDraw( int width = 0, height = 0; Tk_GetPixelsFromObj(NULL, tkwin, arrow->sizeObj, &size); - Tcl_GetIndexFromObj(NULL, arrow->directionObj, directionStrings, - ""/*message*/, 0/*flags*/, &postDirection); + Tcl_GetIndexFromObjStruct(NULL, arrow->directionObj, directionStrings, + sizeof(char *), ""/*message*/, 0/*flags*/, &postDirection); /* ... this might not be such a great idea ... */ switch (postDirection) { diff --git a/generic/ttk/ttkElements.c b/generic/ttk/ttkElements.c index 22af1d6..5c95dba 100644 --- a/generic/ttk/ttkElements.c +++ b/generic/ttk/ttkElements.c @@ -1145,7 +1145,7 @@ static void TabElementDraw( Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC), pts, 6, Convex, CoordModeOrigin); -#ifndef WIN32 +#ifndef _WIN32 /* * Account for whether XDrawLines draws endpoints by platform */ @@ -1275,7 +1275,7 @@ void TtkElements_Init(Tcl_Interp *interp) /* * Register "default" as a user-loadable theme (for now): */ - Tcl_PkgProvide(interp, "ttk::theme::default", TTK_VERSION); + Tcl_PkgProvideEx(interp, "ttk::theme::default", TTK_VERSION, NULL); } /*EOF*/ diff --git a/generic/ttk/ttkEntry.c b/generic/ttk/ttkEntry.c index 82504a1..1579a32 100644 --- a/generic/ttk/ttkEntry.c +++ b/generic/ttk/ttkEntry.c @@ -8,11 +8,7 @@ * Copyright (c) 2004 Joe English */ -#include <string.h> -#include <stdio.h> -#include <tkInt.h> -#include <X11/Xatom.h> - +#include "tkInt.h" #include "ttkTheme.h" #include "ttkWidget.h" @@ -282,15 +278,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'; @@ -336,7 +333,8 @@ EntryFetchSelection( const char *string; const char *selStart, *selEnd; - if (entryPtr->entry.selectFirst < 0 || !entryPtr->entry.exportSelection) { + if (entryPtr->entry.selectFirst < 0 || (!entryPtr->entry.exportSelection) + || Tcl_IsSafe(entryPtr->core.interp)) { return -1; } string = entryPtr->entry.displayString; @@ -371,11 +369,12 @@ static void EntryLostSelection(ClientData clientData) /* EntryOwnSelection -- * Assert ownership of the PRIMARY selection, - * if -exportselection set and selection is present. + * if -exportselection set and selection is present and interp is unsafe. */ static void EntryOwnSelection(Entry *entryPtr) { if (entryPtr->entry.exportSelection + && (!Tcl_IsSafe(entryPtr->core.interp)) && !(entryPtr->core.flags & GOT_SELECTION)) { Tk_OwnSelection(entryPtr->core.tkwin, XA_PRIMARY, EntryLostSelection, (ClientData) entryPtr); @@ -405,7 +404,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 +428,7 @@ ExpandPercents( */ ++template; /* skip over % */ if (*template != '\0') { - template += Tcl_UtfToUniChar(template, &ch); + template += TkUtfToUniChar(template, &ch); } else { ch = '%'; } @@ -479,7 +478,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; @@ -652,7 +651,7 @@ static void EntryRevalidateBG(Entry *entryPtr, VREASON reason) { Tcl_Interp *interp = entryPtr->core.interp; if (EntryRevalidate(interp, entryPtr, reason) == TCL_ERROR) { - Tcl_BackgroundError(interp); + Tcl_BackgroundException(interp, TCL_ERROR); } } @@ -758,8 +757,8 @@ static int EntrySetValue(Entry *entryPtr, const char *value) Tcl_GetString(entryPtr->entry.textVariableObj); if (textVarName && *textVarName) { entryPtr->core.flags |= SYNCING_VARIABLE; - value = Tcl_SetVar(entryPtr->core.interp, textVarName, - value, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG); + value = Tcl_SetVar2(entryPtr->core.interp, textVarName, + NULL, value, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG); entryPtr->core.flags &= ~SYNCING_VARIABLE; if (!value || WidgetDestroyed(&entryPtr->core)) { return TCL_ERROR; @@ -786,7 +785,7 @@ static void EntryTextVariableTrace(void *recordPtr, const char *value) } if (entryPtr->core.flags & SYNCING_VARIABLE) { - /* Trace was fired due to Tcl_SetVar call in EntrySetValue. + /* Trace was fired due to Tcl_SetVar2 call in EntrySetValue. * Don't do anything. */ return; @@ -976,7 +975,7 @@ static int EntryConfigure(Tcl_Interp *interp, void *recordPtr, int mask) Ttk_TraceHandle *vt = 0; if (mask & TEXTVAR_CHANGED) { - if (textVarName && *Tcl_GetString(textVarName)) { + if (textVarName && *Tcl_GetString(textVarName) != '\0') { vt = Ttk_TraceVariable(interp, textVarName,EntryTextVariableTrace,entryPtr); if (!vt) return TCL_ERROR; @@ -998,7 +997,8 @@ static int EntryConfigure(Tcl_Interp *interp, void *recordPtr, int mask) /* Claim the selection, in case we've suddenly started exporting it. */ - if (entryPtr->entry.exportSelection && entryPtr->entry.selectFirst != -1) { + if (entryPtr->entry.exportSelection && (entryPtr->entry.selectFirst != -1) + && (!Tcl_IsSafe(entryPtr->core.interp))) { EntryOwnSelection(entryPtr); } @@ -1179,13 +1179,13 @@ static void EntryDisplay(void *clientData, Drawable d) textarea = Ttk_ClientRegion(entryPtr->core.layout, "textarea"); showCursor = - (entryPtr->core.flags & CURSOR_ON) != 0 + (entryPtr->core.flags & CURSOR_ON) && EntryEditable(entryPtr) && entryPtr->entry.insertPos >= leftIndex && entryPtr->entry.insertPos <= rightIndex ; showSelection = - (entryPtr->core.state & TTK_STATE_DISABLED) == 0 + !(entryPtr->core.state & TTK_STATE_DISABLED) && selFirst > -1 && selLast > leftIndex && selFirst <= rightIndex @@ -1240,6 +1240,7 @@ static void EntryDisplay(void *clientData, Drawable d) /* Draw cursor: */ if (showCursor) { + Ttk_Box field = Ttk_ClientRegion(entryPtr->core.layout, "field"); int cursorX = EntryCharPosition(entryPtr, entryPtr->entry.insertPos), cursorY = entryPtr->entry.layoutY, cursorHeight = entryPtr->entry.layoutHeight, @@ -1253,10 +1254,16 @@ static void EntryDisplay(void *clientData, Drawable d) /* @@@ should: maybe: SetCaretPos even when blinked off */ Tk_SetCaretPos(tkwin, cursorX, cursorY, cursorHeight); - gc = EntryGetGC(entryPtr, es.insertColorObj, clipRegion); + cursorX -= cursorWidth/2; + if (cursorX < field.x) { + cursorX = field.x; + } else if (cursorX + cursorWidth > field.x + field.width) { + cursorX = field.x + field.width - cursorWidth; + } + + gc = EntryGetGC(entryPtr, es.insertColorObj, NULL); XFillRectangle(Tk_Display(tkwin), d, gc, - cursorX-cursorWidth/2, cursorY, cursorWidth, cursorHeight); - XSetClipMask(Tk_Display(tkwin), gc, None); + cursorX, cursorY, cursorWidth, cursorHeight); Tk_FreeGC(Tk_Display(tkwin), gc); } @@ -1314,8 +1321,8 @@ EntryIndex( int *indexPtr) /* Return value */ { # define EntryWidth(e) (Tk_Width(entryPtr->core.tkwin)) /* Not Right */ - int length; - const char *string = Tcl_GetStringFromObj(indexObj, &length); + const char *string = Tcl_GetString(indexObj); + size_t length = indexObj->length; if (strncmp(string, "end", length) == 0) { *indexPtr = entryPtr->entry.numChars; @@ -1327,9 +1334,10 @@ EntryIndex( *indexPtr = entryPtr->entry.xscroll.last; } else if (strncmp(string, "sel.", 4) == 0) { if (entryPtr->entry.selectFirst < 0) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "selection isn't in widget ", - Tk_PathName(entryPtr->core.tkwin), NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "selection isn't in widget %s", + Tk_PathName(entryPtr->core.tkwin))); + Tcl_SetErrorCode(interp, "TTK", "ENTRY", "NO_SELECTION", NULL); return TCL_ERROR; } if (strncmp(string, "sel.first", length) == 0) { @@ -1354,6 +1362,7 @@ EntryIndex( *indexPtr = Tk_PointToChar(entryPtr->entry.textLayout, x - entryPtr->entry.layoutX, 0); + TtkUpdateScrollInfo(entryPtr->entry.xscrollHandle); if (*indexPtr < entryPtr->entry.xscroll.first) { *indexPtr = entryPtr->entry.xscroll.first; } @@ -1381,8 +1390,9 @@ EntryIndex( return TCL_OK; badIndex: - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "bad entry index \"", string, "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad entry index \"%s\"", string)); + Tcl_SetErrorCode(interp, "TTK", "ENTRY", "INDEX", NULL); return TCL_ERROR; } @@ -1457,7 +1467,7 @@ EntryGetCommand( Tcl_WrongNumArgs(interp, 2, objv, NULL); return TCL_ERROR; } - Tcl_SetResult(interp, entryPtr->entry.string, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_NewStringObj(entryPtr->entry.string, -1)); return TCL_OK; } @@ -1647,7 +1657,7 @@ static int EntryXViewCommand( if (EntryIndex(interp, entryPtr, objv[2], &newFirst) != TCL_OK) { return TCL_ERROR; } - TtkScrollTo(entryPtr->entry.xscrollHandle, newFirst); + TtkScrollTo(entryPtr->entry.xscrollHandle, newFirst, 1); return TCL_OK; } return TtkScrollviewCommand(interp, objc, objv, entryPtr->entry.xscrollHandle); @@ -1691,6 +1701,16 @@ static WidgetSpec EntryWidgetSpec = { }; /*------------------------------------------------------------------------ + * Named indices for the combobox "current" command + */ +static const char *const comboboxCurrentIndexNames[] = { + "end", NULL +}; +enum comboboxCurrentIndices { + INDEX_END +}; + +/*------------------------------------------------------------------------ * +++ Combobox widget record. */ @@ -1791,15 +1811,42 @@ static int ComboboxCurrentCommand( Tcl_SetObjResult(interp, Tcl_NewIntObj(currentIndex)); return TCL_OK; } else if (objc == 3) { - if (Tcl_GetIntFromObj(interp, objv[2], ¤tIndex) != TCL_OK) { - return TCL_ERROR; - } - if (currentIndex < 0 || currentIndex >= nValues) { - Tcl_AppendResult(interp, - "Index ", Tcl_GetString(objv[2]), " out of range", - NULL); - return TCL_ERROR; - } + int result, index; + + result = Tcl_GetIndexFromObj(NULL, objv[2], comboboxCurrentIndexNames, + "", 0, &index); + if (result == TCL_OK) { + + /* + * The index is one of the named indices. + */ + + switch (index) { + case INDEX_END: + /* "end" index */ + currentIndex = nValues - 1; + break; + } + } else { + + /* + * The index should be just an integer. + */ + + if (Tcl_GetIntFromObj(NULL, objv[2], ¤tIndex) != TCL_OK) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "Incorrect index %s", Tcl_GetString(objv[2]))); + Tcl_SetErrorCode(interp, "TTK", "COMBOBOX", "IDX_VALUE", NULL); + return TCL_ERROR; + } + + if (currentIndex < 0 || currentIndex >= nValues) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "Index %s out of range", Tcl_GetString(objv[2]))); + Tcl_SetErrorCode(interp, "TTK", "COMBOBOX", "IDX_RANGE", NULL); + return TCL_ERROR; + } + } cbPtr->combobox.currentIndex = currentIndex; diff --git a/generic/ttk/ttkFrame.c b/generic/ttk/ttkFrame.c index 7860024..3e50a7f 100644 --- a/generic/ttk/ttkFrame.c +++ b/generic/ttk/ttkFrame.c @@ -206,10 +206,9 @@ int TtkGetLabelAnchorFromObj( error: if (interp) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, - "Bad label anchor specification ", Tcl_GetString(objPtr), - NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "Bad label anchor specification %s", Tcl_GetString(objPtr))); + Tcl_SetErrorCode(interp, "TTK", "LABEL", "ANCHOR", NULL); } return TCL_ERROR; } diff --git a/generic/ttk/ttkGenStubs.tcl b/generic/ttk/ttkGenStubs.tcl index 5b374e6..8047e3f 100644 --- a/generic/ttk/ttkGenStubs.tcl +++ b/generic/ttk/ttkGenStubs.tcl @@ -5,23 +5,17 @@ # # # 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.20 +# SOURCE: tcl/tools/genStubs.tcl, revision 1.44 # # CHANGES: -# + Remove xxx_TCL_DECLARED #ifdeffery -# + Use application-defined storage class specifier instead of "EXTERN" -# + Add "epoch" and "revision" fields to stubs table record -# + Remove dead code related to USE_*_STUB_PROCS (emitStubs, makeStub) # + Second argument to "declare" is used as a status guard # instead of a platform guard. -# + Use void (*reserved$i)(void) = 0 instead of void *reserved$i = NULL -# for unused stub entries, in case pointer-to-function and -# pointer-to-object are different sizes. # + Allow trailing semicolon in function declarations -# + stubs table is const-qualified # namespace eval genStubs { @@ -48,9 +42,9 @@ namespace eval genStubs { # scspec -- # # Storage class specifier for external function declarations. - # Normally "extern", may be set to something like XYZAPI + # Normally "EXTERN", may be set to something like XYZAPI # - variable scspec "extern" + variable scspec "EXTERN" # epoch, revision -- # @@ -58,7 +52,7 @@ namespace eval genStubs { # (@@@TODO: should be an array mapping interface names -> numbers) # - variable epoch 0 + variable epoch {} variable revision 0 # hooks -- @@ -179,6 +173,9 @@ proc genStubs::hooks {names} { # decl The C function declaration, or {} for an undefined # entry. # +# Results: +# None. + proc genStubs::declare {args} { variable stubs variable curName @@ -201,7 +198,6 @@ proc genStubs::declare {args} { if {[info exists stubs($curName,decl,$index)]} { puts stderr "Duplicate entry: $index" } - regsub -all const $decl CONST decl regsub -all "\[ \t\n\]+" [string trim $decl] " " decl set decl [parseDecl $decl] @@ -288,22 +284,48 @@ proc genStubs::rewriteFile {file text} { # Results: # Returns the original text inside an appropriate #ifdef. -proc genStubs::addPlatformGuard {plat text} { +proc genStubs::addPlatformGuard {plat iftxt {eltxt {}}} { + set text "" switch $plat { win { - return "#ifdef __WIN32__\n${text}#endif /* __WIN32__ */\n" + append text "#ifdef _WIN32 /* WIN */\n${iftxt}" + if {$eltxt ne ""} { + append text "#else /* WIN */\n${eltxt}" + } + append text "#endif /* WIN */\n" } unix { - return "#if !defined(__WIN32__) /* UNIX */\n${text}#endif /* UNIX */\n" + 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 { - return "#ifdef MAC_OSX_TCL\n${text}#endif /* MAC_OSX_TCL */\n" + append text "#ifdef MAC_OSX_TCL /* MACOSX */\n${iftxt}" + if {$eltxt ne ""} { + append text "#else /* MACOSX */\n${eltxt}" + } + append text "#endif /* MACOSX */\n" } aqua { - return "#ifdef MAC_OSX_TK\n${text}#endif /* MAC_OSX_TK */\n" + append text "#ifdef MAC_OSX_TK /* AQUA */\n${iftxt}" + if {$eltxt ne ""} { + append text "#else /* AQUA */\n${eltxt}" + } + append text "#endif /* AQUA */\n" } x11 { - return "#if !(defined(__WIN32__) || defined(MAC_OSX_TK)) /* X11 */\n${text}#endif /* X11 */\n" + 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 @@ -311,7 +333,9 @@ proc genStubs::addPlatformGuard {plat text} { # genStubs::emitSlots -- # -# Generate the stub table slots for the given interface. +# 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. @@ -322,6 +346,7 @@ proc genStubs::addPlatformGuard {plat text} { proc genStubs::emitSlots {name textVar} { upvar $textVar text + forAllStubs $name makeSlot noGuard text {" void (*reserved$i)(void);\n"} return } @@ -350,7 +375,7 @@ proc genStubs::parseDecl {decl} { return } set rtype [string trim $rtype] - if {$args == ""} { + if {$args eq ""} { return [list $rtype $fname {}] } foreach arg [split $args ,] { @@ -398,14 +423,14 @@ proc genStubs::parseDecl {decl} { proc genStubs::parseArg {arg} { if {![regexp {^(.+[ ][*]*)([^][ *]+)(\[\])?$} $arg all type name array]} { - if {$arg == "void"} { + if {$arg eq "void"} { return $arg } else { return } } set result [list [string trim $type] $name] - if {$array != ""} { + if {$array ne ""} { lappend result $array } return $result @@ -428,9 +453,6 @@ proc genStubs::makeDecl {name decl index} { lassign $decl rtype fname args append text "/* $index */\n" - if {$rtype != "void"} { - regsub -all void $rtype VOID rtype - } set line "$scspec $rtype" set count [expr {2 - ([string length $line] / 8)}] append line [string range "\t\t\t" 0 $count] @@ -439,7 +461,7 @@ proc genStubs::makeDecl {name decl index} { append line " " set pad 0 } - if {$args == ""} { + if {$args eq ""} { append line $fname append text $line append text ";\n" @@ -447,10 +469,9 @@ proc genStubs::makeDecl {name decl index} { } append line $fname - regsub -all void $args VOID args set arg1 [lindex $args 0] switch -exact $arg1 { - VOID { + void { append line "(void)" } TCL_VARARGS { @@ -518,7 +539,7 @@ proc genStubs::makeMacro {name decl index} { append lfname [string range $fname 1 end] set text "#define $fname \\\n\t(" - if {$args == ""} { + if {$args eq ""} { append text "*" } append text "${name}StubsPtr->$lfname)" @@ -545,19 +566,18 @@ proc genStubs::makeSlot {name decl index} { append lfname [string range $fname 1 end] set text " " - if {$rtype != "void"} { - regsub -all void $rtype VOID rtype - } - if {$args == ""} { + if {$args eq ""} { append text $rtype " *" $lfname "; /* $index */\n" return $text } - append text $rtype " (*" $lfname ") " - - regsub -all void $args VOID args + 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 { + void { append text "(void)" } TCL_VARARGS { @@ -603,7 +623,7 @@ proc genStubs::makeSlot {name decl index} { # Returns the formatted declaration string. proc genStubs::makeInit {name decl index} { - if {[lindex $decl 2] == ""} { + if {[lindex $decl 2] eq ""} { append text " &" [lindex $decl 1] ", /* " $index " */\n" } else { append text " " [lindex $decl 1] ", /* " $index " */\n" @@ -633,7 +653,7 @@ proc genStubs::makeInit {name decl index} { # None. proc genStubs::forAllStubs {name slotProc guardProc textVar - {skipString {"/* Slot $i is reserved */\n"}}} { + {skipString {"/* Slot $i is reserved */\n"}}} { variable stubs upvar $textVar text @@ -740,17 +760,19 @@ proc genStubs::emitHeader {name} { set capName [string toupper [string index $name 0]] append capName [string range $name 1 end] - set CAPName [string toupper $name] - append text "\n" - append text "#define ${CAPName}_STUBS_EPOCH $epoch\n" - append text "#define ${CAPName}_STUBS_REVISION $revision\n" + 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 ${capName}StubHooks {\n" + append text "\ntypedef struct {\n" foreach hook $hooks($name) { set capHook [string toupper [string index $hook 0]] append capHook [string range $hook 1 end] @@ -760,9 +782,15 @@ proc genStubs::emitHeader {name} { } append text "\ntypedef struct ${capName}Stubs {\n" append text " int magic;\n" - append text " int epoch;\n" - append text " int revision;\n" - append text " const struct ${capName}StubHooks *hooks;\n\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 @@ -792,13 +820,11 @@ proc genStubs::emitInit {name textVar} { variable hooks variable interfaces variable epoch - variable revision upvar $textVar text - set root 1 + set capName [string toupper [string index $name 0]] append capName [string range $name 1 end] - set CAPName [string toupper $name] if {[info exists hooks($name)]} { append text "\nstatic const ${capName}StubHooks ${name}StubHooks = \{\n" @@ -811,21 +837,23 @@ proc genStubs::emitInit {name textVar} { } foreach intf [array names interfaces] { if {[info exists hooks($intf)]} { - if {0<=[lsearch -exact $hooks($intf) $name]} { + if {[lsearch -exact $hooks($intf) $name] >= 0} { set root 0 - break; + break } } } - if {$root} { - append text "\nconst ${capName}Stubs ${name}Stubs = \{\n" - } else { - append text "\nstatic const ${capName}Stubs ${name}Stubs = \{\n" + 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" } - append text " TCL_STUB_MAGIC,\n" - append text " ${CAPName}_STUBS_EPOCH,\n" - append text " ${CAPName}_STUBS_REVISION,\n" if {[info exists hooks($name)]} { append text " &${name}StubHooks,\n" } else { diff --git a/generic/ttk/ttkImage.c b/generic/ttk/ttkImage.c index c435a50..e403e2d 100644 --- a/generic/ttk/ttkImage.c +++ b/generic/ttk/ttkImage.c @@ -75,7 +75,7 @@ TtkGetImageSpecEx(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, int i = 0, n = 0, objc; Tcl_Obj **objv; - imageSpec = (Ttk_ImageSpec *)ckalloc(sizeof(*imageSpec)); + imageSpec = ckalloc(sizeof(*imageSpec)); imageSpec->baseImage = 0; imageSpec->mapCount = 0; imageSpec->states = 0; @@ -89,16 +89,17 @@ TtkGetImageSpecEx(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, if ((objc % 2) != 1) { if (interp) { - Tcl_SetResult(interp, + Tcl_SetObjResult(interp, Tcl_NewStringObj( "image specification must contain an odd number of elements", - TCL_STATIC); + -1)); + Tcl_SetErrorCode(interp, "TTK", "IMAGE", "SPEC", NULL); } goto error; } n = (objc - 1) / 2; - imageSpec->states = (Ttk_StateSpec*)ckalloc(n * sizeof(Ttk_StateSpec)); - imageSpec->images = (Tk_Image*)ckalloc(n * sizeof(Tk_Image *)); + imageSpec->states = ckalloc(n * sizeof(Ttk_StateSpec)); + imageSpec->images = ckalloc(n * sizeof(Tk_Image *)); /* Get base image: */ @@ -147,10 +148,10 @@ void TtkFreeImageSpec(Ttk_ImageSpec *imageSpec) } if (imageSpec->baseImage) { Tk_FreeImage(imageSpec->baseImage); } - if (imageSpec->states) { ckfree((ClientData)imageSpec->states); } - if (imageSpec->images) { ckfree((ClientData)imageSpec->images); } + if (imageSpec->states) { ckfree(imageSpec->states); } + if (imageSpec->images) { ckfree(imageSpec->images); } - ckfree((ClientData)imageSpec); + ckfree(imageSpec); } /* TtkSelectImage -- @@ -354,7 +355,9 @@ Ttk_CreateImageElement( int i; if (objc <= 0) { - Tcl_AppendResult(interp, "Must supply a base image", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "Must supply a base image", -1)); + Tcl_SetErrorCode(interp, "TTK", "IMAGE", "BASE", NULL); return TCL_ERROR; } @@ -363,7 +366,7 @@ Ttk_CreateImageElement( return TCL_ERROR; } - imageData = (ImageData*)ckalloc(sizeof(*imageData)); + imageData = ckalloc(sizeof(*imageData)); imageData->imageSpec = imageSpec; imageData->minWidth = imageData->minHeight = -1; imageData->sticky = TTK_FILL_BOTH; @@ -377,9 +380,9 @@ Ttk_CreateImageElement( int option; if (i == objc - 1) { - Tcl_AppendResult(interp, - "Value for ", Tcl_GetString(objv[i]), " missing", - NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "Value for %s missing", Tcl_GetString(objv[i]))); + Tcl_SetErrorCode(interp, "TTK", "IMAGE", "VALUE", NULL); goto error; } @@ -391,13 +394,17 @@ Ttk_CreateImageElement( } #endif - if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings, - "option", 0, &option) != TCL_OK) { goto error; } + if (Tcl_GetIndexFromObjStruct(interp, objv[i], optionStrings, + sizeof(char *), "option", 0, &option) != TCL_OK) { + goto error; + } switch (option) { case O_BORDER: if (Ttk_GetBorderFromObj(interp, objv[i+1], &imageData->border) - != TCL_OK) { goto error; } + != TCL_OK) { + goto error; + } if (!padding_specified) { imageData->padding = imageData->border; } diff --git a/generic/ttk/ttkInit.c b/generic/ttk/ttkInit.c index 78676c6..dc6e994 100644 --- a/generic/ttk/ttkInit.c +++ b/generic/ttk/ttkInit.c @@ -21,8 +21,8 @@ int Ttk_GetButtonDefaultStateFromObj( Tcl_Interp *interp, Tcl_Obj *objPtr, int *statePtr) { *statePtr = TTK_BUTTON_DEFAULT_DISABLED; - return Tcl_GetIndexFromObj(interp, objPtr, - ttkDefaultStrings, "default state", 0, statePtr); + return Tcl_GetIndexFromObjStruct(interp, objPtr, ttkDefaultStrings, + sizeof(char *), "default state", 0, statePtr); } /* @@ -38,8 +38,8 @@ int Ttk_GetCompoundFromObj( Tcl_Interp *interp, Tcl_Obj *objPtr, int *statePtr) { *statePtr = TTK_COMPOUND_NONE; - return Tcl_GetIndexFromObj(interp, objPtr, - ttkCompoundStrings, "compound layout", 0, statePtr); + return Tcl_GetIndexFromObjStruct(interp, objPtr, ttkCompoundStrings, + sizeof(char *), "compound layout", 0, statePtr); } /* @@ -54,8 +54,8 @@ int Ttk_GetOrientFromObj( Tcl_Interp *interp, Tcl_Obj *objPtr, int *resultPtr) { *resultPtr = TTK_ORIENT_HORIZONTAL; - return Tcl_GetIndexFromObj(interp, objPtr, - ttkOrientStrings, "orientation", 0, resultPtr); + return Tcl_GetIndexFromObjStruct(interp, objPtr, ttkOrientStrings, + sizeof(char *), "orientation", 0, resultPtr); } /* @@ -65,18 +65,18 @@ int Ttk_GetOrientFromObj( static const char *ttkStateStrings[] = { "normal", "readonly", "disabled", "active", NULL }; -enum { +enum { TTK_COMPAT_STATE_NORMAL, TTK_COMPAT_STATE_READONLY, TTK_COMPAT_STATE_DISABLED, TTK_COMPAT_STATE_ACTIVE }; -/* TtkCheckStateOption -- +/* TtkCheckStateOption -- * Handle -state compatibility option. * - * NOTE: setting -state disabled / -state enabled affects the - * widget state, but the internal widget state does *not* affect + * NOTE: setting -state disabled / -state enabled affects the + * widget state, but the internal widget state does *not* affect * the value of the -state option. * This option is present for compatibility only. */ @@ -86,7 +86,8 @@ void TtkCheckStateOption(WidgetCore *corePtr, Tcl_Obj *objPtr) unsigned all = TTK_STATE_DISABLED|TTK_STATE_READONLY|TTK_STATE_ACTIVE; # define SETFLAGS(f) TtkWidgetChangeState(corePtr, f, all^f) - (void)Tcl_GetIndexFromObj(NULL,objPtr,ttkStateStrings,"",0,&stateOption); + (void)Tcl_GetIndexFromObjStruct(NULL, objPtr, ttkStateStrings, + sizeof(char *), "", 0, &stateOption); switch (stateOption) { case TTK_COMPAT_STATE_NORMAL: default: @@ -174,7 +175,7 @@ int TtkGetOptionValue( * type name dbName dbClass default objOffset intOffset flags clientData mask */ -/* public */ +/* public */ Tk_OptionSpec ttkCoreOptionSpecs[] = { {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", NULL, diff --git a/generic/ttk/ttkLabel.c b/generic/ttk/ttkLabel.c index e2dd0b1..3cebc14 100644 --- a/generic/ttk/ttkLabel.c +++ b/generic/ttk/ttkLabel.c @@ -6,8 +6,7 @@ * */ -#include <tcl.h> -#include <tkInt.h> +#include "tkInt.h" #include "ttkTheme.h" /*---------------------------------------------------------------------- diff --git a/generic/ttk/ttkLayout.c b/generic/ttk/ttkLayout.c index 04dd86f..2512c4b 100644 --- a/generic/ttk/ttkLayout.c +++ b/generic/ttk/ttkLayout.c @@ -326,8 +326,9 @@ int Ttk_GetPaddingFromObj( if (padc > 4) { if (interp) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "Wrong #elements in padding spec", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "Wrong #elements in padding spec", -1)); + Tcl_SetErrorCode(interp, "TTK", "VALUE", "PADDING", NULL); } goto error; } @@ -363,8 +364,9 @@ int Ttk_GetBorderFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Ttk_Padding *pad) if (padc > 4) { if (interp) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "Wrong #elements in border spec", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "Wrong #elements in padding spec", -1)); + Tcl_SetErrorCode(interp, "TTK", "VALUE", "BORDER", NULL); } goto error; } @@ -476,11 +478,10 @@ int Ttk_GetStickyFromObj( case 's': case 'S': sticky |= TTK_STICK_S; break; default: if (interp) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, - "Bad -sticky specification ", - Tcl_GetString(objPtr), - NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "Bad -sticky specification %s", + Tcl_GetString(objPtr))); + Tcl_SetErrorCode(interp, "TTK", "VALUE", "STICKY", NULL); } return TCL_ERROR; } @@ -524,7 +525,7 @@ struct Ttk_LayoutNode_ static Ttk_LayoutNode *Ttk_NewLayoutNode( unsigned flags, Ttk_ElementClass *elementClass) { - Ttk_LayoutNode *node = (Ttk_LayoutNode*)ckalloc(sizeof(*node)); + Ttk_LayoutNode *node = ckalloc(sizeof(*node)); node->flags = flags; node->eclass = elementClass; @@ -540,7 +541,7 @@ static void Ttk_FreeLayoutNode(Ttk_LayoutNode *node) while (node) { Ttk_LayoutNode *next = node->next; Ttk_FreeLayoutNode(node->child); - ckfree((ClientData)node); + ckfree(node); node = next; } } @@ -557,7 +558,7 @@ struct Ttk_TemplateNode_ { static Ttk_TemplateNode *Ttk_NewTemplateNode(const char *name, unsigned flags) { - Ttk_TemplateNode *op = (Ttk_TemplateNode*)ckalloc(sizeof(*op)); + Ttk_TemplateNode *op = ckalloc(sizeof(*op)); op->name = ckalloc(strlen(name) + 1); strcpy(op->name, name); op->flags = flags; op->next = op->child = 0; @@ -570,7 +571,7 @@ void Ttk_FreeLayoutTemplate(Ttk_LayoutTemplate op) Ttk_LayoutTemplate next = op->next; Ttk_FreeLayoutTemplate(op->child); ckfree(op->name); - ckfree((ClientData)op); + ckfree(op); op = next; } } @@ -635,25 +636,25 @@ Ttk_LayoutTemplate Ttk_ParseLayoutTemplate(Tcl_Interp *interp, Tcl_Obj *objPtr) if (optName[0] != '-') break; - if (Tcl_GetIndexFromObj( - interp, objv[i], optStrings, "option", 0, &option) + if (Tcl_GetIndexFromObjStruct(interp, objv[i], optStrings, + sizeof(char *), "option", 0, &option) != TCL_OK) { goto error; } if (++i >= objc) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, - "Missing value for option ",Tcl_GetString(objv[i-1]), - NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "Missing value for option %s", + Tcl_GetString(objv[i-1]))); + Tcl_SetErrorCode(interp, "TTK", "VALUE", "LAYOUT", NULL); goto error; } switch (option) { case OP_SIDE: /* <<NOTE-PACKSIDE>> */ - if (Tcl_GetIndexFromObj(interp, objv[i], packSideStrings, - "side", 0, &value) != TCL_OK) + if (Tcl_GetIndexFromObjStruct(interp, objv[i], packSideStrings, + sizeof(char *), "side", 0, &value) != TCL_OK) { goto error; } @@ -701,6 +702,8 @@ Ttk_LayoutTemplate Ttk_ParseLayoutTemplate(Tcl_Interp *interp, Tcl_Obj *objPtr) if (childSpec) { tail->child = Ttk_ParseLayoutTemplate(interp, childSpec); if (!tail->child) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf("Invalid -children value")); + Tcl_SetErrorCode(interp, "TTK", "VALUE", "CHILDREN", NULL); goto error; } } @@ -790,7 +793,7 @@ Tcl_Obj *Ttk_UnparseLayoutTemplate(Ttk_TemplateNode *node) int side = 0; unsigned sideFlags = flags & _TTK_MASK_PACK; - while ((sideFlags & TTK_PACK_LEFT) == 0) { + while (!(sideFlags & TTK_PACK_LEFT)) { ++side; sideFlags >>= 1; } @@ -799,9 +802,11 @@ Tcl_Obj *Ttk_UnparseLayoutTemplate(Ttk_TemplateNode *node) } } - /* In Ttk_ParseLayoutTemplate, default -sticky is "nsew", - * so always include this even if no sticky bits are set. + /* + * In Ttk_ParseLayoutTemplate, default -sticky is "nsew", so always + * include this even if no sticky bits are set. */ + APPENDSTR("-sticky"); APPENDOBJ(Ttk_NewStickyObj(flags & _TTK_MASK_STICK)); @@ -839,7 +844,7 @@ static Ttk_Layout TTKNewLayout( void *recordPtr,Tk_OptionTable optionTable, Tk_Window tkwin, Ttk_LayoutNode *root) { - Ttk_Layout layout = (Ttk_Layout)ckalloc(sizeof(*layout)); + Ttk_Layout layout = ckalloc(sizeof(*layout)); layout->style = style; layout->recordPtr = recordPtr; layout->optionTable = optionTable; @@ -851,7 +856,7 @@ static Ttk_Layout TTKNewLayout( void Ttk_FreeLayout(Ttk_Layout layout) { Ttk_FreeLayoutNode(layout->root); - ckfree((ClientData)layout); + ckfree(layout); } /* @@ -875,8 +880,9 @@ Ttk_Layout Ttk_CreateLayout( Ttk_LayoutNode *bgnode; if (!layoutTemplate) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "Layout ", styleName, " not found", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "Layout %s not found", styleName)); + Tcl_SetErrorCode(interp, "TTK", "LOOKUP", "LAYOUT", styleName, NULL); return 0; } @@ -915,8 +921,9 @@ Ttk_CreateSublayout( layoutTemplate = Ttk_FindLayoutTemplate(themePtr, styleName); if (!layoutTemplate) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "Layout ", styleName, " not found", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "Layout %s not found", styleName)); + Tcl_SetErrorCode(interp, "TTK", "LOOKUP", "LAYOUT", styleName, NULL); return 0; } diff --git a/generic/ttk/ttkManager.c b/generic/ttk/ttkManager.c index 2fcb190..24a0fb1 100644 --- a/generic/ttk/ttkManager.c +++ b/generic/ttk/ttkManager.c @@ -188,7 +188,7 @@ static void SlaveEventHandler(ClientData clientData, XEvent *eventPtr) static Ttk_Slave *NewSlave( Ttk_Manager *mgr, Tk_Window slaveWindow, void *slaveData) { - Ttk_Slave *slave = (Ttk_Slave*)ckalloc(sizeof(*slave)); + Ttk_Slave *slave = ckalloc(sizeof(*slave)); slave->slaveWindow = slaveWindow; slave->manager = mgr; @@ -200,7 +200,7 @@ static Ttk_Slave *NewSlave( static void DeleteSlave(Ttk_Slave *slave) { - ckfree((ClientData)slave); + ckfree(slave); } /*------------------------------------------------------------------------ @@ -210,7 +210,7 @@ static void DeleteSlave(Ttk_Slave *slave) Ttk_Manager *Ttk_CreateManager( Ttk_ManagerSpec *managerSpec, void *managerData, Tk_Window masterWindow) { - Ttk_Manager *mgr = (Ttk_Manager*)ckalloc(sizeof(*mgr)); + Ttk_Manager *mgr = ckalloc(sizeof(*mgr)); mgr->managerSpec = managerSpec; mgr->managerData = managerData; @@ -234,12 +234,12 @@ void Ttk_DeleteManager(Ttk_Manager *mgr) Ttk_ForgetSlave(mgr, mgr->nSlaves - 1); } if (mgr->slaves) { - ckfree((ClientData)mgr->slaves); + ckfree(mgr->slaves); } Tcl_CancelIdleCall(ManagerIdleProc, mgr); - ckfree((ClientData)mgr); + ckfree(mgr); } /*------------------------------------------------------------------------ @@ -252,8 +252,7 @@ void Ttk_DeleteManager(Ttk_Manager *mgr) static void InsertSlave(Ttk_Manager *mgr, Ttk_Slave *slave, int index) { int endIndex = mgr->nSlaves++; - mgr->slaves = (Ttk_Slave**)ckrealloc( - (ClientData)mgr->slaves, mgr->nSlaves * sizeof(Ttk_Slave *)); + mgr->slaves = ckrealloc(mgr->slaves, mgr->nSlaves * sizeof(Ttk_Slave *)); while (endIndex > index) { mgr->slaves[endIndex] = mgr->slaves[endIndex - 1]; @@ -456,10 +455,9 @@ int Ttk_GetSlaveIndexFromObj( */ if (Tcl_GetIntFromObj(NULL, objPtr, &slaveIndex) == TCL_OK) { if (slaveIndex < 0 || slaveIndex >= mgr->nSlaves) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, - "Slave index ", Tcl_GetString(objPtr), " out of bounds", - NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "Slave index %d out of bounds", slaveIndex)); + Tcl_SetErrorCode(interp, "TTK", "SLAVE", "INDEX", NULL); return TCL_ERROR; } *indexPtr = slaveIndex; @@ -468,23 +466,23 @@ int Ttk_GetSlaveIndexFromObj( /* Try interpreting as a slave window name; */ - if ( (*string == '.') - && (tkwin = Tk_NameToWindow(interp, string, mgr->masterWindow))) - { + if ((*string == '.') && + (tkwin = Tk_NameToWindow(interp, string, mgr->masterWindow))) { slaveIndex = Ttk_SlaveIndex(mgr, tkwin); if (slaveIndex < 0) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, - string, " is not managed by ", Tk_PathName(mgr->masterWindow), - NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "%s is not managed by %s", string, + Tk_PathName(mgr->masterWindow))); + Tcl_SetErrorCode(interp, "TTK", "SLAVE", "MANAGER", NULL); return TCL_ERROR; } *indexPtr = slaveIndex; return TCL_OK; } - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "Invalid slave specification ", string, NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "Invalid slave specification %s", string)); + Tcl_SetErrorCode(interp, "TTK", "SLAVE", "SPEC", NULL); return TCL_ERROR; } @@ -543,10 +541,9 @@ int Ttk_Maintainable(Tcl_Interp *interp, Tk_Window slave, Tk_Window master) return 1; badWindow: - Tcl_AppendResult(interp, - "can't add ", Tk_PathName(slave), - " as slave of ", Tk_PathName(master), - NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf("can't add %s as slave of %s", + Tk_PathName(slave), Tk_PathName(master))); + Tcl_SetErrorCode(interp, "TTK", "GEOMETRY", "MAINTAINABLE", NULL); return 0; } diff --git a/generic/ttk/ttkNotebook.c b/generic/ttk/ttkNotebook.c index dd757cb..56439a6 100644 --- a/generic/ttk/ttkNotebook.c +++ b/generic/ttk/ttkNotebook.c @@ -288,13 +288,14 @@ static void ActivateTab(Notebook *nb, int index) * TabState -- * Return the state of the specified tab, based on * notebook state, currentIndex, activeIndex, and user-specified tab state. - * The USER1 bit is set for the leftmost tab, and USER2 - * is set for the rightmost tab. + * The USER1 bit is set for the leftmost visible tab, and USER2 + * is set for the rightmost visible tab. */ static Ttk_State TabState(Notebook *nb, int index) { Ttk_State state = nb->core.state; Tab *tab = Ttk_SlaveData(nb->notebook.mgr, index); + int i = 0; if (index == nb->notebook.currentIndex) { state |= TTK_STATE_SELECTED; @@ -305,11 +306,25 @@ static Ttk_State TabState(Notebook *nb, int index) if (index == nb->notebook.activeIndex) { state |= TTK_STATE_ACTIVE; } - if (index == 0) { - state |= TTK_STATE_USER1; + for (i = 0; i < Ttk_NumberSlaves(nb->notebook.mgr); ++i) { + Tab *tab = Ttk_SlaveData(nb->notebook.mgr, i); + if (tab->state == TAB_STATE_HIDDEN) { + continue; + } + if (index == i) { + state |= TTK_STATE_USER1; + } + break; } - if (index == Ttk_NumberSlaves(nb->notebook.mgr) - 1) { - state |= TTK_STATE_USER2; + for (i = Ttk_NumberSlaves(nb->notebook.mgr) - 1; i >= 0; --i) { + Tab *tab = Ttk_SlaveData(nb->notebook.mgr, i); + if (tab->state == TAB_STATE_HIDDEN) { + continue; + } + if (index == i) { + state |= TTK_STATE_USER2; + } + break; } if (tab->state == TAB_STATE_DISABLED) { state |= TTK_STATE_DISABLED; @@ -325,6 +340,8 @@ static Ttk_State TabState(Notebook *nb, int index) /* TabrowSize -- * Compute max height and total width of all tabs (horizontal layouts) * or total height and max width (vertical layouts). + * The -mintabwidth style option is taken into account (for the width + * only). * * Side effects: * Sets width and height fields for all tabs. @@ -334,7 +351,7 @@ static Ttk_State TabState(Notebook *nb, int index) * (max height/width) but not parallel (total width/height). */ static void TabrowSize( - Notebook *nb, Ttk_Orient orient, int *widthPtr, int *heightPtr) + Notebook *nb, Ttk_Orient orient, int minTabWidth, int *widthPtr, int *heightPtr) { Ttk_Layout tabLayout = nb->notebook.tabLayout; int tabrowWidth = 0, tabrowHeight = 0; @@ -346,6 +363,7 @@ static void TabrowSize( Ttk_RebindSublayout(tabLayout, tab); Ttk_LayoutSize(tabLayout,tabState,&tab->width,&tab->height); + tab->width = MAX(tab->width, minTabWidth); if (orient == TTK_ORIENT_HORIZONTAL) { tabrowHeight = MAX(tabrowHeight, tab->height); @@ -406,7 +424,7 @@ static int NotebookSize(void *clientData, int *widthPtr, int *heightPtr) /* Tab row: */ - TabrowSize(nb, nbstyle.tabOrient, &tabrowWidth, &tabrowHeight); + TabrowSize(nb, nbstyle.tabOrient, nbstyle.minTabWidth, &tabrowWidth, &tabrowHeight); tabrowHeight += Ttk_PaddingHeight(nbstyle.tabMargins); tabrowWidth += Ttk_PaddingWidth(nbstyle.tabMargins); @@ -436,47 +454,30 @@ static int NotebookSize(void *clientData, int *widthPtr, int *heightPtr) /* SqueezeTabs -- * Squeeze or stretch tabs to fit within the tab area parcel. + * This happens independently of the -mintabwidth style option. * - * All tabs are adjusted by an equal amount, but will not be made - * smaller than the minimum width. (If all the tabs still do - * not fit in the available space, the rightmost ones will - * be further squozen by PlaceTabs()). - * - * The algorithm does not always yield an optimal layout, but does - * have the important property that decreasing the available width - * by one pixel will cause at most one tab to shrink by one pixel; - * this means that tabs resize "smoothly" when the window shrinks - * and grows. + * All tabs are adjusted by an equal amount. * * @@@ <<NOTE-TABPOSITION>> bug: only works for horizontal orientations * @@@ <<NOTE-SQUEEZE-HIDDEN>> does not account for hidden tabs. */ static void SqueezeTabs( - Notebook *nb, int needed, int available, int minTabWidth) + Notebook *nb, int needed, int available) { int nTabs = Ttk_NumberSlaves(nb->notebook.mgr); if (nTabs > 0) { - int difference = available - needed, - delta = difference / nTabs, - remainder = difference % nTabs, - slack = 0; + int difference = available - needed; + double delta = (double)difference / needed; + double slack = 0; int i; - if (remainder < 0) { remainder += nTabs; --delta; } - for (i = 0; i < nTabs; ++i) { Tab *tab = Ttk_SlaveData(nb->notebook.mgr,i); - int adj = delta + (i < remainder) + slack; - - if (tab->width + adj >= minTabWidth) { - tab->width += adj; - slack = 0; - } else { - slack = adj - (minTabWidth - tab->width); - tab->width = minTabWidth; - } + double ad = slack + tab->width * delta; + tab->width += (int)ad; + slack = ad - (int)ad; } } } @@ -539,8 +540,13 @@ static void NotebookDoLayout(void *recordPtr) Ttk_PlaceLayout(nb->core.layout, nb->core.state, Ttk_WinBox(nbwin)); /* Place tabs: + * Note: TabrowSize() takes into account -mintabwidth, but the tabs will + * actually have this minimum size when displayed only if there is enough + * space to draw the tabs with this width. Otherwise some of the tabs can + * be squeezed to a size smaller than -mintabwidth because we prefer + * displaying all tabs than than honoring -mintabwidth for all of them. */ - TabrowSize(nb, nbstyle.tabOrient, &tabrowWidth, &tabrowHeight); + TabrowSize(nb, nbstyle.tabOrient, nbstyle.minTabWidth, &tabrowWidth, &tabrowHeight); tabrowBox = Ttk_PadBox( Ttk_PositionBox(&cavity, tabrowWidth + Ttk_PaddingWidth(nbstyle.tabMargins), @@ -548,7 +554,7 @@ static void NotebookDoLayout(void *recordPtr) nbstyle.tabPosition), nbstyle.tabMargins); - SqueezeTabs(nb, tabrowWidth, tabrowBox.width, nbstyle.minTabWidth); + SqueezeTabs(nb, tabrowWidth, tabrowBox.width); PlaceTabs(nb, tabrowBox, nbstyle.tabPlacement); /* Layout for client area frame: @@ -621,9 +627,12 @@ static void SelectTab(Notebook *nb, int index) Ttk_UnmapSlave(nb->notebook.mgr, currentIndex); } - NotebookPlaceSlave(nb, index); - + /* Must be set before calling NotebookPlaceSlave(), otherwise it may + * happen that NotebookPlaceSlaves(), triggered by an interveaning + * geometry request, will swap to old index. */ nb->notebook.currentIndex = index; + + NotebookPlaceSlave(nb, index); TtkRedisplayWidget(&nb->core); TtkSendVirtualEvent(nb->core.tkwin, "NotebookTabChanged"); @@ -727,9 +736,9 @@ static int AddTab( } #if 0 /* can't happen */ if (Ttk_SlaveIndex(nb->notebook.mgr, slaveWindow) >= 0) { - Tcl_AppendResult(interp, - Tk_PathName(slaveWindow), " already added", - NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf("%s already added", + Tk_PathName(slaveWindow))); + Tcl_SetErrorCode(interp, "TTK", "NOTEBOOK", "PRESENT", NULL); return TCL_ERROR; } #endif @@ -859,10 +868,9 @@ static int GetTabIndex( int status = FindTabIndex(interp, nb, objPtr, index_rtn); if (status == TCL_OK && *index_rtn < 0) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, - "tab '", Tcl_GetString(objPtr), "' not found", - NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "tab '%s' not found", Tcl_GetString(objPtr))); + Tcl_SetErrorCode(interp, "TTK", "NOTEBOOK", "TAB", NULL); status = TCL_ERROR; } return status; @@ -1059,9 +1067,8 @@ static int NotebookIdentifyCommand( if ( Tcl_GetIntFromObj(interp, objv[objc-2], &x) != TCL_OK || Tcl_GetIntFromObj(interp, objv[objc-1], &y) != TCL_OK - || (objc == 5 && - Tcl_GetIndexFromObj(interp, objv[2], whatTable, "option", 0, &what) - != TCL_OK) + || (objc == 5 && Tcl_GetIndexFromObjStruct(interp, objv[2], whatTable, + sizeof(char *), "option", 0, &what) != TCL_OK) ) { return TCL_ERROR; } @@ -1082,7 +1089,8 @@ static int NotebookIdentifyCommand( case IDENTIFY_ELEMENT: if (element) { const char *elementName = Ttk_ElementName(element); - Tcl_SetObjResult(interp,Tcl_NewStringObj(elementName,-1)); + + Tcl_SetObjResult(interp, Tcl_NewStringObj(elementName, -1)); } break; case IDENTIFY_TAB: @@ -1173,10 +1181,10 @@ static int NotebookTabsCommand( result = Tcl_NewListObj(0, NULL); for (i = 0; i < Ttk_NumberSlaves(mgr); ++i) { const char *pathName = Tk_PathName(Ttk_SlaveWindow(mgr,i)); - Tcl_ListObjAppendElement(interp, result, Tcl_NewStringObj(pathName,-1)); + + Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj(pathName,-1)); } Tcl_SetObjResult(interp, result); - return TCL_OK; } diff --git a/generic/ttk/ttkPanedwindow.c b/generic/ttk/ttkPanedwindow.c index b301372..adc2aef 100644 --- a/generic/ttk/ttkPanedwindow.c +++ b/generic/ttk/ttkPanedwindow.c @@ -157,7 +157,9 @@ static int ConfigurePane( /* Sanity-check: */ if (pane->weight < 0) { - Tcl_AppendResult(interp, "-weight must be nonnegative", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "-weight must be nonnegative", -1)); + Tcl_SetErrorCode(interp, "TTK", "PANE", "WEIGHT", NULL); goto error; } @@ -419,9 +421,9 @@ static int AddPane( return TCL_ERROR; } if (Ttk_SlaveIndex(pw->paned.mgr, slaveWindow) >= 0) { - Tcl_AppendResult(interp, - Tk_PathName(slaveWindow), " already added", - NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "%s already added", Tk_PathName(slaveWindow))); + Tcl_SetErrorCode(interp, "TTK", "PANE", "PRESENT", NULL); return TCL_ERROR; } @@ -729,9 +731,8 @@ static int PanedIdentifyCommand( if ( Tcl_GetIntFromObj(interp, objv[objc-2], &x) != TCL_OK || Tcl_GetIntFromObj(interp, objv[objc-1], &y) != TCL_OK - || (objc == 5 && - Tcl_GetIndexFromObj(interp, objv[2], whatTable, "option", 0, &what) - != TCL_OK) + || (objc == 5 && Tcl_GetIndexFromObjStruct(interp, objv[2], whatTable, + sizeof(char *), "option", 0, &what) != TCL_OK) ) { return TCL_ERROR; } @@ -844,9 +845,9 @@ static int PanedSashposCommand( return TCL_ERROR; } if (sashIndex < 0 || sashIndex >= Ttk_NumberSlaves(pw->paned.mgr) - 1) { - Tcl_AppendResult(interp, - "sash index ", Tcl_GetString(objv[2]), " out of range", - NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "sash index %d out of range", sashIndex)); + Tcl_SetErrorCode(interp, "TTK", "PANE", "SASH_INDEX", NULL); return TCL_ERROR; } diff --git a/generic/ttk/ttkProgress.c b/generic/ttk/ttkProgress.c index 4dc50a2..6c13992 100644 --- a/generic/ttk/ttkProgress.c +++ b/generic/ttk/ttkProgress.c @@ -421,21 +421,23 @@ static int ProgressbarStepCommand( } newValueObj = Tcl_NewDoubleObj(value); + Tcl_IncrRefCount(newValueObj); TtkRedisplayWidget(&pb->core); /* Update value by setting the linked -variable, if there is one: */ if (pb->progress.variableTrace) { - return Tcl_ObjSetVar2( - interp, pb->progress.variableObj, 0, newValueObj, - TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG) - ? TCL_OK : TCL_ERROR; + int result = Tcl_ObjSetVar2( + interp, pb->progress.variableObj, 0, newValueObj, + TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG) + ? TCL_OK : TCL_ERROR; + Tcl_DecrRefCount(newValueObj); + return result; } /* Otherwise, change the -value directly: */ - Tcl_IncrRefCount(newValueObj); Tcl_DecrRefCount(pb->progress.valueObj); pb->progress.valueObj = newValueObj; CheckAnimation(pb); diff --git a/generic/ttk/ttkScale.c b/generic/ttk/ttkScale.c index 69753d1..279fc7a 100644 --- a/generic/ttk/ttkScale.c +++ b/generic/ttk/ttkScale.c @@ -15,6 +15,10 @@ #define MAX(a,b) ((a) > (b) ? (a) : (b)) #define MIN(a,b) ((a) < (b) ? (a) : (b)) +/* Bit fields for OptionSpec mask field: + */ +#define STATE_CHANGED (0x100) /* -state option changed */ + /* * Scale widget record */ @@ -35,6 +39,11 @@ typedef struct /* internal state */ Ttk_TraceHandle *variableTrace; + /* + * Compatibility/legacy options: + */ + Tcl_Obj *stateObj; + } ScalePart; typedef struct @@ -66,6 +75,10 @@ static Tk_OptionSpec ScaleOptionSpecs[] = DEF_SCALE_LENGTH, Tk_Offset(Scale,scale.lengthObj), -1, 0, 0, GEOMETRY_CHANGED}, + {TK_OPTION_STRING, "-state", "state", "State", + "normal", Tk_Offset(Scale,scale.stateObj), -1, + 0,0,STATE_CHANGED}, + WIDGET_TAKEFOCUS_TRUE, WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs) }; @@ -139,6 +152,10 @@ static int ScaleConfigure(Tcl_Interp *interp, void *recordPtr, int mask) } scale->scale.variableTrace = vt; + if (mask & STATE_CHANGED) { + TtkCheckStateOption(&scale->core, scale->scale.stateObj); + } + return TCL_OK; } diff --git a/generic/ttk/ttkScroll.c b/generic/ttk/ttkScroll.c index fc305e9..47db6ac 100644 --- a/generic/ttk/ttkScroll.c +++ b/generic/ttk/ttkScroll.c @@ -7,7 +7,7 @@ * * Scrollable interface: * - * + 'first' is controlled by [xy]view widget command + * + 'first' is controlled by [xy]view widget command * and other scrolling commands like 'see'; * + 'total' depends on widget contents; * + 'last' depends on first, total, and widget size. @@ -16,15 +16,15 @@ * * 1. User adjusts scrollbar, scrollbar widget calls its -command * 2. Scrollbar -command invokes the scrollee [xy]view widget method - * 3. TtkScrollviewCommand calls TtkScrollTo(), which updates + * 3. TtkScrollviewCommand calls TtkScrollTo(), which updates * 'first' and schedules a redisplay. - * 4. Once the scrollee knows 'total' and 'last' (typically in - * the LayoutProc), call TtkScrolled(h,first,last,total) to + * 4. Once the scrollee knows 'total' and 'last' (typically in + * the LayoutProc), call TtkScrolled(h,first,last,total) to * synchronize the scrollbar. * 5. The scrollee -[xy]scrollcommand is called (in an idle callback) * 6. Which calls the scrollbar 'set' method and redisplays the scrollbar. * - * If the scrollee has internal scrolling (e.g., a 'see' method), + * If the scrollee has internal scrolling (e.g., a 'see' method), * it should TtkScrollTo() directly (step 2). * * If the widget value changes, it should call TtkScrolled() (step 4). @@ -34,7 +34,7 @@ * TtkScrollbarUpdateRequired, which will invoke step (5) (@@@ Fix this) */ -#include <tkInt.h> +#include "tkInt.h" #include "ttkTheme.h" #include "ttkWidget.h" @@ -55,7 +55,7 @@ struct ScrollHandleRec */ ScrollHandle TtkCreateScrollHandle(WidgetCore *corePtr, Scrollable *scrollPtr) { - ScrollHandle h = (ScrollHandle)ckalloc(sizeof(*h)); + ScrollHandle h = ckalloc(sizeof(*h)); h->flags = 0; h->corePtr = corePtr; @@ -130,7 +130,7 @@ static void UpdateScrollbarBG(ClientData clientData) Tcl_Preserve((ClientData) interp); code = UpdateScrollbar(interp, h); if (code == TCL_ERROR && !Tcl_InterpDeleted(interp)) { - Tcl_BackgroundError(interp); + Tcl_BackgroundException(interp, code); } Tcl_Release((ClientData) interp); } @@ -141,7 +141,7 @@ static void UpdateScrollbarBG(ClientData clientData) void TtkScrolled(ScrollHandle h, int first, int last, int total) { Scrollable *s = h->scrollPtr; - + /* Sanity-check inputs: */ if (total <= 0) { @@ -181,6 +181,19 @@ void TtkScrollbarUpdateRequired(ScrollHandle h) h->flags |= SCROLL_UPDATE_REQUIRED; } +/* TtkUpdateScrollInfo -- + * Call the layoutProc to update the scroll info first, last, and total. + * Do it only if needed, that is when a redisplay is pending (which + * indicates scroll info are possibly out of date). + */ + +void TtkUpdateScrollInfo(ScrollHandle h) +{ + if (h->corePtr->flags & REDISPLAY_PENDING) { + h->corePtr->widgetSpec->layoutProc(h->corePtr); + } +} + /* TtkScrollviewCommand -- * Widget [xy]view command implementation. * @@ -193,7 +206,10 @@ int TtkScrollviewCommand( Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], ScrollHandle h) { Scrollable *s = h->scrollPtr; - int newFirst = s->first; + int newFirst; + + TtkUpdateScrollInfo(h); + newFirst = s->first; if (objc == 2) { Tcl_Obj *result[2]; @@ -226,15 +242,19 @@ int TtkScrollviewCommand( } } - TtkScrollTo(h, newFirst); + TtkScrollTo(h, newFirst, 0); return TCL_OK; } -void TtkScrollTo(ScrollHandle h, int newFirst) +void TtkScrollTo(ScrollHandle h, int newFirst, int updateScrollInfo) { Scrollable *s = h->scrollPtr; + if (updateScrollInfo) { + TtkUpdateScrollInfo(h); + } + if (newFirst >= s->total) newFirst = s->total - 1; if (newFirst > s->first && s->last >= s->total) /* don't scroll past end */ @@ -253,6 +273,6 @@ void TtkFreeScrollHandle(ScrollHandle h) if (h->flags & SCROLL_UPDATE_PENDING) { Tcl_CancelIdleCall(UpdateScrollbarBG, (ClientData)h); } - ckfree((ClientData)h); + ckfree(h); } diff --git a/generic/ttk/ttkState.c b/generic/ttk/ttkState.c index a71ae21..5b62f3c 100644 --- a/generic/ttk/ttkState.c +++ b/generic/ttk/ttkState.c @@ -98,8 +98,9 @@ static int StateSpecSetFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr) if (stateNames[j] == 0) { if (interp) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "Invalid state name ", stateName,NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "Invalid state name %s", stateName)); + Tcl_SetErrorCode(interp, "TTK", "VALUE", "STATE", NULL); } return TCL_ERROR; } @@ -129,7 +130,8 @@ static void StateSpecUpdateString(Tcl_Obj *objPtr) unsigned int offbits = objPtr->internalRep.longValue & 0x0000FFFF; unsigned int mask = onbits | offbits; Tcl_DString result; - int i, len; + int i; + int len; Tcl_DStringInit(&result); @@ -145,14 +147,14 @@ static void StateSpecUpdateString(Tcl_Obj *objPtr) len = Tcl_DStringLength(&result); if (len) { /* 'len' includes extra trailing ' ' */ - objPtr->bytes = Tcl_Alloc((unsigned)len); + objPtr->bytes = ckalloc(len); objPtr->length = len-1; - strncpy(objPtr->bytes, Tcl_DStringValue(&result), (size_t)len-1); + strncpy(objPtr->bytes, Tcl_DStringValue(&result), len-1); objPtr->bytes[len-1] = '\0'; } else { /* empty string */ objPtr->length = 0; - objPtr->bytes = Tcl_Alloc(1); + objPtr->bytes = ckalloc(1); *objPtr->bytes = '\0'; } @@ -216,8 +218,8 @@ Tcl_Obj *Ttk_StateMapLookup( return specs[j+1]; } if (interp) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "No match in state map", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj("No match in state map", -1)); + Tcl_SetErrorCode(interp, "TTK", "STATE", "UNMATCHED", NULL); } return NULL; } @@ -240,10 +242,11 @@ Ttk_StateMap Ttk_GetStateMapFromObj( return NULL; if (nSpecs % 2 != 0) { - if (interp) - Tcl_SetResult(interp, - "State map must have an even number of elements", - TCL_STATIC); + if (interp) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "State map must have an even number of elements", -1)); + Tcl_SetErrorCode(interp, "TTK", "VALUE", "STATEMAP", NULL); + } return 0; } diff --git a/generic/ttk/ttkTagSet.c b/generic/ttk/ttkTagSet.c index 9f2a87b..f2108b9 100644 --- a/generic/ttk/ttkTagSet.c +++ b/generic/ttk/ttkTagSet.c @@ -34,7 +34,7 @@ struct TtkTagTable { */ static Ttk_Tag NewTag(Ttk_TagTable tagTable, const char *tagName) { - Ttk_Tag tag = (Ttk_Tag)ckalloc(sizeof(*tag)); + Ttk_Tag tag = ckalloc(sizeof(*tag)); tag->tagRecord = ckalloc(tagTable->recordSize); memset(tag->tagRecord, 0, tagTable->recordSize); /* Don't need Tk_InitOptions() here, all defaults should be NULL. */ @@ -47,7 +47,7 @@ static void DeleteTag(Ttk_TagTable tagTable, Ttk_Tag tag) { Tk_FreeConfigOptions(tag->tagRecord,tagTable->optionTable,tagTable->tkwin); ckfree(tag->tagRecord); - ckfree((void*)tag); + ckfree(tag); } /*------------------------------------------------------------------------ @@ -58,7 +58,7 @@ Ttk_TagTable Ttk_CreateTagTable( Tcl_Interp *interp, Tk_Window tkwin, Tk_OptionSpec optionSpecs[], int recordSize) { - Ttk_TagTable tagTable = (Ttk_TagTable)ckalloc(sizeof(*tagTable)); + Ttk_TagTable tagTable = ckalloc(sizeof(*tagTable)); tagTable->tkwin = tkwin; tagTable->optionSpecs = optionSpecs; tagTable->optionTable = Tk_CreateOptionTable(interp, optionSpecs); @@ -80,7 +80,7 @@ void Ttk_DeleteTagTable(Ttk_TagTable tagTable) } Tcl_DeleteHashTable(&tagTable->tags); - ckfree((void*)tagTable); + ckfree(tagTable); } Ttk_Tag Ttk_GetTag(Ttk_TagTable tagTable, const char *tagName) @@ -116,7 +116,7 @@ Ttk_Tag Ttk_GetTagFromObj(Ttk_TagTable tagTable, Tcl_Obj *objPtr) Ttk_TagSet Ttk_GetTagSetFromObj( Tcl_Interp *interp, Ttk_TagTable tagTable, Tcl_Obj *objPtr) { - Ttk_TagSet tagset = (Ttk_TagSet)(ckalloc(sizeof *tagset)); + Ttk_TagSet tagset = ckalloc(sizeof(*tagset)); Tcl_Obj **objv; int i, objc; @@ -127,11 +127,11 @@ Ttk_TagSet Ttk_GetTagSetFromObj( } if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { - ckfree((ClientData)tagset); + ckfree(tagset); return NULL; } - tagset->tags = (Ttk_Tag*)ckalloc((objc+1) * sizeof(Ttk_Tag)); + tagset->tags = ckalloc((objc+1) * sizeof(Ttk_Tag)); for (i=0; i<objc; ++i) { tagset->tags[i] = Ttk_GetTagFromObj(tagTable, objv[i]); } @@ -158,8 +158,8 @@ Tcl_Obj *Ttk_NewTagSetObj(Ttk_TagSet tagset) void Ttk_FreeTagSet(Ttk_TagSet tagset) { - ckfree((ClientData)tagset->tags); - ckfree((ClientData)tagset); + ckfree(tagset->tags); + ckfree(tagset); } /* Ttk_TagSetContains -- test if tag set contains a tag. @@ -188,7 +188,7 @@ int Ttk_TagSetAdd(Ttk_TagSet tagset, Ttk_Tag tag) return 0; } } - tagset->tags = (void*)ckrealloc((void*)tagset->tags, + tagset->tags = ckrealloc(tagset->tags, (tagset->nTags+1)*sizeof(tagset->tags[0])); tagset->tags[tagset->nTags++] = tag; return 1; diff --git a/generic/ttk/ttkTheme.c b/generic/ttk/ttkTheme.c index a2c51c0..cc75238 100644 --- a/generic/ttk/ttkTheme.c +++ b/generic/ttk/ttkTheme.c @@ -10,14 +10,18 @@ * of this file, and for a DISCLAIMER OF ALL WARRANTIES. */ -#include <stdlib.h> -#include <string.h> -#include <tk.h> -#include <tkInt.h> +#include "tkInt.h" #include "ttkThemeInt.h" #define PKG_ASSOC_KEY "Ttk" +#ifdef MAC_OSX_TK + extern void TkMacOSXFlushWindows(void); + #define UPDATE_WINDOWS() TkMacOSXFlushWindows() +#else + #define UPDATE_WINDOWS() +#endif + /*------------------------------------------------------------------------ * +++ Styles. * @@ -40,7 +44,7 @@ typedef struct Ttk_Style_ static Style *NewStyle() { - Style *stylePtr = (Style*)ckalloc(sizeof(Style)); + Style *stylePtr = ckalloc(sizeof(Style)); stylePtr->styleName = NULL; stylePtr->parentStyle = NULL; @@ -75,7 +79,7 @@ static void FreeStyle(Style *stylePtr) Ttk_FreeLayoutTemplate(stylePtr->layoutTemplate); - ckfree((ClientData)stylePtr); + ckfree(stylePtr); } /* @@ -179,7 +183,7 @@ static const Tk_OptionSpec *TTKGetOptionSpec( static OptionMap BuildOptionMap(Ttk_ElementClass *elementClass, Tk_OptionTable optionTable) { - OptionMap optionMap = (OptionMap)ckalloc( + OptionMap optionMap = ckalloc( sizeof(const Tk_OptionSpec) * elementClass->nResources + 1); int i; @@ -221,8 +225,7 @@ GetOptionMap(Ttk_ElementClass *elementClass, Tk_OptionTable optionTable) static Ttk_ElementClass * NewElementClass(const char *name, Ttk_ElementSpec *specPtr,void *clientData) { - Ttk_ElementClass *elementClass = - (Ttk_ElementClass*)ckalloc(sizeof(Ttk_ElementClass)); + Ttk_ElementClass *elementClass = ckalloc(sizeof(Ttk_ElementClass)); int i; elementClass->name = name; @@ -238,7 +241,7 @@ NewElementClass(const char *name, Ttk_ElementSpec *specPtr,void *clientData) /* Initialize default values: */ - elementClass->defaultValues = (Tcl_Obj**) + elementClass->defaultValues = ckalloc(elementClass->nResources * sizeof(Tcl_Obj *) + 1); for (i=0; i < elementClass->nResources; ++i) { const char *defaultValue = specPtr->options[i].defaultValue; @@ -275,7 +278,7 @@ static void FreeElementClass(Ttk_ElementClass *elementClass) Tcl_DecrRefCount(elementClass->defaultValues[i]); } } - ckfree((ClientData)elementClass->defaultValues); + ckfree(elementClass->defaultValues); /* * Free option map cache: @@ -288,7 +291,7 @@ static void FreeElementClass(Ttk_ElementClass *elementClass) Tcl_DeleteHashTable(&elementClass->optMapCache); ckfree(elementClass->elementRecord); - ckfree((ClientData)elementClass); + ckfree(elementClass); } /*------------------------------------------------------------------------ @@ -311,7 +314,7 @@ typedef struct Ttk_Theme_ static Theme *NewTheme(Ttk_ResourceCache cache, Ttk_Theme parent) { - Theme *themePtr = (Theme*)ckalloc(sizeof(Theme)); + Theme *themePtr = ckalloc(sizeof(Theme)); Tcl_HashEntry *entryPtr; int unused; @@ -365,7 +368,7 @@ static void FreeTheme(Theme *themePtr) /* * Free theme record: */ - ckfree((ClientData)themePtr); + ckfree(themePtr); return; } @@ -454,11 +457,11 @@ static void Ttk_StylePkgFree(ClientData clientData, Tcl_Interp *interp) while (cleanup) { Cleanup *next = cleanup->next; cleanup->cleanupProc(cleanup->clientData); - ckfree((ClientData)cleanup); + ckfree(cleanup); cleanup = next; } - ckfree((ClientData)pkgPtr); + ckfree(pkgPtr); } /* @@ -484,7 +487,7 @@ void Ttk_RegisterCleanup( Tcl_Interp *interp, ClientData clientData, Ttk_CleanupProc *cleanupProc) { StylePackageData *pkgPtr = GetStylePackageData(interp); - Cleanup *cleanup = (Cleanup*)ckalloc(sizeof(*cleanup)); + Cleanup *cleanup = ckalloc(sizeof(*cleanup)); cleanup->clientData = clientData; cleanup->cleanupProc = cleanupProc; @@ -509,10 +512,12 @@ static void ThemeChangedProc(ClientData clientData) static char ThemeChangedScript[] = "ttk::ThemeChanged"; StylePackageData *pkgPtr = clientData; - if (Tcl_EvalEx(pkgPtr->interp, ThemeChangedScript, -1, TCL_EVAL_GLOBAL) != TCL_OK) { - Tcl_BackgroundError(pkgPtr->interp); + int code = Tcl_EvalEx(pkgPtr->interp, ThemeChangedScript, -1, TCL_EVAL_GLOBAL); + if (code != TCL_OK) { + Tcl_BackgroundException(pkgPtr->interp, code); } pkgPtr->themeChangePending = 0; + UPDATE_WINDOWS(); } /* @@ -549,8 +554,9 @@ Ttk_CreateTheme( entryPtr = Tcl_CreateHashEntry(&pkgPtr->themeTable, name, &newEntry); if (!newEntry) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "Theme ", name, " already exists", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "Theme %s already exists", name)); + Tcl_SetErrorCode(interp, "TTK", "THEME", "EXISTS", NULL); return NULL; } @@ -592,8 +598,9 @@ static Ttk_Theme LookupTheme( entryPtr = Tcl_FindHashEntry(&pkgPtr->themeTable, name); if (!entryPtr) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "theme \"", name, "\" doesn't exist", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "theme \"%s\" doesn't exist", name)); + Tcl_SetErrorCode(interp, "TTK", "LOOKUP", "THEME", name, NULL); return NULL; } @@ -800,7 +807,7 @@ int Ttk_RegisterElementFactory( Ttk_ElementFactory factory, void *clientData) { StylePackageData *pkgPtr = GetStylePackageData(interp); - FactoryRec *recPtr = (FactoryRec*)ckalloc(sizeof(*recPtr)); + FactoryRec *recPtr = ckalloc(sizeof(*recPtr)); Tcl_HashEntry *entryPtr; int newEntry; @@ -876,9 +883,10 @@ Ttk_ElementClass *Ttk_RegisterElement( if (specPtr->version != TK_STYLE_VERSION_2) { /* Version mismatch */ if (interp) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "Internal error: Ttk_RegisterElement (", - name, "): invalid version", + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "Internal error: Ttk_RegisterElement (%s): invalid version", + name)); + Tcl_SetErrorCode(interp, "TTK", "REGISTER_ELEMENT", "VERSION", NULL); } return 0; @@ -888,7 +896,9 @@ Ttk_ElementClass *Ttk_RegisterElement( if (!newEntry) { if (interp) { Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "Duplicate element ", name, NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "Duplicate element %s", name)); + Tcl_SetErrorCode(interp, "TTK", "REGISTER_ELEMENT", "DUPE", NULL); } return 0; } @@ -1356,8 +1366,9 @@ static int StyleThemeCurrentCmd( } if (name == NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("error: failed to get theme name", -1)); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "error: failed to get theme name", -1)); + Tcl_SetErrorCode(interp, "TTK", "THEME", "NAMELESS", NULL); return TCL_ERROR; } @@ -1388,8 +1399,8 @@ static int StyleThemeCreateCmd( for (i=4; i < objc; i +=2) { int option; - if (Tcl_GetIndexFromObj( - interp, objv[i], optStrings, "option", 0, &option) != TCL_OK) + if (Tcl_GetIndexFromObjStruct(interp, objv[i], optStrings, + sizeof(char *), "option", 0, &option) != TCL_OK) { return TCL_ERROR; } @@ -1492,7 +1503,10 @@ static int StyleElementCreateCmd( entryPtr = Tcl_FindHashEntry(&pkgPtr->factoryTable, factoryName); if (!entryPtr) { - Tcl_AppendResult(interp, "No such element type ", factoryName, NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "No such element type %s", factoryName)); + Tcl_SetErrorCode(interp, "TTK", "LOOKUP", "ELEMENT_TYPE", factoryName, + NULL); return TCL_ERROR; } @@ -1551,7 +1565,9 @@ static int StyleElementOptionsCmd( return TCL_OK; } - Tcl_AppendResult(interp, "element ", elementName, " not found", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "element %s not found", elementName)); + Tcl_SetErrorCode(interp, "TTK", "LOOKUP", "ELEMENT", elementName, NULL); return TCL_ERROR; } @@ -1575,7 +1591,10 @@ static int StyleLayoutCmd( if (objc == 3) { layoutTemplate = Ttk_FindLayoutTemplate(theme, layoutName); if (!layoutTemplate) { - Tcl_AppendResult(interp, "Layout ", layoutName, " not found", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "Layout %s not found", layoutName)); + Tcl_SetErrorCode(interp, "TTK", "LOOKUP", "LAYOUT", layoutName, + NULL); return TCL_ERROR; } Tcl_SetObjResult(interp, Ttk_UnparseLayoutTemplate(layoutTemplate)); @@ -1660,7 +1679,7 @@ StyleObjCmd( return Ttk_InvokeEnsemble(StyleEnsemble, 1, clientData,interp,objc,objv); } -MODULE_SCOPE +MODULE_SCOPE int Ttk_InvokeEnsemble( /* Run an ensemble command */ const Ttk_Ensemble *ensemble, int cmdIndex, void *clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) @@ -1695,8 +1714,7 @@ void Ttk_StylePkgInit(Tcl_Interp *interp) { Tcl_Namespace *nsPtr; - StylePackageData *pkgPtr = (StylePackageData *) - ckalloc(sizeof(StylePackageData)); + StylePackageData *pkgPtr = ckalloc(sizeof(StylePackageData)); pkgPtr->interp = interp; Tcl_InitHashTable(&pkgPtr->themeTable, TCL_STRING_KEYS); diff --git a/generic/ttk/ttkTheme.h b/generic/ttk/ttkTheme.h index 9251dea..cf0a07c 100644 --- a/generic/ttk/ttkTheme.h +++ b/generic/ttk/ttkTheme.h @@ -29,9 +29,13 @@ extern "C" { * +++ Defaults for element option specifications. */ #define DEFAULT_FONT "TkDefaultFont" +#ifdef MAC_OSX_TK +#define DEFAULT_BACKGROUND "systemTextBackgroundColor" +#define DEFAULT_FOREGROUND "systemTextColor" +#else #define DEFAULT_BACKGROUND "#d9d9d9" #define DEFAULT_FOREGROUND "black" - +#endif /*------------------------------------------------------------------------ * +++ Widget states. * Keep in sync with stateNames[] in tkstate.c. diff --git a/generic/ttk/ttkTrace.c b/generic/ttk/ttkTrace.c index 8bc8519..7c4345d 100644 --- a/generic/ttk/ttkTrace.c +++ b/generic/ttk/ttkTrace.c @@ -34,7 +34,7 @@ VarTraceProc( const char *name, *value; Tcl_Obj *valuePtr; - if (flags & TCL_INTERP_DESTROYED) { + if (Tcl_InterpDeleted(interp)) { return NULL; } @@ -54,7 +54,7 @@ VarTraceProc( ckfree((ClientData)tracePtr); return NULL; } - Tcl_TraceVar(interp, name, + Tcl_TraceVar2(interp, name, NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, VarTraceProc, clientData); tracePtr->callback(tracePtr->clientData, NULL); @@ -85,7 +85,7 @@ Ttk_TraceHandle *Ttk_TraceVariable( Ttk_TraceProc callback, void *clientData) { - Ttk_TraceHandle *h = (Ttk_TraceHandle*)ckalloc(sizeof(*h)); + Ttk_TraceHandle *h = ckalloc(sizeof(*h)); int status; h->interp = interp; @@ -94,13 +94,13 @@ Ttk_TraceHandle *Ttk_TraceVariable( h->clientData = clientData; h->callback = callback; - status = Tcl_TraceVar(interp, Tcl_GetString(varnameObj), - TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + status = Tcl_TraceVar2(interp, Tcl_GetString(varnameObj), + NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, VarTraceProc, (ClientData)h); if (status != TCL_OK) { Tcl_DecrRefCount(h->varnameObj); - ckfree((ClientData)h); + ckfree(h); return NULL; } @@ -150,11 +150,11 @@ void Ttk_UntraceVariable(Ttk_TraceHandle *h) h->interp = NULL; return; } - Tcl_UntraceVar(h->interp, Tcl_GetString(h->varnameObj), - TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + Tcl_UntraceVar2(h->interp, Tcl_GetString(h->varnameObj), + NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, VarTraceProc, (ClientData)h); Tcl_DecrRefCount(h->varnameObj); - ckfree((ClientData)h); + ckfree(h); } } diff --git a/generic/ttk/ttkTrack.c b/generic/ttk/ttkTrack.c index 9cf8267..396b073 100644 --- a/generic/ttk/ttkTrack.c +++ b/generic/ttk/ttkTrack.c @@ -173,7 +173,7 @@ ElementStateEventProc(ClientData clientData, XEvent *ev) void TtkTrackElementState(WidgetCore *corePtr) { - ElementStateTracker *es = (ElementStateTracker*)ckalloc(sizeof(*es)); + ElementStateTracker *es = ckalloc(sizeof(*es)); es->corePtr = corePtr; es->tracking = 0; es->activeElement = es->pressedElement = 0; diff --git a/generic/ttk/ttkTreeview.c b/generic/ttk/ttkTreeview.c index 473d1e6..b1739b6 100644 --- a/generic/ttk/ttkTreeview.c +++ b/generic/ttk/ttkTreeview.c @@ -86,7 +86,7 @@ static Tk_OptionSpec ItemOptionSpecs[] = { */ static TreeItem *NewItem(void) { - TreeItem *item = (TreeItem*)ckalloc(sizeof(*item)); + TreeItem *item = ckalloc(sizeof(*item)); item->entryPtr = 0; item->parent = item->children = item->next = item->prev = NULL; @@ -118,7 +118,7 @@ static void FreeItem(TreeItem *item) if (item->tagset) { Ttk_FreeTagSet(item->tagset); } if (item->imagespec) { TtkFreeImageSpec(item->imagespec); } - ckfree((ClientData)item); + ckfree(item); } static void FreeItemCB(void *clientData) { FreeItem(clientData); } @@ -282,7 +282,7 @@ static Tk_OptionSpec ColumnOptionSpecs[] = { 0,0,0 }, {TK_OPTION_BOOLEAN, "-stretch", "stretch", "Stretch", "1", -1, Tk_Offset(TreeColumn,stretch), - 0,0,0 }, + 0,0,GEOMETRY_CHANGED }, {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", "w", Tk_Offset(TreeColumn,anchorObj), -1, /* <<NOTE-ANCHOR>> */ 0,0,0 }, @@ -340,8 +340,8 @@ static int GetEnumSetFromObj( for (i = 0; i < objc; ++i) { int index; - if (TCL_OK != Tcl_GetIndexFromObj( - interp, objv[i], table, "value", TCL_EXACT, &index)) + if (TCL_OK != Tcl_GetIndexFromObjStruct(interp, objv[i], table, + sizeof(char *), "value", TCL_EXACT, &index)) { return TCL_ERROR; } @@ -534,21 +534,18 @@ static TreeColumn *GetColumn( */ if (Tcl_GetIntFromObj(NULL, columnIDObj, &columnIndex) == TCL_OK) { if (columnIndex < 0 || columnIndex >= tv->tree.nColumns) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, - "Column index ", - Tcl_GetString(columnIDObj), - " out of bounds", - NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "Column index %s out of bounds", + Tcl_GetString(columnIDObj))); + Tcl_SetErrorCode(interp, "TTK", "TREE", "COLBOUND", NULL); return NULL; } return tv->tree.columns + columnIndex; } - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, - "Invalid column index ", Tcl_GetString(columnIDObj), - NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "Invalid column index %s", Tcl_GetString(columnIDObj))); + Tcl_SetErrorCode(interp, "TTK", "TREE", "COLUMN", NULL); return NULL; } @@ -566,10 +563,9 @@ static TreeColumn *FindColumn( return tv->tree.displayColumns[colno]; } /* else */ - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, - "Column ", Tcl_GetString(columnIDObj), " out of range", - NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "Column %s out of range", Tcl_GetString(columnIDObj))); + Tcl_SetErrorCode(interp, "TTK", "TREE", "COLUMN", NULL); return NULL; } @@ -587,8 +583,9 @@ static TreeItem *FindItem( Tcl_HashEntry *entryPtr = Tcl_FindHashEntry(&tv->tree.items, itemName); if (!entryPtr) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "Item ", itemName, " not found", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "Item %s not found", itemName)); + Tcl_SetErrorCode(interp, "TTK", "TREE", "ITEM", NULL); return 0; } return Tcl_GetHashValue(entryPtr); @@ -612,11 +609,11 @@ static TreeItem **GetItemListFromObj( return NULL; } - items = (TreeItem**)ckalloc((nElements + 1)*sizeof(TreeItem*)); + items = ckalloc((nElements + 1)*sizeof(TreeItem*)); for (i = 0; i < nElements; ++i) { items[i] = FindItem(interp, tv, elements[i]); if (!items[i]) { - ckfree((ClientData)items); + ckfree(items); return NULL; } } @@ -658,7 +655,7 @@ static void TreeviewFreeColumns(Treeview *tv) if (tv->tree.columns) { for (i = 0; i < tv->tree.nColumns; ++i) FreeColumn(tv->tree.columns + i); - ckfree((ClientData)tv->tree.columns); + ckfree(tv->tree.columns); tv->tree.columns = 0; } } @@ -687,8 +684,7 @@ static int TreeviewInitColumns(Tcl_Interp *interp, Treeview *tv) * Initialize columns array and columnNames hash table: */ tv->tree.nColumns = ncols; - tv->tree.columns = - (TreeColumn*)ckalloc(tv->tree.nColumns * sizeof(TreeColumn)); + tv->tree.columns = ckalloc(tv->tree.nColumns * sizeof(TreeColumn)); for (i = 0; i < ncols; ++i) { int isNew; @@ -733,16 +729,16 @@ static int TreeviewInitDisplayColumns(Tcl_Interp *interp, Treeview *tv) if (!strcmp(Tcl_GetString(tv->tree.displayColumnsObj), "#all")) { ndcols = tv->tree.nColumns; - displayColumns = (TreeColumn**)ckalloc((ndcols+1)*sizeof(TreeColumn*)); + displayColumns = ckalloc((ndcols+1) * sizeof(TreeColumn*)); for (index = 0; index < ndcols; ++index) { displayColumns[index+1] = tv->tree.columns + index; } } else { - displayColumns = (TreeColumn**)ckalloc((ndcols+1)*sizeof(TreeColumn*)); + displayColumns = ckalloc((ndcols+1) * sizeof(TreeColumn*)); for (index = 0; index < ndcols; ++index) { displayColumns[index+1] = GetColumn(interp, tv, dcolumns[index]); if (!displayColumns[index+1]) { - ckfree((ClientData)displayColumns); + ckfree(displayColumns); return TCL_ERROR; } } @@ -750,7 +746,7 @@ static int TreeviewInitDisplayColumns(Tcl_Interp *interp, Treeview *tv) displayColumns[0] = &tv->tree.column0; if (tv->tree.displayColumns) - ckfree((ClientData)tv->tree.displayColumns); + ckfree(tv->tree.displayColumns); tv->tree.displayColumns = displayColumns; tv->tree.nDisplayColumns = ndcols + 1; @@ -1223,8 +1219,9 @@ static int ConfigureColumn( } if (mask & READONLY_OPTION) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "Attempt to change read-only option", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "Attempt to change read-only option", -1)); + Tcl_SetErrorCode(interp, "TTK", "TREE", "READONLY", NULL); goto error; } @@ -1237,11 +1234,10 @@ static int ConfigureColumn( TtkResizeWidget(&tv->core); } RecomputeSlack(tv); + ResizeColumns(tv, TreeWidth(tv)); } TtkRedisplayWidget(&tv->core); - /* ASSERT: SLACKINVARIANT */ - Tk_FreeSavedOptions(&savedOptions); return TCL_OK; @@ -1618,13 +1614,10 @@ static void TreeviewDoLayout(void *clientData) Treeview *tv = clientData; int visibleRows; - /* ASSERT: SLACKINVARIANT */ - Ttk_PlaceLayout(tv->core.layout,tv->core.state,Ttk_WinBox(tv->core.tkwin)); tv->tree.treeArea = Ttk_ClientRegion(tv->core.layout, "treearea"); ResizeColumns(tv, tv->tree.treeArea.width); - /* ASSERT: SLACKINVARIANT */ TtkScrolled(tv->tree.xscrollHandle, tv->tree.xscroll.first, @@ -1828,7 +1821,7 @@ static int DrawSubtree( static int DrawForest( Treeview *tv, TreeItem *item, Drawable d, int depth, int row) { - while (item && row <= tv->tree.yscroll.last) { + while (item && row < tv->tree.yscroll.last) { row = DrawSubtree(tv, item, d, depth, row); item = item->next; } @@ -1913,11 +1906,10 @@ static int AncestryCheck( TreeItem *p = parent; while (p) { if (p == item) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, - "Cannot insert ", ItemName(tv, item), - " as a descendant of ", ItemName(tv, parent), - NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "Cannot insert %s as descendant of %s", + ItemName(tv, item), ItemName(tv, parent))); + Tcl_SetErrorCode(interp, "TTK", "TREE", "ANCESTRY", NULL); return 0; } p = p->parent; @@ -1986,7 +1978,7 @@ static int TreeviewChildrenCommand( */ for (i=0; newChildren[i]; ++i) { if (!AncestryCheck(interp, tv, newChildren[i], item)) { - ckfree((ClientData)newChildren); + ckfree(newChildren); return TCL_ERROR; } } @@ -2022,7 +2014,7 @@ static int TreeviewChildrenCommand( child = newChildren[i]; } - ckfree((ClientData)newChildren); + ckfree(newChildren); TtkRedisplayWidget(&tv->core); } @@ -2237,7 +2229,9 @@ static int TreeviewHorribleIdentify( Ttk_Element element; BoundingBox(tv, item, NULL, &itemBox); - PrepareItem(tv, item, &displayItem); /*@@@ FIX: -text, etc*/ + PrepareItem(tv, item, &displayItem); + if (item->textObj) { displayItem.textObj = item->textObj; } + if (item->imageObj) { displayItem.imageObj = item->imageObj; } Ttk_RebindSublayout(layout, &displayItem); Ttk_PlaceLayout(layout, ItemState(tv,item), itemBox); element = Ttk_IdentifyElement(layout, x, y); @@ -2291,8 +2285,8 @@ static int TreeviewIdentifyCommand( return TCL_ERROR; } - if ( Tcl_GetIndexFromObj(interp, objv[2], - submethodStrings, "command", TCL_EXACT, &submethod) != TCL_OK + if (Tcl_GetIndexFromObjStruct(interp, objv[2], submethodStrings, + sizeof(char *), "command", TCL_EXACT, &submethod) != TCL_OK || Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK || Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK ) { @@ -2319,9 +2313,7 @@ static int TreeviewIdentifyCommand( case I_COLUMN : if (colno >= 0) { - char dcolbuf[16]; - sprintf(dcolbuf, "#%d", colno); - Tcl_SetObjResult(interp, Tcl_NewStringObj(dcolbuf, -1)); + Tcl_SetObjResult(interp, Tcl_ObjPrintf("#%d", colno)); } break; @@ -2351,7 +2343,9 @@ static int TreeviewIdentifyCommand( return TCL_OK; } - PrepareItem(tv, item, &displayItem); /*@@@ FIX: fill in -text,etc */ + PrepareItem(tv, item, &displayItem); + if (item->textObj) { displayItem.textObj = item->textObj; } + if (item->imageObj) { displayItem.imageObj = item->imageObj; } Ttk_RebindSublayout(layout, &displayItem); Ttk_PlaceLayout(layout, ItemState(tv,item), bbox); element = Ttk_IdentifyElement(layout, x, y); @@ -2489,9 +2483,9 @@ static int TreeviewSetCommand( for (columnNumber=0; columnNumber<tv->tree.nColumns; ++columnNumber) { Tcl_ListObjIndex(interp, item->valuesObj, columnNumber, &value); if (value) { - Tcl_ListObjAppendElement(interp, result, + Tcl_ListObjAppendElement(NULL, result, tv->tree.columns[columnNumber].idObj); - Tcl_ListObjAppendElement(interp, result, value); + Tcl_ListObjAppendElement(NULL, result, value); } } Tcl_SetObjResult(interp, result); @@ -2505,7 +2499,9 @@ static int TreeviewSetCommand( if (column == &tv->tree.column0) { /* @@@ Maybe set -text here instead? */ - Tcl_AppendResult(interp, "Display column #0 cannot be set", NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "Display column #0 cannot be set", -1)); + Tcl_SetErrorCode(interp, "TTK", "TREE", "COLUMN_0", NULL); return TCL_ERROR; } @@ -2588,9 +2584,12 @@ static int TreeviewInsertCommand( objc -= 4; objv += 4; if (objc >= 2 && !strcmp("-id", Tcl_GetString(objv[0]))) { const char *itemName = Tcl_GetString(objv[1]); + entryPtr = Tcl_CreateHashEntry(&tv->tree.items, itemName, &isNew); if (!isNew) { - Tcl_AppendResult(interp, "Item ",itemName," already exists",NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "Item %s already exists", itemName)); + Tcl_SetErrorCode(interp, "TTK", "TREE", "ITEM_EXISTS", NULL); return TCL_ERROR; } objc -= 2; objv += 2; @@ -2647,8 +2646,10 @@ static int TreeviewDetachCommand( /* Sanity-check */ for (i = 0; items[i]; ++i) { if (items[i] == tv->tree.root) { - Tcl_AppendResult(interp, "Cannot detach root item", NULL); - ckfree((ClientData)items); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "Cannot detach root item", -1)); + Tcl_SetErrorCode(interp, "TTK", "TREE", "ROOT", NULL); + ckfree(items); return TCL_ERROR; } } @@ -2658,7 +2659,7 @@ static int TreeviewDetachCommand( } TtkRedisplayWidget(&tv->core); - ckfree((ClientData)items); + ckfree(items); return TCL_OK; } @@ -2679,7 +2680,7 @@ static int TreeviewDeleteCommand( { Treeview *tv = recordPtr; TreeItem **items, *delq; - int i; + int i, selItemDeleted = 0; if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "items"); @@ -2694,8 +2695,10 @@ static int TreeviewDeleteCommand( */ for (i=0; items[i]; ++i) { if (items[i] == tv->tree.root) { - ckfree((ClientData)items); - Tcl_AppendResult(interp, "Cannot delete root item", NULL); + ckfree(items); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "Cannot delete root item", -1)); + Tcl_SetErrorCode(interp, "TTK", "TREE", "ROOT", NULL); return TCL_ERROR; } } @@ -2704,6 +2707,9 @@ static int TreeviewDeleteCommand( */ delq = 0; for (i=0; items[i]; ++i) { + if (items[i]->state & TTK_STATE_SELECTED) { + selItemDeleted = 1; + } delq = DeleteItems(items[i], delq); } @@ -2719,7 +2725,10 @@ static int TreeviewDeleteCommand( delq = next; } - ckfree((ClientData)items); + ckfree(items); + if (selItemDeleted) { + TtkSendVirtualEvent(tv->core.tkwin, "TreeviewSelect"); + } TtkRedisplayWidget(&tv->core); return TCL_OK; } @@ -2838,10 +2847,10 @@ static int TreeviewSeeCommand( */ rowNumber = RowNumber(tv, item); if (rowNumber < tv->tree.yscroll.first) { - TtkScrollTo(tv->tree.yscrollHandle, rowNumber); + TtkScrollTo(tv->tree.yscrollHandle, rowNumber, 1); } else if (rowNumber >= tv->tree.yscroll.last) { TtkScrollTo(tv->tree.yscrollHandle, - tv->tree.yscroll.first + (1+rowNumber - tv->tree.yscroll.last)); + tv->tree.yscroll.first + (1+rowNumber - tv->tree.yscroll.last), 1); } return TCL_OK; @@ -2878,21 +2887,53 @@ static int TreeviewDragCommand( TreeColumn *c = tv->tree.displayColumns[i]; int right = left + c->width; if (c == column) { - DragColumn(tv, i, newx - right); - /* ASSERT: SLACKINVARIANT */ - TtkRedisplayWidget(&tv->core); + /* The limit not to exceed at the right is given by the tree width + minus the sum of the min widths of the columns at the right of + the one being resized (and don't forget possible x scrolling!). + For stretchable columns, this min width really is the minWidth, + for non-stretchable columns, this is the column width. + */ + int newxRightLimit = tv->tree.treeArea.x - tv->tree.xscroll.first + + tv->tree.treeArea.width; + int j = i + 1; + while (j < tv->tree.nDisplayColumns) { + TreeColumn *cr = tv->tree.displayColumns[j]; + if (cr->stretch) { + newxRightLimit -= cr->minWidth; + } else { + newxRightLimit -= cr->width; + } + ++j; + } + if (newx <= newxRightLimit) { + DragColumn(tv, i, newx - right); + TtkRedisplayWidget(&tv->core); + } return TCL_OK; } left = right; } - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, - "column ", Tcl_GetString(objv[2]), " is not displayed", - NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "column %s is not displayed", Tcl_GetString(objv[2]))); + Tcl_SetErrorCode(interp, "TTK", "TREE", "COLUMN_INVISIBLE", NULL); return TCL_ERROR; } +static int TreeviewDropCommand( + void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) +{ + Treeview *tv = recordPtr; + + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, "drop"); + return TCL_ERROR; + } + ResizeColumns(tv, TreeWidth(tv)); + TtkRedisplayWidget(&tv->core); + return TCL_OK; +} + /*------------------------------------------------------------------------ * +++ Widget commands -- focus and selection */ @@ -2953,9 +2994,8 @@ static int TreeviewSelectionCommand( return TCL_ERROR; } - if (Tcl_GetIndexFromObj(interp, objv[2], selopStrings, - "selection operation", 0, &selop) != TCL_OK) - { + if (Tcl_GetIndexFromObjStruct(interp, objv[2], selopStrings, + sizeof(char *), "selection operation", 0, &selop) != TCL_OK) { return TCL_ERROR; } @@ -2988,7 +3028,7 @@ static int TreeviewSelectionCommand( break; } - ckfree((ClientData)items); + ckfree(items); TtkSendVirtualEvent(tv->core.tkwin, "TreeviewSelect"); TtkRedisplayWidget(&tv->core); @@ -3041,10 +3081,10 @@ static int TreeviewTagBindCommand( */ if (mask & (~TreeviewBindEventMask)) { Tk_DeleteBinding(interp, bindingTable, tag, sequence); - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "unsupported event ", sequence, - "\nonly key, button, motion, and virtual events supported", - NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "unsupported event %s\nonly key, button, motion, and" + " virtual events supported", sequence)); + Tcl_SetErrorCode(interp, "TTK", "TREE", "BIND_EVENTS", NULL); return TCL_ERROR; } } @@ -3243,6 +3283,7 @@ static const Ttk_Ensemble TreeviewCommands[] = { { "delete", TreeviewDeleteCommand,0 }, { "detach", TreeviewDetachCommand,0 }, { "drag", TreeviewDragCommand,0 }, + { "drop", TreeviewDropCommand,0 }, { "exists", TreeviewExistsCommand,0 }, { "focus", TreeviewFocusCommand,0 }, { "heading", TreeviewHeadingCommand,0 }, diff --git a/generic/ttk/ttkWidget.c b/generic/ttk/ttkWidget.c index 557ca8f..d7f4b25 100644 --- a/generic/ttk/ttkWidget.c +++ b/generic/ttk/ttkWidget.c @@ -198,7 +198,7 @@ WidgetInstanceObjCmdDeleted(ClientData clientData) * Final cleanup for widget; called via Tcl_EventuallyFree(). */ static void -FreeWidget(char *memPtr) +FreeWidget(void *memPtr) { ckfree(memPtr); } @@ -231,7 +231,7 @@ DestroyWidget(WidgetCore *corePtr) /* NB: this can reenter the interpreter via a command traces */ Tcl_DeleteCommandFromToken(corePtr->interp, cmd); } - Tcl_EventuallyFree(corePtr, FreeWidget); + Tcl_EventuallyFree(corePtr, (Tcl_FreeProc *) FreeWidget); } /* @@ -440,7 +440,8 @@ int TtkWidgetConstructorObjCmd( error: if (WidgetDestroyed(corePtr)) { - Tcl_SetResult(interp, "Widget has been destroyed", TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "widget has been destroyed", -1)); } else { Tk_DestroyWindow(tkwin); } @@ -634,8 +635,8 @@ int TtkWidgetConfigureCommand( return status; if (mask & READONLY_OPTION) { - Tcl_SetResult(interp, - "Attempt to change read-only option", TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "attempt to change read-only option", -1)); Tk_RestoreSavedOptions(&savedOptions); return TCL_ERROR; } @@ -649,7 +650,8 @@ int TtkWidgetConfigureCommand( status = corePtr->widgetSpec->postConfigureProc(interp,recordPtr,mask); if (WidgetDestroyed(corePtr)) { - Tcl_SetResult(interp, "Widget has been destroyed", TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "widget has been destroyed", -1)); status = TCL_ERROR; } if (status != TCL_OK) { @@ -764,8 +766,8 @@ int TtkWidgetIdentifyCommand( } if (objc == 5) { /* $w identify element $x $y */ - if (Tcl_GetIndexFromObj(interp,objv[2],whatTable,"option",0,&what) - != TCL_OK) + if (Tcl_GetIndexFromObjStruct(interp, objv[2], whatTable, + sizeof(char *), "option", 0, &what) != TCL_OK) { return TCL_ERROR; } diff --git a/generic/ttk/ttkWidget.h b/generic/ttk/ttkWidget.h index 9e9ab69..8a94bb7 100644 --- a/generic/ttk/ttkWidget.h +++ b/generic/ttk/ttkWidget.h @@ -195,7 +195,8 @@ MODULE_SCOPE void TtkFreeScrollHandle(ScrollHandle); MODULE_SCOPE int TtkScrollviewCommand( Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], ScrollHandle); -MODULE_SCOPE void TtkScrollTo(ScrollHandle, int newFirst); +MODULE_SCOPE void TtkUpdateScrollInfo(ScrollHandle h); +MODULE_SCOPE void TtkScrollTo(ScrollHandle, int newFirst, int updateScrollInfo); MODULE_SCOPE void TtkScrolled(ScrollHandle, int first, int last, int total); MODULE_SCOPE void TtkScrollbarUpdateRequired(ScrollHandle); @@ -260,7 +261,7 @@ MODULE_SCOPE int TtkGetLabelAnchorFromObj( * Platform-specific initialization. */ -#if defined(__WIN32__) +#ifdef _WIN32 #define Ttk_PlatformInit Ttk_WinPlatformInit MODULE_SCOPE int Ttk_PlatformInit(Tcl_Interp *); #elif defined(MAC_OSX_TK) |