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.
getuserinput(char * stra,unsigned int size,unsigned int password,unsigned int showoldvalue)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
drawbox(const char top,const char left,const char bot,const char right,const char attr)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 
drawhorizline(const char top,const char left,const char right,const char attr,char dumb)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