1 /* GKrellM
2 |  Copyright (C) 1999-2019 Bill Wilson
3 |                2007-2019 Stefan Gehn
4 |
5 |  Authors:  Bill Wilson    billw@gkrellm.net
6 |            Stefan Gehn    stefan+gkrellm@srcbox.net
7 |  Latest versions might be found at:  http://gkrellm.net
8 |
9 |
10 |  GKrellM is free software: you can redistribute it and/or modify it
11 |  under the terms of the GNU General Public License as published by
12 |  the Free Software Foundation, either version 3 of the License, or
13 |  (at your option) any later version.
14 |
15 |  GKrellM is distributed in the hope that it will be useful, but WITHOUT
16 |  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 |  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
18 |  License for more details.
19 |
20 |  You should have received a copy of the GNU General Public License
21 |  along with this program. If not, see http://www.gnu.org/licenses/
22 |
23 |
24 |  Additional permission under GNU GPL version 3 section 7
25 |
26 |  If you modify this program, or any covered work, by linking or
27 |  combining it with the OpenSSL project's OpenSSL library (or a
28 |  modified version of that library), containing parts covered by
29 |  the terms of the OpenSSL or SSLeay licenses, you are granted
30 |  additional permission to convey the resulting work.
31 |  Corresponding Source for a non-source form of such a combination
32 |  shall include the source code for the parts of OpenSSL used as well
33 |  as that of the covered work.
34 */
35 
36 #include "gkrellm.h"
37 #include "gkrellm-private.h"
38 #include <gdk/gdkwin32.h>
39 
40 static GdkGC	*trans_gc  = NULL;
41 static GdkColor trans_color;
42 
43 
44 void
gkrellm_winop_reset(void)45 gkrellm_winop_reset(void)
46 {
47 }
48 
49 void
gkrellm_winop_options(gint argc,gchar ** argv)50 gkrellm_winop_options(gint argc, gchar **argv)
51 	{
52 	// This essentially hides the taskbar entry on win32, unfortunately
53 	// gtk_window_set_skip_taskbar_hint() does not have any effect
54 	gtk_window_set_type_hint(GTK_WINDOW(gkrellm_get_top_window()), GDK_WINDOW_TYPE_HINT_UTILITY);
55 
56 	gkrellm_winop_state_above(_GK.on_top);
57 	}
58 
59 void
gkrellm_winop_withdrawn(void)60 gkrellm_winop_withdrawn(void)
61 	{
62 	}
63 
64 void
gkrellm_winop_place_gkrellm(gchar * geom)65 gkrellm_winop_place_gkrellm(gchar *geom)
66 	{
67 	gint newX = _GK.x_position;
68 	gint newY = _GK.y_position;
69 
70 	// parse the command line
71 	// +x+y or -x+y or +x-y or -x-y
72 
73 	gint startx = -1, starty = -1, endx = -1, endy = -1;
74 	gint w_gkrell, h_gkrell;
75 	gint stringSize = strlen(geom);
76 	gint i;
77 	gint xsign = 1, ysign = 1;
78 	gchar* part;
79 
80 	for (i = 0; i < stringSize; i++)
81 		{
82 		if (geom[i] != '+' && geom[i] != '-')
83 			{
84 			if (startx == -1)
85 				startx = i;
86 			if (starty == -1 && endx != -1)
87 				starty = i;
88 			}
89 		else
90 			{
91 			if (startx != -1 && endx == -1)
92 				{
93 				endx = i - 1;
94 				if (geom[i] == '-')
95 					xsign = -1;
96 				}
97 			if (starty != -1 && endy == -1)
98 				{
99 				endy = i - 1;
100 				if (geom[i] == '-')
101 					ysign = -1;
102 				}
103 			}
104 		}
105 
106 	if (starty != -1 && endy == -1)
107 		endy = stringSize - 1;
108 
109 	w_gkrell = _GK.chart_width + _GK.frame_left_width + _GK.frame_right_width;
110 	h_gkrell = _GK.monitor_height + _GK.total_frame_height;
111 
112 	if (startx >= 0 && startx <= endx && endx >= 0)
113 		{
114 		part = malloc(sizeof(gchar) * (endx - startx + 1 + 1));
115 		for (i = 0; i < endx - startx + 1; i++)
116 			part[i] = geom[i + startx];
117 		part[i] = '\0';
118 		newX = atoi(part);
119 		if (xsign == -1)
120 			newX = _GK.w_display - w_gkrell + newX;
121 		free(part);
122 		}
123 
124 	if (starty >= 0 && starty <= endy && endy >= 0)
125 		{
126 		part = malloc(sizeof(gchar) * (endy - starty + 1 + 1));
127 		for (i = 0; i < endy - starty + 1; i++)
128 			part[i] = geom[i + starty];
129 		part[i] = '\0';
130 		newY = atoi(part);
131 		if (ysign == -1)
132 			newY = _GK.h_display - h_gkrell + newY;
133 		free(part);
134 		}
135 
136 	if (   newX >= 0 && newX < _GK.w_display - 10
137 	    && newY >= 0 && newY < _GK.h_display - 25)
138 		{
139 		gdk_window_move(gkrellm_get_top_window()->window, newX, newY);
140 		_GK.y_position = newY;
141 		_GK.x_position = newX;
142 		}
143 
144 	_GK.position_valid = TRUE;
145 	}
146 
147 void
gkrellm_winop_flush_motion_events(void)148 gkrellm_winop_flush_motion_events(void)
149 	{
150 	}
151 
152 gboolean
gkrellm_winop_updated_background(void)153 gkrellm_winop_updated_background(void)
154 	{
155 	return TRUE;
156 	}
157 
158 void
gkrellm_winop_update_struts(void)159 gkrellm_winop_update_struts(void)
160 	{
161 	}
162 
163 gboolean
gkrellm_winop_draw_rootpixmap_onto_transparent_chart(GkrellmChart * p)164 gkrellm_winop_draw_rootpixmap_onto_transparent_chart(GkrellmChart *p)
165 	{
166 	if (!p->transparency || !p->drawing_area || !p->drawing_area->window || !trans_gc)
167 		return FALSE;
168 
169 	// Fill the panel with transparency color
170 	gdk_draw_rectangle(p->bg_src_pixmap, trans_gc, TRUE, 0, 0, p->w, p->h);
171 
172 	// If mode permits, stencil on non transparent parts of bg_clean_pixmap.
173 	if (p->transparency == 2 && p->bg_mask)
174 		{
175 		gdk_gc_set_clip_mask(_GK.text_GC, p->bg_mask);
176 		gdk_draw_drawable(p->bg_src_pixmap, _GK.text_GC, p->bg_clean_pixmap,
177 			0, 0, 0, 0, p->w, p->h);
178 		}
179 
180 	gdk_gc_set_clip_mask(_GK.text_GC, NULL);
181 	p->bg_sequence_id += 1;
182 	return TRUE;
183 	}
184 
185 gboolean
gkrellm_winop_draw_rootpixmap_onto_transparent_panel(GkrellmPanel * p)186 gkrellm_winop_draw_rootpixmap_onto_transparent_panel(GkrellmPanel *p)
187 	{
188 	if (!p->transparency || !p->drawing_area || !p->drawing_area->window || !trans_gc)
189 		return FALSE;
190 
191 	gdk_gc_set_fill(trans_gc, GDK_SOLID);
192 	gdk_gc_set_foreground(trans_gc, &trans_color);
193 
194 	// Fill the panel with transparency color
195 	gdk_draw_rectangle(p->bg_pixmap, trans_gc, TRUE, 0, 0, p->w, p->h);
196 
197 	// If mode permits, stencil on non transparent parts of bg_clean_pixmap.
198 	if (p->transparency == 2 && p->bg_mask)
199 		{
200 		gdk_gc_set_clip_mask(_GK.text_GC, p->bg_mask);
201 		gdk_draw_drawable(p->bg_pixmap, _GK.text_GC, p->bg_clean_pixmap,
202 			0, 0, 0, 0, p->w, p->h);
203 		gdk_gc_set_clip_mask(_GK.text_GC, NULL);
204 		}
205 	return TRUE;
206 	}
207 
208 static void
draw_rootpixmap_onto_transparent_spacers(GkrellmMonitor * mon)209 draw_rootpixmap_onto_transparent_spacers(GkrellmMonitor *mon)
210 {
211 	GkrellmMonprivate	*mp = mon->privat;
212 
213 	if (mp->top_spacer.image)
214 	{
215 		// Fill the panel with transparency color
216 		gdk_draw_rectangle(mp->top_spacer.pixmap, trans_gc, TRUE, 0, 0,
217 			_GK.chart_width, mp->top_spacer.height);
218 
219 		if (mp->top_spacer.mask)
220 		{
221 			gdk_gc_set_clip_mask(_GK.text_GC, mp->top_spacer.mask);
222 			gdk_draw_drawable(mp->top_spacer.pixmap, _GK.text_GC,
223 				mp->top_spacer.clean_pixmap, 0, 0, 0, 0, _GK.chart_width,
224 				mp->top_spacer.height);
225 		}
226 
227 		gtk_image_set_from_pixmap(GTK_IMAGE(mp->top_spacer.image),
228 			mp->top_spacer.pixmap, NULL);
229 	}
230 
231 	if (mp->bottom_spacer.image)
232 	{
233 		// Fill the panel with transparency color
234 		gdk_draw_rectangle(mp->bottom_spacer.pixmap, trans_gc, TRUE, 0, 0,
235 			_GK.chart_width, mp->bottom_spacer.height);
236 
237 		if (mp->bottom_spacer.mask)
238 		{
239 			gdk_gc_set_clip_mask(_GK.text_GC, mp->bottom_spacer.mask);
240 			gdk_draw_drawable(mp->bottom_spacer.pixmap, _GK.text_GC,
241 				mp->bottom_spacer.clean_pixmap, 0, 0, 0, 0, _GK.chart_width,
242 				mp->bottom_spacer.height);
243 		}
244 
245 		gtk_image_set_from_pixmap(GTK_IMAGE(mp->bottom_spacer.image),
246 			mp->bottom_spacer.pixmap, NULL);
247 	}
248 }
249 
250 void
gkrellm_winop_apply_rootpixmap_transparency(void)251 gkrellm_winop_apply_rootpixmap_transparency(void)
252 	{
253 	static gboolean isTransparent = FALSE;
254 
255 	GList			*list;
256 	GkrellmChart	*cp;
257 	GkrellmPanel	*p;
258 	HWND			w;
259 
260 	w = GDK_WINDOW_HWND(gkrellm_get_top_window()->window);
261 	if (!_GK.any_transparency && isTransparent)
262 		{	// make opaque
263 		SetWindowLong(w, GWL_EXSTYLE, GetWindowLong(w, GWL_EXSTYLE) & ~WS_EX_LAYERED);
264 		isTransparent = FALSE;
265 		return;
266 		}
267 	else if (_GK.any_transparency && !isTransparent)
268 		{	// make transparent
269 		if (trans_gc == NULL)
270 			{
271 			GdkColormap *cm = gtk_widget_get_colormap(gkrellm_get_top_window());
272 
273 			trans_gc = gdk_gc_new(gkrellm_get_top_window()->window);
274 			if (trans_gc == NULL)
275 				{
276 				g_warning("Could not create trans_gc!\n");
277 				return;
278 				}
279 
280 			gdk_gc_copy(trans_gc, _GK.draw1_GC);
281 			gdk_gc_set_fill(trans_gc, GDK_SOLID);
282 
283 			trans_color.red   = 65535;
284 			trans_color.green = 0;
285 			trans_color.blue  = 65535;
286 
287 			if (!gdk_colormap_alloc_color(cm , &trans_color, FALSE, TRUE))
288 				{
289 				g_warning("Could not allocate trans_color!\n");
290 				g_object_unref(trans_gc);
291 				trans_gc = NULL;
292 				return;
293 				}
294 
295 			gdk_gc_set_foreground(trans_gc, &trans_color);
296 			}
297 		SetWindowLong(w, GWL_EXSTYLE, GetWindowLong(w, GWL_EXSTYLE) | WS_EX_LAYERED);
298 		SetLayeredWindowAttributes(w, RGB(255, 0, 255), 0, LWA_COLORKEY);
299 		isTransparent = TRUE;
300 		}
301 
302 	if (isTransparent)
303 		{
304 		for (list = gkrellm_get_chart_list(); list; list = list->next)
305 			{
306 			cp = (GkrellmChart *) list->data;
307 			if (!cp->transparency || !cp->shown)
308 				continue;
309 			gkrellm_winop_draw_rootpixmap_onto_transparent_chart(cp);
310 			gkrellm_refresh_chart(cp);
311 			}
312 
313 		for (list = gkrellm_get_panel_list(); list; list = list->next)
314 			{
315 			p = (GkrellmPanel *) list->data;
316 			if (!p->transparency || !p->shown)
317 				continue;
318 			gkrellm_draw_panel_label(p);
319 			}
320 
321 		for (list = gkrellm_monitor_list; list; list = list->next)
322 			{
323 			draw_rootpixmap_onto_transparent_spacers((GkrellmMonitor *)list->data);
324 			}
325 
326 		gdk_gc_set_clip_mask(_GK.text_GC, NULL);
327 		}
328 	}
329 
330 void
gkrellm_winop_state_skip_taskbar(gboolean state)331 gkrellm_winop_state_skip_taskbar(gboolean state)
332 	{
333 	}
334 
335 void
gkrellm_winop_state_skip_pager(gboolean state)336 gkrellm_winop_state_skip_pager(gboolean state)
337 	{
338 	}
339 
340 void
gkrellm_winop_state_above(gboolean state)341 gkrellm_winop_state_above(gboolean state)
342 	{
343 	GtkWindow *window = GTK_WINDOW(gkrellm_get_top_window());
344 	gtk_window_set_keep_above(window, state);
345 	}
346 
347 void
gkrellm_winop_state_below(gboolean state)348 gkrellm_winop_state_below(gboolean state)
349 	{
350 	}
351