home *** CD-ROM | disk | FTP | other *** search
- /*-----------------------------------------------------------------------------
- Module FmFw.c
-
- (c) Simon Marlow 1991
- (c) Albert Graef 1994
-
- functions & data for creating a file window, and various functions
- related to file windows
- -----------------------------------------------------------------------------*/
-
- #include <pwd.h>
- #include <time.h>
- #include <string.h>
- #include <sys/wait.h>
-
- #include <X11/Intrinsic.h>
- #include <X11/Shell.h>
- #include <X11/StringDefs.h>
- #include <X11/Xaw/Form.h>
- #include <X11/Xaw/Box.h>
- #include <X11/Xaw/Viewport.h>
- #include <X11/Xaw/Toggle.h>
- #include <X11/Xaw/Label.h>
-
- #include "Am.h"
- #include "Fm.h"
-
- #define FW_WIDTH 400
- #define FW_HEIGHT 300
- #define TEXT_PADDING 10
- #define MAXCFGLINELEN 1024
-
- /*-----------------------------------------------------------------------------
- PUBLIC DATA
- -----------------------------------------------------------------------------*/
-
- FileWindowList file_windows = NULL;
- FileWindowRec *popup_fw;
- Widget file_popup_widget, *file_popup_items;
- Widget dir_popup_widget, *dir_popup_items;
-
- int n_types;
- TypeList types;
-
- int n_devices;
- DevList devs;
-
- /*-----------------------------------------------------------------------------
- STATIC DATA
- -----------------------------------------------------------------------------*/
-
- static MenuItemRec file_popup_menu[] = {
- { "edit", "Edit", fileEditCb },
- { "line1", NULL, NULL },
- { "move", "Move...", movePopup },
- { "copy", "Copy...", copyPopup },
- { "delete", "Delete", deleteItems },
- { "line2", NULL, NULL },
- { "info", "Information...", infoPopup },
- { "chmod", "Permissions...", chmodPopup }
- };
-
- static MenuItemRec dir_popup_menu[] = {
- { "open", "Open", fileOpenCb },
- { "line1", NULL, NULL },
- { "move", "Move...", movePopup },
- { "copy", "Copy...", copyPopup },
- { "delete", "Delete", deleteItems },
- { "line2", NULL, NULL },
- { "info", "Information...", infoPopup },
- { "chmod", "Permissions...", chmodPopup }
- };
-
- static MenuItemRec file_menu[] = {
- { "new", "New...", createFilePopup },
- { "line1", NULL, NULL },
- { "move", "Move...", movePopup },
- { "copy", "Copy...", copyPopup },
- { "link", "Link...", linkPopup },
- { "line2", NULL, NULL },
- { "delete", "Delete", deleteItems },
- { "line3", NULL, NULL },
- { "select", "Select...", selectPopup },
- { "select all", "Select all", fileSelectAllCb },
- { "deselect all", "Deselect all", fileDeselectCb },
- { "line4", NULL, NULL },
- { "quit", "Quit", appCloseCb },
- };
-
- static MenuItemRec folder_menu[] = {
- { "new", "New...", mkdirPopup },
- { "line1", NULL, NULL },
- { "goto", "Go to...", goToPopup },
- { "home", "Home", fileHomeCb },
- { "up", "Up", fileUpCb },
- { "line2", NULL, NULL },
- { "empty", "Empty", emptyDir },
- { "line3", NULL, NULL },
- { "close", "Close", fileCloseCb },
- };
-
- static MenuItemRec view_menu[] = {
- { "tree", "Tree", fileTreeCb },
- { "icons", "Icons", fileIconsCb },
- { "text", "Text", fileTextCb },
- { "line1", NULL, NULL },
- { "sort by name", "Sort by name", fileSortNameCb },
- { "sort by size", "Sort by size", fileSortSizeCb },
- { "sort by mtime", "Sort by date", fileSortMTimeCb },
- { "line2", NULL, NULL },
- { "hide folders", "Hide folders", fileShowDirsCb },
- { "mix folders/files", "Mix folders/files",
- fileDirsFirstCb },
- { "show hidden files", "Show hidden files", fileShowHiddenCb },
- };
-
- /*-----------------------------------------------------------------------------
- Widget Argument Lists
- -----------------------------------------------------------------------------*/
-
- static Arg shell_args[] = {
- { XtNtitle, (XtArgVal) NULL },
- { XtNiconPixmap, (XtArgVal) NULL },
- { XtNiconMask, (XtArgVal) NULL }
- };
-
- static Arg form_args[] = {
- { XtNdefaultDistance, (XtArgVal) 0 }
- };
-
- static Arg button_box_args[] = {
- { XtNtop, XtChainTop },
- { XtNbottom, XtChainTop },
- { XtNleft, XtChainLeft },
- { XtNright, XtChainLeft },
- };
-
- static Arg label_args[] = {
- { XtNfromVert, (XtArgVal) NULL },
- { XtNlabel, (XtArgVal) NULL },
- { XtNwidth, (XtArgVal) FW_WIDTH },
- { XtNfont, (XtArgVal) NULL },
- { XtNresize, (XtArgVal) False },
- { XtNtop, XtChainTop },
- { XtNbottom, XtChainTop },
- { XtNleft, XtChainLeft },
- { XtNright, XtChainRight },
- { XtNtranslations, (XtArgVal) NULL },
- };
-
- static Arg viewport_args[] = {
- { XtNfromVert, (XtArgVal) NULL },
- { XtNwidth, (XtArgVal) FW_WIDTH },
- { XtNtop, XtChainTop },
- { XtNbottom, XtChainBottom },
- { XtNleft, XtChainLeft },
- { XtNright, XtChainRight },
- { XtNallowVert, (XtArgVal) True }
- };
-
- static Arg status_args[] = {
- { XtNfromVert, (XtArgVal) NULL },
- { XtNlabel, (XtArgVal) NULL },
- { XtNwidth, (XtArgVal) FW_WIDTH },
- { XtNfont, (XtArgVal) NULL },
- { XtNresize, (XtArgVal) False },
- { XtNtop, XtChainBottom },
- { XtNbottom, XtChainBottom },
- { XtNleft, XtChainLeft },
- { XtNright, XtChainRight },
- { XtNjustify, XtJustifyLeft }
- };
-
- static Arg icon_box_args[] = {
- { XtNwidth, (XtArgVal) 0 },
- { XtNtranslations, (XtArgVal) NULL }
- };
-
- static Arg tree_box_args[] = {
- { XtNwidth, (XtArgVal) 1 },
- { XtNdefaultDistance, (XtArgVal) 0 },
- { XtNheight, (XtArgVal) 1 }
- };
-
- static Arg icon_form_args[] = {
- { XtNdefaultDistance, (XtArgVal) 0 },
- { XtNwidth, (XtArgVal) 0 }
- };
-
- static Arg tree_form_args[] = {
- { XtNfromHoriz, (XtArgVal) NULL },
- { XtNfromVert, (XtArgVal) NULL },
- { XtNdefaultDistance, (XtArgVal) 0 },
- { XtNwidth, (XtArgVal) 0 },
- { XtNtop, XtChainTop },
- { XtNbottom, XtChainTop },
- { XtNleft, XtChainLeft },
- { XtNright, XtChainLeft }
- };
-
- static Arg icon_toggle_args[] = {
- { XtNfromHoriz, (XtArgVal) NULL },
- { XtNfromVert, (XtArgVal) NULL },
- { XtNbitmap, (XtArgVal) NULL },
- { XtNtranslations, (XtArgVal) NULL },
- { XtNwidth, (XtArgVal) 0 },
- { XtNheight, (XtArgVal) 0 }
- };
-
- static Arg icon_label_args[] = {
- { XtNfromHoriz, (XtArgVal) NULL },
- { XtNfromVert, (XtArgVal) NULL },
- { XtNlabel, (XtArgVal) NULL },
- { XtNfont, (XtArgVal) NULL },
- { XtNwidth, (XtArgVal) 0 },
- { XtNtranslations, (XtArgVal) NULL },
- { XtNinternalWidth, (XtArgVal) 0 },
- { XtNinternalHeight, (XtArgVal) 0 },
- };
-
- static Arg text_label_args[] = {
- { XtNfromHoriz, (XtArgVal) NULL },
- { XtNfromVert, (XtArgVal) NULL },
- { XtNlabel, (XtArgVal) NULL },
- { XtNfont, (XtArgVal) NULL },
- { XtNwidth, (XtArgVal) 0 },
- { XtNjustify, XtJustifyLeft },
- { XtNhorizDistance, (XtArgVal) TEXT_PADDING },
- { XtNinternalWidth, (XtArgVal) 0 },
- { XtNinternalHeight, (XtArgVal) 0 }
- };
-
- static Arg text_toggle_args[] = {
- { XtNfromHoriz, (XtArgVal) NULL },
- { XtNfromVert, (XtArgVal) NULL },
- { XtNlabel, (XtArgVal) NULL },
- { XtNfont, (XtArgVal) NULL },
- { XtNwidth, (XtArgVal) 0 },
- { XtNtranslations, (XtArgVal) NULL },
- { XtNjustify, XtJustifyLeft },
- { XtNinternalWidth, (XtArgVal) 0 },
- { XtNinternalHeight, (XtArgVal) 0 }
- };
-
- static Arg arrow_args[] = {
- { XtNfromHoriz, (XtArgVal) NULL },
- { XtNfromVert, (XtArgVal) NULL },
- { XtNbitmap, (XtArgVal) NULL },
- { XtNsensitive, (XtArgVal) True },
- { XtNtop, XtChainTop },
- { XtNbottom, XtChainTop },
- { XtNleft, XtChainLeft },
- { XtNright, XtChainLeft },
- { XtNinternalWidth, (XtArgVal) 0 },
- { XtNinternalHeight, (XtArgVal) 0 },
- { XtNhighlightThickness, (XtArgVal) 0 }
- };
-
- static Arg line_args[] = {
- { XtNfromHoriz, (XtArgVal) NULL },
- { XtNfromVert, (XtArgVal) NULL },
- { XtNbitmap, (XtArgVal) NULL },
- { XtNtop, XtChainTop },
- { XtNbottom, XtChainTop },
- { XtNleft, XtChainLeft },
- { XtNright, XtChainLeft },
- { XtNinternalWidth, (XtArgVal) 0 },
- { XtNinternalHeight, (XtArgVal) 0 }
- };
-
- /*-----------------------------------------------------------------------------
- Translation tables
- -----------------------------------------------------------------------------*/
-
- static char label_translations_s[] = "\
- <Btn1Up>(2) : fileRefresh()\n";
-
- static char tree_translations_s[] = "\
- <Enter> : fileHighlight()\n\
- <Leave> : resetCursor()\n\
- <Btn1Down>,<Btn1Up> : fileSelect()\n\
- <Btn1Down>,<Leave> : fileBeginDrag(1,move)\n\
- <Btn2Down>,<Btn2Up> : fileToggle()\n\
- <Btn2Down>,<Leave> : fileBeginDrag(2,copy)\n\
- <Btn3Down> : dirPopup()\n";
-
-
- static char dir_translations_s[] = "\
- <Enter> : fileHighlight()\n\
- <Leave> : resetCursor()\n\
- <Btn1Down>,<Btn1Up> : fileSelect()\n\
- <Btn1Down>,<Leave> : fileBeginDrag(1,move)\n\
- <Btn1Up>(2) : fileOpenDir()\n\
- <Btn2Down>,<Btn2Up> : fileToggle()\n\
- <Btn2Down>,<Leave> : fileBeginDrag(2,copy)\n\
- <Btn3Down> : dirPopup()\n";
-
- static char file_translations_s[] = "\
- <Enter> : fileMaybeHighlight()\n\
- <Leave> : unhighlight()\n\
- <Btn1Up>(2) : fileExecAction()\n\
- <Btn1Down>,<Btn1Up> : fileSelect()\n\
- <Btn1Down>,<Leave> : fileBeginDrag(1,move)\n\
- <Btn2Down>,<Btn2Up> : fileToggle()\n\
- <Btn2Down>,<Leave> : fileBeginDrag(2,copy)\n\
- <Btn3Down> : filePopup()\n";
-
- static char exec_translations_s[] = "\
- <Enter> : fileHighlight()\n\
- <Leave> : resetCursor()\n\
- <Btn1Up>(2) : fileExecFile()\n\
- <Btn1Down>,<Btn1Up> : fileSelect()\n\
- <Btn1Down>,<Leave> : fileBeginDrag(1,move)\n\
- <Btn2Down>,<Btn2Up> : fileToggle()\n\
- <Btn2Down>,<Leave> : fileBeginDrag(2,copy)\n\
- <Btn3Down> : filePopup()\n";
-
- /* This is a hack to get the icon box to recognise button events */
- static char iconbox_translations_s[] = "\
- <Btn2Up> : dummy()\n\
- <Btn3Up> : dummy()\n";
-
- static void dummy(Widget w, XEvent *event, String *params,
- Cardinal *num_params) {}
-
- static XtActionsRec file_actions[] = {
- { "fileRefresh", fileRefresh },
- { "fileToggle", fileToggle },
- { "fileSelect", fileSelect },
- { "fileHighlight", fileHighlight },
- { "fileOpenDir", fileOpenDir },
- { "fileBeginDrag", fileBeginDrag },
- { "fileExecFile", fileExecFile },
- { "fileExecAction", fileExecAction },
- { "resetCursor", resetCursor },
- { "fileMaybeHighlight", fileMaybeHighlight },
- { "filePopup", filePopup },
- { "dirPopup", dirPopup },
- { "dummy", dummy }
- };
-
- static XtTranslations label_translations, dir_translations, file_translations,
- iconbox_translations, tree_translations, exec_translations;
-
- /*-----------------------------------------------------------------------------
- PRIVATE FUNCTIONS
- -----------------------------------------------------------------------------*/
-
- static int longestName(FileWindowRec *fw)
- {
- int i,l;
- int longest = 0;
-
- for (i=0; i<fw->n_files; i++)
- if ((l = XTextWidth(resources.icon_font, fw->files[i]->name,
- strlen(fw->files[i]->name))) > longest)
- longest = l;
- return longest;
- }
-
- /*---------------------------------------------------------------------------*/
-
- static int parseType(FILE *fp, char **pattern, char **icon, char **push_action,
- char **drop_action)
- {
- static char s[MAXCFGLINELEN];
- int l;
-
- start:
- if (feof(fp)||!fgets(s, MAXCFGLINELEN, fp))
- return 0;
- l = strlen(s);
- if (s[l-1] == '\n')
- s[--l] = '\0';
- if (!l || *s == '#')
- goto start;
- if (!(*pattern = split(s, ':')))
- return -1;
- if (!(*icon = split(NULL, ':')))
- return -1;
- if (!(*push_action = split(NULL, ':')))
- return -1;
- if (!(*drop_action = split(NULL, ':')))
- return -1;
- return l;
- }
-
- /*---------------------------------------------------------------------------*/
-
- static void readFileBitmaps()
- {
- int i;
-
- for (i=0; i<n_types; i++)
- if (!types[i].icon[0])
- types[i].icon_bm = bm[FILE_BM];
- else if ((types[i].icon_bm = readIcon(types[i].icon)) == None) {
- fprintf(stderr, "%s: can't read icon for type %s%s%s\n", progname,
- types[i].dir<0?"*":"", types[i].pattern,
- types[i].dir>0?"*":"");
- types[i].icon_bm = bm[FILE_BM];
- }
- }
-
- /*---------------------------------------------------------------------------*/
-
- static void readFileTypes(String path)
- {
- FILE *fp;
- char *pattern, *icon, *push_action, *drop_action;
- char s[MAXCFGSTRINGLEN];
- int i, l, p;
-
- n_types = 0;
- types = NULL;
-
- if (!(fp = fopen(path, "r"))) return;
-
- for (i=0; (p = parseType(fp, &pattern, &icon, &push_action,
- &drop_action)) > 0; i++) {
- types = (TypeList) XTREALLOC(types, (i+1)*sizeof(TypeRec) );
- l = strlen(pattern);
- if (pattern[0] == '*') {
- types[i].dir = -1;
- strparse(s, pattern+1, "\\:");
- } else if (pattern[l-1] == '*') {
- types[i].dir = 1;
- pattern[l-1] = '\0';
- strparse(s, pattern, "\\:");
- } else {
- types[i].dir = 0;
- strparse(s, pattern, "\\:");
- }
- types[i].len = strlen(s);
- types[i].pattern = XtNewString(s);
- types[i].icon = XtNewString(strparse(s, icon, "\\:"));
- types[i].push_action = XtNewString(strparse(s, push_action, "\\:"));
- types[i].drop_action = XtNewString(strparse(s, drop_action, "\\:"));
- }
-
- if (p == -1)
- error("Error in configuration file", "");
-
- n_types = i;
-
- if (fclose(fp))
- sysError("Error reading configuration file:");
-
- readFileBitmaps();
- }
-
- /*---------------------------------------------------------------------------*/
-
- static TypeRec *fileType(char *name)
- {
- int i, l = strlen(name);
-
- for (i = 0; i < n_types; i++)
- switch (types[i].dir) {
- case 0:
- if (!strcmp(name, types[i].pattern))
- return types+i;
- break;
- case 1:
- if (!strncmp(types[i].pattern, name, types[i].len))
- return types+i;
- break;
- case -1:
- if (l >= types[i].len && !strncmp(types[i].pattern, name+l-types[i].len,
- types[i].len))
- return types+i;
- break;
- }
- return NULL;
- }
-
- /*---------------------------------------------------------------------------*/
-
- static int parseDev(FILE *fp, char **name, char **mount_action,
- char **umount_action)
- {
- static char s[MAXCFGLINELEN];
- int l;
-
- start:
- if (feof(fp)||!fgets(s, MAXCFGLINELEN, fp))
- return 0;
- l = strlen(s);
- if (s[l-1] == '\n')
- s[--l] = '\0';
- if (!l || *s == '#')
- goto start;
- if (!(*name = split(s, ':')))
- return -1;
- if (!(*mount_action = split(NULL, ':')))
- return -1;
- if (!(*umount_action = split(NULL, ':')))
- return -1;
- return l;
- }
-
- /*---------------------------------------------------------------------------*/
-
- static void readDevices(String path)
- {
- FILE *fp;
- char *name, *mount_action, *umount_action;
- char s[MAXCFGSTRINGLEN];
- int i, p;
-
- n_devices = 0;
- devs = NULL;
-
- if (!(fp = fopen(path, "r"))) return;
-
- for (i=0; (p = parseDev(fp, &name, &mount_action, &umount_action)) > 0;
- i++) {
- devs = (DevList) XTREALLOC(devs, (i+1)*sizeof(DevRec) );
- devs[i].name = XtNewString(strparse(s, name, "\\:"));
- devs[i].mount_action = XtNewString(strparse(s, mount_action, "\\:"));
- devs[i].umount_action = XtNewString(strparse(s, umount_action, "\\:"));
- devs[i].mounted = 0;
- }
-
- if (p == -1)
- error("Error in devices file", "");
-
- n_devices = i;
-
- if (fclose(fp))
- sysError("Error reading devices file:");
- }
-
- /*---------------------------------------------------------------------------*/
-
- static int devAction(int d, char *action)
- {
- int pid, status;
-
- if ((pid = fork()) == -1) {
- sysError("Can't fork:");
- return 0;
- } else if (chdir(user.home)) {
- sysError("Can't chdir:");
- return 0;
- } else if (!pid) {
- if (resources.echo_actions)
- fprintf(stderr, "%s\n", action);
- freopen("/dev/null", "r", stdin);
- execlp(user.shell, user.shell, "-c", action, NULL);
- perror("Exec failed");
- exit(1);
- } else if (waitpid(pid, &status, 0) == -1 || !WIFEXITED(status) ||
- WEXITSTATUS(status))
- return 0;
- else
- return 1;
- }
-
- /*---------------------------------------------------------------------------*/
-
- static void createFileIcons(FileWindowRec *fw)
- {
- int i;
- Dimension width;
- FileRec *file;
- Pixmap icon;
- char *iconname[4] = {"dir_icon","file_icon","exe_icon","other_icon"};
- int icontype;
-
- XtVaGetValues(fw->viewport, XtNwidth, &width, NULL);
- icon_box_args[0].value = (XtArgVal) width;
-
- width = longestName(fw);
- if (width < resources.file_icon_width)
- width = resources.file_icon_width;
- icon_form_args[1].value = (XtArgVal) width;
- icon_toggle_args[4].value = (XtArgVal) width;
- icon_toggle_args[5].value = (XtArgVal) resources.file_icon_height;
- icon_label_args[4].value = (XtArgVal) width;
-
- fw->icon_box = XtCreateWidget("icon box", boxWidgetClass,
- fw->viewport, icon_box_args, XtNumber(icon_box_args) );
-
- for (i=0; i < fw->n_files; i++) {
- Pixel back;
-
- file = fw->files[i];
- file->icon.form = XtCreateManagedWidget(file->name,
- formWidgetClass, fw->icon_box, icon_form_args,
- XtNumber(icon_form_args) );
-
- icon = None;
- icontype = 3;
-
- /* Symbolic link to non-existent file */
- if (S_ISLNK(file->stats.st_mode)) {
- icon_toggle_args[3].value = (XtArgVal) file_translations;
- icon = (XtArgVal) bm[BLACKHOLE_BM];
- }
-
- else if (S_ISDIR(file->stats.st_mode)) {
- icon_toggle_args[3].value = (XtArgVal) dir_translations;
- if (icon == None)
- if (file->sym_link)
- icon = (XtArgVal) bm[DIRLNK_BM];
- else if (!strcmp(file->name, ".."))
- icon = (XtArgVal) bm[UPDIR_BM];
- else
- icon = (XtArgVal) bm[DIR_BM];
- icontype = 0;
- }
- else if (file->stats.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
- icon_toggle_args[3].value = (XtArgVal) exec_translations;
- if (icon == None)
- if (file->sym_link)
- icon = (XtArgVal) bm[EXECLNK_BM];
- else
- icon = (XtArgVal) bm[EXEC_BM];
- icontype = 2;
- }
- else {
- icon_toggle_args[3].value = (XtArgVal) file_translations;
- file->type = fileType(file->name);
- if (icon == None)
- if (file->type)
- icon = (XtArgVal) file->type->icon_bm;
- else if (file->sym_link)
- icon = (XtArgVal) bm[SYMLNK_BM];
- else
- icon = (XtArgVal) bm[FILE_BM];
- icontype = 1;
- }
- icon_toggle_args[2].value = icon;
-
- file->icon.toggle = XtCreateManagedWidget(iconname[icontype],
- toggleWidgetClass, file->icon.form, icon_toggle_args,
- XtNumber(icon_toggle_args) );
-
- XtVaGetValues(file->icon.toggle, XtNbackground, &back, NULL);
- XtVaSetValues(file->icon.toggle, XtNborder, (XtArgVal) back, NULL);
-
- icon_label_args[0].value = (XtArgVal) NULL;
- icon_label_args[1].value = (XtArgVal) file->icon.toggle;
- icon_label_args[2].value = (XtArgVal) file->name;
- file->icon.label = XtCreateManagedWidget("label",
- labelWidgetClass, file->icon.form, icon_label_args,
- XtNumber(icon_label_args) );
- }
- }
-
- /*----------------------------------------------------------------------------*/
-
- static void createTextDisplay(FileWindowRec *fw)
- {
- int i, l;
- Widget w;
- Dimension width, m_width, name_w, size_w, perm_w, own_w = 0, date_w;
- char s[10], name[FILENAME_MAX];
- struct passwd *pw;
- char **owners = NULL;
- FileRec *file;
-
- XtVaGetValues(fw->viewport, XtNwidth, &width, NULL);
- icon_box_args[0].value = (XtArgVal) width;
-
- m_width = XTextWidth(resources.icon_font, "m", 1);
- name_w = longestName(fw) + 2*m_width;
- size_w = m_width * 7;
- perm_w = m_width * 9;
- date_w = m_width * 20;
-
- if (resources.show_owner) {
- owners = (char **) XtMalloc(fw->n_files * sizeof(char *));
- own_w = 0;
- for (i=0; i<fw->n_files; i++) {
- /* bug fixed by hkarhune@hydra.helsinki.fi - Thanks */
- if((pw = getpwuid(fw->files[i]->stats.st_uid)) == NULL) {
- char tmp[11];
-
- sprintf(tmp, "%d", fw->files[i]->stats.st_uid);
- owners[i] = XtNewString(tmp);
- }
- else
- owners[i] = XtNewString(pw->pw_name);
- l = XTextWidth(resources.icon_font, owners[i], strlen(owners[i]));
- if (l > own_w)
- own_w = l;
- }
- }
-
- fw->icon_box = XtCreateWidget("icon box", boxWidgetClass,
- fw->viewport, icon_box_args,
- XtNumber(icon_box_args) );
-
- for (i=0; i<fw->n_files; i++) {
- Pixel pix;
-
- file = fw->files[i];
- if (S_ISDIR(file->stats.st_mode)) {
- sprintf(name, "[%s]", file->name);
- text_toggle_args[2].value = (XtArgVal) name;
- text_toggle_args[5].value = (XtArgVal) dir_translations;
- }
- else {
- text_toggle_args[2].value = (XtArgVal) file->name;
- if (file->stats.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))
- text_toggle_args[5].value = (XtArgVal) exec_translations;
- else
- text_toggle_args[5].value = (XtArgVal) file_translations;
- }
-
- file->icon.form = XtCreateManagedWidget(file->name,
- formWidgetClass, fw->icon_box, icon_form_args,
- XtNumber(icon_form_args) );
-
- text_toggle_args[0].value = (XtArgVal) NULL;
- text_toggle_args[4].value = (XtArgVal) name_w;
- w = file->icon.toggle = XtCreateManagedWidget("name",
- toggleWidgetClass, file->icon.form, text_toggle_args,
- XtNumber(text_toggle_args) );
-
- XtVaGetValues(file->icon.toggle, file->selected?XtNforeground:
- XtNbackground, &pix, NULL);
- XtVaSetValues(file->icon.toggle, XtNborder, (XtArgVal) pix, NULL);
-
- if (resources.show_length) {
- sprintf(s, "%ld", (long) file->stats.st_size);
- text_label_args[0].value = (XtArgVal) w;
- text_label_args[2].value = (XtArgVal) s;
- text_label_args[4].value = (XtArgVal) size_w;
- text_label_args[5].value = (XtArgVal) XtJustifyRight;
- w = XtCreateManagedWidget("size", labelWidgetClass,
- file->icon.form, text_label_args,
- XtNumber(text_label_args) );
- }
-
- if (resources.show_owner) {
- text_label_args[0].value = (XtArgVal) w;
- text_label_args[2].value = (XtArgVal) owners[i];
- text_label_args[4].value = (XtArgVal) own_w;
- text_label_args[5].value = (XtArgVal) XtJustifyLeft;
- w = XtCreateManagedWidget("owner", labelWidgetClass,
- file->icon.form, text_label_args,
- XtNumber(text_label_args) );
- }
-
- if (resources.show_perms) {
- makePermissionsString(s, file->stats.st_mode);
- text_label_args[0].value = (XtArgVal) w;
- text_label_args[2].value = (XtArgVal) s;
- text_label_args[4].value = (XtArgVal) perm_w;
- text_label_args[5].value = (XtArgVal) XtJustifyLeft;
- w = XtCreateManagedWidget("permissions", labelWidgetClass,
- file->icon.form, text_label_args,
- XtNumber(text_label_args) );
- }
-
- if (resources.show_date) {
- text_label_args[0].value = (XtArgVal) w;
- text_label_args[2].value = (XtArgVal)ctime(&file->stats.st_mtime);
- text_label_args[4].value = (XtArgVal) date_w;
- text_label_args[5].value = (XtArgVal) XtJustifyLeft;
- w = XtCreateManagedWidget("date", labelWidgetClass,
- file->icon.form, text_label_args,
- XtNumber(text_label_args) );
- }
- }
-
- if (resources.show_owner) {
- for(i=0; i<fw->n_files; i++)
- XTFREE(owners[i]);
- XTFREE(owners);
- }
- }
-
-
- /*----------------------------------------------------------------------------*/
-
- /* create a directory icon in position specified by horiz & vert */
- static Widget createDirIcon(FileWindowRec *fw, int i, Widget horiz,Widget vert)
- {
- FileRec *file = fw->files[i];
- char *dirlabel;
- Pixel back;
-
- /* create form */
- tree_form_args[0].value = (XtArgVal) horiz;
- tree_form_args[1].value = (XtArgVal) vert;
- file->icon.form = XtCreateManagedWidget(file->name,
- formWidgetClass, fw->icon_box, tree_form_args, XtNumber(tree_form_args) );
-
- /* create icon */
- icon_toggle_args[0].value = (XtArgVal) NULL;
- icon_toggle_args[1].value = (XtArgVal) NULL;
- icon_toggle_args[2].value = (XtArgVal) bm[DIR_BM];
- icon_toggle_args[3].value = (XtArgVal) tree_translations;
- file->icon.toggle = XtCreateManagedWidget("icon",
- toggleWidgetClass, file->icon.form, icon_toggle_args,
- XtNumber(icon_toggle_args) );
-
- XtVaGetValues(file->icon.toggle, XtNbackground, &back, NULL);
- XtVaSetValues(file->icon.toggle, XtNborder, (XtArgVal) back, NULL);
-
-
- /* create label */
- icon_label_args[0].value = (XtArgVal) NULL;
- icon_label_args[1].value = (XtArgVal) file->icon.toggle;
- if (i == 0)
- dirlabel = fw->directory[1]?strrchr(fw->directory, '/')+1:fw->directory;
- else
- dirlabel = file->name;
- icon_label_args[2].value = (XtArgVal)dirlabel;
- file->icon.label = XtCreateManagedWidget("label",
- labelWidgetClass, file->icon.form, icon_label_args,
- XtNumber(icon_label_args) );
-
- return file->icon.form;
- }
-
- /*----------------------------------------------------------------------------*/
-
- /* create the icons for the directory display */
- static void createTreeDisplay(FileWindowRec *fw)
- {
- int i;
- Widget vert, horiz;
- Pixmap line_bm;
- Dimension width;
- FileList files = fw->files;
-
- /* find width of icons */
- width = longestName(fw);
- if (width < resources.tree_icon_width)
- width = resources.tree_icon_width;
- tree_form_args[3].value = (XtArgVal) width;
- icon_toggle_args[4].value = (XtArgVal) width;
- icon_toggle_args[5].value = (XtArgVal) resources.tree_icon_height;
- icon_label_args[4].value = (XtArgVal) width;
-
- /* create icon box in viewport */
- XtVaGetValues(fw->viewport, XtNwidth, &width, NULL);
- tree_box_args[0].value = (XtArgVal) width;
- fw->icon_box = XtCreateWidget("icon box", formWidgetClass,
- fw->viewport, tree_box_args, XtNumber(tree_box_args) );
-
- /* The '..' directory is not displayed, and no arrow for '.' */
- files[1]->icon.form = files[1]->icon.toggle =
- files[1]->icon.label = NULL;
- files[0]->icon.arrow = NULL;
-
- /* create left arrow */
- arrow_args[0].value = (XtArgVal) NULL;
- arrow_args[1].value = (XtArgVal) NULL;
- if (!permission(&files[1]->stats, P_EXECUTE)) {
- arrow_args[2].value = bm[NOENTRY_CBM];
- arrow_args[3].value = False;
- }
- else {
- arrow_args[2].value = bm[LARROW_BM];
- arrow_args[3].value = True;
- }
- horiz = files[1]->icon.arrow = XtCreateManagedWidget("left arrow",
- commandWidgetClass, fw->icon_box, arrow_args, XtNumber(arrow_args) );
- XtAddCallback(horiz, XtNcallback, (XtCallbackProc) mainArrowCb, fw);
-
- /* create current directory icon */
- horiz = createDirIcon(fw, 0, horiz, NULL);
-
- vert = NULL;
-
- for(i = 2; i < fw->n_files; i++, horiz = files[0]->icon.form) {
-
- /* create line */
- if (i == 2)
- if (fw->n_files == 3)
- line_bm = bm[LLINE_BM];
- else
- line_bm = bm[TLINE_BM];
- else
- if (i == fw->n_files - 1)
- line_bm = bm[CLINE_BM];
- else
- line_bm = bm[FLINE_BM];
- line_args[0].value = (XtArgVal) horiz;
- line_args[1].value = (XtArgVal) vert;
- line_args[2].value = (XtArgVal) line_bm;
- horiz = XtCreateManagedWidget("line", labelWidgetClass,
- fw->icon_box, line_args, XtNumber(line_args) );
-
- /* create icon */
- horiz = createDirIcon(fw, i, horiz, vert);
-
- /* create right arrow */
- arrow_args[0].value = (XtArgVal) horiz;
- arrow_args[1].value = (XtArgVal) vert;
- if (!permission(&files[i]->stats, P_EXECUTE)) {
- arrow_args[2].value = bm[NOENTRY_CBM];
- arrow_args[3].value = False;
- }
- else if (files[i]->sym_link) {
- arrow_args[2].value = bm[WAVY_BM];
- arrow_args[3].value = True;
- }
- else {
- arrow_args[2].value = bm[RARROW_BM];
- arrow_args[3].value = True;
- }
- vert = files[i]->icon.arrow
- = XtCreateManagedWidget("right arrow", commandWidgetClass, fw->icon_box,
- arrow_args, XtNumber(arrow_args) );
- XtAddCallback(vert, XtNcallback, (XtCallbackProc) mainArrowCb, fw);
- }
- }
-
- /*-----------------------------------------------------------------------------
- PUBLIC FUNCTIONS
- -----------------------------------------------------------------------------*/
-
- /* find the device for a directory */
- int findDev(char *path)
- {
- int d;
-
- for (d = 0; d < n_devices; d++)
- if (prefix(devs[d].name, path))
- return d;
- return -1;
- }
-
- /*---------------------------------------------------------------------------*/
- /* mount a device */
- void mountDev(int d)
- {
- if (d == -1)
- ;
- else if (devs[d].mounted)
- devs[d].mounted++;
- else
- devs[d].mounted += devAction(d, devs[d].mount_action);
- }
-
- /*---------------------------------------------------------------------------*/
- /* unmount a device */
- void umountDev(int d)
- {
- if (d == -1 || !devs[d].mounted)
- ;
- else if (devs[d].mounted > 1)
- devs[d].mounted--;
- else
- devs[d].mounted -= devAction(d, devs[d].umount_action);
- }
-
- /*---------------------------------------------------------------------------*/
- /* initialise the file Windows module */
- void initFileWindows()
- {
- XtAppAddActions(app_context, file_actions, XtNumber(file_actions));
- label_translations = XtParseTranslationTable(label_translations_s);
- dir_translations = XtParseTranslationTable(dir_translations_s);
- file_translations = XtParseTranslationTable(file_translations_s);
- iconbox_translations = XtParseTranslationTable(iconbox_translations_s);
- tree_translations = XtParseTranslationTable(tree_translations_s);
- exec_translations = XtParseTranslationTable(exec_translations_s);
-
- icon_box_args[1].value = (XtArgVal) iconbox_translations;
- label_args[9].value = (XtArgVal) label_translations;
-
- label_args[3].value = (XtArgVal) resources.label_font;
- status_args[3].value = (XtArgVal) resources.status_font;
- icon_label_args[3].value = (XtArgVal) resources.icon_font;
- text_toggle_args[3].value = (XtArgVal) resources.icon_font;
- text_label_args[3].value = (XtArgVal) resources.icon_font;
- shell_args[1].value = (XtArgVal) bm[ICON_BM];
- shell_args[2].value = (XtArgVal) bm[ICONMSK_BM];
-
- file_popup_items = createFloatingMenu("file popup", file_popup_menu,
- XtNumber(file_popup_menu), 4, aw.shell,
- NULL, &file_popup_widget);
- XtRegisterGrabAction(filePopup, True, ButtonPressMask | ButtonReleaseMask,
- GrabModeAsync, GrabModeAsync);
- dir_popup_items = createFloatingMenu("dir popup", dir_popup_menu,
- XtNumber(dir_popup_menu), 4, aw.shell,
- NULL, &dir_popup_widget);
- XtRegisterGrabAction(dirPopup, True, ButtonPressMask | ButtonReleaseMask,
- GrabModeAsync, GrabModeAsync);
- readFileTypes(resources.cfg_file);
- readDevices(resources.dev_file);
- }
-
- /*---------------------------------------------------------------------------*/
- /* Create a file Window at the specified path, in the specified format */
-
- static FileWindowRec *createFileWindow(String path, String title,
- DisplayType format)
- {
- FileWindowRec *fw;
- char *shell_name;
-
- #ifdef DEBUG_MALLOC
- fprintf(stderr, "entering createFileWindow: %lu\n", malloc_inuse(NULL));
- #endif
-
- if (chdir(path)) {
- sysError("Can't open folder:");
- return NULL;
- }
-
- /* put at front of linked list */
- fw = (FileWindowRec *) XtMalloc(sizeof(FileWindowRec));
- fw->next = file_windows;
- file_windows = fw;
-
- if (!getwd(fw->directory)) {
- sysError("Can't open folder:");
- return NULL;
- }
-
- /* set up defaults */
- fw->dev = -1;
- fw->display_type = format;
- fw->sort_type = resources.default_sort_type;
- fw->show_dirs = True;
- fw->show_hidden = False;
- fw->dirs_first = True;
- fw->n_selections = 0;
- fw->n_bytes_selected = 0;
- fw->unreadable = NULL;
- fw->files = NULL;
- fw->n_files = 0;
- fw->n_bytes = 0;
- fw->update = False;
-
- shell_name = "file window";
- shell_args[0].value = (XtArgVal) title;
- fw->shell = XtCreatePopupShell(shell_name, topLevelShellWidgetClass,
- aw.shell, shell_args, XtNumber(shell_args) );
- if (resources.init_geometry)
- XtVaSetValues(fw->shell, XtNgeometry, resources.init_geometry, NULL);
-
- /* create form */
- fw->form = XtCreateManagedWidget("form", formWidgetClass, fw->shell,
- form_args, XtNumber(form_args) );
-
- /* create button box */
- fw->button_box = XtCreateManagedWidget("button box", boxWidgetClass,
- fw->form, button_box_args,
- XtNumber(button_box_args) );
-
- /* create the menus */
- fw->file_items = createMenu("file", "File", file_menu, XtNumber(file_menu),
- 4, fw->button_box, (XtPointer) fw);
- fw->folder_items = createMenu("folder", "Folder", folder_menu,
- XtNumber(folder_menu), 4, fw->button_box,
- (XtPointer) fw);
- fw->view_items = createMenu("view", "View", view_menu, XtNumber(view_menu),
- 16, fw->button_box, (XtPointer) fw);
-
- /* create folder label */
- label_args[0].value = (XtArgVal) fw->button_box;
- label_args[1].value = (XtArgVal) fw->directory;
- fw->label = XtCreateManagedWidget("label", labelWidgetClass, fw->form,
- label_args, XtNumber(label_args) );
-
- /* create viewport */
- viewport_args[0].value = (XtArgVal) fw->label;
- fw->viewport = XtCreateManagedWidget("viewport", viewportWidgetClass,
- fw->form, viewport_args,
- XtNumber(viewport_args) );
-
- /* create status line */
- status_args[0].value = (XtArgVal) fw->viewport;
- status_args[1].value = (XtArgVal) "";
- fw->status = XtCreateManagedWidget("status", labelWidgetClass, fw->form,
- status_args, XtNumber(status_args) );
-
- #ifdef DEBUG_MALLOC
- fprintf(stderr, "exiting createFileWindow: %lu\n", malloc_inuse(NULL));
- #endif
-
- return fw;
- }
-
- /*----------------------------------------------------------------------------*/
-
- void newFileWindow(String path, DisplayType d, Boolean by_cursor)
- {
- FileWindowRec *fw;
-
- #ifdef DEBUG_MALLOC
- fprintf(stderr, "entering newFileWindow: %lu\n", malloc_inuse(NULL));
- #endif
-
- if (!(fw = createFileWindow(path, "File Manager", d)))
- return;
- createFileDisplay(fw);
- XtRealizeWidget(fw->shell);
- XSetIconName(XtDisplay(fw->shell), XtWindow(fw->shell), fw->directory);
- XSetWMProtocols(XtDisplay(fw->shell), XtWindow(fw->shell),
- &wm_delete_window, 1);
- XtAddEventHandler(fw->shell, (EventMask)0L, True,
- (XtEventHandler)clientMessageHandler, (XtPointer)NULL);
- if (by_cursor)
- popupByCursor(fw->shell, XtGrabNone);
- else
- XtPopup(fw->shell, XtGrabNone);
-
- #ifdef DEBUG_MALLOC
- fprintf(stderr, "exiting newFileWindow: %lu\n", malloc_inuse(NULL));
- #endif
- }
-
- /*---------------------------------------------------------------------------*/
-
- /* Main procedure to create the display in the viewport */
- void createFileDisplay(FileWindowRec *fw)
- {
- int i;
-
- #ifdef DEBUG_MALLOC
- fprintf(stderr, "entering createFileDisplay: %lu\n", malloc_inuse(NULL));
- #endif
-
- XtVaSetValues(fw->label, XtNlabel, (XtArgVal) fw->directory, NULL);
-
- fw->icon_box = NULL;
-
- if (fw->unreadable) {
- XtDestroyWidget(fw->unreadable);
- fw->unreadable = NULL;
- }
-
- if (!readDirectory(fw)) {
- fw->unreadable =
- XtVaCreateManagedWidget("label", labelWidgetClass, fw->viewport,
- XtNlabel, "Directory is unreadable",
- XtNfont, resources.label_font, NULL);
- return;
- }
-
- for (i=0; i<fw->n_files; i++)
- fw->files[i]->selected = False;
- fw->n_selections = 0;
- fw->n_bytes_selected = 0;
-
- switch (fw->display_type) {
- case Tree:
- filterDirectory(fw, Directories);
- sortDirectory(fw->files+2, fw->n_files-2, fw->sort_type, False);
- createTreeDisplay(fw);
- break;
- case Icons:
- filterDirectory(fw, fw->show_dirs ? All : Files);
- sortDirectory(fw->files, fw->n_files, fw->sort_type, fw->dirs_first);
- createFileIcons(fw);
- break;
- case Text:
- filterDirectory(fw, fw->show_dirs ? All : Files);
- sortDirectory(fw->files, fw->n_files, fw->sort_type, fw->dirs_first);
- createTextDisplay(fw);
- break;
- }
-
- updateStatus(fw);
-
- XtManageChild(fw->icon_box);
-
- #ifdef DEBUG_MALLOC
- fprintf(stderr, "exiting createFileDisplay: %lu\n", malloc_inuse(NULL));
- #endif
- }
-
- /*---------------------------------------------------------------------------*/
-
- /* Update the display in the viewport */
- void updateFileDisplay(FileWindowRec *fw)
- {
- int d;
-
- #ifdef DEBUG_MALLOC
- fprintf(stderr, "entering updateFileDisplay: %lu\n", malloc_inuse(NULL));
- #endif
-
- zzz();
-
- d = fw->dev;
-
- if (fw->icon_box)
- XtDestroyWidget(fw->icon_box);
-
- freeFileList(fw);
- createFileDisplay(fw);
-
- if (d != -1) umountDev(d);
-
- XSetIconName(XtDisplay(fw->shell), XtWindow(fw->shell), fw->directory);
-
- wakeUp();
-
- #ifdef DEBUG_MALLOC
- fprintf(stderr, "exiting updateFileDisplay: %lu\n", malloc_inuse(NULL));
- #endif
- }
-
- /*---------------------------------------------------------------------------*/
-
- /* resort the icons in the display */
- void reSortFileDisplay(FileWindowRec *fw)
- {
- #ifdef DEBUG_MALLOC
- fprintf(stderr, "entering resortFileDisplay: %lu\n", malloc_inuse(NULL));
- #endif
-
- if (fw->unreadable)
- return;
-
- zzz();
-
- XtDestroyWidget(fw->icon_box);
- fw->n_selections = 0;
- fw->n_bytes_selected = 0;
-
- switch (fw->display_type) {
- case Tree:
- sortDirectory(fw->files+2, fw->n_files-2, fw->sort_type, False);
- createTreeDisplay(fw);
- break;
- case Icons:
- sortDirectory(fw->files, fw->n_files, fw->sort_type, fw->dirs_first);
- createFileIcons(fw);
- break;
- case Text:
- sortDirectory(fw->files, fw->n_files, fw->sort_type, fw->dirs_first);
- createTextDisplay(fw);
- break;
- }
-
- updateStatus(fw);
- XtManageChild(fw->icon_box);
-
- wakeUp();
-
- #ifdef DEBUG_MALLOC
- fprintf(stderr, "exiting resortFileDisplay: %lu\n", malloc_inuse(NULL));
- #endif
- }
-
- /*---------------------------------------------------------------------------*/
-
- void reDisplayFileWindow(FileWindowRec *fw)
- {
- #ifdef DEBUG_MALLOC
- fprintf(stderr, "entering redisplayFileWindow: %lu\n", malloc_inuse(NULL));
- #endif
-
- if (fw->unreadable)
- return;
-
- zzz();
-
- XtDestroyWidget(fw->icon_box);
-
- switch (fw->display_type) {
- case Tree:
- createTreeDisplay(fw);
- break;
- case Icons:
- createFileIcons(fw);
- break;
- case Text:
- createTextDisplay(fw);
- break;
- }
-
- updateStatus(fw);
- XtManageChild(fw->icon_box);
-
- wakeUp();
-
- #ifdef DEBUG_MALLOC
- fprintf(stderr, "exiting redisplayFileWindow: %lu\n", malloc_inuse(NULL));
- #endif
- }
-
- /*----------------------------------------------------------------------------
- Intelligent update - only update the windows needed.
- Use markForUpdate() to explicitly mark a directory for update.
- Call intUpdate to execute all the actions.
- -----------------------------------------------------------------------------*/
- void markForUpdate(String path)
- {
- FileWindowRec *fw;
-
- for (fw = file_windows; fw; fw = fw->next)
- if (!strcmp(path, fw->directory))
- fw->update = True;
- }
-
- void intUpdate()
- {
- FileWindowRec *fw;
- struct stat cur;
-
- for (fw = file_windows; fw; fw = fw->next) {
- if (fw->update ||
- stat(fw->directory, &cur) ||
- cur.st_ctime > fw->stats.st_ctime)
- updateFileDisplay(fw);
- }
-
- for (fw = file_windows; fw; fw = fw->next)
- fw->update = False;
- }
-
- /*-----------------------------------------------------------------------------
- Keep menus and status line consistent with the number of selections in each
- window. Currently this must be called manually, which is bad news.
- -----------------------------------------------------------------------------*/
- void updateStatus(FileWindowRec *fw)
- {
- char s[1024];
- int n_files, n_selections;
- long n_bytes, n_bytes_selected;
-
- if (fw->n_selections >= 1) {
- fillIn(fw->file_items[2]);
- fillIn(fw->file_items[3]);
- fillIn(fw->file_items[6]);
- fillIn(fw->file_items[10]);
- }else {
- grayOut(fw->file_items[2]);
- grayOut(fw->file_items[3]);
- grayOut(fw->file_items[6]);
- grayOut(fw->file_items[10]);
- }
-
- if (fw->display_type == Tree) {
- grayOut(fw->view_items[8]);
- grayOut(fw->view_items[9]);
- noTick(fw->view_items[8]);
- noTick(fw->view_items[9]);
- }
- else {
- fillIn(fw->view_items[8]);
- if (fw->show_dirs) {
- fillIn(fw->view_items[9]);
- noTick(fw->view_items[8]);
- if (fw->dirs_first)
- noTick(fw->view_items[9]);
- else
- tick(fw->view_items[9]);
- }
- else {
- grayOut(fw->view_items[9]);
- tick(fw->view_items[8]);
- noTick(fw->view_items[9]);
- }
- }
-
- if (fw->show_hidden)
- tick(fw->view_items[10]);
- else
- noTick(fw->view_items[10]);
-
- noTick(fw->view_items[0]);
- noTick(fw->view_items[1]);
- noTick(fw->view_items[2]);
- noTick(fw->view_items[4]);
- noTick(fw->view_items[5]);
- noTick(fw->view_items[6]);
-
- switch (fw->display_type) {
- case Tree:
- tick(fw->view_items[0]);
- break;
- case Icons:
- tick(fw->view_items[1]);
- break;
- case Text:
- tick(fw->view_items[2]);
- break;
- }
-
- switch (fw->sort_type) {
- case SortByName:
- tick(fw->view_items[4]);
- break;
- case SortBySize:
- tick(fw->view_items[5]);
- break;
- case SortByMTime:
- tick(fw->view_items[6]);
- break;
- }
-
- /* update the status line */
-
- n_bytes = fw->n_bytes;
- n_files = fw->n_files;
- n_bytes_selected = fw->n_bytes_selected;
- n_selections = fw->n_selections;
-
- if (fw->display_type == Tree) {
- n_bytes -= fw->files[1]->stats.st_size;
- n_files--;
- }
-
- if (n_selections > 0)
- sprintf(s,
- "%ld byte%s in %d item%s, %ld byte%s in %d selected item%s",
- n_bytes, n_bytes==1?"":"s",
- n_files, n_files==1?"":"s",
- n_bytes_selected, n_bytes_selected==1?"":"s",
- n_selections, n_selections==1?"":"s");
- else
- sprintf(s, "%ld byte%s in %d item%s", n_bytes, n_bytes==1?"":"s",
- n_files, n_files==1?"":"s");
-
- XtVaSetValues(fw->status, XtNlabel, (XtArgVal) s, NULL);
- }
-