~aacid/unity8/activtion-progress

« back to all changes in this revision

Viewing changes to plugins/UInput/uinput.cpp

  • Committer: Albert Astals Cid
  • Date: 2016-02-19 11:48:26 UTC
  • mfrom: (2143.1.60 unity8)
  • Revision ID: albert.astals@canonical.com-20160219114826-ctquarjfkew3fmn7
Merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2015 Canonical Ltd.
 
3
 *
 
4
 * This program is free software: you can redistribute it and/or modify it
 
5
 * under the terms of the GNU General Public License version 3, as published
 
6
 * by the Free Software Foundation.
 
7
 *
 
8
 * This program is distributed in the hope that it will be useful, but
 
9
 * WITHOUT ANY WARRANTY; without even the implied warranties of
 
10
 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
 
11
 * PURPOSE.  See the GNU General Public License for more details.
 
12
 *
 
13
 * You should have received a copy of the GNU General Public License along
 
14
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 
15
 */
 
16
 
 
17
#include "uinput.h"
 
18
 
 
19
#include <QFile>
 
20
#include <QDebug>
 
21
#include <QDateTime>
 
22
 
 
23
#include <unistd.h>
 
24
#include <time.h>
 
25
 
 
26
UInput::UInput(QObject *parent) :
 
27
    QObject(parent)
 
28
{
 
29
    m_devName = QByteArrayLiteral("unity8-simulated-mouse");
 
30
    m_uinput.setFileName(QStringLiteral("/dev/uinput"));
 
31
 
 
32
    memset(&m_uinput_mouse_dev, 0, sizeof(m_uinput_mouse_dev));
 
33
    m_uinput_mouse_dev.id.bustype = BUS_USB;
 
34
    m_uinput_mouse_dev.id.version = 1;
 
35
    strncpy(m_uinput_mouse_dev.name, m_devName.constData(), m_devName.length());
 
36
}
 
37
 
 
38
UInput::~UInput()
 
39
{
 
40
    if (m_mouseCreated) {
 
41
        removeMouse();
 
42
    }
 
43
}
 
44
 
 
45
void UInput::createMouse()
 
46
{
 
47
    if (m_mouseCreated) {
 
48
        qDebug() << "Already have a virtual device. Not creating another one.";
 
49
        return;
 
50
    }
 
51
 
 
52
    if (!m_uinput.isOpen() && !m_uinput.open(QFile::WriteOnly)) {
 
53
        return;
 
54
    }
 
55
 
 
56
    ioctl(m_uinput.handle(), UI_SET_EVBIT, EV_REL);
 
57
    ioctl(m_uinput.handle(), UI_SET_RELBIT, REL_X);
 
58
    ioctl(m_uinput.handle(), UI_SET_RELBIT, REL_Y);
 
59
    ioctl(m_uinput.handle(), UI_SET_RELBIT, REL_HWHEEL);
 
60
    ioctl(m_uinput.handle(), UI_SET_RELBIT, REL_WHEEL);
 
61
 
 
62
    ioctl(m_uinput.handle(), UI_SET_EVBIT, EV_KEY);
 
63
    ioctl(m_uinput.handle(), UI_SET_KEYBIT, BTN_MOUSE);
 
64
    ioctl(m_uinput.handle(), UI_SET_KEYBIT, BTN_LEFT);
 
65
    ioctl(m_uinput.handle(), UI_SET_KEYBIT, BTN_MIDDLE);
 
66
    ioctl(m_uinput.handle(), UI_SET_KEYBIT, BTN_RIGHT);
 
67
    ioctl(m_uinput.handle(), UI_SET_KEYBIT, BTN_FORWARD);
 
68
    ioctl(m_uinput.handle(), UI_SET_KEYBIT, BTN_BACK);
 
69
 
 
70
    ioctl(m_uinput.handle(), UI_SET_EVBIT, EV_SYN);
 
71
 
 
72
    int len = write(m_uinput.handle(), &m_uinput_mouse_dev, sizeof(m_uinput_mouse_dev));
 
73
    if (len <= 0) {
 
74
        qWarning() << "Failed to write to uinput. Cannot create virtual uinput mouse.";
 
75
        return;
 
76
    }
 
77
 
 
78
    int err = ioctl(m_uinput.handle(), UI_DEV_CREATE);
 
79
    if (err != 0) {
 
80
        qWarning() << "Cannot create virtual uinput device. Create ioctl failed:" << err;
 
81
        return;
 
82
    }
 
83
    m_mouseCreated = true;
 
84
    qDebug() << "Virtual uinput mouse device created.";
 
85
}
 
