aboutsummaryrefslogtreecommitdiffstats
path: root/sway/desktop/output.c
diff options
context:
space:
mode:
authorLibravatar Tony Crisci <tony@dubstepdish.com>2018-01-14 10:35:56 -0500
committerLibravatar Tony Crisci <tony@dubstepdish.com>2018-01-14 10:35:56 -0500
commit4c8c9b29e43668e9076234a7e221b3746012669f (patch)
treec7d989991219f767636b9eefa987ca9c87d159c7 /sway/desktop/output.c
parentMerge pull request #1556 from martinetd/cleanup_logging (diff)
downloadsway-4c8c9b29e43668e9076234a7e221b3746012669f.tar.gz
sway-4c8c9b29e43668e9076234a7e221b3746012669f.tar.zst
sway-4c8c9b29e43668e9076234a7e221b3746012669f.zip
render xdg surface
Diffstat (limited to 'sway/desktop/output.c')
-rw-r--r--sway/desktop/output.c169
1 files changed, 112 insertions, 57 deletions
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index 2b428c30..1e9a823a 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -1,4 +1,5 @@
1#define _POSIX_C_SOURCE 200809L 1#define _POSIX_C_SOURCE 200809L
2#include <assert.h>
2#include <stdlib.h> 3#include <stdlib.h>
3#include <time.h> 4#include <time.h>
4#include <wayland-server.h> 5#include <wayland-server.h>
@@ -15,76 +16,131 @@
15#include "sway/input/input-manager.h" 16#include "sway/input/input-manager.h"
16#include "sway/input/seat.h" 17#include "sway/input/seat.h"
17 18
18static void output_frame_view(swayc_t *view, void *data) { 19/**
19 struct sway_output *output = data; 20 * Rotate a child's position relative to a parent. The parent size is (pw, ph),
20 struct wlr_output *wlr_output = output->wlr_output; 21 * the child position is (*sx, *sy) and its size is (sw, sh).
21 struct sway_view *sway_view = view->sway_view; 22 */
22 struct wlr_surface *surface = sway_view->surface; 23static void rotate_child_position(double *sx, double *sy, double sw, double sh,
24 double pw, double ph, float rotation) {
25 if (rotation != 0.0) {
26 // Coordinates relative to the center of the subsurface
27 double ox = *sx - pw/2 + sw/2,
28 oy = *sy - ph/2 + sh/2;
29 // Rotated coordinates
30 double rx = cos(-rotation)*ox - sin(-rotation)*oy,
31 ry = cos(-rotation)*oy + sin(-rotation)*ox;
32 *sx = rx + pw/2 - sw/2;
33 *sy = ry + ph/2 - sh/2;
34 }
35}
36
37static void render_surface(struct wlr_surface *surface,
38 struct wlr_output *wlr_output, struct timespec *when,
39 double lx, double ly, float rotation) {
23 if (!wlr_surface_has_buffer(surface)) { 40 if (!wlr_surface_has_buffer(surface)) {
24 return; 41 return;
25 } 42 }
26 // TODO 43 struct wlr_output_layout *layout = root_container.sway_root->output_layout;
27 // - Deal with wlr_output_layout 44 int width = surface->current->width;
28 int width = sway_view->surface->current->width; 45 int height = surface->current->height;
29 int height = sway_view->surface->current->height;
30 int render_width = width * wlr_output->scale; 46 int render_width = width * wlr_output->scale;
31 int render_height = height * wlr_output->scale; 47 int render_height = height * wlr_output->scale;
32 double ox = view->x, oy = view->y; 48 double ox = lx, oy = ly;
33 // TODO 49 wlr_output_layout_output_coords(layout, wlr_output, &ox, &oy);
34 //wlr_output_layout_output_coords(desktop->layout, wlr_output, &ox, &oy);
35 ox *= wlr_output->scale; 50 ox *= wlr_output->scale;
36 oy *= wlr_output->scale; 51 oy *= wlr_output->scale;
37 // TODO
38 //if (wlr_output_layout_intersects(desktop->layout, wlr_output,
39 // lx, ly, lx + render_width, ly + render_height)) {
40 // return;
41 //}
42
43 // if the shell specifies window geometry, make the top left corner of the
44 // window in the top left corner of the container to avoid arbitrarily
45 // sized gaps based on the attached buffer size
46 int window_offset_x = 0;
47 int window_offset_y = 0;
48
49 if (view->sway_view->type == SWAY_XDG_SHELL_V6_VIEW) {
50 window_offset_x = view->sway_view->wlr_xdg_surface_v6->geometry->x;
51 window_offset_y = view->sway_view->wlr_xdg_surface_v6->geometry->y;
52 }
53 52
54 // TODO 53 struct wlr_box render_box = {
55 double rotation = 0; 54 .x = lx, .y = ly,
56 float matrix[16]; 55 .width = render_width, .height = render_height,
56 };
57 if (wlr_output_layout_intersects(layout, wlr_output, &render_box)) {
58 float matrix[16];
57 59
58 float translate_origin[16]; 60 float translate_center[16];
59 wlr_matrix_translate(&translate_origin, 61 wlr_matrix_translate(&translate_center,
60 (int)ox + render_width / 2 - window_offset_x, 62 (int)ox + render_width / 2, (int)oy + render_height / 2, 0);
61 (int)oy + render_height / 2 - window_offset_y,
62 0);
63 63
64 float rotate[16]; 64 float rotate[16];
65 wlr_matrix_rotate(&rotate, rotation); 65 wlr_matrix_rotate(&rotate, rotation);
66 66
67 float translate_center[16]; 67 float translate_origin[16];
68 wlr_matrix_translate(&translate_center, 68 wlr_matrix_translate(&translate_origin, -render_width / 2,
69 -render_width / 2, 69 -render_height / 2, 0);
70 -render_height / 2, 0);
71 70
72 float scale[16]; 71 float scale[16];
73 wlr_matrix_scale(&scale, render_width, render_height, 1); 72 wlr_matrix_scale(&scale, render_width, render_height, 1);
74 73
75 float transform[16]; 74 float transform[16];
76 wlr_matrix_mul(&translate_origin, &rotate, &transform); 75 wlr_matrix_mul(&translate_center, &rotate, &transform);
77 wlr_matrix_mul(&transform, &translate_center, &transform); 76 wlr_matrix_mul(&transform, &translate_origin, &transform);
78 wlr_matrix_mul(&transform, &scale, &transform); 77 wlr_matrix_mul(&transform, &scale, &transform);
79 wlr_matrix_mul(&wlr_output->transform_matrix, &transform, &matrix);
80 78
81 wlr_render_with_matrix(output->server->renderer, surface->texture, &matrix); 79 if (surface->current->transform != WL_OUTPUT_TRANSFORM_NORMAL) {
80 float surface_translate_center[16];
81 wlr_matrix_translate(&surface_translate_center, 0.5, 0.5, 0);
82 82
83 // TODO: move into wlroots 83 float surface_transform[16];
84 struct timespec now; 84 wlr_matrix_transform(surface_transform,
85 clock_gettime(CLOCK_MONOTONIC, &now); 85 wlr_output_transform_invert(surface->current->transform));
86
87 float surface_translate_origin[16];
88 wlr_matrix_translate(&surface_translate_origin, -0.5, -0.5, 0);
89
90 wlr_matrix_mul(&transform, &surface_translate_center,
91 &transform);
92 wlr_matrix_mul(&transform, &surface_transform, &transform);
93 wlr_matrix_mul(&transform, &surface_translate_origin,
94 &transform);
95 }
96
97 wlr_matrix_mul(&wlr_output->transform_matrix, &transform, &matrix);
98
99 wlr_render_with_matrix(server.renderer, surface->texture,
100 &matrix);
101
102 wlr_surface_send_frame_done(surface, when);
103 }
86 104
87 wlr_surface_send_frame_done(surface, &now); 105 struct wlr_subsurface *subsurface;
106 wl_list_for_each(subsurface, &surface->subsurface_list, parent_link) {
107 struct wlr_surface_state *state = subsurface->surface->current;
108 double sx = state->subsurface_position.x;
109 double sy = state->subsurface_position.y;
110 double sw = state->buffer_width / state->scale;
111 double sh = state->buffer_height / state->scale;
112 rotate_child_position(&sx, &sy, sw, sh, width, height, rotation);
113
114 render_surface(subsurface->surface, wlr_output, when,
115 lx + sx,
116 ly + sy,
117 rotation);
118 }
119}
120
121static void output_frame_view(swayc_t *view, void *data) {
122 struct sway_output *output = data;
123 struct wlr_output *wlr_output = output->wlr_output;
124 struct sway_view *sway_view = view->sway_view;
125 struct wlr_surface *surface = sway_view->surface;
126
127 switch (sway_view->type) {
128 case SWAY_XDG_SHELL_V6_VIEW: {
129 int window_offset_x = view->sway_view->wlr_xdg_surface_v6->geometry->x;
130 int window_offset_y = view->sway_view->wlr_xdg_surface_v6->geometry->y;
131 render_surface(surface, wlr_output, &output->last_frame,
132 view->x - window_offset_x,
133 view->y - window_offset_y,
134 0);
135 break;
136 }
137 case SWAY_WL_SHELL_VIEW:
138 break;
139 case SWAY_XWAYLAND_VIEW:
140 break;
141 case SWAY_VIEW_TYPES:
142 break;
143 }
88} 144}
89 145
90static void output_frame_notify(struct wl_listener *listener, void *data) { 146static void output_frame_notify(struct wl_listener *listener, void *data) {
@@ -92,9 +148,6 @@ static void output_frame_notify(struct wl_listener *listener, void *data) {
92 struct wlr_output *wlr_output = data; 148 struct wlr_output *wlr_output = data;
93 struct sway_server *server = soutput->server; 149 struct sway_server *server = soutput->server;
94 150
95 struct timespec now;
96 clock_gettime(CLOCK_MONOTONIC, &now);
97
98 wlr_output_make_current(wlr_output); 151 wlr_output_make_current(wlr_output);
99 wlr_renderer_begin(server->renderer, wlr_output); 152 wlr_renderer_begin(server->renderer, wlr_output);
100 153
@@ -104,6 +157,8 @@ static void output_frame_notify(struct wl_listener *listener, void *data) {
104 wlr_renderer_end(server->renderer); 157 wlr_renderer_end(server->renderer);
105 wlr_output_swap_buffers(wlr_output); 158 wlr_output_swap_buffers(wlr_output);
106 159
160 struct timespec now;
161 clock_gettime(CLOCK_MONOTONIC, &now);
107 soutput->last_frame = now; 162 soutput->last_frame = now;
108} 163}
109 164