]> icculus.org git repositories - mikachu/rspanel.git/blob - icon.c
better with bevel2
[mikachu/rspanel.git] / icon.c
1 #include "icon.h"
2 #include "xprop.h"
3 #include "rspanel.h"
4
5 icon* icon_update(screen *sc, Window win, gint *nicons)
6 {
7     /* these bits are borrowed from openbox' client.c::client_update_icons */
8     unsigned int num;
9     RrPixel32 *data;
10     unsigned int w, h, i, j;
11     icon *ret = NULL;
12
13     *nicons = 0;
14
15     data = xprop_get_data(sc, win, _NET_WM_ICON, XA_CARDINAL, &num);
16     if (num) {
17         /* figure out how many valid icons are in here */
18         i = 0;
19         while (num - i > 2) {
20             w = data[i++];
21             h = data[i++];
22             i += w * h;
23             if (i > num || w*h == 0) break;
24             ++(*nicons);
25         }
26
27         ret = calloc(*nicons, sizeof(icon));
28     
29         /* store the icons */
30         i = 0;
31         for (j = 0; j < *nicons; ++j) {
32             guint x, y, t;
33
34             w = ret[j].width = data[i++];
35             h = ret[j].height = data[i++];
36
37             if (w*h == 0) continue;
38
39             ret[j].data = g_new(RrPixel32, w * h);
40             for (x = 0, y = 0, t = 0; t < w * h; ++t, ++x, ++i) {
41                 if (x >= w) {
42                     x = 0;
43                     ++y;
44                 }
45                 ret[j].data[t] =
46                     (((data[i] >> 24) & 0xff) << RrDefaultAlphaOffset) +
47                     (((data[i] >> 16) & 0xff) << RrDefaultRedOffset) +
48                     (((data[i] >> 8) & 0xff) << RrDefaultGreenOffset) +
49                     (((data[i] >> 0) & 0xff) << RrDefaultBlueOffset);
50             }
51             g_assert(i <= num);
52         }
53
54         g_free(data);
55     } else {
56         XWMHints *hints;
57
58         if ((hints = XGetWMHints(sc->dd, win))) {
59             if (hints->flags & IconPixmapHint) {
60                 *nicons = 1;
61                 ret = calloc(*nicons, sizeof(icon));
62 //                xerror_set_ignore(TRUE);
63                 if (!RrPixmapToRGBA(sc->rr,
64                                     hints->icon_pixmap,
65                                     (hints->flags & IconMaskHint ?
66                                      hints->icon_mask : None),
67                                     &ret[0].width,
68                                     &ret[0].height,
69                                     &ret[0].data))
70                 {
71                     free(ret);
72                     ret = NULL;
73                     *nicons = 0;
74                 }
75 //                xerror_set_ignore(FALSE);
76             }
77             XFree(hints);
78         }
79     }    
80     return ret;
81 }
82
83 const icon* icon_get_best(icon list[], int num, int w, int h)
84 {
85     static icon deficon;
86     guint i;
87     gulong min_diff, min_i;
88
89     if (num < 1) return NULL;
90
91     min_diff = ABS(list[0].width - w) + ABS(list[0].height - h);
92     min_i = 0;
93
94     for (i = 1; i < num; ++i) {
95         gulong diff;
96
97         diff = ABS(list[i].width - w) + ABS(list[i].height - h);
98         if (diff < min_diff) {
99             min_diff = diff;
100             min_i = i;
101         }
102     }
103     return &list[min_i];
104 }