~timo-jyrinki/ubuntu/trusty/maliit-framework/fix_qt52

« back to all changes in this revision

Viewing changes to src/waylandplatform.cpp

  • Committer: Package Import Robot
  • Author(s): Ricardo Salveti de Araujo, Sergio Schvezov, Ricardo Salveti de Araujo
  • Date: 2013-07-23 19:47:04 UTC
  • mfrom: (1.1.2) (1.2.1 experimental)
  • Revision ID: package-import@ubuntu.com-20130723194704-1lsy1kmlda069cea
Tags: 0.99.0+git20130615+97e8335-0ubuntu1
[ Sergio Schvezov ]
* New build from HEAD 97e8335.
* Packaging import from lp:phablet-extras/maliit-framework.

[ Ricardo Salveti de Araujo ]
* debian/control: adding vcs and fixing dependencies
* General package cleanup

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* * This file is part of Maliit framework *
 
2
 *
 
3
 * Copyright (C) 2013 Openismus GmbH
 
4
 *
 
5
 * Contact: maliit-discuss@lists.maliit.org
 
6
 *
 
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
 
11
 * of this file.
 
12
 */
 
13
 
 
14
#include <wayland-client.h>
 
15
#include "qwayland-input-method.h"
 
16
 
 
17
#include <QDebug>
 
18
#include <QGuiApplication>
 
19
#include <QRegion>
 
20
#include <QVector>
 
21
#include <QWindow>
 
22
#include <qpa/qplatformnativeinterface.h>
 
23
 
 
24
#include "waylandplatform.h"
 
25
#include "windowdata.h"
 
26
 
 
27
namespace
 
28
{
 
29
QtWayland::wl_input_panel_surface::position maliitToWestonPosition(Maliit::Position position)
 
30
{
 
31
    switch (position) {
 
32
    case Maliit::PositionCenterBottom:
 
33
        return QtWayland::wl_input_panel_surface::position_center_bottom;
 
34
    default:
 
35
        qWarning() << "Weston only supports center bottom position for top-level surfaces.";
 
36
 
 
37
        return QtWayland::wl_input_panel_surface::position_center_bottom;
 
38
    }
 
39
}
 
40
} // unnamed namespace
 
41
 
 
42
namespace Maliit
 
43
{
 
44
 
 
45
class WaylandPlatformPrivate
 
46
{
 
47
public:
 
48
    WaylandPlatformPrivate();
 
49
    ~WaylandPlatformPrivate();
 
50
 
 
51
    void handleRegistryGlobal(uint32_t name,
 
52
                              const char *interface,
 
53
                              uint32_t version);
 
54
    void handleRegistryGlobalRemove(uint32_t name);
 
55
    void setupInputSurface(QWindow *window,
 
56
                           Maliit::Position position,
 
57
                           bool avoid_crash = false);
 
58
 
 
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;
 
63
};
 
64
 
 
65
namespace {
 
66
 
 
67
void registryGlobal(void *data,
 
68
                    wl_registry *registry,
 
69
                    uint32_t name,
 
70
                    const char *interface,
 
71
                    uint32_t version)
 
72
{
 
73
    qDebug() << __PRETTY_FUNCTION__;
 
74
    WaylandPlatformPrivate *d = static_cast<WaylandPlatformPrivate *>(data);
 
75
 
 
76
    Q_UNUSED(registry);
 
77
    d->handleRegistryGlobal(name, interface, version);
 
78
}
 
79
 
 
80
void registryGlobalRemove(void *data,
 
81
                          wl_registry *registry,
 
82
                          uint32_t name)
 
83
{
 
84
    qDebug() << __PRETTY_FUNCTION__;
 
85
    WaylandPlatformPrivate *d = static_cast<WaylandPlatformPrivate *>(data);
 
86
 
 
87
    Q_UNUSED(registry);
 
88
    d->handleRegistryGlobalRemove(name);
 
89
}
 
90
 
 
91
const wl_registry_listener maliit_registry_listener = {
 
92
    registryGlobal,
 
93
    registryGlobalRemove
 
94
};
 
95
 
 
96
} // unnamed namespace
 
97
 
 
98
WaylandPlatformPrivate::WaylandPlatformPrivate()
 
99
    : m_registry(0),
 
100
      m_panel(0),
 
101
      m_panel_name(0),
 
102
      m_scheduled_windows()
 
103
{
 
104
    wl_display *display = static_cast<wl_display *>(QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("display"));
 
105
    if (!display) {
 
106
        qCritical() << __PRETTY_FUNCTION__ << "Failed to get a display.";
 
107
        return;
 
108
    }
 
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.
 
112
}
 
113
 
 
114
WaylandPlatformPrivate::~WaylandPlatformPrivate()
 
115
{
 
116
    if (m_registry) {
 
117
        wl_registry_destroy (m_registry);
 
118
    }
 
119
}
 
120
 
 
121
void WaylandPlatformPrivate::handleRegistryGlobal(uint32_t name,
 
122
                                                  const char *interface,
 
123
                                                  uint32_t version)
 
124
{
 
125
    Q_UNUSED(version);
 
126
 
 
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));
 
