* FDL: Updated to version 1.2 (from www.gnu.org/copyleft).
[s-roff.git] / src / xditview / xditview.c
blobeac2edd880781491e16f9e51b0cf9193847962ef
1 /*
2 * Copyright 1991 Massachusetts Institute of Technology
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of M.I.T. not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission. M.I.T. makes no representations about the
11 * suitability of this software for any purpose. It is provided "as is"
12 * without express or implied warranty.
14 * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
16 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
18 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
19 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 * xditview --
25 * Display ditroff output in an X window
28 #ifndef SABER
29 #ifndef lint
30 static char rcsid[] = "$XConsortium: xditview.c,v 1.17 89/12/10 17:05:08 rws Exp $";
31 #endif /* lint */
32 #endif /* SABER */
34 #include <X11/Xatom.h>
35 #include <X11/Xlib.h>
36 #include <X11/Xos.h>
37 #include <X11/Intrinsic.h>
38 #include <X11/StringDefs.h>
39 #include <X11/Shell.h>
40 #include <X11/Xaw/Paned.h>
41 #include <X11/Xaw/Viewport.h>
42 #include <X11/Xaw/Box.h>
43 #include <X11/Xaw/Command.h>
44 #include <X11/Xaw/Dialog.h>
45 #include <X11/Xaw/Label.h>
46 #include <X11/Xaw/SimpleMenu.h>
47 #include <X11/Xaw/SmeBSB.h>
49 #include <stdlib.h>
50 #include <signal.h>
52 #include "Dvi.h"
54 #include "xdit.bm"
55 #include "xdit_mask.bm"
56 #include "stdio.h"
58 extern FILE *popen();
59 extern void exit();
61 static String fallback_resources[] = {
62 #include "GXditview-ad.h"
63 NULL
66 static struct app_resources {
67 char *print_command;
68 char *filename;
69 } app_resources;
71 #define offset(field) XtOffset(struct app_resources *, field)
73 /* Application resources. */
75 static XtResource resources[] = {
76 {"printCommand", "PrintCommand", XtRString, sizeof(char*),
77 offset(print_command), XtRString, NULL},
78 {"filename", "Filename", XtRString, sizeof(char*),
79 offset(filename), XtRString, NULL},
82 #undef offset
84 /* Command line options table. Only resources are entered here...there is a
85 pass over the remaining options after XtParseCommand is let loose. */
87 static XrmOptionDescRec options[] = {
88 {"-page", "*dvi.pageNumber", XrmoptionSepArg, NULL},
89 {"-backingStore", "*dvi.backingStore", XrmoptionSepArg, NULL},
90 {"-resolution", "*dvi.resolution", XrmoptionSepArg, NULL},
91 {"-printCommand", ".printCommand", XrmoptionSepArg, NULL},
92 {"-filename", ".filename", XrmoptionSepArg, NULL},
93 {"-noPolyText", "*dvi.noPolyText", XrmoptionNoArg, "TRUE"},
96 static char current_print_command[1024];
98 static char current_file_name[1024];
99 static FILE *current_file;
102 * Report the syntax for calling xditview.
105 static void
106 Syntax(call)
107 char *call;
109 (void) printf ("Usage: %s [-fg <color>] [-bg <color>]\n", call);
110 (void) printf (" [-bd <color>] [-bw <pixels>] [-help]\n");
111 (void) printf (" [-display displayname] [-geometry geom]\n");
112 (void) printf (" [-page <page-number>] [-backing <backing-store>]\n");
113 (void) printf (" [-resolution <res>] [-print <command>]\n");
114 (void) printf (" [-filename <file>] [filename]\n\n");
115 exit(1);
118 static void NewFile (), SetPageNumber ();
119 static Widget toplevel, paned, viewport, dvi;
120 static Widget page;
121 static Widget simpleMenu;
123 static void NextPage(), PreviousPage(), SelectPage(), OpenFile(), Quit();
124 static void Print();
126 static struct menuEntry {
127 char *name;
128 void (*function)();
129 } menuEntries[] = {
130 {"nextPage", NextPage},
131 {"previousPage", PreviousPage},
132 {"selectPage", SelectPage},
133 {"print", Print},
134 {"openFile", OpenFile},
135 {"quit", Quit},
138 static void NextPageAction(), PreviousPageAction(), SelectPageAction();
139 static void OpenFileAction(), QuitAction();
140 static void AcceptAction(), CancelAction();
141 static void PrintAction();
142 static void RerasterizeAction();
143 static void MakePrompt();
145 XtActionsRec xditview_actions[] = {
146 {"NextPage", NextPageAction},
147 {"PreviousPage", PreviousPageAction},
148 {"SelectPage", SelectPageAction},
149 {"Print", PrintAction},
150 {"OpenFile", OpenFileAction},
151 {"Rerasterize", RerasterizeAction},
152 {"Quit", QuitAction},
153 {"Accept", AcceptAction},
154 {"Cancel", CancelAction},
157 #define MenuNextPage 0
158 #define MenuPreviousPage 1
159 #define MenuSelectPage 2
160 #define MenuPrint 3
161 #define MenuOpenFile 4
162 #define MenuQuit 5
164 static char pageLabel[256] = "Page <none>";
166 int main(argc, argv)
167 int argc;
168 char **argv;
170 char *file_name = 0;
171 int i;
172 static Arg labelArgs[] = {
173 {XtNlabel, (XtArgVal) pageLabel},
175 XtAppContext xtcontext;
176 Arg topLevelArgs[2];
177 Widget entry;
178 Arg pageNumberArgs[1];
179 int page_number;
181 toplevel = XtAppInitialize(&xtcontext, "GXditview",
182 options, XtNumber (options),
183 &argc, argv, fallback_resources, NULL, 0);
184 if (argc > 2
185 || (argc == 2 && (!strcmp(argv[1], "-help")
186 || !strcmp(argv[1], "--help"))))
187 Syntax(argv[0]);
189 XtGetApplicationResources(toplevel, (XtPointer)&app_resources,
190 resources, XtNumber(resources),
191 NULL, (Cardinal) 0);
192 if (app_resources.print_command)
193 strcpy(current_print_command, app_resources.print_command);
195 XtAppAddActions(xtcontext, xditview_actions, XtNumber (xditview_actions));
197 XtSetArg (topLevelArgs[0], XtNiconPixmap,
198 XCreateBitmapFromData (XtDisplay (toplevel),
199 XtScreen(toplevel)->root,
200 xdit_bits, xdit_width, xdit_height));
202 XtSetArg (topLevelArgs[1], XtNiconMask,
203 XCreateBitmapFromData (XtDisplay (toplevel),
204 XtScreen(toplevel)->root,
205 xdit_mask_bits,
206 xdit_mask_width, xdit_mask_height));
207 XtSetValues (toplevel, topLevelArgs, 2);
208 if (argc > 1)
209 file_name = argv[1];
212 * create the menu and insert the entries
214 simpleMenu = XtCreatePopupShell ("menu", simpleMenuWidgetClass, toplevel,
215 NULL, 0);
216 for (i = 0; i < XtNumber (menuEntries); i++) {
217 entry = XtCreateManagedWidget(menuEntries[i].name,
218 smeBSBObjectClass, simpleMenu,
219 NULL, (Cardinal) 0);
220 XtAddCallback(entry, XtNcallback, menuEntries[i].function, NULL);
223 paned = XtCreateManagedWidget("paned", panedWidgetClass, toplevel,
224 NULL, (Cardinal) 0);
225 viewport = XtCreateManagedWidget("viewport", viewportWidgetClass, paned,
226 NULL, (Cardinal) 0);
227 dvi = XtCreateManagedWidget ("dvi", dviWidgetClass, viewport, NULL, 0);
228 page = XtCreateManagedWidget ("label", labelWidgetClass, paned,
229 labelArgs, XtNumber (labelArgs));
230 XtSetArg (pageNumberArgs[0], XtNpageNumber, &page_number);
231 XtGetValues (dvi, pageNumberArgs, 1);
232 if (file_name)
233 NewFile (file_name);
234 /* NewFile modifies current_file_name, so do this here. */
235 if (app_resources.filename)
236 strcpy(current_file_name, app_resources.filename);
237 XtRealizeWidget (toplevel);
238 if (file_name)
239 SetPageNumber (page_number);
240 XtAppMainLoop(xtcontext);
241 return 0;
244 static void
245 SetPageNumber (number)
247 Arg arg[2];
248 int actual_number, last_page;
250 XtSetArg (arg[0], XtNpageNumber, number);
251 XtSetValues (dvi, arg, 1);
252 XtSetArg (arg[0], XtNpageNumber, &actual_number);
253 XtSetArg (arg[1], XtNlastPageNumber, &last_page);
254 XtGetValues (dvi, arg, 2);
255 if (actual_number == 0)
256 sprintf (pageLabel, "Page <none>");
257 else if (last_page > 0)
258 sprintf (pageLabel, "Page %d of %d", actual_number, last_page);
259 else
260 sprintf (pageLabel, "Page %d", actual_number);
261 XtSetArg (arg[0], XtNlabel, pageLabel);
262 XtSetValues (page, arg, 1);
265 static void
266 SelectPageNumber (number_string)
267 char *number_string;
269 SetPageNumber (atoi(number_string));
272 static int hadFile = 0;
274 static void
275 NewFile (name)
276 char *name;
278 Arg arg[2];
279 char *n;
280 FILE *new_file;
281 Boolean seek = 0;
283 if (current_file) {
284 if (!strcmp (current_file_name, "-"))
286 else if (current_file_name[0] == '|')
287 pclose (current_file);
288 else
289 fclose (current_file);
291 if (!strcmp (name, "-"))
292 new_file = stdin;
293 else if (name[0] == '|')
294 new_file = popen (name+1, "r");
295 else {
296 new_file = fopen (name, "r");
297 seek = 1;
299 if (!new_file) {
300 /* XXX display error message */
301 return;
303 XtSetArg (arg[0], XtNfile, new_file);
304 XtSetArg (arg[1], XtNseek, seek);
305 XtSetValues (dvi, arg, 2);
306 if (hadFile || name[0] != '-' || name[1] != '\0') {
307 XtSetArg (arg[0], XtNtitle, name);
308 if (name[0] != '/' && (n = strrchr (name, '/')))
309 n = n + 1;
310 else
311 n = name;
312 XtSetArg (arg[1], XtNiconName, n);
313 XtSetValues (toplevel, arg, 2);
315 hadFile = 1;
316 SelectPageNumber ("1");
317 strcpy (current_file_name, name);
318 current_file = new_file;
321 static char fileBuf[1024];
323 static void
324 ResetMenuEntry (entry)
325 Widget entry;
327 Arg arg[1];
329 XtSetArg (arg[0], XtNpopupOnEntry, entry);
330 XtSetValues (XtParent(entry) , arg, (Cardinal) 1);
333 /*ARGSUSED*/
335 static void
336 NextPage (entry, name, data)
337 Widget entry;
338 caddr_t name, data;
340 NextPageAction();
341 ResetMenuEntry (entry);
344 static void
345 NextPageAction ()
347 Arg args[1];
348 int number;
350 XtSetArg (args[0], XtNpageNumber, &number);
351 XtGetValues (dvi, args, 1);
352 SetPageNumber (number+1);
355 /*ARGSUSED*/
357 static void
358 PreviousPage (entry, name, data)
359 Widget entry;
360 caddr_t name, data;
362 PreviousPageAction ();
363 ResetMenuEntry (entry);
366 static void
367 PreviousPageAction ()
369 Arg args[1];
370 int number;
372 XtSetArg (args[0], XtNpageNumber, &number);
373 XtGetValues (dvi, args, 1);
374 SetPageNumber (number-1);
377 /* ARGSUSED */
379 static void
380 SelectPage (entry, name, data)
381 Widget entry;
382 caddr_t name, data;
384 SelectPageAction ();
385 ResetMenuEntry (entry);
388 static void
389 SelectPageAction ()
391 MakePrompt (toplevel, "Page number", SelectPageNumber, "");
395 static void
396 DoPrint (name)
397 char *name;
399 FILE *print_file;
400 #ifdef SIGNALRETURNSINT
401 int (*handler)();
402 #else
403 void (*handler)();
404 #endif
405 /* Avoid dieing because of an invalid command. */
406 handler = signal(SIGPIPE, SIG_IGN);
408 print_file = popen(name, "w");
409 if (!print_file)
410 /* XXX print error message */
411 return;
412 DviSaveToFile(dvi, print_file);
413 pclose(print_file);
414 signal(SIGPIPE, handler);
415 strcpy(current_print_command, name);
418 static void
419 RerasterizeAction()
421 Arg args[1];
422 int number;
424 if (current_file_name[0] == 0) {
425 /* XXX display an error message */
426 return;
428 XtSetArg (args[0], XtNpageNumber, &number);
429 XtGetValues (dvi, args, 1);
430 NewFile(current_file_name);
431 SetPageNumber (number);
434 /* ARGSUSED */
436 static void
437 Print (entry, name, data)
438 Widget entry;
439 caddr_t name, data;
441 PrintAction ();
442 ResetMenuEntry (entry);
445 static void
446 PrintAction ()
448 if (current_print_command[0])
449 strcpy (fileBuf, current_print_command);
450 else
451 fileBuf[0] = '\0';
452 MakePrompt (toplevel, "Print command:", DoPrint, fileBuf);
456 /* ARGSUSED */
458 static void
459 OpenFile (entry, name, data)
460 Widget entry;
461 caddr_t name, data;
463 OpenFileAction ();
464 ResetMenuEntry (entry);
467 static void
468 OpenFileAction ()
470 if (current_file_name[0])
471 strcpy (fileBuf, current_file_name);
472 else
473 fileBuf[0] = '\0';
474 MakePrompt (toplevel, "File to open:", NewFile, fileBuf);
477 /* ARGSUSED */
479 static void
480 Quit (entry, closure, data)
481 Widget entry;
482 caddr_t closure, data;
484 QuitAction ();
487 static void
488 QuitAction ()
490 exit (0);
493 Widget promptShell, promptDialog;
494 void (*promptfunction)();
496 /* ARGSUSED */
497 static
498 void CancelAction (widget, event, params, num_params)
499 Widget widget;
500 XEvent *event;
501 String *params;
502 Cardinal *num_params;
504 if (promptShell) {
505 XtSetKeyboardFocus(toplevel, (Widget) None);
506 XtDestroyWidget(promptShell);
507 promptShell = (Widget) 0;
511 static
512 void AcceptAction (widget, event, params, num_params)
513 Widget widget;
514 XEvent *event;
515 String *params;
516 Cardinal *num_params;
518 (*promptfunction)(XawDialogGetValueString(promptDialog));
519 CancelAction (widget, event, params, num_params);
522 static void
523 MakePrompt(centerw, prompt, func, def)
524 Widget centerw;
525 char *prompt;
526 void (*func)();
527 char *def;
529 static Arg dialogArgs[] = {
530 {XtNlabel, 0},
531 {XtNvalue, 0},
533 Arg valueArgs[1];
534 Arg centerArgs[2];
535 Position source_x, source_y;
536 Position dest_x, dest_y;
537 Dimension center_width, center_height;
538 Dimension prompt_width, prompt_height;
539 Widget valueWidget;
541 CancelAction ((Widget)NULL, (XEvent *) 0, (String *) 0, (Cardinal *) 0);
542 promptShell = XtCreatePopupShell ("promptShell", transientShellWidgetClass,
543 toplevel, NULL, (Cardinal) 0);
544 dialogArgs[0].value = (XtArgVal)prompt;
545 dialogArgs[1].value = (XtArgVal)def;
546 promptDialog = XtCreateManagedWidget( "promptDialog", dialogWidgetClass,
547 promptShell, dialogArgs, XtNumber (dialogArgs));
548 XawDialogAddButton(promptDialog, "accept", NULL, (caddr_t) 0);
549 XawDialogAddButton(promptDialog, "cancel", NULL, (caddr_t) 0);
550 valueWidget = XtNameToWidget (promptDialog, "value");
551 if (valueWidget) {
552 XtSetArg (valueArgs[0], XtNresizable, TRUE);
553 XtSetValues (valueWidget, valueArgs, 1);
555 * as resizable isn't set until just above, the
556 * default value will be displayed incorrectly.
557 * rectify the situation by resetting the values
559 XtSetValues (promptDialog, dialogArgs, XtNumber (dialogArgs));
561 XtSetKeyboardFocus (promptDialog, valueWidget);
562 XtSetKeyboardFocus (toplevel, valueWidget);
563 XtRealizeWidget (promptShell);
565 * place the widget in the center of the "parent"
567 XtSetArg (centerArgs[0], XtNwidth, &center_width);
568 XtSetArg (centerArgs[1], XtNheight, &center_height);
569 XtGetValues (centerw, centerArgs, 2);
570 XtSetArg (centerArgs[0], XtNwidth, &prompt_width);
571 XtSetArg (centerArgs[1], XtNheight, &prompt_height);
572 XtGetValues (promptShell, centerArgs, 2);
573 source_x = (center_width - prompt_width) / 2;
574 source_y = (center_height - prompt_height) / 3;
575 XtTranslateCoords (centerw, source_x, source_y, &dest_x, &dest_y);
576 XtSetArg (centerArgs[0], XtNx, dest_x);
577 XtSetArg (centerArgs[1], XtNy, dest_y);
578 XtSetValues (promptShell, centerArgs, 2);
579 XtMapWidget(promptShell);
580 promptfunction = func;
583 /* For DviChar.c */
585 char *xmalloc(n)
586 int n;
588 return XtMalloc(n);
592 Local Variables:
593 c-indent-level: 4
594 c-continued-statement-offset: 4
595 c-brace-offset: -4
596 c-argdecl-indent: 4
597 c-label-offset: -4
598 c-tab-always-indent: nil
599 End: