uinput - проблема синхронизации координат мыши
Я пишу программу для удаленного управления устройством на основе руки, на котором не запущен X-сервер. У меня есть небольшая утилита для захвата событий мыши, которые отправляются со стороны клиента, и эмулировать их на устройстве. Для этого я использую uinput.
Проблема, с которой я сталкиваюсь, заключается в том, что курсор на устройстве рычага изначально находится, скажем, (300 300). Когда я подключаюсь к устройству (используя плагин VNC в Chrome), указатель мыши клиента в браузере находится, скажем, (100, 100). Разрыв между двумя позициями указателя мыши (в браузере и на устройстве) составляет 200 пикселей по диагонали. Этот разрыв поддерживается постоянно. Если я переместу указатель вправо на 10 пикселей (от 100 100 до 110 100), указатель мыши на устройстве переместится с 300 300 на 310 300. Я не уверен, что может быть причиной этого. Единственный раз, когда эта проблема не возникает, это когда я проверяю, что оба указателя мыши изначально начинаются с одинаковых координат (например, начиная с любого угла окна).
Вот весь код, связанный с uinput:
static char TOUCH_DEVICE[256] = "/dev/uinput";
struct uinput_user_dev touch_uidev;
struct input_event moveev[2];
struct input_event touchev;
static int touchfd = -1;
// Opening device
if((touchfd = open(TOUCH_DEVICE, O_WRONLY | O_NONBLOCK)) == -1)
{
printf("cannot open touch device %s\n", TOUCH_DEVICE);
exit(EXIT_FAILURE);
}
printf("Registering event types...\n");
if(ioctl(touchfd, UI_SET_EVBIT, EV_SYN) < 0)
die("error: ioctl");
if(ioctl(touchfd, UI_SET_EVBIT, EV_ABS) < 0)
die("error: ioctl");
if(ioctl(touchfd, UI_SET_ABSBIT, ABS_X) < 0)
die("error: ioctl");
if(ioctl(touchfd, UI_SET_ABSBIT, ABS_Y) < 0)
die("error: ioctl");
memset(&touch_uidev, 0, sizeof(touch_uidev));
snprintf(touch_uidev.name, UINPUT_MAX_NAME_SIZE, "uinput-mouse");
touch_uidev.id.bustype = BUS_USB;
touch_uidev.id.vendor = 0x1;
touch_uidev.id.product = 0x1;
touch_uidev.id.version = 1;
touch_uidev.absmin[ABS_X] = 0;
touch_uidev.absmax[ABS_X] = 640;
touch_uidev.absmin[ABS_Y] = 0;
touch_uidev.absmax[ABS_Y] = 480;
if(write(touchfd, &touch_uidev, sizeof(touch_uidev)) < 0)
die("error: write");
if(ioctl(touchfd, UI_DEV_CREATE) < 0)
die("error: ioctl");
printf("Mouse fd opened successfully.\n");
//Injecting events
memset(moveev, 0, sizeof(moveev));
moveev[0].type = EV_ABS;
moveev[0].code = ABS_X;
moveev[0].value = x;
moveev[1].type = EV_ABS;
moveev[1].code = ABS_Y;
moveev[1].value = y;
if(write(touchfd, moveev, sizeof(moveev)) < 0)
die("error: write");
memset(&touchev, 0, sizeof(touchev));
touchev.type = EV_SYN;
touchev.code = 0;
touchev.value = 0;
if(write(touchfd, &touchev, sizeof(touchev)) < 0)
die("error: write");
Эта проблема не возникает, когда работает X-сервер. Мне любопытно, что вызывает это. Любая помощь с благодарностью. Благодарю.