/* -*- 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); }