1 /*
2  * (SLIK) SimpLIstic sKin functions
3  * (C) 2005 John Ellis
4  *
5  * Author: John Ellis
6  *
7  * This software is released under the GNU General Public License (GNU GPL).
8  * Please read the included file COPYING for more information.
9  * This software comes with no warranty of any kind, use at your own risk!
10  */
11 
12 #include "ui2_includes.h"
13 #include "ui2_typedefs.h"
14 #include "ui2_util.h"
15 
16 #include "ui2_main.h"
17 #include "ui_fileops.h"
18 #include "ui_pixbuf_ops.h"
19 
20 #include <gdk/gdkx.h>
21 #include <X11/Xlib.h>
22 #include <X11/Xatom.h>
23 
24 
25 /*
26  * try 0.5 or 3 ;)
27  * for non-whole numbers change GDK_INTERP_NEAREST to GDK_INTERP_BILINEAR below
28  */
29 #define DOUBLE_MULTIPLIER 2
30 
31 
util_size(gint * n)32 void util_size(gint *n)
33 {
34 	if (slik_scale && slik_scale_value > 0.1)
35 		{
36 		if (*n > 0)
37 			{
38 			*n = (gint)((gfloat)*n * slik_scale_value);
39 			if (*n < 1) *n = 1;
40 			}
41 		}
42 	else if (slik_double_size)
43 		{
44 		*n *= DOUBLE_MULTIPLIER;
45 		}
46 }
47 
util_color(guint8 * r,guint8 * g,guint8 * b,guint8 * a)48 void util_color(guint8 *r, guint8 *g, guint8 *b, guint8 *a)
49 {
50 	if (slik_colorshift_on && r && g && b)
51 		{
52 		gint saturation = (*r + *g + *b) / 3;
53 
54 		*r = pixel_shift(*r, saturation, slik_colorshift_r, slik_colorshift_a);
55 		*g = pixel_shift(*g, saturation, slik_colorshift_g, slik_colorshift_a);
56 		*b = pixel_shift(*b, saturation, slik_colorshift_b, slik_colorshift_a);
57 		}
58 	if (slik_transparency_force && a)
59 		{
60 		gint t;
61 
62 		t = (gint)*a;
63 		t = (t * 3 + t * slik_transparency_force_a / 255) / 4;
64 		*a = t;
65 		}
66 }
67 
util_pixbuf_new_from_file(const gchar * path)68 GdkPixbuf *util_pixbuf_new_from_file(const gchar *path)
69 {
70 	GdkPixbuf *pixbuf;
71 	gchar *pathl;
72 
73 	pathl = path_from_utf8(path);
74 	pixbuf = gdk_pixbuf_new_from_file(pathl, NULL);
75 	g_free(pathl);
76 
77 	return pixbuf;
78 }
79 
util_size_pixbuf(GdkPixbuf * pb,gint apply_adjustments)80 GdkPixbuf *util_size_pixbuf(GdkPixbuf *pb, gint apply_adjustments)
81 {
82 	if (slik_scale && slik_scale_value > 0.1)
83 		{
84 		gint w, h;
85 		GdkPixbuf *tmp;
86 
87 		tmp = pb;
88 		w = gdk_pixbuf_get_width(tmp);
89 		h = gdk_pixbuf_get_height(tmp);
90 		w = (gint)((gfloat)w * slik_scale_value);
91 		if (w < 1) w = 1;
92 		h = (gint)((gfloat)h * slik_scale_value);
93 		if (h < 1) h = 1;
94 
95 		pb = gdk_pixbuf_scale_simple(tmp, w, h, GDK_INTERP_NEAREST);
96 
97 		gdk_pixbuf_unref(tmp);
98 		}
99 	else if (pb && slik_double_size)
100 		{
101 		GdkPixbuf *tmp = pb;
102 		pb = gdk_pixbuf_scale_simple(tmp, gdk_pixbuf_get_width(tmp) * DOUBLE_MULTIPLIER,
103 					     gdk_pixbuf_get_height(tmp) * DOUBLE_MULTIPLIER,
104 					     GDK_INTERP_NEAREST);
105 		gdk_pixbuf_unref(tmp);
106 		}
107 
108 	if (pb && apply_adjustments && slik_transparency_force)
109 		{
110 		gint t;
111 		if (!gdk_pixbuf_get_has_alpha(pb))
112 			{
113 			GdkPixbuf *tmp = pb;
114 			pb = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8,
115 					    gdk_pixbuf_get_width(pb), gdk_pixbuf_get_height(pb));
116 			pixbuf_copy_area(tmp, 0, 0, pb, 0, 0,
117 					 gdk_pixbuf_get_width(pb), gdk_pixbuf_get_height(pb), FALSE);
118 			pixbuf_alpha_adjust(pb, 0, 0, gdk_pixbuf_get_width(pb), gdk_pixbuf_get_height(pb), 255);
119 			gdk_pixbuf_unref(tmp);
120 			}
121 		t = (gint)((float)-64.0 * (255 - slik_transparency_force_a) / 255);
122 		pixbuf_alpha_adjust(pb, 0, 0, gdk_pixbuf_get_width(pb), gdk_pixbuf_get_height(pb), t);
123 		}
124 
125 	if (pb && apply_adjustments && slik_colorshift_on)
126 		{
127 		pixbuf_draw_rect_shift(pb, 0, 0, gdk_pixbuf_get_width(pb), gdk_pixbuf_get_height(pb),
128 				       slik_colorshift_r, slik_colorshift_g, slik_colorshift_b, slik_colorshift_a);
129 		}
130 
131 	return pb;
132 }
133 
util_clip_region(gint x,gint y,gint w,gint h,gint clip_x,gint clip_y,gint clip_w,gint clip_h,gint * rx,gint * ry,gint * rw,gint * rh)134 gint util_clip_region(gint x, gint y, gint w, gint h,
135 		      gint clip_x, gint clip_y, gint clip_w, gint clip_h,
136 		      gint *rx, gint *ry, gint *rw, gint *rh)
137 {
138 	if (clip_x + clip_w < x ||
139 	    clip_x > x + w ||
140 	    clip_y + clip_h < y ||
141 	    clip_y > y + h)
142 		{
143 		return FALSE;
144 		}
145 
146 	*rx = MAX(x, clip_x);
147 	*rw = MIN((x + w), (clip_x + clip_w)) - *rx;
148 
149 	*ry = MAX(y, clip_y);
150 	*rh = MIN((y + h), (clip_y + clip_h)) - *ry;
151 
152 	return TRUE;
153 }
154 
util_pixbuf_copy_border_clipped(GdkPixbuf * src,gint border_left,gint border_right,gint border_top,gint border_bottom,GdkPixbuf * dest,gint x,gint y,gint w,gint h,gint clip_x,gint clip_y,gint clip_w,gint clip_h,gint alpha)155 void util_pixbuf_copy_border_clipped(GdkPixbuf *src,
156 				     gint border_left, gint border_right,
157 				     gint border_top, gint border_bottom,
158 				     GdkPixbuf *dest, gint x, gint y, gint w, gint h,
159 				     gint clip_x, gint clip_y, gint clip_w, gint clip_h,
160 				     gint alpha)
161 {
162 	gint bx, by, bw, bh;
163 	gint sw, sh;
164 	gint rx, ry;
165 
166 	sw = gdk_pixbuf_get_width(src);
167 	sh = gdk_pixbuf_get_height(src);
168 
169 	border_left = MIN(border_left, w);
170 	border_right = MIN(border_right, w);
171 	border_top = MIN(border_top, h);
172 	border_bottom = MIN(border_bottom, h);
173 
174 	/* top left */
175 	rx = x;
176 	ry = y;
177 	if (util_clip_region(rx, ry, border_left, border_top,
178 			     clip_x, clip_y, clip_w, clip_h,
179 			     &bx, &by, &bw, &bh))
180 		{
181 		pixbuf_copy_area_alpha(src, bx - rx, by - ry,
182 				       dest, bx, by, bw, bh, alpha);
183 		}
184 	/* top */
185 	rx = x + border_left;
186 	ry = y;
187 	if (util_clip_region(rx, ry, w - border_left - border_right, border_top,
188 			     clip_x, clip_y, clip_w, clip_h,
189 			     &bx, &by, &bw, &bh))
190 		{
191 		pixbuf_copy_fill_alpha_offset(src, border_left, 0, sw - border_left - border_right, border_top,
192 					      dest, bx, by, bw, bh, FALSE, alpha,
193 					      bx - rx, by - ry);
194 		}
195 	/* top right */
196 	rx = x + w - border_right;
197 	ry = y;
198 	if (util_clip_region(rx, ry, border_right, border_top,
199 			     clip_x, clip_y, clip_w, clip_h,
200 			     &bx, &by, &bw, &bh))
201 		{
202 		pixbuf_copy_area_alpha(src, sw - border_right + (bx - rx), by - ry,
203 				       dest, bx, by, bw, bh, alpha);
204 		}
205 	/* left */
206 	rx = x;
207 	ry = y + border_top;
208 	if (util_clip_region(rx, ry, border_left, h - border_top - border_bottom,
209 			     clip_x, clip_y, clip_w, clip_h,
210 			     &bx, &by, &bw, &bh))
211 		{
212 		pixbuf_copy_fill_alpha_offset(src, 0, border_top, border_left, sh - border_top - border_bottom,
213 					      dest, bx, by, bw, bh, FALSE, alpha,
214 					      bx - rx, by - ry);
215 		}
216 	/* right */
217 	rx = x + w - border_right;
218 	ry = y + border_top;
219 	if (util_clip_region(rx, ry, border_right, h - border_top - border_bottom,
220 			     clip_x, clip_y, clip_w, clip_h,
221 			     &bx, &by, &bw, &bh))
222 		{
223 		pixbuf_copy_fill_alpha_offset(src, sw - border_right, border_top, border_right, sh - border_top - border_bottom,
224 					      dest, bx, by, bw, bh, FALSE, alpha,
225 					      bx - rx, by - ry);
226 		}
227 	/* bottom left */
228 	rx = x;
229 	ry = y + h - border_bottom;
230 	if (util_clip_region(rx, ry, border_left, border_bottom,
231 			     clip_x, clip_y, clip_w, clip_h,
232 			     &bx, &by, &bw, &bh))
233 		{
234 		pixbuf_copy_area_alpha(src, bx - rx, sh - border_bottom + (by - ry),
235 				       dest, bx, by, bw, bh, alpha);
236 		}
237 	/* bottom */
238 	rx = x + border_left;
239 	ry = y + h - border_bottom;
240 	if (util_clip_region(rx, ry, w - border_left - border_right, border_bottom,
241 			     clip_x, clip_y, clip_w, clip_h,
242 			     &bx, &by, &bw, &bh))
243 		{
244 		pixbuf_copy_fill_alpha_offset(src, border_left, sh - border_bottom, sw - border_left - border_right, border_bottom,
245 					      dest, bx, by, bw, bh, FALSE, alpha,
246 					      bx - rx, by - ry);
247 		}
248 	/* bottom right */
249 	rx = x + w - border_right;
250 	ry = y + h - border_bottom;
251 	if (util_clip_region(rx, ry, border_right, border_bottom,
252 			     clip_x, clip_y, clip_w, clip_h,
253 			     &bx, &by, &bw, &bh))
254 		{
255 		pixbuf_copy_area_alpha(src, sw - border_right + (bx - rx), sh - border_bottom + (by - ry),
256 				       dest, bx, by, bw, bh, alpha);
257 		}
258 }
259 
260 
261 /*
262  * returns a portion of the root window in a gdk_pixbuf
263  * any part that is off the screen is set to black.
264  */
265 
util_pixbuf_fill_from_root_window(GdkPixbuf * pb,gint x,gint y,gint get_all)266 gint util_pixbuf_fill_from_root_window(GdkPixbuf *pb, gint x, gint y, gint get_all)
267 {
268 	GdkVisual *gdkvisual;
269 	GdkWindow *rootwindow;
270 	gint screen_w;
271 	gint screen_h;
272 	gint screen_x;
273 	gint screen_y;
274 	gint clear_window = TRUE;
275 	gint w;
276 	gint h;
277 
278 	if (!pb) return FALSE;
279 
280 	w = gdk_pixbuf_get_width(pb);
281 	h = gdk_pixbuf_get_height(pb);
282 
283 	if (w < 1 || h < 1 ) return FALSE;
284 
285 	screen_w = gdk_screen_width();
286 	screen_h = gdk_screen_height();
287 
288 	if (x >= screen_w || y >= screen_h || x + w < 0 || y + h < 0)
289 		{
290 		pixbuf_draw_rect_fill(pb, 0, 0, w, h, 0, 0, 0, 255);
291 		return TRUE;
292 		}
293 
294 	screen_x = x;
295 	if (screen_x < 0)
296 		{
297 		pixbuf_draw_rect_fill(pb, 0, 0, -screen_x, h, 0, 0, 0, 255);
298 		w += screen_x;
299 		screen_x = 0;
300 		}
301 	if (screen_x + w > screen_w)
302 		{
303 		pixbuf_draw_rect_fill(pb, w - (screen_x + w - screen_w), 0, screen_x + w - screen_w, h, 0, 0, 0, 255);
304 		w -= screen_x + w - screen_w;
305 		}
306 
307 	screen_y = y;
308 	if (screen_y < 0)
309 		{
310 		pixbuf_draw_rect_fill(pb, 0, 0, w, -screen_y, 0, 0, 0, 255);
311 		h += screen_y;
312 		screen_y = 0;
313 		}
314 	if (screen_y + h > screen_h)
315 		{
316 		pixbuf_draw_rect_fill(pb, 0, h - (screen_y + h - screen_h), w, screen_y + h - screen_h, 0, 0, 0, 255);
317 		h -= screen_y + h - screen_h;
318 		}
319 
320 	if (w < 1 || h < 1) return TRUE;
321 
322 	rootwindow = gdk_get_default_root_window();
323 	if (!rootwindow) return TRUE;
324 
325 	gdkvisual = gdk_drawable_get_visual(rootwindow);
326 	if (gdkvisual != gdk_visual_get_system()) return TRUE;
327 
328 	if (debug_mode) printf("root window capture: %d, %d (%d x %d) to %d, %d\n", screen_x, screen_y, w, h, x, y);
329 
330 	if (!get_all)
331 		{
332 		/*
333 		 * get the backing pixmap
334 		 * Don't even ask how this works, I slapped it together
335 		 * from various references from other apps that do the same.
336 		 */
337 		Atom prop, type;
338 		int format;
339 		unsigned long length, after;
340 		unsigned char *data = NULL;
341 		Window desktop_window;
342 
343 		gdk_error_trap_push();
344 
345 		desktop_window = GDK_ROOT_WINDOW();
346 
347 		prop = XInternAtom(GDK_DISPLAY(), "_XROOTPMAP_ID", True);
348 
349 		if (prop != None)
350 			{
351 			XGetWindowProperty(GDK_DISPLAY(), desktop_window, prop, 0L, 1L, False,
352 					   AnyPropertyType, &type, &format, &length, &after,
353 					   &data);
354 
355 			if (type == XA_PIXMAP)
356 				{
357 				Pixmap p;
358 				p = *((Pixmap *)data);
359 
360 				if (p != None)
361 					{
362 					static GdkPixmap *pp = NULL;
363 					GdkColormap *cmap;
364 					gint p_w, p_h;
365 
366 					clear_window = FALSE;
367 
368 					if (!pp) pp = gdk_pixmap_foreign_new(p);
369 					cmap = gdk_drawable_get_colormap(rootwindow);
370 
371 					gdk_drawable_get_size(pp, &p_w, &p_h);
372 
373 					if (p_w < screen_x + w || p_h < screen_y + h)
374 						{
375 						/* tiled */
376 						gint i, j;
377 
378 						for (j = (screen_y / p_h) * p_h; j < screen_y + h; j += p_h)
379 						    for (i = (screen_x / p_w) * p_w; i < screen_x + w; i += p_w)
380 							{
381 							gint offset_x, offset_y;
382 							gint offset_w, offset_h;
383 
384 							if (j < screen_y)
385 								{
386 								offset_y = screen_y - j;
387 								}
388 							else
389 								{
390 								offset_y = 0;
391 								}
392 
393 							offset_h = p_h - offset_y;
394 							if (j + offset_y + offset_h >= screen_y + h) offset_h = (screen_y + h) - (j + offset_y);
395 
396 							if (i < screen_x)
397 								{
398 								offset_x = screen_x - i;
399 								}
400 							else
401 								{
402 								offset_x = 0;
403 								}
404 
405 							offset_w = p_w - offset_x;
406 							if (i + offset_x + offset_w >= screen_x + w) offset_w = (screen_x + w) - (i + offset_x);
407 
408 							gdk_pixbuf_get_from_drawable(pb, pp, cmap,
409 										     offset_x, offset_y,
410 									     	     (i + offset_x) - screen_x, (j + offset_y) - screen_y, offset_w, offset_h);
411 							}
412 						}
413 					else
414 						{
415 						gdk_pixbuf_get_from_drawable(pb, pp, cmap,
416 									     screen_x, screen_y,
417 								     	     screen_x - x, screen_y - y, w, h);
418 						}
419 					}
420 				}
421 			if (data) XFree(data);
422 			}
423 		gdk_error_trap_pop();
424 		}
425 	else
426 		{
427 		/* merely get whatever is on the screen in this area, including other windows */
428 		gdk_pixbuf_get_from_drawable(pb, rootwindow, NULL,
429 					     screen_x, screen_y,
430 					     screen_x - x, screen_y - y, w, h);
431 		clear_window = FALSE;
432 		}
433 
434 	if (clear_window) pixbuf_draw_rect_fill(pb, screen_x - x, screen_y - y, w, h, 0, 0, 0, 255);
435 
436 	return TRUE;
437 }
438 
439 /* returns a newly allocated pixbuf */
440 
util_pixbuf_from_root_window(gint x,gint y,gint w,gint h,gint get_all)441 GdkPixbuf *util_pixbuf_from_root_window(gint x, gint y, gint w, gint h, gint get_all)
442 {
443 	GdkPixbuf *pb;
444 
445 	if (w < 1 || h < 1 ) return NULL;
446 
447 	pb = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, w, h);
448 	util_pixbuf_fill_from_root_window(pb, x, y, get_all);
449 
450 	return pb;
451 }
452 
453 /*
454  *---------------------------------------------------------
455  * state saving / restoring stuff
456  *---------------------------------------------------------
457  */
458 
459 typedef struct _StateData StateData;
460 struct _StateData
461 {
462 	gchar *skin_name;
463 	GList *window_list;	/* list of active WindowStateData *'s */
464 };
465 
466 typedef struct _WindowStateData WindowStateData;
467 struct _WindowStateData
468 {
469 	gchar *id;
470 	gint active;	/* window is currently open */
471 	gint x;		/* root window coords */
472 	gint y;
473 	gint width;	/* window size */
474 	gint height;
475 };
476 
477 
478 static GList *slik_state_list = NULL;
479 
480 
ui_states_save(const gchar * path)481 gint ui_states_save(const gchar *path)
482 {
483 	FILE *f;
484 	gchar *pathl;
485 	GList *work;
486 
487 	ui_sync_states();
488 
489 	pathl = path_from_utf8(path);
490 	f = fopen(pathl, "w");
491 	g_free(pathl);
492 	if (!f)
493 		{
494 		printf(_("Unable to save skin state information to: %s\n"), path);
495 		return FALSE;
496 		}
497 
498 	fprintf(f, "#SLIK skin states\n");
499 	fprintf(f, "\n");
500 
501 	work = slik_state_list;
502 	while (work)
503 		{
504 		StateData *sd;
505 		GList *w;
506 
507 		sd = work->data;
508 		work = work->next;
509 
510 		fprintf(f, "[%s]\n", sd->skin_name);
511 
512 		w = sd->window_list;
513 		while (w)
514 			{
515 			WindowStateData *ws = w->data;
516 			w = w->next;
517 
518 			fprintf(f, "%s = [ %d ] %d, %d ( %d x %d )\n", ws->id,
519 				ws->active, ws->x, ws->y, ws->width, ws->height);
520 			}
521 
522 		fprintf(f, "\n");
523 		}
524 
525 	fprintf(f, "#end\n");
526 
527 	fclose(f);
528 
529 	return TRUE;
530 }
531 
ui_states_load(const gchar * path)532 gint ui_states_load(const gchar *path)
533 {
534 	FILE *f;
535 	gchar *key = NULL;
536 	gchar s_buf[1024];
537 	gchar *pathl;
538 
539 	pathl = path_from_utf8(path);
540 	f = fopen(pathl, "r");
541 	g_free(pathl);
542 	if (!f) return FALSE;
543 
544 	/* first line must start with correct comment to id file */
545 	if (!fgets(s_buf,1024,f) ||
546 	    strncmp(s_buf, "#SLIK skin state", 15) != 0)
547 		{
548 		fclose(f);
549 		return FALSE;
550 		}
551 
552 	while (fgets(s_buf, 1024, f))
553 		{
554 		if (s_buf[0]=='#') continue;
555 		if (s_buf[0]=='[')
556 			{
557 			gint c;
558 			gchar *ptr;
559 
560 			ptr = s_buf + 1;
561 			c = 0;
562 			while(ptr[c] != ']' && ptr[c] != '\n' && ptr[c] != '\0') c++;
563 
564 			g_free(key);
565 			key = g_strndup(ptr, c);
566 			}
567 		else if (key)
568 			{
569 			gchar window_id[256];
570 			gint active;
571 			gint x;
572 			gint y;
573 			gint w;
574 			gint h;
575 			if (sscanf(s_buf, "%255s = [ %d ] %d, %d ( %d x %d )", window_id, &active, &x, &y, &w, &h) == 6)
576 				{
577 				ui_state_set(key, window_id, x, y, w, h);
578 				ui_state_set_active(key, window_id, active);
579 				}
580 			}
581 		}
582 
583 	fclose(f);
584 
585 	g_free(key);
586 
587 	return TRUE;
588 }
589 
ui_state_find_skin(const gchar * skin_name)590 static StateData *ui_state_find_skin(const gchar *skin_name)
591 {
592 	GList *work;
593 
594 	if (!skin_name) skin_name = "default";
595 
596 	work = slik_state_list;
597 	while (work)
598 		{
599 		StateData *sd = work->data;
600 		work = work->next;
601 
602 		if (strcmp(skin_name, sd->skin_name) == 0) return sd;
603 		}
604 
605 	return NULL;
606 }
607 
ui_state_find_window(const gchar * window_id,StateData * sd)608 static WindowStateData *ui_state_find_window(const gchar *window_id, StateData *sd)
609 {
610 	GList *work;
611 
612 	if (!sd || !window_id) return NULL;
613 
614 	work = sd->window_list;
615 	while (work)
616 		{
617 		WindowStateData *ws = work->data;
618 		work = work->next;
619 
620 		if (strcmp(window_id, ws->id) == 0) return ws;
621 		}
622 
623 	return NULL;
624 }
625 
626 /* this creates things if they do not already exist */
ui_state_get_window(const gchar * skin_name,const gchar * window_id)627 static WindowStateData *ui_state_get_window(const gchar *skin_name, const gchar *window_id)
628 {
629 	StateData *sd;
630 	WindowStateData *ws;
631 
632 	if (!window_id) return NULL;
633 	if (!skin_name) skin_name = "default";
634 
635 	sd = ui_state_find_skin(skin_name);
636 
637 	if (!sd)
638 		{
639 		sd = g_new0(StateData, 1);
640 		sd->skin_name = g_strdup(skin_name);
641 		slik_state_list = g_list_append(slik_state_list, sd);
642 		}
643 
644 	ws = ui_state_find_window(window_id, sd);
645 
646 	if (!ws)
647 		{
648 		ws = g_new0(WindowStateData, 1);
649 		ws->id = g_strdup(window_id);
650 		sd->window_list = g_list_append(sd->window_list, ws);
651 		}
652 
653 	return ws;
654 }
655 
ui_state_set(const gchar * skin_name,const gchar * window_id,gint x,gint y,gint w,gint h)656 void ui_state_set(const gchar *skin_name, const gchar *window_id, gint x, gint y, gint w, gint h)
657 {
658 	WindowStateData *ws;
659 
660 	if (debug_mode) printf("set: %s %s\n", skin_name, window_id);
661 
662 	ws = ui_state_get_window(skin_name, window_id);
663 	if (!ws) return;
664 
665 	ws->x = x;
666 	ws->y = y;
667 	ws->width = w;
668 	ws->height = h;
669 }
670 
ui_state_get(const gchar * skin_name,const gchar * window_id,gint * x,gint * y,gint * w,gint * h)671 gint ui_state_get(const gchar *skin_name, const gchar *window_id, gint *x, gint *y, gint *w, gint *h)
672 {
673 	StateData *sd;
674 	WindowStateData *ws;
675 
676 	if (debug_mode) printf("get: %s %s\n", skin_name, window_id);
677 
678 	sd = ui_state_find_skin(skin_name);
679 	if (!sd) return FALSE;
680 
681 	ws = ui_state_find_window(window_id, sd);
682 	if (!ws) return FALSE;
683 
684 	if (x) *x = ws->x;
685 	if (y) *y = ws->y;
686 	if (w) *w = ws->width;
687 	if (h) *h = ws->height;
688 
689 	return TRUE;
690 }
691 
ui_state_set_active(const gchar * skin_name,const gchar * window_id,gint active)692 void ui_state_set_active(const gchar *skin_name, const gchar *window_id, gint active)
693 {
694 	WindowStateData *ws;
695 
696 	ws = ui_state_get_window(skin_name, window_id);
697 	if (!ws) return;
698 
699 	ws->active = active;
700 }
701 
ui_state_get_active(const gchar * skin_name,const gchar * window_id)702 gint ui_state_get_active(const gchar *skin_name, const gchar *window_id)
703 {
704 	StateData *sd;
705 	WindowStateData *ws;
706 
707 	sd = ui_state_find_skin(skin_name);
708 	if (!sd) return FALSE;
709 
710 	ws = ui_state_find_window(window_id, sd);
711 	if (!ws) return FALSE;
712 
713 	return ws->active;
714 }
715 
716 
717 
718