🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: vmsnet.sources
Article #20

Ghostview for VMS 10/14

#20
From: Terry Poot
Date: Thu, 29 Oct 1992 18:49
1510 lines
48996 bytes
Submitted-by: Terry Poot <tp@mccall.com>
Posting-number: Volume 3, Issue 228
Archive-name: ghostview/part10

-+-+-+-+-+-+-+-+ START OF PART 10 -+-+-+-+-+-+-+-+
X          XBSDLIB = `09`09`09  -lXbsd
X
X LINTEXTENSIONLIB =  $(LINTLIBDIR)/llib-lXext.ln
X         LINTXLIB =  $(LINTLIBDIR)/llib-lX11.ln
X          LINTXMU =  $(LINTLIBDIR)/llib-lXmu.ln
X        LINTXTOOL =  $(LINTLIBDIR)/llib-lXt.ln
X          LINTXAW =  $(LINTLIBDIR)/llib-lXaw.ln
X           LINTXI =  $(LINTLIBDIR)/llib-lXi.ln
X        LINTPHIGS =  $(LINTLIBDIR)/llib-lphigs.ln
X
X          DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB)
X
X         DEPLIBS1 = $(DEPLIBS)
X         DEPLIBS2 = $(DEPLIBS)
X         DEPLIBS3 = $(DEPLIBS)
X
X# -------------------------------------------------------------------------
X# Imake rules for building libraries, programs, scripts, and data files
X# rules:  $XConsortium: Imake.rules,v 1.123 91/09/16 20:12:16 rws Exp $
X
X# -------------------------------------------------------------------------
X# start of Imakefile
X
X#  Imakefile -- Imakefile for ghostview.
X#  Copyright (C) 1992  Timothy O. Theisen
X#
X#  This program is free software; you can redistribute it and/or modify
X#  it under the terms of the GNU General Public License as published by
X#  the Free Software Foundation; either version 2 of the License, or
X#  (at your option) any later version.
X#
X#  This program is distributed in the hope that it will be useful,
X#  but WITHOUT ANY WARRANTY; without even the implied warranty of
X#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
X#  GNU General Public License for more details.
X#
X#  You should have received a copy of the GNU General Public License
X#  along with this program; if not, write to the Free Software
X#  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X#
X#    Author: Tim Theisen           Systems Programmer
X#  Internet: tim@cs.wisc.edu       Department of Computer Sciences
X#      UUCP: uwvax!tim             University of Wisconsin-Madison
X#     Phone: (608)262-0438         1210 West Dayton Street
X#       FAX: (608)262-9777         Madison, WI   53706
X
X           SRCS = main.c misc.c callbacks.c actions.c dialogs.c \
X                  Ghostview.c ps.c getenv.c setenv.c strcasecmp.c \
X                  SelFile.c Dir.c Path.c Draw.c
X           OBJS = main.o misc.o callbacks.o actions.o dialogs.o \
X                  Ghostview.o ps.o getenv.o setenv.o strcasecmp.o \
X                  SelFile.o Dir.o Path.o Draw.o
X SELFILE_DEFINE = -DSELFILE -DHOME_ON_DEMAND
X
X        DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB)
XLOCAL_LIBRARIES = $(XAWLIB) $(XMULIB) $(XTOOLLIB) $(XLIB)
X  SYS_LIBRARIES = -lm
X
X        DEFINES = -DNON_BLOCKING_IO $(SIGNAL_DEFINES) $(SELFILE_DEFINE)
X
X.NOEXPORT:
X
Xall:: ghostview
X
Xdepend:: app-defaults.h
X
X        PROGRAM = ghostview
X
Xall:: ghostview
X
Xghostview: $(OBJS) $(DEPLIBS)
X`09 $(RM) $@
X`09$(CC) -o $@ $(OBJS) $(LDOPTIONS) $(LOCAL_LIBRARIES) $(LDLIBS) $(EXTRA_LOA
VD_FLAGS)
X
Xinstall:: ghostview
X`09 @if `5B -d $(DESTDIR)$(BINDIR) `5D; then set +x; \
X`09`09else (set -x; $(MKDIRHIER) $(DESTDIR)$(BINDIR)); fi
X`09$(INSTALL) -c $(INSTPGMFLAGS)  ghostview $(DESTDIR)$(BINDIR)
X
Xinstall.man:: ghostview.man
X`09 @if `5B -d $(DESTDIR)$(MANDIR) `5D; then set +x; \
X`09`09else (set -x; $(MKDIRHIER) $(DESTDIR)$(MANDIR)); fi
X`09$(INSTALL) -c $(INSTMANFLAGS) ghostview.man $(DESTDIR)$(MANDIR)/ghostview
V.$(MANSUFFIX)
X
Xdepend::
X`09$(DEPEND) $(DEPENDFLAGS) -s "# DO NOT DELETE" -- $(ALLDEFINES) -- $(SRCS)
X
Xlint:
X`09$(LINT) $(LINTFLAGS) $(SRCS) $(LINTLIBS)
Xlint1:
X`09$(LINT) $(LINTFLAGS) $(FILE) $(LINTLIBS)
X
Xclean::
X`09$(RM) $(PROGRAM)
X
Xinstall:: Ghostview.ad
X`09 @if `5B -d $(DESTDIR)$(XAPPLOADDIR) `5D; then set +x; \
X`09`09else (set -x; $(MKDIRHIER) $(DESTDIR)$(XAPPLOADDIR)); fi
X`09$(INSTALL) -c $(INSTAPPFLAGS) Ghostview.ad $(DESTDIR)$(XAPPLOADDIR)/Ghost
Vview
X
Xmain.o: app-defaults.h
X
Xapp-defaults.h: Ghostview.ad
X`09./ad2c Ghostview.ad > app-defaults.h
X
Xclean::
X`09$(RM) app-defaults.h
X
X# -------------------------------------------------------------------------
X# common rules for all Makefiles - do not edit
X
Xemptyrule::
X
Xclean::
X`09$(RM_CMD) "#"*
X
XMakefile::
X`09-@if `5B -f Makefile `5D; then set -x; \
X`09`09$(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
X`09else exit 0; fi
X`09$(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR)
X
Xtags::
X`09$(TAGS) -w *.`5Bch`5D
X`09$(TAGS) -xw *.`5Bch`5D > TAGS
X
X# -------------------------------------------------------------------------
X# empty rules for directories that do not have SUBDIRS - do not edit
X
Xinstall::
X`09@echo "install in $(CURRENT_DIR) done"
X
Xinstall.man::
X`09@echo "install.man in $(CURRENT_DIR) done"
X
XMakefiles::
X
Xincludes::
X
X# -------------------------------------------------------------------------
X# dependencies generated by makedepend
X
X# DO NOT DELETE
X
Xmain.o: Ghostview.h
Xmain.o: gv.h
Xmain.o: ps.h app-defaults.h
Xmisc.o: Ghostview.h gv.h
Xmisc.o: ps.h
Xcallbacks.o: Ghostview.h gv.h
Xcallbacks.o: ps.h
Xactions.o: gv.h
Xactions.o: Ghostview.h ps.h
Xdialogs.o: gv.h
Xdialogs.o: Ghostview.h
XGhostview.o: GhostviewP.h Ghostview.h
Xps.o: ps.h
Xstrcasecmp.o: stdc.h
XSelFile.o: SFinternal.h
XDir.o: SFinternal.h
XPath.o: SFinternal.h
XPath.o: xstat.h
XDraw.o: SFinternal.h
XDraw.o: xstat.h
$ CALL UNPACK MAKEFILE.;1 1230381043
$ create 'f'
X/*
X * misc.c -- Everything that isn't a callback or action.
X * Copyright (C) 1992  Timothy O. Theisen
X *
X * This program is free software; you can redistribute it and/or modify
X * it under the terms of the GNU General Public License as published by
X * the Free Software Foundation; either version 2 of the License, or
X * (at your option) any later version.
X *
X * This program is distributed in the hope that it will be useful,
X * but WITHOUT ANY WARRANTY; without even the implied warranty of
X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
X * GNU General Public License for more details.
X *
X * You should have received a copy of the GNU General Public License
X * along with this program; if not, write to the Free Software
X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X *
X *   Author: Tim Theisen           Systems Programmer
X * Internet: tim@cs.wisc.edu       Department of Computer Sciences
X *     UUCP: uwvax!tim             University of Wisconsin-Madison
X *    Phone: (608)262-0438         1210 West Dayton Street
X *      FAX: (608)262-9777         Madison, WI   53706
X */
X
X#include <stdio.h>
X#ifndef SEEK_SET
X#define SEEK_SET 0
X#endif
X
X#include <X11/Xos.h>
X#include <signal.h>
X#ifdef SIGNALRETURNSINT
X#define SIGVAL int
X#else
X#define SIGVAL void
X#endif
X
X#include <math.h>
X
X#include <X11/Xatom.h>
X#include <X11/Intrinsic.h>
X#include <X11/StringDefs.h>
X#include <X11/Shell.h>
X#include <X11/Xaw/Cardinals.h>
X#include <X11/Xaw/Form.h>
X#include <X11/Xaw/SimpleMenu.h>
X#include <X11/Xaw/SmeBSB.h>
X#include <X11/Xaw/SmeLine.h>
X#include <X11/Xaw/Scrollbar.h>
X#include <X11/Xaw/AsciiText.h>
X/* Yuck, cannot get vScrollbar via the usual methods */
X#include <X11/IntrinsicP.h>
X#include <X11/Xaw/TextP.h>
X#include <X11/Xmu/StdCmap.h>
X
X#include <errno.h>
X/* BSD 4.3 errno.h does not declare errno */
Xextern int errno;
X#ifdef VMS
X#include <perror.h>
X#else
Xextern int sys_nerr;
Xextern char *sys_errlist`5B`5D;
X#endif
X
X#include "Ghostview.h"
X#include "gv.h"
X#include "ps.h"
X
X#ifndef max
X#define max(a, b)`09((a) > (b) ? (a) : (b))
X#endif
X
X/* Translate orientations defined by the enum in "ps.h" to
X * XtPageOrientations defined in "Ghostview.h".
X */
Xstatic XtPageOrientation
Xxorient(psorient)
X    int psorient;
X`7B
X    switch (psorient) `7B
X    case PORTRAIT: return XtPageOrientationPortrait;
X    case LANDSCAPE:
X`09if (app_res.swap_landscape) `7B
X`09    return XtPageOrientationSeascape;
X`09`7D else `7B
X`09    return XtPageOrientationLandscape;
X`09`7D
X    `7D
X`7D
X
Xstatic void
Xbreak_chains()
X`7B
X    Arg args`5B2`5D;
X    XtSetArg(args`5B0`5D, XtNbottom, XtChainTop);
X    XtSetArg(args`5B1`5D, XtNright, XtChainLeft);
X    XtSetValues(toc, args, ONE);
X    XtSetValues(pageview, args, TWO);
X`7D
X
Xstatic void
Xset_chains()
X`7B
X    Arg args`5B2`5D;
X
X    XtSetArg(args`5B0`5D, XtNbottom, XtChainBottom);
X    XtSetArg(args`5B1`5D, XtNright, XtChainRight);
X    XtSetValues(toc, args, ONE);
X    XtSetValues(pageview, args, TWO);
X`7D
X
Xstatic void
Xreset_size_hints()
X`7B
X    Arg args`5B4`5D;
X    if (app_res.ncdwm) return;
X    XtSetArg(args`5B0`5D, XtNmaxWidth, XtUnspecifiedShellInt);
X    XtSetArg(args`5B1`5D, XtNmaxHeight, XtUnspecifiedShellInt);
X    XtSetArg(args`5B2`5D, XtNminWidth, XtUnspecifiedShellInt);
X    XtSetArg(args`5B3`5D, XtNminHeight, XtUnspecifiedShellInt);
X    XtSetValues(toplevel, args, FOUR);
X`7D
X
Xstatic void
Xset_size_hints(minw, minh, maxw, maxh)
X    Dimension minw, minh, maxw, maxh;
X`7B
X    Arg args`5B4`5D;
X
X    XtSetArg(args`5B0`5D, XtNminWidth, minw);
X    XtSetArg(args`5B1`5D, XtNminHeight, minh);
X    XtSetArg(args`5B2`5D, XtNmaxWidth, maxw);
X    XtSetArg(args`5B3`5D, XtNmaxHeight, maxh);
X    XtSetValues(toplevel, args, FOUR);
X`7D
X
Xstatic Boolean horiz_scroll_saved = False;
Xstatic Boolean vert_scroll_saved = False;
Xstatic float horiz_top;
Xstatic float vert_top;
X
Xstatic void
Xreset_scroll_bars()
X`7B
X    Arg args`5B1`5D;
X    Widget scroll;
X    float zero = 0.0;
X   `20
X    if (horiz_scroll_saved `7C`7C vert_scroll_saved) return;
X
X    scroll = XtNameToWidget(pageview, "horizontal");
X    if (scroll) `7B
X`09XtSetArg(args`5B0`5D, XtNtopOfThumb, &horiz_top);
X`09XtGetValues(scroll, args, ONE);
X`09XtCallCallbacks(scroll, XtNjumpProc, &zero);
X`09horiz_scroll_saved = True;
X    `7D
X
X    scroll = XtNameToWidget(pageview, "vertical");
X    if (scroll) `7B
X`09XtSetArg(args`5B0`5D, XtNtopOfThumb, &vert_top);
X`09XtGetValues(scroll, args, ONE);
X`09XtCallCallbacks(scroll, XtNjumpProc, &zero);
X`09vert_scroll_saved = True;
X    `7D
X`7D
X
Xstatic void
Xset_scroll_bars()
X`7B
X    Arg args`5B1`5D;
X    Widget scroll;
X    float shown;
X
X    if (horiz_scroll_saved) `7B
X`09scroll = XtNameToWidget(pageview, "horizontal");
X`09if (scroll) `7B
X`09    XtSetArg(args`5B0`5D, XtNshown, &shown);
X`09    XtGetValues(scroll, args, ONE);
X`09    if (horiz_top > (1.0 - shown)) horiz_top = (1.0 - shown);
X`09    XtCallCallbacks(scroll, XtNjumpProc, &horiz_top);
X`09`7D
X    `7D
X
X    if (vert_scroll_saved) `7B
X`09scroll = XtNameToWidget(pageview, "vertical");
X`09if (scroll) `7B
X`09    XtSetArg(args`5B0`5D, XtNshown, &shown);
X`09    XtGetValues(scroll, args, ONE);
X`09    if (vert_top > (1.0 - shown)) vert_top = (1.0 - shown);
X`09    XtCallCallbacks(scroll, XtNjumpProc, &vert_top);
X`09`7D
X    `7D
X
X    horiz_scroll_saved = vert_scroll_saved = False;
X`7D
X
X/* Start rendering a new page */
Xvoid
Xshow_page(number)
X    int number;
X`7B
X    struct stat sbuf;
X    int i;
X
X    if (!filename) return;
X
X    /* Unmark current_page as current */
X    if (toc_text && (current_page >= 0)) `7B
X`09int marker = current_page*toc_entry_length + toc_entry_length-2;
X`09toc_text`5Bmarker`5D = ' ';
X`09XawTextInvalidate(toc, marker, marker+1);
X    `7D
X
X    /* If the file has changed, rescan it so that offsets into the file
X     * are still correct.  If the file is rescanned, we must setup ghostview
X     * again.  Also, force a new copy of ghostscript to start. */
X    if (psfile) `7B
X`09if (!stat(filename, &sbuf) && mtime != sbuf.st_mtime) `7B
X`09    fclose(psfile);
X`09    psfile = fopen(filename, "r");
X`09    mtime = sbuf.st_mtime;
X`09    if (oldfilename) XtFree(oldfilename);
X`09    oldfilename = XtNewString(filename);
X`09    new_file(number);
X`09`7D
X    `7D
X
X    /* Coerce page number to fall in range */
X    if (toc_text) `7B
X`09if (number >= doc->numpages) number = doc->numpages - 1;
X`09if (number < 0) number = 0;
X    `7D
X
X    if (set_new_orientation(number) `7C`7C set_new_pagemedia(number))
X`09layout_ghostview();
X
X    if (toc_text) `7B
X`09int marker;
X`09current_page = number;
X`09XawTextUnsetSelection(toc);
X`09XawTextSetInsertionPoint(toc, current_page * toc_entry_length);
X`09marker = current_page*toc_entry_length + toc_entry_length-2;
X`09toc_text`5Bmarker`5D = '<';
X`09XawTextInvalidate(toc, marker, marker+1);
X`09if (GhostviewIsInterpreterReady(page)) `7B
X`09    GhostviewNextPage(page);
X`09`7D else `7B
X`09    GhostviewEnableInterpreter(page);
X`09    GhostviewSendPS(page, psfile, doc->beginprolog,
X`09`09`09    doc->lenprolog, False);
X`09    GhostviewSendPS(page, psfile, doc->beginsetup,
X`09`09`09    doc->lensetup, False);
X`09`7D
X`09if (doc->pageorder == DESCEND)
X`09    i = (doc->numpages - 1) - current_page;
X`09else
X`09    i = current_page;
X`09GhostviewSendPS(page, psfile, doc->pages`5Bi`5D.begin,
X`09`09`09doc->pages`5Bi`5D.len, False);
X    `7D else `7B
X`09if (!GhostviewIsInterpreterRunning(page))
X`09    GhostviewEnableInterpreter(page);
X`09else if (GhostviewIsInterpreterReady(page))
X`09    GhostviewNextPage(page);
X`09else
X`09    XBell(XtDisplay(page), 0);
X    `7D
X
X    if (toc_text) `7B
X`09XtSetSensitive(prevbutton, current_page != 0);
X`09XtSetSensitive(nextbutton, current_page != doc->numpages-1);
X`09XtSetSensitive(showbutton, True);
X    `7D
X`7D
X
X/* setup ghostview.  This includes:
X *  scanning the PostScript file,
X *  setting the title and date labels,
X *  building the pagemedia menu,
X *  building the toc (table of contents)
X *  sensitizing the appropriate menu buttons,
X *  popping down and erasing the infotext popup.
X */
X
Xstatic Boolean useful_page_labels;
XBoolean
Xsetup_ghostview()
X`7B
X    Arg args`5B20`5D;
X    Cardinal num_args;
X    int oldtoc_entry_length;
X    char *tocp;
X    XawTextBlock message_block;
X    static String nothing = "";
X    String label;
X    Pixmap bitmap;
X
X    /* Reset to a known state. */
X    psfree(olddoc);
X    olddoc = doc;
X    doc = NULL;
X    current_page = -1;
X    if (toc_text) XtFree(toc_text);
X    oldtoc_entry_length = toc_entry_length;
X    toc_text = NULL;
X
X    /* Scan document and start setting things up */
X    if (psfile) doc = psscan(psfile);
X
X    if (app_res.show_title) `7B
X`09if (doc && doc->title) `7B
X`09    label = doc->title;
X`09    bitmap = menu16_bitmap;
X`09`7D else `7B
X`09    if (filename) `7B
X`09`09label = filename;
X`09    `7D else `7B
X`09`09label = "";
X`09    `7D
X`09    bitmap = None;
X`09`7D
X`09XtSetArg(args`5B0`5D, XtNlabel, label);
X`09XtSetValues(titlebutton, args, ONE);
X`09if (titlemenu) XtDestroyWidget(titlemenu);
X`09titlemenu = build_label_menu(titlebutton, "title", label, bitmap);
X    `7D
X
X    if (app_res.show_date) `7B
X`09if (doc && doc->date) `7B
X`09    label = doc->date;
X`09    bitmap = menu16_bitmap;
X`09`7D else `7B
X`09    if (psfile) `7B
X`09`09label = ctime(&mtime);
X`09    `7D else `7B
X`09`09label = "";
X`09    `7D
X`09    bitmap = None;
X`09`7D
X`09XtSetArg(args`5B0`5D, XtNlabel, label);
X`09XtSetValues(datebutton, args, ONE);
X`09if (datemenu) XtDestroyWidget(datemenu);
X`09datemenu = build_label_menu(datebutton, "date", label, bitmap);
X    `7D
X
X    build_pagemedia_menu();
X
X    /* Reset ghostscript and output messages popup */
X    if (!doc `7C`7C !olddoc `7C`7C
X`09strcmp(oldfilename, filename) `7C`7C
X`09olddoc->beginprolog != doc->beginprolog `7C`7C
X`09olddoc->endprolog != doc->endprolog `7C`7C
X`09olddoc->beginsetup != doc->beginsetup `7C`7C
X`09olddoc->endsetup != doc->endsetup) `7B
X
X`09GhostviewDisableInterpreter(page);
X`09XtPopdown(infopopup);
X`09info_up = False;
X`09XtSetArg(args`5B0`5D, XtNeditType, XawtextEdit);
X`09XtSetArg(args`5B1`5D, XtNinsertPosition, 0);
X`09XtSetValues(infotext, args, TWO);
X`09message_block.length = 0;
X`09XawTextReplace(infotext, 0, info_length, &message_block);
X`09info_length = 0;
X`09XtSetArg(args`5B0`5D, XtNeditType, XawtextRead);
X`09XtSetValues(infotext, args, ONE);
X    `7D
X
X    /* Build table of contents */
X    if (doc && (!doc->epsf && doc->numpages > 0 `7C`7C
X`09`09 doc->epsf && doc->numpages > 1)) `7B
X`09int maxlen = 0;
X`09int i, j;
X`09useful_page_labels = False;
X
X`09if (doc->numpages == 1) useful_page_labels = True;
X`09for (i = 1; i < doc->numpages; i++)
X`09    if (useful_page_labels = (useful_page_labels `7C`7C
X`09`09    strcmp(doc->pages`5Bi-1`5D.label, doc->pages`5Bi`5D.label))) break
V;
X`09if (useful_page_labels) `7B
X`09    for (i = 0; i < doc->numpages; i++)`20
X`09`09maxlen = max(maxlen, strlen(doc->pages`5Bi`5D.label));
X`09`7D else `7B
X`09    double x;
X`09    x = doc->numpages;
X`09    maxlen = log10(x) + 1;
X`09`7D
X`09toc_entry_length = maxlen + 3;
X`09toc_length = doc->numpages * toc_entry_length - 1;
X`09toc_text = XtMalloc(toc_length + 2); /* include final NULL */
X
X`09for (i = 0, tocp = toc_text; i < doc->numpages;
X`09     i++, tocp += toc_entry_length) `7B
X`09    if (useful_page_labels) `7B
X`09`09if (doc->pageorder == DESCEND) `7B
X`09`09    j = (doc->numpages - 1) - i;
X`09`09`7D else `7B
X`09`09    j = i;
X`09`09`7D
X`09`09sprintf(tocp, " %*s \n", maxlen, doc->pages`5Bj`5D.label);
X`09    `7D else `7B
X`09`09sprintf(tocp, " %*d \n", maxlen, i+1);
X`09    `7D
X`09`7D
X`09toc_text`5Btoc_length`5D = '\0';
X`09`09`09`09`09`09`09      `09num_args = 0;
X`09XtSetArg(args`5Bnum_args`5D, XtNfilename, NULL);      `09num_args++;
X`09XtSetValues(page, args, num_args);
X    `7D else `7B
X`09toc_length = 0;
X`09toc_entry_length = 3;
X`09`09`09`09`09`09`09      `09num_args = 0;
X`09XtSetArg(args`5Bnum_args`5D, XtNfilename, filename);      `09num_args++;
X`09XtSetValues(page, args, num_args);
X    `7D
X`09`09`09`09`09`09`09`09num_args = 0;
X    XtSetArg(args`5Bnum_args`5D, XtNlength, toc_length);`09`09num_args++;
X    if (toc_text) `7B
X`09XtSetArg(args`5Bnum_args`5D, XtNstring, toc_text);`09`09num_args++;
X    `7D else `7B
X`09/* Text widget sometime blows up when given a NULL pointer */
X`09XtSetArg(args`5Bnum_args`5D, XtNstring, nothing);`09`09num_args++;
X    `7D
X    XtSetValues(toc, args, num_args);
X
X    XtSetSensitive(reopenbutton, (psfile != NULL));
X    XtSetSensitive(printwholebutton, (psfile != NULL));
X    XtSetSensitive(printmarkedbutton, (psfile != NULL));
X    XtSetSensitive(savebutton, (toc_text != NULL));
X    XtSetSensitive(nextbutton, (filename != NULL));
X    XtSetSensitive(showbutton, (filename != NULL));
X    XtSetSensitive(prevbutton, (toc_text != NULL));
X    XtSetSensitive(centerbutton, (filename != NULL));
X    XtSetSensitive(markbutton, (toc_text != NULL));
X    XtSetSensitive(unmarkbutton, (toc_text != NULL));
X
X    return oldtoc_entry_length != toc_entry_length;
X`7D
X
Xint
Xfind_page(label)
X    String label;
X`7B
X    int i, j;
X
X    if (label == NULL `7C`7C doc == NULL) return 0;
X
X    if (useful_page_labels) `7B
X`09for (i = 0; i < doc->numpages; i++) `7B
X`09    if (doc->pageorder == DESCEND) `7B
X`09`09j = (doc->numpages - 1) - i;
X`09    `7D else `7B
X`09`09j = i;
X`09    `7D
X`09    if (!strcmp(label, doc->pages`5Bj`5D.label)) return i;
X`09`7D
X`09return 0;
X    `7D else `7B
X`09return atoi(label) - 1;
X    `7D
X`7D
X
X/* try_try_again sets the geometry of the form when the form failed
X * to do it earlier.  It uses activity check with exponential backoff
X * to make sure that the dust has settled before trying again.
X */
Xstatic unsigned int delay = 125;`09/* Start with 1/8 second delay */
X
Xstatic void
Xtry_try_again(client_data, timer)
X    XtPointer client_data;
X    XtIntervalId *timer;
X`7B
X    XSync(XtDisplay(toplevel), False);
X    if (XtAppPending(app_con)) `7B
X`09XtAppAddTimeOut(app_con, delay, try_try_again, NULL);
X`09/* fprintf(stderr, "Delaying(%d)...\n",delay); */
X`09delay *= 2;
X    `7D else `7B
X`09/* fprintf(stderr, "Trying again...\n"); */
X`09layout_ghostview();
X    `7D
X`7D
X
X/* set the dimensions for items in the main form widget. */
X/* set foreground and background color in scrollbars. */
X/* (The scroll bars come and go as size changes.) */
X/* Set window manager hints to keep window manager from causing main */
X/* viewport from growing too large */
Xvoid
Xlayout_ghostview()
X`7B
X    Arg args`5B20`5D;
X    Cardinal num_args;
X    Widget w;
X    /* Yuck, cannot get vScrollbar via the usual methods */
X    TextWidget tw;
X    Dimension min_width, min_height;
X    Dimension max_width, max_height;
X    Dimension form_width, form_height;
X    Dimension title_height, title_border;
X    Dimension date_height, date_border;
X    Dimension locator_height, locator_border;
X    Dimension box_width, box_height, box_border;
X    Dimension label_width;
X    Dimension toc_width, toc_height, toc_border;
X    Dimension view_width, view_height, view_border;
X    Dimension page_width, page_height;
X    Dimension leftMargin, rightMargin;
X    Dimension width, height;
X    Boolean correct = True;
X    int distance;
X    int a_label;
X    XFontStruct *font;
X
X    XawFormDoLayout(form, False);
X    reset_size_hints();
X    reset_scroll_bars();
X    break_chains();
X
X    XtSetArg(args`5B0`5D, XtNdefaultDistance, &distance);
X    XtGetValues(form, args, ONE);
X
X    a_label = 0;
X    if (app_res.show_title) `7B
X`09XtSetArg(args`5B0`5D, XtNheight, &title_height);
X`09XtSetArg(args`5B1`5D, XtNborderWidth, &title_border);
X`09XtGetValues(titlebutton, args, TWO);
X`09a_label = 1;
X    `7D else `7B
X`09title_height = title_border = 0;
X    `7D
X
X    if (app_res.show_date) `7B
X`09XtSetArg(args`5B0`5D, XtNheight, &date_height);
X`09XtSetArg(args`5B1`5D, XtNborderWidth, &date_border);
X`09XtGetValues(datebutton, args, TWO);
X`09a_label = 1;
X    `7D else `7B
X`09date_height = date_border = 0;
X    `7D
X
X    if (app_res.show_locator) `7B
X`09XtSetArg(args`5B0`5D, XtNheight, &locator_height);
X`09XtSetArg(args`5B1`5D, XtNborderWidth, &locator_border);
X`09XtGetValues(locator, args, TWO);
X`09a_label = 1;
X    `7D else `7B
X`09locator_height = locator_border = 0;
X    `7D
X
X    XtSetArg(args`5B0`5D, XtNwidth, &box_width);
X    XtSetArg(args`5B1`5D, XtNheight, &box_height);
X    XtSetArg(args`5B2`5D, XtNborderWidth, &box_border);
X    XtGetValues(box, args, THREE);
X
X    XtSetArg(args`5B0`5D, XtNfont, &font);
X    XtSetArg(args`5B1`5D, XtNleftMargin, &leftMargin);
X    XtSetArg(args`5B2`5D, XtNrightMargin, &rightMargin);
X    XtSetArg(args`5B3`5D, XtNborderWidth, &toc_border);
X    XtGetValues(toc, args, FOUR);
X    toc_width = font->max_bounds.width * (toc_entry_length - 1) +
X`09`09leftMargin + rightMargin;
X
X    XtSetArg(args`5B0`5D, XtNwidth, &page_width);
X    XtSetArg(args`5B1`5D, XtNheight, &page_height);
X    XtGetValues(page, args, TWO);
X
X    XtSetArg(args`5B0`5D, XtNborderWidth, &view_border);
X    XtGetValues(pageview, args, ONE);
X    view_width = page_width;
X    view_height = page_height;
X
X    min_width = box_width + 2*box_border + toc_width + 2*toc_border +
X`09`092*view_border + 4*distance;
X    min_height = title_height + 2*title_border + date_height + 2*date_border
V +
X`09`09 locator_height + 2*locator_border + box_height + 2*box_border +
X`09`09 (2+a_label)*distance;
X
X    max_width = WidthOfScreen(XtScreen(toplevel)) - app_res.wm_horiz_margin;
X    max_height = HeightOfScreen(XtScreen(toplevel)) - app_res.wm_vert_margin
V;
X
X    if (min_width + view_width > max_width)
X`09view_width = max_width - min_width;
X    if (2*(view_border + distance) + view_height > max_height)
X`09view_height = max_height - 2*(view_border + distance);
X    form_width = view_width + min_width;
X    form_height = max(view_height + 2*(view_border + distance), min_height);
X    toc_height = view_height - (title_height + 2*title_border +
X`09`09`09`09date_height + 2*date_border +
X`09`09`09`09locator_height + 2*locator_border +
X`09`09`09`09a_label*distance);
X
X    label_width = box_width + 2*box_border + distance +
X`09`09  toc_width + 2*toc_border;
X
X    XtSetArg(args`5B0`5D, XtNwidth, form_width);
X    XtSetArg(args`5B1`5D, XtNheight, form_height);
X    XtSetValues(form, args, TWO);
X
X    XtSetArg(args`5B0`5D, XtNwidth, label_width);
X    if (app_res.show_title) XtSetValues(titlebutton, args, ONE);
X    if (app_res.show_date) XtSetValues(datebutton, args, ONE);
X    if (app_res.show_locator) XtSetValues(locator, args, ONE);
X
X    XtSetArg(args`5B0`5D, XtNwidth, toc_width);
X    XtSetArg(args`5B1`5D, XtNheight, toc_height);
X    XtSetValues(toc, args, TWO);
X
X    XtSetArg(args`5B0`5D, XtNwidth, view_width);
X    XtSetArg(args`5B1`5D, XtNheight, view_height);
X    XtSetValues(pageview, args, TWO);
X
X    XawFormDoLayout(form, True);
X
X    /* Check to make sure everything was done as planned. */
X    XtSetArg(args`5B0`5D, XtNwidth, &width);
X    XtSetArg(args`5B1`5D, XtNheight, &height);
X
X    XtGetValues(form, args, TWO);
X    if (width != form_width `7C`7C height != form_height) `7B
X`09correct = False;
X`09/* fprintf(stderr, "Oops, %dx%d form was supposed to be %dx%d.\n",
X`09`09width, height, form_width, form_height); */
X    `7D
X    if (app_res.show_title) `7B
X`09XtGetValues(titlebutton, args, ONE);
X`09if (width != label_width) `7B
X`09    correct = False;
X`09    /* fprintf(stderr,
X`09`09"Oops, %d wide title was supposed to be %d wide.\n",
X`09`09width, label_width); */
X`09`7D
X    `7D
X    if (app_res.show_date) `7B
X`09XtGetValues(datebutton, args, ONE);
X`09if (width != label_width) `7B
X`09    correct = False;
X`09    /* fprintf(stderr,
X`09`09"Oops, %d wide date was supposed to be %d wide.\n",
X`09`09width, label_width); */
X`09`7D
X    `7D
X    if (app_res.show_locator) `7B
X`09XtGetValues(locator, args, ONE);
X`09if (width != label_width) `7B
X`09    correct = False;
X`09    /* fprintf(stderr,
X`09`09"Oops, %d wide locator was supposed to be %d wide.\n",
X`09`09width, label_width); */
X`09`7D
X    `7D
X    XtGetValues(toc, args, TWO);
X    if (width != toc_width `7C`7C height != toc_height) `7B
X`09correct = False;
X`09/* fprintf(stderr, "Oops, %dx%d toc was supposed to be %dx%d.\n",
X`09`09width, height, toc_width, toc_height); */
X    `7D
X    XtGetValues(pageview, args, TWO);
X    if (width != view_width `7C`7C height != view_height) `7B
X`09correct = False;
X`09/* fprintf(stderr, "Oops, %dx%d pageview was supposed to be %dx%d.\n",
X`09`09width, height, view_width, view_height); */
X    `7D
X
X    if (correct) `7B
X`09if (special_cmap) `7B
X`09    /* Yuck, cannot get vScrollbar via the usual methods */
X`09    /* w = XtNameToWidget(toc, "*vScrollbar"); */
X`09    tw = (TextWidget) toc;
X`09    w = tw->text.vbar;
X`09    if (w) `7B
X`09`09/* Double Yuck, have to set them twice to make them */
X`09`09/* get the right colors */
X`09`09`09`09`09`09`09`09num_args = 0;
X`09`09XtSetArg(args`5Bnum_args`5D, XtNforeground, white);`09num_args++;
X`09`09XtSetArg(args`5Bnum_args`5D, XtNbackground, black);`09num_args++;
X`09`09XtSetValues(w, args, num_args);
X`09`09`09`09`09`09`09`09num_args = 0;
X`09`09XtSetArg(args`5Bnum_args`5D, XtNforeground, black);`09num_args++;
X`09`09XtSetArg(args`5Bnum_args`5D, XtNbackground, white);`09num_args++;
X`09`09XtSetValues(w, args, num_args);
X`09    `7D
X
X`09    w = XtNameToWidget(pageview, "horizontal");
X`09    if (w) `7B
X`09`09`09`09`09`09`09`09num_args = 0;
X`09`09XtSetArg(args`5Bnum_args`5D, XtNforeground, black);`09num_args++;
X`09`09XtSetArg(args`5Bnum_args`5D, XtNbackground, white);`09num_args++;
X`09`09XtSetValues(w, args, num_args);
X`09    `7D
X
X`09    w = XtNameToWidget(pageview, "vertical");
X`09    if (w) `7B
X`09`09`09`09`09`09`09`09num_args = 0;
X`09`09XtSetArg(args`5Bnum_args`5D, XtNforeground, black);`09num_args++;
X`09`09XtSetArg(args`5Bnum_args`5D, XtNbackground, white);`09num_args++;
X`09`09XtSetValues(w, args, num_args);
X`09    `7D
X`09`7D
X
X`09set_size_hints(min_width, min_height, min_width+page_width,
X`09`09       max(form_height,
X`09`09`09   page_height + 2*(view_border + distance)));
X`09if (app_res.auto_center) `7B
X`09    horiz_scroll_saved = vert_scroll_saved = False;
X`09    center_page(form, NULL, NULL);
X`09`7D else `7B
X`09    set_scroll_bars();
X`09`7D
X`09set_chains();
X`09delay = 125;`09/* Reset to 1/8 second delay */
X`09/* fprintf(stderr, "Layout correct.\n"); */
X    `7D else `7B
X`09XSync(XtDisplay(toplevel), False);
X`09XtAppAddTimeOut(app_con, delay, try_try_again, NULL);
X`09/* fprintf(stderr, "Didn't work, scheduling(%d)...\n",delay); */
X    `7D
X
X`7D
X
X/* Create a Standard colormap for ghostscript to use. */
Xvoid
XSetStandardColormap(w)
X    Widget w;
X`7B
X    XVisualInfo xvinfo;
X    XVisualInfo *xvinfop;
X    Atom prop;
X    XStandardColormap *std_cmap = NULL;
X    XStandardColormap *scmap, *sp;
X    Screen *scr = DefaultScreenOfDisplay(XtDisplay(w));
X    int nitems, i;
X    Boolean has_color;
X    Arg args`5B20`5D;
X    Cardinal num_args;
X
X    XtSetArg(args`5B0`5D, XtNvisual, &(xvinfo.visual));
X    XtGetValues(w, args, ONE);
X    if (xvinfo.visual == CopyFromParent)
X`09xvinfo.visual = DefaultVisualOfScreen(scr);
X    xvinfo.visualid = XVisualIDFromVisual(xvinfo.visual);
X    xvinfop = XGetVisualInfo(XtDisplay(w), VisualIDMask, &xvinfo, &nitems);
X    if (xvinfop == NULL) `7B
X        fprintf(stderr, "Bad visual class.\n");
X`09exit(1);
X    `7D
X    xvinfo = *xvinfop;
X    XtFree((char *)xvinfop);
X
X    has_color = (xvinfo.class != StaticGray) && (xvinfo.class != GrayScale);
X
X    if (has_color) `7B
X`09if (xvinfo.visual == DefaultVisualOfScreen(scr)) `7B
X`09    prop = XA_RGB_DEFAULT_MAP;
X`09`7D else `7B
X`09    prop = XA_RGB_BEST_MAP;
X`09`7D
X    `7D else `7B
X`09prop = XA_RGB_GRAY_MAP;
X    `7D
X
X    if (XGetRGBColormaps(XtDisplay(w), RootWindowOfScreen(scr),
X`09`09`09 &scmap, &nitems, prop)) `7B
X`09for (i = 0, sp = scmap; i < nitems; i++, sp++) `7B
X`09    if (xvinfo.visualid == sp->visualid) `7B
X`09`09std_cmap = sp;
X`09`09break;
X`09    `7D
X`09`7D
X    `7D
X
X    if (!std_cmap && app_res.install_std_cmap) `7B
X`09if (XmuLookupStandardColormap(XtDisplay(w),
X`09`09`09`09      DefaultScreen(XtDisplay(w)),
X`09`09`09`09      xvinfo.visualid, xvinfo.depth,
X`09`09`09`09      prop, False, app_res.retain_std_cmap)) `7B
X`09    if (XGetRGBColormaps(XtDisplay(w), RootWindowOfScreen(scr),
X`09`09`09`09 &scmap, &nitems, prop)) `7B
X`09`09for (i = 0, sp = scmap; i < nitems; i++, sp++) `7B
X`09`09    if (xvinfo.visualid == sp->visualid) `7B
X`09`09`09std_cmap = sp;
X`09`09    `7D
X`09`09`7D
X`09    `7D
X`09`7D
X    `7D
X
X    if (std_cmap && xvinfo.visual == DefaultVisualOfScreen(scr) &&
X`09std_cmap->colormap != DefaultColormapOfScreen(scr) &&
X`09!app_res.private_cmap) `7B
X`09std_cmap = NULL;
X    `7D
X    if (std_cmap) `7B
X`09cmap = std_cmap->colormap;
X`09if (std_cmap->colormap != DefaultColormapOfScreen(scr)) `7B
X`09    black = std_cmap->base_pixel;
X`09    white = std_cmap->red_max * std_cmap->red_mult +
X`09`09    std_cmap->green_max * std_cmap->green_mult +
X`09`09    std_cmap->blue_max * std_cmap->blue_mult +
X`09`09    std_cmap->base_pixel;
X`09`7D else `7B
X`09    white = WhitePixelOfScreen(scr);
X`09    black = BlackPixelOfScreen(scr);
X`09`7D
X    `7D else `7B
X`09if (xvinfo.visual == DefaultVisualOfScreen(scr)) `7B
X`09    cmap = DefaultColormapOfScreen(scr);
X`09    white = WhitePixelOfScreen(scr);
X`09    black = BlackPixelOfScreen(scr);
X`09`7D else `7B
X`09    XColor c;
X`09    cmap = XCreateColormap(XtDisplay(w), RootWindowOfScreen(scr),
X`09`09`09`09   xvinfo.visual, AllocNone);
X`09    c.red = c.green = c.blue = `7E(unsigned short)0;
X`09    XAllocColor(XtDisplay(w), cmap, &c);
X`09    white = c.pixel;
X`09    c.red = c.green = c.blue = 0;
X`09    XAllocColor(XtDisplay(w), cmap, &c);
X`09    black = c.pixel;
X`09`7D
X    `7D
X    special_cmap = cmap != DefaultColormapOfScreen(scr);
X
X`09`09`09`09`09`09`09num_args = 0;
X    XtSetArg(args`5Bnum_args`5D, XtNcolormap, cmap);`09num_args++;
X    if (special_cmap) `7B
X`09XtSetArg(args`5Bnum_args`5D, XtNforeground, black);`09num_args++;
X`09XtSetArg(args`5Bnum_args`5D, XtNbackground, white);`09num_args++;
X    `7D
X    XtSetValues(w, args, num_args);
X`7D
X
X/* Compute new dpi from magstep */
Xvoid
Xmagnify(dpi, magstep)
X    float *dpi;
X    int    magstep;
X`7B
X    if (magstep < 0) `7B
X`09while (magstep++) *dpi /= 1.2;
X    `7D else `7B
X`09while (magstep--) *dpi *= 1.2;
X    `7D
X`7D
X
X/* Attempt to open file, return error message string on failure */
XString
Xopen_file(name)
X    String name;
X`7B
X    FILE *fp;
X    struct stat sbuf;
X
X    if (*name == '\0') `7B`09/* Null filename */
X`09return(NULL);
X    `7D
X    if (strcmp(name, "-")) `7B
X`09if ((fp = fopen(name, "r")) == NULL) `7B
X`09    String buf = XtMalloc(strlen(app_res.open_fail) +
X`09`09`09`09  strlen(sys_errlist`5Berrno`5D) + 1);
X`09    strcpy(buf, app_res.open_fail);
X`09    if (errno <= sys_nerr) strcat(buf, sys_errlist`5Berrno`5D);
X`09    return buf;
X`09`7D else `7B
X`09    if (oldfilename) XtFree(oldfilename);
X`09    oldfilename = filename;
X`09    filename = XtNewString(name);
X`09    if (psfile) fclose(psfile);
X`09    psfile = fp;
X`09    stat(filename, &sbuf);
X`09    mtime = sbuf.st_mtime;
X`09    new_file(0);
X`09    show_page(0);
X`09    return(NULL);
X`09`7D
X    `7D else `7B
X`09if (oldfilename) XtFree(oldfilename);
X`09oldfilename = filename;
X`09filename = XtNewString(name);
X`09if (psfile) fclose(psfile);
X`09psfile = NULL;
X`09new_file(0);
X`09show_page(0);
X`09return(NULL);
X    `7D
X`7D
X
X/* Attempt to save file, return error message string on failure */
XString
Xsave_file(name)
X    String name;
X`7B
X    FILE *pswrite;
X
X    if (*name == '\0') `7B`09/* Null filename */
X`09return(NULL);
X    `7D
X    if ((pswrite = fopen(name, "w")) == NULL) `7B
X`09String buf = XtMalloc(strlen(app_res.save_fail) +
X`09`09`09      strlen(sys_errlist`5Berrno`5D) + 1);
X`09strcpy(buf, app_res.save_fail);
X`09if (errno <= sys_nerr) strcat(buf, sys_errlist`5Berrno`5D);
X`09return buf;
X    `7D else `7B
X`09pscopydoc(pswrite);
X`09fclose(pswrite);
X`09return(NULL);
X    `7D
X`7D
X
X/* Attempt to print file.  Return error string on failure */`20
XString
Xprint_file(name, whole_mode)
X    String name;
X    Boolean whole_mode;
X`7B
X    FILE *printer;
X    SIGVAL (*oldsig)();
X    int bytes;
X    char buf`5BBUFSIZ`5D;
X#ifdef VMS
X    char fnam`5B64`5D, *p;
X#endif
X    Boolean failed;
X    String ret_val;
X
X#ifdef VMS
X    sprintf(fnam, "sys$scratch:%s.tmp", tmpnam(NULL));
X    printer = fopen(fnam, "w");
X#else /* VMS */
X    if (*name != '\0') `7B
X`09setenv(app_res.printer_variable, name, True);
X    `7D
X    oldsig = signal(SIGPIPE, SIG_IGN);
X    printer = popen(app_res.print_command, "w");
X#endif /* VMS */
X    if (toc_text && !whole_mode) `7B
X`09pscopydoc(printer);
X    `7D else `7B
X`09FILE *psfile = fopen(filename, "r");
X`09while (bytes = read(fileno(psfile), buf, BUFSIZ))
X`09    bytes = write(fileno(printer), buf, bytes);
X`09fclose(psfile);
X    `7D
X#ifdef VMS
X    sprintf(buf, "%s %s %s", app_res.print_command, name, fnam);
X    failed = fclose(printer) != 0 `7C`7C system(buf) != 1;
X#else /* VMS */
X    failed = pclose(printer) != 0;
X#endif /* VMS */
X    if (failed) `7B
X`09sprintf(buf, app_res.print_fail, app_res.print_command);
X`09ret_val = XtNewString(buf);
X    `7D else `7B
X`09ret_val = NULL;
X    `7D
X#ifndef VMS
X    signal(SIGPIPE, oldsig);
X#endif /* VMS */
X    return(ret_val);
X`7D
X
X/* length calculates string length at compile time */
X/* can only be used with character constants */
X#define length(a) (sizeof(a)-1)
X
X/* Copy the headers, marked pages, and trailer to fp */
Xvoid
Xpscopydoc(fp)
X    FILE *fp;
X`7B
X    FILE *psfile;
X    char text`5BPSLINELENGTH`5D;
X    char *comment;
X    Boolean pages_written = False;
X    Boolean pages_atend = False;
X    Boolean marked_pages = False;
X    int pages = 0;
X    int page = 1;
X    int i, j;
X    long here;
X
X    psfile = fopen(filename, "r");
X
X    for (i = 0; i < doc->numpages; i++) `7B
X`09if (toc_text`5Btoc_entry_length * i`5D == '*') pages++;
X    `7D
X
X    if (pages == 0) `7B`09/* User forgot to mark the pages */
X`09mark_page(form, NULL, NULL);
X`09marked_pages = True;
X`09for (i = 0; i < doc->numpages; i++) `7B
X`09    if (toc_text`5Btoc_entry_length * i`5D == '*') pages++;
X`09`7D
X    `7D
X
X    here = doc->beginheader;
X    while (comment = pscopyuntil(psfile, fp, here,
X`09`09`09`09 doc->endheader, "%%Pages:")) `7B
X`09here = ftell(psfile);
X`09if (pages_written `7C`7C pages_atend) `7B
X`09    free(comment);
X`09    continue;
X`09`7D
X`09sscanf(comment+length("%%Pages:"), "%s", text);
X`09if (strcmp(text, "(atend)") == 0) `7B
X`09    fputs(comment, fp);
X`09    pages_atend = True;
X`09`7D else `7B
X`09    switch (sscanf(comment+length("%%Pages:"), "%*d %d", &i)) `7B
X`09`09case 1:
X`09`09    fprintf(fp, "%%%%Pages: %d %d\n", pages, i);
X`09`09    break;
X`09`09default:
X`09`09    fprintf(fp, "%%%%Pages: %d\n", pages);
X`09`09    break;
X`09    `7D
X`09    pages_written = True;
X`09`7D
X`09free(comment);
X    `7D
X    pscopy(psfile, fp, doc->beginpreview, doc->endpreview);
X    pscopy(psfile, fp, doc->begindefaults, doc->enddefaults);
X    pscopy(psfile, fp, doc->beginprolog, doc->endprolog);
X    pscopy(psfile, fp, doc->beginsetup, doc->endsetup);
X
X    for (i = 0; i < doc->numpages; i++) `7B
X`09if (doc->pageorder == DESCEND)`20
X`09    j = (doc->numpages - 1) - i;
X`09else
X`09    j = i;
X`09if (toc_text`5Btoc_entry_length * j`5D == '*') `7B
X`09    comment = pscopyuntil(psfile, fp, doc->pages`5Bi`5D.begin,
X`09`09`09`09  doc->pages`5Bi`5D.end, "%%Page:");
X`09    fprintf(fp, "%%%%Page: %s %d\n",
X`09`09    doc->pages`5Bi`5D.label, page++);
X`09    free(comment);
X`09    pscopy(psfile, fp, -1, doc->pages`5Bi`5D.end);
X`09`7D
X    `7D
X
X    here = doc->begintrailer;
X    while (comment = pscopyuntil(psfile, fp, here,
X`09`09`09`09 doc->endtrailer, "%%Pages:")) `7B
X`09here = ftell(psfile);
X`09if (pages_written) `7B
X`09    free(comment);
X`09    continue;
X`09`7D
X`09switch (sscanf(comment+length("%%Pages:"), "%*d %d", &i)) `7B
X`09    case 1:
X`09`09fprintf(fp, "%%%%Pages: %d %d\n", pages, i);
X`09`09break;
X`09    default:
X`09`09fprintf(fp, "%%%%Pages: %d\n", pages);
X`09`09break;
X`09`7D
X`09pages_written = True;
X`09free(comment);
X    `7D
X    fclose(psfile);
X
X    if (marked_pages) unmark_page(form, NULL, NULL);
X`7D
X#undef length
X
X/* position popup window under the cursor */
Xvoid
Xpositionpopup(w)
X    Widget w;
X`7B
X    Arg args`5B3`5D;
X    Cardinal num_args;
X    Dimension width, height, b_width;
X    int x, y, max_x, max_y;
X    Window root, child;
X    int dummyx, dummyy;
X    unsigned int dummymask;
X   `20
X    XQueryPointer(XtDisplay(w), XtWindow(w), &root, &child, &x, &y,
X`09`09  &dummyx, &dummyy, &dummymask);
X    num_args = 0;
X    XtSetArg(args`5Bnum_args`5D, XtNwidth, &width); num_args++;
X    XtSetArg(args`5Bnum_args`5D, XtNheight, &height); num_args++;
X    XtSetArg(args`5Bnum_args`5D, XtNborderWidth, &b_width); num_args++;
X    XtGetValues(w, args, num_args);
X
X    width += 2 * b_width;
X    height += 2 * b_width;
X
X    x -= ( (Position) width/2 );
X    if (x < 0) x = 0;
X    if ( x > (max_x = (Position) (XtScreen(w)->width - width)) ) x = max_x;
X
X    y -= ( (Position) height/2 );
X    if (y < 0) y = 0;
X    if ( y > (max_y = (Position) (XtScreen(w)->height - height)) ) y = max_y
V;
X   `20
X    num_args = 0;
X    XtSetArg(args`5Bnum_args`5D, XtNx, x); num_args++;
X    XtSetArg(args`5Bnum_args`5D, XtNy, y); num_args++;
X    XtSetValues(w, args, num_args);
X`7D
X
X/* Set new magstep */
XBoolean
Xset_new_magstep()
X`7B
X    int new_magstep;
X    Boolean changed = False;
X    Arg args`5B20`5D;
X    Cardinal num_args;
X    float xdpi, ydpi;
X
X    new_magstep = app_res.magstep;
X    /* If magstep changed, stop interpreter and setup for new dpi. */
X    if (new_magstep != current_magstep) `7B
X`09GhostviewDisableInterpreter(page);
X`09XawFormDoLayout(form, False);
X`09reset_size_hints();
X`09reset_scroll_bars();
X`09break_chains();
X`09changed = True;
X`09xdpi = default_xdpi;
X`09ydpi = default_ydpi;
X`09magnify(&xdpi, new_magstep);
X`09magnify(&ydpi, new_magstep);
X`09`09`09`09`09`09`09num_args = 0;
X`09XtSetFloatArg(args`5Bnum_args`5D, XtNxdpi, xdpi);`09num_args++;
X`09XtSetFloatArg(args`5Bnum_args`5D, XtNydpi, ydpi);`09num_args++;
X`09XtSetValues(page, args, num_args);
X
X`09XtSetArg(args`5B0`5D, XtNleftBitmap, None);
X`09XtSetValues(magstepentry`5Bcurrent_magstep - app_res.minimum_magstep`5D,
X`09`09    args, ONE);
X`09current_magstep = new_magstep;
X    `7D
X    XtSetArg(args`5B0`5D, XtNleftBitmap, dot_bitmap);
X    XtSetValues(magstepentry`5Bcurrent_magstep - app_res.minimum_magstep`5D,
X`09`09args, ONE);
X
X    return changed;
X`7D
X
X/* Set new orientation */
XBoolean
Xset_new_orientation(number)
X    int number;
X`7B
X    Boolean changed = False;
X    Boolean from_doc = False;
X    Arg args`5B1`5D;
X    XtPageOrientation new_orientation;
X
X    if (app_res.force_orientation) `7B
X`09new_orientation = app_res.orientation;
X    `7D else `7B
X`09if (doc) `7B
X`09    if (toc_text && doc->pages`5Bnumber`5D.orientation != NONE) `7B
X`09`09new_orientation = xorient(doc->pages`5Bnumber`5D.orientation);
X`09`09from_doc = True;
X`09    `7D else if (doc->default_page_orientation != NONE) `7B
X`09`09new_orientation = xorient(doc->default_page_orientation);
X`09`09from_doc = True;
X`09    `7D else if (doc->orientation != NONE) `7B
X`09`09new_orientation = xorient(doc->orientation);
X`09`09from_doc = True;
X`09    `7D else `7B
X`09`09new_orientation = app_res.orientation;
X`09    `7D
X`09`7D else `7B
X`09    new_orientation = app_res.orientation;
X`09`7D
X    `7D
X
X    /* If orientation changed,
X     * stop interpreter and setup for new orientation. */
X    if (new_orientation != current_orientation) `7B
X`09GhostviewDisableInterpreter(page);
X`09XawFormDoLayout(form, False);
X`09reset_size_hints();
X`09reset_scroll_bars();
X`09break_chains();
X`09changed = True;
X`09XtSetArg(args`5B0`5D, XtNorientation, new_orientation);
X`09XtSetValues(page, args, ONE);
X`09XtSetArg(args`5B0`5D, XtNleftBitmap, None);
X`09if (current_orientation == XtPageOrientationPortrait)`20
X`09    XtSetValues(portraitbutton, args, ONE);
X`09else if (current_orientation == XtPageOrientationLandscape)
X            XtSetValues(landscapebutton, args, ONE);
X        else if (current_orientation == XtPageOrientationUpsideDown)
X            XtSetValues(upsidedownbutton, args, ONE);
X        else if (current_orientation == XtPageOrientationSeascape)
X            XtSetValues(seascapebutton, args, ONE);
X`09current_orientation = new_orientation;
X    `7D
X
X    /* mark forced orientation with tie fighter. ("Use the force, Luke") */
X    if (app_res.force_orientation) `7B
X`09XtSetArg(args`5B0`5D, XtNleftBitmap, tie_fighter_bitmap);
X    `7D else if (from_doc) `7B
X`09XtSetArg(args`5B0`5D, XtNleftBitmap, menu16_bitmap);
X    `7D else `7B
X`09XtSetArg(args`5B0`5D, XtNleftBitmap, dot_bitmap);
X    `7D
X    if (current_orientation == XtPageOrientationPortrait)`20
X`09XtSetValues(portraitbutton, args, ONE);
X    else if (current_orientation == XtPageOrientationLandscape)
X`09XtSetValues(landscapebutton, args, ONE);
X    else if (current_orientation == XtPageOrientationUpsideDown)
X`09XtSetValues(upsidedownbutton, args, ONE);
X    else if (current_orientation == XtPageOrientationSeascape)
X`09XtSetValues(seascapebutton, args, ONE);
X   `20
X    return changed;
X`7D
X
X/* Set new pagemedia */
XBoolean
Xset_new_pagemedia(number)
X    int number;
X`7B
X    int new_pagemedia;
X    int new_llx;
X    int new_lly;
X    int new_urx;
X    int new_ury;
X    Boolean changed = False;
X    Boolean from_doc = False;
X    Arg args`5B4`5D;
X
X    if (force_document_media) `7B
X`09new_pagemedia = document_media;
X    `7D else if (app_res.force_pagemedia) `7B
X`09new_pagemedia = default_pagemedia;
X    `7D else `7B
X`09if (doc) `7B
X`09    if (toc_text && doc->pages`5Bnumber`5D.media != NULL) `7B
X`09`09new_pagemedia = doc->pages`5Bnumber`5D.media - doc->media;
X`09`09from_doc = True;
X`09    `7D else if (doc->default_page_media != NULL) `7B
X`09`09new_pagemedia = doc->default_page_media - doc->media;
X`09`09from_doc = True;
X`09    `7D else `7B
X`09`09new_pagemedia = default_pagemedia;
X`09    `7D
X`09`7D else `7B
X`09    new_pagemedia = default_pagemedia;
X`09`7D
X    `7D
X
X    /* If pagemedia changed, remove the old marker. */
X    if (new_pagemedia != current_pagemedia) `7B
X`09XtSetArg(args`5B0`5D, XtNleftBitmap, None);
X`09if (pagemediaentry`5Bcurrent_pagemedia`5D)
X`09    XtSetValues(pagemediaentry`5Bcurrent_pagemedia`5D, args, ONE);
X`09else
X`09    XtSetValues(pagemediaentry`5Bcurrent_pagemedia-1`5D, args, ONE);
X
X`09current_pagemedia = new_pagemedia;
X    `7D
X
X    /* mark forced page media with tie fighter. ("Use the force, Luke") */
X    if (force_document_media `7C`7C app_res.force_pagemedia) `7B
X`09XtSetArg(args`5B0`5D, XtNleftBitmap, tie_fighter_bitmap);
X    `7D else if (from_doc) `7B
X`09XtSetArg(args`5B0`5D, XtNleftBitmap, menu16_bitmap);
X    `7D else `7B
X`09XtSetArg(args`5B0`5D, XtNleftBitmap, dot_bitmap);
X    `7D
X    if (pagemediaentry`5Bcurrent_pagemedia`5D)
X`09XtSetValues(pagemediaentry`5Bcurrent_pagemedia`5D, args, ONE);
X    else
X`09XtSetValues(pagemediaentry`5Bcurrent_pagemedia-1`5D, args, ONE);
X
X    /* Compute bounding box */
X    if (!force_document_media && !app_res.force_pagemedia &&
X`09doc && doc->epsf &&
X`09/* Ignore malformed bounding boxes */
X`09(doc->boundingbox`5BURX`5D > doc->boundingbox`5BLLX`5D) &&
X`09(doc->boundingbox`5BURY`5D > doc->boundingbox`5BLLY`5D)) `7B
X`09new_llx = doc->boundingbox`5BLLX`5D;
X`09new_lly = doc->boundingbox`5BLLY`5D;
X`09new_urx = doc->boundingbox`5BURX`5D;
X`09new_ury = doc->boundingbox`5BURY`5D;
X    `7D else `7B
X`09new_llx = new_lly = 0;
X`09if (new_pagemedia < base_papersize) `7B
X`09    new_urx = doc->media`5Bnew_pagemedia`5D.width;
X`09    new_ury = doc->media`5Bnew_pagemedia`5D.height;
X`09`7D else `7B
X`09    new_urx = papersizes`5Bnew_pagemedia-base_papersize`5D.width;
X`09    new_ury = papersizes`5Bnew_pagemedia-base_papersize`5D.height;
X`09`7D
X    `7D
X
X    /* If bounding box changed, setup for new size. */
X    if ((new_llx != current_llx) `7C`7C (new_lly != current_lly) `7C`7C
X`09(new_urx != current_urx) `7C`7C (new_ury != current_ury)) `7B
X`09GhostviewDisableInterpreter(page);
X`09XawFormDoLayout(form, False);
X`09reset_size_hints();
X`09reset_scroll_bars();
X`09break_chains();
X`09changed = True;
X`09current_llx = new_llx;
X`09current_lly = new_lly;
X`09current_urx = new_urx;
X`09current_ury = new_ury;
X`09XtSetArg(args`5B0`5D, XtNllx, current_llx);
X`09XtSetArg(args`5B1`5D, XtNlly, current_lly);
X`09XtSetArg(args`5B2`5D, XtNurx, current_urx);
X`09XtSetArg(args`5B3`5D, XtNury, current_ury);
X`09XtSetValues(page, args, FOUR);
X    `7D
X
X    return changed;
X`7D
X
Xstatic Boolean
Xsame_document_media()
X`7B
X    int i;
X
X    if (olddoc == NULL && doc == NULL) return True;
X    if (olddoc == NULL `7C`7C doc == NULL) return False;
+-+-+-+-+-+-+-+-  END  OF PART 10 +-+-+-+-+-+-+-+-
Technical Details
Message-ID: <8881766@MVB.SAIC.COM>
Path: arc1-ca.pugleaf.net!sparky!uunet!cs.utexas.edu!usc!news.service.uci.edu!unogate!mvb.saic.com!vmsnet-sources

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!sparky!uunet!cs.utexas.edu!usc!news.service.uci.edu!unogate!mvb.saic.com!vmsnet-sources
Newsgroups: vmsnet.sources
From: Terry Poot <tp@mccall.com>
Subject: Ghostview for VMS 10/14
Message-ID: <8881766@MVB.SAIC.COM>
Date: Thu, 29 Oct 1992 18:49:58 GMT
Lines: 1510
Approved: Mark.Berryman@Mvb.Saic.Com