summaryrefslogtreecommitdiffstats
path: root/generic/tkTest.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tkTest.c')
-rw-r--r--generic/tkTest.c201
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));
}