1 Commits

16 changed files with 206 additions and 4465 deletions

2
.gitignore vendored
View File

@@ -6,7 +6,5 @@ include/config.h
.gdb_history .gdb_history
*.log *.log
wvkbd wvkbd
*.1
config.h config.h
wvkbd-mobintl wvkbd-mobintl
wvkbd-deskintl

View File

@@ -10,10 +10,9 @@ PKGS = wayland-client xkbcommon pangocairo
WVKBD_SOURCES += $(wildcard $(SRC)/*.c) WVKBD_SOURCES += $(wildcard $(SRC)/*.c)
WVKBD_HEADERS += $(wildcard $(SRC)/*.h) WVKBD_HEADERS += $(wildcard $(SRC)/*.h)
PKG_CONFIG ?= pkg-config
CFLAGS += -std=gnu99 -Wall -g -DWITH_WAYLAND_SHM -DLAYOUT=\"layout.${LAYOUT}.h\" -DKEYMAP=\"keymap.${LAYOUT}.h\" CFLAGS += -std=gnu99 -Wall -g -DWITH_WAYLAND_SHM -DLAYOUT=\"layout.${LAYOUT}.h\" -DKEYMAP=\"keymap.${LAYOUT}.h\"
CFLAGS += $(shell $(PKG_CONFIG) --cflags $(PKGS)) CFLAGS += $(shell pkg-config --cflags $(PKGS))
LDFLAGS += $(shell $(PKG_CONFIG) --libs $(PKGS)) -lm -lutil -lrt LDFLAGS += $(shell pkg-config --libs $(PKGS)) -lm -lutil -lrt
WAYLAND_HEADERS = $(wildcard proto/*.xml) WAYLAND_HEADERS = $(wildcard proto/*.xml)
@@ -21,15 +20,12 @@ HDRS = $(WAYLAND_HEADERS:.xml=-client-protocol.h)
WAYLAND_SRC = $(HDRS:.h=.c) WAYLAND_SRC = $(HDRS:.h=.c)
SOURCES = $(WVKBD_SOURCES) $(WAYLAND_SRC) SOURCES = $(WVKBD_SOURCES) $(WAYLAND_SRC)
SCDOC=scdoc
DOCS = wvkbd.1
OBJECTS = $(SOURCES:.c=.o) OBJECTS = $(SOURCES:.c=.o)
all: ${BIN} ${DOCS} all: ${BIN}
config.h: config.h:
cp config.${LAYOUT}.h config.h cp config.def.h config.h
proto/%-client-protocol.c: proto/%.xml proto/%-client-protocol.c: proto/%.xml
wayland-scanner code < $? > $@ wayland-scanner code < $? > $@
@@ -43,14 +39,11 @@ wvkbd-${LAYOUT}: config.h $(OBJECTS) layout.${LAYOUT}.h
$(CC) -o wvkbd-${LAYOUT} $(OBJECTS) $(LDFLAGS) $(CC) -o wvkbd-${LAYOUT} $(OBJECTS) $(LDFLAGS)
clean: clean:
rm -f $(OBJECTS) config.h $(HDRS) $(WAYLAND_SRC) ${BIN} ${DOCS} rm -f $(OBJECTS) $(HDRS) $(WAYLAND_SRC) ${BIN}
format: format:
clang-format -i $(WVKBD_SOURCES) $(WVKBD_HEADERS) clang-format -i $(WVKBD_SOURCES) $(WVKBD_HEADERS)
%: %.scd
$(SCDOC) < $< > $@
install: all install: all
mkdir -p ${DESTDIR}${PREFIX}/bin mkdir -p ${DESTDIR}${PREFIX}/bin
cp -f ${NAME}-${LAYOUT} ${DESTDIR}${PREFIX}/bin cp -f ${NAME}-${LAYOUT} ${DESTDIR}${PREFIX}/bin

View File

@@ -1,6 +1,6 @@
# wvkbd - On-screen keyboard for wlroots that sucks less # wvkbd - On-screen keyboard for wlroots that sucks less
<img src="https://raw.githubusercontent.com/jjsullivan5196/wvkbd/master/contrib/wvkbd-mobintl.jpg" width=300 /> <img src="https://raw.githubusercontent.com/jjsullivan5196/wvkbd/master/contrib/wvkbd-mobintl-cyrillic.jpg" width=300 /> <img src="https://raw.githubusercontent.com/proycon/wvkbd/master/contrib/wvkbd-mobintl.jpg" width=300 /> <img src="https://raw.githubusercontent.com/proycon/wvkbd/master/contrib/wvkbd-mobintl-cyrillic.jpg" width=300 />
This project aims to deliver a minimal but practically usable implementation of a wlroots on-screen This project aims to deliver a minimal but practically usable implementation of a wlroots on-screen
keyboard in legible C. This will **only** be a keyboard, not a feedback buzzer, keyboard in legible C. This will **only** be a keyboard, not a feedback buzzer,
@@ -25,7 +25,7 @@ new features.
- Automatic portrait/landscape detection and subsequent layout switching - Automatic portrait/landscape detection and subsequent layout switching
<img src="https://raw.githubusercontent.com/jjsullivan5196/wvkbd/master/contrib/wvkbd-mobintl-landscape.jpg" width=640 /> <img src="https://raw.githubusercontent.com/proycon/wvkbd/master/contrib/wvkbd-mobintl-landscape.jpg" width=640 />
There are some areas that still need work: There are some areas that still need work:
@@ -42,22 +42,18 @@ You'll need the following developer packages
- wayland-client - wayland-client
- xkbcommon - xkbcommon
You also need [scdoc](https://git.sr.ht/~sircmpwn/scdoc/) to generate the documentation. Make any customizations you would like in `config.def.h` and run `make`
The default set of layouts is called `mobintl` *(mobile international)*, which groups various layouts aimed at mobile devices The default set of layouts is called `mobintl` *(mobile international)*, which groups various layouts aimed at mobile devices
and also attempts to accommodate various international users. Run `make`. The resulting binary is called `wvkbd-mobintl`. and also attempts to accommodate various international users. The resulting binary is called `wvkbd-mobintl`.
The other set of layouts is called `deskintl` *(desktop international)*, which groups layouts aimed at desktop, laptop, and You can, however, define your own layouts by copying and modifying `layout.mobintl.h` and `keymap.mobintl.h`
tablet devices with a larger touchscreen. The set is US-International English. Run `make LAYOUT=deskintl`. The resulting binary (replace `mobintl` for something like `yourlayout`). Then make your layout set using `make LAYOUT=yourlayout`, and
is called `wvkbd-deskintl`. the resulting binary will be `wvkbd-yourlayout`
You can, however, define your own layouts by copying and modifying `config.mobintl.h`, `layout.mobintl.h` and `keymap.mobintl.h`
(replace `mobintl` for something like `yourlayout`), or `config.deskintl.h`, `layout.deskintl.h` and `keymap.deskintl.h`. Then
make your layout set using `make LAYOUT=yourlayout`, and the resulting binary will be `wvkbd-yourlayout`.
## Usage ## Usage
Run `wvkbd-mobintl`, `wvkbd-deskintl` or the binary for your custom layout set. Run `wvkbd-mobintl` (or the binary for your custom layout set).
You can switch between the layouts/layers of the keyboard by pressing the You can switch between the layouts/layers of the keyboard by pressing the
⌨ key (little keyboard) the bottom-left (press shift to iterate back instead of ⌨ key (little keyboard) the bottom-left (press shift to iterate back instead of
@@ -103,7 +99,7 @@ layout by name, even layouts not explicitly added to your layers on startup.
Any contributions are welcome, there are two ways to contribute, the first one is **preferred**: Any contributions are welcome, there are two ways to contribute, the first one is **preferred**:
1. [Sourcehut](https://git.sr.ht/~proycon/wvkbd) - Submit your patches using `git send-email` to [~mil/sxmo-devel@lists.sr.ht](mailto:~mil/sxmo-devel@lists.sr.ht), follow [these contribution guidelines](https://sxmo.org/contribute/). Questions can also be asked on Sxmo's [mailing lists](https://sxmo.org/support/). 1. [Sourcehut](https://git.sr.ht/~proycon/wvkbd) - Submit your patches using `git mail` to [~mil/sxmo-devel@lists.sr.ht](mailto:~mil/sxmo-devel@lists.sr.ht), follow [these contribution guidelines](https://sxmo.org/contribute/). Questions can also be asked on Sxmo's [mailing lists](https://sxmo.org/support/).
2. [Github](https://github.com/jjsullivan5196/wvkbd/) - Submit a pull request or open an issue *(legacy method)* 2. [Github](https://github.com/jjsullivan5196/wvkbd/) - Submit a pull request or open an issue *(legacy method)*
This project was started by [John Sullivan](https://jsullivan.cc/) and is This project was started by [John Sullivan](https://jsullivan.cc/) and is

View File

@@ -1,9 +1,7 @@
#ifndef config_h_INCLUDED #ifndef config_def_h_INCLUDED
#define config_h_INCLUDED #define config_def_h_INCLUDED
#define DEFAULT_FONT "Sans 14" #define DEFAULT_FONT "Sans 14"
#define DEFAULT_ROUNDING 5
#define SHIFT_SPACE_IS_TAB
static const int transparency = 255; static const int transparency = 255;
struct clr_scheme schemes[] = { struct clr_scheme schemes[] = {
@@ -15,7 +13,6 @@ struct clr_scheme schemes[] = {
.swipe = {.bgra = {100, 255, 100, 64}}, .swipe = {.bgra = {100, 255, 100, 64}},
.text = {.color = UINT32_MAX}, .text = {.color = UINT32_MAX},
.font = DEFAULT_FONT, .font = DEFAULT_FONT,
.rounding = DEFAULT_ROUNDING,
}, },
{ {
/* colors */ /* colors */
@@ -25,14 +22,13 @@ struct clr_scheme schemes[] = {
.swipe = {.bgra = {100, 255, 100, 64}}, .swipe = {.bgra = {100, 255, 100, 64}},
.text = {.color = UINT32_MAX}, .text = {.color = UINT32_MAX},
.font = DEFAULT_FONT, .font = DEFAULT_FONT,
.rounding = DEFAULT_ROUNDING,
} }
}; };
/* layers is an ordered list of layouts, used to cycle through */ /* layers is an ordered list of layouts, used to cycle through */
static enum layout_id layers[] = { static enum layout_id layers[] = {
Full, // First layout is the default layout on startup Full, // First layout is the default layout on startup
Special, Special,
NumLayouts // signals the last item, may not be omitted NumLayouts // signals the last item, may not be omitted
}; };
@@ -43,4 +39,4 @@ static enum layout_id landscape_layers[] = {
NumLayouts // signals the last item, may not be omitted NumLayouts // signals the last item, may not be omitted
}; };
#endif // config_h_INCLUDED #endif // config_def_h_INCLUDED

