2
* Copyright (C) 2015 Canonical Ltd.
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.
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.
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/>.
26
UInput::UInput(QObject *parent) :
29
m_devName = QByteArrayLiteral("unity8-simulated-mouse");
30
m_uinput.setFileName(QStringLiteral("/dev/uinput"));
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());
45
void UInput::createMouse()
48
qDebug() << "Already have a virtual device. Not creating another one.";
52
if (!m_uinput.isOpen() && !m_uinput.open(QFile::WriteOnly)) {
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);
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);
70
ioctl(m_uinput.handle(), UI_SET_EVBIT, EV_SYN);
72
int len = write(m_uinput.handle(), &m_uinput_mouse_dev, sizeof(m_uinput_mouse_dev));
74
qWarning() << "Failed to write to uinput. Cannot create virtual uinput mouse.";
78
int err = ioctl(m_uinput.handle(), UI_DEV_CREATE);
80
qWarning() << "Cannot create virtual uinput device. Create ioctl failed:" << err;
83
m_mouseCreated = true;
84
qDebug() << "Virtual uinput mouse device created.";
87
void UInput::removeMouse()
89
if (!m_mouseCreated) {
93
if (!m_uinput.isOpen() && !m_uinput.open(QFile::WriteOnly)) {
94
qWarning() << "cannot open uinput... ";
98
int err = ioctl(m_uinput.handle(), UI_DEV_DESTROY);
100
qWarning() << "Failed to destroy virtual uinput device. Destroy ioctl failed:" << err;
102
qDebug() << "Virtual uinput mouse device removed.";
105
m_mouseCreated = false;
108
void UInput::moveMouse(int dx, int dy)
110
struct input_event event;
111
memset(&event, 0, sizeof(event));
112
clock_gettime(CLOCK_MONOTONIC, (timespec*)&event.time);
116
write(m_uinput.handle(), &event, sizeof(event));
120
write(m_uinput.handle(), &event, sizeof(event));
123
event.code = SYN_REPORT;
125
write(m_uinput.handle(), &event, sizeof(event));
128
void UInput::pressMouse(Button button)
130
injectMouse(button, 1);
133
void UInput::releaseMouse(Button button)
135
injectMouse(button, 0);
138
void UInput::scrollMouse(int dh, int dv)
140
struct input_event event;
141
memset(&event, 0, sizeof(event));
142
clock_gettime(CLOCK_MONOTONIC, (timespec*)&event.time);
144
event.code = REL_HWHEEL;
146
write(m_uinput.handle(), &event, sizeof(event));
148
event.code = REL_WHEEL;
150
write(m_uinput.handle(), &event, sizeof(event));
153
event.code = SYN_REPORT;
155
write(m_uinput.handle(), &event, sizeof(event));
158
void UInput::injectMouse(Button button, int down)
160
struct input_event event;
161
memset(&event, 0, sizeof(event));
162
clock_gettime(CLOCK_MONOTONIC, (timespec*)&event.time);
166
event.code = BTN_LEFT;
169
event.code = BTN_RIGHT;
172
event.code = BTN_MIDDLE;
176
write(m_uinput.handle(), &event, sizeof(event));
179
event.code = SYN_REPORT;
181
write(m_uinput.handle(), &event, sizeof(event));