/*-------------------------------------------------------------------+
| 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 <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 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
|