blob: 5cd994cb1bd9ef86aa6c72f3333a802994bb8a03 [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
Pekka Paalanen3d5d9472019-03-28 16:28:47 +020036#include <libweston/libweston.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;
Takuro Ashie5ff978a2021-09-15 13:54:29 +0900106 bool overlay_keyboard;
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100107 struct wl_client *client;
Eduardo Lima (Etrunko)27337002013-05-14 13:09:31 -0300108
109 unsigned deathcount;
Alexandros Frantzis409b01f2017-11-16 18:21:01 +0200110 struct timespec deathstamp;
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100111 } input_method;
112
Derek Foreman89dcea92015-06-25 15:49:49 -0500113 struct wl_listener client_listener;
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100114 struct wl_listener seat_created_listener;
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100115};
116
Derek Foremancb5fcea2014-12-05 15:38:37 -0600117static void
Derek Foreman0f299232015-05-08 17:08:41 -0500118input_method_context_create(struct text_input *input,
Derek Foremancb5fcea2014-12-05 15:38:37 -0600119 struct input_method *input_method);
120static void
121input_method_context_end_keyboard_grab(struct input_method_context *context);
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200122
Derek Foremancb5fcea2014-12-05 15:38:37 -0600123static void
124input_method_init_seat(struct weston_seat *seat);
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +0200125
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200126static void
Derek Foreman516d6032015-05-08 17:08:40 -0500127deactivate_input_method(struct input_method *input_method)
Philipp Brüschweiler17467812012-07-11 22:25:30 +0200128{
Derek Foreman0f299232015-05-08 17:08:41 -0500129 struct text_input *text_input = input_method->input;
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200130 struct weston_compositor *ec = text_input->ec;
Philipp Brüschweiler17467812012-07-11 22:25:30 +0200131
Derek Foreman516d6032015-05-08 17:08:40 -0500132 if (input_method->context && input_method->input_method_binding) {
133 input_method_context_end_keyboard_grab(input_method->context);
Jonas Ådahlb57f4722015-11-17 16:00:30 +0800134 zwp_input_method_v1_send_deactivate(
Murray Calavera972d1af2015-06-09 20:29:28 +0000135 input_method->input_method_binding,
136 input_method->context->resource);
Daniel Stone97863d62016-11-10 15:47:56 +0000137 input_method->context->input = NULL;
Philipp Brüschweiler17467812012-07-11 22:25:30 +0200138 }
Derek Foreman516d6032015-05-08 17:08:40 -0500139
140 wl_list_remove(&input_method->link);
Derek Foreman0f299232015-05-08 17:08:41 -0500141 input_method->input = NULL;
Derek Foreman516d6032015-05-08 17:08:40 -0500142 input_method->context = NULL;
143
144 if (wl_list_empty(&text_input->input_methods) &&
Joshua Wattdd616252017-06-24 16:03:41 -0500145 text_input->input_panel_visible &&
146 text_input->manager->current_text_input == text_input) {
Derek Foreman516d6032015-05-08 17:08:40 -0500147 wl_signal_emit(&ec->hide_input_panel_signal, ec);
148 text_input->input_panel_visible = false;
Derek Foreman516d6032015-05-08 17:08:40 -0500149 }
Joshua Wattdd616252017-06-24 16:03:41 -0500150
151 if (text_input->manager->current_text_input == text_input)
152 text_input->manager->current_text_input = NULL;
153
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800154 zwp_text_input_v1_send_leave(text_input->resource);
Philipp Brüschweiler17467812012-07-11 22:25:30 +0200155}
156
157static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200158destroy_text_input(struct wl_resource *resource)
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200159{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500160 struct text_input *text_input = wl_resource_get_user_data(resource);
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200161 struct input_method *input_method, *next;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200162
Murray Calavera972d1af2015-06-09 20:29:28 +0000163 wl_list_for_each_safe(input_method, next,
164 &text_input->input_methods, link)
Derek Foreman516d6032015-05-08 17:08:40 -0500165 deactivate_input_method(input_method);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200166
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200167 free(text_input);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200168}
169
170static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200171text_input_set_surrounding_text(struct wl_client *client,
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200172 struct wl_resource *resource,
Jan Arne Petersencb08f4d2012-09-09 23:08:40 +0200173 const char *text,
174 uint32_t cursor,
175 uint32_t anchor)
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200176{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500177 struct text_input *text_input = wl_resource_get_user_data(resource);
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200178 struct input_method *input_method, *next;
179
Murray Calavera972d1af2015-06-09 20:29:28 +0000180 wl_list_for_each_safe(input_method, next,
181 &text_input->input_methods, link) {
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200182 if (!input_method->context)
183 continue;
Jonas Ådahlb57f4722015-11-17 16:00:30 +0800184 zwp_input_method_context_v1_send_surrounding_text(
Murray Calavera972d1af2015-06-09 20:29:28 +0000185 input_method->context->resource, text, cursor, anchor);
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200186 }
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200187}
188
189static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200190text_input_activate(struct wl_client *client,
Jan Arne Petersencc75ec12013-04-18 16:47:39 +0200191 struct wl_resource *resource,
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200192 struct wl_resource *seat,
193 struct wl_resource *surface)
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200194{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500195 struct text_input *text_input = wl_resource_get_user_data(resource);
Jason Ekstrand44a38632013-06-14 10:08:00 -0500196 struct weston_seat *weston_seat = wl_resource_get_user_data(seat);
Alexandros Frantzis8480d132018-02-15 13:07:09 +0200197 struct input_method *input_method;
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200198 struct weston_compositor *ec = text_input->ec;
Derek Foreman516d6032015-05-08 17:08:40 -0500199 struct text_input *current;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200200
Alexandros Frantzis8480d132018-02-15 13:07:09 +0200201 if (!weston_seat)
202 return;
203
204 input_method = weston_seat->input_method;
Derek Foreman0f299232015-05-08 17:08:41 -0500205 if (input_method->input == text_input)
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200206 return;
Jan Arne Petersende3b6a12012-08-10 16:47:21 +0200207
Derek Foreman0f299232015-05-08 17:08:41 -0500208 if (input_method->input)
Derek Foreman516d6032015-05-08 17:08:40 -0500209 deactivate_input_method(input_method);
Jan Arne Petersende3b6a12012-08-10 16:47:21 +0200210
Derek Foreman0f299232015-05-08 17:08:41 -0500211 input_method->input = text_input;
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200212 wl_list_insert(&text_input->input_methods, &input_method->link);
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +0200213 input_method_init_seat(weston_seat);
214
Jason Ekstrand0f2ef7e2013-06-14 10:07:53 -0500215 text_input->surface = wl_resource_get_user_data(surface);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200216
Jan Arne Petersen00191c72013-04-18 16:47:33 +0200217 input_method_context_create(text_input, input_method);
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200218
Joshua Wattdd616252017-06-24 16:03:41 -0500219 current = text_input->manager->current_text_input;
Derek Foreman516d6032015-05-08 17:08:40 -0500220
221 if (current && current != text_input) {
222 current->input_panel_visible = false;
223 wl_signal_emit(&ec->hide_input_panel_signal, ec);
Derek Foreman516d6032015-05-08 17:08:40 -0500224 }
225
Jan Arne Petersen14da96b2013-04-18 16:47:28 +0200226 if (text_input->input_panel_visible) {
Murray Calavera972d1af2015-06-09 20:29:28 +0000227 wl_signal_emit(&ec->show_input_panel_signal,
228 text_input->surface);
229 wl_signal_emit(&ec->update_input_panel_signal,
230 &text_input->cursor_rectangle);
Jan Arne Petersen14da96b2013-04-18 16:47:28 +0200231 }
Joshua Wattdd616252017-06-24 16:03:41 -0500232 text_input->manager->current_text_input = text_input;
Jan Arne Petersende3b6a12012-08-10 16:47:21 +0200233
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800234 zwp_text_input_v1_send_enter(text_input->resource,
235 text_input->surface->resource);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200236}
237
238static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200239text_input_deactivate(struct wl_client *client,
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200240 struct wl_resource *resource,
241 struct wl_resource *seat)
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200242{
Jason Ekstrand44a38632013-06-14 10:08:00 -0500243 struct weston_seat *weston_seat = wl_resource_get_user_data(seat);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200244
Alexandros Frantzis8480d132018-02-15 13:07:09 +0200245 if (weston_seat && weston_seat->input_method->input)
Derek Foreman516d6032015-05-08 17:08:40 -0500246 deactivate_input_method(weston_seat->input_method);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200247}
248
249static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200250text_input_reset(struct wl_client *client,
Jan Arne Petersen00191c72013-04-18 16:47:33 +0200251 struct wl_resource *resource)
Jan Arne Petersenc1e481e2012-09-09 23:08:46 +0200252{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500253 struct text_input *text_input = wl_resource_get_user_data(resource);
Jan Arne Petersenc1e481e2012-09-09 23:08:46 +0200254 struct input_method *input_method, *next;
255
Murray Calavera972d1af2015-06-09 20:29:28 +0000256 wl_list_for_each_safe(input_method, next,
257 &text_input->input_methods, link) {
Jan Arne Petersenc1e481e2012-09-09 23:08:46 +0200258 if (!input_method->context)
259 continue;
Jonas Ådahlb57f4722015-11-17 16:00:30 +0800260 zwp_input_method_context_v1_send_reset(
Murray Calavera972d1af2015-06-09 20:29:28 +0000261 input_method->context->resource);
Jan Arne Petersenc1e481e2012-09-09 23:08:46 +0200262 }
263}
264
265static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200266text_input_set_cursor_rectangle(struct wl_client *client,
Jan Arne Petersen7ef8eff2013-04-18 16:47:23 +0200267 struct wl_resource *resource,
268 int32_t x,
269 int32_t y,
270 int32_t width,
271 int32_t height)
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200272{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500273 struct text_input *text_input = wl_resource_get_user_data(resource);
Jan Arne Petersen14da96b2013-04-18 16:47:28 +0200274 struct weston_compositor *ec = text_input->ec;
275
276 text_input->cursor_rectangle.x1 = x;
277 text_input->cursor_rectangle.y1 = y;
278 text_input->cursor_rectangle.x2 = x + width;
279 text_input->cursor_rectangle.y2 = y + height;
280
Murray Calavera972d1af2015-06-09 20:29:28 +0000281 wl_signal_emit(&ec->update_input_panel_signal,
282 &text_input->cursor_rectangle);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200283}
284
285static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200286text_input_set_content_type(struct wl_client *client,
Jan Arne Petersen26ffa812013-01-16 21:26:43 +0100287 struct wl_resource *resource,
288 uint32_t hint,
289 uint32_t purpose)
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200290{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500291 struct text_input *text_input = wl_resource_get_user_data(resource);
Jan Arne Petersen26ffa812013-01-16 21:26:43 +0100292 struct input_method *input_method, *next;
293
Murray Calavera972d1af2015-06-09 20:29:28 +0000294 wl_list_for_each_safe(input_method, next,
295 &text_input->input_methods, link) {
Jan Arne Petersen26ffa812013-01-16 21:26:43 +0100296 if (!input_method->context)
297 continue;
Jonas Ådahlb57f4722015-11-17 16:00:30 +0800298 zwp_input_method_context_v1_send_content_type(
Murray Calavera972d1af2015-06-09 20:29:28 +0000299 input_method->context->resource, hint, purpose);
Jan Arne Petersen26ffa812013-01-16 21:26:43 +0100300 }
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200301}
302
Jan Arne Petersenadfedc12013-01-16 21:26:46 +0100303static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200304text_input_invoke_action(struct wl_client *client,
Jan Arne Petersenadfedc12013-01-16 21:26:46 +0100305 struct wl_resource *resource,
306 uint32_t button,
307 uint32_t index)
308{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500309 struct text_input *text_input = wl_resource_get_user_data(resource);
Jan Arne Petersenadfedc12013-01-16 21:26:46 +0100310 struct input_method *input_method, *next;
311
Murray Calavera972d1af2015-06-09 20:29:28 +0000312 wl_list_for_each_safe(input_method, next,
313 &text_input->input_methods, link) {
Jan Arne Petersenadfedc12013-01-16 21:26:46 +0100314 if (!input_method->context)
315 continue;
Jonas Ådahlb57f4722015-11-17 16:00:30 +0800316 zwp_input_method_context_v1_send_invoke_action(
Murray Calavera972d1af2015-06-09 20:29:28 +0000317 input_method->context->resource, button, index);
Jan Arne Petersenadfedc12013-01-16 21:26:46 +0100318 }
319}
320
Jan Arne Petersen0eabcaa2013-01-31 15:52:20 +0100321static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200322text_input_commit_state(struct wl_client *client,
Jan Arne Petersen00191c72013-04-18 16:47:33 +0200323 struct wl_resource *resource,
324 uint32_t serial)
Jan Arne Petersen0eabcaa2013-01-31 15:52:20 +0100325{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500326 struct text_input *text_input = wl_resource_get_user_data(resource);
Jan Arne Petersen0eabcaa2013-01-31 15:52:20 +0100327 struct input_method *input_method, *next;
328
Murray Calavera972d1af2015-06-09 20:29:28 +0000329 wl_list_for_each_safe(input_method, next,
330 &text_input->input_methods, link) {
Jan Arne Petersen0eabcaa2013-01-31 15:52:20 +0100331 if (!input_method->context)
332 continue;
Jonas Ådahlb57f4722015-11-17 16:00:30 +0800333 zwp_input_method_context_v1_send_commit_state(
Murray Calavera972d1af2015-06-09 20:29:28 +0000334 input_method->context->resource, serial);
Jan Arne Petersen0eabcaa2013-01-31 15:52:20 +0100335 }
336}
337
Jan Arne Petersen61381972013-01-31 15:52:21 +0100338static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200339text_input_show_input_panel(struct wl_client *client,
Jan Arne Petersen61381972013-01-31 15:52:21 +0100340 struct wl_resource *resource)
341{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500342 struct text_input *text_input = wl_resource_get_user_data(resource);
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200343 struct weston_compositor *ec = text_input->ec;
Jan Arne Petersen61381972013-01-31 15:52:21 +0100344
Derek Foremand09dbb32014-12-05 15:38:39 -0600345 text_input->input_panel_visible = true;
Jan Arne Petersen61381972013-01-31 15:52:21 +0100346
Joshua Wattdd616252017-06-24 16:03:41 -0500347 if (!wl_list_empty(&text_input->input_methods) &&
348 text_input == text_input->manager->current_text_input) {
Murray Calavera972d1af2015-06-09 20:29:28 +0000349 wl_signal_emit(&ec->show_input_panel_signal,
350 text_input->surface);
351 wl_signal_emit(&ec->update_input_panel_signal,
352 &text_input->cursor_rectangle);
Jan Arne Petersen14da96b2013-04-18 16:47:28 +0200353 }
Jan Arne Petersen61381972013-01-31 15:52:21 +0100354}
355
356static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200357text_input_hide_input_panel(struct wl_client *client,
Jan Arne Petersen61381972013-01-31 15:52:21 +0100358 struct wl_resource *resource)
359{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500360 struct text_input *text_input = wl_resource_get_user_data(resource);
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200361 struct weston_compositor *ec = text_input->ec;
Jan Arne Petersen61381972013-01-31 15:52:21 +0100362
Derek Foremand09dbb32014-12-05 15:38:39 -0600363 text_input->input_panel_visible = false;
Jan Arne Petersen61381972013-01-31 15:52:21 +0100364
Derek Foreman516d6032015-05-08 17:08:40 -0500365 if (!wl_list_empty(&text_input->input_methods) &&
Joshua Wattdd616252017-06-24 16:03:41 -0500366 text_input == text_input->manager->current_text_input)
Jan Arne Petersen61381972013-01-31 15:52:21 +0100367 wl_signal_emit(&ec->hide_input_panel_signal, ec);
368}
369
Jan Arne Petersenece6b5a2013-04-18 16:47:15 +0200370static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200371text_input_set_preferred_language(struct wl_client *client,
Jan Arne Petersenece6b5a2013-04-18 16:47:15 +0200372 struct wl_resource *resource,
373 const char *language)
374{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500375 struct text_input *text_input = wl_resource_get_user_data(resource);
Jan Arne Petersenece6b5a2013-04-18 16:47:15 +0200376 struct input_method *input_method, *next;
377
Murray Calavera972d1af2015-06-09 20:29:28 +0000378 wl_list_for_each_safe(input_method, next,
379 &text_input->input_methods, link) {
Jan Arne Petersenece6b5a2013-04-18 16:47:15 +0200380 if (!input_method->context)
381 continue;
Jonas Ådahlb57f4722015-11-17 16:00:30 +0800382 zwp_input_method_context_v1_send_preferred_language(
Murray Calavera972d1af2015-06-09 20:29:28 +0000383 input_method->context->resource, language);
Jan Arne Petersenece6b5a2013-04-18 16:47:15 +0200384 }
385}
386
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800387static const struct zwp_text_input_v1_interface text_input_implementation = {
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200388 text_input_activate,
389 text_input_deactivate,
390 text_input_show_input_panel,
391 text_input_hide_input_panel,
392 text_input_reset,
393 text_input_set_surrounding_text,
394 text_input_set_content_type,
395 text_input_set_cursor_rectangle,
396 text_input_set_preferred_language,
397 text_input_commit_state,
398 text_input_invoke_action
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200399};
400
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200401static void text_input_manager_create_text_input(struct wl_client *client,
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200402 struct wl_resource *resource,
Jan Arne Petersen4c265182012-09-09 23:08:30 +0200403 uint32_t id)
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200404{
Murray Calavera972d1af2015-06-09 20:29:28 +0000405 struct text_input_manager *text_input_manager =
406 wl_resource_get_user_data(resource);
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200407 struct text_input *text_input;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200408
Bryce Harringtonde16d892014-11-20 22:21:57 -0800409 text_input = zalloc(sizeof *text_input);
410 if (text_input == NULL)
411 return;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200412
Jason Ekstranda85118c2013-06-27 20:17:02 -0500413 text_input->resource =
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800414 wl_resource_create(client, &zwp_text_input_v1_interface, 1, id);
Jason Ekstranda85118c2013-06-27 20:17:02 -0500415 wl_resource_set_implementation(text_input->resource,
416 &text_input_implementation,
417 text_input, destroy_text_input);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200418
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200419 text_input->ec = text_input_manager->ec;
Derek Foreman516d6032015-05-08 17:08:40 -0500420 text_input->manager = text_input_manager;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200421
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200422 wl_list_init(&text_input->input_methods);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200423};
424
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800425static const struct zwp_text_input_manager_v1_interface manager_implementation = {
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200426 text_input_manager_create_text_input
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200427};
428
429static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200430bind_text_input_manager(struct wl_client *client,
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200431 void *data,
432 uint32_t version,
433 uint32_t id)
434{
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200435 struct text_input_manager *text_input_manager = data;
Jason Ekstranda85118c2013-06-27 20:17:02 -0500436 struct wl_resource *resource;
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200437
Jason Ekstranda85118c2013-06-27 20:17:02 -0500438 /* No checking for duplicate binding necessary. */
439 resource =
440 wl_resource_create(client,
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800441 &zwp_text_input_manager_v1_interface, 1, id);
Jason Ekstranda85118c2013-06-27 20:17:02 -0500442 if (resource)
443 wl_resource_set_implementation(resource,
Murray Calavera972d1af2015-06-09 20:29:28 +0000444 &manager_implementation,
Jason Ekstranda85118c2013-06-27 20:17:02 -0500445 text_input_manager, NULL);
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200446}
447
448static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200449text_input_manager_notifier_destroy(struct wl_listener *listener, void *data)
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200450{
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200451 struct text_input_manager *text_input_manager =
Murray Calavera972d1af2015-06-09 20:29:28 +0000452 container_of(listener,
453 struct text_input_manager,
454 destroy_listener);
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200455
Harsha M Mb8b2c722018-08-07 19:05:02 +0530456 wl_list_remove(&text_input_manager->destroy_listener.link);
Kristian Høgsberg919cddb2013-07-08 19:03:57 -0400457 wl_global_destroy(text_input_manager->text_input_manager_global);
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200458
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200459 free(text_input_manager);
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200460}
461
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100462static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200463text_input_manager_create(struct weston_compositor *ec)
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200464{
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200465 struct text_input_manager *text_input_manager;
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200466
Bryce Harringtonde16d892014-11-20 22:21:57 -0800467 text_input_manager = zalloc(sizeof *text_input_manager);
468 if (text_input_manager == NULL)
469 return;
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200470
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200471 text_input_manager->ec = ec;
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200472
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200473 text_input_manager->text_input_manager_global =
Kristian Høgsberg919cddb2013-07-08 19:03:57 -0400474 wl_global_create(ec->wl_display,
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800475 &zwp_text_input_manager_v1_interface, 1,
Kristian Høgsberg919cddb2013-07-08 19:03:57 -0400476 text_input_manager, bind_text_input_manager);
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200477
Murray Calavera972d1af2015-06-09 20:29:28 +0000478 text_input_manager->destroy_listener.notify =
479 text_input_manager_notifier_destroy;
480 wl_signal_add(&ec->destroy_signal,
481 &text_input_manager->destroy_listener);
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200482}
483
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200484static void
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200485input_method_context_destroy(struct wl_client *client,
486 struct wl_resource *resource)
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200487{
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200488 wl_resource_destroy(resource);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200489}
490
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200491static void
492input_method_context_commit_string(struct wl_client *client,
493 struct wl_resource *resource,
Jan Arne Petersenc7d2a982013-01-16 21:26:39 +0100494 uint32_t serial,
Jan Arne Petersen1cc9e082013-01-31 15:52:23 +0100495 const char *text)
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200496{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500497 struct input_method_context *context =
498 wl_resource_get_user_data(resource);
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200499
Derek Foreman0f299232015-05-08 17:08:41 -0500500 if (context->input)
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800501 zwp_text_input_v1_send_commit_string(context->input->resource,
502 serial, text);
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200503}
504
Jan Arne Petersen43f4aa82012-09-09 23:08:43 +0200505static void
506input_method_context_preedit_string(struct wl_client *client,
Jan Arne Petersen46535312013-01-16 21:26:38 +0100507 struct wl_resource *resource,
Jan Arne Petersenc7d2a982013-01-16 21:26:39 +0100508 uint32_t serial,
Jan Arne Petersen46535312013-01-16 21:26:38 +0100509 const char *text,
510 const char *commit)
Jan Arne Petersen43f4aa82012-09-09 23:08:43 +0200511{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500512 struct input_method_context *context =
513 wl_resource_get_user_data(resource);
Jan Arne Petersen43f4aa82012-09-09 23:08:43 +0200514
Derek Foreman0f299232015-05-08 17:08:41 -0500515 if (context->input)
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800516 zwp_text_input_v1_send_preedit_string(context->input->resource,
517 serial, text, commit);
Jan Arne Petersen46535312013-01-16 21:26:38 +0100518}
519
520static void
521input_method_context_preedit_styling(struct wl_client *client,
522 struct wl_resource *resource,
523 uint32_t index,
524 uint32_t length,
525 uint32_t style)
526{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500527 struct input_method_context *context =
528 wl_resource_get_user_data(resource);
Jan Arne Petersen46535312013-01-16 21:26:38 +0100529
Derek Foreman0f299232015-05-08 17:08:41 -0500530 if (context->input)
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800531 zwp_text_input_v1_send_preedit_styling(context->input->resource,
532 index, length, style);
Jan Arne Petersen46535312013-01-16 21:26:38 +0100533}
534
535static void
536input_method_context_preedit_cursor(struct wl_client *client,
537 struct wl_resource *resource,
538 int32_t cursor)
539{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500540 struct input_method_context *context =
541 wl_resource_get_user_data(resource);
Jan Arne Petersen46535312013-01-16 21:26:38 +0100542
Derek Foreman0f299232015-05-08 17:08:41 -0500543 if (context->input)
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800544 zwp_text_input_v1_send_preedit_cursor(context->input->resource,
545 cursor);
Jan Arne Petersen43f4aa82012-09-09 23:08:43 +0200546}
547
Jan Arne Petersene202bae2012-09-09 23:08:44 +0200548static void
549input_method_context_delete_surrounding_text(struct wl_client *client,
550 struct wl_resource *resource,
551 int32_t index,
552 uint32_t length)
553{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500554 struct input_method_context *context =
555 wl_resource_get_user_data(resource);
Jan Arne Petersene202bae2012-09-09 23:08:44 +0200556
Derek Foreman0f299232015-05-08 17:08:41 -0500557 if (context->input)
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800558 zwp_text_input_v1_send_delete_surrounding_text(
Murray Calavera972d1af2015-06-09 20:29:28 +0000559 context->input->resource, index, length);
Jan Arne Petersene202bae2012-09-09 23:08:44 +0200560}
561
Jan Arne Petersence8a4432012-09-09 23:08:45 +0200562static void
Jan Arne Petersen1cc9e082013-01-31 15:52:23 +0100563input_method_context_cursor_position(struct wl_client *client,
564 struct wl_resource *resource,
Jan Arne Petersen1cc9e082013-01-31 15:52:23 +0100565 int32_t index,
566 int32_t anchor)
567{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500568 struct input_method_context *context =
569 wl_resource_get_user_data(resource);
Jan Arne Petersen1cc9e082013-01-31 15:52:23 +0100570
Derek Foreman0f299232015-05-08 17:08:41 -0500571 if (context->input)
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800572 zwp_text_input_v1_send_cursor_position(context->input->resource,
573 index, anchor);
Jan Arne Petersen1cc9e082013-01-31 15:52:23 +0100574}
575
576static void
Jan Arne Petersend9be93b2012-11-18 19:06:43 +0100577input_method_context_modifiers_map(struct wl_client *client,
578 struct wl_resource *resource,
579 struct wl_array *map)
Jan Arne Petersence8a4432012-09-09 23:08:45 +0200580{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500581 struct input_method_context *context =
582 wl_resource_get_user_data(resource);
Jan Arne Petersence8a4432012-09-09 23:08:45 +0200583
Derek Foreman0f299232015-05-08 17:08:41 -0500584 if (context->input)
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800585 zwp_text_input_v1_send_modifiers_map(context->input->resource,
586 map);
Jan Arne Petersend9be93b2012-11-18 19:06:43 +0100587}
588
589static void
590input_method_context_keysym(struct wl_client *client,
591 struct wl_resource *resource,
592 uint32_t serial,
593 uint32_t time,
594 uint32_t sym,
595 uint32_t state,
596 uint32_t modifiers)
597{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500598 struct input_method_context *context =
599 wl_resource_get_user_data(resource);
Jan Arne Petersend9be93b2012-11-18 19:06:43 +0100600
Derek Foreman0f299232015-05-08 17:08:41 -0500601 if (context->input)
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800602 zwp_text_input_v1_send_keysym(context->input->resource,
603 serial, time,
604 sym, state, modifiers);
Jan Arne Petersence8a4432012-09-09 23:08:45 +0200605}
606
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100607static void
608unbind_keyboard(struct wl_resource *resource)
609{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500610 struct input_method_context *context =
611 wl_resource_get_user_data(resource);
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100612
613 input_method_context_end_keyboard_grab(context);
614 context->keyboard = NULL;
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100615}
616
617static void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400618input_method_context_grab_key(struct weston_keyboard_grab *grab,
Alexandros Frantzis47e79c82017-11-16 18:20:57 +0200619 const struct timespec *time, uint32_t key,
620 uint32_t state_w)
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100621{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400622 struct weston_keyboard *keyboard = grab->keyboard;
Jan Arne Petersena75a7892013-01-16 21:26:50 +0100623 struct wl_display *display;
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100624 uint32_t serial;
Alexandros Frantzis47e79c82017-11-16 18:20:57 +0200625 uint32_t msecs;
Jan Arne Petersena75a7892013-01-16 21:26:50 +0100626
627 if (!keyboard->input_method_resource)
628 return;
629
Murray Calavera972d1af2015-06-09 20:29:28 +0000630 display = wl_client_get_display(
631 wl_resource_get_client(keyboard->input_method_resource));
Jan Arne Petersena75a7892013-01-16 21:26:50 +0100632 serial = wl_display_next_serial(display);
Alexandros Frantzis47e79c82017-11-16 18:20:57 +0200633 msecs = timespec_to_msec(time);
Jan Arne Petersena75a7892013-01-16 21:26:50 +0100634 wl_keyboard_send_key(keyboard->input_method_resource,
Alexandros Frantzis47e79c82017-11-16 18:20:57 +0200635 serial, msecs, key, state_w);
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100636}
637
638static void
Murray Calavera972d1af2015-06-09 20:29:28 +0000639input_method_context_grab_modifier(struct weston_keyboard_grab *grab,
640 uint32_t serial,
641 uint32_t mods_depressed,
642 uint32_t mods_latched,
643 uint32_t mods_locked,
644 uint32_t group)
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100645{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400646 struct weston_keyboard *keyboard = grab->keyboard;
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100647
Jan Arne Petersena75a7892013-01-16 21:26:50 +0100648 if (!keyboard->input_method_resource)
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100649 return;
650
Jan Arne Petersena75a7892013-01-16 21:26:50 +0100651 wl_keyboard_send_modifiers(keyboard->input_method_resource,
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100652 serial, mods_depressed, mods_latched,
653 mods_locked, group);
654}
655
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200656static void
657input_method_context_grab_cancel(struct weston_keyboard_grab *grab)
658{
659 weston_keyboard_end_grab(grab->keyboard);
660}
661
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400662static const struct weston_keyboard_grab_interface input_method_context_grab = {
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100663 input_method_context_grab_key,
664 input_method_context_grab_modifier,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200665 input_method_context_grab_cancel,
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100666};
667
668static void
669input_method_context_grab_keyboard(struct wl_client *client,
670 struct wl_resource *resource,
671 uint32_t id)
672{
Murray Calavera972d1af2015-06-09 20:29:28 +0000673 struct input_method_context *context =
674 wl_resource_get_user_data(resource);
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100675 struct wl_resource *cr;
676 struct weston_seat *seat = context->input_method->seat;
Derek Foreman1281a362015-07-31 16:55:32 -0500677 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100678
Takuro Ashie29d81c02021-08-16 14:51:45 +0900679 if (!keyboard)
680 return;
681
Jason Ekstranda85118c2013-06-27 20:17:02 -0500682 cr = wl_resource_create(client, &wl_keyboard_interface, 1, id);
683 wl_resource_set_implementation(cr, NULL, context, unbind_keyboard);
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100684
685 context->keyboard = cr;
686
Derek Foremanf8f7fd62017-06-28 11:41:43 -0500687 weston_keyboard_send_keymap(keyboard, cr);
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100688
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400689 if (keyboard->grab != &keyboard->default_grab) {
690 weston_keyboard_end_grab(keyboard);
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100691 }
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400692 weston_keyboard_start_grab(keyboard, &keyboard->input_method_grab);
Jan Arne Petersena75a7892013-01-16 21:26:50 +0100693 keyboard->input_method_resource = cr;
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100694}
695
Jan Arne Petersen337df952012-11-18 19:06:46 +0100696static void
697input_method_context_key(struct wl_client *client,
698 struct wl_resource *resource,
699 uint32_t serial,
700 uint32_t time,
701 uint32_t key,
702 uint32_t state_w)
703{
Murray Calavera972d1af2015-06-09 20:29:28 +0000704 struct input_method_context *context =
705 wl_resource_get_user_data(resource);
Jan Arne Petersen337df952012-11-18 19:06:46 +0100706 struct weston_seat *seat = context->input_method->seat;
Derek Foreman1281a362015-07-31 16:55:32 -0500707 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400708 struct weston_keyboard_grab *default_grab = &keyboard->default_grab;
Alexandros Frantzis47e79c82017-11-16 18:20:57 +0200709 struct timespec ts;
Jan Arne Petersen337df952012-11-18 19:06:46 +0100710
Alexandros Frantzis47e79c82017-11-16 18:20:57 +0200711 timespec_from_msec(&ts, time);
712
713 default_grab->interface->key(default_grab, &ts, key, state_w);
Jan Arne Petersen337df952012-11-18 19:06:46 +0100714}
715
716static void
717input_method_context_modifiers(struct wl_client *client,
718 struct wl_resource *resource,
719 uint32_t serial,
720 uint32_t mods_depressed,
721 uint32_t mods_latched,
722 uint32_t mods_locked,
723 uint32_t group)
724{
Murray Calavera972d1af2015-06-09 20:29:28 +0000725 struct input_method_context *context =
726 wl_resource_get_user_data(resource);
Jan Arne Petersen337df952012-11-18 19:06:46 +0100727
728 struct weston_seat *seat = context->input_method->seat;
Derek Foreman1281a362015-07-31 16:55:32 -0500729 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400730 struct weston_keyboard_grab *default_grab = &keyboard->default_grab;
Jan Arne Petersen337df952012-11-18 19:06:46 +0100731
732 default_grab->interface->modifiers(default_grab,
733 serial, mods_depressed,
734 mods_latched, mods_locked,
735 group);
736}
737
Jan Arne Petersenece6b5a2013-04-18 16:47:15 +0200738static void
739input_method_context_language(struct wl_client *client,
740 struct wl_resource *resource,
741 uint32_t serial,
742 const char *language)
743{
Murray Calavera972d1af2015-06-09 20:29:28 +0000744 struct input_method_context *context =
745 wl_resource_get_user_data(resource);
Jan Arne Petersenece6b5a2013-04-18 16:47:15 +0200746
Derek Foreman0f299232015-05-08 17:08:41 -0500747 if (context->input)
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800748 zwp_text_input_v1_send_language(context->input->resource,
749 serial, language);
Jan Arne Petersenece6b5a2013-04-18 16:47:15 +0200750}
751
752static void
753input_method_context_text_direction(struct wl_client *client,
754 struct wl_resource *resource,
755 uint32_t serial,
756 uint32_t direction)
757{
Murray Calavera972d1af2015-06-09 20:29:28 +0000758 struct input_method_context *context =
759 wl_resource_get_user_data(resource);
Jan Arne Petersenece6b5a2013-04-18 16:47:15 +0200760
Derek Foreman0f299232015-05-08 17:08:41 -0500761 if (context->input)
Jonas Ådahl3bcba342015-11-17 16:00:29 +0800762 zwp_text_input_v1_send_text_direction(context->input->resource,
763 serial, direction);
Jan Arne Petersenece6b5a2013-04-18 16:47:15 +0200764}
765
766
Jonas Ådahlb57f4722015-11-17 16:00:30 +0800767static const struct zwp_input_method_context_v1_interface context_implementation = {
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200768 input_method_context_destroy,
Jan Arne Petersen43f4aa82012-09-09 23:08:43 +0200769 input_method_context_commit_string,
770 input_method_context_preedit_string,
Jan Arne Petersen46535312013-01-16 21:26:38 +0100771 input_method_context_preedit_styling,
772 input_method_context_preedit_cursor,
Jan Arne Petersence8a4432012-09-09 23:08:45 +0200773 input_method_context_delete_surrounding_text,
Jan Arne Petersen1cc9e082013-01-31 15:52:23 +0100774 input_method_context_cursor_position,
Jan Arne Petersend9be93b2012-11-18 19:06:43 +0100775 input_method_context_modifiers_map,
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100776 input_method_context_keysym,
Jan Arne Petersen337df952012-11-18 19:06:46 +0100777 input_method_context_grab_keyboard,
778 input_method_context_key,
Jan Arne Petersenece6b5a2013-04-18 16:47:15 +0200779 input_method_context_modifiers,
780 input_method_context_language,
781 input_method_context_text_direction
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200782};
783
784static void
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200785destroy_input_method_context(struct wl_resource *resource)
786{
Murray Calavera972d1af2015-06-09 20:29:28 +0000787 struct input_method_context *context =
788 wl_resource_get_user_data(resource);
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200789
Murray Calavera972d1af2015-06-09 20:29:28 +0000790 if (context->keyboard)
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100791 wl_resource_destroy(context->keyboard);
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100792
Derek Foreman516d6032015-05-08 17:08:40 -0500793 if (context->input_method && context->input_method->context == context)
794 context->input_method->context = NULL;
795
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200796 free(context);
797}
798
799static void
Derek Foreman0f299232015-05-08 17:08:41 -0500800input_method_context_create(struct text_input *input,
Jan Arne Petersen00191c72013-04-18 16:47:33 +0200801 struct input_method *input_method)
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200802{
803 struct input_method_context *context;
Jason Ekstrand89d31992013-06-14 10:07:59 -0500804 struct wl_resource *binding;
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200805
806 if (!input_method->input_method_binding)
807 return;
808
Bryce Harringtonde16d892014-11-20 22:21:57 -0800809 context = zalloc(sizeof *context);
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200810 if (context == NULL)
811 return;
812
Jason Ekstrand89d31992013-06-14 10:07:59 -0500813 binding = input_method->input_method_binding;
Jason Ekstranda85118c2013-06-27 20:17:02 -0500814 context->resource =
815 wl_resource_create(wl_resource_get_client(binding),
Jonas Ådahlb57f4722015-11-17 16:00:30 +0800816 &zwp_input_method_context_v1_interface,
817 1, 0);
Jason Ekstranda85118c2013-06-27 20:17:02 -0500818 wl_resource_set_implementation(context->resource,
Murray Calavera972d1af2015-06-09 20:29:28 +0000819 &context_implementation,
Jason Ekstranda85118c2013-06-27 20:17:02 -0500820 context, destroy_input_method_context);
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200821
Derek Foreman0f299232015-05-08 17:08:41 -0500822 context->input = input;
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100823 context->input_method = input_method;
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200824 input_method->context = context;
825
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200826
Jonas Ådahlb57f4722015-11-17 16:00:30 +0800827 zwp_input_method_v1_send_activate(binding, context->resource);
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200828}
829
830static void
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100831input_method_context_end_keyboard_grab(struct input_method_context *context)
832{
Derek Foremanf0aaa412014-12-08 10:48:29 -0600833 struct weston_keyboard_grab *grab;
834 struct weston_keyboard *keyboard;
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100835
Derek Foreman1281a362015-07-31 16:55:32 -0500836 keyboard = weston_seat_get_keyboard(context->input_method->seat);
837 if (!keyboard)
Jan Arne Petersena75a7892013-01-16 21:26:50 +0100838 return;
839
Derek Foreman1281a362015-07-31 16:55:32 -0500840 grab = &keyboard->input_method_grab;
Derek Foremanf0aaa412014-12-08 10:48:29 -0600841 keyboard = grab->keyboard;
842 if (!keyboard)
843 return;
844
845 if (keyboard->grab == grab)
846 weston_keyboard_end_grab(keyboard);
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100847
Jan Arne Petersena75a7892013-01-16 21:26:50 +0100848 keyboard->input_method_resource = NULL;
849}
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100850
851static void
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200852unbind_input_method(struct wl_resource *resource)
853{
Jason Ekstrand89d31992013-06-14 10:07:59 -0500854 struct input_method *input_method = wl_resource_get_user_data(resource);
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200855
Pekka Paalanena49ca3d2021-05-07 15:58:10 +0300856 if (!input_method)
857 return;
858
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200859 input_method->input_method_binding = NULL;
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200860 input_method->context = NULL;
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200861}
862
863static void
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200864bind_input_method(struct wl_client *client,
865 void *data,
866 uint32_t version,
867 uint32_t id)
868{
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200869 struct input_method *input_method = data;
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100870 struct text_backend *text_backend = input_method->text_backend;
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200871 struct wl_resource *resource;
872
Jason Ekstranda85118c2013-06-27 20:17:02 -0500873 resource =
Jonas Ådahlb57f4722015-11-17 16:00:30 +0800874 wl_resource_create(client,
875 &zwp_input_method_v1_interface, 1, id);
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200876
Jan Arne Petersenb41531a2013-04-18 16:47:31 +0200877 if (input_method->input_method_binding != NULL) {
Murray Calavera972d1af2015-06-09 20:29:28 +0000878 wl_resource_post_error(resource,
879 WL_DISPLAY_ERROR_INVALID_OBJECT,
Jan Arne Petersenb41531a2013-04-18 16:47:31 +0200880 "interface object already bound");
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200881 return;
882 }
883
Jan Arne Petersenb41531a2013-04-18 16:47:31 +0200884 if (text_backend->input_method.client != client) {
Murray Calavera972d1af2015-06-09 20:29:28 +0000885 wl_resource_post_error(resource,
886 WL_DISPLAY_ERROR_INVALID_OBJECT,
887 "permission to bind "
888 "input_method denied");
Jan Arne Petersenb41531a2013-04-18 16:47:31 +0200889 return;
890 }
891
Jason Ekstranda85118c2013-06-27 20:17:02 -0500892 wl_resource_set_implementation(resource, NULL, input_method,
893 unbind_input_method);
Jan Arne Petersenb41531a2013-04-18 16:47:31 +0200894 input_method->input_method_binding = resource;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200895}
896
897static void
898input_method_notifier_destroy(struct wl_listener *listener, void *data)
899{
Kristian Høgsbergf97f3792012-07-22 11:51:42 -0400900 struct input_method *input_method =
901 container_of(listener, struct input_method, destroy_listener);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200902
Derek Foreman0f299232015-05-08 17:08:41 -0500903 if (input_method->input)
Derek Foreman516d6032015-05-08 17:08:40 -0500904 deactivate_input_method(input_method);
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200905
Pekka Paalanena49ca3d2021-05-07 15:58:10 +0300906 if (input_method->input_method_binding)
907 wl_resource_set_user_data(input_method->input_method_binding, NULL);
908
Kristian Høgsberg919cddb2013-07-08 19:03:57 -0400909 wl_global_destroy(input_method->input_method_global);
Rob Bradfordead3ef82013-07-24 16:57:32 +0100910 wl_list_remove(&input_method->destroy_listener.link);
Pekka Paalanena49ca3d2021-05-07 15:58:10 +0300911 input_method->seat->input_method = NULL;
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200912
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200913 free(input_method);
914}
915
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +0200916static void
917handle_keyboard_focus(struct wl_listener *listener, void *data)
918{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400919 struct weston_keyboard *keyboard = data;
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +0200920 struct input_method *input_method =
Murray Calavera972d1af2015-06-09 20:29:28 +0000921 container_of(listener, struct input_method,
922 keyboard_focus_listener);
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400923 struct weston_surface *surface = keyboard->focus;
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +0200924
Derek Foreman0f299232015-05-08 17:08:41 -0500925 if (!input_method->input)
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +0200926 return;
927
Derek Foreman0f299232015-05-08 17:08:41 -0500928 if (!surface || input_method->input->surface != surface)
Derek Foreman516d6032015-05-08 17:08:40 -0500929 deactivate_input_method(input_method);
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +0200930}
931
932static void
933input_method_init_seat(struct weston_seat *seat)
934{
Derek Foreman1281a362015-07-31 16:55:32 -0500935 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
936
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +0200937 if (seat->input_method->focus_listener_initialized)
938 return;
939
Derek Foreman1281a362015-07-31 16:55:32 -0500940 if (keyboard) {
Murray Calavera972d1af2015-06-09 20:29:28 +0000941 seat->input_method->keyboard_focus_listener.notify =
942 handle_keyboard_focus;
Derek Foreman1281a362015-07-31 16:55:32 -0500943 wl_signal_add(&keyboard->focus_signal,
Murray Calavera972d1af2015-06-09 20:29:28 +0000944 &seat->input_method->keyboard_focus_listener);
Derek Foreman1281a362015-07-31 16:55:32 -0500945 keyboard->input_method_grab.interface =
Murray Calavera972d1af2015-06-09 20:29:28 +0000946 &input_method_context_grab;
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +0200947 }
948
Derek Foremanddc2c972015-07-15 13:00:32 -0500949 seat->input_method->focus_listener_initialized = true;
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +0200950}
951
Eduardo Lima (Etrunko)27337002013-05-14 13:09:31 -0300952static void launch_input_method(struct text_backend *text_backend);
953
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100954static void
Derek Foreman89dcea92015-06-25 15:49:49 -0500955respawn_input_method_process(struct text_backend *text_backend)
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200956{
Alexandros Frantzis409b01f2017-11-16 18:21:01 +0200957 struct timespec time;
958 int64_t tdiff;
Eduardo Lima (Etrunko)27337002013-05-14 13:09:31 -0300959
960 /* if input_method dies more than 5 times in 10 seconds, give up */
Alexandros Frantzis409b01f2017-11-16 18:21:01 +0200961 weston_compositor_get_time(&time);
962 tdiff = timespec_sub_to_msec(&time,
963 &text_backend->input_method.deathstamp);
964 if (tdiff > 10000) {
Eduardo Lima (Etrunko)27337002013-05-14 13:09:31 -0300965 text_backend->input_method.deathstamp = time;
966 text_backend->input_method.deathcount = 0;
967 }
968
969 text_backend->input_method.deathcount++;
970 if (text_backend->input_method.deathcount > 5) {
Derek Foreman89dcea92015-06-25 15:49:49 -0500971 weston_log("input_method disconnected, giving up.\n");
Eduardo Lima (Etrunko)27337002013-05-14 13:09:31 -0300972 return;
973 }
974
Derek Foreman89dcea92015-06-25 15:49:49 -0500975 weston_log("input_method disconnected, respawning...\n");
Eduardo Lima (Etrunko)27337002013-05-14 13:09:31 -0300976 launch_input_method(text_backend);
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100977}
978
979static void
Derek Foreman89dcea92015-06-25 15:49:49 -0500980input_method_client_notifier(struct wl_listener *listener, void *data)
981{
982 struct text_backend *text_backend;
983
984 text_backend = container_of(listener, struct text_backend,
985 client_listener);
986
987 text_backend->input_method.client = NULL;
988 respawn_input_method_process(text_backend);
989}
990
991static void
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100992launch_input_method(struct text_backend *text_backend)
993{
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100994 if (!text_backend->input_method.path)
995 return;
996
Murray Calaveraf65f89b2015-06-09 20:28:06 +0000997 if (strcmp(text_backend->input_method.path, "") == 0)
998 return;
999
Takuro Ashie5ff978a2021-09-15 13:54:29 +09001000 if (text_backend->input_method.overlay_keyboard)
1001 setenv("WESTON_KEYBOARD_SURFACE_TYPE", "overlay", 1);
1002
Murray Calavera972d1af2015-06-09 20:29:28 +00001003 text_backend->input_method.client =
Derek Foreman89dcea92015-06-25 15:49:49 -05001004 weston_client_start(text_backend->compositor,
1005 text_backend->input_method.path);
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001006
Derek Foreman89dcea92015-06-25 15:49:49 -05001007 if (!text_backend->input_method.client) {
Murray Calavera972d1af2015-06-09 20:29:28 +00001008 weston_log("not able to start %s\n",
1009 text_backend->input_method.path);
Derek Foreman89dcea92015-06-25 15:49:49 -05001010 return;
1011 }
1012
1013 text_backend->client_listener.notify = input_method_client_notifier;
1014 wl_client_add_destroy_listener(text_backend->input_method.client,
1015 &text_backend->client_listener);
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001016}
1017
1018static void
Murray Calavera25881242015-06-10 21:15:30 +00001019text_backend_seat_created(struct text_backend *text_backend,
1020 struct weston_seat *seat)
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001021{
Jan Arne Petersen1f17be42012-06-21 21:52:18 +02001022 struct input_method *input_method;
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001023 struct weston_compositor *ec = seat->compositor;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +02001024
Bryce Harringtonde16d892014-11-20 22:21:57 -08001025 input_method = zalloc(sizeof *input_method);
1026 if (input_method == NULL)
1027 return;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +02001028
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +02001029 input_method->seat = seat;
Derek Foreman0f299232015-05-08 17:08:41 -05001030 input_method->input = NULL;
Derek Foremanddc2c972015-07-15 13:00:32 -05001031 input_method->focus_listener_initialized = false;
Jan Arne Petersen620cd622012-09-09 23:08:32 +02001032 input_method->context = NULL;
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001033 input_method->text_backend = text_backend;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +02001034
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +02001035 input_method->input_method_global =
Jonas Ådahlb57f4722015-11-17 16:00:30 +08001036 wl_global_create(ec->wl_display,
1037 &zwp_input_method_v1_interface, 1,
Kristian Høgsberg919cddb2013-07-08 19:03:57 -04001038 input_method, bind_input_method);
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +02001039
Jan Arne Petersen1f17be42012-06-21 21:52:18 +02001040 input_method->destroy_listener.notify = input_method_notifier_destroy;
Kristian Høgsberg49124542013-05-06 22:27:40 -04001041 wl_signal_add(&seat->destroy_signal, &input_method->destroy_listener);
Jan Arne Petersene829adc2012-08-10 16:47:22 +02001042
1043 seat->input_method = input_method;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +02001044}
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +02001045
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001046static void
Murray Calavera25881242015-06-10 21:15:30 +00001047handle_seat_created(struct wl_listener *listener, void *data)
1048{
1049 struct weston_seat *seat = data;
1050 struct text_backend *text_backend =
1051 container_of(listener, struct text_backend,
1052 seat_created_listener);
1053
1054 text_backend_seat_created(text_backend, seat);
1055}
1056
1057static void
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001058text_backend_configuration(struct text_backend *text_backend)
1059{
Giulio Camuffod52f3b72016-06-02 21:48:11 +03001060 struct weston_config *config = wet_get_config(text_backend->compositor);
Kristian Høgsberg00fd7b82013-05-23 21:45:51 -04001061 struct weston_config_section *section;
Derek Foremanc7210432014-08-21 11:32:38 -05001062 char *client;
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001063
Giulio Camuffod52f3b72016-06-02 21:48:11 +03001064 section = weston_config_get_section(config,
Kristian Høgsberg00fd7b82013-05-23 21:45:51 -04001065 "input-method", NULL, NULL);
Marius Vlad64fbd0f2018-12-15 15:51:57 +02001066 client = wet_get_libexec_path("weston-keyboard");
Kristian Høgsberg00fd7b82013-05-23 21:45:51 -04001067 weston_config_section_get_string(section, "path",
1068 &text_backend->input_method.path,
Derek Foremanc7210432014-08-21 11:32:38 -05001069 client);
Takuro Ashie5ff978a2021-09-15 13:54:29 +09001070 weston_config_section_get_bool(section, "overlay-keyboard",
1071 &text_backend->input_method.overlay_keyboard,
1072 false);
Derek Foremanc7210432014-08-21 11:32:38 -05001073 free(client);
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001074}
1075
Pekka Paalanenaa9536a2015-06-24 16:09:17 +03001076WL_EXPORT void
1077text_backend_destroy(struct text_backend *text_backend)
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001078{
Harsha M Mb8b2c722018-08-07 19:05:02 +05301079 wl_list_remove(&text_backend->seat_created_listener.link);
1080
Derek Foreman89dcea92015-06-25 15:49:49 -05001081 if (text_backend->input_method.client) {
1082 /* disable respawn */
1083 wl_list_remove(&text_backend->client_listener.link);
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001084 wl_client_destroy(text_backend->input_method.client);
Derek Foreman89dcea92015-06-25 15:49:49 -05001085 }
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001086
1087 free(text_backend->input_method.path);
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001088 free(text_backend);
1089}
1090
Pekka Paalanenaa9536a2015-06-24 16:09:17 +03001091WL_EXPORT struct text_backend *
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001092text_backend_init(struct weston_compositor *ec)
1093{
1094 struct text_backend *text_backend;
Murray Calavera25881242015-06-10 21:15:30 +00001095 struct weston_seat *seat;
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001096
Bryce Harringtonde16d892014-11-20 22:21:57 -08001097 text_backend = zalloc(sizeof(*text_backend));
1098 if (text_backend == NULL)
Pekka Paalanenaa9536a2015-06-24 16:09:17 +03001099 return NULL;
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001100
1101 text_backend->compositor = ec;
1102
Murray Calavera25881242015-06-10 21:15:30 +00001103 text_backend_configuration(text_backend);
1104
1105 wl_list_for_each(seat, &ec->seat_list, link)
1106 text_backend_seat_created(text_backend, seat);
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001107 text_backend->seat_created_listener.notify = handle_seat_created;
1108 wl_signal_add(&ec->seat_created_signal,
1109 &text_backend->seat_created_listener);
1110
Jan Arne Petersen78d00e42013-04-18 16:47:24 +02001111 text_input_manager_create(ec);
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001112
Derek Foremanb4bacd22015-06-25 15:49:47 -05001113 launch_input_method(text_backend);
1114
Pekka Paalanenaa9536a2015-06-24 16:09:17 +03001115 return text_backend;
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +01001116}