mirror of
https://github.com/jjsullivan5196/wvkbd.git
synced 2026-01-30 23:17:58 +01:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
764c39633a |
22
.build.yml
22
.build.yml
@@ -1,22 +0,0 @@
|
|||||||
arch: x86_64
|
|
||||||
image: alpine/edge
|
|
||||||
packages:
|
|
||||||
- fontconfig
|
|
||||||
- wayland-dev
|
|
||||||
- libxkbcommon-dev
|
|
||||||
- pango-dev
|
|
||||||
- scdoc
|
|
||||||
- clang21-extra-tools # needed for formatting
|
|
||||||
sources:
|
|
||||||
- https://git.sr.ht/~proycon/wvkbd
|
|
||||||
triggers:
|
|
||||||
- action: email
|
|
||||||
condition: failure
|
|
||||||
to: "~mil/sxmo-devel@lists.sr.ht"
|
|
||||||
tasks:
|
|
||||||
- format: |
|
|
||||||
cd wvkbd
|
|
||||||
make format
|
|
||||||
- build: |
|
|
||||||
cd wvkbd
|
|
||||||
make
|
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -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
|
|
||||||
|
|||||||
17
Makefile
17
Makefile
@@ -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
|
||||||
|
|||||||
22
README.md
22
README.md
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
VERSION = 0.19
|
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
218
drw.c
@@ -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
41
drw.h
@@ -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
|
||||||
|
|||||||
120
keyboard.c
120
keyboard.c
@@ -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"
|
||||||
@@ -274,44 +273,25 @@ kbd_get_layer_index(struct kbd *kb, struct layout *l)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
zwp_virtual_keyboard_v1_key_mods(struct zwp_virtual_keyboard_v1 *vkbd, uint32_t time, uint32_t mods, enum wl_keyboard_key_state state)
|
|
||||||
{
|
|
||||||
if ((mods & Shift) == Shift)
|
|
||||||
zwp_virtual_keyboard_v1_key(vkbd, time, KEY_LEFTSHIFT, state);
|
|
||||||
if ((mods & CapsLock) == CapsLock)
|
|
||||||
zwp_virtual_keyboard_v1_key(vkbd, time, KEY_CAPSLOCK, state);
|
|
||||||
if ((mods & Ctrl) == Ctrl)
|
|
||||||
zwp_virtual_keyboard_v1_key(vkbd, time, KEY_LEFTCTRL, state);
|
|
||||||
if ((mods & Alt) == Alt)
|
|
||||||
zwp_virtual_keyboard_v1_key(vkbd, time, KEY_LEFTALT, state);
|
|
||||||
if ((mods & Super) == Super)
|
|
||||||
zwp_virtual_keyboard_v1_key(vkbd, time, KEY_LEFTMETA, state);
|
|
||||||
if ((mods & AltGr) == AltGr)
|
|
||||||
zwp_virtual_keyboard_v1_key(vkbd, time, KEY_RIGHTALT, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
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, unlatch_tab;
|
bool unlatch_shift = false;
|
||||||
unlatch_shift = unlatch_ctrl = unlatch_alt = unlatch_super = unlatch_altgr = unlatch_tab = 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;
|
if (unlatch_shift) {
|
||||||
unlatch_super = (kb->mods & Super) == Super;
|
kb->mods ^= Shift;
|
||||||
unlatch_altgr = (kb->mods & AltGr) == AltGr;
|
zwp_virtual_keyboard_v1_modifiers(kb->vkbd, kb->mods, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (kb->last_press->type == Copy) {
|
if (kb->last_press->type == Copy) {
|
||||||
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
|
||||||
unlatch_shift = false;
|
|
||||||
unlatch_tab = true;
|
|
||||||
kb->mods ^= Shift;
|
|
||||||
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);
|
||||||
} else {
|
} else {
|
||||||
@@ -321,35 +301,10 @@ kbd_unpress_key(struct kbd *kb, uint32_t time)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlatch_shift) {
|
|
||||||
kb->mods ^= Shift;
|
|
||||||
zwp_virtual_keyboard_v1_key_mods(kb->vkbd, time, Shift, WL_KEYBOARD_KEY_STATE_RELEASED);
|
|
||||||
}
|
|
||||||
if (unlatch_ctrl) {
|
|
||||||
kb->mods ^= Ctrl;
|
|
||||||
zwp_virtual_keyboard_v1_key_mods(kb->vkbd, time, Ctrl, WL_KEYBOARD_KEY_STATE_RELEASED);
|
|
||||||
}
|
|
||||||
if (unlatch_alt) {
|
|
||||||
kb->mods ^= Alt;
|
|
||||||
zwp_virtual_keyboard_v1_key_mods(kb->vkbd, time, Alt, WL_KEYBOARD_KEY_STATE_RELEASED);
|
|
||||||
}
|
|
||||||
if (unlatch_super) {
|
|
||||||
kb->mods ^= Super;
|
|
||||||
zwp_virtual_keyboard_v1_key_mods(kb->vkbd, time, Super, WL_KEYBOARD_KEY_STATE_RELEASED);
|
|
||||||
}
|
|
||||||
if (unlatch_altgr) {
|
|
||||||
kb->mods ^= AltGr;
|
|
||||||
zwp_virtual_keyboard_v1_key_mods(kb->vkbd, time, AltGr, WL_KEYBOARD_KEY_STATE_RELEASED);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unlatch_shift||unlatch_ctrl||unlatch_alt||unlatch_super||unlatch_altgr||unlatch_tab) {
|
|
||||||
zwp_virtual_keyboard_v1_modifiers(kb->vkbd, kb->mods, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
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||unlatch_tab) {
|
} 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);
|
||||||
@@ -371,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
|
||||||
@@ -397,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
|
||||||
@@ -426,7 +387,6 @@ kbd_press_key(struct kbd *kb, struct key *k, uint32_t time)
|
|||||||
switch (k->type) {
|
switch (k->type) {
|
||||||
case Code:
|
case Code:
|
||||||
if (k->code_mod) {
|
if (k->code_mod) {
|
||||||
zwp_virtual_keyboard_v1_key_mods(kb->vkbd, time, k->code_mod, WL_KEYBOARD_KEY_STATE_PRESSED);
|
|
||||||
if (k->reset_mod) {
|
if (k->reset_mod) {
|
||||||
zwp_virtual_keyboard_v1_modifiers(kb->vkbd, k->code_mod, 0, 0,
|
zwp_virtual_keyboard_v1_modifiers(kb->vkbd, k->code_mod, 0, 0,
|
||||||
0);
|
0);
|
||||||
@@ -439,10 +399,9 @@ 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_key_mods(kb->vkbd, time, Shift, WL_KEYBOARD_KEY_STATE_RELEASED);
|
zwp_virtual_keyboard_v1_modifiers(kb->vkbd, 0, 0, 0, 0);
|
||||||
zwp_virtual_keyboard_v1_modifiers(kb->vkbd, kb->mods ^ Shift, 0, 0, 0);
|
|
||||||
zwp_virtual_keyboard_v1_key(kb->vkbd, time, KEY_TAB,
|
zwp_virtual_keyboard_v1_key(kb->vkbd, time, KEY_TAB,
|
||||||
WL_KEYBOARD_KEY_STATE_PRESSED);
|
WL_KEYBOARD_KEY_STATE_PRESSED);
|
||||||
} else {
|
} else {
|
||||||
@@ -459,12 +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 (kb->mods & k->code) {
|
if (k->code == Shift) {
|
||||||
zwp_virtual_keyboard_v1_key_mods(kb->vkbd, time, k->code, WL_KEYBOARD_KEY_STATE_PRESSED);
|
|
||||||
} else {
|
|
||||||
zwp_virtual_keyboard_v1_key_mods(kb->vkbd, time, k->code, WL_KEYBOARD_KEY_STATE_RELEASED);
|
|
||||||
}
|
|
||||||
if ((k->code == Shift) || (k->code == CapsLock)) {
|
|
||||||
kbd_draw_layout(kb);
|
kbd_draw_layout(kb);
|
||||||
} else {
|
} else {
|
||||||
if (kb->mods & k->code) {
|
if (kb->mods & k->code) {
|
||||||
@@ -536,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
|
||||||
@@ -570,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);
|
||||||
@@ -585,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -592,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);
|
||||||
@@ -603,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);
|
||||||
@@ -627,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -644,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)) {
|
||||||
@@ -659,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
|
||||||
@@ -685,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
|
||||||
@@ -716,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");
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
2934
keymap.deskintl.h
2934
keymap.deskintl.h
File diff suppressed because it is too large
Load Diff
1007
layout.deskintl.h
1007
layout.deskintl.h
File diff suppressed because it is too large
Load Diff
@@ -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},
|
||||||
|
|||||||
409
main.c
409
main.c
@@ -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;
|
||||||
@@ -47,18 +47,25 @@ static struct wp_fractional_scale_manager_v1 *wfs_mgr;
|
|||||||
static struct wp_viewport *draw_surf_viewport, *popup_draw_surf_viewport;
|
static struct wp_viewport *draw_surf_viewport, *popup_draw_surf_viewport;
|
||||||
static struct wp_viewporter *viewporter;
|
static struct wp_viewporter *viewporter;
|
||||||
static bool popup_xdg_surface_configured;
|
static bool popup_xdg_surface_configured;
|
||||||
static bool layer_surface_configured;
|
|
||||||
|
|
||||||
static uint32_t available_width, available_height = 0;
|
struct Output {
|
||||||
static void refresh_available_dimension();
|
uint32_t name;
|
||||||
|
uint32_t w, h;
|
||||||
|
double scale;
|
||||||
|
struct wl_output *data;
|
||||||
|
};
|
||||||
|
static struct Output *current_output;
|
||||||
|
|
||||||
|
#define WL_OUTPUTS_LIMIT 8
|
||||||
|
static struct Output wl_outputs[WL_OUTPUTS_LIMIT];
|
||||||
|
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;
|
||||||
@@ -69,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 */
|
||||||
@@ -108,6 +114,11 @@ static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
|
|||||||
static void seat_handle_name(void *data, struct wl_seat *wl_seat,
|
static void seat_handle_name(void *data, struct wl_seat *wl_seat,
|
||||||
const char *name);
|
const char *name);
|
||||||
|
|
||||||
|
static void wl_surface_enter(void *data, struct wl_surface *wl_surface,
|
||||||
|
struct wl_output *wl_output);
|
||||||
|
static void wl_surface_leave(void *data, struct wl_surface *wl_surface,
|
||||||
|
struct wl_output *wl_output);
|
||||||
|
|
||||||
static void handle_global(void *data, struct wl_registry *registry,
|
static void handle_global(void *data, struct wl_registry *registry,
|
||||||
uint32_t name, const char *interface,
|
uint32_t name, const char *interface,
|
||||||
uint32_t version);
|
uint32_t version);
|
||||||
@@ -119,9 +130,7 @@ static void layer_surface_configure(void *data,
|
|||||||
uint32_t serial, uint32_t w, uint32_t h);
|
uint32_t serial, uint32_t w, uint32_t h);
|
||||||
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 redimension_keyboard();
|
static void flip_landscape();
|
||||||
static void show();
|
|
||||||
static void hide();
|
|
||||||
|
|
||||||
/* event handlers */
|
/* event handlers */
|
||||||
static const struct wl_pointer_listener pointer_listener = {
|
static const struct wl_pointer_listener pointer_listener = {
|
||||||
@@ -147,33 +156,9 @@ static const struct wl_seat_listener seat_listener = {
|
|||||||
.name = seat_handle_name,
|
.name = seat_handle_name,
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
|
||||||
wl_surface_enter(void *data, struct wl_surface *wl_surface,
|
|
||||||
struct wl_output *wl_output)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
wl_surface_leave(void *data, struct wl_surface *wl_surface,
|
|
||||||
struct wl_output *wl_output) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
wl_preferred_buffer_scale(void *data, struct wl_surface *wl_surface,
|
|
||||||
int scale) {
|
|
||||||
keyboard.preferred_scale = scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
wl_preferred_buffer_transform(void *data, struct wl_surface *wl_surface,
|
|
||||||
uint32_t transform) {
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct wl_surface_listener surface_listener = {
|
static const struct wl_surface_listener surface_listener = {
|
||||||
.enter = wl_surface_enter,
|
.enter = wl_surface_enter,
|
||||||
.leave = wl_surface_leave,
|
.leave = wl_surface_leave,
|
||||||
.preferred_buffer_scale = wl_preferred_buffer_scale,
|
|
||||||
.preferred_buffer_transform = wl_preferred_buffer_transform,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct wl_registry_listener registry_listener = {
|
static const struct wl_registry_listener registry_listener = {
|
||||||
@@ -181,25 +166,6 @@ static const struct wl_registry_listener registry_listener = {
|
|||||||
.global_remove = handle_global_remove,
|
.global_remove = handle_global_remove,
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
|
||||||
initiate_configure(void *data, struct zwlr_layer_surface_v1 *surface,
|
|
||||||
uint32_t serial, uint32_t w, uint32_t h)
|
|
||||||
{
|
|
||||||
available_width = w;
|
|
||||||
available_height = h;
|
|
||||||
zwlr_layer_surface_v1_ack_configure(surface, serial);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
initiate_closed(void *data, struct zwlr_layer_surface_v1 *surface)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct zwlr_layer_surface_v1_listener initiate_listener = {
|
|
||||||
.configure = initiate_configure,
|
|
||||||
.closed = initiate_closed,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct zwlr_layer_surface_v1_listener layer_surface_listener = {
|
static const struct zwlr_layer_surface_v1_listener layer_surface_listener = {
|
||||||
.configure = layer_surface_configure,
|
.configure = layer_surface_configure,
|
||||||
.closed = layer_surface_closed,
|
.closed = layer_surface_closed,
|
||||||
@@ -225,7 +191,7 @@ wl_touch_down(void *data, struct wl_touch *wl_touch, uint32_t serial,
|
|||||||
uint32_t time, struct wl_surface *surface, int32_t id,
|
uint32_t time, struct wl_surface *surface, int32_t id,
|
||||||
wl_fixed_t x, wl_fixed_t y)
|
wl_fixed_t x, wl_fixed_t y)
|
||||||
{
|
{
|
||||||
if(!layer_surface_configured || !popup_xdg_surface_configured) {
|
if(!popup_xdg_surface_configured) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,7 +217,7 @@ void
|
|||||||
wl_touch_up(void *data, struct wl_touch *wl_touch, uint32_t serial,
|
wl_touch_up(void *data, struct wl_touch *wl_touch, uint32_t serial,
|
||||||
uint32_t time, int32_t id)
|
uint32_t time, int32_t id)
|
||||||
{
|
{
|
||||||
if(!layer_surface_configured || !popup_xdg_surface_configured) {
|
if(!popup_xdg_surface_configured) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,7 +228,7 @@ void
|
|||||||
wl_touch_motion(void *data, struct wl_touch *wl_touch, uint32_t time,
|
wl_touch_motion(void *data, struct wl_touch *wl_touch, uint32_t time,
|
||||||
int32_t id, wl_fixed_t x, wl_fixed_t y)
|
int32_t id, wl_fixed_t x, wl_fixed_t y)
|
||||||
{
|
{
|
||||||
if(!layer_surface_configured || !popup_xdg_surface_configured) {
|
if(!popup_xdg_surface_configured) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -314,7 +280,7 @@ void
|
|||||||
wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, uint32_t time,
|
wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, uint32_t time,
|
||||||
wl_fixed_t surface_x, wl_fixed_t surface_y)
|
wl_fixed_t surface_x, wl_fixed_t surface_y)
|
||||||
{
|
{
|
||||||
if(!layer_surface_configured || !popup_xdg_surface_configured) {
|
if(!popup_xdg_surface_configured) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,7 +296,7 @@ void
|
|||||||
wl_pointer_button(void *data, struct wl_pointer *wl_pointer, uint32_t serial,
|
wl_pointer_button(void *data, struct wl_pointer *wl_pointer, uint32_t serial,
|
||||||
uint32_t time, uint32_t button, uint32_t state)
|
uint32_t time, uint32_t button, uint32_t state)
|
||||||
{
|
{
|
||||||
if(!layer_surface_configured || !popup_xdg_surface_configured) {
|
if(!popup_xdg_surface_configured) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -359,11 +325,12 @@ void
|
|||||||
wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, uint32_t time,
|
wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, uint32_t time,
|
||||||
uint32_t axis, wl_fixed_t value)
|
uint32_t axis, wl_fixed_t value)
|
||||||
{
|
{
|
||||||
if(!layer_surface_configured || !popup_xdg_surface_configured) {
|
if(!popup_xdg_surface_configured) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
kbd_next_layer(&keyboard, NULL, (value >= 0));
|
kbd_next_layer(&keyboard, NULL, (value >= 0));
|
||||||
|
drwsurf_flip(keyboard.surf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -399,6 +366,82 @@ seat_handle_name(void *data, struct wl_seat *wl_seat, const char *name)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wl_surface_enter(void *data, struct wl_surface *wl_surface,
|
||||||
|
struct wl_output *wl_output)
|
||||||
|
{
|
||||||
|
struct Output *old_output = current_output;
|
||||||
|
for (int i = 0; i < wl_outputs_size; i += 1) {
|
||||||
|
if (wl_outputs[i].data == wl_output) {
|
||||||
|
current_output = &wl_outputs[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (current_output == old_output) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
keyboard.preferred_scale = current_output->scale;
|
||||||
|
flip_landscape();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wl_surface_leave(void *data, struct wl_surface *wl_surface,
|
||||||
|
struct wl_output *wl_output) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
display_handle_geometry(void *data, struct wl_output *wl_output, int x, int y,
|
||||||
|
int physical_width, int physical_height, int subpixel,
|
||||||
|
const char *make, const char *model, int transform)
|
||||||
|
{
|
||||||
|
struct Output *output = data;
|
||||||
|
|
||||||
|
// Swap width and height on rotated displays
|
||||||
|
if (transform % 2 != 0) {
|
||||||
|
int tmp = physical_width;
|
||||||
|
physical_width = physical_height;
|
||||||
|
physical_height = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
output->w = physical_width;
|
||||||
|
output->h = physical_height;
|
||||||
|
|
||||||
|
if (current_output == output) {
|
||||||
|
flip_landscape();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
display_handle_done(void *data, struct wl_output *wl_output)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
display_handle_scale(void *data, struct wl_output *wl_output, int32_t scale)
|
||||||
|
{
|
||||||
|
struct Output *output = data;
|
||||||
|
output->scale = scale;
|
||||||
|
|
||||||
|
if (current_output == output) {
|
||||||
|
keyboard.preferred_scale = scale;
|
||||||
|
flip_landscape();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
display_handle_mode(void *data, struct wl_output *wl_output, uint32_t flags,
|
||||||
|
int width, int height, int refresh)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wl_output_listener output_listener = {
|
||||||
|
.geometry = display_handle_geometry,
|
||||||
|
.mode = display_handle_mode,
|
||||||
|
.done = display_handle_done,
|
||||||
|
.scale = display_handle_scale};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
xdg_wm_base_ping(void *data, struct xdg_wm_base *xdg_wm_base, uint32_t serial)
|
xdg_wm_base_ping(void *data, struct xdg_wm_base *xdg_wm_base, uint32_t serial)
|
||||||
{
|
{
|
||||||
@@ -415,9 +458,19 @@ handle_global(void *data, struct wl_registry *registry, uint32_t name,
|
|||||||
{
|
{
|
||||||
if (strcmp(interface, wl_compositor_interface.name) == 0) {
|
if (strcmp(interface, wl_compositor_interface.name) == 0) {
|
||||||
compositor =
|
compositor =
|
||||||
wl_registry_bind(registry, name, &wl_compositor_interface, 6);
|
wl_registry_bind(registry, name, &wl_compositor_interface, 3);
|
||||||
} else if (strcmp(interface, wl_shm_interface.name) == 0) {
|
} else if (strcmp(interface, wl_shm_interface.name) == 0) {
|
||||||
draw_ctx.shm = wl_registry_bind(registry, name, &wl_shm_interface, 1);
|
draw_ctx.shm = wl_registry_bind(registry, name, &wl_shm_interface, 1);
|
||||||
|
} else if (strcmp(interface, wl_output_interface.name) == 0) {
|
||||||
|
if (wl_outputs_size < WL_OUTPUTS_LIMIT) {
|
||||||
|
struct Output *output = &wl_outputs[wl_outputs_size];
|
||||||
|
output->data =
|
||||||
|
wl_registry_bind(registry, name, &wl_output_interface, 2);
|
||||||
|
output->name = name;
|
||||||
|
output->scale = 1;
|
||||||
|
wl_output_add_listener(output->data, &output_listener, output);
|
||||||
|
wl_outputs_size += 1;
|
||||||
|
}
|
||||||
} else if (strcmp(interface, wl_seat_interface.name) == 0) {
|
} else if (strcmp(interface, wl_seat_interface.name) == 0) {
|
||||||
seat = wl_registry_bind(registry, name, &wl_seat_interface, 1);
|
seat = wl_registry_bind(registry, name, &wl_seat_interface, 1);
|
||||||
wl_seat_add_listener(seat, &seat_listener, NULL);
|
wl_seat_add_listener(seat, &seat_listener, NULL);
|
||||||
@@ -444,6 +497,16 @@ handle_global(void *data, struct wl_registry *registry, uint32_t name,
|
|||||||
void
|
void
|
||||||
handle_global_remove(void *data, struct wl_registry *registry, uint32_t name)
|
handle_global_remove(void *data, struct wl_registry *registry, uint32_t name)
|
||||||
{
|
{
|
||||||
|
for (int i = 0; i < wl_outputs_size; i += 1) {
|
||||||
|
if (wl_outputs[i].name == name) {
|
||||||
|
wl_output_destroy(wl_outputs[i].data);
|
||||||
|
for (; i < wl_outputs_size - 1; i += 1) {
|
||||||
|
wl_outputs[i] = wl_outputs[i + 1];
|
||||||
|
}
|
||||||
|
wl_outputs_size -= 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -452,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 = {
|
||||||
@@ -489,9 +552,20 @@ static const struct wp_fractional_scale_v1_listener
|
|||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
redimension_keyboard()
|
flip_landscape()
|
||||||
{
|
{
|
||||||
keyboard.landscape = available_width > available_height;
|
bool previous_landscape = keyboard.landscape;
|
||||||
|
|
||||||
|
if (current_output) {
|
||||||
|
keyboard.landscape = current_output->w > current_output->h;
|
||||||
|
} else if (wl_outputs_size) {
|
||||||
|
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;
|
||||||
if (keyboard.landscape) {
|
if (keyboard.landscape) {
|
||||||
@@ -502,80 +576,86 @@ redimension_keyboard()
|
|||||||
height = normal_height;
|
height = normal_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
keyboard.w = available_width;
|
|
||||||
keyboard.h = height;
|
|
||||||
keyboard.layout = &keyboard.layouts[layer];
|
keyboard.layout = &keyboard.layouts[layer];
|
||||||
keyboard.layer_index = 0;
|
keyboard.layer_index = 0;
|
||||||
keyboard.prevlayout = keyboard.layout;
|
keyboard.prevlayout = keyboard.layout;
|
||||||
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) {
|
||||||
|
zwlr_layer_surface_v1_set_size(layer_surface, 0, height);
|
||||||
|
zwlr_layer_surface_v1_set_exclusive_zone(layer_surface, height);
|
||||||
|
wl_surface_commit(draw_surf.surf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface,
|
layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface,
|
||||||
uint32_t serial, uint32_t w, uint32_t h)
|
uint32_t serial, uint32_t w, uint32_t h)
|
||||||
{
|
{
|
||||||
// Swallow events for old/destroyed surface
|
|
||||||
if (surface != layer_surface) {
|
|
||||||
zwlr_layer_surface_v1_ack_configure(surface, serial);
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Not what we expected, or redimension, refresh and restart
|
|
||||||
if (keyboard.w != w || keyboard.h != h) {
|
|
||||||
zwlr_layer_surface_v1_ack_configure(surface, serial);
|
|
||||||
hide();
|
|
||||||
show();
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Swallow useless events
|
|
||||||
if (layer_surface_configured) {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
layer_surface_configured = true;
|
|
||||||
|
|
||||||
double scale = keyboard.preferred_scale;
|
double scale = keyboard.preferred_scale;
|
||||||
if (keyboard.preferred_fractional_scale) {
|
if (keyboard.preferred_fractional_scale) {
|
||||||
scale = keyboard.preferred_fractional_scale;
|
scale = keyboard.preferred_fractional_scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
keyboard.scale = scale;
|
if (keyboard.w != w || keyboard.h != h || keyboard.scale != scale ||
|
||||||
hidden = false;
|
hidden) {
|
||||||
|
|
||||||
if (wfs_mgr && viewporter) {
|
keyboard.w = w;
|
||||||
wp_viewport_set_destination(draw_surf_viewport, keyboard.w,
|
keyboard.h = h;
|
||||||
keyboard.h);
|
keyboard.scale = scale;
|
||||||
|
hidden = false;
|
||||||
|
|
||||||
|
if (wfs_mgr && viewporter) {
|
||||||
|
wp_viewport_set_destination(draw_surf_viewport, keyboard.w,
|
||||||
|
keyboard.h);
|
||||||
|
} else {
|
||||||
|
wl_surface_set_buffer_scale(draw_surf.surf, keyboard.scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (popup_xdg_popup) {
|
||||||
|
xdg_popup_destroy(popup_xdg_popup);
|
||||||
|
}
|
||||||
|
if (popup_xdg_surface) {
|
||||||
|
xdg_surface_destroy(popup_xdg_surface);
|
||||||
|
}
|
||||||
|
if (popup_draw_surf.surf) {
|
||||||
|
wl_surface_destroy(popup_draw_surf.surf);
|
||||||
|
}
|
||||||
|
|
||||||
|
popup_draw_surf.surf = wl_compositor_create_surface(compositor);
|
||||||
|
|
||||||
|
xdg_positioner_set_size(popup_xdg_positioner, w, h * 2);
|
||||||
|
xdg_positioner_set_anchor_rect(popup_xdg_positioner, 0, -h, w, h * 2);
|
||||||
|
|
||||||
|
wl_surface_set_input_region(popup_draw_surf.surf, empty_region);
|
||||||
|
popup_xdg_surface =
|
||||||
|
xdg_wm_base_get_xdg_surface(wm_base, popup_draw_surf.surf);
|
||||||
|
popup_xdg_surface_configured = false;
|
||||||
|
xdg_surface_add_listener(popup_xdg_surface, &xdg_popup_surface_listener,
|
||||||
|
NULL);
|
||||||
|
popup_xdg_popup = xdg_surface_get_popup(popup_xdg_surface, NULL,
|
||||||
|
popup_xdg_positioner);
|
||||||
|
xdg_popup_add_listener(popup_xdg_popup, &xdg_popup_listener, NULL);
|
||||||
|
zwlr_layer_surface_v1_get_popup(layer_surface, popup_xdg_popup);
|
||||||
|
|
||||||
|
if (wfs_mgr && viewporter) {
|
||||||
|
popup_draw_surf_viewport =
|
||||||
|
wp_viewporter_get_viewport(viewporter, popup_draw_surf.surf);
|
||||||
|
wp_viewport_set_destination(popup_draw_surf_viewport, keyboard.w,
|
||||||
|
keyboard.h * 2);
|
||||||
|
} else {
|
||||||
|
wl_surface_set_buffer_scale(popup_draw_surf.surf, keyboard.scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_surface_commit(popup_draw_surf.surf);
|
||||||
|
|
||||||
|
zwlr_layer_surface_v1_ack_configure(surface, serial);
|
||||||
|
kbd_resize(&keyboard, layouts, NumLayouts);
|
||||||
|
drwsurf_flip(&draw_surf);
|
||||||
} else {
|
} else {
|
||||||
wl_surface_set_buffer_scale(draw_surf.surf, keyboard.scale);
|
zwlr_layer_surface_v1_ack_configure(surface, serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
popup_draw_surf.surf = wl_compositor_create_surface(compositor);
|
|
||||||
|
|
||||||
xdg_positioner_set_size(popup_xdg_positioner, w, h * 2);
|
|
||||||
xdg_positioner_set_anchor_rect(popup_xdg_positioner, 0, -h, w, h * 2);
|
|
||||||
|
|
||||||
wl_surface_set_input_region(popup_draw_surf.surf, empty_region);
|
|
||||||
popup_xdg_surface = xdg_wm_base_get_xdg_surface(wm_base, popup_draw_surf.surf);
|
|
||||||
popup_xdg_surface_configured = false;
|
|
||||||
xdg_surface_add_listener(popup_xdg_surface, &xdg_popup_surface_listener, NULL);
|
|
||||||
popup_xdg_popup = xdg_surface_get_popup(popup_xdg_surface, NULL, popup_xdg_positioner);
|
|
||||||
xdg_popup_add_listener(popup_xdg_popup, &xdg_popup_listener, NULL);
|
|
||||||
zwlr_layer_surface_v1_get_popup(layer_surface, popup_xdg_popup);
|
|
||||||
|
|
||||||
if (wfs_mgr && viewporter) {
|
|
||||||
popup_draw_surf_viewport = wp_viewporter_get_viewport(viewporter, popup_draw_surf.surf);
|
|
||||||
wp_viewport_set_destination(popup_draw_surf_viewport, keyboard.w, keyboard.h * 2);
|
|
||||||
} else {
|
|
||||||
wl_surface_set_buffer_scale(popup_draw_surf.surf, keyboard.scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
wl_surface_commit(popup_draw_surf.surf);
|
|
||||||
|
|
||||||
zwlr_layer_surface_v1_ack_configure(surface, serial);
|
|
||||||
|
|
||||||
kbd_resize(&keyboard, layouts, NumLayouts);
|
|
||||||
drwsurf_attach(&draw_surf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -600,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(
|
||||||
@@ -624,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
|
||||||
@@ -647,40 +723,18 @@ hide()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wfs_draw_surf) {
|
if(wfs_draw_surf) {
|
||||||
wp_fractional_scale_v1_destroy(wfs_draw_surf);
|
wp_fractional_scale_v1_destroy(wfs_draw_surf);
|
||||||
wfs_draw_surf = NULL;
|
wfs_draw_surf = NULL;
|
||||||
}
|
}
|
||||||
if (draw_surf_viewport) {
|
if(draw_surf_viewport) {
|
||||||
wp_viewport_destroy(draw_surf_viewport);
|
wp_viewport_destroy(draw_surf_viewport);
|
||||||
draw_surf_viewport = NULL;
|
draw_surf_viewport = NULL;
|
||||||
}
|
}
|
||||||
if (popup_xdg_popup) {
|
|
||||||
xdg_popup_destroy(popup_xdg_popup);
|
|
||||||
popup_xdg_popup = NULL;
|
|
||||||
}
|
|
||||||
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);
|
zwlr_layer_surface_v1_destroy(layer_surface);
|
||||||
layer_surface = NULL;
|
|
||||||
layer_surface_configured = false;
|
|
||||||
|
|
||||||
// Cancel pending frame callback before destroying surface
|
|
||||||
if (draw_surf.frame_cb) {
|
|
||||||
wl_callback_destroy(draw_surf.frame_cb);
|
|
||||||
draw_surf.frame_cb = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
wl_surface_destroy(draw_surf.surf);
|
wl_surface_destroy(draw_surf.surf);
|
||||||
draw_surf.attached = false;
|
layer_surface = NULL;
|
||||||
|
|
||||||
hidden = true;
|
hidden = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -691,12 +745,12 @@ show()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
refresh_available_dimension();
|
wl_display_sync(display);
|
||||||
redimension_keyboard();
|
|
||||||
|
flip_landscape();
|
||||||
|
|
||||||
draw_surf.surf = wl_compositor_create_surface(compositor);
|
draw_surf.surf = wl_compositor_create_surface(compositor);
|
||||||
wl_surface_add_listener(
|
wl_surface_add_listener(draw_surf.surf, &surface_listener, NULL);
|
||||||
draw_surf.surf, &surface_listener, NULL);
|
|
||||||
if (wfs_mgr && viewporter) {
|
if (wfs_mgr && viewporter) {
|
||||||
wfs_draw_surf = wp_fractional_scale_manager_v1_get_fractional_scale(
|
wfs_draw_surf = wp_fractional_scale_manager_v1_get_fractional_scale(
|
||||||
wfs_mgr, draw_surf.surf);
|
wfs_mgr, draw_surf.surf);
|
||||||
@@ -707,15 +761,15 @@ show()
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct wl_output *current_output_data = NULL;
|
struct wl_output *current_output_data = NULL;
|
||||||
|
if (current_output)
|
||||||
|
current_output_data = current_output->data;
|
||||||
|
|
||||||
layer_surface = zwlr_layer_shell_v1_get_layer_surface(
|
layer_surface = zwlr_layer_shell_v1_get_layer_surface(
|
||||||
layer_shell, draw_surf.surf, current_output_data, layer, namespace);
|
layer_shell, draw_surf.surf, current_output_data, layer, namespace);
|
||||||
|
|
||||||
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);
|
||||||
@@ -743,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);
|
||||||
@@ -757,25 +811,6 @@ set_kbd_colors(uint8_t *bgra, char *hex)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
refresh_available_dimension()
|
|
||||||
{
|
|
||||||
struct wl_surface *surface = wl_compositor_create_surface(compositor);
|
|
||||||
struct zwlr_layer_surface_v1 *layer_surface = zwlr_layer_shell_v1_get_layer_surface(
|
|
||||||
layer_shell, surface, NULL, layer, namespace);
|
|
||||||
zwlr_layer_surface_v1_set_anchor(layer_surface,
|
|
||||||
ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
|
|
||||||
ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM |
|
|
||||||
ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT |
|
|
||||||
ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT);
|
|
||||||
zwlr_layer_surface_v1_add_listener(layer_surface, &initiate_listener, NULL);
|
|
||||||
wl_surface_commit(surface);
|
|
||||||
wl_display_roundtrip(display);
|
|
||||||
zwlr_layer_surface_v1_destroy(layer_surface);
|
|
||||||
wl_surface_destroy(surface);
|
|
||||||
wl_display_roundtrip(display);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
@@ -803,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;
|
||||||
@@ -914,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"))) {
|
||||||
@@ -939,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]);
|
||||||
@@ -962,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;
|
||||||
|
|
||||||
@@ -1001,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);
|
||||||
|
|
||||||
@@ -1012,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
76
wvkbd.1
Normal 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>.
|
||||||
134
wvkbd.1.scd
134
wvkbd.1.scd
@@ -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>.
|
|
||||||
Reference in New Issue
Block a user