Tk Source Code

Artifact [6847aa87]
Login

Artifact 6847aa87f552b9b2c04fa2e06537ba041c23ad94:

Attachment "tip97.patch" to ticket [2157629f] added by dkf 2008-10-24 21:53:43.
Index: generic/tkCanvas.c
===================================================================
RCS file: /cvsroot/tktoolkit/tk/generic/tkCanvas.c,v
retrieving revision 1.54
diff -u -r1.54 tkCanvas.c
--- generic/tkCanvas.c	18 Oct 2008 11:26:20 -0000	1.54
+++ generic/tkCanvas.c	24 Oct 2008 14:46:51 -0000
@@ -268,8 +268,7 @@
 static int		CanvasWidgetCmd(ClientData clientData,
 			    Tcl_Interp *interp, int argc,
 			    Tcl_Obj *const *argv);
-static void		CanvasWorldChanged(
-			    ClientData instanceData);
+static void		CanvasWorldChanged(ClientData instanceData);
 static int		ConfigureCanvas(Tcl_Interp *interp,
 			    TkCanvas *canvasPtr, int argc,
 			    Tcl_Obj *const *argv, int flags);
@@ -341,6 +340,10 @@
 #define FOR_EVERY_CANVAS_ITEM_MATCHING(objPtr,searchPtrPtr,errorExitClause) \
     for ((itemPtr) = StartTagSearch(canvasPtr, (objPtr), &search); \
 	    (itemPtr) != NULL; (itemPtr) = NextItem(&search))
+#define FIND_ITEMS(objPtr, n) \
+    FindItems(interp, canvasPtr, objc, objv, (objPtr), (n))
+#define RELINK_ITEMS(objPtr, itemPtr) \
+    RelinkItems(canvasPtr, (objPtr), (itemPtr))
 #else /* USE_OLD_TAG_SEARCH */
 #define FIRST_CANVAS_ITEM_MATCHING(objPtr,searchPtrPtr,errorExitClause) \
     if ((result=TagSearchScan(canvasPtr,(objPtr),(searchPtrPtr))) != TCL_OK){ \
@@ -353,8 +356,126 @@
     } \
     for (itemPtr = TagSearchFirst(*(searchPtrPtr)); \
 	    itemPtr != NULL; itemPtr = TagSearchNext(*(searchPtrPtr)))
+#define FIND_ITEMS(objPtr, n) \
+    FindItems(interp, canvasPtr, objc, objv, (objPtr), (n), &searchPtr)
+#define RELINK_ITEMS(objPtr, itemPtr) \
+    result = RelinkItems(canvasPtr, (objPtr), (itemPtr), &searchPtr)
 #endif /* USE_OLD_TAG_SEARCH */
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * ItemConfigure, ItemCoords, ItemDelete, ItemIndex, ItemInsert --
+ *
+ *	Helper functions that make access to canvas item functions simpler.
+ *	The focus of these wrappers is on making the access to overloaded item
+ *	types simpler; they are not used where an item function only has a
+ *	single type in all versions.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static inline int
+ItemCoords(
+    Tcl_Interp *interp,
+    Tk_Canvas canvas,
+    Tk_Item *itemPtr,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    int result;
+
+    if (itemPtr->typePtr->coordProc == NULL) {
+	result = TCL_OK;
+    } else if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
+	result = itemPtr->typePtr->coordProc(interp, canvas, itemPtr, objc,
+		objv);
+    } else {
+	const char **args = TkGetStringsFromObjs(objc, objv);
+
+	result = itemPtr->typePtr->coordProc(interp, canvas, itemPtr, objc,
+		(Tcl_Obj **) args);
+	if (args != NULL) {
+	    ckfree((char *) args);
+	}
+    }
+    return result;
+}
+
+static inline int
+ItemIndex(
+    Tcl_Interp *interp,
+    Tk_Canvas canvas,
+    Tk_Item *itemPtr,
+    Tcl_Obj *objPtr,
+    int *indexPtr)
+{
+    if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
+	return itemPtr->typePtr->indexProc(interp, canvas, itemPtr,
+		(char *) objPtr, indexPtr);
+    } else {
+	return itemPtr->typePtr->indexProc(interp, canvas, itemPtr,
+		Tcl_GetString(objPtr), indexPtr);
+    }
+}
+
+static inline void
+ItemInsert(
+    Tk_Canvas canvas,
+    Tk_Item *itemPtr,
+    int beforeThis,
+    Tcl_Obj *toInsert)
+{
+    if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
+	itemPtr->typePtr->insertProc(canvas, itemPtr, beforeThis,
+		(char *) toInsert);
+    } else {
+	itemPtr->typePtr->insertProc(canvas, itemPtr, beforeThis,
+		Tcl_GetString(toInsert));
+    }
+}
+
+static inline int
+ItemDelete(
+    Tk_Canvas canvas,
+    Tk_Item *itemPtr,
+    int first,
+    int last)
+{
+    itemPtr->typePtr->dCharsProc(canvas, itemPtr, first, last);
+}
+
+static inline int
+ItemConfigure(
+    Tcl_Interp *interp,
+    TkCanvas *canvasPtr,
+    Tk_Item *itemPtr,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    int result;
+
+    if (interp == NULL) {
+	interp = canvasPtr->interp;
+    }
+    if (itemPtr == NULL) {
+	itemPtr = canvasPtr->currentItemPtr;
+    }
 
+    if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
+	result = itemPtr->typePtr->configProc(interp, (Tk_Canvas) canvasPtr,
+		itemPtr, objc, objv, TK_CONFIG_ARGV_ONLY);
+    } else {
+	const char **args = TkGetStringsFromObjs(objc, objv);
+
+	result = itemPtr->typePtr->configProc(interp, (Tk_Canvas) canvasPtr,
+		itemPtr, objc, (Tcl_Obj **) args, TK_CONFIG_ARGV_ONLY);
+	if (args != NULL) {
+	    ckfree((char *) args);
+	}
+    }
+    return result;
+}
 
 /*
  *--------------------------------------------------------------
@@ -380,7 +501,7 @@
     int argc,			/* Number of arguments. */
     Tcl_Obj *const argv[])	/* Argument objects. */
 {
-    Tk_Window tkwin = (Tk_Window) clientData;
+    Tk_Window tkwin = clientData;
     TkCanvas *canvasPtr;
     Tk_Window newWin;
 
@@ -409,8 +530,8 @@
     canvasPtr->display = Tk_Display(newWin);
     canvasPtr->interp = interp;
     canvasPtr->widgetCmd = Tcl_CreateObjCommand(interp,
-	    Tk_PathName(canvasPtr->tkwin), CanvasWidgetCmd,
-	    (ClientData) canvasPtr, CanvasCmdDeletedProc);
+	    Tk_PathName(canvasPtr->tkwin), CanvasWidgetCmd, canvasPtr,
+	    CanvasCmdDeletedProc);
     canvasPtr->firstItemPtr = NULL;
     canvasPtr->lastItemPtr = NULL;
     canvasPtr->borderWidth = 0;
