chiark / gitweb /
converts to CanonImage
authorIan Jackson <ian@liberator.relativity.greenend.org.uk>
Sat, 6 Jun 2009 13:13:10 +0000 (14:13 +0100)
committerIan Jackson <ian@liberator.relativity.greenend.org.uk>
Sat, 6 Jun 2009 13:13:10 +0000 (14:13 +0100)
pctb/pages.c

index 39690388ebc41589c583653916aaaefc7a8adf3e..69f097da0fc0ad1b1414e313c6657ea506b7df37 100644 (file)
@@ -18,11 +18,16 @@ static KeyCode keycode(KeySym sym) {
   return XKeysymToKeycode(disp,sym);
 }
 
+static void check_exitstatus(int st) {
+  eassert(WIFEXITED(st));
+  eassert(!WEXITSTATUS(st));
+}
+
 static void check_pclose(FILE *f, char *cmd) {
   int r;
   eassert(!ferror(f));
   r= fgetc(f);  eassert(r==EOF);  eassert(feof(f));
-  r= pclose(f);  eassert(r>=0);  eassert(WIFEXITED(r) && !WEXITSTATUS(r));
+  r= pclose(f);  eassert(r>=0);  check_exitstatus(r);
   free(cmd);
 }
 
@@ -227,7 +232,76 @@ static void raise_and_set_focus(void) {
   fprintf(stderr,"PAGING raise_and_set_focus done.\n");
 }
 
+static void store_page(int pageno, Snapshot *sn) {
+  pid_t converter, paster;
+  eassert(pageno < MAX_PAGES);
+  int paste[2], results[2];
+  FILE *err;
+  int r;
 
+  eassert(!fflush(stdout));
+  eassert(!fflush(stderr));
+  
+  r= pipe(paste);  eassert(!r);
+  r= pipe(results);  eassert(!r);
+  err= tmpfile();  eassert(err);
+
+  converter= fork();  eassert(converter!=-1);
+  if (!converter) {
+    r= dup2(paste[0],0);  eassert(r==0);
+    r= dup2(results[1],1);  eassert(r==1);
+    r= dup2(2,4);            eassert(r==4); /* fileno(errn) > 4, see above */
+    r= dup2(fileno(err),2);  eassert(r==2);
+    close(paste[0]);
+    close(paste[1]);
+    close(results[0]);
+    close(results[1]);
+    execlp("xwdtopnm", "xwdtopnm",(char*)0);
+    dup2(4,2);
+    eassert(!"xwdtopnm exec failure");
+  }
+
+  paster= fork();  eassert(paster!=-1);
+  if (!paster) {
+    FILE *f= fdopen(paste[1],"w");  eassert(f);
+    close(paste[0]);
+    close(results[0]);
+    close(results[1]);
+    size_t did= fwrite(sn->d, 1, sn->len, f);
+    eassert(did==sn->len);
+    eassert(!fclose(f));
+    exit(0);
+  }
+
+  close(paste[0]);
+  close(paste[1]);
+  close(results[1]);
+
+  FILE *f= fdopen(results[0],"r");
+  int c1= fgetc(f);
+  if (c1!=EOF) {
+    ungetc(c1,f);
+    page_images[pageno]= file_read_image(f);
+    r= fgetc(f);  eassert(r==EOF);  eassert(!ferror(f));  eassert(feof(f));
+    fclose(f);
+  }
+
+  pid_t got_conv,got_paste;
+  int st_conv, st_paste;
+
+  got_conv= waitpid(converter,&st_conv,0);  eassert(got_conv==converter);
+  got_paste= waitpid(paster,&st_paste,0);  eassert(got_paste==paster);
+
+  if (!st_conv &&
+      (!st_paste || (WIFSIGNALED(st_paste) && WTERMSIG(st_paste)==SIGPIPE))
+      && c1!=EOF) {
+    fclose(err);
+    return;
+  }
+  rewind(err); int c; while ((c=getc(err))!=EOF) fputc(c,stderr);
+  fprintf(stderr, "convert: subprocess statuses: %d %d\n", st_conv, st_paste);
+  _exit(127);
+}
 
 static void read_pages(void) {
   Snapshot *current=0, *last=0;
@@ -235,13 +309,14 @@ static void read_pages(void) {
   raise_and_set_focus();
 
   /* page to the top - keep pressing page up until the image stops changing */
-  wait_for_stability(&last,0, send_pgup_many);
+  wait_for_stability(&current,0, send_pgup_many);
 
   /* now to actually page down */
   for (;;) {
     fprintf(stderr,"PAGING page %d\n",npages);
-    //eassert(npages < MAX_PAGES);
-    //page_images[npages++]=
+    store_page(npages, current);
+    free(last); last=current; current=0;
+    fprintf(stderr,"PAGING page %d converted\n",npages);
 
     wait_for_stability(&current,last, 0);
     if (npages &&  /* first pagedown doesn't do much */
@@ -250,8 +325,6 @@ static void read_pages(void) {
       break;
     }
 
-    free(last); last=current; current=0;
-
     send_pgdown();
     npages++;
   }