diff options
-rw-r--r-- | README.es.md | 4 | ||||
-rw-r--r-- | README.fr.md | 4 | ||||
-rw-r--r-- | README.ja.md | 4 | ||||
-rw-r--r-- | README.md | 4 | ||||
-rw-r--r-- | README.pl.md | 4 | ||||
-rw-r--r-- | README.uk.md | 4 | ||||
-rw-r--r-- | README.zh-CN.md | 4 | ||||
-rw-r--r-- | client/meson.build | 1 | ||||
-rw-r--r-- | common/background-image.c | 100 | ||||
-rw-r--r-- | common/cairo.c | 99 | ||||
-rw-r--r-- | include/cairo.h | 11 | ||||
-rw-r--r-- | meson.build | 2 | ||||
-rw-r--r-- | sway/meson.build | 1 | ||||
-rw-r--r-- | swaybg/main.c | 542 | ||||
-rw-r--r-- | swaybg/meson.build | 16 | ||||
-rw-r--r-- | swaybg/swaybg.1.scd | 44 | ||||
-rw-r--r-- | swaynag/meson.build | 1 |
17 files changed, 107 insertions, 738 deletions
diff --git a/README.es.md b/README.es.md index 30f11639..9cb4a65c 100644 --- a/README.es.md +++ b/README.es.md | |||
@@ -34,14 +34,12 @@ Instale las dependencias: | |||
34 | * json-c | 34 | * json-c |
35 | * pango | 35 | * pango |
36 | * cairo | 36 | * cairo |
37 | * gdk-pixbuf2 \*\* | 37 | * gdk-pixbuf2 (optional: system tray) |
38 | * [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (optional: man pages) \* | 38 | * [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (optional: man pages) \* |
39 | * git \* | 39 | * git \* |
40 | 40 | ||
41 | _\*Compile-time dep_ | 41 | _\*Compile-time dep_ |
42 | 42 | ||
43 | _\*\*opcional: necesario para swaybg_ | ||
44 | |||
45 | Desde su consola, ejecute las órdenes: | 43 | Desde su consola, ejecute las órdenes: |
46 | 44 | ||
47 | meson build | 45 | meson build |
diff --git a/README.fr.md b/README.fr.md index 97c09667..50ba2e40 100644 --- a/README.fr.md +++ b/README.fr.md | |||
@@ -41,14 +41,12 @@ Installez les dépendances : | |||
41 | * json-c | 41 | * json-c |
42 | * pango | 42 | * pango |
43 | * cairo | 43 | * cairo |
44 | * gdk-pixbuf2 \*\* | 44 | * gdk-pixbuf2 (optionnel: system tray) |
45 | * [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (optionnel: requis pour les pages man) \* | 45 | * [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (optionnel: requis pour les pages man) \* |
46 | * git \* | 46 | * git \* |
47 | 47 | ||
48 | _\*Requis uniquement pour la compilation_ | 48 | _\*Requis uniquement pour la compilation_ |
49 | 49 | ||
50 | _\*\*Optionnel: requis uniquement pour swaybg_ | ||
51 | |||
52 | Exécutez ces commandes : | 50 | Exécutez ces commandes : |
53 | 51 | ||
54 | meson build | 52 | meson build |
diff --git a/README.ja.md b/README.ja.md index 800daa62..f0253f5d 100644 --- a/README.ja.md +++ b/README.ja.md | |||
@@ -36,14 +36,12 @@ Swayは沢山のディストリビューションで提供されています。" | |||
36 | * json-c | 36 | * json-c |
37 | * pango | 37 | * pango |
38 | * cairo | 38 | * cairo |
39 | * gdk-pixbuf2 \*\* | 39 | * gdk-pixbuf2 (システムイコンで必要です) |
40 | * [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (manで必要です) \* | 40 | * [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (manで必要です) \* |
41 | * git \* | 41 | * git \* |
42 | 42 | ||
43 | _\*コンパイルの時_ | 43 | _\*コンパイルの時_ |
44 | 44 | ||
45 | _\*\*オプション: swaybgでのみ必要です_ | ||
46 | |||
47 | 次のコマンドを実行してください: | 45 | 次のコマンドを実行してください: |
48 | 46 | ||
49 | meson build | 47 | meson build |
@@ -38,14 +38,12 @@ Install dependencies: | |||
38 | * json-c | 38 | * json-c |
39 | * pango | 39 | * pango |
40 | * cairo | 40 | * cairo |
41 | * gdk-pixbuf2 \*\* | 41 | * gdk-pixbuf2 (optional: system tray) |
42 | * [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (optional: man pages) \* | 42 | * [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (optional: man pages) \* |
43 | * git \* | 43 | * git \* |
44 | 44 | ||
45 | _\*Compile-time dep_ | 45 | _\*Compile-time dep_ |
46 | 46 | ||
47 | _\*\*optional: required for swaybg_ | ||
48 | |||
49 | Run these commands: | 47 | Run these commands: |
50 | 48 | ||
51 | meson build | 49 | meson build |
diff --git a/README.pl.md b/README.pl.md index 31427d53..45b610b3 100644 --- a/README.pl.md +++ b/README.pl.md | |||
@@ -34,14 +34,12 @@ Zainstaluj zależności: | |||
34 | * json-c | 34 | * json-c |
35 | * pango | 35 | * pango |
36 | * cairo | 36 | * cairo |
37 | * gdk-pixbuf2 \*\* | 37 | * gdk-pixbuf2 (opcjonalnie: system tray) |
38 | * [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (opcjonalnie: strony pomocy man) \* | 38 | * [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (opcjonalnie: strony pomocy man) \* |
39 | * git \* | 39 | * git \* |
40 | 40 | ||
41 | _\*zależności kompilacji_ | 41 | _\*zależności kompilacji_ |
42 | 42 | ||
43 | _\*\*opcjonalnie: wymagane dla swaybg_ | ||
44 | |||
45 | Wykonaj następujące polecenia: | 43 | Wykonaj następujące polecenia: |
46 | 44 | ||
47 | meson build | 45 | meson build |
diff --git a/README.uk.md b/README.uk.md index b0c81c51..413579e6 100644 --- a/README.uk.md +++ b/README.uk.md | |||
@@ -46,14 +46,12 @@ Sway доступний у багатьох дистрибутивах Linux (а | |||
46 | * json-c | 46 | * json-c |
47 | * pango | 47 | * pango |
48 | * cairo | 48 | * cairo |
49 | * gdk-pixbuf2 \*\* | 49 | * gdk-pixbuf2 (optional: system tray) |
50 | * [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (необов'язково, необхідно для сторінок man) \* | 50 | * [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (необов'язково, необхідно для сторінок man) \* |
51 | * git \* | 51 | * git \* |
52 | 52 | ||
53 | _\*Лише для компіляції_ | 53 | _\*Лише для компіляції_ |
54 | 54 | ||
55 | _\*\*Необов'язково, необхідно для swaybg_ | ||
56 | |||
57 | Виконайте ці команди: | 55 | Виконайте ці команди: |
58 | 56 | ||
59 | meson build | 57 | meson build |
diff --git a/README.zh-CN.md b/README.zh-CN.md index 6df5a1f3..f40572da 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md | |||
@@ -35,14 +35,12 @@ Sway 在很多发行版中可用. 尝试在你的发行版中安装 "sway" 包. | |||
35 | * json-c | 35 | * json-c |
36 | * pango | 36 | * pango |
37 | * cairo | 37 | * cairo |
38 | * gdk-pixbuf2 \*\* | 38 | * gdk-pixbuf2 (可选的: system tray) |
39 | * [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (可选的: man pages) \* | 39 | * [scdoc](https://git.sr.ht/~sircmpwn/scdoc) (可选的: man pages) \* |
40 | * git \* | 40 | * git \* |
41 | 41 | ||
42 | _\*编译时依赖_ | 42 | _\*编译时依赖_ |
43 | 43 | ||
44 | _\*\*可选的: swaybg 依赖_ | ||
45 | |||
46 | 运行这些命令: | 44 | 运行这些命令: |
47 | 45 | ||
48 | meson build | 46 | meson build |
diff --git a/client/meson.build b/client/meson.build index abe6f1eb..4484a38c 100644 --- a/client/meson.build +++ b/client/meson.build | |||
@@ -5,7 +5,6 @@ lib_sway_client = static_library( | |||
5 | ), | 5 | ), |
6 | dependencies: [ | 6 | dependencies: [ |
7 | cairo, | 7 | cairo, |
8 | gdk_pixbuf, | ||
9 | pango, | 8 | pango, |
10 | pangocairo, | 9 | pangocairo, |
11 | wayland_client | 10 | wayland_client |
diff --git a/common/background-image.c b/common/background-image.c index 4431b725..de42e8e9 100644 --- a/common/background-image.c +++ b/common/background-image.c | |||
@@ -2,6 +2,9 @@ | |||
2 | #include "background-image.h" | 2 | #include "background-image.h" |
3 | #include "cairo.h" | 3 | #include "cairo.h" |
4 | #include "log.h" | 4 | #include "log.h" |
5 | #if HAVE_GDK_PIXBUF | ||
6 | #include <gdk-pixbuf/gdk-pixbuf.h> | ||
7 | #endif | ||
5 | 8 | ||
6 | enum background_mode parse_background_mode(const char *mode) { | 9 | enum background_mode parse_background_mode(const char *mode) { |
7 | if (strcmp(mode, "stretch") == 0) { | 10 | if (strcmp(mode, "stretch") == 0) { |
@@ -21,6 +24,103 @@ enum background_mode parse_background_mode(const char *mode) { | |||
21 | return BACKGROUND_MODE_INVALID; | 24 | return BACKGROUND_MODE_INVALID; |
22 | } | 25 | } |
23 | 26 | ||
27 | #if HAVE_GDK_PIXBUF | ||
28 | static cairo_surface_t* gdk_cairo_image_surface_create_from_pixbuf( | ||
29 | const GdkPixbuf *gdkbuf) { | ||
30 | int chan = gdk_pixbuf_get_n_channels(gdkbuf); | ||
31 | if (chan < 3) { | ||
32 | return NULL; | ||
33 | } | ||
34 | |||
35 | const guint8* gdkpix = gdk_pixbuf_read_pixels(gdkbuf); | ||
36 | if (!gdkpix) { | ||
37 | return NULL; | ||
38 | } | ||
39 | gint w = gdk_pixbuf_get_width(gdkbuf); | ||
40 | gint h = gdk_pixbuf_get_height(gdkbuf); | ||
41 | int stride = gdk_pixbuf_get_rowstride(gdkbuf); | ||
42 | |||
43 | cairo_format_t fmt = (chan == 3) ? CAIRO_FORMAT_RGB24 : CAIRO_FORMAT_ARGB32; | ||
44 | cairo_surface_t * cs = cairo_image_surface_create (fmt, w, h); | ||
45 | cairo_surface_flush (cs); | ||
46 | if ( !cs || cairo_surface_status(cs) != CAIRO_STATUS_SUCCESS) { | ||
47 | return NULL; | ||
48 | } | ||
49 | |||
50 | int cstride = cairo_image_surface_get_stride(cs); | ||
51 | unsigned char * cpix = cairo_image_surface_get_data(cs); | ||
52 | |||
53 | if (chan == 3) { | ||
54 | int i; | ||
55 | for (i = h; i; --i) { | ||
56 | const guint8 *gp = gdkpix; | ||
57 | unsigned char *cp = cpix; | ||
58 | const guint8* end = gp + 3*w; | ||
59 | while (gp < end) { | ||
60 | #if G_BYTE_ORDER == G_LITTLE_ENDIAN | ||
61 | cp[0] = gp[2]; | ||
62 | cp[1] = gp[1]; | ||
63 | cp[2] = gp[0]; | ||
64 | #else | ||
65 | cp[1] = gp[0]; | ||
66 | cp[2] = gp[1]; | ||
67 | cp[3] = gp[2]; | ||
68 | #endif | ||
69 | gp += 3; | ||
70 | cp += 4; | ||
71 | } | ||
72 | gdkpix += stride; | ||
73 | cpix += cstride; | ||
74 | } | ||
75 | } else { | ||
76 | /* premul-color = alpha/255 * color/255 * 255 = (alpha*color)/255 | ||
77 | * (z/255) = z/256 * 256/255 = z/256 (1 + 1/255) | ||
78 | * = z/256 + (z/256)/255 = (z + z/255)/256 | ||
79 | * # recurse once | ||
80 | * = (z + (z + z/255)/256)/256 | ||
81 | * = (z + z/256 + z/256/255) / 256 | ||
82 | * # only use 16bit uint operations, loose some precision, | ||
83 | * # result is floored. | ||
84 | * -> (z + z>>8)>>8 | ||
85 | * # add 0x80/255 = 0.5 to convert floor to round | ||
86 | * => (z+0x80 + (z+0x80)>>8 ) >> 8 | ||
87 | * ------ | ||
88 | * tested as equal to lround(z/255.0) for uint z in [0..0xfe02] | ||
89 | */ | ||
90 | #define PREMUL_ALPHA(x,a,b,z) \ | ||
91 | G_STMT_START { z = a * b + 0x80; x = (z + (z >> 8)) >> 8; } \ | ||
92 | G_STMT_END | ||
93 | int i; | ||
94 | for (i = h; i; --i) { | ||
95 | const guint8 *gp = gdkpix; | ||
96 | unsigned char *cp = cpix; | ||
97 | const guint8* end = gp + 4*w; | ||
98 | guint z1, z2, z3; | ||
99 | while (gp < end) { | ||
100 | #if G_BYTE_ORDER == G_LITTLE_ENDIAN | ||
101 | PREMUL_ALPHA(cp[0], gp[2], gp[3], z1); | ||
102 | PREMUL_ALPHA(cp[1], gp[1], gp[3], z2); | ||
103 | PREMUL_ALPHA(cp[2], gp[0], gp[3], z3); | ||
104 | cp[3] = gp[3]; | ||
105 | #else | ||
106 | PREMUL_ALPHA(cp[1], gp[0], gp[3], z1); | ||
107 | PREMUL_ALPHA(cp[2], gp[1], gp[3], z2); | ||
108 | PREMUL_ALPHA(cp[3], gp[2], gp[3], z3); | ||
109 | cp[0] = gp[3]; | ||
110 | #endif | ||
111 | gp += 4; | ||
112 | cp += 4; | ||
113 | } | ||
114 | gdkpix += stride; | ||
115 | cpix += cstride; | ||
116 | } | ||
117 | #undef PREMUL_ALPHA | ||
118 | } | ||
119 | cairo_surface_mark_dirty(cs); | ||
120 | return cs; | ||
121 | } | ||
122 | #endif // HAVE_GDK_PIXBUF | ||
123 | |||
24 | cairo_surface_t *load_background_image(const char *path) { | 124 | cairo_surface_t *load_background_image(const char *path) { |
25 | cairo_surface_t *image; | 125 | cairo_surface_t *image; |
26 | #if HAVE_GDK_PIXBUF | 126 | #if HAVE_GDK_PIXBUF |
diff --git a/common/cairo.c b/common/cairo.c index f2ad54c1..403dcf49 100644 --- a/common/cairo.c +++ b/common/cairo.c | |||
@@ -1,9 +1,6 @@ | |||
1 | #include <stdint.h> | 1 | #include <stdint.h> |
2 | #include <cairo/cairo.h> | 2 | #include <cairo/cairo.h> |
3 | #include "cairo.h" | 3 | #include "cairo.h" |
4 | #if HAVE_GDK_PIXBUF | ||
5 | #include <gdk-pixbuf/gdk-pixbuf.h> | ||
6 | #endif | ||
7 | 4 | ||
8 | void cairo_set_source_u32(cairo_t *cairo, uint32_t color) { | 5 | void cairo_set_source_u32(cairo_t *cairo, uint32_t color) { |
9 | cairo_set_source_rgba(cairo, | 6 | cairo_set_source_rgba(cairo, |
@@ -45,99 +42,3 @@ cairo_surface_t *cairo_image_surface_scale(cairo_surface_t *image, | |||
45 | cairo_destroy(cairo); | 42 | cairo_destroy(cairo); |
46 | return new; | 43 | return new; |
47 | } | 44 | } |
48 | |||
49 | #if HAVE_GDK_PIXBUF | ||
50 | cairo_surface_t* gdk_cairo_image_surface_create_from_pixbuf(const GdkPixbuf *gdkbuf) { | ||
51 | int chan = gdk_pixbuf_get_n_channels(gdkbuf); | ||
52 | if (chan < 3) { | ||
53 | return NULL; | ||
54 | } | ||
55 | |||
56 | const guint8* gdkpix = gdk_pixbuf_read_pixels(gdkbuf); | ||
57 | if (!gdkpix) { | ||
58 | return NULL; | ||
59 | } | ||
60 | gint w = gdk_pixbuf_get_width(gdkbuf); | ||
61 | gint h = gdk_pixbuf_get_height(gdkbuf); | ||
62 | int stride = gdk_pixbuf_get_rowstride(gdkbuf); | ||
63 | |||
64 | cairo_format_t fmt = (chan == 3) ? CAIRO_FORMAT_RGB24 : CAIRO_FORMAT_ARGB32; | ||
65 | cairo_surface_t * cs = cairo_image_surface_create (fmt, w, h); | ||
66 | cairo_surface_flush (cs); | ||
67 | if ( !cs || cairo_surface_status(cs) != CAIRO_STATUS_SUCCESS) { | ||
68 | return NULL; | ||
69 | } | ||
70 | |||
71 | int cstride = cairo_image_surface_get_stride(cs); | ||
72 | unsigned char * cpix = cairo_image_surface_get_data(cs); | ||
73 | |||
74 | if (chan == 3) { | ||
75 | int i; | ||
76 | for (i = h; i; --i) { | ||
77 | const guint8 *gp = gdkpix; | ||
78 | unsigned char *cp = cpix; | ||
79 | const guint8* end = gp + 3*w; | ||
80 | while (gp < end) { | ||
81 | #if G_BYTE_ORDER == G_LITTLE_ENDIAN | ||
82 | cp[0] = gp[2]; | ||
83 | cp[1] = gp[1]; | ||
84 | cp[2] = gp[0]; | ||
85 | #else | ||
86 | cp[1] = gp[0]; | ||
87 | cp[2] = gp[1]; | ||
88 | cp[3] = gp[2]; | ||
89 | #endif | ||
90 | gp += 3; | ||
91 | cp += 4; | ||
92 | } | ||
93 | gdkpix += stride; | ||
94 | cpix += cstride; | ||
95 | } | ||
96 | } else { | ||
97 | /* premul-color = alpha/255 * color/255 * 255 = (alpha*color)/255 | ||
98 | * (z/255) = z/256 * 256/255 = z/256 (1 + 1/255) | ||
99 | * = z/256 + (z/256)/255 = (z + z/255)/256 | ||
100 | * # recurse once | ||
101 | * = (z + (z + z/255)/256)/256 | ||
102 | * = (z + z/256 + z/256/255) / 256 | ||
103 | * # only use 16bit uint operations, loose some precision, | ||
104 | * # result is floored. | ||
105 | * -> (z + z>>8)>>8 | ||
106 | * # add 0x80/255 = 0.5 to convert floor to round | ||
107 | * => (z+0x80 + (z+0x80)>>8 ) >> 8 | ||
108 | * ------ | ||
109 | * tested as equal to lround(z/255.0) for uint z in [0..0xfe02] | ||
110 | */ | ||
111 | #define PREMUL_ALPHA(x,a,b,z) \ | ||
112 | G_STMT_START { z = a * b + 0x80; x = (z + (z >> 8)) >> 8; } \ | ||
113 | G_STMT_END | ||
114 | int i; | ||
115 | for (i = h; i; --i) { | ||
116 | const guint8 *gp = gdkpix; | ||
117 | unsigned char *cp = cpix; | ||
118 | const guint8* end = gp + 4*w; | ||
119 | guint z1, z2, z3; | ||
120 | while (gp < end) { | ||
121 | #if G_BYTE_ORDER == G_LITTLE_ENDIAN | ||
122 | PREMUL_ALPHA(cp[0], gp[2], gp[3], z1); | ||
123 | PREMUL_ALPHA(cp[1], gp[1], gp[3], z2); | ||
124 | PREMUL_ALPHA(cp[2], gp[0], gp[3], z3); | ||
125 | cp[3] = gp[3]; | ||
126 | #else | ||
127 | PREMUL_ALPHA(cp[1], gp[0], gp[3], z1); | ||
128 | PREMUL_ALPHA(cp[2], gp[1], gp[3], z2); | ||
129 | PREMUL_ALPHA(cp[3], gp[2], gp[3], z3); | ||
130 | cp[0] = gp[3]; | ||
131 | #endif | ||
132 | gp += 4; | ||
133 | cp += 4; | ||
134 | } | ||
135 | gdkpix += stride; | ||
136 | cpix += cstride; | ||
137 | } | ||
138 | #undef PREMUL_ALPHA | ||
139 | } | ||
140 | cairo_surface_mark_dirty(cs); | ||
141 | return cs; | ||
142 | } | ||
143 | #endif // HAVE_GDK_PIXBUF | ||
diff --git a/include/cairo.h b/include/cairo.h index d1b9b8d7..c1275db2 100644 --- a/include/cairo.h +++ b/include/cairo.h | |||
@@ -1,13 +1,9 @@ | |||
1 | #ifndef _SWAY_CAIRO_H | 1 | #ifndef _SWAY_CAIRO_H |
2 | #define _SWAY_CAIRO_H | 2 | #define _SWAY_CAIRO_H |
3 | |||
4 | #include "config.h" | 3 | #include "config.h" |
5 | #include <stdint.h> | 4 | #include <stdint.h> |
6 | #include <cairo/cairo.h> | 5 | #include <cairo/cairo.h> |
7 | #include <wayland-client-protocol.h> | 6 | #include <wayland-client-protocol.h> |
8 | #if HAVE_GDK_PIXBUF | ||
9 | #include <gdk-pixbuf/gdk-pixbuf.h> | ||
10 | #endif | ||
11 | 7 | ||
12 | void cairo_set_source_u32(cairo_t *cairo, uint32_t color); | 8 | void cairo_set_source_u32(cairo_t *cairo, uint32_t color); |
13 | cairo_subpixel_order_t to_cairo_subpixel_order(enum wl_output_subpixel subpixel); | 9 | cairo_subpixel_order_t to_cairo_subpixel_order(enum wl_output_subpixel subpixel); |
@@ -15,11 +11,4 @@ cairo_subpixel_order_t to_cairo_subpixel_order(enum wl_output_subpixel subpixel) | |||
15 | cairo_surface_t *cairo_image_surface_scale(cairo_surface_t *image, | 11 | cairo_surface_t *cairo_image_surface_scale(cairo_surface_t *image, |
16 | int width, int height); | 12 | int width, int height); |
17 | 13 | ||
18 | #if HAVE_GDK_PIXBUF | ||
19 | |||
20 | cairo_surface_t* gdk_cairo_image_surface_create_from_pixbuf( | ||
21 | const GdkPixbuf *gdkbuf); | ||
22 | |||
23 | #endif // HAVE_GDK_PIXBUF | ||
24 | |||
25 | #endif | 14 | #endif |
diff --git a/meson.build b/meson.build index d2b6e8c0..9937eebe 100644 --- a/meson.build +++ b/meson.build | |||
@@ -107,7 +107,6 @@ if scdoc.found() | |||
107 | 'sway/sway-input.5.scd', | 107 | 'sway/sway-input.5.scd', |
108 | 'sway/sway-ipc.7.scd', | 108 | 'sway/sway-ipc.7.scd', |
109 | 'sway/sway-output.5.scd', | 109 | 'sway/sway-output.5.scd', |
110 | 'swaybg/swaybg.1.scd', | ||
111 | 'swaymsg/swaymsg.1.scd', | 110 | 'swaymsg/swaymsg.1.scd', |
112 | 'swaynag/swaynag.1.scd', | 111 | 'swaynag/swaynag.1.scd', |
113 | 'swaynag/swaynag.5.scd', | 112 | 'swaynag/swaynag.5.scd', |
@@ -151,7 +150,6 @@ subdir('sway') | |||
151 | subdir('swaymsg') | 150 | subdir('swaymsg') |
152 | 151 | ||
153 | subdir('client') | 152 | subdir('client') |
154 | subdir('swaybg') | ||
155 | subdir('swaybar') | 153 | subdir('swaybar') |
156 | subdir('swaynag') | 154 | subdir('swaynag') |
157 | 155 | ||
diff --git a/sway/meson.build b/sway/meson.build index 8254fb5c..0f943a1f 100644 --- a/sway/meson.build +++ b/sway/meson.build | |||
@@ -186,7 +186,6 @@ sway_sources = files( | |||
186 | 186 | ||
187 | sway_deps = [ | 187 | sway_deps = [ |
188 | cairo, | 188 | cairo, |
189 | gdk_pixbuf, | ||
190 | jsonc, | 189 | jsonc, |
191 | libevdev, | 190 | libevdev, |
192 | libinput, | 191 | libinput, |
diff --git a/swaybg/main.c b/swaybg/main.c deleted file mode 100644 index b983dd6a..00000000 --- a/swaybg/main.c +++ /dev/null | |||
@@ -1,542 +0,0 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <assert.h> | ||
3 | #include <ctype.h> | ||
4 | #include <getopt.h> | ||
5 | #include <stdbool.h> | ||
6 | #include <stdio.h> | ||
7 | #include <stdlib.h> | ||
8 | #include <string.h> | ||
9 | #include <strings.h> | ||
10 | #include <wayland-client.h> | ||
11 | #include "background-image.h" | ||
12 | #include "cairo.h" | ||
13 | #include "log.h" | ||
14 | #include "pool-buffer.h" | ||
15 | #include "util.h" | ||
16 | #include "wlr-layer-shell-unstable-v1-client-protocol.h" | ||
17 | #include "xdg-output-unstable-v1-client-protocol.h" | ||
18 | |||
19 | struct swaybg_state { | ||
20 | struct wl_display *display; | ||
21 | struct wl_compositor *compositor; | ||
22 | struct wl_shm *shm; | ||
23 | struct zwlr_layer_shell_v1 *layer_shell; | ||
24 | struct zxdg_output_manager_v1 *xdg_output_manager; | ||
25 | struct wl_list configs; // struct swaybg_output_config::link | ||
26 | struct wl_list outputs; // struct swaybg_output::link | ||
27 | bool run_display; | ||
28 | }; | ||
29 | |||
30 | struct swaybg_output_config { | ||
31 | char *output; | ||
32 | cairo_surface_t *image; | ||
33 | enum background_mode mode; | ||
34 | uint32_t color; | ||
35 | struct wl_list link; | ||
36 | }; | ||
37 | |||
38 | struct swaybg_output { | ||
39 | uint32_t wl_name; | ||
40 | struct wl_output *wl_output; | ||
41 | struct zxdg_output_v1 *xdg_output; | ||
42 | char *name; | ||
43 | char *identifier; | ||
44 | |||
45 | struct swaybg_state *state; | ||
46 | struct swaybg_output_config *config; | ||
47 | |||
48 | struct wl_surface *surface; | ||
49 | struct zwlr_layer_surface_v1 *layer_surface; | ||
50 | struct pool_buffer buffers[2]; | ||
51 | struct pool_buffer *current_buffer; | ||
52 | |||
53 | uint32_t width, height; | ||
54 | int32_t scale; | ||
55 | |||
56 | struct wl_list link; | ||
57 | }; | ||
58 | |||
59 | bool is_valid_color(const char *color) { | ||
60 | int len = strlen(color); | ||
61 | if (len != 7 || color[0] != '#') { | ||
62 | sway_log(SWAY_ERROR, "%s is not a valid color for swaybg. " | ||
63 | "Color should be specified as #rrggbb (no alpha).", color); | ||
64 | return false; | ||
65 | } | ||
66 | |||
67 | int i; | ||
68 | for (i = 1; i < len; ++i) { | ||
69 | if (!isxdigit(color[i])) { | ||
70 | return false; | ||
71 | } | ||
72 | } | ||
73 | |||
74 | return true; | ||
75 | } | ||
76 | |||
77 | static void render_frame(struct swaybg_output *output) { | ||
78 | int buffer_width = output->width * output->scale, | ||
79 | buffer_height = output->height * output->scale; | ||
80 | output->current_buffer = get_next_buffer(output->state->shm, | ||
81 | output->buffers, buffer_width, buffer_height); | ||
82 | if (!output->current_buffer) { | ||
83 | return; | ||
84 | } | ||
85 | cairo_t *cairo = output->current_buffer->cairo; | ||
86 | cairo_save(cairo); | ||
87 | cairo_set_operator(cairo, CAIRO_OPERATOR_CLEAR); | ||
88 | cairo_paint(cairo); | ||
89 | cairo_restore(cairo); | ||
90 | if (output->config->mode == BACKGROUND_MODE_SOLID_COLOR) { | ||
91 | cairo_set_source_u32(cairo, output->config->color); | ||
92 | cairo_paint(cairo); | ||
93 | } else { | ||
94 | if (output->config->color) { | ||
95 | cairo_set_source_u32(cairo, output->config->color); | ||
96 | cairo_paint(cairo); | ||
97 | } | ||
98 | render_background_image(cairo, output->config->image, | ||
99 | output->config->mode, buffer_width, buffer_height); | ||
100 | } | ||
101 | |||
102 | wl_surface_set_buffer_scale(output->surface, output->scale); | ||
103 | wl_surface_attach(output->surface, output->current_buffer->buffer, 0, 0); | ||
104 | wl_surface_damage_buffer(output->surface, 0, 0, INT32_MAX, INT32_MAX); | ||
105 | wl_surface_commit(output->surface); | ||
106 | } | ||
107 | |||
108 | static void destroy_swaybg_output_config(struct swaybg_output_config *config) { | ||
109 | if (!config) { | ||
110 | return; | ||
111 | } | ||
112 | wl_list_remove(&config->link); | ||
113 | free(config->output); | ||
114 | free(config); | ||
115 | } | ||
116 | |||
117 | static void destroy_swaybg_output(struct swaybg_output *output) { | ||
118 | if (!output) { | ||
119 | return; | ||
120 | } | ||
121 | wl_list_remove(&output->link); | ||
122 | if (output->layer_surface != NULL) { | ||
123 | zwlr_layer_surface_v1_destroy(output->layer_surface); | ||
124 | } | ||
125 | if (output->surface != NULL) { | ||
126 | wl_surface_destroy(output->surface); | ||
127 | } | ||
128 | zxdg_output_v1_destroy(output->xdg_output); | ||
129 | wl_output_destroy(output->wl_output); | ||
130 | destroy_buffer(&output->buffers[0]); | ||
131 | destroy_buffer(&output->buffers[1]); | ||
132 | free(output->name); | ||
133 | free(output->identifier); | ||
134 | free(output); | ||
135 | } | ||
136 | |||
137 | static void layer_surface_configure(void *data, | ||
138 | struct zwlr_layer_surface_v1 *surface, | ||
139 | uint32_t serial, uint32_t width, uint32_t height) { | ||
140 | struct swaybg_output *output = data; | ||
141 | output->width = width; | ||
142 | output->height = height; | ||
143 | zwlr_layer_surface_v1_ack_configure(surface, serial); | ||
144 | render_frame(output); | ||
145 | } | ||
146 | |||
147 | static void layer_surface_closed(void *data, | ||
148 | struct zwlr_layer_surface_v1 *surface) { | ||
149 | struct swaybg_output *output = data; | ||
150 | sway_log(SWAY_DEBUG, "Destroying output %s (%s)", | ||
151 | output->name, output->identifier); | ||
152 | destroy_swaybg_output(output); | ||
153 | } | ||
154 | |||
155 | static const struct zwlr_layer_surface_v1_listener layer_surface_listener = { | ||
156 | .configure = layer_surface_configure, | ||
157 | .closed = layer_surface_closed, | ||
158 | }; | ||
159 | |||
160 | static void output_geometry(void *data, struct wl_output *output, int32_t x, | ||
161 | int32_t y, int32_t width_mm, int32_t height_mm, int32_t subpixel, | ||
162 | const char *make, const char *model, int32_t transform) { | ||
163 | // Who cares | ||
164 | } | ||
165 | |||
166 | static void output_mode(void *data, struct wl_output *output, uint32_t flags, | ||
167 | int32_t width, int32_t height, int32_t refresh) { | ||
168 | // Who cares | ||
169 | } | ||
170 | |||
171 | static void output_done(void *data, struct wl_output *output) { | ||
172 | // Who cares | ||
173 | } | ||
174 | |||
175 | static void output_scale(void *data, struct wl_output *wl_output, | ||
176 | int32_t scale) { | ||
177 | struct swaybg_output *output = data; | ||
178 | output->scale = scale; | ||
179 | if (output->state->run_display && output->width > 0 && output->height > 0) { | ||
180 | render_frame(output); | ||
181 | } | ||
182 | } | ||
183 | |||
184 | static const struct wl_output_listener output_listener = { | ||
185 | .geometry = output_geometry, | ||
186 | .mode = output_mode, | ||
187 | .done = output_done, | ||
188 | .scale = output_scale, | ||
189 | }; | ||
190 | |||
191 | static void xdg_output_handle_logical_position(void *data, | ||
192 | struct zxdg_output_v1 *xdg_output, int32_t x, int32_t y) { | ||
193 | // Who cares | ||
194 | } | ||
195 | |||
196 | static void xdg_output_handle_logical_size(void *data, | ||
197 | struct zxdg_output_v1 *xdg_output, int32_t width, int32_t height) { | ||
198 | // Who cares | ||
199 | } | ||
200 | |||
201 | static void find_config(struct swaybg_output *output, const char *name) { | ||
202 | struct swaybg_output_config *config = NULL; | ||
203 | wl_list_for_each(config, &output->state->configs, link) { | ||
204 | if (strcmp(config->output, name) == 0) { | ||
205 | output->config = config; | ||
206 | return; | ||
207 | } else if (!output->config && strcmp(config->output, "*") == 0) { | ||
208 | output->config = config; | ||
209 | } | ||
210 | } | ||
211 | } | ||
212 | |||
213 | static void xdg_output_handle_name(void *data, | ||
214 | struct zxdg_output_v1 *xdg_output, const char *name) { | ||
215 | struct swaybg_output *output = data; | ||
216 | output->name = strdup(name); | ||
217 | |||
218 | // If description was sent first, the config may already be populated. If | ||
219 | // there is an identifier config set, keep it. | ||
220 | if (!output->config || strcmp(output->config->output, "*") == 0) { | ||
221 | find_config(output, name); | ||
222 | } | ||
223 | } | ||
224 | |||
225 | static void xdg_output_handle_description(void *data, | ||
226 | struct zxdg_output_v1 *xdg_output, const char *description) { | ||
227 | struct swaybg_output *output = data; | ||
228 | |||
229 | // wlroots currently sets the description to `make model serial (name)` | ||
230 | // If this changes in the future, this will need to be modified. | ||
231 | char *paren = strrchr(description, '('); | ||
232 | if (paren) { | ||
233 | size_t length = paren - description; | ||
234 | output->identifier = malloc(length); | ||
235 | if (!output->identifier) { | ||
236 | sway_log(SWAY_ERROR, "Failed to allocate output identifier"); | ||
237 | return; | ||
238 | } | ||
239 | strncpy(output->identifier, description, length); | ||
240 | output->identifier[length - 1] = '\0'; | ||
241 | |||
242 | find_config(output, output->identifier); | ||
243 | } | ||
244 | } | ||
245 | |||
246 | static void create_layer_surface(struct swaybg_output *output) { | ||
247 | output->surface = wl_compositor_create_surface(output->state->compositor); | ||
248 | assert(output->surface); | ||
249 | |||
250 | // Empty input region | ||
251 | struct wl_region *input_region = | ||
252 | wl_compositor_create_region(output->state->compositor); | ||
253 | assert(input_region); | ||
254 | wl_surface_set_input_region(output->surface, input_region); | ||
255 | wl_region_destroy(input_region); | ||
256 | |||
257 | output->layer_surface = zwlr_layer_shell_v1_get_layer_surface( | ||
258 | output->state->layer_shell, output->surface, output->wl_output, | ||
259 | ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND, "wallpaper"); | ||
260 | assert(output->layer_surface); | ||
261 | |||
262 | zwlr_layer_surface_v1_set_size(output->layer_surface, 0, 0); | ||
263 | zwlr_layer_surface_v1_set_anchor(output->layer_surface, | ||
264 | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | | ||
265 | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | | ||
266 | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | | ||
267 | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT); | ||
268 | zwlr_layer_surface_v1_set_exclusive_zone(output->layer_surface, -1); | ||
269 | zwlr_layer_surface_v1_add_listener(output->layer_surface, | ||
270 | &layer_surface_listener, output); | ||
271 | wl_surface_commit(output->surface); | ||
272 | } | ||
273 | |||
274 | static void xdg_output_handle_done(void *data, | ||
275 | struct zxdg_output_v1 *xdg_output) { | ||
276 | struct swaybg_output *output = data; | ||
277 | if (!output->config) { | ||
278 | sway_log(SWAY_DEBUG, "Could not find config for output %s (%s)", | ||
279 | output->name, output->identifier); | ||
280 | destroy_swaybg_output(output); | ||
281 | } else if (!output->layer_surface) { | ||
282 | sway_log(SWAY_DEBUG, "Found config %s for output %s (%s)", | ||
283 | output->config->output, output->name, output->identifier); | ||
284 | create_layer_surface(output); | ||
285 | } | ||
286 | } | ||
287 | |||
288 | static const struct zxdg_output_v1_listener xdg_output_listener = { | ||
289 | .logical_position = xdg_output_handle_logical_position, | ||
290 | .logical_size = xdg_output_handle_logical_size, | ||
291 | .name = xdg_output_handle_name, | ||
292 | .description = xdg_output_handle_description, | ||
293 | .done = xdg_output_handle_done, | ||
294 | }; | ||
295 | |||
296 | static void handle_global(void *data, struct wl_registry *registry, | ||
297 | uint32_t name, const char *interface, uint32_t version) { | ||
298 | struct swaybg_state *state = data; | ||
299 | if (strcmp(interface, wl_compositor_interface.name) == 0) { | ||
300 | state->compositor = | ||
301 | wl_registry_bind(registry, name, &wl_compositor_interface, 4); | ||
302 | } else if (strcmp(interface, wl_shm_interface.name) == 0) { | ||
303 | state->shm = wl_registry_bind(registry, name, &wl_shm_interface, 1); | ||
304 | } else if (strcmp(interface, wl_output_interface.name) == 0) { | ||
305 | struct swaybg_output *output = calloc(1, sizeof(struct swaybg_output)); | ||
306 | output->state = state; | ||
307 | output->wl_name = name; | ||
308 | output->wl_output = | ||
309 | wl_registry_bind(registry, name, &wl_output_interface, 3); | ||
310 | wl_output_add_listener(output->wl_output, &output_listener, output); | ||
311 | wl_list_insert(&state->outputs, &output->link); | ||
312 | |||
313 | if (state->run_display) { | ||
314 | output->xdg_output = zxdg_output_manager_v1_get_xdg_output( | ||
315 | state->xdg_output_manager, output->wl_output); | ||
316 | zxdg_output_v1_add_listener(output->xdg_output, | ||
317 | &xdg_output_listener, output); | ||
318 | } | ||
319 | } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) { | ||
320 | state->layer_shell = | ||
321 | wl_registry_bind(registry, name, &zwlr_layer_shell_v1_interface, 1); | ||
322 | } else if (strcmp(interface, zxdg_output_manager_v1_interface.name) == 0) { | ||
323 | state->xdg_output_manager = wl_registry_bind(registry, name, | ||
324 | &zxdg_output_manager_v1_interface, 2); | ||
325 | } | ||
326 | } | ||
327 | |||
328 | static void handle_global_remove(void *data, struct wl_registry *registry, | ||
329 | uint32_t name) { | ||
330 | struct swaybg_state *state = data; | ||
331 | struct swaybg_output *output, *tmp; | ||
332 | wl_list_for_each_safe(output, tmp, &state->outputs, link) { | ||
333 | if (output->wl_name == name) { | ||
334 | sway_log(SWAY_DEBUG, "Destroying output %s (%s)", | ||
335 | output->name, output->identifier); | ||
336 | destroy_swaybg_output(output); | ||
337 | break; | ||
338 | } | ||
339 | } | ||
340 | } | ||
341 | |||
342 | static const struct wl_registry_listener registry_listener = { | ||
343 | .global = handle_global, | ||
344 | .global_remove = handle_global_remove, | ||
345 | }; | ||
346 | |||
347 | static bool store_swaybg_output_config(struct swaybg_state *state, | ||
348 | struct swaybg_output_config *config) { | ||
349 | struct swaybg_output_config *oc = NULL; | ||
350 | wl_list_for_each(oc, &state->configs, link) { | ||
351 | if (strcmp(config->output, oc->output) == 0) { | ||
352 | // Merge on top | ||
353 | if (config->image) { | ||
354 | free(oc->image); | ||
355 | oc->image = config->image; | ||
356 | config->image = NULL; | ||
357 | } | ||
358 | if (config->color) { | ||
359 | oc->color = config->color; | ||
360 | } | ||
361 | if (config->mode != BACKGROUND_MODE_INVALID) { | ||
362 | oc->mode = config->mode; | ||
363 | } | ||
364 | return false; | ||
365 | } | ||
366 | } | ||
367 | // New config, just add it | ||
368 | wl_list_insert(&state->configs, &config->link); | ||
369 | return true; | ||
370 | } | ||
371 | |||
372 | static void parse_command_line(int argc, char **argv, | ||
373 | struct swaybg_state *state) { | ||
374 | static struct option long_options[] = { | ||
375 | {"color", required_argument, NULL, 'c'}, | ||
376 | {"help", no_argument, NULL, 'h'}, | ||
377 | {"image", required_argument, NULL, 'i'}, | ||
378 | {"mode", required_argument, NULL, 'm'}, | ||
379 | {"output", required_argument, NULL, 'o'}, | ||
380 | {"version", no_argument, NULL, 'v'}, | ||
381 | {0, 0, 0, 0} | ||
382 | }; | ||
383 | |||
384 | const char *usage = | ||
385 | "Usage: swaybg <options...>\n" | ||
386 | "\n" | ||
387 | " -c, --color Set the background color.\n" | ||
388 | " -h, --help Show help message and quit.\n" | ||
389 | " -i, --image Set the image to display.\n" | ||
390 | " -m, --mode Set the mode to use for the image.\n" | ||
391 | " -o, --output Set the output to operate on or * for all.\n" | ||
392 | " -v, --version Show the version number and quit.\n" | ||
393 | "\n" | ||
394 | "Background Modes:\n" | ||
395 | " stretch, fit, fill, center, tile, or solid_color\n"; | ||
396 | |||
397 | struct swaybg_output_config *config = NULL; | ||
398 | |||
399 | int c; | ||
400 | while (1) { | ||
401 | int option_index = 0; | ||
402 | c = getopt_long(argc, argv, "c:hi:m:o:v", long_options, &option_index); | ||
403 | if (c == -1) { | ||
404 | break; | ||
405 | } | ||
406 | switch (c) { | ||
407 | case 'c': // color | ||
408 | if (!config) { | ||
409 | goto no_output; | ||
410 | } | ||
411 | if (!is_valid_color(optarg)) { | ||
412 | sway_log(SWAY_ERROR, "Invalid color: %s", optarg); | ||
413 | continue; | ||
414 | } | ||
415 | config->color = parse_color(optarg); | ||
416 | break; | ||
417 | case 'i': // image | ||
418 | if (!config) { | ||
419 | goto no_output; | ||
420 | } | ||
421 | free(config->image); | ||
422 | config->image = load_background_image(optarg); | ||
423 | if (!config->image) { | ||
424 | sway_log(SWAY_ERROR, "Failed to load image: %s", optarg); | ||
425 | } | ||
426 | break; | ||
427 | case 'm': // mode | ||
428 | if (!config) { | ||
429 | goto no_output; | ||
430 | } | ||
431 | config->mode = parse_background_mode(optarg); | ||
432 | if (config->mode == BACKGROUND_MODE_INVALID) { | ||
433 | sway_log(SWAY_ERROR, "Invalid mode: %s", optarg); | ||
434 | } | ||
435 | break; | ||
436 | case 'o': // output | ||
437 | if (config && !store_swaybg_output_config(state, config)) { | ||
438 | // Empty config or merged on top of an existing one | ||
439 | destroy_swaybg_output_config(config); | ||
440 | } | ||
441 | config = calloc(sizeof(struct swaybg_output_config), 1); | ||
442 | config->output = strdup(optarg); | ||
443 | config->mode = BACKGROUND_MODE_INVALID; | ||
444 | wl_list_init(&config->link); // init for safe removal | ||
445 | break; | ||
446 | case 'v': // version | ||
447 | fprintf(stdout, "swaybg version " SWAY_VERSION "\n"); | ||
448 | exit(EXIT_SUCCESS); | ||
449 | break; | ||
450 | default: | ||
451 | fprintf(c == 'h' ? stdout : stderr, "%s", usage); | ||
452 | exit(c == 'h' ? EXIT_SUCCESS : EXIT_FAILURE); | ||
453 | } | ||
454 | } | ||
455 | if (config && !store_swaybg_output_config(state, config)) { | ||
456 | // Empty config or merged on top of an existing one | ||
457 | destroy_swaybg_output_config(config); | ||
458 | } | ||
459 | |||
460 | // Check for invalid options | ||
461 | if (optind < argc) { | ||
462 | config = NULL; | ||
463 | struct swaybg_output_config *tmp = NULL; | ||
464 | wl_list_for_each_safe(config, tmp, &state->configs, link) { | ||
465 | destroy_swaybg_output_config(config); | ||
466 | } | ||
467 | // continue into empty list | ||
468 | } | ||
469 | if (wl_list_empty(&state->configs)) { | ||
470 | fprintf(stderr, "%s", usage); | ||
471 | exit(EXIT_FAILURE); | ||
472 | } | ||
473 | |||
474 | // Set default mode and remove empties | ||
475 | config = NULL; | ||
476 | struct swaybg_output_config *tmp = NULL; | ||
477 | wl_list_for_each_safe(config, tmp, &state->configs, link) { | ||
478 | if (!config->image && !config->color) { | ||
479 | destroy_swaybg_output_config(config); | ||
480 | } else if (config->mode == BACKGROUND_MODE_INVALID) { | ||
481 | config->mode = config->image | ||
482 | ? BACKGROUND_MODE_STRETCH | ||
483 | : BACKGROUND_MODE_SOLID_COLOR; | ||
484 | } | ||
485 | } | ||
486 | return; | ||
487 | no_output: | ||
488 | fprintf(stderr, "Cannot operate on NULL output config\n"); | ||
489 | exit(EXIT_FAILURE); | ||
490 | } | ||
491 | |||
492 | int main(int argc, char **argv) { | ||
493 | sway_log_init(SWAY_DEBUG, NULL); | ||
494 | |||
495 | struct swaybg_state state = {0}; | ||
496 | wl_list_init(&state.configs); | ||
497 | wl_list_init(&state.outputs); | ||
498 | |||
499 | parse_command_line(argc, argv, &state); | ||
500 | |||
501 | state.display = wl_display_connect(NULL); | ||
502 | if (!state.display) { | ||
503 | sway_log(SWAY_ERROR, "Unable to connect to the compositor. " | ||
504 | "If your compositor is running, check or set the " | ||
505 | "WAYLAND_DISPLAY environment variable."); | ||
506 | return 1; | ||
507 | } | ||
508 | |||
509 | struct wl_registry *registry = wl_display_get_registry(state.display); | ||
510 | wl_registry_add_listener(registry, ®istry_listener, &state); | ||
511 | wl_display_roundtrip(state.display); | ||
512 | if (state.compositor == NULL || state.shm == NULL || | ||
513 | state.layer_shell == NULL || state.xdg_output_manager == NULL) { | ||
514 | sway_log(SWAY_ERROR, "Missing a required Wayland interface"); | ||
515 | return 1; | ||
516 | } | ||
517 | |||
518 | struct swaybg_output *output; | ||
519 | wl_list_for_each(output, &state.outputs, link) { | ||
520 | output->xdg_output = zxdg_output_manager_v1_get_xdg_output( | ||
521 | state.xdg_output_manager, output->wl_output); | ||
522 | zxdg_output_v1_add_listener(output->xdg_output, | ||
523 | &xdg_output_listener, output); | ||
524 | } | ||
525 | |||
526 | state.run_display = true; | ||
527 | while (wl_display_dispatch(state.display) != -1 && state.run_display) { | ||
528 | // This space intentionally left blank | ||
529 | } | ||
530 | |||
531 | struct swaybg_output *tmp_output; | ||
532 | wl_list_for_each_safe(output, tmp_output, &state.outputs, link) { | ||
533 | destroy_swaybg_output(output); | ||
534 | } | ||
535 | |||
536 | struct swaybg_output_config *config = NULL, *tmp_config = NULL; | ||
537 | wl_list_for_each_safe(config, tmp_config, &state.configs, link) { | ||
538 | destroy_swaybg_output_config(config); | ||
539 | } | ||
540 | |||
541 | return 0; | ||
542 | } | ||
diff --git a/swaybg/meson.build b/swaybg/meson.build deleted file mode 100644 index 2b93da47..00000000 --- a/swaybg/meson.build +++ /dev/null | |||
@@ -1,16 +0,0 @@ | |||
1 | executable( | ||
2 | 'swaybg', | ||
3 | 'main.c', | ||
4 | include_directories: [sway_inc], | ||
5 | dependencies: [ | ||
6 | cairo, | ||
7 | client_protos, | ||
8 | gdk_pixbuf, | ||
9 | jsonc, | ||
10 | pango, | ||
11 | pangocairo, | ||
12 | wayland_client | ||
13 | ], | ||
14 | link_with: [lib_sway_common, lib_sway_client], | ||
15 | install: true | ||
16 | ) | ||
diff --git a/swaybg/swaybg.1.scd b/swaybg/swaybg.1.scd deleted file mode 100644 index 027e5d63..00000000 --- a/swaybg/swaybg.1.scd +++ /dev/null | |||
@@ -1,44 +0,0 @@ | |||
1 | swaybg(1) | ||
2 | |||
3 | # NAME | ||
4 | |||
5 | swaybg - Background for Wayland | ||
6 | |||
7 | # SYNOPSIS | ||
8 | |||
9 | *swaybg* [options...] | ||
10 | |||
11 | Displays a background image on all outputs of your Wayland session. | ||
12 | |||
13 | Without an output specified, appearance options apply to all outputs. | ||
14 | Per-output appearance options can be set by passing _-o, --output_ followed by | ||
15 | these options. | ||
16 | |||
17 | # OPTIONS | ||
18 | |||
19 | *-c, --color* <rrggbb[aa]> | ||
20 | Set the background color. | ||
21 | |||
22 | *-h, --help* | ||
23 | Show help message and quit. | ||
24 | |||
25 | *-i, --image* <path> | ||
26 | Set the background image. | ||
27 | |||
28 | *-m, --mode* <mode> | ||
29 | Scaling mode for images: _stretch_, _fill_, _fit_, _center_, or _tile_. Use | ||
30 | the additional mode _solid\_color_ to display only the background color, | ||
31 | even if a background image is specified. | ||
32 | |||
33 | *-o, --output* <name> | ||
34 | Select an output to configure. Subsequent appearance options will only | ||
35 | apply to this output. The special value _\*_ selects all outputs. | ||
36 | |||
37 | *-v, --version* | ||
38 | Show the version number and quit. | ||
39 | |||
40 | # AUTHORS | ||
41 | |||
42 | Maintained by Drew DeVault <sir@cmpwn.com>, who is assisted by other open | ||
43 | source contributors. For more information about swaybg development, see | ||
44 | https://github.com/swaywm/sway. | ||
diff --git a/swaynag/meson.build b/swaynag/meson.build index 9c29fd1a..71f2fc2d 100644 --- a/swaynag/meson.build +++ b/swaynag/meson.build | |||
@@ -10,7 +10,6 @@ executable( | |||
10 | dependencies: [ | 10 | dependencies: [ |
11 | cairo, | 11 | cairo, |
12 | client_protos, | 12 | client_protos, |
13 | gdk_pixbuf, | ||
14 | pango, | 13 | pango, |
15 | pangocairo, | 14 | pangocairo, |
16 | wayland_client, | 15 | wayland_client, |