/*-------------------------------------------------------------------+
| Copyright (c) 1996, SAS Institute Inc. |
| Unpublished - All Rights Reserved |
| S A S / C S A M P L E |
| |
| NAME: CMSMENU |
| LANGUAGE: C |
| PURPOSE: Demonstrate use of the SAS/C FSSL to develop menus, |
| submenus, help screens, and error displays |
| SYSTEM NOTES: Written for CMS only. The only thing that is |
| operating system dependent is the CMS commands. |
| INPUT: via SAS/C FSSL |
| OUTPUT: via SAS/C FSSL |
| |
| CMS - |
| COMPILE: GLOBAL MACLIB LC370 L$FSSL |
| LC370 CMSMENU |
| LINK: GLOBAL TXTLIB LC370BAS LC370STD L$FSSL |
| CLINK CMSMENU (GENMOD |
| EXECUTE: CMSMENU |
| |
| MISC NOTES: SAS/C FSSL *must* be installed. |
| See OSMENU for an OS version of this program. |
| |
+-------------------------------------------------------------------*/
#include <lcio.h>
#include <lclib.h>
#include <time.h>
#include <l$fappl.h>
#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 CMS Action Menu";
char msg[6][51];
char *menuline[] = { /* max length displayed is 40 */
" 0 - Display help on this menu ",
" 1 - Request general CMS help ",
" 2 - List all datasets on the Adisk ",
" 3 - List all minidisks attached ",
" 4 - Display all libraries globalled ",
" 5 - Display 'all' information ",
" 6 - Display files currently FILEDEFed ",
" 7 - Display all jobs in virtual reader ",
" 8 - Log onto another system ",
" 9 - Enter any CMS command " };
char *menucmd[] = { /* corresponding command */
"n/a",
"cms: help",
"cms: filel",
"cms: q disk",
"cms: q library",
"cms: q all",
"cms: file",
"cms: rdrlist",
"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, "CMS:", 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 <-----------------");
}
/*----------------------------------------------------------------+
| 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 CMS 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, "CMS Command Entry Screen", stitle,
1, 2, tattr, color, len);
/*----------------------------------------------------------------+
| define field for CMS input |
+----------------------------------------------------------------*/
tsoattr = BRIGHT | PROTECTED;
color = MAGENTA;
fsdffd(submenu, field++, 8, 2, 20, "Enter CMS 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
|