微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

XCB 如何获取原子的值

如何解决XCB 如何获取原子的值

我正在编写一个小的系统信息(“*fetch”)程序(用 C 语言),我想获得 WM 的名称,唯一的问题是 XCB 的文档相当缺乏,而 Xlib 的文档非常糟糕.所以我无法自己弄清楚。

我知道根窗口的 atom: _NET_SUPPORTING_WM_CHECK 应该有一个 WM 的 ID,WM 应该将它的 _NET_WM_NAME 设置为它的名称。但我什至不知道如何获得它的 id。

我唯一确定的是如何获取根窗口。但其他部分根本就没有任何文档,或者(更有可能)我一直在使用错误搜索词...

解决方法

#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <xcb/xcb.h>

static xcb_intern_atom_cookie_t intern(xcb_connection_t *c,const char *name) {
    return xcb_intern_atom(c,strlen(name),name);
}

int main() {
    // TODO: Any kind of error handling. This is just the happy path.

    xcb_connection_t *c = xcb_connect(NULL,NULL);
    xcb_screen_t *s = xcb_setup_roots_iterator(xcb_get_setup(c)).data;
    xcb_intern_atom_cookie_t wm_name_cookie = intern(c,"_NET_WM_NAME");
    xcb_intern_atom_cookie_t wm_check_cookie = intern(c,"_NET_SUPPORTING_WM_CHECK");
    xcb_intern_atom_reply_t *wm_name = xcb_intern_atom_reply(c,wm_name_cookie,NULL);
    xcb_intern_atom_reply_t *wm_check = xcb_intern_atom_reply(c,wm_check_cookie,NULL);

    xcb_get_property_reply_t *wm_name_value = xcb_get_property_reply(c,xcb_get_property(c,s->root,wm_name->atom,XCB_GET_PROPERTY_TYPE_ANY,~0),NULL);
    xcb_get_property_reply_t *wm_check_value = xcb_get_property_reply(c,wm_check->atom,XCB_ATOM_WINDOW,NULL);

    printf("%.*s\n",xcb_get_property_value_length(wm_name_value),(char*) xcb_get_property_value(wm_name_value));
    printf("0x%"PRIx32"\n",*(xcb_window_t*) xcb_get_property_value(wm_check_value));

    free(wm_name_value);
    free(wm_check_value);
    free(wm_name);
    free(wm_check);

    return 0;
}

为了检查上述情况,这是我与“已知良好”程序进行比较的实验:

$ gcc t.c -O2 -Wall -Wextra -lxcb && ./a.out ; echo ; xprop -root | grep -E '(_NET_WM_NAME|SUPPORTING_WM_CHECK)\('
i3
0x800063

_NET_WM_NAME(UTF8_STRING) = "i3"
_NET_SUPPORTING_WM_CHECK(WINDOW): window id # 0x800063

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。