* src/roff/troff/node.cpp (suppress_node::tprint): Don't expect
[s-roff.git] / src / xditview / Dvi.c
blobb577b9aada8de51e3daa56238c6a2c723990c16e
1 #ifndef SABER
2 #ifndef lint
3 static char Xrcsid[] = "$XConsortium: Dvi.c,v 1.9 89/12/10 16:12:25 rws Exp $";
4 #endif /* lint */
5 #endif /* SABER */
7 /*
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>
21 #include <stdio.h>
22 #include <ctype.h>
23 #include "DviP.h"
25 /****************************************************************
27 * Full class record constant
29 ****************************************************************/
31 /* Private Data */
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"},
84 #undef offset
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 /* font.c */
98 extern void ParseFontMap();
99 extern void DestroyFontMap();
100 extern void ForgetFonts();
102 /* page.c */
103 extern void DestroyFileMap();
104 extern long SearchPagePosition();
105 extern void FileSeek();
106 extern void ForgetPagePositions();
108 /* parse.c */
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 */
122 NULL, /* actions */
123 0, /* num_actions */
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 */
132 NULL, /* resize */
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 */
141 0, /* tm_table */
142 QueryGeometry, /* query_geometry */
143 NULL, /* display_accelerator */
144 NULL /* extension */
146 SaveToFile, /* save */
150 WidgetClass dviWidgetClass = (WidgetClass) &dviClassRec;
152 static void ClassInitialize ()
154 XtAddConverter( XtRString, XtRBackingStore, XmuCvtStringToBackingStore,
155 NULL, 0 );
158 /****************************************************************
160 * Private Procedures
162 ****************************************************************/
164 /* ARGSUSED */
165 static void Initialize(request, new)
166 Widget 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;
176 dw->dvi.file = 0;
177 dw->dvi.tmpFile = 0;
178 dw->dvi.state = 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;
185 dw->dvi.fonts = 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;
199 dw->dvi.device = 0;
200 dw->dvi.native = 0;
203 #include "gray1.bm"
204 #include "gray2.bm"
205 #include "gray3.bm"
206 #include "gray4.bm"
207 #include "gray5.bm"
208 #include "gray6.bm"
209 #include "gray7.bm"
210 #include "gray8.bm"
212 static void
213 Realize (w, valueMask, attrs)
214 Widget w;
215 XtValueMask *valueMask;
216 XSetWindowAttributes *attrs;
218 DviWidget dw = (DviWidget) w;
219 XGCValues values;
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,
226 *valueMask, attrs);
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
233 |GCLineWidth,
234 &values);
235 dw->dvi.gray[0] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
236 gray1_bits,
237 gray1_width, gray1_height);
238 dw->dvi.gray[1] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
239 gray2_bits,
240 gray2_width, gray2_height);
241 dw->dvi.gray[2] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
242 gray3_bits,
243 gray3_width, gray3_height);
244 dw->dvi.gray[3] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
245 gray4_bits,
246 gray4_width, gray4_height);
247 dw->dvi.gray[4] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
248 gray5_bits,
249 gray5_width, gray5_height);
250 dw->dvi.gray[5] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
251 gray6_bits,
252 gray6_width, gray6_height);
253 dw->dvi.gray[6] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
254 gray7_bits,
255 gray7_width, gray7_height);
256 dw->dvi.gray[7] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
257 gray8_bits,
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,
263 &values);
265 dw->dvi.fill_type = 9;
267 if (dw->dvi.file)
268 OpenFile (dw);
269 ParseFontMap (dw);
272 static void
273 Destroy(w)
274 Widget w;
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
297 /* ARGSUSED */
298 static void
299 Redisplay(w, event, region)
300 Widget w;
301 XEvent *event;
302 Region region;
304 DviWidget dw = (DviWidget) w;
305 XRectangle extents;
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;
312 ShowDvi (dw);
316 * Set specified arguments into widget
318 /* ARGSUSED */
319 static Boolean
320 SetValues (current, request, new)
321 DviWidget current, request, new;
323 Boolean redisplay = FALSE;
324 char *new_map;
325 int cur, req;
327 if (current->dvi.font_map_string != request->dvi.font_map_string) {
328 new_map = XtMalloc (strlen (request->dvi.font_map_string) + 1);
329 if (new_map) {
330 redisplay = TRUE;
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;
336 ParseFontMap (new);
340 req = request->dvi.requested_page;
341 cur = current->dvi.requested_page;
342 if (cur != req) {
343 if (!request->dvi.file)
344 req = 0;
345 else {
346 if (req < 1)
347 req = 1;
348 if (current->dvi.last_page != 0 &&
349 req > current->dvi.last_page)
350 req = current->dvi.last_page;
352 if (cur != req)
353 redisplay = TRUE;
354 new->dvi.requested_page = req;
355 if (current->dvi.last_page == 0 && req > cur)
356 FindPage (new);
359 return redisplay;
363 * use the set_values_hook entry to check when
364 * the file is set
367 static Boolean
368 SetValuesHook (dw, args, num_argsp)
369 DviWidget dw;
370 ArgList args;
371 Cardinal *num_argsp;
373 Cardinal i;
375 for (i = 0; i < *num_argsp; i++) {
376 if (!strcmp (args[i].name, XtNfile)) {
377 CloseFile (dw);
378 OpenFile (dw);
379 return TRUE;
382 return FALSE;
385 static void CloseFile (dw)
386 DviWidget dw;
388 if (dw->dvi.tmpFile)
389 fclose (dw->dvi.tmpFile);
390 ForgetPagePositions (dw);
393 static void OpenFile (dw)
394 DviWidget dw;
396 dw->dvi.tmpFile = 0;
397 if (!dw->dvi.seek)
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)
405 Widget w;
406 XtWidgetGeometry *request, *geometry_return;
408 XtGeometryResult ret;
409 DviWidget dw = (DviWidget) w;
411 ret = XtGeometryYes;
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;
420 return ret;
423 void
424 SetDevice (dw, name)
425 DviWidget dw;
426 char *name;
428 XtWidgetGeometry request, reply;
429 XtGeometryResult ret;
431 ForgetFonts (dw);
432 dw->dvi.device = device_load (name);
433 if (!dw->dvi.device)
434 return;
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;
444 else {
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);
462 static void
463 ShowDvi (dw)
464 DviWidget dw;
466 if (!dw->dvi.file) {
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));
473 return;
476 FindPage (dw);
478 dw->dvi.display_enable = 1;
479 ParseInput (dw);
480 if (dw->dvi.last_page && dw->dvi.requested_page > dw->dvi.last_page)
481 dw->dvi.requested_page = dw->dvi.last_page;
484 static void
485 FindPage (dw)
486 DviWidget dw;
488 int i;
489 long file_position;
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;
501 } else {
502 for (i=dw->dvi.requested_page; i > 0; i--) {
503 file_position = SearchPagePosition (dw, i);
504 if (file_position != -1)
505 break;
507 if (file_position == -1)
508 file_position = 0;
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;
525 break;
531 void DviSaveToFile(w, fp)
532 Widget w;
533 FILE *fp;
535 XtCheckSubclass(w, dviWidgetClass, NULL);
536 (*((DviWidgetClass) XtClass(w))->command_class.save)(w, fp);
539 static
540 void SaveToFile(w, fp)
541 Widget w;
542 FILE *fp;
544 DviWidget dw = (DviWidget)w;
545 long pos;
546 int c;
548 if (dw->dvi.tmpFile) {
549 pos = ftell(dw->dvi.tmpFile);
550 if (dw->dvi.ungot) {
551 pos--;
552 dw->dvi.ungot = 0;
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);
558 else
559 pos = ftell(dw->dvi.file);
560 FileSeek(dw, 0L);
561 while (DviGetC(dw, &c) != EOF)
562 if (putc(c, fp) == EOF) {
563 /* XXX print error message */
564 break;
566 FileSeek(dw, pos);
569 static
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;
580 Local Variables:
581 c-indent-level: 8
582 c-continued-statement-offset: 8
583 c-brace-offset: -8
584 c-argdecl-indent: 8
585 c-label-offset: -8
586 c-tab-always-indent: nil
587 End: