/*
 *	This program is Copyright (C) 1987 by the Board of Trustees of the
 *	University of Illinois, and by the author Dirk Grunwald.
 */

/*
 *
 *	This looks kind of strange because, initially, I had intended to
 *	allow you to `put away' a page without destroying it -- but
 *	I've decided not to do that.
 *
 */

#include <stdio.h>
#include <X11/Xos.h>  
#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>

#include <stdio.h>
#include <assert.h>

#include "dvi-simple.h"

#include "texx2.h"

#include "DviPage.h"
#include "texx2-page.h"
#include "texx2-font.h"
#include <X11/ViewportP.h>	/* needed to get scrollbar sizes? */

extern Widget TopLevelWidget;

#ifdef _STCD_
  void TeXPageRealize(TeXPage *, int);
  static void showPage(TeXPage *, int);
#else
  void TeXPageRealize();
  static void showPage();
#endif

int TeXPages;
TeXPage *TheTeXPages[ MAX_TEX_PAGES ];

typedef struct {
  char *thePage;
  int refs;
} DviPageRef;

DviPageRef *ThePageRefs = 0;

void
TeXPageCloseFile()
{
  int popup;

  /* dispose of existing information */

  for ( popup = 0; popup < TeXPages; popup++ ) {
    TeXPage *tp = TheTeXPages[popup];
    if ( tp && tp -> popUpPage) {
      TeXPageDeref( tp -> pageNumber );
      TeXFontUnref( tp -> userMag);
      tp -> pageData = 0;
    }
  }

  if ( ThePageRefs ) {
    int i;
    for (i = 0; i < DviTotalPages; i++ ) {
      XtFree( ThePageRefs[i].thePage );
      ThePageRefs[ i ].thePage = 0;
    }
  }

  XtFree( ThePageRefs );

  ThePageRefs = 0;
}

void
TeXPageSlamPages()
{
  int popup;

  /* take down pages, dispose of existing information */

  for ( popup = 0; popup < TeXPages; popup++ ) {
    if ( TheTeXPages[popup] && TheTeXPages[ popup ] -> popUpPage) {
      XtDestroyWidget( TheTeXPages[ popup ] -> popUpPage ); 
    }
  }
}

void
TeXPageOpenFile()
{
  /* now rebuild it all */

  if ( DviFile != 0 ) {
    int i;
    int popup;

    ThePageRefs =
      (DviPageRef *)  XtMalloc( (DviTotalPages+1) * sizeof(DviPageRef) );

    for (i = 0; i < DviTotalPages; i++ ) {
      ThePageRefs[i].thePage = 0;
      ThePageRefs[i].refs = 0;
    }

    for ( popup = 0; popup < TeXPages; popup++ ) {
      TeXPage *tp = TheTeXPages[ popup ];

      if ( tp && tp -> popUpPage) {

	int pno = tp -> pageNumber;

	if (pno >= 0 && pno < DviTotalPages) {
	  Arg argList[20];
	  int args = 0;

	  tp -> pageData = TeXPageRef( tp -> pageNumber );

	  XtSetArg(argList[args], XtNpai, &ThePostAmbleInfo); args++;
	  XtSetArg(argList[args], XtNpage, tp -> pageData); args++;
	  XtSetArg(argList[args], XtNdviFonts, TheFontInfo); args++;
	  XtSetArg(argList[args], XtNxFonts,
		   TeXFontRef(tp -> userMag)); args++;

	  XtSetValues( tp -> singleDviPage, argList, args);

	  showPage( tp, False );
	}
	else {
	  XtDestroyWidget( tp -> popUpPage ); 
	}
      }
    }
  }
}


/*
 *	Reference and dereference a page structure -- these keep track
 *	of the memory allocated for page buffers & disposes of them
 *	when not in use.
 */

