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