blob: 13fff241d2549f905be7ef017ed810b09d65a3e9 [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 *
5 * Permission to use, copy, modify, distribute, and sell this software and
6 * its documentation for any purpose is hereby granted without fee, provided
7 * that the above copyright notice appear in all copies and that both that
8 * copyright notice and this permission notice appear in supporting
9 * documentation, and that the name of the copyright holders not be used in
10 * advertising or publicity pertaining to distribution of the software
11 * without specific, written prior permission. The copyright holders make
12 * no representations about the suitability of this software for any
13 * purpose. It is provided "as is" without express or implied warranty.
14 *
15 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
16 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
18 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
19 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
20 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 */
23
24#include <stdlib.h>
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +010025#include <string.h>
Jan Arne Petersen1f17be42012-06-21 21:52:18 +020026
27#include "compositor.h"
28#include "text-server-protocol.h"
Jan Arne Petersen30b66ef2012-09-09 23:08:41 +020029#include "input-method-server-protocol.h"
Jan Arne Petersen1f17be42012-06-21 21:52:18 +020030
31struct input_method;
Jan Arne Petersen620cd622012-09-09 23:08:32 +020032struct input_method_context;
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +010033struct text_backend;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +020034
Jan Arne Petersen78d00e42013-04-18 16:47:24 +020035struct text_input {
Jan Arne Petersen1f17be42012-06-21 21:52:18 +020036 struct wl_resource resource;
37
Jan Arne Petersene829adc2012-08-10 16:47:22 +020038 struct weston_compositor *ec;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +020039
Jan Arne Petersene829adc2012-08-10 16:47:22 +020040 struct wl_list input_methods;
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +020041
42 struct wl_surface *surface;
Jan Arne Petersen61381972013-01-31 15:52:21 +010043
44 uint32_t input_panel_visible;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +020045};
46
Jan Arne Petersen78d00e42013-04-18 16:47:24 +020047struct text_input_manager {
48 struct wl_global *text_input_manager_global;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +020049 struct wl_listener destroy_listener;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +020050
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +020051 struct weston_compositor *ec;
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +020052};
53
54struct input_method {
55 struct wl_resource *input_method_binding;
56 struct wl_global *input_method_global;
57 struct wl_listener destroy_listener;
58
59 struct weston_seat *seat;
Jan Arne Petersen78d00e42013-04-18 16:47:24 +020060 struct text_input *model;
Jan Arne Petersene829adc2012-08-10 16:47:22 +020061
62 struct wl_list link;
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +020063
64 struct wl_listener keyboard_focus_listener;
65
66 int focus_listener_initialized;
Jan Arne Petersen620cd622012-09-09 23:08:32 +020067
68 struct input_method_context *context;
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +010069
70 struct text_backend *text_backend;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +020071};
72
Jan Arne Petersen620cd622012-09-09 23:08:32 +020073struct input_method_context {
74 struct wl_resource resource;
75
Jan Arne Petersen78d00e42013-04-18 16:47:24 +020076 struct text_input *model;
Jan Arne Petersen466b9c12012-11-18 19:06:45 +010077 struct input_method *input_method;
Jan Arne Petersen620cd622012-09-09 23:08:32 +020078
79 struct wl_list link;
Jan Arne Petersen466b9c12012-11-18 19:06:45 +010080
81 struct wl_resource *keyboard;
Jan Arne Petersen620cd622012-09-09 23:08:32 +020082};
83
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +010084struct text_backend {
85 struct weston_compositor *compositor;
86
87 struct {
88 char *path;
89 struct wl_resource *binding;
90 struct weston_process process;
91 struct wl_client *client;
92 } input_method;
93
94 struct wl_listener seat_created_listener;
95 struct wl_listener destroy_listener;
96};
97
Jan Arne Petersen78d00e42013-04-18 16:47:24 +020098static void input_method_context_create(struct text_input *model,
Jan Arne Petersenc7d2a982013-01-16 21:26:39 +010099 struct input_method *input_method,
100 uint32_t serial);
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100101static void input_method_context_end_keyboard_grab(struct input_method_context *context);
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200102
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +0200103static void input_method_init_seat(struct weston_seat *seat);
104
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200105static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200106deactivate_text_input(struct text_input *text_input,
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200107 struct input_method *input_method)
Philipp Brüschweiler17467812012-07-11 22:25:30 +0200108{
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200109 struct weston_compositor *ec = text_input->ec;
Philipp Brüschweiler17467812012-07-11 22:25:30 +0200110
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200111 if (input_method->model == text_input) {
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100112 if (input_method->context && input_method->input_method_binding) {
113 input_method_context_end_keyboard_grab(input_method->context);
114 input_method_send_deactivate(input_method->input_method_binding,
115 &input_method->context->resource);
116 }
117
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200118 wl_list_remove(&input_method->link);
119 input_method->model = NULL;
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200120 input_method->context = NULL;
Kristian Høgsbergf97f3792012-07-22 11:51:42 -0400121 wl_signal_emit(&ec->hide_input_panel_signal, ec);
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200122 text_input_send_leave(&text_input->resource);
Philipp Brüschweiler17467812012-07-11 22:25:30 +0200123 }
124}
125
126static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200127destroy_text_input(struct wl_resource *resource)
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200128{
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200129 struct text_input *text_input =
130 container_of(resource, struct text_input, resource);
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200131 struct input_method *input_method, *next;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200132
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200133 wl_list_for_each_safe(input_method, next, &text_input->input_methods, link)
134 deactivate_text_input(text_input, input_method);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200135
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200136 free(text_input);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200137}
138
139static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200140text_input_set_surrounding_text(struct wl_client *client,
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200141 struct wl_resource *resource,
Jan Arne Petersencb08f4d2012-09-09 23:08:40 +0200142 const char *text,
143 uint32_t cursor,
144 uint32_t anchor)
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200145{
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200146 struct text_input *text_input = resource->data;
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200147 struct input_method *input_method, *next;
148
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200149 wl_list_for_each_safe(input_method, next, &text_input->input_methods, link) {
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200150 if (!input_method->context)
151 continue;
Jan Arne Petersencb08f4d2012-09-09 23:08:40 +0200152 input_method_context_send_surrounding_text(&input_method->context->resource,
153 text,
154 cursor,
155 anchor);
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200156 }
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200157}
158
159static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200160text_input_activate(struct wl_client *client,
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200161 struct wl_resource *resource,
Jan Arne Petersenc7d2a982013-01-16 21:26:39 +0100162 uint32_t serial,
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200163 struct wl_resource *seat,
164 struct wl_resource *surface)
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200165{
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200166 struct text_input *text_input = resource->data;
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200167 struct weston_seat *weston_seat = seat->data;
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200168 struct input_method *input_method = weston_seat->input_method;
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200169 struct text_input *old = weston_seat->input_method->model;
170 struct weston_compositor *ec = text_input->ec;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200171
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200172 if (old == text_input)
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200173 return;
Jan Arne Petersende3b6a12012-08-10 16:47:21 +0200174
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200175 if (old) {
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200176 deactivate_text_input(old,
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200177 weston_seat->input_method);
Jan Arne Petersende3b6a12012-08-10 16:47:21 +0200178 }
179
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200180 input_method->model = text_input;
181 wl_list_insert(&text_input->input_methods, &input_method->link);
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +0200182 input_method_init_seat(weston_seat);
183
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200184 text_input->surface = surface->data;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200185
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200186 input_method_context_create(text_input, input_method, serial);
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200187
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200188 if (text_input->input_panel_visible)
Jan Arne Petersen61381972013-01-31 15:52:21 +0100189 wl_signal_emit(&ec->show_input_panel_signal, ec);
Jan Arne Petersende3b6a12012-08-10 16:47:21 +0200190
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200191 text_input_send_enter(&text_input->resource, &text_input->surface->resource);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200192}
193
194static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200195text_input_deactivate(struct wl_client *client,
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200196 struct wl_resource *resource,
197 struct wl_resource *seat)
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200198{
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200199 struct text_input *text_input = resource->data;
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200200 struct weston_seat *weston_seat = seat->data;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200201
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200202 deactivate_text_input(text_input,
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200203 weston_seat->input_method);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200204}
205
206static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200207text_input_reset(struct wl_client *client,
Jan Arne Petersenc7d2a982013-01-16 21:26:39 +0100208 struct wl_resource *resource,
209 uint32_t serial)
Jan Arne Petersenc1e481e2012-09-09 23:08:46 +0200210{
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200211 struct text_input *text_input = resource->data;
Jan Arne Petersenc1e481e2012-09-09 23:08:46 +0200212 struct input_method *input_method, *next;
213
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200214 wl_list_for_each_safe(input_method, next, &text_input->input_methods, link) {
Jan Arne Petersenc1e481e2012-09-09 23:08:46 +0200215 if (!input_method->context)
216 continue;
Jan Arne Petersenc7d2a982013-01-16 21:26:39 +0100217 input_method_context_send_reset(&input_method->context->resource, serial);
Jan Arne Petersenc1e481e2012-09-09 23:08:46 +0200218 }
219}
220
221static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200222text_input_set_cursor_rectangle(struct wl_client *client,
Jan Arne Petersen7ef8eff2013-04-18 16:47:23 +0200223 struct wl_resource *resource,
224 int32_t x,
225 int32_t y,
226 int32_t width,
227 int32_t height)
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200228{
229}
230
231static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200232text_input_set_content_type(struct wl_client *client,
Jan Arne Petersen26ffa812013-01-16 21:26:43 +0100233 struct wl_resource *resource,
234 uint32_t hint,
235 uint32_t purpose)
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200236{
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200237 struct text_input *text_input = resource->data;
Jan Arne Petersen26ffa812013-01-16 21:26:43 +0100238 struct input_method *input_method, *next;
239
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200240 wl_list_for_each_safe(input_method, next, &text_input->input_methods, link) {
Jan Arne Petersen26ffa812013-01-16 21:26:43 +0100241 if (!input_method->context)
242 continue;
243 input_method_context_send_content_type(&input_method->context->resource, hint, purpose);
244 }
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200245}
246
Jan Arne Petersenadfedc12013-01-16 21:26:46 +0100247static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200248text_input_invoke_action(struct wl_client *client,
Jan Arne Petersenadfedc12013-01-16 21:26:46 +0100249 struct wl_resource *resource,
250 uint32_t button,
251 uint32_t index)
252{
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200253 struct text_input *text_input = resource->data;
Jan Arne Petersenadfedc12013-01-16 21:26:46 +0100254 struct input_method *input_method, *next;
255
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200256 wl_list_for_each_safe(input_method, next, &text_input->input_methods, link) {
Jan Arne Petersenadfedc12013-01-16 21:26:46 +0100257 if (!input_method->context)
258 continue;
259 input_method_context_send_invoke_action(&input_method->context->resource, button, index);
260 }
261}
262
Jan Arne Petersen0eabcaa2013-01-31 15:52:20 +0100263static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200264text_input_commit_state(struct wl_client *client,
Jan Arne Petersenfa357382013-04-18 16:47:22 +0200265 struct wl_resource *resource)
Jan Arne Petersen0eabcaa2013-01-31 15:52:20 +0100266{
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200267 struct text_input *text_input = resource->data;
Jan Arne Petersen0eabcaa2013-01-31 15:52:20 +0100268 struct input_method *input_method, *next;
269
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200270 wl_list_for_each_safe(input_method, next, &text_input->input_methods, link) {
Jan Arne Petersen0eabcaa2013-01-31 15:52:20 +0100271 if (!input_method->context)
272 continue;
273 input_method_context_send_commit(&input_method->context->resource);
274 }
275}
276
Jan Arne Petersen61381972013-01-31 15:52:21 +0100277static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200278text_input_show_input_panel(struct wl_client *client,
Jan Arne Petersen61381972013-01-31 15:52:21 +0100279 struct wl_resource *resource)
280{
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200281 struct text_input *text_input = resource->data;
282 struct weston_compositor *ec = text_input->ec;
Jan Arne Petersen61381972013-01-31 15:52:21 +0100283
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200284 text_input->input_panel_visible = 1;
Jan Arne Petersen61381972013-01-31 15:52:21 +0100285
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200286 if (!wl_list_empty(&text_input->input_methods))
Jan Arne Petersen61381972013-01-31 15:52:21 +0100287 wl_signal_emit(&ec->show_input_panel_signal, ec);
288}
289
290static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200291text_input_hide_input_panel(struct wl_client *client,
Jan Arne Petersen61381972013-01-31 15:52:21 +0100292 struct wl_resource *resource)
293{
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200294 struct text_input *text_input = resource->data;
295 struct weston_compositor *ec = text_input->ec;
Jan Arne Petersen61381972013-01-31 15:52:21 +0100296
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200297 text_input->input_panel_visible = 0;
Jan Arne Petersen61381972013-01-31 15:52:21 +0100298
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200299 if (!wl_list_empty(&text_input->input_methods))
Jan Arne Petersen61381972013-01-31 15:52:21 +0100300 wl_signal_emit(&ec->hide_input_panel_signal, ec);
301}
302
Jan Arne Petersenece6b5a2013-04-18 16:47:15 +0200303static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200304text_input_set_preferred_language(struct wl_client *client,
Jan Arne Petersenece6b5a2013-04-18 16:47:15 +0200305 struct wl_resource *resource,
306 const char *language)
307{
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200308 struct text_input *text_input = resource->data;
Jan Arne Petersenece6b5a2013-04-18 16:47:15 +0200309 struct input_method *input_method, *next;
310
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200311 wl_list_for_each_safe(input_method, next, &text_input->input_methods, link) {
Jan Arne Petersenece6b5a2013-04-18 16:47:15 +0200312 if (!input_method->context)
313 continue;
314 input_method_context_send_preferred_language(&input_method->context->resource,
315 language);
316 }
317}
318
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200319static const struct text_input_interface text_input_implementation = {
320 text_input_activate,
321 text_input_deactivate,
322 text_input_show_input_panel,
323 text_input_hide_input_panel,
324 text_input_reset,
325 text_input_set_surrounding_text,
326 text_input_set_content_type,
327 text_input_set_cursor_rectangle,
328 text_input_set_preferred_language,
329 text_input_commit_state,
330 text_input_invoke_action
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200331};
332
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200333static void text_input_manager_create_text_input(struct wl_client *client,
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200334 struct wl_resource *resource,
Jan Arne Petersen4c265182012-09-09 23:08:30 +0200335 uint32_t id)
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200336{
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200337 struct text_input_manager *text_input_manager = resource->data;
338 struct text_input *text_input;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200339
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200340 text_input = calloc(1, sizeof *text_input);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200341
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200342 text_input->resource.object.id = id;
343 text_input->resource.object.interface = &text_input_interface;
344 text_input->resource.object.implementation =
345 (void (**)(void)) &text_input_implementation;
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200346
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200347 text_input->resource.data = text_input;
348 text_input->resource.destroy = destroy_text_input;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200349
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200350 text_input->ec = text_input_manager->ec;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200351
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200352 wl_list_init(&text_input->input_methods);
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200353
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200354 wl_client_add_resource(client, &text_input->resource);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200355};
356
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200357static const struct text_input_manager_interface text_input_manager_implementation = {
358 text_input_manager_create_text_input
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200359};
360
361static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200362bind_text_input_manager(struct wl_client *client,
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200363 void *data,
364 uint32_t version,
365 uint32_t id)
366{
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200367 struct text_input_manager *text_input_manager = data;
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200368
369 /* No checking for duplicate binding necessary.
370 * No events have to be sent, so we don't need the return value. */
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200371 wl_client_add_object(client, &text_input_manager_interface,
372 &text_input_manager_implementation,
373 id, text_input_manager);
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200374}
375
376static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200377text_input_manager_notifier_destroy(struct wl_listener *listener, void *data)
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200378{
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200379 struct text_input_manager *text_input_manager =
380 container_of(listener, struct text_input_manager, destroy_listener);
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200381
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200382 wl_display_remove_global(text_input_manager->ec->wl_display,
383 text_input_manager->text_input_manager_global);
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200384
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200385 free(text_input_manager);
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200386}
387
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100388static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200389text_input_manager_create(struct weston_compositor *ec)
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200390{
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200391 struct text_input_manager *text_input_manager;
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200392
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200393 text_input_manager = calloc(1, sizeof *text_input_manager);
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200394
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200395 text_input_manager->ec = ec;
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200396
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200397 text_input_manager->text_input_manager_global =
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200398 wl_display_add_global(ec->wl_display,
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200399 &text_input_manager_interface,
400 text_input_manager, bind_text_input_manager);
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200401
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200402 text_input_manager->destroy_listener.notify = text_input_manager_notifier_destroy;
403 wl_signal_add(&ec->destroy_signal, &text_input_manager->destroy_listener);
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200404}
405
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200406static void
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200407input_method_context_destroy(struct wl_client *client,
408 struct wl_resource *resource)
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200409{
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200410 wl_resource_destroy(resource);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200411}
412
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200413static void
414input_method_context_commit_string(struct wl_client *client,
415 struct wl_resource *resource,
Jan Arne Petersenc7d2a982013-01-16 21:26:39 +0100416 uint32_t serial,
Jan Arne Petersen1cc9e082013-01-31 15:52:23 +0100417 const char *text)
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200418{
419 struct input_method_context *context = resource->data;
420
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200421 text_input_send_commit_string(&context->model->resource, serial, text);
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200422}
423
Jan Arne Petersen43f4aa82012-09-09 23:08:43 +0200424static void
425input_method_context_preedit_string(struct wl_client *client,
Jan Arne Petersen46535312013-01-16 21:26:38 +0100426 struct wl_resource *resource,
Jan Arne Petersenc7d2a982013-01-16 21:26:39 +0100427 uint32_t serial,
Jan Arne Petersen46535312013-01-16 21:26:38 +0100428 const char *text,
429 const char *commit)
Jan Arne Petersen43f4aa82012-09-09 23:08:43 +0200430{
431 struct input_method_context *context = resource->data;
432
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200433 text_input_send_preedit_string(&context->model->resource, serial, text, commit);
Jan Arne Petersen46535312013-01-16 21:26:38 +0100434}
435
436static void
437input_method_context_preedit_styling(struct wl_client *client,
438 struct wl_resource *resource,
Jan Arne Petersenc7d2a982013-01-16 21:26:39 +0100439 uint32_t serial,
Jan Arne Petersen46535312013-01-16 21:26:38 +0100440 uint32_t index,
441 uint32_t length,
442 uint32_t style)
443{
444 struct input_method_context *context = resource->data;
445
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200446 text_input_send_preedit_styling(&context->model->resource, serial, index, length, style);
Jan Arne Petersen46535312013-01-16 21:26:38 +0100447}
448
449static void
450input_method_context_preedit_cursor(struct wl_client *client,
451 struct wl_resource *resource,
Jan Arne Petersenc7d2a982013-01-16 21:26:39 +0100452 uint32_t serial,
Jan Arne Petersen46535312013-01-16 21:26:38 +0100453 int32_t cursor)
454{
455 struct input_method_context *context = resource->data;
456
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200457 text_input_send_preedit_cursor(&context->model->resource, serial, cursor);
Jan Arne Petersen43f4aa82012-09-09 23:08:43 +0200458}
459
Jan Arne Petersene202bae2012-09-09 23:08:44 +0200460static void
461input_method_context_delete_surrounding_text(struct wl_client *client,
462 struct wl_resource *resource,
Jan Arne Petersenc7d2a982013-01-16 21:26:39 +0100463 uint32_t serial,
Jan Arne Petersene202bae2012-09-09 23:08:44 +0200464 int32_t index,
465 uint32_t length)
466{
467 struct input_method_context *context = resource->data;
468
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200469 text_input_send_delete_surrounding_text(&context->model->resource, serial, index, length);
Jan Arne Petersene202bae2012-09-09 23:08:44 +0200470}
471
Jan Arne Petersence8a4432012-09-09 23:08:45 +0200472static void
Jan Arne Petersen1cc9e082013-01-31 15:52:23 +0100473input_method_context_cursor_position(struct wl_client *client,
474 struct wl_resource *resource,
475 uint32_t serial,
476 int32_t index,
477 int32_t anchor)
478{
479 struct input_method_context *context = resource->data;
480
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200481 text_input_send_cursor_position(&context->model->resource, serial, index, anchor);
Jan Arne Petersen1cc9e082013-01-31 15:52:23 +0100482}
483
484static void
Jan Arne Petersend9be93b2012-11-18 19:06:43 +0100485input_method_context_modifiers_map(struct wl_client *client,
486 struct wl_resource *resource,
487 struct wl_array *map)
Jan Arne Petersence8a4432012-09-09 23:08:45 +0200488{
489 struct input_method_context *context = resource->data;
490
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200491 text_input_send_modifiers_map(&context->model->resource, map);
Jan Arne Petersend9be93b2012-11-18 19:06:43 +0100492}
493
494static void
495input_method_context_keysym(struct wl_client *client,
496 struct wl_resource *resource,
497 uint32_t serial,
498 uint32_t time,
499 uint32_t sym,
500 uint32_t state,
501 uint32_t modifiers)
502{
503 struct input_method_context *context = resource->data;
504
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200505 text_input_send_keysym(&context->model->resource, serial, time,
Jan Arne Petersend9be93b2012-11-18 19:06:43 +0100506 sym, state, modifiers);
Jan Arne Petersence8a4432012-09-09 23:08:45 +0200507}
508
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100509static void
510unbind_keyboard(struct wl_resource *resource)
511{
512 struct input_method_context *context = resource->data;
513
514 input_method_context_end_keyboard_grab(context);
515 context->keyboard = NULL;
516
517 free(resource);
518}
519
520static void
521input_method_context_grab_key(struct wl_keyboard_grab *grab,
522 uint32_t time, uint32_t key, uint32_t state_w)
523{
Jan Arne Petersena75a7892013-01-16 21:26:50 +0100524 struct weston_keyboard *keyboard = (struct weston_keyboard *)grab->keyboard;
525 struct wl_display *display;
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100526 uint32_t serial;
Jan Arne Petersena75a7892013-01-16 21:26:50 +0100527
528 if (!keyboard->input_method_resource)
529 return;
530
531 display = wl_client_get_display(keyboard->input_method_resource->client);
532 serial = wl_display_next_serial(display);
533 wl_keyboard_send_key(keyboard->input_method_resource,
534 serial, time, key, state_w);
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100535}
536
537static void
538input_method_context_grab_modifier(struct wl_keyboard_grab *grab, uint32_t serial,
539 uint32_t mods_depressed, uint32_t mods_latched,
540 uint32_t mods_locked, uint32_t group)
541{
Jan Arne Petersena75a7892013-01-16 21:26:50 +0100542 struct weston_keyboard *keyboard = (struct weston_keyboard *)grab->keyboard;
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100543
Jan Arne Petersena75a7892013-01-16 21:26:50 +0100544 if (!keyboard->input_method_resource)
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100545 return;
546
Jan Arne Petersena75a7892013-01-16 21:26:50 +0100547 wl_keyboard_send_modifiers(keyboard->input_method_resource,
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100548 serial, mods_depressed, mods_latched,
549 mods_locked, group);
550}
551
552static const struct wl_keyboard_grab_interface input_method_context_grab = {
553 input_method_context_grab_key,
554 input_method_context_grab_modifier,
555};
556
557static void
558input_method_context_grab_keyboard(struct wl_client *client,
559 struct wl_resource *resource,
560 uint32_t id)
561{
562 struct input_method_context *context = resource->data;
563 struct wl_resource *cr;
564 struct weston_seat *seat = context->input_method->seat;
Jan Arne Petersena75a7892013-01-16 21:26:50 +0100565 struct weston_keyboard *keyboard = &seat->keyboard;
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100566
567 cr = wl_client_add_object(client, &wl_keyboard_interface,
568 NULL, id, context);
569 cr->destroy = unbind_keyboard;
570
571 context->keyboard = cr;
572
573 wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
574 seat->xkb_info.keymap_fd,
575 seat->xkb_info.keymap_size);
576
Jan Arne Petersena75a7892013-01-16 21:26:50 +0100577 if (keyboard->keyboard.grab != &keyboard->keyboard.default_grab) {
578 wl_keyboard_end_grab(&keyboard->keyboard);
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100579 }
Jan Arne Petersena75a7892013-01-16 21:26:50 +0100580 wl_keyboard_start_grab(&keyboard->keyboard, &keyboard->input_method_grab);
581 keyboard->input_method_resource = cr;
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100582}
583
Jan Arne Petersen337df952012-11-18 19:06:46 +0100584static void
585input_method_context_key(struct wl_client *client,
586 struct wl_resource *resource,
587 uint32_t serial,
588 uint32_t time,
589 uint32_t key,
590 uint32_t state_w)
591{
592 struct input_method_context *context = resource->data;
593 struct weston_seat *seat = context->input_method->seat;
594 struct wl_keyboard *keyboard = seat->seat.keyboard;
595 struct wl_keyboard_grab *default_grab = &keyboard->default_grab;
596
597 default_grab->interface->key(default_grab, time, key, state_w);
598}
599
600static void
601input_method_context_modifiers(struct wl_client *client,
602 struct wl_resource *resource,
603 uint32_t serial,
604 uint32_t mods_depressed,
605 uint32_t mods_latched,
606 uint32_t mods_locked,
607 uint32_t group)
608{
609 struct input_method_context *context = resource->data;
610
611 struct weston_seat *seat = context->input_method->seat;
612 struct wl_keyboard *keyboard = seat->seat.keyboard;
613 struct wl_keyboard_grab *default_grab = &keyboard->default_grab;
614
615 default_grab->interface->modifiers(default_grab,
616 serial, mods_depressed,
617 mods_latched, mods_locked,
618 group);
619}
620
Jan Arne Petersenece6b5a2013-04-18 16:47:15 +0200621static void
622input_method_context_language(struct wl_client *client,
623 struct wl_resource *resource,
624 uint32_t serial,
625 const char *language)
626{
627 struct input_method_context *context = resource->data;
628
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200629 text_input_send_language(&context->model->resource, serial, language);
Jan Arne Petersenece6b5a2013-04-18 16:47:15 +0200630}
631
632static void
633input_method_context_text_direction(struct wl_client *client,
634 struct wl_resource *resource,
635 uint32_t serial,
636 uint32_t direction)
637{
638 struct input_method_context *context = resource->data;
639
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200640 text_input_send_text_direction(&context->model->resource, serial, direction);
Jan Arne Petersenece6b5a2013-04-18 16:47:15 +0200641}
642
643
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200644static const struct input_method_context_interface input_method_context_implementation = {
645 input_method_context_destroy,
Jan Arne Petersen43f4aa82012-09-09 23:08:43 +0200646 input_method_context_commit_string,
647 input_method_context_preedit_string,
Jan Arne Petersen46535312013-01-16 21:26:38 +0100648 input_method_context_preedit_styling,
649 input_method_context_preedit_cursor,
Jan Arne Petersence8a4432012-09-09 23:08:45 +0200650 input_method_context_delete_surrounding_text,
Jan Arne Petersen1cc9e082013-01-31 15:52:23 +0100651 input_method_context_cursor_position,
Jan Arne Petersend9be93b2012-11-18 19:06:43 +0100652 input_method_context_modifiers_map,
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100653 input_method_context_keysym,
Jan Arne Petersen337df952012-11-18 19:06:46 +0100654 input_method_context_grab_keyboard,
655 input_method_context_key,
Jan Arne Petersenece6b5a2013-04-18 16:47:15 +0200656 input_method_context_modifiers,
657 input_method_context_language,
658 input_method_context_text_direction
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200659};
660
661static void
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200662destroy_input_method_context(struct wl_resource *resource)
663{
664 struct input_method_context *context = resource->data;
665
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100666 if (context->keyboard) {
667 wl_resource_destroy(context->keyboard);
668 }
669
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200670 free(context);
671}
672
673static void
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200674input_method_context_create(struct text_input *model,
Jan Arne Petersenc7d2a982013-01-16 21:26:39 +0100675 struct input_method *input_method,
676 uint32_t serial)
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200677{
678 struct input_method_context *context;
679
680 if (!input_method->input_method_binding)
681 return;
682
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100683 context = calloc(1, sizeof *context);
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200684 if (context == NULL)
685 return;
686
687 context->resource.destroy = destroy_input_method_context;
688 context->resource.object.id = 0;
689 context->resource.object.interface = &input_method_context_interface;
690 context->resource.object.implementation =
691 (void (**)(void)) &input_method_context_implementation;
692 context->resource.data = context;
693 wl_signal_init(&context->resource.destroy_signal);
694
695 context->model = model;
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100696 context->input_method = input_method;
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200697 input_method->context = context;
698
699 wl_client_add_resource(input_method->input_method_binding->client, &context->resource);
700
Jan Arne Petersenc7d2a982013-01-16 21:26:39 +0100701 input_method_send_activate(input_method->input_method_binding, &context->resource, serial);
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200702}
703
704static void
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100705input_method_context_end_keyboard_grab(struct input_method_context *context)
706{
Jan Arne Petersena75a7892013-01-16 21:26:50 +0100707 struct wl_keyboard_grab *grab = &context->input_method->seat->keyboard.input_method_grab;
708 struct weston_keyboard *keyboard = (struct weston_keyboard *)grab->keyboard;
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100709
Jan Arne Petersena75a7892013-01-16 21:26:50 +0100710 if (!grab->keyboard)
711 return;
712
713 if (grab->keyboard->grab == grab)
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100714 wl_keyboard_end_grab(grab->keyboard);
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100715
Jan Arne Petersena75a7892013-01-16 21:26:50 +0100716 keyboard->input_method_resource = NULL;
717}
Jan Arne Petersen466b9c12012-11-18 19:06:45 +0100718
719static void
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200720unbind_input_method(struct wl_resource *resource)
721{
722 struct input_method *input_method = resource->data;
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100723 struct text_backend *text_backend = input_method->text_backend;
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200724
725 input_method->input_method_binding = NULL;
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200726 input_method->context = NULL;
727
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100728 text_backend->input_method.binding = NULL;
729
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200730 free(resource);
731}
732
733static void
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200734bind_input_method(struct wl_client *client,
735 void *data,
736 uint32_t version,
737 uint32_t id)
738{
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200739 struct input_method *input_method = data;
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100740 struct text_backend *text_backend = input_method->text_backend;
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200741 struct wl_resource *resource;
742
743 resource = wl_client_add_object(client, &input_method_interface,
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200744 NULL,
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200745 id, input_method);
746
747 if (input_method->input_method_binding == NULL) {
748 resource->destroy = unbind_input_method;
749 input_method->input_method_binding = resource;
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100750
751 text_backend->input_method.binding = resource;
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200752 return;
753 }
754
755 wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
756 "interface object already bound");
757 wl_resource_destroy(resource);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200758}
759
760static void
761input_method_notifier_destroy(struct wl_listener *listener, void *data)
762{
Kristian Høgsbergf97f3792012-07-22 11:51:42 -0400763 struct input_method *input_method =
764 container_of(listener, struct input_method, destroy_listener);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200765
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200766 if (input_method->model)
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200767 deactivate_text_input(input_method->model, input_method);
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200768
769 wl_display_remove_global(input_method->seat->compositor->wl_display,
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200770 input_method->input_method_global);
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200771
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200772 free(input_method);
773}
774
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +0200775static void
776handle_keyboard_focus(struct wl_listener *listener, void *data)
777{
778 struct wl_keyboard *keyboard = data;
779 struct input_method *input_method =
780 container_of(listener, struct input_method, keyboard_focus_listener);
781 struct wl_surface *surface = keyboard->focus;
782
783 if (!input_method->model)
784 return;
785
786 if (!surface || input_method->model->surface != surface)
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200787 deactivate_text_input(input_method->model,
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +0200788 input_method);
789}
790
791static void
792input_method_init_seat(struct weston_seat *seat)
793{
794 if (seat->input_method->focus_listener_initialized)
795 return;
796
797 if (seat->has_keyboard) {
798 seat->input_method->keyboard_focus_listener.notify = handle_keyboard_focus;
799 wl_signal_add(&seat->seat.keyboard->focus_signal, &seat->input_method->keyboard_focus_listener);
Jan Arne Petersena75a7892013-01-16 21:26:50 +0100800 seat->keyboard.input_method_grab.interface = &input_method_context_grab;
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +0200801 }
802
803 seat->input_method->focus_listener_initialized = 1;
804}
805
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100806static void
807handle_input_method_sigchld(struct weston_process *process, int status)
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200808{
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100809 struct text_backend *text_backend =
810 container_of(process, struct text_backend, input_method.process);
811
812 text_backend->input_method.process.pid = 0;
813 text_backend->input_method.client = NULL;
814}
815
816static void
817launch_input_method(struct text_backend *text_backend)
818{
819 if (text_backend->input_method.binding)
820 return;
821
822 if (!text_backend->input_method.path)
823 return;
824
825 if (text_backend->input_method.process.pid != 0)
826 return;
827
828 text_backend->input_method.client = weston_client_launch(text_backend->compositor,
829 &text_backend->input_method.process,
830 text_backend->input_method.path,
831 handle_input_method_sigchld);
832
833 if (!text_backend->input_method.client)
834 weston_log("not able to start %s\n", text_backend->input_method.path);
835}
836
837static void
838handle_seat_created(struct wl_listener *listener,
839 void *data)
840{
841 struct weston_seat *seat = data;
842 struct text_backend *text_backend =
843 container_of(listener, struct text_backend,
844 seat_created_listener);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200845 struct input_method *input_method;
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100846 struct weston_compositor *ec = seat->compositor;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200847
Philipp Brüschweiler17467812012-07-11 22:25:30 +0200848 input_method = calloc(1, sizeof *input_method);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200849
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200850 input_method->seat = seat;
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200851 input_method->model = NULL;
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +0200852 input_method->focus_listener_initialized = 0;
Jan Arne Petersen620cd622012-09-09 23:08:32 +0200853 input_method->context = NULL;
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100854 input_method->text_backend = text_backend;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200855
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200856 input_method->input_method_global =
857 wl_display_add_global(ec->wl_display,
858 &input_method_interface,
859 input_method, bind_input_method);
860
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200861 input_method->destroy_listener.notify = input_method_notifier_destroy;
Philipp Brüschweilerb13b9ff2012-09-09 23:08:31 +0200862 wl_signal_add(&seat->seat.destroy_signal, &input_method->destroy_listener);
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200863
864 seat->input_method = input_method;
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100865
866 launch_input_method(text_backend);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200867}
Jan Arne Petersencd8cdcc2012-08-10 16:47:23 +0200868
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100869static void
870text_backend_configuration(struct text_backend *text_backend)
871{
872 char *config_file;
873 char *path = NULL;
874
875 struct config_key input_method_keys[] = {
876 { "path", CONFIG_KEY_STRING, &path }
877 };
878
879 struct config_section cs[] = {
880 { "input-method", input_method_keys, ARRAY_LENGTH(input_method_keys), NULL }
881 };
882
883 config_file = config_file_path("weston.ini");
884 parse_config_file(config_file, cs, ARRAY_LENGTH(cs), text_backend);
885 free(config_file);
886
887 if (path)
888 text_backend->input_method.path = path;
889 else
890 text_backend->input_method.path = strdup(LIBEXECDIR "/weston-keyboard");
891}
892
893static void
894text_backend_notifier_destroy(struct wl_listener *listener, void *data)
895{
896 struct text_backend *text_backend =
897 container_of(listener, struct text_backend, destroy_listener);
898
899 if (text_backend->input_method.client)
900 wl_client_destroy(text_backend->input_method.client);
901
902 free(text_backend->input_method.path);
903
904 free(text_backend);
905}
906
907
908WL_EXPORT int
909text_backend_init(struct weston_compositor *ec)
910{
911 struct text_backend *text_backend;
912
913 text_backend = calloc(1, sizeof(*text_backend));
914
915 text_backend->compositor = ec;
916
917 text_backend->seat_created_listener.notify = handle_seat_created;
918 wl_signal_add(&ec->seat_created_signal,
919 &text_backend->seat_created_listener);
920
921 text_backend->destroy_listener.notify = text_backend_notifier_destroy;
922 wl_signal_add(&ec->destroy_signal, &text_backend->destroy_listener);
923
924 text_backend_configuration(text_backend);
925
Jan Arne Petersen78d00e42013-04-18 16:47:24 +0200926 text_input_manager_create(ec);
Jan Arne Petersen674fd1d2012-11-18 19:06:42 +0100927
928 return 0;
929}