diff options
Diffstat (limited to 'generic/tkCanvas.c')
-rw-r--r-- | generic/tkCanvas.c | 129 |
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]; } |