/* -*- c -*- ------------------------------------------------------------- * * * Copyright 2004-2005 Murali Krishnan Ganapathy - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ #include #include #include "tui.h" #include "syslnx.h" #include "com32io.h" #include "scancodes.h" #include com32sys_t inreg,outreg; // Global register sets for use char bkspstr[] = " \b$"; char eolstr[] = "\n$"; #define GETSTRATTR 0x07 // Reads a line of input from stdin. Replace CR with NUL byte // password <> 0 implies not echoed on screen // showoldvalue <> 0 implies currentvalue displayed first // If showoldvalue <> 0 then caller responsibility to ensure that // str is NULL terminated. void getuserinput(char *stra, unsigned int size, unsigned int password, unsigned int showoldvalue) { unsigned char c,scan; char *p,*q; // p = current char of string, q = tmp char *last; // The current last char of string char *str; // pointer to string which is going to be allocated char page; char row,col; char start,end; // Cursor shape char fudge; // How many chars should be removed from output char insmode; // Are we in insert or overwrite page = getdisppage(); getpos(&row,&col,page); // Get current position getcursorshape(&start,&end); insmode = 1; str = (char *)malloc(size+1); // Allocate memory to store user input memset(str,0,size+1); // Zero it out if (password != 0) showoldvalue = 0; // Password's never displayed if (showoldvalue != 0) strcpy(str,stra); // If show old value copy current value last = str; while (*last) {last++;} // Find the terminating null byte p = str+ strlen(str); if (insmode == 0) setcursorshape(1,7); // Block cursor else setcursorshape(6,7); // Normal cursor // Invariants: p is the current char // col is the corresponding column on the screen if (password == 0) // Not a password, print initial value { gotoxy(row,col,page); csprint(str,GETSTRATTR); } while (1) { // Do forever c = inputc(&scan); if (c == '\r') break; // User hit Enter getout of loop if (scan == ESCAPE) // User hit escape getout and nullify string { *str = 0; break; } fudge = 0; // if scan code is regognized do something // else if char code is recognized do something // else ignore switch(scan) { case HOMEKEY: p = str; break; case ENDKEY: p = last; break; case LTARROW: if (p > str) p--; break; case CTRLLT: if (p==str) break; if (*p == ' ') while ((p > str) && (*p == ' ')) p--; else { if (*(p-1) == ' ') { p--; while ((p > str) && (*p == ' ')) p--; } } while ((p > str) && ((*p == ' ') || (*(p-1) != ' '))) p--; break; case RTARROW: if (p < last) p++; break; case CTRLRT: if (*p==0) break; // At end of string if (*p != ' ') while ((*p!=0) && (*p != ' ')) p++; while ((*p!=0) && ((*p == ' ') && (*(p+1) != ' '))) p++; if (*p==' ') p++; break; case DELETE: q = p; while (*(q+1)) {*q = *(q+1); q++; } if (last > str) last--; fudge = 1; break; case INSERT: insmode = 1-insmode; // Switch mode if (insmode == 0) setcursorshape(1,7); // Block cursor else setcursorshape(6,7); // Normal cursor break; default: // Unrecognized scan code, look at the ascii value switch (c) { case '\b': // Move over by one q=p; while ( q <= last ) { *(q-1)=*q; q++;} if (last > str) last--; if (p > str) p--; fudge = 1; break; case '\x15': /* Ctrl-U: kill input */ fudge = last-str; while ( p > str ) *p--=0; p = str; *p=0; last = str; break; default: // Handle insert and overwrite mode if ((c >= ' ') && (c < 128) && ((unsigned int)(p-str) < size-1) ) { if (insmode == 0) { // Overwrite mode if (p==last) last++; *last = 0; *p++ = c; } else { // Insert mode if (p==last) { // last char last++; *last=0; *p++=c; } else { // Non-last char q=last++; while (q >= p) { *q=*(q-1); q--;} *p++=c; } } } else beep(); } break; } // Now the string has been modified, print it if (password == 0) { gotoxy(row,col,page); csprint(str,GETSTRATTR); if (fudge > 0) cprint(' ',GETSTRATTR,fudge,page); gotoxy(row,col+(p-str),page); } } *p = '\0'; if (password == 0) csprint("\r\n",GETSTRATTR); setcursorshape(start,end); // Block cursor // If user hit ESCAPE so return without any changes if (scan != ESCAPE) strcpy(stra,str); free(str); } /* Print a C string (NUL-terminated) */ void cswprint(const char *str,char attr,char left) { char page = getdisppage(); char newattr=0,cha,chb; char row,col; char nr,nc; nr = getnumrows(); nc = getnumcols(); getpos(&row,&col,page); while ( *str ) { switch (*str) { case '\b': --col; break; case '\n': ++row; col = left; break; case '\r': //col=left; break; case BELL: // Bell Char beep(); break; case CHRELATTR: // change attribute (relatively) case CHABSATTR: // change attribute (absolute) cha = *(str+1); chb = *(str+2); if ((((cha >= '0') && (cha <= '9')) || ((cha >= 'A') && (cha <= 'F'))) && (((chb >= '0') && (chb <= '9')) || ((chb >= 'A') && (chb <= 'F')))) // Next two chars are legal { if ((cha >= 'A') && (cha <= 'F')) cha = cha - 'A'+10; else cha = cha - '0'; if ((chb >= 'A') && (chb <= 'F')) chb = chb - 'A'+10; else chb = chb - '0'; newattr = (cha << 4) + chb; attr = (*str == CHABSATTR ? newattr : attr ^ newattr); str += 2; // Will be incremented again later } break; default: putch(*str, attr, page); ++col; } if (col >= nc) { ++row; col=left; } if (row > nr) { scrollup(); row= nr; } gotoxy(row,col,page); str++; } } void clearwindow(char top, char left, char bot, char right, char page, char fillchar, char fillattr) { char x; for (x=top; x < bot+1; x++) { gotoxy(x,left,page); cprint(fillchar,fillattr,right-left+1,page); } } void cls(void) { unsigned char dp = getdisppage(); gotoxy(0,0,dp); cprint(' ',GETSTRATTR,(1+getnumrows())*getnumcols(),dp); } //////////////////////////////Box Stuff // This order of numbers must match // the values of BOX_TOPLEFT,... in the header file unsigned char SINSIN_CHARS[] = {218,192,191,217, //Corners 196,179, // Horiz and Vertical 195,180,194,193,197}; // Connectors & Middle unsigned char DBLDBL_CHARS[] = {201,200,187,188, // Corners 205,186, // Horiz and Vertical 199,182,203,202,206}; // Connectors & Middle unsigned char SINDBL_CHARS[] = {214,211,183,189, // Corners 196,186, // Horiz & Vert 199,182,210,208,215}; // Connectors & Middle unsigned char DBLSIN_CHARS[] = {213,212,184,190, // Corners 205,179, // Horiz & Vert 198,181,209,207,216}; // Connectors & Middle unsigned char * getboxchars(boxtype bt) { switch (bt) { case BOX_SINSIN: return SINSIN_CHARS; break; case BOX_DBLDBL: return DBLDBL_CHARS; break; case BOX_SINDBL: return SINDBL_CHARS; break; case BOX_DBLSIN: return DBLSIN_CHARS; break; default: return SINSIN_CHARS; break; } return SINSIN_CHARS; } // Draw box and lines void drawbox(char top,char left,char bot, char right, char page, char attr,boxtype bt) { unsigned char *box_chars; // pointer to array of box chars unsigned char x; box_chars = getboxchars(bt); // Top border gotoxy(top,left,page); cprint(box_chars[BOX_TOPLEFT],attr,1,page); gotoxy(top,left+1,page); cprint(box_chars[BOX_TOP],attr,right-left,page); gotoxy(top,right,page); cprint(box_chars[BOX_TOPRIGHT],attr,1,page); // Bottom border gotoxy(bot,left,page); cprint(box_chars[BOX_BOTLEFT],attr,1,page); gotoxy(bot,left+1,page); cprint(box_chars[BOX_BOT],attr,right-left,page); gotoxy(bot,right,page); cprint(box_chars[BOX_BOTRIGHT],attr,1,page); // Left & right borders for (x=top+1; x < bot; x++) { gotoxy(x,left,page); cprint(box_chars[BOX_LEFT],attr,1,page); gotoxy(x,right,page); cprint(box_chars[BOX_RIGHT],attr,1,page); } } void drawhorizline(char top, char left, char right, char page, char attr, boxtype bt, char dumb) { unsigned char start,end; unsigned char *box_chars = getboxchars(bt); if (dumb==0) { start = left+1; end = right-1; } else { start = left; end = right; } gotoxy(top,start,page); cprint(box_chars[BOX_HORIZ],attr,end-start+1,page); if (dumb == 0) { gotoxy(top,left,page); cprint(box_chars[BOX_LTRT],attr,1,page); gotoxy(top,right,page); cprint(box_chars[BOX_RTLT],attr,1,page); } }