on deee36b help sign in
unity8/plugins/UInput/uinput.cpp
166 lines 4.3 kB history raw
1#include "uinput.h"
3#include <QFile>
4#include <QDebug>
5#include <QDateTime>
7#include <unistd.h>
9UInput::UInput(QObject *parent) :
10 QObject(parent)
12 m_devName = QStringLiteral("unity8-simulated-mouse");
13 m_uinput.setFileName("/dev/uinput");
15 memset(&m_uinput_mouse_dev, 0, sizeof(m_uinput_mouse_dev));
16 m_uinput_mouse_dev.id.bustype = BUS_USB;
17 m_uinput_mouse_dev.id.version = 1;
18 strncpy(m_uinput_mouse_dev.name, m_devName.toLocal8Bit().data(), m_devName.length());
22UInput::~UInput()
24 if (m_mouseCreated) {
25 removeMouse();
26 }
29void UInput::createMouse()
31 if (m_mouseCreated) {
32 qDebug() << "Already have a virtual device. Not creating another one.";
33 return;
34 }
36 if (!m_uinput.isOpen() && !m_uinput.open(QFile::WriteOnly)) {
37 return;
38 }
40 ioctl(m_uinput.handle(), UI_SET_EVBIT, EV_REL);
41 ioctl(m_uinput.handle(), UI_SET_RELBIT, REL_X);
42 ioctl(m_uinput.handle(), UI_SET_RELBIT, REL_Y);
43 ioctl(m_uinput.handle(), UI_SET_RELBIT, REL_HWHEEL);
44 ioctl(m_uinput.handle(), UI_SET_RELBIT, REL_WHEEL);
46 ioctl(m_uinput.handle(), UI_SET_EVBIT, EV_KEY);
47 ioctl(m_uinput.handle(), UI_SET_KEYBIT, BTN_MOUSE);
48 ioctl(m_uinput.handle(), UI_SET_KEYBIT, BTN_LEFT);
49 ioctl(m_uinput.handle(), UI_SET_KEYBIT, BTN_MIDDLE);
50 ioctl(m_uinput.handle(), UI_SET_KEYBIT, BTN_RIGHT);
51 ioctl(m_uinput.handle(), UI_SET_KEYBIT, BTN_FORWARD);
52 ioctl(m_uinput.handle(), UI_SET_KEYBIT, BTN_BACK);
54 ioctl(m_uinput.handle(), UI_SET_EVBIT, EV_SYN);
56 int len = write(m_uinput.handle(), &m_uinput_mouse_dev, sizeof(m_uinput_mouse_dev));
57 if (len <= 0) {
58 qWarning() << "Failed to write to uinput. Cannot create virtual uinput mouse.";
59 return;
60 }
62 int err = ioctl(m_uinput.handle(), UI_DEV_CREATE);
63 if (err != 0) {
64 qWarning() << "Cannot create virtual uinput device. Create ioctl failed:" << err;
65 return;
66 }
67 m_mouseCreated = true;
68 qDebug() << "Virtual uinput mouse device created.";
71void UInput::removeMouse()
73 if (!m_mouseCreated) {
74 return;
75 }
77 if (!m_uinput.isOpen() && !m_uinput.open(QFile::WriteOnly)) {
78 qDebug() << "cannot open uinput... ";
79 return;
80 }
82 int err = ioctl(m_uinput.handle(), UI_DEV_DESTROY);
83 if (err != 0) {
84 qWarning() << "Failed to destroy virtual uinput device. Destroy ioctl failed:" << err;
85 } else {
86 qDebug() << "Virtual uinput mouse device removed.";
87 }
88 m_uinput.close();
89 m_mouseCreated = false;
92void UInput::moveMouse(int dx, int dy)
94 struct input_event event;
95 memset(&event, 0, sizeof(event));
96 gettimeofday(&event.time, 0);
97 event.type = EV_REL;
98 event.code = REL_X;
99 event.value = dx;
100 write(m_uinput.handle(), &event, sizeof(event));
102 event.code = REL_Y;
103 event.value = dy;
104 write(m_uinput.handle(), &event, sizeof(event));
106 event.type = EV_SYN;
107 event.code = SYN_REPORT;
108 event.value = 0;
109 write(m_uinput.handle(), &event, sizeof(event));
112void UInput::pressMouse(Button button)
114 injectMouse(button, 1);
117void UInput::releaseMouse(Button button)
119 injectMouse(button, 0);
122void UInput::scrollMouse(int dh, int dv)
124 struct input_event event;
125 memset(&event, 0, sizeof(event));
126 gettimeofday(&event.time, 0);
127 event.type = EV_REL;
128 event.code = REL_HWHEEL;
129 event.value = dh;
130 write(m_uinput.handle(), &event, sizeof(event));
132 event.code = REL_WHEEL;
133 event.value = dv;
134 write(m_uinput.handle(), &event, sizeof(event));
136 event.type = EV_SYN;
137 event.code = SYN_REPORT;
138 event.value = 0;
139 write(m_uinput.handle(), &event, sizeof(event));
142void UInput::injectMouse(Button button, int down)
144 struct input_event event;
145 memset(&event, 0, sizeof(event));
146 gettimeofday(&event.time, 0);
147 event.type = EV_KEY;
148 switch (button) {
149 case ButtonLeft:
150 event.code = BTN_LEFT;
151 break;
152 case ButtonRight:
153 event.code = BTN_RIGHT;
154 break;
155 case ButtonMiddle:
156 event.code = BTN_MIDDLE;
157 break;
158 }
159 event.value = down;
160 write(m_uinput.handle(), &event, sizeof(event));
162 event.type = EV_SYN;
163 event.code = SYN_REPORT;
164 event.value = 0;
165 write(m_uinput.handle(), &event, sizeof(event));