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