tkUnixDraw.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:6k
- /*
- * tkUnixDraw.c --
- *
- * This file contains X specific drawing routines.
- *
- * Copyright (c) 1995 Sun Microsystems, Inc.
- *
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
- *
- * RCS: @(#) $Id: tkUnixDraw.c,v 1.6.8.1 2005/07/28 04:57:38 hobbs Exp $
- */
- #include "tkPort.h"
- #include "tkInt.h"
- #if !defined(__WIN32__) && !defined(MAC_TCL)
- #include "tkUnixInt.h"
- #endif
- /*
- * The following structure is used to pass information to
- * ScrollRestrictProc from TkScrollWindow.
- */
- typedef struct ScrollInfo {
- int done; /* Flag is 0 until filtering is done. */
- Display *display; /* Display to filter. */
- Window window; /* Window to filter. */
- TkRegion region; /* Region into which damage is accumulated. */
- int dx, dy; /* Amount by which window was shifted. */
- } ScrollInfo;
- /*
- * Forward declarations for procedures declared later in this file:
- */
- static Tk_RestrictAction ScrollRestrictProc _ANSI_ARGS_((
- ClientData arg, XEvent *eventPtr));
- /*
- *----------------------------------------------------------------------
- *
- * TkScrollWindow --
- *
- * Scroll a rectangle of the specified window and accumulate
- * damage information in the specified Region.
- *
- * Results:
- * Returns 0 if no damage additional damage was generated. Sets
- * damageRgn to contain the damaged areas and returns 1 if
- * GraphicsExpose events were detected.
- *
- * Side effects:
- * Scrolls the bits in the window and enters the event loop
- * looking for damage events.
- *
- *----------------------------------------------------------------------
- */
- int
- TkScrollWindow(tkwin, gc, x, y, width, height, dx, dy, damageRgn)
- Tk_Window tkwin; /* The window to be scrolled. */
- GC gc; /* GC for window to be scrolled. */
- int x, y, width, height; /* Position rectangle to be scrolled. */
- int dx, dy; /* Distance rectangle should be moved. */
- TkRegion damageRgn; /* Region to accumulate damage in. */
- {
- Tk_RestrictProc *oldProc;
- ClientData oldArg, dummy;
- ScrollInfo info;
-
- XCopyArea(Tk_Display(tkwin), Tk_WindowId(tkwin), Tk_WindowId(tkwin), gc,
- x, y, (unsigned int) width, (unsigned int) height, x + dx, y + dy);
- info.done = 0;
- info.window = Tk_WindowId(tkwin);
- info.display = Tk_Display(tkwin);
- info.region = damageRgn;
- info.dx = dx;
- info.dy = dy;
- /*
- * Sync the event stream so all of the expose events will be on the
- * Tk event queue before we start filtering. This avoids busy waiting
- * while we filter events.
- */
- TkpSync(info.display);
- oldProc = Tk_RestrictEvents(ScrollRestrictProc, (ClientData) &info,
- &oldArg);
- while (!info.done) {
- Tcl_ServiceEvent(TCL_WINDOW_EVENTS);
- }
- Tk_RestrictEvents(oldProc, oldArg, &dummy);
- if (XEmptyRegion((Region) damageRgn)) {
- return 0;
- } else {
- return 1;
- }
- }
- /*
- *----------------------------------------------------------------------
- *
- * ScrollRestrictProc --
- *
- * A Tk_RestrictProc used by TkScrollWindow to gather up Expose
- * information into a single damage region. It accumulates damage
- * events on the specified window until a NoExpose or the last
- * GraphicsExpose event is detected.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Discards Expose events after accumulating damage information
- * for a particular window.
- *
- *----------------------------------------------------------------------
- */
- static Tk_RestrictAction
- ScrollRestrictProc(arg, eventPtr)
- ClientData arg;
- XEvent *eventPtr;
- {
- ScrollInfo *info = (ScrollInfo *) arg;
- XRectangle rect;
- /*
- * Defer events which aren't for the specified window.
- */
- if (info->done || (eventPtr->xany.display != info->display)
- || (eventPtr->xany.window != info->window)) {
- return TK_DEFER_EVENT;
- }
- if (eventPtr->type == NoExpose) {
- info->done = 1;
- } else if (eventPtr->type == GraphicsExpose) {
- rect.x = eventPtr->xgraphicsexpose.x;
- rect.y = eventPtr->xgraphicsexpose.y;
- rect.width = eventPtr->xgraphicsexpose.width;
- rect.height = eventPtr->xgraphicsexpose.height;
- XUnionRectWithRegion(&rect, (Region) info->region,
- (Region) info->region);
- if (eventPtr->xgraphicsexpose.count == 0) {
- info->done = 1;
- }
- } else if (eventPtr->type == Expose) {
- /*
- * This case is tricky. This event was already queued before
- * the XCopyArea was issued. If this area overlaps the area
- * being copied, then some of the copied area may be invalid.
- * The easiest way to handle this case is to mark both the
- * original area and the shifted area as damaged.
- */
- rect.x = eventPtr->xexpose.x;
- rect.y = eventPtr->xexpose.y;
- rect.width = eventPtr->xexpose.width;
- rect.height = eventPtr->xexpose.height;
- XUnionRectWithRegion(&rect, (Region) info->region,
- (Region) info->region);
- rect.x += info->dx;
- rect.y += info->dy;
- XUnionRectWithRegion(&rect, (Region) info->region,
- (Region) info->region);
- } else {
- return TK_DEFER_EVENT;
- }
- return TK_DISCARD_EVENT;
- }
- /*
- *----------------------------------------------------------------------
- *
- * TkpDrawHighlightBorder --
- *
- * This procedure draws a rectangular ring around the outside of
- * a widget to indicate that it has received the input focus.
- *
- * On Unix, we just draw the simple inset ring. On other sytems,
- * e.g. the Mac, the focus ring is a little more complicated, so we
- * need this abstraction.
- *
- * Results:
- * None.
- *
- * Side effects:
- * A rectangle "width" pixels wide is drawn in "drawable",
- * corresponding to the outer area of "tkwin".
- *
- *----------------------------------------------------------------------
- */
- void
- TkpDrawHighlightBorder(tkwin, fgGC, bgGC, highlightWidth, drawable)
- Tk_Window tkwin;
- GC fgGC;
- GC bgGC;
- int highlightWidth;
- Drawable drawable;
- {
- TkDrawInsetFocusHighlight(tkwin, fgGC, highlightWidth, drawable, 0);
- }
- /*
- *----------------------------------------------------------------------
- *
- * TkpDrawFrame --
- *
- * This procedure draws the rectangular frame area.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Draws inside the tkwin area.
- *
- *----------------------------------------------------------------------
- */
- void
- TkpDrawFrame (Tk_Window tkwin, Tk_3DBorder border,
- int highlightWidth, int borderWidth, int relief)
- {
- Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin),
- border, highlightWidth, highlightWidth,
- Tk_Width(tkwin) - 2 * highlightWidth,
- Tk_Height(tkwin) - 2 * highlightWidth,
- borderWidth, relief);
- }