static CanonImage *convert_page(Snapshot *sn, RgbImage *ri) {
CanonImage *im;
- fprintf(screenshot_file,
- "P6\n"
- "%d %d\n"
- "255\n", sn->w, sn->h);
+ fwrite_ppmraw(screenshot_file, sn);
+ if (ri) memcpy(ri->data, sn->data, ri->h * ri->w * 3);
+ unsigned char *pixel= sn->data;
CANONICALISE_IMAGE(im, sn->w, sn->h, {
- int i;
- rgb= 0;
- for (i=0; i<3; i++) {
- rgb <<= 8;
- unsigned long sample= RI_PIXEL(sn,x,y)[i];
- rgb |= sample;
- fputc(sample, screenshot_file);
- }
- if (ri)
- CANONIMG_ALSO_STORERGB(ri);
+ rgb=
+ (pixel[0] << 16) |
+ (pixel[1] << 8) |
+ (pixel[2] );
+ pixel += 3;
});
-
+
sysassert(!ferror(screenshot_file));
sysassert(!fflush(screenshot_file));
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,"