chiark / gitweb /
Look deeper in window tree for YPP client
authorIan Jackson <ian@liberator.relativity.greenend.org.uk>
Sun, 28 Jun 2009 17:33:23 +0000 (18:33 +0100)
committerIan Jackson <ian@liberator.relativity.greenend.org.uk>
Sun, 28 Jun 2009 17:33:23 +0000 (18:33 +0100)
pctb/pages.c

index d298ac4..c5cc941 100644 (file)
@@ -611,112 +611,116 @@ void set_yppclient_window(unsigned long wul) {
 
 DEBUG_DEFINE_SOME_DEBUGF(findypp,debugfind)
 
+static int nfound;
+static Atom wm_name;
+static int screen;
+
+static void findypp_recurse(int depth, int targetdepth, Window w) {
+  unsigned int nchildren;
+  int i;
+  Window *children=0;
+  Window gotroot, gotparent;
+
+  static const char prefix[]= "Puzzle Pirates - ";
+  static const char onthe[]= " on the ";
+  static const char suffix[]= " ocean";
+#define S(x) (sizeof((x))-1)
+
+  debugfind("FINDYPP %d/%d screen %d  %*s %lx",
+           depth,targetdepth,screen,
+           depth,"",(unsigned long)w);
+  
+  if (depth!=targetdepth) {
+    xassert( XQueryTree(disp,w,
+                       &gotroot,&gotparent,
+                       &children,&nchildren) );
+    debugfind(" nchildren=%d\n",nchildren);
+  
+    for (i=0; i<nchildren; i++) {
+      Window child= children[i];
+      findypp_recurse(depth+1, targetdepth, child);
+    }
+    XFree(children);
+    return;
+  }
+    
+
+  int gotfmt;
+  Atom gottype;
+  unsigned long len, gotbytesafter;
+  char *title;
+  unsigned char *gottitle=0;
+  xassert( !XGetWindowProperty(disp,w, wm_name,0,512, False,
+                              AnyPropertyType,&gottype, &gotfmt, &len,
+                              &gotbytesafter, &gottitle) );
+  title= (char*)gottitle;
+
+  if (DEBUGP(findypp)) {
+    debugfind(" gf=%d len=%lu gba=%lu \"", gotfmt,len,gotbytesafter);
+    char *p;
+    for (p=title; p < title+len; p++) {
+      char c= *p;
+      if (c>=' ' && c<=126) fputc(c,debug);
+      else fprintf(debug,"\\x%02x",c & 0xff);
+    }
+    fputs("\": ",debug);
+  }
+
+#define REQUIRE(pred)                                                  \
+  if (!(pred)) { debugfind(" failed test  %s\n", #pred); return; }     \
+  else
+
+  REQUIRE( gottype!=None );
+  REQUIRE( len );
+  REQUIRE( gotfmt==8 );
+
+  REQUIRE( len >= S(prefix) + 1 + S(onthe) + 1 + S(suffix) );
+
+  char *spc1= strchr(  title        + S(prefix), ' ');  REQUIRE(spc1);
+  char *spc2= strrchr((title + len) - S(suffix), ' ');  REQUIRE(spc2);
+
+  REQUIRE( (title + len) - spc1  >= S(onthe)  + S(suffix) );
+  REQUIRE(  spc2         - title >= S(prefix) + S(onthe) );
+
+  REQUIRE( !memcmp(title,                   prefix, S(prefix)) );
+  REQUIRE( !memcmp(title + len - S(suffix), suffix, S(suffix))  );
+  REQUIRE( !memcmp(spc1,                    onthe,  S(onthe))  );
+
+#define ASSIGN(what, start, end)                       \
+  what= masprintf("%.*s", (end)-(start), start);       \
+  if (o_##what) REQUIRE( !strcasecmp(o_##what, what) );        \
+  else
+
+  ASSIGN(ocean,  spc1 + S(onthe),   (title + len) - S(suffix));
+  ASSIGN(pirate, title + S(prefix),  spc1);
+
+  debugfind(" YES!\n");
+  id= w;
+  nfound++;
+  progress_log("found YPP client (0x%lx):"
+              " %s ocean - %s.",
+              (unsigned long)id, ocean, pirate);
+}
+
 void find_yppclient_window(void) {
-  Window root, gotroot, gotparent;
-  int screen;
-  int nfound=0;
+  int targetdepth;
+
+  nfound=0;
   
   if (id) return;
   
   progress("looking for YPP client window...");
 
-  static const char prefix[]= "Puzzle Pirates - ";
-  static const char onthe[]= " on the ";
-  static const char suffix[]= " ocean";
-#define S(x) (sizeof((x))-1)
+  xassert( (wm_name= XInternAtom(disp,"WM_NAME",True)) != None);
 
-  Atom wm_name= XInternAtom(disp,"WM_NAME",True);
-  xassert(wm_name != None);
-
-  for (screen=0; screen<ScreenCount(disp); screen++) {
-    debugfind("FINDYPP screen %d\n", screen);
-    root= RootWindow(disp,screen);
-    unsigned int nchildren1;
-    Window *children1=0;
-
-    xassert( XQueryTree(disp,root,
-                 &gotroot,&gotparent,
-                 &children1,&nchildren1) );
-    debugfind("FINDYPP screen %d nchildren1=%d\n", screen, nchildren1);
-
-    int i;
-    for (i=0; i<nchildren1; i++) {
-      Window w1= children1[i];
-      unsigned int nchildren2;
-      Window *children2=0;
-
-      xassert( XQueryTree(disp,w1,
-                         &gotroot,&gotparent,
-                         &children2,&nchildren2) );
-      debugfind("FINDYPP screen %d c1[%2d]=0x%08lx nchildren2=%d\n",
-               screen, i, (unsigned long)w1, nchildren2);
-
-      int j;
-      for (j=-1; j<(int)nchildren2; j++) {
-       Window w2= j<0 ? w1 : children2[j];
-       debugfind("FINDYPP screen %d c1[%2d]=0x%08lx c2[%2d]=0x%08lx",
-                 screen, i, (unsigned long)w1, j, (unsigned long)w2);
-
-       int gotfmt;
-       Atom gottype;
-       unsigned long len, gotbytesafter;
-       char *title;
-       unsigned char *gottitle=0;
-       xassert( !XGetWindowProperty(disp,w2, wm_name,0,512, False,
-                                    AnyPropertyType,&gottype, &gotfmt, &len,
-                                    &gotbytesafter, &gottitle) );
-       title= (char*)gottitle;
-
-       if (DEBUGP(findypp)) {
-         debugfind(" gf=%d len=%lu gba=%lu \"", gotfmt,len,gotbytesafter);
-         char *p;
-         for (p=title; p < title+len; p++) {
-           char c= *p;
-           if (c>=' ' && c<=126) fputc(c,debug);
-           else fprintf(debug,"\\x%02x",c & 0xff);
-         }
-         fputs("\": ",debug);
-       }
-
-#define REQUIRE(pred)                                                     \
-        if (!(pred)) { debugfind(" failed test  %s\n", #pred); continue; } \
-        else
-
-       REQUIRE( gottype!=None );
-       REQUIRE( len );
-       REQUIRE( gotfmt==8 );
-
-       REQUIRE( len >= S(prefix) + 1 + S(onthe) + 1 + S(suffix) );
-
-       char *spc1= strchr(  title        + S(prefix), ' ');  REQUIRE(spc1);
-       char *spc2= strrchr((title + len) - S(suffix), ' ');  REQUIRE(spc2);
-
-       REQUIRE( (title + len) - spc1  >= S(onthe)  + S(suffix) );
-       REQUIRE(  spc2         - title >= S(prefix) + S(onthe) );
-
-       REQUIRE( !memcmp(title,                   prefix, S(prefix)) );
-       REQUIRE( !memcmp(title + len - S(suffix), suffix, S(suffix))  );
-       REQUIRE( !memcmp(spc1,                    onthe,  S(onthe))  );
-
-#define ASSIGN(what, start, end)                               \
-       what= masprintf("%.*s", (end)-(start), start);          \
-       if (o_##what) REQUIRE( !strcasecmp(o_##what, what) );   \
-       else
-
-       ASSIGN(ocean,  spc1 + S(onthe),   (title + len) - S(suffix));
-       ASSIGN(pirate, title + S(prefix),  spc1);
-
-       debugfind(" YES!\n");
-       id= w2;
-       nfound++;
-       progress_log("found YPP client (0x%lx):"
-                    " %s ocean - %s.",
-                    (unsigned long)id, ocean, pirate);
-      }
-      if (children2) XFree(children2);
+  for (targetdepth=1; targetdepth<4; targetdepth++) {
+    for (screen=0; screen<ScreenCount(disp); screen++) {
+      debugfind("FINDYPP screen %d\n", screen);
+      findypp_recurse(0,targetdepth, RootWindow(disp,screen));
     }
-    if (children1) XFree(children1);
+    if (nfound) break;
   }
+
   if (nfound>1)
     fatal("Found several possible YPP clients.   Close one,\n"
          " disambiguate with --pirate or --ocean,"