mirror of
https://github.com/jjsullivan5196/wvkbd.git
synced 2025-03-12 18:32:48 +01:00
Drop wld and implement our own pangocairo renderer
This commit is contained in:
parent
9b53b2c836
commit
c806023fd5
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -1,3 +0,0 @@
|
||||
[submodule "wld"]
|
||||
path = wld
|
||||
url = https://github.com/michaelforney/wld.git
|
13
Makefile
13
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)
|
||||
|
118
drw.c
118
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;
|
||||
}
|
||||
|
||||
|
59
drw.h
59
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);
|
||||
|
||||
struct drw {
|
||||
struct wld_context *wld;
|
||||
struct wld_font_context *fctx;
|
||||
struct wld_font *font;
|
||||
};
|
||||
|
||||
struct drwsurf {
|
||||
uint32_t w, h;
|
||||
bool dirty;
|
||||
|
||||
struct drw *ctx;
|
||||
struct wl_surface *surf;
|
||||
struct wld_renderer *render;
|
||||
struct wld_buffer *buf;
|
||||
struct wl_buffer *ref;
|
||||
|
||||
struct wl_callback *cb;
|
||||
};
|
||||
|
||||
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 wl_shm *shm;
|
||||
PangoFontDescription *font_description;
|
||||
};
|
||||
|
||||
struct drwsurf {
|
||||
uint32_t w, h, s;
|
||||
bool dirty;
|
||||
|
||||
struct drw *ctx;
|
||||
struct wl_surface *surf;
|
||||
struct wl_buffer *buf;
|
||||
struct wl_shm *shm;
|
||||
unsigned char *pool_data;
|
||||
|
||||
cairo_t *cairo;
|
||||
PangoLayout *layout;
|
||||
|
||||
struct wl_callback *cb;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
14
keyboard.h
14
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);
|
||||
}
|
||||
|
@ -71,10 +71,7 @@ static enum layout_id layers[] = {
|
||||
#include "keymap.mobintl.h"
|
||||
#include "keyboard.h"
|
||||
|
||||
/* font (see `man fonts-conf` for instructions) */
|
||||
static const char *fc_font_pattern =
|
||||
"Monospace:size=16:antialias=true:hinting=true";
|
||||
|
||||
static const char *fc_font_pattern = "Monospace 16";
|
||||
|
||||
static struct key keys_full[], keys_special[], keys_simple[], keys_cyrillic[],
|
||||
keys_arabic[],
|
||||
|
2
main.c
2
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>
|
||||
|
55
shm_open.c
Normal file
55
shm_open.c
Normal file
@ -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;
|
||||
}
|
||||
|
9
shm_open.h
Normal file
9
shm_open.h
Normal file
@ -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
|
||||
|
1
wld
1
wld
@ -1 +0,0 @@
|
||||
Subproject commit ea4eccb64cfcfc508b029a530fc434d6e6695af5
|
Loading…
x
Reference in New Issue
Block a user