3 typedef struct _E_Pointer_Stack E_Pointer_Stack;
4 struct _E_Pointer_Stack
11 static Eina_List *_hdlrs = NULL;
12 static Eina_List *_ptrs = NULL;
13 static Eina_Bool _initted = EINA_FALSE;
16 _e_pointer_theme_buf(E_Pointer *ptr, char cursor[1024])
19 snprintf(cursor, 1024, "e/pointer/enlightenment/%s/color", ptr->type);
21 snprintf(cursor, 1024, "e/pointer/enlightenment/%s/mono", ptr->type);
25 _e_pointer_hot_update(E_Pointer *ptr, int x, int y)
27 if ((ptr->hot.x != x) || (ptr->hot.y != y))
31 ptr->hot.update = EINA_TRUE;
36 _e_pointer_active(E_Pointer *ptr)
38 if (!ptr->idle) return;
40 edje_object_signal_emit(ptr->o_ptr, "e,state,mouse,active", "e");
41 ptr->idle = EINA_FALSE;
45 _e_pointer_idle(E_Pointer *ptr)
47 if (ptr->idle) return;
49 edje_object_signal_emit(ptr->o_ptr, "e,state,mouse,idle", "e");
50 ptr->idle = EINA_TRUE;
54 _e_pointer_cb_idle_poller(void *data)
59 if (!(ptr = data)) return ECORE_CALLBACK_RENEW;
61 if (!e_config->idle_cursor)
63 ptr->idle_poll = NULL;
64 return ECORE_CALLBACK_CANCEL;
68 ecore_evas_pointer_xy_get(ptr->ee, &x, &y);
70 if ((ptr->x != x) || (ptr->y != y))
74 if (ptr->idle) _e_pointer_active(ptr);
75 return ECORE_CALLBACK_RENEW;
78 if (!ptr->idle) _e_pointer_idle(ptr);
80 return ECORE_CALLBACK_RENEW;
84 _e_pointer_cb_idle_wait(void *data)
88 if (!(ptr = data)) return ECORE_CALLBACK_RENEW;
90 if (!e_config->idle_cursor)
92 E_FREE_FUNC(ptr->idle_poll, ecore_poller_del);
93 return ECORE_CALLBACK_CANCEL;
97 ptr->idle_poll = ecore_poller_add(ECORE_POLLER_CORE, 64,
98 _e_pointer_cb_idle_poller, ptr);
100 return ECORE_CALLBACK_CANCEL;
104 _e_pointer_cb_idle_pre(void *data)
108 if (!(ptr = data)) return ECORE_CALLBACK_RENEW;
111 ecore_evas_pointer_xy_get(ptr->ee, &ptr->x, &ptr->y);
113 ptr->idle_tmr = ecore_timer_loop_add(4.0, _e_pointer_cb_idle_wait, ptr);
115 return ECORE_CALLBACK_CANCEL;
119 _e_pointer_active_handle(E_Pointer *ptr)
121 _e_pointer_active(ptr);
123 ecore_timer_reset(ptr->idle_tmr);
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);
133 _e_pointer_cb_mouse_down(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
138 EINA_LIST_FOREACH(_ptrs, l, ptr)
140 _e_pointer_active_handle(ptr);
142 edje_object_signal_emit(ptr->o_ptr, "e,action,mouse,down", "e");
145 return ECORE_CALLBACK_PASS_ON;
149 _e_pointer_cb_mouse_up(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
154 EINA_LIST_FOREACH(_ptrs, l, ptr)
156 _e_pointer_active_handle(ptr);
158 edje_object_signal_emit(ptr->o_ptr, "e,action,mouse,up", "e");
161 return ECORE_CALLBACK_PASS_ON;
165 _e_pointer_cb_mouse_move(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
170 EINA_LIST_FOREACH(_ptrs, l, ptr)
172 _e_pointer_active_handle(ptr);
174 edje_object_signal_emit(ptr->o_ptr, "e,action,mouse,move", "e");
177 return ECORE_CALLBACK_PASS_ON;
181 _e_pointer_cb_mouse_wheel(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
186 EINA_LIST_FOREACH(_ptrs, l, ptr)
188 _e_pointer_active_handle(ptr);
190 edje_object_signal_emit(ptr->o_ptr, "e,action,mouse,wheel", "e");
193 return ECORE_CALLBACK_PASS_ON;
197 _e_pointer_cb_hot_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
199 E_Pointer *ptr = data;
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",
206 _e_pointer_hot_update(ptr, x, y);
210 _e_pointer_cb_hot_show(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
212 E_Pointer *ptr = data;
215 if (!ptr->e_cursor) return;
216 edje_object_part_geometry_get(ptr->o_ptr, "e.swallow.hotspot",
218 _e_pointer_hot_update(ptr, x, y);
222 _e_pointer_pointer_canvas_init(E_Pointer *ptr, Evas *e, Evas_Object **o_ptr, Evas_Object **o_hot)
224 /* create pointer object */
225 *o_ptr = edje_object_add(e);
227 /* create hotspot object */
228 *o_hot = evas_object_rectangle_add(e);
229 evas_object_color_set(*o_hot, 0, 0, 0, 0);
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);
236 evas_object_move(*o_ptr, 0, 0);
237 evas_object_resize(*o_ptr, ptr->w, ptr->h);
241 _e_pointer_canvas_del(E_Pointer *ptr)
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);
250 _e_pointer_canvas_add(E_Pointer *ptr)
252 Evas_Engine_Info_Buffer *einfo;
255 /* try to create new canvas */
256 if (!(ptr->buffer_evas = evas_new())) goto err;
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);
263 /* try to allocate space for pixels */
264 if (!(ptr->pixels = malloc(ptr->w * ptr->h * sizeof(int))))
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;
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;
280 /* set buffer engine info */
281 evas_engine_info_set(ptr->buffer_evas, (Evas_Engine_Info *)einfo);
283 _e_pointer_pointer_canvas_init(ptr, ptr->buffer_evas, &ptr->buffer_o_ptr, &ptr->buffer_o_hot);
286 ptr->evas = ptr->buffer_evas;
287 ptr->o_ptr = ptr->buffer_o_ptr;
288 ptr->o_hot = ptr->buffer_o_hot;
293 _e_pointer_canvas_del(ptr);
297 _e_pointer_canvas_resize(E_Pointer *ptr, int w, int h)
299 Evas_Engine_Info_Buffer *einfo;
301 if ((ptr->w == w) && (ptr->h == h)) return;
304 evas_output_size_set(ptr->buffer_evas, w, h);
305 evas_output_viewport_set(ptr->buffer_evas, 0, 0, w, h);
307 ptr->pixels = realloc(ptr->pixels, (ptr->w * ptr->h * sizeof(int)));
309 einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ptr->buffer_evas);
310 EINA_SAFETY_ON_NULL_RETURN(einfo);
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);
316 evas_object_move(ptr->buffer_o_ptr, 0, 0);
317 evas_object_resize(ptr->buffer_o_ptr, ptr->w, ptr->h);
321 _e_pointer_stack_free(E_Pointer_Stack *stack)
323 if (stack->type) eina_stringshare_del(stack->type);
328 _e_pointer_cb_free(E_Pointer *ptr)
330 _ptrs = eina_list_remove(_ptrs, ptr);
332 E_FREE_LIST(ptr->stack, _e_pointer_stack_free);
334 eina_stringshare_del(ptr->type);
336 E_FREE_FUNC(ptr->idle_tmr, ecore_timer_del);
337 E_FREE_FUNC(ptr->idle_poll, ecore_poller_del);
339 if (ptr->buffer_evas) _e_pointer_canvas_del(ptr);
345 _e_pointer_x11_setup(E_Pointer *ptr, const char *cursor)
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))
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);
358 if (ptr->buffer_evas) _e_pointer_canvas_del(ptr);
362 _e_pointer_type_set(E_Pointer *ptr, const char *type)
364 /* check if pointer type is already set */
365 if (!e_util_strcmp(ptr->type, type)) return;
367 eina_stringshare_replace(&ptr->type, type);
369 /* don't show cursor if in hidden mode */
370 if ((!e_config->show_cursor) || (!e_comp_wl->ptr.enabled))
381 if ((!ptr->buffer_evas) && ptr->win) _e_pointer_canvas_add(ptr);
382 _e_pointer_theme_buf(ptr, cursor);
384 /* try to set the edje object theme */
385 if (!e_theme_edje_object_set(ptr->o_ptr, "base/theme/pointer", cursor))
387 _e_pointer_x11_setup(ptr, cursor);
388 if (!cursor[0]) return;
390 edje_object_part_geometry_get(ptr->o_ptr, "e.swallow.hotspot",
392 _e_pointer_hot_update(ptr, x, y);
395 e_pointer_object_set(ptr, NULL, 0, 0);
397 evas_object_show(ptr->o_ptr);
401 _e_pointer_x11_setup(ptr, NULL);
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;
420 e_pointer_shutdown(void)
422 _initted = EINA_FALSE;
423 E_FREE_LIST(_hdlrs, ecore_event_handler_del);
428 e_pointer_window_new(Ecore_Window win, Eina_Bool filled)
430 E_Pointer *ptr = NULL;
432 EINA_SAFETY_ON_FALSE_RETURN_VAL(win, NULL);
433 if (!_initted) return NULL;
435 /* allocate space for new pointer */
436 if (!(ptr = E_OBJECT_ALLOC(E_Pointer, E_POINTER_TYPE, _e_pointer_cb_free)))
439 /* set default pointer properties */
440 ptr->w = ptr->h = e_config->cursor_size;
441 ptr->e_cursor = e_config->use_e_cursor;
443 ptr->color = EINA_FALSE;
445 ptr->color = e_comp->pointer->color;
447 /* set pointer default type */
448 if (filled) e_pointer_type_push(ptr, ptr, "default");
450 /* append this pointer to the list */
451 _ptrs = eina_list_append(_ptrs, ptr);
457 e_pointer_canvas_new(Ecore_Evas *ee, Eina_Bool filled)
459 E_Pointer *ptr = NULL;
461 EINA_SAFETY_ON_FALSE_RETURN_VAL(ee, NULL);
462 if (!_initted) return NULL;
464 /* allocate space for new pointer */
465 if (!(ptr = E_OBJECT_ALLOC(E_Pointer, E_POINTER_TYPE, _e_pointer_cb_free)))
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;
475 ptr->evas = ecore_evas_get(ee);
476 _e_pointer_pointer_canvas_init(ptr, ptr->evas, &ptr->o_ptr, &ptr->o_hot);
478 /* set pointer default type */
479 if (filled) e_pointer_type_push(ptr, ptr, "default");
481 /* append this pointer to the list */
482 _ptrs = eina_list_append(_ptrs, ptr);
484 _e_pointer_active_handle(ptr);
490 e_pointers_size_set(int size)
495 if (!e_config->show_cursor) return;
497 EINA_LIST_FOREACH(_ptrs, l, ptr)
499 if ((ptr->w == size) && (ptr->h == size)) continue;
500 if (ptr->buffer_evas)
501 _e_pointer_canvas_resize(ptr, size, size);
506 evas_object_resize(ptr->o_ptr, size, size);
512 e_pointer_hide(E_Pointer *ptr)
514 EINA_SAFETY_ON_NULL_RETURN(ptr);
516 if (ptr->buffer_evas)
517 _e_pointer_canvas_del(ptr);
519 evas_object_hide(ptr->o_ptr);
523 e_pointer_type_push(E_Pointer *ptr, void *obj, const char *type)
525 E_Pointer_Stack *stack;
527 EINA_SAFETY_ON_NULL_RETURN(ptr);
529 _e_pointer_type_set(ptr, type);
531 if (!(stack = E_NEW(E_Pointer_Stack, 1))) return;
532 stack->type = eina_stringshare_ref(ptr->type);
534 ptr->stack = eina_list_prepend(ptr->stack, stack);
538 e_pointer_type_pop(E_Pointer *ptr, void *obj, const char *type)
541 E_Pointer_Stack *stack;
543 EINA_SAFETY_ON_NULL_RETURN(ptr);
545 EINA_LIST_FOREACH_SAFE(ptr->stack, l, ll, stack)
547 if ((stack->obj == obj) &&
548 ((!type) || (!e_util_strcmp(stack->type, type))))
550 _e_pointer_stack_free(stack);
551 ptr->stack = eina_list_remove_list(ptr->stack, l);
559 eina_stringshare_replace(&ptr->type, NULL);
563 if (!(stack = eina_list_data_get(ptr->stack))) return;
565 _e_pointer_type_set(ptr, stack->type);
567 eina_stringshare_refplace(&ptr->type, stack->type);
571 e_pointer_mode_push(void *obj, E_Pointer_Mode mode)
576 EINA_SAFETY_ON_NULL_RETURN(e_comp->pointer);
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)))
584 case E_POINTER_RESIZE_TL:
585 e_pointer_type_push(e_comp->pointer, obj, "resize_tl");
588 case E_POINTER_RESIZE_T:
589 e_pointer_type_push(e_comp->pointer, obj, "resize_t");
592 case E_POINTER_RESIZE_TR:
593 e_pointer_type_push(e_comp->pointer, obj, "resize_tr");
596 case E_POINTER_RESIZE_R:
597 e_pointer_type_push(e_comp->pointer, obj, "resize_r");
600 case E_POINTER_RESIZE_BR:
601 e_pointer_type_push(e_comp->pointer, obj, "resize_br");
604 case E_POINTER_RESIZE_B:
605 e_pointer_type_push(e_comp->pointer, obj, "resize_b");
608 case E_POINTER_RESIZE_BL:
609 e_pointer_type_push(e_comp->pointer, obj, "resize_bl");
612 case E_POINTER_RESIZE_L:
613 e_pointer_type_push(e_comp->pointer, obj, "resize_l");
617 e_pointer_type_push(e_comp->pointer, obj, "move");
625 e_pointer_mode_pop(void *obj, E_Pointer_Mode mode)
629 case E_POINTER_RESIZE_TL:
630 e_pointer_type_pop(e_comp->pointer, obj, "resize_tl");
633 case E_POINTER_RESIZE_T:
634 e_pointer_type_pop(e_comp->pointer, obj, "resize_t");
637 case E_POINTER_RESIZE_TR:
638 e_pointer_type_pop(e_comp->pointer, obj, "resize_tr");
641 case E_POINTER_RESIZE_R:
642 e_pointer_type_pop(e_comp->pointer, obj, "resize_r");
645 case E_POINTER_RESIZE_BR:
646 e_pointer_type_pop(e_comp->pointer, obj, "resize_br");
649 case E_POINTER_RESIZE_B:
650 e_pointer_type_pop(e_comp->pointer, obj, "resize_b");
653 case E_POINTER_RESIZE_BL:
654 e_pointer_type_pop(e_comp->pointer, obj, "resize_bl");
657 case E_POINTER_RESIZE_L:
658 e_pointer_type_pop(e_comp->pointer, obj, "resize_l");
662 e_pointer_type_pop(e_comp->pointer, obj, "move");
670 e_pointer_idler_before(void)
675 if ((!e_config->show_cursor) || (!e_comp_wl->ptr.enabled)) return;
677 EINA_LIST_FOREACH(_ptrs, l, ptr)
679 if ((!ptr->e_cursor) || (!ptr->buffer_evas)) continue;
682 _e_pointer_type_set(ptr, ptr->type);
684 if (ptr->buffer_evas)
688 if ((updates = evas_render_updates(ptr->buffer_evas)))
690 evas_render_updates_free(updates);
694 ptr->hot.update = EINA_FALSE;
699 e_pointer_object_set(E_Pointer *ptr, Evas_Object *obj, int x, int y)
704 EINA_SAFETY_ON_NULL_RETURN(ptr);
706 /* don't show cursor if in hidden mode */
707 if ((!e_config->show_cursor) || (!e_comp_wl->ptr.enabled))
709 if (obj) evas_object_hide(obj);
713 ecore_evas_cursor_get(ptr->ee, &o, NULL, NULL, NULL);
718 ecore_evas_object_cursor_set(ptr->ee, obj, E_LAYER_MAX - 1, x, y);
719 if (e_pointer_is_hidden(ptr))
721 e_comp_hwc_end("re_cursor_set");
725 ec = e_comp_object_client_get(o);
729 ec->visible = EINA_FALSE;
732 ecore_evas_cursor_unset(ptr->ee);
736 ec = e_comp_object_client_get(obj);
740 ec->visible = EINA_FALSE;
742 ecore_evas_object_cursor_set(ptr->ee, obj, E_LAYER_MAX - 1, x, y);
745 ecore_evas_object_cursor_set(ptr->ee, ptr->o_ptr, E_LAYER_MAX - 1, ptr->hot.x, ptr->hot.y);
747 if (e_pointer_is_hidden(ptr))
749 e_comp_hwc_end("cursor_set");
754 e_pointer_window_add(E_Pointer *ptr, Ecore_Window win)
759 _e_pointer_theme_buf(ptr, buf);
760 _e_pointer_x11_setup(ptr, buf);
764 e_pointer_is_hidden(E_Pointer *ptr)
768 EINA_SAFETY_ON_NULL_RETURN_VAL(ptr, EINA_TRUE);
770 if (!e_config->show_cursor)
773 ecore_evas_cursor_get(ptr->ee, &o, NULL, NULL, NULL);
776 if (evas_object_visible_get(o))
781 if (ptr->o_ptr && (evas_object_visible_get(ptr->o_ptr)))