ftp.nice.ch/pub/next/text/tex/apps/texview.s.tar.gz#/texview/random.c

This is random.c in view mode; [Download] [Up]

/*
 *   This software is Copyright 1988 by Radical Eye Software.
 *   All Rights Reserved.
 */
/*
 *   Random page motion file for dviamiga.c (now called preview.c.)
 */
#include "structures.h"
/*
 *   The data structure we need for the linked list of pages.
 */
struct pagetype {
   struct pagetype *next ;
   integer page, no, pos ;
} *pages = NULL ;
struct pagetype *last = NULL ;
struct pagetype *currentpage = NULL ;
/*
 *   Some externals we need to get to.
 */
extern integer curpos ;
extern FILE *dvifile ;
extern integer prevpage, thispage, rthispage ;
extern integer pagenum, seq ;
extern integer numalloc, memalloc ;
extern struct Screen *myscreen ;
extern Boolean pageinterrupted ;
extern struct pagetype *mymalloc() ;
extern integer signedquad() ;
extern int skipnop() ;
extern int dvierror ;
extern long lseek() ;
extern void free() ;
extern void abortdvi() ;
extern void skipover() ;
extern void skippage() ;
extern int debugon ;
extern void qstatus() ;
extern Boolean dualpage ;
extern Boolean pagedrawn ;
extern integer fakeeof ;
/*
 *   This 'dviseek' routine should be faster than the usual one.
 *   Now we also need to check for writing, and some code needs
 *   to be changed to handle a no page dvi file.
 */
int lastwaswrite ;
void dviseek(where)
register integer where ;
{
   if (debugon > 6)
      printf("Seeking to %ld\n", where) ;
   fseek(dvifile, where, 0) ;
   curpos = where ;
}
/*
 *   This routine is called when a dvi file is closed to release all memory
 *   associated with the pages and to reset the variables to NULL.
 */
void freepages()
{
   register struct pagetype *p ;

   while (pages != NULL) {
      p = pages->next ;
      free(pages) ;
      pages = p ;
   }
   pages = last = currentpage = NULL ;
}
/*
 *   This routine adds a new page to the list we are constructing.
 */
struct pagetype *addpage(page, where)
integer page ;
register integer where ;
{
   register struct pagetype *p ;
   register integer c = 0 ;

   if (last == NULL || where > last->pos) {
      p = mymalloc(sizeof(struct pagetype), MEMF_CLEAR) ;
      if (last == NULL)
         pages = p ;
      else
         last->next = p ;
      last = p ;
      p->page = page ;
      p->pos = where ;
      p->next = NULL ;
      for (p=pages; p!=NULL; p=p->next)
         if (page==p->page)
            c++ ;
      last->no = c - 1 ;
      seq = c - 1 ;
      return(last) ;
   } else {
      for (p=pages; p!=NULL; p=p->next)
         if (p->pos == where) {
            seq = p->no ;
            return(p) ;
         }
   }
   return 0 ;
}
/*
 *   Here we add a page to the list the first time we scan it.  Only if it
 *   is the first time, though; we check it by looking at the current
 *   position and the position of the last page.   (By the way, the position
 *   we are referring to is always the location of the bop.)
 */
int processbop()
{
   register int cmd ;
   register long waswhere = curpos ;

   if (debugon > 6)
      printf("Processbop at %ld\n", curpos) ;
   cmd = skipnop() ;
   if (cmd==248 || cmd < 0) {
      dviseek(waswhere) ;
      return 0 ;
   } else if (cmd!=139) {
      abortdvi() ;
   }
   thispage = curpos - 1 ;
   pagenum = signedquad() ;
   currentpage = addpage(pagenum, thispage) ;
   skipover(36) ;
   prevpage = signedquad() ;
   rthispage = curpos ;
   return(1) ;
}

void missbop() {
   if (! processbop())
      abortdvi() ;
}
/*
 *   Here we look for a page and a number.  If it is not found, we skip to
 *   the end and scan forward until we find it.  When we find it, we seek
 *   to the correct location and return.  If it is not found, we return false.
 */
Boolean seekpage(page, no)
integer page, no ;
{
   register struct pagetype *p ;

   for (p=pages; p!=NULL; p=p->next) {
      if (page==p->page && no==p->no) {
         thispage = p->pos ;
         dviseek(thispage) ;
         if (!processbop())
            abortdvi() ;
         pagedrawn = 0 ;
         return(1) ;
      }
   }
   qstatus("Looking for page") ;
   if (last == NULL)
      dviseek(thispage) ;
   else
      dviseek(last->pos) ;
   for (;;) {
      if (!processbop()) {
         dviseek(thispage) ;
         missbop() ;
         pagedrawn = 0 ;
         return(0) ;
      }
      if (last->page == page && last->no == no) {
         pagedrawn = 0 ;
         return(1) ;
      }
      skippage() ;
   }
}
/*
 *   This one goes to a particular page.  -1 means back one, 0 means same
 *   page, 1 means next page.
 */
int relativepage(loc)
register int loc ;
{
#ifdef DEBUG
        if (debugon > 7) {
           printf("\nRelativepage %d %ld\n", loc, curpos) ;
           fflush(stdout) ;
        }
#endif
   if (loc == 0) {
      dviseek(thispage) ;
      missbop() ;
      return 1 ;
   } else if (loc == 1) {
/*    if (pageinterrupted) {
         if (currentpage == NULL || currentpage->next == NULL) {
            dviseek(curpos) ;
            skippage() ;
         } else {
            dviseek(currentpage->next->pos) ;
         }
      }
      if (dualpage && ! pageinterrupted) {
         if (currentpage == NULL)
            error("! this can't happen foo") ;
         if (currentpage != NULL && currentpage->next != NULL)
            dviseek(currentpage->next->pos) ;
      } */
      if (!processbop()) {
         return 0 ;
      } else
         pagedrawn = 0 ;
   } else if (loc == -1) {
      if (prevpage > 0) {
         dviseek(prevpage) ;
         missbop() ;
         pagedrawn = 0 ;
      } else
         return 0 ;
   } else {
      dviseek(pages->pos) ;
      missbop() ;
      pagedrawn = 0 ;
   }
   return 1 ;
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.