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);
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 ptr->idle_poll = NULL;
92 return ECORE_CALLBACK_CANCEL;
96 ptr->idle_poll = ecore_poller_add(ECORE_POLLER_CORE, 64,
97 _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;
110 #ifndef HAVE_WAYLAND_ONLY
112 ecore_x_pointer_xy_get(ptr->win, &ptr->x, &ptr->y);
115 ecore_evas_pointer_xy_get(ptr->ee, &ptr->x, &ptr->y);
118 ptr->idle_tmr = ecore_timer_loop_add(4.0, _e_pointer_cb_idle_wait, ptr);
120 return ECORE_CALLBACK_CANCEL;
124 _e_pointer_active_handle(E_Pointer *ptr)
126 _e_pointer_active(ptr);
128 ecore_timer_reset(ptr->idle_tmr);
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);
140 _e_pointer_cb_mouse_down(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
145 EINA_LIST_FOREACH(_ptrs, l, ptr)
147 _e_pointer_active_handle(ptr);
148 if (e_powersave_mode_get() < E_POWERSAVE_MODE_EXTREME)
151 edje_object_signal_emit(ptr->o_ptr, "e,action,mouse,down", "e");
155 return ECORE_CALLBACK_PASS_ON;
159 _e_pointer_cb_mouse_up(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
164 EINA_LIST_FOREACH(_ptrs, l, ptr)
166 _e_pointer_active_handle(ptr);
167 if (e_powersave_mode_get() < E_POWERSAVE_MODE_EXTREME)
170 edje_object_signal_emit(ptr->o_ptr, "e,action,mouse,up", "e");
174 return ECORE_CALLBACK_PASS_ON;
178 _e_pointer_cb_mouse_move(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
183 EINA_LIST_FOREACH(_ptrs, l, ptr)
185 _e_pointer_active_handle(ptr);
186 if (e_powersave_mode_get() < E_POWERSAVE_MODE_HIGH)
189 edje_object_signal_emit(ptr->o_ptr, "e,action,mouse,move", "e");
193 return ECORE_CALLBACK_PASS_ON;
197 _e_pointer_cb_mouse_wheel(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
202 EINA_LIST_FOREACH(_ptrs, l, ptr)
204 _e_pointer_active_handle(ptr);
205 if (e_powersave_mode_get() < E_POWERSAVE_MODE_EXTREME)
208 edje_object_signal_emit(ptr->o_ptr, "e,action,mouse,wheel", "e");
212 return ECORE_CALLBACK_PASS_ON;
216 _e_pointer_cb_hot_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
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",
226 _e_pointer_hot_update(ptr, x, y);
230 _e_pointer_cb_hot_show(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
235 if (!(ptr = data)) return;
236 edje_object_part_geometry_get(ptr->o_ptr, "e.swallow.hotspot",
238 _e_pointer_hot_update(ptr, x, y);
242 _e_pointer_canvas_del(E_Pointer *ptr)
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);
252 _e_pointer_canvas_add(E_Pointer *ptr)
254 Evas_Engine_Info_Buffer *einfo;
257 /* try to create new canvas */
258 if (!(ptr->evas = evas_new())) goto err;
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);
265 /* try to allocate space for pixels */
266 if (!(ptr->pixels = malloc(ptr->w * ptr->h * sizeof(int))))
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;
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;
282 /* set buffer engine info */
283 evas_engine_info_set(ptr->evas, (Evas_Engine_Info *)einfo);
285 /* create pointer object */
286 ptr->o_ptr = edje_object_add(ptr->evas);
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);
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);
297 evas_object_move(ptr->o_ptr, 0, 0);
298 evas_object_resize(ptr->o_ptr, ptr->w, ptr->h);
303 _e_pointer_canvas_del(ptr);
307 _e_pointer_canvas_resize(E_Pointer *ptr, int w, int h)
309 Evas_Engine_Info_Buffer *einfo;
311 if ((ptr->w == w) && (ptr->h == h)) return;
314 evas_output_size_set(ptr->evas, w, h);
315 evas_output_viewport_set(ptr->evas, 0, 0, w, h);
317 ptr->pixels = realloc(ptr->pixels, (ptr->w * ptr->h * sizeof(int)));
319 einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ptr->evas);
320 EINA_SAFETY_ON_NULL_RETURN(einfo);
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);
326 evas_object_move(ptr->o_ptr, 0, 0);
327 evas_object_resize(ptr->o_ptr, ptr->w, ptr->h);
331 _e_pointer_stack_free(E_Pointer_Stack *stack)
333 if (stack->type) eina_stringshare_del(stack->type);
338 _e_pointer_cb_free(E_Pointer *ptr)
340 _ptrs = eina_list_remove(_ptrs, ptr);
342 E_FREE_LIST(ptr->stack, _e_pointer_stack_free);
344 if (ptr->type) eina_stringshare_del(ptr->type);
346 E_FREE_FUNC(ptr->idle_tmr, ecore_timer_del);
347 E_FREE_FUNC(ptr->idle_poll, ecore_poller_del);
349 if (!ptr->canvas) _e_pointer_canvas_del(ptr);
355 _e_pointer_type_set(E_Pointer *ptr, const char *type)
357 /* check if pointer type is already set */
358 if (!e_util_strcmp(ptr->type, type)) return;
360 eina_stringshare_replace(&ptr->type, type);
362 /* don't show cursor if in hidden mode */
363 if (!e_config->show_cursor)
374 /* create a pointer canvas if we need to */
375 if ((!ptr->evas) && (!ptr->canvas)) _e_pointer_canvas_add(ptr);
378 snprintf(cursor, sizeof(cursor),
379 "e/pointer/enlightenment/%s/color", type);
381 snprintf(cursor, sizeof(cursor),
382 "e/pointer/enlightenment/%s/mono", type);
384 /* try to set the edje object theme */
385 if (!e_theme_edje_object_set(ptr->o_ptr, "base/theme/pointer", cursor))
388 edje_object_part_swallow(ptr->o_ptr, "e.swallow.hotspot", ptr->o_hot);
390 edje_object_part_geometry_get(ptr->o_ptr, "e.swallow.hotspot",
392 _e_pointer_hot_update(ptr, x, y);
395 ecore_evas_object_cursor_set(ptr->ee, ptr->o_ptr, EVAS_LAYER_MAX,
396 ptr->hot.x, ptr->hot.y);
398 evas_object_show(ptr->o_ptr);
404 if ((ptr->evas) && (!ptr->canvas)) _e_pointer_canvas_del(ptr);
405 #ifndef HAVE_WAYLAND_ONLY
406 Ecore_X_Cursor cursor = 0;
408 if (!strcmp(type, "move"))
409 cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_FLEUR);
411 else if (!strcmp(type, "resize"))
412 cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_SIZING);
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);
442 WRN("Unknown pointer type: %s\n", type);
443 cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_ARROW);
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);
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);
467 e_pointer_shutdown(void)
469 E_FREE_LIST(_hdlrs, ecore_event_handler_del);
474 e_pointer_window_new(Ecore_Window win, Eina_Bool filled)
476 E_Pointer *ptr = NULL;
479 EINA_SAFETY_ON_FALSE_RETURN_VAL(win, NULL);
481 /* allocate space for new pointer */
482 if (!(ptr = E_OBJECT_ALLOC(E_Pointer, E_POINTER_TYPE, _e_pointer_cb_free)))
485 /* set default pointer properties */
486 ptr->w = ptr->h = e_config->cursor_size;
487 ptr->e_cursor = e_config->use_e_cursor;
489 ptr->color = EINA_FALSE;
490 if ((comp = e_comp_get(NULL)))
493 ptr->color = comp->pointer->color;
496 /* set pointer default type */
497 if (filled) e_pointer_type_push(ptr, ptr, "default");
499 /* append this pointer to the list */
500 _ptrs = eina_list_append(_ptrs, ptr);
506 e_pointer_canvas_new(Ecore_Evas *ee, Eina_Bool filled)
508 E_Pointer *ptr = NULL;
510 EINA_SAFETY_ON_FALSE_RETURN_VAL(ee, NULL);
512 /* allocate space for new pointer */
513 if (!(ptr = E_OBJECT_ALLOC(E_Pointer, E_POINTER_TYPE, _e_pointer_cb_free)))
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;
523 ptr->evas = ecore_evas_get(ee);
525 ptr->o_ptr = edje_object_add(ptr->evas);
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);
534 evas_object_move(ptr->o_ptr, 0, 0);
535 evas_object_resize(ptr->o_ptr, ptr->w, ptr->h);
537 /* set pointer default type */
538 if (filled) e_pointer_type_push(ptr, ptr, "default");
540 /* append this pointer to the list */
541 _ptrs = eina_list_append(_ptrs, ptr);
543 _e_pointer_active_handle(ptr);
549 e_pointers_size_set(int size)
554 if (!e_config->show_cursor) return;
556 EINA_LIST_FOREACH(_ptrs, l, ptr)
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)
565 evas_object_resize(ptr->o_ptr, size, size);
568 #ifndef HAVE_WAYLAND_ONLY
569 ecore_x_cursor_size_set(e_config->cursor_size * 3 / 4);
575 e_pointer_hide(E_Pointer *ptr)
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);
587 e_pointer_type_push(E_Pointer *ptr, void *obj, const char *type)
589 E_Pointer_Stack *stack;
591 EINA_SAFETY_ON_NULL_RETURN(ptr);
593 _e_pointer_type_set(ptr, type);
595 if (!(stack = E_NEW(E_Pointer_Stack, 1))) return;
596 stack->type = eina_stringshare_ref(ptr->type);
598 ptr->stack = eina_list_prepend(ptr->stack, stack);
602 e_pointer_type_pop(E_Pointer *ptr, void *obj, const char *type)
605 E_Pointer_Stack *stack;
607 EINA_SAFETY_ON_NULL_RETURN(ptr);
609 EINA_LIST_FOREACH_SAFE(ptr->stack, l, ll, stack)
611 if ((stack->obj == obj) &&
612 ((!type) || (!e_util_strcmp(stack->type, type))))
614 _e_pointer_stack_free(stack);
615 ptr->stack = eina_list_remove_list(ptr->stack, l);
623 eina_stringshare_replace(&ptr->type, NULL);
627 if (!(stack = eina_list_data_get(ptr->stack))) return;
629 _e_pointer_type_set(ptr, stack->type);
631 eina_stringshare_refplace(&ptr->type, stack->type);
635 e_pointer_mode_push(void *obj, E_Pointer_Mode mode)
639 case E_POINTER_RESIZE_TL:
640 e_pointer_type_push(e_comp_get(obj)->pointer, obj, "resize_tl");
643 case E_POINTER_RESIZE_T:
644 e_pointer_type_push(e_comp_get(obj)->pointer, obj, "resize_t");
647 case E_POINTER_RESIZE_TR:
648 e_pointer_type_push(e_comp_get(obj)->pointer, obj, "resize_tr");
651 case E_POINTER_RESIZE_R:
652 e_pointer_type_push(e_comp_get(obj)->pointer, obj, "resize_r");
655 case E_POINTER_RESIZE_BR:
656 e_pointer_type_push(e_comp_get(obj)->pointer, obj, "resize_br");
659 case E_POINTER_RESIZE_B:
660 e_pointer_type_push(e_comp_get(obj)->pointer, obj, "resize_b");
663 case E_POINTER_RESIZE_BL:
664 e_pointer_type_push(e_comp_get(obj)->pointer, obj, "resize_bl");
667 case E_POINTER_RESIZE_L:
668 e_pointer_type_push(e_comp_get(obj)->pointer, obj, "resize_l");
672 e_pointer_type_push(e_comp_get(obj)->pointer, obj, "move");
680 e_pointer_mode_pop(void *obj, E_Pointer_Mode mode)
684 case E_POINTER_RESIZE_TL:
685 e_pointer_type_pop(e_comp_get(obj)->pointer, obj, "resize_tl");
688 case E_POINTER_RESIZE_T:
689 e_pointer_type_pop(e_comp_get(obj)->pointer, obj, "resize_t");
692 case E_POINTER_RESIZE_TR:
693 e_pointer_type_pop(e_comp_get(obj)->pointer, obj, "resize_tr");
696 case E_POINTER_RESIZE_R:
697 e_pointer_type_pop(e_comp_get(obj)->pointer, obj, "resize_r");
700 case E_POINTER_RESIZE_BR:
701 e_pointer_type_pop(e_comp_get(obj)->pointer, obj, "resize_br");
704 case E_POINTER_RESIZE_B:
705 e_pointer_type_pop(e_comp_get(obj)->pointer, obj, "resize_b");
708 case E_POINTER_RESIZE_BL:
709 e_pointer_type_pop(e_comp_get(obj)->pointer, obj, "resize_bl");
712 case E_POINTER_RESIZE_L:
713 e_pointer_type_pop(e_comp_get(obj)->pointer, obj, "resize_l");
717 e_pointer_type_pop(e_comp_get(obj)->pointer, obj, "move");
725 e_pointer_idler_before(void)
730 if (!e_config->show_cursor) return;
732 EINA_LIST_FOREACH(_ptrs, l, ptr)
734 if ((!ptr->e_cursor) || (!ptr->evas)) continue;
737 _e_pointer_type_set(ptr, ptr->type);
743 if ((updates = evas_render_updates(ptr->evas)))
745 #ifndef HAVE_WAYLAND_ONLY
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);
753 evas_render_updates_free(updates);
757 ptr->hot.update = EINA_FALSE;