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_hot_update(E_Pointer *ptr, int x, int y)
18 if ((ptr->hot.x != x) || (ptr->hot.y != y))
22 ptr->hot.update = EINA_TRUE;
27 _e_pointer_active(E_Pointer *ptr)
29 if (!ptr->idle) return;
31 edje_object_signal_emit(ptr->o_ptr, "e,state,mouse,active", "e");
32 ptr->idle = EINA_FALSE;
36 _e_pointer_idle(E_Pointer *ptr)
38 if (ptr->idle) return;
40 edje_object_signal_emit(ptr->o_ptr, "e,state,mouse,idle", "e");
41 ptr->idle = EINA_TRUE;
45 _e_pointer_cb_idle_poller(void *data)
50 if (!(ptr = data)) return ECORE_CALLBACK_RENEW;
52 if ((e_powersave_mode_get() >= E_POWERSAVE_MODE_MEDIUM) ||
53 (!e_config->idle_cursor))
55 ptr->idle_poll = NULL;
56 return ECORE_CALLBACK_CANCEL;
59 #ifndef HAVE_WAYLAND_ONLY
61 ecore_x_pointer_xy_get(ptr->win, &x, &y);
64 ecore_evas_pointer_xy_get(ptr->ee, &x, &y);
66 if ((ptr->x != x) || (ptr->y != y))
70 if (ptr->idle) _e_pointer_active(ptr);
71 return ECORE_CALLBACK_RENEW;
74 if (!ptr->idle) _e_pointer_idle(ptr);
76 return ECORE_CALLBACK_RENEW;
80 _e_pointer_cb_idle_wait(void *data)
84 if (!(ptr = data)) return ECORE_CALLBACK_RENEW;
86 if ((e_powersave_mode_get() >= E_POWERSAVE_MODE_MEDIUM) ||
87 (!e_config->idle_cursor))
89 E_FREE_FUNC(ptr->idle_poll, ecore_poller_del);
90 return ECORE_CALLBACK_CANCEL;
94 ptr->idle_poll = ecore_poller_add(ECORE_POLLER_CORE, 64,
95 _e_pointer_cb_idle_poller, ptr);
97 return ECORE_CALLBACK_CANCEL;
101 _e_pointer_cb_idle_pre(void *data)
105 if (!(ptr = data)) return ECORE_CALLBACK_RENEW;
107 #ifndef HAVE_WAYLAND_ONLY
109 ecore_x_pointer_xy_get(ptr->win, &ptr->x, &ptr->y);
112 ecore_evas_pointer_xy_get(ptr->ee, &ptr->x, &ptr->y);
114 ptr->idle_tmr = ecore_timer_loop_add(4.0, _e_pointer_cb_idle_wait, ptr);
116 return ECORE_CALLBACK_CANCEL;
120 _e_pointer_active_handle(E_Pointer *ptr)
122 _e_pointer_active(ptr);
124 ecore_timer_reset(ptr->idle_tmr);
127 E_FREE_FUNC(ptr->idle_poll, ecore_poller_del);
128 if (e_powersave_mode_get() >= E_POWERSAVE_MODE_MEDIUM) return;
129 if (!e_config->idle_cursor) return;
130 ptr->idle_tmr = ecore_timer_loop_add(1.0, _e_pointer_cb_idle_pre, ptr);
135 _e_pointer_cb_mouse_down(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
140 EINA_LIST_FOREACH(_ptrs, l, ptr)
142 _e_pointer_active_handle(ptr);
143 if (e_powersave_mode_get() < E_POWERSAVE_MODE_EXTREME)
146 edje_object_signal_emit(ptr->o_ptr, "e,action,mouse,down", "e");
150 return ECORE_CALLBACK_PASS_ON;
154 _e_pointer_cb_mouse_up(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
159 EINA_LIST_FOREACH(_ptrs, l, ptr)
161 _e_pointer_active_handle(ptr);
162 if (e_powersave_mode_get() < E_POWERSAVE_MODE_EXTREME)
165 edje_object_signal_emit(ptr->o_ptr, "e,action,mouse,up", "e");
169 return ECORE_CALLBACK_PASS_ON;
173 _e_pointer_cb_mouse_move(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
178 EINA_LIST_FOREACH(_ptrs, l, ptr)
180 _e_pointer_active_handle(ptr);
181 if (e_powersave_mode_get() < E_POWERSAVE_MODE_HIGH)
184 edje_object_signal_emit(ptr->o_ptr, "e,action,mouse,move", "e");
188 return ECORE_CALLBACK_PASS_ON;
192 _e_pointer_cb_mouse_wheel(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
197 EINA_LIST_FOREACH(_ptrs, l, ptr)
199 _e_pointer_active_handle(ptr);
200 if (e_powersave_mode_get() < E_POWERSAVE_MODE_EXTREME)
203 edje_object_signal_emit(ptr->o_ptr, "e,action,mouse,wheel", "e");
207 return ECORE_CALLBACK_PASS_ON;
211 _e_pointer_cb_hot_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
216 if (!(ptr = data)) return;
217 if (!ptr->e_cursor) return;
218 if (!evas_object_visible_get(ptr->o_ptr)) return;
219 edje_object_part_geometry_get(ptr->o_ptr, "e.swallow.hotspot",
221 _e_pointer_hot_update(ptr, x, y);
225 _e_pointer_cb_hot_show(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
230 if (!(ptr = data)) return;
231 edje_object_part_geometry_get(ptr->o_ptr, "e.swallow.hotspot",
233 _e_pointer_hot_update(ptr, x, y);
237 _e_pointer_canvas_del(E_Pointer *ptr)
239 E_FREE_FUNC(ptr->o_hot, evas_object_del);
240 E_FREE_FUNC(ptr->o_ptr, evas_object_del);
241 if (ptr->evas) evas_free(ptr->evas);
247 _e_pointer_canvas_add(E_Pointer *ptr)
249 Evas_Engine_Info_Buffer *einfo;
252 /* try to create new canvas */
253 if (!(ptr->evas = evas_new())) goto err;
255 method = evas_render_method_lookup("buffer");
256 evas_output_method_set(ptr->evas, method);
257 evas_output_size_set(ptr->evas, ptr->w, ptr->h);
258 evas_output_viewport_set(ptr->evas, 0, 0, ptr->w, ptr->h);
260 /* try to allocate space for pixels */
261 if (!(ptr->pixels = malloc(ptr->w * ptr->h * sizeof(int))))
264 /* try to get the buffer engine info */
265 einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ptr->evas);
266 if (!einfo) goto err;
268 /* fill in buffer engine info */
269 einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32;
270 einfo->info.dest_buffer = ptr->pixels;
271 einfo->info.dest_buffer_row_bytes = (ptr->w * sizeof(int));
272 einfo->info.use_color_key = 0;
273 einfo->info.alpha_threshold = 0;
274 einfo->info.func.new_update_region = NULL;
275 einfo->info.func.free_update_region = NULL;
277 /* set buffer engine info */
278 evas_engine_info_set(ptr->evas, (Evas_Engine_Info *)einfo);
280 /* create pointer object */
281 ptr->o_ptr = edje_object_add(ptr->evas);
283 /* create hotspot object */
284 ptr->o_hot = evas_object_rectangle_add(ptr->evas);
285 evas_object_color_set(ptr->o_hot, 0, 0, 0, 0);
287 evas_object_event_callback_add(ptr->o_hot, EVAS_CALLBACK_MOVE,
288 _e_pointer_cb_hot_move, ptr);
289 evas_object_event_callback_add(ptr->o_hot, EVAS_CALLBACK_SHOW,
290 _e_pointer_cb_hot_show, ptr);
292 evas_object_move(ptr->o_ptr, 0, 0);
293 evas_object_resize(ptr->o_ptr, ptr->w, ptr->h);
298 _e_pointer_canvas_del(ptr);
302 _e_pointer_canvas_resize(E_Pointer *ptr, int w, int h)
304 Evas_Engine_Info_Buffer *einfo;
306 if ((ptr->w == w) && (ptr->h == h)) return;
309 evas_output_size_set(ptr->evas, w, h);
310 evas_output_viewport_set(ptr->evas, 0, 0, w, h);
312 ptr->pixels = realloc(ptr->pixels, (ptr->w * ptr->h * sizeof(int)));
314 einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ptr->evas);
315 EINA_SAFETY_ON_NULL_RETURN(einfo);
317 einfo->info.dest_buffer = ptr->pixels;
318 einfo->info.dest_buffer_row_bytes = (ptr->w * sizeof(int));
319 evas_engine_info_set(ptr->evas, (Evas_Engine_Info *)einfo);
321 evas_object_move(ptr->o_ptr, 0, 0);
322 evas_object_resize(ptr->o_ptr, ptr->w, ptr->h);
326 _e_pointer_stack_free(E_Pointer_Stack *stack)
328 if (stack->type) eina_stringshare_del(stack->type);
333 _e_pointer_cb_free(E_Pointer *ptr)
335 _ptrs = eina_list_remove(_ptrs, ptr);
337 E_FREE_LIST(ptr->stack, _e_pointer_stack_free);
339 eina_stringshare_del(ptr->type);
341 E_FREE_FUNC(ptr->idle_tmr, ecore_timer_del);
342 E_FREE_FUNC(ptr->idle_poll, ecore_poller_del);
344 if (!ptr->canvas) _e_pointer_canvas_del(ptr);
350 _e_pointer_type_set(E_Pointer *ptr, const char *type)
352 /* check if pointer type is already set */
353 if (!e_util_strcmp(ptr->type, type)) return;
355 eina_stringshare_replace(&ptr->type, type);
357 /* don't show cursor if in hidden mode */
358 if (!e_config->show_cursor)
369 /* create a pointer canvas if we need to */
370 if ((!ptr->evas) && (!ptr->canvas)) _e_pointer_canvas_add(ptr);
373 snprintf(cursor, sizeof(cursor),
374 "e/pointer/enlightenment/%s/color", type);
376 snprintf(cursor, sizeof(cursor),
377 "e/pointer/enlightenment/%s/mono", type);
379 /* try to set the edje object theme */
380 if (!e_theme_edje_object_set(ptr->o_ptr, "base/theme/pointer", cursor))
383 edje_object_part_swallow(ptr->o_ptr, "e.swallow.hotspot", ptr->o_hot);
385 edje_object_part_geometry_get(ptr->o_ptr, "e.swallow.hotspot",
387 _e_pointer_hot_update(ptr, x, y);
390 e_pointer_object_set(ptr, NULL, 0, 0);
392 evas_object_show(ptr->o_ptr);
398 if ((ptr->evas) && (!ptr->canvas)) _e_pointer_canvas_del(ptr);
399 #ifndef HAVE_WAYLAND_ONLY
400 Ecore_X_Cursor cursor = 0;
402 if (!strcmp(type, "move"))
403 cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_FLEUR);
405 else if (!strcmp(type, "resize"))
406 cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_SIZING);
408 else if (!strcmp(type, "resize_tl"))
409 cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_TOP_LEFT_CORNER);
410 else if (!strcmp(type, "resize_t"))
411 cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_TOP_SIDE);
412 else if (!strcmp(type, "resize_tr"))
413 cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_TOP_RIGHT_CORNER);
414 else if (!strcmp(type, "resize_r"))
415 cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_RIGHT_SIDE);
416 else if (!strcmp(type, "resize_br"))
417 cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_BOTTOM_RIGHT_CORNER);
418 else if (!strcmp(type, "resize_b"))
419 cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_BOTTOM_SIDE);
420 else if (!strcmp(type, "resize_bl"))
421 cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_BOTTOM_LEFT_CORNER);
422 else if (!strcmp(type, "resize_l"))
423 cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_LEFT_SIDE);
424 else if (!strcmp(type, "entry"))
425 cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_XTERM);
426 else if (!strcmp(type, "default"))
427 cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_LEFT_PTR);
428 else if (!strcmp(type, "plus"))
429 cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_PLUS);
430 else if (!strcmp(type, "hand"))
431 cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_HAND1);
432 else if (!strcmp(type, "rotate"))
433 cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_EXCHANGE);
436 WRN("Unknown pointer type: %s\n", type);
437 cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_ARROW);
439 if (!cursor) WRN("X Cursor for %s is missing\n", type);
440 ecore_x_window_cursor_set(ptr->win, cursor);
441 if (cursor) ecore_x_cursor_free(cursor);
449 E_LIST_HANDLER_APPEND(_hdlrs, ECORE_EVENT_MOUSE_BUTTON_DOWN,
450 _e_pointer_cb_mouse_down, NULL);
451 E_LIST_HANDLER_APPEND(_hdlrs, ECORE_EVENT_MOUSE_BUTTON_UP,
452 _e_pointer_cb_mouse_up, NULL);
453 E_LIST_HANDLER_APPEND(_hdlrs, ECORE_EVENT_MOUSE_MOVE,
454 _e_pointer_cb_mouse_move, NULL);
455 E_LIST_HANDLER_APPEND(_hdlrs, ECORE_EVENT_MOUSE_WHEEL,
456 _e_pointer_cb_mouse_wheel, NULL);
457 _initted = EINA_TRUE;
462 e_pointer_shutdown(void)
464 _initted = EINA_FALSE;
465 E_FREE_LIST(_hdlrs, ecore_event_handler_del);
470 e_pointer_window_new(Ecore_Window win, Eina_Bool filled)
472 E_Pointer *ptr = NULL;
474 EINA_SAFETY_ON_FALSE_RETURN_VAL(win, NULL);
475 if (!_initted) return NULL;
477 /* allocate space for new pointer */
478 if (!(ptr = E_OBJECT_ALLOC(E_Pointer, E_POINTER_TYPE, _e_pointer_cb_free)))
481 /* set default pointer properties */
482 ptr->w = ptr->h = e_config->cursor_size;
483 ptr->e_cursor = e_config->use_e_cursor;
485 ptr->color = EINA_FALSE;
487 ptr->color = e_comp->pointer->color;
489 /* set pointer default type */
490 if (filled) e_pointer_type_push(ptr, ptr, "default");
492 /* append this pointer to the list */
493 _ptrs = eina_list_append(_ptrs, ptr);
499 e_pointer_canvas_new(Ecore_Evas *ee, Eina_Bool filled)
501 E_Pointer *ptr = NULL;
503 EINA_SAFETY_ON_FALSE_RETURN_VAL(ee, NULL);
504 if (!_initted) return NULL;
506 /* allocate space for new pointer */
507 if (!(ptr = E_OBJECT_ALLOC(E_Pointer, E_POINTER_TYPE, _e_pointer_cb_free)))
510 /* set default pointer properties */
511 ptr->color = EINA_TRUE;
512 ptr->canvas = EINA_TRUE;
513 ptr->w = ptr->h = e_config->cursor_size;
514 ptr->e_cursor = e_config->use_e_cursor;
517 ptr->evas = ecore_evas_get(ee);
519 ptr->o_ptr = edje_object_add(ptr->evas);
521 ptr->o_hot = evas_object_rectangle_add(ptr->evas);
522 evas_object_color_set(ptr->o_hot, 0, 0, 0, 0);
523 evas_object_event_callback_add(ptr->o_hot, EVAS_CALLBACK_MOVE,
524 _e_pointer_cb_hot_move, ptr);
525 evas_object_event_callback_add(ptr->o_hot, EVAS_CALLBACK_SHOW,
526 _e_pointer_cb_hot_show, ptr);
528 evas_object_move(ptr->o_ptr, 0, 0);
529 evas_object_resize(ptr->o_ptr, ptr->w, ptr->h);
531 /* set pointer default type */
532 if (filled) e_pointer_type_push(ptr, ptr, "default");
534 /* append this pointer to the list */
535 _ptrs = eina_list_append(_ptrs, ptr);
537 _e_pointer_active_handle(ptr);
543 e_pointers_size_set(int size)
548 if (!e_config->show_cursor) return;
550 EINA_LIST_FOREACH(_ptrs, l, ptr)
552 if ((ptr->w == size) && (ptr->h == size)) continue;
553 if ((ptr->evas) && (!ptr->canvas))
554 _e_pointer_canvas_resize(ptr, size, size);
555 else if (ptr->canvas)
559 evas_object_resize(ptr->o_ptr, size, size);
562 #ifndef HAVE_WAYLAND_ONLY
563 ecore_x_cursor_size_set(e_config->cursor_size * 3 / 4);
569 e_pointer_hide(E_Pointer *ptr)
571 EINA_SAFETY_ON_NULL_RETURN(ptr);
573 if ((ptr->evas) && (!ptr->canvas))
574 _e_pointer_canvas_del(ptr);
575 else if (ptr->canvas)
576 evas_object_hide(ptr->o_ptr);
577 #ifndef HAVE_WAYLAND_ONLY
578 ecore_x_window_cursor_set(ptr->win, 0);
583 e_pointer_type_push(E_Pointer *ptr, void *obj, const char *type)
585 E_Pointer_Stack *stack;
587 EINA_SAFETY_ON_NULL_RETURN(ptr);
589 _e_pointer_type_set(ptr, type);
591 if (!(stack = E_NEW(E_Pointer_Stack, 1))) return;
592 stack->type = eina_stringshare_ref(ptr->type);
594 ptr->stack = eina_list_prepend(ptr->stack, stack);
598 e_pointer_type_pop(E_Pointer *ptr, void *obj, const char *type)
601 E_Pointer_Stack *stack;
603 EINA_SAFETY_ON_NULL_RETURN(ptr);
605 EINA_LIST_FOREACH_SAFE(ptr->stack, l, ll, stack)
607 if ((stack->obj == obj) &&
608 ((!type) || (!e_util_strcmp(stack->type, type))))
610 _e_pointer_stack_free(stack);
611 ptr->stack = eina_list_remove_list(ptr->stack, l);
619 eina_stringshare_replace(&ptr->type, NULL);
623 if (!(stack = eina_list_data_get(ptr->stack))) return;
625 _e_pointer_type_set(ptr, stack->type);
627 eina_stringshare_refplace(&ptr->type, stack->type);
631 e_pointer_mode_push(void *obj, E_Pointer_Mode mode)
636 EINA_SAFETY_ON_NULL_RETURN(e_comp->pointer);
638 ecore_evas_cursor_get(e_comp->pointer->ee, &o, NULL, NULL, NULL);
639 if ((o != e_comp->pointer->o_ptr) && (ec = e_comp_object_client_get(o)))
644 case E_POINTER_RESIZE_TL:
645 e_pointer_type_push(e_comp->pointer, obj, "resize_tl");
648 case E_POINTER_RESIZE_T:
649 e_pointer_type_push(e_comp->pointer, obj, "resize_t");
652 case E_POINTER_RESIZE_TR:
653 e_pointer_type_push(e_comp->pointer, obj, "resize_tr");
656 case E_POINTER_RESIZE_R:
657 e_pointer_type_push(e_comp->pointer, obj, "resize_r");
660 case E_POINTER_RESIZE_BR:
661 e_pointer_type_push(e_comp->pointer, obj, "resize_br");
664 case E_POINTER_RESIZE_B:
665 e_pointer_type_push(e_comp->pointer, obj, "resize_b");
668 case E_POINTER_RESIZE_BL:
669 e_pointer_type_push(e_comp->pointer, obj, "resize_bl");
672 case E_POINTER_RESIZE_L:
673 e_pointer_type_push(e_comp->pointer, obj, "resize_l");
677 e_pointer_type_push(e_comp->pointer, obj, "move");
685 e_pointer_mode_pop(void *obj, E_Pointer_Mode mode)
689 case E_POINTER_RESIZE_TL:
690 e_pointer_type_pop(e_comp->pointer, obj, "resize_tl");
693 case E_POINTER_RESIZE_T:
694 e_pointer_type_pop(e_comp->pointer, obj, "resize_t");
697 case E_POINTER_RESIZE_TR:
698 e_pointer_type_pop(e_comp->pointer, obj, "resize_tr");
701 case E_POINTER_RESIZE_R:
702 e_pointer_type_pop(e_comp->pointer, obj, "resize_r");
705 case E_POINTER_RESIZE_BR:
706 e_pointer_type_pop(e_comp->pointer, obj, "resize_br");
709 case E_POINTER_RESIZE_B:
710 e_pointer_type_pop(e_comp->pointer, obj, "resize_b");
713 case E_POINTER_RESIZE_BL:
714 e_pointer_type_pop(e_comp->pointer, obj, "resize_bl");
717 case E_POINTER_RESIZE_L:
718 e_pointer_type_pop(e_comp->pointer, obj, "resize_l");
722 e_pointer_type_pop(e_comp->pointer, obj, "move");
730 e_pointer_idler_before(void)
735 if (!e_config->show_cursor) return;
737 EINA_LIST_FOREACH(_ptrs, l, ptr)
739 if ((!ptr->e_cursor) || (!ptr->evas)) continue;
742 _e_pointer_type_set(ptr, ptr->type);
748 if ((updates = evas_render_updates(ptr->evas)))
750 #ifndef HAVE_WAYLAND_ONLY
753 cur = ecore_x_cursor_new(ptr->win, ptr->pixels, ptr->w,
754 ptr->h, ptr->hot.x, ptr->hot.y);
755 ecore_x_window_cursor_set(ptr->win, cur);
756 ecore_x_cursor_free(cur);
758 evas_render_updates_free(updates);
762 ptr->hot.update = EINA_FALSE;
767 e_pointer_object_set(E_Pointer *ptr, Evas_Object *obj, int x, int y)
772 EINA_SAFETY_ON_NULL_RETURN(ptr);
774 /* don't show cursor if in hidden mode */
775 if (!e_config->show_cursor)
777 if (obj) evas_object_hide(obj);
781 ecore_evas_cursor_get(ptr->ee, &o, NULL, NULL, NULL);
786 ecore_evas_object_cursor_set(ptr->ee, obj, EVAS_LAYER_MAX, x, y);
789 ec = e_comp_object_client_get(o);
793 ecore_evas_cursor_unset(ptr->ee);
797 ec = e_comp_object_client_get(obj);
800 ecore_evas_object_cursor_set(ptr->ee, obj, EVAS_LAYER_MAX, x, y);
804 ecore_evas_object_cursor_set(ptr->ee, ptr->o_ptr, EVAS_LAYER_MAX, ptr->hot.x, ptr->hot.y);