[PATCH:xwininfo 2/2] Add some EWMH hints to the -wm output

Alan Coopersmith alan.coopersmith at oracle.com
Tue Jun 29 23:04:34 PDT 2010


Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
---
 xwininfo.c |  199 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 194 insertions(+), 5 deletions(-)

diff --git a/xwininfo.c b/xwininfo.c
index 2c6221c..aba5890 100644
--- a/xwininfo.c
+++ b/xwininfo.c
@@ -78,6 +78,7 @@ of the copyright holder.
 #include <locale.h>
 #include <langinfo.h>
 #include <iconv.h>
+#include <ctype.h>
 #include <errno.h>
 
 /* Include routines to handle parsing defaults */
@@ -183,6 +184,8 @@ enum {
 
 /* Possibly in xcb-emwh in the future? */
 static xcb_atom_t atom_net_wm_name, atom_utf8_string;
+static xcb_atom_t atom_net_wm_desktop, atom_net_wm_window_type,
+    atom_net_wm_state, atom_net_wm_pid, atom_net_frame_extents;
 static xcb_get_property_cookie_t get_net_wm_name (xcb_connection_t *,
 						  xcb_window_t);
 
@@ -200,6 +203,12 @@ struct wininfo {
     xcb_get_window_attributes_cookie_t	attr_cookie;
     xcb_get_property_cookie_t		normal_hints_cookie;
     xcb_get_property_cookie_t		hints_cookie;
+    xcb_get_property_cookie_t		wm_desktop_cookie;
+    xcb_get_property_cookie_t		wm_window_type_cookie;
+    xcb_get_property_cookie_t		wm_state_cookie;
+    xcb_get_property_cookie_t		wm_pid_cookie;
+    xcb_get_property_cookie_t		wm_client_machine_cookie;
+    xcb_get_property_cookie_t		frame_extents_cookie;
     xcb_get_property_cookie_t		zoom_cookie;
 
     /* cached results from previous requests */
@@ -234,6 +243,7 @@ static const char *window_id_format = "0x%lx";
 static const char *user_encoding;
 static iconv_t iconv_from_utf8;
 static void print_utf8 (const char *, char *, size_t, const char *);
+static void print_friendly_name (const char *, const char *, const char *);
 
 static xcb_connection_t *dpy;
 static xcb_screen_t *screen;
@@ -510,7 +520,13 @@ main (int argc, char **argv)
     /* preload atoms we may need later */
     Intern_Atom (dpy, "_NET_WM_NAME");
     Intern_Atom (dpy, "UTF8_STRING");
-
+    if (wm) {
+	Intern_Atom (dpy, "_NET_WM_DESKTOP");
+	Intern_Atom (dpy, "_NET_WM_WINDOW_TYPE");
+	Intern_Atom (dpy, "_NET_WM_STATE");
+	Intern_Atom (dpy, "_NET_WM_PID");
+	Intern_Atom (dpy, "_NET_FRAME_EXTENTS");
+    }
     /* initialize scaling data */
     scale_init(screen);
 
@@ -575,8 +591,46 @@ main (int argc, char **argv)
 	w->attr_cookie = xcb_get_window_attributes (dpy, window);
     if (stats || size)
 	w->normal_hints_cookie = xcb_get_wm_normal_hints (dpy, window);
-    if (wm)
+    if (wm) {
 	w->hints_cookie = xcb_get_wm_hints(dpy, window);
+
+	atom_net_wm_desktop = Get_Atom (dpy, "_NET_WM_DESKTOP");
+	if (atom_net_wm_desktop) {
+	    w->wm_desktop_cookie = xcb_get_property
+		(dpy, False, window, atom_net_wm_desktop,
+		 XCB_ATOM_CARDINAL, 0, 4);
+	}
+
+	atom_net_wm_window_type	= Get_Atom (dpy, "_NET_WM_WINDOW_TYPE");
+	if (atom_net_wm_window_type) {
+	    w->wm_window_type_cookie = xcb_get_property
+		(dpy, False, window, atom_net_wm_window_type,
+		 XCB_ATOM_ATOM, 0, BUFSIZ);
+	}
+
+	atom_net_wm_state = Get_Atom (dpy, "_NET_WM_STATE");
+	if (atom_net_wm_state) {
+	    w->wm_state_cookie = xcb_get_property
+		(dpy, False, window, atom_net_wm_state,
+		 XCB_ATOM_ATOM, 0, BUFSIZ);
+	}
+
+	atom_net_wm_pid	= Get_Atom (dpy, "_NET_WM_PID");
+	if (atom_net_wm_pid) {
+	    w->wm_pid_cookie = xcb_get_property
+		(dpy, False, window, atom_net_wm_pid,
+		 XCB_ATOM_CARDINAL, 0, BUFSIZ);
+	    w->wm_client_machine_cookie =
+		GET_TEXT_PROPERTY(dpy, window, XCB_ATOM_WM_CLIENT_MACHINE);
+	}
+
+	atom_net_frame_extents = Get_Atom (dpy, "_NET_FRAME_EXTENTS");
+	if (atom_net_frame_extents) {
+	    w->frame_extents_cookie = xcb_get_property
+		(dpy, False, window, atom_net_frame_extents,
+		 XCB_ATOM_CARDINAL, 0, 4 * 4);
+	}
+    }
     if (size)
 	w->zoom_cookie = xcb_get_wm_size_hints (dpy, window,
 						XCB_ATOM_WM_ZOOM_HINTS);
@@ -1563,6 +1617,8 @@ Display_WM_Info (struct wininfo *w)
 {
     xcb_wm_hints_t wmhints;
     long flags;
+    xcb_get_property_reply_t *prop;
+    int i;
 
     printf ("\n");
     if (!xcb_get_wm_hints_reply(dpy, w->hints_cookie, &wmhints, &err))
@@ -1570,9 +1626,9 @@ Display_WM_Info (struct wininfo *w)
 	printf ("  No window manager hints defined\n");
 	if (err)
 	    Print_X_Error (dpy, err);
-	return;
-    }
-    flags = wmhints.flags;
+	flags = 0;
+    } else
+	flags = wmhints.flags;
 
     printf ("  Window manager hints:\n");
 
@@ -1597,6 +1653,101 @@ Display_WM_Info (struct wininfo *w)
     if (flags & XCB_WM_HINT_STATE)
 	printf ("      Initial state is %s\n",
 		Lookup (wmhints.initial_state, _state_hints));
+
+    if (atom_net_wm_desktop) {
+	prop = xcb_get_property_reply (dpy, w->wm_desktop_cookie, NULL);
+	if (prop && (prop->type != XCB_NONE)) {
+	    uint32_t *desktop = xcb_get_property_value (prop);
+	    if (*desktop == 0xFFFFFFFF) {
+		printf ("      Displayed on all desktops\n");
+	    } else {
+		printf ("      Displayed on desktop %d\n", *desktop);
+	    }
+	}
+	free (prop);
+    }
+
+    if (atom_net_wm_window_type) {
+	prop = xcb_get_property_reply (dpy, w->wm_window_type_cookie,
+				       NULL);
+	if (prop && (prop->type != XCB_NONE) && (prop->value_len > 0)) {
+	    xcb_atom_t *atoms = xcb_get_property_value (prop);
+	    int atom_count = prop->value_len;
+
+	    if (atom_count > 0) {
+		printf ("      Window type:\n");
+		for (i = 0; i < atom_count; i++) {
+		    const char *atom_name = Get_Atom_Name (dpy, atoms[i]);
+
+		    if (atom_name) {
+			print_friendly_name ("          %s\n", atom_name,
+					     "_NET_WM_WINDOW_TYPE_");
+		    } else {
+			printf ("          (unresolvable ATOM 0x%x)\n",
+				atoms[i]);
+		    }
+		}
+	    }
+	}
+	free (prop);
+    }
+
+    if (atom_net_wm_state) {
+	prop = xcb_get_property_reply (dpy, w->wm_state_cookie, NULL);
+	if (prop && (prop->type != XCB_NONE) && (prop->value_len > 0)) {
+	    xcb_atom_t *atoms = xcb_get_property_value (prop);
+	    int atom_count = prop->value_len;
+
+	    if (atom_count > 0) {
+		printf ("      Window state:\n");
+		for (i = 0; i < atom_count; i++) {
+		    const char *atom_name = Get_Atom_Name (dpy, atoms[i]);
+
+		    if (atom_name) {
+			print_friendly_name ("          %s\n", atom_name,
+					     "_NET_WM_STATE_");
+		    } else {
+			printf ("          (unresolvable ATOM 0x%x)\n",
+				atoms[i]);
+		    }
+		}
+	    }
+	}
+	free (prop);
+    }
+
+    if (atom_net_wm_pid) {
+	printf ("      Process id: ");
+	prop = xcb_get_property_reply (dpy, w->wm_pid_cookie, NULL);
+	if (prop && (prop->type == XCB_ATOM_CARDINAL)) {
+	    uint32_t *pid = xcb_get_property_value (prop);
+	    printf ("%d", *pid);
+	} else {
+	    printf ("(unknown)");
+	}
+	free (prop);
+
+	prop = xcb_get_property_reply (dpy, w->wm_client_machine_cookie, NULL);
+	if (prop && (prop->type == XCB_ATOM_STRING)) {
+	    const char *hostname = xcb_get_property_value (prop);
+	    int hostname_len = xcb_get_property_value_length (prop);
+	    printf (" on host %.*s", hostname_len, hostname);
+	}
+	printf ("\n");
+	free (prop);
+    }
+
+    if (atom_net_frame_extents) {
+	prop = xcb_get_property_reply (dpy, w->frame_extents_cookie, NULL);
+	if (prop && (prop->type == XCB_ATOM_CARDINAL)
+	    && (prop->value_len == 4)) {
+	    uint32_t *extents = xcb_get_property_value (prop);
+
+	    printf ("      Frame extents: %d, %d, %d, %d\n",
+		    extents[0], extents[1], extents[2], extents[3]);
+	}
+	free (prop);
+    }
 }
 
 /* Frees all members of a wininfo struct, but not the struct itself */
@@ -1676,3 +1827,41 @@ print_utf8 (const char *prefix, char *u8str, size_t length, const char *suffix)
 		user_encoding);
     }
 }
+
+/*
+ * Takes a string such as an atom name, strips the prefix, converts
+ * underscores to spaces, lowercases all but the first letter of each word,
+ * and prints it.
+ */
+static void
+print_friendly_name (const char *format, const char *string,
+		     const char *prefix)
+{
+    const char *name_start = string;
+    char *lowered_name, *n;
+    int prefix_len = strlen (prefix);
+
+    if (strncmp (name_start, prefix, prefix_len) == 0) {
+	name_start += prefix_len;
+    }
+
+    lowered_name = strdup (name_start);
+    if (lowered_name) {
+	Bool first = True;
+
+	for (n = lowered_name ; *n != 0 ; n++) {
+	    if (*n == '_') {
+		*n = ' ';
+		first = True;
+	    } else if (first) {
+		first = False;
+	    } else {
+		*n = tolower(*n);
+	    }
+	}
+	name_start = lowered_name;
+    }
+
+    printf (format, name_start);
+    free (lowered_name);
+}
-- 
1.5.6.5



More information about the xorg-devel mailing list