]> Dogcows Code - chaz/tint2/blob - src/util/common.c
launcher_apps_dir-v2.patch
[chaz/tint2] / src / util / common.c
1 /**************************************************************************
2 *
3 * Tint2 : common windows function
4 *
5 * Copyright (C) 2007 Pål Staurland (staura@gmail.com)
6 * Modified (C) 2008 thierry lorthiois (lorthiois@bbsoft.fr) from Omega distribution
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License version 2
10 * as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 **************************************************************************/
20
21 #include <X11/Xlib.h>
22 #include <X11/Xutil.h>
23 #include <X11/Xatom.h>
24 #include <X11/extensions/Xrender.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <unistd.h>
31 #include <fnmatch.h>
32
33 #include "common.h"
34 #include "../server.h"
35
36
37
38 void copy_file(const char *pathSrc, const char *pathDest)
39 {
40 FILE *fileSrc, *fileDest;
41 char line[100];
42 int nb;
43
44 fileSrc = fopen(pathSrc, "rb");
45 if (fileSrc == NULL) return;
46
47 fileDest = fopen(pathDest, "wb");
48 if (fileDest == NULL) return;
49
50 while ((nb = fread(line, 1, 100, fileSrc)) > 0)
51 if ( nb != fwrite(line, 1, nb, fileDest))
52 printf("Error while copying file %s to %s\n", pathSrc, pathDest);
53
54 fclose (fileDest);
55 fclose (fileSrc);
56 }
57
58
59 int parse_line (const char *line, char **key, char **value)
60 {
61 char *a, *b;
62
63 /* Skip useless lines */
64 if ((line[0] == '#') || (line[0] == '\n')) return 0;
65 if (!(a = strchr (line, '='))) return 0;
66
67 /* overwrite '=' with '\0' */
68 a[0] = '\0';
69 *key = strdup (line);
70 a++;
71
72 /* overwrite '\n' with '\0' if '\n' present */
73 if ((b = strchr (a, '\n'))) b[0] = '\0';
74
75 *value = strdup (a);
76
77 g_strstrip(*key);
78 g_strstrip(*value);
79 return 1;
80 }
81
82
83 void tint_exec(const char *command)
84 {
85 if (command) {
86 pid_t pid;
87 pid = fork();
88 if (pid == 0) {
89 // change for the fork the signal mask
90 // sigset_t sigset;
91 // sigprocmask(SIG_SETMASK, &sigset, 0);
92 // sigprocmask(SIG_UNBLOCK, &sigset, 0);
93 execl("/bin/sh", "/bin/sh", "-c", command, NULL);
94 _exit(0);
95 }
96 }
97 }
98
99
100 int hex_char_to_int (char c)
101 {
102 int r;
103
104 if (c >= '0' && c <= '9') r = c - '0';
105 else if (c >= 'a' && c <= 'f') r = c - 'a' + 10;
106 else if (c >= 'A' && c <= 'F') r = c - 'A' + 10;
107 else r = 0;
108
109 return r;
110 }
111
112
113 int hex_to_rgb (char *hex, int *r, int *g, int *b)
114 {
115 int len;
116
117 if (hex == NULL || hex[0] != '#') return (0);
118
119 len = strlen (hex);
120 if (len == 3 + 1) {
121 *r = hex_char_to_int (hex[1]);
122 *g = hex_char_to_int (hex[2]);
123 *b = hex_char_to_int (hex[3]);
124 }
125 else if (len == 6 + 1) {
126 *r = hex_char_to_int (hex[1]) * 16 + hex_char_to_int (hex[2]);
127 *g = hex_char_to_int (hex[3]) * 16 + hex_char_to_int (hex[4]);
128 *b = hex_char_to_int (hex[5]) * 16 + hex_char_to_int (hex[6]);
129 }
130 else if (len == 12 + 1) {
131 *r = hex_char_to_int (hex[1]) * 16 + hex_char_to_int (hex[2]);
132 *g = hex_char_to_int (hex[5]) * 16 + hex_char_to_int (hex[6]);
133 *b = hex_char_to_int (hex[9]) * 16 + hex_char_to_int (hex[10]);
134 }
135 else return 0;
136
137 return 1;
138 }
139
140
141 void get_color (char *hex, double *rgb)
142 {
143 int r, g, b;
144 hex_to_rgb (hex, &r, &g, &b);
145
146 rgb[0] = (r / 255.0);
147 rgb[1] = (g / 255.0);
148 rgb[2] = (b / 255.0);
149 }
150
151
152 void extract_values (const char *value, char **value1, char **value2, char **value3)
153 {
154 char *b=0, *c=0;
155
156 if (*value1) free (*value1);
157 if (*value2) free (*value2);
158 if (*value3) free (*value3);
159
160 if ((b = strchr (value, ' '))) {
161 b[0] = '\0';
162 b++;
163 }
164 else {
165 *value2 = 0;
166 *value3 = 0;
167 }
168 *value1 = strdup (value);
169 g_strstrip(*value1);
170
171 if (b) {
172 if ((c = strchr (b, ' '))) {
173 c[0] = '\0';
174 c++;
175 }
176 else {
177 c = 0;
178 *value3 = 0;
179 }
180 *value2 = strdup (b);
181 g_strstrip(*value2);
182 }
183
184 if (c) {
185 *value3 = strdup (c);
186 g_strstrip(*value3);
187 }
188 }
189
190
191 void adjust_asb(DATA32 *data, int w, int h, int alpha, float satur, float bright)
192 {
193 unsigned int x, y;
194 unsigned int a, r, g, b, argb;
195 unsigned long id;
196 int cmax, cmin;
197 float h2, f, p, q, t;
198 float hue, saturation, brightness;
199 float redc, greenc, bluec;
200
201 for(y = 0; y < h; y++) {
202 for(id = y * w, x = 0; x < w; x++, id++) {
203 argb = data[id];
204 a = (argb >> 24) & 0xff;
205 // transparent => nothing to do.
206 if (a == 0) continue;
207 r = (argb >> 16) & 0xff;
208 g = (argb >> 8) & 0xff;
209 b = (argb) & 0xff;
210
211 // convert RGB to HSB
212 cmax = (r > g) ? r : g;
213 if (b > cmax) cmax = b;
214 cmin = (r < g) ? r : g;
215 if (b < cmin) cmin = b;
216 brightness = ((float)cmax) / 255.0f;
217 if (cmax != 0)
218 saturation = ((float)(cmax - cmin)) / ((float)cmax);
219 else
220 saturation = 0;
221 if (saturation == 0)
222 hue = 0;
223 else {
224 redc = ((float)(cmax - r)) / ((float)(cmax - cmin));
225 greenc = ((float)(cmax - g)) / ((float)(cmax - cmin));
226 bluec = ((float)(cmax - b)) / ((float)(cmax - cmin));
227 if (r == cmax)
228 hue = bluec - greenc;
229 else if (g == cmax)
230 hue = 2.0f + redc - bluec;
231 else
232 hue = 4.0f + greenc - redc;
233 hue = hue / 6.0f;
234 if (hue < 0)
235 hue = hue + 1.0f;
236 }
237
238 // adjust
239 saturation += satur;
240 if (saturation < 0.0) saturation = 0.0;
241 if (saturation > 1.0) saturation = 1.0;
242 brightness += bright;
243 if (brightness < 0.0) brightness = 0.0;
244 if (brightness > 1.0) brightness = 1.0;
245 if (alpha != 100)
246 a = (a * alpha)/100;
247
248 // convert HSB to RGB
249 if (saturation == 0) {
250 r = g = b = (int)(brightness * 255.0f + 0.5f);
251 } else {
252 h2 = (hue - (int)hue) * 6.0f;
253 f = h2 - (int)(h2);
254 p = brightness * (1.0f - saturation);
255 q = brightness * (1.0f - saturation * f);
256 t = brightness * (1.0f - (saturation * (1.0f - f)));
257 switch ((int) h2) {
258 case 0:
259 r = (int)(brightness * 255.0f + 0.5f);
260 g = (int)(t * 255.0f + 0.5f);
261 b = (int)(p * 255.0f + 0.5f);
262 break;
263 case 1:
264 r = (int)(q * 255.0f + 0.5f);
265 g = (int)(brightness * 255.0f + 0.5f);
266 b = (int)(p * 255.0f + 0.5f);
267 break;
268 case 2:
269 r = (int)(p * 255.0f + 0.5f);
270 g = (int)(brightness * 255.0f + 0.5f);
271 b = (int)(t * 255.0f + 0.5f);
272 break;
273 case 3:
274 r = (int)(p * 255.0f + 0.5f);
275 g = (int)(q * 255.0f + 0.5f);
276 b = (int)(brightness * 255.0f + 0.5f);
277 break;
278 case 4:
279 r = (int)(t * 255.0f + 0.5f);
280 g = (int)(p * 255.0f + 0.5f);
281 b = (int)(brightness * 255.0f + 0.5f);
282 break;
283 case 5:
284 r = (int)(brightness * 255.0f + 0.5f);
285 g = (int)(p * 255.0f + 0.5f);
286 b = (int)(q * 255.0f + 0.5f);
287 break;
288 }
289 }
290
291 argb = a;
292 argb = (argb << 8) + r;
293 argb = (argb << 8) + g;
294 argb = (argb << 8) + b;
295 data[id] = argb;
296 }
297 }
298 }
299
300
301 void createHeuristicMask(DATA32* data, int w, int h)
302 {
303 // first we need to find the mask color, therefore we check all 4 edge pixel and take the color which
304 // appears most often (we only need to check three edges, the 4th is implicitly clear)
305 unsigned int topLeft = data[0], topRight = data[w-1], bottomLeft = data[w*h-w], bottomRight = data[w*h-1];
306 int max = (topLeft == topRight) + (topLeft == bottomLeft) + (topLeft == bottomRight);
307 int maskPos = 0;
308 if ( max < (topRight == topLeft) + (topRight == bottomLeft) + (topRight == bottomRight) ) {
309 max = (topRight == topLeft) + (topRight == bottomLeft) + (topRight == bottomRight);
310 maskPos = w-1;
311 }
312 if ( max < (bottomLeft == topRight) + (bottomLeft == topLeft) + (bottomLeft == bottomRight) )
313 maskPos = w*h-w;
314
315 // now mask out every pixel which has the same color as the edge pixels
316 unsigned char* udata = (unsigned char*)data;
317 unsigned char b = udata[4*maskPos];
318 unsigned char g = udata[4*maskPos+1];
319 unsigned char r = udata[4*maskPos+1];
320 int i;
321 for (i=0; i<h*w; ++i) {
322 if ( b-udata[0] == 0 && g-udata[1] == 0 && r-udata[2] == 0 )
323 udata[3] = 0;
324 udata += 4;
325 }
326 }
327
328
329 void render_image(Drawable d, int x, int y, int w, int h)
330 {
331 // in real_transparency mode imlib_render_image_on_drawable does not the right thing, because
332 // the operation is IMLIB_OP_COPY, but we would need IMLIB_OP_OVER (which does not exist)
333 // Therefore we have to do it with the XRender extension (i.e. copy what imlib is doing internally)
334 // But first we need to render the image onto itself with PictOpIn to adjust the colors to the alpha channel
335 Pixmap pmap_tmp = XCreatePixmap(server.dsp, server.root_win, w, h, 32);
336 imlib_context_set_drawable(pmap_tmp);
337 imlib_context_set_blend(0);
338 imlib_render_image_on_drawable(0, 0);
339 Picture pict_image = XRenderCreatePicture(server.dsp, pmap_tmp, XRenderFindStandardFormat(server.dsp, PictStandardARGB32), 0, 0);
340 Picture pict_drawable = XRenderCreatePicture(server.dsp, d, XRenderFindVisualFormat(server.dsp, server.visual), 0, 0);
341 XRenderComposite(server.dsp, PictOpIn, pict_image, None, pict_image, 0, 0, 0, 0, 0, 0, w, h);
342 XRenderComposite(server.dsp, PictOpOver, pict_image, None, pict_drawable, 0, 0, 0, 0, x, y, w, h);
343 imlib_context_set_blend(1);
344 XFreePixmap(server.dsp, pmap_tmp);
345 XRenderFreePicture(server.dsp, pict_image);
346 XRenderFreePicture(server.dsp, pict_drawable);
347 }
348
349 /**
350 * @brief
351 * Scan given directory for files which are meet the given mask and sort them alphabetically
352 *
353 * @param path - directory path
354 * @param mask - filename mask
355 *
356 * @return files list
357 */
358 GList *dir_scan_alpha(const char *path, const char *mask)
359 {
360 GError *err = NULL;
361 GList *list = NULL;
362 const char *n;
363 gchar *fn;
364 struct stat st;
365
366 GDir *dir = g_dir_open(path, 0, &err);
367
368 if (!dir) {
369 fprintf(stderr, "%s\n", err->message);
370 g_error_free(err);
371 } else {
372 // Enumerate files
373 while ((n = g_dir_read_name(dir))) {
374 if (!fnmatch(mask, n, FNM_PATHNAME)) {
375 fn = g_build_filename(path, n, NULL);
376
377 if (stat((char *)fn, &st) < 0)
378 continue;
379
380 // Only regular files
381 if (S_ISREG(st.st_mode))
382 list = g_list_prepend(list, (gpointer)fn);
383 }
384 }
385
386 list = g_list_sort (list, (GCompareFunc) &strcmp);
387 }
388
389 return list;
390 }
This page took 0.047133 seconds and 4 git commands to generate.