home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume17 / tcl-editor / part09 / browser.c next >
Encoding:
C/C++ Source or Header  |  1992-03-18  |  20.3 KB  |  838 lines

  1. /* $Header: /nfs/unmvax/faculty/crowley/x/pt/RCS/browser.c,v 1.12 1992/03/04 17:07:18 crowley Exp crowley $ */
  2.  
  3. #include <sys/types.h>
  4. #include <string.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include "pt.h"
  8. #ifdef SYSV
  9. /*** NECESSARY? #include <libgen.h> ***/
  10. #include <dirent.h>
  11. #else
  12. #include <sys/dir.h>
  13. #endif
  14. #include <sys/stat.h>
  15. /***#include <stdio.h>***/
  16. #include <X11/keysym.h>
  17. #include <X11/StringDefs.h>
  18.  
  19.  
  20. #define FILENAMESSIZE        10000
  21. #define FILELISTSIZE         1000
  22. #define FILETREECHARSIZE    10000
  23. #define FILETREELISTSIZE     1000
  24. #define HOME                1
  25. #define N_OLD_DIRS           30
  26.  
  27. BrowserData *mainBrowser = NULL;
  28. BrowserData *activeBrowser = NULL;
  29. BrowserData *browserList = NULL;
  30.  
  31. /* open window list data */
  32. OpenWindowStruct *openWindowList;
  33. int numberOfOpenWindows;
  34.  
  35. /* cache of old directory data */
  36. int nextOldDirs = 0;
  37. FileListData *oldDirs[N_OLD_DIRS];
  38.  
  39. #ifdef VAX_FIX
  40. char *
  41. getcwd( buffer, length )
  42.     char * buffer;
  43.     int length;
  44. {
  45.     char *getwd();
  46.  
  47.     return getwd( buffer );
  48. }
  49. int
  50. isspace( c )
  51.     char c;
  52. {
  53.     return c==' '||c=='\t'||c=='\n'||c=='\r'||c=='\f';
  54. }
  55. double
  56. strtod( str, ptr )
  57.     char * str;
  58.     char ** ptr;
  59. {
  60.     double d = atof( str );
  61.  
  62.     /* this is not exactly correct put will do for here */
  63.     if( ptr != NULL )
  64.         *ptr = str + strlen(str);
  65.     return d;
  66. }
  67. #endif
  68.  
  69. static void
  70. InitializeDirectoryCache()
  71. {
  72.     int i;
  73.     FileListData *fl;
  74.     int size = sizeof(FileListData);
  75.     
  76.     for( i = 0; i < N_OLD_DIRS; ++i ) {
  77.         fl = (FileListData *)PtMalloc( size, "list of files" );
  78.         fl->fileNames = NULL;
  79.         fl->listOfFilesShowing = NULL;
  80.         fl->numberOfFilesShowing = 0;
  81.         fl->ino = 0;
  82.         fl->mtime = 0;
  83.         fl->directoryName = NULL;
  84.         fl->age = 0;
  85.         fl->use_count = 0;
  86.         fl->flags = 0;
  87.         fl->filePattern[0] = '\0';
  88.         oldDirs[i] = fl;
  89.     }
  90. }
  91.  
  92. BrowserData *
  93. FindBrowserByTkName( name )
  94.     char * name;
  95. {
  96.     extern BrowserData * browserList;
  97.  
  98.     BrowserData * browser = browserList;
  99.  
  100.     while( browser != NULL ) {
  101.         if( strcmp( browser->tk_pathname, name ) == 0 )
  102.             break;
  103.         browser = browser->nextBrowser;
  104.     }
  105.     return browser;
  106. }
  107.  
  108. void
  109. ReduceUseCount( fl )
  110.     FileListData *fl;
  111. {
  112.     int i;
  113.  
  114.     for( i = 0; i < N_OLD_DIRS; ++i ) {
  115.         if( fl == oldDirs[i] ) {
  116.             --(fl->use_count);
  117.             break;
  118.         }
  119.     }
  120. }
  121.  
  122. extern struct window *activeWindow;
  123. extern Display *MainDisplay;
  124.  
  125. #ifdef LATERLATER
  126. void
  127. ptBrowserLetter(w, event, args, nargs)
  128.     int w;
  129.     XKeyEvent *event;
  130.     String *args;
  131.     Cardinal *nargs;
  132. {
  133.     extern char msgBuffer[];
  134.     extern char * textGeometry;
  135.     extern int debug;
  136.  
  137.     char buf[4];
  138.     int ret;
  139.     KeySym keysym;
  140.     static char prefix[100];
  141.     static int iprefix = 0;
  142.     static int last_index = -1;
  143.  
  144.     if( event->type != KeyPress )
  145.         return;
  146.     ret = XLookupString(event, buf, 4, &keysym, NULL);
  147.     buf[ret] = '\0';
  148.     if( ret != 1 ) {
  149.         switch( keysym ) {
  150.         case XK_Shift_L:
  151.         case XK_Shift_R:
  152.         case XK_Control_L:
  153.         case XK_Control_R:
  154.         case XK_Caps_Lock:
  155.         case XK_Shift_Lock:
  156.         case XK_Meta_L:
  157.         case XK_Meta_R:
  158.         case XK_Alt_L:
  159.         case XK_Alt_R:
  160.         case XK_Super_L:
  161.         case XK_Super_R:
  162.         case XK_Hyper_L:
  163.         case XK_Hyper_R:
  164.             /* modifier keys, ignore them */
  165.             return;
  166.         }
  167.     }
  168.     if( ret == 1 ) {
  169.         char **list = activeBrowser->fileListData->listOfFilesShowing;
  170.         int num = activeBrowser->fileListData->numberOfFilesShowing;
  171.         int i;
  172.         if( buf[0] == '\r' ) {
  173.             if( last_index != -1 ) {
  174. #ifdef LATER
  175.                 OpenListFile( buf, textGeometry );
  176. #endif
  177.                 printf("Unhighlight list item\n");
  178.             } else if( iprefix == 0 ) {
  179.                 XBell( MainDisplay, 0 );
  180.                 printf("No file selected\n");
  181.             } else {
  182.                 GetNewFile( NULL, prefix, textGeometry );
  183.             }
  184.         } else {
  185.     startOver:
  186.             prefix[iprefix++] = buf[0];
  187.             prefix[iprefix] = '\0';
  188.             for( i = 0; i < num; ++i ) {
  189.                 if( strncmp(prefix,list[i],iprefix) == 0 ) {
  190.                     printf("Highlight list item\n");
  191.                     last_index = i;
  192.                     break;
  193.                 }
  194.             }
  195.             if( i >= num ) {
  196.                 last_index = -1;
  197.                 printf("Unhighlight list item\n");
  198.             }
  199.         }
  200.     } else {
  201.         iprefix = 0;
  202.         last_index = -1;
  203.         printf("Unhighlight list item\n");
  204.     }
  205. }
  206. #endif
  207.  
  208. void
  209. ChangeBrowserFontTo( browser, fontName )
  210.     BrowserData *browser;
  211.     char *fontName;
  212. {
  213.     extern char msgBuffer[];
  214.     extern Tcl_Interp * interp;
  215.  
  216.     XFontStruct *fontInfo;
  217.  
  218. retry_font:
  219.     fontInfo = Tk_GetFontStruct( interp, browser->tk_toplevel,
  220.                         Tk_GetUid(fontName) );
  221.     if( fontInfo == NULL ) {
  222.         printf("Cannot load font %s, using \"fixed\"\n", fontName );
  223.         fontName = "fixed";
  224.         goto retry_font;
  225.     }
  226.     (browser->browserFont).height = fontInfo->ascent + fontInfo->descent;
  227.     (browser->browserFont).width  = fontInfo->max_bounds.width;
  228.     (browser->browserFont).ascent = fontInfo->ascent;
  229.     Tk_FreeFontStruct( fontInfo );
  230.  
  231.     sprintf( msgBuffer, "%s.fileList.list configure -font %s",
  232.                     browser->tk_pathname, fontName );
  233.     (void)ExecTclCommand( (char *)msgBuffer );
  234.  
  235.     sprintf( msgBuffer, "%s.openList.list configure -font %s",
  236.                     browser->tk_pathname, fontName );
  237.     (void)ExecTclCommand( (char *)msgBuffer );
  238. }
  239.  
  240. void
  241. RaiseListWindow( n, geometry )
  242.     int n;
  243.     char * geometry;
  244. {
  245.     extern char msgBuffer[];
  246.  
  247.     struct window * w;
  248.  
  249.     if( n < 0 || n >= numberOfOpenWindows ) {
  250.         printf("MakeActiveWindow: index=%d should be < %d\n",
  251.             n, numberOfOpenWindows );
  252.         return;
  253.     }
  254.     w = openWindowList[n].w;
  255.     if( w != NULL ) {
  256.         activeWindow = w;
  257.         sprintf( msgBuffer, "MoveWindow %s", geometry );
  258.         (void)ExecTclCommand( (char *)msgBuffer );
  259.     } else
  260.         printf("ERROR: window %s not found in list of open windows\n",
  261.             openWindowList[n].name);
  262. }
  263.  
  264. int
  265. listComp( a, b )
  266.     char *a;
  267.     char *b;
  268. {
  269.     extern int showDirsFirst;
  270.     extern int showSizes;
  271.  
  272.     if( showDirsFirst ) {
  273.         char last_in_a;
  274.         char last_in_b;
  275.         char * end_of_a = strlen(*(char **)a) - 1 + *(char **)a;
  276.         char * end_of_b = strlen(*(char **)b) - 1 + *(char **)b;
  277.         /* ignore the file size if present */
  278.         if( showSizes ) {
  279.             /* back up past the ' (NNNk)' */
  280.             while( *end_of_a-- != ' ' )
  281.                 /*EMPTY*/
  282.                 ;
  283.             while( *end_of_b-- != ' ' )
  284.                 /*EMPTY*/
  285.                 ;
  286.         }
  287.         /* get the last character in the file name */
  288.         last_in_a = *end_of_a;
  289.         last_in_b = *end_of_b;
  290.         if( last_in_a == '/' ) {
  291.             if( last_in_b != '/' )
  292.                 return -1;
  293.         } else {
  294.             if( last_in_b == '/' )
  295.                 return 1;
  296.         }
  297.     }
  298.     return strcmp(*(char **)a, *(char **)b);
  299. }
  300.  
  301. int
  302. openComp( a, b )
  303.     char *a;
  304.     char *b;
  305. {
  306.     return strcmp(  ((OpenWindowStruct *)a)->name,
  307.             ((OpenWindowStruct *)b)->name );
  308. }
  309.  
  310. #ifdef SVR4
  311. #undef SYSV
  312. #define SYSV
  313. #endif
  314.  
  315. /*SUPPRESS 68*/ /*SUPPRESS 544*/
  316.  
  317. void
  318. NewFilelist( browser )
  319.     BrowserData *browser;
  320. {
  321.     extern char * filePattern;
  322.     extern char msgBuffer[];
  323.     extern char textBuffer[];
  324.     extern char currentDirectory[];
  325.     extern int showSizes;
  326.     extern int debug;
  327.  
  328.     DIR *dirp;
  329. #ifdef SYSV
  330.     struct dirent *dp;
  331. #else
  332.     struct direct *dp;
  333. #endif
  334.     int namelength;
  335.     char *endFileNames, *curFileNames;
  336.     char **endList, **curList;
  337.     int wide;
  338.     struct stat statbuf;
  339.     int nCols;
  340.     int longestName;
  341.     int i, col, oldest_unused, oldest_age, new_dir;
  342.     char *p;
  343.     char *pp;
  344.     FileListData *fl;
  345.     char flags;
  346.     char buffer[256];
  347.     char * from, * to, * re_bad;
  348.  
  349.     /* to save computation keep local copies of these */
  350.     char *fileNames;
  351.     char **listOfFilesShowing;
  352.     int numberOfFilesShowing;
  353.  
  354.     /* protect myself (this happens during initialization) */
  355.     if( browser == NULL )
  356.         return;
  357.     /* make up the flags byte */
  358.     flags = 0;
  359.     if( showSizes )
  360.         flags |= SHOW_SIZES_FLAG;
  361.  
  362.     /* get the current directory and change the label to display it */
  363.     (void)getcwd(currentDirectory, FILENAMESIZE);
  364.     strncpy(browser->cwd, currentDirectory, FILENAMESIZE);
  365.  
  366.     /* see if this directory is in our cache (and has not changed) */
  367.     stat( currentDirectory, &statbuf );    /* get inode and mtime */
  368.     oldest_unused = 0;    /* always have a legal value */
  369.     oldest_age = -1;
  370.     new_dir = -1;
  371.     for( i = 0; i < N_OLD_DIRS; ++i ) {
  372.         fl = oldDirs[i];    /* constantly used so get ptr */
  373.         /* increment the age and look for the oldest, unused one */
  374.         ++(fl->age);
  375.         if( fl->use_count == 0 && fl->age > oldest_age ) {
  376.             oldest_age = fl->age;
  377.             oldest_unused = i;
  378.         }
  379.         /* look for the old directory in the cache */
  380.         if( fl == browser->fileListData ) {
  381.             --(fl->use_count);
  382.         }
  383.         /* if this directory is in the cache and unchanged, use it */
  384.         if( fl->ino==statbuf.st_ino && fl->mtime==statbuf.st_mtime
  385.          && fl->flags==flags && fl->showSizes==showSizes
  386.          && strcmp(fl->filePattern,filePattern)==0 ) {
  387.              fl->age = 0;    /* restart aging */
  388.              ++(fl->use_count);    /* another user of this one */
  389.              new_dir = i;
  390.          }
  391.     }
  392.     if( new_dir >= 0 ) {    /* found it in the cache */
  393.         fl = oldDirs[new_dir];
  394.         browser->fileListData = fl;
  395.         longestName = fl->longestname;
  396.         listOfFilesShowing = fl->listOfFilesShowing;
  397.         numberOfFilesShowing = fl->numberOfFilesShowing;
  398.         goto changeDisplay;
  399.     }
  400.     /* else erase the oldest entry in the directory cache, */
  401.     fl = oldDirs[oldest_unused];
  402.  
  403.     /* free the strings whose pointers we will write over */
  404.     PtFree( fl->fileNames );
  405.     PtFree( (char *)(fl->listOfFilesShowing) );
  406.     PtFree( fl->directoryName );
  407.  
  408.     /* initialize the fields */
  409.     browser->fileListData = fl;
  410.     fl->age = 0;
  411.     fl->use_count = 1;
  412.     fl->ino = statbuf.st_ino;
  413.     fl->mtime = statbuf.st_mtime;
  414.     fl->flags = flags;
  415.     strncpy( fl->filePattern, filePattern, 128 );
  416.  
  417.     /* remember the directory name */
  418.     p = (char *)PtMalloc( strlen(currentDirectory)+1, "directory name" );
  419.     strcpy( p, currentDirectory );
  420.     fl->directoryName = (char *)p;
  421.     
  422.     /* allocate the space for the lists */
  423.     fileNames = PtMalloc(FILENAMESSIZE*sizeof(char), "file names" );
  424.     endFileNames = fileNames + FILENAMESSIZE;
  425.     curFileNames = fileNames;
  426.     listOfFilesShowing = (char **)PtMalloc(FILELISTSIZE*sizeof(char *),
  427.                         (char *)"files showing" );
  428.     endList = listOfFilesShowing + FILELISTSIZE;
  429.     curList = listOfFilesShowing;
  430.  
  431.     /* set up the regular expression to check the filenames against */
  432.     to = buffer;
  433.     from = fl->filePattern;
  434.     *to++ = '^';
  435.     while( 1 ) {
  436.         char ch = *from++;
  437.         switch( ch ) {
  438.             case '\0':
  439.                 *to++ = '$';
  440.                 *to = '\0';
  441.                 goto out;
  442.             case '*':
  443.                 *to++ = '.';
  444.                 break;
  445.             case '?':
  446.                 ch = '.';
  447.                 break;
  448.             case '.':
  449.                 *to++ = '\\';
  450.                 break;
  451.         }
  452.         *to++ = ch;
  453.     }
  454. out:
  455.     if( (re_bad = re_comp(buffer)) != NULL ) {
  456.         printf("RE error: %s\n", re_bad);
  457.     }
  458.     
  459.     dirp = opendir(".");
  460.     if( dirp == NULL ) {
  461.         extern int errno;
  462.         extern int sys_nerr;
  463.         extern char *sys_errlist[];
  464.         if( errno < sys_nerr )
  465.             p = (char *)sys_errlist[errno];
  466.         else
  467.             p = (char *)"";
  468.         sprintf( msgBuffer, "Open directory failed: %s", (char *)p );
  469.         msg( (char *)msgBuffer, 1 );
  470.         *curList = "Could not open directory";
  471.         longestName = strlen(*curList);
  472.         numberOfFilesShowing = 1;
  473.         goto skipDirectorySearch;
  474.     }
  475.     /* put in the Tk command */
  476.     numberOfFilesShowing = 0;
  477.     longestName = 0;
  478.     dp = readdir(dirp);    /* skip '.' (which is always first) */
  479.     for( dp = readdir(dirp); dp != NULL; dp = readdir(dirp) ) {
  480. #ifdef SYSV
  481.         namelength = strlen(dp->d_name);
  482. #else
  483.         namelength = dp->d_namlen;
  484. #endif
  485.         stat(dp->d_name, &statbuf);
  486.         if( (statbuf.st_mode & S_IFMT)!=S_IFDIR &&  re_bad==NULL ) {
  487.             i = re_match( dp->d_name );
  488.             if( i < 1 ) {
  489. printf(" (NoMatch %s)", dp->d_name);
  490.                 continue;
  491.             }
  492.         }
  493.         if( curFileNames + namelength >= endFileNames ) {
  494.             printf("name list overflow\n");
  495. /* LATER REALLOCATE THE LIST LARGER */
  496.             break;
  497.         }
  498.         if( curList >= endList ) {
  499.             printf("pointer list overflow\n");
  500.             /* later reallocate the list larger */
  501.             break;
  502.         }
  503.         *curList++ = curFileNames;
  504.         strcpy(curFileNames, dp->d_name);
  505.         curFileNames += namelength + 1;    /* +1 for the nul */
  506.         if( (statbuf.st_mode & S_IFMT) == S_IFDIR ) {
  507.             *--curFileNames = '/';
  508.             *++curFileNames = '\0';
  509.             ++curFileNames;
  510.             ++(namelength);
  511.         }
  512.         if( showSizes ) {
  513.             char s[25];
  514.             int i, l;
  515.             sprintf( s, " (%dk)", (statbuf.st_size+1023)/1024 );
  516.             l = strlen( s );
  517.             --curFileNames;        /* back up over the '\0' */
  518.             for( i = 0; i <= l; ++i ) {
  519.                 *curFileNames++ = s[i];
  520.             }
  521.             /* this loop will copy the '\0' also */
  522.             namelength += l;
  523.         }
  524.         if( namelength > longestName )
  525.             longestName = namelength;
  526.         ++numberOfFilesShowing;
  527.     }
  528.     closedir(dirp);
  529.  
  530.     /* sort the file names */
  531.     qsort( (char *)listOfFilesShowing, numberOfFilesShowing,
  532.             sizeof(char *), listComp);
  533.  
  534. skipDirectorySearch:
  535.     /* put everything back into the structure */
  536.     fl->fileNames = fileNames;
  537.     fl->listOfFilesShowing = listOfFilesShowing;
  538.     fl->numberOfFilesShowing = numberOfFilesShowing;
  539.     fl->longestname = longestName;
  540.     fl->showSizes = showSizes;
  541.  
  542. changeDisplay:
  543.     /* figure out how many columns to use */
  544.         /* for big browsers only */
  545.     {
  546.         int columnSpacing = 7;
  547.         int overhead = 46;
  548.  
  549.         wide = Tk_Width( browser->tk_toplevel ) - overhead;
  550.         col = longestName*((browser->browserFont).width)+columnSpacing;
  551.         nCols = (wide + columnSpacing) / col;
  552.         if( nCols < 1 )
  553.             nCols = 1;
  554.         sprintf(msgBuffer,"%s.fileList.list configure -columns %d",
  555.                         browser->tk_pathname, nCols );
  556.         (void)ExecTclCommand( (char *)msgBuffer );
  557.     }
  558.  
  559.     /* make this the new list */
  560.     /* first delete all the old list elements */
  561.     sprintf( msgBuffer, "catch {%s.fileList.list delete 0 end}",
  562.                             browser->tk_pathname );
  563.     (void)ExecTclCommand( (char *)msgBuffer );
  564.     
  565.     /* then insert each file name in the new list */
  566.     for( i = 0; i < numberOfFilesShowing; ++i ) {
  567.         sprintf( msgBuffer, "%s.fileList.list insert end \"%s\"",
  568.                 browser->tk_pathname, listOfFilesShowing[i] );
  569.         (void)ExecTclCommand( (char *)msgBuffer );
  570.     }
  571.  
  572.     /* store the directory name in the window title */
  573.     strcpy( msgBuffer, browser->cwd );
  574.     pp = tildefyFilename( (char *)msgBuffer );
  575.     sprintf( textBuffer,
  576.         "wm title %s {%s};wm iconname %s {%s}",
  577.             browser->tk_pathname, pp, browser->tk_pathname, pp );
  578.     (void)ExecTclCommand( textBuffer );
  579. }
  580.  
  581. void
  582. NewOpenList( )
  583. {
  584.     extern struct openFile *files;
  585.     extern struct window *windowList;
  586.     extern char msgBuffer[];
  587.     extern int pathNames;
  588.     extern int debug;
  589.     extern struct openFile *files;
  590.     extern BrowserData *browserList;
  591.  
  592.     int col;
  593.     int n, wide, nCols, len, longestName;
  594.     struct window *w;
  595.     char *s, *new_s;
  596.     BrowserData *browser;
  597.  
  598.     /* free the old space first */
  599.     if( openWindowList != NULL ) {
  600.         int i = 0;
  601.         OpenWindowStruct *sp = openWindowList;
  602.         while( i++ < numberOfOpenWindows )
  603.             PtFree( (sp++)->name );
  604.         PtFree((char *)openWindowList);
  605.     }
  606.         
  607.     /* see how many windows there are */
  608.     w = windowList;
  609.     numberOfOpenWindows = 0;
  610.     while( w != NULL ) {
  611.         ++numberOfOpenWindows;
  612.         w = w->nextWindow;
  613.     }
  614.  
  615.     /* always have at least one space in openWindowList */
  616.     if( (n = numberOfOpenWindows) == 0 )
  617.         n = 1;
  618.     openWindowList = (OpenWindowStruct *) PtMalloc(
  619.             n * sizeof(OpenWindowStruct), "open window list" );
  620.  
  621.     if( numberOfOpenWindows > 0 ) {
  622.         w = windowList;
  623.         longestName = 0;
  624.         n = 0;
  625.         while( n < numberOfOpenWindows ) {
  626.             /* see if we should use the full pathname */
  627.             col = (pathNames ? 0 : w->nameOffset);
  628.             s = &((files[w->fileId].origName)[col]);
  629.             len = strlen(s) + 2;
  630.             /* allocate space for the name and copy it in */
  631.             new_s = (char *)PtMalloc(len, "file name");
  632.             strncpy( new_s, s, len );
  633.             if( files[w->fileId].flags & IS_CHANGED ) {
  634.                 /* if changed add a '*' at the end */
  635.                 --len;    /* we added one for the '\0' */
  636.                 new_s[len-1] = '*';
  637.                 new_s[len] = '\0';
  638.             } else
  639.                 /* otherwise correct the length */
  640.                 len -= 2;
  641.             openWindowList[n].name = new_s;
  642.             if( len > longestName )
  643.                 longestName = len;
  644.             /* remember the window ID so we can raise it easily */
  645.             openWindowList[n].w = w;
  646.             w = w->nextWindow;
  647.             ++n;
  648.         }
  649.         qsort( (char *)openWindowList, numberOfOpenWindows,
  650.                 sizeof(OpenWindowStruct), openComp );
  651.     
  652.     } else {
  653. #define NO_WINDOWS "No Open Windows"
  654.         s = (char *)PtMalloc( strlen(NO_WINDOWS)+1, "file name" );
  655.         strcpy( s, NO_WINDOWS );
  656. #undef NO_WINDOWS
  657.         openWindowList[numberOfOpenWindows].w = NULL;
  658.         openWindowList[numberOfOpenWindows++].name = s;
  659.         longestName = strlen(s);
  660.     }
  661.  
  662.     /* loop through all the browsers and change their open lists */
  663.     for( browser = browserList; browser != NULL;
  664.                     browser = browser->nextBrowser) {
  665.         int columnSpacing = 7;
  666.  
  667.         if( browser->tk_pathname[0] == '\0' )
  668.             /* main browser was not created, so skip it */
  669.             continue;
  670.         /* make this the new list */
  671.         /* first delete all the old list elements */
  672.         sprintf( msgBuffer, "catch {%s.openList.list delete 0 end}",
  673.                             browser->tk_pathname );
  674.         (void)ExecTclCommand( (char *)msgBuffer );
  675.  
  676.         /* then insert each file name in the new list */
  677.         for( n = 0; n < numberOfOpenWindows; ++n ) {
  678.             sprintf( msgBuffer, "%s.openList.list insert end {%s}",
  679.                 browser->tk_pathname, openWindowList[n].name );
  680.             (void)ExecTclCommand( (char *) msgBuffer );
  681.         }
  682.  
  683.         wide = Tk_Width( browser->tk_toplevel ) - 50;
  684.         col = longestName*((browser->browserFont).width)+columnSpacing;
  685.         nCols = (wide + columnSpacing) / col;
  686.         if( nCols < 1 )
  687.             nCols = 1;
  688.         sprintf(msgBuffer,"%s.openList.list configure -columns %d",
  689.                         browser->tk_pathname, nCols );
  690. if( debug == 0 )
  691.         (void)ExecTclCommand( (char *) msgBuffer );
  692.     }
  693.  
  694. }
  695.  
  696. void
  697. CreateNewBrowser( bigBrowser, geometry )
  698.     int bigBrowser;
  699.     char * geometry;
  700. {
  701.     extern struct window *windowList;
  702.     extern int debug;
  703.     extern int thinBrowser;
  704.  
  705.     BrowserData *browser;
  706.  
  707.     /* create the browser data structure */
  708.     browser = (BrowserData *)PtMalloc(sizeof(BrowserData),"browser data");
  709.     browser->fileListData = NULL; /* this is allocated in NewFilelist */
  710.  
  711.     thinBrowser = !bigBrowser;
  712.  
  713.     /* put on the browserList */
  714.     browser->nextBrowser = browserList;
  715.     browser->prevBrowser = NULL;
  716.     browserList->prevBrowser = browser;
  717.     browserList = browser;
  718.     browser->tk_toplevel = NULL;
  719.     CreateBigBrowser( browser, geometry );
  720. }
  721.  
  722. void
  723. CreateBigBrowser( browser, geometry )
  724.     BrowserData *browser;
  725.     char * geometry;
  726. {
  727.     extern BrowserData *activeBrowser;
  728.     extern char msgBuffer[];
  729.     extern char * browserFont;
  730.     extern Tcl_Interp * interp;
  731.     extern int debug;
  732.  
  733.     char * name;
  734.  
  735.     sprintf (msgBuffer, "BrowserWindow %s", geometry );
  736.     name = ExecTclCommand( (char *)msgBuffer );
  737.     browser->tk_pathname = Tk_GetUid( name );
  738.     browser->tk_toplevel = Tk_NameToWindow( interp, browser->tk_pathname,
  739.                         mainBrowser->tk_toplevel );
  740.  
  741.     Tk_SetWindowBackground( browser->tk_toplevel,
  742.             WhitePixelOfScreen(Tk_Screen(browser->tk_toplevel)));
  743.     XSetForeground( Tk_Display(browser->tk_toplevel),
  744.             DefaultGCOfScreen(Tk_Screen(browser->tk_toplevel)),
  745.             BlackPixelOfScreen(Tk_Screen(browser->tk_toplevel)));
  746.             
  747.     ChangeBrowserFontTo( browser, browserFont );
  748.  
  749.     activeBrowser = browser;
  750.     (void)ExecTclCommand( "update" );
  751.     NewOpenList();
  752.  
  753.     /* Now create the list of files */
  754.     NewFilelist( browser );
  755. }
  756.  
  757. Tk_Window TkMainWindow;
  758.  
  759. void
  760. CreateFilelist()
  761. {
  762.     extern Tcl_Interp * interp;
  763.     extern int Pt_ColboxCmd();
  764.     extern char * browserGeometry;
  765.     extern char * thinBrowserGeometry;
  766.     extern int noBrowser;
  767.     extern int thinBrowser;
  768.     extern char msgBuffer[];
  769.  
  770.     Tk_Uid uid;
  771.  
  772.     InitializeDirectoryCache();
  773.  
  774.     /* create the browser data structure */
  775.     mainBrowser = (BrowserData *)PtMalloc( sizeof(BrowserData),
  776.                         "browser data" );
  777.     mainBrowser->fileListData = NULL; /* this is allocated in NewFileList */
  778.     numberOfOpenWindows = 0;
  779.     openWindowList = NULL;
  780.  
  781.     /* make this the only entry in the browserList */
  782.     mainBrowser->nextBrowser = NULL;
  783.     mainBrowser->prevBrowser = NULL;
  784.     browserList = mainBrowser;
  785.  
  786.     /* finish creating the browser */
  787.     /* create the main tcl interpreter and add the Point commands */
  788.     interp = Tcl_CreateInterp();
  789.     AddPointCommands( interp );
  790.     
  791.     /* create the main window and set up some options */
  792.     TkMainWindow = Tk_CreateMainWindow( interp, (char *) NULL, "point");
  793.     mainBrowser->tk_toplevel = TkMainWindow;
  794.     if( mainBrowser->tk_toplevel == NULL ) {
  795.         printf("%s\n", interp->result);
  796.         exit(1);
  797.     }
  798.  
  799.     Tk_SetClass( mainBrowser->tk_toplevel, "Point");
  800.  
  801.     /* check the user's default font, foreground and background. */
  802.     /* Use those if they are defined */
  803.     uid = Tk_GetOption( mainBrowser->tk_toplevel, "font", NULL );
  804.     if( uid == NULL )
  805.         uid = Tk_GetOption( mainBrowser->tk_toplevel, "Font", NULL );
  806.     if( uid != NULL ) {
  807.         SetPointOption( "browserFont", uid );
  808.         SetPointOption( "textFont", uid );
  809.     }
  810.     uid = Tk_GetOption( mainBrowser->tk_toplevel, "foreground", NULL );
  811.     if( uid != NULL )
  812.         SetPointOption( "textForeground", uid );
  813.     uid = Tk_GetOption( mainBrowser->tk_toplevel, "background", NULL );
  814.     if( uid != NULL )
  815.         SetPointOption( "textBackground", uid );
  816.  
  817.     Tcl_CreateCommand( interp, "colbox", Pt_ColboxCmd,
  818.             (ClientData)(mainBrowser->tk_toplevel), NULL );
  819.  
  820.     /* read in the Point proc's and create a browser window */
  821.     sprintf( msgBuffer,
  822. "global PointTclLibrary\n\
  823. set PointTclLibrary \"%s\"\n\
  824. if [file exists $PointTclLibrary/startup.tcl] \"\n\
  825.     source $PointTclLibrary/startup.tcl\n\
  826. \" {puts stderr \"CANNOT FIND A STARTUP FILE. POINT WILL NOT WORK.\"}",
  827.         POINT_LIBRARY );
  828.     (void)ExecTclCommand( msgBuffer );
  829.  
  830.     (void)ExecTclCommand( "if [file exists .ptdirrc] {source .ptdirrc}" );
  831.     Tk_MakeWindowExist( mainBrowser->tk_toplevel );
  832.     mainBrowser->tk_pathname = "";
  833.     if( !noBrowser )
  834.         CreateNewBrowser( !thinBrowser,
  835.             (thinBrowser ? thinBrowserGeometry : browserGeometry));
  836. }
  837.  
  838.