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