summaryrefslogtreecommitdiffstats
path: root/generic/tkCanvas.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tkCanvas.c')
-rw-r--r--generic/tkCanvas.c129
1 files changed, 75 insertions, 54 deletions
diff --git a/generic/tkCanvas.c b/generic/tkCanvas.c
index c095f7e..2ec336d 100644
--- a/generic/tkCanvas.c
+++ b/generic/tkCanvas.c
@@ -6,13 +6,13 @@
* objects such as rectangles, lines, and texts.
*
* Copyright (c) 1991-1994 The Regents of the University of California.
- * Copyright (c) 1994-1995 Sun Microsystems, Inc.
+ * Copyright (c) 1994-1997 Sun Microsystems, Inc.
* Copyright (c) 1998 by Scriptics Corporation.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkCanvas.c,v 1.3 1998/10/13 18:13:06 rjohnson Exp $
+ * RCS: @(#) $Id: tkCanvas.c,v 1.4 1999/04/16 01:51:12 stanton Exp $
*/
#include "default.h"
@@ -152,20 +152,6 @@ extern Tk_ItemType tkOvalType, tkPolygonType;
extern Tk_ItemType tkRectangleType, tkTextType, tkWindowType;
/*
- * Various Tk_Uid's used by this module (set up during initialization):
- */
-
-static Tk_Uid allUid = NULL;
-static Tk_Uid currentUid = NULL;
-
-/*
- * Statistics counters:
- */
-
-static int numIdSearches;
-static int numSlowSearches;
-
-/*
* Prototypes for procedures defined later in this file:
*/
@@ -356,7 +342,7 @@ Tk_CanvasCmd(clientData, interp, argc, argv)
canvasPtr->nextId = 1;
canvasPtr->psInfoPtr = NULL;
Tcl_InitHashTable(&canvasPtr->idTable, TCL_ONE_WORD_KEYS);
-
+
Tk_SetClass(canvasPtr->tkwin, "Canvas");
TkSetClassProcs(canvasPtr->tkwin, &canvasClass, (ClientData) canvasPtr);
Tk_CreateEventHandler(canvasPtr->tkwin,
@@ -372,7 +358,7 @@ Tk_CanvasCmd(clientData, interp, argc, argv)
goto error;
}
- interp->result = Tk_PathName(canvasPtr->tkwin);
+ Tcl_SetResult(interp, Tk_PathName(canvasPtr->tkwin), TCL_STATIC);
return TCL_OK;
error:
@@ -475,7 +461,10 @@ CanvasWidgetCmd(clientData, interp, argc, argv)
}
}
if (gotAny) {
- sprintf(interp->result, "%d %d %d %d", x1, y1, x2, y2);
+ char buf[TCL_INTEGER_SPACE * 4];
+
+ sprintf(buf, "%d %d %d %d", x1, y1, x2, y2);
+ Tcl_SetResult(interp, buf, TCL_VOLATILE);
}
} else if ((c == 'b') && (strncmp(argv[1], "bind", length) == 0)
&& (length >= 2)) {
@@ -565,15 +554,30 @@ CanvasWidgetCmd(clientData, interp, argc, argv)
command = Tk_GetBinding(interp, canvasPtr->bindingTable,
object, argv[3]);
if (command == NULL) {
- goto error;
+ char *string;
+
+ string = Tcl_GetStringResult(interp);
+ /*
+ * Ignore missing binding errors. This is a special hack
+ * that relies on the error message returned by FindSequence
+ * in tkBind.c.
+ */
+
+ if (string[0] != '\0') {
+ goto error;
+ } else {
+ Tcl_ResetResult(interp);
+ }
+ } else {
+ Tcl_SetResult(interp, command, TCL_STATIC);
}
- interp->result = command;
} else {
Tk_GetAllBindings(interp, canvasPtr->bindingTable, object);
}
} else if ((c == 'c') && (strcmp(argv[1], "canvasx") == 0)) {
int x;
double grid;
+ char buf[TCL_DOUBLE_SPACE];
if ((argc < 3) || (argc > 4)) {
Tcl_AppendResult(interp, "wrong # args: should be \"",
@@ -593,10 +597,12 @@ CanvasWidgetCmd(clientData, interp, argc, argv)
grid = 0.0;
}
x += canvasPtr->xOrigin;
- Tcl_PrintDouble(interp, GridAlign((double) x, grid), interp->result);
+ Tcl_PrintDouble(interp, GridAlign((double) x, grid), buf);
+ Tcl_SetResult(interp, buf, TCL_VOLATILE);
} else if ((c == 'c') && (strcmp(argv[1], "canvasy") == 0)) {
int y;
double grid;
+ char buf[TCL_DOUBLE_SPACE];
if ((argc < 3) || (argc > 4)) {
Tcl_AppendResult(interp, "wrong # args: should be \"",
@@ -616,7 +622,8 @@ CanvasWidgetCmd(clientData, interp, argc, argv)
grid = 0.0;
}
y += canvasPtr->yOrigin;
- Tcl_PrintDouble(interp, GridAlign((double) y, grid), interp->result);
+ Tcl_PrintDouble(interp, GridAlign((double) y, grid), buf);
+ Tcl_SetResult(interp, buf, TCL_VOLATILE);
} else if ((c == 'c') && (strncmp(argv[1], "cget", length) == 0)
&& (length >= 2)) {
if (argc != 3) {
@@ -667,9 +674,10 @@ CanvasWidgetCmd(clientData, interp, argc, argv)
Tk_ItemType *typePtr;
Tk_ItemType *matchPtr = NULL;
Tk_Item *itemPtr;
+ char buf[TCL_INTEGER_SPACE];
int isNew = 0;
Tcl_HashEntry *entryPtr;
-
+
if (argc < 3) {
Tcl_AppendResult(interp, "wrong # args: should be \"",
argv[0], " create type ?arg arg ...?\"", (char *) NULL);
@@ -722,7 +730,8 @@ CanvasWidgetCmd(clientData, interp, argc, argv)
Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr,
itemPtr->x1, itemPtr->y1, itemPtr->x2, itemPtr->y2);
canvasPtr->flags |= REPICK_NEEDED;
- sprintf(interp->result, "%d", itemPtr->id);
+ sprintf(buf, "%d", itemPtr->id);
+ Tcl_SetResult(interp, buf, TCL_VOLATILE);
} else if ((c == 'd') && (strncmp(argv[1], "dchars", length) == 0)
&& (length >= 2)) {
int first, last;
@@ -870,7 +879,10 @@ CanvasWidgetCmd(clientData, interp, argc, argv)
itemPtr = canvasPtr->textInfo.focusItemPtr;
if (argc == 2) {
if (itemPtr != NULL) {
- sprintf(interp->result, "%d", itemPtr->id);
+ char buf[TCL_INTEGER_SPACE];
+
+ sprintf(buf, "%d", itemPtr->id);
+ Tcl_SetResult(interp, buf, TCL_VOLATILE);
}
goto done;
}
@@ -940,6 +952,7 @@ CanvasWidgetCmd(clientData, interp, argc, argv)
} else if ((c == 'i') && (strncmp(argv[1], "index", length) == 0)
&& (length >= 3)) {
int index;
+ char buf[TCL_INTEGER_SPACE];
if (argc != 4) {
Tcl_AppendResult(interp, "wrong # args: should be \"",
@@ -962,7 +975,8 @@ CanvasWidgetCmd(clientData, interp, argc, argv)
itemPtr, argv[3], &index) != TCL_OK) {
goto error;
}
- sprintf(interp->result, "%d", index);
+ sprintf(buf, "%d", index);
+ Tcl_SetResult(interp, buf, TCL_VOLATILE);
} else if ((c == 'i') && (strncmp(argv[1], "insert", length) == 0)
&& (length >= 3)) {
int beforeThis;
@@ -1145,7 +1159,7 @@ CanvasWidgetCmd(clientData, interp, argc, argv)
goto error;
}
if ((xScale == 0.0) || (yScale == 0.0)) {
- interp->result = "scale factor cannot be zero";
+ Tcl_SetResult(interp, "scale factor cannot be zero", TCL_STATIC);
goto error;
}
for (itemPtr = StartTagSearch(canvasPtr, argv[2], &search);
@@ -1280,8 +1294,10 @@ CanvasWidgetCmd(clientData, interp, argc, argv)
goto error;
}
if (canvasPtr->textInfo.selItemPtr != NULL) {
- sprintf(interp->result, "%d",
- canvasPtr->textInfo.selItemPtr->id);
+ char buf[TCL_INTEGER_SPACE];
+
+ sprintf(buf, "%d", canvasPtr->textInfo.selItemPtr->id);
+ Tcl_SetResult(interp, buf, TCL_VOLATILE);
}
} else if ((c == 't') && (strncmp(argv[2], "to", length) == 0)) {
if (argc != 5) {
@@ -1305,7 +1321,7 @@ CanvasWidgetCmd(clientData, interp, argc, argv)
}
itemPtr = StartTagSearch(canvasPtr, argv[2], &search);
if (itemPtr != NULL) {
- interp->result = itemPtr->typePtr->name;
+ Tcl_SetResult(interp, itemPtr->typePtr->name, TCL_STATIC);
}
} else if ((c == 'x') && (strncmp(argv[1], "xview", length) == 0)) {
int count, type;
@@ -1317,7 +1333,7 @@ CanvasWidgetCmd(clientData, interp, argc, argv)
PrintScrollFractions(canvasPtr->xOrigin + canvasPtr->inset,
canvasPtr->xOrigin + Tk_Width(canvasPtr->tkwin)
- canvasPtr->inset, canvasPtr->scrollX1,
- canvasPtr->scrollX2, interp->result);
+ canvasPtr->scrollX2, Tcl_GetStringResult(interp));
} else {
type = Tk_GetScrollInfo(interp, argc, argv, &fraction, &count);
switch (type) {
@@ -1355,7 +1371,7 @@ CanvasWidgetCmd(clientData, interp, argc, argv)
PrintScrollFractions(canvasPtr->yOrigin + canvasPtr->inset,
canvasPtr->yOrigin + Tk_Height(canvasPtr->tkwin)
- canvasPtr->inset, canvasPtr->scrollY1,
- canvasPtr->scrollY2, interp->result);
+ canvasPtr->scrollY2, Tcl_GetStringResult(interp));
} else {
type = Tk_GetScrollInfo(interp, argc, argv, &fraction, &count);
switch (type) {
@@ -1473,7 +1489,7 @@ DestroyCanvas(memPtr)
*
* Results:
* The return value is a standard Tcl result. If TCL_ERROR is
- * returned, then interp->result contains an error message.
+ * returned, then the interp's result contains an error message.
*
* Side effects:
* Configuration information, such as colors, border width,
@@ -2141,8 +2157,6 @@ InitCanvas()
tkBitmapType.nextPtr = &tkArcType;
tkArcType.nextPtr = &tkWindowType;
tkWindowType.nextPtr = NULL;
- allUid = Tk_GetUid("all");
- currentUid = Tk_GetUid("current");
}
/*
@@ -2183,6 +2197,11 @@ StartTagSearch(canvasPtr, tag, searchPtr)
Tk_Uid *tagPtr;
Tk_Uid uid;
int count;
+ TkWindow *tkwin;
+ TkDisplay *dispPtr;
+
+ tkwin = (TkWindow *) canvasPtr->tkwin;
+ dispPtr = tkwin->dispPtr;
/*
* Initialize the search.
@@ -2201,15 +2220,15 @@ StartTagSearch(canvasPtr, tag, searchPtr)
if (isdigit(UCHAR(*tag))) {
char *end;
Tcl_HashEntry *entryPtr;
-
- numIdSearches++;
+
+ dispPtr->numIdSearches++;
id = strtoul(tag, &end, 0);
if (*end == 0) {
itemPtr = canvasPtr->hotPtr;
- lastPtr = canvasPtr->hotPrevPtr;
+ lastPtr = canvasPtr->hotPrevPtr;
if ((itemPtr == NULL) || (itemPtr->id != id) || (lastPtr == NULL)
|| (lastPtr->nextPtr != itemPtr)) {
- numSlowSearches++;
+ dispPtr->numSlowSearches++;
entryPtr = Tcl_FindHashEntry(&canvasPtr->idTable, (char *) id);
if (entryPtr != NULL) {
itemPtr = (Tk_Item *)Tcl_GetHashValue(entryPtr);
@@ -2227,7 +2246,7 @@ StartTagSearch(canvasPtr, tag, searchPtr)
}
searchPtr->tag = uid = Tk_GetUid(tag);
- if (uid == allUid) {
+ if (uid == Tk_GetUid("all")) {
/*
* All items match.
@@ -2362,7 +2381,7 @@ NextItem(searchPtr)
*
* Side effects:
* If tag is NULL then itemPtr's id is added as a list element
- * to interp->result; otherwise tag is added to itemPtr's
+ * to the interp's result; otherwise tag is added to itemPtr's
* list of tags.
*
*--------------------------------------------------------------
@@ -2384,7 +2403,8 @@ DoItem(interp, itemPtr, tag)
*/
if (tag == NULL) {
- char msg[30];
+ char msg[TCL_INTEGER_SPACE];
+
sprintf(msg, "%d", itemPtr->id);
Tcl_AppendElement(interp, msg);
return;
@@ -2438,9 +2458,9 @@ DoItem(interp, itemPtr, tag)
* Results:
* A standard Tcl return value. If newTag is NULL, then a
* list of ids from all the items that match argc/argv is
- * returned in interp->result. If newTag is NULL, then
- * the normal interp->result is an empty string. If an error
- * occurs, then interp->result will hold an error message.
+ * returned in the interp's result. If newTag is NULL, then
+ * the normal the interp's result is an empty string. If an error
+ * occurs, then the interp's result will hold an error message.
*
* Side effects:
* If newTag is non-NULL, then all the items that match the
@@ -2463,7 +2483,7 @@ FindItems(interp, canvasPtr, argc, argv, newTag, cmdName, option)
char *newTag; /* If non-NULL, gives new tag to set
* on all found items; if NULL, then
* ids of found items are returned
- * in interp->result. */
+ * in the interp's result. */
char *cmdName; /* Name of original Tcl command, for
* use in error messages. */
char *option; /* For error messages: gives option
@@ -2671,9 +2691,9 @@ FindItems(interp, canvasPtr, argc, argv, newTag, cmdName, option)
* Results:
* A standard Tcl return value. If newTag is NULL, then a
* list of ids from all the items overlapping or enclosed
- * by the rectangle given by argc is returned in interp->result.
- * If newTag is NULL, then the normal interp->result is an
- * empty string. If an error occurs, then interp->result will
+ * by the rectangle given by argc is returned in the interp's result.
+ * If newTag is NULL, then the normal the interp's result is an
+ * empty string. If an error occurs, then the interp's result will
* hold an error message.
*
* Side effects:
@@ -2696,7 +2716,7 @@ FindArea(interp, canvasPtr, argv, uid, enclosed)
Tk_Uid uid; /* If non-NULL, gives new tag to set
* on all found items; if NULL, then
* ids of found items are returned
- * in interp->result. */
+ * in the interp's result. */
int enclosed; /* 0 means overlapping or enclosed
* items are OK, 1 means only enclosed
* items are OK. */
@@ -3114,7 +3134,7 @@ PickCurrentItem(canvasPtr, eventPtr)
if ((itemPtr == canvasPtr->currentItemPtr) && !buttonDown) {
for (i = itemPtr->numTags-1; i >= 0; i--) {
- if (itemPtr->tagPtr[i] == currentUid) {
+ if (itemPtr->tagPtr[i] == Tk_GetUid("current")) {
itemPtr->tagPtr[i] = itemPtr->tagPtr[itemPtr->numTags-1];
itemPtr->numTags--;
break;
@@ -3144,7 +3164,8 @@ PickCurrentItem(canvasPtr, eventPtr)
if (canvasPtr->currentItemPtr != NULL) {
XEvent event;
- DoItem((Tcl_Interp *) NULL, canvasPtr->currentItemPtr, currentUid);
+ DoItem((Tcl_Interp *) NULL, canvasPtr->currentItemPtr,
+ Tk_GetUid("current"));
event = canvasPtr->pickEvent;
event.type = EnterNotify;
event.xcrossing.detail = NotifyAncestor;
@@ -3260,7 +3281,7 @@ CanvasDoEvent(canvasPtr, eventPtr)
objectPtr = (ClientData *) ckalloc((unsigned)
(numObjects * sizeof(ClientData)));
}
- objectPtr[0] = (ClientData) allUid;
+ objectPtr[0] = (ClientData) Tk_GetUid("all");
for (i = itemPtr->numTags-1; i >= 0; i--) {
objectPtr[i+1] = (ClientData) itemPtr->tagPtr[i];
}