windows_curses.h

Go to the documentation of this file.
00001 //
00002 // Copyright 2002, Lowell Boggs Jr.
00003 //
00004 // This file or directory, containing source code for a computer program,
00005 // is Copyrighted by Lowell Boggs, Jr.  987 Regency Drive, Lewisville
00006 // TX (USA), 75067.  You may use, copy, modify, and distribute this
00007 // source file without charge or obligation so long as you agree to
00008 // the following:
00009 //
00010 //  1.  You must indemnify Lowell Boggs against any and all financial
00011 //      obligations caused by its use, misuse, function, or malfunction.
00012 //      Further, you acknowledge that there is no warranty of any kind,
00013 //      whatsoever.
00014 //
00015 //  2.  You agree not to attempt to patent any portion of this original
00016 //      work -- though you may attempt to patent your own extensions to
00017 //      it if you so choose.
00018 //
00019 //  3.  You keep this copyright notice with the file and all copies
00020 //      of the file and do not change it anyway except language translation.
00021 //
00022 // You are responsible for enforcing your own compliance with these
00023 // conditions and may not use this source file if you cannot agree to the
00024 // above terms and conditions.
00025 
00031 
00032 #include <cxxtls/cursorwindow.h>
00033 #include <cxxtls/sequence_map.h>
00034 #include <string>
00035 #include <stdlib.h>
00036 #include <io.h>
00037 #include <signal.h>
00038 #include <algorithm>
00039 #include <cxxtls/file.h>
00040 #include <cxxtls/user.h>
00041 #include <cxxtls/machine.h>
00042 #include <iostream>
00043 #include <fstream>
00044 #include <portable_io.h>
00045 
00046 #include <cxxtls/cursesinterface.h>
00047 
00048 
00049 #include <term.h> // drags in curses
00050 
00051 namespace cxxtls
00052 {
00053 
00054 namespace CursesInterface
00055 {
00056   mouse_info read_mouse_info() { return mouse_info(0,0,0); } // not yet implemented
00057 
00058   long line_chars[lcCOUNT];
00059 
00060   char* _map_kf1  ;  // global variables holding function key sequences
00061   char* _map_kf2  ;  // obtained from the term.h header file after the
00062   char* _map_kf3  ;  // terminal is opened.
00063   char* _map_kf4  ;
00064   char* _map_kf5  ;
00065   char* _map_kf6  ;
00066   char* _map_kf7  ;
00067   char* _map_kf8  ;
00068   char* _map_kf9  ;
00069   char* _map_kf10 ;
00070   char* _map_kf11 ;
00071   char* _map_kf12 ;
00072   char* _map_khom ;
00073   char* _map_kend ;
00074   char* _map_kic  ;
00075   char* _map_kdc  ;
00076   char* _map_kpr  ;
00077   char* _map_knx  ;
00078   char* _map_kup  ;
00079   char* _map_kdn  ;
00080   char* _map_klf  ;
00081   char* _map_krt  ;
00082   char* _map_kbtab;
00083 
00084 
00085   void map_init_key_strings()
00086   {
00087 #if 0
00088      _map_kf1  = key_f1;
00089      _map_kf2  = key_f2;
00090      _map_kf3  = key_f3;
00091      _map_kf4  = key_f4;
00092      _map_kf5  = key_f5;
00093      _map_kf6  = key_f6;
00094      _map_kf7  = key_f7;
00095      _map_kf8  = key_f8;
00096      _map_kf9  = key_f9;
00097      _map_kf10 = key_f10;
00098      _map_kf11 = key_f11;
00099      _map_kf12 = key_f12;
00100      _map_khom = key_home;
00101      _map_kend = key_end;
00102      _map_kic  = key_ic;
00103      _map_kdc  = key_dc;
00104      _map_kpr  = key_ppage;
00105      _map_knx  = key_npage;
00106      _map_kup  = key_up;
00107      _map_kdn  = key_down;
00108      _map_klf  = key_left;
00109      _map_krt  = key_right;
00110      _map_kbtab= key_btab;
00111 
00112 #endif
00113   }
00114 
00115 typedef Sequence_Map<char,int> SEQMAP;
00116 typedef SEQMAP::search         SEARCH;
00117 typedef SEQMAP::sequence       SEQUENCE;
00118 
00119 SEQMAP key_sequences;
00120 
00121 void insert_key_sequence(char const *s, int code)
00122 {
00123    if(s == 0)
00124      return;
00125 
00126    SEQUENCE seq(key_sequences, code);
00127 
00128    while(*s)
00129    {
00130       seq += *s++;
00131    }
00132 
00133    seq.complete();
00134 
00135 }
00136 
00137 void create_key_sequences_map();
00138 
00139 #if 0
00140 sigset_t winch_blocker;  // holds 'SIGWINCH' flag (window change signal)
00141 
00142 void make_xterm_terminfo_file(FileName const &dir);
00143 #endif
00144 
00145 #ifdef __linux
00146 static bool quit_occurred;
00147 static bool susp_occurred;
00148 static bool int_occurred;
00149 
00150   extern "C"
00151   {
00152     static void quit_handler(int)
00153     {
00154       quit_occurred=1;
00155       signal(SIGQUIT, quit_handler); // re-enable signal
00156     }
00157   }
00158 
00159   extern "C"
00160   {
00161     static void susp_handler(int)
00162     {
00163       susp_occurred=1;
00164       signal(SIGTSTP, susp_handler); // re-enable signal
00165     }
00166   }
00167 
00168 
00169   extern "C"
00170   {
00171     static void int_handler(int)
00172     {
00173       int_occurred=1;
00174       signal(SIGINT, int_handler); // re-enable signal
00175     }
00176   }
00177 
00178 
00179 
00180 
00181 #endif
00182 
00183 
00184 static int CursorWindowReversedAtt   = 1;
00185 static int CursorWindowUnderlinedAtt = 2;
00186 static int CursorWindowBlinkingAtt   = 3;
00187 static int CursorWindowBoldAtt       = 4;
00188 static int CursorWindowReverseULAtt  = 5;
00189 static int CursorWindowReverseBoldAtt= 6;
00190 static int CursorWindowBoldULAtt     = 7;
00191 static int CursorWindowNormalAtt     = 8;
00192 static int CursorWindowRevULBoldAtt  = 9;
00193 
00194 
00195 void initializeColorPairs()
00196 {
00197   init_pair(CursorWindowNormalAtt,       COLOR_BLACK, COLOR_WHITE);
00198   init_pair(CursorWindowReversedAtt,     COLOR_WHITE, COLOR_BLACK);
00199   init_pair(CursorWindowUnderlinedAtt,   COLOR_WHITE, COLOR_BLUE);
00200   init_pair(CursorWindowBlinkingAtt,     COLOR_WHITE, COLOR_RED);
00201   init_pair(CursorWindowBoldAtt,         COLOR_BLUE , COLOR_WHITE);
00202   init_pair(CursorWindowReverseULAtt,    COLOR_GREEN, COLOR_BLACK);
00203   init_pair(CursorWindowReverseBoldAtt,  COLOR_WHITE, COLOR_BLUE);
00204   init_pair(CursorWindowRevULBoldAtt,    COLOR_WHITE, COLOR_BLACK);
00205   init_pair(CursorWindowBoldULAtt,       COLOR_BLACK, COLOR_CYAN);
00206 }
00207 
00208 
00209 
00210 
00211 void openCursesTerminal()
00212 {
00213 #ifdef __linux
00214   quit_occurred = false;
00215   susp_occurred = false;
00216   int_occurred  = false;
00217 #endif
00218 
00219 #if 0
00220   if(getenv("WAIT_FOR_DEBUGGER"))
00221   {
00222      printf("waiting for debugger to attach and single step this program\n");
00223 
00224      int stop=1;
00225 
00226      while(stop)
00227      {
00228         sleep(1);
00229      }
00230 
00231   }
00232 #endif
00233 
00234 static bool first_time=true;
00235 if(first_time)
00236 { // begin environment settings
00237 
00238   first_time =false;
00239 
00240 
00241 
00242 } // end environment settings
00243 
00244 
00245 
00246   initscr();
00247 
00248   start_color(); // turn on color features
00249 
00250   initializeColorPairs();
00251 
00252   raw();
00253   noecho();
00254   meta(stdscr, TRUE);
00255 
00256   halfdelay(10);
00257 
00258   intrflush(stdscr,FALSE);
00259   keypad(stdscr,TRUE);
00260   typeahead(0);  /* tells refresh() to check for pending input() */
00261 
00262 #if 0
00263 
00264   #ifdef __linux
00265 
00266 
00267     static struct termios override_termios;
00268 
00269     tcgetattr(0, &override_termios);
00270       
00271     cfmakeraw(&override_termios);
00272 
00273     override_termios.c_cc[VQUIT]=0;
00274     override_termios.c_cc[VSUSP]=0;
00275 
00276     tcsetattr(0, TCSANOW, &override_termios);
00277 
00278   #else
00279 
00280     termios io_info;
00281 
00282 
00283     tcgetattr(0, &io_info);
00284 
00285     io_info.c_cc[VMIN]=1;
00286     io_info.c_cc[VTIME]=10;
00287     tcsetattr(0, TCSANOW, &io_info);
00288 
00289 
00290   #endif
00291 
00292 
00293   // block the sigwinch signal
00294 
00295   sigemptyset(&winch_blocker);
00296 
00297   sigaddset(&winch_blocker, SIGWINCH);
00298 
00299   sigprocmask(SIG_BLOCK, &winch_blocker, 0);
00300 
00301 
00302 
00303   siginterrupt(SIGWINCH, true);
00304   siginterrupt(SIGALRM, true);
00305 
00306 #ifdef __linux
00307   siginterrupt(SIGQUIT, true);
00308   siginterrupt(SIGTSTP, true);
00309   siginterrupt(SIGINT,  true);
00310 #endif
00311 
00312 #endif
00313 
00314   map_init_key_strings();
00315   create_key_sequences_map();
00316 
00317   using namespace CursesInterface;
00318 
00319   line_chars[UL_CORNER] = ACS_ULCORNER;
00320   line_chars[LL_CORNER] = ACS_LLCORNER;
00321   line_chars[UR_CORNER] = ACS_URCORNER;
00322   line_chars[LR_CORNER] = ACS_LRCORNER;
00323   line_chars[HL_MIDDLE] = ACS_HLINE;
00324   line_chars[VL_MIDDLE] = ACS_VLINE;
00325   line_chars[PL_BOX   ] = ACS_PLUS;
00326   line_chars[TE_LEFT  ] = ACS_LTEE;
00327   line_chars[TE_RIGHT ] = ACS_RTEE; 
00328   line_chars[TE_BOTTOM] = ACS_BTEE;
00329   line_chars[TE_TOP   ] = ACS_TTEE;
00330 
00331 }
00332 
00333 void closeCursesTerminal()
00334 {
00335             attrset(0);
00336             clear();
00337             refresh();
00338             endwin();
00339             #ifdef __linux
00340             resetterm();
00341             #endif
00342 
00343 }
00344 
00345 #undef key_up
00346 #undef key_down
00347 #undef key_left
00348 #undef key_right
00349 #undef key_sup
00350 #undef key_sdown
00351 #undef key_sleft
00352 #undef key_sright
00353 #undef key_prior
00354 #undef key_next
00355 #undef key_ic
00356 #undef key_dc
00357 #undef key_home
00358 #undef key_end
00359 #undef key_btab
00360 #undef key_f1
00361 #undef key_f2
00362 #undef key_f3
00363 #undef key_f4
00364 #undef key_f5
00365 #undef key_f6
00366 #undef key_f7
00367 #undef key_f8
00368 #undef key_f9
00369 #undef key_f10
00370 #undef key_f11
00371 #undef key_f12
00372 #undef erase
00373 
00374 int mapCursesKey(int curses_key)  // map to CursorWindow key representation
00375 {
00376   switch(curses_key)
00377   {
00378     case KEY_UP:    return CursorWindow::key_up;
00379     case KEY_DOWN:  return CursorWindow::key_down;
00380     case KEY_LEFT:  return CursorWindow::key_left;
00381     case KEY_RIGHT: return CursorWindow::key_right;
00382     case KEY_SLEFT: return CursorWindow::key_sleft;
00383     case KEY_SRIGHT:return CursorWindow::key_sright;
00384     case KEY_PPAGE: return CursorWindow::key_prior;
00385     case KEY_NPAGE: return CursorWindow::key_next;
00386     case KEY_IC:    return CursorWindow::key_ic;
00387     case KEY_DC:    return CursorWindow::key_dc;
00388     case KEY_HOME:  return CursorWindow::key_home;
00389     case KEY_SHOME: return CursorWindow::key_home;
00390     case KEY_END:   return CursorWindow::key_end;
00391     case KEY_BTAB:  return CursorWindow::key_btab;
00392 
00393 
00394     #ifdef __linux
00395     case 0x7f:      return CursorWindow::key_bs;
00396     case KEY_BACKSPACE: return CursorWindow::key_bs;
00397     #endif
00398                 
00399     case KEY_F(1):  return CursorWindow::key_f1;
00400     case KEY_F(2):  return CursorWindow::key_f2;
00401     case KEY_F(3):  return CursorWindow::key_f3;
00402     case KEY_F(4):  return CursorWindow::key_f4;
00403     case KEY_F(5):  return CursorWindow::key_f5;
00404     case KEY_F(6):  return CursorWindow::key_f6;
00405     case KEY_F(7):  return CursorWindow::key_f7;
00406     case KEY_F(8):  return CursorWindow::key_f8;
00407     case KEY_F(9):  return CursorWindow::key_f9;
00408     case KEY_F(10): return CursorWindow::key_f10;
00409     case KEY_F(11): return CursorWindow::key_f11;
00410     case KEY_F(12): return CursorWindow::key_f12;
00411   }
00412 
00413   return curses_key;
00414 }
00415 
00416 
00417 
00418 void getCursesCursor(int *row, int *col)
00419 {
00420    getyx(stdscr, *row, *col);
00421 }
00422 
00423 void getCursesScreenSize(int *row, int *col)
00424 {
00425    getmaxyx(stdscr, *row, *col);
00426 }
00427 
00428 
00429 // A_STANDOUT      000010000000
00430 // _STANDOUT       A_STANDOUT    /* for compatability with old curses */
00431 // A_UNDERLINE     000020000000
00432 // A_REVERSE       000040000000
00433 // A_BLINK         000100000000
00434 // A_DIM           000200000000
00435 // A_BOLD          000400000000
00436 // A_ALTCHARSET    001000000000
00437 
00438 void setCursesAttributes( int a )
00439 {
00440   // 'a' is assumed to be a CursorWindow attribute
00441 
00442   int att;
00443 
00444   switch(a)
00445   {
00446 
00447     case   CursorWindow::normal:   // no special video enhancements (ie colors)
00448       att = COLOR_PAIR(CursorWindowNormalAtt);
00449       break;
00450     
00451     case   CursorWindow::reversed:   // only reverse video, no other enhancements
00452         att = COLOR_PAIR(CursorWindowReversedAtt);
00453       break;
00454 
00455     case   CursorWindow::underlined: // only underlined, no other video enah
00456         att = COLOR_PAIR(CursorWindowUnderlinedAtt);
00457       break;
00458 
00459     case   CursorWindow::blinking:
00460         att = COLOR_PAIR(CursorWindowBlinkingAtt);
00461       break;
00462 
00463     case   CursorWindow::bold:
00464         att = COLOR_PAIR(CursorWindowBoldAtt);
00465       break;
00466 
00467     case   CursorWindow::reverse_ul:
00468         att = COLOR_PAIR(CursorWindowReverseULAtt);
00469       break;
00470 
00471     case   CursorWindow::reverse_bold:
00472         att = COLOR_PAIR(CursorWindowReverseBoldAtt);
00473       break;
00474 
00475     case   CursorWindow::rev_ul_bold:
00476         att = COLOR_PAIR(CursorWindowRevULBoldAtt);
00477       break;
00478 
00479     case   CursorWindow::bold_ul:
00480         att = COLOR_PAIR(CursorWindowBoldULAtt);
00481       break;
00482 
00483 
00484 
00485     default:
00486       break;
00487   }
00488 
00489   attrset(att);
00490 
00491 }
00492 
00493 
00494 void paintCharString(char const *r, int count, int a, int row, int col)
00495 {
00496     setCursesAttributes(a);
00497 
00498     while(count--)
00499         {
00500             mvaddch(row, col++, *r);
00501             ++r;
00502         }
00503 }
00504 
00505 void paintCharString(long c, int count, int a, int row, int col)
00506 {
00507     setCursesAttributes(a);
00508 
00509     while(count--)
00510         {
00511             mvaddch(row, col++, c);
00512         }
00513 }
00514 
00515 
00516 
00517 void refreshCursesWindow()
00518 {
00519   refresh();
00520 }
00521 
00522 void beepCursesTerminal()
00523 {
00524   beep();
00525 }
00526 
00527 
00528 void moveCursesCursor(int row, int col)
00529 {
00530   move(row,col);
00531 }
00532 
00533 
00534 void make_xterm_terminfo_file(FileName const &dir)
00540 {
00541   FileName filename = dir;
00542            filename += "/xterm.info";
00543 
00544   if(filename.exists())
00545     return;
00546 
00547   std::fstream f(filename.c_str(), std::ios::out);
00548 
00549   if(f.bad())
00550   {
00551     std::cerr << "Error creating file " << filename << std::endl;
00552     exit(1);
00553   }
00554 
00555 #ifdef LINUX
00556   char const *terminfo =
00557 "#       Reconstructed via infocmp from file: /usr/share/terminfo/x/xterm                                  \n"
00558 "xterm|xterm terminal emulator (X Window System),                                                          \n"
00559 "        am, bce, km, mc5i, mir, msgr, xenl,                                                               \n"
00560 "        colors#8, cols#80, it#8, lines#24, pairs#64,                                                      \n"
00561 "        acsc=``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,                                        \n"
00562 "        bel=^G, blink=\\E[5m, bold=\\E[1m, cbt=\\E[Z, civis=\\E[?25l,                                     \n"
00563 "        clear=\\E[H\\E[2J, cnorm=\\E[?25h, cr=^M,                                                         \n"
00564 "        csr=\\E[%i%p1%d;%p2%dr, cub=\\E[%p1%dD, cub1=^H,                                                  \n"
00565 "        cud=\\E[%p1%dB, cud1=^J, cuf=\\E[%p1%dC, cuf1=\\E[C,                                              \n"
00566 "        cup=\\E[%i%p1%d;%p2%dH, cuu=\\E[%p1%dA, cuu1=\\E[A,                                               \n"
00567 "        cvvis=\\E[?25h, dch=\\E[%p1%dP, dch1=\\E[P, dl=\\E[%p1%dM,                                        \n"
00568 "        dl1=\\E[M, ech=\\E[%p1%dX, ed=\\E[J, el=\\E[K, el1=\\E[1K,                                        \n"
00569 "        enacs=\\E(B\\E)0, flash=\\E[?5h$<100/>\\E[?5l, home=\\E[H,                                        \n"
00570 "        hpa=\\E[%i%p1%dG, ht=^I, hts=\\EH, ich=\\E[%p1%d@, ich1=\\E[@,                                    \n"
00571 "        il=\\E[%p1%dL, il1=\\E[L, ind=^J, invis=\\E[8m,                                                   \n"
00572 "        is2=\\E[!p\\E[?3;4l\\E[4l\\E>, kBEG=\\EOu, kDC=\\EOn,                                             \n"
00573 "        kEND=\\EOq, kHOM=\\EOw, kIC=\\EOp, kLFT=\\EOt, kNXT=\\EOr,                                        \n"
00574 "        kPRV=\\EOx, kRIT=\\EOv, ka1=\\EOH, ka3=\\E[5~, kb2=\\EOE,                                         \n"
00575 "        kbeg=\\EOE, kbs=\\177, kc1=\\EOF, kc3=\\E[6~, kcub1=\\EOD,                                        \n"
00576 "        kcud1=\\EOB, kcuf1=\\EOC, kcuu1=\\EOA, kdch1=\\E[3~, kend=\\EOF,                                  \n"
00577 "        kent=\\EOM, kf0=\\E[21~, kf1=\\E[11~, kf10=\\E[21~,                                               \n"
00578 "        kf11=\\E[23~, kf12=\\E[24~, kf13=\\E[25~, kf14=\\E[26~,                                           \n"
00579 "        kf15=\\E[28~, kf16=\\E[29~, kf17=\\E[31~, kf18=\\E[32~,                                           \n"
00580 "        kf19=\\E[33~, kf2=\\E[12~, kf20=\\E[34~, kf21=\\E[35~,                                            \n"
00581 "        kf22=\\E[36~, kf3=\\E[13~, kf4=\\E[14~, kf5=\\E[15~, kf54=\\EOo,                                  \n"
00582 "        kf55=\\EOj, kf56=\\EOm, kf57=\\EOk, kf58=\\EOl, kf6=\\E[17~,                                      \n"
00583 "        kf7=\\E[18~, kf8=\\E[19~, kf9=\\E[20~, kfnd=\\E[1~, khome=\\EOH,                                  \n"
00584 "        kich1=\\E[2~, kind=\\EOs, kmous=\\E[M, knp=\\E[6~, kpp=\\E[5~,                                    \n"
00585 "        kri=\\EOy, kslt=\\E[4~, mc0=\\E[i, mc4=\\E[4i, mc5=\\E[5i,                                        \n"
00586 "        op=\\E[39;49m, rc=\\E8, rev=\\E[7m, ri=\\EM, rmacs=^O,                                            \n"
00587 "        rmam=\\E[?7l, rmcup=\\E[?1047l\\E[?1048l, rmir=\\E[4l,                                            \n"
00588 "        rmkx=\\E[?1l\\E>, rmso=\\E[27m, rmul=\\E[24m,                                                     \n"
00589 "        rs1=\\Ec\\E[?67;9l, rs2=\\E[!p\\E[?3;4l\\E[4l\\E>, sc=\\E7,                                       \n"
00590 "        setab=\\E[4%p1%dm, setaf=\\E[3%p1%dm,                                                             \n"
00591 "        setb=\\E[4%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m,                     \n"
00592 "        setf=\\E[3%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m,                     \n"
00593 "        sgr=\\E[0%?%p1%p6%|%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m%?%p9%t\\016%e\\017%;, \n"
00594 "        sgr0=\\E[m\\017, smacs=^N, smam=\\E[?7h,                                                          \n"
00595 "        smcup=\\E[?1048h\\E[?1047h, smir=\\E[4h, smkx=\\E[?1h\\E=,                                        \n"
00596 "        smso=\\E[7m, smul=\\E[4m, tbc=\\E[3g, u6=\\E[%i%d;%dR,                                            \n"
00597 "        u7=\\E[6n, u8=\\E[?1;2c, u9=\\E[c, vpa=\\E[%i%p1%dd,                                              \n"
00598 ;
00599 
00600 #else
00601   char const *terminfo =
00602 "#       Reconstructed via infocmp from file: /usr/share/lib/terminfo/x/xterm             \n"
00603 "xterm|vs100|lowells extended xterm terminal emulator,                                    \n"
00604 "        am, km, mir, msgr, xenl,                                                         \n"
00605 "        cols#80, it#8, lines#65,                                                         \n"
00606 "        acsc=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,                         \n"
00607 "        bel=^G, blink=\\E[5m, bold=\\E[1m, clear=\\E[H\\E[2J,                            \n"
00608 "        cr=\\r, csr=\\E[%i%p1%d;%p2%dr, cub=\\E[%p1%dD, cub1=\\b,                        \n"
00609 "        cud=\\E[%p1%dB, cud1=\\n, cuf=\\E[%p1%dC, cuf1=\\E[C,                            \n"
00610 "        cup=\\E[%i%p1%d;%p2%dH, cuu=\\E[%p1%dA, cuu1=\\E[A,                              \n"
00611 "        dch=\\E[%p1%dP, dch1=\\E[P, dl=\\E[%p1%dM, dl1=\\E[M,                            \n"
00612 "        ed=\\E[J, el=\\E[K, el1=\\E[1K$<3>, enacs=\\E(B\\E)0,                            \n"
00613 "        home=\\E[H, ht=\\t, hts=\\EH, ich=\\E[%p1%d@, ich1=\\E[@,                        \n"
00614 "        il=\\E[%p1%dL, il1=\\E[L, ind=\\n, ka1=\\EOq, ka3=\\EOs,                         \n"
00615 "        kb2=\\EOr, kbs=\\b, kc1=\\EOp, kc3=\\EOn, kcub1=\\EOD,                           \n"
00616 "        kcud1=\\EOB, kcuf1=\\EOC, kcuu1=\\EOA, kent=\\EOM,                               \n"
00617 "        kf1=\\E[11~,                                                                     \n"
00618 "        kf10=\\E[21~,                                                                    \n"
00619 "        kf2=\\E[12~,                                                                     \n"
00620 "        kf3=\\E[13~,                                                                     \n"
00621 "        kf4=\\E[14~,                                                                     \n"
00622 "        kf5=\\E[15~,                                                                     \n"
00623 "        kf6=\\E[17~,                                                                     \n"
00624 "        kf7=\\E[18~,                                                                     \n"
00625 "        kf8=\\E[19~,                                                                     \n"
00626 "        kf9=\\E[20~,                                                                     \n"
00627 "        rc=\\E8,                                                                         \n"
00628 "        rev=\\E[7m,                                                                      \n"
00629 "        khome=\\E[1~,                                                                    \n"
00630 "        kend=\\E[4~,                                                                     \n"
00631 "        kll=\\E[E;,                                                                      \n"
00632 "        kpp=\\E[5~,                                                                      \n"
00633 "        knp=\\E[6~,                                                                      \n"
00634 "        kich1=\\E[2~,                                                                    \n"
00635 "        kf11=\\E[23~,                                                                    \n"
00636 "        kf12=\\E[24~,                                                                    \n"
00637 "        kcbt=\\E[TAB;,                                                                   \n"
00638 "        kLFT=\\E[LEFT;,                                                                  \n"
00639 "        kRIT=\\E[RIGHT;,                                                                 \n"
00640 "        kPRV=\\E[prior;,                                                                 \n"
00641 "        kNXT=\\E[next;,                                                                  \n"
00642 "        kdch1=\\177,                                                                    \n"
00643 "        ri=\\EM, rmacs=^O, rmkx=\\E[?1l\\E>, rmso=\\E[m,                                 \n"
00644 "        rmul=\\E[m,                                                                      \n"
00645 "        rs1=\\E>\\E[1;3;4;5;6l\\E[?7h\\E[m\\E[r\\E[2J\\E[H, rs2=@,                       \n"
00646 "        sc=\\E7,                                                                         \n"
00647 "        sgr=\\E[0%?%p1%p6%|%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;m%?%p9%t^N%e^O%;, \n"
00648 "        sgr0=\\E[m, smacs=^N, smkx=\\E[?1h\\E=, smso=\\E[7m,                             \n"
00649 "        smul=\\E[4m, tbc=\\E[3g,                                                         \n"
00650 "        kHOM=\\E[H,                                                                      \n"
00651 "        kEND=\\E[E,                                                                      \n"
00652 ;
00653 #endif
00654 
00655    f.write(terminfo, strlen(terminfo));
00656 
00657    if(f.bad())
00658    {
00659      std::cerr << "Error creating " << filename << std::endl;
00660      exit(1);
00661    }
00662 
00663    f.close();
00664 
00665    std::cerr << "\n\n\n\n"
00666              << "Since this is the first time you have run this program as this\n"
00667              << "user on this host, the special purpose curses TERMINFO database\n"
00668              << "is created for you in \n\n  " 
00669              << dir 
00670              << "/xterm.info\n\n"
00671              << "If you wish to change the keyboard bindings used by curses\n"
00672              << "You can edit that file then remove\n\n  "
00673              <<  dir
00674              << "terminfo/x/xterm\n\n"
00675              << "to get the database automatically rebuilt the next\n"
00676              << "you run this program.\n\n"
00677              ;
00678 
00679    std::cerr << "Press enter to continue:" << std::endl;
00680    std::cerr.flush();
00681    std::cin.get();
00682 
00683    std::cerr << "\n\n\n\n"
00684              << "You should have received documentation about configuring\n"
00685              << "curses with this program.  If you have a source distribution\n"
00686              << "look in the etc sub-directory directory for a README file.\n\n"
00687              << "If you are using an X windows emulator you will need to\n"
00688              << "make sure that your emulator passes the Home, End, Page Up,\n"
00689              << "and Page Down keys through as a string not as functions!\n"
00690              << "You'll also want to make the backspace key send ^H not ^?\n"
00691              << "and perhaps modify your shell startup to use \n\n  "
00692              << "stty erase '^H'\n\n"
00693              ;
00694 
00695    std::cerr << "Press enter to continue:" << std::endl;
00696    std::cerr.flush();
00697    std::cin.get();
00698 
00699    std::cerr << "\n\n\n\n"
00700              << "Note:  you should have received an Xterm file which is used\n"
00701              << "by X windows to define key bindings for your xterm program.\n"
00702              << "If you choose not use the one provided, you must ensure that\n"
00703              << "all the function keys you like using are set up in both\n"
00704              << "$HOME/Xterm and $HOME/.tools_dir/<OS>/xterm.info.\n\n"
00705              << "If your keys still don't work after making sure of all the\n"
00706              << "above, check to see if you are setting your xmodmap key bindings\n"
00707              << "in some way that conflicts with Xterm and xterm.info.\n\nGood luck!\n\n"
00708              ;
00709 
00710 
00711    std::cerr << "Press enter to continue:" << std::endl;
00712    std::cerr.flush();
00713    std::cin.get();
00714 
00715 }
00716 
00717 
00718 
00719 
00720   void create_key_sequences_map()
00721   {
00722     insert_key_sequence(CursesInterface::_map_kf1  , CursorWindow::key_f1);
00723     insert_key_sequence(CursesInterface::_map_kf2  , CursorWindow::key_f2);
00724     insert_key_sequence(CursesInterface::_map_kf3  , CursorWindow::key_f3);
00725     insert_key_sequence(CursesInterface::_map_kf4  , CursorWindow::key_f4);
00726     insert_key_sequence(CursesInterface::_map_kf5  , CursorWindow::key_f5);
00727     insert_key_sequence(CursesInterface::_map_kf6  , CursorWindow::key_f6);
00728     insert_key_sequence(CursesInterface::_map_kf7  , CursorWindow::key_f7);
00729     insert_key_sequence(CursesInterface::_map_kf8  , CursorWindow::key_f8);
00730     insert_key_sequence(CursesInterface::_map_kf9  , CursorWindow::key_f9);
00731     insert_key_sequence(CursesInterface::_map_kf10 , CursorWindow::key_f10);
00732     insert_key_sequence(CursesInterface::_map_kf11 , CursorWindow::key_f11);
00733     insert_key_sequence(CursesInterface::_map_kf12 , CursorWindow::key_f12);
00734     insert_key_sequence(CursesInterface::_map_khom , CursorWindow::key_home);
00735     insert_key_sequence(CursesInterface::_map_kend , CursorWindow::key_end);
00736     insert_key_sequence(CursesInterface::_map_kic  , CursorWindow::key_ic);
00737     insert_key_sequence(CursesInterface::_map_kdc  , CursorWindow::key_dc);
00738     insert_key_sequence(CursesInterface::_map_kpr  , CursorWindow::key_prior);
00739     insert_key_sequence(CursesInterface::_map_knx  , CursorWindow::key_next);
00740     insert_key_sequence(CursesInterface::_map_kup  , CursorWindow::key_up);
00741     insert_key_sequence(CursesInterface::_map_kdn  , CursorWindow::key_down);
00742     insert_key_sequence(CursesInterface::_map_klf  , CursorWindow::key_left);
00743     insert_key_sequence(CursesInterface::_map_krt  , CursorWindow::key_right);
00744     insert_key_sequence(CursesInterface::_map_kbtab, CursorWindow::key_btab);
00745 
00746     {
00747       static char extra_home [] = { 0x1b, '[', 'H', 0 };
00748       static char extra_end  [] = { 0x1b, '[', 'F', 0 };
00749       static char extra_btab [] = { 0x1b, '[', 'Z', 0 };
00750 
00751       insert_key_sequence(extra_home,  CursorWindow::key_home);
00752       insert_key_sequence(extra_end,   CursorWindow::key_end);
00753       insert_key_sequence(extra_btab,  CursorWindow::key_btab);
00754 
00755 
00756       #ifdef __linux
00757       static char extra_bs   [] = { 0x7f, 0 };
00758       insert_key_sequence(extra_bs,    CursorWindow::key_bs);
00759       #else
00760       static char extra_dc   [] = { 0x7f, 0 };
00761       insert_key_sequence(extra_dc,    CursorWindow::key_dc);
00762 
00763       static char extra_dc1   [] = { 0x1b, '[', '3', '~', 0 };
00764       insert_key_sequence(extra_dc1,    CursorWindow::key_dc);
00765 
00766       static char extra_bs   [] = { 0x008, 0 };
00767       insert_key_sequence(extra_bs,    CursorWindow::key_bs);
00768       #endif
00769 
00770     }
00771 
00772     {
00773       static char extra_home1[] = { 0x1b, 'O', 'H', 0 };
00774       static char extra_end1 [] = { 0x1b, 'O', 'F', 0 };
00775       static char extra_btab1[] = { 0x1b, 'O', 'Z', 0 };
00776 
00777 
00778       insert_key_sequence(extra_home1, CursorWindow::key_home);
00779       insert_key_sequence(extra_end1,  CursorWindow::key_end);
00780       insert_key_sequence(extra_btab1, CursorWindow::key_btab);
00781     }
00782 
00783 
00784     {
00785       static char extra_f1[] = { 0x1b, 'O', 'P', 0 };
00786       static char extra_f2[] = { 0x1b, 'O', 'Q', 0 };
00787       static char extra_f3[] = { 0x1b, 'O', 'R', 0 };
00788       static char extra_f4[] = { 0x1b, 'O', 'S', 0 };
00789       static char extra_end  [] = { 0x1b, '[', 'E', 0 };
00790 
00791       insert_key_sequence(extra_f1,  CursorWindow::key_f1);
00792       insert_key_sequence(extra_f2,  CursorWindow::key_f2);
00793       insert_key_sequence(extra_f3,  CursorWindow::key_f3);
00794       insert_key_sequence(extra_f4,  CursorWindow::key_f4);
00795       insert_key_sequence(extra_end,  CursorWindow::key_end);
00796     }
00797 
00798 
00799     {
00800       static char extra_home1[] = { 0x1b, '[', '1', '~', 0 };
00801       static char extra_end1 [] = { 0x1b, '[', '4', '~', 0 };
00802 
00803       insert_key_sequence(extra_home1, CursorWindow::key_home);
00804       insert_key_sequence(extra_end1,  CursorWindow::key_end);
00805     }
00806 
00807 
00808     {
00809       SEARCH search(key_sequences);
00810 
00811       if(!search(0x1b))
00812       {
00813         closeCursesTerminal();
00814         printf("couldn't find the Esc key in the sequence!");
00815         exit(1);
00816       }
00817       ++search;
00818 
00819       if(!search('['))
00820       {
00821         closeCursesTerminal();
00822         printf("couldn't find the '[' key in the!");
00823         exit(1);
00824       }
00825       ++search;
00826 
00827       if(!search('H'))
00828       {
00829         closeCursesTerminal();
00830         printf("couldn't find the 'H' sequence!");
00831         exit(1);
00832       }
00833       ++search;
00834 
00835       int code=0;
00836 
00837       if(!search.finished(&code))
00838       {
00839         closeCursesTerminal();
00840         printf("couldn't find the home sequence!");
00841         exit(1);
00842       }
00843 
00844       if(code != CursorWindow::key_home)
00845       {
00846         closeCursesTerminal();
00847         printf("wrong key code returned");
00848         exit(1);
00849       }
00850 
00851     }
00852 
00853 
00854   }
00855 
00856 
00857   int alarm_occurred=0;
00858 
00859 #if 0
00860 
00861   int read_key_char()
00862     // return a 'char' to the user -- or a 0 that indicates the alarm
00863     // timer fired.
00864   {
00865     char buffer[1];
00866 
00867       while(winch_occurred == 0      &&
00868             read(0, &buffer, 1) < 1  &&
00869             alarm_occurred == 0      
00870 #ifdef __linux
00871             &&
00872             quit_occurred == 0       &&
00873             susp_occurred == 0       &&
00874             int_occurred  == 0
00875 #endif
00876            )
00877       {
00878         usleep(100000);  // sleep 1/10 of a second
00879       }
00880 
00881 
00882     if(alarm_occurred)
00883     {
00884       alarm_occurred = 0;
00885       return 0;
00886     }
00887 
00888     if(winch_occurred)
00889     {
00890         return -1;
00891     }
00892 
00893     alarm_occurred=0;
00894 
00895 #ifdef __linux
00896     if(quit_occurred)
00897     {
00898       quit_occurred=0;
00899       buffer[0] = 0x1c;  // control backslash
00900     }
00901 
00902     if(susp_occurred)
00903     {
00904       susp_occurred=0;
00905       buffer[0] = 0x1a;  // control backslash
00906     }
00907 
00908     if(int_occurred)
00909     {
00910       int_occurred=0;
00911       buffer[0] = 3;   // ^C
00912     }
00913 #endif
00914 
00915 
00916     return buffer[0];
00917   }
00918 
00919 #else
00920 
00921   int read_key_char()
00922   {
00923     return getch();
00924   }
00925 
00926 #endif
00927 
00928 
00929 #undef refresh
00930 
00931   extern "C" void alarm_handler(int signum)
00932   {
00933 #if 0
00934      
00935      alarm_occurred=1;
00936      signal(SIGALRM, alarm_handler);
00937 #endif
00938   }
00939 
00940   extern "C"
00941   {
00942     static void sigwinch_handler(int)
00943     {
00944       winch_occurred=1;
00945     }
00946   }
00947 
00948 
00949   static std::string _saved;
00950 
00951 #if 0
00952 
00953   int read_mapped_key(CursorWindow &w)
00954     //
00955     // read a key from the keyboard and handle function key sequences
00956     //
00957   {
00958 
00959     if(_saved.size())
00960     {
00961        // keys have been pushed back in the algorithm below
00962        // and we are reading the saved values in subsequent reads
00963 
00964        int rv = _saved[0];
00965 
00966        _saved.erase(_saved.begin());
00967 
00968        return rv;
00969     }
00970 
00971     if(resize_requested)
00972       return -1;
00973 
00974     refresh();
00975 
00976 #if 0
00977     signal(SIGWINCH, sigwinch_handler);
00978 
00979     signal(SIGALRM, alarm_handler);
00980 
00981 #ifdef __linux
00982     signal(SIGQUIT, quit_handler);
00983     signal(SIGTSTP, susp_handler);
00984     signal(SIGINT, int_handler);
00985 #endif
00986 
00987 #endif
00988 
00989     SEARCH search_term = key_sequences;
00990 
00991 
00992     int c;
00993 
00994     int code;
00995 
00996 
00997     for(;;)
00998     {
00999       sigprocmask(SIG_UNBLOCK, &winch_blocker, 0); // enable window change signals
01000 
01001       c = read_key_char();
01002 
01003 
01004       sigprocmask(SIG_BLOCK, &winch_blocker, 0); // disable window change signals
01005 
01006       if(c == 0x1b)
01007       {
01008          // escape is never the middle character in a sequence
01009          alarm_occurred=0;
01010          ualarm(1000000,0);  // cause the next read to type out
01011 
01012       }
01013       else
01014       {
01015          ualarm(0,0);  // turn off any pending alarm
01016 
01017       }
01018 
01019       if(winch_occurred || resize_requested || c == -1)
01020       {
01021         _saved.resize(0);
01022         
01023         closeCursesTerminal();
01024         openCursesTerminal();
01025         refresh();
01026         
01027         return -1;
01028       }
01029 
01030       if( c == 0  || !search_term(c) )
01031       {
01032         // either we have a read time out or this key isn't part of
01033         // a valid sequence
01034 
01035         if(c == 0x1b)
01036         {
01037           // escape is never found in the middle of a sequence
01038         
01039           if( _saved.size() && _saved[0] == 0x1b )
01040           {
01041             // discard the previous sequence and let this start a new one
01042         
01043             SEARCH new_term = key_sequences;
01044         
01045             new_term(c);
01046 
01047             ++new_term;
01048         
01049             search_term = new_term;
01050         
01051             _saved.resize(0);
01052             _saved += (char)(0x1b);
01053 
01054             continue;
01055         
01056           }
01057         
01058         }
01059 
01060         if(c != 0)
01061           _saved += (char)(c);
01062 
01063         if(_saved.size())
01064         {
01065           int rv = _saved[0];
01066 
01067           _saved.erase(_saved.begin());
01068 
01069           return rv;
01070         }
01071 
01072         continue;  // if no chars read, keep reading
01073       }
01074 
01075       ++search_term;
01076 
01077       _saved += (char)(c);
01078 
01079       if(search_term.finished(&code))
01080       {
01081         _saved.resize(0);
01082         return code;
01083       }
01084     }
01085 
01086   }
01087 #else
01088   int read_mapped_key(CursorWindow &)
01089   {
01090     int ch;
01091 
01092     while( (ch = getch()) < 0)
01093       ;
01094 
01095     return mapCursesKey(ch);
01096 
01097   }
01098 #endif
01099 };
01100 
01101 } // namespace cxxtls
Generated on Wed Feb 29 22:50:05 2012 for CXXUtilities by  doxygen 1.6.3