compositor: quick fix for sub-surface mapping
[profile/ivi/weston-ivi-shell.git] / src / text-backend.c
1 /*
2  * Copyright © 2012 Openismus GmbH
3  * Copyright © 2012 Intel Corporation
4  *
5  * Permission to use, copy, modify, distribute, and sell this software and
6  * its documentation for any purpose is hereby granted without fee, provided
7  * that the above copyright notice appear in all copies and that both that
8  * copyright notice and this permission notice appear in supporting
9  * documentation, and that the name of the copyright holders not be used in
10  * advertising or publicity pertaining to distribution of the software
11  * without specific, written prior permission.  The copyright holders make
12  * no representations about the suitability of this software for any
13  * purpose.  It is provided "as is" without express or implied warranty.
14  *
15  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
16  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
18  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
19  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
20  * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22  */
23
24 #include "config.h"
25
26 #include <stdlib.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <time.h>
30
31 #include "compositor.h"
32 #include "text-server-protocol.h"
33 #include "input-method-server-protocol.h"
34
35 struct input_method;
36 struct input_method_context;
37 struct text_backend;
38
39 struct text_input {
40         struct wl_resource *resource;
41
42         struct weston_compositor *ec;
43
44         struct wl_list input_methods;
45
46         struct weston_surface *surface;
47
48         pixman_box32_t cursor_rectangle;
49
50         uint32_t input_panel_visible;
51 };
52
53 struct text_input_manager {
54         struct wl_global *text_input_manager_global;
55         struct wl_listener destroy_listener;
56
57         struct weston_compositor *ec;
58 };
59
60 struct input_method {
61         struct wl_resource *input_method_binding;
62         struct wl_global *input_method_global;
63         struct wl_listener destroy_listener;
64
65         struct weston_seat *seat;
66         struct text_input *model;
67
68         struct wl_list link;
69
70         struct wl_listener keyboard_focus_listener;
71
72         int focus_listener_initialized;
73
74         struct input_method_context *context;
75
76         struct text_backend *text_backend;
77 };
78
79 struct input_method_context {
80         struct wl_resource *resource;
81
82         struct text_input *model;
83         struct input_method *input_method;
84
85         struct wl_list link;
86
87         struct wl_resource *keyboard;
88 };
89
90 struct text_backend {
91         struct weston_compositor *compositor;
92
93         struct {
94                 char *path;
95                 struct wl_resource *binding;
96                 struct weston_process process;
97                 struct wl_client *client;
98
99                 unsigned deathcount;
100                 uint32_t deathstamp;
101         } input_method;
102
103         struct wl_listener seat_created_listener;
104         struct wl_listener destroy_listener;
105 };
106
107 static void input_method_context_create(struct text_input *model,
108                                         struct input_method *input_method);
109 static void input_method_context_end_keyboard_grab(struct input_method_context *context);
110
111 static void input_method_init_seat(struct weston_seat *seat);
112
113 static void
114 deactivate_text_input(struct text_input *text_input,
115                       struct input_method *input_method)
116 {
117         struct weston_compositor *ec = text_input->ec;
118
119         if (input_method->model == text_input) {
120                 if (input_method->context && input_method->input_method_binding) {
121                         input_method_context_end_keyboard_grab(input_method->context);
122                         wl_input_method_send_deactivate(input_method->input_method_binding,
123                                                         input_method->context->resource);
124                         input_method->context->model = NULL;
125                 }
126
127                 wl_list_remove(&input_method->link);
128                 input_method->model = NULL;
129                 input_method->context = NULL;
130                 wl_signal_emit(&ec->hide_input_panel_signal, ec);
131                 wl_text_input_send_leave(text_input->resource);
132         }
133 }
134
135 static void
136 destroy_text_input(struct wl_resource *resource)
137 {
138         struct text_input *text_input = wl_resource_get_user_data(resource);
139         struct input_method *input_method, *next;
140
141         wl_list_for_each_safe(input_method, next, &text_input->input_methods, link)
142                 deactivate_text_input(text_input, input_method);
143
144         free(text_input);
145 }
146
147 static void
148 text_input_set_surrounding_text(struct wl_client *client,
149                                 struct wl_resource *resource,
150                                 const char *text,
151                                 uint32_t cursor,
152                                 uint32_t anchor)
153 {
154         struct text_input *text_input = wl_resource_get_user_data(resource);
155         struct input_method *input_method, *next;
156
157         wl_list_for_each_safe(input_method, next, &text_input->input_methods, link) {
158                 if (!input_method->context)
159                         continue;
160                 wl_input_method_context_send_surrounding_text(input_method->context->resource,
161                                                               text,
162                                                               cursor,
163                                                               anchor);
164         }
165 }
166
167 static void
168 text_input_activate(struct wl_client *client,
169                     struct wl_resource *resource,
170                     struct wl_resource *seat,
171                     struct wl_resource *surface)
172 {
173         struct text_input *text_input = wl_resource_get_user_data(resource);
174         struct weston_seat *weston_seat = wl_resource_get_user_data(seat);
175         struct input_method *input_method = weston_seat->input_method;
176         struct text_input *old = weston_seat->input_method->model;
177         struct weston_compositor *ec = text_input->ec;
178
179         if (old == text_input)
180                 return;
181
182         if (old) {
183                 deactivate_text_input(old,
184                                       weston_seat->input_method);
185         }
186
187         input_method->model = text_input;
188         wl_list_insert(&text_input->input_methods, &input_method->link);
189         input_method_init_seat(weston_seat);
190
191         text_input->surface = wl_resource_get_user_data(surface);
192
193         input_method_context_create(text_input, input_method);
194
195         if (text_input->input_panel_visible) {
196                 wl_signal_emit(&ec->show_input_panel_signal, text_input->surface);
197                 wl_signal_emit(&ec->update_input_panel_signal, &text_input->cursor_rectangle);
198         }
199
200         wl_text_input_send_enter(text_input->resource, text_input->surface->resource);
201 }
202
203 static void
204 text_input_deactivate(struct wl_client *client,
205                       struct wl_resource *resource,
206                       struct wl_resource *seat)
207 {
208         struct text_input *text_input = wl_resource_get_user_data(resource);
209         struct weston_seat *weston_seat = wl_resource_get_user_data(seat);
210
211         deactivate_text_input(text_input,
212                               weston_seat->input_method);
213 }
214
215 static void
216 text_input_reset(struct wl_client *client,
217                  struct wl_resource *resource)
218 {
219         struct text_input *text_input = wl_resource_get_user_data(resource);
220         struct input_method *input_method, *next;
221
222         wl_list_for_each_safe(input_method, next, &text_input->input_methods, link) {
223                 if (!input_method->context)
224                         continue;
225                 wl_input_method_context_send_reset(input_method->context->resource);
226         }
227 }
228
229 static void
230 text_input_set_cursor_rectangle(struct wl_client *client,
231                                 struct wl_resource *resource,
232                                 int32_t x,
233                                 int32_t y,
234                                 int32_t width,
235                                 int32_t height)
236 {
237         struct text_input *text_input = wl_resource_get_user_data(resource);
238         struct weston_compositor *ec = text_input->ec;
239
240         text_input->cursor_rectangle.x1 = x;
241         text_input->cursor_rectangle.y1 = y;
242         text_input->cursor_rectangle.x2 = x + width;
243         text_input->cursor_rectangle.y2 = y + height;
244
245         wl_signal_emit(&ec->update_input_panel_signal, &text_input->cursor_rectangle);
246 }
247
248 static void
249 text_input_set_content_type(struct wl_client *client,
250                             struct wl_resource *resource,
251                             uint32_t hint,
252                             uint32_t purpose)
253 {
254         struct text_input *text_input = wl_resource_get_user_data(resource);
255         struct input_method *input_method, *next;
256
257         wl_list_for_each_safe(input_method, next, &text_input->input_methods, link) {
258                 if (!input_method->context)
259                         continue;
260                 wl_input_method_context_send_content_type(input_method->context->resource, hint, purpose);
261         }
262 }
263
264 static void
265 text_input_invoke_action(struct wl_client *client,
266                          struct wl_resource *resource,
267                          uint32_t button,
268                          uint32_t index)
269 {
270         struct text_input *text_input = wl_resource_get_user_data(resource);
271         struct input_method *input_method, *next;
272
273         wl_list_for_each_safe(input_method, next, &text_input->input_methods, link) {
274                 if (!input_method->context)
275                         continue;
276                 wl_input_method_context_send_invoke_action(input_method->context->resource, button, index);
277         }
278 }
279
280 static void
281 text_input_commit_state(struct wl_client *client,
282                         struct wl_resource *resource,
283                         uint32_t serial)
284 {
285         struct text_input *text_input = wl_resource_get_user_data(resource);
286         struct input_method *input_method, *next;
287
288         wl_list_for_each_safe(input_method, next, &text_input->input_methods, link) {
289                 if (!input_method->context)
290                         continue;
291                 wl_input_method_context_send_commit_state(input_method->context->resource, serial);
292         }
293 }
294
295 static void
296 text_input_show_input_panel(struct wl_client *client,
297                             struct wl_resource *resource)
298 {
299         struct text_input *text_input = wl_resource_get_user_data(resource);
300         struct weston_compositor *ec = text_input->ec;
301
302         text_input->input_panel_visible = 1;
303
304         if (!wl_list_empty(&text_input->input_methods)) {
305                 wl_signal_emit(&ec->show_input_panel_signal, text_input->surface);
306                 wl_signal_emit(&ec->update_input_panel_signal, &text_input->cursor_rectangle);
307         }
308 }
309
310 static void
311 text_input_hide_input_panel(struct wl_client *client,
312                             struct wl_resource *resource)
313 {
314         struct text_input *text_input = wl_resource_get_user_data(resource);
315         struct weston_compositor *ec = text_input->ec;
316
317         text_input->input_panel_visible = 0;
318
319         if (!wl_list_empty(&text_input->input_methods))
320                 wl_signal_emit(&ec->hide_input_panel_signal, ec);
321 }
322
323 static void
324 text_input_set_preferred_language(struct wl_client *client,
325                                   struct wl_resource *resource,
326                                   const char *language)
327 {
328         struct text_input *text_input = wl_resource_get_user_data(resource);
329         struct input_method *input_method, *next;
330
331         wl_list_for_each_safe(input_method, next, &text_input->input_methods, link) {
332                 if (!input_method->context)
333                         continue;
334                 wl_input_method_context_send_preferred_language(input_method->context->resource,
335                                                                 language);
336         }
337 }
338
339 static const struct wl_text_input_interface text_input_implementation = {
340         text_input_activate,
341         text_input_deactivate,
342         text_input_show_input_panel,
343         text_input_hide_input_panel,
344         text_input_reset,
345         text_input_set_surrounding_text,
346         text_input_set_content_type,
347         text_input_set_cursor_rectangle,
348         text_input_set_preferred_language,
349         text_input_commit_state,
350         text_input_invoke_action
351 };
352
353 static void text_input_manager_create_text_input(struct wl_client *client,
354                                                  struct wl_resource *resource,
355                                                  uint32_t id)
356 {
357         struct text_input_manager *text_input_manager = wl_resource_get_user_data(resource);
358         struct text_input *text_input;
359
360         text_input = calloc(1, sizeof *text_input);
361
362         text_input->resource =
363                 wl_resource_create(client, &wl_text_input_interface, 1, id);
364         wl_resource_set_implementation(text_input->resource,
365                                        &text_input_implementation,
366                                        text_input, destroy_text_input);
367
368         text_input->ec = text_input_manager->ec;
369
370         wl_list_init(&text_input->input_methods);
371 };
372
373 static const struct wl_text_input_manager_interface text_input_manager_implementation = {
374         text_input_manager_create_text_input
375 };
376
377 static void
378 bind_text_input_manager(struct wl_client *client,
379                         void *data,
380                         uint32_t version,
381                         uint32_t id)
382 {
383         struct text_input_manager *text_input_manager = data;
384         struct wl_resource *resource;
385
386         /* No checking for duplicate binding necessary.  */
387         resource =
388                 wl_resource_create(client,
389                                    &wl_text_input_manager_interface, 1, id);
390         if (resource)
391                 wl_resource_set_implementation(resource,
392                                                &text_input_manager_implementation,
393                                                text_input_manager, NULL);
394 }
395
396 static void
397 text_input_manager_notifier_destroy(struct wl_listener *listener, void *data)
398 {
399         struct text_input_manager *text_input_manager =
400                 container_of(listener, struct text_input_manager, destroy_listener);
401
402         wl_global_destroy(text_input_manager->text_input_manager_global);
403
404         free(text_input_manager);
405 }
406
407 static void
408 text_input_manager_create(struct weston_compositor *ec)
409 {
410         struct text_input_manager *text_input_manager;
411
412         text_input_manager = calloc(1, sizeof *text_input_manager);
413
414         text_input_manager->ec = ec;
415
416         text_input_manager->text_input_manager_global =
417                 wl_global_create(ec->wl_display,
418                                  &wl_text_input_manager_interface, 1,
419                                  text_input_manager, bind_text_input_manager);
420
421         text_input_manager->destroy_listener.notify = text_input_manager_notifier_destroy;
422         wl_signal_add(&ec->destroy_signal, &text_input_manager->destroy_listener);
423 }
424
425 static void
426 input_method_context_destroy(struct wl_client *client,
427                              struct wl_resource *resource)
428 {
429         wl_resource_destroy(resource);
430 }
431
432 static void
433 input_method_context_commit_string(struct wl_client *client,
434                                    struct wl_resource *resource,
435                                    uint32_t serial,
436                                    const char *text)
437 {
438         struct input_method_context *context =
439                 wl_resource_get_user_data(resource);
440
441         if (context->model)
442                 wl_text_input_send_commit_string(context->model->resource,
443                                                  serial, text);
444 }
445
446 static void
447 input_method_context_preedit_string(struct wl_client *client,
448                                     struct wl_resource *resource,
449                                     uint32_t serial,
450                                     const char *text,
451                                     const char *commit)
452 {
453         struct input_method_context *context =
454                 wl_resource_get_user_data(resource);
455
456         if (context->model)
457                 wl_text_input_send_preedit_string(context->model->resource,
458                                                   serial, text, commit);
459 }
460
461 static void
462 input_method_context_preedit_styling(struct wl_client *client,
463                                      struct wl_resource *resource,
464                                      uint32_t index,
465                                      uint32_t length,
466                                      uint32_t style)
467 {
468         struct input_method_context *context =
469                 wl_resource_get_user_data(resource);
470
471         if (context->model)
472                 wl_text_input_send_preedit_styling(context->model->resource,
473                                                    index, length, style);
474 }
475
476 static void
477 input_method_context_preedit_cursor(struct wl_client *client,
478                                     struct wl_resource *resource,
479                                     int32_t cursor)
480 {
481         struct input_method_context *context =
482                 wl_resource_get_user_data(resource);
483
484         if (context->model)
485                 wl_text_input_send_preedit_cursor(context->model->resource,
486                                                   cursor);
487 }
488
489 static void
490 input_method_context_delete_surrounding_text(struct wl_client *client,
491                                              struct wl_resource *resource,
492                                              int32_t index,
493                                              uint32_t length)
494 {
495         struct input_method_context *context =
496                 wl_resource_get_user_data(resource);
497
498         if (context->model)
499                 wl_text_input_send_delete_surrounding_text(context->model->resource,
500                                                            index, length);
501 }
502
503 static void
504 input_method_context_cursor_position(struct wl_client *client,
505                                      struct wl_resource *resource,
506                                      int32_t index,
507                                      int32_t anchor)
508 {
509         struct input_method_context *context =
510                 wl_resource_get_user_data(resource);
511
512         if (context->model)
513                 wl_text_input_send_cursor_position(context->model->resource,
514                                                    index, anchor);
515 }
516
517 static void
518 input_method_context_modifiers_map(struct wl_client *client,
519                                    struct wl_resource *resource,
520                                    struct wl_array *map)
521 {
522         struct input_method_context *context =
523                 wl_resource_get_user_data(resource);
524
525         if (context->model)
526                 wl_text_input_send_modifiers_map(context->model->resource, map);
527 }
528
529 static void
530 input_method_context_keysym(struct wl_client *client,
531                             struct wl_resource *resource,
532                             uint32_t serial,
533                             uint32_t time,
534                             uint32_t sym,
535                             uint32_t state,
536                             uint32_t modifiers)
537 {
538         struct input_method_context *context =
539                 wl_resource_get_user_data(resource);
540
541         if (context->model)
542                 wl_text_input_send_keysym(context->model->resource,
543                                           serial, time, sym, state, modifiers);
544 }
545
546 static void
547 unbind_keyboard(struct wl_resource *resource)
548 {
549         struct input_method_context *context =
550                 wl_resource_get_user_data(resource);
551
552         input_method_context_end_keyboard_grab(context);
553         context->keyboard = NULL;
554 }
555
556 static void
557 input_method_context_grab_key(struct weston_keyboard_grab *grab,
558                               uint32_t time, uint32_t key, uint32_t state_w)
559 {
560         struct weston_keyboard *keyboard = grab->keyboard;
561         struct wl_display *display;
562         uint32_t serial;
563
564         if (!keyboard->input_method_resource)
565                 return;
566
567         display = wl_client_get_display(wl_resource_get_client(keyboard->input_method_resource));
568         serial = wl_display_next_serial(display);
569         wl_keyboard_send_key(keyboard->input_method_resource,
570                              serial, time, key, state_w);
571 }
572
573 static void
574 input_method_context_grab_modifier(struct weston_keyboard_grab *grab, uint32_t serial,
575                                    uint32_t mods_depressed, uint32_t mods_latched,
576                                    uint32_t mods_locked, uint32_t group)
577 {
578         struct weston_keyboard *keyboard = grab->keyboard;
579
580         if (!keyboard->input_method_resource)
581                 return;
582
583         wl_keyboard_send_modifiers(keyboard->input_method_resource,
584                                    serial, mods_depressed, mods_latched,
585                                    mods_locked, group);
586 }
587
588 static void
589 input_method_context_grab_cancel(struct weston_keyboard_grab *grab)
590 {
591         weston_keyboard_end_grab(grab->keyboard);
592 }
593
594 static const struct weston_keyboard_grab_interface input_method_context_grab = {
595         input_method_context_grab_key,
596         input_method_context_grab_modifier,
597         input_method_context_grab_cancel,
598 };
599
600 static void
601 input_method_context_grab_keyboard(struct wl_client *client,
602                                    struct wl_resource *resource,
603                                    uint32_t id)
604 {
605         struct input_method_context *context = wl_resource_get_user_data(resource);
606         struct wl_resource *cr;
607         struct weston_seat *seat = context->input_method->seat;
608         struct weston_keyboard *keyboard = seat->keyboard;
609
610         cr = wl_resource_create(client, &wl_keyboard_interface, 1, id);
611         wl_resource_set_implementation(cr, NULL, context, unbind_keyboard);
612
613         context->keyboard = cr;
614
615         wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
616                                 keyboard->xkb_info->keymap_fd,
617                                 keyboard->xkb_info->keymap_size);
618
619         if (keyboard->grab != &keyboard->default_grab) {
620                 weston_keyboard_end_grab(keyboard);
621         }
622         weston_keyboard_start_grab(keyboard, &keyboard->input_method_grab);
623         keyboard->input_method_resource = cr;
624 }
625
626 static void
627 input_method_context_key(struct wl_client *client,
628                          struct wl_resource *resource,
629                          uint32_t serial,
630                          uint32_t time,
631                          uint32_t key,
632                          uint32_t state_w)
633 {
634         struct input_method_context *context = wl_resource_get_user_data(resource);
635         struct weston_seat *seat = context->input_method->seat;
636         struct weston_keyboard *keyboard = seat->keyboard;
637         struct weston_keyboard_grab *default_grab = &keyboard->default_grab;
638
639         default_grab->interface->key(default_grab, time, key, state_w);
640 }
641
642 static void
643 input_method_context_modifiers(struct wl_client *client,
644                                struct wl_resource *resource,
645                                uint32_t serial,
646                                uint32_t mods_depressed,
647                                uint32_t mods_latched,
648                                uint32_t mods_locked,
649                                uint32_t group)
650 {
651         struct input_method_context *context = wl_resource_get_user_data(resource);
652
653         struct weston_seat *seat = context->input_method->seat;
654         struct weston_keyboard *keyboard = seat->keyboard;
655         struct weston_keyboard_grab *default_grab = &keyboard->default_grab;
656
657         default_grab->interface->modifiers(default_grab,
658                                            serial, mods_depressed,
659                                            mods_latched, mods_locked,
660                                            group);
661 }
662
663 static void
664 input_method_context_language(struct wl_client *client,
665                               struct wl_resource *resource,
666                               uint32_t serial,
667                               const char *language)
668 {
669         struct input_method_context *context = wl_resource_get_user_data(resource);
670
671         if (context->model)
672                 wl_text_input_send_language(context->model->resource,
673                                             serial, language);
674 }
675
676 static void
677 input_method_context_text_direction(struct wl_client *client,
678                                     struct wl_resource *resource,
679                                     uint32_t serial,
680                                     uint32_t direction)
681 {
682         struct input_method_context *context = wl_resource_get_user_data(resource);
683
684         if (context->model)
685                 wl_text_input_send_text_direction(context->model->resource,
686                                                   serial, direction);
687 }
688
689
690 static const struct wl_input_method_context_interface input_method_context_implementation = {
691         input_method_context_destroy,
692         input_method_context_commit_string,
693         input_method_context_preedit_string,
694         input_method_context_preedit_styling,
695         input_method_context_preedit_cursor,
696         input_method_context_delete_surrounding_text,
697         input_method_context_cursor_position,
698         input_method_context_modifiers_map,
699         input_method_context_keysym,
700         input_method_context_grab_keyboard,
701         input_method_context_key,
702         input_method_context_modifiers,
703         input_method_context_language,
704         input_method_context_text_direction
705 };
706
707 static void
708 destroy_input_method_context(struct wl_resource *resource)
709 {
710         struct input_method_context *context = wl_resource_get_user_data(resource);
711
712         if (context->keyboard) {
713                 wl_resource_destroy(context->keyboard);
714         }
715
716         free(context);
717 }
718
719 static void
720 input_method_context_create(struct text_input *model,
721                             struct input_method *input_method)
722 {
723         struct input_method_context *context;
724         struct wl_resource *binding;
725
726         if (!input_method->input_method_binding)
727                 return;
728
729         context = calloc(1, sizeof *context);
730         if (context == NULL)
731                 return;
732
733         binding = input_method->input_method_binding;
734         context->resource =
735                 wl_resource_create(wl_resource_get_client(binding),
736                                    &wl_input_method_context_interface, 1, 0);
737         wl_resource_set_implementation(context->resource,
738                                        &input_method_context_implementation,
739                                        context, destroy_input_method_context);
740
741         context->model = model;
742         context->input_method = input_method;
743         input_method->context = context;
744
745
746         wl_input_method_send_activate(binding, context->resource);
747 }
748
749 static void
750 input_method_context_end_keyboard_grab(struct input_method_context *context)
751 {
752         struct weston_keyboard_grab *grab =
753                 &context->input_method->seat->keyboard->input_method_grab;
754         struct weston_keyboard *keyboard = grab->keyboard;
755
756         if (!grab->keyboard)
757                 return;
758
759         if (grab->keyboard->grab == grab)
760                 weston_keyboard_end_grab(grab->keyboard);
761
762         keyboard->input_method_resource = NULL;
763 }
764
765 static void
766 unbind_input_method(struct wl_resource *resource)
767 {
768         struct input_method *input_method = wl_resource_get_user_data(resource);
769         struct text_backend *text_backend = input_method->text_backend;
770
771         input_method->input_method_binding = NULL;
772         input_method->context = NULL;
773
774         text_backend->input_method.binding = NULL;
775 }
776
777 static void
778 bind_input_method(struct wl_client *client,
779                   void *data,
780                   uint32_t version,
781                   uint32_t id)
782 {
783         struct input_method *input_method = data;
784         struct text_backend *text_backend = input_method->text_backend;
785         struct wl_resource *resource;
786
787         resource =
788                 wl_resource_create(client, &wl_input_method_interface, 1, id);
789
790         if (input_method->input_method_binding != NULL) {
791                 wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
792                                        "interface object already bound");
793                 wl_resource_destroy(resource);
794                 return;
795         }
796
797         if (text_backend->input_method.client != client) {
798                 wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
799                                        "permission to bind input_method denied");
800                 wl_resource_destroy(resource);
801                 return;
802         }
803
804         wl_resource_set_implementation(resource, NULL, input_method,
805                                        unbind_input_method);
806         input_method->input_method_binding = resource;
807
808         text_backend->input_method.binding = resource;
809 }
810
811 static void
812 input_method_notifier_destroy(struct wl_listener *listener, void *data)
813 {
814         struct input_method *input_method =
815                 container_of(listener, struct input_method, destroy_listener);
816
817         if (input_method->model)
818                 deactivate_text_input(input_method->model, input_method);
819
820         wl_global_destroy(input_method->input_method_global);
821         wl_list_remove(&input_method->destroy_listener.link);
822
823         free(input_method);
824 }
825
826 static void
827 handle_keyboard_focus(struct wl_listener *listener, void *data)
828 {
829         struct weston_keyboard *keyboard = data;
830         struct input_method *input_method =
831                 container_of(listener, struct input_method, keyboard_focus_listener);
832         struct weston_surface *surface = keyboard->focus;
833
834         if (!input_method->model)
835                 return;
836
837         if (!surface || input_method->model->surface != surface)
838                 deactivate_text_input(input_method->model,
839                                       input_method);
840 }
841
842 static void
843 input_method_init_seat(struct weston_seat *seat)
844 {
845         if (seat->input_method->focus_listener_initialized)
846                 return;
847
848         if (seat->keyboard) {
849                 seat->input_method->keyboard_focus_listener.notify = handle_keyboard_focus;
850                 wl_signal_add(&seat->keyboard->focus_signal, &seat->input_method->keyboard_focus_listener);
851                 seat->keyboard->input_method_grab.interface = &input_method_context_grab;
852         }
853
854         seat->input_method->focus_listener_initialized = 1;
855 }
856
857 static void launch_input_method(struct text_backend *text_backend);
858
859 static void
860 handle_input_method_sigchld(struct weston_process *process, int status)
861 {
862         uint32_t time;
863         struct text_backend *text_backend =
864                 container_of(process, struct text_backend, input_method.process);
865
866         text_backend->input_method.process.pid = 0;
867         text_backend->input_method.client = NULL;
868
869         /* if input_method dies more than 5 times in 10 seconds, give up */
870         time = weston_compositor_get_time();
871         if (time - text_backend->input_method.deathstamp > 10000) {
872                 text_backend->input_method.deathstamp = time;
873                 text_backend->input_method.deathcount = 0;
874         }
875
876         text_backend->input_method.deathcount++;
877         if (text_backend->input_method.deathcount > 5) {
878                 weston_log("input_method died, giving up.\n");
879                 return;
880         }
881
882         weston_log("input_method died, respawning...\n");
883         launch_input_method(text_backend);
884 }
885
886 static void
887 launch_input_method(struct text_backend *text_backend)
888 {
889         if (text_backend->input_method.binding)
890                 return;
891
892         if (!text_backend->input_method.path)
893                 return;
894
895         if (text_backend->input_method.process.pid != 0)
896                 return;
897
898         text_backend->input_method.client = weston_client_launch(text_backend->compositor,
899                                                                  &text_backend->input_method.process,
900                                                                  text_backend->input_method.path,
901                                                                  handle_input_method_sigchld);
902
903         if (!text_backend->input_method.client)
904                 weston_log("not able to start %s\n", text_backend->input_method.path);
905 }
906
907 static void
908 handle_seat_created(struct wl_listener *listener,
909                     void *data)
910 {
911         struct weston_seat *seat = data;
912         struct text_backend *text_backend =
913                 container_of(listener, struct text_backend,
914                              seat_created_listener);
915         struct input_method *input_method;
916         struct weston_compositor *ec = seat->compositor;
917
918         input_method = calloc(1, sizeof *input_method);
919
920         input_method->seat = seat;
921         input_method->model = NULL;
922         input_method->focus_listener_initialized = 0;
923         input_method->context = NULL;
924         input_method->text_backend = text_backend;
925
926         input_method->input_method_global =
927                 wl_global_create(ec->wl_display, &wl_input_method_interface, 1,
928                                  input_method, bind_input_method);
929
930         input_method->destroy_listener.notify = input_method_notifier_destroy;
931         wl_signal_add(&seat->destroy_signal, &input_method->destroy_listener);
932
933         seat->input_method = input_method;
934
935         launch_input_method(text_backend);
936 }
937
938 static void
939 text_backend_configuration(struct text_backend *text_backend)
940 {
941         struct weston_config_section *section;
942
943         section = weston_config_get_section(text_backend->compositor->config,
944                                             "input-method", NULL, NULL);
945         weston_config_section_get_string(section, "path",
946                                          &text_backend->input_method.path,
947                                          LIBEXECDIR "/weston-keyboard");
948 }
949
950 static void
951 text_backend_notifier_destroy(struct wl_listener *listener, void *data)
952 {
953         struct text_backend *text_backend =
954                 container_of(listener, struct text_backend, destroy_listener);
955
956         if (text_backend->input_method.client)
957                 wl_client_destroy(text_backend->input_method.client);
958
959         free(text_backend->input_method.path);
960
961         free(text_backend);
962 }
963
964
965 WL_EXPORT int
966 text_backend_init(struct weston_compositor *ec)
967 {
968         struct text_backend *text_backend;
969
970         text_backend = calloc(1, sizeof(*text_backend));
971
972         text_backend->compositor = ec;
973
974         text_backend->seat_created_listener.notify = handle_seat_created;
975         wl_signal_add(&ec->seat_created_signal,
976                       &text_backend->seat_created_listener);
977
978         text_backend->destroy_listener.notify = text_backend_notifier_destroy;
979         wl_signal_add(&ec->destroy_signal, &text_backend->destroy_listener);
980
981         text_backend_configuration(text_backend);
982
983         text_input_manager_create(ec);
984
985         return 0;
986 }