@@ -483,21 +604,21 @@
     Tcl_InitHashTable(&canvasPtr->idTable, TCL_ONE_WORD_KEYS);
 
     Tk_SetClass(canvasPtr->tkwin, "Canvas");
-    Tk_SetClassProcs(canvasPtr->tkwin, &canvasClass, (ClientData) canvasPtr);
+    Tk_SetClassProcs(canvasPtr->tkwin, &canvasClass, canvasPtr);
     Tk_CreateEventHandler(canvasPtr->tkwin,
 	    ExposureMask|StructureNotifyMask|FocusChangeMask,
-	    CanvasEventProc, (ClientData) canvasPtr);
+	    CanvasEventProc, canvasPtr);
     Tk_CreateEventHandler(canvasPtr->tkwin, KeyPressMask|KeyReleaseMask
 	    |ButtonPressMask|ButtonReleaseMask|EnterWindowMask
 	    |LeaveWindowMask|PointerMotionMask|VirtualEventMask,
-	    CanvasBindProc, (ClientData) canvasPtr);
+	    CanvasBindProc, canvasPtr);
     Tk_CreateSelHandler(canvasPtr->tkwin, XA_PRIMARY, XA_STRING,
-	    CanvasFetchSelection, (ClientData) canvasPtr, XA_STRING);
+	    CanvasFetchSelection, canvasPtr, XA_STRING);
     if (ConfigureCanvas(interp, canvasPtr, argc-2, argv+2, 0) != TCL_OK) {
 	goto error;
     }
 
-    Tcl_SetResult(interp, Tk_PathName(canvasPtr->tkwin), TCL_STATIC);
+    Tcl_SetObjResult(interp, TkNewWindowObj(canvasPtr->tkwin));
     return TCL_OK;
 
   error:
@@ -547,10 +668,11 @@
 	"canvasy",	"cget",		"configure",	"coords",
 	"create",	"dchars",	"delete",	"dtag",
 	"find",		"focus",	"gettags",	"icursor",
-	"index",	"insert",	"itemcget",	"itemconfigure",
+	"imove",	"index",	"insert",	"itemcget",
+	"itemconfigure",
 	"lower",	"move",		"moveto",	"postscript",
-	"raise",	"scale",	"scan",		"select",
-	"type",		"xview",	"yview",
+	"raise",	"rchars",	"scale",	"scan",
+	"select",	"type",		"xview",	"yview",
 	NULL
     };
     enum options {
@@ -558,10 +680,11 @@
 	CANV_CANVASY,	CANV_CGET,	CANV_CONFIGURE,	CANV_COORDS,
 	CANV_CREATE,	CANV_DCHARS,	CANV_DELETE,	CANV_DTAG,
 	CANV_FIND,	CANV_FOCUS,	CANV_GETTAGS,	CANV_ICURSOR,
-	CANV_INDEX,	CANV_INSERT,	CANV_ITEMCGET,	CANV_ITEMCONFIGURE,
+	CANV_IMOVE,	CANV_INDEX,	CANV_INSERT,	CANV_ITEMCGET,
+	CANV_ITEMCONFIGURE,
 	CANV_LOWER,	CANV_MOVE,	CANV_MOVETO,	CANV_POSTSCRIPT,
-	CANV_RAISE,	CANV_SCALE,	CANV_SCAN,	CANV_SELECT,
-	CANV_TYPE,	CANV_XVIEW,	CANV_YVIEW
+	CANV_RAISE,	CANV_RCHARS,	CANV_SCALE,	CANV_SCAN,
+	CANV_SELECT,	CANV_TYPE,	CANV_XVIEW,	CANV_YVIEW
     };
 
     if (objc < 2) {
@@ -572,7 +695,7 @@
 	    &index) != TCL_OK) {
 	return TCL_ERROR;
     }
-    Tcl_Preserve((ClientData) canvasPtr);
+    Tcl_Preserve(canvasPtr);
 
     result = TCL_OK;
     switch ((enum options) index) {
@@ -582,12 +705,7 @@
 	    result = TCL_ERROR;
 	    goto done;
 	}
-#ifdef USE_OLD_TAG_SEARCH
-	result = FindItems(interp, canvasPtr, objc, objv, objv[2], 3);
-#else /* USE_OLD_TAG_SEARCH */
-	result = FindItems(interp, canvasPtr, objc, objv, objv[2], 3,
-		&searchPtr);
-#endif /* USE_OLD_TAG_SEARCH */
+	result = FIND_ITEMS(objv[2], 3);
 	break;
 
     case CANV_BBOX: {
@@ -631,10 +749,13 @@
 	    }
 	}
 	if (gotAny) {
-	    char buf[TCL_INTEGER_SPACE * 4];
+	    Tcl_Obj *resultObjs[4];
 
-	    sprintf(buf, "%d %d %d %d", x1, y1, x2, y2);
-	    Tcl_SetResult(interp, buf, TCL_VOLATILE);
+	    resultObjs[0] = Tcl_NewIntObj(x1);
+	    resultObjs[1] = Tcl_NewIntObj(y1);
+	    resultObjs[2] = Tcl_NewIntObj(x2);
+	    resultObjs[3] = Tcl_NewIntObj(y2);
+	    Tcl_SetObjResult(interp, Tcl_NewListObj(4, resultObjs));
 	}
 	break;
     }
