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;
15 _e_pointer_hot_update(E_Pointer *ptr, int x, int y)
17 if ((ptr->hot.x != x) || (ptr->hot.y != y))
21 ptr->hot.update = EINA_TRUE;
26 _e_pointer_active(E_Pointer *ptr)
28 if (!ptr->idle) return;
30 edje_object_signal_emit(ptr->o_ptr, "e,state,mouse,active", "e");
31 ptr->idle = EINA_FALSE;
35 _e_pointer_idle(E_Pointer *ptr)
37 if (ptr->idle) return;
39 edje_object_signal_emit(ptr->o_ptr, "e,state,mouse,idle", "e");
40 ptr->idle = EINA_TRUE;
44 _e_pointer_cb_idle_poller(void *data)
49 if (!(ptr = data)) return ECORE_CALLBACK_RENEW;
51 if ((e_powersave_mode_get() >= E_POWERSAVE_MODE_MEDIUM) ||
52 (!e_config->idle_cursor))
54 ptr->idle_poll = NULL;
55 return ECORE_CALLBACK_CANCEL;
58 #ifndef HAVE_WAYLAND_ONLY
60 ecore_x_pointer_xy_get(ptr->win, &x, &y);
63 ecore_evas_pointer_xy_get(ptr->ee, &x, &y);
65 if ((ptr->x != x) || (ptr->y != y))
69 if (ptr->idle) _e_pointer_active(ptr);
70 return ECORE_CALLBACK_RENEW;
73 if (!ptr->idle) _e_pointer_idle(ptr);
75 return ECORE_CALLBACK_RENEW;
79 _e_pointer_cb_idle_wait(void *data)
83 if (!(ptr = data)) return ECORE_CALLBACK_RENEW;
85 if ((e_powersave_mode_get() >= E_POWERSAVE_MODE_MEDIUM) ||
86 (!e_config->idle_cursor))
88 E_FREE_FUNC(ptr->idle_poll, ecore_poller_del);
89 return ECORE_CALLBACK_CANCEL;
93 ptr->idle_poll = ecore_poller_add(ECORE_POLLER_CORE, 64,
94 _e_pointer_cb_idle_poller, ptr);
96 return ECORE_CALLBACK_CANCEL;
100 _e_pointer_cb_idle_pre(void *data)
104 if (!(ptr = data)) return ECORE_CALLBACK_RENEW;
106 #ifndef HAVE_WAYLAND_ONLY
108 ecore_x_pointer_xy_get(ptr->win, &ptr->x, &ptr->y);
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_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);
134 _e_pointer_cb_mouse_down(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
139 EINA_LIST_FOREACH(_ptrs, l, ptr)
141 _e_pointer_active_handle(ptr);
142 if (e_powersave_mode_get() < E_POWERSAVE_MODE_EXTREME)
145 edje_object_signal_emit(ptr->o_ptr, "e,action,mouse,down", "e");
149 return ECORE_CALLBACK_PASS_ON;
153 _e_pointer_cb_mouse_up(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
158 EINA_LIST_FOREACH(_ptrs, l, ptr)
160 _e_pointer_active_handle(ptr);
161 if (e_powersave_mode_get() < E_POWERSAVE_MODE_EXTREME)
164 edje_object_signal_emit(ptr->o_ptr, "e,action,mouse,up", "e");
168 return ECORE_CALLBACK_PASS_ON;
172 _e_pointer_cb_mouse_move(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
177 EINA_LIST_FOREACH(_ptrs, l, ptr)
179 _e_pointer_active_handle(ptr);
180 if (e_powersave_mode_get() < E_POWERSAVE_MODE_HIGH)
183 edje_object_signal_emit(ptr->o_ptr, "e,action,mouse,move", "e");
187 return ECORE_CALLBACK_PASS_ON;
191 _e_pointer_cb_mouse_wheel(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
196 EINA_LIST_FOREACH(_ptrs, l, ptr)
198 _e_pointer_active_handle(ptr);
199 if (e_powersave_mode_get() < E_POWERSAVE_MODE_EXTREME)
202 edje_object_signal_emit(ptr->o_ptr, "e,action,mouse,wheel", "e");
206 return ECORE_CALLBACK_PASS_ON;
210 _e_pointer_cb_hot_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
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",
220 _e_pointer_hot_update(ptr, x, y);
224 _e_pointer_cb_hot_show(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
229 if (!(ptr = data)) return;
230 edje_object_part_geometry_get(ptr->o_ptr, "e.swallow.hotspot",
232 _e_pointer_hot_update(ptr, x, y);
236 _e_pointer_canvas_del(E_Pointer *ptr)
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);
246 _e_pointer_canvas_add(E_Pointer *ptr)
248 Evas_Engine_Info_Buffer *einfo;
251 /* try to create new canvas */
252 if (!(ptr->evas = evas_new())) goto err;
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);
259 /* try to allocate space for pixels */
260 if (!(ptr->pixels = malloc(ptr->w * ptr->h * sizeof(int))))
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;
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;
276 /* set buffer engine info */
277 evas_engine_info_set(ptr->evas, (Evas_Engine_Info *)einfo);
279 /* create pointer object */
280 ptr->o_ptr = edje_object_add(ptr->evas);
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);
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);
291 evas_object_move(ptr->o_ptr, 0, 0);
292 evas_object_resize(ptr->o_ptr, ptr->w, ptr->h);
297 _e_pointer_canvas_del(ptr);
301 _e_pointer_canvas_resize(E_Pointer *ptr, int w, int h)
303 Evas_Engine_Info_Buffer *einfo;
305 if ((ptr->w == w) && (ptr->h == h)) return;
308 evas_output_size_set(ptr->evas, w, h);
309 evas_output_viewport_set(ptr->evas, 0, 0, w, h);
311 ptr->pixels = realloc(ptr->pixels, (ptr->w * ptr->h * sizeof(int)));
313 einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ptr->evas);
314 EINA_SAFETY_ON_NULL_RETURN(einfo);
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);
320 evas_object_move(ptr->o_ptr, 0, 0);
321 evas_object_resize(ptr->o_ptr, ptr->w, ptr->h);
325 _e_pointer_stack_free(E_Pointer_Stack *stack)
327 if (stack->type) eina_stringshare_del(stack->type);
332 _e_pointer_cb_free(E_Pointer *ptr)
334 _ptrs = eina_list_remove(_ptrs, ptr);
336 E_FREE_LIST(ptr->stack, _e_pointer_stack_free);
338 eina_stringshare_del(ptr->type);
340 E_FREE_FUNC(ptr->idle_tmr, ecore_timer_del);
341 E_FREE_FUNC(ptr->idle_poll, ecore_poller_del);
343 if (!ptr->canvas) _e_pointer_canvas_del(ptr);
349 _e_pointer_type_set(E_Pointer *ptr, const char *type)
351 /* check if pointer type is already set */
352 if (!e_util_strcmp(ptr->type, type)) return;
354 eina_stringshare_replace(&ptr->type, type);
356 /* don't show cursor if in hidden mode */
357 if (!e_config->show_cursor)
368 /* create a pointer canvas if we need to */
369 if ((!ptr->evas) && (!ptr->canvas)) _e_pointer_canvas_add(ptr);
372 snprintf(cursor, sizeof(cursor),
373 "e/pointer/enlightenment/%s/color", type);
375 snprintf(cursor, sizeof(cursor),
376 "e/pointer/enlightenment/%s/mono", type);
378 /* try to set the edje object theme */
379 if (!e_theme_edje_object_set(ptr->o_ptr, "base/theme/pointer", cursor))
382 edje_object_part_swallow(ptr->o_ptr, "e.swallow.hotspot", ptr->o_hot);
384 edje_object_part_geometry_get(ptr->o_ptr, "e.swallow.hotspot",
386 _e_pointer_hot_update(ptr, x, y);
389 e_pointer_object_set(ptr, NULL, 0, 0);
391 evas_object_show(ptr->o_ptr);
397 if ((ptr->evas) && (!ptr->canvas)) _e_pointer_canvas_del(ptr);
398 #ifndef HAVE_WAYLAND_ONLY
399 Ecore_X_Cursor cursor = 0;
401 if (!strcmp(type, "move"))
402 cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_FLEUR);
404 else if (!strcmp(type, "resize"))
405 cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_SIZING);
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);
435 WRN("Unknown pointer type: %s\n", type);
436 cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_ARROW);
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);
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);
460 e_pointer_shutdown(void)
462 E_FREE_LIST(_hdlrs, ecore_event_handler_del);
467 e_pointer_window_new(Ecore_Window win, Eina_Bool filled)
469 E_Pointer *ptr = NULL;
471 EINA_SAFETY_ON_FALSE_RETURN_VAL(win, NULL);
473 /* allocate space for new pointer */
474 if (!(ptr = E_OBJECT_ALLOC(E_Pointer, E_POINTER_TYPE, _e_pointer_cb_free)))
477 /* set default pointer properties */
478 ptr->w = ptr->h = e_config->cursor_size;
479 ptr->e_cursor = e_config->use_e_cursor;
481 ptr->color = EINA_FALSE;
483 ptr->color = e_comp->pointer->color;
485 /* set pointer default type */
486 if (filled) e_pointer_type_push(ptr, ptr, "default");
488 /* append this pointer to the list */
489 _ptrs = eina_list_append(_ptrs, ptr);
495 e_pointer_canvas_new(Ecore_Evas *ee, Eina_Bool filled)
497 E_Pointer *ptr = NULL;
499 EINA_SAFETY_ON_FALSE_RETURN_VAL(ee, NULL);
501 /* allocate space for new pointer */
502 if (!(ptr = E_OBJECT_ALLOC(E_Pointer, E_POINTER_TYPE, _e_pointer_cb_free)))
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;
512 ptr->evas = ecore_evas_get(ee);
514 ptr->o_ptr = edje_object_add(ptr->evas);
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);
523 evas_object_move(ptr->o_ptr, 0, 0);
524 evas_object_resize(ptr->o_ptr, ptr->w, ptr->h);
526 /* set pointer default type */
527 if (filled) e_pointer_type_push(ptr, ptr, "default");
529 /* append this pointer to the list */
530 _ptrs = eina_list_append(_ptrs, ptr);
532 _e_pointer_active_handle(ptr);
538 e_pointers_size_set(int size)
543 if (!e_config->show_cursor) return;
545 EINA_LIST_FOREACH(_ptrs, l, ptr)
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)
554 evas_object_resize(ptr->o_ptr, size, size);
557 #ifndef HAVE_WAYLAND_ONLY
558 ecore_x_cursor_size_set(e_config->cursor_size * 3 / 4);
564 e_pointer_hide(E_Pointer *ptr)
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);
576 e_pointer_type_push(E_Pointer *ptr, void *obj, const char *type)
578 E_Pointer_Stack *stack;
580 EINA_SAFETY_ON_NULL_RETURN(ptr);
582 _e_pointer_type_set(ptr, type);
584 if (!(stack = E_NEW(E_Pointer_Stack, 1))) return;
585 stack->type = eina_stringshare_ref(ptr->type);
587 ptr->stack = eina_list_prepend(ptr->stack, stack);
591 e_pointer_type_pop(E_Pointer *ptr, void *obj, const char *type)
594 E_Pointer_Stack *stack;
596 EINA_SAFETY_ON_NULL_RETURN(ptr);
598 EINA_LIST_FOREACH_SAFE(ptr->stack, l, ll, stack)
600 if ((stack->obj == obj) &&
601 ((!type) || (!e_util_strcmp(stack->type, type))))
603 _e_pointer_stack_free(stack);
604 ptr->stack = eina_list_remove_list(ptr->stack, l);
612 eina_stringshare_replace(&ptr->type, NULL);
616 if (!(stack = eina_list_data_get(ptr->stack))) return;
618 _e_pointer_type_set(ptr, stack->type);
620 eina_stringshare_refplace(&ptr->type, stack->type);
624 e_pointer_mode_push(void *obj, E_Pointer_Mode mode)
628 case E_POINTER_RESIZE_TL:
629 e_pointer_type_push(e_comp->pointer, obj, "resize_tl");
632 case E_POINTER_RESIZE_T:
633 e_pointer_type_push(e_comp->pointer, obj, "resize_t");
636 case E_POINTER_RESIZE_TR:
637 e_pointer_type_push(e_comp->pointer, obj, "resize_tr");
640 case E_POINTER_RESIZE_R:
641 e_pointer_type_push(e_comp->pointer, obj, "resize_r");
644 case E_POINTER_RESIZE_BR:
645 e_pointer_type_push(e_comp->pointer, obj, "resize_br");
648 case E_POINTER_RESIZE_B:
649 e_pointer_type_push(e_comp->pointer, obj, "resize_b");
652 case E_POINTER_RESIZE_BL:
653 e_pointer_type_push(e_comp->pointer, obj, "resize_bl");
656 case E_POINTER_RESIZE_L:
657 e_pointer_type_push(e_comp->pointer, obj, "resize_l");
661 e_pointer_type_push(e_comp->pointer, obj, "move");
669 e_pointer_mode_pop(void *obj, E_Pointer_Mode mode)
673 case E_POINTER_RESIZE_TL:
674 e_pointer_type_pop(e_comp->pointer, obj, "resize_tl");
677 case E_POINTER_RESIZE_T:
678 e_pointer_type_pop(e_comp->pointer, obj, "resize_t");
681 case E_POINTER_RESIZE_TR:
682 e_pointer_type_pop(e_comp->pointer, obj, "resize_tr");
685 case E_POINTER_RESIZE_R:
686 e_pointer_type_pop(e_comp->pointer, obj, "resize_r");
689 case E_POINTER_RESIZE_BR:
690 e_pointer_type_pop(e_comp->pointer, obj, "resize_br");
693 case E_POINTER_RESIZE_B:
694 e_pointer_type_pop(e_comp->pointer, obj, "resize_b");
697 case E_POINTER_RESIZE_BL:
698 e_pointer_type_pop(e_comp->pointer, obj, "resize_bl");
701 case E_POINTER_RESIZE_L:
702 e_pointer_type_pop(e_comp->pointer, obj, "resize_l");
706 e_pointer_type_pop(e_comp->pointer, obj, "move");
714 e_pointer_idler_before(void)
719 if (!e_config->show_cursor) return;
721 EINA_LIST_FOREACH(_ptrs, l, ptr)
723 if ((!ptr->e_cursor) || (!ptr->evas)) continue;
726 _e_pointer_type_set(ptr, ptr->type);
732 if ((updates = evas_render_updates(ptr->evas)))
734 #ifndef HAVE_WAYLAND_ONLY
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);
742 evas_render_updates_free(updates);
746 ptr->hot.update = EINA_FALSE;
751 e_pointer_object_set(E_Pointer *ptr, Evas_Object *obj, int x, int y)
756 ecore_evas_cursor_get(ptr->ee, &o, NULL, NULL, NULL);
759 ec = e_comp_object_client_get(o);
763 ecore_evas_cursor_unset(ptr->ee);
767 ec = e_comp_object_client_get(obj);
770 ecore_evas_object_cursor_set(ptr->ee, obj, EVAS_LAYER_MAX, x, y);
773 ecore_evas_object_cursor_set(ptr->ee, ptr->o_ptr, EVAS_LAYER_MAX, ptr->hot.x, ptr->hot.y);