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"
42 struct text_input_manager;
44 struct input_method_context;
48 struct wl_resource *resource;
50 struct weston_compositor *ec;
52 struct wl_list input_methods;
54 struct weston_surface *surface;
56 pixman_box32_t cursor_rectangle;
58 bool input_panel_visible;
60 struct text_input_manager *manager;
63 struct text_input_manager {
64 struct wl_global *text_input_manager_global;
65 struct wl_listener destroy_listener;
67 struct text_input *current_panel;
69 struct weston_compositor *ec;
73 struct wl_resource *input_method_binding;
74 struct wl_global *input_method_global;
75 struct wl_listener destroy_listener;
77 struct weston_seat *seat;
78 struct text_input *input;
82 struct wl_listener keyboard_focus_listener;
84 bool focus_listener_initialized;
86 struct input_method_context *context;
88 struct text_backend *text_backend;
91 struct input_method_context {
92 struct wl_resource *resource;
94 struct text_input *input;
95 struct input_method *input_method;
97 struct wl_resource *keyboard;
100 struct text_backend {
101 struct weston_compositor *compositor;
105 struct wl_client *client;
111 struct wl_listener client_listener;
112 struct wl_listener seat_created_listener;
116 input_method_context_create(struct text_input *input,
117 struct input_method *input_method);
119 input_method_context_end_keyboard_grab(struct input_method_context *context);
122 input_method_init_seat(struct weston_seat *seat);
125 deactivate_input_method(struct input_method *input_method)
127 struct text_input *text_input = input_method->input;
128 struct weston_compositor *ec = text_input->ec;
130 if (input_method->context && input_method->input_method_binding) {
131 input_method_context_end_keyboard_grab(input_method->context);
132 zwp_input_method_v1_send_deactivate(
133 input_method->input_method_binding,
134 input_method->context->resource);
135 input_method->context->input = NULL;
138 wl_list_remove(&input_method->link);
139 input_method->input = NULL;
140 input_method->context = NULL;
142 if (wl_list_empty(&text_input->input_methods) &&
143 text_input->input_panel_visible) {
144 wl_signal_emit(&ec->hide_input_panel_signal, ec);
145 text_input->input_panel_visible = false;
146 text_input->manager->current_panel = NULL;
148 zwp_text_input_v1_send_leave(text_input->resource);
152 destroy_text_input(struct wl_resource *resource)
154 struct text_input *text_input = wl_resource_get_user_data(resource);
155 struct input_method *input_method, *next;
157 wl_list_for_each_safe(input_method, next,
158 &text_input->input_methods, link)
159 deactivate_input_method(input_method);
165 text_input_set_surrounding_text(struct wl_client *client,
166 struct wl_resource *resource,
171 struct text_input *text_input = wl_resource_get_user_data(resource);
172 struct input_method *input_method, *next;
174 wl_list_for_each_safe(input_method, next,
175 &text_input->input_methods, link) {
176 if (!input_method->context)
178 zwp_input_method_context_v1_send_surrounding_text(
179 input_method->context->resource, text, cursor, anchor);
184 text_input_activate(struct wl_client *client,
185 struct wl_resource *resource,
186 struct wl_resource *seat,
187 struct wl_resource *surface)
189 struct text_input *text_input = wl_resource_get_user_data(resource);
190 struct weston_seat *weston_seat = wl_resource_get_user_data(seat);
191 struct input_method *input_method = weston_seat->input_method;
192 struct weston_compositor *ec = text_input->ec;
193 struct text_input *current;
195 if (input_method->input == text_input)
198 if (input_method->input)
199 deactivate_input_method(input_method);
201 input_method->input = text_input;
202 wl_list_insert(&text_input->input_methods, &input_method->link);
203 input_method_init_seat(weston_seat);
205 text_input->surface = wl_resource_get_user_data(surface);
207 input_method_context_create(text_input, input_method);
209 current = text_input->manager->current_panel;
211 if (current && current != text_input) {
212 current->input_panel_visible = false;
213 wl_signal_emit(&ec->hide_input_panel_signal, ec);
214 text_input->manager->current_panel = NULL;
217 if (text_input->input_panel_visible) {
218 wl_signal_emit(&ec->show_input_panel_signal,
219 text_input->surface);
220 wl_signal_emit(&ec->update_input_panel_signal,
221 &text_input->cursor_rectangle);
222 text_input->manager->current_panel = text_input;
225 zwp_text_input_v1_send_enter(text_input->resource,
226 text_input->surface->resource);
230 text_input_deactivate(struct wl_client *client,
231 struct wl_resource *resource,
232 struct wl_resource *seat)
234 struct weston_seat *weston_seat = wl_resource_get_user_data(seat);
236 if (weston_seat->input_method->input)
237 deactivate_input_method(weston_seat->input_method);
241 text_input_reset(struct wl_client *client,
242 struct wl_resource *resource)
244 struct text_input *text_input = wl_resource_get_user_data(resource);
245 struct input_method *input_method, *next;
247 wl_list_for_each_safe(input_method, next,
248 &text_input->input_methods, link) {
249 if (!input_method->context)
251 zwp_input_method_context_v1_send_reset(
252 input_method->context->resource);
257 text_input_set_cursor_rectangle(struct wl_client *client,
258 struct wl_resource *resource,
264 struct text_input *text_input = wl_resource_get_user_data(resource);
265 struct weston_compositor *ec = text_input->ec;
267 text_input->cursor_rectangle.x1 = x;
268 text_input->cursor_rectangle.y1 = y;
269 text_input->cursor_rectangle.x2 = x + width;
270 text_input->cursor_rectangle.y2 = y + height;
272 wl_signal_emit(&ec->update_input_panel_signal,
273 &text_input->cursor_rectangle);
277 text_input_set_content_type(struct wl_client *client,
278 struct wl_resource *resource,
282 struct text_input *text_input = wl_resource_get_user_data(resource);
283 struct input_method *input_method, *next;
285 wl_list_for_each_safe(input_method, next,
286 &text_input->input_methods, link) {
287 if (!input_method->context)
289 zwp_input_method_context_v1_send_content_type(
290 input_method->context->resource, hint, purpose);
295 text_input_invoke_action(struct wl_client *client,
296 struct wl_resource *resource,
300 struct text_input *text_input = wl_resource_get_user_data(resource);
301 struct input_method *input_method, *next;
303 wl_list_for_each_safe(input_method, next,
304 &text_input->input_methods, link) {
305 if (!input_method->context)
307 zwp_input_method_context_v1_send_invoke_action(
308 input_method->context->resource, button, index);
313 text_input_commit_state(struct wl_client *client,
314 struct wl_resource *resource,
317 struct text_input *text_input = wl_resource_get_user_data(resource);
318 struct input_method *input_method, *next;
320 wl_list_for_each_safe(input_method, next,
321 &text_input->input_methods, link) {
322 if (!input_method->context)
324 zwp_input_method_context_v1_send_commit_state(
325 input_method->context->resource, serial);
330 text_input_show_input_panel(struct wl_client *client,
331 struct wl_resource *resource)
333 struct text_input *text_input = wl_resource_get_user_data(resource);
334 struct weston_compositor *ec = text_input->ec;
336 text_input->input_panel_visible = true;
338 if (!wl_list_empty(&text_input->input_methods)) {
339 wl_signal_emit(&ec->show_input_panel_signal,
340 text_input->surface);
341 wl_signal_emit(&ec->update_input_panel_signal,
342 &text_input->cursor_rectangle);
347 text_input_hide_input_panel(struct wl_client *client,
348 struct wl_resource *resource)
350 struct text_input *text_input = wl_resource_get_user_data(resource);
351 struct weston_compositor *ec = text_input->ec;
353 text_input->input_panel_visible = false;
355 if (!wl_list_empty(&text_input->input_methods) &&
356 text_input == text_input->manager->current_panel) {
357 text_input->manager->current_panel = NULL;
358 wl_signal_emit(&ec->hide_input_panel_signal, ec);
363 text_input_set_preferred_language(struct wl_client *client,
364 struct wl_resource *resource,
365 const char *language)
367 struct text_input *text_input = wl_resource_get_user_data(resource);
368 struct input_method *input_method, *next;
370 wl_list_for_each_safe(input_method, next,
371 &text_input->input_methods, link) {
372 if (!input_method->context)
374 zwp_input_method_context_v1_send_preferred_language(
375 input_method->context->resource, language);
379 static const struct zwp_text_input_v1_interface text_input_implementation = {
381 text_input_deactivate,
382 text_input_show_input_panel,
383 text_input_hide_input_panel,
385 text_input_set_surrounding_text,
386 text_input_set_content_type,
387 text_input_set_cursor_rectangle,
388 text_input_set_preferred_language,
389 text_input_commit_state,
390 text_input_invoke_action
393 static void text_input_manager_create_text_input(struct wl_client *client,
394 struct wl_resource *resource,
397 struct text_input_manager *text_input_manager =
398 wl_resource_get_user_data(resource);
399 struct text_input *text_input;
401 text_input = zalloc(sizeof *text_input);
402 if (text_input == NULL)
405 text_input->resource =
406 wl_resource_create(client, &zwp_text_input_v1_interface, 1, id);
407 wl_resource_set_implementation(text_input->resource,
408 &text_input_implementation,
409 text_input, destroy_text_input);
411 text_input->ec = text_input_manager->ec;
412 text_input->manager = text_input_manager;
414 wl_list_init(&text_input->input_methods);
417 static const struct zwp_text_input_manager_v1_interface manager_implementation = {
418 text_input_manager_create_text_input
422 bind_text_input_manager(struct wl_client *client,
427 struct text_input_manager *text_input_manager = data;
428 struct wl_resource *resource;
430 /* No checking for duplicate binding necessary. */
432 wl_resource_create(client,
433 &zwp_text_input_manager_v1_interface, 1, id);
435 wl_resource_set_implementation(resource,
436 &manager_implementation,
437 text_input_manager, NULL);
441 text_input_manager_notifier_destroy(struct wl_listener *listener, void *data)
443 struct text_input_manager *text_input_manager =
444 container_of(listener,
445 struct text_input_manager,
448 wl_global_destroy(text_input_manager->text_input_manager_global);
450 free(text_input_manager);
454 text_input_manager_create(struct weston_compositor *ec)
456 struct text_input_manager *text_input_manager;
458 text_input_manager = zalloc(sizeof *text_input_manager);
459 if (text_input_manager == NULL)
462 text_input_manager->ec = ec;
464 text_input_manager->text_input_manager_global =
465 wl_global_create(ec->wl_display,
466 &zwp_text_input_manager_v1_interface, 1,
467 text_input_manager, bind_text_input_manager);
469 text_input_manager->destroy_listener.notify =
470 text_input_manager_notifier_destroy;
471 wl_signal_add(&ec->destroy_signal,
472 &text_input_manager->destroy_listener);
476 input_method_context_destroy(struct wl_client *client,
477 struct wl_resource *resource)
479 wl_resource_destroy(resource);
483 input_method_context_commit_string(struct wl_client *client,
484 struct wl_resource *resource,
488 struct input_method_context *context =
489 wl_resource_get_user_data(resource);
492 zwp_text_input_v1_send_commit_string(context->input->resource,
497 input_method_context_preedit_string(struct wl_client *client,
498 struct wl_resource *resource,
503 struct input_method_context *context =
504 wl_resource_get_user_data(resource);
507 zwp_text_input_v1_send_preedit_string(context->input->resource,
508 serial, text, commit);
512 input_method_context_preedit_styling(struct wl_client *client,
513 struct wl_resource *resource,
518 struct input_method_context *context =
519 wl_resource_get_user_data(resource);
522 zwp_text_input_v1_send_preedit_styling(context->input->resource,
523 index, length, style);
527 input_method_context_preedit_cursor(struct wl_client *client,
528 struct wl_resource *resource,
531 struct input_method_context *context =
532 wl_resource_get_user_data(resource);
535 zwp_text_input_v1_send_preedit_cursor(context->input->resource,
540 input_method_context_delete_surrounding_text(struct wl_client *client,
541 struct wl_resource *resource,
545 struct input_method_context *context =
546 wl_resource_get_user_data(resource);
549 zwp_text_input_v1_send_delete_surrounding_text(
550 context->input->resource, index, length);
554 input_method_context_cursor_position(struct wl_client *client,
555 struct wl_resource *resource,
559 struct input_method_context *context =
560 wl_resource_get_user_data(resource);
563 zwp_text_input_v1_send_cursor_position(context->input->resource,
568 input_method_context_modifiers_map(struct wl_client *client,
569 struct wl_resource *resource,
570 struct wl_array *map)
572 struct input_method_context *context =
573 wl_resource_get_user_data(resource);
576 zwp_text_input_v1_send_modifiers_map(context->input->resource,
581 input_method_context_keysym(struct wl_client *client,
582 struct wl_resource *resource,
589 struct input_method_context *context =
590 wl_resource_get_user_data(resource);
593 zwp_text_input_v1_send_keysym(context->input->resource,
595 sym, state, modifiers);
599 unbind_keyboard(struct wl_resource *resource)
601 struct input_method_context *context =
602 wl_resource_get_user_data(resource);
604 input_method_context_end_keyboard_grab(context);
605 context->keyboard = NULL;
609 input_method_context_grab_key(struct weston_keyboard_grab *grab,
610 uint32_t time, uint32_t key, uint32_t state_w)
612 struct weston_keyboard *keyboard = grab->keyboard;
613 struct wl_display *display;
616 if (!keyboard->input_method_resource)
619 display = wl_client_get_display(
620 wl_resource_get_client(keyboard->input_method_resource));
621 serial = wl_display_next_serial(display);
622 wl_keyboard_send_key(keyboard->input_method_resource,
623 serial, time, key, state_w);
627 input_method_context_grab_modifier(struct weston_keyboard_grab *grab,
629 uint32_t mods_depressed,
630 uint32_t mods_latched,
631 uint32_t mods_locked,
634 struct weston_keyboard *keyboard = grab->keyboard;
636 if (!keyboard->input_method_resource)
639 wl_keyboard_send_modifiers(keyboard->input_method_resource,
640 serial, mods_depressed, mods_latched,
645 input_method_context_grab_cancel(struct weston_keyboard_grab *grab)
647 weston_keyboard_end_grab(grab->keyboard);
650 static const struct weston_keyboard_grab_interface input_method_context_grab = {
651 input_method_context_grab_key,
652 input_method_context_grab_modifier,
653 input_method_context_grab_cancel,
657 input_method_context_grab_keyboard(struct wl_client *client,
658 struct wl_resource *resource,
661 struct input_method_context *context =
662 wl_resource_get_user_data(resource);
663 struct wl_resource *cr;
664 struct weston_seat *seat = context->input_method->seat;
665 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
667 cr = wl_resource_create(client, &wl_keyboard_interface, 1, id);
668 wl_resource_set_implementation(cr, NULL, context, unbind_keyboard);
670 context->keyboard = cr;
672 wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
673 keyboard->xkb_info->keymap_fd,
674 keyboard->xkb_info->keymap_size);
676 if (keyboard->grab != &keyboard->default_grab) {
677 weston_keyboard_end_grab(keyboard);
679 weston_keyboard_start_grab(keyboard, &keyboard->input_method_grab);
680 keyboard->input_method_resource = cr;
684 input_method_context_key(struct wl_client *client,
685 struct wl_resource *resource,
691 struct input_method_context *context =
692 wl_resource_get_user_data(resource);
693 struct weston_seat *seat = context->input_method->seat;
694 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
695 struct weston_keyboard_grab *default_grab = &keyboard->default_grab;
697 default_grab->interface->key(default_grab, time, key, state_w);
701 input_method_context_modifiers(struct wl_client *client,
702 struct wl_resource *resource,
704 uint32_t mods_depressed,
705 uint32_t mods_latched,
706 uint32_t mods_locked,
709 struct input_method_context *context =
710 wl_resource_get_user_data(resource);
712 struct weston_seat *seat = context->input_method->seat;
713 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
714 struct weston_keyboard_grab *default_grab = &keyboard->default_grab;
716 default_grab->interface->modifiers(default_grab,
717 serial, mods_depressed,
718 mods_latched, mods_locked,
723 input_method_context_language(struct wl_client *client,
724 struct wl_resource *resource,
726 const char *language)
728 struct input_method_context *context =
729 wl_resource_get_user_data(resource);
732 zwp_text_input_v1_send_language(context->input->resource,
737 input_method_context_text_direction(struct wl_client *client,
738 struct wl_resource *resource,
742 struct input_method_context *context =
743 wl_resource_get_user_data(resource);
746 zwp_text_input_v1_send_text_direction(context->input->resource,
751 static const struct zwp_input_method_context_v1_interface context_implementation = {
752 input_method_context_destroy,
753 input_method_context_commit_string,
754 input_method_context_preedit_string,
755 input_method_context_preedit_styling,
756 input_method_context_preedit_cursor,
757 input_method_context_delete_surrounding_text,
758 input_method_context_cursor_position,
759 input_method_context_modifiers_map,
760 input_method_context_keysym,
761 input_method_context_grab_keyboard,
762 input_method_context_key,
763 input_method_context_modifiers,
764 input_method_context_language,
765 input_method_context_text_direction
769 destroy_input_method_context(struct wl_resource *resource)
771 struct input_method_context *context =
772 wl_resource_get_user_data(resource);
774 if (context->keyboard)
775 wl_resource_destroy(context->keyboard);
777 if (context->input_method && context->input_method->context == context)
778 context->input_method->context = NULL;
784 input_method_context_create(struct text_input *input,
785 struct input_method *input_method)
787 struct input_method_context *context;
788 struct wl_resource *binding;
790 if (!input_method->input_method_binding)
793 context = zalloc(sizeof *context);
797 binding = input_method->input_method_binding;
799 wl_resource_create(wl_resource_get_client(binding),
800 &zwp_input_method_context_v1_interface,
802 wl_resource_set_implementation(context->resource,
803 &context_implementation,
804 context, destroy_input_method_context);
806 context->input = input;
807 context->input_method = input_method;
808 input_method->context = context;
811 zwp_input_method_v1_send_activate(binding, context->resource);
815 input_method_context_end_keyboard_grab(struct input_method_context *context)
817 struct weston_keyboard_grab *grab;
818 struct weston_keyboard *keyboard;
820 keyboard = weston_seat_get_keyboard(context->input_method->seat);
824 grab = &keyboard->input_method_grab;
825 keyboard = grab->keyboard;
829 if (keyboard->grab == grab)
830 weston_keyboard_end_grab(keyboard);
832 keyboard->input_method_resource = NULL;
836 unbind_input_method(struct wl_resource *resource)
838 struct input_method *input_method = wl_resource_get_user_data(resource);
840 input_method->input_method_binding = NULL;
841 input_method->context = NULL;
845 bind_input_method(struct wl_client *client,
850 struct input_method *input_method = data;
851 struct text_backend *text_backend = input_method->text_backend;
852 struct wl_resource *resource;
855 wl_resource_create(client,
856 &zwp_input_method_v1_interface, 1, id);
858 if (input_method->input_method_binding != NULL) {
859 wl_resource_post_error(resource,
860 WL_DISPLAY_ERROR_INVALID_OBJECT,
861 "interface object already bound");
865 if (text_backend->input_method.client != client) {
866 wl_resource_post_error(resource,
867 WL_DISPLAY_ERROR_INVALID_OBJECT,
868 "permission to bind "
869 "input_method denied");
873 wl_resource_set_implementation(resource, NULL, input_method,
874 unbind_input_method);
875 input_method->input_method_binding = resource;
879 input_method_notifier_destroy(struct wl_listener *listener, void *data)
881 struct input_method *input_method =
882 container_of(listener, struct input_method, destroy_listener);
884 if (input_method->input)
885 deactivate_input_method(input_method);
887 wl_global_destroy(input_method->input_method_global);
888 wl_list_remove(&input_method->destroy_listener.link);
894 handle_keyboard_focus(struct wl_listener *listener, void *data)
896 struct weston_keyboard *keyboard = data;
897 struct input_method *input_method =
898 container_of(listener, struct input_method,
899 keyboard_focus_listener);
900 struct weston_surface *surface = keyboard->focus;
902 if (!input_method->input)
905 if (!surface || input_method->input->surface != surface)
906 deactivate_input_method(input_method);
910 input_method_init_seat(struct weston_seat *seat)
912 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
914 if (seat->input_method->focus_listener_initialized)
918 seat->input_method->keyboard_focus_listener.notify =
919 handle_keyboard_focus;
920 wl_signal_add(&keyboard->focus_signal,
921 &seat->input_method->keyboard_focus_listener);
922 keyboard->input_method_grab.interface =
923 &input_method_context_grab;
926 seat->input_method->focus_listener_initialized = true;
929 static void launch_input_method(struct text_backend *text_backend);
932 respawn_input_method_process(struct text_backend *text_backend)
936 /* if input_method dies more than 5 times in 10 seconds, give up */
937 time = weston_compositor_get_time();
938 if (time - text_backend->input_method.deathstamp > 10000) {
939 text_backend->input_method.deathstamp = time;
940 text_backend->input_method.deathcount = 0;
943 text_backend->input_method.deathcount++;
944 if (text_backend->input_method.deathcount > 5) {
945 weston_log("input_method disconnected, giving up.\n");
949 weston_log("input_method disconnected, respawning...\n");
950 launch_input_method(text_backend);
954 input_method_client_notifier(struct wl_listener *listener, void *data)
956 struct text_backend *text_backend;
958 text_backend = container_of(listener, struct text_backend,
961 text_backend->input_method.client = NULL;
962 respawn_input_method_process(text_backend);
966 launch_input_method(struct text_backend *text_backend)
968 if (!text_backend->input_method.path)
971 if (strcmp(text_backend->input_method.path, "") == 0)
974 text_backend->input_method.client =
975 weston_client_start(text_backend->compositor,
976 text_backend->input_method.path);
978 if (!text_backend->input_method.client) {
979 weston_log("not able to start %s\n",
980 text_backend->input_method.path);
984 text_backend->client_listener.notify = input_method_client_notifier;
985 wl_client_add_destroy_listener(text_backend->input_method.client,
986 &text_backend->client_listener);
990 text_backend_seat_created(struct text_backend *text_backend,
991 struct weston_seat *seat)
993 struct input_method *input_method;
994 struct weston_compositor *ec = seat->compositor;
996 input_method = zalloc(sizeof *input_method);
997 if (input_method == NULL)
1000 input_method->seat = seat;
1001 input_method->input = NULL;
1002 input_method->focus_listener_initialized = false;
1003 input_method->context = NULL;
1004 input_method->text_backend = text_backend;
1006 input_method->input_method_global =
1007 wl_global_create(ec->wl_display,
1008 &zwp_input_method_v1_interface, 1,
1009 input_method, bind_input_method);
1011 input_method->destroy_listener.notify = input_method_notifier_destroy;
1012 wl_signal_add(&seat->destroy_signal, &input_method->destroy_listener);
1014 seat->input_method = input_method;
1018 handle_seat_created(struct wl_listener *listener, void *data)
1020 struct weston_seat *seat = data;
1021 struct text_backend *text_backend =
1022 container_of(listener, struct text_backend,
1023 seat_created_listener);
1025 text_backend_seat_created(text_backend, seat);
1029 text_backend_configuration(struct text_backend *text_backend)
1031 struct weston_config *config = wet_get_config(text_backend->compositor);
1032 struct weston_config_section *section;
1036 section = weston_config_get_section(config,
1037 "input-method", NULL, NULL);
1038 ret = asprintf(&client, "%s/weston-keyboard",
1039 weston_config_get_libexec_dir());
1042 weston_config_section_get_string(section, "path",
1043 &text_backend->input_method.path,
1049 text_backend_destroy(struct text_backend *text_backend)
1051 if (text_backend->input_method.client) {
1052 /* disable respawn */
1053 wl_list_remove(&text_backend->client_listener.link);
1054 wl_client_destroy(text_backend->input_method.client);
1057 free(text_backend->input_method.path);
1061 WL_EXPORT struct text_backend *
1062 text_backend_init(struct weston_compositor *ec)
1064 struct text_backend *text_backend;
1065 struct weston_seat *seat;
1067 text_backend = zalloc(sizeof(*text_backend));
1068 if (text_backend == NULL)
1071 text_backend->compositor = ec;
1073 text_backend_configuration(text_backend);
1075 wl_list_for_each(seat, &ec->seat_list, link)
1076 text_backend_seat_created(text_backend, seat);
1077 text_backend->seat_created_listener.notify = handle_seat_created;
1078 wl_signal_add(&ec->seat_created_signal,
1079 &text_backend->seat_created_listener);
1081 text_input_manager_create(ec);
1083 launch_input_method(text_backend);
1085 return text_backend;