2

我能够抓住鼠标,但我的问题是在抓住鼠标时发生的鼠标事件只是排队,并且在我释放鼠标后发生。

这是我到目前为止的代码:

#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;
}

如您所见,我尝试以多种方式使用所有事件,例如使用 XPending 和 XNextEvent、使用 XFlush 以及使用 XSync。无论我尝试什么功能,我在鼠标被抓住时所做的所有鼠标事件都发生在我关闭显示器之后。

有人可以帮忙吗?

4

2 回答 2

1

创建窗口:

#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
  );

捕获指针事件:

  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;
}

或者,如果您需要捕获窗口内的所有事件,您可以使用XQueryPointer代替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);
...

以上信息将是您研究的良好起点。

于 2018-01-11T11:45:50.067 回答
1

如果你注销这两行代码,你也可以得到鼠标事件。

unsigned int masks = PointerMotionMask | ButtonPressMask | ButtonReleaseMask;
XGrabPointer(disp, win, 1, masks, GrabModeSync, GrabModeAsync, None, None, CurrentTime);
于 2018-03-22T11:10:39.767 回答