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