char *
TeXPageRef(pageno)
int pageno;
{
  assert( pageno >= 0 || pageno < DviTotalPages );

  ThePageRefs[ pageno ].refs++;
  if ( ThePageRefs[ pageno ].thePage == 0 ) {
    ThePageRefs[ pageno ].thePage = DviFetchPage( pageno );
  }

  return(ThePageRefs[ pageno ].thePage );
}

void
TeXPageDeref(pageno)
int pageno;
{
  assert( pageno >= 0 || pageno < DviTotalPages );
  if ( ThePageRefs && ThePageRefs[ pageno ].refs > 0) {
    ThePageRefs[ pageno ].refs--;
    if ( ThePageRefs[ pageno ].refs <= 0 ) {
      XtFree( ThePageRefs[ pageno ].thePage );
      ThePageRefs[ pageno ].thePage = 0;
    }
  }
}

/*
 *	Locate a free TeXPage structure. See comment at head.
 */

TeXPage *
TeXPageLocate()
{
  int i;
  TeXPage *tp;

  for (i = 0; i < TeXPages; i++ ) {
    if ( ! TheTeXPages[ i ] -> active ) {
      return( TheTeXPages[ i ] );
    }
  }

  tp = (TeXPage *) XtMalloc(sizeof(TeXPage));

  bzero( tp, sizeof(TeXPage) );

  tp -> realized = False;
  tp -> tied = 0;
  tp -> tiedTo = 0;

  /* install the page in the page list */
  
  if ( TeXPages > MAX_TEX_PAGES ) {
    error(0,0,"No more pages available");
    return(0);
  }
  
  TheTeXPages[ TeXPages++ ] = tp;

  return( tp );
}

/*
 *	The callback when pages die.
 */

static void
  dviPageDied(w, clientData,  callData)
Widget w;
caddr_t clientData;	/* unused */
caddr_t callData; /* unused */
{
  TeXPage *tp = (TeXPage*) clientData;

  if ( tp != 0 ){
    tp -> active = False;
    tp -> realized = False;
    TeXPageDeref( tp -> pageNumber );
    TeXFontUnref( tp -> userMag);
    tp -> popUpPage = 0;

    if ( tp -> tiedTo != 0 && tp -> tiedTo -> active ) {
      tp -> tiedTo -> tied = 0;
    }

    if ( tp -> tied != 0 && tp -> tied -> active ) {
      tp -> tied -> tiedTo = 0;
    }

    tp -> tiedTo = 0;
    tp -> tied = 0;

  }
}

static void
  pushQuitButton(w, clientData,  callData)
Widget w;
caddr_t clientData;	/* unused */
caddr_t callData; /* unused */
{
  TeXPage *tp = (TeXPage*) clientData;
  XtDestroyWidget( tp -> popUpPage );
} 

/*
 *	Set all the buttons for this page, possibly also
 *	sending the page information
 */

static   Arg sensArgs[] = {
  {XtNsensitive, (XtArgVal) True}
};

static   Arg insensArgs[] = {
  {XtNsensitive, (XtArgVal) False}
};

static void
  showPage(tp, displayPage)
