]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/groff/src/devices/xditview/Dvi.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / groff / src / devices / xditview / Dvi.c
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 */
6
7 /*
8  * Dvi.c - Dvi display widget
9  *
10  */
11
12 #define XtStrlen(s)     ((s) ? strlen(s) : 0)
13
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.  */
17
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"
24
25 /****************************************************************
26  *
27  * Full class record constant
28  *
29  ****************************************************************/
30
31 /* Private Data */
32
33 static char default_font_map_1[] = "\
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 ";
43 static char default_font_map_2[] = "\
44 HR      -adobe-helvetica-medium-r-normal--*-100-*-*-*-*-iso8859-1\n\
45 HI      -adobe-helvetica-medium-o-normal--*-100-*-*-*-*-iso8859-1\n\
46 HB      -adobe-helvetica-bold-r-normal--*-100-*-*-*-*-iso8859-1\n\
47 HBI     -adobe-helvetica-bold-o-normal--*-100-*-*-*-*-iso8859-1\n\
48 ";
49 static char default_font_map_3[] = "\
50 NR      -adobe-new century schoolbook-medium-r-normal--*-100-*-*-*-*-iso8859-1\n\
51 NI      -adobe-new century schoolbook-medium-i-normal--*-100-*-*-*-*-iso8859-1\n\
52 NB      -adobe-new century schoolbook-bold-r-normal--*-100-*-*-*-*-iso8859-1\n\
53 NBI     -adobe-new century schoolbook-bold-i-normal--*-100-*-*-*-*-iso8859-1\n\
54 S       -adobe-symbol-medium-r-normal--*-100-*-*-*-*-adobe-fontspecific\n\
55 SS      -adobe-symbol-medium-r-normal--*-100-*-*-*-*-adobe-fontspecific\n\
56 ";
57
58 #define offset(field) XtOffset(DviWidget, field)
59
60 #define MY_WIDTH(dw) ((int)(dw->dvi.paperwidth * dw->dvi.scale_factor + .5))
61 #define MY_HEIGHT(dw) ((int)(dw->dvi.paperlength * dw->dvi.scale_factor + .5))
62
63 static XtResource resources[] = { 
64         {(String)XtNfontMap, (String)XtCFontMap, (String)XtRString,
65          sizeof (char *), offset(dvi.font_map_string),
66          (String)XtRString, NULL /* set in code */},
67         {(String)XtNforeground, (String)XtCForeground, (String)XtRPixel,
68          sizeof (unsigned long), offset(dvi.foreground),
69          (String)XtRString, (XtPointer)"XtDefaultForeground"},
70         {(String)XtNbackground, (String)XtCBackground, (String)XtRPixel,
71          sizeof (unsigned long), offset(dvi.background),
72          (String)XtRString, (XtPointer)"XtDefaultBackground"},
73         {(String)XtNpageNumber, (String)XtCPageNumber, (String)XtRInt,
74          sizeof (int), offset(dvi.requested_page),
75          (String)XtRString, (XtPointer)"1"},
76         {(String)XtNlastPageNumber, (String)XtCLastPageNumber, (String)XtRInt,
77          sizeof (int), offset (dvi.last_page),
78          (String)XtRString, (XtPointer)"0"},
79         {(String)XtNfile, (String)XtCFile, (String)XtRFile,
80          sizeof (FILE *), offset (dvi.file),
81          (String)XtRFile, (XtPointer)0},
82         {(String)XtNseek, (String)XtCSeek, (String)XtRBoolean,
83          sizeof (Boolean), offset(dvi.seek),
84          (String)XtRString, (XtPointer)"false"},
85         {(String)XtNfont, (String)XtCFont, (String)XtRFontStruct,
86          sizeof (XFontStruct *), offset(dvi.default_font),
87          (String)XtRString, (XtPointer)"xtdefaultfont"},
88         {(String)XtNbackingStore, (String)XtCBackingStore, (String)XtRBackingStore,
89          sizeof (int), offset(dvi.backing_store),
90          (String)XtRString, (XtPointer)"default"},
91         {(String)XtNnoPolyText, (String)XtCNoPolyText, (String)XtRBoolean,
92          sizeof (Boolean), offset(dvi.noPolyText),
93          (String)XtRString, (XtPointer)"false"},
94         {(String)XtNresolution, (String)XtCResolution, (String)XtRInt,
95          sizeof(int), offset(dvi.default_resolution),
96          (String)XtRString, (XtPointer)"75"},
97 };
98
99 #undef offset
100
101 static void             ClassInitialize (void);
102 static void             ClassPartInitialize(WidgetClass);
103 static void             Initialize(Widget, Widget, ArgList, Cardinal *);
104 static void             Realize (Widget, XtValueMask *, XSetWindowAttributes *);
105 static void             Destroy (Widget);
106 static void             Redisplay (Widget, XEvent *, Region);
107 static Boolean          SetValues (Widget, Widget, Widget,
108                                    ArgList, Cardinal *);
109 static Boolean          SetValuesHook (Widget, ArgList, Cardinal *);
110 static XtGeometryResult QueryGeometry (Widget, XtWidgetGeometry *,
111                                        XtWidgetGeometry *);
112 static void             ShowDvi (DviWidget);
113 static void             CloseFile (DviWidget);
114 static void             OpenFile (DviWidget);
115 static void             FindPage (DviWidget);
116
117 static void             SaveToFile (Widget, FILE *);
118
119 /* font.c */
120 extern void ParseFontMap(DviWidget);
121 extern void DestroyFontMap(DviFontMap *);
122 extern void ForgetFonts(DviWidget);
123
124 /* page.c */
125 extern void DestroyFileMap(DviFileMap *);
126 extern long SearchPagePosition(DviWidget, int);
127 extern void FileSeek(DviWidget, long);
128 extern void ForgetPagePositions(DviWidget);
129
130 /* parse.c */
131 extern int ParseInput(register DviWidget);
132
133 DviClassRec dviClassRec = {
134 {
135         &widgetClassRec,                /* superclass             */    
136         (String)"Dvi",                  /* class_name             */
137         sizeof(DviRec),                 /* size                   */
138         ClassInitialize,                /* class_initialize       */
139         ClassPartInitialize,            /* class_part_initialize  */
140         FALSE,                          /* class_inited           */
141         Initialize,                     /* initialize             */
142         NULL,                           /* initialize_hook        */
143         Realize,                        /* realize                */
144         NULL,                           /* actions                */
145         0,                              /* num_actions            */
146         resources,                      /* resources              */
147         XtNumber(resources),            /* resource_count         */
148         NULLQUARK,                      /* xrm_class              */
149         FALSE,                          /* compress_motion        */
150         TRUE,                           /* compress_exposure      */
151         TRUE,                           /* compress_enterleave    */
152         FALSE,                          /* visible_interest       */
153         Destroy,                        /* destroy                */
154         NULL,                           /* resize                 */
155         Redisplay,                      /* expose                 */
156         SetValues,                      /* set_values             */
157         SetValuesHook,                  /* set_values_hook        */
158         NULL,                           /* set_values_almost      */
159         NULL,                           /* get_values_hook        */
160         NULL,                           /* accept_focus           */
161         XtVersion,                      /* version                */
162         NULL,                           /* callback_private       */
163         0,                              /* tm_table               */
164         QueryGeometry,                  /* query_geometry         */
165         NULL,                           /* display_accelerator    */
166         NULL                            /* extension              */
167 },{
168         SaveToFile,                     /* save    */
169 },
170 };
171
172 WidgetClass dviWidgetClass = (WidgetClass) &dviClassRec;
173
174 static void ClassInitialize (void)
175 {
176         int len1 = strlen(default_font_map_1);
177         int len2 = strlen(default_font_map_2);
178         int len3 = strlen(default_font_map_3);
179         char *dfm = XtMalloc(len1 + len2 + len3 + 1);
180         char *ptr = dfm;
181         strcpy(ptr, default_font_map_1); ptr += len1;
182         strcpy(ptr, default_font_map_2); ptr += len2;
183         strcpy(ptr, default_font_map_3);
184         resources[0].default_addr = dfm;
185
186         XtAddConverter( XtRString, XtRBackingStore, XmuCvtStringToBackingStore,
187                         NULL, 0 );
188 }
189
190 /****************************************************************
191  *
192  * Private Procedures
193  *
194  ****************************************************************/
195
196 /* ARGSUSED */
197 static void Initialize(Widget request, Widget new_wd,
198                        ArgList args, Cardinal *num_args)
199 {
200         DviWidget       dw = (DviWidget) new_wd;
201
202         dw->dvi.current_page = 0;
203         dw->dvi.font_map = 0;
204         dw->dvi.cache.index = 0;
205         dw->dvi.text_x_width = 0;
206         dw->dvi.text_device_width = 0;
207         dw->dvi.word_flag = 0;
208         dw->dvi.file = 0;
209         dw->dvi.tmpFile = 0;
210         dw->dvi.state = 0;
211         dw->dvi.readingTmp = 0;
212         dw->dvi.cache.char_index = 0;
213         dw->dvi.cache.font_size = -1;
214         dw->dvi.cache.font_number = -1;
215         dw->dvi.cache.adjustable[0] = 0;
216         dw->dvi.file_map = 0;
217         dw->dvi.fonts = 0;
218         dw->dvi.seek = False;
219         dw->dvi.device_resolution = dw->dvi.default_resolution;
220         dw->dvi.display_resolution = dw->dvi.default_resolution;
221         dw->dvi.paperlength = dw->dvi.default_resolution*11;
222         dw->dvi.paperwidth = (dw->dvi.default_resolution*8
223                               + dw->dvi.default_resolution/2);
224         dw->dvi.scale_factor = 1.0;
225         dw->dvi.sizescale = 1;
226         dw->dvi.line_thickness = -1;
227         dw->dvi.line_width = 1;
228         dw->dvi.fill = DVI_FILL_MAX;
229         dw->dvi.device_font = 0;
230         dw->dvi.device_font_number = -1;
231         dw->dvi.device = 0;
232         dw->dvi.native = 0;
233
234         request = request;      /* unused; suppress compiler warning */
235         args = args;
236         num_args = num_args;
237 }
238
239 #include "gray1.bm"
240 #include "gray2.bm"
241 #include "gray3.bm"
242 #include "gray4.bm"
243 #include "gray5.bm"
244 #include "gray6.bm"
245 #include "gray7.bm"
246 #include "gray8.bm"
247
248 static void
249 Realize (Widget w, XtValueMask *valueMask, XSetWindowAttributes *attrs)
250 {
251         DviWidget       dw = (DviWidget) w;
252         XGCValues       values;
253
254         if (dw->dvi.backing_store != Always + WhenMapped + NotUseful) {
255                 attrs->backing_store = dw->dvi.backing_store;
256                 *valueMask |= CWBackingStore;
257         }
258         XtCreateWindow (w, (unsigned)InputOutput, (Visual *) CopyFromParent,
259                         *valueMask, attrs);
260         values.foreground = dw->dvi.foreground;
261         values.cap_style = CapRound;
262         values.join_style = JoinRound;
263         values.line_width = dw->dvi.line_width;
264         dw->dvi.normal_GC = XCreateGC (XtDisplay (w), XtWindow (w),
265                                        GCForeground|GCCapStyle|GCJoinStyle
266                                        |GCLineWidth,
267                                        &values);
268         dw->dvi.gray[0] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
269                                              gray1_bits,
270                                              gray1_width, gray1_height);
271         dw->dvi.gray[1] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
272                                              gray2_bits,
273                                              gray2_width, gray2_height);
274         dw->dvi.gray[2] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
275                                              gray3_bits,
276                                              gray3_width, gray3_height);
277         dw->dvi.gray[3] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
278                                              gray4_bits,
279                                              gray4_width, gray4_height);
280         dw->dvi.gray[4] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
281                                              gray5_bits,
282                                              gray5_width, gray5_height);
283         dw->dvi.gray[5] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
284                                              gray6_bits,
285                                              gray6_width, gray6_height);
286         dw->dvi.gray[6] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
287                                              gray7_bits,
288                                              gray7_width, gray7_height);
289         dw->dvi.gray[7] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
290                                              gray8_bits,
291                                              gray8_width, gray8_height);
292         values.background = dw->dvi.background;
293         values.stipple = dw->dvi.gray[5];
294         dw->dvi.fill_GC = XCreateGC (XtDisplay (w), XtWindow (w),
295                                      GCForeground|GCBackground|GCStipple,
296                                      &values);
297
298         dw->dvi.fill_type = 9;
299
300         if (dw->dvi.file)
301                 OpenFile (dw);
302         ParseFontMap (dw);
303 }
304
305 static void
306 Destroy(Widget w)
307 {
308         DviWidget       dw = (DviWidget) w;
309
310         XFreeGC (XtDisplay (w), dw->dvi.normal_GC);
311         XFreeGC (XtDisplay (w), dw->dvi.fill_GC);
312         XFreePixmap (XtDisplay (w), dw->dvi.gray[0]);
313         XFreePixmap (XtDisplay (w), dw->dvi.gray[1]);
314         XFreePixmap (XtDisplay (w), dw->dvi.gray[2]);
315         XFreePixmap (XtDisplay (w), dw->dvi.gray[3]);
316         XFreePixmap (XtDisplay (w), dw->dvi.gray[4]);
317         XFreePixmap (XtDisplay (w), dw->dvi.gray[5]);
318         XFreePixmap (XtDisplay (w), dw->dvi.gray[6]);
319         XFreePixmap (XtDisplay (w), dw->dvi.gray[7]);
320         DestroyFontMap (dw->dvi.font_map);
321         DestroyFileMap (dw->dvi.file_map);
322         device_destroy (dw->dvi.device);
323 }
324
325 /*
326  * Repaint the widget window
327  */
328
329 /* ARGSUSED */
330 static void
331 Redisplay(Widget w, XEvent *event, Region region)
332 {
333         DviWidget       dw = (DviWidget) w;
334         XRectangle      extents;
335         
336         XClipBox (region, &extents);
337         dw->dvi.extents.x1 = extents.x;
338         dw->dvi.extents.y1 = extents.y;
339         dw->dvi.extents.x2 = extents.x + extents.width;
340         dw->dvi.extents.y2 = extents.y + extents.height;
341         ShowDvi (dw);
342
343         event = event;          /* unused; suppress compiler warning */
344 }
345
346 /*
347  * Set specified arguments into widget
348  */
349 /* ARGSUSED */
350 static Boolean
351 SetValues (Widget wcurrent, Widget wrequest, Widget wnew,
352            ArgList args, Cardinal *num_args)
353 {
354         Boolean         redisplay = FALSE;
355         char            *new_map;
356         int             cur, req;
357         DviWidget       current = (DviWidget)wcurrent;
358         DviWidget       request = (DviWidget)wrequest;
359         DviWidget       new_wd = (DviWidget)wnew;
360
361         if (current->dvi.font_map_string != request->dvi.font_map_string) {
362                 new_map = XtMalloc (strlen (request->dvi.font_map_string) + 1);
363                 if (new_map) {
364                         redisplay = TRUE;
365                         strcpy (new_map, request->dvi.font_map_string);
366                         new_wd->dvi.font_map_string = new_map;
367                         if (current->dvi.font_map_string)
368                                 XtFree (current->dvi.font_map_string);
369                         current->dvi.font_map_string = 0;
370                         ParseFontMap (new_wd);
371                 }
372         }
373
374         req = request->dvi.requested_page;
375         cur = current->dvi.requested_page;
376         if (cur != req) {
377                 if (!request->dvi.file)
378                     req = 0;
379                 else {
380                     if (req < 1)
381                             req = 1;
382                     if (current->dvi.last_page != 0 &&
383                         req > current->dvi.last_page)
384                             req = current->dvi.last_page;
385                 }
386                 if (cur != req)
387                     redisplay = TRUE;
388                 new_wd->dvi.requested_page = req;
389                 if (current->dvi.last_page == 0 && req > cur)
390                         FindPage (new_wd);
391         }
392
393         args = args;            /* unused; suppress compiler warning */
394         num_args = num_args;
395
396         return redisplay;
397 }
398
399 /*
400  * use the set_values_hook entry to check when
401  * the file is set
402  */
403
404 static Boolean
405 SetValuesHook (Widget wdw, ArgList args, Cardinal *num_argsp)
406 {
407         Cardinal        i;
408         DviWidget       dw = (DviWidget)wdw;
409
410         for (i = 0; i < *num_argsp; i++) {
411                 if (!strcmp (args[i].name, XtNfile)) {
412                         CloseFile (dw);
413                         OpenFile (dw);
414                         return TRUE;
415                 }
416         }
417         return FALSE;
418 }
419
420 static void CloseFile (DviWidget dw)
421 {
422         if (dw->dvi.tmpFile)
423                 fclose (dw->dvi.tmpFile);
424         ForgetPagePositions (dw);
425 }
426
427 static void OpenFile (DviWidget dw)
428 {
429         dw->dvi.tmpFile = 0;
430         if (!dw->dvi.seek)
431                 dw->dvi.tmpFile = tmpfile();
432         dw->dvi.requested_page = 1;
433         dw->dvi.last_page = 0;
434 }
435
436 static XtGeometryResult
437 QueryGeometry (Widget w, XtWidgetGeometry *request,
438                XtWidgetGeometry *geometry_return)
439 {
440         XtGeometryResult        ret;
441         DviWidget               dw = (DviWidget) w;
442
443         ret = XtGeometryYes;
444         if (((request->request_mode & CWWidth)
445              && request->width < MY_WIDTH(dw))
446             || ((request->request_mode & CWHeight)
447                 && request->height < MY_HEIGHT(dw)))
448                 ret = XtGeometryAlmost;
449         geometry_return->width = MY_WIDTH(dw);
450         geometry_return->height = MY_HEIGHT(dw);
451         geometry_return->request_mode = CWWidth|CWHeight;
452         return ret;
453 }
454
455 void
456 SetDevice (DviWidget dw, const char *name)
457 {
458         XtWidgetGeometry        request, reply;
459         XtGeometryResult ret;
460
461         ForgetFonts (dw);
462         dw->dvi.device = device_load (name);
463         if (!dw->dvi.device)
464                 return;
465         dw->dvi.sizescale = dw->dvi.device->sizescale;
466         dw->dvi.device_resolution = dw->dvi.device->res;
467         dw->dvi.native = dw->dvi.device->X11;
468         dw->dvi.paperlength = dw->dvi.device->paperlength;
469         dw->dvi.paperwidth = dw->dvi.device->paperwidth;
470         if (dw->dvi.native) {
471                 dw->dvi.display_resolution = dw->dvi.device_resolution;
472                 dw->dvi.scale_factor = 1.0;
473         }
474         else {
475                 dw->dvi.display_resolution = dw->dvi.default_resolution;
476                 dw->dvi.scale_factor = ((double)dw->dvi.display_resolution
477                                         / dw->dvi.device_resolution);
478         }
479         request.request_mode = CWWidth|CWHeight;
480         request.width = MY_WIDTH(dw);
481         request.height = MY_HEIGHT(dw);
482         ret = XtMakeGeometryRequest ((Widget)dw, &request, &reply);
483         if (ret == XtGeometryAlmost
484             && reply.height >= request.height
485             && reply.width >= request.width) {
486                 request.width = reply.width;
487                 request.height = reply.height;
488                 XtMakeGeometryRequest ((Widget)dw, &request, &reply);
489         }
490 }
491
492 static void
493 ShowDvi (DviWidget dw)
494 {
495         if (!dw->dvi.file) {
496                 static char Error[] = "No file selected";
497
498                 XSetFont (XtDisplay(dw), dw->dvi.normal_GC,
499                           dw->dvi.default_font->fid);
500                 XDrawString (XtDisplay (dw), XtWindow (dw), dw->dvi.normal_GC,
501                              20, 20, Error, strlen (Error));
502                 return;
503         }
504
505         FindPage (dw);
506         
507         dw->dvi.display_enable = 1;
508         ParseInput (dw);
509         if (dw->dvi.last_page && dw->dvi.requested_page > dw->dvi.last_page)
510                 dw->dvi.requested_page = dw->dvi.last_page;
511 }
512
513 static void
514 FindPage (DviWidget dw)
515 {
516         int     i;
517         long    file_position;
518
519         if (dw->dvi.requested_page < 1)
520                 dw->dvi.requested_page = 1;
521
522         if (dw->dvi.last_page != 0 && dw->dvi.requested_page > dw->dvi.last_page)
523                 dw->dvi.requested_page = dw->dvi.last_page;
524
525         file_position = SearchPagePosition (dw, dw->dvi.requested_page);
526         if (file_position != -1) {
527                 FileSeek(dw, file_position);
528                 dw->dvi.current_page = dw->dvi.requested_page;
529         } else {
530                 for (i=dw->dvi.requested_page; i > 0; i--) {
531                         file_position = SearchPagePosition (dw, i);
532                         if (file_position != -1)
533                                 break;
534                 }
535                 if (file_position == -1)
536                         file_position = 0;
537                 FileSeek (dw, file_position);
538
539                 dw->dvi.current_page = i;
540                 
541                 dw->dvi.display_enable = 0;
542                 while (dw->dvi.current_page != dw->dvi.requested_page) {
543                         dw->dvi.current_page = ParseInput (dw);
544                         /*
545                          * at EOF, seek back to the beginning of this page.
546                          */
547                         if (!dw->dvi.readingTmp && feof (dw->dvi.file)) {
548                                 file_position = SearchPagePosition (dw,
549                                                 dw->dvi.current_page);
550                                 if (file_position != -1)
551                                         FileSeek (dw, file_position);
552                                 dw->dvi.requested_page = dw->dvi.current_page;
553                                 break;
554                         }
555                 }
556         }
557 }
558
559 void DviSaveToFile(Widget w, FILE *fp)
560 {
561         XtCheckSubclass(w, dviWidgetClass, NULL);
562         (*((DviWidgetClass) XtClass(w))->command_class.save)(w, fp);
563 }
564
565 static
566 void SaveToFile(Widget w, FILE *fp)
567 {
568         DviWidget dw = (DviWidget)w;
569         long pos;
570         int c;
571
572         if (dw->dvi.tmpFile) {
573                 pos = ftell(dw->dvi.tmpFile);
574                 if (dw->dvi.ungot) {
575                         pos--;
576                         dw->dvi.ungot = 0;
577                         /* The ungot character is in the tmpFile, so we don't
578                            want to read it from file. */
579                         (void)getc(dw->dvi.file);
580                 }
581         }
582         else
583                 pos = ftell(dw->dvi.file);
584         FileSeek(dw, 0L);
585         while (DviGetC(dw, &c) != EOF)
586                 if (putc(c, fp) == EOF) {
587                         /* XXX print error message */
588                         break;
589                 }
590         FileSeek(dw, pos);
591 }
592
593 static
594 void ClassPartInitialize(WidgetClass widget_class)
595 {
596         DviWidgetClass wc = (DviWidgetClass)widget_class;
597         DviWidgetClass super = (DviWidgetClass) wc->core_class.superclass;
598         if (wc->command_class.save == InheritSaveToFile)
599                 wc->command_class.save = super->command_class.save;
600 }
601         
602 /*
603 Local Variables:
604 c-indent-level: 8
605 c-continued-statement-offset: 8
606 c-brace-offset: -8
607 c-argdecl-indent: 8
608 c-label-offset: -8
609 c-tab-always-indent: nil
610 End:
611 */