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 ();
97 DviClassRec dviClassRec
= {
99 &widgetClassRec
, /* superclass */
100 "Dvi", /* class_name */
101 sizeof(DviRec
), /* size */
102 ClassInitialize
, /* class_initialize */
103 ClassPartInitialize
, /* class_part_initialize */
104 FALSE
, /* class_inited */
105 Initialize
, /* initialize */
106 NULL
, /* initialize_hook */
107 Realize
, /* realize */
110 resources
, /* resources */
111 XtNumber(resources
), /* resource_count */
112 NULLQUARK
, /* xrm_class */
113 FALSE
, /* compress_motion */
114 TRUE
, /* compress_exposure */
115 TRUE
, /* compress_enterleave */
116 FALSE
, /* visible_interest */
117 Destroy
, /* destroy */
119 Redisplay
, /* expose */
120 SetValues
, /* set_values */
121 SetValuesHook
, /* set_values_hook */
122 NULL
, /* set_values_almost */
123 NULL
, /* get_values_hook */
124 NULL
, /* accept_focus */
125 XtVersion
, /* version */
126 NULL
, /* callback_private */
128 QueryGeometry
, /* query_geometry */
129 NULL
, /* display_accelerator */
132 SaveToFile
, /* save */
136 WidgetClass dviWidgetClass
= (WidgetClass
) &dviClassRec
;
138 static void ClassInitialize ()
140 XtAddConverter( XtRString
, XtRBackingStore
, XmuCvtStringToBackingStore
,
144 /****************************************************************
148 ****************************************************************/
151 static void Initialize(request
, new)
154 DviWidget dw
= (DviWidget
) new;
156 dw
->dvi
.current_page
= 0;
157 dw
->dvi
.font_map
= 0;
158 dw
->dvi
.cache
.index
= 0;
159 dw
->dvi
.text_x_width
= 0;
160 dw
->dvi
.text_device_width
= 0;
161 dw
->dvi
.word_flag
= 0;
165 dw
->dvi
.readingTmp
= 0;
166 dw
->dvi
.cache
.char_index
= 0;
167 dw
->dvi
.cache
.font_size
= -1;
168 dw
->dvi
.cache
.font_number
= -1;
169 dw
->dvi
.cache
.adjustable
[0] = 0;
170 dw
->dvi
.file_map
= 0;
172 dw
->dvi
.seek
= False
;
173 dw
->dvi
.device_resolution
= dw
->dvi
.default_resolution
;
174 dw
->dvi
.display_resolution
= dw
->dvi
.default_resolution
;
175 dw
->dvi
.paperlength
= dw
->dvi
.default_resolution
*11;
176 dw
->dvi
.paperwidth
= (dw
->dvi
.default_resolution
*8
177 + dw
->dvi
.default_resolution
/2);
178 dw
->dvi
.scale_factor
= 1.0;
179 dw
->dvi
.sizescale
= 1;
180 dw
->dvi
.line_thickness
= -1;
181 dw
->dvi
.line_width
= 1;
182 dw
->dvi
.fill
= DVI_FILL_MAX
;
183 dw
->dvi
.device_font
= 0;
184 dw
->dvi
.device_font_number
= -1;
189 #include <X11/bitmaps/gray>
192 Realize (w
, valueMask
, attrs
)
194 XtValueMask
*valueMask
;
195 XSetWindowAttributes
*attrs
;
197 DviWidget dw
= (DviWidget
) w
;
200 if (dw
->dvi
.backing_store
!= Always
+ WhenMapped
+ NotUseful
) {
201 attrs
->backing_store
= dw
->dvi
.backing_store
;
202 *valueMask
|= CWBackingStore
;
204 XtCreateWindow (w
, (unsigned)InputOutput
, (Visual
*) CopyFromParent
,
206 values
.foreground
= dw
->dvi
.foreground
;
207 values
.cap_style
= CapRound
;
208 values
.join_style
= JoinRound
;
209 values
.line_width
= dw
->dvi
.line_width
;
210 dw
->dvi
.normal_GC
= XCreateGC (XtDisplay (w
), XtWindow (w
),
211 GCForeground
|GCCapStyle
|GCJoinStyle
214 dw
->dvi
.gray
= XCreateBitmapFromData(XtDisplay (w
), XtWindow (w
),
216 gray_width
, gray_height
);
217 values
.background
= dw
->dvi
.background
;
218 values
.stipple
= dw
->dvi
.gray
;
219 dw
->dvi
.fill_GC
= XCreateGC (XtDisplay (w
), XtWindow (w
),
220 GCForeground
|GCBackground
|GCStipple
,
223 dw
->dvi
.fill_type
= DVI_FILL_BLACK
;
234 DviWidget dw
= (DviWidget
) w
;
236 XFreeGC (XtDisplay (w
), dw
->dvi
.normal_GC
);
237 XFreeGC (XtDisplay (w
), dw
->dvi
.fill_GC
);
238 XFreePixmap (XtDisplay (w
), dw
->dvi
.gray
);
239 DestroyFontMap (dw
->dvi
.font_map
);
240 DestroyFileMap (dw
->dvi
.file_map
);
241 device_destroy (dw
->dvi
.device
);
245 * Repaint the widget window
250 Redisplay(w
, event
, region
)
255 DviWidget dw
= (DviWidget
) w
;
258 XClipBox (region
, &extents
);
259 dw
->dvi
.extents
.x1
= extents
.x
;
260 dw
->dvi
.extents
.y1
= extents
.y
;
261 dw
->dvi
.extents
.x2
= extents
.x
+ extents
.width
;
262 dw
->dvi
.extents
.y2
= extents
.y
+ extents
.height
;
267 * Set specified arguments into widget
271 SetValues (current
, request
, new)
272 DviWidget current
, request
, new;
274 Boolean redisplay
= FALSE
;
278 if (current
->dvi
.font_map_string
!= request
->dvi
.font_map_string
) {
279 new_map
= XtMalloc (strlen (request
->dvi
.font_map_string
) + 1);
282 strcpy (new_map
, request
->dvi
.font_map_string
);
283 new->dvi
.font_map_string
= new_map
;
284 if (current
->dvi
.font_map_string
)
285 XtFree (current
->dvi
.font_map_string
);
286 current
->dvi
.font_map_string
= 0;
291 req
= request
->dvi
.requested_page
;
292 cur
= current
->dvi
.requested_page
;
294 if (!request
->dvi
.file
)
299 if (current
->dvi
.last_page
!= 0 &&
300 req
> current
->dvi
.last_page
)
301 req
= current
->dvi
.last_page
;
305 new->dvi
.requested_page
= req
;
306 if (current
->dvi
.last_page
== 0 && req
> cur
)
314 * use the set_values_hook entry to check when
319 SetValuesHook (dw
, args
, num_argsp
)
326 for (i
= 0; i
< *num_argsp
; i
++) {
327 if (!strcmp (args
[i
].name
, XtNfile
)) {
336 static void CloseFile (dw
)
340 fclose (dw
->dvi
.tmpFile
);
341 ForgetPagePositions (dw
);
344 static void OpenFile (dw
)
347 char tmpName
[sizeof ("/tmp/dviXXXXXX")];
351 strcpy (tmpName
, "/tmp/dviXXXXXX");
353 dw
->dvi
.tmpFile
= fopen (tmpName
, "w+");
356 dw
->dvi
.requested_page
= 1;
357 dw
->dvi
.last_page
= 0;
360 static XtGeometryResult
361 QueryGeometry (w
, request
, geometry_return
)
363 XtWidgetGeometry
*request
, *geometry_return
;
365 XtGeometryResult ret
;
366 DviWidget dw
= (DviWidget
) w
;
369 if (((request
->request_mode
& CWWidth
)
370 && request
->width
< MY_WIDTH(dw
))
371 || ((request
->request_mode
& CWHeight
)
372 && request
->height
< MY_HEIGHT(dw
)))
373 ret
= XtGeometryAlmost
;
374 geometry_return
->width
= MY_WIDTH(dw
);
375 geometry_return
->height
= MY_HEIGHT(dw
);
376 geometry_return
->request_mode
= CWWidth
|CWHeight
;
384 XtWidgetGeometry request
, reply
;
385 XtGeometryResult ret
;
388 dw
->dvi
.device
= device_load (name
);
391 dw
->dvi
.sizescale
= dw
->dvi
.device
->sizescale
;
392 dw
->dvi
.device_resolution
= dw
->dvi
.device
->res
;
393 dw
->dvi
.native
= dw
->dvi
.device
->X11
;
394 dw
->dvi
.paperlength
= dw
->dvi
.device
->paperlength
;
395 dw
->dvi
.paperwidth
= dw
->dvi
.device
->paperwidth
;
396 if (dw
->dvi
.native
) {
397 dw
->dvi
.display_resolution
= dw
->dvi
.device_resolution
;
398 dw
->dvi
.scale_factor
= 1.0;
401 dw
->dvi
.display_resolution
= dw
->dvi
.default_resolution
;
402 dw
->dvi
.scale_factor
= ((double)dw
->dvi
.display_resolution
403 / dw
->dvi
.device_resolution
);
405 request
.request_mode
= CWWidth
|CWHeight
;
406 request
.width
= MY_WIDTH(dw
);
407 request
.height
= MY_HEIGHT(dw
);
408 ret
= XtMakeGeometryRequest ((Widget
)dw
, &request
, &reply
);
409 if (ret
== XtGeometryAlmost
410 && reply
.height
>= request
.height
411 && reply
.width
>= request
.width
) {
412 request
.width
= reply
.width
;
413 request
.height
= reply
.height
;
414 XtMakeGeometryRequest ((Widget
)dw
, &request
, &reply
);
423 static char Error
[] = "No file selected";
425 XSetFont (XtDisplay(dw
), dw
->dvi
.normal_GC
,
426 dw
->dvi
.default_font
->fid
);
427 XDrawString (XtDisplay (dw
), XtWindow (dw
), dw
->dvi
.normal_GC
,
428 20, 20, Error
, strlen (Error
));
434 dw
->dvi
.display_enable
= 1;
436 if (dw
->dvi
.last_page
&& dw
->dvi
.requested_page
> dw
->dvi
.last_page
)
437 dw
->dvi
.requested_page
= dw
->dvi
.last_page
;
447 if (dw
->dvi
.requested_page
< 1)
448 dw
->dvi
.requested_page
= 1;
450 if (dw
->dvi
.last_page
!= 0 && dw
->dvi
.requested_page
> dw
->dvi
.last_page
)
451 dw
->dvi
.requested_page
= dw
->dvi
.last_page
;
453 file_position
= SearchPagePosition (dw
, dw
->dvi
.requested_page
);
454 if (file_position
!= -1) {
455 FileSeek(dw
, file_position
);
456 dw
->dvi
.current_page
= dw
->dvi
.requested_page
;
458 for (i
=dw
->dvi
.requested_page
; i
> 0; i
--) {
459 file_position
= SearchPagePosition (dw
, i
);
460 if (file_position
!= -1)
463 if (file_position
== -1)
465 FileSeek (dw
, file_position
);
467 dw
->dvi
.current_page
= i
;
469 dw
->dvi
.display_enable
= 0;
470 while (dw
->dvi
.current_page
!= dw
->dvi
.requested_page
) {
471 dw
->dvi
.current_page
= ParseInput (dw
);
473 * at EOF, seek back to the beginning of this page.
475 if (!dw
->dvi
.readingTmp
&& feof (dw
->dvi
.file
)) {
476 file_position
= SearchPagePosition (dw
,
477 dw
->dvi
.current_page
);
478 if (file_position
!= -1)
479 FileSeek (dw
, file_position
);
480 dw
->dvi
.requested_page
= dw
->dvi
.current_page
;
487 void DviSaveToFile(w
, fp
)
491 XtCheckSubclass(w
, dviWidgetClass
, NULL
);
492 (*((DviWidgetClass
) XtClass(w
))->command_class
.save
)(w
, fp
);
496 void SaveToFile(w
, fp
)
500 DviWidget dw
= (DviWidget
)w
;
504 if (dw
->dvi
.tmpFile
) {
505 pos
= ftell(dw
->dvi
.tmpFile
);
509 /* The ungot character is in the tmpFile, so we don't
510 want to read it from file. */
511 (void)getc(dw
->dvi
.file
);
515 pos
= ftell(dw
->dvi
.file
);
517 while (DviGetC(dw
, &c
) != EOF
)
518 if (putc(c
, fp
) == EOF
) {
519 /* XXX print error message */
526 void ClassPartInitialize(widget_class
)
527 WidgetClass widget_class
;
529 DviWidgetClass wc
= (DviWidgetClass
)widget_class
;
530 DviWidgetClass super
= (DviWidgetClass
) wc
->core_class
.superclass
;
531 if (wc
->command_class
.save
== InheritSaveToFile
)
532 wc
->command_class
.save
= super
->command_class
.save
;
538 c-continued-statement-offset: 8
542 c-tab-always-indent: nil