26UInput::UInput(QObject *parent) :
29 m_devName = QByteArrayLiteral(
"lomiri-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());
45void 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.";
87void 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;
108void UInput::moveMouse(
int dx,
int dy)
110 struct input_event event;
112 memset(&event, 0,
sizeof(event));
113 clock_gettime(CLOCK_MONOTONIC, &ts);
114 event.input_event_sec = ts.tv_sec;
115 event.input_event_usec = ts.tv_nsec / 1000;
119 write(m_uinput.handle(), &event,
sizeof(event));
123 write(m_uinput.handle(), &event,
sizeof(event));
126 event.code = SYN_REPORT;
128 write(m_uinput.handle(), &event,
sizeof(event));
131void UInput::pressMouse(Button button)
133 injectMouse(button, 1);
136void UInput::releaseMouse(Button button)
138 injectMouse(button, 0);
141void UInput::scrollMouse(
int dh,
int dv)
143 struct input_event event;
145 memset(&event, 0,
sizeof(event));
146 clock_gettime(CLOCK_MONOTONIC, &ts);
147 event.input_event_sec = ts.tv_sec;
148 event.input_event_usec = ts.tv_nsec / 1000;
150 event.code = REL_HWHEEL;
152 write(m_uinput.handle(), &event,
sizeof(event));
154 event.code = REL_WHEEL;
156 write(m_uinput.handle(), &event,
sizeof(event));
159 event.code = SYN_REPORT;
161 write(m_uinput.handle(), &event,
sizeof(event));
164void UInput::injectMouse(Button button,
int down)
166 struct input_event event;
168 memset(&event, 0,
sizeof(event));
169 clock_gettime(CLOCK_MONOTONIC, &ts);
170 event.input_event_sec = ts.tv_sec;
171 event.input_event_usec = ts.tv_nsec / 1000;
175 event.code = BTN_LEFT;
178 event.code = BTN_RIGHT;
181 event.code = BTN_MIDDLE;
185 write(m_uinput.handle(), &event,
sizeof(event));
188 event.code = SYN_REPORT;
190 write(m_uinput.handle(), &event,
sizeof(event));