@@ -665,8 +786,8 @@
 	    }
 	    entryPtr = Tcl_FindHashEntry(&canvasPtr->idTable, (char *) id);
 	    if (entryPtr != NULL) {
-		itemPtr = (Tk_Item *) Tcl_GetHashValue(entryPtr);
-		object = (ClientData) itemPtr;
+		itemPtr = Tcl_GetHashValue(entryPtr);
+		object = itemPtr;
 	    }
 
 	    if (object == 0) {
@@ -676,8 +797,8 @@
 		goto done;
 	    }
 	} else {
-	    bindByTag:
-	    object = (ClientData) Tk_GetUid(Tcl_GetString(objv[2]));
+	bindByTag:
+	    object = Tk_GetUid(Tcl_GetString(objv[2]));
 	}
 #else /* USE_OLD_TAG_SEARCH */
 	result = TagSearchScan(canvasPtr, objv[2], &searchPtr);
@@ -690,8 +811,8 @@
 	    entryPtr = Tcl_FindHashEntry(&canvasPtr->idTable,
 		    (char *) INT2PTR(searchPtr->id));
 	    if (entryPtr != NULL) {
-		itemPtr = (Tk_Item *) Tcl_GetHashValue(entryPtr);
-		object = (ClientData) itemPtr;
+		itemPtr = Tcl_GetHashValue(entryPtr);
+		object = itemPtr;
 	    }
 
 	    if (object == 0) {
@@ -716,7 +837,7 @@
 	if (objc == 5) {
 	    int append = 0;
 	    unsigned long mask;
-	    char* argv4 = Tcl_GetString(objv[4]);
+	    char *argv4 = Tcl_GetString(objv[4]);
 
 	    if (argv4[0] == 0) {
 		result = Tk_DeleteBinding(interp, canvasPtr->bindingTable,
@@ -785,9 +906,7 @@
 	    command = Tk_GetBinding(interp, canvasPtr->bindingTable,
 		    object, Tcl_GetString(objv[3]));
 	    if (command == NULL) {
-		const char *string;
-
-		string = Tcl_GetStringResult(interp);
+		const char *string = Tcl_GetStringResult(interp);
 
 		/*
 		 * Ignore missing binding errors. This is a special hack that
@@ -798,11 +917,10 @@
 		if (string[0] != '\0') {
 		    result = TCL_ERROR;
 		    goto done;
-		} else {
-		    Tcl_ResetResult(interp);
 		}
+		Tcl_ResetResult(interp);
 	    } else {
-		Tcl_SetResult(interp, (char *) command, TCL_STATIC);
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(command, -1));
 	    }
 	} else {
 	    Tk_GetAllBindings(interp, canvasPtr->bindingTable, object);
@@ -812,7 +930,6 @@
     case CANV_CANVASX: {
 	int x;
 	double grid;
-	char buf[TCL_DOUBLE_SPACE];
 
 	if ((objc < 3) || (objc > 4)) {
 	    Tcl_WrongNumArgs(interp, 2, objv, "screenx ?gridspacing?");
@@ -834,14 +951,12 @@
 	    grid = 0.0;
 	}
 	x += canvasPtr->xOrigin;
-	Tcl_PrintDouble(interp, GridAlign((double) x, grid), buf);
-	Tcl_SetResult(interp, buf, TCL_VOLATILE);
+	Tcl_SetObjResult(interp, Tcl_NewDoubleObj(GridAlign((double)x,grid)));
 	break;
     }
     case CANV_CANVASY: {
 	int y;
 	double grid;
-	char buf[TCL_DOUBLE_SPACE];
 
 	if ((objc < 3) || (objc > 4)) {
 	    Tcl_WrongNumArgs(interp, 2, objv, "screeny ?gridspacing?");
@@ -863,8 +978,7 @@
 	    grid = 0.0;
 	}
 	y += canvasPtr->yOrigin;
-	Tcl_PrintDouble(interp, GridAlign((double) y, grid), buf);
-	Tcl_SetResult(interp, buf, TCL_VOLATILE);
+	Tcl_SetObjResult(interp, Tcl_NewDoubleObj(GridAlign((double)y,grid)));
 	break;
     }
     case CANV_CGET:
@@ -899,31 +1013,90 @@
 	    if (objc != 3) {
 		EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr);
 	    }
-	    if (itemPtr->typePtr->coordProc != NULL) {
-		if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
-		    result = itemPtr->typePtr->coordProc(interp,
-			    (Tk_Canvas) canvasPtr, itemPtr, objc-3, objv+3);
-		} else {
-		    const char **args = TkGetStringsFromObjs(objc-3, objv+3);
+	    result = ItemCoords(interp, (Tk_Canvas) canvasPtr, itemPtr,
+		    objc-3, objv+3);
+	    if (objc != 3) {
+		EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr);
+	    }
+	}
+	break;
+    case CANV_IMOVE: {
+	double ignored;
+	Tcl_Obj *tmpObj;
 
-		    result = itemPtr->typePtr->coordProc(interp,
-			    (Tk_Canvas) canvasPtr, itemPtr, objc-3,
-			    (Tcl_Obj **) args);
-		    if (args != NULL) {
-			ckfree((char *) args);
-		    }
-		}
+	if (objc != 6) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId index x y");
+	    result = TCL_ERROR;
+	    goto done;
+	}
+	if (Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr,
+		    objv[4], &ignored) != TCL_OK
+		|| Tk_CanvasGetCoordFromObj(interp, (Tk_Canvas) canvasPtr,
+		    objv[5], &ignored) != TCL_OK) {
+	    result = TCL_ERROR;
+	    goto done;
+	}
+
+	/*
+	 * Make a temporary object here that we can reuse for all the
+	 * modifications in the loop.
+	 */
+
+	tmpObj = Tcl_NewListObj(2, objv+4);
+
+	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto doneImove) {
+	    int index;
+	    int x1,x2,y1,y2;
+
+	    /*
+	     * Boo! This code only works for lines and polygons, as they're
+	     * the only types we know of that have correctly functioning
+	     * dCharsProc and insertProc. Currently have the safety check
+	     * hard-coded, but ought to do it by some sort of flag to enable
+	     * third-party items to work right.
+	     */
+
+	    if (itemPtr == NULL || (itemPtr->typePtr != &tkLineType
+		    && itemPtr->typePtr != &tkPolygonType)) {
+		continue;
 	    }
-	    if (objc != 3) {
+
+	    result = ItemIndex(interp, (Tk_Canvas) canvasPtr, itemPtr,
+		    objv[3], &index);
+	    if (result != TCL_OK) {
+		break;
+	    }
+
+	    /*
+	     * Redraw both item's old and new areas: it's possible that a
+	     * replace could result in a new area larger than the old area.
+	     * Except if the dCharsProc or insertProc sets the
+	     * TK_ITEM_DONT_REDRAW flag, nothing more needs to be done.
+	     */
+
+	    x1 = itemPtr->x1; y1 = itemPtr->y1;
+	    x2 = itemPtr->x2; y2 = itemPtr->y2;
+	    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
+
+	    ItemDelete((Tk_Canvas) canvasPtr, itemPtr, index, index);
+	    ItemInsert((Tk_Canvas)canvasPtr, itemPtr, index, tmpObj);
+
+	    if (!(itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW)) {
+		Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr,
+			x1, y1, x2, y2);
 		EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr);
 	    }
+	    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
 	}
+
+    doneImove:
+	Tcl_DecrRefCount(tmpObj);
 	break;
+    }
     case CANV_CREATE: {
 	Tk_ItemType *typePtr;
 	Tk_ItemType *matchPtr = NULL;
 	Tk_Item *itemPtr;
-	char buf[TCL_INTEGER_SPACE];
 	int isNew = 0;
 	Tcl_HashEntry *entryPtr;
 	char *arg;
@@ -949,12 +1122,7 @@
 		    && (!strncmp(arg, typePtr->name, (unsigned)length))) {
 		if (matchPtr != NULL) {
 		    Tcl_MutexUnlock(&typeListMutex);
-		badType:
-		    Tcl_AppendResult(interp,
-			    "unknown or ambiguous item type \"", arg, "\"",
-			    NULL);
-		    result = TCL_ERROR;
-		    goto done;
+		    goto badType;
 		}
 		matchPtr = typePtr;
 	    }
@@ -967,7 +1135,11 @@
 
 	Tcl_MutexUnlock(&typeListMutex);
 	if (matchPtr == NULL) {
-	    goto badType;
+	badType:
+	    Tcl_AppendResult(interp,
+		    "unknown or ambiguous item type \"", arg, "\"", NULL);
+	    result = TCL_ERROR;
+	    goto done;
 	}
 	if (objc < 4) {
 	    /*
@@ -978,6 +1150,7 @@
 	    result = TCL_ERROR;
 	    goto done;
 	}
+
 	typePtr = matchPtr;
 	itemPtr = (Tk_Item *) ckalloc((unsigned) typePtr->itemSize);
 	itemPtr->id = canvasPtr->nextId;
@@ -988,6 +1161,7 @@
 	itemPtr->typePtr = typePtr;
 	itemPtr->state = TK_STATE_NULL;
 	itemPtr->redraw_flags = 0;
+
 	if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
 	    result = typePtr->createProc(interp, (Tk_Canvas) canvasPtr,
 		    itemPtr, objc-3, objv+3);
@@ -1005,6 +1179,7 @@
 	    result = TCL_ERROR;
 	    goto done;
 	}
+
 	itemPtr->nextPtr = NULL;
 	entryPtr = Tcl_CreateHashEntry(&canvasPtr->idTable,
 		(char *) INT2PTR(itemPtr->id), &isNew);
@@ -1021,8 +1196,7 @@
 	itemPtr->redraw_flags |= FORCE_REDRAW;
 	EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr);
 	canvasPtr->flags |= REPICK_NEEDED;
-	sprintf(buf, "%d", itemPtr->id);
-	Tcl_SetResult(interp, buf, TCL_VOLATILE);
+	Tcl_SetObjResult(interp, Tcl_NewIntObj(itemPtr->id));
 	break;
     }
     case CANV_DCHARS: {
@@ -1039,28 +1213,14 @@
 		    || (itemPtr->typePtr->dCharsProc == NULL)) {
 		continue;
 	    }
-	    if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
-		result = itemPtr->typePtr->indexProc(interp,
-			(Tk_Canvas) canvasPtr, itemPtr, (char *) objv[3],
-			&first);
-	    } else {
-		result = itemPtr->typePtr->indexProc(interp,
-			(Tk_Canvas) canvasPtr, itemPtr,
-			Tcl_GetString(objv[3]), &first);
-	    }
+	    result = ItemIndex(interp, (Tk_Canvas) canvasPtr, itemPtr,
+		    objv[3], &first);
 	    if (result != TCL_OK) {
 		goto done;
 	    }
 	    if (objc == 5) {
-		if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
-		    result = itemPtr->typePtr->indexProc(interp,
-			    (Tk_Canvas) canvasPtr, itemPtr, (char *) objv[4],
-			    &last);
-		} else {
-		    result = itemPtr->typePtr->indexProc(interp,
-			    (Tk_Canvas) canvasPtr, itemPtr,
-			    Tcl_GetString(objv[4]), &last);
-		}
+		result = ItemIndex(interp, (Tk_Canvas) canvasPtr, itemPtr,
+			objv[4], &last);
 		if (result != TCL_OK) {
 		    goto done;
 		}
@@ -1078,8 +1238,7 @@
 	    x1 = itemPtr->x1; y1 = itemPtr->y1;
 	    x2 = itemPtr->x2; y2 = itemPtr->y2;
 	    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
-	    itemPtr->typePtr->dCharsProc((Tk_Canvas) canvasPtr, itemPtr,
-		    first, last);
+	    ItemDelete((Tk_Canvas) canvasPtr, itemPtr, first, last);
 	    if (!(itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW)) {
 		Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr,
 			x1, y1, x2, y2);
@@ -1097,8 +1256,7 @@
 	    FOR_EVERY_CANVAS_ITEM_MATCHING(objv[i], &searchPtr, goto done) {
 		EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr);
 		if (canvasPtr->bindingTable != NULL) {
-		    Tk_DeleteAllBindings(canvasPtr->bindingTable,
-			    (ClientData) itemPtr);
+		    Tk_DeleteAllBindings(canvasPtr->bindingTable, itemPtr);
 		}
 		itemPtr->typePtr->deleteProc((Tk_Canvas) canvasPtr, itemPtr,
 			canvasPtr->display);
@@ -1176,12 +1334,7 @@
 	    result = TCL_ERROR;
 	    goto done;
 	}
-#ifdef USE_OLD_TAG_SEARCH
-	result = FindItems(interp, canvasPtr, objc, objv, NULL, 2);
-#else /* USE_OLD_TAG_SEARCH */
-	result = FindItems(interp, canvasPtr, objc, objv, NULL, 2,
-		&searchPtr);
-#endif /* USE_OLD_TAG_SEARCH */
+	result = FIND_ITEMS(NULL, 2);
 	break;
     case CANV_FOCUS:
 	if (objc > 3) {
@@ -1192,10 +1345,7 @@
 	itemPtr = canvasPtr->textInfo.focusItemPtr;
 	if (objc == 2) {
 	    if (itemPtr != NULL) {
-		char buf[TCL_INTEGER_SPACE];
-
-		sprintf(buf, "%d", itemPtr->id);
-		Tcl_SetResult(interp, buf, TCL_VOLATILE);
+		Tcl_SetObjResult(interp, Tcl_NewIntObj(itemPtr->id));
 	    }
 	    goto done;
 	}
@@ -1246,15 +1396,8 @@
 		    || (itemPtr->typePtr->icursorProc == NULL)) {
 		goto done;
 	    }
-	    if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
-		result = itemPtr->typePtr->indexProc(interp,
-			(Tk_Canvas) canvasPtr, itemPtr, (char *) objv[3],
-			&index);
-	    } else {
-		result = itemPtr->typePtr->indexProc(interp,
-			(Tk_Canvas) canvasPtr, itemPtr,
-			Tcl_GetString(objv[3]), &index);
-	    }
+	    result = ItemIndex(interp, (Tk_Canvas) canvasPtr, itemPtr,
+		    objv[3], &index);
 	    if (result != TCL_OK) {
 		goto done;
 	    }
@@ -1269,7 +1412,6 @@
     }
     case CANV_INDEX: {
 	int index;
-	char buf[TCL_INTEGER_SPACE];
 
 	if (objc != 4) {
 	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId string");
@@ -1287,18 +1429,12 @@
 	    result = TCL_ERROR;
 	    goto done;
 	}
-	if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
-	    result = itemPtr->typePtr->indexProc(interp, (Tk_Canvas)canvasPtr,
-		    itemPtr, (char *) objv[3], &index);
-	} else {
-	    result = itemPtr->typePtr->indexProc(interp, (Tk_Canvas)canvasPtr,
-		    itemPtr, Tcl_GetString(objv[3]), &index);
-	}
+	result = ItemIndex(interp, (Tk_Canvas) canvasPtr, itemPtr, objv[3],
+		&index);
 	if (result != TCL_OK) {
 	    goto done;
 	}
-	sprintf(buf, "%d", index);
-	Tcl_SetResult(interp, buf, TCL_VOLATILE);
+	Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
 	break;
     }
     case CANV_INSERT: {
@@ -1315,15 +1451,8 @@
 		    || (itemPtr->typePtr->insertProc == NULL)) {
 		continue;
 	    }
