blob: 107756b5cb2626f44feeb01c72a63f678e83c2d5 [file] [log] [blame]
Eddie James21b177e2018-12-11 13:14:46 -06001#include "ikvm_input.hpp"
2
3#include "ikvm_server.hpp"
George Liuf79f6f52022-07-06 09:32:35 +08004#include "scancodes.hpp"
Eddie James21b177e2018-12-11 13:14:46 -06005
6#include <err.h>
7#include <errno.h>
8#include <fcntl.h>
9#include <rfb/keysym.h>
10#include <sys/stat.h>
11#include <sys/types.h>
12
13#include <phosphor-logging/elog-errors.hpp>
14#include <phosphor-logging/elog.hpp>
15#include <phosphor-logging/log.hpp>
16#include <xyz/openbmc_project/Common/File/error.hpp>
17
Jae Hyun Yooc11257d2020-07-22 23:39:18 -070018namespace fs = std::filesystem;
19
Eddie James21b177e2018-12-11 13:14:46 -060020namespace ikvm
21{
22
23using namespace phosphor::logging;
24using namespace sdbusplus::xyz::openbmc_project::Common::File::Error;
25
Marvin Linfe685fb2022-10-25 16:20:08 +080026Input::Input(const std::string& kbdPath, const std::string& ptrPath,
27 const std::string& udc) :
28 keyboardFd(-1),
29 pointerFd(-1), keyboardReport{0}, pointerReport{0}, keyboardPath(kbdPath),
30 pointerPath(ptrPath), udcName(udc)
Eddie James21b177e2018-12-11 13:14:46 -060031{
Jae Hyun Yooc11257d2020-07-22 23:39:18 -070032 hidUdcStream.exceptions(std::ofstream::failbit | std::ofstream::badbit);
33 hidUdcStream.open(hidUdcPath, std::ios::out | std::ios::app);
34}
35
36Input::~Input()
37{
38 if (keyboardFd >= 0)
39 {
40 close(keyboardFd);
41 }
42
43 if (pointerFd >= 0)
44 {
45 close(pointerFd);
46 }
47
48 disconnect();
49 hidUdcStream.close();
50}
51
52void Input::connect()
53{
54 try
55 {
Marvin Linfe685fb2022-10-25 16:20:08 +080056 if (udcName.empty())
Jae Hyun Yooc11257d2020-07-22 23:39:18 -070057 {
Marvin Linfe685fb2022-10-25 16:20:08 +080058 for (const auto& port : fs::directory_iterator(usbVirtualHubPath))
Jae Hyun Yooc11257d2020-07-22 23:39:18 -070059 {
Marvin Linfe685fb2022-10-25 16:20:08 +080060 if (fs::is_directory(port) && !fs::is_symlink(port) &&
61 !fs::exists(port.path() / "gadget/suspended"))
62 {
63 const std::string portId = port.path().filename();
64 hidUdcStream << portId << std::endl;
65 break;
66 }
Jae Hyun Yooc11257d2020-07-22 23:39:18 -070067 }
68 }
Marvin Linfe685fb2022-10-25 16:20:08 +080069 else // If UDC has been specified by '-u' parameter, connect to it.
70 {
71 hidUdcStream << udcName << std::endl;
72 }
Jae Hyun Yooc11257d2020-07-22 23:39:18 -070073 }
74 catch (fs::filesystem_error& e)
75 {
76 log<level::ERR>("Failed to search USB virtual hub port",
77 entry("ERROR=%s", e.what()));
78 return;
79 }
80 catch (std::ofstream::failure& e)
81 {
82 log<level::ERR>("Failed to connect HID gadget",
83 entry("ERROR=%s", e.what()));
84 return;
85 }
86
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -080087 if (!keyboardPath.empty())
Eddie James21b177e2018-12-11 13:14:46 -060088 {
George Liuf79f6f52022-07-06 09:32:35 +080089 keyboardFd =
90 open(keyboardPath.c_str(), O_RDWR | O_CLOEXEC | O_NONBLOCK);
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -080091 if (keyboardFd < 0)
92 {
93 log<level::ERR>("Failed to open input device",
94 entry("PATH=%s", keyboardPath.c_str()),
95 entry("ERROR=%s", strerror(errno)));
96 elog<Open>(xyz::openbmc_project::Common::File::Open::ERRNO(errno),
97 xyz::openbmc_project::Common::File::Open::PATH(
98 keyboardPath.c_str()));
99 }
Eddie James21b177e2018-12-11 13:14:46 -0600100 }
101
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800102 if (!pointerPath.empty())
103 {
Eddie James4749f932019-04-18 11:06:39 -0500104 pointerFd = open(pointerPath.c_str(), O_RDWR | O_CLOEXEC | O_NONBLOCK);
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800105 if (pointerFd < 0)
106 {
107 log<level::ERR>("Failed to open input device",
108 entry("PATH=%s", pointerPath.c_str()),
109 entry("ERROR=%s", strerror(errno)));
110 elog<Open>(xyz::openbmc_project::Common::File::Open::ERRNO(errno),
111 xyz::openbmc_project::Common::File::Open::PATH(
112 pointerPath.c_str()));
113 }
114 }
Eddie James21b177e2018-12-11 13:14:46 -0600115}
116
Jae Hyun Yooc11257d2020-07-22 23:39:18 -0700117void Input::disconnect()
Eddie James21b177e2018-12-11 13:14:46 -0600118{
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800119 if (keyboardFd >= 0)
120 {
121 close(keyboardFd);
Jae Hyun Yooc11257d2020-07-22 23:39:18 -0700122 keyboardFd = -1;
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800123 }
124
125 if (pointerFd >= 0)
126 {
127 close(pointerFd);
Jae Hyun Yooc11257d2020-07-22 23:39:18 -0700128 pointerFd = -1;
129 }
130
131 try
132 {
133 hidUdcStream << "" << std::endl;
134 }
135 catch (std::ofstream::failure& e)
136 {
137 log<level::ERR>("Failed to disconnect HID gadget",
138 entry("ERROR=%s", e.what()));
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800139 }
Eddie James21b177e2018-12-11 13:14:46 -0600140}
141
142void Input::keyEvent(rfbBool down, rfbKeySym key, rfbClientPtr cl)
143{
144 Server::ClientData* cd = (Server::ClientData*)cl->clientData;
145 Input* input = cd->input;
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700146 bool sendKeyboard = false;
147
148 if (input->keyboardFd < 0)
149 {
150 return;
151 }
Eddie James21b177e2018-12-11 13:14:46 -0600152
153 if (down)
154 {
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800155 uint8_t sc = keyToScancode(key);
Eddie James21b177e2018-12-11 13:14:46 -0600156
157 if (sc)
158 {
159 if (input->keysDown.find(key) == input->keysDown.end())
160 {
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800161 for (unsigned int i = 2; i < KEY_REPORT_LENGTH; ++i)
Eddie James21b177e2018-12-11 13:14:46 -0600162 {
163 if (!input->keyboardReport[i])
164 {
165 input->keyboardReport[i] = sc;
166 input->keysDown.insert(std::make_pair(key, i));
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700167 sendKeyboard = true;
Eddie James21b177e2018-12-11 13:14:46 -0600168 break;
169 }
170 }
171 }
172 }
173 else
174 {
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800175 uint8_t mod = keyToMod(key);
Eddie James21b177e2018-12-11 13:14:46 -0600176
177 if (mod)
178 {
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800179 input->keyboardReport[0] |= mod;
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700180 sendKeyboard = true;
Eddie James21b177e2018-12-11 13:14:46 -0600181 }
182 }
183 }
184 else
185 {
186 auto it = input->keysDown.find(key);
187
188 if (it != input->keysDown.end())
189 {
190 input->keyboardReport[it->second] = 0;
191 input->keysDown.erase(it);
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700192 sendKeyboard = true;
Eddie James21b177e2018-12-11 13:14:46 -0600193 }
194 else
195 {
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800196 uint8_t mod = keyToMod(key);
Eddie James21b177e2018-12-11 13:14:46 -0600197
198 if (mod)
199 {
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800200 input->keyboardReport[0] &= ~mod;
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700201 sendKeyboard = true;
Eddie James21b177e2018-12-11 13:14:46 -0600202 }
203 }
204 }
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700205
206 if (sendKeyboard)
207 {
208 input->writeKeyboard(input->keyboardReport);
209 }
Eddie James21b177e2018-12-11 13:14:46 -0600210}
211
212void Input::pointerEvent(int buttonMask, int x, int y, rfbClientPtr cl)
213{
214 Server::ClientData* cd = (Server::ClientData*)cl->clientData;
215 Input* input = cd->input;
216 Server* server = (Server*)cl->screen->screenData;
217 const Video& video = server->getVideo();
218
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700219 if (input->pointerFd < 0)
220 {
221 return;
222 }
223
Tejas Patil3fa0bfb2021-12-23 15:44:47 +0530224 if (buttonMask > 4)
225 {
226 input->pointerReport[0] = 0;
227 if (buttonMask == 8)
228 {
229 input->pointerReport[5] = 1;
230 }
231 else if (buttonMask == 16)
232 {
233 input->pointerReport[5] = 0xff;
234 }
235 }
236 else
237 {
238 input->pointerReport[0] = ((buttonMask & 0x4) >> 1) |
George Liuf79f6f52022-07-06 09:32:35 +0800239 ((buttonMask & 0x2) << 1) |
240 (buttonMask & 0x1);
Tejas Patil3fa0bfb2021-12-23 15:44:47 +0530241 input->pointerReport[5] = 0;
242 }
Eddie James21b177e2018-12-11 13:14:46 -0600243
244 if (x >= 0 && (unsigned int)x < video.getWidth())
245 {
Jae Hyun Yoo2bc661d2019-02-25 13:52:47 -0800246 uint16_t xx = (uint16_t)(x * (SHRT_MAX + 1) / video.getWidth());
Eddie James21b177e2018-12-11 13:14:46 -0600247
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800248 memcpy(&input->pointerReport[1], &xx, 2);
Eddie James21b177e2018-12-11 13:14:46 -0600249 }
250
251 if (y >= 0 && (unsigned int)y < video.getHeight())
252 {
Jae Hyun Yoo2bc661d2019-02-25 13:52:47 -0800253 uint16_t yy = (uint16_t)(y * (SHRT_MAX + 1) / video.getHeight());
Eddie James21b177e2018-12-11 13:14:46 -0600254
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800255 memcpy(&input->pointerReport[3], &yy, 2);
Eddie James21b177e2018-12-11 13:14:46 -0600256 }
257
Eddie James21b177e2018-12-11 13:14:46 -0600258 rfbDefaultPtrAddEvent(buttonMask, x, y, cl);
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700259 input->writePointer(input->pointerReport);
Eddie James21b177e2018-12-11 13:14:46 -0600260}
261
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800262void Input::sendWakeupPacket()
Eddie James21b177e2018-12-11 13:14:46 -0600263{
Jae Hyun Yooeaf5c5b2019-02-20 15:03:17 -0800264 uint8_t wakeupReport[KEY_REPORT_LENGTH] = {0};
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800265
Jae Hyun Yooeaf5c5b2019-02-20 15:03:17 -0800266 if (pointerFd >= 0)
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800267 {
Jae Hyun Yooeaf5c5b2019-02-20 15:03:17 -0800268 uint16_t xy = SHRT_MAX / 2;
269
270 memcpy(&wakeupReport[1], &xy, 2);
271 memcpy(&wakeupReport[3], &xy, 2);
272
Eddie James7cf1f1d2019-09-30 15:05:16 -0500273 writePointer(wakeupReport);
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800274 }
275
Jae Hyun Yooeaf5c5b2019-02-20 15:03:17 -0800276 if (keyboardFd >= 0)
Eddie James21b177e2018-12-11 13:14:46 -0600277 {
Jae Hyun Yooeaf5c5b2019-02-20 15:03:17 -0800278 memset(&wakeupReport[0], 0, KEY_REPORT_LENGTH);
279
280 wakeupReport[0] = keyToMod(XK_Shift_L);
281
Eddie James7cf1f1d2019-09-30 15:05:16 -0500282 if (!writeKeyboard(wakeupReport))
Jae Hyun Yooeaf5c5b2019-02-20 15:03:17 -0800283 {
Jae Hyun Yooeaf5c5b2019-02-20 15:03:17 -0800284 return;
285 }
286
287 wakeupReport[0] = 0;
288
Eddie James7cf1f1d2019-09-30 15:05:16 -0500289 writeKeyboard(wakeupReport);
Eddie James21b177e2018-12-11 13:14:46 -0600290 }
291}
292
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800293uint8_t Input::keyToMod(rfbKeySym key)
Eddie James21b177e2018-12-11 13:14:46 -0600294{
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800295 uint8_t mod = 0;
Eddie James21b177e2018-12-11 13:14:46 -0600296
297 if (key >= XK_Shift_L && key <= XK_Control_R)
298 {
299 mod = shiftCtrlMap[key - XK_Shift_L];
300 }
301 else if (key >= XK_Meta_L && key <= XK_Alt_R)
302 {
303 mod = metaAltMap[key - XK_Meta_L];
304 }
305
306 return mod;
307}
308
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800309uint8_t Input::keyToScancode(rfbKeySym key)
Eddie James21b177e2018-12-11 13:14:46 -0600310{
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800311 uint8_t scancode = 0;
Eddie James21b177e2018-12-11 13:14:46 -0600312
313 if ((key >= 'A' && key <= 'Z') || (key >= 'a' && key <= 'z'))
314 {
315 scancode = USBHID_KEY_A + ((key & 0x5F) - 'A');
316 }
317 else if (key >= '1' && key <= '9')
318 {
319 scancode = USBHID_KEY_1 + (key - '1');
320 }
321 else if (key >= XK_F1 && key <= XK_F12)
322 {
323 scancode = USBHID_KEY_F1 + (key - XK_F1);
324 }
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700325 else if (key >= XK_KP_F1 && key <= XK_KP_F4)
326 {
327 scancode = USBHID_KEY_F1 + (key - XK_KP_F1);
328 }
329 else if (key >= XK_KP_1 && key <= XK_KP_9)
330 {
331 scancode = USBHID_KEY_KP_1 + (key - XK_KP_1);
332 }
Eddie James21b177e2018-12-11 13:14:46 -0600333 else
334 {
335 switch (key)
336 {
337 case XK_exclam:
338 scancode = USBHID_KEY_1;
339 break;
340 case XK_at:
341 scancode = USBHID_KEY_2;
342 break;
343 case XK_numbersign:
344 scancode = USBHID_KEY_3;
345 break;
346 case XK_dollar:
347 scancode = USBHID_KEY_4;
348 break;
349 case XK_percent:
350 scancode = USBHID_KEY_5;
351 break;
352 case XK_asciicircum:
353 scancode = USBHID_KEY_6;
354 break;
355 case XK_ampersand:
356 scancode = USBHID_KEY_7;
357 break;
358 case XK_asterisk:
359 scancode = USBHID_KEY_8;
360 break;
361 case XK_parenleft:
362 scancode = USBHID_KEY_9;
363 break;
364 case XK_0:
365 case XK_parenright:
366 scancode = USBHID_KEY_0;
367 break;
368 case XK_Return:
369 scancode = USBHID_KEY_RETURN;
370 break;
371 case XK_Escape:
372 scancode = USBHID_KEY_ESC;
373 break;
374 case XK_BackSpace:
375 scancode = USBHID_KEY_BACKSPACE;
376 break;
377 case XK_Tab:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700378 case XK_KP_Tab:
Eddie James21b177e2018-12-11 13:14:46 -0600379 scancode = USBHID_KEY_TAB;
380 break;
381 case XK_space:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700382 case XK_KP_Space:
Eddie James21b177e2018-12-11 13:14:46 -0600383 scancode = USBHID_KEY_SPACE;
384 break;
385 case XK_minus:
386 case XK_underscore:
387 scancode = USBHID_KEY_MINUS;
388 break;
389 case XK_plus:
390 case XK_equal:
391 scancode = USBHID_KEY_EQUAL;
392 break;
393 case XK_bracketleft:
394 case XK_braceleft:
395 scancode = USBHID_KEY_LEFTBRACE;
396 break;
397 case XK_bracketright:
398 case XK_braceright:
399 scancode = USBHID_KEY_RIGHTBRACE;
400 break;
401 case XK_backslash:
402 case XK_bar:
403 scancode = USBHID_KEY_BACKSLASH;
404 break;
405 case XK_colon:
406 case XK_semicolon:
407 scancode = USBHID_KEY_SEMICOLON;
408 break;
409 case XK_quotedbl:
410 case XK_apostrophe:
411 scancode = USBHID_KEY_APOSTROPHE;
412 break;
413 case XK_grave:
414 case XK_asciitilde:
415 scancode = USBHID_KEY_GRAVE;
416 break;
417 case XK_comma:
418 case XK_less:
419 scancode = USBHID_KEY_COMMA;
420 break;
421 case XK_period:
422 case XK_greater:
423 scancode = USBHID_KEY_DOT;
424 break;
425 case XK_slash:
426 case XK_question:
427 scancode = USBHID_KEY_SLASH;
428 break;
429 case XK_Caps_Lock:
430 scancode = USBHID_KEY_CAPSLOCK;
431 break;
432 case XK_Print:
433 scancode = USBHID_KEY_PRINT;
434 break;
435 case XK_Scroll_Lock:
436 scancode = USBHID_KEY_SCROLLLOCK;
437 break;
438 case XK_Pause:
439 scancode = USBHID_KEY_PAUSE;
440 break;
441 case XK_Insert:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700442 case XK_KP_Insert:
Eddie James21b177e2018-12-11 13:14:46 -0600443 scancode = USBHID_KEY_INSERT;
444 break;
445 case XK_Home:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700446 case XK_KP_Home:
Eddie James21b177e2018-12-11 13:14:46 -0600447 scancode = USBHID_KEY_HOME;
448 break;
449 case XK_Page_Up:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700450 case XK_KP_Page_Up:
Eddie James21b177e2018-12-11 13:14:46 -0600451 scancode = USBHID_KEY_PAGEUP;
452 break;
453 case XK_Delete:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700454 case XK_KP_Delete:
Eddie James21b177e2018-12-11 13:14:46 -0600455 scancode = USBHID_KEY_DELETE;
456 break;
457 case XK_End:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700458 case XK_KP_End:
Eddie James21b177e2018-12-11 13:14:46 -0600459 scancode = USBHID_KEY_END;
460 break;
461 case XK_Page_Down:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700462 case XK_KP_Page_Down:
Eddie James21b177e2018-12-11 13:14:46 -0600463 scancode = USBHID_KEY_PAGEDOWN;
464 break;
465 case XK_Right:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700466 case XK_KP_Right:
Eddie James21b177e2018-12-11 13:14:46 -0600467 scancode = USBHID_KEY_RIGHT;
468 break;
469 case XK_Left:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700470 case XK_KP_Left:
Eddie James21b177e2018-12-11 13:14:46 -0600471 scancode = USBHID_KEY_LEFT;
472 break;
473 case XK_Down:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700474 case XK_KP_Down:
Eddie James21b177e2018-12-11 13:14:46 -0600475 scancode = USBHID_KEY_DOWN;
476 break;
477 case XK_Up:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700478 case XK_KP_Up:
Eddie James21b177e2018-12-11 13:14:46 -0600479 scancode = USBHID_KEY_UP;
480 break;
481 case XK_Num_Lock:
482 scancode = USBHID_KEY_NUMLOCK;
483 break;
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700484 case XK_KP_Enter:
485 scancode = USBHID_KEY_KP_ENTER;
486 break;
487 case XK_KP_Equal:
488 scancode = USBHID_KEY_KP_EQUAL;
489 break;
490 case XK_KP_Multiply:
491 scancode = USBHID_KEY_KP_MULTIPLY;
492 break;
493 case XK_KP_Add:
494 scancode = USBHID_KEY_KP_ADD;
495 break;
496 case XK_KP_Subtract:
497 scancode = USBHID_KEY_KP_SUBTRACT;
498 break;
499 case XK_KP_Decimal:
500 scancode = USBHID_KEY_KP_DECIMAL;
501 break;
502 case XK_KP_Divide:
503 scancode = USBHID_KEY_KP_DIVIDE;
504 break;
505 case XK_KP_0:
506 scancode = USBHID_KEY_KP_0;
507 break;
Eddie James21b177e2018-12-11 13:14:46 -0600508 }
509 }
510
511 return scancode;
512}
513
George Liuf79f6f52022-07-06 09:32:35 +0800514bool Input::writeKeyboard(const uint8_t* report)
Eddie James7cf1f1d2019-09-30 15:05:16 -0500515{
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700516 std::unique_lock<std::mutex> lk(keyMutex);
517 uint retryCount = HID_REPORT_RETRY_MAX;
518
519 while (retryCount > 0)
Eddie James7cf1f1d2019-09-30 15:05:16 -0500520 {
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700521 if (write(keyboardFd, report, KEY_REPORT_LENGTH) == KEY_REPORT_LENGTH)
Eddie James7cf1f1d2019-09-30 15:05:16 -0500522 {
Zev Weiss40fd5422021-06-17 05:41:40 +0000523 return true;
Eddie James7cf1f1d2019-09-30 15:05:16 -0500524 }
525
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700526 if (errno != EAGAIN)
527 {
528 if (errno != ESHUTDOWN)
529 {
530 log<level::ERR>("Failed to write keyboard report",
531 entry("ERROR=%s", strerror(errno)));
532 }
533
534 break;
535 }
536
537 lk.unlock();
538 std::this_thread::sleep_for(std::chrono::milliseconds(10));
539 lk.lock();
540 retryCount--;
541 }
542
Zev Weiss40fd5422021-06-17 05:41:40 +0000543 return false;
Eddie James7cf1f1d2019-09-30 15:05:16 -0500544}
545
George Liuf79f6f52022-07-06 09:32:35 +0800546void Input::writePointer(const uint8_t* report)
Eddie James7cf1f1d2019-09-30 15:05:16 -0500547{
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700548 std::unique_lock<std::mutex> lk(ptrMutex);
549 uint retryCount = HID_REPORT_RETRY_MAX;
550
551 while (retryCount > 0)
Eddie James7cf1f1d2019-09-30 15:05:16 -0500552 {
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700553 if (write(pointerFd, report, PTR_REPORT_LENGTH) == PTR_REPORT_LENGTH)
Eddie James7cf1f1d2019-09-30 15:05:16 -0500554 {
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700555 break;
Eddie James7cf1f1d2019-09-30 15:05:16 -0500556 }
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700557
558 if (errno != EAGAIN)
559 {
560 if (errno != ESHUTDOWN)
561 {
562 log<level::ERR>("Failed to write pointer report",
563 entry("ERROR=%s", strerror(errno)));
564 }
565
566 break;
567 }
568
569 lk.unlock();
570 std::this_thread::sleep_for(std::chrono::milliseconds(10));
571 lk.lock();
572 retryCount--;
Eddie James7cf1f1d2019-09-30 15:05:16 -0500573 }
574}
575
Eddie James21b177e2018-12-11 13:14:46 -0600576} // namespace ikvm