当前位置: 首页>>技术问答>>正文


通过写入/dev/input/mice来控制鼠标

, , ,

问题描述

我使用的是Ubuntu 12.04。对于我的一个应用程序,我需要使用脚本在软件中控制鼠标。

我知道鼠标设备是/dev/input/mice。如果我执行cat /dev/input/mice然后移动鼠标,我会看到很多输出被转储到屏幕上。

现在我想删除鼠标,并有一个脚本写入/dev/input/mice以控制鼠标指针

请帮我完成以下命令:(1)执行左键单击(2)执行右键单击(3)将鼠标从一个位置移动到另一个位置。

请注意,我正在寻找一个shell脚本解决方案,而不是一个C /C++解决方案。

最佳解决方法

这不是你提到的文件,但它更快地使用这个工具而不是解密该文件的转储。它在bash中完成了你想要的一切。

xdotool在我的终端中完成了这个技巧。 this是ubuntu的软件包站点。你可能可以安装它

# apt-get install xdotool

我可以在gentoo上出现它而不添加任何存储库。 the tool works fairly simple

#! /bin/bash
# move the mouse  x    y
xdotool mousemove 1800 500
# left click
xdotool click 1
# right click
xdotool click 3

found it here

次佳解决方法

如果你很勇敢,并且你不想依赖任何第三方工具,你应该使用Xlib。文档可以在here找到。如果您不想使用C /C++,也可以尝试python-xlib

检查此thread以获取示例(C /C++)。

这是一个接收坐标并在该位置模拟鼠标点击的程序示例。

#include <X11/Xlib.h>
#include<stdio.h>
#include<unistd.h>
#include <stdlib.h>
#include <string.h>

#include <unistd.h>

#include <X11/Xlib.h>
#include <X11/Xutil.h>

void mouseClick(int button)
{
    Display *display = XOpenDisplay(NULL);

    XEvent event;

    if(display == NULL)
    {
        fprintf(stderr, "Errore nell'apertura del Display !!!\n");
        exit(EXIT_FAILURE);
    }

    memset(&event, 0x00, sizeof(event));

    event.type = ButtonPress;
    event.xbutton.button = button;
    event.xbutton.same_screen = True;

    XQueryPointer(display, RootWindow(display, DefaultScreen(display)), &event.xbutton.root, &event.xbutton.window, &event.xbutton.x_root, &event.xbutton.y_root, &event.xbutton.x, &event.xbutton.y, &event.xbutton.state);

    event.xbutton.subwindow = event.xbutton.window;

    while(event.xbutton.subwindow)
    {
        event.xbutton.window = event.xbutton.subwindow;

        XQueryPointer(display, event.xbutton.window, &event.xbutton.root, &event.xbutton.subwindow, &event.xbutton.x_root, &event.xbutton.y_root, &event.xbutton.x, &event.xbutton.y, &event.xbutton.state);
    }

    if(XSendEvent(display, PointerWindow, True, 0xfff, &event) == 0) fprintf(stderr, "Error\n");

    XFlush(display);

    usleep(100000);

    event.type = ButtonRelease;
    event.xbutton.state = 0x100;

    if(XSendEvent(display, PointerWindow, True, 0xfff, &event) == 0) fprintf(stderr, "Error\n");

    XFlush(display);

    XCloseDisplay(display);
}
int main(int argc,char * argv[]) {
    int i=0;
    int x , y;
    x=atoi(argv[1]);
    y=atoi(argv[2]);
    Display *display = XOpenDisplay(0);
    Window root = DefaultRootWindow(display);

    XWarpPointer(display, None, root, 0, 0, 0, 0, x, y);

    mouseClick(Button1);
    XFlush(display);


    XCloseDisplay(display);
    return 0;
}

第三种解决方法

您可以使用/dev /input /mice中的od工具捕获事件,然后在解码序列后重放它们。

# cat /dev/input/mice | od -t x1 -w3
0000000 08 02 00
0000003 08 08 00
0000006 08 09 00
0000011 08 07 00
0000014 08 04 00
0000017 08 01 01
0000022 08 00 02
0000025 08 02 02

为此,您可以在此处获取python代码的帮助:

Get mouse deltas using Python! (in Linux)

L:0, M: 0, R: 0, x: -1, y: -1

L:0, M: 0, R: 0, x: 0, y: -1

L:0, M: 0, R: 0, x: 0, y: -1

L:0, M: 0, R: 0, x: 0, y: 2

L:0, M: 0, R: 0, x: 0, y: 1

L:0, M: 0, R: 0, x: 0, y: -1

L:0, M: 0, R: 0, x: 1, y: -1

完成后,您可以将其编码为每个鼠标移动的3字节序列。

要使用bash对二进制值进行编码,可以参考以下问题:Passing binary data as arguments in bash

但是我尝试写/dev/input/mice不起作用。

原因是,此文件仅为您提供已经发生的事件流。因此必须有其他方式来注入此类事件。

How to control mouse movement in linux?

第四种方法

有一个适当的模块用于在linux中模拟鼠标,键盘和其他类型的输入设备。该模块名为uinput,代表user-space输入。

您可以轻松创建通过软件控制的虚拟设备。例如,如果您了解Python,则可以通过使用python-uinput设置虚拟鼠标并发出简单命令,例如移动到此处,单击此处。例如,移动鼠标,相应的文档:

import uinput

device = uinput.Device([uinput.REL_X, uinput.REL_Y])

for i in range(20):
    device.emit(uinput.REL_X, 5)
    device.emit(uinput.REL_Y, 5)

我从来没有使用过这种装订,但几年前我创建了一个鼠标模拟器,可以通过键盘控制我的iBook,它带有破碎的触摸板。您可以查看我的code以获得参考,以实现鼠标/触摸板移动操作。

第五种方法

正是这篇早期帖子中的超链接让我走上正轨:How to control mouse movement in Linux

在其他各个地方的信息帮助下,我设法将C示例代码移植到Bash脚本中。这是一个将鼠标光标向右移动100个像素的PoC:

seconds=$(date +%s)
type=2      # EV_REL
code=0      # REL_X
value=100   # 100 pixels

printf '%08X%04X%04X%08X%08X\n' $value $code $type 0 $seconds | xxd -r -p | perl -0777e 'print scalar reverse <>' > /dev/input/event8

type=0      # EV_SYN
code=0      # SYN_REPORT
value=0

printf '%08X%04X%04X%08X%08X\n' $value $code $type 0 $seconds | xxd -r -p | perl -0777e 'print scalar reverse <>' > /dev/input/event8

注意事项:

  • 您必须将event8调整为系统的鼠标输入设备。使用此命令查找:cat /proc /bus /input /devices

  • 您需要足够的权限(可能是root)才能写入输入设备。

  • 我假设little-endian处理器架构(因此使用Perl进行字节反转)。

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/6695.html,未经允许,请勿转载。