-	    if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
-		result = itemPtr->typePtr->indexProc(interp,
-			(Tk_Canvas) canvasPtr, itemPtr, (char *) objv[3],
-			&beforeThis);
-	    } else {
-		result = itemPtr->typePtr->indexProc(interp,
-			(Tk_Canvas) canvasPtr, itemPtr,
-			Tcl_GetString(objv[3]), &beforeThis);
-	    }
+	    result = ItemIndex(interp, (Tk_Canvas) canvasPtr, itemPtr,
+		    objv[3], &beforeThis);
 	    if (result != TCL_OK) {
 		goto done;
 	    }
@@ -1338,13 +1467,7 @@
 	    x1 = itemPtr->x1; y1 = itemPtr->y1;
 	    x2 = itemPtr->x2; y2 = itemPtr->y2;
 	    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
-	    if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
-		itemPtr->typePtr->insertProc((Tk_Canvas) canvasPtr, itemPtr,
-			beforeThis, (char *) objv[4]);
-	    } else {
-		itemPtr->typePtr->insertProc((Tk_Canvas) canvasPtr, itemPtr,
-			beforeThis, Tcl_GetString(objv[4]));
-	    }
+	    ItemInsert((Tk_Canvas) canvasPtr, itemPtr, beforeThis, objv[4]);
 	    if (!(itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW)) {
 		Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr,
 			x1, y1, x2, y2);