View File

@@ -1,45 +0,0 @@
#ifndef config_h_INCLUDED
#define config_h_INCLUDED
#define DEFAULT_FONT "Sans 18"
#define DEFAULT_ROUNDING 5
static const int transparency = 255;
struct clr_scheme schemes[] = {
{
/* colors */
.bg = {.bgra = {15, 15, 15, transparency}},
.fg = {.bgra = {45, 45, 45, transparency}},
.high = {.bgra = {100, 100, 100, transparency}},
.swipe = {.bgra = {100, 255, 100, 64}},
.text = {.color = UINT32_MAX},
.font = DEFAULT_FONT,
.rounding = DEFAULT_ROUNDING,
},
{
/* colors */
.bg = {.bgra = {15, 15, 15, transparency}},
.fg = {.bgra = {32, 32, 32, transparency}},
.high = {.bgra = {100, 100, 100, transparency}},
.swipe = {.bgra = {100, 255, 100, 64}},
.text = {.color = UINT32_MAX},
.font = DEFAULT_FONT,
.rounding = DEFAULT_ROUNDING,
}
};
/* layers is an ordered list of layouts, used to cycle through */
static enum layout_id layers[] = {
Full, // First layout is the default layout on startup
Special,
NumLayouts // signals the last item, may not be omitted
};
/* layers is an ordered list of layouts, used to cycle through */
static enum layout_id landscape_layers[] = {
Full, // First layout is the default layout on startup
Special,
NumLayouts // signals the last item, may not be omitted
};
#endif // config_h_INCLUDED

View File

@@ -1,4 +1,4 @@
VERSION = 0.18 VERSION = 0.14.3
CFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=700 CFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=700
PREFIX = /usr/local PREFIX = /usr/local
MANPREFIX = ${PREFIX}/share/man MANPREFIX = ${PREFIX}/share/man

218
drw.c
View File

