handler.c revision 467bed7c
1/*
2
3Copyright (c) 1987, 1988  X Consortium
4
5Permission is hereby granted, free of charge, to any person obtaining
6a copy of this software and associated documentation files (the
7"Software"), to deal in the Software without restriction, including
8without limitation the rights to use, copy, modify, merge, publish,
9distribute, sublicense, and/or sell copies of the Software, and to
10permit persons to whom the Software is furnished to do so, subject to
11the following conditions:
12
13The above copyright notice and this permission notice shall be included
14in all copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
20OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22OTHER DEALINGS IN THE SOFTWARE.
23
24Except as contained in this notice, the name of the X Consortium shall
25not be used in advertising or otherwise to promote the sale, use or
26other dealings in this Software without prior written authorization
27from the X Consortium.
28
29*/
30
31/*
32 * xman - X window system manual page display program.
33 * Author:    Chris D. Peterson, MIT Project Athena
34 * Created:   October 29, 1987
35 */
36#ifdef HAVE_CONFIG_H
37# include "config.h"
38#endif
39
40#include <sys/types.h>
41#include <sys/stat.h>
42#include "globals.h"
43#include "vendor.h"
44#ifdef INCLUDE_XPRINT_SUPPORT
45#include "printdialog.h"
46#include "print.h"
47#endif /* INCLUDE_XPRINT_SUPPORT */
48
49#ifdef RELEASE_VERSION
50#define XMAN_VERSION "Xman Version " PACKAGE_VERSION " - X11R" RELEASE_VERSION
51#else
52#define XMAN_VERSION "Xman Version " PACKAGE_VERSION
53#endif
54
55static void PutUpManpage(ManpageGlobals * man_globals, FILE * file);
56static void ToggleBothShownState(ManpageGlobals * man_globals);
57
58/*	Function Name: OptionCallback
59 *	Description: This is the callback function for the callback menu.
60 *	Arguments: w - the widget we are calling back from.
61 *                 globals_pointer - a pointer to the pseudo globals structure
62 *                                  for this manpage.
63 *                 junk - (call data) not used.
64 *	Returns: none.
65 */
66
67/*ARGSUSED*/
68void
69OptionCallback(Widget w, XtPointer pointer, XtPointer junk)
70{
71    ManpageGlobals *man_globals = (ManpageGlobals *) pointer;
72    String params;
73    Cardinal num_params = 1;
74
75    if (w == man_globals->search_entry)
76        PopupSearch(XtParent(w), NULL, NULL, NULL);
77    else if (w == man_globals->dir_entry) {     /* Put Up Directory */
78        params = "Directory";
79        GotoPage(XtParent(w), NULL, &params, &num_params);
80    }
81    else if (w == man_globals->manpage_entry) { /* Put Up Man Page */
82        params = "ManualPage";
83        GotoPage(XtParent(w), NULL, &params, &num_params);
84    }
85    else if (w == man_globals->help_entry)      /* Help */
86        PopupHelp(XtParent(w), NULL, NULL, NULL);
87    else if (w == man_globals->both_screens_entry)      /*Toggle Both_Shown State. */
88        ToggleBothShownState(man_globals);
89    else if (w == man_globals->remove_entry)    /* Kill the manpage */
90        RemoveThisManpage(XtParent(w), NULL, NULL, NULL);
91    else if (w == man_globals->open_entry)      /* Open new manpage */
92        CreateNewManpage(XtParent(w), NULL, NULL, NULL);
93#ifdef INCLUDE_XPRINT_SUPPORT
94    else if (w == man_globals->print_entry)     /* Print current manpage */
95        PrintThisManpage(XtParent(w), NULL, NULL, NULL);
96#endif                          /* INCLUDE_XPRINT_SUPPORT */
97    else if (w == man_globals->version_entry)   /* Get version */
98        ShowVersion(XtParent(w), NULL, NULL, NULL);
99    else if (w == man_globals->quit_entry)      /* Quit. */
100        Quit(XtParent(w), NULL, NULL, NULL);
101}
102
103/*      Function Name: ToggleBothShownState;
104 *      Description: toggles the state of the both shown feature.
105 *      Arguments: man_globals - the man globals structure.
106 *      Returns: none.
107 */
108
109/*
110 * I did not have a two state widget, which is the way this
111 * should really be done.  1/22/88 - CDP.
112 */
113
114static void
115ToggleBothShownState(ManpageGlobals * man_globals)
116{
117    const char *label_str;
118    Arg arglist[1];
119
120    if (man_globals->both_shown == TRUE) {
121        label_str = SHOW_BOTH;
122        if (man_globals->dir_shown)
123            XtUnmanageChild(man_globals->manpagewidgets.manpage);
124        else
125            XtUnmanageChild(man_globals->manpagewidgets.directory);
126    }
127    else {
128        Widget manpage = man_globals->manpagewidgets.manpage;
129        Widget dir = man_globals->manpagewidgets.directory;
130
131        label_str = SHOW_ONE;
132
133        XtSetArg(arglist[0], XtNpreferredPaneSize, resources.directory_height);
134        XtSetValues(dir, arglist, (Cardinal) 1);
135
136        if (!man_globals->dir_shown) {
137            XtUnmanageChild(manpage);
138            XtManageChild(dir);
139        }
140        XtManageChild(manpage);
141    }
142    man_globals->both_shown = !man_globals->both_shown;
143
144    if (man_globals->dir_shown)
145        ChangeLabel(man_globals->label,
146                    man_globals->section_name[man_globals->current_directory]);
147    else
148        ChangeLabel(man_globals->label, man_globals->manpage_title);
149
150    XtSetArg(arglist[0], XtNlabel, label_str);
151    XtSetValues(man_globals->both_screens_entry, arglist, ONE);
152
153    /* if both are shown there is no need to switch between the two. */
154
155    XtSetArg(arglist[0], XtNsensitive, !man_globals->both_shown);
156    XtSetValues(man_globals->manpage_entry, arglist, ONE);
157    XtSetValues(man_globals->dir_entry, arglist, ONE);
158}
159
160/*	Function Name: Popup
161 *	Description: This function pops up the given widget under the cursor.
162 *	Arguments: w - the widget to popup.
163 *                 grab_kind - the kind of grab to register.
164 *	Returns: none
165 */
166
167/* How far off the top of the widget to have the initial cursor position. */
168
169#define OFF_OF_TOP 25
170
171void
172Popup(Widget w, XtGrabKind grab_kind)
173{
174    int x_root, y_root, y_pos, garbage;
175    unsigned int mask;
176    Window junk_window;
177
178    XQueryPointer(XtDisplay(w), XtWindow(w), &junk_window, &junk_window,
179                  &x_root, &y_root, &garbage, &garbage, &mask);
180
181    y_pos = OFF_OF_TOP - Height(w) / 2 - BorderWidth(w);
182    PositionCenter(w, x_root, y_root, y_pos, 0, 2, 2);
183    XtPopup(w, grab_kind);
184}
185
186/*	Function Name: PutUpManpage
187 *	Description: Puts the manpage on the display.
188 *	Arguments: man_globals - a pointer to the pseudo globals structure
189 *                                  for this manpage.
190 *                 file - the file to display.
191 *	Returns: none.
192 */
193
194static void
195PutUpManpage(ManpageGlobals * man_globals, FILE * file)
196{
197    String params = "ManualPage";
198    Cardinal num_params = 1;
199
200    if (file == NULL)
201        return;
202
203    OpenFile(man_globals, file);
204
205    if (!man_globals->both_shown) {
206        Arg arglist[1];
207
208        XtSetArg(arglist[0], XtNsensitive, TRUE);
209        XtSetValues(man_globals->manpage_entry, arglist, ONE);
210        XtSetValues(man_globals->both_screens_entry, arglist, ONE);
211    }
212    GotoPage(man_globals->manpagewidgets.manpage, NULL, &params, &num_params);
213}
214
215/*	Function Name: DirectoryHandler
216 *	Description: This is the callback function for the directory listings.
217 *	Arguments: w - the widget we are calling back from.
218 *                 global_pointer - the pointer to the pseudo global structure
219 *                                  associated with this manpage.
220 *                 ret_val - return value from the list widget.
221 *	Returns: none.
222 */
223
224void
225DirectoryHandler(Widget w, XtPointer global_pointer, XtPointer ret_val)
226{
227    FILE *file;                 /* The manpage file. */
228    ManpageGlobals *man_globals = (ManpageGlobals *) global_pointer;
229    XawListReturnStruct *ret_struct = (XawListReturnStruct *) ret_val;
230
231    file = FindManualFile(man_globals, man_globals->current_directory,
232                          ret_struct->list_index);
233    PutUpManpage(man_globals, file);
234    if ((file != NULL) && (file != man_globals->curr_file)) {
235        fclose(file);
236    }
237}
238
239/*	Function Name: DirPopupCallback
240 *	Description: This is the callback function for the callback menu.
241 *	Arguments: w - the widget we are calling back from.
242 *                 pointer - a pointer to the pseudo globals structure
243 *                                  for this manpage.
244 *                 junk - (call data) not used.
245 *	Returns: none.
246 */
247
248/*ARGSUSED*/
249void
250DirPopupCallback(Widget w, XtPointer pointer, XtPointer junk)
251{
252    ManpageGlobals *man_globals;
253    MenuStruct *menu_struct;
254    Widget parent;
255    int number;
256    int current_box;
257
258    menu_struct = (MenuStruct *) pointer;
259    man_globals = (ManpageGlobals *) menu_struct->data;
260
261    number = menu_struct->number;
262    current_box = man_globals->current_directory;
263
264    /* We have used this guy, pop down the menu. */
265
266    if (number != current_box) {
267        /* This is the only one that we know has a parent. */
268        parent = XtParent(man_globals->manpagewidgets.box[INITIAL_DIR]);
269
270        MakeDirectoryBox(man_globals, parent,
271                         man_globals->manpagewidgets.box + number, number);
272        XtUnmanageChild(man_globals->manpagewidgets.box[current_box]);
273        XtManageChild(man_globals->manpagewidgets.box[number]);
274
275        XawListUnhighlight(man_globals->manpagewidgets.box[current_box]);
276        ChangeLabel(man_globals->label, man_globals->section_name[number]);
277        man_globals->current_directory = number;
278    }
279
280    /* put up directory. */
281    if (!man_globals->both_shown) {
282        XtUnmanageChild(man_globals->manpagewidgets.manpage);
283        XtManageChild(man_globals->manpagewidgets.directory);
284    }
285}
286
287/************************************************************
288 *
289 * Action Routines.
290 *
291 ************************************************************/
292
293/*	Function Name: SaveFormattedPage
294 *	Description: This is the action routine may save the manpage.
295 *      Arguments: w - any widget in the widget tree.
296 *                 event - NOT USED.
297 *                 params, num_params - the parameters passed to the action
298 *                                      routine, can be either Manpage or
299 *                                      Directory.
300 *      Returns: none.
301 */
302
303/*ARGSUSED*/
304void
305SaveFormattedPage(Widget w, XEvent * event, String * params,
306                  Cardinal * num_params)
307{
308    ManpageGlobals *man_globals;
309    char cmdbuf[BUFSIZ], error_buf[BUFSIZ];
310
311    if (*num_params != 1) {
312        XtAppWarning(XtWidgetToApplicationContext(w),
313                     "Xman - SaveFormattedPage: This action routine requires one argument.");
314        return;
315    }
316
317    man_globals = GetGlobals(w);
318
319/*
320 * If we are not active then take no action.
321 */
322
323#if ARRAY_COMPARISON_TO_NULL_POINTER_MAKES_SENSE
324    if (man_globals->tempfile == NULL)
325        return;
326#endif
327
328    switch (params[0][0]) {
329    case 'S':
330    case 's':
331
332#ifndef NO_COMPRESS
333        if (!man_globals->compress)
334#endif
335
336            snprintf(cmdbuf, sizeof(cmdbuf), "%s %s %s", COPY,
337                     man_globals->tempfile, man_globals->save_file);
338
339#ifndef NO_COMPRESS
340        else if (man_globals->gzip)
341            snprintf(cmdbuf, sizeof(cmdbuf), "%s < %s > %s", GZIP_COMPRESS,
342                     man_globals->tempfile, man_globals->save_file);
343        else
344            snprintf(cmdbuf, sizeof(cmdbuf), "%s < %s > %s", COMPRESS,
345                     man_globals->tempfile, man_globals->save_file);
346#endif
347
348        if (!system(cmdbuf)) {
349            /* make sure the formatted man page is fully accessible by the world */
350            if (chmod(man_globals->save_file, CHMOD_MODE) != 0) {
351                snprintf(error_buf, sizeof(error_buf),
352                         "Couldn't set permissions on formatted man page '%s'.\n",
353                         man_globals->save_file);
354                PopupWarning(man_globals, error_buf);
355            }
356        }
357        else {
358            snprintf(error_buf, sizeof(error_buf),
359                     "Error while executing the command '%s'.\n", cmdbuf);
360            PopupWarning(man_globals, error_buf);
361        }
362        break;
363    case 'C':
364    case 'c':
365        break;
366    default:
367        PopupWarning(man_globals, "Xman - SaveFormattedPage: "
368                     "Unknown argument must be either 'Save' or 'Cancel'.");
369        return;
370    }
371
372/*
373 * We do not need the filename anymore, and have the fd open.
374 * We will remove it.
375 */
376
377    remove(man_globals->tempfile);
378    XtPopdown(XtParent(XtParent(w)));
379}
380
381/*      Function Name: GotoPage
382 *      Description: The Action routine that switches over to the manpage
383 *                   or directory.
384 *      Arguments: w - any widget in the widget tree.
385 *                 event - NOT USED.
386 *                 params, num_params - the parameters passed to the action
387 *                                      routine, can be either Manpage or
388 *                                      Directory.
389 *      Returns: none.
390 */
391
392/*ARGSUSED*/
393void
394GotoPage(Widget w, XEvent * event, String * params, Cardinal * num_params)
395{
396    ManpageGlobals *man_globals;
397    Arg arglist[1];
398    Boolean sensitive;
399
400    if (*num_params != 1) {
401        XtAppWarning(XtWidgetToApplicationContext(w),
402                     "Xman - GotoPage: This action routine requires one argument.");
403        return;
404    }
405
406    man_globals = GetGlobals(w);
407
408    if (man_globals->both_shown) {
409        ChangeLabel(man_globals->label,
410                    man_globals->section_name[man_globals->current_directory]);
411        return;
412    }
413
414    switch (params[0][0]) {
415    case 'M':
416    case 'm':
417        XtSetArg(arglist[0], XtNsensitive, &sensitive);
418        XtGetValues(man_globals->manpage_entry, arglist, ONE);
419        if (sensitive) {
420            ChangeLabel(man_globals->label, man_globals->manpage_title);
421            XtUnmanageChild(man_globals->manpagewidgets.directory);
422            XtManageChild(man_globals->manpagewidgets.manpage);
423            man_globals->dir_shown = FALSE;
424        }
425        break;
426    case 'D':
427    case 'd':
428        ChangeLabel(man_globals->label,
429                    man_globals->section_name[man_globals->current_directory]);
430        XtUnmanageChild(man_globals->manpagewidgets.manpage);
431        XtManageChild(man_globals->manpagewidgets.directory);
432        man_globals->dir_shown = TRUE;
433        break;
434    default:
435        XtAppWarning(XtWidgetToApplicationContext(w),
436                     "Xman - GotoPage: Unknown argument must be "
437                     "either Manpage or Directory.");
438        return;
439    }
440}
441
442/*      Function Name: Quit.
443 *      Description: Quits Xman.
444 *      Arguments: w - any widget.
445 *                 event - NOT USED.
446 *                 params, num_params - NOT USED.
447 *      Returns: none.
448 */
449
450/*ARGSUSED*/
451void
452Quit(Widget w, XEvent * event, String * params, Cardinal * num_params)
453{
454    XtAppSetExitFlag(XtWidgetToApplicationContext(w));
455}
456
457/*      Function Name: PopupHelp
458 *      Description: Pops up xman's help.
459 *      Arguments: w - NOT USED.
460 *                 event - NOT USED.
461 *                 params, num_params - NOT USED.
462 *      Returns: none.
463 */
464
465/*ARGSUSED*/
466void
467PopupHelp(Widget w, XEvent * event, String * params, Cardinal * num_params)
468{
469    if (MakeHelpWidget())
470        XtPopup(help_widget, XtGrabNone);
471}
472
473/*      Function Name: PopupSearch
474 *      Description: Pops up this manual pages search widget.
475 *      Arguments: w - any widget in this manpage.
476 *                 event - NOT USED.
477 *                 params, num_params - NOT USED.
478 *      Returns: none.
479 */
480
481/*ARGSUSED*/
482void
483PopupSearch(Widget w, XEvent * event, String * params, Cardinal * num_params)
484{
485    ManpageGlobals *man_globals = GetGlobals(w);
486
487    if (man_globals->search_widget) {
488        if (!XtIsRealized(man_globals->search_widget)) {
489            XtRealizeWidget(man_globals->search_widget);
490            AddCursor(man_globals->search_widget,
491                      resources.cursors.search_entry);
492        }
493        Popup(man_globals->search_widget, XtGrabNone);
494    }
495}
496
497/*      Function Name: CreateNewManpage
498 *      Description: Creates A New Manual Page.
499 *      Arguments: w - NOT USED.
500 *                 event - NOT USED.
501 *                 params, num_params - NOT USED.
502 *      Returns: none.
503 */
504
505/*ARGSUSED*/
506void
507CreateNewManpage(Widget w, XEvent * event, String * params,
508                 Cardinal * num_params)
509{
510    if (CreateManpage(NULL))
511        man_pages_shown++;
512}
513
514/*      Function Name: RemoveThisManpage
515 *      Description: Removes a manual page.
516 *      Arguments: w - any widget in the manpage.
517 *                 event - NOT USED.
518 *                 params, num_params - NOT USED.
519 *      Returns: none.
520 */
521
522/*ARGSUSED*/
523void
524RemoveThisManpage(Widget w, XEvent * event, String * params,
525                  Cardinal * num_params)
526{
527    ManpageGlobals *man_globals = GetGlobals(w);
528
529    if (man_globals->This_Manpage != help_widget) {
530        RemoveGlobals(man_globals->This_Manpage);
531        XtDestroyWidget(man_globals->This_Manpage);
532
533        XtFree((char *) man_globals->section_name);
534        XtFree((char *) man_globals->manpagewidgets.box);
535        XtFree((char *) man_globals);
536
537        if ((--man_pages_shown) == 0)
538            Quit(w, NULL, NULL, NULL);
539    }
540    else
541        XtPopdown(help_widget);
542}
543
544/*      Function Name: Search
545 *      Description: Actually performs a search.
546 *      Arguments: w - any widget in the manpage.
547 *                 event - NOT USED.
548 *                 params, num_params - NOT USED.
549 *      Returns: none.
550 */
551
552/*ARGSUSED*/
553void
554Search(Widget w, XEvent * event, String * params, Cardinal * num_params)
555{
556    ManpageGlobals *man_globals = GetGlobals(w);
557    FILE *file = NULL;
558
559    XtPopdown(XtParent(XtParent(w)));   /* popdown the search widget */
560
561    if ((*num_params < 1) || (*num_params > 2)) {
562        XtAppWarning(XtWidgetToApplicationContext(w),
563                     "Xman - Search: This action routine requires one or two arguments.");
564        return;
565    }
566
567    switch (params[0][0]) {
568    case 'a':
569    case 'A':
570        file = DoSearch(man_globals, APROPOS);
571        break;
572    case 'm':
573    case 'M':
574        file = DoSearch(man_globals, MANUAL);
575        break;
576    case 'c':
577    case 'C':
578        file = NULL;
579        break;
580    default:
581        XtAppWarning(XtWidgetToApplicationContext(w),
582                     "Xman - Search: First parameter unknown.");
583        file = NULL;
584        break;
585    }
586
587    if (*num_params == 2)
588        switch (params[1][0]) {
589        case 'O':
590        case 'o':
591            if (file != NULL) {
592                Widget w;
593                char *label;
594
595                w = CreateManpage(file);
596                if (w) {
597                    man_pages_shown++;
598
599                    /* Put title into new manual page. */
600
601                    label = man_globals->manpage_title;
602                    man_globals = GetGlobals(w);
603                    strcpy(man_globals->manpage_title, label);
604                    ChangeLabel(man_globals->label, label);
605                }
606            }
607            break;
608        default:
609            XtAppWarning(XtWidgetToApplicationContext(w),
610                         "Xman - Search: Second parameter unknown.");
611            break;
612        }
613    else {
614        PutUpManpage(man_globals, file);
615    }
616    if ((file != NULL) && (file != man_globals->curr_file)) {
617        fclose(file);
618    }
619}
620
621#ifdef INCLUDE_XPRINT_SUPPORT
622static void
623printshellDestroyXtProc(Widget w, XtPointer client_data, XtPointer callData)
624{
625    ManpageGlobals *mg = GetGlobals(w);
626
627    XawPrintDialogClosePrinterConnection(mg->printdialog, False);
628}
629
630static void
631printOKXtProc(Widget w, XtPointer client_data, XtPointer callData)
632{
633    XawPrintDialogCallbackStruct *pdcs =
634        (XawPrintDialogCallbackStruct *) callData;
635    Cardinal n;
636    Arg args[2];
637    ManpageGlobals *mg = GetGlobals(w);
638    Widget topwindow = mg->This_Manpage;
639    FILE *file;
640
641    Log(("printOKXtProc: OK.\n"));
642
643    /* Get file object */
644    n = 0;
645    XtSetArg(args[n], XtNfile, &file);
646    n++;
647    XtGetValues(mg->manpagewidgets.manpage, args, n);
648    Assertion(file != NULL, (("printOKXtProc: file == NULL.\n")));
649
650    DoPrintManpage("Xman",
651                   file, topwindow,
652                   pdcs->pdpy, pdcs->pcontext, pdcs->colorspace,
653                   printshellDestroyXtProc,
654                   mg->manpage_title,
655                   pdcs->printToFile ? pdcs->printToFileName : NULL);
656
657    XtPopdown(mg->printdialog_shell);
658}
659
660static void
661printCancelXtProc(Widget w, XtPointer client_data, XtPointer callData)
662{
663    ManpageGlobals *mg = GetGlobals(w);
664
665    Log(("printCancelXtProc: cancel.\n"));
666    XtPopdown(mg->printdialog_shell);
667
668    Log(("destroying print dialog shell...\n"));
669    XtDestroyWidget(mg->printdialog_shell);
670    mg->printdialog_shell = NULL;
671    mg->printdialog = NULL;
672    Log(("... done\n"));
673}
674
675/*      Function Name: PrintThisManpage
676 *      Description: Print the current manual page.
677 *      Arguments: mg - manpage globals
678 *      Returns: none.
679 */
680
681/*ARGSUSED*/
682void
683PrintThisManpage(Widget w, XEvent * event, String * params,
684                 Cardinal * num_params)
685{
686    ManpageGlobals *mg = GetGlobals(w);
687    Dimension width, height;
688    Position x, y;
689    Widget parent = mg->This_Manpage;
690    Widget topwindow = mg->This_Manpage;
691
692    Log(("print!\n"));
693
694    if (!mg->printdialog) {
695        int n;
696        Arg args[20];
697
698        n = 0;
699        XtSetArg(args[n], XtNallowShellResize, True);
700        n++;
701        mg->printdialog_shell = XtCreatePopupShell("printdialogshell",
702                                                   transientShellWidgetClass,
703                                                   topwindow, args, n);
704        n = 0;
705        mg->printdialog =
706            XtCreateManagedWidget("printdialog", printDialogWidgetClass,
707                                  mg->printdialog_shell, args, n);
708        XtAddCallback(mg->printdialog, XawNOkCallback, printOKXtProc, NULL);
709        XtAddCallback(mg->printdialog, XawNCancelCallback, printCancelXtProc,
710                      NULL);
711
712        XtRealizeWidget(mg->printdialog_shell);
713    }
714
715    /* Center dialog */
716    XtVaGetValues(mg->printdialog_shell,
717                  XtNwidth, &width, XtNheight, &height, NULL);
718
719    x = (Position) (XWidthOfScreen(XtScreen(parent)) - width) / 2;
720    y = (Position) (XHeightOfScreen(XtScreen(parent)) - height) / 3;
721
722    XtVaSetValues(mg->printdialog_shell, XtNx, x, XtNy, y, NULL);
723
724    XtPopup(mg->printdialog_shell, XtGrabNonexclusive);
725}
726#endif                          /* INCLUDE_XPRINT_SUPPORT */
727
728/*      Function Name: ShowVersion
729 *      Description: Show current version.
730 *      Arguments: w - any widget in the manpage.
731 *                 event - NOT USED.
732 *                 params, num_params - NOT USED.
733 *      Returns: none.
734 */
735
736/*ARGSUSED*/
737void
738ShowVersion(Widget w, XEvent * event, String * params, Cardinal * num_params)
739{
740    ManpageGlobals *man_globals = GetGlobals(w);
741
742    ChangeLabel(man_globals->label, XMAN_VERSION);
743}
744