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