@@ -1384,20 +1507,8 @@
 			Tcl_GetString(objv[3]), 0);
 	    } else {
 		EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr);
-		if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
-		    result = itemPtr->typePtr->configProc(interp,
-			    (Tk_Canvas) canvasPtr, itemPtr, objc-3, objv+3,
-			    TK_CONFIG_ARGV_ONLY);
-		} else {
-		    const char **args = TkGetStringsFromObjs(objc-3, objv+3);
-
-		    result = itemPtr->typePtr->configProc(interp,
-			    (Tk_Canvas) canvasPtr, itemPtr, objc-3,
-			    (Tcl_Obj **) args, TK_CONFIG_ARGV_ONLY);
-		    if (args != NULL) {
-			ckfree((char *) args);
-		    }
-		}
+		result = ItemConfigure(interp, canvasPtr, itemPtr, objc-3,
+			objv+3);
 		EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr);
 		canvasPtr->flags |= REPICK_NEEDED;
 	    }
@@ -1430,11 +1541,7 @@
 	    }
 	    itemPtr = itemPtr->prevPtr;
 	}
-#ifdef USE_OLD_TAG_SEARCH
-	RelinkItems(canvasPtr, objv[2], itemPtr);
-#else /* USE_OLD_TAG_SEARCH */
-	result = RelinkItems(canvasPtr, objv[2], itemPtr, &searchPtr);
-#endif /* USE_OLD_TAG_SEARCH */
+	RELINK_ITEMS(objv[2], itemPtr);
 	break;
     }
     case CANV_MOVE: {
@@ -1560,11 +1667,56 @@
 		goto done;
 	    }
 	}
