How to read low level mouse click position in linux .
Solution 1
You can get the initial position from X11, and use relative coordinates to track the pointer:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/input.h>
#include <fcntl.h>
#include <X11/Xlib.h>
#define MOUSEFILE "/dev/input/event6"
int main()
{
int fd;
struct input_event ie;
Display *dpy;
Window root, child;
int rootX, rootY, winX, winY;
unsigned int mask;
dpy = XOpenDisplay(NULL);
XQueryPointer(dpy,DefaultRootWindow(dpy),&root,&child,
&rootX,&rootY,&winX,&winY,&mask);
if((fd = open(MOUSEFILE, O_RDONLY)) == -1) {
perror("opening device");
exit(EXIT_FAILURE);
}
while(read(fd, &ie, sizeof(struct input_event))) {
if (ie.type == 2) {
if (ie.code == 0) { rootX += ie.value; }
else if (ie.code == 1) { rootY += ie.value; }
printf("time%ld.%06ld\tx %d\ty %d\n",
ie.time.tv_sec, ie.time.tv_usec, rootX, rootY);
} else if (ie.type == 1) {
if (ie.code == 272 ) {
printf("Mouse button ");
if (ie.value == 0)
printf("released!!\n");
if (ie.value == 1)
printf("pressed!!\n");
} else {
printf("time %ld.%06ld\ttype %d\tcode %d\tvalue %d\n",
ie.time.tv_sec, ie.time.tv_usec, ie.type, ie.code, ie.value);
}
}
return 0;
}
Solution 2
A mouse only sends relative movement, not absolute position. You have to keep track of it yourself, and when you receive a mouse-button event you have to check your own coordinates for the position.
Related videos on Youtube
rajat
Updated on July 14, 2022Comments
-
rajat almost 2 years
I am using this code to read mouse events from the dev/input/event* in linux .
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <linux/input.h> #include <fcntl.h> #define MOUSEFILE "/dev/input/event4" int main() { int fd; struct input_event ie; if((fd = open(MOUSEFILE, O_RDONLY)) == -1) { perror("opening device"); exit(EXIT_FAILURE); } while(read(fd, &ie, sizeof(struct input_event))) { printf("time %ld.%06ld\ttype %d\tcode %d\tvalue %d\n", ie.time.tv_sec, ie.time.tv_usec, ie.type, ie.code, ie.value); } return 0; }
It gives me the results in the format :
time 1342517261.840285 type 2 code 0 value -1
'time' is the timestamp, it returns the time at which the event happened.
'code' is event code, for example REL_X or KEY_BACKSPACE, complete list is in include/linux/input.h.
'value' is the value the event carries. Either a relative change for EV_REL, absolute new value for EV_ABS (joysticks ...), or 0 for EV_KEY for release, 1 for keypress and 2 for autorepeat.
when i click , i get the event but i don't get the position of the mouse on the screen , what is the way to get the position of the mouse on screen .
Edit 1:So as it turns out that i have to use the relative co-ordinates to get the mouse co-ordinates .I believe this is a common requirement so there might be libraries/pre-existing code that you can use to get the co-ordinates. Any info on this topic will be very useful .
Edit2 : SOLUTION
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <linux/input.h> #include <fcntl.h> #include <X11/Xlib.h> #define MOUSEFILE "/dev/input/event4" int main() { int fd; struct input_event ie; Display *dpy; Window root, child; int rootX, rootY, winX, winY; unsigned int mask; dpy = XOpenDisplay(NULL); XQueryPointer(dpy,DefaultRootWindow(dpy),&root,&child, &rootX,&rootY,&winX,&winY,&mask); if((fd = open(MOUSEFILE, O_RDONLY)) == -1) { perror("opening device"); exit(EXIT_FAILURE); } while(read(fd, &ie, sizeof(struct input_event))) { if (ie.type == 2) { if (ie.code == 0) { XQueryPointer(dpy,DefaultRootWindow(dpy),&root,&child, &rootX,&rootY,&winX,&winY,&mask); //rootX += ie.value; } else if (ie.code == 1) { XQueryPointer(dpy,DefaultRootWindow(dpy),&root,&child, &rootX,&rootY,&winX,&winY,&mask); // rootY += ie.value; } printf("time%ld.%06ld\tx %d\ty %d\n", ie.time.tv_sec, ie.time.tv_usec, rootX, rootY); } else printf("time %ld.%06ld\ttype %d\tcode %d\tvalue %d\n", ie.time.tv_sec, ie.time.tv_usec, ie.type, ie.code, ie.value); } return 0; }
XQueryPointer seems more convenient solution . Thanks , @perreal for the guidance .
-
rajat almost 12 yearsHi ,The code seems very elegant .Thanks . But it is giving me following errors :1.
undefined reference to XOpenDisplay
, 2.undefined reference to XQueryPointer
. -
perreal almost 12 yearsyou need to compile with X11 lib:
gcc main.c -lX11
. -
rajat almost 12 yearsYup , it worked :) . But the co-ordinates are messed up , the 0,0 point is somewhere in between of the screen.
-
rajat almost 12 yearsI understood the problem , when i go to the corners of the screen the mouse is not able to move but it still keeps on increasing the value of the mmouse co-ordinates . what are the Possible solutions ?
-
perreal almost 12 yearsYou can use XQueryPointer when you need absolute coordinates instead of tracking the pointer.
-
rajat almost 12 yearsHow to differentiate between mouse up and down events , using the low level thing , the code that appear for both mouse down and mouse up is same . if i want to detect the co-ordinates only when the mouse button is pressed , what should i do ?
-
perreal almost 12 years@rajat, added an example for buttons in the code. hope it helps
-
Matical almost 9 yearshow to do this in android?