home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / vile-src.zip / vile-8.1 / menu.c < prev    next >
C/C++ Source or Header  |  1998-09-29  |  22KB  |  737 lines

  1. /************************************************************************/
  2. /*  File        : menu.c                                                */
  3. /*  Description : Implement a Motif MenuBar into Mxvile                 */
  4. /*                Parse a File (environment variable XVILE_MENU)        */
  5. /*                and create it at the top of the window                */
  6. /*  Auteur      : Philippe CHASSANY                                     */
  7. /*  Date        : 20/02/97                                              */
  8. /************************************************************************/
  9.  
  10. /*
  11.  * $Header: /usr/build/vile/vile/RCS/menu.c,v 1.24 1998/09/29 23:53:17 tom Exp $
  12.  */
  13.  
  14. #define NEED_X_INCLUDES 1
  15.  
  16. /* Vile includes */
  17. #include "estruct.h"
  18. #include "edef.h"
  19.  
  20. #if DISP_X11
  21.  
  22. #if MOTIF_WIDGETS
  23. #include <Xm/MainW.h>
  24. #include <Xm/CascadeB.h>
  25. #include <Xm/SeparatoG.h>
  26. #include <Xm/RowColumn.h>
  27. #include <Xm/PushBG.h>
  28. #include <Xm/ToggleB.h>
  29. #endif
  30.  
  31. #if ATHENA_WIDGETS
  32. #include <X11/Xaw/Form.h>
  33. #include <X11/Xaw/SimpleMenu.h>
  34. #include <X11/Xaw/MenuButton.h>
  35. #include <X11/Xaw/SmeLine.h>
  36. #include <X11/Xaw/SmeBSB.h>
  37. #endif
  38.  
  39. /* Locals */
  40. static Widget cascade;
  41.  
  42. /* Tokens of the rc file */
  43. #define MAX_TOKEN   200
  44. struct  _tok_
  45. {
  46.     char    type;
  47.     int     idx_cascade;
  48.     char    libelle [NSTRING];
  49.     char    action  [NSTRING];
  50.     int     macro;
  51. } Token [MAX_TOKEN];
  52. int Nb_Token;
  53.  
  54. /* Actions of the rc file */
  55. typedef void (*ActionFunc) ( char * );
  56.  
  57. typedef struct
  58. {
  59.     char                name [30];
  60.     const   ActionFunc  fact;
  61.  
  62. } TAct;
  63.  
  64. /* Common Actions = User defined Actions */
  65. /* Why not use dynamic link library to get functions ? */
  66. static void common_action ( char *action );
  67. static TAct Actions [] = {
  68.     { "nop",            0 },
  69.     { "new_xvile",      common_action },
  70.     { "edit_rc",        common_action },
  71.     { "parse_rc",       common_action },
  72.     { "edit_mrc",       common_action },
  73. };
  74. int Nb_Actions = sizeof(Actions)/sizeof(TAct);
  75.  
  76.  
  77. static char *
  78. menu_filename(void)
  79. {
  80.         static char default_menu[] = ".vilemenu";
  81.         char *menurc = getenv ("XVILE_MENU");
  82.  
  83.         if (menurc == NULL || *menurc == EOS)
  84.                 menurc = default_menu;
  85.  
  86.         return flook(menurc, FL_ANYWHERE|FL_READABLE);
  87. }
  88.  
  89. static char *
  90. startup_filename(void)
  91. {
  92.         return flook(startup_file, FL_ANYWHERE|FL_READABLE);
  93. }
  94.  
  95. /************************************************************************/
  96. /* All the Common Action are pointed to this function                   */
  97. /************************************************************************/
  98. static void common_action ( char *action )
  99. {
  100.     TRACE(("Action=%s\n", action));
  101.  
  102.     if (!strcmp(action, "new_xvile"))
  103.     {
  104.         int pid;
  105.         int status;
  106.         char path[NFILEN];
  107.  
  108.         lsprintf(path, "%s/%s", exec_pathname, prog_arg);
  109.  
  110.         if ((pid = fork()) > 0) {
  111.             while (wait(&status) >= 0)
  112.                 ;
  113.         } else if (pid == 0) {
  114.             if ((pid = fork()) > 0) {
  115.                 _exit(0);       /* abandon exec'ing process */
  116.             } else if (pid == 0) {
  117.                 newprocessgroup(FALSE, 1);
  118.                 execl (path, "xvile", NULL, 0);
  119.                 _exit(errno);   /* just in case exec-failed */
  120.             }
  121.         }
  122.     }
  123.     else
  124.     if (!strcmp(action, "edit_rc"))
  125.     {
  126.         splitwind(FALSE, 1);
  127.         getfile (startup_filename(), TRUE);
  128.     }
  129.     else
  130.     if (!strcmp(action, "parse_rc"))
  131.     {
  132.         dofile (startup_filename());
  133.     }
  134.     else
  135.     if (!strcmp(action, "edit_mrc"))
  136.     {
  137.         splitwind(FALSE, 1);
  138.  
  139.         getfile (menu_filename(), TRUE);
  140.     }
  141. }
  142.  
  143. /************************************************************************/
  144. /* Test if the action name is part of the Actions of the rc file        */
  145. /************************************************************************/
  146. static int
  147. is_action ( char *action )
  148. {
  149.     int i;
  150.  
  151.     for (i=0; i<Nb_Actions; i++)
  152.     {
  153.         if (!strcmp(Actions[i].name, action))
  154.             return 1;
  155.     }
  156.  
  157.     return 0;
  158. }
  159.  
  160. /************************************************************************/
  161. /* Return the function pointer associated with the action name          */
  162. /************************************************************************/
  163. static ActionFunc
  164. get_action_fonc ( char *action )
  165. {
  166.     int i;
  167.  
  168.     for (i=0; i<Nb_Actions; i++)
  169.     {
  170.         if (!strcmp(Actions[i].name, action))
  171.             return Actions[i].fact;
  172.     }
  173.  
  174.     return 0;
  175. }
  176.  
  177. /************************************************************************/
  178. /* Test if the action name is a bind (inspired from vile sources        */
  179. /************************************************************************/
  180. static int
  181. is_bind ( char *action )
  182. {
  183.     char tok[NSTRING];
  184.     (void) token(action, tok, EOS);
  185.     if (engl2fnc(tok) != NULL)
  186.         return 1;
  187.  
  188.     return 0;
  189. }
  190.  
  191. /************************************************************************/
  192. /* Test if the action name begins with the keyword "cmd",               */
  193. /************************************************************************/
  194. static char *
  195. is_cmd ( char *action )
  196. {
  197.     char tok[NSTRING];
  198.     char *result = (char *)token(action, tok, EOS);
  199.     if (!strcmp(tok, "cmd"))
  200.         return result;
  201.  
  202.     return 0;
  203. }
  204.  
  205. /************************************************************************/
  206. /* Main function to parse the rc file                                   */
  207. /************************************************************************/
  208. int parse_menu ( const char *rc_filename )
  209. {
  210.     FILE    *fp;
  211.     char    line [1000];
  212.     char    *ptr_tok;
  213.     int     n, tmp;
  214.     int     cascade_token = 0;
  215.     int     nlig = 0;
  216.  
  217.     if ((fp = fopen(rc_filename, "r")) == NULL)
  218.         return FALSE;
  219.  
  220.     Nb_Token = 0;
  221.     while (fgets (line, sizeof(line), fp) != NULL)
  222.     {
  223.         nlig++;
  224.  
  225.         /* Let a tab begin inline comment */
  226.         if ((ptr_tok = strchr(line, '\t')) != 0)
  227.                 *ptr_tok = EOS;
  228.  
  229.         ptr_tok = strtok(line, ":");
  230.         if (ptr_tok == NULL)
  231.             continue;
  232.  
  233.         switch (*ptr_tok)
  234.         {
  235.         case ';': /* FALLTHRU */
  236.         case '#':
  237.                 continue;
  238.  
  239.         case 'C':
  240.                 Token[Nb_Token].type = *ptr_tok;
  241.                 if ((ptr_tok = strtok(NULL, ":\n")) != NULL)
  242.                 {
  243.                     strcpy(Token[Nb_Token].libelle, ptr_tok);
  244.                     cascade_token = Nb_Token;
  245.                     if ((ptr_tok = strtok(NULL, ":\n")) != NULL)
  246.                     {
  247.                         Token[Nb_Token].type = 'H';
  248.                     }
  249.                     Nb_Token++;
  250.                 }
  251.                 else
  252.                 {
  253.                     fclose (fp);
  254.                     return FAILED;
  255.                 }
  256.                 break;
  257.  
  258.         case 'S':
  259.                 Token[Nb_Token].type = *ptr_tok;
  260.                 Token[Nb_Token].idx_cascade = cascade_token;
  261.                 Nb_Token++;
  262.                 break;
  263.  
  264.         case 'L':
  265.                 Token[Nb_Token].type = 'S';
  266.                 Token[Nb_Token].idx_cascade = cascade_token;
  267.                 Nb_Token++;
  268.                 Token[Nb_Token].type = *ptr_tok;
  269.                 Token[Nb_Token].idx_cascade = cascade_token;
  270.                 if ((ptr_tok = strtok(NULL, ":\n")) != NULL)
  271.                 {
  272.                     strcpy(Token[Nb_Token].action, ptr_tok);
  273.                     cascade_token = Nb_Token;
  274.                 }
  275.                 Nb_Token++;
  276.                 break;
  277.  
  278.         case 'B':
  279.                 Token[Nb_Token].type = *ptr_tok;
  280.                 Token[Nb_Token].idx_cascade = cascade_token;
  281.                 n = 0;
  282.                 while ((ptr_tok = strtok(NULL, ":\n")) != NULL)
  283.                 {
  284.                     switch (n)
  285.                     {
  286.                     case 0:
  287.                         strcpy(Token[Nb_Token].libelle, ptr_tok);
  288.                         break;
  289.                     case 1:
  290.                         if (isDigit((int)*ptr_tok))
  291.                         {
  292.                             tmp = (int)atoi(ptr_tok);
  293.                             Token[Nb_Token].macro = tmp;
  294.                         }
  295.                         else
  296.                         {
  297.                             if (is_action(ptr_tok)
  298.                              || is_bind(ptr_tok)
  299.                              || is_cmd(ptr_tok))
  300.                             {
  301.                                 strcpy(Token[Nb_Token].action, ptr_tok);
  302.                             }
  303.                             else
  304.                             {
  305.                                 printf("Error in line %d : '%s' is not an action\n",
  306.                                             nlig, ptr_tok);
  307.                                 strcpy(Token[Nb_Token].action, "beep");
  308.                             }
  309.                         }
  310.                         break;
  311.                     }
  312.                     n++;
  313.                 }
  314.                 if (n != 2)
  315.                 {
  316.                     fclose (fp);
  317.                     return FAILED;
  318.                 }
  319.                 Nb_Token++;
  320.                 break;
  321.         }
  322.     }
  323.     fclose (fp);
  324.  
  325.     return TRUE;
  326. }
  327.  
  328. /************************************************************************/
  329. /* Debug function to print the  tokens of the rc file                   */
  330. /************************************************************************/
  331. #if OPT_TRACE
  332. static void
  333. print_token (void)
  334. {
  335.     int     i;
  336.  
  337.     for (i=0; i<Nb_Token; i++)
  338.     {
  339.         switch (Token[i].type)
  340.         {
  341.         case 'C':
  342.         case 'H':
  343.             Trace("%c %s\n",
  344.                         Token[i].type,
  345.                         Token[i].libelle);
  346.             break;
  347.         case 'S':
  348.             Trace("\t%c (%s)\n",
  349.                         Token[i].type,
  350.                         Token[Token[i].idx_cascade].libelle);
  351.             break;
  352.         case 'L':
  353.             Trace("\t%c %s\n",
  354.                         Token[i].type,
  355.                         Token[i].action);
  356.             break;
  357.         case 'B':
  358.             if (Token[i].macro > 0)
  359.                 Trace("\t%c %s(%s) -> Macro-%d\n",
  360.                         Token[i].type,
  361.                         Token[i].libelle,
  362.                         Token[Token[i].idx_cascade].libelle,
  363.                         Token[i].macro);
  364.             else
  365.                 Trace("\t%c %s(%s) -> Action-%s\n",
  366.                         Token[i].type,
  367.                         Token[i].libelle,
  368.                         Token[Token[i].idx_cascade].libelle,
  369.                         Token[i].action);
  370.         }
  371.     }
  372. }
  373. #endif
  374.  
  375. /************************************************************************/
  376. /* Motif function to make a cascade button into a menubar               */
  377. /************************************************************************/
  378. static Widget do_cascade ( Widget menub, char *nom, int the_class )
  379. {
  380. #if MOTIF_WIDGETS
  381.     Widget      pm;
  382.     XmString    xms;
  383.     char        str [50];
  384.  
  385.     sprintf(str, "%sMenu", nom);
  386.     pm = (Widget) XmCreatePulldownMenu (menub, str, NULL, 0);
  387. #if OPT_MENUS_COLORED
  388.     XtVaSetValues (pm,
  389.                 XtNforeground,          x_menu_foreground(),
  390.                 XtNbackground,          x_menu_background(),
  391.                 NULL);
  392.     XtVaSetValues (menub,
  393.                 XtNforeground,          x_menu_foreground(),
  394.                 XtNbackground,          x_menu_background(),
  395.                 NULL);
  396. #endif /* OPT_MENUS_COLORED */
  397.  
  398.     xms = XmStringCreateSimple (nom);
  399.  
  400.     cascade = XtVaCreateManagedWidget ("menuHeader",
  401.                 xmCascadeButtonWidgetClass,     menub,
  402.                 XmNlabelString,         xms,
  403.                 XmNsubMenuId,           pm,
  404. #if OPT_MENUS_COLORED
  405.                 XtNforeground,          x_menu_foreground(),
  406.                 XtNbackground,          x_menu_background(),
  407. #endif /* OPT_MENUS_COLORED */
  408.                 NULL);
  409.     XmStringFree (xms);
  410.  
  411.     if (the_class == 'H')
  412.     {
  413.         XtVaSetValues (menub,
  414.             XmNmenuHelpWidget,  cascade,
  415.             NULL);
  416.     }
  417.     return pm;
  418. #endif /* MOTIF_WIDGETS */
  419. #if ATHENA_WIDGETS
  420.     static      Widget last;
  421.     Widget      pm;
  422.     String      str = XtMalloc(strlen(nom) + 10);
  423.  
  424.     sprintf(str, "%sMenu", nom);
  425.     pm = XtVaCreatePopupShell (str,
  426.         simpleMenuWidgetClass,
  427.         menub,
  428.         XtNgeometry,                    NULL,
  429.         NULL);
  430.  
  431.     cascade = XtVaCreateManagedWidget ("menuHeader",
  432.         menuButtonWidgetClass,
  433.         menub,
  434.         XtNheight,                      x_menu_height(),
  435.         XtNlabel,                       nom,
  436.         XtNfromHoriz,                   last,
  437.         XtNmenuName,                    str,
  438.         NULL);
  439.     last = cascade;
  440.  
  441.     return pm;
  442. #endif /* ATHENA_WIDGETS */
  443. }
  444.  
  445. /************************************************************************/
  446. /* Motif function to make a button into a cascade (with accelarator)    */
  447. /************************************************************************/
  448. static Widget do_button ( Widget pm, char *nom, char *accel, int the_class )
  449. {
  450. #if MOTIF_WIDGETS
  451.     Widget      w;
  452.     XmString    xms_accl;
  453.     XmString    xms_name;
  454.     WidgetClass wc;
  455.  
  456.     switch (the_class) {
  457.         case 'S':
  458.             wc = xmSeparatorGadgetClass;
  459.             break;
  460.         default:
  461.             /* FALLTHRU */
  462.         case 'B':
  463.             wc = xmPushButtonGadgetClass;
  464.             break;
  465.     }
  466.  
  467.     if (accel != NULL)
  468.         xms_accl = XmStringCreateSimple (accel);
  469.     else
  470.         xms_accl = XmStringCreateSimple ("");
  471.  
  472.     xms_name = XmStringCreateSimple (nom);
  473.     w = XtVaCreateManagedWidget ("menuEntry",
  474.                 wc,
  475.                 pm,
  476.                 XmNacceleratorText,     xms_accl,
  477.                 XmNlabelString,         xms_name,
  478.                 NULL);
  479.  
  480.     XmStringFree (xms_accl);
  481.     XmStringFree (xms_name);
  482.  
  483.     return w;
  484. #endif /* MOTIF_WIDGETS */
  485. #if ATHENA_WIDGETS
  486.     Widget      w;
  487.  
  488.     w = XtVaCreateManagedWidget ("menuEntry",
  489.                 (the_class == 'B') ? smeBSBObjectClass : smeLineObjectClass,
  490.                 pm,
  491.                 XtNlabel,               nom,
  492.                 NULL);
  493.  
  494.     return w;
  495. #endif /* ATHENA_WIDGETS */
  496. }
  497.  
  498. /************************************************************************/
  499. /* Function called when a button is clicked into the menu               */
  500. /* Bind and Action are tested                                           */
  501. /************************************************************************/
  502. static void proc_back ( Widget w GCC_UNUSED, XtPointer arg, XtPointer call  GCC_UNUSED)
  503. {
  504.     char    *macro_action = (char *)arg;
  505.     ActionFunc fact;
  506.     int     oldflag = im_waiting(-1);
  507.     int     exec_flag = TRUE;
  508.     char    *s;
  509.  
  510.     TRACE(("Macro/Action=%s\n", macro_action));
  511.  
  512.     if ((s = is_cmd(macro_action)) != 0)
  513.     {
  514.         macro_action = s;
  515.         exec_flag = FALSE;
  516.     }
  517.  
  518.     if (is_bind (macro_action))
  519.     {
  520.         docmd (macro_action, exec_flag, FALSE, 1);
  521.     }
  522.     else
  523.     {
  524.         /* Action predefined */
  525.         fact = get_action_fonc (macro_action);
  526.         if (fact == NULL)
  527.             return;
  528.         fact(macro_action);
  529.     }
  530.  
  531.     (void)im_waiting(oldflag);
  532.     (void)update(TRUE);
  533. }
  534.  
  535. /************************************************************************/
  536. /* Function called when a buffer button is clicked into the menu        */
  537. /* A buffer button takes part from the list tokens (L)                  */
  538. /************************************************************************/
  539. static void list_proc_back ( Widget w, XtPointer bname, XtPointer call GCC_UNUSED )
  540. {
  541.     int     num_buff;
  542.     int     oldflag = im_waiting(-1);
  543.  
  544. #if MOTIF_WIDGETS
  545.     char *accel;
  546.     XmString xms;
  547.     XtVaGetValues (w, XmNacceleratorText, &xms, NULL);
  548. #ifndef XmFONTLIST_DEFAULT_TAG
  549. #define XmFONTLIST_DEFAULT_TAG "XmFONTLIST_DEFAULT_TAG_STRING"
  550. #endif
  551.     XmStringGetLtoR (xms,  XmFONTLIST_DEFAULT_TAG, &accel);
  552.     num_buff = atoi(&accel[1]);
  553. #endif
  554. #if ATHENA_WIDGETS
  555.     num_buff = (int)bname;
  556. #endif
  557.  
  558.     (void)histbuff(TRUE, num_buff);
  559.     (void)im_waiting(oldflag);
  560.     (void)update(TRUE);
  561. }
  562.  
  563. static void add_callback(Widget w, XtCallbackProc function, XtPointer closure)
  564. {
  565. #if MOTIF_WIDGETS
  566.     XtAddCallback (w, XmNactivateCallback, function, closure);
  567. #endif
  568. #if ATHENA_WIDGETS
  569.     XtAddCallback (w, XtNcallback, function, closure);
  570. #endif /* ATHENA_WIDGETS */
  571. }
  572.  
  573. /************************************************************************/
  574. /* Function called when the cascade containing the List (buffers)       */
  575. /* is clicked => Post the PullDown associated                           */
  576. /* It's dirty ...                                                       */
  577. /************************************************************************/
  578. static void post_buffer_list ( Widget w GCC_UNUSED, XtPointer client GCC_UNUSED, XEvent *ev GCC_UNUSED, Boolean *ok  GCC_UNUSED)
  579. {
  580.     static int in_item_menu_list = 0;   /* number allocated */
  581.     static int nb_item_menu_list = 0;   /* number in use */
  582.     static Widget *pm_buffer;
  583.  
  584.     int     i, n = nb_item_menu_list;
  585.     BUFFER  *bp;
  586.     char    string[NBUFN+2+NFILEN], temp[1+NFILEN], *p;
  587.     Widget  pm = (Widget) client;
  588.  
  589.     TRACE(("post_buffer_list\n"));
  590.     nb_item_menu_list = 0;
  591.  
  592.     for_each_buffer(bp)
  593.     {
  594.         if (b_is_temporary(bp)) /* cf: hist_show() */
  595.             continue;
  596.  
  597.         p = shorten_path(strcpy(temp, bp->b_fname), FALSE);
  598.         sprintf(string, "%-*.*s %s", NBUFN-1, NBUFN-1,
  599.                 bp->b_bname, p);
  600.  
  601.         sprintf(temp, "_%d", nb_item_menu_list);
  602.         TRACE(("ACCEL(%s) = %s\n", temp, string));
  603.  
  604.         if (nb_item_menu_list + 2 >= in_item_menu_list)
  605.         {
  606.             int m = in_item_menu_list;
  607.             in_item_menu_list = (in_item_menu_list + 3) * 2;
  608.             if (pm_buffer != 0)
  609.                 pm_buffer = typereallocn(Widget,pm_buffer,in_item_menu_list);
  610.             else
  611.                 pm_buffer = typeallocn(Widget,in_item_menu_list);
  612.             while (m < in_item_menu_list)
  613.                 pm_buffer[m++] = 0;
  614.         }
  615.  
  616.         if (pm_buffer [nb_item_menu_list] == 0)
  617.         {
  618.             pm_buffer [nb_item_menu_list] = do_button (pm, string, temp, 'B');
  619.         }
  620.         else
  621.         {
  622. #if MOTIF_WIDGETS
  623.             XmString xms = XmStringCreateSimple (string);
  624.             XtVaSetValues (pm_buffer [nb_item_menu_list],
  625.                         XmNlabelString, xms, NULL);
  626.             XmStringFree (xms);
  627.             XtRemoveCallback (pm_buffer[nb_item_menu_list],
  628.                               XmNactivateCallback, list_proc_back, NULL);
  629. #endif
  630. #if ATHENA_WIDGETS
  631.             XtVaSetValues (pm_buffer [nb_item_menu_list],
  632.                         XtNlabel, string, NULL);
  633.             XtRemoveAllCallbacks (pm_buffer[nb_item_menu_list],
  634.                         XtNcallback);
  635. #endif
  636.         }
  637.  
  638. #if MOTIF_WIDGETS
  639.         XtAddCallback (pm_buffer[nb_item_menu_list],
  640.                         XmNactivateCallback,
  641.                         list_proc_back,
  642.                         NULL);
  643. #endif
  644. #if ATHENA_WIDGETS
  645.         XtAddCallback (pm_buffer[nb_item_menu_list],
  646.                         XtNcallback,
  647.                         list_proc_back,
  648.                         (XtPointer)nb_item_menu_list);
  649. #endif
  650.         nb_item_menu_list++;
  651.     }
  652.     for (i=nb_item_menu_list; i<n; i++)
  653.     {
  654.         XtDestroyWidget (pm_buffer[i]);
  655.         pm_buffer[i] = NULL;
  656.     }
  657.  
  658. #if MOTIF_WIDGETS
  659.     XmUpdateDisplay(pm);
  660. #endif
  661. }
  662.  
  663. /************************************************************************/
  664. /* Main function : Take the MotifBar as argument and create all the     */
  665. /* Cascades, PullDowns Menus and Buttons read from the rc file          */
  666. /************************************************************************/
  667. void do_menu ( Widget menub )
  668. {
  669.     int     i, n = 0;
  670.     char    *arg, *accel, *macro;
  671.     Widget  pm = 0;
  672.     Widget  pm_w [50];
  673.     int     rc;
  674.     char   *menurc = menu_filename();
  675.  
  676.     if ((rc = parse_menu (menurc)) != TRUE)
  677.     {
  678.         if (rc == FAILED)
  679.             puts ("Error parsing menu-file");
  680.         return;
  681.     }
  682. #if OPT_TRACE
  683.     print_token();
  684. #endif
  685.  
  686.     for (i=0; i<Nb_Token; i++)
  687.     {
  688.         switch (Token[i].type)
  689.         {
  690.         /* HELP CASCADE */
  691.         case 'C':
  692.         case 'H':
  693.             pm = do_cascade (menub, Token[i].libelle, Token[i].type);
  694.             n = 0;
  695.             break;
  696.  
  697.         /* SEPARATOR WIDGET */
  698.         case 'S':
  699.             do_button (pm, "sep", NULL, Token[i].type);
  700.             break;
  701.  
  702.         /* LIST (BUFFER LIST) */
  703.         case 'L':
  704.             if (!strcmp(Token[i].action, "list_buff")
  705.              && cascade != 0)
  706.             {
  707.                 XtAddEventHandler (cascade,
  708.                         ButtonPressMask, False, post_buffer_list, pm);
  709.             }
  710.             break;
  711.  
  712.         /* BUTTON WIDGET */
  713.         case 'B':
  714.             if (Token[i].macro > 0)
  715.             {
  716.                 macro = castalloc(char,50);
  717.                 sprintf(macro, "execute-macro-%d", Token[i].macro);
  718.                 accel = give_accelerator (macro);
  719.                 pm_w[n] = do_button (pm, Token[i].libelle, accel, Token[i].type);
  720.  
  721.                 add_callback (pm_w[n], proc_back, macro);
  722.             }
  723.             else
  724.             {
  725.                 accel = give_accelerator (Token[i].action);
  726.                 pm_w[n] = do_button (pm, Token[i].libelle, accel, Token[i].type);
  727.                 add_callback (pm_w[n], proc_back, Token[i].action);
  728.             }
  729.             n++;
  730.             break;
  731.         }
  732.     }
  733. }
  734. /************************************************************************/
  735.  
  736. #endif /* DISP_X11 */
  737.