diff options
author | Drew DeVault <ddevault@linode.com> | 2016-09-05 11:36:48 -0400 |
---|---|---|
committer | Drew DeVault <ddevault@linode.com> | 2016-09-05 11:36:48 -0400 |
commit | b2226ac6551f18275fadbcb3bc16a06d2a3dd97f (patch) | |
tree | 65628cb83abaa546c5f0e2cd8949c55aacb40360 | |
parent | Initial testing on hidpi clients (diff) | |
download | sway-b2226ac6551f18275fadbcb3bc16a06d2a3dd97f.tar.gz sway-b2226ac6551f18275fadbcb3bc16a06d2a3dd97f.tar.zst sway-b2226ac6551f18275fadbcb3bc16a06d2a3dd97f.zip |
Add client support for HiDPI
This adds HiDPI support to swaybar, swaybg, and swaylock.
-rw-r--r-- | include/client/window.h | 4 | ||||
-rw-r--r-- | swaybar/bar.c | 9 | ||||
-rw-r--r-- | swaybar/render.c | 21 | ||||
-rw-r--r-- | swaybg/main.c | 34 | ||||
-rw-r--r-- | swaylock/main.c | 53 | ||||
-rw-r--r-- | wayland/buffers.c | 15 | ||||
-rw-r--r-- | wayland/pango.c | 4 | ||||
-rw-r--r-- | wayland/registry.c | 3 | ||||
-rw-r--r-- | wayland/window.c | 14 |
9 files changed, 96 insertions, 61 deletions
diff --git a/include/client/window.h b/include/client/window.h index 296dd9ed..fbfbbc5f 100644 --- a/include/client/window.h +++ b/include/client/window.h | |||
@@ -51,12 +51,14 @@ struct window { | |||
51 | struct wl_callback *frame_cb; | 51 | struct wl_callback *frame_cb; |
52 | struct cursor cursor; | 52 | struct cursor cursor; |
53 | uint32_t width, height; | 53 | uint32_t width, height; |
54 | int32_t scale; | ||
54 | char *font; | 55 | char *font; |
55 | cairo_t *cairo; | 56 | cairo_t *cairo; |
56 | struct pointer_input pointer_input; | 57 | struct pointer_input pointer_input; |
57 | }; | 58 | }; |
58 | 59 | ||
59 | struct window *window_setup(struct registry *registry, uint32_t width, uint32_t height, bool shell_surface); | 60 | struct window *window_setup(struct registry *registry, uint32_t width, uint32_t height, |
61 | int32_t scale, bool shell_surface); | ||
60 | void window_teardown(struct window *state); | 62 | void window_teardown(struct window *state); |
61 | int window_prerender(struct window *state); | 63 | int window_prerender(struct window *state); |
62 | int window_render(struct window *state); | 64 | int window_render(struct window *state); |
diff --git a/swaybar/bar.c b/swaybar/bar.c index f3767409..7ec3e0ea 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c | |||
@@ -152,12 +152,15 @@ void bar_setup(struct bar *bar, const char *socket_path, const char *bar_id) { | |||
152 | 152 | ||
153 | struct output_state *output = bar_output->registry->outputs->items[bar_output->idx]; | 153 | struct output_state *output = bar_output->registry->outputs->items[bar_output->idx]; |
154 | 154 | ||
155 | bar_output->window = window_setup(bar_output->registry, output->width * output->scale, 30 * output->scale, false); | 155 | bar_output->window = window_setup(bar_output->registry, |
156 | output->width / output->scale, 30, output->scale, false); | ||
156 | if (!bar_output->window) { | 157 | if (!bar_output->window) { |
157 | sway_abort("Failed to create window."); | 158 | sway_abort("Failed to create window."); |
158 | } | 159 | } |
159 | desktop_shell_set_panel(bar_output->registry->desktop_shell, output->output, bar_output->window->surface); | 160 | desktop_shell_set_panel(bar_output->registry->desktop_shell, |
160 | desktop_shell_set_panel_position(bar_output->registry->desktop_shell, bar->config->position); | 161 | output->output, bar_output->window->surface); |
162 | desktop_shell_set_panel_position(bar_output->registry->desktop_shell, | ||
163 | bar->config->position); | ||
161 | 164 | ||
162 | window_make_shell(bar_output->window); | 165 | window_make_shell(bar_output->window); |
163 | 166 | ||
diff --git a/swaybar/render.c b/swaybar/render.c index 83b4cec7..58325050 100644 --- a/swaybar/render.c +++ b/swaybar/render.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include "swaybar/config.h" | 8 | #include "swaybar/config.h" |
9 | #include "swaybar/status_line.h" | 9 | #include "swaybar/status_line.h" |
10 | #include "swaybar/render.h" | 10 | #include "swaybar/render.h" |
11 | #include "log.h" | ||
11 | 12 | ||
12 | 13 | ||
13 | /* internal spacing */ | 14 | /* internal spacing */ |
@@ -283,7 +284,8 @@ void render(struct output *output, struct config *config, struct status_line *li | |||
283 | 284 | ||
284 | if (line->protocol == TEXT) { | 285 | if (line->protocol == TEXT) { |
285 | get_text_size(window->cairo, window->font, &width, &height, config->pango_markup, "%s", line->text_line); | 286 | get_text_size(window->cairo, window->font, &width, &height, config->pango_markup, "%s", line->text_line); |
286 | cairo_move_to(cairo, window->width - margin - width, margin); | 287 | cairo_move_to(cairo, (window->width * window->scale) |
288 | - margin - width, margin); | ||
287 | pango_printf(window->cairo, window->font, config->pango_markup, "%s", line->text_line); | 289 | pango_printf(window->cairo, window->font, config->pango_markup, "%s", line->text_line); |
288 | } else if (line->protocol == I3BAR && line->block_line) { | 290 | } else if (line->protocol == I3BAR && line->block_line) { |
289 | double pos = window->width - 0.5; | 291 | double pos = window->width - 0.5; |
@@ -315,12 +317,13 @@ void render(struct output *output, struct config *config, struct status_line *li | |||
315 | } | 317 | } |
316 | 318 | ||
317 | void set_window_height(struct window *window, int height) { | 319 | void set_window_height(struct window *window, int height) { |
318 | int text_width, text_height; | 320 | int text_width, text_height; |
319 | get_text_size(window->cairo, window->font, &text_width, &text_height, false, | 321 | get_text_size(window->cairo, window->font, |
320 | "Test string for measuring purposes"); | 322 | &text_width, &text_height, false, |
321 | if (height > 0) { | 323 | "Test string for measuring purposes"); |
322 | margin = (height - text_height) / 2; | 324 | if (height > 0) { |
323 | ws_vertical_padding = margin - 1.5; | 325 | margin = (height - text_height) / 2; |
324 | } | 326 | ws_vertical_padding = margin - 1.5; |
325 | window->height = text_height + margin * 2; | 327 | } |
328 | window->height = (text_height + margin * 2) / window->scale; | ||
326 | } | 329 | } |
diff --git a/swaybg/main.c b/swaybg/main.c index b23b8027..9dba0c8f 100644 --- a/swaybg/main.c +++ b/swaybg/main.c | |||
@@ -69,7 +69,8 @@ int main(int argc, const char **argv) { | |||
69 | sway_log(L_INFO, "Using output %d of %d", desired_output, registry->outputs->length); | 69 | sway_log(L_INFO, "Using output %d of %d", desired_output, registry->outputs->length); |
70 | int i; | 70 | int i; |
71 | struct output_state *output = registry->outputs->items[desired_output]; | 71 | struct output_state *output = registry->outputs->items[desired_output]; |
72 | struct window *window = window_setup(registry, output->width, output->height, false); | 72 | struct window *window = window_setup(registry, |
73 | output->width, output->height, output->scale, false); | ||
73 | if (!window) { | 74 | if (!window) { |
74 | sway_abort("Failed to create surfaces."); | 75 | sway_abort("Failed to create surfaces."); |
75 | } | 76 | } |
@@ -115,60 +116,63 @@ int main(int argc, const char **argv) { | |||
115 | sway_abort("Unsupported scaling mode: %s", scaling_mode_str); | 116 | sway_abort("Unsupported scaling mode: %s", scaling_mode_str); |
116 | } | 117 | } |
117 | 118 | ||
119 | int wwidth = window->width * window->scale; | ||
120 | int wheight = window->height * window->scale; | ||
121 | |||
118 | for (i = 0; i < surfaces->length; ++i) { | 122 | for (i = 0; i < surfaces->length; ++i) { |
119 | struct window *window = surfaces->items[i]; | 123 | struct window *window = surfaces->items[i]; |
120 | if (window_prerender(window) && window->cairo) { | 124 | if (window_prerender(window) && window->cairo) { |
121 | switch (scaling_mode) { | 125 | switch (scaling_mode) { |
122 | case SCALING_MODE_STRETCH: | 126 | case SCALING_MODE_STRETCH: |
123 | cairo_scale(window->cairo, | 127 | cairo_scale(window->cairo, |
124 | (double) window->width / width, | 128 | (double) wwidth / width, |
125 | (double) window->height / height); | 129 | (double) wheight / height); |
126 | cairo_set_source_surface(window->cairo, image, 0, 0); | 130 | cairo_set_source_surface(window->cairo, image, 0, 0); |
127 | break; | 131 | break; |
128 | case SCALING_MODE_FILL: | 132 | case SCALING_MODE_FILL: |
129 | { | 133 | { |
130 | double window_ratio = (double) window->width / window->height; | 134 | double window_ratio = (double) wwidth / wheight; |
131 | double bg_ratio = width / height; | 135 | double bg_ratio = width / height; |
132 | 136 | ||
133 | if (window_ratio > bg_ratio) { | 137 | if (window_ratio > bg_ratio) { |
134 | double scale = (double) window->width / width; | 138 | double scale = (double) wwidth / width; |
135 | cairo_scale(window->cairo, scale, scale); | 139 | cairo_scale(window->cairo, scale, scale); |
136 | cairo_set_source_surface(window->cairo, image, | 140 | cairo_set_source_surface(window->cairo, image, |
137 | 0, | 141 | 0, |
138 | (double) window->height/2 / scale - height/2); | 142 | (double) wheight/2 / scale - height/2); |
139 | } else { | 143 | } else { |
140 | double scale = (double) window->height / height; | 144 | double scale = (double) wheight / height; |
141 | cairo_scale(window->cairo, scale, scale); | 145 | cairo_scale(window->cairo, scale, scale); |
142 | cairo_set_source_surface(window->cairo, image, | 146 | cairo_set_source_surface(window->cairo, image, |
143 | (double) window->width/2 / scale - width/2, | 147 | (double) wwidth/2 / scale - width/2, |
144 | 0); | 148 | 0); |
145 | } | 149 | } |
146 | break; | 150 | break; |
147 | } | 151 | } |
148 | case SCALING_MODE_FIT: | 152 | case SCALING_MODE_FIT: |
149 | { | 153 | { |
150 | double window_ratio = (double) window->width / window->height; | 154 | double window_ratio = (double) wwidth / wheight; |
151 | double bg_ratio = width / height; | 155 | double bg_ratio = width / height; |
152 | 156 | ||
153 | if (window_ratio > bg_ratio) { | 157 | if (window_ratio > bg_ratio) { |
154 | double scale = (double) window->height / height; | 158 | double scale = (double) wheight / height; |
155 | cairo_scale(window->cairo, scale, scale); | 159 | cairo_scale(window->cairo, scale, scale); |
156 | cairo_set_source_surface(window->cairo, image, | 160 | cairo_set_source_surface(window->cairo, image, |
157 | (double) window->width/2 / scale - width/2, | 161 | (double) wwidth/2 / scale - width/2, |
158 | 0); | 162 | 0); |
159 | } else { | 163 | } else { |
160 | double scale = (double) window->width / width; | 164 | double scale = (double) wwidth / width; |
161 | cairo_scale(window->cairo, scale, scale); | 165 | cairo_scale(window->cairo, scale, scale); |
162 | cairo_set_source_surface(window->cairo, image, | 166 | cairo_set_source_surface(window->cairo, image, |
163 | 0, | 167 | 0, |
164 | (double) window->height/2 / scale - height/2); | 168 | (double) wheight/2 / scale - height/2); |
165 | } | 169 | } |
166 | break; | 170 | break; |
167 | } | 171 | } |
168 | case SCALING_MODE_CENTER: | 172 | case SCALING_MODE_CENTER: |
169 | cairo_set_source_surface(window->cairo, image, | 173 | cairo_set_source_surface(window->cairo, image, |
170 | (double) window->width/2 - width/2, | 174 | (double) wwidth/2 - width/2, |
171 | (double) window->height/2 - height/2); | 175 | (double) wheight/2 - height/2); |
172 | break; | 176 | break; |
173 | case SCALING_MODE_TILE: | 177 | case SCALING_MODE_TILE: |
174 | { | 178 | { |
diff --git a/swaylock/main.c b/swaylock/main.c index 0637453c..075e44e7 100644 --- a/swaylock/main.c +++ b/swaylock/main.c | |||
@@ -223,58 +223,60 @@ void render_color(struct window *window, uint32_t color) { | |||
223 | void render_image(struct window *window, cairo_surface_t *image, enum scaling_mode scaling_mode) { | 223 | void render_image(struct window *window, cairo_surface_t *image, enum scaling_mode scaling_mode) { |
224 | double width = cairo_image_surface_get_width(image); | 224 | double width = cairo_image_surface_get_width(image); |
225 | double height = cairo_image_surface_get_height(image); | 225 | double height = cairo_image_surface_get_height(image); |
226 | int wwidth = window->width * window->scale; | ||
227 | int wheight = window->height * window->scale; | ||
226 | 228 | ||
227 | switch (scaling_mode) { | 229 | switch (scaling_mode) { |
228 | case SCALING_MODE_STRETCH: | 230 | case SCALING_MODE_STRETCH: |
229 | cairo_scale(window->cairo, | 231 | cairo_scale(window->cairo, |
230 | (double) window->width / width, | 232 | (double) wwidth / width, |
231 | (double) window->height / height); | 233 | (double) wheight / height); |
232 | cairo_set_source_surface(window->cairo, image, 0, 0); | 234 | cairo_set_source_surface(window->cairo, image, 0, 0); |
233 | break; | 235 | break; |
234 | case SCALING_MODE_FILL: | 236 | case SCALING_MODE_FILL: |
235 | { | 237 | { |
236 | double window_ratio = (double) window->width / window->height; | 238 | double window_ratio = (double) wwidth / wheight; |
237 | double bg_ratio = width / height; | 239 | double bg_ratio = wheight; |
238 | 240 | ||
239 | if (window_ratio > bg_ratio) { | 241 | if (window_ratio > bg_ratio) { |
240 | double scale = (double) window->width / width; | 242 | double scale = (double) wwidth / width; |
241 | cairo_scale(window->cairo, scale, scale); | 243 | cairo_scale(window->cairo, scale, scale); |
242 | cairo_set_source_surface(window->cairo, image, | 244 | cairo_set_source_surface(window->cairo, image, |
243 | 0, | 245 | 0, |
244 | (double) window->height/2 / scale - height/2); | 246 | (double) wheight/2 / scale - height/2); |
245 | } else { | 247 | } else { |
246 | double scale = (double) window->height / height; | 248 | double scale = (double) wheight / height; |
247 | cairo_scale(window->cairo, scale, scale); | 249 | cairo_scale(window->cairo, scale, scale); |
248 | cairo_set_source_surface(window->cairo, image, | 250 | cairo_set_source_surface(window->cairo, image, |
249 | (double) window->width/2 / scale - width/2, | 251 | (double) wwidth/2 / scale - width/2, |
250 | 0); | 252 | 0); |
251 | } | 253 | } |
252 | break; | 254 | break; |
253 | } | 255 | } |
254 | case SCALING_MODE_FIT: | 256 | case SCALING_MODE_FIT: |
255 | { | 257 | { |
256 | double window_ratio = (double) window->width / window->height; | 258 | double window_ratio = (double) wwidth / wheight; |
257 | double bg_ratio = width / height; | 259 | double bg_ratio = width / height; |
258 | 260 | ||
259 | if (window_ratio > bg_ratio) { | 261 | if (window_ratio > bg_ratio) { |
260 | double scale = (double) window->height / height; | 262 | double scale = (double) wheight / height; |
261 | cairo_scale(window->cairo, scale, scale); | 263 | cairo_scale(window->cairo, scale, scale); |
262 | cairo_set_source_surface(window->cairo, image, | 264 | cairo_set_source_surface(window->cairo, image, |
263 | (double) window->width/2 / scale - width/2, | 265 | (double) wwidth/2 / scale - width/2, |
264 | 0); | 266 | 0); |
265 | } else { | 267 | } else { |
266 | double scale = (double) window->width / width; | 268 | double scale = (double) wwidth / width; |
267 | cairo_scale(window->cairo, scale, scale); | 269 | cairo_scale(window->cairo, scale, scale); |
268 | cairo_set_source_surface(window->cairo, image, | 270 | cairo_set_source_surface(window->cairo, image, |
269 | 0, | 271 | 0, |
270 | (double) window->height/2 / scale - height/2); | 272 | (double) wheight/2 / scale - height/2); |
271 | } | 273 | } |
272 | break; | 274 | break; |
273 | } | 275 | } |
274 | case SCALING_MODE_CENTER: | 276 | case SCALING_MODE_CENTER: |
275 | cairo_set_source_surface(window->cairo, image, | 277 | cairo_set_source_surface(window->cairo, image, |
276 | (double) window->width/2 - width/2, | 278 | (double) wwidth/2 - width/2, |
277 | (double) window->height/2 - height/2); | 279 | (double) wheight/2 - height/2); |
278 | break; | 280 | break; |
279 | case SCALING_MODE_TILE: | 281 | case SCALING_MODE_TILE: |
280 | { | 282 | { |
@@ -477,7 +479,8 @@ int main(int argc, char **argv) { | |||
477 | 479 | ||
478 | for (i = 0; i < registry->outputs->length; ++i) { | 480 | for (i = 0; i < registry->outputs->length; ++i) { |
479 | struct output_state *output = registry->outputs->items[i]; | 481 | struct output_state *output = registry->outputs->items[i]; |
480 | struct window *window = window_setup(registry, output->width, output->height, true); | 482 | struct window *window = window_setup(registry, |
483 | output->width, output->height, output->scale, true); | ||
481 | if (!window) { | 484 | if (!window) { |
482 | sway_abort("Failed to create surfaces."); | 485 | sway_abort("Failed to create surfaces."); |
483 | } | 486 | } |
@@ -564,6 +567,8 @@ void render(struct render_data *render_data) { | |||
564 | if (!window_prerender(window) || !window->cairo) { | 567 | if (!window_prerender(window) || !window->cairo) { |
565 | continue; | 568 | continue; |
566 | } | 569 | } |
570 | int wwidth = window->width * window->scale; | ||
571 | int wheight = window->height * window->scale; | ||
567 | 572 | ||
568 | // Reset the transformation matrix | 573 | // Reset the transformation matrix |
569 | cairo_identity_matrix(window->cairo); | 574 | cairo_identity_matrix(window->cairo); |
@@ -595,7 +600,7 @@ void render(struct render_data *render_data) { | |||
595 | if (show_indicator && render_data->auth_state != AUTH_STATE_IDLE) { | 600 | if (show_indicator && render_data->auth_state != AUTH_STATE_IDLE) { |
596 | // Draw circle | 601 | // Draw circle |
597 | cairo_set_line_width(window->cairo, ARC_THICKNESS); | 602 | cairo_set_line_width(window->cairo, ARC_THICKNESS); |
598 | cairo_arc(window->cairo, window->width/2, window->height/2, ARC_RADIUS, 0, 2 * M_PI); | 603 | cairo_arc(window->cairo, wwidth/2, wheight/2, ARC_RADIUS, 0, 2 * M_PI); |
599 | switch (render_data->auth_state) { | 604 | switch (render_data->auth_state) { |
600 | case AUTH_STATE_INPUT: | 605 | case AUTH_STATE_INPUT: |
601 | case AUTH_STATE_BACKSPACE: { | 606 | case AUTH_STATE_BACKSPACE: { |
@@ -638,8 +643,8 @@ void render(struct render_data *render_data) { | |||
638 | double x, y; | 643 | double x, y; |
639 | 644 | ||
640 | cairo_text_extents(window->cairo, text, &extents); | 645 | cairo_text_extents(window->cairo, text, &extents); |
641 | x = window->width/2 - ((extents.width/2) + extents.x_bearing); | 646 | x = wwidth/2 - ((extents.width/2) + extents.x_bearing); |
642 | y = window->height/2 - ((extents.height/2) + extents.y_bearing); | 647 | y = wheight/2 - ((extents.height/2) + extents.y_bearing); |
643 | 648 | ||
644 | cairo_move_to(window->cairo, x, y); | 649 | cairo_move_to(window->cairo, x, y); |
645 | cairo_show_text(window->cairo, text); | 650 | cairo_show_text(window->cairo, text); |
@@ -651,7 +656,7 @@ void render(struct render_data *render_data) { | |||
651 | if (render_data->auth_state == AUTH_STATE_INPUT || render_data->auth_state == AUTH_STATE_BACKSPACE) { | 656 | if (render_data->auth_state == AUTH_STATE_INPUT || render_data->auth_state == AUTH_STATE_BACKSPACE) { |
652 | static double highlight_start = 0; | 657 | static double highlight_start = 0; |
653 | highlight_start += (rand() % (int)(M_PI * 100)) / 100.0 + M_PI * 0.5; | 658 | highlight_start += (rand() % (int)(M_PI * 100)) / 100.0 + M_PI * 0.5; |
654 | cairo_arc(window->cairo, window->width/2, window->height/2, ARC_RADIUS, highlight_start, highlight_start + TYPE_INDICATOR_RANGE); | 659 | cairo_arc(window->cairo, wwidth/2, wheight/2, ARC_RADIUS, highlight_start, highlight_start + TYPE_INDICATOR_RANGE); |
655 | if (render_data->auth_state == AUTH_STATE_INPUT) { | 660 | if (render_data->auth_state == AUTH_STATE_INPUT) { |
656 | cairo_set_source_rgb(window->cairo, 51.0 / 255, 219.0 / 255, 0); | 661 | cairo_set_source_rgb(window->cairo, 51.0 / 255, 219.0 / 255, 0); |
657 | } else { | 662 | } else { |
@@ -661,19 +666,19 @@ void render(struct render_data *render_data) { | |||
661 | 666 | ||
662 | // Draw borders | 667 | // Draw borders |
663 | cairo_set_source_rgb(window->cairo, 0, 0, 0); | 668 | cairo_set_source_rgb(window->cairo, 0, 0, 0); |
664 | cairo_arc(window->cairo, window->width/2, window->height/2, ARC_RADIUS, highlight_start, highlight_start + TYPE_INDICATOR_BORDER_THICKNESS); | 669 | cairo_arc(window->cairo, wwidth/2, wheight/2, ARC_RADIUS, highlight_start, highlight_start + TYPE_INDICATOR_BORDER_THICKNESS); |
665 | cairo_stroke(window->cairo); | 670 | cairo_stroke(window->cairo); |
666 | 671 | ||
667 | cairo_arc(window->cairo, window->width/2, window->height/2, ARC_RADIUS, highlight_start + TYPE_INDICATOR_RANGE, (highlight_start + TYPE_INDICATOR_RANGE) + TYPE_INDICATOR_BORDER_THICKNESS); | 672 | cairo_arc(window->cairo, wwidth/2, wheight/2, ARC_RADIUS, highlight_start + TYPE_INDICATOR_RANGE, (highlight_start + TYPE_INDICATOR_RANGE) + TYPE_INDICATOR_BORDER_THICKNESS); |
668 | cairo_stroke(window->cairo); | 673 | cairo_stroke(window->cairo); |
669 | } | 674 | } |
670 | 675 | ||
671 | // Draw inner + outer border of the circle | 676 | // Draw inner + outer border of the circle |
672 | cairo_set_source_rgb(window->cairo, 0, 0, 0); | 677 | cairo_set_source_rgb(window->cairo, 0, 0, 0); |
673 | cairo_set_line_width(window->cairo, 2.0); | 678 | cairo_set_line_width(window->cairo, 2.0); |
674 | cairo_arc(window->cairo, window->width/2, window->height/2, ARC_RADIUS - ARC_THICKNESS/2, 0, 2*M_PI); | 679 | cairo_arc(window->cairo, wwidth/2, wheight/2, ARC_RADIUS - ARC_THICKNESS/2, 0, 2*M_PI); |
675 | cairo_stroke(window->cairo); | 680 | cairo_stroke(window->cairo); |
676 | cairo_arc(window->cairo, window->width/2, window->height/2, ARC_RADIUS + ARC_THICKNESS/2, 0, 2*M_PI); | 681 | cairo_arc(window->cairo, wwidth/2, wheight/2, ARC_RADIUS + ARC_THICKNESS/2, 0, 2*M_PI); |
677 | cairo_stroke(window->cairo); | 682 | cairo_stroke(window->cairo); |
678 | } | 683 | } |
679 | window_render(window); | 684 | window_render(window); |
diff --git a/wayland/buffers.c b/wayland/buffers.c index ff1e5ecf..227d6d2c 100644 --- a/wayland/buffers.c +++ b/wayland/buffers.c | |||
@@ -50,8 +50,10 @@ static const struct wl_buffer_listener buffer_listener = { | |||
50 | }; | 50 | }; |
51 | 51 | ||
52 | static struct buffer *create_buffer(struct window *window, struct buffer *buf, | 52 | static struct buffer *create_buffer(struct window *window, struct buffer *buf, |
53 | int32_t width, int32_t height, uint32_t format) { | 53 | int32_t width, int32_t height, int32_t scale, uint32_t format) { |
54 | 54 | ||
55 | width *= scale; | ||
56 | height *= scale; | ||
55 | uint32_t stride = width * 4; | 57 | uint32_t stride = width * 4; |
56 | uint32_t size = stride * height; | 58 | uint32_t size = stride * height; |
57 | 59 | ||
@@ -63,7 +65,8 @@ static struct buffer *create_buffer(struct window *window, struct buffer *buf, | |||
63 | } | 65 | } |
64 | void *data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); | 66 | void *data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); |
65 | struct wl_shm_pool *pool = wl_shm_create_pool(window->registry->shm, fd, size); | 67 | struct wl_shm_pool *pool = wl_shm_create_pool(window->registry->shm, fd, size); |
66 | buf->buffer = wl_shm_pool_create_buffer(pool, 0, width, height, stride, format); | 68 | buf->buffer = wl_shm_pool_create_buffer(pool, 0, |
69 | width, height, stride, format); | ||
67 | wl_shm_pool_destroy(pool); | 70 | wl_shm_pool_destroy(pool); |
68 | close(fd); | 71 | close(fd); |
69 | unlink(name); | 72 | unlink(name); |
@@ -72,10 +75,10 @@ static struct buffer *create_buffer(struct window *window, struct buffer *buf, | |||
72 | 75 | ||
73 | buf->width = width; | 76 | buf->width = width; |
74 | buf->height = height; | 77 | buf->height = height; |
75 | buf->surface = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32, width, height, stride); | 78 | buf->surface = cairo_image_surface_create_for_data(data, |
79 | CAIRO_FORMAT_ARGB32, width, height, stride); | ||
76 | buf->cairo = cairo_create(buf->surface); | 80 | buf->cairo = cairo_create(buf->surface); |
77 | buf->pango = pango_cairo_create_context(buf->cairo); | 81 | buf->pango = pango_cairo_create_context(buf->cairo); |
78 | pango_cairo_context_set_resolution(buf->pango, 96 * 2); | ||
79 | 82 | ||
80 | wl_buffer_add_listener(buf->buffer, &buffer_listener, buf); | 83 | wl_buffer_add_listener(buf->buffer, &buffer_listener, buf); |
81 | return buf; | 84 | return buf; |
@@ -114,7 +117,9 @@ struct buffer *get_next_buffer(struct window *window) { | |||
114 | } | 117 | } |
115 | 118 | ||
116 | if (!buffer->buffer) { | 119 | if (!buffer->buffer) { |
117 | if (!create_buffer(window, buffer, window->width, window->height, WL_SHM_FORMAT_ARGB8888)) { | 120 | if (!create_buffer(window, buffer, |
121 | window->width, window->height, window->scale, | ||
122 | WL_SHM_FORMAT_ARGB8888)) { | ||
118 | return NULL; | 123 | return NULL; |
119 | } | 124 | } |
120 | } | 125 | } |
diff --git a/wayland/pango.c b/wayland/pango.c index f143aa6c..d601021f 100644 --- a/wayland/pango.c +++ b/wayland/pango.c | |||
@@ -9,6 +9,8 @@ | |||
9 | 9 | ||
10 | PangoLayout *get_pango_layout(cairo_t *cairo, const char *font, const char *text, bool markup) { | 10 | PangoLayout *get_pango_layout(cairo_t *cairo, const char *font, const char *text, bool markup) { |
11 | PangoLayout *layout = pango_cairo_create_layout(cairo); | 11 | PangoLayout *layout = pango_cairo_create_layout(cairo); |
12 | PangoAttrList *attrs = pango_attr_list_new(); | ||
13 | pango_attr_list_insert(attrs, pango_attr_scale_new(2)); | ||
12 | if (markup) { | 14 | if (markup) { |
13 | pango_layout_set_markup(layout, text, -1); | 15 | pango_layout_set_markup(layout, text, -1); |
14 | } else { | 16 | } else { |
@@ -17,6 +19,8 @@ PangoLayout *get_pango_layout(cairo_t *cairo, const char *font, const char *text | |||
17 | PangoFontDescription *desc = pango_font_description_from_string(font); | 19 | PangoFontDescription *desc = pango_font_description_from_string(font); |
18 | pango_layout_set_font_description(layout, desc); | 20 | pango_layout_set_font_description(layout, desc); |
19 | pango_layout_set_single_paragraph_mode(layout, 1); | 21 | pango_layout_set_single_paragraph_mode(layout, 1); |
22 | pango_layout_set_attributes(layout, attrs); | ||
23 | pango_attr_list_unref(attrs); | ||
20 | pango_font_description_free(desc); | 24 | pango_font_description_free(desc); |
21 | return layout; | 25 | return layout; |
22 | } | 26 | } |
diff --git a/wayland/registry.c b/wayland/registry.c index 2d66b7eb..44afb146 100644 --- a/wayland/registry.c +++ b/wayland/registry.c | |||
@@ -18,6 +18,8 @@ static void display_handle_mode(void *data, struct wl_output *wl_output, | |||
18 | state->flags = flags; | 18 | state->flags = flags; |
19 | state->width = width; | 19 | state->width = width; |
20 | state->height = height; | 20 | state->height = height; |
21 | sway_log(L_DEBUG, "Got mode %dx%x:0x%X for output %p", | ||
22 | width, height, flags, data); | ||
21 | } | 23 | } |
22 | } | 24 | } |
23 | 25 | ||
@@ -34,6 +36,7 @@ static void display_handle_done(void *data, struct wl_output *wl_output) { | |||
34 | static void display_handle_scale(void *data, struct wl_output *wl_output, int32_t factor) { | 36 | static void display_handle_scale(void *data, struct wl_output *wl_output, int32_t factor) { |
35 | struct output_state *state = data; | 37 | struct output_state *state = data; |
36 | state->scale = factor; | 38 | state->scale = factor; |
39 | sway_log(L_DEBUG, "Got scale factor %d for output %p", factor, data); | ||
37 | } | 40 | } |
38 | 41 | ||
39 | static const struct wl_output_listener output_listener = { | 42 | static const struct wl_output_listener output_listener = { |
diff --git a/wayland/window.c b/wayland/window.c index 3f48d39f..8a506656 100644 --- a/wayland/window.c +++ b/wayland/window.c | |||
@@ -93,11 +93,13 @@ void window_make_shell(struct window *window) { | |||
93 | wl_shell_surface_set_toplevel(window->shell_surface); | 93 | wl_shell_surface_set_toplevel(window->shell_surface); |
94 | } | 94 | } |
95 | 95 | ||
96 | struct window *window_setup(struct registry *registry, uint32_t width, uint32_t height, bool shell_surface) { | 96 | struct window *window_setup(struct registry *registry, uint32_t width, uint32_t height, |
97 | int32_t scale, bool shell_surface) { | ||
97 | struct window *window = malloc(sizeof(struct window)); | 98 | struct window *window = malloc(sizeof(struct window)); |
98 | memset(window, 0, sizeof(struct window)); | 99 | memset(window, 0, sizeof(struct window)); |
99 | window->width = width; | 100 | window->width = width; |
100 | window->height = height; | 101 | window->height = height; |
102 | window->scale = scale; | ||
101 | window->registry = registry; | 103 | window->registry = registry; |
102 | window->font = "monospace 10"; | 104 | window->font = "monospace 10"; |
103 | 105 | ||
@@ -121,15 +123,18 @@ struct window *window_setup(struct registry *registry, uint32_t width, uint32_t | |||
121 | cursor_size = "16"; | 123 | cursor_size = "16"; |
122 | } | 124 | } |
123 | 125 | ||
126 | sway_log(L_DEBUG, "Cursor scale: %d", scale); | ||
124 | window->cursor.cursor_theme = wl_cursor_theme_load(cursor_theme, | 127 | window->cursor.cursor_theme = wl_cursor_theme_load(cursor_theme, |
125 | atoi(cursor_size), registry->shm); | 128 | atoi(cursor_size) * scale, registry->shm); |
126 | window->cursor.cursor = wl_cursor_theme_get_cursor(window->cursor.cursor_theme, "left_ptr"); | 129 | window->cursor.cursor = wl_cursor_theme_get_cursor(window->cursor.cursor_theme, "left_ptr"); |
127 | window->cursor.surface = wl_compositor_create_surface(registry->compositor); | 130 | window->cursor.surface = wl_compositor_create_surface(registry->compositor); |
128 | 131 | ||
129 | struct wl_cursor_image *image = window->cursor.cursor->images[0]; | 132 | struct wl_cursor_image *image = window->cursor.cursor->images[0]; |
130 | struct wl_buffer *cursor_buf = wl_cursor_image_get_buffer(image); | 133 | struct wl_buffer *cursor_buf = wl_cursor_image_get_buffer(image); |
131 | wl_surface_attach(window->cursor.surface, cursor_buf, 0, 0); | 134 | wl_surface_attach(window->cursor.surface, cursor_buf, 0, 0); |
132 | wl_surface_damage(window->cursor.surface, 0, 0, image->width, image->height); | 135 | wl_surface_set_buffer_scale(window->cursor.surface, scale); |
136 | wl_surface_damage(window->cursor.surface, 0, 0, | ||
137 | image->width, image->height); | ||
133 | wl_surface_commit(window->cursor.surface); | 138 | wl_surface_commit(window->cursor.surface); |
134 | } | 139 | } |
135 | 140 | ||
@@ -159,8 +164,9 @@ int window_render(struct window *window) { | |||
159 | window->frame_cb = wl_surface_frame(window->surface); | 164 | window->frame_cb = wl_surface_frame(window->surface); |
160 | wl_callback_add_listener(window->frame_cb, &listener, window); | 165 | wl_callback_add_listener(window->frame_cb, &listener, window); |
161 | 166 | ||
162 | wl_surface_damage(window->surface, 0, 0, window->buffer->width, window->buffer->height); | ||
163 | wl_surface_attach(window->surface, window->buffer->buffer, 0, 0); | 167 | wl_surface_attach(window->surface, window->buffer->buffer, 0, 0); |
168 | wl_surface_set_buffer_scale(window->surface, window->scale); | ||
169 | wl_surface_damage(window->surface, 0, 0, window->width, window->height); | ||
164 | wl_surface_commit(window->surface); | 170 | wl_surface_commit(window->surface); |
165 | 171 | ||
166 | return 1; | 172 | return 1; |