/*
- * uterm - Linux User-Space Terminal
+ * uterm - Linux User-Space Terminal Input Handling
*
- * Copyright (c) 2011-2012 David Herrmann <dh.herrmann@googlemail.com>
+ * Copyright (c) 2011-2013 David Herrmann <dh.herrmann@googlemail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-/* Internal definitions */
+/*
+ * Input Devices
+ * This input object can combine multiple linux input devices into a single
+ * device and notifies the application about events. It has several different
+ * keyboard backends so the full XKB feature set is available.
+ */
-#ifndef UTERM_INPUT_H
-#define UTERM_INPUT_H
+#ifndef UTERM_UTERM_INPUT_H
+#define UTERM_UTERM_INPUT_H
+#include <eloop.h>
#include <inttypes.h>
-#include <limits.h>
#include <stdbool.h>
#include <stdlib.h>
-#include <xkbcommon/xkbcommon-keysyms.h>
-#include "eloop.h"
-#include "uterm.h"
-
-struct kbd_desc;
-struct kbd_dev;
-
-struct kbd_desc_ops {
- int (*init) (struct kbd_desc **out, const char *layout,
- const char *variant, const char *options);
- void (*ref) (struct kbd_desc *desc);
- void (*unref) (struct kbd_desc *desc);
- int (*alloc) (struct kbd_desc *desc, struct kbd_dev **out);
- void (*keysym_to_string) (uint32_t keysym, char *str, size_t size);
- int (*string_to_keysym) (const char *n, uint32_t *out);
-};
-struct kbd_dev_ops {
- void (*ref) (struct kbd_dev *dev);
- void (*unref) (struct kbd_dev *dev);
- void (*reset) (struct kbd_dev *dev, const unsigned long *ledbits);
- int (*process) (struct kbd_dev *dev, uint16_t state, uint16_t code,
- struct uterm_input_event *out);
+struct uterm_input;
+
+typedef void (*uterm_input_log_t) (void *data,
+ const char *file,
+ int line,
+ const char *func,
+ const char *subs,
+ unsigned int sev,
+ const char *format,
+ va_list args);
+
+/* keep in sync with shl_xkb_mods */
+enum uterm_input_modifier {
+ UTERM_SHIFT_MASK = (1 << 0),
+ UTERM_LOCK_MASK = (1 << 1),
+ UTERM_CONTROL_MASK = (1 << 2),
+ UTERM_ALT_MASK = (1 << 3),
+ UTERM_LOGO_MASK = (1 << 4),
};
-struct plain_desc {
- int unused;
-};
-
-struct plain_dev {
- unsigned int mods;
-};
+/* keep in sync with TSM_VTE_INVALID */
+#define UTERM_INPUT_INVALID 0xffffffff
-static const bool plain_available = true;
-extern const struct kbd_desc_ops plain_desc_ops;
-extern const struct kbd_dev_ops plain_dev_ops;
+struct uterm_input_event {
+ bool handled; /* user-controlled, default is false */
+ uint16_t keycode; /* linux keycode - KEY_* - linux/input.h */
+ uint32_t ascii; /* ascii keysym for @keycode */
+ unsigned int mods; /* active modifiers - uterm_modifier mask */
-extern int plain_string_to_keysym(const char *n, uint32_t *out);
-
-#ifdef UTERM_HAVE_XKBCOMMON
-
-struct uxkb_desc {
- struct xkb_context *ctx;
- struct xkb_keymap *keymap;
+ unsigned int num_syms; /* number of keysyms */
+ uint32_t *keysyms; /* XKB-common keysym-array - XKB_KEY_* */
+ uint32_t *codepoints; /* ucs4 unicode value or UTERM_INPUT_INVALID */
};
-struct uxkb_dev {
- struct xkb_state *state;
-};
+#define UTERM_INPUT_HAS_MODS(_ev, _mods) (((_ev)->mods & (_mods)) == (_mods))
-static const bool uxkb_available = true;
-extern const struct kbd_desc_ops uxkb_desc_ops;
-extern const struct kbd_dev_ops uxkb_dev_ops;
+typedef void (*uterm_input_cb) (struct uterm_input *input,
+ struct uterm_input_event *ev,
+ void *data);
-extern int uxkb_string_to_keysym(const char *n, uint32_t *out);
+int uterm_input_new(struct uterm_input **out, struct ev_eloop *eloop,
+ const char *model, const char *layout, const char *variant,
+ const char *options, const char *keymap,
+ unsigned int repeat_delay, unsigned int repeat_rate,
+ uterm_input_log_t log, void *log_data);
+void uterm_input_ref(struct uterm_input *input);
+void uterm_input_unref(struct uterm_input *input);
-#else /* !UTERM_HAVE_XKBCOMMON */
+void uterm_input_add_dev(struct uterm_input *input, const char *node);
+void uterm_input_remove_dev(struct uterm_input *input, const char *node);
-struct uxkb_desc {
- int unused;
-};
+int uterm_input_register_cb(struct uterm_input *input, uterm_input_cb cb,
+ void *data);
+void uterm_input_unregister_cb(struct uterm_input *input, uterm_input_cb cb,
+ void *data);
-struct uxkb_dev {
- int unused;
-};
-
-static const bool uxkb_available = false;
-static const struct kbd_desc_ops uxkb_desc_ops;
-static const struct kbd_dev_ops uxkb_dev_ops;
-
-#endif /* UTERM_HAVE_XKBCOMMON */
-
-struct kbd_desc {
- unsigned long ref;
- const struct kbd_desc_ops *ops;
-
- union {
- struct plain_desc plain;
- struct uxkb_desc uxkb;
- };
-};
-
-struct kbd_dev {
- unsigned long ref;
- struct kbd_desc *desc;
- const struct kbd_dev_ops *ops;
-
- union {
- struct plain_dev plain;
- struct uxkb_dev uxkb;
- };
-};
-
-enum kbd_mode {
- KBD_PLAIN,
- KBD_UXKB,
-};
+void uterm_input_sleep(struct uterm_input *input);
+void uterm_input_wake_up(struct uterm_input *input);
+bool uterm_input_is_awake(struct uterm_input *input);
-static inline int kbd_desc_new(struct kbd_desc **out, const char *layout,
- const char *variant, const char *options,
- unsigned int mode)
-{
- const struct kbd_desc_ops *ops;
-
- switch (mode) {
- case KBD_UXKB:
- if (!uxkb_available) {
- log_error("XKB KBD backend not available");
- return -EOPNOTSUPP;
- }
- ops = &uxkb_desc_ops;
- break;
- case KBD_PLAIN:
- if (!plain_available) {
- log_error("plain KBD backend not available");
- return -EOPNOTSUPP;
- }
- ops = &plain_desc_ops;
- break;
- default:
- log_error("unknown KBD backend %u", mode);
- return -EINVAL;
- }
-
- return ops->init(out, layout, variant, options);
-}
-
-static inline void kbd_desc_ref(struct kbd_desc *desc)
-{
- if (!desc)
- return;
-
- return desc->ops->ref(desc);
-}
-
-static inline void kbd_desc_unref(struct kbd_desc *desc)
-{
- if (!desc)
- return;
-
- return desc->ops->unref(desc);
-}
-
-static inline int kbd_desc_alloc(struct kbd_desc *desc, struct kbd_dev **out)
-{
- if (!desc)
- return -EINVAL;
-
- return desc->ops->alloc(desc, out);
-}
-
-static inline void kbd_desc_keysym_to_string(struct kbd_desc *desc,
- uint32_t keysym,
- char *str, size_t size)
-{
- if (!desc)
- return;
-
- return desc->ops->keysym_to_string(keysym, str, size);
-}
-
-static inline int kbd_desc_string_to_keysym(struct kbd_desc *desc,
- const char *n,
- uint32_t *out)
-{
- if (!desc)
- return -EINVAL;
-
- return desc->ops->string_to_keysym(n, out);
-}
-
-static inline void kbd_dev_ref(struct kbd_dev *dev)
-{
- if (!dev)
- return;
-
- return dev->ops->ref(dev);
-}
-
-static inline void kbd_dev_unref(struct kbd_dev *dev)
-{
- if (!dev)
- return;
-
- return dev->ops->unref(dev);
-}
-
-static inline void kbd_dev_reset(struct kbd_dev *dev,
- const unsigned long *ledbits)
-{
- if (!dev)
- return;
-
- return dev->ops->reset(dev, ledbits);
-}
-
-static inline int kbd_dev_process(struct kbd_dev *dev,
- uint16_t key_state,
- uint16_t code,
- struct uterm_input_event *out)
-{
- if (!dev)
- return -EINVAL;
-
- return dev->ops->process(dev, key_state, code, out);
-}
-
-static inline bool input_bit_is_set(const unsigned long *array, int bit)
-{
- return !!(array[bit / LONG_BIT] & (1LL << (bit % LONG_BIT)));
-}
-
-#endif /* UTERM_INPUT_H */
+#endif /* UTERM_UTERM_INPUT_H */