home *** CD-ROM | disk | FTP | other *** search
/ Fish 'n' More 2 / fishmore-publicdomainlibraryvol.ii1991xetec.iso / fish / applications / xlispstat / src / src1.lzh / Amiga / amimenus.c < prev    next >
C/C++ Source or Header  |  1990-10-11  |  10KB  |  311 lines

  1. /* AmiMenus.c - Low Level Menu Objects for Amiga                       */
  2. /* Copyright (c) 1990 by J.K. Lindsey                                  */
  3. /* Additions to XLISP-STAT 2.1 Copyright (c) 1990, by Luke Tierney     */
  4. /* Additions to Xlisp 2.1, Copyright (c) 1989 by David Michael Betz    */
  5. /* You may give out copies of this software; for conditions see the    */
  6. /* file COPYING included with this distribution.                       */
  7.  
  8. #include <proto/intuition.h>
  9. #include <stdlib.h>
  10. #include "autil2.h"
  11. #include "xlisp.h"
  12. #include "osdef.h"
  13. #include "xlproto.h"
  14. #include "xlsproto.h"
  15. #include "iviewproto.h"
  16. #include "Stproto.h"
  17. #include "xlsvar.h"
  18. #include "amivar.h"
  19.  
  20. char *get_item_string(LVAL);
  21.  
  22. #define get_menu_id(m) ((int) getfixnum(slot_value(m, s_id)))
  23.  
  24. /***********************************************************************/
  25. /**                                                                   **/
  26. /**                        Support Function                           **/
  27. /**                                                                   **/
  28. /***********************************************************************/
  29.  
  30. static LVAL GetMenuList(void){
  31.    return(slot_value(getvalue(s_menu_proto),s_menu_list));}
  32.  
  33. /* find the position of the item in the menu */
  34. static int get_item_position(LVAL menu,LVAL item){
  35.    int i;
  36.    LVAL items;
  37.    for(items=slot_value(menu,s_items),i=0;consp(items)&&car(items)!=item;
  38.    i++,items=cdr(items));
  39.    if(item!=car(items))xlfail("item not in the menu");
  40.    return(i);}
  41.  
  42. /***********************************************************************/
  43. /**                                                                   **/
  44. /**                            Menu Functions                         **/
  45. /**                                                                   **/
  46. /***********************************************************************/
  47.  
  48. int StMObInstalled(LVAL m){
  49.   return(StMObAllocated(m));}
  50.  
  51. /* find menu object with given hardware address */
  52. LVAL get_menu_by_hardware(IVIEW_MENU m){
  53.    LVAL menu=0,next;
  54.    for(next=GetMenuList();menu==0&&consp(next);next=cdr(next)){
  55.       if(StMObAllocated(car(next))&&m==get_menu_address(car(next)))menu=car(next);}
  56.    if(!menu)xlfail("can't find menu with this ID");
  57.    return(menu);}
  58.  
  59. /* find lisp menu with a specified Amiga address */
  60. /*static LVAL get_menu_by_id(IVIEW_MENU m){
  61.    return(get_menu_by_hardware(m));} not used */
  62.  
  63. /* allocate an Amiga internal menu */
  64. static int id_in_use(int id){
  65.    LVAL next;
  66.    for(next=GetMenuList();consp(next);next=cdr(next)){
  67.       if(id==get_menu_id(car(next)))return(TRUE);}
  68.    return(FALSE);}
  69.  
  70. static unique_id(void){
  71.    static int id=2000;
  72.    if(id>32000)id=2000;
  73.    id++;
  74.    while(id_in_use(id))id++;
  75.    return(id);}
  76.  
  77. void StMObAllocateMach(LVAL menu){
  78.    int MenuID,i;
  79.    struct SuperMenu *tmptr,*this;
  80.    tmptr=calloc(1,sizeof(struct SuperMenu));
  81.    if(!tmptr)xlfail("menu allocation failed");
  82.    this=Menu_Ptr;
  83.    i=0;
  84.    if(this){            /* find last menu on list */
  85.       i++;
  86.       while(this->Next){
  87.          i++;
  88.          this=this->Next;}
  89.       this->Next=tmptr;}
  90.    else Menu_Ptr=tmptr;
  91.    if(i>30){
  92.       free(tmptr);
  93.       xlfail("no menu space left");}
  94.    tmptr->MenuNum=i;
  95.    tmptr->Title=getstring(slot_value(menu,s_title));
  96.    tmptr->Next=0;
  97.    tmptr->Items=0;
  98.    set_menu_address(tmptr,menu);
  99.    MenuID=unique_id();
  100.    set_slot_value(menu,s_id,cvfixnum((FIXTYPE)MenuID));}
  101.  
  102. /* dispose of an Amiga internal menu */
  103. void StMObDisposeMach(LVAL menu){
  104.    int i;
  105.    struct SuperMenu *theMenu,*this,*temp;
  106.    struct SuperMenuItem *tmptr,*ptr;
  107.    if(StMObAllocated(menu)){
  108.       theMenu=get_menu_address(menu);
  109.       this=Menu_Ptr;
  110.       i=0;
  111.       if(this==theMenu){
  112.          temp=this;
  113.          Menu_Ptr=this=this->Next;}
  114.       else {
  115.          while(this->Next&&this->Next!=theMenu){
  116.             i++;
  117.             this=this->Next;}
  118.          if(!this->Next)xlfail("menu not found");
  119.          temp=this->Next;
  120.          this=this->Next=this->Next->Next;}
  121.       while(this){
  122.          this->MenuNum=++i;
  123.          this=this->Next;}
  124.       ptr=temp->Items;
  125.       while(ptr){
  126.          tmptr=ptr;
  127.          ptr=ptr->Next;
  128.          free(tmptr);}
  129.       free(temp);
  130.       StMObInstall(0);}}
  131.  
  132. /* add items to an Amiga internal menu */
  133. void StMObAppendItems(LVAL menu,LVAL items){
  134.    LVAL item,key;
  135.    int i;
  136.    struct SuperMenu *theMenu;
  137.    struct SuperMenuItem *tmptr,*this,*next;
  138.    if(StMObAllocated(menu)){
  139.       theMenu=get_menu_address(menu);
  140.       i=llength(slot_value(menu,s_items))-llength(items);
  141.       if(i<0)xlfail("append list should not exceed item list");
  142.       i=0;
  143.       tmptr=this=0;
  144.       next=theMenu->Items;
  145.       while(next){
  146.          i++;         /* i is number of items and number for next item */
  147.          this=next;
  148.          next=next->Next;}
  149.       for(;consp(items);items=cdr(items),i++){
  150.          item=car(items);
  151.          tmptr=calloc(1,sizeof(struct SuperMenuItem));
  152.          if(!tmptr)xlfail("menu item allocation failed");
  153.          tmptr->ItemNum=i;
  154.          tmptr->Text=get_item_string(item);
  155.          if(charp(key=slot_value(item,s_key)))tmptr->CmndChar=getchcode(key);
  156.          if(slot_value(item,s_enabled))tmptr->Enabled=1;
  157.          else tmptr->Enabled=0;
  158.          if(this)this->Next=tmptr;
  159.          else theMenu->Items=tmptr;
  160.          this=tmptr;}
  161.       if(tmptr)tmptr->Next=0;
  162.       StMObInstall(menu);}}
  163.  
  164. /* remove item from an Amiga menu */
  165. void StMObDeleteItem(LVAL menu,LVAL item){
  166.    int i;
  167.    struct SuperMenu *theMenu;
  168.    struct SuperMenuItem *this,*temp;
  169.    if(StMObAllocated(menu)){
  170.       theMenu=get_menu_address(menu);
  171.       i=get_item_position(menu,item);
  172.       this=theMenu->Items;
  173.       if(i){
  174.          while(this->Next->ItemNum!=i)this=this->Next;
  175.          temp=this->Next;
  176.          this=this->Next=this->Next->Next;}
  177.       else {
  178.          temp=this;
  179.          this=theMenu->Items=this->Next;}
  180.       while(this){
  181.          this->ItemNum=i--;
  182.          this=this->Next;}
  183.       free(temp);
  184.       StMObInstall(menu);}}
  185.  
  186. /* install an Amiga menu */
  187. void StMObInstall(LVAL menu){
  188.    struct Window *w;
  189.    struct SuperMenu *mptr;
  190.    struct SuperMenuItem *iptr;
  191.    int i,j;
  192.    if(!Menu_Ptr)return;
  193.    if(menu&&!StMObAllocated(menu))StMObAllocate(menu);
  194.    if(!(mymenu=BuildMenuStripL(Menu_Ptr,8)))xlfail("menu build failed");
  195.    w=screen->FirstWindow;
  196.    while(w){
  197.       ClearMenuStrip(w);
  198.       SetMenuStrip(w,mymenu);
  199.       mptr=Menu_Ptr;
  200.       i=0;
  201.       while(mptr){
  202.          iptr=mptr->Items;
  203.          j=0;
  204.          while(iptr){
  205.             if(!iptr->Enabled)OffMenu(w,i+(j<<5));
  206.             j++;
  207.             iptr=iptr->Next;}
  208.          i++;
  209.          mptr=mptr->Next;}
  210.       w=w->NextWindow;}}
  211.  
  212. /* remove an Amiga menu */
  213. void StMObRemove(LVAL menu){
  214.    if(StMObAllocated(menu))StMObDispose(menu);}
  215.  
  216. /* enable or disable an Amiga menu */
  217. void StMObEnable(LVAL menu,int enable){
  218.    struct SuperMenu *theMenu,*this;
  219.    struct Window *w;
  220.    short i;
  221.    if(StMObAllocated(menu)){
  222.       theMenu=get_menu_address(menu);
  223.       this=Menu_Ptr;
  224.       i=0;
  225.       while(this->Next&&this!=theMenu){
  226.          i++;
  227.          this=this->Next;}
  228.       if(!this->Next)return;
  229.       w=screen->FirstWindow;
  230.       while(w){
  231.          if(enable)OnMenu(w,i);
  232.          else OffMenu(w,i);
  233.          w=w->NextWindow;}}
  234.    set_slot_value(menu,s_enabled,(enable)?s_true:NIL);}
  235.  
  236. int StMObPopup(LVAL menu,int left,int top,LVAL window){
  237.    return(0);}
  238.  
  239. /***********************************************************************/
  240. /**                                                                   **/
  241. /**                         Menu Item Functions                       **/
  242. /**                                                                   **/
  243. /***********************************************************************/
  244.  
  245. /* Get a string for use by AppendMenu. Style info is not encoded. */
  246. static char *get_item_string(LVAL item){
  247.    LVAL title;/*,key,mark,enabled;
  248.    static char *s;*/
  249.    if(!menu_item_p(item))xlerror("not a menu item", item);
  250.    title=slot_value(item,s_title);
  251.    if(!stringp(title))xlerror("title is not a string", title);
  252. /*   key=slot_value(item, s_key);
  253.    mark=slot_value(item, s_mark);
  254.    enabled=slot_value(item, s_enabled);
  255.    s=buf;
  256.    if(!enabled)s+=sprintf(s,"(");
  257.    if(charp(key))s+=sprintf(s,"/%c",getchcode(key));
  258.    if(mark==s_true)s+=sprintf(s,"!%c",0x12);
  259.    else if(charp(mark))s+=sprintf(s,"!%c",getchcode(key));
  260.    sprintf(s,"%s",getstring(title));*/
  261.    return((char *)getstring(title));}
  262.  
  263. /* adjust internal implementation of allocated menu to new instance value */ 
  264. void StMObSetItemProp(LVAL item,int which){
  265.    struct SuperMenu *theMenu,*mptr;
  266.    struct SuperMenuItem *iptr;
  267.    LVAL menu;
  268.    int j;
  269.    menu=slot_value(item,s_menu);
  270.    if(menu&&StMObAllocated(menu)){
  271.       theMenu=get_menu_address(menu);
  272.       mptr=Menu_Ptr;
  273.       while(mptr&&mptr!=theMenu){
  274.          mptr=mptr->Next;}
  275.       if(!mptr)xlfail("menu not found");
  276.       j=get_item_position(menu,item);
  277.       iptr=theMenu->Items;
  278.       if(j)while(iptr&&iptr->ItemNum!=j)iptr=iptr->Next;
  279.       if(!iptr)xlfail("menu item not found");
  280. printf("which=%c\n",which);
  281.       switch(which){
  282.          case 'T': {
  283.             LVAL title=slot_value(item,s_title);
  284.             if(!stringp(title))xlerror("title is not a string",title);
  285.             iptr->Text=getstring(title);
  286.             break;}
  287.          case 'K': {
  288.             LVAL key=slot_value(item,s_key);
  289.             if(charp(key))iptr->CmndChar=getchcode(key);
  290.             break;}
  291.          case 'M': {
  292.             LVAL mark=slot_value(item,s_mark);
  293.             if(mark==s_true)iptr->SetFlags|=CHECKIT|MENUTOGGLE|CHECKED;
  294.             else iptr->SetFlags&=~CHECKIT&~MENUTOGGLE&~CHECKED;
  295.             break;}
  296.          case 'S':
  297.          case 'A': break;
  298.          case 'E': {
  299.             if(slot_value(item,s_enabled))iptr->Enabled=1;
  300.             else iptr->Enabled=0;
  301.             break;}
  302.          default: xlfail("unknown item instance variable");}
  303.       StMObInstall(menu);}}
  304.  
  305. /* about alert for the compiler */
  306. LVAL xsabout_xlisp_stat(void){
  307.    struct IntuiText text[]={{1,2,JAM2,20,5,0,"Lattice C, V5.05",0},
  308.                             {0,1,JAM2,5,4,0,"OK",0}};
  309.    AutoRequest(window,&text[0],0,&text[1],0,0,200,50);
  310.    return(NIL);}
  311.