1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif /* ifdef HAVE_CONFIG_H */
4
5 #include <stdlib.h>
6
7 #include "ecore_x_private.h"
8
9 EAPI Eina_Bool
ecore_x_cursor_color_supported_get(void)10 ecore_x_cursor_color_supported_get(void)
11 {
12 return _ecore_x_xcursor;
13 }
14
15 EAPI Ecore_X_Cursor
ecore_x_cursor_new(Ecore_X_Window win,int * pixels,int w,int h,int hot_x,int hot_y)16 ecore_x_cursor_new(Ecore_X_Window win,
17 int *pixels,
18 int w,
19 int h,
20 int hot_x,
21 int hot_y)
22 {
23 EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, 0);
24 #ifdef ECORE_XCURSOR
25 LOGFN;
26
27 if (_ecore_x_xcursor)
28 {
29 Cursor c;
30 XcursorImage *xci;
31
32 xci = XcursorImageCreate(w, h);
33 if (_ecore_xlib_sync) ecore_x_sync();
34 if (xci)
35 {
36 int i;
37
38 xci->xhot = hot_x;
39 xci->yhot = hot_y;
40 xci->delay = 0;
41 for (i = 0; i < (w * h); i++)
42 {
43 // int r, g, b, a;
44 //
45 // a = (pixels[i] >> 24) & 0xff;
46 // r = (((pixels[i] >> 16) & 0xff) * a) / 0xff;
47 // g = (((pixels[i] >> 8 ) & 0xff) * a) / 0xff;
48 // b = (((pixels[i] ) & 0xff) * a) / 0xff;
49 xci->pixels[i] = pixels[i];
50 // (a << 24) | (r << 16) | (g << 8) | (b);
51 }
52 c = XcursorImageLoadCursor(_ecore_x_disp, xci);
53 if (_ecore_xlib_sync) ecore_x_sync();
54 XcursorImageDestroy(xci);
55 return c;
56 }
57 }
58 else
59 #endif /* ifdef ECORE_XCURSOR */
60 {
61 XColor c1, c2;
62 Cursor c;
63 Pixmap pmap, mask;
64 GC gc;
65 XGCValues gcv;
66 XImage *xim;
67 unsigned int *pix;
68 int fr, fg, fb, br, bg, bb;
69 int brightest = 0;
70 int darkest = 255 * 3;
71 int x, y;
72 const int dither[2][2] =
73 {
74 {0, 2},
75 {3, 1}
76 };
77
78 pmap = XCreatePixmap(_ecore_x_disp, win, w, h, 1);
79 if (_ecore_xlib_sync) ecore_x_sync();
80 mask = XCreatePixmap(_ecore_x_disp, win, w, h, 1);
81 if (_ecore_xlib_sync) ecore_x_sync();
82 xim = XCreateImage(_ecore_x_disp,
83 DefaultVisual(_ecore_x_disp, 0),
84 1, ZPixmap, 0, NULL, w, h, 32, 0);
85 if (_ecore_xlib_sync) ecore_x_sync();
86 xim->data = malloc(xim->bytes_per_line * xim->height);
87
88 fr = 0x00; fg = 0x00; fb = 0x00;
89 br = 0xff; bg = 0xff; bb = 0xff;
90 pix = (unsigned int *)pixels;
91 for (y = 0; y < h; y++)
92 {
93 for (x = 0; x < w; x++)
94 {
95 int r, g, b, a;
96
97 a = (pix[0] >> 24) & 0xff;
98 r = (pix[0] >> 16) & 0xff;
99 g = (pix[0] >> 8) & 0xff;
100 b = (pix[0]) & 0xff;
101 if (a > 0)
102 {
103 if ((r + g + b) > brightest)
104 {
105 brightest = r + g + b;
106 br = r;
107 bg = g;
108 bb = b;
109 }
110
111 if ((r + g + b) < darkest)
112 {
113 darkest = r + g + b;
114 fr = r;
115 fg = g;
116 fb = b;
117 }
118 }
119
120 pix++;
121 }
122 }
123
124 pix = (unsigned int *)pixels;
125 for (y = 0; y < h; y++)
126 {
127 for (x = 0; x < w; x++)
128 {
129 int v;
130 int r, g, b;
131 int d1, d2;
132
133 r = (pix[0] >> 16) & 0xff;
134 g = (pix[0] >> 8) & 0xff;
135 b = (pix[0]) & 0xff;
136 d1 =
137 ((r - fr) * (r - fr)) +
138 ((g - fg) * (g - fg)) +
139 ((b - fb) * (b - fb));
140 d2 =
141 ((r - br) * (r - br)) +
142 ((g - bg) * (g - bg)) +
143 ((b - bb) * (b - bb));
144 if (d1 + d2)
145 {
146 v = (((d2 * 255) / (d1 + d2)) * 5) / 256;
147 if (v > dither[x & 0x1][y & 0x1])
148 v = 1;
149 else
150 v = 0;
151 }
152 else
153 v = 0;
154
155 XPutPixel(xim, x, y, v);
156 if (_ecore_xlib_sync) ecore_x_sync();
157 pix++;
158 }
159 }
160 gc = XCreateGC(_ecore_x_disp, pmap, 0, &gcv);
161 if (_ecore_xlib_sync) ecore_x_sync();
162 XPutImage(_ecore_x_disp, pmap, gc, xim, 0, 0, 0, 0, w, h);
163 if (_ecore_xlib_sync) ecore_x_sync();
164 XFreeGC(_ecore_x_disp, gc);
165
166 pix = (unsigned int *)pixels;
167 for (y = 0; y < h; y++)
168 {
169 for (x = 0; x < w; x++)
170 {
171 int v;
172
173 v = (((pix[0] >> 24) & 0xff) * 5) / 256;
174 if (v > dither[x & 0x1][y & 0x1])
175 v = 1;
176 else
177 v = 0;
178
179 XPutPixel(xim, x, y, v);
180 pix++;
181 }
182 }
183 gc = XCreateGC(_ecore_x_disp, mask, 0, &gcv);
184 if (_ecore_xlib_sync) ecore_x_sync();
185 XPutImage(_ecore_x_disp, mask, gc, xim, 0, 0, 0, 0, w, h);
186 if (_ecore_xlib_sync) ecore_x_sync();
187 XFreeGC(_ecore_x_disp, gc);
188
189 free(xim->data);
190 xim->data = NULL;
191 XDestroyImage(xim);
192
193 c1.pixel = 0;
194 c1.red = fr << 8 | fr;
195 c1.green = fg << 8 | fg;
196 c1.blue = fb << 8 | fb;
197 c1.flags = DoRed | DoGreen | DoBlue;
198
199 c2.pixel = 0;
200 c2.red = br << 8 | br;
201 c2.green = bg << 8 | bg;
202 c2.blue = bb << 8 | bb;
203 c2.flags = DoRed | DoGreen | DoBlue;
204
205 c = XCreatePixmapCursor(_ecore_x_disp,
206 pmap, mask,
207 &c1, &c2,
208 hot_x, hot_y);
209 if (_ecore_xlib_sync) ecore_x_sync();
210 XFreePixmap(_ecore_x_disp, pmap);
211 XFreePixmap(_ecore_x_disp, mask);
212 return c;
213 }
214
215 return 0;
216 }
217
218 EAPI void
ecore_x_cursor_free(Ecore_X_Cursor c)219 ecore_x_cursor_free(Ecore_X_Cursor c)
220 {
221 LOGFN;
222 EINA_SAFETY_ON_NULL_RETURN(_ecore_x_disp);
223 XFreeCursor(_ecore_x_disp, c);
224 if (_ecore_xlib_sync) ecore_x_sync();
225 }
226
227 /*
228 * Returns the cursor for the given shape.
229 * Note that the return value must not be freed with
230 * ecore_x_cursor_free()!
231 */
232 EAPI Ecore_X_Cursor
ecore_x_cursor_shape_get(int shape)233 ecore_x_cursor_shape_get(int shape)
234 {
235 Ecore_X_Cursor cur;
236 LOGFN;
237 EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, 0);
238 /* Shapes are defined in Ecore_X_Cursor.h */
239 cur = XCreateFontCursor(_ecore_x_disp, shape);
240 if (_ecore_xlib_sync) ecore_x_sync();
241 return cur;
242 }
243
244 EAPI void
ecore_x_cursor_size_set(int size)245 ecore_x_cursor_size_set(int size)
246 {
247 #ifdef ECORE_XCURSOR
248 LOGFN;
249 EINA_SAFETY_ON_NULL_RETURN(_ecore_x_disp);
250 XcursorSetDefaultSize(_ecore_x_disp, size);
251 if (_ecore_xlib_sync) ecore_x_sync();
252 #else /* ifdef ECORE_XCURSOR */
253 (void) size;
254 #endif /* ifdef ECORE_XCURSOR */
255 }
256
257 EAPI int
ecore_x_cursor_size_get(void)258 ecore_x_cursor_size_get(void)
259 {
260 #ifdef ECORE_XCURSOR
261 LOGFN;
262 EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_x_disp, 0);
263 return XcursorGetDefaultSize(_ecore_x_disp);
264 #else /* ifdef ECORE_XCURSOR */
265 return 0;
266 #endif /* ifdef ECORE_XCURSOR */
267 }
268
269