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