-#ifdef USE_OLD_TAG_SEARCH
-	RelinkItems(canvasPtr, objv[2], prevPtr);
-#else /* USE_OLD_TAG_SEARCH */
-	result = RelinkItems(canvasPtr, objv[2], prevPtr, &searchPtr);
-#endif /* USE_OLD_TAG_SEARCH */
+	RELINK_ITEMS(objv[2], prevPtr);
+	break;
+    }
+    case CANV_RCHARS: {
+	int first, last;
+	int x1,x2,y1,y2;
+
+	if (objc != 6) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId first last string");
+	    result = TCL_ERROR;
+	    goto done;
+	}
+	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
+	    if ((itemPtr->typePtr->indexProc == NULL)
+		    || (itemPtr->typePtr->dCharsProc == NULL)
+		    || (itemPtr->typePtr->insertProc == NULL)) {
+		continue;
+	    }
+	    result = ItemIndex(interp, (Tk_Canvas) canvasPtr, itemPtr,
+		    objv[3], &first);
+	    if (result != TCL_OK) {
+		goto done;
+	    }
+	    result = ItemIndex(interp, (Tk_Canvas) canvasPtr, itemPtr,
+		    objv[4], &last);
+	    if (result != TCL_OK) {
+		goto done;
+	    }
+
+	    /*
+	     * Redraw both item's old and new areas: it's possible that a
+	     * replace could result in a new area larger than the old area.
+	     * Except if the dCharsProc or insertProc sets the
+	     * TK_ITEM_DONT_REDRAW flag, nothing more needs to be done.
+	     */
+
+	    x1 = itemPtr->x1; y1 = itemPtr->y1;
+	    x2 = itemPtr->x2; y2 = itemPtr->y2;
+	    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
+
+	    ItemDelete((Tk_Canvas) canvasPtr, itemPtr, first, last);
+	    ItemInsert((Tk_Canvas) canvasPtr, itemPtr, first, objv[5]);
+
+	    if (!(itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW)) {
+		Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr,
+			x1, y1, x2, y2);
+		EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr);
+	    }
+	    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
+	}
 	break;
     }
     case CANV_SCALE: {
@@ -1673,15 +1825,8 @@
 	    }
 	}
 	if (objc == 5) {
-	    if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
-		result = itemPtr->typePtr->indexProc(interp,
-			(Tk_Canvas) canvasPtr, itemPtr, (char *) objv[4],
-			&index);
-	    } else {
-		result = itemPtr->typePtr->indexProc(interp,
-			(Tk_Canvas) canvasPtr, itemPtr,
-			Tcl_GetString(objv[4]), &index);
-	    }
+	    result = ItemIndex(interp, (Tk_Canvas) canvasPtr, itemPtr,
+		    objv[4], &index);
 	    if (result != TCL_OK) {
 		goto done;
 	    }
@@ -1721,7 +1866,6 @@
 			canvasPtr->textInfo.selItemPtr);
 		canvasPtr->textInfo.selItemPtr = NULL;
 	    }
-	    goto done;
 	    break;
 	case CANV_FROM:
 	    if (objc != 5) {
@@ -1867,7 +2011,7 @@
 #ifndef USE_OLD_TAG_SEARCH
     TagSearchDestroy(searchPtr);
 #endif /* not USE_OLD_TAG_SEARCH */
-    Tcl_Release((ClientData) canvasPtr);
+    Tcl_Release(canvasPtr);
     return result;
 }
 
