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