Control mouse by writing to /dev/input/mice
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
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.
Vishal
Updated on July 09, 2022Comments
-
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 acat /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 pointerPlease 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.