keyrouter: Fix wrong validity check
[platform/core/uifw/libds-tizen.git] / src / libds / seat / seat_keyboard.c
1 #include <assert.h>
2 #include <stdint.h>
3 #include <stdlib.h>
4 #include <time.h>
5
6 #include "libds/log.h"
7 #include "seat_private.h"
8
9 static const struct ds_keyboard_grab_interface default_keyboard_grab_iface;
10 static const struct wl_keyboard_interface keyboard_impl;
11
12 static void
13 seat_client_send_keyboard_leave_raw(struct ds_seat_client *seat_client,
14         struct ds_surface *surface);
15 static void
16 seat_keyboard_handle_surface_destroy(struct wl_listener *listener,
17         void *data);
18 static void keyboard_handle_resource_destroy(struct wl_resource *resource);
19
20 WL_EXPORT void
21 ds_seat_keyboard_notify_enter(struct ds_seat *seat,
22         struct ds_surface *surface, uint32_t keycodes[], size_t num_keycodes,
23         struct ds_keyboard_modifiers *modifiers)
24 {
25     struct ds_seat_keyboard_grab *grab = seat->keyboard.grab;
26
27     grab->iface->enter(grab, surface, keycodes, num_keycodes, modifiers);
28 }
29
30 WL_EXPORT void
31 ds_seat_keyboard_notify_clear_focus(struct ds_seat *seat)
32 {
33     struct ds_seat_keyboard_grab *grab = seat->keyboard.grab;
34
35     grab->iface->clear_focus(grab);
36 }
37
38 WL_EXPORT void
39 ds_seat_keyboard_notify_modifiers(struct ds_seat *seat,
40         struct ds_keyboard_modifiers *modifiers)
41 {
42     struct ds_seat_keyboard_grab *grab = seat->keyboard.grab;
43
44     clock_gettime(CLOCK_MONOTONIC, &seat->last_event);
45     grab->iface->modifiers(grab, modifiers);
46 }
47
48 WL_EXPORT void
49 ds_seat_keyboard_notify_key(struct ds_seat *seat, uint32_t time_msec,
50         uint32_t key, uint32_t state)
51 {
52     struct ds_seat_keyboard_grab *grab = seat->keyboard.grab;
53
54     clock_gettime(CLOCK_MONOTONIC, &seat->last_event);
55     grab->iface->key(grab, time_msec, key, state);
56 }
57
58 WL_EXPORT void
59 ds_seat_keyboard_add_grab_begin_listener(struct ds_seat *seat,
60         struct wl_listener *listener)
61 {
62     wl_signal_add(&seat->events.keyboard_grab_begin, listener);
63 }
64
65 WL_EXPORT void
66 ds_seat_keyboard_add_grab_end_listener(struct ds_seat *seat,
67         struct wl_listener *listener)
68 {
69     wl_signal_add(&seat->events.keyboard_grab_end, listener);
70 }
71
72 WL_EXPORT void
73 ds_seat_keyboard_add_focus_change_listener(struct ds_seat *seat,
74         struct wl_listener *listener)
75 {
76     wl_signal_add(&seat->keyboard.events.focus_change, listener);
77 }
78
79 void
80 ds_seat_keyboard_start_grab(struct ds_seat *seat,
81         struct ds_seat_keyboard_grab *grab)
82 {
83     grab->seat = seat;
84     seat->keyboard.grab = grab;
85
86     wl_signal_emit(&seat->events.keyboard_grab_begin, grab);
87 }
88
89 void
90 ds_seat_keyboard_end_grab(struct ds_seat *seat)
91 {
92     struct ds_seat_keyboard *keyboard = &seat->keyboard;
93     struct ds_seat_keyboard_grab *grab = keyboard->grab;
94
95     if (grab != keyboard->default_grab) {
96         keyboard->grab = keyboard->default_grab;
97         wl_signal_emit(&seat->events.keyboard_grab_end, grab);
98         if (grab->iface->cancel)
99             grab->iface->cancel(grab);
100     }
101 }
102
103 void
104 ds_seat_keyboard_enter(struct ds_seat *seat, struct ds_surface *surface,
105         uint32_t keycodes[], size_t num_keycodes,
106         struct ds_keyboard_modifiers *modifiers)
107 {
108     struct ds_seat_keyboard *keyboard = &seat->keyboard;
109     struct ds_seat_client *seat_client = NULL, *focused_client;
110     struct ds_surface *focused_surface;
111     struct wl_client *wl_client;
112     struct wl_array keys;
113     struct wl_resource *resource;
114     uint32_t *p;
115     uint32_t serial;
116
117     if (keyboard->focused_surface == surface)
118         return;
119
120     if (surface) {
121         wl_client =
122             wl_resource_get_client(ds_surface_get_wl_resource(surface));
123         seat_client = seat_client_for_wl_client(seat, wl_client);
124     }
125
126     focused_client = keyboard->focused_client;
127     focused_surface = keyboard->focused_surface;
128
129     if (focused_client != NULL && focused_surface != NULL)
130         seat_client_send_keyboard_leave_raw(focused_client, focused_surface);
131
132     if (seat_client) {
133         wl_array_init(&keys);
134
135         for (size_t i = 0; i < num_keycodes; i++) {
136             p = wl_array_add(&keys, sizeof(uint32_t));
137             if (!p) {
138                 ds_err("Cannot allocate memory, skipping keycode: %" PRIu32
139                         "\n", keycodes[i]);
140                 continue;
141             }
142             *p = keycodes[i];
143         }
144
145         serial = wl_display_next_serial(seat->display);
146
147         wl_resource_for_each(resource, &seat_client->keyboards) {
148             wl_keyboard_send_enter(resource, serial,
149                     ds_surface_get_wl_resource(surface), &keys);
150         }
151         wl_array_release(&keys);
152     }
153
154     wl_list_remove(&keyboard->surface_destroy.link);
155     wl_list_init(&keyboard->surface_destroy.link);
156
157     if (surface) {
158         keyboard->surface_destroy.notify =
159             seat_keyboard_handle_surface_destroy;
160         ds_surface_add_destroy_listener(surface, &keyboard->surface_destroy);
161     }
162
163     keyboard->focused_client = seat_client;
164     keyboard->focused_surface = surface;
165
166     if (seat_client) {
167         ds_seat_keyboard_send_modifiers(seat, modifiers);
168
169         // TODO handle selection
170     }
171
172     struct ds_event_seat_keyboard_focus_change event = {
173         .seat = seat,
174         .old_surface = focused_surface,
175         .new_surface = surface,
176     };
177     wl_signal_emit(&keyboard->events.focus_change, &event);
178 }
179
180 void
181 ds_seat_keyboard_clear_focus(struct ds_seat *seat)
182 {
183     ds_seat_keyboard_enter(seat, NULL, NULL, 0, NULL);
184 }
185
186 void
187 ds_seat_keyboard_send_key(struct ds_seat *seat, uint32_t time_msec,
188         uint32_t key, uint32_t state)
189 {
190     struct ds_seat_client *seat_client;
191     struct wl_resource *resource;
192     uint32_t serial;
193
194     seat_client = seat->keyboard.focused_client;
195     if (!seat_client)
196         return;
197
198     serial = wl_display_next_serial(seat->display);
199     wl_resource_for_each(resource, &seat_client->keyboards)
200         wl_keyboard_send_key(resource, serial, time_msec, key, state);
201 }
202
203 void
204 ds_seat_keyboard_send_modifiers(struct ds_seat *seat,
205         struct ds_keyboard_modifiers *modifiers)
206 {
207     struct ds_seat_keyboard *keyboard = &seat->keyboard;
208     struct ds_seat_client *seat_client = keyboard->focused_client;
209     struct wl_resource *resource;
210     uint32_t serial;
211
212     if (!seat_client)
213         return;
214
215     serial = wl_display_next_serial(seat->display);
216     wl_resource_for_each(resource, &seat_client->keyboards) {
217         if (!modifiers) {
218             wl_keyboard_send_modifiers(resource, serial, 0, 0, 0, 0);
219         }
220         else {
221             wl_keyboard_send_modifiers(resource, serial,
222                     modifiers->depressed, modifiers->latched,
223                     modifiers->locked, modifiers->group);
224         }
225     }
226 }
227
228 bool
229 seat_keyboard_init(struct ds_seat *seat)
230 {
231     struct ds_seat_keyboard *keyboard = &seat->keyboard;
232     struct ds_seat_keyboard_grab *grab;
233
234     grab = calloc(1, sizeof *grab);
235     if (!grab)
236         return false;
237
238     grab->iface = &default_keyboard_grab_iface;
239     grab->seat = seat;
240
241     keyboard->default_grab = grab;
242     keyboard->grab = grab;
243     keyboard->seat = seat;
244
245     wl_list_init(&keyboard->surface_destroy.link);
246
247     wl_signal_init(&keyboard->events.focus_change);
248
249     return true;
250 }
251
252 void seat_keyboard_finish(struct ds_seat *seat)
253 {
254     struct ds_seat_keyboard *keyboard = &seat->keyboard;
255
256     wl_list_remove(&keyboard->surface_destroy.link);
257     free(keyboard->default_grab);
258 }
259
260 void
261 seat_client_add_keyboard_resource(struct ds_seat_client *seat_client,
262         uint32_t version, uint32_t id)
263 {
264     struct wl_resource *resource;
265
266     resource = wl_resource_create(seat_client->wl_client,
267             &wl_keyboard_interface, version, id);
268     if (!resource) {
269         wl_client_post_no_memory(seat_client->wl_client);
270         return;
271     }
272
273     wl_resource_set_implementation(resource, &keyboard_impl, seat_client,
274             keyboard_handle_resource_destroy);
275
276     wl_list_insert(&seat_client->keyboards, wl_resource_get_link(resource));
277
278     if (!(seat_client->seat->capabilities & WL_SEAT_CAPABILITY_KEYBOARD)) {
279         wl_resource_set_user_data(resource, NULL);
280         return;
281     }
282 }
283
284 void
285 seat_client_remove_all_keyboard_resources(struct ds_seat_client *seat_client)
286 {
287     struct wl_resource *resource, *tmp;
288
289     wl_resource_for_each_safe(resource, tmp, &seat_client->keyboards) {
290         wl_list_remove(wl_resource_get_link(resource));
291         wl_resource_set_user_data(resource, NULL);
292     }
293 }
294
295 static void
296 keyboard_handle_release(struct wl_client *client, struct wl_resource *resource)
297 {
298     wl_resource_destroy(resource);
299 }
300
301 static const struct wl_keyboard_interface keyboard_impl =
302 {
303     .release = keyboard_handle_release,
304 };
305
306 static void
307 keyboard_handle_resource_destroy(struct wl_resource *resource)
308 {
309     if (!wl_resource_get_user_data(resource))
310         return;
311
312     wl_list_remove(wl_resource_get_link(resource));
313 }
314
315 static void
316 default_keyboard_grab_iface_enter(struct ds_seat_keyboard_grab *grab,
317             struct ds_surface *surface, uint32_t keycodes[],
318             size_t num_keycodes, struct ds_keyboard_modifiers *modifiers)
319 {
320     ds_seat_keyboard_enter(grab->seat, surface, keycodes, num_keycodes,
321             modifiers);
322 }
323
324 static void
325 default_keyboard_grab_iface_clear_focus(struct ds_seat_keyboard_grab *grab)
326 {
327     ds_seat_keyboard_clear_focus(grab->seat);
328 }
329
330 static void
331 default_keyboard_grab_iface_key(struct ds_seat_keyboard_grab *grab,
332         uint32_t time_msec, uint32_t key, uint32_t state)
333 {
334     ds_seat_keyboard_send_key(grab->seat, time_msec, key, state);
335 }
336
337 static void
338 default_modifiers_grab_iface_key(struct ds_seat_keyboard_grab *grab,
339         struct ds_keyboard_modifiers *modifiers)
340 {
341     ds_seat_keyboard_send_modifiers(grab->seat, modifiers);
342 }
343
344 static void
345 default_cancel_grab_iface_key(struct ds_seat_keyboard_grab *grab)
346 {
347     // cannot be cancelled
348 }
349
350 static const struct ds_keyboard_grab_interface default_keyboard_grab_iface = {
351     .enter = default_keyboard_grab_iface_enter,
352     .clear_focus = default_keyboard_grab_iface_clear_focus,
353     .key = default_keyboard_grab_iface_key,
354     .modifiers = default_modifiers_grab_iface_key,
355     .cancel = default_cancel_grab_iface_key,
356 };
357
358 static void
359 seat_client_send_keyboard_leave_raw(struct ds_seat_client *seat_client,
360         struct ds_surface *surface)
361 {
362     struct wl_resource *resource;
363     uint32_t serial;
364
365     serial = wl_display_next_serial(wl_client_get_display(seat_client->wl_client));
366     wl_resource_for_each(resource, &seat_client->keyboards) {
367         wl_keyboard_send_leave(resource, serial,
368                 ds_surface_get_wl_resource(surface));
369     }
370 }
371
372 static void
373 seat_keyboard_handle_surface_destroy(struct wl_listener *listener,
374         void *data)
375 {
376     struct ds_seat_keyboard *keyboard;
377
378     keyboard = wl_container_of(listener, keyboard, surface_destroy);
379
380     wl_list_remove(&keyboard->surface_destroy.link);
381     wl_list_init(&keyboard->surface_destroy.link);
382     ds_seat_keyboard_clear_focus(keyboard->seat);
383 }