Article View: vmsnet.sources
Article #17Ghostview for VMS 03/14
From: Terry Poot
Date: Thu, 29 Oct 1992 18:49
Date: Thu, 29 Oct 1992 18:49
1365 lines
49205 bytes
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-sourcesShow 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