mask_screen.c revision b18c2d1e
1/*
2 * Routines for un/masking the whole screen.
3 *
4 * Used in showing the WelcomeWindow splash screen.
5 */
6
7#include "ctwm.h"
8
9#include <sys/select.h>
10
11#include "screen.h"
12#include "icons.h"
13#include "cursor.h"
14#include "image.h"
15#include "gram.tab.h"
16#include "list.h"
17#include "vscreen.h"
18#include "win_decorations.h"
19#include "win_utils.h"
20#include "workspace_manager.h"
21
22#include "mask_screen.h"
23
24
25/* Various internal subbits */
26static void PaintAllDecoration(void);
27
28
29/*
30 * Masking and unmasking; our public interface
31 */
32void
33MaskScreen(char *file)
34{
35	unsigned long valuemask;
36	XSetWindowAttributes attributes;
37	XEvent event;
38	Cursor waitcursor;
39	int x, y;
40	XColor black;
41
42	NewFontCursor(&waitcursor, "watch");
43
44	valuemask = (CWBackPixel | CWOverrideRedirect | CWEventMask | CWCursor);
45	attributes.override_redirect = True;
46	attributes.event_mask        = ExposureMask;
47	attributes.cursor            = waitcursor;
48	attributes.background_pixel  = Scr->Black;
49	Scr->WindowMask = XCreateWindow(dpy, Scr->Root, 0, 0,
50	                                Scr->rootw,
51	                                Scr->rooth,
52	                                0,
53	                                CopyFromParent, CopyFromParent,
54	                                CopyFromParent, valuemask,
55	                                &attributes);
56	XMapWindow(dpy, Scr->WindowMask);
57	XMaskEvent(dpy, ExposureMask, &event);
58
59	if(Scr->Monochrome != COLOR) {
60		return;
61	}
62
63	ColorPair WelcomeCp = {
64		.fore = Scr->Black,
65		.back = Scr->White,
66	};
67	Scr->WelcomeCmap  = XCreateColormap(dpy, Scr->WindowMask, Scr->d_visual,
68	                                    AllocNone);
69	if(! Scr->WelcomeCmap) {
70		return;
71	}
72	XSetWindowColormap(dpy, Scr->WindowMask, Scr->WelcomeCmap);
73	black.red   = 0;
74	black.green = 0;
75	black.blue  = 0;
76	XAllocColor(dpy, Scr->WelcomeCmap, &black);
77
78	AlternateCmap = Scr->WelcomeCmap;
79	if(! file) {
80		Scr->WelcomeImage  = GetImage("xwd:welcome.xwd", WelcomeCp);
81#ifdef XPM
82		if(Scr->WelcomeImage == None) {
83			Scr->WelcomeImage  = GetImage("xpm:welcome.xpm", WelcomeCp);
84		}
85#endif
86	}
87	else {
88		Scr->WelcomeImage  = GetImage(file, WelcomeCp);
89	}
90	AlternateCmap = None;
91	if(Scr->WelcomeImage == None) {
92		return;
93	}
94
95	if(0) {
96		// Dummy
97	}
98#ifdef CAPTIVE
99	else if(CLarg.is_captive) {
100		XSetWindowColormap(dpy, Scr->WindowMask, Scr->WelcomeCmap);
101		XSetWMColormapWindows(dpy, Scr->Root, &(Scr->WindowMask), 1);
102	}
103#endif
104	else {
105		XInstallColormap(dpy, Scr->WelcomeCmap);
106	}
107
108	Scr->WelcomeGC = XCreateGC(dpy, Scr->WindowMask, 0, NULL);
109	x = (Scr->rootw  -  Scr->WelcomeImage->width) / 2;
110	y = (Scr->rooth - Scr->WelcomeImage->height) / 2;
111
112	XSetWindowBackground(dpy, Scr->WindowMask, black.pixel);
113	XClearWindow(dpy, Scr->WindowMask);
114	XCopyArea(dpy, Scr->WelcomeImage->pixmap, Scr->WindowMask, Scr->WelcomeGC, 0, 0,
115	          Scr->WelcomeImage->width, Scr->WelcomeImage->height, x, y);
116}
117
118
119
120void
121UnmaskScreen(void)
122{
123	struct timeval      timeout;
124	Colormap            stdcmap = Scr->RootColormaps.cwins[0]->colormap->c;
125	Colormap            cmap;
126	XColor              colors [256], stdcolors [256];
127	int                 i, j, usec;
128
129	usec = 6000;
130	timeout.tv_usec = usec % (unsigned long) 1000000;
131	timeout.tv_sec  = usec / (unsigned long) 1000000;
132
133	if(Scr->WelcomeImage) {
134		Pixel pixels [256];
135
136		cmap = Scr->WelcomeCmap;
137		for(i = 0; i < 256; i++) {
138			pixels [i] = i;
139			colors [i].pixel = i;
140		}
141		XQueryColors(dpy, cmap, colors, 256);
142		XFreeColors(dpy, cmap, pixels, 256, 0L);
143		XFreeColors(dpy, cmap, pixels, 256, 0L);   /* Ah Ah */
144
145		for(i = 0; i < 256; i++) {
146			colors [i].pixel = i;
147			colors [i].flags = DoRed | DoGreen | DoBlue;
148			stdcolors [i].red   = colors [i].red;
149			stdcolors [i].green = colors [i].green;
150			stdcolors [i].blue  = colors [i].blue;
151		}
152		for(i = 0; i < 128; i++) {
153			for(j = 0; j < 256; j++) {
154				colors [j].red   = stdcolors [j].red   * ((127.0 - i) / 128.0);
155				colors [j].green = stdcolors [j].green * ((127.0 - i) / 128.0);
156				colors [j].blue  = stdcolors [j].blue  * ((127.0 - i) / 128.0);
157			}
158			XStoreColors(dpy, cmap, colors, 256);
159			select(0, NULL, NULL, NULL, &timeout);
160		}
161		XFreeColors(dpy, cmap, pixels, 256, 0L);
162		XFreeGC(dpy, Scr->WelcomeGC);
163		FreeImage(Scr->WelcomeImage);
164	}
165	if(Scr->Monochrome != COLOR) {
166		goto fin;
167	}
168
169	cmap = XCreateColormap(dpy, Scr->Root, Scr->d_visual, AllocNone);
170	if(! cmap) {
171		goto fin;
172	}
173	for(i = 0; i < 256; i++) {
174		colors [i].pixel = i;
175		colors [i].red   = 0;
176		colors [i].green = 0;
177		colors [i].blue  = 0;
178		colors [i].flags = DoRed | DoGreen | DoBlue;
179	}
180	XStoreColors(dpy, cmap, colors, 256);
181
182	if(0) {
183		// Dummy
184	}
185#ifdef CAPTIVE
186	else if(CLarg.is_captive) {
187		XSetWindowColormap(dpy, Scr->Root, cmap);
188	}
189#endif
190	else {
191		XInstallColormap(dpy, cmap);
192	}
193
194	XUnmapWindow(dpy, Scr->WindowMask);
195	XClearWindow(dpy, Scr->Root);
196	XSync(dpy, 0);
197	PaintAllDecoration();
198
199	for(i = 0; i < 256; i++) {
200		stdcolors [i].pixel = i;
201	}
202	XQueryColors(dpy, stdcmap, stdcolors, 256);
203	for(i = 0; i < 128; i++) {
204		for(j = 0; j < 256; j++) {
205			colors [j].pixel = j;
206			colors [j].red   = stdcolors [j].red   * (i / 127.0);
207			colors [j].green = stdcolors [j].green * (i / 127.0);
208			colors [j].blue  = stdcolors [j].blue  * (i / 127.0);
209			colors [j].flags = DoRed | DoGreen | DoBlue;
210		}
211		XStoreColors(dpy, cmap, colors, 256);
212		select(0, NULL, NULL, NULL, &timeout);
213	}
214
215	if(0) {
216		// Dummy
217	}
218#ifdef CAPTIVE
219	else if(CLarg.is_captive) {
220		XSetWindowColormap(dpy, Scr->Root, stdcmap);
221	}
222#endif
223	else {
224		XInstallColormap(dpy, stdcmap);
225	}
226
227	XFreeColormap(dpy, cmap);
228
229fin:
230	if(Scr->WelcomeCmap) {
231		XFreeColormap(dpy, Scr->WelcomeCmap);
232	}
233	XDestroyWindow(dpy, Scr->WindowMask);
234	Scr->WindowMask = (Window) 0;
235}
236
237
238
239
240/*
241 * Internal utils
242 */
243static void
244PaintAllDecoration(void)
245{
246	TwmWindow *tmp_win;
247	VirtualScreen *vs;
248
249	for(tmp_win = Scr->FirstWindow; tmp_win != NULL; tmp_win = tmp_win->next) {
250		if(! visible(tmp_win)) {
251			continue;
252		}
253		if(tmp_win->mapped) {
254			if(tmp_win->frame_bw3D) {
255				PaintBorders(tmp_win,
256				             (tmp_win->highlight && tmp_win == Scr->Focus));
257			}
258			if(tmp_win->title_w) {
259				PaintTitle(tmp_win);
260			}
261			if(tmp_win->titlebuttons) {
262				PaintTitleButtons(tmp_win);
263			}
264		}
265		else if((tmp_win->icon_on == true)  &&
266		                !Scr->NoIconTitlebar    &&
267		                tmp_win->icon           &&
268		                tmp_win->icon->w        &&
269		                !tmp_win->icon->w_not_ours &&
270		                ! LookInList(Scr->NoIconTitle, tmp_win->name, &tmp_win->class)) {
271			PaintIcon(tmp_win);
272		}
273	}
274	for(vs = Scr->vScreenList; vs != NULL; vs = vs->next) {
275		PaintWorkSpaceManager(vs);
276	}
277}
278