mirror of
https://github.com/jjsullivan5196/wvkbd.git
synced 2025-09-19 01:21:59 +02:00
Compare commits
61 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
ed702f9562 | ||
|
ecc3d5ae1a | ||
|
74667dc2e8 | ||
|
cf60305a61 | ||
|
915a881111 | ||
|
5318ee9256 | ||
|
3a44beac1f | ||
|
b3a7e95c69 | ||
|
5689b6bd33 | ||
|
90ac0454cd | ||
|
49975e78ee | ||
|
b0fd6777fc | ||
|
3142271882 | ||
|
ace77b2aaa | ||
|
47d27e48d5 | ||
|
3826cd6050 | ||
|
73caeee513 | ||
|
55b88bc14f | ||
|
686b27a72d | ||
|
646d47d072 | ||
|
e0ecf38853 | ||
|
ca53099c9d | ||
|
29639c28d5 | ||
|
745a0b6f53 | ||
|
c742b58f51 | ||
|
97efb1de74 | ||
|
125664afd5 | ||
|
6041473421 | ||
|
9cc8931b46 | ||
|
7d195c8217 | ||
|
d5db545dcc | ||
|
7d677d23b7 | ||
|
fe3257450a | ||
|
1852b3ab06 | ||
|
9d130e7fd2 | ||
|
2f72b176cb | ||
|
ba778478e6 | ||
|
d423720553 | ||
|
e3081fb6e9 | ||
|
8106d7606d | ||
|
bb237f5afa | ||
|
b083169ee4 | ||
|
538b48d08d | ||
|
de3b9a77e4 | ||
|
77c6cf4fe6 | ||
|
927918ccc5 | ||
|
9f8e73b315 | ||
|
0e17680041 | ||
|
3cccdab2e8 | ||
|
2d01b8963b | ||
|
c457d697aa | ||
|
5471e2ea0e | ||
|
a126945401 | ||
|
aa9e8ab7ab | ||
|
d6439afcb9 | ||
|
6e52be343d | ||
|
aaff22a105 | ||
|
ab56a2748b | ||
|
7ff5605303 | ||
|
02027621af | ||
|
63c209ec7f |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -6,5 +6,7 @@ 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,9 +10,10 @@ 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)
|
||||||
|
|
||||||
@@ -20,12 +21,15 @@ 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}
|
all: ${BIN} ${DOCS}
|
||||||
|
|
||||||
config.h:
|
config.h:
|
||||||
cp config.def.h config.h
|
cp config.${LAYOUT}.h config.h
|
||||||
|
|
||||||
proto/%-client-protocol.c: proto/%.xml
|
proto/%-client-protocol.c: proto/%.xml
|
||||||
wayland-scanner code < $? > $@
|
wayland-scanner code < $? > $@
|
||||||
@@ -39,11 +43,14 @@ 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) $(HDRS) $(WAYLAND_SRC) ${BIN}
|
rm -f $(OBJECTS) config.h $(HDRS) $(WAYLAND_SRC) ${BIN} ${DOCS}
|
||||||
|
|
||||||
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/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 />
|
<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 />
|
||||||
|
|
||||||
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/proycon/wvkbd/master/contrib/wvkbd-mobintl-landscape.jpg" width=640 />
|
<img src="https://raw.githubusercontent.com/jjsullivan5196/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,18 +42,22 @@ You'll need the following developer packages
|
|||||||
- wayland-client
|
- wayland-client
|
||||||
- xkbcommon
|
- xkbcommon
|
||||||
|
|
||||||
Make any customizations you would like in `config.def.h` and run `make`
|
You also need [scdoc](https://git.sr.ht/~sircmpwn/scdoc/) to generate the documentation.
|
||||||
|
|
||||||
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. The resulting binary is called `wvkbd-mobintl`.
|
and also attempts to accommodate various international users. Run `make`. The resulting binary is called `wvkbd-mobintl`.
|
||||||
|
|
||||||
You can, however, define your own layouts by copying and modifying `layout.mobintl.h` and `keymap.mobintl.h`
|
The other set of layouts is called `deskintl` *(desktop international)*, which groups layouts aimed at desktop, laptop, and
|
||||||
(replace `mobintl` for something like `yourlayout`). Then make your layout set using `make LAYOUT=yourlayout`, and
|
tablet devices with a larger touchscreen. The set is US-International English. Run `make LAYOUT=deskintl`. The resulting binary
|
||||||
the resulting binary will be `wvkbd-yourlayout`
|
is called `wvkbd-deskintl`.
|
||||||
|
|
||||||
|
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` (or the binary for your custom layout set).
|
Run `wvkbd-mobintl`, `wvkbd-deskintl` 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
|
||||||
@@ -99,7 +103,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 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/).
|
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/).
|
||||||
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
|
||||||
|
45
config.deskintl.h
Normal file
45
config.deskintl.h
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#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.14
|
VERSION = 0.18
|
||||||
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
|
||||||
|
@@ -1,24 +1,32 @@
|
|||||||
#ifndef config_def_h_INCLUDED
|
#ifndef config_h_INCLUDED
|
||||||
#define config_def_h_INCLUDED
|
#define config_h_INCLUDED
|
||||||
|
|
||||||
static const char *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 scheme = {
|
struct clr_scheme schemes[] = {
|
||||||
|
{
|
||||||
/* colors */
|
/* colors */
|
||||||
.bg = {.bgra = {15, 15, 15, transparency}},
|
.bg = {.bgra = {15, 15, 15, transparency}},
|
||||||
.fg = {.bgra = {45, 45, 45, transparency}},
|
.fg = {.bgra = {45, 45, 45, transparency}},
|
||||||
.high = {.bgra = {100, 100, 100, transparency}},
|
.high = {.bgra = {100, 100, 100, transparency}},
|
||||||
.swipe = {.bgra = {100, 255, 100, 64}},
|
.swipe = {.bgra = {100, 255, 100, 64}},
|
||||||
.text = {.color = UINT32_MAX},
|
.text = {.color = UINT32_MAX},
|
||||||
};
|
.font = DEFAULT_FONT,
|
||||||
struct clr_scheme scheme1 = {
|
.rounding = DEFAULT_ROUNDING,
|
||||||
|
},
|
||||||
|
{
|
||||||
/* colors */
|
/* colors */
|
||||||
.bg = {.bgra = {15, 15, 15, transparency}},
|
.bg = {.bgra = {15, 15, 15, transparency}},
|
||||||
.fg = {.bgra = {32, 32, 32, transparency}},
|
.fg = {.bgra = {32, 32, 32, transparency}},
|
||||||
.high = {.bgra = {100, 100, 100, transparency}},
|
.high = {.bgra = {100, 100, 100, transparency}},
|
||||||
.swipe = {.bgra = {100, 255, 100, 64}},
|
.swipe = {.bgra = {100, 255, 100, 64}},
|
||||||
.text = {.color = UINT32_MAX},
|
.text = {.color = UINT32_MAX},
|
||||||
|
.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 */
|
||||||
@@ -35,4 +43,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_def_h_INCLUDED
|
#endif // config_h_INCLUDED
|
218
drw.c
218
drw.c
@@ -4,37 +4,139 @@
|
|||||||
|
|
||||||
#include "drw.h"
|
#include "drw.h"
|
||||||
#include "shm_open.h"
|
#include "shm_open.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 = w * s;
|
ds->width = ceil(w * s);
|
||||||
ds->height = h * s;
|
ds->height = ceil(h * s);
|
||||||
|
|
||||||
setup_buffer(ds);
|
if (ds->damage)
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
wl_surface_attach(ds->surf, ds->buf, 0, 0);
|
if (ds->released)
|
||||||
wl_surface_commit(ds->surf);
|
return;
|
||||||
|
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 *d, Color color, uint32_t x, uint32_t y,
|
drw_draw_text(struct drwsurf *ds, 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)
|
||||||
{
|
{
|
||||||
|
drwsurf_flip(ds);
|
||||||
|
struct drwbuf *d = ds->back_buffer;
|
||||||
|
drwsurf_damage(ds, x, y, w, h);
|
||||||
|
|
||||||
cairo_save(d->cairo);
|
cairo_save(d->cairo);
|
||||||
|
|
||||||
|
pango_layout_set_font_description(d->layout, font_description);
|
||||||
|
|
||||||
cairo_set_source_rgba(
|
cairo_set_source_rgba(
|
||||||
d->cairo, color.bgra[2] / (double)255, color.bgra[1] / (double)255,
|
d->cairo, color.bgra[2] / (double)255, color.bgra[1] / (double)255,
|
||||||
color.bgra[0] / (double)255, color.bgra[3] / (double)255);
|
color.bgra[0] / (double)255, color.bgra[3] / (double)255);
|
||||||
@@ -54,8 +156,12 @@ drw_draw_text(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
drw_do_clear(struct drwsurf *d, uint32_t x, uint32_t y, uint32_t w, uint32_t h)
|
drw_do_clear(struct drwsurf *ds, 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);
|
||||||
@@ -66,9 +172,13 @@ drw_do_clear(struct drwsurf *d, uint32_t x, uint32_t y, uint32_t w, uint32_t h)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
drw_do_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
|
drw_do_rectangle(struct drwsurf *ds, Color color, uint32_t x, uint32_t y,
|
||||||
uint32_t w, uint32_t h, bool over)
|
uint32_t w, uint32_t h, bool over, int rounding)
|
||||||
{
|
{
|
||||||
|
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) {
|
||||||
@@ -77,6 +187,28 @@ drw_do_rectangle(struct drwsurf *d, 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) {
|
||||||
|
double radius = rounding / 1.0;
|
||||||
|
double degrees = M_PI / 180.0;
|
||||||
|
|
||||||
|
cairo_new_sub_path (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_rectangle(d->cairo, x, y, w, h);
|
||||||
cairo_set_source_rgba(
|
cairo_set_source_rgba(
|
||||||
d->cairo, color.bgra[2] / (double)255, color.bgra[1] / (double)255,
|
d->cairo, color.bgra[2] / (double)255, color.bgra[1] / (double)255,
|
||||||
@@ -84,60 +216,70 @@ drw_do_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
|
|||||||
cairo_fill(d->cairo);
|
cairo_fill(d->cairo);
|
||||||
|
|
||||||
cairo_restore(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)
|
uint32_t w, uint32_t h, int rounding)
|
||||||
{
|
{
|
||||||
drw_do_rectangle(d, color, x, y, w, h, false);
|
drw_do_rectangle(d, color, x, y, w, h, false, rounding);
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
uint32_t w, uint32_t h, int rounding)
|
||||||
{
|
{
|
||||||
drw_do_rectangle(d, color, x, y, w, h, true);
|
drw_do_rectangle(d, color, x, y, w, h, true, rounding);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
setup_buffer(struct drwsurf *drwsurf)
|
setup_buffer(struct drwsurf *drwsurf, struct drwbuf *drwbuf)
|
||||||
{
|
{
|
||||||
|
int prev_size = drwbuf->size;
|
||||||
int stride = drwsurf->width * 4;
|
int stride = drwsurf->width * 4;
|
||||||
drwsurf->size = stride * drwsurf->height;
|
drwbuf->size = stride * drwsurf->height;
|
||||||
|
|
||||||
int fd = allocate_shm_file(drwsurf->size);
|
int fd = allocate_shm_file(drwbuf->size);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
drwsurf->pool_data =
|
if (drwbuf->pool_data)
|
||||||
mmap(NULL, drwsurf->size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
munmap(drwbuf->pool_data, prev_size);
|
||||||
if (drwsurf->pool_data == MAP_FAILED) {
|
drwbuf->pool_data =
|
||||||
|
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, drwsurf->size);
|
wl_shm_create_pool(drwsurf->ctx->shm, fd, drwbuf->size);
|
||||||
drwsurf->buf =
|
drwbuf->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(
|
|
||||||
drwsurf->pool_data, CAIRO_FORMAT_ARGB32, drwsurf->width,
|
if (drwbuf->cairo_surf)
|
||||||
|
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);
|
||||||
|
|
||||||
drwsurf->cairo = cairo_create(s);
|
if (drwbuf->cairo)
|
||||||
cairo_scale(drwsurf->cairo, drwsurf->scale, drwsurf->scale);
|
cairo_destroy(drwbuf->cairo);
|
||||||
cairo_set_antialias(drwsurf->cairo, CAIRO_ANTIALIAS_NONE);
|
drwbuf->cairo = cairo_create(drwbuf->cairo_surf);
|
||||||
drwsurf->layout = pango_cairo_create_layout(drwsurf->cairo);
|
cairo_scale(drwbuf->cairo, drwsurf->scale, drwsurf->scale);
|
||||||
pango_layout_set_font_description(drwsurf->layout,
|
cairo_set_antialias(drwbuf->cairo, CAIRO_ANTIALIAS_NONE);
|
||||||
drwsurf->ctx->font_description);
|
drwbuf->layout = pango_cairo_create_layout(drwbuf->cairo);
|
||||||
pango_layout_set_auto_dir(drwsurf->layout, false);
|
pango_layout_set_auto_dir(drwbuf->layout, false);
|
||||||
cairo_save(drwsurf->cairo);
|
cairo_save(drwbuf->cairo);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
45
drw.h
45
drw.h
@@ -6,43 +6,54 @@
|
|||||||
|
|
||||||
struct drw {
|
struct drw {
|
||||||
struct wl_shm *shm;
|
struct wl_shm *shm;
|
||||||
PangoFontDescription *font_description;
|
};
|
||||||
|
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, size;
|
uint32_t width, height;
|
||||||
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;
|
||||||
unsigned char *pool_data;
|
struct wl_callback *frame_cb;
|
||||||
|
|
||||||
cairo_t *cairo;
|
cairo_region_t *damage, *backport_damage;
|
||||||
PangoLayout *layout;
|
bool attached;
|
||||||
|
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_flip(struct drwsurf *ds);
|
void drwsurf_attach(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 *d, uint32_t x, uint32_t y,
|
void drw_do_clear(struct drwsurf *ds, uint32_t x, uint32_t y,
|
||||||
uint32_t w, uint32_t h);
|
|
||||||
void drw_do_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
|
|
||||||
uint32_t w, uint32_t h, bool fill);
|
|
||||||
void drw_fill_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
|
|
||||||
uint32_t w, uint32_t h);
|
|
||||||
void drw_over_rectangle(struct drwsurf *d, Color color, 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,
|
||||||
|
uint32_t w, uint32_t h, bool fill, int rounding);
|
||||||
|
void drw_fill_rectangle(struct drwsurf *ds, Color color, uint32_t x, uint32_t y,
|
||||||
|
uint32_t w, uint32_t h, int rounding);
|
||||||
|
void drw_over_rectangle(struct drwsurf *ds, Color color, uint32_t x, uint32_t y,
|
||||||
|
uint32_t w, uint32_t h, int rounding);
|
||||||
|
|
||||||
void drw_draw_text(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
|
void drw_draw_text(struct drwsurf *ds, 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);
|
||||||
|
|
||||||
uint32_t setup_buffer(struct drwsurf *drwsurf);
|
uint32_t setup_buffer(struct drwsurf *ds, struct drwbuf *db);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
77
keyboard.c
77
keyboard.c
@@ -3,6 +3,7 @@
|
|||||||
#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"
|
||||||
@@ -276,13 +277,23 @@ 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 = false;
|
bool unlatch_shift, unlatch_ctrl, unlatch_alt, unlatch_super, unlatch_altgr;
|
||||||
|
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) {
|
if (unlatch_shift) kb->mods ^= Shift;
|
||||||
kb->mods ^= Shift;
|
if (unlatch_ctrl) kb->mods ^= Ctrl;
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,7 +301,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->last_press->code == KEY_SPACE) && (unlatch_shift)) {
|
if ((kb->shift_space_is_tab) && (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);
|
||||||
@@ -304,7 +315,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) {
|
} else if (unlatch_shift||unlatch_ctrl||unlatch_alt||unlatch_super||unlatch_altgr) {
|
||||||
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);
|
||||||
@@ -326,10 +337,7 @@ 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
|
||||||
@@ -355,10 +363,7 @@ 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
|
||||||
@@ -399,7 +404,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 ((k->code == KEY_SPACE) && (kb->mods & Shift)) {
|
if ((kb->shift_space_is_tab) && (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,
|
||||||
@@ -418,7 +423,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) {
|
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) {
|
||||||
@@ -490,9 +495,6 @@ 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
|
||||||
@@ -527,7 +529,8 @@ kbd_print_key_stdout(struct kbd *kb, struct key *k)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!handled) {
|
if (!handled) {
|
||||||
if ((kb->mods & Shift) || (kb->mods & CapsLock))
|
if ((kb->mods & Shift) ||
|
||||||
|
((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);
|
||||||
@@ -541,9 +544,6 @@ 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,32 +551,31 @@ 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) ? k->shift_label : k->label;
|
const char *label = ((kb->mods & Shift)||((kb->mods & CapsLock) &&
|
||||||
|
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);
|
||||||
struct clr_scheme *scheme =
|
struct clr_scheme *scheme = &kb->schemes[k->scheme];
|
||||||
(k->scheme == 0) ? &(kb->scheme) : &(kb->scheme1);
|
|
||||||
|
|
||||||
switch (type) {
|
switch (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->fg, scheme->rounding);
|
||||||
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->high, scheme->rounding);
|
||||||
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->swipe, scheme->rounding);
|
||||||
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);
|
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,14 +585,13 @@ kbd_draw_key(struct kbd *kb, struct key *k, enum key_draw_type type)
|
|||||||
kb->last_popup_w = k->w;
|
kb->last_popup_w = k->w;
|
||||||
kb->last_popup_h = k->h;
|
kb->last_popup_h = k->h;
|
||||||
|
|
||||||
drw_fill_rectangle(kb->popup_surf, kb->scheme.bg, k->x,
|
drw_fill_rectangle(kb->popup_surf, scheme->bg, k->x,
|
||||||
kb->last_popup_y, k->w, k->h);
|
kb->last_popup_y, k->w, k->h, scheme->rounding);
|
||||||
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);
|
KBD_KEY_BORDER, scheme->high, scheme->rounding);
|
||||||
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,
|
||||||
wl_surface_damage(kb->popup_surf->surf, k->x, kb->last_popup_y, k->w,
|
scheme->font_description);
|
||||||
k->h);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -605,7 +603,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->scheme.bg, 0, 0, kb->w, kb->h);
|
drw_fill_rectangle(d, kb->schemes[0].bg, 0, 0, kb->w, kb->h, 0);
|
||||||
|
|
||||||
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)) {
|
||||||
@@ -620,7 +618,6 @@ kbd_draw_layout(struct kbd *kb)
|
|||||||
}
|
}
|
||||||
next_key++;
|
next_key++;
|
||||||
}
|
}
|
||||||
wl_surface_damage(d->surf, 0, 0, kb->w, kb->h);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -647,17 +644,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)
|
uint32_t height, uint32_t border, Color color, int rounding)
|
||||||
{
|
{
|
||||||
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));
|
height - (border * 2), rounding);
|
||||||
}
|
}
|
||||||
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)
|
uint32_t height, uint32_t border, Color color, int rounding)
|
||||||
{
|
{
|
||||||
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));
|
height - (border * 2), rounding);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
16
keyboard.h
16
keyboard.h
@@ -54,6 +54,9 @@ struct clr_scheme {
|
|||||||
Color high;
|
Color high;
|
||||||
Color swipe;
|
Color swipe;
|
||||||
Color text;
|
Color text;
|
||||||
|
char *font;
|
||||||
|
int rounding;
|
||||||
|
PangoFontDescription *font_description;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct key {
|
struct key {
|
||||||
@@ -90,14 +93,16 @@ struct kbd {
|
|||||||
bool debug;
|
bool debug;
|
||||||
|
|
||||||
struct layout *layout;
|
struct layout *layout;
|
||||||
struct clr_scheme scheme;
|
struct clr_scheme *schemes;
|
||||||
struct clr_scheme scheme1;
|
|
||||||
|
|
||||||
bool print;
|
bool print;
|
||||||
bool print_intersect;
|
bool print_intersect;
|
||||||
uint32_t w, h;
|
uint32_t w, h;
|
||||||
double scale, pending_scale;
|
double 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;
|
||||||
@@ -108,6 +113,7 @@ 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;
|
||||||
|
|
||||||
@@ -119,9 +125,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);
|
uint32_t height, uint32_t border, Color color, int rounding);
|
||||||
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);
|
uint32_t height, uint32_t border, Color color, int rounding);
|
||||||
|
|
||||||
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
Normal file
2934
keymap.deskintl.h
Normal file
File diff suppressed because it is too large
Load Diff
1007
layout.deskintl.h
Normal file
1007
layout.deskintl.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1626,7 +1626,8 @@ 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},
|
||||||
{"", "", 9.0, Pad},
|
{"ґ", "Ґ", 1.0, Copy, 0x0491, 0, 0x0490},
|
||||||
|
{"", "", 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},
|
||||||
|
273
main.c
273
main.c
@@ -3,6 +3,7 @@
|
|||||||
#include "proto/xdg-shell-client-protocol.h"
|
#include "proto/xdg-shell-client-protocol.h"
|
||||||
#include "proto/fractional-scale-v1-client-protocol.h"
|
#include "proto/fractional-scale-v1-client-protocol.h"
|
||||||
#include "proto/viewporter-client-protocol.h"
|
#include "proto/viewporter-client-protocol.h"
|
||||||
|
#include <errno.h>
|
||||||
#include <linux/input-event-codes.h>
|
#include <linux/input-event-codes.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -23,8 +24,11 @@
|
|||||||
fprintf(stderr, __VA_ARGS__); \
|
fprintf(stderr, __VA_ARGS__); \
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
|
/* array size */
|
||||||
|
#define countof(x) (sizeof(x) / sizeof(*x))
|
||||||
|
|
||||||
/* client state */
|
/* client state */
|
||||||
static const char *namespace = "wlroots";
|
static const char *namespace = "wvkbd";
|
||||||
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;
|
||||||
@@ -42,6 +46,7 @@ static struct wp_fractional_scale_v1 *wfs_draw_surf;
|
|||||||
static struct wp_fractional_scale_manager_v1 *wfs_mgr;
|
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;
|
||||||
|
|
||||||
struct Output {
|
struct Output {
|
||||||
uint32_t name;
|
uint32_t name;
|
||||||
@@ -57,10 +62,11 @@ 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_TOP;
|
static uint32_t layer = ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY;
|
||||||
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;
|
||||||
@@ -71,6 +77,7 @@ 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 */
|
||||||
@@ -111,6 +118,8 @@ static void seat_handle_name(void *data, struct wl_seat *wl_seat,
|
|||||||
|
|
||||||
static void wl_surface_enter(void *data, struct wl_surface *wl_surface,
|
static void wl_surface_enter(void *data, struct wl_surface *wl_surface,
|
||||||
struct wl_output *wl_output);
|
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,
|
||||||
@@ -123,7 +132,8 @@ 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 resize();
|
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 = {
|
||||||
@@ -151,6 +161,7 @@ static const struct wl_seat_listener seat_listener = {
|
|||||||
|
|
||||||
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,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct wl_registry_listener registry_listener = {
|
static const struct wl_registry_listener registry_listener = {
|
||||||
@@ -183,6 +194,10 @@ 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(!popup_xdg_surface_configured) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
struct key *next_key;
|
struct key *next_key;
|
||||||
uint32_t touch_x, touch_y;
|
uint32_t touch_x, touch_y;
|
||||||
|
|
||||||
@@ -205,6 +220,10 @@ 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(!popup_xdg_surface_configured) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
kbd_release_key(&keyboard, time);
|
kbd_release_key(&keyboard, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,6 +231,10 @@ 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(!popup_xdg_surface_configured) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t touch_x, touch_y;
|
uint32_t touch_x, touch_y;
|
||||||
|
|
||||||
touch_x = wl_fixed_to_int(x);
|
touch_x = wl_fixed_to_int(x);
|
||||||
@@ -260,6 +283,10 @@ 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(!popup_xdg_surface_configured) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
cur_x = wl_fixed_to_int(surface_x);
|
cur_x = wl_fixed_to_int(surface_x);
|
||||||
cur_y = wl_fixed_to_int(surface_y);
|
cur_y = wl_fixed_to_int(surface_y);
|
||||||
|
|
||||||
@@ -272,6 +299,10 @@ 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(!popup_xdg_surface_configured) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
struct key *next_key;
|
struct key *next_key;
|
||||||
cur_press = state == WL_POINTER_BUTTON_STATE_PRESSED;
|
cur_press = state == WL_POINTER_BUTTON_STATE_PRESSED;
|
||||||
|
|
||||||
@@ -297,8 +328,11 @@ 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(!popup_xdg_surface_configured) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
kbd_next_layer(&keyboard, NULL, (value >= 0));
|
kbd_next_layer(&keyboard, NULL, (value >= 0));
|
||||||
drwsurf_flip(keyboard.surf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -338,16 +372,27 @@ void
|
|||||||
wl_surface_enter(void *data, struct wl_surface *wl_surface,
|
wl_surface_enter(void *data, struct wl_surface *wl_surface,
|
||||||
struct wl_output *wl_output)
|
struct wl_output *wl_output)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < WL_OUTPUTS_LIMIT; i += 1) {
|
struct Output *old_output = current_output;
|
||||||
|
for (int i = 0; i < wl_outputs_size; i += 1) {
|
||||||
if (wl_outputs[i].data == wl_output) {
|
if (wl_outputs[i].data == wl_output) {
|
||||||
current_output = &wl_outputs[i];
|
current_output = &wl_outputs[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (current_output == old_output) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
resize();
|
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
|
static void
|
||||||
display_handle_geometry(void *data, struct wl_output *wl_output, int x, int y,
|
display_handle_geometry(void *data, struct wl_output *wl_output, int x, int y,
|
||||||
int physical_width, int physical_height, int subpixel,
|
int physical_width, int physical_height, int subpixel,
|
||||||
@@ -366,7 +411,7 @@ display_handle_geometry(void *data, struct wl_output *wl_output, int x, int y,
|
|||||||
output->h = physical_height;
|
output->h = physical_height;
|
||||||
|
|
||||||
if (current_output == output) {
|
if (current_output == output) {
|
||||||
resize();
|
flip_landscape();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -382,7 +427,8 @@ display_handle_scale(void *data, struct wl_output *wl_output, int32_t scale)
|
|||||||
output->scale = scale;
|
output->scale = scale;
|
||||||
|
|
||||||
if (current_output == output) {
|
if (current_output == output) {
|
||||||
resize();
|
keyboard.preferred_scale = scale;
|
||||||
|
flip_landscape();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -417,7 +463,7 @@ handle_global(void *data, struct wl_registry *registry, uint32_t name,
|
|||||||
wl_registry_bind(registry, name, &wl_compositor_interface, 3);
|
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") == 0) {
|
} else if (strcmp(interface, wl_output_interface.name) == 0) {
|
||||||
if (wl_outputs_size < WL_OUTPUTS_LIMIT) {
|
if (wl_outputs_size < WL_OUTPUTS_LIMIT) {
|
||||||
struct Output *output = &wl_outputs[wl_outputs_size];
|
struct Output *output = &wl_outputs[wl_outputs_size];
|
||||||
output->data =
|
output->data =
|
||||||
@@ -453,10 +499,10 @@ 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_LIMIT; i += 1) {
|
for (int i = 0; i < wl_outputs_size; i += 1) {
|
||||||
if (wl_outputs[i].name == name) {
|
if (wl_outputs[i].name == name) {
|
||||||
wl_output_destroy(wl_outputs[i].data);
|
wl_output_destroy(wl_outputs[i].data);
|
||||||
for (; i < WL_OUTPUTS_LIMIT - 1; i += 1) {
|
for (; i < wl_outputs_size - 1; i += 1) {
|
||||||
wl_outputs[i] = wl_outputs[i + 1];
|
wl_outputs[i] = wl_outputs[i + 1];
|
||||||
}
|
}
|
||||||
wl_outputs_size -= 1;
|
wl_outputs_size -= 1;
|
||||||
@@ -470,7 +516,8 @@ xdg_popup_surface_configure(void *data, struct xdg_surface *xdg_surface,
|
|||||||
uint32_t serial)
|
uint32_t serial)
|
||||||
{
|
{
|
||||||
xdg_surface_ack_configure(xdg_surface, serial);
|
xdg_surface_ack_configure(xdg_surface, serial);
|
||||||
drwsurf_flip(&popup_draw_surf);
|
popup_xdg_surface_configured = true;
|
||||||
|
drwsurf_attach(&popup_draw_surf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct xdg_surface_listener xdg_popup_surface_listener = {
|
static const struct xdg_surface_listener xdg_popup_surface_listener = {
|
||||||
@@ -481,9 +528,6 @@ static void
|
|||||||
xdg_popup_configure(void *data, struct xdg_popup *xdg_popup, int32_t x,
|
xdg_popup_configure(void *data, struct xdg_popup *xdg_popup, int32_t x,
|
||||||
int32_t y, int32_t width, int32_t height)
|
int32_t y, int32_t width, int32_t height)
|
||||||
{
|
{
|
||||||
kbd_resize(&keyboard, layouts, NumLayouts);
|
|
||||||
|
|
||||||
drwsurf_flip(&draw_surf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -497,22 +541,28 @@ static const struct xdg_popup_listener xdg_popup_listener = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
wp_fractional_scale_prefered_scale(
|
wp_fractional_scale_preferred_scale(
|
||||||
void *data, struct wp_fractional_scale_v1 *wp_fractional_scale_v1,
|
void *data, struct wp_fractional_scale_v1 *wp_fractional_scale_v1,
|
||||||
uint32_t scale)
|
uint32_t scale)
|
||||||
{
|
{
|
||||||
keyboard.pending_scale = (double)scale / 120;
|
keyboard.preferred_fractional_scale = (double)scale / 120;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct wp_fractional_scale_v1_listener
|
static const struct wp_fractional_scale_v1_listener
|
||||||
wp_fractional_scale_listener = {
|
wp_fractional_scale_listener = {
|
||||||
.preferred_scale = wp_fractional_scale_prefered_scale,
|
.preferred_scale = wp_fractional_scale_preferred_scale,
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
resize()
|
flip_landscape()
|
||||||
{
|
{
|
||||||
|
bool previous_landscape = keyboard.landscape;
|
||||||
|
|
||||||
|
if (current_output) {
|
||||||
keyboard.landscape = current_output->w > current_output->h;
|
keyboard.landscape = current_output->w > current_output->h;
|
||||||
|
} else if (wl_outputs_size) {
|
||||||
|
keyboard.landscape = wl_outputs[0].w > wl_outputs[0].h;
|
||||||
|
}
|
||||||
|
|
||||||
enum layout_id layer;
|
enum layout_id layer;
|
||||||
if (keyboard.landscape) {
|
if (keyboard.landscape) {
|
||||||
@@ -529,14 +579,25 @@ resize()
|
|||||||
keyboard.last_abc_layout = keyboard.layout;
|
keyboard.last_abc_layout = keyboard.layout;
|
||||||
keyboard.last_abc_index = 0;
|
keyboard.last_abc_index = 0;
|
||||||
|
|
||||||
if (!wfs_mgr || !viewporter) {
|
if (layer_surface && previous_landscape != keyboard.landscape) {
|
||||||
keyboard.pending_scale = current_output->scale;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (layer_surface) {
|
zwlr_layer_surface_v1_destroy(layer_surface);
|
||||||
zwlr_layer_surface_v1_set_size(layer_surface, 0, height);
|
layer_surface = NULL;
|
||||||
zwlr_layer_surface_v1_set_exclusive_zone(layer_surface, height);
|
wl_surface_destroy(draw_surf.surf);
|
||||||
wl_surface_commit(draw_surf.surf);
|
|
||||||
|
show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -544,24 +605,20 @@ 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)
|
||||||
{
|
{
|
||||||
if (keyboard.w != w || keyboard.h != h ||
|
double scale = keyboard.preferred_scale;
|
||||||
keyboard.scale != keyboard.pending_scale) {
|
if (keyboard.preferred_fractional_scale) {
|
||||||
|
scale = keyboard.preferred_fractional_scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyboard.w != w || keyboard.h != h || keyboard.scale != scale ||
|
||||||
|
keyboard.output != current_output || hidden) {
|
||||||
|
|
||||||
keyboard.w = w;
|
keyboard.w = w;
|
||||||
keyboard.h = h;
|
keyboard.h = h;
|
||||||
keyboard.scale = keyboard.pending_scale;
|
keyboard.scale = scale;
|
||||||
|
hidden = false;
|
||||||
|
|
||||||
if (wfs_mgr && viewporter) {
|
if (wfs_mgr && viewporter) {
|
||||||
if (!wfs_draw_surf) {
|
|
||||||
wfs_draw_surf =
|
|
||||||
wp_fractional_scale_manager_v1_get_fractional_scale(
|
|
||||||
wfs_mgr, draw_surf.surf);
|
|
||||||
wp_fractional_scale_v1_add_listener(
|
|
||||||
wfs_draw_surf, &wp_fractional_scale_listener, NULL);
|
|
||||||
}
|
|
||||||
if (!draw_surf_viewport) {
|
|
||||||
draw_surf_viewport =
|
|
||||||
wp_viewporter_get_viewport(viewporter, draw_surf.surf);
|
|
||||||
}
|
|
||||||
wp_viewport_set_destination(draw_surf_viewport, keyboard.w,
|
wp_viewport_set_destination(draw_surf_viewport, keyboard.w,
|
||||||
keyboard.h);
|
keyboard.h);
|
||||||
} else {
|
} else {
|
||||||
@@ -586,6 +643,7 @@ layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface,
|
|||||||
wl_surface_set_input_region(popup_draw_surf.surf, empty_region);
|
wl_surface_set_input_region(popup_draw_surf.surf, empty_region);
|
||||||
popup_xdg_surface =
|
popup_xdg_surface =
|
||||||
xdg_wm_base_get_xdg_surface(wm_base, popup_draw_surf.surf);
|
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,
|
xdg_surface_add_listener(popup_xdg_surface, &xdg_popup_surface_listener,
|
||||||
NULL);
|
NULL);
|
||||||
popup_xdg_popup = xdg_surface_get_popup(popup_xdg_surface, NULL,
|
popup_xdg_popup = xdg_surface_get_popup(popup_xdg_surface, NULL,
|
||||||
@@ -603,9 +661,14 @@ layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface,
|
|||||||
}
|
}
|
||||||
|
|
||||||
wl_surface_commit(popup_draw_surf.surf);
|
wl_surface_commit(popup_draw_surf.surf);
|
||||||
}
|
|
||||||
|
|
||||||
zwlr_layer_surface_v1_ack_configure(surface, serial);
|
zwlr_layer_surface_v1_ack_configure(surface, serial);
|
||||||
|
kbd_resize(&keyboard, layouts, NumLayouts);
|
||||||
|
drwsurf_attach(&draw_surf);
|
||||||
|
keyboard.output = current_output;
|
||||||
|
} else {
|
||||||
|
zwlr_layer_surface_v1_ack_configure(surface, serial);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -630,6 +693,7 @@ 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(
|
||||||
@@ -653,6 +717,9 @@ 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
|
||||||
@@ -673,6 +740,15 @@ hide()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(wfs_draw_surf) {
|
||||||
|
wp_fractional_scale_v1_destroy(wfs_draw_surf);
|
||||||
|
wfs_draw_surf = NULL;
|
||||||
|
}
|
||||||
|
if(draw_surf_viewport) {
|
||||||
|
wp_viewport_destroy(draw_surf_viewport);
|
||||||
|
draw_surf_viewport = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
zwlr_layer_surface_v1_destroy(layer_surface);
|
zwlr_layer_surface_v1_destroy(layer_surface);
|
||||||
wl_surface_destroy(draw_surf.surf);
|
wl_surface_destroy(draw_surf.surf);
|
||||||
layer_surface = NULL;
|
layer_surface = NULL;
|
||||||
@@ -688,20 +764,35 @@ show()
|
|||||||
|
|
||||||
wl_display_sync(display);
|
wl_display_sync(display);
|
||||||
|
|
||||||
|
flip_landscape();
|
||||||
|
|
||||||
draw_surf.surf = wl_compositor_create_surface(compositor);
|
draw_surf.surf = wl_compositor_create_surface(compositor);
|
||||||
wl_surface_add_listener(draw_surf.surf, &surface_listener, NULL);
|
wl_surface_add_listener(draw_surf.surf, &surface_listener, NULL);
|
||||||
|
if (wfs_mgr && viewporter) {
|
||||||
|
wfs_draw_surf = wp_fractional_scale_manager_v1_get_fractional_scale(
|
||||||
|
wfs_mgr, draw_surf.surf);
|
||||||
|
wp_fractional_scale_v1_add_listener(
|
||||||
|
wfs_draw_surf, &wp_fractional_scale_listener, NULL);
|
||||||
|
draw_surf_viewport =
|
||||||
|
wp_viewporter_get_viewport(viewporter, draw_surf.surf);
|
||||||
|
}
|
||||||
|
|
||||||
|
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, NULL, 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);
|
||||||
wl_surface_commit(draw_surf.surf);
|
wl_surface_commit(draw_surf.surf);
|
||||||
|
|
||||||
hidden = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -725,7 +816,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[2];
|
char subhex[3] = { 0 };
|
||||||
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);
|
||||||
@@ -744,9 +835,9 @@ main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
/* parse command line arguments */
|
/* parse command line arguments */
|
||||||
char *layer_names_list = NULL, *landscape_layer_names_list = NULL;
|
char *layer_names_list = NULL, *landscape_layer_names_list = NULL;
|
||||||
const char *fc_font_pattern = NULL;
|
char *fc_font_pattern = NULL;
|
||||||
height = normal_height = KBD_PIXEL_HEIGHT;
|
height = landscape_height = KBD_PIXEL_LANDSCAPE_HEIGHT;
|
||||||
landscape_height = KBD_PIXEL_LANDSCAPE_HEIGHT;
|
normal_height = KBD_PIXEL_HEIGHT;
|
||||||
|
|
||||||
char *tmp;
|
char *tmp;
|
||||||
if ((tmp = getenv("WVKBD_LAYERS")))
|
if ((tmp = getenv("WVKBD_LAYERS")))
|
||||||
@@ -761,10 +852,12 @@ main(int argc, char **argv)
|
|||||||
/* keyboard settings */
|
/* keyboard settings */
|
||||||
keyboard.layers = (enum layout_id *)&layers;
|
keyboard.layers = (enum layout_id *)&layers;
|
||||||
keyboard.landscape_layers = (enum layout_id *)&landscape_layers;
|
keyboard.landscape_layers = (enum layout_id *)&landscape_layers;
|
||||||
keyboard.scheme = scheme;
|
keyboard.schemes = schemes;
|
||||||
|
keyboard.landscape = true;
|
||||||
keyboard.layer_index = 0;
|
keyboard.layer_index = 0;
|
||||||
keyboard.scheme1 = scheme1;
|
keyboard.preferred_scale = 1;
|
||||||
keyboard.pending_scale = 1;
|
keyboard.preferred_fractional_scale = 0;
|
||||||
|
keyboard.exclusive = true;
|
||||||
|
|
||||||
uint8_t alpha = 0;
|
uint8_t alpha = 0;
|
||||||
bool alpha_defined = false;
|
bool alpha_defined = false;
|
||||||
@@ -799,7 +892,7 @@ main(int argc, char **argv)
|
|||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
set_kbd_colors(keyboard.scheme.bg.bgra, argv[++i]);
|
set_kbd_colors(keyboard.schemes[0].bg.bgra, argv[++i]);
|
||||||
} else if ((!strcmp(argv[i], "-alpha")) ||
|
} else if ((!strcmp(argv[i], "-alpha")) ||
|
||||||
(!strcmp(argv[i], "--alpha"))) {
|
(!strcmp(argv[i], "--alpha"))) {
|
||||||
if (i >= argc - 1) {
|
if (i >= argc - 1) {
|
||||||
@@ -813,68 +906,74 @@ main(int argc, char **argv)
|
|||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
set_kbd_colors(keyboard.scheme.fg.bgra, argv[++i]);
|
set_kbd_colors(keyboard.schemes[0].fg.bgra, argv[++i]);
|
||||||
} else if ((!strcmp(argv[i], "-fg-sp")) ||
|
} else if ((!strcmp(argv[i], "-fg-sp")) ||
|
||||||
(!strcmp(argv[i], "--fg-sp"))) {
|
(!strcmp(argv[i], "--fg-sp"))) {
|
||||||
if (i >= argc - 1) {
|
if (i >= argc - 1) {
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
set_kbd_colors(keyboard.scheme1.fg.bgra, argv[++i]);
|
set_kbd_colors(keyboard.schemes[1].fg.bgra, argv[++i]);
|
||||||
} else if ((!strcmp(argv[i], "-press")) ||
|
} else if ((!strcmp(argv[i], "-press")) ||
|
||||||
(!strcmp(argv[i], "--press"))) {
|
(!strcmp(argv[i], "--press"))) {
|
||||||
if (i >= argc - 1) {
|
if (i >= argc - 1) {
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
set_kbd_colors(keyboard.scheme.high.bgra, argv[++i]);
|
set_kbd_colors(keyboard.schemes[0].high.bgra, argv[++i]);
|
||||||
} else if ((!strcmp(argv[i], "-press-sp")) ||
|
} else if ((!strcmp(argv[i], "-press-sp")) ||
|
||||||
(!strcmp(argv[i], "--press-sp"))) {
|
(!strcmp(argv[i], "--press-sp"))) {
|
||||||
if (i >= argc - 1) {
|
if (i >= argc - 1) {
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
set_kbd_colors(keyboard.scheme1.high.bgra, argv[++i]);
|
set_kbd_colors(keyboard.schemes[1].high.bgra, argv[++i]);
|
||||||
} else if ((!strcmp(argv[i], "-swipe")) ||
|
} else if ((!strcmp(argv[i], "-swipe")) ||
|
||||||
(!strcmp(argv[i], "--swipe"))) {
|
(!strcmp(argv[i], "--swipe"))) {
|
||||||
if (i >= argc - 1) {
|
if (i >= argc - 1) {
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
set_kbd_colors(keyboard.scheme.swipe.bgra, argv[++i]);
|
set_kbd_colors(keyboard.schemes[0].swipe.bgra, argv[++i]);
|
||||||
} else if ((!strcmp(argv[i], "-swipe-sp")) ||
|
} else if ((!strcmp(argv[i], "-swipe-sp")) ||
|
||||||
(!strcmp(argv[i], "--swipe-sp"))) {
|
(!strcmp(argv[i], "--swipe-sp"))) {
|
||||||
if (i >= argc - 1) {
|
if (i >= argc - 1) {
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
set_kbd_colors(keyboard.scheme1.swipe.bgra, argv[++i]);
|
set_kbd_colors(keyboard.schemes[1].swipe.bgra, argv[++i]);
|
||||||
} else if ((!strcmp(argv[i], "-text")) ||
|
} else if ((!strcmp(argv[i], "-text")) ||
|
||||||
(!strcmp(argv[i], "--text"))) {
|
(!strcmp(argv[i], "--text"))) {
|
||||||
if (i >= argc - 1) {
|
if (i >= argc - 1) {
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
set_kbd_colors(keyboard.scheme.text.bgra, argv[++i]);
|
set_kbd_colors(keyboard.schemes[0].text.bgra, argv[++i]);
|
||||||
} else if ((!strcmp(argv[i], "-text-sp")) ||
|
} else if ((!strcmp(argv[i], "-text-sp")) ||
|
||||||
(!strcmp(argv[i], "--text-sp"))) {
|
(!strcmp(argv[i], "--text-sp"))) {
|
||||||
if (i >= argc - 1) {
|
if (i >= argc - 1) {
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
set_kbd_colors(keyboard.scheme1.text.bgra, argv[++i]);
|
set_kbd_colors(keyboard.schemes[1].text.bgra, argv[++i]);
|
||||||
} else if (!strcmp(argv[i], "-H")) {
|
} else if (!strcmp(argv[i], "-H")) {
|
||||||
if (i >= argc - 1) {
|
if (i >= argc - 1) {
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
height = normal_height = atoi(argv[++i]);
|
normal_height = atoi(argv[++i]);
|
||||||
} else if (!strcmp(argv[i], "-L")) {
|
} else if (!strcmp(argv[i], "-L")) {
|
||||||
if (i >= argc - 1) {
|
if (i >= argc - 1) {
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
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"))) {
|
||||||
@@ -894,6 +993,8 @@ 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]);
|
||||||
@@ -902,16 +1003,22 @@ main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (alpha_defined) {
|
if (alpha_defined) {
|
||||||
keyboard.scheme.bg.bgra[3] = alpha;
|
keyboard.schemes[0].bg.bgra[3] = alpha;
|
||||||
keyboard.scheme.fg.bgra[3] = alpha;
|
keyboard.schemes[0].fg.bgra[3] = alpha;
|
||||||
keyboard.scheme.high.bgra[3] = alpha;
|
keyboard.schemes[0].high.bgra[3] = alpha;
|
||||||
keyboard.scheme1.bg.bgra[3] = alpha;
|
keyboard.schemes[1].bg.bgra[3] = alpha;
|
||||||
keyboard.scheme1.fg.bgra[3] = alpha;
|
keyboard.schemes[1].fg.bgra[3] = alpha;
|
||||||
keyboard.scheme1.high.bgra[3] = alpha;
|
keyboard.schemes[1].high.bgra[3] = alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fc_font_pattern) {
|
if (fc_font_pattern) {
|
||||||
fc_font_pattern = default_font;
|
for (i = 0; i < countof(schemes); i++)
|
||||||
|
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);
|
||||||
@@ -920,7 +1027,11 @@ main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
@@ -944,6 +1055,9 @@ 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);
|
||||||
|
|
||||||
@@ -952,12 +1066,19 @@ 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);
|
||||||
|
|
||||||
draw_ctx.font_description =
|
for (i = 0; i < countof(schemes); i++) {
|
||||||
pango_font_description_from_string(fc_font_pattern);
|
schemes[i].font_description =
|
||||||
|
pango_font_description_from_string(schemes[i].font);
|
||||||
|
}
|
||||||
|
|
||||||
if (!hidden)
|
if (!hidden)
|
||||||
show();
|
show();
|
||||||
@@ -994,6 +1115,12 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
if (fds[WAYLAND_FD].revents & POLLIN)
|
if (fds[WAYLAND_FD].revents & POLLIN)
|
||||||
wl_display_dispatch(display);
|
wl_display_dispatch(display);
|
||||||
|
if (fds[WAYLAND_FD].revents & POLLERR) {
|
||||||
|
die("Exceptional condition on wayland socket.\n");
|
||||||
|
}
|
||||||
|
if (fds[WAYLAND_FD].revents & POLLHUP) {
|
||||||
|
die("Wayland socket has been disconnected.\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (fds[SIGNAL_FD].revents & POLLIN) {
|
if (fds[SIGNAL_FD].revents & POLLIN) {
|
||||||
struct signalfd_siginfo si;
|
struct signalfd_siginfo si;
|
||||||
@@ -1011,8 +1138,10 @@ main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fc_font_pattern != default_font) {
|
if (fc_font_pattern) {
|
||||||
free((void *)fc_font_pattern);
|
free((void *)fc_font_pattern);
|
||||||
|
for (i = 0; i < countof(schemes); i++)
|
||||||
|
schemes[i].font = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
76
wvkbd.1
76
wvkbd.1
@@ -1,76 +0,0 @@
|
|||||||
.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
Normal file
134
wvkbd.1.scd
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
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