about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.gitmodules3
-rw-r--r--Makefile13
-rw-r--r--drw.c118
-rw-r--r--drw.h45
-rw-r--r--keyboard.h14
-rw-r--r--main.c2
-rw-r--r--shm_open.c55
-rw-r--r--shm_open.h9
m---------wld0
9 files changed, 202 insertions, 57 deletions
diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644
index c1792d8..0000000
--- a/.gitmodules
+++ /dev/null
@@ -1,3 +0,0 @@
-[submodule "wld"]
-	path = wld
-	url = https://github.com/michaelforney/wld.git
diff --git a/Makefile b/Makefile
index 3afd46e..a498597 100644
--- a/Makefile
+++ b/Makefile
@@ -3,16 +3,15 @@ include config.mk
 NAME=wvkbd
 BIN=${NAME}-${LAYOUT}
 SRC=.
-WLDSRC=wld
 
-PKGS = fontconfig wayland-client xkbcommon pixman-1
+PKGS = wayland-client xkbcommon pangocairo
 
 WVKBD_SOURCES += $(wildcard $(SRC)/*.c)
 WVKBD_HEADERS += $(wildcard $(SRC)/*.h)
 
 CFLAGS += -std=gnu99 -Wall -g -DWITH_WAYLAND_SHM -DLAYOUT=\"layout.${LAYOUT}.h\"
 CFLAGS += $(shell pkg-config --cflags $(PKGS))
-LDFLAGS =wld/libwld.a $(shell pkg-config --libs $(PKGS)) -lm -lutil
+LDFLAGS =$(shell pkg-config --libs $(PKGS)) -lm -lutil -lrt
 
 WAYLAND_HEADERS = $(wildcard proto/*.xml)
 
@@ -22,7 +21,7 @@ SOURCES = $(WVKBD_SOURCES) $(WAYLAND_SRC)
 
 OBJECTS = $(SOURCES:.c=.o)
 
-all: wld ${BIN}
+all: ${BIN}
 
 proto/%-client-protocol.c: proto/%.xml
 	wayland-scanner code < $? > $@
@@ -35,14 +34,8 @@ $(OBJECTS): $(HDRS) $(WVKBD_HEADERS)
 wvkbd-${LAYOUT}: $(OBJECTS) layout.${LAYOUT}.h
 	$(CC) -o wvkbd-${LAYOUT} $(OBJECTS) $(LDFLAGS)
 
-wld: wld/libwld.a
-
-wld/libwld.a:
-	$(MAKE) -C wld ENABLE_DRM=0
-
 clean:
 	rm -f $(OBJECTS) $(HDRS) $(WAYLAND_SRC) ${BIN}
-	$(MAKE) -C wld clean
 
 format:
 	clang-format -i $(WVKBD_SOURCES) $(WVKBD_HEADERS)
diff --git a/drw.c b/drw.c
index fef0686..6d803d6 100644
--- a/drw.c
+++ b/drw.c
@@ -1,49 +1,43 @@
-#include "wld/wayland.h"
-#include "wld/wld.h"
 #include <wayland-client.h>
+#include <sys/mman.h>
+#include <unistd.h>
 
 #include "drw.h"
+#include "shm_open.h"
 
 void
 drw_init(struct drw *d, const char *fc_pattern, struct wl_display *dpy,
-         void *iface) {
-	d->wld = wld_wayland_create_context(dpy, WLD_ANY, iface);
-	d->fctx = wld_font_create_context();
-	d->font = wld_font_open_name(d->fctx, fc_pattern);
+         void *shm) {
+	d->shm = shm;
+	d->font_description = pango_font_description_from_string(fc_pattern);
 }
 
 void
 drwsurf_init(struct drw *d, struct drwsurf *ds, struct wl_surface *surf) {
 	ds->ctx = d;
 	ds->surf = surf;
-	ds->render = wld_create_renderer(d->wld);
 }
 
 void
 drwsurf_resize(struct drwsurf *ds, uint32_t w, uint32_t h) {
-	union wld_object obj;
-
 	if (ds->buf) {
-		wld_buffer_unreference(ds->buf);
+		munmap(ds->pool_data, ds->s);
+		wl_buffer_destroy(ds->buf);
 		ds->buf = NULL;
-		ds->ref = NULL;
 	}
 
 	ds->w = w;
 	ds->h = h;
 
-	ds->buf = wld_create_buffer(ds->ctx->wld, w, h, WLD_FORMAT_ARGB8888, 0);
-	wld_set_target_buffer(ds->render, ds->buf);
-
-	wld_export(ds->buf, WLD_WAYLAND_OBJECT_BUFFER, &obj);
-	ds->ref = obj.ptr;
+	setup_buffer(ds);
 }
 
 static void surface_frame_callback(void *data, struct wl_callback *cb,
                                    uint32_t time);
 
-static struct wl_callback_listener frame_listener = {.done =
-                                                       surface_frame_callback};
+static struct wl_callback_listener frame_listener = {
+    .done = surface_frame_callback
+};
 
 void
 drwsurf_flip(struct drwsurf *ds) {
@@ -52,12 +46,10 @@ drwsurf_flip(struct drwsurf *ds) {
 
 	if (ds->dirty) {
 		wl_surface_damage(ds->surf, 0, 0, ds->w, ds->h);
-		wld_flush(ds->render);
-		wld_set_target_buffer(ds->render, ds->buf);
 		ds->dirty = false;
 	}
 
-	wl_surface_attach(ds->surf, ds->ref, 0, 0);
+	wl_surface_attach(ds->surf, ds->buf, 0, 0);
 	wl_surface_commit(ds->surf);
 }
 
@@ -69,3 +61,87 @@ surface_frame_callback(void *data, struct wl_callback *cb, uint32_t time) {
 
 	drwsurf_flip(ds);
 }
+
+void
+drw_draw_text(struct drwsurf *d, Color color,
+	uint32_t x, uint32_t y,
+	uint32_t w, uint32_t h,
+	const char *label) {
+
+	cairo_save(d->cairo);
+
+    cairo_set_source_rgba (
+		d->cairo,
+		color.bgra[2] / (double)255,
+		color.bgra[1] / (double)255,
+		color.bgra[0] / (double)255,
+		color.bgra[3] / (double)255
+    );
+	cairo_move_to(d->cairo, x + (double)w / 2.0, y + (double)h / 2.0);
+
+	pango_layout_set_text(d->layout, label, -1);
+
+	int width, height;
+	pango_layout_get_size(d->layout, &width, &height);
+
+	cairo_rel_move_to(d->cairo, - ((double)width / PANGO_SCALE) / 2, - ((double)height / PANGO_SCALE) / 2);
+	pango_cairo_show_layout(d->cairo, d->layout);
+	cairo_restore(d->cairo);
+}
+
+void
+drw_fill_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
+	uint32_t w, uint32_t h) {
+	cairo_save(d->cairo);
+
+	cairo_set_operator(d->cairo, CAIRO_OPERATOR_SOURCE);
+
+	cairo_rectangle(d->cairo, x, y, w, h);
+	cairo_set_source_rgba(
+		d->cairo,
+		color.bgra[2] / (double)255,
+		color.bgra[1] / (double)255,
+		color.bgra[0] / (double)255,
+		color.bgra[3] / (double)255
+	);
+	cairo_fill(d->cairo);
+
+	cairo_restore(d->cairo);
+}
+
+uint32_t
+setup_buffer(struct drwsurf *drwsurf)
+{
+	int stride = drwsurf->w * 4;
+	drwsurf->s = stride * drwsurf->h;
+
+	int fd = allocate_shm_file(drwsurf->s);
+	if (fd == -1) {
+		return 1;
+	}
+
+	drwsurf->pool_data = mmap(NULL, drwsurf->s,
+	PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+	if (drwsurf->pool_data == MAP_FAILED) {
+		close(fd);
+		return 1;
+	}
+
+	struct wl_shm_pool *pool = wl_shm_create_pool(drwsurf->ctx->shm, fd, drwsurf->s);
+	drwsurf->buf = wl_shm_pool_create_buffer(pool, 0,
+		drwsurf->w, drwsurf->h, stride, WL_SHM_FORMAT_ARGB8888);
+	wl_shm_pool_destroy(pool);
+	close(fd);
+
+	cairo_surface_t *s = cairo_image_surface_create_for_data(drwsurf->pool_data,
+		CAIRO_FORMAT_ARGB32,
+	drwsurf->w, drwsurf->h, stride);
+
+	drwsurf->cairo = cairo_create(s);
+	drwsurf->layout = pango_cairo_create_layout(drwsurf->cairo);
+	pango_layout_set_font_description(drwsurf->layout, drwsurf->ctx->font_description);
+	cairo_save(drwsurf->cairo);
+
+	return 0;
+}
+
diff --git a/drw.h b/drw.h
index 15abbb7..d3d0e95 100644
--- a/drw.h
+++ b/drw.h
@@ -1,37 +1,56 @@
 #ifndef __DRW_H
 #define __DRW_H
 
+#include <pango/pangocairo.h>
+#include <stdbool.h>
+
 struct drw;
 struct drwsurf;
+struct kbd;
 
 void drw_init(struct drw *d, const char *fc_pattern, struct wl_display *dpy,
-              void *iface);
+	void *iface);
 void drwsurf_init(struct drw *d, struct drwsurf *ds, struct wl_surface *surf);
 void drwsurf_resize(struct drwsurf *ds, uint32_t w, uint32_t h);
 void drwsurf_flip(struct drwsurf *ds);
 
+typedef union {
+	uint8_t bgra[4];
+	uint32_t color;
+} Color;
+
+void
+drw_fill_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
+	uint32_t w, uint32_t h);
+
+void
+drw_draw_text(struct drwsurf *d, Color color,
+	uint32_t x, uint32_t y,
+	uint32_t w, uint32_t h,
+	const char *label);
+
+uint32_t
+setup_buffer(struct drwsurf *drwsurf);
+
 struct drw {
-	struct wld_context *wld;
-	struct wld_font_context *fctx;
-	struct wld_font *font;
+	struct wl_shm *shm;
+	PangoFontDescription *font_description;
 };
 
 struct drwsurf {
-	uint32_t w, h;
+	uint32_t w, h, s;
 	bool dirty;
 
 	struct drw *ctx;
 	struct wl_surface *surf;
-	struct wld_renderer *render;
-	struct wld_buffer *buf;
-	struct wl_buffer *ref;
+	struct wl_buffer *buf;
+	struct wl_shm *shm;
+	unsigned char *pool_data;
+
+	cairo_t *cairo;
+	PangoLayout *layout;
 
 	struct wl_callback *cb;
 };
 
-typedef union {
-	uint8_t bgra[4];
-	uint32_t color;
-} Color;
-
 #endif
diff --git a/keyboard.h b/keyboard.h
index 289bccb..5f7b973 100644
--- a/keyboard.h
+++ b/keyboard.h
@@ -91,7 +91,7 @@ struct kbd {
 
 static inline void draw_inset(struct drwsurf *d, uint32_t x, uint32_t y,
                               uint32_t width, uint32_t height, uint32_t border,
-                              uint32_t color);
+                              Color color);
 
 static void kbd_init(struct kbd *kb, struct layout * layouts, char * layer_names_list);
 static void kbd_init_layout(struct layout *l, uint32_t width, uint32_t height);
@@ -406,10 +406,8 @@ kbd_draw_key(struct kbd *kb, struct key *k, bool pressed) {
 	        label);
 	struct clr_scheme *scheme = (k->scheme == 0) ? &(kb->scheme) : &(kb->scheme1);
 	Color *fill = pressed ? &scheme->high : &scheme->fg;
-	draw_inset(d, k->x, k->y, k->w, k->h, KBD_KEY_BORDER, fill->color);
-	uint32_t xoffset = k->w / (strlen(label) + 2);
-	wld_draw_text(d->render, d->ctx->font, scheme->text.color, k->x + xoffset,
-	              k->y + (k->h / 2), label, -1, NULL);
+	draw_inset(d, k->x, k->y, k->w, k->h, KBD_KEY_BORDER, *fill);
+	drw_draw_text(d, scheme->text, k->x, k->y, k->w, k->h, label);
 }
 
 void
@@ -419,7 +417,7 @@ kbd_draw_layout(struct kbd *kb) {
 	bool pressed = false;
 	if (debug) fprintf(stderr, "Draw layout");
 
-	wld_fill_rectangle(d->render, kb->scheme.bg.color, 0, 0, kb->w, kb->h);
+	drw_fill_rectangle(d, kb->scheme.bg, 0, 0, kb->w, kb->h);
 
 	while (next_key->type != Last) {
 		if ((next_key->type == Pad) || (next_key->type == EndRow)) {
@@ -452,7 +450,7 @@ kbd_resize(struct kbd *kb, uint32_t w, uint32_t h, struct layout *layouts,
 
 void
 draw_inset(struct drwsurf *d, uint32_t x, uint32_t y, uint32_t width,
-           uint32_t height, uint32_t border, uint32_t color) {
-	wld_fill_rectangle(d->render, color, x + border, y + border, width - border,
+           uint32_t height, uint32_t border, Color color) {
+	drw_fill_rectangle(d, color, x + border, y + border, width - border,
 	                   height - border);
 }
diff --git a/main.c b/main.c
index 9b60fc5..1d46c9e 100644
--- a/main.c
+++ b/main.c
@@ -1,7 +1,5 @@
 #include "proto/virtual-keyboard-unstable-v1-client-protocol.h"
 #include "proto/wlr-layer-shell-unstable-v1-client-protocol.h"
-#include "wld/wayland.h"
-#include "wld/wld.h"
 #include <linux/input-event-codes.h>
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/shm_open.c b/shm_open.c
new file mode 100644
index 0000000..05cb571
--- /dev/null
+++ b/shm_open.c
@@ -0,0 +1,55 @@
+#define _POSIX_C_SOURCE 200112L
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <time.h>
+#include <unistd.h>
+
+static void
+randname(char *buf)
+{
+	struct timespec ts;
+	long r;
+	clock_gettime(CLOCK_REALTIME, &ts);
+	r = ts.tv_nsec;
+	for (int i = 0; i < 6; ++i) {
+		buf[i] = 'A'+(r&15)+(r&16)*2;
+		r >>= 5;
+	}
+}
+
+static int
+create_shm_file(void)
+{
+	int retries = 100;
+	int fd;
+	do {
+		char name[] = "/wl_shm-XXXXXX";
+		randname(name + sizeof(name) - 7);
+		--retries;
+		fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL, 0600);
+		if (fd >= 0) {
+			shm_unlink(name);
+			return fd;
+		}
+	} while (retries > 0 && errno == EEXIST);
+	return -1;
+}
+
+int
+allocate_shm_file(size_t size)
+{
+	int fd = create_shm_file();
+	int ret;
+	if (fd < 0)
+		return -1;
+	do {
+		ret = ftruncate(fd, size);
+	} while (ret < 0 && errno == EINTR);
+	if (ret < 0) {
+		close(fd);
+		return -1;
+	}
+	return fd;
+}
+
diff --git a/shm_open.h b/shm_open.h
new file mode 100644
index 0000000..bfec6eb
--- /dev/null
+++ b/shm_open.h
@@ -0,0 +1,9 @@
+#ifndef shm_open_h_INCLUDED
+#define shm_open_h_INCLUDED
+
+void randname(char *buf);
+int create_shm_file(void);
+int allocate_shm_file(size_t size);
+
+#endif // shm_open_h_INCLUDED
+
diff --git a/wld b/wld
deleted file mode 160000
-Subproject ea4eccb64cfcfc508b029a530fc434d6e6695af