summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Michael <cp.michael@samsung.com>2013-03-14 10:01:44 +0000
committerChris Michael <cp.michael@samsung.com>2013-03-21 07:21:46 +0000
commitaa8f748d69f2c52e07388e829259b686e3575326 (patch)
tree1c7ffeec3e7979f4fd5f22b68ae75204623a7f81
parentee5eb613a67affd6a0b742eeea262906ec12589f (diff)
downloadenlightenment-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.c568
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;
}