replace all occurrences of cursor setting with calls to pointer util function
[platform/upstream/enlightenment.git] / src / bin / e_pointer.c
1 #include "e.h"
2
3 typedef struct _E_Pointer_Stack E_Pointer_Stack;
4 struct _E_Pointer_Stack
5 {
6    void *obj;
7    const char *type;
8 };
9
10 /* local variables */
11 static Eina_List *_hdlrs = NULL;
12 static Eina_List *_ptrs = NULL;
13
14 static inline void 
15 _e_pointer_hot_update(E_Pointer *ptr, int x, int y)
16 {
17    if ((ptr->hot.x != x) || (ptr->hot.y != y))
18      {
19         ptr->hot.x = x;
20         ptr->hot.y = y;
21         ptr->hot.update = EINA_TRUE;
22      }
23 }
24
25 static void 
26 _e_pointer_active(E_Pointer *ptr)
27 {
28    if (!ptr->idle) return;
29    if (ptr->o_ptr)
30      edje_object_signal_emit(ptr->o_ptr, "e,state,mouse,active", "e");
31    ptr->idle = EINA_FALSE;
32 }
33
34 static void 
35 _e_pointer_idle(E_Pointer *ptr)
36 {
37    if (ptr->idle) return;
38    if (ptr->o_ptr)
39      edje_object_signal_emit(ptr->o_ptr, "e,state,mouse,idle", "e");
40    ptr->idle = EINA_TRUE;
41 }
42
43 static Eina_Bool 
44 _e_pointer_cb_idle_poller(void *data)
45 {
46    E_Pointer *ptr;
47    int x = 0, y = 0;
48
49    if (!(ptr = data)) return ECORE_CALLBACK_RENEW;
50
51    if ((e_powersave_mode_get() >= E_POWERSAVE_MODE_MEDIUM) || 
52        (!e_config->idle_cursor))
53      {
54         ptr->idle_poll = NULL;
55         return ECORE_CALLBACK_CANCEL;
56      }
57
58 #ifndef HAVE_WAYLAND_ONLY
59    if (!ptr->canvas)
60      ecore_x_pointer_xy_get(ptr->win, &x, &y);
61    else
62 #endif
63      ecore_evas_pointer_xy_get(ptr->ee, &x, &y);
64
65    if ((ptr->x != x) || (ptr->y != y))
66      {
67         ptr->x = x;
68         ptr->y = y;
69         if (ptr->idle) _e_pointer_active(ptr);
70         return ECORE_CALLBACK_RENEW;
71      }
72
73    if (!ptr->idle) _e_pointer_idle(ptr);
74
75    return ECORE_CALLBACK_RENEW;
76 }
77
78 static Eina_Bool 
79 _e_pointer_cb_idle_wait(void *data)
80 {
81    E_Pointer *ptr;
82
83    if (!(ptr = data)) return ECORE_CALLBACK_RENEW;
84    ptr->idle_tmr = NULL;
85    if ((e_powersave_mode_get() >= E_POWERSAVE_MODE_MEDIUM) || 
86        (!e_config->idle_cursor))
87      {
88         E_FREE_FUNC(ptr->idle_poll, ecore_poller_del);
89         return ECORE_CALLBACK_CANCEL;
90      }
91
92    if (!ptr->idle_poll)
93      ptr->idle_poll = ecore_poller_add(ECORE_POLLER_CORE, 64, 
94                                        _e_pointer_cb_idle_poller, ptr);
95
96    return ECORE_CALLBACK_CANCEL;
97 }
98
99 static Eina_Bool 
100 _e_pointer_cb_idle_pre(void *data)
101 {
102    E_Pointer *ptr;
103
104    if (!(ptr = data)) return ECORE_CALLBACK_RENEW;
105
106 #ifndef HAVE_WAYLAND_ONLY
107    if (!ptr->canvas)
108      ecore_x_pointer_xy_get(ptr->win, &ptr->x, &ptr->y);
109    else
110 #endif
111      ecore_evas_pointer_xy_get(ptr->ee, &ptr->x, &ptr->y);
112
113    ptr->idle_tmr = ecore_timer_loop_add(4.0, _e_pointer_cb_idle_wait, ptr);
114
115    return ECORE_CALLBACK_CANCEL;
116 }
117
118 static void 
119 _e_pointer_active_handle(E_Pointer *ptr)
120 {
121    _e_pointer_active(ptr);
122    if (ptr->idle_tmr)
123      ecore_timer_reset(ptr->idle_tmr);
124    else
125      {
126         E_FREE_FUNC(ptr->idle_poll, ecore_poller_del);
127         if (e_powersave_mode_get() >= E_POWERSAVE_MODE_MEDIUM) return;
128         if (!e_config->idle_cursor) return;
129         ptr->idle_tmr = ecore_timer_loop_add(1.0, _e_pointer_cb_idle_pre, ptr);
130      }
131 }
132
133 static Eina_Bool 
134 _e_pointer_cb_mouse_down(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
135 {
136    Eina_List *l;
137    E_Pointer *ptr;
138
139    EINA_LIST_FOREACH(_ptrs, l, ptr)
140      {
141         _e_pointer_active_handle(ptr);
142         if (e_powersave_mode_get() < E_POWERSAVE_MODE_EXTREME)
143           {
144              if (ptr->o_ptr)
145                edje_object_signal_emit(ptr->o_ptr, "e,action,mouse,down", "e");
146           }
147      }
148
149    return ECORE_CALLBACK_PASS_ON;
150 }
151
152 static Eina_Bool 
153 _e_pointer_cb_mouse_up(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
154 {
155    Eina_List *l;
156    E_Pointer *ptr;
157
158    EINA_LIST_FOREACH(_ptrs, l, ptr)
159      {
160         _e_pointer_active_handle(ptr);
161         if (e_powersave_mode_get() < E_POWERSAVE_MODE_EXTREME)
162           {
163              if (ptr->o_ptr)
164                edje_object_signal_emit(ptr->o_ptr, "e,action,mouse,up", "e");
165           }
166      }
167
168    return ECORE_CALLBACK_PASS_ON;
169 }
170
171 static Eina_Bool 
172 _e_pointer_cb_mouse_move(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
173 {
174    Eina_List *l;
175    E_Pointer *ptr;
176
177    EINA_LIST_FOREACH(_ptrs, l, ptr)
178      {
179         _e_pointer_active_handle(ptr);
180         if (e_powersave_mode_get() < E_POWERSAVE_MODE_HIGH)
181           {
182              if (ptr->o_ptr)
183                edje_object_signal_emit(ptr->o_ptr, "e,action,mouse,move", "e");
184           }
185      }
186
187    return ECORE_CALLBACK_PASS_ON;
188 }
189
190 static Eina_Bool 
191 _e_pointer_cb_mouse_wheel(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
192 {
193    Eina_List *l;
194    E_Pointer *ptr;
195
196    EINA_LIST_FOREACH(_ptrs, l, ptr)
197      {
198         _e_pointer_active_handle(ptr);
199         if (e_powersave_mode_get() < E_POWERSAVE_MODE_EXTREME)
200           {
201              if (ptr->o_ptr)
202                edje_object_signal_emit(ptr->o_ptr, "e,action,mouse,wheel", "e");
203           }
204      }
205
206    return ECORE_CALLBACK_PASS_ON;
207 }
208
209 static void 
210 _e_pointer_cb_hot_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
211 {
212    E_Pointer *ptr;
213    int x = 0, y = 0;
214
215    if (!(ptr = data)) return;
216    if (!ptr->e_cursor) return;
217    if (!evas_object_visible_get(ptr->o_ptr)) return;
218    edje_object_part_geometry_get(ptr->o_ptr, "e.swallow.hotspot", 
219                                  &x, &y, NULL, NULL);
220    _e_pointer_hot_update(ptr, x, y);
221 }
222
223 static void 
224 _e_pointer_cb_hot_show(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
225 {
226    E_Pointer *ptr;
227    int x = 0, y = 0;
228
229    if (!(ptr = data)) return;
230    edje_object_part_geometry_get(ptr->o_ptr, "e.swallow.hotspot", 
231                                  &x, &y, NULL, NULL);
232    _e_pointer_hot_update(ptr, x, y);
233 }
234
235 static void 
236 _e_pointer_canvas_del(E_Pointer *ptr)
237 {
238    E_FREE_FUNC(ptr->o_hot, evas_object_del);
239    E_FREE_FUNC(ptr->o_ptr, evas_object_del);
240    if (ptr->evas) evas_free(ptr->evas);
241    ptr->evas = NULL;
242    E_FREE(ptr->pixels);
243 }
244
245 static void 
246 _e_pointer_canvas_add(E_Pointer *ptr)
247 {
248    Evas_Engine_Info_Buffer *einfo;
249    int method = 0;
250
251    /* try to create new canvas */
252    if (!(ptr->evas = evas_new())) goto err;
253
254    method = evas_render_method_lookup("buffer");
255    evas_output_method_set(ptr->evas, method);
256    evas_output_size_set(ptr->evas, ptr->w, ptr->h);
257    evas_output_viewport_set(ptr->evas, 0, 0, ptr->w, ptr->h);
258
259    /* try to allocate space for pixels */
260    if (!(ptr->pixels = malloc(ptr->w * ptr->h * sizeof(int))))
261      goto err;
262
263    /* try to get the buffer engine info */
264    einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ptr->evas);
265    if (!einfo) goto err;
266
267    /* fill in buffer engine info */
268    einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32;
269    einfo->info.dest_buffer = ptr->pixels;
270    einfo->info.dest_buffer_row_bytes = (ptr->w * sizeof(int));
271    einfo->info.use_color_key = 0;
272    einfo->info.alpha_threshold = 0;
273    einfo->info.func.new_update_region = NULL;
274    einfo->info.func.free_update_region = NULL;
275
276    /* set buffer engine info */
277    evas_engine_info_set(ptr->evas, (Evas_Engine_Info *)einfo);
278
279    /* create pointer object */
280    ptr->o_ptr = edje_object_add(ptr->evas);
281
282    /* create hotspot object */
283    ptr->o_hot = evas_object_rectangle_add(ptr->evas);
284    evas_object_color_set(ptr->o_hot, 0, 0, 0, 0);
285
286    evas_object_event_callback_add(ptr->o_hot, EVAS_CALLBACK_MOVE, 
287                                   _e_pointer_cb_hot_move, ptr);
288    evas_object_event_callback_add(ptr->o_hot, EVAS_CALLBACK_SHOW, 
289                                   _e_pointer_cb_hot_show, ptr);
290
291    evas_object_move(ptr->o_ptr, 0, 0);
292    evas_object_resize(ptr->o_ptr, ptr->w, ptr->h);
293
294    return;
295
296 err:
297    _e_pointer_canvas_del(ptr);
298 }
299
300 static void 
301 _e_pointer_canvas_resize(E_Pointer *ptr, int w, int h)
302 {
303    Evas_Engine_Info_Buffer *einfo;
304
305    if ((ptr->w == w) && (ptr->h == h)) return;
306    ptr->w = w;
307    ptr->h = h;
308    evas_output_size_set(ptr->evas, w, h);
309    evas_output_viewport_set(ptr->evas, 0, 0, w, h);
310
311    ptr->pixels = realloc(ptr->pixels, (ptr->w * ptr->h * sizeof(int)));
312
313    einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ptr->evas);
314    EINA_SAFETY_ON_NULL_RETURN(einfo);
315
316    einfo->info.dest_buffer = ptr->pixels;
317    einfo->info.dest_buffer_row_bytes = (ptr->w * sizeof(int));
318    evas_engine_info_set(ptr->evas, (Evas_Engine_Info *)einfo);
319
320    evas_object_move(ptr->o_ptr, 0, 0);
321    evas_object_resize(ptr->o_ptr, ptr->w, ptr->h);
322 }
323
324 static void 
325 _e_pointer_stack_free(E_Pointer_Stack *stack)
326 {
327    if (stack->type) eina_stringshare_del(stack->type);
328    free(stack);
329 }
330
331 static void 
332 _e_pointer_cb_free(E_Pointer *ptr)
333 {
334    _ptrs = eina_list_remove(_ptrs, ptr);
335
336    E_FREE_LIST(ptr->stack, _e_pointer_stack_free);
337
338    eina_stringshare_del(ptr->type);
339
340    E_FREE_FUNC(ptr->idle_tmr, ecore_timer_del);
341    E_FREE_FUNC(ptr->idle_poll, ecore_poller_del);
342
343    if (!ptr->canvas) _e_pointer_canvas_del(ptr);
344
345    free(ptr);
346 }
347
348 static void 
349 _e_pointer_type_set(E_Pointer *ptr, const char *type)
350 {
351    /* check if pointer type is already set */
352    if (!e_util_strcmp(ptr->type, type)) return;
353
354    eina_stringshare_replace(&ptr->type, type);
355
356    /* don't show cursor if in hidden mode */
357    if (!e_config->show_cursor)
358      {
359         e_pointer_hide(ptr);
360         return;
361      }
362
363    if (ptr->e_cursor)
364      {
365         char cursor[1024];
366         int x = 0, y = 0;
367
368         /* create a pointer canvas if we need to */
369         if ((!ptr->evas) && (!ptr->canvas)) _e_pointer_canvas_add(ptr);
370
371         if (ptr->color)
372           snprintf(cursor, sizeof(cursor), 
373                    "e/pointer/enlightenment/%s/color", type);
374         else
375           snprintf(cursor, sizeof(cursor), 
376                    "e/pointer/enlightenment/%s/mono", type);
377
378         /* try to set the edje object theme */
379         if (!e_theme_edje_object_set(ptr->o_ptr, "base/theme/pointer", cursor))
380           goto fallback;
381
382         edje_object_part_swallow(ptr->o_ptr, "e.swallow.hotspot", ptr->o_hot);
383
384         edje_object_part_geometry_get(ptr->o_ptr, "e.swallow.hotspot", 
385                                       &x, &y, NULL, NULL);
386         _e_pointer_hot_update(ptr, x, y);
387
388         if (ptr->canvas)
389           e_pointer_object_set(ptr, NULL, 0, 0);
390         else
391           evas_object_show(ptr->o_ptr);
392
393         return;
394      }
395
396 fallback:
397    if ((ptr->evas) && (!ptr->canvas)) _e_pointer_canvas_del(ptr);
398 #ifndef HAVE_WAYLAND_ONLY
399    Ecore_X_Cursor cursor = 0;
400
401    if (!strcmp(type, "move"))
402      cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_FLEUR);
403 # if 0
404    else if (!strcmp(type, "resize"))
405      cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_SIZING);
406 # endif
407    else if (!strcmp(type, "resize_tl"))
408      cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_TOP_LEFT_CORNER);
409    else if (!strcmp(type, "resize_t"))
410      cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_TOP_SIDE);
411    else if (!strcmp(type, "resize_tr"))
412      cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_TOP_RIGHT_CORNER);
413    else if (!strcmp(type, "resize_r"))
414      cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_RIGHT_SIDE);
415    else if (!strcmp(type, "resize_br"))
416      cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_BOTTOM_RIGHT_CORNER);
417    else if (!strcmp(type, "resize_b"))
418      cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_BOTTOM_SIDE);
419    else if (!strcmp(type, "resize_bl"))
420      cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_BOTTOM_LEFT_CORNER);
421    else if (!strcmp(type, "resize_l"))
422      cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_LEFT_SIDE);
423    else if (!strcmp(type, "entry"))
424      cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_XTERM);
425    else if (!strcmp(type, "default"))
426      cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_LEFT_PTR);
427    else if (!strcmp(type, "plus"))
428      cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_PLUS);
429    else if (!strcmp(type, "hand"))
430      cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_HAND1);
431    else if (!strcmp(type, "rotate"))
432      cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_EXCHANGE);
433    else
434      {
435         WRN("Unknown pointer type: %s\n", type);
436         cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_ARROW);
437      }
438    if (!cursor) WRN("X Cursor for %s is missing\n", type);
439    ecore_x_window_cursor_set(ptr->win, cursor);
440    if (cursor) ecore_x_cursor_free(cursor);
441 #endif
442    return;
443 }
444
445 EINTERN int 
446 e_pointer_init(void)
447 {
448    E_LIST_HANDLER_APPEND(_hdlrs, ECORE_EVENT_MOUSE_BUTTON_DOWN, 
449                          _e_pointer_cb_mouse_down, NULL);
450    E_LIST_HANDLER_APPEND(_hdlrs, ECORE_EVENT_MOUSE_BUTTON_UP, 
451                          _e_pointer_cb_mouse_up, NULL);
452    E_LIST_HANDLER_APPEND(_hdlrs, ECORE_EVENT_MOUSE_MOVE, 
453                          _e_pointer_cb_mouse_move, NULL);
454    E_LIST_HANDLER_APPEND(_hdlrs, ECORE_EVENT_MOUSE_WHEEL, 
455                          _e_pointer_cb_mouse_wheel, NULL);
456    return 1;
457 }
458
459 EINTERN int 
460 e_pointer_shutdown(void)
461 {
462    E_FREE_LIST(_hdlrs, ecore_event_handler_del);
463    return 1;
464 }
465
466 EAPI E_Pointer *
467 e_pointer_window_new(Ecore_Window win, Eina_Bool filled)
468 {
469    E_Pointer *ptr = NULL;
470
471    EINA_SAFETY_ON_FALSE_RETURN_VAL(win, NULL);
472
473    /* allocate space for new pointer */
474    if (!(ptr = E_OBJECT_ALLOC(E_Pointer, E_POINTER_TYPE, _e_pointer_cb_free)))
475      return NULL;
476
477    /* set default pointer properties */
478    ptr->w = ptr->h = e_config->cursor_size;
479    ptr->e_cursor = e_config->use_e_cursor;
480    ptr->win = win;
481    ptr->color = EINA_FALSE;
482    if (e_comp->pointer)
483      ptr->color = e_comp->pointer->color;
484
485    /* set pointer default type */
486    if (filled) e_pointer_type_push(ptr, ptr, "default");
487
488    /* append this pointer to the list */
489    _ptrs = eina_list_append(_ptrs, ptr);
490
491    return ptr;
492 }
493
494 EAPI E_Pointer *
495 e_pointer_canvas_new(Ecore_Evas *ee, Eina_Bool filled)
496 {
497    E_Pointer *ptr = NULL;
498
499    EINA_SAFETY_ON_FALSE_RETURN_VAL(ee, NULL);
500
501    /* allocate space for new pointer */
502    if (!(ptr = E_OBJECT_ALLOC(E_Pointer, E_POINTER_TYPE, _e_pointer_cb_free)))
503      return NULL;
504
505    /* set default pointer properties */
506    ptr->color = EINA_TRUE;
507    ptr->canvas = EINA_TRUE;
508    ptr->w = ptr->h = e_config->cursor_size;
509    ptr->e_cursor = e_config->use_e_cursor;
510
511    ptr->ee = ee;
512    ptr->evas = ecore_evas_get(ee);
513
514    ptr->o_ptr = edje_object_add(ptr->evas);
515
516    ptr->o_hot = evas_object_rectangle_add(ptr->evas);
517    evas_object_color_set(ptr->o_hot, 0, 0, 0, 0);
518    evas_object_event_callback_add(ptr->o_hot, EVAS_CALLBACK_MOVE, 
519                                   _e_pointer_cb_hot_move, ptr);
520    evas_object_event_callback_add(ptr->o_hot, EVAS_CALLBACK_SHOW, 
521                                   _e_pointer_cb_hot_show, ptr);
522
523    evas_object_move(ptr->o_ptr, 0, 0);
524    evas_object_resize(ptr->o_ptr, ptr->w, ptr->h);
525
526    /* set pointer default type */
527    if (filled) e_pointer_type_push(ptr, ptr, "default");
528
529      /* append this pointer to the list */
530    _ptrs = eina_list_append(_ptrs, ptr);
531
532    _e_pointer_active_handle(ptr);
533
534    return ptr;
535 }
536
537 EAPI void 
538 e_pointers_size_set(int size)
539 {
540    Eina_List *l;
541    E_Pointer *ptr;
542
543    if (!e_config->show_cursor) return;
544
545    EINA_LIST_FOREACH(_ptrs, l, ptr)
546      {
547         if ((ptr->w == size) && (ptr->h == size)) continue;
548         if ((ptr->evas) && (!ptr->canvas))
549           _e_pointer_canvas_resize(ptr, size, size);
550         else if (ptr->canvas)
551           {
552              ptr->w = size;
553              ptr->h = size;
554              evas_object_resize(ptr->o_ptr, size, size);
555           }
556
557 #ifndef HAVE_WAYLAND_ONLY
558         ecore_x_cursor_size_set(e_config->cursor_size * 3 / 4);
559 #endif
560      }
561 }
562
563 EAPI void 
564 e_pointer_hide(E_Pointer *ptr)
565 {
566    if ((ptr->evas) && (!ptr->canvas)) 
567      _e_pointer_canvas_del(ptr);
568    else if (ptr->canvas)
569      evas_object_hide(ptr->o_ptr);
570 #ifndef HAVE_WAYLAND_ONLY
571    ecore_x_window_cursor_set(ptr->win, 0);
572 #endif
573 }
574
575 EAPI void 
576 e_pointer_type_push(E_Pointer *ptr, void *obj, const char *type)
577 {
578    E_Pointer_Stack *stack;
579
580    EINA_SAFETY_ON_NULL_RETURN(ptr);
581
582    _e_pointer_type_set(ptr, type);
583
584    if (!(stack = E_NEW(E_Pointer_Stack, 1))) return;
585    stack->type = eina_stringshare_ref(ptr->type);
586    stack->obj = obj;
587    ptr->stack = eina_list_prepend(ptr->stack, stack);
588 }
589
590 EAPI void 
591 e_pointer_type_pop(E_Pointer *ptr, void *obj, const char *type)
592 {
593    Eina_List *l, *ll;
594    E_Pointer_Stack *stack;
595
596    EINA_SAFETY_ON_NULL_RETURN(ptr);
597
598    EINA_LIST_FOREACH_SAFE(ptr->stack, l, ll, stack)
599      {
600         if ((stack->obj == obj) && 
601             ((!type) || (!e_util_strcmp(stack->type, type))))
602           {
603              _e_pointer_stack_free(stack);
604              ptr->stack = eina_list_remove_list(ptr->stack, l);
605              if (type) break;
606           }
607      }
608
609    if (!ptr->stack)
610      {
611         e_pointer_hide(ptr);
612         eina_stringshare_replace(&ptr->type, NULL);
613         return;
614      }
615
616    if (!(stack = eina_list_data_get(ptr->stack))) return;
617
618    _e_pointer_type_set(ptr, stack->type);
619
620    eina_stringshare_refplace(&ptr->type, stack->type);
621 }
622
623 EAPI void 
624 e_pointer_mode_push(void *obj, E_Pointer_Mode mode)
625 {
626    switch (mode)
627      {
628       case E_POINTER_RESIZE_TL:
629         e_pointer_type_push(e_comp->pointer, obj, "resize_tl");
630         break;
631
632       case E_POINTER_RESIZE_T:
633         e_pointer_type_push(e_comp->pointer, obj, "resize_t");
634         break;
635
636       case E_POINTER_RESIZE_TR:
637         e_pointer_type_push(e_comp->pointer, obj, "resize_tr");
638         break;
639
640       case E_POINTER_RESIZE_R:
641         e_pointer_type_push(e_comp->pointer, obj, "resize_r");
642         break;
643
644       case E_POINTER_RESIZE_BR:
645         e_pointer_type_push(e_comp->pointer, obj, "resize_br");
646         break;
647
648       case E_POINTER_RESIZE_B:
649         e_pointer_type_push(e_comp->pointer, obj, "resize_b");
650         break;
651
652       case E_POINTER_RESIZE_BL:
653         e_pointer_type_push(e_comp->pointer, obj, "resize_bl");
654         break;
655
656       case E_POINTER_RESIZE_L:
657         e_pointer_type_push(e_comp->pointer, obj, "resize_l");
658         break;
659
660       case E_POINTER_MOVE:
661         e_pointer_type_push(e_comp->pointer, obj, "move");
662         break;
663
664       default: break;
665      }
666 }
667
668 EAPI void 
669 e_pointer_mode_pop(void *obj, E_Pointer_Mode mode)
670 {
671    switch (mode)
672      {
673       case E_POINTER_RESIZE_TL:
674         e_pointer_type_pop(e_comp->pointer, obj, "resize_tl");
675         break;
676
677       case E_POINTER_RESIZE_T:
678         e_pointer_type_pop(e_comp->pointer, obj, "resize_t");
679         break;
680
681       case E_POINTER_RESIZE_TR:
682         e_pointer_type_pop(e_comp->pointer, obj, "resize_tr");
683         break;
684
685       case E_POINTER_RESIZE_R:
686         e_pointer_type_pop(e_comp->pointer, obj, "resize_r");
687         break;
688
689       case E_POINTER_RESIZE_BR:
690         e_pointer_type_pop(e_comp->pointer, obj, "resize_br");
691         break;
692
693       case E_POINTER_RESIZE_B:
694         e_pointer_type_pop(e_comp->pointer, obj, "resize_b");
695         break;
696
697       case E_POINTER_RESIZE_BL:
698         e_pointer_type_pop(e_comp->pointer, obj, "resize_bl");
699         break;
700
701       case E_POINTER_RESIZE_L:
702         e_pointer_type_pop(e_comp->pointer, obj, "resize_l");
703         break;
704
705       case E_POINTER_MOVE:
706         e_pointer_type_pop(e_comp->pointer, obj, "move");
707         break;
708
709       default: break;
710      }
711 }
712
713 EAPI void 
714 e_pointer_idler_before(void)
715 {
716    Eina_List *l;
717    E_Pointer *ptr;
718
719    if (!e_config->show_cursor) return;
720
721    EINA_LIST_FOREACH(_ptrs, l, ptr)
722      {
723         if ((!ptr->e_cursor) || (!ptr->evas)) continue;
724
725         if (ptr->hot.update)
726           _e_pointer_type_set(ptr, ptr->type);
727  
728         if (!ptr->canvas)
729           {
730              Eina_List *updates;
731
732              if ((updates = evas_render_updates(ptr->evas)))
733                {
734 #ifndef HAVE_WAYLAND_ONLY
735                   Ecore_X_Cursor cur;
736
737                   cur = ecore_x_cursor_new(ptr->win, ptr->pixels, ptr->w, 
738                                            ptr->h, ptr->hot.x, ptr->hot.y);
739                   ecore_x_window_cursor_set(ptr->win, cur);
740                   ecore_x_cursor_free(cur);
741 #endif
742                   evas_render_updates_free(updates);
743                }
744           }
745
746         ptr->hot.update = EINA_FALSE;
747      }
748 }
749
750 EAPI void
751 e_pointer_object_set(E_Pointer *ptr, Evas_Object *obj, int x, int y)
752 {
753    ecore_evas_cursor_unset(ptr->ee);
754    if (obj)
755      ecore_evas_object_cursor_set(ptr->ee, obj, EVAS_LAYER_MAX, x, y);
756    else
757      ecore_evas_object_cursor_set(ptr->ee, ptr->o_ptr, EVAS_LAYER_MAX, ptr->hot.x, ptr->hot.y);
758 }