source: trunk/third/tex/xdvi/xdvi.c @ 12213

Revision 12213, 54.1 KB checked in by ghudson, 26 years ago (diff)
Merge local changes.
Line 
1/*
2 * Copyright (c) 1994 Paul Vojta.  All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 *
25 * NOTE:
26 *      xdvi is based on prior work as noted in the modification history, below.
27 */
28
29/*
30 * DVI previewer for X.
31 *
32 * Eric Cooper, CMU, September 1985.
33 *
34 * Code derived from dvi-imagen.c.
35 *
36 * Modification history:
37 * 1/1986       Modified for X.10       --Bob Scheifler, MIT LCS.
38 * 7/1988       Modified for X.11       --Mark Eichin, MIT
39 * 12/1988      Added 'R' option, toolkit, magnifying glass
40 *                                      --Paul Vojta, UC Berkeley.
41 * 2/1989       Added tpic support      --Jeffrey Lee, U of Toronto
42 * 4/1989       Modified for System V   --Donald Richardson, Clarkson Univ.
43 * 3/1990       Added VMS support       --Scott Allendorf, U of Iowa
44 * 7/1990       Added reflection mode   --Michael Pak, Hebrew U of Jerusalem
45 * 1/1992       Added greyscale code    --Till Brychcy, Techn. Univ. Muenchen
46 *                                        and Lee Hetherington, MIT
47 * 4/1994       Added DPS support, bounding box
48 *                                      --Ricardo Telichevesky
49 *                                        and Luis Miguel Silveira, MIT RLE.
50 *
51 *      Compilation options:
52 *      SYSV    compile for System V
53 *      VMS     compile for VMS
54 *      NOTOOL  compile without toolkit
55 *      BUTTONS compile with buttons on the side of the window (needs toolkit)
56 *      MSBITFIRST      store bitmaps internally with most significant bit first
57 *      BMSHORT store bitmaps in shorts instead of bytes
58 *      BMLONG  store bitmaps in longs instead of bytes
59 *      ALTFONT default for -altfont option
60 *      SHRINK  default for -s option (shrink factor)
61 *      MFMODE  default for -mfmode option
62 *      A4      use European size paper
63 *      TEXXET  support reflection dvi codes (right-to-left typesetting)
64 *      GREY    use grey levels to shrink fonts
65 *      PS_DPS  use display postscript to render pictures/bounding boxes
66 *      PS_NEWS use the NeWS server to render pictures/bounding boxes
67 *      PS_GS   use Ghostscript to render pictures/bounding boxes
68 *      GS_PATH path to call the Ghostscript interpreter by
69 */
70
71#ifndef lint
72static  char    copyright[] =
73"@(#) Copyright (c) 1994 Paul Vojta.  All rights reserved.\n";
74#endif
75
76#ifndef ALTFONT
77#define ALTFONT "cmr10"
78#endif
79
80#ifndef SHRINK
81#define SHRINK  6
82#endif
83
84#ifndef BDPI
85#define BDPI    300
86#endif
87
88#ifndef MFMODE
89#define MFMODE  NULL
90#endif
91
92#if     defined(PS_GS) && !defined(GS_PATH)
93#define GS_PATH "gs"
94#endif
95
96#ifndef A4
97#define DEFAULT_PAPER           "us"
98#else
99#define DEFAULT_PAPER           "a4"
100#endif
101
102#define EXTERN
103#define INIT(x) =x
104
105#include <math.h>       /* includes atof() */
106#include <ctype.h>
107#include "xdvi.h"
108
109#include "patchlevel.h"
110static  _Xconst struct {char    a[24], b, c, d;}
111        version = {"This is xdvi patchlevel ", '0' + PATCHLEVEL / 10,
112                '0' + PATCHLEVEL % 10, 0};
113
114#ifdef  X_NOT_STDC_ENV
115#ifndef atof
116extern  double  atof ARGS((_Xconst char *));
117#endif
118#endif
119
120/* Xlib and Xutil are already included */
121#include <X11/cursorfont.h>
122#include <X11/keysym.h>
123#include "xdvi.icon"
124
125#ifdef  TOOLKIT
126#ifdef  OLD_X11_TOOLKIT
127#include <X11/Atoms.h>
128#else /* not OLD_X11_TOOLKIT */
129#include <X11/Xatom.h>
130#include <X11/StringDefs.h>
131#endif /* not OLD_X11_TOOLKIT */
132#include <X11/Shell.h>  /* needed for def. of XtNiconX */
133#ifndef XtSpecificationRelease
134#define XtSpecificationRelease  0
135#endif
136#if     XtSpecificationRelease >= 4
137#include <X11/Xaw/Viewport.h>
138#ifdef  BUTTONS
139#include <X11/Xaw/Command.h>
140#endif
141#else   /* XtSpecificationRelease < 4 */
142#define XtPointer caddr_t
143#include <X11/Viewport.h>
144#ifdef  BUTTONS
145#include <X11/Command.h>
146#endif
147#endif  /* XtSpecificationRelease */
148#if     XtSpecificationRelease < 5
149typedef caddr_t XPointer;
150#endif
151#else   /* !TOOLKIT */
152typedef int             Position;
153#endif  /* TOOLKIT */
154
155#ifdef  VMS
156/*
157 * Magnifying glass cursor
158 *
159 * Developed by Tom Sawyer, April 1990
160 * Contibuted by Hunter Goatley, January 1991
161 *
162 */
163
164#define mag_glass_width 16
165#define mag_glass_height 16
166#define mag_glass_x_hot 6
167#define mag_glass_y_hot 6
168static char mag_glass_bits[] = {
169        0xf8, 0x03, 0x0c, 0x06, 0xe2, 0x09, 0x13, 0x1a, 0x01, 0x14, 0x01, 0x14,
170        0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x03, 0x10, 0x02, 0x18, 0x0c, 0x34,
171        0xf8, 0x6f, 0x00, 0xd8, 0x00, 0xb0, 0x00, 0xe0
172};
173#include <decw$cursor.h>        /* Include the DECWindows cursor symbols */
174static  int     DECWCursorFont; /* Space for the DECWindows cursor font  */
175static  Pixmap  MagnifyPixmap;  /* Pixmap to hold our special mag-glass  */
176#include <X11/Xresource.h>      /* Motif apparently needs this one */
177#endif  /* VMS */
178
179/*
180 * Command line flags.
181 */
182
183static  Dimension       bwidth  = 2;
184
185#define fore_Pixel      resource._fore_Pixel
186#define back_Pixel      resource._back_Pixel
187#ifdef  TOOLKIT
188struct _resource        resource;
189#define brdr_Pixel      resource._brdr_Pixel
190#define hl_Pixel        resource._hl_Pixel
191#define cr_Pixel        resource._cr_Pixel
192#else   /* TOOLKIT */
193static  Pixel           hl_Pixel, cr_Pixel;
194#endif  /* TOOLKIT */
195
196struct  mg_size_rec     mg_size[5]      = {{200, 150}, {400, 250}, {700, 500},
197                                           {1000, 800}, {1200, 1200}};
198
199static  char    *curr_page;
200
201struct WindowRec mane   ={(Window) 0, SHRINK, 0, 0, 0, 0, MAXDIM, 0, MAXDIM, 0};
202struct WindowRec alt    = {(Window) 0, 1, 0, 0, 0, 0, MAXDIM, 0, MAXDIM, 0};
203/*      currwin is temporary storage except for within redraw() */
204struct WindowRec currwin = {(Window) 0, 3, 0, 0, 0, 0, MAXDIM, 0, MAXDIM, 0};
205
206#ifdef  lint
207#ifdef  TOOLKIT
208WidgetClass     viewportWidgetClass, widgetClass;
209#ifdef  BUTTONS
210WidgetClass     formWidgetClass, compositeWidgetClass, commandWidgetClass;
211#endif  /* BUTTONS */
212#endif  /* TOOLKIT */
213#endif  /* lint */
214
215/*
216 *      Data for options processing
217 */
218
219static  _Xconst char    silent[] = " "; /* flag value for usage() */
220
221static  _Xconst char    subst[] = "x";  /* another flag value */
222
223static  _Xconst char    *subst_val[] = {
224#ifdef  BUTTONS
225                                        "-shrinkbutton[1-4] <shrink>",
226#endif
227                                        "-mgs[n] <size>"};
228
229#ifdef  TOOLKIT
230
231static  XrmOptionDescRec        options[] = {
232{"-s",          ".shrinkFactor", XrmoptionSepArg,       (caddr_t) NULL},
233#ifndef VMS
234{"-S",          ".densityPercent", XrmoptionSepArg,     (caddr_t) NULL},
235#endif
236{"-density",    ".densityPercent", XrmoptionSepArg,     (caddr_t) NULL},
237#ifdef  GREY
238{"-nogrey",     ".grey",        XrmoptionNoArg,         (caddr_t) "off"},
239{"+nogrey",     ".grey",        XrmoptionNoArg,         (caddr_t) "on"},
240{"-gamma",      ".gamma",       XrmoptionSepArg,        (caddr_t) NULL},
241#endif
242{"-p",          ".pixelsPerInch", XrmoptionSepArg,      (caddr_t) NULL},
243{"-margins",    ".Margin",      XrmoptionSepArg,        (caddr_t) NULL},
244{"-sidemargin", ".sideMargin",  XrmoptionSepArg,        (caddr_t) NULL},
245{"-topmargin",  ".topMargin",   XrmoptionSepArg,        (caddr_t) NULL},
246{"-offsets",    ".Offset",      XrmoptionSepArg,        (caddr_t) NULL},
247{"-xoffset",    ".xOffset",     XrmoptionSepArg,        (caddr_t) NULL},
248{"-yoffset",    ".yOffset",     XrmoptionSepArg,        (caddr_t) NULL},
249{"-paper",      ".paper",       XrmoptionSepArg,        (caddr_t) NULL},
250{"-altfont",    ".altFont",     XrmoptionSepArg,        (caddr_t) NULL},
251#ifdef  MAKEPK
252{"-nomakepk",   ".makePk",      XrmoptionNoArg,         (caddr_t) "off"},
253{"+nomakepk",   ".makePk",      XrmoptionNoArg,         (caddr_t) "on"},
254#endif
255{"-mfmode",     ".mfMode",      XrmoptionSepArg,        (caddr_t) NULL},
256{"-l",          ".listFonts",   XrmoptionNoArg,         (caddr_t) "on"},
257{"+l",          ".listFonts",   XrmoptionNoArg,         (caddr_t) "off"},
258#ifdef  BUTTONS
259{"-expert",     ".expert",      XrmoptionNoArg,         (caddr_t) "on"},
260{"+expert",     ".expert",      XrmoptionNoArg,         (caddr_t) "off"},
261{"-shrinkbutton1",".shrinkButton1",XrmoptionSepArg,     (caddr_t) NULL},
262{"-shrinkbutton2",".shrinkButton2",XrmoptionSepArg,     (caddr_t) NULL},
263{"-shrinkbutton3",".shrinkButton3",XrmoptionSepArg,     (caddr_t) NULL},
264{"-shrinkbutton4",".shrinkButton4",XrmoptionSepArg,     (caddr_t) NULL},
265#endif
266{"-mgs",        ".magnifierSize1",XrmoptionSepArg,      (caddr_t) NULL},
267{"-mgs1",       ".magnifierSize1",XrmoptionSepArg,      (caddr_t) NULL},
268{"-mgs2",       ".magnifierSize2",XrmoptionSepArg,      (caddr_t) NULL},
269{"-mgs3",       ".magnifierSize3",XrmoptionSepArg,      (caddr_t) NULL},
270{"-mgs4",       ".magnifierSize4",XrmoptionSepArg,      (caddr_t) NULL},
271{"-mgs5",       ".magnifierSize5",XrmoptionSepArg,      (caddr_t) NULL},
272{"-hush",       ".Hush",        XrmoptionNoArg,         (caddr_t) "on"},
273{"+hush",       ".Hush",        XrmoptionNoArg,         (caddr_t) "off"},
274{"-hushspecials", ".hushSpecials", XrmoptionNoArg,      (caddr_t) "on"},
275{"+hushspecials", ".hushSpecials", XrmoptionNoArg,      (caddr_t) "off"},
276{"-hushchars",  ".hushLostChars", XrmoptionNoArg,       (caddr_t) "on"},
277{"+hushchars",  ".hushLostChars", XrmoptionNoArg,       (caddr_t) "off"},
278{"-hushchecksums", ".hushChecksums", XrmoptionNoArg,    (caddr_t) "on"},
279{"+hushchecksums", ".hushChecksums", XrmoptionNoArg,    (caddr_t) "off"},
280{"-safer",      ".safer",       XrmoptionNoArg,         (caddr_t) "on"},
281{"+safer",      ".safer",       XrmoptionNoArg,         (caddr_t) "off"},
282{"-fg",         ".foreground",  XrmoptionSepArg,        (caddr_t) NULL},
283{"-foreground", ".foreground",  XrmoptionSepArg,        (caddr_t) NULL},
284{"-bg",         ".background",  XrmoptionSepArg,        (caddr_t) NULL},
285{"-background", ".background",  XrmoptionSepArg,        (caddr_t) NULL},
286{"-hl",         ".highlight",   XrmoptionSepArg,        (caddr_t) NULL},
287{"-cr",         ".cursorColor", XrmoptionSepArg,        (caddr_t) NULL},
288{"-icongeometry",".iconGeometry",XrmoptionSepArg,       (caddr_t) NULL},
289{"-keep",       ".keepPosition",XrmoptionNoArg,         (caddr_t) "on"},
290{"+keep",       ".keepPosition",XrmoptionNoArg,         (caddr_t) "off"},
291{"-copy",       ".copy",        XrmoptionNoArg,         (caddr_t) "on"},
292{"+copy",       ".copy",        XrmoptionNoArg,         (caddr_t) "off"},
293{"-thorough",   ".thorough",    XrmoptionNoArg,         (caddr_t) "on"},
294{"+thorough",   ".thorough",    XrmoptionNoArg,         (caddr_t) "off"},
295#if     PS
296{"-nopostscript",".postscript", XrmoptionNoArg,         (caddr_t) "off"},
297{"+nopostscript",".postscript", XrmoptionNoArg,         (caddr_t) "on"},
298{"-noscan",     ".prescan",     XrmoptionNoArg,         (caddr_t) "off"},
299{"+noscan",     ".prescan",     XrmoptionNoArg,         (caddr_t) "on"},
300{"-allowshell", ".allowShell",  XrmoptionNoArg,         (caddr_t) "on"},
301{"+allowshell", ".allowShell",  XrmoptionNoArg,         (caddr_t) "off"},
302#ifdef  PS_DPS
303{"-nodps",      ".dps",         XrmoptionNoArg,         (caddr_t) "off"},
304{"+nodps",      ".dps",         XrmoptionNoArg,         (caddr_t) "on"},
305#endif
306#ifdef  PS_NEWS
307{"-nonews",     ".news",        XrmoptionNoArg,         (caddr_t) "off"},
308{"+nonews",     ".news",        XrmoptionNoArg,         (caddr_t) "on"},
309#endif
310#ifdef  PS_GS
311{"-noghostscript",".ghostscript", XrmoptionNoArg,       (caddr_t) "off"},
312{"+noghostscript",".ghostscript", XrmoptionNoArg,       (caddr_t) "on"},
313{"-interpreter",".interpreter", XrmoptionSepArg,        (caddr_t) NULL},
314{"-nogssafer",  ".gsSafer",     XrmoptionNoArg,         (caddr_t) "off"},
315{"+nogssafer",  ".gsSafer",     XrmoptionNoArg,         (caddr_t) "on"},
316{"-gspalette",  ".palette",     XrmoptionSepArg,        (caddr_t) NULL},
317#endif
318#endif  /* PS */
319{"-debug",      ".debugLevel",  XrmoptionSepArg,        (caddr_t) NULL},
320{"-version",    ".version",     XrmoptionNoArg,         (caddr_t) "on"},
321{"+version",    ".version",     XrmoptionNoArg,         (caddr_t) "off"},
322};
323
324#define offset(field)   XtOffsetOf(struct _resource, field)
325
326static  char    XtRBool3[]      = "Bool3";      /* resource for Bool3 */
327
328static  XtResource      application_resources[] = {
329{"shrinkFactor", "ShrinkFactor", XtRInt, sizeof(int),
330  offset(shrinkfactor), XtRImmediate, (XtPointer) SHRINK},
331{"densityPercent", "DensityPercent", XtRInt, sizeof(int),
332  offset(_density), XtRString, "20"},
333#ifdef  GREY
334{"gamma", "Gamma", XtRFloat, sizeof(float),
335  offset(_gamma), XtRString, "1"},
336#endif
337{"pixelsPerInch", "PixelsPerInch", XtRInt, sizeof(int),
338  offset(_pixels_per_inch), XtRImmediate, (XtPointer) BDPI},
339{"sideMargin", "Margin", XtRString, sizeof(char *),
340  offset(sidemargin), XtRString, (caddr_t) NULL},
341{"topMargin", "Margin", XtRString, sizeof(char *),
342  offset(topmargin), XtRString, (caddr_t) NULL},
343{"xOffset", "Offset", XtRString, sizeof(char *),
344  offset(xoffset), XtRString, (caddr_t) NULL},
345{"yOffset", "Offset", XtRString, sizeof(char *),
346  offset(yoffset), XtRString, (caddr_t) NULL},
347{"paper", "Paper", XtRString, sizeof(char *),
348  offset(paper), XtRString, (caddr_t) DEFAULT_PAPER},
349{"altFont", "AltFont", XtRString, sizeof(char *),
350  offset(_alt_font), XtRString, (caddr_t) ALTFONT},
351#ifdef  MAKEPK
352{"makePk", "MakePk", XtRBoolean, sizeof(Boolean),
353  offset(makepk), XtRString, "true"},
354#endif
355{"mfMode", "MfMode", XtRString, sizeof(char *),
356  offset(mfmode), XtRString, MFMODE},
357{"listFonts", "ListFonts", XtRBoolean, sizeof(Boolean),
358  offset(_list_fonts), XtRString, "false"},
359{"reverseVideo", "ReverseVideo", XtRBoolean, sizeof(Boolean),
360  offset(reverse), XtRString, "false"},
361{"hushSpecials", "Hush", XtRBoolean, sizeof(Boolean),
362  offset(_hush_spec), XtRString, "false"},
363{"hushLostChars", "Hush", XtRBoolean, sizeof(Boolean),
364  offset(_hush_chars), XtRString, "false"},
365{"hushChecksums", "Hush", XtRBoolean, sizeof(Boolean),
366  offset(_hush_chk), XtRString, "false"},
367{"safer", "Safer", XtRBoolean, sizeof(Boolean),
368  offset(safer), XtRString, "false"},
369{"foreground", "Foreground", XtRPixel, sizeof(Pixel),
370  offset(_fore_Pixel), XtRPixel, (caddr_t) &resource._fore_Pixel},
371{"foreground", "Foreground", XtRString, sizeof(char *),
372  offset(fore_color), XtRString, (caddr_t) NULL},
373{"background", "Background", XtRPixel, sizeof(Pixel),
374  offset(_back_Pixel), XtRPixel, (caddr_t) &resource._back_Pixel},
375{"background", "Background", XtRString, sizeof(char *),
376  offset(back_color), XtRString, (caddr_t) NULL},
377{"borderColor", "BorderColor", XtRPixel, sizeof(Pixel),
378  offset(_brdr_Pixel), XtRPixel, (caddr_t) &resource._brdr_Pixel},
379{"borderColor", "BorderColor", XtRString, sizeof(char *),
380  offset(brdr_color), XtRString, (caddr_t) NULL},
381{"highlight", "Highlight", XtRPixel, sizeof(Pixel),
382  offset(_hl_Pixel), XtRPixel, (caddr_t) &resource._hl_Pixel},
383{"highlight", "Highlight", XtRString, sizeof(char *),
384  offset(high_color), XtRString, (caddr_t) NULL},
385{"cursorColor", "CursorColor", XtRPixel, sizeof(Pixel),
386  offset(_cr_Pixel), XtRPixel, (caddr_t) &resource._cr_Pixel},
387{"cursorColor", "CursorColor", XtRString, sizeof(char *),
388  offset(curs_color), XtRString, (caddr_t) NULL},
389{"iconGeometry", "IconGeometry", XtRString, sizeof(char *),
390  offset(icon_geometry), XtRString, (caddr_t) NULL},
391{"keepPosition", "KeepPosition", XtRBoolean, sizeof(Boolean),
392  offset(keep_flag), XtRString, "false"},
393#if     PS
394{"postscript", "Postscript", XtRBoolean, sizeof(Boolean),
395  offset(_postscript), XtRString, "true"},
396{"prescan", "Prescan", XtRBoolean, sizeof(Boolean),
397  offset(prescan), XtRString, "true"},
398{"allowShell", "AllowShell", XtRBoolean, sizeof(Boolean),
399  offset(allow_shell), XtRString, "false"},
400#ifdef  PS_DPS
401{"dps", "DPS", XtRBoolean, sizeof(Boolean),
402  offset(useDPS), XtRString, "true"},
403#endif
404#ifdef  PS_NEWS
405{"news", "News", XtRBoolean, sizeof(Boolean),
406  offset(useNeWS), XtRString, "true"},
407#endif
408#ifdef  PS_GS
409{"ghostscript", "Ghostscript", XtRBoolean, sizeof(Boolean),
410  offset(useGS), XtRString, "true"},
411{"interpreter", "Interpreter", XtRString, sizeof(char *),
412  offset(gs_path), XtRString, (caddr_t) GS_PATH},
413{"gsSafer", "Safer", XtRBoolean, sizeof(Boolean),
414  offset(gs_safer), XtRString, "true"},
415{"palette", "Palette", XtRString, sizeof(char *),
416  offset(gs_palette), XtRString, (caddr_t) "Color"},
417#endif
418#endif  /* PS */
419{"copy", "Copy", XtRBool3, sizeof(Bool3),
420  offset(copy), XtRString, "maybe"},
421{"thorough", "Thorough", XtRBoolean, sizeof(Boolean),
422  offset(thorough), XtRString, "false"},
423{"debugLevel", "DebugLevel", XtRString, sizeof(char *),
424  offset(debug_arg), XtRString, (caddr_t) NULL},
425{"version", "Version", XtRBoolean, sizeof(Boolean),
426  offset(version_flag), XtRString, "false"},
427#ifdef  BUTTONS
428{"expert", "Expert", XtRBoolean, sizeof(Boolean),
429  offset(expert), XtRString, "false"},
430{"shrinkButton1", "ShrinkButton1", XtRInt, sizeof(int),
431  offset(shrinkbutton[0]), XtRImmediate, (XtPointer) 1},
432{"shrinkButton2", "ShrinkButton2", XtRInt, sizeof(int),
433  offset(shrinkbutton[1]), XtRImmediate, (XtPointer) 2},
434{"shrinkButton3", "ShrinkButton3", XtRInt, sizeof(int),
435  offset(shrinkbutton[2]), XtRImmediate, (XtPointer) 3},
436{"shrinkButton4", "ShrinkButton4", XtRInt, sizeof(int),
437  offset(shrinkbutton[3]), XtRImmediate, (XtPointer) 4},
438#endif
439{"magnifierSize1", "MagnifierSize", XtRString, sizeof(char *),
440  offset(mg_arg[0]), XtRString, (caddr_t) NULL},
441{"magnifierSize2", "MagnifierSize", XtRString, sizeof(char *),
442  offset(mg_arg[1]), XtRString, (caddr_t) NULL},
443{"magnifierSize3", "MagnifierSize", XtRString, sizeof(char *),
444  offset(mg_arg[2]), XtRString, (caddr_t) NULL},
445{"magnifierSize4", "MagnifierSize", XtRString, sizeof(char *),
446  offset(mg_arg[3]), XtRString, (caddr_t) NULL},
447{"magnifierSize5", "MagnifierSize", XtRString, sizeof(char *),
448  offset(mg_arg[4]), XtRString, (caddr_t) NULL},
449#ifdef  GREY
450{"grey", "Grey", XtRBoolean, sizeof(Boolean),
451  offset(_use_grey), XtRString, "true"},
452#endif
453};
454#undef  offset
455
456static  _Xconst char    *usagestr[] = {
457        /* shrinkFactor */      "shrink",
458#ifndef VMS
459        /* S */                 "density",
460        /* density */           silent,
461#else
462        /* density */           "density",
463#endif
464#ifdef  GREY
465        /* gamma */             "g",
466#endif
467        /* p */                 "pixels",
468        /* margins */           "dimen",
469        /* sidemargin */        "dimen",
470        /* topmargin */         "dimen",
471        /* offsets */           "dimen",
472        /* xoffset */           "dimen",
473        /* yoffset */           "dimen",
474        /* paper */             "papertype",
475        /* altfont */           "font",
476        /* mfmode */            "mode-def",
477        /* rv */                "^-l", "-rv",
478#ifdef  BUTTONS
479        /* shrinkbutton1 */     subst,
480        /* shrinkbutton2 */     silent,
481        /* shrinkbutton3 */     silent,
482        /* shrinkbutton4 */     silent,
483#endif
484        /* mgs */               subst,
485        /* mgs1 */              silent,
486        /* mgs2 */              silent,
487        /* mgs3 */              silent,
488        /* mgs4 */              silent,
489        /* mgs5 */              silent,
490        /* bw */                "^-safer", "-bw <width>",
491        /* fg */                "color",
492        /* foreground */        silent,
493        /* bg */                "color",
494        /* background */        silent,
495        /* hl */                "color",
496        /* bd */                "^-hl", "-bd <color>",
497        /* cr */                "color",
498#ifndef VMS
499        /* display */           "^-cr", "-display <host:display>",
500#else
501        /* display */           "^-cr", "-display <host::display>",
502#endif
503        /* geometry */          "^-cr", "-geometry <geometry>",
504        /* icongeometry */      "geometry",
505        /* iconic */            "^-icongeometry", "-iconic",
506#ifdef  BUTTONS
507        /* font */              "^-icongeometry", "-font <font>",
508#endif
509#ifdef  PS_GS
510        /* interpreter */       "path",
511        /* gspalette */         "monochrome|grayscale|color",
512#endif
513        /* debug */             "bitmask",
514        /* [dummy] */           "z"
515};
516
517#ifdef  NOQUERY
518#define drawWidgetClass widgetClass
519#else
520
521/* ARGSUSED */
522static  XtGeometryResult
523QueryGeometry(w, constraints, reply)
524        Widget  w;
525        XtWidgetGeometry *constraints, *reply;
526{
527        reply->request_mode = CWWidth | CWHeight;
528        reply->width = page_w;
529        reply->height = page_h;
530        return XtGeometryAlmost;
531}
532
533#include <X11/IntrinsicP.h>
534#include <X11/CoreP.h>
535
536#ifdef  lint
537WidgetClassRec  widgetClassRec;
538#endif
539
540        /* if the following gives you trouble, just compile with -DNOQUERY */
541static  WidgetClassRec  drawingWidgetClass = {
542  {
543    /* superclass         */    &widgetClassRec,
544    /* class_name         */    "Draw",
545    /* widget_size        */    sizeof(WidgetRec),
546    /* class_initialize   */    NULL,
547    /* class_part_initialize*/  NULL,
548    /* class_inited       */    FALSE,
549    /* initialize         */    NULL,
550    /* initialize_hook    */    NULL,
551    /* realize            */    XtInheritRealize,
552    /* actions            */    NULL,
553    /* num_actions        */    0,
554    /* resources          */    NULL,
555    /* num_resources      */    0,
556    /* xrm_class          */    NULLQUARK,
557    /* compress_motion    */    FALSE,
558    /* compress_exposure  */    TRUE,
559    /* compress_enterleave*/    FALSE,
560    /* visible_interest   */    FALSE,
561    /* destroy            */    NULL,
562    /* resize             */    XtInheritResize,
563    /* expose             */    XtInheritExpose,
564    /* set_values         */    NULL,
565    /* set_values_hook    */    NULL,
566    /* set_values_almost  */    XtInheritSetValuesAlmost,
567    /* get_values_hook    */    NULL,
568    /* accept_focus       */    XtInheritAcceptFocus,
569    /* version            */    XtVersion,
570    /* callback_offsets   */    NULL,
571    /* tm_table           */    XtInheritTranslations,
572    /* query_geometry       */  QueryGeometry,
573    /* display_accelerator  */  XtInheritDisplayAccelerator,
574    /* extension            */  NULL
575  }
576};
577
578#define drawWidgetClass &drawingWidgetClass
579
580#endif  /* NOQUERY */
581
582static  Arg     vport_args[] = {
583#ifdef  BUTTONS
584        {XtNborderWidth, (XtArgVal) 0},
585        {XtNtop,        (XtArgVal) XtChainTop},
586        {XtNbottom,     (XtArgVal) XtChainBottom},
587        {XtNleft,       (XtArgVal) XtChainLeft},
588        {XtNright,      (XtArgVal) XtChainRight},
589#endif
590        {XtNallowHoriz, (XtArgVal) True},
591        {XtNallowVert,  (XtArgVal) True},
592};
593
594static  Arg     draw_args[] = {
595        {XtNwidth,      (XtArgVal) 0},
596        {XtNheight,     (XtArgVal) 0},
597#ifdef  GREY
598        {XtNbackground, (XtArgVal) 0},
599#endif
600        {XtNx,          (XtArgVal) 0},
601        {XtNy,          (XtArgVal) 0},
602        {XtNlabel,      (XtArgVal) ""},
603};
604
605#ifdef  BUTTONS
606static  Arg     form_args[] = {
607        {XtNdefaultDistance, (XtArgVal) 0},
608};
609#endif
610
611#else   /* !TOOLKIT */
612
613static  char    *display;
614static  char    *geometry;
615static  char    *margins;
616static  char    *offsets;
617static  Boolean hush;
618static  Boolean iconic  = False;
619
620#define ADDR(x) (caddr_t) &resource.x
621
622static  struct option {
623        _Xconst char    *name;
624        _Xconst char    *resource;
625        enum {FalseArg, TrueArg, StickyArg, SepArg}
626                        argclass;
627        enum {BooleanArg, Bool3Arg, StringArg, NumberArg, FloatArg}
628                        argtype;
629        int             classcount;
630        _Xconst char    *usagestr;
631        caddr_t         address;
632}       options[] = {
633{"+",           NULL,           StickyArg, StringArg, 1,
634  NULL,         (caddr_t) &curr_page},
635{"-s",          "shrinkFactor", SepArg, NumberArg, 1,
636  "shrink",     (caddr_t)&shrink_factor},
637#ifndef VMS
638{"-S",          NULL,           SepArg, NumberArg, 2,
639  "density",    ADDR(_density)},
640{"-density",    "densityPercent", SepArg, NumberArg, 1,
641  silent,       ADDR(_density)},
642#else
643{"-density",    "densityPercent", SepArg, NumberArg, 1,
644  "density",    ADDR(_density)},
645#endif
646#ifdef  GREY
647{"-nogrey",     NULL,           FalseArg, BooleanArg, 2,
648  NULL,         ADDR(_use_grey)},
649{"+nogrey",     "grey",         TrueArg, BooleanArg, 1,
650  NULL,         ADDR(_use_grey)},
651{"-gamma",      "gamma",        SepArg, FloatArg, 1,
652  "g",          ADDR(_gamma)},
653#endif
654{"-p",          "pixelsPerInch", SepArg, NumberArg, 1,
655  "pixels",     ADDR(_pixels_per_inch)},
656{"-margins",    "Margin",       SepArg, StringArg, 3,
657  "dimen",      (caddr_t) &margins},
658{"-sidemargin", "sideMargin",   SepArg, StringArg, 1,
659  "dimen",      ADDR(sidemargin)},
660{"-topmargin",  "topMargin",    SepArg, StringArg, 1,
661  "dimen",      ADDR(topmargin)},
662{"-offsets",    "Offset",       SepArg, StringArg, 3,
663  "dimen",      (caddr_t) &offsets},
664{"-xoffset",    "xOffset",      SepArg, StringArg, 1,
665  "dimen",      ADDR(xoffset)},
666{"-yoffset",    "yOffset",      SepArg, StringArg, 1,
667  "dimen",      ADDR(yoffset)},
668{"-paper",      "paper",        SepArg, StringArg, 1,
669  "papertype",  ADDR(paper)},
670{"-altfont",    "altFont",      SepArg, StringArg, 1,
671  "font",       ADDR(_alt_font)},
672#ifdef  MAKEPK
673{"-nomakepk",   "makePk",       FalseArg, BooleanArg, 2,
674  NULL,         ADDR(makepk)},
675{"+nomakepk",   "makePk",       TrueArg, BooleanArg, 1,
676  NULL,         ADDR(makepk)},
677#endif
678{"-mfmode",     "mfMode",       SepArg, StringArg, 1,
679  "mode-def",   ADDR(mfmode)},
680{"-l",          NULL,           TrueArg, BooleanArg, 2,
681  NULL,         ADDR(_list_fonts)},
682{"+l",          "listFonts",    FalseArg, BooleanArg, 1,
683  NULL,         ADDR(_list_fonts)},
684{"-rv",         NULL,           TrueArg, BooleanArg, 2,
685  NULL,         ADDR(reverse)},
686{"+rv",         "reverseVideo", FalseArg, BooleanArg, 1,
687  NULL,         ADDR(reverse)},
688{"-mgs",        NULL,           SepArg, StringArg, 2,
689  subst,        ADDR(mg_arg[0])},
690{"-mgs1",       "magnifierSize1",SepArg, StringArg, 1,
691  silent,       ADDR(mg_arg[0])},
692{"-mgs2",       "magnifierSize2",SepArg, StringArg, 1,
693  silent,       ADDR(mg_arg[1])},
694{"-mgs3",       "magnifierSize3",SepArg, StringArg, 1,
695  silent,       ADDR(mg_arg[2])},
696{"-mgs4",       "magnifierSize4",SepArg, StringArg, 1,
697  silent,       ADDR(mg_arg[3])},
698{"-mgs5",       "magnifierSize5",SepArg, StringArg, 1,
699  silent,       ADDR(mg_arg[4])},
700{"-hush",       NULL,           TrueArg, BooleanArg, 6,
701  NULL,         (caddr_t) &hush},
702{"+hush",       "Hush",         FalseArg, BooleanArg, 5,
703  NULL,         (caddr_t) &hush},
704{"-hushspecials", NULL,         TrueArg, BooleanArg, 2,
705  NULL,         ADDR(_hush_spec)},
706{"+hushspecials", "hushSpecials", FalseArg, BooleanArg, 1,
707  NULL,         ADDR(_hush_spec)},
708{"-hushchars",  NULL,           TrueArg, BooleanArg, 2,
709  NULL,         ADDR(_hush_chars)},
710{"+hushchars",  "hushLostChars", FalseArg, BooleanArg, 1,
711  NULL,         ADDR(_hush_chars)},
712{"-hushchecksums", NULL,        TrueArg, BooleanArg, 2,
713  NULL,         ADDR(_hush_chk)},
714{"+hushchecksums","hushChecksums", FalseArg, BooleanArg, 1,
715  NULL,         ADDR(_hush_chk)},
716{"-safer",      NULL,           TrueArg, BooleanArg, 2,
717  NULL,         ADDR(safer)},
718{"+safer",      "safer",        FalseArg, BooleanArg, 1,
719  NULL,         ADDR(safer)},
720{"-bw",         NULL,           SepArg, NumberArg, 2,
721  "width",      (caddr_t) &bwidth},
722{"-borderwidth", "borderWidth", SepArg, NumberArg, 1,
723  silent,       (caddr_t) &bwidth},
724{"-fg",         NULL,           SepArg, StringArg, 2,
725  "color",      ADDR(fore_color)},
726{"-foreground", "foreground",   SepArg, StringArg, 1,
727  silent,       ADDR(fore_color)},
728{"-bg",         NULL,           SepArg, StringArg, 2,
729  "color",      ADDR(back_color)},
730{"-background", "background",   SepArg, StringArg, 1,
731  silent,       ADDR(back_color)},
732{"-hl",         "highlight",    SepArg, StringArg, 1,
733  "color",      ADDR(high_color)},
734{"-bd",         NULL,           SepArg, StringArg, 2,
735  "color",      ADDR(brdr_color)},
736{"-bordercolor","borderColor",  SepArg, StringArg, 1,
737  silent,       ADDR(brdr_color)},
738{"-cr",         "cursorColor",  SepArg, StringArg, 1,
739  "color",      ADDR(curs_color)},
740#ifndef VMS
741{"-display",    NULL,           SepArg, StringArg, 1,
742  "host:display", (caddr_t) &display},
743#else
744{"-display",    NULL,           SepArg, StringArg, 1,
745  "host::display", (caddr_t) &display},
746#endif
747{"-geometry",   "geometry",     SepArg, StringArg, 1,
748  "geometry",   (caddr_t) &geometry},
749{"-icongeometry","iconGeometry",StickyArg, StringArg, 1,
750  "geometry",   ADDR(icon_geometry)},
751{"-iconic",     NULL,           TrueArg, BooleanArg, 2,
752  NULL,         (caddr_t) &iconic},
753{"+iconic",     "iconic",       FalseArg, BooleanArg, 1,
754  NULL,         (caddr_t) &iconic},
755{"-keep",       NULL,           TrueArg, BooleanArg, 2,
756  NULL,         ADDR(keep_flag)},
757{"+keep",       "keepPosition", FalseArg, BooleanArg, 1,
758  NULL,         ADDR(keep_flag)},
759{"-copy",       NULL,           TrueArg, Bool3Arg, 2,
760  NULL,         ADDR(copy)},
761{"+copy",       "copy",         FalseArg, Bool3Arg, 1,
762  NULL,         ADDR(copy)},
763{"-thorough",   NULL,           TrueArg, BooleanArg, 2,
764  NULL,         ADDR(thorough)},
765{"+thorough",   "thorough",     FalseArg, BooleanArg, 1,
766  NULL,         ADDR(thorough)},
767#if     PS
768{"-nopostscript", NULL,         FalseArg, BooleanArg, 2,
769  NULL,         ADDR(_postscript)},
770{"+nopostscript", "postscript", TrueArg, BooleanArg, 1,
771  NULL,         ADDR(_postscript)},
772{"-noscan", NULL,               FalseArg, BooleanArg, 2,
773  NULL,         ADDR(prescan)},
774{"+noscan",     "prescan",      TrueArg, BooleanArg, 1,
775  NULL,         ADDR(prescan)},
776{"-allowshell", NULL,           TrueArg, BooleanArg, 2,
777  NULL,         ADDR(allow_shell)},
778{"+allowshell", "allowShell",   FalseArg, BooleanArg, 1,
779  NULL,         ADDR(allow_shell)},
780#ifdef  PS_DPS
781{"-nodps",      NULL,           FalseArg, BooleanArg, 2,
782  NULL,         ADDR(useDPS)},
783{"+nodps",      "dps",          TrueArg, BooleanArg, 1,
784  NULL,         ADDR(useDPS)},
785#endif
786#ifdef  PS_NEWS
787{"-nonews",     NULL,           FalseArg, BooleanArg, 2,
788  NULL,         ADDR(useNeWS)},
789{"+nonews",     "news",         TrueArg, BooleanArg, 1,
790  NULL,         ADDR(useNeWS)},
791#endif
792#ifdef  PS_GS
793{"-noghostscript",NULL,         FalseArg, BooleanArg, 2,
794  NULL,         ADDR(useGS)},
795{"+noghostscript","ghostscript", TrueArg, BooleanArg, 1,
796  NULL,         ADDR(useGS)},
797{"-interpreter", "interpreter", SepArg, StringArg, 1,
798  "path",       ADDR(gs_path)},
799{"-nogssafer",  NULL,           FalseArg, BooleanArg, 2,
800  NULL,         ADDR(gs_safer)},
801{"+nogssafer",  "gsSafer",      TrueArg, BooleanArg, 1,
802  NULL,         ADDR(gs_safer)},
803{"-gspalette",  "palette",      SepArg, StringArg, 1,
804  "monochrome|grayscale|color", ADDR(gs_palette)},
805#endif
806#endif  /* PS */
807{"-debug",      "debugLevel",   SepArg, StringArg, 1,
808  "bitmask",    ADDR(debug_arg)},
809{"-version",    NULL,           TrueArg, BooleanArg, 2,
810  NULL,         ADDR(version_flag)},
811{"+version",    "version",      FalseArg, BooleanArg, 1,
812  NULL,         ADDR(version_flag)},
813};
814
815#endif  /* !TOOLKIT */
816
817static  NORETURN void
818usage() {
819#ifdef  TOOLKIT
820        XrmOptionDescRec *opt;
821        _Xconst char    **usageptr = usagestr;
822#else
823        struct option   *opt;
824#endif
825        _Xconst char    **sv    = subst_val;
826        _Xconst char    *str1;
827        _Xconst char    *str2;
828        int             col     = 23;
829        int             n;
830
831        Fputs("Usage: xdvi [+[<page>]]", stderr);
832        for (opt = options; opt < options + XtNumber(options); ++opt) {
833#ifdef  TOOLKIT
834            str1 = opt->option;
835            if (*str1 != '-') continue;
836            str2 = NULL;
837            if (opt->argKind != XrmoptionNoArg) {
838                str2 = *usageptr++;
839                if (str2 == silent) continue;
840                if (str2 == subst) {
841                    str1 = *sv++;
842                    str2 = NULL;
843                }
844            }
845            for (;;) {
846                n = strlen(str1) + 3;
847                if (str2 != NULL) n += strlen(str2) + 3;
848                if (col + n < 80) Putc(' ', stderr);
849                else {
850                    Fputs("\n\t", stderr);
851                    col = 8 - 1;
852                }
853                if (str2 == NULL)
854                    Fprintf(stderr, "[%s]", str1);
855                else
856                    Fprintf(stderr, "[%s <%s>]", str1, str2);
857                col += n;
858                if (**usageptr != '^'
859                         || strcmp(*usageptr + 1, opt->option) != 0) break;
860                ++usageptr;
861                str1 = *usageptr++;
862                str2 = NULL;
863            }
864#else   /* !TOOLKIT */
865            str1 = opt->name;
866            str2 = opt->usagestr;
867            if (*str1 != '-' || str2 == silent) continue;
868            if (str2 == subst) {
869                str1 = *sv++;
870                str2 = NULL;
871            }
872            n = strlen(str1) + 3;
873            if (str2 != NULL) n += strlen(str2) + 3;
874            if (col + n < 80) Putc(' ', stderr);
875            else {
876                Fputs("\n\t", stderr);
877                col = 8 - 1;
878            }
879            if (str2 == NULL)
880                Fprintf(stderr, "[%s]", str1);
881            else
882                Fprintf(stderr, "[%s <%s>]", str1, str2);
883            col += n;
884#endif
885        }
886        if (col + 9 < 80) Putc(' ', stderr);
887        else Fputs("\n\t", stderr);
888        Fputs("dvi_file\n", stderr);
889        exit(1);
890}
891
892static  int
893atopix(arg)
894        _Xconst char    *arg;
895{
896        int             len     = strlen(arg);
897        _Xconst char    *arg_end = arg;
898        char            tmp[11];
899
900        while ((*arg_end >= '0' && *arg_end <= '9') || *arg_end == '.')
901            if (arg_end >= arg + XtNumber(tmp) - 1) return 0;
902            else ++arg_end;
903        bcopy(arg, tmp, arg_end - arg);
904        tmp[arg_end - arg] = '\0';
905
906        return (len > 2 && arg[len - 2] == 'c' && arg[len - 1] == 'm' ?
907                1.0 / 2.54 : 1.0) * atof(tmp) * pixels_per_inch + 0.5;
908}
909
910/**
911 **     Main programs start here.
912 **/
913
914#ifdef  TOOLKIT
915
916static  Arg     temp_args1[] = {
917        {XtNiconX,      (XtArgVal) 0},
918        {XtNiconY,      (XtArgVal) 0},
919};
920
921static  Arg     temp_args2 = {XtNborderWidth,   (XtArgVal) &bwidth};
922
923static  Pixmap  icon_pm;
924
925static  Arg     temp_args3[] = {
926        {XtNiconPixmap, (XtArgVal) &icon_pm},
927};
928
929static  Arg     temp_args4[] = {
930        {XtNtitle,      (XtArgVal) 0},
931        {XtNiconName,   (XtArgVal) 0},
932        {XtNinput,      (XtArgVal) True},
933};
934
935static  Arg     set_wh_args[] = {
936        {XtNwidth,      (XtArgVal) 0},
937        {XtNheight,     (XtArgVal) 0},
938};
939
940/*
941 *      Convert string to yes/no/maybe.  Adapted from the X toolkit.
942 */
943
944/*ARGSUSED*/
945Boolean XtCvtStringToBool3(dpy, args, num_args, fromVal, toVal, closure_ret)
946        Display         *dpy;
947        XrmValuePtr     args;
948        Cardinal        *num_args;
949        XrmValuePtr     fromVal;
950        XrmValuePtr     toVal;
951        XtPointer       *closure_ret;
952{
953        String          str     = (String)fromVal->addr;
954        static Bool3    value;
955
956        if (   memicmp(str, "true", 5) == 0
957            || memicmp(str, "yes", 4) == 0
958            || memicmp(str, "on", 3) == 0
959            || memicmp(str, "1", 2) == 0)       value = True;
960
961        else if (memicmp(str, "false", 6) == 0
962            ||   memicmp(str, "no", 3) == 0
963            ||   memicmp(str, "off", 4) == 0
964            ||   memicmp(str, "0", 2) == 0)     value = False;
965
966        else if (memicmp(str, "maybe", 6) == 0) value = Maybe;
967
968        else {
969            XtDisplayStringConversionWarning(dpy, str, XtRBoolean);
970            return False;
971        }
972
973        if (toVal->addr != NULL) {
974            if (toVal->size < sizeof(Bool3)) {
975                toVal->size = sizeof(Bool3);
976                return False;
977            }
978            *(Bool3 *)(toVal->addr) = value;
979        }
980        else toVal->addr = (XPointer) &value;
981
982        toVal->size = sizeof(Bool3);
983        return True;
984}
985
986#else   /* !TOOLKIT */
987
988struct _resource        resource = {
989        /* density              */      40,
990#ifdef  GREY
991        /* gamma                */      1.0,
992#endif
993        /* pixels_per_inch      */      BDPI,
994        /* sidemargin           */      NULL,
995        /* topmargin            */      NULL,
996        /* xoffset              */      NULL,
997        /* yoffset              */      NULL,
998        /* paper                */      DEFAULT_PAPER,
999        /* alt_font             */      ALTFONT,
1000#ifdef  MAKEPK
1001        /* makepk               */      True,
1002#endif
1003        /* mfmode               */      MFMODE,
1004        /* list_fonts           */      False,
1005        /* reverse              */      False,
1006        /* hush_spec            */      False,
1007        /* hush_chars           */      False,
1008        /* hush_chk             */      False,
1009        /* safer                */      False,
1010        /* fore_color           */      NULL,
1011        /* back_color           */      NULL,
1012        /* brdr_color           */      NULL,
1013        /* high_color           */      NULL,
1014        /* curs_color           */      NULL,
1015        /* fore_Pixel           */      (Pixel) 0,
1016        /* back_Pixel           */      (Pixel) 0,
1017        /* icon_geometry        */      NULL,
1018        /* keep_flag            */      False,
1019        /* copy                 */      Maybe,
1020        /* thorough             */      False,
1021#if     PS
1022        /* postscript           */      True,
1023        /* prescan              */      True,
1024        /* allow_shell          */      Maybe,
1025#ifdef  PS_DPS
1026        /* useDPS               */      True,
1027#endif
1028#ifdef  PS_NEWS
1029        /* useNeWS              */      True,
1030#endif
1031#ifdef  PS_GS
1032        /* useGS                */      True,
1033        /* gs_path              */      GS_PATH,
1034        /* gs_safer             */      True,
1035        /* gs_palette           */      "Color",
1036#endif
1037#endif  /* PS */
1038        /* debug_arg            */      NULL,
1039        /* version_flag         */      False,
1040        /* mg_arg               */      {NULL, NULL, NULL, NULL, NULL},
1041#ifdef  GREY
1042        /* use_grey             */      True,
1043#endif
1044};
1045
1046static  Pixel
1047string_to_pixel(strp)           /* adapted from the toolkit */
1048        char    **strp;
1049{
1050        char    *str = *strp;
1051        Status  status;
1052        XColor  color, junk;
1053
1054        if (*str == '#') {      /* an rgb definition */
1055            status = XParseColor(DISP, DefaultColormapOfScreen(SCRN),
1056                str, &color);
1057            if (status != 0)
1058                status = XAllocColor(DISP, DefaultColormapOfScreen(SCRN),
1059                    &color);
1060        }
1061        else    /* a name */
1062            status = XAllocNamedColor(DISP, DefaultColormapOfScreen(SCRN),
1063                str, &color, &junk);
1064        if (status == 0) {
1065            Fprintf(stderr, "Cannot allocate colormap entry for \"%s\"\n", str);
1066            *strp = NULL;
1067            return (Pixel) 0;
1068        }
1069        return color.pixel;
1070}
1071
1072/*
1073 *      Process the option table.  This is not guaranteed for all possible
1074 *      option tables, but at least it works for this one.
1075 */
1076
1077static  void
1078parse_options(argc, argv)
1079        int argc;
1080        char **argv;
1081{
1082        char    **arg;
1083        char    **argvend = argv + argc;
1084        char    *optstring;
1085        caddr_t addr;
1086        struct option *opt, *lastopt, *candidate;
1087        int     len1, len2, matchlen;
1088
1089        /*
1090         * Step 1.  Process command line options.
1091         */
1092        for (arg = argv + 1; arg < argvend; ++arg) {
1093            len1 = strlen(*arg);
1094            candidate = NULL;
1095            matchlen = 0;
1096            for (opt = options; opt < options + XtNumber(options); ++opt) {
1097                len2 = strlen(opt->name);
1098                if (opt->argclass == StickyArg) {
1099                    if (matchlen <= len2 && !strncmp(*arg, opt->name, len2)) {
1100                        candidate = opt;
1101                        matchlen = len2;
1102                    }
1103                }
1104                else if (len1 <= len2 && matchlen <= len1 &&
1105                    !strncmp(*arg, opt->name, len1)) {
1106                    if (len1 == len2) {
1107                        candidate = opt;
1108                        break;
1109                    }
1110                    if (matchlen < len1) candidate = opt;
1111                    else if (candidate && candidate->argclass != StickyArg)
1112                        candidate = NULL;
1113                    matchlen = len1;
1114                }
1115            }
1116            if (candidate == NULL) {
1117                if (**arg == '-' || dvi_name) usage();
1118                else {
1119                    dvi_name = *arg;
1120                    continue;
1121                }
1122            }
1123                /* flag it for subsequent processing */
1124            candidate->resource = (char *) candidate;
1125                /* store the value */
1126            addr = candidate->address;
1127            switch (candidate->argclass) {
1128                case FalseArg:  *((Boolean *) addr) = False; continue;
1129                case TrueArg:   *((Boolean *) addr) = True; continue;
1130                case StickyArg: optstring = *arg + strlen(candidate->name);
1131                    break;
1132                case SepArg:
1133                    ++arg;
1134                    if (arg >= argvend) usage();
1135                    optstring = *arg;
1136                    break;
1137            }
1138            switch (candidate->argtype) {
1139                case StringArg: *((char **) addr) = optstring; break;
1140                case NumberArg: *((int *) addr) = atoi(optstring); break;
1141                case FloatArg:  *((float *) addr) = atof(optstring); break;
1142                default:  ;
1143            }
1144        }
1145        /*
1146         * Step 2.  Propagate classes for command line arguments.  Backwards.
1147         */
1148        for (opt = options + XtNumber(options) - 1; opt >= options; --opt)
1149            if (opt->resource == (char *) opt) {
1150                addr = opt->address;
1151                lastopt = opt + opt->classcount;
1152                for (candidate = opt; candidate < lastopt; ++candidate) {
1153                    if (candidate->resource != NULL) {
1154                        switch (opt->argtype) {
1155                            case BooleanArg:
1156                            case Bool3Arg:      /* same type as Boolean */
1157                                *((Boolean *) candidate->address) =
1158                                    *((Boolean *) addr);
1159                                break;
1160                            case StringArg:
1161                                *((char **) candidate->address) =
1162                                    *((char **) addr);
1163                                break;
1164                            case NumberArg:
1165                                *((int *) candidate->address) = *((int *) addr);
1166                                break;
1167                            case FloatArg:
1168                                *((float *) candidate->address) =
1169                                    *((float *) addr);
1170                                break;
1171                        }
1172                        candidate->resource = NULL;
1173                    }
1174                }
1175            }
1176
1177        if ((DISP = XOpenDisplay(display)) == NULL)
1178            oops("Can't open display");
1179        SCRN = DefaultScreenOfDisplay(DISP);
1180        /*
1181         * Step 3.  Handle resources (including classes).
1182         */
1183        for (opt = options; opt < options + XtNumber(options); ++opt)
1184            if (opt->resource &&
1185                    ((optstring = XGetDefault(DISP, prog, opt->resource)) ||
1186                    (optstring = XGetDefault(DISP, "XDvi", opt->resource))))
1187                {
1188                    lastopt = opt + opt->classcount;
1189                    for (candidate = opt; candidate < lastopt; ++candidate)
1190                        if (candidate->resource != NULL) switch (opt->argtype) {
1191                            case Bool3Arg:
1192                                if (       memicmp(optstring, "maybe", 6) == 0)
1193                                {
1194                                    * (Bool3 *) candidate->address = Maybe;
1195                                    break;
1196                                }
1197                                /* otherwise, fall through; the underlying */
1198                                /* types of Bool3 and Boolean are the same. */
1199                            case BooleanArg:
1200                                * (Boolean *) candidate->address =
1201                                    (  memicmp(optstring, "true", 5) == 0
1202                                    || memicmp(optstring, "yes", 4) == 0
1203                                    || memicmp(optstring, "on", 3) == 0
1204                                    || memicmp(optstring, "1", 2) == 0);
1205                                break;
1206                            case StringArg:
1207                                * (char **) candidate->address = optstring;
1208                                break;
1209                            case NumberArg:
1210                                * (int *) candidate->address = atoi(optstring);
1211                                break;
1212                            case FloatArg:
1213                                * (float *) candidate->address =
1214                                    atof(optstring);
1215                        }
1216                }
1217}
1218
1219#endif  /* TOOLKIT */
1220
1221static  _Xconst char    *paper_types[] = {
1222        "us",           "8.5x11",
1223        "usr",          "11x8.5",
1224        "legal",        "8.5x14",
1225        "foolscap",     "13.5x17.0",    /* ??? */
1226
1227        /* ISO `A' formats, Portrait */
1228        "a1",           "59.4x84.0cm",
1229        "a2",           "42.0x59.4cm",
1230        "a3",           "29.7x42.0cm",
1231        "a4",           "21.0x29.7cm",
1232        "a5",           "14.85x21.0cm",
1233        "a6",           "10.5x14.85cm",
1234        "a7",           "7.42x10.5cm",
1235
1236        /* ISO `A' formats, Landscape */
1237        "a1r",          "84.0x59.4cm",
1238        "a2r",          "59.4x42.0cm",
1239        "a3r",          "42.0x29.7cm",
1240        "a4r",          "29.7x21.0cm",
1241        "a5r",          "21.0x14.85cm",
1242        "a6r",          "14.85x10.5cm",
1243        "a7r",          "10.5x7.42cm",
1244
1245        /* ISO `B' formats, Portrait */
1246        "b1",           "70.6x100.0cm",
1247        "b2",           "50.0x70.6cm",
1248        "b3",           "35.3x50.0cm",
1249        "b4",           "25.0x35.3cm",
1250        "b5",           "17.6x25.0cm",
1251        "b6",           "13.5x17.6cm",
1252        "b7",           "8.8x13.5cm",
1253
1254        /* ISO `B' formats, Landscape */
1255        "b1r",          "100.0x70.6cm",
1256        "b2r",          "70.6x50.0cm",
1257        "b3r",          "50.0x35.3cm",
1258        "b4r",          "35.3x25.0cm",
1259        "b5r",          "25.0x17.6cm",
1260        "b6r",          "17.6x13.5cm",
1261        "b7r",          "13.5x8.8cm",
1262
1263        /* ISO `C' formats, Portrait */
1264        "c1",           "64.8x91.6cm",
1265        "c2",           "45.8x64.8cm",
1266        "c3",           "32.4x45.8cm",
1267        "c4",           "22.9x32.4cm",
1268        "c5",           "16.2x22.9cm",
1269        "c6",           "11.46x16.2cm",
1270        "c7",           "8.1x11.46cm",
1271
1272        /* ISO `C' formats, Landscape */
1273        "c1r",          "91.6x64.8cm",
1274        "c2r",          "64.8x45.8cm",
1275        "c3r",          "45.8x32.4cm",
1276        "c4r",          "32.4x22.9cm",
1277        "c5r",          "22.9x16.2cm",
1278        "c6r",          "16.2x11.46cm",
1279        "c7r",          "11.46x8.1cm",
1280};
1281
1282static  Boolean
1283set_paper_type() {
1284        _Xconst char    *arg, *arg1;
1285        char    temp[21];
1286        _Xconst char    **p;
1287        char    *q;
1288
1289        if (strlen(resource.paper) > sizeof(temp) - 1) return False;
1290        arg = resource.paper;
1291        q = temp;
1292        for (;;) {      /* convert to lower case */
1293            char c = *arg++;
1294            if (c >= 'A' && c <= 'Z') c ^= ('a' ^ 'A');
1295            *q++ = c;
1296            if (c == '\0') break;
1297        }
1298        arg = temp;
1299        /* perform substitutions */
1300        for (p = paper_types; p < paper_types + XtNumber(paper_types); p += 2)
1301            if (strcmp(temp, *p) == 0) {
1302                arg = p[1];
1303                break;
1304            }
1305        arg1 = index(arg, 'x');
1306        if (arg1 == NULL) return False;
1307        unshrunk_paper_w = atopix(arg);
1308        unshrunk_paper_h = atopix(arg1 + 1);
1309        return (unshrunk_paper_w != 0 && unshrunk_paper_h != 0);
1310}
1311
1312/*
1313 *      main program
1314 */
1315
1316int
1317main(argc, argv)
1318        int argc;
1319        char **argv;
1320{
1321
1322#ifndef TOOLKIT
1323        XSizeHints      size_hints;
1324        XWMHints        wmhints;
1325#endif  /* TOOLKIT */
1326        Dimension       screen_w, screen_h;
1327        char            *title_name;
1328        char            *icon_name;
1329        unsigned        baselen;
1330        int     i;
1331
1332#ifndef VMS
1333        prog = rindex(*argv, '/');
1334#else
1335        prog = rindex(*argv, ']');
1336#endif
1337        if (prog != NULL) ++prog; else prog = *argv;
1338
1339#ifdef  VMS
1340        if (index(prog, '.') != NULL) *index(prog, '.') = '\0';
1341#endif
1342
1343        /* This has to be a special case, for now. */
1344
1345        if (argc == 2 && (strcmp(argv[1], "-version") == 0
1346                || strcmp(argv[1], "--version") == 0)) {
1347            Puts((_Xconst char *) &version);
1348            exit(0);
1349        }
1350
1351#if     CFGFILE
1352        /* get the debug value (if any) from the environment */
1353        /* (it's too early to get it from the command line) */
1354        {
1355            _Xconst char *dbg_str;
1356
1357            dbg_str = getenv("XDVIDEBUG");
1358            if (dbg_str != NULL)
1359                debug = atoi(dbg_str);
1360        }
1361#ifdef  SELFAUTO
1362        argv0 = argv[0];
1363#endif
1364#ifndef CFG2RES
1365        readconfig();           /* read config file(s). */
1366#else   /* CFG2RES */
1367        {
1368            static _Xconst struct cfg2res cfg2reslist[] = {
1369                {"MFMODE",              "mfMode",               False},
1370                {"PIXELSPERINCH",       "pixelsPerInch",        True},
1371                {"SHRINKFACTOR",        "shrinkFactor",         True},
1372#ifdef  BUTTONS
1373                {"SHRINKBUTTON1",       "shrinkButton1",        True},
1374                {"SHRINKBUTTON2",       "shrinkButton2",        True},
1375                {"SHRINKBUTTON3",       "shrinkButton3",        True},
1376                {"SHRINKBUTTON4",       "shrinkButton4",        True},
1377#endif
1378                {"PAPER",               "paper",                False},
1379            };
1380
1381            readconfig(cfg2reslist, cfg2reslist + XtNumber(cfg2reslist),
1382              application_resources,
1383              application_resources + XtNumber(application_resources));
1384        }
1385#endif  /* CFG2RES */
1386#endif  /* CFGFILE */
1387
1388#ifdef  TOOLKIT
1389        top_level = XtInitialize(prog, "XDvi", options, XtNumber(options),
1390                &argc, argv);
1391        while (--argc > 0) {
1392            if (*(*++argv) == '+')
1393                if (curr_page != NULL) usage();
1394                else curr_page = *argv + 1;
1395            else if (dvi_name != NULL) usage();
1396                else dvi_name = *argv;
1397        }
1398
1399        XtSetTypeConverter(XtRString, XtRBool3, XtCvtStringToBool3,
1400            NULL, 0, XtCacheNone, NULL);
1401
1402        XtGetApplicationResources(top_level, (XtPointer) &resource,
1403            application_resources, XtNumber(application_resources),
1404            (ArgList) NULL, 0);
1405        DISP = XtDisplay(top_level);
1406        SCRN = XtScreen(top_level);
1407        shrink_factor = resource.shrinkfactor;
1408
1409#else   /* !TOOLKIT */
1410
1411        parse_options(argc, argv);
1412        if (resource.fore_color)
1413            fore_Pixel = string_to_pixel(&resource.fore_color);
1414        if (resource.back_color)
1415            back_Pixel = string_to_pixel(&resource.back_color);
1416        if (resource.brdr_color)
1417            brdr_Pixel = string_to_pixel(&resource.brdr_color);
1418        if (resource.high_color)
1419            hl_Pixel = string_to_pixel(&resource.high_color);
1420        if (resource.curs_color)
1421            cr_Pixel = string_to_pixel(&resource.curs_color);
1422
1423#endif  /* TOOLKIT */
1424
1425        if (shrink_factor <= 0 || density <= 0 || pixels_per_inch <= 0 ||
1426                dvi_name == NULL) usage();
1427        if (shrink_factor != 1) bak_shrink = shrink_factor;
1428        mane.shrinkfactor = shrink_factor;
1429        if (resource.debug_arg != NULL)
1430            debug = isdigit(*resource.debug_arg) ? atoi(resource.debug_arg)
1431                : DBG_ALL;
1432        if (resource.sidemargin) home_x = atopix(resource.sidemargin);
1433        if (resource.topmargin) home_y = atopix(resource.topmargin);
1434        offset_x = resource.xoffset ? atopix(resource.xoffset)
1435            : pixels_per_inch;
1436        offset_y = resource.yoffset ? atopix(resource.yoffset)
1437            : pixels_per_inch;
1438        if (!set_paper_type())
1439            oops("Don't recognize paper type %s", resource.paper);
1440        for (i = 0; i < 5; ++i)
1441            if (resource.mg_arg[i] != NULL) {
1442                char    *s;
1443
1444                mg_size[i].w = mg_size[i].h = atoi(resource.mg_arg[i]);
1445                s = index(resource.mg_arg[i], 'x');
1446                if (s != NULL) {
1447                    mg_size[i].h = atoi(s + 1);
1448                    if (mg_size[i].h <= 0) mg_size[i].w = 0;
1449                }
1450            }
1451#if     PS
1452        if (resource.safer) {
1453            resource.allow_shell = False;
1454#ifdef  PS_GS
1455            resource.gs_safer = True;
1456#endif
1457        }
1458#endif  /* PS */
1459#ifdef  PS_GS
1460        {
1461            _Xconst char *CGMcgm = "CGMcgm";
1462            _Xconst char *cgmp;
1463
1464            cgmp = index(CGMcgm, resource.gs_palette[0]);
1465            if (cgmp == NULL)
1466                oops("Illegal value %s for gs palette option",
1467                    resource.gs_palette);
1468            if (cgmp >= CGMcgm + 3) {
1469                static  char    gsp[]   = "x";
1470
1471                gsp[0] = *(cgmp - 3);
1472                resource.gs_palette = gsp;
1473            }
1474        }
1475#endif
1476        if (resource.version_flag) Puts((_Xconst char *) &version);
1477
1478        /*
1479         *      Open the dvi file and set titles
1480         */
1481
1482        init_font_open();
1483        open_dvi_file();
1484        if (curr_page) {
1485                current_page = (*curr_page ? atoi(curr_page) : total_pages) - 1;
1486                if (current_page < 0 || current_page >= total_pages) usage();
1487        }
1488        icon_name = rindex(dvi_name, '/');
1489        if (icon_name != NULL) ++icon_name; else icon_name = dvi_name;
1490        baselen = strlen(icon_name);
1491        if (baselen >= sizeof(".dvi")
1492                && strcmp(icon_name + baselen - sizeof(".dvi") + 1, ".dvi")
1493                == 0) {         /* remove the .dvi */
1494            char *p;
1495
1496            baselen -= sizeof(".dvi") - 1;
1497            p = xmalloc(baselen + 1, "icon name");
1498            (void) strncpy(p, icon_name, (int) baselen);
1499            p[baselen] = '\0';
1500            icon_name = p;
1501        }
1502        title_name = xmalloc(baselen + sizeof("Xdvi:  "), "title name");
1503        Strcpy(title_name, "Xdvi:  ");
1504        Strcat(title_name, icon_name);
1505
1506        /*
1507         *      Colors
1508         */
1509
1510        if (resource.reverse) {
1511            if (!resource.fore_color) fore_Pixel = WhitePixelOfScreen(SCRN);
1512            if (!resource.back_color) back_Pixel = BlackPixelOfScreen(SCRN);
1513            /* Set them nonzero */
1514            resource.fore_color = resource.back_color =
1515              (_Xconst char *) &version;
1516        } else {
1517            if (!resource.fore_color) fore_Pixel = BlackPixelOfScreen(SCRN);
1518            if (!resource.back_color) back_Pixel = WhitePixelOfScreen(SCRN);
1519        }
1520
1521        copy = (resource.copy == True);
1522
1523#ifdef  GREY
1524        if (DefaultDepthOfScreen(SCRN) == 1)
1525            use_grey = False;
1526        if (resource._gamma == 0.0) resource._gamma = 1.0;
1527        if (use_grey)
1528            init_pix(True);
1529        else
1530#endif
1531        {
1532            XGCValues   values;
1533            Pixel       set_bits = (Pixel) (fore_Pixel & ~back_Pixel);
1534            Pixel       clr_bits = (Pixel) (back_Pixel & ~fore_Pixel);
1535
1536#define MakeGC(fcn, fg, bg)     (values.function = fcn, values.foreground=fg,\
1537                values.background=bg,\
1538                XCreateGC(DISP, RootWindowOfScreen(SCRN),\
1539                        GCFunction|GCForeground|GCBackground, &values))
1540
1541            if (copy || (set_bits && clr_bits)) {
1542                ruleGC = MakeGC(GXcopy, fore_Pixel, back_Pixel);
1543                if (!resource.thorough) copy = True;
1544            }
1545            if (copy) {
1546                foreGC = ruleGC;
1547                if (resource.copy != True)
1548                    Puts("Note:  overstrike characters may be incorrect.");
1549            }
1550            else {
1551                if (set_bits) foreGC = MakeGC(GXor, set_bits, 0);
1552                if (clr_bits || !set_bits)
1553                    *(foreGC ? &foreGC2 : &foreGC) =
1554                        MakeGC(GXandInverted, clr_bits, 0);
1555                if (!ruleGC) ruleGC = foreGC;
1556            }
1557        }
1558
1559        {
1560            XGCValues   values;
1561
1562            highGC = ruleGC;
1563            if (resource.high_color)
1564                highGC = MakeGC(GXcopy, hl_Pixel, back_Pixel);
1565        }
1566
1567        if (!resource.brdr_color) brdr_Pixel = fore_Pixel;
1568        if (!resource.high_color) hl_Pixel = fore_Pixel;
1569
1570#ifndef VMS
1571        ready_cursor = XCreateFontCursor(DISP, XC_cross);
1572        redraw_cursor = XCreateFontCursor(DISP, XC_watch);
1573#else
1574        DECWCursorFont = XLoadFont(DISP, "DECW$CURSOR");
1575        XSetFont(DISP, foreGC, DECWCursorFont);
1576        redraw_cursor = XCreateGlyphCursor(DISP, DECWCursorFont, DECWCursorFont,
1577                decw$c_wait_cursor, decw$c_wait_cursor + 1,
1578                &resource.fore_color, &resource.back_color);
1579        MagnifyPixmap = XCreateBitmapFromData (DISP, RootWindowOfScreen(SCRN),
1580                mag_glass_bits, mag_glass_width, mag_glass_height);
1581        ready_cursor = XCreatePixmapCursor(DISP, MagnifyPixmap, MagnifyPixmap,
1582                &resource.back_color, &resource.fore_color,
1583                mag_glass_x_hot, mag_glass_y_hot);
1584#endif  /* VMS */
1585
1586        if (!resource.curs_color) cr_Pixel = hl_Pixel;
1587        {
1588            XColor bg_Color, cr_Color;
1589
1590            bg_Color.pixel = back_Pixel;
1591            XQueryColor(DISP, DefaultColormapOfScreen(SCRN), &bg_Color);
1592            cr_Color.pixel = cr_Pixel;
1593            XQueryColor(DISP, DefaultColormapOfScreen(SCRN), &cr_Color);
1594            XRecolorCursor(DISP, ready_cursor, &cr_Color, &bg_Color);
1595            XRecolorCursor(DISP, redraw_cursor, &cr_Color, &bg_Color);
1596        }
1597
1598#ifdef  TOOLKIT
1599
1600        /*
1601         *      Windows (toolkit)
1602         */
1603
1604                /* The following code is lifted from Xterm */
1605        if (resource.icon_geometry != NULL) {
1606            int scr, junk;
1607
1608            for(scr = 0;        /* yyuucchh */
1609                SCRN != ScreenOfDisplay(DISP, scr);
1610                scr++);
1611
1612            (void) XGeometry(DISP, scr, resource.icon_geometry, "",
1613                        0, 0, 0, 0, 0,
1614                        (int *) &temp_args1[0].value,
1615                        (int *) &temp_args1[1].value, &junk, &junk);
1616            XtSetValues(top_level, temp_args1, XtNumber(temp_args1));
1617        }
1618                /* Set icon pixmap */
1619        XtGetValues(top_level, temp_args3, XtNumber(temp_args3));
1620        if (icon_pm == (Pixmap) 0) {
1621            temp_args3[0].value = (XtArgVal) (XCreateBitmapFromData(DISP,
1622                RootWindowOfScreen(SCRN), (_Xconst char *) xdvi_bits,
1623                xdvi_width, xdvi_height));
1624            XtSetValues(top_level, temp_args3, XtNumber(temp_args3));
1625        }
1626        temp_args4[0].value = (XtArgVal) title_name;
1627        temp_args4[1].value = (XtArgVal) icon_name;
1628        XtSetValues(top_level, temp_args4, XtNumber(temp_args4));
1629
1630#ifdef  BUTTONS
1631        form_widget = XtCreateManagedWidget("form", formWidgetClass,
1632                top_level, form_args, XtNumber(form_args));
1633#define form_or_top     form_widget     /* for calls later on */
1634#define form_or_vport   form_widget
1635#else   /* !BUTTONS */
1636#define form_or_top     top_level       /* for calls later on */
1637#define form_or_vport   vport_widget
1638#endif  /* BUTTONS */
1639        vport_widget = XtCreateManagedWidget("vport", viewportWidgetClass,
1640                form_or_top, vport_args, XtNumber(vport_args));
1641        clip_widget = XtNameToWidget(vport_widget, "clip");
1642        draw_args[0].value = (XtArgVal) page_w;
1643        draw_args[1].value = (XtArgVal) page_h;
1644#ifdef  GREY
1645        draw_args[2].value = (XtArgVal) back_Pixel;
1646#endif
1647        draw_widget = XtCreateManagedWidget("drawing", drawWidgetClass,
1648                vport_widget, draw_args, XtNumber(draw_args));
1649        {       /* set default window size */
1650#ifdef  BUTTONS
1651            int xtra_wid = resource.expert ? 0 : XTRA_WID;
1652#else
1653#define xtra_wid        0
1654#endif
1655            XtWidgetGeometry constraints;
1656            XtWidgetGeometry reply;
1657
1658            XtGetValues(top_level, &temp_args2, 1);     /* get border width */
1659            screen_w = WidthOfScreen(SCRN) - 2 * bwidth - xtra_wid;
1660            screen_h = HeightOfScreen(SCRN) - 2 * bwidth;
1661            constraints.request_mode = reply.request_mode = 0;
1662            constraints.width = page_w;
1663            if (page_w > screen_w) {
1664                constraints.request_mode = CWWidth;
1665                constraints.width = screen_w;
1666            }
1667            constraints.height = page_h;
1668            if (page_h > screen_h) {
1669                constraints.request_mode = CWHeight;
1670                constraints.height = screen_h;
1671            }
1672            if (constraints.request_mode != 0
1673                    && constraints.request_mode != (CWWidth | CWHeight))
1674                (void) XtQueryGeometry(vport_widget, &constraints, &reply);
1675            if (!(reply.request_mode & CWWidth))
1676                reply.width = constraints.width;
1677            set_wh_args[0].value = (XtArgVal) ((reply.width < screen_w
1678                                ? reply.width : screen_w) + xtra_wid);
1679            if (!(reply.request_mode & CWHeight))
1680                reply.height = constraints.height;
1681            set_wh_args[1].value = (XtArgVal) (reply.height < screen_h
1682                                        ? reply.height : screen_h);
1683            XtSetValues(top_level, set_wh_args, XtNumber(set_wh_args));
1684#ifdef  BUTTONS
1685            set_wh_args[0].value -= xtra_wid;
1686            XtSetValues(vport_widget, set_wh_args, XtNumber(set_wh_args));
1687            if (!resource.expert) create_buttons(set_wh_args[1].value);
1688#endif  /* BUTTONS */
1689        }
1690        if (resource.fore_color) {
1691            static Arg fore_args = {XtNforeground, (XtArgVal) 0};
1692
1693            fore_args.value = fore_Pixel;
1694            XtSetValues(draw_widget, &fore_args, 1);
1695        }
1696        if (resource.back_color) {
1697            static Arg back_args = {XtNbackground, (XtArgVal) 0};
1698
1699            back_args.value = back_Pixel;
1700            XtSetValues(draw_widget, &back_args, 1);
1701            XtSetValues(clip_widget, &back_args, 1);
1702        }
1703        XtAddEventHandler(form_or_vport, KeyPressMask, False, handle_key,
1704                (caddr_t) NULL);
1705        XtAddEventHandler(vport_widget, StructureNotifyMask, False,
1706                handle_resize, (caddr_t) NULL);
1707        XtAddEventHandler(draw_widget, ExposureMask, False, handle_exp,
1708                (caddr_t) &mane);
1709        XtAddEventHandler(draw_widget, ButtonPressMask, False, handle_button,
1710                (caddr_t) NULL);
1711        XtAddEventHandler(draw_widget, ButtonMotionMask, False, handle_motion,
1712                (caddr_t) NULL);
1713        XtAddEventHandler(draw_widget, ButtonReleaseMask, False, handle_release,
1714                (caddr_t) NULL);
1715        XtRealizeWidget(top_level);
1716
1717        currwin.win = mane.win = XtWindow(draw_widget);
1718
1719        {
1720            XWindowAttributes attrs;
1721
1722            (void) XGetWindowAttributes(DISP, mane.win, &attrs);
1723            backing_store = attrs.backing_store;
1724        }
1725
1726#else   /* !TOOLKIT */
1727
1728        /*
1729         *      Windows (non toolkit)
1730         */
1731
1732        screen_w = WidthOfScreen(SCRN) - 2*bwidth;
1733        screen_h = HeightOfScreen(SCRN) - 2*bwidth;
1734        size_hints.flags = PMinSize;
1735        size_hints.min_width = size_hints.min_height = 50;
1736        size_hints.x = size_hints.y = 0;
1737        if (geometry != NULL) {
1738            int flag = XParseGeometry(geometry, &size_hints.x, &size_hints.y,
1739                &window_w, &window_h);
1740
1741            if (flag & (XValue | YValue))
1742                size_hints.flags |= USPosition;
1743            if (flag & (WidthValue | HeightValue))
1744                size_hints.flags |= USSize;
1745            if (flag & XNegative) size_hints.x += screen_w - window_w;
1746            if (flag & YNegative) size_hints.y += screen_h - window_h;
1747        }
1748        if (!(size_hints.flags & USSize)) {
1749            int x_thick = 0;
1750            int y_thick = 0;
1751            if (screen_w < page_w) x_thick = BAR_THICK;
1752            if (screen_h < page_h + x_thick) y_thick = BAR_THICK;
1753            window_w = page_w + y_thick;
1754            if (window_w > screen_w) {
1755                x_thick = BAR_THICK;
1756                window_w = screen_w;
1757            }
1758            window_h = page_h + x_thick;
1759            if (window_h > screen_h) window_h = screen_h;
1760            size_hints.flags |= PSize;
1761        }
1762        size_hints.width = window_w;
1763        size_hints.height = window_h;
1764        top_level = XCreateSimpleWindow(DISP, RootWindowOfScreen(SCRN),
1765                size_hints.x, size_hints.y, window_w, window_h, bwidth,
1766                brdr_Pixel, back_Pixel);
1767        XSetStandardProperties(DISP, top_level, title_name, icon_name,
1768                (Pixmap) 0, argv, argc, &size_hints);
1769
1770        wmhints.flags = InputHint | StateHint | IconPixmapHint;
1771        wmhints.input = True;   /* window manager must direct input */
1772        wmhints.initial_state = iconic ? IconicState : NormalState;
1773        wmhints.icon_pixmap = XCreateBitmapFromData(DISP,
1774            RootWindowOfScreen(SCRN), (_Xconst char *) xdvi_bits,
1775            xdvi_width, xdvi_height);
1776        if (resource.icon_geometry != NULL) {
1777            int junk;
1778
1779            wmhints.flags |= IconPositionHint;
1780            (void) XGeometry(DISP, DefaultScreen(DISP), resource.icon_geometry,
1781                "", 0, 0, 0, 0, 0, &wmhints.icon_x, &wmhints.icon_y,
1782                &junk, &junk);
1783        }
1784        XSetWMHints(DISP, top_level, &wmhints);
1785
1786        XSelectInput(DISP, top_level, KeyPressMask | StructureNotifyMask);
1787        XMapWindow(DISP, top_level);
1788        XFlush(DISP);
1789
1790#endif  /* TOOLKIT */
1791
1792#define rebindkey(ks, str)      XRebindKeysym(DISP, (KeySym) ks, \
1793                (KeySym *) NULL, 0, (_Xconst ubyte *) str, 1)
1794        rebindkey(XK_Home, "^");
1795        rebindkey(XK_Left, "l");
1796        rebindkey(XK_Up, "u");
1797        rebindkey(XK_Right, "r");
1798        rebindkey(XK_Down, "d");
1799        rebindkey(XK_Prior, "b");
1800        rebindkey(XK_Next, "f");
1801#ifdef  XK_KP_Left
1802        rebindkey(XK_KP_Home, "^");
1803        rebindkey(XK_KP_Left, "l");
1804        rebindkey(XK_KP_Up, "u");
1805        rebindkey(XK_KP_Right, "r");
1806        rebindkey(XK_KP_Down, "d");
1807        rebindkey(XK_KP_Prior, "b");
1808        rebindkey(XK_KP_Next, "f");
1809        rebindkey(XK_KP_Delete, "\177");
1810#endif  /* XK_KP_Left */
1811#undef  rebindkey
1812
1813        image = XCreateImage(DISP, DefaultVisualOfScreen(SCRN), 1, XYBitmap, 0,
1814                             (char *) NULL, 0, 0, BITS_PER_BMUNIT, 0);
1815        image->bitmap_unit = BITS_PER_BMUNIT;
1816#ifndef MSBITFIRST
1817        image->bitmap_bit_order = LSBFirst;
1818#else
1819        image->bitmap_bit_order = MSBFirst;
1820#endif
1821        {
1822            short endian = MSBFirst << 8 | LSBFirst;
1823            image->byte_order = *((char *) &endian);
1824        }
1825
1826        do_pages();
1827        return 0;       /* do_pages() returns if DBG_BATCH is specified */
1828}
Note: See TracBrowser for help on using the repository browser.