@@ -2035,7 +2179,7 @@
 	if (argc2 != 4) {
 	    Tcl_AppendResult(interp, "bad scrollRegion \"",
 		    canvasPtr->regionString, "\"", NULL);
-	    badRegion:
+	badRegion:
 	    ckfree(canvasPtr->regionString);
 	    ckfree((char *) argv2);
 	    canvasPtr->regionString = NULL;
@@ -2085,7 +2229,7 @@
 }
 
 /*
- *---------------------------------------------------------------------------
+ *----------------------------------------------------------------------
  *
  * CanvasWorldChanged --
  *
@@ -2101,23 +2245,19 @@
  *	side effect of causing all the items to recompute their geometry and
  *	to be redisplayed.
  *
- *---------------------------------------------------------------------------
+ *----------------------------------------------------------------------
  */
 
 static void
 CanvasWorldChanged(
     ClientData instanceData)	/* Information about widget. */
 {
-    TkCanvas *canvasPtr = (TkCanvas *) instanceData;
+    TkCanvas *canvasPtr = instanceData;
     Tk_Item *itemPtr;
-    int result;
 
     itemPtr = canvasPtr->firstItemPtr;
     for ( ; itemPtr != NULL; itemPtr = itemPtr->nextPtr) {
-	result = itemPtr->typePtr->configProc(canvasPtr->interp,
-		(Tk_Canvas) canvasPtr, itemPtr, 0, NULL,
-		TK_CONFIG_ARGV_ONLY);
-	if (result != TCL_OK) {
+	if (ItemConfigure(NULL, canvasPtr, itemPtr, 0, NULL) != TCL_OK) {
 	    Tcl_ResetResult(canvasPtr->interp);
 	}
     }
@@ -2129,7 +2269,7 @@
 }
 
 /*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
  *
  * DisplayCanvas --
  *
@@ -2143,7 +2283,7 @@
  * Side effects:
  *	Information appears on the screen.
  *
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
  */
 
 static void
@@ -2170,11 +2310,11 @@
      */
 
     while (canvasPtr->flags & REPICK_NEEDED) {
-	Tcl_Preserve((ClientData) canvasPtr);
+	Tcl_Preserve(canvasPtr);
 	canvasPtr->flags &= ~REPICK_NEEDED;
 	PickCurrentItem(canvasPtr, &canvasPtr->pickEvent);
 	tkwin = canvasPtr->tkwin;
-	Tcl_Release((ClientData) canvasPtr);
+	Tcl_Release(canvasPtr);
 	if (tkwin == NULL) {
 	    return;
 	}
@@ -2187,13 +2327,14 @@
      */
 
     for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;
-		itemPtr = itemPtr->nextPtr) {
+	    itemPtr = itemPtr->nextPtr) {
 	if (itemPtr->redraw_flags & FORCE_REDRAW) {
 	    itemPtr->redraw_flags &= ~FORCE_REDRAW;
-	    EventuallyRedrawItem((Tk_Canvas)canvasPtr, itemPtr);
+	    EventuallyRedrawItem((Tk_Canvas) canvasPtr, itemPtr);
 	    itemPtr->redraw_flags &= ~FORCE_REDRAW;
 	}
     }
+
     /*
      * Compute the intersection between the area that needs redrawing and the
      * area that's visible on the screen.
@@ -2300,8 +2441,8 @@
 		}
 	    }
 	    if (itemPtr->state == TK_STATE_HIDDEN ||
-		(itemPtr->state == TK_STATE_NULL &&
-		 canvasPtr->canvas_state == TK_STATE_HIDDEN)) {
+		    (itemPtr->state == TK_STATE_NULL &&
+		    canvasPtr->canvas_state == TK_STATE_HIDDEN)) {
 		continue;
 	    }
 	    itemPtr->typePtr->displayProc((Tk_Canvas) canvasPtr, itemPtr,
@@ -2369,7 +2510,7 @@
 }
 
 /*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
  *
  * CanvasEventProc --
  *
@@ -2380,10 +2521,10 @@
  *	None.
  *
  * Side effects:
- *	When the window gets deleted, internal structures get cleaned up.
- *	When it gets exposed, it is redisplayed.
+ *	When the window gets deleted, internal structures get cleaned up. When
+ *	it gets exposed, it is redisplayed.
  *
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
  */
 
 static void
@@ -2416,10 +2557,9 @@
 		    canvasPtr->widgetCmd);
 	}
 	if (canvasPtr->flags & REDRAW_PENDING) {
-	    Tcl_CancelIdleCall(DisplayCanvas, (ClientData) canvasPtr);
+	    Tcl_CancelIdleCall(DisplayCanvas, canvasPtr);
 	}
-	Tcl_EventuallyFree((ClientData) canvasPtr,
-		(Tcl_FreeProc *) DestroyCanvas);
+	Tcl_EventuallyFree(canvasPtr, (Tcl_FreeProc *) DestroyCanvas);
     } else if (eventPtr->type == ConfigureNotify) {
 	canvasPtr->flags |= UPDATE_SCROLLBARS;
 
@@ -2500,7 +2640,7 @@
 }
 
 /*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
  *
  * Tk_CanvasEventuallyRedraw --
  *
@@ -2513,7 +2653,7 @@
  * Side effects:
  *	The screen will eventually be refreshed.
  *
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
  */
 
 void
@@ -2562,13 +2702,13 @@
 	canvasPtr->flags |= BBOX_NOT_EMPTY;
     }
     if (!(canvasPtr->flags & REDRAW_PENDING)) {
-	Tcl_DoWhenIdle(DisplayCanvas, (ClientData) canvasPtr);
+	Tcl_DoWhenIdle(DisplayCanvas, canvasPtr);
 	canvasPtr->flags |= REDRAW_PENDING;
     }
 }
 
 /*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
  *
  * EventuallyRedrawItem --
  *
@@ -2581,7 +2721,7 @@
  * Side effects:
  *	The screen will eventually be refreshed.
  *
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
  */
 
 static void
@@ -2624,13 +2764,13 @@
 	itemPtr->redraw_flags |= FORCE_REDRAW;
     }
     if (!(canvasPtr->flags & REDRAW_PENDING)) {
-	Tcl_DoWhenIdle(DisplayCanvas, (ClientData) canvasPtr);
+	Tcl_DoWhenIdle(DisplayCanvas, canvasPtr);
 	canvasPtr->flags |= REDRAW_PENDING;
     }
 }
 
 /*
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
  *
  * Tk_CreateItemType --
  *
@@ -2646,7 +2786,7 @@
  *	commands). If there was already a type with the same name as in
  *	typePtr, it is replaced with the new type.
  *
- *--------------------------------------------------------------
+ *----------------------------------------------------------------------
  */
 
 void
