131 lines
4.0 KiB
C
131 lines
4.0 KiB
C
// x-run: make run
|
|
#include "windowtree.h"
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <xcb/xcb.h>
|
|
#include <xcb/xproto.h>
|
|
|
|
|
|
struct _cookies_container {
|
|
xcb_get_property_cookie_t gp_cookie;
|
|
xcb_get_geometry_cookie_t gg_cookie;
|
|
xcb_get_window_attributes_cookie_t ga_cookie;
|
|
};
|
|
|
|
struct window_info *get_windows_list(xcb_connection_t *conn, size_t *n_windows) {
|
|
xcb_generic_error_t *err;
|
|
|
|
xcb_screen_t *screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data;
|
|
|
|
#if 0
|
|
xcb_query_tree_reply_t *qt_reply;
|
|
xcb_query_tree_cookie_t qt_cookie = xcb_query_tree(conn, screen->root);
|
|
|
|
if (!(qt_reply = xcb_query_tree_reply(conn, qt_cookie, &err))) {
|
|
fprintf(stderr, "xcb: error: xcb_query_tree_reply: %d\n", err->error_code);
|
|
return NULL;
|
|
}
|
|
|
|
xcb_window_t *children = xcb_query_tree_children(qt_reply);
|
|
|
|
*n_windows = xcb_query_tree_children_length(qt_reply);
|
|
struct window_info *windows = calloc(*n_windows, sizeof(struct window_info));
|
|
#else
|
|
xcb_intern_atom_cookie_t ia_cookie = xcb_intern_atom(conn, 1, 16, "_NET_CLIENT_LIST");
|
|
xcb_intern_atom_reply_t *ia_reply = xcb_intern_atom_reply(conn, ia_cookie, &err);
|
|
|
|
enum xcb_atom_enum_t at_list = XCB_ATOM_WINDOW;
|
|
|
|
/*if (!ia_reply) {*/
|
|
/* printf("using _WIN_CLIENT_LIST\n");*/
|
|
/* ia_cookie = xcb_intern_atom(conn, 1, 16, "_WIN_CLIENT_LIST");*/
|
|
/* ia_reply = xcb_intern_atom_reply(conn, ia_cookie, &err);*/
|
|
/* at_list = XCB_ATOM_CARDINAL;*/
|
|
/*}*/
|
|
|
|
if (!ia_reply) {
|
|
fprintf(stderr, "xcb: error: xcb_intern_atom_reply: %d\n", err->error_code);
|
|
return NULL;
|
|
}
|
|
|
|
xcb_get_property_cookie_t gp_client_list_cookie = xcb_get_property(conn, 0, screen->root, ia_reply->atom, at_list, 0, 1024);
|
|
free(ia_reply);
|
|
|
|
xcb_get_property_reply_t *gp_client_list_reply = xcb_get_property_reply(conn, gp_client_list_cookie, &err);
|
|
|
|
if (!gp_client_list_reply) {
|
|
fprintf(stderr, "xcb: error: xcb_get_property_reply: %d\n", err->error_code);
|
|
return NULL;
|
|
}
|
|
|
|
*n_windows = xcb_get_property_value_length(gp_client_list_reply);
|
|
printf("length: %zu\n", *n_windows);
|
|
|
|
struct window_info *windows = calloc(*n_windows, sizeof(struct window_info));
|
|
xcb_window_t *child = (xcb_window_t *)xcb_get_property_value(gp_client_list_reply);
|
|
|
|
for (int i = 0; i < *n_windows; i++) {
|
|
printf("WID 0x%08d\n", child[i]);
|
|
windows[i].wid = child[i];
|
|
}
|
|
|
|
free(gp_client_list_reply);
|
|
|
|
#endif
|
|
|
|
struct _cookies_container *cookies = calloc(*n_windows, sizeof(struct _cookies_container));
|
|
// queueing requests
|
|
for (int i = 0; i < *n_windows; i++) {
|
|
cookies[i].gp_cookie = xcb_get_property(conn, 0, windows[i].wid, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 0, 1023);
|
|
cookies[i].gg_cookie = xcb_get_geometry(conn, windows[i].wid);
|
|
cookies[i].ga_cookie = xcb_get_window_attributes(conn, windows[i].wid);
|
|
}
|
|
|
|
// reading results
|
|
for (int i = 0; i < *n_windows; i++) {
|
|
xcb_get_geometry_reply_t *gg_reply = xcb_get_geometry_reply(conn, cookies[i].gg_cookie, &err);
|
|
if (!gg_reply) {
|
|
fprintf(stderr, "xcb: error: xcb_get_geometry: %d\n", err->error_code);
|
|
goto failure;
|
|
}
|
|
|
|
windows[i].rect.x = gg_reply->x;
|
|
windows[i].rect.y = gg_reply->y;
|
|
windows[i].rect.width = gg_reply->width;
|
|
windows[i].rect.height = gg_reply->height;
|
|
|
|
free(gg_reply);
|
|
|
|
xcb_get_property_reply_t *gp_reply = xcb_get_property_reply(conn, cookies[i].gp_cookie, &err);
|
|
if (!gp_reply) {
|
|
fprintf(stderr, "xcb: error: xcb_get_property: %d\n", err->error_code);
|
|
goto failure;
|
|
}
|
|
|
|
char *gp_value = (char *)xcb_get_property_value(gp_reply);
|
|
|
|
memset(windows[i].title, 0, 1024);
|
|
strncpy(windows[i].title, gp_value, 1023);
|
|
|
|
free(gp_reply);
|
|
|
|
xcb_get_window_attributes_reply_t *ga_reply = xcb_get_window_attributes_reply(conn, cookies[i].ga_cookie, &err);
|
|
if (!gp_reply) {
|
|
fprintf(stderr, "xcb: error: xcb_get_window_attributes: %d\n", err->error_code);
|
|
goto failure;
|
|
}
|
|
|
|
windows[i].win_gravity = ga_reply->win_gravity;
|
|
|
|
free(ga_reply);
|
|
}
|
|
|
|
free(cookies); // yay!
|
|
return windows; // ewww
|
|
|
|
failure:
|
|
free(cookies);
|
|
return NULL;
|
|
}
|