130
        m_panel_name = name;
 
131
 
 
132
        Q_FOREACH (const WindowData& data, m_scheduled_windows) {
 
133
            setupInputSurface(data.m_window, data.m_position, true);
 
134
        }
 
135
        m_scheduled_windows.clear();
 
136
    }
 
137
}
 
138
 
 
139
void WaylandPlatformPrivate::handleRegistryGlobalRemove(uint32_t name)
 
140
{
 
141
    qDebug() << __PRETTY_FUNCTION__ << "Name:" << name;
 
142
    if (m_panel and m_panel_name == name) {
 
143
        m_panel.reset();
 
144
    }
 
145
}
 
146
 
 
147
void WaylandPlatformPrivate::setupInputSurface(QWindow *window,
 
148
                                               Maliit::Position position,
 
149
                                               bool avoid_crash)
 
150
{
 
151
    struct wl_surface *surface = avoid_crash ? 0 : static_cast<struct wl_surface *>(QGuiApplication::platformNativeInterface()->nativeResourceForWindow("surface", window));
 
152
 
 
153
    struct wl_output *output = static_cast<struct wl_output*>(QGuiApplication::platformNativeInterface()->nativeResourceForScreen("output", QGuiApplication::primaryScreen()));
 
154
 
 
155
    if (!surface) {
 
156
        if (avoid_crash) {
 
157
            qDebug() << "Creating surface to avoid crash in QtWayland";
 
158
        } else {
 
159
            qDebug() << "No wl_surface, calling create.";
 
160
        }
 
161
        qDebug() << __PRETTY_FUNCTION__ << "WId:" << window->winId();
 
162
        window->create();
 
163
    }
 
164
 
 
165
    surface = static_cast<struct wl_surface *>(QGuiApplication::platformNativeInterface()->nativeResourceForWindow("surface", window));
 
166
    qDebug() << __PRETTY_FUNCTION__ << "WId:" << window->winId();
 
167
    if (!surface) {
 
168
        qDebug() << __PRETTY_FUNCTION__ << "Still no surface, giving up.";
 
169
        return;
 
170
    }
 
171
 
 
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);
 
174
 
 
175
    wl_input_panel_surface_set_toplevel(ip_surface, output, weston_position);
 
176
}
 
177
 
 
178
WaylandPlatform::WaylandPlatform()
 
179
    : d_ptr(new WaylandPlatformPrivate)
 
180
{}
 
181
 
 
182
void WaylandPlatform::setupInputPanel(QWindow* window,
 
183
                                      Maliit::Position position)
 
184
{
 
185
    // we ignore non toplevel surfaces
 
186
    if (not window or window->parent()) {
 
187
        return;
 
188
    }
 
189
 
 
190
    Q_D(WaylandPlatform);
 
191
 
 
192
    // If we have an input panel, we set up the surface now. Otherwise we
 
193
    // schedule it for later.
 
194
    if (d->m_panel) {
 
195
        d->setupInputSurface(window, position);
 
196
    } else {
 
197
        d->m_scheduled_windows.append(WindowData(window, position));
 
198
    }
 
199
}
 
200
 
 
201
void WaylandPlatform::setInputRegion(QWindow* window,
 
202
                                     const QRegion& region)
 
203
{
 
204
    if (not window) {
 
205
        return;
 
206
    }
 
207
 
 
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);
 
211
 
 
212
    Q_FOREACH (const QRect &rect, region.rects()) {
 
213
        wl_region_add(wlregion, rect.x(), rect.y(),
 
214
                      rect.width(), rect.height());
 
215
    }
 
216
 
 
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);
 
220
}
 
221
 
 
222
} // namespace Maliit