Skip to content

Commit

Permalink
Use XKB to handle keyboard input
Browse files Browse the repository at this point in the history
Resolves artemsen#2.

Signed-off-by: Artem Senichev <[email protected]>
  • Loading branch information
artemsen authored and Artem Senichev committed Mar 27, 2021
1 parent acc22de commit 1985456
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 49 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
run: >
sudo apt install --no-install-recommends --yes
build-essential meson pkg-config wayland-protocols
libwayland-dev libcairo-dev libjson-c-dev
libwayland-dev libcairo-dev libjson-c-dev libxkbcommon-dev
libgif-dev libjpeg-dev librsvg2-dev libwebp-dev
- name: Configure
Expand Down
15 changes: 9 additions & 6 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,17 @@ add_project_arguments(

cc = meson.get_compiler('c')

# project dependencies
# mandatory dependencies
wlcln = dependency('wayland-client')
cairo = dependency('cairo')
json = dependency('json-c')
xkb = dependency('xkbcommon')
rt = cc.find_library('rt')
# optional dependencies
jpeg = dependency('libjpeg', required: get_option('jpeg'))
rsvg = dependency('librsvg-2.0', version: '>=2.14', required: get_option('svg'))
webp = dependency('libwebp', required: get_option('webp'))
gif = cc.find_library('gif', required: get_option('gif'))
rt = cc.find_library('rt')
bash = dependency('bash-completion', required: get_option('bash'))

# configuration file
Expand Down Expand Up @@ -113,14 +115,15 @@ executable(
'swayimg',
sources,
dependencies: [
wlcln,
cairo,
json,
gif,
jpeg,
json,
rsvg,
webp,
gif,
rt,
webp,
wlcln,
xkb,
],
install: true
)
65 changes: 27 additions & 38 deletions src/viewer.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <linux/input.h>

// Scale thresholds
#define MIN_SCALE_PIXEL 10
Expand Down Expand Up @@ -318,60 +317,50 @@ static void on_resize(void)
}

/** Keyboard handler, see handlers::on_keyboard. */
static bool on_keyboard(uint32_t key)
static bool on_keyboard(xkb_keysym_t key)
{
switch (key) {
case KEY_PAGEUP:
case KEY_KP9:
case KEY_P:
case XKB_KEY_SunPageUp:
case XKB_KEY_p:
return load_next_file(false);
case KEY_PAGEDOWN:
case KEY_KP3:
case KEY_N:
case XKB_KEY_SunPageDown:
case XKB_KEY_n:
return load_next_file(true);
case KEY_LEFT:
case KEY_KP4:
case KEY_H:
case XKB_KEY_Left:
case XKB_KEY_h:
return change_position(move_left);
case KEY_RIGHT:
case KEY_KP6:
case KEY_L:
case XKB_KEY_Right:
case XKB_KEY_l:
return change_position(move_right);
case KEY_UP:
case KEY_KP8:
case KEY_K:
case XKB_KEY_Up:
case XKB_KEY_k:
return change_position(move_up);
case KEY_DOWN:
case KEY_KP2:
case KEY_J:
case XKB_KEY_Down:
case XKB_KEY_j:
return change_position(move_down);
case KEY_EQUAL:
case KEY_KPPLUS:
case XKB_KEY_equal:
case XKB_KEY_plus:
return change_scale(zoom_in);
case KEY_MINUS:
case KEY_KPMINUS:
case XKB_KEY_minus:
return change_scale(zoom_out);
case KEY_0:
case XKB_KEY_0:
return change_scale(actual_size);
case KEY_BACKSPACE:
case XKB_KEY_BackSpace:
return change_scale(optimal_scale);
case KEY_I:
case XKB_KEY_i:
viewer.show_info = !viewer.show_info;
return true;
case KEY_F11:
case KEY_F:
case XKB_KEY_F11:
case XKB_KEY_f:
viewer.fullscreen = !viewer.fullscreen;
enable_fullscreen(viewer.fullscreen);
return false;
case KEY_ESC:
case KEY_ENTER:
case KEY_KPENTER:
case KEY_F3:
case KEY_F4:
case KEY_F10:
case KEY_Q:
case KEY_E:
case KEY_X:
case XKB_KEY_Escape:
case XKB_KEY_Return:
case XKB_KEY_F3:
case XKB_KEY_F4:
case XKB_KEY_F10:
case XKB_KEY_q:
close_window();
return false;
}
Expand Down
24 changes: 21 additions & 3 deletions src/window.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
#include <unistd.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <linux/input.h>

/** Loop state */
enum state {
Expand All @@ -42,6 +41,12 @@ struct context {
struct xdg_toplevel* toplevel;
} xdg;

struct xkb {
struct xkb_context* context;
struct xkb_keymap* keymap;
struct xkb_state* state;
} xkb;

struct surface {
cairo_surface_t* cairo;
struct wl_buffer* buffer;
Expand Down Expand Up @@ -159,7 +164,11 @@ static void on_keyboard_modifiers(void* data, struct wl_keyboard* wl_keyboard,
uint32_t serial, uint32_t mods_depressed,
uint32_t mods_latched, uint32_t mods_locked,
uint32_t group)
{}
{
xkb_state_update_mask(ctx.xkb.state,
mods_depressed, mods_latched, mods_locked,
0, 0, group);
}

static void on_keyboard_repeat_info(void* data, struct wl_keyboard* wl_keyboard,
int32_t rate, int32_t delay)
Expand All @@ -168,15 +177,23 @@ static void on_keyboard_repeat_info(void* data, struct wl_keyboard* wl_keyboard,
static void on_keyboard_keymap(void* data, struct wl_keyboard* wl_keyboard,
uint32_t format, int32_t fd, uint32_t size)
{
char* keymap = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
xkb_keymap_unref(ctx.xkb.keymap);
ctx.xkb.keymap = xkb_keymap_new_from_string(ctx.xkb.context, keymap,
XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
munmap(keymap, size);
close(fd);
xkb_state_unref(ctx.xkb.state);
ctx.xkb.state = xkb_state_new(ctx.xkb.keymap);
}

static void on_keyboard_key(void* data, struct wl_keyboard* wl_keyboard,
uint32_t serial, uint32_t time, uint32_t key,
uint32_t state)
{
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
if (ctx.handlers.on_keyboard(key)) {
xkb_keysym_t keysym = xkb_state_key_get_one_sym(ctx.xkb.state, key + 8);
if (keysym != XKB_KEY_NoSymbol && ctx.handlers.on_keyboard(keysym)) {
redraw();
}
}
Expand Down Expand Up @@ -310,6 +327,7 @@ bool create_window(const struct handlers* handlers, size_t width, size_t height,
fprintf(stderr, "Failed to open display\n");
return false;
}
ctx.xkb.context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
ctx.wl.registry = wl_display_get_registry(ctx.wl.display);
if (!ctx.wl.registry) {
fprintf(stderr, "Failed to open registry\n");
Expand Down
3 changes: 2 additions & 1 deletion src/window.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <stdint.h>
#include <stdbool.h>
#include <cairo/cairo.h>
#include <xkbcommon/xkbcommon.h>

/** UI event handlers. */
struct handlers {
Expand All @@ -27,7 +28,7 @@ struct handlers {
* @param[in] key code of key pressed
* @return true if state was changed and window must be redrawn
*/
bool (*on_keyboard)(uint32_t key);
bool (*on_keyboard)(xkb_keysym_t key);
};

/**
Expand Down

0 comments on commit 1985456

Please sign in to comment.