home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- *******************************************************************************
-
- Site: Western Michigan University Academic Computer Center
-
- System: Directory/File System Maintenance
-
- Program: maint
-
- Version=01 Level=00 01/24/92 Leonard J. Peirce
-
- Purpose: Screen-handling routines. Initialization, messages, etc.
-
- Arguments: See individual routines
-
- External variables: See individual routines
-
- External functions:
-
- Defined: clean_up, clear_mess, erase_tag, highlite, info_mess,
- initialize, prompt_getstr, put_buf, put_options,
- put_pagnum, put_slot, put_spec, put_stat,
- resize_screen, screen_reset, tag_file, write_mess,
- xmess
-
- Called: file_search, get_scr_num, make_slot, set_nodes
-
- Files accessed: None
-
- Return codes: See individual routines
-
- Compiling instructions: See Makefile
-
- Linking instructions: See Makefile
-
- Other information: Copyright (C) 1992, Leonard J. Peirce
-
- ********************************************************************************
- *******************************************************************************/
-
- /******************************************************************************/
- /* */
- /* # I N C L U D E F I L E S */
- /* */
- /******************************************************************************/
-
- #ifdef ultrix
- #include <cursesX.h>
- #else
- #include <curses.h>
- #endif
- #include <sys/param.h>
- #include <stdio.h> /* who knows? (NULL maybe?) */
- #include <ctype.h>
- #include <signal.h>
- #include <string.h>
- #if !defined(SYSV) || defined(sun)
- #include <sys/types.h>
- #endif
- #include <memory.h>
- #include "maint.h" /* our very own header file */
-
- /******************************************************************************/
- /* */
- /* # D E F I N E S */
- /* */
- /******************************************************************************/
-
- /******************************************************************************/
- /* */
- /* S T R U C T U R E S , U N I O N S , T Y P E D E F S */
- /* */
- /******************************************************************************/
-
- /******************************************************************************/
- /* */
- /* E X T E R N A L D E F I N I T I O N S & D E C L A R A T I O N S */
- /* */
- /******************************************************************************/
-
- extern WINDOW *stat_win,
- *spec_win,
- *main_win;
-
- extern int main_rows,
- make_slot(),
- strtcpy(),
- file_search();
-
- extern short get_scr_num();
-
- extern void set_nodes(),
- cont_after_stop();
-
- int put_slot(),
- put_buf();
-
- void initialize(),
- put_stat(),
- put_spec(),
- put_pagnum(),
- put_options(),
- prompt_getstr(),
- screen_reset(),
- clear_mess(),
- highlite(),
- write_mess(),
- tag_file(),
- erase_tag(),
- clean_up(),
- resize_screen();
-
- /******************************************************************************/
- /* */
- /* S T A T I C D E F I N I T I O N S & D E C L A R A T I O N S */
- /* */
- /******************************************************************************/
-
- static char user_erase = '\0';
-
- static int put_line();
-
- static void adjust_str();
-
- /*******************************************************************************
- ********************************************************************************
-
- Function: initialize
-
- Purpose: Allocate all of the windows that will be needed and initialize
- all of the screen parameters needed.
-
- Global variables:
-
- Name Examine/Modify/Use/Read/Write
- ---- -----------------------------
- main_rows X
- user_erase X X
- LINES X
- COLS
-
- Return Codes:
-
- Code Reason
- ---- ------
- none
-
- ********************************************************************************
- *******************************************************************************/
-
- void initialize(spec_win,main_win,stat_win,node_row_max,node_col_max)
- /******* FORMAL PARAMETERS *******/
- WINDOW **spec_win, /* window for directory spec/page # */
- **main_win, /* window where files are displayed */
- **stat_win; /* summary stats window */
- u_short *node_row_max, /* max. number of rows in nodes array */
- *node_col_max; /* max. # of columns in nodes array */
-
- { /*** initialize ***/
-
- initscr(); /* start things off */
- signal(SIGHUP,clean_up); /* catch interrupt and clean up */
- signal(SIGINT,clean_up); /* catch interrupt and clean up */
- signal(SIGQUIT,clean_up); /* catch interrupt and clean up */
- signal(SIGILL,clean_up); /* catch interrupt and clean up */
- signal(SIGFPE,clean_up); /* catch interrupt and clean up */
- signal(SIGBUS,clean_up); /* catch interrupt and clean up */
- signal(SIGSEGV,clean_up); /* catch interrupt and clean up */
- signal(SIGSYS,clean_up); /* catch interrupt and clean up */
- signal(SIGPIPE,clean_up); /* catch interrupt and clean up */
- signal(SIGALRM,clean_up); /* catch interrupt and clean up */
- signal(SIGTERM,clean_up); /* catch interrupt and clean up */
- /* signal(SIGCONT,resize_screen); /* resize and repaint screen */
- signal(SIGWINCH,resize_screen); /* resize and repaint screen */
-
- #ifndef DEBUG
- nonl(); /* turn off for debugging */
- #endif
-
- cbreak();
- noecho();
- user_erase = erasechar();
-
- /* allocate all of the windows that we will need */
-
- *spec_win = newwin(SPEC_WINDOW_ROWS,COLS,SPEC_WINDOW_START_ROW,0);
-
- main_rows = LINES - (SPEC_WINDOW_ROWS + STAT_WINDOW_ROWS);
- *main_win = newwin(main_rows,COLS,SPEC_WINDOW_ROWS,0);
-
- *stat_win = newwin(STAT_WINDOW_ROWS,COLS,SPEC_WINDOW_ROWS+main_rows,0);
-
- if(main_rows > MAX_NODE_ROW)
- *node_row_max = MAX_NODE_ROW;
- else
- *node_row_max = main_rows - 1;
-
- *node_col_max = MAX_NODE_COL;
-
- /* set some attributes for the windows */
-
- wattron(*spec_win,A_REVERSE);
- wattron(*stat_win,A_REVERSE);
- keypad(*main_win,TRUE);
-
- return;
-
- } /*** initialize ***/
-
- /*******************************************************************************
- ********************************************************************************
-
- Function: clean_up
-
- Purpose: Exit handler routine to clean up before exiting.
-
- Global variables:
-
- Name Examine/Modify/Use/Read/Write
- ---- -----------------------------
- stat_win X
- spec_win X
- main_win X
-
- Return Codes:
-
- Code Reason
- ---- ------
- none
-
- ********************************************************************************
- *******************************************************************************/
-
- void clean_up()
-
- { /*** clean_up ***/
-
- werase(stat_win); /* exit nicely */
- wrefresh(stat_win);
- clear_mess(main_win); /* in case a message needs clearing */
- nocbreak();
- delwin(stat_win);
- delwin(spec_win);
- delwin(main_win);
- endwin();
- exit();
-
- } /*** clean_up ***/
-
- /*******************************************************************************
- ********************************************************************************
-
- Function: resize_screen
-
- Purpose: Signal handler called when SIGWINCH is detected.
-
- Global variables:
-
- Name Examine/Modify/Use/Read/Write
- ---- -----------------------------
- global_row
-
- Return Codes:
-
- Code Reason
- ---- ------
- none
-
- ********************************************************************************
- *******************************************************************************/
-
- void resize_screen()
-
- { /*** resize_screen ***/
-
- return;
-
- } /*** resize_screen ***/
-
- /*******************************************************************************
- ********************************************************************************
-
- Function: put_stat
-
- Purpose: write the directory statistics line in the third virtual
- display in reverse video; this line will include the number of
- files and number of blocks for the directory.
-
- Global variables:
-
- Name Examine/Modify/Use/Read/Write
- ---- -----------------------------
- COLS X
-
- Return Codes:
-
- Code Reason
- ---- ------
- none
-
- ********************************************************************************
- *******************************************************************************/
-
- void put_stat(window,num_block,num_file)
- /******* FORMAL PARAMETERS *******/
- WINDOW *window; /* window to write in */
- long num_block; /* number of blocks in directory */
- short num_file; /* number of files in directory */
-
- { /*** put_stat ***/
- /******** LOCAL VARIABLES ********/
- char buf[BUFSIZ], /* formatting buffer #1 */
- buf2[BUFSIZ]; /* " " " */
-
-
- /* get the first string */
-
- #if !defined(SYSV) || defined(sun)
-
- sprintf(buf2," %d files %d blocks Press ? for help",
- num_file,kbytes(dbtob(num_block)));
- #else
-
- sprintf(buf2," %d files %d blocks Press ? for help",
- num_file,kbytes(num_block));
-
- #endif
-
- /* now left-justify it with blanks on the right */
-
- padcpy(buf,buf2,MAX_SCREEN_COLS);
- buf[COLS] = '\0'; /* terminate things where we want */
-
- /* write it to the virtual display */
-
- mvwaddstr(window,0,STAT_WINDOW_START_ROW,buf);
- wrefresh(window);
-
- return;
-
- } /*** put_stat ***/
-
- /*******************************************************************************
- ********************************************************************************
-
- Function: put_spec
-
- Purpose: write the directory specification/page number line at the top of
- screen
-
- Global variables:
-
- Name Examine/Modify/Use/Read/Write
- ---- -----------------------------
- home_dir X
- home_len X
-
- Return Codes:
-
- Code Reason
- ---- ------
- COLS
-
- ********************************************************************************
- *******************************************************************************/
-
- void put_spec(window,dir_name,home_dir,home_len,num_screen)
- /******* FORMAL PARAMETERS *******/
- WINDOW *window; /* window to write to */
- char *dir_name, /* current directory specification */
- *home_dir; /* home directory string */
- int home_len; /* length of home_dir */
- short num_screen; /* number of screens for directory */
-
- { /*** put_spec ***/
- /******** LOCAL VARIABLES ********/
- char *tptr, /* temporary character pointer */
- *tptr2; /* " " " */
- int page_str_len, /* length of "Page n of m" string */
- dir_len, /* length of directory name */
- count, /* temporary counter */
- temp; /* temporary value */
- char buf1[MAX_SCREEN_COLS+3], /* formatting buffer */
- buf2[MAX_SCREEN_COLS+3]; /* formatting buffer #2 */
-
-
- sprintf(buf2,"Page 1 of %2d",num_screen);
- page_str_len = strlen(buf2);
-
- /* if the current directory is a descendant of the user's home,
- * strip the home directory part out of it
- */
-
- dir_len = strlen(dir_name);
-
- if(strncmp(dir_name,home_dir,home_len) == 0)
- {
- /* the user's home directory is definitely a prefix of the current
- * directory string; now see if matches exactly
- */
-
- if(dir_len != home_len)
- {
- dir_name = &dir_name[home_len+1];
- dir_len -= home_len;
- }
- }
-
- temp = COLS - (page_str_len + 1);
- tptr = dir_name;
-
- if(dir_len > temp)
- {
- /* directory name is too long to fit on the screen; we have to prune
- * it back; start from the end and work backwords first until we get it
- * so that it will fit; then look for a nice place to break it
- */
-
- tptr = dir_name + ((u_long) dir_len - 1);
- count = 2;
-
- while(tptr != dir_name && count < temp)
- {
- --tptr;
- ++count;
- }
-
- /* now look for place to break it */
-
- tptr2 = strchr(tptr,'/');
-
- if(tptr2 != NULL)
- tptr = tptr2 + 1L; /* good, we found a spot */
- }
-
- memset(buf1,' ',sizeof(buf1)); /* clear out any old garbage */
-
- if(tptr == dir_name) /* did we prune the directory name? */
- padcpy(buf1,dir_name,MAX_SCREEN_COLS);
- else
- {
- buf1[0] = '*';
- padcpy(&buf1[1],tptr,MAX_SCREEN_COLS-1);
- }
-
- /* right-justify page number string */
-
- temp = strlen(buf1);
- strcpy(&buf1[COLS - page_str_len],buf2);
- temp = strlen(buf1);
- mvwaddstr(window,0,SPEC_WINDOW_START_ROW,buf1);
- wrefresh(window);
-
- return;
-
- } /*** put_spec ***/
-
- /*******************************************************************************
- ********************************************************************************
-
- Function: put_pagnum
-
- Purpose: write the "Page nn of nn" to the top right of the screen.
-
- Global variables:
-
- Name Examine/Modify/Use/Read/Write
- ---- -----------------------------
- none
-
- Return Codes:
-
- Code Reason
- ---- ------
- none
-
- ********************************************************************************
- *******************************************************************************/
-
- void put_pagnum(window,curr_screen,num_screen)
- /******* FORMAL PARAMETERS *******/
- WINDOW *window; /* window to write in */
- short curr_screen, /* current screen number */
- num_screen; /* number of screens for directory */
-
- { /*** put_pagnum ***/
- /******** LOCAL VARIABLES ********/
- char buf[MAX_SCREEN_COLS+1]; /* for formatting things */
-
-
- sprintf(buf,"Page %2d of %2d",curr_screen,num_screen);
- mvwaddstr(window,0,COLS - strlen(buf),buf);
- wrefresh(window);
-
- return;
-
- } /*** put_pagnum ***/
-
- /*******************************************************************************
- ********************************************************************************
-
- Function: put_options
-
- Purpose: Write the options line to the statistics/options virtual
- display. The keystroke needed to invoke the command is written
- in bold, the rest of the command in normal.
-
- Global variables:
-
- Name Examine/Modify/Use/Read/Write
- ---- -----------------------------
- COLS X
-
- Return Codes:
-
- Code Reason
- ---- ------
- none
-
- ********************************************************************************
- *******************************************************************************/
-
- void put_options(window)
- /******* FORMAL PARAMETERS *******/
- WINDOW *window; /* window to write in */
-
- { /*** put_options ***/
- /******** LOCAL VARIABLES ********/
- register OPT_DEF *opt_ptr; /* pointer to options array */
- register int column, /* current column number for writing */
- length, /* current length of options line */
- index; /* index into options[] */
- static OPT_DEF options[] = /* options array for 80-column mode */
- {
- {"d","el",1,2,1},
- {"r","en",1,2,1},
- {"p","rot",1,3,1},
- {"c","opy",1,3,1},
- {"u","nmark",1,5,1},
- {"e","dit",1,3,1},
- {"+","",1,0,1},
- {"-","",1,0,1},
- {"!","",1,0,1},
- {"/","",1,0,1},
- {".","",1,0,1},
- {"s","elect",1,5,1},
- {"f","in",1,2,1},
- {"x","ecute",1,5,1},
- {"q","uit",1,3,1},
- {"t","ext",1,3,1},
- {"i","nfo",1,3,1},
- #if defined(SYSV) && !defined(sun)
- {"g","roup",1,4,1},
- {"o","wner",1,4,1},
- #endif
- {"b","ranch",1,5,1},
- {"^g","o",2,1,1},
- #if !defined(SYSV) || defined(sun)
- {"g","roup",1,4,1},
- {"o","wner",1,4,1},
- #endif
- {"O","ptions",1,6,1},
- {"","",0,0,0}
- };
-
-
- wattroff(window,A_REVERSE); /* make sure the window is set right */
-
- /* first see how many options will fit on the screen */
-
- index = 0;
- length = 0;
-
- while(length <= COLS - 1 && options[index].key_len > 0)
- {
- length = length + options[index].key_len + options[index].rem_len +
- options[index].spaces;
- index++;
- }
-
- if(length - options[index].spaces > COLS)
- index--; /* don't use last one if no room */
-
- opt_ptr = &options[0];
-
- column = 0; /* make sure we start ok */
- wmove(window,STAT_WINDOW_ROWS - 1,0);
-
- while(index--)
- {
- /* write the key that activates the option in bright mode */
-
- wattron(window,A_BOLD);
- waddstr(window,opt_ptr->keystr);
- wattroff(window,A_BOLD);
-
- /* write the rest of the command name in normal video */
-
- waddstr(window,opt_ptr->remaining);
-
- /* skip the length of the remaining command name AND the number of
- * spaces that separates this command from the next
- */
-
- column += (int) opt_ptr->key_len + (int) opt_ptr->spaces +
- (int) opt_ptr->rem_len;
- wmove(window,STAT_WINDOW_ROWS - 1,column);
- opt_ptr++; /* go to next option slot */
- }
-
- wattron(window,A_REVERSE); /* this window is normally REVERSE */
- wrefresh(window);
- return;
-
- } /*** put_options ***/
-
- /*******************************************************************************
- ********************************************************************************
-
- Function: screen_reset
-
- Purpose: Called when something has changed the format of the screen
- and we have to make sure that the cursor still points to the
- right place. The current file is located and the row, column,
- and screen values are reset/recalculated.
-
- Global variables:
-
- Name Examine/Modify/Use/Read/Write
- ---- -----------------------------
- none
-
- Return Codes:
-
- Code Reason
- ---- ------
- none
-
- ********************************************************************************
- *******************************************************************************/
-
- void screen_reset(nodes,dirptr,filename,node_row,node_col,scr_file,
- curr_screen,node_row_max,num_file,num_slot,
- num_screen,slot_width,num_row,num_col)
- /******* FORMAL PARAMETERS *******/
- NODE_DEF nodes[][MAX_NODE_COL+1]; /* screen node matrix */
- ENT_DEF *dirptr; /* pointer to directory information */
- char *filename; /* filename to search for */
- short *node_row, /* current node array row */
- *node_col, /* current node array column */
- *scr_file, /* number of files for current screen */
- *curr_screen; /* current screen of directory */
- u_short node_row_max; /* max. row in nodes array */
- short num_file, /* number of files in current direct. */
- num_slot, /* number of slots per screen */
- num_screen, /* number of screens in directory */
- slot_width, /* width of one screen slot */
- num_row, /* number of rows on the screen */
- num_col; /* number of columns on the screen */
-
- { /*** screen_reset ***/
- /******** LOCAL VARIABLES ********/
- short temp, /* temporary variable and return code */
- temp2, /* temporary variable number two */
- new_screen; /* temporary current screen number */
-
-
- /* find the file in memory so we can calculate what page it is supposed to
- * be on
- */
-
- temp = (short) file_search(dirptr,filename,num_file,strlen(filename));
-
- if(temp >= 0)
- {
- /* we should ALWAYS get here, because the directory name should not
- * disappear from our memory, right?
- */
-
- new_screen = (temp / num_slot) + 1;
-
- /* get us to the current screen */
-
- temp2 = temp - ((new_screen - 1) * num_slot);
- *node_col = temp2 / num_row;
- *node_row = temp % num_row;
-
- /* do we need to go to a new screen? if so, make the new one now */
-
- if(new_screen != *curr_screen)
- {
- /* create the new screen by first putting the new page number in the
- * upper-right and then rebuilding the main display
- */
-
- /* do we need to update the screen node pointers? */
-
- *curr_screen = new_screen;
-
- if((new_screen == num_screen) || (*curr_screen == num_screen))
- {
- /* set the nodes */
-
- set_nodes(nodes,node_row_max,scr_file,num_screen,*curr_screen,
- num_file,slot_width,num_col);
- }
- }
- }
-
- return;
-
- } /*** screen_reset ***/
-
- /*******************************************************************************
- ********************************************************************************
-
- Function: clear_mess
-
- Purpose: Clear an informational message on the screen
-
- Global variables:
-
- Name Examine/Modify/Use/Read/Write
- ---- -----------------------------
- main_rows X
-
- Return Codes:
-
- Code Reason
- ---- ------
- none
-
- ********************************************************************************
- *******************************************************************************/
-
- void clear_mess(window)
- /******* FORMAL PARAMETERS *******/
- WINDOW *window; /* where the message is */
-
- { /*** clear_mess ***/
-
-
- wmove(window,main_rows-1,0);
- wclrtoeol(window);
- wrefresh(window);
- return;
-
- } /*** clear_mess ***/
-
- /*******************************************************************************
- ********************************************************************************
-
- Function: highlite
-
- Purpose: Rewrite a slot entry for a file, highlighting it if it is
- necessary. It will be highlighted if there are commands
- associated with the file entry.
-
- Global variables:
-
- Name Examine/Modify/Use/Read/Write
- ---- -----------------------------
- none
-
- Return Codes:
-
- Code Reason
- ---- ------
- none
-
- ********************************************************************************
- *******************************************************************************/
-
- void highlite(window,buf,ent,args,row,col,slot_width,text_flag)
- /******* FORMAL PARAMETERS *******/
- WINDOW *window; /* where to write */
- char *buf; /* where to put the screen slot */
- ENT_DEF *ent; /* file entry pointer */
- ARG_DEF *args; /* run-time arguments */
- int row, /* column to write it at */
- col; /* row to write it at */
- short slot_width, /* width of screen slot */
- text_flag; /* whether we display text descrips */
-
- { /*** highlite ***/
- /******** LOCAL VARIABLES ********/
- int rend_set; /* rendition setting for slot entry */
-
-
- /* first create the slot */
-
- if(ent->command != NULL)
- {
- rend_set = make_slot(buf,ent,args,slot_width,text_flag);
-
- /* write the slot */
-
- put_slot(window,row,col,buf,rend_set);
- }
-
- return;
-
- } /*** highlite ***/
-
- /*******************************************************************************
- ********************************************************************************
-
- Function: tag_file
-
- Purpose: Put a mark by a file on the screen so that user knows what
- file is being accessed when he is prompted at the bottom of
- the virtual display for information. With the cursor at the
- bottom of the display in preparation for receiving input, it
- is sometimes hard to remember what file was selected. This
- should help alleviate that.
-
- Global variables:
-
- Name Examine/Modify/Use/Read/Write
- ---- -----------------------------
- none
-
- Return Codes:
-
- Code Reason
- ---- ------
- none
-
- ********************************************************************************
- *******************************************************************************/
-
- void tag_file(window,row,column)
- /******* FORMAL PARAMETERS *******/
- WINDOW *window; /* where to write */
- int row, /* row of where to write tag */
- column; /* column of where to write tag */
-
- { /*** tag_file ***/
- /******** LOCAL VARIABLES ********/
-
- /* write the tag character by the file */
-
- wattron(window,A_BOLD);
- mvwaddch(window,row,column,TAG_CHAR);
- wattroff(window,A_BOLD);
- wrefresh(window);
- return;
-
- } /*** tag_file ***/
-
- /*******************************************************************************
- ********************************************************************************
-
- Function: erase_tag
-
- Purpose: Erase a file tag now that user is done doing what they wanted
- with the file.
-
- Global variables:
-
- Name Examine/Modify/Use/Read/Write
- ---- -----------------------------
- none
-
- Return Codes:
-
- Code Reason
- ---- ------
- none
-
- ********************************************************************************
- *******************************************************************************/
-
- void erase_tag(window,row,column)
- /******* FORMAL PARAMETERS *******/
- WINDOW *window; /* where to write */
- int row, /* row of where to write tag */
- column; /* column of where to write tag */
-
- { /*** erase_tag ***/
- /******** LOCAL VARIABLES ********/
- /* erase the tag */
-
- mvwaddch(window,row,column,' ');
- wrefresh(window);
- return;
-
- } /*** erase_tag ***/
-
- /*******************************************************************************
- ********************************************************************************
-
- Function: get_scr_num
-
- Purpose: Prompt for and read in a digit string that is supposed to
- represent the screen number that the user wants to go to.
- Also check to see if the screen number is valid.
-
- Global variables:
-
- Name Examine/Modify/Use/Read/Write
- ---- -----------------------------
- main_rows X
-
- Return Codes:
-
- Code Reason
- ---- ------
- BAD_SCREEN_NO invalid screen number specified
- new_screen new screen number
- curr_screen user just hit <RETURN>
-
- ********************************************************************************
- *******************************************************************************/
-
- short get_scr_num(window,curr_screen,num_screen)
- /******* FORMAL PARAMETERS *******/
- WINDOW *window; /* where to read/write */
- short curr_screen, /* current screen of directory */
- num_screen; /* number of screens in directory */
-
- { /*** get_scr_num ***/
- /******** LOCAL VARIABLES ********/
- int new_screen, /* new screen number */
- temp; /* temporary string length */
- char buf[PAGE_NO_MAX+1]; /* for holding page number string */
-
-
- /* prompt for and read it */
-
- prompt_getstr(window,"Page number? ",buf,main_rows,PAGE_NO_MAX);
-
- temp = strlen(buf);
-
- if(temp == 0)
- return(curr_screen); /* user didn't specify anything */
-
- --temp; /* move back over the NUL char */
-
- /* make sure that this is a string of DIGITS or atoi() will do
- * weird things
- */
-
- while(temp >= 0)
- {
- if(isdigit(buf[temp]) || isspace(buf[temp]))
- temp--;
- else
- return(BAD_SCREEN_NO);
- }
-
- new_screen = atoi(buf); /* NOW make it an integer */
-
- if((new_screen < 1) || (new_screen > num_screen))
- return(BAD_SCREEN_NO); /* bad screen number was specified */
-
- return((short) new_screen); /* return the new screen number */
-
- } /*** get_scr_num ***/
-
- /*******************************************************************************
- ********************************************************************************
-
- Function: put_buf
-
- Purpose: Output the current buffer to the display.
-
- This routine will also wrap long lines. It will look
- for the character specified by the separator parameter
- and wrap it there if it finds one.
-
- Also, if there is a pad_str specified, it will be inserted
- at the beginning of the buffer to be printed.
-
- Global variables:
-
- Name Examine/Modify/Use/Read/Write
- ---- -----------------------------
- COLS
-
- Return Codes:
-
- Code Reason
- ---- ------
- 0 successful
- ret_val return code (possibly successful) from call
- to put_buf
-
- ********************************************************************************
- *******************************************************************************/
-
- int put_buf(window,buf,row,max_row,prefix_len,attributes,get_flag,separator,
- eof_flag)
- /******* FORMAL PARAMETERS *******/
- WINDOW *window; /* where to read/write */
- char *buf; /* buffer to be written */
- int *row, /* row # where line is to be written */
- max_row, /* max. row in the window */
- prefix_len, /* length of prefix in line */
- attributes; /* screen attributes for buffer */
- u_short get_flag; /* set if we need to ask for a char */
- char separator, /* separator char for wrapping */
- eof_flag; /* end-of-file from expand() */
-
- { /*** put_buf ***/
- /******** LOCAL VARIABLES ********/
- char *ptr, /* for splitting long lines */
- *ptr2, /* ditto..... */
- *save_ptr; /* for saving a character pointer */
- char tchar; /* for holding one character */
- static int buf_len, /* length of current buffer */
- temp_len, /* temporary length */
- ret_val; /* return value holder */
-
-
- ret_val = 0; /* set default return value */
- buf_len = strlen(buf); /* get length of stuff to be written */
-
- if(eof_flag == TRUE)
- {
- /* write the EOF record to the inverted co-routine */
-
- ret_val = put_line(window,NULL,row,max_row,attributes,get_flag,TRUE);
- }
- else
- {
- if(buf_len >= COLS) /* too long for screen? */
- {
- /* the line is too long so we have to wrap it ourselves by breaking
- * the input line up into segments that will fit on the screen
- */
-
- ptr = buf; /* start at the beginning */
- temp_len = buf_len;
-
- while(ptr && temp_len > COLS)
- {
- /* move backwards until we find a word boundary */
-
- ptr2 = ptr + (u_long) (COLS - 1);
- save_ptr = ptr2; /* so we can go back if we need to */
-
- while(*ptr2 != separator && ptr2 != ptr + prefix_len)
- --ptr2;
-
- if(ptr2 == ptr + prefix_len) /* couldn't find a word boundary? */
- ptr2 = save_ptr; /* nope, go back to where we were */
-
- tchar = *(ptr2 + 1); /* make the segment a string */
- *(ptr2 + 1) = '\0';
-
- /* output the segment */
-
- ret_val = put_line(window,ptr,row,max_row,attributes,get_flag,
- eof_flag);
-
- *(ptr2 + 1) = tchar; /* restore the segment */
- prefix_len = 0; /* only good for first pass thru */
- ptr = ptr2 + 1L; /* skip this segment */
- temp_len = strlen(ptr);
- }
-
- /* if there is a segment left over, write it */
-
- if(temp_len)
- ret_val = put_line(window,ptr,row,max_row,attributes,get_flag,
- eof_flag);
- }
- else
- {
- /* everything will fit on one line; just write it */
-
- ret_val = put_line(window,buf,row,max_row,attributes,get_flag,
- eof_flag);
- }
- }
-
- return(ret_val);
-
- } /*** put_buf ***/
-
- /*******************************************************************************
- ********************************************************************************
-
- Function: put_line
-
- Purpose: Inverted co-routine (to put_buf) that controls writing to
- the screen and prompting when we reach the bottom. If get_flag
- is TRUE, we force to the bottom of the screen.
-
- Global variables:
-
- Name Examine/Modify/Use/Read/Write
- ---- -----------------------------
- LINES X
-
- Return Codes:
-
- Code Reason
- ---- ------
- SUCCESS
- FAILURE
-
- ********************************************************************************
- *******************************************************************************/
-
- static int put_line(window,buf,row,max_row,attr,get_flag,eof_flag)
- /******* FORMAL PARAMETERS *******/
- WINDOW *window; /* where to read/write */
- char *buf; /* buffer to be written */
- int *row, /* row where output is to go */
- max_row, /* max. # of rows for screen */
- attr; /* attributes to be used */
- u_short get_flag; /* set if need to get a char */
- char eof_flag; /* used to terminate co-routine */
-
- { /*** put_line ***/
- /******** LOCAL VARIABLES ********/
- static u_char state; /* co-routine state variable */
- static char prompt[] =
- {"Press any key to continue \
- \
- "};
-
-
- switch(state) /* perform resuming operation */
- {
- case(1):
- goto lab0;
- default:
- prompt[COLS] = '\0';
- break;
- }
-
- state = 1; /* so we resume in the right place */
-
- while(eof_flag == FALSE)
- {
- while(*row < max_row)
- {
- /* write the line */
-
- if(buf == NULL || *buf == '\0')
- {
- mvwaddch(window,*row,0,'x');
- mvwdelch(window,*row,0);
- }
- else
- {
- if(attr != A_NORMAL)
- wattron(window,attr);
-
- mvwaddstr(window,*row,0,buf); /* write it */
-
- if(attr != A_NORMAL)
- wattroff(window,attr);
- }
-
- *row += 1; /* count this row */
-
- /* do we need another record? or are we just filling to the bottom
- * of the screen?
- */
-
- if(get_flag == FALSE)
- return(SUCCESS); /* get another record */
-
- lab0: ;
- }
-
- /* we're at the end of a window; prompt and get a char
- * we continue
- */
-
- wattron(window,A_REVERSE);
- mvwaddstr(window,*row,0,prompt);
- wattroff(window,A_REVERSE);
- wrefresh(window);
- wgetch(window);
- werase(window);
- wrefresh(window);
- *row = 0;
- }
-
- /* terminate the co-routine */
-
- state = 0;
-
- return(SUCCESS);
-
- } /*** put_line ***/
-
- /*******************************************************************************
- ********************************************************************************
-
- Function: put_slot
-
- Purpose: Write a file slot to the specified coordinates with the
- proper attirbutes.
-
- Global variables:
-
- Name Examine/Modify/Use/Read/Write
- ---- -----------------------------
- none
-
- Return Codes:
-
- Code Reason
- ---- ------
- mvaddstr() return code from mvaddstr()
-
- ********************************************************************************
- *******************************************************************************/
-
- int put_slot(window,row,col,string,attr)
- /******* FORMAL PARAMETERS ********/
- WINDOW *window; /* where to write the slot */
- int row, /* screen row */
- col; /* screen column */
- char *string; /* slot to be written */
- int attr; /* attribute to use */
-
- { /*** put_slot ***/
-
- if(attr != A_NORMAL) /* turn on the attributes if needed */
- wattron(window,attr);
-
- mvwaddstr(window,row,col,string);
-
- if(attr != A_NORMAL) /* and turn them back off */
- wattroff(window,attr);
-
- return(SUCCESS);
-
- } /*** put_slot ***/
-
- /*******************************************************************************
- ********************************************************************************
-
- Function: prompt_getstr
-
- Purpose: Prompt for and get a string from the window.
-
- Global variables:
-
- Name Examine/Modify/Use/Read/Write
- ---- -----------------------------
- none
-
- Return Codes:
-
- Code Reason
- ---- ------
- mvaddstr() return code from mvaddstr()
-
- ********************************************************************************
- *******************************************************************************/
-
- void prompt_getstr(window,prompt,buf,row,max_len)
- /******* FORMAL PARAMETERS *******/
- WINDOW *window; /* where to read/write */
- char *prompt, /* prompt user with this */
- *buf; /* return input string here */
- int row, /* row in window to prompt from */
- max_len; /* max. length string to accept */
-
- { /*** prompt_getstr ***/
- /******** LOCAL VARIABLES ********/
- register short i; /* array index */
- int prompt_len, /* length of prompt string */
- column, /* column where cursor is */
- disp_len; /* total displayed length of buf */
- short eoi; /* end-of-input flag */
- static int ch; /* keystroke from screen */
-
-
- prompt_len = strlen(prompt);
- column = prompt_len;
- row--; /* easier than -1 everytime... */
- wattron(window,A_BOLD);
- mvwaddstr(window,row,0,prompt); /* prompt 'em... */
- wattroff(window,A_BOLD);
- wrefresh(window);
-
- i = 0;
- eoi = FALSE;
- disp_len = 0;
-
- while(eoi == FALSE)
- {
- ch = wgetch(window);
-
- if (ch == user_erase)
- ch = KEY_BACKSPACE;
-
- switch(ch)
- {
- case(CARRIAGE_RETURN):
- case(LINEFEED):
-
- eoi = TRUE; /* break out of the loop */
- buf[i] = '\0'; /* make it a string */
- break;
-
- case(KEY_BACKSPACE):
- case(KEY_LEFT):
-
- /* see if we need to shift back to the left */
-
- if(i > 0) /* anything there to erase? */
- {
- --i;
- adjust_str(window,buf,&column,row,prompt_len,disp_len,i,LEFT);
-
- if(!iscntrl(buf[i]))
- disp_len--;
- else
- disp_len -= 2;
-
- buf[i] = '\0'; /* erase the character */
- }
- else
- beep();
-
- break;
-
- case(ESCAPE):
-
- break;
-
- default:
-
- /* the user typed a character */
-
- if(i < max_len)
- {
- /* add the character to the buffer and see if we need to shift
- * to make more room for input
- */
-
- if(!iscntrl(ch))
- disp_len++;
- else
- disp_len += 2;
-
- buf[i++] = (char) ch;
- adjust_str(window,buf,&column,row,prompt_len,disp_len,i,RIGHT);
- }
- else
- beep();
-
- break;
- }
- }
-
- buf[i] = '\0';
- clear_mess(window);
- return;
-
- } /*** prompt_getstr ***/
-
- /*******************************************************************************
- ********************************************************************************
-
- Function: adjust_str
-
- Purpose: Adjust the string being typed in if it needs it. If the
- user tried to type past the right edge of the screen, shift
- things to the left to give him room. If the user is moving
- backwards (via Delete), shift to the right if necessary.
-
- Global variables:
-
- Name Examine/Modify/Use/Read/Write
- ---- -----------------------------
- none
-
- Return Codes:
-
- Code Reason
- ---- ------
- none
-
- ********************************************************************************
- *******************************************************************************/
-
- static void adjust_str(window,buf,column,row,prompt_len,disp_len,i,direction)
- /******* FORMAL PARAMETERS *******/
- WINDOW *window; /* where to write */
- char *buf; /* where the input is stored */
- register int *column; /* where the cursor is on the screen */
- int row, /* row on the screen to write */
- prompt_len, /* length of prompt string */
- disp_len, /* total displayed length of buf */
- i; /* index into buf */
- short direction; /* direction on screen we are moving */
-
- { /*** adjust_str ***/
- /******** LOCAL VARIABLES ********/
- static int start, /* loop and array index */
- temp, /* temporary trash variable */
- count, /* length of chars to be displayed */
- tcolumn; /* temporary column value */
-
-
- if(direction == RIGHT)
- {
- /* attempting to move past right edge of the screen? */
-
- if(*column > COLS - 2 || (*column > COLS - 3 && iscntrl(buf[i-1])))
- {
- /* shift things left to make room; first find where in buf to start
- * displaying things
- */
-
- start = i - 1;
- count = 0;
-
- while(count < MIN_DISP_LEN)
- {
- if(iscntrl(buf[start]))
- count += 2; /* control chars preceded by ^ */
- else
- ++count;
-
- --start;
- }
-
- /* now write the stuff */
-
- wmove(window,row,prompt_len);
- *column = prompt_len;
- tcolumn = prompt_len; /* to cut down on indirect addressing */
- wclrtoeol(window);
- start++; /* start in the right place */
-
- while(start < i)
- {
- if(iscntrl(buf[start]))
- {
- /* this is a control character; output the ^ first and
- * then convert the character to something printable and
- * print it, too
- */
-
- mvwaddch(window,row,tcolumn,'^');
- waddch(window,buf[start] + 64);
- tcolumn += 2;
- }
- else
- {
- mvwaddch(window,row,tcolumn,buf[start]);
- tcolumn += 1;
- }
-
- ++start;
- }
-
- *column = tcolumn; /* now store it */
- }
- else
- {
- /* we have the room, just write the character */
-
- if(iscntrl(buf[i-1]))
- {
- mvwaddch(window,row,*column,'^');
- waddch(window,buf[i-1] + 64);
- *column += 2;
- }
- else
- {
- mvwaddch(window,row,*column,buf[i-1]);
- *column += 1;
- }
- }
- }
- else /* moving left */
- {
- /* are we moving past the spot that would cause to shift to
- * the right?
- */
-
- if(*column == prompt_len + MIN_DISP_LEN ||
- (*column == prompt_len + MIN_DISP_LEN + 1 && iscntrl(buf[i])))
- {
- /* adjust the input line if necessary */
-
- if(disp_len >= COLS - (prompt_len + 1))
- {
- /* shift the input line to the right so the user can see
- * what was typed in
- */
-
- start = i - 1;
- count = 0;
- temp = COLS - (prompt_len + 1);
-
- while(count < temp && start >= 0)
- {
- if(iscntrl(buf[start]))
- count += 2; /* control chars preceded by ^ */
- else
- ++count;
-
- --start;
- }
-
- /* now write the stuff */
-
- ++start; /* start in the right spot */
- wmove(window,row,prompt_len);
- wclrtoeol(window);
- *column = prompt_len;
- tcolumn = prompt_len; /* to cut down on indirect addressing */
-
- while(start < i)
- {
- if(iscntrl(buf[start]))
- {
- /* this is a control character; output the ^ first and
- * then convert the character to something printable and
- * print it, too
- */
-
- mvwaddch(window,row,tcolumn,'^');
- waddch(window,buf[start] + 64);
- tcolumn += 2;
- }
- else
- {
- mvwaddch(window,row,tcolumn,buf[start]);
- tcolumn += 1;
- }
-
- ++start;
- }
-
- *column = tcolumn; /* now store it */
- }
- else
- {
- /* no need to shift, just move left */
-
- if(iscntrl(buf[i]))
- {
- *column -= 2;
- }
- else
- {
- *column -= 1;
- }
- }
- }
- else
- {
- /* we have room to just move to the left */
-
- if(iscntrl(buf[i]))
- {
- *column -= 2;
- }
- else
- {
- *column -= 1;
- }
- }
-
- wmove(window,row,*column);
- wclrtoeol(window);
- }
-
- wrefresh(window);
- return;
-
- } /*** adjust_str ***/
-
- /*******************************************************************************
- ********************************************************************************
-
- Function: write_mess
-
- Purpose: Actually write an informational message to the screen, breaking
- up messages that are too long for the screen.
-
- Global variables:
-
- Name Examine/Modify/Use/Read/Write
- ---- -----------------------------
- main_win X
- main_rows X
-
- Return Codes:
-
- Code Reason
- ---- ------
- none
-
- ********************************************************************************
- *******************************************************************************/
-
- void write_mess(message,attributes,prefix_len)
- /******* FORMAL PARAMETERS *******/
- char *message; /* message to be written */
- int attributes, /* display attributes */
- prefix_len; /* length to skip when splitting */
-
- { /*** write_mess ***/
- /******** LOCAL VARIABLES ********/
- char *ptr, /* for breaking up long messages */
- *ptr2, /* ditto.... */
- *save_ptr; /* for saving a pointer */
- int length; /* temporary string length */
- char tchar; /* for saving a single character */
-
-
- /* first clear out things in case the new message is shorter than the
- * previous one; we would have garbage at the end of it
- */
-
- clear_mess(main_win); /* clear the message line first */
-
- if(strlen(message) > COLS)
- {
- /* message is too long to be written in just one chunk; break it up
- * and write them separately
- */
-
- ptr = message; /* start at the beginning */
- prefix_len -= 2; /* don't count the space */
- length = strlen(ptr);
-
- while(*ptr && length > COLS)
- {
- wmove(main_win,main_rows-1,0); /* move cursor back to start of line */
-
- /* get a full screen-width worth and work backwords to get a break
- * point; if we can't find one, take the whole line
- */
-
- ptr2 = ptr + (u_long) (COLS - 1);
- save_ptr = ptr2; /* save so we can go back */
-
- while(!isspace(*ptr2) && ptr2 != ptr + prefix_len)
- --ptr2;
-
- if(ptr2 == ptr + prefix_len) /* did we find a word separator? */
- ptr2 = save_ptr; /* nope, go back to where we were */
-
- tchar = *(ptr2 + 1); /* make the segment a string */
- *(ptr2 + 1) = '\0';
- wattron(main_win,attributes);
- waddstr(main_win,ptr); /* write the message segment */
- wattroff(main_win,attributes);
- wmove(main_win,main_rows-1,0); /* move cursor back to start of line */
- wrefresh(main_win); /* update the screen */
- *(ptr2 + 1) = tchar; /* restore the character */
- sleep(2); /* let the user read it */
- prefix_len = 0; /* only good for first pass */
- ptr = ptr2 + 1L; /* move to start of next segment */
- length = strlen(ptr);
- }
-
- /* if there is a segment left over, write it */
-
- if(length)
- {
- wmove(main_win,main_rows-1,0); /* move cursor back to start of line */
- wclrtoeol(main_win); /* make sure we have a clean line */
- wrefresh(main_win);
- wattron(main_win,attributes);
- waddstr(main_win,ptr); /* write the message segment */
- wattroff(main_win,attributes);
- wrefresh(main_win);
- }
- }
- else
- {
- /* write the message, bold */
-
- wattron(main_win,attributes);
- mvwaddstr(main_win,main_rows-1,0,message);
- wattroff(main_win,attributes);
- wrefresh(main_win);
- }
-
- return;
-
- } /*** write_mess ***/
-