1
/* $XConsortium: buttons.c,v 1.33 94/04/17 20:43:50 dave Exp $ */
4
Copyright (c) 1987, 1988 X Consortium
6
Permission is hereby granted, free of charge, to any person obtaining
7
a copy of this software and associated documentation files (the
8
"Software"), to deal in the Software without restriction, including
9
without limitation the rights to use, copy, modify, merge, publish,
10
distribute, sublicense, and/or sell copies of the Software, and to
11
permit persons to whom the Software is furnished to do so, subject to
12
the following conditions:
14
The above copyright notice and this permission notice shall be included
15
in all copies or substantial portions of the Software.
17
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20
IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
21
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
OTHER DEALINGS IN THE SOFTWARE.
25
Except as contained in this notice, the name of the X Consortium shall
26
not be used in advertising or otherwise to promote the sale, use or
27
other dealings in this Software without prior written authorization
28
from the X Consortium.
31
/* $XFree86: xc/programs/xman/buttons.c,v 1.4 2003/01/19 04:44:45 paulo Exp $ */
34
* xman - X window system manual page display program.
35
* Author: Chris D. Peterson, MIT Project Athena
36
* Created: October 27, 1987
42
/* The files with the icon bits in them. */
44
#include "icon_open.h"
45
#include "icon_help.h"
46
#include "iconclosed.h"
48
static void CreateOptionMenu(ManpageGlobals * man_globals, Widget parent);
49
static void CreateSectionMenu(ManpageGlobals * man_globals, Widget parent);
50
static void StartManpage(ManpageGlobals * man_globals, Boolean help, Boolean page);
51
static Widget * ConvertNamesToWidgets(Widget parent, char ** names);
53
/* Function Name: MakeTopBox
54
* Description: This funtion creates the top menu, in a shell widget.
56
* Returns: the top level widget
61
extern Atom wm_delete_window; /* in main.c */
63
Widget top; /* needed in PopupWarning, misc.c */
68
Widget form, command, label; /* widgets. */
69
Arg arglist[TOPARGS]; /* An argument list */
70
Cardinal num_args = 0; /* The number of arguments. */
71
ManpageGlobals * man_globals;
72
static char * full_size[] = {
73
"topLabel", MANPAGE_BUTTON, NULL
75
static char * half_size[] = {
76
HELP_BUTTON, QUIT_BUTTON, NULL
79
/* create the top icon. */
82
XtSetArg(arglist[num_args], XtNiconPixmap,
83
XCreateBitmapFromData( XtDisplay(initial_widget),
84
XtScreen(initial_widget)->root,
85
(char *)iconclosed_bits, iconclosed_width,
88
XtSetArg(arglist[num_args], XtNtitle, resources.title);
90
XtSetArg(arglist[num_args], XtNiconic, resources.iconic);
92
top = XtCreatePopupShell(TOPBOXNAME, topLevelShellWidgetClass,
93
initial_widget, arglist, num_args);
95
form = XtCreateManagedWidget("form", formWidgetClass, top,
98
label = XtCreateManagedWidget("topLabel", labelWidgetClass, form,
102
XtSetArg(arglist[num_args], XtNfromVert, label); num_args++;
103
command = XtCreateManagedWidget(HELP_BUTTON, commandWidgetClass, form,
106
/* use same vertical as help widget. */
107
XtSetArg(arglist[num_args], XtNfromHoriz, command); num_args++;
108
command = XtCreateManagedWidget(QUIT_BUTTON, commandWidgetClass, form,
112
XtSetArg(arglist[num_args], XtNfromVert, command); num_args++;
113
command = XtCreateManagedWidget(MANPAGE_BUTTON, commandWidgetClass, form,
116
help_widget = NULL; /* We have not seen the help yet. */
118
FormUpWidgets(form, full_size, half_size);
120
XtRealizeWidget(top);
121
/* add WM_COMMAND property */
122
XSetCommand(XtDisplay(top), XtWindow(top), saved_argv, saved_argc);
124
man_globals = (ManpageGlobals*) XtMalloc( (Cardinal) sizeof(ManpageGlobals));
125
man_globals->label = NULL;
126
man_globals->search_widget = NULL;
127
man_globals->manpagewidgets.directory = NULL;
128
man_globals->manpagewidgets.manpage = NULL;
129
man_globals->manpagewidgets.box = NULL;
130
man_globals->current_directory = 0;
131
MakeSearchWidget(man_globals, top);
132
MakeSaveWidgets(man_globals, top);
134
SaveGlobals( (man_globals->This_Manpage = top), man_globals);
136
AddCursor(top, resources.cursors.top);
139
* Set up ICCCM delete window.
141
XtOverrideTranslations
142
(top, XtParseTranslationTable ("<Message>WM_PROTOCOLS: Quit()"));
143
(void) XSetWMProtocols (XtDisplay(top), XtWindow(top),
144
&wm_delete_window, 1);
149
/* Function Name: CreateManpage
150
* Description: Creates a new manpage.
156
CreateManpage(FILE * file)
158
ManpageGlobals * man_globals; /* The psuedo global structure. */
160
man_globals = InitPsuedoGlobals();
161
CreateManpageWidget(man_globals, MANNAME, TRUE);
164
StartManpage( man_globals, OpenHelpfile(man_globals), FALSE );
166
OpenFile(man_globals, file);
167
StartManpage( man_globals, FALSE, TRUE);
169
return(man_globals->This_Manpage);
172
/* Function Name: InitPsuedoGlobals
173
* Description: Initializes the psuedo global variables.
175
* Returns: a pointer to a new pseudo globals structure.
179
InitPsuedoGlobals(void)
181
ManpageGlobals * man_globals;
184
* Allocate necessary memory.
187
man_globals = (ManpageGlobals *)
188
XtMalloc( (Cardinal) sizeof(ManpageGlobals));
190
man_globals->search_widget = NULL;
191
man_globals->section_name = (char **) XtMalloc( (Cardinal) (sections *
193
man_globals->manpagewidgets.box = (Widget *) XtCalloc( (Cardinal) sections,
194
(Cardinal) sizeof(Widget));
196
/* Initialize the number of screens that will be shown */
198
man_globals->both_shown = resources.both_shown_initial;
203
/* Function Name: CreateManpageWidget
204
* Description: Creates a new manual page widget.
205
* Arguments: man_globals - a new man_globals structure.
206
* name - name of this shell widget instance.
207
* full_instance - if true then create a full manpage,
208
* otherwise create stripped down version
213
#define MANPAGEARGS 10
217
ManpageGlobals * man_globals,
219
Boolean full_instance)
221
Arg arglist[MANPAGEARGS]; /* An argument list for widget creation */
222
Cardinal num_args; /* The number of arguments in the list. */
223
Widget mytop, pane, hpane, mysections; /* Widgets */
224
ManPageWidgets * mpw = &(man_globals->manpagewidgets);
226
num_args = (Cardinal) 0;
227
XtSetArg(arglist[num_args], XtNwidth, default_width);
229
XtSetArg(arglist[num_args], XtNheight, default_height);
232
mytop = XtCreatePopupShell(name, topLevelShellWidgetClass, initial_widget,
235
man_globals->This_Manpage = mytop; /* pointer to root widget of Manualpage. */
238
XtSetArg(arglist[num_args], XtNiconPixmap,
239
XCreateBitmapFromData( XtDisplay(mytop), XtScreen(mytop)->root,
240
(char *)icon_open_bits, icon_open_width,
243
XtSetArg(arglist[num_args], XtNiconPixmap,
244
XCreateBitmapFromData( XtDisplay(mytop), XtScreen(mytop)->root,
245
(char *)icon_help_bits, icon_help_width,
248
XtSetValues(mytop, arglist, num_args);
250
pane = XtCreateManagedWidget("vertPane", panedWidgetClass, mytop, NULL,
253
/* Create menu bar. */
255
hpane = XtCreateManagedWidget("horizPane", panedWidgetClass,
256
pane, NULL, (Cardinal) 0);
258
XtSetArg(arglist[num_args], XtNmenuName, OPTION_MENU); num_args++;
259
(void) XtCreateManagedWidget("options", menuButtonWidgetClass,
260
hpane, arglist, num_args);
262
CreateOptionMenu(man_globals, mytop);
265
XtSetArg(arglist[num_args], XtNmenuName, SECTION_MENU); num_args++;
266
mysections = XtCreateManagedWidget("sections", menuButtonWidgetClass,
267
hpane, arglist, num_args);
269
XtSetArg(arglist[0], XtNlabel, SHOW_BOTH);
270
XtSetValues(man_globals->both_screens_entry, arglist, (Cardinal) 1);
273
MakeSearchWidget(man_globals, mytop);
274
CreateSectionMenu(man_globals, mytop);
275
MakeSaveWidgets(man_globals, mytop);
277
XtSetSensitive(mysections, FALSE);
278
XtSetArg(arglist[0], XtNsensitive, FALSE);
279
XtSetValues(man_globals->dir_entry, arglist, ONE);
280
XtSetValues(man_globals->manpage_entry, arglist, ONE);
281
XtSetValues(man_globals->help_entry, arglist, ONE);
282
XtSetValues(man_globals->search_entry, arglist, ONE);
283
XtSetValues(man_globals->both_screens_entry, arglist, ONE);
286
man_globals->label = XtCreateManagedWidget("manualTitle", labelWidgetClass,
287
hpane, NULL, (Cardinal) 0);
289
/* Create Directory */
293
XtSetArg(arglist[num_args], XtNallowVert, TRUE);
296
mpw->directory = XtCreateWidget(DIRECTORY_NAME, viewportWidgetClass,
297
pane, arglist, num_args);
299
man_globals->current_directory = INITIAL_DIR;
300
MakeDirectoryBox(man_globals, mpw->directory,
301
mpw->box + man_globals->current_directory,
302
man_globals->current_directory );
303
XtManageChild(mpw->box[man_globals->current_directory]);
308
mpw->manpage = XtCreateWidget(MANUALPAGE, scrollByLineWidgetClass,
309
pane, NULL, (Cardinal) 0);
313
/* Function Name: StartManpage
314
* Description: Starts up a new manpage.
315
* Arguments: man_globals - the psuedo globals variable.
316
* help - is this a help file?
317
* page - Is there a page to display?
322
StartManpage(ManpageGlobals * man_globals, Boolean help, Boolean page)
324
Widget dir = man_globals->manpagewidgets.directory;
325
Widget manpage = man_globals->manpagewidgets.manpage;
326
Widget label = man_globals->label;
330
* If there is a helpfile then put up both screens if both_show is set.
335
strcpy(man_globals->manpage_title, "Xman Help");
337
if (man_globals->both_shown) {
339
man_globals->dir_shown = TRUE;
341
XtSetArg(arglist[0], XtNpreferredPaneSize, resources.directory_height);
342
XtSetValues(dir, arglist, (Cardinal) 1);
344
XtSetArg(arglist[0], XtNsensitive, FALSE);
345
XtSetValues(man_globals->manpage_entry, arglist, ONE);
346
XtSetValues(man_globals->dir_entry, arglist, ONE);
348
XtSetArg(arglist[0], XtNlabel, SHOW_ONE);
349
XtSetValues(man_globals->both_screens_entry, arglist, ONE);
351
man_globals->section_name[man_globals->current_directory]);
354
ChangeLabel(label,man_globals->manpage_title);
356
XtManageChild(manpage);
357
man_globals->dir_shown = FALSE;
360
* Since There is file to display, put up directory and do not allow change
361
* to manpage, show both, or help.
365
man_globals->dir_shown = TRUE;
366
XtSetArg(arglist[0], XtNsensitive, FALSE);
367
XtSetValues(man_globals->manpage_entry, arglist, ONE);
368
XtSetValues(man_globals->help_entry, arglist, ONE);
369
XtSetValues(man_globals->both_screens_entry, arglist, ONE);
370
man_globals->both_shown = FALSE;
372
man_globals->section_name[man_globals->current_directory]);
376
* Start 'er up, and change the cursor.
379
XtRealizeWidget( man_globals->This_Manpage );
380
SaveGlobals( man_globals->This_Manpage, man_globals);
381
XtMapWidget( man_globals->This_Manpage );
382
AddCursor( man_globals->This_Manpage, resources.cursors.manpage);
383
XtSetArg(arglist[0], XtNtransientFor, man_globals->This_Manpage);
384
XtSetValues(XtParent(man_globals->standby), arglist, (Cardinal)1);
385
XtSetValues(XtParent(man_globals->save), arglist, (Cardinal) 1);
386
XtRealizeWidget(XtParent(man_globals->standby));
387
XtRealizeWidget(XtParent(man_globals->save));
388
AddCursor( XtParent(man_globals->standby), resources.cursors.top);
389
AddCursor( XtParent(man_globals->save), resources.cursors.top);
392
* Set up ICCCM delete window.
394
XtOverrideTranslations
395
(man_globals->This_Manpage,
396
XtParseTranslationTable ("<Message>WM_PROTOCOLS: RemoveThisManpage()"));
397
(void) XSetWMProtocols (XtDisplay(man_globals->This_Manpage),
398
XtWindow(man_globals->This_Manpage),
399
&wm_delete_window, 1);
403
/* Function Name: MenuDestroy
404
* Description: free's data associated with menu when it is destroyed.
405
* Arguments: w - menu widget.
406
* free_me - data to free.
413
MenuDestroy(Widget w, XtPointer free_me, XtPointer junk)
415
XtFree( (char *) free_me);
418
/* Function Name: CreateOptionMenu
419
* Description: Create the option menu.
420
* Arguments: man_globals - the manual page globals.
421
* parent - the button that activates the menu.
426
CreateOptionMenu(ManpageGlobals * man_globals, Widget parent)
430
static char * option_names[] = { /* Names of the buttons. */
442
menu = XtCreatePopupShell(OPTION_MENU, simpleMenuWidgetClass, parent,
444
man_globals->option_menu = menu;
446
for (i = 0 ; i < NUM_OPTIONS ; i++) {
447
entry = XtCreateManagedWidget(option_names[i], smeBSBObjectClass,
449
XtAddCallback(entry, XtNcallback, OptionCallback, (caddr_t) man_globals);
452
man_globals->dir_entry = entry;
455
man_globals->manpage_entry = entry;
458
man_globals->help_entry = entry;
461
man_globals->search_entry = entry;
464
man_globals->both_screens_entry = entry;
467
man_globals->remove_entry = entry;
470
man_globals->open_entry = entry;
473
man_globals->version_entry = entry;
476
man_globals->quit_entry = entry;
484
/* Function Name: CreateSectionMenu
485
* Description: Create the Section menu.
486
* Arguments: man_globals - the manual page globals.
487
* parent - the button that activates the menu.
492
CreateSectionMenu(ManpageGlobals * man_globals, Widget parent)
496
MenuStruct * menu_struct;
499
char entry_name[BUFSIZ];
501
menu = XtCreatePopupShell(SECTION_MENU, simpleMenuWidgetClass, parent,
504
for (i = 0 ; i < sections ; i ++) {
506
XtSetArg(args[num_args], XtNlabel, manual[i].blabel); num_args++;
507
sprintf(entry_name, "section%d", i);
509
entry = XtCreateManagedWidget(entry_name, smeBSBObjectClass,
510
menu, args, num_args);
511
menu_struct = (MenuStruct *) XtMalloc(sizeof(MenuStruct));
512
menu_struct->data = (caddr_t) man_globals;
513
menu_struct->number = i;
514
XtAddCallback(entry, XtNcallback, DirPopupCallback, (caddr_t) menu_struct);
515
XtAddCallback(entry, XtNdestroyCallback,MenuDestroy, (caddr_t)menu_struct);
520
/* Function Name: CreateList
521
* Description: this function prints a label in the directory list
522
* Arguments: section - the manual section.
527
CreateList(int section)
529
char ** ret_list, **current;
532
ret_list = (char **) XtMalloc( (manual[section].nentries + 1) *
535
for (current = ret_list, count = 0 ; count < manual[section].nentries ;
537
*current = CreateManpageName(manual[section].entries[count], section,
538
manual[section].flags);
540
*current = NULL; /* NULL terminate the list. */
544
/* Function Name: MakeDirectoryBox
545
* Description: make a directory box.
546
* Arguments: man_globals - the psuedo global structure for each manpage.
547
* parent - this guys parent widget.
548
* dir_disp - the directory display widget.
549
* section - the section number.
554
MakeDirectoryBox(ManpageGlobals *man_globals, Widget parent, Widget *dir_disp, int section)
558
char * name, label_name[BUFSIZ];
560
if (*dir_disp != NULL) /* If we have one, don't make another. */
563
name = manual[section].blabel; /* Set the section name */
564
sprintf(label_name,"Directory of: %s",name);
565
man_globals->section_name[section] = StrAlloc(label_name);
568
XtSetArg(arglist[num_args], XtNlist, CreateList(section));
570
XtSetArg(arglist[num_args], XtNfont, resources.fonts.directory);
573
*dir_disp = XtCreateWidget(DIRECTORY_NAME, listWidgetClass, parent,
576
XtAddCallback(*dir_disp, XtNcallback,
577
DirectoryHandler, (caddr_t) man_globals);
580
/* Function Name: MakeSaveWidgets.
581
* Description: This functions creates two popup widgets, the please
582
* standby widget and the would you like to save widget.
583
* Arguments: man_globals - the psuedo globals structure for each man page
584
* parent - the realized parent for both popups.
589
MakeSaveWidgets(ManpageGlobals *man_globals, Widget parent)
591
Widget shell, dialog; /* misc. widgets. */
595
/* make the please stand by popup widget. */
596
if (XtIsRealized(parent)) {
597
XtSetArg(warg[0], XtNtransientFor, parent); n++;
599
shell = XtCreatePopupShell( "pleaseStandBy", transientShellWidgetClass,
600
parent, warg, (Cardinal) n);
602
man_globals->standby = XtCreateManagedWidget("label", labelWidgetClass,
603
shell, NULL, (Cardinal) 0);
605
man_globals->save = XtCreatePopupShell("likeToSave",
606
transientShellWidgetClass,
609
dialog = XtCreateManagedWidget("dialog", dialogWidgetClass,
610
man_globals->save, NULL, (Cardinal) 0);
612
XawDialogAddButton(dialog, FILE_SAVE, NULL, NULL);
613
XawDialogAddButton(dialog, CANCEL_FILE_SAVE, NULL, NULL);
615
if (XtIsRealized(parent)) {
616
XtRealizeWidget(shell);
617
AddCursor(shell,resources.cursors.top);
618
XtRealizeWidget(man_globals->save);
619
AddCursor(man_globals->save, resources.cursors.top);
623
/* Function Name: FormUpWidgets
624
* Description: Sizes widgets to look nice.
625
* Arguments: parent - the common parent of all the widgets.
626
* full_size - array of widget names that will he full size.
627
* half_size - array of widget names that will he half size.
632
FormUpWidgets(Widget parent, char ** full_size, char ** half_size)
634
Widget * full_widgets, * half_widgets, *temp, long_widget;
635
Dimension longest, length, b_width;
639
full_widgets = ConvertNamesToWidgets(parent, full_size);
640
half_widgets = ConvertNamesToWidgets(parent, half_size);
644
XtSetArg(arglist[0], XtNwidth, &length);
645
XtSetArg(arglist[1], XtNborderWidth, &b_width);
648
* Find Longest widget.
651
for ( temp = full_widgets ; *temp != (Widget) NULL ; temp++) {
652
XtGetValues(*temp, arglist, (Cardinal) 2);
653
length += 2 * b_width;
654
if (length > longest) {
660
if (long_widget == (Widget) NULL) { /* Make sure we found one. */
661
PopupWarning(GetGlobals(parent),
662
"Could not find longest widget, aborting...");
663
XtFree((char *)full_widgets);
664
XtFree((char *)half_widgets);
669
* Set all other full_widgets to this length.
672
for ( temp = full_widgets ; *temp != (Widget) NULL ; temp++ )
673
if ( long_widget != *temp) {
674
Dimension width, border_width;
676
XtSetArg(arglist[0], XtNborderWidth, &border_width);
677
XtGetValues(*temp, arglist, (Cardinal) 1);
679
width = longest - 2 * border_width;
680
XtSetArg(arglist[0], XtNwidth, width);
681
XtSetValues(*temp, arglist, (Cardinal) 1);
685
* Set all the half widgets to the right length.
688
XtSetArg(arglist[0], XtNdefaultDistance, &interior_dist);
689
XtGetValues(parent, arglist, (Cardinal) 1);
691
for ( temp = half_widgets ; *temp != (Widget) NULL ; temp++) {
692
Dimension width, border_width;
694
XtSetArg(arglist[0], XtNborderWidth, &border_width);
695
XtGetValues(*temp, arglist, (Cardinal) 1);
697
width = (int)(longest - interior_dist)/2 - 2 * border_width;
698
XtSetArg(arglist[0], XtNwidth, width);
699
XtSetValues(*temp, arglist, (Cardinal) 1);
702
XtFree((char *)full_widgets);
703
XtFree((char *)half_widgets);
706
/* Function Name: ConvertNamesToWidgets
707
* Description: Convers a list of names into a list of widgets.
708
* Arguments: parent - the common parent of these widgets.
709
* names - an array of widget names.
710
* Returns: an array of widget id's.
714
ConvertNamesToWidgets(Widget parent, char ** names)
717
Widget * ids, * temp_ids;
720
for (count = 0, temp = names; *temp != NULL ; count++, temp++);
722
ids = (Widget *) XtMalloc( (count + 1) * sizeof(Widget));
725
for ( temp_ids = ids; *names != NULL ; names++, temp_ids++) {
726
*temp_ids = XtNameToWidget(parent, *names);
727
if (*temp_ids == NULL) {
728
char error_buf[BUFSIZ];
730
sprintf(error_buf, "Could not find widget named '%s'", *names);
731
PrintError(error_buf);
737
*temp_ids = (Widget) NULL;