Don't use .Xo/.Xc. Fix date format.
[netbsd-mini2440.git] / gnu / usr.bin / groff / libXdvi / Dvi.c
blob86042df72f00cf5a235dd72b821132d69fd902b9
1 #ifndef lint
2 static char Xrcsid[] = "$XConsortium: Dvi.c,v 1.9 89/12/10 16:12:25 rws Exp $";
3 #endif /* lint */
5 /*
6 * Dvi.c - Dvi display widget
8 */
10 #define XtStrlen(s) ((s) ? strlen(s) : 0)
12 /* The following are defined for the reader's convenience. Any
13 Xt..Field macro in this code just refers to some field in
14 one of the substructures of the WidgetRec. */
16 #include <X11/IntrinsicP.h>
17 #include <X11/StringDefs.h>
18 #include <X11/Xmu/Converters.h>
19 #include <stdio.h>
20 #include <ctype.h>
21 #include "DviP.h"
23 /****************************************************************
25 * Full class record constant
27 ****************************************************************/
29 /* Private Data */
31 static char default_font_map[] = "\
32 TR -*-times-medium-r-normal--*-100-*-*-*-*-iso8859-1\n\
33 TI -*-times-medium-i-normal--*-100-*-*-*-*-iso8859-1\n\
34 TB -*-times-bold-r-normal--*-100-*-*-*-*-iso8859-1\n\
35 TBI -*-times-bold-i-normal--*-100-*-*-*-*-iso8859-1\n\
36 CR -*-courier-medium-r-normal--*-100-*-*-*-*-iso8859-1\n\
37 CI -*-courier-medium-o-normal--*-100-*-*-*-*-iso8859-1\n\
38 CB -*-courier-bold-r-normal--*-100-*-*-*-*-iso8859-1\n\
39 CBI -*-courier-bold-o-normal--*-100-*-*-*-*-iso8859-1\n\
40 HR -*-helvetica-medium-r-normal--*-100-*-*-*-*-iso8859-1\n\
41 HI -*-helvetica-medium-o-normal--*-100-*-*-*-*-iso8859-1\n\
42 HB -*-helvetica-bold-r-normal--*-100-*-*-*-*-iso8859-1\n\
43 HBI -*-helvetica-bold-o-normal--*-100-*-*-*-*-iso8859-1\n\
44 NR -*-new century schoolbook-medium-r-normal--*-100-*-*-*-*-iso8859-1\n\
45 NI -*-new century schoolbook-medium-i-normal--*-100-*-*-*-*-iso8859-1\n\
46 NB -*-new century schoolbook-bold-r-normal--*-100-*-*-*-*-iso8859-1\n\
47 NBI -*-new century schoolbook-bold-i-normal--*-100-*-*-*-*-iso8859-1\n\
48 S -*-symbol-medium-r-normal--*-100-*-*-*-*-adobe-fontspecific\n\
51 #define offset(field) XtOffset(DviWidget, field)
53 # define MY_WIDTH(dw) (dw->dvi.device_resolution * 9)
54 # define MY_HEIGHT(dw) (dw->dvi.device_resolution * 11)
56 static XtResource resources[] = {
57 {XtNfontMap, XtCFontMap, XtRString, sizeof (char *),
58 offset(dvi.font_map_string), XtRString, default_font_map},
59 {XtNforeground, XtCForeground, XtRPixel, sizeof (unsigned long),
60 offset(dvi.foreground), XtRString, "black"},
61 {XtNbackground, XtCBackground, XtRPixel, sizeof (unsigned long),
62 offset(dvi.background), XtRString, "white"},
63 {XtNpageNumber, XtCPageNumber, XtRInt, sizeof (int),
64 offset(dvi.requested_page), XtRString, "1"},
65 {XtNlastPageNumber, XtCLastPageNumber, XtRInt, sizeof (int),
66 offset (dvi.last_page), XtRString, "0"},
67 {XtNfile, XtCFile, XtRFile, sizeof (FILE *),
68 offset (dvi.file), XtRFile, (char *) 0},
69 {XtNseek, XtCSeek, XtRBoolean, sizeof (Boolean),
70 offset(dvi.seek), XtRString, "false"},
71 {XtNfont, XtCFont, XtRFontStruct, sizeof (XFontStruct *),
72 offset(dvi.default_font), XtRString, "xtdefaultfont"},
73 {XtNbackingStore, XtCBackingStore, XtRBackingStore, sizeof (int),
74 offset(dvi.backing_store), XtRString, "default"},
75 {XtNnoPolyText, XtCNoPolyText, XtRBoolean, sizeof (Boolean),
76 offset(dvi.noPolyText), XtRString, "false"},
79 #undef offset
81 static void ClassInitialize ();
82 static void Initialize(), Realize (), Destroy (), Redisplay ();
83 static Boolean SetValues (), SetValuesHook ();
84 static XtGeometryResult QueryGeometry ();
85 static void ShowDvi ();
86 static void CloseFile (), OpenFile ();
87 static void FindPage ();
89 DviClassRec dviClassRec = {
91 &widgetClassRec, /* superclass */
92 "Dvi", /* class_name */
93 sizeof(DviRec), /* size */
94 ClassInitialize, /* class_initialize */
95 NULL, /* class_part_initialize */
96 FALSE, /* class_inited */
97 Initialize, /* initialize */
98 NULL, /* initialize_hook */
99 Realize, /* realize */
100 NULL, /* actions */
101 0, /* num_actions */
102 resources, /* resources */
103 XtNumber(resources), /* resource_count */
104 NULLQUARK, /* xrm_class */
105 FALSE, /* compress_motion */
106 TRUE, /* compress_exposure */
107 TRUE, /* compress_enterleave */
108 FALSE, /* visible_interest */
109 Destroy, /* destroy */
110 NULL, /* resize */
111 Redisplay, /* expose */
112 SetValues, /* set_values */
113 SetValuesHook, /* set_values_hook */
114 NULL, /* set_values_almost */
115 NULL, /* get_values_hook */
116 NULL, /* accept_focus */
117 XtVersion, /* version */
118 NULL, /* callback_private */
119 0, /* tm_table */
120 QueryGeometry, /* query_geometry */
121 NULL, /* display_accelerator */
122 NULL /* extension */
124 0, /* field not used */
128 WidgetClass dviWidgetClass = (WidgetClass) &dviClassRec;
130 static void ClassInitialize ()
132 XtAddConverter( XtRString, XtRBackingStore, XmuCvtStringToBackingStore,
133 NULL, 0 );
136 /****************************************************************
138 * Private Procedures
140 ****************************************************************/
142 /* ARGSUSED */
143 static void Initialize(request, new)
144 Widget request, new;
146 DviWidget dw = (DviWidget) new;
148 dw->dvi.current_page = 0;
149 dw->dvi.font_map = 0;
150 dw->dvi.cache.index = 0;
151 dw->dvi.file = 0;
152 dw->dvi.seek = False;
153 dw->dvi.device_resolution = 75;
154 dw->dvi.line_thickness = -1;
155 dw->dvi.line_width = 1;
156 dw->dvi.fill = DVI_FILL_MAX;
159 #include <X11/bitmaps/gray>
161 static void
162 Realize (w, valueMask, attrs)
163 Widget w;
164 XtValueMask *valueMask;
165 XSetWindowAttributes *attrs;
167 DviWidget dw = (DviWidget) w;
168 XGCValues values;
170 if (dw->dvi.backing_store != Always + WhenMapped + NotUseful) {
171 attrs->backing_store = dw->dvi.backing_store;
172 *valueMask |= CWBackingStore;
174 XtCreateWindow (w, (unsigned)InputOutput, (Visual *) CopyFromParent,
175 *valueMask, attrs);
176 values.foreground = dw->dvi.foreground;
177 values.cap_style = CapRound;
178 values.join_style = JoinRound;
179 values.line_width = dw->dvi.line_width;
180 dw->dvi.normal_GC = XCreateGC (XtDisplay (w), XtWindow (w),
181 GCForeground|GCCapStyle|GCJoinStyle
182 |GCLineWidth,
183 &values);
184 dw->dvi.gray = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
185 gray_bits,
186 gray_width, gray_height);
187 values.background = dw->dvi.background;
188 values.stipple = dw->dvi.gray;
189 dw->dvi.fill_GC = XCreateGC (XtDisplay (w), XtWindow (w),
190 GCForeground|GCBackground|GCStipple,
191 &values);
193 dw->dvi.fill_type = DVI_FILL_BLACK;
195 if (dw->dvi.file)
196 OpenFile (dw);
197 ParseFontMap (dw);
200 static void
201 Destroy(w)
202 Widget w;
204 DviWidget dw = (DviWidget) w;
206 XFreeGC (XtDisplay (w), dw->dvi.normal_GC);
207 XFreeGC (XtDisplay (w), dw->dvi.fill_GC);
208 XFreePixmap (XtDisplay (w), dw->dvi.gray);
209 DestroyFontMap (dw->dvi.font_map);
210 DestroyFileMap (dw->dvi.file_map);
214 * Repaint the widget window
217 /* ARGSUSED */
218 static void
219 Redisplay(w, event, region)
220 Widget w;
221 XEvent *event;
222 Region region;
224 DviWidget dw = (DviWidget) w;
225 XRectangle extents;
227 XClipBox (region, &extents);
228 dw->dvi.extents.x1 = extents.x;
229 dw->dvi.extents.y1 = extents.y;
230 dw->dvi.extents.x2 = extents.x + extents.width;
231 dw->dvi.extents.y2 = extents.y + extents.height;
232 ShowDvi (dw);
236 * Set specified arguments into widget
238 /* ARGSUSED */
239 static Boolean
240 SetValues (current, request, new)
241 DviWidget current, request, new;
243 Boolean redisplay = FALSE;
244 extern char *malloc ();
245 char *new_map;
246 int cur, req;
248 if (current->dvi.font_map_string != request->dvi.font_map_string) {
249 new_map = malloc (strlen (request->dvi.font_map_string) + 1);
250 if (new_map) {
251 redisplay = TRUE;
252 strcpy (new_map, request->dvi.font_map_string);
253 new->dvi.font_map_string = new_map;
254 if (current->dvi.font_map_string)
255 free (current->dvi.font_map_string);
256 current->dvi.font_map_string = 0;
257 ParseFontMap (new);
261 req = request->dvi.requested_page;
262 cur = current->dvi.requested_page;
263 if (cur != req) {
264 if (!request->dvi.file)
265 req = 0;
266 else {
267 if (req < 1)
268 req = 1;
269 if (current->dvi.last_page != 0 &&
270 req > current->dvi.last_page)
271 req = current->dvi.last_page;
273 if (cur != req)
274 redisplay = TRUE;
275 new->dvi.requested_page = req;
276 if (current->dvi.last_page == 0 && req > cur)
277 FindPage (new);
280 return redisplay;
284 * use the set_values_hook entry to check when
285 * the file is set
288 static Boolean
289 SetValuesHook (dw, args, num_argsp)
290 DviWidget dw;
291 ArgList args;
292 Cardinal *num_argsp;
294 Cardinal i;
296 for (i = 0; i < *num_argsp; i++) {
297 if (!strcmp (args[i].name, XtNfile)) {
298 CloseFile (dw);
299 OpenFile (dw);
300 return TRUE;
303 return FALSE;
306 static void CloseFile (dw)
307 DviWidget dw;
309 if (dw->dvi.tmpFile)
310 fclose (dw->dvi.tmpFile);
311 ForgetPagePositions (dw);
314 static void OpenFile (dw)
315 DviWidget dw;
317 char tmpName[sizeof ("/tmp/dviXXXXXX")];
319 dw->dvi.tmpFile = 0;
320 if (!dw->dvi.seek) {
321 strcpy (tmpName, "/tmp/dviXXXXXX");
322 mktemp (tmpName);
323 dw->dvi.tmpFile = fopen (tmpName, "w+");
324 unlink (tmpName);
326 dw->dvi.requested_page = 1;
327 dw->dvi.last_page = 0;
330 static XtGeometryResult
331 QueryGeometry (w, request, geometry_return)
332 Widget w;
333 XtWidgetGeometry *request, *geometry_return;
335 XtGeometryResult ret;
336 DviWidget dw = (DviWidget) w;
338 ret = XtGeometryYes;
339 if (request->width < MY_WIDTH(dw) || request->height < MY_HEIGHT(dw))
340 ret = XtGeometryAlmost;
341 geometry_return->width = MY_WIDTH(dw);
342 geometry_return->height = MY_HEIGHT(dw);
343 geometry_return->request_mode = CWWidth|CWHeight;
344 return ret;
347 SetDeviceResolution (dw, resolution)
348 DviWidget dw;
349 int resolution;
351 XtWidgetGeometry request, reply;
353 if (resolution != dw->dvi.device_resolution) {
354 dw->dvi.device_resolution = resolution;
355 request.request_mode = CWWidth|CWHeight;
356 request.width = MY_WIDTH(dw);
357 request.height = MY_HEIGHT(dw);
358 XtMakeGeometryRequest (dw, &request, &reply);
362 static void
363 ShowDvi (dw)
364 DviWidget dw;
366 if (!dw->dvi.file) {
367 static char Error[] = "No file selected";
369 XSetFont (XtDisplay(dw), dw->dvi.normal_GC,
370 dw->dvi.default_font->fid);
371 XDrawString (XtDisplay (dw), XtWindow (dw), dw->dvi.normal_GC,
372 20, 20, Error, strlen (Error));
373 return;
376 FindPage (dw);
378 dw->dvi.display_enable = 1;
379 ParseInput (dw);
380 if (dw->dvi.last_page && dw->dvi.requested_page > dw->dvi.last_page)
381 dw->dvi.requested_page = dw->dvi.last_page;
384 static void
385 FindPage (dw)
386 DviWidget dw;
388 int i;
389 long file_position;
391 if (dw->dvi.requested_page < 1)
392 dw->dvi.requested_page = 1;
394 if (dw->dvi.last_page != 0 && dw->dvi.requested_page > dw->dvi.last_page)
395 dw->dvi.requested_page = dw->dvi.last_page;
397 file_position = SearchPagePosition (dw, dw->dvi.requested_page);
398 if (file_position != -1) {
399 FileSeek(dw, file_position);
400 dw->dvi.current_page = dw->dvi.requested_page;
401 } else {
402 for (i=dw->dvi.requested_page; i > 0; i--) {
403 file_position = SearchPagePosition (dw, i);
404 if (file_position != -1)
405 break;
407 if (file_position == -1)
408 file_position = 0;
409 FileSeek (dw, file_position);
411 dw->dvi.current_page = i;
413 dw->dvi.display_enable = 0;
414 while (dw->dvi.current_page != dw->dvi.requested_page) {
415 dw->dvi.current_page = ParseInput (dw);
417 * at EOF, seek back to the begining of this page.
419 if (feof (dw->dvi.file)) {
420 file_position = SearchPagePosition (dw,
421 dw->dvi.current_page);
422 if (file_position != -1)
423 FileSeek (dw, file_position);
424 dw->dvi.requested_page = dw->dvi.current_page;
425 break;
432 Local Variables:
433 c-indent-level: 8
434 c-continued-statement-offset: 8
435 c-brace-offset: -8
436 c-argdecl-indent: 8
437 c-label-offset: -8
438 c-tab-always-indent: nil
439 End: