diff --git a/img/scrall/Makefile b/img/scrall/Makefile index a798906..c641093 100644 --- a/img/scrall/Makefile +++ b/img/scrall/Makefile @@ -1,16 +1,20 @@ -CFLAGS += -Wall -Wextra `exec pkg-config --cflags raylib xcb xcb-composite` +CFLAGS += -Wall -Wextra -Wpedantic -Werror `exec pkg-config --cflags raylib xcb xcb-composite` LDFLAGS := -lm `pkg-config --libs raylib xcb xcb-composite` OBJECTS = ./screenshot.o ./windowtree.o -scrall: main.c $(OBJECTS) +scrall: $(OBJECTS) main.c $(CC) $(CFLAGS) main.c $(LDFLAGS) -o scrall $(OBJECTS) %.o: %.c $(CC) $(CFLAGS) -c $^ -o $@ clean: - $(RM) scrall + $(RM) scrall $(OBJECTS) + +debug: + make CFLAGS+=-ggdb + gdb ./scrall run: scrall ./scrall diff --git a/img/scrall/main.c b/img/scrall/main.c index 420d1bc..d2fc472 100644 --- a/img/scrall/main.c +++ b/img/scrall/main.c @@ -1,6 +1,7 @@ // x-run: make run #include #include +#include #include #include #include "screenshot.h" @@ -19,20 +20,30 @@ int main(int argc, char **argv) { size_t n_windows; struct window_info *windows = get_windows_list(xcb, &n_windows); - for (int i = 0; i < n_windows; i++) { - printf("0x%08x %02x %s\n", windows[i].wid, windows[i].win_gravity, windows[i].title); - } - xcb_disconnect(xcb); - return 0; - - SetConfigFlags(FLAG_WINDOW_TRANSPARENT); + SetConfigFlags(FLAG_WINDOW_TRANSPARENT | FLAG_WINDOW_RESIZABLE); InitWindow(0, 0, "img/scrall"); + Font font = LoadFontEx("/usr/share/fonts/Unifont/Unifont.ttf", 16, 0, 1024); + while (!WindowShouldClose()) { BeginDrawing(); - ClearBackground(BLANK); + ClearBackground(Fade(BLACK, 0.9)); + + for (size_t i = 0; i < n_windows; i++) { + DrawTextEx(font, + TextFormat("0x%08x %dx%d+%d+%d %s\n", + windows[i].wid, + windows[i].rect.width, + windows[i].rect.height, + windows[i].rect.x, + windows[i].rect.y, + windows[i].title), + (Vector2) { 8, 8 + 18 * i }, 16, 0, WHITE); + } EndDrawing(); } + + UnloadFont(font); } diff --git a/img/scrall/windowtree.c b/img/scrall/windowtree.c index 2c7ba6f..3d53f6e 100644 --- a/img/scrall/windowtree.c +++ b/img/scrall/windowtree.c @@ -6,51 +6,20 @@ #include #include - -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_cookie_t gp_client_list_cookie = xcb_get_property(conn, 0, screen->root, ia_reply->atom, XCB_ATOM_WINDOW, 0, (uint32_t)~0UL); xcb_get_property_reply_t *gp_client_list_reply = xcb_get_property_reply(conn, gp_client_list_cookie, &err); @@ -59,35 +28,51 @@ struct window_info *get_windows_list(xcb_connection_t *conn, size_t *n_windows) return NULL; } - *n_windows = xcb_get_property_value_length(gp_client_list_reply); - printf("length: %zu\n", *n_windows); + *n_windows = xcb_get_property_value_length(gp_client_list_reply) / sizeof(xcb_window_t); 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); + xcb_window_t *child = xcb_get_property_value(gp_client_list_reply); - for (int i = 0; i < *n_windows; i++) { - printf("WID 0x%08d\n", child[i]); + for (size_t i = 0; i < *n_windows; i++) { windows[i].wid = child[i]; } + free(ia_reply); free(gp_client_list_reply); -#endif + // Get atom: UTF8_STRING {{{ + ia_cookie = xcb_intern_atom(conn, 1, 11, "UTF8_STRING"); + ia_reply = xcb_intern_atom_reply(conn, ia_cookie, &err); - 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); + if (!ia_reply) { + fprintf(stderr, "xcb: error: xcb_intern_atom(UTF8_STRING): %d\n", err->error_code); + return NULL; } - // 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); + xcb_atom_t atom_utf8_string = ia_reply->atom; + free(ia_reply); + // }}} + + // Get atom: _NET_WM_NAME {{{ + ia_cookie = xcb_intern_atom(conn, 1, 12, "_NET_WM_NAME"); + ia_reply = xcb_intern_atom_reply(conn, ia_cookie, &err); + + if (!ia_reply) { + fprintf(stderr, "xcb: error: xcb_intern_atom(_NET_WM_NAME): %d\n", err->error_code); + return NULL; + } + + xcb_atom_t atom_net_wm_name = ia_reply->atom; + free(ia_reply); + // }}} + + for (size_t i = 0; i < *n_windows; i++) { + // Getting geometry {{{ + xcb_get_geometry_cookie_t gg_cookie = xcb_get_geometry(conn, windows[i].wid); + xcb_get_geometry_reply_t *gg_reply = xcb_get_geometry_reply(conn, gg_cookie, &err); if (!gg_reply) { fprintf(stderr, "xcb: error: xcb_get_geometry: %d\n", err->error_code); - goto failure; + return NULL; } windows[i].rect.x = gg_reply->x; @@ -96,11 +81,28 @@ struct window_info *get_windows_list(xcb_connection_t *conn, size_t *n_windows) 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); + // Translating geometry {{{ + xcb_translate_coordinates_cookie_t tc_cookie = xcb_translate_coordinates(conn, windows[i].wid, screen->root, windows[i].rect.x, windows[i].rect.y); + xcb_translate_coordinates_reply_t *tc_reply = xcb_translate_coordinates_reply(conn, tc_cookie, &err); + if (!tc_reply) { + fprintf(stderr, "xcb: error: xcb_translate_coordinates: %d\n", err->error_code); + return NULL; + } + + windows[i].rect.x = tc_reply->dst_x; + windows[i].rect.y = tc_reply->dst_y; + + free(tc_reply); + // }}} + + // Getting name: {{{ + xcb_get_property_cookie_t gp_cookie = xcb_get_property(conn, 0, windows[i].wid, atom_net_wm_name, atom_utf8_string, 0, 1024); + xcb_get_property_reply_t *gp_reply = xcb_get_property_reply(conn, gp_cookie, &err); if (!gp_reply) { fprintf(stderr, "xcb: error: xcb_get_property: %d\n", err->error_code); - goto failure; + return NULL; } char *gp_value = (char *)xcb_get_property_value(gp_reply); @@ -109,22 +111,9 @@ struct window_info *get_windows_list(xcb_connection_t *conn, size_t *n_windows) 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; } diff --git a/img/scrall/windowtree.h b/img/scrall/windowtree.h index b422763..a4cc298 100644 --- a/img/scrall/windowtree.h +++ b/img/scrall/windowtree.h @@ -11,7 +11,6 @@ struct window_info { xcb_window_t wid; xcb_rectangle_t rect; char title[1024]; - uint8_t win_gravity; }; struct window_info *get_windows_list(xcb_connection_t *conn, size_t *n_windows);