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