+static void raise_and_get_details(void) {
+ int r;
+ int evbase,errbase,majver,minver;
+ unsigned bd,depth;
+ Window dummy;
+
+ fprintf(stderr,"PAGING raise_and_get_details\n");
+
+ r= XTestQueryExtension(disp, &evbase,&errbase,&majver,&minver);
+ eassert(r==True);
+
+ r= XRaiseWindow(disp, id); eassert(r);
+
+ 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);
+}
+
+static void set_focus(void) {
+ int screen= XScreenNumberOfScreen(attr.screen);
+
+ fprintf(stderr,"PAGING set_focus\n");
+
+ XTestFakeMotionEvent(disp,screen, wxpos,wypos, 0);
+
+ XTestFakeButtonEvent(disp,1,1, 50);
+ XTestFakeButtonEvent(disp,1,0, 50);
+
+ sync_after_input();
+ fprintf(stderr,"PAGING raise_and_set_focus done.\n");
+}
+
+#define SAMPLEMASK 0xfful
+
+typedef struct {
+ int lshift, rshift;
+} ShMask;
+
+static void compute_shift_mask(ShMask *sm, unsigned long ximage_mask) {
+ sm->lshift= 0;
+ sm->rshift= 0;
+
+ for (;;) {
+ if (ximage_mask <= (SAMPLEMASK>>1)) {
+ sm->lshift++; ximage_mask <<= 1;
+ } else if (ximage_mask > SAMPLEMASK) {
+ sm->rshift++; ximage_mask >>= 1;
+ } else {
+ break;
+ }
+ assert(!(sm->lshift && sm->rshift));
+ }
+ assert(sm->lshift < LONG_BIT);
+ assert(sm->rshift < LONG_BIT);
+}
+
+static CanonImage *convert_page(Snapshot *sn) {
+ ShMask shiftmasks[3];
+ CanonImage *im;
+
+ fprintf(screenshots_file,
+ "P6\n"
+ "%d %d\n"
+ "255\n", sn->width, sn->height);
+
+#define COMPUTE_SHIFT_MASK(ix, rgb) \
+ compute_shift_mask(&shiftmasks[ix], sn->rgb##_mask)
+ COMPUTE_SHIFT_MASK(0, red);
+ COMPUTE_SHIFT_MASK(1, green);
+ COMPUTE_SHIFT_MASK(2, blue);
+
+ CANONICALISE_IMAGE(im, sn->width, sn->height, {
+ long xrgb= XGetPixel(sn, x, y);
+ int i;
+ rgb= 0;
+ for (i=0; i<3; i++) {
+ rgb <<= 8;
+ unsigned long sample=
+ ((xrgb << shiftmasks[i].lshift)
+ >> shiftmasks[i].rshift) & SAMPLEMASK;
+ rgb |= sample;
+ fputc(sample, screenshots_file);
+ }
+ });
+
+ eassert(!fflush(screenshots_file));
+
+ return im;
+}
+
+void take_screenshots(void) {