1 #ifndef SABER
2 #ifndef lint
3 static char Xrcsid[] = "$XConsortium: Dvi.c,v 1.9 89/12/10 16:12:25 rws Exp $";
4 #endif /* lint */
5 #endif /* SABER */
6 
7 /*
8  * Dvi.c - Dvi display widget
9  *
10  */
11 
12 #define XtStrlen(s)	((s) ? strlen(s) : 0)
13 
14   /* The following are defined for the reader's convenience.  Any
15      Xt..Field macro in this code just refers to some field in
16      one of the substructures of the WidgetRec.  */
17 
18 #include <X11/IntrinsicP.h>
19 #include <X11/StringDefs.h>
20 #include <X11/Xmu/Converters.h>
21 #include <stdio.h>
22 #include <ctype.h>
23 #include "DviP.h"
24 
25 /****************************************************************
26  *
27  * Full class record constant
28  *
29  ****************************************************************/
30 
31 /* Private Data */
32 
33 static char default_font_map_1[] = "\
34 TR	-adobe-times-medium-r-normal--*-100-*-*-*-*-iso8859-1\n\
35 TI	-adobe-times-medium-i-normal--*-100-*-*-*-*-iso8859-1\n\
36 TB	-adobe-times-bold-r-normal--*-100-*-*-*-*-iso8859-1\n\
37 TBI	-adobe-times-bold-i-normal--*-100-*-*-*-*-iso8859-1\n\
38 CR	-adobe-courier-medium-r-normal--*-100-*-*-*-*-iso8859-1\n\
39 CI	-adobe-courier-medium-o-normal--*-100-*-*-*-*-iso8859-1\n\
40 CB	-adobe-courier-bold-r-normal--*-100-*-*-*-*-iso8859-1\n\
41 CBI	-adobe-courier-bold-o-normal--*-100-*-*-*-*-iso8859-1\n\
42 ";
43 static char default_font_map_2[] = "\
44 HR	-adobe-helvetica-medium-r-normal--*-100-*-*-*-*-iso8859-1\n\
45 HI	-adobe-helvetica-medium-o-normal--*-100-*-*-*-*-iso8859-1\n\
46 HB	-adobe-helvetica-bold-r-normal--*-100-*-*-*-*-iso8859-1\n\
47 HBI	-adobe-helvetica-bold-o-normal--*-100-*-*-*-*-iso8859-1\n\
48 ";
49 static char default_font_map_3[] = "\
50 NR	-adobe-new century schoolbook-medium-r-normal--*-100-*-*-*-*-iso8859-1\n\
51 NI	-adobe-new century schoolbook-medium-i-normal--*-100-*-*-*-*-iso8859-1\n\
52 NB	-adobe-new century schoolbook-bold-r-normal--*-100-*-*-*-*-iso8859-1\n\
53 NBI	-adobe-new century schoolbook-bold-i-normal--*-100-*-*-*-*-iso8859-1\n\
54 S	-adobe-symbol-medium-r-normal--*-100-*-*-*-*-adobe-fontspecific\n\
55 SS	-adobe-symbol-medium-r-normal--*-100-*-*-*-*-adobe-fontspecific\n\
56 ";
57 
58 #define offset(field) XtOffset(DviWidget, field)
59 
60 #define MY_WIDTH(dw) ((int)(dw->dvi.paperwidth * dw->dvi.scale_factor + .5))
61 #define MY_HEIGHT(dw) ((int)(dw->dvi.paperlength * dw->dvi.scale_factor + .5))
62 
63 static XtResource resources[] = {
64 	{(String)XtNfontMap, (String)XtCFontMap, (String)XtRString,
65 	 sizeof (char *), offset(dvi.font_map_string),
66 	 (String)XtRString, NULL /* set in code */},
67 	{(String)XtNforeground, (String)XtCForeground, (String)XtRPixel,
68 	 sizeof (unsigned long), offset(dvi.foreground),
69 	 (String)XtRString, (XtPointer)"XtDefaultForeground"},
70 	{(String)XtNbackground, (String)XtCBackground, (String)XtRPixel,
71 	 sizeof (unsigned long), offset(dvi.background),
72 	 (String)XtRString, (XtPointer)"XtDefaultBackground"},
73 	{(String)XtNpageNumber, (String)XtCPageNumber, (String)XtRInt,
74 	 sizeof (int), offset(dvi.requested_page),
75 	 (String)XtRString, (XtPointer)"1"},
76 	{(String)XtNlastPageNumber, (String)XtCLastPageNumber, (String)XtRInt,
77 	 sizeof (int), offset (dvi.last_page),
78 	 (String)XtRString, (XtPointer)"0"},
79 	{(String)XtNfile, (String)XtCFile, (String)XtRFile,
80 	 sizeof (FILE *), offset (dvi.file),
81 	 (String)XtRFile, (XtPointer)0},
82 	{(String)XtNseek, (String)XtCSeek, (String)XtRBoolean,
83 	 sizeof (Boolean), offset(dvi.seek),
84 	 (String)XtRString, (XtPointer)"false"},
85 	{(String)XtNfont, (String)XtCFont, (String)XtRFontStruct,
86 	 sizeof (XFontStruct *), offset(dvi.default_font),
87 	 (String)XtRString, (XtPointer)"xtdefaultfont"},
88 	{(String)XtNbackingStore, (String)XtCBackingStore, (String)XtRBackingStore,
89 	 sizeof (int), offset(dvi.backing_store),
90 	 (String)XtRString, (XtPointer)"default"},
91 	{(String)XtNnoPolyText, (String)XtCNoPolyText, (String)XtRBoolean,
92 	 sizeof (Boolean), offset(dvi.noPolyText),
93 	 (String)XtRString, (XtPointer)"false"},
94 	{(String)XtNresolution, (String)XtCResolution, (String)XtRInt,
95 	 sizeof(int), offset(dvi.default_resolution),
96 	 (String)XtRString, (XtPointer)"75"},
97 };
98 
99 #undef offset
100 
101 static void		ClassInitialize (void);
102 static void		ClassPartInitialize(WidgetClass);
103 static void		Initialize(Widget, Widget, ArgList, Cardinal *);
104 static void		Realize (Widget, XtValueMask *, XSetWindowAttributes *);
105 static void		Destroy (Widget);
106 static void		Redisplay (Widget, XEvent *, Region);
107 static Boolean		SetValues (Widget, Widget, Widget,
108 				   ArgList, Cardinal *);
109 static Boolean		SetValuesHook (Widget, ArgList, Cardinal *);
110 static XtGeometryResult	QueryGeometry (Widget, XtWidgetGeometry *,
111 				       XtWidgetGeometry *);
112 static void		ShowDvi (DviWidget);
113 static void		CloseFile (DviWidget);
114 static void		OpenFile (DviWidget);
115 static void		FindPage (DviWidget);
116 
117 static void		SaveToFile (Widget, FILE *);
118 
119 /* font.c */
120 extern void ParseFontMap(DviWidget);
121 extern void DestroyFontMap(DviFontMap *);
122 extern void ForgetFonts(DviWidget);
123 
124 /* page.c */
125 extern void DestroyFileMap(DviFileMap *);
126 extern long SearchPagePosition(DviWidget, int);
127 extern void FileSeek(DviWidget, long);
128 extern void ForgetPagePositions(DviWidget);
129 
130 /* parse.c */
131 extern int ParseInput(register DviWidget);
132 
133 DviClassRec dviClassRec = {
134 {
135 	&widgetClassRec,		/* superclass		  */
136 	(String)"Dvi",			/* class_name		  */
137 	sizeof(DviRec),			/* size			  */
138 	ClassInitialize,		/* class_initialize	  */
139 	ClassPartInitialize,		/* class_part_initialize  */
140 	FALSE,				/* class_inited		  */
141 	Initialize,			/* initialize		  */
142 	NULL,				/* initialize_hook	  */
143 	Realize,			/* realize		  */
144 	NULL,				/* actions		  */
145 	0,				/* num_actions		  */
146 	resources,			/* resources		  */
147 	XtNumber(resources),		/* resource_count	  */
148 	NULLQUARK,			/* xrm_class		  */
149 	FALSE,				/* compress_motion	  */
150 	TRUE,				/* compress_exposure	  */
151 	TRUE,				/* compress_enterleave    */
152 	FALSE,				/* visible_interest	  */
153 	Destroy,			/* destroy		  */
154 	NULL,				/* resize		  */
155 	Redisplay,			/* expose		  */
156 	SetValues,			/* set_values		  */
157 	SetValuesHook,			/* set_values_hook	  */
158 	NULL,				/* set_values_almost	  */
159 	NULL,				/* get_values_hook	  */
160 	NULL,				/* accept_focus		  */
161 	XtVersion,			/* version		  */
162 	NULL,				/* callback_private	  */
163 	0,				/* tm_table		  */
164 	QueryGeometry,			/* query_geometry	  */
165 	NULL,				/* display_accelerator	  */
166 	NULL				/* extension		  */
167 },{
168 	SaveToFile,			/* save    */
169 },
170 };
171 
172 WidgetClass dviWidgetClass = (WidgetClass) &dviClassRec;
173 
ClassInitialize(void)174 static void ClassInitialize (void)
175 {
176 	int len1 = strlen(default_font_map_1);
177 	int len2 = strlen(default_font_map_2);
178 	int len3 = strlen(default_font_map_3);
179 	char *dfm = XtMalloc(len1 + len2 + len3 + 1);
180 	char *ptr = dfm;
181 	strcpy(ptr, default_font_map_1); ptr += len1;
182 	strcpy(ptr, default_font_map_2); ptr += len2;
183 	strcpy(ptr, default_font_map_3);
184 	resources[0].default_addr = dfm;
185 
186 	XtAddConverter( XtRString, XtRBackingStore, XmuCvtStringToBackingStore,
187 			NULL, 0 );
188 }
189 
190 /****************************************************************
191  *
192  * Private Procedures
193  *
194  ****************************************************************/
195 
196 /* ARGSUSED */
Initialize(Widget request,Widget new_wd,ArgList args,Cardinal * num_args)197 static void Initialize(Widget request, Widget new_wd,
198 		       ArgList args, Cardinal *num_args)
199 {
200 	DviWidget	dw = (DviWidget) new_wd;
201 
202 	dw->dvi.current_page = 0;
203 	dw->dvi.font_map = 0;
204 	dw->dvi.cache.index = 0;
205 	dw->dvi.text_x_width = 0;
206 	dw->dvi.text_device_width = 0;
207 	dw->dvi.word_flag = 0;
208 	dw->dvi.file = 0;
209 	dw->dvi.tmpFile = 0;
210 	dw->dvi.state = 0;
211 	dw->dvi.readingTmp = 0;
212 	dw->dvi.cache.char_index = 0;
213 	dw->dvi.cache.font_size = -1;
214 	dw->dvi.cache.font_number = -1;
215 	dw->dvi.cache.adjustable[0] = 0;
216 	dw->dvi.file_map = 0;
217 	dw->dvi.fonts = 0;
218 	dw->dvi.seek = False;
219 	dw->dvi.device_resolution = dw->dvi.default_resolution;
220 	dw->dvi.display_resolution = dw->dvi.default_resolution;
221 	dw->dvi.paperlength = dw->dvi.default_resolution*11;
222 	dw->dvi.paperwidth = (dw->dvi.default_resolution*8
223 			      + dw->dvi.default_resolution/2);
224 	dw->dvi.scale_factor = 1.0;
225 	dw->dvi.sizescale = 1;
226 	dw->dvi.line_thickness = -1;
227 	dw->dvi.line_width = 1;
228 	dw->dvi.fill = DVI_FILL_MAX;
229 	dw->dvi.device_font = 0;
230 	dw->dvi.device_font_number = -1;
231 	dw->dvi.device = 0;
232 	dw->dvi.native = 0;
233 
234 	request = request;	/* unused; suppress compiler warning */
235 	args = args;
236 	num_args = num_args;
237 }
238 
239 #include "gray1.bm"
240 #include "gray2.bm"
241 #include "gray3.bm"
242 #include "gray4.bm"
243 #include "gray5.bm"
244 #include "gray6.bm"
245 #include "gray7.bm"
246 #include "gray8.bm"
247 
248 static void
Realize(Widget w,XtValueMask * valueMask,XSetWindowAttributes * attrs)249 Realize (Widget w, XtValueMask *valueMask, XSetWindowAttributes *attrs)
250 {
251 	DviWidget	dw = (DviWidget) w;
252 	XGCValues	values;
253 
254 	if (dw->dvi.backing_store != Always + WhenMapped + NotUseful) {
255 		attrs->backing_store = dw->dvi.backing_store;
256 		*valueMask |= CWBackingStore;
257 	}
258 	XtCreateWindow (w, (unsigned)InputOutput, (Visual *) CopyFromParent,
259 			*valueMask, attrs);
260 	values.foreground = dw->dvi.foreground;
261 	values.cap_style = CapRound;
262 	values.join_style = JoinRound;
263 	values.line_width = dw->dvi.line_width;
264 	dw->dvi.normal_GC = XCreateGC (XtDisplay (w), XtWindow (w),
265 				       GCForeground|GCCapStyle|GCJoinStyle
266 				       |GCLineWidth,
267 				       &values);
268 	dw->dvi.gray[0] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
269 					     gray1_bits,
270 					     gray1_width, gray1_height);
271 	dw->dvi.gray[1] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
272 					     gray2_bits,
273 					     gray2_width, gray2_height);
274 	dw->dvi.gray[2] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
275 					     gray3_bits,
276 					     gray3_width, gray3_height);
277 	dw->dvi.gray[3] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
278 					     gray4_bits,
279 					     gray4_width, gray4_height);
280 	dw->dvi.gray[4] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
281 					     gray5_bits,
282 					     gray5_width, gray5_height);
283 	dw->dvi.gray[5] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
284 					     gray6_bits,
285 					     gray6_width, gray6_height);
286 	dw->dvi.gray[6] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
287 					     gray7_bits,
288 					     gray7_width, gray7_height);
289 	dw->dvi.gray[7] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
290 					     gray8_bits,
291 					     gray8_width, gray8_height);
292 	values.background = dw->dvi.background;
293 	values.stipple = dw->dvi.gray[5];
294 	dw->dvi.fill_GC = XCreateGC (XtDisplay (w), XtWindow (w),
295 				     GCForeground|GCBackground|GCStipple,
296 				     &values);
297 
298 	dw->dvi.fill_type = 9;
299 
300 	if (dw->dvi.file)
301 		OpenFile (dw);
302 	ParseFontMap (dw);
303 }
304 
305 static void
Destroy(Widget w)306 Destroy(Widget w)
307 {
308 	DviWidget	dw = (DviWidget) w;
309 
310 	XFreeGC (XtDisplay (w), dw->dvi.normal_GC);
311 	XFreeGC (XtDisplay (w), dw->dvi.fill_GC);
312 	XFreePixmap (XtDisplay (w), dw->dvi.gray[0]);
313 	XFreePixmap (XtDisplay (w), dw->dvi.gray[1]);
314 	XFreePixmap (XtDisplay (w), dw->dvi.gray[2]);
315 	XFreePixmap (XtDisplay (w), dw->dvi.gray[3]);
316 	XFreePixmap (XtDisplay (w), dw->dvi.gray[4]);
317 	XFreePixmap (XtDisplay (w), dw->dvi.gray[5]);
318 	XFreePixmap (XtDisplay (w), dw->dvi.gray[6]);
319 	XFreePixmap (XtDisplay (w), dw->dvi.gray[7]);
320 	DestroyFontMap (dw->dvi.font_map);
321 	DestroyFileMap (dw->dvi.file_map);
322 	device_destroy (dw->dvi.device);
323 }
324 
325 /*
326  * Repaint the widget window
327  */
328 
329 /* ARGSUSED */
330 static void
Redisplay(Widget w,XEvent * event,Region region)331 Redisplay(Widget w, XEvent *event, Region region)
332 {
333 	DviWidget	dw = (DviWidget) w;
334 	XRectangle	extents;
335 
336 	XClipBox (region, &extents);
337 	dw->dvi.extents.x1 = extents.x;
338 	dw->dvi.extents.y1 = extents.y;
339 	dw->dvi.extents.x2 = extents.x + extents.width;
340 	dw->dvi.extents.y2 = extents.y + extents.height;
341 	ShowDvi (dw);
342 
343 	event = event;		/* unused; suppress compiler warning */
344 }
345 
346 /*
347  * Set specified arguments into widget
348  */
349 /* ARGSUSED */
350 static Boolean
SetValues(Widget wcurrent,Widget wrequest,Widget wnew,ArgList args,Cardinal * num_args)351 SetValues (Widget wcurrent, Widget wrequest, Widget wnew,
352 	   ArgList args, Cardinal *num_args)
353 {
354 	Boolean		redisplay = FALSE;
355 	char		*new_map;
356 	int		cur, req;
357 	DviWidget	current = (DviWidget)wcurrent;
358 	DviWidget	request = (DviWidget)wrequest;
359 	DviWidget	new_wd = (DviWidget)wnew;
360 
361 	if (current->dvi.font_map_string != request->dvi.font_map_string) {
362 		new_map = XtMalloc (strlen (request->dvi.font_map_string) + 1);
363 		if (new_map) {
364 			redisplay = TRUE;
365 			strcpy (new_map, request->dvi.font_map_string);
366 			new_wd->dvi.font_map_string = new_map;
367 			if (current->dvi.font_map_string)
368 				XtFree (current->dvi.font_map_string);
369 			current->dvi.font_map_string = 0;
370 			ParseFontMap (new_wd);
371 		}
372 	}
373 
374 	req = request->dvi.requested_page;
375 	cur = current->dvi.requested_page;
376 	if (cur != req) {
377 		if (!request->dvi.file)
378 		    req = 0;
379 		else {
380 		    if (req < 1)
381 			    req = 1;
382 		    if (current->dvi.last_page != 0 &&
383 			req > current->dvi.last_page)
384 			    req = current->dvi.last_page;
385 		}
386 		if (cur != req)
387 	    	    redisplay = TRUE;
388 		new_wd->dvi.requested_page = req;
389 		if (current->dvi.last_page == 0 && req > cur)
390 			FindPage (new_wd);
391 	}
392 
393 	args = args;		/* unused; suppress compiler warning */
394 	num_args = num_args;
395 
396 	return redisplay;
397 }
398 
399 /*
400  * use the set_values_hook entry to check when
401  * the file is set
402  */
403 
404 static Boolean
SetValuesHook(Widget wdw,ArgList args,Cardinal * num_argsp)405 SetValuesHook (Widget wdw, ArgList args, Cardinal *num_argsp)
406 {
407 	Cardinal	i;
408 	DviWidget	dw = (DviWidget)wdw;
409 
410 	for (i = 0; i < *num_argsp; i++) {
411 		if (!strcmp (args[i].name, XtNfile)) {
412 			CloseFile (dw);
413 			OpenFile (dw);
414 			return TRUE;
415 		}
416 	}
417 	return FALSE;
418 }
419 
CloseFile(DviWidget dw)420 static void CloseFile (DviWidget dw)
421 {
422 	if (dw->dvi.tmpFile)
423 		fclose (dw->dvi.tmpFile);
424 	ForgetPagePositions (dw);
425 }
426 
OpenFile(DviWidget dw)427 static void OpenFile (DviWidget dw)
428 {
429 	dw->dvi.tmpFile = 0;
430 	if (!dw->dvi.seek)
431 		dw->dvi.tmpFile = tmpfile();
432 	dw->dvi.requested_page = 1;
433 	dw->dvi.last_page = 0;
434 }
435 
436 static XtGeometryResult
QueryGeometry(Widget w,XtWidgetGeometry * request,XtWidgetGeometry * geometry_return)437 QueryGeometry (Widget w, XtWidgetGeometry *request,
438 	       XtWidgetGeometry *geometry_return)
439 {
440 	XtGeometryResult	ret;
441 	DviWidget		dw = (DviWidget) w;
442 
443 	ret = XtGeometryYes;
444 	if (((request->request_mode & CWWidth)
445 	     && request->width < MY_WIDTH(dw))
446 	    || ((request->request_mode & CWHeight)
447 		&& request->height < MY_HEIGHT(dw)))
448 		ret = XtGeometryAlmost;
449 	geometry_return->width = MY_WIDTH(dw);
450 	geometry_return->height = MY_HEIGHT(dw);
451 	geometry_return->request_mode = CWWidth|CWHeight;
452 	return ret;
453 }
454 
455 void
SetDevice(DviWidget dw,const char * name)456 SetDevice (DviWidget dw, const char *name)
457 {
458 	XtWidgetGeometry	request, reply;
459 	XtGeometryResult ret;
460 
461 	ForgetFonts (dw);
462 	dw->dvi.device = device_load (name);
463 	if (!dw->dvi.device)
464 		return;
465 	dw->dvi.sizescale = dw->dvi.device->sizescale;
466 	dw->dvi.device_resolution = dw->dvi.device->res;
467 	dw->dvi.native = dw->dvi.device->X11;
468 	dw->dvi.paperlength = dw->dvi.device->paperlength;
469 	dw->dvi.paperwidth = dw->dvi.device->paperwidth;
470 	if (dw->dvi.native) {
471 		dw->dvi.display_resolution = dw->dvi.device_resolution;
472 		dw->dvi.scale_factor = 1.0;
473 	}
474 	else {
475 		dw->dvi.display_resolution = dw->dvi.default_resolution;
476 		dw->dvi.scale_factor = ((double)dw->dvi.display_resolution
477 					/ dw->dvi.device_resolution);
478 	}
479 	request.request_mode = CWWidth|CWHeight;
480 	request.width = MY_WIDTH(dw);
481 	request.height = MY_HEIGHT(dw);
482 	ret = XtMakeGeometryRequest ((Widget)dw, &request, &reply);
483 	if (ret == XtGeometryAlmost
484 	    && reply.height >= request.height
485 	    && reply.width >= request.width) {
486 		request.width = reply.width;
487 		request.height = reply.height;
488 		XtMakeGeometryRequest ((Widget)dw, &request, &reply);
489 	}
490 }
491 
492 static void
ShowDvi(DviWidget dw)493 ShowDvi (DviWidget dw)
494 {
495 	if (!dw->dvi.file) {
496 		static char Error[] = "No file selected";
497 
498 		XSetFont (XtDisplay(dw), dw->dvi.normal_GC,
499 			  dw->dvi.default_font->fid);
500 		XDrawString (XtDisplay (dw), XtWindow (dw), dw->dvi.normal_GC,
501 			     20, 20, Error, strlen (Error));
502 		return;
503 	}
504 
505 	FindPage (dw);
506 
507 	dw->dvi.display_enable = 1;
508 	ParseInput (dw);
509 	if (dw->dvi.last_page && dw->dvi.requested_page > dw->dvi.last_page)
510 		dw->dvi.requested_page = dw->dvi.last_page;
511 }
512 
513 static void
FindPage(DviWidget dw)514 FindPage (DviWidget dw)
515 {
516 	int	i;
517 	long	file_position;
518 
519 	if (dw->dvi.requested_page < 1)
520 		dw->dvi.requested_page = 1;
521 
522 	if (dw->dvi.last_page != 0 && dw->dvi.requested_page > dw->dvi.last_page)
523 		dw->dvi.requested_page = dw->dvi.last_page;
524 
525 	file_position = SearchPagePosition (dw, dw->dvi.requested_page);
526 	if (file_position != -1) {
527 		FileSeek(dw, file_position);
528 		dw->dvi.current_page = dw->dvi.requested_page;
529 	} else {
530 		for (i=dw->dvi.requested_page; i > 0; i--) {
531 			file_position = SearchPagePosition (dw, i);
532 			if (file_position != -1)
533 				break;
534 		}
535 		if (file_position == -1)
536 			file_position = 0;
537 		FileSeek (dw, file_position);
538 
539 		dw->dvi.current_page = i;
540 
541 		dw->dvi.display_enable = 0;
542 		while (dw->dvi.current_page != dw->dvi.requested_page) {
543 			dw->dvi.current_page = ParseInput (dw);
544 			/*
545 			 * at EOF, seek back to the beginning of this page.
546 			 */
547 			if (!dw->dvi.readingTmp && feof (dw->dvi.file)) {
548 				file_position = SearchPagePosition (dw,
549 						dw->dvi.current_page);
550 				if (file_position != -1)
551 					FileSeek (dw, file_position);
552 				dw->dvi.requested_page = dw->dvi.current_page;
553 				break;
554 			}
555 		}
556 	}
557 }
558 
DviSaveToFile(Widget w,FILE * fp)559 void DviSaveToFile(Widget w, FILE *fp)
560 {
561 	XtCheckSubclass(w, dviWidgetClass, NULL);
562 	(*((DviWidgetClass) XtClass(w))->command_class.save)(w, fp);
563 }
564 
565 static
SaveToFile(Widget w,FILE * fp)566 void SaveToFile(Widget w, FILE *fp)
567 {
568 	DviWidget dw = (DviWidget)w;
569 	long pos;
570 	int c;
571 
572 	if (dw->dvi.tmpFile) {
573 		pos = ftell(dw->dvi.tmpFile);
574 		if (dw->dvi.ungot) {
575 			pos--;
576 			dw->dvi.ungot = 0;
577 			/* The ungot character is in the tmpFile, so we don't
578 			   want to read it from file. */
579 			(void)getc(dw->dvi.file);
580 		}
581 	}
582 	else
583 		pos = ftell(dw->dvi.file);
584 	FileSeek(dw, 0L);
585 	while (DviGetC(dw, &c) != EOF)
586 		if (putc(c, fp) == EOF) {
587 			/* XXX print error message */
588 			break;
589 		}
590 	FileSeek(dw, pos);
591 }
592 
593 static
ClassPartInitialize(WidgetClass widget_class)594 void ClassPartInitialize(WidgetClass widget_class)
595 {
596 	DviWidgetClass wc = (DviWidgetClass)widget_class;
597 	DviWidgetClass super = (DviWidgetClass) wc->core_class.superclass;
598 	if (wc->command_class.save == InheritSaveToFile)
599 		wc->command_class.save = super->command_class.save;
600 }
601 
602 /*
603 Local Variables:
604 c-indent-level: 8
605 c-continued-statement-offset: 8
606 c-brace-offset: -8
607 c-argdecl-indent: 8
608 c-label-offset: -8
609 c-tab-always-indent: nil
610 End:
611 */
612