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