aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2018-03-27 15:37:24 -0400
committerLibravatar Drew DeVault <sir@cmpwn.com>2018-03-28 14:25:19 -0400
commite9922ec52496068e0976d77ba52e5b9c0d074ce1 (patch)
treef8aac2ec0e51266923cb1938018580ce851cebf2
parentFix style (diff)
downloadsway-e9922ec52496068e0976d77ba52e5b9c0d074ce1.tar.gz
sway-e9922ec52496068e0976d77ba52e5b9c0d074ce1.tar.zst
sway-e9922ec52496068e0976d77ba52e5b9c0d074ce1.zip
Remove obsolete client code
-rw-r--r--include/client/buffer.h8
-rw-r--r--include/client/cairo.h17
-rw-r--r--include/client/pango.h16
-rw-r--r--include/client/registry.h75
-rw-r--r--include/client/window.h67
-rw-r--r--wayland/buffers.c127
-rw-r--r--wayland/cairo.c134
-rw-r--r--wayland/pango.c73
-rw-r--r--wayland/registry.c293
-rw-r--r--wayland/window.c177
10 files changed, 0 insertions, 987 deletions
diff --git a/include/client/buffer.h b/include/client/buffer.h
deleted file mode 100644
index eb9973ed..00000000
--- a/include/client/buffer.h
+++ /dev/null
@@ -1,8 +0,0 @@
1#ifndef _BUFFER_H
2#define _BUFFER_H
3
4#include "client/window.h"
5
6struct buffer *get_next_buffer(struct window *state);
7
8#endif
diff --git a/include/client/cairo.h b/include/client/cairo.h
deleted file mode 100644
index e7ef7c7e..00000000
--- a/include/client/cairo.h
+++ /dev/null
@@ -1,17 +0,0 @@
1#ifndef _SWAY_CAIRO_H
2#define _SWAY_CAIRO_H
3
4#include <stdint.h>
5#include <cairo/cairo.h>
6
7void cairo_set_source_u32(cairo_t *cairo, uint32_t color);
8
9cairo_surface_t *cairo_image_surface_scale(cairo_surface_t *image, int width, int height);
10
11#ifdef WITH_GDK_PIXBUF
12#include <gdk-pixbuf/gdk-pixbuf.h>
13
14cairo_surface_t* gdk_cairo_image_surface_create_from_pixbuf(const GdkPixbuf *gdkbuf);
15#endif //WITH_GDK_PIXBUF
16
17#endif
diff --git a/include/client/pango.h b/include/client/pango.h
deleted file mode 100644
index dd2f53c3..00000000
--- a/include/client/pango.h
+++ /dev/null
@@ -1,16 +0,0 @@
1#ifndef _SWAY_CLIENT_PANGO_H
2#define _SWAY_CLIENT_PANGO_H
3
4#include <cairo/cairo.h>
5#include <pango/pangocairo.h>
6#include <stdarg.h>
7#include <stdbool.h>
8#include <stdint.h>
9
10PangoLayout *get_pango_layout(cairo_t *cairo, const char *font, const char *text,
11 int32_t scale, bool markup);
12void get_text_size(cairo_t *cairo, const char *font, int *width, int *height,
13 int32_t scale, bool markup, const char *fmt, ...);
14void pango_printf(cairo_t *cairo, const char *font, int32_t scale, bool markup, const char *fmt, ...);
15
16#endif
diff --git a/include/client/registry.h b/include/client/registry.h
deleted file mode 100644
index 9dfbd835..00000000
--- a/include/client/registry.h
+++ /dev/null
@@ -1,75 +0,0 @@
1#ifndef _SWAY_CLIENT_REGISTRY_H
2#define _SWAY_CLIENT_REGISTRY_H
3
4#include <wayland-client.h>
5#include <xkbcommon/xkbcommon.h>
6#include "wayland-desktop-shell-client-protocol.h"
7#include "wayland-swaylock-client-protocol.h"
8#include "list.h"
9
10enum mod_bit {
11 MOD_SHIFT = 1<<0,
12 MOD_CAPS = 1<<1,
13 MOD_CTRL = 1<<2,
14 MOD_ALT = 1<<3,
15 MOD_MOD2 = 1<<4,
16 MOD_MOD3 = 1<<5,
17 MOD_LOGO = 1<<6,
18 MOD_MOD5 = 1<<7,
19};
20
21enum mask {
22 MASK_SHIFT,
23 MASK_CAPS,
24 MASK_CTRL,
25 MASK_ALT,
26 MASK_MOD2,
27 MASK_MOD3,
28 MASK_LOGO,
29 MASK_MOD5,
30 MASK_LAST
31};
32
33struct output_state {
34 struct wl_output *output;
35 uint32_t flags;
36 uint32_t width, height;
37 uint32_t scale;
38};
39
40struct xkb {
41 struct xkb_state *state;
42 struct xkb_context *context;
43 struct xkb_keymap *keymap;
44 xkb_mod_mask_t masks[MASK_LAST];
45};
46
47struct input {
48 struct xkb xkb;
49
50 xkb_keysym_t sym;
51 uint32_t code;
52 uint32_t last_code;
53 uint32_t modifiers;
54
55 void (*notify)(enum wl_keyboard_key_state state, xkb_keysym_t sym, uint32_t code, uint32_t codepoint);
56};
57
58struct registry {
59 struct wl_compositor *compositor;
60 struct wl_display *display;
61 struct wl_pointer *pointer;
62 struct wl_keyboard *keyboard;
63 struct wl_seat *seat;
64 struct wl_shell *shell;
65 struct wl_shm *shm;
66 struct desktop_shell *desktop_shell;
67 struct lock *swaylock;
68 struct input *input;
69 list_t *outputs;
70};
71
72struct registry *registry_poll(void);
73void registry_teardown(struct registry *registry);
74
75#endif
diff --git a/include/client/window.h b/include/client/window.h
deleted file mode 100644
index 8af8225c..00000000
--- a/include/client/window.h
+++ /dev/null
@@ -1,67 +0,0 @@
1#ifndef _CLIENT_H
2#define _CLIENT_H
3
4#include <wayland-client.h>
5#include "wayland-desktop-shell-client-protocol.h"
6#include <cairo/cairo.h>
7#include <pango/pangocairo.h>
8#include <stdbool.h>
9#include "list.h"
10#include "client/registry.h"
11
12struct window;
13
14struct buffer {
15 struct wl_buffer *buffer;
16 cairo_surface_t *surface;
17 cairo_t *cairo;
18 PangoContext *pango;
19 uint32_t width, height;
20 bool busy;
21};
22
23struct cursor {
24 struct wl_surface *surface;
25 struct wl_cursor_theme *cursor_theme;
26 struct wl_cursor *cursor;
27 struct wl_pointer *pointer;
28};
29
30enum scroll_direction {
31 SCROLL_UP,
32 SCROLL_DOWN,
33 SCROLL_LEFT,
34 SCROLL_RIGHT,
35};
36
37struct pointer_input {
38 int last_x;
39 int last_y;
40
41 void (*notify_button)(struct window *window, int x, int y, uint32_t button, uint32_t state_w);
42 void (*notify_scroll)(struct window *window, enum scroll_direction direction);
43};
44
45struct window {
46 struct registry *registry;
47 struct buffer buffers[2];
48 struct buffer *buffer;
49 struct wl_surface *surface;
50 struct wl_shell_surface *shell_surface;
51 struct wl_callback *frame_cb;
52 struct cursor cursor;
53 uint32_t width, height;
54 int32_t scale;
55 char *font;
56 cairo_t *cairo;
57 struct pointer_input pointer_input;
58};
59
60struct window *window_setup(struct registry *registry, uint32_t width, uint32_t height,
61 int32_t scale, bool shell_surface);
62void window_teardown(struct window *state);
63int window_prerender(struct window *state);
64int window_render(struct window *state);
65void window_make_shell(struct window *window);
66
67#endif
diff --git a/wayland/buffers.c b/wayland/buffers.c
deleted file mode 100644
index 3b809e6f..00000000
--- a/wayland/buffers.c
+++ /dev/null
@@ -1,127 +0,0 @@
1#define _XOPEN_SOURCE 500
2#include <wayland-client.h>
3#include <cairo/cairo.h>
4#include <pango/pangocairo.h>
5#include <stdlib.h>
6#include <string.h>
7#include <stdio.h>
8#include <unistd.h>
9#include <errno.h>
10#include <sys/mman.h>
11#include "client/buffer.h"
12#include "list.h"
13#include "log.h"
14
15static int create_pool_file(size_t size, char **name) {
16 static const char template[] = "sway-client-XXXXXX";
17 const char *path = getenv("XDG_RUNTIME_DIR");
18 if (!path) {
19 return -1;
20 }
21
22 int ts = (path[strlen(path) - 1] == '/');
23
24 *name = malloc(
25 strlen(template) +
26 strlen(path) +
27 (ts ? 0 : 1) + 1);
28 sprintf(*name, "%s%s%s", path, ts ? "" : "/", template);
29
30 int fd = mkstemp(*name);
31
32 if (fd < 0) {
33 return -1;
34 }
35
36 if (ftruncate(fd, size) < 0) {
37 close(fd);
38 return -1;
39 }
40
41 return fd;
42}
43
44static void buffer_release(void *data, struct wl_buffer *wl_buffer) {
45 struct buffer *buffer = data;
46 buffer->busy = false;
47}
48
49static const struct wl_buffer_listener buffer_listener = {
50 .release = buffer_release
51};
52
53static struct buffer *create_buffer(struct wl_shm *shm, struct buffer *buf,
54 int32_t width, int32_t height, uint32_t format) {
55 uint32_t stride = width * 4;
56 uint32_t size = stride * height;
57
58 char *name;
59 int fd = create_pool_file(size, &name);
60 if (fd == -1) {
61 sway_abort("Unable to allocate buffer");
62 return NULL; // never reached
63 }
64 void *data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
65 struct wl_shm_pool *pool = wl_shm_create_pool(shm, fd, size);
66 buf->buffer = wl_shm_pool_create_buffer(pool, 0,
67 width, height, stride, format);
68 wl_shm_pool_destroy(pool);
69 close(fd);
70 unlink(name);
71 free(name);
72 fd = -1;
73
74 buf->width = width;
75 buf->height = height;
76 buf->surface = cairo_image_surface_create_for_data(data,
77 CAIRO_FORMAT_ARGB32, width, height, stride);
78 buf->cairo = cairo_create(buf->surface);
79 buf->pango = pango_cairo_create_context(buf->cairo);
80
81 wl_buffer_add_listener(buf->buffer, &buffer_listener, buf);
82 return buf;
83}
84
85static void destroy_buffer(struct buffer *buffer) {
86 if (buffer->buffer) {
87 wl_buffer_destroy(buffer->buffer);
88 }
89 if (buffer->cairo) {
90 cairo_destroy(buffer->cairo);
91 }
92 if (buffer->surface) {
93 cairo_surface_destroy(buffer->surface);
94 }
95 if (buffer->pango) {
96 g_object_unref(buffer->pango);
97 }
98 memset(buffer, 0, sizeof(struct buffer));
99}
100
101struct pool_buffer *get_next_buffer(struct wl_shm *shm,
102 struct pool_buffer pool[2], uint32_t width, uint32_t height) {
103 struct buffer *buffer = NULL;
104
105 for (size_t i = 0; i < sizeof(pool) / sizeof(pool[0]); ++i) {
106 if (buffers[i].busy) {
107 continue;
108 }
109 buffer = &buffers[i];
110 }
111
112 if (!buffer) {
113 return NULL;
114 }
115
116 if (buffer->width != width || buffer->height != height) {
117 destroy_buffer(buffer);
118 }
119
120 if (!buffer->buffer) {
121 if (!create_buffer(shm, buffer, width, height,
122 WL_SHM_FORMAT_ARGB8888)) {
123 return NULL;
124 }
125 }
126 return buffer;
127}
diff --git a/wayland/cairo.c b/wayland/cairo.c
deleted file mode 100644
index 193205b1..00000000
--- a/wayland/cairo.c
+++ /dev/null
@@ -1,134 +0,0 @@
1#include "client/cairo.h"
2
3void cairo_set_source_u32(cairo_t *cairo, uint32_t color) {
4 cairo_set_source_rgba(cairo,
5 (color >> (3*8) & 0xFF) / 255.0,
6 (color >> (2*8) & 0xFF) / 255.0,
7 (color >> (1*8) & 0xFF) / 255.0,
8 (color >> (0*8) & 0xFF) / 255.0);
9}
10
11cairo_surface_t *cairo_image_surface_scale(cairo_surface_t *image, int width, int height) {
12 int image_width = cairo_image_surface_get_width(image);
13 int image_height = cairo_image_surface_get_height(image);
14
15 cairo_surface_t *new =
16 cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
17
18 cairo_t *cairo = cairo_create(new);
19
20 cairo_scale(cairo, (double) width / image_width, (double) height / image_height);
21
22 cairo_set_source_surface(cairo, image, 0, 0);
23 cairo_paint(cairo);
24
25 cairo_destroy(cairo);
26
27 return new;
28}
29
30#ifdef WITH_GDK_PIXBUF
31#include <gdk-pixbuf/gdk-pixbuf.h>
32
33#ifndef GDK_PIXBUF_CHECK_VERSION
34#define GDK_PIXBUF_CHECK_VERSION(major,minor,micro) \
35 (GDK_PIXBUF_MAJOR > (major) || \
36 (GDK_PIXBUF_MAJOR == (major) && GDK_PIXBUF_MINOR > (minor)) || \
37 (GDK_PIXBUF_MAJOR == (major) && GDK_PIXBUF_MINOR == (minor) && \
38 GDK_PIXBUF_MICRO >= (micro)))
39#endif
40
41cairo_surface_t* gdk_cairo_image_surface_create_from_pixbuf(const GdkPixbuf *gdkbuf) {
42 int chan = gdk_pixbuf_get_n_channels(gdkbuf);
43 if (chan < 3) return NULL;
44
45#if GDK_PIXBUF_CHECK_VERSION(2,32,0)
46 const guint8* gdkpix = gdk_pixbuf_read_pixels(gdkbuf);
47#else
48 const guint8* gdkpix = gdk_pixbuf_get_pixels(gdkbuf);
49#endif
50 if (!gdkpix) {
51 return NULL;
52 }
53 gint w = gdk_pixbuf_get_width(gdkbuf);
54 gint h = gdk_pixbuf_get_height(gdkbuf);
55 int stride = gdk_pixbuf_get_rowstride(gdkbuf);
56
57 cairo_format_t fmt = (chan == 3) ? CAIRO_FORMAT_RGB24 : CAIRO_FORMAT_ARGB32;
58 cairo_surface_t * cs = cairo_image_surface_create (fmt, w, h);
59 cairo_surface_flush (cs);
60 if ( !cs || cairo_surface_status(cs) != CAIRO_STATUS_SUCCESS) {
61 return NULL;
62 }
63
64 int cstride = cairo_image_surface_get_stride(cs);
65 unsigned char * cpix = cairo_image_surface_get_data(cs);
66
67 if (chan == 3) {
68 int i;
69 for (i = h; i; --i) {
70 const guint8 *gp = gdkpix;
71 unsigned char *cp = cpix;
72 const guint8* end = gp + 3*w;
73 while (gp < end) {
74#if G_BYTE_ORDER == G_LITTLE_ENDIAN
75 cp[0] = gp[2];
76 cp[1] = gp[1];
77 cp[2] = gp[0];
78#else
79 cp[1] = gp[0];
80 cp[2] = gp[1];
81 cp[3] = gp[2];
82#endif
83 gp += 3;
84 cp += 4;
85 }
86 gdkpix += stride;
87 cpix += cstride;
88 }
89 } else {
90 /* premul-color = alpha/255 * color/255 * 255 = (alpha*color)/255
91 * (z/255) = z/256 * 256/255 = z/256 (1 + 1/255)
92 * = z/256 + (z/256)/255 = (z + z/255)/256
93 * # recurse once
94 * = (z + (z + z/255)/256)/256
95 * = (z + z/256 + z/256/255) / 256
96 * # only use 16bit uint operations, loose some precision,
97 * # result is floored.
98 * -> (z + z>>8)>>8
99 * # add 0x80/255 = 0.5 to convert floor to round
100 * => (z+0x80 + (z+0x80)>>8 ) >> 8
101 * ------
102 * tested as equal to lround(z/255.0) for uint z in [0..0xfe02]
103 */
104#define PREMUL_ALPHA(x,a,b,z) G_STMT_START { z = a * b + 0x80; x = (z + (z >> 8)) >> 8; } G_STMT_END
105 int i;
106 for (i = h; i; --i) {
107 const guint8 *gp = gdkpix;
108 unsigned char *cp = cpix;
109 const guint8* end = gp + 4*w;
110 guint z1, z2, z3;
111 while (gp < end) {
112#if G_BYTE_ORDER == G_LITTLE_ENDIAN
113 PREMUL_ALPHA(cp[0], gp[2], gp[3], z1);
114 PREMUL_ALPHA(cp[1], gp[1], gp[3], z2);
115 PREMUL_ALPHA(cp[2], gp[0], gp[3], z3);
116 cp[3] = gp[3];
117#else
118 PREMUL_ALPHA(cp[1], gp[0], gp[3], z1);
119 PREMUL_ALPHA(cp[2], gp[1], gp[3], z2);
120 PREMUL_ALPHA(cp[3], gp[2], gp[3], z3);
121 cp[0] = gp[3];
122#endif
123 gp += 4;
124 cp += 4;
125 }
126 gdkpix += stride;
127 cpix += cstride;
128 }
129#undef PREMUL_ALPHA
130 }
131 cairo_surface_mark_dirty(cs);
132 return cs;
133}
134#endif //WITH_GDK_PIXBUF
diff --git a/wayland/pango.c b/wayland/pango.c
deleted file mode 100644
index f9eec98c..00000000
--- a/wayland/pango.c
+++ /dev/null
@@ -1,73 +0,0 @@
1#include <cairo/cairo.h>
2#include <pango/pangocairo.h>
3#include <stdarg.h>
4#include <stdlib.h>
5#include <string.h>
6#include <stdio.h>
7#include <stdbool.h>
8#include <stdint.h>
9#include "log.h"
10
11PangoLayout *get_pango_layout(cairo_t *cairo, const char *font, const char *text,
12 int32_t scale, bool markup) {
13 PangoLayout *layout = pango_cairo_create_layout(cairo);
14 PangoAttrList *attrs;
15 if (markup) {
16 char *buf;
17 pango_parse_markup(text, -1, 0, &attrs, &buf, NULL, NULL);
18 pango_layout_set_markup(layout, buf, -1);
19 free(buf);
20 } else {
21 attrs = pango_attr_list_new();
22 pango_layout_set_text(layout, text, -1);
23 }
24 pango_attr_list_insert(attrs, pango_attr_scale_new(scale));
25 PangoFontDescription *desc = pango_font_description_from_string(font);
26 pango_layout_set_font_description(layout, desc);
27 pango_layout_set_single_paragraph_mode(layout, 1);
28 pango_layout_set_attributes(layout, attrs);
29 pango_attr_list_unref(attrs);
30 pango_font_description_free(desc);
31 return layout;
32}
33
34void get_text_size(cairo_t *cairo, const char *font, int *width, int *height,
35 int32_t scale, bool markup, const char *fmt, ...) {
36 char *buf = malloc(2048);
37
38 va_list args;
39 va_start(args, fmt);
40 if (vsnprintf(buf, 2048, fmt, args) >= 2048) {
41 strcpy(buf, "[buffer overflow]");
42 }
43 va_end(args);
44
45 PangoLayout *layout = get_pango_layout(cairo, font, buf, scale, markup);
46 pango_cairo_update_layout(cairo, layout);
47
48 pango_layout_get_pixel_size(layout, width, height);
49
50 g_object_unref(layout);
51
52 free(buf);
53}
54
55void pango_printf(cairo_t *cairo, const char *font, int32_t scale, bool markup, const char *fmt, ...) {
56 char *buf = malloc(2048);
57
58 va_list args;
59 va_start(args, fmt);
60 if (vsnprintf(buf, 2048, fmt, args) >= 2048) {
61 strcpy(buf, "[buffer overflow]");
62 }
63 va_end(args);
64
65 PangoLayout *layout = get_pango_layout(cairo, font, buf, scale, markup);
66 pango_cairo_update_layout(cairo, layout);
67
68 pango_cairo_show_layout(cairo, layout);
69
70 g_object_unref(layout);
71
72 free(buf);
73}
diff --git a/wayland/registry.c b/wayland/registry.c
deleted file mode 100644
index bbb43ad9..00000000
--- a/wayland/registry.c
+++ /dev/null
@@ -1,293 +0,0 @@
1#include <wayland-client.h>
2#include <xkbcommon/xkbcommon.h>
3#include <stdlib.h>
4#include <string.h>
5#include <unistd.h>
6#include <sys/mman.h>
7#include <sys/types.h>
8#include <sys/timerfd.h>
9#include "wayland-desktop-shell-client-protocol.h"
10#include "wayland-swaylock-client-protocol.h"
11#include "client/registry.h"
12#include "stringop.h"
13#include "log.h"
14
15static void display_handle_mode(void *data, struct wl_output *wl_output,
16 uint32_t flags, int32_t width, int32_t height, int32_t refresh) {
17 struct output_state *state = data;
18 if (flags & WL_OUTPUT_MODE_CURRENT) {
19 state->flags = flags;
20 state->width = width;
21 state->height = height;
22 sway_log(L_DEBUG, "Got mode %dx%d:0x%X for output %p",
23 width, height, flags, data);
24 }
25}
26
27static void display_handle_geometry(void *data, struct wl_output *wl_output,
28 int32_t x, int32_t y, int32_t physical_width, int32_t physical_height,
29 int32_t subpixel, const char *make, const char *model, int32_t transform) {
30 // this space intentionally left blank
31}
32
33static void display_handle_done(void *data, struct wl_output *wl_output) {
34 // this space intentionally left blank
35}
36
37static void display_handle_scale(void *data, struct wl_output *wl_output, int32_t factor) {
38 struct output_state *state = data;
39 state->scale = factor;
40 sway_log(L_DEBUG, "Got scale factor %d for output %p", factor, data);
41}
42
43static const struct wl_output_listener output_listener = {
44 .mode = display_handle_mode,
45 .geometry = display_handle_geometry,
46 .done = display_handle_done,
47 .scale = display_handle_scale
48};
49
50const char *XKB_MASK_NAMES[MASK_LAST] = {
51 XKB_MOD_NAME_SHIFT,
52 XKB_MOD_NAME_CAPS,
53 XKB_MOD_NAME_CTRL,
54 XKB_MOD_NAME_ALT,
55 "Mod2",
56 "Mod3",
57 XKB_MOD_NAME_LOGO,
58 "Mod5",
59};
60
61const enum mod_bit XKB_MODS[MASK_LAST] = {
62 MOD_SHIFT,
63 MOD_CAPS,
64 MOD_CTRL,
65 MOD_ALT,
66 MOD_MOD2,
67 MOD_MOD3,
68 MOD_LOGO,
69 MOD_MOD5
70};
71
72static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
73 uint32_t format, int fd, uint32_t size) {
74 // Keyboard errors are abort-worthy because you wouldn't be able to unlock your screen otherwise.
75
76 struct registry *registry = data;
77 if (!data) {
78 close(fd);
79 return;
80 }
81
82 if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
83 close(fd);
84 sway_abort("Unknown keymap format %d, aborting", format);
85 }
86
87 char *map_str = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
88 if (map_str == MAP_FAILED) {
89 close(fd);
90 sway_abort("Unable to initialized shared keyboard memory, aborting");
91 }
92
93 struct xkb_keymap *keymap = xkb_keymap_new_from_string(registry->input->xkb.context,
94 map_str, XKB_KEYMAP_FORMAT_TEXT_V1, 0);
95 munmap(map_str, size);
96 close(fd);
97
98 if (!keymap) {
99 sway_abort("Failed to compile keymap, aborting");
100 }
101
102 struct xkb_state *state = xkb_state_new(keymap);
103 if (!state) {
104 xkb_keymap_unref(keymap);
105 sway_abort("Failed to create xkb state, aborting");
106 }
107
108 xkb_keymap_unref(registry->input->xkb.keymap);
109 xkb_state_unref(registry->input->xkb.state);
110 registry->input->xkb.keymap = keymap;
111 registry->input->xkb.state = state;
112
113 int i;
114 for (i = 0; i < MASK_LAST; ++i) {
115 registry->input->xkb.masks[i] = 1 << xkb_keymap_mod_get_index(registry->input->xkb.keymap, XKB_MASK_NAMES[i]);
116 }
117}
118
119static void keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
120 uint32_t serial, struct wl_surface *surface, struct wl_array *keys) {
121 // this space intentionally left blank
122}
123
124static void keyboard_handle_leave(void *data, struct wl_keyboard *keyboard,
125 uint32_t serial, struct wl_surface *surface) {
126 // this space intentionally left blank
127}
128
129static void keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
130 uint32_t serial, uint32_t time, uint32_t key, uint32_t state_w) {
131 struct registry *registry = data;
132 enum wl_keyboard_key_state state = state_w;
133
134 if (!registry->input->xkb.state) {
135 return;
136 }
137
138 xkb_keysym_t sym = xkb_state_key_get_one_sym(registry->input->xkb.state, key + 8);
139 registry->input->sym = (state == WL_KEYBOARD_KEY_STATE_PRESSED ? sym : XKB_KEY_NoSymbol);
140 registry->input->code = (state == WL_KEYBOARD_KEY_STATE_PRESSED ? key + 8 : 0);
141 uint32_t codepoint = xkb_state_key_get_utf32(registry->input->xkb.state, registry->input->code);
142 if (registry->input->notify) {
143 registry->input->notify(state, sym, key, codepoint);
144 }
145}
146
147static void keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
148 uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched,
149 uint32_t mods_locked, uint32_t group) {
150 struct registry *registry = data;
151
152 if (!registry->input->xkb.keymap) {
153 return;
154 }
155
156 xkb_state_update_mask(registry->input->xkb.state, mods_depressed, mods_latched, mods_locked, 0, 0, group);
157 xkb_mod_mask_t mask = xkb_state_serialize_mods(registry->input->xkb.state,
158 XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED);
159
160 registry->input->modifiers = 0;
161 for (uint32_t i = 0; i < MASK_LAST; ++i) {
162 if (mask & registry->input->xkb.masks[i]) {
163 registry->input->modifiers |= XKB_MODS[i];
164 }
165 }
166}
167
168static void keyboard_handle_repeat_info(void *data, struct wl_keyboard *keyboard,
169 int32_t rate, int32_t delay) {
170 // this space intentionally left blank
171}
172
173static const struct wl_keyboard_listener keyboard_listener = {
174 .keymap = keyboard_handle_keymap,
175 .enter = keyboard_handle_enter,
176 .leave = keyboard_handle_leave,
177 .key = keyboard_handle_key,
178 .modifiers = keyboard_handle_modifiers,
179 .repeat_info = keyboard_handle_repeat_info
180};
181
182static void seat_handle_capabilities(void *data, struct wl_seat *seat,
183 enum wl_seat_capability caps) {
184 struct registry *reg = data;
185
186 if ((caps & WL_SEAT_CAPABILITY_POINTER) && !reg->pointer) {
187 reg->pointer = wl_seat_get_pointer(reg->seat);
188 } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && reg->pointer) {
189 wl_pointer_destroy(reg->pointer);
190 reg->pointer = NULL;
191 }
192
193 if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !reg->keyboard) {
194 reg->keyboard = wl_seat_get_keyboard(reg->seat);
195 wl_keyboard_add_listener(reg->keyboard, &keyboard_listener, reg);
196 } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && reg->keyboard) {
197 wl_keyboard_destroy(reg->keyboard);
198 reg->keyboard = NULL;
199 }
200}
201
202static void seat_handle_name(void *data, struct wl_seat *seat, const char *name) {
203 // this space intentionally left blank
204}
205
206static const struct wl_seat_listener seat_listener = {
207 .capabilities = seat_handle_capabilities,
208 .name = seat_handle_name,
209};
210
211static void registry_global(void *data, struct wl_registry *registry,
212 uint32_t name, const char *interface, uint32_t version) {
213 struct registry *reg = data;
214
215 if (strcmp(interface, wl_compositor_interface.name) == 0) {
216 reg->compositor = wl_registry_bind(registry, name, &wl_compositor_interface, version);
217 } else if (strcmp(interface, wl_shm_interface.name) == 0) {
218 reg->shm = wl_registry_bind(registry, name, &wl_shm_interface, version);
219 } else if (strcmp(interface, wl_shell_interface.name) == 0) {
220 reg->shell = wl_registry_bind(registry, name, &wl_shell_interface, version);
221 } else if (strcmp(interface, wl_seat_interface.name) == 0) {
222 reg->seat = wl_registry_bind(registry, name, &wl_seat_interface, version);
223 wl_seat_add_listener(reg->seat, &seat_listener, reg);
224 } else if (strcmp(interface, wl_output_interface.name) == 0) {
225 struct wl_output *output = wl_registry_bind(registry, name, &wl_output_interface, version);
226 struct output_state *ostate = malloc(sizeof(struct output_state));
227 ostate->output = output;
228 ostate->scale = 1;
229 wl_output_add_listener(output, &output_listener, ostate);
230 list_add(reg->outputs, ostate);
231 } else if (strcmp(interface, desktop_shell_interface.name) == 0) {
232 reg->desktop_shell = wl_registry_bind(registry, name, &desktop_shell_interface, version);
233 } else if (strcmp(interface, lock_interface.name) == 0) {
234 reg->swaylock = wl_registry_bind(registry, name, &lock_interface, version);
235 }
236}
237
238static void registry_global_remove(void *data, struct wl_registry *registry, uint32_t name) {
239 // this space intentionally left blank
240}
241
242static const struct wl_registry_listener registry_listener = {
243 .global = registry_global,
244 .global_remove = registry_global_remove
245};
246
247struct registry *registry_poll(void) {
248 struct registry *registry = malloc(sizeof(struct registry));
249 memset(registry, 0, sizeof(struct registry));
250 registry->outputs = create_list();
251 registry->input = calloc(sizeof(struct input), 1);
252 registry->input->xkb.context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
253
254 registry->display = wl_display_connect(NULL);
255 if (!registry->display) {
256 sway_log(L_ERROR, "Error opening display");
257 registry_teardown(registry);
258 return NULL;
259 }
260
261 struct wl_registry *reg = wl_display_get_registry(registry->display);
262 wl_registry_add_listener(reg, &registry_listener, registry);
263 wl_display_dispatch(registry->display);
264 wl_display_roundtrip(registry->display);
265 wl_registry_destroy(reg);
266
267 return registry;
268}
269
270void registry_teardown(struct registry *registry) {
271 if (registry->pointer) {
272 wl_pointer_destroy(registry->pointer);
273 }
274 if (registry->seat) {
275 wl_seat_destroy(registry->seat);
276 }
277 if (registry->shell) {
278 wl_shell_destroy(registry->shell);
279 }
280 if (registry->shm) {
281 wl_shm_destroy(registry->shm);
282 }
283 if (registry->compositor) {
284 wl_compositor_destroy(registry->compositor);
285 }
286 if (registry->display) {
287 wl_display_disconnect(registry->display);
288 }
289 if (registry->outputs) {
290 free_flat_list(registry->outputs);
291 }
292 free(registry);
293}
diff --git a/wayland/window.c b/wayland/window.c
deleted file mode 100644
index 8a506656..00000000
--- a/wayland/window.c
+++ /dev/null
@@ -1,177 +0,0 @@
1#include <wayland-client.h>
2#include <wayland-cursor.h>
3#include "wayland-xdg-shell-client-protocol.h"
4#include "wayland-desktop-shell-client-protocol.h"
5#include <cairo/cairo.h>
6#include <pango/pangocairo.h>
7#include <stdlib.h>
8#include <string.h>
9#include <stdio.h>
10#include <unistd.h>
11#include <errno.h>
12#include <sys/mman.h>
13#include "client/window.h"
14#include "client/buffer.h"
15#include "list.h"
16#include "log.h"
17
18static void pointer_handle_enter(void *data, struct wl_pointer *pointer,
19 uint32_t serial, struct wl_surface *surface, wl_fixed_t sx_w, wl_fixed_t sy_w) {
20 struct window *window = data;
21 if (window->registry->pointer) {
22 struct wl_cursor_image *image = window->cursor.cursor->images[0];
23 wl_pointer_set_cursor(pointer, serial, window->cursor.surface, image->hotspot_x, image->hotspot_y);
24 }
25}
26
27static void pointer_handle_leave(void *data, struct wl_pointer *pointer,
28 uint32_t serial, struct wl_surface *surface) {
29}
30
31static void pointer_handle_motion(void *data, struct wl_pointer *pointer,
32 uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w) {
33 struct window *window = data;
34
35 window->pointer_input.last_x = wl_fixed_to_int(sx_w);
36 window->pointer_input.last_y = wl_fixed_to_int(sy_w);
37}
38
39static void pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
40 uint32_t time, uint32_t button, uint32_t state_w) {
41 struct window *window = data;
42 struct pointer_input *input = &window->pointer_input;
43
44 if (window->pointer_input.notify_button) {
45 window->pointer_input.notify_button(window, input->last_x, input->last_y, button, state_w);
46 }
47}
48
49static void pointer_handle_axis(void *data, struct wl_pointer *pointer,
50 uint32_t time, uint32_t axis, wl_fixed_t value) {
51 struct window *window = data;
52 enum scroll_direction direction;
53
54 switch (axis) {
55 case 0:
56 direction = wl_fixed_to_double(value) < 0 ? SCROLL_UP : SCROLL_DOWN;
57 break;
58 case 1:
59 direction = wl_fixed_to_double(value) < 0 ? SCROLL_LEFT : SCROLL_RIGHT;
60 break;
61 default:
62 sway_log(L_DEBUG, "Unexpected axis value on mouse scroll");
63 return;
64 }
65
66 if (window->pointer_input.notify_scroll) {
67 window->pointer_input.notify_scroll(window, direction);
68 }
69}
70
71static const struct wl_pointer_listener pointer_listener = {
72 .enter = pointer_handle_enter,
73 .leave = pointer_handle_leave,
74 .motion = pointer_handle_motion,
75 .button = pointer_handle_button,
76 .axis = pointer_handle_axis
77};
78
79void shell_surface_configure(void *data, struct wl_shell_surface *wl_shell_surface,
80 uint32_t edges, int32_t width, int32_t height) {
81 struct window *window = data;
82 window->width = width;
83 window->height = height;
84}
85
86static const struct wl_shell_surface_listener surface_listener = {
87 .configure = shell_surface_configure
88};
89
90void window_make_shell(struct window *window) {
91 window->shell_surface = wl_shell_get_shell_surface(window->registry->shell, window->surface);
92 wl_shell_surface_add_listener(window->shell_surface, &surface_listener, window);
93 wl_shell_surface_set_toplevel(window->shell_surface);
94}
95
96struct window *window_setup(struct registry *registry, uint32_t width, uint32_t height,
97 int32_t scale, bool shell_surface) {
98 struct window *window = malloc(sizeof(struct window));
99 memset(window, 0, sizeof(struct window));
100 window->width = width;
101 window->height = height;
102 window->scale = scale;
103 window->registry = registry;
104 window->font = "monospace 10";
105
106 window->surface = wl_compositor_create_surface(registry->compositor);
107 if (shell_surface) {
108 window_make_shell(window);
109 }
110 if (registry->pointer) {
111 wl_pointer_add_listener(registry->pointer, &pointer_listener, window);
112 }
113
114 get_next_buffer(window);
115
116 if (registry->pointer) {
117 char *cursor_theme = getenv("SWAY_CURSOR_THEME");
118 if (!cursor_theme) {
119 cursor_theme = "default";
120 }
121 char *cursor_size = getenv("SWAY_CURSOR_SIZE");
122 if (!cursor_size) {
123 cursor_size = "16";
124 }
125
126 sway_log(L_DEBUG, "Cursor scale: %d", scale);
127 window->cursor.cursor_theme = wl_cursor_theme_load(cursor_theme,
128 atoi(cursor_size) * scale, registry->shm);
129 window->cursor.cursor = wl_cursor_theme_get_cursor(window->cursor.cursor_theme, "left_ptr");
130 window->cursor.surface = wl_compositor_create_surface(registry->compositor);
131
132 struct wl_cursor_image *image = window->cursor.cursor->images[0];
133 struct wl_buffer *cursor_buf = wl_cursor_image_get_buffer(image);
134 wl_surface_attach(window->cursor.surface, cursor_buf, 0, 0);
135 wl_surface_set_buffer_scale(window->cursor.surface, scale);
136 wl_surface_damage(window->cursor.surface, 0, 0,
137 image->width, image->height);
138 wl_surface_commit(window->cursor.surface);
139 }
140
141 return window;
142}
143
144static void frame_callback(void *data, struct wl_callback *callback, uint32_t time) {
145 struct window *window = data;
146 wl_callback_destroy(callback);
147 window->frame_cb = NULL;
148}
149
150static const struct wl_callback_listener listener = {
151 frame_callback
152};
153
154int window_prerender(struct window *window) {
155 if (window->frame_cb) {
156 return 0;
157 }
158
159 get_next_buffer(window);
160 return 1;
161}
162
163int window_render(struct window *window) {
164 window->frame_cb = wl_surface_frame(window->surface);
165 wl_callback_add_listener(window->frame_cb, &listener, window);
166
167 wl_surface_attach(window->surface, window->buffer->buffer, 0, 0);
168 wl_surface_set_buffer_scale(window->surface, window->scale);
169 wl_surface_damage(window->surface, 0, 0, window->width, window->height);
170 wl_surface_commit(window->surface);
171
172 return 1;
173}
174
175void window_teardown(struct window *window) {
176 // TODO
177}