* gxditview.c (main): Handle `-help' and `--help' correctly.
[s-roff.git] / src / xditview / xditview.c
blob75b7fd1497e1e5a43dc32c3ecbcb8ec38c96ee62
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 <signal.h>
51 #include "Dvi.h"
53 #include "xdit.bm"
54 #include "xdit_mask.bm"
55 #include "stdio.h"
57 extern FILE *popen();
58 extern void exit();
60 static String fallback_resources[] = {
61 #include "GXditview-ad.h"
62 NULL
65 static struct app_resources {
66 char *print_command;
67 char *filename;
68 } app_resources;
70 #define offset(field) XtOffset(struct app_resources *, field)
72 /* Application resources. */
74 static XtResource resources[] = {
75 {"printCommand", "PrintCommand", XtRString, sizeof(char*),
76 offset(print_command), XtRString, NULL},
77 {"filename", "Filename", XtRString, sizeof(char*),
78 offset(filename), XtRString, NULL},
81 #undef offset
83 /* Command line options table. Only resources are entered here...there is a
84 pass over the remaining options after XtParseCommand is let loose. */
86 static XrmOptionDescRec options[] = {
87 {"-page", "*dvi.pageNumber", XrmoptionSepArg, NULL},
88 {"-backingStore", "*dvi.backingStore", XrmoptionSepArg, NULL},
89 {"-resolution", "*dvi.resolution", XrmoptionSepArg, NULL},
90 {"-printCommand", ".printCommand", XrmoptionSepArg, NULL},
91 {"-filename", ".filename", XrmoptionSepArg, NULL},
92 {"-noPolyText", "*dvi.noPolyText", XrmoptionNoArg, "TRUE"},
95 static char current_print_command[1024];
97 static char current_file_name[1024];
98 static FILE *current_file;
101 * Report the syntax for calling xditview.
104 static
105 Syntax(call)
106 char *call;
108 (void) printf ("Usage: %s [-fg <color>] [-bg <color>]\n", call);
109 (void) printf (" [-bd <color>] [-bw <pixels>] [-help]\n");
110 (void) printf (" [-display displayname] [-geometry geom]\n");
111 (void) printf (" [-page <page-number>] [-backing <backing-store>]\n");
112 (void) printf (" [-resolution <res>] [-print <command>]\n");
113 (void) printf (" [-filename <file>] [filename]\n\n");
114 exit(1);
117 static void NewFile (), SetPageNumber ();
118 static Widget toplevel, paned, viewport, dvi;
119 static Widget page;
120 static Widget simpleMenu;
122 static void NextPage(), PreviousPage(), SelectPage(), OpenFile(), Quit();
123 static void Print();
125 static struct menuEntry {
126 char *name;
127 void (*function)();
128 } menuEntries[] = {
129 "nextPage", NextPage,
130 "previousPage", PreviousPage,
131 "selectPage", SelectPage,
132 "print", Print,
133 "openFile", OpenFile,
134 "quit", Quit,
137 static void NextPageAction(), PreviousPageAction(), SelectPageAction();
138 static void OpenFileAction(), QuitAction();
139 static void AcceptAction(), CancelAction();
140 static void PrintAction();
141 static void RerasterizeAction();
143 XtActionsRec xditview_actions[] = {
144 "NextPage", NextPageAction,
145 "PreviousPage", PreviousPageAction,
146 "SelectPage", SelectPageAction,
147 "Print", PrintAction,
148 "OpenFile", OpenFileAction,
149 "Rerasterize", RerasterizeAction,
150 "Quit", QuitAction,
151 "Accept", AcceptAction,
152 "Cancel", CancelAction,
155 #define MenuNextPage 0
156 #define MenuPreviousPage 1
157 #define MenuSelectPage 2
158 #define MenuPrint 3
159 #define MenuOpenFile 4
160 #define MenuQuit 5
162 static char pageLabel[256] = "Page <none>";
164 int main(argc, argv)
165 int argc;
166 char **argv;
168 char *file_name = 0;
169 int i;
170 static Arg labelArgs[] = {
171 {XtNlabel, (XtArgVal) pageLabel},
173 XtAppContext xtcontext;
174 Arg topLevelArgs[2];
175 Widget entry;
176 Arg pageNumberArgs[1];
177 int page_number;
179 toplevel = XtAppInitialize(&xtcontext, "GXditview",
180 options, XtNumber (options),
181 &argc, argv, fallback_resources, NULL, 0);
182 if (argc > 2
183 || (argc == 2 && (!strcmp(argv[1], "-help")
184 || !strcmp(argv[1], "--help"))))
185 Syntax(argv[0]);
187 XtGetApplicationResources(toplevel, (XtPointer)&app_resources,
188 resources, XtNumber(resources),
189 NULL, (Cardinal) 0);
190 if (app_resources.print_command)
191 strcpy(current_print_command, app_resources.print_command);
193 XtAppAddActions(xtcontext, xditview_actions, XtNumber (xditview_actions));
195 XtSetArg (topLevelArgs[0], XtNiconPixmap,
196 XCreateBitmapFromData (XtDisplay (toplevel),
197 XtScreen(toplevel)->root,
198 xdit_bits, xdit_width, xdit_height));
200 XtSetArg (topLevelArgs[1], XtNiconMask,
201 XCreateBitmapFromData (XtDisplay (toplevel),
202 XtScreen(toplevel)->root,
203 xdit_mask_bits,
204 xdit_mask_width, xdit_mask_height));
205 XtSetValues (toplevel, topLevelArgs, 2);
206 if (argc > 1)
207 file_name = argv[1];
210 * create the menu and insert the entries
212 simpleMenu = XtCreatePopupShell ("menu", simpleMenuWidgetClass, toplevel,
213 NULL, 0);
214 for (i = 0; i < XtNumber (menuEntries); i++) {
215 entry = XtCreateManagedWidget(menuEntries[i].name,
216 smeBSBObjectClass, simpleMenu,
217 NULL, (Cardinal) 0);
218 XtAddCallback(entry, XtNcallback, menuEntries[i].function, NULL);
221 paned = XtCreateManagedWidget("paned", panedWidgetClass, toplevel,
222 NULL, (Cardinal) 0);
223 viewport = XtCreateManagedWidget("viewport", viewportWidgetClass, paned,
224 NULL, (Cardinal) 0);
225 dvi = XtCreateManagedWidget ("dvi", dviWidgetClass, viewport, NULL, 0);
226 page = XtCreateManagedWidget ("label", labelWidgetClass, paned,
227 labelArgs, XtNumber (labelArgs));
228 XtSetArg (pageNumberArgs[0], XtNpageNumber, &page_number);
229 XtGetValues (dvi, pageNumberArgs, 1);
230 if (file_name)
231 NewFile (file_name);
232 /* NewFile modifies current_file_name, so do this here. */
233 if (app_resources.filename)
234 strcpy(current_file_name, app_resources.filename);
235 XtRealizeWidget (toplevel);
236 if (file_name)
237 SetPageNumber (page_number);
238 XtAppMainLoop(xtcontext);
239 return 0;
242 static void
243 SetPageNumber (number)
245 Arg arg[2];
246 int actual_number, last_page;
248 XtSetArg (arg[0], XtNpageNumber, number);
249 XtSetValues (dvi, arg, 1);
250 XtSetArg (arg[0], XtNpageNumber, &actual_number);
251 XtSetArg (arg[1], XtNlastPageNumber, &last_page);
252 XtGetValues (dvi, arg, 2);
253 if (actual_number == 0)
254 sprintf (pageLabel, "Page <none>");
255 else if (last_page > 0)
256 sprintf (pageLabel, "Page %d of %d", actual_number, last_page);
257 else
258 sprintf (pageLabel, "Page %d", actual_number);
259 XtSetArg (arg[0], XtNlabel, pageLabel);
260 XtSetValues (page, arg, 1);
263 static void
264 SelectPageNumber (number_string)
265 char *number_string;
267 SetPageNumber (atoi(number_string));
270 static int hadFile = 0;
272 static void
273 NewFile (name)
274 char *name;
276 Arg arg[2];
277 char *n;
278 FILE *new_file;
279 Boolean seek = 0;
281 if (current_file) {
282 if (!strcmp (current_file_name, "-"))
284 else if (current_file_name[0] == '|')
285 pclose (current_file);
286 else
287 fclose (current_file);
289 if (!strcmp (name, "-"))
290 new_file = stdin;
291 else if (name[0] == '|')
292 new_file = popen (name+1, "r");
293 else {
294 new_file = fopen (name, "r");
295 seek = 1;
297 if (!new_file) {
298 /* XXX display error message */
299 return;
301 XtSetArg (arg[0], XtNfile, new_file);
302 XtSetArg (arg[1], XtNseek, seek);
303 XtSetValues (dvi, arg, 2);
304 if (hadFile || name[0] != '-' || name[1] != '\0') {
305 XtSetArg (arg[0], XtNtitle, name);
306 if (name[0] != '/' && (n = strrchr (name, '/')))
307 n = n + 1;
308 else
309 n = name;
310 XtSetArg (arg[1], XtNiconName, n);
311 XtSetValues (toplevel, arg, 2);
313 hadFile = 1;
314 SelectPageNumber ("1");
315 strcpy (current_file_name, name);
316 current_file = new_file;
319 static char fileBuf[1024];
321 ResetMenuEntry (entry)
322 Widget entry;
324 Arg arg[1];
326 XtSetArg (arg[0], XtNpopupOnEntry, entry);
327 XtSetValues (XtParent(entry) , arg, (Cardinal) 1);
330 /*ARGSUSED*/
332 static void
333 NextPage (entry, name, data)
334 Widget entry;
335 caddr_t name, data;
337 NextPageAction();
338 ResetMenuEntry (entry);
341 static void
342 NextPageAction ()
344 Arg args[1];
345 int number;
347 XtSetArg (args[0], XtNpageNumber, &number);
348 XtGetValues (dvi, args, 1);
349 SetPageNumber (number+1);
352 /*ARGSUSED*/
354 static void
355 PreviousPage (entry, name, data)
356 Widget entry;
357 caddr_t name, data;
359 PreviousPageAction ();
360 ResetMenuEntry (entry);
363 static void
364 PreviousPageAction ()
366 Arg args[1];
367 int number;
369 XtSetArg (args[0], XtNpageNumber, &number);
370 XtGetValues (dvi, args, 1);
371 SetPageNumber (number-1);
374 /* ARGSUSED */
376 static void
377 SelectPage (entry, name, data)
378 Widget entry;
379 caddr_t name, data;
381 SelectPageAction ();
382 ResetMenuEntry (entry);
385 static void
386 SelectPageAction ()
388 MakePrompt (toplevel, "Page number", SelectPageNumber, "");
392 static void
393 DoPrint (name)
394 char *name;
396 FILE *print_file;
397 #ifdef SIGNALRETURNSINT
398 int (*handler)();
399 #else
400 void (*handler)();
401 #endif
402 /* Avoid dieing because of an invalid command. */
403 handler = signal(SIGPIPE, SIG_IGN);
405 print_file = popen(name, "w");
406 if (!print_file)
407 /* XXX print error message */
408 return;
409 DviSaveToFile(dvi, print_file);
410 pclose(print_file);
411 signal(SIGPIPE, handler);
412 strcpy(current_print_command, name);
415 static void
416 RerasterizeAction()
418 Arg args[1];
419 int number;
421 if (current_file_name[0] == 0) {
422 /* XXX display an error message */
423 return;
425 XtSetArg (args[0], XtNpageNumber, &number);
426 XtGetValues (dvi, args, 1);
427 NewFile(current_file_name);
428 SetPageNumber (number);
431 /* ARGSUSED */
433 static void
434 Print (entry, name, data)
435 Widget entry;
436 caddr_t name, data;
438 PrintAction ();
439 ResetMenuEntry (entry);
442 static void
443 PrintAction ()
445 if (current_print_command[0])
446 strcpy (fileBuf, current_print_command);
447 else
448 fileBuf[0] = '\0';
449 MakePrompt (toplevel, "Print command:", DoPrint, fileBuf);
453 /* ARGSUSED */
455 static void
456 OpenFile (entry, name, data)
457 Widget entry;
458 caddr_t name, data;
460 OpenFileAction ();
461 ResetMenuEntry (entry);
464 static void
465 OpenFileAction ()
467 if (current_file_name[0])
468 strcpy (fileBuf, current_file_name);
469 else
470 fileBuf[0] = '\0';
471 MakePrompt (toplevel, "File to open:", NewFile, fileBuf);
474 /* ARGSUSED */
476 static void
477 Quit (entry, closure, data)
478 Widget entry;
479 caddr_t closure, data;
481 QuitAction ();
484 static void
485 QuitAction ()
487 exit (0);
490 Widget promptShell, promptDialog;
491 void (*promptfunction)();
493 /* ARGSUSED */
494 static
495 void CancelAction (widget, event, params, num_params)
496 Widget widget;
497 XEvent *event;
498 String *params;
499 Cardinal *num_params;
501 if (promptShell) {
502 XtSetKeyboardFocus(toplevel, (Widget) None);
503 XtDestroyWidget(promptShell);
504 promptShell = (Widget) 0;
508 static
509 void AcceptAction (widget, event, params, num_params)
510 Widget widget;
511 XEvent *event;
512 String *params;
513 Cardinal *num_params;
515 (*promptfunction)(XawDialogGetValueString(promptDialog));
516 CancelAction (widget, event, params, num_params);
519 MakePrompt(centerw, prompt, func, def)
520 Widget centerw;
521 char *prompt;
522 void (*func)();
523 char *def;
525 static Arg dialogArgs[] = {
526 {XtNlabel, 0},
527 {XtNvalue, 0},
529 Arg valueArgs[1];
530 Arg centerArgs[2];
531 Position source_x, source_y;
532 Position dest_x, dest_y;
533 Dimension center_width, center_height;
534 Dimension prompt_width, prompt_height;
535 Widget valueWidget;
537 CancelAction ((Widget)NULL, (XEvent *) 0, (String *) 0, (Cardinal *) 0);
538 promptShell = XtCreatePopupShell ("promptShell", transientShellWidgetClass,
539 toplevel, NULL, (Cardinal) 0);
540 dialogArgs[0].value = (XtArgVal)prompt;
541 dialogArgs[1].value = (XtArgVal)def;
542 promptDialog = XtCreateManagedWidget( "promptDialog", dialogWidgetClass,
543 promptShell, dialogArgs, XtNumber (dialogArgs));
544 XawDialogAddButton(promptDialog, "accept", NULL, (caddr_t) 0);
545 XawDialogAddButton(promptDialog, "cancel", NULL, (caddr_t) 0);
546 valueWidget = XtNameToWidget (promptDialog, "value");
547 if (valueWidget) {
548 XtSetArg (valueArgs[0], XtNresizable, TRUE);
549 XtSetValues (valueWidget, valueArgs, 1);
551 * as resizable isn't set until just above, the
552 * default value will be displayed incorrectly.
553 * rectify the situation by resetting the values
555 XtSetValues (promptDialog, dialogArgs, XtNumber (dialogArgs));
557 XtSetKeyboardFocus (promptDialog, valueWidget);
558 XtSetKeyboardFocus (toplevel, valueWidget);
559 XtRealizeWidget (promptShell);
561 * place the widget in the center of the "parent"
563 XtSetArg (centerArgs[0], XtNwidth, &center_width);
564 XtSetArg (centerArgs[1], XtNheight, &center_height);
565 XtGetValues (centerw, centerArgs, 2);
566 XtSetArg (centerArgs[0], XtNwidth, &prompt_width);
567 XtSetArg (centerArgs[1], XtNheight, &prompt_height);
568 XtGetValues (promptShell, centerArgs, 2);
569 source_x = (center_width - prompt_width) / 2;
570 source_y = (center_height - prompt_height) / 3;
571 XtTranslateCoords (centerw, source_x, source_y, &dest_x, &dest_y);
572 XtSetArg (centerArgs[0], XtNx, dest_x);
573 XtSetArg (centerArgs[1], XtNy, dest_y);
574 XtSetValues (promptShell, centerArgs, 2);
575 XtMapWidget(promptShell);
576 promptfunction = func;
579 /* For DviChar.c */
581 char *xmalloc(n)
582 int n;
584 return XtMalloc(n);
588 Local Variables:
589 c-indent-level: 4
590 c-continued-statement-offset: 4
591 c-brace-offset: -4
592 c-argdecl-indent: 4
593 c-label-offset: -4
594 c-tab-always-indent: nil
595 End: