keyrouter: Fix wrong return value
[platform/core/uifw/libds-tizen.git] / src / libds / keyboard.c
1 #include <stdbool.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <sys/mman.h>
5
6 #include <wayland-server.h>
7
8 #include "libds/log.h"
9 #include "libds/interfaces/keyboard.h"
10 #include "util.h"
11
12 static bool keyboard_modifier_update(struct ds_keyboard *keyboard);
13 static void keyboard_key_update(struct ds_keyboard *keyboard,
14         struct ds_event_keyboard_key *event);
15 static void keyboard_led_update(struct ds_keyboard *keyboard);
16
17 WL_EXPORT bool
18 ds_keyboard_set_keymap(struct ds_keyboard *keyboard, struct xkb_keymap *keymap)
19 {
20     char *tmp_keymap_string;
21     void *dst;
22     int rw_fd, ro_fd;
23     xkb_keycode_t keycode;
24     const char *led_names[DS_LED_COUNT] = {
25         XKB_LED_NAME_NUM,
26         XKB_LED_NAME_CAPS,
27         XKB_LED_NAME_SCROLL,
28     };
29     const char *mod_names[DS_MODIFIER_COUNT] = {
30         XKB_MOD_NAME_SHIFT,
31         XKB_MOD_NAME_CAPS,
32         XKB_MOD_NAME_CTRL,
33         XKB_MOD_NAME_ALT,
34         XKB_MOD_NAME_NUM,
35         "Mod3",
36         XKB_MOD_NAME_LOGO,
37         "Mod5",
38     };
39
40     if (keyboard->keymap)
41         xkb_keymap_unref(keyboard->keymap);
42
43     keyboard->keymap = xkb_keymap_ref(keymap);
44
45     if (keyboard->xkb_state)
46         xkb_state_unref(keyboard->xkb_state);
47
48     keyboard->xkb_state = xkb_state_new(keyboard->keymap);
49     if (!keyboard->xkb_state) {
50         ds_err("Failed to create XKB state");
51         goto err_state;
52     }
53
54     for (size_t i = 0; i < DS_LED_COUNT; i++) {
55         keyboard->led_indexes[i] =
56             xkb_map_led_get_index(keyboard->keymap, led_names[i]);
57     }
58
59     for (size_t i = 0; i < DS_MODIFIER_COUNT; i++) {
60         keyboard->mod_indexes[i] =
61             xkb_map_mod_get_index(keyboard->keymap, mod_names[i]);
62     }
63
64     tmp_keymap_string = xkb_keymap_get_as_string(keyboard->keymap,
65             XKB_KEYMAP_FORMAT_TEXT_V1);
66     if (!tmp_keymap_string) {
67         ds_err("Failed to get string version of keymap");
68         goto err_keymap_string;
69     }
70
71     if (keyboard->keymap_string)
72         free(keyboard->keymap_string);
73     keyboard->keymap_string = tmp_keymap_string;
74     keyboard->keymap_size = strlen(keyboard->keymap_string) + 1;
75
76     if (!allocate_shm_file_pair(keyboard->keymap_size, &rw_fd, &ro_fd)) {
77         ds_err("Failed to allocate shm_file for keymap");
78         goto err_shm_file;
79     }
80
81     dst = mmap(NULL, keyboard->keymap_size, PROT_READ | PROT_WRITE,
82             MAP_SHARED, rw_fd, 0);
83     if (dst == MAP_FAILED) {
84         ds_log_errno(DS_ERR, "mmap failed");
85         goto err_mmap;
86     }
87
88     memcpy(dst, keyboard->keymap_string, keyboard->keymap_size);
89     munmap(dst, keyboard->keymap_size);
90     close(rw_fd);
91
92     if (keyboard->keymap_fd >= 0)
93         close(keyboard->keymap_fd);
94     keyboard->keymap_fd = ro_fd;
95
96     for (size_t i = 0; i < keyboard->num_keycodes; i++) {
97         keycode = keyboard->keycodes[i] + 8;
98         xkb_state_update_key(keyboard->xkb_state, keycode, XKB_KEY_DOWN);
99     }
100
101     keyboard_modifier_update(keyboard);
102
103     wl_signal_emit(&keyboard->events.keymap, keyboard);
104
105     return true;
106
107 err_mmap:
108     close(rw_fd);
109     close(ro_fd);
110 err_shm_file:
111     free(keyboard->keymap_string);
112     keyboard->keymap_string = NULL;
113 err_keymap_string:
114     xkb_state_unref(keyboard->xkb_state);
115     keyboard->xkb_state = NULL;
116 err_state:
117     xkb_keymap_unref(keymap);
118     keyboard->keymap = NULL;
119
120     return false;
121 }
122
123 WL_EXPORT void
124 ds_keyboard_set_repeat_info(struct ds_keyboard *keyboard,
125         int32_t rate, int32_t delay)
126 {
127     if (keyboard->repeat_info.rate == rate &&
128             keyboard->repeat_info.delay == delay)
129         return;
130     keyboard->repeat_info.rate = rate;
131     keyboard->repeat_info.delay = delay;
132
133     wl_signal_emit(&keyboard->events.repeat_info, keyboard);
134 }
135
136 WL_EXPORT uint32_t
137 ds_keyboard_get_modifiers(struct ds_keyboard *keyboard)
138 {
139     xkb_mod_mask_t mask;
140     uint32_t modifiers = 0;
141
142     mask = keyboard->modifiers.depressed | keyboard->modifiers.latched;
143     for (size_t i = 0; i < DS_MODIFIER_COUNT; i++) {
144         if (keyboard->mod_indexes[i] != XKB_MOD_INVALID &&
145                 (mask & (1 << keyboard->mod_indexes[i])))
146             modifiers |= (1 << i);
147     }
148
149     return modifiers;
150 }
151
152 WL_EXPORT struct xkb_state *
153 ds_keyboard_get_xkb_state(struct ds_keyboard *keyboard)
154 {
155     return keyboard->xkb_state;
156 }
157
158 WL_EXPORT void
159 ds_keyboard_notify_key(struct ds_keyboard *keyboard,
160         struct ds_event_keyboard_key *event)
161 {
162     uint32_t keycode;
163     enum xkb_key_direction dir;
164     bool updated;
165
166     keyboard_key_update(keyboard, event);
167
168     wl_signal_emit(&keyboard->events.key, event);
169
170     if (!keyboard->xkb_state)
171         return;
172
173     if (event->update_state) {
174         keycode = event->keycode + 8;
175         dir = (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) ?
176             XKB_KEY_DOWN : XKB_KEY_UP;
177         xkb_state_update_key(keyboard->xkb_state, keycode, dir);
178     }
179
180     updated = keyboard_modifier_update(keyboard);
181     if (updated)
182         wl_signal_emit(&keyboard->events.modifiers, keyboard);
183
184     keyboard_led_update(keyboard);
185 }
186
187 WL_EXPORT void
188 ds_keyboard_notify_modifiers(struct ds_keyboard *keyboard,
189         uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked,
190         uint32_t group)
191 {
192     bool updated;
193
194     if (!keyboard->xkb_state)
195         return;
196
197     xkb_state_update_mask(keyboard->xkb_state, mods_depressed, mods_latched,
198             mods_locked, 0, 0, group);
199
200     updated = keyboard_modifier_update(keyboard);
201     if (updated)
202         wl_signal_emit(&keyboard->events.modifiers, keyboard);
203
204     keyboard_led_update(keyboard);
205 }
206
207 WL_EXPORT void
208 ds_keyboard_add_destroy_listener(struct ds_keyboard *keyboard,
209         struct wl_listener *listener)
210 {
211     wl_signal_add(&keyboard->events.destroy, listener);
212 }
213
214 WL_EXPORT void
215 ds_keyboard_add_key_listener(struct ds_keyboard *keyboard,
216         struct wl_listener *listener)
217 {
218     wl_signal_add(&keyboard->events.key, listener);
219 }
220
221 WL_EXPORT void
222 ds_keyboard_add_modifiers_listener(struct ds_keyboard *keyboard,
223         struct wl_listener *listener)
224 {
225     wl_signal_add(&keyboard->events.modifiers, listener);
226 }
227
228 WL_EXPORT void
229 ds_keyboard_add_keymap_listener(struct ds_keyboard *keyboard,
230         struct wl_listener *listener)
231 {
232     wl_signal_add(&keyboard->events.keymap, listener);
233 }
234
235 WL_EXPORT void
236 ds_keyboard_add_repeat_info_listener(struct ds_keyboard *keyboard,
237         struct wl_listener *listener)
238 {
239     wl_signal_add(&keyboard->events.repeat_info, listener);
240 }
241
242 void
243 ds_keyboard_init(struct ds_keyboard *keyboard,
244         const struct ds_keyboard_interface *iface)
245 {
246     keyboard->iface = iface;
247     keyboard->keymap_fd = -1;
248
249     wl_signal_init(&keyboard->events.destroy);
250     wl_signal_init(&keyboard->events.key);
251     wl_signal_init(&keyboard->events.modifiers);
252     wl_signal_init(&keyboard->events.keymap);
253     wl_signal_init(&keyboard->events.repeat_info);
254 }
255
256 void
257 ds_keyboard_destroy(struct ds_keyboard *keyboard)
258 {
259     if (keyboard->iface && keyboard->iface->destroy)
260         keyboard->iface->destroy(keyboard);
261     else
262         free(keyboard);
263 }
264
265 static bool
266 keyboard_modifier_update(struct ds_keyboard *keyboard)
267 {
268     xkb_mod_mask_t depressed, latched, locked, group;
269
270     if (!keyboard->xkb_state)
271         return false;
272
273     depressed = xkb_state_serialize_mods(keyboard->xkb_state,
274             XKB_STATE_MODS_DEPRESSED);
275     latched = xkb_state_serialize_mods(keyboard->xkb_state,
276             XKB_STATE_MODS_LATCHED);
277     locked = xkb_state_serialize_mods(keyboard->xkb_state,
278             XKB_STATE_MODS_LOCKED);
279     group = xkb_state_serialize_layout(keyboard->xkb_state,
280             XKB_STATE_LAYOUT_EFFECTIVE);
281     if (depressed == keyboard->modifiers.depressed &&
282             latched == keyboard->modifiers.latched &&
283             locked == keyboard->modifiers.locked &&
284             group == keyboard->modifiers.group)
285         return false;
286
287     keyboard->modifiers.depressed = depressed;
288     keyboard->modifiers.latched = latched;
289     keyboard->modifiers.locked = locked;
290     keyboard->modifiers.group = group;
291
292     return true;
293 }
294
295 static void keyboard_key_update(struct ds_keyboard *keyboard,
296         struct ds_event_keyboard_key *event)
297 {
298     // TODO
299 }
300
301 static void keyboard_led_update(struct ds_keyboard *keyboard)
302 {
303     // TODO
304 }