1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
|
#define _POSIX_C_SOURCE 200809L
#include <stdlib.h>
#include <time.h>
#include <wayland-server.h>
#include <wlr/types/wlr_output.h>
#include <wlr/types/wlr_surface.h>
#include <wlr/render.h>
#include <wlr/render/matrix.h>
#include "log.h"
#include "sway/container.h"
#include "sway/layout.h"
#include "sway/output.h"
#include "sway/server.h"
#include "sway/view.h"
static void output_frame_view(swayc_t *view, void *data) {
struct sway_output *output = data;
struct wlr_output *wlr_output = output->wlr_output;
struct sway_view *sway_view = view->sway_view;
struct wlr_surface *surface = sway_view->surface;
if (!wlr_surface_has_buffer(surface)) {
return;
}
// TODO
// - Deal with wlr_output_layout
int width = sway_view->width;
int height = sway_view->height;
int render_width = width * wlr_output->scale;
int render_height = height * wlr_output->scale;
double ox = view->x, oy = view->y;
// TODO
//wlr_output_layout_output_coords(desktop->layout, wlr_output, &ox, &oy);
ox *= wlr_output->scale;
oy *= wlr_output->scale;
// TODO
//if (wlr_output_layout_intersects(desktop->layout, wlr_output,
// lx, ly, lx + render_width, ly + render_height)) {
// return;
//}
// TODO
double rotation = 0;
float matrix[16];
float translate_origin[16];
wlr_matrix_translate(&translate_origin,
(int)ox + render_width / 2, (int)oy + render_height / 2, 0);
float rotate[16];
wlr_matrix_rotate(&rotate, rotation);
float translate_center[16];
wlr_matrix_translate(&translate_center, -render_width / 2,
-render_height / 2, 0);
float scale[16];
wlr_matrix_scale(&scale, render_width, render_height, 1);
float transform[16];
wlr_matrix_mul(&translate_origin, &rotate, &transform);
wlr_matrix_mul(&transform, &translate_center, &transform);
wlr_matrix_mul(&transform, &scale, &transform);
wlr_matrix_mul(&wlr_output->transform_matrix, &transform, &matrix);
wlr_render_with_matrix(output->server->renderer, surface->texture, &matrix);
// TODO: move into wlroots
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
wlr_surface_send_frame_done(surface, &now);
}
static void output_frame_notify(struct wl_listener *listener, void *data) {
struct sway_output *soutput = wl_container_of(listener, soutput, frame);
struct wlr_output *wlr_output = data;
struct sway_server *server = soutput->server;
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
wlr_output_make_current(wlr_output);
wlr_renderer_begin(server->renderer, wlr_output);
swayc_descendants_of_type(
&root_container, C_VIEW, output_frame_view, soutput);
wlr_renderer_end(server->renderer);
wlr_output_swap_buffers(wlr_output);
soutput->last_frame = now;
}
static void output_update_size(struct sway_output *output) {
struct wlr_box *output_layout_box = wlr_output_layout_get_box(
root_container.sway_root->output_layout, output->wlr_output);
output->swayc->x = output_layout_box->x;
output->swayc->y = output_layout_box->y;
output->swayc->width = output_layout_box->width;
output->swayc->height = output_layout_box->height;
arrange_windows(output->swayc, -1, -1);
}
static void output_resolution_notify(struct wl_listener *listener, void *data) {
struct sway_output *output = wl_container_of(listener, output, resolution);
output_update_size(output);
}
static void output_scale_notify(struct wl_listener *listener, void *data) {
struct sway_output *output = wl_container_of(listener, output, scale);
output_update_size(output);
}
static void output_transform_notify(struct wl_listener *listener, void *data) {
struct sway_output *output = wl_container_of(listener, output, transform);
output_update_size(output);
}
void output_add_notify(struct wl_listener *listener, void *data) {
struct sway_server *server = wl_container_of(listener, server, output_add);
struct wlr_output *wlr_output = data;
sway_log(L_DEBUG, "New output %p: %s", wlr_output, wlr_output->name);
struct sway_output *output = calloc(1, sizeof(struct sway_output));
if (!output) {
return;
}
output->wlr_output = wlr_output;
output->server = server;
wl_signal_init(&output->events.scale);
wl_signal_init(&output->events.transform);
output->swayc = new_output(output);
if (!output->swayc) {
free(output);
return;
}
if (!wl_list_empty(&wlr_output->modes)) {
struct wlr_output_mode *mode = NULL;
mode = wl_container_of((&wlr_output->modes)->prev, mode, link);
wlr_output_set_mode(wlr_output, mode);
}
output->frame.notify = output_frame_notify;
wl_signal_add(&wlr_output->events.frame, &output->frame);
output->resolution.notify = output_resolution_notify;
wl_signal_add(&wlr_output->events.resolution, &output->resolution);
output->scale.notify = output_scale_notify;
wl_signal_add(&output->events.scale, &output->scale);
output->transform.notify = output_transform_notify;
wl_signal_add(&output->events.transform, &output->transform);
arrange_windows(output->swayc, -1, -1);
}
void output_remove_notify(struct wl_listener *listener, void *data) {
struct sway_server *server = wl_container_of(listener, server, output_remove);
struct wlr_output *wlr_output = data;
sway_log(L_DEBUG, "Output %p %s removed", wlr_output, wlr_output->name);
// TODO
}
|