TeXPage *tp;
Bool displayPage;
{
  Arg argList[20];
  Cardinal args;

  Pixel fore;
  Pixel back;

  if ( displayPage ) {
    tp -> pageData = TeXPageRef( tp -> pageNumber );
    args = 0;
    XtSetArg(argList[args], XtNpage, tp -> pageData); args++;

    XtSetValues(tp -> singleDviPage, argList, args);
  }

  if ( tp -> pageNumber == 0 ) {
    XtSetValues( tp -> backwardButton, insensArgs, XtNumber(insensArgs));
  }
  else {
    XtSetValues( tp -> backwardButton, sensArgs, XtNumber(sensArgs));
  }

  if ( tp -> pageNumber >= (DviTotalPages-1)) {
    XtSetValues( tp -> forewardButton, insensArgs, XtNumber(insensArgs));
  }
  else {
    XtSetValues( tp -> forewardButton, sensArgs, XtNumber(sensArgs));
  }

  /* Take normal values from another button */

  args = 0;
  XtSetArg(argList[args], XtNforeground, &fore); args++;
  XtSetArg(argList[args], XtNbackground, &back); args++;
  XtGetValues( tp -> forewardButton, argList, args);

  if (TeXMarkState( tp -> pageNumber ) ) {
    Arg argList[20];
    Cardinal args;

    args = 0;
    XtSetArg(argList[args], XtNforeground, back); args++;
    XtSetArg(argList[args], XtNbackground, fore); args++;

    XtSetValues( tp -> markButton, argList, args );
  }
  else {
    Arg argList[20];
    Cardinal args;

    args = 0;
    XtSetArg(argList[args], XtNforeground, fore); args++;
    XtSetArg(argList[args], XtNbackground, back); args++;

    XtSetValues( tp -> markButton, argList, args );
  }
}

static void
  pushForewardButton(w, clientData,  callData)
Widget w;
caddr_t clientData;	/* unused */
caddr_t callData; /* unused */
{
  TeXPage *tp = (TeXPage*) clientData; /*  */
  char *p;

  if (tp -> pageNumber >= DviTotalPages) {
    return;
  }
  else {
    if ( tp -> pageData != 0 ) {
      TeXPageDeref( tp -> pageNumber );
    }
    tp -> pageNumber++;
  }
  showPage(tp, True);
  if ( tp -> tied ) {
    pushForewardButton( tp -> tied, tp -> tied, 0 );
  }
} 

static void
  pushBackwardButton(w, clientData,  callData)
Widget w;
caddr_t clientData;	/* unused */
caddr_t callData; /* unused */
{
  TeXPage *tp = (TeXPage*) clientData;
  char *p;

  if ( tp -> tied ) {
    pushBackwardButton( tp -> tied, tp -> tied, 0 );
  }

  if ( tp -> pageNumber <= 0 ) {
    return;
  }
  else {
    if ( tp -> pageData != 0 ) {
      TeXPageDeref( tp -> pageNumber );
    }

    tp -> pageNumber--;
  }
  showPage(tp, True);
} 

static void
  pushMarkButton(w, clientData,  callData)
Widget w;
caddr_t clientData;	/* unused */
caddr_t callData; /* unused */
{
  TeXPage *tp = (TeXPage*) clientData;

  TeXMarkToggle( tp -> pageNumber );
  showPage(tp, False);
} 

static void
  pushDupButton(w, clientData,  callData)
Widget w;
caddr_t clientData;	/* unused */
caddr_t callData; /* unused */
{
  TeXPage *tp = (TeXPage *) clientData;
  TeXPage *newtp = TeXPageLocate();
  TeXPageRealize(newtp, tp -> pageNumber);
} 

static void
  pushTieButton(w, clientData,  callData)
Widget w;
caddr_t clientData;	/* unused */
caddr_t callData; /* unused */
{
  TeXPage *tp = (TeXPage *) clientData;
  if ( tp -> tied == 0 ) {
    TeXPage *newtp = TeXPageLocate();
    tp -> tied = newtp;
    newtp -> tiedTo = tp;
    TeXPageRealize(newtp, tp -> pageNumber);
  }
} 

/*
 *	The goto button. This scans, starting at the current page number,
 *	until a value of ``DviCount[0]'' meets the goto destination.
 *	This allows us to hit the multiple ``page 1'' refs.
 */
static void
  pushGotoButton(w, clientData,  callData)
Widget w;
caddr_t clientData;	/* unused */
caddr_t callData; /* unused */
{
  TeXPage *tp = (TeXPage*) clientData;

  char *pageNumber = tp -> pageNumberBuffer;
  if ( pageNumber != 0 && strlen( pageNumber ) > 0 ) {

    int want = atoi( pageNumber );
    int here = tp -> pageNumber;
    int page = here;

    for(;;) {
      page++;
      if ( page >= DviTotalPages ) {
	page = 0;
      }
      if ( page == here ) 
	return;

      if ( DviCount[0][page] == want ) {
	TeXPageDeref( tp -> pageNumber );
	tp -> pageNumber = page;
	TeXPageRef( tp -> pageNumber );
	showPage(tp, True);
	return;
      }
    }
  }
} 

