home *** CD-ROM | disk | FTP | other *** search
- /*
- * xarchie : An X browser interface to Archie
- *
- * This file is sort of a mishmash of functions, some of which might get
- * sorted out later. Its primary purpose is to establish the X connection,
- * create the application's widgets, call any other other necessary
- * initialization routines, and enter XtAppMainLoop(). It also provides
- * the callback procedure selectItem() that makes the List widgets work
- * like a browser (in collaboration with the display routines in db.c).
- * Finally, it provides the generic setText(), setLabel(), and status*()
- * routines which could go just about anywhere.
- *
- * George Ferguson, ferguson@cs.rochester.edu, 21 Aug 1991.
- *
- */
- #include <stdio.h>
- #include <signal.h>
- #include <sys/time.h>
- #include <X11/Intrinsic.h>
- #include <X11/StringDefs.h>
- #include <X11/Shell.h>
- #include <X11/Xaw/Paned.h>
- #include <X11/Xaw/Viewport.h>
- #include <X11/Xaw/List.h>
- #include <X11/Xaw/Form.h>
- #include <X11/Xaw/Box.h>
- #include <X11/Xaw/Label.h>
- #include <X11/Xaw/AsciiText.h>
- #include <X11/Xaw/Command.h>
- #include <X11/Xaw/Cardinals.h>
- #include "types.h"
- #include "appres.h"
- #include "classnames.h"
- #include "db.h"
- #include "actions.h"
- #include "patchlevel.h"
-
- /* - - - - - - - - */
- /*
- * Functions defined in this file:
- */
- int main();
- void doPendingEvents();
- void initWidgetsFromString();
- void displayHostInfo(), clearHostInfo();
- void displayLocationInfo(), clearLocationInfo();
- void displayFileInfo(), clearFileInfo();
- void setText(), setLabel();
- void status0(), status1(), status2();
- void fail0(), fail1();
-
- static void initGraphics(), initWidgets();
- static void selectItem();
- static void syntax();
-
- /*
- * Global graphics data
- */
- Display *display;
- Screen *screen;
- Window root;
-
- /*
- * Global widget data
- */
- XtAppContext appContext;
- Widget toplevel;
- Widget hostList,locationList,fileList;
- Widget searchText;
-
- static Widget statusText;
- static Widget hostText,locationText,fileText,sizeText,modesText,dateText;
-
- /*
- * Other global data
- */
- Database *db;
- char *progname;
-
- /*
- * The application resources
- */
- AppResources appResources;
-
- /*
- * Non-widget resources obtained from resource manager
- */
- static XtResource resources[] = {
- { "widgets", "Widgets", XtRString, sizeof(String),
- XtOffset(AppResources *,widgets), XtRImmediate, "" },
- { "searchType", "SearchType", GfRSearchType, sizeof(SearchType),
- XtOffset(AppResources *,searchType), XtRImmediate, (XtPointer)GfExact },
- { "sortType", "SortType", GfRSortType, sizeof(SortType),
- XtOffset(AppResources *,sortType), XtRImmediate, (XtPointer)GfDefault },
- { "archieHost", "ArchieHost", XtRString, sizeof(String),
- XtOffset(AppResources *,archieHost), XtRImmediate, "archie.mcgill.ca" },
- { "maxHits", "MaxHits", XtRInt, sizeof(int),
- XtOffset(AppResources *,maxHits), XtRImmediate, (XtPointer)99 },
- { "offset", "Offset", XtRInt, sizeof(int),
- XtOffset(AppResources *,offset), XtRImmediate, (XtPointer)0 },
- { "timeout", "Timeout", XtRInt, sizeof(int),
- XtOffset(AppResources *,timeout), XtRImmediate, (XtPointer)0 },
- { "retries", "Retries", XtRInt, sizeof(int),
- XtOffset(AppResources *,retries), XtRImmediate, (XtPointer)0 },
- { "niceLevel", "NiceLevel", XtRInt, sizeof(int),
- XtOffset(AppResources *,niceLevel), XtRImmediate, (XtPointer)0 },
- { "debugLevel", "DebugLevel", XtRInt, sizeof(int),
- XtOffset(AppResources *,debugLevel), XtRImmediate, (XtPointer)0 },
- { "settingsWidgets", "SettingsWidgets", XtRString, sizeof(String),
- XtOffset(AppResources *,settingsWidgets), XtRImmediate, "" },
- };
-
- /*
- * Non-widget resources set on command line.
- */
- static XrmOptionDescRec options[] = {
- { "-search", ".searchType", XrmoptionSepArg, (XtPointer)"exact" },
- { "-e", ".searchType", XrmoptionNoArg, (XtPointer)"exact" },
- { "-s", ".searchType", XrmoptionNoArg, (XtPointer)"substr" },
- { "-c", ".searchType", XrmoptionNoArg, (XtPointer)"subcase" },
- { "-r", ".searchType", XrmoptionNoArg, (XtPointer)"regexp" },
- { "-es", ".searchType", XrmoptionNoArg, (XtPointer)"exactSubstr" },
- { "-ec", ".searchType", XrmoptionNoArg, (XtPointer)"exactSubcase" },
- { "-er", ".searchType", XrmoptionNoArg, (XtPointer)"exactRegexp" },
- { "-sort", ".sortType", XrmoptionSepArg, (XtPointer)"default" },
- { "-t", ".sortType", XrmoptionNoArg, (XtPointer)"invdate" },
- { "-host", ".archieHost", XrmoptionSepArg,
- (XtPointer)"archie.mcgill.ca" },
- { "-maxhits", ".maxHits", XrmoptionSepArg, (XtPointer)"99" },
- { "-offset", ".offset", XrmoptionSepArg, (XtPointer)"0" },
- { "-nice", ".niceLevel", XrmoptionSepArg, (XtPointer)"0" },
- { "-N", ".niceLevel", XrmoptionSepArg, (XtPointer)"0" },
- { "-debug", ".debugLevel", XrmoptionNoArg, (XtPointer)"1" },
- { "-D", ".debugLevel", XrmoptionSepArg, (XtPointer)"1" },
- };
-
- /*
- * Widget and non-widget resources if the application defaults
- * file can't be found.
- * Generated automatically from Xarchie.ad by "ad2c".
- * Comment out the include line (but not the NULL) if you don't want
- * any resources compiled in.
- */
- static String fallbackResources[] = {
- #include "Xarchie.ad.h"
- NULL
- };
-
- /* - - - - - - - - */
-
- main(argc,argv)
- int argc;
- char **argv;
- {
- char buf[32];
-
- progname = argv[0];
- initGraphics(&argc,argv);
- if (argc > 1) {
- syntax(argc,argv);
- XtDestroyApplicationContext(appContext);
- exit(1);
- }
- initWidgets();
- XtRealizeWidget(toplevel);
- /* Set window title to indicate version */
- sprintf(buf,"xarchie %d.%d",xarchieMajorVersion,xarchieMinorVersion);
- XStoreName(display,XtWindow(toplevel),buf);
- sprintf(buf,"Welcome to xarchie %d.%d",xarchieMajorVersion,
- xarchieMinorVersion);
- status0(buf);
- /* get the data structure for responses */
- db = newDb();
- /* do it */
- XtAppMainLoop(appContext);
- /*NOTREACHED*/
- }
-
- void
- doPendingEvents()
- {
- while (XtAppPending(appContext))
- XtAppProcessEvent(appContext,XtIMAll);
- }
-
- static void
- initGraphics(argcp,argv)
- int *argcp;
- char **argv;
- {
- toplevel = XtAppInitialize(&appContext, "Xarchie",
- options, XtNumber(options),
- argcp,argv,fallbackResources,NULL,ZERO);
- initConverters(appContext);
- XawSimpleMenuAddGlobalActions(appContext);
- XtAppAddActions(appContext,actionTable,XtNumber(actionTable));
- XtGetApplicationResources(toplevel,(XtPointer)&appResources,
- resources,XtNumber(resources),NULL,ZERO);
- display = XtDisplay(toplevel);
- screen = XtScreen(toplevel);
- root = RootWindowOfScreen(screen);
- }
-
- /*
- * initWidgets: Initialize the widgets given in the .widgets resource,
- * check for required widgets, and set globals vars.
- */
- static void
- initWidgets()
- {
- initWidgetsFromString(appResources.widgets,".widgets");
- /* check for the necessary widgets and set the global variables */
- if ((hostList=XtNameToWidget(toplevel,"*hostList")) == NULL)
- fail0("didn't create widget \"hostList\"");
- if ((locationList=XtNameToWidget(toplevel,"*locationList")) == NULL)
- fail0("didn't create widget \"locationList\"");
- if ((fileList=XtNameToWidget(toplevel,"*fileList")) == NULL)
- fail0("didn't create widget \"fileList\"");
- if ((searchText=XtNameToWidget(toplevel,"*searchText")) == NULL)
- fail0("didn't create widget \"searchText\"");
- /* set globals for optional widgets */
- statusText = XtNameToWidget(toplevel,"*statusText");
- hostText = XtNameToWidget(toplevel,"*hostText");
- locationText = XtNameToWidget(toplevel,"*locationText");
- fileText = XtNameToWidget(toplevel,"*fileText");
- sizeText = XtNameToWidget(toplevel,"*sizeText");
- modesText = XtNameToWidget(toplevel,"*modesText");
- dateText = XtNameToWidget(toplevel,"*dateText");
- /* make the lists behave like a browser should */
- XtAddCallback(hostList,XtNcallback,selectItem,(XtPointer)1);
- XtAddCallback(locationList,XtNcallback,selectItem,(XtPointer)2);
- XtAddCallback(fileList,XtNcallback,selectItem,(XtPointer)3);
- /* since Xaw is so bloody stupid... */
- clearList(hostList);
- clearList(locationList);
- clearList(fileList);
- }
-
- #define ISSPACE(c) ((c) == ' ' || (c) == '\t' || (c) == '\n')
- #define NUL '\0'
-
- /*
- * initWidgetsFromString : Create the widgets specified in resourceStr as
- * "parent class name" triples. The resourceName is used for
- * error messages.
- */
- void
- initWidgetsFromString(resourceStr,resourceName)
- char *resourceStr,*resourceName;
- {
- char name[32],class[32],parent[256];
- char *s,*t;
- Boolean isShell;
- WidgetClass wc;
- Widget pw;
-
- if ((s=resourceStr) == NULL)
- fail1("no widgets specified in %s resource!",resourceName);
- while (*s) {
- /* skip leading whitespace */
- while (ISSPACE(*s))
- s += 1;
- if (!*s)
- break;
- /* Gather the parent widget name */
- t = parent;
- while (*s && !ISSPACE(*s))
- *t++ = *s++;
- *t = NUL;
- /* skip whitespace */
- while (isspace(*s))
- s += 1;
- if (!*s)
- fail1("missing widget class and name in %s resource",resourceName);
- /* Gather the class name */
- t = class;
- while (*s && !ISSPACE(*s))
- *t++ = *s++;
- *t = NUL;
- /* skip whitespace */
- while (isspace(*s))
- s += 1;
- if (!*s)
- fail1("missing widget name in %s resource",resourceName);
- /* Gather the widget's name */
- t = name;
- while (*s && !ISSPACE(*s))
- *t++ = *s++;
- *t = NUL;
- /* convert class name to WidgetClass */
- if ((wc=classNameToWidgetClass(class,&isShell)) == NULL)
- fail1("can't convert string \"%s\" to widgetClass",class);
- /* convert parent name to Widget */
- if (strcmp(parent,"toplevel") == 0)
- pw = toplevel;
- else if ((pw=XtNameToWidget(toplevel,parent)) == NULL)
- fail1("can't convert string \"%s\" to widget",parent);
- /* finally create the widget */
- if (isShell)
- (void)XtCreatePopupShell(name,wc,pw,NULL,ZERO);
- else
- (void)XtCreateManagedWidget(name,wc,pw,NULL,ZERO);
- }
- }
-
- /* - - - - - - - - */
- /* Callback procedures */
-
- /*ARGSUSED*/
- static void
- selectItem(w,closure,call_data)
- Widget w;
- XtPointer closure,call_data;
- {
- XawListReturnStruct *item = (XawListReturnStruct*)call_data;
-
- switch ((int)closure) {
- case 1 :
- if (selectedHostEntry &&
- findHostIndexFromEntry(selectedHostEntry) == item->list_index) {
- XawListUnhighlight(hostList);
- clearFileInfo();
- clearList(fileList);
- clearLocationInfo();
- clearList(locationList);
- clearHostInfo();
- selectedHostEntry = HOST_NULL;
- } else {
- selectedHostEntry = findHostEntryFromIndex(item->list_index,
- db);
- displayHostInfo(selectedHostEntry);
- displayLocs(selectedHostEntry);
- }
- break;
- case 2 :
- if (selectedLocEntry &&
- findLocIndexFromEntry(selectedLocEntry) == item->list_index) {
- XawListUnhighlight(locationList);
- clearFileInfo();
- clearList(fileList);
- clearLocationInfo();
- selectedLocEntry = LOC_NULL;
- } else {
- selectedLocEntry = findLocEntryFromIndex(item->list_index,
- selectedHostEntry);
- displayLocationInfo(selectedLocEntry);
- displayFiles(selectedLocEntry);
- }
- break;
- case 3 :
- if (selectedFileEntry &&
- findFileIndexFromEntry(selectedFileEntry) == item->list_index) {
- XawListUnhighlight(fileList);
- clearFileInfo();
- selectedFileEntry = FILE_NULL;
- } else {
- selectedFileEntry = findFileEntryFromIndex(item->list_index,
- selectedLocEntry);
- displayFileInfo(selectedFileEntry);
- }
- break;
- }
- }
-
- /* - - - - - - - - */
-
- void
- displayHostInfo(hostp)
- HostEntry *hostp;
- {
- if (hostText != NULL)
- setText(hostText,hostp->hostname);
- }
-
- void
- clearHostInfo()
- {
- if (hostText != NULL)
- setText(hostText,"");
- }
-
- void
- displayLocationInfo(locp)
- LocEntry *locp;
- {
- if (locationText != NULL)
- setText(locationText,locp->linkpath);
- }
-
- void
- clearLocationInfo()
- {
- if (locationText != NULL)
- setText(locationText,"");
- }
-
- void
- displayFileInfo(filep)
- FileEntry *filep;
- {
- char buf[16];
-
- if (fileText != NULL)
- setText(fileText,filep->name);
- if (sizeText != NULL) {
- sprintf(buf,"%d",filep->size);
- setText(sizeText,buf);
- }
- if (modesText != NULL)
- setText(modesText,filep->modes);
- if (sizeText != NULL)
- setText(dateText,filep->date);
- }
-
- void
- clearFileInfo()
- {
- if (fileText != NULL)
- setText(fileText,"");
- if (sizeText != NULL)
- setText(sizeText,"");
- if (modesText != NULL)
- setText(modesText,"");
- if (dateText != NULL)
- setText(dateText,"");
- }
-
- /* - - - - - - - - */
- /*
- * setText() : Set the given Text item's value to the given string.
- */
- void
- setText(item,text)
- Widget item;
- char *text;
- {
- Arg args[1];
-
- if (item != NULL) {
- XtSetArg(args[0],XtNstring,text);
- XtSetValues(item,args,ONE);
- }
- }
-
- /*
- * setLabel() : Set the given Label item's value to the given string.
- */
- void
- setLabel(item,text)
- Widget item;
- char *text;
- {
- Arg args[1];
-
- if (item != NULL) {
- XtSetArg(args[0],XtNlabel,text);
- XtSetValues(item,args,ONE);
- }
- }
-
- /* - - - - - - - - */
-
- void
- status0(str)
- char *str;
- {
- if (statusText != NULL)
- setText(statusText,str);
- doPendingEvents();
- }
-
- void
- status1(fmt,arg)
- char *fmt,*arg;
- {
- char buf[256];
-
- sprintf(buf,fmt,arg);
- status0(buf);
- }
-
- void
- status2(fmt,arg1,arg2)
- char *fmt,*arg1,*arg2;
- {
- char buf[256];
-
- sprintf(buf,fmt,arg1,arg2);
- status0(buf);
- }
-
- /* - - - - - - - - */
-
- void
- fail0(str)
- char *str;
- {
- fprintf(stderr,"%s: %s\n",progname,str);
- XtDestroyApplicationContext(appContext);
- exit(1);
- }
-
- void
- fail1(fmt,arg)
- char *fmt,*arg;
- {
- char buf[256];
-
- sprintf(buf,fmt,arg);
- fail0(buf);
- }
-
- /* - - - - - - - - */
- /*
- * syntax() : Print whatever caused the error and the usage message.
- */
- static void
- syntax(argc,argv)
- int argc;
- char **argv;
- {
- char *program;
-
- program = *argv;
- argv += 1;
- if (argc > 2 || (strcmp(*argv,"-help") != 0 && strcmp(*argv,"-?") != 0)) {
- fprintf(stderr,"%s: bad argument(s): ",program);
- while (--argc)
- fprintf(stderr,"%s ",*argv++);
- fprintf(stderr,"\n");
- }
- fprintf(stderr,"Valid options (in addition to X Toolkit options) are:\n");
- fprintf(stderr," -search type\tset query type\n");
- fprintf(stderr," -e\t\tset query type to exact\n");
- fprintf(stderr," -c\t\tset query type to subcase\n");
- fprintf(stderr," -s\t\tset query type to substr\n");
- fprintf(stderr," -r\t\tset query type to regexp\n");
- fprintf(stderr," -ec\t\tset query type to exactSubcase\n");
- fprintf(stderr," -es\t\tset query type to exactSubstr\n");
- fprintf(stderr," -er\t\tset query type to exactRegexp\n");
- fprintf(stderr," -sort type\tset sort mode\n");
- fprintf(stderr," -t\t\tset sort mode to invdate\n");
- fprintf(stderr," -host host\tconnect to Archie at host\n");
- fprintf(stderr," -maxHits num\tset maximum number of matches per query\n");
- fprintf(stderr," -offset off\tset Prospero offset\n");
- fprintf(stderr," -[nice|N] level\tset query niceness\n");
- fprintf(stderr," -[debug|D] level\tset Prospero debugging level\n");
- fprintf(stderr," -help\t\tprint this message\n");
- fprintf(stderr," -xrm 'resource: value' pass arbitrary resources\n");
- fprintf(stderr,"Options can be abbreviated to their shortest unique prefix.\n");
- }
-