home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / XAP / XFILEMAN / XFILEMAN.TAR / xfilemanager / main.c.old < prev    next >
Encoding:
Text File  |  1993-09-22  |  26.6 KB  |  1,107 lines

  1. /*
  2.  * Copyright 1993 by Ove Kalkan, Cremlingen, Germany
  3.  *
  4.  * Permission to use, copy, modify, distribute and sell this software and it's
  5.  * documentation for any purpose is hereby granted without fee, rpovided that
  6.  * the above copyright notice and this permission appear in supporting
  7.  * documentation, and that the name of Ove Kalkan not to be used in
  8.  * advertising or publicity pertaining to distributiopn of the software without
  9.  * specific, written prior permission. Ove Kalkan makes no representations
  10.  * about the suitability of this software for any purpose. It is provided
  11.  * as is without express or implied warranty.
  12.  *
  13.  * OVE KALKAN DISPLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  14.  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABLILITY AND FITNESS, IN NO
  15.  * EVENT SHALL OVE KALKAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  16.  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  17.  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  18.  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  19.  * PERFORMANCE OF THIS SOFTWARE.
  20.  *
  21.  * $Header: filename,v 1.0 yyyy/mm/dd hh:mm:ss loginname Exp $
  22.  */
  23.  
  24.  
  25. #include <stdio.h>
  26. #include <dirent.h>
  27. #include <unistd.h>
  28. #include <sys/stat.h>
  29.  
  30. #include <X11/X.h>
  31. #include <X11/cursorfont.h>
  32.  
  33. #include <X11/Intrinsic.h>
  34. #include <X11/StringDefs.h>
  35.  
  36. #ifdef    HAVE_XPM
  37. #include <X11/xpm.h>
  38. #include "icons.h"
  39. #else
  40. #include "bitmaps.h"
  41. #endif
  42.  
  43. #include "cursor.h"
  44. #include "cursorm.h"
  45. #include "fcursor.h"
  46. #include "fcursorm.h"
  47.  
  48. #include <X11/Shell.h>
  49.  
  50. #include <X11/Xaw/Paned.h>
  51. #include <X11/Xaw/Form.h>
  52. #include <X11/Xaw/Viewport.h>
  53. #include <X11/Xaw/Simple.h>
  54. #include <X11/Xaw/Label.h>
  55.  
  56. #include "struct.h"
  57. #include "config.h"
  58.  
  59.  
  60. /*
  61.  * Globale Variablen
  62.  */
  63.  
  64.  
  65. Widget        toplevel,        /* Das toplevel Widget */
  66.         dir_area,        /* Die Area in die der Diretorybaum gezeichnet
  67.                        wird */
  68.         dir_vp,
  69.         file_label,        /* File Label */
  70.         file_area;        /* Hier werden die Files gezeigt */
  71.  
  72. XtAppContext    app_context;        /* Der ApplicationContext - wichtig
  73.                        fuer den periodischen Directory Scan */
  74.  
  75. Dir_Glyph    root;            /* Das Root-Glyphe */
  76. Folder_Glyph    folder;            /* Der Main Folder */
  77.  
  78. GC        line_gc;        /* Die GC fuer die Linien */
  79. GC        back_gc;        /* Die GC fuer den Background */
  80. GC        selc_gc;        /* Die GC fuer den Background */
  81.  
  82. Font        iconfont;        /* der Font fuer die Icons */
  83.  
  84. Pixmap        Dir_Closed_PM;        /* Geschlossene Dirs */
  85. Pixmap        Dir_Opened_PM;        /* Offenes Directory */
  86. Pixmap        Dir_Locked_PM;        /* Verschlossen fuer Read/Write */
  87.  
  88. Pixmap        File_Root_PM;        /* Fuer das Parentdir */
  89. Pixmap        File_Plain_PM;        /* Fuer unknown Files */
  90. Pixmap        File_Text_PM;        /* Fuer Text-Files */
  91. Pixmap        File_Link_PM;        /* Fuer Links */
  92. Pixmap        File_Lock_PM;        /* Fuer readpermitted files */
  93. Pixmap        File_Pic_PM;        /* Fuer pictures */
  94.  
  95. Boolean        DIR_CHANGED = FALSE;    /* Bildhintergrund refreshen */
  96. Boolean        FILE_CHANGED = FALSE;    /* Bildhintergrund refreshen */
  97.  
  98. Dimension    last_y = 16000;        /* Fuer die MotionEvents */
  99. Dir_Glyph    *last_g = NULL;
  100.  
  101. Dimension    last_v = 16000;        /* Fuer die Motionevents in der File-liste */
  102.  
  103. Dir_Glyph    *grab_g = NULL;        /* Gerade gegrabbte Glyph im Dir-Feld */
  104. File_Glyph    *grab_f = NULL;    
  105.  
  106. Dir_Glyph    selc_g = NULL
  107. Dimension    selc_f = 16000;
  108. Time        selc_t = 0;
  109.  
  110. Cursor        def_cursor;
  111. Cursor        file_cursor;
  112.  
  113. Atom        wm_delete_window;
  114.  
  115. int        label_height, vp_width;
  116.  
  117. Suffix_Glyph    commands[] = {
  118.     {"xv",    ".gif,.jpg,.GIF,.JPG,.pbm,.xbm,.ppm,.pgm,.XBM,.BM,.bm,.PBM,.PPM,.PGM",    FILE_PIC},
  119.     {"xmore",".txt,.doc",    FILE_TEXT},
  120.     {NULL,NULL,FILE_PLAIN},
  121. };
  122.  
  123.  
  124. /*
  125.  * Function Prototypes
  126.  */
  127. void    main (int argc, char **argv);
  128. void    createWidgets (Widget parent);
  129. void    FATAL_ERROR (char *message);
  130.  
  131. extern    void        fillDir (Dir_Glyph *dir);
  132. extern    void        showDir (Widget window, Dir_Glyph *dir,
  133.                  Dimension x, Dimension y,
  134.                  Dimension *lx, Dimension *ly);
  135.  
  136. extern    void        fillFolder (Folder_Glyph *folder);
  137. extern    String        getPath (Dir_Glyph *dir);
  138.  
  139. Dir_Glyph    *getGlyph (Dir_Glyph *d, Dimension x, Dimension y);
  140.  
  141. XtActionProc    refresh_dirs(Widget w, XEvent *e, String *s, Cardinal *c);
  142. XtActionProc    button_press(Widget w, XButtonEvent *e, String *s, Cardinal *c);
  143. XtActionProc    dir_mouse(Widget w, XMotionEvent *e, String *s, Cardinal *c);
  144. XtActionProc    dir_unhighlight(Widget w, XMotionEvent *e, String *s, Cardinal *c);
  145. XtActionProc    dir_ungrab(Widget w, XMotionEvent *e, String *s, Cardinal *c);
  146. XtActionProc    dir_grab(Widget w, XMotionEvent *e, String *s, Cardinal *c);
  147.  
  148. XtActionProc    refresh_files(Widget w, XEvent *e, String *s, Cardinal *c);
  149. XtActionProc    file_mouse(Widget w, XMotionEvent *e, String *s, Cardinal *c);
  150.  
  151. XtActionProc    mark_object(Widget w, XEvent *e, String *s, Cardinal *c);
  152.  
  153. void        DEBUG (char *message);
  154. void        makeCursor ();
  155.  
  156. #define        EXIT    (exit(0))
  157.  
  158. /*
  159.  * Den Actionsrec erzeugen
  160.  */
  161. static XtActionsRec actions[] =
  162. {
  163.     {"refresh-dirs",
  164.         (XtActionProc) refresh_dirs
  165.     },
  166.     {"unhighlight-dir",
  167.         (XtActionProc) dir_unhighlight
  168.     },
  169.     {"follow-dir",
  170.         (XtActionProc) dir_mouse
  171.     },
  172.     {"grab-dir",
  173.         (XtActionProc) dir_grab
  174.     },
  175.     {"grab-file",
  176.         (XtActionProc) dir_grab
  177.     },
  178.     {"ungrab-dir",
  179.         (XtActionProc) dir_ungrab
  180.     },
  181.     {"refresh-files",
  182.         (XtActionProc) refresh_files
  183.     },
  184.     {"button-press",
  185.         (XtActionProc) button_press
  186.     },
  187.     {"follow-file",
  188.         (XtActionProc) file_mouse
  189.     },
  190.     {"mark",
  191.         (XtActionProc) mark_object
  192.     },
  193. };
  194.  
  195.  
  196. /*
  197. **    Function name : main
  198. **
  199. **    Description :    Hauptinitialisierung
  200. **    Input :     int argc, char **argv;
  201. **    Ouput :        none
  202. */
  203. void main (int argc, char **argv)
  204. {
  205.     Arg    args[2];
  206.     
  207.     /*
  208.      * Den App-Context initalisieren und das ToplevelWidget holen
  209.      */
  210.     XtSetArg(args[0],XtNminWidth, 200);
  211.     XtSetArg(args[1],XtNminHeight,100);
  212.     toplevel = XtAppInitialize(&app_context,"Xfilemanager",NULL,0,
  213.                    &argc,argv,NULL,args,2);
  214.  
  215.     XtAppAddActions (app_context, actions, XtNumber (actions));
  216.  
  217.     /*
  218.      * Den Main-WidgetTree auf diesem Fenster erzeugen
  219.      */
  220.     createWidgets(toplevel);
  221.  
  222.     /*
  223.      * Den Main-Folder setzen
  224.      */
  225.     folder.max_length = 0;
  226.     folder.rows = 1;
  227.     folder.file_count = 0;
  228.     folder.dir = &root;
  229.     folder.file = NULL;
  230.  
  231.     /*
  232.      * Den Root-Glyph initialisieren
  233.      */
  234.     root.x = 0;
  235.     root.y = 0;
  236.     root.open = TRUE;
  237.     root.name = (String) getenv("HOME");
  238. /*    root.name = "";
  239. */    root.parent = NULL;
  240.     root.dir = NULL;
  241.     root.dir_count = 0;
  242.  
  243.     /*
  244.      * Den Status des Root-Directories holen
  245.      */
  246.     {
  247.         struct stat buf;
  248.  
  249.         (void) stat ("/",&buf);
  250.         root.flags = (buf.st_mode&(S_IRUSR | S_IRGRP | S_IROTH) ? DIR_READABLE : 0)
  251.                  + (buf.st_mode&(S_IWUSR | S_IWGRP | S_IWOTH) ? DIR_WRITEABLE : 0);
  252.     }
  253.     fillDir(&root);
  254.     fillFolder(&folder);
  255.  
  256.     /*
  257.      * Jetzt die Widgets erst einmal darstellen
  258.      */
  259.     XtRealizeWidget(toplevel);
  260.  
  261.     /*
  262.      * Die Pixmaps laden
  263.      */
  264. #ifdef    HAVE_XPM
  265.     {
  266.         Pixmap        smap;
  267.         XpmAttributes    attr;
  268.  
  269.         if (XpmCreatePixmapFromData (XtDisplay(toplevel),
  270.                          XtWindow(toplevel), dir_closed,
  271.                          &Dir_Closed_PM, &smap,
  272.                          &attr) != XpmSuccess)
  273.             FATAL_ERROR("main: Failed to get 1. Icon\n");
  274.         if (XpmCreatePixmapFromData (XtDisplay(toplevel),
  275.                          XtWindow(toplevel), dir_opened,
  276.                          &Dir_Opened_PM, &smap,
  277.                          &attr) != XpmSuccess)
  278.             FATAL_ERROR("main: Failed to get 2. Icon\n");
  279.         if (XpmCreatePixmapFromData (XtDisplay(toplevel),
  280.                          XtWindow(toplevel), dir_locked,
  281.                          &Dir_Locked_PM, &smap,
  282.                          &attr) != XpmSuccess)
  283.             FATAL_ERROR("main: Failed to get 3. Icon\n");
  284.         if (XpmCreatePixmapFromData (XtDisplay(toplevel),
  285.                          XtWindow(toplevel), file_root,
  286.                          &File_Root_PM, &smap,
  287.                          &attr) != XpmSuccess)
  288.             FATAL_ERROR("main: Failed to get 4. Icon\n");
  289.         if (XpmCreatePixmapFromData (XtDisplay(toplevel),
  290.                          XtWindow(toplevel), file_plain,
  291.                          &File_Plain_PM, &smap,
  292.                          &attr) != XpmSuccess)
  293.             FATAL_ERROR("main: Failed to get 5. Icon\n");
  294.         if (XpmCreatePixmapFromData (XtDisplay(toplevel),
  295.                          XtWindow(toplevel), file_text,
  296.                          &File_Text_PM, &smap,
  297.                          &attr) != XpmSuccess)
  298.             FATAL_ERROR("main: Failed to get 6. Icon\n");
  299.         if (XpmCreatePixmapFromData (XtDisplay(toplevel),
  300.                          XtWindow(toplevel), file_lock,
  301.                          &File_Lock_PM, &smap,
  302.                          &attr) != XpmSuccess)
  303.             FATAL_ERROR("main: Failed to get 7. Icon\n");
  304.         if (XpmCreatePixmapFromData (XtDisplay(toplevel),
  305.                          XtWindow(toplevel), file_link,
  306.                          &File_Link_PM, &smap,
  307.                          &attr) != XpmSuccess)
  308.             FATAL_ERROR("main: Failed to get 8. Icon\n");
  309.         if (XpmCreatePixmapFromData (XtDisplay(toplevel),
  310.                          XtWindow(toplevel), file_pic,
  311.                          &File_Pic_PM, &smap,
  312.                          &attr) != XpmSuccess)
  313.             FATAL_ERROR("main: Failed to get 9. Icon\n");
  314.     }
  315. #else
  316. #endif
  317.     /*
  318.      * Die GC's zum Zeichnen des Dir-Trees initialisieren
  319.      */
  320.     iconfont = XLoadFont(XtDisplay(toplevel),DEFAULT_ICON_FONT);
  321.     {
  322.         XtGCMask    mask;
  323.         XGCValues    values;
  324.  
  325.         mask = GCFont | GCForeground;
  326.         values.font = iconfont;
  327.         values.foreground = XBlackPixel (XtDisplay(toplevel),
  328.                          XDefaultScreen(XtDisplay(toplevel)));
  329.         line_gc = XtGetGC (toplevel, mask, &values);
  330.  
  331.         mask = GCFont | GCForeground;
  332.         values.font = iconfont;
  333.         values.foreground = XWhitePixel (XtDisplay(toplevel),
  334.                          XDefaultScreen(XtDisplay(toplevel)));
  335.         back_gc = XtGetGC (toplevel, mask, &values);
  336.  
  337.         mask = GCFont | GCForeground;
  338.         values.font = iconfont;
  339.         values.foreground = 6;
  340.         selc_gc = XtGetGC (toplevel, mask, &values);
  341.     }
  342.     XtManageChild(dir_area);
  343.     XtManageChild(file_area);
  344.  
  345.     {
  346.         Arg    args[1],largs[1];
  347.  
  348.         XtSetArg(args[0],XtNwidth,0);
  349.         XtGetValues(dir_vp,args,1);
  350.         XtSetArg(largs[0],XtNheight,0);
  351.         XtGetValues(file_label,largs,1);
  352.  
  353.         label_height = largs[0].value;
  354.         vp_width = args[0].value;
  355.     }
  356.  
  357.     /*
  358.      * Den Default Cursor setzen
  359.      */
  360.     makeCursor();
  361.  
  362.     XDefineCursor(XtDisplay(dir_area),XtWindow(dir_area), def_cursor);
  363.     XDefineCursor(XtDisplay(file_area),XtWindow(file_area), def_cursor);
  364.  
  365.     /*
  366.      * Den Quit-Button im WM-Menu als Quitbutton nutzen
  367.      */
  368.     wm_delete_window = XInternAtom(XtDisplay(toplevel),"WM_DELETE_WINDOW",
  369.                     FALSE);
  370.     (void) XSetWMProtocols (XtDisplay(toplevel),XtWindow(toplevel),&wm_delete_window,1);
  371.     /*
  372.      * Der Main-Loop
  373.      */
  374.     XtAppMainLoop(app_context);
  375. }
  376.  
  377.  
  378.  
  379.  
  380. /*
  381. **    Function name : createWidgets
  382. **
  383. **    Description :    Diese Funktion erzeugt ein Directoryfenster
  384. **    Input :        Widget    parent;    Zeiger auf das Parentwidget
  385. **    Ouput :        none
  386. */
  387. void createWidgets (Widget parent)
  388. {
  389.     Arg    args[10];
  390.     Widget    main_pane,
  391.         field_pane,
  392.         dummy,
  393.         viewport;
  394.     
  395.     
  396.     /*
  397.      * Zunaechst erst einmal den main-pane erzeugen
  398.      */
  399.     main_pane = XtCreateManagedWidget("main_pane", panedWidgetClass,
  400.                       parent, args,0);
  401.  
  402.     /*
  403.      * Die Seperator-pane fuer die Directoryfields setzen
  404.      */
  405.     XtSetArg(args[0],XtNorientation, XtorientHorizontal);
  406.     field_pane = XtCreateManagedWidget("field_pane", panedWidgetClass,
  407.                        main_pane, args,1);
  408.  
  409.     /*
  410.      * Auf dieses field_pane jetzt den Viewport setzen, der das
  411.      * Simple-Widget fuer den Directory-Tree enthalten soll
  412.      */    
  413.     XtSetArg(args[0],XtNallowHoriz, TRUE);
  414.     XtSetArg(args[1],XtNallowVert, TRUE);
  415.     XtSetArg(args[2],XtNwidth, 300);
  416.     XtSetArg(args[3],XtNheight,400);
  417.     XtSetArg(args[4],XtNforceBars, TRUE);
  418.     XtSetArg(args[5],XtNuseBottom, TRUE);
  419.     XtSetArg(args[6],XtNuseRight, TRUE);
  420.     viewport = XtCreateManagedWidget("viewport", viewportWidgetClass,
  421.                      field_pane, args,7);
  422.     dir_vp = viewport;
  423.  
  424.     /*
  425.      * Auf das Viewport kommt jetzt das Simple-Widget fuer den
  426.      * Directory Tree
  427.      */
  428.     XtSetArg(args[0],XtNwidth, 300);
  429.     XtSetArg(args[1],XtNheight,400);
  430.     dir_area = XtCreateWidget("dir_simple", simpleWidgetClass,
  431.                   viewport, args, 2);
  432.     XtOverrideTranslations(dir_area, 
  433.                    XtParseTranslationTable("<Expose>: refresh-dirs()\n\
  434.                                 <Btn1Motion>: follow-dir() grab-dir()\n\
  435.                             <Btn1Down>: follow-dir() mark()\n\
  436.                                 <Leave>: unhighlight-dir()\n\
  437.                                 <Btn1Up>: button-press() unhighlight-dir() ungrab-dir()"));
  438.  
  439.     /*
  440.      * Den Bereich fuer das Folder-Fenster
  441.      */
  442.     dummy = XtCreateManagedWidget("folder_pane", panedWidgetClass,
  443.                       field_pane, args,0);
  444.  
  445.     /*
  446.      * darauf den File_label erzeugen
  447.      */
  448.     XtSetArg(args[0],XtNshowGrip, FALSE);
  449.     file_label = XtCreateManagedWidget("file_label", labelWidgetClass,
  450.                        dummy, args,1);
  451.  
  452.     /*
  453.      * Auf dieses field_pane jetzt den Viewport setzen, der das
  454.      * Simple-Widget fuer den Directory-Tree enthalten soll
  455.      */    
  456.     XtSetArg(args[0],XtNallowHoriz, TRUE);
  457.     XtSetArg(args[1],XtNallowVert, TRUE);
  458.     XtSetArg(args[2],XtNwidth, 400);
  459.     XtSetArg(args[3],XtNheight,400);
  460.     XtSetArg(args[4],XtNforceBars, TRUE);
  461.     XtSetArg(args[5],XtNuseBottom, TRUE);
  462.     XtSetArg(args[6],XtNuseRight, TRUE);
  463.     viewport = XtCreateManagedWidget("viewport", viewportWidgetClass,
  464.                      dummy, args,7);
  465.  
  466.     /*
  467.      * Auf das Viewport kommt jetzt das Simple-Widget fuer den
  468.      * Directory Tree
  469.      */
  470.     XtSetArg(args[0],XtNwidth, 400);
  471.     XtSetArg(args[1],XtNheight,400);
  472.     file_area = XtCreateWidget("file_simple", simpleWidgetClass,
  473.                   viewport, args, 2);
  474.     XtOverrideTranslations(file_area, 
  475.                    XtParseTranslationTable("<Btn1Motion>: follow-file() grab-file()\n\
  476.                             <Btn1Down>: follow-file() mark()\n\
  477.                                 <Leave>: unhighlight-dir()\n\
  478.                                 <Btn1Up>: button-press() unhighlight-dir() ungrab-dir()\n\
  479.                             <Expose>: refresh-files()"));
  480.  
  481. }
  482.  
  483.  
  484.  
  485.  
  486. /*
  487. **    Function name : FATAL_ERROR
  488. **
  489. **    Description : Bricht im Fehlerfall mit einer Fehlermeldung ab
  490. **    Input : 
  491. **    Ouput :
  492. */
  493. void FATAL_ERROR (char *message)
  494. {
  495.     fprintf(stderr,"%s",message);
  496.     exit(1);
  497. }
  498.  
  499.  
  500.  
  501. /*
  502. **    Function name : refresh_files
  503. **
  504. **    Description : Neuzeichnen des Directories nach einem Expose
  505. **    Input : none
  506. **    Ouput : none
  507. */
  508. XtActionProc refresh_files (Widget w, XEvent *e, String *s, Cardinal *c)
  509. {
  510.     Dimension    lx = 0, ly;
  511.     Arg        args[4];
  512.  
  513.     /*
  514.      * Directorypfad neu Zeichnen
  515.      */
  516.     if (FILE_CHANGED) {
  517.         XClearWindow(XtDisplay(file_area),XtWindow(file_area));
  518.         FILE_CHANGED = FALSE;
  519.     }
  520.     showFolder (file_area, &folder, 20, 6, &lx, &ly);
  521.     folder.max_length = lx + DIR_X_STEP;
  522.  
  523.     /*
  524.      * Die Hoehe anpassen
  525.      */
  526.     XtSetArg(args[0],XtNheight, ly + 2*DIR_Y_STEP);
  527.     XtSetArg(args[1],XtNwidth, lx + 2*DIR_X_STEP);
  528.     XtSetArg(args[2],XtNx, 0);
  529.     XtSetArg(args[3],XtNy, 0);
  530.     XtSetValues(file_area,args,4);
  531. }
  532.  
  533.  
  534.  
  535. /*
  536. **    Function name : refresh_dirs
  537. **
  538. **    Description : Neuzeichnen des Directories nach einem Expose
  539. **    Input : none
  540. **    Ouput : none
  541. */
  542. XtActionProc refresh_dirs (Widget w, XEvent *e, String *s, Cardinal *c)
  543. {
  544.     Dimension    lx = 0, ly;
  545.     Arg        args[2];
  546.  
  547.     /*
  548.      * Directorypfad neu Zeichnen
  549.      */
  550.     if (DIR_CHANGED) {
  551.         DIR_CHANGED = FALSE;
  552.         XClearWindow(XtDisplay(dir_area),XtWindow(dir_area));
  553.     }
  554.     showDir (dir_area, &root, 20, 6, &lx, &ly);
  555.  
  556.     /*
  557.      * Die Hoehe anpassen
  558.      */
  559.     XtSetArg(args[0],XtNheight, ly + 2*DIR_Y_STEP);
  560.     XtSetArg(args[1],XtNwidth, lx + 2*DIR_X_STEP);
  561.     XtSetValues(dir_area,args,2);
  562. }
  563.  
  564.  
  565.  
  566.  
  567. /*
  568. **    Function name : dir_mouse
  569. **
  570. **    Description : Sobald ein Button gedrueckt wurde.
  571. **    Input : 
  572. **    Ouput :
  573. */
  574. XtActionProc dir_mouse (Widget w, XMotionEvent *e, String *s, Cardinal *c)
  575. {
  576.     Dir_Glyph    *dir;
  577.     int        y;
  578.     Arg        args[2];
  579.  
  580.     XtSetArg(args[0],XtNx,0);
  581.     XtSetArg(args[1],XtNy,0);
  582.     XtGetValues(dir_area,args,2);
  583.  
  584.     /*
  585.      * Nachsehen ob eventuell wieder in einem neuen Feld
  586.      */
  587.     if (e->x-args[0].value > vp_width) {
  588.         /*
  589.          * Fenster wird verlassen, also Event an File-Handler weiterreichen
  590.          */
  591.         Arg    largs[2];
  592.         XtSetArg(largs[0],XtNx,0);
  593.         XtSetArg(largs[1],XtNy,0);
  594.         XtGetValues(file_area,largs,2);
  595.  
  596.         e->y -= label_height - (args[1].value - largs[1].value);
  597.         e->x -= vp_width  + (args[0].value - largs[0].value);
  598.         file_mouse (w,e,s,c);
  599.     }
  600.     else {
  601.         if (last_v < 16000) {
  602.             XDrawRectangle(XtDisplay(file_area),XtWindow(file_area),
  603.                        back_gc, 16, last_v*DIR_Y_STEP + 4,
  604.                        folder.max_length, 20);
  605.             last_v = 16000;
  606.         }
  607.         y = (e->y - last_y < 0) ? (last_y - e->y) : (e->y - last_y);
  608.         if (y > DIR_Y_STEP/2) {
  609.             if (last_y > 0 && last_y < 16000) {
  610.                 XDrawRectangle(XtDisplay(dir_area),XtWindow(dir_area),
  611.                            back_gc, last_g->x - 4, last_g->y - 2,
  612.                            30 + 8*strlen(last_g->name), 20);
  613.                 last_y = 0;
  614.                 last_g = NULL;
  615.             }
  616.             dir = getGlyph(&root,e->x,e->y);
  617.             if (dir) {
  618.                 last_g = dir;
  619.                 if (last_g != grab_g && (last_g->flags & DIR_WRITEABLE))
  620.                     XDrawRectangle(XtDisplay(dir_area),XtWindow(dir_area),
  621.                                selc_gc, last_g->x - 4, last_g->y - 2,
  622.                                30 + strlen(last_g->name)*8, 20);
  623.                 last_y = dir->y + 8;
  624.             }
  625.         }
  626.     }
  627. }
  628.  
  629.  
  630.  
  631. /*
  632. **    Function name : dir_unhighlight
  633. **
  634. **    Description : Sobald ein Button gedrueckt wurde.
  635. **    Input : 
  636. **    Ouput :
  637. */
  638. XtActionProc dir_unhighlight (Widget w, XMotionEvent *e, String *s, Cardinal *c)
  639. {
  640.     /*
  641.      * Nachsehen ob noch ein Eintrag gehighlighted ist
  642.      */
  643.     if (last_v < 16000) {
  644.         XDrawRectangle(XtDisplay(file_area),XtWindow(file_area),
  645.                    back_gc, 16, last_v*DIR_Y_STEP + 4,
  646.                    folder.max_length, 20);
  647.         last_v = 16000;
  648.     }
  649.     if (last_y > 0 && last_y < 16000) {
  650.         XDrawRectangle(XtDisplay(dir_area),XtWindow(dir_area),
  651.                    back_gc, last_g->x - 4, last_g->y - 2,
  652.                    30 + 8*strlen(last_g->name), 20);
  653.         last_y = 0;
  654.     }
  655. }
  656.  
  657.  
  658.  
  659. /*
  660. **    Function name : button_press
  661. **
  662. **    Description : Sobald ein Button gedrueckt wurde.
  663. **    Input : 
  664. **    Ouput :
  665. */
  666. XtActionProc button_press (Widget w, XButtonEvent *e, String *s, Cardinal *c)
  667. {
  668.     Arg    args[2],largs[2];
  669.  
  670.     XtSetArg(args[0],XtNx,0);
  671.     XtSetArg(args[1],XtNy,0);
  672.     XtGetValues(dir_area,args,2);
  673.     XtSetArg(largs[0],XtNx,0);
  674.     XtSetArg(largs[1],XtNy,0);
  675.     XtGetValues(file_area,largs,2);
  676.     /*
  677.      * Der Endpunkt der Graboperation lag im Dir-Feld
  678.      */
  679.     if (w == dir_area && e->x - args[0].value > vp_width) {
  680.         e->y -= label_height - (args[1].value - largs[1].value);
  681.         e->x -= vp_width  + (args[0].value - largs[0].value);
  682.         w = file_area;
  683.     }
  684.     else if (w == file_area && e->x - largs[0].value < 0) {
  685.         e->y += label_height + (args[1].value - largs[1].value);
  686.         e->x += vp_width  - (args[0].value - largs[0].value);
  687.         w = dir_area;
  688.     }
  689.     if (w == dir_area) {
  690.         Dir_Glyph    *dir;
  691.  
  692.         /*
  693.          * Zunaechst einmal muss anhand der Koordinaten das entsprechde
  694.          * Dir_Glyph heraus gesucht werden
  695.          */
  696.         dir = last_g;
  697.  
  698.         if (dir) {
  699.             /*
  700.              * Nachsehen ob gerade eine Move-Grab operation ausgefuehrt wird
  701.              */
  702.             if (grab_g && dir != grab_g) {
  703.                 /*
  704.                  * Verschieben des Directories in das gerade selectierte
  705.                  */
  706.                 printf ("mv %s %s\n",getPath(grab_g),getPath(dir));
  707.             }
  708.             else if (grab_f && folder.dir != dir) {
  709.                 /*
  710.                  * Verschieben des Icons vom file_area in die Dir-area
  711.                  */
  712.                 printf("mv %s/%s %s\n",getPath(folder.dir),grab_f->name,
  713.                               getPath(dir));
  714.             }
  715.             else if (!grab_g && !grab_f) {
  716.                 /*
  717.                  * Nachpruefen ob Directory geoeffnet ist
  718.                  */
  719.                 if (dir->open) {
  720.                     if (dir->dir_count > 0)
  721.                         DIR_CHANGED = TRUE;
  722.                     dir->open = FALSE;
  723.                     refresh_dirs(NULL,NULL,NULL,NULL);
  724.                 }
  725.                 else {
  726.                     if (dir->flags & DIR_READABLE) {
  727.                         fillDir(dir);
  728.                         if (dir->dir_count > 0)
  729.                             DIR_CHANGED = TRUE;
  730.                         refresh_dirs(NULL,NULL,NULL,NULL);
  731.                         FILE_CHANGED = TRUE;
  732.                         folder.dir = dir;
  733.                         fillFolder(&folder);
  734.                         refresh_files(NULL,NULL,NULL,NULL);
  735.                     }
  736.                 }
  737.             }
  738.         }
  739.     }
  740.     /*
  741.      * Der Endpunkt der Grabaktion lag im File-Feld
  742.      */
  743.     else if (w == file_area) {
  744.         /*
  745.          * Testen ob zum Schluss noch ein Argument aktiviert war
  746.          */
  747.         if (last_v < 16000) {
  748.             if (grab_f && grab_f != folder.file[last_v]) {
  749.                 printf("mv %s/%s %s/%s\n",getPath(folder.dir),grab_f->name,
  750.                               getPath(folder.dir),folder.file[last_v]->name);
  751.             }
  752.             else if (grab_g) {
  753.                 printf("mv %s %s/%s\n",getPath(grab_g),
  754.                               getPath(folder.dir),folder.file[last_v]->name);
  755.             }
  756.             else if (!grab_f && !grab_g) {
  757.                 File_Glyph    *file = folder.file[last_v];
  758.  
  759.                 if (file->prog_type == FILE_ROOT && folder.dir->parent) {
  760.                     folder.dir = folder.dir->parent;
  761.                     fillFolder(&folder);
  762.                     FILE_CHANGED = TRUE;
  763.                     refresh_files(NULL,NULL,NULL,NULL);
  764.                 }
  765.                 else if (file->prog_type == FILE_DIR) {
  766.                     int    i = 0, j = -1;
  767.  
  768.                     while (i < folder.dir->dir_count) {
  769.                         if (!(strcmp(folder.dir->dir[i]->name,file->name))) {
  770.                             j = i;
  771.                             i = folder.dir->dir_count;
  772.                         }
  773.                         i++;
  774.                     }
  775.                     if (j > -1) {
  776.                         folder.dir = folder.dir->dir[j];
  777.                         if (!folder.dir->open && folder.dir->dir_count == 0) {
  778.                             fillDir (folder.dir);
  779.                             folder.dir->open = FALSE;
  780.                         }
  781.                         fillFolder (&folder);
  782.                         FILE_CHANGED = TRUE;
  783.                         refresh_files(NULL,NULL,NULL,NULL);
  784.                     }
  785.                 }
  786.                 else if (file->prog_type != FILE_PLAIN) {
  787.                     int    i = 0;
  788.  
  789.                     while (commands[i].cmd && commands[i].type != file->prog_type)
  790.                         i++;
  791.  
  792.                     if (commands[i].type == file->prog_type) {
  793.                         char    buf[200];
  794.  
  795.                         sprintf(buf,"%s %s/%s &\0",commands[i].cmd,
  796.                                 getPath(folder.dir),file->name);
  797.                         system(buf);
  798.                     }
  799.                 }
  800.             }
  801.         }
  802.     }
  803. }
  804.  
  805.  
  806.  
  807.  
  808.  
  809. /*
  810. **    Function name : getGlyph
  811. **
  812. **    Description : Prueft, ob an den Koordinaten x,y ein Glyph liegt
  813. **    Input : Dir_Glyph Root; Position x,y
  814. **    Ouput :
  815. */
  816. Dir_Glyph *getGlyph (Dir_Glyph *d, Dimension x, Dimension y)
  817. {
  818.     /*
  819.      * Pruefen ob Punkt ueberhaupt im Bereich liegen kann
  820.      */
  821.     if (y < d->y || x < d->x)
  822.         return(NULL);
  823.  
  824.     /*
  825.      * Pruefen ob das Icon das an dieser Position liegt
  826.      */
  827.     if ( y < d->y + 16 && x < d->x + 24 + 8*strlen(d->name))
  828.         return(d);
  829.  
  830.     /*
  831.      * Das Stammglyph war es nicht, also Verzeichnis durchsuchen
  832.      */
  833.     if (d->dir_count > 0 && d->open) {
  834.         int    i;
  835.  
  836.         /*
  837.          * alle Glyphs durchprobieren
  838.          */
  839.         for (i = 0; i < d->dir_count; i++) {
  840.             Dir_Glyph    *b;
  841.  
  842.             b = getGlyph(d->dir[i],x,y);
  843.             if (b != NULL)
  844.                 return(b);
  845.         }
  846.     }
  847.     return(NULL);
  848. }
  849.  
  850.  
  851.  
  852. /*
  853. **    Function name : DEBUG
  854. **
  855. **    Description : Gibt eine Debugmessage aus
  856. **    Input : char *message - Nachricht die ausgegeben werden soll
  857. **    Ouput :
  858. */
  859. void DEBUG (char *message)
  860. {
  861.     printf("DEBUG: %s\n",message);
  862. }
  863.  
  864.  
  865.  
  866. /*
  867. **    Function name : file_mouse
  868. **
  869. **    Description : Berechnet anhand der Mausposition, ob ein File angewaehlt wurde
  870. **              oder nicht.
  871. **    Input : nicht beachtet
  872. **    Ouput : unwichtig
  873. */
  874. XtActionProc file_mouse (Widget w, XMotionEvent *e, String *s, Cardinal *c)
  875. {
  876.     int        y;
  877.     Arg        largs[2];
  878.  
  879.     XtSetArg(largs[0],XtNx,0);
  880.     XtSetArg(largs[1],XtNy,0);
  881.     XtGetValues(file_area,largs,2);
  882.  
  883.     /*
  884.      * Nachsehen ob eventuell wieder in einem neuen Feld
  885.      */
  886.     if (e->x - largs[0].value < 0) {
  887.         /*
  888.          * Es wird das Feld gewechselt, also Event an dir-handling-Routine
  889.          * weiterreichen
  890.          */
  891.         Arg    args[2];
  892.  
  893.         XtSetArg(args[0],XtNx,0);
  894.         XtSetArg(args[1],XtNy,0);
  895.         XtGetValues(dir_area,args,2);
  896.  
  897.         e->y += label_height - (args[1].value - largs[1].value);
  898.         e->x += vp_width  + (args[0].value - largs[0].value);
  899.         dir_mouse(w,e,s,c);
  900.     }
  901.     else {
  902.         y = (e->y - 4)/DIR_Y_STEP;
  903.         if (last_y > 0 && last_y < 16000) {
  904.             XDrawRectangle(XtDisplay(dir_area),XtWindow(dir_area),
  905.                        back_gc, last_g->x - 4, last_g->y - 2,
  906.                        30 + 8*strlen(last_g->name), 20);
  907.             last_y = 0;
  908.             last_g = NULL;
  909.         }
  910.         if (y != last_v) {
  911.             if (last_v < 16000) {
  912.                 XDrawRectangle(XtDisplay(file_area),XtWindow(file_area),
  913.                            back_gc, 16, last_v*DIR_Y_STEP + 4,
  914.                            folder.max_length, 20);
  915.                 last_v = 16000;
  916.             }
  917.             if (y < folder.file_count) {
  918.                 last_v = y;
  919.                 if (folder.file[last_v] != grab_f)
  920.                     XDrawRectangle(XtDisplay(file_area),XtWindow(file_area),
  921.                                selc_gc, 16, last_v*DIR_Y_STEP + 4,
  922.                                folder.max_length, 20);
  923.             }
  924.         }
  925.     }
  926. }
  927.  
  928.  
  929.  
  930.  
  931. /*
  932. **    Function name : dir_grab
  933. **
  934. **    Description : Falls moeglich wird das Glyph in den Grab_buffer gepackt
  935. **    Input : Widget w - gibt an ob dir_area oder file_area, Rest unwichtig
  936. **    Ouput : nichts
  937. */
  938. XtActionProc dir_grab (Widget w, XMotionEvent *e, String *s, Cardinal *c)
  939. {
  940.     if (!grab_g && !grab_f) {
  941.         Pixmap    pmap, mask;
  942.         XColor    fg,bg;
  943.         Cursor    cursor;
  944.         GC    gc;
  945.  
  946.         /*
  947.          * Selected Widget setzen
  948.          */
  949.         Arg    args[1],largs[1];
  950.  
  951.         XtSetArg(args[0],XtNwidth,0);
  952.         XtGetValues(dir_vp,args,1);
  953.         XtSetArg(largs[0],XtNheight,0);
  954.         XtGetValues(file_label,largs,1);
  955.  
  956.         label_height = largs[0].value;
  957.         vp_width = args[0].value;
  958.  
  959.         if (w == dir_area && last_g) {
  960.             if (last_g->flags & DIR_WRITEABLE) {
  961.                 grab_g = last_g;
  962.  
  963.                 /*
  964.                  * Cursor setzen
  965.                  */
  966.                 XDefineCursor(XtDisplay(dir_area),XtWindow(dir_area),file_cursor);
  967.                 XDefineCursor(XtDisplay(file_area),XtWindow(file_area),file_cursor);
  968.             }
  969.         }
  970.         else if (w == file_area && last_v < 16000 && 
  971.              folder.file[last_v]->prog_type != FILE_ROOT){
  972.             grab_f = folder.file[last_v];
  973.  
  974.             /*
  975.              * Cursor setzen
  976.              */
  977.             XDefineCursor(XtDisplay(dir_area),XtWindow(dir_area),file_cursor);
  978.             XDefineCursor(XtDisplay(file_area),XtWindow(file_area),file_cursor);
  979.         }
  980.     }
  981. }
  982.  
  983.  
  984. /*
  985. **    Function name : dir_ungrab
  986. **
  987. **    Description : Loescht den Grabbuffer und resetet den Cursor
  988. **    Input : unwichtig das ActionProc
  989. **    Ouput : nichts
  990. */
  991. XtActionProc dir_ungrab (Widget w, XMotionEvent *e, String *s, Cardinal *c)
  992. {
  993.     if (grab_g || grab_f) {
  994.         /*
  995.          * Selected Glyph = NULL
  996.          */
  997.         grab_g = NULL;
  998.         grab_f = NULL;
  999.         /*
  1000.          * Cursor ruecksetzen
  1001.          */
  1002.         XDefineCursor(XtDisplay(dir_area),XtWindow(dir_area), def_cursor);
  1003.         XDefineCursor(XtDisplay(file_area),XtWindow(file_area), def_cursor);
  1004.     }
  1005. }
  1006.  
  1007.  
  1008. /*********************************************************
  1009.  * name:    makeCursor
  1010.  * description:    Erzeugt einen Cursor aus einem Icon und einem Text
  1011.  * input:    Pixmap    icon
  1012.  *        char    *label
  1013.  * output:    Zeiger auf den Cursor
  1014.  * date:    Main 93
  1015.  *********************************************************/
  1016. void    makeCursor ()
  1017. {
  1018.     Pixmap    pmap;
  1019.     Pixmap    smap;
  1020.     XColor    fg,bg;
  1021.  
  1022.     /*
  1023.      * Die Pixmap erzeugen
  1024.      */
  1025.     fg.red = fg.blue = fg.green = 0;
  1026.     bg.red = bg.blue = bg.green = 0xffff;
  1027.     pmap = XCreatePixmapFromBitmapData(XtDisplay(toplevel), XtWindow(toplevel), cursor_bits,
  1028.                        cursor_width,cursor_height, 1,0, 1);
  1029.     smap = XCreatePixmapFromBitmapData(XtDisplay(toplevel), XtWindow(toplevel), cursorm_bits,
  1030.                        cursorm_width,cursorm_height, 1,0, 1);
  1031.  
  1032.     def_cursor = XCreatePixmapCursor(XtDisplay(toplevel),pmap,smap,&fg,&bg,
  1033.                      cursor_x_hot,cursor_y_hot);
  1034.  
  1035.     pmap = XCreatePixmapFromBitmapData(XtDisplay(toplevel), XtWindow(toplevel), fcursor_bits,
  1036.                        fcursor_width,fcursor_height, 1,0, 1);
  1037.     smap = XCreatePixmapFromBitmapData(XtDisplay(toplevel), XtWindow(toplevel), fcursorm_bits,
  1038.                        fcursorm_width,fcursorm_height, 1,0, 1);
  1039.  
  1040.     file_cursor = XCreatePixmapCursor(XtDisplay(toplevel),pmap,smap,&fg,&bg,
  1041.                       fcursor_x_hot,fcursor_y_hot);
  1042. }
  1043.  
  1044.  
  1045. /*
  1046. **    Function name : mark_object
  1047. **
  1048. **    Description : markieren des gerade angewaehlten Icons und achten auf Doppelklicks
  1049. **    Input : none
  1050. **    Ouput : none
  1051. */
  1052. XtActionProc mark_object (Widget w, XButtonEvent *e, String *s, Cardinal *c)
  1053. {
  1054. #define    ABSDIFF(a,b)    (a - b < 0 ? b - a : a - b)
  1055. #define    MAX_INTERVAL    300
  1056.  
  1057.     if (w == file_area && last_v < 16000) {
  1058.         if (selc_f != last_v) {
  1059.             selc_t = e->time;
  1060.             if (selc_g) {
  1061.                 /*
  1062.                  * Demarkieren
  1063.                  */
  1064.                 selc_g = NULL;
  1065.             }
  1066.             else if (selc_f < 16000) {
  1067.                 /*
  1068.                  * demarkieren
  1069.                  */
  1070.             }
  1071.             selc_f = last_v;
  1072.             /*
  1073.              * Markieren
  1074.              */
  1075.         }
  1076.         else if (ABSDIFF(selc_t,e->time) < MAX_INTERVAL) {    /* Innerhalb der Doppelklickid */
  1077.             selc_t = e->time;
  1078.         }
  1079.     }
  1080.     else if (w == dir_area && last_g) {
  1081.         if (last_g != selc_g) {
  1082.             selc_t = e->time;
  1083.             if (selc_f) {
  1084.                 /*
  1085.                  * Demarkieren
  1086.                  */
  1087.                 selc_f = 16000;
  1088.             }
  1089.             if (selc_g) {
  1090.                 /*
  1091.                  * demarkieren
  1092.                  */
  1093.             }
  1094.             selc_g = last_g;
  1095.             /*
  1096.              * Markieren
  1097.              */
  1098.         }
  1099.         else if (ABSDIFF(selc_t,e->time) < MAX_INTERVAL) {    /* Innerhalb der Doppelklickid */
  1100.             selc_t = e->time;
  1101.         }
  1102.     }
  1103. }
  1104.  
  1105.  
  1106.  
  1107.