1 #include "e_pointer_intern.h"
2 #include "e_input_intern.h"
3 #include "e_client_intern.h"
6 static Eina_List *_ptrs = NULL;
7 static Eina_Bool _initted = EINA_FALSE;
9 static int _e_pointer_hooks_delete = 0;
10 static int _e_pointer_hooks_walking = 0;
11 static Eina_Inlist *_e_pointer_hooks[] =
13 [E_POINTER_HOOK_TOUCH_MOVE] = NULL,
14 [E_POINTER_HOOK_MOUSE_MOVE] = NULL,
15 [E_POINTER_HOOK_SHOW] = NULL,
16 [E_POINTER_HOOK_HIDE] = NULL,
20 _e_pointer_configured_output_resolution_ratio_get(E_Client *ec, double *ratio)
24 double cal_ratio_w, cal_ratio_h, cal_ratio;
30 if (!e_config->cursor_configured_output_resolution.use) return;
31 if (e_config->cursor_configured_output_resolution.w == 0) return;
32 if (e_config->cursor_configured_output_resolution.h == 0) return;
36 zone = e_comp_zone_find_by_ec(ec);
39 output = e_output_find(zone->output_id);
41 if (output->config.geom.w == 0) return;
42 if (output->config.geom.h == 0) return;
44 cal_ratio_w = (double)output->config.geom.w /
45 (double)e_config->cursor_configured_output_resolution.w;
47 cal_ratio_h = (double)output->config.geom.h /
48 (double)e_config->cursor_configured_output_resolution.h;
50 cal_ratio = MIN(cal_ratio_w, cal_ratio_h);
55 /* move the cursor image with the calcaultion of the hot spot */
57 _e_pointer_position_update(E_Pointer *ptr)
61 int cursor_w, cursor_h;
64 int hot_x = 0, hot_y = 0;
66 if (!ptr->o_ptr) return;
68 ec = e_comp_object_client_get(ptr->o_ptr);
69 EINA_SAFETY_ON_NULL_RETURN(ec);
71 rotation = ptr->rotation;
73 evas_object_geometry_get(ec->frame, NULL, NULL, &cursor_w, &cursor_h);
74 _e_pointer_configured_output_resolution_ratio_get(ec, &ratio);
78 hot_x = (int)((double)ptr->hot.x * ratio);
79 hot_y = (int)((double)ptr->hot.y * ratio);
111 evas_object_move(ptr->o_ptr, nx, ny);
115 _e_pointer_map_apply(E_Pointer *ptr)
123 EINA_SAFETY_ON_NULL_RETURN(ptr);
124 if (!ptr->o_ptr) return;
126 ec = e_comp_object_client_get(ptr->o_ptr);
127 EINA_SAFETY_ON_NULL_RETURN(ec);
129 _e_pointer_configured_output_resolution_ratio_get(ec, &ratio);
130 rotation = ptr->rotation;
132 if ((ratio == 1.0) &&
133 ((rotation == 0) || (rotation % 90 != 0) || (rotation / 90 > 3)))
135 e_client_map_enable_set(ec, EINA_FALSE);
136 e_client_map_set(ec, NULL);
140 evas_object_geometry_get(ec->frame, &x, &y, &w, &h);
143 EINA_SAFETY_ON_NULL_RETURN(map);
145 e_map_util_points_populate_from_object_full(map, ec->frame, 0);
149 e_map_point_coord_set(map, 1, x + (int)((double)w * ratio), y, 0);
150 e_map_point_coord_set(map, 2, x + (int)((double)w * ratio),
151 y + (int)((double)h * ratio), 0);
152 e_map_point_coord_set(map, 3, x, y + (int)((double)h * ratio), 0);
159 else if (rotation == 270)
162 e_map_util_rotate(map, rotation, x, y);
165 e_map_util_points_color_set(map, 255, 255, 255, 255);
166 e_map_util_object_move_sync_set(map, EINA_TRUE);
168 e_client_map_set(ec, map);
169 e_client_map_enable_set(ec, EINA_TRUE);
175 _e_pointer_cb_object_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
177 E_Pointer *ptr = (E_Pointer *)data;
180 ptr->device = E_POINTER_NONE;
186 _e_pointer_object_set(E_Pointer *ptr, Evas_Object *obj)
188 if (ptr->o_ptr == obj) return;
192 evas_object_event_callback_del_full(ptr->o_ptr, EVAS_CALLBACK_DEL, _e_pointer_cb_object_del, ptr);
198 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _e_pointer_cb_object_del, ptr);
204 _e_pointer_cb_free(E_Pointer *ptr)
206 _e_pointer_object_set(ptr, NULL);
208 _ptrs = eina_list_remove(_ptrs, ptr);
214 _e_pointer_hooks_clean(void)
220 for (x = 0; x < E_POINTER_HOOK_LAST; x++)
221 EINA_INLIST_FOREACH_SAFE(_e_pointer_hooks[x], l, ph)
223 if (!ph->delete_me) continue;
224 _e_pointer_hooks[x] = eina_inlist_remove(_e_pointer_hooks[x], EINA_INLIST_GET(ph));
228 _e_pointer_hooks_delete = 0;
232 _e_pointer_hook_call(E_Pointer_Hook_Point hookpoint, E_Pointer *ptr)
236 e_object_ref(E_OBJECT(ptr));
237 _e_pointer_hooks_walking++;
238 EINA_INLIST_FOREACH(_e_pointer_hooks[hookpoint], ph)
240 if (ph->delete_me) continue;
241 ph->func(ph->data, ptr);
242 if (e_object_is_del(E_OBJECT(ptr)))
245 _e_pointer_hooks_walking--;
246 if ((_e_pointer_hooks_walking == 0) && (_e_pointer_hooks_delete > 0))
247 _e_pointer_hooks_clean();
248 return !!e_object_unref(E_OBJECT(ptr));
254 _initted = EINA_TRUE;
259 e_pointer_shutdown(void)
261 _initted = EINA_FALSE;
266 e_pointer_canvas_new(Ecore_Evas *ee, Eina_Bool filled)
268 E_Pointer *ptr = NULL;
269 E_Output *output = NULL;
271 EINA_SAFETY_ON_FALSE_RETURN_VAL(ee, NULL);
272 if (!_initted) return NULL;
274 /* allocate space for new pointer */
275 if (!(ptr = E_OBJECT_ALLOC(E_Pointer, E_POINTER_TYPE, _e_pointer_cb_free)))
278 /* set default pointer properties */
279 ptr->canvas = EINA_TRUE;
280 ptr->w = ptr->h = e_config->cursor_size;
281 ptr->e_cursor = e_config->use_e_cursor;
282 output = e_output_find_by_index(0);
285 ptr->x = output->config.mode.w / 2;
286 ptr->y = output->config.mode.h / 2;
290 ptr->evas = ecore_evas_get(ee);
292 /* append this pointer to the list */
293 _ptrs = eina_list_append(_ptrs, ptr);
299 _e_pointer_object_hide(E_Pointer *ptr, Evas_Object *obj)
302 Eina_Bool res = EINA_FALSE;
304 ec = e_comp_object_client_get(obj);
305 if ((ec) && (!e_object_is_del(E_OBJECT(ec))))
308 ec->visible = EINA_FALSE;
309 ec->visibility.obscured = E_VISIBILITY_FULLY_OBSCURED;
310 ec->comp_data->mapped = EINA_FALSE;
311 ec->override = 1; /* ignore the previous cursor_ec */
314 /* hide cursor object */
315 if (evas_object_visible_get(obj))
318 evas_object_hide(obj);
319 evas_damage_rectangle_add(e_comp->evas, 0, 0, e_comp->w, e_comp->h);
322 _e_pointer_object_set(ptr, NULL);
323 ptr->device = E_POINTER_NONE;
329 _e_pointer_object_show(E_Pointer *ptr, Evas_Object *obj)
332 Eina_Bool res = EINA_FALSE;
334 ec = e_comp_object_client_get(obj);
335 if (ec && e_pixmap_usable_get(ec->pixmap))
338 ec->visible = EINA_TRUE;
339 ec->visibility.obscured = E_VISIBILITY_UNOBSCURED;
340 evas_object_geometry_set(ec->frame, ec->x, ec->y, ec->w, ec->h);
341 ec->comp_data->mapped = EINA_TRUE;
342 ec->override = 0; /* do not ignore the cursor_ec to set the image object */
345 /* show cursor object */
346 if (!evas_object_visible_get(obj))
349 evas_object_show(obj);
352 _e_pointer_object_set(ptr, obj);
358 e_pointer_object_set(E_Pointer *ptr, Evas_Object *obj, int x, int y)
360 Eina_Bool need_call_hide = EINA_FALSE;
362 EINA_SAFETY_ON_NULL_RETURN(ptr);
364 /* don't show cursor if in hidden mode */
365 if ((!e_config->show_cursor) || (!e_comp_wl->ptr.enabled))
367 if (ptr->o_ptr && _e_pointer_object_hide(ptr, ptr->o_ptr))
368 _e_pointer_hook_call(E_POINTER_HOOK_HIDE, ptr);
373 /* hide and unset the existed ptr->o_ptr */
374 if (ptr->o_ptr && (ptr->o_ptr != obj))
376 if (_e_pointer_object_hide(ptr, ptr->o_ptr))
377 need_call_hide = EINA_TRUE;
380 /* update the hot spot of the cursor */
384 /* if obj is not null, set the obj to ptr->o_ptr */
385 if (obj && (ptr->o_ptr != obj))
387 if (_e_pointer_object_show(ptr, obj))
389 need_call_hide = EINA_FALSE;
390 _e_pointer_hook_call(E_POINTER_HOOK_SHOW, ptr);
393 /* apply the cursor obj map */
394 _e_pointer_map_apply(ptr);
396 /* move the pointer to the current position */
397 _e_pointer_position_update(ptr);
401 _e_pointer_hook_call(E_POINTER_HOOK_HIDE, ptr);
405 e_pointer_touch_move(E_Pointer *ptr, int x, int y)
407 EINA_SAFETY_ON_NULL_RETURN(ptr);
409 if (!e_config->show_cursor) return;
411 /* save the current position */
415 if (ptr->device != E_POINTER_TOUCH) ptr->device = E_POINTER_TOUCH;
417 _e_pointer_position_update(ptr);
419 _e_pointer_hook_call(E_POINTER_HOOK_TOUCH_MOVE, ptr);
423 e_pointer_mouse_move(E_Pointer *ptr, int x, int y)
425 EINA_SAFETY_ON_NULL_RETURN(ptr);
427 if (!e_config->show_cursor) return;
429 /* save the current position */
433 if (ptr->device != E_POINTER_MOUSE) ptr->device = E_POINTER_MOUSE;
435 _e_pointer_position_update(ptr);
437 _e_pointer_hook_call(E_POINTER_HOOK_MOUSE_MOVE, ptr);
441 e_pointer_hide(E_Pointer *ptr)
443 EINA_SAFETY_ON_NULL_RETURN(ptr);
444 if (!ptr->o_ptr) return;
445 if (!evas_object_visible_get(ptr->o_ptr)) return;
447 evas_object_hide(ptr->o_ptr);
451 e_pointer_is_hidden(E_Pointer *ptr)
453 EINA_SAFETY_ON_NULL_RETURN_VAL(ptr, EINA_TRUE);
455 if (!e_config->show_cursor) return EINA_TRUE;
456 if (ptr->o_ptr && evas_object_visible_get(ptr->o_ptr)) return EINA_FALSE;
462 e_pointer_rotation_set(E_Pointer *ptr, int rotation)
467 EINA_SAFETY_ON_NULL_RETURN(ptr);
468 if (ptr->rotation == rotation) return;
470 ptr->rotation = rotation;
472 _e_pointer_map_apply(ptr);
473 _e_pointer_position_update(ptr);
475 EINA_LIST_FOREACH(e_input_devices_get(), l, dev)
476 e_input_device_pointer_rotation_set(dev, rotation);
480 e_pointer_position_get(E_Pointer *ptr, int *x, int *y)
482 EINA_SAFETY_ON_NULL_RETURN(ptr);
484 if (!e_config->show_cursor) return;
485 if (!ptr->o_ptr) return;
486 if (!evas_object_visible_get(ptr->o_ptr)) return;
493 e_pointer_get(E_Client *ec)
497 E_Client *ptr_ec = NULL;
499 if ((!ec) || (e_object_is_del(E_OBJECT(ec)))) return NULL;
501 EINA_LIST_FOREACH(_ptrs, l, ptr)
505 ptr_ec = e_comp_object_client_get(ptr->o_ptr);
514 E_API E_Pointer_Hook *
515 e_pointer_hook_add(E_Pointer_Hook_Point hookpoint, E_Pointer_Hook_Cb func, const void *data)
519 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_POINTER_HOOK_LAST, NULL);
520 ph = E_NEW(E_Pointer_Hook, 1);
521 if (!ph) return NULL;
522 ph->hookpoint = hookpoint;
524 ph->data = (void*)data;
525 _e_pointer_hooks[hookpoint] = eina_inlist_append(_e_pointer_hooks[hookpoint], EINA_INLIST_GET(ph));
530 e_pointer_hook_del(E_Pointer_Hook *ph)
533 if (_e_pointer_hooks_walking == 0)
535 _e_pointer_hooks[ph->hookpoint] = eina_inlist_remove(_e_pointer_hooks[ph->hookpoint], EINA_INLIST_GET(ph));
539 _e_pointer_hooks_delete++;