wio

a wayland wm stylised after plan9 rio - forked from git.sr.ht/~srcmpwn/wio
git clone git://src.gearsix.net/wio
Log | Files | Refs | Atom | Submodules | README | LICENSE

commit 765b9bd99fb181078e15c553e0cbd57d2c0908ea
parent 2e46c9d760a6541606eec145a2b9ba9e7af1b351
Author: Drew DeVault <sir@cmpwn.com>
Date:   Tue, 23 Apr 2019 21:26:27 -0400

Receive & render new XDG surfaces

Diffstat:
Minclude/server.h | 5+++++
Ainclude/view.h | 18++++++++++++++++++
Mmain.c | 8++++++++
Mmeson.build | 1+
Moutput.c | 54+++++++++++++++++++++++++++++++++++++++++++++++++++++-
Aview.c | 29+++++++++++++++++++++++++++++
6 files changed, 114 insertions(+), 1 deletion(-)

diff --git a/include/server.h b/include/server.h @@ -10,6 +10,7 @@ #include <wlr/types/wlr_output_layout.h> #include <wlr/types/wlr_pointer.h> #include <wlr/types/wlr_xcursor_manager.h> +#include <wlr/types/wlr_xdg_shell.h> struct wio_server { struct wl_display *wl_display; @@ -20,11 +21,13 @@ struct wio_server { struct wlr_renderer *renderer; struct wlr_seat *seat; struct wlr_xcursor_manager *cursor_mgr; + struct wlr_xdg_shell *xdg_shell; struct wl_list outputs; struct wl_list inputs; struct wl_list pointers; struct wl_list keyboards; + struct wl_list views; struct wl_listener new_output; struct wl_listener new_input; @@ -32,6 +35,8 @@ struct wio_server { struct wl_listener cursor_motion_absolute; struct wl_listener cursor_button; struct wl_listener cursor_axis; + + struct wl_listener new_xdg_surface; }; struct wio_output { diff --git a/include/view.h b/include/view.h @@ -0,0 +1,18 @@ +#ifndef _WIO_VIEW_H +#define _WIO_VIEW_H +#include <wlr/types/wlr_xdg_shell.h> +#include <wayland-server.h> + +struct wio_server; + +struct wio_view { + int x, y; + struct wlr_xdg_surface *xdg_surface; + struct wio_server *server; + struct wl_list link; + struct wl_listener destroy; +}; + +void server_new_xdg_surface(struct wl_listener *listener, void *data); + +#endif diff --git a/main.c b/main.c @@ -8,8 +8,10 @@ #include <wlr/types/wlr_data_device.h> #include <wlr/types/wlr_seat.h> #include <wlr/types/wlr_xcursor_manager.h> +#include <wlr/types/wlr_xdg_shell.h> #include <wlr/util/log.h> #include "server.h" +#include "view.h" int main(int argc, char **argv) { struct wio_server server; @@ -56,6 +58,12 @@ int main(int argc, char **argv) { wl_list_init(&server.keyboards); wl_list_init(&server.pointers); + wl_list_init(&server.views); + server.xdg_shell = wlr_xdg_shell_create(server.wl_display); + server.new_xdg_surface.notify = server_new_xdg_surface; + wl_signal_add(&server.xdg_shell->events.new_surface, + &server.new_xdg_surface); + const char *socket = wl_display_add_socket_auto(server.wl_display); if (!socket) { wlr_backend_destroy(server.backend); diff --git a/meson.build b/meson.build @@ -34,6 +34,7 @@ wio_sources = files( 'main.c', 'input.c', 'output.c', + 'view.c', ) executable( diff --git a/output.c b/output.c @@ -2,10 +2,47 @@ #include <stdlib.h> #include <time.h> #include <wayland-server.h> +#include <wlr/types/wlr_matrix.h> #include <wlr/types/wlr_output.h> #include <wlr/render/wlr_renderer.h> #include "colors.h" #include "server.h" +#include "view.h" + +struct render_data { + struct wlr_output *output; + struct wlr_renderer *renderer; + struct wio_view *view; + struct timespec *when; +}; + +static void render_surface(struct wlr_surface *surface, + int sx, int sy, void *data) { + struct render_data *rdata = data; + struct wio_view *view = rdata->view; + struct wlr_output *output = rdata->output; + struct wlr_texture *texture = wlr_surface_get_texture(surface); + if (texture == NULL) { + return; + } + double ox = 0, oy = 0; + wlr_output_layout_output_coords( + view->server->output_layout, output, &ox, &oy); + ox += view->x + sx, oy += view->y + sy; + struct wlr_box box = { + .x = ox * output->scale, + .y = oy * output->scale, + .width = surface->current.width * output->scale, + .height = surface->current.height * output->scale, + }; + float matrix[9]; + enum wl_output_transform transform = + wlr_output_transform_invert(surface->current.transform); + wlr_matrix_project_box(matrix, &box, transform, 0, + output->transform_matrix); + wlr_render_texture_with_matrix(rdata->renderer, texture, matrix, 1); + wlr_surface_send_frame_done(surface, rdata->when); +} static void output_frame(struct wl_listener *listener, void *data) { struct wio_output *output = wl_container_of(listener, output, frame); @@ -23,7 +60,22 @@ static void output_frame(struct wl_listener *listener, void *data) { wlr_renderer_begin(renderer, width, height); wlr_renderer_clear(renderer, background); - // TODO: other stuff + + struct wio_view *view; + wl_list_for_each_reverse(view, &output->server->views, link) { + if (!view->xdg_surface->mapped) { + continue; + } + struct render_data rdata = { + .output = output->wlr_output, + .view = view, + .renderer = renderer, + .when = &now, + }; + wlr_xdg_surface_for_each_surface(view->xdg_surface, + render_surface, &rdata); + } + wlr_renderer_end(renderer); wlr_output_swap_buffers(output->wlr_output, NULL, NULL); } diff --git a/view.c b/view.c @@ -0,0 +1,29 @@ +#include <stdlib.h> +#include <wayland-server.h> +#include <wlr/types/wlr_xdg_shell.h> +#include "server.h" +#include "view.h" + +static void xdg_surface_destroy(struct wl_listener *listener, void *data) { + struct wio_view *view = wl_container_of(listener, view, destroy); + wl_list_remove(&view->link); + free(view); +} + +void server_new_xdg_surface(struct wl_listener *listener, void *data) { + struct wio_server *server = wl_container_of( + listener, server, new_xdg_surface); + struct wlr_xdg_surface *xdg_surface = data; + if (xdg_surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) { + return; + } + + struct wio_view *view = calloc(1, sizeof(struct wio_view)); + view->server = server; + view->xdg_surface = xdg_surface; + + view->destroy.notify = xdg_surface_destroy; + wl_signal_add(&xdg_surface->events.destroy, &view->destroy); + + wl_list_insert(&server->views, &view->link); +}