void
changeMag( tp, mag )
TeXPage *tp;
int mag;
{
  Arg argList[20];
  Cardinal args;

  if ( mag > 0 && mag != tp -> userMag ) {
    XFontStruct **x;
    Dimension maxHt
      = (int) ((HeightOfScreen(XtScreen(TopLevelWidget))) * 0.90);
    Dimension maxWd
      = (int) ((WidthOfScreen(XtScreen(TopLevelWidget))) * 0.95);
    Dimension dviHt;
    Dimension dviWd;
    
    TeXFontUnref( tp -> userMag);
    
    tp -> userMag = mag; x = TeXFontRef(tp -> userMag);
    
    args = 0;
    XtSetArg(argList[args], XtNuserMag, tp -> userMag); args++;
    XtSetArg(argList[args], XtNxFonts, x); args++;
    XtSetValues( tp -> singleDviPage, argList, args);
    
    /* get the size of the dvi page */
    if ( TeXxResources.autoSize ) {
      args = 0; XtSetArg(argList[args], XtNwidth, &dviWd); args++;
      XtSetArg(argList[args], XtNheight, &dviHt); args++;
      XtGetValues( tp -> singleDviPage, argList, args);
      
      if ( dviWd <= maxWd ){
	maxWd = dviWd;

	/* will we need scrollbars? */

	if ( dviHt > maxHt ) {
	  ViewportWidget vp = (ViewportWidget) (tp -> viewPort);
	  maxWd = maxWd
	    + vp -> viewport.vert_bar -> core.width
	      + vp -> viewport.vert_bar -> core.border_width;
	}
      }
      if ( dviHt <= maxHt ) {
	maxHt = dviHt;
	if ( dviWd > maxWd ) {
	  ViewportWidget vp = (ViewportWidget) (tp -> viewPort);
	  maxHt = maxHt
	    + vp -> viewport.horiz_bar -> core.width
	      + vp -> viewport.horiz_bar -> core.border_width;
	}
      }
      
      args = 0;
      XtSetArg(argList[args], XtNwidth, maxWd); args++;
      XtSetArg(argList[args], XtNheight, maxHt); args++;
      XtSetValues( tp -> viewPort, argList, args);
    }
  }
}

static void
  pushMagButton(w, clientData, callData)
Widget w;
caddr_t clientData;
caddr_t callData;
{
  TeXPage *tp = (TeXPage *) clientData;
  int mag;

  mag = atoi( tp -> pageNumberBuffer );
  changeMag( tp, mag );
}

static void
  pushLargeButton(w, clientData,  callData)
Widget w;
caddr_t clientData;	/* unused */
caddr_t callData; /* unused */
{
  TeXPage *tp = (TeXPage *) clientData;
  changeMag( tp, TeXxResources.largeMag );
} 

static void
  pushSmallButton(w, clientData,  callData)
Widget w;
caddr_t clientData;	/* unused */
caddr_t callData; /* unused */
{
  TeXPage *tp = (TeXPage *) clientData;
  changeMag( tp, TeXxResources.smallMag );
} 

/*
 *	Realize the TeXPage structure and pop up the corresponding window
 */
