From 08822bfc3683f6f3b0af04540c55847ed2b0ecd9 Mon Sep 17 00:00:00 2001 From: nijtmans Date: Wed, 12 Nov 2008 00:15:24 +0000 Subject: modify Tk_Create(Old)ImageType signature, relaxing the constraint that every Tk_ImageType can only be passed to this function once. This allows tkImg to be loaded in multiple interpreters in a thread-enabled build of Tk. This CONSTification complies with TIP #27. It is binary compatible with the old interface, but not fully source compatible (although tkImg does not suffer). --- ChangeLog | 11 +++++++ doc/CrtImgType.3 | 11 +++---- generic/tk.decls | 8 ++--- generic/tk.h | 6 ++-- generic/tkDecls.h | 14 ++++----- generic/tkImage.c | 83 ++++++++++++++++++++++++++++++++++++++++++---------- generic/tkImgBmap.c | 10 +++---- generic/tkImgPhoto.c | 20 ++++++------- generic/tkTest.c | 10 +++---- 9 files changed, 118 insertions(+), 55 deletions(-) diff --git a/ChangeLog b/ChangeLog index 17e5811..0365864 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,17 @@ * win/tcl.m4: reverted change from 2008-11-06 (was under the impression that "-Wno-implicit-int" added an extra warning) * win/configure (regenerated) + * generic/tk.decls modify Tk_Create(Old)ImageType signature, relaxing + * generic/tk.h the constraint that every Tk_ImageType can only + * generic/tkImage.c be passed to this function once. This allows + * generic/tkImgBmap.c tkImg to be loaded in multiple interpreters + * generic/tkImgPhoto.c in a thread-enabled build of Tk. + * generic/tkTest.c This CONSTification complies with TIP #27. It is + * doc/CrtImgType.3 binary compatible with the old interface, but not + fully source compatible (although tkImg does not suffer). + * generic/tkDecls.h (regenerated) + + *** POTENTIAL INCOMPATIBILITY *** 2008-11-09 Joe English diff --git a/doc/CrtImgType.3 b/doc/CrtImgType.3 index 5b074d2..2505272 100644 --- a/doc/CrtImgType.3 +++ b/doc/CrtImgType.3 @@ -5,7 +5,7 @@ '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" -'\" RCS: @(#) $Id: CrtImgType.3,v 1.15 2008/11/09 23:16:56 nijtmans Exp $ +'\" RCS: @(#) $Id: CrtImgType.3,v 1.16 2008/11/12 00:15:26 nijtmans Exp $ '\" .so man.macros .TH Tk_CreateImageType 3 8.5 Tk "Tk Library Procedures" @@ -23,11 +23,12 @@ ClientData .sp \fBTk_InitImageArgs\fR(\fIinterp, argc, argvPtr\fR) .SH ARGUMENTS -.AS Tk_ImageType *typePtrPtr -.AP Tk_ImageType *typePtr in +.AS "const Tk_ImageType" *typePtrPtr +.AP "const Tk_ImageType" *typePtr in Structure that defines the new type of image. -Must be static: a +For Tk 8.4 and earlier this must be static: a pointer to this structure is retained by the image code. +In Tk 8.5, this limitation was relaxed. .AP Tcl_Interp *interp in Interpreter in which image was created. .AP "const char" *name in @@ -113,7 +114,7 @@ typedef int \fBTk_ImageCreateProc\fR( const char *\fIname\fR, int \fIobjc\fR, Tcl_Obj *const \fIobjv\fR[], - Tk_ImageType *\fItypePtr\fR, + const Tk_ImageType *\fItypePtr\fR, Tk_ImageMaster \fImaster\fR, ClientData *\fImasterDataPtr\fR); .CE diff --git a/generic/tk.decls b/generic/tk.decls index 632c85f..8d3740e 100644 --- a/generic/tk.decls +++ b/generic/tk.decls @@ -11,7 +11,7 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # -# RCS: @(#) $Id: tk.decls,v 1.44 2008/11/09 23:16:56 nijtmans Exp $ +# RCS: @(#) $Id: tk.decls,v 1.45 2008/11/12 00:15:24 nijtmans Exp $ library tk @@ -185,7 +185,7 @@ declare 37 generic { void Tk_CreateGenericHandler(Tk_GenericProc *proc, ClientData clientData) } declare 38 generic { - void Tk_CreateImageType(Tk_ImageType *typePtr) + void Tk_CreateImageType(const Tk_ImageType *typePtr) } declare 39 generic { void Tk_CreateItemType(Tk_ItemType *typePtr) @@ -405,7 +405,7 @@ declare 97 generic { } declare 98 generic { ClientData Tk_GetImageMasterData(Tcl_Interp *interp, - const char *name, Tk_ImageType **typePtrPtr) + const char *name, CONST86 Tk_ImageType **typePtrPtr) } declare 99 generic { Tk_ItemType * Tk_GetItemTypes(void) @@ -1068,7 +1068,7 @@ declare 271 generic { # Developers who need to produce a file [load]able into legacy interps must # build against legacy sources. declare 272 generic { - void Tk_CreateOldImageType(Tk_ImageType *typePtr) + void Tk_CreateOldImageType(const Tk_ImageType *typePtr) } declare 273 generic { void Tk_CreateOldPhotoImageFormat(const Tk_PhotoImageFormat *formatPtr) diff --git a/generic/tk.h b/generic/tk.h index 003143c..516205b 100644 --- a/generic/tk.h +++ b/generic/tk.h @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tk.h,v 1.123 2008/11/02 11:20:03 dkf Exp $ + * RCS: @(#) $Id: tk.h,v 1.124 2008/11/12 00:15:26 nijtmans Exp $ */ #ifndef _TK @@ -1187,8 +1187,8 @@ 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) (Tcl_Interp *interp, char *name, int objc, - Tcl_Obj *const objv[], Tk_ImageType *typePtr, Tk_ImageMaster master, +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 typedef ClientData (Tk_ImageGetProc) (Tk_Window tkwin, ClientData masterData); diff --git a/generic/tkDecls.h b/generic/tkDecls.h index a105ab0..16af814 100644 --- a/generic/tkDecls.h +++ b/generic/tkDecls.h @@ -8,7 +8,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkDecls.h,v 1.39 2008/11/09 23:16:56 nijtmans Exp $ + * RCS: @(#) $Id: tkDecls.h,v 1.40 2008/11/12 00:15:26 nijtmans Exp $ */ #ifndef _TKDECLS @@ -284,7 +284,7 @@ EXTERN void Tk_CreateGenericHandler (Tk_GenericProc * proc, #ifndef Tk_CreateImageType_TCL_DECLARED #define Tk_CreateImageType_TCL_DECLARED /* 38 */ -EXTERN void Tk_CreateImageType (Tk_ImageType * typePtr); +EXTERN void Tk_CreateImageType (const Tk_ImageType * typePtr); #endif #ifndef Tk_CreateItemType_TCL_DECLARED #define Tk_CreateItemType_TCL_DECLARED @@ -650,7 +650,7 @@ EXTERN Tk_Image Tk_GetImage (Tcl_Interp * interp, Tk_Window tkwin, /* 98 */ EXTERN ClientData Tk_GetImageMasterData (Tcl_Interp * interp, const char * name, - Tk_ImageType ** typePtrPtr); + CONST86 Tk_ImageType ** typePtrPtr); #endif #ifndef Tk_GetItemTypes_TCL_DECLARED #define Tk_GetItemTypes_TCL_DECLARED @@ -1686,7 +1686,7 @@ EXTERN Tcl_Interp * Tk_Interp (Tk_Window tkwin); #ifndef Tk_CreateOldImageType_TCL_DECLARED #define Tk_CreateOldImageType_TCL_DECLARED /* 272 */ -EXTERN void Tk_CreateOldImageType (Tk_ImageType * typePtr); +EXTERN void Tk_CreateOldImageType (const Tk_ImageType * typePtr); #endif #ifndef Tk_CreateOldPhotoImageFormat_TCL_DECLARED #define Tk_CreateOldPhotoImageFormat_TCL_DECLARED @@ -1744,7 +1744,7 @@ typedef struct TkStubs { 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) (const Tk_PhotoImageFormat * formatPtr); /* 40 */ void (*tk_CreateSelHandler) (Tk_Window tkwin, Atom selection, Atom target, Tk_SelectionProc * proc, ClientData clientData, Atom format); /* 41 */ @@ -1804,7 +1804,7 @@ typedef struct TkStubs { 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 */ + 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 */ @@ -1978,7 +1978,7 @@ 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_CreateOldImageType) (const Tk_ImageType * typePtr); /* 272 */ void (*tk_CreateOldPhotoImageFormat) (const Tk_PhotoImageFormat * formatPtr); /* 273 */ } TkStubs; diff --git a/generic/tkImage.c b/generic/tkImage.c index 0f25906..3ce3a8d 100644 --- a/generic/tkImage.c +++ b/generic/tkImage.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkImage.c,v 1.40 2008/11/08 18:44:40 dkf Exp $ + * RCS: @(#) $Id: tkImage.c,v 1.41 2008/11/12 00:15:26 nijtmans Exp $ */ #include "tkInt.h" @@ -74,6 +74,8 @@ typedef struct ThreadSpecificData { Tk_ImageType *oldImageTypeList; /* First in a list of all known old-style * image types. */ + int initialized; /* Set to 1 if we've initialized the + * structure. */ } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; @@ -81,6 +83,7 @@ static Tcl_ThreadDataKey dataKey; * Prototypes for local functions: */ +static void ImageTypeThreadExitProc(ClientData clientData); static void DeleteImage(ImageMaster *masterPtr); static void EventuallyDeleteImage(ImageMaster *masterPtr, int forgetImageHashNow); @@ -88,6 +91,42 @@ static void EventuallyDeleteImage(ImageMaster *masterPtr, /* *---------------------------------------------------------------------- * + * ImageTypeThreadExitProc -- + * + * Clean up the registered list of image types. + * + * Results: + * None. + * + * Side effects: + * The thread's linked lists of photo image formats is deleted. + * + *---------------------------------------------------------------------- + */ + +static void +ImageTypeThreadExitProc( + ClientData clientData) /* not used */ +{ + 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); + } + while (tsdPtr->imageTypeList != NULL) { + freePtr = tsdPtr->imageTypeList; + tsdPtr->imageTypeList = tsdPtr->imageTypeList->nextPtr; + ckfree((char *) freePtr); + } +} + +/* + *---------------------------------------------------------------------- + * * Tk_CreateOldImageType, Tk_CreateImageType -- * * This function is invoked by an image manager to tell Tk about a new @@ -106,30 +145,42 @@ static void EventuallyDeleteImage(ImageMaster *masterPtr, 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. Must not have been passed to - * Tk_CreateImageType previously. */ + * by caller. */ { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + Tk_ImageType *copyPtr; + ThreadSpecificData *tsdPtr = + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - typePtr->nextPtr = tsdPtr->oldImageTypeList; - tsdPtr->oldImageTypeList = typePtr; + if (!tsdPtr->initialized) { + tsdPtr->initialized = 1; + Tcl_CreateThreadExitHandler(ImageTypeThreadExitProc, NULL); + } + copyPtr = (Tk_ImageType *) ckalloc(sizeof(Tk_ImageType)); + *copyPtr = *typePtr; + copyPtr->nextPtr = tsdPtr->oldImageTypeList; + tsdPtr->oldImageTypeList = copyPtr; } 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. Must not have been passed to - * Tk_CreateImageType previously. */ + * by caller. */ { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + Tk_ImageType *copyPtr; + ThreadSpecificData *tsdPtr = + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - typePtr->nextPtr = tsdPtr->imageTypeList; - tsdPtr->imageTypeList = typePtr; + if (!tsdPtr->initialized) { + tsdPtr->initialized = 1; + Tcl_CreateThreadExitHandler(ImageTypeThreadExitProc, NULL); + } + copyPtr = (Tk_ImageType *) ckalloc(sizeof(Tk_ImageType)); + *copyPtr = *typePtr; + copyPtr->nextPtr = tsdPtr->imageTypeList; + tsdPtr->imageTypeList = copyPtr; } /* @@ -1011,7 +1062,7 @@ 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 Tk_ImageType **typePtrPtr) /* Points to location to fill in with pointer * to type information for image. */ { Tcl_HashEntry *hPtr; diff --git a/generic/tkImgBmap.c b/generic/tkImgBmap.c index 3fc7561..b7de72a 100644 --- a/generic/tkImgBmap.c +++ b/generic/tkImgBmap.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkImgBmap.c,v 1.26 2008/11/05 22:48:58 nijtmans Exp $ + * RCS: @(#) $Id: tkImgBmap.c,v 1.27 2008/11/12 00:15:26 nijtmans Exp $ */ #include "tkInt.h" @@ -77,8 +77,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, @@ -175,11 +175,11 @@ 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 * 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 diff --git a/generic/tkImgPhoto.c b/generic/tkImgPhoto.c index 0c19640..6213472 100644 --- a/generic/tkImgPhoto.c +++ b/generic/tkImgPhoto.c @@ -17,7 +17,7 @@ * Department of Computer Science, * Australian National University. * - * RCS: @(#) $Id: tkImgPhoto.c,v 1.85 2008/11/09 23:16:56 nijtmans Exp $ + * RCS: @(#) $Id: tkImgPhoto.c,v 1.86 2008/11/12 00:15:26 nijtmans Exp $ */ #include "tkImgPhoto.h" @@ -77,7 +77,7 @@ struct SubcommandOptions { * of the OPT_* constants above. */ -static const char *optionNames[] = { +static const char *const optionNames[] = { "-background", "-compositingrule", "-format", @@ -102,9 +102,9 @@ static const char *optionNames[] = { * Functions used in the type record for photo images. */ -static int ImgPhotoCreate(Tcl_Interp *interp, char *name, +static int ImgPhotoCreate(Tcl_Interp *interp, const char *name, int objc, Tcl_Obj *const objv[], - Tk_ImageType *typePtr, Tk_ImageMaster master, + const Tk_ImageType *typePtr, Tk_ImageMaster master, ClientData *clientDataPtr); static void ImgPhotoDelete(ClientData clientData); static int ImgPhotoPostscript(ClientData clientData, @@ -135,7 +135,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; @@ -333,11 +333,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 * 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 @@ -1401,8 +1401,8 @@ ParseSubcommandOptions( { int index, c, bit, currentBit, length; int values[4], numValues, maxValues, argIndex; - char *option; - const char **listPtr; + const char *option; + const char *const *listPtr; for (index = *optIndexPtr; index < objc; *optIndexPtr = ++index) { /* @@ -2518,7 +2518,7 @@ Tk_FindPhoto( * exists. */ const char *imageName) /* Name of the desired photo image. */ { - Tk_ImageType *typePtr; + const Tk_ImageType *typePtr; ClientData clientData = Tk_GetImageMasterData(interp, imageName, &typePtr); diff --git a/generic/tkTest.c b/generic/tkTest.c index cba8546..b7a27a6 100644 --- a/generic/tkTest.c +++ b/generic/tkTest.c @@ -13,7 +13,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkTest.c,v 1.40 2008/10/30 23:18:59 nijtmans Exp $ + * RCS: @(#) $Id: tkTest.c,v 1.41 2008/11/12 00:15:26 nijtmans Exp $ */ #include "tkInt.h" @@ -61,8 +61,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, @@ -1491,11 +1491,11 @@ 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 -- cgit v0.12