home *** CD-ROM | disk | FTP | other *** search
- /* AmiMenus.c - Low Level Menu Objects for Amiga */
- /* Copyright (c) 1990 by J.K. Lindsey */
- /* Additions to XLISP-STAT 2.1 Copyright (c) 1990, by Luke Tierney */
- /* Additions to Xlisp 2.1, Copyright (c) 1989 by David Michael Betz */
- /* You may give out copies of this software; for conditions see the */
- /* file COPYING included with this distribution. */
-
- #include <proto/intuition.h>
- #include <stdlib.h>
- #include "autil2.h"
- #include "xlisp.h"
- #include "osdef.h"
- #include "xlproto.h"
- #include "xlsproto.h"
- #include "iviewproto.h"
- #include "Stproto.h"
- #include "xlsvar.h"
- #include "amivar.h"
-
- char *get_item_string(LVAL);
-
- #define get_menu_id(m) ((int) getfixnum(slot_value(m, s_id)))
-
- /***********************************************************************/
- /** **/
- /** Support Function **/
- /** **/
- /***********************************************************************/
-
- static LVAL GetMenuList(void){
- return(slot_value(getvalue(s_menu_proto),s_menu_list));}
-
- /* find the position of the item in the menu */
- static int get_item_position(LVAL menu,LVAL item){
- int i;
- LVAL items;
- for(items=slot_value(menu,s_items),i=0;consp(items)&&car(items)!=item;
- i++,items=cdr(items));
- if(item!=car(items))xlfail("item not in the menu");
- return(i);}
-
- /***********************************************************************/
- /** **/
- /** Menu Functions **/
- /** **/
- /***********************************************************************/
-
- int StMObInstalled(LVAL m){
- return(StMObAllocated(m));}
-
- /* find menu object with given hardware address */
- LVAL get_menu_by_hardware(IVIEW_MENU m){
- LVAL menu=0,next;
- for(next=GetMenuList();menu==0&&consp(next);next=cdr(next)){
- if(StMObAllocated(car(next))&&m==get_menu_address(car(next)))menu=car(next);}
- if(!menu)xlfail("can't find menu with this ID");
- return(menu);}
-
- /* find lisp menu with a specified Amiga address */
- /*static LVAL get_menu_by_id(IVIEW_MENU m){
- return(get_menu_by_hardware(m));} not used */
-
- /* allocate an Amiga internal menu */
- static int id_in_use(int id){
- LVAL next;
- for(next=GetMenuList();consp(next);next=cdr(next)){
- if(id==get_menu_id(car(next)))return(TRUE);}
- return(FALSE);}
-
- static unique_id(void){
- static int id=2000;
- if(id>32000)id=2000;
- id++;
- while(id_in_use(id))id++;
- return(id);}
-
- void StMObAllocateMach(LVAL menu){
- int MenuID,i;
- struct SuperMenu *tmptr,*this;
- tmptr=calloc(1,sizeof(struct SuperMenu));
- if(!tmptr)xlfail("menu allocation failed");
- this=Menu_Ptr;
- i=0;
- if(this){ /* find last menu on list */
- i++;
- while(this->Next){
- i++;
- this=this->Next;}
- this->Next=tmptr;}
- else Menu_Ptr=tmptr;
- if(i>30){
- free(tmptr);
- xlfail("no menu space left");}
- tmptr->MenuNum=i;
- tmptr->Title=getstring(slot_value(menu,s_title));
- tmptr->Next=0;
- tmptr->Items=0;
- set_menu_address(tmptr,menu);
- MenuID=unique_id();
- set_slot_value(menu,s_id,cvfixnum((FIXTYPE)MenuID));}
-
- /* dispose of an Amiga internal menu */
- void StMObDisposeMach(LVAL menu){
- int i;
- struct SuperMenu *theMenu,*this,*temp;
- struct SuperMenuItem *tmptr,*ptr;
- if(StMObAllocated(menu)){
- theMenu=get_menu_address(menu);
- this=Menu_Ptr;
- i=0;
- if(this==theMenu){
- temp=this;
- Menu_Ptr=this=this->Next;}
- else {
- while(this->Next&&this->Next!=theMenu){
- i++;
- this=this->Next;}
- if(!this->Next)xlfail("menu not found");
- temp=this->Next;
- this=this->Next=this->Next->Next;}
- while(this){
- this->MenuNum=++i;
- this=this->Next;}
- ptr=temp->Items;
- while(ptr){
- tmptr=ptr;
- ptr=ptr->Next;
- free(tmptr);}
- free(temp);
- StMObInstall(0);}}
-
- /* add items to an Amiga internal menu */
- void StMObAppendItems(LVAL menu,LVAL items){
- LVAL item,key;
- int i;
- struct SuperMenu *theMenu;
- struct SuperMenuItem *tmptr,*this,*next;
- if(StMObAllocated(menu)){
- theMenu=get_menu_address(menu);
- i=llength(slot_value(menu,s_items))-llength(items);
- if(i<0)xlfail("append list should not exceed item list");
- i=0;
- tmptr=this=0;
- next=theMenu->Items;
- while(next){
- i++; /* i is number of items and number for next item */
- this=next;
- next=next->Next;}
- for(;consp(items);items=cdr(items),i++){
- item=car(items);
- tmptr=calloc(1,sizeof(struct SuperMenuItem));
- if(!tmptr)xlfail("menu item allocation failed");
- tmptr->ItemNum=i;
- tmptr->Text=get_item_string(item);
- if(charp(key=slot_value(item,s_key)))tmptr->CmndChar=getchcode(key);
- if(slot_value(item,s_enabled))tmptr->Enabled=1;
- else tmptr->Enabled=0;
- if(this)this->Next=tmptr;
- else theMenu->Items=tmptr;
- this=tmptr;}
- if(tmptr)tmptr->Next=0;
- StMObInstall(menu);}}
-
- /* remove item from an Amiga menu */
- void StMObDeleteItem(LVAL menu,LVAL item){
- int i;
- struct SuperMenu *theMenu;
- struct SuperMenuItem *this,*temp;
- if(StMObAllocated(menu)){
- theMenu=get_menu_address(menu);
- i=get_item_position(menu,item);
- this=theMenu->Items;
- if(i){
- while(this->Next->ItemNum!=i)this=this->Next;
- temp=this->Next;
- this=this->Next=this->Next->Next;}
- else {
- temp=this;
- this=theMenu->Items=this->Next;}
- while(this){
- this->ItemNum=i--;
- this=this->Next;}
- free(temp);
- StMObInstall(menu);}}
-
- /* install an Amiga menu */
- void StMObInstall(LVAL menu){
- struct Window *w;
- struct SuperMenu *mptr;
- struct SuperMenuItem *iptr;
- int i,j;
- if(!Menu_Ptr)return;
- if(menu&&!StMObAllocated(menu))StMObAllocate(menu);
- if(!(mymenu=BuildMenuStripL(Menu_Ptr,8)))xlfail("menu build failed");
- w=screen->FirstWindow;
- while(w){
- ClearMenuStrip(w);
- SetMenuStrip(w,mymenu);
- mptr=Menu_Ptr;
- i=0;
- while(mptr){
- iptr=mptr->Items;
- j=0;
- while(iptr){
- if(!iptr->Enabled)OffMenu(w,i+(j<<5));
- j++;
- iptr=iptr->Next;}
- i++;
- mptr=mptr->Next;}
- w=w->NextWindow;}}
-
- /* remove an Amiga menu */
- void StMObRemove(LVAL menu){
- if(StMObAllocated(menu))StMObDispose(menu);}
-
- /* enable or disable an Amiga menu */
- void StMObEnable(LVAL menu,int enable){
- struct SuperMenu *theMenu,*this;
- struct Window *w;
- short i;
- if(StMObAllocated(menu)){
- theMenu=get_menu_address(menu);
- this=Menu_Ptr;
- i=0;
- while(this->Next&&this!=theMenu){
- i++;
- this=this->Next;}
- if(!this->Next)return;
- w=screen->FirstWindow;
- while(w){
- if(enable)OnMenu(w,i);
- else OffMenu(w,i);
- w=w->NextWindow;}}
- set_slot_value(menu,s_enabled,(enable)?s_true:NIL);}
-
- int StMObPopup(LVAL menu,int left,int top,LVAL window){
- return(0);}
-
- /***********************************************************************/
- /** **/
- /** Menu Item Functions **/
- /** **/
- /***********************************************************************/
-
- /* Get a string for use by AppendMenu. Style info is not encoded. */
- static char *get_item_string(LVAL item){
- LVAL title;/*,key,mark,enabled;
- static char *s;*/
- if(!menu_item_p(item))xlerror("not a menu item", item);
- title=slot_value(item,s_title);
- if(!stringp(title))xlerror("title is not a string", title);
- /* key=slot_value(item, s_key);
- mark=slot_value(item, s_mark);
- enabled=slot_value(item, s_enabled);
- s=buf;
- if(!enabled)s+=sprintf(s,"(");
- if(charp(key))s+=sprintf(s,"/%c",getchcode(key));
- if(mark==s_true)s+=sprintf(s,"!%c",0x12);
- else if(charp(mark))s+=sprintf(s,"!%c",getchcode(key));
- sprintf(s,"%s",getstring(title));*/
- return((char *)getstring(title));}
-
- /* adjust internal implementation of allocated menu to new instance value */
- void StMObSetItemProp(LVAL item,int which){
- struct SuperMenu *theMenu,*mptr;
- struct SuperMenuItem *iptr;
- LVAL menu;
- int j;
- menu=slot_value(item,s_menu);
- if(menu&&StMObAllocated(menu)){
- theMenu=get_menu_address(menu);
- mptr=Menu_Ptr;
- while(mptr&&mptr!=theMenu){
- mptr=mptr->Next;}
- if(!mptr)xlfail("menu not found");
- j=get_item_position(menu,item);
- iptr=theMenu->Items;
- if(j)while(iptr&&iptr->ItemNum!=j)iptr=iptr->Next;
- if(!iptr)xlfail("menu item not found");
- printf("which=%c\n",which);
- switch(which){
- case 'T': {
- LVAL title=slot_value(item,s_title);
- if(!stringp(title))xlerror("title is not a string",title);
- iptr->Text=getstring(title);
- break;}
- case 'K': {
- LVAL key=slot_value(item,s_key);
- if(charp(key))iptr->CmndChar=getchcode(key);
- break;}
- case 'M': {
- LVAL mark=slot_value(item,s_mark);
- if(mark==s_true)iptr->SetFlags|=CHECKIT|MENUTOGGLE|CHECKED;
- else iptr->SetFlags&=~CHECKIT&~MENUTOGGLE&~CHECKED;
- break;}
- case 'S':
- case 'A': break;
- case 'E': {
- if(slot_value(item,s_enabled))iptr->Enabled=1;
- else iptr->Enabled=0;
- break;}
- default: xlfail("unknown item instance variable");}
- StMObInstall(menu);}}
-
- /* about alert for the compiler */
- LVAL xsabout_xlisp_stat(void){
- struct IntuiText text[]={{1,2,JAM2,20,5,0,"Lattice C, V5.05",0},
- {0,1,JAM2,5,4,0,"OK",0}};
- AutoRequest(window,&text[0],0,&text[1],0,0,200,50);
- return(NIL);}
-