diff --git a/src/modules/comp/Makefile.am b/src/modules/comp/Makefile.am index b75f9f184..c51464525 100644 --- a/src/modules/comp/Makefile.am +++ b/src/modules/comp/Makefile.am @@ -47,7 +47,9 @@ module_la_SOURCES += e_mod_comp_wl.h \ e_mod_comp_wl_surface.h \ e_mod_comp_wl_surface.c \ e_mod_comp_wl_buffer.h \ - e_mod_comp_wl_buffer.c + e_mod_comp_wl_buffer.c \ + e_mod_comp_wl_region.h \ + e_mod_comp_wl_region.c endif module_la_LIBADD = @e_libs@ @dlopen_libs@ @WAYLAND_LIBS@ diff --git a/src/modules/comp/e_mod_comp_wl.c b/src/modules/comp/e_mod_comp_wl.c index 50bd1df9c..4b9861f1d 100644 --- a/src/modules/comp/e_mod_comp_wl.c +++ b/src/modules/comp/e_mod_comp_wl.c @@ -34,6 +34,18 @@ e_mod_comp_wl_init(void) return EINA_FALSE; } + if (wl_display_add_socket(_wl_disp, NULL)) + { + /* e_mod_comp_wl_shell_shutdown(); */ + /* e_mod_comp_wl_input_shutdown(); */ + /* e_mod_comp_wl_output_shutdown(); */ + /* e_mod_comp_wl_shm_shutdown(); */ + /* e_mod_comp_wl_comp_shutdown(); */ + wl_display_terminate(_wl_disp); + EINA_LOG_ERR("Failed to add socket to wayland display\n"); + return EINA_FALSE; + } + /* init a wayland compositor ?? */ if (!e_mod_comp_wl_comp_init()) { @@ -84,18 +96,6 @@ e_mod_comp_wl_init(void) return EINA_FALSE; } - if (wl_display_add_socket(_wl_disp, NULL)) - { - e_mod_comp_wl_shell_shutdown(); - e_mod_comp_wl_input_shutdown(); - e_mod_comp_wl_output_shutdown(); - e_mod_comp_wl_shm_shutdown(); - e_mod_comp_wl_comp_shutdown(); - wl_display_terminate(_wl_disp); - EINA_LOG_ERR("Failed to add socket to wayland display\n"); - return EINA_FALSE; - } - loop = wl_display_get_event_loop(_wl_disp); fd = wl_event_loop_get_fd(loop); diff --git a/src/modules/comp/e_mod_comp_wl.h b/src/modules/comp/e_mod_comp_wl.h index 96c034cb3..a79a9ddda 100644 --- a/src/modules/comp/e_mod_comp_wl.h +++ b/src/modules/comp/e_mod_comp_wl.h @@ -29,6 +29,7 @@ typedef struct _Wayland_Compositor Wayland_Compositor; typedef struct _Wayland_Mode Wayland_Mode; typedef struct _Wayland_Output Wayland_Output; typedef struct _Wayland_Input Wayland_Input; +typedef struct _Wayland_Region Wayland_Region; enum _Wayland_Visual { @@ -65,7 +66,7 @@ struct _Wayland_Surface struct wl_listener buffer_destroy_listener; struct wl_list frame_callbacks; - pixman_region32_t damage, opaque; + pixman_region32_t damage, opaque, clip, input; GLuint texture, saved_texture; int32_t x, y, w, h; @@ -154,6 +155,12 @@ struct _Wayland_Input uint32_t modifier_state; }; +struct _Wayland_Region +{ + struct wl_resource resource; + pixman_region32_t region; +}; + struct wl_shell { Wayland_Shell shell; diff --git a/src/modules/comp/e_mod_comp_wl_comp.c b/src/modules/comp/e_mod_comp_wl_comp.c index 6cb16492e..222e80a3c 100644 --- a/src/modules/comp/e_mod_comp_wl_comp.c +++ b/src/modules/comp/e_mod_comp_wl_comp.c @@ -6,6 +6,7 @@ # include "e_mod_comp_wl_shm.h" # include "e_mod_comp_wl_input.h" # include "e_mod_comp_wl_surface.h" +# include "e_mod_comp_wl_region.h" #endif #ifdef __linux__ @@ -30,6 +31,8 @@ static void _e_mod_comp_wl_comp_egl_shutdown(void); static void _e_mod_comp_wl_comp_destroy(void); static void _e_mod_comp_wl_comp_bind(struct wl_client *client, void *data, uint32_t version __UNUSED__, uint32_t id); static void _e_mod_comp_wl_comp_surface_create(struct wl_client *client, struct wl_resource *resource, uint32_t id); +static void _e_mod_comp_wl_comp_region_create(struct wl_client *client, struct wl_resource *resource, unsigned int id); +static void _e_mod_comp_wl_comp_region_destroy(struct wl_resource *resource); static Eina_Bool _e_mod_comp_wl_cb_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event); static Eina_Bool _e_mod_comp_wl_cb_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event); static Eina_Bool _e_mod_comp_wl_cb_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event); @@ -46,14 +49,23 @@ static void _e_mod_comp_wl_comp_update_modifier(Wayland_Input *input, uint32_t k /* wayland interfaces */ static const struct wl_compositor_interface _wl_comp_interface = { - _e_mod_comp_wl_comp_surface_create + _e_mod_comp_wl_comp_surface_create, + _e_mod_comp_wl_comp_region_create }; static const struct wl_surface_interface _wl_surface_interface = { e_mod_comp_wl_surface_destroy, e_mod_comp_wl_surface_attach, e_mod_comp_wl_surface_damage, - e_mod_comp_wl_surface_frame + e_mod_comp_wl_surface_frame, + e_mod_comp_wl_surface_set_opaque_region, + e_mod_comp_wl_surface_set_input_region +}; +static const struct wl_region_interface _wl_region_interface = +{ + e_mod_comp_wl_region_destroy, + e_mod_comp_wl_region_add, + e_mod_comp_wl_region_subtract }; /* private variables */ @@ -338,6 +350,38 @@ _e_mod_comp_wl_comp_surface_create(struct wl_client *client, struct wl_resource wl_client_add_resource(client, &ws->surface.resource); } +static void +_e_mod_comp_wl_comp_region_create(struct wl_client *client, struct wl_resource *resource, unsigned int id) +{ + Wayland_Region *region; + + region = malloc(sizeof(*region)); + if (!region) + { + wl_resource_post_no_memory(resource); + return; + } + + region->resource.destroy = _e_mod_comp_wl_comp_region_destroy; + region->resource.object.id = id; + region->resource.object.interface = &wl_region_interface; + region->resource.object.implementation = + (void (**)(void))&_wl_region_interface; + region->resource.data = region; + + pixman_region32_init(®ion->region); + wl_client_add_resource(client, ®ion->resource); +} + +static void +_e_mod_comp_wl_comp_region_destroy(struct wl_resource *resource) +{ + Wayland_Region *region; + + region = container_of(resource, Wayland_Region, resource); + pixman_region32_fini(®ion->region); + free(region); +} static Eina_Bool _e_mod_comp_wl_cb_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event) diff --git a/src/modules/comp/e_mod_comp_wl_region.c b/src/modules/comp/e_mod_comp_wl_region.c new file mode 100644 index 000000000..d6204cd67 --- /dev/null +++ b/src/modules/comp/e_mod_comp_wl_region.c @@ -0,0 +1,35 @@ +#include "e.h" +#include "e_mod_main.h" +#ifdef HAVE_WAYLAND_CLIENTS +# include "e_mod_comp_wl.h" +# include "e_mod_comp_wl_comp.h" +# include "e_mod_comp_wl_region.h" +#endif + +void +e_mod_comp_wl_region_destroy(struct wl_client *client __UNUSED__, struct wl_resource *resource) +{ + wl_resource_destroy(resource, e_mod_comp_wl_time_get()); +} + +void +e_mod_comp_wl_region_add(struct wl_client *client __UNUSED__, struct wl_resource *resource, int x, int y, int w, int h) +{ + Wayland_Region *region; + + region = resource->data; + pixman_region32_union_rect(®ion->region, ®ion->region, x, y, w, h); +} + +void +e_mod_comp_wl_region_subtract(struct wl_client *client __UNUSED__, struct wl_resource *resource, int x, int y, int w, int h) +{ + Wayland_Region *region; + pixman_region32_t rect; + + region = resource->data; + pixman_region32_init_rect(&rect, x, y, w, h); + pixman_region32_subtract(®ion->region, ®ion->region, &rect); + pixman_region32_fini(&rect); +} + diff --git a/src/modules/comp/e_mod_comp_wl_region.h b/src/modules/comp/e_mod_comp_wl_region.h new file mode 100644 index 000000000..d7d731e53 --- /dev/null +++ b/src/modules/comp/e_mod_comp_wl_region.h @@ -0,0 +1,11 @@ +#ifdef E_TYPEDEFS +#else +# ifndef E_MOD_COMP_WL_REGION_H +# define E_MOD_COMP_WL_REGION_H + +void e_mod_comp_wl_region_destroy(struct wl_client *client __UNUSED__, struct wl_resource *resource); +void e_mod_comp_wl_region_add(struct wl_client *client __UNUSED__, struct wl_resource *resource, int x, int y, int w, int h); +void e_mod_comp_wl_region_subtract(struct wl_client *client __UNUSED__, struct wl_resource *resource, int x, int y, int w, int h); + +# endif +#endif diff --git a/src/modules/comp/e_mod_comp_wl_surface.c b/src/modules/comp/e_mod_comp_wl_surface.c index f5f02845c..d3ce95432 100644 --- a/src/modules/comp/e_mod_comp_wl_surface.c +++ b/src/modules/comp/e_mod_comp_wl_surface.c @@ -139,6 +139,51 @@ e_mod_comp_wl_surface_frame(struct wl_client *client, struct wl_resource *resour wl_list_insert(ws->frame_callbacks.prev, &cb->link); } +void +e_mod_comp_wl_surface_set_opaque_region(struct wl_client *client __UNUSED__, struct wl_resource *resource, struct wl_resource *region_resource) +{ + Wayland_Surface *ws; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ws = resource->data; + pixman_region32_fini(&ws->opaque); + if (region_resource) + { + Wayland_Region *region; + + region = region_resource->data; + pixman_region32_init_rect(&ws->opaque, 0, 0, ws->w, ws->h); + pixman_region32_intersect(&ws->opaque, &ws->opaque, ®ion->region); + } + else + pixman_region32_init(&ws->opaque); +} + +void +e_mod_comp_wl_surface_set_input_region(struct wl_client *client __UNUSED__, struct wl_resource *resource, struct wl_resource *region_resource) +{ + Wayland_Surface *ws; + Wayland_Input *input; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ws = resource->data; + if (region_resource) + { + Wayland_Region *region; + + region = region_resource->data; + pixman_region32_init_rect(&ws->input, 0, 0, ws->w, ws->h); + pixman_region32_intersect(&ws->input, &ws->input, ®ion->region); + } + else + pixman_region32_init_rect(&ws->input, 0, 0, ws->w, ws->h); + + input = e_mod_comp_wl_input_get(); + e_mod_comp_wl_comp_repick(&input->input_device, e_mod_comp_wl_time_get()); +} + void e_mod_comp_wl_surface_destroy_surface(struct wl_resource *resource) { diff --git a/src/modules/comp/e_mod_comp_wl_surface.h b/src/modules/comp/e_mod_comp_wl_surface.h index 23841ee77..208879be4 100644 --- a/src/modules/comp/e_mod_comp_wl_surface.h +++ b/src/modules/comp/e_mod_comp_wl_surface.h @@ -8,6 +8,8 @@ void e_mod_comp_wl_surface_destroy(struct wl_client *client __UNUSED__, struct w void e_mod_comp_wl_surface_attach(struct wl_client *client __UNUSED__, struct wl_resource *resource, struct wl_resource *buffer_resource, int32_t x, int32_t y); void e_mod_comp_wl_surface_damage(struct wl_client *client __UNUSED__, struct wl_resource *resource, int32_t x, int32_t y, int32_t width, int32_t height); void e_mod_comp_wl_surface_frame(struct wl_client *client, struct wl_resource *resource, uint32_t callback); +void e_mod_comp_wl_surface_set_opaque_region(struct wl_client *client __UNUSED__, struct wl_resource *resource, struct wl_resource *region_resource); +void e_mod_comp_wl_surface_set_input_region(struct wl_client *client __UNUSED__, struct wl_resource *resource, struct wl_resource *region_resource); void e_mod_comp_wl_surface_destroy_surface(struct wl_resource *resource); void e_mod_comp_wl_surface_configure(Wayland_Surface *ws, int32_t x, int32_t y, int32_t width, int32_t height); void e_mod_comp_wl_surface_activate(Wayland_Surface *ws, Wayland_Input *wi, uint32_t timestamp);