OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [insight/] [tk/] [unix/] [tkUnixDraw.c] - Blame information for rev 578

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*
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.1.1.1 2002-01-16 10:26:01 markom Exp $
12
 */
13
 
14
#include "tkPort.h"
15
#include "tkInt.h"
16
 
17
/*
18
 * The following structure is used to pass information to
19
 * ScrollRestrictProc from TkScrollWindow.
20
 */
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
/*
31
 * Forward declarations for procedures declared later in this file:
32
 */
33
 
34
static Tk_RestrictAction        ScrollRestrictProc _ANSI_ARGS_((
35
                                    ClientData arg, XEvent *eventPtr));
36
 
37
/*
38
 *----------------------------------------------------------------------
39
 *
40
 * TkScrollWindow --
41
 *
42
 *      Scroll a rectangle of the specified window and accumulate
43
 *      damage information in the specified Region.
44
 *
45
 * Results:
46
 *      Returns 0 if no damage additional damage was generated.  Sets
47
 *      damageRgn to contain the damaged areas and returns 1 if
48
 *      GraphicsExpose events were detected.
49
 *
50
 * Side effects:
51
 *      Scrolls the bits in the window and enters the event loop
52
 *      looking for damage events.
53
 *
54
 *----------------------------------------------------------------------
55
 */
56
 
57
int
58
TkScrollWindow(tkwin, gc, x, y, width, height, dx, dy, damageRgn)
59
    Tk_Window tkwin;            /* The window to be scrolled. */
60
    GC gc;                      /* GC for window to be scrolled. */
61
    int x, y, width, height;    /* Position rectangle to be scrolled. */
62
    int dx, dy;                 /* Distance rectangle should be moved. */
63
    TkRegion damageRgn;         /* Region to accumulate damage in. */
64
{
65
    Tk_RestrictProc *oldProc;
66
    ClientData oldArg, dummy;
67
    ScrollInfo info;
68
 
69
    XCopyArea(Tk_Display(tkwin), Tk_WindowId(tkwin), Tk_WindowId(tkwin), gc,
70
            x, y, (unsigned int) width, (unsigned int) height, x + dx, y + dy);
71
 
72
    info.done = 0;
73
    info.window = Tk_WindowId(tkwin);
74
    info.display = Tk_Display(tkwin);
75
    info.region = damageRgn;
76
    info.dx = dx;
77
    info.dy = dy;
78
 
79
    /*
80
     * Sync the event stream so all of the expose events will be on the
81
     * Tk event queue before we start filtering.  This avoids busy waiting
82
     * while we filter events.
83
     */
84
 
85
    TkpSync(info.display);
86
    oldProc = Tk_RestrictEvents(ScrollRestrictProc, (ClientData) &info,
87
            &oldArg);
88
    while (!info.done) {
89
        Tcl_ServiceEvent(TCL_WINDOW_EVENTS);
90
    }
91
    Tk_RestrictEvents(oldProc, oldArg, &dummy);
92
 
93
    return XEmptyRegion((Region) damageRgn) ? 0 : 1;
94
}
95
 
96
/*
97
 *----------------------------------------------------------------------
98
 *
99
 * ScrollRestrictProc --
100
 *
101
 *      A Tk_RestrictProc used by TkScrollWindow to gather up Expose
102
 *      information into a single damage region.  It accumulates damage
103
 *      events on the specified window until a NoExpose or the last
104
 *      GraphicsExpose event is detected.
105
 *
106
 * Results:
107
 *      None.
108
 *
109
 * Side effects:
110
 *      Discards Expose events after accumulating damage information
111
 *      for a particular window.
112
 *
113
 *----------------------------------------------------------------------
114
 */
115
 
116
static Tk_RestrictAction
117
ScrollRestrictProc(arg, eventPtr)
118
    ClientData arg;
119
    XEvent *eventPtr;
120
{
121
    ScrollInfo *info = (ScrollInfo *) arg;
122
    XRectangle rect;
123
 
124
    /*
125
     * Defer events which aren't for the specified window.
126
     */
127
 
128
    if (info->done || (eventPtr->xany.display != info->display)
129
            || (eventPtr->xany.window != info->window)) {
130
        return TK_DEFER_EVENT;
131
    }
132
 
133
    if (eventPtr->type == NoExpose) {
134
        info->done = 1;
135
    } else if (eventPtr->type == GraphicsExpose) {
136
        rect.x = eventPtr->xgraphicsexpose.x;
137
        rect.y = eventPtr->xgraphicsexpose.y;
138
        rect.width = eventPtr->xgraphicsexpose.width;
139
        rect.height = eventPtr->xgraphicsexpose.height;
140
        XUnionRectWithRegion(&rect, (Region) info->region,
141
                (Region) info->region);
142
 
143
        if (eventPtr->xgraphicsexpose.count == 0) {
144
            info->done = 1;
145
        }
146
    } else if (eventPtr->type == Expose) {
147
 
148
        /*
149
         * This case is tricky.  This event was already queued before
150
         * the XCopyArea was issued.  If this area overlaps the area
151
         * being copied, then some of the copied area may be invalid.
152
         * The easiest way to handle this case is to mark both the
153
         * original area and the shifted area as damaged.
154
         */
155
 
156
        rect.x = eventPtr->xexpose.x;
157
        rect.y = eventPtr->xexpose.y;
158
        rect.width = eventPtr->xexpose.width;
159
        rect.height = eventPtr->xexpose.height;
160
        XUnionRectWithRegion(&rect, (Region) info->region,
161
                (Region) info->region);
162
        rect.x += info->dx;
163
        rect.y += info->dy;
164
        XUnionRectWithRegion(&rect, (Region) info->region,
165
                (Region) info->region);
166
    } else {
167
        return TK_DEFER_EVENT;
168
    }
169
    return TK_DISCARD_EVENT;
170
}
171
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.