summaryrefslogtreecommitdiffstats
path: root/swaybg
diff options
context:
space:
mode:
authorLibravatar Zandr Martin <zandrmartin@gmail.com>2016-07-30 18:50:13 -0500
committerLibravatar Zandr Martin <zandrmartin@gmail.com>2016-07-30 18:50:13 -0500
commit98aa59fdda5fcc9a589e93f7c6ef40d3eaee3972 (patch)
treea7acb9aab8520040d49be04184d70984a66b95e7 /swaybg
parentMerge pull request #803 from zandrmartin/x11-pids (diff)
downloadsway-98aa59fdda5fcc9a589e93f7c6ef40d3eaee3972.tar.gz
sway-98aa59fdda5fcc9a589e93f7c6ef40d3eaee3972.tar.zst
sway-98aa59fdda5fcc9a589e93f7c6ef40d3eaee3972.zip
implement solid color rendering for swaybg
Diffstat (limited to 'swaybg')
-rw-r--r--swaybg/main.c216
1 files changed, 121 insertions, 95 deletions
diff --git a/swaybg/main.c b/swaybg/main.c
index 4e0cc4b3..b23b8027 100644
--- a/swaybg/main.c
+++ b/swaybg/main.c
@@ -1,6 +1,8 @@
1#include "wayland-desktop-shell-client-protocol.h" 1#include "wayland-desktop-shell-client-protocol.h"
2#include <stdbool.h>
2#include <stdio.h> 3#include <stdio.h>
3#include <stdlib.h> 4#include <stdlib.h>
5#include <ctype.h>
4#include <wayland-client.h> 6#include <wayland-client.h>
5#include <time.h> 7#include <time.h>
6#include <string.h> 8#include <string.h>
@@ -9,6 +11,7 @@
9#include "client/cairo.h" 11#include "client/cairo.h"
10#include "log.h" 12#include "log.h"
11#include "list.h" 13#include "list.h"
14#include "util.h"
12 15
13list_t *surfaces; 16list_t *surfaces;
14struct registry *registry; 17struct registry *registry;
@@ -32,6 +35,23 @@ void sway_terminate(int exit_code) {
32 exit(exit_code); 35 exit(exit_code);
33} 36}
34 37
38bool is_valid_color(const char *color) {
39 int len = strlen(color);
40 if (len != 7 || color[0] != '#') {
41 sway_log(L_ERROR, "%s is not a valid color for swaybg. Color should be specified as #rrggbb (no alpha).", color);
42 return false;
43 }
44
45 int i;
46 for (i = 1; i < len; ++i) {
47 if (!isxdigit(color[i])) {
48 return false;
49 }
50 }
51
52 return true;
53}
54
35int main(int argc, const char **argv) { 55int main(int argc, const char **argv) {
36 init_log(L_INFO); 56 init_log(L_INFO);
37 surfaces = create_list(); 57 surfaces = create_list();
@@ -57,112 +77,118 @@ int main(int argc, const char **argv) {
57 window_make_shell(window); 77 window_make_shell(window);
58 list_add(surfaces, window); 78 list_add(surfaces, window);
59 79
80 if (strcmp(argv[3], "solid_color") == 0 && is_valid_color(argv[2])) {
81 cairo_set_source_u32(window->cairo, parse_color(argv[2]));
82 cairo_paint(window->cairo);
83 window_render(window);
84 } else {
60#ifdef WITH_GDK_PIXBUF 85#ifdef WITH_GDK_PIXBUF
61 GError *err = NULL; 86 GError *err = NULL;
62 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(argv[2], &err); 87 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(argv[2], &err);
63 if (!pixbuf) { 88 if (!pixbuf) {
64 sway_abort("Failed to load background image."); 89 sway_abort("Failed to load background image.");
65 } 90 }
66 cairo_surface_t *image = gdk_cairo_image_surface_create_from_pixbuf(pixbuf); 91 cairo_surface_t *image = gdk_cairo_image_surface_create_from_pixbuf(pixbuf);
67 g_object_unref(pixbuf); 92 g_object_unref(pixbuf);
68#else 93#else
69 cairo_surface_t *image = cairo_image_surface_create_from_png(argv[2]); 94 cairo_surface_t *image = cairo_image_surface_create_from_png(argv[2]);
70#endif //WITH_GDK_PIXBUF 95#endif //WITH_GDK_PIXBUF
71 if (!image) { 96 if (!image) {
72 sway_abort("Failed to read background image."); 97 sway_abort("Failed to read background image.");
73 } 98 }
74 double width = cairo_image_surface_get_width(image); 99 double width = cairo_image_surface_get_width(image);
75 double height = cairo_image_surface_get_height(image); 100 double height = cairo_image_surface_get_height(image);
76 101
77 const char *scaling_mode_str = argv[3]; 102 const char *scaling_mode_str = argv[3];
78 enum scaling_mode scaling_mode = SCALING_MODE_STRETCH; 103 enum scaling_mode scaling_mode = SCALING_MODE_STRETCH;
79 if (strcmp(scaling_mode_str, "stretch") == 0) { 104 if (strcmp(scaling_mode_str, "stretch") == 0) {
80 scaling_mode = SCALING_MODE_STRETCH; 105 scaling_mode = SCALING_MODE_STRETCH;
81 } else if (strcmp(scaling_mode_str, "fill") == 0) { 106 } else if (strcmp(scaling_mode_str, "fill") == 0) {
82 scaling_mode = SCALING_MODE_FILL; 107 scaling_mode = SCALING_MODE_FILL;
83 } else if (strcmp(scaling_mode_str, "fit") == 0) { 108 } else if (strcmp(scaling_mode_str, "fit") == 0) {
84 scaling_mode = SCALING_MODE_FIT; 109 scaling_mode = SCALING_MODE_FIT;
85 } else if (strcmp(scaling_mode_str, "center") == 0) { 110 } else if (strcmp(scaling_mode_str, "center") == 0) {
86 scaling_mode = SCALING_MODE_CENTER; 111 scaling_mode = SCALING_MODE_CENTER;
87 } else if (strcmp(scaling_mode_str, "tile") == 0) { 112 } else if (strcmp(scaling_mode_str, "tile") == 0) {
88 scaling_mode = SCALING_MODE_TILE; 113 scaling_mode = SCALING_MODE_TILE;
89 } else { 114 } else {
90 sway_abort("Unsupported scaling mode: %s", scaling_mode_str); 115 sway_abort("Unsupported scaling mode: %s", scaling_mode_str);
91 } 116 }
92 117
93 for (i = 0; i < surfaces->length; ++i) { 118 for (i = 0; i < surfaces->length; ++i) {
94 struct window *window = surfaces->items[i]; 119 struct window *window = surfaces->items[i];
95 if (window_prerender(window) && window->cairo) { 120 if (window_prerender(window) && window->cairo) {
96 switch (scaling_mode) { 121 switch (scaling_mode) {
97 case SCALING_MODE_STRETCH: 122 case SCALING_MODE_STRETCH:
98 cairo_scale(window->cairo, 123 cairo_scale(window->cairo,
99 (double) window->width / width, 124 (double) window->width / width,
100 (double) window->height / height); 125 (double) window->height / height);
101 cairo_set_source_surface(window->cairo, image, 0, 0); 126 cairo_set_source_surface(window->cairo, image, 0, 0);
102 break; 127 break;
103 case SCALING_MODE_FILL: 128 case SCALING_MODE_FILL:
104 { 129 {
105 double window_ratio = (double) window->width / window->height; 130 double window_ratio = (double) window->width / window->height;
106 double bg_ratio = width / height; 131 double bg_ratio = width / height;
107 132
108 if (window_ratio > bg_ratio) { 133 if (window_ratio > bg_ratio) {
109 double scale = (double) window->width / width; 134 double scale = (double) window->width / width;
110 cairo_scale(window->cairo, scale, scale); 135 cairo_scale(window->cairo, scale, scale);
111 cairo_set_source_surface(window->cairo, image, 136 cairo_set_source_surface(window->cairo, image,
112 0, 137 0,
113 (double) window->height/2 / scale - height/2); 138 (double) window->height/2 / scale - height/2);
114 } else { 139 } else {
115 double scale = (double) window->height / height; 140 double scale = (double) window->height / height;
116 cairo_scale(window->cairo, scale, scale); 141 cairo_scale(window->cairo, scale, scale);
117 cairo_set_source_surface(window->cairo, image, 142 cairo_set_source_surface(window->cairo, image,
118 (double) window->width/2 / scale - width/2, 143 (double) window->width/2 / scale - width/2,
119 0); 144 0);
145 }
146 break;
120 } 147 }
121 break; 148 case SCALING_MODE_FIT:
122 } 149 {
123 case SCALING_MODE_FIT: 150 double window_ratio = (double) window->width / window->height;
124 { 151 double bg_ratio = width / height;
125 double window_ratio = (double) window->width / window->height; 152
126 double bg_ratio = width / height; 153 if (window_ratio > bg_ratio) {
127 154 double scale = (double) window->height / height;
128 if (window_ratio > bg_ratio) { 155 cairo_scale(window->cairo, scale, scale);
129 double scale = (double) window->height / height; 156 cairo_set_source_surface(window->cairo, image,
130 cairo_scale(window->cairo, scale, scale); 157 (double) window->width/2 / scale - width/2,
131 cairo_set_source_surface(window->cairo, image, 158 0);
132 (double) window->width/2 / scale - width/2, 159 } else {
133 0); 160 double scale = (double) window->width / width;
134 } else { 161 cairo_scale(window->cairo, scale, scale);
135 double scale = (double) window->width / width; 162 cairo_set_source_surface(window->cairo, image,
136 cairo_scale(window->cairo, scale, scale); 163 0,
164 (double) window->height/2 / scale - height/2);
165 }
166 break;
167 }
168 case SCALING_MODE_CENTER:
137 cairo_set_source_surface(window->cairo, image, 169 cairo_set_source_surface(window->cairo, image,
138 0, 170 (double) window->width/2 - width/2,
139 (double) window->height/2 / scale - height/2); 171 (double) window->height/2 - height/2);
172 break;
173 case SCALING_MODE_TILE:
174 {
175 cairo_pattern_t *pattern = cairo_pattern_create_for_surface(image);
176 cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
177 cairo_set_source(window->cairo, pattern);
178 break;
179 }
180 default:
181 sway_abort("Scaling mode '%s' not implemented yet!", scaling_mode_str);
140 } 182 }
141 break;
142 }
143 case SCALING_MODE_CENTER:
144 cairo_set_source_surface(window->cairo, image,
145 (double) window->width/2 - width/2,
146 (double) window->height/2 - height/2);
147 break;
148 case SCALING_MODE_TILE:
149 {
150 cairo_pattern_t *pattern = cairo_pattern_create_for_surface(image);
151 cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
152 cairo_set_source(window->cairo, pattern);
153 break;
154 }
155 default:
156 sway_abort("Scaling mode '%s' not implemented yet!", scaling_mode_str);
157 }
158 183
159 cairo_paint(window->cairo); 184 cairo_paint(window->cairo);
160 185
161 window_render(window); 186 window_render(window);
187 }
162 } 188 }
163 }
164 189
165 cairo_surface_destroy(image); 190 cairo_surface_destroy(image);
191 }
166 192
167 while (wl_display_dispatch(registry->display) != -1); 193 while (wl_display_dispatch(registry->display) != -1);
168 194