00001 #include <termios.h>
00002 #include <unistd.h>
00003 #include <stdlib.h>
00004 #include <signal.h>
00005 #include <stdio.h>
00006 #include <string.h>
00007
00008
00009 static struct termios save_termios;
00010 static int ttysavefd = -1;
00011 static enum { CBREAK, RESET } ttystate = RESET;
00012
00013 #define HISTORY_SIZE 100
00014 char history[HISTORY_SIZE][255];
00015
00016 int tty_cbreak(int fd)
00017 {
00018 struct termios buf;
00019 if(tcgetattr(fd, & save_termios) < 0)
00020 return -1;
00021
00022 buf = save_termios;
00023
00024 buf.c_lflag &= ~(ECHO | ICANON);
00025 buf.c_cc[VMIN] = 1;
00026 buf.c_cc[VTIME] = 0;
00027
00028 if(tcsetattr(fd, TCSAFLUSH, &buf) < 0)
00029 return -1;
00030
00031 ttysavefd = fd;
00032 ttystate = CBREAK;
00033 return 0;
00034 }
00035
00036 int tty_reset(int fd)
00037 {
00038 if(ttystate != CBREAK) return 0;
00039 if(tcsetattr(fd, TCSAFLUSH, &save_termios) < 0)
00040 return -1;
00041 ttystate = RESET;
00042 return 0;
00043 }
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 static int c_line = 0;
00055
00056 void get_line(char *buff)
00057 {
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 if(tty_cbreak(STDIN_FILENO) < 0)
00077 {
00078
00079 exit(0);
00080 }
00081
00082 int h_line;
00083 int c_char = 0;
00084 int l_char = 0;
00085 int t;
00086 int i;
00087 char c;
00088
00089 h_line = c_line;
00090 c_char = 0;
00091 l_char = 0;
00092 memset(history[c_line],0,sizeof(history[c_line]));
00093
00094 while( (i = read(STDIN_FILENO, &c, 1)) == 1)
00095 {
00096 c &= 0xff;
00097 switch(c)
00098 {
00099 case 0xa:
00100 putchar(0xa);
00101 fflush(stdout);
00102 break;
00103 case 0x8:
00104 case 0x7f:
00105
00106 if(c_char == 0) break;
00107 for(t=c_char;t<=l_char;t++)
00108 {
00109 history[c_line][t-1] = history[c_line][t];
00110 }
00111 history[c_line][l_char] = '\0';
00112 l_char--;
00113 c_char--;
00114
00115
00116 putchar(0x8);
00117 for(t=c_char;t<l_char;t++)
00118 {
00119 putchar(history[c_line][t]);
00120 }
00121 putchar(' ');
00122 for(t=c_char;t<l_char+1;t++)
00123 putchar(0x8);
00124
00125 fflush(stdout);
00126 break;
00127
00128 case 0x1b:
00129 {
00130 i = read(STDIN_FILENO, &c, 1);
00131 i = read(STDIN_FILENO, &c, 1);
00132 if(c == 0x43)
00133 {
00134 if(c_char < l_char)
00135 {
00136 c_char++;
00137 putchar(0x1b);
00138 putchar(0x5b);
00139 putchar(0x43);
00140 }
00141 }
00142 else if(c==0x44)
00143 {
00144 if(c_char > 0)
00145 {
00146 c_char--;
00147 putchar(0x1b);
00148 putchar(0x5b);
00149 putchar(0x44);
00150 }
00151 }
00152 else if(c==0x41)
00153 {
00154 h_line--;
00155 if(h_line < 0) h_line = HISTORY_SIZE-1;
00156
00157 for(t=c_char;t>0;t--)
00158 {
00159 putchar(0x8);
00160 }
00161 for(t=0;t<l_char;t++)
00162 {
00163 putchar(' ');
00164 }
00165 for(t=l_char;t>0;t--)
00166 {
00167 putchar(0x8);
00168 }
00169 l_char = 0;
00170 c_char = 0;
00171 memset(history[c_line],0,sizeof(history[c_line]));
00172 while(history[h_line][c_char])
00173 {
00174 putchar(history[h_line][c_char]);
00175 history[c_line][c_char] = history[h_line][c_char];
00176 c_char++;
00177 }
00178 l_char = c_char;
00179 }
00180 else if(c==0x42)
00181 {
00182 h_line++;
00183 if(h_line >= HISTORY_SIZE) h_line = 0;
00184 for(t=c_char;t>0;t--)
00185 {
00186 putchar(0x8);
00187 }
00188 for(t=0;t<l_char;t++)
00189 {
00190 putchar(' ');
00191 }
00192 for(t=l_char;t>0;t--)
00193 {
00194 putchar(0x8);
00195 }
00196 l_char = 0;
00197 c_char = 0;
00198 memset(history[c_line],0,sizeof(history[c_line]));
00199 while(history[h_line][c_char])
00200 {
00201 putchar(history[h_line][c_char]);
00202 history[c_line][c_char] = history[h_line][c_char];
00203 c_char++;
00204 }
00205 l_char = c_char;
00206 }
00207 fflush(stdout);
00208 break;
00209 }
00210
00211 default:
00212
00213 for(t=l_char;t>c_char;t--)
00214 {
00215 history[c_line][t] = history[c_line][t-1];
00216 }
00217 history[c_line][c_char] = c;
00218 l_char++;
00219 c_char++;
00220
00221
00222 for(t=c_char-1;t<l_char;t++)
00223 {
00224 putchar(history[c_line][t]);
00225 }
00226 for(t=c_char;t<l_char;t++)
00227 {
00228 putchar(0x8);
00229 }
00230 fflush(stdout);
00231 break;
00232 }
00233
00234 if(c == 0xa) break;
00235 }
00236
00237
00238 strcpy(buff,history[c_line]);
00239
00240 c_line++;
00241 if(c_line >= HISTORY_SIZE) c_line = 0;
00242
00243 tty_reset(STDIN_FILENO);
00244 }
00245
00246 char one_line_buff[255];
00247
00248 void get_one_line(char *buff)
00249 {
00250 fflush(stdout);
00251 if(tty_cbreak(STDIN_FILENO) < 0)
00252 {
00253
00254 exit(0);
00255 }
00256
00257 int c_char = 0;
00258 int l_char = 0;
00259 int t;
00260 int i;
00261 char c;
00262
00263 c_char = 0;
00264 l_char = 0;
00265 memset(one_line_buff,0,sizeof(one_line_buff));
00266
00267 while( (i = read(STDIN_FILENO, &c, 1)) == 1)
00268 {
00269 c &= 0xff;
00270 switch(c)
00271 {
00272 case 0xa:
00273 putchar(0xa);
00274 fflush(stdout);
00275 break;
00276 case 0x8:
00277 case 0x7f:
00278
00279 if(c_char == 0) break;
00280 for(t=c_char;t<=l_char;t++)
00281 {
00282 one_line_buff[t-1] = one_line_buff[t];
00283 }
00284 one_line_buff[l_char] = '\0';
00285 l_char--;
00286 c_char--;
00287
00288
00289 putchar(0x8);
00290 for(t=c_char;t<l_char;t++)
00291 {
00292 putchar(one_line_buff[t]);
00293 }
00294 putchar(' ');
00295 for(t=c_char;t<l_char+1;t++)
00296 putchar(0x8);
00297
00298 fflush(stdout);
00299 break;
00300
00301 case 0x1b:
00302 {
00303 i = read(STDIN_FILENO, &c, 1);
00304 i = read(STDIN_FILENO, &c, 1);
00305 if(c == 0x43)
00306 {
00307 if(c_char < l_char)
00308 {
00309 c_char++;
00310 putchar(0x1b);
00311 putchar(0x5b);
00312 putchar(0x43);
00313 }
00314 }
00315 else if(c==0x44)
00316 {
00317 if(c_char > 0)
00318 {
00319 c_char--;
00320 putchar(0x1b);
00321 putchar(0x5b);
00322 putchar(0x44);
00323 }
00324 }
00325 fflush(stdout);
00326 break;
00327 }
00328
00329 default:
00330
00331 for(t=l_char;t>c_char;t--)
00332 {
00333 one_line_buff[t] = one_line_buff[t-1];
00334 }
00335 one_line_buff[c_char] = c;
00336 l_char++;
00337 c_char++;
00338
00339
00340 for(t=c_char-1;t<l_char;t++)
00341 {
00342 putchar(one_line_buff[t]);
00343 }
00344 for(t=c_char;t<l_char;t++)
00345 {
00346 putchar(0x8);
00347 }
00348 fflush(stdout);
00349 break;
00350 }
00351
00352 if(c == 0xa) break;
00353 }
00354
00355
00356 strcpy(buff,one_line_buff);
00357
00358 tty_reset(STDIN_FILENO);
00359 }