- How to set mouse cursor position in C on linux?
- 6 Answers 6
- How to set absolute mouse cursor position in Wayland without using mouse?
- 3 Answers 3
- How to set cursor position with command/script?
- 1 Answer 1
- Moving the mouse to a defined (absolute) position
- Straightforward version (move cursor to the center of the left screen)
- Extended version (optional arguments x, y)
- Explanation
- How to set mouse cursor position in c on linux?
- Method 1: Using the Xlib Library
- Method 2: Using the XTest Extension
- Step 1: Include the necessary headers
- Step 2: Open a connection to the X server
- Step 3: Get the root window
- Step 4: Move the mouse cursor to the desired position
- Step 5: Close the connection to the X server
How to set mouse cursor position in C on linux?
how can I set the mouse cursor position in an X window using a C program under Linux? thanks 🙂 (like setcursorpos() in WIN) EDIT: I’ve tried this code, but doesn’t work:
in an X window.. but I don’t have to get the cursor position, I have to set it everywhere in the screen
(I’ve edited your question for you; you really wanted to do that when you replied to my comment.) You see the value of being specific. 🙂 You now have three answers completely unrelated to the question (they’re all about setting cursor position in terminal windows).
In X Window System, the mouse cursor refers to the graphic icon, whereas you seem to want to move the pointer itself (which moves the «hotspot» as well as also moving the cursor icon).
6 Answers 6
Although movement of the pointer normally should be left to the control of the end user, sometimes it is necessary to move the pointer to a new position under program control.
To move the pointer to an arbitrary point in a window, use XWarpPointer().
Display *dpy; Window root_window; dpy = XOpenDisplay(0); root_window = XRootWindow(dpy, 0); XSelectInput(dpy, root_window, KeyReleaseMask); XWarpPointer(dpy, None, root_window, 0, 0, 0, 0, 100, 100); XFlush(dpy); // Flushes the output buffer, therefore updates the cursor's position. Thanks to Achernar.
thanks but it doesn’t work: I edited the 2nd argument of XWarpPointer from NULL to None, I get no errors while compiling, but cursor doesn’t move
It didn’t compile for me either and I think it’s because of missing libraries. I tried including the libraries mentioned by @Achernar, but my compiler still can’t find the references to XOpenDisplay and the other library calls. I’m including them as follows (obviously, not all in one line, but I’m having trouble formatting my comment): #include
This is old, but in case someone else comes across this issue. The answer provided by tusbar was correct but the command XFlush(dpy) must be added at the end to update the cursor’s position. The libraries needed are: X11/X.h, X11/Xlib.h, X11/Xutil.h.
int main(int argc, char *argv[]) < //Get system window Display *dpy; Window root_window; dpy = XOpenDisplay(0); root_window = XRootWindow(dpy, 0); XSelectInput(dpy, root_window, KeyReleaseMask); XWarpPointer(dpy, None, root_window, 0, 0, 0, 0, 100, 100); XFlush(dpy); return 0;>
PS: You can use this command to build the code gcc main.c -lX11
You want to write a X11 program that uses the call XWarpPointer function to move the point to a relative or global position. (Xlib Programming Manual, Vol 1)
In general, using Xlib for programming the X Window System, is the most basic, and quite low-level interface for graphical programming on a Unix or Linux system. Most applications developed nowadays using a higher level library such as GTK or Qt for developing their GUI applications.
Curses or NCurses (New Curses) is for programming terminal-oriented interfaces, so are not useful in this case.
use Jordan Sissel’s excellent utility xdotool.
it provide XWarpPointer wrapper function like xdo_mousemove(), here is some example:
Display *display = NULL; xdo_t *xdo = NULL; void mouse_left_down(int x, int y) < xdo_mousemove(xdo, x, y, 0) xdo_mousedown(xdo, CURRENTWINDOW, Button1); >void mouse_left_up(int x, int y) < xdo_mouseup(xdo, CURRENTWINDOW, Button1, 1, 0); >void mouse_left_double_click(int x, int y) < xdo_mousemove(xdo, x, y, 0); xdo_click_multiple(xdo, CURRENTWINDOW, Button1, 1, 0); doubleclick = TRUE; >int main() < display = XOpenDisplay(NULL); if(display == NULL) < fprintf(stderr, "can't open display!\n"); return -1; >xdo = xdo_new((char*) display); //some task here // . return 0; >
How to set absolute mouse cursor position in Wayland without using mouse?
The question is pretty straight forward. What I would have used under X [xdotool] obviously does not work moving forward, and no obvious new solutions have arisen given the relative new adoption of wayland. Solutions which require programming are acceptable.
3 Answers 3
You can use uinput ( linux/uinput.h ). It works across X as well as Wayland.
The documentation page above has an example that includes creating a virtual device that behaves as a mouse:
#include 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; >
If you don’t want to write C code for uinput, there are python packages and even some existing debug and test utilities that work at the same evdev level, namely evemu-describe , evemu-device , evemu-play , evemu-record , and evemu-event from the evemu package. You need to be root to use them. Here’s an example that finds the mouse device and the events it generates, then artificially generates an event for it.
First we list the evdev devices:
$ sudo evemu-describe Available devices: . /dev/input/event5: Logitech USB Optical Mouse .
This is an interactive command, which after listing the physical devices asks us to choose one for further details on it. We choose 5, the mouse:
Select the device event number 3: 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) .
Another of the evemu test commands will show us the events being generated when we move the mouse:
$ 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
Typically, for a mouse movement there is the event type EV_REL, the event code REL_X and or REL_Y for the relative movement axis, and the event value distance moved (4, 7, 1 above). The events are followed by a synchronisation event of type EV_SYN with code SYN_REPORT to signal the end of the event.
We can inject our own event (say a move of 20,10) with another of the test commands:
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
The —sync option adds the SYN_REPORT event to the end (the equivalent of —type EV_SYN —code SYN_REPORT ).
Finally, another test command, evemu-device allows us to create a new input device by giving a description such as the ones we have already seen for the mouse. It uses /dev/uinput and creates a new /dev/input/event* device, which we can then use to send events to.
So even if you do not have a mouse, you can add one dynamically, and then control it as you wish. I do not have a device with absolute position events to provide you with an example, but you can similarly add a tablet-like device and send absolute moves events through it.
How to set cursor position with command/script?
I have a script which resets some things, and at the end of it I need it to set the cursor to certain coordinates, either to a custom set or to the centre of the screen (where it is reset to by default when restarting gnome-shell for instance). How can this be achieved? The solution would have to work for all display sizes and be able to automatically get the data and do all the maths etc involved. I am running Ubuntu GNOME 16.04 with GNOME 3.20.
Do I understand that it symply needs to set the cursor in the middle op the screen? If so, which one if multiple?
@JacobVlijm: That as well as being able to be given custom coordinates for where to reset it two. Perhaps it should be given the custom coordinates as arguments, but if there are no arguments given then it should assume the centre.
1 Answer 1
Moving the mouse to a defined (absolute) position
..is simply done by the command (e.g.):
xdotool mousemove 200 200
To move the mouse to the centre of the screen however is a relative command, for which we need to read the screen’s information and do some calculations. This is done in the two small scripts below.
Straightforward version (move cursor to the center of the left screen)
To move the mouse to the center of the (leftmost) screen, use the script below:
#!/usr/bin/env python3 import subprocess xr = [s for s in subprocess.check_output("xrandr").decode("utf-8").split() if "+0+" in s] scr = [int(n)/2 for n in xr[0].split("+")[0].split("x")] subprocess.Popen(["xdotool", "mousemove", str(scr[0]), str(scr[1])])
sudo apt-get install xdotool
python3 /path/to/center_screen.py
Extended version (optional arguments x, y)
If arbitrary coordinates are optional, use:
#!/usr/bin/env python3 import subprocess import sys if sys.argv[1:]: scr = [sys.argv[1], sys.argv[2]] else: xr = [s for s in subprocess.check_output("xrandr").decode("utf-8").split() if "+0+" in s] scr = [str(int(n)/2) for n in xr[0].split("+")[0].split("x")] subprocess.Popen(["xdotool", "mousemove", scr[0], scr[1]])
This version will move the cursor to the center of the screen, when run without arguments, or to an arbitrary position, when run with arguments, e.g.:
python3 /path/to/center_screen.py 200 200
Explanation
In the output of the command: xrandr , all we need to find is the string like:
. which contains the data on the leftmost screen ( +0+ ). both figures in 1680×1050 are then to be divided by two, to be used in:
is then to decide wether the given arguments should be used or the calculated ones.
How to set mouse cursor position in c on linux?
Setting the mouse cursor position in C on Linux is a task that requires the use of specific libraries and functions. The process can be different depending on the operating system you are using and the programming environment you are working in. In this article, we will focus on setting the mouse cursor position in C on Linux systems. The following methods will be covered:
Method 1: Using the Xlib Library
To set the mouse cursor position in C on Linux using the Xlib library, you can follow these steps:
Display *display = XOpenDisplay(NULL); if (display == NULL) fprintf(stderr, "Cannot open display\n"); exit(1); >
Window root = XDefaultRootWindow(display);
int x = 100; // set the x-coordinate int y = 100; // set the y-coordinate XWarpPointer(display, None, root, 0, 0, 0, 0, x, y); XFlush(display); // flush the output buffer to update the cursor position
#include #include #include int main() Display *display = XOpenDisplay(NULL); if (display == NULL) fprintf(stderr, "Cannot open display\n"); exit(1); > Window root = XDefaultRootWindow(display); int x = 100; // set the x-coordinate int y = 100; // set the y-coordinate XWarpPointer(display, None, root, 0, 0, 0, 0, x, y); XFlush(display); XCloseDisplay(display); return 0; >
This code opens a connection to the X server, gets the root window, sets the mouse cursor position to (100, 100), flushes the output buffer to update the cursor position, and then closes the connection to the X server.
Method 2: Using the XTest Extension
To set the mouse cursor position in C on Linux using the XTest Extension, you can follow these steps:
Step 1: Include the necessary headers
Step 2: Open a connection to the X server
Display *display = XOpenDisplay(NULL);
Step 3: Get the root window
Window root = XDefaultRootWindow(display);
Step 4: Move the mouse cursor to the desired position
XTestFakeMotionEvent(display, -1, x, y, 0); XFlush(display);
In the above code, x and y are the coordinates of the desired position.
Step 5: Close the connection to the X server
#include #include int main() Display *display = XOpenDisplay(NULL); Window root = XDefaultRootWindow(display); int x = 100, y = 100; XTestFakeMotionEvent(display, -1, x, y, 0); XFlush(display); XCloseDisplay(display); return 0; >
This code will move the mouse cursor to the position (100, 100) on the screen.
Note that you need to link your program with the X11 and Xtst libraries:
gcc -o program program.c -lX11 -lXtst