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