Dvi.c revision 8c7c3c7e
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#define XtStrlen(s)	((s) ? strlen(s) : 0)
41f80a6dcdSmrg
42f80a6dcdSmrg  /* The following are defined for the reader's convenience.  Any
43f80a6dcdSmrg     Xt..Field macro in this code just refers to some field in
44f80a6dcdSmrg     one of the substructures of the WidgetRec.  */
45f80a6dcdSmrg
46f80a6dcdSmrg#include <X11/IntrinsicP.h>
47f80a6dcdSmrg#include <X11/StringDefs.h>
48f80a6dcdSmrg#include <X11/Xmu/Converters.h>
49f80a6dcdSmrg#include <stdio.h>
50f80a6dcdSmrg#include <stdlib.h>
51f80a6dcdSmrg#include <unistd.h>
52f80a6dcdSmrg#include <ctype.h>
53f80a6dcdSmrg#include "DviP.h"
54f80a6dcdSmrg
55f80a6dcdSmrg/****************************************************************
56f80a6dcdSmrg *
57f80a6dcdSmrg * Full class record constant
58f80a6dcdSmrg *
59f80a6dcdSmrg ****************************************************************/
60f80a6dcdSmrg
61f80a6dcdSmrg/* Private Data */
62f80a6dcdSmrg/* Note: default_font_map was too long a token for some machines...
638c7c3c7eSmrg *       therefore it has been split in two and assigned to resources
64f80a6dcdSmrg *       in the ClassInitialize routine.
65f80a6dcdSmrg */
66c166fba9Smrgstatic const char *default_font_map_1 =  "\
67f80a6dcdSmrgR	-*-times-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\
68f80a6dcdSmrgI	-*-times-medium-i-normal--*-*-*-*-*-*-iso8859-1\n\
69f80a6dcdSmrgB	-*-times-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\
70f80a6dcdSmrgF	-*-times-bold-i-normal--*-*-*-*-*-*-iso8859-1\n\
71f80a6dcdSmrgTR	-*-times-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\
72f80a6dcdSmrgTI	-*-times-medium-i-normal--*-*-*-*-*-*-iso8859-1\n\
73f80a6dcdSmrgTB	-*-times-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\
74f80a6dcdSmrgTF	-*-times-bold-i-normal--*-*-*-*-*-*-iso8859-1\n\
75f80a6dcdSmrgBI	-*-times-bold-i-normal--*-*-*-*-*-*-iso8859-1\n\
76f80a6dcdSmrgC	-*-courier-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\
77f80a6dcdSmrgCO	-*-courier-medium-o-normal--*-*-*-*-*-*-iso8859-1\n\
78f80a6dcdSmrgCB	-*-courier-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\
79f80a6dcdSmrgCF	-*-courier-bold-o-normal--*-*-*-*-*-*-iso8859-1\n\
80f80a6dcdSmrgH	-*-helvetica-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\
81f80a6dcdSmrgHO	-*-helvetica-medium-o-normal--*-*-*-*-*-*-iso8859-1\n\
82f80a6dcdSmrgHB	-*-helvetica-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\
83f80a6dcdSmrgHF	-*-helvetica-bold-o-normal--*-*-*-*-*-*-iso8859-1\n\
84f80a6dcdSmrg";
85c166fba9Smrgstatic const char *default_font_map_2 =  "\
86f80a6dcdSmrgN	-*-new century schoolbook-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\
87f80a6dcdSmrgNI	-*-new century schoolbook-medium-i-normal--*-*-*-*-*-*-iso8859-1\n\
88f80a6dcdSmrgNB	-*-new century schoolbook-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\
89f80a6dcdSmrgNF	-*-new century schoolbook-bold-i-normal--*-*-*-*-*-*-iso8859-1\n\
90f80a6dcdSmrgA	-*-charter-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\
91f80a6dcdSmrgAI	-*-charter-medium-i-normal--*-*-*-*-*-*-iso8859-1\n\
92f80a6dcdSmrgAB	-*-charter-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\
93f80a6dcdSmrgAF	-*-charter-bold-i-normal--*-*-*-*-*-*-iso8859-1\n\
94f80a6dcdSmrgS	-*-symbol-medium-r-normal--*-*-*-*-*-*-adobe-fontspecific\n\
95f80a6dcdSmrgS2	-*-symbol-medium-r-normal--*-*-*-*-*-*-adobe-fontspecific\n\
96f80a6dcdSmrg";
97f80a6dcdSmrg
98f80a6dcdSmrg#define offset(field) XtOffsetOf(DviRec, field)
99f80a6dcdSmrg
100f80a6dcdSmrgstatic XtResource resources[] = {
101f80a6dcdSmrg	{XtNfontMap, XtCFontMap, XtRString, sizeof (char *),
102f80a6dcdSmrg	 offset(dvi.font_map_string), XtRString, NULL /* set in code */},
103f80a6dcdSmrg	{XtNforeground, XtCForeground, XtRPixel, sizeof (unsigned long),
104f80a6dcdSmrg	 offset(dvi.foreground), XtRString, XtDefaultForeground},
105f80a6dcdSmrg	{XtNpageNumber, XtCPageNumber, XtRInt, sizeof (int),
106f80a6dcdSmrg	 offset(dvi.requested_page), XtRImmediate, (XtPointer) 1},
107f80a6dcdSmrg	{XtNlastPageNumber, XtCLastPageNumber, XtRInt, sizeof (int),
108f80a6dcdSmrg	 offset (dvi.last_page), XtRImmediate, (XtPointer) 0},
109f80a6dcdSmrg	{XtNfile, XtCFile, XtRFile, sizeof (FILE *),
110f80a6dcdSmrg	 offset (dvi.file), XtRFile, (char *) 0},
111f80a6dcdSmrg	{XtNseek, XtCSeek, XtRBoolean, sizeof (Boolean),
112f80a6dcdSmrg	 offset(dvi.seek), XtRImmediate, (XtPointer) False},
113f80a6dcdSmrg	{XtNfont, XtCFont, XtRFontStruct, sizeof (XFontStruct *),
114f80a6dcdSmrg	 offset(dvi.default_font), XtRString, XtDefaultFont},
115f80a6dcdSmrg	{XtNbackingStore, XtCBackingStore, XtRBackingStore, sizeof (int),
116f80a6dcdSmrg	 offset(dvi.backing_store), XtRString, "default"},
117f80a6dcdSmrg	{XtNnoPolyText, XtCNoPolyText, XtRBoolean, sizeof (Boolean),
118f80a6dcdSmrg	 offset(dvi.noPolyText), XtRImmediate, (XtPointer) False},
119f80a6dcdSmrg	{XtNscreenResolution, XtCScreenResolution, XtRInt, sizeof (int),
120f80a6dcdSmrg	 offset(dvi.screen_resolution), XtRImmediate, (XtPointer) 75},
121f80a6dcdSmrg	{XtNpageWidth, XtCPageWidth, XtRFloat, sizeof (float),
122f80a6dcdSmrg	 offset(dvi.page_width), XtRString, "8.5"},
123f80a6dcdSmrg	{XtNpageHeight, XtCPageHeight, XtRFloat, sizeof (float),
124f80a6dcdSmrg	 offset(dvi.page_height), XtRString, "11"},
125f80a6dcdSmrg	{XtNsizeScale, XtCSizeScale, XtRInt, sizeof (int),
126f80a6dcdSmrg	 offset(dvi.size_scale_set), XtRImmediate, (XtPointer) 0},
127f80a6dcdSmrg};
128f80a6dcdSmrg
129f80a6dcdSmrg#undef offset
130f80a6dcdSmrg
131f80a6dcdSmrgstatic void		ClassInitialize(void);
132f80a6dcdSmrgstatic void		Initialize(Widget, Widget, ArgList, Cardinal *);
133f80a6dcdSmrgstatic void		Realize(Widget, XtValueMask *, XSetWindowAttributes *);
134f80a6dcdSmrgstatic void		Destroy(Widget);
135f80a6dcdSmrgstatic void		Redisplay(Widget, XEvent *, Region);
136f80a6dcdSmrgstatic Boolean		SetValues(Widget, Widget, Widget, ArgList , Cardinal *);
137f80a6dcdSmrgstatic Boolean		SetValuesHook(Widget, ArgList, Cardinal	*);
138f80a6dcdSmrgstatic XtGeometryResult	QueryGeometry(Widget,
139f80a6dcdSmrg				      XtWidgetGeometry *, XtWidgetGeometry *);
140f80a6dcdSmrgstatic void		RequestDesiredSize(DviWidget);
141f80a6dcdSmrgstatic void		ShowDvi(DviWidget);
142f80a6dcdSmrgstatic void		CloseFile(DviWidget);
143f80a6dcdSmrgstatic void		OpenFile(DviWidget);
144f80a6dcdSmrg
145f80a6dcdSmrg#define SuperClass ((SimpleWidgetClass)&simpleClassRec)
146f80a6dcdSmrg
147f80a6dcdSmrgDviClassRec dviClassRec = {
148f80a6dcdSmrg{
149f80a6dcdSmrg	(WidgetClass) SuperClass,	/* superclass		  */
150f80a6dcdSmrg	"Dvi",				/* class_name		  */
151f80a6dcdSmrg	sizeof(DviRec),			/* size			  */
152f80a6dcdSmrg	ClassInitialize,		/* class_initialize	  */
153f80a6dcdSmrg	NULL,				/* class_part_initialize  */
154f80a6dcdSmrg	FALSE,				/* class_inited		  */
155f80a6dcdSmrg	Initialize,			/* initialize		  */
156f80a6dcdSmrg	NULL,				/* initialize_hook	  */
157f80a6dcdSmrg	Realize,			/* realize		  */
158f80a6dcdSmrg	NULL,				/* actions		  */
159f80a6dcdSmrg	0,				/* num_actions		  */
160f80a6dcdSmrg	resources,			/* resources		  */
161f80a6dcdSmrg	XtNumber(resources),		/* resource_count	  */
162f80a6dcdSmrg	NULLQUARK,			/* xrm_class		  */
163f80a6dcdSmrg	FALSE,				/* compress_motion	  */
164f80a6dcdSmrg	XtExposeCompressMaximal,    	/* compress_exposure	  */
165f80a6dcdSmrg	TRUE,				/* compress_enterleave    */
166f80a6dcdSmrg	FALSE,				/* visible_interest	  */
167f80a6dcdSmrg	Destroy,			/* destroy		  */
168f80a6dcdSmrg	NULL,				/* resize		  */
169f80a6dcdSmrg	Redisplay,			/* expose		  */
170f80a6dcdSmrg	SetValues,			/* set_values		  */
171f80a6dcdSmrg	SetValuesHook,			/* set_values_hook	  */
172f80a6dcdSmrg	XtInheritSetValuesAlmost,	/* set_values_almost	  */
173f80a6dcdSmrg	NULL,				/* get_values_hook	  */
174f80a6dcdSmrg	NULL,				/* accept_focus		  */
175f80a6dcdSmrg	XtVersion,			/* version		  */
176f80a6dcdSmrg	NULL,				/* callback_private	  */
17765912f00Smrg	NULL,				/* tm_table		  */
178f80a6dcdSmrg	QueryGeometry,			/* query_geometry	  */
179f80a6dcdSmrg	XtInheritDisplayAccelerator,	/* display_accelerator	  */
180f80a6dcdSmrg	NULL,				/* extension		  */
181f80a6dcdSmrg},  /* CoreClass fields initialization */
182f80a6dcdSmrg{
183f80a6dcdSmrg    XtInheritChangeSensitive		/* change_sensitive	*/
184f80a6dcdSmrg},  /* SimpleClass fields initialization */
185f80a6dcdSmrg{
186f80a6dcdSmrg    0,                                     /* field not used    */
187f80a6dcdSmrg},  /* DviClass fields initialization */
188f80a6dcdSmrg};
189f80a6dcdSmrg
190f80a6dcdSmrgWidgetClass dviWidgetClass = (WidgetClass) &dviClassRec;
191f80a6dcdSmrg
192f80a6dcdSmrgstatic void
193f80a6dcdSmrgClassInitialize (void)
194f80a6dcdSmrg{
195f80a6dcdSmrg  int len1 = strlen(default_font_map_1);
196f80a6dcdSmrg  int len2 = strlen(default_font_map_2);
197f80a6dcdSmrg  char *dfm = XtMalloc(len1 + len2 + 1);
198f80a6dcdSmrg  char *ptr = dfm;
199f80a6dcdSmrg  strcpy(ptr, default_font_map_1); ptr += len1;
200f80a6dcdSmrg  strcpy(ptr, default_font_map_2);
201f80a6dcdSmrg  resources[0].default_addr = dfm;
202f80a6dcdSmrg
203f80a6dcdSmrg  XtAddConverter( XtRString, XtRBackingStore, XmuCvtStringToBackingStore,
204f80a6dcdSmrg		 NULL, 0 );
205f80a6dcdSmrg}
206f80a6dcdSmrg
207f80a6dcdSmrg/****************************************************************
208f80a6dcdSmrg *
209f80a6dcdSmrg * Private Procedures
210f80a6dcdSmrg *
211f80a6dcdSmrg ****************************************************************/
212f80a6dcdSmrg
213f80a6dcdSmrg/* ARGSUSED */
214f80a6dcdSmrgstatic void
21565912f00SmrgInitialize(Widget request, Widget new, ArgList args, Cardinal *num_args)
216f80a6dcdSmrg{
217f80a6dcdSmrg    DviWidget	dw = (DviWidget) new;
218f80a6dcdSmrg
21965912f00Smrg    dw->dvi.tmpFile = NULL;
220f80a6dcdSmrg    dw->dvi.readingTmp = 0;
221f80a6dcdSmrg    dw->dvi.ungot = 0;
22265912f00Smrg    dw->dvi.normal_GC = NULL;
22365912f00Smrg    dw->dvi.file_map = NULL;
22465912f00Smrg    dw->dvi.fonts = NULL;
22565912f00Smrg    dw->dvi.font_map = NULL;
226f80a6dcdSmrg    dw->dvi.current_page = 0;
227f80a6dcdSmrg    dw->dvi.font_size = 0;
228f80a6dcdSmrg    dw->dvi.font_number = 0;
229f80a6dcdSmrg    dw->dvi.device_resolution = 0;
230f80a6dcdSmrg    dw->dvi.line_width = 0;
231f80a6dcdSmrg    dw->dvi.line_style = 0;
23265912f00Smrg    dw->dvi.font = NULL;
233f80a6dcdSmrg    dw->dvi.display_enable = 0;
234f80a6dcdSmrg    dw->dvi.scale = 0.0;
23565912f00Smrg    dw->dvi.state = NULL;
236f80a6dcdSmrg    dw->dvi.cache.index = 0;
23765912f00Smrg    dw->dvi.cache.font = NULL;
238f80a6dcdSmrg    dw->dvi.size_scale = 0;
239f80a6dcdSmrg    dw->dvi.size_scale_set = 0;
240f80a6dcdSmrg    RequestDesiredSize (dw);
241f80a6dcdSmrg}
242f80a6dcdSmrg
243f80a6dcdSmrgstatic void
24465912f00SmrgRealize(Widget w, XtValueMask *valueMask, XSetWindowAttributes *attrs)
245f80a6dcdSmrg{
246f80a6dcdSmrg    DviWidget	dw = (DviWidget) w;
247f80a6dcdSmrg    XGCValues	values;
248f80a6dcdSmrg
249f80a6dcdSmrg    if (dw->dvi.backing_store != Always + WhenMapped + NotUseful) {
250f80a6dcdSmrg	attrs->backing_store = dw->dvi.backing_store;
251f80a6dcdSmrg	*valueMask |= CWBackingStore;
252f80a6dcdSmrg    }
253f80a6dcdSmrg    XtCreateWindow (w, (unsigned)InputOutput, (Visual *) CopyFromParent,
254f80a6dcdSmrg		    *valueMask, attrs);
255f80a6dcdSmrg    values.foreground = dw->dvi.foreground;
256f80a6dcdSmrg    dw->dvi.normal_GC = XCreateGC (XtDisplay (w), XtWindow (w),
257f80a6dcdSmrg				    GCForeground, &values);
258f80a6dcdSmrg#ifdef USE_XFT
259f80a6dcdSmrg    {
260f80a6dcdSmrg	int		scr;
261f80a6dcdSmrg	Visual		*visual;
262f80a6dcdSmrg	Colormap	cmap;
263f80a6dcdSmrg	XRenderColor	black;
264f80a6dcdSmrg
265f80a6dcdSmrg	scr = XScreenNumberOfScreen (dw->core.screen);
266f80a6dcdSmrg	visual = DefaultVisual (XtDisplay (w), scr);
267f80a6dcdSmrg	cmap = DefaultColormap (XtDisplay (w), scr);
268f80a6dcdSmrg	dw->dvi.draw = XftDrawCreate (XtDisplay (w), XtWindow (w),
269f80a6dcdSmrg				      visual, cmap);
270f80a6dcdSmrg
271f80a6dcdSmrg	black.red = black.green = black.blue = 0;
272f80a6dcdSmrg	black.alpha = 0xffff;
273f80a6dcdSmrg	XftColorAllocValue (XtDisplay (w), visual, cmap,
274f80a6dcdSmrg			    &black, &dw->dvi.black);
275f80a6dcdSmrg	dw->dvi.default_font = XftFontOpenName (XtDisplay (w),
276f80a6dcdSmrg						scr,
277f80a6dcdSmrg						"serif-12");
278f80a6dcdSmrg    }
279f80a6dcdSmrg#endif
280f80a6dcdSmrg    if (dw->dvi.file)
281f80a6dcdSmrg	OpenFile (dw);
282f80a6dcdSmrg    ParseFontMap (dw);
283f80a6dcdSmrg}
284f80a6dcdSmrg
285f80a6dcdSmrgstatic void
28665912f00SmrgDestroy(Widget w)
287f80a6dcdSmrg{
288f80a6dcdSmrg	DviWidget	dw = (DviWidget) w;
289f80a6dcdSmrg
290f80a6dcdSmrg	XFreeGC (XtDisplay (w), dw->dvi.normal_GC);
291f80a6dcdSmrg	DestroyFontMap (dw->dvi.font_map);
292f80a6dcdSmrg	DestroyFileMap (dw->dvi.file_map);
293f80a6dcdSmrg}
294f80a6dcdSmrg
295f80a6dcdSmrg/*
296f80a6dcdSmrg * Repaint the widget window
297f80a6dcdSmrg */
298f80a6dcdSmrg
299f80a6dcdSmrg/* ARGSUSED */
300f80a6dcdSmrgstatic void
30165912f00SmrgRedisplay(Widget w, XEvent *event, Region region)
302f80a6dcdSmrg{
303f80a6dcdSmrg	DviWidget	dw = (DviWidget) w;
304f80a6dcdSmrg#ifndef USE_XFT
305f80a6dcdSmrg	XRectangle	extents;
306f80a6dcdSmrg#endif
307f80a6dcdSmrg
308f80a6dcdSmrg#ifdef USE_XFT
309f80a6dcdSmrg	XClearArea (XtDisplay (dw),
310f80a6dcdSmrg		    XtWindow (dw),
311f80a6dcdSmrg		    0, 0, 0, 0, False);
312f80a6dcdSmrg	dw->dvi.extents.x1 = 0;
313f80a6dcdSmrg	dw->dvi.extents.y1 = 0;
314f80a6dcdSmrg	dw->dvi.extents.x2 = dw->core.width;
315f80a6dcdSmrg	dw->dvi.extents.y2 = dw->core.height;
316f80a6dcdSmrg#else
317f80a6dcdSmrg	XClipBox (region, &extents);
318f80a6dcdSmrg	dw->dvi.extents.x1 = extents.x;
319f80a6dcdSmrg	dw->dvi.extents.y1 = extents.y;
320f80a6dcdSmrg	dw->dvi.extents.x2 = extents.x + extents.width;
321f80a6dcdSmrg	dw->dvi.extents.y2 = extents.y + extents.height;
322f80a6dcdSmrg#endif
323f80a6dcdSmrg	ShowDvi (dw);
324f80a6dcdSmrg}
325f80a6dcdSmrg
326f80a6dcdSmrgstatic void
32765912f00SmrgRequestDesiredSize (DviWidget dw)
328f80a6dcdSmrg{
329f80a6dcdSmrg    XtWidgetGeometry	req, rep;
330f80a6dcdSmrg
331f80a6dcdSmrg    dw->dvi.desired_width = dw->dvi.page_width *
332f80a6dcdSmrg				 dw->dvi.screen_resolution;
333f80a6dcdSmrg    dw->dvi.desired_height = dw->dvi.page_height *
334f80a6dcdSmrg				  dw->dvi.screen_resolution;
335f80a6dcdSmrg    req.request_mode = CWWidth|CWHeight;
336f80a6dcdSmrg    req.width = dw->dvi.desired_width;
337f80a6dcdSmrg    req.height = dw->dvi.desired_height;
338f80a6dcdSmrg    XtMakeGeometryRequest ((Widget) dw, &req, &rep);
339f80a6dcdSmrg}
340f80a6dcdSmrg
341f80a6dcdSmrg/*
342f80a6dcdSmrg * Set specified arguments into widget
343f80a6dcdSmrg */
344f80a6dcdSmrg/* ARGSUSED */
345f80a6dcdSmrgstatic Boolean
34665912f00SmrgSetValues (Widget wcurrent, Widget wrequest, Widget wnew,
34765912f00Smrg	   ArgList args, Cardinal *num_args)
348f80a6dcdSmrg{
349f80a6dcdSmrg    DviWidget	current = (DviWidget) wcurrent;
350f80a6dcdSmrg    DviWidget	request = (DviWidget) wrequest;
351f80a6dcdSmrg    DviWidget	new     = (DviWidget) wnew;
352f80a6dcdSmrg    Boolean	redisplay = FALSE;
353f80a6dcdSmrg    char	*new_map;
354f80a6dcdSmrg    int		cur, req;
355f80a6dcdSmrg
356f80a6dcdSmrg    req = request->dvi.requested_page;
357f80a6dcdSmrg    cur = current->dvi.requested_page;
358f80a6dcdSmrg    if (cur != req) {
359f80a6dcdSmrg	    if (req < 1)
360f80a6dcdSmrg		req = 1;
361f80a6dcdSmrg	    if (request->dvi.file)
362f80a6dcdSmrg	    {
363f80a6dcdSmrg		if (current->dvi.last_page != 0 &&
364f80a6dcdSmrg		    req > current->dvi.last_page)
365f80a6dcdSmrg			req = current->dvi.last_page;
366f80a6dcdSmrg	    }
367f80a6dcdSmrg	    if (cur != req)
368f80a6dcdSmrg		redisplay = TRUE;
369f80a6dcdSmrg	    new->dvi.requested_page = req;
370f80a6dcdSmrg    }
371f80a6dcdSmrg
372f80a6dcdSmrg    if (current->dvi.font_map_string != request->dvi.font_map_string) {
373f80a6dcdSmrg	    new_map = XtMalloc (strlen (request->dvi.font_map_string) + 1);
374f80a6dcdSmrg	    if (new_map) {
375f80a6dcdSmrg		    redisplay = TRUE;
376f80a6dcdSmrg		    strcpy (new_map, request->dvi.font_map_string);
377f80a6dcdSmrg		    new->dvi.font_map_string = new_map;
378f80a6dcdSmrg		    if (current->dvi.font_map_string)
379f80a6dcdSmrg			    XtFree (current->dvi.font_map_string);
38065912f00Smrg		    current->dvi.font_map_string = NULL;
381f80a6dcdSmrg		    ParseFontMap (new);
382f80a6dcdSmrg	    }
383f80a6dcdSmrg    }
384f80a6dcdSmrg    if (current->dvi.screen_resolution != request->dvi.screen_resolution)
385f80a6dcdSmrg    {
386f80a6dcdSmrg	ResetFonts (new);
387f80a6dcdSmrg	new->dvi.line_width = -1;
388f80a6dcdSmrg    }
389f80a6dcdSmrg    if (request->dvi.device_resolution)
390f80a6dcdSmrg	new->dvi.scale = ((double) request->dvi.screen_resolution) /
391f80a6dcdSmrg			     ((double) request->dvi.device_resolution);
392f80a6dcdSmrg    if (current->dvi.page_width !=  request->dvi.page_width ||
393f80a6dcdSmrg	current->dvi.page_height != request->dvi.page_height ||
394f80a6dcdSmrg	current->dvi.screen_resolution != request->dvi.screen_resolution)
395f80a6dcdSmrg    {
396f80a6dcdSmrg	RequestDesiredSize (new);
397f80a6dcdSmrg	redisplay = TRUE;
398f80a6dcdSmrg    }
399f80a6dcdSmrg    return redisplay;
400f80a6dcdSmrg}
401f80a6dcdSmrg
402f80a6dcdSmrg/*
403f80a6dcdSmrg * use the set_values_hook entry to check when
404f80a6dcdSmrg * the file is set
405f80a6dcdSmrg */
406f80a6dcdSmrg
407f80a6dcdSmrgstatic Boolean
40865912f00SmrgSetValuesHook (Widget widget, ArgList args, Cardinal *num_argsp)
409f80a6dcdSmrg{
410f80a6dcdSmrg	DviWidget	dw = (DviWidget) widget;
411f80a6dcdSmrg	Cardinal	i;
412f80a6dcdSmrg
413f80a6dcdSmrg	for (i = 0; i < *num_argsp; i++) {
414f80a6dcdSmrg		if (!strcmp (args[i].name, XtNfile)) {
415f80a6dcdSmrg			CloseFile (dw);
416f80a6dcdSmrg			OpenFile (dw);
417f80a6dcdSmrg			return TRUE;
418f80a6dcdSmrg		}
419f80a6dcdSmrg	}
420f80a6dcdSmrg	return FALSE;
421f80a6dcdSmrg}
422f80a6dcdSmrg
423f80a6dcdSmrgstatic void
42465912f00SmrgCloseFile (DviWidget dw)
425f80a6dcdSmrg{
426f80a6dcdSmrg    if (dw->dvi.tmpFile)
427f80a6dcdSmrg	fclose (dw->dvi.tmpFile);
428f80a6dcdSmrg    ForgetPagePositions (dw);
429f80a6dcdSmrg}
430f80a6dcdSmrg
431f80a6dcdSmrgstatic void
43265912f00SmrgOpenFile (DviWidget dw)
433f80a6dcdSmrg{
43465912f00Smrg    dw->dvi.tmpFile = NULL;
435f80a6dcdSmrg    if (!dw->dvi.seek) {
436c166fba9Smrg	char	tmpName[] = "/tmp/dviXXXXXX";
437c166fba9Smrg
438f80a6dcdSmrg#ifndef HAS_MKSTEMP
439f80a6dcdSmrg	mktemp (tmpName);
440f80a6dcdSmrg	dw->dvi.tmpFile = fopen (tmpName, "w+");
441f80a6dcdSmrg#else
442c166fba9Smrg	int fd = mkstemp(tmpName);
443c166fba9Smrg	if (fd != -1) {
444c166fba9Smrg	    dw->dvi.tmpFile = fdopen(fd, "w+");
445c166fba9Smrg	    if (dw->dvi.tmpFile == NULL)
446c166fba9Smrg		close(fd);
447c166fba9Smrg	}
448f80a6dcdSmrg#endif
449c166fba9Smrg	remove (tmpName);
450f80a6dcdSmrg    }
451f80a6dcdSmrg    if (dw->dvi.requested_page < 1)
452f80a6dcdSmrg	dw->dvi.requested_page = 1;
453f80a6dcdSmrg    dw->dvi.last_page = 0;
454f80a6dcdSmrg}
455f80a6dcdSmrg
456f80a6dcdSmrgstatic XtGeometryResult
45765912f00SmrgQueryGeometry (Widget w, XtWidgetGeometry *request,
45865912f00Smrg	       XtWidgetGeometry *geometry_return)
459f80a6dcdSmrg{
460f80a6dcdSmrg	XtGeometryResult	ret;
461f80a6dcdSmrg	DviWidget		dw = (DviWidget) w;
462f80a6dcdSmrg
463f80a6dcdSmrg	ret = XtGeometryYes;
464f80a6dcdSmrg	if ((int)request->width < dw->dvi.desired_width
465f80a6dcdSmrg	    || (int)request->height < dw->dvi.desired_height)
466f80a6dcdSmrg		ret = XtGeometryAlmost;
467f80a6dcdSmrg	geometry_return->width = dw->dvi.desired_width;
468f80a6dcdSmrg	geometry_return->height = dw->dvi.desired_height;
469f80a6dcdSmrg	geometry_return->request_mode = CWWidth|CWHeight;
470f80a6dcdSmrg	return ret;
471f80a6dcdSmrg}
472f80a6dcdSmrg
473f80a6dcdSmrgvoid
47465912f00SmrgSetDeviceResolution (DviWidget dw, int resolution)
475f80a6dcdSmrg{
476f80a6dcdSmrg    if (resolution != dw->dvi.device_resolution) {
477f80a6dcdSmrg	dw->dvi.device_resolution = resolution;
478f80a6dcdSmrg	dw->dvi.scale = ((double)  dw->dvi.screen_resolution) /
479f80a6dcdSmrg			((double) resolution);
480f80a6dcdSmrg    }
481f80a6dcdSmrg}
482f80a6dcdSmrg
483f80a6dcdSmrgstatic void
48465912f00SmrgShowDvi (DviWidget dw)
485f80a6dcdSmrg{
486f80a6dcdSmrg	long	file_position;
487f80a6dcdSmrg
488f80a6dcdSmrg	if (!dw->dvi.file)
489f80a6dcdSmrg	  return;
490f80a6dcdSmrg
491f80a6dcdSmrg	if (dw->dvi.requested_page < 1)
492f80a6dcdSmrg		dw->dvi.requested_page = 1;
493f80a6dcdSmrg
494f80a6dcdSmrg	if (dw->dvi.last_page != 0 && dw->dvi.requested_page > dw->dvi.last_page)
495f80a6dcdSmrg		dw->dvi.requested_page = dw->dvi.last_page;
496f80a6dcdSmrg
497f80a6dcdSmrg	file_position = SearchPagePosition (dw, dw->dvi.requested_page);
498f80a6dcdSmrg	if (file_position != -1) {
499f80a6dcdSmrg		FileSeek(dw, file_position);
500f80a6dcdSmrg		dw->dvi.current_page = dw->dvi.requested_page;
501f80a6dcdSmrg	} else {
5028c7c3c7eSmrg		int	i;
5038c7c3c7eSmrg
5048c7c3c7eSmrg		for (i = dw->dvi.requested_page; i > 0; i--) {
505f80a6dcdSmrg			file_position = SearchPagePosition (dw, i);
506f80a6dcdSmrg			if (file_position != -1)
507f80a6dcdSmrg				break;
508f80a6dcdSmrg		}
509f80a6dcdSmrg		if (file_position == -1)
510f80a6dcdSmrg			file_position = 0;
511f80a6dcdSmrg		FileSeek (dw, file_position);
512f80a6dcdSmrg
513f80a6dcdSmrg		dw->dvi.current_page = i;
514f80a6dcdSmrg
515f80a6dcdSmrg		dw->dvi.display_enable = 0;
516f80a6dcdSmrg		while (dw->dvi.current_page != dw->dvi.requested_page) {
517f80a6dcdSmrg			dw->dvi.current_page = ParseInput (dw);
518f80a6dcdSmrg			/*
5198c7c3c7eSmrg			 * at EOF, seek back to the beginning of this page.
520f80a6dcdSmrg			 */
521f80a6dcdSmrg			if (feof (dw->dvi.file)) {
522f80a6dcdSmrg				file_position = SearchPagePosition (dw,
523f80a6dcdSmrg						dw->dvi.current_page);
524f80a6dcdSmrg				if (file_position != -1)
525f80a6dcdSmrg					FileSeek (dw, file_position);
526f80a6dcdSmrg				break;
527f80a6dcdSmrg			}
528f80a6dcdSmrg		}
529f80a6dcdSmrg	}
530f80a6dcdSmrg
531f80a6dcdSmrg	dw->dvi.display_enable = 1;
532f80a6dcdSmrg	ParseInput (dw);
533f80a6dcdSmrg	if (dw->dvi.last_page && dw->dvi.requested_page > dw->dvi.last_page)
534f80a6dcdSmrg		dw->dvi.requested_page = dw->dvi.last_page;
535f80a6dcdSmrg}
536