Back to index

tetex-bin  3.0
xdvi.c
Go to the documentation of this file.
00001 /*========================================================================*\
00002 
00003 Copyright (c) 1990-2004  Paul Vojta and others
00004 
00005 Permission is hereby granted, free of charge, to any person obtaining a copy
00006 of this software and associated documentation files (the "Software"), to
00007 deal in the Software without restriction, including without limitation the
00008 rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
00009 sell copies of the Software, and to permit persons to whom the Software is
00010 furnished to do so, subject to the following conditions:
00011 
00012 The above copyright notice and this permission notice shall be included in
00013 all copies or substantial portions of the Software.
00014 
00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL PAUL
00018 VOJTA OR ANY OTHER AUTHOR OF THIS SOFTWARE BE LIABLE FOR ANY CLAIM, DAMAGES OR
00019 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00020 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00021 THE SOFTWARE.
00022 
00023 NOTE: xdvi is based on prior work as noted in the modification history, below.
00024 
00025 \*========================================================================*/
00026 
00027 /*
00028  * DVI previewer for X.
00029  *
00030  * Eric Cooper, CMU, September 1985.
00031  *
00032  * Code derived from dvi-imagen.c.
00033  *
00034  * Modification history:
00035  * 1/1986     Modified for X.10    --Bob Scheifler, MIT LCS.
00036  * 7/1988     Modified for X.11    --Mark Eichin, MIT
00037  * 12/1988    Added 'R' option, toolkit, magnifying glass
00038  *                                 --Paul Vojta, UC Berkeley.
00039  * 2/1989     Added tpic support   --Jeffrey Lee, U of Toronto
00040  * 4/1989     Modified for System V       --Donald Richardson, Clarkson Univ.
00041  * 3/1990     Added VMS support    --Scott Allendorf, U of Iowa
00042  * 7/1990     Added reflection mode       --Michael Pak, Hebrew U of Jerusalem
00043  * 1/1992     Added greyscale code --Till Brychcy, Techn. Univ. Muenchen
00044  *                                   and Lee Hetherington, MIT
00045  * 7/1992       Added extra menu buttons--Nelson H. F. Beebe <beebe@math.utah.edu>
00046  * 4/1994     Added DPS support, bounding box
00047  *                                 --Ricardo Telichevesky
00048  *                                   and Luis Miguel Silveira, MIT RLE.
00049  * 2/1995       Added rulers support    --Nelson H. F. Beebe <beebe@math.utah.edu>
00050  * 1/2001     Added source specials       --including ideas from Stefan Ulrich,
00051  *                                   U Munich
00052  *
00053  * Compilation options:
00054  *
00055  * VMS            compile for VMS
00056  * WORDS_BIGENDIAN  store bitmaps internally with most significant bit first
00057  * BMTYPE         store bitmaps in unsigned BMTYPE
00058  * BMBYTES        sizeof(unsigned BMTYPE)
00059  * ALTFONT        default for -altfont option
00060  * SHRINK         default for -s option (shrink factor)
00061  * MFMODE         default for -mfmode option
00062  * A4             use European size paper, and change default dimension to cm
00063  * TEXXET         support reflection dvi codes (right-to-left typesetting)
00064  * GREY                  use grey levels to shrink fonts
00065  * PS_GS          use Ghostscript to render pictures/bounding boxes
00066  * PS_DPS         use display postscript to render pictures/bounding boxes
00067  * PS_NEWS        use the NeWS server to render pictures/bounding boxes
00068  * GS_PATH        path to call the Ghostscript interpreter by
00069  * MAGICK         use ImageMagick to render (external) image files
00070  */
00071 
00072 
00073 #include "xdvi-config.h"
00074 #include "xdvi.h"
00075 #include "version.h"
00076 
00077 #include <locale.h>
00078 
00079 /* Xlib and Xutil are already included */
00080 #include <X11/cursorfont.h>
00081 #include <X11/keysym.h>
00082 #include <X11/Xatom.h>
00083 #include <X11/StringDefs.h>
00084 #include <X11/Shell.h>      /* needed for def. of XtNiconX */
00085 
00086 #ifdef HAVE_X11_XMU_EDITRES_H
00087 # include <X11/Xmu/Editres.h>
00088 #endif
00089 
00090 /* to allow one common dependency file for Xaw/Motif,
00091    we always include all the headers and have
00092    #ifdef MOTIF
00093    tests inside the headers.
00094 */
00095 #if defined(NEW_MENU_CREATION) || defined(MOTIF)
00096 #include "menu.h"    
00097 #else
00098 #include "xm_menu.h" 
00099 #include "xaw_menu.h"
00100 #endif /* NEW_MENU_CREATION */
00101 #include "xm_toolbar.h"
00102 
00103 #ifdef T1LIB
00104 #include "t1lib.h"
00105 #endif /* T1LIB */
00106 
00107 #ifdef MOTIF
00108 
00109 # include <Xm/Xm.h>
00110 # include <Xm/Frame.h>
00111 # include <Xm/PushB.h>
00112 # include <Xm/MainW.h>
00113 # include <Xm/ToggleB.h>
00114 # include <Xm/RowColumn.h>
00115 # include <Xm/ScrolledW.h>
00116 # include <Xm/MenuShell.h>
00117 # include <Xm/DrawingA.h>
00118 # include <Xm/Form.h>
00119 # include <Xm/PanedW.h>
00120 # include <Xm/List.h>
00121 # include <Xm/Protocols.h>
00122 
00123 # include <Xm/Display.h>
00124 
00125 # ifdef MOTIF11 /* FIXME: We'll probably need a config check for this? */
00126 /* used to set up XmStrings */
00127 XmStringCharSet G_charset = (XmStringCharSet)XmSTRING_DEFAULT_CHARSET;
00128 # else
00129 XmStringCharSet G_charset = XmFONTLIST_DEFAULT_TAG;
00130 # endif
00131 
00132 #else /* MOTIF */
00133 
00134 # include <X11/Xaw/Viewport.h>
00135 # include <X11/Xaw/AsciiText.h>
00136 # include <X11/Xaw/Box.h>
00137 # include <X11/Xaw/Command.h>
00138 # include <X11/Xaw/Dialog.h>
00139 # include <X11/Xaw/Form.h>
00140 # include <X11/Xaw/Paned.h>
00141 # include <X11/Xaw/Scrollbar.h>
00142 # include <X11/Xaw/Command.h>
00143 
00144 #endif /* MOTIF */
00145 
00146 #include <signal.h>
00147 #include <stdlib.h>
00148 #include <ctype.h>
00149 
00150 #include "xserver-info.h"
00151 
00152 #include "kpathsea/c-fopen.h"
00153 #include "kpathsea/c-pathch.h"
00154 #include "kpathsea/c-stat.h"
00155 #include "kpathsea/proginit.h"
00156 #include "kpathsea/progname.h"
00157 #include "kpathsea/tex-file.h"
00158 #include "kpathsea/tex-hush.h"
00159 #include "kpathsea/tex-make.h"
00160 #include "string-utils.h"
00161 #include "kpathsea/c-errno.h"
00162 #include "kpathsea/expand.h"
00163 
00164 #include "translations.h"
00165 #include "dvi-init.h"
00166 #include "c-openmx.h"
00167 #include "xicon.h"
00168 #include "x_util.h"
00169 #include "message-window.h"
00170 #include "events.h"
00171 #include "mag.h"
00172 #include "pagesel.h"
00173 #include "dvi-draw.h"
00174 #include "statusline.h"
00175 #include "util.h"
00176 #include "my-snprintf.h"
00177 #include "hypertex.h"
00178 #include "xaw_menu.h"
00179 #include "xdvi-debug.h"
00180 #include "pagehist.h"
00181 #include "filehist.h"
00182 #include "sfSelFile.h"
00183 #include "print-internal.h"
00184 #include "xm_prefsP.h" /* for Xdvi_PREFS_BROWSER_DEFAULTS and Xdvi_PREFS_EDITOR_DEFAULTS */
00185 
00186 #include "pixmaps/time16.xbm"
00187 #include "pixmaps/time16_mask.xbm"
00188 #ifdef VMS 
00189 #  include "pixmaps/hand.xbm"
00190 #  include "pixmaps/hand_mask.xbm"
00191 #endif
00192 #include "pixmaps/magglass.xbm"
00193 #include "pixmaps/magglass_mask.xbm"
00194 #include "pixmaps/drag_vert.xbm"
00195 #include "pixmaps/drag_vert_mask.xbm"
00196 #include "pixmaps/drag_horiz.xbm"
00197 #include "pixmaps/drag_horiz_mask.xbm"
00198 #include "pixmaps/drag_omni.xbm"
00199 #include "pixmaps/drag_omni_mask.xbm"
00200 
00201 #ifdef DEBUG
00202 #include<asm/msr.h>
00203 unsigned long time_start=0, time_end=0;
00204 #endif
00205 
00206 
00207 #ifdef MOTIF
00208 #include <Xm/MwmUtil.h>
00209 
00210 #else /* MOTIF */
00211 
00212 /* need to fake it */
00213 
00214 /* bit definitions for MwmHints.flags */
00215 #define MWM_HINTS_FUNCTIONS (1L << 0)
00216 #define MWM_HINTS_DECORATIONS (1L << 1)
00217 #define MWM_HINTS_INPUT_MODE (1L << 2)
00218 #define MWM_HINTS_STATUS (1L << 3)
00219 
00220 /* bit definitions for MwmHints.decorations */
00221 #define MWM_DECOR_ALL  (1L << 0)
00222 #define MWM_DECOR_BORDER (1L << 1)
00223 #define MWM_DECOR_RESIZEH (1L << 2)
00224 #define MWM_DECOR_TITLE  (1L << 3)
00225 #define MWM_DECOR_MENU  (1L << 4)
00226 #define MWM_DECOR_MINIMIZE (1L << 5)
00227 #define MWM_DECOR_MAXIMIZE (1L << 6)
00228 
00229 struct PropMotifWmHints {
00230     unsigned long flags;
00231     unsigned long functions;
00232     unsigned long decorations;
00233     long          inputMode;
00234     unsigned long status;
00235 };
00236 
00237 #define PROP_MOTIF_WM_HINTS_ELEMENTS 5
00238 
00239 #endif /* MOTIF */
00240 
00241 char *dvi_property;         /* for setting in window */
00242 size_t dvi_property_length; /* length of above, for efficiency */
00243 XImage *G_image;
00244 int G_backing_store;
00245 Display *DISP;
00246 Screen *SCRN;
00247 XtAccelerators G_accels_cr;
00248 
00249 #ifdef GREY
00250 Visual        *G_visual;
00251 unsigned int  G_depth;
00252 Colormap      G_colormap;
00253 #else
00254 # define G_depth     (unsigned int) DefaultDepthOfScreen(SCRN)
00255 # define G_visual    DefaultVisualOfScreen(SCRN)
00256 # define G_colormap  DefaultColormapOfScreen(SCRN)
00257 #endif
00258 
00259 /* global widgets */
00260 
00261 #if defined(MOTIF)
00262 Widget page_list, page_list_scroll;
00263 #if USE_XAW_PANNER
00264 #include "Panner.h"
00265 Widget panner;
00266 static Dimension g_save_shadow_thickness;
00267 #endif
00268 #endif
00269 
00270 static Atom mainDeleteWindow;
00271 
00272 #ifndef MOTIF
00273 static Atom wmProtocols;
00274 static void
00275 handle_delete_message(Widget widget, XtPointer closure, XEvent *event, Boolean *cont)
00276 {
00277     UNUSED(cont);
00278     UNUSED(widget);
00279 
00280     ASSERT(closure == NULL, "handle_delete_message doesn't accept a non-NULL closure argument");
00281     if (event->type == ClientMessage
00282        && event->xclient.message_type == wmProtocols
00283        && (unsigned)(event->xclient.data.l[0]) == mainDeleteWindow) {
00284        /* non-k xdvi also evaluates closure, but we don't, since it's a function pointer
00285           which isn't convertible to void * in ANSI C */
00286        xdvi_exit(EXIT_SUCCESS);
00287     }
00288 }
00289 #endif
00290 
00291 #ifdef TEST_SCROLLING
00292 #warning ========== compiling with TEST_SCROLLING ==========
00293 #endif
00294 
00295 
00296 /* for measuring distance from the ruler */
00297 int g_ruler_pos_x, g_ruler_pos_y;
00298 
00299 Boolean ignore_papersize_specials = False;
00300 
00301 #ifndef       ALTFONT
00302 # define ALTFONT    "cmr10"
00303 #endif
00304 
00305 #ifndef       SHRINK
00306 # define SHRINK          8
00307 #endif
00308 
00309 #ifndef       MFMODE
00310 # define MFMODE          NULL
00311 #endif
00312 
00313 #undef MKTEXPK
00314 #define MKTEXPK MAKEPK
00315 
00316 #if defined(PS_GS) && !defined(GS_PATH)
00317 # define GS_PATH "gs"
00318 #endif
00319 
00320 #if A4
00321 # define DEFAULT_PAPER             "a4"
00322 #else
00323 # define DEFAULT_PAPER             "us"
00324 #endif
00325 
00326 /*
00327  * Main application context, used for Xt event processing.
00328  */
00329 XtAppContext app = NULL;
00330 
00331 static Dimension bwidth = 2;
00332 
00333 struct x_resources resource;
00334 
00335 struct program_globals globals;
00336 
00337 /* color of cursor */
00338 static XColor m_cursor_color;
00339 
00340 /* default magnifier dimensions */
00341 static struct mg_size_rec {
00342     int w;
00343     int h;
00344 } mg_size[] = {
00345     {200, 150}, {400, 250}, {700, 500}, {1000, 800}, {1200, 1200}
00346 };
00347 
00348 size_t get_magglass_items(void) {
00349     return XtNumber(mg_size);
00350 }
00351 
00352 int get_magglass_width(int idx) {
00353     return mg_size[idx].w;
00354 }
00355 
00356 int get_magglass_height(int idx) {
00357     return mg_size[idx].h;
00358 }
00359 
00360 struct WindowRec mane = { (Window) 0, 1, 0, 0, 0, 0, MAXDIM, 0, MAXDIM, 0 };
00361 
00362 /* currwin is temporary storage except for within redraw() */
00363 struct WindowRec currwin = { (Window) 0, 1, 0, 0, 0, 0, MAXDIM, 0, MAXDIM, 0 };
00364 
00365 /*
00366  * Data for options processing.
00367  */
00368 static const char SILENT[] = " ";  /* flag value for usage() */
00369 
00370 static const char SUBST[] = "x";   /* another flag value */
00371 
00372 static const char USAGESTR_END_MARKER[] = "__USAGE_END_MARKER__"; /* end marker */
00373 
00374 static const char *SUBST_VAL[] = { "-mgs[n] <size>" };
00375 
00376 static XrmOptionDescRec options[] = {
00377     {"-q",           ".noInitFile",              XrmoptionNoArg,             (XPointer)"on"       },
00378     {"+q",           ".noInitFile",              XrmoptionNoArg,             (XPointer)"off"      },
00379     {"-geometry",       ".geometry",              XrmoptionSepArg,    (XPointer)NULL       },
00380 #ifdef MOTIF
00381     /* to make `-font' and `-fn' options work, make them an alias for `fontList' */
00382     { "-font",              "*fontList",         XrmoptionSepArg,     (XPointer)NULL       },
00383     { "-fn",         "*fontList",         XrmoptionSepArg,     (XPointer)NULL       },
00384 #endif
00385     {"-s",           ".shrinkFactor",     XrmoptionSepArg,     (XPointer)NULL       },
00386 #ifndef       VMS
00387     {"-S",           ".densityPercent",   XrmoptionSepArg,     (XPointer)NULL       },
00388 #endif
00389     {"-density",     ".densityPercent",   XrmoptionSepArg,     (XPointer)NULL       },
00390     {"-noomega",     ".omega",            XrmoptionNoArg,             (XPointer)"off"      },
00391     {"+noomega",     ".omega",            XrmoptionNoArg,             (XPointer)"on"       },
00392 #if COLOR
00393     {"-nocolor",     ".color",            XrmoptionNoArg,             (XPointer)"off"      },
00394     {"+nocolor",     ".color",            XrmoptionNoArg,             (XPointer)"on"       },
00395 #endif
00396 #ifdef GREY
00397     {"-nogrey",             ".grey",             XrmoptionNoArg,             (XPointer)"off"      },
00398     {"+nogrey",             ".grey",             XrmoptionNoArg,             (XPointer)"on"       },
00399     {"-gamma",              ".gamma",            XrmoptionSepArg,     (XPointer)NULL       },
00400     {"-nomatchinverted",".matchInverted", XrmoptionNoArg,      (XPointer)"off"      },
00401     {"+nomatchinverted",".matchInverted", XrmoptionNoArg,      (XPointer)"on"       },     
00402 /*     {"-invertedfactor", ".invertedFactor",    XrmoptionSepArg,     (XPointer)NULL       }, */
00403     {"-install",     ".install",          XrmoptionNoArg,             (XPointer)"on"       },
00404     {"-noinstall",   ".install",          XrmoptionNoArg,             (XPointer)"off"      },
00405 #endif
00406     {"-rulecolor",   ".ruleColor",        XrmoptionSepArg,     (XPointer)NULL       },
00407     {"-p",           ".pixelsPerInch",    XrmoptionSepArg,     (XPointer)NULL       },
00408     {"-margins",     ".Margin",           XrmoptionSepArg,     (XPointer)NULL       },
00409     {"-sidemargin",  ".sideMargin",              XrmoptionSepArg,     (XPointer)NULL       },
00410     {"-topmargin",   ".topMargin",        XrmoptionSepArg,     (XPointer)NULL       },
00411     {"-offsets",     ".Offset",           XrmoptionSepArg,     (XPointer)NULL       },
00412     {"-xoffset",     ".xOffset",          XrmoptionSepArg,     (XPointer)NULL       },
00413     {"-yoffset",     ".yOffset",          XrmoptionSepArg,     (XPointer)NULL       },
00414     {"-paper",              ".paper",            XrmoptionSepArg,     (XPointer)NULL       },
00415     {"-altfont",     ".altFont",          XrmoptionSepArg,     (XPointer)NULL       },
00416 #ifdef MKTEXPK
00417     {"-nomakepk",    ".makePk",           XrmoptionNoArg,             (XPointer)"off"      },
00418     {"+nomakepk",    ".makePk",           XrmoptionNoArg,             (XPointer)"on"       },
00419 #endif
00420     {"-mfmode",             ".mfMode",           XrmoptionSepArg,     (XPointer)NULL       },
00421     {"-editor",             ".editor",           XrmoptionSepArg,     (XPointer)NULL       },
00422 #ifdef T1LIB
00423     {"-not1lib",     ".t1lib",            XrmoptionNoArg,             (XPointer)"off"      },
00424     {"+not1lib",     ".t1lib",            XrmoptionNoArg,             (XPointer)"on"       },
00425 #endif
00426     {"-sourceposition",     ".sourcePosition",   XrmoptionSepArg,     (XPointer)NULL       },
00427     {"-findstring",  ".findString",              XrmoptionSepArg,     (XPointer)NULL       },
00428     {"-text-encoding",      ".textEncoding",     XrmoptionSepArg,     (XPointer)NULL       },
00429     {"-unique",             ".unique",           XrmoptionNoArg,             (XPointer)"on"       },
00430     {"+unique",             ".unique",           XrmoptionNoArg,             (XPointer)"off"      },
00431     {"-nofork",             ".fork",             XrmoptionNoArg,             (XPointer)"off" },
00432     {"+nofork",             ".fork",             XrmoptionNoArg,             (XPointer)"on"  },
00433 #ifdef RGB_ANTI_ALIASING
00434     {"-subpixels",   ".subPixels",        XrmoptionSepArg,     (XPointer)NULL       },
00435 #endif
00436     {"-l",           ".listFonts",        XrmoptionNoArg,             (XPointer)"on"       },
00437     {"+l",           ".listFonts",        XrmoptionNoArg,             (XPointer)"off"      },
00438     {"-watchfile",   ".watchFile",        XrmoptionSepArg,     (XPointer)NULL       },
00439     {"-expertmode",  ".expertMode",              XrmoptionSepArg,     (XPointer)NULL       },
00440     {"-expert",             ".expert",           XrmoptionNoArg,             (XPointer)"on"       },
00441     {"+expert",             ".expert",           XrmoptionNoArg,             (XPointer)"off"      },
00442     {"+statusline",  ".statusline",              XrmoptionNoArg,             (XPointer)"off"      },
00443     {"-statusline",  ".statusline",              XrmoptionNoArg,             (XPointer)"on"       },
00444     {"+useTeXpages", ".useTeXPages",             XrmoptionNoArg,             (XPointer)"off"      },
00445     {"-useTeXpages", ".useTeXPages",             XrmoptionNoArg,             (XPointer)"on"       },
00446     {"-mgs",         ".magnifierSize1",   XrmoptionSepArg,     (XPointer)NULL       },
00447     {"-mgs1",        ".magnifierSize1",   XrmoptionSepArg,     (XPointer)NULL       },
00448     {"-mgs2",        ".magnifierSize2",   XrmoptionSepArg,     (XPointer)NULL       },
00449     {"-mgs3",        ".magnifierSize3",   XrmoptionSepArg,     (XPointer)NULL       },
00450     {"-mgs4",        ".magnifierSize4",   XrmoptionSepArg,     (XPointer)NULL       },
00451     {"-mgs5",        ".magnifierSize5",   XrmoptionSepArg,     (XPointer)NULL       },
00452     {"-warnspecials",       ".warnSpecials",     XrmoptionNoArg,             (XPointer)"on"       },
00453     {"+warnspecials",       ".warnSpecials",     XrmoptionNoArg,             (XPointer)"off"      },
00454     {"-hush",        ".Hush",             XrmoptionNoArg,             (XPointer)"on"       },
00455     {"+hush",        ".Hush",             XrmoptionNoArg,             (XPointer)"off"      },
00456     {"-hushchars",   ".hushLostChars",    XrmoptionNoArg,             (XPointer)"on"       },
00457     {"+hushchars",   ".hushLostChars",    XrmoptionNoArg,             (XPointer)"off"      },
00458     {"-hushchecksums",      ".hushChecksums",    XrmoptionNoArg,             (XPointer)"on"       },
00459     {"+hushchecksums",      ".hushChecksums",    XrmoptionNoArg,             (XPointer)"off"      },
00460     {"-hushstdout",  ".hushStdout",              XrmoptionNoArg,             (XPointer)"on"       },
00461     {"+hushstdout",  ".hushStdout",              XrmoptionNoArg,             (XPointer)"off"      },
00462     {"-safer",              ".safer",            XrmoptionNoArg,             (XPointer)"on"       },
00463     {"+safer",              ".safer",            XrmoptionNoArg,             (XPointer)"off"      },
00464     {"-fg",          ".foreground",              XrmoptionSepArg,     (XPointer)NULL       },
00465     {"-foreground",  ".foreground",              XrmoptionSepArg,     (XPointer)NULL       },
00466     {"-bg",          ".background",              XrmoptionSepArg,     (XPointer)NULL       },
00467     {"-background",  ".background",              XrmoptionSepArg,     (XPointer)NULL       },
00468     {"-hl",          ".highlight",        XrmoptionSepArg,     (XPointer)NULL       },
00469     {"-cr",          ".cursorColor",             XrmoptionSepArg,     (XPointer)NULL       },
00470     {"-icongeometry",       ".iconGeometry",     XrmoptionSepArg,     (XPointer)NULL       },
00471     {"-keep",        ".keepPosition",     XrmoptionNoArg,             (XPointer)"on"       },
00472     {"+keep",        ".keepPosition",     XrmoptionNoArg,             (XPointer)"off"      },
00473     {"-copy",        ".copy",             XrmoptionNoArg,             (XPointer)"on"       },
00474     {"+copy",        ".copy",             XrmoptionNoArg,             (XPointer)"off"      },
00475     {"-thorough",    ".thorough",         XrmoptionNoArg,             (XPointer)"on"       },
00476     {"+thorough",    ".thorough",         XrmoptionNoArg,             (XPointer)"off"      },
00477     {"-fullscreen",  ".fullscreen",              XrmoptionNoArg,             (XPointer)"on"       },
00478     {"+fullscreen",  ".fullscreen",              XrmoptionNoArg,             (XPointer)"off"      },
00479     {"-pause",              ".pause",            XrmoptionNoArg,             (XPointer)"on"       },
00480     {"+pause",              ".pause",            XrmoptionNoArg,             (XPointer)"off"      },
00481     {"-pausespecial",       ".pauseSpecial",     XrmoptionSepArg,     (XPointer)NULL       },
00482     {"-wheelunit",   ".wheelUnit",        XrmoptionSepArg,     (XPointer)NULL       },
00483     {"-mousemode",   ".mouseMode",        XrmoptionSepArg,     (XPointer)NULL       },
00484 #ifdef PS
00485     {"-postscript",  ".postscript",              XrmoptionSepArg,     (XPointer)NULL       },
00486     {"-allowshell",  ".allowShell",              XrmoptionNoArg,             (XPointer)"on"       },
00487     {"+allowshell",  ".allowShell",              XrmoptionNoArg,             (XPointer)"off"      },
00488 # ifdef       PS_DPS
00489     {"-nodps",              ".dps",                     XrmoptionNoArg,             (XPointer)"off"      },
00490     {"+nodps",              ".dps",                     XrmoptionNoArg,             (XPointer)"on"       },
00491 # endif
00492 # ifdef       PS_NEWS
00493     {"-nonews",             ".news",             XrmoptionNoArg,             (XPointer)"off"      },
00494     {"+nonews",             ".news",             XrmoptionNoArg,             (XPointer)"on"       },
00495 # endif
00496 # ifdef       PS_GS
00497     {"-noghostscript",      ".ghostscript",             XrmoptionNoArg,             (XPointer)"off"      },
00498     {"+noghostscript",      ".ghostscript",             XrmoptionNoArg,             (XPointer)"on"       },
00499     {"-nogssafer",   ".gsSafer",          XrmoptionNoArg,             (XPointer)"off"      },
00500     {"+nogssafer",   ".gsSafer",          XrmoptionNoArg,             (XPointer)"on"       },
00501     {"-gsalpha",     ".gsAlpha",          XrmoptionNoArg,             (XPointer)"on"       },
00502     {"+gsalpha",     ".gsAlpha",          XrmoptionNoArg,             (XPointer)"off"      },
00503     {"-interpreter", ".interpreter",             XrmoptionSepArg,     (XPointer)NULL       },
00504     {"-gspalette",   ".palette",          XrmoptionSepArg,     (XPointer)NULL       },
00505 # endif
00506 # ifdef       MAGICK
00507     {"-magick",             ".ImageMagick",             XrmoptionNoArg,             (XPointer)"on"  },
00508     {"+magick",             ".ImageMagick",             XrmoptionNoArg,             (XPointer)"off" },
00509     {"-magick_cache",       ".MagickCache",             XrmoptionSepArg,     (XPointer)NULL       },
00510 # endif
00511 #endif /* PS */
00512     {"-noscan",             ".prescan",          XrmoptionNoArg,             (XPointer)"off"      },
00513     {"+noscan",             ".prescan",          XrmoptionNoArg,             (XPointer)"on"       },
00514     {"-notempfile",  ".tempFile",         XrmoptionNoArg,             (XPointer)"off"      },
00515     {"+notempfile",  ".tempFile",         XrmoptionNoArg,             (XPointer)"on"       },
00516     {"-dvipspath",   ".dvipsPath",        XrmoptionSepArg,     (XPointer)NULL       },
00517     {"-ps2pdfpath",  ".ps2pdfPath",              XrmoptionSepArg,     (XPointer)NULL       },
00518     {"-debug",              ".debugLevel",              XrmoptionSepArg,     (XPointer)NULL       },
00519     {"-linkstyle",   ".linkStyle",        XrmoptionSepArg,     (XPointer)NULL       },
00520     {"-linkcolor",   ".linkColor",        XrmoptionSepArg,     (XPointer)NULL       },
00521     {"-visitedlinkcolor",".visitedLinkColor",    XrmoptionSepArg,     (XPointer)NULL       },
00522     {"-browser",     ".wwwBrowser",              XrmoptionSepArg,     (XPointer)NULL       },
00523     {"-anchorposition",     ".anchorPosition",   XrmoptionSepArg,     (XPointer)NULL       },
00524 };
00525 
00526 
00527 #define       offset(field) XtOffsetOf(struct x_resources, field)
00528 static int base_tick_length = 4;
00529 
00530 static char XtRBool3[] = "Bool3";  /* resource for Bool3 */
00531 
00532 static XtResource application_resources[] = {
00533     {"regression", "Regression", XtRBoolean, sizeof(Boolean),
00534      offset(regression), XtRString, "false"},
00535     {"geometry", "Geometry", XtRString, sizeof(char *),
00536      offset(geometry), XtRString, (XtPointer) NULL},
00537     {"windowSize", "WindowSize", XtRString, sizeof(char *),
00538      offset(windowsize), XtRString, (XtPointer) NULL},
00539     {"rememberWindowSize", "RememberWindowSize", XtRBoolean, sizeof(Boolean),
00540      offset(remember_windowsize), XtRString, "false"},
00541     /* used to check whether app-defaults file is out of sync. Initialize
00542        to a low default value (one before the resource was introduced) */
00543     {"appDefaultsFileVersion", "AppDefaultsFileVersion", XtRInt, sizeof(int),
00544      offset(app_defaults_fileversion), XtRImmediate, (XtPointer)20030302 },
00545     {"shrinkFactor", "ShrinkFactor", XtRInt, sizeof(int),
00546      offset(shrinkfactor), XtRImmediate, (XtPointer) SHRINK},
00547     {"delayRulers", "DelayRulers", XtRBoolean, sizeof(Boolean),
00548      offset(delay_rulers), XtRString, "true"},
00549     {"useTeXPages", "UseTeXPages", XtRBoolean, sizeof(Boolean),
00550      offset(use_tex_pages), XtRString, "false"},
00551     {"densityPercent", "DensityPercent", XtRInt, sizeof(int),
00552      offset(density), XtRString, "40"},
00553     {"omega", "Omega", XtRBoolean, sizeof(Boolean),
00554      offset(omega), XtRString, "true"},
00555     {"mainTranslations", "MainTranslations", XtRString, sizeof(char *),
00556      offset(main_translations), XtRString, (XtPointer) NULL},
00557     {"wheelTranslations", "WheelTranslations", XtRString, sizeof(char *),
00558      offset(wheel_translations), XtRString, (XtPointer) "<Btn4Down>:wheel(-0.2)\n<Btn5Down>:wheel(0.2)"},
00559     {"wheelUnit", "WheelUnit", XtRInt, sizeof(int),
00560      offset(wheel_unit), XtRImmediate, (XtPointer) 80},
00561     {"mouseMode", "MouseMode", XtRInt, sizeof(int),
00562      offset(mouse_mode), XtRImmediate, (XtPointer)MOUSE_MAGNIFIER_MODE},
00563 #ifdef GREY
00564     {"gamma", "Gamma", XtRFloat, sizeof(float),
00565      offset(gamma), XtRString, "1"},
00566 /*     {"invertedFactor", "InvertedFactor", XtRFloat, sizeof(float), */
00567 /*      offset(inverted_factor), XtRString, "3.0"}, */
00568 #endif
00569     {"pixelsPerInch", "PixelsPerInch", XtRInt, sizeof(int),
00570      offset(pixels_per_inch), XtRImmediate, (XtPointer) BDPI},
00571     {"sideMargin", "Margin", XtRString, sizeof(char *),
00572      offset(sidemargin), XtRString, (XtPointer) NULL},
00573     {"tickLength", "TickLength", XtRInt, sizeof(int),
00574      offset(tick_length), XtRInt, (XtPointer) & base_tick_length},
00575     {"tickUnits", "TickUnits", XtRString, sizeof(char *),
00576      offset(tick_units), XtRString, "mm"},
00577     {"topMargin", "Margin", XtRString, sizeof(char *),
00578      offset(topmargin), XtRString, (XtPointer) NULL},
00579     {"xOffset", "Offset", XtRString, sizeof(char *),
00580      offset(xoffset), XtRString, (XtPointer) NULL},
00581     {"yOffset", "Offset", XtRString, sizeof(char *),
00582      offset(yoffset), XtRString, (XtPointer) NULL},
00583     {"useCurrentOffset", "UseCurrentOffset", XtRBoolean, sizeof(Boolean),
00584      offset(use_current_offset), XtRString, "False" },
00585     {"paper", "Paper", XtRString, sizeof(char *),
00586      offset(paper), XtRString, (XtPointer) DEFAULT_PAPER},
00587     {"paperLandscape", "PaperLandscape", XtRBoolean, sizeof(Boolean),
00588      offset(paper_landscape), XtRString, "false"},
00589     {"altFont", "AltFont", XtRString, sizeof(char *),
00590      offset(alt_font), XtRString, (XtPointer) ALTFONT},
00591     {"makePk", "MakePk", XtRBoolean, sizeof(Boolean),
00592      offset(makepk), XtRString,
00593 #ifdef MAKE_TEX_PK_BY_DEFAULT
00594      "true"
00595 #else
00596      "false"
00597 #endif
00598      },
00599     {"mfMode", "MfMode", XtRString, sizeof(char *),
00600      offset(mfmode), XtRString, MFMODE},
00601     {"editor", "Editor", XtRString, sizeof(char *),
00602      offset(editor), XtRString, (XtPointer) NULL},
00603 #ifdef T1LIB
00604     {"t1lib", "T1lib", XtRBoolean, sizeof(Boolean),
00605      offset(t1lib), XtRString, "true"},
00606 #endif
00607     {"sourcePosition", "SourcePosition", XtRString, sizeof(char *),
00608      offset(src_pos), XtRString, (XtPointer) NULL},
00609     {"findString", "FindString", XtRString, sizeof(char *),
00610      offset(find_string), XtRString, (XtPointer) NULL},
00611     {"textEncoding", "TextEncoding", XtRString, sizeof(char *),
00612      offset(text_encoding), XtRString, (XtPointer) NULL},
00613     {"fork", "Fork", XtRBoolean, sizeof(Boolean),
00614      offset(src_fork), XtRString, "true"},
00615 #ifdef RGB_ANTI_ALIASING
00616     {"subPixels", "SubPixels", XtRString, sizeof(char *),
00617      offset(sub_pixels), XtRString, "Unknown"},
00618 #endif
00619     {"noFileArgUseHistory", "NoFileArgUseHistory", XtRBoolean, sizeof(Boolean),
00620      offset(no_file_arg_use_history), XtRString, "true"},
00621     {"fileHistory", "FileHistory", XtRString, sizeof(char *),
00622      offset(file_history), XtRString, (XtPointer) NULL},
00623     {"fileHistorySize", "FileHistorySize", XtRInt, sizeof(int),
00624      offset(file_history_size), XtRImmediate, (XtPointer)20},
00625     {"unique", "Unique", XtRBoolean, sizeof(Boolean),
00626      offset(unique), XtRString, "false"},
00627     {"listFonts", "ListFonts", XtRBoolean, sizeof(Boolean),
00628      offset(list_fonts), XtRString, "false"},
00629     {"reverseVideo", "ReverseVideo", XtRBoolean, sizeof(Boolean),
00630      offset(reverse), XtRString, "false"},
00631     {"warnSpecials", "WarnSpecials", XtRBoolean, sizeof(Boolean),
00632      offset(warn_spec), XtRString, "false"},
00633     {"hushLostChars", "Hush", XtRBoolean, sizeof(Boolean),
00634      offset(hush_chars), XtRString, "false"},
00635     {"hushChecksums", "Hush", XtRBoolean, sizeof(Boolean),
00636      offset(hush_chk), XtRString, "false"},
00637     {"hushStdout", "HushStdout", XtRBoolean, sizeof(Boolean),
00638      offset(hush_stdout), XtRString, "false"},
00639     {"safer", "Safer", XtRBoolean, sizeof(Boolean),
00640      offset(safer), XtRString, "false"},
00641 #ifdef VMS
00642     {"foreground", "Foreground", XtRString, sizeof(char *),
00643      offset(fore_color), XtRString, (XtPointer) NULL},
00644     {"background", "Background", XtRString, sizeof(char *),
00645      offset(back_color), XtRString, (XtPointer) NULL},
00646 #endif
00647     {"iconGeometry", "IconGeometry", XtRString, sizeof(char *),
00648      offset(icon_geometry), XtRString, (XtPointer) NULL},
00649     {"keepPosition", "KeepPosition", XtRBoolean, sizeof(Boolean),
00650      offset(keep_flag), XtRString, "false"},
00651 #ifdef PS
00652     {"postscript", "Postscript", XtRInt, sizeof(int),
00653      offset(postscript), XtRImmediate, (XtPointer)1},
00654     {"allowShell", "AllowShell", XtRBoolean, sizeof(Boolean),
00655      offset(allow_shell), XtRString, "false"},
00656 # ifdef       PS_DPS
00657     {"dps", "DPS", XtRBoolean, sizeof(Boolean),
00658      offset(useDPS), XtRString, "true"},
00659 # endif
00660 # ifdef       PS_NEWS
00661     {"news", "News", XtRBoolean, sizeof(Boolean),
00662      offset(useNeWS), XtRString, "true"},
00663 # endif
00664 # ifdef       PS_GS
00665     {"ghostscript", "Ghostscript", XtRBoolean, sizeof(Boolean),
00666      offset(useGS), XtRString, "true"},
00667     {"gsSafer", "Safer", XtRBoolean, sizeof(Boolean),
00668      offset(gs_safer), XtRString, "true"},
00669     {"gsAlpha", "Alpha", XtRBoolean, sizeof(Boolean),
00670      offset(gs_alpha), XtRString, "false"},
00671     {"interpreter", "Interpreter", XtRString, sizeof(char *),
00672      offset(gs_path), XtRString, (XtPointer) GS_PATH},
00673     {"palette", "Palette", XtRString, sizeof(char *),
00674      offset(gs_palette), XtRString, (XtPointer) "Color"},
00675     {"gsTimeout", "GSTimeout", XtRInt, sizeof(int),
00676      offset(gs_timeout), XtRImmediate, (XtPointer)3000},
00677 # endif /* PS_GS */
00678 # ifdef       MAGICK
00679     {"magick", "ImageMagick", XtRBoolean, sizeof(Boolean),
00680      offset(useMAGICK), XtRString, "true"},
00681     {"magick_cache", "MagickCache", XtRString, sizeof(char *),
00682      offset(magick_cache), XtRString, (XtPointer) NULL},
00683 # endif
00684 #endif /* PS */
00685     {"prescan", "Prescan", XtRBoolean, sizeof(Boolean),
00686      offset(prescan), XtRString, "true"},
00687     {"tempFile", "TempFile", XtRBoolean, sizeof(Boolean),
00688      offset(use_temp_fp), XtRString, "true"},
00689     {"copy", "Copy", XtRBoolean, sizeof(Boolean),
00690      offset(copy), XtRString, "false"},
00691     {"thorough", "Thorough", XtRBoolean, sizeof(Boolean),
00692      offset(thorough), XtRString, "false"},
00693     {"fullscreen", "Fullscreen", XtRBoolean, sizeof(Boolean),
00694      offset(fullscreen), XtRString, "false"},
00695     {"pause", "Pause", XtRBoolean, sizeof(Boolean),
00696      offset(pause), XtRString, "false"},
00697     {"pauseSpecial", "PauseSpecial", XtRString, sizeof(char *),
00698      offset(pause_special), XtRString, (XtPointer)"xdvi:pause"},
00699     {"debugLevel", "DebugLevel", XtRString, sizeof(char *),
00700      offset(debug_arg), XtRString, (XtPointer) NULL},
00701     {"menuTranslations", "MenuTranslations", XtRString, sizeof(char *),
00702      offset(menu_translations), XtRString, (XtPointer) default_menu_config},
00703     {"watchFile", "WatchFile", XtRFloat, sizeof(float),
00704      offset(watch_file), XtRString, "0"},
00705     {"expert", "Expert", XtRBoolean, sizeof(Boolean),
00706      offset(expert), XtRString, (XtPointer) NULL},
00707     {"expertMode", "ExpertMode", XtRInt, sizeof(int),
00708      offset(expert_mode), XtRImmediate, (XtPointer)31 /* everything on */ },
00709 #ifndef MOTIF
00710     {"buttonSideSpacing", "ButtonSpacing", XtRDimension, sizeof(Dimension),
00711      offset(btn_side_spacing), XtRImmediate, (XtPointer) 8},
00712     {"buttonTopSpacing", "ButtonSpacing", XtRDimension, sizeof(Dimension),
00713      offset(btn_top_spacing), XtRImmediate, (XtPointer) 16},
00714     {"buttonBetweenSpacing", "ButtonSpacing", XtRDimension, sizeof(Dimension),
00715      offset(btn_between_spacing), XtRImmediate, (XtPointer) 8},
00716     /* ignored; only for backwards compatibility */
00717     {"buttonBetweenExtra", "ButtonSpacing", XtRDimension, sizeof(Dimension),
00718      offset(btn_between_extra), XtRImmediate, (XtPointer)0},
00719     {"buttonBorderWidth", "BorderWidth", XtRDimension, sizeof(Dimension),
00720      offset(btn_border_width), XtRImmediate, (XtPointer) 1},
00721 #endif /* MOTIF */
00722     {"statusline", "Statusline", XtRBoolean, sizeof(Boolean),
00723      offset(statusline), XtRString, (XtPointer) NULL},
00724 #ifdef MOTIF
00725     {"toolbarTranslations", "ToolbarTranslations", XtRString, sizeof(char *),
00726      offset(toolbar_translations), XtRString, (XtPointer) default_toolbar_translations},
00727     {"toolbarPixmapFile", "ToolbarPixmapFile", XtRString, sizeof(char *),
00728      offset(toolbar_pixmap_file), XtRString, (XtPointer) "toolbar.xpm"},
00729     {"toolbarButtonsRaised", "ToolbarButtonsRaised", XtRBoolean, sizeof(Boolean),
00730      offset(toolbar_buttons_raised), XtRString, "True"},
00731     {"tooltipsInStatusline", "TooltipsInStatusline", XtRBoolean, sizeof(Boolean),
00732      offset(tooltips_in_statusline), XtRString, "True"},
00733     {"showTooltips", "ShowTooltips", XtRBoolean, sizeof(Boolean),
00734      offset(show_tooltips), XtRString, "True"},
00735 #endif /* MOTIF */
00736     {"pageListHighlightCurrent", "PageListHighlightCurrent", XtRBoolean, sizeof(Boolean),
00737      offset(pagelist_highlight_current), XtRString, "True"},
00738     {"pageListWidth", "PageListWidth", XtRDimension, sizeof(Dimension),
00739      offset(pagelist_width), XtRImmediate, (XtPointer) 80},
00740     {"magnifierSize1", "MagnifierSize", XtRString, sizeof(char *),
00741      offset(mg_arg[0]), XtRString, (XtPointer) NULL},
00742     {"magnifierSize2", "MagnifierSize", XtRString, sizeof(char *),
00743      offset(mg_arg[1]), XtRString, (XtPointer) NULL},
00744     {"magnifierSize3", "MagnifierSize", XtRString, sizeof(char *),
00745      offset(mg_arg[2]), XtRString, (XtPointer) NULL},
00746     {"magnifierSize4", "MagnifierSize", XtRString, sizeof(char *),
00747      offset(mg_arg[3]), XtRString, (XtPointer) NULL},
00748     {"magnifierSize5", "MagnifierSize", XtRString, sizeof(char *),
00749      offset(mg_arg[4]), XtRString, (XtPointer) NULL},
00750 #if COLOR
00751     {"color", "Color", XtRBoolean, sizeof(Boolean),
00752      offset(use_color), XtRString, "true"},
00753 #endif /* COLOR */
00754     {"dvipsPath", "DvipsPath", XtRString, sizeof(char *),
00755      offset(dvips_path), XtRString, (XtPointer)DEFAULT_DVIPS_PATH},
00756     {"ps2pdfPath", "Ps2PdfPath", XtRString, sizeof(char *),
00757      offset(ps2pdf_path), XtRString, (XtPointer)DEFAULT_PS2PDF_PATH},
00758     {"dvipsHangTime", "DvipsHangTime", XtRInt, sizeof(int),
00759      offset(dvips_hang), XtRImmediate, (XtPointer) -1500},
00760     {"dvipsFailHangTime", "DvipsFailHangTime", XtRInt, sizeof(int),
00761      offset(dvips_fail_hang), XtRImmediate, (XtPointer) -5000},
00762     {"dvipsPrinterString", "DvipsPrinterString", XtRString, sizeof(char *),
00763      offset(dvips_printer_str), XtRString, (XtPointer)NULL},
00764     {"dvipsOptionsString", "DvipsOptionsString", XtRString, sizeof(char *),
00765      offset(dvips_options_str), XtRString, (XtPointer)NULL},
00766     {"defaultSavingFormat", "DefaultSavingFormat", XtRInt, sizeof(int),
00767      offset(default_saving_format), XtRImmediate, (XtPointer)0},
00768     {"defaultPrintingTarget", "DefaultPrintingTarget", XtRInt, sizeof(int),
00769      offset(default_printing_target), XtRImmediate, (XtPointer)1},
00770 #ifdef GREY
00771     {"grey", "Grey", XtRBoolean, sizeof(Boolean),
00772      offset(use_grey), XtRString, "true"},
00773     {"install", "Install", XtRBool3, sizeof(Bool3),
00774      offset(install), XtRString, "maybe"},
00775 #endif /* GREY */
00776     {"matchInverted", "MatchInverted", XtRBoolean, sizeof(Boolean),
00777      offset(match_highlight_inverted), XtRString, "true"},
00778     {"ruleColor", "RuleColor", XtRPixel, sizeof(Pixel),
00779      offset(rule_pixel), XtRPixel, (XtPointer) &resource.rule_pixel},
00780     {"ruleColor", "RuleColor", XtRString, sizeof(char *),
00781      offset(rule_color), XtRString, (XtPointer) NULL},
00782     /* linkStyle: style for presenting links:
00783        link_style is a bitsmask `xy' with x = color, y = underline, viz.:
00784        0: no highlighting at all
00785        1: underline with linkColor
00786        2: no underlining, text with linkColor
00787        3: underlining and text with linkColor
00788     */
00789     {"linkStyle", "LinkStyle", XtRInt, sizeof(int),
00790      offset(link_style), XtRImmediate, (XtPointer) 3},
00791     {"linkColor", "LinkColor", XtRString, sizeof(char *),
00792      offset(link_color), XtRString, (XtPointer)LINK_COLOR_FALLBACK},
00793     {"visitedLinkColor", "VisitedLinkColor", XtRString, sizeof(char *),
00794      offset(visited_link_color), XtRString, (XtPointer)VISITED_LINK_COLOR_FALLBACK},
00795     {"wwwBrowser", "WWWBrowser", XtRString, sizeof(char *),
00796      offset(browser), XtRString, (XtPointer) NULL},
00797 #ifdef MOTIF
00798     {"prefsBrowserList", "PrefsBrowserList", XtRString, sizeof(char *),
00799      offset(prefs_browser_list), XtRString, (XtPointer)Xdvi_PREFS_BROWSER_DEFAULTS },
00800     {"prefsEditorList", "PrefsEditorList", XtRString, sizeof(char *),
00801      offset(prefs_editor_list), XtRString, (XtPointer)Xdvi_PREFS_EDITOR_DEFAULTS },
00802 #endif
00803     /* defaults for unknown mime types */
00804     {"unknownMimeSuffix", "UnknownMimeSuffix", XtRString, sizeof(char *),
00805      offset(unknown_mime_suffix), XtRString, "application/x-unknown"},
00806     {"noMimeSuffix", "NoMimeSuffix", XtRString, sizeof(char *),
00807      offset(no_mime_suffix), XtRString, "application/x-unknown"},
00808     {"anchorPosition", "AnchorPosition", XtRString, sizeof(char *),
00809      offset(anchor_pos), XtRString, (XtPointer) NULL},
00810     /* bitmask for current search window settings; only used internally! */
00811     {"searchWindowDefaults", "SearchWindowDefaults", XtRInt, sizeof(int),
00812      offset(search_window_defaults), XtRImmediate, (XtPointer)0},
00813     /* resources for help text */
00814     {"helpGeneral", "HelpGeneral", XtRString, sizeof(char *),
00815      offset(help_general), XtRString, NULL},
00816     {"helpHypertex", "HelpHypertex", XtRString, sizeof(char *),
00817      offset(help_hypertex), XtRString, NULL},
00818     {"helpOthercommands", "HelpOthercommands", XtRString, sizeof(char *),
00819      offset(help_othercommands), XtRString, NULL},
00820     {"helpMarking", "HelpMarking", XtRString, sizeof(char *),
00821      offset(help_marking), XtRString, NULL},
00822     {"helpPagemotion", "HelpPagemotion", XtRString, sizeof(char *),
00823      offset(help_pagemotion), XtRString, NULL},
00824     {"helpMousebuttons", "HelpMousebuttons", XtRString, sizeof(char *),
00825      offset(help_mousebuttons), XtRString, NULL},
00826     {"helpModes", "HelpModes", XtRString, sizeof(char *),
00827      offset(help_modes), XtRString, NULL},
00828     {"helpSearch", "HelpSearch", XtRString, sizeof(char *),
00829      offset(help_search), XtRString, NULL},
00830     {"helpSourcespecials", "HelpSoucespecials", XtRString, sizeof(char *),
00831      offset(help_sourcespecials), XtRString, NULL},
00832 #ifdef GREY
00833     {"pageHistorySize", "PageHistorySize", XtRInt, sizeof(int),
00834      offset(page_history_size), XtRImmediate, (XtPointer)1000},
00835 };
00836 
00837 /* get these before setting `application_resources' */
00838 static XtResource xdvirc_resources[] = {
00839     {"noInitFile", "NoInitFile", XtRBoolean, sizeof(Boolean),
00840      offset(no_init_file), XtRString, "false"},
00841 };
00842 
00843 static XtResource app_pixel_resources[] = {      /* get these later */
00844 #endif /* GREY */
00845     {"foreground", "Foreground", XtRPixel, sizeof(Pixel),
00846      offset(fore_Pixel), XtRString, XtDefaultForeground},
00847     {"background", "Background", XtRPixel, sizeof(Pixel),
00848      offset(back_Pixel), XtRString, XtDefaultBackground},
00849 /*     {"borderColor", "BorderColor", XtRPixel, sizeof(Pixel), */
00850 /*      offset(brdr_Pixel), XtRPixel, (XtPointer) &resource.fore_Pixel}, */
00851     {"highlight", "Highlight", XtRPixel, sizeof(Pixel),
00852      offset(hl_Pixel), XtRPixel, (XtPointer) &resource.fore_Pixel},
00853     {"cursorColor", "CursorColor", XtRPixel, sizeof(Pixel),
00854      offset(cr_Pixel), XtRImmediate, (XtPointer)ULONG_MAX},
00855 };
00856 #undef offset
00857 
00858 /* Here, list usage values for options that have `XrmoptionSepArg' set.
00859    TODO: what does the `^' stand for?
00860  */
00861 static const char *usagestr[] = {
00862     /* geometry             */ SILENT,
00863 #ifdef MOTIF
00864     /* font          */ SILENT,
00865     /* f             */ SILENT,
00866 #endif
00867     /* shrinkFactor  */ "shrink",
00868 #ifndef       VMS
00869     /* S             */ "density",
00870     /* density              */ SILENT,
00871 #else
00872     /* density              */ "density",
00873 #endif
00874 #ifdef GREY
00875     /* gamma         */ "float",
00876 #endif
00877     /* rulecolor     */ "color",
00878     /* p             */ "pixels",
00879     /* margins              */ "dimen",
00880     /* sidemargin    */ "dimen",
00881     /* topmargin     */ "dimen",
00882     /* offsets              */ "dimen",
00883     /* xoffset              */ "dimen",
00884     /* yoffset              */ "dimen",
00885     /* paper         */ "papertype",
00886     /* altfont              */ "font",
00887     /* mfmode        */ "mode-def",
00888     /* editor        */ "editor",
00889     /* sourceposition       */ "linenumber[ ]*filename",
00890     /* findstring    */ "string",
00891     /* textencoding  */ "charset",
00892 #ifdef RGB_ANTI_ALIASING
00893     /* subpixels     */ "{rgb,bgr}[ i1 i2 i3]",
00894 #endif
00895     /* rv            */ "^-l", "-rv",
00896     /* watchfile     */ "secs",
00897     /* expertmode    */ "flag",
00898     /* mgs           */ SUBST,
00899     /* mgs1          */ SILENT,
00900     /* mgs2          */ SILENT,
00901     /* mgs3          */ SILENT,
00902     /* mgs4          */ SILENT,
00903     /* mgs5          */ SILENT,
00904     /* fg            */ "color",
00905     /* foreground    */ SILENT,
00906     /* bg            */ "color",
00907     /* background    */ SILENT,
00908     /* hl            */ "color",
00909     /* cr            */ "color",
00910 #ifndef VMS
00911     /* display              */ "^-cr", "-display <host:display>",
00912 #else
00913     /* display              */ "^-cr", "-display <host::display>",
00914 #endif
00915     /* geometry             */ "^-cr", "-geometry <geometry>",
00916     /* icongeometry  */ "geometry",
00917     /* iconic        */ "^-icongeometry", "-iconic",
00918     /* font          */ "^-icongeometry", "-font <font>",
00919     /* pausespecial  */ "string",
00920     /* wheelunit     */ "pixels",
00921     /* mousemode     */ "0|1|2",
00922 #ifdef PS
00923     /* postscript    */ "0|1|2",
00924 # ifdef PS_GS
00925     /* interpreter   */ "path",
00926     /* gspalette     */ "monochrome|grayscale|color",
00927 # endif
00928 # ifdef MAGICK
00929     /* magick_cache  */ "size[k|K|m|M|g|G]",
00930 # endif
00931 #endif
00932     /* dvipspath     */ "path",
00933     /* ps2pdfpath    */ "path",
00934     /* debug         */ "bitmask|string[,string ...]",
00935     /* linkstyle     */ "0|1|2|3",
00936     /* linkcolor     */ "color",
00937     /* visitedlinkcolor     */ "color",
00938     /* browser              */ "WWWbrowser",
00939     /* anchorposition       */ "anchor",
00940     /* [end marker]  */ USAGESTR_END_MARKER
00941 };
00942 
00943 #ifndef MOTIF
00944 
00945 # ifdef       NOQUERY
00946 #  define drawWidgetClass widgetClass
00947 # else
00948 
00949 static XtGeometryResult
00950 QueryGeometry(Widget w,
00951              XtWidgetGeometry *constraints,
00952              XtWidgetGeometry *reply)
00953 {
00954     UNUSED(w);
00955     UNUSED(constraints);
00956     reply->request_mode = CWWidth | CWHeight;
00957     reply->width = globals.page.w;
00958     reply->height = globals.page.h + global_statusline_h;
00959 
00960     return XtGeometryAlmost;
00961 }
00962 
00963 # include <X11/IntrinsicP.h>
00964 # include <X11/CoreP.h>
00965 
00966 /* if the following gives you trouble, just compile with -DNOQUERY */
00967 static WidgetClassRec drawingWidgetClass = {
00968     {
00969      /* superclass          */ &widgetClassRec,
00970      /* class_name          */ "Draw",
00971      /* widget_size         */ sizeof(WidgetRec),
00972      /* class_initialize    */ NULL,
00973      /* class_part_initialize      */ NULL,
00974      /* class_inited        */ FALSE,
00975      /* initialize          */ NULL,
00976      /* initialize_hook            */ NULL,
00977      /* realize                    */ XtInheritRealize,
00978      /* actions                    */ NULL,
00979      /* num_actions         */ 0,
00980      /* resources           */ NULL,
00981      /* num_resources              */ 0,
00982      /* xrm_class           */ NULLQUARK,
00983      /* compress_motion            */ FALSE,
00984      /* compress_exposure   */ TRUE,
00985      /* compress_enterleave */ FALSE,
00986      /* visible_interest    */ FALSE,
00987      /* destroy                    */ NULL,
00988      /* resize                     */ XtInheritResize,
00989      /* expose                     */ XtInheritExpose,
00990      /* set_values          */ NULL,
00991      /* set_values_hook            */ NULL,
00992      /* set_values_almost   */ XtInheritSetValuesAlmost,
00993      /* get_values_hook            */ NULL,
00994      /* accept_focus        */ XtInheritAcceptFocus,
00995      /* version                    */ XtVersion,
00996      /* callback_offsets    */ NULL,
00997      /* tm_table            */ XtInheritTranslations,
00998      /* query_geometry             */ QueryGeometry,
00999      /* display_accelerator */ XtInheritDisplayAccelerator,
01000      /* extension           */ NULL
01001      }
01002 };
01003 
01004 #  define drawWidgetClass &drawingWidgetClass
01005 
01006 # endif /* NOQUERY */
01007 #endif /* not MOTIF */
01008 
01009 static int
01010 compare_strings(const void *s, const void *t)
01011 {
01012     const char **ss = (const char**)s;
01013     const char **tt = (const char**)t;
01014 
01015     return memicmp(*ss, *tt, strlen(*tt) + 1); /* also check for final 0 */
01016 }
01017 
01018 static void
01019 usage(int exitval)
01020 {
01021     XrmOptionDescRec *opt;
01022     const char **usageptr = usagestr;
01023     const char **sv = SUBST_VAL;
01024     const char *str1;
01025     const char *str2;
01026     const char *sorted_options[XtNumber(options)];
01027     char buf[256];
01028     char *s;
01029     int col, n;
01030     size_t nopt = 0, k;
01031     
01032     for (opt = options; opt < options + XtNumber(options); ++opt) {
01033        str1 = opt->option;
01034        if (*str1 != '-')
01035            continue;
01036 
01037        ASSERT(*usageptr != USAGESTR_END_MARKER, "Too few elements in usageptr[]");
01038 
01039        str2 = NULL;
01040        if (opt->argKind != XrmoptionNoArg) {
01041            str2 = *usageptr++;
01042            if (str2 == SILENT)
01043               continue;
01044            if (str2 == SUBST) {
01045               str1 = *sv++;
01046               str2 = NULL;
01047            }
01048        }
01049 #if 0
01050        fprintf(stderr, "str1: %s, str2: %s\n", str1, str2);
01051 #endif
01052        for (;;) {
01053            if (str2 == NULL)
01054               sprintf(buf, "[%.80s]", str1);
01055            else
01056               sprintf(buf, "[%.80s <%.80s>]", str1, str2);
01057 
01058 /*         fprintf(stderr, "number of options: %d; len of usagestr: %d\n", */
01059 /*                XtNumber(options), XtNumber(usagestr)); */
01060            ASSERT(nopt < XtNumber(options), "index out of range");
01061 /*         fprintf(stderr, "sorted: %d=%s\n", nopt, buf); */
01062            sorted_options[nopt++] = xstrdup(buf);
01063            
01064            if (**usageptr != '^' || strcmp(*usageptr + 1, opt->option) != 0)
01065               break;
01066            ++usageptr;
01067            str1 = *usageptr++;
01068            str2 = NULL;
01069        }
01070     }
01071 
01072     ASSERT(*usageptr == USAGESTR_END_MARKER, "Too many elements in usageptr[]");
01073 
01074 /*     fprintf(stderr, "elems in sorted options: %d\n", nopt); */
01075     qsort((void*)sorted_options,
01076          nopt,
01077          sizeof(sorted_options[0]),
01078          compare_strings);
01079     
01080     s = xstrdup("Usage: ");
01081     s = xstrcat(s, XDVI_PROGNAME); /* use `xdvi' here, not `xdvik' or `xdvi-xaw.bin' or ... */
01082     s = xstrcat(s, " [+[<page>]]");
01083 
01084     col = strlen(s);
01085     fputs(s, stdout);
01086     
01087     for (k = 0; k < nopt; ++k) {
01088        n = strlen(sorted_options[k]);
01089        if (col + n < 80)
01090            putc(' ', stdout);
01091        else {
01092            fputs("\n\t", stdout);
01093            col = 8 - 1;
01094        }
01095        fputs(sorted_options[k], stdout);
01096        col += n + 1;
01097     }
01098 
01099     /* put this in an extra line, to emphasize that it must come last */
01100     fputs("\n\t[dvi_file]\n", stdout);
01101 
01102     xdvi_exit(exitval);
01103 }
01104 
01105 int
01106 atopix(const char *arg, Boolean allow_minus)
01107 {
01108     int len = strlen(arg);
01109     const char *arg_end = arg;
01110     char tmp[11];
01111     double factor;
01112 
01113     if (allow_minus && *arg_end == '-')
01114        ++arg_end;
01115     while ((*arg_end >= '0' && *arg_end <= '9') || *arg_end == '.')
01116        if (arg_end >= arg + XtNumber(tmp) - 1)
01117            return 0;
01118        else
01119            ++arg_end;
01120     memcpy(tmp, arg, arg_end - arg);
01121     tmp[arg_end - arg] = '\0';
01122 
01123 #if A4
01124     factor = 1.0 / 2.54;    /* cm */
01125 #else
01126     factor = 1.0;    /* inches */
01127 #endif
01128     if (len > 2)
01129        switch (arg[len - 2] << 8 | arg[len - 1]) {
01130 #if A4
01131        case 'i' << 8 | 'n':
01132            factor = 1.0;
01133            break;
01134 #else
01135        case 'c' << 8 | 'm':
01136            factor = 1.0 / 2.54;
01137            break;
01138 #endif
01139        case 'm' << 8 | 'm':
01140            factor = 1.0 / 25.4;
01141            break;
01142        case 'p' << 8 | 't':
01143            factor = 1.0 / 72.27;
01144            break;
01145        case 'p' << 8 | 'c':
01146            factor = 12.0 / 72.27;
01147            break;
01148        case 'b' << 8 | 'p':
01149            factor = 1.0 / 72.0;
01150            break;
01151        case 'd' << 8 | 'd':
01152            factor = 1238.0 / 1157.0 / 72.27;
01153            break;
01154        case 'c' << 8 | 'c':
01155            factor = 12 * 1238.0 / 1157.0 / 72.27;
01156            break;
01157        case 's' << 8 | 'p':
01158            factor = 1.0 / 72.27 / 65536;
01159            break;
01160        }
01161 
01162     return factor * atof(tmp) * resource.pixels_per_inch + 0.5;
01163 }
01164 
01165 #if CHECK_APP_FILEVERSION
01166 static void
01167 check_app_defaults_fileversion(void)
01168 {
01169     /* update this when new essential resources are introduced */
01170     static const int required_version = 20030303;
01171     
01172     if (resource.app_defaults_fileversion < required_version) {
01173        const char *filename = kpse_find_file("XDvi", kpse_program_text_format, 0);
01174        if (filename == NULL)
01175            filename = "XDvi";
01176 
01177        fprintf(stderr, "filename: %d\n", resource.app_defaults_fileversion);
01178        popup_message(globals.widgets.top_level,
01179                     MSG_WARN,
01180                     NULL,
01181                     "Your application defaults file `%s' is outdated. "
01182                     "This version of xdvi requires a file "
01183                     "with date >= %d. Your file is older, or doesn't have a date.\n"
01184                     "Please obtain a new version of the file `XDvi', e.g. from:\n"
01185                     "http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/xdvi/xdvik/texk/xdvik/texmf/\n"
01186                     "and copy it to a directory in your $XDVIINPUTS path.",
01187                     filename, required_version);
01188     }
01189 }
01190 #endif
01191 
01192 
01193 static void
01194 warn_about_prerelease_versions(void)
01195 {
01196     int unstable_version = 0;
01197     if (strstr(XDVI_VERSION_INFO, "-cvs") != NULL)
01198        unstable_version = 1;
01199     else if (strstr(XDVI_VERSION_INFO, "-beta") != NULL)
01200        unstable_version = 2;
01201 
01202     if (unstable_version > 0) {
01203        printf("\n**********************************************************************\n");
01204        printf("%s version %s,\n%s version.\n\n", XDVIK_PROGNAME, XDVI_VERSION_INFO,
01205               unstable_version == 1 ? "an unstable development" : "a beta testing");
01206        printf("Want a stable version instead?\n"
01207               " -> please visit one of:\n"
01208               "    http://xdvi.sourceforge.net/cvs-upgrade.html\n"
01209               "    http://sourceforge.net/project/showfiles.php?group_id=23164\n\n"
01210               "Found a bug?\n"
01211               " -> please report it to:\n"
01212               "    http://sourceforge.net/tracker/?group_id=23164&atid=377580\n\n"
01213               "Thanks for your support!\n");
01214        printf("**********************************************************************\n");
01215     }
01216 }
01217 
01218 
01219 #ifdef GREY
01220 static Arg temp_args1[] = {
01221     {XtNdepth, (XtArgVal) 0},
01222     {XtNvisual, (XtArgVal) 0},
01223     {XtNcolormap, (XtArgVal) 0},
01224 };
01225 
01226 /*
01227  * Alternate routine to convert color name to Pixel (needed to substitute
01228  * "black" or "white" for BlackPixelOfScreen, etc., since a different visual
01229  * and colormap are in use).
01230  */
01231 
01232 static Boolean
01233 XdviCvtStringToPixel(Display *dpy,
01234                    XrmValuePtr args, Cardinal *num_args,
01235                    XrmValuePtr fromVal, XrmValuePtr toVal,
01236                    XtPointer *closure_ret)
01237 {
01238     XrmValue replacement_val;
01239     Boolean default_is_fg;
01240 
01241     if ((strcmp((String) fromVal->addr, XtDefaultForeground) == 0
01242         && (default_is_fg = True, True))
01243        || (strcmp((String) fromVal->addr, XtDefaultBackground) == 0
01244            && ((default_is_fg = False), True))) {
01245        replacement_val.size = sizeof(String);
01246        replacement_val.addr = (default_is_fg == resource.reverse)
01247            ? "white" : "black";
01248        fromVal = &replacement_val;
01249     }
01250 
01251     return XtCvtStringToPixel(dpy, args, num_args, fromVal, toVal, closure_ret);
01252 }
01253 
01254 /*
01255  * Convert string to yes/no/maybe.  Adapted from the X toolkit.
01256  */
01257 
01258 static Boolean
01259 XdviCvtStringToBool3(Display *dpy,
01260                    XrmValuePtr args, Cardinal *num_args,
01261                    XrmValuePtr fromVal, XrmValuePtr toVal,
01262                    XtPointer *closure_ret)
01263 {
01264     String str = (String) fromVal->addr;
01265     static Bool3 value;
01266 
01267     UNUSED(args);
01268     UNUSED(num_args);
01269     UNUSED(closure_ret);
01270     
01271     if (memicmp(str, "true", 5) == 0
01272        || memicmp(str, "yes", 4) == 0
01273        || memicmp(str, "on", 3) == 0 || memicmp(str, "1", 2) == 0)
01274        value = True;
01275 
01276     else if (memicmp(str, "false", 6) == 0
01277             || memicmp(str, "no", 3) == 0
01278             || memicmp(str, "off", 4) == 0 || memicmp(str, "0", 2) == 0)
01279        value = False;
01280 
01281     else if (memicmp(str, "maybe", 6) == 0)
01282        value = Maybe;
01283 
01284     else {
01285        XtDisplayStringConversionWarning(dpy, str, XtRBoolean);
01286        return False;
01287     }
01288 
01289     if (toVal->addr != NULL) {
01290        if (toVal->size < sizeof(Bool3)) {
01291            toVal->size = sizeof(Bool3);
01292            return False;
01293        }
01294        *(Bool3 *) (toVal->addr) = value;
01295     }
01296     else
01297        toVal->addr = (XPointer) & value;
01298 
01299     toVal->size = sizeof(Bool3);
01300     return True;
01301 }
01302 
01303 #endif
01304 
01305 
01306 /*
01307  * Set the `sourceposition' propery of the window `w' to `source_str'.
01308  * This is usually done in `client' mode to notify the instance of
01309  * xdvi running in window `w' to start a forward search. After this,
01310  * the client usually exits normally.
01311  */
01312 static void
01313 set_sourceposition_property(const char *source_str, Window win)
01314 {
01315     /* parse the special in order to expand the filename */
01316     struct src_parsed_special data;
01317     char *new_special = NULL;
01318     char *expanded_filename = NULL;
01319            
01320     data.filename_len = 0;
01321     data.filename = NULL;
01322            
01323     src_parse(source_str, strlen(source_str), &data);
01324 
01325     if (data.filename_len == 0) {
01326        /* can't give a GUI warning in `client' mode - just exit with error */
01327        XDVI_FATAL((stderr,
01328                   "Filename missing in -sourceposition argument (%s)!",
01329                   source_str));
01330     }
01331            
01332     TRACE_CLIENT((stderr, "got data: line %d, col %d, file |%s|, len %lu\n",
01333                 data.line, data.col, data.filename, (unsigned long)data.filename_len));
01334 
01335     /* expand -sourceposition argument if it contains a path component.
01336        We don't use REALPATH here, because `tex -src' doesn't expand
01337        symlinks either. Instead, use canonicalize_path() to expand
01338        `../' and './' manually. */
01339     if (strchr(data.filename, '/') != NULL
01340        && (expanded_filename = expand_filename(data.filename, USE_CWD_PATH)) != NULL) {
01341        char *tmp = canonicalize_path(expanded_filename);
01342        free(data.filename);
01343        free(expanded_filename);
01344        expanded_filename = tmp;           
01345     }
01346     else
01347        expanded_filename = data.filename;
01348            
01349     TRACE_CLIENT((stderr, "expanded1: |%s|\n", expanded_filename));
01350 
01351     new_special = xmalloc(2 * LENGTH_OF_INT + 2 /* 2 for `:' and separating space */
01352                        + strlen(expanded_filename) + 1);
01353     sprintf(new_special, "%d:%d %s", data.line, data.col, expanded_filename);
01354     free(expanded_filename);                              
01355                               
01356     TRACE_CLIENT((stderr, "matched!"));
01357     set_string_property(new_special, atom_src_goto(), win);
01358     free(new_special);
01359     set_string_property("", atom_raise(), win);
01360 }
01361 
01362 static void
01363 set_stringsearch_property(const char *str, Window win)
01364 {
01365     set_string_property(str, atom_find_string(), win);
01366     set_string_property("", atom_raise(), win);
01367 }
01368 
01369 
01370 
01371 /* Translation of valid paper types to dimensions,
01372    which are used internally. The newline characters are a hack
01373    to format the list neatly for error messages.
01374    A* series measures are taken from
01375    http://www.cl.cam.ac.uk/~mgk25/iso-paper.html
01376 */
01377 static const char *paper_types[] = {
01378     "us", "8.5x11in",
01379     "letter", "8.5x11in",   /* dvips compatibility */
01380     "ledger", "17x11in",    /* dvips compatibility */
01381     "tabloid", "11x17in",   /* dvips compatibility */
01382     "usr", "11x8.5in",
01383     "legal", "8.5x14in",
01384     "legalr", "14x8.5in",
01385     "foolscap", "13.5x17.0in",     /* ??? */
01386     "foolscapr", "17.0x13.5in",
01387     "", "0",
01388 
01389     /* ISO `A' formats, Portrait */
01390     "a0", "841x1189mm",
01391     "a1", "594x841mm",
01392     "a2", "420x594mm",
01393     "a3", "297x420mm",
01394     "a4", "210x297mm",
01395     "a5", "148x210mm",
01396     "a6", "105x148mm",
01397     "a7", "74x105mm",
01398     "a8", "52x74mm",
01399     "a9", "37x52mm",
01400     "a10","26x37mm",
01401     "", "0",
01402 
01403     /* ISO `A' formats, Landscape */
01404     "a0r", "1189x841mm",
01405     "a1r", "841x594mm",
01406     "a2r", "594x420mm",
01407     "a3r", "420x297mm",
01408     "a4r", "297x210mm",
01409     "a5r", "210x148mm",
01410     "a6r", "148x105mm",
01411     "a7r", "105x74mm",
01412     "a8r", "74x52mm",
01413     "a9r", "52x37mm",
01414     "a10r","37x26mm",
01415     "", "0",
01416 
01417     /* ISO `B' formats, Portrait */
01418     "b0", "1000x1414mm",
01419     "b1", "707x1000mm",
01420     "b2", "500x707mm",
01421     "b3", "353x500mm",
01422     "b4", "250x353mm",
01423     "b5", "176x250mm",
01424     "b6", "125x176mm",
01425     "b7", "88x125mm",
01426     "b8", "62x88mm",
01427     "b9", "44x62mm",
01428     "b10","31x44mm",
01429     "", "0",
01430 
01431     /* ISO `B' formats, Landscape */
01432     "b0r", "1414x1000mm",
01433     "b1r", "1000x707mm",
01434     "b2r", "707x500mm",
01435     "b3r", "500x353mm",
01436     "b4r", "353x250mm",
01437     "b5r", "250x176mm",
01438     "b6r", "176x125mm",
01439     "b7r", "125x88mm",
01440     "b8r", "88x62mm",
01441     "b9r", "62x44mm",
01442     "b10r","44x31mm",
01443     "", "0",
01444 
01445     /* ISO `C' formats, Portrait */
01446     "c0", "917x1297mm",
01447     "c1", "648x917mm",
01448     "c2", "458x648mm",
01449     "c3", "324x458mm",
01450     "c4", "229x324mm",
01451     "c5", "162x229mm",
01452     "c6", "114x162mm",
01453     "c7", "81x114mm",
01454     "c8", "57x81mm",
01455     "c9", "40x57mm",
01456     "c10","28x40mm",
01457     "", "0",
01458 
01459     /* ISO `C' formats, Landscape */
01460     "c0r", "1297x917mm",
01461     "c1r", "917x648mm",
01462     "c2r", "648x458mm",
01463     "c3r", "458x324mm",
01464     "c4r", "324x229mm",
01465     "c5r", "229x162mm",
01466     "c6r", "162x114mm",
01467     "c7r", "114x81mm",
01468     "c8r", "81x57mm",
01469     "c9r", "57x40mm",
01470     "c10r","40x28mm",
01471 };
01472 
01473 /* access methods for paper_types */
01474 const char **get_paper_types(void) {
01475     return paper_types;
01476 }
01477 
01478 size_t get_paper_types_size(void) {
01479     return XtNumber(paper_types);
01480 }
01481 
01482 /* Set the icon name and title name standard properties on `globals.widgets.top_level'.
01483  * We use the basename of the DVI file (without the .dvi), so different xdvi
01484  * invocations can be distinguished, yet do not use up too much real estate.
01485  *
01486  * This function returns freshly allocated memory in *icon_name and *title_name
01487  * which the caller is responsible for free()ing again.
01488  */
01489 void
01490 get_icon_and_title(const char *filename, char **icon_name, char **title_name)
01491 {
01492     /* Use basename of DVI file for name in icon and title.  */
01493     const char *ptr;
01494     char *ptr2;
01495 
01496     /* SU 2000/12/16: added page number information */
01497     const char *const title_name_fmt = "%s:  %s   (%d page%s)";
01498 
01499     MYTRACE((stderr, "get_icon_and_title called with: |%s|", filename));
01500 
01501     ptr = strrchr(filename, '/');
01502     if (ptr != NULL)
01503        ++ptr;
01504     else {
01505        ptr = filename;
01506     }
01507         
01508     /*
01509      * Remove the `file:' prefix from the icon name; since some windowmanagers
01510      * only display a prefix in window lists etc., it's more significant this
01511      * way.
01512      */
01513 
01514     if (memcmp(ptr, "file:", 5) == 0) {
01515        ptr += 5;
01516     }
01517     *icon_name = xstrdup(ptr);
01518     
01519     MYTRACE((stderr, "before chopping: icon_name: |%s|", *icon_name));
01520     if ((ptr2 = strstr(*icon_name, ".dvi")) != NULL) {
01521        /* chop off .dvi extension */
01522        *ptr2 = '\0';
01523     }
01524     MYTRACE((stderr, "after chopping: icon_name: |%s|", *icon_name));
01525 
01526     *title_name = xmalloc(strlen(title_name_fmt)
01527                        + strlen(XDVIK_PROGNAME)
01528                        + strlen(*icon_name)
01529                        + LENGTH_OF_INT
01530                        + 2);       /* 2 for additional plural `s' */
01531     MYTRACE((stderr, "total_pages: %d", total_pages));
01532     sprintf(*title_name, title_name_fmt, XDVIK_PROGNAME, *icon_name, total_pages,
01533            (total_pages > 1) ? "s" : "");
01534 
01535     MYTRACE((stderr, "title_name, icon_name: |%s|%s|", *title_name, *icon_name));
01536 }
01537 
01538 void
01539 set_icon_and_title(const char *icon_name, const char *title_name)
01540 {
01541     if (!XtIsRealized(globals.widgets.top_level)) {
01542        MYTRACE((stderr, "set_icon_and_title: returning"));
01543        return;
01544     }
01545     XtVaSetValues(globals.widgets.top_level, XtNtitle, (XtArgVal) title_name, XtNiconName, (XtArgVal) icon_name, NULL);
01546     XSetStandardProperties(DISP, XtWindow(globals.widgets.top_level), title_name, icon_name,
01547                         (Pixmap) 0, NULL, 0, NULL);
01548 }
01549 
01550 static void
01551 display_version_info(void)
01552 {
01553     printf("%s version %s ", XDVIK_PROGNAME, XDVI_VERSION);
01554 #ifdef MOTIF
01555     printf("(%s, runtime version %d.%d)\n",
01556           /*     XmVERSION, XmREVISION, XmUPDATE_LEVEL, */
01557           XmVERSION_STRING,
01558           xmUseVersion / 1000, xmUseVersion % 1000);
01559 #else
01560     printf("%s\n", XDVI_GUI);
01561 #endif
01562     printf("Libraries: %s, T1lib version %s\n", kpathsea_version_string, T1LIB_VERSIONSTRING);
01563 }
01564 
01565 static void
01566 display_bug_reporting_info(void)
01567 {
01568     printf("Please send bug reports, feature requests etc. to one of:\n"
01569           "   http://sourceforge.net/tracker/?group_id=23164&atid=377580\n"
01570           "   tex-k@tug.org (http://tug.org/mailman/listinfo/tex-k)\n\n"
01571           "\n");
01572 }
01573 
01574 static void
01575 display_licensing_info(void)
01576 {
01577     fputs("Licenses: X Consortium license, GNU Library General Public\n"
01578          "License, GNU General Public License (use option `-license'\n"
01579          "for more details). There is NO WARRANTY of anything.\n\n", stdout);
01580 }
01581 
01582 static void
01583 display_long_licensing_info(void)
01584 {
01585     fputs("The major parts of Xdvik are licensed under the X Consortium license.\n"
01586          "Parts (encoding.c) are licensed under the GNU General Public License.\n"
01587          "Xdvik uses the following libraries:\n"
01588          "- The kpathsea library, licensed in part under the GNU General Public\n"
01589          "  License, in part under the GNU Library General Public License.\n"
01590          "- t1lib, licensed in parts under the GNU Library General Public License,\n"
01591          "  in parts under the X Consortium license.\n"
01592          "There is NO WARRANTY of anything.\n\n", stdout);
01593 }
01594 
01595 static void
01596 get_window_constraints(XtWidgetGeometry *reply,
01597                      Dimension screen_w, Dimension screen_h,
01598                      int add_h)
01599 {
01600     XtWidgetGeometry constraints;
01601 
01602     constraints.request_mode = reply->request_mode = 0;
01603 
01604     /*               fprintf(stderr, "setting constraints.width to %d\n", globals.page.w); */
01605     constraints.width = globals.page.w;
01606     if (globals.page.w > screen_w) {
01607        /*            fprintf(stderr, "setting CWWidth constraint\n"); */
01608        constraints.request_mode |= CWWidth;
01609        constraints.width = screen_w;
01610     }
01611 
01612     /*            fprintf(stderr, "setting constraints.height to %d\n", globals.page.h + global_statusline_h); */
01613     constraints.height = globals.page.h + global_statusline_h;
01614     if (constraints.height > screen_h) {
01615        /*            fprintf(stderr, "setting CWHeight constraint\n"); */
01616        constraints.request_mode |= CWHeight;
01617        /* if window too large, need to subtract height of toolbar etc. again */
01618        constraints.height = screen_h - add_h;
01619     }
01620 
01621     if (constraints.request_mode != 0
01622        && constraints.request_mode != (CWWidth | CWHeight)) {
01623 #ifdef MOTIF
01624        (void)XtQueryGeometry(globals.widgets.main_window, &constraints, reply);
01625 #else
01626        (void)XtQueryGeometry(globals.widgets.vport_widget, &constraints, reply);
01627 #endif
01628     }
01629     if (!(reply->request_mode & CWWidth))
01630        reply->width = constraints.width;
01631     if (reply->width >= screen_w)
01632        reply->width = screen_w;
01633     if (!(reply->request_mode & CWHeight))
01634        reply->height = constraints.height;
01635     if (reply->height >= screen_h)
01636        reply->height = screen_h;
01637     /*               fprintf(stderr, "width now: %d\n", reply.width); */
01638 
01639 }
01640 
01641 void
01642 set_windowsize(Dimension *ret_w, Dimension *ret_h, int add_w, int add_h, Boolean override)
01643 {
01644     static Arg set_wh_args[] = {
01645        {XtNwidth, (XtArgVal) 0},
01646        {XtNheight, (XtArgVal) 0},
01647     };
01648     Dimension screen_w, screen_h;
01649 
01650     const char *test_geometry = resource.geometry;
01651     
01652     if (resource.fullscreen) {
01653        Dimension w = WidthOfScreen(SCRN), h = HeightOfScreen(SCRN);
01654 
01655        if (currwin.shrinkfactor == 0) { /* if not set by user */
01656            Dimension height_factor = ROUNDUP(globals.page.unshrunk_h, h);
01657            currwin.shrinkfactor = ROUNDUP(globals.page.unshrunk_w, w);
01658            if (height_factor >= currwin.shrinkfactor)
01659               currwin.shrinkfactor = height_factor;
01660 /*         fprintf(stderr, "factor was 0, using %d\n", currwin.shrinkfactor); */
01661        }
01662 /*     else */
01663 /*         fprintf(stderr, "factor != 0, using %d\n", currwin.shrinkfactor); */
01664 
01665        mane.shrinkfactor = currwin.shrinkfactor;
01666        init_page();
01667        set_wh_args[0].value = (XtArgVal)w;
01668        set_wh_args[1].value = (XtArgVal)h;
01669        *ret_w = w;
01670        *ret_h = h;
01671 #ifdef MOTIF
01672 #if USE_XAW_PANNER
01673        XtVaGetValues(globals.widgets.main_window, XmNshadowThickness, &g_save_shadow_thickness, NULL);
01674 #endif
01675        XtVaSetValues(globals.widgets.main_window, XmNshadowThickness, 0, NULL);
01676 #endif
01677        XtSetValues(globals.widgets.top_level, set_wh_args, XtNumber(set_wh_args));
01678     }
01679     else if (override) {
01680        set_wh_args[0].value = (XtArgVal)*ret_w;
01681        set_wh_args[1].value = (XtArgVal)*ret_h;
01682        XtSetValues(globals.widgets.top_level, set_wh_args, XtNumber(set_wh_args));
01683     }
01684     else { /* determine a window size that fits the current shrink factor */
01685        Arg temp_args3 = { XtNborderWidth, (XtArgVal)&bwidth };
01686        XtWidgetGeometry reply;
01687        
01688        XtGetValues(globals.widgets.top_level, &temp_args3, 1); /* get border width */
01689        screen_w = WidthOfScreen(SCRN) - 2 * bwidth;
01690 
01691        screen_w -= add_w;
01692        screen_h = HeightOfScreen(SCRN) - 2 * bwidth - global_statusline_h - 6;
01693        for (;;) {    /* actually, at most two passes */
01694            Dimension height_factor;
01695 
01696            TRACE_GUI((stderr, "geometry: |%s|; remember: %d, windowsize: %s",
01697                      resource.geometry ? resource.geometry : "<NULL>",
01698                      resource.remember_windowsize,
01699                      resource.windowsize ? resource.windowsize : "<NULL>"));
01700            
01701            if (resource.geometry == NULL && !resource.remember_windowsize) {
01702               /* geometry not set by user, try to find geometry that fits the shrink factor */
01703               get_window_constraints(&reply, screen_w, screen_h, add_h);
01704            }
01705            else {
01706               int x, y;
01707               unsigned int width, height;
01708               int flags;
01709 
01710               if (resource.remember_windowsize && resource.windowsize != NULL)
01711                   test_geometry = resource.windowsize;
01712               else
01713                   test_geometry = resource.geometry;
01714               flags = XParseGeometry(test_geometry, &x, &y, &width, &height);
01715 
01716               if (!(flags & WidthValue) || !(flags & HeightValue)) {
01717                   /* no geometry specified, use fallback */
01718                   get_window_constraints(&reply, screen_w, screen_h, add_h);
01719               }
01720 
01721               /* warn about bad values */
01722               if (flags & WidthValue) {
01723                   if (width > (unsigned int)(2 * bwidth + add_w)) {
01724                      TRACE_FILES((stderr, "width: %hu, bwidth: %hu, add_w: %d",
01725                                  width, bwidth, add_w));
01726                      reply.width = width - 2 * bwidth - add_w;
01727                   }
01728                   else {
01729                      reply.width = width;
01730                   }
01731               }
01732               if (flags & HeightValue) {
01733                   if (height > (unsigned int)(2 * bwidth + add_h)) {
01734                      TRACE_FILES((stderr, "height: %hu, bwidth: %hu, add_h: %d",
01735                                  height, bwidth, add_h));
01736                      reply.height = height - 2 * bwidth - add_h;
01737                   }
01738                   else {
01739                      reply.height = height;
01740                   }
01741               }
01742               TRACE_FILES((stderr, "setting geometry: %dx%d", (int)reply.width, (int)reply.height));
01743            }
01744            
01745            /* now reply.{width,height} contain max. usable window size */
01746 
01747            /* User didn't use `-s 0', use either default or other user-specified value */
01748            if (currwin.shrinkfactor != 0) {
01749 /*            fprintf(stderr, "factor != 0, using %d\n", currwin.shrinkfactor); */
01750               break;
01751            }
01752 /*         else { */
01753 /*            fprintf(stderr, "factor was 0, using %d\n", currwin.shrinkfactor); */
01754 /*         } */
01755 
01756            /* else, try to find a suitable shrink factor: */
01757            currwin.shrinkfactor = ROUNDUP(globals.page.unshrunk_w, reply.width - 2);
01758 /*         fprintf(stderr, "factor w: %d\n", currwin.shrinkfactor); */
01759            
01760            height_factor = ROUNDUP(globals.page.unshrunk_h, reply.height - 2);
01761 /*         fprintf(stderr, "factor h: %d\n", height_factor); */
01762            if (height_factor >= currwin.shrinkfactor)
01763               currwin.shrinkfactor = height_factor;
01764 
01765 /*         fprintf(stderr, "factor now is: %d\n", currwin.shrinkfactor); */
01766            
01767            mane.shrinkfactor = currwin.shrinkfactor;
01768            init_page();
01769            set_wh_args[0].value = (XtArgVal)globals.page.w;
01770            set_wh_args[1].value = (XtArgVal)globals.page.h;
01771            *ret_w = globals.page.w;
01772            *ret_h = globals.page.h;
01773            XtSetValues(globals.widgets.draw_widget, set_wh_args, XtNumber(set_wh_args));
01774        }
01775 #ifdef MOTIF
01776        /*
01777          SU 2002/11/23: Added scrollbar width to height computation.
01778          Otherwise, when the vertical space isn't sufficient, a
01779          vertical scrollbar will be added, but since this makes the
01780          display narrower, a horizontal scrollbar will be added as
01781          well, even if this wouldn't be neccessary.
01782 
01783          SU 2003/09/30: Apparently the size computation works now, even
01784          though I'm not sure why (scrollbar value isn't in add_w). Investigate.
01785        */
01786        /* HACK ALERT: 4 for window decoration borders - FIXME: get actual values?? */
01787        set_wh_args[0].value = reply.width + add_w + (test_geometry == NULL ? 4 : 0);
01788        set_wh_args[1].value = reply.height + add_h - (test_geometry == NULL ? 4 : 0);
01789        XtSetValues(globals.widgets.top_level, set_wh_args, XtNumber(set_wh_args));
01790 
01791 #else /* MOTIF */
01792 
01793        set_wh_args[0].value = reply.width + add_w + (test_geometry == NULL ? 15 : (2 * bwidth));
01794        /*
01795          FIXME: use real height of statusline here
01796          Somehow I didn't manage to use XtVaCreateWidget in a call to
01797          create_statusline() above, and XtManageChild() below.
01798          In that case, we could do without global_statusline_h.
01799         */
01800        set_wh_args[1].value = reply.height + (test_geometry == NULL ? (2 * bwidth + add_h) : 0);
01801        XtSetValues(globals.widgets.top_level, set_wh_args, XtNumber(set_wh_args));
01802        set_wh_args[0].value -= add_w;
01803        XtSetValues(globals.widgets.vport_widget, set_wh_args, XtNumber(set_wh_args));
01804 
01805 #endif /* MOTIF */
01806        *ret_w = set_wh_args[0].value;
01807        *ret_h = set_wh_args[1].value;
01808        TRACE_FILES((stderr, "returning: w=%d, h=%d", *ret_w, *ret_h));
01809     }
01810 }
01811 
01812 static void
01813 net_wm_toggle_fullscreen(int flag)
01814 {
01815     Atom NET_WM_FULLSCREEN = XInternAtom(DISP, "_NET_WM_STATE_FULLSCREEN", True);
01816 
01817     if (NET_WM_FULLSCREEN) {
01818        XEvent ev;
01819        Atom NET_WM_STATE = XInternAtom(DISP, "_NET_WM_STATE", False);
01820 
01821 /*     XDVI_INFO((stdout, "trying _NET_WM_STATE_FULLSCREEN ...")); */
01822 
01823        ev.type = ClientMessage;
01824        ev.xclient.serial = 0;
01825        ev.xclient.send_event = True;
01826        ev.xclient.display = DISP;
01827        ev.xclient.window = XtWindow(globals.widgets.top_level);
01828        ev.xclient.message_type = NET_WM_STATE;
01829        ev.xclient.format = 32;
01830        ev.xclient.data.l[0] = flag; /* _NET_WM_STATE_REMOVE (0) or _NET_WM_STATE_ADD (1) */
01831        ev.xclient.data.l[1] = NET_WM_FULLSCREEN;
01832        ev.xclient.data.l[2] = 0L;
01833        
01834        XSendEvent(DISP, DefaultRootWindow(DISP), False,
01835                  SubstructureNotifyMask, &ev);
01836     }
01837     else {
01838        XDVI_INFO((stdout, "_NET_WM_STATE_FULLSCREEN not supported by this window manager."));
01839     }
01840 }
01841 
01842 void
01843 reconfigure_window(Boolean fullscreen, Dimension width, Dimension height,
01844                   Boolean save_position)
01845 {
01846     static int x_old = 5, y_old = 15;
01847 #ifdef SIZECONFIGURE_WORKS
01848     int sizeconfiguremask;
01849     XWindowChanges sizeconfigure;
01850 #endif /* SIZECONFIGURE_WORKS */
01851 #ifdef MOTIF
01852     static int save_wm_decorations;
01853 #else
01854     static struct PropMotifWmHints MWMHints = {MWM_HINTS_DECORATIONS, 0, 0, 0, 0};
01855     Atom WM_HINTS = XInternAtom(DISP, "_MOTIF_WM_HINTS", True);
01856 #endif
01857     int x, y;
01858 
01859 #ifdef SIZECONFIGURE_WORKS
01860     sizeconfiguremask = CWX | CWY | CWWidth | CWHeight | CWBorderWidth;
01861     sizeconfigure.width = width;
01862     sizeconfigure.height = height;
01863 #endif /* SIZECONFIGURE_WORKS */
01864     
01865     if (fullscreen) {
01866 #if 0
01867        static Boolean first_time = True;
01868        /* offsets between the raw window and the decorated window */
01869        static int wm_x_offset = 0;
01870        static int wm_y_offset = 0;
01871 #endif
01872        Window dummy;
01873 
01874 #ifdef SIZECONFIGURE_WORKS
01875        sizeconfigure.x = 0;
01876        sizeconfigure.y = 0;
01877        sizeconfigure.border_width = 0;
01878 #endif /* SIZECONFIGURE_WORKS */
01879        
01880        /* Note ZLB: avoid to call XTranslateCoordinates if the window is
01881           not yet mapped since XTranslateCoordinates implicitly maps the
01882           window (note: calling the function XGetWindowAttributes also
01883           makes the window mapped).
01884 
01885           This effectively eliminates the flashing effect when xdvik is
01886           started in fullscreen mode for the Motif version. For the Xaw
01887           version we still get flashing effect (seems that the window is
01888           already mapped). */
01889 
01890         if (save_position) {
01891           /* save current window coordinates so that we can change them back */
01892            (void)XTranslateCoordinates(DISP, XtWindow(globals.widgets.top_level),
01893                                    RootWindowOfScreen(SCRN),
01894                                    0, 0,
01895                                    &x_old, &y_old,
01896                                    &dummy);
01897 #if 0
01898             if (first_time) {
01899               first_time = False;
01900               /* This is a hack for finding out wm_x_offset, wm_y_offset */
01901               XMoveWindow(DISP, XtWindow(globals.widgets.top_level), 0, 0);
01902               XSync(DISP, False);
01903               (void)XTranslateCoordinates(DISP, XtWindow(globals.widgets.top_level),
01904                                    RootWindowOfScreen(SCRN),
01905                                    0, 0, &wm_x_offset, &wm_y_offset,
01906                                    &dummy);
01907               fprintf(stderr, "wm offset = (%d,%d)\n",
01908                      wm_x_offset, wm_y_offset);
01909            }
01910            x_old -= wm_x_offset;
01911            y_old -= wm_y_offset;
01912 #endif
01913         }
01914 
01915        x = y = 0;
01916 
01917 #ifdef MOTIF
01918        XtVaGetValues(globals.widgets.top_level, XmNmwmDecorations, &save_wm_decorations, NULL);
01919        /* FIXME: this doesn't work e.g. with KDE */
01920        XtVaSetValues(globals.widgets.top_level,
01921                     XmNmwmDecorations, 0,
01922                     XmNgeometry, "+0+0",
01923                     NULL);
01924        XtVaSetValues(globals.widgets.main_window, XmNshadowThickness, 0, NULL);
01925 #else
01926        MWMHints.decorations = 0;
01927        if (WM_HINTS != None) {
01928            XChangeProperty(DISP, XtWindow(globals.widgets.top_level),
01929                          WM_HINTS, WM_HINTS, 32,
01930                          PropModeReplace, (unsigned char *)&MWMHints,
01931                          sizeof(MWMHints) / 4);
01932        }
01933 #endif
01934        /* SU: apparently some new standard that is supposed to work
01935           with some WMs ... but it doesn't with my versions of Gnome and KDE. */
01936        net_wm_toggle_fullscreen(1);
01937 
01938 #ifdef SIZECONFIGURE_WORKS
01939        XConfigureWindow(DISP, XtWindow(globals.widgets.top_level), sizeconfiguremask, &sizeconfigure);
01940 #endif /* SIZECONFIGURE_WORKS */
01941     }
01942     else {
01943 #ifdef SIZECONFIGURE_WORKS
01944        sizeconfiguremask = CWWidth | CWHeight | CWX | CWY;
01945        sizeconfigure.x = x_old;
01946        sizeconfigure.y = y_old;
01947        sizeconfigure.border_width = 20;
01948 #endif /* SIZECONFIGURE_WORKS */
01949        XtVaSetValues(globals.widgets.top_level, XtNx, x_old, XtNy, y_old, NULL);
01950 #ifdef MOTIF
01951        XtVaSetValues(globals.widgets.top_level, XmNmwmDecorations, save_wm_decorations, NULL);
01952 #if USE_XAW_PANNER
01953        XtVaSetValues(globals.widgets.main_window, XmNshadowThickness, g_save_shadow_thickness, NULL);
01954 #endif
01955 #else
01956        MWMHints.decorations = MWM_DECOR_ALL;
01957        if (WM_HINTS != None) {
01958            XChangeProperty(DISP, XtWindow(globals.widgets.top_level),
01959                          WM_HINTS, WM_HINTS, 32,
01960                          PropModeReplace, (unsigned char *)&MWMHints,
01961                          sizeof(MWMHints) / 4);
01962        }
01963 #endif
01964        net_wm_toggle_fullscreen(0);
01965 
01966        x = x_old;
01967        y = y_old;
01968     }
01969 
01970 #if 1
01971 #if 0
01972     XUnmapWindow(DISP, XtWindow(globals.widgets.top_level));
01973 #else
01974     XWithdrawWindow(DISP, XtWindow(globals.widgets.top_level), XScreenNumberOfScreen(SCRN));
01975 #endif
01976 
01977     /* Note ZLB: Placing XResizeWindow before XUnmapWindow or after XMapWindow
01978        makes the fullscreen window size smaller than the screen size when
01979        using `mwm' of Lesstif */
01980     XSetWindowBorderWidth(DISP, XtWindow(globals.widgets.top_level), 0);
01981     XResizeWindow(DISP, XtWindow(globals.widgets.top_level), width, height);
01982 
01983     XMapRaised(DISP, XtWindow(globals.widgets.top_level));
01984 
01985     /* Note ZLB: XMapWindow might change the window position with some WMs
01986        (like Sawfish), so we place the window position after it's mapped. */
01987     XMoveWindow(DISP, XtWindow(globals.widgets.top_level), x, y);
01988 #endif /* 0 */
01989 
01990     /* need to redraw the page to avoid artifacts */
01991     globals.ev.flags |= EV_NEWPAGE;
01992     XFlush(DISP);
01993 }
01994 
01995 /*
01996   a custom error handler that makes it easier to catch X errors in the debugger
01997   (by setting a breakpoint to this function, plus using the -sync option).
01998   There was an X error reported by Svend Tollak Munkejord when running remotly
01999   on OSF1/V5.1 alpha with display on SuSE 9.1, after selecting some text with the
02000   mouse and releasing the mouse button, which I couldn't track down:
02001 
02002   X Error of failed request:  BadValue (integer parameter out of range for operation)
02003     Major opcode of failed request:  18 (X_ChangeProperty)
02004     Value in failed request:  0x40
02005     Serial number of failed request:  518
02006     Current serial number in output stream:  519
02007 
02008   From the trace:
02009     
02010   signal IOT/Abort trap at >*[__kill, 0x3ff800e8908]      beq     a3, 0x3ff800e8920
02011   (dbx) where
02012   >  0 __kill(0x0, 0x5, 0x3ff00000000, 0x11fffb188, 0x3ff801a9c14) [0x3ff800e8908]
02013      1 (unknown)() [0x3ff801ee108]
02014      2 __tis_raise(0x3ff801a9c14, 0x11fffb620, 0x3ff801229d8, 0x3ff00000006, 0x3ff801869b4) [0x3ff801229d4]
02015      3 raise(0x3ff801229d8, 0x3ff00000006, 0x3ff801869b4, 0x0, 0x3ff801a9c44) [0x3ff801869b0]
02016      4 abort(0x12006f858, 0x406f28ae75776627, 0x0, 0x0, 0x100000000) [0x3ff801a9c40]
02017      5 do_abort() ["util.c":442, 0x12006f854]
02018      6 x_error_handler(display = 0x140088800, error = 0x11fffb620) ["xdvi.c":1972, 0x1200764c8]
02019      7 (unknown)() [0x3ff8086caf0]
02020      8 _XError(0x11fffb758, 0x0, 0x36c, 0x24, 0x20) [0x3ff8044f7f0]
02021      9 _XReply(0x0, 0x3, 0x0, 0x11fffba40, 0x100000000) [0x3ff8044cec8]
02022     10 XSync(0x14019ea40, 0x40036b0200, 0x19170b000120000, 0x12, 0x43197900000000) [0x3ff80444910]
02023     11 _XSyncFunction(0x19170b000120000, 0x12, 0x43197900000000, 0x0, 0x3ff80408994) [0x3ff804449f0]
02024     12 XChangeProperty(0x3ff8086c9c0, 0x0, 0x2c, 0xb6, 0x4) [0x3ff80408990]
02025     13 (unknown)() [0x3ff8086d2d0]
02026     14 (unknown)() [0x3ff8086d654]
02027     15 XtDispatchEventToWidget(0x3ff80852834, 0x11fffbde8, 0x3ff80852974, 0x11fffbde8, 0x0) [0x3ff80852060]
02028     16 (unknown)() [0x3ff80852990]
02029     17 XtDispatchEvent(0x801, 0x4, 0x11fffc018, 0x0, 0x100000000) [0x3ff80852fb0]
02030     18 read_events(ret_mask = 131070) ["events.c":5048, 0x120046fa4]
02031     19 do_pages() ["events.c":5290, 0x120047e58]
02032     20 run_dvi_file(filename = 0x14005f370 = "/auto/home/vsl175/a/svendm/latex/a.dvi", data = 0x14005f778)
02033        ["xdvi.c":3852, 0x12007a5e8]
02034     21 main(argc = 2, argv = 0x11fffc018) ["xdvi.c":4231, 0x12007b780]
02035 
02036     Since it seemed to work regardless of this error, I decided to enable the custom
02037     error handler by default, at least until we've figured this problem out.
02038 */ 
02039 static int
02040 x_error_handler(Display *display, XErrorEvent *error)
02041 {
02042     char buf[1024], req_buf[1024];
02043 
02044     if (error->request_code < 128) {
02045        char num[LENGTH_OF_INT];
02046        sprintf(num, "%d", error->request_code);
02047        XGetErrorDatabaseText(display, "XRequest", num, "", req_buf, 1024);
02048     }
02049     else {
02050        req_buf[0] = '\0';
02051     }
02052     
02053     XGetErrorText(display, error->error_code, buf, sizeof buf);
02054     /*     XtCloseDisplay(DISP); */
02055     if (error->error_code == BadWindow
02056        || error->error_code == BadPixmap
02057        || error->error_code == BadCursor
02058        || error->error_code == BadFont
02059        || error->error_code == BadDrawable
02060        || error->error_code == BadColor
02061        || error->error_code == BadGC
02062        || error->error_code == BadIDChoice
02063        || error->error_code == BadValue
02064        || error->error_code == BadAtom) {
02065        XDVI_WARNING((stderr, "X protocol error: %s\n    X Request %d (%s), Value=0x%x.",
02066                 buf, error->request_code, req_buf, (unsigned int)error->resourceid));
02067     }
02068     else {
02069        XDVI_WARNING((stderr, "X protocol error: %s\n    X Request %d (%s).",
02070                     buf, error->request_code, req_buf));
02071     }
02072     return 0;
02073 }
02074 
02075 
02076 /*
02077  * Parse colors from resource.{visited_}link_color, saving them
02078  * to g_{visited_}link_color and {visited_}link_pix.
02079 */
02080 static void
02081 get_link_colors(Pixel *link_pix, Pixel *visited_link_pix)
02082 {
02083     XrmValue from1, from2, to1, to2;
02084        
02085     XColor exact, approx;
02086     double r, g, b;
02087     double factor = 65535.0;
02088     int ret;
02089 
02090     /* get rgb values from color for links */
02091     if ((ret = XLookupColor(DISP, G_colormap,
02092                          resource.link_color,
02093                          &exact, &approx)) != 0) {
02094     }
02095     else {
02096        XDVI_WARNING((stderr, "XLookupColor failed for resource.link_color \"%s\"\n"
02097                     "- using fallback color \"%s\".",
02098                     resource.visited_link_color, LINK_COLOR_FALLBACK));
02099        XLookupColor(DISP, G_colormap, LINK_COLOR_FALLBACK, &exact, &approx);
02100     }
02101        
02102 #if 0
02103     fprintf(stderr, "lookup color for %s returned: %d, %d, %d\n",
02104            resource.link_color, exact.red, exact.green, exact.blue);
02105 #endif
02106     r = exact.red / factor;
02107     g = exact.green / factor;
02108     b = exact.blue / factor;
02109     g_link_color_rgb = xmalloc(strlen("push rgb 0.00 0.00 0.00") + 1);
02110     sprintf(g_link_color_rgb, "push rgb %.2f %.2f %.2f", r, g, b);
02111        
02112     /* same for visited links */
02113     if ((ret = XLookupColor(DISP, G_colormap,
02114                          resource.visited_link_color,
02115                          &exact, &approx)) != 0) {
02116     }
02117     else {
02118        XDVI_WARNING((stderr, "XLookupColor failed for resource.visited_link_color \"%s\"\n"
02119                     "- using fallback color \"%s\".",
02120                     resource.visited_link_color, VISITED_LINK_COLOR_FALLBACK));
02121        XLookupColor(DISP, G_colormap, VISITED_LINK_COLOR_FALLBACK, &exact, &approx);
02122     }
02123        
02124 #if 0
02125     fprintf(stderr, "lookup color for %s returned: %d, %d, %d\n",
02126            resource.visited_link_color, exact.red, exact.green, exact.blue);
02127 #endif
02128     r = exact.red / factor;
02129     g = exact.green / factor;
02130     b = exact.blue / factor;
02131     g_visited_link_color_rgb = xmalloc(strlen("push rgb 0.00 0.00 0.00") + 1);
02132     sprintf(g_visited_link_color_rgb, "push rgb %.2f %.2f %.2f", r, g, b);
02133 
02134     /* 2nd part: Create CG for the underlines. */
02135     from1.addr = resource.link_color;
02136     from1.size = strlen(from1.addr) + 1;
02137     to1.addr = (XtPointer)link_pix;
02138     to1.size = sizeof(Pixel);
02139     if (!XtConvertAndStore(globals.widgets.top_level, XtRString, &from1, XtRPixel, &to1)) {
02140        XDVI_WARNING((stderr, "String to pixel conversion failed for resource.link_color \"%s\"\n"
02141                     "- using fallback color \"%s\".",
02142                     resource.link_color, LINK_COLOR_FALLBACK));
02143        from1.addr = LINK_COLOR_FALLBACK;
02144        from1.size = strlen(from1.addr) + 1;
02145        to1.addr = (XtPointer)link_pix;
02146        to1.size = sizeof(Pixel);
02147        XtConvertAndStore(globals.widgets.top_level, XtRString, &from1, XtRPixel, &to1);
02148     }
02149     from2.addr = resource.visited_link_color;
02150     from2.size = strlen(from2.addr) + 1;
02151     to2.addr = (XtPointer)visited_link_pix;
02152     to2.size = sizeof(Pixel);
02153     if (!XtConvertAndStore(globals.widgets.top_level, XtRString, &from2, XtRPixel, &to2)) {
02154        XDVI_WARNING((stderr, "String to pixel conversion failed for resource.visited_link_color \"%s\"\n"
02155                     "- using fallback color \"%s\".",
02156                     resource.visited_link_color, VISITED_LINK_COLOR_FALLBACK));
02157        from2.addr = VISITED_LINK_COLOR_FALLBACK;
02158        from2.size = strlen(from2.addr) + 1;
02159        to2.addr = (XtPointer)visited_link_pix;
02160        to2.size = sizeof(Pixel);
02161        XtConvertAndStore(globals.widgets.top_level, XtRString, &from2, XtRPixel, &to2);
02162     }
02163 }
02164 
02165 /*  Widget globals.widgets.main_row, globals.widgets.menu_bar; */
02166 
02167 
02168 #ifdef MOTIF
02169 /* make sure the translations for the drawing area are properly set
02170    (Motif 2.x seems to somehow overwrite them somewhere in the
02171    initialization phase; bug #610206).
02172 */
02173 void
02174 motif_translations_hack(void)
02175 {
02176     static XtTranslations xlats = NULL;
02177     const char *const translations = \
02178        "<Key>osfPageUp:back-page()\n"
02179        "<Key>osfPageDown:forward-page()\n"
02180        "Ctrl<Key>osfBeginLine:goto-page(1)\n"
02181        "Ctrl<Key>osfEndLine:goto-page()\n"
02182        "<Key>osfBeginLine:home-or-top()\n"
02183        "<Key>osfEndLine:end-or-bottom()\n"
02184 #if 0
02185        /* AFAIK the following don't have any effect with Motif */
02186 #ifdef XK_KP_Left
02187        "<Key>KP_Home:home()\n"
02188        "<Key>KP_End:down()\n"
02189        "<Key>KP_Prior:back-page()\n"
02190        "<Key>KP_Next:forward-page()\n"
02191 #endif
02192 #endif
02193        ;
02194 
02195     if (xlats == NULL) {
02196        xlats = XtParseTranslationTable(translations);
02197     }
02198            
02199     ASSERT(globals.widgets.clip_widget != NULL, "globals.widgets.clip_widget must have been initialized");
02200     ASSERT(globals.widgets.draw_widget != NULL, "globals.widgets.draw_widget must have been initialized");
02201     XtOverrideTranslations(globals.widgets.clip_widget, xlats);
02202 }
02203 #endif /* MOTIF */
02204 
02205 
02206 /*
02207   Initialize internal data (most of them global ...) according to the values
02208   of resources/command-line arguments, warning user about illegal values
02209   etc.
02210 */
02211 static void
02212 init_check_resources(void)
02213 {
02214     size_t i;
02215     
02216     if (resource.mfmode != NULL) {
02217        char *p;
02218 
02219        p = strrchr(resource.mfmode, ':');
02220        if (p != NULL) {
02221            unsigned int len;
02222            char *p1;
02223 
02224            ++p;
02225            len = p - resource.mfmode;
02226            p1 = xmalloc(len);
02227            memcpy(p1, resource.mfmode, len - 1);
02228            p1[len - 1] = '\0';
02229            resource.mfmode = p1;
02230            resource.pixels_per_inch = atoi(p);
02231        }
02232     }
02233     if (currwin.shrinkfactor < 0) {
02234        XDVI_ERROR((stderr, "Invalid shrink factor: %d.", currwin.shrinkfactor));
02235        usage(EXIT_FAILURE);
02236     }
02237     if (resource.density <= 0) {
02238        XDVI_ERROR((stderr, "Invalid shrink density: %d.", resource.density));
02239        usage(EXIT_FAILURE);
02240     }
02241     if (resource.pixels_per_inch <= 0) {
02242        XDVI_ERROR((stderr, "Invalid dpi value: %d.", resource.pixels_per_inch));
02243        usage(EXIT_FAILURE);
02244     }
02245     if (resource.link_style < 0 || resource.link_style > 3) {
02246        XDVI_ERROR((stderr, "Unrecognized value %d for resource \"linkstyle\" (valid range is 0 - 3); assuming 3.",
02247                   resource.link_style));
02248        resource.link_style = 3;
02249     }
02250     if (currwin.shrinkfactor > 1) {
02251        mane.shrinkfactor = currwin.shrinkfactor; /* otherwise it's 1 */
02252     }
02253 
02254 #ifdef RGB_ANTI_ALIASING
02255 #warning Note: RGB Anti-aliasing enabled
02256     /* subpixel rendering */
02257     resource.subpixel_order = SUBPIXEL_NONE;
02258     if (resource.sub_pixels != NULL) {
02259        int sum;
02260        
02261        if (memicmp(resource.sub_pixels, "rgb", 3) == 0)
02262            resource.subpixel_order = SUBPIXEL_RGB;
02263        else if (memicmp(resource.sub_pixels, "bgr", 3) == 0)
02264            resource.subpixel_order = SUBPIXEL_BGR;
02265        else if (memicmp(resource.sub_pixels, "none", 3) == 0)
02266            resource.subpixel_order = SUBPIXEL_NONE;
02267        else {
02268            XDVI_ERROR((stderr,
02269                      "Unrecognized value \"%s\" for resource subpixels\n"
02270                      "(possible values are: \"rgb\" or \"bgr\").",
02271                      resource.sub_pixels));
02272            xdvi_exit(EXIT_FAILURE);
02273        }
02274        /* get the energy distribution */
02275        if (resource.subpixel_order == SUBPIXEL_RGB || resource.subpixel_order == SUBPIXEL_BGR) {
02276            const char *ptr = resource.sub_pixels + 3;
02277            while (isspace(*ptr))
02278               ptr++;
02279            fprintf(stderr, "ptr: |%s|\n", ptr);
02280            resource.subpixel_energy[0] = 33.333;
02281            resource.subpixel_energy[1] = 33.333;
02282            resource.subpixel_energy[2] = 0.0;
02283            if (*ptr != '\0') {
02284               if (sscanf(ptr, "%f %f %f",
02285                         &(resource.subpixel_energy[0]),
02286                         &(resource.subpixel_energy[1]),
02287                         &(resource.subpixel_energy[2]))
02288                   != 3) {
02289                   XDVI_ERROR((stderr,
02290                             "Illegal color mask `%s' for resource subpixels (should be: `n n n')\n",
02291                             ptr));
02292               }
02293            }
02294 
02295            sum = (int)(resource.subpixel_energy[0] +
02296                      2 * resource.subpixel_energy[1] +
02297                      2 * resource.subpixel_energy[2]);
02298            if (sum < 99 || sum > 100) {
02299               XDVI_WARNING((stderr, "energy values %f + 2 * %f + 2 * %f don't sum up to 100%%!\n",
02300                            resource.subpixel_energy[0], resource.subpixel_energy[1], resource.subpixel_energy[2]));
02301               exit(1);
02302            }
02303            
02304            resource.subpixel_energy[0] /= 100.0;
02305            resource.subpixel_energy[1] /= 100.0;
02306            resource.subpixel_energy[2] /= 100.0;
02307            fprintf(stderr, "subpixel order: %s = %d; [%f %f %f]\n",
02308                   resource.sub_pixels, resource.subpixel_order,
02309                   resource.subpixel_energy[0], resource.subpixel_energy[1], resource.subpixel_energy[2]);
02310        }
02311     }
02312 #endif
02313 
02314     /* margins */
02315     if (resource.sidemargin)
02316        resource.sidemargin_int = atopix(resource.sidemargin, False);
02317     if (resource.topmargin)
02318        resource.topmargin_int = atopix(resource.topmargin, False);
02319     resource.xoffset_int = resource.xoffset ? atopix(resource.xoffset, True)
02320        : resource.pixels_per_inch;
02321     resource.yoffset_int = resource.yoffset ? atopix(resource.yoffset, True)
02322        : resource.pixels_per_inch;
02323 
02324     /* paper type */
02325     if (!set_paper_type(resource.paper)) {
02326        const char **p;
02327        char *helpmsg = xstrdup("Possible paper types are:\n    ");
02328        for (p = paper_types; p < paper_types + XtNumber(paper_types); p += 2) {
02329            if (**p == '\0') { /* next line of list */
02330               helpmsg = xstrcat(helpmsg, "\n    ");
02331            }
02332            else {
02333               helpmsg = xstrcat(helpmsg, *p);
02334               helpmsg = xstrcat(helpmsg, " ");
02335            }
02336        }
02337        helpmsg = xstrcat(helpmsg,
02338                       "\n(the names ending with `r' are `rotated' or `landscape' variants).\n"
02339                       "Alternatively, you can specify the dimensions as `WIDTHxHEIGHT', followed "
02340                       "by a dimension unit (one of: pt pc in bp cm mm dd cc sp).");
02341        /* also dump it to stderr ... */
02342        fprintf(stderr,
02343               "Unrecognized value `%s' for paper type option; using a4 instead.\n%s\n",
02344               resource.paper, helpmsg);
02345        
02346        popup_message(globals.widgets.top_level,
02347                     MSG_WARN, helpmsg,
02348                     "Unrecognized value `%s' for paper type option; using a4 instead.", resource.paper);
02349        set_paper_type("a4");
02350     }
02351 
02352     /* magnifier sizes */
02353     for (i = 0; i < get_magglass_items(); ++i) {
02354        if (resource.mg_arg[i] != NULL) {
02355            char *s;
02356 
02357            mg_size[i].w = mg_size[i].h = atoi(resource.mg_arg[i]);
02358            s = strchr(resource.mg_arg[i], 'x');
02359            if (s != NULL) {
02360               mg_size[i].h = atoi(s + 1);
02361               if (mg_size[i].h <= 0)
02362                   mg_size[i].w = 0;
02363            }
02364        }
02365     }
02366 
02367 #ifdef PS
02368     if (resource.safer) {
02369        resource.allow_shell = False;
02370 # ifdef PS_GS
02371        resource.gs_safer = True;
02372 # endif /* PS_GS */
02373     }
02374 # ifdef       PS_GS
02375     {
02376        const char *CGMcgm = "CGMcgm";
02377        const char *cgmp;
02378 
02379        cgmp = strchr(CGMcgm, resource.gs_palette[0]);
02380        if (cgmp == NULL)
02381            XDVI_FATAL((stderr, "Invalid value %s for gs palette option", resource.gs_palette));
02382        if (cgmp >= CGMcgm + 3) {
02383            static char gsp[] = "x";
02384 
02385            gsp[0] = *(cgmp - 3);
02386            resource.gs_palette = gsp;
02387        }
02388     }
02389 # endif /* PS_GS */
02390 #endif /* PS */
02391 
02392     /* The old `-expert' flag overrides resource.expert_mode, `+expert' (or not
02393        setting it) just uses expert_mode.
02394      */
02395     if (resource.expert)
02396        resource.expert_mode = XPRT_SHOW_NONE;
02397 /*      fprintf(stderr, "++++++++ initializing resource.expert_mode: %d\n", resource.expert_mode); */
02398     update_expert_mode();
02399 }
02400 
02401 static void
02402 create_cursors(void)
02403 {
02404     XColor bg_Color;
02405     Pixmap temp;
02406     Pixmap mask;
02407 
02408     /* first try colors by name, as fix for #804294; fall back on
02409        WhitePixelOfScreen() etc. if this fails:
02410     */
02411     if (resource.cr_Pixel != (Pixel)ULONG_MAX) {
02412        m_cursor_color.pixel = resource.cr_Pixel;
02413        XQueryColor(DISP, G_colormap, &m_cursor_color);
02414     }
02415     else {
02416        if (XParseColor(DISP, G_colormap, "black", &m_cursor_color) == 0) { /* lookup failure */
02417            m_cursor_color.pixel = BlackPixelOfScreen(SCRN);
02418            XQueryColor(DISP, G_colormap, &m_cursor_color);
02419        }
02420     }
02421     if (XParseColor(DISP, G_colormap, "white", &bg_Color) == 0) { /* lookup failure */
02422        bg_Color.pixel = WhitePixelOfScreen(SCRN);
02423        XQueryColor(DISP, G_colormap, &bg_Color);
02424     }
02425 
02426     /* wait cursor */
02427 #if 0 /* this makes no big difference for #804294 */
02428     temp = XCreatePixmapFromBitmapData(DISP, RootWindowOfScreen(SCRN),
02429                                    (char *)time16_bits,
02430                                    time16_width, time16_height,
02431                                    1, 0, 1);
02432     mask = XCreatePixmapFromBitmapData(DISP, RootWindowOfScreen(SCRN),
02433                                    (char *)time16_mask_bits,
02434                                    time16_mask_width, time16_mask_height,
02435                                    1, 0, 1);
02436 #else
02437     temp = XCreateBitmapFromData(DISP, RootWindowOfScreen(SCRN),
02438                              (char *)time16_bits,
02439                              time16_width, time16_height);
02440     mask = XCreateBitmapFromData(DISP, RootWindowOfScreen(SCRN),
02441                              (char *)time16_mask_bits,
02442                              time16_mask_width, time16_mask_height);
02443 #endif
02444     globals.cursor.wait = XCreatePixmapCursor(DISP, temp, mask,
02445                                   &m_cursor_color, &bg_Color,
02446                                   time16_width / 2, time16_height / 2);
02447     XFreePixmap(DISP, temp);
02448     XFreePixmap(DISP, mask);
02449 
02450     /* ready cursor, magnifier by default */
02451     temp = XCreateBitmapFromData(DISP, RootWindowOfScreen(SCRN),
02452                              (char *)magglass_bits,
02453                              magglass_width, magglass_height);
02454     mask = XCreateBitmapFromData(DISP, RootWindowOfScreen(SCRN),
02455                              (char *)magglass_mask_bits,
02456                              magglass_mask_width, magglass_mask_height);
02457 
02458     globals.cursor.ready = XCreatePixmapCursor(DISP, temp, mask,
02459                                    &m_cursor_color, &bg_Color,
02460                                    magglass_x_hot, magglass_y_hot);
02461     XFreePixmap(DISP, temp);
02462     XFreePixmap(DISP, mask);
02463 
02464     globals.cursor.corrupted = XCreateFontCursor(DISP, XC_watch);
02465 
02466 #if !COLOR
02467     XRecolorCursor(DISP, globals.cursor.ready, &m_cursor_color, &bg_Color);
02468     XRecolorCursor(DISP, globals.cursor.wait, &m_cursor_color, &bg_Color);
02469 #endif
02470     /* Cursor when page is paused */
02471 #ifdef VMS
02472     temp = XCreateBitmapFromData(DISP, RootWindowOfScreen(SCRN),
02473                              (char *)hand_bits, hand_width, hand_height);
02474     mask = XCreateBitmapFromData(DISP, RootWindowOfScreen(SCRN),
02475                              (char *)hand_mask_bits, hand_mask_width, hand_mask_height);
02476     globals.cursor.pause = XCreatePixmapCursor(DISP, temp, mask,
02477                                    &m_cursor_color, &bg_Color, 6, 6);
02478     XFreePixmap(DISP, temp);
02479     XFreePixmap(DISP, mask);
02480 #else
02481     globals.cursor.pause = XCreateFontCursor(DISP, XC_watch);
02482 #endif
02483 
02484     /* cursors indicating dragging direction */
02485     temp = XCreateBitmapFromData(DISP, RootWindowOfScreen(SCRN),
02486                              (char *)drag_vert_bits,
02487                              drag_vert_width, drag_vert_height);
02488     mask = XCreateBitmapFromData(DISP, RootWindowOfScreen(SCRN),
02489                              (char *)drag_vert_mask_bits,
02490                              drag_vert_mask_width, drag_vert_mask_height);
02491     globals.cursor.drag_v = XCreatePixmapCursor(DISP, temp, mask,
02492                                    &m_cursor_color, &bg_Color,
02493                                    drag_vert_x_hot, drag_vert_y_hot);
02494     XFreePixmap(DISP, temp);
02495     XFreePixmap(DISP, mask);
02496 
02497     temp = XCreateBitmapFromData(DISP, RootWindowOfScreen(SCRN),
02498                              (char *)drag_horiz_bits,
02499                              drag_horiz_width, drag_horiz_height);
02500     mask = XCreateBitmapFromData(DISP, RootWindowOfScreen(SCRN),
02501                              (char *)drag_horiz_mask_bits,
02502                              drag_horiz_width, drag_horiz_height);
02503     globals.cursor.drag_h = XCreatePixmapCursor(DISP, temp, mask,
02504                                    &m_cursor_color, &bg_Color,
02505                                    drag_horiz_x_hot, drag_horiz_y_hot);
02506     XFreePixmap(DISP, temp);
02507     XFreePixmap(DISP, mask);
02508 
02509     temp = XCreateBitmapFromData(DISP, RootWindowOfScreen(SCRN),
02510                              (char *)drag_omni_bits,
02511                              drag_omni_width, drag_omni_height);
02512     mask = XCreateBitmapFromData(DISP, RootWindowOfScreen(SCRN),
02513                              (char *)drag_omni_mask_bits,
02514                              drag_omni_mask_width, drag_omni_mask_height);
02515     globals.cursor.drag_a = XCreatePixmapCursor(DISP, temp, mask,
02516                                    &m_cursor_color, &bg_Color,
02517                                    drag_omni_x_hot, drag_omni_y_hot);
02518     XFreePixmap(DISP, temp);
02519     XFreePixmap(DISP, mask);
02520 
02521 #ifdef VMS
02522     globals.cursor.link = globals.cursor.ready;
02523     globals.cursor.rule = globals.cursor.ready;
02524     globals.cursor.mag = globals.cursor.ready;
02525     globals.cursor.text = globals.cursor.ready;
02526 #else
02527     globals.cursor.link = XCreateFontCursor(DISP, XC_hand2);
02528     globals.cursor.rule = XCreateFontCursor(DISP, XC_crosshair);
02529     globals.cursor.mag = XCreateFontCursor(DISP, XC_crosshair);
02530     globals.cursor.text = XCreateFontCursor(DISP, XC_cross);
02531     /*  globals.cursor.text = XCreateFontCursor(DISP, XC_tcross); */
02532     XRecolorCursor(DISP, globals.cursor.mag, &m_cursor_color, &bg_Color);
02533 #endif
02534 }
02535 
02536 /* Initialize a forward search if the source_position argument is not NULL. */
02537 static void
02538 do_forward_search(const char *source_position)
02539 {
02540     /* parse the special to expand the filename */
02541     struct src_parsed_special data;
02542     char *new_special = NULL;
02543     char *expanded_filename = NULL;
02544            
02545     if (source_position == NULL) /* nothing to do */
02546        return;
02547     
02548     data.filename_len = 0;
02549     data.filename = NULL;
02550 
02551     src_parse(source_position, strlen(source_position), &data);
02552            
02553     if (data.filename_len == 0) { /* malformed argument: tell user, and ignore it */
02554        popup_message(globals.widgets.top_level,
02555                     MSG_ERR,
02556                     /* helptext */
02557                     "The format of the -sourceposition argument should be:\n"
02558                     "-sourceposition '<nn>[ ]*<filename'\n"
02559                     "with <nn> = linenumber, [ ]* = an arbitrary number of spaces, "
02560                     "and <filename> = TeX source file.",
02561                     /* error message */
02562                     "Filename missing in `-sourceposition' argument \"%s\". "
02563                     "Could not perform forward search.",
02564                     source_position);
02565     }
02566     else {
02567        TRACE_CLIENT((stderr, "got data: line %d, col %d, file |%s|, len %lu\n",
02568                     data.line, data.col, data.filename, (unsigned long)data.filename_len));
02569               
02570        /* expand -sourceposition argument if it contains a path component, like above */
02571        if (strchr(data.filename, '/') != NULL
02572            && (expanded_filename = expand_filename(data.filename, USE_CWD_PATH)) != NULL) {
02573            char *tmp = canonicalize_path(expanded_filename);
02574            free(data.filename);
02575            free(expanded_filename);
02576            expanded_filename = tmp;              
02577        }
02578        else
02579            expanded_filename = data.filename;
02580               
02581        TRACE_CLIENT((stderr, "expanded source_position: |%s|\n", expanded_filename));
02582               
02583        new_special = xmalloc(2 * LENGTH_OF_INT + 2 /* 2 for `:' and separating space */
02584                            + strlen(expanded_filename) + 1);
02585        sprintf(new_special, "%d:%d %s", data.line, data.col, expanded_filename);
02586        free(expanded_filename);
02587        globals.src.fwd_string = new_special;
02588        globals.ev.flags |= EV_SRC;
02589     }
02590 }
02591 
02592 static void
02593 check_early_arguments(int argc, char **argv)
02594 {
02595     /* This checks arguments that need to work before the X machinery is
02596      * started (e.g. if no display is available, or for information that is
02597      * needed before the X defaults are evaluated), so the `options' structure
02598      * can't be used for them.
02599      *
02600      * We need to loop through all arguments in case xdvi is aliased,
02601      * or called via a shell script (like in teTeX) that adds things
02602      * like `-name' at the beginning of the arglist.
02603      */
02604     int i;
02605     Boolean install_err_handler = True;
02606     
02607     for (i = 1; i < argc; i++) {
02608        if (strcmp(argv[i], "-help") == 0
02609            || strcmp(argv[i], "-h") == 0
02610            || strcmp(argv[i], "+help") == 0
02611            || strcmp(argv[i], "--help") == 0) {
02612            printf("%s version %s\n", XDVIK_PROGNAME, XDVI_VERSION_INFO);
02613            printf("A DVI file previewer for the X window system.\n\n");
02614            display_licensing_info();
02615            display_bug_reporting_info();
02616            usage(0);
02617        }
02618        else if (strcmp(argv[i], "-license") == 0) {
02619            display_long_licensing_info();
02620            xdvi_exit(EXIT_SUCCESS);
02621        }
02622        else if (strcmp(argv[i], "--version") == 0
02623                || strcmp(argv[i], "-version") == 0
02624                || strcmp(argv[i], "-v") == 0) {
02625            display_version_info();
02626            xdvi_exit(EXIT_SUCCESS);
02627        }
02628        else if (strcmp(argv[i], "--default-xerr-handler") == 0) { /* hook to disable custom handler */
02629            install_err_handler = False;
02630        }
02631     }
02632 
02633     if (install_err_handler) {
02634        (void)XSetErrorHandler(x_error_handler);
02635     }
02636 }
02637 
02638 static void
02639 create_colormaps(void)
02640 {
02641 #ifdef GREY
02642     G_depth = (unsigned int)DefaultDepthOfScreen(SCRN);
02643     G_visual = DefaultVisualOfScreen(SCRN);
02644     G_colormap = DefaultColormapOfScreen(SCRN);
02645 #ifdef XSERVER_INFO
02646     if (globals.debug & DBG_ALL)
02647        fprintf(stdout, "--- G_depth: %d\n", G_depth);
02648 #endif
02649 
02650     if (resource.install != False && G_visual->class == PseudoColor) {
02651        /* look for a TrueColor visual with more bits */
02652        XVisualInfo template;
02653        XVisualInfo *list;
02654        int nitems_return;
02655 #ifdef XSERVER_INFO
02656        if (globals.debug & DBG_ALL)
02657            fprintf(stdout, "--- looking for a better TrueColor visual\n");
02658 #endif
02659 
02660        template.screen = XScreenNumberOfScreen(SCRN);
02661        template.class = TrueColor;
02662        list = XGetVisualInfo(DISP, VisualScreenMask | VisualClassMask,
02663                            &template, &nitems_return);
02664        if (list != NULL) {
02665            XVisualInfo *list1;
02666            XVisualInfo *best = NULL;
02667 
02668            for (list1 = list; list1 < list + nitems_return; ++list1) {
02669 #ifdef XSERVER_INFO
02670               if (globals.debug & DBG_ALL)
02671                   fprintf(stdout, "--- checking %d\n", list1->depth);
02672 #endif
02673               if ((unsigned int)list1->depth > G_depth
02674 # if PS_GS
02675                   /* patch by Toni Ronkko <tronkko@hytti.uku.fi>, fixes bug #458057:
02676                    * SGI supports additional depths of 12 and 30, but
02677                    * these are not supported by ghostscript (see
02678                    * xdev->vinfo->depth in gdevxcmp.c (ghostscript-6.51)),
02679                    * so we restrict the values to those supported by gs.
02680                    */
02681                   && (list1->depth == 1 || list1->depth == 2
02682                      || list1->depth == 4 || list1->depth == 8
02683                      || list1->depth == 15 || list1->depth == 16
02684                      || list1->depth == 24 || list1->depth == 32)
02685 # endif
02686                   && (best == NULL || list1->depth > best->depth))
02687                   best = list1;
02688            }
02689            if (best != NULL) {
02690 #ifdef XSERVER_INFO
02691               if (globals.debug & DBG_ALL)
02692                   fprintf(stdout, "--- best depth: %d\n", best->depth);
02693 #endif
02694               G_depth = best->depth;
02695               G_visual = best->visual;
02696               G_colormap = XCreateColormap(DISP,
02697                                           RootWindowOfScreen(SCRN),
02698                                           G_visual, AllocNone);
02699               XInstallColormap(DISP, G_colormap);
02700               temp_args1[0].value = (XtArgVal) G_depth;
02701               temp_args1[1].value = (XtArgVal) G_visual;
02702               temp_args1[2].value = (XtArgVal) G_colormap;
02703               XtSetValues(globals.widgets.top_level, temp_args1, XtNumber(temp_args1));
02704               XtSetTypeConverter(XtRString, XtRPixel,
02705                                XdviCvtStringToPixel,
02706                                (XtConvertArgList) colorConvertArgs, 2,
02707                                XtCacheByDisplay, NULL);
02708               {
02709                   /* This is needed so that popup windows have the right
02710                      visual and colormap.  It is unnecessary for newer
02711                      versions of Motif (Motif 2.1.0, Solaris 9) but
02712                      needed for older versions (Motif 1.2.5, Solaris 2.6),
02713                      and for Xaw.
02714                   */
02715                   XrmDatabase      db = XtScreenDatabase(SCRN);
02716                   XrmValue  val;
02717                   
02718                   val.size = sizeof G_visual;
02719                   val.addr = (XtPointer) &G_visual;
02720                   XrmPutResource(&db, "XDvi*visual", XtRVisual, &val);
02721                   
02722                   val.size = sizeof G_colormap;
02723                   val.addr = (XtPointer) &G_colormap;
02724                   XrmPutResource(&db, "XDvi*colormap", XtRColormap, &val);
02725               }
02726            }
02727            XFree(list);
02728        }
02729     }
02730 
02731 #ifdef MOTIF
02732     if (globals.debug & DBG_GUI) {
02733        printf("Compiled with %s, runtime version %d.%d\n",
02734               /*        XmVERSION, XmREVISION, XmUPDATE_LEVEL, */
02735               XmVERSION_STRING,
02736               xmUseVersion / 1000, xmUseVersion % 1000);
02737     }
02738 #endif
02739     
02740     if (resource.install == True && G_visual->class == PseudoColor) {
02741        XColor tmp_color;
02742 #ifdef XSERVER_INFO
02743        if (globals.debug & DBG_ALL)
02744            fprintf(stdout, "--- PseudoColor, trying to install colormap\n");
02745 #endif
02746 
02747        /* This next bit makes sure that the standard black and white pixels
02748           are allocated in the new colormap. */
02749        tmp_color.pixel = BlackPixelOfScreen(SCRN);
02750        XQueryColor(DISP, G_colormap, &tmp_color);
02751        XAllocColor(DISP, G_colormap, &tmp_color);
02752 
02753        tmp_color.pixel = WhitePixelOfScreen(SCRN);
02754        XQueryColor(DISP, G_colormap, &tmp_color);
02755        XAllocColor(DISP, G_colormap, &tmp_color);
02756 
02757        G_colormap = XCopyColormapAndFree(DISP, G_colormap);
02758        temp_args1[2].value = (XtArgVal) G_colormap;
02759        XtSetValues(globals.widgets.top_level, temp_args1 + 2, 1);
02760     }
02761 
02762     XtGetApplicationResources(globals.widgets.top_level, (XtPointer)&resource,
02763                            app_pixel_resources, XtNumber(app_pixel_resources),
02764                            (ArgList)NULL, 0);
02765 
02766 #endif /* GREY */
02767 
02768     globals.gc.do_copy = resource.copy;
02769 
02770 #if GREY || COLOR
02771     color_data[0].pixel = resource.fore_Pixel;
02772     color_data[1].pixel = resource.back_Pixel;
02773     XQueryColors(DISP, G_colormap, color_data, 2);
02774 #endif
02775     
02776 #if COLOR
02777     fg_initial.r = color_data[0].red;
02778     fg_initial.g = color_data[0].green;
02779     fg_initial.b = color_data[0].blue;
02780     bg_initial.r = color_data[1].red;
02781     bg_initial.g = color_data[1].green;
02782     bg_initial.b = color_data[1].blue;
02783 
02784 #endif
02785 
02786 #if GREY
02787     if (G_depth == 1) {
02788 #ifdef XSERVER_INFO
02789        if (globals.debug & DBG_ALL)
02790            fprintf(stdout, "--- using depth 1\n");
02791 #endif
02792        resource.use_grey = False;
02793     }
02794     if (resource.use_grey && G_visual->class != TrueColor) {
02795 #ifdef XSERVER_INFO
02796        if (globals.debug & DBG_ALL)
02797            fprintf(stdout, "--- using grey, but not TrueColor\n");
02798 #endif
02799        init_plane_masks();
02800        if (!globals.gc.do_copy) {
02801            /* Retain color_data[1].pixel for psgs.c.  */
02802            XColor tmp_color;
02803 #ifdef XSERVER_INFO
02804            if (globals.debug & DBG_ALL)
02805               fprintf(stdout, "--- not using copy\n");
02806 #endif
02807            
02808            tmp_color = color_data[1];
02809            tmp_color.pixel = resource.back_Pixel;
02810            XStoreColor(DISP, G_colormap, &tmp_color);
02811        }
02812     }
02813 #endif
02814 }
02815 
02816 static void
02817 create_widgets(
02818 #ifdef MOTIF
02819               Widget tool_bar, Widget form,
02820 #endif
02821               int *add_w, int *add_h)
02822 {
02823     static const char default_key_translations[] =
02824        "\"0\":digit(0)\n"
02825        "\"1\":digit(1)\n"
02826        "\"2\":digit(2)\n"
02827        "\"3\":digit(3)\n"
02828        "\"4\":digit(4)\n"
02829        "\"5\":digit(5)\n"
02830        "\"6\":digit(6)\n"
02831        "\"7\":digit(7)\n"
02832        "\"8\":digit(8)\n"
02833        "\"9\":digit(9)\n"
02834        /*            "\"-\":minus()\n" */
02835        "<Motion>:motion()\n";
02836     
02837     static const char default_mouse_translations[] =
02838        "<BtnUp>:release()";
02839 
02840 #ifdef MOTIF
02841     Widget status_line;
02842 
02843 #if 0
02844  {
02845      int i, n, longest_page = 0;
02846      Dimension width, height;
02847      char tmpbuf[1024];
02848      char *fontname;
02849      XmString tmpstring;
02850      Widget dummy_list;
02851      XmRendition rendition;
02852      XmRenderTable rtable;
02853      Arg args[10];
02854     /*
02855      * Try to determine width of longest page string:
02856      */
02857     for (i = 0; i < total_pages; i++) {
02858        int curr = abs(pageinfo_get_number(i));
02859        if (curr > longest_page)
02860            longest_page = curr;
02861     }
02862     fprintf(stderr, "longest page number: %d\n", longest_page);
02863     sprintf(tmpbuf, "* %d", longest_page);
02864     tmpstring = XmStringCreateLocalized(tmpbuf);
02865     dummy_list = XtCreateWidget("PageList", xmListWidgetClass, form, NULL, 0);
02866     fprintf(stderr, "rendition table\n");
02867     n = 0;
02868 /*     XtVaGetValues(globals.widgets.top_level, XmNfontList, &fontname, NULL); */
02869 /*     fprintf(stderr, "fontname: |%s|\n", fontname); */
02870     XtSetArg(args[n], XmNfontName, "8x16"); n++;
02871     XtSetArg(args[n], XmNfontType, XmFONT_IS_FONT); n++;
02872     rendition = XmRenditionCreate(dummy_list, XmFONTLIST_DEFAULT_TAG, args, n);
02873     rtable = XmRenderTableAddRenditions(NULL, &rendition, 1, XmMERGE_REPLACE);
02874     XtVaSetValues(dummy_list, XmNrenderTable, rtable, NULL);
02875     
02876     /*        rendition = XmRenditionCreate(globals.widgets.top_level, XmFONTLIST_DEFAULT_TAG, NULL, 0); */
02877     fprintf(stderr, "extent\n");
02878     XmStringExtent(rtable, tmpstring, &width, &height);
02879     fprintf(stderr, "string %s has width %d, height %d\n", tmpbuf, width, height);
02880     XtDestroyWidget(dummy_list);
02881     XmRenditionFree(rendition);
02882     XmStringFree(tmpstring);
02883  }
02884 #endif
02885     {
02886 #define ARG_LEN 20
02887        int n = 0;
02888        Arg list_args[ARG_LEN];
02889 
02890        XtSetArg(list_args[n], XmNlistSizePolicy, XmVARIABLE);                n++;
02891        XtSetArg(list_args[n], XmNwidth, resource.pagelist_width);            n++;
02892 #if defined(USE_PANNER) && USE_XAW_PANNER
02893        XtSetArg(list_args[n], XmNheight, globals.page.h - 62);               n++;
02894 #else
02895        XtSetArg(list_args[n], XmNheight, globals.page.h);                    n++;
02896 #endif
02897 /*     XtSetArg(list_args[n], XmNspacing, 10);                               n++; */
02898 #if defined(USE_PANNER) && USE_XAW_PANNER
02899        XtSetArg(list_args[n], XmNtopAttachment, XmATTACH_WIDGET);            n++;
02900        XtSetArg(list_args[n], XmNtopWidget, panner);                         n++;
02901 #else
02902        XtSetArg(list_args[n], XmNtopAttachment, XmATTACH_FORM);              n++;
02903 #endif
02904        XtSetArg(list_args[n], XmNbottomAttachment, XmATTACH_FORM);           n++;
02905        XtSetArg(list_args[n], XmNleftAttachment, XmATTACH_FORM);             n++;
02906        XtSetArg(list_args[n], XmNrightAttachment, XmATTACH_OPPOSITE_FORM);   n++;
02907        XtSetArg(list_args[n], XmNrightOffset, -resource.pagelist_width);     n++;
02908        XtSetArg(list_args[n], XmNresizable, True);                           n++;
02909        XtSetArg(list_args[n], XmNtopOffset, 2);                       n++;
02910        XtSetArg(list_args[n], XmNleftOffset, 2);                      n++;
02911        ASSERT(n < ARG_LEN, "list_args too short");
02912 #undef ARG_LEN
02913        /* TODO: Find a smart way to determine size of pagelist instead of using resource.pagelist_width,
02914           and find a smart way of resizing it when switching to a file with larger page numbers!
02915        */
02916        page_list = XmCreateScrolledList(form, "PageList", list_args, n);
02917     }
02918     
02919     if (resource.expert_mode == XPRT_SHOW_NONE) {
02920        XtUnmanageChild(XtParent(page_list));
02921        XtUnmanageChild(page_list);
02922     }
02923     
02924     globals.widgets.main_window = XtVaCreateManagedWidget("mainWindow",
02925                                      xmScrolledWindowWidgetClass, form,
02926                                      XmNscrollingPolicy, XmAUTOMATIC,
02927                                      XmNleftAttachment, XmATTACH_WIDGET,
02928                                      /* lesstif balks if we just use page_list, so use its parent,
02929                                         the xmScrolledWindow, for alignment: */
02930                                      XmNleftWidget, XtParent(page_list),
02931                                      XmNallowResize, True,
02932 /*                                   XmNtopOffset, 2, */
02933                                      XmNtopAttachment, XmATTACH_FORM,
02934                                      XmNbottomAttachment, XmATTACH_FORM,
02935                                      XmNrightAttachment, XmATTACH_FORM,
02936                                      /*                                     XmNleftOffset, 10, */
02937                                      XmNresizable, True,
02938                                      XmNborderWidth, 0,
02939                                      NULL);
02940     XtManageChild(form);
02941 
02942     globals.widgets.x_bar = XtNameToWidget(globals.widgets.main_window, "HorScrollBar");
02943     globals.widgets.y_bar = XtNameToWidget(globals.widgets.main_window, "VertScrollBar");
02944 
02945     
02946 #ifdef TEST_SCROLLING
02947     /* TODO: try the following to prevent `flashing' effect - still breaks
02948        scrolling in its current form though */
02949     globals.widgets.draw_background = XtVaCreateManagedWidget("drawing_bg",
02950                                          xmFormWidgetClass, globals.widgets.main_window,
02951                                          XmNwidth, globals.page.w,
02952                                          XmNheight, globals.page.h,
02953                                          XmNtopAttachment, XmATTACH_FORM,
02954                                          XmNbottomAttachment, XmATTACH_FORM,
02955                                          XmNrightAttachment, XmATTACH_FORM,
02956                                          XmNleftAttachment, XmATTACH_FORM,
02957                                          XmNhighlightThickness, 0,
02958                                          XmNbackground, resource.back_Pixel,
02959                                          XmNrubberPositioning, True,
02960                                          NULL);
02961 #endif
02962     globals.widgets.draw_widget = XtVaCreateWidget("drawing",
02963                                xmDrawingAreaWidgetClass,
02964 #ifdef TEST_SCROLLING
02965                                globals.widgets.draw_background,
02966 #else
02967                                globals.widgets.main_window,
02968 #endif
02969                                XmNwidth, globals.page.w,
02970                                XmNheight, globals.page.h,
02971                                XmNhighlightThickness, 0,
02972                                XmNrubberPositioning, True,
02973                                XtNbackground, resource.back_Pixel,
02974                                NULL);
02975 
02976 #if !FIXED_FLUSHING_PAGING
02977     ASSERT(XtParent(globals.widgets.draw_widget) != NULL, "");
02978     XtVaSetValues(XtParent(globals.widgets.draw_widget), XtNbackground, resource.back_Pixel, NULL);
02979 #endif
02980     
02981 #ifdef TEST_SCROLLING
02982     fprintf(stderr, "globals.widgets.draw_widget is: %p\n", globals.widgets.draw_widget);
02983 #endif
02984     XtVaGetValues(globals.widgets.main_window, XmNclipWindow, &globals.widgets.clip_widget, NULL);
02985 
02986     XtVaSetValues(globals.widgets.main_row,
02987                 XmNmenuBar, globals.widgets.menu_bar,
02988                 XmNcommandWindow, XtParent(tool_bar),
02989                 XmNworkWindow, form,
02990                 NULL);
02991     
02992     XtVaSetValues(globals.widgets.main_window,
02993                 XmNworkWindow, globals.widgets.draw_widget,
02994                 NULL);
02995 
02996     XtManageChild(globals.widgets.draw_widget);
02997 
02998     status_line = create_statusline(globals.widgets.main_row);
02999     XtVaSetValues(globals.widgets.main_row,
03000                 XmNmessageWindow, status_line,
03001                 NULL);
03002     if ((resource.expert_mode & XPRT_SHOW_STATUSLINE) == 0) {
03003        XtUnmanageChild(status_line);
03004     }
03005 
03006     XtManageChild(globals.widgets.main_row);
03007 
03008     if ((resource.expert_mode & XPRT_SHOW_TOOLBAR) != 0) {
03009        if (resource.toolbar_unusable)
03010            statusline_print(STATUS_LONG,
03011                           "Error creating the toolbar pixmaps - toolbar is disabled!");
03012        else
03013            XtManageChild(XtParent(tool_bar));
03014     }
03015 
03016     if ((resource.expert_mode & XPRT_SHOW_MENUBAR) != 0)
03017        XtManageChild(globals.widgets.menu_bar);
03018     
03019     XmAddTabGroup(globals.widgets.draw_widget);
03020     
03021     /*
03022       note: a few more custom translations for page_list are defined in
03023       pagesel.c, since the actions are only known there.
03024     */
03025     {
03026        size_t i, k = 0;
03027 #define WIDGETS_SIZE 10
03028        Widget widgets[WIDGETS_SIZE];
03029 
03030        widgets[k++] = globals.widgets.main_row;
03031 /*     widgets[k++] = globals.widgets.menu_bar; */
03032        widgets[k++] = tool_bar;
03033        widgets[k++] = page_list;
03034        widgets[k++] = globals.widgets.main_window;
03035        widgets[k++] = globals.widgets.draw_widget;
03036        widgets[k++] = globals.widgets.clip_widget;
03037 
03038        ASSERT(k < WIDGETS_SIZE, "widgets list too short");
03039 #undef WIDGETS_SIZE
03040        for (i = 0; i < k; i++) {
03041            XtOverrideTranslations(widgets[i], XtParseTranslationTable(base_key_translations));
03042            XtOverrideTranslations(widgets[i], XtParseTranslationTable(default_key_translations));
03043            if (i > 3) { /* widgets for which we want to use our own mouse translations */
03044               XtOverrideTranslations(widgets[i], XtParseTranslationTable(base_mouse_translations));
03045               XtOverrideTranslations(widgets[i], XtParseTranslationTable(default_mouse_translations));
03046            }
03047        }
03048     }
03049     
03050     if (resource.main_translations != NULL) {
03051        XtOverrideTranslations(globals.widgets.draw_widget, XtParseTranslationTable(resource.main_translations));
03052        XtOverrideTranslations(globals.widgets.clip_widget, XtParseTranslationTable(resource.main_translations));
03053        /* don't do it for the page list, otherwise mouse customizations will break
03054           the default list bindings too. */
03055        /* XtOverrideTranslations(page_list, XtParseTranslationTable(resource.main_translations)); */
03056     }
03057     /* widgets for which wheel mouse should scroll the drawing area */
03058     if (resource.wheel_unit != 0 && resource.wheel_translations != NULL) {
03059        XtOverrideTranslations(globals.widgets.main_row, XtParseTranslationTable(resource.wheel_translations));
03060        XtOverrideTranslations(tool_bar, XtParseTranslationTable(resource.wheel_translations));
03061        XtOverrideTranslations(globals.widgets.main_window, XtParseTranslationTable(resource.wheel_translations));
03062        XtOverrideTranslations(globals.widgets.draw_widget, XtParseTranslationTable(resource.wheel_translations));
03063 /*     XtOverrideTranslations(globals.widgets.draw_background, XtParseTranslationTable(resource.wheel_translations)); */
03064     }
03065     
03066 #else /* MOTIF */
03067     
03068     globals.widgets.form_widget = XtVaCreateManagedWidget("form", formWidgetClass, globals.widgets.top_level,
03069                                                    XtNdefaultDistance, 0,
03070                                                    NULL);
03071     globals.widgets.vport_widget = XtVaCreateManagedWidget("vport", viewportWidgetClass,
03072                                                     globals.widgets.form_widget,
03073                                                     XtNborderWidth, 0,
03074                                                     XtNtop, XtChainTop,
03075                                                     XtNbottom, XtChainBottom,
03076                                                     XtNleft, XtChainLeft,
03077                                                     XtNright, XtChainRight,
03078                                                     XtNallowHoriz, True,
03079                                                     XtNallowVert, True,
03080                                                     NULL);
03081     globals.widgets.clip_widget = XtNameToWidget(globals.widgets.vport_widget, "clip");
03082     
03083     globals.widgets.draw_widget = XtVaCreateManagedWidget("drawing", drawWidgetClass, globals.widgets.vport_widget,
03084                                                    XtNwidth, globals.page.w,
03085                                                    XtNheight, globals.page.h,
03086                                                    XtNx, 0,
03087                                                    XtNy, 0,
03088                                                    XtNlabel, "",
03089                                                    NULL);
03090     
03091     XtOverrideTranslations(globals.widgets.form_widget, XtParseTranslationTable(base_key_translations));
03092     XtOverrideTranslations(globals.widgets.form_widget, XtParseTranslationTable(base_mouse_translations));
03093     XtOverrideTranslations(globals.widgets.form_widget, XtParseTranslationTable(default_key_translations));
03094     XtOverrideTranslations(globals.widgets.form_widget, XtParseTranslationTable(default_mouse_translations));
03095     
03096     if (resource.wheel_unit != 0 && resource.wheel_translations != NULL)
03097        XtOverrideTranslations(globals.widgets.form_widget, XtParseTranslationTable(resource.wheel_translations));
03098 
03099     if (resource.main_translations != NULL) {
03100        XtOverrideTranslations(globals.widgets.form_widget, XtParseTranslationTable(resource.main_translations));
03101     }
03102     
03103     
03104     /* set background colors of the drawing widget */
03105     XtVaSetValues(globals.widgets.draw_widget, XtNbackground, resource.back_Pixel, NULL);
03106     
03107 #if !FIXED_FLUSHING_PAGING
03108     XtVaSetValues(globals.widgets.clip_widget, XtNbackground, resource.back_Pixel, NULL);
03109 #endif
03110 
03111     /* initialize add_w with width of button panel */
03112     if ((resource.expert_mode & XPRT_SHOW_BUTTONS) != 0)
03113        create_menu_buttons(globals.widgets.form_widget, add_w);
03114     else
03115        *add_w = 0;
03116 #endif /* MOTIF */
03117 
03118     /* activate expert mode and related settings */
03119     toggle_statusline();
03120     toggle_scrollbars();
03121 #ifdef MOTIF
03122     toggle_pagelist();
03123     toggle_toolbar();
03124     toggle_menubar();
03125 #else
03126     toggle_buttons();
03127 #endif
03128 
03129 #ifdef MOTIF
03130     *add_w = 0;
03131     if (resource.expert_mode & XPRT_SHOW_PAGELIST)
03132        *add_w += xm_get_width(page_list);
03133 /*      if (globals.widgets.y_bar != NULL) */
03134 /*     add_w += xm_get_width(globals.widgets.y_bar); */
03135     *add_h = 0;
03136     if (resource.expert_mode & XPRT_SHOW_MENUBAR)
03137        *add_h += xm_get_height(globals.widgets.menu_bar);
03138     if (resource.expert_mode & XPRT_SHOW_TOOLBAR)
03139        *add_h += xm_get_height(tool_bar);
03140     if (resource.expert_mode & XPRT_SHOW_STATUSLINE)
03141        *add_h += xm_get_height(status_line);
03142 /*      if (globals.widgets.x_bar != NULL) */
03143 /*     add_h += xm_get_width(globals.widgets.x_bar); */
03144 #else
03145     /* add_w has been initialized by create_menu_buttons() call above */
03146     *add_h = 0;
03147 #endif
03148 }
03149 
03150 
03151 static void
03152 realize_widgets(Dimension main_win_w, Dimension main_win_h, int add_w)
03153 {    
03154     /*
03155      * Realize the widgets (or windows).
03156      */
03157 
03158 #ifndef MOTIF
03159     if ((resource.expert_mode & XPRT_SHOW_BUTTONS) != 0) {
03160        set_button_panel_height(main_win_h);
03161     }
03162 #endif
03163     XtAddEventHandler(
03164 #ifdef MOTIF
03165                     globals.widgets.clip_widget,
03166 #else
03167                     globals.widgets.vport_widget,
03168 #endif
03169                     StructureNotifyMask, False,
03170                     handle_resize, (XtPointer) NULL);
03171     
03172     XtAddEventHandler(globals.widgets.top_level, PropertyChangeMask, False,
03173                     handle_property_change, (XtPointer) NULL);
03174     XtAddEventHandler(globals.widgets.draw_widget, ExposureMask, False, handle_expose,
03175                     (XtPointer) &mane);
03176     XtRealizeWidget(globals.widgets.top_level);
03177 
03178     mainDeleteWindow = XInternAtom(DISP, "WM_DELETE_WINDOW", False);
03179 
03180 #ifdef MOTIF
03181     /* for Xaw, event handlers for scrollbars are added inside get_geom(), events.c */
03182     ASSERT(globals.widgets.x_bar != NULL, "");
03183     ASSERT(globals.widgets.y_bar != NULL, "");
03184     XtAddEventHandler(globals.widgets.x_bar, ButtonPressMask | ButtonReleaseMask, False, handle_x_scroll, NULL);
03185     XtAddEventHandler(globals.widgets.y_bar, ButtonPressMask | ButtonReleaseMask, False, handle_y_scroll, NULL);
03186     XmAddWMProtocolCallback(globals.widgets.top_level, mainDeleteWindow, xdvi_exit_callback, NULL);
03187 #else
03188     wmProtocols = XInternAtom(DISP, "WM_PROTOCOLS", False);
03189     XSetWMProtocols(DISP, XtWindow(globals.widgets.top_level), &mainDeleteWindow, 1);
03190     XtAddEventHandler(globals.widgets.top_level, NoEventMask, True, handle_delete_message, NULL);
03191 #endif
03192     
03193     /* check whether we want to run in fullscreen mode */
03194     if (resource.fullscreen) {
03195        reconfigure_window(resource.fullscreen, main_win_w + add_w, main_win_h, False);
03196     }
03197 
03198 #ifdef MOTIF
03199     XmProcessTraversal(globals.widgets.draw_widget, XmTRAVERSE_CURRENT);
03200     TRACE_GUI((stderr, "toplevel: %p", (void *)globals.widgets.top_level));
03201     create_tips(globals.widgets.top_level);
03202 #else
03203     if ((resource.expert_mode & XPRT_SHOW_STATUSLINE) != 0) {
03204        create_statusline();
03205     }
03206 #endif
03207 
03208     currwin.win = mane.win = XtWindow(globals.widgets.draw_widget);
03209 
03210     {
03211        XWindowAttributes attrs;
03212 
03213        (void)XGetWindowAttributes(DISP, mane.win, &attrs);
03214        G_backing_store = attrs.backing_store;
03215     }
03216 
03217 #ifdef HAVE_X11_XMU_EDITRES_H
03218     /*
03219      * Enable editres protocol (see "man editres").
03220      * Usually will need to add -lXmu to the linker line as well.
03221      */
03222     XtAddEventHandler(globals.widgets.top_level, (EventMask)0, True, _XEditResCheckMessages,
03223                     (XtPointer)NULL);
03224 #endif
03225 }
03226 
03227 /*
03228  * Create colors and GCs.
03229  * In color mode, color changes affect globals.gc.fore, globals.gc.fore2,
03230  * and globals.gc.rule, but not globals.gc.copy or globals.gc.high.
03231  */
03232 static void
03233 create_gcs(void)
03234 {
03235     
03236 #if GREY
03237     if (resource.gamma == 0.0)
03238        resource.gamma = 1.0;
03239 #endif
03240 
03241     if (!resource.rule_color)
03242        resource.rule_pixel = resource.fore_Pixel;
03243 
03244 #if !COLOR
03245 
03246 #if GREY
03247     if (resource.use_grey)
03248        init_pix();
03249     else
03250 #endif
03251        { /* not #defined GREY, or not resource.use_grey */
03252            XGCValues values;
03253            Pixel set_bits = (Pixel) (resource.fore_Pixel & ~resource.back_Pixel);
03254            Pixel clr_bits = (Pixel) (resource.back_Pixel & ~resource.fore_Pixel);
03255            Boolean copy_tmp = resource.copy;
03256            
03257            globals.gc.copy = set_or_make_gc(NULL, GXcopy, resource.fore_Pixel, resource.back_Pixel);
03258            if (copy_tmp || (set_bits && clr_bits)) {
03259               globals.gc.rule = globals.gc.copy;
03260               if (!resource.thorough)
03261                   copy_tmp = True;
03262            }
03263            if (copy_tmp) {
03264               globals.gc.fore = globals.gc.rule;
03265               if (!resource.copy) {
03266                   warn_overstrike();
03267               }
03268            }
03269            else {
03270               if (set_bits) {
03271                   globals.gc.fore = set_or_make_gc(NULL, GXor, set_bits, 0);
03272               }
03273               if (clr_bits || !set_bits)
03274                   *(globals.gc.fore ? &globals.gc.fore2 : &globals.gc.fore) = set_or_make_gc(NULL, GXandInverted, clr_bits, 0);
03275               if (!globals.gc.rule)
03276                   globals.gc.rule = globals.gc.fore;
03277            }
03278        }
03279 #endif /* !COLOR */
03280     
03281     {
03282        Pixel link_pix, visited_link_pix;
03283        get_link_colors(&link_pix, &visited_link_pix);
03284        globals.gc.linkcolor = set_or_make_gc(NULL, GXcopy, link_pix, resource.back_Pixel);
03285        globals.gc.visited_linkcolor = set_or_make_gc(NULL, GXcopy, visited_link_pix, resource.back_Pixel);
03286     }
03287        
03288 #if COLOR
03289     /* Not affected by color changes.  */
03290     globals.gc.copy = set_or_make_gc(NULL, GXcopy, resource.fore_Pixel, resource.back_Pixel);
03291 #endif
03292     globals.gc.high = set_or_make_gc(NULL, GXcopy, resource.hl_Pixel, resource.back_Pixel);
03293     
03294     globals.gc.ruler = set_or_make_gc(NULL, GXcopy, resource.rule_pixel, resource.fore_Pixel);
03295     
03296 #if XAW
03297     /*
03298      * There's a bug in the Xaw toolkit, in which it uses the
03299      * DefaultGCOfScreen to do vertical scrolling in the Text widget.
03300      * This leads to a BadMatch error if our visual is not the default one.
03301      * The following kludge works around this.
03302      */
03303     DefaultGCOfScreen(SCRN) = globals.gc.copy;
03304 #endif
03305 }
03306 
03307 static void
03308 do_fork(void)
03309 {
03310     TRACE_CLIENT((stderr, "no other instance of xdvi found, forking ..."));
03311     /*
03312      * No suitable xdvi found, so we start one by
03313      * self-backgrounding.
03314      */
03315     /* flush output buffers to avoid double buffering (i.e. data
03316        waiting in the output buffer being written twice, by the parent
03317        and the child) */
03318     fflush(stdout);
03319     fflush(stderr);
03320     XFlush(DISP);
03321     if (fork())      /* if initial process (do NOT use vfork()!) */
03322        _exit(0);
03323 }
03324 
03325 #if defined(MOTIF) && defined(USE_PANNER) && USE_XAW_PANNER
03326 static void 
03327 panner_cb(Widget widget, XtPointer closure, XtPointer report_ptr)
03328 {
03329     fprintf(stderr, "panner_cb called!\n");
03330 }
03331 #endif
03332 
03333 
03334 static XtIntervalId m_font_popup_id = 0;
03335 static Widget m_font_popup = 0;
03336 
03337 static void
03338 remove_font_popup(XtPointer client_data, XtIntervalId *id)
03339 {
03340     UNUSED(client_data);
03341     UNUSED(id);
03342 
03343     if (m_font_popup != 0) {
03344        kill_message_window(m_font_popup);
03345     }
03346 }
03347 
03348 static void
03349 remove_font_popup_exit_cb(XtPointer arg)
03350 {
03351     UNUSED(arg);
03352     xdvi_exit(EXIT_SUCCESS);
03353 }
03354 
03355 static void
03356 create_font_popup(XtPointer client_data, XtIntervalId *id)
03357 {
03358     int *curr_timeout = (int *)client_data;
03359     static int new_timeout = 0;
03360     
03361     UNUSED(client_data);
03362     UNUSED(id);
03363     
03364     if (m_font_popup_id) {
03365        if (*curr_timeout > 0) {
03366            XtRemoveTimeOut(m_font_popup_id);
03367            m_font_popup_id = XtAppAddTimeOut(app, *curr_timeout, create_font_popup, (XtPointer)&new_timeout);
03368        }
03369        else {
03370            m_font_popup = choice_dialog(globals.widgets.top_level,
03371                                     MSG_INFO, NULL,
03372 #ifndef MOTIF                       
03373                                     NULL,
03374 #endif
03375                                     NULL, NULL, /* no pre_callbacks */
03376                                     NULL, NULL, NULL, /* default arguments for `OK' */
03377                                     "Exit Xdvi", remove_font_popup_exit_cb, (XtPointer)NULL,
03378                                     "Loading %s\n(may take some time creating fonts ...)",
03379                                     globals.dvi_name);
03380        }
03381     }
03382 }
03383 
03384 static void
03385 register_font_popup(void)
03386 {
03387     /* Use a two-step process, so that when the timeout is removed by unregister_font_popup(),
03388        it will occur before new_timeout. create_font_popup() will call XtAppAddTimeOut() again
03389        with new_timeout = 0.
03390     */
03391     static int new_timeout = 50;
03392     m_font_popup_id = XtAppAddTimeOut(app, 700, create_font_popup, (XtPointer)&new_timeout);
03393 }
03394 
03395 static void
03396 unregister_font_popup(void)
03397 {
03398     if (m_font_popup_id) {
03399        XtRemoveTimeOut(m_font_popup_id);
03400        m_font_popup_id = 0;
03401        /* FIXME: calling this directly crashes xdvi?? */
03402        /*     m_font_popup_id = XtAppAddTimeOut(app, 1, remove_font_popup, (XtPointer)NULL); */
03403        remove_font_popup(NULL, NULL);
03404     }    
03405 }
03406 
03407 /* initialize global variables with default values. */
03408 static void
03409 init_globals(void) {
03410     globals.program_name = NULL;
03411     globals.dvi_name = NULL;
03412     globals.xdvi_dir = xgetcwd();
03413     globals.orig_locale = NULL;
03414     globals.debug = 0L;
03415     globals.pageno_correct = 1;
03416 
03417     globals.curr_paper = NULL;
03418     globals.curr_editor = NULL;
03419     globals.curr_browser = NULL;
03420     
03421     globals.ev.flags = EV_IDLE;
03422     globals.ev.ctr = 0;
03423     
03424     globals.pausing.num = 0;
03425     globals.pausing.num_save = NULL;
03426     globals.pausing.flag = False;
03427 
03428     globals.win_expose.min_x = 0;
03429     globals.win_expose.max_x = 0;
03430     globals.win_expose.min_y = 0;
03431     globals.win_expose.max_y = 0;
03432 
03433     globals.gc.rule = NULL;
03434     globals.gc.fore = NULL;
03435     globals.gc.inverted = NULL;
03436     globals.gc.high = NULL;
03437     globals.gc.linkcolor = NULL;
03438     globals.gc.visited_linkcolor = NULL;
03439     globals.gc.fore2 = NULL;
03440     globals.gc.fore2_bak = NULL;
03441     globals.gc.fore2_bak1 = NULL;
03442     globals.gc.copy = NULL;
03443     globals.gc.ruler = NULL;
03444     
03445     globals.gc.do_copy = False;
03446     
03447     globals.cursor.flags = 0;
03448 
03449     globals.src.fwd_box_page = -1; /* -1 means no box */
03450     globals.src.fwd_string = NULL;
03451 
03452     globals.widgets.top_level = 0;
03453     globals.widgets.draw_widget = 0;
03454     globals.widgets.draw_background = 0;
03455     globals.widgets.clip_widget = 0;
03456     globals.widgets.x_bar = 0;
03457     globals.widgets.y_bar = 0;
03458 #ifdef MOTIF
03459     globals.widgets.main_window = 0;
03460     globals.widgets.main_row = 0;
03461     globals.widgets.tool_bar = 0;
03462     globals.widgets.top_row = 0;
03463     globals.widgets.menu_bar = 0;
03464 #else
03465     globals.widgets.vport_widget = 0;
03466     globals.widgets.form_widget = 0;
03467     globals.widgets.paned = 0;
03468 #endif
03469 
03470     globals.page.w = 0;
03471     globals.page.h = 0;
03472     globals.page.unshrunk_w = 0;
03473     globals.page.unshrunk_h = 0;
03474     
03475     globals.dvi_file.dirname = NULL;
03476     globals.dvi_file.dirlen = 0;
03477     globals.dvi_file.bak_fp = NULL;
03478     globals.dvi_file.time = 0;
03479 
03480 #if defined(LESSTIF_VERSION)
03481     globals.broken_motif_event_handling = True;
03482 #elif defined(MOTIF) /* was: && XmVersion <= 1002 - better use runtime information:*/
03483     if (xmUseVersion <= 1002)
03484        globals.broken_motif_event_handling = True;
03485     else
03486        globals.broken_motif_event_handling = False;
03487 #else
03488     globals.broken_motif_event_handling = False;
03489 #endif
03490     
03491 }
03492 
03493 /* revert resources */
03494 void
03495 reload_app_resources(void)
03496 {
03497 /*     /\* reset some resources to built-in defaults *\/ */
03498 /*     resource.browser = NULL; */
03499 /*     resource.editor = NULL; */
03500 /*     resource.gamma = 1; */
03501 /*     resource.link_style = 3; */
03502 /*     resource.link_color = LINK_COLOR_FALLBACK; */
03503 /*     resource.visited_link_color = VISITED_LINK_COLOR_FALLBACK; */
03504 /*     resource.expert_mode = 31; */
03505 /*     resource.use_color = True; */
03506 /*     resource.match_highlight_inverted = True; */
03507     
03508     XtGetApplicationResources(globals.widgets.top_level, (XtPointer)&resource,
03509                            application_resources, XtNumber(application_resources),
03510                            (ArgList)NULL, 0);
03511     XtGetApplicationResources(globals.widgets.top_level, (XtPointer)&resource,
03512                            app_pixel_resources, XtNumber(app_pixel_resources),
03513                            (ArgList)NULL, 0);
03514 /*      fprintf(stderr, "gamma: %f\n", resource.gamma); */
03515 }
03516 
03517 struct filehist_info {
03518     int file_idx;
03519     char *page_arg;
03520 };
03521 
03522 
03523 /*
03524  * Unfortunately this must be a callback, for the file selector ...
03525  * This is the second part of Main: Create all widgets, initialize the DVI file,
03526  * and enter the main event loop.
03527  */
03528 static void
03529 run_dvi_file(const char *filename, void *data)
03530 {
03531     Boolean tried_dvi_ext = False;
03532     struct filehist_info *cb = (struct filehist_info *)data;
03533     
03534 #ifdef MOTIF
03535     Widget tool_bar = 0;
03536     Widget form = 0;
03537 #endif
03538 
03539     char *title_name = NULL;
03540     char *icon_name = NULL;
03541     dviErrFlagT errflag = NO_ERROR;
03542     
03543     int add_w, add_h;
03544     Dimension main_win_w, main_win_h;
03545     
03546     UNUSED(data);
03547     ASSERT(filename != NULL, "filename must have been initialized here!");
03548     
03549     globals.dvi_name = xstrdup(filename);
03550     file_history_push(globals.dvi_name);
03551     
03552     TRACE_FILES((stderr, "globals.dvi_name is: |%s| %p\n", globals.dvi_name, globals.dvi_name));
03553 
03554     globals.dvi_file.dirname = get_dir_component(globals.dvi_name);
03555     ASSERT(globals.dvi_file.dirname != NULL, "dvi_name must contain a dir component");
03556     globals.dvi_file.dirlen = strlen(globals.dvi_file.dirname);
03557 
03558     form_dvi_property();
03559     
03560     /*
03561       If `unique' is active, we may need to pass the file
03562       to a different instance of xdvi:
03563     */
03564     if (resource.unique) {
03565        Window w1 = 0, w2 = 0;
03566        if ((w1 = get_xdvi_window_id(True, NULL)) != 0 || (w2 = get_xdvi_window_id(False, NULL)) != 0) {
03567            if (w1 != 0) { /* another xdvi, and same file: reload and raise */
03568               w2 = w1;
03569               set_string_property("", atom_reload(), w2);
03570               set_string_property("", atom_raise(), w2);
03571            }
03572            else { /* another xdvi, and different file: load new file and raise */
03573               set_string_property(globals.dvi_name, atom_newdoc(), w2);
03574               set_string_property("", atom_raise(), w2);
03575            }
03576            if (cb->page_arg != NULL) { /* switch to different page and raise */
03577               if (strlen(cb->page_arg) == 0) /* special case: treat `+' as last page */
03578                   set_string_property("+", atom_newpage(), w2);
03579               else
03580                   set_string_property(cb->page_arg, atom_newpage(), w2);
03581               set_string_property("", atom_raise(), w2);
03582            }
03583            xdvi_exit(EXIT_SUCCESS);
03584        }
03585        else if (resource.src_fork) {
03586            do_fork();
03587        }
03588     }
03589 
03590     /*
03591       Similar for forward search or string search:
03592      */
03593     if (resource.src_pos != NULL || resource.find_string != NULL) {
03594        Window w;
03595        if ((w = get_xdvi_window_id(True, NULL)) != 0) {
03596            /* another instance of xdvi running, displaying the same file */
03597            TRACE_CLIENT((stderr, "Match; changing property of client and exiting ..."));
03598            if (resource.src_pos != NULL)
03599               set_sourceposition_property(resource.src_pos, w);
03600            else
03601               set_stringsearch_property(resource.find_string, w);
03602            xdvi_exit(EXIT_SUCCESS);
03603        }
03604        else if (resource.src_fork) {
03605            do_fork();
03606        }
03607     }
03608 
03609     /* Needed for source specials and for calling ghostscript. */
03610     xputenv("DISPLAY", XDisplayString(DISP));
03611 
03612 
03613     if (globals.debug) {
03614        fprintf(stderr, "%s %s, kpathsea: %s\n", XDVIK_PROGNAME, XDVI_VERSION_INFO, kpathsea_version_string);
03615        fprintf(stderr,
03616               "configured with: ppi=%d shrink=%d mfmode=%s alt_font=%s paper=%s\n",
03617               resource.pixels_per_inch,
03618               currwin.shrinkfactor,
03619               resource.mfmode ? resource.mfmode : "<NONE>",
03620               resource.alt_font,
03621               resource.paper);
03622     }
03623     
03624 #ifdef T1LIB
03625     /* needed so that T1lib can produce tfm's e.g. for cm-super */
03626     kpse_set_program_enabled(kpse_tfm_format, True, kpse_src_compile);
03627 #endif
03628     kpse_set_program_enabled(kpse_any_glyph_format, resource.makepk, kpse_src_compile);
03629     /* janl 16/11/98: I have changed this. The above line used to
03630        say the settings in resource.makepk was supplied on the
03631        commandline, resulting in it overriding _all other_
03632        settings, derived from the environment or texmf.cnf, no
03633        matter what the value. The value in resource.makepk could
03634        be the compile-time default...
03635 
03636        Personaly I like the environment/texmf.cnf to override
03637        resources and thus changed the 'level' of this setting to
03638        kpse_src_compile so the environment/texmf.cnf will override
03639        the values derived by Xt.
03640 
03641        Previous comment here:
03642 
03643        ``Let true values as an X resource/command line override false
03644        values in texmf.cnf/envvar.''  */
03645 
03646     /*
03647      *        Step 2:  Settle colormap issues.  This should be done before
03648      *        other widgets are created, so that they get the right
03649      *        pixel values.  (The top-level widget won't have the right
03650      *        values, but I don't think that makes any difference.)
03651      */
03652     
03653 #ifdef XSERVER_INFO
03654     print_xserver_info();
03655 #endif
03656 
03657     create_colormaps();
03658 
03659     
03660 #ifdef TESTING_OPEN_FILES
03661     fprintf(stderr, "open_max: %ld\n", OPEN_MAX);
03662     for (i = 0; i < OPEN_MAX - 10; i++) {
03663        FILE *fp;
03664        if ((fp = fopen("/tmp/foo", "r")) == NULL) {
03665            perror("fopen");
03666            xdvi_exit(EXIT_FAILURE);
03667        }
03668     }
03669     fprintf(stderr, "opened %d files.\n", i);
03670 #endif
03671     
03672 
03673     /* toolbar code may open files, but we have no check close_a_file() in
03674        the toolbar code; so do this before prescan() possibly opens lots of files.
03675      */
03676 #ifdef MOTIF
03677     globals.widgets.main_row = XmCreateMainWindow(globals.widgets.top_level, "main", NULL, 0);
03678     
03679     create_menu_buttons(globals.widgets.main_row, &globals.widgets.menu_bar);
03680 
03681     /* seems to be needed for enabling `XmNhighlightOnEnter' for the toolbar buttons
03682        - is this the correct place to do it? */
03683     XtVaSetValues(globals.widgets.top_level, XmNkeyboardFocusPolicy, (XtArgVal)XmPOINTER, NULL);
03684 
03685     form = XtVaCreateWidget("form", xmFormWidgetClass, globals.widgets.main_row,
03686                          XmNshadowThickness, 0,
03687                          NULL);
03688 #if defined(USE_PANNER) && USE_XAW_PANNER
03689     panner = XtVaCreateWidget("panner", pannerWidgetClass, form,
03690                            XmNtopAttachment, XmATTACH_FORM,
03691                            XmNleftAttachment, XmATTACH_FORM,
03692                            XmNleftOffset, 20,
03693                            XmNrightAttachment, XmATTACH_OPPOSITE_FORM,
03694                            XmNrightOffset, -resource.pagelist_width + 20,
03695                            XmNtopOffset, 2,
03696                            XmNleftOffset, 2,
03697                            XtNheight, 60,
03698                            XtNwidth, resource.pagelist_width - 50,
03699                            XtNsliderX, 5,
03700                            XtNsliderY, 7,
03701                            XtNinternalSpace, 0,
03702                            XtNshadowThickness, 0,
03703                            NULL);
03704 #endif
03705 #endif
03706 
03707     /* use bounding box for highlighting if our visual isn't TrueColor
03708        (not worth the trouble ...) */
03709     if (G_visual->class != TrueColor) {
03710        resource.match_highlight_inverted = False;
03711     }
03712     
03713     /*
03714      *        Step 3:  Initialize the dvi file and set titles.
03715      */
03716 
03717 #ifdef T1LIB
03718     /*
03719       At this point DISP, G_visual, G_depth and G_colormap must
03720       be defined. Also, init_t1() must go before internal_open_dvi(), since
03721       read_postamble will define some fonts and insert them into
03722       fontmaps_hash, but we need a clean fontmaps_hash for detecting
03723       duplicate entries in the map file.
03724     */
03725 
03726     if (resource.t1lib) {
03727        init_t1();
03728     }
03729 #endif /* T1LIB */
03730 
03731 
03732     setup_signal_handlers();
03733 
03734     /* Notify users that fonts are being created. This is just a hack
03735        and no replacement for true asynchronous font creation (see
03736        EXPERIMENTAL_DELAYED_MTKEXPK in font-open.c for that approach)
03737        since it doesn't give details (is just invoked if startup takes
03738        somewhat longer) and freezes during font creation.
03739     */
03740     register_font_popup();
03741     
03742     /* open and initialize the DVI file, but don't read the fonts yet */
03743     if (!internal_open_dvi(globals.dvi_name, &errflag,
03744 #ifdef EXPERIMENTAL_DELAYED_MTKEXPK
03745                         False
03746 #else
03747                         True
03748 #endif
03749                         )) {
03750        if (tried_dvi_ext)
03751            XDVI_FATAL((stderr, "Could not open %s: %s, and %s.dvi doesn't exist either - exiting.",
03752                      globals.dvi_name, get_dvi_error(errflag), globals.dvi_name));
03753        else
03754            XDVI_FATAL((stderr, "Could not open %s: %s.",
03755                      globals.dvi_name, get_dvi_error(errflag)));
03756     }
03757     
03758     unregister_font_popup();
03759     
03760     if (cb->page_arg != NULL) {
03761        if (cb->page_arg[0] == '\0') { /* empty page_arg -> goto last page */
03762            current_page = total_pages - 1;
03763            page_history_insert(current_page);
03764        }
03765        else {
03766            char *testptr;
03767            current_page = strtoul(cb->page_arg, &testptr, 10) - 1;
03768            if (*testptr != '\0') {
03769               XDVI_FATAL((stderr, "Invalid page number: `%s'.", cb->page_arg));
03770            }
03771            current_page = check_goto_page(current_page);
03772        }
03773     }
03774 
03775     file_history_set_page(current_page);
03776     
03777     ASSERT(globals.dvi_file.bak_fp != NULL, "Backup file pointer must have been initialized here");
03778     if (resource.prescan) {
03779        prescan(globals.dvi_file.bak_fp);
03780     }
03781 
03782     globals.page.unshrunk_w = pageinfo_get_page_width(current_page);
03783     globals.page.unshrunk_h = pageinfo_get_page_height(current_page);
03784     TRACE_FILES((stderr, "globals.page.unshrunk_w: %d, h: %d; window: %d, %d",
03785                globals.page.unshrunk_w, globals.page.unshrunk_h,
03786                pageinfo_get_window_width(current_page),
03787                pageinfo_get_window_height(current_page)));
03788     
03789     init_page();
03790 
03791     /*
03792      *        Step 4:  Create widgets, and set initial window size.
03793      */
03794 
03795     /* currently these override expert mode - using this is deprecated
03796        in favour of `-expertmode'; inform user about this: */
03797     if (resource.statusline) {
03798        XDVI_WARNING((stderr, "The option/X resource `statusline' is obsolete; "
03799                     "use `-expertmode <flag>' instead, e.g. `-expertmode 1'\n"
03800                     "to switch on the status line, or `-expertmode 6'\n"
03801                     "to switch it off. See the xdvi man page for details."));
03802        resource.expert_mode |= XPRT_SHOW_STATUSLINE;
03803     }
03804 
03805 /*      XtRealizeWidget(globals.widgets.top_level); */
03806 
03807 #ifdef MOTIF
03808     tool_bar = create_toolbar(globals.widgets.main_row, globals.widgets.menu_bar);
03809 #endif
03810 
03811     create_widgets(
03812 #ifdef MOTIF
03813                  tool_bar, form,
03814 #endif
03815                  &add_w, &add_h);
03816 
03817     /*  fprintf(stderr, "geometry xdvirc: |%s|, orig: |%s|\n", resource.xdvirc_geometry, resource.geometry); */
03818     
03819 
03820     /*
03821      * Set initial window size.
03822      * This needs to be done before colors are assigned because if
03823      * -s 0 is specified, we need to compute the shrink factor
03824      * (which in turn affects whether init_pix is called).
03825      */
03826     set_windowsize(&main_win_w, &main_win_h, add_w, add_h, False);
03827 
03828     realize_widgets(main_win_w, main_win_h, add_w);
03829 
03830     /* this needs to be done after total_pages is known (via internal_open_dvi) */
03831     get_icon_and_title(globals.dvi_name, &icon_name, &title_name);
03832     add_icon(globals.widgets.top_level, title_name, icon_name);
03833     /* this needs to be done after the widgets have been created */
03834     set_icon_and_title(icon_name, title_name);
03835     free(icon_name);
03836     free(title_name);
03837     icon_name = title_name = NULL;
03838 
03839     
03840     G_image = XCreateImage(DISP, G_visual, 1, XYBitmap, 0,
03841                         (char *)NULL, 0, 0, BMBITS, 0);
03842     G_image->bitmap_unit = BMBITS;
03843 #ifdef WORDS_BIGENDIAN
03844     G_image->bitmap_bit_order = MSBFirst;
03845 #else
03846     G_image->bitmap_bit_order = LSBFirst;
03847 #endif
03848     {
03849        short endian = MSBFirst << 8 | LSBFirst;
03850        G_image->byte_order = *((char *)&endian);
03851     }
03852 
03853     /* Store window id for use by src_client_check().  */
03854     {
03855 #ifndef WORD64
03856        xuint32 data = XtWindow(globals.widgets.top_level);
03857        XChangeProperty(DISP, DefaultRootWindow(DISP),
03858                      atom_xdvi_windows(), atom_xdvi_windows(), 32,
03859                      PropModePrepend, (unsigned char *)&data, 1);
03860 #else
03861        unsigned char data[4];
03862        set_window_id(XtWindow(globals.widgets.top_level), data);
03863        XChangeProperty(DISP, DefaultRootWindow(DISP),
03864                      atom_xdvi_windows(), atom_xdvi_windows(), 32,
03865                      PropModePrepend, data, 1);
03866 #endif
03867        set_dvi_property();
03868     }
03869 
03870     /*
03871      * Step 5:  Assign colors and GCs.
03872      *         Because of the latter, this has to go after the widgets are realized.
03873      */
03874 
03875     create_gcs();
03876 
03877     create_cursors();
03878 
03879 #ifdef EXPERIMENTAL_DELAYED_MTKEXPK
03880     /* Only now, we initialize the fonts. First update the window: */
03881     force_statusline_update();
03882     printlog_create("test", "Close", NULL, NULL, NULL, NULL);
03883     printlog_popup();
03884     
03885     printlog_append_str("\nTrying to create font(s)\n");
03886     if (!find_postamble(globals.dvi_file.bak_fp, &errflag) || !read_postamble(globals.dvi_file.bak_fp, &errflag, True)) {
03887        XDVI_ERROR((stderr, "Couldn't read fonts from postamble: %s\n", get_dvi_error(errflag)));
03888     }
03889 #endif /* EXPERIMENTAL_DELAYED_MTKEXPK */
03890     
03891 #ifdef MOTIF
03892 #if defined(USE_PANNER) && USE_XAW_PANNER
03893     XtVaSetValues(panner, XtNsliderWidth, globals.page.w / 2,
03894                 XtNsliderHeight, globals.page.h / 2,
03895                 XtNcanvasWidth, globals.page.w,
03896                 XtNcanvasHeight, globals.page.h,
03897                 NULL);
03898     XtManageChild(panner);
03899     XtAddCallback(panner, XtNreportCallback, panner_cb, (XtPointer)NULL);
03900 #endif
03901     create_pagelist();
03902 #endif
03903 
03904     /* trigger forward search */
03905     do_forward_search(resource.src_pos);
03906 
03907     /* trigger string search */
03908     if (resource.find_string != NULL) {
03909        globals.ev.flags |= EV_FIND;
03910     }
03911 
03912     /* trigger anchor search */
03913     if (resource.anchor_pos != NULL) {
03914        g_anchor_pos = xstrdup(resource.anchor_pos);
03915        g_anchor_len = strlen(g_anchor_pos);
03916        globals.ev.flags |= EV_ANCHOR;
03917     }
03918 
03919 #if defined(MOTIF) && HAVE_XPM
03920     tb_check_navigation_sensitivity(current_page);
03921 #endif
03922 
03923 #if CHECK_APP_FILEVERSION
03924     check_app_defaults_fileversion();
03925 #endif
03926 
03927     /* can do this only after scrollbars have been realized */
03928     if (!BROKEN_RECONFIG && (resource.expert_mode & XPRT_SHOW_SCROLLBARS) == 0) {
03929        toggle_scrollbars();
03930     }
03931 
03932     /* initialize file watching */
03933     if (resource.watch_file > 0.0) {
03934 #if XDVI_XT_TIMER_HACK
03935        watch_file_cb(NULL, NULL);
03936 #else
03937        XDVI_WARNING((stderr, "Could not redefine XtAppAddTimeOut(); `watchfile' not available."));
03938 #endif
03939     }
03940 
03941     /* raise `early' message windows */
03942     raise_message_windows();
03943 
03944     if (resource.mouse_mode == MOUSE_RULER_MODE) {
03945        show_ruler(NULL);
03946     }
03947     
03948     /* insert this page into the history */
03949     globals.ev.flags |= EV_PAGEHIST_INSERT;
03950     
03951     do_pages();
03952 }
03953 
03954 static char *
03955 is_good_dvi_file(const char *filename, Boolean from_history)
03956 {
03957     static char canonical_path[MAXPATHLEN + 1];
03958     Boolean tried_dvi_extension = False;
03959     /* following allocates real_filename */
03960     char *real_filename = find_dvi_file(filename, &tried_dvi_extension, from_history);
03961     char *ret;
03962     FILE *f = NULL;
03963     dviErrFlagT errflag;
03964        
03965     if (real_filename == NULL)
03966        return NULL;
03967     
03968     ret = REALPATH(real_filename, canonical_path);
03969     free(real_filename);
03970 
03971     /* check for correct DVI files */
03972     if ((f = XFOPEN(ret, OPEN_MODE)) != NULL) {
03973        TRACE_EVENTS((stderr, "watching: new file opened successfully."));
03974        if (process_preamble(f, &errflag)
03975            && find_postamble(f, &errflag)
03976            && read_postamble(f, &errflag, False)) {
03977            fclose(f);
03978            return ret;
03979        }
03980        fclose(f);
03981        if (!from_history)
03982            XDVI_FATAL((stderr, "%s: %s.", filename, get_dvi_error(errflag)));
03983        return NULL;
03984     }
03985     else {
03986        if (!from_history)
03987            XDVI_FATAL((stderr, "Could not open `%s': %s.", filename, strerror(errno)));
03988        return NULL;
03989     }
03990 }
03991 
03992 static char *
03993 get_filename_from_history(int *pageno)
03994 {
03995     size_t i;
03996     /* loop through history, trying to get a good file */
03997     for (i = 0; i < file_history_size(); i++) {
03998        char *ret, *test;
03999        
04000        if ((test = file_history_get_elem(i, pageno)) == NULL)
04001            return NULL;
04002        TRACE_FILES((stderr, "HISTORY %lu: |%s|", (unsigned long)i, test));
04003        if ((ret = is_good_dvi_file(test, True)) != NULL) {
04004            TRACE_FILES((stderr, "SUCCESS: |%s|", test));
04005            return ret;
04006        }
04007     }
04008     return NULL;
04009 }
04010 
04011 
04012 /*
04013   ************************************************************
04014   ************************************************************
04015                      main routine
04016   ************************************************************
04017   ************************************************************
04018 */
04019 
04020 int
04021 main(int argc, char **argv)
04022 {
04023     int i;
04024     static struct filehist_info info;
04025     const char *file_name = NULL;
04026     const char *file_name2 = NULL;
04027     
04028     /* Hack to have command-line options override ~/.xdvirc stuff:
04029      * Parse and merge them again from argv_bak, a copy of the command-line options,
04030      * via XrmParseCommand(). I think the only alternative would be to merge in all
04031      * resources manually instead of using XtInitialize(), similar to what's done in gv,
04032      * but that looks like too much trouble.
04033      */
04034 #define COMMANDLINE_OVERRIDE_HACK 1
04035     
04036 #if COMMANDLINE_OVERRIDE_HACK
04037     int argc_bak;
04038     char **argv_bak;
04039 #endif
04040 
04041     info.file_idx = 0;
04042     info.page_arg = NULL;
04043     
04044     /* BEGIN_TIMER_LOOP; */
04045     
04046     init_globals();
04047     
04048     /*
04049      *      Step 1:  Process command-line options and resources.
04050      */
04051 
04052     globals.program_name = xstrdup(argv[0]);
04053     {   /* get filename from program_name if it contains a path */
04054        char sep;
04055        char *ptr;
04056 #ifdef VMS
04057        sep = ']';
04058 #else
04059        sep = '/';
04060 #endif
04061        if ((ptr = strrchr(globals.program_name, sep)) != NULL) {
04062            globals.program_name = ++ptr;
04063        }
04064 #ifdef VMS
04065        if ((ptr = strchr(globals.program_name, '.')) != NULL)
04066            *ptr = '\0';
04067 #endif
04068     }
04069 
04070 #if COMMANDLINE_OVERRIDE_HACK
04071     /* create a copy of argv[] */
04072     argc_bak = argc;
04073     argv_bak = xmalloc((1 + argc_bak) * sizeof *argv_bak);
04074     for (i = 0; i < argc_bak; i++) {
04075        argv_bak[i] = xstrdup(argv[i]);
04076     }
04077     argv_bak[i] = NULL;
04078 #endif
04079 
04080     /*
04081       Arguments that need to be checked early, like `help', `version' and `sync'.
04082       The former don't even require an X connection.
04083     */
04084     check_early_arguments(argc, argv);
04085     
04086     warn_about_prerelease_versions();
04087 
04088     /* We need to set up SIGALRM before calling XtAppAddTimeOut() (inside sfSelFile, or
04089        called from XtInitialize() in Motif), else and we'll die with the error message
04090        `Alarm clock'. However, we mustn't install SIGPOLL before the forking is done
04091        below, else xdvi may hang forever waiting for input. So the signal handler setup
04092        is split in 2 parts: setup_sigalarm(), and setup_signal_handlers() below.
04093     */
04094     setup_sigalarm();
04095 
04096     /* get the debug value (if any) from the environment
04097        (it's too early to get it from the command line) */
04098     globals.debug = parse_debugging_option(getenv("XDVIDEBUG"));
04099 
04100     /* to make input of non-latin characters work */
04101     XtSetLanguageProc(NULL, (XtLanguageProc)NULL, NULL);
04102     globals.widgets.top_level = XtInitialize(globals.program_name, "XDvi", options, XtNumber(options),
04103                                         &argc, argv);
04104 
04105     app = XtWidgetToApplicationContext(globals.widgets.top_level);
04106     
04107     XtAppAddActions(app, get_actions(), get_num_actions());
04108 
04109     create_magnifier();
04110 
04111     if ((globals.orig_locale = setlocale(LC_ALL, "")) != NULL)
04112        globals.orig_locale = xstrdup(globals.orig_locale); /* note: never free'd */
04113     else /* fallback */
04114        globals.orig_locale = xstrdup(setlocale(LC_ALL, NULL));
04115     
04116     /* Override LC_NUMERIC, else sscanf(), strtod() etc. will stop working on floats
04117        inside specials for locales like LANG=de_DE which uses `,' not `.'
04118        as fractional part separator. (Strangely, using
04119          LC_CTYPE | LC_COLLATE 
04120        above doesn't work?)
04121        Regression:
04122        xdvik/regression/special-pics/pictest.dvi
04123     */
04124     setlocale(LC_NUMERIC, "C");
04125 
04126     /* at this point, all known options will have been consumed; so the
04127        only ones remaining should be: +pageno, and the dvi name. Exit with
04128        usage message if this is not the case. The following rather complicated
04129        looping logic ensures that the first unknown option is regarded as dvi_name,
04130        unless it's followed by another option, in which case it will result in an
04131        `Unrecognized option' error.
04132     */
04133     for (i = 0; i < argc - 1; i++) { /* argc - 1 because we're going to look at
04134                                    argv[i + 1] to skip argv[0] */
04135        if (*(argv[i + 1]) == '+') {
04136            if (info.page_arg != NULL) {
04137               XDVI_ERROR((stderr, "Unrecognized option `%s'.", argv[i + 1]));
04138               usage(EXIT_FAILURE);
04139            }
04140            else {
04141               info.page_arg = argv[i + 1] + 1;
04142            }
04143        }
04144        else if (file_name == NULL) {
04145            file_name = xstrdup(argv[i + 1]); /* LEAK */
04146        }
04147        else {
04148            XDVI_ERROR((stderr, "Unrecognized option `%s'.", argv[i]));
04149            usage(EXIT_FAILURE);
04150        }
04151     }
04152 
04153     DISP = XtDisplay(globals.widgets.top_level);
04154     SCRN = XtScreen(globals.widgets.top_level);
04155 
04156 #ifdef GREY
04157     XtSetTypeConverter(XtRString, XtRBool3, XdviCvtStringToBool3,
04158                      NULL, 0, XtCacheNone, NULL);
04159 #endif
04160 
04161 #ifdef MOTIF
04162     /* we'll take care of that ourselves */
04163     XtVaSetValues(globals.widgets.top_level, XmNdeleteResponse, XmDO_NOTHING, NULL);
04164     
04165     {
04166        /* Hack to work around #884290 (drag&drop freezes file selector, see comment
04167           in xm_filesel.c): Disable drag&drop altogether (we don't need it).
04168           Could also be done via Xdefaults as follows:
04169           XDvi*dragInitiatorProtocolStyle: XmDRAG_NONE
04170           XDvi*dragReceiverProtocolStyle:  XmDRAG_NONE
04171        */
04172        Widget display = XmGetXmDisplay(DISP);
04173        XtVaSetValues(display,
04174                     XmNdragInitiatorProtocolStyle, XmDRAG_NONE,
04175                     XmNdragReceiverProtocolStyle,  XmDRAG_NONE,
04176                     NULL);
04177     }
04178 #else
04179     G_accels_cr = XtParseAcceleratorTable("<Key>Return:set()notify()unset()\n"
04180                                      "<Key>q:set()notify()unset()\n"
04181                                      "<Key>Escape: set()notify()unset()");
04182 #endif
04183 
04184     /* get the no_init_file resource first: This needs to be done
04185      * before the call to XtGetApplicationResources() below, which populates
04186      * the `resource' struct with the actual application resources (which
04187      * may be merged from ~/.xdvirc). */
04188     XtGetApplicationResources(globals.widgets.top_level, (XtPointer)&resource,
04189                            xdvirc_resources, XtNumber(xdvirc_resources),
04190                            (ArgList)NULL, 0);
04191 
04192     if (!resource.no_init_file) { /* Read user preferences from ~/.xdvirc. */
04193        read_user_preferences(globals.widgets.top_level, ".xdvirc");
04194     }
04195 
04196 #if COMMANDLINE_OVERRIDE_HACK /* see above */
04197     {
04198        XrmDatabase cmdline_db = XrmGetDatabase(DISP);
04199        XrmParseCommand(&cmdline_db, options, XtNumber(options),
04200                      "xdvi", &argc_bak, argv_bak);
04201 
04202        for (i = 0; i < argc_bak; i++) {
04203            free(argv_bak[i]);
04204        }
04205        free(argv_bak);
04206        argc_bak = 0;
04207     }
04208 #endif /* COMMANDLINE_OVERRIDE_HACK */
04209     
04210     XtGetApplicationResources(globals.widgets.top_level, (XtPointer)&resource,
04211                            application_resources, XtNumber(application_resources),
04212                            (ArgList)NULL, 0);
04213 
04214     if (resource.shrinkfactor == 0) /* protect against division by 0 */
04215        resource.shrinkfactor = 1;
04216     currwin.shrinkfactor = resource.shrinkfactor;
04217     globals.curr_use_color = resource.use_color;
04218     globals.curr_gamma = resource.gamma;
04219     globals.curr_paper = xstrdup(resource.paper); /* never free()d */
04220     globals.curr_editor = NULL;
04221     globals.curr_browser = NULL;
04222     
04223     /* Initialize `globals.debug' as early as possible.  Note: earlier
04224      * calls to TRACE_* or tests for `if (globals.debug)' will only work if the
04225      * XDVIDEBUG environment variable is set!
04226      */
04227     globals.debug |= parse_debugging_option(resource.debug_arg);
04228     kpathsea_debug = globals.debug / DBG_STAT;
04229 
04230     if (globals.debug)
04231        fprintf(stderr, "KPATHSEA_DEBUG = %d\n", kpathsea_debug);
04232 
04233     kpse_init_prog("XDVI", resource.pixels_per_inch, resource.mfmode, resource.alt_font);
04234     
04235     kpse_set_program_name(argv[0], "xdvi");
04236 
04237     
04238     if (globals.debug & DBG_EXPAND) {
04239        const char *texmfcnf = kpse_path_expand("$TEXMFCNF");
04240        const char *texmfmain = kpse_path_expand("$TEXMFMAIN");
04241        fprintf(stderr, "\n%s:%d: KPATHSEA variables:\n", __FILE__, __LINE__);
04242        fprintf(stderr, "%s:%d: SELFAUTOLOC=\"%s\"\n", __FILE__, __LINE__, getenv("SELFAUTOLOC"));
04243        fprintf(stderr, "%s:%d: SELFAUTODIR=\"%s\"\n", __FILE__, __LINE__, getenv("SELFAUTODIR"));
04244        fprintf(stderr, "%s:%d: SELFAUTOPARENT=\"%s\"\n", __FILE__, __LINE__, getenv("SELFAUTOPARENT"));
04245        fprintf(stderr, "%s:%d: TEXMFCNF=\"%s\"\n", __FILE__, __LINE__, texmfcnf);
04246        fprintf(stderr, "%s:%d: TEXMFMAIN=\"%s\"\n\n", __FILE__, __LINE__, texmfmain);
04247     }
04248     
04249     if (resource.regression) {
04250        /* currently it just turns on everything; what we'd like here is
04251           output that's usable for automatic diffs (e.g. independent
04252           of window manager state) */
04253        globals.debug = DBG_ALL;
04254     }
04255 
04256     /* Check early for whether to pass off to a different xdvi process
04257      * (-sourceposition argument for reverse source special lookup).
04258      */
04259     property_initialize();
04260 
04261 #if 0 /*  def RGB_ANTI_ALIASING */
04262     /* error checking and setting of resources according to command line arguments */
04263     if (resource.sub_pixels != NULL && memicmp(resource.sub_pixels, "unknown", 4) == 0) {
04264 #ifdef __GNUC__
04265 #warning TODO: implement callbacks
04266 #endif
04267        choice_dialog_sized(globals.widgets.top_level,
04268                          MSG_QUESTION,
04269                          SIZE_MEDIUM,
04270                          NULL,
04271 #ifndef MOTIF
04272                          NULL, /* TODO: xaw ret_action_str */
04273 #endif
04274                          NULL, NULL, /* pre callback */
04275                          "Enable", NULL, NULL,
04276                          "Disable", NULL, NULL,
04277                          "This version of xdvi can optimize the anti-aliased font display "
04278                          "when running on an LCD monitor, such as a notebook screen or a TFT flat screen."
04279                          "\n\n"
04280                          "If you are using such a monitor, click `Enable' to enable optimized display; otherwise click `Disable'."
04281                          "\n\n"
04282                          "You can change this setting later via the Menu `Options -> Anti-Aliasing'.");
04283        /* enter event loop */
04284        do_pages();
04285     }
04286     else {
04287 #endif
04288        init_check_resources();
04289 
04290        TRACE_FILES((stderr, "file history: |%s|", resource.file_history));
04291        file_history_init();
04292 
04293        if (file_name == NULL) { /* no filename argument */
04294 
04295            if (resource.no_file_arg_use_history) {
04296               static char buf[LENGTH_OF_INT]; /* so that we can pass its address */
04297               int pageno;
04298               if ((file_name = get_filename_from_history(&pageno)) != NULL) {
04299                   SNPRINTF(buf, LENGTH_OF_INT, "%d", pageno + 1); /* pageno is 0-based */
04300                   info.page_arg = buf;
04301               }
04302            }
04303 
04304            TRACE_FILES((stderr, "got from history: |%s|", file_name));
04305        
04306            if (file_name != NULL) {
04307               run_dvi_file(file_name, &info);
04308            }
04309            else { /* get filename from file selector */
04310               static struct filesel_callback cb; /* static so that we can pass its address */
04311               cb.title = "Xdvi: Open file";
04312               cb.prompt = "Open file:";
04313               cb.ok = "OK";
04314               cb.cancel = "Cancel";
04315               cb.init_path = NULL;
04316               cb.filemask = "*.dvi";
04317               cb.must_exist = True;
04318               cb.exit_on_cancel = True;
04319               cb.func_ptr = run_dvi_file;
04320               cb.data = &info;
04321 
04322               XsraSelFile(globals.widgets.top_level, &cb);
04323               /* enter event loop */
04324               do_pages();
04325            }
04326        }
04327        else if ((file_name2 = is_good_dvi_file(file_name, False)) != NULL) {
04328            run_dvi_file(file_name2, &info);
04329        }
04330 #if 0 /*  def RGB_ANTI_ALIASING */
04331     }
04332 #endif
04333     /* notreached */
04334     return 0;
04335 }
04336 
04337