]>
Dogcows Code - chaz/openbox/blob - tools/obprop/obprop.c
2 #include <X11/cursorfont.h>
9 gint
fail(const gchar
*s
) {
11 fprintf(stderr
, "%s\n", s
);
15 "Usage: obprop [OPTIONS]\n\n"
17 " --help Display this help and exit\n"
18 " --display DISPLAY Connect to this X display\n"
19 " --id ID Show the properties for this window\n");
23 gint
parse_hex(gchar
*s
) {
27 if (*s
>= '0' && *s
<='9')
29 else if (*s
>= 'A' && *s
<='F')
31 else if (*s
>= 'a' && *s
<='f')
42 Window
find_client(Display
*d
, Window win
)
46 Atom state
= XInternAtom(d
, "WM_STATE", True
);
49 gulong ret_items
, ret_bytesleft
, *xdata
;
51 XQueryTree(d
, win
, &r
, &r
, &children
, &n
);
52 for (i
= 0; i
< n
; ++i
) {
53 Window w
= find_client(d
, children
[i
]);
58 res
= XGetWindowProperty(d
, win
, state
, 0, 1,
59 False
, state
, &ret_type
, &ret_format
,
60 &ret_items
, &ret_bytesleft
,
61 (unsigned char**) &xdata
);
63 if (res
!= Success
|| ret_type
== None
|| ret_items
< 1)
65 return win
; // found it!
68 static gboolean
get_all(Display
*d
, Window win
, Atom prop
,
69 Atom
*type
, gint
*size
,
70 guchar
**data
, guint
*num
)
75 gulong ret_items
, bytes_left
;
77 res
= XGetWindowProperty(d
, win
, prop
, 0l, G_MAXLONG
,
78 FALSE
, AnyPropertyType
, type
, size
,
79 &ret_items
, &bytes_left
, &xdata
);
84 *data
= g_malloc(ret_items
* (*size
/ 8));
85 for (i
= 0; i
< ret_items
; ++i
)
88 (*data
)[i
] = xdata
[i
];
91 ((guint16
*)*data
)[i
] = ((gushort
*)xdata
)[i
];
94 ((guint32
*)*data
)[i
] = ((gulong
*)xdata
)[i
];
97 g_assert_not_reached(); /* unhandled size */
107 gchar
*append_string(gchar
*before
, gchar
*after
, gboolean quote
)
110 const gchar
*q
= quote
? "\"" : "";
112 tmp
= g_strdup_printf("%s, %s%s%s", before
, q
, after
, q
);
114 tmp
= g_strdup_printf("%s%s%s", q
, after
, q
);
119 gchar
*append_int(gchar
*before
, guint after
)
123 tmp
= g_strdup_printf("%s, %u", before
, after
);
125 tmp
= g_strdup_printf("%u", after
);
130 gchar
* read_strings(gchar
*val
, guint n
, gboolean utf8
)
132 GSList
*strs
= NULL
, *it
;
137 while (p
< val
+ n
) {
138 strs
= g_slist_append(strs
, g_strndup(p
, n
- (p
- val
)));
139 p
+= strlen(p
) + 1; /* next string */
143 for (i
= 0, it
= strs
; it
; ++i
, it
= g_slist_next(it
)) {
147 if (g_utf8_validate(it
->data
, -1, NULL
))
148 data
= g_strdup(it
->data
);
153 data
= g_locale_to_utf8(it
->data
, -1, NULL
, NULL
, NULL
);
155 ret
= append_string(ret
, data
, TRUE
);
161 strs
= g_slist_delete_link(strs
, strs
);
166 gchar
* read_atoms(Display
*d
, guchar
*val
, guint n
)
172 for (i
= 0; i
< n
; ++i
)
173 ret
= append_string(ret
, XGetAtomName(d
, ((guint32
*)val
)[i
]), FALSE
);
177 gchar
* read_numbers(guchar
*val
, guint n
, guint size
)
183 for (i
= 0; i
< n
; ++i
)
186 ret
= append_int(ret
, ((guint8
*)val
)[i
]);
189 ret
= append_int(ret
, ((guint16
*)val
)[i
]);
192 ret
= append_int(ret
, ((guint32
*)val
)[i
]);
195 g_assert_not_reached(); /* unhandled size */
201 gboolean
read_prop(Display
*d
, Window w
, Atom prop
, const gchar
**type
, gchar
**val
)
209 if (get_all(d
, w
, prop
, &ret_type
, &size
, &ret
, &nret
)) {
210 *type
= XGetAtomName(d
, ret_type
);
212 if (strcmp(*type
, "STRING") == 0)
213 *val
= read_strings((gchar
*)ret
, nret
, FALSE
);
214 else if (strcmp(*type
, "UTF8_STRING") == 0)
215 *val
= read_strings((gchar
*)ret
, nret
, TRUE
);
216 else if (strcmp(*type
, "ATOM") == 0) {
217 g_assert(size
== 32);
218 *val
= read_atoms(d
, ret
, nret
);
221 *val
= read_numbers(ret
, nret
, size
);
229 void show_properties(Display
*d
, Window w
)
234 props
= XListProperties(d
, w
, &n
);
236 for (i
= 0; i
< n
; ++i
) {
240 name
= XGetAtomName(d
, props
[i
]);
242 if (read_prop(d
, w
, props
[i
], &type
, &val
)) {
243 g_print("%s(%s) = %s\n", name
, type
, val
);
253 int main(int argc
, char **argv
)
256 Window id
, userid
= None
;
260 for (i
= 1; i
< argc
; ++i
) {
261 if (!strcmp(argv
[i
], "--help")) {
264 else if (!strcmp(argv
[i
], "--id")) {
267 if (argv
[i
][0] == '0' && argv
[i
][1] == 'x') {
269 userid
= parse_hex(argv
[i
]+2);
273 userid
= atoi(argv
[i
]);
277 else if (!strcmp(argv
[i
], "--display")) {
284 d
= XOpenDisplay(dname
);
286 return fail("Unable to find an X display. "
287 "Ensure you have permission to connect to the display.");
290 if (userid
== None
) {
291 i
= XGrabPointer(d
, RootWindow(d
, DefaultScreen(d
)),
292 False
, ButtonPressMask
,
293 GrabModeAsync
, GrabModeAsync
,
294 None
, XCreateFontCursor(d
, XC_crosshair
),
296 if (i
!= GrabSuccess
)
297 return fail("Unable to grab the pointer device");
302 if (ev
.type
== ButtonPress
) {
303 XUngrabPointer(d
, CurrentTime
);
304 userid
= ev
.xbutton
.subwindow
;
310 id
= find_client(d
, userid
);
313 return fail("Unable to find window with the requested ID");
315 show_properties(d
, id
);
This page took 0.05263 seconds and 4 git commands to generate.