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