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