[ecore] merged svn latest code (svn54830)
[profile/ivi/ecore.git] / src / lib / ecore_x / xcb / ecore_xcb_cursor.c
1 #include "ecore_xcb_private.h"
2 #include <xcb/shm.h>
3 #include <xcb/xcb_image.h>
4
5 extern int _ecore_xcb_xcursor;
6
7 EAPI Eina_Bool
8 ecore_x_cursor_color_supported_get(void)
9 {
10    return _ecore_xcb_xcursor;
11 } /* ecore_x_cursor_color_supported_get */
12
13 EAPI Ecore_X_Cursor
14 ecore_x_cursor_new(Ecore_X_Window window,
15                    int           *pixels,
16                    int            w,
17                    int            h,
18                    int            hot_x,
19                    int            hot_y)
20 {
21    Ecore_X_Cursor cursor = 0;
22
23 #ifdef ECORE_XCB_CURSOR
24    if (_ecore_x_xcursor)
25      {
26         Cursor c;
27         XcursorImage *xci;
28
29         xci = XcursorImageCreate(w, h);
30         if (xci)
31           {
32              int i;
33
34              xci->xhot = hot_x;
35              xci->yhot = hot_y;
36              xci->delay = 0;
37              for (i = 0; i < (w * h); i++)
38                {
39 //                int r, g, b, a;
40 //
41 //                a = (pixels[i] >> 24) & 0xff;
42 //                r = (((pixels[i] >> 16) & 0xff) * a) / 0xff;
43 //                g = (((pixels[i] >> 8 ) & 0xff) * a) / 0xff;
44 //                b = (((pixels[i]      ) & 0xff) * a) / 0xff;
45                   xci->pixels[i] = pixels[i];
46 //                  (a << 24) | (r << 16) | (g << 8) | (b);
47                }
48              c = XcursorImageLoadCursor(_ecore_x_disp, xci);
49              XcursorImageDestroy(xci);
50              return c;
51           }
52      }
53    else
54 #endif /* ECORE_XCB_CURSOR */
55    {
56       const uint32_t dither[2][2] =
57       {
58          {0, 2},
59          {3, 1}
60       };
61       Ecore_X_Drawable draw;
62       Ecore_X_Pixmap pixmap;
63       Ecore_X_Pixmap mask;
64       Ecore_X_GC gc;
65       xcb_image_t *image;
66       uint32_t *pix;
67       uint8_t fr;
68       uint8_t fg;
69       uint8_t fb;
70       uint8_t br;
71       uint8_t bg;
72       uint8_t bb;
73       uint32_t brightest = 0;
74       uint32_t darkest = 255 * 3;
75       uint16_t x;
76       uint16_t y;
77
78       draw = window;
79       pixmap = xcb_generate_id(_ecore_xcb_conn);
80       xcb_create_pixmap(_ecore_xcb_conn,
81                         1, pixmap, draw,
82                         1, 1);
83       mask = xcb_generate_id(_ecore_xcb_conn);
84       xcb_create_pixmap(_ecore_xcb_conn,
85                         1, mask, draw,
86                         1, 1);
87
88       image = xcb_image_create_native(_ecore_xcb_conn, w, h,
89                                       XCB_IMAGE_FORMAT_Z_PIXMAP,
90                                       32, NULL, ~0, NULL);
91       image->data = malloc(image->size);
92
93       fr = 0x00; fg = 0x00; fb = 0x00;
94       br = 0xff; bg = 0xff; bb = 0xff;
95       pix = (uint32_t *)pixels;
96       for (y = 0; y < h; y++)
97         {
98            for (x = 0; x < w; x++)
99              {
100                 uint8_t r, g, b, a;
101
102                 a = (pix[0] >> 24) & 0xff;
103                 r = (pix[0] >> 16) & 0xff;
104                 g = (pix[0] >> 8) & 0xff;
105                 b = (pix[0]) & 0xff;
106                 if (a > 0)
107                   {
108                      if ((uint32_t)(r + g + b) > brightest)
109                        {
110                           brightest = r + g + b;
111                           br = r;
112                           bg = g;
113                           bb = b;
114                        }
115
116                      if ((uint32_t)(r + g + b) < darkest)
117                        {
118                           darkest = r + g + b;
119                           fr = r;
120                           fg = g;
121                           fb = b;
122                        }
123                   }
124
125                 pix++;
126              }
127         }
128
129       pix = (uint32_t *)pixels;
130       for (y = 0; y < h; y++)
131         {
132            for (x = 0; x < w; x++)
133              {
134                 uint32_t v;
135                 uint8_t r, g, b;
136                 int32_t d1, d2;
137
138                 r = (pix[0] >> 16) & 0xff;
139                 g = (pix[0] >> 8) & 0xff;
140                 b = (pix[0]) & 0xff;
141                 d1 =
142                    ((r - fr) * (r - fr)) +
143                    ((g - fg) * (g - fg)) +
144                    ((b - fb) * (b - fb));
145                 d2 =
146                    ((r - br) * (r - br)) +
147                    ((g - bg) * (g - bg)) +
148                    ((b - bb) * (b - bb));
149                 if (d1 + d2)
150                   {
151                      v = (((d2 * 255) / (d1 + d2)) * 5) / 256;
152                      if (v > dither[x & 0x1][y & 0x1])
153                         v = 1;
154                      else
155                         v = 0;
156                   }
157                 else
158                   {
159                      v = 0;
160                   }
161
162                 xcb_image_put_pixel(image, x, y, v);
163                 pix++;
164              }
165         }
166       draw = pixmap;
167       gc = xcb_generate_id(_ecore_xcb_conn);
168       xcb_create_gc(_ecore_xcb_conn, gc, draw, 0, NULL);
169       xcb_image_put(_ecore_xcb_conn, draw, gc, image, 0, 0, 0);
170       xcb_free_gc(_ecore_xcb_conn, gc);
171
172       pix = (uint32_t *)pixels;
173       for (y = 0; y < h; y++)
174         {
175            for (x = 0; x < w; x++)
176              {
177                 uint32_t v;
178
179                 v = (((pix[0] >> 24) & 0xff) * 5) / 256;
180                 if (v > dither[x & 0x1][y & 0x1])
181                    v = 1;
182                 else
183                    v = 0;
184
185                 xcb_image_put_pixel(image, x, y, v);
186                 pix++;
187              }
188         }
189       draw = mask;
190       gc = xcb_generate_id(_ecore_xcb_conn);
191       xcb_create_gc (_ecore_xcb_conn, gc, draw, 0, NULL);
192       xcb_image_put(_ecore_xcb_conn, draw, gc, image, 0, 0, 0);
193       xcb_free_gc(_ecore_xcb_conn, gc);
194
195       free(image->data);
196       image->data = NULL;
197       xcb_image_destroy(image);
198
199       cursor = xcb_generate_id(_ecore_xcb_conn);
200       xcb_create_cursor (_ecore_xcb_conn, cursor,
201                          pixmap, mask,
202                          fr << 8 | fr,
203                          fg << 8 | fg,
204                          fb << 8 | fb,
205                          br << 8 | br,
206                          bg << 8 | bg,
207                          bb << 8 | bb,
208                          hot_x,
209                          hot_y);
210       xcb_free_pixmap(_ecore_xcb_conn, pixmap);
211       xcb_free_pixmap(_ecore_xcb_conn, mask);
212
213       return cursor;
214    }
215
216    return 0;
217 } /* ecore_x_cursor_new */
218
219 EAPI void
220 ecore_x_cursor_free(Ecore_X_Cursor cursor)
221 {
222    xcb_free_cursor(_ecore_xcb_conn, cursor);
223 } /* ecore_x_cursor_free */
224
225 /*
226  * Returns the cursor for the given shape.
227  * Note that the return value must not be freed with
228  * ecore_x_cursor_free()!
229  */
230 EAPI Ecore_X_Cursor
231 ecore_x_cursor_shape_get(int shape)
232 {
233    Ecore_X_Cursor cursor;
234    xcb_font_t font;
235
236    /* Shapes are defined in Ecore_X_Cursor.h */
237    font = xcb_generate_id(_ecore_xcb_conn);
238    xcb_open_font(_ecore_xcb_conn, font, strlen("cursor"), "cursor");
239
240    cursor = xcb_generate_id(_ecore_xcb_conn);
241    xcb_create_glyph_cursor (_ecore_xcb_conn,
242                             cursor,
243                             font,
244                             font,
245                             shape,
246                             shape + 1,
247                             0, 0, 0,
248                             65535, 65535, 65535);
249
250    xcb_close_font(_ecore_xcb_conn, font);
251
252    return cursor;
253 } /* ecore_x_cursor_shape_get */
254
255 EAPI void
256 ecore_x_cursor_size_set(int size)
257 {
258 #ifdef ECORE_XCB_CURSOR
259    XcursorSetDefaultSize(_ecore_x_disp, size);
260 #else /* ifdef ECORE_XCB_CURSOR */
261    size = 0;
262 #endif /* ECORE_XCB_CURSOR */
263 } /* ecore_x_cursor_size_set */
264
265 EAPI int
266 ecore_x_cursor_size_get(void)
267 {
268 #ifdef ECORE_XCB_CURSOR
269    return XcursorGetDefaultSize(_ecore_x_disp);
270 #else /* ifdef ECORE_XCB_CURSOR */
271    return 0;
272 #endif /* ECORE_XCB_CURSOR */
273 } /* ecore_x_cursor_size_get */
274