@@ -6,132 +6,34 @@
#include "shm_open.h" #include "shm_open.h"
#include "math.h" #include "math.h"
void drwbuf_handle_release(void *data, struct wl_buffer *wl_buffer) {
struct drwsurf *ds = data;
ds->released = true;
};
const struct wl_buffer_listener buffer_listener = {
.release = drwbuf_handle_release
};
void drwsurf_handle_frame_cb(void* data, struct wl_callback* callback,
uint32_t time)
{
struct drwsurf *ds = data;
wl_callback_destroy(ds->frame_cb);
ds->frame_cb = NULL;
cairo_rectangle_int_t r = {0};
for (int i = 0; i < cairo_region_num_rectangles(ds->damage); i++) {
cairo_region_get_rectangle(ds->damage, i, &r);
wl_surface_damage(ds->surf, r.x, r.y, r.width, r.height);
};
cairo_region_subtract(ds->damage, ds->damage);
drwsurf_attach(ds);
}
const struct wl_callback_listener frame_listener = {
.done = drwsurf_handle_frame_cb
};
void drwsurf_register_frame_cb(struct drwsurf *ds)
{
if (ds->frame_cb)
return;
if (!ds->attached)
return;
ds->frame_cb = wl_surface_frame(ds->surf);
wl_callback_add_listener(ds->frame_cb, &frame_listener, ds);
wl_surface_commit(ds->surf);
}
void drwsurf_damage(struct drwsurf *ds, uint32_t x, uint32_t y, uint32_t w, uint32_t h)
{
cairo_rectangle_int_t rect = { x, y, w, h };
cairo_region_union_rectangle(ds->damage, &rect);
cairo_region_union_rectangle(ds->backport_damage, &rect);
drwsurf_register_frame_cb(ds);
}
void void
drwsurf_resize(struct drwsurf *ds, uint32_t w, uint32_t h, double s) drwsurf_resize(struct drwsurf *ds, uint32_t w, uint32_t h, double s)
{ {
if (ds->buf) {
munmap(ds->pool_data, ds->size);
wl_buffer_destroy(ds->buf);
ds->buf = NULL;
}
ds->scale = s; ds->scale = s;
ds->width = ceil(w * s); ds->width = ceil(w * s);
ds->height = ceil(h * s); ds->height = ceil(h * s);
if (ds->damage) setup_buffer(ds);
cairo_region_destroy(ds->damage);
ds->damage = cairo_region_create();
if (ds->backport_damage)
cairo_region_destroy(ds->backport_damage);
ds->backport_damage = cairo_region_create();
ds->released = true;
setup_buffer(ds, ds->back_buffer);
setup_buffer(ds, ds->display_buffer);
}
void
drwsurf_backport(struct drwsurf *ds)
{
cairo_save(ds->back_buffer->cairo);
cairo_scale(ds->back_buffer->cairo, 1/ds->scale, 1/ds->scale);
cairo_set_operator(ds->back_buffer->cairo, CAIRO_OPERATOR_SOURCE);
cairo_rectangle_int_t r = {0};
for (int i = 0; i < cairo_region_num_rectangles(ds->backport_damage); i++) {
cairo_region_get_rectangle(ds->backport_damage, i, &r);
cairo_set_source_surface(ds->back_buffer->cairo, ds->display_buffer->cairo_surf, 0, 0);
cairo_rectangle(
ds->back_buffer->cairo,
r.x * ds->scale,
r.y * ds->scale,
r.width * ds->scale,
r.height * ds->scale
);
cairo_fill(ds->back_buffer->cairo);
};
cairo_restore(ds->back_buffer->cairo);
cairo_region_subtract(ds->backport_damage, ds->backport_damage);
}
void
drwsurf_attach(struct drwsurf *ds)
{
wl_surface_attach(ds->surf, ds->back_buffer->buf, 0, 0);
wl_surface_commit(ds->surf);
ds->released = false;
ds->attached = true;
} }
void void
drwsurf_flip(struct drwsurf *ds) drwsurf_flip(struct drwsurf *ds)
{ {
if (ds->released) wl_surface_attach(ds->surf, ds->buf, 0, 0);
return; wl_surface_commit(ds->surf);
ds->released = true;
struct drwbuf *tmp = ds->back_buffer;
ds->back_buffer = ds->display_buffer;
ds->display_buffer = tmp;
drwsurf_backport(ds);
} }
void void
drw_draw_text(struct drwsurf *ds, Color color, uint32_t x, uint32_t y, drw_draw_text(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
uint32_t w, uint32_t h, uint32_t b, const char *label, uint32_t w, uint32_t h, uint32_t b, const char *label,
PangoFontDescription *font_description) PangoFontDescription *font_description)
{ {
drwsurf_flip(ds);
struct drwbuf *d = ds->back_buffer;
drwsurf_damage(ds, x, y, w, h);
cairo_save(d->cairo); cairo_save(d->cairo);
@@ -156,12 +58,8 @@ drw_draw_text(struct drwsurf *ds, Color color, uint32_t x, uint32_t y,
} }
void void
drw_do_clear(struct drwsurf *ds, uint32_t x, uint32_t y, uint32_t w, uint32_t h) drw_do_clear(struct drwsurf *d, uint32_t x, uint32_t y, uint32_t w, uint32_t h)
{ {
drwsurf_flip(ds);
struct drwbuf *d = ds->back_buffer;
drwsurf_damage(ds, x, y, w, h);
cairo_save(d->cairo); cairo_save(d->cairo);
cairo_set_operator(d->cairo, CAIRO_OPERATOR_CLEAR); cairo_set_operator(d->cairo, CAIRO_OPERATOR_CLEAR);
@@ -172,13 +70,9 @@ drw_do_clear(struct drwsurf *ds, uint32_t x, uint32_t y, uint32_t w, uint32_t h)
} }
void void
drw_do_rectangle(struct drwsurf *ds, Color color, uint32_t x, uint32_t y, drw_do_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
uint32_t w, uint32_t h, bool over, int rounding) uint32_t w, uint32_t h, bool over)
{ {
drwsurf_flip(ds);
struct drwbuf *d = ds->back_buffer;
drwsurf_damage(ds, x, y, w, h);
cairo_save(d->cairo); cairo_save(d->cairo);
if (over) { if (over) {
@@ -187,99 +81,65 @@ drw_do_rectangle(struct drwsurf *ds, Color color, uint32_t x, uint32_t y,
cairo_set_operator(d->cairo, CAIRO_OPERATOR_SOURCE); cairo_set_operator(d->cairo, CAIRO_OPERATOR_SOURCE);
} }
if (rounding > 0) { cairo_rectangle(d->cairo, x, y, w, h);
double radius = rounding / 1.0; cairo_set_source_rgba(
double degrees = M_PI / 180.0; 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_new_sub_path (d->cairo); cairo_restore(d->cairo);
cairo_arc (d->cairo, x + w - radius, y + radius, radius, -90 * degrees, 0 * degrees);
cairo_arc (d->cairo, x + w - radius, y + h - radius, radius, 0 * degrees, 90 * degrees);
cairo_arc (d->cairo, x + radius, y + h - radius, radius, 90 * degrees, 180 * degrees);
cairo_arc (d->cairo, x + radius, y + radius, radius, 180 * degrees, 270 * degrees);
cairo_close_path (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_fill (d->cairo);
cairo_set_source_rgba(d->cairo, 0, 0, 0, 0.9);
cairo_set_line_width(d->cairo, 1.0);
cairo_stroke(d->cairo);
cairo_restore(d->cairo);
}
else {
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);
}
} }
void void
drw_fill_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y, drw_fill_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
uint32_t w, uint32_t h, int rounding) uint32_t w, uint32_t h)
{ {
drw_do_rectangle(d, color, x, y, w, h, false, rounding); drw_do_rectangle(d, color, x, y, w, h, false);
} }
void void
drw_over_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y, drw_over_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
uint32_t w, uint32_t h, int rounding) uint32_t w, uint32_t h)
{ {
drw_do_rectangle(d, color, x, y, w, h, true, rounding); drw_do_rectangle(d, color, x, y, w, h, true);
} }
uint32_t uint32_t
setup_buffer(struct drwsurf *drwsurf, struct drwbuf *drwbuf) setup_buffer(struct drwsurf *drwsurf)
{ {
int prev_size = drwbuf->size;
int stride = drwsurf->width * 4; int stride = drwsurf->width * 4;
drwbuf->size = stride * drwsurf->height; drwsurf->size = stride * drwsurf->height;
int fd = allocate_shm_file(drwbuf->size); int fd = allocate_shm_file(drwsurf->size);
if (fd == -1) { if (fd == -1) {
return 1; return 1;
} }
if (drwbuf->pool_data) drwsurf->pool_data =
munmap(drwbuf->pool_data, prev_size); mmap(NULL, drwsurf->size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
drwbuf->pool_data = if (drwsurf->pool_data == MAP_FAILED) {
mmap(NULL, drwbuf->size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (drwbuf->pool_data == MAP_FAILED) {
close(fd); close(fd);
return 1; return 1;
} }
if (drwbuf->buf)
wl_buffer_destroy(drwbuf->buf);
struct wl_shm_pool *pool = struct wl_shm_pool *pool =
wl_shm_create_pool(drwsurf->ctx->shm, fd, drwbuf->size); wl_shm_create_pool(drwsurf->ctx->shm, fd, drwsurf->size);
drwbuf->buf = drwsurf->buf =
wl_shm_pool_create_buffer(pool, 0, drwsurf->width, drwsurf->height, wl_shm_pool_create_buffer(pool, 0, drwsurf->width, drwsurf->height,
stride, WL_SHM_FORMAT_ARGB8888); stride, WL_SHM_FORMAT_ARGB8888);
wl_shm_pool_destroy(pool); wl_shm_pool_destroy(pool);
close(fd); close(fd);
wl_buffer_add_listener(drwbuf->buf, &buffer_listener, drwsurf);
cairo_surface_t *s = cairo_image_surface_create_for_data(
if (drwbuf->cairo_surf) drwsurf->pool_data, CAIRO_FORMAT_ARGB32, drwsurf->width,
cairo_surface_destroy(drwbuf->cairo_surf);
drwbuf->cairo_surf = cairo_image_surface_create_for_data(
drwbuf->pool_data, CAIRO_FORMAT_ARGB32, drwsurf->width,
drwsurf->height, stride); drwsurf->height, stride);
if (drwbuf->cairo) drwsurf->cairo = cairo_create(s);
cairo_destroy(drwbuf->cairo); cairo_scale(drwsurf->cairo, drwsurf->scale, drwsurf->scale);
drwbuf->cairo = cairo_create(drwbuf->cairo_surf); cairo_set_antialias(drwsurf->cairo, CAIRO_ANTIALIAS_NONE);
cairo_scale(drwbuf->cairo, drwsurf->scale, drwsurf->scale); drwsurf->layout = pango_cairo_create_layout(drwsurf->cairo);
cairo_set_antialias(drwbuf->cairo, CAIRO_ANTIALIAS_NONE); pango_layout_set_auto_dir(drwsurf->layout, false);
drwbuf->layout = pango_cairo_create_layout(drwbuf->cairo); cairo_save(drwsurf->cairo);
pango_layout_set_auto_dir(drwbuf->layout, false);
cairo_save(drwbuf->cairo);
return 0; return 0;
} }

41
drw.h
View File

@@ -7,53 +7,42 @@
struct drw { struct drw {
struct wl_shm *shm; struct wl_shm *shm;
}; };
struct drwbuf {
uint32_t size;
struct wl_buffer *buf;
cairo_surface_t *cairo_surf;
cairo_t *cairo;
PangoLayout *layout;
unsigned char *pool_data;
};
struct drwsurf { struct drwsurf {
uint32_t width, height; uint32_t width, height, size;
double scale; double scale;
struct drw *ctx; struct drw *ctx;
struct wl_surface *surf; struct wl_surface *surf;
struct wl_buffer *buf;
struct wl_shm *shm; struct wl_shm *shm;
struct wl_callback *frame_cb; unsigned char *pool_data;
cairo_region_t *damage, *backport_damage; cairo_t *cairo;
bool attached; PangoLayout *layout;
bool released;
struct drwbuf *back_buffer;
struct drwbuf *display_buffer;
}; };
struct kbd; struct kbd;
void drwsurf_resize(struct drwsurf *ds, uint32_t w, uint32_t h, double s); void drwsurf_resize(struct drwsurf *ds, uint32_t w, uint32_t h, double s);
void drwsurf_attach(struct drwsurf *ds); void drwsurf_flip(struct drwsurf *ds);
typedef union { typedef union {
uint8_t bgra[4]; uint8_t bgra[4];
uint32_t color; uint32_t color;
} Color; } Color;
void drw_do_clear(struct drwsurf *ds, uint32_t x, uint32_t y, void drw_do_clear(struct drwsurf *d, uint32_t x, uint32_t y,
uint32_t w, uint32_t h); uint32_t w, uint32_t h);
void drw_do_rectangle(struct drwsurf *ds, Color color, uint32_t x, uint32_t y, void drw_do_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
uint32_t w, uint32_t h, bool fill, int rounding); uint32_t w, uint32_t h, bool fill);
void drw_fill_rectangle(struct drwsurf *ds, Color color, uint32_t x, uint32_t y, void drw_fill_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
uint32_t w, uint32_t h, int rounding); uint32_t w, uint32_t h);
void drw_over_rectangle(struct drwsurf *ds, Color color, uint32_t x, uint32_t y, void drw_over_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
uint32_t w, uint32_t h, int rounding); uint32_t w, uint32_t h);
void drw_draw_text(struct drwsurf *ds, Color color, uint32_t x, uint32_t y, void drw_draw_text(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
uint32_t w, uint32_t h, uint32_t b, const char *label, uint32_t w, uint32_t h, uint32_t b, const char *label,
PangoFontDescription *font_description); PangoFontDescription *font_description);
uint32_t setup_buffer(struct drwsurf *ds, struct drwbuf *db); uint32_t setup_buffer(struct drwsurf *drwsurf);
#endif #endif

