diff --git a/.gitignore b/.gitignore index 109ac5c7..d9148ab5 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,7 @@ test/calculator test/dialog test/string-operations test/opti-move +test/termcap test/hello test/watch test/menu diff --git a/ChangeLog b/ChangeLog index 08edb2fa..d8774cf6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2017-03-26 Markus Gans + * The Final Cut compiles now under FreeBSD + * A new test program to show the termcap variables + 2017-03-19 Markus Gans * Add the "mouse" example to illustrate mouse programming diff --git a/Makefile.in b/Makefile.in index 53d016d7..ef17166c 100644 --- a/Makefile.in +++ b/Makefile.in @@ -341,6 +341,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ diff --git a/configure b/configure index 3b404023..0b1e1624 100755 --- a/configure +++ b/configure @@ -735,6 +735,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -820,6 +821,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1072,6 +1074,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1209,7 +1220,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1362,6 +1373,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] diff --git a/doc/Makefile.in b/doc/Makefile.in index dd2511fa..c7657eba 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -258,6 +258,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ diff --git a/src/Makefile.in b/src/Makefile.in index de9d13e8..177b514c 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -362,6 +362,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ diff --git a/src/fapp.cpp b/src/fapp.cpp index 2f38eb54..fdc401d6 100644 --- a/src/fapp.cpp +++ b/src/fapp.cpp @@ -33,8 +33,10 @@ FApplication::eventQueue* FApplication::event_queue = 0; // constructors and destructor //---------------------------------------------------------------------- -FApplication::FApplication (int& _argc, char* _argv[]) - : FWidget(0) +FApplication::FApplication ( int& _argc + , char* _argv[] + , bool disable_alt_screen ) + : FWidget(0, disable_alt_screen) , app_argc(_argc) , app_argv(_argv) , key(0) @@ -323,10 +325,10 @@ void FApplication::init() void FApplication::setExitMessage (std::string message) { quit_now = true; - std::snprintf ( FTerm::exit_message - , sizeof(FTerm::exit_message) - , "%s" - , message.c_str() ); + snprintf ( FTerm::exit_message + , sizeof(FTerm::exit_message) + , "%s" + , message.c_str() ); } //---------------------------------------------------------------------- @@ -548,7 +550,10 @@ void FApplication::processKeyboardEvent() if ( key != NEED_MORE_DATA ) { + +#if defined(__linux__) key = modifierKeyCorrection (key); +#endif switch ( key ) { @@ -704,6 +709,7 @@ void FApplication::processKeyboardEvent() } } +#if defined(__linux__) //---------------------------------------------------------------------- int FApplication::modifierKeyCorrection (int& key_id) { @@ -983,6 +989,7 @@ int FApplication::modifierKeyCorrection (int& key_id) return key_id; } +#endif //---------------------------------------------------------------------- bool FApplication::processDialogSwitchAccelerator() diff --git a/src/fapp.h b/src/fapp.h index d2541b5f..50ef748f 100644 --- a/src/fapp.h +++ b/src/fapp.h @@ -55,7 +55,7 @@ class FApplication : public FWidget { public: // Constructor - FApplication (int&, char*[]); + FApplication (int&, char*[], bool = false); // Destructor virtual ~FApplication(); @@ -129,7 +129,9 @@ class FApplication : public FWidget bool KeyPressed(); ssize_t readKey(); void processKeyboardEvent(); +#if defined(__linux__) int modifierKeyCorrection (int& key); +#endif bool processDialogSwitchAccelerator(); bool processAccelerator (FWidget*&); void getX11ButtonState (int); diff --git a/src/fbutton.cpp b/src/fbutton.cpp index 50b814e0..e0ed03fe 100644 --- a/src/fbutton.cpp +++ b/src/fbutton.cpp @@ -163,8 +163,8 @@ bool FButton::setFocus (bool on) { if ( getStatusBar() ) { - const FString msg = getStatusbarMessage(); - const FString curMsg = getStatusBar()->getMessage(); + const FString& msg = getStatusbarMessage(); + const FString& curMsg = getStatusBar()->getMessage(); if ( curMsg != msg ) getStatusBar()->setMessage(msg); @@ -734,8 +734,8 @@ void FButton::draw() if ( is_Focus && getStatusBar() ) { - const FString msg = getStatusbarMessage(); - const FString curMsg = getStatusBar()->getMessage(); + const FString& msg = getStatusbarMessage(); + const FString& curMsg = getStatusBar()->getMessage(); if ( curMsg != msg ) { diff --git a/src/ffiledialog.cpp b/src/ffiledialog.cpp index bba95410..02cec4a1 100644 --- a/src/ffiledialog.cpp +++ b/src/ffiledialog.cpp @@ -368,7 +368,7 @@ const FString FFileDialog::fileOpenChooser ( FWidget* parent { path = getHomeDir(); - if ( path.isEmpty() || path.isEmpty() ) + if ( path.isNull() || path.isEmpty() ) path = FString("/"); } @@ -403,7 +403,7 @@ const FString FFileDialog::fileSaveChooser ( FWidget* parent { path = getHomeDir(); - if ( path.isEmpty() || path.isEmpty() ) + if ( path.isNull() || path.isEmpty() ) path = FString("/"); } diff --git a/src/flineedit.cpp b/src/flineedit.cpp index 63f58184..12b0539b 100644 --- a/src/flineedit.cpp +++ b/src/flineedit.cpp @@ -108,8 +108,8 @@ bool FLineEdit::setFocus (bool on) if ( getStatusBar() ) { - const FString msg = getStatusbarMessage(); - const FString curMsg = getStatusBar()->getMessage(); + const FString& msg = getStatusbarMessage(); + const FString& curMsg = getStatusBar()->getMessage(); if ( curMsg != msg ) getStatusBar()->setMessage(msg); @@ -153,7 +153,7 @@ bool FLineEdit::setShadow (bool on) } //---------------------------------------------------------------------- -void FLineEdit::setText (const FString txt) +void FLineEdit::setText (const FString& txt) { text_offset = 0; cursor_pos = 0; @@ -165,7 +165,7 @@ void FLineEdit::setText (const FString txt) } //---------------------------------------------------------------------- -void FLineEdit::setLabelText (const FString ltxt) +void FLineEdit::setLabelText (const FString& ltxt) { label_text = ltxt; label->setText(label_text); @@ -734,8 +734,8 @@ void FLineEdit::draw() if ( isFocus && getStatusBar() ) { - const FString msg = getStatusbarMessage(); - const FString curMsg = getStatusBar()->getMessage(); + const FString& msg = getStatusbarMessage(); + const FString& curMsg = getStatusBar()->getMessage(); if ( curMsg != msg ) { diff --git a/src/flineedit.h b/src/flineedit.h index 27c52670..800ad835 100644 --- a/src/flineedit.h +++ b/src/flineedit.h @@ -62,8 +62,8 @@ class FLineEdit : public FWidget int getLabelOrientation(); // Mutators - void setText (const FString); - void setLabelText (const FString); + void setText (const FString&); + void setLabelText (const FString&); void setLabelOrientation(const label_o); bool setEnable(bool); bool setEnable(); diff --git a/src/flistbox.cpp b/src/flistbox.cpp index 7faf1ce6..42aed8ff 100644 --- a/src/flistbox.cpp +++ b/src/flistbox.cpp @@ -195,8 +195,8 @@ bool FListBox::setFocus (bool on) if ( getStatusBar() ) { - const FString msg = getStatusbarMessage(); - const FString curMsg = getStatusBar()->getMessage(); + const FString& msg = getStatusbarMessage(); + const FString& curMsg = getStatusBar()->getMessage(); if ( curMsg != msg ) getStatusBar()->setMessage(msg); @@ -214,7 +214,7 @@ bool FListBox::setFocus (bool on) } //---------------------------------------------------------------------- -void FListBox::setText (const FString txt) +void FListBox::setText (const FString& txt) { text = txt; } @@ -261,7 +261,7 @@ void FListBox::hide() } //---------------------------------------------------------------------- -void FListBox::insert ( const FString item +void FListBox::insert ( const FString& item , fc::brackets_type b , bool s , data_ptr d ) diff --git a/src/flistbox.h b/src/flistbox.h index f89b8eb9..d0e4de7b 100644 --- a/src/flistbox.h +++ b/src/flistbox.h @@ -139,7 +139,7 @@ class FListBox : public FWidget bool setFocus (bool); bool setFocus(); bool unsetFocus(); - void setText (const FString); + void setText (const FString&); // Inquiries bool isSelected (int) const; @@ -148,7 +148,7 @@ class FListBox : public FWidget // Methods void hide(); - void insert ( const FString + void insert ( const FString& , fc::brackets_type = fc::NoBrackets , bool = false , data_ptr = 0); diff --git a/src/fmenu.cpp b/src/fmenu.cpp index 14f95a12..a64e144c 100644 --- a/src/fmenu.cpp +++ b/src/fmenu.cpp @@ -64,7 +64,7 @@ bool FMenu::setMenuWidget (bool on) } //---------------------------------------------------------------------- -void FMenu::setStatusbarMessage (const FString msg) +void FMenu::setStatusbarMessage (const FString& msg) { FWidget::setStatusbarMessage(msg); @@ -622,8 +622,8 @@ void FMenu::onMouseMove (FMouseEvent* ev) // Mouse is over border or separator if ( getStatusBar() ) { - const FString msg = getStatusbarMessage(); - const FString curMsg = getStatusBar()->getMessage(); + const FString& msg = getStatusbarMessage(); + const FString& curMsg = getStatusBar()->getMessage(); if ( curMsg != msg ) { diff --git a/src/fmenu.h b/src/fmenu.h index 91a4460f..9d293835 100644 --- a/src/fmenu.h +++ b/src/fmenu.h @@ -73,7 +73,7 @@ class FMenu : public FWindow, public FMenuList bool setMenuWidget (bool); bool setMenuWidget(); bool unsetMenuWidget(); - void setStatusbarMessage (const FString); + void setStatusbarMessage (const FString&); void setMenu (FMenu*); void setText (const FString&); diff --git a/src/fmenuitem.cpp b/src/fmenuitem.cpp index 54bd00e3..e807d0de 100644 --- a/src/fmenuitem.cpp +++ b/src/fmenuitem.cpp @@ -158,8 +158,8 @@ bool FMenuItem::setFocus (bool on) if ( getStatusBar() ) { - const FString msg = getStatusbarMessage(); - const FString curMsg = getStatusBar()->getMessage(); + const FString& msg = getStatusbarMessage(); + const FString& curMsg = getStatusBar()->getMessage(); if ( curMsg != msg ) getStatusBar()->setMessage(msg); @@ -754,7 +754,7 @@ void FMenuItem::createDialogList (FMenu* winmenu) { int n = int(std::distance(begin, iter)); // get the dialog title - const FString name = win->getText(); + const FString& name = win->getText(); // create a new dialog list item FMenuItem* win_item = new FMenuItem (name, winmenu); diff --git a/src/fmessagebox.cpp b/src/fmessagebox.cpp index 9d605e7c..efc33fac 100644 --- a/src/fmessagebox.cpp +++ b/src/fmessagebox.cpp @@ -212,7 +212,7 @@ int FMessageBox::error ( FWidget* parent , int button2 ) { int reply; - const FString caption = "Error message"; + const FString& caption = "Error message"; FMessageBox* mbox = new FMessageBox ( caption, message , button0, button1, button2 , parent ); diff --git a/src/fonts/Makefile.in b/src/fonts/Makefile.in index 3c11302a..f0bfb00e 100644 --- a/src/fonts/Makefile.in +++ b/src/fonts/Makefile.in @@ -228,6 +228,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ diff --git a/src/fscrollview.cpp b/src/fscrollview.cpp index 35b4938c..5093bc51 100644 --- a/src/fscrollview.cpp +++ b/src/fscrollview.cpp @@ -383,7 +383,6 @@ void FScrollView::draw() void FScrollView::onKeyPress (FKeyEvent* ev) { int key = ev->key(); - bool hasChanges = false; short& xoffset = viewport_geometry.x1_ref(); short& yoffset = viewport_geometry.y1_ref(); short xoffset_before = xoffset; @@ -457,6 +456,8 @@ void FScrollView::onKeyPress (FKeyEvent* ev) if ( ev->isAccepted() ) { + bool hasChanges = false; + if ( isVisible() && viewport && (xoffset_before != xoffset || yoffset_before != yoffset) ) { @@ -690,8 +691,6 @@ void FScrollView::copy2area() // copy viewport to area int ax, ay, dx, dy, y_end, x_end; - char_data* vc; // viewport character - char_data* ac; // area character if ( ! hasPrintArea() ) FVTerm::getPrintArea(); @@ -711,6 +710,8 @@ void FScrollView::copy2area() for (int y=0; y < y_end; y++) // line loop { + char_data* vc; // viewport character + char_data* ac; // area character int v_line_len = viewport->width; int a_line_len = print_area->width + print_area->right_shadow; vc = &viewport->text[(dy+y) * v_line_len + dx]; @@ -734,15 +735,16 @@ void FScrollView::copy2area() //---------------------------------------------------------------------- inline FPoint FScrollView::getViewportCursorPos() { - int x, y; FWidget* window = FWindow::getWindowWidget(this); if ( window ) { int widget_offsetX = getTermX() - window->getTermX(); int widget_offsetY = getTermY() - window->getTermY(); - x = widget_offsetX + viewport->input_cursor_x - viewport_geometry.getX(); - y = widget_offsetY + viewport->input_cursor_y - viewport_geometry.getY(); + int x = widget_offsetX + viewport->input_cursor_x + - viewport_geometry.getX(); + int y = widget_offsetY + viewport->input_cursor_y + - viewport_geometry.getY(); return FPoint(x,y); } else diff --git a/src/fstring.cpp b/src/fstring.cpp index 5bcd502f..a221959b 100644 --- a/src/fstring.cpp +++ b/src/fstring.cpp @@ -517,14 +517,14 @@ FString& FString::sprintf (const char* format, ...) buffer = buf; va_start (args, format); - len = std::vsnprintf (buffer, sizeof(buf), format, args); + len = vsnprintf (buffer, sizeof(buf), format, args); va_end (args); if ( len >= int(sizeof(buf)) ) { buffer = new char[len+1](); va_start (args, format); - std::vsnprintf (buffer, uLong(len+1), format, args); + vsnprintf (buffer, uLong(len+1), format, args); va_end (args); } @@ -1999,20 +1999,24 @@ FString FString::replaceControlCodes() const } //---------------------------------------------------------------------- -FString FString::expandTabs (uInt tabstop) const +FString FString::expandTabs (int tabstop) const { uLong last; std::vector tab_split; FString instr(string); FString outstr; + if ( tabstop <= 0 ) + return instr; + tab_split = instr.split("\t"); last = tab_split.size(); for (uInt i=0; i < last; i++) { uInt len = tab_split[i].getLength(); - outstr += tab_split[i] + FString(tabstop - len % tabstop, L' '); + uInt tab_len = uInt(tabstop); + outstr += tab_split[i] + FString(tab_len - (len % tab_len), L' '); } return outstr; diff --git a/src/fstring.h b/src/fstring.h index b1d284fc..28535859 100644 --- a/src/fstring.h +++ b/src/fstring.h @@ -306,7 +306,7 @@ class FString FString replace (const char, const char); FString replaceControlCodes() const; - FString expandTabs (uInt = 8) const; + FString expandTabs (int = 8) const; FString removeDel() const; FString removeBackspaces() const; diff --git a/src/fterm.cpp b/src/fterm.cpp index 2ab76eec..c29da0e4 100644 --- a/src/fterm.cpp +++ b/src/fterm.cpp @@ -6,9 +6,11 @@ #include "fkey_map.h" #include "ftcap_map.h" -#include "fonts/newfont.h" -#include "fonts/unicodemap.h" -#include "fonts/vgafont.h" +#if defined(__linux__) + #include "fonts/newfont.h" + #include "fonts/unicodemap.h" + #include "fonts/vgafont.h" +#endif // global FTerm object static FTerm* init_term_object = 0; @@ -68,8 +70,12 @@ bool FTerm::no_shadow_character; bool FTerm::no_half_block_character; bool FTerm::cursor_optimisation; bool FTerm::xterm_default_colors; +bool FTerm::use_alternate_screen = true; termios FTerm::term_init; -char FTerm::termtype[30] = ""; +char FTerm::termtype[30] = ""; +char FTerm::termtype_256color[30] = ""; +char FTerm::termtype_Answerback[30] = ""; +char FTerm::termtype_SecDA[30] = ""; char* FTerm::term_name = 0; char* FTerm::locale_name = 0; char* FTerm::locale_xterm = 0; @@ -97,12 +103,15 @@ bool FTermcap::ansi_default_color = false; bool FTermcap::osc_support = false; bool FTermcap::no_utf8_acs_chars = false; int FTermcap::max_color = 1; -uInt FTermcap::tabstop = 8; -uInt FTermcap::attr_without_color = 0; -console_font_op FTerm::screen_font; -unimapdesc FTerm::screen_unicode_map; +int FTermcap::tabstop = 8; +int FTermcap::attr_without_color = 0; fc::consoleCursorStyle FTerm::console_cursor_style; +#if defined(__linux__) + console_font_op FTerm::screen_font; + unimapdesc FTerm::screen_unicode_map; +#endif + //---------------------------------------------------------------------- // class FTerm @@ -110,13 +119,16 @@ fc::consoleCursorStyle FTerm::console_cursor_style; // constructors and destructor //---------------------------------------------------------------------- -FTerm::FTerm() +FTerm::FTerm (bool disable_alt_screen) : color_map() { resize_term = false; if ( ! term_initialized ) + { + use_alternate_screen = ! disable_alt_screen; init(); + } } //---------------------------------------------------------------------- @@ -174,6 +186,7 @@ const FString FTerm::getKeyName (int keynum) return FString(""); } +#if defined(__linux__) //---------------------------------------------------------------------- FTerm::modifier_key& FTerm::getModifierKey() { @@ -199,6 +212,7 @@ FTerm::modifier_key& FTerm::getModifierKey() return mod_key; } +#endif //---------------------------------------------------------------------- fc::consoleCursorStyle FTerm::getConsoleCursor() @@ -530,6 +544,7 @@ bool FTerm::setVGAFont() else Fputchar = &FTerm::putchar_ASCII; } +#if defined(__linux__) else if ( linux_terminal ) { if ( openConsole() == 0 ) @@ -562,6 +577,7 @@ bool FTerm::setVGAFont() Encoding = fc::PC; Fputchar = &FTerm::putchar_ASCII; } +#endif else VGAFont = false; @@ -599,6 +615,7 @@ bool FTerm::setNewFont() else Fputchar = &FTerm::putchar_ASCII; } +#if defined(__linux__) else if ( linux_terminal ) { NewFont = true; @@ -631,6 +648,7 @@ bool FTerm::setNewFont() Encoding = fc::PC; Fputchar = &FTerm::putchar_ASCII; // function pointer } +#endif else NewFont = false; @@ -670,6 +688,7 @@ bool FTerm::setOldFont() std::fflush(stdout); retval = true; } +#if defined(__linux__) else if ( linux_terminal ) { if ( openConsole() == 0 ) @@ -701,6 +720,7 @@ bool FTerm::setOldFont() closeConsole(); } } +#endif return retval; } @@ -1425,7 +1445,7 @@ const FString FTerm::getSecDA() FD_ZERO(&ifds); FD_SET(stdin_no, &ifds); tv.tv_sec = 0; - tv.tv_usec = 600000;; // 600 ms + tv.tv_usec = 600000; // 600 ms // read the answer if ( select (stdin_no+1, &ifds, 0, 0, &tv) == 1 ) @@ -1445,7 +1465,7 @@ void FTerm::putstringf (const char* const format, ...) buffer = buf; va_start (args, format); - std::vsnprintf (buffer, sizeof(buf), format, args); + vsnprintf (buffer, sizeof(buf), format, args); va_end (args); tputs (buffer, 1, std::putchar); @@ -1550,6 +1570,7 @@ int FTerm::UTF8decode (const char utf8[]) // protected methods of FTerm //---------------------------------------------------------------------- +#if defined(__linux__) void FTerm::init_consoleCharMap() { uInt c1, c2, c3, c4, c5; @@ -1597,6 +1618,7 @@ void FTerm::init_consoleCharMap() no_half_block_character = true; } } +#endif //---------------------------------------------------------------------- bool FTerm::charEncodable (uInt c) @@ -1707,6 +1729,7 @@ bool FTerm::gpmMouse (bool on) // private methods of FTerm //---------------------------------------------------------------------- +#if defined(__linux__) int FTerm::isConsole() { char arg = 0; @@ -1844,6 +1867,7 @@ int FTerm::getFramebuffer_bpp () return -1; } +#endif //---------------------------------------------------------------------- int FTerm::openConsole() @@ -1902,7 +1926,7 @@ void FTerm::identifyTermType() std::FILE *fp; if ( (fp = std::fopen("/etc/ttytype", "r")) != 0 - || (fp = std::fopen("/etc/ttys", "r")) != 0 ) + || (fp = std::fopen("/etc/ttys", "r")) != 0 ) // FreeBSD: man 5 ttys { char* p; char* type; @@ -1965,6 +1989,7 @@ void FTerm::restoreTTYsettings() setTTY (term_init); } +#if defined(__linux__) //---------------------------------------------------------------------- int FTerm::getScreenFont() { @@ -2172,6 +2197,7 @@ void FTerm::init_console() std::abort(); } } +#endif //---------------------------------------------------------------------- uInt FTerm::getBaudRate (const struct termios* termios_p) @@ -2283,6 +2309,13 @@ char* FTerm::init_256colorTerminal() new_termtype = const_cast("gnome-256color"); } +#if DEBUG + if ( new_termtype ) + std::strncpy ( termtype_256color + , new_termtype + , std::strlen(new_termtype) + 1 ); +#endif + return new_termtype; } @@ -2310,6 +2343,13 @@ char* FTerm::parseAnswerbackMsg (char*& current_termtype) if ( cygwin_terminal ) putstring (BS " " BS); +#if DEBUG + if ( new_termtype ) + std::strncpy ( termtype_Answerback + , new_termtype + , std::strlen(new_termtype) + 1 ); +#endif + return new_termtype; } @@ -2373,6 +2413,7 @@ char* FTerm::parseSecDA (char*& current_termtype) { terminal_id_version = -1; } + switch ( terminal_id_type ) { case 0: // DEC VT100 @@ -2453,6 +2494,13 @@ char* FTerm::parseSecDA (char*& current_termtype) } } +#if DEBUG + if ( new_termtype ) + std::strncpy ( termtype_SecDA + , new_termtype + , std::strlen(new_termtype) + 1 ); +#endif + return new_termtype; } @@ -2485,9 +2533,10 @@ void FTerm::oscPostfix() void FTerm::init_alt_charset() { // read the used vt100 pairs + if ( tcap[fc::t_acs_chars].string ) { - for (int n=0; tcap[fc::t_acs_chars].string[n]; tcap[fc::t_acs_chars].string += 2) + for (int n=0; tcap[fc::t_acs_chars].string[n]; n += 2) { // insert the vt100 key/value pairs into a map uChar p1 = uChar(tcap[fc::t_acs_chars].string[n]); @@ -2595,328 +2644,446 @@ void FTerm::init_termcaps() static char term_buffer[2048]; static char string_buf[2048]; char* buffer = string_buf; + char* key_up_string; + const int success = 1; + const int no_entry = 0; + const int db_not_found = -1; + const int not_available = -1; + const int uninitialized = -2; + int status = uninitialized; // share the terminal capabilities FTermcap().setTermcapMap(tcap); - // open the termcap file + load entry for termtype - if ( tgetent(term_buffer, termtype) == 1 ) + if ( termtype[0] ) { - char* key_up_string; + // open the termcap file + load entry for termtype + status = tgetent(term_buffer, termtype); + } - // screen erased with the background color - FTermcap::background_color_erase = tgetflag(const_cast("ut")); + if ( status != success ) + { + // use xterm as fallback if not found + std::strncpy (termtype, const_cast("xterm"), 5); + status = tgetent(term_buffer, termtype); - // t_cursor_left wraps from column 0 to last column - FTermcap::automatic_left_margin = tgetflag(const_cast("bw")); + if ( status != success ) + { + // use ansi as fallback if not found + std::strncpy (termtype, const_cast("ansi"), 5); + status = tgetent(term_buffer, termtype); + ansi_terminal = true; - // terminal has auto-matic margins - FTermcap::automatic_right_margin = tgetflag(const_cast("am")); + if ( status != success ) + { + // use vt100 as fallback if not found + std::strncpy (termtype, const_cast("vt100"), 6); + status = tgetent(term_buffer, termtype); + ansi_terminal = false; + } + } + } - // newline ignored after 80 cols - FTermcap::eat_nl_glitch = tgetflag(const_cast("xn")); + if ( status == no_entry ) + { + std::cerr << "Unknown terminal: " << termtype << "\n" + << "Check the TERM environment variable\n" + << "Also make sure that the terminal\n" + << "is defined in the termcap/terminfo database.\n"; + std::abort(); + } + else if ( status == db_not_found ) + { + std::cerr << "The termcap/terminfo database could not be found.\n"; + std::abort(); + } - // terminal supports ANSI set default fg and bg color - FTermcap::ansi_default_color = tgetflag(const_cast("AX")); + // get termcap booleans + // -------------------- - // terminal supports operating system commands (OSC) - // OSC = Esc + ']' - FTermcap::osc_support = tgetflag(const_cast("XT")); + // screen erased with the background color + FTermcap::background_color_erase = tgetflag(const_cast("ut")); - // U8 is nonzero for terminals with no VT100 line-drawing in UTF-8 mode - FTermcap::no_utf8_acs_chars = bool(tgetnum(const_cast("U8")) != 0); + // t_cursor_left wraps from column 0 to last column + FTermcap::automatic_left_margin = tgetflag(const_cast("bw")); - if ( isTeraTerm() ) - FTermcap::eat_nl_glitch = true; + // terminal has auto-matic margins + FTermcap::automatic_right_margin = tgetflag(const_cast("am")); - // maximum number of colors on screen - FTermcap::max_color = std::max( FTermcap::max_color - , tgetnum(const_cast("Co")) ); + // newline ignored after 80 cols + FTermcap::eat_nl_glitch = tgetflag(const_cast("xn")); - if ( FTermcap::max_color < 0 ) - FTermcap::max_color = 1; + // terminal supports ANSI set default fg and bg color + FTermcap::ansi_default_color = tgetflag(const_cast("AX")); - if ( FTermcap::max_color < 8 ) - monochron = true; + // terminal supports operating system commands (OSC) + // OSC = Esc + ']' + FTermcap::osc_support = tgetflag(const_cast("XT")); + + // U8 is nonzero for terminals with no VT100 line-drawing in UTF-8 mode + FTermcap::no_utf8_acs_chars = bool(tgetnum(const_cast("U8")) != 0); + + if ( isTeraTerm() ) + FTermcap::eat_nl_glitch = true; + + // get termcap numeric + // ------------------- + + // maximum number of colors on screen + FTermcap::max_color = std::max( FTermcap::max_color + , tgetnum(const_cast("Co")) ); + + if ( FTermcap::max_color < 0 ) + FTermcap::max_color = 1; + + if ( FTermcap::max_color < 8 ) + monochron = true; + else + monochron = false; + + // get initial spacing for hardware tab stop + FTermcap::tabstop = tgetnum(const_cast("it")); + + if ( FTermcap::tabstop == not_available ) + FTermcap::tabstop = 8; + + // get video attributes that cannot be used with colors + FTermcap::attr_without_color = tgetnum(const_cast("NC")); + + if ( FTermcap::attr_without_color == not_available ) + FTermcap::attr_without_color = 0; + + // gnome-terminal has NC=16 however, it can use the dim attribute + if ( gnome_terminal ) + FTermcap::attr_without_color = 0; + + // PuTTY has NC=22 however, it can show underline and reverse + if ( putty_terminal ) + FTermcap::attr_without_color = 16; + + // get termcap strings + // ------------------- + + // read termcap output strings + for (int i=0; tcap[i].tname[0] != 0; i++) + tcap[i].string = tgetstr(tcap[i].tname, &buffer); + + // set invisible cursor for cygwin terminal + if ( cygwin_terminal && ! tcap[fc::t_cursor_invisible].string ) + tcap[fc::t_cursor_invisible].string = \ + const_cast(CSI "?25l"); + + // set visible cursor for cygwin terminal + if ( cygwin_terminal && ! tcap[fc::t_cursor_visible].string ) + tcap[fc::t_cursor_visible].string = \ + const_cast(CSI "?25h"); + + // set ansi blink for cygwin terminal + if ( cygwin_terminal && ! tcap[fc::t_enter_blink_mode].string ) + tcap[fc::t_enter_blink_mode].string = \ + const_cast(CSI "5m"); + + // set enter/exit alternative charset mode for rxvt terminal + if ( rxvt_terminal && std::strncmp(termtype, "rxvt-16color", 12) == 0 ) + { + tcap[fc::t_enter_alt_charset_mode].string = \ + const_cast(ESC "(0"); + tcap[fc::t_exit_alt_charset_mode].string = \ + const_cast(ESC "(B"); + } + + // set exit underline for gnome terminal + if ( gnome_terminal ) + tcap[fc::t_exit_underline_mode].string = \ + const_cast(CSI "24m"); + + // set background color erase for cygwin terminal + if ( cygwin_terminal ) + FTermcap::background_color_erase = true; + + // set ansi foreground and background color + if ( linux_terminal || cygwin_terminal ) + { + if ( FTermcap::max_color > 8 ) + { + tcap[fc::t_set_a_foreground].string = \ + const_cast(CSI "3%p1%{8}%m%d%?%p1%{7}%>%t;1%e;21%;m"); + tcap[fc::t_set_a_background].string = \ + const_cast(CSI "4%p1%{8}%m%d%?%p1%{7}%>%t;5%e;25%;m"); + } else - monochron = false; - - FTermcap::tabstop = uInt(tgetnum(const_cast("it"))); - FTermcap::attr_without_color = uInt(tgetnum(const_cast("NC"))); - - // gnome-terminal has NC=16 however, it can use the dim attribute - if ( gnome_terminal ) - FTermcap::attr_without_color = 0; - - // PuTTY has NC=22 however, it can show underline and reverse - if ( putty_terminal ) - FTermcap::attr_without_color = 16; - - // read termcap output strings - for (int i=0; tcap[i].tname[0] != 0; i++) - tcap[i].string = tgetstr(tcap[i].tname, &buffer); - - // set invisible cursor for cygwin terminal - if ( cygwin_terminal && ! tcap[fc::t_cursor_invisible].string ) - tcap[fc::t_cursor_invisible].string = \ - const_cast(CSI "?25l"); - - // set visible cursor for cygwin terminal - if ( cygwin_terminal && ! tcap[fc::t_cursor_visible].string ) - tcap[fc::t_cursor_visible].string = \ - const_cast(CSI "?25h"); - - // set ansi blink for cygwin terminal - if ( cygwin_terminal && ! tcap[fc::t_enter_blink_mode].string ) - tcap[fc::t_enter_blink_mode].string = \ - const_cast(CSI "5m"); - - // set enter/exit alternative charset mode for rxvt terminal - if ( rxvt_terminal && std::strncmp(termtype, "rxvt-16color", 12) == 0 ) { - tcap[fc::t_enter_alt_charset_mode].string = \ - const_cast(ESC "(0"); - tcap[fc::t_exit_alt_charset_mode].string = \ - const_cast(ESC "(B"); - } - - // set exit underline for gnome terminal - if ( gnome_terminal ) - tcap[fc::t_exit_underline_mode].string = \ - const_cast(CSI "24m"); - - // set background color erase for cygwin terminal - if ( cygwin_terminal ) - FTermcap::background_color_erase = true; - - // set ansi foreground and background color - if ( linux_terminal || cygwin_terminal ) - { - if ( FTermcap::max_color > 8 ) - { - tcap[fc::t_set_a_foreground].string = \ - const_cast(CSI "3%p1%{8}%m%d%?%p1%{7}%>%t;1%e;21%;m"); - tcap[fc::t_set_a_background].string = \ - const_cast(CSI "4%p1%{8}%m%d%?%p1%{7}%>%t;5%e;25%;m"); - } - else - { - tcap[fc::t_set_a_foreground].string = \ - const_cast(CSI "3%p1%dm"); - tcap[fc::t_set_a_background].string = \ - const_cast(CSI "4%p1%dm"); - } - - tcap[fc::t_orig_pair].string = \ - const_cast(CSI "39;49;25m"); - - // avoid dim + underline - tcap[fc::t_enter_dim_mode].string = 0; - tcap[fc::t_exit_dim_mode].string = 0; - tcap[fc::t_enter_underline_mode].string = 0; - tcap[fc::t_exit_underline_mode].string = 0; - FTermcap::attr_without_color = 18; - } - else if ( rxvt_terminal && ! urxvt_terminal ) - { - tcap[fc::t_set_a_foreground].string = \ - const_cast(CSI "%?%p1%{8}%<%t%p1%{30}%+%e%p1%'R'%+%;%dm"); - tcap[fc::t_set_a_background].string = \ - const_cast(CSI "%?%p1%{8}%<%t%p1%'('%+%e%p1%{92}%+%;%dm"); - } - else if ( tera_terminal ) - { - tcap[fc::t_set_a_foreground].string = \ - const_cast(CSI "38;5;%p1%dm"); - tcap[fc::t_set_a_background].string = \ - const_cast(CSI "48;5;%p1%dm"); - tcap[fc::t_exit_attribute_mode].string = \ - const_cast(CSI "0m" SI); - tcap[fc::t_orig_pair].string = \ - const_cast(CSI "39;49m"); - } - else if ( putty_terminal ) - { - tcap[fc::t_set_a_foreground].string = \ - const_cast(CSI "%?%p1%{8}%<" - "%t3%p1%d" - "%e%p1%{16}%<" - "%t9%p1%{8}%-%d" - "%e38;5;%p1%d%;m"); - tcap[fc::t_set_a_background].string = \ - const_cast(CSI "%?%p1%{8}%<" - "%t4%p1%d" - "%e%p1%{16}%<" - "%t10%p1%{8}%-%d" - "%e48;5;%p1%d%;m"); - } - - // fallback if "AF" is not found - if ( ! tcap[fc::t_set_a_foreground].string ) tcap[fc::t_set_a_foreground].string = \ const_cast(CSI "3%p1%dm"); - - // fallback if "AB" is not found - if ( ! tcap[fc::t_set_a_background].string ) tcap[fc::t_set_a_background].string = \ const_cast(CSI "4%p1%dm"); + } - // fallback if "Ic" is not found - if ( ! tcap[fc::t_initialize_color].string ) + tcap[fc::t_orig_pair].string = \ + const_cast(CSI "39;49;25m"); + + // avoid dim + underline + tcap[fc::t_enter_dim_mode].string = 0; + tcap[fc::t_exit_dim_mode].string = 0; + tcap[fc::t_enter_underline_mode].string = 0; + tcap[fc::t_exit_underline_mode].string = 0; + FTermcap::attr_without_color = 18; + } + else if ( rxvt_terminal && ! urxvt_terminal ) + { + tcap[fc::t_set_a_foreground].string = \ + const_cast(CSI "%?%p1%{8}%<%t%p1%{30}%+%e%p1%'R'%+%;%dm"); + tcap[fc::t_set_a_background].string = \ + const_cast(CSI "%?%p1%{8}%<%t%p1%'('%+%e%p1%{92}%+%;%dm"); + } + else if ( tera_terminal ) + { + tcap[fc::t_set_a_foreground].string = \ + const_cast(CSI "38;5;%p1%dm"); + tcap[fc::t_set_a_background].string = \ + const_cast(CSI "48;5;%p1%dm"); + tcap[fc::t_exit_attribute_mode].string = \ + const_cast(CSI "0m" SI); + tcap[fc::t_orig_pair].string = \ + const_cast(CSI "39;49m"); + } + else if ( putty_terminal ) + { + FTermcap::background_color_erase = true; + FTermcap::osc_support = true; + + tcap[fc::t_set_a_foreground].string = \ + const_cast(CSI "%?%p1%{8}%<" + "%t3%p1%d" + "%e%p1%{16}%<" + "%t9%p1%{8}%-%d" + "%e38;5;%p1%d%;m"); + + tcap[fc::t_set_a_background].string = \ + const_cast(CSI "%?%p1%{8}%<" + "%t4%p1%d" + "%e%p1%{16}%<" + "%t10%p1%{8}%-%d" + "%e48;5;%p1%d%;m"); + + if ( ! tcap[fc::t_clr_bol].string ) + tcap[fc::t_clr_bol].string = \ + const_cast(CSI "1K"); + + if ( ! tcap[fc::t_orig_pair].string ) + tcap[fc::t_orig_pair].string = \ + const_cast(CSI "39;49m"); + + if ( ! tcap[fc::t_orig_colors].string ) + tcap[fc::t_orig_colors].string = \ + const_cast(OSC "R"); + + if ( ! tcap[fc::t_column_address].string ) + tcap[fc::t_column_address].string = \ + const_cast(CSI "%i%p1%dG"); + + if ( ! tcap[fc::t_row_address].string ) + tcap[fc::t_row_address].string = \ + const_cast(CSI "%i%p1%dd"); + + if ( ! tcap[fc::t_enable_acs].string ) + tcap[fc::t_enable_acs].string = \ + const_cast(ESC "(B" ESC ")0"); + + if ( ! tcap[fc::t_set_attributes].string ) + tcap[fc::t_set_attributes].string = \ + const_cast(CSI "0%?%p1%p6%|" + "%t;1%;%?%p2%t;" + "4%;%?%p1%p3%|" + "%t;7%;%?%p4%t;" + "5%;m%?%p9%t\016%e\017%;"); + + if ( ! tcap[fc::t_enter_am_mode].string ) + tcap[fc::t_enter_am_mode].string = \ + const_cast(CSI "?7h"); + + if ( ! tcap[fc::t_exit_am_mode].string ) + tcap[fc::t_exit_am_mode].string = \ + const_cast(CSI "?7l"); + + if ( ! tcap[fc::t_enter_pc_charset_mode].string ) + tcap[fc::t_enter_pc_charset_mode].string = \ + const_cast(CSI "11m"); + + if ( ! tcap[fc::t_exit_pc_charset_mode].string ) + tcap[fc::t_exit_pc_charset_mode].string = \ + const_cast(CSI "10m"); + + if ( ! tcap[fc::t_key_mouse].string ) + tcap[fc::t_key_mouse].string = \ + const_cast(CSI "M"); + } + + // fallback if "AF" is not found + if ( ! tcap[fc::t_set_a_foreground].string ) + tcap[fc::t_set_a_foreground].string = \ + const_cast(CSI "3%p1%dm"); + + // fallback if "AB" is not found + if ( ! tcap[fc::t_set_a_background].string ) + tcap[fc::t_set_a_background].string = \ + const_cast(CSI "4%p1%dm"); + + // fallback if "Ic" is not found + if ( ! tcap[fc::t_initialize_color].string ) + { + if ( screen_terminal ) { - if ( screen_terminal ) + if ( tmux_terminal ) { - if ( tmux_terminal ) - { - tcap[fc::t_initialize_color].string = \ - const_cast(ESC "Ptmux;" ESC OSC "4;%p1%d;rgb:" - "%p2%{255}%*%{1000}%/%2.2X/" - "%p3%{255}%*%{1000}%/%2.2X/" - "%p4%{255}%*%{1000}%/%2.2X" BEL ESC "\\"); - } - else - { - tcap[fc::t_initialize_color].string = \ - const_cast(ESC "P" OSC "4;%p1%d;rgb:" - "%p2%{255}%*%{1000}%/%2.2X/" - "%p3%{255}%*%{1000}%/%2.2X/" - "%p4%{255}%*%{1000}%/%2.2X" BEL ESC "\\"); - } + tcap[fc::t_initialize_color].string = \ + const_cast(ESC "Ptmux;" ESC OSC "4;%p1%d;rgb:" + "%p2%{255}%*%{1000}%/%2.2X/" + "%p3%{255}%*%{1000}%/%2.2X/" + "%p4%{255}%*%{1000}%/%2.2X" BEL ESC "\\"); } else { tcap[fc::t_initialize_color].string = \ - const_cast(OSC "P%p1%x" - "%p2%{255}%*%{1000}%/%02x" - "%p3%{255}%*%{1000}%/%02x" - "%p4%{255}%*%{1000}%/%02x"); + const_cast(ESC "P" OSC "4;%p1%d;rgb:" + "%p2%{255}%*%{1000}%/%2.2X/" + "%p3%{255}%*%{1000}%/%2.2X/" + "%p4%{255}%*%{1000}%/%2.2X" BEL ESC "\\"); } - } - - // fallback if "ti" is not found - if ( ! tcap[fc::t_enter_ca_mode].string ) - tcap[fc::t_enter_ca_mode].string = \ - const_cast(ESC "7" CSI "?47h"); - - // fallback if "te" is not found - if ( ! tcap[fc::t_exit_ca_mode].string ) - tcap[fc::t_exit_ca_mode].string = \ - const_cast(CSI "?47l" ESC "8" CSI "m"); - - // set ansi move if "cm" is not found - if ( ! tcap[fc::t_cursor_address].string ) - tcap[fc::t_cursor_address].string = \ - const_cast(CSI "%i%p1%d;%p2%dH"); - - // test for standard ECMA-48 (ANSI X3.64) terminal - if ( tcap[fc::t_exit_underline_mode].string - && std::strncmp(tcap[fc::t_exit_underline_mode].string, CSI "24m", 5) == 0 ) - { - // seems to be a ECMA-48 (ANSI X3.64) compatible terminal - tcap[fc::t_enter_dbl_underline_mode].string = \ - const_cast(CSI "21m"); // Exit single underline, too - - tcap[fc::t_exit_dbl_underline_mode].string = \ - const_cast(CSI "24m"); - - tcap[fc::t_exit_bold_mode].string = \ - const_cast(CSI "22m"); // Exit dim, too - - tcap[fc::t_exit_dim_mode].string = \ - const_cast(CSI "22m"); - - tcap[fc::t_exit_underline_mode].string = \ - const_cast(CSI "24m"); - - tcap[fc::t_exit_blink_mode].string = \ - const_cast(CSI "25m"); - - tcap[fc::t_exit_reverse_mode].string = \ - const_cast(CSI "27m"); - - tcap[fc::t_exit_secure_mode].string = \ - const_cast(CSI "28m"); - - tcap[fc::t_enter_crossed_out_mode].string = \ - const_cast(CSI "9m"); - - tcap[fc::t_exit_crossed_out_mode].string = \ - const_cast(CSI "29m"); } - - // read termcap key strings - for (int i=0; Fkey[i].tname[0] != 0; i++) + else if ( xterm_terminal && ! putty_terminal ) { - Fkey[i].string = tgetstr(Fkey[i].tname, &buffer); - - // fallback for rxvt with TERM=xterm - if ( std::strncmp(Fkey[i].tname, "khx", 3) == 0 ) - Fkey[i].string = const_cast(CSI "7~"); // home key - - if ( std::strncmp(Fkey[i].tname, "@7x", 3) == 0 ) - Fkey[i].string = const_cast(CSI "8~"); // end key - - if ( std::strncmp(Fkey[i].tname, "k1x", 3) == 0 ) - Fkey[i].string = const_cast(CSI "11~"); // F1 - - if ( std::strncmp(Fkey[i].tname, "k2x", 3) == 0 ) - Fkey[i].string = const_cast(CSI "12~"); // F2 - - if ( std::strncmp(Fkey[i].tname, "k3x", 3) == 0 ) - Fkey[i].string = const_cast(CSI "13~"); // F3 - - if ( std::strncmp(Fkey[i].tname, "k4x", 3) == 0 ) - Fkey[i].string = const_cast(CSI "14~"); // F4 - - // fallback for TERM=ansi - if ( std::strncmp(Fkey[i].tname, "@7X", 3) == 0 ) - Fkey[i].string = const_cast(CSI "K"); // end key + tcap[fc::t_initialize_color].string = \ + const_cast(OSC "4;%p1%d;rgb:" + "%p2%{255}%*%{1000}%/%2.2X/" + "%p3%{255}%*%{1000}%/%2.2X/" + "%p4%{255}%*%{1000}%/%2.2X" ESC "\\"); } - - // Some terminals (e.g. PuTTY) send the wrong code for the arrow keys - // http://www.unix.com/shell-programming-scripting/.. - // ..110380-using-arrow-keys-shell-scripts.html - key_up_string = tgetstr(const_cast("ku"), &buffer); - - if ( (key_up_string && (std::strcmp(key_up_string, CSI "A") == 0)) - || ( tcap[fc::t_cursor_up].string - && (std::strcmp(tcap[fc::t_cursor_up].string, CSI "A") == 0) ) ) + else { - for (int i=0; Fkey[i].tname[0] != 0; i++) - { - if ( std::strncmp(Fkey[i].tname, "kux", 3) == 0 ) - Fkey[i].string = const_cast(CSI "A"); // key up - - if ( std::strncmp(Fkey[i].tname, "kdx", 3) == 0 ) - Fkey[i].string = const_cast(CSI "B"); // key down - - if ( std::strncmp(Fkey[i].tname, "krx", 3) == 0 ) - Fkey[i].string = const_cast(CSI "C"); // key right - - if ( std::strncmp(Fkey[i].tname, "klx", 3) == 0 ) - Fkey[i].string = const_cast(CSI "D"); // key left - - if ( std::strncmp(Fkey[i].tname, "k1X", 3) == 0 ) - Fkey[i].string = const_cast(ESC "OP"); // PF1 - - if ( std::strncmp(Fkey[i].tname, "k2X", 3) == 0 ) - Fkey[i].string = const_cast(ESC "OQ"); // PF2 - - if ( std::strncmp(Fkey[i].tname, "k3X", 3) == 0 ) - Fkey[i].string = const_cast(ESC "OR"); // PF3 - - if ( std::strncmp(Fkey[i].tname, "k4X", 3) == 0 ) - Fkey[i].string = const_cast(ESC "OS"); // PF4 - } + tcap[fc::t_initialize_color].string = \ + const_cast(OSC "P%p1%x" + "%p2%{255}%*%{1000}%/%02x" + "%p3%{255}%*%{1000}%/%02x" + "%p4%{255}%*%{1000}%/%02x"); } } - else + + // fallback if "ti" is not found + if ( ! tcap[fc::t_enter_ca_mode].string ) + tcap[fc::t_enter_ca_mode].string = \ + const_cast(ESC "7" CSI "?47h"); + + // fallback if "te" is not found + if ( ! tcap[fc::t_exit_ca_mode].string ) + tcap[fc::t_exit_ca_mode].string = \ + const_cast(CSI "?47l" ESC "8" CSI "m"); + + // set ansi move if "cm" is not found + if ( ! tcap[fc::t_cursor_address].string ) + tcap[fc::t_cursor_address].string = \ + const_cast(CSI "%i%p1%d;%p2%dH"); + + // test for standard ECMA-48 (ANSI X3.64) terminal + if ( tcap[fc::t_exit_underline_mode].string + && std::strncmp(tcap[fc::t_exit_underline_mode].string, CSI "24m", 5) == 0 ) { - std::cerr << "Unknown terminal: " << termtype << "\n" - << "Check the TERM environment variable\n" - << "Also make sure that the terminal" - << "is defined in the terminfo database.\n"; - std::abort(); + // seems to be a ECMA-48 (ANSI X3.64) compatible terminal + tcap[fc::t_enter_dbl_underline_mode].string = \ + const_cast(CSI "21m"); // Exit single underline, too + + tcap[fc::t_exit_dbl_underline_mode].string = \ + const_cast(CSI "24m"); + + tcap[fc::t_exit_bold_mode].string = \ + const_cast(CSI "22m"); // Exit dim, too + + tcap[fc::t_exit_dim_mode].string = \ + const_cast(CSI "22m"); + + tcap[fc::t_exit_underline_mode].string = \ + const_cast(CSI "24m"); + + tcap[fc::t_exit_blink_mode].string = \ + const_cast(CSI "25m"); + + tcap[fc::t_exit_reverse_mode].string = \ + const_cast(CSI "27m"); + + tcap[fc::t_exit_secure_mode].string = \ + const_cast(CSI "28m"); + + tcap[fc::t_enter_crossed_out_mode].string = \ + const_cast(CSI "9m"); + + tcap[fc::t_exit_crossed_out_mode].string = \ + const_cast(CSI "29m"); + } + + // read termcap key strings + for (int i=0; Fkey[i].tname[0] != 0; i++) + { + Fkey[i].string = tgetstr(Fkey[i].tname, &buffer); + + // fallback for rxvt with TERM=xterm + if ( std::strncmp(Fkey[i].tname, "khx", 3) == 0 ) + Fkey[i].string = const_cast(CSI "7~"); // home key + + if ( std::strncmp(Fkey[i].tname, "@7x", 3) == 0 ) + Fkey[i].string = const_cast(CSI "8~"); // end key + + if ( std::strncmp(Fkey[i].tname, "k1x", 3) == 0 ) + Fkey[i].string = const_cast(CSI "11~"); // F1 + + if ( std::strncmp(Fkey[i].tname, "k2x", 3) == 0 ) + Fkey[i].string = const_cast(CSI "12~"); // F2 + + if ( std::strncmp(Fkey[i].tname, "k3x", 3) == 0 ) + Fkey[i].string = const_cast(CSI "13~"); // F3 + + if ( std::strncmp(Fkey[i].tname, "k4x", 3) == 0 ) + Fkey[i].string = const_cast(CSI "14~"); // F4 + + // fallback for TERM=ansi + if ( std::strncmp(Fkey[i].tname, "@7X", 3) == 0 ) + Fkey[i].string = const_cast(CSI "K"); // end key + } + + // Some terminals (e.g. PuTTY) send the wrong code for the arrow keys + // http://www.unix.com/shell-programming-scripting/.. + // ..110380-using-arrow-keys-shell-scripts.html + key_up_string = tgetstr(const_cast("ku"), &buffer); + + if ( (key_up_string && (std::strcmp(key_up_string, CSI "A") == 0)) + || ( tcap[fc::t_cursor_up].string + && (std::strcmp(tcap[fc::t_cursor_up].string, CSI "A") == 0) ) ) + { + for (int i=0; Fkey[i].tname[0] != 0; i++) + { + if ( std::strncmp(Fkey[i].tname, "kux", 3) == 0 ) + Fkey[i].string = const_cast(CSI "A"); // key up + + if ( std::strncmp(Fkey[i].tname, "kdx", 3) == 0 ) + Fkey[i].string = const_cast(CSI "B"); // key down + + if ( std::strncmp(Fkey[i].tname, "krx", 3) == 0 ) + Fkey[i].string = const_cast(CSI "C"); // key right + + if ( std::strncmp(Fkey[i].tname, "klx", 3) == 0 ) + Fkey[i].string = const_cast(CSI "D"); // key left + + if ( std::strncmp(Fkey[i].tname, "k1X", 3) == 0 ) + Fkey[i].string = const_cast(ESC "OP"); // PF1 + + if ( std::strncmp(Fkey[i].tname, "k2X", 3) == 0 ) + Fkey[i].string = const_cast(ESC "OQ"); // PF2 + + if ( std::strncmp(Fkey[i].tname, "k3X", 3) == 0 ) + Fkey[i].string = const_cast(ESC "OR"); // PF3 + + if ( std::strncmp(Fkey[i].tname, "k4X", 3) == 0 ) + Fkey[i].string = const_cast(ESC "OS"); // PF4 + } } // duration precalculation of the cursor movement strings @@ -3051,8 +3218,10 @@ void FTerm::init_encoding() Fputchar = &FTerm::putchar_ASCII; // function pointer } - if ( linux_terminal - && (Encoding == fc::VT100 || Encoding == fc::PC) ) + // In some alternative character sets, a tab character prints a '○' + // on the terminal and does not move the cursor to the next tab stop + // position + if ( Encoding == fc::VT100 || Encoding == fc::PC ) { char* empty = 0; opti_move->set_tabular (empty); @@ -3129,8 +3298,10 @@ void FTerm::init() term_name = ttyname(stdout_no); +#if defined(__linux__) // initialize terminal and Linux console init_console(); +#endif // save termios settings storeTTYsettings(); @@ -3213,6 +3384,7 @@ void FTerm::init() FTermcap::max_color = 16; } +#if defined(__linux__) if ( linux_terminal && openConsole() == 0 ) { if ( isConsole() ) @@ -3229,6 +3401,7 @@ void FTerm::init() if ( linux_terminal && getFramebuffer_bpp() >= 4 ) FTermcap::max_color = 16; +#endif t.c_lflag |= uInt(ICANON | ECHO); tcsetattr(stdin_no, TCSADRAIN, &t); @@ -3236,7 +3409,7 @@ void FTerm::init() // Test if the terminal is a xterm if ( std::strncmp(termtype, const_cast("xterm"), 5) == 0 - || std::strncmp(termtype, const_cast("Eterm"), 4) == 0 ) + || std::strncmp(termtype, const_cast("Eterm"), 5) == 0 ) { xterm_terminal = true; @@ -3304,7 +3477,7 @@ void FTerm::init() #endif // xterm mouse support - if ( tcap[fc::t_key_mouse].string != 0 && ! linux_terminal ) + if ( tcap[fc::t_key_mouse].string && ! linux_terminal ) { mouse_support = true; enableXTermMouse(); @@ -3318,14 +3491,14 @@ void FTerm::init() } // save current cursor position - if ( tcap[fc::t_save_cursor].string ) + if ( use_alternate_screen && tcap[fc::t_save_cursor].string ) { putstring (tcap[fc::t_save_cursor].string); std::fflush(stdout); } // saves the screen and the cursor position - if ( tcap[fc::t_enter_ca_mode].string ) + if ( use_alternate_screen && tcap[fc::t_enter_ca_mode].string ) { putstring (tcap[fc::t_enter_ca_mode].string); std::fflush(stdout); @@ -3358,7 +3531,8 @@ void FTerm::init() if ( FTermcap::max_color >= 16 && ! cygwin_terminal && ! kde_konsole - && ! tera_terminal ) + && ! tera_terminal + && ! ansi_terminal ) { resetColorMap(); saveColorMap(); @@ -3437,7 +3611,8 @@ void FTerm::finish() // set xterm full block cursor setXTermCursorStyle(fc::steady_block); - if ( FTermcap::max_color >= 16 && ! (kde_konsole || tera_terminal) ) + if ( FTermcap::max_color >= 16 + && ! (kde_konsole || tera_terminal || ansi_terminal) ) { // reset screen settings setPalette (fc::Cyan, 0x18, 0xb2, 0xb2); @@ -3457,11 +3632,13 @@ void FTerm::finish() std::fflush(stdout); } +#if defined(__linux__) if ( linux_terminal ) { setBlinkAsIntensity (false); setConsoleCursor(fc::default_cursor, false); } +#endif if ( kde_konsole ) setKDECursor(fc::BlockCursor); @@ -3479,14 +3656,14 @@ void FTerm::finish() #endif // restores the screen and the cursor position - if ( tcap[fc::t_exit_ca_mode].string ) + if ( use_alternate_screen && tcap[fc::t_exit_ca_mode].string ) { putstring (tcap[fc::t_exit_ca_mode].string); std::fflush(stdout); } // restore cursor to position of last save_cursor - if ( tcap[fc::t_restore_cursor].string ) + if ( use_alternate_screen && tcap[fc::t_restore_cursor].string ) { putstring (tcap[fc::t_restore_cursor].string); std::fflush(stdout); @@ -3499,6 +3676,7 @@ void FTerm::finish() std::fflush(stdout); } +#if defined(__linux__) if ( linux_terminal && utf8_console ) setUTF8(true); @@ -3512,6 +3690,7 @@ void FTerm::finish() if ( screen_unicode_map.entries != 0 ) delete[] screen_unicode_map.entries; } +#endif if ( encoding_set ) delete encoding_set; diff --git a/src/fterm.h b/src/fterm.h index 64a3be86..3a4f8de9 100644 --- a/src/fterm.h +++ b/src/fterm.h @@ -33,12 +33,14 @@ #include #endif -#include // Linux framebuffer console -#include // need for gpm keyboard modifiers +#if defined(__linux__) + #include // Linux framebuffer console + #include // need for gpm keyboard modifiers + #include // is deprecated, use instead + #include +#endif -#include // is deprecated, use instead #include -#include #include #include @@ -99,7 +101,7 @@ class FTerm } mod_key; // Constructor - FTerm (); + FTerm (bool = false); // Destructor virtual ~FTerm(); @@ -110,13 +112,20 @@ class FTerm static int getLineNumber(); static int getColumnNumber(); static const FString getKeyName (int); +#if defined(__linux__) static modifier_key& getModifierKey(); +#endif static char* getTermType(); static char* getTermName(); - static uInt getTabstop(); + static int getTabstop(); static int getMaxColor(); static fc::consoleCursorStyle getConsoleCursor(); +#if DEBUG + static const FString& getAnswerbackString(); + static const FString& getSecDAString(); +#endif + // Inquiries static bool isKeyTimeout (timeval*, register long); static bool isNormal (char_data*&); @@ -156,6 +165,7 @@ class FTerm static bool setRawMode(); static bool unsetRawMode(); static bool setCookedMode(); + static void disableAltScreen(); static bool setUTF8 (bool); static bool setUTF8(); static bool unsetUTF8(); @@ -227,9 +237,17 @@ class FTerm static int putchar_UTF8 (register int); static int UTF8decode (const char[]); +#if DEBUG + static char termtype_256color[30]; + static char termtype_Answerback[30]; + static char termtype_SecDA[30]; +#endif + protected: // Methods +#if defined(__linux__) static void init_consoleCharMap(); +#endif static bool charEncodable (uInt); static uInt charEncode (uInt); static uInt charEncode (uInt, fc::encoding); @@ -265,6 +283,7 @@ class FTerm static bool no_half_block_character; static bool cursor_optimisation; static bool xterm_default_colors; + static bool use_alternate_screen; static fc::encoding Encoding; static char exit_message[8192]; @@ -287,6 +306,7 @@ class FTerm // Disable assignment operator (=) FTerm& operator = (const FTerm&); +#if defined(__linux__) // Inquiries static int isConsole(); @@ -298,16 +318,19 @@ class FTerm static void setAttributeMode (uChar); static int setBlinkAsIntensity (bool); static int getFramebuffer_bpp(); +#endif static int openConsole(); static int closeConsole(); static void identifyTermType(); static void storeTTYsettings(); static void restoreTTYsettings(); +#if defined(__linux__) static int getScreenFont(); static int setScreenFont (uChar*, uInt, uInt, uInt, bool = false); static int setUnicodeMap (struct unimapdesc*); static int getUnicodeMap (); static void init_console(); +#endif static uInt getBaudRate (const struct termios*); static char* init_256colorTerminal(); static char* parseAnswerbackMsg (char*&); @@ -406,13 +429,23 @@ inline char* FTerm::getTermName() { return term_name; } //---------------------------------------------------------------------- -inline uInt FTerm::getTabstop() +inline int FTerm::getTabstop() { return FTermcap::tabstop; } //---------------------------------------------------------------------- inline int FTerm::getMaxColor() { return FTermcap::max_color; } +#if DEBUG +//---------------------------------------------------------------------- +inline const FString& FTerm::getAnswerbackString() +{ return *answer_back; } + +//---------------------------------------------------------------------- +inline const FString& FTerm::getSecDAString() +{ return *sec_da; } +#endif + //---------------------------------------------------------------------- inline bool FTerm::isRaw() { return raw_mode; } @@ -533,6 +566,10 @@ inline bool FTerm::unsetRawMode() inline bool FTerm::setCookedMode() { return setRawMode(false); } +//---------------------------------------------------------------------- +inline void FTerm::disableAltScreen() +{ use_alternate_screen = false; } + //---------------------------------------------------------------------- inline bool FTerm::setUTF8() { return setUTF8(true); } diff --git a/src/ftermcap.h b/src/ftermcap.h index 02d9c919..cd8a6375 100644 --- a/src/ftermcap.h +++ b/src/ftermcap.h @@ -38,13 +38,13 @@ class FTermcap { } // Accessor - tcap_map* getTermcapMap() + static tcap_map* getTermcapMap() { return tcap; } // Mutator - void setTermcapMap (tcap_map* t) + static void setTermcapMap (tcap_map* t) { tcap = t; } @@ -58,8 +58,8 @@ class FTermcap static bool osc_support; static bool no_utf8_acs_chars; static int max_color; - static uInt tabstop; - static uInt attr_without_color; + static int tabstop; + static int attr_without_color; private: // Data Members diff --git a/src/ftextview.cpp b/src/ftextview.cpp index c019c9f2..50117a61 100644 --- a/src/ftextview.cpp +++ b/src/ftextview.cpp @@ -670,8 +670,8 @@ void FTextView::draw() if ( hasFocus() && getStatusBar() ) { - const FString msg = getStatusbarMessage(); - const FString curMsg = getStatusBar()->getMessage(); + const FString& msg = getStatusbarMessage(); + const FString& curMsg = getStatusBar()->getMessage(); if ( curMsg != msg ) { diff --git a/src/ftogglebutton.cpp b/src/ftogglebutton.cpp index cd996b8c..f18c27b8 100644 --- a/src/ftogglebutton.cpp +++ b/src/ftogglebutton.cpp @@ -146,8 +146,8 @@ bool FToggleButton::setFocus (bool on) if ( getStatusBar() ) { - const FString msg = getStatusbarMessage(); - const FString curMsg = getStatusBar()->getMessage(); + const FString& msg = getStatusbarMessage(); + const FString& curMsg = getStatusBar()->getMessage(); if ( curMsg != msg ) getStatusBar()->setMessage(msg); @@ -184,7 +184,7 @@ bool FToggleButton::setChecked (bool on) } //---------------------------------------------------------------------- -void FToggleButton::setText (const FString txt) +void FToggleButton::setText (const FString& txt) { text = txt; setWidth(button_width + int(text.getLength())); @@ -456,8 +456,8 @@ void FToggleButton::draw() if ( isFocus && getStatusBar() ) { - const FString msg = getStatusbarMessage(); - const FString curMsg = getStatusBar()->getMessage(); + const FString& msg = getStatusbarMessage(); + const FString& curMsg = getStatusBar()->getMessage(); if ( curMsg != msg ) { diff --git a/src/ftogglebutton.h b/src/ftogglebutton.h index ccf21ea5..3914d5f7 100644 --- a/src/ftogglebutton.h +++ b/src/ftogglebutton.h @@ -73,7 +73,7 @@ class FToggleButton : public FWidget bool setChecked (bool); bool setChecked(); bool unsetChecked(); - virtual void setText (const FString); + virtual void setText (const FString&); // Inquiries bool isChecked(); diff --git a/src/fvterm.cpp b/src/fvterm.cpp index 1e097805..8cdb1ecc 100644 --- a/src/fvterm.cpp +++ b/src/fvterm.cpp @@ -33,8 +33,9 @@ FVTerm::char_data FVTerm::next_attribute; // constructors and destructor //---------------------------------------------------------------------- -FVTerm::FVTerm (FVTerm* parent) +FVTerm::FVTerm (FVTerm* parent, bool disable_alt_screen) : FObject(parent) + , FTerm(disable_alt_screen) , print_area(0) , child_print_area(0) , vwin(0) @@ -304,14 +305,14 @@ int FVTerm::printf (const char* format, ...) buffer = buf; va_start (args, format); - len = std::vsnprintf (buffer, sizeof(buf), format, args); + len = vsnprintf (buffer, sizeof(buf), format, args); va_end (args); if ( len >= int(sizeof(buf)) ) { buffer = new char[len+1](); va_start (args, format); - std::vsnprintf (buffer, uLong(len+1), format, args); + vsnprintf (buffer, uLong(len+1), format, args); va_end (args); } @@ -409,7 +410,7 @@ int FVTerm::print (term_area* area, const FString& s) assert ( ! s.isNull() ); register int len = 0; const wchar_t* p; - uInt tabstop = getTabstop(); + uInt tabstop = uInt(getTabstop()); if ( ! area ) return -1; @@ -2102,7 +2103,10 @@ void FVTerm::finish() // Clear the terminal setNormal(); - clearTerm(); + + if ( use_alternate_screen ) + clearTerm(); + flush_out(); if ( output_buffer ) diff --git a/src/fvterm.h b/src/fvterm.h index d56afac9..3075ebeb 100644 --- a/src/fvterm.h +++ b/src/fvterm.h @@ -126,7 +126,7 @@ class FVTerm : public FObject, public FTerm }; // Constructor - explicit FVTerm (FVTerm* = 0); + explicit FVTerm (FVTerm* = 0, bool = false); // Destructor ~FVTerm(); diff --git a/src/fwidget.cpp b/src/fwidget.cpp index c458f0db..685cb4f1 100644 --- a/src/fwidget.cpp +++ b/src/fwidget.cpp @@ -32,8 +32,8 @@ bool FWidget::hideable; // constructors and destructor //---------------------------------------------------------------------- -FWidget::FWidget (FWidget* parent) - : FVTerm(parent) +FWidget::FWidget (FWidget* parent, bool disable_alt_screen) + : FVTerm(parent, disable_alt_screen) , accelerator_list(0) , flags(0) , callback_objects() @@ -301,7 +301,7 @@ void FWidget::setOpenMenu (FWidget* obj) } //---------------------------------------------------------------------- -void FWidget::setStatusbarMessage (const FString msg) +void FWidget::setStatusbarMessage (const FString& msg) { statusbar_message = msg; } @@ -874,7 +874,7 @@ bool FWidget::close() } //---------------------------------------------------------------------- -void FWidget::addCallback ( const FString cb_signal +void FWidget::addCallback ( const FString& cb_signal , FCallback cb_handler , data_ptr data ) { @@ -884,7 +884,7 @@ void FWidget::addCallback ( const FString cb_signal } //---------------------------------------------------------------------- -void FWidget::addCallback ( const FString cb_signal +void FWidget::addCallback ( const FString& cb_signal , FWidget* cb_instance , FMemberCallback cb_handler , data_ptr data ) @@ -946,7 +946,7 @@ inline void FWidget::delCallbacks() } //---------------------------------------------------------------------- -void FWidget::emitCallback (const FString emit_signal) +void FWidget::emitCallback (const FString& emit_signal) { // member function pointer if ( ! member_callback_objects.empty() ) @@ -1157,9 +1157,11 @@ void FWidget::show() if ( ! init_desktop ) { +#if defined(__linux__) // Important: Do not use setNewFont() or setVGAFont() after // the console character mapping has been initialized init_consoleCharMap(); +#endif // set xterm underline cursor setXTermCursorStyle(fc::blinking_underline); diff --git a/src/fwidget.h b/src/fwidget.h index 39eab583..d6a8fdf4 100644 --- a/src/fwidget.h +++ b/src/fwidget.h @@ -113,7 +113,7 @@ class FWidget : public FVTerm typedef std::vector Accelerators; // Constructor - explicit FWidget (FWidget* = 0); + explicit FWidget (FWidget* = 0, bool = false); // Destructor ~FWidget(); @@ -166,7 +166,7 @@ class FWidget : public FVTerm static void setClickedWidget (FWidget*); static void setMoveSizeWidget (FWidget*); static void setOpenMenu (FWidget*); - virtual void setStatusbarMessage (const FString); + virtual void setStatusbarMessage (const FString&); bool setVisible(); virtual bool setEnable (bool); virtual bool setEnable(); @@ -240,17 +240,17 @@ class FWidget : public FVTerm int numOfFocusableChildren(); virtual bool close(); void clearStatusbarMessage(); - void addCallback ( const FString + void addCallback ( const FString& , FCallback , data_ptr = null ); - void addCallback ( const FString + void addCallback ( const FString& , FWidget* , FMemberCallback , data_ptr = null ); void delCallback (FCallback); void delCallback (FWidget*); void delCallbacks(); - void emitCallback (const FString); + void emitCallback (const FString&); void addAccelerator (int); virtual void addAccelerator (int, FWidget*); void delAccelerator (); diff --git a/test/Makefile.am b/test/Makefile.am index b2a9c069..1186781d 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -11,6 +11,7 @@ noinst_PROGRAMS = \ input-dialog \ choice \ opti-move \ + termcap \ string-operations \ mandelbrot \ calculator \ @@ -35,6 +36,7 @@ mandelbrot_SOURCES = mandelbrot.cpp calculator_SOURCES = calculator.cpp watch_SOURCES = watch.cpp term_attributes_SOURCES = term-attributes.cpp +termcap_SOURCES = termcap.cpp transparent_SOURCES = transparent.cpp keyboard_SOURCES = keyboard.cpp mouse_SOURCES = mouse.cpp diff --git a/test/Makefile.in b/test/Makefile.in index 342d2c4c..8a8236af 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -83,11 +83,12 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ noinst_PROGRAMS = hello$(EXEEXT) dialog$(EXEEXT) input-dialog$(EXEEXT) \ - choice$(EXEEXT) opti-move$(EXEEXT) string-operations$(EXEEXT) \ - mandelbrot$(EXEEXT) calculator$(EXEEXT) watch$(EXEEXT) \ - term-attributes$(EXEEXT) transparent$(EXEEXT) \ - keyboard$(EXEEXT) mouse$(EXEEXT) timer$(EXEEXT) \ - scrollview$(EXEEXT) windows$(EXEEXT) menu$(EXEEXT) ui$(EXEEXT) + choice$(EXEEXT) opti-move$(EXEEXT) termcap$(EXEEXT) \ + string-operations$(EXEEXT) mandelbrot$(EXEEXT) \ + calculator$(EXEEXT) watch$(EXEEXT) term-attributes$(EXEEXT) \ + transparent$(EXEEXT) keyboard$(EXEEXT) mouse$(EXEEXT) \ + timer$(EXEEXT) scrollview$(EXEEXT) windows$(EXEEXT) \ + menu$(EXEEXT) ui$(EXEEXT) subdir = test DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp @@ -146,6 +147,9 @@ string_operations_LDADD = $(LDADD) am_term_attributes_OBJECTS = term-attributes.$(OBJEXT) term_attributes_OBJECTS = $(am_term_attributes_OBJECTS) term_attributes_LDADD = $(LDADD) +am_termcap_OBJECTS = termcap.$(OBJEXT) +termcap_OBJECTS = $(am_termcap_OBJECTS) +termcap_LDADD = $(LDADD) am_timer_OBJECTS = timer.$(OBJEXT) timer_OBJECTS = $(am_timer_OBJECTS) timer_LDADD = $(LDADD) @@ -200,15 +204,15 @@ SOURCES = $(calculator_SOURCES) $(choice_SOURCES) $(dialog_SOURCES) \ $(mandelbrot_SOURCES) $(menu_SOURCES) $(mouse_SOURCES) \ $(opti_move_SOURCES) $(scrollview_SOURCES) \ $(string_operations_SOURCES) $(term_attributes_SOURCES) \ - $(timer_SOURCES) $(transparent_SOURCES) $(ui_SOURCES) \ - $(watch_SOURCES) $(windows_SOURCES) + $(termcap_SOURCES) $(timer_SOURCES) $(transparent_SOURCES) \ + $(ui_SOURCES) $(watch_SOURCES) $(windows_SOURCES) DIST_SOURCES = $(calculator_SOURCES) $(choice_SOURCES) \ $(dialog_SOURCES) $(hello_SOURCES) $(input_dialog_SOURCES) \ $(keyboard_SOURCES) $(mandelbrot_SOURCES) $(menu_SOURCES) \ $(mouse_SOURCES) $(opti_move_SOURCES) $(scrollview_SOURCES) \ $(string_operations_SOURCES) $(term_attributes_SOURCES) \ - $(timer_SOURCES) $(transparent_SOURCES) $(ui_SOURCES) \ - $(watch_SOURCES) $(windows_SOURCES) + $(termcap_SOURCES) $(timer_SOURCES) $(transparent_SOURCES) \ + $(ui_SOURCES) $(watch_SOURCES) $(windows_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -347,6 +351,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -367,6 +372,7 @@ mandelbrot_SOURCES = mandelbrot.cpp calculator_SOURCES = calculator.cpp watch_SOURCES = watch.cpp term_attributes_SOURCES = term-attributes.cpp +termcap_SOURCES = termcap.cpp transparent_SOURCES = transparent.cpp keyboard_SOURCES = keyboard.cpp mouse_SOURCES = mouse.cpp @@ -471,6 +477,10 @@ term-attributes$(EXEEXT): $(term_attributes_OBJECTS) $(term_attributes_DEPENDENC @rm -f term-attributes$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(term_attributes_OBJECTS) $(term_attributes_LDADD) $(LIBS) +termcap$(EXEEXT): $(termcap_OBJECTS) $(termcap_DEPENDENCIES) $(EXTRA_termcap_DEPENDENCIES) + @rm -f termcap$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(termcap_OBJECTS) $(termcap_LDADD) $(LIBS) + timer$(EXEEXT): $(timer_OBJECTS) $(timer_DEPENDENCIES) $(EXTRA_timer_DEPENDENCIES) @rm -f timer$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(timer_OBJECTS) $(timer_LDADD) $(LIBS) @@ -510,6 +520,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scrollview.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string-operations.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/term-attributes.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/termcap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transparent.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ui.Po@am__quote@ diff --git a/test/calculator.cpp b/test/calculator.cpp index e24d0a93..101aff09 100644 --- a/test/calculator.cpp +++ b/test/calculator.cpp @@ -429,7 +429,7 @@ bool Calc::isOperatorKey(int key) void Calc::setDisplay (lDouble d) { char buffer[33]; - std::snprintf (buffer, sizeof(buffer), "%32.11Lg", d); + snprintf (buffer, sizeof(buffer), "%32.11Lg", d); input = buffer; } diff --git a/test/mouse.cpp b/test/mouse.cpp index 3b3f93ba..8638d4d4 100644 --- a/test/mouse.cpp +++ b/test/mouse.cpp @@ -444,8 +444,6 @@ void MouseDraw::drawBrush (int x, int y, bool swap_color) void MouseDraw::drawCanvas() { int ax, ay, y_end, x_end; - char_data* cc; // canvas character - char_data* wc; // window character if ( ! hasPrintArea() ) FVTerm::getPrintArea(); @@ -461,6 +459,8 @@ void MouseDraw::drawCanvas() for (int y=0; y < y_end; y++) // line loop { + char_data* cc; // canvas character + char_data* wc; // window character cc = &canvas->text[y * x_end]; wc = &print_area->text[(ay+y) * w_line_len + ax]; std::memcpy (wc, cc, sizeof(char_data) * unsigned(x_end)); diff --git a/test/termcap.cpp b/test/termcap.cpp new file mode 100644 index 00000000..e43ddee6 --- /dev/null +++ b/test/termcap.cpp @@ -0,0 +1,207 @@ +// File: opti-move.cpp + +#include +#include "fapp.h" +#include "ftermcap.h" +#include "fvterm.h" + + +// global FVTerm object +static FVTerm* terminal; + +// function prototype +void tcapBooleans (std::string, bool); +void tcapNumeric (std::string, int); +void termcapString (std::string, char*); + + +//---------------------------------------------------------------------- +// functions +//---------------------------------------------------------------------- +void tcapBooleans (std::string name, bool cap_bool) +{ + std::cout << "FTermcap::" << name << ": "; + + if ( cap_bool ) + std::cout << "true\r\n"; + else + std::cout << "false\r\n"; +} + +//---------------------------------------------------------------------- +void tcapNumeric (std::string name, int cap_num) +{ + std::cout << "FTermcap::" << name << ": " << cap_num << "\r\n"; +} + +//---------------------------------------------------------------------- +void tcapString (std::string name, const char* cap_str) +{ + uInt len; + std::string sequence; + std::cout << name << ": "; + + if ( cap_str == 0 ) + { + std::cout << "\r\n"; + return; + } + + len = uInt(std::strlen(cap_str)); + + for (uInt i=0; i < len; i++) + { + if ( cap_str[i] < 32 ) + { + if ( cap_str[i] == 27 ) + sequence += "\\E"; + else + { + sequence += '^'; + sequence += cap_str[i] + 64; + } + } + else + sequence += cap_str[i]; + } + + std::cout << sequence << " "; + std::cout << "\r\n"; +} + + +//---------------------------------------------------------------------- +// main part +//---------------------------------------------------------------------- +int main (int argc, char* argv[]) +{ + bool disable_alt_screen = true; + FApplication app (argc, argv, disable_alt_screen); + terminal = new FVTerm(&app); + + FTermcap::tcap_map* tcap = 0; + tcap = FTermcap::getTermcapMap(); + + std::cout << "--------\r\nFTermcap\r\n--------\r\n\n"; + std::cout << "Terminal: " << terminal->getTermType() << "\r\n"; + +#if DEBUG + std::cout << "\n.------------------- debug -------------------\r\n"; + std::cout << "| after init_256colorTerminal(): " + << terminal->termtype_256color << "\r\n"; + std::cout << "| after parseAnswerbackMsg(): " + << terminal->termtype_Answerback << "\r\n"; + std::cout << "| after parseSecDA(): " + << terminal->termtype_SecDA << "\r\n"; + tcapString ( "| The answerback String" + , terminal->getAnswerbackString().c_str() ); + tcapString ( "| The SecDA String" + , terminal->getSecDAString().c_str() ); + std::cout << "'------------------- debug -------------------\r\n"; +#endif + + std::cout << "\r\n[Booleans]\r\n"; + tcapBooleans ( "background_color_erase" + , FTermcap::background_color_erase ); + tcapBooleans ( "automatic_left_margin" + , FTermcap::automatic_left_margin ); + tcapBooleans ( "automatic_right_margin" + , FTermcap::automatic_right_margin ); + tcapBooleans ( "eat_nl_glitch" + , FTermcap::eat_nl_glitch ); + tcapBooleans ( "ansi_default_color" + , FTermcap::ansi_default_color ); + tcapBooleans ( "osc_support" + , FTermcap::osc_support ); + tcapBooleans ( "no_utf8_acs_chars" + , FTermcap::no_utf8_acs_chars ); + + std::cout << "\r\n[Numeric]\r\n"; + tcapNumeric ("max_color", FTermcap::max_color); + tcapNumeric ("tabstop", FTermcap::tabstop); + tcapNumeric ("attr_without_color", FTermcap::attr_without_color); + + std::cout << "\r\n[String]\r\n"; + tcapString ("t_bell", tcap[fc::t_bell].string); + tcapString ("t_erase_chars", tcap[fc::t_erase_chars].string); + tcapString ("t_clear_screen", tcap[fc::t_clear_screen].string); + tcapString ("t_clr_eos", tcap[fc::t_clr_eos].string); + tcapString ("t_clr_eol", tcap[fc::t_clr_eol].string); + tcapString ("t_clr_bol", tcap[fc::t_clr_bol].string); + tcapString ("t_cursor_home", tcap[fc::t_cursor_home].string); + tcapString ("t_cursor_to_ll", tcap[fc::t_cursor_to_ll].string); + tcapString ("t_carriage_return", tcap[fc::t_carriage_return].string); + tcapString ("t_tab", tcap[fc::t_tab].string); + tcapString ("t_back_tab", tcap[fc::t_back_tab].string); + tcapString ("t_insert_padding", tcap[fc::t_insert_padding].string); + tcapString ("t_insert_character", tcap[fc::t_insert_character].string); + tcapString ("t_parm_ich", tcap[fc::t_parm_ich].string); + tcapString ("t_repeat_char", tcap[fc::t_repeat_char].string); + tcapString ("t_initialize_color", tcap[fc::t_initialize_color].string); + tcapString ("t_initialize_pair", tcap[fc::t_initialize_pair].string); + tcapString ("t_set_a_foreground", tcap[fc::t_set_a_foreground].string); + tcapString ("t_set_a_background", tcap[fc::t_set_a_background].string); + tcapString ("t_set_foreground", tcap[fc::t_set_foreground].string); + tcapString ("t_set_background", tcap[fc::t_set_background].string); + tcapString ("t_set_color_pair", tcap[fc::t_set_color_pair].string); + tcapString ("t_orig_pair", tcap[fc::t_orig_pair].string); + tcapString ("t_orig_colors", tcap[fc::t_orig_colors].string); + tcapString ("t_no_color_video", tcap[fc::t_no_color_video].string); + tcapString ("t_cursor_address", tcap[fc::t_cursor_address].string); + tcapString ("t_column_address", tcap[fc::t_column_address].string); + tcapString ("t_row_address", tcap[fc::t_row_address].string); + tcapString ("t_cursor_visible", tcap[fc::t_cursor_visible].string); + tcapString ("t_cursor_invisible", tcap[fc::t_cursor_invisible].string); + tcapString ("t_cursor_normal", tcap[fc::t_cursor_normal].string); + tcapString ("t_cursor_up", tcap[fc::t_cursor_up].string); + tcapString ("t_cursor_down", tcap[fc::t_cursor_down].string); + tcapString ("t_cursor_left", tcap[fc::t_cursor_left].string); + tcapString ("t_cursor_right", tcap[fc::t_cursor_right].string); + tcapString ("t_parm_up_cursor", tcap[fc::t_parm_up_cursor].string); + tcapString ("t_parm_down_cursor", tcap[fc::t_parm_down_cursor].string); + tcapString ("t_parm_left_cursor", tcap[fc::t_parm_left_cursor].string); + tcapString ("t_parm_right_cursor", tcap[fc::t_parm_right_cursor].string); + tcapString ("t_save_cursor", tcap[fc::t_save_cursor].string); + tcapString ("t_restore_cursor", tcap[fc::t_restore_cursor].string); + tcapString ("t_scroll_forward", tcap[fc::t_scroll_forward].string); + tcapString ("t_scroll_reverse", tcap[fc::t_scroll_reverse].string); + tcapString ("t_enter_ca_mode", tcap[fc::t_enter_ca_mode].string); + tcapString ("t_exit_ca_mode", tcap[fc::t_exit_ca_mode].string); + tcapString ("t_enable_acs", tcap[fc::t_enable_acs].string); + tcapString ("t_enter_bold_mode", tcap[fc::t_enter_bold_mode].string); + tcapString ("t_exit_bold_mode", tcap[fc::t_exit_bold_mode].string); + tcapString ("t_enter_dim_mode", tcap[fc::t_enter_dim_mode].string); + tcapString ("t_exit_dim_mode", tcap[fc::t_exit_dim_mode].string); + tcapString ("t_enter_italics_mode", tcap[fc::t_enter_italics_mode].string); + tcapString ("t_exit_italics_mode", tcap[fc::t_exit_italics_mode].string); + tcapString ("t_enter_underline_mode", tcap[fc::t_enter_underline_mode].string); + tcapString ("t_exit_underline_mode", tcap[fc::t_exit_underline_mode].string); + tcapString ("t_enter_blink_mode", tcap[fc::t_enter_blink_mode].string); + tcapString ("t_exit_blink_mode", tcap[fc::t_exit_blink_mode].string); + tcapString ("t_enter_reverse_mode", tcap[fc::t_enter_reverse_mode].string); + tcapString ("t_exit_reverse_mode", tcap[fc::t_exit_reverse_mode].string); + tcapString ("t_enter_standout_mode", tcap[fc::t_enter_standout_mode].string); + tcapString ("t_exit_standout_mode", tcap[fc::t_exit_standout_mode].string); + tcapString ("t_enter_secure_mode", tcap[fc::t_enter_secure_mode].string); + tcapString ("t_exit_secure_mode", tcap[fc::t_exit_secure_mode].string); + tcapString ("t_enter_protected_mode", tcap[fc::t_enter_protected_mode].string); + tcapString ("t_exit_protected_mode", tcap[fc::t_exit_protected_mode].string); + tcapString ("t_enter_crossed_out_mode", tcap[fc::t_enter_crossed_out_mode].string); + tcapString ("t_exit_crossed_out_mode", tcap[fc::t_exit_crossed_out_mode].string); + tcapString ("t_enter_dbl_underline_mode", tcap[fc::t_enter_dbl_underline_mode].string); + tcapString ("t_exit_dbl_underline_mode", tcap[fc::t_exit_dbl_underline_mode].string); + tcapString ("t_set_attributes", tcap[fc::t_set_attributes].string); + tcapString ("t_exit_attribute_mode", tcap[fc::t_exit_attribute_mode].string); + tcapString ("t_enter_alt_charset_mode", tcap[fc::t_enter_alt_charset_mode].string); + tcapString ("t_exit_alt_charset_mode", tcap[fc::t_exit_alt_charset_mode].string); + tcapString ("t_enter_pc_charset_mode", tcap[fc::t_enter_pc_charset_mode].string); + tcapString ("t_exit_pc_charset_mode", tcap[fc::t_exit_pc_charset_mode].string); + tcapString ("t_enter_insert_mode", tcap[fc::t_enter_insert_mode].string); + tcapString ("t_exit_insert_mode", tcap[fc::t_exit_insert_mode].string); + tcapString ("t_enter_am_mode", tcap[fc::t_enter_am_mode].string); + tcapString ("t_exit_am_mode", tcap[fc::t_exit_am_mode].string); + tcapString ("t_acs_chars", tcap[fc::t_acs_chars].string); + tcapString ("t_keypad_xmit", tcap[fc::t_keypad_xmit].string); + tcapString ("t_keypad_local", tcap[fc::t_keypad_local].string); + tcapString ("t_key_mouse", tcap[fc::t_key_mouse].string); +}