blob: dd69277ac0a0afed9fd3c03333600163cd2a3b42 [file] [log] [blame]
/* -*- 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);
}