home *** CD-ROM | disk | FTP | other *** search
/ PC-Online 1996 May / PCOnline_05_1996.bin / linux / source / xap / xfm / xfm-1.000 / xfm-1 / xfm-1.3.2 / src / FmAw.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-13  |  16.5 KB  |  587 lines

  1. /*-----------------------------------------------------------------------------
  2.   FmAw.c
  3.   
  4.   (c) Simon Marlow 1990-1993
  5.   (c) Albert Graef 1994
  6.  
  7.   Functions & data for creating & maintaining  the application window
  8. -----------------------------------------------------------------------------*/
  9.  
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <memory.h>
  13. #include <time.h>
  14.  
  15. #include <X11/Intrinsic.h>
  16. #include <X11/Shell.h>
  17. #include <X11/StringDefs.h>
  18. #include <X11/Xaw/Form.h>
  19. #include <X11/Xaw/Box.h>
  20. #include <X11/Xaw/Viewport.h>
  21. #include <X11/Xaw/Toggle.h>
  22. #include <X11/Xaw/Label.h>
  23.  
  24. #include "Am.h"
  25.  
  26. #define APPWIDTH 300
  27.  
  28. /*-----------------------------------------------------------------------------
  29.   PUBLIC DATA 
  30. -----------------------------------------------------------------------------*/
  31. AppWindowRec aw;
  32. Widget *aw_button_items,
  33. app_popup_widget, *app_popup_items, app_popup_widget1;
  34. int n_appst = 0;
  35. char **appst = NULL;
  36.  
  37. /*-----------------------------------------------------------------------------
  38.   STATIC DATA 
  39. -----------------------------------------------------------------------------*/
  40.  
  41. static MenuItemRec app_popup_menu[] = {
  42.   { "install app", "Install...", appInstallAppCb },
  43.   { "install group", "Install group...", appInstallGroupCb },
  44.   { "line1", NULL, NULL },
  45.   { "cut", "Cut", appCutCb },
  46.   { "copy", "Copy", appCopyCb },
  47.   { "paste", "Paste", appPasteCb },
  48.   { "line2", NULL, NULL },
  49.   { "delete", "Delete", appRemoveCb },
  50.   { "line3", NULL, NULL },
  51.   { "select all", "Select all", appSelectAllCb },
  52.   { "deselect all", "Deselect all", appDeselectCb },
  53.   { "line4", NULL, NULL },
  54.   { "quit", "Quit", appCloseCb },
  55. };
  56.  
  57. static MenuItemRec app_popup_menu1[] = {
  58.   { "edit", "Edit...", appEditCb },
  59.   { "line1", NULL, NULL },
  60.   { "cut", "Cut", appCutCb },
  61.   { "copy", "Copy", appCopyCb },
  62.   { "line2", NULL, NULL },
  63.   { "delete", "Delete", appRemoveCb },
  64. };
  65.  
  66. /*-----------------------------------------------------------------------------
  67.   Widget Argument lists
  68. -----------------------------------------------------------------------------*/
  69.  
  70. static Arg form_args[] = {
  71.   { XtNdefaultDistance, 0 }
  72. };
  73.  
  74. static Arg viewport_args[] = {
  75.   { XtNfromVert, (XtArgVal) NULL },
  76.   { XtNwidth, APPWIDTH },
  77.   { XtNtop, XtChainTop },
  78.   { XtNbottom, XtChainBottom },
  79.   { XtNleft, XtChainLeft },
  80.   { XtNright, XtChainRight },
  81.   { XtNallowVert, (XtArgVal) True },
  82. };
  83.  
  84. static Arg button_box_args[] = {
  85.   { XtNfromVert, (XtArgVal) NULL },
  86.   { XtNtop, XtChainBottom },
  87.   { XtNbottom, XtChainBottom },
  88.   { XtNleft, XtChainLeft },
  89.   { XtNright, XtChainLeft },
  90. };
  91.  
  92. static Arg icon_box_args[] = {
  93.   { XtNwidth, 0 },
  94.   { XtNtranslations, (XtArgVal) NULL }
  95. };
  96.  
  97. static Arg icon_form_args[] = {
  98.   { XtNdefaultDistance, 0 },
  99.   { XtNwidth, 0 }
  100. };
  101.  
  102. static Arg icon_toggle_args[] = {
  103.   { XtNfromHoriz, (XtArgVal) NULL },
  104.   { XtNfromVert, (XtArgVal) NULL },
  105.   { XtNbitmap, (XtArgVal) NULL },
  106.   { XtNtranslations, (XtArgVal) NULL },
  107.   { XtNwidth, 0 },
  108.   { XtNheight, 0 }
  109. };
  110.  
  111. static Arg icon_label_args[] = {
  112.   { XtNfromHoriz, (XtArgVal) NULL },
  113.   { XtNfromVert, (XtArgVal) NULL },
  114.   { XtNlabel, (XtArgVal) NULL },
  115.   { XtNfont, (XtArgVal) NULL },
  116.   { XtNwidth, 0 },
  117.   { XtNinternalWidth, 0 },
  118.   { XtNinternalHeight, 0 }
  119. };
  120.  
  121. /*-----------------------------------------------------------------------------
  122.   Translation tables
  123. -----------------------------------------------------------------------------*/
  124.  
  125. static char app_translations[] = "\
  126.     <Enter>             : appMaybeHighlight()\n\
  127.     <Leave>             : unhighlight()\n\
  128.     <Btn1Up>(2)         : runApp()\n\
  129.     <Btn1Down>,<Btn1Up> : appSelect()\n\
  130.     <Btn1Down>,<Leave>  : appBeginDrag(1,move)\n\
  131.     <Btn2Down>,<Btn2Up> : appToggle()\n\
  132.     <Btn2Down>,<Leave>  : appBeginDrag(2,copy)\n";
  133.  
  134. static char iconbox_translations[] = "\
  135.     <Btn2Up>            : dummy()\n\
  136.     <Btn3Up>            : dummy()\n\
  137.     <Btn3Down>          : appPopup()\n";
  138.  
  139. /*-----------------------------------------------------------------------------
  140.   Action tables
  141. -----------------------------------------------------------------------------*/
  142.  
  143. static void dummy(Widget w, XEvent *event, String *params, 
  144.                Cardinal *num_params) {}
  145.  
  146. static XtActionsRec app_actions[] = {
  147.   { "appMaybeHighlight", appMaybeHighlight },
  148.   { "runApp", runApp },
  149.   { "appSelect", appSelect },
  150.   { "appToggle", appToggle },
  151.   { "appPopup", appPopup },
  152.   { "appBeginDrag", appBeginDrag },
  153.   { "dummy", dummy }
  154. };
  155.  
  156. /*-----------------------------------------------------------------------------
  157.   Button Data
  158. -----------------------------------------------------------------------------*/
  159.  
  160. static ButtonRec aw_buttons[] = {
  161.   { "back", "Back", (FmCallbackProc *) appBackCb },
  162.   { "main", "Main", (FmCallbackProc *) appMainCb },
  163.   { "reload", "Reload", (FmCallbackProc *) appLoadCb },
  164.   { "open", "File window", appOpenCb },
  165. };
  166.  
  167.  
  168. /*-----------------------------------------------------------------------------
  169.   PRIVATE FUNCTIONS
  170. -----------------------------------------------------------------------------*/
  171.  
  172. static int longestName()
  173. {
  174.   int i, l, longest = 0;
  175.  
  176.   for (i=0; i<aw.n_apps; i++)
  177.     if ((l = XTextWidth(resources.icon_font, aw.apps[i].name, 
  178.             strlen(aw.apps[i].name))) > longest)
  179.       longest = l;
  180.   return longest;
  181. }
  182.  
  183. /*-----------------------------------------------------------------------------
  184.   PUBLIC FUNCTIONS
  185. -----------------------------------------------------------------------------*/
  186.  
  187. int parseApp(FILE *fp, char **name, char **directory, char **fname,
  188.          char **icon, char **push_action, char **drop_action)
  189. {
  190.   static char s[MAXAPPSTRINGLEN];
  191.   int l;
  192.  
  193.  start:
  194.   if (feof(fp)||!fgets(s, MAXAPPSTRINGLEN, fp))
  195.     return 0;
  196.   l = strlen(s);
  197.   if (s[l-1] == '\n')
  198.     s[--l] = '\0';
  199.   if (!l || *s == '#')
  200.     goto start;
  201.   if (!(*name = split(s, ':')))
  202.     return -1;
  203.   if (!(*directory = split(NULL, ':')))
  204.     return -1;
  205.   if (!(*fname = split(NULL, ':')))
  206.     return -1;
  207.   if (!(*icon = split(NULL, ':')))
  208.     return -1;
  209.   if (!(*push_action = split(NULL, ':')))
  210.     return -1;
  211.   if (!(*drop_action = split(NULL, ':')))
  212.     return -1;
  213.   return l;
  214. }
  215.  
  216. /*---------------------------------------------------------------------------*/
  217.  
  218. /* determine the default icon of an application */
  219.  
  220. Pixmap defaultIcon(char *name, char *directory, char *fname)
  221. {
  222.   if (!*fname)
  223.     return bm[EXEC_BM];
  224.   else {
  225.     struct stat stats;
  226.     Boolean sym_link;
  227.     int l = *directory?strlen(directory):strlen(user.home);
  228.     char *path = (char *)alloca(2+strlen(fname)+l);
  229.     
  230.     strcpy(path, *directory?directory:user.home);
  231.  
  232.     if (l) {
  233.       if (path[l-1] != '/')
  234.     path[l++] = '/';
  235.       strcpy(path+l, fname);
  236.     } else
  237.       strcpy(path, fname);
  238.  
  239.     if (lstat(path, &stats))
  240.       return bm[FILE_BM];
  241.     else if (S_ISLNK(stats.st_mode)) {
  242.       sym_link = True;
  243.       stat(path, &stats);
  244.     } else
  245.       sym_link = False;
  246.  
  247.     if (S_ISLNK(stats.st_mode))
  248.       return bm[BLACKHOLE_BM];
  249.     else if (S_ISDIR(stats.st_mode))
  250.       if (sym_link)
  251.     return bm[DIRLNK_BM];
  252.       else if (!strcmp(name, ".."))
  253.     return bm[UPDIR_BM];
  254.       else
  255.     return bm[DIR_BM];
  256.     else if (stats.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))
  257.       if (sym_link)
  258.     return bm[EXECLNK_BM];
  259.       else
  260.     return bm[EXEC_BM];
  261.     else if (sym_link)
  262.       return bm[SYMLNK_BM];
  263.     else
  264.       return bm[FILE_BM];
  265.   }
  266. }
  267.  
  268. /*-------------------------------------------------------------------------*/
  269.  
  270. void createApplicationWindow()
  271. {
  272.   XtTranslations t;
  273.  
  274.   /* Add new actions and parse the translation tables */
  275.   XtAppAddActions(app_context, app_actions, XtNumber(app_actions));
  276.  
  277.   t = XtParseTranslationTable(app_translations);
  278.   icon_toggle_args[3].value = (XtArgVal) t;
  279.  
  280.   t = XtParseTranslationTable(iconbox_translations);
  281.   icon_box_args[1].value = (XtArgVal) t;
  282.  
  283.   icon_label_args[3].value = (XtArgVal) resources.icon_font;
  284.  
  285.   /* create the install popups */
  286.   createInstallPopups();
  287.  
  288.   /* create the menus */
  289.   app_popup_items = createFloatingMenu("app popup", 
  290.                        app_popup_menu,
  291.                        XtNumber(app_popup_menu),
  292.                        4, aw.shell,
  293.                        NULL, &app_popup_widget);
  294.   createFloatingMenu("app popup 1", app_popup_menu1,
  295.              XtNumber(app_popup_menu1), 4, aw.shell,
  296.              NULL, &app_popup_widget1);
  297.  
  298.   XtRegisterGrabAction(appPopup, True, ButtonPressMask | ButtonReleaseMask,
  299.                GrabModeAsync, GrabModeAsync);
  300.  
  301.   /* create the form */
  302.   aw.form = XtCreateManagedWidget("form", formWidgetClass, aw.shell,
  303.                   form_args, XtNumber(form_args) );
  304.   
  305.   /* create the viewport */
  306.   aw.viewport = XtCreateManagedWidget("viewport", viewportWidgetClass,
  307.     aw.form, viewport_args, XtNumber(viewport_args) );
  308.  
  309.   /* create button box */
  310.   button_box_args[0].value = (XtArgVal) aw.viewport;
  311.   aw.button_box = XtCreateManagedWidget("button box", boxWidgetClass,
  312.                     aw.form, button_box_args, 
  313.                     XtNumber(button_box_args) );
  314.   aw_button_items = createButtons(aw_buttons, XtNumber(aw_buttons),
  315.                   aw.button_box, NULL);
  316.  
  317.   aw.n_selections = 0;
  318. }
  319.  
  320. /*---------------------------------------------------------------------------*/
  321.  
  322. void createApplicationDisplay()
  323. {
  324.   int i;
  325.   Dimension width;
  326.  
  327.   for (i=0; i<aw.n_apps; i++)
  328.     aw.apps[i].selected = False;
  329.   aw.n_selections = 0;
  330.   
  331.   XtVaGetValues(aw.viewport, XtNwidth, &width, NULL);
  332.   icon_box_args[0].value = (XtArgVal) width;
  333.  
  334.   aw.icon_box = XtCreateWidget("icon box", boxWidgetClass,
  335.     aw.viewport, icon_box_args, XtNumber(icon_box_args) );
  336.  
  337.   if (aw.n_apps == 0)
  338.     XtVaCreateManagedWidget("label", labelWidgetClass, aw.icon_box,
  339.                 XtNlabel, "No configured applications",
  340.                 XtNfont, resources.label_font, NULL);
  341.   else {
  342.     width = longestName();
  343.     if (width < resources.app_icon_width)
  344.       width = resources.app_icon_width;
  345.     icon_form_args[1].value = (XtArgVal) width;
  346.     icon_label_args[4].value = (XtArgVal) width;
  347.     icon_toggle_args[4].value = (XtArgVal) width;
  348.     icon_toggle_args[5].value = (XtArgVal) resources.app_icon_height;
  349.     
  350.     for (i=0; i < aw.n_apps; i++) {
  351.       Pixel back;
  352.       aw.apps[i].form = XtCreateManagedWidget(aw.apps[i].name,
  353.                           formWidgetClass, aw.icon_box,
  354.                           icon_form_args,
  355.                           XtNumber(icon_form_args) );
  356.       icon_toggle_args[2].value = aw.apps[i].icon_bm;
  357.       aw.apps[i].toggle = XtCreateManagedWidget("icon", toggleWidgetClass,
  358.                         aw.apps[i].form,
  359.                         icon_toggle_args,
  360.                         XtNumber(icon_toggle_args) );
  361.       XtVaGetValues(aw.apps[i].toggle, XtNbackground, &back, NULL);
  362.       XtVaSetValues(aw.apps[i].toggle, XtNborder, (XtArgVal) back, NULL);
  363.  
  364.       icon_label_args[1].value = (XtArgVal) aw.apps[i].toggle;
  365.       icon_label_args[2].value = (XtArgVal) aw.apps[i].name;
  366.       aw.apps[i].label = XtCreateManagedWidget("label", labelWidgetClass,
  367.                            aw.apps[i].form,
  368.                            icon_label_args,
  369.                            XtNumber(icon_label_args) );
  370.     };
  371.   }
  372.  
  373.   if (n_appst > 0)
  374.     fillIn(aw_button_items[0]);
  375.   else
  376.     grayOut(aw_button_items[0]);
  377.   XtManageChild(aw.icon_box);
  378. }
  379.  
  380. /*---------------------------------------------------------------------------*/
  381.  
  382. void updateApplicationDisplay()
  383. {
  384.   XtDestroyWidget(aw.icon_box);
  385.   createApplicationDisplay();
  386. }
  387.  
  388. /*---------------------------------------------------------------------------*/
  389.  
  390. void readApplicationBitmaps()
  391. {
  392.   int i;
  393.  
  394.   for (i=0; i<aw.n_apps; i++) {
  395.     aw.apps[i].loaded = False;
  396.     if (!aw.apps[i].icon[0])
  397.       aw.apps[i].icon_bm = defaultIcon(aw.apps[i].name, aw.apps[i].directory,
  398.                        aw.apps[i].fname);
  399.     else if ((aw.apps[i].icon_bm = readIcon(aw.apps[i].icon)) == None) {
  400.       fprintf(stderr, "%s: can't read icon for application %s\n",
  401.           progname, aw.apps[i].name);
  402.       aw.apps[i].icon_bm = defaultIcon(aw.apps[i].name, aw.apps[i].directory,
  403.                        aw.apps[i].fname);
  404.     } else
  405.       aw.apps[i].loaded = True;
  406.   }
  407. }
  408.  
  409. /*---------------------------------------------------------------------------*/
  410.  
  411. void readApplicationData(String path)
  412. {
  413.   FILE *fp;
  414.   char *name, *directory, *fname, *icon, *push_action, *drop_action;
  415.   char s[MAXAPPSTRINGLEN];
  416.   int i, p;
  417.   
  418.   aw.n_apps = 0;
  419.   aw.apps = NULL;
  420.   
  421.   if (!(fp = fopen(path, "r"))) return;
  422.  
  423.   for (i=0; (p = parseApp(fp, &name, &directory, &fname, &icon, &push_action,
  424.               &drop_action)) > 0; i++) {
  425.     aw.apps = (AppList) XTREALLOC(aw.apps, (i+1)*sizeof(AppRec) );
  426.     aw.apps[i].name = XtNewString(strparse(s, name, "\\:"));
  427.     aw.apps[i].directory = XtNewString(strparse(s, directory, "\\:"));
  428.     aw.apps[i].fname = XtNewString(strparse(s, fname, "\\:"));
  429.     aw.apps[i].icon = XtNewString(strparse(s, icon, "\\:"));
  430.     aw.apps[i].push_action = XtNewString(strparse(s, push_action, "\\:"));
  431.     aw.apps[i].drop_action = XtNewString(strparse(s, drop_action, "\\:"));
  432.   }
  433.  
  434.   if (p == -1)
  435.     error("Error in applications file", "");
  436.  
  437.   aw.n_apps = i;
  438.   
  439.   if (fclose(fp))
  440.     sysError("Error reading applications file:");
  441.  
  442.   readApplicationBitmaps();
  443. }
  444.  
  445. /*---------------------------------------------------------------------------*/
  446.  
  447. int writeApplicationData(String path)
  448. {
  449.   FILE *fp;
  450.   int i;
  451.   char name[2*MAXAPPSTRINGLEN], directory[2*MAXAPPSTRINGLEN],
  452.     fname[2*MAXAPPSTRINGLEN], icon[2*MAXAPPSTRINGLEN],
  453.     push_action[2*MAXAPPSTRINGLEN], drop_action[2*MAXAPPSTRINGLEN];
  454.   
  455.   if (! (fp = fopen(path, "w") )) {
  456.     sysError("Error writing applications file:");
  457.     return -1;
  458.   }
  459.  
  460.   fprintf(fp, "#XFM\n");
  461.  
  462.   for (i=0; i < aw.n_apps; i++) {
  463.     expand(name, aw.apps[i].name, "\\:");
  464.     expand(directory, aw.apps[i].directory, "\\:");
  465.     expand(fname, aw.apps[i].fname, "\\:");
  466.     expand(icon, aw.apps[i].icon, "\\:");
  467.     expand(push_action, aw.apps[i].push_action, "\\:");
  468.     expand(drop_action, aw.apps[i].drop_action, "\\:");
  469.     fprintf(fp, "%s:%s:%s:%s:%s:%s\n", name, directory, fname, icon,
  470.         push_action, drop_action);
  471.   }
  472.   
  473.   if (fclose(fp)) {
  474.     sysError("Error writing applications file:");
  475.     return -1;
  476.   }
  477.  
  478.   return 0;
  479. }
  480.  
  481. /*---------------------------------------------------------------------------*/
  482.  
  483. void freeApplicationResources(AppRec *app)
  484. {
  485.   if (app->loaded)
  486.     XFreePixmap(XtDisplay(aw.shell), app->icon_bm);
  487.   XTFREE(app->name);
  488.   XTFREE(app->directory);
  489.   XTFREE(app->fname);
  490.   XTFREE(app->icon);
  491.   XTFREE(app->push_action);
  492.   XTFREE(app->drop_action);
  493. }
  494.  
  495. /*---------------------------------------------------------------------------*/
  496.  
  497. void installApplication(char *name, char *directory, char *fname, char *icon,
  498.             char *push_action, char *drop_action)
  499. {
  500.   int i;
  501.   Pixmap icon_bm;
  502.   Boolean loaded = False;
  503.  
  504.   if (!*icon)
  505.     icon_bm = defaultIcon(name, directory, fname);
  506.   else if ((icon_bm = readIcon(icon)) == None) {
  507.     error("Can't read icon for", name);
  508.     icon_bm = defaultIcon(name, directory, fname);
  509.   } else
  510.     loaded = True;
  511.  
  512.   i = aw.n_apps++;
  513.   aw.apps = (AppList) XTREALLOC(aw.apps, aw.n_apps * sizeof(AppRec));
  514.  
  515.   aw.apps[i].name = XtNewString(name);
  516.   aw.apps[i].directory = XtNewString(directory);
  517.   aw.apps[i].fname = XtNewString(fname);
  518.   aw.apps[i].icon = XtNewString(icon);
  519.   aw.apps[i].push_action = XtNewString(push_action);
  520.   aw.apps[i].drop_action = XtNewString(drop_action);
  521.   aw.apps[i].icon_bm = icon_bm;
  522.   aw.apps[i].loaded = loaded;
  523.   aw.apps[i].form = aw.apps[i].toggle = aw.apps[i].label = NULL;
  524. }
  525.  
  526. /*---------------------------------------------------------------------------*/
  527.  
  528. void replaceApplication(AppRec *app, char *name, char *directory, char *fname,
  529.             char *icon, char *push_action, char *drop_action)
  530. {
  531.   Pixmap icon_bm;
  532.   Boolean loaded = False;
  533.  
  534.   if (!*icon)
  535.     icon_bm = defaultIcon(name, directory, fname);
  536.   else if ((icon_bm = readIcon(icon)) == None) {
  537.     error("Can't read icon for", name);
  538.     icon_bm = defaultIcon(name, directory, fname);
  539.   } else
  540.     loaded = True;
  541.  
  542.   freeApplicationResources(app);
  543.  
  544.   app->name = XtNewString(name);
  545.   app->directory = XtNewString(directory);
  546.   app->fname = XtNewString(fname);
  547.   app->icon = XtNewString(icon);
  548.   app->push_action = XtNewString(push_action);
  549.   app->drop_action = XtNewString(drop_action);
  550.   app->icon_bm = icon_bm;
  551.   app->loaded = loaded;
  552.   app->form = app->toggle = app->label = NULL;
  553. }
  554.  
  555. /*---------------------------------------------------------------------------*/
  556.  
  557. void pushApplicationsFile()
  558. {
  559.   int i = n_appst++;
  560.  
  561.   appst = (char **) XTREALLOC(appst, n_appst * sizeof(char *));
  562.   appst[i] = XtNewString(resources.app_file);
  563. }
  564.  
  565. /*---------------------------------------------------------------------------*/
  566.  
  567. void popApplicationsFile()
  568. {
  569.   if (n_appst <= 0) return;
  570.   strcpy(resources.app_file, appst[--n_appst]);
  571.   XTFREE(appst[n_appst]);
  572.   appst = (char **) XTREALLOC(appst, n_appst * sizeof(char *));
  573. }
  574.  
  575. /*---------------------------------------------------------------------------*/
  576.  
  577. void clearApplicationsStack()
  578. {
  579.   int i;
  580.   for (i = 0; i < n_appst; i++)
  581.     XTFREE(appst[i]);
  582.   XTFREE(appst);
  583.   appst = NULL;
  584.   n_appst = 0;
  585. }
  586.  
  587.