503.1.58
by Matthew Fuller
Start moving generalized drawing funcs into their own file by pulling |
1 |
/*
|
2 |
* Various drawing routines.
|
|
3 |
*
|
|
4 |
* These are generalized routines that are used in multiple places in the
|
|
5 |
* codebase. A number of other functions that are "drawing" related are
|
|
6 |
* left in various places through the codebase; some are only used in one
|
|
7 |
* file, and are left there for internal linkage, while others are
|
|
8 |
* part of a more abstract subdivision (e.g., the window decoration bits
|
|
538.1.2
by Matthew Fuller
Update a ref to decorations.c in a comment. |
9 |
* in win_decorations.c) and so belong there.
|
503.1.58
by Matthew Fuller
Start moving generalized drawing funcs into their own file by pulling |
10 |
*/
|
11 |
||
12 |
#include "ctwm.h" |
|
13 |
||
14 |
||
15 |
#include "screen.h" |
|
16 |
#include "gram.tab.h" |
|
524.1.1
by Matthew Fuller
Pull occupation.h out of screen.h, and include it directly in the |
17 |
#include "occupation.h" |
524.1.3
by Matthew Fuller
Pull vscreen.h out of screen.h and #include it directly in the files |
18 |
#include "vscreen.h" |
503.1.58
by Matthew Fuller
Start moving generalized drawing funcs into their own file by pulling |
19 |
|
20 |
#include "drawing.h" |
|
21 |
||
22 |
||
23 |
||
24 |
/*
|
|
25 |
* "3D border" drawings are used all over the place, not just in the
|
|
26 |
* obvious usage as window borders.
|
|
27 |
*/
|
|
28 |
#define FBGC(gc, fix_fore, fix_back)\
|
|
29 |
Gcv.foreground = fix_fore;\
|
|
30 |
Gcv.background = fix_back;\
|
|
31 |
XChangeGC(dpy, gc, GCForeground|GCBackground,&Gcv)
|
|
32 |
||
33 |
void
|
|
34 |
Draw3DBorder(Window w, int x, int y, int width, int height, int bw, |
|
505.1.23
by Matthew Fuller
Switch Draw3DBorder's state arg over to the ButtonState enum. All the |
35 |
ColorPair cp, ButtonState state, bool fill, bool forcebw) |
503.1.58
by Matthew Fuller
Start moving generalized drawing funcs into their own file by pulling |
36 |
{
|
37 |
int i; |
|
38 |
XGCValues gcv; |
|
39 |
unsigned long gcm; |
|
40 |
||
41 |
if((width < 1) || (height < 1)) { |
|
42 |
return; |
|
43 |
}
|
|
44 |
if(Scr->Monochrome != COLOR) { |
|
45 |
if(fill) { |
|
46 |
gcm = GCFillStyle; |
|
47 |
gcv.fill_style = FillOpaqueStippled; |
|
48 |
XChangeGC(dpy, Scr->BorderGC, gcm, &gcv); |
|
49 |
XFillRectangle(dpy, w, Scr->BorderGC, x, y, width, height); |
|
50 |
}
|
|
51 |
gcm = 0; |
|
52 |
gcm |= GCLineStyle; |
|
53 |
gcv.line_style = (state == on) ? LineSolid : LineDoubleDash; |
|
54 |
gcm |= GCFillStyle; |
|
55 |
gcv.fill_style = FillSolid; |
|
56 |
XChangeGC(dpy, Scr->BorderGC, gcm, &gcv); |
|
57 |
for(i = 0; i < bw; i++) { |
|
58 |
XDrawLine(dpy, w, Scr->BorderGC, x, y + i, |
|
59 |
x + width - i - 1, y + i); |
|
60 |
XDrawLine(dpy, w, Scr->BorderGC, x + i, y, |
|
61 |
x + i, y + height - i - 1); |
|
62 |
}
|
|
63 |
||
64 |
gcm = 0; |
|
65 |
gcm |= GCLineStyle; |
|
66 |
gcv.line_style = (state == on) ? LineDoubleDash : LineSolid; |
|
67 |
gcm |= GCFillStyle; |
|
68 |
gcv.fill_style = FillSolid; |
|
69 |
XChangeGC(dpy, Scr->BorderGC, gcm, &gcv); |
|
70 |
for(i = 0; i < bw; i++) { |
|
71 |
XDrawLine(dpy, w, Scr->BorderGC, x + width - i - 1, y + i, |
|
72 |
x + width - i - 1, y + height - 1); |
|
73 |
XDrawLine(dpy, w, Scr->BorderGC, x + i, y + height - i - 1, |
|
74 |
x + width - 1, y + height - i - 1); |
|
75 |
}
|
|
76 |
return; |
|
77 |
}
|
|
78 |
||
79 |
if(fill) { |
|
80 |
FBGC(Scr->BorderGC, cp.back, cp.fore); |
|
81 |
XFillRectangle(dpy, w, Scr->BorderGC, x, y, width, height); |
|
82 |
}
|
|
83 |
if(Scr->BeNiceToColormap) { |
|
84 |
int dashoffset = 0; |
|
85 |
||
86 |
gcm = 0; |
|
87 |
gcm |= GCLineStyle; |
|
88 |
gcv.line_style = (forcebw) ? LineSolid : LineDoubleDash; |
|
89 |
gcm |= GCBackground; |
|
90 |
gcv.background = cp.back; |
|
91 |
XChangeGC(dpy, Scr->BorderGC, gcm, &gcv); |
|
92 |
||
93 |
if(state == on) { |
|
94 |
XSetForeground(dpy, Scr->BorderGC, Scr->Black); |
|
95 |
}
|
|
96 |
else { |
|
97 |
XSetForeground(dpy, Scr->BorderGC, Scr->White); |
|
98 |
}
|
|
99 |
for(i = 0; i < bw; i++) { |
|
100 |
XDrawLine(dpy, w, Scr->BorderGC, x + i, y + dashoffset, |
|
101 |
x + i, y + height - i - 1); |
|
102 |
XDrawLine(dpy, w, Scr->BorderGC, x + dashoffset, y + i, |
|
103 |
x + width - i - 1, y + i); |
|
104 |
dashoffset = 1 - dashoffset; |
|
105 |
}
|
|
106 |
XSetForeground(dpy, Scr->BorderGC, ((state == on) ? Scr->White : Scr->Black)); |
|
107 |
for(i = 0; i < bw; i++) { |
|
108 |
XDrawLine(dpy, w, Scr->BorderGC, x + i, y + height - i - 1, |
|
109 |
x + width - 1, y + height - i - 1); |
|
110 |
XDrawLine(dpy, w, Scr->BorderGC, x + width - i - 1, y + i, |
|
111 |
x + width - i - 1, y + height - 1); |
|
112 |
}
|
|
113 |
return; |
|
114 |
}
|
|
115 |
if(state == on) { |
|
116 |
FBGC(Scr->BorderGC, cp.shadd, cp.shadc); |
|
117 |
}
|
|
118 |
else { |
|
119 |
FBGC(Scr->BorderGC, cp.shadc, cp.shadd); |
|
120 |
}
|
|
121 |
for(i = 0; i < bw; i++) { |
|
122 |
XDrawLine(dpy, w, Scr->BorderGC, x, y + i, |
|
123 |
x + width - i - 1, y + i); |
|
124 |
XDrawLine(dpy, w, Scr->BorderGC, x + i, y, |
|
125 |
x + i, y + height - i - 1); |
|
126 |
}
|
|
127 |
||
128 |
if(state == on) { |
|
129 |
FBGC(Scr->BorderGC, cp.shadc, cp.shadd); |
|
130 |
}
|
|
131 |
else { |
|
132 |
FBGC(Scr->BorderGC, cp.shadd, cp.shadc); |
|
133 |
}
|
|
134 |
for(i = 0; i < bw; i++) { |
|
135 |
XDrawLine(dpy, w, Scr->BorderGC, x + width - i - 1, y + i, |
|
136 |
x + width - i - 1, y + height - 1); |
|
137 |
XDrawLine(dpy, w, Scr->BorderGC, x + i, y + height - i - 1, |
|
138 |
x + width - 1, y + height - i - 1); |
|
139 |
}
|
|
140 |
return; |
|
141 |
}
|
|
142 |
||
143 |
#undef FBGC
|
|
503.1.59
by Matthew Fuller
Pull PaintWsButton() off into general drawing file, since it's shortly |
144 |
|
145 |
||
146 |
||
147 |
/*
|
|
148 |
* Paint a button representing a workspace. This is used in the
|
|
149 |
* workspace manager window when it button mode, as well as in the
|
|
150 |
* f.occupy window.
|
|
151 |
*/
|
|
152 |
void
|
|
153 |
PaintWsButton(PWBType which, VirtualScreen *vs, Window w, |
|
503.1.99
by Matthew Fuller
Convert PaintWsButton() arg from int to ButtonState; it's already |
154 |
char *label, ColorPair cp, ButtonState state) |
503.1.59
by Matthew Fuller
Pull PaintWsButton() off into general drawing file, since it's shortly |
155 |
{
|
156 |
int bwidth, bheight; |
|
157 |
MyFont font; |
|
158 |
int hspace, vspace; |
|
159 |
||
160 |
if(which == WSPCWINDOW) { |
|
161 |
bwidth = vs->wsw->bwidth; |
|
162 |
bheight = vs->wsw->bheight; |
|
163 |
font = Scr->workSpaceMgr.buttonFont; |
|
164 |
}
|
|
165 |
else if(which == OCCUPYWINDOW) { |
|
166 |
OccupyWindow *occwin = Scr->workSpaceMgr.occupyWindow; |
|
167 |
bwidth = occwin->bwidth; |
|
168 |
bheight = occwin->bheight; |
|
169 |
font = occwin->font; |
|
170 |
}
|
|
171 |
else if(which == OCCUPYBUTTON) { |
|
172 |
OccupyWindow *occwin = Scr->workSpaceMgr.occupyWindow; |
|
173 |
bwidth = occwin->owidth; |
|
174 |
bheight = occwin->bheight; |
|
175 |
font = occwin->font; |
|
176 |
}
|
|
177 |
else { |
|
178 |
return; |
|
179 |
}
|
|
180 |
||
181 |
{
|
|
182 |
int strWid, strHei; |
|
183 |
XRectangle inc_rect; |
|
184 |
XRectangle logical_rect; |
|
185 |
||
186 |
XmbTextExtents(font.font_set, label, strlen(label), &inc_rect, |
|
187 |
&logical_rect); |
|
188 |
strHei = logical_rect.height; |
|
189 |
vspace = ((bheight + strHei - font.descent) / 2); |
|
190 |
strWid = logical_rect.width; |
|
191 |
hspace = (bwidth - strWid) / 2; |
|
192 |
}
|
|
193 |
||
194 |
if(hspace < (Scr->WMgrButtonShadowDepth + 1)) { |
|
195 |
hspace = Scr->WMgrButtonShadowDepth + 1; |
|
196 |
}
|
|
197 |
XClearWindow(dpy, w); |
|
198 |
||
199 |
if(Scr->Monochrome == COLOR) { |
|
200 |
Draw3DBorder(w, 0, 0, bwidth, bheight, Scr->WMgrButtonShadowDepth, |
|
201 |
cp, state, true, false); |
|
202 |
||
203 |
switch(Scr->workSpaceMgr.buttonStyle) { |
|
204 |
case STYLE_NORMAL: |
|
205 |
break; |
|
206 |
||
207 |
case STYLE_STYLE1: |
|
208 |
Draw3DBorder(w, |
|
209 |
Scr->WMgrButtonShadowDepth - 1, |
|
210 |
Scr->WMgrButtonShadowDepth - 1, |
|
211 |
bwidth - 2 * Scr->WMgrButtonShadowDepth + 2, |
|
212 |
bheight - 2 * Scr->WMgrButtonShadowDepth + 2, |
|
213 |
1, cp, (state == on) ? off : on, true, false); |
|
214 |
break; |
|
215 |
||
216 |
case STYLE_STYLE2: |
|
217 |
Draw3DBorder(w, |
|
218 |
Scr->WMgrButtonShadowDepth / 2, |
|
219 |
Scr->WMgrButtonShadowDepth / 2, |
|
220 |
bwidth - Scr->WMgrButtonShadowDepth, |
|
221 |
bheight - Scr->WMgrButtonShadowDepth, |
|
222 |
1, cp, (state == on) ? off : on, true, false); |
|
223 |
break; |
|
224 |
||
225 |
case STYLE_STYLE3: |
|
226 |
Draw3DBorder(w, |
|
227 |
1, |
|
228 |
1, |
|
229 |
bwidth - 2, |
|
230 |
bheight - 2, |
|
231 |
1, cp, (state == on) ? off : on, true, false); |
|
232 |
break; |
|
233 |
}
|
|
234 |
FB(cp.fore, cp.back); |
|
235 |
XmbDrawString(dpy, w, font.font_set, Scr->NormalGC, hspace, vspace, |
|
236 |
label, strlen(label)); |
|
237 |
}
|
|
238 |
else { |
|
239 |
Draw3DBorder(w, 0, 0, bwidth, bheight, Scr->WMgrButtonShadowDepth, |
|
240 |
cp, state, true, false); |
|
241 |
if(state == on) { |
|
242 |
FB(cp.fore, cp.back); |
|
243 |
XmbDrawImageString(dpy, w, font.font_set, Scr->NormalGC, hspace, vspace, |
|
244 |
label, strlen(label)); |
|
245 |
}
|
|
246 |
else { |
|
247 |
FB(cp.back, cp.fore); |
|
248 |
XmbDrawImageString(dpy, w, font.font_set, Scr->NormalGC, hspace, vspace, |
|
249 |
label, strlen(label)); |
|
250 |
}
|
|
251 |
}
|
|
252 |
}
|