home *** CD-ROM | disk | FTP | other *** search
- /*=============================================================================
-
- The INSTALL program source code, object code, sample script files,
- executable program, and documentation are subject to copyright
- protection under the laws of the United States and other countries.
-
- This software is licensed, not sold, and may only be redistributed
- in executable format and only in accordance with the provisions of
- the INSTALL Source Code License Agreement.
-
- INSTALL is Copyright(C) 1987-1990 by Knowledge Dynamics Corp
- Highway Contract 4 Box 185-H, Canyon Lake, TX (USA) 78133-3508
- 512-964-3994 (Voice) 512-964-3958 (24-hr FAX)
-
- All rights reserved worldwide.
-
- ===============================================================================
-
- FILENAME:
- list.c
-
- AUTHOR:
- eric jon heflin
-
- PUBLIC FUNCTIONS:
- select_m() - "pushes" window, selects item, then "pops" window back
-
- LOCAL FUNCTIONS:
- list_io() - handles all of the cursor and arrow key functions
-
- DESCRIPTION:
- This file contains functions to display a list on the screen and allow
- the user to use the arrow keys to select an item from the list.
-
- REVISION HISTORY:
- DATE: AUTHOR: DESCRIPTION OF CHANGES:
- 891203 allyn jordan documentation
- 900321 ejh Added code to handle "all off" state and "all on"
- state of elements.
-
- ==============================================================================*/
-
- #include "install.h"
- #include "control.h"
- #include "keys.h"
- #include <ctype.h>
- #include <string.h>
- #include "lint.h"
- #if defined(__TURBOC__)
- #include <mem.h>
- #endif
- #define SPACEBAR (0x20)
- #define PLUS (0x2b)
- #define MINUS (0x2d)
- #define ASTERISK (0x2a)
-
- #define ONBIT0 (0x01)
- #define ONBIT1 (0x02)
- #define ONBIT2 (0x04)
- #define ONBIT3 (0x08)
- #define ONBIT4 (0x10)
- #define ONBIT5 (0x20)
- #define ONBIT6 (0x40)
- #define ONBIT7 (0x80)
-
- #define ONALLBIT (0xff)
- #define OFFALLBIT (0x00)
-
-
- /* prototypes */
- static int list_io(P8(byte **, word, word, word, word, int, int, int));
- static int tags(P8(byte **, int, int, int, int, int, int, int));
- static void trim_list(byte **list, word list_max);
- int is_set(word n);
-
- /* static variables */
- static int test = 0;
- static byte vector[500];
- static byte *yes = " YES", *no = " NO ";
-
- #define TAG_ALL (1)
- #define TAG_ONE (2)
- #define TOGGLE (3)
- #define FORCE (4)
- #define YES (5)
- #define NO (6)
-
- static bool first_tag = TRUE;
- static byte maskbit[10] =
- {
- ONBIT7,
- ONBIT6,
- ONBIT5,
- ONBIT4,
- ONBIT3,
- ONBIT2,
- ONBIT1,
- ONBIT0,
- ONALLBIT,
- OFFALLBIT
- };
-
-
- int select_m(list, min_row, min_col, max_row, max_col, max, start, tagyn)
- byte **list;
- word min_row, min_col; /* location of ulhc of window */
- word max_row, max_col; /* location of lrhc of window */
- int max; /* total number of entries in the list */
- int start; /* initial cursor position */
- int tagyn; /* enable/disable tagging routine (TRUE/FALSE) */
- {
- int ret = 2;
-
- /* save area about to be overwritten */
- scr_push(min_row - 1, min_col - 1, max_row + 1, max_col + 1);
-
- /* hide cursor */
- scr_nocur();
-
- /* let user select element */
- ret = list_io(list, min_row, min_col, max_row, max_col, max, start, tagyn);
-
- /* restore screen */
- scr_pop();
-
- return ret;
- }
-
- /*
- * returns: -1 if user pressed ESC,
- * entry number if user pressed CR
- */
-
- static byte blanks[80] = " ";
-
- /*
- * Interpret the user keystroke and update the display.
- */
-
- static int list_io(list, min_row, min_col, max_row, max_col, max, start, tagyn)
- byte **list;
- word min_row, min_col; /* location of ulhc of window */
- word max_row, max_col; /* location of lrhc of window */
- int max; /* total number of entries in the list */
- int start; /* initial highlighted element */
- { /* list */
- int i, c, len;
- /* current selected element number */
- int current = start;
- /* prior selected element */
- int last_current = start;
- int first = TRUE;
-
- /* prior selected window top */
- int last_top = 0;
- int last_row = min_row + start;
- /* change from current position to next position of window top */
- int delta_top = 0;
- /* change from current position to next position of bounce bar */
- int delta_current = 0;
- /* the index w/i element[] of first entry displayed in widow */
- int top = 0;
- /* the number of rows in the window */
- int w_size = max_row - min_row;
-
- if (top + w_size < start)
- top = start - w_size;
-
- if (last_row > min_row + w_size)
- last_row = top + w_size;
- if (max < 0)
- return -1;
- c = 0;
-
- while (c != ESC && c != CR)
- {
- if (!first)
- {
- if ((c = sgetch()) == 0)
- c = sgetch();
- }
- else
- {
- blanks[max_col - min_col] = '\0';
- box(min_row - 1, min_col - 1, max_row + 1, max_col + 1, block, get_attr());
- c = 0;
- if (tagyn == TRUE)
- {
- first = TRUE;
- start = max;
- memset(vector, '\0', sizeof (vector));
- tags(list, max, current, max_col, min_col, FORCE, TAG_ALL, NO);
- } /* end tagyn if */
- } /* end else */
- switch (toupper(c))
- {
- case CTRL_A:
- case '7':
- case HOME:
- top = 0;
- current = 0;
- delta_top = 0;
- delta_current = 0;
- break;
- case 'S':
- /*
- * Toggle
- */
- if (tagyn == TRUE)
- {
- first = TRUE;
- start = max;
- tags(list, max, current, max_col, min_col, TOGGLE, TAG_ALL, TOGGLE);
- } /* end tagyn if */
- break;
- case 'T':
- case 'Y':
- /*
- * Tag
- */
- if (tagyn == TRUE)
- {
- first = TRUE;
- start = max;
- tags(list, max, current, max_col, min_col, FORCE, TAG_ALL, YES);
- } /* end tagyn if */
- break;
- case 'U':
- case 'N':
- /*
- * Untag
- */
- if (tagyn == TRUE)
- {
- first = TRUE;
- start = max;
- tags(list, max, current, max_col, min_col, FORCE, TAG_ALL, NO);
- } /* end tagyn if */
- break;
- case CTRL_F:
- case '1':
- case END:
- top = max - w_size;
- current = max;
- delta_top = 0;
- delta_current = 0;
- break;
- case CTRL_W:
- case CTRL_R:
- case '9':
- case PGUP:
- delta_top = -w_size;
- delta_current = -w_size;
- break;
- case CTRL_C:
- case '3':
- case PGDN:
- case CTRL_Z:
- delta_top = w_size;
- delta_current = w_size;
- break;
- case CTRL_E:
- case CTRL_S:
- case '8':
- case UPARROW:
- if (current == top)
- delta_top = -1;
- delta_current = -1;
- break;
- case ASTERISK:
- case SPACEBAR:
- if (tagyn == TRUE)
- tags(list, max, current, max_col, min_col, TOGGLE, TAG_ONE, TOGGLE);
- if (current + 1 > top + w_size)
- delta_top = 1;
- delta_current = 1;
- break;
- case MINUS:
- if (tagyn == TRUE)
- tags(list, max, current, max_col, min_col, FORCE, TAG_ONE, NO);
- if (current + 1 > top + w_size)
- delta_top = 1;
- delta_current = 1;
- break;
- case PLUS:
- if (tagyn == TRUE)
- tags(list, max, current, max_col, min_col, FORCE, TAG_ONE, YES);
- break;
- case CTRL_D:
- case CTRL_X:
- case '2':
- case DOWNARROW:
- if (current + 1 > top + w_size)
- delta_top = 1;
- delta_current = 1;
- break;
- } /* switch */
-
- top += delta_top;
- current += delta_current;
- if (top > max - w_size)
- top = max - w_size;
- if (top < 0)
- top = 0;
- if (current < top)
- current = top;
- if (current > top + w_size)
- current = top + w_size;
- if (current > max)
- current = max;
- delta_top = 0;
- delta_current = 0;
- if (!first && top == last_top)
- {
- /* no scroll */
- len = strlen(list[last_current]);
- blanks[0] = blanks[1] = ' ';
- strcpy(blanks + 2, list[last_current]);
- memset(blanks + len + 2, ' ', 80 - len - 4);
- blanks[max_col - min_col + 1] = '\0';
- colors(last_row, min_col, blanks, WHITE_F | BRITE);
- /* erase last current */
- len = strlen(list[current]);
- blanks[0] = blanks[1] = ' ';
- strcpy(blanks + 2, list[current]);
- memset(blanks + len + 2, ' ', 80 - len - 4);
- blanks[max_col - min_col + 1] = '\0';
- colors(min_row - top + current, min_col, blanks, WHITE_B | FLASH);
- last_row = (min_row - top) + current;
- }
- else
- {
- /* scroll update display w/i window */
- first = FALSE;
- for (i = top; i <= top + w_size; ++i)
- {
- if (i > max)
- {
- memset(blanks, ' ', sizeof (blanks));
- blanks[max_col - min_col + 1] = '\0';
- colors((min_row + i) - top, min_col, blanks, WHITE_F | BRITE);
- }
- else if (i != current)
- {
- len = strlen(list[i]);
- blanks[0] = blanks[1] = ' ';
- strcpy(blanks + 2, list[i]);
- memset(blanks + len + 2, ' ', 80 - len - 4);
- blanks[max_col - min_col + 1] = '\0';
- colors((min_row + i) - top, min_col, blanks, WHITE_F | BRITE);
- }
- else
- {
- len = strlen(list[i]);
- blanks[0] = blanks[1] = ' ';
- strcpy(blanks + 2, list[i]);
- memset(blanks + len + 2, ' ', 80 - len - 4);
- blanks[max_col - min_col + 1] = '\0';
- colors((min_row + i) - top, min_col, blanks, WHITE_B | FLASH);
- last_row = (min_row + i) - top;
- }
- }
- } /* scroll */
- last_current = current;
- last_top = top;
- } /* while */
- test = is_set(0);
- test = is_set(2);
- if (tagyn)
- trim_list(list, max);
- if (c != ESC)
- return current;
- if (max_col == 0)
- ; /* quiet lint */
- return -1;
- } /* list */
-
-
- /*
- * tag or untag selected menu items
- */
-
- static int tags(list, max, current, max_col, min_col, f_or_t, a_or_o, y_or_n)
- byte **list;
- int max, current, max_col, min_col;
- int f_or_t, a_or_o, y_or_n;
- {
- int bytenum = current / 8, bitnum = current % 8;
- int yes_offset = max_col - min_col - 2 - strlen(yes);
- int no_offset = max_col - min_col - 2 - strlen(no);
- int line_len = max_col - min_col; /* number of positions in line */
- int i;
-
- if (f_or_t == TOGGLE) /* TOGGLE instead of FORCE */
- {
- if (a_or_o == TAG_ONE) /* TOGGLE only one */
- {
- vector[bytenum] ^= maskbit[bitnum]; /* TOGGLE state */
- if (vector[bytenum] & maskbit[bitnum])
- {
- strcpy(list[current] + yes_offset, yes);
- return 1;
- }
- else
- {
- strcpy(list[current] + no_offset, no);
- return 2;
- }
- } /* end TOGGLE one */
- else /* TOGGLE states for all members */
- {
- for (i = 0; i <= max; ++i)
- {
- bytenum = i / 8;
- bitnum = i % 8;
- vector[bytenum] ^= maskbit[bitnum];
- if (vector[bytenum] & maskbit[bitnum])
- strcpy(list[i] + yes_offset, yes);
- else
- strcpy(list[i] + no_offset, no);
- } /* end for */
- return 3;
- } /* end TOGGLE all */
- } /* end TOGGLE */
- else
- { /* FORCE to one state or another (not TOGGLE) */
- if (y_or_n == YES) /* FORCE to "on state" */
- {
- if (a_or_o == TAG_ALL) /* FORCE all to "on state" */
- {
- if (first_tag == TRUE)
- {
- memset(vector, '\xff', sizeof (vector));
- for (i = 0; i <= max; ++i)
- {
- /* pad line with spaces */
- memset(list[i] + strlen(list[i]), ' ', line_len - strlen(list[i]));
- strcpy(list[i] + no_offset, yes);
- }
- }
- else
- {
- memset(vector, '\0', sizeof (vector));
- for (i = 0; i <= max; ++i)
- strcpy(list[i] + no_offset, no);
- }
- return 4;
- } /* end FORCE all */
- else
- {
- vector[bytenum] |= maskbit[bitnum];
- strcpy(list[current] + yes_offset, yes);
- return 5;
- } /* end FORCE one */
- } /* end of "on states " */
- else /* begin of FORCEd "off states" */
- {
- if (a_or_o == TAG_ALL) /* FORCE all to "off state" */
- {
- if (first_tag == TRUE)
- {
- memset(vector, '\0', sizeof (vector));
- for (i = 0; i <= max; ++i)
- {
- /* pad line with spaces */
- memset(list[i] + strlen(list[i]), ' ', line_len - strlen(list[i]));
- strcpy(list[i] + no_offset, no);
- }
- return 6;
- }
- else
- {
- memset(vector, '\0', sizeof (vector));
- for (i = 0; i <= max; ++i)
- strcpy(list[i] + no_offset, no);
- return 7;
- }
- } /* end FORCE all */
- else
- {
- vector[bytenum] ^= maskbit[bitnum];
- strcpy(list[current] + no_offset, no);
- return 8;
- } /* end FORCE one */
- } /* end of "off states " */
- } /* end of FORCE */
- } /* tags */
-
-
- /*
- * is_set() returns zero if the item passed is selected, non-zero otherwise.
- */
-
- int is_set(word n)
- { /* is_set */
- /* n/8 == byte offset, n%8 == bit offset */
- return vector[n / 8] & maskbit[n % 8];
- } /* is_set */
-
-
- /*
- * Return the input list to its original value by removing the "YES/NO"
- * text at the end of each element.
- */
-
- static void trim_list(byte **list, word list_max)
- { /* trim_list */
- int i;
- byte *s;
-
- for (i = 0; i < list_max; ++i)
- {
- /* skip tag */
- for (s = list[i] + strlen(list[i]) - 1; s > list[i]; --s)
- {
- if (! isspace(*s))
- break;
- }
- /* skip tag */
- for (;s > list[i]; --s)
- {
- if (isspace(*s))
- break;
- }
- /* trim spaces */
- for (;s > list[i]; --s)
- {
- if (! isspace(*s))
- break;
- }
- *++s = 0;
- }
- } /* trim_list */
-
-
- /* end-of-file */