86
 
 
87
void UInput::removeMouse()
 
88
{
 
89
    if (!m_mouseCreated) {
 
90
        return;
 
91
    }
 
92
 
 
93
    if (!m_uinput.isOpen() && !m_uinput.open(QFile::WriteOnly)) {
 
94
        qWarning() << "cannot open uinput... ";
 
95
        return;
 
96
    }
 
97
 
 
98
    int err = ioctl(m_uinput.handle(), UI_DEV_DESTROY);
 
99
    if (err != 0) {
 
100
        qWarning() << "Failed to destroy virtual uinput device. Destroy ioctl failed:" << err;
 
101
    } else {
 
102
        qDebug() << "Virtual uinput mouse device removed.";
 
103
    }
 
104
    m_uinput.close();
 
105
    m_mouseCreated = false;
 
106
}
 
107
 
 
108
void UInput::moveMouse(int dx, int dy)
 
109
{
 
110
    struct input_event event;
 
111
    memset(&event, 0, sizeof(event));
 
112
    clock_gettime(CLOCK_MONOTONIC, (timespec*)&event.time);
 
113
    event.type = EV_REL;
 
114
    event.code = REL_X;
 
115
    event.value = dx;
 
116
    write(m_uinput.handle(), &event, sizeof(event));
 
117
 
 
118
    event.code = REL_Y;
 
119
    event.value = dy;
 
120
    write(m_uinput.handle(), &event, sizeof(event));
 
121
 
 
122
    event.type = EV_SYN;
 
123
    event.code = SYN_REPORT;
 
124
    event.value = 0;
 
125
    write(m_uinput.handle(), &event, sizeof(event));
 
126
}
 
127
 
 
128
void UInput::pressMouse(Button button)
 
129
{
 
130
    injectMouse(button, 1);
 
131
}
 
132
 
 
133
void UInput::releaseMouse(Button button)
 
134
{
 
135
    injectMouse(button, 0);
 
136
}
 
137
 
 
138
void UInput::scrollMouse(int dh, int dv)
 
139
{
 
140
    struct input_event event;
 
141
    memset(&event, 0, sizeof(event));
 
142
    clock_gettime(CLOCK_MONOTONIC, (timespec*)&event.time);
 
143
    event.type = EV_REL;
 
144
    event.code = REL_HWHEEL;
 
145
    event.value = dh;
 
146
    write(m_uinput.handle(), &event, sizeof(event));
 
147
 
 
148
    event.code = REL_WHEEL;
 
149
    event.value = dv;
 
150
    write(m_uinput.handle(), &event, sizeof(event));
 
151
 
 
152
    event.type = EV_SYN;
 
153
    event.code = SYN_REPORT;
 
154
    event.value = 0;
 
155
    write(m_uinput.handle(), &event, sizeof(event));
 
156
}
 
157
 
 
158
void UInput::injectMouse(Button button, int down)
 
159
{
 
160
    struct input_event event;
 
161
    memset(&event, 0, sizeof(event));
 
162
    clock_gettime(CLOCK_MONOTONIC, (timespec*)&event.time);
 
163
    event.type = EV_KEY;
 
164
    switch (button) {
 
165
    case ButtonLeft:
 
166
        event.code = BTN_LEFT;
 
167
        break;
 
168
    case ButtonRight:
 
169
        event.code = BTN_RIGHT;
 
170
        break;
 
171
    case ButtonMiddle:
 
172
        event.code = BTN_MIDDLE;
 
173
        break;
 
174
    }
 
175
    event.value = down;
 
176
    write(m_uinput.handle(), &event, sizeof(event));
 
177
 
 
178
    event.type = EV_SYN;
 
179
    event.code = SYN_REPORT;
 
180
    event.value = 0;
 
181
    write(m_uinput.handle(), &event, sizeof(event));
 
182
}