마우스를 사용하지 않고 Wayland에서 절대 마우스 커서 위치를 설정하는 방법은 무엇입니까?

마우스를 사용하지 않고 Wayland에서 절대 마우스 커서 위치를 설정하는 방법은 무엇입니까?

질문은 간단합니다.

내가 사용하고 [xdotool]있던 것

프로그래밍이 필요한 솔루션은 허용됩니다.

답변1

당신은 그것을 사용할 수 있습니다입력( linux/uinput.h). X와 Wayland에서 작동합니다.

위 문서 페이지에는 마우스 역할을 하는 가상 장치 생성을 포함하는 예가 있습니다.

#include <linux/uinput.h>

void emit(int fd, int type, int code, int val)
{
   struct input_event ie;

   ie.type = type;
   ie.code = code;
   ie.value = val;
   /* timestamp values below are ignored */
   ie.time.tv_sec = 0;
   ie.time.tv_usec = 0;

   write(fd, &ie, sizeof(ie));
}

int main(void)
{
   struct uinput_setup usetup;
   int i = 50;

   int fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);

   /* enable mouse button left and relative events */
   ioctl(fd, UI_SET_EVBIT, EV_KEY);
   ioctl(fd, UI_SET_KEYBIT, BTN_LEFT);

   ioctl(fd, UI_SET_EVBIT, EV_REL);
   ioctl(fd, UI_SET_RELBIT, REL_X);
   ioctl(fd, UI_SET_RELBIT, REL_Y);

   memset(&usetup, 0, sizeof(usetup));
   usetup.id.bustype = BUS_USB;
   usetup.id.vendor = 0x1234; /* sample vendor */
   usetup.id.product = 0x5678; /* sample product */
   strcpy(usetup.name, "Example device");

   ioctl(fd, UI_DEV_SETUP, &usetup);
   ioctl(fd, UI_DEV_CREATE);

   /*
    * On UI_DEV_CREATE the kernel will create the device node for this
    * device. We are inserting a pause here so that userspace has time
    * to detect, initialize the new device, and can start listening to
    * the event, otherwise it will not notice the event we are about
    * to send. This pause is only needed in our example code!
    */
   sleep(1);

   /* Move the mouse diagonally, 5 units per axis */
   while (i--) {
      emit(fd, EV_REL, REL_X, 5);
      emit(fd, EV_REL, REL_Y, 5);
      emit(fd, EV_SYN, SYN_REPORT, 0);
      usleep(15000);
   }

   /*
    * Give userspace some time to read the events before we destroy the
    * device with UI_DEV_DESTOY.
    */
   sleep(1);

   ioctl(fd, UI_DEV_DESTROY);
   close(fd);

   return 0;
}

답변2

C 코드를 작성하고 싶지 않다면입력, 동시에 작동할 수 있는 Python 패키지와 일부 기존 디버깅 및 테스트 유틸리티도 있습니다.evdev레벨, 즉 evemu-describe, evemu-device, evemu-play, evemu-recordevemu-eventevemu 패키지에서. 이를 사용하려면 루트 권한이 필요합니다. 다음은 마우스 장치와 해당 장치가 생성하는 이벤트를 찾은 다음 인위적으로 이벤트를 생성하는 예입니다.

먼저 evdev 장치를 나열합니다.

$ sudo evemu-describe 
Available devices:
...
/dev/input/event5:     Logitech USB Optical Mouse
...

이는 대화형 명령으로, 물리적 장치를 나열한 후 자세한 내용을 보려면 하나를 선택하라는 메시지를 표시합니다. 5. 마우스를 선택합니다.

Select the device event number [0-9]: 5
...
# Input device name: "Logitech USB Optical Mouse"
...
# Supported events:
#   Event type 0 (EV_SYN)
#     Event code 0 (SYN_REPORT)
...
#   Event type 1 (EV_KEY)
#     Event code 272 (BTN_LEFT)
#     Event code 273 (BTN_RIGHT)
#     Event code 274 (BTN_MIDDLE)
#   Event type 2 (EV_REL)
#     Event code 0 (REL_X)
#     Event code 1 (REL_Y)
#     Event code 8 (REL_WHEEL)
...

또 다른 evemu 테스트 명령은 마우스가 움직일 때 생성되는 이벤트를 보여줍니다.

$ sudo evemu-record /dev/input/event5
E: 4.223 0002 0000 0004 # EV_REL / REL_X                4
E: 4.223 0000 0000 0000 # ------------ SYN_REPORT (0) ------ +8ms
E: 4.231 0002 0000 0007 # EV_REL / REL_X                7
E: 4.231 0002 0001 0001 # EV_REL / REL_Y                1
E: 4.231 0000 0000 0000 # ------------ SYN_REPORT (0) ------ +8ms

일반적으로 마우스 이동의 경우 이벤트 유형 EV_REL, 이동 축에 대한 이벤트 코드 REL_X 및/또는 REL_Y, 이동에 대한 이벤트 값 거리(위의 4, 7, 1)가 있습니다. 이러한 이벤트 뒤에는 이벤트 종료를 나타내는 SYN_REPORT 코드가 포함된 EV_SYN 유형의 동기화 이벤트가 옵니다.

다른 테스트 명령을 사용하여 자체 이벤트(예: 20,10 이동)를 주입할 수 있습니다.

sudo evemu-event /dev/input/event5 --type EV_REL --code REL_X --value 20
sudo evemu-event /dev/input/event5 --type EV_REL --code REL_Y --value 10 --sync

--sync옵션은 SYN_REPORT 이벤트를 끝에 추가합니다( 와 동일 --type EV_SYN --code SYN_REPORT).

마지막으로 또 다른 테스트 명령을 사용하면 evemu-device설명(예: 이미 본 마우스의 설명)을 제공하여 새 입력 장치를 만들 수 있습니다. 이벤트를 보내는 데 사용할 수 있는 /dev/uinput새 장치를 가져와 생성합니다./dev/input/event*

따라서 마우스가 없더라도 동적으로 추가하고 원하는 대로 제어할 수 있습니다. 예를 들기 위한 절대 위치 이벤트가 있는 장치는 없지만 유사하게 태블릿과 같은 장치를 추가하고 이를 통해 절대 이동 이벤트를 보낼 수 있습니다.

답변3

~에서야옹의 대답, 내가 이걸 조금 썼어mousemovebash 스크립트, 인수로 실행 XREL YREL.

#!/bin/bash

while IFS=: read dev desc ;do
    case $desc in 
        *[Mm]ouse* ) mousedev=$dev;;
    esac 
done < <(evemu-describe <<<'' 2>&1)

[ -c "$mousedev" ] && 
    evemu-event $mousedev --type EV_REL --code REL_X --value $1 &&
    evemu-event $mousedev --type EV_REL --code REL_Y --value $2 --sync

~처럼root또는 다음을 통해 sudo:

sudo mousemove -20 10
sudo mousemove -4000 -4000

왜냐하면마우스 가속개념적으로 실제 움직임은 매우 낮은 값을 제외하고는 정확한 값과 일치하지 않습니다.

관련 정보