diff options
author | Mike Blumenkrantz <m.blumenkran@samsung.com> | 2013-09-11 13:03:31 +0100 |
---|---|---|
committer | Mike Blumenkrantz <m.blumenkran@samsung.com> | 2013-10-28 13:23:32 +0000 |
commit | c209b0f06a55eb6ccb6b449cfa1a5c858c35badf (patch) | |
tree | 8bdf33ff16813128fdedd271bc99180ab9a73be2 | |
parent | 18a4e27c7d534da1c51c659e8847b24f9169a967 (diff) | |
download | enlightenment-c209b0f06a55eb6ccb6b449cfa1a5c858c35badf.tar.gz |
wl pointers done
-rw-r--r-- | src/bin/e_comp_canvas.c | 1 | ||||
-rw-r--r-- | src/bin/e_comp_wl.c | 66 | ||||
-rw-r--r-- | src/bin/e_comp_x.c | 2 | ||||
-rw-r--r-- | src/bin/e_pointer.c | 874 | ||||
-rw-r--r-- | src/bin/e_pointer.h | 13 | ||||
-rw-r--r-- | src/bin/e_win.c | 10 | ||||
-rw-r--r-- | src/modules/wl_desktop_shell/e_mod_main.c | 29 | ||||
-rw-r--r-- | src/modules/wl_fb/e_mod_main.c | 1 | ||||
-rw-r--r-- | src/modules/wl_x11/e_mod_main.c | 2 |
9 files changed, 600 insertions, 398 deletions
diff --git a/src/bin/e_comp_canvas.c b/src/bin/e_comp_canvas.c index 50f9d9108c..3ca46befd7 100644 --- a/src/bin/e_comp_canvas.c +++ b/src/bin/e_comp_canvas.c @@ -129,7 +129,6 @@ e_comp_canvas_init(E_Comp *c) evas_event_callback_add(c->evas, EVAS_CALLBACK_RENDER_POST, _e_comp_canvas_render_post, c); c->ee_win = ecore_evas_window_get(c->ee); - c->pointer = e_pointer_window_new(c->man->root, 1); for (layer = 0; layer <= e_comp_canvas_layer_map(E_LAYER_MAX); layer++) { diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index c0f7c9dfb6..7d24fa4c40 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -1717,6 +1717,10 @@ _e_comp_wl_cb_surface_destroy(struct wl_resource *resource) buffer->ews = NULL; ews->buffers = eina_inlist_remove(ews->buffers, EINA_INLIST_GET(buffer)); } + if (e_comp_get(NULL)->pointer->pixmap == ews->pixmap) + { + e_pointer_image_set(e_comp_get(NULL)->pointer, NULL, 0, 0, 0, 0); + } e_pixmap_parent_window_set(ews->pixmap, NULL); e_pixmap_free(ews->pixmap); @@ -2256,53 +2260,17 @@ _e_comp_wl_pointer_configure(E_Wayland_Surface *ews, Evas_Coord x, Evas_Coord y, /* do we have a focused surface ? */ if (!input->wl.seat.pointer->focus) return; - if ((focus = wl_resource_get_user_data(input->wl.seat.pointer->focus))) - { - /* NB: Ideally, I wanted to use the e_pointer methods here so that - * the cursor would match the E theme, however Wayland currently - * provides NO Method to get the cursor name :( so we are stuck - * using the pixels from their cursor surface */ - - /* is it mapped ? */ - if ((focus->mapped) && (focus->ec)) - { - Ecore_Window win; - - /* try to get the ecore_window */ -#warning CURSOR BROKEN -#if 0 - if ((win = ecore_evas_window_get(focus->ee))) - { - E_Wayland_Buffer_Reference *ref; - struct wl_shm_buffer *shm_buffer; - void *pixels; - - ref = &ews->buffer_reference; - - shm_buffer = wl_shm_buffer_get(ref->buffer->wl.resource); - - /* grab the pixels from the cursor surface */ - if ((pixels = wl_shm_buffer_get_data(shm_buffer))) - { - Ecore_X_Cursor cur; - - /* create the new X cursor with this image */ - cur = ecore_x_cursor_new(win, pixels, w, h, - input->pointer.hot.x, - input->pointer.hot.y); - - /* set the cursor on this window */ - ecore_x_window_cursor_set(win, cur); + focus = wl_resource_get_user_data(input->wl.seat.pointer->focus); + if (!focus) return; + /* NB: Ideally, I wanted to use the e_pointer methods here so that + * the cursor would match the E theme, however Wayland currently + * provides NO Method to get the cursor name :( so we are stuck + * using the pixels from their cursor surface */ - /* free the cursor */ - ecore_x_cursor_free(cur); - } - else - ecore_x_window_cursor_set(win, 0); - } -#endif - } - } + /* is it mapped ? */ + if ((!focus->mapped) || (!focus->ec)) return; + e_pixmap_dirty(ews->pixmap); + e_pointer_image_set(focus->ec->comp->pointer, ews->pixmap, w, h, input->pointer.hot.x, input->pointer.hot.y); } static void @@ -2383,7 +2351,11 @@ _e_comp_wl_pointer_cb_cursor_set(struct wl_client *client, struct wl_resource *r input->pointer.surface = ews; /* if we don't have a pointer surface, we are done here */ - if (!ews) return; + if (!ews) + { + e_pointer_hide(e_comp_get(NULL)->pointer); + return; + } /* set the destroy listener */ wl_signal_add(&ews->wl.destroy_signal, diff --git a/src/bin/e_comp_x.c b/src/bin/e_comp_x.c index b392f886fa..09a4be8e77 100644 --- a/src/bin/e_comp_x.c +++ b/src/bin/e_comp_x.c @@ -4725,6 +4725,8 @@ _e_comp_x_setup(E_Comp *c, Ecore_X_Window root, int w, int h) } ecore_evas_lower(c->ee); + c->pointer = e_pointer_window_new(c->man->root, 1); + c->pointer->color = c->pointer->e_cursor && ecore_x_cursor_color_supported_get(); _e_comp_x_manage_windows(c); return !!c->bg_blank_object; diff --git a/src/bin/e_pointer.c b/src/bin/e_pointer.c index 87ccaa1d8e..5529c39b79 100644 --- a/src/bin/e_pointer.c +++ b/src/bin/e_pointer.c @@ -17,324 +17,100 @@ struct _E_Pointer_Stack static Eina_List *_e_pointers = NULL; static Eina_List *handlers = NULL; -static void _e_pointer_canvas_add(E_Pointer *p); static void _e_pointer_canvas_del(E_Pointer *p); -static void _e_pointer_cb_move(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info); static void _e_pointer_free(E_Pointer *p); static void _e_pointer_stack_free(E_Pointer_Stack *elem); static void _e_pointer_type_set(E_Pointer *p, const char *type); static void _e_pointer_active_handle(E_Pointer *p); -static Eina_Bool _e_pointer_cb_mouse_down(void *data, - int type, - void *event); -static Eina_Bool _e_pointer_cb_mouse_up(void *data, - int type, - void *event); -static Eina_Bool _e_pointer_cb_mouse_move(void *data, - int type, - void *event); -static Eina_Bool _e_pointer_cb_mouse_wheel(void *data, - int type, - void *event); static Eina_Bool _e_pointer_cb_idle_timer_pre(void *data); static Eina_Bool _e_pointer_cb_idle_timer_wait(void *data); static Eina_Bool _e_pointer_cb_idle_poller(void *data); -/* externally accessible functions */ -EINTERN int -e_pointer_init(void) -{ - handlers = - eina_list_append(handlers, - ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, - _e_pointer_cb_mouse_down, NULL)); - handlers = - eina_list_append(handlers, - ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, - _e_pointer_cb_mouse_up, NULL)); - handlers = - eina_list_append(handlers, - ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, - _e_pointer_cb_mouse_move, NULL)); - handlers = - eina_list_append(handlers, - ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL, - _e_pointer_cb_mouse_wheel, NULL)); - return 1; -} -EINTERN int -e_pointer_shutdown(void) -{ - E_FREE_LIST(handlers, ecore_event_handler_del); - return 1; -} - -EAPI E_Pointer * -e_pointer_window_new(Ecore_X_Window win, - int filled) -{ - E_Pointer *p = NULL; - - if (!win) return NULL; - p = E_OBJECT_ALLOC(E_Pointer, E_POINTER_TYPE, _e_pointer_free); - if (!p) return NULL; - - p->e_cursor = e_config->use_e_cursor; - p->win = win; - p->color = 0; - if (e_config->use_e_cursor) - if (ecore_x_cursor_color_supported_get()) p->color = 1; - - ecore_x_cursor_size_set(e_config->cursor_size * 3 / 4); - if (filled) e_pointer_type_push(p, p, "default"); - _e_pointers = eina_list_append(_e_pointers, p); - return p; -} - -EAPI void -e_pointers_size_set(int size) +static void +_e_pointer_hot_update(E_Pointer *p, int x, int y) { - Eina_List *l; - E_Pointer *p; - - if (!e_config->show_cursor) return; - EINA_LIST_FOREACH(_e_pointers, l, p) + if ((p->hot.x != x) || (p->hot.y != y)) { - Evas_Engine_Info_Buffer *einfo; - - if (p->evas) - { - p->w = p->h = size; - evas_output_size_set(p->evas, p->w, p->h); - evas_output_viewport_set(p->evas, 0, 0, p->w, p->h); - - p->pixels = realloc(p->pixels, p->w * p->h * sizeof(int)); - - einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(p->evas); - if (einfo) - { - einfo->info.dest_buffer = p->pixels; - einfo->info.dest_buffer_row_bytes = p->w * sizeof(int); - evas_engine_info_set(p->evas, (Evas_Engine_Info *)einfo); - } - - evas_object_move(p->pointer_object, 0, 0); - evas_object_resize(p->pointer_object, p->w, p->h); - } - else - { - const char *type; - - ecore_x_cursor_size_set(e_config->cursor_size * 3 / 4); - type = p->type; - if (type) - { - p->type = NULL; - _e_pointer_type_set(p, type); - eina_stringshare_del(type); - } - } + p->hot.x = x; + p->hot.y = y; + p->hot.update = 1; } } -EAPI void -e_pointer_hide(E_Pointer *p) +static void +_e_pointer_active(E_Pointer *p) { - if (!p) return; - if (p->win) ecore_x_window_cursor_set(p->win, 0); - if (p->evas) _e_pointer_canvas_del(p); + if (!p->idle) return; + if (p->pointer_object) + edje_object_signal_emit(p->pointer_object, + "e,state,mouse,active", "e"); + p->idle = 0; } -EAPI void -e_pointer_type_push(E_Pointer *p, - void *obj, - const char *type) +static void +_e_pointer_idle(E_Pointer *p) { - E_Pointer_Stack *stack; - - if (!p) return; - p->e_cursor = e_config->use_e_cursor; - - _e_pointer_type_set(p, type); - - p->obj = obj; - - stack = E_NEW(E_Pointer_Stack, 1); - if (stack) - { - stack->type = eina_stringshare_add(p->type); - stack->obj = p->obj; - p->stack = eina_list_prepend(p->stack, stack); - } + if (p->idle) return; + if (p->pointer_object) + edje_object_signal_emit(p->pointer_object, "e,state,mouse,idle", "e"); + p->idle = 1; } -EAPI void -e_pointer_type_pop(E_Pointer *p, - void *obj, - const char *type) +static void +_e_pointer_cb_show(void *data, + Evas *e __UNUSED__, + Evas_Object *obj, + void *event_info __UNUSED__) { - Eina_List *l, *l_next; - E_Pointer_Stack *stack; - - if (!p) return; - EINA_LIST_FOREACH_SAFE(p->stack, l, l_next, stack) - { - if ((stack->obj == obj) && ((!type) || (!strcmp(stack->type, type)))) - { - _e_pointer_stack_free(stack); - p->stack = eina_list_remove_list(p->stack, l); - if (type) break; - } - } - - if (!p->stack) - { - if (p->evas) _e_pointer_canvas_del(p); - ecore_x_window_cursor_set(p->win, 0); - if (p->type) eina_stringshare_del(p->type); - p->type = NULL; - return; - } - - stack = eina_list_data_get(p->stack); - _e_pointer_type_set(p, stack->type); - - if (p->type) eina_stringshare_del(p->type); - p->type = eina_stringshare_add(stack->type); - p->obj = stack->obj; - - /* try the default cursor next time */ - p->e_cursor = e_config->use_e_cursor; + int x, y; + edje_object_part_geometry_get(obj, "e.swallow.hotspot", + &x, &y, NULL, NULL); + _e_pointer_hot_update(data, x, y); } -EAPI void -e_pointer_idler_before(void) +static void +_e_pointer_cb_move(void *data, + Evas *e __UNUSED__, + Evas_Object *obj __UNUSED__, + void *event_info __UNUSED__) { - Eina_List *l; E_Pointer *p; + Evas_Coord x, y; if (!e_config->show_cursor) return; - EINA_LIST_FOREACH(_e_pointers, l, p) - { - Eina_List *updates; - - if (!p->e_cursor) continue; - if (!p->evas) continue; - if (!p->win) continue; - - updates = evas_render_updates(p->evas); - if ((updates) || (p->hot.update)) - { - Ecore_X_Cursor cur; - - cur = ecore_x_cursor_new(p->win, p->pixels, p->w, p->h, - p->hot.x, p->hot.y); - ecore_x_window_cursor_set(p->win, cur); - ecore_x_cursor_free(cur); - evas_render_updates_free(updates); - p->hot.update = 0; - } - } -} - -/** - * mode_{push,pop} functions are ONLY for use with compositor objects. - * these functions should NEVER be used for setting internal window pointers!!!! - */ -EAPI void -e_pointer_mode_push(void *obj, E_Pointer_Mode mode) -{ - switch (mode) - { - case E_POINTER_RESIZE_TL: - e_pointer_type_push(e_comp_get(obj)->pointer, obj, "resize_tl"); - break; - - case E_POINTER_RESIZE_T: - e_pointer_type_push(e_comp_get(obj)->pointer, obj, "resize_t"); - break; - - case E_POINTER_RESIZE_TR: - e_pointer_type_push(e_comp_get(obj)->pointer, obj, "resize_tr"); - break; - - case E_POINTER_RESIZE_R: - e_pointer_type_push(e_comp_get(obj)->pointer, obj, "resize_r"); - break; - - case E_POINTER_RESIZE_BR: - e_pointer_type_push(e_comp_get(obj)->pointer, obj, "resize_br"); - break; - - case E_POINTER_RESIZE_B: - e_pointer_type_push(e_comp_get(obj)->pointer, obj, "resize_b"); - break; - - case E_POINTER_RESIZE_BL: - e_pointer_type_push(e_comp_get(obj)->pointer, obj, "resize_bl"); - break; - - case E_POINTER_RESIZE_L: - e_pointer_type_push(e_comp_get(obj)->pointer, obj, "resize_l"); - break; - - case E_POINTER_MOVE: - e_pointer_type_push(e_comp_get(obj)->pointer, obj, "move"); - break; - - default: break; - } + if (!(p = data)) return; + if (!p->e_cursor) return; + if (!evas_object_visible_get(p->pointer_object)) return; + edje_object_part_geometry_get(p->pointer_object, "e.swallow.hotspot", + &x, &y, NULL, NULL); + _e_pointer_hot_update(p, x, y); } -EAPI void -e_pointer_mode_pop(void *obj, E_Pointer_Mode mode) +static void +_e_pointer_canvas_resize(E_Pointer *p, int w, int h) { - switch (mode) - { - case E_POINTER_RESIZE_TL: - e_pointer_type_pop(e_comp_get(obj)->pointer, obj, "resize_tl"); - break; - - case E_POINTER_RESIZE_T: - e_pointer_type_pop(e_comp_get(obj)->pointer, obj, "resize_t"); - break; - - case E_POINTER_RESIZE_TR: - e_pointer_type_pop(e_comp_get(obj)->pointer, obj, "resize_tr"); - break; - - case E_POINTER_RESIZE_R: - e_pointer_type_pop(e_comp_get(obj)->pointer, obj, "resize_r"); - break; - - case E_POINTER_RESIZE_BR: - e_pointer_type_pop(e_comp_get(obj)->pointer, obj, "resize_br"); - break; + Evas_Engine_Info_Buffer *einfo; - case E_POINTER_RESIZE_B: - e_pointer_type_pop(e_comp_get(obj)->pointer, obj, "resize_b"); - break; + if ((p->w == w) && (p->h == h)) return; + p->w = w, p->h = h; + evas_output_size_set(p->evas, p->w, p->h); + evas_output_viewport_set(p->evas, 0, 0, p->w, p->h); - case E_POINTER_RESIZE_BL: - e_pointer_type_pop(e_comp_get(obj)->pointer, obj, "resize_bl"); - break; + p->pixels = realloc(p->pixels, p->w * p->h * sizeof(int)); - case E_POINTER_RESIZE_L: - e_pointer_type_pop(e_comp_get(obj)->pointer, obj, "resize_l"); - break; + einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(p->evas); - case E_POINTER_MOVE: - e_pointer_type_pop(e_comp_get(obj)->pointer, obj, "move"); - break; + EINA_SAFETY_ON_NULL_RETURN(einfo); + einfo->info.dest_buffer = p->pixels; + einfo->info.dest_buffer_row_bytes = p->w * sizeof(int); + evas_engine_info_set(p->evas, (Evas_Engine_Info *)einfo); - default: break; - } + evas_object_move(p->pointer_object, 0, 0); + evas_object_resize(p->pointer_object, p->w, p->h); + if (p->pointer_image) evas_object_resize(p->pointer_image, p->w, p->h); } /* local subsystem functions */ @@ -391,6 +167,8 @@ _e_pointer_canvas_add(E_Pointer *p) p->hot_object = o; evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _e_pointer_cb_move, p); + evas_object_event_callback_add(o, EVAS_CALLBACK_SHOW, + _e_pointer_cb_show, p); /* init edje */ evas_object_move(p->pointer_object, 0, 0); evas_object_resize(p->pointer_object, p->w, p->h); @@ -401,37 +179,11 @@ static void _e_pointer_canvas_del(E_Pointer *p) { if (!p) return; - if (p->pointer_object) evas_object_del(p->pointer_object); - if (p->hot_object) evas_object_del(p->hot_object); - if (p->evas) evas_free(p->evas); - free(p->pixels); - p->pointer_object = NULL; - p->hot_object = NULL; + E_FREE_FUNC(p->pointer_object, evas_object_del); + E_FREE_FUNC(p->hot_object, evas_object_del); + if (p->evas && (!p->canvas)) evas_free(p->evas); p->evas = NULL; - p->pixels = NULL; -} - -static void -_e_pointer_cb_move(void *data, - Evas *e __UNUSED__, - Evas_Object *obj __UNUSED__, - void *event_info __UNUSED__) -{ - E_Pointer *p; - Evas_Coord x, y; - - if (!e_config->show_cursor) return; - - if (!(p = data)) return; - if (!p->e_cursor) return; - edje_object_part_geometry_get(p->pointer_object, "e.swallow.hotspot", - &x, &y, NULL, NULL); - if ((p->hot.x != x) || (p->hot.y != y)) - { - p->hot.x = x; - p->hot.y = y; - p->hot.update = 1; - } + E_FREE(p->pixels); } static void @@ -441,6 +193,7 @@ _e_pointer_free(E_Pointer *p) _e_pointers = eina_list_remove(_e_pointers, p); _e_pointer_canvas_del(p); + E_FREE_FUNC(p->pointer_image, evas_object_del); E_FREE_LIST(p->stack, _e_pointer_stack_free); @@ -468,14 +221,19 @@ _e_pointer_type_set(E_Pointer *p, if (!p) return; /* Check if this pointer is already set */ - if ((p->type) && (!strcmp(p->type, type))) return; + if (!e_util_strcmp(p->type, type)) return; eina_stringshare_replace(&p->type, type); /* Do not set type if in "hidden mode" */ if (!e_config->show_cursor) { - ecore_x_window_cursor_set(p->win, 0); +#ifdef WAYLAND_ONLY + evas_object_hide(p->pointer_image); +#else + if (!p->canvas) + ecore_x_window_cursor_set(p->win, 0); +#endif return; } @@ -504,12 +262,16 @@ _e_pointer_type_set(E_Pointer *p, p->hot.y = y; } p->hot.update = 1; + evas_object_show(p->pointer_object); return; } fallback: +#ifndef WAYLAND_ONLY + if (p->canvas) return; { Ecore_X_Cursor cursor = 0; + E_FREE_FUNC(p->pointer_image, evas_object_del); if (p->evas) _e_pointer_canvas_del(p); if (!strcmp(type, "move")) cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_FLEUR); @@ -552,31 +314,24 @@ fallback: ecore_x_window_cursor_set(p->win, cursor); if (cursor) ecore_x_cursor_free(cursor); } +#endif } static void _e_pointer_active_handle(E_Pointer *p) { if (!p) return; + _e_pointer_active(p); + if (p->canvas) + { + ecore_timer_reset(p->idle_timer); + return; + } /* we got some mouse event - if there was an idle timer emit an active * signal as we WERE idle, NOW we are active */ - if (p->idle_timer) - { - ecore_timer_del(p->idle_timer); - p->idle_timer = NULL; - } - if (p->idle_poller) - { - ecore_poller_del(p->idle_poller); - p->idle_poller = NULL; - } - if (p->idle) - { - if (p->pointer_object) - edje_object_signal_emit(p->pointer_object, "e,state,mouse,active", "e"); - p->idle = 0; - } + E_FREE_FUNC(p->idle_timer, ecore_timer_del); + E_FREE_FUNC(p->idle_poller, ecore_poller_del); if (e_powersave_mode_get() >= E_POWERSAVE_MODE_MEDIUM) return; /* and schedule a pre-idle check in 1 second if no more events happen */ if (!e_config->idle_cursor) return; @@ -628,7 +383,7 @@ _e_pointer_cb_mouse_up(void *data __UNUSED__, static Eina_Bool _e_pointer_cb_mouse_move(void *data __UNUSED__, int type __UNUSED__, - void *event __UNUSED__) + Ecore_Event_Mouse_Move *ev) { Eina_List *l; E_Pointer *p; @@ -642,6 +397,13 @@ _e_pointer_cb_mouse_move(void *data __UNUSED__, edje_object_signal_emit(p->pointer_object, "e,action,mouse,move", "e"); } + if (p->canvas) + { + evas_object_move(p->pointer_image, + e_comp_canvas_x_root_adjust(e_comp_get(NULL), ev->root.x), + e_comp_canvas_y_root_adjust(e_comp_get(NULL), ev->root.y) + ); + } } return ECORE_CALLBACK_PASS_ON; } @@ -668,6 +430,18 @@ _e_pointer_cb_mouse_wheel(void *data __UNUSED__, } static Eina_Bool +_e_pointer_idle_timer(void *data) +{ + E_Pointer *p = data; + + if (e_config->idle_cursor) + _e_pointer_idle(p); + + return EINA_TRUE; +} + +#ifndef WAYLAND_ONLY +static Eina_Bool _e_pointer_cb_idle_timer_pre(void *data) { E_Pointer *p; @@ -677,10 +451,16 @@ _e_pointer_cb_idle_timer_pre(void *data) ecore_x_pointer_xy_get(p->win, &x, &y); p->x = x; p->y = y; + if (p->canvas) + evas_object_move(p->pointer_image, + e_comp_canvas_x_root_adjust(e_comp_get(NULL), x), + e_comp_canvas_y_root_adjust(e_comp_get(NULL), y) + ); p->idle_timer = ecore_timer_loop_add(4.0, _e_pointer_cb_idle_timer_wait, p); return ECORE_CALLBACK_CANCEL; } + static Eina_Bool _e_pointer_cb_idle_timer_wait(void *data) { @@ -725,22 +505,438 @@ _e_pointer_cb_idle_poller(void *data) p->x = x; p->y = y; if (p->idle) - { - if (p->pointer_object) - edje_object_signal_emit(p->pointer_object, - "e,state,mouse,active", "e"); - p->idle = 0; - } + _e_pointer_active(p); + /* use poller to check from now on */ return ECORE_CALLBACK_RENEW; } /* we are idle - report it if not idle before */ if (!p->idle) + _e_pointer_idle(p); + return ECORE_CALLBACK_RENEW; +} +#endif + + +/* externally accessible functions */ +EINTERN int +e_pointer_init(void) +{ + E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_MOUSE_BUTTON_DOWN, + _e_pointer_cb_mouse_down, NULL); + E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_MOUSE_BUTTON_UP, + _e_pointer_cb_mouse_up, NULL); + E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_MOUSE_MOVE, + _e_pointer_cb_mouse_move, NULL); + E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_MOUSE_WHEEL, + _e_pointer_cb_mouse_wheel, NULL); + return 1; +} + +EINTERN int +e_pointer_shutdown(void) +{ + E_FREE_LIST(handlers, ecore_event_handler_del); + return 1; +} + +EAPI E_Pointer * +e_pointer_window_new(Ecore_Window win, + int filled) +{ + E_Pointer *p = NULL; + + EINA_SAFETY_ON_FALSE_RETURN_VAL(win, NULL); + p = E_OBJECT_ALLOC(E_Pointer, E_POINTER_TYPE, _e_pointer_free); + if (!p) return NULL; + + p->e_cursor = e_config->use_e_cursor; + p->win = win; + p->color = 0; + +#ifndef WAYLAND_ONLY + ecore_x_cursor_size_set(e_config->cursor_size * 3 / 4); +#endif + if (filled) e_pointer_type_push(p, p, "default"); + _e_pointers = eina_list_append(_e_pointers, p); + return p; +} + +EAPI E_Pointer * +e_pointer_canvas_new(Evas *e, int filled) +{ + E_Pointer *p = NULL; + + EINA_SAFETY_ON_NULL_RETURN_VAL(e, NULL); + p = E_OBJECT_ALLOC(E_Pointer, E_POINTER_TYPE, _e_pointer_free); + if (!p) return NULL; + + p->e_cursor = p->canvas = 1; + p->color = 1; + p->w = p->h = e_config->cursor_size; + p->idle_timer = ecore_timer_loop_add(4.0, _e_pointer_idle_timer, p); + p->pointer_image = evas_object_image_filled_add(e); + evas_object_pass_events_set(p->pointer_image, 1); + evas_object_layer_set(p->pointer_image, EVAS_LAYER_MAX); + evas_object_image_alpha_set(p->pointer_image, 1); + evas_object_show(p->pointer_image); + + if (filled) e_pointer_type_push(p, p, "default"); + _e_pointers = eina_list_append(_e_pointers, p); + return p; +} + +EAPI void +e_pointer_image_set(E_Pointer *p, E_Pixmap *cp, int w, int h, int hot_x, int hot_y) +{ + void *img = NULL; + + EINA_SAFETY_ON_NULL_RETURN(p); + + p->pixmap = cp; + if (cp) { - if (p->pointer_object) - edje_object_signal_emit(p->pointer_object, "e,state,mouse,idle", "e"); - p->idle = 1; + e_pixmap_refresh(cp); + e_pixmap_image_refresh(cp); + img = e_pixmap_image_data_get(cp); + } + else + { + Eina_Stringshare *type; + + type = p->type; + if (type) + { + p->type = NULL; + _e_pointer_type_set(p, type); + eina_stringshare_del(type); + } + } + _e_pointer_hot_update(p, hot_x, hot_y); + + if (p->evas) + { + /* e cursor: edje or image */ + if (!p->canvas) + _e_pointer_canvas_resize(p, w, h); + evas_object_hide(p->pointer_object); + if (!p->pointer_image) + { + p->pointer_image = evas_object_image_filled_add(p->evas); + evas_object_image_alpha_set(p->pointer_image, 1); + } + evas_object_image_size_set(p->pointer_image, w, h); + evas_object_image_data_set(p->pointer_image, img); + evas_object_resize(p->pointer_image, w, h); + evas_object_show(p->pointer_image); + } +#ifndef WAYLAND_ONLY + else + { + Ecore_X_Cursor cur; + + if (cp) + cur = ecore_x_cursor_new(p->win, img, w, h, + p->hot.x, p->hot.y); + ecore_x_window_cursor_set(p->win, cp ? cur : 0); + if (cp) + ecore_x_cursor_free(cur); + } +#endif +} + +EAPI void +e_pointers_size_set(int size) +{ + Eina_List *l; + E_Pointer *p; + + if (!e_config->show_cursor) return; + EINA_LIST_FOREACH(_e_pointers, l, p) + { + Eina_Stringshare *type; + if (p->evas) + { + if (!p->canvas) + _e_pointer_canvas_resize(p, size, size); + } +#ifndef WAYLAND_ONLY + else + ecore_x_cursor_size_set(e_config->cursor_size * 3 / 4); +#endif + type = p->type; + if (type) + { + p->type = NULL; + _e_pointer_type_set(p, type); + eina_stringshare_del(type); + } + } +} + +EAPI void +e_pointer_hide(E_Pointer *p) +{ + if (!p) return; +#ifdef WAYLAND_ONLY +#else + if (p->win) ecore_x_window_cursor_set(p->win, 0); +#endif + if (p->canvas) + evas_object_hide(p->pointer_image); + else + E_FREE_FUNC(p->pointer_image, evas_object_del); + if (p->evas) _e_pointer_canvas_del(p); +} + +EAPI void +e_pointer_type_push(E_Pointer *p, + void *obj, + const char *type) +{ + E_Pointer_Stack *stack; + + if (!p) return; + p->e_cursor = e_config->use_e_cursor; + + if (!p->canvas) + { + evas_object_hide(p->pointer_image); +#ifndef WAYLAND_ONLY + if (p->blocks) + { + ecore_x_cursor_size_set(e_config->cursor_size * 3 / 4); + _e_pointer_canvas_resize(p, e_config->cursor_size, e_config->cursor_size); + } +#endif + } + _e_pointer_type_set(p, type); + + p->obj = obj; + + stack = E_NEW(E_Pointer_Stack, 1); + stack->type = eina_stringshare_ref(p->type); + stack->obj = p->obj; + p->stack = eina_list_prepend(p->stack, stack); +} + +EAPI void +e_pointer_type_pop(E_Pointer *p, + void *obj, + const char *type) +{ + Eina_List *l, *l_next; + E_Pointer_Stack *stack; + + if (!p) return; + EINA_LIST_FOREACH_SAFE(p->stack, l, l_next, stack) + { + if ((stack->obj == obj) && ((!type) || (!e_util_strcmp(stack->type, type)))) + { + _e_pointer_stack_free(stack); + p->stack = eina_list_remove_list(p->stack, l); + if (type) break; + } + } + + if (!p->stack) + { + e_pointer_hide(p); + eina_stringshare_replace(&p->type, NULL); + return; + } + + stack = eina_list_data_get(p->stack); + _e_pointer_type_set(p, stack->type); + if ((p->blocks) && (stack->obj == p)) + { + evas_object_hide(p->pointer_object); + evas_object_show(p->pointer_image); +#ifndef WAYLAND_ONLY + if (!p->canvas) + { + int w, h; + + e_pixmap_size_get(p->pixmap, &w, &h); + _e_pointer_canvas_resize(p, w, h); + } +#endif + } + + eina_stringshare_refplace(&p->type, stack->type); + p->obj = stack->obj; + + /* try the default cursor next time */ + p->e_cursor = e_config->use_e_cursor; +} + +EAPI void +e_pointer_idler_before(void) +{ +#ifndef WAYLAND_ONLY + Eina_List *l; + E_Pointer *p; + + if (!e_config->show_cursor) return; + EINA_LIST_FOREACH(_e_pointers, l, p) + { + Eina_List *updates; + + if (!p->e_cursor) continue; + if (!p->evas) continue; + + updates = evas_render_updates(p->evas); + if ((updates) || (p->hot.update)) + { + if (p->canvas) + { + if (!p->blocks) + { + evas_object_resize(p->pointer_image, p->w, p->h); + evas_object_image_size_set(p->pointer_image, p->w, p->h); + evas_object_image_data_set(p->pointer_image, p->pixels); + } + } + else + { + Ecore_X_Cursor cur; + + cur = ecore_x_cursor_new(p->win, p->pixels, p->w, p->h, + p->hot.x, p->hot.y); + ecore_x_window_cursor_set(p->win, cur); + ecore_x_cursor_free(cur); + } + evas_render_updates_free(updates); + } + p->hot.update = 0; + } +#endif +} + +/** + * mode_{push,pop} functions are ONLY for use with compositor objects. + * these functions should NEVER be used for setting internal window pointers!!!! + */ +EAPI void +e_pointer_mode_push(void *obj, E_Pointer_Mode mode) +{ + switch (mode) + { + case E_POINTER_RESIZE_TL: + e_pointer_type_push(e_comp_get(obj)->pointer, obj, "resize_tl"); + break; + + case E_POINTER_RESIZE_T: + e_pointer_type_push(e_comp_get(obj)->pointer, obj, "resize_t"); + break; + + case E_POINTER_RESIZE_TR: + e_pointer_type_push(e_comp_get(obj)->pointer, obj, "resize_tr"); + break; + + case E_POINTER_RESIZE_R: + e_pointer_type_push(e_comp_get(obj)->pointer, obj, "resize_r"); + break; + + case E_POINTER_RESIZE_BR: + e_pointer_type_push(e_comp_get(obj)->pointer, obj, "resize_br"); + break; + + case E_POINTER_RESIZE_B: + e_pointer_type_push(e_comp_get(obj)->pointer, obj, "resize_b"); + break; + + case E_POINTER_RESIZE_BL: + e_pointer_type_push(e_comp_get(obj)->pointer, obj, "resize_bl"); + break; + + case E_POINTER_RESIZE_L: + e_pointer_type_push(e_comp_get(obj)->pointer, obj, "resize_l"); + break; + + case E_POINTER_MOVE: + e_pointer_type_push(e_comp_get(obj)->pointer, obj, "move"); + break; + + default: break; } - return ECORE_CALLBACK_RENEW; } +EAPI void +e_pointer_mode_pop(void *obj, E_Pointer_Mode mode) +{ + switch (mode) + { + case E_POINTER_RESIZE_TL: + e_pointer_type_pop(e_comp_get(obj)->pointer, obj, "resize_tl"); + break; + + case E_POINTER_RESIZE_T: + e_pointer_type_pop(e_comp_get(obj)->pointer, obj, "resize_t"); + break; + + case E_POINTER_RESIZE_TR: + e_pointer_type_pop(e_comp_get(obj)->pointer, obj, "resize_tr"); + break; + + case E_POINTER_RESIZE_R: + e_pointer_type_pop(e_comp_get(obj)->pointer, obj, "resize_r"); + break; + + case E_POINTER_RESIZE_BR: + e_pointer_type_pop(e_comp_get(obj)->pointer, obj, "resize_br"); + break; + + case E_POINTER_RESIZE_B: + e_pointer_type_pop(e_comp_get(obj)->pointer, obj, "resize_b"); + break; + + case E_POINTER_RESIZE_BL: + e_pointer_type_pop(e_comp_get(obj)->pointer, obj, "resize_bl"); + break; + + case E_POINTER_RESIZE_L: + e_pointer_type_pop(e_comp_get(obj)->pointer, obj, "resize_l"); + break; + + case E_POINTER_MOVE: + e_pointer_type_pop(e_comp_get(obj)->pointer, obj, "move"); + break; + + default: break; + } +} + +EAPI void +e_pointer_block_add(E_Pointer *p) +{ + if (!p->blocks) + { + evas_object_hide(p->pointer_object); + if (p->pixmap) + { + int w, h; + + e_pixmap_size_get(p->pixmap, &w, &h); + e_pointer_image_set(p, p->pixmap, w, h, p->hot.x, p->hot.y); + } + } + p->blocks++; + +} + +EAPI void +e_pointer_block_del(E_Pointer *p) +{ + if (!p->blocks) return; + p->blocks--; + if (p->blocks) return; + e_pointers_size_set(e_config->cursor_size); + if (p->pointer_image) + { + if (p->canvas) + evas_object_resize(p->pointer_image, p->w, p->h); + else + evas_object_hide(p->pointer_image); + } +} diff --git a/src/bin/e_pointer.h b/src/bin/e_pointer.h index f96f6ba78a..d808b17d34 100644 --- a/src/bin/e_pointer.h +++ b/src/bin/e_pointer.h @@ -31,16 +31,20 @@ struct _E_Pointer unsigned char e_cursor : 1; unsigned char color : 1; unsigned char idle : 1; + unsigned char canvas : 1; Evas *evas; + E_Pixmap *pixmap; Evas_Object *pointer_object; + Evas_Object *pointer_image; Evas_Object *hot_object; int *pixels; - Ecore_X_Window win; + Ecore_Window win; int w, h; Ecore_Timer *idle_timer; Ecore_Poller *idle_poller; int x, y; + unsigned int blocks; const char *type; void *obj; @@ -54,8 +58,10 @@ struct _E_Pointer EINTERN int e_pointer_init(void); EINTERN int e_pointer_shutdown(void); -EAPI E_Pointer *e_pointer_window_new(Ecore_X_Window win, int filled); +EAPI E_Pointer *e_pointer_window_new(Ecore_Window win, int filled); EAPI void e_pointer_hide(E_Pointer *p); +EAPI E_Pointer *e_pointer_canvas_new(Evas *e, int filled); +EAPI void e_pointer_image_set(E_Pointer *p, E_Pixmap *cp, int w, int h, int hot_x, int hot_y); EAPI void e_pointer_type_push(E_Pointer *p, void *obj, const char *type); EAPI void e_pointer_type_pop(E_Pointer *p, void *obj, const char *type); EAPI void e_pointers_size_set(int size); @@ -64,5 +70,8 @@ EAPI void e_pointer_idler_before(void); EAPI void e_pointer_mode_push(void *obj, E_Pointer_Mode mode); EAPI void e_pointer_mode_pop(void *obj, E_Pointer_Mode mode); +EAPI void e_pointer_block_add(E_Pointer *p); +EAPI void e_pointer_block_del(E_Pointer *p); + #endif #endif diff --git a/src/bin/e_win.c b/src/bin/e_win.c index d2b50fe31e..731d69979b 100644 --- a/src/bin/e_win.c +++ b/src/bin/e_win.c @@ -327,9 +327,13 @@ e_win_new(E_Comp *c) win->max_aspect = 0.0; wins = eina_list_append(wins, win); -#warning FIXME WL POINTERS - if (c->man->root) - win->pointer = e_pointer_window_new(win->evas_win, 1); +#ifndef WAYLAND_ONLY + if (c->comp_type == E_PIXMAP_TYPE_X) + { + win->pointer = e_pointer_window_new(win->evas_win, 1); + win->pointer->color = c->pointer->color; + } +#endif return win; } diff --git a/src/modules/wl_desktop_shell/e_mod_main.c b/src/modules/wl_desktop_shell/e_mod_main.c index f344b904d0..d9d3ff24f5 100644 --- a/src/modules/wl_desktop_shell/e_mod_main.c +++ b/src/modules/wl_desktop_shell/e_mod_main.c @@ -43,6 +43,7 @@ static void _e_wl_shell_shell_surface_cb_destroy(struct wl_listener *listener, v static int _e_wl_shell_shell_surface_cb_ping_timeout(void *data); static void _e_wl_shell_render_post(void *data, Evas *e EINA_UNUSED, void *event EINA_UNUSED); +static void _e_wl_shell_shell_surface_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event); static void _e_wl_shell_shell_surface_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event); static void _e_wl_shell_shell_surface_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event); static void _e_wl_shell_shell_surface_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event); @@ -625,6 +626,8 @@ _e_wl_shell_shell_surface_create_toplevel(E_Wayland_Surface *ews) EC_CHANGED(ews->ec); /* hook object callbacks */ + evas_object_event_callback_add(ews->ec->frame, EVAS_CALLBACK_MOUSE_IN, + _e_wl_shell_shell_surface_cb_mouse_in, ews); evas_object_event_callback_add(ews->ec->frame, EVAS_CALLBACK_MOUSE_OUT, _e_wl_shell_shell_surface_cb_mouse_out, ews); evas_object_event_callback_add(ews->ec->frame, EVAS_CALLBACK_MOUSE_MOVE, @@ -686,6 +689,8 @@ _e_wl_shell_shell_surface_create_popup(E_Wayland_Surface *ews) EC_CHANGED(ews->ec); /* hook object callbacks */ + evas_object_event_callback_add(ews->ec->frame, EVAS_CALLBACK_MOUSE_IN, + _e_wl_shell_shell_surface_cb_mouse_in, ews); evas_object_event_callback_add(ews->ec->frame, EVAS_CALLBACK_MOUSE_OUT, _e_wl_shell_shell_surface_cb_mouse_out, ews); evas_object_event_callback_add(ews->ec->frame, EVAS_CALLBACK_MOUSE_MOVE, @@ -913,8 +918,10 @@ _e_wl_shell_shell_surface_unmap(E_Wayland_Surface *ews) if (ews->ec) { - evas_object_event_callback_del_full(ews->ec->frame, EVAS_CALLBACK_MOUSE_OUT, - _e_wl_shell_shell_surface_cb_mouse_out, ews); + evas_object_event_callback_del_full(ews->ec->frame, EVAS_CALLBACK_MOUSE_IN, + _e_wl_shell_shell_surface_cb_mouse_in, ews); + //evas_object_event_callback_del_full(ews->ec->frame, EVAS_CALLBACK_MOUSE_OUT, + //_e_wl_shell_shell_surface_cb_mouse_out, ews); evas_object_event_callback_del_full(ews->ec->frame, EVAS_CALLBACK_MOUSE_MOVE, _e_wl_shell_shell_surface_cb_mouse_move, ews); evas_object_event_callback_del_full(ews->ec->frame, EVAS_CALLBACK_MOUSE_UP, @@ -1123,6 +1130,14 @@ _e_wl_shell_render_post(void *data EINA_UNUSED, Evas *e EINA_UNUSED, void *event } static void +_e_wl_shell_shell_surface_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) +{ + E_Wayland_Surface *ews = data; + + e_pointer_block_add(ews->ec->comp->pointer); +} + +static void _e_wl_shell_shell_surface_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) { E_Wayland_Surface *ews = NULL; @@ -1131,6 +1146,9 @@ _e_wl_shell_shell_surface_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Obj /* try to cast data to our surface structure */ if (!(ews = data)) return; + if (ews->ec->cur_mouse_action || ews->ec->border_menu) return; + if (ews->ec->comp->pointer) e_pointer_block_del(ews->ec->comp->pointer); + if (e_object_is_del(E_OBJECT(ews->ec))) return; /* try to get the pointer from this input */ if ((ptr = _e_wl_comp->input->wl.seat.pointer)) @@ -1158,6 +1176,7 @@ _e_wl_shell_shell_surface_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Ob /* try to cast data to our surface structure */ if (!(ews = data)) return; + if (ews->ec->cur_mouse_action || ews->ec->border_menu) return; /* try to get the pointer from this input */ if ((ptr = _e_wl_comp->input->wl.seat.pointer)) @@ -1186,7 +1205,7 @@ _e_wl_shell_shell_surface_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Obje /* try to cast data to our surface structure */ if (!(ews = data)) return; - if (ews->ec && ews->ec->cur_mouse_action) return; + if (ews->ec->cur_mouse_action || ews->ec->border_menu) return; /* try to get the pointer from this input */ if ((ptr = _e_wl_comp->input->wl.seat.pointer)) @@ -1220,7 +1239,7 @@ _e_wl_shell_shell_surface_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Ob /* try to cast data to our surface structure */ if (!(ews = data)) return; - if (ews->ec && ews->ec->cur_mouse_action) return; + if (ews->ec->cur_mouse_action || ews->ec->border_menu) return; /* try to get the pointer from this input */ if ((ptr = _e_wl_comp->input->wl.seat.pointer)) @@ -1273,7 +1292,7 @@ _e_wl_shell_shell_surface_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_O /* try to cast data to our surface structure */ if (!(ews = data)) return; - if (ews->ec && ews->ec->cur_mouse_action) return; + if (ews->ec->cur_mouse_action || ews->ec->border_menu) return; /* try to get the pointer from this input */ if ((ptr = _e_wl_comp->input->wl.seat.pointer)) diff --git a/src/modules/wl_fb/e_mod_main.c b/src/modules/wl_fb/e_mod_main.c index e92f52c15e..85a7e607d4 100644 --- a/src/modules/wl_fb/e_mod_main.c +++ b/src/modules/wl_fb/e_mod_main.c @@ -42,6 +42,7 @@ e_modapi_init(E_Module *m) e_comp_wl_init(); e_comp_canvas_init(comp); e_comp_canvas_fake_layers_init(comp); + comp->pointer = e_pointer_canvas_new(comp->evas, 1); ecore_wl_init(NULL); ecore_wl_server_mode_set(1); diff --git a/src/modules/wl_x11/e_mod_main.c b/src/modules/wl_x11/e_mod_main.c index 3545dc7105..2978386368 100644 --- a/src/modules/wl_x11/e_mod_main.c +++ b/src/modules/wl_x11/e_mod_main.c @@ -44,10 +44,10 @@ e_modapi_init(E_Module *m) e_xinerama_screens_set(eina_list_append(NULL, screen)); } comp->man = e_manager_new(0, comp, SCREEN_W, SCREEN_H); - comp->pointer = e_pointer_window_new(comp->man->root, 1); e_comp_wl_init(); e_comp_canvas_init(comp); e_comp_canvas_fake_layers_init(comp); + comp->pointer = e_pointer_canvas_new(comp->evas, 1); ecore_evas_callback_delete_request_set(ee, _cb_delete_request); |