Dvi.c revision f80a6dcd
1f80a6dcdSmrg/* $XConsortium: Dvi.c,v 1.21 94/04/17 20:43:34 keith Exp $ */
2f80a6dcdSmrg/* $XdotOrg: $ */
3f80a6dcdSmrg/*
4f80a6dcdSmrg
5f80a6dcdSmrgCopyright (c) 1991  X Consortium
6f80a6dcdSmrg
7f80a6dcdSmrgPermission is hereby granted, free of charge, to any person obtaining
8f80a6dcdSmrga copy of this software and associated documentation files (the
9f80a6dcdSmrg"Software"), to deal in the Software without restriction, including
10f80a6dcdSmrgwithout limitation the rights to use, copy, modify, merge, publish,
11f80a6dcdSmrgdistribute, sublicense, and/or sell copies of the Software, and to
12f80a6dcdSmrgpermit persons to whom the Software is furnished to do so, subject to
13f80a6dcdSmrgthe following conditions:
14f80a6dcdSmrg
15f80a6dcdSmrgThe above copyright notice and this permission notice shall be included
16f80a6dcdSmrgin all copies or substantial portions of the Software.
17f80a6dcdSmrg
18f80a6dcdSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19f80a6dcdSmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20f80a6dcdSmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21f80a6dcdSmrgIN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
22f80a6dcdSmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23f80a6dcdSmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24f80a6dcdSmrgOTHER DEALINGS IN THE SOFTWARE.
25f80a6dcdSmrg
26f80a6dcdSmrgExcept as contained in this notice, the name of the X Consortium shall
27f80a6dcdSmrgnot be used in advertising or otherwise to promote the sale, use or
28f80a6dcdSmrgother dealings in this Software without prior written authorization
29f80a6dcdSmrgfrom the X Consortium.
30f80a6dcdSmrg
31f80a6dcdSmrg*/
32f80a6dcdSmrg/* $XFree86: xc/programs/xditview/Dvi.c,v 1.3 2001/08/01 00:45:03 tsi Exp $ */
33f80a6dcdSmrg
34f80a6dcdSmrg
35f80a6dcdSmrg/*
36f80a6dcdSmrg * Dvi.c - Dvi display widget
37f80a6dcdSmrg */
38f80a6dcdSmrg
39f80a6dcdSmrg#ifdef HAVE_CONFIG_H
40f80a6dcdSmrg# include "config.h"
41f80a6dcdSmrg#endif
42f80a6dcdSmrg
43f80a6dcdSmrg#define XtStrlen(s)	((s) ? strlen(s) : 0)
44f80a6dcdSmrg
45f80a6dcdSmrg  /* The following are defined for the reader's convenience.  Any
46f80a6dcdSmrg     Xt..Field macro in this code just refers to some field in
47f80a6dcdSmrg     one of the substructures of the WidgetRec.  */
48f80a6dcdSmrg
49f80a6dcdSmrg#include <X11/IntrinsicP.h>
50f80a6dcdSmrg#include <X11/StringDefs.h>
51f80a6dcdSmrg#include <X11/Xmu/Converters.h>
52f80a6dcdSmrg#include <stdio.h>
53f80a6dcdSmrg#include <stdlib.h>
54f80a6dcdSmrg#include <unistd.h>
55f80a6dcdSmrg#include <ctype.h>
56f80a6dcdSmrg#include "DviP.h"
57f80a6dcdSmrg
58f80a6dcdSmrg/****************************************************************
59f80a6dcdSmrg *
60f80a6dcdSmrg * Full class record constant
61f80a6dcdSmrg *
62f80a6dcdSmrg ****************************************************************/
63f80a6dcdSmrg
64f80a6dcdSmrg/* Private Data */
65f80a6dcdSmrg/* Note: default_font_map was too long a token for some machines...
66f80a6dcdSmrg *       therefor it has been split in to and assigned to resources
67f80a6dcdSmrg *       in the ClassInitialize routine.
68f80a6dcdSmrg */
69f80a6dcdSmrgstatic char default_font_map_1[] =  "\
70f80a6dcdSmrgR	-*-times-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\
71f80a6dcdSmrgI	-*-times-medium-i-normal--*-*-*-*-*-*-iso8859-1\n\
72f80a6dcdSmrgB	-*-times-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\
73f80a6dcdSmrgF	-*-times-bold-i-normal--*-*-*-*-*-*-iso8859-1\n\
74f80a6dcdSmrgTR	-*-times-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\
75f80a6dcdSmrgTI	-*-times-medium-i-normal--*-*-*-*-*-*-iso8859-1\n\
76f80a6dcdSmrgTB	-*-times-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\
77f80a6dcdSmrgTF	-*-times-bold-i-normal--*-*-*-*-*-*-iso8859-1\n\
78f80a6dcdSmrgBI	-*-times-bold-i-normal--*-*-*-*-*-*-iso8859-1\n\
79f80a6dcdSmrgC	-*-courier-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\
80f80a6dcdSmrgCO	-*-courier-medium-o-normal--*-*-*-*-*-*-iso8859-1\n\
81f80a6dcdSmrgCB	-*-courier-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\
82f80a6dcdSmrgCF	-*-courier-bold-o-normal--*-*-*-*-*-*-iso8859-1\n\
83f80a6dcdSmrgH	-*-helvetica-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\
84f80a6dcdSmrgHO	-*-helvetica-medium-o-normal--*-*-*-*-*-*-iso8859-1\n\
85f80a6dcdSmrgHB	-*-helvetica-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\
86f80a6dcdSmrgHF	-*-helvetica-bold-o-normal--*-*-*-*-*-*-iso8859-1\n\
87f80a6dcdSmrg";
88f80a6dcdSmrgstatic char default_font_map_2[] =  "\
89f80a6dcdSmrgN	-*-new century schoolbook-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\
90f80a6dcdSmrgNI	-*-new century schoolbook-medium-i-normal--*-*-*-*-*-*-iso8859-1\n\
91f80a6dcdSmrgNB	-*-new century schoolbook-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\
92f80a6dcdSmrgNF	-*-new century schoolbook-bold-i-normal--*-*-*-*-*-*-iso8859-1\n\
93f80a6dcdSmrgA	-*-charter-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\
94f80a6dcdSmrgAI	-*-charter-medium-i-normal--*-*-*-*-*-*-iso8859-1\n\
95f80a6dcdSmrgAB	-*-charter-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\
96f80a6dcdSmrgAF	-*-charter-bold-i-normal--*-*-*-*-*-*-iso8859-1\n\
97f80a6dcdSmrgS	-*-symbol-medium-r-normal--*-*-*-*-*-*-adobe-fontspecific\n\
98f80a6dcdSmrgS2	-*-symbol-medium-r-normal--*-*-*-*-*-*-adobe-fontspecific\n\
99f80a6dcdSmrg";
100f80a6dcdSmrg
101f80a6dcdSmrg#define offset(field) XtOffsetOf(DviRec, field)
102f80a6dcdSmrg
103f80a6dcdSmrgstatic XtResource resources[] = {
104f80a6dcdSmrg	{XtNfontMap, XtCFontMap, XtRString, sizeof (char *),
105f80a6dcdSmrg	 offset(dvi.font_map_string), XtRString, NULL /* set in code */},
106f80a6dcdSmrg	{XtNforeground, XtCForeground, XtRPixel, sizeof (unsigned long),
107f80a6dcdSmrg	 offset(dvi.foreground), XtRString, XtDefaultForeground},
108f80a6dcdSmrg	{XtNpageNumber, XtCPageNumber, XtRInt, sizeof (int),
109f80a6dcdSmrg	 offset(dvi.requested_page), XtRImmediate, (XtPointer) 1},
110f80a6dcdSmrg	{XtNlastPageNumber, XtCLastPageNumber, XtRInt, sizeof (int),
111f80a6dcdSmrg	 offset (dvi.last_page), XtRImmediate, (XtPointer) 0},
112f80a6dcdSmrg	{XtNfile, XtCFile, XtRFile, sizeof (FILE *),
113f80a6dcdSmrg	 offset (dvi.file), XtRFile, (char *) 0},
114f80a6dcdSmrg	{XtNseek, XtCSeek, XtRBoolean, sizeof (Boolean),
115f80a6dcdSmrg	 offset(dvi.seek), XtRImmediate, (XtPointer) False},
116f80a6dcdSmrg	{XtNfont, XtCFont, XtRFontStruct, sizeof (XFontStruct *),
117f80a6dcdSmrg	 offset(dvi.default_font), XtRString, XtDefaultFont},
118f80a6dcdSmrg	{XtNbackingStore, XtCBackingStore, XtRBackingStore, sizeof (int),
119f80a6dcdSmrg	 offset(dvi.backing_store), XtRString, "default"},
120f80a6dcdSmrg	{XtNnoPolyText, XtCNoPolyText, XtRBoolean, sizeof (Boolean),
121f80a6dcdSmrg	 offset(dvi.noPolyText), XtRImmediate, (XtPointer) False},
122f80a6dcdSmrg	{XtNscreenResolution, XtCScreenResolution, XtRInt, sizeof (int),
123f80a6dcdSmrg	 offset(dvi.screen_resolution), XtRImmediate, (XtPointer) 75},
124f80a6dcdSmrg	{XtNpageWidth, XtCPageWidth, XtRFloat, sizeof (float),
125f80a6dcdSmrg	 offset(dvi.page_width), XtRString, "8.5"},
126f80a6dcdSmrg	{XtNpageHeight, XtCPageHeight, XtRFloat, sizeof (float),
127f80a6dcdSmrg	 offset(dvi.page_height), XtRString, "11"},
128f80a6dcdSmrg	{XtNsizeScale, XtCSizeScale, XtRInt, sizeof (int),
129f80a6dcdSmrg	 offset(dvi.size_scale_set), XtRImmediate, (XtPointer) 0},
130f80a6dcdSmrg};
131f80a6dcdSmrg
132f80a6dcdSmrg#undef offset
133f80a6dcdSmrg
134f80a6dcdSmrgstatic void		ClassInitialize(void);
135f80a6dcdSmrgstatic void		Initialize(Widget, Widget, ArgList, Cardinal *);
136f80a6dcdSmrgstatic void		Realize(Widget, XtValueMask *, XSetWindowAttributes *);
137f80a6dcdSmrgstatic void		Destroy(Widget);
138f80a6dcdSmrgstatic void		Redisplay(Widget, XEvent *, Region);
139f80a6dcdSmrgstatic Boolean		SetValues(Widget, Widget, Widget, ArgList , Cardinal *);
140f80a6dcdSmrgstatic Boolean		SetValuesHook(Widget, ArgList, Cardinal	*);
141f80a6dcdSmrgstatic XtGeometryResult	QueryGeometry(Widget,
142f80a6dcdSmrg				      XtWidgetGeometry *, XtWidgetGeometry *);
143f80a6dcdSmrgstatic void		RequestDesiredSize(DviWidget);
144f80a6dcdSmrgstatic void		ShowDvi(DviWidget);
145f80a6dcdSmrgstatic void		CloseFile(DviWidget);
146f80a6dcdSmrgstatic void		OpenFile(DviWidget);
147f80a6dcdSmrg
148f80a6dcdSmrg#define SuperClass ((SimpleWidgetClass)&simpleClassRec)
149f80a6dcdSmrg
150f80a6dcdSmrgDviClassRec dviClassRec = {
151f80a6dcdSmrg{
152f80a6dcdSmrg	(WidgetClass) SuperClass,	/* superclass		  */
153f80a6dcdSmrg	"Dvi",				/* class_name		  */
154f80a6dcdSmrg	sizeof(DviRec),			/* size			  */
155f80a6dcdSmrg	ClassInitialize,		/* class_initialize	  */
156f80a6dcdSmrg	NULL,				/* class_part_initialize  */
157f80a6dcdSmrg	FALSE,				/* class_inited		  */
158f80a6dcdSmrg	Initialize,			/* initialize		  */
159f80a6dcdSmrg	NULL,				/* initialize_hook	  */
160f80a6dcdSmrg	Realize,			/* realize		  */
161f80a6dcdSmrg	NULL,				/* actions		  */
162f80a6dcdSmrg	0,				/* num_actions		  */
163f80a6dcdSmrg	resources,			/* resources		  */
164f80a6dcdSmrg	XtNumber(resources),		/* resource_count	  */
165f80a6dcdSmrg	NULLQUARK,			/* xrm_class		  */
166f80a6dcdSmrg	FALSE,				/* compress_motion	  */
167f80a6dcdSmrg	XtExposeCompressMaximal,    	/* compress_exposure	  */
168f80a6dcdSmrg	TRUE,				/* compress_enterleave    */
169f80a6dcdSmrg	FALSE,				/* visible_interest	  */
170f80a6dcdSmrg	Destroy,			/* destroy		  */
171f80a6dcdSmrg	NULL,				/* resize		  */
172f80a6dcdSmrg	Redisplay,			/* expose		  */
173f80a6dcdSmrg	SetValues,			/* set_values		  */
174f80a6dcdSmrg	SetValuesHook,			/* set_values_hook	  */
175f80a6dcdSmrg	XtInheritSetValuesAlmost,	/* set_values_almost	  */
176f80a6dcdSmrg	NULL,				/* get_values_hook	  */
177f80a6dcdSmrg	NULL,				/* accept_focus		  */
178f80a6dcdSmrg	XtVersion,			/* version		  */
179f80a6dcdSmrg	NULL,				/* callback_private	  */
180f80a6dcdSmrg	0,				/* tm_table		  */
181f80a6dcdSmrg	QueryGeometry,			/* query_geometry	  */
182f80a6dcdSmrg	XtInheritDisplayAccelerator,	/* display_accelerator	  */
183f80a6dcdSmrg	NULL,				/* extension		  */
184f80a6dcdSmrg},  /* CoreClass fields initialization */
185f80a6dcdSmrg{
186f80a6dcdSmrg    XtInheritChangeSensitive		/* change_sensitive	*/
187f80a6dcdSmrg},  /* SimpleClass fields initialization */
188f80a6dcdSmrg{
189f80a6dcdSmrg    0,                                     /* field not used    */
190f80a6dcdSmrg},  /* DviClass fields initialization */
191f80a6dcdSmrg};
192f80a6dcdSmrg
193f80a6dcdSmrgWidgetClass dviWidgetClass = (WidgetClass) &dviClassRec;
194f80a6dcdSmrg
195f80a6dcdSmrgstatic void
196f80a6dcdSmrgClassInitialize (void)
197f80a6dcdSmrg{
198f80a6dcdSmrg  int len1 = strlen(default_font_map_1);
199f80a6dcdSmrg  int len2 = strlen(default_font_map_2);
200f80a6dcdSmrg  char *dfm = XtMalloc(len1 + len2 + 1);
201f80a6dcdSmrg  char *ptr = dfm;
202f80a6dcdSmrg  strcpy(ptr, default_font_map_1); ptr += len1;
203f80a6dcdSmrg  strcpy(ptr, default_font_map_2);
204f80a6dcdSmrg  resources[0].default_addr = dfm;
205f80a6dcdSmrg
206f80a6dcdSmrg  XtAddConverter( XtRString, XtRBackingStore, XmuCvtStringToBackingStore,
207f80a6dcdSmrg		 NULL, 0 );
208f80a6dcdSmrg}
209f80a6dcdSmrg
210f80a6dcdSmrg/****************************************************************
211f80a6dcdSmrg *
212f80a6dcdSmrg * Private Procedures
213f80a6dcdSmrg *
214f80a6dcdSmrg ****************************************************************/
215f80a6dcdSmrg
216f80a6dcdSmrg/* ARGSUSED */
217f80a6dcdSmrgstatic void
218f80a6dcdSmrgInitialize(request, new, args, num_args)
219f80a6dcdSmrg	Widget request, new;
220f80a6dcdSmrg	ArgList args;
221f80a6dcdSmrg	Cardinal *num_args;
222f80a6dcdSmrg{
223f80a6dcdSmrg    DviWidget	dw = (DviWidget) new;
224f80a6dcdSmrg
225f80a6dcdSmrg    dw->dvi.tmpFile = 0;
226f80a6dcdSmrg    dw->dvi.readingTmp = 0;
227f80a6dcdSmrg    dw->dvi.ungot = 0;
228f80a6dcdSmrg    dw->dvi.normal_GC = 0;
229f80a6dcdSmrg    dw->dvi.file_map = 0;
230f80a6dcdSmrg    dw->dvi.fonts = 0;
231f80a6dcdSmrg    dw->dvi.font_map = 0;
232f80a6dcdSmrg    dw->dvi.current_page = 0;
233f80a6dcdSmrg    dw->dvi.font_size = 0;
234f80a6dcdSmrg    dw->dvi.font_number = 0;
235f80a6dcdSmrg    dw->dvi.device_resolution = 0;
236f80a6dcdSmrg    dw->dvi.line_width = 0;
237f80a6dcdSmrg    dw->dvi.line_style = 0;
238f80a6dcdSmrg    dw->dvi.font = 0;
239f80a6dcdSmrg    dw->dvi.display_enable = 0;
240f80a6dcdSmrg    dw->dvi.scale = 0.0;
241f80a6dcdSmrg    dw->dvi.state = 0;
242f80a6dcdSmrg    dw->dvi.cache.index = 0;
243f80a6dcdSmrg    dw->dvi.cache.font = 0;
244f80a6dcdSmrg    dw->dvi.size_scale = 0;
245f80a6dcdSmrg    dw->dvi.size_scale_set = 0;
246f80a6dcdSmrg    RequestDesiredSize (dw);
247f80a6dcdSmrg}
248f80a6dcdSmrg
249f80a6dcdSmrgstatic void
250f80a6dcdSmrgRealize(w, valueMask, attrs)
251f80a6dcdSmrg	Widget			w;
252f80a6dcdSmrg	XtValueMask		*valueMask;
253f80a6dcdSmrg	XSetWindowAttributes	*attrs;
254f80a6dcdSmrg{
255f80a6dcdSmrg    DviWidget	dw = (DviWidget) w;
256f80a6dcdSmrg    XGCValues	values;
257f80a6dcdSmrg
258f80a6dcdSmrg    if (dw->dvi.backing_store != Always + WhenMapped + NotUseful) {
259f80a6dcdSmrg	attrs->backing_store = dw->dvi.backing_store;
260f80a6dcdSmrg	*valueMask |= CWBackingStore;
261f80a6dcdSmrg    }
262f80a6dcdSmrg    XtCreateWindow (w, (unsigned)InputOutput, (Visual *) CopyFromParent,
263f80a6dcdSmrg		    *valueMask, attrs);
264f80a6dcdSmrg    values.foreground = dw->dvi.foreground;
265f80a6dcdSmrg    dw->dvi.normal_GC = XCreateGC (XtDisplay (w), XtWindow (w),
266f80a6dcdSmrg				    GCForeground, &values);
267f80a6dcdSmrg#ifdef USE_XFT
268f80a6dcdSmrg    {
269f80a6dcdSmrg	int		scr;
270f80a6dcdSmrg	Visual		*visual;
271f80a6dcdSmrg	Colormap	cmap;
272f80a6dcdSmrg	XRenderColor	black;
273f80a6dcdSmrg
274f80a6dcdSmrg	scr = XScreenNumberOfScreen (dw->core.screen);
275f80a6dcdSmrg	visual = DefaultVisual (XtDisplay (w), scr);
276f80a6dcdSmrg	cmap = DefaultColormap (XtDisplay (w), scr);
277f80a6dcdSmrg	dw->dvi.draw = XftDrawCreate (XtDisplay (w), XtWindow (w),
278f80a6dcdSmrg				      visual, cmap);
279f80a6dcdSmrg
280f80a6dcdSmrg	black.red = black.green = black.blue = 0;
281f80a6dcdSmrg	black.alpha = 0xffff;
282f80a6dcdSmrg	XftColorAllocValue (XtDisplay (w), visual, cmap,
283f80a6dcdSmrg			    &black, &dw->dvi.black);
284f80a6dcdSmrg	dw->dvi.default_font = XftFontOpenName (XtDisplay (w),
285f80a6dcdSmrg						scr,
286f80a6dcdSmrg						"serif-12");
287f80a6dcdSmrg    }
288f80a6dcdSmrg#endif
289f80a6dcdSmrg    if (dw->dvi.file)
290f80a6dcdSmrg	OpenFile (dw);
291f80a6dcdSmrg    ParseFontMap (dw);
292f80a6dcdSmrg}
293f80a6dcdSmrg
294f80a6dcdSmrgstatic void
295f80a6dcdSmrgDestroy(w)
296f80a6dcdSmrg	Widget w;
297f80a6dcdSmrg{
298f80a6dcdSmrg	DviWidget	dw = (DviWidget) w;
299f80a6dcdSmrg
300f80a6dcdSmrg	XFreeGC (XtDisplay (w), dw->dvi.normal_GC);
301f80a6dcdSmrg	DestroyFontMap (dw->dvi.font_map);
302f80a6dcdSmrg	DestroyFileMap (dw->dvi.file_map);
303f80a6dcdSmrg}
304f80a6dcdSmrg
305f80a6dcdSmrg/*
306f80a6dcdSmrg * Repaint the widget window
307f80a6dcdSmrg */
308f80a6dcdSmrg
309f80a6dcdSmrg/* ARGSUSED */
310f80a6dcdSmrgstatic void
311f80a6dcdSmrgRedisplay(w, event, region)
312f80a6dcdSmrg	Widget w;
313f80a6dcdSmrg	XEvent *event;
314f80a6dcdSmrg	Region region;
315f80a6dcdSmrg{
316f80a6dcdSmrg	DviWidget	dw = (DviWidget) w;
317f80a6dcdSmrg#ifndef USE_XFT
318f80a6dcdSmrg	XRectangle	extents;
319f80a6dcdSmrg#endif
320f80a6dcdSmrg
321f80a6dcdSmrg#ifdef USE_XFT
322f80a6dcdSmrg	XClearArea (XtDisplay (dw),
323f80a6dcdSmrg		    XtWindow (dw),
324f80a6dcdSmrg		    0, 0, 0, 0, False);
325f80a6dcdSmrg	dw->dvi.extents.x1 = 0;
326f80a6dcdSmrg	dw->dvi.extents.y1 = 0;
327f80a6dcdSmrg	dw->dvi.extents.x2 = dw->core.width;
328f80a6dcdSmrg	dw->dvi.extents.y2 = dw->core.height;
329f80a6dcdSmrg#else
330f80a6dcdSmrg	XClipBox (region, &extents);
331f80a6dcdSmrg	dw->dvi.extents.x1 = extents.x;
332f80a6dcdSmrg	dw->dvi.extents.y1 = extents.y;
333f80a6dcdSmrg	dw->dvi.extents.x2 = extents.x + extents.width;
334f80a6dcdSmrg	dw->dvi.extents.y2 = extents.y + extents.height;
335f80a6dcdSmrg#endif
336f80a6dcdSmrg	ShowDvi (dw);
337f80a6dcdSmrg}
338f80a6dcdSmrg
339f80a6dcdSmrgstatic void
340f80a6dcdSmrgRequestDesiredSize (dw)
341f80a6dcdSmrg    DviWidget	dw;
342f80a6dcdSmrg{
343f80a6dcdSmrg    XtWidgetGeometry	req, rep;
344f80a6dcdSmrg
345f80a6dcdSmrg    dw->dvi.desired_width = dw->dvi.page_width *
346f80a6dcdSmrg				 dw->dvi.screen_resolution;
347f80a6dcdSmrg    dw->dvi.desired_height = dw->dvi.page_height *
348f80a6dcdSmrg				  dw->dvi.screen_resolution;
349f80a6dcdSmrg    req.request_mode = CWWidth|CWHeight;
350f80a6dcdSmrg    req.width = dw->dvi.desired_width;
351f80a6dcdSmrg    req.height = dw->dvi.desired_height;
352f80a6dcdSmrg    XtMakeGeometryRequest ((Widget) dw, &req, &rep);
353f80a6dcdSmrg}
354f80a6dcdSmrg
355f80a6dcdSmrg/*
356f80a6dcdSmrg * Set specified arguments into widget
357f80a6dcdSmrg */
358f80a6dcdSmrg/* ARGSUSED */
359f80a6dcdSmrgstatic Boolean
360f80a6dcdSmrgSetValues (wcurrent, wrequest, wnew, args, num_args)
361f80a6dcdSmrg	Widget wcurrent, wrequest, wnew;
362f80a6dcdSmrg	ArgList args;
363f80a6dcdSmrg	Cardinal *num_args;
364f80a6dcdSmrg{
365f80a6dcdSmrg    DviWidget	current = (DviWidget) wcurrent;
366f80a6dcdSmrg    DviWidget	request = (DviWidget) wrequest;
367f80a6dcdSmrg    DviWidget	new     = (DviWidget) wnew;
368f80a6dcdSmrg    Boolean	redisplay = FALSE;
369f80a6dcdSmrg    char	*new_map;
370f80a6dcdSmrg    int		cur, req;
371f80a6dcdSmrg
372f80a6dcdSmrg    req = request->dvi.requested_page;
373f80a6dcdSmrg    cur = current->dvi.requested_page;
374f80a6dcdSmrg    if (cur != req) {
375f80a6dcdSmrg	    if (req < 1)
376f80a6dcdSmrg		req = 1;
377f80a6dcdSmrg	    if (request->dvi.file)
378f80a6dcdSmrg	    {
379f80a6dcdSmrg		if (current->dvi.last_page != 0 &&
380f80a6dcdSmrg		    req > current->dvi.last_page)
381f80a6dcdSmrg			req = current->dvi.last_page;
382f80a6dcdSmrg	    }
383f80a6dcdSmrg	    if (cur != req)
384f80a6dcdSmrg		redisplay = TRUE;
385f80a6dcdSmrg	    new->dvi.requested_page = req;
386f80a6dcdSmrg    }
387f80a6dcdSmrg
388f80a6dcdSmrg    if (current->dvi.font_map_string != request->dvi.font_map_string) {
389f80a6dcdSmrg	    new_map = XtMalloc (strlen (request->dvi.font_map_string) + 1);
390f80a6dcdSmrg	    if (new_map) {
391f80a6dcdSmrg		    redisplay = TRUE;
392f80a6dcdSmrg		    strcpy (new_map, request->dvi.font_map_string);
393f80a6dcdSmrg		    new->dvi.font_map_string = new_map;
394f80a6dcdSmrg		    if (current->dvi.font_map_string)
395f80a6dcdSmrg			    XtFree (current->dvi.font_map_string);
396f80a6dcdSmrg		    current->dvi.font_map_string = 0;
397f80a6dcdSmrg		    ParseFontMap (new);
398f80a6dcdSmrg	    }
399f80a6dcdSmrg    }
400f80a6dcdSmrg    if (current->dvi.screen_resolution != request->dvi.screen_resolution)
401f80a6dcdSmrg    {
402f80a6dcdSmrg	ResetFonts (new);
403f80a6dcdSmrg	new->dvi.line_width = -1;
404f80a6dcdSmrg    }
405f80a6dcdSmrg    if (request->dvi.device_resolution)
406f80a6dcdSmrg	new->dvi.scale = ((double) request->dvi.screen_resolution) /
407f80a6dcdSmrg			     ((double) request->dvi.device_resolution);
408f80a6dcdSmrg    if (current->dvi.page_width !=  request->dvi.page_width ||
409f80a6dcdSmrg	current->dvi.page_height != request->dvi.page_height ||
410f80a6dcdSmrg	current->dvi.screen_resolution != request->dvi.screen_resolution)
411f80a6dcdSmrg    {
412f80a6dcdSmrg	RequestDesiredSize (new);
413f80a6dcdSmrg	redisplay = TRUE;
414f80a6dcdSmrg    }
415f80a6dcdSmrg    return redisplay;
416f80a6dcdSmrg}
417f80a6dcdSmrg
418f80a6dcdSmrg/*
419f80a6dcdSmrg * use the set_values_hook entry to check when
420f80a6dcdSmrg * the file is set
421f80a6dcdSmrg */
422f80a6dcdSmrg
423f80a6dcdSmrgstatic Boolean
424f80a6dcdSmrgSetValuesHook (widget, args, num_argsp)
425f80a6dcdSmrg	Widget		widget;
426f80a6dcdSmrg	ArgList		args;
427f80a6dcdSmrg	Cardinal	*num_argsp;
428f80a6dcdSmrg{
429f80a6dcdSmrg	DviWidget	dw = (DviWidget) widget;
430f80a6dcdSmrg	Cardinal	i;
431f80a6dcdSmrg
432f80a6dcdSmrg	for (i = 0; i < *num_argsp; i++) {
433f80a6dcdSmrg		if (!strcmp (args[i].name, XtNfile)) {
434f80a6dcdSmrg			CloseFile (dw);
435f80a6dcdSmrg			OpenFile (dw);
436f80a6dcdSmrg			return TRUE;
437f80a6dcdSmrg		}
438f80a6dcdSmrg	}
439f80a6dcdSmrg	return FALSE;
440f80a6dcdSmrg}
441f80a6dcdSmrg
442f80a6dcdSmrgstatic void
443f80a6dcdSmrgCloseFile (dw)
444f80a6dcdSmrg	DviWidget	dw;
445f80a6dcdSmrg{
446f80a6dcdSmrg    if (dw->dvi.tmpFile)
447f80a6dcdSmrg	fclose (dw->dvi.tmpFile);
448f80a6dcdSmrg    ForgetPagePositions (dw);
449f80a6dcdSmrg}
450f80a6dcdSmrg
451f80a6dcdSmrgstatic void
452f80a6dcdSmrgOpenFile (dw)
453f80a6dcdSmrg	DviWidget	dw;
454f80a6dcdSmrg{
455f80a6dcdSmrg    char	tmpName[sizeof ("/tmp/dviXXXXXX")];
456f80a6dcdSmrg#ifdef HAS_MKSTEMP
457f80a6dcdSmrg    int fd;
458f80a6dcdSmrg#endif
459f80a6dcdSmrg
460f80a6dcdSmrg    dw->dvi.tmpFile = 0;
461f80a6dcdSmrg    if (!dw->dvi.seek) {
462f80a6dcdSmrg	strcpy (tmpName, "/tmp/dviXXXXXX");
463f80a6dcdSmrg#ifndef HAS_MKSTEMP
464f80a6dcdSmrg	mktemp (tmpName);
465f80a6dcdSmrg	dw->dvi.tmpFile = fopen (tmpName, "w+");
466f80a6dcdSmrg#else
467f80a6dcdSmrg	fd = mkstemp(tmpName);
468f80a6dcdSmrg	dw->dvi.tmpFile = fdopen(fd, "w+");
469f80a6dcdSmrg#endif
470f80a6dcdSmrg	unlink (tmpName);
471f80a6dcdSmrg    }
472f80a6dcdSmrg    if (dw->dvi.requested_page < 1)
473f80a6dcdSmrg	dw->dvi.requested_page = 1;
474f80a6dcdSmrg    dw->dvi.last_page = 0;
475f80a6dcdSmrg}
476f80a6dcdSmrg
477f80a6dcdSmrgstatic XtGeometryResult
478f80a6dcdSmrgQueryGeometry (w, request, geometry_return)
479f80a6dcdSmrg	Widget			w;
480f80a6dcdSmrg	XtWidgetGeometry	*request, *geometry_return;
481f80a6dcdSmrg{
482f80a6dcdSmrg	XtGeometryResult	ret;
483f80a6dcdSmrg	DviWidget		dw = (DviWidget) w;
484f80a6dcdSmrg
485f80a6dcdSmrg	ret = XtGeometryYes;
486f80a6dcdSmrg	if ((int)request->width < dw->dvi.desired_width
487f80a6dcdSmrg	    || (int)request->height < dw->dvi.desired_height)
488f80a6dcdSmrg		ret = XtGeometryAlmost;
489f80a6dcdSmrg	geometry_return->width = dw->dvi.desired_width;
490f80a6dcdSmrg	geometry_return->height = dw->dvi.desired_height;
491f80a6dcdSmrg	geometry_return->request_mode = CWWidth|CWHeight;
492f80a6dcdSmrg	return ret;
493f80a6dcdSmrg}
494f80a6dcdSmrg
495f80a6dcdSmrgvoid
496f80a6dcdSmrgSetDeviceResolution (dw, resolution)
497f80a6dcdSmrg	DviWidget   dw;
498f80a6dcdSmrg	int	    resolution;
499f80a6dcdSmrg{
500f80a6dcdSmrg    if (resolution != dw->dvi.device_resolution) {
501f80a6dcdSmrg	dw->dvi.device_resolution = resolution;
502f80a6dcdSmrg	dw->dvi.scale = ((double)  dw->dvi.screen_resolution) /
503f80a6dcdSmrg			((double) resolution);
504f80a6dcdSmrg    }
505f80a6dcdSmrg}
506f80a6dcdSmrg
507f80a6dcdSmrgstatic void
508f80a6dcdSmrgShowDvi (dw)
509f80a6dcdSmrg	DviWidget	dw;
510f80a6dcdSmrg{
511f80a6dcdSmrg	int	i;
512f80a6dcdSmrg	long	file_position;
513f80a6dcdSmrg
514f80a6dcdSmrg	if (!dw->dvi.file)
515f80a6dcdSmrg	  return;
516f80a6dcdSmrg
517f80a6dcdSmrg	if (dw->dvi.requested_page < 1)
518f80a6dcdSmrg		dw->dvi.requested_page = 1;
519f80a6dcdSmrg
520f80a6dcdSmrg	if (dw->dvi.last_page != 0 && dw->dvi.requested_page > dw->dvi.last_page)
521f80a6dcdSmrg		dw->dvi.requested_page = dw->dvi.last_page;
522f80a6dcdSmrg
523f80a6dcdSmrg	file_position = SearchPagePosition (dw, dw->dvi.requested_page);
524f80a6dcdSmrg	if (file_position != -1) {
525f80a6dcdSmrg		FileSeek(dw, file_position);
526f80a6dcdSmrg		dw->dvi.current_page = dw->dvi.requested_page;
527f80a6dcdSmrg	} else {
528f80a6dcdSmrg		for (i=dw->dvi.requested_page; i > 0; i--) {
529f80a6dcdSmrg			file_position = SearchPagePosition (dw, i);
530f80a6dcdSmrg			if (file_position != -1)
531f80a6dcdSmrg				break;
532f80a6dcdSmrg		}
533f80a6dcdSmrg		if (file_position == -1)
534f80a6dcdSmrg			file_position = 0;
535f80a6dcdSmrg		FileSeek (dw, file_position);
536f80a6dcdSmrg
537f80a6dcdSmrg		dw->dvi.current_page = i;
538f80a6dcdSmrg
539f80a6dcdSmrg		dw->dvi.display_enable = 0;
540f80a6dcdSmrg		while (dw->dvi.current_page != dw->dvi.requested_page) {
541f80a6dcdSmrg			dw->dvi.current_page = ParseInput (dw);
542f80a6dcdSmrg			/*
543f80a6dcdSmrg			 * at EOF, seek back to the begining of this page.
544f80a6dcdSmrg			 */
545f80a6dcdSmrg			if (feof (dw->dvi.file)) {
546f80a6dcdSmrg				file_position = SearchPagePosition (dw,
547f80a6dcdSmrg						dw->dvi.current_page);
548f80a6dcdSmrg				if (file_position != -1)
549f80a6dcdSmrg					FileSeek (dw, file_position);
550f80a6dcdSmrg				break;
551f80a6dcdSmrg			}
552f80a6dcdSmrg		}
553f80a6dcdSmrg	}
554f80a6dcdSmrg
555f80a6dcdSmrg	dw->dvi.display_enable = 1;
556f80a6dcdSmrg	ParseInput (dw);
557f80a6dcdSmrg	if (dw->dvi.last_page && dw->dvi.requested_page > dw->dvi.last_page)
558f80a6dcdSmrg		dw->dvi.requested_page = dw->dvi.last_page;
559f80a6dcdSmrg}
560