home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3126 / xbrowser.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-03-25  |  37.5 KB  |  1,572 lines

  1. /** XBrowser V1.0 by Andy Colebourne **/
  2.  
  3. /** Some of this code is not very tidy!  I may clean it up one day. **/
  4. /** if you find any bugs, please mail me with the details (and fixes?) **/
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <sys/param.h>
  9. #include <dirent.h>
  10.  
  11. #include <X11/Intrinsic.h>
  12. #include <Xm/Xm.h>
  13. #include <Xm/Label.h>
  14. #include <Xm/RowColumn.h>
  15. #include <Xm/Text.h>
  16. #include <Xm/List.h>
  17. #include <Xm/PushB.h>
  18. #include <Xm/Form.h>
  19. #include <Xm/Frame.h>
  20. #include <Xm/SelectioB.h>
  21. #include <Xm/DialogS.h>
  22.  
  23. #define VERSIONSTRING "XBrowser Version 1.0"
  24. #define MAGIC_FILE "xbrowser.magic"
  25. #define BUTTONS_FILE "xbrowser.buttons"
  26.  
  27. String fallback_resources[] = {
  28.     "*title*fontList:            *-times-bold-r-*-*-*-140-*" ,
  29.     "*textwindow.rows:            24",
  30.     "*textwindow.columns:        80",
  31.     "*sidelist.visibleItemCount:    12",
  32.     NULL,
  33. };
  34.  
  35.  
  36. #define DIRSIZE 1000
  37. #define STRING(A) strcpy(malloc(strlen(A)+1),A);
  38. #define MFILE 0
  39. #define MSUFFIX 1
  40. #define LEFT 0
  41. #define RIGHT 1
  42.  
  43. char leftcd[MAXPATHLEN];
  44. char rightcd[MAXPATHLEN];
  45. Widget toplevel, leftinfolabel, rightinfolabel;
  46. char *astring;
  47. Boolean debug;
  48. Boolean readaftercommand;
  49.  
  50.  
  51. struct Entry
  52. {
  53.     char *name;
  54.     off_t size;
  55.     Boolean dir;
  56.     int mode;
  57.     char *path;
  58.     char *fullname;
  59. };
  60.  
  61.  
  62. struct Magic
  63. {
  64.     int mtype;
  65.     char *mname;
  66.     char *mstring;
  67.     Boolean mreread;
  68.  
  69. };
  70.  
  71.  
  72. struct Button
  73. {
  74.     int context;
  75.     char *command;
  76.     Boolean reread;
  77. };
  78.  
  79.  
  80. #define BALL 0
  81. #define BEACH 1
  82. #define BCOMMAND 2
  83. #define BSOURCEDEST 3
  84. #define BALLPATH 4
  85.  
  86. struct Button *buttonlist[255];
  87. int num_buttons;
  88.  
  89. struct Magic *magiclist[255];
  90. int num_magic;
  91.  
  92. struct Entry *leftptrs[DIRSIZE];
  93. struct Entry *rightptrs[DIRSIZE];
  94. int leftlistnum, rightlistnum;
  95. Widget leftlist, rightlist ,leftlabel, rightlabel, leftdirtext, rightdirtext;
  96. int rename_popups;
  97. char *command_string;
  98. long int size;
  99. char *xbrowserpath;
  100.  
  101. int compare(ptr1, ptr2)
  102. void *ptr1, *ptr2;
  103. {
  104.     return( strcmp( ((struct Entry *)*(struct Entry **)ptr1)->name, ((struct Entry *)*(struct Entry **)ptr2)->name ));
  105. }
  106.  
  107.  
  108. void set_label(w, str)
  109. Widget w;
  110. char *str;
  111. {
  112. int ac;
  113. Arg al[2];
  114. XmString label_label;
  115.  
  116.     ac = 0;
  117.     label_label = XmStringCreateLtoR(str, XmSTRING_DEFAULT_CHARSET);
  118.     XtSetArg(al[ac], XmNlabelType, XmSTRING); ac++;
  119.     XtSetArg(al[ac], XmNlabelString, label_label); ac++;
  120.     XtSetValues(w, al, ac);
  121.     XmUpdateDisplay(w);
  122. }
  123.  
  124. void displayerror(t, side)
  125. char *t;
  126. int side;
  127. {
  128.  
  129.     if (side == LEFT)
  130.         set_label(leftinfolabel, t);
  131.     else
  132.         set_label(rightinfolabel, t);
  133.  
  134. }
  135.  
  136. void add_size(ptr)
  137. struct Entry *ptr;
  138. {
  139.     size = size + ptr->size;
  140. }
  141.  
  142.  
  143.  
  144. void display_info(side)
  145. int side;
  146. {
  147. int *sellist;
  148. int numsel, n;
  149. char line[255];
  150.  
  151.     numsel = 0;
  152.     size = 0;
  153.     if (side == LEFT)
  154.         {
  155.         numsel = foreachleft(add_size);
  156.         sprintf(line, "%d selected, %d bytes", numsel, size);
  157.         set_label(leftinfolabel, line);
  158.         }
  159.     else
  160.         {
  161.         numsel = foreachright(add_size);
  162.         sprintf(line, "%d selected, %d bytes", numsel, size);
  163.         set_label(rightinfolabel, line);
  164.         }
  165.  
  166. }
  167.  
  168. int dir_list(list, dir, ptrs)
  169. /* ** read a dir from 'dir' string and set the list contents in widget 'list **/
  170. Widget list;
  171. char *dir; 
  172. struct Entry *ptrs[];
  173. {
  174. Arg al[10];
  175. int ac;
  176. DIR *dirl;
  177. struct dirent *dent;
  178. XmString item_array[DIRSIZE];
  179. int items,loop, side, n;
  180. struct stat buf;
  181. char info_line[255];
  182. char p[10];
  183. mode_t mode;
  184.  
  185.     if (list == leftlist)
  186.         side = LEFT;
  187.     else
  188.         side = RIGHT;
  189.  
  190.     dirl = opendir(dir);
  191.     if (dirl == NULL)
  192.         {
  193.         displayerror("can't open dir", side);
  194.         return(0);
  195.         }
  196.  
  197.     if (side == LEFT)
  198.         {
  199.         for (n=0; n < leftlistnum; n++)
  200.              free(ptrs[n]);
  201.         }
  202.     else 
  203.         {
  204.         for (n=0; n < rightlistnum; n++)
  205.              free(ptrs[n]);
  206.         }
  207.     items = 0;
  208.     for ( dent = readdir(dirl); dent != NULL ; dent = readdir(dirl) )
  209.         {
  210.         char path[MAXNAMLEN];
  211.  
  212.         sprintf(path, "%s/%s", dir, dent->d_name);
  213.         stat(path, &buf);
  214.  
  215.         ptrs[items] = (struct Entry *)malloc(sizeof(struct Entry));
  216.         ptrs[items]->dir = S_ISDIR(buf.st_mode);
  217.         ptrs[items]->size = buf.st_size;
  218.         ptrs[items]->mode = buf.st_mode;
  219.         ptrs[items]->name = STRING(dent->d_name);
  220.         ptrs[items]->path = STRING(dir);
  221.         ptrs[items]->fullname = XtMalloc(strlen(dir)+strlen(dent->d_name)+2);
  222.         sprintf(ptrs[items]->fullname, "%s/%s", dir, dent->d_name);
  223.         items++;
  224.         }
  225.  
  226.     closedir(dirl);
  227.  
  228.     qsort(ptrs, items, sizeof(struct Entry *), compare);
  229.  
  230.     for (loop=0; loop < items; loop++)
  231.         {
  232.         char t;
  233.  
  234.         t = ' ';
  235.         if (ptrs[loop]->dir)
  236.             t='/';
  237.         else
  238.         if (ptrs[loop]->mode & S_IXUSR)
  239.             t = '*';
  240.     mode = ptrs[loop]->mode;
  241.     strcpy(p, "----------");
  242.     if (ptrs[loop]->dir)
  243.         p[0] = 'd';
  244.     if (mode & S_IRUSR)
  245.         p[1] = 'r';
  246.     if (mode & S_IWUSR)
  247.         p[2] = 'w';
  248.     if (mode & S_IXUSR)
  249.         p[3] = 'x';
  250.     if (mode & S_IRGRP)
  251.         p[4] = 'r';
  252.     if (mode & S_IWGRP)
  253.         p[5] = 'w';
  254.     if (mode & S_IXGRP)
  255.         p[6] = 'x';
  256.     if (mode & S_IROTH)
  257.         p[7] = 'r';
  258.     if (mode & S_IWOTH)
  259.         p[8] = 'w';
  260.     if (mode & S_IXOTH)
  261.         p[9] = 'x';
  262.  
  263.         sprintf(info_line, " %s %8d %s%c", p, ptrs[loop]->size, ptrs[loop]->name, t);
  264.         item_array[loop] = (XmString)XmStringCreateLtoR(info_line, XmSTRING_DEFAULT_CHARSET);
  265.         }
  266.  
  267.     ac = 0;
  268.     XtSetArg(al[ac], XmNitems, (XtArgVal)item_array); ac++;
  269.     XtSetArg(al[ac], XmNitemCount, (XtArgVal)items); ac++;
  270.     XtSetValues(list, al, ac);
  271.     XmListDeselectAllItems(list);
  272.     displayerror("OK.", side);
  273.     return(items);
  274. }
  275.  
  276. void read_left()
  277. {
  278.     set_label(leftinfolabel, "Reading directory...");
  279.     leftlistnum = dir_list(leftlist, leftcd, leftptrs);
  280. }
  281.  
  282. void read_right()
  283. {
  284.     set_label(rightinfolabel, "Reading directory...");
  285.     rightlistnum = dir_list(rightlist, rightcd, rightptrs);
  286. }
  287.  
  288. void do_left()
  289. {
  290.     getwd(leftcd);
  291.     XmTextSetString(leftdirtext, leftcd);
  292.     read_left();
  293. }
  294.  
  295. void do_right()
  296. {
  297.     getwd(rightcd);
  298.     XmTextSetString(rightdirtext, rightcd);
  299.     read_right();
  300. }
  301.  
  302. void init()
  303. {
  304.     do_left();
  305.     do_right();
  306. }
  307.  
  308.  
  309.  
  310. void newleftdir()
  311. {
  312.     strcpy(leftcd, XmTextGetString(leftdirtext));
  313.     read_left();
  314. }
  315.  
  316. void newrightdir()
  317. {
  318.     strcpy(rightcd, XmTextGetString(rightdirtext));
  319.     read_right();
  320. }
  321.  
  322.  
  323.  
  324. void sys(com)
  325. char *com;
  326. {
  327.     fprintf(stdout, "%s\n", com);
  328.     system(com);
  329.     if (readaftercommand)
  330.         {
  331.         read_left();
  332.         read_right();
  333.         }
  334.  
  335. }
  336.  
  337.      
  338.  
  339.  
  340.  
  341. void killpop(w, c1, c2)
  342. Widget w;
  343. {
  344.     XtUnmanageChild(w);
  345.     XtDestroyWidget(w);
  346. }
  347.  
  348.  
  349. static XtCallbackRec call_kill[] = { {(XtCallbackProc)killpop, (caddr_t)NULL},
  350.                             { (XtCallbackProc)NULL, (caddr_t)NULL} };
  351.  
  352.  
  353.  
  354. void string_popup(title, info, initstr, callback, entry)
  355. char *title, *info, *initstr;
  356. XtCallbackProc callback;
  357. struct Entry *entry;
  358. {
  359. Widget pop, stringtext, outer, rc, label;
  360. Arg al[10];
  361. int ac;
  362. FILE *fp = NULL;
  363. Widget okbutton, cancelbutton, cancelallbutton;
  364.  
  365.  
  366.     ac = 0;
  367.     XtSetArg(al[ac], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL);  ac++;
  368.     XtSetArg(al[ac], XmNselectionLabelString, XmStringCreate(info, XmSTRING_DEFAULT_CHARSET) ); ac++;
  369.     XtSetArg(al[ac], XmNtextString, XmStringCreate(initstr, XmSTRING_DEFAULT_CHARSET) ); ac++;
  370.     pop = XmCreatePromptDialog(toplevel, "stringpopup", al, ac);
  371.     outer = XtParent(pop);
  372.  
  373.     ac = 0;
  374.     XtSetArg(al[ac], XmNunmapCallback, call_kill);  ac++;
  375.     XtSetValues(outer, al, ac);
  376.  
  377.     stringtext = XmSelectionBoxGetChild(pop, XmDIALOG_TEXT );
  378.  
  379.     okbutton = XmSelectionBoxGetChild(pop, XmDIALOG_OK_BUTTON);
  380.     cancelbutton = XmSelectionBoxGetChild(pop, XmDIALOG_CANCEL_BUTTON);
  381.  
  382.     XtUnmanageChild(XmSelectionBoxGetChild(pop, XmDIALOG_HELP_BUTTON) );
  383.  
  384.     XtAddCallback(pop, XmNokCallback, callback, (XtPointer)entry);
  385.     XtAddCallback(pop, XmNcancelCallback, callback, (XtPointer)entry);
  386.  
  387.     XtUnmanageChild(XmSelectionBoxGetChild(pop, XmDIALOG_SEPARATOR ) );
  388.  
  389.     ac = 0;
  390.     XtSetArg (al[ac], XmNtitle, title); ac++;
  391.     XtSetValues(outer, al, ac);
  392.  
  393.     XtManageChild(pop);
  394. }
  395.  
  396.  
  397. void view_window(str, title)
  398. char *str;
  399. char *title;
  400. {
  401. Widget pop, textwindow, outer;
  402. Arg al[10];
  403. int ac;
  404.     ac = 0;
  405.     XtSetArg(al[ac], XmNokLabelString, XmStringCreate("Close", XmSTRING_DEFAULT_CHARSET) ); ac++;
  406.     pop = XmCreatePromptDialog(toplevel, "textpopup", al, ac);
  407.     outer = XtParent(pop);
  408.  
  409.     ac = 0;
  410.     XtSetArg(al[ac], XmNunmapCallback, call_kill);  ac++;
  411.     XtSetValues(outer, al, ac);
  412.  
  413.     XtUnmanageChild(XmSelectionBoxGetChild(pop, XmDIALOG_SELECTION_LABEL) );
  414.     XtUnmanageChild(XmSelectionBoxGetChild(pop, XmDIALOG_TEXT ) );
  415.     XtUnmanageChild(XmSelectionBoxGetChild(pop, XmDIALOG_SEPARATOR ) );
  416.     XtUnmanageChild(XmSelectionBoxGetChild(pop, XmDIALOG_APPLY_BUTTON) );
  417.     XtUnmanageChild(XmSelectionBoxGetChild(pop, XmDIALOG_CANCEL_BUTTON) );
  418.     XtUnmanageChild(XmSelectionBoxGetChild(pop, XmDIALOG_HELP_BUTTON) );
  419.  
  420.  
  421.     ac = 0;
  422.  
  423.     XtSetArg(al[ac], XmNeditMode, XmMULTI_LINE_EDIT); ac++;
  424.     XtSetArg(al[ac], XmNscrollLeftSide, TRUE); ac++;
  425.     textwindow = XmCreateScrolledText(pop, "textwindow", al, ac);
  426.     XtManageChild(textwindow);
  427.  
  428.     ac = 0;
  429.     XtSetArg (al[ac], XmNtitle, title); ac++;
  430.     XtSetValues(outer, al, ac);
  431.  
  432.     XmTextSetString(textwindow, str);
  433.     XmUpdateDisplay(textwindow);
  434.     XtManageChild(pop);
  435. }
  436.  
  437.  
  438. void text_popup(filename)
  439. char *filename;
  440. {
  441.  
  442. FILE *fp = NULL;
  443. int file_length;
  444. char * file_string;
  445. struct stat statbuf;
  446.  
  447.  
  448.     /** load the file **/
  449.  
  450.     if ((fp = fopen(filename, "r")) == NULL)
  451.         {
  452.         char line[255];
  453.  
  454.             sprintf(line, "can't open file %s for viewing\n", filename);
  455.             fprintf(stderr, line);
  456.             return;
  457.         }
  458.  
  459.     
  460.     if (stat(filename, &statbuf) == 0)
  461.         file_length = statbuf.st_size;
  462.     file_string = (char *) XtMalloc((unsigned)file_length+1);
  463.     file_string[file_length]='\0';
  464.     fread(file_string, sizeof(char), file_length, fp);
  465.     if (fclose(fp) != NULL)
  466.         fprintf(stdout, "%s\n", "Warning: unable to close file.");
  467.  
  468.     view_window(file_string, filename);
  469.     XtFree(file_string);
  470.  
  471.  
  472. }
  473.  
  474.  
  475. char *dumporama(file)
  476. char* file;
  477. {
  478.     struct stat statbuf;
  479.     char ch,str[17];
  480.     char line[80];
  481.     char hex[4];
  482.     char* massivebuf;
  483.     char* massiveptr;
  484.     int i,count=0,offset=(-16);
  485.     int fd;
  486.     int wanted;
  487.  
  488.     str[16]='\0';
  489.     if ((fd=open(file,O_RDONLY,0))==-1) {
  490.         fprintf(stderr,"cannot open %s\n",file);
  491.         return(NULL);
  492.     }
  493.     if (fstat(fd,&statbuf))
  494.     {
  495.         fprintf(stderr,"cannot stat file\n");
  496.         return(NULL);
  497.     }
  498.     wanted=(statbuf.st_size)*75+1;
  499.     massiveptr=massivebuf=(char*)malloc(wanted);
  500.     if (!massivebuf)
  501.     {
  502.         fprintf(stderr,"cannot malloc %d bytes\n",wanted);
  503.         return(NULL);
  504.     }
  505.     sprintf(line,"%6X: ",offset+=16);
  506.     while (read(fd,&ch,1)>0)
  507.     {
  508.         ch=(int)ch&0xff;
  509.         str[count++]=((ch>31 && ch<127)?ch:'.');
  510.         sprintf(hex,"%2.2X ",(int) ch&0xff);
  511.         strcat(line,hex);
  512.         if (count==16)
  513.         {
  514.             count=0;
  515.             strcat(line,": ");
  516.             strcat(line,str);
  517.             sprintf(massiveptr,"%s\n",line);
  518.             massiveptr+=strlen(line)+1;
  519.             sprintf(line,"%6X: ",offset+=16);
  520.         }
  521.     }
  522.     sprintf(massiveptr,"%s",line);
  523.     massiveptr+=strlen(line);
  524.     close(fd);
  525.     if (count>0) for (i=count;i<16;i++)
  526.     {
  527.         sprintf(massiveptr,(i!=15)?"-- ":"-- : ");
  528.         massiveptr+=(i!=15)?3:5;
  529.     }
  530.     i=count;
  531.     while (count>0)
  532.     {
  533.         sprintf(massiveptr,count==0?"%c\n":"%c",str[i-count--]);
  534.         massiveptr+=count==0?2:1;
  535.     }
  536.     return(massivebuf);
  537. }
  538.  
  539.  
  540.  
  541. void hex_popup(filename)
  542. char *filename;
  543. {
  544. char *string;
  545.  
  546.     string = dumporama(filename);
  547.     if (string != NULL)
  548.         {
  549.         view_window(string, filename);
  550.         free(string);
  551.         }
  552. }
  553.  
  554. executeCB(w, c1, calldata)
  555. Widget w;
  556. caddr_t c1;
  557. caddr_t calldata;
  558. {
  559. char *param;
  560. XmSelectionBoxCallbackStruct *call;
  561. char *line;
  562. char *command = (char*)c1;
  563.  
  564.     call = (XmSelectionBoxCallbackStruct *)calldata;
  565.     if (call->reason != XmCR_CANCEL)
  566.         {
  567.         XmStringGetLtoR(call->value, XmSTRING_DEFAULT_CHARSET, ¶m);
  568.         line = XtMalloc(strlen(command) + strlen(param) + 1);
  569.         sprintf(line, command, param);
  570.         sys(line);
  571.         XtFree(line);
  572.         }
  573. }
  574.  
  575. void execute(command)
  576. char *command;
  577. {
  578. int len = strlen(command);
  579. char *newcmd = malloc(len+1);
  580. char *promptstring = malloc(len+1);
  581. char *titlestring = malloc(len+1);
  582. int newptr = 0;
  583. int callbackused;
  584. int tit = 0;
  585. int pit = 0;
  586. int n;
  587. Boolean popupneeded = FALSE;
  588.  
  589.     for (n=0; n< len; n++)
  590.         {
  591.         if (command[n] == '^')
  592.             {
  593.             popupneeded = TRUE;
  594.             while (command[++n] != '@')
  595.                 titlestring[tit++] = command[n];
  596.             titlestring[tit] = '\0';
  597.             while (command[++n] != '^')
  598.                 promptstring[pit++] = command[n];
  599.             promptstring[pit] = '\0';
  600.             n++;
  601.             newcmd[newptr++] = '%';
  602.             newcmd[newptr++] = 's';
  603.             }
  604.          newcmd[newptr++] = command[n];
  605.          }
  606.      newcmd[newptr] =  '\0';
  607.  
  608.      if (popupneeded)
  609.          string_popup(titlestring, promptstring, "", executeCB, newcmd);
  610.      else
  611.          sys(command);
  612. }
  613.  
  614. void renameCB(w, c1, calldata)
  615. Widget w;
  616. caddr_t c1;
  617. caddr_t calldata;
  618. {
  619. char *newname;
  620. XmSelectionBoxCallbackStruct *call;
  621. char newpath[255];
  622. struct Entry *e;
  623.  
  624.     e=(struct Entry *)c1;
  625.  
  626.     call = (XmSelectionBoxCallbackStruct *)calldata;
  627.  
  628.     if (call->reason != XmCR_CANCEL)
  629.         {
  630.         XmStringGetLtoR(call->value, XmSTRING_DEFAULT_CHARSET, &newname);
  631.         sprintf(newpath, "%s/%s", e->path, newname);
  632.         if (rename(e->fullname, newpath) !=0)
  633.             fprintf(stderr, "Error: rename %s %s failed.\n", e->fullname, newpath); 
  634.         }
  635.  
  636.     rename_popups--;
  637.     if (rename_popups == 0) /** reread the dir after all the popups have gone **/
  638.         {
  639.         read_left();
  640.         read_right();
  641.         } 
  642.  
  643. }
  644.  
  645. int foreachleft(func)
  646. int (*func)();
  647. {
  648. int *sellist;
  649. int numsel, n;
  650.  
  651.     if (XmListGetSelectedPos(leftlist, &sellist, &numsel) )
  652.         for (n = 0; n < numsel; n++)
  653.             (*func)(leftptrs[sellist[n]-1]);
  654.     else
  655.         numsel = 0;
  656.     return(numsel);
  657. }
  658.  
  659. int foreachright(func)
  660. int (*func)();
  661. {
  662. int *sellist;
  663. int numsel, n;
  664.  
  665.     if (XmListGetSelectedPos(rightlist, &sellist, &numsel) )
  666.         for (n = 0; n < numsel; n++)
  667.             (*func)(rightptrs[sellist[n]-1]);
  668.     else
  669.         numsel = 0;
  670.     return(numsel);
  671.  
  672. }
  673.  
  674. int foreachselected(func)
  675. int (*func)();
  676. {
  677.     return(foreachleft(func) + foreachright(func));
  678. }
  679.  
  680.  
  681. int rename_one_file(ent)
  682. struct Entry *ent;
  683. {
  684. char *tstr;
  685. static char text[]="Enter new name for : ";
  686.  
  687.     printf("rename %s\n", ent->name);
  688.     tstr = XtMalloc(strlen(text) + strlen(ent->fullname) +2);
  689.     sprintf(tstr, "%s%s", text, ent->fullname );
  690.     string_popup("Rename", tstr, ent->name, (XtCallbackProc)renameCB, ent);
  691.     rename_popups++;
  692.     XtFree(tstr);
  693. }
  694.  
  695.  
  696. void ren(w, c1, c2)
  697. /** rename the selected files **/
  698. Widget w;
  699. caddr_t c1, c2;
  700. {
  701.     rename_popups = 0;
  702.     foreachselected(rename_one_file);
  703. }
  704.  
  705.  
  706. void view_one_file(ptr)
  707. struct Entry *ptr;
  708. {
  709.      text_popup(ptr->fullname);
  710. }
  711.  
  712.  
  713. void view(w, c1, c2)
  714. /** view the selected files **/
  715. Widget w;
  716. caddr_t c1;
  717. caddr_t c2;
  718. {
  719.     foreachselected(view_one_file);
  720. }
  721.  
  722. void hex_view_one_file(ptr)
  723. struct Entry *ptr;
  724. {
  725.      hex_popup(ptr->fullname);
  726. }
  727.  
  728. void hex_view(w, c1, c2)
  729. /** view the selected files **/
  730. Widget w;
  731. caddr_t c1;
  732. caddr_t c2;
  733. {
  734.     foreachselected(hex_view_one_file);
  735. }
  736.  
  737.  
  738. void do_each_one(ptr)
  739. struct Entry *ptr;
  740. {
  741. char line[255];
  742.  
  743.     sprintf(line, command_string, ptr->fullname);
  744.     execute(line);
  745. }
  746.  
  747.  
  748. void do_each(command, rereaddir)
  749. /** execute the command for each file that is selected **/
  750. char *command;
  751. Boolean rereaddir;
  752. {
  753. int *sellist;   
  754. int numsel, n;
  755. char line[255], path[255];
  756.  
  757.     command_string = command;
  758.     readaftercommand = rereaddir;
  759.     foreachselected(do_each_one);
  760. }
  761.  
  762. void do_sourcedest(command, rereaddir)
  763. char *command;
  764. Boolean rereaddir;
  765. {
  766. char *string;
  767. int *sellist;   
  768. int numsel, n, len;
  769. char *tptr, *fname;
  770. char *line;
  771.  
  772.     string = NULL;
  773.     chdir(leftcd);
  774.     readaftercommand = rereaddir;
  775.  
  776.     if (XmListGetSelectedPos(leftlist, &sellist, &numsel) )
  777.     {
  778.     for (n = 0; n < numsel; n++)
  779.         {
  780.         fname = leftptrs[sellist[n]-1]->name;
  781.         len = strlen(fname);
  782.         if (strcmp(fname, "..") && strcmp(fname, "."))
  783.             {
  784.             if (string == NULL)
  785.                 {
  786.                 string = XtMalloc(len+2);
  787.                 sprintf(string, "%s ", fname);
  788.                 }
  789.             else
  790.                 {
  791.                 tptr = XtMalloc(strlen(string)+len+2);
  792.                 sprintf(tptr, "%s ", string);
  793.                 strcat(tptr, fname);
  794.                 XtFree(string);
  795.                 string = tptr;
  796.                 }
  797.             }
  798.         }
  799.     printf("source dest = \"%s\"\n", string);
  800.     line = XtMalloc(strlen(string)+strlen(command)+strlen(rightcd));
  801.     sprintf(line,command, string, rightcd);
  802.     execute(line);
  803.     XtFree(line);
  804.     XtFree(string);
  805.  
  806. /**    if (rereaddir)
  807.         {
  808.         newleftdir();
  809.         newrightdir();
  810.         }
  811. **/
  812.     display_info(LEFT);
  813.     display_info(RIGHT);
  814.  
  815.     }
  816.  
  817.  
  818. }
  819.  
  820. void assemble_str(ptr)
  821. struct Entry *ptr;
  822. {
  823. char *nstr;
  824. char *t;
  825.  
  826.     if (astring == NULL)
  827.         astring = strcpy(XtMalloc(strlen(ptr->fullname)+1),ptr->fullname); 
  828.  
  829.     else
  830.  
  831.         {
  832.         nstr = XtMalloc(strlen(ptr->fullname) + 2);
  833.         sprintf(nstr, " %s", ptr->fullname);
  834.         t = XtMalloc(strlen(nstr) + strlen(astring) + 1);
  835.         strcpy(t, astring);
  836.         strcat(t, nstr);
  837.         XtFree(astring);
  838.         astring = t;
  839.         XtFree(nstr);
  840.         }
  841. }
  842.  
  843.         
  844.  
  845. void do_allpath(command, rereaddir)
  846. /** execute a single command with each file that is selected **/
  847. char *command;
  848. Boolean rereaddir;
  849. {
  850. char *s;
  851.  
  852.     if (astring != NULL)
  853.         {
  854.         XtFree(astring);
  855.         astring = NULL;
  856.         }
  857.     readaftercommand = rereaddir;
  858.     if (foreachselected(assemble_str))
  859.         {
  860.         s = XtMalloc(strlen(command) + strlen(astring) + 2);
  861.         sprintf(s, command, astring);
  862.         execute(s);
  863.         XtFree(s);
  864.         }
  865. }
  866.  
  867.  
  868. void do_all(command, rereaddir)
  869. /** execute a single command with each file that is selected **/
  870. char *command;
  871. Boolean rereaddir;
  872. {
  873.  
  874. int *sellist;   
  875. int numsel;
  876. char *line;
  877. int len, n;
  878. char *string, *fname;
  879. char *tptr, path[255];
  880. char fullname[255];
  881.  
  882.     string = NULL;
  883.     chdir(leftcd);
  884.  
  885.     readaftercommand = rereaddir;
  886.  
  887.     if (XmListGetSelectedPos(leftlist, &sellist, &numsel) )
  888.     {
  889.     for (n = 0; n < numsel; n++)
  890.         {
  891.         fname = leftptrs[sellist[n]-1]->name;
  892.         sprintf(fullname, "%s/%s", path, fname);
  893.         len = strlen(fname);
  894.         if (string == NULL)
  895.             {
  896.             string = XtMalloc(len);
  897.             sprintf(string, "%s", fname);
  898.             }
  899.         else
  900.             {
  901.             tptr = XtMalloc(strlen(string)+len+2);
  902.             sprintf(tptr, "%s ", string);
  903.             strcat(tptr, fname);
  904.             XtFree(string);
  905.             string = tptr;
  906.             }
  907.         }
  908.     }
  909.  
  910.     
  911.     if (XmListGetSelectedPos(rightlist, &sellist, &numsel) )
  912.     {
  913.     if (strcmp(leftcd, rightcd))
  914.         {
  915.         if (string!=NULL)    /** execute the command if there is one **/
  916.             {
  917.             line = XtMalloc(strlen(string) + strlen(command) + 2);
  918.             sprintf(line, command, string);
  919.             execute(line);
  920.             }
  921.         chdir(rightcd);
  922.         *path = '\0';
  923.         XtFree(string);
  924.         string = NULL;
  925.         }
  926.  
  927.  
  928.     strcpy(path, rightcd);
  929.  
  930.     for (n = 0; n < numsel; n++)
  931.         {
  932.         fname = rightptrs[sellist[n]-1]->name;
  933.         if (!(*path!='\0'))
  934.             sprintf(fullname, "%s/%s", path, fname);
  935.         else
  936.             sprintf(fullname, "%s", fname);
  937.  
  938.         len = strlen(fullname);
  939.         if (string == NULL)
  940.             {
  941.             string = XtMalloc(len+2);
  942.             sprintf(string, " %s", fullname);    /** this space should not be in the string! */
  943.             }
  944.         else
  945.             {
  946.             tptr = XtMalloc(strlen(string)+len+2);
  947.             sprintf(tptr, "%s ", string);
  948.             strcat(tptr, fullname);
  949.             XtFree(string);
  950.             string = tptr;
  951.             }
  952.         }
  953.     }
  954.  
  955.     if (string == NULL)
  956.         return;
  957.  
  958.     line = XtMalloc(strlen(string) + strlen(command) + 2);
  959.     sprintf(line, command, string);
  960.     execute(line);
  961.     XtFree(line);
  962.  
  963.     XtFree(string);
  964.  
  965. }
  966.  
  967. void prog_button(w, c1, c2)
  968. /** a user defined button has been pressed **/
  969. Widget w;
  970. caddr_t c1;
  971. caddr_t c2;
  972. {
  973. int b, context;
  974. char *str;
  975. Boolean reread;
  976.  
  977.     b = (int)c1;
  978.     context = buttonlist[b]->context;
  979.     str = buttonlist[b]->command;
  980.     reread = buttonlist[b]->reread;
  981.     
  982.     switch (context)
  983.         {
  984.         case BCOMMAND:     readaftercommand = reread; execute(str); break;
  985.         case BEACH:    do_each(str, reread); break;
  986.         case BALL:     do_all(str, reread); break;
  987.         case BALLPATH:     do_allpath(str, reread); break;
  988.         case BSOURCEDEST: do_sourcedest(str, reread); break;
  989.         }
  990. }
  991.  
  992. void do_magic_file(m, name)
  993. int m;
  994. char *name;
  995. {
  996. char command[255];
  997.  
  998.     if (*magiclist[m]->mstring == '*')
  999.         {
  1000.         if (!strcmp(magiclist[m]->mstring, "*view") )
  1001.             text_popup(name);
  1002.         if (!strcmp(magiclist[m]->mstring, "*hex") )
  1003.             hex_popup(name);
  1004.         }
  1005.     else
  1006.         {
  1007.         readaftercommand = magiclist[m]->mreread;
  1008.         sprintf(command, magiclist[m]->mstring, name);
  1009.         execute(command);
  1010.         }
  1011. }
  1012.  
  1013. void selection(w, side, c2)
  1014. /** a list item was selected by a single click **/
  1015. Widget w;
  1016. caddr_t side;
  1017. caddr_t c2;
  1018. {
  1019. int s;
  1020.     s = (int)side;
  1021.     display_info(s);
  1022.     if (side ==LEFT)
  1023.         chdir(leftcd);
  1024.     else
  1025.         chdir(rightcd);
  1026. }
  1027.        
  1028.  
  1029. void dc_selection(w, side, c2)
  1030. Widget w;
  1031. caddr_t side;
  1032. caddr_t c2;
  1033. {
  1034. /** a list item was selected by a double click **/
  1035. int pos;
  1036. XmListCallbackStruct *cb =  (XmListCallbackStruct *)c2;
  1037. char *fname, *path, *fullname;
  1038. int n, fmode;
  1039. Boolean fdir;
  1040.  
  1041.     pos = (cb->item_position) - 1;
  1042.  
  1043.     if ((int)side == LEFT)
  1044.         {
  1045.         fname = leftptrs[pos]->name;
  1046.         fdir = leftptrs[pos]->dir;
  1047.         fmode = leftptrs[pos]->mode;
  1048.         fullname = leftptrs[pos]->fullname;
  1049.         path = leftcd;
  1050.         }
  1051.     else
  1052.         {
  1053.         fname = rightptrs[pos]->name;
  1054.         fdir = rightptrs[pos]->dir;
  1055.         fmode = rightptrs[pos]->mode;
  1056.         fullname = rightptrs[pos]->fullname;
  1057.         path = rightcd;
  1058.         }
  1059.  
  1060.     /** if the file is a dir then attempt to change **/
  1061.     if (fdir)
  1062.         {
  1063.         if (chdir(fullname) != 0)
  1064.             displayerror("can't change dir!\n", (int)side );
  1065.         else
  1066.             {
  1067.             if ((int)side == RIGHT)
  1068.                 do_right();
  1069.             else
  1070.                 do_left();
  1071.             }
  1072.         }
  1073.     else
  1074.     {
  1075.     for (n=0; n<num_magic; n++)
  1076.         {
  1077.         if ((magiclist[n]->mtype == MFILE) && (!strcmp(fname, magiclist[n]->mname)) )
  1078.             do_magic_file(n, fullname);    
  1079.         }
  1080.  
  1081.     for (n=0; n<num_magic; n++)
  1082.         {
  1083.         char *cf;
  1084.         cf = fname + strlen(fname)-strlen(magiclist[n]->mname);
  1085.  
  1086.         if ((magiclist[n]->mtype == MSUFFIX) && (!strcmp(cf, magiclist[n]->mname)) )
  1087.             do_magic_file(n, fullname);    
  1088.         }
  1089.  
  1090.     if (fmode & S_IXUSR) /**execute it if it has execute permission **/
  1091.         {
  1092.         char *line;
  1093.  
  1094.             line = XtMalloc(strlen(fullname)+3);
  1095.             sprintf(line, "%s &", fullname);
  1096.             execute(line);
  1097.             XtFree(line);
  1098.         }
  1099.  
  1100.     }
  1101. }
  1102.  
  1103. void get_magic()
  1104. {
  1105. FILE *mfile;    
  1106. char mtype[255], mname[255], mreread[255], mstring[255];
  1107. int mline;
  1108. char *m;
  1109. char magic_path[255];
  1110.  
  1111.  
  1112.     sprintf(magic_path, "%s/%s", xbrowserpath, MAGIC_FILE);
  1113.  
  1114.     num_magic = 0;
  1115.     mline = 0;
  1116.     if (!(mfile = fopen(magic_path, "r")))
  1117.         {
  1118.         fprintf(stderr, "can't open magic file %s.\n", magic_path);
  1119.         return;   
  1120.         }
  1121.  
  1122.     while (1)
  1123.         {
  1124.         if (fscanf(mfile, "%s%s%s %[ ]" , mtype, mname, mreread) == -1)
  1125.             break;
  1126.         if (fgets(mstring, 255, mfile) == NULL)
  1127.             {
  1128.             fprintf(stderr, "error in magic file line:%d\n",mline);
  1129.             break;
  1130.             }
  1131.         else
  1132.             mstring[strlen(mstring)-1] = '\0';  /** clear return chr **/
  1133.  
  1134.         if (mtype[0] != '#') 
  1135.             {
  1136.             if (debug)
  1137.                 fprintf(stdout, "mclass = %s \t mstring = %s \t\t mcommand = %s\n",mtype, mname, mstring);
  1138.             magiclist[num_magic] = (struct Magic *)malloc(sizeof(struct Magic));
  1139.             if (!strcmp("file", mtype))
  1140.                 magiclist[num_magic]->mtype = MFILE; 
  1141.             else
  1142.             if (!strcmp("suffix", mtype))
  1143.                 magiclist[num_magic]->mtype = MSUFFIX; 
  1144.             else
  1145.                 fprintf(stderr, "unknown magic type line:%d\n", mline);
  1146.             
  1147.             magiclist[num_magic]->mname = STRING(mname);
  1148.             magiclist[num_magic]->mstring = STRING(mstring);
  1149.             if (*mreread == 'y' || *mreread == 'Y')
  1150.                 magiclist[num_magic]->mreread = TRUE;
  1151.             else
  1152.             if (*mreread == 'n' || *mreread == 'N')
  1153.                 magiclist[num_magic]->mreread = FALSE;
  1154.             else
  1155.                 fprintf(stderr, "error in magic file (rereaddir) line:%d\n",mline);
  1156.  
  1157.             num_magic++;
  1158.             }
  1159.  
  1160.         mline++;
  1161.         }
  1162.     fclose(mfile);
  1163.     if (debug)
  1164.         fprintf(stdout, "\n\nMagic file read, %d lines, %d magic classes\n\n\n", mline+1, num_magic);
  1165. }
  1166.  
  1167.  
  1168. void get_buttons(parent)
  1169. Widget parent;
  1170. {
  1171. FILE *mfile;    
  1172. char mcontext[255], mname[255], mreread[255], mstring[255], button_label[255];
  1173. int mline;
  1174. Widget w;
  1175. Boolean make_button;
  1176. Arg al[10];
  1177. int ac;
  1178. char button_path[255];
  1179.  
  1180.     num_buttons = 0;
  1181.     mline = 0;
  1182.     sprintf(button_path, "%s/%s", xbrowserpath, BUTTONS_FILE);
  1183.  
  1184.     if (!(mfile = fopen(button_path, "r")))
  1185.         {
  1186.         fprintf(stderr, "can't open buttons file %s.\n", button_path);
  1187.         return;   
  1188.         }
  1189.  
  1190.     while (1)
  1191.         {
  1192.         if (fscanf(mfile, "%s %s%s %[ ]" , mname, mcontext, mreread) == -1)
  1193.             break;
  1194.         if (fgets(mstring, 255, mfile) == NULL)
  1195.             {
  1196.             fprintf(stderr, "error in button file line:%d\n",mline);
  1197.             break;
  1198.             }
  1199.         else
  1200.             mstring[strlen(mstring)-1] = '\0';  /** clear return chr **/
  1201.  
  1202.         if (mname[0] != '#') 
  1203.             {
  1204.             make_button = TRUE;
  1205.             if (debug)
  1206.                 fprintf(stdout, "bname = %s \t bcontext = %s \t bstring = %s\n",mname, mcontext, mstring);
  1207.             buttonlist[num_buttons] = (struct Button *)malloc(sizeof(struct Button));
  1208.             if (!strcmp("all", mcontext))
  1209.                 buttonlist[num_buttons]->context = BALL; 
  1210.             else
  1211.             if (!strcmp("allpath", mcontext))
  1212.                 buttonlist[num_buttons]->context = BALLPATH; 
  1213.             else
  1214.             if (!strcmp("each", mcontext))
  1215.                 buttonlist[num_buttons]->context = BEACH; 
  1216.             else
  1217.             if (!strcmp("command", mcontext))
  1218.                 buttonlist[num_buttons]->context = BCOMMAND;
  1219.             else
  1220.             if (!strcmp("sourcedest", mcontext))
  1221.                 buttonlist[num_buttons]->context = BSOURCEDEST;
  1222.             else
  1223.                 {
  1224.                 fprintf(stderr, "unknown button context line:%d\n", mline);
  1225.                 make_button = FALSE;
  1226.                 }
  1227.  
  1228.             if (*mreread == 'y' || *mreread == 'Y')
  1229.                 buttonlist[num_buttons]->reread = TRUE;
  1230.             else
  1231.             if (*mreread == 'n' || *mreread == 'N')
  1232.                 buttonlist[num_buttons]->reread = FALSE;
  1233.             else
  1234.                 {
  1235.                 fprintf(stderr, "error in buttons file (rereaddir) line:%d\n",mline);
  1236.                 make_button = FALSE;
  1237.                 }
  1238.  
  1239.             if (make_button)
  1240.                 {
  1241.                 buttonlist[num_buttons]->command = STRING(mstring);
  1242.                 ac = 0;
  1243.                 XtSetArg(al[ac], XmNlabelString, XmStringCreate(mname, XmSTRING_DEFAULT_CHARSET) ); ac++;
  1244.                 w = XtCreateManagedWidget("button", xmPushButtonWidgetClass, parent, al, ac);
  1245.                 XtAddCallback(w, XmNactivateCallback, prog_button, (XtPointer)num_buttons);
  1246.                 num_buttons++;
  1247.                 }
  1248.             }
  1249.  
  1250.         mline++;
  1251.         }
  1252.     fclose(mfile);
  1253.  
  1254.     if (debug)
  1255.         fprintf(stdout, "\n\nButton file read, %d lines, %d buttons\n\n\n", mline+1, num_buttons);
  1256. }
  1257.  
  1258. void quit(w, c1, c2)
  1259. Widget w;
  1260. caddr_t c1;
  1261. caddr_t c2;
  1262. {
  1263.     fprintf(stdout, "Bye!\n");
  1264.     exit(0);
  1265. }
  1266.  
  1267. void select_all(w, side, c2)
  1268. Widget w;
  1269. caddr_t side;
  1270. caddr_t c2;
  1271. {
  1272. Widget list;
  1273. int n, maxi;
  1274.  
  1275.     if ( (int)side == LEFT)
  1276.         {
  1277.         maxi = leftlistnum;
  1278.         list = leftlist;
  1279.         }
  1280.     else
  1281.         {
  1282.         list = rightlist;
  1283.         maxi = rightlistnum;
  1284.         }
  1285.     XmListDeselectAllItems(list);
  1286.     for (n = 1; n <=maxi; n++)
  1287.         XmListSelectPos(list, n, FALSE);
  1288.     display_info((int)side);
  1289. }
  1290.  
  1291. void select_files(w, side, c2)
  1292. Widget w;
  1293. caddr_t side;
  1294. caddr_t c2;
  1295. {
  1296. Widget list;
  1297. int n, maxi;
  1298. struct Entry *(*ptrs);
  1299.  
  1300.     if ( (int)side == LEFT)
  1301.         {
  1302.         maxi = leftlistnum;
  1303.         list = leftlist;
  1304.         ptrs = leftptrs;
  1305.         }
  1306.     else
  1307.         {
  1308.         list = rightlist;
  1309.         maxi = rightlistnum;
  1310.         ptrs = rightptrs;
  1311.         }
  1312.     XmListDeselectAllItems(list);
  1313.     for (n = 1; n <=maxi; n++)
  1314.         if (!ptrs[n-1]->dir)
  1315.             XmListSelectPos(list, n, FALSE);
  1316.     display_info((int)side);
  1317. }
  1318.  
  1319. void invert_all(w, side, c2)
  1320. Widget w;
  1321. caddr_t side;
  1322. caddr_t c2;
  1323. {
  1324. Widget list;
  1325. int n, maxi;
  1326.  
  1327.     if ( (int)side == LEFT)
  1328.         {
  1329.         maxi = leftlistnum;
  1330.         list = leftlist;
  1331.         }
  1332.     else
  1333.         {
  1334.         list = rightlist;
  1335.         maxi = rightlistnum;
  1336.         }
  1337.  
  1338.     for (n = 1; n <=maxi; n++)
  1339.         XmListSelectPos(list, n, FALSE);
  1340.     display_info((int)side);
  1341. }
  1342.  
  1343. void clear_all(w, side, c2)
  1344. Widget w;
  1345. caddr_t side;
  1346. caddr_t c2;
  1347. {
  1348. Widget list;
  1349.  
  1350.     if ( (int)side == LEFT)
  1351.         list = leftlist;
  1352.     else
  1353.         list = rightlist;
  1354.     XmListDeselectAllItems(list);
  1355.     display_info((int)side);
  1356. }
  1357.  
  1358.  
  1359. void newdir(w, side, c2)
  1360. Widget w;
  1361. caddr_t side;
  1362. caddr_t c2;
  1363. {
  1364. int s;
  1365.     s = (int)side;
  1366.     if (side == LEFT)
  1367.         newleftdir();
  1368.     else 
  1369.         newrightdir();
  1370.  
  1371. }
  1372.  
  1373.  
  1374. Widget make_side(side, title, parentform, dirtext, list, label)
  1375. int side;
  1376. char *title;
  1377. Widget parentform;
  1378. Widget *dirtext;
  1379. Widget *list;
  1380. Widget *label;
  1381. {
  1382. Widget sidef, sideform, sidelabel, sidedirtext, sidelist, siderc, w;
  1383. Arg al[10];
  1384. int ac;
  1385.  
  1386.     ac = 0;
  1387.     XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  1388.     XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  1389.     XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  1390.     sidef = XtCreateManagedWidget("sideform", xmFormWidgetClass, parentform, al, ac);
  1391.  
  1392.     ac = 0;
  1393.     XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  1394.     XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  1395.     XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  1396.     sideform = XtCreateManagedWidget("sideform", xmFormWidgetClass, sidef, al, ac);
  1397.  
  1398.     ac = 0;
  1399.     XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  1400.     XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  1401.     XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  1402.     sidelabel = XtCreateManagedWidget(title, xmLabelWidgetClass, sideform, al, ac);
  1403.  
  1404.     ac = 0;
  1405.     XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
  1406.     XtSetArg(al[ac], XmNtopWidget, sidelabel); ac++;
  1407.     XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  1408.     XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  1409.     sidedirtext = XtCreateManagedWidget("sidedir", xmTextWidgetClass, sideform, al, ac);
  1410.     XtAddCallback(sidedirtext, XmNactivateCallback, (XtCallbackProc)newdir, (XtPointer)side);
  1411.  
  1412.  
  1413.     ac = 0;
  1414.     XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
  1415.     XtSetArg(al[ac], XmNtopWidget, sidedirtext); ac++;
  1416.     XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  1417.     XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  1418.     XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  1419.     XtSetArg(al[ac], XmNselectionPolicy, XmMULTIPLE_SELECT); ac++;
  1420.  
  1421.     sidelist = XmCreateScrolledList(sideform, "sidelist", al, ac);
  1422.     XtAddCallback(sidelist, XmNmultipleSelectionCallback, selection, (XtPointer)side);
  1423.     XtAddCallback(sidelist, XmNdefaultActionCallback, dc_selection, (XtPointer)side);
  1424.     XtManageChild(sidelist);
  1425.  
  1426.     ac = 0;
  1427.     XtSetArg(al[ac], XmNentryAlignment, XmALIGNMENT_CENTER); ac++;
  1428.     XtSetArg(al[ac], XmNorientation, XmHORIZONTAL); ac++;
  1429.     XtSetArg(al[ac], XmNpacking, XmPACK_COLUMN); ac++;
  1430.     siderc = XtCreateManagedWidget("siderc", xmRowColumnWidgetClass, sidef, al, ac);
  1431.  
  1432.     ac = 0;
  1433.     XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
  1434.     XtSetArg(al[ac], XmNbottomWidget, siderc); ac++;
  1435.     XtSetValues(sideform, al, ac);
  1436.  
  1437.  
  1438.     ac = 0;
  1439.     w = XtCreateManagedWidget("All", xmPushButtonWidgetClass, siderc, al, ac);
  1440.     XtAddCallback(w, XmNactivateCallback, select_all, (XtPointer)side);
  1441.     w = XtCreateManagedWidget("Clear", xmPushButtonWidgetClass, siderc, al, ac);
  1442.     XtAddCallback(w, XmNactivateCallback, clear_all, (XtPointer)side);
  1443.     w = XtCreateManagedWidget("Files", xmPushButtonWidgetClass, siderc, al, ac);
  1444.     XtAddCallback(w, XmNactivateCallback, select_files, (XtPointer)side);
  1445.     w = XtCreateManagedWidget("Invert", xmPushButtonWidgetClass, siderc, al, ac);
  1446.     XtAddCallback(w, XmNactivateCallback, invert_all, (XtPointer)side);
  1447.  
  1448.     ac = 0;
  1449.     XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  1450.     XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  1451.     XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  1452.     XtSetArg(al[ac], XmNmarginLeft, 10); ac++;
  1453.     XtSetArg(al[ac], XmNmarginHeight, 4); ac++;
  1454.     XtSetArg(al[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++;
  1455.     sidelabel = XtCreateManagedWidget("sidelabel", xmLabelWidgetClass, sidef, al, ac);
  1456.  
  1457.     ac = 0;
  1458.     XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
  1459.     XtSetArg(al[ac], XmNbottomWidget, sidelabel); ac++;
  1460.     XtSetValues(siderc, al, ac);
  1461.  
  1462.     *dirtext = sidedirtext;
  1463.     *list = sidelist;
  1464.     *label = sidelabel;
  1465.  
  1466.     return(sidef);
  1467. }
  1468.  
  1469.  
  1470. main(argc, argv)
  1471. int argc;
  1472. char *argv[];
  1473. {
  1474. Widget topform, topformframe, w, mainform, mainlabel;
  1475. Widget leftform, rightform, buttonrc, buttonrcframe;
  1476. XtAppContext app_con;
  1477.  
  1478.  
  1479. Arg al[10];
  1480. int ac;
  1481.  
  1482.     toplevel = XtAppInitialize(&app_con, "Xbrowser", NULL, 0,
  1483.                    &argc, argv, fallback_resources, NULL, 0);
  1484.  
  1485.     if ( (argc == 2) && (!strcmp(argv[1], "-debug") ) )
  1486.         debug = TRUE;
  1487.     else
  1488.         debug = FALSE;
  1489.  
  1490.     if (debug)
  1491.         printf("xbrowser path = %s\n", getenv("XBROWSER") );
  1492.     xbrowserpath = getenv("XBROWSER");
  1493.     if (xbrowserpath == NULL)
  1494.         xbrowserpath = STRING(".");
  1495.     get_magic();
  1496.  
  1497.     ac = 0;
  1498.     mainform = XtCreateManagedWidget("mainform", xmFormWidgetClass, toplevel, al, ac);
  1499.  
  1500.     ac = 0;
  1501.     XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  1502.     XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  1503.     XtSetArg(al[ac], XmNmarginHeight, 5); ac++;
  1504.     XtSetArg(al[ac], XmNlabelString,
  1505.         XmStringCreate(VERSIONSTRING, XmSTRING_DEFAULT_CHARSET)); ac++;
  1506.     mainlabel = XtCreateManagedWidget("title", xmLabelWidgetClass, mainform, al, ac);
  1507.  
  1508.     ac = 0;
  1509.     XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
  1510.     XtSetArg(al[ac], XmNtopWidget, mainlabel); ac++;
  1511.     XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  1512.     XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  1513.     XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  1514.     XtSetArg(al[ac], XmNshadowType, XmSHADOW_OUT); ac++;
  1515.     topformframe = XtCreateManagedWidget("topformframe", xmFrameWidgetClass, mainform, al, ac);
  1516.  
  1517.     ac = 0;
  1518.     topform = XtCreateManagedWidget("topform", xmFormWidgetClass, topformframe, al, ac);
  1519.  
  1520.     leftform = make_side(LEFT, "Source:", topform, &leftdirtext, &leftlist, &leftinfolabel);
  1521.     rightform = make_side(RIGHT, "Destination:", topform, &rightdirtext, &rightlist, &rightinfolabel);
  1522.  
  1523.     /** button strip frame**/
  1524.     ac = 0;
  1525.     XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  1526.     XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  1527.     XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  1528.     XtSetArg(al[ac], XmNshadowType, XmSHADOW_OUT); ac++;
  1529.     buttonrcframe = XtCreateManagedWidget("buttonstripframe", xmFrameWidgetClass, topform, al, ac);
  1530.  
  1531.     /** button strip **/
  1532.     ac = 0;
  1533.     XtSetArg(al[ac], XmNorientation, XmHORIZONTAL); ac++;
  1534.     XtSetArg(al[ac], XmNentryAlignment, XmALIGNMENT_CENTER); ac++;
  1535.     buttonrc = XtCreateManagedWidget("buttonstrip", xmRowColumnWidgetClass, buttonrcframe, al, ac);
  1536.  
  1537.     ac = 0;
  1538.     w = XtCreateManagedWidget("QUIT", xmPushButtonWidgetClass, buttonrc, al, ac);
  1539.     XtAddCallback(w, XmNactivateCallback, quit, NULL);
  1540.     w = XtCreateManagedWidget("VIEW", xmPushButtonWidgetClass, buttonrc, al, ac);
  1541.     XtAddCallback(w, XmNactivateCallback, view, NULL);
  1542.     w = XtCreateManagedWidget("HEX-VIEW", xmPushButtonWidgetClass, buttonrc, al, ac);
  1543.     XtAddCallback(w, XmNactivateCallback, hex_view, NULL);
  1544.     w = XtCreateManagedWidget("RENAME", xmPushButtonWidgetClass, buttonrc, al, ac);
  1545.     XtAddCallback(w, XmNactivateCallback, ren, NULL);
  1546.  
  1547.     get_buttons(buttonrc);
  1548.  
  1549.     /** attach to button strip **/
  1550.     ac = 0;
  1551.     XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
  1552.     XtSetArg(al[ac], XmNbottomWidget, buttonrcframe); ac++;
  1553.     XtSetValues(rightform, al, ac);
  1554.     XtSetValues(leftform, al, ac);
  1555.  
  1556.     ac = 0;
  1557.     XtSetArg(al[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
  1558.     XtSetArg(al[ac], XmNrightPosition, 50); ac++;
  1559.     XtSetValues(leftform, al, ac);
  1560.  
  1561.     ac = 0;
  1562.     XtSetArg(al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
  1563.     XtSetArg(al[ac], XmNleftWidget, leftform); ac++;
  1564.     XtSetArg(al[ac], XmNleftOffset, 10); ac++;
  1565.     XtSetValues(rightform, al, ac);
  1566.  
  1567.     init();
  1568.  
  1569.     XtRealizeWidget(toplevel);
  1570.     XtAppMainLoop(app_con);
  1571. }
  1572.