KWayland

textinput_interface_v0.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-server-protocol.h>
13 
14 namespace KWayland
15 {
16 namespace Server
17 {
18 
19 class TextInputUnstableV0Interface::Private : public TextInputInterface::Private
20 {
21 public:
22  Private(TextInputInterface *q, TextInputManagerUnstableV0Interface *c, wl_resource *parentResource);
23  ~Private();
24 
25  void activate(SeatInterface *seat, SurfaceInterface *surface);
26  void deactivate();
27 
28  void sendEnter(SurfaceInterface *surface, quint32 serial) override;
29  void sendLeave(quint32 serial, SurfaceInterface *surface) override;
30  void preEdit(const QByteArray &text, const QByteArray &commit) override;
31  void commit(const QByteArray &text) override;
32  void deleteSurroundingText(quint32 beforeLength, quint32 afterLength) override;
33  void setTextDirection(Qt::LayoutDirection direction) override;
34  void setPreEditCursor(qint32 index) override;
35  void setCursorPosition(qint32 index, qint32 anchor) override;
36  void keysymPressed(quint32 keysym, Qt::KeyboardModifiers modifiers) override;
37  void keysymReleased(quint32 keysym, Qt::KeyboardModifiers modifiers) override;
38  TextInputInterfaceVersion interfaceVersion() const override {
40  }
41  void sendInputPanelState() override;
42  void sendLanguage() override;
43 
44 private:
45  static const struct wl_text_input_interface s_interface;
46  TextInputUnstableV0Interface *q_func() {
47  return reinterpret_cast<TextInputUnstableV0Interface *>(q);
48  }
49 
50  static void activateCallback(wl_client *client, wl_resource *resource, wl_resource * seat, wl_resource * surface);
51  static void deactivateCallback(wl_client *client, wl_resource *resource, wl_resource * seat);
52  static void resetCallback(wl_client *client, wl_resource *resource);
53  static void setSurroundingTextUintCallback(wl_client *client, wl_resource *resource, const char * text, uint32_t cursor, uint32_t anchor);
54  static void commitStateCallback(wl_client *client, wl_resource *resource, uint32_t serial);
55  static void invokeActionCallback(wl_client *client, wl_resource *resource, uint32_t button, uint32_t index);
56 
57  // helpers
58  TextInputInterface::ContentHints convertContentHint(uint32_t hint) const override;
59  TextInputInterface::ContentPurpose convertContentPurpose(uint32_t purpose) const override;
60 
61  quint32 latestState = 0;
62 };
63 
64 #ifndef K_DOXYGEN
65 const struct wl_text_input_interface TextInputUnstableV0Interface::Private::s_interface = {
66  activateCallback,
67  deactivateCallback,
68  showInputPanelCallback,
69  hideInputPanelCallback,
70  resetCallback,
71  setSurroundingTextUintCallback,
72  setContentTypeCallback,
73  setCursorRectangleCallback,
74  setPreferredLanguageCallback,
75  commitStateCallback,
76  invokeActionCallback
77 };
78 #endif
79 
80 void TextInputUnstableV0Interface::Private::activate(SeatInterface *seat, SurfaceInterface *s)
81 {
82  surface = QPointer<SurfaceInterface>(s);
83  enabled = true;
84  emit q_func()->enabledChanged();
85  emit q_func()->requestActivate(seat, surface);
86 }
87 
88 void TextInputUnstableV0Interface::Private::deactivate()
89 {
90  surface.clear();
91  enabled = false;
92  emit q_func()->enabledChanged();
93 }
94 
95 void TextInputUnstableV0Interface::Private::sendEnter(SurfaceInterface *surface, quint32 serial)
96 {
97  Q_UNUSED(serial)
98  if (!resource) {
99  return;
100  }
101  wl_text_input_send_enter(resource, surface->resource());
102 }
103 
104 void TextInputUnstableV0Interface::Private::sendLeave(quint32 serial, SurfaceInterface *surface)
105 {
106  Q_UNUSED(serial)
107  Q_UNUSED(surface)
108  if (!resource) {
109  return;
110  }
111  wl_text_input_send_leave(resource);
112 }
113 
114 void TextInputUnstableV0Interface::Private::preEdit(const QByteArray &text, const QByteArray &commit)
115 {
116  if (!resource) {
117  return;
118  }
119  wl_text_input_send_preedit_string(resource, latestState, text.constData(), commit.constData());
120 }
121 
122 void TextInputUnstableV0Interface::Private::commit(const QByteArray &text)
123 {
124  if (!resource) {
125  return;
126  }
127  wl_text_input_send_commit_string(resource, latestState, text.constData());
128 }
129 
130 void TextInputUnstableV0Interface::Private::keysymPressed(quint32 keysym, Qt::KeyboardModifiers modifiers)
131 {
132  Q_UNUSED(modifiers)
133  if (!resource) {
134  return;
135  }
136  wl_text_input_send_keysym(resource, latestState, seat ? seat->timestamp() : 0, keysym, WL_KEYBOARD_KEY_STATE_PRESSED, 0);
137 }
138 
139 void TextInputUnstableV0Interface::Private::keysymReleased(quint32 keysym, Qt::KeyboardModifiers modifiers)
140 {
141  Q_UNUSED(modifiers)
142  if (!resource) {
143  return;
144  }
145  wl_text_input_send_keysym(resource, latestState, seat ? seat->timestamp() : 0, keysym, WL_KEYBOARD_KEY_STATE_RELEASED, 0);
146 }
147 
148 void TextInputUnstableV0Interface::Private::deleteSurroundingText(quint32 beforeLength, quint32 afterLength)
149 {
150  if (!resource) {
151  return;
152  }
153  wl_text_input_send_delete_surrounding_text(resource, -1 * beforeLength, beforeLength + afterLength);
154 }
155 
156 void TextInputUnstableV0Interface::Private::setCursorPosition(qint32 index, qint32 anchor)
157 {
158  if (!resource) {
159  return;
160  }
161  wl_text_input_send_cursor_position(resource, index, anchor);
162 }
163 
164 void TextInputUnstableV0Interface::Private::setTextDirection(Qt::LayoutDirection direction)
165 {
166  if (!resource) {
167  return;
168  }
169  wl_text_input_text_direction wlDirection;
170  switch (direction) {
171  case Qt::LeftToRight:
172  wlDirection = WL_TEXT_INPUT_TEXT_DIRECTION_LTR;
173  break;
174  case Qt::RightToLeft:
175  wlDirection = WL_TEXT_INPUT_TEXT_DIRECTION_RTL;
176  break;
178  wlDirection = WL_TEXT_INPUT_TEXT_DIRECTION_AUTO;
179  break;
180  default:
181  Q_UNREACHABLE();
182  break;
183  }
184  wl_text_input_send_text_direction(resource, latestState, wlDirection);
185 }
186 
187 void TextInputUnstableV0Interface::Private::setPreEditCursor(qint32 index)
188 {
189  if (!resource) {
190  return;
191  }
192  wl_text_input_send_preedit_cursor(resource, index);
193 }
194 
195 void TextInputUnstableV0Interface::Private::sendInputPanelState()
196 {
197  if (!resource) {
198  return;
199  }
200  wl_text_input_send_input_panel_state(resource, inputPanelVisible);
201 }
202 
203 void TextInputUnstableV0Interface::Private::sendLanguage()
204 {
205  if (!resource) {
206  return;
207  }
208  wl_text_input_send_language(resource, latestState, language.constData());
209 }
210 
211 TextInputUnstableV0Interface::Private::Private(TextInputInterface *q, TextInputManagerUnstableV0Interface *c, wl_resource *parentResource)
212  : TextInputInterface::Private(q, c, parentResource, &wl_text_input_interface, &s_interface)
213 {
214 }
215 
216 TextInputUnstableV0Interface::Private::~Private() = default;
217 
218 void TextInputUnstableV0Interface::Private::activateCallback(wl_client *client, wl_resource *resource, wl_resource *seat, wl_resource *surface)
219 {
220  auto p = cast<Private>(resource);
221  Q_ASSERT(*p->client == client);
222  p->activate(SeatInterface::get(seat), SurfaceInterface::get(surface));
223 }
224 
225 void TextInputUnstableV0Interface::Private::deactivateCallback(wl_client *client, wl_resource *resource, wl_resource *seat)
226 {
227  Q_UNUSED(seat)
228  auto p = cast<Private>(resource);
229  Q_ASSERT(*p->client == client);
230  p->deactivate();
231 }
232 
233 void TextInputUnstableV0Interface::Private::resetCallback(wl_client *client, wl_resource *resource)
234 {
235  auto p = cast<Private>(resource);
236  Q_ASSERT(*p->client == client);
237  emit p->q_func()->requestReset();
238 }
239 
240 void TextInputUnstableV0Interface::Private::setSurroundingTextUintCallback(wl_client *client, wl_resource *resource, const char * text, uint32_t cursor, uint32_t anchor)
241 {
242  setSurroundingTextCallback(client, resource, text, cursor, anchor);
243 }
244 
245 void TextInputUnstableV0Interface::Private::commitStateCallback(wl_client *client, wl_resource *resource, uint32_t serial)
246 {
247  auto p = cast<Private>(resource);
248  Q_ASSERT(*p->client == client);
249  p->latestState = serial;
250 }
251 
252 void TextInputUnstableV0Interface::Private::invokeActionCallback(wl_client *client, wl_resource *resource, uint32_t button, uint32_t index)
253 {
254  Q_UNUSED(button)
255  Q_UNUSED(index)
256  // TODO: implement
257  auto p = cast<Private>(resource);
258  Q_ASSERT(*p->client == client);
259 }
260 
261 TextInputInterface::ContentHints TextInputUnstableV0Interface::Private::convertContentHint(uint32_t hint) const
262 {
263  const auto hints = wl_text_input_content_hint(hint);
264  TextInputInterface::ContentHints ret = TextInputInterface::ContentHint::None;
265 
266  if (hints & WL_TEXT_INPUT_CONTENT_HINT_AUTO_COMPLETION) {
268  }
269  if (hints & WL_TEXT_INPUT_CONTENT_HINT_AUTO_CORRECTION) {
271  }
272  if (hints & WL_TEXT_INPUT_CONTENT_HINT_AUTO_CAPITALIZATION) {
274  }
275  if (hints & WL_TEXT_INPUT_CONTENT_HINT_LOWERCASE) {
277  }
278  if (hints & WL_TEXT_INPUT_CONTENT_HINT_UPPERCASE) {
280  }
281  if (hints & WL_TEXT_INPUT_CONTENT_HINT_TITLECASE) {
283  }
284  if (hints & WL_TEXT_INPUT_CONTENT_HINT_HIDDEN_TEXT) {
286  }
287  if (hints & WL_TEXT_INPUT_CONTENT_HINT_SENSITIVE_DATA) {
289  }
290  if (hints & WL_TEXT_INPUT_CONTENT_HINT_LATIN) {
292  }
293  if (hints & WL_TEXT_INPUT_CONTENT_HINT_MULTILINE) {
295  }
296  return ret;
297 }
298 
299 TextInputInterface::ContentPurpose TextInputUnstableV0Interface::Private::convertContentPurpose(uint32_t purpose) const
300 {
301  const auto wlPurpose = wl_text_input_content_purpose(purpose);
302 
303  switch (wlPurpose) {
304  case WL_TEXT_INPUT_CONTENT_PURPOSE_ALPHA:
306  case WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS:
308  case WL_TEXT_INPUT_CONTENT_PURPOSE_NUMBER:
310  case WL_TEXT_INPUT_CONTENT_PURPOSE_PHONE:
312  case WL_TEXT_INPUT_CONTENT_PURPOSE_URL:
314  case WL_TEXT_INPUT_CONTENT_PURPOSE_EMAIL:
316  case WL_TEXT_INPUT_CONTENT_PURPOSE_NAME:
318  case WL_TEXT_INPUT_CONTENT_PURPOSE_PASSWORD:
320  case WL_TEXT_INPUT_CONTENT_PURPOSE_DATE:
322  case WL_TEXT_INPUT_CONTENT_PURPOSE_TIME:
324  case WL_TEXT_INPUT_CONTENT_PURPOSE_DATETIME:
326  case WL_TEXT_INPUT_CONTENT_PURPOSE_TERMINAL:
328  case WL_TEXT_INPUT_CONTENT_PURPOSE_NORMAL:
329  default:
331  }
332 }
333 
334 TextInputUnstableV0Interface::TextInputUnstableV0Interface(TextInputManagerUnstableV0Interface *parent, wl_resource *parentResource)
335  : TextInputInterface(new Private(this, parent, parentResource))
336 {
337 }
338 
339 TextInputUnstableV0Interface::~TextInputUnstableV0Interface() = default;
340 
341 class TextInputManagerUnstableV0Interface::Private : public TextInputManagerInterface::Private
342 {
343 public:
344  Private(TextInputManagerUnstableV0Interface *q, Display *d);
345 
346 private:
347  void bind(wl_client *client, uint32_t version, uint32_t id) override;
348 
349  static void unbind(wl_resource *resource);
350  static Private *cast(wl_resource *r) {
351  return reinterpret_cast<Private*>(wl_resource_get_user_data(r));
352  }
353 
354  static void createTextInputCallback(wl_client *client, wl_resource *resource, uint32_t id);
355 
356  TextInputManagerUnstableV0Interface *q;
357  static const struct wl_text_input_manager_interface s_interface;
358  static const quint32 s_version;
359 };
360 const quint32 TextInputManagerUnstableV0Interface::Private::s_version = 1;
361 
362 #ifndef K_DOXYGEN
363 const struct wl_text_input_manager_interface TextInputManagerUnstableV0Interface::Private::s_interface = {
364  createTextInputCallback
365 };
366 #endif
367 
368 void TextInputManagerUnstableV0Interface::Private::createTextInputCallback(wl_client *client, wl_resource *resource, uint32_t id)
369 {
370  auto m = cast(resource);
371  auto *t = new TextInputUnstableV0Interface(m->q, resource);
372  m->inputs << t;
374  [t, m] {
375  m->inputs.removeAll(t);
376  }
377  );
378  QObject::connect(t, &TextInputUnstableV0Interface::requestActivate, m->q,
379  [t] (SeatInterface *seat) {
380  // TODO: disallow for other seat
381  seat->d_func()->registerTextInput(t);
382  t->d_func()->seat = seat;
383  }
384  );
385  t->d->create(m->display->getConnection(client), version, id);
386 }
387 
388 TextInputManagerInterface::Private::Private(TextInputInterfaceVersion interfaceVersion, TextInputManagerInterface *q, Display *d, const wl_interface *interface, quint32 version)
389  : Global::Private(d, interface, version)
390  , interfaceVersion(interfaceVersion)
391  , q(q)
392 {
393 }
394 
395 TextInputManagerUnstableV0Interface::Private::Private(TextInputManagerUnstableV0Interface *q, Display *d)
396  : TextInputManagerInterface::Private(TextInputInterfaceVersion::UnstableV0, q, d, &wl_text_input_manager_interface, s_version)
397  , q(q)
398 {
399 }
400 
401 void TextInputManagerUnstableV0Interface::Private::bind(wl_client *client, uint32_t version, uint32_t id)
402 {
403  auto c = display->getConnection(client);
404  wl_resource *resource = c->createResource(&wl_text_input_manager_interface, qMin(version, s_version), id);
405  if (!resource) {
406  wl_client_post_no_memory(client);
407  return;
408  }
409  wl_resource_set_implementation(resource, &s_interface, this, unbind);
410  // TODO: should we track?
411 }
412 
413 void TextInputManagerUnstableV0Interface::Private::unbind(wl_resource *resource)
414 {
415  Q_UNUSED(resource)
416  // TODO: implement?
417 }
418 
419 TextInputManagerUnstableV0Interface::TextInputManagerUnstableV0Interface(Display *display, QObject *parent)
420  : TextInputManagerInterface(new Private(this, display), parent)
421 {
422 }
423 
424 TextInputManagerUnstableV0Interface::~TextInputManagerUnstableV0Interface() = default;
425 
426 }
427 }
quint32 id() const
Definition: resource.cpp:98
typedef KeyboardModifiers
ContentPurpose
The ContentPurpose allows to specify the primary purpose of a text input.
TextInputInterfaceVersion interfaceVersion() const
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
wl_text_input as the non-standardized version
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.