blur: Support wtz_blur_rectangle protocol
[platform/core/uifw/libds-tizen.git] / src / input_method / input_method.c
1 #include <stdlib.h>
2 #include <wayland-server.h>
3 #include <input-method-server-protocol.h>
4 #include <libds/log.h>
5
6 #include "util.h"
7 #include <libds/seat.h>
8 #include <libds-tizen/input_method.h>
9
10 #define INPUT_METHOD_VERSION 1
11
12 struct ds_tizen_input_method;
13
14 struct ds_tizen_input_method_context {
15     struct wl_resource *resource;
16     struct ds_tizen_input_method *input_method;
17
18     struct {
19         struct wl_signal destroy;
20         struct wl_signal commit_string;
21         struct wl_signal preedit_string;
22         struct wl_signal preedit_styling;
23         struct wl_signal preedit_cursor;
24         struct wl_signal delete_surrounding_text;
25         struct wl_signal cursor_position;
26         struct wl_signal modifiers_map;
27         struct wl_signal keysym;
28         struct wl_signal grab_keyboard;
29         struct wl_signal key;
30         struct wl_signal modifiers;
31         struct wl_signal language;
32         struct wl_signal text_direction;
33     } events;
34 };
35
36 struct ds_tizen_input_method {
37     struct wl_global *global;
38     struct wl_resource *resource;
39     struct ds_tizen_input_method_context *context;
40
41     struct wl_listener destroy;
42
43     struct {
44         struct wl_signal destroy;
45     } events;
46 };
47
48 struct ds_tizen_input_method_manager {
49     struct wl_global *global;
50     struct wl_resource *resource;
51
52     struct wl_listener destroy;
53
54     struct {
55         struct wl_signal destroy;
56         struct wl_signal set_transient_for;
57     } events;
58 };
59
60 static const struct zwp_input_method_context_v1_interface context_impl;
61 static const struct zwp_input_method_manager_v1_interface input_method_mgr_impl;
62
63 WL_EXPORT void
64 ds_tizen_input_method_manager_add_destroy_listener(
65     struct ds_tizen_input_method_manager *im_mgr, struct wl_listener *listener)
66 {
67     wl_signal_add(&im_mgr->events.destroy, listener);
68 }
69
70 WL_EXPORT void
71 ds_tizen_input_method_manager_add_set_transient_for_listener(
72     struct ds_tizen_input_method_manager *im_mgr, struct wl_listener *listener)
73 {
74     wl_signal_add(&im_mgr->events.set_transient_for, listener);
75 }
76
77 static void
78 input_method_mgr_handle_display_destroy(struct wl_listener *listener, void *data)
79 {
80     struct ds_tizen_input_method_manager *input_method_mgr;
81
82     input_method_mgr = wl_container_of(listener, input_method_mgr, destroy);
83
84     ds_inf("Global destroy: input_method_mgr(%p)", input_method_mgr);
85
86     wl_signal_emit(&input_method_mgr->events.destroy, input_method_mgr);
87     wl_list_remove(&input_method_mgr->destroy.link);
88
89     wl_global_destroy(input_method_mgr->global);
90     free(input_method_mgr);
91 }
92
93 static void
94 input_method_mgr_handle_set_transient_for(struct wl_client *wl_client,
95     struct wl_resource *resource, uint32_t parent_pid, uint32_t child_pid)
96 {
97     struct ds_tizen_input_method_manager_event_set_transient_for ds_event;
98     struct ds_tizen_input_method_manager *input_method_mgr;
99
100     input_method_mgr = wl_resource_get_user_data(resource);
101
102     ds_inf("input_method_mgr_handle_set_transient_for() parent:%u, child:%u",
103         parent_pid, child_pid);
104
105     ds_event.im_mgr = input_method_mgr;
106     ds_event.pid_parent = parent_pid;
107     ds_event.pid_child = child_pid;
108     wl_signal_emit(&input_method_mgr->events.set_transient_for, &ds_event);
109 }
110
111 static const struct zwp_input_method_manager_v1_interface input_method_mgr_impl =
112 {
113     .set_transient_for = input_method_mgr_handle_set_transient_for,
114 };
115
116 static void
117 input_method_mgr_bind(struct wl_client *wl_client, void *data,
118     uint32_t version, uint32_t id)
119 {
120     struct ds_tizen_input_method_manager *input_method_mgr = data;
121
122     ds_inf("input_method_mgr. client binds. (client:%p)", wl_client);
123
124     input_method_mgr->resource = wl_resource_create(wl_client,
125             &zwp_input_method_manager_v1_interface,
126             version, id);
127     if (input_method_mgr->resource == NULL) {
128         ds_err("input_method_mgr. wl_resource_create() failed.");
129         wl_client_post_no_memory(wl_client);
130         return;
131     }
132     wl_resource_set_implementation(input_method_mgr->resource, &input_method_mgr_impl,
133         input_method_mgr, NULL);
134 }
135
136 WL_EXPORT struct ds_tizen_input_method_manager *
137 ds_tizen_input_method_manager_create(struct wl_display *display)
138 {
139     struct ds_tizen_input_method_manager *input_method_mgr;
140
141     input_method_mgr = calloc(1, sizeof *input_method_mgr);
142     if (input_method_mgr == NULL) {
143         ds_err("calloc() failed. ds_tizen_input_method_manager");
144         return NULL;
145     }
146
147     input_method_mgr->global = wl_global_create(display,
148         &zwp_input_method_manager_v1_interface, INPUT_METHOD_VERSION, input_method_mgr, input_method_mgr_bind);
149     if (!input_method_mgr->global) {
150         free(input_method_mgr);
151         return NULL;
152     }
153
154     wl_signal_init(&input_method_mgr->events.destroy);
155     wl_signal_init(&input_method_mgr->events.set_transient_for);
156
157     input_method_mgr->destroy.notify = input_method_mgr_handle_display_destroy;
158     wl_display_add_destroy_listener(display, &input_method_mgr->destroy);
159
160     ds_inf("Global create: zwp_input_method_manager_v1. input_method_mgr(%p)", input_method_mgr);
161
162     return input_method_mgr;
163 }
164
165 WL_EXPORT void
166 ds_tizen_input_method_add_destroy_listener(
167     struct ds_tizen_input_method *im, struct wl_listener *listener)
168 {
169     wl_signal_add(&im->events.destroy, listener);
170 }
171
172 WL_EXPORT void
173 ds_tizen_input_method_send_activate(struct ds_tizen_input_method *im,
174     struct ds_tizen_input_method_context *context)
175 {
176     if (!im || !context) return;
177
178     ds_inf("ds_tizen_input_method_send_activate");
179     zwp_input_method_v1_send_activate(im->resource, context->resource);
180 }
181
182 WL_EXPORT void
183 ds_tizen_input_method_send_deactivate(struct ds_tizen_input_method *im,
184     struct ds_tizen_input_method_context *context)
185 {
186     if (!im || !context) return;
187
188     ds_inf("ds_tizen_input_method_send_deactivate");
189     zwp_input_method_v1_send_deactivate(im->resource, context->resource);
190 }
191
192 static void
193 context_destroy(struct ds_tizen_input_method_context *context)
194 {
195     ds_inf("input_method_context(%p) destroy", context);
196
197     wl_signal_emit(&context->events.destroy, context);
198
199     free(context);
200 }
201
202 static void
203 input_method_context_client_handle_destroy(struct wl_resource *resource)
204 {
205     struct ds_tizen_input_method_context *context = wl_resource_get_user_data(resource);
206     struct ds_tizen_input_method *input_method;
207
208     ds_inf("input_method_context_client_handle_destroy");
209
210     input_method = context->input_method;
211     input_method->context = NULL;
212
213     context_destroy(context);
214 }
215
216 WL_EXPORT struct ds_tizen_input_method_context *
217 ds_tizen_input_method_create_context(struct ds_tizen_input_method *input_method)
218 {
219     struct ds_tizen_input_method_context *context;
220     struct wl_resource *binding;
221
222     ds_inf("ds_tizen_input_method_create_context");
223     context = calloc(1, sizeof *context);
224     if (context == NULL) {
225         ds_err("calloc() failed. ds_tizen_input_method_context");
226         return NULL;
227     }
228
229     binding = input_method->resource;
230     if (!binding) {
231         ds_err("context. there is no resource of input_method.");
232         free(context);
233         return NULL;
234     }
235     context->resource = wl_resource_create(wl_resource_get_client(binding),
236             &zwp_input_method_context_v1_interface, INPUT_METHOD_VERSION, 0);
237     if (context->resource == NULL) {
238         ds_err("context. wl_resource_create() failed.");
239         free(context);
240         return NULL;
241     }
242     wl_resource_set_implementation(context->resource, &context_impl,
243         context, input_method_context_client_handle_destroy);
244
245     wl_signal_init(&context->events.destroy);
246     wl_signal_init(&context->events.commit_string);
247     wl_signal_init(&context->events.preedit_string);
248     wl_signal_init(&context->events.preedit_styling);
249     wl_signal_init(&context->events.preedit_cursor);
250     wl_signal_init(&context->events.delete_surrounding_text);
251     wl_signal_init(&context->events.cursor_position);
252     wl_signal_init(&context->events.modifiers_map);
253     wl_signal_init(&context->events.keysym);
254     wl_signal_init(&context->events.grab_keyboard);
255     wl_signal_init(&context->events.key);
256     wl_signal_init(&context->events.modifiers);
257     wl_signal_init(&context->events.language);
258     wl_signal_init(&context->events.text_direction);
259
260     ds_tizen_input_method_send_activate(input_method, context);
261
262     input_method->context = context;
263     context->input_method = input_method;
264
265     return context;
266 }
267
268 WL_EXPORT void
269 ds_tizen_input_method_context_add_destroy_listener(
270     struct ds_tizen_input_method_context *context, struct wl_listener *listener)
271 {
272     wl_signal_add(&context->events.destroy, listener);
273 }
274
275 WL_EXPORT void
276 ds_tizen_input_method_context_add_commit_string_listener(
277     struct ds_tizen_input_method_context *context, struct wl_listener *listener)
278 {
279     wl_signal_add(&context->events.commit_string, listener);
280 }
281
282 WL_EXPORT void
283 ds_tizen_input_method_context_add_preedit_string_listener(
284     struct ds_tizen_input_method_context *context, struct wl_listener *listener)
285 {
286     wl_signal_add(&context->events.preedit_string, listener);
287 }
288
289 WL_EXPORT void
290 ds_tizen_input_method_context_add_preedit_styling_listener(
291     struct ds_tizen_input_method_context *context, struct wl_listener *listener)
292 {
293     wl_signal_add(&context->events.preedit_styling, listener);
294 }
295
296 WL_EXPORT void
297 ds_tizen_input_method_context_add_preedit_cursor_listener(
298     struct ds_tizen_input_method_context *context, struct wl_listener *listener)
299 {
300     wl_signal_add(&context->events.preedit_cursor, listener);
301 }
302
303 WL_EXPORT void
304 ds_tizen_input_method_context_add_delete_surrounding_text_listener(
305     struct ds_tizen_input_method_context *context, struct wl_listener *listener)
306 {
307     wl_signal_add(&context->events.delete_surrounding_text, listener);
308 }
309
310 WL_EXPORT void
311 ds_tizen_input_method_context_add_cursor_position_listener(
312     struct ds_tizen_input_method_context *context, struct wl_listener *listener)
313 {
314     wl_signal_add(&context->events.cursor_position, listener);
315 }
316
317 WL_EXPORT void
318 ds_tizen_input_method_context_add_modifiers_map_listener(
319     struct ds_tizen_input_method_context *context, struct wl_listener *listener)
320 {
321     wl_signal_add(&context->events.modifiers_map, listener);
322 }
323
324 WL_EXPORT void
325 ds_tizen_input_method_context_add_keysym_listener(
326     struct ds_tizen_input_method_context *context, struct wl_listener *listener)
327 {
328     wl_signal_add(&context->events.keysym, listener);
329 }
330
331 WL_EXPORT void
332 ds_tizen_input_method_context_add_grab_keyboard_listener(
333     struct ds_tizen_input_method_context *context, struct wl_listener *listener)
334 {
335     wl_signal_add(&context->events.grab_keyboard, listener);
336 }
337
338 WL_EXPORT void
339 ds_tizen_input_method_context_add_key_listener(
340     struct ds_tizen_input_method_context *context, struct wl_listener *listener)
341 {
342     wl_signal_add(&context->events.key, listener);
343 }
344
345 WL_EXPORT void
346 ds_tizen_input_method_context_add_modifiers_listener(
347     struct ds_tizen_input_method_context *context, struct wl_listener *listener)
348 {
349     wl_signal_add(&context->events.modifiers, listener);
350 }
351
352 WL_EXPORT void
353 ds_tizen_input_method_context_add_language_listener(
354     struct ds_tizen_input_method_context *context, struct wl_listener *listener)
355 {
356     wl_signal_add(&context->events.language, listener);
357 }
358
359 WL_EXPORT void
360 ds_tizen_input_method_context_add_text_direction_listener(
361     struct ds_tizen_input_method_context *context, struct wl_listener *listener)
362 {
363     wl_signal_add(&context->events.text_direction, listener);
364 }
365
366 WL_EXPORT void
367 ds_tizen_input_method_context_send_surrounding_text(struct ds_tizen_input_method_context *context,
368     const char *text, uint32_t cursor, uint32_t anchor)
369 {
370     if (!context || !context->resource) return;
371
372     ds_inf("ds_tizen_input_method_context_send_surrounding_text");
373     zwp_input_method_context_v1_send_surrounding_text(context->resource, text, cursor, anchor);
374 }
375
376 WL_EXPORT void
377 ds_tizen_input_method_context_send_reset(
378     struct ds_tizen_input_method_context *context)
379 {
380     if (!context || !context->resource) return;
381
382     ds_inf("ds_tizen_input_method_context_send_reset");
383     zwp_input_method_context_v1_send_reset(context->resource);
384 }
385
386 WL_EXPORT void
387 ds_tizen_input_method_context_send_content_type(
388     struct ds_tizen_input_method_context *context, uint32_t hint, uint32_t purpose)
389 {
390     if (!context || !context->resource) return;
391
392     ds_inf("ds_tizen_input_method_context_send_content_type");
393     zwp_input_method_context_v1_send_content_type(context->resource, hint, purpose);
394 }
395
396 WL_EXPORT void
397 ds_tizen_input_method_context_send_invoke_action(
398     struct ds_tizen_input_method_context *context, uint32_t button, uint32_t index)
399 {
400     if (!context || !context->resource) return;
401
402     ds_inf("ds_tizen_input_method_context_send_invoke_action");
403     zwp_input_method_context_v1_send_invoke_action(context->resource, button, index);
404 }
405
406 WL_EXPORT void
407 ds_tizen_input_method_context_send_commit_state(
408     struct ds_tizen_input_method_context *context, uint32_t serial)
409 {
410     if (!context || !context->resource) return;
411
412     ds_inf("ds_tizen_input_method_context_send_commit_state");
413     zwp_input_method_context_v1_send_commit_state(context->resource, serial);
414 }
415
416 WL_EXPORT void
417 ds_tizen_input_method_context_send_preferred_language(
418     struct ds_tizen_input_method_context *context, const char *language)
419 {
420     if (!context || !context->resource) return;
421
422     ds_inf("ds_tizen_input_method_context_send_preferred_language");
423     zwp_input_method_context_v1_send_preferred_language(context->resource, language);
424 }
425
426 static void
427 context_handle_destroy(struct wl_client *client, struct wl_resource *resource)
428 {
429     ds_inf("context_handle_destroy");
430     wl_resource_destroy(resource);
431 }
432
433 static void
434 context_handle_commit_string(struct wl_client *client,
435     struct wl_resource *resource, uint32_t serial, const char *text)
436 {
437     struct ds_tizen_input_method_context *context = wl_resource_get_user_data(resource);
438     struct ds_tizen_input_method_context_event_commit_string ds_event;
439
440     ds_inf("context_handle_commit_string");
441     ds_event.im_context = context;
442     ds_event.serial = serial;
443     ds_event.text = text;
444
445     wl_signal_emit(&context->events.commit_string, &ds_event);
446 }
447
448 static void
449 context_handle_preedit_string(struct wl_client *client,
450     struct wl_resource *resource, uint32_t serial, const char *text,
451     const char *commit)
452 {
453     struct ds_tizen_input_method_context *context = wl_resource_get_user_data(resource);
454     struct ds_tizen_input_method_context_event_preedit_string ds_event;
455
456     ds_inf("context_handle_preedit_string() serial:%u, text:%s, commit:%s",
457         serial, text, commit);
458
459     ds_event.im_context = context;
460     ds_event.serial = serial;
461     ds_event.text = text;
462     ds_event.commit = commit;
463
464     wl_signal_emit(&context->events.preedit_string, &ds_event);
465 }
466
467 static void
468 context_handle_preedit_styling(struct wl_client *client,
469     struct wl_resource *resource, uint32_t index, uint32_t length,
470     uint32_t style)
471 {
472     struct ds_tizen_input_method_context *context = wl_resource_get_user_data(resource);
473     struct ds_tizen_input_method_context_event_preedit_styling ds_event;
474
475     ds_inf("context_handle_preedit_styling() index:%u, length:%u, style:%u",
476         index, length, style);
477
478     ds_event.im_context = context;
479     ds_event.index = index;
480     ds_event.length = length;
481     ds_event.style = style;
482
483     wl_signal_emit(&context->events.preedit_styling, &ds_event);
484 }
485
486 static void
487 context_handle_preedit_cursor(struct wl_client *client,
488     struct wl_resource *resource, int32_t index)
489 {
490     struct ds_tizen_input_method_context *context = wl_resource_get_user_data(resource);
491     struct ds_tizen_input_method_context_event_preedit_cursor ds_event;
492
493     ds_inf("context_handle_preedit_cursor() cursor:%d", index);
494
495     ds_event.im_context = context;
496     ds_event.index = index;
497     wl_signal_emit(&context->events.preedit_styling, &ds_event);
498 }
499
500 static void
501 context_handle_delete_surrounding_text(struct wl_client *client,
502     struct wl_resource *resource, int32_t index, uint32_t length)
503 {
504     struct ds_tizen_input_method_context *context = wl_resource_get_user_data(resource);
505     struct ds_tizen_input_method_context_event_delete_surrounding_text ds_event;
506
507     ds_inf("context_handle_delete_surrounding_text() index:%d, length:%u", index, length);
508
509     ds_event.im_context = context;
510     ds_event.index = index;
511     ds_event.length = length;
512     wl_signal_emit(&context->events.delete_surrounding_text, &ds_event);
513 }
514
515 static void
516 context_handle_cursor_position(struct wl_client *client,
517     struct wl_resource *resource, int32_t index, int32_t anchor)
518 {
519     struct ds_tizen_input_method_context *context = wl_resource_get_user_data(resource);
520     struct ds_tizen_input_method_context_event_cursor_position ds_event;
521
522     ds_inf("context_handle_cursor_position() index:%d anchor:%d", index, anchor);
523
524     ds_event.im_context = context;
525     ds_event.index = index;
526     ds_event.anchor = anchor;
527     wl_signal_emit(&context->events.cursor_position, &ds_event);
528 }
529
530 static void
531 context_handle_modifiers_map(struct wl_client *client,
532     struct wl_resource *resource, struct wl_array *map)
533 {
534     struct ds_tizen_input_method_context *context = wl_resource_get_user_data(resource);
535     struct ds_tizen_input_method_context_event_modifiers_map ds_event;
536
537     ds_inf("context_handle_modifiers_map() map(%p)", map);
538
539     ds_event.im_context = context;
540     ds_event.map = map;
541     wl_signal_emit(&context->events.modifiers_map, &ds_event);
542 }
543
544 static void
545 context_handle_keysym(struct wl_client *client, struct wl_resource *resource,
546     uint32_t serial, uint32_t time, uint32_t sym,
547     uint32_t state, uint32_t modifiers)
548 {
549     struct ds_tizen_input_method_context *context = wl_resource_get_user_data(resource);
550     struct ds_tizen_input_method_context_event_keysym ds_event;
551
552     ds_inf("context_handle_keysym() serial(%u), time(%u), sym(%u), state(%u), modifiers(%u)",
553         serial, time, sym, state, modifiers);
554
555     ds_event.im_context = context;
556     ds_event.serial = serial;
557     ds_event.time = time;
558     ds_event.sym = sym;
559     ds_event.state = state;
560     ds_event.modifiers = modifiers;
561     wl_signal_emit(&context->events.keysym, &ds_event);
562 }
563
564 static void
565 context_handle_grab_keyboard(struct wl_client *client,
566     struct wl_resource *resource, uint32_t id)
567 {
568     ds_inf("context_handle_grab_keyboard() nothing done");
569     //TODO
570 }
571
572 static void
573 context_handle_key(struct wl_client *client, struct wl_resource *resource,
574     uint32_t serial, uint32_t time, uint32_t key, uint32_t state_w)
575 {
576     ds_inf("context_handle_key() nothing done");
577     //TODO
578 }
579
580 static void
581 context_handle_modifiers(struct wl_client *client,
582     struct wl_resource *resource, uint32_t serial, uint32_t mods_depressed,
583     uint32_t mods_latched, uint32_t mods_locked, uint32_t group)
584 {
585     ds_inf("context_handle_modifiers() nothing done");
586     //TODO
587 }
588
589 static void
590 context_handle_language(struct wl_client *client,
591     struct wl_resource *resource, uint32_t serial, const char *language)
592 {
593     struct ds_tizen_input_method_context *context = wl_resource_get_user_data(resource);
594     struct ds_tizen_input_method_context_event_language ds_event;
595
596     ds_inf("context_handle_language() serial(%u) language(%s)", serial, language);
597
598     ds_event.im_context = context;
599     ds_event.serial = serial;
600     ds_event.language = language;
601     wl_signal_emit(&context->events.language, &ds_event);
602 }
603
604 static void
605 context_handle_text_direction(struct wl_client *client,
606     struct wl_resource *resource, uint32_t serial, uint32_t direction)
607 {
608     struct ds_tizen_input_method_context *context = wl_resource_get_user_data(resource);
609     struct ds_tizen_input_method_context_event_text_direction ds_event;
610
611     ds_inf("context_handle_text_direction() serial(%u) direction(%u)", serial, direction);
612
613     ds_event.im_context = context;
614     ds_event.serial = serial;
615     ds_event.direction = direction;
616     wl_signal_emit(&context->events.text_direction, &ds_event);
617 }
618
619 static const struct zwp_input_method_context_v1_interface context_impl = {
620     .destroy = context_handle_destroy,
621     .commit_string = context_handle_commit_string,
622     .preedit_string = context_handle_preedit_string,
623     .preedit_styling = context_handle_preedit_styling,
624     .preedit_cursor = context_handle_preedit_cursor,
625     .delete_surrounding_text = context_handle_delete_surrounding_text,
626     .cursor_position = context_handle_cursor_position,
627     .modifiers_map = context_handle_modifiers_map,
628     .keysym = context_handle_keysym,
629     .grab_keyboard = context_handle_grab_keyboard,
630     .key = context_handle_key,
631     .modifiers = context_handle_modifiers,
632     .language = context_handle_language,
633     .text_direction = context_handle_text_direction,
634     //for tizen_only
635     .selection_region = NULL,
636     .private_command = NULL,
637     .update_input_panel_data = NULL,
638     .hide_input_panel = NULL,
639     .get_selection_text = NULL,
640     .get_surrounding_text = NULL,
641     .filter_key_event_done = NULL,
642     .update_ise_geometry = NULL,
643     .recapture_string = NULL,
644     .input_panel_event = NULL,
645     .commit_content = NULL,
646     .update_candidate_state = NULL,
647     .reshow_input_panel = NULL,
648     .set_floating_panel = NULL,
649     .set_floating_drag_enabled = NULL,
650 };
651
652 static void
653 input_method_handle_display_destroy(struct wl_listener *listener, void *data)
654 {
655     struct ds_tizen_input_method *input_method;
656
657     input_method = wl_container_of(listener, input_method, destroy);
658
659     ds_inf("Global destroy: input_method(%p)", input_method);
660
661     if (input_method->context)
662         context_destroy(input_method->context);
663
664     wl_signal_emit(&input_method->events.destroy, input_method);
665     wl_list_remove(&input_method->destroy.link);
666
667     wl_global_destroy(input_method->global);
668     free(input_method);
669 }
670
671 static void
672 input_method_bind(struct wl_client *wl_client, void *data,
673     uint32_t version, uint32_t id)
674 {
675     struct ds_tizen_input_method *input_method = data;
676
677     ds_inf("input_method. client binds. (client:%p)", wl_client);
678
679     input_method->resource = wl_resource_create(wl_client,
680             &zwp_input_method_v1_interface,
681             version, id);
682     if (input_method->resource == NULL) {
683         ds_err("input_method. wl_resource_create() failed.");
684         wl_client_post_no_memory(wl_client);
685         return;
686     }
687     wl_resource_set_implementation(input_method->resource, NULL,
688         input_method, NULL);
689 }
690
691 WL_EXPORT struct ds_tizen_input_method *
692 ds_tizen_input_method_create(struct wl_display *display)
693 {
694     struct ds_tizen_input_method *input_method;
695
696     input_method = calloc(1, sizeof *input_method);
697     if (input_method == NULL) {
698         ds_err("calloc() failed. ds_tizen_input_method");
699         return NULL;
700     }
701
702     input_method->global = wl_global_create(display,
703         &zwp_input_method_v1_interface, INPUT_METHOD_VERSION, input_method, input_method_bind);
704     if (!input_method->global) {
705         free(input_method);
706         return NULL;
707     }
708
709     wl_signal_init(&input_method->events.destroy);
710
711     input_method->destroy.notify = input_method_handle_display_destroy;
712     wl_display_add_destroy_listener(display, &input_method->destroy);
713
714     ds_inf("Global create: zwp_input_method_v1. input_method(%p)", input_method);
715
716     return input_method;
717 }