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.
25 * Display ditroff output in an X window
30 static char rcsid[] = "$XConsortium: xditview.c,v 1.17 89/12/10 17:05:08 rws Exp $";
38 #include <X11/Xatom.h>
41 #include <X11/Intrinsic.h>
42 #include <X11/StringDefs.h>
43 #include <X11/Shell.h>
44 #include <X11/Xaw/Paned.h>
45 #include <X11/Xaw/Viewport.h>
46 #include <X11/Xaw/Box.h>
47 #include <X11/Xaw/Command.h>
48 #include <X11/Xaw/Dialog.h>
49 #include <X11/Xaw/Label.h>
50 #include <X11/Xaw/SimpleMenu.h>
51 #include <X11/Xaw/SmeBSB.h>
60 #include "xdit_mask.bm"
62 #ifdef NEED_DECLARATION_POPEN
63 FILE *popen(const char *, const char *);
64 #endif /* NEED_DECLARATION_POPEN */
66 #ifdef NEED_DECLARATION_PCLOSE
68 #endif /* NEED_DECLARATION_PCLOSE */
70 typedef void (*MakePromptFunc)(const char *);
72 static String fallback_resources[] = {
73 #include "GXditview-ad.h"
77 static struct app_resources {
82 #define offset(field) XtOffset(struct app_resources *, field)
84 /* Application resources. */
86 static XtResource resources[] = {
87 {(String)"printCommand", (String)"PrintCommand", (String)XtRString,
88 sizeof(char*), offset(print_command), (String)XtRString, NULL},
89 {(String)"filename", (String)"Filename", (String)XtRString,
90 sizeof(char*), offset(filename), (String)XtRString, NULL},
95 /* Command line options table. Only resources are entered here...there is a
96 pass over the remaining options after XtParseCommand is let loose. */
98 static XrmOptionDescRec options[] = {
99 {(char *)"-page", (char *)"*dvi.pageNumber",
100 XrmoptionSepArg, NULL},
101 {(char *)"-backingStore", (char *)"*dvi.backingStore",
102 XrmoptionSepArg, NULL},
103 {(char *)"-resolution", (char *)"*dvi.resolution",
104 XrmoptionSepArg, NULL},
105 {(char *)"-printCommand", (char *)".printCommand",
106 XrmoptionSepArg, NULL},
107 {(char *)"-filename", (char *)".filename",
108 XrmoptionSepArg, NULL},
109 {(char *)"-noPolyText", (char *)"*dvi.noPolyText",
110 XrmoptionNoArg, (XPointer)"TRUE"},
113 static char current_print_command[1024];
115 static char current_file_name[1024];
116 static FILE *current_file;
119 * Report the syntax for calling xditview.
123 Syntax(const char *call)
125 (void) printf ("Usage: %s [-fg <color>] [-bg <color>]\n", call);
126 (void) printf (" [-bd <color>] [-bw <pixels>] [-help]\n");
127 (void) printf (" [-display displayname] [-geometry geom]\n");
128 (void) printf (" [-page <page-number>] [-backing <backing-store>]\n");
129 (void) printf (" [-resolution <res>] [-print <command>]\n");
130 (void) printf (" [-filename <file>] [filename]\n\n");
134 static void NewFile (const char *);
135 static void SetPageNumber (int);
136 static Widget toplevel, paned, viewport, dvi;
138 static Widget simpleMenu;
140 static void NextPage(Widget, XtPointer, XtPointer);
141 static void PreviousPage(Widget, XtPointer, XtPointer);
142 static void SelectPage(Widget, XtPointer, XtPointer);
143 static void OpenFile(Widget, XtPointer, XtPointer);
144 static void Quit(Widget, XtPointer, XtPointer);
145 static void Print(Widget, XtPointer, XtPointer);
147 static struct menuEntry {
149 XtCallbackProc function;
151 {"nextPage", NextPage},
152 {"previousPage", PreviousPage},
153 {"selectPage", SelectPage},
155 {"openFile", OpenFile},
159 static void NextPageAction(Widget, XEvent *, String *, Cardinal *);
160 static void PreviousPageAction(Widget, XEvent *, String *, Cardinal *);
161 static void SelectPageAction(Widget, XEvent *, String *, Cardinal *);
162 static void OpenFileAction(Widget, XEvent *, String *, Cardinal *);
163 static void QuitAction(Widget, XEvent *, String *, Cardinal *);
164 static void AcceptAction(Widget, XEvent *, String *, Cardinal *);
165 static void CancelAction(Widget, XEvent *, String *, Cardinal *);
166 static void PrintAction(Widget, XEvent *, String *, Cardinal *);
167 static void RerasterizeAction(Widget, XEvent *, String *, Cardinal *);
169 static void MakePrompt(Widget, const char *, MakePromptFunc, const char *);
171 XtActionsRec xditview_actions[] = {
172 {(String)"NextPage", NextPageAction},
173 {(String)"PreviousPage", PreviousPageAction},
174 {(String)"SelectPage", SelectPageAction},
175 {(String)"Print", PrintAction},
176 {(String)"OpenFile", OpenFileAction},
177 {(String)"Rerasterize", RerasterizeAction},
178 {(String)"Quit", QuitAction},
179 {(String)"Accept", AcceptAction},
180 {(String)"Cancel", CancelAction},
183 #define MenuNextPage 0
184 #define MenuPreviousPage 1
185 #define MenuSelectPage 2
187 #define MenuOpenFile 4
190 static char pageLabel[256] = "Page <none>";
192 int main(int argc, char **argv)
196 static Arg labelArgs[] = {
197 {XtNlabel, (XtArgVal) pageLabel},
199 XtAppContext xtcontext;
202 Arg pageNumberArgs[1];
205 toplevel = XtAppInitialize(&xtcontext, "GXditview",
206 options, XtNumber (options),
207 &argc, argv, fallback_resources, NULL, 0);
209 || (argc == 2 && (!strcmp(argv[1], "-help")
210 || !strcmp(argv[1], "--help"))))
213 XtGetApplicationResources(toplevel, (XtPointer)&app_resources,
214 resources, XtNumber(resources),
216 if (app_resources.print_command)
217 strcpy(current_print_command, app_resources.print_command);
219 XtAppAddActions(xtcontext, xditview_actions, XtNumber (xditview_actions));
221 XtSetArg (topLevelArgs[0], XtNiconPixmap,
222 XCreateBitmapFromData (XtDisplay (toplevel),
223 XtScreen(toplevel)->root,
225 xdit_width, xdit_height));
227 XtSetArg (topLevelArgs[1], XtNiconMask,
228 XCreateBitmapFromData (XtDisplay (toplevel),
229 XtScreen(toplevel)->root,
230 (char *)xdit_mask_bits,
231 xdit_mask_width, xdit_mask_height));
232 XtSetValues (toplevel, topLevelArgs, 2);
237 * create the menu and insert the entries
239 simpleMenu = XtCreatePopupShell ("menu", simpleMenuWidgetClass, toplevel,
241 for (i = 0; i < XtNumber (menuEntries); i++) {
242 entry = XtCreateManagedWidget(menuEntries[i].name,
243 smeBSBObjectClass, simpleMenu,
245 XtAddCallback(entry, XtNcallback, menuEntries[i].function, NULL);
248 paned = XtCreateManagedWidget("paned", panedWidgetClass, toplevel,
250 viewport = XtCreateManagedWidget("viewport", viewportWidgetClass, paned,
252 dvi = XtCreateManagedWidget ("dvi", dviWidgetClass, viewport, NULL, 0);
253 page = XtCreateManagedWidget ("label", labelWidgetClass, paned,
254 labelArgs, XtNumber (labelArgs));
255 XtSetArg (pageNumberArgs[0], XtNpageNumber, &page_number);
256 XtGetValues (dvi, pageNumberArgs, 1);
259 /* NewFile modifies current_file_name, so do this here. */
260 if (app_resources.filename)
261 strcpy(current_file_name, app_resources.filename);
262 XtRealizeWidget (toplevel);
264 SetPageNumber (page_number);
265 XtAppMainLoop(xtcontext);
270 SetPageNumber (int number)
273 int actual_number, last_page;
275 XtSetArg (arg[0], XtNpageNumber, number);
276 XtSetValues (dvi, arg, 1);
277 XtSetArg (arg[0], XtNpageNumber, &actual_number);
278 XtSetArg (arg[1], XtNlastPageNumber, &last_page);
279 XtGetValues (dvi, arg, 2);
280 if (actual_number == 0)
281 sprintf (pageLabel, "Page <none>");
282 else if (last_page > 0)
283 sprintf (pageLabel, "Page %d of %d", actual_number, last_page);
285 sprintf (pageLabel, "Page %d", actual_number);
286 XtSetArg (arg[0], XtNlabel, pageLabel);
287 XtSetValues (page, arg, 1);
291 SelectPageNumber (const char *number_string)
293 SetPageNumber (atoi(number_string));
296 static int hadFile = 0;
299 NewFile (const char *name)
307 if (!strcmp (current_file_name, "-"))
309 else if (current_file_name[0] == '|')
310 pclose (current_file);
312 fclose (current_file);
314 if (!strcmp (name, "-"))
316 else if (name[0] == '|')
317 new_file = popen (name+1, "r");
319 new_file = fopen (name, "r");
323 /* XXX display error message */
326 XtSetArg (arg[0], XtNfile, new_file);
327 XtSetArg (arg[1], XtNseek, seek);
328 XtSetValues (dvi, arg, 2);
329 if (hadFile || name[0] != '-' || name[1] != '\0') {
330 XtSetArg (arg[0], XtNtitle, name);
331 if (name[0] != '/' && (n = strrchr (name, '/')))
335 XtSetArg (arg[1], XtNiconName, n);
336 XtSetValues (toplevel, arg, 2);
339 SelectPageNumber ("1");
340 strcpy (current_file_name, name);
341 current_file = new_file;
344 static char fileBuf[1024];
347 ResetMenuEntry (Widget entry)
351 XtSetArg (arg[0], (String)XtNpopupOnEntry, entry);
352 XtSetValues (XtParent(entry) , arg, (Cardinal) 1);
358 NextPage (Widget entry, XtPointer name, XtPointer data)
360 name = name; /* unused; suppress compiler warning */
363 NextPageAction((Widget)NULL, (XEvent *) 0, (String *) 0, (Cardinal *) 0);
364 ResetMenuEntry (entry);
368 NextPageAction (Widget widget, XEvent *event,
369 String *params, Cardinal *num_params)
374 XtSetArg (args[0], XtNpageNumber, &number);
375 XtGetValues (dvi, args, 1);
376 SetPageNumber (number+1);
378 widget = widget; /* unused; suppress compiler warning */
381 num_params = num_params;
387 PreviousPage (Widget entry, XtPointer name, XtPointer data)
389 name = name; /* unused; suppress compiler warning */
392 PreviousPageAction ((Widget)NULL, (XEvent *) 0, (String *) 0,
394 ResetMenuEntry (entry);
398 PreviousPageAction (Widget widget, XEvent *event,
399 String *params, Cardinal *num_params)
404 XtSetArg (args[0], XtNpageNumber, &number);
405 XtGetValues (dvi, args, 1);
406 SetPageNumber (number-1);
408 widget = widget; /* unused; suppress compiler warning */
411 num_params = num_params;
417 SelectPage (Widget entry, XtPointer name, XtPointer data)
419 name = name; /* unused; suppress compiler warning */
422 SelectPageAction ((Widget)NULL, (XEvent *) 0, (String *) 0,
424 ResetMenuEntry (entry);
428 SelectPageAction (Widget widget, XEvent *event,
429 String *params, Cardinal *num_params)
431 widget = widget; /* unused; suppress compiler warning */
434 num_params = num_params;
436 MakePrompt (toplevel, "Page number", SelectPageNumber, "");
441 DoPrint (const char *name)
444 RETSIGTYPE (*handler)(int);
446 /* Avoid dieing because of an invalid command. */
447 handler = signal(SIGPIPE, SIG_IGN);
449 print_file = popen(name, "w");
451 /* XXX print error message */
453 DviSaveToFile(dvi, print_file);
455 signal(SIGPIPE, handler);
456 strcpy(current_print_command, name);
460 RerasterizeAction (Widget widget, XEvent *event,
461 String *params, Cardinal *num_params)
466 if (current_file_name[0] == 0) {
467 /* XXX display an error message */
470 XtSetArg (args[0], XtNpageNumber, &number);
471 XtGetValues (dvi, args, 1);
472 NewFile(current_file_name);
473 SetPageNumber (number);
475 widget = widget; /* unused; suppress compiler warning */
478 num_params = num_params;
484 Print (Widget entry, XtPointer name, XtPointer data)
486 name = name; /* unused; suppress compiler warning */
489 PrintAction ((Widget)NULL, (XEvent *) 0, (String *) 0, (Cardinal *) 0);
490 ResetMenuEntry (entry);
494 PrintAction (Widget widget, XEvent *event,
495 String *params, Cardinal *num_params)
497 widget = widget; /* unused; suppress compiler warning */
500 num_params = num_params;
502 if (current_print_command[0])
503 strcpy (fileBuf, current_print_command);
506 MakePrompt (toplevel, "Print command:", DoPrint, fileBuf);
513 OpenFile (Widget entry, XtPointer name, XtPointer data)
515 name = name; /* unused; suppress compiler warning */
518 OpenFileAction ((Widget)NULL, (XEvent *) 0, (String *) 0, (Cardinal *) 0);
519 ResetMenuEntry (entry);
523 OpenFileAction (Widget widget, XEvent *event,
524 String *params, Cardinal *num_params)
526 widget = widget; /* unused; suppress compiler warning */
529 num_params = num_params;
531 if (current_file_name[0])
532 strcpy (fileBuf, current_file_name);
535 MakePrompt (toplevel, "File to open:", NewFile, fileBuf);
541 Quit (Widget entry, XtPointer closure, XtPointer data)
543 entry = entry; /* unused; suppress compiler warning */
547 QuitAction ((Widget)NULL, (XEvent *) 0, (String *) 0, (Cardinal *) 0);
551 QuitAction (Widget widget, XEvent *event,
552 String *params, Cardinal *num_params)
554 widget = widget; /* unused; suppress compiler warning */
557 num_params = num_params;
562 Widget promptShell, promptDialog;
563 MakePromptFunc promptfunction;
567 void CancelAction (Widget widget, XEvent *event,
568 String *params, Cardinal *num_params)
570 widget = widget; /* unused; suppress compiler warning */
573 num_params = num_params;
576 XtSetKeyboardFocus(toplevel, (Widget) None);
577 XtDestroyWidget(promptShell);
578 promptShell = (Widget) 0;
583 void AcceptAction (Widget widget, XEvent *event,
584 String *params, Cardinal *num_params)
586 (*promptfunction)(XawDialogGetValueString(promptDialog));
587 CancelAction (widget, event, params, num_params);
591 MakePrompt(Widget centerw, const char *prompt,
592 MakePromptFunc func, const char *def)
594 static Arg dialogArgs[] = {
600 Position source_x, source_y;
601 Position dest_x, dest_y;
602 Dimension center_width, center_height;
603 Dimension prompt_width, prompt_height;
606 CancelAction ((Widget)NULL, (XEvent *) 0, (String *) 0, (Cardinal *) 0);
607 promptShell = XtCreatePopupShell ("promptShell", transientShellWidgetClass,
608 toplevel, NULL, (Cardinal) 0);
609 dialogArgs[0].value = (XtArgVal)prompt;
610 dialogArgs[1].value = (XtArgVal)def;
611 promptDialog = XtCreateManagedWidget( "promptDialog", dialogWidgetClass,
612 promptShell, dialogArgs, XtNumber (dialogArgs));
613 XawDialogAddButton(promptDialog, "accept", NULL, (XtPointer) 0);
614 XawDialogAddButton(promptDialog, "cancel", NULL, (XtPointer) 0);
615 valueWidget = XtNameToWidget (promptDialog, "value");
617 XtSetArg (valueArgs[0], (String)XtNresizable, TRUE);
618 XtSetValues (valueWidget, valueArgs, 1);
620 * as resizable isn't set until just above, the
621 * default value will be displayed incorrectly.
622 * rectify the situation by resetting the values
624 XtSetValues (promptDialog, dialogArgs, XtNumber (dialogArgs));
626 XtSetKeyboardFocus (promptDialog, valueWidget);
627 XtSetKeyboardFocus (toplevel, valueWidget);
628 XtRealizeWidget (promptShell);
630 * place the widget in the center of the "parent"
632 XtSetArg (centerArgs[0], XtNwidth, ¢er_width);
633 XtSetArg (centerArgs[1], XtNheight, ¢er_height);
634 XtGetValues (centerw, centerArgs, 2);
635 XtSetArg (centerArgs[0], XtNwidth, &prompt_width);
636 XtSetArg (centerArgs[1], XtNheight, &prompt_height);
637 XtGetValues (promptShell, centerArgs, 2);
638 source_x = (center_width - prompt_width) / 2;
639 source_y = (center_height - prompt_height) / 3;
640 XtTranslateCoords (centerw, source_x, source_y, &dest_x, &dest_y);
641 XtSetArg (centerArgs[0], XtNx, dest_x);
642 XtSetArg (centerArgs[1], XtNy, dest_y);
643 XtSetValues (promptShell, centerArgs, 2);
644 XtMapWidget(promptShell);
645 promptfunction = func;
651 c-continued-statement-offset: 4
655 c-tab-always-indent: nil