chiark / gitweb /
get pirate name right
[ypp-sc-tools.web-live.git] / pctb / pages.c
index b9e1ac1649dc2c5aa8a57997e58cabba430b54f1..dae3d2138bd0d8a3ae0a874b3fc8ff74ff8562f7 100644 (file)
@@ -18,7 +18,6 @@ static Window id;
 static Display *disp;
 static struct timeval tv_startup;
 static unsigned wwidth, wheight;
-static int wxpos, wypos;
 
 DEBUG_DEFINE_DEBUGF(pages)
 
@@ -28,6 +27,7 @@ static KeyCode keycode(KeySym sym) {
 
 void screenshot_startup(void) {
   int r;
+  progress("starting...");
   disp= XOpenDisplay(0);  eassert(disp);
   r= gettimeofday(&tv_startup,0);  eassert(!r);
 }
@@ -61,6 +61,58 @@ static void sync_after_input(void) {
   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);
@@ -85,10 +137,6 @@ static void free_snapshot(Snapshot **io) {
 }
 
 static void snapshot(Snapshot **output) {
-//  char *cmd;
-//  int r;
-//  XImage *xim;
-  
   free_snapshot(output);
 
   debugf("PAGING   snapshot\n");
@@ -96,7 +144,9 @@ static void snapshot(Snapshot **output) {
   timestamp();
   *output= XGetImage(disp,id, 0,0, wwidth,wheight, AllPlanes, ZPixmap);
   timestamp();
-  
+
+  check_not_disturbed();
+
   debugf("PAGING   snapshot done.\n");
 }
 
@@ -111,8 +161,19 @@ static int identical(const Snapshot *a, const Snapshot *b) {
 
 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 */
 
@@ -120,6 +181,11 @@ static void wait_for_stability(Snapshot **output,
          "  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);
@@ -138,6 +204,8 @@ static void wait_for_stability(Snapshot **output,
       break;
     }
     
+    progress_spinner("%s",doing);
+
     debugf("PAGING  wait_for_stability  retry\n");
 
     free_snapshot(&last); last=*output; *output=0;
@@ -149,44 +217,76 @@ static void wait_for_stability(Snapshot **output,
   }
 
   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");
 }
 
@@ -254,14 +354,15 @@ void take_screenshots(void) {
 
   /* find the window and check it's on the right kind of screen */
   raise_and_get_details();
-  wait_for_stability(&current,0,0);
+  wait_for_stability(&current,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(&current,0, send_pgup_many);
+  wait_for_stability(&current,0, send_pgup_many,
+                    "paging up to top of commodity list...");
 
   /* now to actually page down */
   for (;;) {
@@ -273,7 +374,10 @@ void take_screenshots(void) {
 
     debugf("PAGING page %d converted\n",npages);
 
-    wait_for_stability(&current,last, 0);
+    wait_for_stability(&current,last, 0,
+                      "collecting screenshot of page %d...",
+                      npages+1);
+
     if (npages &&  /* first pagedown doesn't do much */
        identical(current,last)) {
       free_snapshot(&current);
@@ -284,6 +388,7 @@ void take_screenshots(void) {
     npages++;
   }
   debugf("PAGING all done.\n");
+  progress_log("collected %d screenshots.",npages);
 }    
 
 void take_one_screenshot(void) {
@@ -291,9 +396,10 @@ void take_one_screenshot(void) {
   
   raise_and_get_details();
   sync_after_input();
-  wait_for_stability(&current,0,0);
+  wait_for_stability(&current,0,0, "taking screenshot...");
   page_images[0]= convert_page(current);
   npages= 1;
+  progress_log("collected single screenshot.");
 }
 
 void set_yppclient_window(unsigned long wul) {
@@ -309,6 +415,8 @@ void find_yppclient_window(void) {
   
   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";
@@ -390,15 +498,18 @@ void find_yppclient_window(void) {
        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);
     }