~unity-team/ubuntu-ui-toolkit/dynamic-grid-unit

« back to all changes in this revision

Viewing changes to src/Ubuntu/UbuntuToolkit/mousetouchadaptor.cpp

  • Committer: CI Train Bot
  • Author(s): Zoltán Balogh, Tim Peeters, Zsombor Egri, Christian Dywan, Andrea Bernabei
  • Date: 2016-04-12 11:12:39 UTC
  • mfrom: (1000.868.47 OTA11-landing-2016-04-08)
  • Revision ID: ci-train-bot@canonical.com-20160412111239-g60hc86tzxtrprn3
OTA11-landing-2016-04-08

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (C) 2013,2015 Canonical, Ltd.
 
2
 * Copyright (C) 2013,2016 Canonical, Ltd.
3
3
 *
4
4
 * This program is free software; you can redistribute it and/or modify
5
5
 * it under the terms of the GNU General Public License as published by
14
14
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
15
 *
16
16
 * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com>
 
17
 *              Zsombor Egri <zsomboir.egri@canonical.com>
17
18
 */
18
19
 
19
 
#include "ucmousetouchadaptor.h"
20
 
#include "uctestextras.h"
 
20
#include "mousetouchadaptor_p.h"
21
21
 
 
22
#include <qpa/qplatformnativeinterface.h>
22
23
#include <qpa/qwindowsysteminterface.h>
23
24
 
24
25
#include <QCoreApplication>
25
26
#include <QMouseEvent>
26
27
#include <QTest>
27
28
 
28
 
using QTest::QTouchEventSequence;
29
 
 
30
 
namespace {
31
 
 
32
 
Qt::MouseButton translateMouseButton(xcb_button_t detail)
 
29
#ifdef UBUNTUTOOLKIT_ENABLE_X11_TOUCH_EMULATION
 
30
    #define ENABLE_TOUCH_EMULATION
 
31
#endif
 
32
 
 
33
namespace UbuntuToolkit {
 
34
 
 
35
QTouchDevice *MouseTouchAdaptor::m_touchDevice = nullptr;
 
36
 
 
37
MouseTouchAdaptorPrivate::~MouseTouchAdaptorPrivate()
33
38
{
34
 
    switch (detail) {
35
 
        case 1: return Qt::LeftButton;
36
 
        case 2: return Qt::MidButton;
37
 
        case 3: return Qt::RightButton;
38
 
        // Button values 4-7 are Wheel events
39
 
        default: return Qt::NoButton;
40
 
    }
 
39
    QCoreApplication::instance()->removeNativeEventFilter(this);
41
40
}
42
 
} // end of anonymous namespace
43
41
 
44
42
/*!
45
43
 * \qmltype MouseTouchAdaptor
46
 
 * \instantiates UCMouseTouchAdaptor
 
44
 * \instantiates MouseTouchAdaptor
47
45
 * \inqmlmodule Ubuntu.Test 1.0
48
46
 * \ingroup ubuntu-test
49
47
 * \brief Singleton type turning mouse events into single finger touch events.
60
58
 * \endqml
61
59
 *
62
60
 */
63
 
UCMouseTouchAdaptor::UCMouseTouchAdaptor()
64
 
    : QObject(nullptr)
65
 
    , m_leftButtonIsPressed(false)
66
 
    , m_enabled(true)
67
 
{
68
 
    QCoreApplication::instance()->installNativeEventFilter(this);
69
 
 
70
 
    UCTestExtras::registerTouchDevice();
71
 
    m_touchDevice = UCTestExtras::m_touchDevice;
72
 
}
73
 
 
74
 
bool UCMouseTouchAdaptor::nativeEventFilter(const QByteArray & eventType,
75
 
                                          void * message, long * /*result*/)
76
 
{
77
 
    if (!m_enabled) {
78
 
        return false;
79
 
    }
80
 
 
81
 
    if (eventType != "xcb_generic_event_t") {
82
 
        // wrong backend.
83
 
        qWarning("MouseTouchAdaptor: XCB backend not in use. Adaptor inoperative!");
84
 
        return false;
85
 
    }
86
 
 
87
 
    xcb_generic_event_t *xcbEvent = static_cast<xcb_generic_event_t *>(message);
88
 
 
89
 
    switch (xcbEvent->response_type & ~0x80) {
90
 
        case XCB_BUTTON_PRESS:
91
 
            return handleButtonPress(reinterpret_cast<xcb_button_press_event_t *>(xcbEvent));
92
 
            break;
93
 
        case XCB_BUTTON_RELEASE:
94
 
            return handleButtonRelease(reinterpret_cast<xcb_button_release_event_t *>(xcbEvent));
95
 
            break;
96
 
        case XCB_MOTION_NOTIFY:
97
 
            return handleMotionNotify(reinterpret_cast<xcb_motion_notify_event_t *>(xcbEvent));
98
 
            break;
99
 
        default:
100
 
            return false;
101
 
            break;
102
 
    };
103
 
}
104
 
 
105
 
bool UCMouseTouchAdaptor::handleButtonPress(xcb_button_press_event_t *pressEvent)
106
 
{
107
 
    Qt::MouseButton button = translateMouseButton(pressEvent->detail);
108
 
 
109
 
    // Just eat the event if it wasn't a left mouse press
110
 
    if (button != Qt::LeftButton)
111
 
        return true;
112
 
 
113
 
    QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(pressEvent->event));
114
 
 
115
 
