KWayland

textinput_interface_v2.cpp
1 /*
2  SPDX-FileCopyrightText: 2016 Martin Gräßlin <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5 */
6 #include "textinput_interface_p.h"
7 #include "display.h"
8 #include "resource_p.h"
9 #include "seat_interface_p.h"
10 #include "surface_interface.h"
11 
12 #include <wayland-text-input-unstable-v2-server-protocol.h>
13 
14 namespace KWayland
15 {
16 namespace Server
17 {
18 
19 class TextInputUnstableV2Interface::Private : public TextInputInterface::Private
20 {
21 public:
22  Private(TextInputInterface *q, TextInputManagerUnstableV2Interface *c, wl_resource *parentResource);
23  ~Private();
24 
25  void sendEnter(SurfaceInterface *surface, quint32 serial) override;
26  void sendLeave(quint32 serial, SurfaceInterface *surface) override;
27  void preEdit(const QByteArray &text, const QByteArray &commit) override;
28  void commit(const QByteArray &text) override;
29  void deleteSurroundingText(quint32 beforeLength, quint32 afterLength) override;
30  void setTextDirection(Qt::LayoutDirection direction) override;
31  void setPreEditCursor(qint32 index) override;
32  void setCursorPosition(qint32 index, qint32 anchor) override;
33  void keysymPressed(quint32 keysym, Qt::KeyboardModifiers modifiers) override;
34  void keysymReleased(quint32 keysym, Qt::KeyboardModifiers modifiers) override;
35  TextInputInterfaceVersion interfaceVersion() const override {
37  }
38  void sendInputPanelState() override;
39  void sendLanguage() override;
40 
41 private:
42  static const struct zwp_text_input_v2_interface s_interface;
43  TextInputUnstableV2Interface *q_func() {
44  return reinterpret_cast<TextInputUnstableV2Interface *>(q);
45  }
46 
47  static void enableCallback(wl_client *client, wl_resource *resource, wl_resource * surface);
48  static void disableCallback(wl_client *client, wl_resource *resource, wl_resource * surface);
49  static void updateStateCallback(wl_client *client, wl_resource *resource, uint32_t serial, uint32_t reason);
50 
51  // helpers
52  TextInputInterface::ContentHints convertContentHint(uint32_t hint) const override;
53  TextInputInterface::ContentPurpose convertContentPurpose(uint32_t purpose) const override;
54 
55  void enable(SurfaceInterface *s);
56  void disable();
57 };
58 
59 #ifndef K_DOXYGEN
60 const struct zwp_text_input_v2_interface TextInputUnstableV2Interface::Private::s_interface = {
61  resourceDestroyedCallback,
62  enableCallback,
63  disableCallback,
64  showInputPanelCallback,
65  hideInputPanelCallback,
66  setSurroundingTextCallback,
67  setContentTypeCallback,
68  setCursorRectangleCallback,
69  setPreferredLanguageCallback,
70  updateStateCallback
71 };
72 #endif
73 
74 void TextInputUnstableV2Interface::Private::enable(SurfaceInterface *s)
75 {
76  surface = QPointer<SurfaceInterface>(s);
77  enabled = true;
78  emit q_func()->enabledChanged();
79 }
80 
81 void TextInputUnstableV2Interface::Private::disable()
82 {
83  surface.clear();
84  enabled = false;
85  emit q_func()->enabledChanged();
86 }
87 
88 void TextInputUnstableV2Interface::Private::sendEnter(SurfaceInterface *surface, quint32 serial)
89 {
90  if (!resource || !surface || !surface->resource()) {
91  return;
92  }
93  zwp_text_input_v2_send_enter(resource, serial, surface->resource());
94 }
95 
96 void TextInputUnstableV2Interface::Private::sendLeave(quint32 serial, SurfaceInterface *surface)
97 {
98  if (!resource || !surface || !surface->resource()) {
99  return;
100  }
101  zwp_text_input_v2_send_leave(resource, serial, surface->resource());
102 }
103 
104 void TextInputUnstableV2Interface::Private::preEdit(const QByteArray &text, const QByteArray &commit)
105 {
106  if (!resource) {
107  return;
108  }
109  zwp_text_input_v2_send_preedit_string(resource, text.constData(), commit.constData());
110 }
111 
112 void TextInputUnstableV2Interface::Private::commit(const QByteArray &text)
113 {
114  if (!resource) {
115  return;
116  }
117  zwp_text_input_v2_send_commit_string(resource, text.constData());
118 }
119 
120 void TextInputUnstableV2Interface::Private::keysymPressed(quint32 keysym, Qt::KeyboardModifiers modifiers)
121 {
122  Q_UNUSED(modifiers)
123  if (!resource) {
124  return;
125  }
126  zwp_text_input_v2_send_keysym(resource, seat ? seat->timestamp() : 0, keysym, WL_KEYBOARD_KEY_STATE_PRESSED, 0);
127 }
128 
129 void TextInputUnstableV2Interface::Private::keysymReleased(quint32 keysym, Qt::KeyboardModifiers modifiers)
130 {
131  Q_UNUSED(modifiers)
132  if (!resource) {
133  return;
134  }
135  zwp_text_input_v2_send_keysym(resource, seat ? seat->timestamp() : 0, keysym, WL_KEYBOARD_KEY_STATE_RELEASED, 0);
136 }
137 
138 void TextInputUnstableV2Interface::Private::deleteSurroundingText(quint32 beforeLength, quint32 afterLength)
139 {
140  if (!resource) {
141  return;
142  }
143  zwp_text_input_v2_send_delete_surrounding_text(resource, beforeLength, afterLength);
144 }
145 
146 void TextInputUnstableV2Interface::Private::setCursorPosition(qint32 index, qint32 anchor)
147 {
148  if (!resource) {
149  return;
150  }
151  zwp_text_input_v2_send_cursor_position(resource, index, anchor);
152 }
153 
154 void TextInputUnstableV2Interface::Private::setTextDirection(Qt::LayoutDirection direction)
155 {
156  if (!resource) {
157  return;
158  }
159  zwp_text_input_v2_text_direction wlDirection;
160  switch (direction) {
161  case Qt::LeftToRight:
162  wlDirection = ZWP_TEXT_INPUT_V2_TEXT_DIRECTION_LTR;
163  break;
164  case Qt::RightToLeft:
165  wlDirection = ZWP_TEXT_INPUT_V2_TEXT_DIRECTION_RTL;
166  break;
168  wlDirection = ZWP_TEXT_INPUT_V2_TEXT_DIRECTION_AUTO;
169  break;
170  default:
171  Q_UNREACHABLE();
172  break;
173  }
174  zwp_text_input_v2_send_text_direction(resource, wlDirection);
175 }
176 
177 void TextInputUnstableV2Interface::Private::setPreEditCursor(qint32 index)
178 {
179  if (!resource) {
180  return;
181  }
182  zwp_text_input_v2_send_preedit_cursor(resource, index);
183 }
184 
185 void TextInputUnstableV2Interface::Private::sendInputPanelState()
186 {
187  if (!resource) {
188  return;
189  }
190  zwp_text_input_v2_send_input_panel_state(resource,
191  inputPanelVisible ? ZWP_TEXT_INPUT_V2_INPUT_PANEL_VISIBILITY_VISIBLE : ZWP_TEXT_INPUT_V2_INPUT_PANEL_VISIBILITY_HIDDEN,
192  overlappedSurfaceArea.x(), overlappedSurfaceArea.y(), overlappedSurfaceArea.width(), overlappedSurfaceArea.height());
193 }
194 
195 void TextInputUnstableV2Interface::Private::sendLanguage()
196 {
197  if (!resource) {
198  return;
199  }
200  zwp_text_input_v2_send_language(resource, language.constData());
201 }
202 
203 TextInputUnstableV2Interface::Private::Private(TextInputInterface *q, TextInputManagerUnstableV2Interface *c, wl_resource *parentResource)
204  : TextInputInterface::Private(q, c, parentResource, &zwp_text_input_v2_interface, &s_interface)
205 {
206 }
207 
208 TextInputUnstableV2Interface::Private::~Private() = default;
209 
210 void TextInputUnstableV2Interface::Private::enableCallback(wl_client *client, wl_resource *resource, wl_resource *surface)
211 {
212  auto p = cast<Private>(resource);
213  Q_ASSERT(*p->client == client);
214  p->enable(SurfaceInterface::get(surface));
215 }
216 
217 void TextInputUnstableV2Interface::Private::disableCallback(wl_client *client, wl_resource *resource, wl_resource *surface)
218 {
219  Q_UNUSED(surface)
220  auto p = cast<Private>(resource);
221  Q_ASSERT(*p->client == client);
222  p->disable();
223 }
224 
225 void TextInputUnstableV2Interface::Private::updateStateCallback(wl_client *client, wl_resource *resource, uint32_t serial, uint32_t reason)
226 {
227  auto p = cast<Private>(resource);
228  Q_ASSERT(*p->client == client);
229  Q_UNUSED(serial)
230  // TODO: use other reason values reason
231  if (reason == ZWP_TEXT_INPUT_V2_UPDATE_STATE_RESET) {
232  emit p->q_func()->requestReset();
233  }
234 }
235 
236 TextInputInterface::ContentHints TextInputUnstableV2Interface::Private::convertContentHint(uint32_t hint) const
237 {
238  const auto hints = zwp_text_input_v2_content_hint(hint);
239  TextInputInterface::ContentHints ret = TextInputInterface::ContentHint::None;
240 
241  if (hints & ZWP_TEXT_INPUT_V2_CONTENT_HINT_AUTO_COMPLETION) {
243  }
244  if (hints & ZWP_TEXT_INPUT_V2_CONTENT_HINT_AUTO_CORRECTION) {
246  }
247  if (hints & ZWP_TEXT_INPUT_V2_CONTENT_HINT_AUTO_CAPITALIZATION) {
249  }
250  if (hints & ZWP_TEXT_INPUT_V2_CONTENT_HINT_LOWERCASE) {
252  }
253  if (hints & ZWP_TEXT_INPUT_V2_CONTENT_HINT_UPPERCASE) {
255  }
256  if (hints & ZWP_TEXT_INPUT_V2_CONTENT_HINT_TITLECASE) {
258  }
259  if (hints & ZWP_TEXT_INPUT_V2_CONTENT_HINT_HIDDEN_TEXT) {
261  }
262  if (hints & ZWP_TEXT_INPUT_V2_CONTENT_HINT_SENSITIVE_DATA) {
264  }
265  if (hints & ZWP_TEXT_INPUT_V2_CONTENT_HINT_LATIN) {
267  }
268  if (hints & ZWP_TEXT_INPUT_V2_CONTENT_HINT_MULTILINE) {
270  }
271  return ret;
272 }
273 
274 TextInputInterface::ContentPurpose TextInputUnstableV2Interface::Private::convertContentPurpose(uint32_t purpose) const
275 {
276  const auto wlPurpose = zwp_text_input_v2_content_purpose(purpose);
277 
278  switch (wlPurpose) {
279  case ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_ALPHA:
281  case ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_DIGITS:
283  case ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_NUMBER:
285  case ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_PHONE:
287  case ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_URL:
289  case ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_EMAIL:
291  case ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_NAME:
293  case ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_PASSWORD:
295  case ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_DATE:
297  case ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_TIME:
299  case ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_DATETIME:
301  case ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_TERMINAL:
303  case ZWP_TEXT_INPUT_V2_CONTENT_PURPOSE_NORMAL:
304  default:
306  }
307 }
308 
309 TextInputUnstableV2Interface::TextInputUnstableV2Interface(TextInputManagerUnstableV2Interface *parent, wl_resource *parentResource)
310  : TextInputInterface(new Private(this, parent, parentResource))
311 {
312 }
313 
314 TextInputUnstableV2Interface::~TextInputUnstableV2Interface() = default;
315 
316 class TextInputManagerUnstableV2Interface::Private : public TextInputManagerInterface::Private
317 {
318 public:
319  Private(TextInputManagerUnstableV2Interface *q, Display *d);
320 
321 private:
322  void bind(wl_client *client, uint32_t version, uint32_t id) override;
323 
324  static void unbind(wl_resource *resource);
325  static Private *cast(wl_resource *r) {
326  return reinterpret_cast<Private*>(wl_resource_get_user_data(r));
327  }
328 
329  static void destroyCallback(wl_client *client, wl_resource *resource);
330  static void getTextInputCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource * seat);
331 
332  TextInputManagerUnstableV2Interface *q;
333  static const struct zwp_text_input_manager_v2_interface s_interface;
334  static const quint32 s_version;
335 };
336 const quint32 TextInputManagerUnstableV2Interface::Private::s_version = 1;
337 
338 #ifndef K_DOXYGEN
339 const struct zwp_text_input_manager_v2_interface TextInputManagerUnstableV2Interface::Private::s_interface = {
340  destroyCallback,
341  getTextInputCallback
342 };
343 #endif
344 
345 void TextInputManagerUnstableV2Interface::Private::destroyCallback(wl_client *client, wl_resource *resource)
346 {
347  Q_UNUSED(client)
348  wl_resource_destroy(resource);
349 }
350 
351 void TextInputManagerUnstableV2Interface::Private::getTextInputCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource * seat)
352 {
353  SeatInterface *s = SeatInterface::get(seat);
354  if (!s) {
355  // TODO: send error
356  return;
357  }
358  auto m = cast(resource);
359  auto *t = new TextInputUnstableV2Interface(m->q, resource);
360  t->d_func()->seat = s;
361  m->inputs << t;
363  [t, m] {
364  m->inputs.removeAll(t);
365  }
366  );
367  t->d->create(m->display->getConnection(client), version, id);
368  s->d_func()->registerTextInput(t);
369 }
370 
371 TextInputManagerUnstableV2Interface::Private::Private(TextInputManagerUnstableV2Interface *q, Display *d)
372  : TextInputManagerInterface::Private(TextInputInterfaceVersion::UnstableV2, q, d, &zwp_text_input_manager_v2_interface, s_version)
373  , q(q)
374 {
375 }
376 
377 void TextInputManagerUnstableV2Interface::Private::bind(wl_client *client, uint32_t version, uint32_t id)
378 {
379  auto c = display->getConnection(client);
380  wl_resource *resource = c->createResource(&zwp_text_input_manager_v2_interface, qMin(version, s_version), id);
381  if (!resource) {
382  wl_client_post_no_memory(client);
383  return;
384  }
385  wl_resource_set_implementation(resource, &s_interface, this, unbind);
386  // TODO: should we track?
387 }
388 
389 void TextInputManagerUnstableV2Interface::Private::unbind(wl_resource *resource)
390 {
391  Q_UNUSED(resource)
392  // TODO: implement?
393 }
394 
395 TextInputManagerUnstableV2Interface::TextInputManagerUnstableV2Interface(Display *display, QObject *parent)
396  : TextInputManagerInterface(new Private(this, display), parent)
397 {
398 }
399 
400 TextInputManagerUnstableV2Interface::~TextInputManagerUnstableV2Interface() = default;
401 
402 }
403 }
quint32 id() const
Definition: resource.cpp:98
typedef KeyboardModifiers
ContentPurpose
The ContentPurpose allows to specify the primary purpose of a text input.
void clear()
wl_resource * parentResource() const
Definition: resource.cpp:93
LayoutDirection
TextInputInterfaceVersion
Enum describing the different InterfaceVersion encapsulated in this implementation.
static SurfaceInterface * get(wl_resource *native)
wl_resource * resource()
Definition: resource.cpp:88
const char * constData() const const
switch to uppercase letters at the start of a sentence
input a number (including decimal separator and sign)
prefer casing for titles and headings (can be language dependent)
just latin characters should be entered
ClientConnection * client()
Definition: resource.cpp:78
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const const
void destroyed(QObject *obj)
KDB_EXPORT KDbVersionInfo version()
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Fri Aug 7 2020 22:48:20 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.