Listing 2

/* A simple function for line input */
/* alternate version using BIOS and direct screen access */
/* compiled with Turbo C 2.0 */
/* Philip J. Erdelsky - 01 JAN 1991 */
/* object code may be used freely */

static int key() {
  int k = bioskey(0);
  return (k&0xFF)!=0 ? k&0xFF : k;
}

int line_input(int far *screen, char *text, int text_length,
                  int display_length) {
  /* start display as though operator had struck Home or End key */
  int k = 0x4700; /* Home 0x4700 or End 0x4F00 */
  int finished = 0;
  int cursor_position;
  int position_within_text;
  while (1) {
    switch (k) {
      /* finish line input and exit if k==0x000D (Enter key) */
      /* other terminating keys could be added, if desired */
      case 0x000D:
        finished = 1;
        /* fall through to next case */
      /* move cursor to left end of text if k==0x4700 (Home key) */
      case 0x4700:
        cursor_position = position_within_text = 0;
        break;
      /* move cursor to right end of text if k==0x4F00 (End key) */
      case 0x4F00:
        position_within_text = strlen(text);
        cursor_position =
          position_within_text<display_length ? position_within_text :
          display_length-1;
        break;
      /* move cursor left one place if k==0x4B00 (left arrow key) */
      case 0x4B00:
        if (position_within_text>0) {
          position_within_text--;
          if (cursor_position>0) cursor_position--;
        }
        break;
      /* move cursor right one place if k==0x4D00 (right arrow key) */
      case 0x4D00:
        if (position_within_text<strlen(text)) {
          position_ within_text++;
          if (cursor_position<display_length-1)
            cursor_position++;
        }
        break;
      /* move cursor left one place and delete character under cursor */
      /* if k==0x0008 (backspace key) */
      case 0x0008:
        if (position_within_text==0) break;
        position_within_text--;
        if (cursor_position>0) cursor_position--;
        /* fall through to next case */
      /* delete character under cursor if k==0x5300 (Del key) */
      case 0x5300:
        if (text[position_within_text]!=0)
          strcpy(text+position_within_text, text+position_within_text+1);
        break;
      /* insert new character to left of character under cursor */
      default:
        if (' '<=k && k<='~' && strlen(text)<text_length) {
          char *t = text+position_within_text;
          do {
            int temp = *t;
            *t++ = k;
            k = temp;
          } while (k!=0);
          *t = 0;
          position_within_text++;
          if (cursor_position<display_length-1)
            cursor_position++;
        }
    }
    /* redisplay entire line */
    {
      int hidden_characters_at_left =
        position_within_text_cursor_position;
      char *t = text+hidden_characters_at_left;
      int i;
      /* display arrows at left end if necessary */
      screen[-1] = hidden_characters_at_left!=0 ? 0x0FAE : 0x0700| ' ';
      /* display text and trailing spaces, if any */
      /* use reverse video to mark cursor position */
      for (i=0; i<display_length; i++) {
        int c;
        screen[i] = (i==cursor_position && !finished ? 0x7000 : 0x0700) |
                    (*t==0 ? ' ' : (c = *t++)==' ' ? 0xFA : c);
      }
      /* display arrows at right end if necessary */
      screen[i] = *t!=0 ? 0x0FAF : 0x0700|' ';
    }
    if (finished) return k;
    k = key();
  }
}

/* test program */

void main(int argc, char **argv) {
  char text[40];
  int k;
  int far *screen =
    (int far *) ((biosequip()&0x30)==0x30 ? 0xB0000000L : 0xB8000000L);
  strcpy(text, argc>1 ? argv[1] : "");
  k = line_input(screen+12*80+2, text, sizeof(text)-1, 20);
  printf("\nreturn value=%04X text=\"%s\"\n", k, text);
}

/* End of File */