summaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2018-03-27 15:25:25 -0400
committerLibravatar Drew DeVault <sir@cmpwn.com>2018-03-28 14:25:19 -0400
commit632bb948b7ffbb08a6e965dabf88347afd0a1fa8 (patch)
treecbd9d4e4e3a7c605d2b0a5e3e66ce35554a74c4b /client
parentAdd client protocols and swaybg skeleton (diff)
downloadsway-632bb948b7ffbb08a6e965dabf88347afd0a1fa8.tar.gz
sway-632bb948b7ffbb08a6e965dabf88347afd0a1fa8.tar.zst
sway-632bb948b7ffbb08a6e965dabf88347afd0a1fa8.zip
Add solid-color rendering to swaybg
Diffstat (limited to 'client')
-rw-r--r--client/buffer-pool.c123
-rw-r--r--client/meson.build21
2 files changed, 144 insertions, 0 deletions
diff --git a/client/buffer-pool.c b/client/buffer-pool.c
new file mode 100644
index 00000000..26d0f7e5
--- /dev/null
+++ b/client/buffer-pool.c
@@ -0,0 +1,123 @@
1#define _XOPEN_SOURCE 500
2#include <assert.h>
3#include <cairo/cairo.h>
4#include <stdio.h>
5#include <stdlib.h>
6#include <string.h>
7#include <sys/mman.h>
8#include <pango/pangocairo.h>
9#include <unistd.h>
10#include <wayland-client.h>
11#include "buffer_pool.h"
12
13static int create_pool_file(size_t size, char **name) {
14 static const char template[] = "sway-client-XXXXXX";
15 const char *path = getenv("XDG_RUNTIME_DIR");
16 if (!path) {
17 return -1;
18 }
19
20 int ts = (path[strlen(path) - 1] == '/');
21
22 *name = malloc(
23 strlen(template) +
24 strlen(path) +
25 (ts ? 0 : 1) + 1);
26 sprintf(*name, "%s%s%s", path, ts ? "" : "/", template);
27
28 int fd = mkstemp(*name);
29
30 if (fd < 0) {
31 return -1;
32 }
33
34 if (ftruncate(fd, size) < 0) {
35 close(fd);
36 return -1;
37 }
38
39 return fd;
40}
41
42static void buffer_release(void *data, struct wl_buffer *wl_buffer) {
43 struct pool_buffer *buffer = data;
44 buffer->busy = false;
45}
46
47static const struct wl_buffer_listener buffer_listener = {
48 .release = buffer_release
49};
50
51static struct pool_buffer *create_buffer(struct wl_shm *shm,
52 struct pool_buffer *buf, int32_t width, int32_t height,
53 uint32_t format) {
54 uint32_t stride = width * 4;
55 uint32_t size = stride * height;
56
57 char *name;
58 int fd = create_pool_file(size, &name);
59 assert(fd);
60 void *data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
61 struct wl_shm_pool *pool = wl_shm_create_pool(shm, fd, size);
62 buf->buffer = wl_shm_pool_create_buffer(pool, 0,
63 width, height, stride, format);
64 wl_shm_pool_destroy(pool);
65 close(fd);
66 unlink(name);
67 free(name);
68 fd = -1;
69
70 buf->width = width;
71 buf->height = height;
72 buf->surface = cairo_image_surface_create_for_data(data,
73 CAIRO_FORMAT_ARGB32, width, height, stride);
74 buf->cairo = cairo_create(buf->surface);
75 buf->pango = pango_cairo_create_context(buf->cairo);
76
77 wl_buffer_add_listener(buf->buffer, &buffer_listener, buf);
78 return buf;
79}
80
81static void destroy_buffer(struct pool_buffer *buffer) {
82 if (buffer->buffer) {
83 wl_buffer_destroy(buffer->buffer);
84 }
85 if (buffer->cairo) {
86 cairo_destroy(buffer->cairo);
87 }
88 if (buffer->surface) {
89 cairo_surface_destroy(buffer->surface);
90 }
91 if (buffer->pango) {
92 g_object_unref(buffer->pango);
93 }
94 memset(buffer, 0, sizeof(struct pool_buffer));
95}
96
97struct pool_buffer *get_next_buffer(struct wl_shm *shm,
98 struct pool_buffer pool[static 2], uint32_t width, uint32_t height) {
99 struct pool_buffer *buffer = NULL;
100
101 for (size_t i = 0; i < 2; ++i) {
102 if (pool[i].busy) {
103 continue;
104 }
105 buffer = &pool[i];
106 }
107
108 if (!buffer) {
109 return NULL;
110 }
111
112 if (buffer->width != width || buffer->height != height) {
113 destroy_buffer(buffer);
114 }
115
116 if (!buffer->buffer) {
117 if (!create_buffer(shm, buffer, width, height,
118 WL_SHM_FORMAT_ARGB8888)) {
119 return NULL;
120 }
121 }
122 return buffer;
123}
diff --git a/client/meson.build b/client/meson.build
new file mode 100644
index 00000000..597899ce
--- /dev/null
+++ b/client/meson.build
@@ -0,0 +1,21 @@
1deps = [
2 cairo,
3 pango,
4 pangocairo,
5 wlroots,
6 wayland_client,
7]
8
9if gdk_pixbuf.found()
10 deps += [gdk_pixbuf]
11endif
12
13lib_sway_client = static_library(
14 'sway-client',
15 files(
16 'buffer-pool.c',
17 ),
18 dependencies: deps,
19 link_with: [lib_sway_common],
20 include_directories: sway_inc
21)