static Display *disp;
static struct timeval tv_startup;
static unsigned wwidth, wheight;
-static int wxpos, wypos;
DEBUG_DEFINE_DEBUGF(pages)
void screenshot_startup(void) {
int r;
+ progress("starting...");
disp= XOpenDisplay(0); eassert(disp);
r= gettimeofday(&tv_startup,0); eassert(!r);
}
last_input= timestamp();
}
+static void translate_coords_toroot(int wx, int wy, int *rx, int *ry) {
+ int r;
+ Window dummy;
+ r= XTranslateCoordinates(disp, id,attr.root, wx,wy, rx,ry, &dummy);
+ eassert(r);
+}
+
+static void check_client_window_all_on_screen(void) {
+ int r;
+ int rxpos, rypos;
+ unsigned rwidth, rheight;
+ Window dummy;
+ unsigned bd, depth;
+
+ r= XGetGeometry(disp,attr.root, &dummy, &rxpos,&rypos,
+ &rwidth, &rheight,
+ &bd,&depth);
+
+ translate_coords_toroot(0,0, &rxpos,&rypos);
+ eassert(rxpos>=0 && rypos>=0);
+
+ translate_coords_toroot(wwidth-1,wheight-1, &rxpos,&rypos);
+ eassert(rxpos<rwidth && rypos<rheight);
+}
+
+static void check_not_disturbed(void) {
+ XEvent ev;
+ int r;
+
+ for (;;) {
+ r= XCheckMaskEvent(disp, ~0, &ev);
+ if (r==False) return;
+
+ switch (ev.type) {
+ case VisibilityNotify:
+ eassert(ev.xvisibility.state == VisibilityUnobscured);
+ break;
+ case ConfigureNotify:
+ check_client_window_all_on_screen();
+ break;
+ case FocusOut:
+ eassert(!"focus left YPP client window");
+ break;
+ case FocusIn:
+ warning("focus entered YPP client window ?!");
+ break;
+ default:
+ eassert(!"unexpected X11 event");
+ }
+ }
+}
+
static void send_key(KeySym sym) {
XTestFakeKeyEvent(disp, keycode(sym),1, 10);
XTestFakeKeyEvent(disp, keycode(sym),0, 10);
}
static void snapshot(Snapshot **output) {
-// char *cmd;
-// int r;
-// XImage *xim;
-
free_snapshot(output);
debugf("PAGING snapshot\n");
timestamp();
*output= XGetImage(disp,id, 0,0, wwidth,wheight, AllPlanes, ZPixmap);
timestamp();
-
+
+ check_not_disturbed();
+
debugf("PAGING snapshot done.\n");
}
static void wait_for_stability(Snapshot **output,
const Snapshot *previously,
- void (*with_keypress)(void)) {
+ void (*with_keypress)(void),
+ const char *fmt, ...)
+ FMT(4,5);
+
+static void wait_for_stability(Snapshot **output,
+ const Snapshot *previously,
+ void (*with_keypress)(void),
+ const char *fmt, ...) {
+ va_list al;
+ va_start(al,fmt);
+
Snapshot *last=0;
+ int r;
/* waits longer if we're going to return an image identical to previously
* if previously==0, all images are considered identical to it */
" last_input=%f previously=%p\n",
last_input, previously);
+ char *doing;
+ r= vasprintf(&doing,fmt,al); eassert(r>=0);
+
+ progress("%s",doing);
+
for (;;) {
double at_snapshot= timestamp();
double need_sleep= min_update_allowance - (at_snapshot - last_input);
break;
}
+ progress_spinner("%s",doing);
+
debugf("PAGING wait_for_stability retry\n");
free_snapshot(&last); last=*output; *output=0;
}
free_snapshot(&last);
+ free(doing);
debugf("PAGING wait_for_stability done.\n");
+ va_end(al);
}
static void raise_and_get_details(void) {
int r;
int evbase,errbase,majver,minver;
+ int wxpos, wypos;
unsigned bd,depth;
- Window dummy;
-
+
+ progress("raising and checking YPP client window...");
+
debugf("PAGING raise_and_get_details\n");
r= XTestQueryExtension(disp, &evbase,&errbase,&majver,&minver);
eassert(r==True);
r= XRaiseWindow(disp, id); eassert(r);
+ /* in case VisibilityNotify triggers right away before we have had a
+ * change to raise; to avoid falsely detecting lowering in that case */
+
+ r= XSelectInput(disp, id,
+ StructureNotifyMask|
+ VisibilityChangeMask
+ ); eassert(r);
+
+ r= XRaiseWindow(disp, id); eassert(r);
+ /* in case the window was lowered between our Raise and our SelectInput;
+ * to avoid failing to detect that lowering */
r= XGetWindowAttributes(disp, id, &attr); eassert(r);
r= XGetGeometry(disp,id, &attr.root,
&wxpos,&wypos, &wwidth,&wheight,
&bd,&depth);
- eassert(r);
- r= XTranslateCoordinates(disp, id,attr.root, 160,160, &wxpos,&wypos,
- &dummy);
- eassert(r);
+ eassert(wwidth >= 320 && wheight >= 320);
+
+ check_client_window_all_on_screen();
}
static void set_focus(void) {
+ int r;
int screen= XScreenNumberOfScreen(attr.screen);
+ progress("taking control of YPP client window...");
+
debugf("PAGING set_focus\n");
- XTestFakeMotionEvent(disp,screen, wxpos,wypos, 0);
+ int xpos, ypos;
+ translate_coords_toroot(160,160, &xpos,&ypos);
+ XTestFakeMotionEvent(disp,screen, xpos,ypos, 0);
XTestFakeButtonEvent(disp,1,1, 50);
XTestFakeButtonEvent(disp,1,0, 50);
sync_after_input();
+
+ delay(0.5);
+ r= XSelectInput(disp, id,
+ StructureNotifyMask|
+ VisibilityChangeMask|
+ FocusChangeMask
+ ); eassert(r);
+
+ translate_coords_toroot(10,10, &xpos,&ypos);
+ XTestFakeMotionEvent(disp,screen, xpos,ypos, 0);
+
+ sync_after_input();
+
debugf("PAGING raise_and_set_focus done.\n");
}
/* find the window and check it's on the right kind of screen */
raise_and_get_details();
- wait_for_stability(¤t,0,0);
+ wait_for_stability(¤t,0,0, "checking current YPP client screen...");
test= convert_page(current);
find_structure(test);
free(test);
/* page to the top - keep pressing page up until the image stops changing */
set_focus();
- wait_for_stability(¤t,0, send_pgup_many);
+ wait_for_stability(¤t,0, send_pgup_many,
+ "paging up to top of commodity list...");
/* now to actually page down */
for (;;) {
debugf("PAGING page %d converted\n",npages);
- wait_for_stability(¤t,last, 0);
+ wait_for_stability(¤t,last, 0,
+ "collecting screenshot of page %d...",
+ npages+1);
+
if (npages && /* first pagedown doesn't do much */
identical(current,last)) {
free_snapshot(¤t);
npages++;
}
debugf("PAGING all done.\n");
+ progress_log("collected %d screenshots.",npages);
}
void take_one_screenshot(void) {
raise_and_get_details();
sync_after_input();
- wait_for_stability(¤t,0,0);
+ wait_for_stability(¤t,0,0, "taking screenshot...");
page_images[0]= convert_page(current);
npages= 1;
+ progress_log("collected single screenshot.");
}
void set_yppclient_window(unsigned long wul) {
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";
REQUIRE( !memcmp(title + len - S(suffix), suffix, S(suffix)) );
REQUIRE( !memcmp(spc1, onthe, S(onthe)) );
-#define ASSIGN(what, start, end) do { \
- r= asprintf(&what, "%.*s", end - start, start); eassert(r>0); \
+#define ASSIGN(what, start, end) do { \
+ r= asprintf(&what, "%.*s", (end)-(start), start); eassert(r>0); \
}while(0)
- ASSIGN(ocean, title + S(prefix), spc1);
- ASSIGN(pirate, spc1 + S(onthe), (title + len) - S(suffix));
+ ASSIGN(pirate, title + S(prefix), spc1);
+ ASSIGN(ocean, spc1 + S(onthe), (title + len) - S(suffix));
debugfind(" YES!\n");
id= w2;
nfound++;
+ progress_log("found YPP client [--window-id 0x%lx]:"
+ " %s ocean - %s.",
+ (unsigned long)id, ocean, pirate);
}
if (children2) XFree(children2);
}