~ctwm/ctwm/trunk

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
}