/*-------------------------------------------------------------------+ | Copyright (c) 1996, SAS Institute Inc. | | Unpublished - All Rights Reserved | | S A S / C S A M P L E | | | | NAME: OSMENU | | LANGUAGE: C | | PURPOSE: Demonstrate use of the SAS/C FSSL to develop menus, | | submenus, help screens, and error displays. ISPF | | commands are directly supported within the SAS/C | | WD-FSSL environment. | | See SAS/C Full Screen Support Library User's Guide, | | Second Edition. | | SYSTEM NOTES: Written for OS only. The only thing that is | | operating system depenent is the TSO commands. | | INPUT/OUTPUT: via SAS/C FSSL | | | | MVS - | | COMPILE/LINK: SUBMIT prefix.SAMPLE.AUX(OSMENU) | | where "prefix" is the installation defined high-level| | qualifier for the SAS/C product. | | EXECUTE: execute under TSO, see below | | TSO - | | COMPILE: LC370 CLIST | | LINK: CLK370 CLIST | | EXECUTE: CALL your.load.lib(OSMENU) | | | | MISC NOTES: SAS/C FSSL must be installed. | | | +-------------------------------------------------------------------*/ #include #include #include #include #define COMMAND 100 time_t timeval; int field = 1000; struct FS_READPAN input; struct FS_READSCR screen; struct FS_TERMATTR *scr_attr; char command(|131|), errmsg(|132|), tm(|26|); char *menu = "MENU1", *submenu = "MENU2", *error = "ERROR"; char *header = "Simplified TSO Action Menu"; char msg(|6|)(|51|); char *menuline(||) = { /* max length displayed is 40 */ " 0 - Display help on this menu ", " 1 - Request general TSO help ", " 2 - List all user datasets ", " 3 - List all files allocated to session", " 4 - List user profile ", " 5 - Receive current 'sent' messages ", " 6 - List current broadcast messages ", " 7 - Display status of running jobs ", " 8 - Log onto another system ", " 9 - Enter any TSO command " }; char *menucmd(||) = { /* corresponding command */ "n/a", "tso: help", "tso: listc", "tso: listalc", "tso: profile", "tso: receive", "tso: listbc", "tso: status", "n/a", "n/a" }; /*-------------------------------------------------------------------+ | The main is used to start the full screen environment, define each | | of the different panels which will be displayed, and then display | | the main panel waiting for input. Upon input it will decide what | | was requested and respond accordingly. | +-------------------------------------------------------------------*/ main() { /*----------------------------------------------------------------+ | define the main menu and sub-menu panels | +----------------------------------------------------------------*/ fsinit(errmsg); scr_attr = fsrttm(); define_main(); define_sub(); define_error(); /*----------------------------------------------------------------+ | Display main menu panel, wait for input and then decide which | | command was requested. | +----------------------------------------------------------------*/ for (;;) { /* update the panel to reflect any changes */ time(&timeval); strcpy(tm, ctime(&timeval)); memset(command, 0, sizeof(command)); fsdspn(menu, 0, 1, 1, COMMAND, 1, FS_FORCE); /* wait for input from the user */ screen = fsrdsc(); if ((screen.aid == PF_3) || (screen.aid == PF_15)) { fsterm(); exit(EXIT_SUCCESS); } /* read the panel...update input from user */ input = fsrdpn(menu); /* decide what user asked for... */ if (*command == '0') /* menu help */ noop(0); else if (*command == '1') /* general help */ system(menucmd(|1|)); else if (*command == '2') /* list user datasets */ system(menucmd(|2|)); else if (*command == '3') /* list allocated dsn */ system(menucmd(|3|)); else if (*command == '4') /* display user profile */ system(menucmd(|4|)); else if (*command == '5') /* receive messages */ system(menucmd(|5|)); else if (*command == '6') /* list broadcast msgs */ system(menucmd(|6|)); else if (*command == '7') /* display job status */ system(menucmd(|7|)); else if (*command == '8') /* log onto system */ noop(1); else if (*command == '9') { /* submenu selection */ memset(command, '\0', 130); /* display new menu and wait for user response */ fsdspn(submenu, 0, 1, 1, 0, 0, FS_FORCE); screen = fsrdsc(); if (screen.aid == ENTER_KEY) { input = fsrdpn(submenu); memcpy(command, "TSO:", 4); /* make it one command */ strcat(command, command+5); strcat(command, command+46); strcat(command, command+86); system(command); } else input = fsrdpn(submenu); /* clear input pending */ } } return(0); } /*-------------------------------------------------------------------+ | This routine will decide which display to generate and then store | | the message into the error/message display panel fields | +-------------------------------------------------------------------*/ noop(code) int code; { int i; /*----------------------------------------------------------------+ | clear message display area and then set error (or message) | | display. | +----------------------------------------------------------------*/ for (i=0; i<6; i++) memset(msg(|i|), ' ', 50); if (code == 1) { strcpy(msg(|0|), "----------------> W A R N I N G <-----------------"); strcpy(msg(|1|), "It has been determined that you are not authorized"); strcpy(msg(|2|), "for the action requested. Information concerning "); strcpy(msg(|3|), "your userid, name, location, and phone have been "); strcpy(msg(|4|), "entered into an access violation database. "); strcpy(msg(|5|), "----------------> W A R N I N G <-----------------"); } else return(1); /*----------------------------------------------------------------+ | display message and wait for user to read and press PF/enter key| +----------------------------------------------------------------*/ fsdspn(error, 0, 1, 1, 0, 0, FS_FORCE | FS_IGNINPUT); screen = fsrdsc(); input = fsrdpn(error); return(0); } /*-------------------------------------------------------------------+ |+------------------------------------------------------------------+| ||NOTE: The following routines are used only to define the display || || panels. They could be dynamically loaded at the beginning || || of the program and then unloaded since they are needed only|| || at that time. This would then free up this memory. || |+------------------------------------------------------------------+| +-------------------------------------------------------------------*/ /*-------------------------------------------------------------------+ | This routine is used to define the main menu screen. | +-------------------------------------------------------------------*/ define_main() { int i, len, row, col, color; static char userid(|L_cuserid+1|), sname(|11|), ename(|11|); static int battr, sattr, sattr2, mattr, battr2, tattr; static char *mtitle, *tb1, *tb2; /*----------------------------------------------------------------+ | define panel and size | +----------------------------------------------------------------*/ fsdfpn(menu, scr_attr->prim_row, scr_attr->prim_col); /*----------------------------------------------------------------+ | define fields for the border | +----------------------------------------------------------------*/ battr = PROTECTED | REVERSE_VIDEO | BRIGHT; color = RED; len = (scr_attr->prim_col - 2) + 1; tb1 = malloc(len + 3); border(menu, tb1, 1, scr_attr->prim_row, 2, scr_attr->prim_col, &battr, color, len, " ", " ", " "); len -= 4; /*----------------------------------------------------------------+ | define field for title | +----------------------------------------------------------------*/ tattr = PROTECTED | BRIGHT; color = MAGENTA; mtitle = malloc(len + 3); title(menu, header, mtitle, 2, 4, &tattr, color, len); /*----------------------------------------------------------------+ | define selection line fields | +----------------------------------------------------------------*/ row = 3; col = 4; sattr = PROTECTED; color = BLUE; fsdffd(menu, field++, row, col, 12, "SELECTION==>", &sattr, color, BLANK); col += 13; sattr2= BRIGHT | AUTOREAD; color = WHITE; fsdffd(menu, COMMAND, row, col, 2, command, &sattr2, color, BLANK); /*----------------------------------------------------------------+ | define fields on menu | +----------------------------------------------------------------*/ row += 3; col = 20; mattr = PROTECTED; color = YELLOW; for (i=0; i<=9; i++) { fsdffd(menu, field++, row, col, 40, menuline(|i|), &mattr, color, BLANK); row += 1; } /*----------------------------------------------------------------+ | define fields for misc information (at bottom of screen) | +----------------------------------------------------------------*/ row = scr_attr->prim_row - 3; col = 4; battr2= PROTECTED; color = GREEN; len = (scr_attr->prim_col - (col * 2)) + 3; tb2 = malloc(len + 3); border(menu, tb2, row, (scr_attr->prim_row-1), col, (scr_attr->prim_col-2), &battr2, color, len, "+", "-", "|"); row++; strcpy(sname, sysname()); fsdffd(menu, field++, row, 6, 10, sname, &battr2, color, BLANK); strcpy(ename, envname()); fsdffd(menu, field++, row, 20, 10, ename, &battr2, color, BLANK); cuserid(userid); fsdffd(menu, field++, row, 35, L_cuserid, userid, &battr2, color, BLANK); time(&timeval); strcpy(tm, ctime(&timeval)); fsdffd(menu, field++, row, 40+L_cuserid, 24, tm, &battr2, color, BLANK); return(0); } /*-------------------------------------------------------------------+ | This routine creates the TSO command entry screen | +-------------------------------------------------------------------*/ define_sub() { int color, len; static int tsoattr, cmdattr, tattr; static char *stitle; /*----------------------------------------------------------------+ | define panel and size | +----------------------------------------------------------------*/ fsdfpn(submenu, scr_attr->prim_row, scr_attr->prim_col); /*----------------------------------------------------------------+ | define field for title of submenu | +----------------------------------------------------------------*/ len = scr_attr->prim_col - 1; tattr = PROTECTED | BRIGHT; color = GREEN; stitle = malloc(len + 4); title(submenu, "TSO Command Entry Screen", stitle, 1, 2, &tattr, color, len); /*----------------------------------------------------------------+ | define field for TSO input | +----------------------------------------------------------------*/ tsoattr = BRIGHT | PROTECTED; color = MAGENTA; fsdffd(submenu, field++, 8, 2, 20, "Enter TSO Command==>", &tsoattr, color, BLANK); cmdattr = BRIGHT | AUTOREAD | REVERSE_VIDEO; color = YELLOW; fsdffd(submenu, field++, 8, 25, 40, command+5, &cmdattr, color, NULL); fsdffd(submenu, field++, 9, 25, 40, command+46, &cmdattr, color, NULL); fsdffd(submenu, field++, 10, 25, 40, command+86, &cmdattr, color, NULL); return(0); } /*-------------------------------------------------------------------+ | This routine defines the error/message display panel | +-------------------------------------------------------------------*/ define_error() { int len, color; static int errbattr, errmattr, rattr; static char *etb1; /*----------------------------------------------------------------+ | define panel and size | +----------------------------------------------------------------*/ fsdfpn(error, scr_attr->prim_row, scr_attr->prim_col); /*----------------------------------------------------------------+ | define fields for the border | +----------------------------------------------------------------*/ errbattr = PROTECTED | REVERSE_VIDEO | BRIGHT; color = RED; len = (scr_attr->prim_col - 2) + 1; etb1 = malloc(len + 3); border(error, etb1, 1, scr_attr->prim_row, 2, scr_attr->prim_col, &errbattr, color, len, " ", " ", " "); /*----------------------------------------------------------------+ | define fields for message display | +----------------------------------------------------------------*/ errmattr = PROTECTED | BRIGHT; color = WHITE; fsdffd(error, field++, 10, 15, 50, msg(|0|), &errmattr, color, BLANK); fsdffd(error, field++, 11, 15, 50, msg(|1|), &errmattr, color, BLANK); fsdffd(error, field++, 12, 15, 50, msg(|2|), &errmattr, color, BLANK); fsdffd(error, field++, 13, 15, 50, msg(|3|), &errmattr, color, BLANK); fsdffd(error, field++, 14, 15, 50, msg(|4|), &errmattr, color, BLANK); fsdffd(error, field++, 15, 15, 50, msg(|5|), &errmattr, color, BLANK); /*----------------------------------------------------------------+ | tell user how to get rid of current display | +----------------------------------------------------------------*/ rattr = PROTECTED | BRIGHT; color = BLUE; fsdffd(error, field++, scr_attr->prim_row-3, 14, 52, "Press any PF key or enter to return to the main menu", &rattr, color, BLANK); return(0); } /*-------------------------------------------------------------------+ | This routine is used to define all the fields needed to create the | | look of a border. | +-------------------------------------------------------------------*/ border(panel, tb, r1, r2, c1, c2, attr, color, len, cor, hor, ver) char *panel, *tb; int r1, r2, c1, c2, *attr, color, len; char *cor, *hor, *ver; { int row; /*----------------------------------------------------------------+ | define fields to create the border | +----------------------------------------------------------------*/ memset(tb, '\0', (len+2)); memset(tb, *hor, len); /* create the horizontal field */ *tb = *cor; *(tb+len-1) = *cor; /* define field on top - only one needed */ fsdffd(panel, field++, r1, c1, len, tb, attr, color, BLANK); /* define field on bottom - only one needed */ fsdffd(panel, field++, r2, c1, len, tb, attr, color, BLANK); /* define fields on left/right - one field needed for each row */ /* and each side. */ for (row=r1+1; row