使用GTK +使用gtk_event_put和GdkEventButton结构来模拟按钮单击 [英] Simulate button click using GTK+ using gtk_event_put and a GdkEventButton structure

查看:110
本文介绍了使用GTK +使用gtk_event_put和GdkEventButton结构来模拟按钮单击的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是对我正在尝试创建一个程序,该程序从外部设备获取输入并产生鼠标点击,以使 GTK + 能够像鼠标点击正常发生一样获取并处理事件.

I'm trying to create a program that takes input from an external device and generates mouse clicks so that GTK+ will get and handle the events as if they mouse click happened normally.

似乎我可以使用 GdkEventButton 结构: https://developer.gnome.org/gdk/stable/gdk-Event-Structures.html#GdkEventButton

Seems I can use a GdkEventButton structure: https://developer.gnome.org/gdk/stable/gdk-Event-Structures.html#GdkEventButton

但是我不确定如何确定要为每个字段输入的值.我正在寻找使用 gtk_event_put() GdkEventButton 结构的人的一小段示例代码或建议.

But I'm not sure how to determine the values to enter for each field. I'm looking for a small snippet of sample code or advice from somebody that has used gtk_event_put() with a GdkEventButton structure.

如果有人知道与我的回答不同或更好的方法,请告诉我.

If anybody knows a different or better way than my answer, please let me know.

推荐答案

还有另一种方法,但是我要介绍的这种方法涉及使用纯X11,尽管看到了您问题的标签,即使用X11的答案.也可以接受.

There is another way, but this way I'm going to present, involve the use of pure X11, although seeing your question's tags, an answer that uses X11 is acceptable too.

也就是说,让我首先介绍所有发生的功能,一件事,如果有些其他人不了解如何使用此功能,我将有点冗长.

That said, let me start by introducing the function where all happens, one thing, I'm going to be a bit verbose, in case of some other people that don't understand how use this function.

void
mouse_click(Display *display, int x, int y, int click_type, struct timeval *t);

    先前由 XOpenDisplay()返回的
  • display 结构,其中包含有关X服务器的所有信息.
  • x 指针相对于屏幕根部的x坐标.
  • y 指针相对于屏幕根部的y坐标.
  • click_type 点击的类型.对于此答案, MOUSE_RIGHT_CLICK MOUSE_LEFT_CLICK
  • t timeval 结构,指定了应保持点击的时间间隔.
    • display structure previously returned by XOpenDisplay() that contains all the information about the X server.
    • x the x coordinate of the pointer relative to the root of the screen.
    • y the y coordinate of the pointer relative to the root of the screen.
    • click_type the type of the click. For this answer, either MOUSE_RIGHT_CLICK or MOUSE_LEFT_CLICK
    • t timeval structure, specified the time interval the click should remain pressed.
    • 实施

      #include <stdio.h>
      #include <string.h>
      #include <stdlib.h>
      #include <unistd.h>
      #include <time.h>
      #include <sys/types.h>
      #include <sys/select.h>
      #include <X11/Xlib.h>
      #include <X11/Xutil.h>
      
      #define portable_usleep(t) select(0, NULL, NULL,NULL, t)
      
      enum { MOUSE_RIGHT_CLICK, MOUSE_LEFT_CLICK };
      
      void
      mouse_click(Display *display, int x, int y, int click_type, struct timeval *t)
      {
              Window root;
              XEvent event;
      
              root = DefaultRootWindow(display);
              XWarpPointer(display, None, root, 0, 0, 0, 0, x, y);
      
              memset(&event, 0, sizeof(event));
      
              event.xbutton.type        = ButtonPress;
              event.xbutton.button      = click_type;
              event.xbutton.same_screen = True;
      
              XQueryPointer(display, root, &event.xbutton.root, &event.xbutton.window,
                           &event.xbutton.x_root, &event.xbutton.y_root,
                           &event.xbutton.x, &event.xbutton.y, &event.xbutton.state);
      
              event.xbutton.subwindow = event.xbutton.window;
      
              while(event.xbutton.subwindow) {
                      event.xbutton.window = event.xbutton.subwindow;
                      XQueryPointer(display, event.xbutton.window,&event.xbutton.root,
                      &event.xbutton.subwindow, &event.xbutton.x_root,
                      &event.xbutton.y_root, &event.xbutton.x, &event.xbutton.y,
                      &event.xbutton.state);
              }
      
              if(XSendEvent(display, PointerWindow, True, 0xfff, &event)==0)
                      fprintf(stderr, "XSendEvent()\n");
      
              XFlush(display);
              portable_usleep(t); /* keeps the click pressed */
      
              event.type = ButtonRelease;
              event.xbutton.state = 0x100;
      
              if(XSendEvent(display, PointerWindow, True, 0xfff, &event)==0)
                      fprintf(stderr, "XSendEvent()\n");
      
              XFlush(display);
      }
      

      好吧,此功能非常简单,例如,在500,645位置处左键单击半秒钟,这是这样的:

      Well, this function it's pretty straight forward, for example, left click at position 500,645 button pressed for half a second, this is how:

      int
      main(void)
      {
              int x;
              int y;
              Display        *display;
              struct timeval t;
      
              display = XOpenDisplay(NULL);
      
              if(!display) {
                      fprintf(stderr, "Can't open display!\n");
                      exit(EXIT_FAILURE);
              }
      
              x = 500;
              y = 645;
      
              t.tv_sec  = 0;
              t.tv_usec = 500000;  /* 0.5 secs */
      
              mouse_click(display, x, y, MOUSE_LEFT_CLICK, &t);
      
              XCloseDisplay(display);
              return 0;
      }
      

      编译

      $ gcc -o click click.c -lX11
      

      这篇关于使用GTK +使用gtk_event_put和GdkEventButton结构来模拟按钮单击的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