2 * Copyright © 2012 Openismus GmbH
3 * Copyright © 2012 Intel Corporation
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial
15 * portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
36 #include "compositor.h"
38 #include "text-input-unstable-v1-server-protocol.h"
39 #include "input-method-unstable-v1-server-protocol.h"
40 #include "shared/helpers.h"
41 #include "shared/timespec-util.h"
43 struct text_input_manager;
45 struct input_method_context;
49 struct wl_resource *resource;
51 struct weston_compositor *ec;
53 struct wl_list input_methods;
55 struct weston_surface *surface;
57 pixman_box32_t cursor_rectangle;
59 bool input_panel_visible;
61 struct text_input_manager *manager;
64 struct text_input_manager {
65 struct wl_global *text_input_manager_global;
66 struct wl_listener destroy_listener;
68 struct text_input *current_text_input;
70 struct weston_compositor *ec;
74 struct wl_resource *input_method_binding;
75 struct wl_global *input_method_global;
76 struct wl_listener destroy_listener;
78 struct weston_seat *seat;
79 struct text_input *input;
83 struct wl_listener keyboard_focus_listener;
85 bool focus_listener_initialized;
87 struct input_method_context *context;
89 struct text_backend *text_backend;
92 struct input_method_context {
93 struct wl_resource *resource;
95 struct text_input *input;
96 struct input_method *input_method;
98 struct wl_resource *keyboard;
101 struct text_backend {
102 struct weston_compositor *compositor;
106 struct wl_client *client;
109 struct timespec deathstamp;
112 struct wl_listener client_listener;
113 struct wl_listener seat_created_listener;
117 input_method_context_create(struct text_input *input,
118 struct input_method *input_method);
120 input_method_context_end_keyboard_grab(struct input_method_context *context);
123 input_method_init_seat(struct weston_seat *seat);
126 deactivate_input_method(struct input_method *input_method)
128 struct text_input *text_input = input_method->input;
129 struct weston_compositor *ec = text_input->ec;
131 if (input_method->context && input_method->input_method_binding) {
132 input_method_context_end_keyboard_grab(input_method->context);
133 zwp_input_method_v1_send_deactivate(
134 input_method->input_method_binding,
135 input_method->context->resource);
136 input_method->context->input = NULL;
139 wl_list_remove(&input_method->link);
140 input_method->input = NULL;
141 input_method->context = NULL;
143 if (wl_list_empty(&text_input->input_methods) &&
144 text_input->input_panel_visible &&
145 text_input->manager->current_text_input == text_input) {
146 wl_signal_emit(&ec->hide_input_panel_signal, ec);
147 text_input->input_panel_visible = false;
150 if (text_input->manager->current_text_input == text_input)
151 text_input->manager->current_text_input = NULL;
153 zwp_text_input_v1_send_leave(text_input->resource);
157 destroy_text_input(struct wl_resource *resource)
159 struct text_input *text_input = wl_resource_get_user_data(resource);
160 struct input_method *input_method, *next;
162 wl_list_for_each_safe(input_method, next,
163 &text_input->input_methods, link)
164 deactivate_input_method(input_method);
170 text_input_set_surrounding_text(struct wl_client *client,
171 struct wl_resource *resource,
176 struct text_input *text_input = wl_resource_get_user_data(resource);
177 struct input_method *input_method, *next;
179 wl_list_for_each_safe(input_method, next,
180 &text_input->input_methods, link) {
181 if (!input_method->context)
183 zwp_input_method_context_v1_send_surrounding_text(
184 input_method->context->resource, text, cursor, anchor);
189 text_input_activate(struct wl_client *client,
190 struct wl_resource *resource,
191 struct wl_resource *seat,
192 struct wl_resource *surface)
194 struct text_input *text_input = wl_resource_get_user_data(resource);
195 struct weston_seat *weston_seat = wl_resource_get_user_data(seat);
196 struct input_method *input_method;
197 struct weston_compositor *ec = text_input->ec;
198 struct text_input *current;
203 input_method = weston_seat->input_method;
204 if (input_method->input == text_input)
207 if (input_method->input)
208 deactivate_input_method(input_method);
210 input_method->input = text_input;
211 wl_list_insert(&text_input->input_methods, &input_method->link);
212 input_method_init_seat(weston_seat);
214 text_input->surface = wl_resource_get_user_data(surface);
216 input_method_context_create(text_input, input_method);
218 current = text_input->manager->current_text_input;
220 if (current && current != text_input) {
221 current->input_panel_visible = false;
222 wl_signal_emit(&ec->hide_input_panel_signal, ec);
225 if (text_input->input_panel_visible) {
226 wl_signal_emit(&ec->show_input_panel_signal,
227 text_input->surface);
228 wl_signal_emit(&ec->update_input_panel_signal,
229 &text_input->cursor_rectangle);
231 text_input->manager->current_text_input = text_input;
233 zwp_text_input_v1_send_enter(text_input->resource,
234 text_input->surface->resource);
238 text_input_deactivate(struct wl_client *client,
239 struct wl_resource *resource,
240 struct wl_resource *seat)
242 struct weston_seat *weston_seat = wl_resource_get_user_data(seat);
244 if (weston_seat && weston_seat->input_method->input)
245 deactivate_input_method(weston_seat->input_method);
249 text_input_reset(struct wl_client *client,
250 struct wl_resource *resource)
252 struct text_input *text_input = wl_resource_get_user_data(resource);
253 struct input_method *input_method, *next;
255 wl_list_for_each_safe(input_method, next,
256 &text_input->input_methods, link) {
257 if (!input_method->context)
259 zwp_input_method_context_v1_send_reset(
260 input_method->context->resource);
265 text_input_set_cursor_rectangle(struct wl_client *client,
266 struct wl_resource *resource,
272 struct text_input *text_input = wl_resource_get_user_data(resource);
273 struct weston_compositor *ec = text_input->ec;
275 text_input->cursor_rectangle.x1 = x;
276 text_input->cursor_rectangle.y1 = y;
277 text_input->cursor_rectangle.x2 = x + width;
278 text_input->cursor_rectangle.y2 = y + height;
280 wl_signal_emit(&ec->update_input_panel_signal,
281 &text_input->cursor_rectangle);
285 text_input_set_content_type(struct wl_client *client,
286 struct wl_resource *resource,
290 struct text_input *text_input = wl_resource_get_user_data(resource);
291 struct input_method *input_method, *next;
293 wl_list_for_each_safe(input_method, next,
294 &text_input->input_methods, link) {
295 if (!input_method->context)
297 zwp_input_method_context_v1_send_content_type(
298 input_method->context->resource, hint, purpose);
303 text_input_invoke_action(struct wl_client *client,
304 struct wl_resource *resource,
308 struct text_input *text_input = wl_resource_get_user_data(resource);
309 struct input_method *input_method, *next;
311 wl_list_for_each_safe(input_method, next,
312 &text_input->input_methods, link) {
313 if (!input_method->context)
315 zwp_input_method_context_v1_send_invoke_action(
316 input_method->context->resource, button, index);
321 text_input_commit_state(struct wl_client *client,
322 struct wl_resource *resource,
325 struct text_input *text_input = wl_resource_get_user_data(resource);
326 struct input_method *input_method, *next;
328 wl_list_for_each_safe(input_method, next,
329 &text_input->input_methods, link) {
330 if (!input_method->context)
332 zwp_input_method_context_v1_send_commit_state(
333 input_method->context->resource, serial);
338 text_input_show_input_panel(struct wl_client *client,
339 struct wl_resource *resource)
341 struct text_input *text_input = wl_resource_get_user_data(resource);
342 struct weston_compositor *ec = text_input->ec;
344 text_input->input_panel_visible = true;
346 if (!wl_list_empty(&text_input->input_methods) &&
347 text_input == text_input->manager->current_text_input) {
348 wl_signal_emit(&ec->show_input_panel_signal,
349 text_input->surface);
350 wl_signal_emit(&ec->update_input_panel_signal,
351 &text_input->cursor_rectangle);
356 text_input_hide_input_panel(struct wl_client *client,
357 struct wl_resource *resource)
359 struct text_input *text_input = wl_resource_get_user_data(resource);
360 struct weston_compositor *ec = text_input->ec;
362 text_input->input_panel_visible = false;
364 if (!wl_list_empty(&text_input->input_methods) &&
365 text_input == text_input->manager->current_text_input)
366 wl_signal_emit(&ec->hide_input_panel_signal, ec);
370 text_input_set_preferred_language(struct wl_client *client,
371 struct wl_resource *resource,
372 const char *language)
374 struct text_input *text_input = wl_resource_get_user_data(resource);
375 struct input_method *input_method, *next;
377 wl_list_for_each_safe(input_method, next,
378 &text_input->input_methods, link) {
379 if (!input_method->context)
381 zwp_input_method_context_v1_send_preferred_language(
382 input_method->context->resource, language);
386 static const struct zwp_text_input_v1_interface text_input_implementation = {
388 text_input_deactivate,
389 text_input_show_input_panel,
390 text_input_hide_input_panel,
392 text_input_set_surrounding_text,
393 text_input_set_content_type,
394 text_input_set_cursor_rectangle,
395 text_input_set_preferred_language,
396 text_input_commit_state,
397 text_input_invoke_action
400 static void text_input_manager_create_text_input(struct wl_client *client,
401 struct wl_resource *resource,
404 struct text_input_manager *text_input_manager =
405 wl_resource_get_user_data(resource);
406 struct text_input *text_input;
408 text_input = zalloc(sizeof *text_input);
409 if (text_input == NULL)
412 text_input->resource =
413 wl_resource_create(client, &zwp_text_input_v1_interface, 1, id);
414 wl_resource_set_implementation(text_input->resource,
415 &text_input_implementation,
416 text_input, destroy_text_input);
418 text_input->ec = text_input_manager->ec;
419 text_input->manager = text_input_manager;
421 wl_list_init(&text_input->input_methods);
424 static const struct zwp_text_input_manager_v1_interface manager_implementation = {
425 text_input_manager_create_text_input
429 bind_text_input_manager(struct wl_client *client,
434 struct text_input_manager *text_input_manager = data;
435 struct wl_resource *resource;
437 /* No checking for duplicate binding necessary. */
439 wl_resource_create(client,
440 &zwp_text_input_manager_v1_interface, 1, id);
442 wl_resource_set_implementation(resource,
443 &manager_implementation,
444 text_input_manager, NULL);
448 text_input_manager_notifier_destroy(struct wl_listener *listener, void *data)
450 struct text_input_manager *text_input_manager =
451 container_of(listener,
452 struct text_input_manager,
455 wl_global_destroy(text_input_manager->text_input_manager_global);
457 free(text_input_manager);
461 text_input_manager_create(struct weston_compositor *ec)
463 struct text_input_manager *text_input_manager;
465 text_input_manager = zalloc(sizeof *text_input_manager);
466 if (text_input_manager == NULL)
469 text_input_manager->ec = ec;
471 text_input_manager->text_input_manager_global =
472 wl_global_create(ec->wl_display,
473 &zwp_text_input_manager_v1_interface, 1,
474 text_input_manager, bind_text_input_manager);
476 text_input_manager->destroy_listener.notify =
477 text_input_manager_notifier_destroy;
478 wl_signal_add(&ec->destroy_signal,
479 &text_input_manager->destroy_listener);
483 input_method_context_destroy(struct wl_client *client,
484 struct wl_resource *resource)
486 wl_resource_destroy(resource);
490 input_method_context_commit_string(struct wl_client *client,
491 struct wl_resource *resource,
495 struct input_method_context *context =
496 wl_resource_get_user_data(resource);
499 zwp_text_input_v1_send_commit_string(context->input->resource,
504 input_method_context_preedit_string(struct wl_client *client,
505 struct wl_resource *resource,
510 struct input_method_context *context =
511 wl_resource_get_user_data(resource);
514 zwp_text_input_v1_send_preedit_string(context->input->resource,
515 serial, text, commit);
519 input_method_context_preedit_styling(struct wl_client *client,
520 struct wl_resource *resource,
525 struct input_method_context *context =
526 wl_resource_get_user_data(resource);
529 zwp_text_input_v1_send_preedit_styling(context->input->resource,
530 index, length, style);
534 input_method_context_preedit_cursor(struct wl_client *client,
535 struct wl_resource *resource,
538 struct input_method_context *context =
539 wl_resource_get_user_data(resource);
542 zwp_text_input_v1_send_preedit_cursor(context->input->resource,
547 input_method_context_delete_surrounding_text(struct wl_client *client,
548 struct wl_resource *resource,
552 struct input_method_context *context =
553 wl_resource_get_user_data(resource);
556 zwp_text_input_v1_send_delete_surrounding_text(
557 context->input->resource, index, length);
561 input_method_context_cursor_position(struct wl_client *client,
562 struct wl_resource *resource,
566 struct input_method_context *context =
567 wl_resource_get_user_data(resource);
570 zwp_text_input_v1_send_cursor_position(context->input->resource,
575 input_method_context_modifiers_map(struct wl_client *client,
576 struct wl_resource *resource,
577 struct wl_array *map)
579 struct input_method_context *context =
580 wl_resource_get_user_data(resource);
583 zwp_text_input_v1_send_modifiers_map(context->input->resource,
588 input_method_context_keysym(struct wl_client *client,
589 struct wl_resource *resource,
596 struct input_method_context *context =
597 wl_resource_get_user_data(resource);
600 zwp_text_input_v1_send_keysym(context->input->resource,
602 sym, state, modifiers);
606 unbind_keyboard(struct wl_resource *resource)
608 struct input_method_context *context =
609 wl_resource_get_user_data(resource);
611 input_method_context_end_keyboard_grab(context);
612 context->keyboard = NULL;
616 input_method_context_grab_key(struct weston_keyboard_grab *grab,
617 const struct timespec *time, uint32_t key,
620 struct weston_keyboard *keyboard = grab->keyboard;
621 struct wl_display *display;
625 if (!keyboard->input_method_resource)
628 display = wl_client_get_display(
629 wl_resource_get_client(keyboard->input_method_resource));
630 serial = wl_display_next_serial(display);
631 msecs = timespec_to_msec(time);
632 wl_keyboard_send_key(keyboard->input_method_resource,
633 serial, msecs, key, state_w);
637 input_method_context_grab_modifier(struct weston_keyboard_grab *grab,
639 uint32_t mods_depressed,
640 uint32_t mods_latched,
641 uint32_t mods_locked,
644 struct weston_keyboard *keyboard = grab->keyboard;
646 if (!keyboard->input_method_resource)
649 wl_keyboard_send_modifiers(keyboard->input_method_resource,
650 serial, mods_depressed, mods_latched,
655 input_method_context_grab_cancel(struct weston_keyboard_grab *grab)
657 weston_keyboard_end_grab(grab->keyboard);
660 static const struct weston_keyboard_grab_interface input_method_context_grab = {
661 input_method_context_grab_key,
662 input_method_context_grab_modifier,
663 input_method_context_grab_cancel,
667 input_method_context_grab_keyboard(struct wl_client *client,
668 struct wl_resource *resource,
671 struct input_method_context *context =
672 wl_resource_get_user_data(resource);
673 struct wl_resource *cr;
674 struct weston_seat *seat = context->input_method->seat;
675 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
677 cr = wl_resource_create(client, &wl_keyboard_interface, 1, id);
678 wl_resource_set_implementation(cr, NULL, context, unbind_keyboard);
680 context->keyboard = cr;
682 wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
683 keyboard->xkb_info->keymap_fd,
684 keyboard->xkb_info->keymap_size);
686 if (keyboard->grab != &keyboard->default_grab) {
687 weston_keyboard_end_grab(keyboard);
689 weston_keyboard_start_grab(keyboard, &keyboard->input_method_grab);
690 keyboard->input_method_resource = cr;
694 input_method_context_key(struct wl_client *client,
695 struct wl_resource *resource,
701 struct input_method_context *context =
702 wl_resource_get_user_data(resource);
703 struct weston_seat *seat = context->input_method->seat;
704 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
705 struct weston_keyboard_grab *default_grab = &keyboard->default_grab;
708 timespec_from_msec(&ts, time);
710 default_grab->interface->key(default_grab, &ts, key, state_w);
714 input_method_context_modifiers(struct wl_client *client,
715 struct wl_resource *resource,
717 uint32_t mods_depressed,
718 uint32_t mods_latched,
719 uint32_t mods_locked,
722 struct input_method_context *context =
723 wl_resource_get_user_data(resource);
725 struct weston_seat *seat = context->input_method->seat;
726 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
727 struct weston_keyboard_grab *default_grab = &keyboard->default_grab;
729 default_grab->interface->modifiers(default_grab,
730 serial, mods_depressed,
731 mods_latched, mods_locked,
736 input_method_context_language(struct wl_client *client,
737 struct wl_resource *resource,
739 const char *language)
741 struct input_method_context *context =
742 wl_resource_get_user_data(resource);
745 zwp_text_input_v1_send_language(context->input->resource,
750 input_method_context_text_direction(struct wl_client *client,
751 struct wl_resource *resource,
755 struct input_method_context *context =
756 wl_resource_get_user_data(resource);
759 zwp_text_input_v1_send_text_direction(context->input->resource,
764 static const struct zwp_input_method_context_v1_interface context_implementation = {
765 input_method_context_destroy,
766 input_method_context_commit_string,
767 input_method_context_preedit_string,
768 input_method_context_preedit_styling,
769 input_method_context_preedit_cursor,
770 input_method_context_delete_surrounding_text,
771 input_method_context_cursor_position,
772 input_method_context_modifiers_map,
773 input_method_context_keysym,
774 input_method_context_grab_keyboard,
775 input_method_context_key,
776 input_method_context_modifiers,
777 input_method_context_language,
778 input_method_context_text_direction
782 destroy_input_method_context(struct wl_resource *resource)
784 struct input_method_context *context =
785 wl_resource_get_user_data(resource);
787 if (context->keyboard)
788 wl_resource_destroy(context->keyboard);
790 if (context->input_method && context->input_method->context == context)
791 context->input_method->context = NULL;
797 input_method_context_create(struct text_input *input,
798 struct input_method *input_method)
800 struct input_method_context *context;
801 struct wl_resource *binding;
803 if (!input_method->input_method_binding)
806 context = zalloc(sizeof *context);
810 binding = input_method->input_method_binding;
812 wl_resource_create(wl_resource_get_client(binding),
813 &zwp_input_method_context_v1_interface,
815 wl_resource_set_implementation(context->resource,
816 &context_implementation,
817 context, destroy_input_method_context);
819 context->input = input;
820 context->input_method = input_method;
821 input_method->context = context;
824 zwp_input_method_v1_send_activate(binding, context->resource);
828 input_method_context_end_keyboard_grab(struct input_method_context *context)
830 struct weston_keyboard_grab *grab;
831 struct weston_keyboard *keyboard;
833 keyboard = weston_seat_get_keyboard(context->input_method->seat);
837 grab = &keyboard->input_method_grab;
838 keyboard = grab->keyboard;
842 if (keyboard->grab == grab)
843 weston_keyboard_end_grab(keyboard);
845 keyboard->input_method_resource = NULL;
849 unbind_input_method(struct wl_resource *resource)
851 struct input_method *input_method = wl_resource_get_user_data(resource);
853 input_method->input_method_binding = NULL;
854 input_method->context = NULL;
858 bind_input_method(struct wl_client *client,
863 struct input_method *input_method = data;
864 struct text_backend *text_backend = input_method->text_backend;
865 struct wl_resource *resource;
868 wl_resource_create(client,
869 &zwp_input_method_v1_interface, 1, id);
871 if (input_method->input_method_binding != NULL) {
872 wl_resource_post_error(resource,
873 WL_DISPLAY_ERROR_INVALID_OBJECT,
874 "interface object already bound");
878 if (text_backend->input_method.client != client) {
879 wl_resource_post_error(resource,
880 WL_DISPLAY_ERROR_INVALID_OBJECT,
881 "permission to bind "
882 "input_method denied");
886 wl_resource_set_implementation(resource, NULL, input_method,
887 unbind_input_method);
888 input_method->input_method_binding = resource;
892 input_method_notifier_destroy(struct wl_listener *listener, void *data)
894 struct input_method *input_method =
895 container_of(listener, struct input_method, destroy_listener);
897 if (input_method->input)
898 deactivate_input_method(input_method);
900 wl_global_destroy(input_method->input_method_global);
901 wl_list_remove(&input_method->destroy_listener.link);
907 handle_keyboard_focus(struct wl_listener *listener, void *data)
909 struct weston_keyboard *keyboard = data;
910 struct input_method *input_method =
911 container_of(listener, struct input_method,
912 keyboard_focus_listener);
913 struct weston_surface *surface = keyboard->focus;
915 if (!input_method->input)
918 if (!surface || input_method->input->surface != surface)
919 deactivate_input_method(input_method);
923 input_method_init_seat(struct weston_seat *seat)
925 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
927 if (seat->input_method->focus_listener_initialized)
931 seat->input_method->keyboard_focus_listener.notify =
932 handle_keyboard_focus;
933 wl_signal_add(&keyboard->focus_signal,
934 &seat->input_method->keyboard_focus_listener);
935 keyboard->input_method_grab.interface =
936 &input_method_context_grab;
939 seat->input_method->focus_listener_initialized = true;
942 static void launch_input_method(struct text_backend *text_backend);
945 respawn_input_method_process(struct text_backend *text_backend)
947 struct timespec time;
950 /* if input_method dies more than 5 times in 10 seconds, give up */
951 weston_compositor_get_time(&time);
952 tdiff = timespec_sub_to_msec(&time,
953 &text_backend->input_method.deathstamp);
955 text_backend->input_method.deathstamp = time;
956 text_backend->input_method.deathcount = 0;
959 text_backend->input_method.deathcount++;
960 if (text_backend->input_method.deathcount > 5) {
961 weston_log("input_method disconnected, giving up.\n");
965 weston_log("input_method disconnected, respawning...\n");
966 launch_input_method(text_backend);
970 input_method_client_notifier(struct wl_listener *listener, void *data)
972 struct text_backend *text_backend;
974 text_backend = container_of(listener, struct text_backend,
977 text_backend->input_method.client = NULL;
978 respawn_input_method_process(text_backend);
982 launch_input_method(struct text_backend *text_backend)
984 if (!text_backend->input_method.path)
987 if (strcmp(text_backend->input_method.path, "") == 0)
990 text_backend->input_method.client =
991 weston_client_start(text_backend->compositor,
992 text_backend->input_method.path);
994 if (!text_backend->input_method.client) {
995 weston_log("not able to start %s\n",
996 text_backend->input_method.path);
1000 text_backend->client_listener.notify = input_method_client_notifier;
1001 wl_client_add_destroy_listener(text_backend->input_method.client,
1002 &text_backend->client_listener);
1006 text_backend_seat_created(struct text_backend *text_backend,
1007 struct weston_seat *seat)
1009 struct input_method *input_method;
1010 struct weston_compositor *ec = seat->compositor;
1012 input_method = zalloc(sizeof *input_method);
1013 if (input_method == NULL)
1016 input_method->seat = seat;
1017 input_method->input = NULL;
1018 input_method->focus_listener_initialized = false;
1019 input_method->context = NULL;
1020 input_method->text_backend = text_backend;
1022 input_method->input_method_global =
1023 wl_global_create(ec->wl_display,
1024 &zwp_input_method_v1_interface, 1,
1025 input_method, bind_input_method);
1027 input_method->destroy_listener.notify = input_method_notifier_destroy;
1028 wl_signal_add(&seat->destroy_signal, &input_method->destroy_listener);
1030 seat->input_method = input_method;
1034 handle_seat_created(struct wl_listener *listener, void *data)
1036 struct weston_seat *seat = data;
1037 struct text_backend *text_backend =
1038 container_of(listener, struct text_backend,
1039 seat_created_listener);
1041 text_backend_seat_created(text_backend, seat);
1045 text_backend_configuration(struct text_backend *text_backend)
1047 struct weston_config *config = wet_get_config(text_backend->compositor);
1048 struct weston_config_section *section;
1052 section = weston_config_get_section(config,
1053 "input-method", NULL, NULL);
1054 ret = asprintf(&client, "%s/weston-keyboard",
1055 weston_config_get_libexec_dir());
1058 weston_config_section_get_string(section, "path",
1059 &text_backend->input_method.path,
1065 text_backend_destroy(struct text_backend *text_backend)
1067 if (text_backend->input_method.client) {
1068 /* disable respawn */
1069 wl_list_remove(&text_backend->client_listener.link);
1070 wl_client_destroy(text_backend->input_method.client);
1073 free(text_backend->input_method.path);
1077 WL_EXPORT struct text_backend *
1078 text_backend_init(struct weston_compositor *ec)
1080 struct text_backend *text_backend;
1081 struct weston_seat *seat;
1083 text_backend = zalloc(sizeof(*text_backend));
1084 if (text_backend == NULL)
1087 text_backend->compositor = ec;
1089 text_backend_configuration(text_backend);
1091 wl_list_for_each(seat, &ec->seat_list, link)
1092 text_backend_seat_created(text_backend, seat);
1093 text_backend->seat_created_listener.notify = handle_seat_created;
1094 wl_signal_add(&ec->seat_created_signal,
1095 &text_backend->seat_created_listener);
1097 text_input_manager_create(ec);
1099 launch_input_method(text_backend);
1101 return text_backend;