ime: refactoring. delete new_input_method_context event/listener
[platform/core/uifw/libds-tizen.git] / src / text_input / text_input.c
1 #include <stdlib.h>
2 #include <wayland-server.h>
3 #include <text-server-protocol.h>
4 #include <libds/log.h>
5
6 #include "util.h"
7 #include <libds-tizen/text_input.h>
8
9 #define TEXT_INPUT_VERSION 1
10
11 struct ds_tizen_text_input {
12     struct wl_resource *resource;
13
14     struct wl_list link;
15
16     struct {
17         struct wl_signal destroy;
18         struct wl_signal activate;
19         struct wl_signal deactivate;
20         struct wl_signal reset;
21         struct wl_signal set_content_type;
22         struct wl_signal invoke_action;
23         struct wl_signal commit_state;
24         struct wl_signal set_preferred_language;
25     } events;
26 };
27
28 struct ds_tizen_text_input_manager {
29     struct wl_global *global;
30     struct wl_list text_inputs;
31
32     struct wl_listener destroy;
33
34     struct {
35         struct wl_signal new_text_input;
36         struct wl_signal destroy;
37     } events;
38 };
39
40 static const struct wl_text_input_interface text_input_impl;
41 static const struct wl_text_input_manager_interface text_input_mgr_impl;
42
43 WL_EXPORT void
44 ds_tizen_text_input_manager_add_destroy_listener(
45     struct ds_tizen_text_input_manager *ti_mgr, struct wl_listener *listener)
46 {
47     wl_signal_add(&ti_mgr->events.destroy, listener);
48 }
49
50 WL_EXPORT void
51 ds_tizen_text_input_manager_add_new_text_input_listener(
52     struct ds_tizen_text_input_manager *ti_mgr, struct wl_listener *listener)
53 {
54     wl_signal_add(&ti_mgr->events.new_text_input, listener);
55 }
56
57 WL_EXPORT void
58 ds_tizen_text_input_add_destroy_listener(
59     struct ds_tizen_text_input *ti, struct wl_listener *listener)
60 {
61     wl_signal_add(&ti->events.destroy, listener);
62 }
63
64 WL_EXPORT void
65 ds_tizen_text_input_add_activate_listener(
66     struct ds_tizen_text_input *ti, struct wl_listener *listener)
67 {
68     wl_signal_add(&ti->events.activate, listener);
69 }
70
71 WL_EXPORT void
72 ds_tizen_text_input_add_deactivate_listener(
73     struct ds_tizen_text_input *ti, struct wl_listener *listener)
74 {
75     wl_signal_add(&ti->events.deactivate, listener);
76 }
77
78 WL_EXPORT void
79 ds_tizen_text_input_add_reset_listener(
80     struct ds_tizen_text_input *ti, struct wl_listener *listener)
81 {
82     wl_signal_add(&ti->events.reset, listener);
83 }
84
85 WL_EXPORT void
86 ds_tizen_text_input_add_set_content_type_listener(
87     struct ds_tizen_text_input *ti, struct wl_listener *listener)
88 {
89     wl_signal_add(&ti->events.set_content_type, listener);
90 }
91
92 WL_EXPORT void
93 ds_tizen_text_input_add_set_preferred_language_listener(
94     struct ds_tizen_text_input *ti, struct wl_listener *listener)
95 {
96     wl_signal_add(&ti->events.set_preferred_language, listener);
97 }
98
99 WL_EXPORT void
100 ds_tizen_text_input_add_commit_state_listener(
101     struct ds_tizen_text_input *ti, struct wl_listener *listener)
102 {
103     wl_signal_add(&ti->events.commit_state, listener);
104 }
105
106 WL_EXPORT void
107 ds_tizen_text_input_add_invoke_action_listener(
108     struct ds_tizen_text_input *ti, struct wl_listener *listener)
109 {
110     wl_signal_add(&ti->events.invoke_action, listener);
111 }
112
113 WL_EXPORT void
114 ds_tizen_text_input_send_enter(struct ds_tizen_text_input *ti,
115     struct ds_surface *surface)
116 {
117     struct wl_resource *resource;
118
119     ds_inf("ds_tizen_text_input_send_enter");
120     resource = ds_surface_get_wl_resource(surface);
121     wl_text_input_send_enter(ti->resource, resource);
122 }
123
124 WL_EXPORT void
125 ds_tizen_text_input_send_leave(struct ds_tizen_text_input *ti)
126 {
127     ds_inf("ds_tizen_text_input_send_leave");
128     wl_text_input_send_leave(ti->resource);
129 }
130
131 WL_EXPORT void
132 ds_tizen_text_input_send_modifiers_map(struct ds_tizen_text_input *ti,
133     struct wl_array *map)
134 {
135     ds_inf("ds_tizen_text_input_send_modifiers_map");
136     wl_text_input_send_modifiers_map(ti->resource, map);
137 }
138
139 WL_EXPORT void
140 ds_tizen_text_input_send_input_panel_state(struct ds_tizen_text_input *ti,
141     uint32_t state)
142 {
143     ds_inf("ds_tizen_text_input_send_input_panel_state");
144     wl_text_input_send_input_panel_state(ti->resource, state);
145 }
146
147 WL_EXPORT void
148 ds_tizen_text_input_send_preedit_string(struct ds_tizen_text_input *ti,
149     uint32_t serial, const char *text, const char *commit)
150 {
151     ds_inf("ds_tizen_text_input_send_preedit_string");
152     wl_text_input_send_preedit_string(ti->resource, serial, text, commit);
153 }
154
155 WL_EXPORT void
156 ds_tizen_text_input_send_preedit_styling(struct ds_tizen_text_input *ti,
157     uint32_t index, uint32_t length, uint32_t style)
158 {
159     ds_inf("ds_tizen_text_input_send_preedit_styling");
160     wl_text_input_send_preedit_styling(ti->resource, index, length, style);
161 }
162
163 WL_EXPORT void
164 ds_tizen_text_input_send_preedit_cursor(struct ds_tizen_text_input *ti,
165     uint32_t index)
166 {
167     ds_inf("ds_tizen_text_input_send_preedit_cursor");
168     wl_text_input_send_preedit_cursor(ti->resource, index);
169 }
170
171 WL_EXPORT void
172 ds_tizen_text_input_send_commit_string(struct ds_tizen_text_input *ti,
173     uint32_t serial, const char *text)
174 {
175     ds_inf("ds_tizen_text_input_send_commit_string");
176     wl_text_input_send_commit_string(ti->resource, serial, text);
177 }
178
179 WL_EXPORT void
180 ds_tizen_text_input_send_cursor_position(struct ds_tizen_text_input *ti,
181     int32_t index, int32_t anchor)
182 {
183     ds_inf("ds_tizen_text_input_send_cursor_position");
184     wl_text_input_send_cursor_position(ti->resource, index, anchor);
185 }
186
187 WL_EXPORT void
188 ds_tizen_text_input_send_delete_surrounding_text(struct ds_tizen_text_input *ti,
189     int32_t index, uint32_t length)
190 {
191     ds_inf("ds_tizen_text_input_send_delete_surrounding_text");
192     wl_text_input_send_delete_surrounding_text(ti->resource, index, length);
193 }
194
195 WL_EXPORT void
196 ds_tizen_text_input_send_keysym(struct ds_tizen_text_input *ti,
197     uint32_t serial, uint32_t time, uint32_t sym, uint32_t state,
198     uint32_t modifiers)
199 {
200     ds_inf("ds_tizen_text_input_send_keysym");
201     wl_text_input_send_keysym(ti->resource, serial, time, sym, state, modifiers);
202 }
203
204 WL_EXPORT void
205 ds_tizen_text_input_send_language(struct ds_tizen_text_input *ti,
206     uint32_t serial, const char *language)
207 {
208     ds_inf("ds_tizen_text_input_send_language");
209     wl_text_input_send_language(ti->resource, serial, language);
210 }
211
212 WL_EXPORT void
213 ds_tizen_text_input_send_text_direction(struct ds_tizen_text_input *ti,
214     uint32_t serial, uint32_t direction)
215 {
216     ds_inf("ds_tizen_text_input_send_text_direction");
217     wl_text_input_send_text_direction(ti->resource, serial, direction);
218 }
219
220 static void
221 text_input_handle_destroy(struct wl_client *client, struct wl_resource *resource)
222 {
223     ds_inf("text_input_handle_destroy");
224     wl_resource_destroy(resource);
225 }
226
227 static void
228 text_input_handle_activate(struct wl_client *client,
229     struct wl_resource *resource, struct wl_resource *seat, struct wl_resource *surface)
230 {
231     struct ds_tizen_text_input *text_input = wl_resource_get_user_data(resource);
232     struct ds_tizen_text_input_event_activate ds_event;
233     struct ds_surface *ds_surf;
234     struct ds_seat_client *seat_client;
235
236     ds_inf("text_input_handle_activate");
237     ds_surf = ds_surface_from_resource(surface);
238
239     ds_event.text_input = text_input;
240     seat_client = ds_seat_client_from_resource(seat);
241     if (seat_client)
242         ds_event.seat = ds_seat_client_get_seat(seat_client);
243     ds_event.surface = ds_surf;
244     wl_signal_emit(&text_input->events.activate, &ds_event);
245
246     ds_tizen_text_input_send_enter(text_input, ds_surf);
247 }
248
249 static void
250 text_input_handle_deactivate(struct wl_client *client,
251     struct wl_resource *resource, struct wl_resource *seat)
252 {
253     struct ds_tizen_text_input *text_input = wl_resource_get_user_data(resource);
254     struct ds_tizen_text_input_event_deactivate ds_event;
255     struct ds_seat_client *seat_client;
256
257     ds_inf("text_input_handle_deactivate");
258     ds_event.text_input = text_input;
259     seat_client = ds_seat_client_from_resource(seat);
260     if (seat_client)
261         ds_event.seat = ds_seat_client_get_seat(seat_client);
262     wl_signal_emit(&text_input->events.deactivate, &ds_event);
263
264     ds_tizen_text_input_send_leave(text_input);
265 }
266
267 static void
268 text_input_handle_show_input_panel(struct wl_client *client,
269     struct wl_resource *resource)
270 {
271     ds_inf("text_input_handle_show_input_panel");
272 }
273
274 static void
275 text_input_handle_hide_input_panel(struct wl_client *client,
276     struct wl_resource *resource)
277 {
278     ds_inf("text_input_handle_hide_input_panel");
279 }
280
281 static void
282 text_input_handle_reset(struct wl_client *client, struct wl_resource *resource)
283 {
284     struct ds_tizen_text_input *text_input = wl_resource_get_user_data(resource);
285
286     ds_inf("text_input_handle_reset");
287     wl_signal_emit(&text_input->events.reset, text_input);
288 }
289
290 static void
291 text_input_handle_set_content_type(struct wl_client *client,
292     struct wl_resource *resource, uint32_t hint, uint32_t purpose)
293 {
294     struct ds_tizen_text_input *text_input = wl_resource_get_user_data(resource);
295     struct ds_tizen_text_input_event_set_content_type ds_event;
296
297     ds_inf("text_input_handle_set_content_type");
298     ds_event.hint = hint;
299     ds_event.purpose = purpose;
300     ds_event.text_input = text_input;
301
302     wl_signal_emit(&text_input->events.set_content_type, &ds_event);
303 }
304
305 static void
306 text_input_handle_set_cursor_rectangle(struct wl_client *client,
307     struct wl_resource *resource, int32_t x, int32_t y,
308     int32_t width, int32_t height)
309 {
310     ds_inf("text_input_handle_set_cursor_rectangle");
311 }
312
313 static void
314 text_input_handle_set_preferred_language(struct wl_client *client,
315     struct wl_resource *resource, const char *language)
316 {
317     struct ds_tizen_text_input *text_input = wl_resource_get_user_data(resource);
318     struct ds_tizen_text_input_event_set_preferred_language ds_event;
319
320     ds_inf("text_input_handle_set_preferred_language");
321     ds_event.language = language;
322     ds_event.text_input = text_input;
323
324     wl_signal_emit(&text_input->events.set_preferred_language, &ds_event);
325 }
326
327 static void
328 text_input_handle_commit_state(struct wl_client *client,
329     struct wl_resource *resource, uint32_t serial)
330 {
331     struct ds_tizen_text_input *text_input = wl_resource_get_user_data(resource);
332     struct ds_tizen_text_input_event_commit_state ds_event;
333
334     ds_inf("text_input_handle_invoke_action");
335     ds_event.serial = serial;
336     ds_event.text_input = text_input;
337
338     wl_signal_emit(&text_input->events.commit_state, &ds_event);
339 }
340
341 static void
342 text_input_handle_invoke_action(struct wl_client *client,
343     struct wl_resource *resource, uint32_t button, uint32_t index)
344 {
345     struct ds_tizen_text_input *text_input = wl_resource_get_user_data(resource);
346     struct ds_tizen_text_input_event_invoke_action ds_event;
347
348     ds_inf("text_input_handle_invoke_action");
349
350     ds_event.button = button;
351     ds_event.index = index;
352     ds_event.text_input = text_input;
353
354     wl_signal_emit(&text_input->events.invoke_action, &ds_event);
355 }
356
357 static const struct wl_text_input_interface text_input_impl = {
358     .destroy = text_input_handle_destroy,
359     .activate = text_input_handle_activate,
360     .deactivate = text_input_handle_deactivate,
361     .show_input_panel = text_input_handle_show_input_panel,
362     .hide_input_panel = text_input_handle_hide_input_panel,
363     .reset = text_input_handle_reset,
364     .set_content_type = text_input_handle_set_content_type,
365     .set_cursor_rectangle = text_input_handle_set_cursor_rectangle,
366     .set_preferred_language = text_input_handle_set_preferred_language,
367     .commit_state = text_input_handle_commit_state,
368     .invoke_action = text_input_handle_invoke_action,
369     //for tizen only
370     .set_return_key_type = NULL,
371     .set_return_key_disabled = NULL,
372     .set_input_panel_data = NULL,
373     .bidi_direction = NULL,
374     .set_cursor_position = NULL,
375     .process_input_device_event = NULL,
376     .filter_key_event = NULL,
377     .get_hide_permission = NULL,
378     .set_capital_mode = NULL,
379     .prediction_hint = NULL,
380     .set_mime_type = NULL,
381     .set_input_panel_position = NULL,
382     .finalize_content = NULL,
383     .prediction_hint_data = NULL,
384     .input_panel_enabled = NULL,
385 };
386
387 static void
388 text_input_destroy(struct ds_tizen_text_input *text_input)
389 {
390     wl_signal_emit(&text_input->events.destroy, text_input);
391     wl_list_remove(&text_input->link);
392
393     free(text_input);
394 }
395
396 static void
397 text_input_mgr_handle_display_destroy(struct wl_listener *listener, void *data)
398 {
399     struct ds_tizen_text_input_manager *text_input_mgr;
400     struct ds_tizen_text_input *text_input, *tmp;
401
402     text_input_mgr = wl_container_of(listener, text_input_mgr, destroy);
403
404     ds_inf("Global destroy: text_input_mgr(%p)", text_input_mgr);
405
406     wl_signal_emit(&text_input_mgr->events.destroy, text_input_mgr);
407     wl_list_remove(&text_input_mgr->destroy.link);
408
409     wl_list_for_each_safe(text_input, tmp, &text_input_mgr->text_inputs, link) {
410         text_input_destroy(text_input);
411     }
412
413     wl_global_destroy(text_input_mgr->global);
414     free(text_input_mgr);
415 }
416
417 static void
418 text_input_client_handle_destroy(struct wl_resource *resource)
419 {
420     struct ds_tizen_text_input *text_input;
421
422     ds_inf("text_input_client_handle_destroy");
423
424     text_input = wl_resource_get_user_data(resource);
425     text_input_destroy(text_input);
426 }
427
428 static void
429 text_input_manager_handle_create_text_input(struct wl_client *wl_client,
430     struct wl_resource *resource, uint32_t id)
431 {
432     struct ds_tizen_text_input *text_input;
433     struct ds_tizen_text_input_manager *text_input_mgr;
434
435     ds_inf("text_input_manager_handle_create_text_input");
436
437     text_input_mgr = wl_resource_get_user_data(resource);
438
439     text_input = calloc(1, sizeof *text_input);
440     if (text_input == NULL) {
441         ds_err("calloc() failed. ds_tizen_text_input");
442         return;
443     }
444
445     text_input->resource = wl_resource_create(wl_client,
446             &wl_text_input_interface,
447             TEXT_INPUT_VERSION, id);
448     if (text_input->resource == NULL) {
449         ds_err("text_input. wl_resource_create() failed.");
450         wl_client_post_no_memory(wl_client);
451         return;
452     }
453     wl_resource_set_implementation(text_input->resource, &text_input_impl,
454         text_input, text_input_client_handle_destroy);
455
456     wl_signal_init(&text_input->events.activate);
457     wl_signal_init(&text_input->events.deactivate);
458     wl_signal_init(&text_input->events.reset);
459     wl_signal_init(&text_input->events.set_content_type);
460     wl_signal_init(&text_input->events.invoke_action);
461     wl_signal_init(&text_input->events.commit_state);
462     wl_signal_init(&text_input->events.set_preferred_language);
463     wl_signal_init(&text_input->events.destroy);
464
465     wl_list_insert(&text_input_mgr->text_inputs, &text_input->link);
466     wl_signal_emit(&text_input_mgr->events.new_text_input, text_input);
467 }
468
469 static const struct wl_text_input_manager_interface text_input_mgr_impl =
470 {
471     .create_text_input = text_input_manager_handle_create_text_input,
472 };
473
474 static void
475 text_input_mgr_bind(struct wl_client *wl_client, void *data,
476     uint32_t version, uint32_t id)
477 {
478     struct ds_tizen_text_input_manager *text_input_mgr = data;
479     struct wl_resource *resource;
480
481     ds_inf("text_input_mgr. client binds. (client:%p)", wl_client);
482
483     resource = wl_resource_create(wl_client,
484             &wl_text_input_manager_interface,
485             version, id);
486     if (resource == NULL) {
487         ds_err("text_input_mgr. wl_resource_create() failed.");
488         wl_client_post_no_memory(wl_client);
489         return;
490     }
491     wl_resource_set_implementation(resource, &text_input_mgr_impl,
492         text_input_mgr, NULL);
493 }
494
495 WL_EXPORT struct ds_tizen_text_input_manager *
496 ds_tizen_text_input_manager_create(struct wl_display *display)
497 {
498     struct ds_tizen_text_input_manager *text_input_mgr;
499
500     text_input_mgr = calloc(1, sizeof *text_input_mgr);
501     if (text_input_mgr == NULL) {
502         ds_err("calloc() failed. ds_tizen_text_input_manager");
503         return NULL;
504     }
505
506     text_input_mgr->global = wl_global_create(display,
507             &wl_text_input_manager_interface, TEXT_INPUT_VERSION, text_input_mgr,
508             text_input_mgr_bind);
509     if (!text_input_mgr->global) {
510         free(text_input_mgr);
511         return NULL;
512     }
513
514     wl_list_init(&text_input_mgr->text_inputs);
515
516     wl_signal_init(&text_input_mgr->events.new_text_input);
517     wl_signal_init(&text_input_mgr->events.destroy);
518
519
520     text_input_mgr->destroy.notify = text_input_mgr_handle_display_destroy;
521     wl_display_add_destroy_listener(display, &text_input_mgr->destroy);
522
523     ds_inf("Global create: wl_text_input_manager. text_input_mgr(%p)", text_input_mgr);
524
525     return text_input_mgr;
526 }