Adding upstream version 4.00~pre61+dfsg.
[syslinux-debian/hramrach.git] / com32 / cmenu / libmenu / tui.c
blobdd69277ac0a0afed9fd3c03333600163cd2a3b42
1 /* -*- c -*- ------------------------------------------------------------- *
3 * Copyright 2004-2006 Murali Krishnan Ganapathy - All Rights Reserved
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.
11 * ----------------------------------------------------------------------- */
13 #include "tui.h"
14 #include <string.h>
15 #include <com32.h>
16 #include <stdlib.h>
17 #include "com32io.h"
19 com32sys_t inreg, outreg; // Global register sets for use
21 char bkspstr[] = " \b$";
22 char eolstr[] = "\n$";
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)
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
41 getpos(&row, &col, 0); // Get current position
42 getcursorshape(&start, &end);
43 insmode = 1;
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
50 if (showoldvalue != 0)
51 strcpy(str, stra); // If show old value copy current value
53 last = str;
54 while (*last) {
55 last++;
56 } // Find the terminating null byte
57 p = str + strlen(str);
59 if (insmode == 0)
60 setcursorshape(1, 7); // Block cursor
61 else
62 setcursorshape(6, 7); // Normal cursor
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
68 gotoxy(row, col);
69 csprint(str, GETSTRATTR);
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
77 *str = 0;
78 break;
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--;
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++;
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++;
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--;
183 *p++ = c;
186 } else
187 beep();
188 break;
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));
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);
209 //////////////////////////////Box Stuff
211 // Draw box and lines
212 void drawbox(const char top, const char left, const char bot,
213 const char right, const char attr)
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);
234 putchar(SI);
237 void drawhorizline(const char top, const char left, const char right,
238 const char attr, char dumb)
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;
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);
257 putchar(SI);