🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: vmsnet.sources
Article #17

Ghostview for VMS 03/14

#17
From: Terry Poot
Date: Thu, 29 Oct 1992 18:49
1365 lines
49205 bytes
Submitted-by: Terry Poot <tp@mccall.com>
Posting-number: Volume 3, Issue 221
Archive-name: ghostview/part03

-+-+-+-+-+-+-+-+ START OF PART 3 -+-+-+-+-+-+-+-+
X`09SFDir`09`09*dir;
X`09int`09`09n;
X`09XawTextPosition`09pos;
X`09int`09SFdirPtrSave;
X
X`09SFdirPtrSave = SFdirPtr;
X`09SFdirPtr = (*new) * SFdirEnd;
X`09if (SFdirPtr == SFdirPtrSave) `7B
X`09`09return;
X`09`7D
X
X`09SFdrawLists(SF_DO_SCROLL);
X
X`09n = 2;
X`09while (SFdirPtr + n >= SFdirEnd) `7B
X`09`09n--;
X`09`7D
X
X`09dir = &(SFdirs`5BSFdirPtr + n`5D);
X
X`09pos = dir->path - SFcurrentPath;
X
X`09if (!strncmp(SFcurrentPath, SFstartDir, strlen(SFstartDir))) `7B
X`09`09pos -= strlen(SFstartDir);
X`09`09if (pos < 0) `7B
X`09`09`09pos = 0;
X`09`09`7D
X`09`7D
X
X`09XawTextSetInsertionPoint(selFileField, pos);
X`7D
X
X/* ARGSUSED */
X
Xvoid
XSFpathAreaSelectedCallback(w, client_data, pnew)
X`09Widget`09`09w;
X`09XtPointer`09client_data;
X`09int`09`09pnew;
X`7B
X`09int`09new;
X`09float`09f;
X
X`09new = SFdirPtr + (((double) pnew) / SFpathScrollWidth) * SFdirEnd;
X
X`09if (new > SFdirEnd - 3) `7B
X`09`09new = SFdirEnd - 3;
X`09`7D
X
X`09if (new < 0) `7B
X`09`09new = 0;
X`09`7D
X
X`09f = ((double) new) / SFdirEnd;
X
X`09XawScrollbarSetThumb(
X`09`09w,
X`09`09f,
X`09`09(float) (((double) ((SFdirEnd < 3) ? SFdirEnd : 3)) /
X`09`09`09SFdirEnd)
X`09);
X
X`09SFpathSliderMovedCallback(w, (XtPointer) NULL, &f);
X`7D
X
XBoolean
XSFworkProc()
X`7B
X`09register SFDir`09`09*dir;
X`09register SFEntry`09*entry;
X
X`09for (dir = &(SFdirs`5BSFdirEnd - 1`5D); dir >= SFdirs; dir--) `7B
X`09`09if (!(dir->nEntries)) `7B
X`09`09`09continue;
X`09`09`7D
X`09`09for (
X`09`09`09entry = &(dir->entries`5Bdir->nEntries - 1`5D);
X`09`09`09entry >= dir->entries;
X`09`09`09entry--
X`09`09) `7B
X`09`09`09if (!(entry->statDone)) `7B
X`09`09`09`09(void) SFstatAndCheck(dir, entry);
X`09`09`09`09return False;
X`09`09`09`7D
X`09`09`7D
X`09`7D
X
X`09SFworkProcAdded = 0;
X
X`09return True;
X`7D
$ CALL UNPACK DRAW.C;1 1853666754
$ create 'f'
X/*
X * Copyright (c) 1987 Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that: (1) source distributions retain this entire copyright
X * notice and comment, and (2) distributions including binaries display
X * the following acknowledgement:  `60`60This product includes software
X * developed by the University of California, Berkeley and its contributors'
V'
X * in the documentation or other materials provided with the distribution
X * and in all advertising materials mentioning features or use of this
X * software. Neither the name of the University nor the names of its
X * contributors may be used to endorse or promote products derived
X * from this software without specific prior written permission.
X * THIS SOFTWARE IS PROVIDED `60`60AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X */
X
X#if defined(LIBC_SCCS) && !defined(lint)
Xstatic char sccsid`5B`5D = "@(#)getenv.c`095.7 (Berkeley) 6/1/90";
X#endif /* LIBC_SCCS and not lint */
X
X#include <stdio.h>
X
X/*
X * getenv --
X *`09Returns ptr to value associated with name, if any, else NULL.
X */
Xchar *
Xgetenv(name)
X`09char *name;
X`7B
X`09int offset;
X`09char *_findenv();
X
X`09return(_findenv(name, &offset));
X`7D
X
X/*
X * _findenv --
X *`09Returns pointer to value associated with name, if any, else NULL.
X *`09Sets offset to be the offset of the name/value combination in the
X *`09environmental array, for use by setenv(3) and unsetenv(3).
X *`09Explicitly removes '=' in argument name.
X *
X *`09This routine *should* be a static; don't use it.
X */
Xchar *
X_findenv(name, offset)
X`09register char *name;
X`09int *offset;
X`7B
X`09extern char **environ;
X`09register int len;
X`09register char **P, *C;
X
X`09for (C = name, len = 0; *C && *C != '='; ++C, ++len);
X`09for (P = environ; *P; ++P)
X`09`09if (!strncmp(*P, name, len))
X`09`09`09if (*(C = *P + len) == '=') `7B
X`09`09`09`09*offset = P - environ;
X`09`09`09`09return(++C);
X`09`09`09`7D
X`09return(NULL);
X`7D
$ CALL UNPACK GETENV.C;1 170920290
$ create 'f'
X!  Ghostview.ad -- Application defaults file for ghostview.
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
X! All of the button labels and actions are determined in this file.
X! It should be easy to adapt to any language.
X! To use a different version of ghostscript, you can add the resource
X! *Ghostview.interpreter: /my/very/own/gs
X
X*input:`09True
X*allowShellResize:`09True
X*ShapeStyle:`09Oval
X*Font:`09-adobe-new century schoolbook-medium-r-normal--*-140-*-*-p-*-iso885
V9-1
X*Text*Font:`09-adobe-courier-medium-r-normal--*-140-*-*-m-*-iso8859-1
X*ghostviewButton.Label:`09Ghostview
X*copyright.Label:`09Copyright...
X*quit.Label:`09Quit
X*fileButton.Label:`09File
X*open.Label:`09Open...
X*reopen.Label:`09Reopen
X*printwhole.Label:`09Print...
X*printmarked.Label:`09Print marked pages...
X*save.Label:`09Save marked pages...
X*pageButton.Label:`09Page
X*next.Label:`09Next
X*show.Label:`09Redisplay
X*prev.Label:`09Previous
X*center.Label:`09Center
X*mark.Label:`09Mark
X*unmark.Label:`09Unmark
X*magstepButton.Label:`09Magstep
X*orientationButton.Label:`09Orientation
X*portrait.Label:`09Portrait
X*landscape.Label:`09Landscape
X*upsidedown.Label:`09Upside-down
X*seascape.Label:`09Seascape
X*swap.Label:`09Swap Landscape
X*pagemediaButton.Label:`09Media
X*pageview.useBottom:`09True
X*pageview.useRight:`09True
X*SimpleMenu.baseTranslations:`09#replace \n\
X    <EnterWindow>:`09highlight() \n\
X    <LeaveWindow>:`09unhighlight() \n\
X    <BtnMotion>:`09highlight() \n\
X    <Btn2Up>:`09MenuPopdown() GhostviewForce() notify() unhighlight() \n\
X    <BtnUp>:`09MenuPopdown() GhostviewDefault() notify() unhighlight()
X*SimpleMenu.Translations:`09#replace \n\
X    <EnterWindow>:`09highlight() \n\
X    <LeaveWindow>:`09unhighlight() \n\
X    <BtnMotion>:`09highlight() \n\
X    <Btn2Up>:`09MenuPopdown() GhostviewForce() notify() unhighlight() \n\
X    <BtnUp>:`09MenuPopdown() GhostviewDefault() notify() unhighlight()
X*okay.Label:`09Okay
X*cancel.Label:`09Cancel
X*dismiss.Label:`09Dismiss
X*Ghostview.busyCursor:`09target
XGhostview.baseTranslations:`09#replace \n\
X    <MapNotify>:`09`09GhostviewCheckFile() \n\
X    <Message>WM_PROTOCOLS:`09GhostviewDeleteWindow()
XGhostview.Translations:`09`09#replace \n\
X    <MapNotify>:`09`09GhostviewCheckFile() \n\
X    <Message>WM_PROTOCOLS:`09GhostviewDeleteWindow()
X*TopLevelShell.baseTranslations:`09#replace \n\
X    <Message>WM_PROTOCOLS:`09GhostviewDismiss()
X*TopLevelShell.Translations:`09#replace \n\
X    <Message>WM_PROTOCOLS:`09GhostviewDismiss()
X*TransientShell.baseTranslations:`09#replace \n\
X    <Message>WM_PROTOCOLS:`09GhostviewDismiss()
X*TransientShell.Translations:`09#replace \n\
X    <Message>WM_PROTOCOLS:`09GhostviewDismiss()
X*zoom.form.baseTranslations:`09#replace \n\
X    <Key>Q:`09`09`09GhostviewDeleteZoom()
X*zoom.form.Translations:`09#replace \n\
X    <Key>Q:`09`09`09GhostviewDeleteZoom()
X*zoom.baseTranslations:`09`09#replace \n\
X    <Message>WM_PROTOCOLS:`09GhostviewDeleteWindow()
X*zoom.Translations:`09`09#replace \n\
X    <Message>WM_PROTOCOLS:`09GhostviewDeleteWindow()
X*Ghostview.baseTranslations:`09#replace \n\
X    <Message>:`09message() \n\
X    <EnterWindow>:`09notify(0) \n\
X    <LeaveWindow>:`09GhostviewEraseLocator() \n\
X    <MotionNotify>:`09notify(0) \n\
X    <Btn1Down>:`09notify(180 180 200 200) \n\
X    <Btn2Down>:`09notify(120 120 300 300) \n\
X    <Btn3Down>:`09notify(90 90 400 400)
X*Ghostview.Translations:`09#replace \n\
X    <Message>:`09message() \n\
X    <EnterWindow>:`09notify(0) \n\
X    <LeaveWindow>:`09GhostviewEraseLocator() \n\
X    <MotionNotify>:`09notify(0) \n\
X    <Btn1Down>:`09notify(180 180 200 200) \n\
X    <Btn2Down>:`09notify(120 120 300 300) \n\
X    <Btn3Down>:`09notify(90 90 400 400)
X*toc.baseTranslations:`09#replace \n\
X    <FocusIn>:`09focus-in() \n\
X    <FocusOut>:`09focus-out() \n\
X    <Btn1Down>:`09select-start() \n\
X    <Btn1Motion>:`09extend-adjust() \n\
X    <Btn1Up>:`09extend-end(PRIMARY, CUT_BUFFER0) \n\
X    <Btn2Down>:`09select-start() \n\
X    <Btn2Motion>:`09extend-adjust() \n\
X    <Btn2Up>:`09extend-end(PRIMARY, CUT_BUFFER0) GhostviewShow() \n\
X    <Btn3Down>:`09extend-start() \n\
X    <Btn3Motion>:`09extend-adjust() \n\
X    <Btn3Up>:`09extend-end(PRIMARY, CUT_BUFFER0)
X*toc.Translations:`09#replace \n\
X    <FocusIn>:`09focus-in() \n\
X    <FocusOut>:`09focus-out() \n\
X    <Btn1Down>:`09select-start() \n\
X    <Btn1Motion>:`09extend-adjust() \n\
X    <Btn1Up>:`09extend-end(PRIMARY, CUT_BUFFER0) \n\
X    <Btn2Down>:`09select-start() \n\
X    <Btn2Motion>:`09extend-adjust() \n\
X    <Btn2Up>:`09extend-end(PRIMARY, CUT_BUFFER0) GhostviewShow() \n\
X    <Btn3Down>:`09extend-start() \n\
X    <Btn3Motion>:`09extend-adjust() \n\
X    <Btn3Up>:`09extend-end(PRIMARY, CUT_BUFFER0)
X*Form.baseTranslations:`09#replace \n\
X    <Key>C:`09GhostviewCenter() \n\
X    <Key>Q:`09GhostviewQuit() \n\
X    <Key>O:`09GhostviewOpen() \n\
X    <Key>R:`09GhostviewReopen() \n\
X    <Key>S:`09GhostviewSave() \n\
X    Shift<Key>P:`09GhostviewPrintWhole() \n\
X    <Key>P:`09GhostviewPrintMarked() \n\
X    <Key>BackSpace:`09GhostviewPrevious() \n\
X    <Key>Delete:`09GhostviewPrevious() \n\
X    <Key>B:`09GhostviewPrevious() \n\
X    <Key>Prior:`09GhostviewPrevious() \n\
X    <Key>space:`09GhostviewNext() \n\
X    <Key>Return:`09GhostviewNext() \n\
X    <Key>F:`09GhostviewNext() \n\
X    <Key>Next:`09GhostviewNext() \n\
X    <Key>period:`09GhostviewShow() \n\
X    Ctrl<Key>L:`09GhostviewShow() \n\
X    <Key>M:`09GhostviewMark() \n\
X    <Key>N:`09GhostviewUnmark() \n\
X    <Key>0:`09GhostviewSetMagstep(0) \n\
X    <Key>1:`09GhostviewSetMagstep(1) \n\
X    <Key>2:`09GhostviewSetMagstep(2) \n\
X    <Key>3:`09GhostviewSetMagstep(3) \n\
X    <Key>4:`09GhostviewSetMagstep(4) \n\
X    <Key>5:`09GhostviewSetMagstep(5) \n\
X    <Key>+:`09GhostviewIncreaseMagstep() \n\
X    <Key>-:`09GhostviewDecreaseMagstep() \n\
X    <Key>U:`09GhostviewScrollUp() \n\
X    <Key>D:`09GhostviewScrollDown() \n\
X    <Key>K:`09GhostviewScrollUp() \n\
X    <Key>J:`09GhostviewScrollDown() \n\
X    <Key>H:`09GhostviewScrollLeft() \n\
X    <Key>L:`09GhostviewScrollRight() \n\
X    Shift<Key>Up:`09GhostviewForce() GhostviewSetOrientation(portrait) \n\
X    Shift<Key>Right:`09GhostviewForce() GhostviewSetOrientation(landscape) \
Vn\
X    Shift<Key>Down: GhostviewForce() GhostviewSetOrientation(upside-down) \n
V\
X    Shift<Key>Left:`09GhostviewForce() GhostviewSetOrientation(seascape) \n\
X    <Key>Up:`09GhostviewDefault() GhostviewSetOrientation(portrait) \n\
X    <Key>Right:`09GhostviewDefault() GhostviewSetOrientation(landscape) \n\
X    <Key>Down:`09GhostviewDefault() GhostviewSetOrientation(upside-down) \n\
X    <Key>Left:`09GhostviewDefault() GhostviewSetOrientation(seascape)
X*Form.Translations:`09#replace \n\
X    <Key>C:`09GhostviewCenter() \n\
X    <Key>Q:`09GhostviewQuit() \n\
X    <Key>O:`09GhostviewOpen() \n\
X    <Key>R:`09GhostviewReopen() \n\
X    <Key>S:`09GhostviewSave() \n\
X    Shift<Key>P:`09GhostviewPrintWhole() \n\
X    <Key>P:`09GhostviewPrintMarked() \n\
X    <Key>BackSpace:`09GhostviewPrevious() \n\
X    <Key>Delete:`09GhostviewPrevious() \n\
X    <Key>B:`09GhostviewPrevious() \n\
X    <Key>Prior:`09GhostviewPrevious() \n\
X    <Key>space:`09GhostviewNext() \n\
X    <Key>Return:`09GhostviewNext() \n\
X    <Key>F:`09GhostviewNext() \n\
X    <Key>Next:`09GhostviewNext() \n\
X    <Key>period:`09GhostviewShow() \n\
X    Ctrl<Key>L:`09GhostviewShow() \n\
X    <Key>M:`09GhostviewMark() \n\
X    <Key>N:`09GhostviewUnmark() \n\
X    <Key>0:`09GhostviewSetMagstep(0) \n\
X    <Key>1:`09GhostviewSetMagstep(1) \n\
X    <Key>2:`09GhostviewSetMagstep(2) \n\
X    <Key>3:`09GhostviewSetMagstep(3) \n\
X    <Key>4:`09GhostviewSetMagstep(4) \n\
X    <Key>5:`09GhostviewSetMagstep(5) \n\
X    <Key>+:`09GhostviewIncreaseMagstep() \n\
X    <Key>-:`09GhostviewDecreaseMagstep() \n\
X    <Key>U:`09GhostviewScrollUp() \n\
X    <Key>D:`09GhostviewScrollDown() \n\
X    <Key>K:`09GhostviewScrollUp() \n\
X    <Key>J:`09GhostviewScrollDown() \n\
X    <Key>H:`09GhostviewScrollLeft() \n\
X    <Key>L:`09GhostviewScrollRight() \n\
X    Shift<Key>Up:`09GhostviewForce() GhostviewSetOrientation(portrait) \n\
X    Shift<Key>Right:`09GhostviewForce() GhostviewSetOrientation(landscape) \
Vn\
X    Shift<Key>Down: GhostviewForce() GhostviewSetOrientation(upside-down) \n
V\
X    Shift<Key>Left:`09GhostviewForce() GhostviewSetOrientation(seascape) \n\
X    <Key>Up:`09GhostviewDefault() GhostviewSetOrientation(portrait) \n\
X    <Key>Right:`09GhostviewDefault() GhostviewSetOrientation(landscape) \n\
X    <Key>Down:`09GhostviewDefault() GhostviewSetOrientation(upside-down) \n\
X    <Key>Left:`09GhostviewDefault() GhostviewSetOrientation(seascape)
$ CALL UNPACK GHOSTVIEW.AD;1 290637961
$ create 'f'
X/*
X * Ghostview.c -- 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#include <X11/IntrinsicP.h>
X#include <X11/StringDefs.h>
X#include <X11/Xatom.h>
X#include <X11/Xproto.h>
X#include <X11/Xos.h>
X#include "GhostviewP.h"
X#include <ctype.h>
X
X#ifndef XlibSpecificationRelease
Xtypedef char *XPointer;
X#endif
X
X#include <signal.h>
X#ifdef SIGNALRETURNSINT
X#define SIGVAL int
X#else
X#define SIGVAL void
X#endif
X
X#ifdef NON_BLOCKING_IO
X#include <fcntl.h>
X/* if POSIX O_NONBLOCK is not available, use O_NDELAY */
X#if !defined(O_NONBLOCK) && defined(O_NDELAY)
X#define O_NONBLOCK O_NDELAY
X#endif
X#endif
X
X#include <errno.h>
X/* BSD 4.3 errno.h does not declare errno */
Xextern int errno;
X/* Both error returns are checked for non-blocking I/O. */
X/* Manufacture the other error code if only one exists. */
X#if !defined(EWOULDBLOCK) && defined(EAGAIN)
X#define EWOULDBLOCK EAGAIN
X#endif
X#if !defined(EAGAIN) && defined(EWOULDBLOCK)
X#define EAGAIN EWOULDBLOCK
X#endif
X
X#ifndef VMS
X/* GV_BUFSIZ is set to the minimum POSIX PIPE_BUF to ensure that
X * nonblocking writes to ghostscript will work properly.
X */
X#define GV_BUFSIZ 512
X#else /* VMS */
X/*
X** GV_BUFSIZ is the maximum length line we can handle, so we up it to 1024
X*/
X#define GV_BUFSIZ 1024
X#endif /* VMS */
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#define iscomment(a, b) (strncmp(a, b, length(b)) == 0)
X
Xstatic void ComputeXdpi();
Xstatic void ComputeYdpi();
X
Xstatic XtResource resources`5B`5D = `7B
X#define offset(field) XtOffsetOf(GhostviewRec, ghostview.field)
X    `7B XtNbottomMargin, XtCMargin, XtRInt, sizeof(int),
X`09  offset(bottom_margin), XtRImmediate, (XtPointer)0 `7D,
X    `7B XtNbusyCursor, XtCCursor, XtRCursor, sizeof(XtPointer),
X`09  offset(busy_cursor), XtRString, "watch" `7D,
X    `7B XtNcallback, XtCCallback, XtRCallback, sizeof(XtPointer),
X`09  offset(callback), XtRCallback, (XtPointer)NULL `7D,
X    `7B XtNcursor, XtCCursor, XtRCursor, sizeof(XtPointer),
X`09  offset(cursor), XtRString, "crosshair" `7D,
X    `7B XtNfilename, XtCFilename, XtRString, sizeof(String),
X`09  offset(filename), XtRString, (XtPointer)NULL `7D,
X    `7B XtNinterpreter, XtCInterpreter, XtRString, sizeof(String),
X`09  offset(interpreter), XtRString, "gs" `7D,
X    `7B XtNleftMargin, XtCMargin, XtRInt, sizeof(int),
X`09  offset(left_margin), XtRImmediate, (XtPointer)0 `7D,
X    `7B XtNllx, XtCBoundingBox, XtRInt, sizeof(int),
X`09  offset(llx), XtRImmediate, (XtPointer)0 `7D,
X    `7B XtNlly, XtCBoundingBox, XtRInt, sizeof(int),
X`09  offset(lly), XtRImmediate, (XtPointer)0 `7D,
X    `7B XtNmessageCallback, XtCCallback, XtRCallback, sizeof(XtPointer),
X`09  offset(message_callback), XtRCallback, (XtPointer)NULL `7D,
X    `7B XtNorientation, XtCOrientation, XtRPageOrientation,
X`09  sizeof(XtPageOrientation), offset(orientation), XtRImmediate,
X`09  (XtPointer)XtPageOrientationPortrait `7D,
X    `7B XtNoutputCallback, XtCCallback, XtRCallback, sizeof(XtPointer),
X`09  offset(output_callback), XtRCallback, (XtPointer)NULL `7D,
X    `7B XtNpreload, XtCPreload, XtRString, sizeof(String),
X`09  offset(preload), XtRString, (XtPointer)NULL `7D,
X    `7B XtNquiet, XtCQuiet, XtRBoolean, sizeof(Boolean),
X`09  offset(quiet), XtRImmediate, (XtPointer)True `7D,
X    `7B XtNrightMargin, XtCMargin, XtRInt, sizeof(int),
X`09  offset(right_margin), XtRImmediate, (XtPointer)0 `7D,
X    `7B XtNtopMargin, XtCMargin, XtRInt, sizeof(int),
X`09  offset(top_margin), XtRImmediate, (XtPointer)0 `7D,
X    `7B XtNuseBackingPixmap, XtCUseBackingPixmap, XtRBoolean, sizeof(Boolean
V),
X`09  offset(use_bpixmap), XtRImmediate, (XtPointer)True `7D,
X    `7B XtNurx, XtCBoundingBox, XtRInt, sizeof(int),
X`09  offset(urx), XtRImmediate, (XtPointer)612 `7D,
X    `7B XtNury, XtCBoundingBox, XtRInt, sizeof(int),
X`09  offset(ury), XtRImmediate, (XtPointer)792 `7D,
X    `7B XtNxdpi, XtCResolution, XtRFloat, sizeof(float),
X`09  offset(xdpi), XtRCallProc, (XtPointer)ComputeXdpi `7D,
X    `7B XtNydpi, XtCResolution, XtRFloat, sizeof(float),
X`09  offset(ydpi), XtRCallProc, (XtPointer)ComputeYdpi `7D,
X#undef offset
X`7D;
X
Xstatic void Message();
Xstatic void Notify();
Xstatic void Input();
Xstatic void Output();
X
Xstatic void ClassInitialize();
Xstatic void ClassPartInitialize();
Xstatic void Initialize();
Xstatic void Realize();
Xstatic void Destroy();
Xstatic void Resize();
Xstatic Boolean SetValues();
Xstatic XtGeometryResult QueryGeometry();
X
Xstatic void Layout();
Xstatic Boolean ComputeSize();
Xstatic void ChangeSize();
Xstatic Boolean Setup();
Xstatic void StartInterpreter();
Xstatic void StopInterpreter();
Xstatic void InterpreterFailed();
X
Xstatic XtActionsRec actions`5B`5D =
X`7B
X    `7B"message",`09Message`7D,
X    `7B"notify",`09Notify`7D,
X`7D;
X
X/* notify takes zero to four parameters.  The first two give the width and
X * height of the zoom requested in the default user coordinate system.
X * If they are omitted, a default value of 72 is provided.  If the second
X * parameter is omitted, the zoom area is assumed to be a square.
X * The next two parameters give the desired resolution of the zoom window.
X * If they are omitted, a default value of 300 is provided. If the four
X * parameter is omitted, the y resolution is assumed to be equal to the
X * x resolution.
X */
Xstatic char translations`5B`5D =
X"<Message>:`09`09message()`09\n\
X<Btn1Down>:`09`09notify(72)`09\n\
X<Btn2Down>:`09`09notify(108)`09\n\
X<Btn3Down>:`09`09notify(144)`09\n\
X";
X
XGhostviewClassRec ghostviewClassRec = `7B
X  `7B /* core fields */
X    /* superclass`09`09*/`09(WidgetClass) &coreClassRec,
X    /* class_name`09`09*/`09"Ghostview",
X    /* widget_size`09`09*/`09sizeof(GhostviewRec),
X    /* class_initialize`09`09*/`09ClassInitialize,
X    /* class_part_initialize`09*/`09ClassPartInitialize,
X    /* class_inited`09`09*/`09FALSE,
X    /* initialize`09`09*/`09Initialize,
X    /* initialize_hook`09`09*/`09NULL,
X    /* realize`09`09`09*/`09Realize,
X    /* actions`09`09`09*/`09actions,
X    /* num_actions`09`09*/`09XtNumber(actions),
X    /* resources`09`09*/`09resources,
X    /* num_resources`09`09*/`09XtNumber(resources),
X    /* xrm_class`09`09*/`09NULLQUARK,
X    /* compress_motion`09`09*/`09TRUE,
X    /* compress_exposure`09*/`09TRUE,
X    /* compress_enterleave`09*/`09TRUE,
X    /* visible_interest`09`09*/`09FALSE,
X    /* destroy`09`09`09*/`09Destroy,
X    /* resize`09`09`09*/`09Resize,
X    /* expose`09`09`09*/`09NULL,
X    /* set_values`09`09*/`09SetValues,
X    /* set_values_hook`09`09*/`09NULL,
X    /* set_values_almost`09*/`09XtInheritSetValuesAlmost,
X    /* get_values_hook`09`09*/`09NULL,
X    /* accept_focus`09`09*/`09NULL,
X    /* version`09`09`09*/`09XtVersion,
X    /* callback_private`09`09*/`09NULL,
X    /* tm_table`09`09`09*/`09translations,
X    /* query_geometry`09`09*/`09QueryGeometry,
X    /* display_accelerator`09*/`09XtInheritDisplayAccelerator,
X    /* extension`09`09*/`09NULL
X  `7D,
X  `7B /* ghostview fields */
X    /* ghostview`09`09*/`09NULL,
X    /* next`09`09`09*/`09NULL,
X    /* page`09`09`09*/`09NULL,
X    /* done`09`09`09*/`09NULL
X  `7D
X`7D;
X
XWidgetClass ghostviewWidgetClass = (WidgetClass)&ghostviewClassRec;
X
X/* Procedures that compute the default xdpi and ydpi from display parameters
V */
X
Xstatic void
XComputeXdpi(w, offset, value)
X    Widget w;
X    int offset;
X    XrmValue *value;
X`7B
X    static float xdpi;
X    xdpi = 25.4 * WidthOfScreen(XtScreen(w)) / WidthMMOfScreen(XtScreen(w));
X    value->addr = (XtPointer) &xdpi;
X`7D
X
Xstatic void
XComputeYdpi(w, offset, value)
X    Widget w;
X    int offset;
X    XrmValue *value;
X`7B
X    static float ydpi;
X    ydpi = 25.4 * HeightOfScreen(XtScreen(w)) / HeightMMOfScreen(XtScreen(w)
V);
X    value->addr = (XtPointer) &ydpi;
X`7D
X
X/* Message action routine.
X * Passes ghostscript message events back to application via
X * the message callback.  It also marks the interpreter as
X * being not busy at the end of page, and stops the interpreter
X * when it send a "done" message.
X */
Xstatic void
XMessage(w, event, params, num_params)
X    Widget w;
X    XEvent *event;
X    String *params;`09`09/* unused */
X    Cardinal *num_params;`09/* unused */
X`7B
X    GhostviewWidget gvw = (GhostviewWidget) w;
X    GhostviewWidgetClass gvc = (GhostviewWidgetClass) XtClass(w);
X
X    gvw->ghostview.mwin = event->xclient.data.l`5B0`5D;
X    if (event->xclient.message_type ==
X`09XmuInternAtom(XtDisplay(w), gvc->ghostview_class.page)) `7B
X`09gvw->ghostview.busy = False;
X`09XDefineCursor(XtDisplay(gvw), XtWindow(gvw), gvw->ghostview.cursor);
X`09XtCallCallbackList(w, gvw->ghostview.message_callback, "Page");
X    `7D else if (event->xclient.message_type ==
X`09       XmuInternAtom(XtDisplay(w), gvc->ghostview_class.done)) `7B
X`09StopInterpreter(w);
X`09XtCallCallbackList(w, gvw->ghostview.message_callback, "Done");
X    `7D
X`7D
X
X/* Notify action routine.
X * Calculates where the user clicked in the default user coordinate system.
X * Call the callbacks with the point of click and size of zoom window
X * requested.
X */
Xstatic void
XNotify(w, event, params, num_params)
X    Widget w;
X    XEvent *event;
X    String *params;
X    Cardinal *num_params;
X`7B
X    GhostviewWidget gvw = (GhostviewWidget) w;
X    GhostviewReturnStruct ret_val;
X
X    /* notify takes zero to four parameters.  The first two give the width a
Vnd
X     * height of the zoom requested in the default user coordinate system.
X     * If they are omitted, a default value of 72 is provided.  If the secon
Vd
X     * parameter is omitted, the zoom area is assumed to be a square.
X     * The next two parameters give the desired resolution of the zoom windo
Vw.
X     * If they are omitted, a default value of 300 is provided. If the four
X     * parameter is omitted, the y resolution is assumed to be equal to the
X     * x resolution.
X     */
X    switch (*num_params) `7B
X    case 0:
X`09ret_val.width = ret_val.height = 72;
X`09ret_val.xdpi = ret_val.ydpi = 300;
X`09break;
X    case 1:
X`09ret_val.width = ret_val.height = atoi(params`5B0`5D);
X`09ret_val.xdpi = ret_val.ydpi = 300;
X`09break;
X    case 2:
X`09ret_val.width = atoi(params`5B0`5D);
X`09ret_val.height = atoi(params`5B1`5D);
X`09ret_val.xdpi = ret_val.ydpi = 300;
X`09break;
X    case 3:
X`09ret_val.width = atoi(params`5B0`5D);
X`09ret_val.height = atoi(params`5B1`5D);
X`09ret_val.xdpi = ret_val.ydpi = atoi(params`5B2`5D);
X`09break;
X    default:
X`09ret_val.width = atoi(params`5B0`5D);
X`09ret_val.height = atoi(params`5B1`5D);
X`09ret_val.xdpi = atoi(params`5B2`5D);
X`09ret_val.ydpi = atoi(params`5B3`5D);
X`09break;
X    `7D
X
X    switch (gvw->ghostview.orientation) `7B
X    case XtPageOrientationPortrait:
X`09ret_val.psx = gvw->ghostview.llx +`20
X`09`09      event->xbutton.x * 72.0 / gvw->ghostview.xdpi;
X`09ret_val.psy = gvw->ghostview.ury -`20
X`09`09      event->xbutton.y * 72.0 / gvw->ghostview.ydpi;
X`09break;
X    case XtPageOrientationLandscape:
X`09ret_val.psx = gvw->ghostview.llx +`20
X`09`09      event->xbutton.y * 72.0 / gvw->ghostview.ydpi;
X`09ret_val.psy = gvw->ghostview.lly +`20
X`09`09      event->xbutton.x * 72.0 / gvw->ghostview.xdpi;
X`09break;
X    case XtPageOrientationUpsideDown:
X`09ret_val.psx = gvw->ghostview.urx -`20
X`09`09      event->xbutton.x * 72.0 / gvw->ghostview.xdpi;
X`09ret_val.psy = gvw->ghostview.lly +`20
X`09`09      event->xbutton.y * 72.0 / gvw->ghostview.ydpi;
X`09break;
X    case XtPageOrientationSeascape:
X`09ret_val.psx = gvw->ghostview.urx -`20
X`09`09      event->xbutton.y * 72.0 / gvw->ghostview.ydpi;
X`09ret_val.psy = gvw->ghostview.ury -`20
X`09`09      event->xbutton.x * 72.0 / gvw->ghostview.xdpi;
X`09break;
X    `7D
X    XtCallCallbackList(w, gvw->ghostview.callback, (XtPointer) &ret_val);
X`7D
X
X#ifndef SEEK_SET
X#define SEEK_SET 0
X#endif
X
Xstatic Boolean broken_pipe = False;
X
Xstatic SIGVAL
XCatchPipe(i)
X    int i;
X`7B
X    broken_pipe = True;
X#ifdef SIGNALRETURNSINT
X    return 0;
X#endif
X`7D
X
X#ifndef VMS
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(client_data, source, id)
X    XtPointer client_data;
X    int *source;
X    XtInputId *id;
X`7B
X    Widget w = (Widget) client_data;
X    GhostviewWidget gvw = (GhostviewWidget) w;
X    int bytes_written;
X    SIGVAL (*oldsig)();
X
X    oldsig = signal(SIGPIPE, CatchPipe);
X
X#ifdef NON_BLOCKING_IO
X    do `7B
X#endif
X
X`09if (gvw->ghostview.buffer_bytes_left == 0) `7B
X
X`09    /* Get a new section if required */
X`09    if (gvw->ghostview.ps_input && gvw->ghostview.bytes_left == 0) `7B
X`09`09struct record_list *ps_old = gvw->ghostview.ps_input;
X`09`09gvw->ghostview.ps_input = ps_old->next;
X`09`09if (ps_old->close) fclose(ps_old->fp);
X`09`09XtFree((char *)ps_old);
X`09    `7D
X
X`09    /* Have to seek at the beginning of each section */
X`09    if (gvw->ghostview.ps_input &&
X`09`09gvw->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
X`09    if (gvw->ghostview.bytes_left > GV_BUFSIZ) `7B
X`09`09gvw->ghostview.buffer_bytes_left =
X`09`09`09fread(gvw->ghostview.input_buffer,
X`09`09`09      sizeof (char), GV_BUFSIZ,
X`09`09`09      gvw->ghostview.ps_input->fp);
X`09    `7D else if (gvw->ghostview.bytes_left > 0) `7B
X`09`09gvw->ghostview.buffer_bytes_left =
X`09`09`09fread(gvw->ghostview.input_buffer,
X`09`09`09      sizeof (char), gvw->ghostview.bytes_left,
X`09`09`09      gvw->ghostview.ps_input->fp);
X`09    `7D else `7B
X`09`09gvw->ghostview.buffer_bytes_left = 0;
X`09    `7D
X`09    if (gvw->ghostview.bytes_left > 0 &&
X`09`09gvw->ghostview.buffer_bytes_left == 0) `7B
X`09`09InterpreterFailed(w);`09/* Error occurred */
X`09    `7D
X`09    gvw->ghostview.input_buffer_ptr = gvw->ghostview.input_buffer;
X`09    gvw->ghostview.bytes_left -= gvw->ghostview.buffer_bytes_left;
X`09`7D
X
X`09if (gvw->ghostview.buffer_bytes_left > 0) `7B
X`09    bytes_written = write(gvw->ghostview.interpreter_input,
X`09`09`09`09  gvw->ghostview.input_buffer_ptr,
X`09`09`09`09  gvw->ghostview.buffer_bytes_left);
X
X`09    if (broken_pipe) `7B
X`09`09broken_pipe = False;
X`09`09InterpreterFailed(w);`09`09/* Something bad happened */
X`09    `7D else if (bytes_written == -1) `7B
X`09`09if ((errno != EWOULDBLOCK) && (errno != EAGAIN)) `7B
X`09`09    InterpreterFailed(w);`09/* Something bad happened */
X`09`09`7D
X`09    `7D else `7B
X`09`09gvw->ghostview.buffer_bytes_left -= bytes_written;
X`09`09gvw->ghostview.input_buffer_ptr += bytes_written;
X`09    `7D
X`09`7D
X#ifdef NON_BLOCKING_IO
X    `7D while(gvw->ghostview.ps_input &&
X`09    gvw->ghostview.buffer_bytes_left == 0);
X#endif
X    signal(SIGPIPE, oldsig);
X    if (gvw->ghostview.ps_input == NULL &&
X`09gvw->ghostview.buffer_bytes_left == 0) `7B
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    `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(client_data, source, id)
X    XtPointer client_data;
X    int *source;
X    XtInputId *id;
X`7B
X    Widget w = (Widget) client_data;
X    GhostviewWidget gvw = (GhostviewWidget) w;
X    char buf`5BGV_BUFSIZ+1`5D;
X    int bytes = 0;
X
X    if (*source == gvw->ghostview.interpreter_output) `7B
X`09bytes = read(gvw->ghostview.interpreter_output, buf, GV_BUFSIZ);
X`09if (bytes == 0) `7B /* EOF occurred */
X`09    close(gvw->ghostview.interpreter_output);
X`09    gvw->ghostview.interpreter_output = -1;
X`09    XtRemoveInput(gvw->ghostview.interpreter_output_id);
X`09    return;
X`09`7D else if (bytes == -1) `7B
X`09    InterpreterFailed(w);`09`09/* Something bad happened */
X`09    return;
X`09`7D
X    `7D else if (*source == gvw->ghostview.interpreter_error) `7B
X`09bytes = read(gvw->ghostview.interpreter_error, buf, GV_BUFSIZ);
X`09if (bytes == 0) `7B /* EOF occurred */
X`09    close(gvw->ghostview.interpreter_error);
X`09    gvw->ghostview.interpreter_error = -1;
X`09    XtRemoveInput(gvw->ghostview.interpreter_error_id);
X`09    return;
X`09`7D else if (bytes == -1) `7B
X`09    InterpreterFailed(w);`09`09/* Something bad happened */
X`09    return;
X`09`7D
X    `7D
X    if (bytes > 0) `7B
X`09buf`5Bbytes`5D = '\0';
X`09XtCallCallbackList(w, gvw->ghostview.output_callback, (XtPointer) buf);
X    `7D
X`7D
X
X#endif /* VMS */
X
X/* Register the type converter required for the PageOrientation. */
X/* This routine is called exactly once. */
Xstatic void
XClassInitialize()
X`7B
X    XtSetTypeConverter(XtRString, XtRPageOrientation,
X`09`09       XmuCvtStringToPageOrientation, NULL, 0,
X`09`09       XtCacheAll, NULL);
X`7D
X
X/* Get atoms needed to communicate with ghostscript. */
X/* This routine is called once per display. */
Xstatic void
XClassPartInitialize(class)
X    WidgetClass class;
X`7B
X    GhostviewWidgetClass gvc = (GhostviewWidgetClass)class;
X    gvc->ghostview_class.ghostview = XmuMakeAtom("GHOSTVIEW");
X    gvc->ghostview_class.next = XmuMakeAtom("NEXT");
X    gvc->ghostview_class.page = XmuMakeAtom("PAGE");
X    gvc->ghostview_class.done = XmuMakeAtom("DONE");
X`7D
X
X/* Initialize private state. */
X
Xstatic void
XInitialize(request, new, args, num_args)
X    Widget request, new;
X    ArgList args;`09`09/* unused */
X    Cardinal *num_args;`09/* unused */
X`7B
X    XGCValues`09values;
X    XtGCMask`09mask;
X    GhostviewWidget ngvw = (GhostviewWidget) new;
X    GhostviewWidget rgvw = (GhostviewWidget) request;
X
X    values.foreground = new->core.background_pixel;
X    mask = GCForeground;
X    ngvw->ghostview.gc = XtGetGC(new, mask, &values);
X    ngvw->ghostview.mwin = None;
X    ngvw->ghostview.disable_start = False;
X    ngvw->ghostview.interpreter_pid = -1;
X    ngvw->ghostview.input_buffer = NULL;
X    ngvw->ghostview.bytes_left = 0;
X#ifndef VMS
X    ngvw->ghostview.input_buffer_ptr = NULL;
X    ngvw->ghostview.buffer_bytes_left = 0;
X#endif
X    ngvw->ghostview.ps_input = NULL;
X    ngvw->ghostview.interpreter_input = -1;
X    ngvw->ghostview.interpreter_output = -1;
X#ifndef VMS
X    ngvw->ghostview.interpreter_error = -1;
X    ngvw->ghostview.interpreter_input_id = None;
X    ngvw->ghostview.interpreter_output_id = None;
X    ngvw->ghostview.interpreter_error_id = None;
X#else /* VMS */
X    memset(ngvw->ghostview.interpreter_input_iosb, 0, 8);
X    memset(ngvw->ghostview.interpreter_output_iosb, 0, 8);
X    ngvw->ghostview.output_buffer = NULL;
X#endif /* VMS */
X    ngvw->ghostview.gs_width = 0;
X    ngvw->ghostview.gs_height = 0;
X    ngvw->ghostview.changed = False;
X    ngvw->ghostview.busy = False;
X
X    /* Compute window size */
X    Layout(new, (rgvw->core.width == 0), (rgvw->core.height == 0));
X`7D
X
X/* Create Window and start interpreter if needed */
Xstatic void
XRealize(w, valueMask, attributes)
X    Widget w;
X    Mask *valueMask;
X    XSetWindowAttributes *attributes;
X`7B
X    GhostviewWidget gvw = (GhostviewWidget) w;
X
X    if (gvw->ghostview.cursor != None) `7B
X`09attributes->cursor = gvw->ghostview.cursor;
X`09*valueMask `7C= CWCursor;
X    `7D
X
X    XtCreateWindow(w, (unsigned int) InputOutput, (Visual *) CopyFromParent,
X`09`09   *valueMask, attributes);
X
X    Setup(w);
X`7D
X
X/* Destroy routine: kill the interpreter and release the GC */
Xstatic void
XDestroy(w)
X    Widget w;
X`7B
X    GhostviewWidget gvw = (GhostviewWidget) w;
X
X    StopInterpreter(w);
X    XtReleaseGC(w, gvw->ghostview.gc);
X    if (gvw->ghostview.input_buffer) XtFree(gvw->ghostview.input_buffer);
X#ifdef VMS
X    if (gvw->ghostview.output_buffer) XtFree(gvw->ghostview.output_buffer);
X#endif VMS
X    if (gvw->core.background_pixmap != XtUnspecifiedPixmap)
X`09XFreePixmap(XtDisplay(w), gvw->core.background_pixmap);
X`7D
X
X/* Process resize request.  Requested size cannot be changed.
X * NOTE: This routine may be called before the widget is realized.
X * (It was a surprise to me.)
X * If the widget is realized, start a new interpreter by calling Setup().
X * If Setup() actually started a new interpreter and it is taking input
X * from stdin, send a refresh message to the application.  This is the
X * only way that the application can be notified that it needs to resend
X * the input because someone forced a new window size on the widget.
X */
Xstatic void
XResize(w)
X    Widget w;
X`7B
X    Layout(w, False, False);
X    if (!XtIsRealized(w)) return;
X    if (Setup(w)) `7B
X`09GhostviewWidget gvw = (GhostviewWidget) w;
X`09if (gvw->ghostview.filename == NULL) `7B
X`09    XtCallCallbackList(w, gvw->ghostview.message_callback, "Refresh");
X`09`7D
X    `7D
X`7D
X
X/* SetValues routine.  Set new private state, based on changed values
X * in the widget.  Always returns False, because redisplay is never needed.
X */
Xstatic Boolean
XSetValues(current, request, new)
X    Widget current, request, new;
X`7B
X    GhostviewWidget cgvw = (GhostviewWidget) current;
X    GhostviewWidget rgvw = (GhostviewWidget) request;
X    GhostviewWidget ngvw = (GhostviewWidget) new;
X    String cfilename;
X    String rfilename;
X    String cpreload;
X    String rpreload;
X
X    cfilename = cgvw->ghostview.filename;
X    if (cfilename == NULL) cfilename = "(null)";
X    rfilename = rgvw->ghostview.filename;
X    if (rfilename == NULL) rfilename = "(null)";
X    cpreload = cgvw->ghostview.preload;
X    if (cpreload == NULL) cpreload = "(null)";
X    rpreload = rgvw->ghostview.preload;
X    if (rpreload == NULL) rpreload = "(null)";
X
X    if (XtIsRealized(new) && !ngvw->ghostview.busy &&
X`09(cgvw->ghostview.cursor != ngvw->ghostview.cursor)) `7B
X`09XDefineCursor(XtDisplay(new), XtWindow(new), ngvw->ghostview.cursor);
X    `7D
X    if (XtIsRealized(new) && ngvw->ghostview.busy &&
X`09(cgvw->ghostview.busy_cursor != ngvw->ghostview.busy_cursor)) `7B
X`09XDefineCursor(XtDisplay(new), XtWindow(new),
X`09`09      ngvw->ghostview.busy_cursor);
X    `7D
X    if ((cgvw->core.width != rgvw->core.width) `7C`7C
X`09(cgvw->core.height != rgvw->core.height) `7C`7C
X`09strcmp(cgvw->ghostview.interpreter, rgvw->ghostview.interpreter) `7C`7C
X`09strcmp(cpreload, rpreload) `7C`7C
X`09(cgvw->ghostview.quiet != rgvw->ghostview.quiet) `7C`7C
X`09strcmp(cfilename, rfilename) `7C`7C
X`09(cgvw->ghostview.orientation != rgvw->ghostview.orientation) `7C`7C
X`09(cgvw->ghostview.use_bpixmap != rgvw->ghostview.use_bpixmap) `7C`7C
X`09(cgvw->ghostview.xdpi != rgvw->ghostview.xdpi) `7C`7C
X`09(cgvw->ghostview.ydpi != rgvw->ghostview.ydpi) `7C`7C
X`09(cgvw->ghostview.bottom_margin != rgvw->ghostview.bottom_margin) `7C`7C
X`09(cgvw->ghostview.left_margin != rgvw->ghostview.left_margin) `7C`7C
X`09(cgvw->ghostview.right_margin != rgvw->ghostview.right_margin) `7C`7C
X`09(cgvw->ghostview.top_margin != rgvw->ghostview.top_margin) `7C`7C
X`09(cgvw->ghostview.llx != rgvw->ghostview.llx) `7C`7C
X`09(cgvw->ghostview.lly != rgvw->ghostview.lly) `7C`7C
X`09(cgvw->ghostview.urx != rgvw->ghostview.urx) `7C`7C
X`09(cgvw->ghostview.ury != rgvw->ghostview.ury)) `7B
X
X`09ngvw->ghostview.changed = True;
X`09Layout(new, True, True);
X    `7D
X
X    if (ngvw->ghostview.changed && XtIsRealized(current)) Setup(new);
X    return(False);
X`7D
X
X/*`09Function Name: QueryGeometry
X *`09Description: This tells the parent what size we would like to be
X *                   given certain constraints.
X *`09Arguments: w - the widget.
X *                 intended - what the parent intends to do with us.
X *                 requested - what we want to happen.
X */
X
Xstatic XtGeometryResult`20
XQueryGeometry(w, intended, requested)
XWidget w;
XXtWidgetGeometry *intended, *requested;
X`7B
X    Dimension new_width, new_height;
X    Boolean change, width_req, height_req;
X   `20
X    width_req = intended->request_mode & CWWidth;
X    height_req = intended->request_mode & CWHeight;
X
X    if (width_req)
X      new_width = intended->width;
X    else
X      new_width = w->core.width;
X
X    if (height_req)
X      new_height = intended->height;
X    else
X      new_height = w->core.height;
X
X    requested->request_mode = 0;
X   `20
X/*
X * We only care about our height and width.
X */
X
X    if (!width_req && !height_req)
X      return(XtGeometryYes);
X   `20
X    change = ComputeSize(w, !width_req, !height_req, &new_width, &new_height
V);
X
X    requested->request_mode `7C= CWWidth;
X    requested->width = new_width;
X    requested->request_mode `7C= CWHeight;
X    requested->height = new_height;
X
X    if (change)
X        return(XtGeometryAlmost);
X    return(XtGeometryYes);
X`7D
X
X/* Layout the widget. */
X
Xstatic void
XLayout(w, xfree, yfree)
X    Widget w;
X    Boolean xfree, yfree;
X`7B
X    Dimension width = w->core.width;
X    Dimension height = w->core.height;
X    Boolean different_size = ComputeSize(w, xfree, yfree, &width, &height);
X    if (different_size) ChangeSize(w, width, height);
X`7D
X
X/* Compute new size of window, sets xdpi and ydpi if necessary.
X * returns True if new window size is different */
Xstatic Boolean
XComputeSize(w, xfree, yfree, width, height)
X    Widget w;
X    Boolean xfree, yfree;`09/* Am I allowed to change width or height */
X    Dimension *width, *height;
X`7B
X    GhostviewWidget gvw = (GhostviewWidget) w;
X    Dimension new_width = *width;
X    Dimension new_height = *height;
X    float newxdpi, newydpi;
X    Boolean change;
X
X    if (xfree && yfree) `7B
X`09/* width and height can be changed, calculate window size according */
X`09/* to xpdi and ydpi */
X`09switch (gvw->ghostview.orientation) `7B
X`09case XtPageOrientationPortrait:
X`09case XtPageOrientationUpsideDown:
X`09    new_width = (gvw->ghostview.urx - gvw->ghostview.llx) / 72.0 *
X`09`09`09 gvw->ghostview.xdpi + 0.5;
X`09    new_height = (gvw->ghostview.ury - gvw->ghostview.lly) / 72.0 *
X`09`09`09  gvw->ghostview.ydpi + 0.5;
X`09    break;
X`09case XtPageOrientationLandscape:
X`09case XtPageOrientationSeascape:
X`09    new_width = (gvw->ghostview.ury - gvw->ghostview.lly) / 72.0 *
X`09`09`09 gvw->ghostview.xdpi + 0.5;
X`09    new_height = (gvw->ghostview.urx - gvw->ghostview.llx) / 72.0 *
X`09`09`09  gvw->ghostview.ydpi + 0.5;
X`09    break;
X`09`7D
X    `7D else if (xfree) `7B
X`09/* height is fixed.  Preserve aspect ratio by recomputing */
X`09/* ydpi and xdpi */
X`09switch (gvw->ghostview.orientation) `7B
X`09case XtPageOrientationPortrait:
X`09case XtPageOrientationUpsideDown:
X`09    newydpi = gvw->core.height * 72.0 /
X`09`09      (gvw->ghostview.ury - gvw->ghostview.lly);
X`09    newxdpi = newydpi * gvw->ghostview.xdpi / gvw->ghostview.ydpi;
X`09    gvw->ghostview.xdpi = newxdpi;
X`09    gvw->ghostview.ydpi = newydpi;
X`09    new_width = (gvw->ghostview.urx - gvw->ghostview.llx) / 72.0 *
X`09`09`09 gvw->ghostview.xdpi + 0.5;
X`09    break;
X`09case XtPageOrientationLandscape:
X`09case XtPageOrientationSeascape:
X`09    newydpi = gvw->core.height * 72.0 /
X`09`09      (gvw->ghostview.urx - gvw->ghostview.llx);
X`09    newxdpi = newydpi * gvw->ghostview.xdpi / gvw->ghostview.ydpi;
X`09    gvw->ghostview.xdpi = newxdpi;
X`09    gvw->ghostview.ydpi = newydpi;
X`09    new_width = (gvw->ghostview.ury - gvw->ghostview.lly) / 72.0 *
X`09`09`09 gvw->ghostview.xdpi + 0.5;
X`09    break;
X`09`7D
X    `7D else if (yfree) `7B
X`09/* width is fixed.  Preserve aspect ratio by recomputing */
X`09/* xdpi and ydpi */
X`09switch (gvw->ghostview.orientation) `7B
X`09case XtPageOrientationPortrait:
X`09case XtPageOrientationUpsideDown:
X`09    newxdpi = gvw->core.width * 72.0 /
X`09`09      (gvw->ghostview.urx - gvw->ghostview.llx);
X`09    newydpi = newxdpi * gvw->ghostview.ydpi / gvw->ghostview.xdpi;
X`09    gvw->ghostview.xdpi = newxdpi;
X`09    gvw->ghostview.ydpi = newydpi;
X`09    new_height = (gvw->ghostview.ury - gvw->ghostview.lly) / 72.0 *
X`09`09`09  gvw->ghostview.ydpi + 0.5;
X`09    break;
X`09case XtPageOrientationLandscape:
X`09case XtPageOrientationSeascape:
X`09    newxdpi = gvw->core.width * 72.0 /
X`09`09      (gvw->ghostview.ury - gvw->ghostview.lly);
X`09    newydpi = newxdpi * gvw->ghostview.ydpi / gvw->ghostview.xdpi;
X`09    gvw->ghostview.xdpi = newxdpi;
X`09    gvw->ghostview.ydpi = newydpi;
X`09    new_height = (gvw->ghostview.urx - gvw->ghostview.llx) / 72.0 *
X`09`09`09  gvw->ghostview.ydpi + 0.5;
X`09    break;
X`09`7D
X    `7D else `7B
X`09/* height and width are fixed.  Just have to live with it. */
X`09switch (gvw->ghostview.orientation) `7B
X`09case XtPageOrientationPortrait:
X`09case XtPageOrientationUpsideDown:
X`09    gvw->ghostview.xdpi = gvw->core.width * 72.0 /
X`09`09`09`09  (gvw->ghostview.urx - gvw->ghostview.llx);
X`09    gvw->ghostview.ydpi = gvw->core.height * 72.0 /
X`09`09`09`09  (gvw->ghostview.ury - gvw->ghostview.lly);
X`09    break;
X`09case XtPageOrientationLandscape:
X`09case XtPageOrientationSeascape:
X`09    gvw->ghostview.xdpi = gvw->core.width * 72.0 /
X`09`09`09`09  (gvw->ghostview.ury - gvw->ghostview.lly);
X`09    gvw->ghostview.ydpi = gvw->core.height * 72.0 /
X`09`09`09`09  (gvw->ghostview.urx - gvw->ghostview.llx);
X`09    break;
X`09`7D
X    `7D
X
X    change = (new_width != *width) `7C`7C (new_height != *height);
X    *width = new_width;
X    *height = new_height;
X    return (change);
X`7D
X
X/*`09Function Name: ChangeSize.
X *`09Description: Request a size change.
X *`09Arguments: w - the widget to try change the size of.
X */
X
Xstatic void
XChangeSize(w, width, height)
XWidget w;
XDimension width, height;
X`7B
X    XtWidgetGeometry request, reply;
X    Boolean changed = False;
X
X    request.request_mode = CWWidth `7C CWHeight;
X    request.width = width;
X    request.height = height;
X   `20
X    switch ( XtMakeGeometryRequest(w, &request, &reply) ) `7B
X    case XtGeometryYes:
X`09changed = True;
X        break;
X    case XtGeometryNo:
X        break;
X    case XtGeometryAlmost:
X`09ComputeSize(w, (request.height != reply.height),
X`09`09       (request.width != reply.width),
X`09`09       &(reply.width), &(reply.height));
X`09request = reply;
X`09switch (XtMakeGeometryRequest(w, &request, &reply) ) `7B
X`09case XtGeometryYes:
X`09    changed = True;
X`09    break;
X`09case XtGeometryNo:
X`09    break;
X`09case XtGeometryAlmost:
X`09    request = reply;
X`09    ComputeSize(w, FALSE, FALSE, &(request.width), &(request.height));
X`09    request.request_mode = CWWidth `7C CWHeight;
X`09    XtMakeGeometryRequest(w, &request, &reply);
X`09    changed = True;
X`09    break;
X`09`7D
X`09break;
X    `7D
X
X    /* If success, setup the widet for the new size. */
X    if (changed && XtIsRealized(w)) Setup(w);
X`7D
X
X/* Catch the alloc error when there is not enough resources for the
X * backing pixmap.  Automatically shut off backing pixmap and let the
X * user know when this happens.
X */
Xstatic Boolean alloc_error;
Xstatic XErrorHandler oldhandler;
X
Xstatic int
Xcatch_alloc (dpy, err)
XDisplay *dpy;
XXErrorEvent *err;
X`7B
X    if (err->error_code == BadAlloc) `7B
X`09alloc_error = True;
X    `7D
X    if (alloc_error) return 0;
X    oldhandler(dpy, err);
X`7D
X
X/* Setup - sets up the backing pixmap, and GHOSTVIEW property and
X * starts interpreter if needed.
X * NOTE: the widget must be realized before calling Setup().
X * Returns True if a new interpreter was started, False otherwise.
X */
X`20
Xstatic Boolean
XSetup(w)
X    Widget w;
X`7B
X    GhostviewWidget gvw = (GhostviewWidget) w;
X    GhostviewWidgetClass gvc = (GhostviewWidgetClass) XtClass(w);
X    char buf`5BGV_BUFSIZ`5D;
X    Pixmap bpixmap;
X    XSetWindowAttributes xswa;
X
X    if (!gvw->ghostview.changed &&
X`09(gvw->core.width == gvw->ghostview.gs_width) &&
X`09(gvw->core.height == gvw->ghostview.gs_height)) return False;
+-+-+-+-+-+-+-+-  END  OF PART 3 +-+-+-+-+-+-+-+-
Technical Details
Message-ID: <8881759@MVB.SAIC.COM>
Path: arc1-ca.pugleaf.net!sparky!uunet!spool.mu.edu!uwm.edu!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!spool.mu.edu!uwm.edu!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 03/14
Message-ID: <8881759@MVB.SAIC.COM>
Date: Thu, 29 Oct 1992 18:49:19 GMT
Lines: 1365
Approved: Mark.Berryman@Mvb.Saic.Com