diff --git a/ChangeLog b/ChangeLog index 5c8d7572..e9fcfd58 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2016-12-11 Markus Gans + * Accelerates text line drawing by clear with CSI sequences + to begin or to end of the current line. + 2016-11-29 Markus Gans * Restore the xterm window title and font only if it could be read before diff --git a/logo/svg/finalcut-logo.svg b/logo/svg/finalcut-logo.svg index 5ee94276..e6b6ab90 100755 --- a/logo/svg/finalcut-logo.svg +++ b/logo/svg/finalcut-logo.svg @@ -32,9 +32,9 @@ inkscape:window-height="1116" id="namedview28" showgrid="false" - inkscape:zoom="1.3630812" - inkscape:cx="431.06797" - inkscape:cy="137.50611" + inkscape:zoom="1.2" + inkscape:cx="341.2437" + inkscape:cy="2.4584348" inkscape:window-x="0" inkscape:window-y="27" inkscape:window-maximized="1" @@ -289,7 +289,7 @@ style="fill:url(#linearGradient3792);fill-opacity:1;stroke:#000000;stroke-width:0.70560002;stroke-opacity:1" inkscape:connector-curvature="0" />The Final Cut \ No newline at end of file diff --git a/src/fenum.h b/src/fenum.h index 285371e5..85f872a9 100644 --- a/src/fenum.h +++ b/src/fenum.h @@ -974,6 +974,7 @@ class fc t_clear_screen, t_clr_eos, t_clr_eol, + t_clr_bol, t_cursor_home, t_cursor_to_ll, t_carriage_return, diff --git a/src/fmenubar.cpp b/src/fmenubar.cpp index d023cf4c..ef9dade8 100644 --- a/src/fmenubar.cpp +++ b/src/fmenubar.cpp @@ -540,6 +540,7 @@ bool FMenuBar::selectNextItem() if ( next == *iter ) return false; + updateTerminal(false); unselectItem(); next->setSelected(); setSelectedItem(next); @@ -563,6 +564,7 @@ bool FMenuBar::selectNextItem() getStatusBar()->drawMessage(); redraw(); + updateTerminal(true); break; } @@ -605,6 +607,7 @@ bool FMenuBar::selectPrevItem() if ( prev == *iter ) return false; + updateTerminal(false); unselectItem(); prev->setSelected(); prev->setFocus(); @@ -628,6 +631,7 @@ bool FMenuBar::selectPrevItem() setSelectedItem(prev); redraw(); + updateTerminal(true); break; } } diff --git a/src/foptimove.cpp b/src/foptimove.cpp index 16e690b2..f616a794 100644 --- a/src/foptimove.cpp +++ b/src/foptimove.cpp @@ -27,6 +27,8 @@ FOptiMove::FOptiMove (int baud) , F_parm_down_cursor() , F_parm_left_cursor() , F_parm_right_cursor() + , F_clr_bol() + , F_clr_eol() , automatic_left_margin(false) , eat_nl_glitch(false) , char_duration(1) @@ -72,186 +74,280 @@ void FOptiMove::setTermSize (int w, int h) } //---------------------------------------------------------------------- -void FOptiMove::set_cursor_home (char*& cap) +int FOptiMove::set_cursor_home (char*& cap) { if ( cap ) { F_cursor_home.cap = cap; F_cursor_home.duration = capDuration (cap, 0); - F_cursor_home.length = int(std::strlen(cap)); + F_cursor_home.length = capDurationToLength (F_cursor_home.duration); } + else + F_cursor_home.duration = LONG_DURATION; + + return F_cursor_home.length; } //---------------------------------------------------------------------- -void FOptiMove::set_cursor_to_ll (char*& cap) +int FOptiMove::set_cursor_to_ll (char*& cap) { if ( cap ) { F_cursor_to_ll.cap = cap; F_cursor_to_ll.duration = capDuration (cap, 0); - F_cursor_to_ll.length = int(std::strlen(cap)); + F_cursor_to_ll.length = capDurationToLength (F_cursor_to_ll.duration); } + else + F_cursor_to_ll.duration = LONG_DURATION; + + return F_cursor_to_ll.length; } //---------------------------------------------------------------------- -void FOptiMove::set_carriage_return (char*& cap) +int FOptiMove::set_carriage_return (char*& cap) { if ( cap ) { F_carriage_return.cap = cap; F_carriage_return.duration = capDuration (cap, 0); - F_carriage_return.length = int(std::strlen(cap)); + F_carriage_return.length = capDurationToLength (F_carriage_return.duration); } + else + F_carriage_return.duration = LONG_DURATION; + + return F_carriage_return.length; } //---------------------------------------------------------------------- -void FOptiMove::set_tabular (char*& cap) +int FOptiMove::set_tabular (char*& cap) { if ( cap ) { F_tab.cap = cap; F_tab.duration = capDuration (cap, 0); - F_tab.length = int(std::strlen(cap)); + F_tab.length = capDurationToLength (F_tab.duration); } + else + F_tab.duration = LONG_DURATION; + + return F_tab.length; } //---------------------------------------------------------------------- -void FOptiMove::set_back_tab (char*& cap) +int FOptiMove::set_back_tab (char*& cap) { if ( cap ) { F_back_tab.cap = cap; F_back_tab.duration = capDuration (cap, 0); - F_back_tab.length = int(std::strlen(cap)); + F_back_tab.length = capDurationToLength (F_back_tab.duration); } + else + F_back_tab.duration = LONG_DURATION; + + return F_back_tab.length; } //---------------------------------------------------------------------- -void FOptiMove::set_cursor_up (char*& cap) +int FOptiMove::set_cursor_up (char*& cap) { if ( cap ) { F_cursor_up.cap = cap; F_cursor_up.duration = capDuration (cap, 0); - F_cursor_up.length = int(std::strlen(cap)); + F_cursor_up.length = capDurationToLength (F_cursor_up.duration); } + else + F_cursor_up.duration = LONG_DURATION; + + return F_cursor_up.length; } //---------------------------------------------------------------------- -void FOptiMove::set_cursor_down (char*& cap) +int FOptiMove::set_cursor_down (char*& cap) { if ( cap ) { F_cursor_down.cap = cap; F_cursor_down.duration = capDuration (cap, 0); - F_cursor_down.length = int(std::strlen(cap)); + F_cursor_down.length = capDurationToLength (F_cursor_down.duration); } + else + F_cursor_down.duration = LONG_DURATION; + + return F_cursor_down.length; } //---------------------------------------------------------------------- -void FOptiMove::set_cursor_left (char*& cap) +int FOptiMove::set_cursor_left (char*& cap) { if ( cap ) { F_cursor_left.cap = cap; F_cursor_left.duration = capDuration (cap, 0); - F_cursor_left.length = int(std::strlen(cap)); + F_cursor_left.length = capDurationToLength (F_cursor_left.duration); } + else + F_cursor_left.duration = LONG_DURATION; + + return F_cursor_left.length; } //---------------------------------------------------------------------- -void FOptiMove::set_cursor_right (char*& cap) +int FOptiMove::set_cursor_right (char*& cap) { if ( cap ) { F_cursor_right.cap = cap; F_cursor_right.duration = capDuration (cap, 0); - F_cursor_right.length = int(std::strlen(cap)); + F_cursor_right.length = capDurationToLength (F_cursor_right.duration); } + else + F_cursor_right.duration = LONG_DURATION; + + return F_cursor_right.length; } //---------------------------------------------------------------------- -void FOptiMove::set_cursor_address (char*& cap) +int FOptiMove::set_cursor_address (char*& cap) { if ( cap ) { char* temp = tgoto(cap, 23, 23); F_cursor_address.cap = cap; F_cursor_address.duration = capDuration (temp, 1); - F_cursor_address.length = int(std::strlen(cap)); + F_cursor_address.length = capDurationToLength (F_cursor_address.duration); } + else + F_cursor_address.duration = LONG_DURATION; + + return F_cursor_address.length; } //---------------------------------------------------------------------- -void FOptiMove::set_column_address (char*& cap) +int FOptiMove::set_column_address (char*& cap) { if ( cap ) { char* temp = tparm(cap, 23); F_column_address.cap = cap; F_column_address.duration = capDuration (temp, 1); - F_column_address.length = int(std::strlen(cap)); + F_column_address.length = capDurationToLength (F_column_address.duration); } + else + F_column_address.duration = LONG_DURATION; + + return F_column_address.length; } //---------------------------------------------------------------------- -void FOptiMove::set_row_address (char*& cap) +int FOptiMove::set_row_address (char*& cap) { if ( cap ) { char* temp = tparm(cap, 23); F_row_address.cap = cap; F_row_address.duration = capDuration (temp, 1); - F_row_address.length = int(std::strlen(cap)); + F_row_address.length = capDurationToLength (F_row_address.duration); } + else + F_row_address.duration = LONG_DURATION; + + return F_row_address.length; } //---------------------------------------------------------------------- -void FOptiMove::set_parm_up_cursor (char*& cap) +int FOptiMove::set_parm_up_cursor (char*& cap) { if ( cap ) { char* temp = tparm(cap, 23); F_parm_up_cursor.cap = cap; F_parm_up_cursor.duration = capDuration (temp, 1); - F_parm_up_cursor.length = int(std::strlen(cap)); + F_parm_up_cursor.length = capDurationToLength (F_parm_up_cursor.duration); } + else + F_parm_up_cursor.duration = LONG_DURATION; + + return F_parm_up_cursor.length; } //---------------------------------------------------------------------- -void FOptiMove::set_parm_down_cursor (char*& cap) +int FOptiMove::set_parm_down_cursor (char*& cap) { if ( cap ) { char* temp = tparm(cap, 23); F_parm_down_cursor.cap = cap; F_parm_down_cursor.duration = capDuration (temp, 1); - F_parm_down_cursor.length = int(std::strlen(cap)); + F_parm_down_cursor.length = capDurationToLength (F_parm_down_cursor.duration); } + else + F_parm_down_cursor.duration = LONG_DURATION; + + return F_parm_down_cursor.length; } //---------------------------------------------------------------------- -void FOptiMove::set_parm_left_cursor (char*& cap) +int FOptiMove::set_parm_left_cursor (char*& cap) { if ( cap ) { char* temp = tparm(cap, 23); F_parm_left_cursor.cap = cap; F_parm_left_cursor.duration = capDuration (temp, 1); - F_parm_left_cursor.length = int(std::strlen(cap)); + F_parm_left_cursor.length = capDurationToLength (F_parm_left_cursor.duration); } + else + F_parm_left_cursor.duration = LONG_DURATION; + + return F_parm_left_cursor.length; } //---------------------------------------------------------------------- -void FOptiMove::set_parm_right_cursor (char*& cap) +int FOptiMove::set_parm_right_cursor (char*& cap) { if ( cap ) { char* temp = tparm(cap, 23); F_parm_right_cursor.cap = cap; F_parm_right_cursor.duration = capDuration (temp, 1); - F_parm_right_cursor.length = int(std::strlen(cap)); + F_parm_right_cursor.length = capDurationToLength (F_parm_right_cursor.duration); } + else + F_parm_right_cursor.duration = LONG_DURATION; + + return F_parm_right_cursor.length; +} + +//---------------------------------------------------------------------- +int FOptiMove::set_clr_bol (char*& cap) +{ + if ( cap ) + { + F_clr_bol.cap = cap; + F_clr_bol.duration = capDuration (cap, 0); + F_clr_bol.length = capDurationToLength (F_clr_bol.duration); + } + else + F_clr_bol.duration = LONG_DURATION; + + return F_clr_bol.length; +} + +//---------------------------------------------------------------------- +int FOptiMove::set_clr_eol (char*& cap) +{ + if ( cap ) + { + F_clr_eol.cap = cap; + F_clr_eol.duration = capDuration (cap, 0); + F_clr_eol.length = capDurationToLength (F_clr_eol.duration); + } + else + F_clr_eol.duration = LONG_DURATION; + + return F_clr_eol.length; } //---------------------------------------------------------------------- @@ -487,6 +583,15 @@ int FOptiMove::capDuration (char*& cap, int affcnt) return int(ms); } +//---------------------------------------------------------------------- +int FOptiMove::capDurationToLength (int duration) +{ + if ( duration != LONG_DURATION ) + return (duration + char_duration - 1) / char_duration; + else + return LONG_DURATION; +} + //---------------------------------------------------------------------- int FOptiMove::repeatedAppend (capability& o, int count, char* dst) { diff --git a/src/foptimove.h b/src/foptimove.h index 16d75c3f..2f78b789 100644 --- a/src/foptimove.h +++ b/src/foptimove.h @@ -18,6 +18,7 @@ #include // need for tparm #include +#include #include // need for printf #include #include @@ -43,22 +44,24 @@ class FOptiMove void setBaudRate (int); void setTabStop (int); void setTermSize (int, int); - void set_cursor_home (char*&); - void set_cursor_to_ll (char*&); - void set_carriage_return (char*&); - void set_tabular (char*&); - void set_back_tab (char*&); - void set_cursor_up (char*&); - void set_cursor_down (char*&); - void set_cursor_left (char*&); - void set_cursor_right (char*&); - void set_cursor_address (char*&); - void set_column_address (char*&); - void set_row_address (char*&); - void set_parm_up_cursor (char*&); - void set_parm_down_cursor (char*&); - void set_parm_left_cursor (char*&); - void set_parm_right_cursor (char*&); + int set_cursor_home (char*&); + int set_cursor_to_ll (char*&); + int set_carriage_return (char*&); + int set_tabular (char*&); + int set_back_tab (char*&); + int set_cursor_up (char*&); + int set_cursor_down (char*&); + int set_cursor_left (char*&); + int set_cursor_right (char*&); + int set_cursor_address (char*&); + int set_column_address (char*&); + int set_row_address (char*&); + int set_parm_up_cursor (char*&); + int set_parm_down_cursor (char*&); + int set_parm_left_cursor (char*&); + int set_parm_right_cursor (char*&); + int set_clr_bol (char*&); + int set_clr_eol (char*&); void set_auto_left_margin (bool&); void set_eat_newline_glitch (bool&); @@ -79,7 +82,7 @@ class FOptiMove } capability; // Constants - static const int LONG_DURATION = 9999999; + static const int LONG_DURATION = INT_MAX; // value for a long capability waiting time static const int MOVE_LIMIT = 7; // maximum character distance to avoid direct cursor addressing @@ -87,9 +90,9 @@ class FOptiMove // Methods void calculateCharDuration(); int capDuration (char*&, int); + int capDurationToLength (int); int repeatedAppend (capability&, int, char*); int relativeMove (char*&, int, int, int, int); - bool isTwoDirectionMove (int, int, int, int); bool isWideMove (int, int, int, int); // Data Members @@ -109,6 +112,8 @@ class FOptiMove capability F_parm_down_cursor; capability F_parm_left_cursor; capability F_parm_right_cursor; + capability F_clr_bol; + capability F_clr_eol; bool automatic_left_margin; bool eat_nl_glitch; diff --git a/src/ftcap_map.h b/src/ftcap_map.h index c53a0834..d8811ddb 100644 --- a/src/ftcap_map.h +++ b/src/ftcap_map.h @@ -15,6 +15,7 @@ static FTermcap::tcap_map term_caps[] = { 0, "cl" }, // clear_screen -> clear screen and home cursor (P*) { 0, "cd" }, // clr_eos -> clear to end of screen (P*) { 0, "ce" }, // clr_eol -> clear to end of line (P) + { 0, "cb" }, // clr_bol -> Clear to beginning of line { 0, "ho" }, // cursor_home -> home cursor (if no cup) { 0, "ll" }, // cursor_to_ll -> last line, first column (if no cup) { 0, "cr" }, // carriage_return -> carriage return (P*) diff --git a/src/fterm.cpp b/src/fterm.cpp index 8ab3dd9b..cb519a0c 100644 --- a/src/fterm.cpp +++ b/src/fterm.cpp @@ -24,6 +24,8 @@ int FTerm::stdin_no; int FTerm::stdout_no; int FTerm::fd_tty; int FTerm::stdin_status_flags; +int FTerm::clr_bol_length; +int FTerm::clr_eol_length; uInt FTerm::baudrate; bool FTerm::resize_term; bool FTerm::mouse_support; @@ -2660,6 +2662,10 @@ void FTerm::init_termcaps() 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 ) { @@ -2908,6 +2914,8 @@ void FTerm::init_termcaps() opti_move->set_parm_right_cursor (tcap[fc::t_parm_right_cursor].string); opti_move->set_auto_left_margin (FTermcap::automatic_left_margin); opti_move->set_eat_newline_glitch (FTermcap::eat_nl_glitch); + clr_bol_length = opti_move->set_clr_bol (tcap[fc::t_clr_bol].string); + clr_eol_length = opti_move->set_clr_eol (tcap[fc::t_clr_eol].string); // attribute settings opti_attr->setNoColorVideo (int(FTermcap::attr_without_color)); diff --git a/src/fterm.h b/src/fterm.h index 4e181f31..0f21b162 100644 --- a/src/fterm.h +++ b/src/fterm.h @@ -254,6 +254,8 @@ class FTerm // Data Members static int stdin_no; static int stdout_no; + static int clr_bol_length; + static int clr_eol_length; static bool NewFont; static bool VGAFont; static bool no_shadow_character; diff --git a/src/fvterm.cpp b/src/fvterm.cpp index 5cd53989..336ff163 100644 --- a/src/fvterm.cpp +++ b/src/fvterm.cpp @@ -124,19 +124,14 @@ void FVTerm::clearTerm (int fillchar) if ( ! ( (cl || cd || cb) && (normal || ut) ) || fillchar != ' ' ) { - int term_width = getColumnNumber(); - - for (int i=0; i < getLineNumber(); i++) + for (int i=0; i < vdesktop->height; i++) { - setTermXY (0,i); - next->code = fillchar; - - for (int n=0; n < term_width; n++) - appendCharacter(next); - - term_pos->setPoint(term_width+1, i); + vdesktop->changes[i].xmin = 0; + vdesktop->changes[i].xmax = vdesktop->width - 1; + vdesktop->changes[i].trans_count = 0; } + updateVTerm (vdesktop); setTermXY (0,0); } else if ( cl ) @@ -267,8 +262,6 @@ void FVTerm::updateTerminal (bool on) void FVTerm::updateTerminal() { // Updates pending changes to the terminal - term_area* vt; - int term_width, term_height; if ( stop_terminal_updates || static_cast(init_object)->isQuit() ) @@ -286,22 +279,116 @@ void FVTerm::updateTerminal() } } - vt = vterm; - term_width = vt->width - 1; - term_height = vt->height - 1; + for (register uInt y=0; y < uInt(vterm->height); y++) + updateTerminalLine (y); - for (register uInt y=0; y < uInt(vt->height); y++) + // sets the new input cursor position + updateTerminalCursor(); +} + +//---------------------------------------------------------------------- +void FVTerm::updateTerminalLine (uInt y) +{ + term_area* vt = vterm; + uInt& xmin = vt->changes[y].xmin; + uInt& xmax = vt->changes[y].xmax; + int term_width = vt->width - 1; + int term_height = vt->height - 1; + + if ( xmin <= xmax ) { - uInt change_xmax = vt->changes[y].xmax; + bool is_eol_clean = false; + bool draw_leading_ws = false; + bool draw_tailing_ws = false; + char*& ce = tcap[fc::t_clr_eol].string; + char*& cb = tcap[fc::t_clr_bol].string; + bool ut = FTermcap::background_color_erase; + char_data* first_char = &vt->text[y * uInt(vt->width)]; + char_data* last_char = &vt->text[(y+1) * uInt(vt->width) - 1]; + char_data* min_char = &vt->text[y * uInt(vt->width) + xmin]; - if ( vt->changes[y].xmin <= vt->changes[y].xmax ) + // Is the line from xmin to the end of the line blank? + if ( min_char->code == ' ' ) { - uInt change_xmin = vt->changes[y].xmin; - setTermXY (int(change_xmin), int(y)); + uInt beginning_whitespace = 1; + bool normal = isNormal(min_char); - for ( register uInt x=change_xmin; - x <= change_xmax; - x++ ) + for (register uInt x=xmin+1; x < uInt(vt->width); x++) + { + if ( *min_char == vt->text[y * uInt(vt->width) + x] ) + beginning_whitespace++; + else + break; + } + + if ( beginning_whitespace == uInt(vt->width) - xmin + && ce && (ut || normal) + && clr_eol_length < int(beginning_whitespace) ) + is_eol_clean = true; + } + + // leading whitespace + if ( ! is_eol_clean && first_char->code == ' ' ) + { + uInt leading_whitespace = 1; + bool normal = isNormal(first_char); + + for (register uInt x=1; x < uInt(vt->width); x++) + { + if ( *first_char == vt->text[y * uInt(vt->width) + x] ) + leading_whitespace++; + else + break; + } + + if ( leading_whitespace > xmin + && cb && (ut || normal) + && clr_bol_length < int(leading_whitespace) ) + { + draw_leading_ws = true; + xmin = leading_whitespace - 1; + } + } + + // tailing whitespace + if ( ! is_eol_clean && last_char->code == ' ' ) + { + uInt tailing_whitespace = 1; + bool normal = isNormal(last_char); + + for (register uInt x=uInt(vt->width)-1; x > 0 ; x--) + { + if ( *last_char == vt->text[y * uInt(vt->width) + x] ) + tailing_whitespace++; + else + break; + } + + if ( tailing_whitespace > uInt(vt->width) - xmax + && ce && (ut || normal) + && clr_bol_length < int(tailing_whitespace) ) + { + draw_tailing_ws = true; + xmax = uInt(vt->width) - tailing_whitespace; + } + } + + setTermXY (int(xmin), int(y)); + + if ( is_eol_clean ) + { + appendAttributes (min_char); + appendOutputBuffer (ce); + } + else + { + if ( draw_leading_ws ) + { + appendAttributes (first_char); + appendOutputBuffer (cb); + } + + for (register uInt x=xmin; x <= xmax; x++) { char_data* print_char; print_char = &vt->text[y * uInt(vt->width) + x]; @@ -315,34 +402,38 @@ void FVTerm::updateTerminal() term_pos->x_ref()++; } - vt->changes[y].xmin = uInt(vt->width); - vt->changes[y].xmax = 0; - } - - // cursor wrap - if ( term_pos->getX() > term_width ) - { - if ( term_pos->getY() == term_height ) - term_pos->x_ref()--; - else + if ( draw_tailing_ws ) { - if ( FTermcap::eat_nl_glitch ) - { - term_pos->setPoint(-1,-1); - } - else if ( FTermcap::automatic_right_margin ) - { - term_pos->setX(0); - term_pos->y_ref()++; - } - else - term_pos->x_ref()--; + appendAttributes (last_char); + appendOutputBuffer (ce); } } + + // Reset line changes + xmin = uInt(vt->width); + xmax = 0; } - // sets the new input cursor position - updateTerminalCursor(); + // cursor wrap + if ( term_pos->getX() > term_width ) + { + if ( term_pos->getY() == term_height ) + term_pos->x_ref()--; + else + { + if ( FTermcap::eat_nl_glitch ) + { + term_pos->setPoint(-1,-1); + } + else if ( FTermcap::automatic_right_margin ) + { + term_pos->setX(0); + term_pos->y_ref()++; + } + else + term_pos->x_ref()--; + } + } } //---------------------------------------------------------------------- @@ -1338,7 +1429,6 @@ void FVTerm::updateVTerm (term_area* area) int ax, ay, aw, ah, rsh, bsh, y_end, ol; char_data* tc; // terminal character char_data* ac; // area character - bool modified = false; if ( ! vterm_updates ) { @@ -1379,6 +1469,7 @@ void FVTerm::updateVTerm (term_area* area) if ( line_xmin <= line_xmax ) { int _xmin, _xmax; + bool modified = false; if ( ax == 0 ) line_xmin = ol; @@ -1403,6 +1494,7 @@ void FVTerm::updateVTerm (term_area* area) line_len = aw + rsh; ac = &area->text[y * line_len + x]; tc = &vterm->text[gy * vterm->width + gx - ol]; + is_covered = isCovered(gx-ol, gy, area); // get covered state if ( is_covered != fully_covered ) diff --git a/src/fvterm.h b/src/fvterm.h index d35488f9..a2746f4a 100644 --- a/src/fvterm.h +++ b/src/fvterm.h @@ -192,6 +192,7 @@ class FVTerm : public FObject, public FTerm static void putVTerm(); static void updateTerminal (bool); static void updateTerminal(); + static void updateTerminalLine (uInt); static bool updateTerminalCursor(); static void processTerminalUpdate(); static bool isInsideTerminal (int, int);