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 $";
34 #include <X11/Xatom.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>
55 #include "xdit_mask.bm"
61 static String fallback_resources
[] = {
62 #include "GXditview-ad.h"
66 static struct 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
},
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.
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");
118 static void NewFile (), SetPageNumber ();
119 static Widget toplevel
, paned
, viewport
, dvi
;
121 static Widget simpleMenu
;
123 static void NextPage(), PreviousPage(), SelectPage(), OpenFile(), Quit();
126 static struct menuEntry
{
130 {"nextPage", NextPage
},
131 {"previousPage", PreviousPage
},
132 {"selectPage", SelectPage
},
134 {"openFile", OpenFile
},
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
161 #define MenuOpenFile 4
164 static char pageLabel
[256] = "Page <none>";
172 static Arg labelArgs
[] = {
173 {XtNlabel
, (XtArgVal
) pageLabel
},
175 XtAppContext xtcontext
;
178 Arg pageNumberArgs
[1];
181 toplevel
= XtAppInitialize(&xtcontext
, "GXditview",
182 options
, XtNumber (options
),
183 &argc
, argv
, fallback_resources
, NULL
, 0);
185 || (argc
== 2 && (!strcmp(argv
[1], "-help")
186 || !strcmp(argv
[1], "--help"))))
189 XtGetApplicationResources(toplevel
, (XtPointer
)&app_resources
,
190 resources
, XtNumber(resources
),
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
,
206 xdit_mask_width
, xdit_mask_height
));
207 XtSetValues (toplevel
, topLevelArgs
, 2);
212 * create the menu and insert the entries
214 simpleMenu
= XtCreatePopupShell ("menu", simpleMenuWidgetClass
, toplevel
,
216 for (i
= 0; i
< XtNumber (menuEntries
); i
++) {
217 entry
= XtCreateManagedWidget(menuEntries
[i
].name
,
218 smeBSBObjectClass
, simpleMenu
,
220 XtAddCallback(entry
, XtNcallback
, menuEntries
[i
].function
, NULL
);
223 paned
= XtCreateManagedWidget("paned", panedWidgetClass
, toplevel
,
225 viewport
= XtCreateManagedWidget("viewport", viewportWidgetClass
, paned
,
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);
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
);
239 SetPageNumber (page_number
);
240 XtAppMainLoop(xtcontext
);
245 SetPageNumber (number
)
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
);
260 sprintf (pageLabel
, "Page %d", actual_number
);
261 XtSetArg (arg
[0], XtNlabel
, pageLabel
);
262 XtSetValues (page
, arg
, 1);
266 SelectPageNumber (number_string
)
269 SetPageNumber (atoi(number_string
));
272 static int hadFile
= 0;
284 if (!strcmp (current_file_name
, "-"))
286 else if (current_file_name
[0] == '|')
287 pclose (current_file
);
289 fclose (current_file
);
291 if (!strcmp (name
, "-"))
293 else if (name
[0] == '|')
294 new_file
= popen (name
+1, "r");
296 new_file
= fopen (name
, "r");
300 /* XXX display error message */
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
, '/')))
312 XtSetArg (arg
[1], XtNiconName
, n
);
313 XtSetValues (toplevel
, arg
, 2);
316 SelectPageNumber ("1");
317 strcpy (current_file_name
, name
);
318 current_file
= new_file
;
321 static char fileBuf
[1024];
324 ResetMenuEntry (entry
)
329 XtSetArg (arg
[0], XtNpopupOnEntry
, entry
);
330 XtSetValues (XtParent(entry
) , arg
, (Cardinal
) 1);
336 NextPage (entry
, name
, data
)
341 ResetMenuEntry (entry
);
350 XtSetArg (args
[0], XtNpageNumber
, &number
);
351 XtGetValues (dvi
, args
, 1);
352 SetPageNumber (number
+1);
358 PreviousPage (entry
, name
, data
)
362 PreviousPageAction ();
363 ResetMenuEntry (entry
);
367 PreviousPageAction ()
372 XtSetArg (args
[0], XtNpageNumber
, &number
);
373 XtGetValues (dvi
, args
, 1);
374 SetPageNumber (number
-1);
380 SelectPage (entry
, name
, data
)
385 ResetMenuEntry (entry
);
391 MakePrompt (toplevel
, "Page number", SelectPageNumber
, "");
400 #ifdef SIGNALRETURNSINT
405 /* Avoid dieing because of an invalid command. */
406 handler
= signal(SIGPIPE
, SIG_IGN
);
408 print_file
= popen(name
, "w");
410 /* XXX print error message */
412 DviSaveToFile(dvi
, print_file
);
414 signal(SIGPIPE
, handler
);
415 strcpy(current_print_command
, name
);
424 if (current_file_name
[0] == 0) {
425 /* XXX display an error message */
428 XtSetArg (args
[0], XtNpageNumber
, &number
);
429 XtGetValues (dvi
, args
, 1);
430 NewFile(current_file_name
);
431 SetPageNumber (number
);
437 Print (entry
, name
, data
)
442 ResetMenuEntry (entry
);
448 if (current_print_command
[0])
449 strcpy (fileBuf
, current_print_command
);
452 MakePrompt (toplevel
, "Print command:", DoPrint
, fileBuf
);
459 OpenFile (entry
, name
, data
)
464 ResetMenuEntry (entry
);
470 if (current_file_name
[0])
471 strcpy (fileBuf
, current_file_name
);
474 MakePrompt (toplevel
, "File to open:", NewFile
, fileBuf
);
480 Quit (entry
, closure
, data
)
482 caddr_t closure
, data
;
493 Widget promptShell
, promptDialog
;
494 void (*promptfunction
)();
498 void CancelAction (widget
, event
, params
, num_params
)
502 Cardinal
*num_params
;
505 XtSetKeyboardFocus(toplevel
, (Widget
) None
);
506 XtDestroyWidget(promptShell
);
507 promptShell
= (Widget
) 0;
512 void AcceptAction (widget
, event
, params
, num_params
)
516 Cardinal
*num_params
;
518 (*promptfunction
)(XawDialogGetValueString(promptDialog
));
519 CancelAction (widget
, event
, params
, num_params
);
523 MakePrompt(centerw
, prompt
, func
, def
)
529 static Arg dialogArgs
[] = {
535 Position source_x
, source_y
;
536 Position dest_x
, dest_y
;
537 Dimension center_width
, center_height
;
538 Dimension prompt_width
, prompt_height
;
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");
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
, ¢er_width
);
568 XtSetArg (centerArgs
[1], XtNheight
, ¢er_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
;
594 c-continued-statement-offset: 4
598 c-tab-always-indent: nil