    QPoint windowPos(pressEvent->event_x / targetWindow->devicePixelRatio(), pressEvent->event_y / targetWindow->devicePixelRatio());
116
 
 
117
 
    QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
118
 
                                                       false /* autoCommit */);
119
 
    touchEvent.press(0 /* touchId */, windowPos);
120
 
    touchEvent.commit(false /* processEvents */);
121
 
 
122
 
    m_leftButtonIsPressed = true;
123
 
    return true;
124
 
}
125
 
 
126
 
bool UCMouseTouchAdaptor::handleButtonRelease(xcb_button_release_event_t *releaseEvent)
127
 
{
128
 
    Qt::MouseButton button = translateMouseButton(releaseEvent->detail);
129
 
 
130
 
    // Just eat the event if it wasn't a left mouse release
131
 
    if (button != Qt::LeftButton)
132
 
        return true;
133
 
 
134
 
    QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(releaseEvent->event));
135
 
 
136
 
    QPoint windowPos(releaseEvent->event_x / targetWindow->devicePixelRatio(), releaseEvent->event_y / targetWindow->devicePixelRatio());
137
 
 
138
 
    QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
139
 
                                                       false /* autoCommit */);
140
 
    touchEvent.release(0 /* touchId */, windowPos);
141
 
    touchEvent.commit(false /* processEvents */);
142
 
 
143
 
    m_leftButtonIsPressed = false;
144
 
    return true;
145
 
}
146
 
 
147
 
bool UCMouseTouchAdaptor::handleMotionNotify(xcb_motion_notify_event_t *event)
148
 
{
149
 
    if (!m_leftButtonIsPressed) {
150
 
        return true;
151
 
    }
152
 
 
153
 
    QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(event->event));
154
 
 
155
 
    QPoint windowPos(event->event_x / targetWindow->devicePixelRatio(), event->event_y / targetWindow->devicePixelRatio());
156
 
 
157
 
    QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
158
 
                                                       false /* autoCommit */);
159
 
    touchEvent.move(0 /* touchId */, windowPos);
160
 
    touchEvent.commit(false /* processEvents */);
161
 
 
162
 
    return true;
163
 
}
164
 
 
165
 
QWindow *UCMouseTouchAdaptor::findQWindowWithXWindowID(WId windowId)
 
61
MouseTouchAdaptor::MouseTouchAdaptor(QObject *parent)
 
62
    :
 
63
#ifdef UBUNTUTOOLKIT_ENABLE_X11_TOUCH_EMULATION
 
64
      QObject(*(new X11MouseTouchAdaptorPrivate), parent)
 
65
#else
 
66
      QObject(*(new MouseTouchAdaptorPrivate), parent)
 
67
#endif
 
68
{
 
69
#ifdef ENABLE_TOUCH_EMULATION
 
70
    registerTouchDevice();
 
71
#else
 
72
    qWarning() << "MouseTouchAdaptor not available on this architecture.";
 
73
#endif
 
74
    Q_D(MouseTouchAdaptor);
 
75
    d->init();
 
76
}
 
77
 
 
78
// registers a test touch device, returns true if a device was found/registered
 
79
bool MouseTouchAdaptor::registerTouchDevice()
 
80
{
 
81
    // check if there is any touch device registered in the system
 
82
    if (!m_touchDevice) {
 
83
        QList<const QTouchDevice*> touchDevices = QTouchDevice::devices();
 
84
        Q_FOREACH(const QTouchDevice *device, touchDevices) {
 
85
            if (device->type() == QTouchDevice::TouchScreen) {
 
86
                m_touchDevice = const_cast<QTouchDevice*>(device);
 
87
                return true;
 
88
            }
 
89
        }
 
90
    }
 
91
    // if none, register one
 
92
#ifdef ENABLE_TOUCH_EMULATION
 
93
    if (!m_touchDevice) {
 
94
        m_touchDevice = new QTouchDevice;
 
95
        m_touchDevice->setType(QTouchDevice::TouchScreen);
 
96
        QWindowSystemInterface::registerTouchDevice(m_touchDevice);
 
97
        return true;
 
98
    }
 
99
#endif
 
100
    return false;
 
101
}
 
102
 
 
103
QWindow *MouseTouchAdaptorPrivate::findQWindowWithXWindowID(WId windowId)
166
104
{
167
105
    QWindowList windowList = QGuiApplication::topLevelWindows();
168
106
    QWindow *foundWindow = nullptr;
185
123
 * \qmlproperty bool MouseTouchAdaptor::enabled
186
124
 * Enables the mouse to touch conversion functionality. Defaults to true.
187
125
 */
188
 
bool UCMouseTouchAdaptor::enabled() const
189
 
{
190
 
    return m_enabled;
191
 
}
192
 
void UCMouseTouchAdaptor::setEnabled(bool value)
193
 
{
194
 
    if (value != m_enabled) {
195
 
        m_enabled = value;
196
 
        Q_EMIT enabledChanged(value);
197
 
    }
198
 
}
 
126
bool MouseTouchAdaptorPrivate::isEnabled() const
 
127
{
 
128
    return enabled;
 
129
}
 
130
void MouseTouchAdaptorPrivate::setEnabled(bool value)
 
131
{
 
132
    Q_UNUSED(value);
 
133
    qWarning() << "MouseTouchAdaptor not available on this architecture, thus cannot be enabled.";
 
134
}
 
135
 
 
136
} // namespace UbuntuToolkit
 
137
 
 
138
#include "moc_mousetouchadaptor.cpp"