uterm: input: remove plain backend
[platform/upstream/kmscon.git] / src / uterm_input.h
1 /*
2  * uterm - Linux User-Space Terminal
3  *
4  * Copyright (c) 2011-2012 David Herrmann <dh.herrmann@googlemail.com>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a copy of this software and associated documentation files
8  * (the "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sublicense, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included
15  * in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  */
25
26 /* Internal definitions */
27
28 #ifndef UTERM_INPUT_H
29 #define UTERM_INPUT_H
30
31 #include <inttypes.h>
32 #include <limits.h>
33 #include <stdbool.h>
34 #include <stdlib.h>
35 #include <xkbcommon/xkbcommon-keysyms.h>
36 #include "eloop.h"
37 #include "uterm.h"
38
39 struct kbd_desc;
40 struct kbd_dev;
41
42 struct kbd_desc_ops {
43         int (*init) (struct kbd_desc **out, const char *layout,
44                      const char *variant, const char *options);
45         void (*ref) (struct kbd_desc *desc);
46         void (*unref) (struct kbd_desc *desc);
47         int (*alloc) (struct kbd_desc *desc, struct kbd_dev **out);
48         void (*keysym_to_string) (uint32_t keysym, char *str, size_t size);
49         int (*string_to_keysym) (const char *n, uint32_t *out);
50 };
51
52 struct kbd_dev_ops {
53         void (*ref) (struct kbd_dev *dev);
54         void (*unref) (struct kbd_dev *dev);
55         void (*reset) (struct kbd_dev *dev, const unsigned long *ledbits);
56         int (*process) (struct kbd_dev *dev, uint16_t state, uint16_t code,
57                         struct uterm_input_event *out);
58 };
59
60 struct uxkb_desc {
61         struct xkb_context *ctx;
62         struct xkb_keymap *keymap;
63 };
64
65 struct uxkb_dev {
66         struct xkb_state *state;
67 };
68
69 static const bool uxkb_available = true;
70 extern const struct kbd_desc_ops uxkb_desc_ops;
71 extern const struct kbd_dev_ops uxkb_dev_ops;
72
73 extern int uxkb_string_to_keysym(const char *n, uint32_t *out);
74
75 struct kbd_desc {
76         unsigned long ref;
77         const struct kbd_desc_ops *ops;
78
79         union {
80                 struct uxkb_desc uxkb;
81         };
82 };
83
84 struct kbd_dev {
85         unsigned long ref;
86         struct kbd_desc *desc;
87         const struct kbd_dev_ops *ops;
88
89         union {
90                 struct uxkb_dev uxkb;
91         };
92 };
93
94 enum kbd_mode {
95         KBD_UXKB,
96 };
97
98 static inline int kbd_desc_new(struct kbd_desc **out, const char *layout,
99                                const char *variant, const char *options,
100                                unsigned int mode)
101 {
102         const struct kbd_desc_ops *ops;
103
104         switch (mode) {
105         case KBD_UXKB:
106                 if (!uxkb_available) {
107                         log_error("XKB KBD backend not available");
108                         return -EOPNOTSUPP;
109                 }
110                 ops = &uxkb_desc_ops;
111                 break;
112         default:
113                 log_error("unknown KBD backend %u", mode);
114                 return -EINVAL;
115         }
116
117         return ops->init(out, layout, variant, options);
118 }
119
120 static inline void kbd_desc_ref(struct kbd_desc *desc)
121 {
122         if (!desc)
123                 return;
124
125         return desc->ops->ref(desc);
126 }
127
128 static inline void kbd_desc_unref(struct kbd_desc *desc)
129 {
130         if (!desc)
131                 return;
132
133         return desc->ops->unref(desc);
134 }
135
136 static inline int kbd_desc_alloc(struct kbd_desc *desc, struct kbd_dev **out)
137 {
138         if (!desc)
139                 return -EINVAL;
140
141         return desc->ops->alloc(desc, out);
142 }
143
144 static inline void kbd_desc_keysym_to_string(struct kbd_desc *desc,
145                                              uint32_t keysym,
146                                              char *str, size_t size)
147 {
148         if (!desc)
149                 return;
150
151         return desc->ops->keysym_to_string(keysym, str, size);
152 }
153
154 static inline int kbd_desc_string_to_keysym(struct kbd_desc *desc,
155                                             const char *n,
156                                             uint32_t *out)
157 {
158         if (!desc)
159                 return -EINVAL;
160
161         return desc->ops->string_to_keysym(n, out);
162 }
163
164 static inline void kbd_dev_ref(struct kbd_dev *dev)
165 {
166         if (!dev)
167                 return;
168
169         return dev->ops->ref(dev);
170 }
171
172 static inline void kbd_dev_unref(struct kbd_dev *dev)
173 {
174         if (!dev)
175                 return;
176
177         return dev->ops->unref(dev);
178 }
179
180 static inline void kbd_dev_reset(struct kbd_dev *dev,
181                                  const unsigned long *ledbits)
182 {
183         if (!dev)
184                 return;
185
186         return dev->ops->reset(dev, ledbits);
187 }
188
189 static inline int kbd_dev_process(struct kbd_dev *dev,
190                                   uint16_t key_state,
191                                   uint16_t code,
192                                   struct uterm_input_event *out)
193 {
194         if (!dev)
195                 return -EINVAL;
196
197         return dev->ops->process(dev, key_state, code, out);
198 }
199
200 static inline bool input_bit_is_set(const unsigned long *array, int bit)
201 {
202         return !!(array[bit / LONG_BIT] & (1LL << (bit % LONG_BIT)));
203 }
204
205 #endif /* UTERM_INPUT_H */