1 /*
2     SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org>
3 
4     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5 */
6 #include "display.h"
7 #include "global_p.h"
8 #include "resource_p.h"
9 #include "seat_interface_p.h"
10 #include "surface_interface.h"
11 #include "textinput_interface_p.h"
12 
13 #include <QVector>
14 
15 #include <wayland-text-input-unstable-v2-server-protocol.h>
16 #include <wayland-text-server-protocol.h>
17 
18 namespace KWayland
19 {
20 namespace Server
21 {
showInputPanelCallback(wl_client * client,wl_resource * resource)22 void TextInputInterface::Private::showInputPanelCallback(wl_client *client, wl_resource *resource)
23 {
24     auto p = cast<Private>(resource);
25     Q_ASSERT(*p->client == client);
26     Q_EMIT p->q_func()->requestShowInputPanel();
27 }
28 
hideInputPanelCallback(wl_client * client,wl_resource * resource)29 void TextInputInterface::Private::hideInputPanelCallback(wl_client *client, wl_resource *resource)
30 {
31     auto p = cast<Private>(resource);
32     Q_ASSERT(*p->client == client);
33     Q_EMIT p->q_func()->requestHideInputPanel();
34 }
35 
setSurroundingTextCallback(wl_client * client,wl_resource * resource,const char * text,int32_t cursor,int32_t anchor)36 void TextInputInterface::Private::setSurroundingTextCallback(wl_client *client, wl_resource *resource, const char *text, int32_t cursor, int32_t anchor)
37 {
38     auto p = cast<Private>(resource);
39     Q_ASSERT(*p->client == client);
40     p->surroundingText = QByteArray(text);
41     // TODO: make qint32
42     p->surroundingTextCursorPosition = cursor;
43     p->surroundingTextSelectionAnchor = anchor;
44     Q_EMIT p->q_func()->surroundingTextChanged();
45 }
46 
setContentTypeCallback(wl_client * client,wl_resource * resource,uint32_t hint,uint32_t purpose)47 void TextInputInterface::Private::setContentTypeCallback(wl_client *client, wl_resource *resource, uint32_t hint, uint32_t purpose)
48 {
49     auto p = cast<Private>(resource);
50     Q_ASSERT(*p->client == client);
51     const auto contentHints = p->convertContentHint(hint);
52     const auto contentPurpose = p->convertContentPurpose(purpose);
53     if (contentHints != p->contentHints || contentPurpose != p->contentPurpose) {
54         p->contentHints = contentHints;
55         p->contentPurpose = contentPurpose;
56         Q_EMIT p->q_func()->contentTypeChanged();
57     }
58 }
59 
setCursorRectangleCallback(wl_client * client,wl_resource * resource,int32_t x,int32_t y,int32_t width,int32_t height)60 void TextInputInterface::Private::setCursorRectangleCallback(wl_client *client, wl_resource *resource, int32_t x, int32_t y, int32_t width, int32_t height)
61 {
62     auto p = cast<Private>(resource);
63     Q_ASSERT(*p->client == client);
64     const QRect rect = QRect(x, y, width, height);
65     if (p->cursorRectangle != rect) {
66         p->cursorRectangle = rect;
67         Q_EMIT p->q_func()->cursorRectangleChanged(p->cursorRectangle);
68     }
69 }
70 
setPreferredLanguageCallback(wl_client * client,wl_resource * resource,const char * language)71 void TextInputInterface::Private::setPreferredLanguageCallback(wl_client *client, wl_resource *resource, const char *language)
72 {
73     auto p = cast<Private>(resource);
74     Q_ASSERT(*p->client == client);
75     const QByteArray preferredLanguage = QByteArray(language);
76     if (p->preferredLanguage != preferredLanguage) {
77         p->preferredLanguage = preferredLanguage;
78         Q_EMIT p->q_func()->preferredLanguageChanged(p->preferredLanguage);
79     }
80 }
81 
Private(TextInputInterface * q,Global * c,wl_resource * parentResource,const wl_interface * interface,const void * implementation)82 TextInputInterface::Private::Private(TextInputInterface *q, Global *c, wl_resource *parentResource, const wl_interface *interface, const void *implementation)
83     : Resource::Private(q, c, parentResource, interface, implementation)
84 {
85 }
86 
~Private()87 TextInputInterface::Private::~Private()
88 {
89     if (resource) {
90         wl_resource_destroy(resource);
91         resource = nullptr;
92     }
93 }
94 
preferredLanguage() const95 QByteArray TextInputInterface::preferredLanguage() const
96 {
97     Q_D();
98     return d->preferredLanguage;
99 }
100 
contentHints() const101 TextInputInterface::ContentHints TextInputInterface::contentHints() const
102 {
103     Q_D();
104     return d->contentHints;
105 }
106 
contentPurpose() const107 TextInputInterface::ContentPurpose TextInputInterface::contentPurpose() const
108 {
109     Q_D();
110     return d->contentPurpose;
111 }
112 
surroundingText() const113 QByteArray TextInputInterface::surroundingText() const
114 {
115     Q_D();
116     return d->surroundingText;
117 }
118 
surroundingTextCursorPosition() const119 qint32 TextInputInterface::surroundingTextCursorPosition() const
120 {
121     Q_D();
122     return d->surroundingTextCursorPosition;
123 }
124 
surroundingTextSelectionAnchor() const125 qint32 TextInputInterface::surroundingTextSelectionAnchor() const
126 {
127     Q_D();
128     return d->surroundingTextSelectionAnchor;
129 }
130 
preEdit(const QByteArray & text,const QByteArray & commit)131 void TextInputInterface::preEdit(const QByteArray &text, const QByteArray &commit)
132 {
133     Q_D();
134     d->preEdit(text, commit);
135 }
136 
commit(const QByteArray & text)137 void TextInputInterface::commit(const QByteArray &text)
138 {
139     Q_D();
140     d->commit(text);
141 }
142 
keysymPressed(quint32 keysym,Qt::KeyboardModifiers modifiers)143 void TextInputInterface::keysymPressed(quint32 keysym, Qt::KeyboardModifiers modifiers)
144 {
145     Q_UNUSED(modifiers)
146     Q_D();
147     d->keysymPressed(keysym, modifiers);
148 }
149 
keysymReleased(quint32 keysym,Qt::KeyboardModifiers modifiers)150 void TextInputInterface::keysymReleased(quint32 keysym, Qt::KeyboardModifiers modifiers)
151 {
152     Q_D();
153     d->keysymReleased(keysym, modifiers);
154 }
155 
deleteSurroundingText(quint32 beforeLength,quint32 afterLength)156 void TextInputInterface::deleteSurroundingText(quint32 beforeLength, quint32 afterLength)
157 {
158     Q_D();
159     d->deleteSurroundingText(beforeLength, afterLength);
160 }
161 
setCursorPosition(qint32 index,qint32 anchor)162 void TextInputInterface::setCursorPosition(qint32 index, qint32 anchor)
163 {
164     Q_D();
165     d->setCursorPosition(index, anchor);
166 }
167 
setTextDirection(Qt::LayoutDirection direction)168 void TextInputInterface::setTextDirection(Qt::LayoutDirection direction)
169 {
170     Q_D();
171     d->setTextDirection(direction);
172 }
173 
setPreEditCursor(qint32 index)174 void TextInputInterface::setPreEditCursor(qint32 index)
175 {
176     Q_D();
177     d->setPreEditCursor(index);
178 }
179 
setInputPanelState(bool visible,const QRect & overlappedSurfaceArea)180 void TextInputInterface::setInputPanelState(bool visible, const QRect &overlappedSurfaceArea)
181 {
182     Q_D();
183     if (d->inputPanelVisible == visible && d->overlappedSurfaceArea == overlappedSurfaceArea) {
184         // not changed
185         return;
186     }
187     d->inputPanelVisible = visible;
188     d->overlappedSurfaceArea = overlappedSurfaceArea;
189     d->sendInputPanelState();
190 }
191 
setLanguage(const QByteArray & languageTag)192 void TextInputInterface::setLanguage(const QByteArray &languageTag)
193 {
194     Q_D();
195     if (d->language == languageTag) {
196         // not changed
197         return;
198     }
199     d->language = languageTag;
200     d->sendLanguage();
201 }
202 
interfaceVersion() const203 TextInputInterfaceVersion TextInputInterface::interfaceVersion() const
204 {
205     Q_D();
206     return d->interfaceVersion();
207 }
208 
surface() const209 QPointer<SurfaceInterface> TextInputInterface::surface() const
210 {
211     Q_D();
212     return d->surface;
213 }
214 
cursorRectangle() const215 QRect TextInputInterface::cursorRectangle() const
216 {
217     Q_D();
218     return d->cursorRectangle;
219 }
220 
isEnabled() const221 bool TextInputInterface::isEnabled() const
222 {
223     Q_D();
224     return d->enabled;
225 }
226 
d_func() const227 TextInputInterface::Private *TextInputInterface::d_func() const
228 {
229     return reinterpret_cast<Private *>(d.data());
230 }
231 
TextInputInterface(Private * p,QObject * parent)232 TextInputInterface::TextInputInterface(Private *p, QObject *parent)
233     : Resource(p, parent)
234 {
235 }
236 
237 TextInputInterface::~TextInputInterface() = default;
238 
TextInputManagerInterface(Private * d,QObject * parent)239 TextInputManagerInterface::TextInputManagerInterface(Private *d, QObject *parent)
240     : Global(d, parent)
241 {
242 }
243 
244 TextInputManagerInterface::~TextInputManagerInterface() = default;
245 
interfaceVersion() const246 TextInputInterfaceVersion TextInputManagerInterface::interfaceVersion() const
247 {
248     Q_D();
249     return d->interfaceVersion;
250 }
251 
d_func() const252 TextInputManagerInterface::Private *TextInputManagerInterface::d_func() const
253 {
254     return reinterpret_cast<Private *>(d.data());
255 }
256 
257 }
258 }
259