View File

@@ -3,7 +3,6 @@
#include <stddef.h> #include <stddef.h>
#include <stdio.h> #include <stdio.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <ctype.h>
#include "keyboard.h" #include "keyboard.h"
#include "drw.h" #include "drw.h"
#include "os-compatibility.h" #include "os-compatibility.h"
@@ -277,23 +276,13 @@ kbd_get_layer_index(struct kbd *kb, struct layout *l)
void void
kbd_unpress_key(struct kbd *kb, uint32_t time) kbd_unpress_key(struct kbd *kb, uint32_t time)
{ {
bool unlatch_shift, unlatch_ctrl, unlatch_alt, unlatch_super, unlatch_altgr; bool unlatch_shift = false;
unlatch_shift = unlatch_ctrl = unlatch_alt = unlatch_super = unlatch_altgr = false;
if (kb->last_press) { if (kb->last_press) {
unlatch_shift = (kb->mods & Shift) == Shift; unlatch_shift = (kb->mods & Shift) == Shift;
unlatch_ctrl = (kb->mods & Ctrl) == Ctrl;
unlatch_alt = (kb->mods & Alt) == Alt;
unlatch_super = (kb->mods & Super) == Super;
unlatch_altgr = (kb->mods & AltGr) == AltGr;
if (unlatch_shift) kb->mods ^= Shift; if (unlatch_shift) {
if (unlatch_ctrl) kb->mods ^= Ctrl; kb->mods ^= Shift;
if (unlatch_alt) kb->mods ^= Alt;
if (unlatch_super) kb->mods ^= Super;
if (unlatch_altgr) kb->mods ^= AltGr;
if (unlatch_shift||unlatch_ctrl||unlatch_alt||unlatch_super||unlatch_altgr) {
zwp_virtual_keyboard_v1_modifiers(kb->vkbd, kb->mods, 0, 0, 0); zwp_virtual_keyboard_v1_modifiers(kb->vkbd, kb->mods, 0, 0, 0);
} }
@@ -301,7 +290,7 @@ kbd_unpress_key(struct kbd *kb, uint32_t time)
zwp_virtual_keyboard_v1_key(kb->vkbd, time, 127, // COMP key zwp_virtual_keyboard_v1_key(kb->vkbd, time, 127, // COMP key
WL_KEYBOARD_KEY_STATE_RELEASED); WL_KEYBOARD_KEY_STATE_RELEASED);
} else { } else {
if ((kb->shift_space_is_tab) && (kb->last_press->code == KEY_SPACE) && (unlatch_shift)) { if ((kb->last_press->code == KEY_SPACE) && (unlatch_shift)) {
// shift + space is tab // shift + space is tab
zwp_virtual_keyboard_v1_key(kb->vkbd, time, KEY_TAB, zwp_virtual_keyboard_v1_key(kb->vkbd, time, KEY_TAB,
WL_KEYBOARD_KEY_STATE_RELEASED); WL_KEYBOARD_KEY_STATE_RELEASED);
@@ -315,7 +304,7 @@ kbd_unpress_key(struct kbd *kb, uint32_t time)
if (kb->compose >= 2) { if (kb->compose >= 2) {
kb->compose = 0; kb->compose = 0;
kbd_switch_layout(kb, kb->last_abc_layout, kb->last_abc_index); kbd_switch_layout(kb, kb->last_abc_layout, kb->last_abc_index);
} else if (unlatch_shift||unlatch_ctrl||unlatch_alt||unlatch_super||unlatch_altgr) { } else if (unlatch_shift) {
kbd_draw_layout(kb); kbd_draw_layout(kb);
} else { } else {
kbd_draw_key(kb, kb->last_press, Unpress); kbd_draw_key(kb, kb->last_press, Unpress);
@@ -337,7 +326,10 @@ kbd_release_key(struct kbd *kb, uint32_t time)
kb->last_swipe = NULL; kb->last_swipe = NULL;
} }
drwsurf_flip(kb->surf);
kbd_clear_last_popup(kb); kbd_clear_last_popup(kb);
drwsurf_flip(kb->popup_surf);
} }
void void
@@ -363,7 +355,10 @@ kbd_motion_key(struct kbd *kb, uint32_t time, uint32_t x, uint32_t y)
kbd_unpress_key(kb, time); kbd_unpress_key(kb, time);
} }
drwsurf_flip(kb->surf);
kbd_clear_last_popup(kb); kbd_clear_last_popup(kb);
drwsurf_flip(kb->popup_surf);
} }
void void
@@ -404,7 +399,7 @@ kbd_press_key(struct kbd *kb, struct key *k, uint32_t time)
} }
kb->last_swipe = kb->last_press = k; kb->last_swipe = kb->last_press = k;
kbd_draw_key(kb, k, Press); kbd_draw_key(kb, k, Press);
if ((kb->shift_space_is_tab) && (k->code == KEY_SPACE) && (kb->mods & Shift)) { if ((k->code == KEY_SPACE) && (kb->mods & Shift)) {
// shift space is tab // shift space is tab
zwp_virtual_keyboard_v1_modifiers(kb->vkbd, 0, 0, 0, 0); zwp_virtual_keyboard_v1_modifiers(kb->vkbd, 0, 0, 0, 0);
zwp_virtual_keyboard_v1_key(kb->vkbd, time, KEY_TAB, zwp_virtual_keyboard_v1_key(kb->vkbd, time, KEY_TAB,
@@ -423,7 +418,7 @@ kbd_press_key(struct kbd *kb, struct key *k, uint32_t time)
break; break;
case Mod: case Mod:
kb->mods ^= k->code; kb->mods ^= k->code;
if ((k->code == Shift) || (k->code == CapsLock)) { if (k->code == Shift) {
kbd_draw_layout(kb); kbd_draw_layout(kb);
} else { } else {
if (kb->mods & k->code) { if (kb->mods & k->code) {
@@ -495,6 +490,9 @@ kbd_press_key(struct kbd *kb, struct key *k, uint32_t time)
default: default:
break; break;
} }
drwsurf_flip(kb->surf);
drwsurf_flip(kb->popup_surf);
} }
void void
@@ -529,8 +527,7 @@ kbd_print_key_stdout(struct kbd *kb, struct key *k)
} }
if (!handled) { if (!handled) {
if ((kb->mods & Shift) || if ((kb->mods & Shift) || (kb->mods & CapsLock))
((kb->mods & CapsLock) & (strlen(k->label) == 1 && isalpha(k->label[0]))))
printf("%s", k->shift_label); printf("%s", k->shift_label);
else if (!(kb->mods & Ctrl) && !(kb->mods & Alt) && !(kb->mods & Super)) else if (!(kb->mods & Ctrl) && !(kb->mods & Alt) && !(kb->mods & Super))
printf("%s", k->label); printf("%s", k->label);
@@ -544,6 +541,9 @@ kbd_clear_last_popup(struct kbd *kb)
if (kb->last_popup_w && kb->last_popup_h) { if (kb->last_popup_w && kb->last_popup_h) {
drw_do_clear(kb->popup_surf, kb->last_popup_x, kb->last_popup_y, drw_do_clear(kb->popup_surf, kb->last_popup_x, kb->last_popup_y,
kb->last_popup_w, kb->last_popup_h); kb->last_popup_w, kb->last_popup_h);
wl_surface_damage(kb->popup_surf->surf, kb->last_popup_x,
kb->last_popup_y, kb->last_popup_w, kb->last_popup_h);
kb->last_popup_w = kb->last_popup_h = 0; kb->last_popup_w = kb->last_popup_h = 0;
} }
} }
@@ -551,8 +551,7 @@ kbd_clear_last_popup(struct kbd *kb)
void void
kbd_draw_key(struct kbd *kb, struct key *k, enum key_draw_type type) kbd_draw_key(struct kbd *kb, struct key *k, enum key_draw_type type)
{ {
const char *label = ((kb->mods & Shift)||((kb->mods & CapsLock) && const char *label = (kb->mods & Shift) ? k->shift_label : k->label;
strlen(k->label) == 1 && isalpha(k->label[0]))) ? k->shift_label : k->label;
if (kb->debug) if (kb->debug)
fprintf(stderr, "Draw key +%d+%d %dx%d -> %s\n", k->x, k->y, k->w, k->h, fprintf(stderr, "Draw key +%d+%d %dx%d -> %s\n", k->x, k->y, k->w, k->h,
label); label);
@@ -562,20 +561,21 @@ kbd_draw_key(struct kbd *kb, struct key *k, enum key_draw_type type)
case None: case None:
case Unpress: case Unpress:
draw_inset(kb->surf, k->x, k->y, k->w, k->h, KBD_KEY_BORDER, draw_inset(kb->surf, k->x, k->y, k->w, k->h, KBD_KEY_BORDER,
scheme->fg, scheme->rounding); scheme->fg);
break; break;
case Press: case Press:
draw_inset(kb->surf, k->x, k->y, k->w, k->h, KBD_KEY_BORDER, draw_inset(kb->surf, k->x, k->y, k->w, k->h, KBD_KEY_BORDER,
scheme->high, scheme->rounding); scheme->high);
break; break;
case Swipe: case Swipe:
draw_over_inset(kb->surf, k->x, k->y, k->w, k->h, KBD_KEY_BORDER, draw_over_inset(kb->surf, k->x, k->y, k->w, k->h, KBD_KEY_BORDER,
scheme->swipe, scheme->rounding); scheme->swipe);
break; break;
} }
drw_draw_text(kb->surf, scheme->text, k->x, k->y, k->w, k->h, drw_draw_text(kb->surf, scheme->text, k->x, k->y, k->w, k->h,
KBD_KEY_BORDER, label, scheme->font_description); KBD_KEY_BORDER, label, scheme->font_description);
wl_surface_damage(kb->surf->surf, k->x, k->y, k->w, k->h);
if (type == Press || type == Unpress) { if (type == Press || type == Unpress) {
kbd_clear_last_popup(kb); kbd_clear_last_popup(kb);
@@ -586,12 +586,14 @@ kbd_draw_key(struct kbd *kb, struct key *k, enum key_draw_type type)
kb->last_popup_h = k->h; kb->last_popup_h = k->h;
drw_fill_rectangle(kb->popup_surf, scheme->bg, k->x, drw_fill_rectangle(kb->popup_surf, scheme->bg, k->x,
kb->last_popup_y, k->w, k->h, scheme->rounding); kb->last_popup_y, k->w, k->h);
draw_inset(kb->popup_surf, k->x, kb->last_popup_y, k->w, k->h, draw_inset(kb->popup_surf, k->x, kb->last_popup_y, k->w, k->h,
KBD_KEY_BORDER, scheme->high, scheme->rounding); KBD_KEY_BORDER, scheme->high);
drw_draw_text(kb->popup_surf, scheme->text, k->x, kb->last_popup_y, drw_draw_text(kb->popup_surf, scheme->text, k->x, kb->last_popup_y,
k->w, k->h, KBD_KEY_BORDER, label, k->w, k->h, KBD_KEY_BORDER, label,
scheme->font_description); scheme->font_description);
wl_surface_damage(kb->popup_surf->surf, k->x, kb->last_popup_y, k->w,
k->h);
} }
} }
@@ -603,7 +605,7 @@ kbd_draw_layout(struct kbd *kb)
if (kb->debug) if (kb->debug)
fprintf(stderr, "Draw layout\n"); fprintf(stderr, "Draw layout\n");
drw_fill_rectangle(d, kb->schemes[0].bg, 0, 0, kb->w, kb->h, 0); drw_fill_rectangle(d, kb->schemes[0].bg, 0, 0, kb->w, kb->h);
while (next_key->type != Last) { while (next_key->type != Last) {
if ((next_key->type == Pad) || (next_key->type == EndRow)) { if ((next_key->type == Pad) || (next_key->type == EndRow)) {
@@ -618,6 +620,7 @@ kbd_draw_layout(struct kbd *kb)
} }
next_key++; next_key++;
} }
wl_surface_damage(d->surf, 0, 0, kb->w, kb->h);
} }
void void
@@ -644,17 +647,17 @@ kbd_resize(struct kbd *kb, struct layout *layouts, uint8_t layoutcount)
void void
draw_inset(struct drwsurf *ds, uint32_t x, uint32_t y, uint32_t width, draw_inset(struct drwsurf *ds, uint32_t x, uint32_t y, uint32_t width,
uint32_t height, uint32_t border, Color color, int rounding) uint32_t height, uint32_t border, Color color)
{ {
drw_fill_rectangle(ds, color, x + border, y + border, width - (border * 2), drw_fill_rectangle(ds, color, x + border, y + border, width - (border * 2),
height - (border * 2), rounding); height - (border * 2));
} }
void void
draw_over_inset(struct drwsurf *ds, uint32_t x, uint32_t y, uint32_t width, draw_over_inset(struct drwsurf *ds, uint32_t x, uint32_t y, uint32_t width,
uint32_t height, uint32_t border, Color color, int rounding) uint32_t height, uint32_t border, Color color)
{ {
drw_over_rectangle(ds, color, x + border, y + border, width - (border * 2), drw_over_rectangle(ds, color, x + border, y + border, width - (border * 2),
height - (border * 2), rounding); height - (border * 2));
} }
void void
@@ -675,7 +678,7 @@ create_and_upload_keymap(struct kbd *kb, const char *name, uint32_t comp_unichr,
size_t keymap_size = strlen(keymap_template) + 64; size_t keymap_size = strlen(keymap_template) + 64;
char *keymap_str = malloc(keymap_size); char *keymap_str = malloc(keymap_size);
sprintf(keymap_str, keymap_template, comp_unichr, comp_shift_unichr); sprintf(keymap_str, keymap_template, comp_unichr, comp_shift_unichr);
keymap_size = strlen(keymap_str); keymap_size = strlen(keymap_str) + 1;
int keymap_fd = os_create_anonymous_file(keymap_size); int keymap_fd = os_create_anonymous_file(keymap_size);
if (keymap_fd < 0) { if (keymap_fd < 0) {
die("could not create keymap fd\n"); die("could not create keymap fd\n");

View File

@@ -55,7 +55,6 @@ struct clr_scheme {
Color swipe; Color swipe;
Color text; Color text;
char *font; char *font;
int rounding;
PangoFontDescription *font_description; PangoFontDescription *font_description;
}; };
@@ -101,8 +100,6 @@ struct kbd {
double scale; double scale;
double preferred_scale, preferred_fractional_scale; double preferred_scale, preferred_fractional_scale;
bool landscape; bool landscape;
bool shift_space_is_tab;
bool exclusive;
uint8_t mods; uint8_t mods;
uint8_t compose; uint8_t compose;
struct key *last_press; struct key *last_press;
@@ -113,7 +110,6 @@ struct kbd {
size_t last_abc_index; //the layer index of the last alphabetical layout size_t last_abc_index; //the layer index of the last alphabetical layout
struct layout *layouts; struct layout *layouts;
struct Output *output; //only used to keep track of landscape flipping, never dereferenced
enum layout_id *layers; enum layout_id *layers;
enum layout_id *landscape_layers; enum layout_id *landscape_layers;
@@ -125,9 +121,9 @@ struct kbd {
}; };
void draw_inset(struct drwsurf *ds, uint32_t x, uint32_t y, uint32_t width, void draw_inset(struct drwsurf *ds, uint32_t x, uint32_t y, uint32_t width,
uint32_t height, uint32_t border, Color color, int rounding); uint32_t height, uint32_t border, Color color);
void draw_over_inset(struct drwsurf *ds, uint32_t x, uint32_t y, uint32_t width, void draw_over_inset(struct drwsurf *ds, uint32_t x, uint32_t y, uint32_t width,
uint32_t height, uint32_t border, Color color, int rounding); uint32_t height, uint32_t border, Color color);
void kbd_init(struct kbd *kb, struct layout *layouts, void kbd_init(struct kbd *kb, struct layout *layouts,
char *layer_names_list, char *landscape_layer_names_list); char *layer_names_list, char *landscape_layer_names_list);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1626,8 +1626,7 @@ static struct key keys_compose_cyr_tse[] = {
static struct key keys_compose_cyr_g[] = { static struct key keys_compose_cyr_g[] = {
{"ѓ", "Ѓ", 1.0, Copy, 0x0453, 0, 0x0403}, {"ѓ", "Ѓ", 1.0, Copy, 0x0453, 0, 0x0403},
{"ґ", "Ґ", 1.0, Copy, 0x0491, 0, 0x0490}, {"", "", 9.0, Pad},
{"", "", 8.0, Pad},
{"", "", 0.0, EndRow}, {"", "", 0.0, EndRow},
{"", "", 0.0, EndRow}, {"", "", 0.0, EndRow},
{"", "", 1.5, Mod, Shift, .scheme = 1}, {"", "", 1.5, Mod, Shift, .scheme = 1},

81
main.c
View File

@@ -28,7 +28,7 @@
#define countof(x) (sizeof(x) / sizeof(*x)) #define countof(x) (sizeof(x) / sizeof(*x))
/* client state */ /* client state */
static const char *namespace = "wvkbd"; static const char *namespace = "wlroots";
static struct wl_display *display; static struct wl_display *display;
static struct wl_compositor *compositor; static struct wl_compositor *compositor;
static struct wl_seat *seat; static struct wl_seat *seat;
@@ -62,11 +62,10 @@ static int wl_outputs_size;
/* drawing */ /* drawing */
static struct drw draw_ctx; static struct drw draw_ctx;
static struct drwbuf draw_surf_back_buffer, draw_surf_display_buffer, popup_draw_surf_back_buffer, popup_draw_surf_display_buffer;
static struct drwsurf draw_surf, popup_draw_surf; static struct drwsurf draw_surf, popup_draw_surf;
/* layer surface parameters */ /* layer surface parameters */
static uint32_t layer = ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY; static uint32_t layer = ZWLR_LAYER_SHELL_V1_LAYER_TOP;
static uint32_t anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | static uint32_t anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM |
ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT |
ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
@@ -77,7 +76,6 @@ static int cur_x = -1, cur_y = -1;
static bool cur_press = false; static bool cur_press = false;
static struct kbd keyboard; static struct kbd keyboard;
static uint32_t height, normal_height, landscape_height; static uint32_t height, normal_height, landscape_height;
static int rounding = DEFAULT_ROUNDING;
static bool hidden = false; static bool hidden = false;
/* event handler prototypes */ /* event handler prototypes */
@@ -133,7 +131,6 @@ static void layer_surface_configure(void *data,
static void layer_surface_closed(void *data, static void layer_surface_closed(void *data,
struct zwlr_layer_surface_v1 *surface); struct zwlr_layer_surface_v1 *surface);
static void flip_landscape(); static void flip_landscape();
static void show();
/* event handlers */ /* event handlers */
static const struct wl_pointer_listener pointer_listener = { static const struct wl_pointer_listener pointer_listener = {
@@ -333,6 +330,7 @@ wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, uint32_t time,
} }
kbd_next_layer(&keyboard, NULL, (value >= 0)); kbd_next_layer(&keyboard, NULL, (value >= 0));
drwsurf_flip(keyboard.surf);
} }
void void
@@ -517,7 +515,7 @@ xdg_popup_surface_configure(void *data, struct xdg_surface *xdg_surface,
{ {
xdg_surface_ack_configure(xdg_surface, serial); xdg_surface_ack_configure(xdg_surface, serial);
popup_xdg_surface_configured = true; popup_xdg_surface_configured = true;
drwsurf_attach(&popup_draw_surf); drwsurf_flip(&popup_draw_surf);
} }
static const struct xdg_surface_listener xdg_popup_surface_listener = { static const struct xdg_surface_listener xdg_popup_surface_listener = {
@@ -561,7 +559,12 @@ flip_landscape()
if (current_output) { if (current_output) {
keyboard.landscape = current_output->w > current_output->h; keyboard.landscape = current_output->w > current_output->h;
} else if (wl_outputs_size) { } else if (wl_outputs_size) {
keyboard.landscape = wl_outputs[0].w > wl_outputs[0].h; for (int i = 0; i < wl_outputs_size; i += 1) {
if (wl_outputs[i].w > wl_outputs[i].h) {
keyboard.landscape = true;
break;
}
}
} }
enum layout_id layer; enum layout_id layer;
@@ -579,25 +582,10 @@ flip_landscape()
keyboard.last_abc_layout = keyboard.layout; keyboard.last_abc_layout = keyboard.layout;
keyboard.last_abc_index = 0; keyboard.last_abc_index = 0;
if (layer_surface && previous_landscape != keyboard.landscape) { if (layer_surface) {
if (popup_xdg_popup) { zwlr_layer_surface_v1_set_size(layer_surface, 0, height);
xdg_popup_destroy(popup_xdg_popup); zwlr_layer_surface_v1_set_exclusive_zone(layer_surface, height);
popup_xdg_popup = NULL; wl_surface_commit(draw_surf.surf);
}
if (popup_xdg_surface) {
xdg_surface_destroy(popup_xdg_surface);
popup_xdg_surface = NULL;
}
if (popup_draw_surf.surf) {
wl_surface_destroy(popup_draw_surf.surf);
popup_draw_surf.surf = NULL;
}
zwlr_layer_surface_v1_destroy(layer_surface);
layer_surface = NULL;
wl_surface_destroy(draw_surf.surf);
show();
} }
} }
@@ -611,7 +599,7 @@ layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface,
} }
if (keyboard.w != w || keyboard.h != h || keyboard.scale != scale || if (keyboard.w != w || keyboard.h != h || keyboard.scale != scale ||
keyboard.output != current_output || hidden) { hidden) {
keyboard.w = w; keyboard.w = w;
keyboard.h = h; keyboard.h = h;
@@ -664,8 +652,7 @@ layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface,
zwlr_layer_surface_v1_ack_configure(surface, serial); zwlr_layer_surface_v1_ack_configure(surface, serial);
kbd_resize(&keyboard, layouts, NumLayouts); kbd_resize(&keyboard, layouts, NumLayouts);
drwsurf_attach(&draw_surf); drwsurf_flip(&draw_surf);
keyboard.output = current_output;
} else { } else {
zwlr_layer_surface_v1_ack_configure(surface, serial); zwlr_layer_surface_v1_ack_configure(surface, serial);
} }
@@ -693,7 +680,6 @@ usage(char *argv0)
" -O - Print intersected keys to standard output\n"); " -O - Print intersected keys to standard output\n");
fprintf(stderr, " -H [int] - Height in pixels\n"); fprintf(stderr, " -H [int] - Height in pixels\n");
fprintf(stderr, " -L [int] - Landscape height in pixels\n"); fprintf(stderr, " -L [int] - Landscape height in pixels\n");
fprintf(stderr, " -R [int] - Rounding radius in pixels\n");
fprintf(stderr, " --fn [font] - Set font (e.g: DejaVu Sans 20)\n"); fprintf(stderr, " --fn [font] - Set font (e.g: DejaVu Sans 20)\n");
fprintf(stderr, " --hidden - Start hidden (send SIGUSR2 to show)\n"); fprintf(stderr, " --hidden - Start hidden (send SIGUSR2 to show)\n");
fprintf( fprintf(
@@ -717,9 +703,6 @@ usage(char *argv0)
" -l - Comma separated list of layers\n"); " -l - Comma separated list of layers\n");
fprintf(stderr, " --landscape-layers - Comma separated list of " fprintf(stderr, " --landscape-layers - Comma separated list of "
"landscape layers\n"); "landscape layers\n");
fprintf(stderr, " --non-exclusive - Allow the keyboard to overlap"
" windows. Do not request an exclusive zone from the"
"compositor\n");
} }
void void
@@ -786,9 +769,7 @@ show()
zwlr_layer_surface_v1_set_size(layer_surface, 0, height); zwlr_layer_surface_v1_set_size(layer_surface, 0, height);
zwlr_layer_surface_v1_set_anchor(layer_surface, anchor); zwlr_layer_surface_v1_set_anchor(layer_surface, anchor);
if (keyboard.exclusive) { zwlr_layer_surface_v1_set_exclusive_zone(layer_surface, height);
zwlr_layer_surface_v1_set_exclusive_zone(layer_surface, height);
}
zwlr_layer_surface_v1_set_keyboard_interactivity(layer_surface, false); zwlr_layer_surface_v1_set_keyboard_interactivity(layer_surface, false);
zwlr_layer_surface_v1_add_listener(layer_surface, &layer_surface_listener, zwlr_layer_surface_v1_add_listener(layer_surface, &layer_surface_listener,
NULL); NULL);
@@ -816,7 +797,7 @@ set_kbd_colors(uint8_t *bgra, char *hex)
// bg, fg, text, high, swipe // bg, fg, text, high, swipe
int length = strlen(hex); int length = strlen(hex);
if (length == 6 || length == 8) { if (length == 6 || length == 8) {
char subhex[3] = { 0 }; char subhex[2];
memcpy(subhex, hex, 2); memcpy(subhex, hex, 2);
bgra[2] = (int)strtol(subhex, NULL, 16); bgra[2] = (int)strtol(subhex, NULL, 16);
memcpy(subhex, hex + 2, 2); memcpy(subhex, hex + 2, 2);
@@ -857,7 +838,6 @@ main(int argc, char **argv)
keyboard.layer_index = 0; keyboard.layer_index = 0;
keyboard.preferred_scale = 1; keyboard.preferred_scale = 1;
keyboard.preferred_fractional_scale = 0; keyboard.preferred_fractional_scale = 0;
keyboard.exclusive = true;
uint8_t alpha = 0; uint8_t alpha = 0;
bool alpha_defined = false; bool alpha_defined = false;
@@ -968,12 +948,6 @@ main(int argc, char **argv)
exit(1); exit(1);
} }
height = landscape_height = atoi(argv[++i]); height = landscape_height = atoi(argv[++i]);
} else if (!strcmp(argv[i], "-R")) {
if (i >= argc - 1) {
usage(argv[0]);
exit(1);
}
rounding = atoi(argv[++i]);
} else if (!strcmp(argv[i], "-D")) { } else if (!strcmp(argv[i], "-D")) {
keyboard.debug = true; keyboard.debug = true;
} else if ((!strcmp(argv[i], "-fn")) || (!strcmp(argv[i], "--fn"))) { } else if ((!strcmp(argv[i], "-fn")) || (!strcmp(argv[i], "--fn"))) {
@@ -993,8 +967,6 @@ main(int argc, char **argv)
(!strcmp(argv[i], "--list-layers"))) { (!strcmp(argv[i], "--list-layers"))) {
list_layers(); list_layers();
exit(0); exit(0);
} else if ((!strcmp(argv[i], "-non-exclusive")) || (!strcmp(argv[i], "--non-exclusive"))) {
keyboard.exclusive = false;
} else { } else {
fprintf(stderr, "Invalid argument: %s\n", argv[i]); fprintf(stderr, "Invalid argument: %s\n", argv[i]);
usage(argv[0]); usage(argv[0]);
@@ -1016,22 +988,13 @@ main(int argc, char **argv)
schemes[i].font = fc_font_pattern; schemes[i].font = fc_font_pattern;
} }
if (rounding != DEFAULT_ROUNDING) {
for (i = 0; i < countof(schemes); i++)
schemes[i].rounding = rounding;
}
display = wl_display_connect(NULL); display = wl_display_connect(NULL);
if (display == NULL) { if (display == NULL) {
die("Failed to create display\n"); die("Failed to create display\n");
} }
draw_surf.ctx = &draw_ctx; draw_surf.ctx = &draw_ctx;
draw_surf.back_buffer = &draw_surf_back_buffer;
draw_surf.display_buffer = &draw_surf_display_buffer;
popup_draw_surf.ctx = &draw_ctx; popup_draw_surf.ctx = &draw_ctx;
popup_draw_surf.back_buffer = &popup_draw_surf_back_buffer;
popup_draw_surf.display_buffer = &popup_draw_surf_display_buffer;
keyboard.surf = &draw_surf; keyboard.surf = &draw_surf;
keyboard.popup_surf = &popup_draw_surf; keyboard.popup_surf = &popup_draw_surf;
@@ -1055,9 +1018,6 @@ main(int argc, char **argv)
die("virtual_keyboard_manager not available\n"); die("virtual_keyboard_manager not available\n");
} }
// A second round-trip to receive wl_outputs events
wl_display_roundtrip(display);
empty_region = wl_compositor_create_region(compositor); empty_region = wl_compositor_create_region(compositor);
popup_xdg_positioner = xdg_wm_base_create_positioner(wm_base); popup_xdg_positioner = xdg_wm_base_create_positioner(wm_base);
@@ -1066,11 +1026,6 @@ main(int argc, char **argv)
if (keyboard.vkbd == NULL) { if (keyboard.vkbd == NULL) {
die("failed to init virtual keyboard_manager\n"); die("failed to init virtual keyboard_manager\n");
} }
#ifdef SHIFT_SPACE_IS_TAB
keyboard.shift_space_is_tab = true;
#else
keyboard.shift_space_is_tab = false;
#endif
kbd_init(&keyboard, (struct layout *)&layouts, layer_names_list, kbd_init(&keyboard, (struct layout *)&layouts, layer_names_list,
landscape_layer_names_list); landscape_layer_names_list);

