summaryrefslogtreecommitdiffstats
path: root/tk8.6/unix/tkUnixDraw.c
diff options
context:
space:
mode:
authorWilliam Joye <wjoye@cfa.harvard.edu>2018-12-25 19:56:49 (GMT)
committerWilliam Joye <wjoye@cfa.harvard.edu>2018-12-25 19:56:49 (GMT)
commitd5a4b3667e9d26b9c13905ccb51021d13ce87c58 (patch)
treefc0f3692516c8c3e8090df20223d342a1b64df93 /tk8.6/unix/tkUnixDraw.c
parentff51550ee89b473c63df78de6b2a413f21105687 (diff)
downloadblt-d5a4b3667e9d26b9c13905ccb51021d13ce87c58.zip
blt-d5a4b3667e9d26b9c13905ccb51021d13ce87c58.tar.gz
blt-d5a4b3667e9d26b9c13905ccb51021d13ce87c58.tar.bz2
update tcl/tk
Diffstat (limited to 'tk8.6/unix/tkUnixDraw.c')
-rw-r--r--tk8.6/unix/tkUnixDraw.c243
1 files changed, 243 insertions, 0 deletions
diff --git a/tk8.6/unix/tkUnixDraw.c b/tk8.6/unix/tkUnixDraw.c
new file mode 100644
index 0000000..acc0565
--- /dev/null
+++ b/tk8.6/unix/tkUnixDraw.c
@@ -0,0 +1,243 @@
+/*
+ * 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.
+ */
+
+#include "tkInt.h"
+
+#ifndef _WIN32
+#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 functions declared later in this file:
+ */
+
+static Tk_RestrictProc ScrollRestrictProc;
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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(
+ Tk_Window tkwin, /* The window to be scrolled. */
+ GC gc, /* GC for window to be scrolled. */
+ int x, int y, int width, int height,
+ /* Position rectangle to be scrolled. */
+ int dx, int dy, /* Distance rectangle should be moved. */
+ TkRegion damageRgn) /* Region to accumulate damage in. */
+{
+ Tk_RestrictProc *prevProc;
+ ClientData prevArg;
+ ScrollInfo info;
+
+ XCopyArea(Tk_Display(tkwin), Tk_WindowId(tkwin), Tk_WindowId(tkwin), gc,
+ x, y, (unsigned) width, (unsigned) 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);
+ prevProc = Tk_RestrictEvents(ScrollRestrictProc, &info, &prevArg);
+ while (!info.done) {
+ Tcl_ServiceEvent(TCL_WINDOW_EVENTS);
+ }
+ Tk_RestrictEvents(prevProc, prevArg, &prevArg);
+
+ 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(
+ 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 function 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(
+ Tk_Window tkwin,
+ GC fgGC,
+ GC bgGC,
+ int highlightWidth,
+ Drawable drawable)
+{
+ TkDrawInsetFocusHighlight(tkwin, fgGC, highlightWidth, drawable, 0);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpDrawFrame --
+ *
+ * This function 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);
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */