示例#1
0
文件: xlsclients.c 项目: aosm/X11
static void
lookat(Display *dpy, Window root, Bool verbose, int maxcmdlen)
{
    Window dummy, *children = NULL, client;
    unsigned int i, nchildren = 0;

    /*
     * clients are not allowed to stomp on the root and ICCCM doesn't yet
     * say anything about window managers putting stuff there; but, try
     * anyway.
     */
    print_client_properties (dpy, root, verbose, maxcmdlen);

    /*
     * then, get the list of windows
     */
    if (!XQueryTree (dpy, root, &dummy, &dummy, &children, &nchildren)) {
	return;
    }

    for (i = 0; i < nchildren; i++) {
	client = XmuClientWindow (dpy, children[i]);
	if (client != None)
	  print_client_properties (dpy, client, verbose, maxcmdlen);
    }
}
static void child_info(void *closure)
{
    child_wm_state *cs = closure;
    xcb_window_t orig = cs->orig_win;
    xcb_connection_t *c = cs->c;
    int verbose = cs->verbose;
    int maxcmdlen = cs->maxcmdlen;
    int i, j;

    int child_count, num_rep;
    xcb_query_tree_reply_t **reply;

    for (i = 0; i < cs->list_length; i++) {
	xcb_get_property_reply_t *reply;
	reply = xcb_get_property_reply(c, cs->prop_cookie[i], NULL);
	if (reply) {
	    if (reply->type) {
		/* Show information for this window */
		print_client_properties(c, cs->win[i], cs->verbose, cs->maxcmdlen);

		free(reply);

		/* drain stale replies */
		for (j = i+1; j < cs->list_length; j++) {
		    reply = xcb_get_property_reply(c, cs->prop_cookie[j], NULL);
		    if (reply)
			free(reply);
		}
		for (j = 0; j < cs->list_length; j++) {
		    xcb_query_tree_reply_t *rep;
		    rep = xcb_query_tree_reply(c, cs->tree_cookie[j], NULL);
		    if (rep)
			free(rep);
		}
		goto done;
	    }
	    free(reply);
	}
    }

    /* WM_STATE not found. Recurse into children: */
    num_rep = 0;
    reply = malloc(sizeof(*reply) * cs->list_length);
    if (!reply)
	goto done; /* TODO: print OOM message, drain reply queue */

    for (i = 0; i < cs->list_length; i++) {
	reply[num_rep] = xcb_query_tree_reply(c, cs->tree_cookie[i], NULL);
	if (reply[num_rep])
	    num_rep++;
    }

    child_count = 0;
    for (i = 0; i < num_rep; i++)
	child_count += reply[i]->children_len;

    if (!child_count) {
	/* No children have CS_STATE; try the parent window */
	print_client_properties(c, cs->orig_win, cs->verbose, cs->maxcmdlen);
	goto reply_done;
    }

    cs = malloc(sizeof(*cs) + child_count * (sizeof(*cs->prop_cookie) + sizeof(*cs->tree_cookie) + sizeof(*cs->win)));
    if (!cs)
	goto reply_done; /* TODO: print OOM message */

    cs->c = c;
    cs->verbose = verbose;
    cs->maxcmdlen = maxcmdlen;
    cs->orig_win = orig;
    cs->prop_cookie = (void *)&cs[1];
    cs->tree_cookie = (void *)&cs->prop_cookie[child_count];
    cs->win = (void *)&cs->tree_cookie[child_count];
    cs->list_length = child_count;

    child_count = 0;
    for (i = 0; i < num_rep; i++) {
	xcb_window_t *child = xcb_query_tree_children(reply[i]);
	for (j = 0; j < reply[i]->children_len; j++) {
	    cs->win[child_count] = child[j];
	    cs->prop_cookie[child_count] = xcb_get_property(c, 0, child[j],
			    WM_STATE, XCB_GET_PROPERTY_TYPE_ANY,
			    0, 0);
	    /* Just in case the property isn't there, get the tree too */
	    cs->tree_cookie[child_count++] = xcb_query_tree(c, child[j]);
	}
    }

    enqueue(child_info, cs);

reply_done:
    for (i = 0; i < num_rep; i++)
	free(reply[i]);
    free(reply);

done:
    free(closure);
}