259 lines
6.2 KiB
C
259 lines
6.2 KiB
C
/* -*- c -*- ------------------------------------------------------------- *
|
|
*
|
|
* Copyright 2004-2006 Murali Krishnan Ganapathy - All Rights Reserved
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, Inc., 53 Temple Place Ste 330,
|
|
* Boston MA 02111-1307, USA; either version 2 of the License, or
|
|
* (at your option) any later version; incorporated herein by reference.
|
|
*
|
|
* ----------------------------------------------------------------------- */
|
|
|
|
#include "tui.h"
|
|
#include <string.h>
|
|
#include <com32.h>
|
|
#include <stdlib.h>
|
|
#include "com32io.h"
|
|
|
|
com32sys_t inreg, outreg; // Global register sets for use
|
|
|
|
char bkspstr[] = " \b$";
|
|
char eolstr[] = "\n$";
|
|
|
|
// Reads a line of input from stdin. Replace CR with NUL byte
|
|
// password <> 0 implies not echoed on screen
|
|
// showoldvalue <> 0 implies currentvalue displayed first
|
|
// If showoldvalue <> 0 then caller responsibility to ensure that
|
|
// str is NULL terminated.
|
|
void getuserinput(char *stra, unsigned int size, unsigned int password,
|
|
unsigned int showoldvalue)
|
|
{
|
|
unsigned int c;
|
|
char *p, *q; // p = current char of string, q = tmp
|
|
char *last; // The current last char of string
|
|
char *str; // pointer to string which is going to be allocated
|
|
char row, col;
|
|
char start, end; // Cursor shape
|
|
char fudge; // How many chars should be removed from output
|
|
char insmode; // Are we in insert or overwrite
|
|
|
|
getpos(&row, &col, 0); // Get current position
|
|
getcursorshape(&start, &end);
|
|
insmode = 1;
|
|
|
|
str = (char *)malloc(size + 1); // Allocate memory to store user input
|
|
memset(str, 0, size + 1); // Zero it out
|
|
if (password != 0)
|
|
showoldvalue = 0; // Password's never displayed
|
|
|
|
if (showoldvalue != 0)
|
|
strcpy(str, stra); // If show old value copy current value
|
|
|
|
last = str;
|
|
while (*last) {
|
|
last++;
|
|
} // Find the terminating null byte
|
|
p = str + strlen(str);
|
|
|
|
if (insmode == 0)
|
|
setcursorshape(1, 7); // Block cursor
|
|
else
|
|
setcursorshape(6, 7); // Normal cursor
|
|
|
|
// Invariants: p is the current char
|
|
// col is the corresponding column on the screen
|
|
if (password == 0) // Not a password, print initial value
|
|
{
|
|
gotoxy(row, col);
|
|
csprint(str, GETSTRATTR);
|
|
}
|
|
while (1) { // Do forever
|
|
c = get_key(stdin, 0);
|
|
if (c == KEY_ENTER)
|
|
break; // User hit Enter getout of loop
|
|
if (c == KEY_ESC) // User hit escape getout and nullify string
|
|
{
|
|
*str = 0;
|
|
break;
|
|
}
|
|
fudge = 0;
|
|
// if scan code is regognized do something
|
|
// else if char code is recognized do something
|
|
// else ignore
|
|
switch (c) {
|
|
case KEY_HOME:
|
|
p = str;
|
|
break;
|
|
case KEY_END:
|
|
p = last;
|
|
break;
|
|
case KEY_LEFT:
|
|
if (p > str)
|
|
p--;
|
|
break;
|
|
case KEY_CTRL(KEY_LEFT):
|
|
if (p == str)
|
|
break;
|
|
if (*p == ' ')
|
|
while ((p > str) && (*p == ' '))
|
|
p--;
|
|
else {
|
|
if (*(p - 1) == ' ') {
|
|
p--;
|
|
while ((p > str) && (*p == ' '))
|
|
p--;
|
|
}
|
|
}
|
|
while ((p > str) && ((*p == ' ') || (*(p - 1) != ' ')))
|
|
p--;
|
|
break;
|
|
case KEY_RIGHT:
|
|
if (p < last)
|
|
p++;
|
|
break;
|
|
case KEY_CTRL(KEY_RIGHT):
|
|
if (*p == 0)
|
|
break; // At end of string
|
|
if (*p != ' ')
|
|
while ((*p != 0) && (*p != ' '))
|
|
p++;
|
|
while ((*p != 0) && ((*p == ' ') && (*(p + 1) != ' ')))
|
|
p++;
|
|
if (*p == ' ')
|
|
p++;
|
|
break;
|
|
case KEY_DEL:
|
|
case KEY_DELETE:
|
|
q = p;
|
|
while (*(q + 1)) {
|
|
*q = *(q + 1);
|
|
q++;
|
|
}
|
|
if (last > str)
|
|
last--;
|
|
fudge = 1;
|
|
break;
|
|
case KEY_INSERT:
|
|
insmode = 1 - insmode; // Switch mode
|
|
if (insmode == 0)
|
|
setcursorshape(1, 7); // Block cursor
|
|
else
|
|
setcursorshape(6, 7); // Normal cursor
|
|
break;
|
|
case KEY_BACKSPACE: // Move over by one
|
|
q = p;
|
|
while (q <= last) {
|
|
*(q - 1) = *q;
|
|
q++;
|
|
}
|
|
if (last > str)
|
|
last--;
|
|
if (p > str)
|
|
p--;
|
|
fudge = 1;
|
|
break;
|
|
case KEY_CTRL('U'): /* Ctrl-U: kill input */
|
|
fudge = last - str;
|
|
while (p > str)
|
|
*p-- = 0;
|
|
p = str;
|
|
*p = 0;
|
|
last = str;
|
|
break;
|
|
default: // Handle insert and overwrite mode
|
|
if ((c >= ' ') && (c < 128) &&
|
|
((unsigned int)(p - str) < size - 1)) {
|
|
if (insmode == 0) { // Overwrite mode
|
|
if (p == last)
|
|
last++;
|
|
*last = 0;
|
|
*p++ = c;
|
|
} else { // Insert mode
|
|
if (p == last) { // last char
|
|
last++;
|
|
*last = 0;
|
|
*p++ = c;
|
|
} else { // Non-last char
|
|
q = last++;
|
|
while (q >= p) {
|
|
*q = *(q - 1);
|
|
q--;
|
|
}
|
|
*p++ = c;
|
|
}
|
|
}
|
|
} else
|
|
beep();
|
|
break;
|
|
}
|
|
// Now the string has been modified, print it
|
|
if (password == 0) {
|
|
gotoxy(row, col);
|
|
csprint(str, GETSTRATTR);
|
|
if (fudge > 0)
|
|
cprint(' ', GETSTRATTR, fudge);
|
|
gotoxy(row, col + (p - str));
|
|
}
|
|
} /* while */
|
|
*p = '\0';
|
|
if (password == 0)
|
|
csprint("\r\n", GETSTRATTR);
|
|
setcursorshape(start, end); // Block cursor
|
|
// If user hit ESCAPE so return without any changes
|
|
if (c != KEY_ESC)
|
|
strcpy(stra, str);
|
|
free(str);
|
|
}
|
|
|
|
//////////////////////////////Box Stuff
|
|
|
|
// Draw box and lines
|
|
void drawbox(const char top, const char left, const char bot,
|
|
const char right, const char attr)
|
|
{
|
|
unsigned char x;
|
|
putchar(SO);
|
|
// Top border
|
|
gotoxy(top, left);
|
|
putch(TOP_LEFT_CORNER_BORDER, attr);
|
|
cprint(TOP_BORDER, attr, right - left - 1);
|
|
putch(TOP_RIGHT_CORNER_BORDER, attr);
|
|
// Bottom border
|
|
gotoxy(bot, left);
|
|
putch(BOTTOM_LEFT_CORNER_BORDER, attr);
|
|
cprint(BOTTOM_BORDER, attr, right - left - 1);
|
|
putch(BOTTOM_RIGHT_CORNER_BORDER, attr);
|
|
// Left & right borders
|
|
for (x = top + 1; x < bot; x++) {
|
|
gotoxy(x, left);
|
|
putch(LEFT_BORDER, attr);
|
|
gotoxy(x, right);
|
|
putch(RIGHT_BORDER, attr);
|
|
}
|
|
putchar(SI);
|
|
}
|
|
|
|
void drawhorizline(const char top, const char left, const char right,
|
|
const char attr, char dumb)
|
|
{
|
|
unsigned char start, end;
|
|
if (dumb == 0) {
|
|
start = left + 1;
|
|
end = right - 1;
|
|
} else {
|
|
start = left;
|
|
end = right;
|
|
}
|
|
gotoxy(top, start);
|
|
putchar(SO);
|
|
cprint(MIDDLE_BORDER, attr, end - start + 1);
|
|
if (dumb == 0) {
|
|
gotoxy(top, left);
|
|
putch(MIDDLE_BORDER, attr);
|
|
gotoxy(top, right);
|
|
putch(MIDDLE_BORDER, attr);
|
|
}
|
|
putchar(SI);
|
|
}
|