diff options
-rw-r--r-- | include/client.h | 3 | ||||
-rw-r--r-- | swaybg/main.c | 14 | ||||
-rw-r--r-- | wayland/client.c | 42 |
3 files changed, 50 insertions, 9 deletions
diff --git a/include/client.h b/include/client.h index ec3537ca..f10e6b1a 100644 --- a/include/client.h +++ b/include/client.h | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <wayland-client.h> | 4 | #include <wayland-client.h> |
5 | #include <cairo/cairo.h> | 5 | #include <cairo/cairo.h> |
6 | #include <pango/pangocairo.h> | 6 | #include <pango/pangocairo.h> |
7 | #include <stdbool.h> | ||
7 | #include "list.h" | 8 | #include "list.h" |
8 | 9 | ||
9 | struct output_state { | 10 | struct output_state { |
@@ -28,6 +29,8 @@ struct client_state { | |||
28 | struct buffer *buffer; | 29 | struct buffer *buffer; |
29 | struct wl_surface *surface; | 30 | struct wl_surface *surface; |
30 | struct wl_shell_surface *shell_surface; | 31 | struct wl_shell_surface *shell_surface; |
32 | struct wl_callback *frame_cb; | ||
33 | bool busy; | ||
31 | cairo_t *cairo; | 34 | cairo_t *cairo; |
32 | cairo_surface_t *cairo_surface; | 35 | cairo_surface_t *cairo_surface; |
33 | PangoContext *pango; | 36 | PangoContext *pango; |
diff --git a/swaybg/main.c b/swaybg/main.c index 1b4af550..5ceb94bc 100644 --- a/swaybg/main.c +++ b/swaybg/main.c | |||
@@ -15,12 +15,22 @@ int main(int argc, char **argv) { | |||
15 | init_log(L_INFO); | 15 | init_log(L_INFO); |
16 | state = client_setup(); | 16 | state = client_setup(); |
17 | 17 | ||
18 | uint8_t r = 0, g = 0, b = 0; | ||
19 | |||
20 | int rs; | ||
18 | do { | 21 | do { |
19 | if (!client_prerender(state)) continue; | 22 | if (!client_prerender(state)) continue; |
20 | cairo_set_source_rgb(state->cairo, 255, 0, 0); | 23 | cairo_set_source_rgb(state->cairo, r, g, b); |
21 | cairo_rectangle(state->cairo, 0, 0, 100, 100); | 24 | cairo_rectangle(state->cairo, 0, 0, 100, 100); |
22 | cairo_fill(state->cairo); | 25 | cairo_fill(state->cairo); |
23 | } while (client_render(state)); | 26 | |
27 | rs = client_render(state); | ||
28 | |||
29 | if (rs == 1) { | ||
30 | sway_log(L_INFO, "rendering %d %d %d", r, g, b); | ||
31 | r++; g++; b++; | ||
32 | } | ||
33 | } while (rs); | ||
24 | 34 | ||
25 | client_teardown(state); | 35 | client_teardown(state); |
26 | return 0; | 36 | return 0; |
diff --git a/wayland/client.c b/wayland/client.c index c62f92bd..b5e5b51a 100644 --- a/wayland/client.c +++ b/wayland/client.c | |||
@@ -103,6 +103,16 @@ static int create_pool_file(size_t size) { | |||
103 | return fd; | 103 | return fd; |
104 | } | 104 | } |
105 | 105 | ||
106 | static void buffer_release(void *data, struct wl_buffer *buffer) { | ||
107 | struct client_state *state = data; | ||
108 | state->busy = false; | ||
109 | sway_log(L_INFO, "buffer release"); | ||
110 | } | ||
111 | |||
112 | static const struct wl_buffer_listener buffer_listener = { | ||
113 | .release = buffer_release | ||
114 | }; | ||
115 | |||
106 | struct buffer *create_buffer(struct client_state *state, | 116 | struct buffer *create_buffer(struct client_state *state, |
107 | int32_t width, int32_t height, uint32_t format) { | 117 | int32_t width, int32_t height, uint32_t format) { |
108 | 118 | ||
@@ -120,10 +130,23 @@ struct buffer *create_buffer(struct client_state *state, | |||
120 | state->cairo = cairo_create(state->cairo_surface); | 130 | state->cairo = cairo_create(state->cairo_surface); |
121 | state->pango = pango_cairo_create_context(state->cairo); | 131 | state->pango = pango_cairo_create_context(state->cairo); |
122 | 132 | ||
133 | wl_buffer_add_listener(buf->buffer, &buffer_listener, state); | ||
134 | |||
123 | sway_log(L_INFO, "%p %p", buf->pool, buf->buffer); | 135 | sway_log(L_INFO, "%p %p", buf->pool, buf->buffer); |
124 | return buf; | 136 | return buf; |
125 | } | 137 | } |
126 | 138 | ||
139 | static void frame_callback(void *data, struct wl_callback *callback, uint32_t time) { | ||
140 | sway_log(L_INFO, "frame callback"); | ||
141 | struct client_state *state = data; | ||
142 | wl_callback_destroy(callback); | ||
143 | state->frame_cb = NULL; | ||
144 | } | ||
145 | |||
146 | static const struct wl_callback_listener listener = { | ||
147 | frame_callback | ||
148 | }; | ||
149 | |||
127 | struct client_state *client_setup(void) { | 150 | struct client_state *client_setup(void) { |
128 | struct client_state *state = malloc(sizeof(struct client_state)); | 151 | struct client_state *state = malloc(sizeof(struct client_state)); |
129 | memset(state, 0, sizeof(struct client_state)); | 152 | memset(state, 0, sizeof(struct client_state)); |
@@ -138,8 +161,8 @@ struct client_state *client_setup(void) { | |||
138 | 161 | ||
139 | struct wl_registry *registry = wl_display_get_registry(state->display); | 162 | struct wl_registry *registry = wl_display_get_registry(state->display); |
140 | wl_registry_add_listener(registry, ®istry_listener, state); | 163 | wl_registry_add_listener(registry, ®istry_listener, state); |
141 | wl_display_roundtrip(state->display); // globals | 164 | wl_display_dispatch(state->display); |
142 | wl_display_roundtrip(state->display); // listeners | 165 | wl_display_roundtrip(state->display); |
143 | wl_registry_destroy(registry); | 166 | wl_registry_destroy(registry); |
144 | 167 | ||
145 | state->buffer = create_buffer(state, 100, 100, WL_SHM_FORMAT_ARGB8888); | 168 | state->buffer = create_buffer(state, 100, 100, WL_SHM_FORMAT_ARGB8888); |
@@ -148,21 +171,26 @@ struct client_state *client_setup(void) { | |||
148 | wl_shell_surface_set_toplevel(state->shell_surface); | 171 | wl_shell_surface_set_toplevel(state->shell_surface); |
149 | 172 | ||
150 | wl_surface_damage(state->surface, 0, 0, 100, 100); | 173 | wl_surface_damage(state->surface, 0, 0, 100, 100); |
151 | wl_surface_attach(state->surface, state->buffer->buffer, 0, 0); | ||
152 | wl_surface_commit(state->surface); | ||
153 | 174 | ||
154 | return state; | 175 | return state; |
155 | } | 176 | } |
156 | 177 | ||
157 | int client_prerender(struct client_state *state) { | 178 | int client_prerender(struct client_state *state) { |
158 | wl_display_dispatch_pending(state->display); | 179 | wl_display_dispatch_pending(state->display); |
159 | if (wl_display_flush(state->display) < 0 && errno != EAGAIN) { | 180 | wl_display_flush(state->display); |
160 | return 0; | ||
161 | } | ||
162 | return 1; | 181 | return 1; |
163 | } | 182 | } |
164 | 183 | ||
165 | int client_render(struct client_state *state) { | 184 | int client_render(struct client_state *state) { |
185 | if (state->frame_cb) { | ||
186 | return 2; | ||
187 | } | ||
188 | state->frame_cb = wl_surface_frame(state->surface); | ||
189 | wl_callback_add_listener(state->frame_cb, &listener, state); | ||
190 | wl_surface_damage(state->surface, 0, 0, 100, 100); | ||
191 | wl_surface_attach(state->surface, state->buffer->buffer, 0, 0); | ||
192 | wl_surface_commit(state->surface); | ||
193 | state->busy = true; | ||
166 | return wl_display_dispatch(state->display) != -1; | 194 | return wl_display_dispatch(state->display) != -1; |
167 | } | 195 | } |
168 | 196 | ||