From 88b8c199e3524b7c4e2667db3683c77d70f34a26 Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Wed, 29 Sep 2021 10:53:41 -0700 Subject: feat(wm): working prototype --- sys/cmd/wm/output.c | 153 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 108 insertions(+), 45 deletions(-) (limited to 'sys/cmd/wm/output.c') diff --git a/sys/cmd/wm/output.c b/sys/cmd/wm/output.c index 3283c41..46e702f 100644 --- a/sys/cmd/wm/output.c +++ b/sys/cmd/wm/output.c @@ -1,23 +1,23 @@ #include "wm.h" -typedef struct Payload Payload; struct Payload { - Client *client; - struct wlr_output *output; - struct wlr_renderer *renderer; - struct timespec *when; + Client *client; + struct wlr_output *output; + struct timespec *when; + int x, y; }; static void -draw(struct wlr_surface *surface, int sx, int sy, void *data) +render(struct wlr_surface *surface, int sx, int sy, void *data) { float matrix[9]; - double ox, oy; + double x, y; Client *client; - Payload *payload; + struct Payload *payload; + struct wlr_box box; struct wlr_output *output; struct wlr_texture *texture; @@ -31,70 +31,134 @@ draw(struct wlr_surface *surface, int sx, int sy, void *data) if(!texture) return; - ox = 0, oy = 0; - wlr_output_layout_output_coords(server.output.layout, output, &ox, &oy); - ox += client->x + sx, oy += client->y + sy; + x = 0, y = 0; + wlr_output_layout_output_coords(server.monitor.layout, output, &x, &y); - box = (struct wlr_box){ - .x = ox * output->scale, - .y = oy * output->scale, - .width = surface->current.width * output->scale, - .height = surface->current.height * output->scale, + box = (struct wlr_box) { + .x = x + payload->x + sx, + .y = y + payload->y + sy, + .width = surface->current.width, + .height = surface->current.height, }; + scale_box(&box, output->scale); transform = wlr_output_transform_invert(surface->current.transform); wlr_matrix_project_box(matrix, &box, transform, 0, output->transform_matrix); - wlr_render_texture_with_matrix(payload->renderer, texture, matrix, 1); + wlr_render_texture_with_matrix(server.renderer, texture, matrix, 1); wlr_surface_send_frame_done(surface, payload->when); + wlr_presentation_surface_sampled_on_output(server.present, surface, output); } static void -render(struct wl_listener *l, void *data) +render_clients(Monitor *monitor, struct timespec *now) { - int width, height; - struct timespec now; + double x, y; + int i, w, h, bw; + float *color; + Client *client; + struct wlr_output *output; + struct wlr_box *borders; + struct wlr_surface *surface; + + output = monitor->output; + wl_list_for_each_reverse(client, &server.clients, link) { + if(!client->ismapped) + continue; + + surface = client->xdg->surface; + + x = client->geo.x, y = client->geo.y; + wlr_output_layout_output_coords(server.monitor.layout, output, &x, &y); + + if((bw=client->border)) { + w = surface->current.width; + h = surface->current.height; + borders = (struct wlr_box[4]) { + {x, y, w+2*bw, bw}, /* top */ + {x, y+bw, bw, h}, /* left */ + {x+bw+w, y+bw, bw, h}, /* right */ + {x, y+bw+h, w+2*bw, bw}, /* bottom */ + }; + + color = (client == server.selected) ? cfg·focuscolor : cfg·bordercolor; + for(i=0; i<4; i++) { + scale_box(&borders[i], output->scale); + wlr_render_rect(server.renderer, &borders[i], color, output->transform_matrix); + } + } + + struct Payload payload = { + .output = output, + .client = client, + .when = now, + + .x = client->geo.x + client->border, + .y = client->geo.y + client->border, + }; + + wlr_xdg_surface_for_each_surface(client->xdg, render, &payload); + } +} + +static +void +render_monitor(struct wl_listener *l, void *data) +{ + int w, h; Monitor *monitor; - struct wlr_renderer *renderer; - float color[4] = {0.3, 0.3, 0.3, 1.0}; + struct timespec now; monitor = wl_container_of(l, monitor, event.render); - renderer = server.renderer; clock_gettime(CLOCK_MONOTONIC, &now); if(!wlr_output_attach_render(monitor->output, nil)) return; - wlr_output_effective_resolution(monitor->output, &width, &height); + wlr_output_effective_resolution(monitor->output, &w, &h); /* start of rendering kernel */ - wlr_renderer_begin(renderer, width, height); - wlr_renderer_clear(renderer, color); + wlr_renderer_begin(server.renderer, w, h); + wlr_renderer_clear(server.renderer, cfg·rootcolor); - wl_list_for_each_reverse(client, &server.clients, link) { - if(!client->mapped) - continue; - - Payload payload = { - .output = monitor->output, - .client = client, - .renderer = renderer, - .when = &now, - }; - - wlr_xdg_surface_for_each_surface(client->xdg, draw, &payload); - } + render_clients(monitor, &now); wlr_output_render_software_cursors(monitor->output, nil); - wlr_renderer_end(renderer); + wlr_renderer_end(server.renderer); wlr_output_commit(monitor->output); } +static +void +free_monitor(struct wl_listener *l, void *data) +{ + int len, i = 0; + struct wlr_output *output = data; + Monitor *monitor = output->data; + + wl_list_remove(&monitor->event.destroy.link); + wl_list_remove(&monitor->event.render.link); + wl_list_remove(&monitor->link); + + wlr_output_layout_remove(server.monitor.layout, monitor->output); + + len = wl_list_length(&server.monitor.list); + /* + do // don't switch to disabled mons + selmon = wl_container_of(mons.prev, selmon, link); + while (!selmon->wlr_output->enabled && i++ < nmons); + focusclient(focustop(selmon), 1); + + closemon(m); + free(monitor); + */ +} + void -make_output(struct wl_listener *l, void *data) +make_monitor(struct wl_listener *l, void *data) { struct wlr_output_mode *mode; struct Monitor *monitor; @@ -112,10 +176,9 @@ make_output(struct wl_listener *l, void *data) monitor = calloc(1, sizeof(*monitor)); monitor->output = output; - monitor->event.render.notify = render; + monitor->event.render.notify = render_monitor; wl_signal_add(&output->events.frame, &monitor->event.render); - wl_list_insert(&server.output.list, &monitor->link); + wl_list_insert(&server.monitor.list, &monitor->link); - wlr_output_layout_add_auto(server.output.layout, output); + wlr_output_layout_add_auto(server.monitor.layout, output); } - -- cgit v1.2.1