From: Ian Jackson Date: Sat, 6 Jun 2009 11:13:38 +0000 (+0100) Subject: wip pager - before change to not converting until sure X-Git-Tag: 1.9.2~171 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~yarrgweb/git?p=ypp-sc-tools.web-live.git;a=commitdiff_plain;h=024dcba9bc55d02e5c05100ed65f8d64a1eb3bbf wip pager - before change to not converting until sure --- diff --git a/pctb/ocr.h b/pctb/ocr.h index d8491e6..d9a25f7 100644 --- a/pctb/ocr.h +++ b/pctb/ocr.h @@ -11,8 +11,11 @@ #include #include #include +#include + #include #include +#include typedef struct { @@ -52,6 +55,10 @@ const char *get_vardir(void); CanonImage *file_read_image(FILE *f); int main_test(void); +#define MAX_PAGES 100 +extern CanonImage *page_images[MAX_PAGES]; +extern int npages; + #define DEBUG_RECTANGLES // #define DEBUG_OCR diff --git a/pctb/pages.c b/pctb/pages.c index 272e5cf..66c3ad8 100644 --- a/pctb/pages.c +++ b/pctb/pages.c @@ -7,15 +7,18 @@ #include #include -#define NUM_PAGES 25 +CanonImage *page_images[MAX_PAGES]; +int npages; +static Window id; static Display *disp; +static struct timeval tv_startup; static KeyCode keycode(KeySym sym) { return XKeysymToKeycode(disp,sym); } -static CanonImage *screenshot_now(Window id) { +static CanonImage *screenshot_now(void) { char *cmd; CanonImage *ci; int r; @@ -30,14 +33,29 @@ static CanonImage *screenshot_now(Window id) { return ci; } -static void read_pages(Window id) { +static void screenshot_startup(void) { + int r; + disp= XOpenDisplay(0); eassert(disp); + r= gettimeofday(&tv_startup,0); eassert(!r); +} + +#if 0 +static CanonImage *single_page(void) { + int r; + r= XRaiseWindow(disp, id); eassert(r); + r= XSync(disp, False); eassert(r); + return screenshot_now(); +} +#endif + +static void raise_and_set_focus(void) { int r; XWindowAttributes attr; int xpos,ypos, evbase,errbase,majver,minver; unsigned width,height,bd,depth; Window dummy; - disp= XOpenDisplay(0); eassert(disp); + fprintf(stderr,"PAGING raise_and_set_focus\n"); r= XTestQueryExtension(disp, &evbase,&errbase,&majver,&minver); eassert(r==True); @@ -55,21 +73,148 @@ static void read_pages(Window id) { int screen= XScreenNumberOfScreen(attr.screen); XTestFakeMotionEvent(disp,screen, xpos, ypos, 0); - XTestFakeButtonEvent(disp,1,1, 0); + XTestFakeButtonEvent(disp,1,1, 50); XTestFakeButtonEvent(disp,1,0, 50); + r= XSync(disp, False); eassert(r); - XTestFakeKeyEvent(disp, keycode(XK_Next),1, 50); - XTestFakeKeyEvent(disp, keycode(XK_Next),0, 50); - + fprintf(stderr,"PAGING raise_and_set_focus done.\n"); +} + +static void send_key(KeySym sym) { + int r; + XTestFakeKeyEvent(disp, keycode(sym),1, 10); + XTestFakeKeyEvent(disp, keycode(sym),0, 10); r= XSync(disp, False); eassert(r); } +static void send_pgup(void) { + fprintf(stderr,"PAGING PageUp\n"); + send_key(XK_Prior); +} +static void send_pgdown(void) { + fprintf(stderr,"PAGING PageDown\n"); + send_key(XK_Next); +} + +static double timestamp(void) { + struct timeval tv; + int r; + + r= gettimeofday(&tv,0); eassert(!r); + return (tv.tv_sec - tv_startup.tv_sec) + + (tv.tv_usec - tv_startup.tv_usec) * 1e-6; +} + +static double worst_snapshot= 0.050, worst_stabilise= 0.100; + +static void snapshot(CanonImage **output) { + free(*output); + double a= timestamp(); + *output= screenshot_now(); + fprintf(stderr,"PAGING snapshot\n"); + double b= timestamp(); + double it_took= b-a; + fprintf(stderr,"PAGING snapshot took=%f\n",it_took); + if (it_took > worst_snapshot) + worst_snapshot= it_took; +} + +static void snapshot_idle(void) { + int r; + r= usleep(worst_snapshot * 1e6 * 2); + /* spend no more than 1/3 of our time constantly snapshotting */ + eassert(!r); +} + +static int identical(const CanonImage *a, const CanonImage *b) { + return !(memcmp(a, b, sizeof(*a)) || + memcmp(a->d, b->d, a->w * a->h)); +} + +static void wait_for_stability(CanonImage **output, + const CanonImage *previously, + void (*with_keypress)(void)) { + CanonImage *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 */ + + double when_started= timestamp(); + double last_change= when_started; + double it_took= -1; + + fprintf(stderr,"PAGING wait_for_stability" + " worst_snapshot=%f worst_stabilise=%f\n", + worst_snapshot, worst_stabilise); + + for (;;) { + snapshot(output); + double right_now= timestamp(); + + if (!last || !identical(*output,last)) { + fprintf(stderr,"PAGING wait_for_stability changed...\n"); + last_change= right_now; + free(last); last=*output; *output=0; + it_took= -1; + } else { + if (it_took<0) + it_took= right_now - when_started; + + double threshold= (worst_stabilise + worst_snapshot) * 3; + if (!previously || identical(*output,previously)) + threshold *= 2; threshold += 1.5; + + double stable_for= right_now - last_change; + fprintf(stderr,"PAGING wait_for_stability" + " worst_snapshot=%f worst_stabilise=%f" + " stable for %f thresh %f...\n", + worst_snapshot, worst_stabilise, + stable_for, threshold); + + if (stable_for > threshold) + break; + } + if (with_keypress) + with_keypress(); + snapshot_idle(); + } + + if (it_took > worst_stabilise) + worst_stabilise= it_took; + + free(last); + fprintf(stderr,"PAGING wait_for_stability done.\n"); +} + +static void read_pages(void) { + CanonImage *current=0, *last; + + raise_and_set_focus(); + + /* page to the top - keep pressing page up until the image stops changing */ + wait_for_stability(¤t,0, send_pgup); + + /* now to actually page down */ + for (;;) { + fprintf(stderr,"PAGING page %d\n",npages); + eassert(npages < MAX_PAGES); + page_images[npages++]= last= current; + send_pgdown(); + wait_for_stability(¤t,last, 0); + if (npages && /* first pagedown doesn't do much */ + identical(current,last)) { + free(current); + break; + } + } + fprintf(stderr,"PAGING all done.\n"); +} + int main(int argc, char **argv) { - Window id; - CanonImage *ci; + screenshot_startup(); id= strtoul(*++argv,0,0); - read_pages(id); - ci= screenshot_now(id); + + read_pages(); return 0; } +