]>
Commit | Line | Data |
---|---|---|
7c5c7a87 RW |
1 | diff -urN WindowMaker-0.91.0/src/wmspec.c WindowMaker-0.91.0.patch/src/wmspec.c |
2 | --- WindowMaker-0.91.0/src/wmspec.c 2004-10-24 21:36:15.000000000 +0200 | |
3 | +++ WindowMaker-0.91.0.patch/src/wmspec.c 2005-01-12 23:31:41.833101648 +0100 | |
4 | @@ -369,57 +369,108 @@ | |
5 | return -1; | |
6 | } | |
7 | ||
8 | +/* | |
9 | + * Find the best icon to be used by Window Maker for appicon/miniwindows. | |
10 | + * Currently the algorithm is to take the image with the size closest | |
11 | + * to icon_size x icon_size, but never bigger than that. | |
12 | + * | |
13 | + * This algorithm is very poorly implemented and needs to be redone (it can | |
14 | + * easily select images with very large widths and very small heights over | |
15 | + * square images, if the area of the former is closer to the desired one). | |
16 | + * | |
17 | + * The logic can also be changed to accept bigger images and scale them down. | |
18 | + */ | |
19 | +static CARD32* | |
20 | +findBestIcon(CARD32 *data, unsigned long items) | |
21 | +{ | |
22 | + long size, wanted, d, distance; | |
23 | + unsigned long i; | |
24 | + CARD32 *icon; | |
25 | + | |
26 | + /* better use only 75% of icon_size. For 64x64 this means 48x48 | |
27 | + * This leaves room around the icon for the miniwindow title and | |
28 | + * results in better overall aesthetics -Dan */ | |
29 | + wanted = wPreferences.icon_size * wPreferences.icon_size; | |
30 | + | |
31 | + for (icon=NULL, distance=LONG_MAX, i=0L; i<items-1; ) { | |
32 | + size = data[i] * data[i+1]; | |
33 | + if (size==0) | |
34 | + break; | |
35 | + d = wanted - size; | |
36 | + if (d>=0 && d<=distance && (i+size+2)<=items) { | |
37 | + distance = d; | |
38 | + icon = &data[i]; | |
39 | + } | |
40 | + i += size+2; | |
41 | + } | |
42 | + | |
43 | + return icon; | |
44 | +} | |
45 | + | |
46 | + | |
47 | +static RImage* | |
48 | +makeRImageFromARGBData(CARD32 *data) | |
49 | +{ | |
50 | + int size, width, height, i; | |
51 | + RImage *image; | |
52 | + unsigned char *imgdata; | |
53 | + CARD32 pixel; | |
54 | + | |
55 | + width = data[0]; | |
56 | + height = data[1]; | |
57 | + size = width * height; | |
58 | + | |
59 | + if (size == 0) | |
60 | + return NULL; | |
61 | + | |
62 | + image = RCreateImage(width, height, True); | |
63 | + | |
64 | + for (imgdata=image->data, i=2; i<size+2; i++, imgdata+=4) { | |
65 | + pixel = data[i]; | |
66 | + imgdata[3] = (pixel >> 24) & 0xff; /* A */ | |
67 | + imgdata[0] = (pixel >> 16) & 0xff; /* R */ | |
68 | + imgdata[1] = (pixel >> 8) & 0xff; /* G */ | |
69 | + imgdata[2] = (pixel >> 0) & 0xff; /* B */ | |
70 | + } | |
71 | + | |
72 | + return image; | |
73 | +} | |
74 | + | |
75 | ||
76 | static void | |
77 | updateIconImage(WScreen *scr, WWindow *wwin) | |
78 | { | |
79 | - Atom actual_type_return; | |
80 | - int actual_format_return; | |
81 | - unsigned long nitems_return, bytes_after_return; | |
82 | - unsigned char *prop_return; | |
83 | - int rc = XGetWindowProperty(dpy, wwin->client_win, net_wm_icon, 0, ~0, False, | |
84 | - XA_CARDINAL, &actual_type_return, &actual_format_return, | |
85 | - &nitems_return, &bytes_after_return, &prop_return); | |
86 | - | |
87 | - if (rc==Success && prop_return) { | |
88 | - unsigned int *data = (unsigned int *)prop_return; | |
89 | - unsigned int pos = 0, len = 0; | |
90 | - unsigned int best_pos = 0, best_tmp = ~0; | |
91 | - extern WPreferences wPreferences; | |
92 | - unsigned int pref_size = wPreferences.icon_size; | |
93 | - unsigned int pref_sq = pref_size*pref_size; | |
94 | - char *src, *dst; | |
95 | - RImage *new_rimage; | |
96 | - | |
97 | - do { | |
98 | - len = data[pos+0]*data[pos+1]; | |
99 | - unsigned int tmp = pref_sq-len; | |
100 | - if (tmp < best_tmp && tmp > 0) { | |
101 | - best_tmp = tmp; | |
102 | - best_pos = pos; | |
103 | - } | |
104 | - pos += 2+len; | |
105 | - } while (pos < nitems_return && len != 0); | |
106 | + CARD32 *property, *data; | |
107 | + unsigned long items, rest; | |
108 | + Atom type; | |
109 | + int format; | |
110 | + RImage *image; | |
111 | + | |
112 | + if (XGetWindowProperty(dpy, wwin->client_win, net_wm_icon, 0L, LONG_MAX, | |
113 | + False, XA_CARDINAL, &type, &format, &items, &rest, | |
114 | + (unsigned char**)&property)!=Success || !property) { | |
115 | + return; | |
116 | + } | |
117 | ||
118 | - new_rimage = RCreateImage(data[best_pos+0], data[best_pos+1], True); | |
119 | - len = data[best_pos+0] * data[best_pos+1]; | |
120 | - src = (char*)&data[best_pos+2]; | |
121 | - dst = new_rimage->data; | |
122 | - for (pos=0; pos<len; ++pos, src+=4, dst+=4) { | |
123 | - dst[0] = src[2]; /* R */ | |
124 | - dst[1] = src[1]; /* G */ | |
125 | - dst[2] = src[0]; /* B */ | |
126 | - dst[3] = src[3]; /* A */ | |
127 | + if (type!=XA_CARDINAL || format!=32 || items<2) { | |
128 | + XFree(property); | |
129 | + return; | |
130 | } | |
131 | ||
132 | - if (new_rimage) { | |
133 | + data = findBestIcon(property, items); | |
134 | + if (!data) { | |
135 | + XFree(property); | |
136 | + return; | |
137 | + } | |
138 | + | |
139 | + image = makeRImageFromARGBData(data); | |
140 | + | |
141 | + if (image) { | |
142 | if (wwin->net_icon_image) | |
143 | RReleaseImage(wwin->net_icon_image); | |
144 | - wwin->net_icon_image = new_rimage; | |
145 | + wwin->net_icon_image = image; | |
146 | } | |
147 | - | |
148 | - XFree(prop_return); | |
149 | - } | |
150 | + XFree(property); | |
151 | } | |
152 | ||
153 |