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;
199 Realize (w
, valueMask
, attrs
)
201 XtValueMask
*valueMask
;
202 XSetWindowAttributes
*attrs
;
204 DviWidget dw
= (DviWidget
) w
;
207 if (dw
->dvi
.backing_store
!= Always
+ WhenMapped
+ NotUseful
) {
208 attrs
->backing_store
= dw
->dvi
.backing_store
;
209 *valueMask
|= CWBackingStore
;
211 XtCreateWindow (w
, (unsigned)InputOutput
, (Visual
*) CopyFromParent
,
213 values
.foreground
= dw
->dvi
.foreground
;
214 values
.cap_style
= CapRound
;
215 values
.join_style
= JoinRound
;
216 values
.line_width
= dw
->dvi
.line_width
;
217 dw
->dvi
.normal_GC
= XCreateGC (XtDisplay (w
), XtWindow (w
),
218 GCForeground
|GCCapStyle
|GCJoinStyle
221 dw
->dvi
.gray
[0] = XCreateBitmapFromData(XtDisplay (w
), XtWindow (w
),
223 gray1_width
, gray1_height
);
224 dw
->dvi
.gray
[1] = XCreateBitmapFromData(XtDisplay (w
), XtWindow (w
),
226 gray2_width
, gray2_height
);
227 dw
->dvi
.gray
[2] = XCreateBitmapFromData(XtDisplay (w
), XtWindow (w
),
229 gray3_width
, gray3_height
);
230 dw
->dvi
.gray
[3] = XCreateBitmapFromData(XtDisplay (w
), XtWindow (w
),
232 gray4_width
, gray4_height
);
233 dw
->dvi
.gray
[4] = XCreateBitmapFromData(XtDisplay (w
), XtWindow (w
),
235 gray5_width
, gray5_height
);
236 dw
->dvi
.gray
[5] = XCreateBitmapFromData(XtDisplay (w
), XtWindow (w
),
238 gray6_width
, gray6_height
);
239 dw
->dvi
.gray
[6] = XCreateBitmapFromData(XtDisplay (w
), XtWindow (w
),
241 gray7_width
, gray7_height
);
242 dw
->dvi
.gray
[7] = XCreateBitmapFromData(XtDisplay (w
), XtWindow (w
),
244 gray8_width
, gray8_height
);
245 values
.background
= dw
->dvi
.background
;
246 values
.stipple
= dw
->dvi
.gray
[5];
247 dw
->dvi
.fill_GC
= XCreateGC (XtDisplay (w
), XtWindow (w
),
248 GCForeground
|GCBackground
|GCStipple
,
251 dw
->dvi
.fill_type
= 9;
262 DviWidget dw
= (DviWidget
) w
;
264 XFreeGC (XtDisplay (w
), dw
->dvi
.normal_GC
);
265 XFreeGC (XtDisplay (w
), dw
->dvi
.fill_GC
);
266 XFreePixmap (XtDisplay (w
), dw
->dvi
.gray
[0]);
267 XFreePixmap (XtDisplay (w
), dw
->dvi
.gray
[1]);
268 XFreePixmap (XtDisplay (w
), dw
->dvi
.gray
[2]);
269 XFreePixmap (XtDisplay (w
), dw
->dvi
.gray
[3]);
270 XFreePixmap (XtDisplay (w
), dw
->dvi
.gray
[4]);
271 XFreePixmap (XtDisplay (w
), dw
->dvi
.gray
[5]);
272 XFreePixmap (XtDisplay (w
), dw
->dvi
.gray
[6]);
273 XFreePixmap (XtDisplay (w
), dw
->dvi
.gray
[7]);
274 DestroyFontMap (dw
->dvi
.font_map
);
275 DestroyFileMap (dw
->dvi
.file_map
);
276 device_destroy (dw
->dvi
.device
);
280 * Repaint the widget window
285 Redisplay(w
, event
, region
)
290 DviWidget dw
= (DviWidget
) w
;
293 XClipBox (region
, &extents
);
294 dw
->dvi
.extents
.x1
= extents
.x
;
295 dw
->dvi
.extents
.y1
= extents
.y
;
296 dw
->dvi
.extents
.x2
= extents
.x
+ extents
.width
;
297 dw
->dvi
.extents
.y2
= extents
.y
+ extents
.height
;
302 * Set specified arguments into widget
306 SetValues (current
, request
, new)
307 DviWidget current
, request
, new;
309 Boolean redisplay
= FALSE
;
313 if (current
->dvi
.font_map_string
!= request
->dvi
.font_map_string
) {
314 new_map
= XtMalloc (strlen (request
->dvi
.font_map_string
) + 1);
317 strcpy (new_map
, request
->dvi
.font_map_string
);
318 new->dvi
.font_map_string
= new_map
;
319 if (current
->dvi
.font_map_string
)
320 XtFree (current
->dvi
.font_map_string
);
321 current
->dvi
.font_map_string
= 0;
326 req
= request
->dvi
.requested_page
;
327 cur
= current
->dvi
.requested_page
;
329 if (!request
->dvi
.file
)
334 if (current
->dvi
.last_page
!= 0 &&
335 req
> current
->dvi
.last_page
)
336 req
= current
->dvi
.last_page
;
340 new->dvi
.requested_page
= req
;
341 if (current
->dvi
.last_page
== 0 && req
> cur
)
349 * use the set_values_hook entry to check when
354 SetValuesHook (dw
, args
, num_argsp
)
361 for (i
= 0; i
< *num_argsp
; i
++) {
362 if (!strcmp (args
[i
].name
, XtNfile
)) {
371 static void CloseFile (dw
)
375 fclose (dw
->dvi
.tmpFile
);
376 ForgetPagePositions (dw
);
379 static void OpenFile (dw
)
384 dw
->dvi
.tmpFile
= tmpfile();
385 dw
->dvi
.requested_page
= 1;
386 dw
->dvi
.last_page
= 0;
389 static XtGeometryResult
390 QueryGeometry (w
, request
, geometry_return
)
392 XtWidgetGeometry
*request
, *geometry_return
;
394 XtGeometryResult ret
;
395 DviWidget dw
= (DviWidget
) w
;
398 if (((request
->request_mode
& CWWidth
)
399 && request
->width
< MY_WIDTH(dw
))
400 || ((request
->request_mode
& CWHeight
)
401 && request
->height
< MY_HEIGHT(dw
)))
402 ret
= XtGeometryAlmost
;
403 geometry_return
->width
= MY_WIDTH(dw
);
404 geometry_return
->height
= MY_HEIGHT(dw
);
405 geometry_return
->request_mode
= CWWidth
|CWHeight
;
413 XtWidgetGeometry request
, reply
;
414 XtGeometryResult ret
;
417 dw
->dvi
.device
= device_load (name
);
420 dw
->dvi
.sizescale
= dw
->dvi
.device
->sizescale
;
421 dw
->dvi
.device_resolution
= dw
->dvi
.device
->res
;
422 dw
->dvi
.native
= dw
->dvi
.device
->X11
;
423 dw
->dvi
.paperlength
= dw
->dvi
.device
->paperlength
;
424 dw
->dvi
.paperwidth
= dw
->dvi
.device
->paperwidth
;
425 if (dw
->dvi
.native
) {
426 dw
->dvi
.display_resolution
= dw
->dvi
.device_resolution
;
427 dw
->dvi
.scale_factor
= 1.0;
430 dw
->dvi
.display_resolution
= dw
->dvi
.default_resolution
;
431 dw
->dvi
.scale_factor
= ((double)dw
->dvi
.display_resolution
432 / dw
->dvi
.device_resolution
);
434 request
.request_mode
= CWWidth
|CWHeight
;
435 request
.width
= MY_WIDTH(dw
);
436 request
.height
= MY_HEIGHT(dw
);
437 ret
= XtMakeGeometryRequest ((Widget
)dw
, &request
, &reply
);
438 if (ret
== XtGeometryAlmost
439 && reply
.height
>= request
.height
440 && reply
.width
>= request
.width
) {
441 request
.width
= reply
.width
;
442 request
.height
= reply
.height
;
443 XtMakeGeometryRequest ((Widget
)dw
, &request
, &reply
);
452 static char Error
[] = "No file selected";
454 XSetFont (XtDisplay(dw
), dw
->dvi
.normal_GC
,
455 dw
->dvi
.default_font
->fid
);
456 XDrawString (XtDisplay (dw
), XtWindow (dw
), dw
->dvi
.normal_GC
,
457 20, 20, Error
, strlen (Error
));
463 dw
->dvi
.display_enable
= 1;
465 if (dw
->dvi
.last_page
&& dw
->dvi
.requested_page
> dw
->dvi
.last_page
)
466 dw
->dvi
.requested_page
= dw
->dvi
.last_page
;
476 if (dw
->dvi
.requested_page
< 1)
477 dw
->dvi
.requested_page
= 1;
479 if (dw
->dvi
.last_page
!= 0 && dw
->dvi
.requested_page
> dw
->dvi
.last_page
)
480 dw
->dvi
.requested_page
= dw
->dvi
.last_page
;
482 file_position
= SearchPagePosition (dw
, dw
->dvi
.requested_page
);
483 if (file_position
!= -1) {
484 FileSeek(dw
, file_position
);
485 dw
->dvi
.current_page
= dw
->dvi
.requested_page
;
487 for (i
=dw
->dvi
.requested_page
; i
> 0; i
--) {
488 file_position
= SearchPagePosition (dw
, i
);
489 if (file_position
!= -1)
492 if (file_position
== -1)
494 FileSeek (dw
, file_position
);
496 dw
->dvi
.current_page
= i
;
498 dw
->dvi
.display_enable
= 0;
499 while (dw
->dvi
.current_page
!= dw
->dvi
.requested_page
) {
500 dw
->dvi
.current_page
= ParseInput (dw
);
502 * at EOF, seek back to the beginning of this page.
504 if (!dw
->dvi
.readingTmp
&& feof (dw
->dvi
.file
)) {
505 file_position
= SearchPagePosition (dw
,
506 dw
->dvi
.current_page
);
507 if (file_position
!= -1)
508 FileSeek (dw
, file_position
);
509 dw
->dvi
.requested_page
= dw
->dvi
.current_page
;
516 void DviSaveToFile(w
, fp
)
520 XtCheckSubclass(w
, dviWidgetClass
, NULL
);
521 (*((DviWidgetClass
) XtClass(w
))->command_class
.save
)(w
, fp
);
525 void SaveToFile(w
, fp
)
529 DviWidget dw
= (DviWidget
)w
;
533 if (dw
->dvi
.tmpFile
) {
534 pos
= ftell(dw
->dvi
.tmpFile
);
538 /* The ungot character is in the tmpFile, so we don't
539 want to read it from file. */
540 (void)getc(dw
->dvi
.file
);
544 pos
= ftell(dw
->dvi
.file
);
546 while (DviGetC(dw
, &c
) != EOF
)
547 if (putc(c
, fp
) == EOF
) {
548 /* XXX print error message */
555 void ClassPartInitialize(widget_class
)
556 WidgetClass widget_class
;
558 DviWidgetClass wc
= (DviWidgetClass
)widget_class
;
559 DviWidgetClass super
= (DviWidgetClass
) wc
->core_class
.superclass
;
560 if (wc
->command_class
.save
== InheritSaveToFile
)
561 wc
->command_class
.save
= super
->command_class
.save
;
567 c-continued-statement-offset: 8
571 c-tab-always-indent: nil