🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: vmsnet.sources
Article #10

Ghostview for VMS 04/14

#10
From: Terry Poot
Date: Thu, 29 Oct 1992 18:49
1411 lines
49196 bytes
Submitted-by: Terry Poot <tp@mccall.com>
Posting-number: Volume 3, Issue 222
Archive-name: ghostview/part04

-+-+-+-+-+-+-+-+ START OF PART 4 -+-+-+-+-+-+-+-+
X
X    StopInterpreter(w);
X
X    if ((gvw->core.width != gvw->ghostview.gs_width) `7C`7C
X`09(gvw->core.height != gvw->ghostview.gs_height) `7C`7C
X`09(!gvw->ghostview.use_bpixmap)) `7B
X`09if (gvw->core.background_pixmap != XtUnspecifiedPixmap) `7B
X`09    XFreePixmap(XtDisplay(w), gvw->core.background_pixmap);
X`09    gvw->core.background_pixmap = XtUnspecifiedPixmap;
X`09    XSetWindowBackgroundPixmap(XtDisplay(w), XtWindow(w), None);
X`09`7D
X    `7D
X
X    if (gvw->ghostview.use_bpixmap) `7B
X`09if (gvw->core.background_pixmap == XtUnspecifiedPixmap) `7B
X`09    /* Get a Backing Pixmap, but be ready for the BadAlloc. */
X`09    oldhandler = XSetErrorHandler(catch_alloc);
X`09    alloc_error = False;
X`09    bpixmap = XCreatePixmap(XtDisplay(w), XtWindow(w),
X`09`09`09`09    gvw->core.width, gvw->core.height,
X`09`09`09`09    gvw->core.depth);
X`09    XSync(XtDisplay(w), False);  /* Force the error */
X`09    if (alloc_error) `7B
X`09`09XtCallCallbackList(w, gvw->ghostview.message_callback,
X`09`09`09`09   "BadAlloc");
X`09`09if (bpixmap != None) `7B
X`09`09    XFreePixmap(XtDisplay(w), bpixmap);
X`09`09    XSync(XtDisplay(w), False);  /* Force the error */
X`09`09    bpixmap = None;
X`09`09`7D
X`09    `7D
X`09    oldhandler = XSetErrorHandler(oldhandler);
X`09    if (bpixmap != None) `7B
X`09`09gvw->core.background_pixmap = bpixmap;
X`09`09XSetWindowBackgroundPixmap(XtDisplay(w), XtWindow(w),
X`09`09`09`09`09   gvw->core.background_pixmap);
X`09    `7D
X`09`7D else `7B
X`09    bpixmap = gvw->core.background_pixmap;
X`09`7D
X    `7D else `7B
X`09if (gvw->core.background_pixmap != XtUnspecifiedPixmap) `7B
X`09    XFreePixmap(XtDisplay(w), gvw->core.background_pixmap);
X`09    gvw->core.background_pixmap = XtUnspecifiedPixmap;
X`09    XSetWindowBackgroundPixmap(XtDisplay(w), XtWindow(w), None);
X`09`7D
X`09bpixmap = None;
X    `7D
X
X    if (bpixmap != None) `7B
X`09xswa.backing_store = NotUseful;
X`09XChangeWindowAttributes(XtDisplay(w), XtWindow(w),
X`09`09`09`09CWBackingStore, &xswa);
X    `7D else `7B
X`09xswa.backing_store = Always;
X`09XChangeWindowAttributes(XtDisplay(w), XtWindow(w),
X`09`09`09`09CWBackingStore, &xswa);
X    `7D
X
X    gvw->ghostview.gs_width = gvw->core.width;
X    gvw->ghostview.gs_height = gvw->core.height;
X
X    sprintf(buf, "%d %d %d %d %d %d %g %g %d %d %d %d",
X`09    bpixmap, gvw->ghostview.orientation,
X`09    gvw->ghostview.llx, gvw->ghostview.lly,
X`09    gvw->ghostview.urx, gvw->ghostview.ury,
X`09    gvw->ghostview.xdpi, gvw->ghostview.ydpi,
X`09    gvw->ghostview.left_margin, gvw->ghostview.bottom_margin,
X`09    gvw->ghostview.right_margin, gvw->ghostview.top_margin);
X    XChangeProperty(XtDisplay(w), XtWindow(w),
X`09`09   XmuInternAtom(XtDisplay(w), gvc->ghostview_class.ghostview),
X`09`09   XA_STRING, 8, PropModeReplace,
X`09`09   (unsigned char *)buf, strlen(buf));
X
X    StartInterpreter(w);
X    return True;
X`7D
X
X#ifndef VMS
X
X/* This routine starts the interpreter.  It sets the DISPLAY and`20
X * GHOSTVIEW environment variables.  The GHOSTVIEW environment variable
X * contains the Window that ghostscript should write on.
X *
X * This routine also opens pipes for stdout and stderr and initializes
X * application input events for them.  If input to ghostscript is not
X * from a file, a pipe for stdin is created.  This pipe is setup for
X * non-blocking I/O so that the user interface never "hangs" because of
X * a write to ghostscript.
X */
Xstatic void
XStartInterpreter(w)
X    Widget w;
X`7B
X    GhostviewWidget gvw = (GhostviewWidget) w;
X    int`09std_in`5B2`5D;
X    int`09std_out`5B2`5D;
X    int`09std_err`5B2`5D;
X    char buf`5BGV_BUFSIZ`5D;
X#define NUM_ARGS 100
X    char *argv`5BNUM_ARGS`5D;
X    char *preload = NULL;
X    char *cptr;
X    int argc = 0;
X    int ret;
X
X    StopInterpreter(w);
X
X    /* Clear the window before starting a new interpreter. */
X    if (gvw->core.background_pixmap != XtUnspecifiedPixmap) `7B
X`09XFillRectangle(XtDisplay(w), gvw->core.background_pixmap,
X`09`09       gvw->ghostview.gc,
X`09`09       0, 0, gvw->core.width, gvw->core.height);
X    `7D
X    XClearArea(XtDisplay(w), XtWindow(w),
X`09       0, 0, gvw->core.width, gvw->core.height, False);
X
X    if (gvw->ghostview.disable_start) return;
X
X    argv`5Bargc++`5D = gvw->ghostview.interpreter;
X    if (gvw->ghostview.quiet) argv`5Bargc++`5D = "-dQUIET";
X    argv`5Bargc++`5D = "-dNOPAUSE";
X    if (gvw->ghostview.preload) `7B
X`09cptr = preload = XtNewString(gvw->ghostview.preload);
X`09while (isspace(*cptr)) cptr++;
X`09while (*cptr) `7B
X`09    argv`5Bargc++`5D = cptr;
X`09    while (*cptr && !isspace(*cptr)) cptr++;
X`09    *cptr++ = '\0';
X`09    if (argc + 2 >= NUM_ARGS) `7B
X`09`09fprintf(stderr, "Too many files to preload.\n");
X`09`09exit(1);
X`09    `7D
X`09    while (isspace(*cptr)) cptr++;
X`09`7D
X    `7D
X    argv`5Bargc++`5D = "-";
X    argv`5Bargc++`5D = NULL;
X
X    if (gvw->ghostview.filename == NULL) `7B
X`09ret = pipe(std_in);
X`09if (ret == -1) `7B
X`09    perror("Could not create pipe");
X`09    exit(1);
X`09`7D
X    `7D else if (strcmp(gvw->ghostview.filename, "-")) `7B
X`09std_in`5B0`5D = open(gvw->ghostview.filename, O_RDONLY, 0);
X    `7D
X    ret = pipe(std_out);
X    if (ret == -1) `7B
X`09perror("Could not create pipe");
X`09exit(1);
X    `7D
X    ret = pipe(std_err);
X    if (ret == -1) `7B
X`09perror("Could not create pipe");
X`09exit(1);
X    `7D
X
X    gvw->ghostview.changed = False;
X    gvw->ghostview.busy = True;
X    XDefineCursor(XtDisplay(gvw), XtWindow(gvw), gvw->ghostview.busy_cursor)
V;
X#if defined(SYSV) `7C`7C defined(USG)
X#define vfork fork
X#endif
X    gvw->ghostview.interpreter_pid = vfork();
X
X    if (gvw->ghostview.interpreter_pid == 0) `7B /* child */
X`09close(std_out`5B0`5D);
X`09close(std_err`5B0`5D);
X`09dup2(std_out`5B1`5D, 1);
X`09close(std_out`5B1`5D);
X`09dup2(std_err`5B1`5D, 2);
X`09close(std_err`5B1`5D);
X`09sprintf(buf, "%d", XtWindow(w));
X`09setenv("GHOSTVIEW", buf, True);
X`09setenv("DISPLAY", XDisplayString(XtDisplay(w)), True);
X`09if (gvw->ghostview.filename == NULL) `7B
X`09    close(std_in`5B1`5D);
X`09    dup2(std_in`5B0`5D, 0);
X`09    close(std_in`5B0`5D);
X`09`7D else if (strcmp(gvw->ghostview.filename, "-")) `7B
X`09    dup2(std_in`5B0`5D, 0);
X`09    close(std_in`5B0`5D);
X`09`7D
X`09execvp(argv`5B0`5D, argv);
X`09sprintf(buf, "Exec of %s failed", argv`5B0`5D);
X`09perror(buf);
X`09_exit(1);
X    `7D else `7B
X`09if (gvw->ghostview.filename == NULL) `7B
X#ifdef NON_BLOCKING_IO
X`09    int result;
X#endif
X`09    close(std_in`5B0`5D);
X
X#ifdef NON_BLOCKING_IO
X`09    result = fcntl(std_in`5B1`5D, F_GETFL, 0);
X`09    result = result `7C O_NONBLOCK;
X`09    result = fcntl(std_in`5B1`5D, F_SETFL, result);
X#endif
X`09    gvw->ghostview.interpreter_input = std_in`5B1`5D;
X`09    gvw->ghostview.interpreter_input_id = None;
X`09`7D else if (strcmp(gvw->ghostview.filename, "-")) `7B
X`09    close(std_in`5B0`5D);
X`09`7D
X`09close(std_out`5B1`5D);
X`09gvw->ghostview.interpreter_output = std_out`5B0`5D;
X`09gvw->ghostview.interpreter_output_id =`20
X`09    XtAppAddInput(XtWidgetToApplicationContext(w), std_out`5B0`5D,
X`09`09`09  (XtPointer)XtInputReadMask, Output, (XtPointer)w);
X`09close(std_err`5B1`5D);
X`09gvw->ghostview.interpreter_error = std_err`5B0`5D;
X`09gvw->ghostview.interpreter_error_id =`20
X`09    XtAppAddInput(XtWidgetToApplicationContext(w), std_err`5B0`5D,
X`09`09`09  (XtPointer)XtInputReadMask, Output, (XtPointer)w);
X    `7D
X    if (preload) XtFree(preload);
X`7D
X
X/* Stop the interperter, if present, and remove any Input sources. */
X/* Also reset the busy state. */
Xstatic void
XStopInterpreter(w)
X    Widget w;
X`7B
X    GhostviewWidget gvw = (GhostviewWidget) w;
X    if (gvw->ghostview.interpreter_pid >= 0) `7B
X`09kill(gvw->ghostview.interpreter_pid, SIGTERM);
X`09wait(0);
X`09gvw->ghostview.interpreter_pid = -1;
X    `7D
X    if (gvw->ghostview.interpreter_input >= 0) `7B
X`09close(gvw->ghostview.interpreter_input);
X`09gvw->ghostview.interpreter_input = -1;
X`09if (gvw->ghostview.interpreter_input_id != None) `7B
X`09    XtRemoveInput(gvw->ghostview.interpreter_input_id);
X`09    gvw->ghostview.interpreter_input_id = None;
X`09`7D
X`09while (gvw->ghostview.ps_input) `7B
X`09    struct record_list *ps_old = gvw->ghostview.ps_input;
X`09    gvw->ghostview.ps_input = ps_old->next;
X`09    if (ps_old->close) fclose(ps_old->fp);
X`09    XtFree((char *)ps_old);
X`09`7D
X    `7D
X    if (gvw->ghostview.interpreter_output >= 0) `7B
X`09close(gvw->ghostview.interpreter_output);
X`09gvw->ghostview.interpreter_output = -1;
X`09XtRemoveInput(gvw->ghostview.interpreter_output_id);
X    `7D
X    if (gvw->ghostview.interpreter_error >= 0) `7B
X`09close(gvw->ghostview.interpreter_error);
X`09gvw->ghostview.interpreter_error = -1;
X`09XtRemoveInput(gvw->ghostview.interpreter_error_id);
X    `7D
X    gvw->ghostview.busy = False;
X    XDefineCursor(XtDisplay(gvw), XtWindow(gvw), gvw->ghostview.cursor);
X`7D
X
X#endif /* VMS */
X
X/* The interpeter failed, Stop what's left and notify application */
Xstatic void
XInterpreterFailed(w)
X    Widget w;
X`7B
X    GhostviewWidget gvw = (GhostviewWidget) w;
X    StopInterpreter(w);
X    XtCallCallbackList(w, gvw->ghostview.message_callback, "Failed");
X`7D
X
X/*
X *`09Public Routines
X */
X
X/* GhostviewDisableInterpreter:
X * Stop any interpreter and disable new ones from starting.
X */
Xvoid
XGhostviewDisableInterpreter(w)
X    Widget w;
X`7B
X    GhostviewWidget gvw = (GhostviewWidget) w;
X    gvw->ghostview.disable_start = True;
X    if (XtIsRealized(w)) StopInterpreter(w);
X`7D
X
X/* GhostviewDisableInterpreter:
X * Allow an interpreter to start and start one if the widget is
X * currently realized.
X */
Xvoid
XGhostviewEnableInterpreter(w)
X    Widget w;
X`7B
X    GhostviewWidget gvw = (GhostviewWidget) w;
X    gvw->ghostview.disable_start = False;
X    if (XtIsRealized(w)) StartInterpreter(w);
X`7D
X
X/* GhostviewIsInterpreterReady:
X * Returns True if the interpreter is ready for new input.
X */
XBoolean
XGhostviewIsInterpreterReady(w)
X    Widget w;
X`7B
X    GhostviewWidget gvw = (GhostviewWidget) w;
X    return gvw->ghostview.interpreter_pid != -1 &&
X`09   !gvw->ghostview.busy &&
X`09   gvw->ghostview.ps_input == NULL;
X`7D
X
X/* GhostviewIsInterpreterRunning:
X * Returns True if the interpreter is running.
X */
XBoolean
XGhostviewIsInterpreterRunning(w)
X    Widget w;
X`7B
X    GhostviewWidget gvw = (GhostviewWidget) w;
X    return gvw->ghostview.interpreter_pid != -1;
X`7D
X
X/* GhostviewGetBackingPixmap:
X * Returns the current backing pixmap.
X */
XPixmap
XGhostviewGetBackingPixmap(w)
X    Widget w;
X`7B
X    GhostviewWidget gvw = (GhostviewWidget) w;
X    if (gvw->core.background_pixmap != XtUnspecifiedPixmap)
X`09return(gvw->core.background_pixmap);
X    else
X`09return(None);
X`7D
X
X#ifndef VMS
X
X/* GhostviewSendPS:
X *   Queue a portion of a PostScript file for output to ghostscript.
X *   fp: FILE * of the file in question.  NOTE: if you have several
X *   Ghostview widgets reading from the same file.  You must open
X *   a unique FILE * for each widget.
X *   SendPS does not actually send the PostScript, it merely queues it
X *   for output.
X *   begin: position in file (returned from ftell()) to start.
X *   len:   number of bytes to write.
X *
X *   If an interpreter is not running, nothing is queued and
X *   False is returned.
X */
XBoolean
XGhostviewSendPS(w, fp, begin, len, close)
X    Widget w;
X    FILE *fp;
X    long begin;
X    unsigned int len;
X    Bool close;
X`7B
X    GhostviewWidget gvw = (GhostviewWidget) w;
X    struct record_list *ps_new;
X
X    if (gvw->ghostview.interpreter_input < 0) return False;
X    ps_new = (struct record_list *) XtMalloc(sizeof (struct record_list));
X    ps_new->fp = fp;
X    ps_new->begin = begin;
X    ps_new->len = len;
X    ps_new->seek_needed = True;
X    ps_new->close = close;
X    ps_new->next = NULL;
X
X    if (gvw->ghostview.input_buffer == NULL) `7B
X`09gvw->ghostview.input_buffer = XtMalloc(GV_BUFSIZ);
X    `7D
X
X    if (gvw->ghostview.ps_input == NULL) `7B
X`09gvw->ghostview.input_buffer_ptr = gvw->ghostview.input_buffer;
X`09gvw->ghostview.bytes_left = len;
X`09gvw->ghostview.buffer_bytes_left = 0;
X`09gvw->ghostview.ps_input = ps_new;
X`09gvw->ghostview.interpreter_input_id =
X`09`09XtAppAddInput(XtWidgetToApplicationContext(w),
X`09`09`09      gvw->ghostview.interpreter_input,
X`09`09`09      (XtPointer)XtInputWriteMask, Input, (XtPointer)w);
X    `7D else `7B
X`09struct record_list *p = gvw->ghostview.ps_input;
X`09while (p->next != NULL) `7B
X`09    p = p->next;
X`09`7D
X`09p->next = ps_new;
X    `7D
X    return True;
X`7D
X
X#endif /* VMS */
X
X/* GhostviewNextPage:
X *   Tell ghostscript to start the next page.
X *   Returns False if ghostscript is not running, or not ready to start
X *   another page.
X *   If another page is started.  Sets the busy flag and cursor.
X */
XBoolean
XGhostviewNextPage(w)
X    Widget w;
X`7B
X    GhostviewWidget gvw = (GhostviewWidget) w;
X    GhostviewWidgetClass gvc = (GhostviewWidgetClass) XtClass(w);
X    XEvent event;
X
X    if (gvw->ghostview.interpreter_pid < 0) return False;
X    if (gvw->ghostview.mwin == None) return False;
X
X    if (!gvw->ghostview.busy) `7B
X`09gvw->ghostview.busy = True;
X`09XDefineCursor(XtDisplay(gvw), XtWindow(gvw),
X`09`09      gvw->ghostview.busy_cursor);
X
X`09event.xclient.type = ClientMessage;
X`09event.xclient.display = XtDisplay(w);
X`09event.xclient.window = gvw->ghostview.mwin;
X`09event.xclient.message_type =
X`09`09XmuInternAtom(XtDisplay(w), gvc->ghostview_class.next);
X`09event.xclient.format = 32;
X`09XSendEvent(XtDisplay(w), gvw->ghostview.mwin, False, 0, &event);
X`09return True;
X    `7D else `7B
X`09return False;
X    `7D
X`7D
X
X#define`09done(type, value) \
X`09`7B`09`09`09`09`09`09`09\
X`09    if (toVal->addr != NULL) `7B`09`09`09`09\
X`09`09if (toVal->size < sizeof(type)) `7B`09`09\
X`09`09    toVal->size = sizeof(type);`09`09`09\
X`09`09    return False;`09`09`09`09\
X`09`09`7D`09`09`09`09`09`09\
X`09`09*(type*)(toVal->addr) = (value);`09`09\
X`09    `7D`09`09`09`09`09`09`09\
X`09    else `7B`09`09`09`09`09`09\
X`09`09static type static_val;`09`09`09`09\
X`09`09static_val = (value);`09`09`09`09\
X`09`09toVal->addr = (XPointer)&static_val;`09`09\
X`09    `7D`09`09`09`09`09`09`09\
X`09    toVal->size = sizeof(type);`09`09`09`09\
X`09    return True;`09`09`09`09`09\
X`09`7D
X
X/* PageOrienation Conversion Routine.
X * Returns True if Conversion is successful.
X */
XBoolean
XXmuCvtStringToPageOrientation(dpy, args, num_args, fromVal, toVal, data)
X    Display`09*dpy;
X    XrmValue`09*args;`09`09/* unused */
X    Cardinal`09*num_args;`09/* unused */
X    XrmValue`09*fromVal;
X    XrmValue`09*toVal;
X    XtPointer`09*data;`09`09/* unused */
X`7B
X    static XrmQuark`09`09XrmQEportrait;
X    static XrmQuark`09`09XrmQElandscape;
X    static XrmQuark`09`09XrmQEupsideDown;
X    static XrmQuark`09`09XrmQEseascape;
X    static int`09`09`09haveQuarks;
X    XrmQuark    q;
X    char`09*str = (XPointer) fromVal->addr;
X    char        lowerName`5B1000`5D;
X
X    if (str == NULL) return False;
X
X    if (!haveQuarks) `7B
X`09XrmQEportrait   = XrmStringToQuark(XtEportrait);
X`09XrmQElandscape  = XrmStringToQuark(XtElandscape);
X`09XrmQEupsideDown = XrmStringToQuark(XtEupsideDown);
X`09XrmQEseascape   = XrmStringToQuark(XtEseascape);
X`09haveQuarks = 1;
X    `7D
X
X    XmuCopyISOLatin1Lowered(lowerName, str);
X
X    q = XrmStringToQuark(lowerName);
X
X    if (q == XrmQEportrait)
X`09done(XtPageOrientation, XtPageOrientationPortrait);
X    if (q == XrmQElandscape)
X`09done(XtPageOrientation, XtPageOrientationLandscape);
X    if (q == XrmQEupsideDown)
X`09done(XtPageOrientation, XtPageOrientationUpsideDown);
X    if (q == XrmQEseascape)
X`09done(XtPageOrientation, XtPageOrientationSeascape);
X
X    XtDisplayStringConversionWarning(dpy, str, XtRPageOrientation);
X    return False;
X`7D
X
X#ifdef VMS
X
X/*
X** VMS specific include files
X*/
X#include <descrip.h>
X#include <ssdef.h>
X#include <clidef.h>
X#include <lnmdef.h>
X#include <iodef.h>
X#include <dvidef.h>
X#include "vms_types.h"
X
X#define ERR_SIGNAL(s) if(!((s) & 1))lib$signal((s), 0, 0)
X#define XtEFN 23
X
Xstruct g_l_i
X`7B
X    GhostviewWidget w;
X    struct g_l_i *next;
X`7D;
X
Xtypedef struct g_l_i GhostListItem, *GLI_p;
X
Xstatic GhostListItem glhead = `7B(GhostviewWidget) -1, NULL`7D;
Xstatic GLI_p GL = &glhead;
Xstatic size_t GLI_Size = sizeof(GhostListItem);
Xstatic XtInputId EventId;
X
X/*
X** This routine is passed to XtAppAddInput(). It is called whenever the even
Vt
X** flag number XtEFN is set and the Xt main loop becomes idle. It clears the
X** event flag and then scans all the ghostview widgets for completed I/O
X** requests, processing each as they are found. We have to do them all becau
Vse
X** there is no way to have Xt dispatch them individually without a window of
X** vulnerability that can cause missed events, or by using a separate event
X** flag for each I/O stream. Event flags are, unfortunately, a limited
X** resource.
X*/
Xstatic Boolean
XIOProcess()
X`7B
X    GhostviewWidget gvw;
X    GLI_p cur;
X
X    /*
X    ** Before we process any I/O's, clear the event flag.
X    */
X    sys$clref(XtEFN);
X    /*
X    ** Scan all the ghostview widgets and check for completed I/O's
X    */
X    for(cur = GL->next; cur; cur = cur->next)`7B
X`09/*
X`09** Get the widget and check for I/O complete on either mailbox.
X`09*/
X`09gvw = cur->w;
X`09if(gvw->ghostview.interpreter_input_iosb`5B0`5D)Input(gvw);
X`09if(gvw->ghostview.interpreter_output_iosb`5B0`5D)Output(gvw);
X    `7D
X`7D
X   `20
X/*
X** This is an AST routine. It is called asynchronously whenever one of our
X** mailbox I/O's completes.
X*/
Xstatic void
XIOComplete(client_data)
X    XtPointer client_data;
X`7B
X    /*
X    ** Set the event flag to tell Xt to call IOProcess.
X    */
X    sys$setef(XtEFN);
X`7D
X
Xstatic void
XGLInsert(w)
X    GhostviewWidget w;
X`7B
X    GLI_p new;
X    int first;
X   `20
X    /*
X    ** Insert this widget after the list head
X    */
X    first = (GL->next == NULL);
X    new = XtMalloc(GLI_Size);
X    new->w = w;
X    new->next = GL->next;
X    GL->next = new;
X    /*
X    ** If this is the first item on the list, call XtAppAddInput()
X    */
X    if(first)EventId = XtAppAddInput(XtWidgetToApplicationContext(w), XtEFN,
V 0,`20
X`09IOProcess, 0);
X`7D
X
Xstatic void
XGLRemove(w)
X    GhostviewWidget w;
X`7B
X    GLI_p prev, cur;
X    int last = 0;
X
X    /*
X    ** Find and remove this widget from the list.
X    */
X    prev = GL;
X    cur = prev->next;
X    while(cur && cur->w != w)`7B
X`09prev = cur;
X`09cur = cur->next;
X    `7D
X    if(cur)`7B
X       prev->next = cur->next;
X       XtFree(cur);
X       last = (GL->next == NULL);
X    `7D
X    /*
X    ** If this was the last item on the list, call XtRemoveInput()
X    */
X    if(last)XtRemoveInput(EventId);
X`7D
X
X/* Input - Feed data to ghostscript's stdin.
X * Write bytes to ghostscript using non-blocking I/O.
X * Also, pipe signals are caught during writing.  The return
X * values are checked and the appropriate action is taken.  I do
X * this at this low level, because it may not be appropriate for
X * SIGPIPE to be caught for the overall application.
X */
X
Xstatic void
XInput(gvw)
X    GhostviewWidget gvw;
X`7B
X    int stat, bbytes;
X    char *ch;
X
X    /*
X    ** Check for error on previous I/O.
X    */
X    stat = gvw->ghostview.interpreter_input_iosb`5B0`5D;
X    if(stat != SS$_NORMAL)`7B
X`09InterpreterFailed(gvw);
X    `7D else `7B
X
X`09/* Get a new section if required */
X`09
X`09if (gvw->ghostview.ps_input && gvw->ghostview.bytes_left == 0) `7B
X`09    struct record_list *ps_old = gvw->ghostview.ps_input;
X`09    gvw->ghostview.ps_input = ps_old->next;
X`09    if (ps_old->close) fclose(ps_old->fp);
X`09    XtFree((char *)ps_old);
X`09`7D
X`09if(gvw->ghostview.ps_input)`7B
X`09    /* Have to seek at the beginning of each section */
X`09    if (gvw->ghostview.ps_input->seek_needed) `7B
X`09`09if (gvw->ghostview.ps_input->len > 0)
X`09`09    fseek(gvw->ghostview.ps_input->fp,
X`09`09`09  gvw->ghostview.ps_input->begin, SEEK_SET);
X`09`09gvw->ghostview.ps_input->seek_needed = False;
X`09`09gvw->ghostview.bytes_left = gvw->ghostview.ps_input->len;
X`09    `7D
X`09    /*
X`09    ** Read a line from the file.
X`09    */
X`09    ch = fgets(gvw->ghostview.input_buffer, GV_BUFSIZ,
X`09`09gvw->ghostview.ps_input->fp);
X`09    if(!ch)`7B
X`09`09/*
X`09`09** Error, EOF when there's supposed to be data left.`20
X`09`09*/
X`09`09InterpreterFailed(gvw);
X`09    `7D else `7B
X`09`09/*
X`09`09** Write it to the mailbox.
X`09`09*/
X`09`09bbytes = strlen(gvw->ghostview.input_buffer);
X`09`09gvw->ghostview.bytes_left -= bbytes;
X`09`09stat = sys$qio(0, (short)gvw->ghostview.interpreter_input,
X`09`09    IO$_WRITEVBLK, &gvw->ghostview.interpreter_input_iosb,
X`09`09    IOComplete, 0, gvw->ghostview.input_buffer, bbytes,
X`09`09    0, 0, 0, 0);
X`09`09ERR_SIGNAL(stat);
X`09    `7D
X`09`7D
X    `7D
X`7D
X
X/* Output - receive I/O from ghostscript's stdout and stderr.
X * Pass this to the application via the output_callback. */
Xstatic void
XOutput(gvw)
X    GhostviewWidget gvw;
X`7B
X    char buf`5BGV_BUFSIZ+1`5D;
X    int bytes, stat;
X
X    stat = gvw->ghostview.interpreter_output_iosb`5B0`5D;
X    bytes = gvw->ghostview.interpreter_output_iosb`5B1`5D;
X    if (stat == SS$_NORMAL) `7B
X`09/*
X`09** Got a message. If line complete, pass to the output_callback.
X`09**
X`09** HACK ALERT, if bytes is -1 nothing happens, but an I/O is queued.
X`09** This is our first time code, since Xt doesn't queue the I/O for us
X`09** under VMS, just watches for completion. In StartInterpreter We setup
X`09** an IOSB with a success status and -1 bytes so Xt will call us the
X`09** first time to get the I/O queued.
X`09*/
X`09if (bytes == 0) `7B
X`09    strcpy(buf, "\n");
X`09`7D else if (bytes == 1) `7B
X`09    buf`5B0`5D = gvw->ghostview.output_buffer`5B0`5D;
X`09    buf`5B1`5D = '\0';
X`09`7D else if (bytes > 1) `7B
X`09    /*
X`09    ** Copy the message to a local buffer and pass it to the callback.
X`09    */
X`09    memcpy(buf, gvw->ghostview.output_buffer, bytes);
X`09    buf`5Bbytes`5D = '\0';
X`09`7D
X`09if(bytes >= 0)XtCallCallbackList(gvw, gvw->ghostview.output_callback,
X`09    (XtPointer) buf);
X`09/*
X`09** Queue a new read to the mailbox
X`09*/
X`09stat = sys$qio(0, (short)gvw->ghostview.interpreter_output,
X`09    IO$_READVBLK, &gvw->ghostview.interpreter_output_iosb, IOComplete,
X`09    0, gvw->ghostview.output_buffer, GV_BUFSIZ, 0, 0, 0, 0);
X`09ERR_SIGNAL(stat);
X    `7D else `7B
X`09InterpreterFailed(gvw);`09`09/* Something bad happened */
X    `7D
X`7D
X
X/* This routine starts the interpreter.  It sets the DISPLAY and`20
X * GHOSTVIEW environment variables.  The GHOSTVIEW environment variable
X * contains the Window that ghostscript should write on.
X *
X * This routine also opens pipes for stdout and stderr and initializes
X * application input events for them.  If input to ghostscript is not
X * from a file, a pipe for stdin is created.  This pipe is setup for
X * non-blocking I/O so that the user interface never "hangs" because of
X * a write to ghostscript.
X */
Xstatic void
XStartInterpreter(w)
X    Widget w;
X`7B
X    GhostviewWidget gvw = (GhostviewWidget) w;
X    char buf`5BGV_BUFSIZ`5D;
X    char cmd`5B512`5D;
X    int ret;
X    short ch1, ch2;
X    char in_mbx_name`5B65`5D, out_mbx_name`5B65`5D;
X    long pid, nowait = CLI$M_NOWAIT;
X    const $DESCRIPTOR(ghostview_desc, "GHOSTVIEW");
X    const $DESCRIPTOR(display_desc, "DECW$DISPLAY");
X    const $DESCRIPTOR(lnt_desc, "LNM$PROCESS");
X    $DESCRIPTOR(in_desc, "");
X    $DESCRIPTOR(out_desc, "");
X    $DESCRIPTOR(lnm_desc, "");
X    $DESCRIPTOR(cmd_desc, cmd);
X    ITEM_LIST_3_T(gv_list, 1) = `7B`7B`7B0, LNM$_STRING, buf, NULL`7D`7D, 0`
V7D;
X    ITEM_LIST_3_T(dis_list, 1) = `7B`7B`7B0, LNM$_STRING, NULL, NULL`7D`7D,
V 0`7D;
X    ITEM_LIST_3_T(dvi_list, 1) = `7B`7B`7B64, DVI$_DEVNAM, NULL, NULL`7D`7D,
V 0`7D;
X    IOSB_GET_T dvi_iosb;
X
X    /*
X    ** Stop interpreter if running
X    */
X    StopInterpreter(w);
X    /*
X    ** Clear the window before starting a new interpreter.
X    */
X    if (gvw->core.background_pixmap != XtUnspecifiedPixmap) `7B
X`09XFillRectangle(XtDisplay(w), gvw->core.background_pixmap,
X`09`09       gvw->ghostview.gc,
X`09`09       0, 0, gvw->core.width, gvw->core.height);
X    `7D
X    XClearArea(XtDisplay(w), XtWindow(w),
X`09       0, 0, gvw->core.width, gvw->core.height, False);
X    /*
X    ** Check for disabled.
X    */
X    if (gvw->ghostview.disable_start) return;
X    /*
X    ** Build Ghostscript startup command
X    */
X    strcpy(cmd, gvw->ghostview.interpreter);
X    strcat(cmd, " ");
X    if (gvw->ghostview.quiet) strcat(cmd, "\"-dQUIET\" ");
X    strcat(cmd, "\"-dNOPAUSE\" ");
X    if (gvw->ghostview.preload) `7B
X`09strcat(cmd, gvw->ghostview.preload);
X`09strcat(cmd, " ");
X    `7D
X    strcat(cmd, "\"-\" ");
X
X    /*
X    ** Determine input source.
X    */
X    if (gvw->ghostview.filename == NULL) `7B
X`09/*
X`09** Create a mailbox to feed input to Ghostscript and get its name.
X`09*/
X`09ret = sys$crembx(0, &ch1, GV_BUFSIZ, GV_BUFSIZ, 0, 0, 0, 0);
X`09ERR_SIGNAL(ret);
X`09dvi_list.item`5B0`5D.buffer_p = in_mbx_name;
X`09ret = sys$getdvi(0, ch1, 0, &dvi_list, &dvi_iosb, 0, 0, 0);
X`09ERR_SIGNAL(ret); ERR_SIGNAL(dvi_iosb.status);
X`09in_mbx_name`5B64`5D = '\0';
X`09in_desc.dsc$a_pointer = in_mbx_name;
X`09in_desc.dsc$w_length = strlen(in_mbx_name);
X    `7D else `7B
X`09/*
X`09** Set up file name to give Ghostscript as standard input.
X`09*/
X`09in_desc.dsc$a_pointer = gvw->ghostview.filename;
X`09in_desc.dsc$w_length = strlen(gvw->ghostview.filename);
X    `7D
X    /*
X    ** Create mailbox to receive Ghostscript's output
X    */
X    ret = sys$crembx(0, &ch2, GV_BUFSIZ, GV_BUFSIZ, 0, 0, 0, 0);
X    ERR_SIGNAL(ret);
X    dvi_list.item`5B0`5D.buffer_p = out_mbx_name;
X    ret = sys$getdvi(0, ch2, 0, &dvi_list, &dvi_iosb, 0, 0, 0);
X    ERR_SIGNAL(ret); ERR_SIGNAL(dvi_iosb.status);
X    out_mbx_name`5B64`5D = '\0';
X    out_desc.dsc$a_pointer = out_mbx_name;
X    out_desc.dsc$w_length = strlen(out_mbx_name);
X    /*
X    ** Create GHOSTVIEW and DECW$DISPLAY logical names.
X    **
X    ** We use CRELNM rather than LIB$SET_LOGICAL because we want these to be
X    ** user mode and go away when the program exits. It doesn't matter that
V we
X    ** may set them multiple times, as with the mailbox logicals, since once
X    ** Ghostscript starts we don't need them any more.
X    */
X    sprintf(buf, "%d", XtWindow(w));
X    gv_list.item`5B0`5D.buffer_size = strlen(buf);
X    ret = sys$crelnm(0, &lnt_desc, &ghostview_desc, 0, &gv_list);
X    ERR_SIGNAL(ret);
X    dis_list.item`5B0`5D.buffer_p = XDisplayString(XtDisplay(w));
X    dis_list.item`5B0`5D.buffer_size = strlen(dis_list.item`5B0`5D.buffer_p)
V;
X    ret = sys$crelnm(0, &lnt_desc, &display_desc, 0, &dis_list);
X    ERR_SIGNAL(ret);
X    /*
X    ** Spawn Ghostscript process
X    */
X    gvw->ghostview.changed = False;
X    gvw->ghostview.busy = True;
X    cmd_desc.dsc$w_length = strlen(cmd);
X    ret = lib$spawn(&cmd_desc, &in_desc, &out_desc, &nowait, 0, &pid, 0, 0,
X`090, 0, 0, 0, 0);
X    ERR_SIGNAL(ret);
X    XDefineCursor(XtDisplay(gvw), XtWindow(gvw), gvw->ghostview.busy_cursor)
V;
X    /*
X    ** Everything worked, initialize IOSBs and save info about interpretter.
X    */
X    gvw->ghostview.interpreter_pid = pid;
X    if (gvw->ghostview.filename == NULL) `7B
X`09gvw->ghostview.interpreter_input = ch1;
X`09gvw->ghostview.interpreter_input_iosb`5B0`5D = 0;
X    `7D
X    gvw->ghostview.interpreter_output = ch2;
X    if (gvw->ghostview.output_buffer == NULL) `7B
X`09gvw->ghostview.output_buffer = XtMalloc(GV_BUFSIZ);
X    `7D
X    GLInsert(gvw);
X    /*
X    ** Fake a completed I/O so Output will get called to queue the first I/O
V.
X    */
X    gvw->ghostview.interpreter_output_iosb`5B0`5D = SS$_NORMAL;
X    gvw->ghostview.interpreter_output_iosb`5B1`5D = -1;
X    IOComplete();
X`7D
X
X/* Stop the interperter, if present, and remove any Input sources. */
X/* Also reset the busy state. */
Xstatic void
XStopInterpreter(w)
X    Widget w;
X`7B
X    int ret;
X   `20
X    GhostviewWidget gvw = (GhostviewWidget) w;
X    if (gvw->ghostview.interpreter_pid >= 0) `7B
X`09ret = sys$delprc(&gvw->ghostview.interpreter_pid, 0);
X`09if(ret != SS$_NORMAL && ret != SS$_NONEXPR)lib$signal(ret, 0, 0);
X`09gvw->ghostview.interpreter_pid = -1;
X    `7D
X    if (gvw->ghostview.interpreter_input >= 0) `7B
X`09(void) sys$dassgn(gvw->ghostview.interpreter_input);
X`09gvw->ghostview.interpreter_input = -1;
X`09while (gvw->ghostview.ps_input) `7B
X`09    struct record_list *ps_old = gvw->ghostview.ps_input;
X`09    gvw->ghostview.ps_input = ps_old->next;
X`09    if (ps_old->close) fclose(ps_old->fp);
X`09    XtFree((char *)ps_old);
X`09`7D
X    `7D
X    if (gvw->ghostview.interpreter_output >= 0) `7B
X`09(void) sys$dassgn(gvw->ghostview.interpreter_output);
X`09gvw->ghostview.interpreter_output = -1;
X    `7D
X    gvw->ghostview.busy = False;
X    XDefineCursor(XtDisplay(gvw), XtWindow(gvw), gvw->ghostview.cursor);
X    GLRemove(gvw);
X`7D
X
X/* GhostviewSendPS:
X *   Queue a portion of a PostScript file for output to ghostscript.
X *   fp: FILE * of the file in question.  NOTE: if you have several
X *   Ghostview widgets reading from the same file.  You must open
X *   a unique FILE * for each widget.
X *   SendPS does not actually send the PostScript, it merely queues it
X *   for output.
X *   begin: position in file (returned from ftell()) to start.
X *   len:   number of bytes to write.
X *
X *   If an interpreter is not running, nothing is queued and
X *   False is returned.
X */
XBoolean
XGhostviewSendPS(w, fp, begin, len, close)
X    Widget w;
X    FILE *fp;
X    long begin;
X    unsigned int len;
X    Bool close;
X`7B
X    GhostviewWidget gvw = (GhostviewWidget) w;
X    struct record_list *ps_new;
X
X    if (gvw->ghostview.interpreter_input < 0) return False;
X    if(len != 0)`7B
X`09ps_new = (struct record_list *) XtMalloc(sizeof (struct record_list));
X`09ps_new->fp = fp;
X`09ps_new->begin = begin;
X`09ps_new->len = len;
X`09ps_new->seek_needed = True;
X`09ps_new->close = close;
X`09ps_new->next = NULL;
X
X`09if (gvw->ghostview.input_buffer == NULL) `7B
X`09    gvw->ghostview.input_buffer = XtMalloc(GV_BUFSIZ);
X`09`7D
X
X`09if (gvw->ghostview.ps_input == NULL) `7B
X`09    gvw->ghostview.bytes_left = len;
X`09    gvw->ghostview.ps_input = ps_new;
X`09    /*
X`09    ** Fake a completed I/O so Input will get called to queue the
X`09    ** first I/O.
X`09    */
X`09    gvw->ghostview.interpreter_input_iosb`5B0`5D = SS$_NORMAL;
X`09    gvw->ghostview.interpreter_input_iosb`5B1`5D = -1;
X`09    IOComplete();
X`09`7D else `7B
X`09    struct record_list *p = gvw->ghostview.ps_input;
X`09    while (p->next != NULL) `7B
X`09`09p = p->next;
X`09    `7D
X`09    p->next = ps_new;
X`09`7D
X    `7D
X    return True;
X`7D
X#endif /* VMS */
$ CALL UNPACK GHOSTVIEW.C;1 1998451905
$ create 'f'
X/*
X * Ghostview.h -- Public header file for Ghostview widget.
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#ifndef _Ghostview_h
X#define _Ghostview_h
X/* Be sure that FILE* is defined */
X#include <stdio.h>
X
X/****************************************************************
X *
X * Ghostview widget
X *
X ****************************************************************/
X
X/* Resources:
X
X Name`09`09     Class`09`09RepType`09`09Default Value
X ----`09`09     -----`09`09-------`09`09-------------
X background`09     Background`09`09Pixel`09`09XtDefaultBackground
X border`09`09     BorderColor`09Pixel`09`09XtDefaultForeground
X borderWidth`09     BorderWidth`09Dimension`091
X bottomMargin`09     Margin`09`09int`09`090
X busyCursor`09     Cursor`09`09Cursor`09`09watch
X callback`09     Callback`09`09Pointer`09`09NULL
X cursor`09`09     Cursor`09`09Cursor`09`09crosshair
X destroyCallback     Callback`09`09Pointer`09`09NULL
X filename`09     Filename`09`09String`09`09"-"
X height`09`09     Height`09`09Dimension`090
X interpreter`09     Interpreter`09String`09`09"gs"
X leftMargin`09     Margin`09`09int`09`090
X llx`09`09     BoundingBox`09Int`09`090
X lly`09`09     BoundingBox`09Int`09`090
X mappedWhenManaged   MappedWhenManaged`09Boolean`09`09True
X messageCallback     Callback`09`09Pointer`09`09NULL
X orientation`09     Orientation`09PageOrientation`09Portrait
X outputCallback      Callback`09`09Pointer`09`09NULL
X preload`09     Preload`09`09String`09`09NULL
X quiet`09`09     Quiet`09`09Boolean`09`09True
X rightMargin`09     Margin`09`09int`09`090
X topMargin`09     Margin`09`09int`09`090
X urx`09`09     BoundingBox`09Int`09`09612
X ury`09`09     BoundingBox`09Int`09`09792
X useBackingPixmap    UseBackingPixmap`09Boolean`09`09True
X width`09`09     Width`09`09Dimension`090
X x`09`09     Position`09`09Position`090
X xdpi`09`09     Resolution`09`09Float`09`09**
X y`09`09     Position`09`09Position`090
X ydpi`09`09     Resolution`09`09Float`09`09**
X
X ** automatically calculated from display parameters if width and
X    height are not set.
X
X*/
X
X/* define any special resource names here that are not in <X11/StringDefs.h>
V */
X
X#define XtNbusyCursor "busyCursor"
X#define XtNcursor "cursor"
X#define XtNfilename "filename"
X#define XtNinterpreter "interpreter"
X#define XtNmessageCallback "messageCallback"
X#define XtNoutputCallback "outputCallback"
X#define XtNpreload "preload"
X#define XtNquiet "quiet"
X#define XtNllx "llx"
X#define XtNlly "lly"
X#define XtNurx "urx"
X#define XtNury "ury"
X#define XtNuseBackingPixmap "useBackingPixmap"
X#define XtNxdpi "xdpi"
X#define XtNydpi "ydpi"
X#define XtNrightMargin "rightMargin"
X#define XtNleftMargin "leftMargin"
X#define XtNbottomMargin "bottomMargin"
X#define XtNtopMargin "topMargin"
X
X#define XtCBoundingBox "BoundingBox"
X#define XtCFilename "Filename"
X#define XtCInterpreter "Interpreter"
X#define XtCPreload "Preload"
X#define XtCQuiet "Quiet"
X#define XtCResolution "Resolution"
X#define XtCUseBackingPixmap "UseBackingPixmap"
X
X#define XtRPageOrientation "PageOrientation"
X
X/***************************************************************************
V***
X * XmuCvtStringToPageOrientation
X */
X/* Number represents clockwise rotation of the paper in degrees */
Xtypedef enum `7B
X    XtPageOrientationPortrait`09=   0,`09/* Normal portrait orientation */
X    XtPageOrientationLandscape`09=  90,`09/* Normal landscape orientation */
X    XtPageOrientationUpsideDown = 180,`09/* Don't think this will be used mu
Vch */
X    XtPageOrientationSeascape`09= 270`09/* Landscape rotated the other way *
V/
X`7D XtPageOrientation;
X#define XtEportrait "portrait"
X#define XtElandscape "landscape"
X#define XtEupsideDown "upside-down"
X#define XtEseascape "seascape"
X#define XtRPageOrientation "PageOrientation"
Xextern Boolean XmuCvtStringToPageOrientation();
X
X/* declare specific GhostviewWidget class and instance datatypes */
X
Xtypedef struct _GhostviewClassRec*`09GhostviewWidgetClass;
Xtypedef struct _GhostviewRec*`09`09GhostviewWidget;
X
X/* declare the class constant */
X
Xextern WidgetClass ghostviewWidgetClass;
X
X/* Public routines */
X
Xextern void GhostviewEnableInterpreter(
X#if NeedFunctionPrototypes
X    Widget`09/* w */
X#endif
X);
X
Xextern void GhostviewDisableInterpreter(
X#if NeedFunctionPrototypes
X    Widget`09/* w */
X#endif
X);
X
Xextern Boolean GhostviewIsInterpreterReady(
X#if NeedFunctionPrototypes
X    Widget`09/* w */
X#endif
X);
X
Xextern Boolean GhostviewIsInterpreterRunning(
X#if NeedFunctionPrototypes
X    Widget`09/* w */
X#endif
X);
X
Xextern Pixmap GhostviewGetBackingPixmap(
X#if NeedFunctionPrototypes
X    Widget`09/* w */
X#endif
X);
X
Xextern Boolean GhostviewSendPS(
X#if NeedFunctionPrototypes
X    Widget`09/* widget */,
X    FILE*`09/* fp */,
X    long`09/* begin */,
X    unsigned int`09/* len */,
X    Bool`09/* close */
X#endif
X);
X
Xextern Boolean GhostviewNextPage(
X#if NeedFunctionPrototypes
X    Widget`09/* w */
X#endif
X);
X
X/* The structure returned by the regular callback */
X
Xtypedef struct _GhostviewReturnStruct `7B
X    int width, height;
X    int`09psx, psy;
X    float xdpi, ydpi;
X`7D GhostviewReturnStruct;
X
X#endif /* _Ghostview_h */
$ CALL UNPACK GHOSTVIEW.H;1 1176915432
$ create 'f'
X.\"  ghostview.man -- Man page for ghostview application
X.\"  Copyright (C) 1992  Timothy O. Theisen
X.\"`20
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.\"`20
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.\"`20
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.\"`20
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.TH GHOSTVIEW 1
X.SH NAME
X\fIghostview\fR \- View PostScript documents using ghostscript
X.SH SYNOPSIS
X.B ghostview
X`5Bfilename`5D
X.br
Xor
X.br
X.B ghostview
X`5B\-staticgray`5D `5B\-grayscale`5D
X`5B\-staticcolor`5D `5B\-pseudocolor`5D `5B\-truecolor`5D `5B\-directcolor`5
VD
X`5B\-`5Bno`5Dinstall`5D `5B\-`5Bno`5Dprivate`5D `5B\-`5Bno`5Dcenter`5D
X`5B\-`5Bno`5Dtitle`5D `5B\-`5Bno`5Ddate`5D `5B\-`5Bno`5Dlocator`5D `5B\-`5Bn
Vo`5Dlabels`5D
X`5B\-resolution\ \fIdpi\fP`5D `5B\-dpi\ \fIdpi\fP`5D
X`5B\-xdpi\ \fIdpi\fP`5D `5B\-ydpi\ \fIdpi\fP`5D
X`5B\-`5Bno`5Dquiet`5D `5B\-preload\ \fIfile\fP`5D `5B\-magstep\ \fIn\fP`5D
X`5B\-portrait`5D `5B\-landscape`5D `5B\-upsidedown`5D `5B\-seascape`5D
X`5B\-letter`5D `5B\-tabloid`5D `5B\-ledger`5D `5B\-legal`5D `5B\-statement`5
VD
X`5B\-executive`5D `5B\-a3`5D `5B\-a4`5D `5B\-a5`5D `5B\-b4`5D `5B\-b5`5D
X`5B\-folio`5D `5B\-quarto`5D `5B\-10x14`5D
X`5B\-force`5D `5B\-forceorientation`5D `5B\-forcemedia`5D
X`5B\-`5Bno`5Dswap`5D `5B\-`5Bno`5Dopenwindows`5D `5B\-`5Bno`5Dncdwm`5D
X`5B\-page \fIlabel\fP`5D `5B\-\fItoolkitoption\fR\ ...`5D
X`5Bfilename`5D
X.SH DESCRIPTION
XThe \fIghostview\fP program provides an X11 user interface for
Xthe \fIghostscript\fP interpreter.
X\fIGhostview\fP and \fIghostscript\fP function as two cooperating programs.
X\fIGhostview\fP creates the viewing window and \fIghostscript\fP draws in it
V.
X.PP
XDon't be alarmed by the number of options.
XGenerally, one invokes \fIghostview\fP with just one parameter, the name of
Xthe file to be previewed.  If the filename is `60`60-'', \fIghostview\fP wil
Vl read
Xfrom `60`60stdin''.
XThe options provide a way to set X resources from
Xthe command line for a single invocation of \fIghostview\fP.  For that reaso
Vn,
Xdiscussion of the options is delayed until after the X resources are discuss
Ved.
X.SH MAIN WINDOW
XThe main viewport is on the right side of the main window.
XIf the page is larger than the viewport, there will be scroll bars along the
Xbottom and right edges of the viewport.
XTo the left of the viewport is the table of contents.
XIf the PostScript file has document structuring convention (DSC) comments,
Xthe table of context will display the page labels (i.e. usually page numbers
V).
XTo the left of the table of contents is the menu box.
XEach push button brings up a popup menu.
XOver the menu box and table of contents there are three optional labels
Xthat contain the title, date, and locator.
XThe title label contains the document title found in the DSC comments.
XIf no title can be found, the filename is used in its place.
XThe date label contains the document date found in the DSC comments.
XIf no date can be found, the last modified date of the file is
Xused in its place.
XSince the title and date labels may be clipped by the main viewport,
Xthe date and title labels are push buttons that bring up a popup window
Xwith the title or date.
XThese popup windows also show the `60`60document'' icon when the displayed s
Vtring
Xcomes from the DSC comments.
XThe locator shows the location of the cursor in the viewport.
XThe location is expressed in the default user coordinate system.
XThe locator is useful for measuring bounding boxes.
X.PP
XWithin the main viewport the mouse cursor is a `60`60target'' when
X\fIghostscript\fP is doing work.
XThe cursor is a `60`60cross hair'' when \fIghostscript\fP is idle.
XWhen moving to another page in a document, it is generally best to wait
Xfor \fIghostscript\fP to become idle.  Otherwise, the current \fIghostscript
V\fP process
Xmust be killed and the overhead of reading the prologue is incurred again.
X.PP
X\fIGhostview\fP will check to see if the file has been modified just before
Xit displays a page or when the application is deiconified.
XIf the file has changed, it will reopen the file.
X.PP
XClicking anywhere within the viewport will popup a zoom window.
XThe window is centered about the location that was clicked.
XClicking with the first mouse button pops up a low resolution zoom window.
XClicking with the second mouse button pops up a medium resolution zoom windo
Vw.
XClicking with the third mouse button pops up a high resolution zoom window.
XThe cursor in the zoom window will display a `60`60target'' or `60`60cross h
Vair''
Xdepending on the state of \fIghostscript\fP.
XThe locator reports the position of the cursor in the zoom windows
Xas well as the main viewport.
X.PP
XIn the table of contents, the first and third mouse button functions exactly
Xas they do in a Text widget.
XThat is the first mouse button selects text and the third mouse button
Xextends selections.
XHowever, clicking on a page label with the second mouse button will cause
Xthat page to be shown.
XThe page being displayed is marked with a '<' in the right margin of
Xthe table of contents.
X.SH POPUP WINDOWS
XThe are several additional windows that may appear.
XThe \fIcopyright\fP window will appear whenever copyright information is
Xrequested.
XThe \fIinformation\fP window appears whenever the \fIghostscript\fP process
Xwrites to `60`60stdout'' or `60`60stderr''.
XWhenever there is an error in the PostScript program, the stack trace will
Xappear in this window.
XWhen \fIghostscript\fP is invoked without the quiet option, informational me
Vssage
Xregarding the state of \fIghostscript\fP will appear in the \fIinformation\f
VP window.
XThe \fIcopyright\fP and \fIinformation\fP windows can be dismissed by pushin
Vg
Xthe `60`60Dismiss'' button.
X.PP
XThe \fISelect File\fP dialog widget will appear when you wish to open or sav
Ve
Xa file.
XThe
X.I Select File
Xdialog widget
Xallows an X11 user to select a file by typing the path or by browsing in
Xdirectory listings and selecting entries with the mouse.
X.PP
XThe space bar can be pressed to complete filenames, and tilde is used for ho
Vme
Xdirectories.
XAll the usual key bindings can be used in the text widget, except for Return
Xand Control\-M, which are equivalent to pressing the OK button.
XThe path can be scrolled using the large horizontal scroll bar, or by moving
Xthe insertion cursor in the text widget.
XThe directory entries can be scrolled using the vertical scroll bars, or by
Xholding a mouse button down and moving out of the listing.
XThe scrolling speed varies with the distance from the listing.
X.PP
XThe directory entries are terminated with special characters that show the
Xtype of entry, similar to the
X.I \-F
Xoption of
X.IR ls (1).
X.PP
XThe
X.I Select File
Xdialog widget is in total control until is pops down.
XNo other controls in \fIghostview\fP will be active during this time.
X.SH MENUS
XThere are five buttons in the menu box.  They are the
X\fBFile\fP, \fBPage\fP, \fBMagstep\fP, \fBOrientation\fP, and \fBMedia\fP
Xbuttons.
XThere are keyboard accelerators for most of the popup menus.  Be sure
Xto read the keyboard accelerator section.
X.IP \fBFile\fB 1i
XThis popup menu controls file access:
X.RS 1i
X.IP "\fBOpen...\fP" 1i
XPops up the Select File window in preparation to open a file.
XThe Select File widget is in total control until it pops down.
XOpens the file for viewing.
X.IP "\fBReopen\fP" 1i
XReopens the current file.
X.IP "\fBPrint...\fP" 1i
XPops up a dialog widget to ask for the printer name.
XSends the whole document to the printer.
X.IP "\fBPrint marked pages...\fP" 1i
XPops up a dialog widget to ask for the printer name.
XSends the marked pages to the printer.
XIf no pages have been marked, the mark procedure is called before
Xprinting and then the unmark procedure is called after printing.
X.IP "\fBSave marked pages...\fP" 1i
XPops up the Select File window in preparation to save a file.
XThe Select File widget is in total control until it pops down.
XSaves the marked pages in the selected file.
XIf no pages have been marked, the mark procedure is called before
Xsaving and then the unmark procedure is called after saving.
X.IP "\fBCopyright...\fP" 1i
XPops up the \fIcopyright\fP window.
X.IP "\fBQuit\fP" 1i
XCauses \fIghostview\fP to exit.
X.RS -1i
X.IP \fBPage\fP 1i
XThis popup menu controls page access:
X.RS 1i
X.IP "\fBNext\fP" 1i
XDisplay the next page.
X.IP "\fBRedisplay\fP" 1i
XDisplay the current page.
X.IP "\fBPrevious\fP" 1i
XDisplay the previous page.
X.IP "\fBCenter\fP" 1i
XCenter the page in the viewport.
X.IP "\fBMark\fP" 1i
XMark the pages that have been selected in the table of contents.
XIf no pages have been selected, mark the current page.
X.IP "\fBUnmark\fP" 1i
+-+-+-+-+-+-+-+-  END  OF PART 4 +-+-+-+-+-+-+-+-
Technical Details
Message-ID: <8881760@MVB.SAIC.COM>
Path: arc1-ca.pugleaf.net!sparky!uunet!europa.asd.contel.com!darwin.sura.net!zaphod.mps.ohio-state.edu!swrinde!elroy.jpl.nasa.gov!usc!news.service.uci.edu!unogate!mvb.saic.com!vmsnet-sources

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!sparky!uunet!europa.asd.contel.com!darwin.sura.net!zaphod.mps.ohio-state.edu!swrinde!elroy.jpl.nasa.gov!usc!news.service.uci.edu!unogate!mvb.saic.com!vmsnet-sources
Newsgroups: vmsnet.sources
From: Terry Poot <tp@mccall.com>
Subject: Ghostview for VMS 04/14
Message-ID: <8881760@MVB.SAIC.COM>
Date: Thu, 29 Oct 1992 18:49:24 GMT
Lines: 1411
Approved: Mark.Berryman@Mvb.Saic.Com