#include <X11/Xlib.h>
#include <X11/Xutil.h>

Display * dpy;

Window findByClass(Window root, const char * name, const char * class) {
    Window firstMatch = None;
    Window parent, *clients;
    unsigned nClients;

    XQueryTree(dpy, root, &root, &parent, &clients, &nClients);

    if (clients) {
	unsigned n;
	
	for (n = 0; !firstMatch && n < nClients; ++n) {
	    XClassHint wmclass;

	    if (XGetClassHint(dpy, clients[n], &wmclass)) {
		if ((name == NULL || !strcmp(name, wmclass.res_name)) &&
		    (class == NULL || !strcmp(class, wmclass.res_class)))
		    firstMatch = clients[n];
		    
		XFree(wmclass.res_name);
		XFree(wmclass.res_class);
	    }
	    
	    if (!firstMatch)
		firstMatch = findByClass(clients[n], name, class);
	}

	XFree(clients);
    }
    
    return firstMatch;
}

int main() {
    if (!(dpy = XOpenDisplay(NULL)))
	return 1;

#define TEST_FIND(Name,Class) \
    { Window win = findByClass(DefaultRootWindow(dpy), Name, Class); \
      printf(win ? "%s.%s: 0x%x\n" : "%s.%s - not found\n", \
      	     Name, Class, win); }
	     
    XGrabServer(dpy);

    TEST_FIND("panel", "Panel")
    TEST_FIND("panel", NULL)
    TEST_FIND(NULL, "Panel")
    TEST_FIND(NULL, "XTerm")
    TEST_FIND("red", "XTerm")

    XUngrabServer(dpy);

    XCloseDisplay(dpy);

    return 0;
}

