1
/* * This file is part of Maliit framework *
3
* Copyright (C) 2013 Openismus GmbH
5
* Contact: maliit-discuss@lists.maliit.org
7
* This library is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License version 2.1 as published by the Free Software Foundation
10
* and appearing in the file LICENSE.LGPL included in the packaging
14
#include <wayland-client.h>
15
#include "qwayland-input-method.h"
18
#include <QGuiApplication>
22
#include <qpa/qplatformnativeinterface.h>
24
#include "waylandplatform.h"
25
#include "windowdata.h"
29
QtWayland::wl_input_panel_surface::position maliitToWestonPosition(Maliit::Position position)
32
case Maliit::PositionCenterBottom:
33
return QtWayland::wl_input_panel_surface::position_center_bottom;
35
qWarning() << "Weston only supports center bottom position for top-level surfaces.";
37
return QtWayland::wl_input_panel_surface::position_center_bottom;
40
} // unnamed namespace
45
class WaylandPlatformPrivate
48
WaylandPlatformPrivate();
49
~WaylandPlatformPrivate();
51
void handleRegistryGlobal(uint32_t name,
52
const char *interface,
54
void handleRegistryGlobalRemove(uint32_t name);
55
void setupInputSurface(QWindow *window,
56
Maliit::Position position,
57
bool avoid_crash = false);
59
struct wl_registry *m_registry;
60
QScopedPointer<QtWayland::wl_input_panel> m_panel;
61
uint32_t m_panel_name;
62
QVector<WindowData> m_scheduled_windows;
67
void registryGlobal(void *data,
68
wl_registry *registry,
70
const char *interface,
73
qDebug() << __PRETTY_FUNCTION__;
74
WaylandPlatformPrivate *d = static_cast<WaylandPlatformPrivate *>(data);
77
d->handleRegistryGlobal(name, interface, version);
80
void registryGlobalRemove(void *data,
81
wl_registry *registry,
84
qDebug() << __PRETTY_FUNCTION__;
85
WaylandPlatformPrivate *d = static_cast<WaylandPlatformPrivate *>(data);
88
d->handleRegistryGlobalRemove(name);
91
const wl_registry_listener maliit_registry_listener = {
96
} // unnamed namespace
98
WaylandPlatformPrivate::WaylandPlatformPrivate()
102
m_scheduled_windows()
104
wl_display *display = static_cast<wl_display *>(QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("display"));
106
qCritical() << __PRETTY_FUNCTION__ << "Failed to get a display.";
109
m_registry = wl_display_get_registry(display);
110
wl_registry_add_listener(m_registry, &maliit_registry_listener, this);
111
// QtWayland will do dispatching for us.
114
WaylandPlatformPrivate::~WaylandPlatformPrivate()
117
wl_registry_destroy (m_registry);
121
void WaylandPlatformPrivate::handleRegistryGlobal(uint32_t name,
122
const char *interface,
127
qDebug() << __PRETTY_FUNCTION__ << "Name:" << name << "Interface:" << interface;
128
if (!strcmp(interface, "wl_input_panel")) {
129
m_panel.reset(new QtWayland::wl_input_panel(m_registry, name));
132
Q_FOREACH (const WindowData& data, m_scheduled_windows) {
133
setupInputSurface(data.m_window, data.m_position, true);
135
m_scheduled_windows.clear();
139
void WaylandPlatformPrivate::handleRegistryGlobalRemove(uint32_t name)
141
qDebug() << __PRETTY_FUNCTION__ << "Name:" << name;
142
if (m_panel and m_panel_name == name) {
147
void WaylandPlatformPrivate::setupInputSurface(QWindow *window,
148
Maliit::Position position,
151
struct wl_surface *surface = avoid_crash ? 0 : static_cast<struct wl_surface *>(QGuiApplication::platformNativeInterface()->nativeResourceForWindow("surface", window));
153
struct wl_output *output = static_cast<struct wl_output*>(QGuiApplication::platformNativeInterface()->nativeResourceForScreen("output", QGuiApplication::primaryScreen()));
157
qDebug() << "Creating surface to avoid crash in QtWayland";
159
qDebug() << "No wl_surface, calling create.";
161
qDebug() << __PRETTY_FUNCTION__ << "WId:" << window->winId();
165
surface = static_cast<struct wl_surface *>(QGuiApplication::platformNativeInterface()->nativeResourceForWindow("surface", window));
166
qDebug() << __PRETTY_FUNCTION__ << "WId:" << window->winId();
168
qDebug() << __PRETTY_FUNCTION__ << "Still no surface, giving up.";
172
struct wl_input_panel_surface *ip_surface = m_panel->get_input_panel_surface(surface);
173
QtWayland::wl_input_panel_surface::position weston_position = maliitToWestonPosition(position);
175
wl_input_panel_surface_set_toplevel(ip_surface, output, weston_position);
178
WaylandPlatform::WaylandPlatform()
179
: d_ptr(new WaylandPlatformPrivate)
182
void WaylandPlatform::setupInputPanel(QWindow* window,
183
Maliit::Position position)
185
// we ignore non toplevel surfaces
186
if (not window or window->parent()) {
190
Q_D(WaylandPlatform);
192
// If we have an input panel, we set up the surface now. Otherwise we
193
// schedule it for later.
195
d->setupInputSurface(window, position);
197
d->m_scheduled_windows.append(WindowData(window, position));
201
void WaylandPlatform::setInputRegion(QWindow* window,
202
const QRegion& region)
208
QPlatformNativeInterface *wliface = QGuiApplication::platformNativeInterface();
209
wl_compositor *wlcompositor = static_cast<wl_compositor *>(wliface->nativeResourceForIntegration("compositor"));
210
wl_region *wlregion = wl_compositor_create_region(wlcompositor);
212
Q_FOREACH (const QRect &rect, region.rects()) {
213
wl_region_add(wlregion, rect.x(), rect.y(),
214
rect.width(), rect.height());
217
wl_surface *wlsurface = static_cast<wl_surface *>(wliface->nativeResourceForWindow("surface", window));
218
wl_surface_set_input_region(wlsurface, wlregion);
219
wl_region_destroy(wlregion);
222
} // namespace Maliit