1151497Sru#ifndef SABER
2151497Sru#ifndef lint
3151497Srustatic char Xrcsid[] = "$XConsortium: Dvi.c,v 1.9 89/12/10 16:12:25 rws Exp $";
4151497Sru#endif /* lint */
5151497Sru#endif /* SABER */
6151497Sru
7151497Sru/*
8151497Sru * Dvi.c - Dvi display widget
9151497Sru *
10151497Sru */
11151497Sru
12151497Sru#define XtStrlen(s)	((s) ? strlen(s) : 0)
13151497Sru
14151497Sru  /* The following are defined for the reader's convenience.  Any
15151497Sru     Xt..Field macro in this code just refers to some field in
16151497Sru     one of the substructures of the WidgetRec.  */
17151497Sru
18151497Sru#include <X11/IntrinsicP.h>
19151497Sru#include <X11/StringDefs.h>
20151497Sru#include <X11/Xmu/Converters.h>
21151497Sru#include <stdio.h>
22151497Sru#include <ctype.h>
23151497Sru#include "DviP.h"
24151497Sru
25151497Sru/****************************************************************
26151497Sru *
27151497Sru * Full class record constant
28151497Sru *
29151497Sru ****************************************************************/
30151497Sru
31151497Sru/* Private Data */
32151497Sru
33151497Srustatic char default_font_map_1[] = "\
34151497SruTR	-adobe-times-medium-r-normal--*-100-*-*-*-*-iso8859-1\n\
35151497SruTI	-adobe-times-medium-i-normal--*-100-*-*-*-*-iso8859-1\n\
36151497SruTB	-adobe-times-bold-r-normal--*-100-*-*-*-*-iso8859-1\n\
37151497SruTBI	-adobe-times-bold-i-normal--*-100-*-*-*-*-iso8859-1\n\
38151497SruCR	-adobe-courier-medium-r-normal--*-100-*-*-*-*-iso8859-1\n\
39151497SruCI	-adobe-courier-medium-o-normal--*-100-*-*-*-*-iso8859-1\n\
40151497SruCB	-adobe-courier-bold-r-normal--*-100-*-*-*-*-iso8859-1\n\
41151497SruCBI	-adobe-courier-bold-o-normal--*-100-*-*-*-*-iso8859-1\n\
42151497Sru";
43151497Srustatic char default_font_map_2[] = "\
44151497SruHR	-adobe-helvetica-medium-r-normal--*-100-*-*-*-*-iso8859-1\n\
45151497SruHI	-adobe-helvetica-medium-o-normal--*-100-*-*-*-*-iso8859-1\n\
46151497SruHB	-adobe-helvetica-bold-r-normal--*-100-*-*-*-*-iso8859-1\n\
47151497SruHBI	-adobe-helvetica-bold-o-normal--*-100-*-*-*-*-iso8859-1\n\
48151497Sru";
49151497Srustatic char default_font_map_3[] = "\
50151497SruNR	-adobe-new century schoolbook-medium-r-normal--*-100-*-*-*-*-iso8859-1\n\
51151497SruNI	-adobe-new century schoolbook-medium-i-normal--*-100-*-*-*-*-iso8859-1\n\
52151497SruNB	-adobe-new century schoolbook-bold-r-normal--*-100-*-*-*-*-iso8859-1\n\
53151497SruNBI	-adobe-new century schoolbook-bold-i-normal--*-100-*-*-*-*-iso8859-1\n\
54151497SruS	-adobe-symbol-medium-r-normal--*-100-*-*-*-*-adobe-fontspecific\n\
55151497SruSS	-adobe-symbol-medium-r-normal--*-100-*-*-*-*-adobe-fontspecific\n\
56151497Sru";
57151497Sru
58151497Sru#define offset(field) XtOffset(DviWidget, field)
59151497Sru
60151497Sru#define MY_WIDTH(dw) ((int)(dw->dvi.paperwidth * dw->dvi.scale_factor + .5))
61151497Sru#define MY_HEIGHT(dw) ((int)(dw->dvi.paperlength * dw->dvi.scale_factor + .5))
62151497Sru
63151497Srustatic XtResource resources[] = {
64151497Sru	{(String)XtNfontMap, (String)XtCFontMap, (String)XtRString,
65151497Sru	 sizeof (char *), offset(dvi.font_map_string),
66151497Sru	 (String)XtRString, NULL /* set in code */},
67151497Sru	{(String)XtNforeground, (String)XtCForeground, (String)XtRPixel,
68151497Sru	 sizeof (unsigned long), offset(dvi.foreground),
69151497Sru	 (String)XtRString, (XtPointer)"XtDefaultForeground"},
70151497Sru	{(String)XtNbackground, (String)XtCBackground, (String)XtRPixel,
71151497Sru	 sizeof (unsigned long), offset(dvi.background),
72151497Sru	 (String)XtRString, (XtPointer)"XtDefaultBackground"},
73151497Sru	{(String)XtNpageNumber, (String)XtCPageNumber, (String)XtRInt,
74151497Sru	 sizeof (int), offset(dvi.requested_page),
75151497Sru	 (String)XtRString, (XtPointer)"1"},
76151497Sru	{(String)XtNlastPageNumber, (String)XtCLastPageNumber, (String)XtRInt,
77151497Sru	 sizeof (int), offset (dvi.last_page),
78151497Sru	 (String)XtRString, (XtPointer)"0"},
79151497Sru	{(String)XtNfile, (String)XtCFile, (String)XtRFile,
80151497Sru	 sizeof (FILE *), offset (dvi.file),
81151497Sru	 (String)XtRFile, (XtPointer)0},
82151497Sru	{(String)XtNseek, (String)XtCSeek, (String)XtRBoolean,
83151497Sru	 sizeof (Boolean), offset(dvi.seek),
84151497Sru	 (String)XtRString, (XtPointer)"false"},
85151497Sru	{(String)XtNfont, (String)XtCFont, (String)XtRFontStruct,
86151497Sru	 sizeof (XFontStruct *), offset(dvi.default_font),
87151497Sru	 (String)XtRString, (XtPointer)"xtdefaultfont"},
88151497Sru	{(String)XtNbackingStore, (String)XtCBackingStore, (String)XtRBackingStore,
89151497Sru	 sizeof (int), offset(dvi.backing_store),
90151497Sru	 (String)XtRString, (XtPointer)"default"},
91151497Sru	{(String)XtNnoPolyText, (String)XtCNoPolyText, (String)XtRBoolean,
92151497Sru	 sizeof (Boolean), offset(dvi.noPolyText),
93151497Sru	 (String)XtRString, (XtPointer)"false"},
94151497Sru	{(String)XtNresolution, (String)XtCResolution, (String)XtRInt,
95151497Sru	 sizeof(int), offset(dvi.default_resolution),
96151497Sru	 (String)XtRString, (XtPointer)"75"},
97151497Sru};
98151497Sru
99151497Sru#undef offset
100151497Sru
101151497Srustatic void		ClassInitialize (void);
102151497Srustatic void		ClassPartInitialize(WidgetClass);
103151497Srustatic void		Initialize(Widget, Widget, ArgList, Cardinal *);
104151497Srustatic void		Realize (Widget, XtValueMask *, XSetWindowAttributes *);
105151497Srustatic void		Destroy (Widget);
106151497Srustatic void		Redisplay (Widget, XEvent *, Region);
107151497Srustatic Boolean		SetValues (Widget, Widget, Widget,
108151497Sru				   ArgList, Cardinal *);
109151497Srustatic Boolean		SetValuesHook (Widget, ArgList, Cardinal *);
110151497Srustatic XtGeometryResult	QueryGeometry (Widget, XtWidgetGeometry *,
111151497Sru				       XtWidgetGeometry *);
112151497Srustatic void		ShowDvi (DviWidget);
113151497Srustatic void		CloseFile (DviWidget);
114151497Srustatic void		OpenFile (DviWidget);
115151497Srustatic void		FindPage (DviWidget);
116151497Sru
117151497Srustatic void		SaveToFile (Widget, FILE *);
118151497Sru
119151497Sru/* font.c */
120151497Sruextern void ParseFontMap(DviWidget);
121151497Sruextern void DestroyFontMap(DviFontMap *);
122151497Sruextern void ForgetFonts(DviWidget);
123151497Sru
124151497Sru/* page.c */
125151497Sruextern void DestroyFileMap(DviFileMap *);
126151497Sruextern long SearchPagePosition(DviWidget, int);
127151497Sruextern void FileSeek(DviWidget, long);
128151497Sruextern void ForgetPagePositions(DviWidget);
129151497Sru
130151497Sru/* parse.c */
131151497Sruextern int ParseInput(register DviWidget);
132151497Sru
133151497SruDviClassRec dviClassRec = {
134151497Sru{
135151497Sru	&widgetClassRec,		/* superclass		  */
136151497Sru	(String)"Dvi",			/* class_name		  */
137151497Sru	sizeof(DviRec),			/* size			  */
138151497Sru	ClassInitialize,		/* class_initialize	  */
139151497Sru	ClassPartInitialize,		/* class_part_initialize  */
140151497Sru	FALSE,				/* class_inited		  */
141151497Sru	Initialize,			/* initialize		  */
142151497Sru	NULL,				/* initialize_hook	  */
143151497Sru	Realize,			/* realize		  */
144151497Sru	NULL,				/* actions		  */
145151497Sru	0,				/* num_actions		  */
146151497Sru	resources,			/* resources		  */
147151497Sru	XtNumber(resources),		/* resource_count	  */
148151497Sru	NULLQUARK,			/* xrm_class		  */
149151497Sru	FALSE,				/* compress_motion	  */
150151497Sru	TRUE,				/* compress_exposure	  */
151151497Sru	TRUE,				/* compress_enterleave    */
152151497Sru	FALSE,				/* visible_interest	  */
153151497Sru	Destroy,			/* destroy		  */
154151497Sru	NULL,				/* resize		  */
155151497Sru	Redisplay,			/* expose		  */
156151497Sru	SetValues,			/* set_values		  */
157151497Sru	SetValuesHook,			/* set_values_hook	  */
158151497Sru	NULL,				/* set_values_almost	  */
159151497Sru	NULL,				/* get_values_hook	  */
160151497Sru	NULL,				/* accept_focus		  */
161151497Sru	XtVersion,			/* version		  */
162151497Sru	NULL,				/* callback_private	  */
163151497Sru	0,				/* tm_table		  */
164151497Sru	QueryGeometry,			/* query_geometry	  */
165151497Sru	NULL,				/* display_accelerator	  */
166151497Sru	NULL				/* extension		  */
167151497Sru},{
168151497Sru	SaveToFile,			/* save    */
169151497Sru},
170151497Sru};
171151497Sru
172151497SruWidgetClass dviWidgetClass = (WidgetClass) &dviClassRec;
173151497Sru
174151497Srustatic void ClassInitialize (void)
175151497Sru{
176151497Sru	int len1 = strlen(default_font_map_1);
177151497Sru	int len2 = strlen(default_font_map_2);
178151497Sru	int len3 = strlen(default_font_map_3);
179151497Sru	char *dfm = XtMalloc(len1 + len2 + len3 + 1);
180151497Sru	char *ptr = dfm;
181151497Sru	strcpy(ptr, default_font_map_1); ptr += len1;
182151497Sru	strcpy(ptr, default_font_map_2); ptr += len2;
183151497Sru	strcpy(ptr, default_font_map_3);
184151497Sru	resources[0].default_addr = dfm;
185151497Sru
186151497Sru	XtAddConverter( XtRString, XtRBackingStore, XmuCvtStringToBackingStore,
187151497Sru			NULL, 0 );
188151497Sru}
189151497Sru
190151497Sru/****************************************************************
191151497Sru *
192151497Sru * Private Procedures
193151497Sru *
194151497Sru ****************************************************************/
195151497Sru
196151497Sru/* ARGSUSED */
197151497Srustatic void Initialize(Widget request, Widget new_wd,
198151497Sru		       ArgList args, Cardinal *num_args)
199151497Sru{
200151497Sru	DviWidget	dw = (DviWidget) new_wd;
201151497Sru
202151497Sru	dw->dvi.current_page = 0;
203151497Sru	dw->dvi.font_map = 0;
204151497Sru	dw->dvi.cache.index = 0;
205151497Sru	dw->dvi.text_x_width = 0;
206151497Sru	dw->dvi.text_device_width = 0;
207151497Sru	dw->dvi.word_flag = 0;
208151497Sru	dw->dvi.file = 0;
209151497Sru	dw->dvi.tmpFile = 0;
210151497Sru	dw->dvi.state = 0;
211151497Sru	dw->dvi.readingTmp = 0;
212151497Sru	dw->dvi.cache.char_index = 0;
213151497Sru	dw->dvi.cache.font_size = -1;
214151497Sru	dw->dvi.cache.font_number = -1;
215151497Sru	dw->dvi.cache.adjustable[0] = 0;
216151497Sru	dw->dvi.file_map = 0;
217151497Sru	dw->dvi.fonts = 0;
218151497Sru	dw->dvi.seek = False;
219151497Sru	dw->dvi.device_resolution = dw->dvi.default_resolution;
220151497Sru	dw->dvi.display_resolution = dw->dvi.default_resolution;
221151497Sru	dw->dvi.paperlength = dw->dvi.default_resolution*11;
222151497Sru	dw->dvi.paperwidth = (dw->dvi.default_resolution*8
223151497Sru			      + dw->dvi.default_resolution/2);
224151497Sru	dw->dvi.scale_factor = 1.0;
225151497Sru	dw->dvi.sizescale = 1;
226151497Sru	dw->dvi.line_thickness = -1;
227151497Sru	dw->dvi.line_width = 1;
228151497Sru	dw->dvi.fill = DVI_FILL_MAX;
229151497Sru	dw->dvi.device_font = 0;
230151497Sru	dw->dvi.device_font_number = -1;
231151497Sru	dw->dvi.device = 0;
232151497Sru	dw->dvi.native = 0;
233151497Sru
234151497Sru	request = request;	/* unused; suppress compiler warning */
235151497Sru	args = args;
236151497Sru	num_args = num_args;
237151497Sru}
238151497Sru
239151497Sru#include "gray1.bm"
240151497Sru#include "gray2.bm"
241151497Sru#include "gray3.bm"
242151497Sru#include "gray4.bm"
243151497Sru#include "gray5.bm"
244151497Sru#include "gray6.bm"
245151497Sru#include "gray7.bm"
246151497Sru#include "gray8.bm"
247151497Sru
248151497Srustatic void
249151497SruRealize (Widget w, XtValueMask *valueMask, XSetWindowAttributes *attrs)
250151497Sru{
251151497Sru	DviWidget	dw = (DviWidget) w;
252151497Sru	XGCValues	values;
253151497Sru
254151497Sru	if (dw->dvi.backing_store != Always + WhenMapped + NotUseful) {
255151497Sru		attrs->backing_store = dw->dvi.backing_store;
256151497Sru		*valueMask |= CWBackingStore;
257151497Sru	}
258151497Sru	XtCreateWindow (w, (unsigned)InputOutput, (Visual *) CopyFromParent,
259151497Sru			*valueMask, attrs);
260151497Sru	values.foreground = dw->dvi.foreground;
261151497Sru	values.cap_style = CapRound;
262151497Sru	values.join_style = JoinRound;
263151497Sru	values.line_width = dw->dvi.line_width;
264151497Sru	dw->dvi.normal_GC = XCreateGC (XtDisplay (w), XtWindow (w),
265151497Sru				       GCForeground|GCCapStyle|GCJoinStyle
266151497Sru				       |GCLineWidth,
267151497Sru				       &values);
268151497Sru	dw->dvi.gray[0] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
269151497Sru					     gray1_bits,
270151497Sru					     gray1_width, gray1_height);
271151497Sru	dw->dvi.gray[1] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
272151497Sru					     gray2_bits,
273151497Sru					     gray2_width, gray2_height);
274151497Sru	dw->dvi.gray[2] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
275151497Sru					     gray3_bits,
276151497Sru					     gray3_width, gray3_height);
277151497Sru	dw->dvi.gray[3] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
278151497Sru					     gray4_bits,
279151497Sru					     gray4_width, gray4_height);
280151497Sru	dw->dvi.gray[4] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
281151497Sru					     gray5_bits,
282151497Sru					     gray5_width, gray5_height);
283151497Sru	dw->dvi.gray[5] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
284151497Sru					     gray6_bits,
285151497Sru					     gray6_width, gray6_height);
286151497Sru	dw->dvi.gray[6] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
287151497Sru					     gray7_bits,
288151497Sru					     gray7_width, gray7_height);
289151497Sru	dw->dvi.gray[7] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
290151497Sru					     gray8_bits,
291151497Sru					     gray8_width, gray8_height);
292151497Sru	values.background = dw->dvi.background;
293151497Sru	values.stipple = dw->dvi.gray[5];
294151497Sru	dw->dvi.fill_GC = XCreateGC (XtDisplay (w), XtWindow (w),
295151497Sru				     GCForeground|GCBackground|GCStipple,
296151497Sru				     &values);
297151497Sru
298151497Sru	dw->dvi.fill_type = 9;
299151497Sru
300151497Sru	if (dw->dvi.file)
301151497Sru		OpenFile (dw);
302151497Sru	ParseFontMap (dw);
303151497Sru}
304151497Sru
305151497Srustatic void
306151497SruDestroy(Widget w)
307151497Sru{
308151497Sru	DviWidget	dw = (DviWidget) w;
309151497Sru
310151497Sru	XFreeGC (XtDisplay (w), dw->dvi.normal_GC);
311151497Sru	XFreeGC (XtDisplay (w), dw->dvi.fill_GC);
312151497Sru	XFreePixmap (XtDisplay (w), dw->dvi.gray[0]);
313151497Sru	XFreePixmap (XtDisplay (w), dw->dvi.gray[1]);
314151497Sru	XFreePixmap (XtDisplay (w), dw->dvi.gray[2]);
315151497Sru	XFreePixmap (XtDisplay (w), dw->dvi.gray[3]);
316151497Sru	XFreePixmap (XtDisplay (w), dw->dvi.gray[4]);
317151497Sru	XFreePixmap (XtDisplay (w), dw->dvi.gray[5]);
318151497Sru	XFreePixmap (XtDisplay (w), dw->dvi.gray[6]);
319151497Sru	XFreePixmap (XtDisplay (w), dw->dvi.gray[7]);
320151497Sru	DestroyFontMap (dw->dvi.font_map);
321151497Sru	DestroyFileMap (dw->dvi.file_map);
322151497Sru	device_destroy (dw->dvi.device);
323151497Sru}
324151497Sru
325151497Sru/*
326151497Sru * Repaint the widget window
327151497Sru */
328151497Sru
329151497Sru/* ARGSUSED */
330151497Srustatic void
331151497SruRedisplay(Widget w, XEvent *event, Region region)
332151497Sru{
333151497Sru	DviWidget	dw = (DviWidget) w;
334151497Sru	XRectangle	extents;
335151497Sru
336151497Sru	XClipBox (region, &extents);
337151497Sru	dw->dvi.extents.x1 = extents.x;
338151497Sru	dw->dvi.extents.y1 = extents.y;
339151497Sru	dw->dvi.extents.x2 = extents.x + extents.width;
340151497Sru	dw->dvi.extents.y2 = extents.y + extents.height;
341151497Sru	ShowDvi (dw);
342151497Sru
343151497Sru	event = event;		/* unused; suppress compiler warning */
344151497Sru}
345151497Sru
346151497Sru/*
347151497Sru * Set specified arguments into widget
348151497Sru */
349151497Sru/* ARGSUSED */
350151497Srustatic Boolean
351151497SruSetValues (Widget wcurrent, Widget wrequest, Widget wnew,
352151497Sru	   ArgList args, Cardinal *num_args)
353151497Sru{
354151497Sru	Boolean		redisplay = FALSE;
355151497Sru	char		*new_map;
356151497Sru	int		cur, req;
357151497Sru	DviWidget	current = (DviWidget)wcurrent;
358151497Sru	DviWidget	request = (DviWidget)wrequest;
359151497Sru	DviWidget	new_wd = (DviWidget)wnew;
360151497Sru
361151497Sru	if (current->dvi.font_map_string != request->dvi.font_map_string) {
362151497Sru		new_map = XtMalloc (strlen (request->dvi.font_map_string) + 1);
363151497Sru		if (new_map) {
364151497Sru			redisplay = TRUE;
365151497Sru			strcpy (new_map, request->dvi.font_map_string);
366151497Sru			new_wd->dvi.font_map_string = new_map;
367151497Sru			if (current->dvi.font_map_string)
368151497Sru				XtFree (current->dvi.font_map_string);
369151497Sru			current->dvi.font_map_string = 0;
370151497Sru			ParseFontMap (new_wd);
371151497Sru		}
372151497Sru	}
373151497Sru
374151497Sru	req = request->dvi.requested_page;
375151497Sru	cur = current->dvi.requested_page;
376151497Sru	if (cur != req) {
377151497Sru		if (!request->dvi.file)
378151497Sru		    req = 0;
379151497Sru		else {
380151497Sru		    if (req < 1)
381151497Sru			    req = 1;
382151497Sru		    if (current->dvi.last_page != 0 &&
383151497Sru			req > current->dvi.last_page)
384151497Sru			    req = current->dvi.last_page;
385151497Sru		}
386151497Sru		if (cur != req)
387151497Sru	    	    redisplay = TRUE;
388151497Sru		new_wd->dvi.requested_page = req;
389151497Sru		if (current->dvi.last_page == 0 && req > cur)
390151497Sru			FindPage (new_wd);
391151497Sru	}
392151497Sru
393151497Sru	args = args;		/* unused; suppress compiler warning */
394151497Sru	num_args = num_args;
395151497Sru
396151497Sru	return redisplay;
397151497Sru}
398151497Sru
399151497Sru/*
400151497Sru * use the set_values_hook entry to check when
401151497Sru * the file is set
402151497Sru */
403151497Sru
404151497Srustatic Boolean
405151497SruSetValuesHook (Widget wdw, ArgList args, Cardinal *num_argsp)
406151497Sru{
407151497Sru	Cardinal	i;
408151497Sru	DviWidget	dw = (DviWidget)wdw;
409151497Sru
410151497Sru	for (i = 0; i < *num_argsp; i++) {
411151497Sru		if (!strcmp (args[i].name, XtNfile)) {
412151497Sru			CloseFile (dw);
413151497Sru			OpenFile (dw);
414151497Sru			return TRUE;
415151497Sru		}
416151497Sru	}
417151497Sru	return FALSE;
418151497Sru}
419151497Sru
420151497Srustatic void CloseFile (DviWidget dw)
421151497Sru{
422151497Sru	if (dw->dvi.tmpFile)
423151497Sru		fclose (dw->dvi.tmpFile);
424151497Sru	ForgetPagePositions (dw);
425151497Sru}
426151497Sru
427151497Srustatic void OpenFile (DviWidget dw)
428151497Sru{
429151497Sru	dw->dvi.tmpFile = 0;
430151497Sru	if (!dw->dvi.seek)
431151497Sru		dw->dvi.tmpFile = tmpfile();
432151497Sru	dw->dvi.requested_page = 1;
433151497Sru	dw->dvi.last_page = 0;
434151497Sru}
435151497Sru
436151497Srustatic XtGeometryResult
437151497SruQueryGeometry (Widget w, XtWidgetGeometry *request,
438151497Sru	       XtWidgetGeometry *geometry_return)
439151497Sru{
440151497Sru	XtGeometryResult	ret;
441151497Sru	DviWidget		dw = (DviWidget) w;
442151497Sru
443151497Sru	ret = XtGeometryYes;
444151497Sru	if (((request->request_mode & CWWidth)
445151497Sru	     && request->width < MY_WIDTH(dw))
446151497Sru	    || ((request->request_mode & CWHeight)
447151497Sru		&& request->height < MY_HEIGHT(dw)))
448151497Sru		ret = XtGeometryAlmost;
449151497Sru	geometry_return->width = MY_WIDTH(dw);
450151497Sru	geometry_return->height = MY_HEIGHT(dw);
451151497Sru	geometry_return->request_mode = CWWidth|CWHeight;
452151497Sru	return ret;
453151497Sru}
454151497Sru
455151497Sruvoid
456151497SruSetDevice (DviWidget dw, const char *name)
457151497Sru{
458151497Sru	XtWidgetGeometry	request, reply;
459151497Sru	XtGeometryResult ret;
460151497Sru
461151497Sru	ForgetFonts (dw);
462151497Sru	dw->dvi.device = device_load (name);
463151497Sru	if (!dw->dvi.device)
464151497Sru		return;
465151497Sru	dw->dvi.sizescale = dw->dvi.device->sizescale;
466151497Sru	dw->dvi.device_resolution = dw->dvi.device->res;
467151497Sru	dw->dvi.native = dw->dvi.device->X11;
468151497Sru	dw->dvi.paperlength = dw->dvi.device->paperlength;
469151497Sru	dw->dvi.paperwidth = dw->dvi.device->paperwidth;
470151497Sru	if (dw->dvi.native) {
471151497Sru		dw->dvi.display_resolution = dw->dvi.device_resolution;
472151497Sru		dw->dvi.scale_factor = 1.0;
473151497Sru	}
474151497Sru	else {
475151497Sru		dw->dvi.display_resolution = dw->dvi.default_resolution;
476151497Sru		dw->dvi.scale_factor = ((double)dw->dvi.display_resolution
477151497Sru					/ dw->dvi.device_resolution);
478151497Sru	}
479151497Sru	request.request_mode = CWWidth|CWHeight;
480151497Sru	request.width = MY_WIDTH(dw);
481151497Sru	request.height = MY_HEIGHT(dw);
482151497Sru	ret = XtMakeGeometryRequest ((Widget)dw, &request, &reply);
483151497Sru	if (ret == XtGeometryAlmost
484151497Sru	    && reply.height >= request.height
485151497Sru	    && reply.width >= request.width) {
486151497Sru		request.width = reply.width;
487151497Sru		request.height = reply.height;
488151497Sru		XtMakeGeometryRequest ((Widget)dw, &request, &reply);
489151497Sru	}
490151497Sru}
491151497Sru
492151497Srustatic void
493151497SruShowDvi (DviWidget dw)
494151497Sru{
495151497Sru	if (!dw->dvi.file) {
496151497Sru		static char Error[] = "No file selected";
497151497Sru
498151497Sru		XSetFont (XtDisplay(dw), dw->dvi.normal_GC,
499151497Sru			  dw->dvi.default_font->fid);
500151497Sru		XDrawString (XtDisplay (dw), XtWindow (dw), dw->dvi.normal_GC,
501151497Sru			     20, 20, Error, strlen (Error));
502151497Sru		return;
503151497Sru	}
504151497Sru
505151497Sru	FindPage (dw);
506151497Sru
507151497Sru	dw->dvi.display_enable = 1;
508151497Sru	ParseInput (dw);
509151497Sru	if (dw->dvi.last_page && dw->dvi.requested_page > dw->dvi.last_page)
510151497Sru		dw->dvi.requested_page = dw->dvi.last_page;
511151497Sru}
512151497Sru
513151497Srustatic void
514151497SruFindPage (DviWidget dw)
515151497Sru{
516151497Sru	int	i;
517151497Sru	long	file_position;
518151497Sru
519151497Sru	if (dw->dvi.requested_page < 1)
520151497Sru		dw->dvi.requested_page = 1;
521151497Sru
522151497Sru	if (dw->dvi.last_page != 0 && dw->dvi.requested_page > dw->dvi.last_page)
523151497Sru		dw->dvi.requested_page = dw->dvi.last_page;
524151497Sru
525151497Sru	file_position = SearchPagePosition (dw, dw->dvi.requested_page);
526151497Sru	if (file_position != -1) {
527151497Sru		FileSeek(dw, file_position);
528151497Sru		dw->dvi.current_page = dw->dvi.requested_page;
529151497Sru	} else {
530151497Sru		for (i=dw->dvi.requested_page; i > 0; i--) {
531151497Sru			file_position = SearchPagePosition (dw, i);
532151497Sru			if (file_position != -1)
533151497Sru				break;
534151497Sru		}
535151497Sru		if (file_position == -1)
536151497Sru			file_position = 0;
537151497Sru		FileSeek (dw, file_position);
538151497Sru
539151497Sru		dw->dvi.current_page = i;
540151497Sru
541151497Sru		dw->dvi.display_enable = 0;
542151497Sru		while (dw->dvi.current_page != dw->dvi.requested_page) {
543151497Sru			dw->dvi.current_page = ParseInput (dw);
544151497Sru			/*
545151497Sru			 * at EOF, seek back to the beginning of this page.
546151497Sru			 */
547151497Sru			if (!dw->dvi.readingTmp && feof (dw->dvi.file)) {
548151497Sru				file_position = SearchPagePosition (dw,
549151497Sru						dw->dvi.current_page);
550151497Sru				if (file_position != -1)
551151497Sru					FileSeek (dw, file_position);
552151497Sru				dw->dvi.requested_page = dw->dvi.current_page;
553151497Sru				break;
554151497Sru			}
555151497Sru		}
556151497Sru	}
557151497Sru}
558151497Sru
559151497Sruvoid DviSaveToFile(Widget w, FILE *fp)
560151497Sru{
561151497Sru	XtCheckSubclass(w, dviWidgetClass, NULL);
562151497Sru	(*((DviWidgetClass) XtClass(w))->command_class.save)(w, fp);
563151497Sru}
564151497Sru
565151497Srustatic
566151497Sruvoid SaveToFile(Widget w, FILE *fp)
567151497Sru{
568151497Sru	DviWidget dw = (DviWidget)w;
569151497Sru	long pos;
570151497Sru	int c;
571151497Sru
572151497Sru	if (dw->dvi.tmpFile) {
573151497Sru		pos = ftell(dw->dvi.tmpFile);
574151497Sru		if (dw->dvi.ungot) {
575151497Sru			pos--;
576151497Sru			dw->dvi.ungot = 0;
577151497Sru			/* The ungot character is in the tmpFile, so we don't
578151497Sru			   want to read it from file. */
579151497Sru			(void)getc(dw->dvi.file);
580151497Sru		}
581151497Sru	}
582151497Sru	else
583151497Sru		pos = ftell(dw->dvi.file);
584151497Sru	FileSeek(dw, 0L);
585151497Sru	while (DviGetC(dw, &c) != EOF)
586151497Sru		if (putc(c, fp) == EOF) {
587151497Sru			/* XXX print error message */
588151497Sru			break;
589151497Sru		}
590151497Sru	FileSeek(dw, pos);
591151497Sru}
592151497Sru
593151497Srustatic
594151497Sruvoid ClassPartInitialize(WidgetClass widget_class)
595151497Sru{
596151497Sru	DviWidgetClass wc = (DviWidgetClass)widget_class;
597151497Sru	DviWidgetClass super = (DviWidgetClass) wc->core_class.superclass;
598151497Sru	if (wc->command_class.save == InheritSaveToFile)
599151497Sru		wc->command_class.save = super->command_class.save;
600151497Sru}
601151497Sru
602151497Sru/*
603151497SruLocal Variables:
604151497Sruc-indent-level: 8
605151497Sruc-continued-statement-offset: 8
606151497Sruc-brace-offset: -8
607151497Sruc-argdecl-indent: 8
608151497Sruc-label-offset: -8
609151497Sruc-tab-always-indent: nil
610151497SruEnd:
611151497Sru*/
612