@ -235,6 +235,13 @@ void append_out(const char *text, int len, int attr);
void draw_input ( void ) ;
void send_trace_options ( void ) ;
void tcp_disconnect ( void ) ;
static int session_count ( void ) ;
static int session_index ( void ) ;
static void session_switch ( int n ) ;
static void session_next ( void ) ;
static void session_prev ( void ) ;
static void session_new ( void ) ;
static void do_connect ( int idx ) ;
/* ═══════════════════════════════════════════════════════════
* Config
@ -828,14 +835,18 @@ void draw_status(void)
/* Left: program name */
mvwprintw ( status_win , 0 , 1 , " TermTCP %s " , VERSION ) ;
/* Center: connection info */
/* Center: session indicator + connection info */
char center [ 80 ] ;
int nsess = session_count ( ) ;
char sess_tag [ 16 ] = " " ;
if ( nsess > 1 )
snprintf ( sess_tag , sizeof ( sess_tag ) , " [%d/%d] " , session_index ( ) + 1 , nsess ) ;
if ( S - > connected & & S - > host_idx > = 0 ) {
int elapsed = ( int ) ( time ( NULL ) - S - > connect_time ) ;
snprintf ( center , sizeof ( center ) , " %s [%02d:%02d] " ,
hosts [ S - > host_idx ] . name , elapsed / 60 , elapsed % 60 ) ;
snprintf ( center , sizeof ( center ) , " %s %s [%02d:%02d]" ,
sess_tag, hosts[ S - > host_idx ] . name , elapsed / 60 , elapsed % 60 ) ;
} else {
snprintf ( center , sizeof ( center ) , " Not Connected" ) ;
snprintf ( center , sizeof ( center ) , " %s Not Connected" , sess_tag ) ;
}
int cx = ( COLS - ( int ) strlen ( center ) ) / 2 ;
if ( cx > 0 ) mvwprintw ( status_win , 0 , cx , " %s " , center ) ;
@ -859,14 +870,17 @@ static void draw_fkeys(void)
werase ( fkey_win ) ;
static const struct { const char * key ; const char * desc ; } fkeys [ ] = {
{ " F1 " , " Help " } ,
{ " F3 " , " Connect " } ,
{ " F4 " , " Disconnect " } ,
{ " F5 " , " Forms " } ,
{ " F6 " , " Log " } ,
{ " F10 " , " Quit " } ,
{ " F1 " , " Help " } ,
{ " F3 " , " Connect " } ,
{ " F4 " , " Disc " } ,
{ " F5 " , " Forms " } ,
{ " F6 " , " Log " } ,
{ " F7 " , " New Ses " } ,
{ " F8 " , " Prev " } ,
{ " F9 " , " Next " } ,
{ " F10 " , " Quit " } ,
} ;
static const int nfkeys = 6 ;
static const int nfkeys = 9 ;
int col = 0 ;
for ( int i = 0 ; i < nfkeys & & col < COLS - 2 ; i + + ) {
@ -2607,6 +2621,73 @@ static void pktnet_checkin_form(void)
force_repaint ( ) ;
}
/* ═══════════════════════════════════════════════════════════
* Session management
* ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ */
static int session_count ( void )
{
int n = 0 ;
for ( int i = 0 ; i < MAX_SESSIONS ; i + + )
if ( sessions [ i ] . active ) n + + ;
return n ;
}
static int session_index ( void ) /* index of S in sessions[] */
{
return ( int ) ( S - sessions ) ;
}
static void session_switch ( int n )
{
if ( n < 0 | | n > = MAX_SESSIONS | | ! sessions [ n ] . active ) return ;
S = & sessions [ n ] ;
refresh_all ( ) ;
draw_fkeys ( ) ;
}
static void session_next ( void )
{
int cur = session_index ( ) ;
for ( int i = 1 ; i < MAX_SESSIONS ; i + + ) {
int n = ( cur + i ) % MAX_SESSIONS ;
if ( sessions [ n ] . active ) { session_switch ( n ) ; return ; }
}
}
static void session_prev ( void )
{
int cur = session_index ( ) ;
for ( int i = MAX_SESSIONS - 1 ; i > 0 ; i - - ) {
int n = ( cur + i ) % MAX_SESSIONS ;
if ( sessions [ n ] . active ) { session_switch ( n ) ; return ; }
}
}
static void session_new ( void )
{
int slot = - 1 ;
for ( int i = 0 ; i < MAX_SESSIONS ; i + + )
if ( ! sessions [ i ] . active ) { slot = i ; break ; }
if ( slot < 0 ) {
append_out ( " Max sessions reached (4). \n " , 26 , COLOR_PAIR ( CP_YELLOW ) ) ;
return ;
}
int idx = pick_host ( " New Session — Select Host " ) ;
if ( idx < 0 ) return ;
memset ( & sessions [ slot ] , 0 , sizeof ( Session ) ) ;
sessions [ slot ] . active = 1 ;
sessions [ slot ] . sock = - 1 ;
sessions [ slot ] . host_idx = - 1 ;
sessions [ slot ] . hist_pos = - 1 ;
snprintf ( sessions [ slot ] . label , SESSION_LABEL , " Session %d " , slot + 1 ) ;
S = & sessions [ slot ] ;
refresh_all ( ) ;
draw_fkeys ( ) ;
do_connect ( idx ) ;
}
/* ═══════════════════════════════════════════════════════════
* Connect helper
* ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ */
@ -2737,7 +2818,7 @@ static void forms_menu(void)
static void ctrl_a_menu ( void )
{
int mh = 1 3, mw = 40 ;
int mh = 1 5, mw = 42 ;
int my = ( LINES - mh ) / 2 ; if ( my < 0 ) my = 0 ;
int mx = ( COLS - mw ) / 2 ; if ( mx < 0 ) mx = 0 ;
@ -2747,12 +2828,14 @@ static void ctrl_a_menu(void)
mvwprintw ( w , 0 , ( mw - 14 ) / 2 , " TermTCP Menu " ) ;
mvwprintw ( w , 2 , 4 , " C - Connect " ) ;
mvwprintw ( w , 3 , 4 , " D - Disconnect " ) ;
mvwprintw ( w , 4 , 4 , " O - Config / Host Editor " ) ;
mvwprintw ( w , 5 , 4 , " M - Monitor Options " ) ;
mvwprintw ( w , 6 , 4 , " L - Toggle Log " ) ;
mvwprintw ( w , 7 , 4 , " F - Forms & Check-Ins " ) ;
mvwprintw ( w , 8 , 4 , " H - Help " ) ;
mvwprintw ( w , 9 , 4 , " Q - Quit " ) ;
mvwprintw ( w , 4 , 4 , " N - New Session " ) ;
mvwprintw ( w , 5 , 4 , " 1-4 Switch Session " ) ;
mvwprintw ( w , 6 , 4 , " O - Config / Host Editor " ) ;
mvwprintw ( w , 7 , 4 , " M - Monitor Options " ) ;
mvwprintw ( w , 8 , 4 , " L - Toggle Log " ) ;
mvwprintw ( w , 9 , 4 , " F - Forms & Check-Ins " ) ;
mvwprintw ( w , 10 , 4 , " H - Help " ) ;
mvwprintw ( w , 11 , 4 , " Q - Quit " ) ;
mvwprintw ( w , mh - 2 , 4 , " Esc = close " ) ;
wrefresh ( w ) ;
@ -2808,6 +2891,14 @@ static void ctrl_a_menu(void)
show_help ( ) ;
break ;
case ' n ' :
session_new ( ) ;
break ;
case ' 1 ' : case ' 2 ' : case ' 3 ' : case ' 4 ' :
session_switch ( ch - ' 1 ' ) ;
break ;
case ' q ' :
if ( S - > connected ) tcp_disconnect ( ) ;
if ( S - > logging ) close_log ( ) ;
@ -2867,6 +2958,18 @@ static void handle_key(int ch)
draw_status ( ) ;
return ;
case KEY_F ( 7 ) :
session_new ( ) ;
return ;
case KEY_F ( 8 ) :
session_prev ( ) ;
return ;
case KEY_F ( 9 ) :
session_next ( ) ;
return ;
case KEY_F ( 10 ) :
if ( S - > connected ) tcp_disconnect ( ) ;
if ( S - > logging ) close_log ( ) ;