home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / UNIX / ARCHIE / CLIENTS / XARCHIE-.1 / XARCHIE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-22  |  21.7 KB  |  710 lines

  1. /*
  2.  * xarchie : An X browser interface to Archie
  3.  *
  4.  * George Ferguson, ferguson@cs.rochester.edu, 2 Nov 1991.
  5.  * Version 2.0: 23 Apr 1993.
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <X11/Intrinsic.h>
  10. #include <X11/StringDefs.h>
  11. #include <X11/Shell.h>    
  12. #include <X11/Xaw/Form.h>
  13. #include <X11/Xaw/Label.h>
  14. #include <X11/Xaw/Command.h>
  15. #include <X11/Xaw/Paned.h>
  16. #include <X11/Xaw/Viewport.h>
  17. #include <X11/Xaw/AsciiText.h>
  18. #include <X11/Xaw/MenuButton.h>
  19. #include <X11/Xaw/SimpleMenu.h>
  20. #include <X11/Xaw/Scrollbar.h>
  21. #include <X11/Xaw/Cardinals.h>    
  22. #include <X11/cursorfont.h>
  23. #ifdef MULTILIST
  24. #include <MultiList.h>
  25. #else
  26. #include <X11/Xaw/List.h>
  27. #endif
  28. #include "sysdefs.h"
  29. #include "xarchie.h"
  30. #include "types.h"
  31. #include "appres.h"
  32. #include "weight.h"
  33. #include "db.h"
  34. #include "actions.h"
  35. #include "display.h"
  36. #include "settings.h"
  37. #include "menu.h"
  38. #include "m-defs.h"
  39. #include "status.h"
  40. #include "browser.h"
  41. #include "selection.h"
  42. #include "file-panel.h"
  43. #include "ftp-actions.h"
  44. #include "about.h"
  45. #ifdef HELP
  46. # include "help.h"
  47. #endif
  48. #include "view-file.h"
  49. #include "username.h"
  50. #include "hostname.h"
  51. #include "syntax.h"
  52. #include "xarchie.xbm"
  53. #include "busy.xbm"
  54.  
  55. /*    -    -    -    -    -    -    -    -    */
  56. /*
  57.  * Functions defined in this file:
  58.  */
  59. /* main() */
  60. void bye();
  61. void setBusyStatus(),setIconStatus();
  62.  
  63. static void initGraphics(),initColors(),initMenus(),initWidgets();
  64. static void initErrorHandlers(), initMisc();
  65. static void browserCallback();
  66. static void setWindowBusyStatus();
  67. static void iconifyEventHandler();
  68. #ifdef DEBUG
  69. static void xerror();
  70. #endif
  71.  
  72. /*
  73.  * Global graphics data
  74.  */
  75. Display *display;
  76. Screen *screen;
  77. Window root;
  78. Atom WM_DELETE_WINDOW,WM_PROTOCOLS,WM_STATE;
  79.  
  80. /*
  81.  * Local graphics data
  82.  */
  83. static Cursor busyCursor;
  84.  
  85. /*
  86.  * Global widget data
  87.  */
  88. XtAppContext appContext;
  89. Widget toplevel,realToplevel;
  90. Widget fileButton,settingsButton;
  91. Widget queryButton,abortButton;
  92. #ifdef HELP
  93. Widget helpButton;
  94. #endif
  95. Widget statusText;
  96. Widget browserForm;
  97. Widget browserUpButton,browserDownButton;
  98. Widget browserViewports[NUM_BROWSER_PANES];
  99. Widget browserScrollbars[NUM_BROWSER_PANES];
  100. Widget browserLists[NUM_BROWSER_PANES];
  101. Widget searchText;
  102. Widget hostText,locationText,fileText,sizeText,modesText,dateText;
  103.  
  104. /*
  105.  * Other global data
  106.  */
  107. DbEntry *db;
  108. char *program;
  109. char *tmpDirectory;
  110.  
  111. /*
  112.  * The application resources
  113.  */
  114. AppResources appResources;
  115.  
  116. /*
  117.  * Non-widget resources obtained from resource manager
  118.  */
  119. static XtResource resources[] = {
  120.     { "searchType", "SearchType", GfRSearchType, sizeof(SearchType),
  121.       XtOffset(AppResources *,searchType), XtRImmediate, (XtPointer)GfExact },
  122.     { "sortType", "SortType", GfRSortType, sizeof(SortType),
  123.       XtOffset(AppResources *,sortType), XtRImmediate, (XtPointer)GfName },
  124.     { "archieHost", "ArchieHost", XtRString, sizeof(String),
  125.       XtOffset(AppResources *,archieHost), XtRImmediate, "archie.sura.net" },
  126.     { "numHosts", "numHosts", XtRInt, sizeof(int),
  127.       XtOffset(AppResources *,numHosts), XtRImmediate, (XtPointer)1 },
  128.     { "maxHits", "MaxHits", XtRInt, sizeof(int),
  129.       XtOffset(AppResources *,maxHits), XtRImmediate, (XtPointer)99 },
  130.     { "offset", "Offset", XtRInt, sizeof(int),
  131.       XtOffset(AppResources *,offset), XtRImmediate, (XtPointer)0 },
  132.     { "timeout", "Timeout", XtRInt, sizeof(int),
  133.       XtOffset(AppResources *,timeout), XtRImmediate, (XtPointer)0 },
  134.     { "retries", "Retries", XtRInt, sizeof(int),
  135.       XtOffset(AppResources *,retries), XtRImmediate, (XtPointer)0 },
  136.     { "niceLevel", "NiceLevel", XtRInt, sizeof(int),
  137.       XtOffset(AppResources *,niceLevel), XtRImmediate, (XtPointer)0 },
  138.     { "ftpLocalDir", "FtpLocalDir", XtRString, sizeof(String),
  139.       XtOffset(AppResources *,ftpLocalDir), XtRImmediate, "" },
  140.     { "ftpType", "FtpType", XtRString, sizeof(String),
  141.       XtOffset(AppResources *,ftpType), XtRImmediate, "binary" },
  142.     { "ftpPrompt", "FtpPrompt", XtRBoolean, sizeof(Boolean),
  143.       XtOffset(AppResources *,ftpPrompt), XtRImmediate, (XtPointer)False },
  144.     { "ftpTrace", "FtpTrace", XtRBoolean, sizeof(Boolean),
  145.       XtOffset(AppResources *,ftpTrace), XtRImmediate, (XtPointer)False },
  146.     { "ftpStrip", "FtpStrip", XtRBoolean, sizeof(Boolean),
  147.       XtOffset(AppResources *,ftpStrip), XtRImmediate, (XtPointer)True },
  148.     { "ftpMailAddress", "FtpMailAddress", XtRString, sizeof(String),
  149.       XtOffset(AppResources *,ftpMailAddress), XtRImmediate, "%s@%s" },
  150.     { "debugLevel", "DebugLevel", XtRInt, sizeof(int),
  151.       XtOffset(AppResources *,debugLevel), XtRImmediate, (XtPointer)0 },
  152.     { "fileWriteOnePerLine", "FileWriteOnePerLine", XtRBoolean,sizeof(Boolean),
  153.       XtOffset(AppResources *,fileWriteOnePerLine), XtRImmediate,
  154.                               (XtPointer)False },
  155.     { "xarchieFont", "Font", XtRFontStruct, sizeof(XFontStruct*),
  156.       XtOffset(AppResources *,xarchieFont), XtRString, XtDefaultFont },
  157.     { "xarchieBoldFont", "Font", XtRFontStruct, sizeof(XFontStruct*),
  158.       XtOffset(AppResources *,xarchieBoldFont), XtRString, XtDefaultFont },
  159.     { "hostWeights", "HostWeights", XtRString, sizeof(String),
  160.       XtOffset(AppResources *,hostWeights), XtRImmediate, NULL },
  161.     { "autoScroll", "AutoScroll", XtRBoolean, sizeof(Boolean),
  162.       XtOffset(AppResources *,autoScroll), XtRImmediate, (XtPointer)True },
  163.     { "pasteBuffer", "PasteBuffer", XtRBoolean, sizeof(Boolean),
  164.       XtOffset(AppResources *,pasteBuffer), XtRImmediate, (XtPointer)True },
  165.     { "visualType", "VisualType", XtRString, sizeof(String),
  166.       XtOffset(AppResources *,visualType), XtRImmediate, (XtPointer)"" },
  167.     { "defaultIcon", "Icon", XtRBitmap, sizeof(Pixmap),
  168.       XtOffset(AppResources *,defaultIcon), XtRImmediate, None },
  169.     { "busyIcon", "Icon", XtRBitmap, sizeof(Pixmap),
  170.       XtOffset(AppResources *,busyIcon), XtRImmediate, None },
  171. };
  172.  
  173. /*
  174.  * Non-widget resources set on command line.
  175.  */
  176. static XrmOptionDescRec options[] = {
  177.     { "-search",  ".searchType", XrmoptionSepArg, (XtPointer)"exact" },
  178.     { "-e",      ".searchType", XrmoptionNoArg,  (XtPointer)"exact" },
  179.     { "-s",      ".searchType", XrmoptionNoArg,  (XtPointer)"substr" },
  180.     { "-c",      ".searchType", XrmoptionNoArg,  (XtPointer)"subcase" },
  181.     { "-r",      ".searchType", XrmoptionNoArg,  (XtPointer)"regexp" },
  182.     { "-es",      ".searchType", XrmoptionNoArg,  (XtPointer)"exactSubstr" },
  183.     { "-ec",      ".searchType", XrmoptionNoArg,  (XtPointer)"exactSubcase" },
  184.     { "-er",      ".searchType", XrmoptionNoArg,  (XtPointer)"exactRegexp" },
  185.     { "-sort",      ".sortType",     XrmoptionSepArg, (XtPointer)"name" },
  186.     { "-t",      ".sortType",     XrmoptionNoArg,  (XtPointer)"date" },
  187.     { "-w",      ".sortType",     XrmoptionNoArg,  (XtPointer)"weight" },
  188.     { "-host",      ".archieHost", XrmoptionSepArg,
  189.                     (XtPointer)"archie.sura.ca" },
  190.     { "-maxhits", ".maxHits",     XrmoptionSepArg, (XtPointer)"99" },
  191.     { "-offset",  ".offset",     XrmoptionSepArg, (XtPointer)"0" },
  192.     { "-nice",      ".niceLevel",     XrmoptionSepArg, (XtPointer)"0" },
  193.     { "-N",      ".niceLevel",     XrmoptionSepArg, (XtPointer)"0" },
  194.     { "-debug",      ".debugLevel", XrmoptionSepArg, (XtPointer)"1" },
  195.     { "-D",      ".debugLevel", XrmoptionSepArg, (XtPointer)"1" },
  196.     { "-noscroll",".autoScroll", XrmoptionNoArg,  (XtPointer)"False" },
  197.     { "-mono",      ".visualType", XrmoptionNoArg,  (XtPointer)"mono" },
  198.     { "-gray",      ".visualType", XrmoptionNoArg,  (XtPointer)"gray" },
  199.     { "-color",      ".visualType", XrmoptionNoArg,  (XtPointer)"color" },
  200. };
  201.  
  202. /*
  203.  * Widget and non-widget resources if the application defaults
  204.  * file can't be found.
  205.  * Generated automatically from Xarchie.ad by "ad2c".
  206.  * Comment out the include line (but not the NULL) if you don't want
  207.  * any resources compiled in.
  208.  */
  209. static String fallbackResources[] = {
  210. #include "Xarchie.ad.h"
  211.     NULL
  212. };
  213.  
  214. /*    -    -    -    -    -    -    -    -    */
  215.  
  216. main(argc,argv)
  217. int argc;
  218. char **argv;
  219. {
  220.     program = argv[0];
  221.     /* Init display and application context, other globals, parse args */
  222.     initGraphics(&argc,argv);
  223.     if (argc > 1) {
  224.     syntax(argc,argv);
  225.     bye(1);
  226.     }
  227.     /* Init other non-widget stuff */
  228.     initErrorHandlers();
  229.     initColors();
  230.     initActions();
  231.     initHostWeights();
  232.     /* Then init the menus so they can be found for other widgets */
  233.     initMenus();
  234.     /* Then the main panel widgets */
  235.     initWidgets();
  236.     /* Now we realize so the toplevel window is available */
  237.     XtRealizeWidget(realToplevel);
  238.     /* Other initializations that need to go now */
  239.     initSettings();
  240. #ifdef HELP
  241.     initHelpPanel();
  242. #endif
  243.     initMisc();
  244.     /* Set icon, then map (must be this order!) */
  245.     setIconStatus(0);
  246.     XtMapWidget(realToplevel);
  247.     /* Enable WM_DELETE_WINDOW processing */
  248.     (void)XSetWMProtocols(display,XtWindow(realToplevel),&WM_DELETE_WINDOW,1);
  249.     status0("Ready");
  250.     /* Init the data structure for responses */
  251.     db = newEntry();
  252.     resetBrowser();
  253.     setBrowserState(BROWSER_READY);
  254.     /* Do it */
  255.     XtAppMainLoop(appContext);
  256.     /*NOTREACHED*/
  257. }
  258.  
  259. void
  260. bye(ret)
  261. int ret;
  262. {
  263.     XtDestroyApplicationContext(appContext);
  264. #ifdef CUTCP
  265.     netshut();
  266. #endif
  267.     exit(ret);
  268. }
  269.  
  270. /*    -    -    -    -    -    -    -    -    */
  271. /* Initialization routines */
  272.  
  273. static void
  274. initGraphics(argcp,argv)
  275. int *argcp;
  276. char **argv;
  277. {
  278.     /* Some systems want (Cardinal*), others want (int*) for argcp. */
  279.     realToplevel = toplevel =
  280.     XtAppInitialize(&appContext,"Xarchie",options,XtNumber(options),
  281.             (Cardinal *)argcp,argv,fallbackResources,NULL,ZERO);
  282.     /*
  283.      * Set graphics globals
  284.      */
  285.     display = XtDisplay(realToplevel);
  286.     screen = XtScreen(realToplevel);
  287.     root = RootWindowOfScreen(screen);
  288.     busyCursor = XCreateFontCursor(display,XC_watch);
  289.     WM_PROTOCOLS = XInternAtom(display,"WM_PROTOCOLS",False);
  290.     WM_DELETE_WINDOW = XInternAtom(display,"WM_DELETE_WINDOW",False);
  291.     WM_STATE = XInternAtom(display,"WM_STATE",False);
  292.     /*
  293.      * Set up the resource converters (needs globals)
  294.      */
  295.     initConverters(appContext);
  296.     /*
  297.      * Get non-widget resources
  298.      */
  299.     XtGetApplicationResources(realToplevel,(XtPointer)&appResources,
  300.                   resources,XtNumber(resources),NULL,ZERO);
  301.     /*
  302.      * Realloc these right away so we can free/realloc them later
  303.      */
  304.     appResources.archieHost = XtNewString(appResources.archieHost);
  305.     appResources.ftpLocalDir = XtNewString(appResources.ftpLocalDir);
  306.     appResources.ftpType = XtNewString(appResources.ftpType);
  307.     appResources.hostWeights = XtNewString(appResources.hostWeights);
  308.     /*
  309.      * Catch iconify/deiconify so we can do children also
  310.      */
  311.     XtAddEventHandler(realToplevel,PropertyChangeMask,False,
  312.               iconifyEventHandler,NULL);
  313. #ifdef DEBUG
  314.     XSetErrorHandler(xerror);
  315.     XSynchronize(display,True);
  316. #endif
  317. }
  318.  
  319. /*
  320.  * initColors: To allow resources to be specfied separately for color
  321.  *    and mono displays, we add a dummy Form widget below realToplevel
  322.  *    in appropriate circumstances.
  323.  *      This means that:
  324.  *      - realToplevel gets realized
  325.  *      - toplevel gets used as parent of children
  326.  */
  327. #define ADDTOPLEVEL(NAME) \
  328.     toplevel = XtCreateManagedWidget(NAME,formWidgetClass, \
  329.                      realToplevel,NULL,0);
  330. static void
  331. initColors()
  332. {
  333.     Visual *visual;
  334.  
  335.     /* The default is no extra widget (ie. mono) */
  336.     toplevel = realToplevel;
  337.     /* See if the user specified a type */
  338.     if (strcmp(appResources.visualType,"mono") == 0) {
  339.     return;
  340.     } else if (strcmp(appResources.visualType,"color") == 0) {
  341.     ADDTOPLEVEL("color");
  342.     return;
  343.     } else if (strcmp(appResources.visualType,"gray") == 0) {
  344.     ADDTOPLEVEL("gray");
  345.     return;
  346.     }
  347.     /* Otherwise we try to figure it out */
  348.     if ((visual=XDefaultVisualOfScreen(screen)) == NULL) {
  349.     fprintf(stderr,"%s: can't get info about visual!\n",program);
  350.     return;
  351.     }
  352.     if (visual->map_entries > 2) {
  353.     switch (visual->class) {
  354.       case StaticColor:
  355.       case PseudoColor:
  356.       case TrueColor:
  357.       case DirectColor:
  358.         ADDTOPLEVEL("color");
  359.         break;
  360.       case StaticGray:
  361.       case GrayScale:
  362.         ADDTOPLEVEL("gray");
  363.         break;
  364.       default:
  365.         toplevel = realToplevel;
  366.     }
  367.     } else {
  368.     toplevel = realToplevel;
  369.     }
  370. }
  371.  
  372. /*
  373.  * initMenus: Call all the menu initialization routines
  374.  */
  375. static void
  376. initMenus()
  377. {
  378.     initMenuCreator();        /* must be first */
  379.     initFileMenu();
  380.     initQueryMenu();
  381.     initSettingsMenu();
  382.     initFilePanelMenu();
  383. }
  384.  
  385. /*
  386.  * initWidgets: Initialize the widgets and set globals variables.
  387.  */
  388. static void
  389. initWidgets()
  390. {
  391.     Widget outerPaned,buttonForm,browserPaned;
  392.     Widget stringForm;
  393.     char name[32];
  394.     int i;
  395.  
  396.     outerPaned = XtCreateManagedWidget("outerPaned",panedWidgetClass,
  397.                        toplevel,NULL,0);
  398.     /* Button Form */
  399.     buttonForm = XtCreateManagedWidget("buttonForm",formWidgetClass,
  400.                        outerPaned,NULL,0);
  401.     fileButton = XtCreateManagedWidget("fileButton",menuButtonWidgetClass,
  402.                        buttonForm,NULL,0);
  403.     settingsButton = XtCreateManagedWidget("settingsButton",
  404.                        menuButtonWidgetClass,
  405.                        buttonForm,NULL,0);
  406.     queryButton = XtCreateManagedWidget("queryButton",
  407.                     menuButtonWidgetClass,
  408.                     buttonForm,NULL,0);
  409.     abortButton = XtCreateManagedWidget("abortButton",
  410.                     commandWidgetClass,
  411.                     buttonForm,NULL,0);
  412.     XtSetSensitive(abortButton,False);
  413. #ifdef HELP
  414.     helpButton = XtCreateManagedWidget("helpButton",commandWidgetClass,
  415.                        buttonForm,NULL,0);
  416. #endif
  417.     (void)XtCreateManagedWidget("statusLabel",labelWidgetClass,
  418.                 buttonForm,NULL,0);
  419.     statusText = XtCreateManagedWidget("statusText",asciiTextWidgetClass,
  420.                        buttonForm,NULL,0);
  421.     /* Browser */
  422.     browserForm = XtCreateManagedWidget("browserForm",formWidgetClass,
  423.                     outerPaned,NULL,0);
  424.     browserUpButton = XtCreateManagedWidget("browserUpButton",
  425.                         commandWidgetClass,
  426.                         browserForm,NULL,0);
  427.     browserDownButton = XtCreateManagedWidget("browserDownButton",
  428.                           commandWidgetClass,
  429.                           browserForm,NULL,0);
  430.     browserPaned = XtCreateManagedWidget("browserPaned",panedWidgetClass,
  431.                      browserForm,NULL,0);
  432.     for (i=0; i < NUM_BROWSER_PANES; i++) {
  433.     sprintf(name,"browserViewport%d",i);
  434.     browserViewports[i] = XtCreateManagedWidget(name,viewportWidgetClass,
  435.                             browserPaned,NULL,0);
  436.     browserScrollbars[i] = XtNameToWidget(browserViewports[i],"vertical");
  437.     sprintf(name,"browserList%d",i);
  438. #ifdef MULTILIST
  439.     browserLists[i] = XtCreateManagedWidget(name,xfwfMultiListWidgetClass,
  440.                         browserViewports[i],NULL,0);
  441. #else
  442.     browserLists[i] = XtCreateManagedWidget(name,listWidgetClass,
  443.                         browserViewports[i],NULL,0);
  444. #endif
  445.     clearBrowserPane(i);
  446.     XtAddCallback(browserLists[i],XtNcallback,
  447.               browserCallback,(XtPointer)i);
  448.     }
  449.     /* String Form */
  450.     stringForm = XtCreateManagedWidget("stringForm",formWidgetClass,
  451.                        outerPaned,NULL,0);
  452.     (void)XtCreateManagedWidget("searchLabel",labelWidgetClass,
  453.                 stringForm,NULL,0);
  454.     searchText = XtCreateManagedWidget("searchText",asciiTextWidgetClass,
  455.                        stringForm,NULL,0);
  456.     (void)XtCreateManagedWidget("hostLabel",labelWidgetClass,
  457.                 stringForm,NULL,0);
  458.     hostText = XtCreateManagedWidget("hostText",asciiTextWidgetClass,
  459.                      stringForm,NULL,0);
  460.     (void)XtCreateManagedWidget("locationLabel",labelWidgetClass,
  461.                 stringForm,NULL,0);
  462.     locationText = XtCreateManagedWidget("locationText",asciiTextWidgetClass,
  463.                      stringForm,NULL,0);
  464.     (void)XtCreateManagedWidget("fileLabel",labelWidgetClass,
  465.                 stringForm,NULL,0);
  466.     fileText = XtCreateManagedWidget("fileText",asciiTextWidgetClass,
  467.                      stringForm,NULL,0);
  468.     (void)XtCreateManagedWidget("sizeLabel",labelWidgetClass,
  469.                 stringForm,NULL,0);
  470.     sizeText = XtCreateManagedWidget("sizeText",asciiTextWidgetClass,
  471.                      stringForm,NULL,0);
  472.     (void)XtCreateManagedWidget("modesLabel",labelWidgetClass,
  473.                 stringForm,NULL,0);
  474.     modesText = XtCreateManagedWidget("modesText",asciiTextWidgetClass,
  475.                       stringForm,NULL,0);
  476.     (void)XtCreateManagedWidget("dateLabel",labelWidgetClass,
  477.                 stringForm,NULL,0);
  478.     dateText = XtCreateManagedWidget("dateText",asciiTextWidgetClass,
  479.                      stringForm,NULL,0);
  480. }
  481.  
  482. static void
  483. initMisc()
  484. {
  485.     char *user,*host,*addr;
  486.  
  487.     if ((tmpDirectory=getenv("TMPDIR")) == NULL) {
  488.     tmpDirectory = "/tmp";
  489.     }
  490.     user = GetUsername();
  491.     host = GetHostname();
  492.     addr = XtMalloc(strlen(user)+
  493.             strlen(host)+strlen(appResources.ftpMailAddress));
  494.     sprintf(addr,appResources.ftpMailAddress,user,host);
  495.     /* Memory leak, but only happens once */
  496.     appResources.ftpMailAddress = addr;
  497.     /* Use the default icons unless overridden */
  498.     if (appResources.defaultIcon == None) {
  499.     appResources.defaultIcon =
  500.         XCreateBitmapFromData(display,root,xarchie_bits,
  501.                   xarchie_width,xarchie_height);
  502.     }
  503.     if (appResources.busyIcon == None) {
  504.     appResources.busyIcon =
  505.         XCreateBitmapFromData(display,root,busy_bits,
  506.                   busy_width,busy_height);
  507.     }
  508. }
  509.  
  510. /*    -    -    -    -    -    -    -    -    */
  511. /* The following functions attempt to provide information in the event of
  512.  * a crash. If you have trouble compiling them because of UNIX-isms in
  513.  * the signal handlers, then add -DDONT_CATCH_ERRORS to the definition
  514.  * of DEFINES in the Imakefile and re-make (or just #define it here).
  515.  */
  516. #ifndef DONT_CATCH_ERRORS
  517. #include <signal.h>
  518. static void crashHandler();
  519. #endif /* DONT_CATCH_ERRORS */
  520.  
  521. static void
  522. initErrorHandlers()
  523. {
  524. #ifndef DONT_CATCH_ERRORS
  525.     signal(SIGBUS,crashHandler);
  526.     signal(SIGSEGV,crashHandler);
  527. #endif /* DONT_CATCH_ERRORS */
  528. }
  529.  
  530. #ifndef DONT_CATCH_ERRORS
  531. static void
  532. crashHandler(sig)
  533. int sig;
  534. {
  535.     char *s;
  536.  
  537.     switch (sig) {
  538.     case SIGBUS: s = "SIGBUS"; break;
  539.     case SIGSEGV: s = "SIGSEGV"; break;
  540.     default: s = "UNKNOWN";
  541.     }
  542.     fprintf(stderr,"%s: caught a %s signal!\n",program,s);
  543.     fprintf(stderr,"If you want to report an error, please indicate your hardware type,\n");
  544.     fprintf(stderr,"operating system, compiler, and your version of X and include a\n");
  545.     fprintf(stderr,"backtrace. Thanks.\n");
  546.     abort();
  547. }
  548.  
  549. #endif /* DONT_CATCH_ERRORS */
  550.  
  551. #ifdef DEBUG
  552. /*
  553.  * Override default X error handler to force an abort to debugger
  554.  */
  555. static void
  556. xerror(display,event)
  557. Display *display;
  558. XErrorEvent *event;
  559. {
  560.     char buf[256];
  561.  
  562.     XGetErrorText(display,event->error_code,buf,256);
  563.     printf("XERROR: %d: %s\n",event->error_code,buf);
  564.     abort();
  565. }
  566. #endif
  567.  
  568. /*    -    -    -    -    -    -    -    -    */
  569. /* Callback procedures */
  570.  
  571. /*ARGSUSED*/
  572. static void
  573. browserCallback(w,client_data,call_data)
  574. Widget w;
  575. XtPointer client_data;    /* pane */
  576. XtPointer call_data;    /* returnStruct */
  577. {
  578.     int pane = (int)client_data;
  579. #ifdef MULTILIST
  580. #ifdef DEBUG
  581.     static char *actions[] = { "NOTHING","HIGHLIGHT","UNHIGHLIGHT","STATUS" };
  582.     int i;
  583. #endif
  584.     XfwfMultiListReturnStruct *ret = (XfwfMultiListReturnStruct*)call_data;
  585.  
  586. #ifdef DEBUG
  587.     printf("Callback: %s, item %d\n",actions[ret->action],ret->item);
  588.     printf("  num_selected = %d\n",ret->num_selected);
  589.     printf("  selected_items[] = ");
  590.     for (i = 0; i < ret->num_selected; i++) {
  591.     printf("%d ",ret->selected_items[i]);
  592.     }
  593.     if (ret->num_selected == 0) printf("None");
  594.     printf("\n");
  595. #endif /* DEBUG */
  596.     switch (ret->action) {
  597.       case XfwfMultiListActionHighlight:
  598.     /* Anything selected? */
  599.     if (ret->item != -1) {
  600.         /* If just one thing selected, then we came here from Select() */
  601.         if (ret->num_selected == 1)
  602.         resetSelectionsForPane(pane);
  603.         selectBrowserItem(pane,ret->item);
  604.     }
  605.     break;
  606.       case XfwfMultiListActionUnhighlight:
  607.     if (ret->item == -1)
  608.         resetSelectionsForPane(pane);
  609.     else
  610.         unselectBrowserItem(pane,ret->item);
  611.     break;
  612.     }
  613. #else /* !MULTILIST */
  614.     XawListReturnStruct *ret = (XawListReturnStruct*)call_data;
  615.  
  616.     resetSelectionsForPane(pane);
  617.     selectBrowserItem(pane,ret->list_index);
  618. #endif /* !MULTILIST */
  619. }
  620.  
  621. /*    -    -    -    -    -    -    -    -    */
  622. /* Misc. routines */
  623.  
  624. void
  625. setBusyStatus(state)
  626. Boolean state;
  627. {
  628.     setWindowBusyStatus(XtWindow(realToplevel),state);
  629. }
  630.  
  631. static void
  632. setWindowBusyStatus(window,state)
  633. Window window;
  634. Boolean state;
  635. {
  636.     Window root,parent,*children;
  637.     unsigned int numChildren;
  638.     int i;
  639.  
  640.     /* Do the window */
  641.     if (state)
  642.     XDefineCursor(display,window,busyCursor);
  643.     else
  644.     XUndefineCursor(display,window);
  645.     /* And all the children... */
  646.     if (XQueryTree(display,window,&root,&parent,&children,&numChildren) != 0) {
  647.     for (i=0; i < numChildren; i++) {
  648.         setWindowBusyStatus(*(children+i),state);
  649.     }
  650.     if (numChildren > 0)
  651.         XFree((char *)children);
  652.     }
  653. }
  654.         
  655. /*    -    -    -    -    -    -    -    -    */
  656.  
  657. /*ARGSUSED*/
  658. static void
  659. iconifyEventHandler(w,client_data,event,cont)
  660. Widget w;
  661. XtPointer client_data;
  662. XEvent *event;
  663. Boolean *cont;
  664. {
  665.     int state;
  666.  
  667.     if (event->xproperty.state == PropertyNewValue &&
  668.     event->xproperty.atom == WM_STATE) {
  669.     Atom actual_type;
  670.     int actual_format;
  671.     unsigned long nitems = 0, bytes_after = 0;
  672.     unsigned char* data = NULL;
  673.  
  674.     if (XGetWindowProperty(display,XtWindow(realToplevel),
  675.                    WM_STATE,0,2,False,AnyPropertyType,
  676.                    &actual_type,&actual_format,
  677.                    &nitems,&bytes_after,&data) == Success) {
  678.         state = *(int *)data;
  679.         setSettingsShellState(state);
  680.         setFileShellState(state);
  681. #ifdef HELP
  682.         setHelpShellState(state);
  683. #endif
  684.         setAboutShellState(state);
  685.         setFtpTraceShellState(state);
  686.         XFree((char *)data);
  687.     }
  688.     }
  689. }
  690.  
  691. void
  692. setIconStatus(state)
  693. Boolean state;
  694. {
  695.     Pixmap pixmap;
  696.     char *name;
  697.     Arg args[2];
  698.  
  699.     if (state == True) {
  700.     pixmap = appResources.busyIcon;
  701.     name = "xarchie:busy";
  702.     } else {
  703.     pixmap = appResources.defaultIcon;
  704.     name = "xarchie";
  705.     }
  706.     XtSetArg(args[0],XtNiconName,name);
  707.     XtSetArg(args[1],XtNiconPixmap,pixmap);
  708.     XtSetValues(toplevel,args,2);
  709. }
  710.