gpt4 book ai didi

c - 如何在 g_main_loop_new 中添加 Xorg 事件处理

转载 作者:太空狗 更新时间:2023-10-29 15:04:40 46 4
gpt4 key购买 nike

我有a lightweight application捕获 Xorg 和 dbus 事件。为此,我初始化了 dbus 循环并启动了 g_main_loop,但我不知道如何以自然的方式添加 Xorg 事件处理:

GMainLoop * mainloop = NULL;
mainloop = g_main_loop_new(NULL,FALSE);
dbus_g_thread_init ();
dbus_init();
// <<<<<<<<<<<<<<<<<<<<<<<<<
//1 way using timeout
//g_timeout_add(100, kbdd_default_iter, mainloop);
//2nd way using pthread
//GThread * t = g_thread_create(kbdd_default_loop, NULL, FALSE, NULL);
//>>>>>>>>>>>>>>>>>>>>>>>>>>>
g_main_loop_run(mainloop);

在默认 iter 中,我检查是否有等待的 X 事件并处理它们。

这两种方式都不好,首先是因为我有不必要的检查事件调用,其次是因为我创建了一个额外的线程并且必须进行额外的锁定。

附言我知道我可以使用 gtk lib,但我不想依赖任何工具包。

最佳答案

如果您想在不使用超时的情况下将 Xorg 事件处理添加到主循环(正如您所说的那样是浪费),您需要添加一个轮询 X 连接的源。为此,您需要进入 Xlib 抽象层以下以获取底层 X 连接文件描述符。这就是下面的完整程序所做的。它是 C. Tronche's excellent X11 tutorial 的改编版使用 glib 主循环进行轮询。我还借鉴了 Andrew Krause 的“Foundations of GTK+ Development”。

如果这看起来不是很“自然”,那是因为我怀疑是否有一种非常“自然”的方式来做到这一点——您实际上是在重新实现 GDK 的核心部分。

/* needed to break into 'Display' struct internals. */
#define XLIB_ILLEGAL_ACCESS

#include <X11/Xlib.h> // Every Xlib program must include this
#include <assert.h> // I include this to test return values the lazy way
#include <glib.h>

typedef struct _x11_source {
GSource source;
Display *dpy;
Window w;
} x11_source_t;

static gboolean
x11_fd_prepare(GSource *source,
gint *timeout)
{
*timeout = -1;
return FALSE;
}

static gboolean
x11_fd_check (GSource *source)
{
return TRUE;
}

static gboolean
x11_fd_dispatch(GSource* source, GSourceFunc callback, gpointer user_data)
{
static gint counter = 0;

Display *dpy = ((x11_source_t*)source)->dpy;
Window window = ((x11_source_t*)source)->w;

XEvent e;

while (XCheckWindowEvent(dpy,
window,
EnterWindowMask,
&e))
{
if (e.type == EnterNotify)
g_print("We're in!!! (%d)\n", ++counter);
}

return TRUE;
}

static gboolean
msg_beacon(gpointer data)
{
static gint counter = 0;
g_print("Beacon %d\n", ++counter);
return TRUE;
}

int
main()
{
Display *dpy = XOpenDisplay(NULL);
assert(dpy);

int blackColor = BlackPixel(dpy, DefaultScreen(dpy));
int whiteColor = WhitePixel(dpy, DefaultScreen(dpy));

Window w = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0,
200, 100, 0, blackColor, blackColor);

XSelectInput(dpy, w, StructureNotifyMask | EnterWindowMask);
XMapWindow(dpy, w);

for (;;) {
XEvent e;
XNextEvent(dpy, &e);
if (e.type == MapNotify)
break;
}

GMainLoop *mainloop = NULL;
mainloop = g_main_loop_new(NULL, FALSE);

/* beacon to demonstrate we're not blocked. */
g_timeout_add(300, msg_beacon, mainloop);

GPollFD dpy_pollfd = {dpy->fd,
G_IO_IN | G_IO_HUP | G_IO_ERR,
0};

GSourceFuncs x11_source_funcs = {
x11_fd_prepare,
x11_fd_check,
x11_fd_dispatch,
NULL, /* finalize */
NULL, /* closure_callback */
NULL /* closure_marshal */
};

GSource *x11_source =
g_source_new(&x11_source_funcs, sizeof(x11_source_t));
((x11_source_t*)x11_source)->dpy = dpy;
((x11_source_t*)x11_source)->w = w;
g_source_add_poll(x11_source, &dpy_pollfd);
g_source_attach(x11_source, NULL);

g_main_loop_run(mainloop);

return 0;

}

关于c - 如何在 g_main_loop_new 中添加 Xorg 事件处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8862004/

46 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com