Dvi.c revision 65912f00
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	  */
18065912f00Smrg	NULL,				/* 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
21865912f00SmrgInitialize(Widget request, Widget new, ArgList args, Cardinal *num_args)
219f80a6dcdSmrg{
220f80a6dcdSmrg    DviWidget	dw = (DviWidget) new;
221f80a6dcdSmrg
22265912f00Smrg    dw->dvi.tmpFile = NULL;
223f80a6dcdSmrg    dw->dvi.readingTmp = 0;
224f80a6dcdSmrg    dw->dvi.ungot = 0;
22565912f00Smrg    dw->dvi.normal_GC = NULL;
22665912f00Smrg    dw->dvi.file_map = NULL;
22765912f00Smrg    dw->dvi.fonts = NULL;
22865912f00Smrg    dw->dvi.font_map = NULL;
229f80a6dcdSmrg    dw->dvi.current_page = 0;
230f80a6dcdSmrg    dw->dvi.font_size = 0;
231f80a6dcdSmrg    dw->dvi.font_number = 0;
232f80a6dcdSmrg    dw->dvi.device_resolution = 0;
233f80a6dcdSmrg    dw->dvi.line_width = 0;
234f80a6dcdSmrg    dw->dvi.line_style = 0;
23565912f00Smrg    dw->dvi.font = NULL;
236f80a6dcdSmrg    dw->dvi.display_enable = 0;
237f80a6dcdSmrg    dw->dvi.scale = 0.0;
23865912f00Smrg    dw->dvi.state = NULL;
239f80a6dcdSmrg    dw->dvi.cache.index = 0;
24065912f00Smrg    dw->dvi.cache.font = NULL;
241f80a6dcdSmrg    dw->dvi.size_scale = 0;
242f80a6dcdSmrg    dw->dvi.size_scale_set = 0;
243f80a6dcdSmrg    RequestDesiredSize (dw);
244f80a6dcdSmrg}
245f80a6dcdSmrg
246f80a6dcdSmrgstatic void
24765912f00SmrgRealize(Widget w, XtValueMask *valueMask, XSetWindowAttributes *attrs)
248f80a6dcdSmrg{
249f80a6dcdSmrg    DviWidget	dw = (DviWidget) w;
250f80a6dcdSmrg    XGCValues	values;
251f80a6dcdSmrg
252f80a6dcdSmrg    if (dw->dvi.backing_store != Always + WhenMapped + NotUseful) {
253f80a6dcdSmrg	attrs->backing_store = dw->dvi.backing_store;
254f80a6dcdSmrg	*valueMask |= CWBackingStore;
255f80a6dcdSmrg    }
256f80a6dcdSmrg    XtCreateWindow (w, (unsigned)InputOutput, (Visual *) CopyFromParent,
257f80a6dcdSmrg		    *valueMask, attrs);
258f80a6dcdSmrg    values.foreground = dw->dvi.foreground;
259f80a6dcdSmrg    dw->dvi.normal_GC = XCreateGC (XtDisplay (w), XtWindow (w),
260f80a6dcdSmrg				    GCForeground, &values);
261f80a6dcdSmrg#ifdef USE_XFT
262f80a6dcdSmrg    {
263f80a6dcdSmrg	int		scr;
264f80a6dcdSmrg	Visual		*visual;
265f80a6dcdSmrg	Colormap	cmap;
266f80a6dcdSmrg	XRenderColor	black;
267f80a6dcdSmrg
268f80a6dcdSmrg	scr = XScreenNumberOfScreen (dw->core.screen);
269f80a6dcdSmrg	visual = DefaultVisual (XtDisplay (w), scr);
270f80a6dcdSmrg	cmap = DefaultColormap (XtDisplay (w), scr);
271f80a6dcdSmrg	dw->dvi.draw = XftDrawCreate (XtDisplay (w), XtWindow (w),
272f80a6dcdSmrg				      visual, cmap);
273f80a6dcdSmrg
274f80a6dcdSmrg	black.red = black.green = black.blue = 0;
275f80a6dcdSmrg	black.alpha = 0xffff;
276f80a6dcdSmrg	XftColorAllocValue (XtDisplay (w), visual, cmap,
277f80a6dcdSmrg			    &black, &dw->dvi.black);
278f80a6dcdSmrg	dw->dvi.default_font = XftFontOpenName (XtDisplay (w),
279f80a6dcdSmrg						scr,
280f80a6dcdSmrg						"serif-12");
281f80a6dcdSmrg    }
282f80a6dcdSmrg#endif
283f80a6dcdSmrg    if (dw->dvi.file)
284f80a6dcdSmrg	OpenFile (dw);
285f80a6dcdSmrg    ParseFontMap (dw);
286f80a6dcdSmrg}
287f80a6dcdSmrg
288f80a6dcdSmrgstatic void
28965912f00SmrgDestroy(Widget w)
290f80a6dcdSmrg{
291f80a6dcdSmrg	DviWidget	dw = (DviWidget) w;
292f80a6dcdSmrg
293f80a6dcdSmrg	XFreeGC (XtDisplay (w), dw->dvi.normal_GC);
294f80a6dcdSmrg	DestroyFontMap (dw->dvi.font_map);
295f80a6dcdSmrg	DestroyFileMap (dw->dvi.file_map);
296f80a6dcdSmrg}
297f80a6dcdSmrg
298f80a6dcdSmrg/*
299f80a6dcdSmrg * Repaint the widget window
300f80a6dcdSmrg */
301f80a6dcdSmrg
302f80a6dcdSmrg/* ARGSUSED */
303f80a6dcdSmrgstatic void
30465912f00SmrgRedisplay(Widget w, XEvent *event, Region region)
305f80a6dcdSmrg{
306f80a6dcdSmrg	DviWidget	dw = (DviWidget) w;
307f80a6dcdSmrg#ifndef USE_XFT
308f80a6dcdSmrg	XRectangle	extents;
309f80a6dcdSmrg#endif
310f80a6dcdSmrg
311f80a6dcdSmrg#ifdef USE_XFT
312f80a6dcdSmrg	XClearArea (XtDisplay (dw),
313f80a6dcdSmrg		    XtWindow (dw),
314f80a6dcdSmrg		    0, 0, 0, 0, False);
315f80a6dcdSmrg	dw->dvi.extents.x1 = 0;
316f80a6dcdSmrg	dw->dvi.extents.y1 = 0;
317f80a6dcdSmrg	dw->dvi.extents.x2 = dw->core.width;
318f80a6dcdSmrg	dw->dvi.extents.y2 = dw->core.height;
319f80a6dcdSmrg#else
320f80a6dcdSmrg	XClipBox (region, &extents);
321f80a6dcdSmrg	dw->dvi.extents.x1 = extents.x;
322f80a6dcdSmrg	dw->dvi.extents.y1 = extents.y;
323f80a6dcdSmrg	dw->dvi.extents.x2 = extents.x + extents.width;
324f80a6dcdSmrg	dw->dvi.extents.y2 = extents.y + extents.height;
325f80a6dcdSmrg#endif
326f80a6dcdSmrg	ShowDvi (dw);
327f80a6dcdSmrg}
328f80a6dcdSmrg
329f80a6dcdSmrgstatic void
33065912f00SmrgRequestDesiredSize (DviWidget dw)
331f80a6dcdSmrg{
332f80a6dcdSmrg    XtWidgetGeometry	req, rep;
333f80a6dcdSmrg
334f80a6dcdSmrg    dw->dvi.desired_width = dw->dvi.page_width *
335f80a6dcdSmrg				 dw->dvi.screen_resolution;
336f80a6dcdSmrg    dw->dvi.desired_height = dw->dvi.page_height *
337f80a6dcdSmrg				  dw->dvi.screen_resolution;
338f80a6dcdSmrg    req.request_mode = CWWidth|CWHeight;
339f80a6dcdSmrg    req.width = dw->dvi.desired_width;
340f80a6dcdSmrg    req.height = dw->dvi.desired_height;
341f80a6dcdSmrg    XtMakeGeometryRequest ((Widget) dw, &req, &rep);
342f80a6dcdSmrg}
343f80a6dcdSmrg
344f80a6dcdSmrg/*
345f80a6dcdSmrg * Set specified arguments into widget
346f80a6dcdSmrg */
347f80a6dcdSmrg/* ARGSUSED */
348f80a6dcdSmrgstatic Boolean
34965912f00SmrgSetValues (Widget wcurrent, Widget wrequest, Widget wnew,
35065912f00Smrg	   ArgList args, Cardinal *num_args)
351f80a6dcdSmrg{
352f80a6dcdSmrg    DviWidget	current = (DviWidget) wcurrent;
353f80a6dcdSmrg    DviWidget	request = (DviWidget) wrequest;
354f80a6dcdSmrg    DviWidget	new     = (DviWidget) wnew;
355f80a6dcdSmrg    Boolean	redisplay = FALSE;
356f80a6dcdSmrg    char	*new_map;
357f80a6dcdSmrg    int		cur, req;
358f80a6dcdSmrg
359f80a6dcdSmrg    req = request->dvi.requested_page;
360f80a6dcdSmrg    cur = current->dvi.requested_page;
361f80a6dcdSmrg    if (cur != req) {
362f80a6dcdSmrg	    if (req < 1)
363f80a6dcdSmrg		req = 1;
364f80a6dcdSmrg	    if (request->dvi.file)
365f80a6dcdSmrg	    {
366f80a6dcdSmrg		if (current->dvi.last_page != 0 &&
367f80a6dcdSmrg		    req > current->dvi.last_page)
368f80a6dcdSmrg			req = current->dvi.last_page;
369f80a6dcdSmrg	    }
370f80a6dcdSmrg	    if (cur != req)
371f80a6dcdSmrg		redisplay = TRUE;
372f80a6dcdSmrg	    new->dvi.requested_page = req;
373f80a6dcdSmrg    }
374f80a6dcdSmrg
375f80a6dcdSmrg    if (current->dvi.font_map_string != request->dvi.font_map_string) {
376f80a6dcdSmrg	    new_map = XtMalloc (strlen (request->dvi.font_map_string) + 1);
377f80a6dcdSmrg	    if (new_map) {
378f80a6dcdSmrg		    redisplay = TRUE;
379f80a6dcdSmrg		    strcpy (new_map, request->dvi.font_map_string);
380f80a6dcdSmrg		    new->dvi.font_map_string = new_map;
381f80a6dcdSmrg		    if (current->dvi.font_map_string)
382f80a6dcdSmrg			    XtFree (current->dvi.font_map_string);
38365912f00Smrg		    current->dvi.font_map_string = NULL;
384f80a6dcdSmrg		    ParseFontMap (new);
385f80a6dcdSmrg	    }
386f80a6dcdSmrg    }
387f80a6dcdSmrg    if (current->dvi.screen_resolution != request->dvi.screen_resolution)
388f80a6dcdSmrg    {
389f80a6dcdSmrg	ResetFonts (new);
390f80a6dcdSmrg	new->dvi.line_width = -1;
391f80a6dcdSmrg    }
392f80a6dcdSmrg    if (request->dvi.device_resolution)
393f80a6dcdSmrg	new->dvi.scale = ((double) request->dvi.screen_resolution) /
394f80a6dcdSmrg			     ((double) request->dvi.device_resolution);
395f80a6dcdSmrg    if (current->dvi.page_width !=  request->dvi.page_width ||
396f80a6dcdSmrg	current->dvi.page_height != request->dvi.page_height ||
397f80a6dcdSmrg	current->dvi.screen_resolution != request->dvi.screen_resolution)
398f80a6dcdSmrg    {
399f80a6dcdSmrg	RequestDesiredSize (new);
400f80a6dcdSmrg	redisplay = TRUE;
401f80a6dcdSmrg    }
402f80a6dcdSmrg    return redisplay;
403f80a6dcdSmrg}
404f80a6dcdSmrg
405f80a6dcdSmrg/*
406f80a6dcdSmrg * use the set_values_hook entry to check when
407f80a6dcdSmrg * the file is set
408f80a6dcdSmrg */
409f80a6dcdSmrg
410f80a6dcdSmrgstatic Boolean
41165912f00SmrgSetValuesHook (Widget widget, ArgList args, Cardinal *num_argsp)
412f80a6dcdSmrg{
413f80a6dcdSmrg	DviWidget	dw = (DviWidget) widget;
414f80a6dcdSmrg	Cardinal	i;
415f80a6dcdSmrg
416f80a6dcdSmrg	for (i = 0; i < *num_argsp; i++) {
417f80a6dcdSmrg		if (!strcmp (args[i].name, XtNfile)) {
418f80a6dcdSmrg			CloseFile (dw);
419f80a6dcdSmrg			OpenFile (dw);
420f80a6dcdSmrg			return TRUE;
421f80a6dcdSmrg		}
422f80a6dcdSmrg	}
423f80a6dcdSmrg	return FALSE;
424f80a6dcdSmrg}
425f80a6dcdSmrg
426f80a6dcdSmrgstatic void
42765912f00SmrgCloseFile (DviWidget dw)
428f80a6dcdSmrg{
429f80a6dcdSmrg    if (dw->dvi.tmpFile)
430f80a6dcdSmrg	fclose (dw->dvi.tmpFile);
431f80a6dcdSmrg    ForgetPagePositions (dw);
432f80a6dcdSmrg}
433f80a6dcdSmrg
434f80a6dcdSmrgstatic void
43565912f00SmrgOpenFile (DviWidget dw)
436f80a6dcdSmrg{
437f80a6dcdSmrg    char	tmpName[sizeof ("/tmp/dviXXXXXX")];
438f80a6dcdSmrg#ifdef HAS_MKSTEMP
439f80a6dcdSmrg    int fd;
440f80a6dcdSmrg#endif
441f80a6dcdSmrg
44265912f00Smrg    dw->dvi.tmpFile = NULL;
443f80a6dcdSmrg    if (!dw->dvi.seek) {
444f80a6dcdSmrg	strcpy (tmpName, "/tmp/dviXXXXXX");
445f80a6dcdSmrg#ifndef HAS_MKSTEMP
446f80a6dcdSmrg	mktemp (tmpName);
447f80a6dcdSmrg	dw->dvi.tmpFile = fopen (tmpName, "w+");
448f80a6dcdSmrg#else
449f80a6dcdSmrg	fd = mkstemp(tmpName);
450f80a6dcdSmrg	dw->dvi.tmpFile = fdopen(fd, "w+");
451f80a6dcdSmrg#endif
452f80a6dcdSmrg	unlink (tmpName);
453f80a6dcdSmrg    }
454f80a6dcdSmrg    if (dw->dvi.requested_page < 1)
455f80a6dcdSmrg	dw->dvi.requested_page = 1;
456f80a6dcdSmrg    dw->dvi.last_page = 0;
457f80a6dcdSmrg}
458f80a6dcdSmrg
459f80a6dcdSmrgstatic XtGeometryResult
46065912f00SmrgQueryGeometry (Widget w, XtWidgetGeometry *request,
46165912f00Smrg	       XtWidgetGeometry *geometry_return)
462f80a6dcdSmrg{
463f80a6dcdSmrg	XtGeometryResult	ret;
464f80a6dcdSmrg	DviWidget		dw = (DviWidget) w;
465f80a6dcdSmrg
466f80a6dcdSmrg	ret = XtGeometryYes;
467f80a6dcdSmrg	if ((int)request->width < dw->dvi.desired_width
468f80a6dcdSmrg	    || (int)request->height < dw->dvi.desired_height)
469f80a6dcdSmrg		ret = XtGeometryAlmost;
470f80a6dcdSmrg	geometry_return->width = dw->dvi.desired_width;
471f80a6dcdSmrg	geometry_return->height = dw->dvi.desired_height;
472f80a6dcdSmrg	geometry_return->request_mode = CWWidth|CWHeight;
473f80a6dcdSmrg	return ret;
474f80a6dcdSmrg}
475f80a6dcdSmrg
476f80a6dcdSmrgvoid
47765912f00SmrgSetDeviceResolution (DviWidget dw, int resolution)
478f80a6dcdSmrg{
479f80a6dcdSmrg    if (resolution != dw->dvi.device_resolution) {
480f80a6dcdSmrg	dw->dvi.device_resolution = resolution;
481f80a6dcdSmrg	dw->dvi.scale = ((double)  dw->dvi.screen_resolution) /
482f80a6dcdSmrg			((double) resolution);
483f80a6dcdSmrg    }
484f80a6dcdSmrg}
485f80a6dcdSmrg
486f80a6dcdSmrgstatic void
48765912f00SmrgShowDvi (DviWidget dw)
488f80a6dcdSmrg{
489f80a6dcdSmrg	int	i;
490f80a6dcdSmrg	long	file_position;
491f80a6dcdSmrg
492f80a6dcdSmrg	if (!dw->dvi.file)
493f80a6dcdSmrg	  return;
494f80a6dcdSmrg
495f80a6dcdSmrg	if (dw->dvi.requested_page < 1)
496f80a6dcdSmrg		dw->dvi.requested_page = 1;
497f80a6dcdSmrg
498f80a6dcdSmrg	if (dw->dvi.last_page != 0 && dw->dvi.requested_page > dw->dvi.last_page)
499f80a6dcdSmrg		dw->dvi.requested_page = dw->dvi.last_page;
500f80a6dcdSmrg
501f80a6dcdSmrg	file_position = SearchPagePosition (dw, dw->dvi.requested_page);
502f80a6dcdSmrg	if (file_position != -1) {
503f80a6dcdSmrg		FileSeek(dw, file_position);
504f80a6dcdSmrg		dw->dvi.current_page = dw->dvi.requested_page;
505f80a6dcdSmrg	} else {
506f80a6dcdSmrg		for (i=dw->dvi.requested_page; i > 0; i--) {
507f80a6dcdSmrg			file_position = SearchPagePosition (dw, i);
508f80a6dcdSmrg			if (file_position != -1)
509f80a6dcdSmrg				break;
510f80a6dcdSmrg		}
511f80a6dcdSmrg		if (file_position == -1)
512f80a6dcdSmrg			file_position = 0;
513f80a6dcdSmrg		FileSeek (dw, file_position);
514f80a6dcdSmrg
515f80a6dcdSmrg		dw->dvi.current_page = i;
516f80a6dcdSmrg
517f80a6dcdSmrg		dw->dvi.display_enable = 0;
518f80a6dcdSmrg		while (dw->dvi.current_page != dw->dvi.requested_page) {
519f80a6dcdSmrg			dw->dvi.current_page = ParseInput (dw);
520f80a6dcdSmrg			/*
521f80a6dcdSmrg			 * at EOF, seek back to the begining of this page.
522f80a6dcdSmrg			 */
523f80a6dcdSmrg			if (feof (dw->dvi.file)) {
524f80a6dcdSmrg				file_position = SearchPagePosition (dw,
525f80a6dcdSmrg						dw->dvi.current_page);
526f80a6dcdSmrg				if (file_position != -1)
527f80a6dcdSmrg					FileSeek (dw, file_position);
528f80a6dcdSmrg				break;
529f80a6dcdSmrg			}
530f80a6dcdSmrg		}
531f80a6dcdSmrg	}
532f80a6dcdSmrg
533f80a6dcdSmrg	dw->dvi.display_enable = 1;
534f80a6dcdSmrg	ParseInput (dw);
535f80a6dcdSmrg	if (dw->dvi.last_page && dw->dvi.requested_page > dw->dvi.last_page)
536f80a6dcdSmrg		dw->dvi.requested_page = dw->dvi.last_page;
537f80a6dcdSmrg}
538