diff options
author | Chris Michael <cp.michael@samsung.com> | 2013-03-14 10:01:44 +0000 |
---|---|---|
committer | Chris Michael <cp.michael@samsung.com> | 2013-03-21 07:21:46 +0000 |
commit | aa8f748d69f2c52e07388e829259b686e3575326 (patch) | |
tree | 1c7ffeec3e7979f4fd5f22b68ae75204623a7f81 | |
parent | ee5eb613a67affd6a0b742eeea262906ec12589f (diff) | |
download | enlightenment-aa8f748d69f2c52e07388e829259b686e3575326.tar.gz |
Add code to handle focus_in/out, mouse_in/out, mouse_up/down on
wayland clients and forward those to the clients.
Convert lists of surfaces and seats to use Eina_List.
Add buffer referencing code.
NB: This needs some cleaning up which will come later.
Signed-off-by: Chris Michael <cp.michael@samsung.com>
-rw-r--r-- | src/bin/e_comp_wl.c | 568 |
1 files changed, 489 insertions, 79 deletions
diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 96cd748058..b8fa86f7e5 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -1,10 +1,23 @@ #include "e.h" #include "e_comp_wl.h" #include <sys/mman.h> +#ifdef __linux__ +# include <linux/input.h> +#else +# define BTN_LEFT 0x110 +# define BTN_RIGHT 0x111 +# define BTN_MIDDLE 0x112 +# define BTN_SIDE 0x113 +# define BTN_EXTRA 0x114 +# define BTN_FORWARD 0x115 +# define BTN_BACK 0x116 +#endif /* local function prototypes */ +static void _e_comp_wl_repick(void); static void _e_comp_wl_cb_bind(struct wl_client *client, void *data EINA_UNUSED, unsigned int version EINA_UNUSED, unsigned int id); -static Eina_Bool _e_comp_wl_cb_fd_handle(void *data EINA_UNUSED, Ecore_Fd_Handler *hdl EINA_UNUSED); +static Eina_Bool _e_comp_wl_cb_fd_handle(void *data EINA_UNUSED, Ecore_Fd_Handler *hdl); +static Eina_Bool _e_comp_wl_cb_idle(void *data EINA_UNUSED); static Eina_Bool _e_comp_wl_input_init(void); static void _e_comp_wl_input_shutdown(void); @@ -13,6 +26,7 @@ static void _e_comp_wl_input_keyboard_get(struct wl_client *client, struct wl_re static void _e_comp_wl_input_touch_get(struct wl_client *client, struct wl_resource *resource, unsigned int id); static struct xkb_keymap *_e_comp_wl_input_keymap_get(void); static int _e_comp_wl_input_keymap_fd_create(off_t size); +static void _e_comp_wl_input_repick(E_Wayland_Input *input); static void _e_comp_wl_input_cb_bind(struct wl_client *client, void *data, unsigned int version EINA_UNUSED, unsigned int id); static void _e_comp_wl_input_cb_unbind(struct wl_resource *resource); @@ -31,7 +45,12 @@ static void _e_comp_wl_surface_cb_opaque_region_set(struct wl_client *client EIN static void _e_comp_wl_surface_cb_input_region_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *region); static void _e_comp_wl_surface_cb_commit(struct wl_client *client EINA_UNUSED, struct wl_resource *resource); static void _e_comp_wl_surface_cb_pending_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED); +static void _e_comp_wl_surface_cb_reference_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED); static void _e_comp_wl_surface_cb_draw_done(void *data, Evas *evas EINA_UNUSED, void *event EINA_UNUSED); +static E_Wayland_Surface *_e_comp_wl_surface_find(Ecore_X_Window win); +static void _e_comp_wl_surface_buffer_reference(E_Wayland_Surface *ews, struct wl_buffer *buffer); +static E_Wayland_Surface *_e_comp_wl_surface_pick(wl_fixed_t x, wl_fixed_t y, wl_fixed_t *cx, wl_fixed_t *cy); +static void _e_comp_wl_surface_from_global_fixed(E_Wayland_Surface *ews, wl_fixed_t x, wl_fixed_t y, wl_fixed_t *sx, wl_fixed_t *sy); static void _e_comp_wl_region_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource); static void _e_comp_wl_region_cb_add(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int x, int y, int w, int h); @@ -41,15 +60,15 @@ static void _e_comp_wl_pointer_cursor_set(struct wl_client *client, struct wl_re static void _e_comp_wl_frame_cb_destroy(struct wl_resource *resource); -static Eina_Bool _e_comp_wl_cb_idle(void *data EINA_UNUSED); - -static Eina_Bool _e_comp_wl_cb_window_focus_in(void *data, int type EINA_UNUSED, void *event); -static Eina_Bool _e_comp_wl_cb_window_focus_out(void *data, int type EINA_UNUSED, void *event); +static Eina_Bool _e_comp_wl_cb_module_idle(void *data EINA_UNUSED); -/* static Eina_Bool _e_comp_wl_cb_mouse_in(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); */ -/* static Eina_Bool _e_comp_wl_cb_mouse_out(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); */ -/* static Eina_Bool _e_comp_wl_cb_mouse_down(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); */ -/* static Eina_Bool _e_comp_wl_cb_mouse_up(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); */ +static Eina_Bool _e_comp_wl_cb_focus_in(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); +static Eina_Bool _e_comp_wl_cb_focus_out(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); +static Eina_Bool _e_comp_wl_cb_mouse_in(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); +static Eina_Bool _e_comp_wl_cb_mouse_out(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); +static Eina_Bool _e_comp_wl_cb_mouse_down(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); +static Eina_Bool _e_comp_wl_cb_mouse_up(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); +static Eina_Bool _e_comp_wl_cb_mouse_move(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); /* static Eina_Bool _e_comp_wl_cb_key_down(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); */ /* static Eina_Bool _e_comp_wl_cb_key_up(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); */ @@ -93,7 +112,7 @@ static const struct wl_pointer_interface _e_wl_pointer_interface = /* local variables */ static Ecore_Idler *_idler = NULL; -/* static Eina_List *_hdlrs = NULL; */ +static Eina_List *_hdlrs = NULL; /* external variables */ E_Wayland_Compositor *_e_wl_comp; @@ -145,8 +164,8 @@ e_comp_wl_init(void) } /* initialize compositor lists */ - wl_list_init(&_e_wl_comp->wl.lists.surface); - wl_list_init(&_e_wl_comp->wl.lists.seat); + /* wl_list_init(&_e_wl_comp->wl.lists.surface); */ + /* wl_list_init(&_e_wl_comp->wl.lists.seat); */ /* initalize the wayland data device manager */ wl_data_device_manager_init(_e_wl_comp->wl.display); @@ -164,7 +183,7 @@ e_comp_wl_init(void) /* setup an idler so we can load the wl_shell module after * init has completed */ - _idler = ecore_idler_add(_e_comp_wl_cb_idle, NULL); + _idler = ecore_idler_add(_e_comp_wl_cb_module_idle, NULL); /* get the display's event loop */ loop = wl_display_get_event_loop(_e_wl_comp->wl.display); @@ -177,19 +196,30 @@ e_comp_wl_init(void) ecore_main_fd_handler_add(fd, ECORE_FD_READ, _e_comp_wl_cb_fd_handle, NULL, NULL, NULL); - /* E_LIST_HANDLER_APPEND(_hdlrs, ECORE_X_EVENT_MOUSE_IN, */ - /* _e_comp_wl_cb_mouse_in, NULL); */ - /* E_LIST_HANDLER_APPEND(_hdlrs, ECORE_X_EVENT_MOUSE_OUT, */ - /* _e_comp_wl_cb_mouse_out, NULL); */ - /* E_LIST_HANDLER_APPEND(_hdlrs, ECORE_EVENT_MOUSE_BUTTON_DOWN, */ - /* _e_comp_wl_cb_mouse_down, NULL); */ - /* E_LIST_HANDLER_APPEND(_hdlrs, ECORE_EVENT_MOUSE_BUTTON_UP, */ - /* _e_comp_wl_cb_mouse_up, NULL); */ + _e_wl_comp->idler = ecore_idle_enterer_add(_e_comp_wl_cb_idle, NULL); + + E_LIST_HANDLER_APPEND(_hdlrs, ECORE_X_EVENT_WINDOW_FOCUS_IN, + _e_comp_wl_cb_focus_in, NULL); + E_LIST_HANDLER_APPEND(_hdlrs, ECORE_X_EVENT_WINDOW_FOCUS_OUT, + _e_comp_wl_cb_focus_out, NULL); + E_LIST_HANDLER_APPEND(_hdlrs, ECORE_X_EVENT_MOUSE_IN, + _e_comp_wl_cb_mouse_in, NULL); + E_LIST_HANDLER_APPEND(_hdlrs, ECORE_X_EVENT_MOUSE_OUT, + _e_comp_wl_cb_mouse_out, NULL); + E_LIST_HANDLER_APPEND(_hdlrs, ECORE_EVENT_MOUSE_BUTTON_DOWN, + _e_comp_wl_cb_mouse_down, NULL); + E_LIST_HANDLER_APPEND(_hdlrs, ECORE_EVENT_MOUSE_BUTTON_UP, + _e_comp_wl_cb_mouse_up, NULL); + E_LIST_HANDLER_APPEND(_hdlrs, ECORE_EVENT_MOUSE_MOVE, + _e_comp_wl_cb_mouse_move, NULL); + /* E_LIST_HANDLER_APPEND(_hdlrs, ECORE_EVENT_KEY_DOWN, */ /* _e_comp_wl_cb_key_down, NULL); */ /* E_LIST_HANDLER_APPEND(_hdlrs, ECORE_EVENT_KEY_UP, */ /* _e_comp_wl_cb_key_up, NULL); */ + wl_event_loop_dispatch(loop, 0); + return EINA_TRUE; err: @@ -212,7 +242,7 @@ e_comp_wl_shutdown(void) LOGFN(__FILE__, __LINE__, __FUNCTION__); - /* E_FREE_LIST(_hdlrs, ecore_event_handler_del); */ + E_FREE_LIST(_hdlrs, ecore_event_handler_del); if (_idler) ecore_idler_del(_idler); _idler = NULL; @@ -223,6 +253,8 @@ e_comp_wl_shutdown(void) if (_e_wl_comp->fd_handler) ecore_main_fd_handler_del(_e_wl_comp->fd_handler); + if (_e_wl_comp->idler) + ecore_idle_enterer_del(_e_wl_comp->idler); /* destroy the display */ if (_e_wl_comp->wl.display) wl_display_destroy(_e_wl_comp->wl.display); @@ -237,6 +269,16 @@ e_comp_wl_shutdown(void) /* local functions */ static void +_e_comp_wl_repick(void) +{ + E_Wayland_Input *input = NULL; + Eina_List *l = NULL; + + EINA_LIST_FOREACH(_e_wl_comp->wl.lists.seat, l, input) + _e_comp_wl_input_repick(input); +} + +static void _e_comp_wl_cb_bind(struct wl_client *client, void *data EINA_UNUSED, unsigned int version EINA_UNUSED, unsigned int id) { LOGFN(__FILE__, __LINE__, __FUNCTION__); @@ -262,6 +304,14 @@ _e_comp_wl_cb_fd_handle(void *data EINA_UNUSED, Ecore_Fd_Handler *hdl EINA_UNUSE } static Eina_Bool +_e_comp_wl_cb_idle(void *data EINA_UNUSED) +{ + wl_display_flush_clients(_e_wl_comp->wl.display); + + return ECORE_CALLBACK_RENEW; +} + +static Eina_Bool _e_comp_wl_input_init(void) { struct xkb_keymap *keymap; @@ -355,7 +405,11 @@ _e_comp_wl_input_init(void) /* TODO: handle cases of touch ? */ - wl_list_insert(_e_wl_comp->wl.lists.seat.prev, &_e_wl_comp->input->wl.link); + wl_list_init(&_e_wl_comp->input->wl.link); + + _e_wl_comp->wl.lists.seat = eina_list_append(_e_wl_comp->wl.lists.seat, + _e_wl_comp->input); + wl_signal_emit(&_e_wl_comp->wl.signals.seat, _e_wl_comp->input); return EINA_TRUE; @@ -377,6 +431,13 @@ _e_comp_wl_input_shutdown(void) if (_e_wl_comp->input->xkb.info->keymap) xkb_map_unref(_e_wl_comp->input->xkb.info->keymap); + if (_e_wl_comp->input->xkb.info->area) + munmap(_e_wl_comp->input->xkb.info->area, + _e_wl_comp->input->xkb.info->size); + + if (_e_wl_comp->input->xkb.info->fd) + close(_e_wl_comp->input->xkb.info->fd); + E_FREE(_e_wl_comp->input->xkb.info); } @@ -415,9 +476,16 @@ _e_comp_wl_input_pointer_get(struct wl_client *client, struct wl_resource *resou E_Wayland_Surface *ews = NULL; if ((ews = (E_Wayland_Surface *)input->wl.seat.pointer->focus)) - wl_pointer_set_focus(input->wl.seat.pointer, - input->wl.seat.pointer->focus, - ews->geometry.x, ews->geometry.y); + { + wl_fixed_t x, y; + + _e_comp_wl_surface_from_global_fixed(ews, + input->wl.seat.pointer->x, + input->wl.seat.pointer->y, + &x, &y); + wl_pointer_set_focus(input->wl.seat.pointer, + input->wl.seat.pointer->focus, x, y); + } } } @@ -551,6 +619,32 @@ _e_comp_wl_input_keymap_fd_create(off_t size) } static void +_e_comp_wl_input_repick(E_Wayland_Input *input) +{ + E_Wayland_Surface *ews = NULL, *focus = NULL; + struct wl_pointer *ptr; + + if (!(ptr = input->wl.seat.pointer)) return; + + ews = _e_comp_wl_surface_pick(ptr->x, ptr->y, + &ptr->current_x, &ptr->current_y); + + if (&ews->wl.surface != ptr->current) + { + const struct wl_pointer_grab_interface *grab; + + grab = ptr->grab->interface; + ptr->current = &ews->wl.surface; + grab->focus(ptr->grab, &ews->wl.surface, + ptr->current_x, ptr->current_y); + } + + if ((focus = (E_Wayland_Surface *)ptr->grab->focus)) + _e_comp_wl_surface_from_global_fixed(focus, ptr->x, ptr->y, + &ptr->grab->x, &ptr->grab->y); +} + +static void _e_comp_wl_input_cb_bind(struct wl_client *client, void *data, unsigned int version EINA_UNUSED, unsigned int id) { struct wl_seat *seat = NULL; @@ -592,10 +686,10 @@ _e_comp_wl_input_focus_cb_destroy(struct wl_listener *listener, void *data EINA_ LOGFN(__FILE__, __LINE__, __FUNCTION__); - input = container_of(listener, E_Wayland_Input, focus_listener); + input = container_of(listener, E_Wayland_Input, saved_focus_listener); if (!input) return; - input->focus = NULL; + input->saved_focus = NULL; } static void @@ -625,11 +719,6 @@ _e_comp_wl_cb_surface_create(struct wl_client *client, struct wl_resource *resou /* ews->width = 700; */ /* ews->height = 400; */ - E_LIST_HANDLER_APPEND(ews->handlers, E_EVENT_BORDER_FOCUS_IN, - _e_comp_wl_cb_window_focus_in, ews); - E_LIST_HANDLER_APPEND(ews->handlers, E_EVENT_BORDER_FOCUS_OUT, - _e_comp_wl_cb_window_focus_out, ews); - ews->win = e_win_new(e_container_current_get(e_manager_current_get())); e_win_borderless_set(ews->win, EINA_TRUE); e_win_shaped_set(ews->win, EINA_TRUE); @@ -665,14 +754,37 @@ _e_comp_wl_cb_surface_destroy(struct wl_resource *resource) ews = container_of(resource, E_Wayland_Surface, wl.surface.resource); - E_FREE_LIST(ews->handlers, ecore_event_handler_del); + /* unmap surface */ + if (ews->mapped) + { + E_Wayland_Input *input; + Eina_List *l; + + EINA_LIST_FOREACH(_e_wl_comp->wl.lists.seat, l, input) +// wl_list_for_each(input, &_e_wl_comp->wl.lists.seat, wl.link) + { + if ((input->wl.seat.keyboard) && + (input->wl.seat.keyboard->focus == &ews->wl.surface)) + wl_keyboard_set_focus(input->wl.seat.keyboard, NULL); + if ((input->wl.seat.pointer) && + (input->wl.seat.pointer->focus == &ews->wl.surface)) + wl_pointer_set_focus(input->wl.seat.pointer, NULL, 0, 0); + } + + e_win_hide(ews->win); + ews->mapped = EINA_FALSE; + } /* loop surface pending frame callbacks and destroy them */ wl_list_for_each_safe(cb, next, &ews->pending.frames, wl.link) wl_resource_destroy(&cb->wl.resource); /* remove pending buffer from list */ - if (ews->pending.buffer) wl_list_remove(&ews->pending.buffer_destroy.link); + if (ews->pending.buffer) + wl_list_remove(&ews->pending.buffer_destroy.link); + + /* unreference the existing buffer */ + _e_comp_wl_surface_buffer_reference(ews, NULL); /* actually destroy the surface */ if (ews->img) evas_object_del(ews->img); @@ -695,6 +807,9 @@ _e_comp_wl_cb_surface_destroy(struct wl_resource *resource) wl_list_for_each_safe(cb, next, &ews->wl.frames, wl.link) wl_resource_destroy(&cb->wl.resource); + _e_wl_comp->wl.lists.surface = + eina_list_remove(_e_wl_comp->wl.lists.surface, ews); + free(ews); } @@ -755,26 +870,39 @@ _e_comp_wl_surface_cb_attach(struct wl_client *client EINA_UNUSED, struct wl_res if (!(ews = resource->data)) return; if (buffer) buff = buffer->data; + /* reference the existing buffer */ + _e_comp_wl_surface_buffer_reference(ews, buff); + + if (!buff) + { + if (ews->mapped) + { + if (ews->win) e_win_hide(ews->win); + ews->mapped = EINA_FALSE; + } + } + /* remove pending buffer */ if (ews->pending.buffer) wl_list_remove(&ews->pending.buffer_destroy.link); - if ((buff) && (ews->pending.buffer != buff)) - ews->pending.new_buffer = EINA_TRUE; + /* if ((buff) && (ews->pending.buffer != buff)) */ + /* ews->pending.new_buffer = EINA_TRUE; */ ews->pending.x = x; ews->pending.y = y; ews->pending.buffer = buff; + ews->pending.new_buffer = EINA_TRUE; if (buff) { wl_signal_add(&buff->resource.destroy_signal, &ews->pending.buffer_destroy); - ews->pending.remove_buffer = EINA_FALSE; + /* ews->pending.remove_buffer = EINA_FALSE; */ } - else - ews->pending.remove_buffer = EINA_TRUE; + /* else */ + /* ews->pending.remove_buffer = EINA_TRUE; */ } static void @@ -884,22 +1012,14 @@ _e_comp_wl_surface_cb_commit(struct wl_client *client EINA_UNUSED, struct wl_res if (!(ews = resource->data)) return; - if ((!ews->pending.buffer) || (ews->pending.remove_buffer)) - { - evas_object_image_data_set(ews->img, NULL); - ews->pending.buffer = NULL; - return; - } - - if ((ews->configure) && (ews->pending.new_buffer)) - ews->configure(ews, ews->pending.x, ews->pending.y, - ews->pending.buffer->width, ews->pending.buffer->height); - - ews->pending.x = 0; - ews->pending.y = 0; - ews->pending.new_buffer = EINA_FALSE; + /* if ((!ews->pending.buffer) || (ews->pending.remove_buffer)) */ + /* { */ + /* evas_object_image_data_set(ews->img, NULL); */ + /* ews->pending.buffer = NULL; */ + /* return; */ + /* } */ - if (ews->pending.buffer) + if ((ews->pending.buffer) || (ews->pending.new_buffer)) { int bw = 0, bh = 0; void *data; @@ -926,6 +1046,18 @@ _e_comp_wl_surface_cb_commit(struct wl_client *client EINA_UNUSED, struct wl_res evas_object_image_data_set(ews->img, data); } + if ((ews->configure) && (ews->pending.new_buffer)) + ews->configure(ews, ews->pending.x, ews->pending.y, + ews->pending.buffer->width, ews->pending.buffer->height); + + if (ews->pending.buffer) + wl_list_remove(&ews->pending.buffer_destroy.link); + + ews->pending.x = 0; + ews->pending.y = 0; + ews->pending.buffer = NULL; + ews->pending.new_buffer = EINA_FALSE; + if (ews->damages) { Eina_Iterator *itr; @@ -959,6 +1091,18 @@ _e_comp_wl_surface_cb_pending_buffer_destroy(struct wl_listener *listener, void } static void +_e_comp_wl_surface_cb_reference_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED) +{ + E_Wayland_Surface *ews = NULL; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ews = container_of(listener, E_Wayland_Surface, reference.buffer_destroy); + if (!ews) return; + ews->reference.buffer = NULL; +} + +static void _e_comp_wl_surface_cb_draw_done(void *data, Evas *evas EINA_UNUSED, void *event EINA_UNUSED) { E_Wayland_Surface *ews = NULL; @@ -982,6 +1126,99 @@ _e_comp_wl_surface_cb_draw_done(void *data, Evas *evas EINA_UNUSED, void *event } } +static E_Wayland_Surface * +_e_comp_wl_surface_find(Ecore_X_Window win) +{ + E_Wayland_Surface *ews = NULL; + Eina_List *l = NULL; + + /* if (!eina_list_count(_e_wl_comp->wl.lists.surface)) return NULL; */ + /* if (wl_list_empty(&_e_wl_comp->wl.lists.surface)) return NULL; */ + + /* printf("Num Of Surfaces: %d\n", */ + /* wl_list_length(&_e_wl_comp->wl.lists.surface)); */ + + EINA_LIST_FOREACH(_e_wl_comp->wl.lists.surface, l, ews) +// wl_list_for_each(ews, &_e_wl_comp->wl.lists.surface, wl.link) + { + if (!ews->mapped) continue; + if ((ews->win) && (ews->win->border)) + { + /* printf("Surface Win: %d\n", ews->win->border->win); */ + /* printf("Surface Client: %d\n", ews->win->border->client.win); */ +// if ((ews->win->border->win == win) || + if ((ews->win->border->client.win == win)) + return ews; + } + } + + return NULL; +} + +static void +_e_comp_wl_surface_buffer_reference(E_Wayland_Surface *ews, struct wl_buffer *buffer) +{ + if (!ews) return; + + if ((ews->reference.buffer) && (buffer != ews->reference.buffer)) + { + ews->reference.buffer->busy_count--; + if (ews->reference.buffer->busy_count == 0) + { + if (ews->reference.buffer->resource.client) + wl_resource_queue_event(&ews->reference.buffer->resource, + WL_BUFFER_RELEASE); + } + wl_list_remove(&ews->reference.buffer_destroy.link); + } + + if ((buffer) && (buffer != ews->reference.buffer)) + { + buffer->busy_count++; + wl_signal_add(&buffer->resource.destroy_signal, + &ews->reference.buffer_destroy); + } + + ews->reference.buffer = buffer; + ews->reference.buffer_destroy.notify = + _e_comp_wl_surface_cb_reference_buffer_destroy; +} + +static E_Wayland_Surface * +_e_comp_wl_surface_pick(wl_fixed_t x, wl_fixed_t y, wl_fixed_t *cx, wl_fixed_t *cy) +{ + E_Wayland_Surface *ews = NULL; + Eina_List *l = NULL; + + EINA_LIST_FOREACH(_e_wl_comp->wl.lists.surface, l, ews) + { + int sx, sy; + + _e_comp_wl_surface_from_global_fixed(ews, x, y, cx, cy); + + sx = wl_fixed_to_int(*cx); + sy = wl_fixed_to_int(*cy); + + if (E_INSIDE(sx, sy, ews->geometry.x, ews->geometry.y, + ews->geometry.w, ews->geometry.h)) + return ews; + } + + return NULL; +} + +static void +_e_comp_wl_surface_from_global_fixed(E_Wayland_Surface *ews, wl_fixed_t x, wl_fixed_t y, wl_fixed_t *sx, wl_fixed_t *sy) +{ + float nx, ny; + + if (!ews) return; + nx = (wl_fixed_to_double(x) - ews->geometry.x); + ny = (wl_fixed_to_double(y) - ews->geometry.y); + if (sx) *sx = wl_fixed_from_double(nx); + if (sy) *sy = wl_fixed_from_double(ny); +} + static void _e_comp_wl_region_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) { @@ -1036,7 +1273,7 @@ _e_comp_wl_frame_cb_destroy(struct wl_resource *resource) } static Eina_Bool -_e_comp_wl_cb_idle(void *data EINA_UNUSED) +_e_comp_wl_cb_module_idle(void *data EINA_UNUSED) { E_Module *mod = NULL; @@ -1058,86 +1295,259 @@ _e_comp_wl_cb_idle(void *data EINA_UNUSED) } static Eina_Bool -_e_comp_wl_cb_window_focus_in(void *data, int type EINA_UNUSED, void *event) +_e_comp_wl_cb_focus_in(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) { E_Wayland_Surface *ews = NULL; - E_Event_Border_Focus_In *ev; - struct wl_keyboard *kbd; + struct wl_surface *surface = NULL; + Ecore_X_Event_Window_Focus_In *ev; - if (!(ews = data)) return ECORE_CALLBACK_PASS_ON; if (!(ev = event)) return ECORE_CALLBACK_PASS_ON; - if ((!ews->win) || (!ews->win->border)) return ECORE_CALLBACK_PASS_ON; - if (ev->border != ews->win->border) return ECORE_CALLBACK_PASS_ON; + /* find the surface at this point */ + if (!(ews = _e_comp_wl_surface_find(ev->win))) + return ECORE_CALLBACK_PASS_ON; - kbd = _e_wl_comp->input->wl.seat.keyboard; + LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (_e_wl_comp->input->focus) + surface = _e_wl_comp->input->saved_focus; + if (surface) { - wl_list_remove(&_e_wl_comp->input->focus_listener.link); - _e_wl_comp->input->focus = NULL; + wl_list_remove(&_e_wl_comp->input->saved_focus_listener.link); + wl_keyboard_set_focus(_e_wl_comp->input->wl.seat.keyboard, + surface); + _e_wl_comp->input->saved_focus = NULL; } - printf("Focus This Wayland Surface !!\n"); - wl_keyboard_set_focus(kbd, &ews->wl.surface); + wl_display_flush_clients(_e_wl_comp->wl.display); return ECORE_CALLBACK_PASS_ON; } static Eina_Bool -_e_comp_wl_cb_window_focus_out(void *data, int type EINA_UNUSED, void *event) +_e_comp_wl_cb_focus_out(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) { E_Wayland_Surface *ews = NULL; - E_Event_Border_Focus_Out *ev; - struct wl_keyboard *kbd; + struct wl_keyboard *kbd = NULL; + Ecore_X_Event_Window_Focus_Out *ev; - if (!(ews = data)) return ECORE_CALLBACK_PASS_ON; if (!(ev = event)) return ECORE_CALLBACK_PASS_ON; - if ((!ews->win) || (!ews->win->border)) return ECORE_CALLBACK_PASS_ON; - if (ev->border != ews->win->border) return ECORE_CALLBACK_PASS_ON; + /* find the surface at this point */ + if (!(ews = _e_comp_wl_surface_find(ev->win))) + return ECORE_CALLBACK_PASS_ON; - printf("Unfocus This Wayland Surface !!\n"); + LOGFN(__FILE__, __LINE__, __FUNCTION__); kbd = _e_wl_comp->input->wl.seat.keyboard; if (kbd->focus) { - _e_wl_comp->input->focus = kbd->focus; - _e_wl_comp->input->focus_listener.notify = + _e_wl_comp->input->saved_focus = kbd->focus; + _e_wl_comp->input->saved_focus_listener.notify = _e_comp_wl_input_focus_cb_destroy; - wl_signal_add(&kbd->focus->resource.destroy_signal, - &_e_wl_comp->input->focus_listener); + &_e_wl_comp->input->saved_focus_listener); } wl_keyboard_set_focus(kbd, NULL); wl_keyboard_end_grab(kbd); + wl_display_flush_clients(_e_wl_comp->wl.display); + return ECORE_CALLBACK_PASS_ON; } static Eina_Bool _e_comp_wl_cb_mouse_in(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) { + Ecore_X_Event_Mouse_In *ev; + struct wl_pointer *ptr; + E_Wayland_Surface *ews = NULL; + + ev = event; + + /* find the surface at this point */ + if (!(ews = _e_comp_wl_surface_find(ev->event_win))) + return ECORE_CALLBACK_PASS_ON; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ptr = _e_wl_comp->input->wl.seat.pointer; + if (!ptr) return ECORE_CALLBACK_PASS_ON; + + ptr->x = wl_fixed_from_int(ev->x); + ptr->y = wl_fixed_from_int(ev->y); + + _e_comp_wl_repick(); + + wl_display_flush_clients(_e_wl_comp->wl.display); + return ECORE_CALLBACK_PASS_ON; } static Eina_Bool _e_comp_wl_cb_mouse_out(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) { + Ecore_X_Event_Mouse_Out *ev; + struct wl_pointer *ptr; + E_Wayland_Surface *ews = NULL; + + ev = event; + + /* find the surface at this point */ + if (!(ews = _e_comp_wl_surface_find(ev->event_win))) + return ECORE_CALLBACK_PASS_ON; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ptr = _e_wl_comp->input->wl.seat.pointer; + if (!ptr) return ECORE_CALLBACK_PASS_ON; + + ptr->x = wl_fixed_from_int(ev->x); + ptr->y = wl_fixed_from_int(ev->y); + + _e_comp_wl_repick(); + + wl_display_flush_clients(_e_wl_comp->wl.display); + return ECORE_CALLBACK_PASS_ON; } static Eina_Bool _e_comp_wl_cb_mouse_down(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) { + E_Wayland_Surface *focus = NULL; + Ecore_Event_Mouse_Button *ev; + struct wl_pointer *ptr; + unsigned int serial = 0; + int btn = 0; + struct timeval tm; + unsigned int timestamp = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ev = event; + + /* find the surface at this point */ + if (!_e_comp_wl_surface_find(ev->event_window)) + return ECORE_CALLBACK_PASS_ON; + + ptr = _e_wl_comp->input->wl.seat.pointer; + if (!ptr) return ECORE_CALLBACK_PASS_ON; + + serial = wl_display_next_serial(_e_wl_comp->wl.display); + focus = (E_Wayland_Surface *)ptr->focus; + + if (ev->buttons == 1) + btn = ev->buttons + BTN_LEFT - 1; + else if (ev->buttons == 2) + btn = BTN_MIDDLE; + else if (ev->buttons == 3) + btn = BTN_RIGHT; + + gettimeofday(&tm, NULL); + timestamp = (tm.tv_sec * 1000 + tm.tv_usec / 1000); + + if ((_e_wl_comp->ping_cb) && (focus)) + _e_wl_comp->ping_cb(focus, serial); + + if (ptr->button_count == 0) + { + ptr->grab_x = ptr->x; + ptr->grab_y = ptr->y; + ptr->grab_button = btn; + ptr->grab_time = timestamp; + } + + ptr->button_count++; + + ptr->grab->interface->button(ptr->grab, timestamp, btn, + WL_POINTER_BUTTON_STATE_PRESSED); + + if (ptr->button_count == 1) + ptr->grab_serial = wl_display_get_serial(_e_wl_comp->wl.display); + + wl_display_flush_clients(_e_wl_comp->wl.display); + return ECORE_CALLBACK_PASS_ON; } static Eina_Bool _e_comp_wl_cb_mouse_up(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) { + Ecore_Event_Mouse_Button *ev; + struct wl_pointer *ptr; + int btn = 0; + struct timeval tm; + unsigned int timestamp = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ev = event; + + /* find the surface at this point */ + if (!_e_comp_wl_surface_find(ev->event_window)) + return ECORE_CALLBACK_PASS_ON; + + ptr = _e_wl_comp->input->wl.seat.pointer; + if (!ptr) return ECORE_CALLBACK_PASS_ON; + + if (ev->buttons == 1) + btn = ev->buttons + BTN_LEFT - 1; + else if (ev->buttons == 2) + btn = BTN_MIDDLE; + else if (ev->buttons == 3) + btn = BTN_RIGHT; + + ptr->button_count--; + + gettimeofday(&tm, NULL); + timestamp = (tm.tv_sec * 1000 + tm.tv_usec / 1000); + + ptr->grab->interface->button(ptr->grab, timestamp, btn, + WL_POINTER_BUTTON_STATE_RELEASED); + + if (ptr->button_count == 1) + ptr->grab_serial = wl_display_get_serial(_e_wl_comp->wl.display); + + wl_display_flush_clients(_e_wl_comp->wl.display); + + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_e_comp_wl_cb_mouse_move(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + const struct wl_pointer_grab_interface *grab; + Ecore_Event_Mouse_Move *ev; + struct wl_pointer *ptr; + struct timeval tm; + unsigned int timestamp = 0; + + ev = event; + + /* find the surface at this point */ + if (!_e_comp_wl_surface_find(ev->event_window)) + return ECORE_CALLBACK_PASS_ON; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ptr = _e_wl_comp->input->wl.seat.pointer; + if (!ptr) return ECORE_CALLBACK_PASS_ON; + + ptr->x = wl_fixed_from_int(ev->x); + ptr->y = wl_fixed_from_int(ev->y); + + _e_comp_wl_input_repick(_e_wl_comp->input); + + gettimeofday(&tm, NULL); + timestamp = (tm.tv_sec * 1000 + tm.tv_usec / 1000); + + grab = ptr->grab->interface; + grab->motion(ptr->grab, timestamp, ptr->grab->x, ptr->grab->y); + + wl_display_flush_clients(_e_wl_comp->wl.display); + return ECORE_CALLBACK_PASS_ON; } |