]> Dogcows Code - chaz/tint2/blob - src/util/common.c
545a6be6e29689b723c9846f444dbc364c9afa61
[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)
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
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 int hex_char_to_int (char c)
81 {
82 int r;
83
84 if (c >= '0' && c <= '9') r = c - '0';
85 else if (c >= 'a' && c <= 'f') r = c - 'a' + 10;
86 else if (c >= 'A' && c <= 'F') r = c - 'A' + 10;
87 else r = 0;
88
89 return r;
90 }
91
92
93 int hex_to_rgb (char *hex, int *r, int *g, int *b)
94 {
95 int len;
96
97 if (hex == NULL || hex[0] != '#') return (0);
98
99 len = strlen (hex);
100 if (len == 3 + 1) {
101 *r = hex_char_to_int (hex[1]);
102 *g = hex_char_to_int (hex[2]);
103 *b = hex_char_to_int (hex[3]);
104 }
105 else if (len == 6 + 1) {
106 *r = hex_char_to_int (hex[1]) * 16 + hex_char_to_int (hex[2]);
107 *g = hex_char_to_int (hex[3]) * 16 + hex_char_to_int (hex[4]);
108 *b = hex_char_to_int (hex[5]) * 16 + hex_char_to_int (hex[6]);
109 }
110 else if (len == 12 + 1) {
111 *r = hex_char_to_int (hex[1]) * 16 + hex_char_to_int (hex[2]);
112 *g = hex_char_to_int (hex[5]) * 16 + hex_char_to_int (hex[6]);
113 *b = hex_char_to_int (hex[9]) * 16 + hex_char_to_int (hex[10]);
114 }
115 else return 0;
116
117 return 1;
118 }
119
120
121 void get_color (char *hex, double *rgb)
122 {
123 int r, g, b;
124 hex_to_rgb (hex, &r, &g, &b);
125
126 rgb[0] = (r / 255.0);
127 rgb[1] = (g / 255.0);
128 rgb[2] = (b / 255.0);
129 }
130
131
132 void adjust_asb(DATA32 *data, int w, int h, int alpha, float satur, float bright)
133 {
134 unsigned int x, y;
135 unsigned int a, r, g, b, argb;
136 unsigned long id;
137 int cmax, cmin;
138 float h2, f, p, q, t;
139 float hue, saturation, brightness;
140 float redc, greenc, bluec;
141
142 for(y = 0; y < h; y++) {
143 for(id = y * w, x = 0; x < w; x++, id++) {
144 argb = data[id];
145 a = (argb >> 24) & 0xff;
146 // transparent => nothing to do.
147 if (a == 0) continue;
148 r = (argb >> 16) & 0xff;
149 g = (argb >> 8) & 0xff;
150 b = (argb) & 0xff;
151
152 // convert RGB to HSB
153 cmax = (r > g) ? r : g;
154 if (b > cmax) cmax = b;
155 cmin = (r < g) ? r : g;
156 if (b < cmin) cmin = b;
157 brightness = ((float)cmax) / 255.0f;
158 if (cmax != 0)
159 saturation = ((float)(cmax - cmin)) / ((float)cmax);
160 else
161 saturation = 0;
162 if (saturation == 0)
163 hue = 0;
164 else {
165 redc = ((float)(cmax - r)) / ((float)(cmax - cmin));
166 greenc = ((float)(cmax - g)) / ((float)(cmax - cmin));
167 bluec = ((float)(cmax - b)) / ((float)(cmax - cmin));
168 if (r == cmax)
169 hue = bluec - greenc;
170 else if (g == cmax)
171 hue = 2.0f + redc - bluec;
172 else
173 hue = 4.0f + greenc - redc;
174 hue = hue / 6.0f;
175 if (hue < 0)
176 hue = hue + 1.0f;
177 }
178
179 // adjust
180 saturation += satur;
181 if (saturation < 0.0) saturation = 0.0;
182 if (saturation > 1.0) saturation = 1.0;
183 brightness += bright;
184 if (brightness < 0.0) brightness = 0.0;
185 if (brightness > 1.0) brightness = 1.0;
186 if (alpha != 100)
187 a = (a * alpha)/100;
188
189 // convert HSB to RGB
190 if (saturation == 0) {
191 r = g = b = (int)(brightness * 255.0f + 0.5f);
192 } else {
193 h2 = (hue - (int)hue) * 6.0f;
194 f = h2 - (int)(h2);
195 p = brightness * (1.0f - saturation);
196 q = brightness * (1.0f - saturation * f);
197 t = brightness * (1.0f - (saturation * (1.0f - f)));
198 switch ((int) h2) {
199 case 0:
200 r = (int)(brightness * 255.0f + 0.5f);
201 g = (int)(t * 255.0f + 0.5f);
202 b = (int)(p * 255.0f + 0.5f);
203 break;
204 case 1:
205 r = (int)(q * 255.0f + 0.5f);
206 g = (int)(brightness * 255.0f + 0.5f);
207 b = (int)(p * 255.0f + 0.5f);
208 break;
209 case 2:
210 r = (int)(p * 255.0f + 0.5f);
211 g = (int)(brightness * 255.0f + 0.5f);
212 b = (int)(t * 255.0f + 0.5f);
213 break;
214 case 3:
215 r = (int)(p * 255.0f + 0.5f);
216 g = (int)(q * 255.0f + 0.5f);
217 b = (int)(brightness * 255.0f + 0.5f);
218 break;
219 case 4:
220 r = (int)(t * 255.0f + 0.5f);
221 g = (int)(p * 255.0f + 0.5f);
222 b = (int)(brightness * 255.0f + 0.5f);
223 break;
224 case 5:
225 r = (int)(brightness * 255.0f + 0.5f);
226 g = (int)(p * 255.0f + 0.5f);
227 b = (int)(q * 255.0f + 0.5f);
228 break;
229 }
230 }
231
232 argb = a;
233 argb = (argb << 8) + r;
234 argb = (argb << 8) + g;
235 argb = (argb << 8) + b;
236 data[id] = argb;
237 }
238 }
239 }
240
241
242 void createHeuristicMask(DATA32* data, int w, int h)
243 {
244 // first we need to find the mask color, therefore we check all 4 edge pixel and take the color which
245 // appears most often (we only need to check three edges, the 4th is implicitly clear)
246 unsigned int topLeft = data[0], topRight = data[w-1], bottomLeft = data[w*h-w], bottomRight = data[w*h-1];
247 int max = (topLeft == topRight) + (topLeft == bottomLeft) + (topLeft == bottomRight);
248 int maskPos = 0;
249 if ( max < (topRight == topLeft) + (topRight == bottomLeft) + (topRight == bottomRight) ) {
250 max = (topRight == topLeft) + (topRight == bottomLeft) + (topRight == bottomRight);
251 maskPos = w-1;
252 }
253 if ( max < (bottomLeft == topRight) + (bottomLeft == topLeft) + (bottomLeft == bottomRight) )
254 maskPos = w*h-w;
255
256 // now mask out every pixel which has the same color as the edge pixels
257 unsigned char* udata = (unsigned char*)data;
258 unsigned char b = udata[4*maskPos];
259 unsigned char g = udata[4*maskPos+1];
260 unsigned char r = udata[4*maskPos+1];
261 int i;
262 for (i=0; i<h*w; ++i) {
263 if ( b-udata[0] == 0 && g-udata[1] == 0 && r-udata[2] == 0 )
264 udata[3] = 0;
265 udata += 4;
266 }
267 }
268
269
270 void render_image(Drawable d, int x, int y, int w, int h)
271 {
272 // in real_transparency mode imlib_render_image_on_drawable does not the right thing, because
273 // the operation is IMLIB_OP_COPY, but we would need IMLIB_OP_OVER (which does not exist)
274 // Therefore we have to do it with the XRender extension (i.e. copy what imlib is doing internally)
275 // But first we need to render the image onto itself with PictOpIn to adjust the colors to the alpha channel
276 Pixmap pmap_tmp = XCreatePixmap(server.dsp, server.root_win, w, h, 32);
277 imlib_context_set_drawable(pmap_tmp);
278 imlib_context_set_blend(0);
279 imlib_render_image_on_drawable(0, 0);
280 Picture pict_image = XRenderCreatePicture(server.dsp, pmap_tmp, XRenderFindStandardFormat(server.dsp, PictStandardARGB32), 0, 0);
281 Picture pict_drawable = XRenderCreatePicture(server.dsp, d, XRenderFindVisualFormat(server.dsp, server.visual), 0, 0);
282 XRenderComposite(server.dsp, PictOpIn, pict_image, None, pict_image, 0, 0, 0, 0, 0, 0, w, h);
283 XRenderComposite(server.dsp, PictOpOver, pict_image, None, pict_drawable, 0, 0, 0, 0, x, y, w, h);
284 imlib_context_set_blend(1);
285 XFreePixmap(server.dsp, pmap_tmp);
286 XRenderFreePicture(server.dsp, pict_image);
287 XRenderFreePicture(server.dsp, pict_drawable);
288 }
This page took 0.053349 seconds and 3 git commands to generate.