⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tkcanvas.c

📁 MPICH是MPI的重要研究,提供了一系列的接口函数,为并行计算的实现提供了编程环境.
💻 C
📖 第 1 页 / 共 5 页
字号:
		"\":  must be addtag, bbox, bind, ",		"canvasx, canvasy, configure, coords, create, ",		"dchars, delete, dtag, find, focus, ",		"gettags, icursor, index, insert, itemconfigure, lower, ",		"move, postscript, raise, scale, scan, ",		"select, type, xview, or yview",		(char *) NULL);  	goto error;    }    done:    Tk_Release((ClientData) canvasPtr);    return result;    error:    Tk_Release((ClientData) canvasPtr);    return TCL_ERROR;}/* *---------------------------------------------------------------------- * * DestroyCanvas -- * *	This procedure is invoked by Tk_EventuallyFree or Tk_Release *	to clean up the internal structure of a canvas at a safe time *	(when no-one is using it anymore). * * Results: *	None. * * Side effects: *	Everything associated with the canvas is freed up. * *---------------------------------------------------------------------- */static voidDestroyCanvas(clientData)    ClientData clientData;	/* Info about canvas widget. */{    register Tk_Canvas *canvasPtr = (Tk_Canvas *) clientData;    register Tk_Item *itemPtr;    /*     * Free up all of the items in the canvas.     */    for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;	    itemPtr = canvasPtr->firstItemPtr) {	canvasPtr->firstItemPtr = itemPtr->nextPtr;	(*itemPtr->typePtr->deleteProc)(canvasPtr, itemPtr);	if (itemPtr->tagPtr != itemPtr->staticTagSpace) {	    ckfree((char *) itemPtr->tagPtr);	}	ckfree((char *) itemPtr);    }    /*     * Free up all the stuff that requires special handling,     * then let Tk_FreeOptions handle all the standard option-related     * stuff.     */    if (canvasPtr->pixmapGC != None) {	Tk_FreeGC(canvasPtr->display, canvasPtr->pixmapGC);    }    Tk_DeleteTimerHandler(canvasPtr->insertBlinkHandler);    if (canvasPtr->bindingTable != NULL) {	Tk_DeleteBindingTable(canvasPtr->bindingTable);    }    Tk_FreeOptions(configSpecs, (char *) canvasPtr, canvasPtr->display, 0);    ckfree((char *) canvasPtr);}/* *---------------------------------------------------------------------- * * ConfigureCanvas -- * *	This procedure is called to process an argv/argc list, plus *	the Tk option database, in order to configure (or *	reconfigure) a canvas widget. * * Results: *	The return value is a standard Tcl result.  If TCL_ERROR is *	returned, then interp->result contains an error message. * * Side effects: *	Configuration information, such as colors, border width, *	etc. get set for canvasPtr;  old resources get freed, *	if there were any. * *---------------------------------------------------------------------- */static intConfigureCanvas(interp, canvasPtr, argc, argv, flags)    Tcl_Interp *interp;		/* Used for error reporting. */    register Tk_Canvas *canvasPtr;	/* Information about widget;  may or may				 * not already have values for some fields. */    int argc;			/* Number of valid entries in argv. */    char **argv;		/* Arguments. */    int flags;			/* Flags to pass to Tk_ConfigureWidget. */{    XGCValues gcValues;    GC new;    if (Tk_ConfigureWidget(interp, canvasPtr->tkwin, configSpecs,	    argc, argv, (char *) canvasPtr, flags) != TCL_OK) {	return TCL_ERROR;    }    /*     * A few options need special processing, such as setting the     * background from a 3-D border and creating a GC for copying     * bits to the screen.     */    Tk_SetBackgroundFromBorder(canvasPtr->tkwin, canvasPtr->bgBorder);    gcValues.function = GXcopy;    gcValues.foreground = Tk_3DBorderColor(canvasPtr->bgBorder)->pixel;    gcValues.graphics_exposures = False;    new = Tk_GetGC(canvasPtr->tkwin,	    GCFunction|GCForeground|GCGraphicsExposures, &gcValues);    if (canvasPtr->pixmapGC != None) {	Tk_FreeGC(canvasPtr->display, canvasPtr->pixmapGC);    }    canvasPtr->pixmapGC = new;    /*     * Reset the desired dimensions for the window.     */    Tk_GeometryRequest(canvasPtr->tkwin, canvasPtr->width, canvasPtr->height);    /*     * Restart the cursor timing sequence in case the on-time or off-time     * just changed.     */    if (canvasPtr->flags & GOT_FOCUS) {	CanvasFocusProc(canvasPtr, 1);    }    /*     * Recompute the scroll region.     */    canvasPtr->scrollX1 = 0;    canvasPtr->scrollY1 = 0;    canvasPtr->scrollX2 = 0;    canvasPtr->scrollY2 = 0;    if (canvasPtr->regionString != NULL) {	int argc2;	char **argv2;	if (Tcl_SplitList(canvasPtr->interp, canvasPtr->regionString,		&argc2, &argv2) != TCL_OK) {	    return TCL_ERROR;	}	if (argc2 != 4) {	    badRegion:	    Tcl_AppendResult(interp, "bad scrollRegion \"",		    canvasPtr->regionString, "\"", (char *) NULL);	    ckfree(canvasPtr->regionString);	    ckfree((char *) argv2);	    canvasPtr->regionString = NULL;	    return TCL_ERROR;	}	if ((Tk_GetPixels(canvasPtr->interp, canvasPtr->tkwin,		    argv2[0], &canvasPtr->scrollX1) != TCL_OK)		|| (Tk_GetPixels(canvasPtr->interp, canvasPtr->tkwin,		    argv2[1], &canvasPtr->scrollY1) != TCL_OK)		|| (Tk_GetPixels(canvasPtr->interp, canvasPtr->tkwin,		    argv2[2], &canvasPtr->scrollX2) != TCL_OK)		|| (Tk_GetPixels(canvasPtr->interp, canvasPtr->tkwin,		    argv2[3], &canvasPtr->scrollY2) != TCL_OK)) {	    goto badRegion;	}	ckfree((char *) argv2);    }    /*     * Reset the canvases origin (this is a no-op unless confine     * mode has just been turned on or the scroll region has changed).     */    CanvasSetOrigin(canvasPtr, canvasPtr->xOrigin, canvasPtr->yOrigin);    canvasPtr->flags |= UPDATE_SCROLLBARS;    EventuallyRedrawArea(canvasPtr, canvasPtr->xOrigin, canvasPtr->yOrigin,	    canvasPtr->xOrigin + Tk_Width(canvasPtr->tkwin),	    canvasPtr->yOrigin + Tk_Height(canvasPtr->tkwin));    return TCL_OK;}/* *-------------------------------------------------------------- * * DisplayCanvas -- * *	This procedure redraws the contents of a canvas window. *	It is invoked as a do-when-idle handler, so it only runs *	when there's nothing else for the application to do. * * Results: *	None. * * Side effects: *	Information appears on the screen. * *-------------------------------------------------------------- */static voidDisplayCanvas(clientData)    ClientData clientData;	/* Information about widget. */{    register Tk_Canvas *canvasPtr = (Tk_Canvas *) clientData;    register Tk_Window tkwin = canvasPtr->tkwin;    register Tk_Item *itemPtr;    Pixmap pixmap;    int screenX1, screenX2, screenY1, screenY2;    if (canvasPtr->tkwin == NULL) {	return;    }    if (!Tk_IsMapped(tkwin)) {	goto done;    }    /*     * Choose a new current item if that is needed (this could cause     * event handlers to be invoked).     */    while (canvasPtr->flags & REPICK_NEEDED) {	Tk_Preserve((ClientData) canvasPtr);	canvasPtr->flags &= ~REPICK_NEEDED;	PickCurrentItem(canvasPtr, &canvasPtr->pickEvent);	tkwin = canvasPtr->tkwin;	Tk_Release((ClientData) canvasPtr);	if (tkwin == NULL) {	    return;	}    }    /*     * Compute the intersection between the area that needs redrawing     * and the area that's visible on the screen.     */    screenX1 = canvasPtr->xOrigin;    screenY1 = canvasPtr->yOrigin;    screenX2 = screenX1 + Tk_Width(tkwin);    screenY2 = screenY1 + Tk_Height(tkwin);    if (canvasPtr->redrawX1 > screenX1) {	screenX1 = canvasPtr->redrawX1;    }    if (canvasPtr->redrawY1 > screenY1) {	screenY1 = canvasPtr->redrawY1;    }    if (canvasPtr->redrawX2 < screenX2) {	screenX2 = canvasPtr->redrawX2;    }    if (canvasPtr->redrawY2 < screenY2) {	screenY2 = canvasPtr->redrawY2;    }    if ((screenX1 >= screenX2) || (screenY1 >= screenY2)) {	goto done;    }    /*     * Redrawing is done in a temporary pixmap that is allocated     * here and freed at the end of the procedure.  All drawing     * is done to the pixmap, and the pixmap is copied to the     * screen at the end of the procedure. The temporary pixmap     * serves two purposes:     *     * 1. It provides a smoother visual effect (no clearing and     *    gradual redraw will be visible to users).     * 2. It allows us to redraw only the objects that overlap     *    the redraw area.  Otherwise incorrect results could     *	  occur from redrawing things that stick outside of     *	  the redraw area (we'd have to redraw everything in     *    order to make the overlaps look right).     *     * Some tricky points about the pixmap:     *     * 1. We only allocate a large enough pixmap to hold the     *    area that has to be redisplayed.  This saves time in     *    in the X server for large objects that cover much     *    more than the area being redisplayed:  only the area     *    of the pixmap will actually have to be redrawn.     * 2. Some X servers (e.g. the one for DECstations) have troubles     *    with characters that overlap an edge of the pixmap (on the     *    DEC servers, as of 8/18/92, such characters are drawn one     *    pixel too far to the right).  To handle this problem,     *    make the pixmap a bit larger than is absolutely needed     *    so that for normal-sized fonts the characters that overlap     *    the edge of the pixmap will be outside the area we care     *    about.     */    canvasPtr->drawableXOrigin = screenX1 - 30;    canvasPtr->drawableYOrigin = screenY1 - 30;    pixmap = XCreatePixmap(Tk_Display(tkwin), Tk_WindowId(tkwin),	screenX2 + 30 - canvasPtr->drawableXOrigin,	screenY2 + 30 - canvasPtr->drawableYOrigin,	Tk_Depth(tkwin));    /*     * Clear the area to be redrawn.     */    XFillRectangle(Tk_Display(tkwin), pixmap, canvasPtr->pixmapGC,	    screenX1 - canvasPtr->drawableXOrigin,	    screenY1 - canvasPtr->drawableYOrigin,	    (unsigned int) (screenX2 - screenX1),	    (unsigned int) (screenY2 - screenY1));    /*     * Scan through the item list, redrawing those items that need it.     * An item must be redraw if either (a) it intersects the smaller     * on-screen area or (b) it intersects the full canvas area and its     * type requests that it be redrawn always (e.g. so subwindows can     * be unmapped when they move off-screen).     */    for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;	    itemPtr = itemPtr->nextPtr) {	if ((itemPtr->x1 >= screenX2)		|| (itemPtr->y1 >= screenY2)		|| (itemPtr->x2 < screenX1)		|| (itemPtr->y2 < screenY1)) {	    if (!itemPtr->typePtr->alwaysRedraw		    || (itemPtr->x1 >= canvasPtr->redrawX2)		    || (itemPtr->y1 >= canvasPtr->redrawY2)		    || (itemPtr->x2 < canvasPtr->redrawX1)		    || (itemPtr->y2 < canvasPtr->redrawY1)) {		continue;	    }	}	(*itemPtr->typePtr->displayProc)(canvasPtr, itemPtr, pixmap);    }    /*     * Draw the window border.     */    if (canvasPtr->relief != TK_RELIEF_FLAT) {	Tk_Draw3DRectangle(Tk_Display(tkwin), pixmap,		canvasPtr->bgBorder,		canvasPtr->xOrigin - canvasPtr->drawableXOrigin,		canvasPtr->yOrigin - canvasPtr->drawableYOrigin,		Tk_Width(tkwin), Tk_Height(tkwin),		canvasPtr->borderWidth, canvasPtr->relief);    }    /*     * Copy from the temporary pixmap to the screen, then free up     * the temporary pixmap.     */    XCopyArea(Tk_Display(tkwin), pixmap, Tk_WindowId(tkwin),	    canvasPtr->pixmapGC,	    screenX1 - canvasPtr->drawableXOrigin,	    screenY1 - canvasPtr->drawableYOrigin,	    screenX2 - screenX1, screenY2 - screenY1,	    screenX1 - canvasPtr->xOrigin, screenY1 - canvasPtr->yOrigin);    XFreePixmap(Tk_Display(tkwin), pixmap);    done:    canvasPtr->flags &= ~REDRAW_PENDING;    if (canvasPtr->flags & UPDATE_SCROLLBARS) {	CanvasUpdateScrollbars(canvasPtr);    }}/* *-------------------------------------------------------------- * * CanvasEventProc -- * *	This procedure is invoked by the Tk dispatcher for various *	events on canvases. * * Results: *	None. * * Side effects: *	When the window gets deleted, internal structures get *	cleaned up.  When it gets exposed, it is redisplayed. * *-------------------------------------------------------------- */static voidCanvasEventProc(clientData, eventPtr)    ClientData clientData;	/* Information about window. */    XEvent *eventPtr;		/* Information about event. */{    Tk_Canvas *canvasPtr = (Tk_Canvas *) clientData;    if (eventPtr->type == Expose) {	int x, y;	x = eventPtr->xexpose.x + canvasPtr->xOrigin;	y = eventPtr->xexpose.y + canvasPtr->yOrigin;	EventuallyRedrawArea(canvasPtr, x, y, x + eventPtr->xexpose.width,		y + eventPtr->xexpose.height);    } else if (eventPtr->type == DestroyNotify) {	Tcl_DeleteCommand(canvasPtr->interp, Tk_PathName(canvasPtr->tkwin));	canvasPtr->tkwin = NULL;	if (canvasPtr->flags & REDRAW_PENDING) {	    Tk_CancelIdleCall(DisplayCanvas, (ClientData) canvasPtr);	}	Tk_EventuallyFree((ClientData) canvasPtr, DestroyCanvas);    } else if (eventPtr->type == ConfigureNotify) {	canvasPtr->flags |= UPDATE_SCROLLBARS;	/*	 * The call below is needed in order to recenter the canvas if	 * it's confined and its scroll region is smaller than the window.	 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -