home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / amiga / utility / text / emacsdif.lha / emacs-18.58 / src / amiga_menu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-26  |  7.0 KB  |  316 lines

  1. #include <exec/types.h>
  2. #include <libraries/gadtools.h>
  3. #include <intuition/intuition.h>
  4. #include <proto/exec.h>
  5. #include <proto/dos.h>
  6. #include <proto/gadtools.h>
  7. #include <proto/intuition.h>
  8. #include "config.h"
  9. #undef NULL
  10. #include "lisp.h"
  11. #include "amiga.h"
  12.  
  13. static struct Menu *emacs_menu;
  14. static char *emacs_menu_strings;
  15. static APTR win_vi;
  16. struct Library *GadToolsBase;
  17.  
  18. DEFUN ("amiga-menus", Famiga_menus, Samiga_menus, 1, 1, 0,
  19.   "Define menus for emacs. The argument is a list structured as follows:\n\
  20.    ((menu1-name ((item1-name item1-expr item1-key item1-disabled) ...)\n\
  21.      menu1-disabled) ...)\n\
  22. menu-name is the name of the menu item header.\n\
  23. The menu is disabled if menu-disabled is not nil [optional].\n\
  24. item-name is the name of an item.\n\
  25. The item-expr fields are ignored.\n\
  26. If item-key is nil, no shortcut is allowed.\n\
  27. If item-disabled is not nil, the item is disabled.\n\
  28. If the item information list is nil, a line is drawn in the menu.\n\
  29. item-key & item-disabled are optional.")
  30.   (menus)
  31.      Lisp_Object menus;
  32. {
  33.     Lisp_Object s_menus, s_items;
  34.     int citems, slen;
  35.     char *strdata;
  36.     struct NewMenu *menudata, *mkm;
  37.     struct Lisp_String *name;
  38.  
  39. /*    int i;
  40.     extern int total[], nb[];
  41.  
  42.     for (i = 0; i < 16; i++)
  43.     {
  44.     printf("%d(%d) ", total[i], nb[i]);
  45.     total[i] = nb[i] = 0;
  46.     }
  47.     printf("\n");
  48.     start_count(15);
  49.     for (i = 0; i < 100; i++) { suspend_count(15); resume_count(15); }
  50.     stop_count(15);
  51.     for (i = 0; i < 100; i++) { start_count(14); stop_count(14); }
  52.     printf("100 s/r: %d, 100 s/s: %d\n", total[15], total[14]);
  53.  
  54.     return Qnil;
  55. */
  56.     check_intuition();
  57.  
  58.     /* Check structure of parameter & count # items & menus */
  59.     s_menus = menus;
  60.     citems = slen = 0;
  61.  
  62.     while (!NULL(s_menus))
  63.     {
  64.     struct Lisp_Cons *menu, *menu_cell;
  65.  
  66.     CHECK_CONS(s_menus, 0);
  67.     menu_cell = XCONS(s_menus);
  68.     citems++;
  69.     CHECK_CONS(menu_cell->car, 0); /* Each menu is a list */
  70.     menu = XCONS(menu_cell->car);
  71.  
  72.     CHECK_STRING(menu->car, 0); /* Check name */
  73.     name = XSTRING(menu->car);
  74.     slen += name->size + 1;
  75.     CHECK_CONS(menu->cdr, 0);
  76.  
  77.     menu = XCONS(menu->cdr); /* Check items */
  78.  
  79.     s_items = menu->car;
  80.     while (!NULL(s_items))
  81.     {
  82.         struct Lisp_Cons *item, *item_cell;
  83.  
  84.         CHECK_CONS(s_items, 0);
  85.         item_cell = XCONS(s_items);
  86.         citems++;
  87.         if (!NULL(item_cell->car))
  88.         {
  89.         CHECK_CONS(item_cell->car, 0); /* Each item is a list */
  90.         item = XCONS(item_cell->car);
  91.  
  92.         CHECK_STRING(item->car, 0);
  93.         name = XSTRING(item->car);
  94.         slen += name->size + 1;
  95.  
  96.         if (!NULL(item->cdr)) /* Only name is necessary */
  97.         {
  98.             CHECK_CONS(item->cdr, 0);
  99.             item = XCONS(item->cdr);
  100.  
  101.             /* Expr is arbitrary */
  102.             if (!NULL(item->cdr))
  103.             {
  104.             CHECK_CONS(item->cdr, 0);
  105.             item = XCONS(item->cdr);
  106.  
  107.             /* Check shortcut */
  108.             if (!NULL(item->car))
  109.             {
  110.                 CHECK_NUMBER(item->car, 0);
  111.                 slen += 2;
  112.             }
  113.  
  114.             if (!NULL(item->cdr))
  115.             {
  116.                 CHECK_CONS(item->cdr, 0);
  117.                 item = XCONS(item->cdr);
  118.  
  119.                 /* Check that end of list */
  120.                 if (!NULL(item->cdr)) error("Badly formed item");
  121.             }
  122.             }
  123.         }
  124.         }
  125.         s_items = item_cell->cdr;
  126.     }
  127.     if (!NULL(menu->cdr))
  128.     {
  129.         CHECK_CONS(menu->cdr, 0);
  130.         menu = XCONS(menu->cdr);
  131.         if (!NULL(menu->cdr)) error("Badly formed menu");
  132.     }
  133.     s_menus = menu_cell->cdr;
  134.     }
  135.  
  136.     if (emacs_menu) Famiga_delete_menus();
  137.  
  138.     /* Now create menu structure */
  139.     menudata = (struct NewMenu *)alloca(sizeof(struct NewMenu) * (citems + 1));
  140.     emacs_menu_strings = strdata = (char *)xmalloc(slen);
  141.     mkm = menudata;
  142.     s_menus = menus;
  143.     while (!NULL(s_menus))
  144.     {
  145.     struct Lisp_Cons *menu, *menu_cell;
  146.     struct NewMenu *menu1;
  147.  
  148.     menu_cell = XCONS(s_menus);
  149.     mkm->nm_Type = NM_TITLE;
  150.     menu = XCONS(menu_cell->car);
  151.     name = XSTRING(menu->car);
  152.     strcpy(strdata, name->data);
  153.     mkm->nm_Label = strdata;
  154.     strdata += name->size + 1;
  155.     mkm->nm_CommKey = 0;
  156.     mkm->nm_Flags = 0;
  157.     mkm->nm_MutualExclude = 0;
  158.     menu1 = mkm++;
  159.  
  160.     menu = XCONS(menu->cdr); /* Check items */
  161.  
  162.     s_items = menu->car;
  163.     while (!NULL(s_items))
  164.     {
  165.         struct Lisp_Cons *item, *item_cell;
  166.  
  167.         item_cell = XCONS(s_items);
  168.         mkm->nm_Type = NM_ITEM;
  169.         mkm->nm_CommKey = 0;
  170.         mkm->nm_Flags = 0;
  171.         mkm->nm_MutualExclude = 0;
  172.         if (NULL(item_cell->car))
  173.         {
  174.         mkm->nm_Type = IM_ITEM;
  175.         mkm->nm_Label = NM_BARLABEL;
  176.         }
  177.         else
  178.         {
  179.  
  180.         item = XCONS(item_cell->car);
  181.         name = XSTRING(item->car);
  182.         strcpy(strdata, name->data);
  183.         mkm->nm_Label = strdata;
  184.         strdata += name->size + 1;
  185.  
  186.         if (!NULL(item->cdr)) /* Only name is necessary */
  187.         {
  188.             item = XCONS(item->cdr);
  189.  
  190.             /* Expr is ignored */
  191.  
  192.             if (!NULL(item->cdr))
  193.             {
  194.             item = XCONS(item->cdr);
  195.  
  196.             /* Check shortcut */
  197.             if (!NULL(item->car))
  198.             {
  199.                 mkm->nm_CommKey = strdata;
  200.                 strdata[0] = XFASTINT(item->car);
  201.                 strdata[1] = '\0';
  202.                 strdata += 2;
  203.             }
  204.             if (!NULL(item->cdr))
  205.             {
  206.                 item = XCONS(item->cdr);
  207.                 if (!NULL(item->car))
  208.                 mkm->nm_Flags |= NM_ITEMDISABLED;
  209.             }
  210.             }
  211.         }
  212.         }
  213.         mkm++;
  214.         s_items = item_cell->cdr;
  215.     }
  216.     if (!NULL(menu->cdr))
  217.     {
  218.         menu = XCONS(menu->cdr);
  219.         if (!NULL(menu->car)) menu1->nm_Flags |= NM_MENUDISABLED;
  220.     }
  221.     s_menus = menu_cell->cdr;
  222.     }
  223.     mkm->nm_Type = NM_END;
  224.     mkm->nm_Label = 0;
  225.     mkm->nm_CommKey = 0;
  226.     mkm->nm_Flags = 0;
  227.     mkm->nm_MutualExclude = 0;
  228.     if (!(emacs_menu = CreateMenus(menudata, TAG_END)))
  229.     {
  230.     free(emacs_menu_strings);
  231.     emacs_menu_strings = 0;
  232.     error("Menu couldn't be created");
  233.     }
  234.     if (!LayoutMenus(emacs_menu, win_vi, TAG_END))
  235.     {
  236.     FreeMenus(emacs_menu);
  237.     emacs_menu = 0;
  238.     free(emacs_menu_strings);
  239.     emacs_menu_strings = 0;
  240.     error("Menu couldn't be layed out");
  241.     }
  242.     SetMenuStrip(emacs_win, emacs_menu);
  243.  
  244.     return Qt;
  245. }
  246.  
  247. DEFUN ("amiga-delete-menus", Famiga_delete_menus, Samiga_delete_menus, 0, 0, 0,
  248.        "Remove & free menu strip")
  249.    ()
  250. {
  251.     check_intuition();
  252.  
  253.     ClearMenuStrip(emacs_win);
  254.     if (emacs_menu) FreeMenus(emacs_menu);
  255.     emacs_menu = 0;
  256.     if (emacs_menu_strings) free(emacs_menu_strings);
  257.     emacs_menu_strings = 0;
  258.  
  259.     return Qt;
  260. }
  261.  
  262. void syms_of_amiga_menu(void)
  263. {
  264.     defsubr(&Samiga_delete_menus);
  265.     defsubr(&Samiga_menus);
  266. }
  267.  
  268. void suspend_menus(void)
  269. {
  270.     ClearMenuStrip(emacs_win);
  271. }
  272.  
  273. void resume_menus(void)
  274. {
  275.     if (emacs_menu) SetMenuStrip(emacs_win, emacs_menu);
  276. }
  277.  
  278. int set_menu_window(struct Window *w)
  279. {
  280.     APTR new_vi = GetVisualInfo(w->WScreen, TAG_END);
  281.  
  282.     if (!new_vi) return FALSE;
  283.  
  284.     if (emacs_menu)
  285.     {
  286.     if (!LayoutMenus(emacs_menu, new_vi, TAG_END))
  287.     {
  288.         FreeVisualInfo(new_vi);
  289.         /* Restore old layout */
  290.         if (!LayoutMenus(emacs_menu, win_vi, TAG_END)) Famiga_delete_menus();
  291.  
  292.         return FALSE;
  293.     }
  294.     }
  295.     FreeVisualInfo(win_vi);
  296.     win_vi = new_vi;
  297.  
  298.     return TRUE;
  299. }
  300.  
  301. int init_amiga_menu(void)
  302. {
  303.     GadToolsBase = OpenLibrary("gadtools.library", 0);
  304.     if (!GadToolsBase) return FALSE;
  305.     if (emacs_win)
  306.     win_vi = GetVisualInfo(emacs_win->WScreen, TAG_END);
  307.     return win_vi != 0;
  308. }
  309.  
  310. void cleanup_amiga_menu(void)
  311. {
  312.     if (emacs_win) Famiga_delete_menus();
  313.     if (win_vi) FreeVisualInfo(win_vi);
  314.     if (GadToolsBase) CloseLibrary(GadToolsBase);
  315. }
  316.