使用gtk_event_put和GdkEventButton结构使用GTK +模拟按钮单击

Chi*_*era 9 c x11 gtk

这是如何将合成鼠标事件插入X11输入队列的后续内容

我正在尝试创建一个程序,从外部设备获取输入并生成鼠标单击,以便GTK+获取和处理事件,就好像鼠标单击正常发生一样.

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

但我不确定如何确定每个字段输入的值.我正在寻找从别人的示例代码或咨询一个小片段,使用了gtk_event_put()具有GdkEventButton结构.

编辑:如果有人知道与我的答案不同或更好的方式,请告诉我.

yey*_*eyo 6

还有另外一种方法,但这种方式我将要介绍,涉及使用纯X11,虽然看到你的问题的标签,使用X11的答案也是可以接受的.

也就是说,让我首先介绍所有发生的功能,有一件事,我会有点冗长,以防其他一些人不明白如何使用这个功能.


void
mouse_click(Display *display, int x, int y, int click_type, struct timeval *t);
Run Code Online (Sandbox Code Playgroud)
  • 之前返回的显示结构XOpenDisplay()包含有关X服务器的所有信息.
  • x指针相对于屏幕根的x坐标.
  • y指针相对于屏幕根的y坐标.
  • click_type点击的类型.对于这个答案,无论是MOUSE_RIGHT_CLICKMOUSE_LEFT_CLICK
  • t timeval结构,指定点击应保持按下的时间间隔.

履行

#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);
}
Run Code Online (Sandbox Code Playgroud)

好吧,这个功能很直接,例如,左键点击位置500,645按钮按下半秒钟,这是如何:

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;
}
Run Code Online (Sandbox Code Playgroud)

$ gcc -o click click.c -lX11
Run Code Online (Sandbox Code Playgroud)