2 #include <wayland-server.h>
3 #include <input-method-server-protocol.h>
7 #include <libds/seat.h>
8 #include <libds-tizen/input_method.h>
10 #define INPUT_METHOD_VERSION 1
12 struct ds_tizen_input_method;
14 struct ds_tizen_input_method_context {
15 struct wl_resource *resource;
16 struct ds_tizen_input_method *input_method;
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;
30 struct wl_signal modifiers;
31 struct wl_signal language;
32 struct wl_signal text_direction;
36 struct ds_tizen_input_method {
37 struct wl_global *global;
38 struct wl_resource *resource;
39 struct ds_tizen_input_method_context *context;
41 struct wl_listener destroy;
44 struct wl_signal destroy;
48 struct ds_tizen_input_method_manager {
49 struct wl_global *global;
50 struct wl_resource *resource;
52 struct wl_listener destroy;
55 struct wl_signal destroy;
56 struct wl_signal set_transient_for;
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;
64 ds_tizen_input_method_manager_add_destroy_listener(
65 struct ds_tizen_input_method_manager *im_mgr, struct wl_listener *listener)
67 wl_signal_add(&im_mgr->events.destroy, listener);
71 ds_tizen_input_method_manager_add_set_transient_for_listener(
72 struct ds_tizen_input_method_manager *im_mgr, struct wl_listener *listener)
74 wl_signal_add(&im_mgr->events.set_transient_for, listener);
78 input_method_mgr_handle_display_destroy(struct wl_listener *listener, void *data)
80 struct ds_tizen_input_method_manager *input_method_mgr;
82 input_method_mgr = wl_container_of(listener, input_method_mgr, destroy);
84 ds_inf("Global destroy: input_method_mgr(%p)", input_method_mgr);
86 wl_signal_emit(&input_method_mgr->events.destroy, input_method_mgr);
87 wl_list_remove(&input_method_mgr->destroy.link);
89 wl_global_destroy(input_method_mgr->global);
90 free(input_method_mgr);
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)
97 struct ds_tizen_input_method_manager_event_set_transient_for ds_event;
98 struct ds_tizen_input_method_manager *input_method_mgr;
100 input_method_mgr = wl_resource_get_user_data(resource);
102 ds_inf("input_method_mgr_handle_set_transient_for() parent:%u, child:%u",
103 parent_pid, child_pid);
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);
111 static const struct zwp_input_method_manager_v1_interface input_method_mgr_impl =
113 .set_transient_for = input_method_mgr_handle_set_transient_for,
117 input_method_mgr_bind(struct wl_client *wl_client, void *data,
118 uint32_t version, uint32_t id)
120 struct ds_tizen_input_method_manager *input_method_mgr = data;
122 ds_inf("input_method_mgr. client binds. (client:%p)", wl_client);
124 input_method_mgr->resource = wl_resource_create(wl_client,
125 &zwp_input_method_manager_v1_interface,
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);
132 wl_resource_set_implementation(input_method_mgr->resource, &input_method_mgr_impl,
133 input_method_mgr, NULL);
136 WL_EXPORT struct ds_tizen_input_method_manager *
137 ds_tizen_input_method_manager_create(struct wl_display *display)
139 struct ds_tizen_input_method_manager *input_method_mgr;
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");
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);
154 wl_signal_init(&input_method_mgr->events.destroy);
155 wl_signal_init(&input_method_mgr->events.set_transient_for);
157 input_method_mgr->destroy.notify = input_method_mgr_handle_display_destroy;
158 wl_display_add_destroy_listener(display, &input_method_mgr->destroy);
160 ds_inf("Global create: zwp_input_method_manager_v1. input_method_mgr(%p)", input_method_mgr);
162 return input_method_mgr;
166 ds_tizen_input_method_add_destroy_listener(
167 struct ds_tizen_input_method *im, struct wl_listener *listener)
169 wl_signal_add(&im->events.destroy, listener);
173 ds_tizen_input_method_send_activate(struct ds_tizen_input_method *im,
174 struct ds_tizen_input_method_context *context)
176 if (!im || !context) return;
178 ds_inf("ds_tizen_input_method_send_activate");
179 zwp_input_method_v1_send_activate(im->resource, context->resource);
183 ds_tizen_input_method_send_deactivate(struct ds_tizen_input_method *im,
184 struct ds_tizen_input_method_context *context)
186 if (!im || !context) return;
188 ds_inf("ds_tizen_input_method_send_deactivate");
189 zwp_input_method_v1_send_deactivate(im->resource, context->resource);
193 context_destroy(struct ds_tizen_input_method_context *context)
195 ds_inf("input_method_context(%p) destroy", context);
197 wl_signal_emit(&context->events.destroy, context);
203 input_method_context_client_handle_destroy(struct wl_resource *resource)
205 struct ds_tizen_input_method_context *context = wl_resource_get_user_data(resource);
206 struct ds_tizen_input_method *input_method;
208 ds_inf("input_method_context_client_handle_destroy");
210 input_method = context->input_method;
211 input_method->context = NULL;
213 context_destroy(context);
216 WL_EXPORT struct ds_tizen_input_method_context *
217 ds_tizen_input_method_create_context(struct ds_tizen_input_method *input_method)
219 struct ds_tizen_input_method_context *context;
220 struct wl_resource *binding;
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");
229 binding = input_method->resource;
231 ds_err("context. there is no resource of input_method.");
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.");
242 wl_resource_set_implementation(context->resource, &context_impl,
243 context, input_method_context_client_handle_destroy);
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);
260 ds_tizen_input_method_send_activate(input_method, context);
262 input_method->context = context;
263 context->input_method = input_method;
269 ds_tizen_input_method_context_add_destroy_listener(
270 struct ds_tizen_input_method_context *context, struct wl_listener *listener)
272 wl_signal_add(&context->events.destroy, listener);
276 ds_tizen_input_method_context_add_commit_string_listener(
277 struct ds_tizen_input_method_context *context, struct wl_listener *listener)
279 wl_signal_add(&context->events.commit_string, listener);
283 ds_tizen_input_method_context_add_preedit_string_listener(
284 struct ds_tizen_input_method_context *context, struct wl_listener *listener)
286 wl_signal_add(&context->events.preedit_string, listener);
290 ds_tizen_input_method_context_add_preedit_styling_listener(
291 struct ds_tizen_input_method_context *context, struct wl_listener *listener)
293 wl_signal_add(&context->events.preedit_styling, listener);
297 ds_tizen_input_method_context_add_preedit_cursor_listener(
298 struct ds_tizen_input_method_context *context, struct wl_listener *listener)
300 wl_signal_add(&context->events.preedit_cursor, listener);
304 ds_tizen_input_method_context_add_delete_surrounding_text_listener(
305 struct ds_tizen_input_method_context *context, struct wl_listener *listener)
307 wl_signal_add(&context->events.delete_surrounding_text, listener);
311 ds_tizen_input_method_context_add_cursor_position_listener(
312 struct ds_tizen_input_method_context *context, struct wl_listener *listener)
314 wl_signal_add(&context->events.cursor_position, listener);
318 ds_tizen_input_method_context_add_modifiers_map_listener(
319 struct ds_tizen_input_method_context *context, struct wl_listener *listener)
321 wl_signal_add(&context->events.modifiers_map, listener);
325 ds_tizen_input_method_context_add_keysym_listener(
326 struct ds_tizen_input_method_context *context, struct wl_listener *listener)
328 wl_signal_add(&context->events.keysym, listener);
332 ds_tizen_input_method_context_add_grab_keyboard_listener(
333 struct ds_tizen_input_method_context *context, struct wl_listener *listener)
335 wl_signal_add(&context->events.grab_keyboard, listener);
339 ds_tizen_input_method_context_add_key_listener(
340 struct ds_tizen_input_method_context *context, struct wl_listener *listener)
342 wl_signal_add(&context->events.key, listener);
346 ds_tizen_input_method_context_add_modifiers_listener(
347 struct ds_tizen_input_method_context *context, struct wl_listener *listener)
349 wl_signal_add(&context->events.modifiers, listener);
353 ds_tizen_input_method_context_add_language_listener(
354 struct ds_tizen_input_method_context *context, struct wl_listener *listener)
356 wl_signal_add(&context->events.language, listener);
360 ds_tizen_input_method_context_add_text_direction_listener(
361 struct ds_tizen_input_method_context *context, struct wl_listener *listener)
363 wl_signal_add(&context->events.text_direction, listener);
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)
370 if (!context || !context->resource) return;
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);
377 ds_tizen_input_method_context_send_reset(
378 struct ds_tizen_input_method_context *context)
380 if (!context || !context->resource) return;
382 ds_inf("ds_tizen_input_method_context_send_reset");
383 zwp_input_method_context_v1_send_reset(context->resource);
387 ds_tizen_input_method_context_send_content_type(
388 struct ds_tizen_input_method_context *context, uint32_t hint, uint32_t purpose)
390 if (!context || !context->resource) return;
392 ds_inf("ds_tizen_input_method_context_send_content_type");
393 zwp_input_method_context_v1_send_content_type(context->resource, hint, purpose);
397 ds_tizen_input_method_context_send_invoke_action(
398 struct ds_tizen_input_method_context *context, uint32_t button, uint32_t index)
400 if (!context || !context->resource) return;
402 ds_inf("ds_tizen_input_method_context_send_invoke_action");
403 zwp_input_method_context_v1_send_invoke_action(context->resource, button, index);
407 ds_tizen_input_method_context_send_commit_state(
408 struct ds_tizen_input_method_context *context, uint32_t serial)
410 if (!context || !context->resource) return;
412 ds_inf("ds_tizen_input_method_context_send_commit_state");
413 zwp_input_method_context_v1_send_commit_state(context->resource, serial);
417 ds_tizen_input_method_context_send_preferred_language(
418 struct ds_tizen_input_method_context *context, const char *language)
420 if (!context || !context->resource) return;
422 ds_inf("ds_tizen_input_method_context_send_preferred_language");
423 zwp_input_method_context_v1_send_preferred_language(context->resource, language);
427 context_handle_destroy(struct wl_client *client, struct wl_resource *resource)
429 ds_inf("context_handle_destroy");
430 wl_resource_destroy(resource);
434 context_handle_commit_string(struct wl_client *client,
435 struct wl_resource *resource, uint32_t serial, const char *text)
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;
440 ds_inf("context_handle_commit_string");
441 ds_event.im_context = context;
442 ds_event.serial = serial;
443 ds_event.text = text;
445 wl_signal_emit(&context->events.commit_string, &ds_event);
449 context_handle_preedit_string(struct wl_client *client,
450 struct wl_resource *resource, uint32_t serial, const char *text,
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;
456 ds_inf("context_handle_preedit_string() serial:%u, text:%s, commit:%s",
457 serial, text, commit);
459 ds_event.im_context = context;
460 ds_event.serial = serial;
461 ds_event.text = text;
462 ds_event.commit = commit;
464 wl_signal_emit(&context->events.preedit_string, &ds_event);
468 context_handle_preedit_styling(struct wl_client *client,
469 struct wl_resource *resource, uint32_t index, uint32_t length,
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;
475 ds_inf("context_handle_preedit_styling() index:%u, length:%u, style:%u",
476 index, length, style);
478 ds_event.im_context = context;
479 ds_event.index = index;
480 ds_event.length = length;
481 ds_event.style = style;
483 wl_signal_emit(&context->events.preedit_styling, &ds_event);
487 context_handle_preedit_cursor(struct wl_client *client,
488 struct wl_resource *resource, int32_t index)
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;
493 ds_inf("context_handle_preedit_cursor() cursor:%d", index);
495 ds_event.im_context = context;
496 ds_event.index = index;
497 wl_signal_emit(&context->events.preedit_styling, &ds_event);
501 context_handle_delete_surrounding_text(struct wl_client *client,
502 struct wl_resource *resource, int32_t index, uint32_t length)
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;
507 ds_inf("context_handle_delete_surrounding_text() index:%d, length:%u", index, length);
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);
516 context_handle_cursor_position(struct wl_client *client,
517 struct wl_resource *resource, int32_t index, int32_t anchor)
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;
522 ds_inf("context_handle_cursor_position() index:%d anchor:%d", index, anchor);
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);
531 context_handle_modifiers_map(struct wl_client *client,
532 struct wl_resource *resource, struct wl_array *map)
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;
537 ds_inf("context_handle_modifiers_map() map(%p)", map);
539 ds_event.im_context = context;
541 wl_signal_emit(&context->events.modifiers_map, &ds_event);
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)
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;
552 ds_inf("context_handle_keysym() serial(%u), time(%u), sym(%u), state(%u), modifiers(%u)",
553 serial, time, sym, state, modifiers);
555 ds_event.im_context = context;
556 ds_event.serial = serial;
557 ds_event.time = time;
559 ds_event.state = state;
560 ds_event.modifiers = modifiers;
561 wl_signal_emit(&context->events.keysym, &ds_event);
565 context_handle_grab_keyboard(struct wl_client *client,
566 struct wl_resource *resource, uint32_t id)
568 ds_inf("context_handle_grab_keyboard() nothing done");
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)
576 ds_inf("context_handle_key() nothing done");
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)
585 ds_inf("context_handle_modifiers() nothing done");
590 context_handle_language(struct wl_client *client,
591 struct wl_resource *resource, uint32_t serial, const char *language)
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;
596 ds_inf("context_handle_language() serial(%u) language(%s)", serial, language);
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);
605 context_handle_text_direction(struct wl_client *client,
606 struct wl_resource *resource, uint32_t serial, uint32_t direction)
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;
611 ds_inf("context_handle_text_direction() serial(%u) direction(%u)", serial, direction);
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);
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,
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,
653 input_method_handle_display_destroy(struct wl_listener *listener, void *data)
655 struct ds_tizen_input_method *input_method;
657 input_method = wl_container_of(listener, input_method, destroy);
659 ds_inf("Global destroy: input_method(%p)", input_method);
661 if (input_method->context)
662 context_destroy(input_method->context);
664 wl_signal_emit(&input_method->events.destroy, input_method);
665 wl_list_remove(&input_method->destroy.link);
667 wl_global_destroy(input_method->global);
672 input_method_bind(struct wl_client *wl_client, void *data,
673 uint32_t version, uint32_t id)
675 struct ds_tizen_input_method *input_method = data;
677 ds_inf("input_method. client binds. (client:%p)", wl_client);
679 input_method->resource = wl_resource_create(wl_client,
680 &zwp_input_method_v1_interface,
682 if (input_method->resource == NULL) {
683 ds_err("input_method. wl_resource_create() failed.");
684 wl_client_post_no_memory(wl_client);
687 wl_resource_set_implementation(input_method->resource, NULL,
691 WL_EXPORT struct ds_tizen_input_method *
692 ds_tizen_input_method_create(struct wl_display *display)
694 struct ds_tizen_input_method *input_method;
696 input_method = calloc(1, sizeof *input_method);
697 if (input_method == NULL) {
698 ds_err("calloc() failed. ds_tizen_input_method");
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) {
709 wl_signal_init(&input_method->events.destroy);
711 input_method->destroy.notify = input_method_handle_display_destroy;
712 wl_display_add_destroy_listener(display, &input_method->destroy);
714 ds_inf("Global create: zwp_input_method_v1. input_method(%p)", input_method);