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