这是How to insert synthetic mouse events into X11 input queue
的后续行动我正在尝试创建一个程序,该程序从外部设备获取输入并生成鼠标单击,以便GTK+
获取并处理事件,就像鼠标点击正常发生一样。
似乎我可以使用GdkEventButton
结构:
https://developer.gnome.org/gdk/stable/gdk-Event-Structures.html#GdkEventButton
但我不确定如何确定每个字段输入的值。我正在寻找一小段示例代码或来自使用gtk_event_put()
结构GdkEventButton
的人的建议。
编辑:如果有人知道的方式与我的答案不同或更好,请告诉我。
答案 0 :(得分:6)
还有另外一种方式,但是这种方式我将要介绍,涉及使用纯X11,虽然看到你的问题的标签,使用X11的答案也是可以接受的。
那就是说,让我首先介绍所有发生的功能,有一件事,我会有点冗长,以防其他一些人不明白如何使用这个功能。
void
mouse_click(Display *display, int x, int y, int click_type, struct timeval *t);
XOpenDisplay()
返回的结构,其中包含有关X服务器的所有信息。MOUSE_RIGHT_CLICK
或MOUSE_LEFT_CLICK
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);
}
嗯,这个功能很直接,例如,左键点击位置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;
}
编译
$ gcc -o click click.c -lX11
答案 1 :(得分:4)
经过一些研究后,我得知GTK+/GDK
2.14和更新版本有一些功能可以为GTK+
应用程序创建自动化测试套件。
我可以使用gdk_test_simulate_button来模拟鼠标点击。 可能不是最佳解决方案,但现在它似乎运作良好。