blob: c634aec04f5cd266667945f5c60d45a349595800 [file] [log] [blame]
Jan Arne Petersen1f17be42012-06-21 21:52:18 +02001/*
2 * Copyright © 2012 Openismus GmbH
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and
5 * its documentation for any purpose is hereby granted without fee, provided
6 * that the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of the copyright holders not be used in
9 * advertising or publicity pertaining to distribution of the software
10 * without specific, written prior permission. The copyright holders make
11 * no representations about the suitability of this software for any
12 * purpose. It is provided "as is" without express or implied warranty.
13 *
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
15 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
17 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
18 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
19 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 */
22
23#include <stdlib.h>
24
25#include "compositor.h"
26#include "text-server-protocol.h"
27
28struct input_method;
29
30struct text_model {
31 struct wl_resource resource;
32
Jan Arne Petersene829adc2012-08-10 16:47:22 +020033 struct weston_compositor *ec;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +020034
Jan Arne Petersene829adc2012-08-10 16:47:22 +020035 struct wl_list input_methods;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +020036};
37
38struct input_method {
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +020039 struct wl_resource *input_method_binding;
40 struct wl_global *input_method_global;
Jan Arne Petersen51963742012-08-10 16:47:20 +020041 struct wl_global *text_model_factory_global;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +020042 struct wl_listener destroy_listener;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +020043
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +020044 struct weston_compositor *ec;
Jan Arne Petersene829adc2012-08-10 16:47:22 +020045 struct text_model *model;
46
47 struct wl_list link;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +020048};
49
50static void
Jan Arne Petersene829adc2012-08-10 16:47:22 +020051deactivate_text_model(struct text_model *text_model,
52 struct input_method *input_method)
Philipp Brüschweiler17467812012-07-11 22:25:30 +020053{
Jan Arne Petersene829adc2012-08-10 16:47:22 +020054 struct weston_compositor *ec = text_model->ec;
Philipp Brüschweiler17467812012-07-11 22:25:30 +020055
Jan Arne Petersene829adc2012-08-10 16:47:22 +020056 if (input_method->model == text_model) {
57 wl_list_remove(&input_method->link);
58 input_method->model = NULL;
Kristian Høgsbergf97f3792012-07-22 11:51:42 -040059 wl_signal_emit(&ec->hide_input_panel_signal, ec);
Jan Arne Petersende3b6a12012-08-10 16:47:21 +020060 text_model_send_deactivated(&text_model->resource);
Philipp Brüschweiler17467812012-07-11 22:25:30 +020061 }
62}
63
64static void
Jan Arne Petersen1f17be42012-06-21 21:52:18 +020065destroy_text_model(struct wl_resource *resource)
66{
Kristian Høgsbergf97f3792012-07-22 11:51:42 -040067 struct text_model *text_model =
68 container_of(resource, struct text_model, resource);
Jan Arne Petersene829adc2012-08-10 16:47:22 +020069 struct input_method *input_method, *next;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +020070
Jan Arne Petersene829adc2012-08-10 16:47:22 +020071 wl_list_for_each_safe(input_method, next, &text_model->input_methods, link)
72 deactivate_text_model(text_model, input_method);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +020073
Jan Arne Petersen1f17be42012-06-21 21:52:18 +020074 free(text_model);
75}
76
77static void
78text_model_set_surrounding_text(struct wl_client *client,
79 struct wl_resource *resource,
80 const char *text)
81{
82}
83
84static void
85text_model_set_cursor_index(struct wl_client *client,
86 struct wl_resource *resource,
87 uint32_t index)
88{
89}
90
91static void
92text_model_activate(struct wl_client *client,
Jan Arne Petersene829adc2012-08-10 16:47:22 +020093 struct wl_resource *resource,
94 struct wl_resource *seat,
95 struct wl_resource *surface)
Jan Arne Petersen1f17be42012-06-21 21:52:18 +020096{
97 struct text_model *text_model = resource->data;
Jan Arne Petersene829adc2012-08-10 16:47:22 +020098 struct weston_seat *weston_seat = seat->data;
99 struct text_model *old = weston_seat->input_method->model;
100 struct weston_compositor *ec = text_model->ec;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200101
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200102 if (old == text_model)
103 return;
Jan Arne Petersende3b6a12012-08-10 16:47:21 +0200104
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200105 if (old) {
106 deactivate_text_model(old,
107 weston_seat->input_method);
Jan Arne Petersende3b6a12012-08-10 16:47:21 +0200108 }
109
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200110 weston_seat->input_method->model = text_model;
111 wl_list_insert(&text_model->input_methods, &weston_seat->input_method->link);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200112
Kristian Høgsbergf97f3792012-07-22 11:51:42 -0400113 wl_signal_emit(&ec->show_input_panel_signal, ec);
Jan Arne Petersende3b6a12012-08-10 16:47:21 +0200114
115 text_model_send_activated(&text_model->resource);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200116}
117
118static void
119text_model_deactivate(struct wl_client *client,
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200120 struct wl_resource *resource,
121 struct wl_resource *seat)
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200122{
123 struct text_model *text_model = resource->data;
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200124 struct weston_seat *weston_seat = seat->data;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200125
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200126 deactivate_text_model(text_model,
127 weston_seat->input_method);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200128}
129
130static void
131text_model_set_selected_text(struct wl_client *client,
132 struct wl_resource *resource,
133 const char *text,
134 int32_t index)
135{
136}
137
138static void
139text_model_set_micro_focus(struct wl_client *client,
140 struct wl_resource *resource,
141 int32_t x,
142 int32_t y,
143 int32_t width,
144 int32_t height)
145{
146}
147
148static void
149text_model_set_preedit(struct wl_client *client,
150 struct wl_resource *resource)
151{
152}
153
154static void
155text_model_set_content_type(struct wl_client *client,
156 struct wl_resource *resource)
157{
158}
159
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200160static const struct text_model_interface text_model_implementation = {
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200161 text_model_set_surrounding_text,
162 text_model_set_cursor_index,
163 text_model_activate,
164 text_model_deactivate,
165 text_model_set_selected_text,
166 text_model_set_micro_focus,
167 text_model_set_preedit,
168 text_model_set_content_type
169};
170
Jan Arne Petersen51963742012-08-10 16:47:20 +0200171static void text_model_factory_create_text_model(struct wl_client *client,
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200172 struct wl_resource *resource,
173 uint32_t id,
174 struct wl_resource *surface)
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200175{
176 struct input_method *input_method = resource->data;
177 struct text_model *text_model;
178
Philipp Brüschweiler17467812012-07-11 22:25:30 +0200179 text_model = calloc(1, sizeof *text_model);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200180
181 text_model->resource.destroy = destroy_text_model;
Philipp Brüschweiler17467812012-07-11 22:25:30 +0200182
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200183 text_model->resource.object.id = id;
184 text_model->resource.object.interface = &text_model_interface;
Philipp Brüschweiler17467812012-07-11 22:25:30 +0200185 text_model->resource.object.implementation =
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200186 (void (**)(void)) &text_model_implementation;
187 text_model->resource.data = text_model;
188
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200189 text_model->ec = input_method->ec;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200190
191 wl_client_add_resource(client, &text_model->resource);
192
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200193 wl_list_init(&text_model->input_methods);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200194};
195
Jan Arne Petersen51963742012-08-10 16:47:20 +0200196static const struct text_model_factory_interface text_model_factory_implementation = {
197 text_model_factory_create_text_model
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200198};
199
200static void
Jan Arne Petersen51963742012-08-10 16:47:20 +0200201bind_text_model_factory(struct wl_client *client,
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200202 void *data,
203 uint32_t version,
204 uint32_t id)
205{
206 struct input_method *input_method = data;
207
208 /* No checking for duplicate binding necessary.
209 * No events have to be sent, so we don't need the return value. */
Jan Arne Petersen51963742012-08-10 16:47:20 +0200210 wl_client_add_object(client, &text_model_factory_interface,
211 &text_model_factory_implementation,
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200212 id, input_method);
213}
214
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200215static void
216input_method_commit_string(struct wl_client *client,
217 struct wl_resource *resource,
218 const char *text,
219 uint32_t index)
220{
221 struct input_method *input_method = resource->data;
222
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200223 if (input_method->model) {
224 text_model_send_commit_string(&input_method->model->resource, text, index);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200225 }
226}
227
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200228static const struct input_method_interface input_method_implementation = {
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200229 input_method_commit_string
230};
231
232static void
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200233unbind_input_method(struct wl_resource *resource)
234{
235 struct input_method *input_method = resource->data;
236
237 input_method->input_method_binding = NULL;
238 free(resource);
239}
240
241static void
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200242bind_input_method(struct wl_client *client,
243 void *data,
244 uint32_t version,
245 uint32_t id)
246{
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200247 struct input_method *input_method = data;
248 struct wl_resource *resource;
249
250 resource = wl_client_add_object(client, &input_method_interface,
251 &input_method_implementation,
252 id, input_method);
253
254 if (input_method->input_method_binding == NULL) {
255 resource->destroy = unbind_input_method;
256 input_method->input_method_binding = resource;
257 return;
258 }
259
260 wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
261 "interface object already bound");
262 wl_resource_destroy(resource);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200263}
264
265static void
266input_method_notifier_destroy(struct wl_listener *listener, void *data)
267{
Kristian Høgsbergf97f3792012-07-22 11:51:42 -0400268 struct input_method *input_method =
269 container_of(listener, struct input_method, destroy_listener);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200270
Kristian Høgsbergf97f3792012-07-22 11:51:42 -0400271 wl_display_remove_global(input_method->ec->wl_display,
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200272 input_method->input_method_global);
273 wl_display_remove_global(input_method->ec->wl_display,
Jan Arne Petersen51963742012-08-10 16:47:20 +0200274 input_method->text_model_factory_global);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200275 free(input_method);
276}
277
278void
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200279input_method_create(struct weston_compositor *ec,
280 struct weston_seat *seat)
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200281{
282 struct input_method *input_method;
283
Philipp Brüschweiler17467812012-07-11 22:25:30 +0200284 input_method = calloc(1, sizeof *input_method);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200285
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200286 input_method->ec = ec;
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200287 input_method->model = NULL;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200288
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200289 input_method->input_method_global =
290 wl_display_add_global(ec->wl_display,
291 &input_method_interface,
292 input_method, bind_input_method);
293
Jan Arne Petersen51963742012-08-10 16:47:20 +0200294 input_method->text_model_factory_global =
Philipp Brüschweilerf25602b2012-07-11 22:25:31 +0200295 wl_display_add_global(ec->wl_display,
Jan Arne Petersen51963742012-08-10 16:47:20 +0200296 &text_model_factory_interface,
297 input_method, bind_text_model_factory);
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200298
299 input_method->destroy_listener.notify = input_method_notifier_destroy;
Philipp Brüschweiler17467812012-07-11 22:25:30 +0200300 wl_signal_add(&ec->destroy_signal, &input_method->destroy_listener);
Jan Arne Petersene829adc2012-08-10 16:47:22 +0200301
302 seat->input_method = input_method;
Jan Arne Petersen1f17be42012-06-21 21:52:18 +0200303}