76
wvkbd.1 Normal file
View File

@@ -0,0 +1,76 @@
.TH "wvkbd" "1" "2022-03-12"
.P
.SH NAME
.P
wvkbd - on-screen keyboard for wlroots
.P
.SH SYNOPSIS
.P
wvkbd-mobintl [OPTION]...
.P
.SH DESCRIPTION
.P
wvkbd is an on-screen keyboard for wlroots that sucks less.
.P
.SH OPTIONS
.P
\fB-D\fR
.RS 4
enable debug
.P
.RE
\fB-o\fR
.RS 4
print pressed keys to standard output
.P
.RE
\fB-O\fR
.RS 4
print intersected keys to standard output
.P
.RE
\fB-l\fR
.RS 4
comma separated list of layers
.P
.RE
\fB--landscape-layers\fR
.RS 4
comma separated list of layers used in landscape mode
.P
.RE
\fB-H\fR \fIPX\fR
.RS 4
height in pixels
.P
.RE
\fB-L\fR \fIPX\fR
.RS 4
landscape height in pixels
.P
.RE
\fB--fn\fR \fIFONT\fR
.RS 4
set font (e.g: DejaVu Sans 20)
.P
.RE
\fB--hidden\fR
.RS 4
start hidden (send SIGUSR2 to show, SIGUSR1 to hide, SIGRTMIN to toggle)
.P
.RE
\fB-v\fR, \fB--version\fR
.RS 4
print version
.P
.RE
\fB-h\fR, \fB--help\fR
.RS 4
show help
.P
.RE
.SH AUTHORS
.P
Created by John Sullivan <jsullivan@csumb.edu>, maintained by the Sxmo project in
collaboration with other open source contributors. For more information about wvkbd development, see
<https://git.sr.ht/~proycon/wvkbd> or <https://github.com/jjsullivan5196/wvkbd>.

