mirror of
https://github.com/jjsullivan5196/wvkbd.git
synced 2026-01-29 14:39:23 +01:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9fb1964f5d | ||
|
|
5b29d8c1a7 | ||
|
|
987ea03f84 | ||
|
|
0c743d9518 | ||
|
|
1963de0165 | ||
|
|
b0eff37239 | ||
|
|
f0c99d276a | ||
|
|
bd4a176eef | ||
|
|
a12c42cd18 | ||
|
|
66cd3bf49d | ||
|
|
b215035efc | ||
|
|
f917d02591 | ||
|
|
34a33b41fa |
22
.build.yml
Normal file
22
.build.yml
Normal file
@@ -0,0 +1,22 @@
|
||||
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
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -5,8 +5,6 @@
|
||||
include/config.h
|
||||
.gdb_history
|
||||
*.log
|
||||
wvkbd
|
||||
*.1
|
||||
config.h
|
||||
wvkbd-mobintl
|
||||
wvkbd-deskintl
|
||||
build-*/*
|
||||
wvkbd-*
|
||||
|
||||
18
Makefile
18
Makefile
@@ -1,5 +1,7 @@
|
||||
include config.mk
|
||||
|
||||
BUILDDIR=build-${LAYOUT}
|
||||
|
||||
NAME=wvkbd
|
||||
BIN=${NAME}-${LAYOUT}
|
||||
SRC=.
|
||||
@@ -9,6 +11,7 @@ PKGS = wayland-client xkbcommon pangocairo
|
||||
|
||||
WVKBD_SOURCES += $(wildcard $(SRC)/*.c)
|
||||
WVKBD_HEADERS += $(wildcard $(SRC)/*.h)
|
||||
WVKBD_DIR_SOURCES = $(foreach src, $(WVKBD_SOURCES), $(addprefix $(BUILDDIR)/, $(src)))
|
||||
|
||||
PKG_CONFIG ?= pkg-config
|
||||
CFLAGS += -std=gnu99 -Wall -g -DWITH_WAYLAND_SHM -DLAYOUT=\"layout.${LAYOUT}.h\" -DKEYMAP=\"keymap.${LAYOUT}.h\"
|
||||
@@ -20,16 +23,21 @@ WAYLAND_HEADERS = $(wildcard proto/*.xml)
|
||||
HDRS = $(WAYLAND_HEADERS:.xml=-client-protocol.h)
|
||||
WAYLAND_SRC = $(HDRS:.h=.c)
|
||||
SOURCES = $(WVKBD_SOURCES) $(WAYLAND_SRC)
|
||||
OBJECTS = $(WVKBD_DIR_SOURCES:.c=.o) $(WAYLAND_SRC:.c=.o)
|
||||
|
||||
SCDOC=scdoc
|
||||
DOCS = wvkbd.1
|
||||
|
||||
OBJECTS = $(SOURCES:.c=.o)
|
||||
|
||||
all: ${BIN} ${DOCS}
|
||||
|
||||
config.h:
|
||||
cp config.${LAYOUT}.h config.h
|
||||
$(BUILDDIR)/config.h:
|
||||
mkdir -p $(BUILDDIR)
|
||||
cp config.$(LAYOUT).h $@
|
||||
|
||||
$(BUILDDIR)/%.o: %.c
|
||||
mkdir -p $(BUILDDIR)
|
||||
$(CC) -I $(CURDIR) -I $(CURDIR)/$(BUILDDIR) -c $(CFLAGS) -o $@ $<
|
||||
|
||||
proto/%-client-protocol.c: proto/%.xml
|
||||
wayland-scanner code < $? > $@
|
||||
@@ -39,11 +47,11 @@ proto/%-client-protocol.h: proto/%.xml
|
||||
|
||||
$(OBJECTS): $(HDRS) $(WVKBD_HEADERS)
|
||||
|
||||
wvkbd-${LAYOUT}: config.h $(OBJECTS) layout.${LAYOUT}.h
|
||||
wvkbd-${LAYOUT}: $(BUILDDIR)/config.h $(OBJECTS) layout.${LAYOUT}.h
|
||||
$(CC) -o wvkbd-${LAYOUT} $(OBJECTS) $(LDFLAGS)
|
||||
|
||||
clean:
|
||||
rm -f $(OBJECTS) config.h $(HDRS) $(WAYLAND_SRC) ${BIN} ${DOCS}
|
||||
rm -rf "$(BUILDDIR)" wvkbd-$(LAYOUT)
|
||||
|
||||
format:
|
||||
clang-format -i $(WVKBD_SOURCES) $(WVKBD_HEADERS)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
VERSION = 0.18
|
||||
VERSION = 0.19.2
|
||||
CFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=700
|
||||
PREFIX = /usr/local
|
||||
MANPREFIX = ${PREFIX}/share/man
|
||||
|
||||
71
keyboard.c
71
keyboard.c
@@ -274,12 +274,28 @@ kbd_get_layer_index(struct kbd *kb, struct layout *l)
|
||||
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
|
||||
kbd_unpress_key(struct kbd *kb, uint32_t time)
|
||||
{
|
||||
bool unlatch_shift, unlatch_ctrl, unlatch_alt, unlatch_super, unlatch_altgr;
|
||||
unlatch_shift = unlatch_ctrl = unlatch_alt = unlatch_super = unlatch_altgr = false;
|
||||
|
||||
bool unlatch_shift, unlatch_ctrl, unlatch_alt, unlatch_super, unlatch_altgr, unlatch_tab;
|
||||
unlatch_shift = unlatch_ctrl = unlatch_alt = unlatch_super = unlatch_altgr = unlatch_tab = false;
|
||||
if (kb->last_press) {
|
||||
unlatch_shift = (kb->mods & Shift) == Shift;
|
||||
unlatch_ctrl = (kb->mods & Ctrl) == Ctrl;
|
||||
@@ -287,22 +303,15 @@ kbd_unpress_key(struct kbd *kb, uint32_t time)
|
||||
unlatch_super = (kb->mods & Super) == Super;
|
||||
unlatch_altgr = (kb->mods & AltGr) == AltGr;
|
||||
|
||||
if (unlatch_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);
|
||||
}
|
||||
|
||||
if (kb->last_press->type == Copy) {
|
||||
zwp_virtual_keyboard_v1_key(kb->vkbd, time, 127, // COMP key
|
||||
WL_KEYBOARD_KEY_STATE_RELEASED);
|
||||
} else {
|
||||
if ((kb->shift_space_is_tab) && (kb->last_press->code == KEY_SPACE) && (unlatch_shift)) {
|
||||
// shift + space is tab
|
||||
unlatch_shift = false;
|
||||
unlatch_tab = true;
|
||||
kb->mods ^= Shift;
|
||||
zwp_virtual_keyboard_v1_key(kb->vkbd, time, KEY_TAB,
|
||||
WL_KEYBOARD_KEY_STATE_RELEASED);
|
||||
} else {
|
||||
@@ -312,10 +321,35 @@ 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) {
|
||||
kb->compose = 0;
|
||||
kbd_switch_layout(kb, kb->last_abc_layout, kb->last_abc_index);
|
||||
} else if (unlatch_shift||unlatch_ctrl||unlatch_alt||unlatch_super||unlatch_altgr) {
|
||||
} else if (unlatch_shift||unlatch_ctrl||unlatch_alt||unlatch_super||unlatch_altgr||unlatch_tab) {
|
||||
kbd_draw_layout(kb);
|
||||
} else {
|
||||
kbd_draw_key(kb, kb->last_press, Unpress);
|
||||
@@ -392,6 +426,7 @@ kbd_press_key(struct kbd *kb, struct key *k, uint32_t time)
|
||||
switch (k->type) {
|
||||
case Code:
|
||||
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) {
|
||||
zwp_virtual_keyboard_v1_modifiers(kb->vkbd, k->code_mod, 0, 0,
|
||||
0);
|
||||
@@ -406,7 +441,8 @@ kbd_press_key(struct kbd *kb, struct key *k, uint32_t time)
|
||||
kbd_draw_key(kb, k, Press);
|
||||
if ((kb->shift_space_is_tab) && (k->code == KEY_SPACE) && (kb->mods & Shift)) {
|
||||
// shift space is tab
|
||||
zwp_virtual_keyboard_v1_modifiers(kb->vkbd, 0, 0, 0, 0);
|
||||
zwp_virtual_keyboard_v1_key_mods(kb->vkbd, time, Shift, WL_KEYBOARD_KEY_STATE_RELEASED);
|
||||
zwp_virtual_keyboard_v1_modifiers(kb->vkbd, kb->mods ^ Shift, 0, 0, 0);
|
||||
zwp_virtual_keyboard_v1_key(kb->vkbd, time, KEY_TAB,
|
||||
WL_KEYBOARD_KEY_STATE_PRESSED);
|
||||
} else {
|
||||
@@ -423,6 +459,11 @@ kbd_press_key(struct kbd *kb, struct key *k, uint32_t time)
|
||||
break;
|
||||
case Mod:
|
||||
kb->mods ^= k->code;
|
||||
if (kb->mods & k->code) {
|
||||
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);
|
||||
} else {
|
||||
|
||||
374
main.c
374
main.c
@@ -47,18 +47,10 @@ static struct wp_fractional_scale_manager_v1 *wfs_mgr;
|
||||
static struct wp_viewport *draw_surf_viewport, *popup_draw_surf_viewport;
|
||||
static struct wp_viewporter *viewporter;
|
||||
static bool popup_xdg_surface_configured;
|
||||
static bool layer_surface_configured;
|
||||
|
||||
struct Output {
|
||||
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;
|
||||
static uint32_t available_width, available_height = 0;
|
||||
static void refresh_available_dimension();
|
||||
|
||||
/* drawing */
|
||||
static struct drw draw_ctx;
|
||||
@@ -116,11 +108,6 @@ static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
|
||||
static void seat_handle_name(void *data, struct wl_seat *wl_seat,
|
||||
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,
|
||||
uint32_t name, const char *interface,
|
||||
uint32_t version);
|
||||
@@ -132,8 +119,9 @@ static void layer_surface_configure(void *data,
|
||||
uint32_t serial, uint32_t w, uint32_t h);
|
||||
static void layer_surface_closed(void *data,
|
||||
struct zwlr_layer_surface_v1 *surface);
|
||||
static void flip_landscape();
|
||||
static void redimension_keyboard();
|
||||
static void show();
|
||||
static void hide();
|
||||
|
||||
/* event handlers */
|
||||
static const struct wl_pointer_listener pointer_listener = {
|
||||
@@ -159,9 +147,33 @@ static const struct wl_seat_listener seat_listener = {
|
||||
.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 = {
|
||||
.enter = wl_surface_enter,
|
||||
.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 = {
|
||||
@@ -169,6 +181,25 @@ static const struct wl_registry_listener registry_listener = {
|
||||
.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 = {
|
||||
.configure = layer_surface_configure,
|
||||
.closed = layer_surface_closed,
|
||||
@@ -194,7 +225,7 @@ wl_touch_down(void *data, struct wl_touch *wl_touch, uint32_t serial,
|
||||
uint32_t time, struct wl_surface *surface, int32_t id,
|
||||
wl_fixed_t x, wl_fixed_t y)
|
||||
{
|
||||
if(!popup_xdg_surface_configured) {
|
||||
if(!layer_surface_configured || !popup_xdg_surface_configured) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -220,7 +251,7 @@ void
|
||||
wl_touch_up(void *data, struct wl_touch *wl_touch, uint32_t serial,
|
||||
uint32_t time, int32_t id)
|
||||
{
|
||||
if(!popup_xdg_surface_configured) {
|
||||
if(!layer_surface_configured || !popup_xdg_surface_configured) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -231,7 +262,7 @@ void
|
||||
wl_touch_motion(void *data, struct wl_touch *wl_touch, uint32_t time,
|
||||
int32_t id, wl_fixed_t x, wl_fixed_t y)
|
||||
{
|
||||
if(!popup_xdg_surface_configured) {
|
||||
if(!layer_surface_configured || !popup_xdg_surface_configured) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -283,7 +314,7 @@ void
|
||||
wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, uint32_t time,
|
||||
wl_fixed_t surface_x, wl_fixed_t surface_y)
|
||||
{
|
||||
if(!popup_xdg_surface_configured) {
|
||||
if(!layer_surface_configured || !popup_xdg_surface_configured) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -299,7 +330,7 @@ void
|
||||
wl_pointer_button(void *data, struct wl_pointer *wl_pointer, uint32_t serial,
|
||||
uint32_t time, uint32_t button, uint32_t state)
|
||||
{
|
||||
if(!popup_xdg_surface_configured) {
|
||||
if(!layer_surface_configured || !popup_xdg_surface_configured) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -328,7 +359,7 @@ void
|
||||
wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, uint32_t time,
|
||||
uint32_t axis, wl_fixed_t value)
|
||||
{
|
||||
if(!popup_xdg_surface_configured) {
|
||||
if(!layer_surface_configured || !popup_xdg_surface_configured) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -368,82 +399,6 @@ 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
|
||||
xdg_wm_base_ping(void *data, struct xdg_wm_base *xdg_wm_base, uint32_t serial)
|
||||
{
|
||||
@@ -460,19 +415,9 @@ handle_global(void *data, struct wl_registry *registry, uint32_t name,
|
||||
{
|
||||
if (strcmp(interface, wl_compositor_interface.name) == 0) {
|
||||
compositor =
|
||||
wl_registry_bind(registry, name, &wl_compositor_interface, 3);
|
||||
wl_registry_bind(registry, name, &wl_compositor_interface, 6);
|
||||
} else if (strcmp(interface, wl_shm_interface.name) == 0) {
|
||||
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) {
|
||||
seat = wl_registry_bind(registry, name, &wl_seat_interface, 1);
|
||||
wl_seat_add_listener(seat, &seat_listener, NULL);
|
||||
@@ -499,16 +444,6 @@ handle_global(void *data, struct wl_registry *registry, uint32_t name,
|
||||
void
|
||||
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
|
||||
@@ -554,15 +489,9 @@ static const struct wp_fractional_scale_v1_listener
|
||||
};
|
||||
|
||||
void
|
||||
flip_landscape()
|
||||
redimension_keyboard()
|
||||
{
|
||||
bool previous_landscape = keyboard.landscape;
|
||||
|
||||
if (current_output) {
|
||||
keyboard.landscape = current_output->w > current_output->h;
|
||||
} else if (wl_outputs_size) {
|
||||
keyboard.landscape = wl_outputs[0].w > wl_outputs[0].h;
|
||||
}
|
||||
keyboard.landscape = available_width > available_height;
|
||||
|
||||
enum layout_id layer;
|
||||
if (keyboard.landscape) {
|
||||
@@ -573,102 +502,80 @@ flip_landscape()
|
||||
height = normal_height;
|
||||
}
|
||||
|
||||
keyboard.w = available_width;
|
||||
keyboard.h = height;
|
||||
keyboard.layout = &keyboard.layouts[layer];
|
||||
keyboard.layer_index = 0;
|
||||
keyboard.prevlayout = keyboard.layout;
|
||||
keyboard.last_abc_layout = keyboard.layout;
|
||||
keyboard.last_abc_index = 0;
|
||||
|
||||
if (layer_surface && previous_landscape != keyboard.landscape) {
|
||||
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);
|
||||
layer_surface = NULL;
|
||||
wl_surface_destroy(draw_surf.surf);
|
||||
|
||||
show();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface,
|
||||
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;
|
||||
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.scale = scale;
|
||||
hidden = false;
|
||||
|
||||
keyboard.w = w;
|
||||
keyboard.h = 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_attach(&draw_surf);
|
||||
keyboard.output = current_output;
|
||||
if (wfs_mgr && viewporter) {
|
||||
wp_viewport_set_destination(draw_surf_viewport, keyboard.w,
|
||||
keyboard.h);
|
||||
} else {
|
||||
zwlr_layer_surface_v1_ack_configure(surface, serial);
|
||||
wl_surface_set_buffer_scale(draw_surf.surf, keyboard.scale);
|
||||
}
|
||||
|
||||
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
|
||||
@@ -740,18 +647,40 @@ hide()
|
||||
return;
|
||||
}
|
||||
|
||||
if(wfs_draw_surf) {
|
||||
if (wfs_draw_surf) {
|
||||
wp_fractional_scale_v1_destroy(wfs_draw_surf);
|
||||
wfs_draw_surf = NULL;
|
||||
}
|
||||
if(draw_surf_viewport) {
|
||||
if (draw_surf_viewport) {
|
||||
wp_viewport_destroy(draw_surf_viewport);
|
||||
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);
|
||||
wl_surface_destroy(draw_surf.surf);
|
||||
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);
|
||||
draw_surf.attached = false;
|
||||
|
||||
hidden = true;
|
||||
}
|
||||
|
||||
@@ -762,12 +691,12 @@ show()
|
||||
return;
|
||||
}
|
||||
|
||||
wl_display_sync(display);
|
||||
|
||||
flip_landscape();
|
||||
refresh_available_dimension();
|
||||
redimension_keyboard();
|
||||
|
||||
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);
|
||||
@@ -778,8 +707,6 @@ show()
|
||||
}
|
||||
|
||||
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_shell, draw_surf.surf, current_output_data, layer, namespace);
|
||||
@@ -830,6 +757,25 @@ 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
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user