diff options
-rw-r--r-- | client/pool-buffer.c | 46 | ||||
-rw-r--r-- | include/pool-buffer.h | 2 |
2 files changed, 37 insertions, 11 deletions
diff --git a/client/pool-buffer.c b/client/pool-buffer.c index 1f54a77c..52438303 100644 --- a/client/pool-buffer.c +++ b/client/pool-buffer.c | |||
@@ -1,37 +1,56 @@ | |||
1 | #define _XOPEN_SOURCE 500 | 1 | #define _XOPEN_SOURCE 500 |
2 | #include <assert.h> | 2 | #include <assert.h> |
3 | #include <cairo/cairo.h> | 3 | #include <cairo/cairo.h> |
4 | #include <fcntl.h> | ||
5 | #include <pango/pangocairo.h> | ||
4 | #include <stdio.h> | 6 | #include <stdio.h> |
5 | #include <stdlib.h> | 7 | #include <stdlib.h> |
6 | #include <string.h> | 8 | #include <string.h> |
7 | #include <sys/mman.h> | 9 | #include <sys/mman.h> |
8 | #include <pango/pangocairo.h> | ||
9 | #include <unistd.h> | 10 | #include <unistd.h> |
10 | #include <wayland-client.h> | 11 | #include <wayland-client.h> |
11 | #include "config.h" | 12 | #include "config.h" |
12 | #include "pool-buffer.h" | 13 | #include "pool-buffer.h" |
13 | 14 | ||
15 | static bool set_cloexec(int fd) { | ||
16 | long flags = fcntl(fd, F_GETFD); | ||
17 | if (flags == -1) { | ||
18 | return false; | ||
19 | } | ||
20 | |||
21 | if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) { | ||
22 | return false; | ||
23 | } | ||
24 | |||
25 | return true; | ||
26 | } | ||
27 | |||
14 | static int create_pool_file(size_t size, char **name) { | 28 | static int create_pool_file(size_t size, char **name) { |
15 | static const char template[] = "sway-client-XXXXXX"; | 29 | static const char template[] = "sway-client-XXXXXX"; |
16 | const char *path = getenv("XDG_RUNTIME_DIR"); | 30 | const char *path = getenv("XDG_RUNTIME_DIR"); |
17 | if (!path) { | 31 | if (path == NULL) { |
32 | fprintf(stderr, "XDG_RUNTIME_DIR is not set\n"); | ||
18 | return -1; | 33 | return -1; |
19 | } | 34 | } |
20 | 35 | ||
21 | int ts = (path[strlen(path) - 1] == '/'); | 36 | size_t name_size = strlen(template) + 1 + strlen(path) + 1; |
22 | 37 | *name = malloc(name_size); | |
23 | *name = malloc( | 38 | if (*name == NULL) { |
24 | strlen(template) + | 39 | fprintf(stderr, "allocation failed\n"); |
25 | strlen(path) + | 40 | return -1; |
26 | (ts ? 0 : 1) + 1); | 41 | } |
27 | sprintf(*name, "%s%s%s", path, ts ? "" : "/", template); | 42 | snprintf(*name, name_size, "%s/%s", path, template); |
28 | 43 | ||
29 | int fd = mkstemp(*name); | 44 | int fd = mkstemp(*name); |
30 | |||
31 | if (fd < 0) { | 45 | if (fd < 0) { |
32 | return -1; | 46 | return -1; |
33 | } | 47 | } |
34 | 48 | ||
49 | if (!set_cloexec(fd)) { | ||
50 | close(fd); | ||
51 | return -1; | ||
52 | } | ||
53 | |||
35 | if (ftruncate(fd, size) < 0) { | 54 | if (ftruncate(fd, size) < 0) { |
36 | close(fd); | 55 | close(fd); |
37 | return -1; | 56 | return -1; |
@@ -53,7 +72,7 @@ static struct pool_buffer *create_buffer(struct wl_shm *shm, | |||
53 | struct pool_buffer *buf, int32_t width, int32_t height, | 72 | struct pool_buffer *buf, int32_t width, int32_t height, |
54 | uint32_t format) { | 73 | uint32_t format) { |
55 | uint32_t stride = width * 4; | 74 | uint32_t stride = width * 4; |
56 | uint32_t size = stride * height; | 75 | size_t size = stride * height; |
57 | 76 | ||
58 | char *name; | 77 | char *name; |
59 | int fd = create_pool_file(size, &name); | 78 | int fd = create_pool_file(size, &name); |
@@ -68,8 +87,10 @@ static struct pool_buffer *create_buffer(struct wl_shm *shm, | |||
68 | free(name); | 87 | free(name); |
69 | fd = -1; | 88 | fd = -1; |
70 | 89 | ||
90 | buf->size = size; | ||
71 | buf->width = width; | 91 | buf->width = width; |
72 | buf->height = height; | 92 | buf->height = height; |
93 | buf->data = data; | ||
73 | buf->surface = cairo_image_surface_create_for_data(data, | 94 | buf->surface = cairo_image_surface_create_for_data(data, |
74 | CAIRO_FORMAT_ARGB32, width, height, stride); | 95 | CAIRO_FORMAT_ARGB32, width, height, stride); |
75 | buf->cairo = cairo_create(buf->surface); | 96 | buf->cairo = cairo_create(buf->surface); |
@@ -92,6 +113,9 @@ void destroy_buffer(struct pool_buffer *buffer) { | |||
92 | if (buffer->pango) { | 113 | if (buffer->pango) { |
93 | g_object_unref(buffer->pango); | 114 | g_object_unref(buffer->pango); |
94 | } | 115 | } |
116 | if (buffer->data) { | ||
117 | munmap(buffer->data, buffer->size); | ||
118 | } | ||
95 | memset(buffer, 0, sizeof(struct pool_buffer)); | 119 | memset(buffer, 0, sizeof(struct pool_buffer)); |
96 | } | 120 | } |
97 | 121 | ||
diff --git a/include/pool-buffer.h b/include/pool-buffer.h index 856f7c8c..54f5be06 100644 --- a/include/pool-buffer.h +++ b/include/pool-buffer.h | |||
@@ -12,6 +12,8 @@ struct pool_buffer { | |||
12 | cairo_t *cairo; | 12 | cairo_t *cairo; |
13 | PangoContext *pango; | 13 | PangoContext *pango; |
14 | uint32_t width, height; | 14 | uint32_t width, height; |
15 | void *data; | ||
16 | size_t size; | ||
15 | bool busy; | 17 | bool busy; |
16 | }; | 18 | }; |
17 | 19 | ||