]> Dogcows Code - chaz/tint2/blob - src/util/common.c
start tint2conf work
[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 <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <unistd.h>
29
30 #include "common.h"
31 #include "../server.h"
32
33
34
35 void copy_file(const char *pathSrc, const char *pathDest)
36 {
37 FILE *fileSrc, *fileDest;
38 char line[100];
39 int nb;
40
41 fileSrc = fopen(pathSrc, "rb");
42 if (fileSrc == NULL) return;
43
44 fileDest = fopen(pathDest, "wb");
45 if (fileDest == NULL) return;
46
47 while ((nb = fread(line, 1, 100, fileSrc)) > 0)
48 if ( nb != fwrite(line, 1, nb, fileDest))
49 printf("Error while copying file %s to %s\n", pathSrc, pathDest);
50
51 fclose (fileDest);
52 fclose (fileSrc);
53 }
54
55
56 int parse_line (const char *line, char **key, char **value)
57 {
58 char *a, *b;
59
60 /* Skip useless lines */
61 if ((line[0] == '#') || (line[0] == '\n')) return 0;
62 if (!(a = strchr (line, '='))) return 0;
63
64 /* overwrite '=' with '\0' */
65 a[0] = '\0';
66 *key = strdup (line);
67 a++;
68
69 /* overwrite '\n' with '\0' if '\n' present */
70 if ((b = strchr (a, '\n'))) b[0] = '\0';
71
72 *value = strdup (a);
73
74 g_strstrip(*key);
75 g_strstrip(*value);
76 return 1;
77 }
78
79
80 void tint_exec(const char *command)
81 {
82 if (command) {
83 pid_t pid;
84 pid = fork();
85 if (pid == 0) {
86 // change for the fork the signal mask
87 // sigset_t sigset;
88 // sigprocmask(SIG_SETMASK, &sigset, 0);
89 // sigprocmask(SIG_UNBLOCK, &sigset, 0);
90 execl("/bin/sh", "/bin/sh", "-c", command, NULL);
91 _exit(0);
92 }
93 }
94 }
95
96
97 int hex_char_to_int (char c)
98 {
99 int r;
100
101 if (c >= '0' && c <= '9') r = c - '0';
102 else if (c >= 'a' && c <= 'f') r = c - 'a' + 10;
103 else if (c >= 'A' && c <= 'F') r = c - 'A' + 10;
104 else r = 0;
105
106 return r;
107 }
108
109
110 int hex_to_rgb (char *hex, int *r, int *g, int *b)
111 {
112 int len;
113
114 if (hex == NULL || hex[0] != '#') return (0);
115
116 len = strlen (hex);
117 if (len == 3 + 1) {
118 *r = hex_char_to_int (hex[1]);
119 *g = hex_char_to_int (hex[2]);
120 *b = hex_char_to_int (hex[3]);
121 }
122 else if (len == 6 + 1) {
123 *r = hex_char_to_int (hex[1]) * 16 + hex_char_to_int (hex[2]);
124 *g = hex_char_to_int (hex[3]) * 16 + hex_char_to_int (hex[4]);
125 *b = hex_char_to_int (hex[5]) * 16 + hex_char_to_int (hex[6]);
126 }
127 else if (len == 12 + 1) {
128 *r = hex_char_to_int (hex[1]) * 16 + hex_char_to_int (hex[2]);
129 *g = hex_char_to_int (hex[5]) * 16 + hex_char_to_int (hex[6]);
130 *b = hex_char_to_int (hex[9]) * 16 + hex_char_to_int (hex[10]);
131 }
132 else return 0;
133
134 return 1;
135 }
136
137
138 void get_color (char *hex, double *rgb)
139 {
140 int r, g, b;
141 hex_to_rgb (hex, &r, &g, &b);
142
143 rgb[0] = (r / 255.0);
144 rgb[1] = (g / 255.0);
145 rgb[2] = (b / 255.0);
146 }
147
148
149 void extract_values (const char *value, char **value1, char **value2, char **value3)
150 {
151 char *b=0, *c=0;
152
153 if (*value1) free (*value1);
154 if (*value2) free (*value2);
155 if (*value3) free (*value3);
156
157 if ((b = strchr (value, ' '))) {
158 b[0] = '\0';
159 b++;
160 }
161 else {
162 *value2 = 0;
163 *value3 = 0;
164 }
165 *value1 = strdup (value);
166 g_strstrip(*value1);
167
168 if (b) {
169 if ((c = strchr (b, ' '))) {
170 c[0] = '\0';
171 c++;
172 }
173 else {
174 c = 0;
175 *value3 = 0;
176 }
177 *value2 = strdup (b);
178 g_strstrip(*value2);
179 }
180
181 if (c) {
182 *value3 = strdup (c);
183 g_strstrip(*value3);
184 }
185 }
186
187
188 void adjust_asb(DATA32 *data, int w, int h, int alpha, float satur, float bright)
189 {
190 unsigned int x, y;
191 unsigned int a, r, g, b, argb;
192 unsigned long id;
193 int cmax, cmin;
194 float h2, f, p, q, t;
195 float hue, saturation, brightness;
196 float redc, greenc, bluec;
197
198 for(y = 0; y < h; y++) {
199 for(id = y * w, x = 0; x < w; x++, id++) {
200 argb = data[id];
201 a = (argb >> 24) & 0xff;
202 // transparent => nothing to do.
203 if (a == 0) continue;
204 r = (argb >> 16) & 0xff;
205 g = (argb >> 8) & 0xff;
206 b = (argb) & 0xff;
207
208 // convert RGB to HSB
209 cmax = (r > g) ? r : g;
210 if (b > cmax) cmax = b;
211 cmin = (r < g) ? r : g;
212 if (b < cmin) cmin = b;
213 brightness = ((float)cmax) / 255.0f;
214 if (cmax != 0)
215 saturation = ((float)(cmax - cmin)) / ((float)cmax);
216 else
217 saturation = 0;
218 if (saturation == 0)
219 hue = 0;
220 else {
221 redc = ((float)(cmax - r)) / ((float)(cmax - cmin));
222 greenc = ((float)(cmax - g)) / ((float)(cmax - cmin));
223 bluec = ((float)(cmax - b)) / ((float)(cmax - cmin));
224 if (r == cmax)
225 hue = bluec - greenc;
226 else if (g == cmax)
227 hue = 2.0f + redc - bluec;
228 else
229 hue = 4.0f + greenc - redc;
230 hue = hue / 6.0f;
231 if (hue < 0)
232 hue = hue + 1.0f;
233 }
234
235 // adjust
236 saturation += satur;
237 if (saturation < 0.0) saturation = 0.0;
238 if (saturation > 1.0) saturation = 1.0;
239 brightness += bright;
240 if (brightness < 0.0) brightness = 0.0;
241 if (brightness > 1.0) brightness = 1.0;
242 if (alpha != 100)
243 a = (a * alpha)/100;
244
245 // convert HSB to RGB
246 if (saturation == 0) {
247 r = g = b = (int)(brightness * 255.0f + 0.5f);
248 } else {
249 h2 = (hue - (int)hue) * 6.0f;
250 f = h2 - (int)(h2);
251 p = brightness * (1.0f - saturation);
252 q = brightness * (1.0f - saturation * f);
253 t = brightness * (1.0f - (saturation * (1.0f - f)));
254 switch ((int) h2) {
255 case 0:
256 r = (int)(brightness * 255.0f + 0.5f);
257 g = (int)(t * 255.0f + 0.5f);
258 b = (int)(p * 255.0f + 0.5f);
259 break;
260 case 1:
261 r = (int)(q * 255.0f + 0.5f);
262 g = (int)(brightness * 255.0f + 0.5f);
263 b = (int)(p * 255.0f + 0.5f);
264 break;
265 case 2:
266 r = (int)(p * 255.0f + 0.5f);
267 g = (int)(brightness * 255.0f + 0.5f);
268 b = (int)(t * 255.0f + 0.5f);
269 break;
270 case 3:
271 r = (int)(p * 255.0f + 0.5f);
272 g = (int)(q * 255.0f + 0.5f);
273 b = (int)(brightness * 255.0f + 0.5f);
274 break;
275 case 4:
276 r = (int)(t * 255.0f + 0.5f);
277 g = (int)(p * 255.0f + 0.5f);
278 b = (int)(brightness * 255.0f + 0.5f);
279 break;
280 case 5:
281 r = (int)(brightness * 255.0f + 0.5f);
282 g = (int)(p * 255.0f + 0.5f);
283 b = (int)(q * 255.0f + 0.5f);
284 break;
285 }
286 }
287
288 argb = a;
289 argb = (argb << 8) + r;
290 argb = (argb << 8) + g;
291 argb = (argb << 8) + b;
292 data[id] = argb;
293 }
294 }
295 }
296
297
298 void createHeuristicMask(DATA32* data, int w, int h)
299 {
300 // first we need to find the mask color, therefore we check all 4 edge pixel and take the color which
301 // appears most often (we only need to check three edges, the 4th is implicitly clear)
302 unsigned int topLeft = data[0], topRight = data[w-1], bottomLeft = data[w*h-w], bottomRight = data[w*h-1];
303 int max = (topLeft == topRight) + (topLeft == bottomLeft) + (topLeft == bottomRight);
304 int maskPos = 0;
305 if ( max < (topRight == topLeft) + (topRight == bottomLeft) + (topRight == bottomRight) ) {
306 max = (topRight == topLeft) + (topRight == bottomLeft) + (topRight == bottomRight);
307 maskPos = w-1;
308 }
309 if ( max < (bottomLeft == topRight) + (bottomLeft == topLeft) + (bottomLeft == bottomRight) )
310 maskPos = w*h-w;
311
312 // now mask out every pixel which has the same color as the edge pixels
313 unsigned char* udata = (unsigned char*)data;
314 unsigned char b = udata[4*maskPos];
315 unsigned char g = udata[4*maskPos+1];
316 unsigned char r = udata[4*maskPos+1];
317 int i;
318 for (i=0; i<h*w; ++i) {
319 if ( b-udata[0] == 0 && g-udata[1] == 0 && r-udata[2] == 0 )
320 udata[3] = 0;
321 udata += 4;
322 }
323 }
324
325
326 void render_image(Drawable d, int x, int y, int w, int h)
327 {
328 // in real_transparency mode imlib_render_image_on_drawable does not the right thing, because
329 // the operation is IMLIB_OP_COPY, but we would need IMLIB_OP_OVER (which does not exist)
330 // Therefore we have to do it with the XRender extension (i.e. copy what imlib is doing internally)
331 // But first we need to render the image onto itself with PictOpIn to adjust the colors to the alpha channel
332 Pixmap pmap_tmp = XCreatePixmap(server.dsp, server.root_win, w, h, 32);
333 imlib_context_set_drawable(pmap_tmp);
334 imlib_context_set_blend(0);
335 imlib_render_image_on_drawable(0, 0);
336 Picture pict_image = XRenderCreatePicture(server.dsp, pmap_tmp, XRenderFindStandardFormat(server.dsp, PictStandardARGB32), 0, 0);
337 Picture pict_drawable = XRenderCreatePicture(server.dsp, d, XRenderFindVisualFormat(server.dsp, server.visual), 0, 0);
338 XRenderComposite(server.dsp, PictOpIn, pict_image, None, pict_image, 0, 0, 0, 0, 0, 0, w, h);
339 XRenderComposite(server.dsp, PictOpOver, pict_image, None, pict_drawable, 0, 0, 0, 0, x, y, w, h);
340 imlib_context_set_blend(1);
341 XFreePixmap(server.dsp, pmap_tmp);
342 XRenderFreePicture(server.dsp, pict_image);
343 XRenderFreePicture(server.dsp, pict_drawable);
344 }
This page took 0.047111 seconds and 4 git commands to generate.