aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2015-11-25 18:58:23 -0500
committerLibravatar Drew DeVault <sir@cmpwn.com>2015-11-25 18:58:23 -0500
commita713686daa0b80bb7273a220d08ad99bcf1dab72 (patch)
treeeb872cf8e54e08d6ee6205564d8959a11430b9b3
parentMerge pull request #251 from sce/criteria_1 (diff)
parentswaybg: implement scaling mode "fit" (diff)
downloadsway-a713686daa0b80bb7273a220d08ad99bcf1dab72.tar.gz
sway-a713686daa0b80bb7273a220d08ad99bcf1dab72.tar.zst
sway-a713686daa0b80bb7273a220d08ad99bcf1dab72.zip
Merge pull request #260 from christophgysin/scale
implement background scaling
-rw-r--r--sway.5.txt2
-rw-r--r--sway/commands.c1
-rw-r--r--swaybg/main.c95
3 files changed, 92 insertions, 6 deletions
diff --git a/sway.5.txt b/sway.5.txt
index 700de8b2..8a949465 100644
--- a/sway.5.txt
+++ b/sway.5.txt
@@ -127,7 +127,7 @@ Commands
127 127
128**output** <name> <background|bg> <file> <mode>:: 128**output** <name> <background|bg> <file> <mode>::
129 Sets the wallpaper for the given output to the specified file, using the given 129 Sets the wallpaper for the given output to the specified file, using the given
130 scaling mode (one of "stretch", "fill", "center", "tile"). 130 scaling mode (one of "stretch", "fill", "fit", "center", "tile").
131 131
132**output** <name> disable:: 132**output** <name> disable::
133 Disables the specified output. 133 Disables the specified output.
diff --git a/sway/commands.c b/sway/commands.c
index 6a4af43c..c63aa320 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -85,6 +85,7 @@ static char *bg_options[] = {
85 "stretch", 85 "stretch",
86 "center", 86 "center",
87 "fill", 87 "fill",
88 "fit",
88 "tile" 89 "tile"
89}; 90};
90 91
diff --git a/swaybg/main.c b/swaybg/main.c
index 5a12eec6..e4c699c1 100644
--- a/swaybg/main.c
+++ b/swaybg/main.c
@@ -12,6 +12,14 @@ list_t *surfaces;
12 12
13struct registry *registry; 13struct registry *registry;
14 14
15enum scaling_mode_t {
16 SCALING_MODE_STRETCH,
17 SCALING_MODE_FILL,
18 SCALING_MODE_FIT,
19 SCALING_MODE_CENTER,
20 SCALING_MODE_TILE,
21};
22
15void sway_terminate(void) { 23void sway_terminate(void) {
16 int i; 24 int i;
17 for (i = 0; i < surfaces->length; ++i) { 25 for (i = 0; i < surfaces->length; ++i) {
@@ -23,12 +31,12 @@ void sway_terminate(void) {
23 exit(1); 31 exit(1);
24} 32}
25 33
26int main(int argc, char **argv) { 34int main(int argc, const char **argv) {
27 init_log(L_INFO); 35 init_log(L_INFO);
28 surfaces = create_list(); 36 surfaces = create_list();
29 registry = registry_poll(); 37 registry = registry_poll();
30 38
31 if (argc < 4) { 39 if (argc != 4) {
32 sway_abort("Do not run this program manually. See man 5 sway and look for output options."); 40 sway_abort("Do not run this program manually. See man 5 sway and look for output options.");
33 } 41 }
34 42
@@ -49,16 +57,93 @@ int main(int argc, char **argv) {
49 desktop_shell_set_background(registry->desktop_shell, output->output, window->surface); 57 desktop_shell_set_background(registry->desktop_shell, output->output, window->surface);
50 list_add(surfaces, window); 58 list_add(surfaces, window);
51 59
52 char *scaling_mode = argv[3];
53 cairo_surface_t *image = cairo_image_surface_create_from_png(argv[2]); 60 cairo_surface_t *image = cairo_image_surface_create_from_png(argv[2]);
54 double width = cairo_image_surface_get_width(image); 61 double width = cairo_image_surface_get_width(image);
55 double height = cairo_image_surface_get_height(image); 62 double height = cairo_image_surface_get_height(image);
56 63
64 const char *scaling_mode_str = argv[3];
65 enum scaling_mode_t scaling_mode;
66 if (strcmp(scaling_mode_str, "stretch") == 0) {
67 scaling_mode = SCALING_MODE_STRETCH;
68 } else if (strcmp(scaling_mode_str, "fill") == 0) {
69 scaling_mode = SCALING_MODE_FILL;
70 } else if (strcmp(scaling_mode_str, "fit") == 0) {
71 scaling_mode = SCALING_MODE_FIT;
72 } else if (strcmp(scaling_mode_str, "center") == 0) {
73 scaling_mode = SCALING_MODE_CENTER;
74 } else if (strcmp(scaling_mode_str, "tile") == 0) {
75 scaling_mode = SCALING_MODE_TILE;
76 } else {
77 sway_abort("Unsupported scaling mode: %s", scaling_mode_str);
78 }
79
57 for (i = 0; i < surfaces->length; ++i) { 80 for (i = 0; i < surfaces->length; ++i) {
58 struct window *window = surfaces->items[i]; 81 struct window *window = surfaces->items[i];
59 if (window_prerender(window) && window->cairo) { 82 if (window_prerender(window) && window->cairo) {
60 cairo_scale(window->cairo, window->width / width, window->height / height); 83
61 cairo_set_source_surface(window->cairo, image, 0, 0); 84 switch (scaling_mode) {
85 case SCALING_MODE_STRETCH:
86 cairo_scale(window->cairo,
87 (double) window->width / width,
88 (double) window->height / height);
89 cairo_set_source_surface(window->cairo, image, 0, 0);
90 break;
91 case SCALING_MODE_FILL:
92 {
93 double window_ratio = (double) window->width / window->height;
94 double bg_ratio = width / height;
95
96 if (window_ratio > bg_ratio) {
97 double scale = (double) window->width / width;
98 cairo_scale(window->cairo, scale, scale);
99 cairo_set_source_surface(window->cairo, image,
100 0,
101 (double) window->height/2 / scale - height/2);
102 } else {
103 double scale = (double) window->height / height;
104 cairo_scale(window->cairo, scale, scale);
105 cairo_set_source_surface(window->cairo, image,
106 (double) window->width/2 / scale - width/2,
107 0);
108 }
109 }
110 break;
111 case SCALING_MODE_FIT:
112 {
113 double window_ratio = (double) window->width / window->height;
114 double bg_ratio = width / height;
115
116 if (window_ratio > bg_ratio) {
117 double scale = (double) window->height / height;
118 cairo_scale(window->cairo, scale, scale);
119 cairo_set_source_surface(window->cairo, image,
120 (double) window->width/2 / scale - width/2,
121 0);
122 } else {
123 double scale = (double) window->width / width;
124 cairo_scale(window->cairo, scale, scale);
125 cairo_set_source_surface(window->cairo, image,
126 0,
127 (double) window->height/2 / scale - height/2);
128 }
129 }
130 break;
131 case SCALING_MODE_CENTER:
132 cairo_set_source_surface(window->cairo, image,
133 (double) window->width/2 - width/2,
134 (double) window->height/2 - height/2);
135 break;
136 case SCALING_MODE_TILE:
137 {
138 cairo_pattern_t *pattern = cairo_pattern_create_for_surface(image);
139 cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
140 cairo_set_source(window->cairo, pattern);
141 }
142 break;
143 default:
144 sway_abort("Scaling mode '%s' not implemented yet!", scaling_mode_str);
145 }
146
62 cairo_paint(window->cairo); 147 cairo_paint(window->cairo);
63 148
64 window_render(window); 149 window_render(window);