shl: move timer to shl_timer_*
[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 "eloop.h"
36 #include "uterm.h"
37
38 struct kbd_desc;
39 struct kbd_dev;
40
41 struct kbd_desc_ops {
42         int (*init) (struct kbd_desc **out, const char *layout,
43                      const char *variant, const char *options);
44         void (*ref) (struct kbd_desc *desc);
45         void (*unref) (struct kbd_desc *desc);
46         int (*alloc) (struct kbd_desc *desc, struct kbd_dev **out);
47         void (*keysym_to_string) (uint32_t keysym, char *str, size_t size);
48         int (*string_to_keysym) (const char *n, uint32_t *out);
49 };
50
51 struct kbd_dev_ops {
52         void (*ref) (struct kbd_dev *dev);
53         void (*unref) (struct kbd_dev *dev);
54         void (*reset) (struct kbd_dev *dev, const unsigned long *ledbits);
55         int (*process) (struct kbd_dev *dev, uint16_t state, uint16_t code,
56                         struct uterm_input_event *out);
57 };
58
59 struct plain_desc {
60         int unused;
61 };
62
63 struct plain_dev {
64         unsigned int mods;
65 };
66
67 static const bool plain_available = true;
68 extern const struct kbd_desc_ops plain_desc_ops;
69 extern const struct kbd_dev_ops plain_dev_ops;
70
71 extern int plain_string_to_keysym(const char *n, uint32_t *out);
72
73 #ifdef UTERM_HAVE_XKBCOMMON
74
75 struct uxkb_desc {
76         struct xkb_context *ctx;
77         struct xkb_keymap *keymap;
78 };
79
80 struct uxkb_dev {
81         struct xkb_state *state;
82 };
83
84 static const bool uxkb_available = true;
85 extern const struct kbd_desc_ops uxkb_desc_ops;
86 extern const struct kbd_dev_ops uxkb_dev_ops;
87
88 extern int uxkb_string_to_keysym(const char *n, uint32_t *out);
89
90 #else /* !UTERM_HAVE_XKBCOMMON */
91
92 struct uxkb_desc {
93         int unused;
94 };
95
96 struct uxkb_dev {
97         int unused;
98 };
99
100 static const bool uxkb_available = false;
101 static const struct kbd_desc_ops uxkb_desc_ops;
102 static const struct kbd_dev_ops uxkb_dev_ops;
103
104 #endif /* UTERM_HAVE_XKBCOMMON */
105
106 struct kbd_desc {
107         unsigned long ref;
108         const struct kbd_desc_ops *ops;
109
110         union {
111                 struct plain_desc plain;
112                 struct uxkb_desc uxkb;
113         };
114 };
115
116 struct kbd_dev {
117         unsigned long ref;
118         struct kbd_desc *desc;
119         const struct kbd_dev_ops *ops;
120
121         union {
122                 struct plain_dev plain;
123                 struct uxkb_dev uxkb;
124         };
125 };
126
127 enum kbd_mode {
128         KBD_PLAIN,
129         KBD_UXKB,
130 };
131
132 static inline int kbd_desc_new(struct kbd_desc **out, const char *layout,
133                                const char *variant, const char *options,
134                                unsigned int mode)
135 {
136         const struct kbd_desc_ops *ops;
137
138         switch (mode) {
139         case KBD_UXKB:
140                 if (!uxkb_available) {
141                         log_error("XKB KBD backend not available");
142                         return -EOPNOTSUPP;
143                 }
144                 ops = &uxkb_desc_ops;
145                 break;
146         case KBD_PLAIN:
147                 if (!plain_available) {
148                         log_error("plain KBD backend not available");
149                         return -EOPNOTSUPP;
150                 }
151                 ops = &plain_desc_ops;
152                 break;
153         default:
154                 log_error("unknown KBD backend %u", mode);
155                 return -EINVAL;
156         }
157
158         return ops->init(out, layout, variant, options);
159 }
160
161 static inline void kbd_desc_ref(struct kbd_desc *desc)
162 {
163         if (!desc)
164                 return;
165
166         return desc->ops->ref(desc);
167 }
168
169 static inline void kbd_desc_unref(struct kbd_desc *desc)
170 {
171         if (!desc)
172                 return;
173
174         return desc->ops->unref(desc);
175 }
176
177 static inline int kbd_desc_alloc(struct kbd_desc *desc, struct kbd_dev **out)
178 {
179         if (!desc)
180                 return -EINVAL;
181
182         return desc->ops->alloc(desc, out);
183 }
184
185 static inline void kbd_desc_keysym_to_string(struct kbd_desc *desc,
186                                              uint32_t keysym,
187                                              char *str, size_t size)
188 {
189         if (!desc)
190                 return;
191
192         return desc->ops->keysym_to_string(keysym, str, size);
193 }
194
195 static inline int kbd_desc_string_to_keysym(struct kbd_desc *desc,
196                                             const char *n,
197                                             uint32_t *out)
198 {
199         if (!desc)
200                 return -EINVAL;
201
202         return desc->ops->string_to_keysym(n, out);
203 }
204
205 static inline void kbd_dev_ref(struct kbd_dev *dev)
206 {
207         if (!dev)
208                 return;
209
210         return dev->ops->ref(dev);
211 }
212
213 static inline void kbd_dev_unref(struct kbd_dev *dev)
214 {
215         if (!dev)
216                 return;
217
218         return dev->ops->unref(dev);
219 }
220
221 static inline void kbd_dev_reset(struct kbd_dev *dev,
222                                  const unsigned long *ledbits)
223 {
224         if (!dev)
225                 return;
226
227         return dev->ops->reset(dev, ledbits);
228 }
229
230 static inline int kbd_dev_process(struct kbd_dev *dev,
231                                   uint16_t key_state,
232                                   uint16_t code,
233                                   struct uterm_input_event *out)
234 {
235         if (!dev)
236                 return -EINVAL;
237
238         return dev->ops->process(dev, key_state, code, out);
239 }
240
241 static inline bool input_bit_is_set(const unsigned long *array, int bit)
242 {
243         return !!(array[bit / LONG_BIT] & (1LL << (bit % LONG_BIT)));
244 }
245
246 #endif /* UTERM_INPUT_H */