summaryrefslogtreecommitdiff
path: root/handler.c
diff options
context:
space:
mode:
Diffstat (limited to 'handler.c')
-rw-r--r--handler.c607
1 files changed, 607 insertions, 0 deletions
diff --git a/handler.c b/handler.c
new file mode 100644
index 0000000..da1fd08
--- /dev/null
+++ b/handler.c
@@ -0,0 +1,607 @@
+/* $XConsortium: handler.c,v 1.22 94/12/16 21:36:53 gildea Exp $ */
+/*
+
+Copyright (c) 1987, 1988 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from the X Consortium.
+
+*/
+/* $XFree86: xc/programs/xman/handler.c,v 1.6 2003/01/19 04:44:45 paulo Exp $ */
+
+/*
+ * xman - X window system manual page display program.
+ * Author: Chris D. Peterson, MIT Project Athena
+ * Created: October 29, 1987
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "globals.h"
+#include "vendor.h"
+
+static void PutUpManpage(ManpageGlobals * man_globals, FILE * file);
+static void ToggleBothShownState(ManpageGlobals * man_globals);
+
+/* Function Name: OptionCallback
+ * Description: This is the callback function for the callback menu.
+ * Arguments: w - the widget we are calling back from.
+ * globals_pointer - a pointer to the psuedo globals structure
+ * for this manpage.
+ * junk - (call data) not used.
+ * Returns: none.
+ */
+
+/*ARGSUSED*/
+void
+OptionCallback(Widget w, XtPointer pointer, XtPointer junk)
+{
+ ManpageGlobals * man_globals = (ManpageGlobals *) pointer;
+ String params;
+ Cardinal num_params = 1;
+
+ if ( w == man_globals->search_entry )
+ PopupSearch(XtParent(w), NULL, NULL, NULL);
+ else if (w == man_globals->dir_entry) { /* Put Up Directory */
+ params = "Directory";
+ GotoPage(XtParent(w), NULL, &params, &num_params);
+ }
+ else if (w == man_globals->manpage_entry ) { /* Put Up Man Page */
+ params = "ManualPage";
+ GotoPage(XtParent(w), NULL, &params, &num_params);
+ }
+ else if ( w == man_globals->help_entry ) /* Help */
+ PopupHelp(XtParent(w), NULL, NULL, NULL);
+ else if ( w == man_globals->both_screens_entry ) /*Toggle Both_Shown State.*/
+ ToggleBothShownState(man_globals);
+ else if ( w == man_globals->remove_entry) /* Kill the manpage */
+ RemoveThisManpage(XtParent(w), NULL, NULL, NULL);
+ else if ( w == man_globals->open_entry) /* Open new manpage */
+ CreateNewManpage(XtParent(w), NULL, NULL, NULL);
+ else if ( w == man_globals->version_entry) /* Get version */
+ ShowVersion(XtParent(w), NULL, NULL, NULL);
+ else if ( w == man_globals->quit_entry) /* Quit. */
+ Quit(XtParent(w), NULL, NULL, NULL);
+}
+
+/* Function Name: ToggleBothShownState;
+ * Description: toggles the state of the both shown feature.
+ * Arguments: man_globals - the man globals structure.
+ * Returns: none.
+ */
+
+/*
+ * I did not have a two state widget, which is the way this
+ * should really be done. 1/22/88 - CDP.
+ */
+
+static void
+ToggleBothShownState(ManpageGlobals * man_globals)
+{
+ char * label_str;
+ Arg arglist[1];
+
+ if (man_globals->both_shown == TRUE) {
+ label_str = SHOW_BOTH;
+ if (man_globals->dir_shown)
+ XtUnmanageChild(man_globals->manpagewidgets.manpage);
+ else
+ XtUnmanageChild(man_globals->manpagewidgets.directory);
+ }
+ else {
+ Widget manpage = man_globals->manpagewidgets.manpage;
+ Widget dir = man_globals->manpagewidgets.directory;
+
+ label_str = SHOW_ONE;
+
+ XtSetArg(arglist[0], XtNpreferredPaneSize, resources.directory_height);
+ XtSetValues(dir, arglist, (Cardinal) 1);
+
+ if (!man_globals->dir_shown) {
+ XtUnmanageChild(manpage);
+ XtManageChild(dir);
+ }
+ XtManageChild(manpage);
+ }
+ man_globals->both_shown = !man_globals->both_shown;
+
+ if (man_globals->dir_shown)
+ ChangeLabel(man_globals->label,
+ man_globals->section_name[man_globals->current_directory]);
+ else
+ ChangeLabel(man_globals->label, man_globals->manpage_title);
+
+ XtSetArg(arglist[0], XtNlabel, label_str);
+ XtSetValues(man_globals->both_screens_entry, arglist, ONE);
+
+ /* if both are shown there is no need to switch between the two. */
+
+ XtSetArg(arglist[0], XtNsensitive, !man_globals->both_shown);
+ XtSetValues(man_globals->manpage_entry, arglist, ONE);
+ XtSetValues(man_globals->dir_entry, arglist, ONE);
+}
+
+/* Function Name: Popup
+ * Description: This function pops up the given widget under the cursor.
+ * Arguments: w - the widget to popup.
+ * grab_kind - the kind of grab to register.
+ * Returns: none
+ */
+
+/* How far off the top of the widget to have the initial cursor postion. */
+
+#define OFF_OF_TOP 25
+
+void
+Popup(Widget w, XtGrabKind grab_kind)
+{
+ int x_root,y_root,y_pos,garbage;
+ unsigned int mask;
+ Window junk_window;
+
+ XQueryPointer(XtDisplay(w), XtWindow(w), &junk_window, &junk_window,
+ &x_root, &y_root, &garbage, &garbage, &mask);
+
+ y_pos = OFF_OF_TOP - Height(w)/2 - BorderWidth(w);
+ PositionCenter(w, x_root, y_root, y_pos, 0, 2, 2);
+ XtPopup(w, grab_kind);
+}
+
+/* Function Name: PutUpManpage
+ * Description: Puts the manpage on the display.
+ * Arguments: man_globals - a pointer to the psuedo globals structure
+ * for this manpage.
+ * file - the file to display.
+ * Returns: none.
+ */
+
+static void
+PutUpManpage(ManpageGlobals * man_globals, FILE * file)
+{
+ String params = "ManualPage";
+ Cardinal num_params = 1;
+
+ if (file == NULL)
+ return;
+
+ OpenFile(man_globals, file);
+
+ if (!man_globals->both_shown) {
+ Arg arglist[1];
+ XtSetArg(arglist[0], XtNsensitive, TRUE);
+ XtSetValues(man_globals->manpage_entry, arglist, ONE);
+ XtSetValues(man_globals->both_screens_entry, arglist, ONE);
+ }
+ GotoPage(man_globals->manpagewidgets.manpage, NULL, &params, &num_params);
+}
+
+/* Function Name: DirectoryHandler
+ * Description: This is the callback function for the directory listings.
+ * Arguments: w - the widget we are calling back from.
+ * global_pointer - the pointer to the psuedo global structure
+ * associated with this manpage.
+ * ret_val - return value from the list widget.
+ * Returns: none.
+ */
+
+void
+DirectoryHandler(Widget w, XtPointer global_pointer, XtPointer ret_val)
+{
+ FILE * file; /* The manpage file. */
+ ManpageGlobals * man_globals = (ManpageGlobals *) global_pointer;
+ XawListReturnStruct * ret_struct = (XawListReturnStruct *) ret_val;
+
+ file = FindManualFile(man_globals, man_globals->current_directory,
+ ret_struct->list_index);
+ PutUpManpage(man_globals, file);
+}
+
+/* Function Name: DirPopupCallback
+ * Description: This is the callback function for the callback menu.
+ * Arguments: w - the widget we are calling back from.
+ * pointer - a pointer to the psuedo globals structure
+ * for this manpage.
+ * junk - (call data) not used.
+ * Returns: none.
+ */
+
+/*ARGSUSED*/
+void
+DirPopupCallback(Widget w, XtPointer pointer, XtPointer junk)
+{
+ ManpageGlobals * man_globals;
+ MenuStruct * menu_struct;
+ Widget parent;
+ int number;
+ int current_box;
+
+ menu_struct = (MenuStruct *) pointer;
+ man_globals = (ManpageGlobals *) menu_struct->data;
+
+ number = menu_struct->number;
+ current_box = man_globals->current_directory;
+
+ /* We have used this guy, pop down the menu. */
+
+ if (number != current_box) {
+ /* This is the only one that we know has a parent. */
+ parent = XtParent(man_globals->manpagewidgets.box[INITIAL_DIR]);
+
+ MakeDirectoryBox(man_globals, parent,
+ man_globals->manpagewidgets.box + number, number);
+ XtUnmanageChild(man_globals->manpagewidgets.box[current_box]);
+ XtManageChild(man_globals->manpagewidgets.box[number]);
+
+ XawListUnhighlight(man_globals->manpagewidgets.box[current_box]);
+ ChangeLabel(man_globals->label, man_globals->section_name[number]);
+ man_globals->current_directory = number;
+ }
+
+ /* put up directory. */
+ if (!man_globals->both_shown) {
+ XtUnmanageChild(man_globals->manpagewidgets.manpage);
+ XtManageChild(man_globals->manpagewidgets.directory);
+ }
+}
+
+/************************************************************
+ *
+ * Action Routines.
+ *
+ ************************************************************/
+
+/* Function Name: SaveFormattedPage
+ * Description: This is the action routine may save the manpage.
+ * Arguments: w - any widget in the widget tree.
+ * event - NOT USED.
+ * params, num_params - the parameters paseed to the action
+ * routine, can be either Manpage or
+ * Directory.
+ * Returns: none.
+ */
+
+/*ARGSUSED*/
+void
+SaveFormattedPage(Widget w, XEvent * event, String * params, Cardinal * num_params)
+{
+ ManpageGlobals * man_globals;
+ char cmdbuf[BUFSIZ], error_buf[BUFSIZ];
+
+ if (*num_params != 1) {
+ XtAppWarning(XtWidgetToApplicationContext(w),
+ "Xman - SaveFormattedPage: This action routine requires one argument.");
+ return;
+ }
+
+ man_globals = GetGlobals(w);
+
+/*
+ * If we are not active then take no action.
+ */
+
+ if (man_globals->tempfile == '\0') return;
+
+ switch (params[0][0]) {
+ case 'S':
+ case 's':
+
+#ifndef NO_COMPRESS
+ if (!man_globals->compress)
+#endif
+
+ sprintf(cmdbuf, "%s %s %s", COPY, man_globals->tempfile,
+ man_globals->save_file);
+
+#ifndef NO_COMPRESS
+ else
+ if (man_globals->gzip)
+ sprintf(cmdbuf, "%s < %s > %s", GZIP_COMPRESS, man_globals->tempfile,
+ man_globals->save_file);
+ else
+ sprintf(cmdbuf, "%s < %s > %s", COMPRESS, man_globals->tempfile,
+ man_globals->save_file);
+#endif
+
+ if(! system(cmdbuf)) {
+ /* make sure the formatted man page is fully accessible by the world */
+ if (chmod(man_globals->save_file, CHMOD_MODE) != 0) {
+ sprintf(error_buf,
+ "Couldn't set permissions on formatted man page '%s'.\n",
+ man_globals->save_file);
+ PopupWarning( man_globals, error_buf);
+ }
+ } else {
+ sprintf(error_buf, "Error while executing the command '%s'.\n",
+ cmdbuf);
+ PopupWarning( man_globals, error_buf);
+ }
+ break;
+ case 'C':
+ case 'c':
+ break;
+ default:
+ sprintf(error_buf,"%s %s", "Xman - SaveFormattedPagee:",
+ "Unknown argument must be either 'Save' or 'Cancel'.");
+ PopupWarning(man_globals, error_buf);
+ return;
+ }
+
+/*
+ * We do not need the filename anymore, and have the fd open.
+ * We will unlink it.
+ */
+
+ unlink(man_globals->tempfile);
+ XtPopdown( XtParent(XtParent(w)) );
+}
+
+/* Function Name: GotoPage
+ * Description: The Action routine that switches over to the manpage
+ * or directory.
+ * Arguments: w - any widget in the widget tree.
+ * event - NOT USED.
+ * params, num_params - the parameters paseed to the action
+ * routine, can be either Manpage or
+ * Directory.
+ * Returns: none.
+ */
+
+/*ARGSUSED*/
+void
+GotoPage(Widget w, XEvent * event, String * params, Cardinal * num_params)
+{
+ ManpageGlobals * man_globals;
+ char error_buf[BUFSIZ];
+ Arg arglist[1];
+ Boolean sensitive;
+
+ if (*num_params != 1) {
+ XtAppWarning(XtWidgetToApplicationContext(w),
+ "Xman - GotoPage: This action routine requires one argument.");
+ return;
+ }
+
+ man_globals = GetGlobals(w);
+
+ if (man_globals->both_shown) {
+ ChangeLabel(man_globals->label,
+ man_globals->section_name[man_globals->current_directory]);
+ return;
+ }
+
+ switch (params[0][0]) {
+ case 'M':
+ case 'm':
+ XtSetArg(arglist[0], XtNsensitive, &sensitive);
+ XtGetValues(man_globals->manpage_entry, arglist, ONE);
+ if (sensitive) {
+ ChangeLabel(man_globals->label,man_globals->manpage_title);
+ XtUnmanageChild(man_globals->manpagewidgets.directory);
+ XtManageChild(man_globals->manpagewidgets.manpage);
+ man_globals->dir_shown = FALSE;
+ }
+ break;
+ case 'D':
+ case 'd':
+ ChangeLabel(man_globals->label,
+ man_globals->section_name[man_globals->current_directory]);
+ XtUnmanageChild(man_globals->manpagewidgets.manpage);
+ XtManageChild(man_globals->manpagewidgets.directory);
+ man_globals->dir_shown = TRUE;
+ break;
+ default:
+ sprintf(error_buf,"%s %s", "Xman - GotoPage: Unknown argument must be",
+ "either Manpage or Directory.");
+ XtAppWarning(XtWidgetToApplicationContext(w), error_buf);
+ return;
+ }
+}
+
+/* Function Name: Quit.
+ * Description: Quits Xman.
+ * Arguments: w - any widget.
+ * event - NOT USED.
+ * params, num_params - NOT USED.
+ * Returns: none.
+ */
+
+/*ARGSUSED*/
+void
+Quit(Widget w, XEvent * event, String * params, Cardinal * num_params)
+{
+ XCloseDisplay(XtDisplay(w));
+ exit(0);
+}
+
+/* Function Name: PopupHelp
+ * Description: Pops up xman's help.
+ * Arguments: w - NOT USED.
+ * event - NOT USED.
+ * params, num_params - NOT USED.
+ * Returns: none.
+ */
+
+/*ARGSUSED*/
+void
+PopupHelp(Widget w, XEvent * event, String * params, Cardinal * num_params)
+{
+ if (MakeHelpWidget())
+ XtPopup(help_widget,XtGrabNone);
+}
+
+/* Function Name: PopupSearch
+ * Description: Pops up this manual pages search widget.
+ * Arguments: w - any widget in this manpage.
+ * event - NOT USED.
+ * params, num_params - NOT USED.
+ * Returns: none.
+ */
+
+/*ARGSUSED*/
+void
+PopupSearch(Widget w, XEvent * event, String * params, Cardinal * num_params)
+{
+ ManpageGlobals * man_globals = GetGlobals(w);
+
+ if (man_globals->search_widget) {
+ if (!XtIsRealized(man_globals->search_widget)) {
+ XtRealizeWidget(man_globals->search_widget);
+ AddCursor(man_globals->search_widget, resources.cursors.search_entry);
+ }
+ Popup(man_globals->search_widget, XtGrabNone);
+ }
+}
+
+/* Function Name: CreateNewManpage
+ * Description: Creates A New Manual Page.
+ * Arguments: w - NOT USED.
+ * event - NOT USED.
+ * params, num_params - NOT USED.
+ * Returns: none.
+ */
+
+/*ARGSUSED*/
+void
+CreateNewManpage(Widget w, XEvent * event, String * params, Cardinal * num_params)
+{
+ (void) CreateManpage(NULL);
+ man_pages_shown++;
+}
+
+/* Function Name: RemoveThisManpage
+ * Description: Removes a manual page.
+ * Arguments: w - any widget in the manpage.
+ * event - NOT USED.
+ * params, num_params - NOT USED.
+ * Returns: none.
+ */
+
+/*ARGSUSED*/
+void
+RemoveThisManpage(Widget w, XEvent * event, String * params, Cardinal * num_params)
+{
+ ManpageGlobals * man_globals = GetGlobals(w);
+
+ if (man_globals->This_Manpage != help_widget) {
+ RemoveGlobals(man_globals->This_Manpage);
+ XtDestroyWidget(man_globals->This_Manpage);
+
+ XtFree( (char *) man_globals->section_name);
+ XtFree( (char *) man_globals->manpagewidgets.box);
+ XtFree( (char *) man_globals);
+
+ if ( (--man_pages_shown) == 0)
+ Quit(w, NULL, NULL, NULL);
+ }
+ else
+ XtPopdown(help_widget);
+}
+
+/* Function Name: Search
+ * Description: Actually performs a search.
+ * Arguments: w - any widget in the manpage.
+ * event - NOT USED.
+ * params, num_params - NOT USED.
+ * Returns: none.
+ */
+
+/*ARGSUSED*/
+void
+Search(Widget w, XEvent * event, String * params, Cardinal * num_params)
+{
+ ManpageGlobals * man_globals = GetGlobals(w);
+ FILE * file;
+
+ XtPopdown( XtParent(XtParent(w)) ); /* popdown the search widget */
+
+ if ( (*num_params < 1) || (*num_params > 2) ) {
+ XtAppWarning(XtWidgetToApplicationContext(w),
+ "Xman - Search: This action routine requires one or two arguments.");
+ return;
+ }
+
+ switch(params[0][0]) {
+ case 'a':
+ case 'A':
+ file = DoSearch(man_globals,APROPOS);
+ break;
+ case 'm':
+ case 'M':
+ file = DoSearch(man_globals,MANUAL);
+ break;
+ case 'c':
+ case 'C':
+ file = NULL;
+ break;
+ default:
+ XtAppWarning(XtWidgetToApplicationContext(w),
+ "Xman - Search: First parameter unknown.");
+ file = NULL;
+ break;
+ }
+
+ if ( *num_params == 2 )
+ switch (params[1][0]) {
+ case 'O':
+ case 'o':
+ if (file != NULL) {
+ Widget w;
+ char * label;
+
+ w = CreateManpage(file);
+ man_pages_shown++;
+
+ /* Put title into new manual page. */
+
+ label = man_globals->manpage_title;
+ man_globals = GetGlobals(w);
+ strcpy(man_globals->manpage_title, label);
+ ChangeLabel(man_globals->label, label);
+ }
+ break;
+ default:
+ XtAppWarning(XtWidgetToApplicationContext(w),
+ "Xman - Search: Second parameter unknown.");
+ break;
+ }
+ else {
+ PutUpManpage(man_globals, file);
+ }
+}
+
+/* Function Name: ShowVersion
+ * Description: Show current version.
+ * Arguments: w - any widget in the manpage.
+ * event - NOT USED.
+ * params, num_params - NOT USED.
+ * Returns: none.
+ */
+
+/*ARGSUSED*/
+void
+ShowVersion(Widget w, XEvent * event, String * params, Cardinal * num_params)
+{
+ ManpageGlobals * man_globals = GetGlobals(w);
+ ChangeLabel(man_globals->label, XMAN_VERSION);
+}