如何在Linux中读取鼠标的低级点击位置。

14

我正在使用这段代码在Linux中读取/dev/input/event*中的鼠标事件。

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

它以以下格式给出结果:

time 1342517261.840285 type 2 code 0 value -1

'time'是时间戳,返回事件发生的时间。

'code'是事件代码,例如REL_X或KEY_BACKSPACE,在include/linux/input.h中完整列表。

'value'是事件携带的值。对于EV_REL,它是相对变化量;对于EV_ABS(如操纵杆),它是绝对新值;对于EV_KEY,它为0表示释放,1表示按下,2表示自动重复。

当我点击时,我可以获得事件,但无法获得鼠标在屏幕上的位置,有什么方法可以获取鼠标在屏幕上的位置。


编辑1:事实证明我必须使用相对坐标来获得鼠标坐标。我认为这是一个常见的需求,因此可能有库/现有代码可用于获取坐标。任何关于此主题的信息都将非常有用。


编辑2:解决方案

#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看起来是更方便的解决方案。 感谢@perreal的指导。

2个回答

10

您可以从X11获取初始位置,并使用相对坐标来跟踪指针:

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

你需要使用X11库进行编译: gcc main.c -lX11 - perreal
是的,它起作用了 :) 但是坐标有问题,0,0点在屏幕中间某处。 - rajat
当您需要绝对坐标而不是跟踪指针时,可以使用XQueryPointer。 - perreal
1
@rajat,代码中添加了按钮的示例。希望能有所帮助。 - perreal
如何在Android中实现这个? - Matical
显示剩余3条评论

0
鼠标只发送相对移动,而不是绝对位置。您必须自己跟踪它,并在接收到鼠标按钮事件时检查自己的坐标以获取位置。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接