void
TeXPageRealize(tp, pageNumber)
TeXPage *tp;
int pageNumber;
{
  Arg argList[20];
  int args;
  
  Dimension maxHt = (int) ((HeightOfScreen(XtScreen(TopLevelWidget))) * 0.90);
  Dimension maxWd = (int) ((WidthOfScreen(XtScreen(TopLevelWidget))) * 0.95);
  Dimension dviHt;
  Dimension dviWd;
  extern pushReopenButton();	/* from texx2-file */

  Dimension gap = 30;
  
  if ( tp == NULL ) {
    return;
  }
  
  assert(TopLevelWidget != 0);
  
  args = 0;
  XtSetArg(argList[args], XtNresize, True); args++;
  XtSetArg(argList[args], XtNallowShellResize, True); args++;
  tp -> popUpPage = 
    XtCreatePopupShell("TeXx2-Page-Display",
		       topLevelShellWidgetClass, TopLevelWidget,
		       argList,args);

  args = 0;
  XtSetArg(argList[args], XtNresize, True); args++;
  tp -> dviPageBox =
    XtCreateManagedWidget("dviPageBox",
			  formWidgetClass, tp -> popUpPage,
			  argList, args);

  args = 0;
  XtSetArg(argList[args], XtNresize, True); args++;
  XtSetArg(argList[args], XtNleft, XtChainLeft); args++;
  XtSetArg(argList[args], XtNtop, XtChainTop); args++;
  tp -> quitButton =
    XtCreateManagedWidget("Quit",
			  commandWidgetClass, tp -> dviPageBox,
			  argList, args);
  XtAddCallback(tp -> quitButton, XtNcallback, pushQuitButton, tp);

  args = 0;
  XtSetArg(argList[args], XtNresize, True); args++;
  XtSetArg(argList[args], XtNtop, XtChainTop); args++;
  XtSetArg(argList[args], XtNfromHoriz, tp -> quitButton); args++;
  XtSetArg(argList[args], XtNhorizDistance, gap); args++;
  tp -> forewardButton =
    XtCreateManagedWidget("Forward",
			  commandWidgetClass, tp -> dviPageBox,
			  argList, args);
  XtAddCallback(tp -> forewardButton, XtNcallback, pushForewardButton, tp);
  
  args = 0;
  XtSetArg(argList[args], XtNresize, True); args++;
  XtSetArg(argList[args], XtNtop, XtChainTop); args++;
  XtSetArg(argList[args], XtNfromHoriz, tp -> forewardButton); args++;
  tp -> backwardButton =
    XtCreateManagedWidget("Backward",
			  commandWidgetClass, tp -> dviPageBox,
			  argList, args);
  XtAddCallback(tp -> backwardButton, XtNcallback, pushBackwardButton, tp);
  
  args = 0;
  XtSetArg(argList[args], XtNresize, True); args++;
  XtSetArg(argList[args], XtNtop, XtChainTop); args++;
  XtSetArg(argList[args], XtNfromHoriz, tp -> backwardButton); args++;
  tp -> markButton =
    XtCreateManagedWidget("Mark",
			  commandWidgetClass, tp -> dviPageBox,
			  argList, args);
  XtAddCallback(tp -> markButton, XtNcallback, pushMarkButton, tp);

  args = 0;
  XtSetArg(argList[args], XtNresize, True); args++;
  XtSetArg(argList[args], XtNtop, XtChainTop); args++;
  XtSetArg(argList[args], XtNfromHoriz, tp -> markButton); args++;
  tp -> dupButton =
    XtCreateManagedWidget("Dup",
			  commandWidgetClass, tp -> dviPageBox,
			  argList, args);
  XtAddCallback(tp -> dupButton, XtNcallback, pushDupButton, tp);


  args = 0;
  XtSetArg(argList[args], XtNresize, True); args++;
  XtSetArg(argList[args], XtNtop, XtChainTop); args++;
  XtSetArg(argList[args], XtNfromHoriz, tp -> dupButton); args++;
  tp -> tieButton =
    XtCreateManagedWidget("Tied",
			  commandWidgetClass, tp -> dviPageBox,
			  argList, args);
  XtAddCallback(tp -> tieButton, XtNcallback, pushTieButton, tp);

  args = 0;
  XtSetArg(argList[args], XtNresize, True); args++;
  XtSetArg(argList[args], XtNtop, XtChainTop); args++;
  XtSetArg(argList[args], XtNfromHoriz, tp -> tieButton); args++;
  tp -> largeButton =
    XtCreateManagedWidget("Large",
			  commandWidgetClass, tp -> dviPageBox,
			  argList, args);
  XtAddCallback(tp -> largeButton, XtNcallback, pushLargeButton, tp);

  args = 0;
  XtSetArg(argList[args], XtNresize, True); args++;
  XtSetArg(argList[args], XtNtop, XtChainTop); args++;
  XtSetArg(argList[args], XtNfromHoriz, tp -> largeButton); args++;
  tp -> smallButton =
    XtCreateManagedWidget("Small",
			  commandWidgetClass, tp -> dviPageBox,
			  argList, args);
  XtAddCallback(tp -> smallButton, XtNcallback, pushSmallButton, tp);

  args = 0;
  XtSetArg(argList[args], XtNresize, True); args++;
  XtSetArg(argList[args], XtNtop, XtChainTop); args++;
  XtSetArg(argList[args], XtNfromHoriz, tp -> smallButton); args++;
  tp -> reopenButton = 
    XtCreateManagedWidget("Reopen",
			  commandWidgetClass, tp -> dviPageBox,
			  argList, args);
  XtAddCallback(tp -> reopenButton, XtNcallback, pushReopenButton, tp);


  args = 0;
  XtSetArg(argList[args], XtNresize, True); args++;
  XtSetArg(argList[args], XtNtop, XtChainTop); args++;
  XtSetArg(argList[args], XtNfromHoriz, tp -> reopenButton); args++;
  XtSetArg(argList[args], XtNhorizDistance, gap); args++;
  XtSetArg(argList[args], XtNeditType, XttextEdit); args++;
  XtSetArg(argList[args], XtNstring, tp -> pageNumberBuffer); args++;
  XtSetArg(argList[args], XtNlength, MAXPAGENUMBERBUFFER); args++;
  XtSetArg(argList[args], XtNtextOptions, resizeWidth); args++;
  XtSetArg(argList[args], XtNresizable,True); args++;
  tp -> pageNumberText =
    XtCreateManagedWidget("",
			  asciiStringWidgetClass, tp -> dviPageBox,
			  argList, args);

  args = 0;
  XtSetArg(argList[args], XtNresize, True); args++;
  XtSetArg(argList[args], XtNtop, XtChainTop); args++;
  XtSetArg(argList[args], XtNfromHoriz, tp -> pageNumberText); args++;
  tp -> gotoButton = 
    XtCreateManagedWidget("Goto",
			  commandWidgetClass, tp -> dviPageBox,
			  argList, args);
  XtAddCallback(tp -> gotoButton, XtNcallback, pushGotoButton, tp);
  
  args = 0;
  XtSetArg(argList[args], XtNresize, True); args++;
  XtSetArg(argList[args], XtNtop, XtChainTop); args++;
  XtSetArg(argList[args], XtNfromHoriz, tp -> gotoButton); args++;
  tp -> magButton = 
    XtCreateManagedWidget("Mag",
			  commandWidgetClass, tp -> dviPageBox,
			  argList, args);
  XtAddCallback(tp -> magButton, XtNcallback, pushMagButton, tp);

  args = 0;
  XtSetArg(argList[args], XtNresize, True); args++;
  XtSetArg(argList[args], XtNleft, XtChainLeft); args++;
  XtSetArg(argList[args], XtNfromVert, tp -> pageNumberText); args++;
  XtSetArg(argList[args], XtNresizable, True); args++;
  XtSetArg(argList[args], XtNallowHoriz, True); args++;
  XtSetArg(argList[args], XtNallowVert, True); args++;
  tp -> viewPort = 
    XtCreateWidget("ViewPort",
			  viewportWidgetClass, tp -> dviPageBox,
			  argList, args);

  bzero(tp -> pageNumberBuffer, MAXPAGENUMBERBUFFER);
  tp -> realized = True;
  tp -> pageNumber = pageNumber;
  tp -> pageData = TeXPageRef( tp -> pageNumber );
  tp -> userMag = TeXxResources.userMag;
  tp -> active = True;
  
  args = 0;
  XtSetArg(argList[args], XtNresize, True); args++;
  XtSetArg(argList[args], XtNpai, &ThePostAmbleInfo); args++;
  XtSetArg(argList[args], XtNdviFonts, TheFontInfo); args++;

  XtSetArg(argList[args], XtNdpi, TeXxResources.dpi ); args++;
  XtSetArg(argList[args], XtNpaperWidth,
	   TeXxResources.paperWidthString ); args++;
  XtSetArg(argList[args], XtNpaperHeight,
	   TeXxResources.paperHeightString ); args++;

  XtSetArg(argList[args], XtNpage, tp -> pageData); args++;
  XtSetArg(argList[args], XtNuserMag, tp -> userMag); args++;
  XtSetArg(argList[args], XtNxFonts, TeXFontRef(tp -> userMag)); args++;

  tp -> singleDviPage = 
    XtCreateWidget("DviPage",
			  dviPageWidgetClass, tp -> viewPort,
			  argList, args);

  XtAddCallback( tp -> singleDviPage, XtNdestroyCallback, dviPageDied, tp);

  /* get the size of the dvi page. This is an attempt to provide
     a nice default window size */

  args = 0;
  XtSetArg(argList[args], XtNwidth, &dviWd); args++;
  XtSetArg(argList[args], XtNheight, &dviHt); args++;
  XtGetValues( tp -> singleDviPage, argList, args);
  if ( dviWd < maxWd ){
    maxWd = dviWd;
  }
  if ( dviHt < maxHt ) {
    maxHt = dviHt;
  }
  args = 0;
  XtSetArg(argList[args], XtNwidth, maxWd); args++;
  XtSetArg(argList[args], XtNheight, maxHt); args++;
  XtSetValues( tp -> viewPort, argList, args);

  /* Now manage the viewport & single page */
  XtManageChild( tp -> singleDviPage );
  XtManageChild( tp -> viewPort );

  XtRealizeWidget(tp -> popUpPage);

  /* did we need scrollbars? */
    
  if ( dviWd <= maxWd ){
    maxWd = dviWd;
    
    if ( dviHt > maxHt ) {
      ViewportWidget vp = (ViewportWidget) (tp -> viewPort);
      maxWd = maxWd
	+ vp -> viewport.vert_bar -> core.width
	  + vp -> viewport.vert_bar -> core.border_width;
    }
  }
  if ( dviHt <= maxHt ) {
    maxHt = dviHt;
    if ( dviWd > maxWd ) {
      ViewportWidget vp = (ViewportWidget) (tp -> viewPort);
      maxHt = maxHt
	+ vp -> viewport.horiz_bar -> core.width
	  + vp -> viewport.horiz_bar -> core.border_width;
    }
  }
  
  args = 0;
  XtSetArg(argList[args], XtNwidth, maxWd); args++;
  XtSetArg(argList[args], XtNheight, maxHt); args++;
  XtSetValues( tp -> viewPort, argList, args);

  /* some bug somewhere makes the first page not appear unless I reset page */
  args = 0;
  XtSetArg(argList[args], XtNpage, tp -> pageData); args++;
  XtSetValues(tp -> singleDviPage, argList, args);

  showPage( tp, False );	/* set remaining buttons */

  XtPopup( tp -> popUpPage, XtGrabNone);
}

void
  TeXPageBuild()
{
  int i;
  
  TeXPage *tp = TeXPageLocate();
  
  if ( ! tp -> realized  ) {
    TeXPageRealize(tp, 0);
  }
}