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