No empty .Rs/.Re
[netbsd-mini2440.git] / gnu / dist / groff / src / devices / xditview / Dvi.c
blob142054af03b8bd7ea359d1b5f150dcd800a9288d
1 /* $NetBSD$ */
3 #ifndef SABER
4 #ifndef lint
5 static char Xrcsid[] = "$XConsortium: Dvi.c,v 1.9 89/12/10 16:12:25 rws Exp $";
6 #endif /* lint */
7 #endif /* SABER */
9 /*
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>
23 #include <stdio.h>
24 #include <ctype.h>
25 #include "DviP.h"
27 /****************************************************************
29 * Full class record constant
31 ****************************************************************/
33 /* Private Data */
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"},
101 #undef offset
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 *,
113 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 *);
121 /* font.c */
122 extern void ParseFontMap(DviWidget);
123 extern void DestroyFontMap(DviFontMap *);
124 extern void ForgetFonts(DviWidget);
126 /* page.c */
127 extern void DestroyFileMap(DviFileMap *);
128 extern long SearchPagePosition(DviWidget, int);
129 extern void FileSeek(DviWidget, long);
130 extern void ForgetPagePositions(DviWidget);
132 /* parse.c */
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 */
146 NULL, /* actions */
147 0, /* num_actions */
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 */
156 NULL, /* resize */
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 */
165 0, /* tm_table */
166 QueryGeometry, /* query_geometry */
167 NULL, /* display_accelerator */
168 NULL /* extension */
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);
182 char *ptr = dfm;
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,
189 NULL, 0 );
192 /****************************************************************
194 * Private Procedures
196 ****************************************************************/
198 /* ARGSUSED */
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;
210 dw->dvi.file = 0;
211 dw->dvi.tmpFile = 0;
212 dw->dvi.state = 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;
219 dw->dvi.fonts = 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;
233 dw->dvi.device = 0;
234 dw->dvi.native = 0;
236 request = request; /* unused; suppress compiler warning */
237 args = args;
238 num_args = num_args;
241 #include "gray1.bm"
242 #include "gray2.bm"
243 #include "gray3.bm"
244 #include "gray4.bm"
245 #include "gray5.bm"
246 #include "gray6.bm"
247 #include "gray7.bm"
248 #include "gray8.bm"
250 static void
251 Realize (Widget w, XtValueMask *valueMask, XSetWindowAttributes *attrs)
253 DviWidget dw = (DviWidget) w;
254 XGCValues values;
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,
261 *valueMask, attrs);
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
268 |GCLineWidth,
269 &values);
270 dw->dvi.gray[0] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
271 gray1_bits,
272 gray1_width, gray1_height);
273 dw->dvi.gray[1] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
274 gray2_bits,
275 gray2_width, gray2_height);
276 dw->dvi.gray[2] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
277 gray3_bits,
278 gray3_width, gray3_height);
279 dw->dvi.gray[3] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
280 gray4_bits,
281 gray4_width, gray4_height);
282 dw->dvi.gray[4] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
283 gray5_bits,
284 gray5_width, gray5_height);
285 dw->dvi.gray[5] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
286 gray6_bits,
287 gray6_width, gray6_height);
288 dw->dvi.gray[6] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
289 gray7_bits,
290 gray7_width, gray7_height);
291 dw->dvi.gray[7] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
292 gray8_bits,
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,
298 &values);
300 dw->dvi.fill_type = 9;
302 if (dw->dvi.file)
303 OpenFile (dw);
304 ParseFontMap (dw);
307 static void
308 Destroy(Widget w)
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
331 /* ARGSUSED */
332 static void
333 Redisplay(Widget w, XEvent *event, Region region)
335 DviWidget dw = (DviWidget) w;
336 XRectangle extents;
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;
343 ShowDvi (dw);
345 event = event; /* unused; suppress compiler warning */
349 * Set specified arguments into widget
351 /* ARGSUSED */
352 static Boolean
353 SetValues (Widget wcurrent, Widget wrequest, Widget wnew,
354 ArgList args, Cardinal *num_args)
356 Boolean redisplay = FALSE;
357 char *new_map;
358 int cur, req;
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);
365 if (new_map) {
366 redisplay = TRUE;
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;
378 if (cur != req) {
379 if (!request->dvi.file)
380 req = 0;
381 else {
382 if (req < 1)
383 req = 1;
384 if (current->dvi.last_page != 0 &&
385 req > current->dvi.last_page)
386 req = current->dvi.last_page;
388 if (cur != req)
389 redisplay = TRUE;
390 new_wd->dvi.requested_page = req;
391 if (current->dvi.last_page == 0 && req > cur)
392 FindPage (new_wd);
395 args = args; /* unused; suppress compiler warning */
396 num_args = num_args;
398 return redisplay;
402 * use the set_values_hook entry to check when
403 * the file is set
406 static Boolean
407 SetValuesHook (Widget wdw, ArgList args, Cardinal *num_argsp)
409 Cardinal i;
410 DviWidget dw = (DviWidget)wdw;
412 for (i = 0; i < *num_argsp; i++) {
413 if (!strcmp (args[i].name, XtNfile)) {
414 CloseFile (dw);
415 OpenFile (dw);
416 return TRUE;
419 return FALSE;
422 static void CloseFile (DviWidget dw)
424 if (dw->dvi.tmpFile)
425 fclose (dw->dvi.tmpFile);
426 ForgetPagePositions (dw);
429 static void OpenFile (DviWidget dw)
431 dw->dvi.tmpFile = 0;
432 if (!dw->dvi.seek)
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;
445 ret = XtGeometryYes;
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;
454 return ret;
457 void
458 SetDevice (DviWidget dw, const char *name)
460 XtWidgetGeometry request, reply;
461 XtGeometryResult ret;
463 ForgetFonts (dw);
464 dw->dvi.device = device_load (name);
465 if (!dw->dvi.device)
466 return;
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;
476 else {
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);
494 static void
495 ShowDvi (DviWidget dw)
497 if (!dw->dvi.file) {
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));
504 return;
507 FindPage (dw);
509 dw->dvi.display_enable = 1;
510 ParseInput (dw);
511 if (dw->dvi.last_page && dw->dvi.requested_page > dw->dvi.last_page)
512 dw->dvi.requested_page = dw->dvi.last_page;
515 static void
516 FindPage (DviWidget dw)
518 int i;
519 long file_position;
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;
531 } else {
532 for (i=dw->dvi.requested_page; i > 0; i--) {
533 file_position = SearchPagePosition (dw, i);
534 if (file_position != -1)
535 break;
537 if (file_position == -1)
538 file_position = 0;
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;
555 break;
561 void DviSaveToFile(Widget w, FILE *fp)
563 XtCheckSubclass(w, dviWidgetClass, NULL);
564 (*((DviWidgetClass) XtClass(w))->command_class.save)(w, fp);
567 static
568 void SaveToFile(Widget w, FILE *fp)
570 DviWidget dw = (DviWidget)w;
571 long pos;
572 int c;
574 if (dw->dvi.tmpFile) {
575 pos = ftell(dw->dvi.tmpFile);
576 if (dw->dvi.ungot) {
577 pos--;
578 dw->dvi.ungot = 0;
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);
584 else
585 pos = ftell(dw->dvi.file);
586 FileSeek(dw, 0L);
587 while (DviGetC(dw, &c) != EOF)
588 if (putc(c, fp) == EOF) {
589 /* XXX print error message */
590 break;
592 FileSeek(dw, pos);
595 static
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;
605 Local Variables:
606 c-indent-level: 8
607 c-continued-statement-offset: 8
608 c-brace-offset: -8
609 c-argdecl-indent: 8
610 c-label-offset: -8
611 c-tab-always-indent: nil
612 End: