1f80a6dcdSmrg/*
2f80a6dcdSmrg
3f80a6dcdSmrgCopyright (c) 1991  X Consortium
4f80a6dcdSmrg
5f80a6dcdSmrgPermission is hereby granted, free of charge, to any person obtaining
6f80a6dcdSmrga copy of this software and associated documentation files (the
7f80a6dcdSmrg"Software"), to deal in the Software without restriction, including
8f80a6dcdSmrgwithout limitation the rights to use, copy, modify, merge, publish,
9f80a6dcdSmrgdistribute, sublicense, and/or sell copies of the Software, and to
10f80a6dcdSmrgpermit persons to whom the Software is furnished to do so, subject to
11f80a6dcdSmrgthe following conditions:
12f80a6dcdSmrg
13f80a6dcdSmrgThe above copyright notice and this permission notice shall be included
14f80a6dcdSmrgin all copies or substantial portions of the Software.
15f80a6dcdSmrg
16f80a6dcdSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17f80a6dcdSmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18f80a6dcdSmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19f80a6dcdSmrgIN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
20f80a6dcdSmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21f80a6dcdSmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22f80a6dcdSmrgOTHER DEALINGS IN THE SOFTWARE.
23f80a6dcdSmrg
24f80a6dcdSmrgExcept as contained in this notice, the name of the X Consortium shall
25f80a6dcdSmrgnot be used in advertising or otherwise to promote the sale, use or
26f80a6dcdSmrgother dealings in this Software without prior written authorization
27f80a6dcdSmrgfrom the X Consortium.
28f80a6dcdSmrg
29f80a6dcdSmrg*/
30f80a6dcdSmrg
31f80a6dcdSmrg
32f80a6dcdSmrg/*
33f80a6dcdSmrg * Dvi.c - Dvi display widget
34f80a6dcdSmrg */
35f80a6dcdSmrg
36f80a6dcdSmrg#ifdef HAVE_CONFIG_H
37f80a6dcdSmrg# include "config.h"
38f80a6dcdSmrg#endif
39f80a6dcdSmrg
40f80a6dcdSmrg  /* The following are defined for the reader's convenience.  Any
41f80a6dcdSmrg     Xt..Field macro in this code just refers to some field in
42f80a6dcdSmrg     one of the substructures of the WidgetRec.  */
43f80a6dcdSmrg
44f80a6dcdSmrg#include <X11/IntrinsicP.h>
45f80a6dcdSmrg#include <X11/StringDefs.h>
46f80a6dcdSmrg#include <X11/Xmu/Converters.h>
47f80a6dcdSmrg#include <stdio.h>
48f80a6dcdSmrg#include <stdlib.h>
49f80a6dcdSmrg#include <unistd.h>
50f80a6dcdSmrg#include <ctype.h>
51f80a6dcdSmrg#include "DviP.h"
52f80a6dcdSmrg
53f80a6dcdSmrg/****************************************************************
54f80a6dcdSmrg *
55f80a6dcdSmrg * Full class record constant
56f80a6dcdSmrg *
57f80a6dcdSmrg ****************************************************************/
58f80a6dcdSmrg
59f80a6dcdSmrg/* Private Data */
60f80a6dcdSmrg/* Note: default_font_map was too long a token for some machines...
618c7c3c7eSmrg *       therefore it has been split in two and assigned to resources
62f80a6dcdSmrg *       in the ClassInitialize routine.
63f80a6dcdSmrg */
6400994698Smrgstatic const char *default_font_map_1 = "\
65f80a6dcdSmrgR	-*-times-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\
66f80a6dcdSmrgI	-*-times-medium-i-normal--*-*-*-*-*-*-iso8859-1\n\
67f80a6dcdSmrgB	-*-times-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\
68f80a6dcdSmrgF	-*-times-bold-i-normal--*-*-*-*-*-*-iso8859-1\n\
69f80a6dcdSmrgTR	-*-times-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\
70f80a6dcdSmrgTI	-*-times-medium-i-normal--*-*-*-*-*-*-iso8859-1\n\
71f80a6dcdSmrgTB	-*-times-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\
72f80a6dcdSmrgTF	-*-times-bold-i-normal--*-*-*-*-*-*-iso8859-1\n\
73f80a6dcdSmrgBI	-*-times-bold-i-normal--*-*-*-*-*-*-iso8859-1\n\
74f80a6dcdSmrgC	-*-courier-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\
75f80a6dcdSmrgCO	-*-courier-medium-o-normal--*-*-*-*-*-*-iso8859-1\n\
76f80a6dcdSmrgCB	-*-courier-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\
77f80a6dcdSmrgCF	-*-courier-bold-o-normal--*-*-*-*-*-*-iso8859-1\n\
78f80a6dcdSmrgH	-*-helvetica-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\
79f80a6dcdSmrgHO	-*-helvetica-medium-o-normal--*-*-*-*-*-*-iso8859-1\n\
80f80a6dcdSmrgHB	-*-helvetica-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\
81f80a6dcdSmrgHF	-*-helvetica-bold-o-normal--*-*-*-*-*-*-iso8859-1\n\
82f80a6dcdSmrg";
8300994698Smrgstatic const char *default_font_map_2 = "\
84f80a6dcdSmrgN	-*-new century schoolbook-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\
85f80a6dcdSmrgNI	-*-new century schoolbook-medium-i-normal--*-*-*-*-*-*-iso8859-1\n\
86f80a6dcdSmrgNB	-*-new century schoolbook-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\
87f80a6dcdSmrgNF	-*-new century schoolbook-bold-i-normal--*-*-*-*-*-*-iso8859-1\n\
88f80a6dcdSmrgA	-*-charter-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\
89f80a6dcdSmrgAI	-*-charter-medium-i-normal--*-*-*-*-*-*-iso8859-1\n\
90f80a6dcdSmrgAB	-*-charter-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\
91f80a6dcdSmrgAF	-*-charter-bold-i-normal--*-*-*-*-*-*-iso8859-1\n\
92f80a6dcdSmrgS	-*-symbol-medium-r-normal--*-*-*-*-*-*-adobe-fontspecific\n\
93f80a6dcdSmrgS2	-*-symbol-medium-r-normal--*-*-*-*-*-*-adobe-fontspecific\n\
94f80a6dcdSmrg";
95f80a6dcdSmrg
96f80a6dcdSmrg#define offset(field) XtOffsetOf(DviRec, field)
97f80a6dcdSmrg
9800994698Smrgstatic XtResource resources[] = {
9900994698Smrg    {XtNfontMap, XtCFontMap, XtRString, sizeof(char *),
10000994698Smrg     offset(dvi.font_map_string), XtRString, NULL /* set in code */ },
10100994698Smrg    {XtNforeground, XtCForeground, XtRPixel, sizeof(unsigned long),
10200994698Smrg     offset(dvi.foreground), XtRString, XtDefaultForeground},
10300994698Smrg    {XtNpageNumber, XtCPageNumber, XtRInt, sizeof(int),
10400994698Smrg     offset(dvi.requested_page), XtRImmediate, (XtPointer) 1},
10500994698Smrg    {XtNlastPageNumber, XtCLastPageNumber, XtRInt, sizeof(int),
10600994698Smrg     offset(dvi.last_page), XtRImmediate, (XtPointer) 0},
10700994698Smrg    {XtNfile, XtCFile, XtRFile, sizeof(FILE *),
10800994698Smrg     offset(dvi.file), XtRFile, (char *) 0},
10900994698Smrg    {XtNseek, XtCSeek, XtRBoolean, sizeof(Boolean),
11000994698Smrg     offset(dvi.seek), XtRImmediate, (XtPointer) False},
11100994698Smrg    {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
11200994698Smrg     offset(dvi.default_font), XtRString, XtDefaultFont},
11300994698Smrg    {XtNbackingStore, XtCBackingStore, XtRBackingStore, sizeof(int),
11400994698Smrg     offset(dvi.backing_store), XtRString, "default"},
11500994698Smrg    {XtNnoPolyText, XtCNoPolyText, XtRBoolean, sizeof(Boolean),
11600994698Smrg     offset(dvi.noPolyText), XtRImmediate, (XtPointer) False},
11700994698Smrg    {XtNscreenResolution, XtCScreenResolution, XtRInt, sizeof(int),
11800994698Smrg     offset(dvi.screen_resolution), XtRImmediate, (XtPointer) 75},
11900994698Smrg    {XtNpageWidth, XtCPageWidth, XtRFloat, sizeof(float),
12000994698Smrg     offset(dvi.page_width), XtRString, "8.5"},
12100994698Smrg    {XtNpageHeight, XtCPageHeight, XtRFloat, sizeof(float),
12200994698Smrg     offset(dvi.page_height), XtRString, "11"},
12300994698Smrg    {XtNsizeScale, XtCSizeScale, XtRInt, sizeof(int),
12400994698Smrg     offset(dvi.size_scale_set), XtRImmediate, (XtPointer) 0},
125f80a6dcdSmrg};
126f80a6dcdSmrg
127f80a6dcdSmrg#undef offset
128f80a6dcdSmrg
12900994698Smrgstatic void ClassInitialize(void);
13000994698Smrgstatic void Initialize(Widget, Widget, ArgList, Cardinal *);
13100994698Smrgstatic void Realize(Widget, XtValueMask *, XSetWindowAttributes *);
13200994698Smrgstatic void Destroy(Widget);
13300994698Smrgstatic void Redisplay(Widget, XEvent *, Region);
13400994698Smrgstatic Boolean SetValues(Widget, Widget, Widget, ArgList, Cardinal *);
13500994698Smrgstatic Boolean SetValuesHook(Widget, ArgList, Cardinal *);
13600994698Smrgstatic XtGeometryResult QueryGeometry(Widget,
13700994698Smrg                                      XtWidgetGeometry *, XtWidgetGeometry *);
13800994698Smrgstatic void RequestDesiredSize(DviWidget);
13900994698Smrgstatic void ShowDvi(DviWidget);
14000994698Smrgstatic void CloseFile(DviWidget);
14100994698Smrgstatic void OpenFile(DviWidget);
142f80a6dcdSmrg
143f80a6dcdSmrg#define SuperClass ((SimpleWidgetClass)&simpleClassRec)
144f80a6dcdSmrg
145f80a6dcdSmrgDviClassRec dviClassRec = {
14600994698Smrg    {
14700994698Smrg     (WidgetClass) SuperClass,  /* superclass             */
14800994698Smrg     "Dvi",                     /* class_name             */
14900994698Smrg     sizeof(DviRec),            /* size                   */
15000994698Smrg     ClassInitialize,           /* class_initialize       */
15100994698Smrg     NULL,                      /* class_part_initialize  */
15200994698Smrg     FALSE,                     /* class_inited           */
15300994698Smrg     Initialize,                /* initialize             */
15400994698Smrg     NULL,                      /* initialize_hook        */
15500994698Smrg     Realize,                   /* realize                */
15600994698Smrg     NULL,                      /* actions                */
15700994698Smrg     0,                         /* num_actions            */
15800994698Smrg     resources,                 /* resources              */
15900994698Smrg     XtNumber(resources),       /* resource_count         */
16000994698Smrg     NULLQUARK,                 /* xrm_class              */
16100994698Smrg     FALSE,                     /* compress_motion        */
16200994698Smrg     XtExposeCompressMaximal,   /* compress_exposure      */
16300994698Smrg     TRUE,                      /* compress_enterleave    */
16400994698Smrg     FALSE,                     /* visible_interest       */
16500994698Smrg     Destroy,                   /* destroy                */
16600994698Smrg     NULL,                      /* resize                 */
16700994698Smrg     Redisplay,                 /* expose                 */
16800994698Smrg     SetValues,                 /* set_values             */
16900994698Smrg     SetValuesHook,             /* set_values_hook        */
17000994698Smrg     XtInheritSetValuesAlmost,  /* set_values_almost      */
17100994698Smrg     NULL,                      /* get_values_hook        */
17200994698Smrg     NULL,                      /* accept_focus           */
17300994698Smrg     XtVersion,                 /* version                */
17400994698Smrg     NULL,                      /* callback_private       */
17500994698Smrg     NULL,                      /* tm_table               */
17600994698Smrg     QueryGeometry,             /* query_geometry         */
17700994698Smrg     XtInheritDisplayAccelerator,       /* display_accelerator    */
17800994698Smrg     NULL,                      /* extension              */
17900994698Smrg     },                         /* CoreClass fields initialization */
18000994698Smrg    {
18100994698Smrg     XtInheritChangeSensitive   /* change_sensitive     */
18200994698Smrg     },                         /* SimpleClass fields initialization */
18300994698Smrg    {
18400994698Smrg     0,                         /* field not used    */
18500994698Smrg     },                         /* DviClass fields initialization */
186f80a6dcdSmrg};
187f80a6dcdSmrg
188f80a6dcdSmrgWidgetClass dviWidgetClass = (WidgetClass) &dviClassRec;
189f80a6dcdSmrg
190f80a6dcdSmrgstatic void
19100994698SmrgClassInitialize(void)
192f80a6dcdSmrg{
19300994698Smrg    size_t len1 = strlen(default_font_map_1);
19400994698Smrg    size_t len2 = strlen(default_font_map_2);
19500994698Smrg    char *dfm = XtMalloc(len1 + len2 + 1);
19600994698Smrg    char *ptr = dfm;
19700994698Smrg
19800994698Smrg    memcpy(ptr, default_font_map_1, len1);
19900994698Smrg    ptr += len1;
20000994698Smrg    memcpy(ptr, default_font_map_2, len2);
20100994698Smrg    ptr[len2] = '\0';
20200994698Smrg    resources[0].default_addr = dfm;
20300994698Smrg
20400994698Smrg    XtAddConverter(XtRString, XtRBackingStore, XmuCvtStringToBackingStore,
20500994698Smrg                   NULL, 0);
206f80a6dcdSmrg}
207f80a6dcdSmrg
208f80a6dcdSmrg/****************************************************************
209f80a6dcdSmrg *
210f80a6dcdSmrg * Private Procedures
211f80a6dcdSmrg *
212f80a6dcdSmrg ****************************************************************/
213f80a6dcdSmrg
214f80a6dcdSmrg/* ARGSUSED */
215f80a6dcdSmrgstatic void
21665912f00SmrgInitialize(Widget request, Widget new, ArgList args, Cardinal *num_args)
217f80a6dcdSmrg{
21800994698Smrg    DviWidget dw = (DviWidget) new;
219f80a6dcdSmrg
22065912f00Smrg    dw->dvi.tmpFile = NULL;
221f80a6dcdSmrg    dw->dvi.readingTmp = 0;
222f80a6dcdSmrg    dw->dvi.ungot = 0;
22365912f00Smrg    dw->dvi.normal_GC = NULL;
22465912f00Smrg    dw->dvi.file_map = NULL;
22565912f00Smrg    dw->dvi.fonts = NULL;
22665912f00Smrg    dw->dvi.font_map = NULL;
227f80a6dcdSmrg    dw->dvi.current_page = 0;
228f80a6dcdSmrg    dw->dvi.font_size = 0;
229f80a6dcdSmrg    dw->dvi.font_number = 0;
230f80a6dcdSmrg    dw->dvi.device_resolution = 0;
231f80a6dcdSmrg    dw->dvi.line_width = 0;
232f80a6dcdSmrg    dw->dvi.line_style = 0;
23365912f00Smrg    dw->dvi.font = NULL;
234f80a6dcdSmrg    dw->dvi.display_enable = 0;
235f80a6dcdSmrg    dw->dvi.scale = 0.0;
23665912f00Smrg    dw->dvi.state = NULL;
237f80a6dcdSmrg    dw->dvi.cache.index = 0;
23800994698Smrg    dw->dvi.cache.font = NULL;
239f80a6dcdSmrg    dw->dvi.size_scale = 0;
240f80a6dcdSmrg    dw->dvi.size_scale_set = 0;
24100994698Smrg    RequestDesiredSize(dw);
242f80a6dcdSmrg}
243f80a6dcdSmrg
244f80a6dcdSmrgstatic void
24500994698SmrgRealize(Widget w, XtValueMask * valueMask, XSetWindowAttributes *attrs)
246f80a6dcdSmrg{
24700994698Smrg    DviWidget dw = (DviWidget) w;
24800994698Smrg    XGCValues values;
249f80a6dcdSmrg
250f80a6dcdSmrg    if (dw->dvi.backing_store != Always + WhenMapped + NotUseful) {
25100994698Smrg        attrs->backing_store = dw->dvi.backing_store;
25200994698Smrg        *valueMask |= CWBackingStore;
253f80a6dcdSmrg    }
25400994698Smrg    XtCreateWindow(w, (unsigned) InputOutput, (Visual *) CopyFromParent,
25500994698Smrg                   *valueMask, attrs);
256f80a6dcdSmrg    values.foreground = dw->dvi.foreground;
25700994698Smrg    dw->dvi.normal_GC = XCreateGC(XtDisplay(w), XtWindow(w),
25800994698Smrg                                  GCForeground, &values);
259f80a6dcdSmrg#ifdef USE_XFT
260f80a6dcdSmrg    {
26100994698Smrg        int scr = XScreenNumberOfScreen(dw->core.screen);
26200994698Smrg        Visual *visual = DefaultVisual(XtDisplay(w), scr);
26300994698Smrg        Colormap cmap = DefaultColormap(XtDisplay(w), scr);
26400994698Smrg        dw->dvi.draw = XftDrawCreate(XtDisplay(w), XtWindow(w), visual, cmap);
26500994698Smrg
26600994698Smrg        XRenderColor black = {
26700994698Smrg            .red = 0,
26800994698Smrg            .green = 0,
26900994698Smrg            .blue = 0,
27000994698Smrg            .alpha = 0xffff
27100994698Smrg        };
27200994698Smrg        XftColorAllocValue(XtDisplay(w), visual, cmap, &black, &dw->dvi.black);
27300994698Smrg        dw->dvi.default_font = XftFontOpenName(XtDisplay(w), scr, "serif-12");
274f80a6dcdSmrg    }
275f80a6dcdSmrg#endif
276f80a6dcdSmrg    if (dw->dvi.file)
27700994698Smrg        OpenFile(dw);
27800994698Smrg    ParseFontMap(dw);
279f80a6dcdSmrg}
280f80a6dcdSmrg
281f80a6dcdSmrgstatic void
28265912f00SmrgDestroy(Widget w)
283f80a6dcdSmrg{
28400994698Smrg    DviWidget dw = (DviWidget) w;
285f80a6dcdSmrg
28600994698Smrg    XFreeGC(XtDisplay(w), dw->dvi.normal_GC);
28700994698Smrg    DestroyFontMap(dw->dvi.font_map);
28800994698Smrg    DestroyFileMap(dw->dvi.file_map);
289f80a6dcdSmrg}
290f80a6dcdSmrg
291f80a6dcdSmrg/*
292f80a6dcdSmrg * Repaint the widget window
293f80a6dcdSmrg */
294f80a6dcdSmrg
295f80a6dcdSmrg/* ARGSUSED */
296f80a6dcdSmrgstatic void
29765912f00SmrgRedisplay(Widget w, XEvent *event, Region region)
298f80a6dcdSmrg{
29900994698Smrg    DviWidget dw = (DviWidget) w;
30000994698Smrg
301f80a6dcdSmrg#ifndef USE_XFT
30200994698Smrg    XRectangle extents;
303f80a6dcdSmrg#endif
30400994698Smrg
305f80a6dcdSmrg#ifdef USE_XFT
30600994698Smrg    XClearArea(XtDisplay(dw), XtWindow(dw), 0, 0, 0, 0, False);
30700994698Smrg    dw->dvi.extents.x1 = 0;
30800994698Smrg    dw->dvi.extents.y1 = 0;
30900994698Smrg    dw->dvi.extents.x2 = dw->core.width;
31000994698Smrg    dw->dvi.extents.y2 = dw->core.height;
311f80a6dcdSmrg#else
31200994698Smrg    XClipBox(region, &extents);
31300994698Smrg    dw->dvi.extents.x1 = extents.x;
31400994698Smrg    dw->dvi.extents.y1 = extents.y;
31500994698Smrg    dw->dvi.extents.x2 = extents.x + extents.width;
31600994698Smrg    dw->dvi.extents.y2 = extents.y + extents.height;
317f80a6dcdSmrg#endif
31800994698Smrg    ShowDvi(dw);
319f80a6dcdSmrg}
320f80a6dcdSmrg
321f80a6dcdSmrgstatic void
32200994698SmrgRequestDesiredSize(DviWidget dw)
323f80a6dcdSmrg{
32400994698Smrg    XtWidgetGeometry req, rep;
325f80a6dcdSmrg
32600994698Smrg    dw->dvi.desired_width = dw->dvi.page_width * dw->dvi.screen_resolution;
32700994698Smrg    dw->dvi.desired_height = dw->dvi.page_height * dw->dvi.screen_resolution;
32800994698Smrg    req.request_mode = CWWidth | CWHeight;
329f80a6dcdSmrg    req.width = dw->dvi.desired_width;
330f80a6dcdSmrg    req.height = dw->dvi.desired_height;
33100994698Smrg    XtMakeGeometryRequest((Widget) dw, &req, &rep);
332f80a6dcdSmrg}
333f80a6dcdSmrg
334f80a6dcdSmrg/*
335f80a6dcdSmrg * Set specified arguments into widget
336f80a6dcdSmrg */
337f80a6dcdSmrg/* ARGSUSED */
338f80a6dcdSmrgstatic Boolean
33900994698SmrgSetValues(Widget wcurrent, Widget wrequest, Widget wnew,
34000994698Smrg          ArgList args, Cardinal *num_args)
341f80a6dcdSmrg{
34200994698Smrg    DviWidget current = (DviWidget) wcurrent;
34300994698Smrg    DviWidget request = (DviWidget) wrequest;
34400994698Smrg    DviWidget new = (DviWidget) wnew;
34500994698Smrg    Boolean redisplay = FALSE;
34600994698Smrg
34700994698Smrg    int req = request->dvi.requested_page;
34800994698Smrg    int cur = current->dvi.requested_page;
349f80a6dcdSmrg    if (cur != req) {
35000994698Smrg        if (req < 1)
35100994698Smrg            req = 1;
35200994698Smrg        if (request->dvi.file) {
35300994698Smrg            if (current->dvi.last_page != 0 && req > current->dvi.last_page)
35400994698Smrg                req = current->dvi.last_page;
35500994698Smrg        }
35600994698Smrg        if (cur != req)
35700994698Smrg            redisplay = TRUE;
35800994698Smrg        new->dvi.requested_page = req;
359f80a6dcdSmrg    }
36000994698Smrg
361f80a6dcdSmrg    if (current->dvi.font_map_string != request->dvi.font_map_string) {
36200994698Smrg        size_t  map_len = strlen (request->dvi.font_map_string) + 1;
36300994698Smrg        char *  new_map = XtMalloc (map_len);
36400994698Smrg
36500994698Smrg        if (new_map) {
36600994698Smrg            redisplay = TRUE;
36700994698Smrg            memcpy(new_map, request->dvi.font_map_string, map_len);
36800994698Smrg            new->dvi.font_map_string = new_map;
36900994698Smrg            if (current->dvi.font_map_string)
37000994698Smrg                XtFree(current->dvi.font_map_string);
37100994698Smrg            current->dvi.font_map_string = NULL;
37200994698Smrg            ParseFontMap(new);
37300994698Smrg        }
374f80a6dcdSmrg    }
37500994698Smrg    if (current->dvi.screen_resolution != request->dvi.screen_resolution) {
37600994698Smrg        ResetFonts(new);
37700994698Smrg        new->dvi.line_width = -1;
378f80a6dcdSmrg    }
379f80a6dcdSmrg    if (request->dvi.device_resolution)
38000994698Smrg        new->dvi.scale = ((double) request->dvi.screen_resolution) /
38100994698Smrg            ((double) request->dvi.device_resolution);
38200994698Smrg    if (current->dvi.page_width != request->dvi.page_width ||
38300994698Smrg        current->dvi.page_height != request->dvi.page_height ||
38400994698Smrg        current->dvi.screen_resolution != request->dvi.screen_resolution) {
38500994698Smrg        RequestDesiredSize(new);
38600994698Smrg        redisplay = TRUE;
387f80a6dcdSmrg    }
388f80a6dcdSmrg    return redisplay;
389f80a6dcdSmrg}
390f80a6dcdSmrg
391f80a6dcdSmrg/*
392f80a6dcdSmrg * use the set_values_hook entry to check when
393f80a6dcdSmrg * the file is set
394f80a6dcdSmrg */
395f80a6dcdSmrg
396f80a6dcdSmrgstatic Boolean
39700994698SmrgSetValuesHook(Widget widget, ArgList args, Cardinal *num_argsp)
398f80a6dcdSmrg{
39900994698Smrg    DviWidget dw = (DviWidget) widget;
40000994698Smrg
40100994698Smrg    for (Cardinal i = 0; i < *num_argsp; i++) {
40200994698Smrg        if (!strcmp(args[i].name, XtNfile)) {
40300994698Smrg            CloseFile(dw);
40400994698Smrg            OpenFile(dw);
40500994698Smrg            return TRUE;
40600994698Smrg        }
40700994698Smrg    }
40800994698Smrg    return FALSE;
409f80a6dcdSmrg}
410f80a6dcdSmrg
411f80a6dcdSmrgstatic void
41200994698SmrgCloseFile(DviWidget dw)
413f80a6dcdSmrg{
414f80a6dcdSmrg    if (dw->dvi.tmpFile)
41500994698Smrg        fclose(dw->dvi.tmpFile);
41600994698Smrg    ForgetPagePositions(dw);
417f80a6dcdSmrg}
418f80a6dcdSmrg
419f80a6dcdSmrgstatic void
42000994698SmrgOpenFile(DviWidget dw)
421f80a6dcdSmrg{
42265912f00Smrg    dw->dvi.tmpFile = NULL;
423f80a6dcdSmrg    if (!dw->dvi.seek) {
42400994698Smrg        char tmpName[] = "/tmp/dviXXXXXX";
425c166fba9Smrg
426f80a6dcdSmrg#ifndef HAS_MKSTEMP
42700994698Smrg        mktemp(tmpName);
42800994698Smrg        dw->dvi.tmpFile = fopen(tmpName, "w+");
429f80a6dcdSmrg#else
43000994698Smrg        int fd = mkstemp(tmpName);
43100994698Smrg
43200994698Smrg        if (fd != -1) {
43300994698Smrg            dw->dvi.tmpFile = fdopen(fd, "w+");
43400994698Smrg            if (dw->dvi.tmpFile == NULL)
43500994698Smrg                close(fd);
43600994698Smrg        }
437f80a6dcdSmrg#endif
43800994698Smrg        remove(tmpName);
439f80a6dcdSmrg    }
440f80a6dcdSmrg    if (dw->dvi.requested_page < 1)
44100994698Smrg        dw->dvi.requested_page = 1;
442f80a6dcdSmrg    dw->dvi.last_page = 0;
443f80a6dcdSmrg}
444f80a6dcdSmrg
445f80a6dcdSmrgstatic XtGeometryResult
44600994698SmrgQueryGeometry(Widget w, XtWidgetGeometry *request,
44700994698Smrg              XtWidgetGeometry *geometry_return)
448f80a6dcdSmrg{
44900994698Smrg    XtGeometryResult ret = XtGeometryYes;
45000994698Smrg    DviWidget dw = (DviWidget) w;
45100994698Smrg
45200994698Smrg    if ((int) request->width < dw->dvi.desired_width
45300994698Smrg        || (int) request->height < dw->dvi.desired_height)
45400994698Smrg        ret = XtGeometryAlmost;
45500994698Smrg    geometry_return->width = dw->dvi.desired_width;
45600994698Smrg    geometry_return->height = dw->dvi.desired_height;
45700994698Smrg    geometry_return->request_mode = CWWidth | CWHeight;
45800994698Smrg    return ret;
459f80a6dcdSmrg}
460f80a6dcdSmrg
461f80a6dcdSmrgvoid
46200994698SmrgSetDeviceResolution(DviWidget dw, int resolution)
463f80a6dcdSmrg{
464f80a6dcdSmrg    if (resolution != dw->dvi.device_resolution) {
46500994698Smrg        dw->dvi.device_resolution = resolution;
46600994698Smrg        dw->dvi.scale = ((double) dw->dvi.screen_resolution) /
46700994698Smrg            ((double) resolution);
468f80a6dcdSmrg    }
469f80a6dcdSmrg}
470f80a6dcdSmrg
471f80a6dcdSmrgstatic void
47200994698SmrgShowDvi(DviWidget dw)
473f80a6dcdSmrg{
47400994698Smrg    long file_position;
47500994698Smrg
47600994698Smrg    if (!dw->dvi.file)
47700994698Smrg        return;
47800994698Smrg
47900994698Smrg    if (dw->dvi.requested_page < 1)
48000994698Smrg        dw->dvi.requested_page = 1;
48100994698Smrg
48200994698Smrg    if (dw->dvi.last_page != 0 && dw->dvi.requested_page > dw->dvi.last_page)
48300994698Smrg        dw->dvi.requested_page = dw->dvi.last_page;
48400994698Smrg
48500994698Smrg    file_position = SearchPagePosition(dw, dw->dvi.requested_page);
48600994698Smrg    if (file_position != -1) {
48700994698Smrg        FileSeek(dw, file_position);
48800994698Smrg        dw->dvi.current_page = dw->dvi.requested_page;
48900994698Smrg    }
49000994698Smrg    else {
49100994698Smrg        int i;
49200994698Smrg
49300994698Smrg        for (i = dw->dvi.requested_page; i > 0; i--) {
49400994698Smrg            file_position = SearchPagePosition(dw, i);
49500994698Smrg            if (file_position != -1)
49600994698Smrg                break;
49700994698Smrg        }
49800994698Smrg        if (file_position == -1)
49900994698Smrg            file_position = 0;
50000994698Smrg        FileSeek(dw, file_position);
50100994698Smrg
50200994698Smrg        dw->dvi.current_page = i;
50300994698Smrg
50400994698Smrg        dw->dvi.display_enable = 0;
50500994698Smrg        while (dw->dvi.current_page != dw->dvi.requested_page) {
50600994698Smrg            dw->dvi.current_page = ParseInput(dw);
50700994698Smrg            /*
50800994698Smrg             * at EOF, seek back to the beginning of this page.
50900994698Smrg             */
51000994698Smrg            if (feof(dw->dvi.file)) {
51100994698Smrg                file_position = SearchPagePosition(dw, dw->dvi.current_page);
51200994698Smrg                if (file_position != -1)
51300994698Smrg                    FileSeek(dw, file_position);
51400994698Smrg                break;
51500994698Smrg            }
51600994698Smrg        }
51700994698Smrg    }
51800994698Smrg
51900994698Smrg    dw->dvi.display_enable = 1;
52000994698Smrg    ParseInput(dw);
52100994698Smrg    if (dw->dvi.last_page && dw->dvi.requested_page > dw->dvi.last_page)
52200994698Smrg        dw->dvi.requested_page = dw->dvi.last_page;
523f80a6dcdSmrg}
524