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