/* Terminalhanterare för Linux *:85 VT 2003 */ /* Av Jozef Swiatycki */ extern "C" { #include #include #include #include #ifndef TIOCGWINSZ #include #endif #include #include } #include "terminal.h" #define FKEYUNDEF 400 #if 0 #define KBDEBUG #endif namespace { // Escape-sekvenser genererade av funktionstangenter enligt VT100 const char *fkeytab[]={ "[11~", /* F1 */ "[12~", /* F2 */ "[13~", /* F3 */ "[14~", /* F4 */ "[15~", /* F5 */ "[17~", /* F6 */ "[18~", /* F7 */ "[19~", /* F8 */ "[20~", /* F9 */ "[21~", /* F10 */ "[23~", /* F11 */ "[24~", /* F12 */ "[25~", /* F13 */ "[26~", /* F14 */ "[28~", /* Hjälp */ "[29~", /* Utför */ "[31~", /* F17 */ "[32~", /* F18 */ "[33~", /* F19 */ "[34~", /* F20 */ "[1~", /* Home (gamla Sök) */ "[2~", /* Sätt in */ "[3~", /* Ta bort */ "[4~", /* End (gamla Välj ut) */ "[5~", /* Pageup (gamla Föreg) */ "[6~", /* Pagedown (gamla Nästa) */ "OA", /* Upp */ "OB", /* Ner */ "OD", /* Vänster */ "OC", /* Höger */ "OP", /* PF1 */ "OQ", /* PF2 */ "OR", /* PF3 */ "OS", /* PF4 */ "Oj", /* NKP x */ "Ok", /* NKP + */ "Oo", /* NKP / */ "Op", /* NKP 0 */ "Oq", /* NKP 1 */ "Or", /* NKP 2 */ "Os", /* NKP 3 */ "Ot", /* NKP 4 */ "Ou", /* NKP 5 */ "Ov", /* NKP 6 */ "Ow", /* NKP 7 */ "Ox", /* NKP 8 */ "Oy", /* NKP 9 */ "Om", /* NKP - */ "Ol", /* NKP , */ "On", /* NKP . */ "OM" /* NKP Enter */ }; const int FKEYMAX = sizeof(fkeytab) / sizeof(unsigned char *); enum FKnames { FK_F1, FK_F2, FK_F3, FK_F4, FK_F5, FK_F6, FK_F7, FK_F8, FK_F9, FK_F10, FK_F11, FK_F12, FK_F13, FK_F14, FK_Help, FK_Execute, FK_F17, FK_F18, FK_F19, FK_F20, FK_Home, FK_Insert, FK_Delete, FK_End, FK_Pageup, FK_Pagedown, FK_Up, FK_Down, FK_Left, FK_Right, FK_PF1, FK_PF2, FK_PF3, FK_PF4, FK_NKPtimes, FK_NKPplus, FK_NKPdiv, FK_NKP0, FK_NKP1, FK_NKP2, FK_NKP3, FK_NKP4, FK_NKP5, FK_NKP6, FK_NKP7, FK_NKP8, FK_NKP9, FK_NKPminus, FK_NKPcomma, FK_NKPdot, FK_NKPenter}; struct replstruct { FKnames fkname; const char *fkstr; }; const replstruct xtermtab[] = { {FK_F1, "OP"}, {FK_F2, "OQ"}, {FK_F3, "OR"}, {FK_F4, "OS"}, {FK_Home, "OH"}, {FK_End, "OF"} }; const replstruct linuxtab[] = { {FK_F1, "[[A"}, {FK_F2, "[[B"}, {FK_F3, "[[C"}, {FK_F4, "[[D"}, {FK_F5, "[[E"} }; const char * const gc[]={"jklmnqtuvwx", "gtrf/,5687."}; struct repls{ const char *type; const replstruct *replace; int siz; int tix; } repltab[] = { {"vt220", NULL, 0, 1}, {"xterm",xtermtab,sizeof(xtermtab)/sizeof(replstruct),0}, {"xterm-color",xtermtab,sizeof(xtermtab)/sizeof(replstruct),0}, {"linux",linuxtab,sizeof(linuxtab)/sizeof(replstruct),0} }; const int NOTT = sizeof(repltab) / sizeof(repls); const char *capatab[]={ "\033[J", /* Clear to end of display */ "\033[1J", /* Clear from begining of display */ "\033[0K", /* Clear to end of line */ "\033[1K", /* Clear begining of line */ "\033[2K", /* Clear line */ "\033[;H\033[2J", /* Clear screen */ "\033[%d;%dH", /* Cursor motion */ "\033[%d;%dr", /* Change scrolling region */ "\033[3g", /* Clear all tab stops */ "\033[%dB", /* Move down one line */ "\033[H", /* Home cursor */ "\033[1;%dr\033[%d;1H", /* Initialization string */ "\033[?1l\033>", /* Out of keypad transmit mode */ "\033[?1h\033=", /* Keypad transmit mode on */ "\033[%dD", /* Move cursor left one place */ "\033[5m", /* Turn on blinking */ "\033[1m", /* Enter bold mode */ "\033[m", /* Enter normal mode */ "\033[7m", /* Enter reverse mode */ "\033[%dC", /* Nondestructive space */ "\033[m", /* End stand-out mode */ "\033[7m", /* Begin stand-out mode */ "\033[M", /* Scroll reverse */ "\033[m", /* End underscore mode */ "\033[%dA", /* Up one line */ "\033[4m", /* Start underscore mode */ "\033[6n", /* Request Cursor Position */ "\033[%d;%dR", /* Cursor Position Answer */ "\033)0", /* Choose graphics as G1 */ "\016", /* Switch to G1 (graphics) */ "\033N", /* Switch to G2 (graphics) next char only */ "\017", /* Switch to G0 (normal) */ "\033[?8h", /* Auto-repeat keys */ "\0337", /* Save cursor and attributes */ "\0338", /* Restore cursor and attributes */ "\033[%d@", /* Insert characters */ "\033[%dP", /* Delete characters */ "\033[%dX", /* Erase charcters */ "\033[%dS", /* Scroll up */ "\033[%dT", /* Scroll down */ "\033[3%dm", /* Set foreground colour */ "\033[4%dm", /* Set background colour */ "\033[%dL", /* Insert lines */ "\033[%dM", /* Delete lines */ "\033[8;%d;%dt" /* Resize window */ }; enum {CLRED, CLRBD, CLREL, CLRBL, CLRL, CLRSCR, CURMOV, CHSCRL, CLTABS, MOVDOWN, HOMCUR, INISTR, KPEND, KPBEG, MOVLEFT, BLINKON, BOLDON, NORMON, REVON, MOVRIGHT, STANDOUTOFF, STANDOUTON, SCROLLREV, UNDEROFF, MOVUP, UNDERON, POSREQ, POSANS, SETGRAPH, GRAPHON, GRAPHNEXT,GRAPHOFF, AUTOREP, SAVECUR, RESETCUR, INSERT, DELETE, ERASE, SCROLLUP, SCROLLDOWN, FGCOLOUR, BGCOLOUR, INSLINS, DELLINS, RESWIN }; enum {LRCORN, URCORN, ULCORN, LLCORN, CROSS, HORL, TLEFT, TRIGHT, TBOTTOM, TTOP, VERL}; int tx; bool gron=false; struct termios savedterm; int rows=24, cols=80; bool szchd=false; void (*drawfunc)()=NULL; int tix(const char *str){ for(int i=0; i(readkey()); curget(eve.whereX, eve.whereY); return eve; } void terminal::clrscr(){ printf(capatab[CLRSCR]); fflush(stdout); } void terminal::clreod(){ printf(capatab[CLRED]); fflush(stdout); } void terminal::clrbod(){ printf(capatab[CLRBD]); fflush(stdout); } void terminal::clrbol(){ printf(capatab[CLRBL]); fflush(stdout); } void terminal::clreol(){ printf(capatab[CLREL]); fflush(stdout); } void terminal::clrln(){ printf(capatab[CLRL]); fflush(stdout); } void terminal::curmove(int x, int y){ printf(capatab[CURMOV],y, x); fflush(stdout); } void terminal::chscroll(int x, int y){ printf(capatab[CHSCRL],x,y); fflush(stdout); } void terminal::curdown(int n){ printf(capatab[MOVDOWN],n); fflush(stdout); } void terminal::curleft(int n){ printf(capatab[MOVLEFT],n); fflush(stdout); } void terminal::curright(int n){ printf(capatab[MOVRIGHT],n); fflush(stdout); } void terminal::curup(int n){ printf(capatab[MOVUP],n); fflush(stdout); } void terminal::curget(int& x, int& y){ char buf[10]; int i=0; printf(capatab[POSREQ]); fflush(stdout); do{ read(fileno(stdin),&buf[i++],1); }while (buf[i-1]!='R'); buf[i]='\0'; sscanf(buf,capatab[POSANS], &y, &x); } void terminal::savecur(){ printf(capatab[SAVECUR]); fflush(stdout); } void terminal::restcur(){ printf(capatab[RESETCUR]); fflush(stdout); } void terminal::bold(){ printf(capatab[BOLDON]); fflush(stdout); } void terminal::reverse(){ printf(capatab[REVON]); fflush(stdout); } void terminal::underline(){ printf(capatab[UNDERON]); fflush(stdout); } void terminal::normal(){ printf(capatab[NORMON]); graphicsoff(); fflush(stdout); } void terminal::horline(int row, int fcol, int tcol){ int savx, savy; curget(savx, savy); curmove(fcol, row); graphicson(); for (int i=fcol; i<=tcol; i++) horl(); graphicsoff(); curmove(savx, savy); } void terminal::verline(int col, int frow, int trow){ int savx, savy; curget(savx, savy); curmove(col, frow); graphicson(); for (int i=frow;i<=trow;i++){ curmove(col,i); verl(); } graphicsoff(); curmove(savx, savy); } void terminal::box(int a, int b, int c, int d){ int i; int savx, savy; curget(savx, savy); graphicson(); curmove(a,b); ulcorn(); for (i=a+1; ia; i--){ curmove(i,d); horl(); } curmove(a,d); llcorn(); for(i=d-1; i>b; i--){ curmove(a,i); verl(); } graphicsoff(); curmove(savx, savy); } void terminal::table(int x, int y, std::vector rows, std::vector cols){ typedef std::vector::size_type sint; int r=1; int savx, savy; curget(savx, savy); graphicson(); curmove(x,y); ulcorn(); for(sint tc=0; tc