How to read low level mouse click position in linux .

17,153

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.

Share:
17,153

Related videos on Youtube

rajat
Author by

rajat

Updated on July 14, 2022

Comments

  • rajat
    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
    rajat almost 12 years
    Hi ,The code seems very elegant .Thanks . But it is giving me following errors :1. undefined reference to XOpenDisplay , 2. undefined reference to XQueryPointer .
  • perreal
    perreal almost 12 years
    you need to compile with X11 lib: gcc main.c -lX11.
  • rajat
    rajat almost 12 years
    Yup , it worked :) . But the co-ordinates are messed up , the 0,0 point is somewhere in between of the screen.
  • rajat
    rajat almost 12 years
    I 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
    perreal almost 12 years
    You can use XQueryPointer when you need absolute coordinates instead of tracking the pointer.
  • rajat
    rajat almost 12 years
    How 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
    perreal almost 12 years
    @rajat, added an example for buttons in the code. hope it helps
  • Matical
    Matical almost 9 years
    how to do this in android?