master ohmu/wmutils / src / core / pdw.c
ohmu  ·  2026-07-25
 1/* See LICENSE file for copyright and license details. */
 2
 3#include <err.h>
 4#include <stdio.h>
 5#include <stdlib.h>
 6#include <string.h>
 7#include <xcb/xcb.h>
 8#include <xcb/xcb_aux.h>
 9
10#include "util.h"
11
12static xcb_connection_t *conn;
13static xcb_screen_t *scrn;
14
15static void usage(char *);
16static xcb_window_t focus_window(void);
17static xcb_window_t parent(xcb_window_t);
18
19static void
20usage(char *name)
21{
22	fprintf(stderr, "usage: %s [wid]\n", name);
23	exit(1);
24}
25
26static xcb_window_t
27focus_window(void)
28{
29	xcb_window_t w = 0;
30	xcb_get_input_focus_cookie_t c;
31	xcb_get_input_focus_reply_t *r;
32
33	c = xcb_get_input_focus(conn);
34	r = xcb_get_input_focus_reply(conn, c, NULL);
35	if (r == NULL)
36		errx(1, "xcb_get_input_focus");
37
38	w = r->focus;
39	free(r);
40
41	if (w == XCB_NONE || w == XCB_INPUT_FOCUS_POINTER_ROOT)
42		errx(1, "focus not set");
43
44	return w;
45}
46
47static xcb_window_t
48parent(xcb_window_t w)
49{
50	xcb_query_tree_cookie_t c;
51	xcb_query_tree_reply_t *r;
52
53	c = xcb_query_tree(conn, w);
54	r = xcb_query_tree_reply(conn, c, NULL);
55	if (r == NULL)
56		errx(1, "failed to get parent");
57
58	w = (!r->parent || r->parent == scrn->root) ? w : parent(r->parent);
59	free(r);
60
61	return w;
62}
63
64int
65main(int argc, char **argv)
66{
67	xcb_window_t w;
68
69	if (argc > 2 || (argc > 1 && (!strncmp(argv[1], "-h", 2))))
70		usage(argv[0]);
71
72	init_xcb(&conn);
73	get_screen(conn, &scrn);
74
75	w = (argc > 1) ? strtoul(argv[1], NULL, 16) : focus_window();
76
77	printf("0x%08x\n", parent(w));
78
79	kill_xcb(&conn);
80	return 0;
81}