Home | History | Annotate | Download | only in libmenu
      1 /* -*- c -*- ------------------------------------------------------------- *
      2  *
      3  *   Copyright 2004-2006 Murali Krishnan Ganapathy - All Rights Reserved
      4  *
      5  *   This program is free software; you can redistribute it and/or modify
      6  *   it under the terms of the GNU General Public License as published by
      7  *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
      8  *   Boston MA 02111-1307, USA; either version 2 of the License, or
      9  *   (at your option) any later version; incorporated herein by reference.
     10  *
     11  * ----------------------------------------------------------------------- */
     12 
     13 #include "tui.h"
     14 #include <string.h>
     15 #include <com32.h>
     16 #include <stdlib.h>
     17 #include "com32io.h"
     18 
     19 com32sys_t inreg, outreg;	// Global register sets for use
     20 
     21 char bkspstr[] = " \b$";
     22 char eolstr[] = "\n$";
     23 
     24 // Reads a line of input from stdin. Replace CR with NUL byte
     25 // password <> 0 implies not echoed on screen
     26 // showoldvalue <> 0 implies currentvalue displayed first
     27 // If showoldvalue <> 0 then caller responsibility to ensure that
     28 // str is NULL terminated.
     29 void getuserinput(char *stra, unsigned int size, unsigned int password,
     30 		  unsigned int showoldvalue)
     31 {
     32     unsigned int c;
     33     char *p, *q;		// p = current char of string, q = tmp
     34     char *last;			// The current last char of string
     35     char *str;			// pointer to string which is going to be allocated
     36     char row, col;
     37     char start, end;		// Cursor shape
     38     char fudge;			// How many chars should be removed from output
     39     char insmode;		// Are we in insert or overwrite
     40 
     41     getpos(&row, &col, 0);	// Get current position
     42     getcursorshape(&start, &end);
     43     insmode = 1;
     44 
     45     str = (char *)malloc(size + 1);	// Allocate memory to store user input
     46     memset(str, 0, size + 1);	// Zero it out
     47     if (password != 0)
     48 	showoldvalue = 0;	// Password's never displayed
     49 
     50     if (showoldvalue != 0)
     51 	strcpy(str, stra);	// If show old value copy current value
     52 
     53     last = str;
     54     while (*last) {
     55 	last++;
     56     }				// Find the terminating null byte
     57     p = str + strlen(str);
     58 
     59     if (insmode == 0)
     60 	setcursorshape(1, 7);	// Block cursor
     61     else
     62 	setcursorshape(6, 7);	// Normal cursor
     63 
     64     // Invariants: p is the current char
     65     // col is the corresponding column on the screen
     66     if (password == 0)		// Not a password, print initial value
     67     {
     68 	gotoxy(row, col);
     69 	csprint(str, GETSTRATTR);
     70     }
     71     while (1) {			// Do forever
     72 	c = get_key(stdin, 0);
     73 	if (c == KEY_ENTER)
     74 	    break;		// User hit Enter getout of loop
     75 	if (c == KEY_ESC)	// User hit escape getout and nullify string
     76 	{
     77 	    *str = 0;
     78 	    break;
     79 	}
     80 	fudge = 0;
     81 	// if scan code is regognized do something
     82 	// else if char code is recognized do something
     83 	// else ignore
     84 	switch (c) {
     85 	case KEY_HOME:
     86 	    p = str;
     87 	    break;
     88 	case KEY_END:
     89 	    p = last;
     90 	    break;
     91 	case KEY_LEFT:
     92 	    if (p > str)
     93 		p--;
     94 	    break;
     95 	case KEY_CTRL(KEY_LEFT):
     96 	    if (p == str)
     97 		break;
     98 	    if (*p == ' ')
     99 		while ((p > str) && (*p == ' '))
    100 		    p--;
    101 	    else {
    102 		if (*(p - 1) == ' ') {
    103 		    p--;
    104 		    while ((p > str) && (*p == ' '))
    105 			p--;
    106 		}
    107 	    }
    108 	    while ((p > str) && ((*p == ' ') || (*(p - 1) != ' ')))
    109 		p--;
    110 	    break;
    111 	case KEY_RIGHT:
    112 	    if (p < last)
    113 		p++;
    114 	    break;
    115 	case KEY_CTRL(KEY_RIGHT):
    116 	    if (*p == 0)
    117 		break;		// At end of string
    118 	    if (*p != ' ')
    119 		while ((*p != 0) && (*p != ' '))
    120 		    p++;
    121 	    while ((*p != 0) && ((*p == ' ') && (*(p + 1) != ' ')))
    122 		p++;
    123 	    if (*p == ' ')
    124 		p++;
    125 	    break;
    126 	case KEY_DEL:
    127 	case KEY_DELETE:
    128 	    q = p;
    129 	    while (*(q + 1)) {
    130 		*q = *(q + 1);
    131 		q++;
    132 	    }
    133 	    if (last > str)
    134 		last--;
    135 	    fudge = 1;
    136 	    break;
    137 	case KEY_INSERT:
    138 	    insmode = 1 - insmode;	// Switch mode
    139 	    if (insmode == 0)
    140 		setcursorshape(1, 7);	// Block cursor
    141 	    else
    142 		setcursorshape(6, 7);	// Normal cursor
    143 	    break;
    144 	case KEY_BACKSPACE:		// Move over by one
    145 		q = p;
    146 		while (q <= last) {
    147 		    *(q - 1) = *q;
    148 		    q++;
    149 		}
    150 		if (last > str)
    151 		    last--;
    152 		if (p > str)
    153 		    p--;
    154 		fudge = 1;
    155 		break;
    156 	case KEY_CTRL('U'):	/* Ctrl-U: kill input */
    157 		fudge = last - str;
    158 		while (p > str)
    159 		    *p-- = 0;
    160 		p = str;
    161 		*p = 0;
    162 		last = str;
    163 		break;
    164 	default:		// Handle insert and overwrite mode
    165 		if ((c >= ' ') && (c < 128) &&
    166 		    ((unsigned int)(p - str) < size - 1)) {
    167 		    if (insmode == 0) {	// Overwrite mode
    168 			if (p == last)
    169 			    last++;
    170 			*last = 0;
    171 			*p++ = c;
    172 		    } else {	// Insert mode
    173 			if (p == last) {	// last char
    174 			    last++;
    175 			    *last = 0;
    176 			    *p++ = c;
    177 			} else {	// Non-last char
    178 			    q = last++;
    179 			    while (q >= p) {
    180 				*q = *(q - 1);
    181 				q--;
    182 			    }
    183 			    *p++ = c;
    184 			}
    185 		    }
    186 		} else
    187 		    beep();
    188 	    break;
    189 	}
    190 	// Now the string has been modified, print it
    191 	if (password == 0) {
    192 	    gotoxy(row, col);
    193 	    csprint(str, GETSTRATTR);
    194 	    if (fudge > 0)
    195 		cprint(' ', GETSTRATTR, fudge);
    196 	    gotoxy(row, col + (p - str));
    197 	}
    198     } /* while */
    199     *p = '\0';
    200     if (password == 0)
    201 	csprint("\r\n", GETSTRATTR);
    202     setcursorshape(start, end);	// Block cursor
    203     // If user hit ESCAPE so return without any changes
    204     if (c != KEY_ESC)
    205 	strcpy(stra, str);
    206     free(str);
    207 }
    208 
    209 //////////////////////////////Box Stuff
    210 
    211 // Draw box and lines
    212 void drawbox(const char top, const char left, const char bot,
    213 	     const char right, const char attr)
    214 {
    215     unsigned char x;
    216 	putchar(SO);
    217     // Top border
    218     gotoxy(top, left);
    219     putch(TOP_LEFT_CORNER_BORDER, attr);
    220     cprint(TOP_BORDER, attr, right - left - 1);
    221     putch(TOP_RIGHT_CORNER_BORDER, attr);
    222     // Bottom border
    223     gotoxy(bot, left);
    224     putch(BOTTOM_LEFT_CORNER_BORDER, attr);
    225     cprint(BOTTOM_BORDER, attr, right - left - 1);
    226     putch(BOTTOM_RIGHT_CORNER_BORDER, attr);
    227     // Left & right borders
    228     for (x = top + 1; x < bot; x++) {
    229 	gotoxy(x, left);
    230 	putch(LEFT_BORDER, attr);
    231 	gotoxy(x, right);
    232 	putch(RIGHT_BORDER, attr);
    233     }
    234 	putchar(SI);
    235 }
    236 
    237 void drawhorizline(const char top, const char left, const char right,
    238 		   const char attr, char dumb)
    239 {
    240     unsigned char start, end;
    241     if (dumb == 0) {
    242 	start = left + 1;
    243 	end = right - 1;
    244     } else {
    245 	start = left;
    246 	end = right;
    247     }
    248     gotoxy(top, start);
    249 	putchar(SO);
    250     cprint(MIDDLE_BORDER, attr, end - start + 1);
    251     if (dumb == 0) {
    252 	gotoxy(top, left);
    253 	putch(MIDDLE_BORDER, attr);
    254 	gotoxy(top, right);
    255 	putch(MIDDLE_BORDER, attr);
    256     }
    257 	putchar(SI);
    258 }
    259