tkUnixDraw.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:6k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /* 
  2.  * tkUnixDraw.c --
  3.  *
  4.  * This file contains X specific drawing routines.
  5.  *
  6.  * Copyright (c) 1995 Sun Microsystems, Inc.
  7.  *
  8.  * See the file "license.terms" for information on usage and redistribution
  9.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  10.  *
  11.  * RCS: @(#) $Id: tkUnixDraw.c,v 1.6.8.1 2005/07/28 04:57:38 hobbs Exp $
  12.  */
  13. #include "tkPort.h"
  14. #include "tkInt.h"
  15. #if !defined(__WIN32__) && !defined(MAC_TCL)
  16. #include "tkUnixInt.h"
  17. #endif
  18. /*
  19.  * The following structure is used to pass information to
  20.  * ScrollRestrictProc from TkScrollWindow.
  21.  */
  22. typedef struct ScrollInfo {
  23.     int done; /* Flag is 0 until filtering is done. */
  24.     Display *display; /* Display to filter. */
  25.     Window window; /* Window to filter. */
  26.     TkRegion region; /* Region into which damage is accumulated. */
  27.     int dx, dy; /* Amount by which window was shifted. */
  28. } ScrollInfo;
  29. /*
  30.  * Forward declarations for procedures declared later in this file:
  31.  */
  32. static Tk_RestrictAction ScrollRestrictProc _ANSI_ARGS_((
  33.          ClientData arg, XEvent *eventPtr));
  34. /*
  35.  *----------------------------------------------------------------------
  36.  *
  37.  * TkScrollWindow --
  38.  *
  39.  * Scroll a rectangle of the specified window and accumulate
  40.  * damage information in the specified Region.
  41.  *
  42.  * Results:
  43.  * Returns 0 if no damage additional damage was generated.  Sets
  44.  * damageRgn to contain the damaged areas and returns 1 if
  45.  * GraphicsExpose events were detected.
  46.  *
  47.  * Side effects:
  48.  * Scrolls the bits in the window and enters the event loop
  49.  * looking for damage events.
  50.  *
  51.  *----------------------------------------------------------------------
  52.  */
  53. int
  54. TkScrollWindow(tkwin, gc, x, y, width, height, dx, dy, damageRgn)
  55.     Tk_Window tkwin; /* The window to be scrolled. */
  56.     GC gc; /* GC for window to be scrolled. */
  57.     int x, y, width, height; /* Position rectangle to be scrolled. */
  58.     int dx, dy; /* Distance rectangle should be moved. */
  59.     TkRegion damageRgn; /* Region to accumulate damage in. */
  60. {
  61.     Tk_RestrictProc *oldProc;
  62.     ClientData oldArg, dummy;
  63.     ScrollInfo info;
  64.     
  65.     XCopyArea(Tk_Display(tkwin), Tk_WindowId(tkwin), Tk_WindowId(tkwin), gc,
  66.     x, y, (unsigned int) width, (unsigned int) height, x + dx, y + dy);
  67.     info.done = 0;
  68.     info.window = Tk_WindowId(tkwin);
  69.     info.display = Tk_Display(tkwin);
  70.     info.region = damageRgn;
  71.     info.dx = dx;
  72.     info.dy = dy;
  73.     /*
  74.      * Sync the event stream so all of the expose events will be on the
  75.      * Tk event queue before we start filtering.  This avoids busy waiting
  76.      * while we filter events.
  77.      */
  78.     TkpSync(info.display);
  79.     oldProc = Tk_RestrictEvents(ScrollRestrictProc, (ClientData) &info,
  80.     &oldArg);
  81.     while (!info.done) {
  82. Tcl_ServiceEvent(TCL_WINDOW_EVENTS);
  83.     }
  84.     Tk_RestrictEvents(oldProc, oldArg, &dummy);
  85.     if (XEmptyRegion((Region) damageRgn)) {
  86. return 0;
  87.     } else {
  88. return 1;
  89.     }
  90. }
  91. /*
  92.  *----------------------------------------------------------------------
  93.  *
  94.  * ScrollRestrictProc --
  95.  *
  96.  * A Tk_RestrictProc used by TkScrollWindow to gather up Expose
  97.  * information into a single damage region.  It accumulates damage
  98.  * events on the specified window until a NoExpose or the last
  99.  * GraphicsExpose event is detected.
  100.  *
  101.  * Results:
  102.  * None.
  103.  *
  104.  * Side effects:
  105.  * Discards Expose events after accumulating damage information
  106.  * for a particular window.
  107.  *
  108.  *----------------------------------------------------------------------
  109.  */
  110. static Tk_RestrictAction
  111. ScrollRestrictProc(arg, eventPtr)
  112.     ClientData arg;
  113.     XEvent *eventPtr;
  114. {
  115.     ScrollInfo *info = (ScrollInfo *) arg;
  116.     XRectangle rect;
  117.     /*
  118.      * Defer events which aren't for the specified window.
  119.      */
  120.     if (info->done || (eventPtr->xany.display != info->display)
  121.     || (eventPtr->xany.window != info->window)) {
  122. return TK_DEFER_EVENT;
  123.     }
  124.     if (eventPtr->type == NoExpose) {
  125. info->done = 1;
  126.     } else if (eventPtr->type == GraphicsExpose) {
  127. rect.x = eventPtr->xgraphicsexpose.x;
  128. rect.y = eventPtr->xgraphicsexpose.y;
  129. rect.width = eventPtr->xgraphicsexpose.width;
  130. rect.height = eventPtr->xgraphicsexpose.height;
  131. XUnionRectWithRegion(&rect, (Region) info->region,
  132. (Region) info->region);
  133. if (eventPtr->xgraphicsexpose.count == 0) {
  134.     info->done = 1;
  135. }
  136.     } else if (eventPtr->type == Expose) {
  137. /*
  138.  * This case is tricky.  This event was already queued before
  139.  * the XCopyArea was issued.  If this area overlaps the area
  140.  * being copied, then some of the copied area may be invalid.
  141.  * The easiest way to handle this case is to mark both the
  142.  * original area and the shifted area as damaged.
  143.  */
  144. rect.x = eventPtr->xexpose.x;
  145. rect.y = eventPtr->xexpose.y;
  146. rect.width = eventPtr->xexpose.width;
  147. rect.height = eventPtr->xexpose.height;
  148. XUnionRectWithRegion(&rect, (Region) info->region,
  149. (Region) info->region);
  150. rect.x += info->dx;
  151. rect.y += info->dy;
  152. XUnionRectWithRegion(&rect, (Region) info->region,
  153. (Region) info->region);
  154.     } else {
  155. return TK_DEFER_EVENT;
  156.     }
  157.     return TK_DISCARD_EVENT;
  158. }
  159. /*
  160.  *----------------------------------------------------------------------
  161.  *
  162.  * TkpDrawHighlightBorder --
  163.  *
  164.  * This procedure draws a rectangular ring around the outside of
  165.  * a widget to indicate that it has received the input focus.
  166.  *
  167.  *      On Unix, we just draw the simple inset ring.  On other sytems,
  168.  *      e.g. the Mac, the focus ring is a little more complicated, so we
  169.  *      need this abstraction.
  170.  *
  171.  * Results:
  172.  * None.
  173.  *
  174.  * Side effects:
  175.  * A rectangle "width" pixels wide is drawn in "drawable",
  176.  * corresponding to the outer area of "tkwin".
  177.  *
  178.  *----------------------------------------------------------------------
  179.  */
  180. void 
  181. TkpDrawHighlightBorder(tkwin, fgGC, bgGC, highlightWidth, drawable)
  182.     Tk_Window tkwin;
  183.     GC fgGC;
  184.     GC bgGC;
  185.     int highlightWidth;
  186.     Drawable drawable;
  187. {
  188.     TkDrawInsetFocusHighlight(tkwin, fgGC, highlightWidth, drawable, 0);
  189. }
  190. /*
  191.  *----------------------------------------------------------------------
  192.  *
  193.  * TkpDrawFrame --
  194.  *
  195.  * This procedure draws the rectangular frame area.
  196.  *
  197.  * Results:
  198.  * None.
  199.  *
  200.  * Side effects:
  201.  * Draws inside the tkwin area.
  202.  *
  203.  *----------------------------------------------------------------------
  204.  */
  205. void
  206. TkpDrawFrame (Tk_Window tkwin, Tk_3DBorder border,
  207. int highlightWidth, int borderWidth, int relief)
  208. {
  209.     Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin),
  210.     border, highlightWidth, highlightWidth,
  211.     Tk_Width(tkwin) - 2 * highlightWidth,
  212.     Tk_Height(tkwin) - 2 * highlightWidth,
  213.     borderWidth, relief);
  214. }