+static void sync_after_input(void) {
+ int r;
+ r= XSync(disp, False); eassert(r);
+ last_input= timestamp();
+}
+
+static void send_key(KeySym sym) {
+ XTestFakeKeyEvent(disp, keycode(sym),1, 10);
+ XTestFakeKeyEvent(disp, keycode(sym),0, 10);
+}
+
+static void send_pgup_many(void) {
+ int i;
+ for (i=0; i<25; i++)
+ send_key(XK_Prior);
+ fprintf(stderr,"PAGING PageUp x %d\n",i);
+ sync_after_input();
+}
+static void send_pgdown(void) {
+ send_key(XK_Next);
+ fprintf(stderr,"PAGING PageDown\n");
+ sync_after_input();
+}
+
+static void free_snapshot(Snapshot **io) {
+ if (*io) XDestroyImage(*io);
+ *io= 0;
+}
+
+static void snapshot(Snapshot **output) {
+// char *cmd;
+// int r;
+// XImage *xim;
+
+ free_snapshot(output);
+
+ fprintf(stderr,"PAGING snapshot\n");
+
+ timestamp();
+ *output= XGetImage(disp,id, 0,0, wwidth,wheight, AllPlanes, ZPixmap);
+ timestamp();
+
+ fprintf(stderr,"PAGING snapshot done.\n");
+}
+
+static int identical(const Snapshot *a, const Snapshot *b) {
+ if (!(a->width == b->width &&
+ a->height == b->height &&
+ a->bytes_per_line == b->bytes_per_line &&
+ a->format == b->format))
+ return 0;
+ return !memcmp(a->data, b->data, a->bytes_per_line * a->height);
+}
+
+static void wait_for_stability(Snapshot **output,
+ const Snapshot *previously,
+ void (*with_keypress)(void)) {
+ Snapshot *last=0;
+ /* waits longer if we're going to return an image identical to previously
+ * if previously==0, all images are considered identical to it */
+
+ fprintf(stderr,"PAGING wait_for_stability"
+ " last_input=%f previously=%p\n",
+ last_input, previously);
+
+ for (;;) {
+ double at_snapshot= timestamp();
+ double need_sleep= min_update_allowance - (at_snapshot - last_input);
+ if (need_sleep > 0) { delay(need_sleep); continue; }
+
+ snapshot(output);
+
+ if (!with_keypress &&
+ !(previously && identical(*output,previously))) {
+ fprintf(stderr,"PAGING wait_for_stability simple\n");
+ break;
+ }
+
+ if (last && identical(*output,last)) {
+ fprintf(stderr,"PAGING wait_for_stability stabilised\n");
+ break;
+ }
+
+ fprintf(stderr,"PAGING wait_for_stability retry\n");
+
+ free_snapshot(&last); last=*output; *output=0;
+
+ if (with_keypress)
+ with_keypress();
+
+ delay(0.5);
+ }
+
+ free_snapshot(&last);
+ fprintf(stderr,"PAGING wait_for_stability done.\n");
+}
+
+static void raise_and_set_focus(void) {