wl pointers done-ish

pointers in E now come in two flavors, one for each protocol that we currently support. each is created from the owner compositor backend:

X pointers still work as usual

Wayland pointers are actually surfaces that we dump image data into periodically to render them as evas images

some small amounts of hack is necessary to make this work, namely blocking X pointers when a Wayland one is in use if we're running a multi-protocol compositor
This commit is contained in:
Mike Blumenkrantz 2013-09-11 13:03:31 +01:00
parent fa32b5e708
commit 5737103d67
9 changed files with 745 additions and 540 deletions

View File

@ -128,7 +128,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++)
{

View File

@ -1742,6 +1742,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);
@ -2281,53 +2285,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 */
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 */
/* 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);
/* 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
@ -2408,7 +2376,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,

View File

@ -4708,6 +4708,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;

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -319,9 +319,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;
}

View File

@ -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,
@ -1122,6 +1129,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)
{
@ -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))

View File

@ -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);

View File

@ -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);