2

I am able to grab the mouse, but my problem is that the mouse events that happen while the mouse is grabbed are just queued, and happen after I release the mouse.

this is the code I have until now:

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <stdio.h>

int main(int argc, char const *argv[])
{
    XEvent e;

    Display* dispaly = XOpenDisplay(NULL);
    Window window = XDefaultRootWindow(dispaly);

    unsigned int count = 0;
    XGrabPointer(dispaly, window, true, PointerMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeSync, GrabModeAsync, None, None, CurrentTime);

    while(count < 500000) {
        if (XPending(dispaly))
            XNextEvent(dispaly, &e);

        count++;
        printf("%d\n", count);
    }


    XFlush(dispaly);

    XCloseDisplay(dispaly);

    scanf("%d", &count);

    printf("end\n");

    return 0;
}

as you can see, I tried consuming the all the events in numerous ways, like with XPending and XNextEvent, with XFlush, and also with XSync. No matter what function I tried, all the mouse events I do while the mouse is grabbed just happen after I close the display.

can someone help?

itayrabin
  • 398
  • 1
  • 2
  • 12

2 Answers2

1

Create window:

#include <stdio.h>
#include <unistd.h>

#include <X11/X.h>
#include <X11/Xlib.h>

int main()
{
  Display* disp     = XOpenDisplay(NULL);
  Window   root     = XDefaultRootWindow(disp);
  int      scr      = XDefaultScreen(disp);
  GC       context  = XDefaultGC(disp, scr);
  ulong fg          = BlackPixel(disp, scr);  // fg color
  ulong bg          = WhitePixel(disp, scr);  // bg color
  int depth         = 1;
  Window win        = XCreateSimpleWindow(disp, root, 0, 0, 50, 50, depth, fg, bg);

  long events = 
    ExposureMask |
    ButtonPressMask | 
    ButtonReleaseMask | 
    PointerMotionMask;

  XSelectInput(disp, win, events);
  XMapWindow(disp, win);
  XFlush(disp);

  unsigned int masks = PointerMotionMask | ButtonPressMask | ButtonReleaseMask;
  XGrabPointer(
    disp, win, true, masks, GrabModeSync, GrabModeAsync, None, None, CurrentTime
  );

Catch pointer events:

  XEvent event;

  do { 
    XNextEvent(disp, &event);
    switch (event.type) {
      case ButtonPress    :
        printf("pressed  %i\n", event.xbutton.button);
        break;
      case ButtonRelease  :
        printf("released %i\n", event.xbutton.button);
        break;
      case MotionNotify   :
        printf("move x %i y %i\n", event.xmotion.x, event.xmotion.y);
        break;
      default : break;
    }
    usleep(1000);    

  } while (true);

  XCloseDisplay(disp);
  return 0;
}

Or if you need to capture all events inside the root window, you may use XQueryPointer instead of XNextEvent:

...
Window root_ret;
Window child_ret;
int x_rel, y_rel;
int x_win, y_win;
unsigned int mask;

do {

  XQueryPointer(
    disp, root,
    &root_ret, &child_ret,
    &x_rel, &y_rel, &x_win, &y_win,
    &mask);
  printf("%d %d\n", x_rel, y_rel);
  usleep(1000);
) while (true);
...

Information above would be a good start point to yours researches.

Ans
  • 527
  • 5
  • 9
  • I am trying to capture events on the entire screen. When I change your code to use root instead of window, it doesn't work. Can you help? – itayrabin Jan 15 '18 at 09:17
  • Querying the pointer in an infinite loop like this is a good way to use 100% CPU and turn your machine into an oven. If you want to track pointer events without blocking them the best way to go is the Xinput extension and raw events. – Ingo Bürk Jan 16 '18 at 08:38
  • 1
    I see no reason to reduce the response score only due to minor typos. This is not respectful of other people. If you have right answer - let`s see. – Ans Jan 16 '18 at 12:13
  • If a context menu is open (typically after a rigth click) XGrabPointer() returns AlreadyGrabbed and I have no idea how recover the possiblitiy of grab the mouse. Can you give me any tip? – ezain Jun 21 '19 at 11:00
1

If you log out these two lines of code, you can also get mouse events.

unsigned int masks = PointerMotionMask | ButtonPressMask | ButtonReleaseMask;
XGrabPointer(disp, win, 1, masks, GrabModeSync, GrabModeAsync, None, None, CurrentTime);
Anuraag Baishya
  • 874
  • 2
  • 11
  • 26
allen
  • 11
  • 1