@@ -3012,9 +3152,9 @@
 TagSearchExprInit(
     TagSearchExpr **exprPtrPtr)
 {
-    TagSearchExpr* expr = *exprPtrPtr;
+    TagSearchExpr *expr = *exprPtrPtr;
 
-    if (! expr) {
+    if (expr == NULL) {
 	expr = (TagSearchExpr *) ckalloc(sizeof(TagSearchExpr));
 	expr->allocated = 0;
 	expr->uids = NULL;
@@ -3044,11 +3184,11 @@
 TagSearchExprDestroy(
     TagSearchExpr *expr)
 {
-    if (expr) {
+    if (expr != NULL) {
     	if (expr->uids) {
-	    ckfree((char *)expr->uids);
+	    ckfree((char *) expr->uids);
 	}
-	ckfree((char *)expr);
+	ckfree((char *) expr);
     }
 }
 
@@ -3089,7 +3229,7 @@
      * Initialize the search.
      */
 
-    if (*searchPtrPtr) {
+    if (*searchPtrPtr != NULL) {
 	searchPtr = *searchPtrPtr;
     } else {
 	/*
@@ -3106,7 +3246,7 @@
 	searchPtr->rewritebufferAllocated = 100;
 	searchPtr->rewritebuffer = ckalloc(searchPtr->rewritebufferAllocated);
     }
-    TagSearchExprInit(&(searchPtr->expr));
+    TagSearchExprInit(&searchPtr->expr);
 
     /*
      * How long is the tagOrId?
@@ -3118,7 +3258,7 @@
      * Make sure there is enough buffer to hold rewritten tags.
      */
 
-    if ((unsigned int)searchPtr->stringLength >=
+    if ((unsigned) searchPtr->stringLength >=
 	    searchPtr->rewritebufferAllocated) {
 	searchPtr->rewritebufferAllocated = searchPtr->stringLength + 100;
 	searchPtr->rewritebuffer =
@@ -3250,8 +3390,8 @@
 {
     if (searchPtr) {
 	TagSearchExprDestroy(searchPtr->expr);
-	ckfree((char *)searchPtr->rewritebuffer);
-	ckfree((char *)searchPtr);
+	ckfree((char *) searchPtr->rewritebuffer);
+	ckfree((char *) searchPtr);
     }
 }
 
@@ -3596,7 +3736,7 @@
 		negate_result = 0;
 	    }
 	    looking_for_tag = 0;
-	} else {    /* ! looking_for_tag */
+	} else {		/* ! looking_for_tag */
 	    if (((uid == searchUids->andUid) && (!result)) ||
 		    ((uid == searchUids->orUid) && result)) {
 		/*
@@ -3925,8 +4065,8 @@
 
 	itemPtr->tagSpace += 5;
 	newTagPtr = (Tk_Uid *)
-		ckalloc((unsigned) (itemPtr->tagSpace * sizeof(Tk_Uid)));
-	memcpy((void *) newTagPtr, itemPtr->tagPtr,
+		ckalloc((unsigned) itemPtr->tagSpace * sizeof(Tk_Uid));
+	memcpy(newTagPtr, itemPtr->tagPtr,
 		itemPtr->numTags * sizeof(Tk_Uid));
 	if (itemPtr->tagPtr != itemPtr->staticTagSpace) {
 	    ckfree((char *) itemPtr->tagPtr);
@@ -4429,6 +4569,7 @@
     XEvent *eventPtr)		/* Pointer to X event that just happened. */
 {
     TkCanvas *canvasPtr = clientData;
+    int mask;
 
     Tcl_Preserve(canvasPtr);
 
@@ -4438,9 +4579,9 @@
      * current item while buttons are down.
      */
 
-    if (eventPtr->type == ButtonPress || eventPtr->type == ButtonRelease) {
-	int mask;
-
+    switch (eventPtr->type) {
+    case ButtonPress:
+    case ButtonRelease:
 	switch (eventPtr->xbutton.button) {
 	case Button1:
 	    mask = Button1Mask;
@@ -4494,19 +4635,20 @@
 	    PickCurrentItem(canvasPtr, eventPtr);
 	    eventPtr->xbutton.state ^= mask;
 	}
-	goto done;
-    } else if ((eventPtr->type == EnterNotify)
-	    || (eventPtr->type == LeaveNotify)) {
+	break;
+    case EnterNotify:
+    case LeaveNotify:
 	canvasPtr->state = eventPtr->xcrossing.state;
 	PickCurrentItem(canvasPtr, eventPtr);
-	goto done;
-    } else if (eventPtr->type == MotionNotify) {
+	break;
+    case MotionNotify:
 	canvasPtr->state = eventPtr->xmotion.state;
 	PickCurrentItem(canvasPtr, eventPtr);
+	/* fallthrough */
+    default:
+	CanvasDoEvent(canvasPtr, eventPtr);
     }
-    CanvasDoEvent(canvasPtr, eventPtr);
 
-  done:
     Tcl_Release(canvasPtr);
 }
 
@@ -4705,9 +4847,7 @@
     if (prevItemPtr != NULL && prevItemPtr != canvasPtr->currentItemPtr &&
 	    (prevItemPtr->redraw_flags & TK_ITEM_STATE_DEPENDANT)) {
 	EventuallyRedrawItem((Tk_Canvas) canvasPtr, prevItemPtr);
-	prevItemPtr->typePtr->configProc(canvasPtr->interp,
-		(Tk_Canvas) canvasPtr, prevItemPtr, 0, NULL,
-		TK_CONFIG_ARGV_ONLY);
+	ItemConfigure(NULL, canvasPtr, prevItemPtr, 0, NULL);
     }
     if (canvasPtr->currentItemPtr != NULL) {
 	XEvent event;
@@ -4716,12 +4856,10 @@
 	DoItem(NULL, canvasPtr->currentItemPtr, Tk_GetUid("current"));
 #else /* USE_OLD_TAG_SEARCH */
 	DoItem(NULL, canvasPtr->currentItemPtr, searchUids->currentUid);
-#endif /* USE_OLD_TAG_SEA */
+#endif /* USE_OLD_TAG_SEARCH */
 	if ((canvasPtr->currentItemPtr->redraw_flags & TK_ITEM_STATE_DEPENDANT
 		&& prevItemPtr != canvasPtr->currentItemPtr)) {
-	    canvasPtr->currentItemPtr->typePtr->configProc(canvasPtr->interp,
-		    (Tk_Canvas) canvasPtr, canvasPtr->currentItemPtr, 0, NULL,
-		    TK_CONFIG_ARGV_ONLY);
+	    ItemConfigure(NULL, canvasPtr, NULL, 0, NULL);
 	    EventuallyRedrawItem((Tk_Canvas) canvasPtr,
 		    canvasPtr->currentItemPtr);
 	}