44

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.

Vishal
  • 3,178
  • 2
  • 34
  • 47
  • Possible duplicate of [How do I simulate a mouse click through the mac terminal?](http://stackoverflow.com/questions/4230867/how-do-i-simulate-a-mouse-click-through-the-mac-terminal) – davidcondrey Jan 08 '17 at 08:42

7 Answers7

68

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

Jappie Kerk
  • 1,257
  • 12
  • 16
  • 3
    Actually I wanted a direct solution, so that I could try the same on Android device. Your solution uses a separate tool. I cannot accept it as the correct answer. Thanks anyways... – Vishal Dec 23 '13 at 09:34
  • 5
    @vishal this is not stated in your question... You said you used ubuntu. Anyways this question is about android key input: http://stackoverflow.com/questions/18244693/android-simulate-a-physical-button-press-of-keyboard-input also please note that android does not use x server as stated here: http://stackoverflow.com/questions/4579573/android-graphics-internals so manipulating input devices is probably not the same as on ubuntu. Also android does not contain gnu, which is the layor on top of most linux desktop distros: http://www.gnu.org/philosophy/android-and-users-freedom.html 5th paragraph – Jappie Kerk Dec 23 '13 at 14:29
  • 1
    Actually I agree I was not fully clear.. By posing the question as "writing to /dev/input/mice", I hoped the solution would be portable to Android. Thanks for your references, they give me a lot of clue on what to expect on Android. – Vishal Dec 23 '13 at 17:45
  • 1
    I liked this answer because it was super-simple, even though it may not have been 100% fitting for the question asked. The other answers are very creative, but I just tried xdotool and moving the mouse and clicking all works fine! I can use this to login to websites which normally required of me to do this manually. :) – shevy Mar 31 '21 at 21:43
  • Hello, Is possible to deny mouse right-click in desktop only? Can any one please let me know? I'm using Ubuntu20 with Mate desktop environment. – Lakshminarayanan S Sep 12 '22 at 04:15
25

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;
}
Raydel Miranda
  • 13,825
  • 3
  • 38
  • 60
14

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?

Community
  • 1
  • 1
tuxdna
  • 8,257
  • 4
  • 43
  • 61
  • 1
    Did you try writing into `/dev/input/eventX` which was the event for the mouse rather than `/dev/input/mice`? I'm asking because `sendevent.c` (https://github.com/android/platform_system_core/blob/master/toolbox/sendevent.c) in Android does just that. I can emulate the power button by writing into the the appropriate event file. Here's the code for that - http://stackoverflow.com/a/17552162/1154689 – Karthik Balakrishnan Apr 02 '15 at 12:54
8

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).
Community
  • 1
  • 1
Ruud Helderman
  • 10,563
  • 1
  • 26
  • 45
  • I am not able to write to the event file even in root mode. Any help? – Dhruv Aug 28 '23 at 14:30
  • @Dhruv Have you adjusted `event8` to your system's mouse input device (as explained in the answer)? If that doesn't help, then please enter a separate question, including code, error message and details about your system. – Ruud Helderman Aug 28 '23 at 17:50
  • Yeah, in my case it is `event5`. The only error I get is permission denied, even in sudo mode. – Dhruv Aug 28 '23 at 21:57
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.

nopper
  • 825
  • 11
  • 18
  • 2
    +1 for not depending on Xorg. To get the example to work I had to modprobe uinput, add `time.sleep(1)` before emitting the mouse events and either run the script as root or add myself to the uinput group – siikamiika Dec 03 '17 at 13:05
1

In addition to use /dev/input/mice to control your mouse, you can use command 'xte' from package 'xautomation'.

apt-get install xautomation

As an example, the following command can be noted:

xte 'mousemove 400 100'

So, the mouse pointer moves to the specific location of the screen. As an other example, we have:

xte 'mouseclick 1'

that click the left button of mouse (1: left click, 2: middle click, 3: right click).

Omidreza Bagheri
  • 781
  • 1
  • 11
  • 22
0

You can create a virtual mouse.

As other mentioned you can use pre-made tools. But it might be funny to play with uinput.

http://thiemonge.org/getting-started-with-uinput

Basically you just have to create a virtual device. And write in /dev/uinput.

chnyda
  • 3
  • 1