home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1993 by Ove Kalkan, Cremlingen, Germany
- *
- * Permission to use, copy, modify, distribute and sell this software and it's
- * documentation for any purpose is hereby granted without fee, rpovided that
- * the above copyright notice and this permission appear in supporting
- * documentation, and that the name of Ove Kalkan not to be used in
- * advertising or publicity pertaining to distributiopn of the software without
- * specific, written prior permission. Ove Kalkan makes no representations
- * about the suitability of this software for any purpose. It is provided
- * as is without express or implied warranty.
- *
- * OVE KALKAN DISPLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABLILITY AND FITNESS, IN NO
- * EVENT SHALL OVE KALKAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- * $Header: filename,v 1.0 yyyy/mm/dd hh:mm:ss loginname Exp $
- */
-
- #define MAIN
- #include "global.h"
-
- #include "resources.h"
-
- /*
- * Globale Variablen
- */
-
-
- /*
- ** Function name : main
- **
- ** Description : Hauptinitialisierung
- ** Input : int argc, char **argv;
- ** Ouput : none
- */
- void main (int argc, char **argv)
- {
- Arg args[2];
- Widget but;
-
- #ifdef DEBUG
- {
- FILE *fp;
- if ((fp = fopen("xfm.debug","w"))) {
- fprintf(fp,"Xfilemanager Version %s - Debugging\n",VERSION);
- fclose(fp);
- }
- }
- #endif
-
- /*
- * Den App-Context initalisieren und das ToplevelWidget holen
- */
- XtSetArg(args[0],XtNminWidth, 200);
- XtSetArg(args[1],XtNminHeight,100);
- toplevel = XtAppInitialize(&app_context,"Xfilemanager",
- options,XtNumber(options),
- &argc,argv,NULL,args,2);
-
- XtAppAddActions (app_context, actions, XtNumber (actions));
- XtVaGetApplicationResources (toplevel,(XtPointer) &defaults,resources,
- XtNumber(resources),NULL);
-
- /*
- * Wenn Trashcan, dann schauen ob das directory existiert
- */
- if (defaults.trashcan) {
- struct stat buf;
-
- if (defaults.trashcan[0] == '~' && defaults.trashcan[1] == '/') {
- char s[1024];
-
- sprintf(s,"%s%s",getenv("HOME"),&defaults.trashcan[1]);
- defaults.trashcan = (char *) malloc(strlen(s) + 1);
- if (!defaults.trashcan)
- FATAL_ERROR("main: tmalloc failed");
- sprintf(defaults.trashcan,"%s",s);
- }
- if (!lstat(defaults.trashcan,&buf) || !S_ISDIR(buf.st_mode)) {
- char s[500];
- sprintf(s,"%s %s",MKDIR_CMD,defaults.trashcan);
- system(s);
- }
- }
-
- /*
- * Den Main-WidgetTree auf diesem Fenster erzeugen
- */
- if (!defaults.multi_window) {
- if (!(folder = (Folder_Glyph *) malloc (sizeof(Folder_Glyph))))
- FATAL_ERROR ("main: Cannot create folder\n");
-
- /*
- * Den Main-Folder setzen
- */
- folder->file_count = 0;
- folder->dir = &root;
- folder_count = 1;
- folder->file = NULL;
- folder->filter = NULL;
- folders[0] = folder;
- folder->fs_type = FS_NORMAL;
- }
- createWidgets(toplevel);
-
- /*
- * Die Usersettings fuer Filetypen einlesen und die Pixmaps
- * generieren
- */
- readCustomSettings();
-
- /*
- * Den Root-Glyph initialisieren
- */
- root.x = 0;
- root.y = 0;
- root.open = TRUE;
- #ifndef RESTRICTED_DIRS
- if (!defaults.root_dir) {
- #endif
- root.name = (String) getenv("HOME");
- if (!root.name)
- root.name = "/";
- #ifdef RESTRICTED_DIRS
- if (!strncmp(root.name,defaults.root_dir,strlen(root.name)))
- root.name = defaults.root_dir;
- #else
- }
- else
- root.name = defaults.root_dir;
- #endif
- root.parent = NULL;
- root.dir = NULL;
- root.dir_count = 0;
-
- /*
- * Den Status des Root-Directories holen
- */
- {
- struct stat buf;
-
- (void) stat (root.name,&buf);
- root.flags = getFlags(&buf);
- }
-
- fillDir(&root);
- if (folders[0])
- fillFolder(folders[0]);
-
- /*
- * Jetzt die Widgets erst einmal darstellen
- */
- if (!defaults.multi_window) {
- Arg args[2];
-
- XtSetArg(args[0],XtNwidth,100);
- XtSetArg(args[1],XtNheight,100);
- XtSetValues(folder->window,args,2);
- }
- XtRealizeWidget(toplevel);
-
- /*
- * Die Pixmaps laden
- */
- if (getuid() == 0)
- LoadDeviceIcons(toplevel);
- loadIcons();
- loadTypeIcons();
- readWorkspace(&workspace,".xfmwrc");
-
- /*
- * Das Haupmenu erweitern - muss hier geschehen, da Icons verlangt werden
- */
- makeIconBar(NULL,icon_bar,icon_left,FALSE,TRUE);
- XtVaCreateManagedWidget("clock",clockWidgetClass, icon_bar,
- XtNwidth, 34,
- XtNheight, 34,
- XtNleft, XawChainRight,
- XtNright, XawChainRight,
- XtNtop, XawChainTop,
- XtNbottom, XawChainBottom,
- XtNhorizDistance, (defaults.multi_window ? 360 : 860),
- XtNshapeWindow, FALSE,
- NULL);
-
- /*
- * Auf der Form 2 Buttons fuer Edit und Delete einrichten
- */
- but = XtVaCreateManagedWidget("wse_but", iconBWidgetClass, ws_bar,
- XtNleft, XawChainLeft,
- XtNright, XawChainLeft,
- XtNbottom, XawChainTop,
- XtNtop, XawChainTop,
- XtNimageWidth, 32,
- XtNimageHeight, 32,
- XtNimage, Icon_WSE_PM,
- NULL);
- XtAddCallback(but,XtNcallback,(XtCallbackProc) start_WSedit,NULL);
-
- but = XtVaCreateManagedWidget("wsd_but", iconBWidgetClass, ws_bar,
- XtNleft, XawChainLeft,
- XtNright, XawChainLeft,
- XtNbottom, XawChainTop,
- XtNtop, XawChainTop,
- XtNfromHoriz, but,
- XtNimageWidth, 32,
- XtNimageHeight, 32,
- XtNimage, Icon_WSD_PM,
- NULL);
- XtAddCallback(but,XtNcallback,(XtCallbackProc) start_WSdelete,NULL);
-
- /*
- * Die GC's zum Zeichnen des Dir-Trees initialisieren
- */
- {
- XtGCMask mask;
- XGCValues values;
- Arg args[1];
-
- mask = GCFont | GCForeground;
- values.font = defaults.icon_font->fid;
- values.foreground = XBlackPixel (XtDisplay(toplevel),
- XDefaultScreen(XtDisplay(toplevel)));
- line_gc = XtGetGC (toplevel, mask, &values);
-
- XtSetArg(args[0],XtNbackground,&values.foreground);
- XtGetValues(toplevel,args,1);
- back_gc = XtGetGC (toplevel, mask, &values);
-
- values.foreground = XWhitePixel (XtDisplay(toplevel),
- XDefaultScreen(XtDisplay(toplevel)));
- white_gc = XtGetGC (toplevel, mask, &values);
-
- values.foreground = defaults.select_color;
- selc_gc = XtGetGC (toplevel, mask, &values);
- }
- XtManageChild(dir_area);
- XtManageChild(workspace.window);
-
- if (!defaults.multi_window) {
- Arg args[2];
- char *s = getPath(folder->dir);
-
- XtSetArg(args[0],XtNwidth,100);
- XtSetArg(args[1],XtNheight,100);
- XtSetValues(folder->window,args,2);
- XtManageChild(folder->window);
- XtSetArg(args[0],XtNlabel,(*s == '\0' ? "/" : s));
- XtSetValues(folder->label,args,1);
-
- }
- else {
- XtWidgetGeometry a,b;
-
- a.width = workspace.fw;
- a.height = workspace.fh;
- a.x = workspace.fx;
- a.y = workspace.fy;
- a.request_mode = CWWidth | CWHeight | CWX | CWY;
- XtMakeGeometryRequest(workspace.shell,&a,&b);
-
- XtManageChild(workspace.shell);
- }
- /*
- * Den Default Cursor setzen
- */
- makeCursor();
-
- XDefineCursor(XtDisplay(dir_area),XtWindow(dir_area), def_cursor);
- XDefineCursor (XtDisplay(workspace.window),
- XtWindow(workspace.window), def_cursor);
- if (!defaults.multi_window)
- XDefineCursor(XtDisplay(folder->window),
- XtWindow(folder->window), def_cursor);
- folder = NULL;
-
- #ifdef HAS_QUOTA
- showQuota(quota_label);
- #endif
-
- signal(SIGCHLD, signal_handler);
- /*
- * Der Main-Loop
- */
- XtAppMainLoop(app_context);
- }
-
-
- MYSIGTYPE signal_handler(int sig)
- {
- while (waitpid(-1,NULL,WNOHANG) > 0);
- signal(SIGCHLD, signal_handler);
- }
-
-
- /*
- ** Function name : createWidgets
- **
- ** Description : Diese Funktion erzeugt ein Directoryfenster
- ** Input : Widget parent; Zeiger auf das Parentwidget
- ** Ouput : none
- */
- void createWidgets (Widget parent)
- {
- Arg args[12];
- Widget field_pane,
- dir_pane,
- dummy,
- viewport,
- dev_box,
- main_pane;
-
-
- /*
- * Zunaechst erst einmal den main-pane erzeugen
- */
- main_pane = XtCreateManagedWidget("main_pane", panedWidgetClass,
- parent, args,0);
-
- /*
- * Das Haupmenu ergaenzen
- */
- makeMenu (main_pane);
-
- /*
- * Die Seperator-pane fuer die Directoryfields setzen
- */
- if (!defaults.multi_window) {
- XtSetArg(args[0],XtNorientation, XtorientHorizontal);
- field_pane = XtCreateManagedWidget("field_pane", panedWidgetClass,
- main_pane, args,1);
- XtSetArg(args[0],XtNwidth,300); /* Bei Single Window hat die
- Iconbar Oben genug Platz */
- }
- else {
- field_pane = main_pane;
- XtSetArg(args[0],XtNwidth, 400);
- }
-
- /*
- * Unter der Dir-Area muss noch ein Feld fuer die Quotas stehen, darum
- * pane erzeugen
- */
- dir_pane = XtVaCreateManagedWidget ("dir_pane",formWidgetClass,
- field_pane,
- XtNdefaultDistance, 0,
- NULL);
-
- /*
- * Auf dieses field_pane jetzt den Viewport setzen, der das
- * Simple-Widget fuer den Directory-Tree enthalten soll
- */
-
- XtSetArg(args[1],XtNheight,480);
- XtSetArg(args[2],XtNallowHoriz, TRUE);
- XtSetArg(args[3],XtNallowVert, TRUE);
- XtSetArg(args[4],XtNforceBars, TRUE);
- XtSetArg(args[5],XtNuseBottom, TRUE);
- XtSetArg(args[6],XtNuseRight, TRUE);
- XtSetArg(args[7],XtNleft, XawChainLeft);
- XtSetArg(args[8],XtNright, XawChainRight);
- XtSetArg(args[9],XtNbottom, XawChainBottom);
- XtSetArg(args[10],XtNtop,XawChainTop);
- viewport = XtCreateManagedWidget("viewport", viewportWidgetClass,
- dir_pane, args,11);
- dir_vp = viewport;
-
- /*
- * Auf das Viewport kommt jetzt das Simple-Widget fuer den
- * Directory Tree
- */
- dir_area = XtCreateWidget("dir_simple", simpleWidgetClass,
- viewport, args, 2);
- XtOverrideTranslations(dir_area,
- XtParseTranslationTable("<Leave>: leave-window()\n\
- <Enter>: enter-window()\n\
- <Expose>: refresh-dirs()\n\
- <Btn3Down>: start-popup()\n\
- <Btn1Down>: clear-multi() start-single()\n\
- <Btn1Motion>: follow-single()\n\
- <Btn1Up>: end-single()"));
- /*
- * Den Quota_label erzeugen
- */
- if (getuid() == 0)
- dev_box = CreateDeviceBox(dir_pane,viewport);
- #ifdef HAS_QUOTA
- else
- quota_label = XtVaCreateManagedWidget("quota_label",labelWidgetClass,
- dir_pane,
- XtNfromVert,dir_vp,
- XtNborderWidth,0,
- XtNleft, XawChainLeft,
- XtNright, XawChainRight,
- XtNtop, XawChainBottom,
- XtNbottom, XawChainBottom,
- XtNjustify, XtJustifyLeft,
- XtNwidth, (defaults.multi_window ? 400 : 300),
- NULL);
- #endif
- /*
- * Den ersten Folder ersellen, je nach Status der Default-Variable
- * im Pane in einem eigenen Fenster
- */
- if (!defaults.multi_window) {
- dummy = field_pane;
- /*
- * Den Folder erzeugen
- */
- makeFolderWindow (dummy, folder,0);
- makeWorkspaceWindow (dummy, &workspace);
- }
- else {
- Widget shell;
-
- shell = XtVaCreatePopupShell("ws_shell",topLevelShellWidgetClass,
- toplevel, XtNtitle,"Workspace",NULL);
- makeWorkspaceWindow (shell, &workspace);
- }
- }
-
-
-
- /*
- ** Function name : FATAL_ERROR
- **
- ** Description : Bricht im Fehlerfall mit einer Fehlermeldung ab
- ** Input :
- ** Ouput :
- */
- void FATAL_ERROR (char *message)
- {
- fprintf(stderr,"%s",message);
- exit(1);
- }
-
-
-
- /*
- ** Function name : refresh_files
- **
- ** Description : Neuzeichnen des Directories nach einem Expose
- ** Input : none
- ** Ouput : none
- */
- XtActionProc refresh_files (Widget w, XExposeEvent *e, String *s, Cardinal *c)
- {
- Dimension lx = 0, ly;
- Arg args[4];
- int hs, he;
- Folder_Glyph *rfolder;
-
- while (lx < folder_count && lx < MAX_FOLDERS && folders[lx]->window != w)
- lx++;
-
- if (lx < folder_count) {
- rfolder = folders[lx];
-
- /*
- * Directorypfad neu Zeichnen
- */
- if (FILE_CHANGED) {
- XClearWindow(XtDisplay(rfolder->window),
- XtWindow(rfolder->window));
- FILE_CHANGED = FALSE;
- if (!defaults.multi_window)
- XtMoveWidget(rfolder->window,0,0);
- }
- /*
- * Berechnen, welche Eintrage gerade sichtbar sind und eines Refreshs
- * beduerfen. Die derzeitige Loesung koennte Probleme bei Terminals
- * mit Backingstores geben.
- */
- if (!e){
- hs = 0;
- he = rfolder->file_count - 1;
- }
- else {
- hs = (e->y - 4) / DIR_Y_STEP;
- if (hs < 0)
- hs = 0;
- he = hs + e->height/DIR_Y_STEP + 1;
- if (he > rfolder->file_count - 1)
- he = rfolder->file_count - 1;
- }
- showFolder (rfolder->window, rfolder, 20, 6, &lx, &ly, hs, he);
-
- /*
- * Die Hoehe anpassen
- */
- {
- Arg args[2];
-
- XtSetArg(args[0],XtNwidth,lx + 2*DIR_Y_STEP + typelength);
- XtSetArg(args[1],XtNheight, ly + 2*DIR_Y_STEP);
- XtSetValues(rfolder->window,args,2);
- }
- }
- }
-
-
-
- /*
- ** Function name : refresh_dirs
- **
- ** Description : Neuzeichnen des Directories nach einem Expose
- ** Input : none
- ** Ouput : none
- */
- XtActionProc refresh_dirs (Widget w, XExposeEvent *e, String *s, Cardinal *c)
- {
- Dimension lx = 0, ly;
- int hs,he;
-
- /*
- * Directorypfad neu Zeichnen
- */
- if (DIR_CHANGED) {
- DIR_CHANGED = FALSE;
- XClearWindow(XtDisplay(dir_area),XtWindow(dir_area));
- }
- /*
- * Berechnen, welche Eintrage gerade sichtbar sind und eines Refreshs
- * beduerfen. Die derzeitige Loesung koennte Probleme bei Terminals
- * mit Backingstores geben.
- */
- if (!e) {
- hs = 0;
- he = 16000;
- }
- else {
- hs = e->y - DIR_Y_STEP;
- if (hs < 0)
- hs = 0;
-
- he = hs + e->height + 2*DIR_Y_STEP;
- }
-
- showDir (dir_area, &root, 20, 6, &lx, &ly,hs,he);
-
- /*
- * Die Hoehe anpassen
- */
- {
- Arg args[2];
-
- XtSetArg(args[0],XtNwidth,lx + 2*DIR_Y_STEP);
- XtSetArg(args[1],XtNheight, ly + 2*DIR_Y_STEP);
- XtSetValues(dir_area,args,2);
- }
- }
-
-
-
-
-
-
- /*
- ** Function name : getGlyph
- **
- ** Description : Prueft, ob an den Koordinaten x,y ein Glyph liegt
- ** Input : Dir_Glyph Root; Position x,y
- ** Ouput :
- */
- Dir_Glyph *getGlyph (Dir_Glyph *d, Dimension x, Dimension y)
- {
- /*
- * Pruefen ob Punkt ueberhaupt im Bereich liegen kann
- */
- if (y < d->y || x < d->x)
- return(NULL);
-
- /*
- * Pruefen ob das Icon das an dieser Position liegt
- */
- if ( y < d->y + 16 && x < d->x + 24 + 8*strlen(d->name))
- return(d);
-
- /*
- * Das Stammglyph war es nicht, also Verzeichnis durchsuchen
- */
- if (d->dir_count > 0 && d->open) {
- int i;
-
- /*
- * alle Glyphs durchprobieren
- */
- for (i = 0; i < d->dir_count; i++) {
- Dir_Glyph *b;
-
- b = getGlyph(d->dir[i],x,y);
- if (b != NULL)
- return(b);
- }
- }
- return(NULL);
- }
-
-
-
- #ifdef HAS_QUOTA
- /*********************************************************
- * name: showQuota
- * description: Anzeigen der Userquotas
- * input: Widget w - Quota-Label
- * output: none
- * author: Ove Kalkan
- * date: 20.7.1993
- *********************************************************/
- void showQuota(Widget w)
- {
- uid_t uid = getuid();
- Arg args[1];
- #if defined(hpux) || defined(ultrix)
- struct dqblk addr;
- #endif
- if (uid == 0)
- return;
- #if defined(hpux) || defined(ultrix)
- if (quotactl(Q_GETQUOTA,QUOTA_DEV,
- uid, (void *) &addr))
- #else
- if (1)
- #endif
- #ifdef DEUTSCH
- XtSetArg(args[0],XtNlabel,"Keine Beschraenkungen");
- #else
- XtSetArg(args[0],XtNlabel,"Cannot get Quotas");
- #endif
- else {
- char s[200];
- #if defined(hpux) || defined(ultrix)
- #ifdef DEUTSCH
- sprintf(s,"Beschraenkung: %d von %d Bloecken",
- #else
- sprintf(s,"Quotas: %d of %d Blocks",
- #endif
- addr.dqb_curblocks,
- addr.dqb_bsoftlimit);
- #endif
- XtSetArg(args[0],XtNlabel,s);
- }
- XtSetValues(w,args,1);
- }
-
- #endif
-
-
- #ifdef HAS_NO_STRRSTR
- /*
- * This function is missing in libc.so.4.4.1 on linux systems,
- */
- char *strrstr (char *vs, char *ve)
- {
- register u_int i = strlen(ve);
- register u_int j = strlen(vs);
- register u_int h;
-
- if (i > j)
- return(NULL);
- for (h = j - i; h; h--) {
- if (!strncmp(vs+h,ve,i))
- return(vs+h);
- }
- return(NULL);
- }
- #endif
-
-
- #ifdef DEBUG
- void debug (const char *format, __va_list list)
- {
- FILE *fp;
-
- if (!(fp = fopen("xfm.debug","a")))
- return;
- fprintf(fp,format,list);
- fclose(fp);
- }
- #endif
-