5 static char Xrcsid
[] = "$XConsortium: Dvi.c,v 1.9 89/12/10 16:12:25 rws Exp $";
10 * Dvi.c - Dvi display widget
14 #define XtStrlen(s) ((s) ? strlen(s) : 0)
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. */
20 #include <X11/IntrinsicP.h>
21 #include <X11/StringDefs.h>
22 #include <X11/Xmu/Converters.h>
27 /****************************************************************
29 * Full class record constant
31 ****************************************************************/
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\
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\
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\
60 #define offset(field) XtOffset(DviWidget, field)
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))
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"},
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
*,
114 static void ShowDvi (DviWidget
);
115 static void CloseFile (DviWidget
);
116 static void OpenFile (DviWidget
);
117 static void FindPage (DviWidget
);
119 static void SaveToFile (Widget
, FILE *);
122 extern void ParseFontMap(DviWidget
);
123 extern void DestroyFontMap(DviFontMap
*);
124 extern void ForgetFonts(DviWidget
);
127 extern void DestroyFileMap(DviFileMap
*);
128 extern long SearchPagePosition(DviWidget
, int);
129 extern void FileSeek(DviWidget
, long);
130 extern void ForgetPagePositions(DviWidget
);
133 extern int ParseInput(register DviWidget
);
135 DviClassRec dviClassRec
= {
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 */
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 */
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 */
166 QueryGeometry
, /* query_geometry */
167 NULL
, /* display_accelerator */
170 SaveToFile
, /* save */
174 WidgetClass dviWidgetClass
= (WidgetClass
) &dviClassRec
;
176 static void ClassInitialize (void)
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);
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
;
188 XtAddConverter( XtRString
, XtRBackingStore
, XmuCvtStringToBackingStore
,
192 /****************************************************************
196 ****************************************************************/
199 static void Initialize(Widget request
, Widget new_wd
,
200 ArgList args
, Cardinal
*num_args
)
202 DviWidget dw
= (DviWidget
) new_wd
;
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;
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;
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;
236 request
= request
; /* unused; suppress compiler warning */
251 Realize (Widget w
, XtValueMask
*valueMask
, XSetWindowAttributes
*attrs
)
253 DviWidget dw
= (DviWidget
) w
;
256 if (dw
->dvi
.backing_store
!= Always
+ WhenMapped
+ NotUseful
) {
257 attrs
->backing_store
= dw
->dvi
.backing_store
;
258 *valueMask
|= CWBackingStore
;
260 XtCreateWindow (w
, (unsigned)InputOutput
, (Visual
*) CopyFromParent
,
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
270 dw
->dvi
.gray
[0] = XCreateBitmapFromData(XtDisplay (w
), XtWindow (w
),
272 gray1_width
, gray1_height
);
273 dw
->dvi
.gray
[1] = XCreateBitmapFromData(XtDisplay (w
), XtWindow (w
),
275 gray2_width
, gray2_height
);
276 dw
->dvi
.gray
[2] = XCreateBitmapFromData(XtDisplay (w
), XtWindow (w
),
278 gray3_width
, gray3_height
);
279 dw
->dvi
.gray
[3] = XCreateBitmapFromData(XtDisplay (w
), XtWindow (w
),
281 gray4_width
, gray4_height
);
282 dw
->dvi
.gray
[4] = XCreateBitmapFromData(XtDisplay (w
), XtWindow (w
),
284 gray5_width
, gray5_height
);
285 dw
->dvi
.gray
[5] = XCreateBitmapFromData(XtDisplay (w
), XtWindow (w
),
287 gray6_width
, gray6_height
);
288 dw
->dvi
.gray
[6] = XCreateBitmapFromData(XtDisplay (w
), XtWindow (w
),
290 gray7_width
, gray7_height
);
291 dw
->dvi
.gray
[7] = XCreateBitmapFromData(XtDisplay (w
), XtWindow (w
),
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
,
300 dw
->dvi
.fill_type
= 9;
310 DviWidget dw
= (DviWidget
) w
;
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
);
328 * Repaint the widget window
333 Redisplay(Widget w
, XEvent
*event
, Region region
)
335 DviWidget dw
= (DviWidget
) w
;
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
;
345 event
= event
; /* unused; suppress compiler warning */
349 * Set specified arguments into widget
353 SetValues (Widget wcurrent
, Widget wrequest
, Widget wnew
,
354 ArgList args
, Cardinal
*num_args
)
356 Boolean redisplay
= FALSE
;
359 DviWidget current
= (DviWidget
)wcurrent
;
360 DviWidget request
= (DviWidget
)wrequest
;
361 DviWidget new_wd
= (DviWidget
)wnew
;
363 if (current
->dvi
.font_map_string
!= request
->dvi
.font_map_string
) {
364 new_map
= XtMalloc (strlen (request
->dvi
.font_map_string
) + 1);
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
);
376 req
= request
->dvi
.requested_page
;
377 cur
= current
->dvi
.requested_page
;
379 if (!request
->dvi
.file
)
384 if (current
->dvi
.last_page
!= 0 &&
385 req
> current
->dvi
.last_page
)
386 req
= current
->dvi
.last_page
;
390 new_wd
->dvi
.requested_page
= req
;
391 if (current
->dvi
.last_page
== 0 && req
> cur
)
395 args
= args
; /* unused; suppress compiler warning */
402 * use the set_values_hook entry to check when
407 SetValuesHook (Widget wdw
, ArgList args
, Cardinal
*num_argsp
)
410 DviWidget dw
= (DviWidget
)wdw
;
412 for (i
= 0; i
< *num_argsp
; i
++) {
413 if (!strcmp (args
[i
].name
, XtNfile
)) {
422 static void CloseFile (DviWidget dw
)
425 fclose (dw
->dvi
.tmpFile
);
426 ForgetPagePositions (dw
);
429 static void OpenFile (DviWidget dw
)
433 dw
->dvi
.tmpFile
= tmpfile();
434 dw
->dvi
.requested_page
= 1;
435 dw
->dvi
.last_page
= 0;
438 static XtGeometryResult
439 QueryGeometry (Widget w
, XtWidgetGeometry
*request
,
440 XtWidgetGeometry
*geometry_return
)
442 XtGeometryResult ret
;
443 DviWidget dw
= (DviWidget
) w
;
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
;
458 SetDevice (DviWidget dw
, const char *name
)
460 XtWidgetGeometry request
, reply
;
461 XtGeometryResult ret
;
464 dw
->dvi
.device
= device_load (name
);
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;
477 dw
->dvi
.display_resolution
= dw
->dvi
.default_resolution
;
478 dw
->dvi
.scale_factor
= ((double)dw
->dvi
.display_resolution
479 / dw
->dvi
.device_resolution
);
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
);
495 ShowDvi (DviWidget dw
)
498 static char Error
[] = "No file selected";
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
));
509 dw
->dvi
.display_enable
= 1;
511 if (dw
->dvi
.last_page
&& dw
->dvi
.requested_page
> dw
->dvi
.last_page
)
512 dw
->dvi
.requested_page
= dw
->dvi
.last_page
;
516 FindPage (DviWidget dw
)
521 if (dw
->dvi
.requested_page
< 1)
522 dw
->dvi
.requested_page
= 1;
524 if (dw
->dvi
.last_page
!= 0 && dw
->dvi
.requested_page
> dw
->dvi
.last_page
)
525 dw
->dvi
.requested_page
= dw
->dvi
.last_page
;
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
;
532 for (i
=dw
->dvi
.requested_page
; i
> 0; i
--) {
533 file_position
= SearchPagePosition (dw
, i
);
534 if (file_position
!= -1)
537 if (file_position
== -1)
539 FileSeek (dw
, file_position
);
541 dw
->dvi
.current_page
= i
;
543 dw
->dvi
.display_enable
= 0;
544 while (dw
->dvi
.current_page
!= dw
->dvi
.requested_page
) {
545 dw
->dvi
.current_page
= ParseInput (dw
);
547 * at EOF, seek back to the beginning of this page.
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
;
561 void DviSaveToFile(Widget w
, FILE *fp
)
563 XtCheckSubclass(w
, dviWidgetClass
, NULL
);
564 (*((DviWidgetClass
) XtClass(w
))->command_class
.save
)(w
, fp
);
568 void SaveToFile(Widget w
, FILE *fp
)
570 DviWidget dw
= (DviWidget
)w
;
574 if (dw
->dvi
.tmpFile
) {
575 pos
= ftell(dw
->dvi
.tmpFile
);
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
);
585 pos
= ftell(dw
->dvi
.file
);
587 while (DviGetC(dw
, &c
) != EOF
)
588 if (putc(c
, fp
) == EOF
) {
589 /* XXX print error message */
596 void ClassPartInitialize(WidgetClass widget_class
)
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
;
607 c-continued-statement-offset: 8
611 c-tab-always-indent: nil