aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/wm/output.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cmd/wm/output.c')
-rw-r--r--sys/cmd/wm/output.c153
1 files changed, 108 insertions, 45 deletions
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);
}
-