]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | Copyright (C) 1996 Scott W. Sadler | |
3 | All rights reserved. | |
4 | */ | |
5 | ||
6 | /* | |
7 | XsOutline.C | |
8 | ||
9 | History | |
10 | 03-Mar-96 1.0; Scott W. Sadler (ssadler@cisco.com) | |
11 | Created | |
12 | */ | |
13 | ||
14 | // Includes | |
15 | ||
16 | #include <assert.h> | |
17 | #include <X11/StringDefs.h> | |
18 | #include "XsOutline.h" | |
19 | ||
20 | // Constructor | |
21 | ||
22 | XsOutline::XsOutline (Widget w) | |
23 | { | |
24 | assert (w != 0); | |
25 | ||
26 | // Initialize | |
27 | ||
28 | _w = w; | |
29 | ||
30 | // Get window dimensions | |
31 | ||
32 | unsigned int moreJunk; | |
33 | unsigned int uw, uh; | |
34 | Window junk; | |
35 | ||
36 | XGetGeometry (XtDisplay (_w), XtWindow (_w), &junk, &_x, &_y, &uw, &uh, &moreJunk, &moreJunk); | |
37 | ||
38 | _width = uw; | |
39 | _height = uh; | |
40 | ||
41 | // Get initial settings | |
42 | ||
43 | _savedX = _x; | |
44 | _savedY = _y; | |
45 | _savedH = _savedW = 0; | |
46 | ||
47 | // Create the graphics context | |
48 | ||
49 | XGCValues values; | |
50 | unsigned long valuemask; | |
51 | ||
52 | Display *dpy = XtDisplay (_w); | |
53 | ||
54 | valuemask = GCFunction | GCLineWidth | GCSubwindowMode; | |
55 | values.function = GXinvert; | |
56 | values.line_width = 0; | |
57 | values.subwindow_mode = IncludeInferiors; | |
58 | ||
59 | _gc = XCreateGC (dpy, XtWindow (_w), valuemask, &values); | |
60 | } | |
61 | ||
62 | // Destructor | |
63 | ||
64 | XsOutline::~XsOutline ( ) | |
65 | { | |
66 | XFreeGC (XtDisplay (_w), _gc); | |
67 | } | |
68 | ||
69 | // go | |
70 | ||
71 | Boolean XsOutline::go (Boolean drawInitial) | |
72 | { | |
73 | XtAppContext appContext = XtWidgetToApplicationContext (_w); | |
74 | XEvent event; | |
75 | int done = 0; | |
76 | ||
77 | // Grab the pointer | |
78 | ||
79 | if (_grabPointer ( ) == False) | |
80 | return (False); | |
81 | ||
82 | // Draw the initial box (if requested) | |
83 | ||
84 | if (drawInitial) | |
85 | _drawOutline (False); | |
86 | ||
87 | // Process the events locally | |
88 | ||
89 | while (!done) | |
90 | { | |
91 | XtAppNextEvent (appContext, &event); | |
92 | ||
93 | switch (event.type) | |
94 | { | |
95 | case ButtonRelease: | |
96 | { | |
97 | ||
98 | // Clear the outline and break | |
99 | ||
100 | _drawOutline (True); | |
101 | done = 1; | |
102 | break; | |
103 | } | |
104 | case MotionNotify: | |
105 | { | |
106 | XEvent next; | |
107 | ||
108 | // Process only the last motion event | |
109 | ||
110 | while (XPending (XtDisplay (_w)) > 0) | |
111 | { | |
112 | XPeekEvent (XtDisplay (_w), &next); | |
113 | if (next.type != MotionNotify) | |
114 | break; | |
115 | XtAppNextEvent (appContext, &event); | |
116 | } | |
117 | ||
118 | // Send this event | |
119 | ||
120 | _motionHandler (&event); | |
121 | ||
122 | break; | |
123 | } | |
124 | default: | |
125 | { | |
126 | XtDispatchEvent (&event); | |
127 | break; | |
128 | } | |
129 | } | |
130 | } | |
131 | ||
132 | // Ungrab the pointer | |
133 | ||
134 | _ungrabPointer ( ); | |
135 | ||
136 | return (True); | |
137 | } | |
138 | ||
139 | // _drawOutline | |
140 | ||
141 | void XsOutline::_drawOutline (Boolean clear) | |
142 | { | |
143 | ||
144 | // Clear the current outline | |
145 | ||
146 | if (_savedH || _savedW) | |
147 | _drawIt (_savedX, _savedY, _savedW, _savedH); | |
148 | ||
149 | // Save current values | |
150 | ||
151 | _savedX = _x; _savedY = _y; | |
152 | _savedW = _width; _savedH = _height; | |
153 | ||
154 | // Draw the new outline (unless flagged to just clear) | |
155 | ||
156 | if (!clear) | |
157 | _drawIt (_x, _y, _width, _height); | |
158 | } | |
159 | ||
160 | // _getCursor | |
161 | ||
162 | Cursor XsOutline::_getCursor ( ) const | |
163 | { | |
164 | return (None); | |
165 | } | |
166 | ||
167 | // _grabPointer | |
168 | ||
169 | Boolean XsOutline::_grabPointer ( ) | |
170 | { | |
171 | ||
172 | // Sync everything up before being grabby | |
173 | ||
174 | XSync (XtDisplay (_w), False); | |
175 | ||
176 | // Grab the pointer | |
177 | ||
178 | if (XGrabPointer (XtDisplay (_w), XtWindow (_w), False, GrabEventMask, | |
179 | GrabModeAsync, GrabModeAsync, XtWindow (XtParent (_w)), _getCursor ( ), | |
180 | CurrentTime) != GrabSuccess) | |
181 | { | |
182 | XBell (XtDisplay (_w), 100); | |
183 | return (False); | |
184 | } | |
185 | ||
186 | return (True); | |
187 | } | |
188 | ||
189 | // _ungrabPointer | |
190 | ||
191 | void XsOutline::_ungrabPointer ( ) | |
192 | { | |
193 | ||
194 | // Ungrab the pointer | |
195 | ||
196 | XUngrabPointer (XtDisplay (_w), CurrentTime); | |
197 | } | |
198 | ||
199 | // _drawIt | |
200 | ||
201 | void XsOutline::_drawIt (int x, int y, int w, int h) | |
202 | { | |
203 | const int nsegs = 8; | |
204 | XSegment segs[nsegs]; | |
205 | ||
206 | // Across the top | |
207 | ||
208 | segs[0].x1 = x; segs[0].y1 = y; | |
209 | segs[0].x2 = x + w - 1; segs[0].y2 = y; | |
210 | ||
211 | segs[1].x1 = x + BorderSize; segs[1].y1 = y + BorderSize; | |
212 | segs[1].x2 = x + w - BorderSize - 1; segs[1].y2 = y + BorderSize; | |
213 | ||
214 | // Down the left | |
215 | ||
216 | segs[2].x1 = x + w - 1; segs[2].y1 = y + 1; | |
217 | segs[2].x2 = x + w - 1; segs[2].y2 = y + h - 1; | |
218 | ||
219 | segs[3].x1 = x + w - BorderSize - 1; segs[3].y1 = y + BorderSize + 1; | |
220 | segs[3].x2 = x + w - BorderSize - 1; segs[3].y2 = y + h - BorderSize - 1; | |
221 | ||
222 | // Across the bottom | |
223 | ||
224 | segs[4].x1 = x + 1; segs[4].y1 = y + h - 1; | |
225 | segs[4].x2 = x + w - 2; segs[4].y2 = y + h - 1; | |
226 | ||
227 | segs[5].x1 = x + BorderSize + 1; segs[5].y1 = y + h - BorderSize - 1; | |
228 | segs[5].x2 = x + w - BorderSize - 2; segs[5].y2 = y + h - BorderSize - 1; | |
229 | ||
230 | // Up the left | |
231 | ||
232 | segs[6].x1 = x; segs[6].y1 = y + h - 1; | |
233 | segs[6].x2 = x; segs[6].y2 = y + 1; | |
234 | ||
235 | segs[7].x1 = x + BorderSize; segs[7].y1 = y + h - BorderSize - 1; | |
236 | segs[7].x2 = x + BorderSize; segs[7].y2 = y + BorderSize + 1; | |
237 | ||
238 | // Draw the segments | |
239 | ||
240 | XDrawSegments (XtDisplay (_w), XtWindow (XtParent (_w)), _gc, segs, nsegs); | |
241 | } |