From 2aafb5dd19f8a3e3436f8843071fa2076a6d2716 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 22 Jun 2017 16:32:47 -0400 Subject: [PATCH 1/7] Add wlcore/wl_shm (WIP) --- CMakeLists.txt | 1 + example/CMakeLists.txt | 13 ++++++ example/compositor.c | 43 +++++++++++++++++++ example/shared.h | 1 - include/endian.h | 8 ++++ include/wlr/render.h | 5 +++ include/wlr/render/interface.h | 8 ++-- include/wlr/wlcore/wl_shm.h | 13 ++++++ render/gles2/renderer.c | 12 ++++++ render/wlr_renderer.c | 5 +++ wlcore/CMakeLists.txt | 3 ++ wlcore/wl_shm.c | 78 ++++++++++++++++++++++++++++++++++ 12 files changed, 186 insertions(+), 4 deletions(-) create mode 100644 example/compositor.c create mode 100644 include/endian.h create mode 100644 include/wlr/wlcore/wl_shm.h create mode 100644 wlcore/CMakeLists.txt create mode 100644 wlcore/wl_shm.c diff --git a/CMakeLists.txt b/CMakeLists.txt index ae2397b2..571b7b61 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,6 +61,7 @@ add_subdirectory(backend) add_subdirectory(types) add_subdirectory(session) add_subdirectory(render) +add_subdirectory(wlcore) add_subdirectory(util) add_subdirectory(example) diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index fff2e49b..6c53e923 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -65,3 +65,16 @@ target_link_libraries(tablet wlr-render ${XKBCOMMON_LIBRARIES} ) + +add_executable(compositor + compositor + shared.c +) + +target_link_libraries(compositor + wlr-backend + wlr-session + wlr-render + wlr-wlcore + ${XKBCOMMON_LIBRARIES} +) diff --git a/example/compositor.c b/example/compositor.c new file mode 100644 index 00000000..5106ec96 --- /dev/null +++ b/example/compositor.c @@ -0,0 +1,43 @@ +#define _POSIX_C_SOURCE 199309L +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "shared.h" + +struct sample_state { + struct wlr_renderer *renderer; +}; + +void handle_output_frame(struct output_state *output, struct timespec *ts) { + struct compositor_state *state = output->compositor; + struct sample_state *sample = state->data; + struct wlr_output *wlr_output = output->output; + + wlr_renderer_begin(sample->renderer, wlr_output); + // TODO: render surfaces + wlr_renderer_end(sample->renderer); +} + +int main() { + struct sample_state state = { 0 }; + struct compositor_state compositor = { 0, + .data = &state, + .output_frame_cb = handle_output_frame, + }; + compositor_init(&compositor); + + state.renderer = wlr_gles2_renderer_init(); + wlr_wl_shm_init(compositor.display); + + compositor_run(&compositor); +} diff --git a/example/shared.h b/example/shared.h index 37f52dcc..1633f2c8 100644 --- a/example/shared.h +++ b/example/shared.h @@ -126,7 +126,6 @@ struct compositor_state { struct wl_listener output_remove; struct wl_list outputs; - bool exit; void *data; }; diff --git a/include/endian.h b/include/endian.h new file mode 100644 index 00000000..0e9b6101 --- /dev/null +++ b/include/endian.h @@ -0,0 +1,8 @@ +#ifndef _WLR_ENDIAN_H +#define _WLR_ENDIAN_H + +// https://stackoverflow.com/a/4240257 + +#define little_endian() (((union { unsigned x; unsigned char c; }){1}).c) + +#endif diff --git a/include/wlr/render.h b/include/wlr/render.h index 90967dd9..496e3638 100644 --- a/include/wlr/render.h +++ b/include/wlr/render.h @@ -38,6 +38,11 @@ void wlr_render_colored_quad(struct wlr_renderer *r, */ void wlr_render_colored_ellipse(struct wlr_renderer *r, const float (*color)[4], const float (*matrix)[16]); +/** + * Returns a list of pixel formats supported by this renderer. + */ +const enum wl_shm_format *wlr_renderer_get_formats( + struct wlr_renderer *r, size_t *len); /** * Destroys this wlr_renderer. Surfaces must be destroyed separately. */ diff --git a/include/wlr/render/interface.h b/include/wlr/render/interface.h index 222b0c4d..c7fa54d6 100644 --- a/include/wlr/render/interface.h +++ b/include/wlr/render/interface.h @@ -20,9 +20,11 @@ struct wlr_renderer_impl { bool (*render_with_matrix)(struct wlr_renderer_state *state, struct wlr_surface *surface, const float (*matrix)[16]); void (*render_quad)(struct wlr_renderer_state *state, - const float (*color)[4], const float (*matrix)[16]); + const float (*color)[4], const float (*matrix)[16]); void (*render_ellipse)(struct wlr_renderer_state *state, - const float (*color)[4], const float (*matrix)[16]); + const float (*color)[4], const float (*matrix)[16]); + const enum wl_shm_format *(*formats)( + struct wlr_renderer_state *state, size_t *len); void (*destroy)(struct wlr_renderer_state *state); }; @@ -36,7 +38,7 @@ struct wlr_surface_impl { struct wl_shm_buffer *shm); // TODO: egl void (*get_matrix)(struct wlr_surface_state *state, - float (*matrix)[16], const float (*projection)[16], int x, int y); + float (*matrix)[16], const float (*projection)[16], int x, int y); void (*bind)(struct wlr_surface_state *state); void (*destroy)(struct wlr_surface_state *state); }; diff --git a/include/wlr/wlcore/wl_shm.h b/include/wlr/wlcore/wl_shm.h new file mode 100644 index 00000000..12c2ef78 --- /dev/null +++ b/include/wlr/wlcore/wl_shm.h @@ -0,0 +1,13 @@ +#ifndef _WLR_WLCORE_WL_SHM_H +#define _WLR_WLCORE_WL_SHM_H +#include +#include + +struct wlr_wl_shm; + +struct wlr_wl_shm *wlr_wl_shm_init(struct wl_display *display); +void wlr_wl_shm_add_format(struct wlr_wl_shm *shm, enum wl_shm_format format); +void wlr_wl_shm_add_renderer_formats( + struct wlr_wl_shm *shm, struct wlr_renderer *renderer); + +#endif diff --git a/render/gles2/renderer.c b/render/gles2/renderer.c index 623f378e..f3906125 100644 --- a/render/gles2/renderer.c +++ b/render/gles2/renderer.c @@ -129,6 +129,7 @@ static void draw_quad() { static bool wlr_gles2_render_surface(struct wlr_renderer_state *state, struct wlr_surface *surface, const float (*matrix)[16]) { assert(surface && surface->valid); + // TODO: Convert GL formats to WL_SHM formats switch (surface->format) { case GL_RGB: GL_CALL(glUseProgram(shaders.rgb)); @@ -163,6 +164,16 @@ static void wlr_gles2_render_ellipse(struct wlr_renderer_state *state, draw_quad(); } +static const enum wl_shm_format *wlr_gles2_formats( + struct wlr_renderer_state *state, size_t *len) { + static enum wl_shm_format formats[] = { + WL_SHM_FORMAT_ARGB8888, + WL_SHM_FORMAT_XRGB8888, + }; + *len = sizeof(formats) / sizeof(formats[0]); + return formats; +} + static void wlr_gles2_destroy(struct wlr_renderer_state *state) { // no-op } @@ -174,6 +185,7 @@ static struct wlr_renderer_impl wlr_renderer_impl = { .render_with_matrix = wlr_gles2_render_surface, .render_quad = wlr_gles2_render_quad, .render_ellipse = wlr_gles2_render_ellipse, + .formats = wlr_gles2_formats, .destroy = wlr_gles2_destroy }; diff --git a/render/wlr_renderer.c b/render/wlr_renderer.c index f48bb3eb..720c5254 100644 --- a/render/wlr_renderer.c +++ b/render/wlr_renderer.c @@ -41,3 +41,8 @@ void wlr_render_colored_ellipse(struct wlr_renderer *r, const float (*color)[4], const float (*matrix)[16]) { r->impl->render_ellipse(r->state, color, matrix); } + +const enum wl_shm_format *wlr_renderer_get_formats( + struct wlr_renderer *r, size_t *len) { + return r->impl->formats(r->state, len); +} diff --git a/wlcore/CMakeLists.txt b/wlcore/CMakeLists.txt new file mode 100644 index 00000000..cf6233c1 --- /dev/null +++ b/wlcore/CMakeLists.txt @@ -0,0 +1,3 @@ +add_library(wlr-wlcore STATIC + wl_shm.c +) diff --git a/wlcore/wl_shm.c b/wlcore/wl_shm.c new file mode 100644 index 00000000..824b3620 --- /dev/null +++ b/wlcore/wl_shm.c @@ -0,0 +1,78 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +struct wlr_wl_shm { + struct wl_global *wl_global; + struct wl_list resources; + struct wl_list pools; + list_t *formats; +}; + +static void wl_shm_destroy(struct wl_resource *resource) { + struct wlr_wl_shm *shm = wl_resource_get_user_data(resource); + struct wl_resource *_resource = NULL; + wl_resource_for_each(_resource, &shm->resources) { + if (_resource == resource) { + struct wl_list *link = wl_resource_get_link(_resource); + wl_list_remove(link); + break; + } + } +} + +struct wl_shm_interface wl_shm_impl = { + //.create_pool = wl_shm_create_pool +}; + +static void wl_shm_bind(struct wl_client *wl_client, void *_wlr_wl_shm, + uint32_t version, uint32_t id) { + struct wlr_wl_shm *wlr_shm = _wlr_wl_shm; + assert(wl_client && wlr_shm); + if (version > 1) { + wlr_log(L_ERROR, "Client requested unsupported wl_shm version, disconnecting"); + wl_client_destroy(wl_client); + return; + } + struct wl_resource *wl_resource = wl_resource_create( + wl_client, &wl_shm_interface, version, id); + wl_resource_set_implementation(wl_resource, &wl_shm_impl, + wlr_shm, wl_shm_destroy); + wl_list_insert(&wlr_shm->resources, wl_resource_get_link(wl_resource)); + for (size_t i = 0; i < wlr_shm->formats->length; ++i) { + uint32_t *f = wlr_shm->formats->items[i]; + wl_shm_send_format(wl_resource, *f); + } +} + +struct wlr_wl_shm *wlr_wl_shm_init(struct wl_display *display) { + struct wlr_wl_shm *shm = calloc(1, sizeof(struct wlr_wl_shm)); + wl_list_init(&shm->resources); + wl_list_init(&shm->pools); + shm->formats = list_create(); + shm->wl_global = wl_global_create(display, &wl_shm_interface, 1, + shm, wl_shm_bind); + return shm; +} + +void wlr_wl_shm_add_format(struct wlr_wl_shm *shm, enum wl_shm_format format) { + assert(shm); + uint32_t *f = calloc(1, sizeof(uint32_t)); + *f = format; + list_add(shm->formats, f); +} + +void wlr_wl_shm_add_renderer_formats(struct wlr_wl_shm *shm, + struct wlr_renderer *renderer) { + assert(shm && renderer); + size_t len; + const enum wl_shm_format *formats = wlr_renderer_get_formats(renderer, &len); + for (size_t i = 0; i < len; ++i) { + wlr_wl_shm_add_format(shm, formats[i]); + } +} From 5a2796266f6f88464396a9cd255dd9d0dedba749 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 23 Jun 2017 14:25:55 -0400 Subject: [PATCH 2/7] Support wl_shm pixel formats in gles2 renderer --- example/rotation.c | 2 +- include/render/gles2.h | 23 +++++++++++++++-- include/wlr/render.h | 5 ++-- include/wlr/render/interface.h | 5 ++-- render/CMakeLists.txt | 1 + render/gles2/pixel_format.c | 45 ++++++++++++++++++++++++++++++++++ render/gles2/renderer.c | 28 ++++++--------------- render/gles2/shaders.c | 15 ++++++------ render/gles2/surface.c | 15 +++++++++--- 9 files changed, 101 insertions(+), 38 deletions(-) create mode 100644 render/gles2/pixel_format.c diff --git a/example/rotation.c b/example/rotation.c index b8c43d4c..84137078 100644 --- a/example/rotation.c +++ b/example/rotation.c @@ -204,7 +204,7 @@ int main(int argc, char *argv[]) { state.renderer = wlr_gles2_renderer_init(); state.cat_texture = wlr_render_surface_init(state.renderer); - wlr_surface_attach_pixels(state.cat_texture, GL_RGBA, + wlr_surface_attach_pixels(state.cat_texture, WL_SHM_FORMAT_ABGR8888, cat_tex.width, cat_tex.height, cat_tex.pixel_data); compositor_run(&compositor); diff --git a/include/render/gles2.h b/include/render/gles2.h index bd0106b3..7b835209 100644 --- a/include/render/gles2.h +++ b/include/render/gles2.h @@ -6,19 +6,38 @@ #include #include +struct pixel_format { + uint32_t wl_format; + GLint gl_format, gl_type; + int depth, bpp; + GLuint *shader; +}; + struct wlr_surface_state { struct wlr_surface *wlr_surface; GLuint tex_id; + const struct pixel_format *pixel_format; }; +struct shaders { + bool initialized; + GLuint rgba, rgbx; + GLuint quad; + GLuint ellipse; +}; + +extern struct shaders shaders; + +const struct pixel_format *gl_format_for_wl_format(enum wl_shm_format fmt); + struct wlr_surface *gles2_surface_init(); extern const GLchar quad_vertex_src[]; extern const GLchar quad_fragment_src[]; extern const GLchar ellipse_fragment_src[]; extern const GLchar vertex_src[]; -extern const GLchar fragment_src_RGB[]; -extern const GLchar fragment_src_RGBA[]; +extern const GLchar fragment_src_rgba[]; +extern const GLchar fragment_src_rgbx[]; bool _gles2_flush_errors(const char *file, int line); #define gles2_flush_errors(...) \ diff --git a/include/wlr/render.h b/include/wlr/render.h index 496e3638..bb333723 100644 --- a/include/wlr/render.h +++ b/include/wlr/render.h @@ -63,8 +63,9 @@ struct wlr_surface { * Attaches a pixel buffer to this surface. The buffer may be discarded after * calling this function. */ -bool wlr_surface_attach_pixels(struct wlr_surface *surf, uint32_t format, - int width, int height, const unsigned char *pixels); +bool wlr_surface_attach_pixels(struct wlr_surface *surf, + enum wl_shm_format format, int width, int height, + const unsigned char *pixels); /** * Attaches pixels from a wl_shm_buffer to this surface. The shm buffer may be * invalidated after calling this function. diff --git a/include/wlr/render/interface.h b/include/wlr/render/interface.h index c7fa54d6..f2168dcd 100644 --- a/include/wlr/render/interface.h +++ b/include/wlr/render/interface.h @@ -32,8 +32,9 @@ struct wlr_renderer *wlr_renderer_init(struct wlr_renderer_state *state, struct wlr_renderer_impl *impl); struct wlr_surface_impl { - bool (*attach_pixels)(struct wlr_surface_state *state, uint32_t format, - int width, int height, const unsigned char *pixels); + bool (*attach_pixels)(struct wlr_surface_state *state, + enum wl_shm_format format, int width, int height, + const unsigned char *pixels); bool (*attach_shm)(struct wlr_surface_state *state, uint32_t format, struct wl_shm_buffer *shm); // TODO: egl diff --git a/render/CMakeLists.txt b/render/CMakeLists.txt index 70ebced2..63412b61 100644 --- a/render/CMakeLists.txt +++ b/render/CMakeLists.txt @@ -5,5 +5,6 @@ add_library(wlr-render STATIC gles2/shaders.c gles2/renderer.c gles2/surface.c + gles2/pixel_format.c gles2/util.c ) diff --git a/render/gles2/pixel_format.c b/render/gles2/pixel_format.c new file mode 100644 index 00000000..a0b9d09f --- /dev/null +++ b/render/gles2/pixel_format.c @@ -0,0 +1,45 @@ +#include +#include +#include "render/gles2.h" + +// Adapted from weston +struct pixel_format formats[] = { + { + .wl_format = WL_SHM_FORMAT_ARGB8888, + .depth = 32, + .bpp = 32, + .gl_format = GL_BGRA_EXT, + .gl_type = GL_UNSIGNED_BYTE, + .shader = &shaders.rgba + }, + { + .wl_format = WL_SHM_FORMAT_XRGB8888, + .depth = 24, + .bpp = 32, + .gl_format = GL_BGRA_EXT, + .gl_type = GL_UNSIGNED_BYTE, + .shader = &shaders.rgbx + }, + { + .wl_format = WL_SHM_FORMAT_XBGR8888, + .gl_format = GL_RGBA, + .gl_type = GL_UNSIGNED_BYTE, + .shader = &shaders.rgbx + }, + { + .wl_format = WL_SHM_FORMAT_ABGR8888, + .gl_format = GL_RGBA, + .gl_type = GL_UNSIGNED_BYTE, + .shader = &shaders.rgba + }, +}; +// TODO: more pixel formats + +const struct pixel_format *gl_format_for_wl_format(enum wl_shm_format fmt) { + for (size_t i = 0; i < sizeof(formats) / sizeof(*formats); ++i) { + if (formats[i].wl_format == fmt) { + return &formats[i]; + } + } + return NULL; +} diff --git a/render/gles2/renderer.c b/render/gles2/renderer.c index f3906125..897dc3b8 100644 --- a/render/gles2/renderer.c +++ b/render/gles2/renderer.c @@ -10,12 +10,7 @@ #include #include "render/gles2.h" -static struct { - bool initialized; - GLuint rgb, rgba; - GLuint quad; - GLuint ellipse; -} shaders; +struct shaders shaders; static bool compile_shader(GLuint type, const GLchar *src, GLuint *shader) { *shader = GL_CALL(glCreateShader(type)); @@ -58,10 +53,10 @@ static void init_default_shaders() { if (shaders.initialized) { return; } - if (!compile_program(vertex_src, fragment_src_RGB, &shaders.rgb)) { + if (!compile_program(vertex_src, fragment_src_rgba, &shaders.rgba)) { goto error; } - if (!compile_program(vertex_src, fragment_src_RGBA, &shaders.rgba)) { + if (!compile_program(vertex_src, fragment_src_rgbx, &shaders.rgbx)) { goto error; } if (!compile_program(quad_vertex_src, quad_fragment_src, &shaders.quad)) { @@ -129,21 +124,10 @@ static void draw_quad() { static bool wlr_gles2_render_surface(struct wlr_renderer_state *state, struct wlr_surface *surface, const float (*matrix)[16]) { assert(surface && surface->valid); - // TODO: Convert GL formats to WL_SHM formats - switch (surface->format) { - case GL_RGB: - GL_CALL(glUseProgram(shaders.rgb)); - break; - case GL_RGBA: - GL_CALL(glUseProgram(shaders.rgba)); - break; - default: - wlr_log(L_ERROR, "No shader for this surface format"); - return false; - } - gles2_flush_errors(); wlr_surface_bind(surface); GL_CALL(glUniformMatrix4fv(0, 1, GL_FALSE, *matrix)); + // TODO: source alpha from somewhere else I guess + GL_CALL(glUniform1f(2, 1.0f)); draw_quad(); return true; } @@ -169,6 +153,8 @@ static const enum wl_shm_format *wlr_gles2_formats( static enum wl_shm_format formats[] = { WL_SHM_FORMAT_ARGB8888, WL_SHM_FORMAT_XRGB8888, + WL_SHM_FORMAT_ABGR8888, + WL_SHM_FORMAT_XBGR8888, }; *len = sizeof(formats) / sizeof(formats[0]); return formats; diff --git a/render/gles2/shaders.c b/render/gles2/shaders.c index 62712230..f5e61dd6 100644 --- a/render/gles2/shaders.c +++ b/render/gles2/shaders.c @@ -20,7 +20,6 @@ const GLchar quad_vertex_src[] = " vec4(i0.z, i1.z, i2.z, i3.z)," " vec4(i0.w, i1.w, i2.w, i3.w)" " );" -"" " return outMatrix;" "}" "void main() {" @@ -37,8 +36,7 @@ const GLchar quad_fragment_src[] = " gl_FragColor = v_color;" "}"; -// Colored ellipses (TODO) - +// Colored ellipses const GLchar ellipse_fragment_src[] = "precision mediump float;" "varying vec4 v_color;" @@ -74,18 +72,21 @@ const GLchar vertex_src[] = " v_texcoord = texcoord;" "}"; -const GLchar fragment_src_RGB[] = +const GLchar fragment_src_rgba[] = "precision mediump float;" "varying vec2 v_texcoord;" "uniform sampler2D tex;" +"uniform float alpha;" "void main() {" -" gl_FragColor = vec4(texture2D(tex, v_texcoord).rgb, 1.0);" +" gl_FragColor = alpha * texture2D(tex, v_texcoord);" "}"; -const GLchar fragment_src_RGBA[] = +const GLchar fragment_src_rgbx[] = "precision mediump float;" "varying vec2 v_texcoord;" "uniform sampler2D tex;" +"uniform float alpha;" "void main() {" -" gl_FragColor = texture2D(tex, v_texcoord);" +" gl_FragColor.rgb = alpha * texture2D(tex, v_texcoord).rgb;" +" gl_FragColor.a = alpha;" "}"; diff --git a/render/gles2/surface.c b/render/gles2/surface.c index 278b3dc3..8c2f459f 100644 --- a/render/gles2/surface.c +++ b/render/gles2/surface.c @@ -7,18 +7,26 @@ #include #include #include +#include #include "render/gles2.h" static bool gles2_surface_attach_pixels(struct wlr_surface_state *surface, - uint32_t format, int width, int height, const unsigned char *pixels) { + enum wl_shm_format format, int width, int height, + const unsigned char *pixels) { assert(surface); + const struct pixel_format *fmt = gl_format_for_wl_format(format); + if (!fmt || !fmt->gl_format) { + wlr_log(L_ERROR, "No supported pixel format for this surface"); + return false; + } surface->wlr_surface->width = width; surface->wlr_surface->height = height; surface->wlr_surface->format = format; + surface->pixel_format = fmt; GL_CALL(glGenTextures(1, &surface->tex_id)); GL_CALL(glBindTexture(GL_TEXTURE_2D, surface->tex_id)); - GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, - format, GL_UNSIGNED_BYTE, pixels)); + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, fmt->gl_format, width, height, 0, + fmt->gl_format, fmt->gl_type, pixels)); surface->wlr_surface->valid = true; return true; } @@ -40,6 +48,7 @@ static void gles2_surface_bind(struct wlr_surface_state *surface) { GL_CALL(glBindTexture(GL_TEXTURE_2D, surface->tex_id)); GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + GL_CALL(glUseProgram(*surface->pixel_format->shader)); } static void gles2_surface_destroy(struct wlr_surface_state *surface) { From 8a18cf456aac6fee666ccb4e7df0a9eb6c059756 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 23 Jun 2017 14:46:12 -0400 Subject: [PATCH 3/7] Remove endian.h Fuck big endian systems anyway --- include/endian.h | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 include/endian.h diff --git a/include/endian.h b/include/endian.h deleted file mode 100644 index 0e9b6101..00000000 --- a/include/endian.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _WLR_ENDIAN_H -#define _WLR_ENDIAN_H - -// https://stackoverflow.com/a/4240257 - -#define little_endian() (((union { unsigned x; unsigned char c; }){1}).c) - -#endif From f5b7bc033eced5c1ba3ba63b52985fb9b0e9f618 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 23 Jun 2017 15:10:52 -0400 Subject: [PATCH 4/7] Add wlr_wl_compositor and remove wlr_wl_shm --- CMakeLists.txt | 2 +- example/CMakeLists.txt | 2 +- example/compositor.c | 5 +- include/wlr/types/wlr_output.h | 3 +- include/wlr/wayland/wlr_compositor.h | 25 +++++++++ include/wlr/wlcore/wl_shm.h | 13 ----- types/wlr_output.c | 6 +-- wayland/CMakeLists.txt | 3 ++ wayland/wlr_compositor.c | 60 +++++++++++++++++++++ wlcore/CMakeLists.txt | 3 -- wlcore/wl_shm.c | 78 ---------------------------- 11 files changed, 98 insertions(+), 102 deletions(-) create mode 100644 include/wlr/wayland/wlr_compositor.h delete mode 100644 include/wlr/wlcore/wl_shm.h create mode 100644 wayland/CMakeLists.txt create mode 100644 wayland/wlr_compositor.c delete mode 100644 wlcore/CMakeLists.txt delete mode 100644 wlcore/wl_shm.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 571b7b61..bd3d4219 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,7 +61,7 @@ add_subdirectory(backend) add_subdirectory(types) add_subdirectory(session) add_subdirectory(render) -add_subdirectory(wlcore) +add_subdirectory(wayland) add_subdirectory(util) add_subdirectory(example) diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 6c53e923..100e110a 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -75,6 +75,6 @@ target_link_libraries(compositor wlr-backend wlr-session wlr-render - wlr-wlcore + wlr-wayland ${XKBCOMMON_LIBRARIES} ) diff --git a/example/compositor.c b/example/compositor.c index 5106ec96..a52fe460 100644 --- a/example/compositor.c +++ b/example/compositor.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include "shared.h" @@ -37,7 +37,8 @@ int main() { compositor_init(&compositor); state.renderer = wlr_gles2_renderer_init(); - wlr_wl_shm_init(compositor.display); + wl_display_init_shm(compositor.display); + wlr_compositor_init(compositor.display); compositor_run(&compositor); } diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h index 71e1d0fe..6c7c320d 100644 --- a/include/wlr/types/wlr_output.h +++ b/include/wlr/types/wlr_output.h @@ -19,8 +19,9 @@ struct wlr_output_state; struct wlr_output { const struct wlr_output_impl *impl; struct wlr_output_state *state; + void *user_data; struct wl_global *wl_global; - struct wl_list resource_list; + struct wl_list wl_resources; uint32_t flags; char name[16]; diff --git a/include/wlr/wayland/wlr_compositor.h b/include/wlr/wayland/wlr_compositor.h new file mode 100644 index 00000000..2c2ade62 --- /dev/null +++ b/include/wlr/wayland/wlr_compositor.h @@ -0,0 +1,25 @@ +#ifndef _WLR_COMPOSITOR_H +#define _WLR_COMPOSITOR_H +#include + +struct wlr_compositor_state; + +struct wlr_compositor { + struct wlr_compositor_state *state; + void *user_data; + struct wl_global *wl_global; + struct wl_list wl_resources; + + struct { + /** Emits a reference to the wl_resource just created */ + struct wl_signal bound; + /** Emits a reference to the wl_surface just created */ + struct wl_signal create_surface; + /** Emits a reference to the wl_region just created */ + struct wl_signal create_region; + } events; +}; + +struct wlr_compositor *wlr_compositor_init(struct wl_display *display); + +#endif diff --git a/include/wlr/wlcore/wl_shm.h b/include/wlr/wlcore/wl_shm.h deleted file mode 100644 index 12c2ef78..00000000 --- a/include/wlr/wlcore/wl_shm.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _WLR_WLCORE_WL_SHM_H -#define _WLR_WLCORE_WL_SHM_H -#include -#include - -struct wlr_wl_shm; - -struct wlr_wl_shm *wlr_wl_shm_init(struct wl_display *display); -void wlr_wl_shm_add_format(struct wlr_wl_shm *shm, enum wl_shm_format format); -void wlr_wl_shm_add_renderer_formats( - struct wlr_wl_shm *shm, struct wlr_renderer *renderer); - -#endif diff --git a/types/wlr_output.c b/types/wlr_output.c index 4d2e7778..b6ca7e79 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -41,7 +41,7 @@ static void wl_output_send_to_resource(struct wl_resource *resource) { static void wl_output_destroy(struct wl_resource *resource) { struct wlr_output *output = wl_resource_get_user_data(resource); struct wl_resource *_resource = NULL; - wl_resource_for_each(_resource, &output->resource_list) { + wl_resource_for_each(_resource, &output->wl_resources) { if (_resource == resource) { struct wl_list *link = wl_resource_get_link(_resource); wl_list_remove(link); @@ -71,7 +71,7 @@ static void wl_output_bind(struct wl_client *wl_client, void *_wlr_output, wl_client, &wl_output_interface, version, id); wl_resource_set_implementation(wl_resource, &wl_output_impl, wlr_output, wl_output_destroy); - wl_list_insert(&wlr_output->resource_list, wl_resource_get_link(wl_resource)); + wl_list_insert(&wlr_output->wl_resources, wl_resource_get_link(wl_resource)); wl_output_send_to_resource(wl_resource); } @@ -80,7 +80,7 @@ struct wl_global *wlr_output_create_global( struct wl_global *wl_global = wl_global_create(display, &wl_output_interface, 3, wlr_output, wl_output_bind); wlr_output->wl_global = wl_global; - wl_list_init(&wlr_output->resource_list); + wl_list_init(&wlr_output->wl_resources); return wl_global; } diff --git a/wayland/CMakeLists.txt b/wayland/CMakeLists.txt new file mode 100644 index 00000000..b629a95c --- /dev/null +++ b/wayland/CMakeLists.txt @@ -0,0 +1,3 @@ +add_library(wlr-wayland STATIC + wlr_compositor.c +) diff --git a/wayland/wlr_compositor.c b/wayland/wlr_compositor.c new file mode 100644 index 00000000..631c22b6 --- /dev/null +++ b/wayland/wlr_compositor.c @@ -0,0 +1,60 @@ +#include +#include +#include +#include +#include + +static void wl_compositor_create_surface(struct wl_client *client, + struct wl_resource *resource, uint32_t id) { + wlr_log(L_DEBUG, "Creating surface for client"); +} + +static void wl_compositor_create_region(struct wl_client *client, + struct wl_resource *resource, uint32_t id) { + wlr_log(L_DEBUG, "Creating region for client"); +} + +static struct wl_compositor_interface wl_compositor_impl = { + .create_surface = wl_compositor_create_surface, + .create_region = wl_compositor_create_region, +}; + +static void wl_compositor_destroy(struct wl_resource *wl_resource) { + struct wlr_compositor *wlr_c = wl_resource_get_user_data(wl_resource); + struct wl_resource *_wl_resource = NULL; + wl_resource_for_each(_wl_resource, &wlr_c->wl_resources) { + if (_wl_resource == wl_resource) { + struct wl_list *link = wl_resource_get_link(_wl_resource); + wl_list_remove(link); + break; + } + } +} + +static void wl_compositor_bind(struct wl_client *wl_client, + void *_wlr_compositor, uint32_t version, uint32_t id) { + struct wlr_compositor *wlr_c = _wlr_compositor; + assert(wl_client && wlr_c); + if (version > 3) { + wlr_log(L_ERROR, "Client requested unsupported wl_compositor version, disconnecting"); + wl_client_destroy(wl_client); + return; + } + struct wl_resource *wl_resource = wl_resource_create( + wl_client, &wl_compositor_interface, version, id); + wl_resource_set_implementation(wl_resource, &wl_compositor_impl, + wlr_c, wl_compositor_destroy); + wl_list_insert(&wlr_c->wl_resources, wl_resource_get_link(wl_resource)); +} + +struct wlr_compositor *wlr_compositor_init(struct wl_display *display) { + struct wlr_compositor *wlr_c = calloc(1, sizeof(struct wlr_compositor)); + struct wl_global *wl_global = wl_global_create(display, + &wl_compositor_interface, 1, wlr_c, wl_compositor_bind); + wlr_c->wl_global = wl_global; + wl_list_init(&wlr_c->wl_resources); + wl_signal_init(&wlr_c->events.bound); + wl_signal_init(&wlr_c->events.create_surface); + wl_signal_init(&wlr_c->events.create_region); + return wlr_c; +} diff --git a/wlcore/CMakeLists.txt b/wlcore/CMakeLists.txt deleted file mode 100644 index cf6233c1..00000000 --- a/wlcore/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -add_library(wlr-wlcore STATIC - wl_shm.c -) diff --git a/wlcore/wl_shm.c b/wlcore/wl_shm.c deleted file mode 100644 index 824b3620..00000000 --- a/wlcore/wl_shm.c +++ /dev/null @@ -1,78 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -struct wlr_wl_shm { - struct wl_global *wl_global; - struct wl_list resources; - struct wl_list pools; - list_t *formats; -}; - -static void wl_shm_destroy(struct wl_resource *resource) { - struct wlr_wl_shm *shm = wl_resource_get_user_data(resource); - struct wl_resource *_resource = NULL; - wl_resource_for_each(_resource, &shm->resources) { - if (_resource == resource) { - struct wl_list *link = wl_resource_get_link(_resource); - wl_list_remove(link); - break; - } - } -} - -struct wl_shm_interface wl_shm_impl = { - //.create_pool = wl_shm_create_pool -}; - -static void wl_shm_bind(struct wl_client *wl_client, void *_wlr_wl_shm, - uint32_t version, uint32_t id) { - struct wlr_wl_shm *wlr_shm = _wlr_wl_shm; - assert(wl_client && wlr_shm); - if (version > 1) { - wlr_log(L_ERROR, "Client requested unsupported wl_shm version, disconnecting"); - wl_client_destroy(wl_client); - return; - } - struct wl_resource *wl_resource = wl_resource_create( - wl_client, &wl_shm_interface, version, id); - wl_resource_set_implementation(wl_resource, &wl_shm_impl, - wlr_shm, wl_shm_destroy); - wl_list_insert(&wlr_shm->resources, wl_resource_get_link(wl_resource)); - for (size_t i = 0; i < wlr_shm->formats->length; ++i) { - uint32_t *f = wlr_shm->formats->items[i]; - wl_shm_send_format(wl_resource, *f); - } -} - -struct wlr_wl_shm *wlr_wl_shm_init(struct wl_display *display) { - struct wlr_wl_shm *shm = calloc(1, sizeof(struct wlr_wl_shm)); - wl_list_init(&shm->resources); - wl_list_init(&shm->pools); - shm->formats = list_create(); - shm->wl_global = wl_global_create(display, &wl_shm_interface, 1, - shm, wl_shm_bind); - return shm; -} - -void wlr_wl_shm_add_format(struct wlr_wl_shm *shm, enum wl_shm_format format) { - assert(shm); - uint32_t *f = calloc(1, sizeof(uint32_t)); - *f = format; - list_add(shm->formats, f); -} - -void wlr_wl_shm_add_renderer_formats(struct wlr_wl_shm *shm, - struct wlr_renderer *renderer) { - assert(shm && renderer); - size_t len; - const enum wl_shm_format *formats = wlr_renderer_get_formats(renderer, &len); - for (size_t i = 0; i < len; ++i) { - wlr_wl_shm_add_format(shm, formats[i]); - } -} From 18e6ddc1c5b091a66113ecf0d761a37980882ce3 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 28 Jun 2017 17:25:01 -0400 Subject: [PATCH 5/7] Remove wlr_compositor --- CMakeLists.txt | 1 - include/wlr/wayland/wlr_compositor.h | 25 ------------ wayland/CMakeLists.txt | 3 -- wayland/wlr_compositor.c | 60 ---------------------------- 4 files changed, 89 deletions(-) delete mode 100644 include/wlr/wayland/wlr_compositor.h delete mode 100644 wayland/CMakeLists.txt delete mode 100644 wayland/wlr_compositor.c diff --git a/CMakeLists.txt b/CMakeLists.txt index bd3d4219..ae2397b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,7 +61,6 @@ add_subdirectory(backend) add_subdirectory(types) add_subdirectory(session) add_subdirectory(render) -add_subdirectory(wayland) add_subdirectory(util) add_subdirectory(example) diff --git a/include/wlr/wayland/wlr_compositor.h b/include/wlr/wayland/wlr_compositor.h deleted file mode 100644 index 2c2ade62..00000000 --- a/include/wlr/wayland/wlr_compositor.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _WLR_COMPOSITOR_H -#define _WLR_COMPOSITOR_H -#include - -struct wlr_compositor_state; - -struct wlr_compositor { - struct wlr_compositor_state *state; - void *user_data; - struct wl_global *wl_global; - struct wl_list wl_resources; - - struct { - /** Emits a reference to the wl_resource just created */ - struct wl_signal bound; - /** Emits a reference to the wl_surface just created */ - struct wl_signal create_surface; - /** Emits a reference to the wl_region just created */ - struct wl_signal create_region; - } events; -}; - -struct wlr_compositor *wlr_compositor_init(struct wl_display *display); - -#endif diff --git a/wayland/CMakeLists.txt b/wayland/CMakeLists.txt deleted file mode 100644 index b629a95c..00000000 --- a/wayland/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -add_library(wlr-wayland STATIC - wlr_compositor.c -) diff --git a/wayland/wlr_compositor.c b/wayland/wlr_compositor.c deleted file mode 100644 index 631c22b6..00000000 --- a/wayland/wlr_compositor.c +++ /dev/null @@ -1,60 +0,0 @@ -#include -#include -#include -#include -#include - -static void wl_compositor_create_surface(struct wl_client *client, - struct wl_resource *resource, uint32_t id) { - wlr_log(L_DEBUG, "Creating surface for client"); -} - -static void wl_compositor_create_region(struct wl_client *client, - struct wl_resource *resource, uint32_t id) { - wlr_log(L_DEBUG, "Creating region for client"); -} - -static struct wl_compositor_interface wl_compositor_impl = { - .create_surface = wl_compositor_create_surface, - .create_region = wl_compositor_create_region, -}; - -static void wl_compositor_destroy(struct wl_resource *wl_resource) { - struct wlr_compositor *wlr_c = wl_resource_get_user_data(wl_resource); - struct wl_resource *_wl_resource = NULL; - wl_resource_for_each(_wl_resource, &wlr_c->wl_resources) { - if (_wl_resource == wl_resource) { - struct wl_list *link = wl_resource_get_link(_wl_resource); - wl_list_remove(link); - break; - } - } -} - -static void wl_compositor_bind(struct wl_client *wl_client, - void *_wlr_compositor, uint32_t version, uint32_t id) { - struct wlr_compositor *wlr_c = _wlr_compositor; - assert(wl_client && wlr_c); - if (version > 3) { - wlr_log(L_ERROR, "Client requested unsupported wl_compositor version, disconnecting"); - wl_client_destroy(wl_client); - return; - } - struct wl_resource *wl_resource = wl_resource_create( - wl_client, &wl_compositor_interface, version, id); - wl_resource_set_implementation(wl_resource, &wl_compositor_impl, - wlr_c, wl_compositor_destroy); - wl_list_insert(&wlr_c->wl_resources, wl_resource_get_link(wl_resource)); -} - -struct wlr_compositor *wlr_compositor_init(struct wl_display *display) { - struct wlr_compositor *wlr_c = calloc(1, sizeof(struct wlr_compositor)); - struct wl_global *wl_global = wl_global_create(display, - &wl_compositor_interface, 1, wlr_c, wl_compositor_bind); - wlr_c->wl_global = wl_global; - wl_list_init(&wlr_c->wl_resources); - wl_signal_init(&wlr_c->events.bound); - wl_signal_init(&wlr_c->events.create_surface); - wl_signal_init(&wlr_c->events.create_region); - return wlr_c; -} From 28736c578701393f35cac2bd2ad49de18d7f879e Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 28 Jun 2017 18:23:49 -0400 Subject: [PATCH 6/7] Move example -> examples And the compositor example into its own directory --- CMakeLists.txt | 2 +- {example => examples}/CMakeLists.txt | 3 +-- {example => examples}/cat.c | 0 {example => examples}/cat.h | 0 example/compositor.c => examples/compositor/main.c | 2 -- {example => examples}/pointer.c | 0 {example => examples}/rotation.c | 0 {example => examples}/shared.c | 0 {example => examples}/shared.h | 0 {example => examples}/simple.c | 0 {example => examples}/tablet.c | 0 {example => examples}/touch.c | 0 12 files changed, 2 insertions(+), 5 deletions(-) rename {example => examples}/CMakeLists.txt (97%) rename {example => examples}/cat.c (100%) rename {example => examples}/cat.h (100%) rename example/compositor.c => examples/compositor/main.c (92%) rename {example => examples}/pointer.c (100%) rename {example => examples}/rotation.c (100%) rename {example => examples}/shared.c (100%) rename {example => examples}/shared.h (100%) rename {example => examples}/simple.c (100%) rename {example => examples}/tablet.c (100%) rename {example => examples}/touch.c (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index ae2397b2..b15882ce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,4 +63,4 @@ add_subdirectory(session) add_subdirectory(render) add_subdirectory(util) -add_subdirectory(example) +add_subdirectory(examples) diff --git a/example/CMakeLists.txt b/examples/CMakeLists.txt similarity index 97% rename from example/CMakeLists.txt rename to examples/CMakeLists.txt index 100e110a..956ea886 100644 --- a/example/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -67,7 +67,7 @@ target_link_libraries(tablet ) add_executable(compositor - compositor + compositor/main.c shared.c ) @@ -75,6 +75,5 @@ target_link_libraries(compositor wlr-backend wlr-session wlr-render - wlr-wayland ${XKBCOMMON_LIBRARIES} ) diff --git a/example/cat.c b/examples/cat.c similarity index 100% rename from example/cat.c rename to examples/cat.c diff --git a/example/cat.h b/examples/cat.h similarity index 100% rename from example/cat.h rename to examples/cat.h diff --git a/example/compositor.c b/examples/compositor/main.c similarity index 92% rename from example/compositor.c rename to examples/compositor/main.c index a52fe460..3e83978e 100644 --- a/example/compositor.c +++ b/examples/compositor/main.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include "shared.h" @@ -38,7 +37,6 @@ int main() { state.renderer = wlr_gles2_renderer_init(); wl_display_init_shm(compositor.display); - wlr_compositor_init(compositor.display); compositor_run(&compositor); } diff --git a/example/pointer.c b/examples/pointer.c similarity index 100% rename from example/pointer.c rename to examples/pointer.c diff --git a/example/rotation.c b/examples/rotation.c similarity index 100% rename from example/rotation.c rename to examples/rotation.c diff --git a/example/shared.c b/examples/shared.c similarity index 100% rename from example/shared.c rename to examples/shared.c diff --git a/example/shared.h b/examples/shared.h similarity index 100% rename from example/shared.h rename to examples/shared.h diff --git a/example/simple.c b/examples/simple.c similarity index 100% rename from example/simple.c rename to examples/simple.c diff --git a/example/tablet.c b/examples/tablet.c similarity index 100% rename from example/tablet.c rename to examples/tablet.c diff --git a/example/touch.c b/examples/touch.c similarity index 100% rename from example/touch.c rename to examples/touch.c From 486ec5953cf51f5fde834bf8fa7fbe56f0be9a0e Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 28 Jun 2017 18:51:58 -0400 Subject: [PATCH 7/7] Add shim implementations of wl_{compositor,shell} To example compositor --- examples/CMakeLists.txt | 2 ++ examples/compositor.h | 21 +++++++++++ examples/compositor/main.c | 5 +++ examples/compositor/wl_compositor.c | 55 +++++++++++++++++++++++++++++ examples/compositor/wl_shell.c | 50 ++++++++++++++++++++++++++ 5 files changed, 133 insertions(+) create mode 100644 examples/compositor.h create mode 100644 examples/compositor/wl_compositor.c create mode 100644 examples/compositor/wl_shell.c diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 956ea886..f3f555c3 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -68,6 +68,8 @@ target_link_libraries(tablet add_executable(compositor compositor/main.c + compositor/wl_compositor.c + compositor/wl_shell.c shared.c ) diff --git a/examples/compositor.h b/examples/compositor.h new file mode 100644 index 00000000..4773b83d --- /dev/null +++ b/examples/compositor.h @@ -0,0 +1,21 @@ +#ifndef _EXAMPLE_COMPOSITOR_H +#define _EXAMPLE_COMPOSITOR_H +#include + +struct wl_compositor_state { + struct wl_global *wl_global; + struct wl_list wl_resources; +}; + +void wl_compositor_init(struct wl_display *display, + struct wl_compositor_state *state); + +struct wl_shell_state { + struct wl_global *wl_global; + struct wl_list wl_resources; +}; + +void wl_shell_init(struct wl_display *display, + struct wl_shell_state *state); + +#endif diff --git a/examples/compositor/main.c b/examples/compositor/main.c index 3e83978e..062669a2 100644 --- a/examples/compositor/main.c +++ b/examples/compositor/main.c @@ -12,9 +12,12 @@ #include #include #include "shared.h" +#include "compositor.h" struct sample_state { struct wlr_renderer *renderer; + struct wl_compositor_state compositor; + struct wl_shell_state shell; }; void handle_output_frame(struct output_state *output, struct timespec *ts) { @@ -37,6 +40,8 @@ int main() { state.renderer = wlr_gles2_renderer_init(); wl_display_init_shm(compositor.display); + wl_compositor_init(compositor.display, &state.compositor); + wl_shell_init(compositor.display, &state.shell); compositor_run(&compositor); } diff --git a/examples/compositor/wl_compositor.c b/examples/compositor/wl_compositor.c new file mode 100644 index 00000000..0cd73afb --- /dev/null +++ b/examples/compositor/wl_compositor.c @@ -0,0 +1,55 @@ +#include +#include +#include +#include "compositor.h" + +static void wl_compositor_create_surface(struct wl_client *client, + struct wl_resource *resource, uint32_t id) { + wlr_log(L_DEBUG, "TODO: implement create_surface"); +} + +static void wl_compositor_create_region(struct wl_client *client, + struct wl_resource *resource, uint32_t id) { + wlr_log(L_DEBUG, "TODO: implement create_region"); +} + +struct wl_compositor_interface wl_compositor_impl = { + .create_surface = wl_compositor_create_surface, + .create_region = wl_compositor_create_region +}; + +static void wl_compositor_destroy(struct wl_resource *resource) { + struct wl_compositor_state *state = wl_resource_get_user_data(resource); + struct wl_resource *_resource = NULL; + wl_resource_for_each(_resource, &state->wl_resources) { + if (_resource == resource) { + struct wl_list *link = wl_resource_get_link(_resource); + wl_list_remove(link); + break; + } + } +} + +static void wl_compositor_bind(struct wl_client *wl_client, void *_state, + uint32_t version, uint32_t id) { + struct wl_compositor_state *state = _state; + assert(wl_client && state); + if (version > 4) { + wlr_log(L_ERROR, "Client requested unsupported wl_compositor version, disconnecting"); + wl_client_destroy(wl_client); + return; + } + struct wl_resource *wl_resource = wl_resource_create( + wl_client, &wl_compositor_interface, version, id); + wl_resource_set_implementation(wl_resource, &wl_compositor_impl, + state, wl_compositor_destroy); + wl_list_insert(&state->wl_resources, wl_resource_get_link(wl_resource)); +} + +void wl_compositor_init(struct wl_display *display, + struct wl_compositor_state *state) { + struct wl_global *wl_global = wl_global_create(display, + &wl_compositor_interface, 4, state, wl_compositor_bind); + state->wl_global = wl_global; + wl_list_init(&state->wl_resources); +} diff --git a/examples/compositor/wl_shell.c b/examples/compositor/wl_shell.c new file mode 100644 index 00000000..f2ec3c56 --- /dev/null +++ b/examples/compositor/wl_shell.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include "compositor.h" + +void wl_shell_get_shell_surface(struct wl_client *client, + struct wl_resource *resource, uint32_t id, + struct wl_resource *surface) { + wlr_log(L_DEBUG, "TODO: implement get_shell_surface"); +} + +static struct wl_shell_interface wl_shell_impl = { + .get_shell_surface = wl_shell_get_shell_surface +}; + +static void wl_shell_destroy(struct wl_resource *resource) { + struct wl_shell_state *state = wl_resource_get_user_data(resource); + struct wl_resource *_resource = NULL; + wl_resource_for_each(_resource, &state->wl_resources) { + if (_resource == resource) { + struct wl_list *link = wl_resource_get_link(_resource); + wl_list_remove(link); + break; + } + } +} + +static void wl_shell_bind(struct wl_client *wl_client, void *_state, + uint32_t version, uint32_t id) { + struct wl_shell_state *state = _state; + assert(wl_client && state); + if (version > 1) { + wlr_log(L_ERROR, "Client requested unsupported wl_shell version, disconnecting"); + wl_client_destroy(wl_client); + return; + } + struct wl_resource *wl_resource = wl_resource_create( + wl_client, &wl_shell_interface, version, id); + wl_resource_set_implementation(wl_resource, &wl_shell_impl, + state, wl_shell_destroy); + wl_list_insert(&state->wl_resources, wl_resource_get_link(wl_resource)); +} + +void wl_shell_init(struct wl_display *display, + struct wl_shell_state *state) { + struct wl_global *wl_global = wl_global_create(display, + &wl_shell_interface, 1, state, wl_shell_bind); + state->wl_global = wl_global; + wl_list_init(&state->wl_resources); +}