handler.c revision b096d6f4
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 (man_globals->tempfile[0] == '\0')
324        return;
325
326    switch (params[0][0]) {
327    case 'S':
328    case 's':
329
330#ifndef NO_COMPRESS
331        if (!man_globals->compress)
332#endif
333
334            snprintf(cmdbuf, sizeof(cmdbuf), "%s %s %s", COPY,
335                     man_globals->tempfile, man_globals->save_file);
336
337#ifndef NO_COMPRESS
338        else if (man_globals->gzip)
339            snprintf(cmdbuf, sizeof(cmdbuf), "%s < %s > %s", GZIP_COMPRESS,
340                     man_globals->tempfile, man_globals->save_file);
341        else
342            snprintf(cmdbuf, sizeof(cmdbuf), "%s < %s > %s", COMPRESS,
343                     man_globals->tempfile, man_globals->save_file);
344#endif
345
346        if (!system(cmdbuf)) {
347            /* make sure the formatted man page is fully accessible by the world */
348            if (chmod(man_globals->save_file, CHMOD_MODE) != 0) {
349                snprintf(error_buf, sizeof(error_buf),
350                         "Couldn't set permissions on formatted man page '%s'.\n",
351                         man_globals->save_file);
352                PopupWarning(man_globals, error_buf);
353            }
354        }
355        else {
356            snprintf(error_buf, sizeof(error_buf),
357                     "Error while executing the command '%s'.\n", cmdbuf);
358            PopupWarning(man_globals, error_buf);
359        }
360        break;
361    case 'C':
362    case 'c':
363        break;
364    default:
365        PopupWarning(man_globals, "Xman - SaveFormattedPage: "
366                     "Unknown argument must be either 'Save' or 'Cancel'.");
367        return;
368    }
369
370/*
371 * We do not need the filename anymore, and have the fd open.
372 * We will remove it.
373 */
374
375    remove(man_globals->tempfile);
376    XtPopdown(XtParent(XtParent(w)));
377}
378
379/*      Function Name: GotoPage
380 *      Description: The Action routine that switches over to the manpage
381 *                   or directory.
382 *      Arguments: w - any widget in the widget tree.
383 *                 event - NOT USED.
384 *                 params, num_params - the parameters passed to the action
385 *                                      routine, can be either Manpage or
386 *                                      Directory.
387 *      Returns: none.
388 */
389
390/*ARGSUSED*/
391void
392GotoPage(Widget w, XEvent * event, String * params, Cardinal * num_params)
393{
394    ManpageGlobals *man_globals;
395    Arg arglist[1];
396    Boolean sensitive;
397
398    if (*num_params != 1) {
399        XtAppWarning(XtWidgetToApplicationContext(w),
400                     "Xman - GotoPage: This action routine requires one argument.");
401        return;
402    }
403
404    man_globals = GetGlobals(w);
405
406    if (man_globals->both_shown) {
407        ChangeLabel(man_globals->label,
408                    man_globals->section_name[man_globals->current_directory]);
409        return;
410    }
411
412    switch (params[0][0]) {
413    case 'M':
414    case 'm':
415        XtSetArg(arglist[0], XtNsensitive, &sensitive);
416        XtGetValues(man_globals->manpage_entry, arglist, ONE);
417        if (sensitive) {
418            ChangeLabel(man_globals->label, man_globals->manpage_title);
419            XtUnmanageChild(man_globals->manpagewidgets.directory);
420            XtManageChild(man_globals->manpagewidgets.manpage);
421            man_globals->dir_shown = FALSE;
422        }
423        break;
424    case 'D':
425    case 'd':
426        ChangeLabel(man_globals->label,
427                    man_globals->section_name[man_globals->current_directory]);
428        XtUnmanageChild(man_globals->manpagewidgets.manpage);
429        XtManageChild(man_globals->manpagewidgets.directory);
430        man_globals->dir_shown = TRUE;
431        break;
432    default:
433        XtAppWarning(XtWidgetToApplicationContext(w),
434                     "Xman - GotoPage: Unknown argument must be "
435                     "either Manpage or Directory.");
436        return;
437    }
438}
439
440/*      Function Name: Quit.
441 *      Description: Quits Xman.
442 *      Arguments: w - any widget.
443 *                 event - NOT USED.
444 *                 params, num_params - NOT USED.
445 *      Returns: none.
446 */
447
448/*ARGSUSED*/
449void
450Quit(Widget w, XEvent * event, String * params, Cardinal * num_params)
451{
452    XtAppSetExitFlag(XtWidgetToApplicationContext(w));
453}
454
455/*      Function Name: PopupHelp
456 *      Description: Pops up xman's help.
457 *      Arguments: w - NOT USED.
458 *                 event - NOT USED.
459 *                 params, num_params - NOT USED.
460 *      Returns: none.
461 */
462
463/*ARGSUSED*/
464void
465PopupHelp(Widget w, XEvent * event, String * params, Cardinal * num_params)
466{
467    if (MakeHelpWidget())
468        XtPopup(help_widget, XtGrabNone);
469}
470
471/*      Function Name: PopupSearch
472 *      Description: Pops up this manual pages search widget.
473 *      Arguments: w - any widget in this manpage.
474 *                 event - NOT USED.
475 *                 params, num_params - NOT USED.
476 *      Returns: none.
477 */
478
479/*ARGSUSED*/
480void
481PopupSearch(Widget w, XEvent * event, String * params, Cardinal * num_params)
482{
483    ManpageGlobals *man_globals = GetGlobals(w);
484
485    if (man_globals->search_widget) {
486        if (!XtIsRealized(man_globals->search_widget)) {
487            XtRealizeWidget(man_globals->search_widget);
488            AddCursor(man_globals->search_widget,
489                      resources.cursors.search_entry);
490        }
491        Popup(man_globals->search_widget, XtGrabNone);
492    }
493}
494
495/*      Function Name: CreateNewManpage
496 *      Description: Creates A New Manual Page.
497 *      Arguments: w - NOT USED.
498 *                 event - NOT USED.
499 *                 params, num_params - NOT USED.
500 *      Returns: none.
501 */
502
503/*ARGSUSED*/
504void
505CreateNewManpage(Widget w, XEvent * event, String * params,
506                 Cardinal * num_params)
507{
508    if (CreateManpage(NULL))
509        man_pages_shown++;
510}
511
512/*      Function Name: RemoveThisManpage
513 *      Description: Removes a manual page.
514 *      Arguments: w - any widget in the manpage.
515 *                 event - NOT USED.
516 *                 params, num_params - NOT USED.
517 *      Returns: none.
518 */
519
520/*ARGSUSED*/
521void
522RemoveThisManpage(Widget w, XEvent * event, String * params,
523                  Cardinal * num_params)
524{
525    ManpageGlobals *man_globals = GetGlobals(w);
526
527    if (man_globals->This_Manpage != help_widget) {
528        RemoveGlobals(man_globals->This_Manpage);
529        XtDestroyWidget(man_globals->This_Manpage);
530
531        XtFree((char *) man_globals->section_name);
532        XtFree((char *) man_globals->manpagewidgets.box);
533        XtFree((char *) man_globals);
534
535        if ((--man_pages_shown) == 0)
536            Quit(w, NULL, NULL, NULL);
537    }
538    else
539        XtPopdown(help_widget);
540}
541
542/*      Function Name: Search
543 *      Description: Actually performs a search.
544 *      Arguments: w - any widget in the manpage.
545 *                 event - NOT USED.
546 *                 params, num_params - NOT USED.
547 *      Returns: none.
548 */
549
550/*ARGSUSED*/
551void
552Search(Widget w, XEvent * event, String * params, Cardinal * num_params)
553{
554    ManpageGlobals *man_globals = GetGlobals(w);
555    FILE *file = NULL;
556
557    XtPopdown(XtParent(XtParent(w)));   /* popdown the search widget */
558
559    if ((*num_params < 1) || (*num_params > 2)) {
560        XtAppWarning(XtWidgetToApplicationContext(w),
561                     "Xman - Search: This action routine requires one or two arguments.");
562        return;
563    }
564
565    switch (params[0][0]) {
566    case 'a':
567    case 'A':
568        file = DoSearch(man_globals, APROPOS);
569        break;
570    case 'm':
571    case 'M':
572        file = DoSearch(man_globals, MANUAL);
573        break;
574    case 'c':
575    case 'C':
576        file = NULL;
577        break;
578    default:
579        XtAppWarning(XtWidgetToApplicationContext(w),
580                     "Xman - Search: First parameter unknown.");
581        file = NULL;
582        break;
583    }
584
585    if (*num_params == 2)
586        switch (params[1][0]) {
587        case 'O':
588        case 'o':
589            if (file != NULL) {
590                Widget w2;
591                char *label;
592
593                w2 = CreateManpage(file);
594                if (w2) {
595                    man_pages_shown++;
596
597                    /* Put title into new manual page. */
598
599                    label = man_globals->manpage_title;
600                    man_globals = GetGlobals(w2);
601                    strcpy(man_globals->manpage_title, label);
602                    ChangeLabel(man_globals->label, label);
603                }
604            }
605            break;
606        default:
607            XtAppWarning(XtWidgetToApplicationContext(w),
608                         "Xman - Search: Second parameter unknown.");
609            break;
610        }
611    else {
612        PutUpManpage(man_globals, file);
613    }
614    if ((file != NULL) && (file != man_globals->curr_file)) {
615        fclose(file);
616    }
617}
618
619#ifdef INCLUDE_XPRINT_SUPPORT
620static void
621printshellDestroyXtProc(Widget w, XtPointer client_data, XtPointer callData)
622{
623    ManpageGlobals *mg = GetGlobals(w);
624
625    XawPrintDialogClosePrinterConnection(mg->printdialog, False);
626}
627
628static void
629printOKXtProc(Widget w, XtPointer client_data, XtPointer callData)
630{
631    XawPrintDialogCallbackStruct *pdcs =
632        (XawPrintDialogCallbackStruct *) callData;
633    Cardinal n;
634    Arg args[2];
635    ManpageGlobals *mg = GetGlobals(w);
636    Widget topwindow = mg->This_Manpage;
637    FILE *file;
638
639    Log(("printOKXtProc: OK.\n"));
640
641    /* Get file object */
642    n = 0;
643    XtSetArg(args[n], XtNfile, &file);
644    n++;
645    XtGetValues(mg->manpagewidgets.manpage, args, n);
646    Assertion(file != NULL, (("printOKXtProc: file == NULL.\n")));
647
648    DoPrintManpage("Xman",
649                   file, topwindow,
650                   pdcs->pdpy, pdcs->pcontext, pdcs->colorspace,
651                   printshellDestroyXtProc,
652                   mg->manpage_title,
653                   pdcs->printToFile ? pdcs->printToFileName : NULL);
654
655    XtPopdown(mg->printdialog_shell);
656}
657
658static void
659printCancelXtProc(Widget w, XtPointer client_data, XtPointer callData)
660{
661    ManpageGlobals *mg = GetGlobals(w);
662
663    Log(("printCancelXtProc: cancel.\n"));
664    XtPopdown(mg->printdialog_shell);
665
666    Log(("destroying print dialog shell...\n"));
667    XtDestroyWidget(mg->printdialog_shell);
668    mg->printdialog_shell = NULL;
669    mg->printdialog = NULL;
670    Log(("... done\n"));
671}
672
673/*      Function Name: PrintThisManpage
674 *      Description: Print the current manual page.
675 *      Arguments: mg - manpage globals
676 *      Returns: none.
677 */
678
679/*ARGSUSED*/
680void
681PrintThisManpage(Widget w, XEvent * event, String * params,
682                 Cardinal * num_params)
683{
684    ManpageGlobals *mg = GetGlobals(w);
685    Dimension width, height;
686    Position x, y;
687    Widget parent = mg->This_Manpage;
688    Widget topwindow = mg->This_Manpage;
689
690    Log(("print!\n"));
691
692    if (!mg->printdialog) {
693        int n;
694        Arg args[20];
695
696        n = 0;
697        XtSetArg(args[n], XtNallowShellResize, True);
698        n++;
699        mg->printdialog_shell = XtCreatePopupShell("printdialogshell",
700                                                   transientShellWidgetClass,
701                                                   topwindow, args, n);
702        n = 0;
703        mg->printdialog =
704            XtCreateManagedWidget("printdialog", printDialogWidgetClass,
705                                  mg->printdialog_shell, args, n);
706        XtAddCallback(mg->printdialog, XawNOkCallback, printOKXtProc, NULL);
707        XtAddCallback(mg->printdialog, XawNCancelCallback, printCancelXtProc,
708                      NULL);
709
710        XtRealizeWidget(mg->printdialog_shell);
711    }
712
713    /* Center dialog */
714    XtVaGetValues(mg->printdialog_shell,
715                  XtNwidth, &width, XtNheight, &height, NULL);
716
717    x = (Position) (XWidthOfScreen(XtScreen(parent)) - width) / 2;
718    y = (Position) (XHeightOfScreen(XtScreen(parent)) - height) / 3;
719
720    XtVaSetValues(mg->printdialog_shell, XtNx, x, XtNy, y, NULL);
721
722    XtPopup(mg->printdialog_shell, XtGrabNonexclusive);
723}
724#endif                          /* INCLUDE_XPRINT_SUPPORT */
725
726/*      Function Name: ShowVersion
727 *      Description: Show current version.
728 *      Arguments: w - any widget in the manpage.
729 *                 event - NOT USED.
730 *                 params, num_params - NOT USED.
731 *      Returns: none.
732 */
733
734/*ARGSUSED*/
735void
736ShowVersion(Widget w, XEvent * event, String * params, Cardinal * num_params)
737{
738    ManpageGlobals *man_globals = GetGlobals(w);
739
740    ChangeLabel(man_globals->label, XMAN_VERSION);
741}
742