/* Written by Dan Heller and Paula Ferguson. * Copyright 1994, O'Reilly & Associates, Inc. * Permission to use, copy, and modify this program without * restriction is hereby granted, as long as this copyright * notice appears in each copy of the program source code. * This program is freely distributable without licensing fees and * is provided without guarantee or warrantee expressed or implied. * This program is -not- in the public domain. */ /* cmd_area.c -- use a ScrolledText object to view the * output of commands input by the user in a Command window. */ #include <Xm/Text.h> #include <Xm/MainW.h> #include <Xm/Command.h> #include <stdio.h> /* For popen() */ void Exit(drawing_a, client_data, call_data) Widget drawing_a; XtPointer client_data; XtPointer call_data; { exit(0); } /* main() -- initialize toolkit, create a main window, menubar, * a Command Area and a ScrolledText to view the output of commands. */ main(argc, argv) int argc; char *argv[]; { Widget top, main_w, menubar, menu, command_w, text_w; XtAppContext app; XmString file, quit; extern void exec_cmd(), exit(); Arg args[5]; int n = 0; XtSetLanguageProc (NULL, NULL, NULL); /* initialize toolkit and create toplevel shell */ top = XtVaAppInitialize (&app, "Demos", NULL, 0, &argc, argv, NULL, NULL); (void) close (0); /* don't let commands read from stdin */ /* MainWindow for the application -- contains menubar, ScrolledText * and CommandArea (which prompts for filename). */ main_w = XtVaCreateManagedWidget ("main_w", xmMainWindowWidgetClass, top, XmNcommandWindowLocation, XmCOMMAND_BELOW_WORKSPACE, NULL); /* Create a simple MenuBar that contains one menu */ file = XmStringCreateLocalized ("File"); menubar = XmVaCreateSimpleMenuBar (main_w, "menubar", XmVaCASCADEBUTTON, file, 'F', NULL); XmStringFree (file); /* "File" menu has only one item (Quit), so make callback exit() */ quit = XmStringCreateLocalized ("Quit"); /* menu = XmVaCreateSimplePulldownMenu (menubar, "file_menu", 0, exit, */ menu = XmVaCreateSimplePulldownMenu (menubar, "file_menu", 0, Exit, XmVaPUSHBUTTON, quit, 'Q', NULL, NULL, NULL); XmStringFree (quit); /* Menubar is done -- manage it */ XtManageChild (menubar); /* Create ScrolledText -- this is work area for the MainWindow */ XtSetArg (args[n], XmNrows, 24); n++; XtSetArg (args[n], XmNcolumns, 80); n++; XtSetArg (args[n], XmNeditable, False); n++; XtSetArg (args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++; text_w = XmCreateScrolledText (main_w, "text_w", args, n); XtManageChild (text_w); /* store text_w as user data in "File" menu for file_cb() callback */ XtVaSetValues (menu, XmNuserData, text_w, NULL); /* Create the command area -- this must be a Command class widget */ file = XmStringCreateLocalized ("Command:"); command_w = XtVaCreateWidget ("command_w", xmCommandWidgetClass, main_w, XmNpromptString, file, NULL); XmStringFree (file); XtAddCallback (command_w, XmNcommandEnteredCallback, exec_cmd, text_w); XtManageChild (command_w); XmMainWindowSetAreas (main_w, menubar, command_w, NULL, NULL, XtParent (text_w)); XtRealizeWidget (top); XtAppMainLoop (app); } /* execute the command and redirect output to the ScrolledText window */ void exec_cmd (cmd_widget, client_data, call_data) Widget cmd_widget; /* the command widget itself, not its Text widget */ XtPointer client_data; /* passed the text_w as client_data */ XtPointer call_data; { char *cmd, buf[BUFSIZ]; XmTextPosition pos; FILE *pp, *popen(); Widget text_w = (Widget) client_data; XmCommandCallbackStruct *cbs = (XmCommandCallbackStruct *) call_data; XmStringGetLtoR (cbs->value, XmFONTLIST_DEFAULT_TAG, &cmd); if (!cmd || !*cmd) { /* nothing typed? */ if (cmd) XtFree (cmd); return; } /* make sure the file is a regular text file and open it */ if (!(pp = popen (cmd, "r"))) perror (cmd); XtFree (cmd); if (!pp) return; /* put the output of the command in the Text widget by reading * until EOF (meaning that the command has terminated). */ for (pos = 0; fgets (buf, sizeof(buf), pp); pos += strlen (buf)) XmTextReplace (text_w, pos, pos, buf); pclose (pp); }