AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 422698
Accepted
Anon
Anon
Asked: 2018-02-08 17:49:04 +0800 CST2018-02-08 17:49:04 +0800 CST 2018-02-08 17:49:04 +0800 CST

如何在不使用鼠标的情况下在 Wayland 中设置绝对鼠标光标位置?

  • 772

这个问题很简单。

我在 X 下使用的[xdotool]显然无法继续前进,并且鉴于相对较新的 Wayland 采用,没有出现明显的新解决方案。

需要编程的解决方案是可以接受的。

mouse wayland
  • 3 3 个回答
  • 5211 Views

3 个回答

  • Voted
  1. Best Answer
    aliceinpalth
    2018-02-08T19:04:18+08:002018-02-08T19:04:18+08:00

    您可以使用uinput ( 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;
    }
    
    • 7
  2. meuh
    2018-02-09T07:57:24+08:002018-02-09T07:57:24+08:00

    如果您不想为uinput编写 C 代码,则可以使用 python 包,甚至一些现有的调试和测试实用程序在相同的evdev级别上工作,即 evemu-describe, evemu-device, evemu-play, evemu-record, 和 evemu-event来自 evemu 包。您需要成为 root 才能使用它们。这是一个示例,它找到鼠标设备及其生成的事件,然后人为地为其生成事件。

    首先我们列出 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)。这些事件之后是 EV_SYN 类型的同步事件,代码为 SYN_REPORT 以表示事件的结束。

    我们可以用另一个测试命令注入我们自己的事件(比如移动 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
  3. F. Hauri - Give Up GitHub
    2022-09-29T00:29:59+08:002022-09-29T00:29:59+08:00

    根据meuh 的回答,我编写了这个小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
    

    由于鼠标加速概念,实际移动不对应于精确值,除了非常低的值。

    • 1

相关问题

  • 如何在 Libinput(Debian Gnome)下的 Wayland 中设置设备特定的鼠标设置?

  • 降低 Kubuntu 17.10 上的鼠标灵敏度

  • 如何在linux中配置鼠标?

  • Virtual Machine Manager 想要在 Wayland 上一次又一次地禁止快捷方式

  • Linux Mint 18 上的鼠标指针太快

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    ssh 无法协商:“找不到匹配的密码”,正在拒绝 cbc

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    如何卸载内核模块“nvidia-drm”?

    • 13 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add 返回:“连接代理时出错:没有这样的文件或目录” 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya 为什么 Linux 使用 LF 作为换行符? 2017-12-20 05:48:21 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve