3 static char Xrcsid
[] = "$XConsortium: Dvi.c,v 1.9 89/12/10 16:12:25 rws Exp $";
8 * Dvi.c - Dvi display widget
12 #define XtStrlen(s) ((s) ? strlen(s) : 0)
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. */
18 #include <X11/IntrinsicP.h>
19 #include <X11/StringDefs.h>
20 #include <X11/Xmu/Converters.h>
25 /****************************************************************
27 * Full class record constant
29 ****************************************************************/
33 static char default_font_map
[] = "\
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 HR -adobe-helvetica-medium-r-normal--*-100-*-*-*-*-iso8859-1\n\
43 HI -adobe-helvetica-medium-o-normal--*-100-*-*-*-*-iso8859-1\n\
44 HB -adobe-helvetica-bold-r-normal--*-100-*-*-*-*-iso8859-1\n\
45 HBI -adobe-helvetica-bold-o-normal--*-100-*-*-*-*-iso8859-1\n\
46 NR -adobe-new century schoolbook-medium-r-normal--*-100-*-*-*-*-iso8859-1\n\
47 NI -adobe-new century schoolbook-medium-i-normal--*-100-*-*-*-*-iso8859-1\n\
48 NB -adobe-new century schoolbook-bold-r-normal--*-100-*-*-*-*-iso8859-1\n\
49 NBI -adobe-new century schoolbook-bold-i-normal--*-100-*-*-*-*-iso8859-1\n\
50 S -adobe-symbol-medium-r-normal--*-100-*-*-*-*-adobe-fontspecific\n\
51 SS -adobe-symbol-medium-r-normal--*-100-*-*-*-*-adobe-fontspecific\n\
54 #define offset(field) XtOffset(DviWidget, field)
56 #define MY_WIDTH(dw) ((int)(dw->dvi.paperwidth * dw->dvi.scale_factor + .5))
57 #define MY_HEIGHT(dw) ((int)(dw->dvi.paperlength * dw->dvi.scale_factor + .5))
59 static XtResource resources
[] = {
60 {XtNfontMap
, XtCFontMap
, XtRString
, sizeof (char *),
61 offset(dvi
.font_map_string
), XtRString
, default_font_map
},
62 {XtNforeground
, XtCForeground
, XtRPixel
, sizeof (unsigned long),
63 offset(dvi
.foreground
), XtRString
, "XtDefaultForeground"},
64 {XtNbackground
, XtCBackground
, XtRPixel
, sizeof (unsigned long),
65 offset(dvi
.background
), XtRString
, "XtDefaultBackground"},
66 {XtNpageNumber
, XtCPageNumber
, XtRInt
, sizeof (int),
67 offset(dvi
.requested_page
), XtRString
, "1"},
68 {XtNlastPageNumber
, XtCLastPageNumber
, XtRInt
, sizeof (int),
69 offset (dvi
.last_page
), XtRString
, "0"},
70 {XtNfile
, XtCFile
, XtRFile
, sizeof (FILE *),
71 offset (dvi
.file
), XtRFile
, (char *) 0},
72 {XtNseek
, XtCSeek
, XtRBoolean
, sizeof (Boolean
),
73 offset(dvi
.seek
), XtRString
, "false"},
74 {XtNfont
, XtCFont
, XtRFontStruct
, sizeof (XFontStruct
*),
75 offset(dvi
.default_font
), XtRString
, "xtdefaultfont"},
76 {XtNbackingStore
, XtCBackingStore
, XtRBackingStore
, sizeof (int),
77 offset(dvi
.backing_store
), XtRString
, "default"},
78 {XtNnoPolyText
, XtCNoPolyText
, XtRBoolean
, sizeof (Boolean
),
79 offset(dvi
.noPolyText
), XtRString
, "false"},
80 {XtNresolution
, XtCResolution
, XtRInt
, sizeof(int),
81 offset(dvi
.default_resolution
), XtRString
, "75"},
86 static void ClassInitialize ();
87 static void ClassPartInitialize();
88 static void Initialize(), Realize (), Destroy (), Redisplay ();
89 static Boolean
SetValues (), SetValuesHook ();
90 static XtGeometryResult
QueryGeometry ();
91 static void ShowDvi ();
92 static void CloseFile (), OpenFile ();
93 static void FindPage ();
95 static void SaveToFile ();
98 extern void ParseFontMap();
99 extern void DestroyFontMap();
100 extern void ForgetFonts();
103 extern void DestroyFileMap();
104 extern long SearchPagePosition();
105 extern void FileSeek();
106 extern void ForgetPagePositions();
109 extern int ParseInput();
111 DviClassRec dviClassRec
= {
113 &widgetClassRec
, /* superclass */
114 "Dvi", /* class_name */
115 sizeof(DviRec
), /* size */
116 ClassInitialize
, /* class_initialize */
117 ClassPartInitialize
, /* class_part_initialize */
118 FALSE
, /* class_inited */
119 Initialize
, /* initialize */
120 NULL
, /* initialize_hook */
121 Realize
, /* realize */
124 resources
, /* resources */
125 XtNumber(resources
), /* resource_count */
126 NULLQUARK
, /* xrm_class */
127 FALSE
, /* compress_motion */
128 TRUE
, /* compress_exposure */
129 TRUE
, /* compress_enterleave */
130 FALSE
, /* visible_interest */
131 Destroy
, /* destroy */
133 Redisplay
, /* expose */
134 SetValues
, /* set_values */
135 SetValuesHook
, /* set_values_hook */
136 NULL
, /* set_values_almost */
137 NULL
, /* get_values_hook */
138 NULL
, /* accept_focus */
139 XtVersion
, /* version */
140 NULL
, /* callback_private */
142 QueryGeometry
, /* query_geometry */
143 NULL
, /* display_accelerator */
146 SaveToFile
, /* save */
150 WidgetClass dviWidgetClass
= (WidgetClass
) &dviClassRec
;
152 static void ClassInitialize ()
154 XtAddConverter( XtRString
, XtRBackingStore
, XmuCvtStringToBackingStore
,
158 /****************************************************************
162 ****************************************************************/
165 static void Initialize(request
, new)
168 DviWidget dw
= (DviWidget
) new;
170 dw
->dvi
.current_page
= 0;
171 dw
->dvi
.font_map
= 0;
172 dw
->dvi
.cache
.index
= 0;
173 dw
->dvi
.text_x_width
= 0;
174 dw
->dvi
.text_device_width
= 0;
175 dw
->dvi
.word_flag
= 0;
179 dw
->dvi
.readingTmp
= 0;
180 dw
->dvi
.cache
.char_index
= 0;
181 dw
->dvi
.cache
.font_size
= -1;
182 dw
->dvi
.cache
.font_number
= -1;
183 dw
->dvi
.cache
.adjustable
[0] = 0;
184 dw
->dvi
.file_map
= 0;
186 dw
->dvi
.seek
= False
;
187 dw
->dvi
.device_resolution
= dw
->dvi
.default_resolution
;
188 dw
->dvi
.display_resolution
= dw
->dvi
.default_resolution
;
189 dw
->dvi
.paperlength
= dw
->dvi
.default_resolution
*11;
190 dw
->dvi
.paperwidth
= (dw
->dvi
.default_resolution
*8
191 + dw
->dvi
.default_resolution
/2);
192 dw
->dvi
.scale_factor
= 1.0;
193 dw
->dvi
.sizescale
= 1;
194 dw
->dvi
.line_thickness
= -1;
195 dw
->dvi
.line_width
= 1;
196 dw
->dvi
.fill
= DVI_FILL_MAX
;
197 dw
->dvi
.device_font
= 0;
198 dw
->dvi
.device_font_number
= -1;
213 Realize (w
, valueMask
, attrs
)
215 XtValueMask
*valueMask
;
216 XSetWindowAttributes
*attrs
;
218 DviWidget dw
= (DviWidget
) w
;
221 if (dw
->dvi
.backing_store
!= Always
+ WhenMapped
+ NotUseful
) {
222 attrs
->backing_store
= dw
->dvi
.backing_store
;
223 *valueMask
|= CWBackingStore
;
225 XtCreateWindow (w
, (unsigned)InputOutput
, (Visual
*) CopyFromParent
,
227 values
.foreground
= dw
->dvi
.foreground
;
228 values
.cap_style
= CapRound
;
229 values
.join_style
= JoinRound
;
230 values
.line_width
= dw
->dvi
.line_width
;
231 dw
->dvi
.normal_GC
= XCreateGC (XtDisplay (w
), XtWindow (w
),
232 GCForeground
|GCCapStyle
|GCJoinStyle
235 dw
->dvi
.gray
[0] = XCreateBitmapFromData(XtDisplay (w
), XtWindow (w
),
237 gray1_width
, gray1_height
);
238 dw
->dvi
.gray
[1] = XCreateBitmapFromData(XtDisplay (w
), XtWindow (w
),
240 gray2_width
, gray2_height
);
241 dw
->dvi
.gray
[2] = XCreateBitmapFromData(XtDisplay (w
), XtWindow (w
),
243 gray3_width
, gray3_height
);
244 dw
->dvi
.gray
[3] = XCreateBitmapFromData(XtDisplay (w
), XtWindow (w
),
246 gray4_width
, gray4_height
);
247 dw
->dvi
.gray
[4] = XCreateBitmapFromData(XtDisplay (w
), XtWindow (w
),
249 gray5_width
, gray5_height
);
250 dw
->dvi
.gray
[5] = XCreateBitmapFromData(XtDisplay (w
), XtWindow (w
),
252 gray6_width
, gray6_height
);
253 dw
->dvi
.gray
[6] = XCreateBitmapFromData(XtDisplay (w
), XtWindow (w
),
255 gray7_width
, gray7_height
);
256 dw
->dvi
.gray
[7] = XCreateBitmapFromData(XtDisplay (w
), XtWindow (w
),
258 gray8_width
, gray8_height
);
259 values
.background
= dw
->dvi
.background
;
260 values
.stipple
= dw
->dvi
.gray
[5];
261 dw
->dvi
.fill_GC
= XCreateGC (XtDisplay (w
), XtWindow (w
),
262 GCForeground
|GCBackground
|GCStipple
,
265 dw
->dvi
.fill_type
= 9;
276 DviWidget dw
= (DviWidget
) w
;
278 XFreeGC (XtDisplay (w
), dw
->dvi
.normal_GC
);
279 XFreeGC (XtDisplay (w
), dw
->dvi
.fill_GC
);
280 XFreePixmap (XtDisplay (w
), dw
->dvi
.gray
[0]);
281 XFreePixmap (XtDisplay (w
), dw
->dvi
.gray
[1]);
282 XFreePixmap (XtDisplay (w
), dw
->dvi
.gray
[2]);
283 XFreePixmap (XtDisplay (w
), dw
->dvi
.gray
[3]);
284 XFreePixmap (XtDisplay (w
), dw
->dvi
.gray
[4]);
285 XFreePixmap (XtDisplay (w
), dw
->dvi
.gray
[5]);
286 XFreePixmap (XtDisplay (w
), dw
->dvi
.gray
[6]);
287 XFreePixmap (XtDisplay (w
), dw
->dvi
.gray
[7]);
288 DestroyFontMap (dw
->dvi
.font_map
);
289 DestroyFileMap (dw
->dvi
.file_map
);
290 device_destroy (dw
->dvi
.device
);
294 * Repaint the widget window
299 Redisplay(w
, event
, region
)
304 DviWidget dw
= (DviWidget
) w
;
307 XClipBox (region
, &extents
);
308 dw
->dvi
.extents
.x1
= extents
.x
;
309 dw
->dvi
.extents
.y1
= extents
.y
;
310 dw
->dvi
.extents
.x2
= extents
.x
+ extents
.width
;
311 dw
->dvi
.extents
.y2
= extents
.y
+ extents
.height
;
316 * Set specified arguments into widget
320 SetValues (current
, request
, new)
321 DviWidget current
, request
, new;
323 Boolean redisplay
= FALSE
;
327 if (current
->dvi
.font_map_string
!= request
->dvi
.font_map_string
) {
328 new_map
= XtMalloc (strlen (request
->dvi
.font_map_string
) + 1);
331 strcpy (new_map
, request
->dvi
.font_map_string
);
332 new->dvi
.font_map_string
= new_map
;
333 if (current
->dvi
.font_map_string
)
334 XtFree (current
->dvi
.font_map_string
);
335 current
->dvi
.font_map_string
= 0;
340 req
= request
->dvi
.requested_page
;
341 cur
= current
->dvi
.requested_page
;
343 if (!request
->dvi
.file
)
348 if (current
->dvi
.last_page
!= 0 &&
349 req
> current
->dvi
.last_page
)
350 req
= current
->dvi
.last_page
;
354 new->dvi
.requested_page
= req
;
355 if (current
->dvi
.last_page
== 0 && req
> cur
)
363 * use the set_values_hook entry to check when
368 SetValuesHook (dw
, args
, num_argsp
)
375 for (i
= 0; i
< *num_argsp
; i
++) {
376 if (!strcmp (args
[i
].name
, XtNfile
)) {
385 static void CloseFile (dw
)
389 fclose (dw
->dvi
.tmpFile
);
390 ForgetPagePositions (dw
);
393 static void OpenFile (dw
)
398 dw
->dvi
.tmpFile
= tmpfile();
399 dw
->dvi
.requested_page
= 1;
400 dw
->dvi
.last_page
= 0;
403 static XtGeometryResult
404 QueryGeometry (w
, request
, geometry_return
)
406 XtWidgetGeometry
*request
, *geometry_return
;
408 XtGeometryResult ret
;
409 DviWidget dw
= (DviWidget
) w
;
412 if (((request
->request_mode
& CWWidth
)
413 && request
->width
< MY_WIDTH(dw
))
414 || ((request
->request_mode
& CWHeight
)
415 && request
->height
< MY_HEIGHT(dw
)))
416 ret
= XtGeometryAlmost
;
417 geometry_return
->width
= MY_WIDTH(dw
);
418 geometry_return
->height
= MY_HEIGHT(dw
);
419 geometry_return
->request_mode
= CWWidth
|CWHeight
;
428 XtWidgetGeometry request
, reply
;
429 XtGeometryResult ret
;
432 dw
->dvi
.device
= device_load (name
);
435 dw
->dvi
.sizescale
= dw
->dvi
.device
->sizescale
;
436 dw
->dvi
.device_resolution
= dw
->dvi
.device
->res
;
437 dw
->dvi
.native
= dw
->dvi
.device
->X11
;
438 dw
->dvi
.paperlength
= dw
->dvi
.device
->paperlength
;
439 dw
->dvi
.paperwidth
= dw
->dvi
.device
->paperwidth
;
440 if (dw
->dvi
.native
) {
441 dw
->dvi
.display_resolution
= dw
->dvi
.device_resolution
;
442 dw
->dvi
.scale_factor
= 1.0;
445 dw
->dvi
.display_resolution
= dw
->dvi
.default_resolution
;
446 dw
->dvi
.scale_factor
= ((double)dw
->dvi
.display_resolution
447 / dw
->dvi
.device_resolution
);
449 request
.request_mode
= CWWidth
|CWHeight
;
450 request
.width
= MY_WIDTH(dw
);
451 request
.height
= MY_HEIGHT(dw
);
452 ret
= XtMakeGeometryRequest ((Widget
)dw
, &request
, &reply
);
453 if (ret
== XtGeometryAlmost
454 && reply
.height
>= request
.height
455 && reply
.width
>= request
.width
) {
456 request
.width
= reply
.width
;
457 request
.height
= reply
.height
;
458 XtMakeGeometryRequest ((Widget
)dw
, &request
, &reply
);
467 static char Error
[] = "No file selected";
469 XSetFont (XtDisplay(dw
), dw
->dvi
.normal_GC
,
470 dw
->dvi
.default_font
->fid
);
471 XDrawString (XtDisplay (dw
), XtWindow (dw
), dw
->dvi
.normal_GC
,
472 20, 20, Error
, strlen (Error
));
478 dw
->dvi
.display_enable
= 1;
480 if (dw
->dvi
.last_page
&& dw
->dvi
.requested_page
> dw
->dvi
.last_page
)
481 dw
->dvi
.requested_page
= dw
->dvi
.last_page
;
491 if (dw
->dvi
.requested_page
< 1)
492 dw
->dvi
.requested_page
= 1;
494 if (dw
->dvi
.last_page
!= 0 && dw
->dvi
.requested_page
> dw
->dvi
.last_page
)
495 dw
->dvi
.requested_page
= dw
->dvi
.last_page
;
497 file_position
= SearchPagePosition (dw
, dw
->dvi
.requested_page
);
498 if (file_position
!= -1) {
499 FileSeek(dw
, file_position
);
500 dw
->dvi
.current_page
= dw
->dvi
.requested_page
;
502 for (i
=dw
->dvi
.requested_page
; i
> 0; i
--) {
503 file_position
= SearchPagePosition (dw
, i
);
504 if (file_position
!= -1)
507 if (file_position
== -1)
509 FileSeek (dw
, file_position
);
511 dw
->dvi
.current_page
= i
;
513 dw
->dvi
.display_enable
= 0;
514 while (dw
->dvi
.current_page
!= dw
->dvi
.requested_page
) {
515 dw
->dvi
.current_page
= ParseInput (dw
);
517 * at EOF, seek back to the beginning of this page.
519 if (!dw
->dvi
.readingTmp
&& feof (dw
->dvi
.file
)) {
520 file_position
= SearchPagePosition (dw
,
521 dw
->dvi
.current_page
);
522 if (file_position
!= -1)
523 FileSeek (dw
, file_position
);
524 dw
->dvi
.requested_page
= dw
->dvi
.current_page
;
531 void DviSaveToFile(w
, fp
)
535 XtCheckSubclass(w
, dviWidgetClass
, NULL
);
536 (*((DviWidgetClass
) XtClass(w
))->command_class
.save
)(w
, fp
);
540 void SaveToFile(w
, fp
)
544 DviWidget dw
= (DviWidget
)w
;
548 if (dw
->dvi
.tmpFile
) {
549 pos
= ftell(dw
->dvi
.tmpFile
);
553 /* The ungot character is in the tmpFile, so we don't
554 want to read it from file. */
555 (void)getc(dw
->dvi
.file
);
559 pos
= ftell(dw
->dvi
.file
);
561 while (DviGetC(dw
, &c
) != EOF
)
562 if (putc(c
, fp
) == EOF
) {
563 /* XXX print error message */
570 void ClassPartInitialize(widget_class
)
571 WidgetClass widget_class
;
573 DviWidgetClass wc
= (DviWidgetClass
)widget_class
;
574 DviWidgetClass super
= (DviWidgetClass
) wc
->core_class
.superclass
;
575 if (wc
->command_class
.save
== InheritSaveToFile
)
576 wc
->command_class
.save
= super
->command_class
.save
;
582 c-continued-statement-offset: 8
586 c-tab-always-indent: nil