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