1 /*
2 SPDX-FileCopyrightText: 2021 Roman Gilg <subdiff@gmail.com>
3
4 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only
5 */
6 #include "input_method_v2_p.h"
7
8 #include "text_input_v3_p.h"
9
10 #include "event_queue.h"
11 #include "seat.h"
12 #include "surface.h"
13
14 namespace Wrapland::Client
15 {
16
input_method_manager_v2(QObject * parent)17 input_method_manager_v2::input_method_manager_v2(QObject* parent)
18 : QObject(parent)
19 , d_ptr(new Private)
20 {
21 }
22
23 input_method_manager_v2::~input_method_manager_v2() = default;
24
setup(zwp_input_method_manager_v2 * manager)25 void input_method_manager_v2::setup(zwp_input_method_manager_v2* manager)
26 {
27 assert(manager);
28 assert(!d_ptr->manager_ptr);
29 d_ptr->manager_ptr.setup(manager);
30 }
31
release()32 void input_method_manager_v2::release()
33 {
34 d_ptr->release();
35 }
36
setEventQueue(EventQueue * queue)37 void input_method_manager_v2::setEventQueue(EventQueue* queue)
38 {
39 d_ptr->queue = queue;
40 }
41
event_queue()42 EventQueue* input_method_manager_v2::event_queue()
43 {
44 return d_ptr->queue;
45 }
46
operator zwp_input_method_manager_v2*()47 input_method_manager_v2::operator zwp_input_method_manager_v2*()
48 {
49 return *(d_ptr.get());
50 }
51
operator zwp_input_method_manager_v2*() const52 input_method_manager_v2::operator zwp_input_method_manager_v2*() const
53 {
54 return *(d_ptr.get());
55 }
56
isValid() const57 bool input_method_manager_v2::isValid() const
58 {
59 return d_ptr->isValid();
60 }
61
get_input_method(Seat * seat,QObject * parent)62 input_method_v2* input_method_manager_v2::get_input_method(Seat* seat, QObject* parent)
63 {
64 return d_ptr->get_input_method(seat, parent);
65 }
66
release()67 void input_method_manager_v2::Private::release()
68 {
69 manager_ptr.release();
70 }
71
isValid()72 bool input_method_manager_v2::Private::isValid()
73 {
74 return manager_ptr.isValid();
75 }
76
get_input_method(Seat * seat,QObject * parent)77 input_method_v2* input_method_manager_v2::Private::get_input_method(Seat* seat, QObject* parent)
78 {
79 assert(isValid());
80 auto im = new input_method_v2(seat, parent);
81 auto wlim = zwp_input_method_manager_v2_get_input_method(manager_ptr, *seat);
82 if (queue) {
83 queue->addProxy(wlim);
84 }
85 im->setup(wlim);
86 return im;
87 }
88
Private(Seat * seat,input_method_v2 * q)89 input_method_v2::Private::Private(Seat* seat, input_method_v2* q)
90 : seat{seat}
91 , q_ptr{q}
92 {
93 }
94
95 zwp_input_method_v2_listener const input_method_v2::Private::s_listener = {
96 activate_callback,
97 deactivate_callback,
98 surrounding_text_callback,
99 text_change_cause_callback,
100 content_type_callback,
101 done_callback,
102 unavailable_callback,
103 };
104
activate_callback(void * data,zwp_input_method_v2 * zwp_input_method_v2)105 void input_method_v2::Private::activate_callback(void* data,
106 zwp_input_method_v2* zwp_input_method_v2)
107 {
108 auto priv = reinterpret_cast<input_method_v2::Private*>(data);
109 assert(priv->input_method_ptr == zwp_input_method_v2);
110 priv->pending = {};
111 priv->pending.active = true;
112 }
113
deactivate_callback(void * data,zwp_input_method_v2 * zwp_input_method_v2)114 void input_method_v2::Private::deactivate_callback(void* data,
115 zwp_input_method_v2* zwp_input_method_v2)
116 {
117 auto priv = reinterpret_cast<input_method_v2::Private*>(data);
118 assert(priv->input_method_ptr == zwp_input_method_v2);
119 priv->pending.active = false;
120 }
121
surrounding_text_callback(void * data,zwp_input_method_v2 * zwp_input_method_v2,char const * text,uint32_t cursor,uint32_t anchor)122 void input_method_v2::Private::surrounding_text_callback(void* data,
123 zwp_input_method_v2* zwp_input_method_v2,
124 char const* text,
125 uint32_t cursor,
126 uint32_t anchor)
127 {
128 auto priv = reinterpret_cast<input_method_v2::Private*>(data);
129 assert(priv->input_method_ptr == zwp_input_method_v2);
130 priv->pending.surrounding_text.update = true;
131 priv->pending.surrounding_text.data = text;
132 priv->pending.surrounding_text.cursor_position = cursor;
133 priv->pending.surrounding_text.selection_anchor = anchor;
134 }
135
text_change_cause_callback(void * data,zwp_input_method_v2 * zwp_input_method_v2,uint32_t cause)136 void input_method_v2::Private::text_change_cause_callback(void* data,
137 zwp_input_method_v2* zwp_input_method_v2,
138 uint32_t cause)
139 {
140 auto priv = reinterpret_cast<input_method_v2::Private*>(data);
141 assert(priv->input_method_ptr == zwp_input_method_v2);
142 priv->pending.surrounding_text.change_cause = convert_change_cause(cause);
143 }
144
content_type_callback(void * data,zwp_input_method_v2 * zwp_input_method_v2,uint32_t hint,uint32_t purpose)145 void input_method_v2::Private::content_type_callback(void* data,
146 zwp_input_method_v2* zwp_input_method_v2,
147 uint32_t hint,
148 uint32_t purpose)
149 {
150 auto priv = reinterpret_cast<input_method_v2::Private*>(data);
151 assert(priv->input_method_ptr == zwp_input_method_v2);
152 priv->pending.content.hints = convert_content_hints(hint);
153 priv->pending.content.purpose = convert_content_purpose(purpose);
154 }
155
done_callback(void * data,zwp_input_method_v2 * zwp_input_method_v2)156 void input_method_v2::Private::done_callback(void* data, zwp_input_method_v2* zwp_input_method_v2)
157 {
158 auto priv = reinterpret_cast<input_method_v2::Private*>(data);
159 assert(priv->input_method_ptr == zwp_input_method_v2);
160 priv->serial++;
161 priv->current = priv->pending;
162 Q_EMIT priv->q_ptr->done();
163 }
164
unavailable_callback(void * data,zwp_input_method_v2 * zwp_input_method_v2)165 void input_method_v2::Private::unavailable_callback(void* data,
166 zwp_input_method_v2* zwp_input_method_v2)
167 {
168 auto priv = reinterpret_cast<input_method_v2::Private*>(data);
169 assert(priv->input_method_ptr == zwp_input_method_v2);
170 Q_EMIT priv->q_ptr->unavailable();
171 }
172
setup(zwp_input_method_v2 * input_method)173 void input_method_v2::Private::setup(zwp_input_method_v2* input_method)
174 {
175 assert(input_method);
176 assert(!input_method_ptr);
177 input_method_ptr.setup(input_method);
178 zwp_input_method_v2_add_listener(input_method, &s_listener, this);
179 }
180
isValid() const181 bool input_method_v2::Private::isValid() const
182 {
183 return input_method_ptr.isValid();
184 }
185
input_method_v2(Seat * seat,QObject * parent)186 input_method_v2::input_method_v2(Seat* seat, QObject* parent)
187 : QObject(parent)
188 , d_ptr(new Private(seat, this))
189 {
190 }
191
~input_method_v2()192 input_method_v2::~input_method_v2()
193 {
194 release();
195 }
196
setEventQueue(EventQueue * queue)197 void input_method_v2::setEventQueue(EventQueue* queue)
198 {
199 d_ptr->queue = queue;
200 }
201
event_queue() const202 EventQueue* input_method_v2::event_queue() const
203 {
204 return d_ptr->queue;
205 }
206
isValid() const207 bool input_method_v2::isValid() const
208 {
209 return d_ptr->isValid();
210 }
211
state() const212 input_method_v2_state const& input_method_v2::state() const
213 {
214 return d_ptr->current;
215 }
216
setup(zwp_input_method_v2 * input_method)217 void input_method_v2::setup(zwp_input_method_v2* input_method)
218 {
219 d_ptr->setup(input_method);
220 }
221
release()222 void input_method_v2::release()
223 {
224 d_ptr->input_method_ptr.release();
225 }
226
operator zwp_input_method_v2*()227 input_method_v2::operator zwp_input_method_v2*()
228 {
229 return d_ptr->input_method_ptr;
230 }
231
operator zwp_input_method_v2*() const232 input_method_v2::operator zwp_input_method_v2*() const
233 {
234 return d_ptr->input_method_ptr;
235 }
236
commit_string(std::string const & text)237 void input_method_v2::commit_string(std::string const& text)
238 {
239 zwp_input_method_v2_commit_string(d_ptr->input_method_ptr, text.c_str());
240 }
241
set_preedit_string(std::string const & text,int32_t cursor_begin,int32_t cursor_end)242 void input_method_v2::set_preedit_string(std::string const& text,
243 int32_t cursor_begin,
244 int32_t cursor_end)
245 {
246 zwp_input_method_v2_set_preedit_string(
247 d_ptr->input_method_ptr, text.c_str(), cursor_begin, cursor_end);
248 }
249
delete_surrounding_text(uint32_t before_length,uint32_t after_length)250 void input_method_v2::delete_surrounding_text(uint32_t before_length, uint32_t after_length)
251 {
252 zwp_input_method_v2_delete_surrounding_text(
253 d_ptr->input_method_ptr, before_length, after_length);
254 }
255
commit()256 void input_method_v2::commit()
257 {
258 zwp_input_method_v2_commit(d_ptr->input_method_ptr, d_ptr->serial);
259 }
260
get_input_popup_surface(Surface * surface,QObject * parent)261 input_popup_surface_v2* input_method_v2::get_input_popup_surface(Surface* surface, QObject* parent)
262 {
263 assert(isValid());
264 auto ips = new input_popup_surface_v2(parent);
265 auto wlips = zwp_input_method_v2_get_input_popup_surface(d_ptr->input_method_ptr, *surface);
266 if (d_ptr->queue) {
267 d_ptr->queue->addProxy(wlips);
268 }
269 ips->setup(wlips);
270 return ips;
271 }
272
grab_keyboard(QObject * parent)273 input_method_keyboard_grab_v2* input_method_v2::grab_keyboard(QObject* parent)
274 {
275 assert(isValid());
276 auto kg = new input_method_keyboard_grab_v2(parent);
277 auto wlkg = zwp_input_method_v2_grab_keyboard(d_ptr->input_method_ptr);
278 if (d_ptr->queue) {
279 d_ptr->queue->addProxy(wlkg);
280 }
281 kg->setup(wlkg);
282 return kg;
283 }
284
Private(input_popup_surface_v2 * q)285 input_popup_surface_v2::Private::Private(input_popup_surface_v2* q)
286 : q_ptr{q}
287 {
288 }
289
290 zwp_input_popup_surface_v2_listener const input_popup_surface_v2::Private::s_listener = {
291 text_input_rectangle_callback,
292 };
293
text_input_rectangle_callback(void * data,zwp_input_popup_surface_v2 * zwp_input_popup_surface_v2,int32_t x,int32_t y,int32_t width,int32_t height)294 void input_popup_surface_v2::Private::text_input_rectangle_callback(
295 void* data,
296 zwp_input_popup_surface_v2* zwp_input_popup_surface_v2,
297 int32_t x,
298 int32_t y,
299 int32_t width,
300 int32_t height)
301 {
302 auto priv = reinterpret_cast<input_popup_surface_v2::Private*>(data);
303 assert(priv->input_popup_ptr == zwp_input_popup_surface_v2);
304 priv->text_input_rectangle = QRect(x, y, width, height);
305 Q_EMIT priv->q_ptr->text_input_rectangle_changed();
306 }
307
setup(zwp_input_popup_surface_v2 * input_popup_surface)308 void input_popup_surface_v2::Private::setup(zwp_input_popup_surface_v2* input_popup_surface)
309 {
310 assert(input_popup_surface);
311 assert(!input_popup_ptr);
312 input_popup_ptr.setup(input_popup_surface);
313 zwp_input_popup_surface_v2_add_listener(input_popup_surface, &s_listener, this);
314 }
315
isValid() const316 bool input_popup_surface_v2::Private::isValid() const
317 {
318 return input_popup_ptr.isValid();
319 }
320
input_popup_surface_v2(QObject * parent)321 input_popup_surface_v2::input_popup_surface_v2(QObject* parent)
322 : QObject(parent)
323 , d_ptr(new Private(this))
324 {
325 }
326
~input_popup_surface_v2()327 input_popup_surface_v2::~input_popup_surface_v2()
328 {
329 release();
330 }
331
setEventQueue(EventQueue * queue)332 void input_popup_surface_v2::setEventQueue(EventQueue* queue)
333 {
334 d_ptr->queue = queue;
335 }
336
event_queue() const337 EventQueue* input_popup_surface_v2::event_queue() const
338 {
339 return d_ptr->queue;
340 }
341
isValid() const342 bool input_popup_surface_v2::isValid() const
343 {
344 return d_ptr->isValid();
345 }
346
setup(zwp_input_popup_surface_v2 * input_popup_surface)347 void input_popup_surface_v2::setup(zwp_input_popup_surface_v2* input_popup_surface)
348 {
349 d_ptr->setup(input_popup_surface);
350 }
351
release()352 void input_popup_surface_v2::release()
353 {
354 d_ptr->input_popup_ptr.release();
355 }
356
operator zwp_input_popup_surface_v2*()357 input_popup_surface_v2::operator zwp_input_popup_surface_v2*()
358 {
359 return d_ptr->input_popup_ptr;
360 }
361
operator zwp_input_popup_surface_v2*() const362 input_popup_surface_v2::operator zwp_input_popup_surface_v2*() const
363 {
364 return d_ptr->input_popup_ptr;
365 }
366
text_input_rectangle() const367 QRect input_popup_surface_v2::text_input_rectangle() const
368 {
369 return d_ptr->text_input_rectangle;
370 }
371
Private(input_method_keyboard_grab_v2 * q)372 input_method_keyboard_grab_v2::Private::Private(input_method_keyboard_grab_v2* q)
373 : q_ptr{q}
374 {
375 }
376
377 zwp_input_method_keyboard_grab_v2_listener const input_method_keyboard_grab_v2::Private::s_listener
378 = {
379 keymap_callback,
380 key_callback,
381 modifiers_callback,
382 repeat_info_callback,
383 };
384
keymap_callback(void * data,zwp_input_method_keyboard_grab_v2 * zwp_input_method_keyboard_grab_v2,uint32_t format,int fd,uint32_t size)385 void input_method_keyboard_grab_v2::Private::keymap_callback(
386 void* data,
387 zwp_input_method_keyboard_grab_v2* zwp_input_method_keyboard_grab_v2,
388 uint32_t format,
389 int fd,
390 uint32_t size)
391 {
392 auto priv = reinterpret_cast<input_method_keyboard_grab_v2::Private*>(data);
393 assert(priv->keyboard_grab_ptr == zwp_input_method_keyboard_grab_v2);
394
395 if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
396 return;
397 }
398 Q_EMIT priv->q_ptr->keymap_changed(fd, size);
399 }
400
key_callback(void * data,zwp_input_method_keyboard_grab_v2 * zwp_input_method_keyboard_grab_v2,uint32_t serial,uint32_t time,uint32_t key,uint32_t state)401 void input_method_keyboard_grab_v2::Private::key_callback(
402 void* data,
403 zwp_input_method_keyboard_grab_v2* zwp_input_method_keyboard_grab_v2,
404 [[maybe_unused]] uint32_t serial,
405 uint32_t time,
406 uint32_t key,
407 uint32_t state)
408 {
409 auto priv = reinterpret_cast<input_method_keyboard_grab_v2::Private*>(data);
410 assert(priv->keyboard_grab_ptr == zwp_input_method_keyboard_grab_v2);
411
412 auto to_state = [state] {
413 if (state == WL_KEYBOARD_KEY_STATE_RELEASED) {
414 return Keyboard::KeyState::Released;
415 } else {
416 return Keyboard::KeyState::Pressed;
417 }
418 };
419 Q_EMIT priv->q_ptr->key_changed(key, to_state(), time);
420 }
421
modifiers_callback(void * data,zwp_input_method_keyboard_grab_v2 * zwp_input_method_keyboard_grab_v2,uint32_t serial,uint32_t depressed,uint32_t latched,uint32_t locked,uint32_t group)422 void input_method_keyboard_grab_v2::Private::modifiers_callback(
423 void* data,
424 zwp_input_method_keyboard_grab_v2* zwp_input_method_keyboard_grab_v2,
425 [[maybe_unused]] uint32_t serial,
426 uint32_t depressed,
427 uint32_t latched,
428 uint32_t locked,
429 uint32_t group)
430 {
431 auto priv = reinterpret_cast<input_method_keyboard_grab_v2::Private*>(data);
432 assert(priv->keyboard_grab_ptr == zwp_input_method_keyboard_grab_v2);
433
434 Q_EMIT priv->q_ptr->modifiers_changed(depressed, latched, locked, group);
435 }
436
repeat_info_callback(void * data,zwp_input_method_keyboard_grab_v2 * zwp_input_method_keyboard_grab_v2,int32_t rate,int32_t delay)437 void input_method_keyboard_grab_v2::Private::repeat_info_callback(
438 void* data,
439 zwp_input_method_keyboard_grab_v2* zwp_input_method_keyboard_grab_v2,
440 int32_t rate,
441 int32_t delay)
442 {
443 auto priv = reinterpret_cast<input_method_keyboard_grab_v2::Private*>(data);
444 assert(priv->keyboard_grab_ptr == zwp_input_method_keyboard_grab_v2);
445
446 priv->repeat_info.rate = std::max(rate, 0);
447 priv->repeat_info.delay = std::max(delay, 0);
448 Q_EMIT priv->q_ptr->repeat_changed();
449 }
450
setup(zwp_input_method_keyboard_grab_v2 * keyboard_grab)451 void input_method_keyboard_grab_v2::Private::setup(zwp_input_method_keyboard_grab_v2* keyboard_grab)
452 {
453 assert(keyboard_grab);
454 assert(!keyboard_grab_ptr);
455 keyboard_grab_ptr.setup(keyboard_grab);
456 zwp_input_method_keyboard_grab_v2_add_listener(keyboard_grab, &s_listener, this);
457 }
458
isValid() const459 bool input_method_keyboard_grab_v2::Private::isValid() const
460 {
461 return keyboard_grab_ptr.isValid();
462 }
463
input_method_keyboard_grab_v2(QObject * parent)464 input_method_keyboard_grab_v2::input_method_keyboard_grab_v2(QObject* parent)
465 : QObject(parent)
466 , d_ptr(new Private(this))
467 {
468 }
469
~input_method_keyboard_grab_v2()470 input_method_keyboard_grab_v2::~input_method_keyboard_grab_v2()
471 {
472 release();
473 }
474
setEventQueue(EventQueue * queue)475 void input_method_keyboard_grab_v2::setEventQueue(EventQueue* queue)
476 {
477 d_ptr->queue = queue;
478 }
479
event_queue() const480 EventQueue* input_method_keyboard_grab_v2::event_queue() const
481 {
482 return d_ptr->queue;
483 }
484
isValid() const485 bool input_method_keyboard_grab_v2::isValid() const
486 {
487 return d_ptr->isValid();
488 }
489
setup(zwp_input_method_keyboard_grab_v2 * keyboard_grab)490 void input_method_keyboard_grab_v2::setup(zwp_input_method_keyboard_grab_v2* keyboard_grab)
491 {
492 d_ptr->setup(keyboard_grab);
493 }
494
release()495 void input_method_keyboard_grab_v2::release()
496 {
497 d_ptr->keyboard_grab_ptr.release();
498 }
499
operator zwp_input_method_keyboard_grab_v2*()500 input_method_keyboard_grab_v2::operator zwp_input_method_keyboard_grab_v2*()
501 {
502 return d_ptr->keyboard_grab_ptr;
503 }
504
operator zwp_input_method_keyboard_grab_v2*() const505 input_method_keyboard_grab_v2::operator zwp_input_method_keyboard_grab_v2*() const
506 {
507 return d_ptr->keyboard_grab_ptr;
508 }
509
repeat_rate() const510 int32_t input_method_keyboard_grab_v2::repeat_rate() const
511 {
512 return d_ptr->repeat_info.rate;
513 }
514
repeat_delay() const515 int32_t input_method_keyboard_grab_v2::repeat_delay() const
516 {
517 return d_ptr->repeat_info.delay;
518 }
519
520 }
521