#pragma once
#include <inttypes.h>
+#include <libudev.h>
+#include <linux/input.h>
#include <stdbool.h>
#include <stdlib.h>
#include <systemd/sd-bus.h>
#include <systemd/sd-event.h>
+#include <xkbcommon/xkbcommon.h>
#include "util.h"
typedef struct idev_data idev_data;
+typedef struct idev_data_evdev idev_data_evdev;
+typedef struct idev_data_keyboard idev_data_keyboard;
typedef struct idev_event idev_event;
typedef struct idev_device idev_device;
*/
enum {
+ IDEV_ELEMENT_EVDEV,
IDEV_ELEMENT_CNT
};
enum {
+ IDEV_DEVICE_KEYBOARD,
IDEV_DEVICE_CNT
};
+/*
+ * Evdev Elements
+ */
+
+struct idev_data_evdev {
+ struct input_event event;
+};
+
+/*
+ * Keyboard Devices
+ */
+
+struct xkb_state;
+
+enum {
+ IDEV_KBDMOD_IDX_SHIFT,
+ IDEV_KBDMOD_IDX_CTRL,
+ IDEV_KBDMOD_IDX_ALT,
+ IDEV_KBDMOD_IDX_LINUX,
+ IDEV_KBDMOD_IDX_CAPS,
+ IDEV_KBDMOD_CNT,
+
+ IDEV_KBDMOD_SHIFT = 1 << IDEV_KBDMOD_IDX_SHIFT,
+ IDEV_KBDMOD_CTRL = 1 << IDEV_KBDMOD_IDX_CTRL,
+ IDEV_KBDMOD_ALT = 1 << IDEV_KBDMOD_IDX_ALT,
+ IDEV_KBDMOD_LINUX = 1 << IDEV_KBDMOD_IDX_LINUX,
+ IDEV_KBDMOD_CAPS = 1 << IDEV_KBDMOD_IDX_CAPS,
+};
+
+enum {
+ IDEV_KBDLED_IDX_NUM,
+ IDEV_KBDLED_IDX_CAPS,
+ IDEV_KBDLED_IDX_SCROLL,
+ IDEV_KBDLED_CNT,
+
+ IDEV_KBDLED_NUM = 1 << IDEV_KBDLED_IDX_NUM,
+ IDEV_KBDLED_CAPS = 1 << IDEV_KBDLED_IDX_CAPS,
+ IDEV_KBDLED_SCROLL = 1 << IDEV_KBDLED_IDX_SCROLL,
+};
+
+struct idev_data_keyboard {
+ struct xkb_state *xkb_state;
+ int8_t ascii;
+ uint8_t value;
+ uint16_t keycode;
+ uint32_t mods;
+ uint32_t consumed_mods;
+ uint32_t n_syms;
+ uint32_t *keysyms;
+ uint32_t *codepoints;
+};
+
+static inline bool idev_kbdmatch(idev_data_keyboard *kdata,
+ uint32_t mods, uint32_t n_syms,
+ const uint32_t *syms) {
+ const uint32_t significant = IDEV_KBDMOD_SHIFT |
+ IDEV_KBDMOD_CTRL |
+ IDEV_KBDMOD_ALT |
+ IDEV_KBDMOD_LINUX;
+ uint32_t real;
+
+ if (n_syms != kdata->n_syms)
+ return false;
+
+ real = kdata->mods & ~kdata->consumed_mods & significant;
+ if (real != mods)
+ return false;
+
+ return !memcmp(syms, kdata->keysyms, n_syms * sizeof(*syms));
+}
+
+#define IDEV_KBDMATCH(_kdata, _mods, _sym) \
+ idev_kbdmatch((_kdata), (_mods), 1, (const uint32_t[]){ (_sym) })
+
/*
* Data Packets
*/
enum {
IDEV_DATA_RESYNC,
+ IDEV_DATA_EVDEV,
+ IDEV_DATA_KEYBOARD,
IDEV_DATA_CNT
};
struct idev_data {
unsigned int type;
bool resync : 1;
+
+ union {
+ idev_data_evdev evdev;
+ idev_data_keyboard keyboard;
+ };
};
/*
void idev_session_enable(idev_session *s);
void idev_session_disable(idev_session *s);
+int idev_session_add_evdev(idev_session *s, struct udev_device *ud);
+int idev_session_remove_evdev(idev_session *s, struct udev_device *ud);
+
/*
* Contexts
*/