blob: e6ee249cbf2e39e992ce71d27ace76eed0821570 [file] [log] [blame]
Jan Arne Petersen1f17be42012-06-21 21:52:18 +02001/*
2 * Copyright © 2012 Openismus GmbH
Jan Arne Petersen4c265182012-09-09 23:08:30 +02003 * Copyright © 2012 Intel Corporation
Jan Arne Petersen1f17be42012-06-21 21:52:18 +02004 *
Bryce Harringtona0bbfea2015-06-11 15:35:43 -07005 * 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:
Jan Arne Petersen1f17be42012-06-21 21:52:18 +020012 *
Bryce Harringtona0bbfea2015-06-11 15:35:43 -070013 * 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.
Jan Arne Petersen1f17be42012-06-21 21:52:18 +020025 */
26
Daniel Stonec228e232013-05-22 18:03:19 +030027#include "config.h"
28
Derek Foremand09dbb32014-12-05 15:38:39 -060029#include <stdbool.h>
Jan Arne Petersen1f17be42012-06-21 21:52:18 +020030#include <stdlib.h>
Jussi Kukkonen649bbce2016-07-19 14:16:27 +030031#include <stdint.h>
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +010032#include <string.h>
Ossama Othmana50e6e42013-05-14 09:48:26 -070033#include <unistd.h>
Eduardo Lima (Etrunko)27337002013-05-14 13:09:31 -030034#include <time.h>
Jan Arne Petersen1f17be42012-06-21 21:52:18 +020035
36#include "compositor.h"
Giulio Camuffofba27fb2016-06-02 21:48:10 +030037#include "weston.h"
Jonas Ådahl3bcba342015-11-17 16:00:29 +080038#include "text-input-unstable-v1-server-protocol.h"
Jonas Ådahlb57f4722015-11-17 16:00:30 +080039#include "input-method-unstable-v1-server-protocol.h"
Jon Cruz867d50e2015-06-15 15:37:10 -070040#include "shared/helpers.h"
Alexandros Frantzis47e79c82017-11-16 18:20:57 +020041#include "shared/timespec-util.h"
Jan Arne Petersen1f17be42012-06-21 21:52:18 +020042
Derek Foreman516d6032015-05-08 17:08:40 -050043struct text_input_manager;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +020044struct input_method;
Jan Arne Petersen620cd622012-09-09 23:08:32 +020045struct input_method_context;
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +010046struct text_backend;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +020047
Jan Arne Petersen78d00e42013-04-18 16:47:24 +020048struct text_input {
Jason Ekstrand89d31992013-06-14 10:07:59 -050049 struct wl_resource *resource;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +020050
Jan Arne Petersene829adc2012-08-10 16:47:22 +020051 struct weston_compositor *ec;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +020052
Jan Arne Petersene829adc2012-08-10 16:47:22 +020053 struct wl_list input_methods;
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +020054
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -040055 struct weston_surface *surface;
Jan Arne Petersen61381972013-01-31 15:52:21 +010056
Jan Arne Petersen14da96b2013-04-18 16:47:28 +020057 pixman_box32_t cursor_rectangle;
58
Derek Foremand09dbb32014-12-05 15:38:39 -060059 bool input_panel_visible;
Derek Foreman516d6032015-05-08 17:08:40 -050060
61 struct text_input_manager *manager;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +020062};
63
Jan Arne Petersen78d00e42013-04-18 16:47:24 +020064struct text_input_manager {
65 struct wl_global *text_input_manager_global;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +020066 struct wl_listener destroy_listener;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +020067
Joshua Wattdd616252017-06-24 16:03:41 -050068 struct text_input *current_text_input;
Derek Foreman516d6032015-05-08 17:08:40 -050069
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +020070 struct weston_compositor *ec;
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +020071};
72
73struct input_method {
74 struct wl_resource *input_method_binding;
75 struct wl_global *input_method_global;
76 struct wl_listener destroy_listener;
77
78 struct weston_seat *seat;
Derek Foreman0f299232015-05-08 17:08:41 -050079 struct text_input *input;
Jan Arne Petersene829adc2012-08-10 16:47:22 +020080
81 struct wl_list link;
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +020082
83 struct wl_listener keyboard_focus_listener;
84
Derek Foremanddc2c972015-07-15 13:00:32 -050085 bool focus_listener_initialized;
Jan Arne Petersen620cd622012-09-09 23:08:32 +020086
87 struct input_method_context *context;
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +010088
89 struct text_backend *text_backend;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +020090};
91
Jan Arne Petersen620cd622012-09-09 23:08:32 +020092struct input_method_context {
Jason Ekstrand89d31992013-06-14 10:07:59 -050093 struct wl_resource *resource;
Jan Arne Petersen620cd622012-09-09 23:08:32 +020094
Derek Foreman0f299232015-05-08 17:08:41 -050095 struct text_input *input;
Jan Arne Petersen466b9c12012-11-18 19:06:45 +010096 struct input_method *input_method;
Jan Arne Petersen620cd622012-09-09 23:08:32 +020097
Jan Arne Petersen466b9c12012-11-18 19:06:45 +010098 struct wl_resource *keyboard;
Jan Arne Petersen620cd622012-09-09 23:08:32 +020099};
100
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100101struct text_backend {
102 struct weston_compositor *compositor;
103
104 struct {
105 char *path;
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100106 struct wl_client *client;
Eduardo Lima (Etrunko)27337002013-05-14 13:09:31 -0300107
108 unsigned deathcount;
Alexandros Frantzis409b01f2017-11-16 18:21:01 +0200109 struct timespec deathstamp;
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100110 } input_method;
111
Derek Foreman89dcea92015-06-25 15:49:49 -0500112 struct wl_listener client_listener;
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100113 struct wl_listener seat_created_listener;
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100114};
115
Derek Foremancb5fcea2014-12-05 15:38:37 -0600116static void
Derek Foreman0f299232015-05-08 17:08:41 -0500117input_method_context_create(struct text_input *input,
Derek Foremancb5fcea2014-12-05 15:38:37 -0600118 struct input_method *input_method);
119static void
120input_method_context_end_keyboard_grab(struct input_method_context *context);
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200121
Derek Foremancb5fcea2014-12-05 15:38:37 -0600122static void
123input_method_init_seat(struct weston_seat *seat);
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +0200124
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200125static void
Derek Foreman516d6032015-05-08 17:08:40 -0500126deactivate_input_method(struct input_method *input_method)
Philipp Brüschweiler17467812012-07-11 22:25:30 +0200127{
Derek Foreman0f299232015-05-08 17:08:41 -0500128 struct text_input *text_input = input_method->input;
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200129 struct weston_compositor *ec = text_input->ec;
Philipp Brüschweiler17467812012-07-11 22:25:30 +0200130
Derek Foreman516d6032015-05-08 17:08:40 -0500131 if (input_method->context && input_method->input_method_binding) {
132 input_method_context_end_keyboard_grab(input_method->context);
Jonas Ådahlb57f4722015-11-17 16:00:30 +0800133 zwp_input_method_v1_send_deactivate(
Murray Calavera972d1af2015-06-09 20:29:28 +0000134 input_method->input_method_binding,
135 input_method->context->resource);
Daniel Stone97863d62016-11-10 15:47:56 +0000136 input_method->context->input = NULL;
Philipp Brüschweiler17467812012-07-11 22:25:30 +0200137 }
Derek Foreman516d6032015-05-08 17:08:40 -0500138
139 wl_list_remove(&input_method->link);
Derek Foreman0f299232015-05-08 17:08:41 -0500140 input_method->input = NULL;
Derek Foreman516d6032015-05-08 17:08:40 -0500141 input_method->context = NULL;
142
143 if (wl_list_empty(&text_input->input_methods) &&
Joshua Wattdd616252017-06-24 16:03:41 -0500144 text_input->input_panel_visible &&
145 text_input->manager->current_text_input == text_input) {
Derek Foreman516d6032015-05-08 17:08:40 -0500146 wl_signal_emit(&ec->hide_input_panel_signal, ec);
147 text_input->input_panel_visible = false;
Derek Foreman516d6032015-05-08 17:08:40 -0500148 }
Joshua Wattdd616252017-06-24 16:03:41 -0500149
150 if (text_input->manager->current_text_input == text_input)
151 text_input->manager->current_text_input = NULL;
152
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800153 zwp_text_input_v1_send_leave(text_input->resource);
Philipp Brüschweiler17467812012-07-11 22:25:30 +0200154}
155
156static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200157destroy_text_input(struct wl_resource *resource)
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200158{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500159 struct text_input *text_input = wl_resource_get_user_data(resource);
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200160 struct input_method *input_method, *next;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200161
Murray Calavera972d1af2015-06-09 20:29:28 +0000162 wl_list_for_each_safe(input_method, next,
163 &text_input->input_methods, link)
Derek Foreman516d6032015-05-08 17:08:40 -0500164 deactivate_input_method(input_method);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200165
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200166 free(text_input);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200167}
168
169static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200170text_input_set_surrounding_text(struct wl_client *client,
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200171 struct wl_resource *resource,
Jan Arne Petersencb08f4d2012-09-09 23:08:40 +0200172 const char *text,
173 uint32_t cursor,
174 uint32_t anchor)
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200175{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500176 struct text_input *text_input = wl_resource_get_user_data(resource);
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200177 struct input_method *input_method, *next;
178
Murray Calavera972d1af2015-06-09 20:29:28 +0000179 wl_list_for_each_safe(input_method, next,
180 &text_input->input_methods, link) {
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200181 if (!input_method->context)
182 continue;
Jonas Ådahlb57f4722015-11-17 16:00:30 +0800183 zwp_input_method_context_v1_send_surrounding_text(
Murray Calavera972d1af2015-06-09 20:29:28 +0000184 input_method->context->resource, text, cursor, anchor);
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200185 }
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200186}
187
188static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200189text_input_activate(struct wl_client *client,
Jan Arne Petersencc75ec12013-04-18 16:47:39 +0200190 struct wl_resource *resource,
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200191 struct wl_resource *seat,
192 struct wl_resource *surface)
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200193{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500194 struct text_input *text_input = wl_resource_get_user_data(resource);
Jason Ekstrand44a38632013-06-14 10:08:00 -0500195 struct weston_seat *weston_seat = wl_resource_get_user_data(seat);
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200196 struct input_method *input_method = weston_seat->input_method;
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200197 struct weston_compositor *ec = text_input->ec;
Derek Foreman516d6032015-05-08 17:08:40 -0500198 struct text_input *current;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200199
Derek Foreman0f299232015-05-08 17:08:41 -0500200 if (input_method->input == text_input)
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200201 return;
Jan Arne Petersende3b6a12012-08-10 16:47:21 +0200202
Derek Foreman0f299232015-05-08 17:08:41 -0500203 if (input_method->input)
Derek Foreman516d6032015-05-08 17:08:40 -0500204 deactivate_input_method(input_method);
Jan Arne Petersende3b6a12012-08-10 16:47:21 +0200205
Derek Foreman0f299232015-05-08 17:08:41 -0500206 input_method->input = text_input;
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200207 wl_list_insert(&text_input->input_methods, &input_method->link);
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +0200208 input_method_init_seat(weston_seat);
209
Jason Ekstrand0f2ef7e2013-06-14 10:07:53 -0500210 text_input->surface = wl_resource_get_user_data(surface);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200211
Jan Arne Petersen00191c72013-04-18 16:47:33 +0200212 input_method_context_create(text_input, input_method);
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200213
Joshua Wattdd616252017-06-24 16:03:41 -0500214 current = text_input->manager->current_text_input;
Derek Foreman516d6032015-05-08 17:08:40 -0500215
216 if (current && current != text_input) {
217 current->input_panel_visible = false;
218 wl_signal_emit(&ec->hide_input_panel_signal, ec);
Derek Foreman516d6032015-05-08 17:08:40 -0500219 }
220
Jan Arne Petersen14da96b2013-04-18 16:47:28 +0200221 if (text_input->input_panel_visible) {
Murray Calavera972d1af2015-06-09 20:29:28 +0000222 wl_signal_emit(&ec->show_input_panel_signal,
223 text_input->surface);
224 wl_signal_emit(&ec->update_input_panel_signal,
225 &text_input->cursor_rectangle);
Jan Arne Petersen14da96b2013-04-18 16:47:28 +0200226 }
Joshua Wattdd616252017-06-24 16:03:41 -0500227 text_input->manager->current_text_input = text_input;
Jan Arne Petersende3b6a12012-08-10 16:47:21 +0200228
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800229 zwp_text_input_v1_send_enter(text_input->resource,
230 text_input->surface->resource);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200231}
232
233static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200234text_input_deactivate(struct wl_client *client,
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200235 struct wl_resource *resource,
236 struct wl_resource *seat)
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200237{
Jason Ekstrand44a38632013-06-14 10:08:00 -0500238 struct weston_seat *weston_seat = wl_resource_get_user_data(seat);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200239
Derek Foreman0f299232015-05-08 17:08:41 -0500240 if (weston_seat->input_method->input)
Derek Foreman516d6032015-05-08 17:08:40 -0500241 deactivate_input_method(weston_seat->input_method);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200242}
243
244static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200245text_input_reset(struct wl_client *client,
Jan Arne Petersen00191c72013-04-18 16:47:33 +0200246 struct wl_resource *resource)
Jan Arne Petersenc1e481e2012-09-09 23:08:46 +0200247{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500248 struct text_input *text_input = wl_resource_get_user_data(resource);
Jan Arne Petersenc1e481e2012-09-09 23:08:46 +0200249 struct input_method *input_method, *next;
250
Murray Calavera972d1af2015-06-09 20:29:28 +0000251 wl_list_for_each_safe(input_method, next,
252 &text_input->input_methods, link) {
Jan Arne Petersenc1e481e2012-09-09 23:08:46 +0200253 if (!input_method->context)
254 continue;
Jonas Ådahlb57f4722015-11-17 16:00:30 +0800255 zwp_input_method_context_v1_send_reset(
Murray Calavera972d1af2015-06-09 20:29:28 +0000256 input_method->context->resource);
Jan Arne Petersenc1e481e2012-09-09 23:08:46 +0200257 }
258}
259
260static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200261text_input_set_cursor_rectangle(struct wl_client *client,
Jan Arne Petersen7ef8eff2013-04-18 16:47:23 +0200262 struct wl_resource *resource,
263 int32_t x,
264 int32_t y,
265 int32_t width,
266 int32_t height)
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200267{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500268 struct text_input *text_input = wl_resource_get_user_data(resource);
Jan Arne Petersen14da96b2013-04-18 16:47:28 +0200269 struct weston_compositor *ec = text_input->ec;
270
271 text_input->cursor_rectangle.x1 = x;
272 text_input->cursor_rectangle.y1 = y;
273 text_input->cursor_rectangle.x2 = x + width;
274 text_input->cursor_rectangle.y2 = y + height;
275
Murray Calavera972d1af2015-06-09 20:29:28 +0000276 wl_signal_emit(&ec->update_input_panel_signal,
277 &text_input->cursor_rectangle);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200278}
279
280static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200281text_input_set_content_type(struct wl_client *client,
Jan Arne Petersen26ffa812013-01-16 21:26:43 +0100282 struct wl_resource *resource,
283 uint32_t hint,
284 uint32_t purpose)
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200285{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500286 struct text_input *text_input = wl_resource_get_user_data(resource);
Jan Arne Petersen26ffa812013-01-16 21:26:43 +0100287 struct input_method *input_method, *next;
288
Murray Calavera972d1af2015-06-09 20:29:28 +0000289 wl_list_for_each_safe(input_method, next,
290 &text_input->input_methods, link) {
Jan Arne Petersen26ffa812013-01-16 21:26:43 +0100291 if (!input_method->context)
292 continue;
Jonas Ådahlb57f4722015-11-17 16:00:30 +0800293 zwp_input_method_context_v1_send_content_type(
Murray Calavera972d1af2015-06-09 20:29:28 +0000294 input_method->context->resource, hint, purpose);
Jan Arne Petersen26ffa812013-01-16 21:26:43 +0100295 }
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200296}
297
Jan Arne Petersenadfedc12013-01-16 21:26:46 +0100298static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200299text_input_invoke_action(struct wl_client *client,
Jan Arne Petersenadfedc12013-01-16 21:26:46 +0100300 struct wl_resource *resource,
301 uint32_t button,
302 uint32_t index)
303{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500304 struct text_input *text_input = wl_resource_get_user_data(resource);
Jan Arne Petersenadfedc12013-01-16 21:26:46 +0100305 struct input_method *input_method, *next;
306
Murray Calavera972d1af2015-06-09 20:29:28 +0000307 wl_list_for_each_safe(input_method, next,
308 &text_input->input_methods, link) {
Jan Arne Petersenadfedc12013-01-16 21:26:46 +0100309 if (!input_method->context)
310 continue;
Jonas Ådahlb57f4722015-11-17 16:00:30 +0800311 zwp_input_method_context_v1_send_invoke_action(
Murray Calavera972d1af2015-06-09 20:29:28 +0000312 input_method->context->resource, button, index);
Jan Arne Petersenadfedc12013-01-16 21:26:46 +0100313 }
314}
315
Jan Arne Petersen0eabcaa2013-01-31 15:52:20 +0100316static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200317text_input_commit_state(struct wl_client *client,
Jan Arne Petersen00191c72013-04-18 16:47:33 +0200318 struct wl_resource *resource,
319 uint32_t serial)
Jan Arne Petersen0eabcaa2013-01-31 15:52:20 +0100320{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500321 struct text_input *text_input = wl_resource_get_user_data(resource);
Jan Arne Petersen0eabcaa2013-01-31 15:52:20 +0100322 struct input_method *input_method, *next;
323
Murray Calavera972d1af2015-06-09 20:29:28 +0000324 wl_list_for_each_safe(input_method, next,
325 &text_input->input_methods, link) {
Jan Arne Petersen0eabcaa2013-01-31 15:52:20 +0100326 if (!input_method->context)
327 continue;
Jonas Ådahlb57f4722015-11-17 16:00:30 +0800328 zwp_input_method_context_v1_send_commit_state(
Murray Calavera972d1af2015-06-09 20:29:28 +0000329 input_method->context->resource, serial);
Jan Arne Petersen0eabcaa2013-01-31 15:52:20 +0100330 }
331}
332
Jan Arne Petersen61381972013-01-31 15:52:21 +0100333static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200334text_input_show_input_panel(struct wl_client *client,
Jan Arne Petersen61381972013-01-31 15:52:21 +0100335 struct wl_resource *resource)
336{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500337 struct text_input *text_input = wl_resource_get_user_data(resource);
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200338 struct weston_compositor *ec = text_input->ec;
Jan Arne Petersen61381972013-01-31 15:52:21 +0100339
Derek Foremand09dbb32014-12-05 15:38:39 -0600340 text_input->input_panel_visible = true;
Jan Arne Petersen61381972013-01-31 15:52:21 +0100341
Joshua Wattdd616252017-06-24 16:03:41 -0500342 if (!wl_list_empty(&text_input->input_methods) &&
343 text_input == text_input->manager->current_text_input) {
Murray Calavera972d1af2015-06-09 20:29:28 +0000344 wl_signal_emit(&ec->show_input_panel_signal,
345 text_input->surface);
346 wl_signal_emit(&ec->update_input_panel_signal,
347 &text_input->cursor_rectangle);
Jan Arne Petersen14da96b2013-04-18 16:47:28 +0200348 }
Jan Arne Petersen61381972013-01-31 15:52:21 +0100349}
350
351static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200352text_input_hide_input_panel(struct wl_client *client,
Jan Arne Petersen61381972013-01-31 15:52:21 +0100353 struct wl_resource *resource)
354{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500355 struct text_input *text_input = wl_resource_get_user_data(resource);
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200356 struct weston_compositor *ec = text_input->ec;
Jan Arne Petersen61381972013-01-31 15:52:21 +0100357
Derek Foremand09dbb32014-12-05 15:38:39 -0600358 text_input->input_panel_visible = false;
Jan Arne Petersen61381972013-01-31 15:52:21 +0100359
Derek Foreman516d6032015-05-08 17:08:40 -0500360 if (!wl_list_empty(&text_input->input_methods) &&
Joshua Wattdd616252017-06-24 16:03:41 -0500361 text_input == text_input->manager->current_text_input)
Jan Arne Petersen61381972013-01-31 15:52:21 +0100362 wl_signal_emit(&ec->hide_input_panel_signal, ec);
363}
364
Jan Arne Petersenece6b5a2013-04-18 16:47:15 +0200365static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200366text_input_set_preferred_language(struct wl_client *client,
Jan Arne Petersenece6b5a2013-04-18 16:47:15 +0200367 struct wl_resource *resource,
368 const char *language)
369{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500370 struct text_input *text_input = wl_resource_get_user_data(resource);
Jan Arne Petersenece6b5a2013-04-18 16:47:15 +0200371 struct input_method *input_method, *next;
372
Murray Calavera972d1af2015-06-09 20:29:28 +0000373 wl_list_for_each_safe(input_method, next,
374 &text_input->input_methods, link) {
Jan Arne Petersenece6b5a2013-04-18 16:47:15 +0200375 if (!input_method->context)
376 continue;
Jonas Ådahlb57f4722015-11-17 16:00:30 +0800377 zwp_input_method_context_v1_send_preferred_language(
Murray Calavera972d1af2015-06-09 20:29:28 +0000378 input_method->context->resource, language);
Jan Arne Petersenece6b5a2013-04-18 16:47:15 +0200379 }
380}
381
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800382static const struct zwp_text_input_v1_interface text_input_implementation = {
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200383 text_input_activate,
384 text_input_deactivate,
385 text_input_show_input_panel,
386 text_input_hide_input_panel,
387 text_input_reset,
388 text_input_set_surrounding_text,
389 text_input_set_content_type,
390 text_input_set_cursor_rectangle,
391 text_input_set_preferred_language,
392 text_input_commit_state,
393 text_input_invoke_action
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200394};
395
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200396static void text_input_manager_create_text_input(struct wl_client *client,
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200397 struct wl_resource *resource,
Jan Arne Petersen4c265182012-09-09 23:08:30 +0200398 uint32_t id)
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200399{
Murray Calavera972d1af2015-06-09 20:29:28 +0000400 struct text_input_manager *text_input_manager =
401 wl_resource_get_user_data(resource);
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200402 struct text_input *text_input;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200403
Bryce Harringtonde16d892014-11-20 22:21:57 -0800404 text_input = zalloc(sizeof *text_input);
405 if (text_input == NULL)
406 return;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200407
Jason Ekstranda85118c2013-06-27 20:17:02 -0500408 text_input->resource =
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800409 wl_resource_create(client, &zwp_text_input_v1_interface, 1, id);
Jason Ekstranda85118c2013-06-27 20:17:02 -0500410 wl_resource_set_implementation(text_input->resource,
411 &text_input_implementation,
412 text_input, destroy_text_input);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200413
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200414 text_input->ec = text_input_manager->ec;
Derek Foreman516d6032015-05-08 17:08:40 -0500415 text_input->manager = text_input_manager;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200416
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200417 wl_list_init(&text_input->input_methods);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200418};
419
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800420static const struct zwp_text_input_manager_v1_interface manager_implementation = {
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200421 text_input_manager_create_text_input
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200422};
423
424static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200425bind_text_input_manager(struct wl_client *client,
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200426 void *data,
427 uint32_t version,
428 uint32_t id)
429{
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200430 struct text_input_manager *text_input_manager = data;
Jason Ekstranda85118c2013-06-27 20:17:02 -0500431 struct wl_resource *resource;
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200432
Jason Ekstranda85118c2013-06-27 20:17:02 -0500433 /* No checking for duplicate binding necessary. */
434 resource =
435 wl_resource_create(client,
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800436 &zwp_text_input_manager_v1_interface, 1, id);
Jason Ekstranda85118c2013-06-27 20:17:02 -0500437 if (resource)
438 wl_resource_set_implementation(resource,
Murray Calavera972d1af2015-06-09 20:29:28 +0000439 &manager_implementation,
Jason Ekstranda85118c2013-06-27 20:17:02 -0500440 text_input_manager, NULL);
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200441}
442
443static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200444text_input_manager_notifier_destroy(struct wl_listener *listener, void *data)
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200445{
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200446 struct text_input_manager *text_input_manager =
Murray Calavera972d1af2015-06-09 20:29:28 +0000447 container_of(listener,
448 struct text_input_manager,
449 destroy_listener);
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200450
Kristian Høgsberg919cddb2013-07-08 19:03:57 -0400451 wl_global_destroy(text_input_manager->text_input_manager_global);
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200452
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200453 free(text_input_manager);
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200454}
455
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100456static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200457text_input_manager_create(struct weston_compositor *ec)
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200458{
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200459 struct text_input_manager *text_input_manager;
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200460
Bryce Harringtonde16d892014-11-20 22:21:57 -0800461 text_input_manager = zalloc(sizeof *text_input_manager);
462 if (text_input_manager == NULL)
463 return;
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200464
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200465 text_input_manager->ec = ec;
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200466
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200467 text_input_manager->text_input_manager_global =
Kristian Høgsberg919cddb2013-07-08 19:03:57 -0400468 wl_global_create(ec->wl_display,
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800469 &zwp_text_input_manager_v1_interface, 1,
Kristian Høgsberg919cddb2013-07-08 19:03:57 -0400470 text_input_manager, bind_text_input_manager);
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200471
Murray Calavera972d1af2015-06-09 20:29:28 +0000472 text_input_manager->destroy_listener.notify =
473 text_input_manager_notifier_destroy;
474 wl_signal_add(&ec->destroy_signal,
475 &text_input_manager->destroy_listener);
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200476}
477
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200478static void
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200479input_method_context_destroy(struct wl_client *client,
480 struct wl_resource *resource)
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200481{
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200482 wl_resource_destroy(resource);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200483}
484
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200485static void
486input_method_context_commit_string(struct wl_client *client,
487 struct wl_resource *resource,
Jan Arne Petersenc7d2a982013-01-16 21:26:39 +0100488 uint32_t serial,
Jan Arne Petersen1cc9e082013-01-31 15:52:23 +0100489 const char *text)
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200490{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500491 struct input_method_context *context =
492 wl_resource_get_user_data(resource);
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200493
Derek Foreman0f299232015-05-08 17:08:41 -0500494 if (context->input)
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800495 zwp_text_input_v1_send_commit_string(context->input->resource,
496 serial, text);
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200497}
498
Jan Arne Petersen43f4aa82012-09-09 23:08:43 +0200499static void
500input_method_context_preedit_string(struct wl_client *client,
Jan Arne Petersen46535312013-01-16 21:26:38 +0100501 struct wl_resource *resource,
Jan Arne Petersenc7d2a982013-01-16 21:26:39 +0100502 uint32_t serial,
Jan Arne Petersen46535312013-01-16 21:26:38 +0100503 const char *text,
504 const char *commit)
Jan Arne Petersen43f4aa82012-09-09 23:08:43 +0200505{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500506 struct input_method_context *context =
507 wl_resource_get_user_data(resource);
Jan Arne Petersen43f4aa82012-09-09 23:08:43 +0200508
Derek Foreman0f299232015-05-08 17:08:41 -0500509 if (context->input)
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800510 zwp_text_input_v1_send_preedit_string(context->input->resource,
511 serial, text, commit);
Jan Arne Petersen46535312013-01-16 21:26:38 +0100512}
513
514static void
515input_method_context_preedit_styling(struct wl_client *client,
516 struct wl_resource *resource,
517 uint32_t index,
518 uint32_t length,
519 uint32_t style)
520{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500521 struct input_method_context *context =
522 wl_resource_get_user_data(resource);
Jan Arne Petersen46535312013-01-16 21:26:38 +0100523
Derek Foreman0f299232015-05-08 17:08:41 -0500524 if (context->input)
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800525 zwp_text_input_v1_send_preedit_styling(context->input->resource,
526 index, length, style);
Jan Arne Petersen46535312013-01-16 21:26:38 +0100527}
528
529static void
530input_method_context_preedit_cursor(struct wl_client *client,
531 struct wl_resource *resource,
532 int32_t cursor)
533{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500534 struct input_method_context *context =
535 wl_resource_get_user_data(resource);
Jan Arne Petersen46535312013-01-16 21:26:38 +0100536
Derek Foreman0f299232015-05-08 17:08:41 -0500537 if (context->input)
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800538 zwp_text_input_v1_send_preedit_cursor(context->input->resource,
539 cursor);
Jan Arne Petersen43f4aa82012-09-09 23:08:43 +0200540}
541
Jan Arne Petersene202bae2012-09-09 23:08:44 +0200542static void
543input_method_context_delete_surrounding_text(struct wl_client *client,
544 struct wl_resource *resource,
545 int32_t index,
546 uint32_t length)
547{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500548 struct input_method_context *context =
549 wl_resource_get_user_data(resource);
Jan Arne Petersene202bae2012-09-09 23:08:44 +0200550
Derek Foreman0f299232015-05-08 17:08:41 -0500551 if (context->input)
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800552 zwp_text_input_v1_send_delete_surrounding_text(
Murray Calavera972d1af2015-06-09 20:29:28 +0000553 context->input->resource, index, length);
Jan Arne Petersene202bae2012-09-09 23:08:44 +0200554}
555
Jan Arne Petersence8a4432012-09-09 23:08:45 +0200556static void
Jan Arne Petersen1cc9e082013-01-31 15:52:23 +0100557input_method_context_cursor_position(struct wl_client *client,
558 struct wl_resource *resource,
Jan Arne Petersen1cc9e082013-01-31 15:52:23 +0100559 int32_t index,
560 int32_t anchor)
561{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500562 struct input_method_context *context =
563 wl_resource_get_user_data(resource);
Jan Arne Petersen1cc9e082013-01-31 15:52:23 +0100564
Derek Foreman0f299232015-05-08 17:08:41 -0500565 if (context->input)
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800566 zwp_text_input_v1_send_cursor_position(context->input->resource,
567 index, anchor);
Jan Arne Petersen1cc9e082013-01-31 15:52:23 +0100568}
569
570static void
Jan Arne Petersend9be93b2012-11-18 19:06:43 +0100571input_method_context_modifiers_map(struct wl_client *client,
572 struct wl_resource *resource,
573 struct wl_array *map)
Jan Arne Petersence8a4432012-09-09 23:08:45 +0200574{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500575 struct input_method_context *context =
576 wl_resource_get_user_data(resource);
Jan Arne Petersence8a4432012-09-09 23:08:45 +0200577
Derek Foreman0f299232015-05-08 17:08:41 -0500578 if (context->input)
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800579 zwp_text_input_v1_send_modifiers_map(context->input->resource,
580 map);
Jan Arne Petersend9be93b2012-11-18 19:06:43 +0100581}
582
583static void
584input_method_context_keysym(struct wl_client *client,
585 struct wl_resource *resource,
586 uint32_t serial,
587 uint32_t time,
588 uint32_t sym,
589 uint32_t state,
590 uint32_t modifiers)
591{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500592 struct input_method_context *context =
593 wl_resource_get_user_data(resource);
Jan Arne Petersend9be93b2012-11-18 19:06:43 +0100594
Derek Foreman0f299232015-05-08 17:08:41 -0500595 if (context->input)
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800596 zwp_text_input_v1_send_keysym(context->input->resource,
597 serial, time,
598 sym, state, modifiers);
Jan Arne Petersence8a4432012-09-09 23:08:45 +0200599}
600
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100601static void
602unbind_keyboard(struct wl_resource *resource)
603{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500604 struct input_method_context *context =
605 wl_resource_get_user_data(resource);
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100606
607 input_method_context_end_keyboard_grab(context);
608 context->keyboard = NULL;
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100609}
610
611static void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400612input_method_context_grab_key(struct weston_keyboard_grab *grab,
Alexandros Frantzis47e79c82017-11-16 18:20:57 +0200613 const struct timespec *time, uint32_t key,
614 uint32_t state_w)
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100615{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400616 struct weston_keyboard *keyboard = grab->keyboard;
Jan Arne Petersena75a7892013-01-16 21:26:50 +0100617 struct wl_display *display;
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100618 uint32_t serial;
Alexandros Frantzis47e79c82017-11-16 18:20:57 +0200619 uint32_t msecs;
Jan Arne Petersena75a7892013-01-16 21:26:50 +0100620
621 if (!keyboard->input_method_resource)
622 return;
623
Murray Calavera972d1af2015-06-09 20:29:28 +0000624 display = wl_client_get_display(
625 wl_resource_get_client(keyboard->input_method_resource));
Jan Arne Petersena75a7892013-01-16 21:26:50 +0100626 serial = wl_display_next_serial(display);
Alexandros Frantzis47e79c82017-11-16 18:20:57 +0200627 msecs = timespec_to_msec(time);
Jan Arne Petersena75a7892013-01-16 21:26:50 +0100628 wl_keyboard_send_key(keyboard->input_method_resource,
Alexandros Frantzis47e79c82017-11-16 18:20:57 +0200629 serial, msecs, key, state_w);
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100630}
631
632static void
Murray Calavera972d1af2015-06-09 20:29:28 +0000633input_method_context_grab_modifier(struct weston_keyboard_grab *grab,
634 uint32_t serial,
635 uint32_t mods_depressed,
636 uint32_t mods_latched,
637 uint32_t mods_locked,
638 uint32_t group)
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100639{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400640 struct weston_keyboard *keyboard = grab->keyboard;
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100641
Jan Arne Petersena75a7892013-01-16 21:26:50 +0100642 if (!keyboard->input_method_resource)
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100643 return;
644
Jan Arne Petersena75a7892013-01-16 21:26:50 +0100645 wl_keyboard_send_modifiers(keyboard->input_method_resource,
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100646 serial, mods_depressed, mods_latched,
647 mods_locked, group);
648}
649
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200650static void
651input_method_context_grab_cancel(struct weston_keyboard_grab *grab)
652{
653 weston_keyboard_end_grab(grab->keyboard);
654}
655
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400656static const struct weston_keyboard_grab_interface input_method_context_grab = {
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100657 input_method_context_grab_key,
658 input_method_context_grab_modifier,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200659 input_method_context_grab_cancel,
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100660};
661
662static void
663input_method_context_grab_keyboard(struct wl_client *client,
664 struct wl_resource *resource,
665 uint32_t id)
666{
Murray Calavera972d1af2015-06-09 20:29:28 +0000667 struct input_method_context *context =
668 wl_resource_get_user_data(resource);
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100669 struct wl_resource *cr;
670 struct weston_seat *seat = context->input_method->seat;
Derek Foreman1281a362015-07-31 16:55:32 -0500671 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100672
Jason Ekstranda85118c2013-06-27 20:17:02 -0500673 cr = wl_resource_create(client, &wl_keyboard_interface, 1, id);
674 wl_resource_set_implementation(cr, NULL, context, unbind_keyboard);
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100675
676 context->keyboard = cr;
677
678 wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100679 keyboard->xkb_info->keymap_fd,
680 keyboard->xkb_info->keymap_size);
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100681
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400682 if (keyboard->grab != &keyboard->default_grab) {
683 weston_keyboard_end_grab(keyboard);
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100684 }
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400685 weston_keyboard_start_grab(keyboard, &keyboard->input_method_grab);
Jan Arne Petersena75a7892013-01-16 21:26:50 +0100686 keyboard->input_method_resource = cr;
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100687}
688
Jan Arne Petersen337df952012-11-18 19:06:46 +0100689static void
690input_method_context_key(struct wl_client *client,
691 struct wl_resource *resource,
692 uint32_t serial,
693 uint32_t time,
694 uint32_t key,
695 uint32_t state_w)
696{
Murray Calavera972d1af2015-06-09 20:29:28 +0000697 struct input_method_context *context =
698 wl_resource_get_user_data(resource);
Jan Arne Petersen337df952012-11-18 19:06:46 +0100699 struct weston_seat *seat = context->input_method->seat;
Derek Foreman1281a362015-07-31 16:55:32 -0500700 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400701 struct weston_keyboard_grab *default_grab = &keyboard->default_grab;
Alexandros Frantzis47e79c82017-11-16 18:20:57 +0200702 struct timespec ts;
Jan Arne Petersen337df952012-11-18 19:06:46 +0100703
Alexandros Frantzis47e79c82017-11-16 18:20:57 +0200704 timespec_from_msec(&ts, time);
705
706 default_grab->interface->key(default_grab, &ts, key, state_w);
Jan Arne Petersen337df952012-11-18 19:06:46 +0100707}
708
709static void
710input_method_context_modifiers(struct wl_client *client,
711 struct wl_resource *resource,
712 uint32_t serial,
713 uint32_t mods_depressed,
714 uint32_t mods_latched,
715 uint32_t mods_locked,
716 uint32_t group)
717{
Murray Calavera972d1af2015-06-09 20:29:28 +0000718 struct input_method_context *context =
719 wl_resource_get_user_data(resource);
Jan Arne Petersen337df952012-11-18 19:06:46 +0100720
721 struct weston_seat *seat = context->input_method->seat;
Derek Foreman1281a362015-07-31 16:55:32 -0500722 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400723 struct weston_keyboard_grab *default_grab = &keyboard->default_grab;
Jan Arne Petersen337df952012-11-18 19:06:46 +0100724
725 default_grab->interface->modifiers(default_grab,
726 serial, mods_depressed,
727 mods_latched, mods_locked,
728 group);
729}
730
Jan Arne Petersenece6b5a2013-04-18 16:47:15 +0200731static void
732input_method_context_language(struct wl_client *client,
733 struct wl_resource *resource,
734 uint32_t serial,
735 const char *language)
736{
Murray Calavera972d1af2015-06-09 20:29:28 +0000737 struct input_method_context *context =
738 wl_resource_get_user_data(resource);
Jan Arne Petersenece6b5a2013-04-18 16:47:15 +0200739
Derek Foreman0f299232015-05-08 17:08:41 -0500740 if (context->input)
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800741 zwp_text_input_v1_send_language(context->input->resource,
742 serial, language);
Jan Arne Petersenece6b5a2013-04-18 16:47:15 +0200743}
744
745static void
746input_method_context_text_direction(struct wl_client *client,
747 struct wl_resource *resource,
748 uint32_t serial,
749 uint32_t direction)
750{
Murray Calavera972d1af2015-06-09 20:29:28 +0000751 struct input_method_context *context =
752 wl_resource_get_user_data(resource);
Jan Arne Petersenece6b5a2013-04-18 16:47:15 +0200753
Derek Foreman0f299232015-05-08 17:08:41 -0500754 if (context->input)
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800755 zwp_text_input_v1_send_text_direction(context->input->resource,
756 serial, direction);
Jan Arne Petersenece6b5a2013-04-18 16:47:15 +0200757}
758
759
Jonas Ådahlb57f4722015-11-17 16:00:30 +0800760static const struct zwp_input_method_context_v1_interface context_implementation = {
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200761 input_method_context_destroy,
Jan Arne Petersen43f4aa82012-09-09 23:08:43 +0200762 input_method_context_commit_string,
763 input_method_context_preedit_string,
Jan Arne Petersen46535312013-01-16 21:26:38 +0100764 input_method_context_preedit_styling,
765 input_method_context_preedit_cursor,
Jan Arne Petersence8a4432012-09-09 23:08:45 +0200766 input_method_context_delete_surrounding_text,
Jan Arne Petersen1cc9e082013-01-31 15:52:23 +0100767 input_method_context_cursor_position,
Jan Arne Petersend9be93b2012-11-18 19:06:43 +0100768 input_method_context_modifiers_map,
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100769 input_method_context_keysym,
Jan Arne Petersen337df952012-11-18 19:06:46 +0100770 input_method_context_grab_keyboard,
771 input_method_context_key,
Jan Arne Petersenece6b5a2013-04-18 16:47:15 +0200772 input_method_context_modifiers,
773 input_method_context_language,
774 input_method_context_text_direction
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200775};
776
777static void
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200778destroy_input_method_context(struct wl_resource *resource)
779{
Murray Calavera972d1af2015-06-09 20:29:28 +0000780 struct input_method_context *context =
781 wl_resource_get_user_data(resource);
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200782
Murray Calavera972d1af2015-06-09 20:29:28 +0000783 if (context->keyboard)
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100784 wl_resource_destroy(context->keyboard);
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100785
Derek Foreman516d6032015-05-08 17:08:40 -0500786 if (context->input_method && context->input_method->context == context)
787 context->input_method->context = NULL;
788
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200789 free(context);
790}
791
792static void
Derek Foreman0f299232015-05-08 17:08:41 -0500793input_method_context_create(struct text_input *input,
Jan Arne Petersen00191c72013-04-18 16:47:33 +0200794 struct input_method *input_method)
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200795{
796 struct input_method_context *context;
Jason Ekstrand89d31992013-06-14 10:07:59 -0500797 struct wl_resource *binding;
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200798
799 if (!input_method->input_method_binding)
800 return;
801
Bryce Harringtonde16d892014-11-20 22:21:57 -0800802 context = zalloc(sizeof *context);
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200803 if (context == NULL)
804 return;
805
Jason Ekstrand89d31992013-06-14 10:07:59 -0500806 binding = input_method->input_method_binding;
Jason Ekstranda85118c2013-06-27 20:17:02 -0500807 context->resource =
808 wl_resource_create(wl_resource_get_client(binding),
Jonas Ådahlb57f4722015-11-17 16:00:30 +0800809 &zwp_input_method_context_v1_interface,
810 1, 0);
Jason Ekstranda85118c2013-06-27 20:17:02 -0500811 wl_resource_set_implementation(context->resource,
Murray Calavera972d1af2015-06-09 20:29:28 +0000812 &context_implementation,
Jason Ekstranda85118c2013-06-27 20:17:02 -0500813 context, destroy_input_method_context);
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200814
Derek Foreman0f299232015-05-08 17:08:41 -0500815 context->input = input;
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100816 context->input_method = input_method;
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200817 input_method->context = context;
818
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200819
Jonas Ådahlb57f4722015-11-17 16:00:30 +0800820 zwp_input_method_v1_send_activate(binding, context->resource);
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200821}
822
823static void
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100824input_method_context_end_keyboard_grab(struct input_method_context *context)
825{
Derek Foremanf0aaa412014-12-08 10:48:29 -0600826 struct weston_keyboard_grab *grab;
827 struct weston_keyboard *keyboard;
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100828
Derek Foreman1281a362015-07-31 16:55:32 -0500829 keyboard = weston_seat_get_keyboard(context->input_method->seat);
830 if (!keyboard)
Jan Arne Petersena75a7892013-01-16 21:26:50 +0100831 return;
832
Derek Foreman1281a362015-07-31 16:55:32 -0500833 grab = &keyboard->input_method_grab;
Derek Foremanf0aaa412014-12-08 10:48:29 -0600834 keyboard = grab->keyboard;
835 if (!keyboard)
836 return;
837
838 if (keyboard->grab == grab)
839 weston_keyboard_end_grab(keyboard);
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100840
Jan Arne Petersena75a7892013-01-16 21:26:50 +0100841 keyboard->input_method_resource = NULL;
842}
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100843
844static void
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200845unbind_input_method(struct wl_resource *resource)
846{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500847 struct input_method *input_method = wl_resource_get_user_data(resource);
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200848
849 input_method->input_method_binding = NULL;
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200850 input_method->context = NULL;
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200851}
852
853static void
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200854bind_input_method(struct wl_client *client,
855 void *data,
856 uint32_t version,
857 uint32_t id)
858{
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200859 struct input_method *input_method = data;
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100860 struct text_backend *text_backend = input_method->text_backend;
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200861 struct wl_resource *resource;
862
Jason Ekstranda85118c2013-06-27 20:17:02 -0500863 resource =
Jonas Ådahlb57f4722015-11-17 16:00:30 +0800864 wl_resource_create(client,
865 &zwp_input_method_v1_interface, 1, id);
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200866
Jan Arne Petersenb41531a2013-04-18 16:47:31 +0200867 if (input_method->input_method_binding != NULL) {
Murray Calavera972d1af2015-06-09 20:29:28 +0000868 wl_resource_post_error(resource,
869 WL_DISPLAY_ERROR_INVALID_OBJECT,
Jan Arne Petersenb41531a2013-04-18 16:47:31 +0200870 "interface object already bound");
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200871 return;
872 }
873
Jan Arne Petersenb41531a2013-04-18 16:47:31 +0200874 if (text_backend->input_method.client != client) {
Murray Calavera972d1af2015-06-09 20:29:28 +0000875 wl_resource_post_error(resource,
876 WL_DISPLAY_ERROR_INVALID_OBJECT,
877 "permission to bind "
878 "input_method denied");
Jan Arne Petersenb41531a2013-04-18 16:47:31 +0200879 return;
880 }
881
Jason Ekstranda85118c2013-06-27 20:17:02 -0500882 wl_resource_set_implementation(resource, NULL, input_method,
883 unbind_input_method);
Jan Arne Petersenb41531a2013-04-18 16:47:31 +0200884 input_method->input_method_binding = resource;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200885}
886
887static void
888input_method_notifier_destroy(struct wl_listener *listener, void *data)
889{
Kristian Høgsbergf97f3792012-07-22 11:51:42 -0400890 struct input_method *input_method =
891 container_of(listener, struct input_method, destroy_listener);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200892
Derek Foreman0f299232015-05-08 17:08:41 -0500893 if (input_method->input)
Derek Foreman516d6032015-05-08 17:08:40 -0500894 deactivate_input_method(input_method);
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200895
Kristian Høgsberg919cddb2013-07-08 19:03:57 -0400896 wl_global_destroy(input_method->input_method_global);
Rob Bradfordead3ef82013-07-24 16:57:32 +0100897 wl_list_remove(&input_method->destroy_listener.link);
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200898
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200899 free(input_method);
900}
901
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +0200902static void
903handle_keyboard_focus(struct wl_listener *listener, void *data)
904{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400905 struct weston_keyboard *keyboard = data;
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +0200906 struct input_method *input_method =
Murray Calavera972d1af2015-06-09 20:29:28 +0000907 container_of(listener, struct input_method,
908 keyboard_focus_listener);
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400909 struct weston_surface *surface = keyboard->focus;
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +0200910
Derek Foreman0f299232015-05-08 17:08:41 -0500911 if (!input_method->input)
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +0200912 return;
913
Derek Foreman0f299232015-05-08 17:08:41 -0500914 if (!surface || input_method->input->surface != surface)
Derek Foreman516d6032015-05-08 17:08:40 -0500915 deactivate_input_method(input_method);
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +0200916}
917
918static void
919input_method_init_seat(struct weston_seat *seat)
920{
Derek Foreman1281a362015-07-31 16:55:32 -0500921 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
922
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +0200923 if (seat->input_method->focus_listener_initialized)
924 return;
925
Derek Foreman1281a362015-07-31 16:55:32 -0500926 if (keyboard) {
Murray Calavera972d1af2015-06-09 20:29:28 +0000927 seat->input_method->keyboard_focus_listener.notify =
928 handle_keyboard_focus;
Derek Foreman1281a362015-07-31 16:55:32 -0500929 wl_signal_add(&keyboard->focus_signal,
Murray Calavera972d1af2015-06-09 20:29:28 +0000930 &seat->input_method->keyboard_focus_listener);
Derek Foreman1281a362015-07-31 16:55:32 -0500931 keyboard->input_method_grab.interface =
Murray Calavera972d1af2015-06-09 20:29:28 +0000932 &input_method_context_grab;
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +0200933 }
934
Derek Foremanddc2c972015-07-15 13:00:32 -0500935 seat->input_method->focus_listener_initialized = true;
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +0200936}
937
Eduardo Lima (Etrunko)27337002013-05-14 13:09:31 -0300938static void launch_input_method(struct text_backend *text_backend);
939
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100940static void
Derek Foreman89dcea92015-06-25 15:49:49 -0500941respawn_input_method_process(struct text_backend *text_backend)
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200942{
Alexandros Frantzis409b01f2017-11-16 18:21:01 +0200943 struct timespec time;
944 int64_t tdiff;
Eduardo Lima (Etrunko)27337002013-05-14 13:09:31 -0300945
946 /* if input_method dies more than 5 times in 10 seconds, give up */
Alexandros Frantzis409b01f2017-11-16 18:21:01 +0200947 weston_compositor_get_time(&time);
948 tdiff = timespec_sub_to_msec(&time,
949 &text_backend->input_method.deathstamp);
950 if (tdiff > 10000) {
Eduardo Lima (Etrunko)27337002013-05-14 13:09:31 -0300951 text_backend->input_method.deathstamp = time;
952 text_backend->input_method.deathcount = 0;
953 }
954
955 text_backend->input_method.deathcount++;
956 if (text_backend->input_method.deathcount > 5) {
Derek Foreman89dcea92015-06-25 15:49:49 -0500957 weston_log("input_method disconnected, giving up.\n");
Eduardo Lima (Etrunko)27337002013-05-14 13:09:31 -0300958 return;
959 }
960
Derek Foreman89dcea92015-06-25 15:49:49 -0500961 weston_log("input_method disconnected, respawning...\n");
Eduardo Lima (Etrunko)27337002013-05-14 13:09:31 -0300962 launch_input_method(text_backend);
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100963}
964
965static void
Derek Foreman89dcea92015-06-25 15:49:49 -0500966input_method_client_notifier(struct wl_listener *listener, void *data)
967{
968 struct text_backend *text_backend;
969
970 text_backend = container_of(listener, struct text_backend,
971 client_listener);
972
973 text_backend->input_method.client = NULL;
974 respawn_input_method_process(text_backend);
975}
976
977static void
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100978launch_input_method(struct text_backend *text_backend)
979{
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100980 if (!text_backend->input_method.path)
981 return;
982
Murray Calaveraf65f89b2015-06-09 20:28:06 +0000983 if (strcmp(text_backend->input_method.path, "") == 0)
984 return;
985
Murray Calavera972d1af2015-06-09 20:29:28 +0000986 text_backend->input_method.client =
Derek Foreman89dcea92015-06-25 15:49:49 -0500987 weston_client_start(text_backend->compositor,
988 text_backend->input_method.path);
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100989
Derek Foreman89dcea92015-06-25 15:49:49 -0500990 if (!text_backend->input_method.client) {
Murray Calavera972d1af2015-06-09 20:29:28 +0000991 weston_log("not able to start %s\n",
992 text_backend->input_method.path);
Derek Foreman89dcea92015-06-25 15:49:49 -0500993 return;
994 }
995
996 text_backend->client_listener.notify = input_method_client_notifier;
997 wl_client_add_destroy_listener(text_backend->input_method.client,
998 &text_backend->client_listener);
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100999}
1000
1001static void
Murray Calavera25881242015-06-10 21:15:30 +00001002text_backend_seat_created(struct text_backend *text_backend,
1003 struct weston_seat *seat)
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001004{
Jan Arne Petersen1f17be42012-06-21 21:52:18 +02001005 struct input_method *input_method;
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001006 struct weston_compositor *ec = seat->compositor;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +02001007
Bryce Harringtonde16d892014-11-20 22:21:57 -08001008 input_method = zalloc(sizeof *input_method);
1009 if (input_method == NULL)
1010 return;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +02001011
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +02001012 input_method->seat = seat;
Derek Foreman0f299232015-05-08 17:08:41 -05001013 input_method->input = NULL;
Derek Foremanddc2c972015-07-15 13:00:32 -05001014 input_method->focus_listener_initialized = false;
Jan Arne Petersen620cd622012-09-09 23:08:32 +02001015 input_method->context = NULL;
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001016 input_method->text_backend = text_backend;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +02001017
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +02001018 input_method->input_method_global =
Jonas Ådahlb57f4722015-11-17 16:00:30 +08001019 wl_global_create(ec->wl_display,
1020 &zwp_input_method_v1_interface, 1,
Kristian Høgsberg919cddb2013-07-08 19:03:57 -04001021 input_method, bind_input_method);
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +02001022
Jan Arne Petersen1f17be42012-06-21 21:52:18 +02001023 input_method->destroy_listener.notify = input_method_notifier_destroy;
Kristian Høgsberg49124542013-05-06 22:27:40 -04001024 wl_signal_add(&seat->destroy_signal, &input_method->destroy_listener);
Jan Arne Petersene829adc2012-08-10 16:47:22 +02001025
1026 seat->input_method = input_method;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +02001027}
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +02001028
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001029static void
Murray Calavera25881242015-06-10 21:15:30 +00001030handle_seat_created(struct wl_listener *listener, void *data)
1031{
1032 struct weston_seat *seat = data;
1033 struct text_backend *text_backend =
1034 container_of(listener, struct text_backend,
1035 seat_created_listener);
1036
1037 text_backend_seat_created(text_backend, seat);
1038}
1039
1040static void
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001041text_backend_configuration(struct text_backend *text_backend)
1042{
Giulio Camuffod52f3b72016-06-02 21:48:11 +03001043 struct weston_config *config = wet_get_config(text_backend->compositor);
Kristian Høgsberg00fd7b82013-05-23 21:45:51 -04001044 struct weston_config_section *section;
Derek Foremanc7210432014-08-21 11:32:38 -05001045 char *client;
Pekka Paalanen974c0942014-09-05 14:45:09 +03001046 int ret;
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001047
Giulio Camuffod52f3b72016-06-02 21:48:11 +03001048 section = weston_config_get_section(config,
Kristian Høgsberg00fd7b82013-05-23 21:45:51 -04001049 "input-method", NULL, NULL);
Pekka Paalanen974c0942014-09-05 14:45:09 +03001050 ret = asprintf(&client, "%s/weston-keyboard",
1051 weston_config_get_libexec_dir());
1052 if (ret < 0)
1053 client = NULL;
Kristian Høgsberg00fd7b82013-05-23 21:45:51 -04001054 weston_config_section_get_string(section, "path",
1055 &text_backend->input_method.path,
Derek Foremanc7210432014-08-21 11:32:38 -05001056 client);
1057 free(client);
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001058}
1059
Pekka Paalanenaa9536a2015-06-24 16:09:17 +03001060WL_EXPORT void
1061text_backend_destroy(struct text_backend *text_backend)
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001062{
Derek Foreman89dcea92015-06-25 15:49:49 -05001063 if (text_backend->input_method.client) {
1064 /* disable respawn */
1065 wl_list_remove(&text_backend->client_listener.link);
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001066 wl_client_destroy(text_backend->input_method.client);
Derek Foreman89dcea92015-06-25 15:49:49 -05001067 }
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001068
1069 free(text_backend->input_method.path);
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001070 free(text_backend);
1071}
1072
Pekka Paalanenaa9536a2015-06-24 16:09:17 +03001073WL_EXPORT struct text_backend *
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001074text_backend_init(struct weston_compositor *ec)
1075{
1076 struct text_backend *text_backend;
Murray Calavera25881242015-06-10 21:15:30 +00001077 struct weston_seat *seat;
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001078
Bryce Harringtonde16d892014-11-20 22:21:57 -08001079 text_backend = zalloc(sizeof(*text_backend));
1080 if (text_backend == NULL)
Pekka Paalanenaa9536a2015-06-24 16:09:17 +03001081 return NULL;
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001082
1083 text_backend->compositor = ec;
1084
Murray Calavera25881242015-06-10 21:15:30 +00001085 text_backend_configuration(text_backend);
1086
1087 wl_list_for_each(seat, &ec->seat_list, link)
1088 text_backend_seat_created(text_backend, seat);
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001089 text_backend->seat_created_listener.notify = handle_seat_created;
1090 wl_signal_add(&ec->seat_created_signal,
1091 &text_backend->seat_created_listener);
1092
Jan Arne Petersen78d00e42013-04-18 16:47:24 +02001093 text_input_manager_create(ec);
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001094
Derek Foremanb4bacd22015-06-25 15:49:47 -05001095 launch_input_method(text_backend);
1096
Pekka Paalanenaa9536a2015-06-24 16:09:17 +03001097 return text_backend;
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001098}