View File

@@ -1,134 +0,0 @@
wvkbd(1)
# NAME
wvkbd - on-screen virtual keyboard for wayland compositors using wlroots
# SYNOPSIS
wvkbd-mobintl [OPTIONS]...
wvkbd-deskintl [OPTIONS]...
*NOTE*: Your binary may have a different suffix depending on which layout you compiled.
# DESCRIPTION
This project aims to deliver a minimal but practically usable implementation of
a wlroots on-screen keyboard in legible C. This will _only_ be a keyboard, not
a feedback buzzer, led blinker, or anything that requires more than what's
needed to input text quickly. The end product should be a static codebase that
can be patched to add new features.
## OPTIONS
*-D*
enable debug mode.
*-o*
print pressed keys to standard output.
*-O*
print intersected keys to standard output.
*-l* _layers_
comma separated list of layers in vertical/portrait mode.
*--landscape-layers* _layers_
comma separated list of layers used in horizontal/landscape mode.
*--list-layers*
prints a list of all available layers.
*-H* _pixels_
Height of the keyboard in pixels, for vertical/portrait mode.
*-L* _pixels_
Height of the keyboard in pixels, for horizontal/landscape mode
*--fn* _font_
set font and size (e.g. DejaVu Sans 20)
*--hidden*
Start hidden (send SIGUSR2 to show).
*--non-exclusive*
Allow keyboard to overlap existing windows, do not request an
exclusive zone from the compositor.
*--alpha* _int_
Set alpha value (i.e. transparency) for all colors [0-255]
*--bg* _rrggbb|aa_
Set color of background
*--fg* _rrggbb|aa_
Set color of keys
*--fg-sp* _rrggbb|aa_
Set color of special keys
*--press* _rrggbb|aa_
Set color of pressed keys
*--press-sp* _rrggbb|aa_
Set color of pressed special keys
*--swipe* _rrggbb|aa_
Set color of swiped keys
*--swipe-sp* _rrggbb|aa_
Set color of swiped special keys
*--text* _rrggbb|aa_
Set color text on keys
*--text-sp* _rrggbb|aa_
Set color text on special keys
*--version*
Print version information
*-h*, *--help*
Print usage help
# SIGNALS
You can send signals to wvkbd to hide/show it (e.g. using _kill_(1) with _-s_):
*SIGUSR1*
Hide the keyboard.
*SIGUSR2*
Show the keyboard
*SIGRTMIN*
Toggle visibility
# COMPOSE BUTTON
The default mobile international layout features a Compose button (*Cmp*)
which, when combined with another key, opens up a layout that offers variants
for that key. This is similar to functionality that other keyboards implemented
using a *long press* (wvkbd has no such notion, holding a key will repeat
it like on a physical keyboard).
For example, press Cmp + a to access variants with diacritics like á,à,â,ä, etc..
Most layouts also feature the following that are less obvious:
- Press Cmp and . to access more punctuation
- Press Cmp and - or , to access 'mathematical' symbols (+,-,=,etc)
- Press Cmp and ' or 0 or 9 to access more brackets and quotes
- Press Cmp and q to access emojis
Last, but not least, pressing Cmp + space or Cmp + ⌨ or Cmp + Abc opens up an
index that allows you to immediately jump to any layout by name, even layouts
not explicitly added to your layers on startup.
# AUTHORS
Created by John Sullivan <jsullivan@csumb.edu>, maintained by the Sxmo project
<https://sxmo.org> in collaboration with other open source contributors. For
more information about wvkbd development, see <https://git.sr.ht/~proycon/wvkbd>
or <https://github.com/jjsullivan5196/wvkbd>.