/*-------------------------------------------------------------------+
| Copyright (c) 1996, SAS Institute Inc. |
| Unpublished - All Rights Reserved |
| S A S / C S A M P L E |
| |
| NAME: CALENDAR |
| LANGUAGE: C |
| PURPOSE: This program demonstrates the use of the SAS/C FSSL. |
| It implements a daily calendar, allowing you to |
| enter reminders for different times during the day, |
| scroll forward and backward and save the entries |
| from one session to the next. |
| See SAS/C Full Screen Support Library User's Guide, |
| Second Edition, Chapter 3, pgs. 108-116. |
| SYSTEM NOTES: This routine will run on either CMS or TSO |
| |
| MVS - |
| COMPILE, LINK: SUBMIT prefix.SAMPLE.AUX(CALENDAR) |
| 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(CALENDAR) |
| CMS - |
| COMPILE: GLOBAL MACLIB LC370 L$FSSL |
| LC370 CALENDAR (EXTNAME |
| LINK: GLOBAL TXTLIB LC370BAS LC370STD L$FSSL |
| CLINK CALENDAR (GENMOD |
| EXECUTE: CALENDAR |
| |
| MISC NOTES: SAS/C FSSL must be installed. |
| A relative access file must be allocated as CALENDAR;|
| (characteristics: RECFM=FBS) |
| |
+-------------------------------------------------------------------*/
#include <lcio.h>
#include <time.h>
#include <fcntl.h>
#include <stdlib.h>
#include <l$fappl.h>
#define TRUE 1
#define FALSE 0
#define MAX_ENTRY 17
#define MAX_LINE 60
struct FS_TERMATTR * scr_attr;
struct FS_READPAN input;
struct FS_READSCR screen;
FILE * fp;
char * calndr = "panel1";
char * timestr;
char errmsg(|132|);
char status(|51|);
int fldno = 10000;
int row, col;
int days = 0;
time_t today;
/* calendar page structure */
struct CALENDAR_PAGE {
char userid(|L_cuserid+1|);
time_t datetime;
char *times(|MAX_ENTRY|);
char entry(|MAX_ENTRY|)(|MAX_LINE+1|);
} calpage;
/*-------------------------------------------------------------------+
| The main routine will initialize, and then accept input from the |
| user. Upon input it will decide whether to save or how to scroll |
| through the entries. |
+-------------------------------------------------------------------*/
main()
{
int rc;
/* initialize */
time(&today);
set_times();
/* enter full screen mode and define layout */
screen_layout();
/* open calendar saved entry file and find today's entry */
calndr_save(0);
calpage.datetime = today;
timestr = ctime(&calpage.datetime);
rc = calndr_save(-1);
if (!rc) {
calndr_init();
}
/* continue while user wants to... */
/* after each input check the user's response; */
/* this response can be either PFkeys or data (enter key) */
while (TRUE) {
/* display panel */
if (days < 0)
strcpy(status, "Input will be ignored");
else
strcpy(status,
"PF 3-END, 7/8-Back/Forward, 12-'today', ENTER-save");
rc = fsdspn(calndr, 0, 1, 1, 0, 0, FS_FORCE);
if (rc != FS_OK && rc != FS_DFLTVIEW) {
fsterm();
printf("ERROR: panel display failure\n");
exit(EXIT_FAILURE);
}
/* wait for input from user */
screen = fsrdsc();
/* check for 'the end' */
if ( (screen.aid == PF_3) || (screen.aid == PF_15) ) {
fsterm();
fclose(fp);
return(0);
}
/* read calendar entry fields */
input = fsrdpn(calndr);
/* enter? save entry only if in future */
if (screen.aid == ENTER_KEY) {
if (days >= 0)
calndr_save(1);
}
/* scroll through calendar? */
/* forward... */
if (screen.aid == PF_8) {
days++;
calpage.datetime = today + (days * 86400);
rc = calndr_save(-1);
if (!rc) {
calndr_init();
}
}
/* backward... */
else if (screen.aid == PF_7) {
days--;
calpage.datetime = today + (days * 86400);
rc = calndr_save(-1);
if (!rc) {
calndr_init();
}
}
/* go back to today... */
else if (screen.aid == PF_12) {
days = 0;
calpage.datetime = today + (days * 86400);
rc = calndr_save(-1);
if (!rc) {
calndr_init();
}
}
timestr = ctime(&calpage.datetime);
}
}
/*-------------------------------------------------------------------+
| This routine creates the full screen image. It sets up the full |
| screen environment, defines the panel, defines all the fields, |
| and other misc initial fs needs. |
+-------------------------------------------------------------------*/
screen_layout()
{
int rc, color, i, even, xlen;
time_t currtime;
char *p;
static char temptime(|26|);
static int attr, attr2;
static char xline(|81|);
/* get FS mode up */
if ((rc = fsinit(errmsg)) != FS_OK) {
fsterm();
printf("ERROR: initialization failure\n");
exit(EXIT_FAILURE);
}
/* get screen attribute capability */
if ((int)(scr_attr = fsrttm()) == FS_INITERR) {
fsterm();
printf("ERROR: terminal read failure\n");
exit(EXIT_FAILURE);
}
/* set line separator */
memset(xline, '-', scr_attr->prim_col-1);
xline(|scr_attr->prim_col|) = '\0';
xlen = strlen(xline);
/* define panel size */
if ((rc = fsdfpn(calndr, scr_attr->prim_row, scr_attr->prim_col))
!= FS_OK) {
fsterm();
printf("ERROR: panel definition failure\n");
exit(EXIT_FAILURE);
}
/* display title */
row = 1;
title(calndr, "Calendar Keeper", row);
/* display user's name (ie: id) */
row += 2;
col = 10;
attr = BRIGHT | PROTECTED;
color = BLUE;
cuserid(calpage.userid);
fsdffd(calndr, fldno++, row, col, L_cuserid, calpage.userid,
&attr, color, BLANK);
/* current date... */
col += L_cuserid + 30;
time(&currtime);
p = ctime(&currtime);
strcpy(temptime, p);
fsdffd(calndr, fldno++, row, col, 25, temptime,
&attr, color, BLANK);
/* separate screen...visible effect only */
row++;
color = RED;
fsdffd(calndr, fldno++, row, 2, xlen, xline, &attr, color, BLANK);
/* calendar date - start with today */
row += 2;
col = 10;
color = CYAN;
fsdffd(calndr, fldno++, row, col, 14, "Calendar Date:",
&attr, color, BLANK);
col += 15;
time(&calpage.datetime);
timestr = ctime(&calpage.datetime);
fsdffd(calndr, fldno++, row, col, 25, timestr,
&attr, color, BLANK);
/* create fields for actual calendar entries */
even = TRUE;
attr2 = BRIGHT | AUTOREAD;
for (i=0; iprim_col+3));
memset(work, '-', scr_attr->prim_col);
*(work+scr_attr->prim_col) = '\0';
len = strlen(ttl);
bg = (scr_attr->prim_col / 2) - (len / 2);
memcpy(work+bg-2, " ", 2);
memcpy(work+bg, ttl, len);
memcpy(work+bg+len, " ", 2);
/* display title */
fsdffd(panel, fldno++, row, 2, scr_attr->prim_col-1, work,
&attr, color, BLANK);
return(0);
}
/*-------------------------------------------------------------------+
| This routine will handle all requests for I/O for the calendar |
| entry dataset. Valid requests are: |
| -1 = read request |
| 0 = open request |
| 1 = write request |
| Note: The I/O is a simply brute force method and does not attempt |
| to show good/effecient I/O access. |
+-------------------------------------------------------------------*/
calndr_save(type)
int type;
{
static long pos;
struct CALENDAR_PAGE day;
char p(|4|);
int rc, i;
/* open request */
if (type == 0) {
quiet(TRUE);
fp = fopen("CALENDAR", "rb+");
if (fp == NULL) fp = fopen("CALENDAR", "wb+");
if (fp == NULL) {
printf("ERROR: open error on CALENDAR\n");
exit(EXIT_FAILURE);
}
quiet(FALSE);
pos = -1;
}
/* read request */
else if (type == -1) {
/* start search...search in a straight brute force way */
rewind(fp);
/* ok, search */
while (TRUE) {
pos = ftell(fp);
quiet(TRUE);
rc = fread((char*)&day, sizeof(day), 1, fp);
quiet(FALSE);
if (rc == 0) {
pos = -1;
clearerr(fp);
return(FALSE);
}
/* check if entry read is one requested...same day */
memcpy(p, ctime(&calpage.datetime), 3);
p(|3|) = '\0';
if ( (difftime(calpage.datetime, day.datetime) < 86400) &&
(memcmp(p, ctime(&day.datetime), 3) == 0) ) {
/* found it...copy entry */
for (i=0; i
|