master ohmu/wmutils / src / core / wattr.c
ohmu  ·  2026-07-25
  1/* See LICENSE file for copyright and license details. */
  2
  3#include <stdio.h>
  4#include <stdlib.h>
  5#include <string.h>
  6#include <err.h>
  7#include <xcb/xcb.h>
  8#include <xcb/xcb_aux.h>
  9
 10#include "util.h"
 11
 12static xcb_connection_t *conn;
 13
 14static void usage(char *);
 15static int get_attribute(xcb_window_t, int);
 16
 17enum {
 18	ATTR_W = 1 << 0,
 19	ATTR_H = 1 << 1,
 20	ATTR_X = 1 << 2,
 21	ATTR_Y = 1 << 3,
 22	ATTR_B = 1 << 4,
 23	ATTR_M = 1 << 5,
 24	ATTR_I = 1 << 6,
 25	ATTR_MAX
 26};
 27
 28static void
 29usage(char *name)
 30{
 31	fprintf(stderr, "usage: %s [-h] [bmiowhxy] <wid>\n", name);
 32	exit(1);
 33}
 34
 35static int
 36get_attribute(xcb_window_t w, int attr)
 37{
 38	xcb_get_geometry_cookie_t c;
 39	xcb_get_geometry_reply_t *r;
 40
 41	c = xcb_get_geometry(conn, w);
 42	r = xcb_get_geometry_reply(conn, c, NULL);
 43
 44	if (r == NULL)
 45		errx(1, "0x%08x: no such window", w);
 46
 47	switch (attr) {
 48		case ATTR_X: attr = r->x; break;
 49		case ATTR_Y: attr = r->y; break;
 50		case ATTR_W: attr = r->width; break;
 51		case ATTR_H: attr = r->height; break;
 52		case ATTR_B: attr = r->border_width; break;
 53	}
 54
 55	free(r);
 56	return attr;
 57}
 58
 59int
 60main(int argc, char **argv)
 61{
 62	int c, ret = 0;
 63	size_t i;
 64	xcb_window_t w = 0;
 65
 66	if (argc < 2 || (strncmp(argv[1], "-h", 2) == 0)) {
 67		usage(argv[0]);
 68	}
 69
 70	init_xcb(&conn);
 71
 72	if (argc == 2) {
 73		w = strtoul(argv[1], NULL, 16);
 74		ret = exists(conn, w) ? 0 : 1;
 75		goto end;
 76	}
 77
 78	for (c=2; argv[c]; c++) {
 79		w = strtoul(argv[c], NULL, 16);
 80
 81		for (i=0; i<strlen(argv[1]); i++) {
 82			switch (argv[1][i]) {
 83				case 'i':
 84					printf("0x%08x", w);
 85					break;
 86				case 'b':
 87					printf("%d", get_attribute(w, ATTR_B));
 88					break;
 89				case 'h': 
 90					printf("%d", get_attribute(w, ATTR_H));
 91					break;
 92				case 'x':
 93					printf("%d", get_attribute(w, ATTR_X));
 94					break;
 95				case 'y':
 96					printf("%d", get_attribute(w, ATTR_Y));
 97					break;
 98				case 'w':
 99					printf("%d", get_attribute(w, ATTR_W));
100					break;
101				case 'o':
102					ret = ignore(conn, w) ? 0 : 1;
103					goto end;
104				case 'm':
105					ret = mapped(conn, w) ? 0 : 1;
106					goto end;
107				default: kill_xcb(&conn); usage(argv[0]);
108			}
109			/* add a space if more attribute come after */
110			putc(i+1 < strlen(argv[1]) ? ' ' : '\n',stdout);
111		}
112	}
113
114end:
115	kill_xcb(&conn);
116
117	return ret;
118}