diff options
Diffstat (limited to 'generic/tkTest.c')
-rw-r--r-- | generic/tkTest.c | 201 |
1 files changed, 95 insertions, 106 deletions
diff --git a/generic/tkTest.c b/generic/tkTest.c index ae67f11..4347600 100644 --- a/generic/tkTest.c +++ b/generic/tkTest.c @@ -31,9 +31,9 @@ #if defined(MAC_OSX_TK) #include "tkMacOSXInt.h" #include "tkScrollbar.h" -#define LOG_DISPLAY TkTestLogDisplay() +#define LOG_DISPLAY(drawable) TkTestLogDisplay(drawable) #else -#define LOG_DISPLAY 1 +#define LOG_DISPLAY(drawable) 1 #endif #ifdef __UNIX__ @@ -57,17 +57,17 @@ EXTERN int Tktest_Init(Tcl_Interp *interp); #endif /* - * The following data structure represents the master for a test image: + * The following data structure represents the model for a test image: */ -typedef struct TImageMaster { - Tk_ImageMaster master; /* Tk's token for image master. */ +typedef struct TImageModel { + Tk_ImageModel model; /* Tk's token for image model. */ Tcl_Interp *interp; /* Interpreter for application. */ int width, height; /* Dimensions of image. */ char *imageName; /* Name of image (malloc-ed). */ char *varName; /* Name of variable in which to log events for * image (malloc-ed). */ -} TImageMaster; +} TImageModel; /* * The following data structure represents a particular use of a particular @@ -75,9 +75,11 @@ typedef struct TImageMaster { */ typedef struct TImageInstance { - TImageMaster *masterPtr; /* Pointer to master for image. */ + TImageModel *modelPtr; /* Pointer to model for image. */ XColor *fg; /* Foreground color for drawing in image. */ GC gc; /* Graphics context for drawing in image. */ + Bool displayFailed; /* macOS display attempted out of drawRect. */ + char buffer[200 + TCL_INTEGER_SPACE * 6]; /* message to log on display. */ } TImageInstance; /* @@ -86,7 +88,7 @@ typedef struct TImageInstance { static int ImageCreate(Tcl_Interp *interp, const char *name, int argc, Tcl_Obj *const objv[], - const Tk_ImageType *typePtr, Tk_ImageMaster master, + const Tk_ImageType *typePtr, Tk_ImageModel model, ClientData *clientDataPtr); static ClientData ImageGet(Tk_Window tkwin, ClientData clientData); static void ImageDisplay(ClientData clientData, @@ -332,13 +334,11 @@ Tktest_Init( static int TestbitmapObjCmd( - ClientData clientData, /* Main window for application. */ + TCL_UNUSED(void *), /* Main window for application. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - (void)clientData; - if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "bitmap"); return TCL_ERROR; @@ -367,13 +367,11 @@ TestbitmapObjCmd( static int TestborderObjCmd( - ClientData clientData, /* Main window for application. */ + TCL_UNUSED(ClientData), /* Main window for application. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - (void)clientData; - if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "border"); return TCL_ERROR; @@ -402,13 +400,11 @@ TestborderObjCmd( static int TestcolorObjCmd( - ClientData clientData, /* Main window for application. */ + TCL_UNUSED(void *), /* Main window for application. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - (void)clientData; - if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "color"); return TCL_ERROR; @@ -437,13 +433,11 @@ TestcolorObjCmd( static int TestcursorObjCmd( - ClientData clientData, /* Main window for application. */ + TCL_UNUSED(void *), /* Main window for application. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - (void)clientData; - if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "cursor"); return TCL_ERROR; @@ -473,16 +467,12 @@ TestcursorObjCmd( static int TestdeleteappsObjCmd( - ClientData clientData, /* Main window for application. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument strings. */ + TCL_UNUSED(void *), /* Main window for application. */ + TCL_UNUSED(Tcl_Interp *), /* Current interpreter. */ + TCL_UNUSED(int), /* Number of arguments. */ + TCL_UNUSED(Tcl_Obj *const *)) /* Argument strings. */ { NewApp *nextPtr; - (void)clientData; - (void)interp; - (void)objc; - (void)objv; while (newAppPtr != NULL) { nextPtr = newAppPtr->nextPtr; @@ -548,7 +538,7 @@ TestobjconfigObjCmd( * "chain2" subcommand: */ - typedef struct ExtensionWidgetRecord { + typedef struct { TrivialCommandHeader header; Tcl_Obj *base1ObjPtr; Tcl_Obj *base2ObjPtr; @@ -576,7 +566,7 @@ TestobjconfigObjCmd( switch (index) { case ALL_TYPES: { - typedef struct TypesRecord { + typedef struct { TrivialCommandHeader header; Tcl_Obj *booleanPtr; Tcl_Obj *integerPtr; @@ -649,7 +639,6 @@ TestobjconfigObjCmd( {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0} }; Tk_OptionTable optionTable; - Tk_Window tkwin; optionTable = Tk_CreateOptionTable(interp, typesSpecs); tables[index] = optionTable; @@ -705,7 +694,6 @@ TestobjconfigObjCmd( case CHAIN1: { ExtensionWidgetRecord *recordPtr; - Tk_Window tkwin; Tk_OptionTable optionTable; tkwin = Tk_CreateWindowFromPath(interp, (Tk_Window)clientData, @@ -758,7 +746,6 @@ TestobjconfigObjCmd( {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, (ClientData) baseSpecs, 0} }; - Tk_Window tkwin; Tk_OptionTable optionTable; tkwin = Tk_CreateWindowFromPath(interp, (Tk_Window)clientData, @@ -797,7 +784,7 @@ TestobjconfigObjCmd( } case CONFIG_ERROR: { - typedef struct ErrorWidgetRecord { + typedef struct { Tcl_Obj *intPtr; } ErrorWidgetRecord; ErrorWidgetRecord widgetRecord; @@ -851,7 +838,7 @@ TestobjconfigObjCmd( * objects. */ - typedef struct InternalRecord { + typedef struct { TrivialCommandHeader header; int boolean; int integer; @@ -927,7 +914,6 @@ TestobjconfigObjCmd( {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0} }; Tk_OptionTable optionTable; - Tk_Window tkwin; optionTable = Tk_CreateOptionTable(interp, internalSpecs); tables[index] = optionTable; @@ -983,7 +969,7 @@ TestobjconfigObjCmd( } case NEW: { - typedef struct FiveRecord { + typedef struct { TrivialCommandHeader header; Tcl_Obj *one; Tcl_Obj *two; @@ -1042,7 +1028,7 @@ TestobjconfigObjCmd( break; } case NOT_ENOUGH_PARAMS: { - typedef struct NotEnoughRecord { + typedef struct { Tcl_Obj *fooObjPtr; } NotEnoughRecord; NotEnoughRecord record; @@ -1072,17 +1058,17 @@ TestobjconfigObjCmd( } case TWO_WINDOWS: { - typedef struct SlaveRecord { + typedef struct { TrivialCommandHeader header; Tcl_Obj *windowPtr; - } SlaveRecord; - SlaveRecord *recordPtr; - static const Tk_OptionSpec slaveSpecs[] = { + } ContentRecord; + ContentRecord *recordPtr; + static const Tk_OptionSpec contentSpecs[] = { {TK_OPTION_WINDOW, "-window", "window", "Window", ".bar", - offsetof(SlaveRecord, windowPtr), TCL_INDEX_NONE, TK_CONFIG_NULL_OK, NULL, 0}, + offsetof(ContentRecord, windowPtr), TCL_INDEX_NONE, TK_CONFIG_NULL_OK, NULL, 0}, {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0} }; - Tk_Window tkwin = Tk_CreateWindowFromPath(interp, + tkwin = Tk_CreateWindowFromPath(interp, (Tk_Window)clientData, Tcl_GetString(objv[2]), NULL); if (tkwin == NULL) { @@ -1090,10 +1076,10 @@ TestobjconfigObjCmd( } Tk_SetClass(tkwin, "Test"); - recordPtr = (SlaveRecord *)ckalloc(sizeof(SlaveRecord)); + recordPtr = (ContentRecord *)ckalloc(sizeof(ContentRecord)); recordPtr->header.interp = interp; recordPtr->header.optionTable = Tk_CreateOptionTable(interp, - slaveSpecs); + contentSpecs); tables[index] = recordPtr->header.optionTable; recordPtr->header.tkwin = tkwin; recordPtr->windowPtr = NULL; @@ -1164,7 +1150,7 @@ TrivialConfigObjCmd( Tk_SavedOptions saved; if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg...?"); + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); return TCL_ERROR; } @@ -1392,16 +1378,15 @@ ImageCreate( int objc, /* Number of arguments. */ Tcl_Obj *const objv[], /* Argument strings for options (doesn't * include image name or type). */ - const Tk_ImageType *typePtr, /* Pointer to our type record (not used). */ - Tk_ImageMaster master, /* Token for image, to be used by us in later + TCL_UNUSED(const Tk_ImageType *), /* Pointer to our type record (not used). */ + Tk_ImageModel model, /* 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; + TImageModel *timPtr; const char *varName; int i; - (void)typePtr; varName = "log"; for (i = 0; i < objc; i += 2) { @@ -1418,8 +1403,8 @@ ImageCreate( varName = Tcl_GetString(objv[i+1]); } - timPtr = (TImageMaster *)ckalloc(sizeof(TImageMaster)); - timPtr->master = master; + timPtr = (TImageModel *)ckalloc(sizeof(TImageModel)); + timPtr->model = model; timPtr->interp = interp; timPtr->width = 30; timPtr->height = 15; @@ -1429,7 +1414,7 @@ ImageCreate( strcpy(timPtr->varName, varName); Tcl_CreateObjCommand(interp, name, ImageObjCmd, timPtr, NULL); *clientDataPtr = timPtr; - Tk_ImageChanged(master, 0, 0, 30, 15, 30, 15); + Tk_ImageChanged(model, 0, 0, 30, 15, 30, 15); return TCL_OK; } @@ -1457,7 +1442,7 @@ ImageObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument strings. */ { - TImageMaster *timPtr = (TImageMaster *)clientData; + TImageModel *timPtr = (TImageModel *)clientData; int x, y, width, height; if (objc < 2) { @@ -1478,7 +1463,7 @@ ImageObjCmd( || (Tcl_GetIntFromObj(interp, objv[7], &timPtr->height) != TCL_OK)) { return TCL_ERROR; } - Tk_ImageChanged(timPtr->master, x, y, width, height, timPtr->width, + Tk_ImageChanged(timPtr->model, x, y, width, height, timPtr->width, timPtr->height); } else { Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[1]), @@ -1510,9 +1495,9 @@ static ClientData ImageGet( Tk_Window tkwin, /* Token for window in which image will be * used. */ - ClientData clientData) /* Pointer to TImageMaster for image. */ + ClientData clientData) /* Pointer to TImageModel for image. */ { - TImageMaster *timPtr = (TImageMaster *)clientData; + TImageModel *timPtr = (TImageModel *)clientData; TImageInstance *instPtr; char buffer[100]; XGCValues gcValues; @@ -1522,10 +1507,11 @@ ImageGet( TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT); instPtr = (TImageInstance *)ckalloc(sizeof(TImageInstance)); - instPtr->masterPtr = timPtr; + instPtr->modelPtr = timPtr; instPtr->fg = Tk_GetColor(timPtr->interp, tkwin, "#ff0000"); gcValues.foreground = instPtr->fg->pixel; instPtr->gc = Tk_GetGC(tkwin, GCForeground, &gcValues); + instPtr->displayFailed = False; return instPtr; } @@ -1560,47 +1546,56 @@ ImageDisplay( * imageX and imageY. */ { TImageInstance *instPtr = (TImageInstance *)clientData; - char buffer[200 + TCL_INTEGER_SPACE * 6]; /* * 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 + * 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). + * it schedules a redraw of the NSView. * - * 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. + * In an attempt to work around this, each image instance maintains it own + * copy of the log message which gets written on the first call to the + * display proc. This usually means that the message created on macOS is + * the same as that created on other platforms. However it is possible + * for the messages to differ for other reasons, namely differences in + * how damage regions are computed. */ - 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 (LOG_DISPLAY(drawable)) { + if (instPtr->displayFailed == False) { + + /* + * Drawing is possible on the first call to DisplayImage. + * Log the message. + */ + + sprintf(instPtr->buffer, "%s display %d %d %d %d", + instPtr->modelPtr->imageName, imageX, imageY, width, height); + } + Tcl_SetVar2(instPtr->modelPtr->interp, instPtr->modelPtr->varName, + NULL, instPtr->buffer, + TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT); + instPtr->displayFailed = False; + } else { + + /* + * Drawing is not possible on the first call to DisplayImage. + * Save the message, but do not log it until the actual display. + */ + + if (instPtr->displayFailed == False) { + sprintf(instPtr->buffer, "%s display %d %d %d %d", + instPtr->modelPtr->imageName, imageX, imageY, width, height); + } + instPtr->displayFailed = True; } - if (width > (instPtr->masterPtr->width - imageX)) { - width = instPtr->masterPtr->width - imageX; + if (width > (instPtr->modelPtr->width - imageX)) { + width = instPtr->modelPtr->width - imageX; } - if (height > (instPtr->masterPtr->height - imageY)) { - height = instPtr->masterPtr->height - imageY; + if (height > (instPtr->modelPtr->height - imageY)) { + height = instPtr->modelPtr->height - imageY; } XDrawRectangle(display, drawable, instPtr->gc, drawableX, drawableY, @@ -1637,8 +1632,8 @@ ImageFree( TImageInstance *instPtr = (TImageInstance *)clientData; char buffer[200]; - sprintf(buffer, "%s free", instPtr->masterPtr->imageName); - Tcl_SetVar2(instPtr->masterPtr->interp, instPtr->masterPtr->varName, NULL, + sprintf(buffer, "%s free", instPtr->modelPtr->imageName); + Tcl_SetVar2(instPtr->modelPtr->interp, instPtr->modelPtr->varName, NULL, buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT); Tk_FreeColor(instPtr->fg); Tk_FreeGC(display, instPtr->gc); @@ -1664,11 +1659,11 @@ ImageFree( static void ImageDelete( - ClientData clientData) /* Pointer to TImageMaster for image. When + ClientData clientData) /* Pointer to TImageModel for image. When * this function is called, no more instances * exist. */ { - TImageMaster *timPtr = (TImageMaster *)clientData; + TImageModel *timPtr = (TImageModel *)clientData; char buffer[100]; sprintf(buffer, "%s delete", timPtr->imageName); @@ -1808,14 +1803,13 @@ TestmenubarObjCmd( #if defined(_WIN32) static int TestmetricsObjCmd( - ClientData dummy, /* Main window for application. */ + TCL_UNUSED(void *), /* Main window for application. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument strings. */ { char buf[TCL_INTEGER_SPACE]; int val; - (void)dummy; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); @@ -2045,9 +2039,9 @@ TestwrapperObjCmd( static int CustomOptionSet( - ClientData dummy, + TCL_UNUSED(void *), Tcl_Interp *interp, - Tk_Window tkwin, + TCL_UNUSED(Tk_Window), Tcl_Obj **value, char *recordPtr, TkSizeT internalOffset, @@ -2056,8 +2050,6 @@ CustomOptionSet( { int objEmpty; char *newStr, *string, *internalPtr; - (void)dummy; - (void)tkwin; objEmpty = 0; @@ -2108,14 +2100,11 @@ CustomOptionSet( static Tcl_Obj * CustomOptionGet( - ClientData dummy, - Tk_Window tkwin, + TCL_UNUSED(void *), + TCL_UNUSED(Tk_Window), char *recordPtr, TkSizeT internalOffset) { - (void)dummy; - (void)tkwin; - return (Tcl_NewStringObj(*(char **)(recordPtr + internalOffset), -1)); } |