Control mouse by writing to /dev/input/mice

46,373

Solution 1

this is not trough the file you mentioned, but its way quicker to use this tool instead of decypering the dump of that file. And it does everything you want in bash.

xdotool does the trick in my terminal.
this is the package site for ubuntu. you probably can install it trough

# apt-get install xdotool

I could just emerge it on gentoo without adding any repositories.
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

Solution 2

If you are brave, and you don't want to depend on any third party tool, you should use Xlib. Documentation can be found here. Also you can try python-xlib if you don't want to mess with C/C++.

Check this thread for an example (C/C++).

This is an example of a program that receives a coord and simulates a mouse click at that position.

#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;
}

Solution 3

You can capture the events using od tool from the /dev/input/mice and then replay them once you have decoded the sequence.

# 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

For this you can take help of the python code here:

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

Once you have that, you can encode it back into a 3 byte sequence for each mouse move.

To encode the binary values using bash you can refer to this question: Passing binary data as arguments in bash

However I tried and writing to /dev/input/mice does not work.

The reason is that, this file is only giving a streams of events for you which have already happened. So there must be some other way to inject such events.

How to control mouse movement in linux?

Solution 4

It was this hyperlink in one of the earlier posts that put me on the right track: How to control mouse movement in Linux

Helped by information from various other places, I managed to port the C sample code to a Bash script. Here's a PoC that moves the mouse cursor 100 pixels to the right:

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

Caveats:

  • You will have to adjust event8 to whatever is your system's mouse input device. Use this command to find out: cat /proc/bus/input/devices
  • You need sufficient permission (possibly root) to write to the input device.
  • I assumed little-endian processor architecture (hence the byte reversal with Perl).

Solution 5

There's an appropriate module for emulating mouse, keyboards and other kind of input devices in linux. The module is called uinput that stands for user-space input.

You can easily create virtual devices that are controlled through software. For example if you know Python you can set up a virtual mouse through the use of python-uinput and issue simple commands such as move here, click there. For example to move your mouse, accordingly to the documentation:

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)

I never used that binding though, but several years ago I created a mouse emulator that can be controlled through keyboard for my iBook that came with a broken touchpad. You can take a look at my code to have a reference in order to implement the mouse/touchpad movement operation.

Share:
46,373
Vishal
Author by

Vishal

Updated on July 09, 2022

Comments

  • Vishal
    Vishal almost 2 years

    I am using Ubuntu 12.04. For one of my applications I require to control the mouse in software using a script.

    I understand that the mouse device is /dev/input/mice. If I do a cat /dev/input/mice and then move my mouse, I see a lot of output being dumped to the screen.

    Now I wish to remove the mouse, and have a script which writes to /dev/input/mice in order to control the mouse pointer

    Please help me with commands for the following:
    (1) Perform a left click
    (2) Perform a right click
    (3) Move the mouse from one location to another.

    Kindly note that I am looking for a shell script solution, rather than a C/C++ solution.