home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------------*/
- /* */
- /* XBBS SOURCE CODE copyright (c) 1990 by M. Kimes */
- /* All Rights Reserved */
- /* */
- /* For complete details of the licensing restrictions, please refer */
- /* to the License agreement, which is published in its entirety in */
- /* the in the file LICENSE.XBS. */
- /* */
- /* USE OF THIS FILE IS SUBJECT TO THE RESTRICTIONS CONTAINED IN THE */
- /* XBBS LICENSING AGREEMENT. IF YOU DO NOT FIND THE TEXT OF */
- /* THIS AGREEMENT IN ANY OF THE AFOREMENTIONED FILES, OR IF YOU DO */
- /* NOT HAVE THESE FILES, YOU SHOULD IMMEDIATELY CONTACT M. KIMES */
- /* AT THE ADDRESS LISTED BELOW. IN NO EVENT SHOULD YOU PROCEED TO USE */
- /* THIS FILE WITHOUT HAVING ACCEPTED THE TERMS OF THE XBBS LICENSING */
- /* AGREEMENT, OR SUCH OTHER AGREEMENT AS YOU ARE ABLE TO REACH WITH */
- /* M. KIMES */
- /* */
- /* */
- /* You can contact M. Kimes at the following address: */
- /* */
- /* M. Kimes 1:380/16.0@FidoNet */
- /* 542 Merrick (318)222-3455 data */
- /* Shreveport, LA 71104 */
- /* */
- /* */
- /* Please feel free to contact me at any time to share your comments about */
- /* my software and/or licensing policies. */
- /* */
- /*--------------------------------------------------------------------------*/
- /****************************************************************************/
- /* XMenu.C (Menu handler) */
- /* */
- /* Menu format (flat ASCII file): */
- /* First line: Menu ID (not used by XBBS) */
- /* Second line: Prompt for this menu */
- /* Third line: Help prompt # in XBBS.TXT (or 0) for this menu */
- /* Fourth line: Color for prompt this menu */
- /* Fifth line: Prompt for this entry */
- /* Sixth line: Key for this entry */
- /* Seventh line: Action for this entry */
- /* Eighth line: Security masks for this entry */
- /* Ninth line: Bitmask for this entry */
- /* Tenth line: Age mask for this entry */
- /* Eleventh line: Misc data for this entry */
- /* Twelvth line: Color for this entry */
- /* Thirteenth line...nth line: Repeat from fifth */
- /* There can be a maximum of 50 entries per menu */
- /* If a line is blank, it must still be included */
- /* This sorta-ASCII format should make it easy for anyone to write a menu */
- /* editor or generator even in QuickBASIC or XBASIC. There will be a slight*/
- /* sacrifice in speed when XBBS first loads the menu; should be negligible. */
- /****************************************************************************/
-
- #include "msg.h"
- #include "xext.h"
-
- struct _menu {
- char prompt[81];
- char key;
- char action;
- char data[133];
- char color;
- };
-
-
- char pascal do_hot (struct _menu **m,char num,char *hotone);
- char pascal do_item (struct _menu **m,char which);
-
-
-
- void pascal xmenu (char *menuname) {
-
- struct _menu *m[50];
- char num,x,keyin;
- int handle,test;
- register int y;
- char s[133];
- char *p;
- char prompt[81];
- word mhelpnum;
- char promptcolor;
- char hotone;
- struct _color {
- bit fore: 3;
- bit flash: 1;
- bit back: 3;
- bit hi: 1;
- };
- union __COLOR__ {
- struct _color c;
- char cl;
- } cr;
-
- for(y=0;y<50;y++) m[y]=NULL;
-
- ReStart:
-
- for(y=0;y<50;y++) {
- if(m[y])ffree(m[y]);
- m[y]=NULL;
- }
-
- handle=oopen(menuname,O_RDONLY | O_BINARY | O_DENYWRITE);
- if(handle==-1) goto OutAHere;
- num=0;
-
- if(!fgetsx(s,133,handle)) {
- cclose(handle);
- goto OutAHere;
- }
- if(!fgetsx(s,133,handle)) {
- cclose(handle);
- goto OutAHere;
- }
- s[80]=0;
- stripcr(s);
- strcpy(prompt,s);
- if(!fgetsx(s,133,handle)) {
- cclose(handle);
- goto OutAHere;
- }
- mhelpnum=(word)atol(s);
- if(!fgetsx(s,133,handle)) {
- cclose(handle);
- goto OutAHere;
- }
- promptcolor=(char)atoi(s);
-
- while(num<50 && !eof(handle)) { /* Load up to 50 menu items */
- Continue:
- if(m[num]==NULL) {
- m[num]=(struct _menu *)mmalloc(sizeof(struct _menu));
- if(m[num]==NULL) break;
- }
- if(!fgetsx(s,133,handle)) break;
- stripcr(s);
- s[79]=0;
- strcpy(m[num]->prompt,s);
- x=strlen(m[num]->prompt);
- if(m[num]->prompt[x-1]==';') {
- m[num]->prompt[x-1]=0;
- }
- else strcat(m[num]->prompt,"\n");
- if(!fgetsx(s,133,handle)) break;
- stripcr(s);
- m[num]->key=toupper(*s);
- if(!fgetsx(s,133,handle)) break;
- m[num]->action=(char)atoi(s);
- /* Security checking for this item */
- if(!fgetsx(s,133,handle)) break;
- s[132]=0;
- stripcr(s);
- p=strtok(s," ");
- if(p) {
- keyin=0;
- do {
- if(keyin==10) break;
- if((word)atol(p)>user.stat[keyin]) goto Continue;
- keyin++;
- } while(p=strtok(0," "));
- }
- if(!fgetsx(s,133,handle)) break;
- test=(word)atol(s);
- if(test) {
- for(y=0;y<16;y++) {
- if(test & (1<<y)) {
- if(!(user.attr2 & (1<<y))) {
- goto Continue;
- }
- }
- }
- }
- if(!fgetsx(s,133,handle)) break;
- test=atoi(s);
- if(test) {
- if(test<0) {
- if(age>(char)test) continue;
- }
- else {
- if(age<(char)test) continue;
- }
- }
- /* End security checking--if he got here, he has access */
- if(!fgetsx(s,133,handle)) break;
- s[132]=0;
- stripcr(s);
- strcpy(m[num]->data,s);
- if(!fgetsx(s,133,handle)) break;
- m[num]->color=(char)atoi(s);
- num++;
- }
- cclose(handle);
- if(!num) {
- OutAHere:
- for(y=0;y<50;y++) {
- if(m[y]) ffree(m[y]);
- }
- return;
- }
- Loop:
- cls();
- pauser=0;
- if(m[0]->key!=0 && !user.cold) {
- keyin=do_hot(m,num,&hotone);
- if(keyin==255) goto OutAHere;
- if(keyin==1) {
- menuname=m[hotone]->data;
- goto ReStart;
- }
- if(keyin!=0) goto Loop;
- }
- if(m[0]->key==0) {
- keyin=do_item(m,0);
- if(keyin==255) goto OutAHere;
- if(keyin==1) {
- menuname=m[0]->data;
- goto ReStart;
- }
- }
- for(x=0;x<num;x++) {
-
- if(m[x]->color && user.graphics) {
-
- /* Translate 1-byte color code to ANSI string. Note that a 0
- byte skips sending a string (so common-colored prompts
- need not waste time resending the same old string). Also
- note that, therefore, one color combination is unavailable:
- dim black-on-black. Somehow I imagine you'll be able to
- live without it.
- See union __COLOR__ definition above for how the bits
- in the char are used.
- Note that while I used a union, similar results can be
- obtained by bit-shifting or selective and/or/not usage.
- */
-
- char tempfore[8];
- char tempback[8];
-
- cr.cl=m[x]->color;
- if(cr.c.hi) strcpy(s,"\x1b[0;1;");
- else strcpy(s,"\x1b[0;2;");
- if(cr.c.flash) strcat(s,"5;");
- sprintf(tempfore,"%u;",cr.c.fore+30);
- sprintf(tempback,"%um",cr.c.back+40);
- strcat(s,tempfore);
- strcat(s,tempback);
- printm(s);
- }
-
- if(*m[x]->prompt) printm(convertstring(m[x]->prompt));
- if(m[0]->key!=0 && !user.cold) {
- keyin=do_hot(m,num,&hotone);
- if(keyin==255) goto OutAHere;
- if(keyin==1) {
- menuname=m[hotone]->data;
- goto ReStart;
- }
- if(keyin!=0) goto Loop;
- }
- if(x<num) {
- if(m[x+1]->key==0) {
- keyin=do_item(m,x+1);
- if(keyin==255) goto OutAHere;
- if(keyin==1) {
- menuname=m[x+1]->data;
- goto ReStart;
- }
- }
- }
- }
- if(promptcolor && user.graphics) {
- /* Translate 1-byte color code to ANSI */
-
- char tempfore[8];
- char tempback[8];
-
- cr.cl=promptcolor;
- if(cr.c.hi) strcpy(s,"\x1b[0;1;");
- else strcpy(s,"\x1b[0;2;");
- if(cr.c.flash) strcat(s,"5;");
- sprintf(tempfore,"%u;",cr.c.fore+30);
- sprintf(tempback,"%um",cr.c.back+40);
- strcat(s,tempfore);
- strcat(s,tempback);
- printm(s);
- }
- gprintf(0,"%s ",convertstring(prompt));
- ReLoop:
- helpnum=mhelpnum;
- keyin=toupper(*genin(1,0,1,1,ALLL));
- helpnum=0;
- if(keyin==0) goto Loop;
- for(x=0;x<num;x++) {
- if(keyin==m[x]->key) {
- keyin=do_item(m,x);
- if(keyin==1) {
- menuname=m[x]->data;
- goto ReStart;
- }
- if(keyin==255) goto OutAHere;
- goto Loop;
- }
- }
- printm(BACKSPACE);
- goto ReLoop;
- }
-
-
- char pascal do_hot (struct _menu **m,char num,char *hotone) {
-
- char keyin;
- register int x;
-
- keyin=toupper(inkey()); /* Check for hot keypress */
- if(keyin) {
- for(x=0;x<num;x++) {
- if(keyin==m[x]->key) {
- *hotone=(char)x;
- return do_item(m,x);
- }
- }
- }
- return 0;
- }
-
-