home *** CD-ROM | disk | FTP | other *** search
- /**************************************************************************
- * *
- * Author : Dr. Thomas Brandes, GMD, I1.HR *
- * Date : Nov 92 *
- * Last Update : April 92 *
- * *
- * Module : xfiles *
- * *
- * Function : Athena Widgets for File Handling *
- * *
- * Export : *
- * *
- * void make_file_menu_entries (Widget father) *
- * *
- * Update : Jan 93, Werner Meurer, GMD, I1.HR *
- * *
- * - only source files / directories should appear in the menu *
- * *
- **************************************************************************/
-
- #include <sys/types.h>
- #include <sys/stat.h>
-
- #ifdef SYS_V
- #include <dirent.h>
- #else
- #include <sys/dir.h>
- #endif
-
- #ifdef alliant
- #include <sys/param.h> /* getwd */
- #else
- #include <unistd.h> /* getcwd */
- #endif
-
- #include <string.h>
-
- #include "xglobal.h"
- #include "xfiles.h"
-
- #define ROW 5
-
- bool is_source_file ();
-
- /*********************************************************************
- * *
- * Global Data is Array of Entries *
- * *
- *********************************************************************/
-
- int count; /* Number of entries */
-
- int* ListDirNamePtr; /* pointer to starting places of file names */
- char* ListDirNames; /* pointer to file names */
- int ListDirNamePtrLen = 0;
- int ListDirNamesLen = 0;
-
- /* ListDirNames [ListDirNamePtr[i]] is start of string for entry i */
-
- /* Sorting the entries */
-
- void ListDirSort (nameptr,names,count)
- int *nameptr;
- char *names;
- int count;
-
- { short int l, r;
- short int j, jfinal, k;
- short int np;
-
- if( count <= 1 ) return;
-
- l = count/2;
- r = count - 1;
- while( r >= 1 ){
- if( l > 0 ){/* buildup phase, decrement l */
- --l;
- j = l;
- }
- else{
- /* selection phase, exchange [0] and [r], decrement r */
- np = nameptr[0];
- nameptr[0] = nameptr[r];
- nameptr[r] = np;
- --r;
- j = 0;
- }
- np = nameptr[j];
- jfinal = -1;
-
- while( (k=2*j+1) <= r && jfinal < 0 ){
- /* sink [j] by interchanging it with the larger of its children */
- /* find the larger child, if there are two */
- if( k < r && strcmp( &(names[ nameptr[k ] ]),
- &(names[ nameptr[k+1] ])) < 0 ){
- k++;
- }
- if( strcmp( &(names[ np ]), &(names[ nameptr[ k ] ])) < 0 ){
- /* exchange [j] and [k], move on with [k] */
- nameptr[j] = nameptr[k];
- j = k;
- }
- else{ /* stop here */
- jfinal = j;
- };
- }
-
- /* if stopped, jfinal==j, else jfinal==0. Use j */
- /* store this name into [j] */
-
- nameptr[j] = np;
-
- }
- }/* ListDirSort */
-
- void ListDirMode (nameptr, names, count )
- int *nameptr;
- char *names;
- int count;
-
- {
- int curcount;
- struct stat buf;
- int i;
-
- /* get the mode of each name.
- /* if Directory, add / to name. If executable, add * */
- for( curcount = 0; curcount < count; curcount++ )
- {
- i = nameptr[curcount];
- stat( &(names[i]), &(buf) );
- if( (buf.st_mode & S_IFMT) == S_IFDIR )
- { for( ; names[i]!='\0'; i++){;}
- names[i] = '/';
- names[i+1] = '\0';
- }
- else if( buf.st_mode & 0111 != 0 )
- { for( ; names[i]!='\0'; i++){;}
- names[i] = '*';
- names[i+1] = '\0';
- }
- } /* for */
- }/* ListDirMode */
-
- void get_dir_entries ()
-
- /* collect information of the current Directory */
-
- { DIR* directory; /* directory record */
- #ifdef SYS_V
- struct dirent* direntry;
- #else
- struct direct* direntry; /* directory entry record */
- #endif
- struct stat mode;
- int maxlen, totallen, thislen;
- char *thisptr;
- int curptr, curcount;
-
- /* open a directory, print out the names */
-
- directory = opendir (".");
- if (directory == NULL)
- { printf ("directory cannot be opened\n");
- return;
- }
-
- count = 0;
- maxlen = 0;
- totallen = 0;
-
- /* count the the number of files, get maximum length, total length */
-
- #ifdef alliant
- getwd (current_dir);
- #else
- getcwd (current_dir, sizeof(current_dir));
- #endif
-
- sprintf (last_message, "Current Directory = %s \n", current_dir);
-
- for( direntry = readdir( directory ); direntry != NULL;
- direntry = readdir( directory ))
- {
- stat(direntry->d_name,&mode);
- if ((direntry->d_name[0] != '.' ) &&
- (is_source_file (direntry->d_name,strlen(direntry->d_name)) ||
- ((mode.st_mode & S_IFMT) == S_IFDIR))){
- #ifdef SYS_V
- thislen = strlen(direntry->d_name) + 1;
- #else
- thislen = direntry->d_namlen;
- #endif
- thisptr = direntry->d_name;
- count += 1;
- totallen += thislen;
- maxlen = ( thislen > maxlen ) ? thislen : maxlen;
- }
- }
-
- /* allocate space to hold the names for the sort.
- /* allocate space to hold the name pointers */
-
- if( sizeof(int)*(count+1) > ListDirNamePtrLen )
- { ListDirNamePtrLen = sizeof(int)*(count+1);
- ListDirNamePtr = (int*)malloc((unsigned)ListDirNamePtrLen);
- }
-
- if( totallen + count > ListDirNamesLen )
- { ListDirNamesLen = totallen + count + count;
- ListDirNames = (char*)malloc((unsigned)ListDirNamesLen);
- }
-
- rewinddir (directory);
-
- curptr = 0;
- curcount = 0;
-
- for( direntry = readdir( directory ); direntry != NULL;
- direntry = readdir( directory ))
- { stat(direntry->d_name,&mode);
- if ((direntry->d_name[0] != '.' ) &&
- (is_source_file (direntry->d_name,strlen(direntry->d_name)) ||
- ((mode.st_mode & S_IFMT) == S_IFDIR))){
- thisptr = direntry->d_name;
- #ifdef SYS_V
- thislen = strlen(thisptr);
- #else
- thislen = direntry->d_namlen;
- #endif
- ListDirNamePtr[curcount] = curptr;
- curcount += 1;
- strcpy( &(ListDirNames[ curptr ]), thisptr );
- curptr += thislen + 2;
- ListDirNames[curptr-1] = '\0';
- ListDirNames[curptr-2] = '\0';
- }
- }
-
- ListDirNamePtr[curcount] = 0; /* zero-terminated array */
-
- closedir (directory);
-
- ListDirSort( ListDirNamePtr, ListDirNames, count );
-
- ListDirMode( ListDirNamePtr, ListDirNames, count );
-
- } /* end of get_dir_entries */
-
- /* this subroutine has only been used for tests */
-
- void print_dir_entries ()
- { int i;
- for (i=0; i<count; i++)
- printf ("Entry = %s\n", &ListDirNames[ListDirNamePtr[i]]);
- }
-
- static void DirSelect (w, client_data, garbage)
- Widget w;
- XtPointer client_data;
- XtPointer garbage; /* call_data */
- { Widget menu, father;
- char *name;
- int i;
-
- int pane_num = (int) client_data;
- name = XtName (w);
-
- /* printf("Menu item %s has been selected.\n", name);
- printf("Data is %d\n", pane_num);
- */
-
- for (i=0;name[i]!='\0';i++) {;}
-
- if ( (pane_num == -1) || (name[i-1] == '/') )
- { /* direcory name has been selected */
- chdir (name);
- menu = XtParent (w);
- father = XtParent (menu);
- XtDestroyWidget (menu);
- make_file_menu_entries (father);
- set_message (); /* display current directory */
- }
- else
- { /* file name has been selected */
- strcpy (selected_file, current_dir);
- strcat (selected_file, "/");
- strcat (selected_file, name);
- set_filelabel (); /* Display String in labelWidget */
- strcpy (last_message, "file selected");
- set_message ();
- }
- }
-
- void make_file_menu_entries (father)
-
- Widget father;
-
- { int i;
- Widget entry, menu;
- char *item;
-
- get_dir_entries ();
-
- menu = XtCreatePopupShell("menu", simpleMenuWidgetClass,
- father, NULL, 0);
-
- entry = XtCreateManagedWidget ("..", smeBSBObjectClass, menu, NULL, 0);
- XtAddCallback (entry, XtNcallback, DirSelect, (XtPointer) -1);
-
- for (i=0; i < count; i++)
- { item = &ListDirNames[ListDirNamePtr[i]];
- entry = XtCreateManagedWidget (item, smeBSBObjectClass, menu, NULL, 0);
- XtAddCallback (entry, XtNcallback, DirSelect, (XtPointer) i);
- }
-
- }
-