do not edit — generated by btf.
git.druid.rocksindexmilitantprogrammerastral_canvassrc/input/input.c

src/input/input.c


#include "input/input.h"
 
#include <linux/input-event-codes.h>
#include <stdlib.h>
#include <string.h>
#include <xkbcommon/xkbcommon-keysyms.h>
 
int inputXkbInit(InputXkb *input)
{
    memset(input, 0, sizeof(*input));
    input->context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
    if (!input->context)
        return -1;
 
    const char *locale = getenv("LC_ALL");
    if (!locale || !locale[0])
        locale = getenv("LC_CTYPE");
    if (!locale || !locale[0])
        locale = getenv("LANG");
    if (!locale || !locale[0])
        locale = "C";
 
    input->composeTable = xkb_compose_table_new_from_locale(input->context, locale,
                                                            XKB_COMPOSE_COMPILE_NO_FLAGS);
    if (input->composeTable) {
        input->compose = xkb_compose_state_new(input->composeTable, XKB_COMPOSE_STATE_NO_FLAGS);
        if (!input->compose) {
            xkb_compose_table_unref(input->composeTable);
            input->composeTable = NULL;
        }
    }
    return 0;
}
 
void inputXkbFinish(InputXkb *input)
{
    if (!input)
        return;
    xkb_compose_state_unref(input->compose);
    xkb_compose_table_unref(input->composeTable);
    xkb_state_unref(input->state);
    xkb_keymap_unref(input->keymap);
    xkb_context_unref(input->context);
    memset(input, 0, sizeof(*input));
}
 
void inputXkbSetKeymap(InputXkb *input, struct xkb_keymap *keymap, struct xkb_state *state)
{
    xkb_state_unref(input->state);
    xkb_keymap_unref(input->keymap);
    input->keymap = keymap;
    input->state = state;
    if (input->compose)
        xkb_compose_state_reset(input->compose);
}
 
static int modifierActive(const InputXkb *input, const char *name)
{
    if (!input->state)
        return 0;
    return xkb_state_mod_name_is_active(input->state, name, XKB_STATE_MODS_EFFECTIVE) > 0;
}
 
uint32_t inputModifiers(const InputXkb *input)
{
    uint32_t modifiers = 0;
    if (modifierActive(input, XKB_MOD_NAME_SHIFT))
        modifiers |= MOD_SHIFT;
    if (modifierActive(input, XKB_MOD_NAME_CAPS))
        modifiers |= MOD_CAPS;
    if (modifierActive(input, XKB_MOD_NAME_CTRL))
        modifiers |= MOD_CTRL;
    if (modifierActive(input, "Alt") || modifierActive(input, XKB_MOD_NAME_ALT))
        modifiers |= MOD_ALT;
    if (modifierActive(input, "NumLock") || modifierActive(input, XKB_MOD_NAME_NUM))
        modifiers |= MOD_NUM;
    if (modifierActive(input, "Super") || modifierActive(input, XKB_MOD_NAME_LOGO))
        modifiers |= MOD_SUPER;
    return modifiers;
}
 
void input_fill_key(const InputXkb *input, KeyEvent *event, xkb_keycode_t keyCode,
                    bool pressed, bool repeat)
{
    memset(event, 0, sizeof(*event));
    event->keyCode = keyCode;
    event->pressed = pressed;
    event->repeat = repeat;
    event->modifiers = inputModifiers(input);
 
    if (!input->state)
        return;
 
    xkb_keysym_t keysym = xkb_state_key_get_one_sym(input->state, keyCode);
 
    if (pressed && input->compose) {
        if (!repeat)
            xkb_compose_state_feed(input->compose, keysym);
        enum xkb_compose_status status = xkb_compose_state_get_status(input->compose);
        if (status == XKB_COMPOSE_COMPOSED) {
            keysym = xkb_compose_state_get_one_sym(input->compose);
            xkb_compose_state_get_utf8(input->compose, event->utf8, sizeof(event->utf8));
            xkb_compose_state_reset(input->compose);
        } else if (status == XKB_COMPOSE_COMPOSING) {
            keysym = XKB_KEY_NoSymbol;
            event->utf8[0] = 0;
        } else if (status == XKB_COMPOSE_CANCELLED) {
            xkb_compose_state_reset(input->compose);
        } else {
            xkb_state_key_get_utf8(input->state, keyCode, event->utf8, sizeof(event->utf8));
        }
    } else if (pressed) {
        xkb_state_key_get_utf8(input->state, keyCode, event->utf8, sizeof(event->utf8));
    }
 
    event->keysym = keysym;
    event->utf32 = xkb_keysym_to_utf32(keysym);
    xkb_keysym_get_name(keysym, event->name, sizeof(event->name));
}
 
uint32_t linuxButtonToButton(uint32_t linuxCode)
{
    switch (linuxCode) {
    case BTN_LEFT:    return BUTTON_LEFT;
    case BTN_MIDDLE:  return BUTTON_MIDDLE;
    case BTN_RIGHT:   return BUTTON_RIGHT;
    case BTN_SIDE:    return BUTTON_BACK;
    case BTN_EXTRA:   return BUTTON_FORWARD;
    default:          return 0;
    }
}
powered by btf.