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;
45 struct wl_signal new_input_method_context;
49 struct ds_tizen_input_method_manager {
50 struct wl_global *global;
51 struct wl_resource *resource;
53 struct wl_listener destroy;
56 struct wl_signal destroy;
57 struct wl_signal set_transient_for;
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;
65 ds_tizen_input_method_manager_add_destroy_listener(
66 struct ds_tizen_input_method_manager *im_mgr, struct wl_listener *listener)
68 wl_signal_add(&im_mgr->events.destroy, listener);
72 ds_tizen_input_method_manager_add_set_transient_for_listener(
73 struct ds_tizen_input_method_manager *im_mgr, struct wl_listener *listener)
75 wl_signal_add(&im_mgr->events.set_transient_for, listener);
79 input_method_mgr_handle_display_destroy(struct wl_listener *listener, void *data)
81 struct ds_tizen_input_method_manager *input_method_mgr;
83 input_method_mgr = wl_container_of(listener, input_method_mgr, destroy);
85 ds_inf("Global destroy: input_method_mgr(%p)", input_method_mgr);
87 wl_signal_emit(&input_method_mgr->events.destroy, input_method_mgr);
88 wl_list_remove(&input_method_mgr->destroy.link);
90 wl_global_destroy(input_method_mgr->global);
91 free(input_method_mgr);
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)
98 struct ds_tizen_input_method_manager_event_set_transient_for ds_event;
99 struct ds_tizen_input_method_manager *input_method_mgr;
101 input_method_mgr = wl_resource_get_user_data(resource);
103 ds_inf("input_method_mgr_handle_set_transient_for() parent:%u, child:%u",
104 parent_pid, child_pid);
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);
112 static const struct zwp_input_method_manager_v1_interface input_method_mgr_impl =
114 .set_transient_for = input_method_mgr_handle_set_transient_for,
118 input_method_mgr_client_handle_destroy(struct wl_resource *resource)
120 ds_inf("input_method_mgr_client_handle_destroy");
124 input_method_mgr_bind(struct wl_client *wl_client, void *data,
125 uint32_t version, uint32_t id)
127 struct ds_tizen_input_method_manager *input_method_mgr = data;
128 struct wl_resource *resource;
130 ds_inf("input_method_mgr. client binds. (client:%p)", wl_client);
132 resource = wl_resource_create(wl_client,
133 &zwp_input_method_manager_v1_interface,
135 if (resource == NULL) {
136 ds_err("input_method_mgr. wl_resource_create() failed.");
137 wl_client_post_no_memory(wl_client);
140 wl_resource_set_implementation(resource, &input_method_mgr_impl,
141 input_method_mgr, input_method_mgr_client_handle_destroy);
144 WL_EXPORT struct ds_tizen_input_method_manager *
145 ds_tizen_input_method_manager_create(struct wl_display *display)
147 struct ds_tizen_input_method_manager *input_method_mgr;
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");
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);
162 wl_signal_init(&input_method_mgr->events.destroy);
163 wl_signal_init(&input_method_mgr->events.set_transient_for);
165 input_method_mgr->destroy.notify = input_method_mgr_handle_display_destroy;
166 wl_display_add_destroy_listener(display, &input_method_mgr->destroy);
168 ds_inf("Global create: zwp_input_method_manager_v1. input_method_mgr(%p)", input_method_mgr);
170 return input_method_mgr;
174 ds_tizen_input_method_add_destroy_listener(
175 struct ds_tizen_input_method *im, struct wl_listener *listener)
177 wl_signal_add(&im->events.destroy, listener);
181 ds_tizen_input_method_add_new_input_method_context_listener(
182 struct ds_tizen_input_method *im, struct wl_listener *listener)
184 wl_signal_add(&im->events.new_input_method_context, listener);
188 ds_tizen_input_method_send_activate(struct ds_tizen_input_method *im,
189 struct ds_tizen_input_method_context *context)
191 if (!im || !context) return;
193 ds_inf("ds_tizen_input_method_send_activate");
194 zwp_input_method_v1_send_activate(im->resource, context->resource);
198 ds_tizen_input_method_send_deactivate(struct ds_tizen_input_method *im,
199 struct ds_tizen_input_method_context *context)
201 if (!im || !context) return;
203 ds_inf("ds_tizen_input_method_send_deactivate");
204 zwp_input_method_v1_send_deactivate(im->resource, context->resource);
208 context_destroy(struct ds_tizen_input_method_context *context)
210 ds_inf("input_method_context(%p) destroy", context);
212 wl_signal_emit(&context->events.destroy, context);
218 input_method_context_client_handle_destroy(struct wl_resource *resource)
220 struct ds_tizen_input_method_context *context = wl_resource_get_user_data(resource);
221 struct ds_tizen_input_method *input_method;
223 ds_inf("input_method_context_client_handle_destroy");
225 input_method = context->input_method;
226 input_method->context = NULL;
228 context_destroy(context);
231 WL_EXPORT struct ds_tizen_input_method_context *
232 ds_tizen_input_method_create_context(struct ds_tizen_input_method *input_method)
234 struct ds_tizen_input_method_context *context;
235 struct wl_resource *binding;
237 ds_inf("ds_tizen_input_method_create_context");
238 context = calloc(1, sizeof *context);
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);
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);
264 wl_signal_emit(&input_method->events.new_input_method_context, context);
266 ds_tizen_input_method_send_activate(input_method, context);
268 input_method->context = context;
269 context->input_method = input_method;
275 ds_tizen_input_method_context_add_destroy_listener(
276 struct ds_tizen_input_method_context *context, struct wl_listener *listener)
278 wl_signal_add(&context->events.destroy, listener);
282 ds_tizen_input_method_context_add_commit_string_listener(
283 struct ds_tizen_input_method_context *context, struct wl_listener *listener)
285 wl_signal_add(&context->events.commit_string, listener);
289 ds_tizen_input_method_context_add_preedit_string_listener(
290 struct ds_tizen_input_method_context *context, struct wl_listener *listener)
292 wl_signal_add(&context->events.preedit_string, listener);
296 ds_tizen_input_method_context_add_preedit_styling_listener(
297 struct ds_tizen_input_method_context *context, struct wl_listener *listener)
299 wl_signal_add(&context->events.preedit_styling, listener);
303 ds_tizen_input_method_context_add_preedit_cursor_listener(
304 struct ds_tizen_input_method_context *context, struct wl_listener *listener)
306 wl_signal_add(&context->events.preedit_cursor, listener);
310 ds_tizen_input_method_context_add_delete_surrounding_text_listener(
311 struct ds_tizen_input_method_context *context, struct wl_listener *listener)
313 wl_signal_add(&context->events.delete_surrounding_text, listener);
317 ds_tizen_input_method_context_add_cursor_position_listener(
318 struct ds_tizen_input_method_context *context, struct wl_listener *listener)
320 wl_signal_add(&context->events.cursor_position, listener);
324 ds_tizen_input_method_context_add_modifiers_map_listener(
325 struct ds_tizen_input_method_context *context, struct wl_listener *listener)
327 wl_signal_add(&context->events.modifiers_map, listener);
331 ds_tizen_input_method_context_add_keysym_listener(
332 struct ds_tizen_input_method_context *context, struct wl_listener *listener)
334 wl_signal_add(&context->events.keysym, listener);
338 ds_tizen_input_method_context_add_grab_keyboard_listener(
339 struct ds_tizen_input_method_context *context, struct wl_listener *listener)
341 wl_signal_add(&context->events.grab_keyboard, listener);
345 ds_tizen_input_method_context_add_key_listener(
346 struct ds_tizen_input_method_context *context, struct wl_listener *listener)
348 wl_signal_add(&context->events.key, listener);
352 ds_tizen_input_method_context_add_modifiers_listener(
353 struct ds_tizen_input_method_context *context, struct wl_listener *listener)
355 wl_signal_add(&context->events.modifiers, listener);
359 ds_tizen_input_method_context_add_language_listener(
360 struct ds_tizen_input_method_context *context, struct wl_listener *listener)
362 wl_signal_add(&context->events.language, listener);
366 ds_tizen_input_method_context_add_text_direction_listener(
367 struct ds_tizen_input_method_context *context, struct wl_listener *listener)
369 wl_signal_add(&context->events.text_direction, listener);
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)
376 if (!context || !context->resource) return;
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);
383 ds_tizen_input_method_context_send_reset(
384 struct ds_tizen_input_method_context *context)
386 if (!context || !context->resource) return;
388 ds_inf("ds_tizen_input_method_context_send_reset");
389 zwp_input_method_context_v1_send_reset(context->resource);
393 ds_tizen_input_method_context_send_content_type(
394 struct ds_tizen_input_method_context *context, uint32_t hint, uint32_t purpose)
396 if (!context || !context->resource) return;
398 ds_inf("ds_tizen_input_method_context_send_content_type");
399 zwp_input_method_context_v1_send_content_type(context->resource, hint, purpose);
403 ds_tizen_input_method_context_send_invoke_action(
404 struct ds_tizen_input_method_context *context, uint32_t button, uint32_t index)
406 if (!context || !context->resource) return;
408 ds_inf("ds_tizen_input_method_context_send_invoke_action");
409 zwp_input_method_context_v1_send_invoke_action(context->resource, button, index);
413 ds_tizen_input_method_context_send_commit_state(
414 struct ds_tizen_input_method_context *context, uint32_t serial)
416 if (!context || !context->resource) return;
418 ds_inf("ds_tizen_input_method_context_send_commit_state");
419 zwp_input_method_context_v1_send_commit_state(context->resource, serial);
423 ds_tizen_input_method_context_send_preferred_language(
424 struct ds_tizen_input_method_context *context, const char *language)
426 if (!context || !context->resource) return;
428 ds_inf("ds_tizen_input_method_context_send_preferred_language");
429 zwp_input_method_context_v1_send_preferred_language(context->resource, language);
433 context_handle_destroy(struct wl_client *client, struct wl_resource *resource)
435 ds_inf("context_handle_destroy");
436 wl_resource_destroy(resource);
440 context_handle_commit_string(struct wl_client *client,
441 struct wl_resource *resource, uint32_t serial, const char *text)
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;
446 ds_inf("context_handle_commit_string");
447 ds_event.im_context = context;
448 ds_event.serial = serial;
449 ds_event.text = text;
451 wl_signal_emit(&context->events.commit_string, &ds_event);
455 context_handle_preedit_string(struct wl_client *client,
456 struct wl_resource *resource, uint32_t serial, const char *text,
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;
462 ds_inf("context_handle_preedit_string() serial:%u, text:%s, commit:%s",
463 serial, text, commit);
465 ds_event.im_context = context;
466 ds_event.serial = serial;
467 ds_event.text = text;
468 ds_event.commit = commit;
470 wl_signal_emit(&context->events.preedit_string, &ds_event);
474 context_handle_preedit_styling(struct wl_client *client,
475 struct wl_resource *resource, uint32_t index, uint32_t length,
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;
481 ds_inf("context_handle_preedit_styling() index:%u, length:%u, style:%u",
482 index, length, style);
484 ds_event.im_context = context;
485 ds_event.index = index;
486 ds_event.length = length;
487 ds_event.style = style;
489 wl_signal_emit(&context->events.preedit_styling, &ds_event);
493 context_handle_preedit_cursor(struct wl_client *client,
494 struct wl_resource *resource, int32_t index)
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;
499 ds_inf("context_handle_preedit_cursor() cursor:%d", index);
501 ds_event.im_context = context;
502 ds_event.index = index;
503 wl_signal_emit(&context->events.preedit_styling, &ds_event);
507 context_handle_delete_surrounding_text(struct wl_client *client,
508 struct wl_resource *resource, int32_t index, uint32_t length)
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;
513 ds_inf("context_handle_delete_surrounding_text() index:%d, length:%u", index, length);
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);
522 context_handle_cursor_position(struct wl_client *client,
523 struct wl_resource *resource, int32_t index, int32_t anchor)
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;
528 ds_inf("context_handle_cursor_position() index:%d anchor:%d", index, anchor);
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);
537 context_handle_modifiers_map(struct wl_client *client,
538 struct wl_resource *resource, struct wl_array *map)
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;
543 ds_inf("context_handle_modifiers_map() map(%p)", map);
545 ds_event.im_context = context;
547 wl_signal_emit(&context->events.modifiers_map, &ds_event);
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)
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;
558 ds_inf("context_handle_keysym() serial(%u), time(%u), sym(%u), state(%u), modifiers(%u)",
559 serial, time, sym, state, modifiers);
561 ds_event.im_context = context;
562 ds_event.serial = serial;
563 ds_event.time = time;
565 ds_event.state = state;
566 ds_event.modifiers = modifiers;
567 wl_signal_emit(&context->events.keysym, &ds_event);
571 context_handle_grab_keyboard(struct wl_client *client,
572 struct wl_resource *resource, uint32_t id)
574 ds_inf("context_handle_grab_keyboard() nothing done");
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)
582 ds_inf("context_handle_key() nothing done");
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)
591 ds_inf("context_handle_modifiers() nothing done");
596 context_handle_language(struct wl_client *client,
597 struct wl_resource *resource, uint32_t serial, const char *language)
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;
602 ds_inf("context_handle_language() serial(%u) language(%s)", serial, language);
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);
611 context_handle_text_direction(struct wl_client *client,
612 struct wl_resource *resource, uint32_t serial, uint32_t direction)
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;
617 ds_inf("context_handle_text_direction() serial(%u) direction(%u)", serial, direction);
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);
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,
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,
659 input_method_handle_display_destroy(struct wl_listener *listener, void *data)
661 struct ds_tizen_input_method *input_method;
663 input_method = wl_container_of(listener, input_method, destroy);
665 ds_inf("Global destroy: input_method(%p)", input_method);
667 if (input_method->context)
668 context_destroy(input_method->context);
670 wl_signal_emit(&input_method->events.destroy, input_method);
671 wl_list_remove(&input_method->destroy.link);
673 wl_global_destroy(input_method->global);
678 input_method_client_handle_destroy(struct wl_resource *resource)
680 ds_inf("input_method_client_handle_destroy");
684 input_method_bind(struct wl_client *wl_client, void *data,
685 uint32_t version, uint32_t id)
687 struct ds_tizen_input_method *input_method = data;
689 ds_inf("input_method. client binds. (client:%p)", wl_client);
691 input_method->resource = wl_resource_create(wl_client,
692 &zwp_input_method_v1_interface,
694 if (input_method->resource == NULL) {
695 ds_err("input_method. wl_resource_create() failed.");
696 wl_client_post_no_memory(wl_client);
699 wl_resource_set_implementation(input_method->resource, NULL,
700 input_method, input_method_client_handle_destroy);
703 WL_EXPORT struct ds_tizen_input_method *
704 ds_tizen_input_method_create(struct wl_display *display)
706 struct ds_tizen_input_method *input_method;
708 input_method = calloc(1, sizeof *input_method);
709 if (input_method == NULL) {
710 ds_err("calloc() failed. ds_tizen_input_method");
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) {
721 wl_signal_init(&input_method->events.destroy);
722 wl_signal_init(&input_method->events.new_input_method_context);
724 input_method->destroy.notify = input_method_handle_display_destroy;
725 wl_display_add_destroy_listener(display, &input_method->destroy);
727 ds_inf("Global create: zwp_input_method_v1. input_method(%p)", input_method);