diff options
author | Tony Crisci <tony@dubstepdish.com> | 2018-01-14 10:35:56 -0500 |
---|---|---|
committer | Tony Crisci <tony@dubstepdish.com> | 2018-01-14 10:35:56 -0500 |
commit | 4c8c9b29e43668e9076234a7e221b3746012669f (patch) | |
tree | c7d989991219f767636b9eefa987ca9c87d159c7 | |
parent | Merge pull request #1556 from martinetd/cleanup_logging (diff) | |
download | sway-4c8c9b29e43668e9076234a7e221b3746012669f.tar.gz sway-4c8c9b29e43668e9076234a7e221b3746012669f.tar.zst sway-4c8c9b29e43668e9076234a7e221b3746012669f.zip |
render xdg surface
-rw-r--r-- | sway/desktop/output.c | 169 |
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 | ||
18 | static 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; | 23 | static 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 | |||
37 | static 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 | |||
121 | static 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 | ||
90 | static void output_frame_notify(struct wl_listener *listener, void *data) { | 146 | static 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 | ||