4 static Eina_List *_ptrs = NULL;
5 static Eina_Bool _initted = EINA_FALSE;
7 static int _e_pointer_hooks_delete = 0;
8 static int _e_pointer_hooks_walking = 0;
9 static Eina_Inlist *_e_pointer_hooks[] =
11 [E_POINTER_HOOK_TOUCH_MOVE] = NULL,
12 [E_POINTER_HOOK_MOUSE_MOVE] = NULL,
13 [E_POINTER_HOOK_SHOW] = NULL,
14 [E_POINTER_HOOK_HIDE] = NULL,
18 _e_pointer_configured_output_resolution_ratio_get(E_Client *ec, double *ratio)
22 double cal_ratio_w, cal_ratio_h, cal_ratio;
28 if (!e_config->cursor_configured_output_resolution.use) return;
29 if (e_config->cursor_configured_output_resolution.w == 0) return;
30 if (e_config->cursor_configured_output_resolution.h == 0) return;
34 zone = e_comp_zone_find_by_ec(ec);
37 output = e_output_find(zone->output_id);
39 if (output->config.geom.w == 0) return;
40 if (output->config.geom.h == 0) return;
42 cal_ratio_w = (double)output->config.geom.w /
43 (double)e_config->cursor_configured_output_resolution.w;
45 cal_ratio_h = (double)output->config.geom.h /
46 (double)e_config->cursor_configured_output_resolution.h;
48 cal_ratio = MIN(cal_ratio_w, cal_ratio_h);
53 /* move the cursor image with the calcaultion of the hot spot */
55 _e_pointer_position_update(E_Pointer *ptr)
59 int cursor_w, cursor_h;
62 int hot_x = 0, hot_y = 0;
64 if (!ptr->o_ptr) return;
66 ec = e_comp_object_client_get(ptr->o_ptr);
67 EINA_SAFETY_ON_NULL_RETURN(ec);
69 rotation = ptr->rotation;
71 evas_object_geometry_get(ec->frame, NULL, NULL, &cursor_w, &cursor_h);
72 _e_pointer_configured_output_resolution_ratio_get(ec, &ratio);
76 hot_x = (int)((double)ptr->hot.x * ratio);
77 hot_y = (int)((double)ptr->hot.y * ratio);
109 evas_object_move(ptr->o_ptr, nx, ny);
113 _e_pointer_map_apply(E_Pointer *ptr)
121 EINA_SAFETY_ON_NULL_RETURN(ptr);
122 if (!ptr->o_ptr) return;
124 ec = e_comp_object_client_get(ptr->o_ptr);
125 EINA_SAFETY_ON_NULL_RETURN(ec);
127 _e_pointer_configured_output_resolution_ratio_get(ec, &ratio);
128 rotation = ptr->rotation;
130 if ((ratio == 1.0) &&
131 ((rotation == 0) || (rotation % 90 != 0) || (rotation / 90 > 3)))
133 e_client_map_enable_set(ec, EINA_FALSE);
134 e_client_map_set(ec, NULL);
138 evas_object_geometry_get(ec->frame, &x, &y, &w, &h);
141 EINA_SAFETY_ON_NULL_RETURN(map);
143 e_map_util_points_populate_from_object_full(map, ec->frame, 0);
147 e_map_point_coord_set(map, 1, x + (int)((double)w * ratio), y, 0);
148 e_map_point_coord_set(map, 2, x + (int)((double)w * ratio),
149 y + (int)((double)h * ratio), 0);
150 e_map_point_coord_set(map, 3, x, y + (int)((double)h * ratio), 0);
157 else if (rotation == 270)
160 e_map_util_rotate(map, rotation, x, y);
163 e_map_util_points_color_set(map, 255, 255, 255, 255);
164 e_map_util_object_move_sync_set(map, EINA_TRUE);
166 e_client_map_set(ec, map);
167 e_client_map_enable_set(ec, EINA_TRUE);
173 _e_pointer_cb_object_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
175 E_Pointer *ptr = (E_Pointer *)data;
178 ptr->device = E_POINTER_NONE;
184 _e_pointer_object_set(E_Pointer *ptr, Evas_Object *obj)
186 if (ptr->o_ptr == obj) return;
190 evas_object_event_callback_del_full(ptr->o_ptr, EVAS_CALLBACK_DEL, _e_pointer_cb_object_del, ptr);
196 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_pointer_cb_object_del, ptr);
202 _e_pointer_cb_free(E_Pointer *ptr)
204 _e_pointer_object_set(ptr, NULL);
206 _ptrs = eina_list_remove(_ptrs, ptr);
212 _e_pointer_hooks_clean(void)
218 for (x = 0; x < E_POINTER_HOOK_LAST; x++)
219 EINA_INLIST_FOREACH_SAFE(_e_pointer_hooks[x], l, ph)
221 if (!ph->delete_me) continue;
222 _e_pointer_hooks[x] = eina_inlist_remove(_e_pointer_hooks[x], EINA_INLIST_GET(ph));
226 _e_pointer_hooks_delete = 0;
230 _e_pointer_hook_call(E_Pointer_Hook_Point hookpoint, E_Pointer *ptr)
234 e_object_ref(E_OBJECT(ptr));
235 _e_pointer_hooks_walking++;
236 EINA_INLIST_FOREACH(_e_pointer_hooks[hookpoint], ph)
238 if (ph->delete_me) continue;
239 ph->func(ph->data, ptr);
240 if (e_object_is_del(E_OBJECT(ptr)))
243 _e_pointer_hooks_walking--;
244 if ((_e_pointer_hooks_walking == 0) && (_e_pointer_hooks_delete > 0))
245 _e_pointer_hooks_clean();
246 return !!e_object_unref(E_OBJECT(ptr));
252 _initted = EINA_TRUE;
257 e_pointer_shutdown(void)
259 _initted = EINA_FALSE;
264 e_pointer_canvas_new(Ecore_Evas *ee, Eina_Bool filled)
266 E_Pointer *ptr = NULL;
267 E_Output *output = NULL;
269 EINA_SAFETY_ON_FALSE_RETURN_VAL(ee, NULL);
270 if (!_initted) return NULL;
272 /* allocate space for new pointer */
273 if (!(ptr = E_OBJECT_ALLOC(E_Pointer, E_POINTER_TYPE, _e_pointer_cb_free)))
276 /* set default pointer properties */
277 ptr->canvas = EINA_TRUE;
278 ptr->w = ptr->h = e_config->cursor_size;
279 ptr->e_cursor = e_config->use_e_cursor;
280 output = e_output_find_by_index(0);
283 ptr->x = output->config.mode.w / 2;
284 ptr->y = output->config.mode.h / 2;
288 ptr->evas = ecore_evas_get(ee);
290 /* append this pointer to the list */
291 _ptrs = eina_list_append(_ptrs, ptr);
297 _e_pointer_object_hide(E_Pointer *ptr, Evas_Object *obj)
300 Eina_Bool res = EINA_FALSE;
302 ec = e_comp_object_client_get(obj);
303 if ((ec) && (!e_object_is_del(E_OBJECT(ec))))
306 ec->visible = EINA_FALSE;
307 ec->visibility.obscured = E_VISIBILITY_FULLY_OBSCURED;
308 ec->comp_data->mapped = EINA_FALSE;
309 ec->override = 1; /* ignore the previous cursor_ec */
312 /* hide cursor object */
313 if (evas_object_visible_get(obj))
316 evas_object_hide(obj);
319 _e_pointer_object_set(ptr, NULL);
320 ptr->device = E_POINTER_NONE;
326 _e_pointer_object_show(E_Pointer *ptr, Evas_Object *obj)
329 Eina_Bool res = EINA_FALSE;
331 ec = e_comp_object_client_get(obj);
332 if (ec && e_pixmap_usable_get(ec->pixmap))
335 ec->visible = EINA_TRUE;
336 ec->visibility.obscured = E_VISIBILITY_UNOBSCURED;
337 evas_object_geometry_set(ec->frame, ec->x, ec->y, ec->w, ec->h);
338 ec->comp_data->mapped = EINA_TRUE;
339 ec->override = 0; /* do not ignore the cursor_ec to set the image object */
342 /* show cursor object */
343 if (!evas_object_visible_get(obj))
346 evas_object_show(obj);
349 _e_pointer_object_set(ptr, obj);
355 e_pointer_object_set(E_Pointer *ptr, Evas_Object *obj, int x, int y)
357 Eina_Bool need_call_hide = EINA_FALSE;
359 EINA_SAFETY_ON_NULL_RETURN(ptr);
361 /* don't show cursor if in hidden mode */
362 if ((!e_config->show_cursor) || (!e_comp_wl->ptr.enabled))
364 if (ptr->o_ptr && _e_pointer_object_hide(ptr, ptr->o_ptr))
365 _e_pointer_hook_call(E_POINTER_HOOK_HIDE, ptr);
370 /* hide and unset the existed ptr->o_ptr */
371 if (ptr->o_ptr && (ptr->o_ptr != obj))
373 if (_e_pointer_object_hide(ptr, ptr->o_ptr))
374 need_call_hide = EINA_TRUE;
377 /* update the hot spot of the cursor */
381 /* if obj is not null, set the obj to ptr->o_ptr */
382 if (obj && (ptr->o_ptr != obj))
384 if (_e_pointer_object_show(ptr, obj))
386 need_call_hide = EINA_FALSE;
387 _e_pointer_hook_call(E_POINTER_HOOK_SHOW, ptr);
390 /* apply the cursor obj map */
391 _e_pointer_map_apply(ptr);
393 /* move the pointer to the current position */
394 _e_pointer_position_update(ptr);
398 _e_pointer_hook_call(E_POINTER_HOOK_HIDE, ptr);
402 e_pointer_touch_move(E_Pointer *ptr, int x, int y)
404 EINA_SAFETY_ON_NULL_RETURN(ptr);
406 if (!e_config->show_cursor) return;
408 /* save the current position */
412 if (ptr->device != E_POINTER_TOUCH) ptr->device = E_POINTER_TOUCH;
414 _e_pointer_position_update(ptr);
416 _e_pointer_hook_call(E_POINTER_HOOK_TOUCH_MOVE, ptr);
420 e_pointer_mouse_move(E_Pointer *ptr, int x, int y)
422 EINA_SAFETY_ON_NULL_RETURN(ptr);
424 if (!e_config->show_cursor) return;
426 /* save the current position */
430 if (ptr->device != E_POINTER_MOUSE) ptr->device = E_POINTER_MOUSE;
432 _e_pointer_position_update(ptr);
434 _e_pointer_hook_call(E_POINTER_HOOK_MOUSE_MOVE, ptr);
438 e_pointer_hide(E_Pointer *ptr)
440 EINA_SAFETY_ON_NULL_RETURN(ptr);
441 if (!ptr->o_ptr) return;
442 if (!evas_object_visible_get(ptr->o_ptr)) return;
444 evas_object_hide(ptr->o_ptr);
448 e_pointer_is_hidden(E_Pointer *ptr)
450 EINA_SAFETY_ON_NULL_RETURN_VAL(ptr, EINA_TRUE);
452 if (!e_config->show_cursor) return EINA_TRUE;
453 if (ptr->o_ptr && evas_object_visible_get(ptr->o_ptr)) return EINA_FALSE;
459 e_pointer_rotation_set(E_Pointer *ptr, int rotation)
464 EINA_SAFETY_ON_NULL_RETURN(ptr);
465 if (ptr->rotation == rotation) return;
467 ptr->rotation = rotation;
469 _e_pointer_map_apply(ptr);
470 _e_pointer_position_update(ptr);
472 EINA_LIST_FOREACH(e_input_devices_get(), l, dev)
473 e_input_device_pointer_rotation_set(dev, rotation);
477 e_pointer_position_get(E_Pointer *ptr, int *x, int *y)
479 EINA_SAFETY_ON_NULL_RETURN(ptr);
481 if (!e_config->show_cursor) return;
482 if (!ptr->o_ptr) return;
483 if (!evas_object_visible_get(ptr->o_ptr)) return;
490 e_pointer_get(E_Client *ec)
494 E_Client *ptr_ec = NULL;
496 if ((!ec) || (e_object_is_del(E_OBJECT(ec)))) return NULL;
498 EINA_LIST_FOREACH(_ptrs, l, ptr)
502 ptr_ec = e_comp_object_client_get(ptr->o_ptr);
511 E_API E_Pointer_Hook *
512 e_pointer_hook_add(E_Pointer_Hook_Point hookpoint, E_Pointer_Hook_Cb func, const void *data)
516 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_POINTER_HOOK_LAST, NULL);
517 ph = E_NEW(E_Pointer_Hook, 1);
518 if (!ph) return NULL;
519 ph->hookpoint = hookpoint;
521 ph->data = (void*)data;
522 _e_pointer_hooks[hookpoint] = eina_inlist_append(_e_pointer_hooks[hookpoint], EINA_INLIST_GET(ph));
527 e_pointer_hook_del(E_Pointer_Hook *ph)
530 if (_e_pointer_hooks_walking == 0)
532 _e_pointer_hooks[ph->hookpoint] = eina_inlist_remove(_e_pointer_hooks[ph->hookpoint], EINA_INLIST_GET(ph));
536 _e_pointer_hooks_delete++;