@ -8,7 +8,6 @@ 
			
		
	
		
			
				
					# include  "character_sets.h"  
			
		
	
		
			
				
					# include  "utf8.h"  
			
		
	
		
			
				
					# include  "cgi_sockets.h"  
			
		
	
		
			
				
					# include  "cgi_logging.h"  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					TerminalConfigBundle  *  const  termconf  =  & persist . current . termconf ;  
			
		
	
		
			
				
					TerminalConfigBundle  termconf_live ;  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -39,7 +38,6 @@ static Cell screen[MAX_SCREEN_SIZE]; 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					# define TABSTOP_WORDS 5  
			
		
	
		
			
				
					# define LINE_ATTRS_COUNT 64  
			
		
	
		
			
				
					/**
  
			
		
	
		
			
				
					 *  Screen  state  structure   
			
		
	
		
			
				
					 */   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -58,12 +56,9 @@ static struct { 
			
		
	
		
			
				
						int  vm1 ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						u32  tab_stops [ TABSTOP_WORDS ] ;  // tab stops bitmap
   
			
		
	
		
			
				
						u8  line_attribs [ LINE_ATTRS_COUNT ] ;  // assume that's quite enough...
   
			
		
	
		
			
				
						char  last_char [ 4 ] ;   
			
		
	
		
			
				
					}  scr ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					# define IS_DOUBLE_WIDTH() (scr.line_attribs[cursor.y]&0b001)  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					# define TOP scr.vm0  
			
		
	
		
			
				
					# define BTM scr.vm1  
			
		
	
		
			
				
					# define RH (scr.vm1 - scr.vm0 + 1)  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -111,19 +106,8 @@ bool cursor_saved = false; 
			
		
	
		
			
				
					static  struct  {  
			
		
	
		
			
				
						bool  alternate_active ;   
			
		
	
		
			
				
						char  title [ TERM_TITLE_LEN ] ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						char  btn1 [ TERM_BTN_LEN ] ;   
			
		
	
		
			
				
						char  btn2 [ TERM_BTN_LEN ] ;   
			
		
	
		
			
				
						char  btn3 [ TERM_BTN_LEN ] ;   
			
		
	
		
			
				
						char  btn4 [ TERM_BTN_LEN ] ;   
			
		
	
		
			
				
						char  btn5 [ TERM_BTN_LEN ] ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						char  btn1_msg [ TERM_BTN_MSG_LEN ] ;   
			
		
	
		
			
				
						char  btn2_msg [ TERM_BTN_MSG_LEN ] ;   
			
		
	
		
			
				
						char  btn3_msg [ TERM_BTN_MSG_LEN ] ;   
			
		
	
		
			
				
						char  btn4_msg [ TERM_BTN_MSG_LEN ] ;   
			
		
	
		
			
				
						char  btn5_msg [ TERM_BTN_MSG_LEN ] ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						char  btn [ TERM_BTN_COUNT ] [ TERM_BTN_LEN ] ;   
			
		
	
		
			
				
						char  btn_msg [ TERM_BTN_COUNT ] [ TERM_BTN_MSG_LEN ] ;   
			
		
	
		
			
				
						u32  width ;   
			
		
	
		
			
				
						u32  height ;   
			
		
	
		
			
				
						int  vm0 ;   
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -159,200 +143,46 @@ static struct { 
			
		
	
		
			
				
						int  x_min ,  y_min ,  x_max ,  y_max ;   
			
		
	
		
			
				
					}  scr_dirty ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  void  ICACHE_FLASH_ATTR  reset_screen_dirty ( void )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						scr_dirty . x_min  =  W ;   
			
		
	
		
			
				
						scr_dirty . x_max  =  - 1 ;   
			
		
	
		
			
				
						scr_dirty . y_min  =  H ;   
			
		
	
		
			
				
						scr_dirty . y_max  =  - 1 ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					# define reset_screen_dirty() do { \  
			
		
	
		
			
				
							scr_dirty . x_min  =  W ;  \
  
			
		
	
		
			
				
							scr_dirty . x_max  =  - 1 ;  \
  
			
		
	
		
			
				
							scr_dirty . y_min  =  H ;  \
  
			
		
	
		
			
				
							scr_dirty . y_max  =  - 1 ;  \
  
			
		
	
		
			
				
						}  while ( 0 )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  void  ICACHE_FLASH_ATTR  expand_dirty ( int  y0 ,  int  y1 ,  int  x0 ,  int  x1 )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						seri_dbg ( " Expand: X: (%d..%d) -> %d..%d, Y: (%d..%d) -> %d..%d " ,   
			
		
	
		
			
				
								 scr_dirty . x_min ,  scr_dirty . x_max ,  x0 ,  x1 ,  scr_dirty . y_min ,  scr_dirty . y_max ,  y0 ,  y1 ) ;   
			
		
	
		
			
				
					# define expand_dirty(y0, y1, x0, x1)  do { \  
			
		
	
		
			
				
							seri_dbg ( " Expand: X: (%d..%d) -> %d..%d, Y: (%d..%d) -> %d..%d " ,  scr_dirty . x_min ,  scr_dirty . x_max ,  x0 ,  x1 ,  scr_dirty . y_min ,  scr_dirty . y_max ,  y0 ,  y1 ) ;  \
  
			
		
	
		
			
				
							if  ( ( int ) ( y0 )  <  scr_dirty . y_min )  scr_dirty . y_min   =  ( y0 ) ;  \
  
			
		
	
		
			
				
							if  ( ( int ) ( x0 )  <  scr_dirty . x_min )  scr_dirty . x_min   =  ( x0 ) ;  \
  
			
		
	
		
			
				
							if  ( ( int ) ( y1 )  >  scr_dirty . y_max )  scr_dirty . y_max   =  ( y1 ) ;  \
  
			
		
	
		
			
				
							if  ( ( int ) ( x1 )  >  scr_dirty . x_max )  scr_dirty . x_max   =  ( x1 ) ;  \
  
			
		
	
		
			
				
						}  while ( 0 )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( ( y0 )  <  scr_dirty . y_min )  scr_dirty . y_min   =  ( y0 ) ;   
			
		
	
		
			
				
						if  ( ( x0 )  <  scr_dirty . x_min )  scr_dirty . x_min   =  ( x0 ) ;   
			
		
	
		
			
				
						if  ( ( y1 )  >  scr_dirty . y_max )  scr_dirty . y_max   =  ( y1 ) ;   
			
		
	
		
			
				
						if  ( ( x1 )  >  scr_dirty . x_max )  scr_dirty . x_max   =  ( x1 ) ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					# define NOTIFY_LOCK() do { \  
			
		
	
		
			
				
												notifyLock + + ;  \
  
			
		
	
		
			
				
											}  while ( 0 )   
			
		
	
		
			
				
					            
  
			
		
	
		
			
				
					# define NOTIFY_LOCK() { notifyLock++; }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  void  ICACHE_FLASH_ATTR  NOTIFY_DONE ( u32  updateTopics )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						lockTopics  | =  ( updateTopics ) ;   
			
		
	
		
			
				
						if  ( notifyLock  >  0 )  notifyLock - - ;   
			
		
	
		
			
				
						if  ( notifyLock  = =  0 )  {   
			
		
	
		
			
				
							screen_notifyChange ( lockTopics ) ;   
			
		
	
		
			
				
							lockTopics  =  0 ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					# define NOTIFY_DONE(updateTopics) do { \  
			
		
	
		
			
				
												lockTopics  | =  ( updateTopics ) ;  \
  
			
		
	
		
			
				
												if  ( notifyLock  >  0 )  notifyLock - - ;  \
  
			
		
	
		
			
				
												if  ( notifyLock  = =  0 )  {  \
  
			
		
	
		
			
				
													screen_notifyChange ( lockTopics ) ;  \
  
			
		
	
		
			
				
													lockTopics  =  0 ; \
  
			
		
	
		
			
				
												}  \
  
			
		
	
		
			
				
											}  while ( 0 )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					/** Clear the hanging attribute if the cursor is no longer >= W */  
			
		
	
		
			
				
					static  void  ICACHE_FLASH_ATTR  clear_invalid_hanging ( void )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						if  ( cursor . hanging  & &  cursor . x  ! =  W - 1 )  {   
			
		
	
		
			
				
							cursor . hanging  =  false ;   
			
		
	
		
			
				
							screen_notifyChange ( TOPIC_CHANGE_CURSOR ) ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					# define clear_invalid_hanging() do { \  
			
		
	
		
			
				
														if  ( cursor . hanging  & &  cursor . x  ! =  W - 1 )  {  \
  
			
		
	
		
			
				
															cursor . hanging  =  false ;  \
  
			
		
	
		
			
				
															screen_notifyChange ( TOPIC_CHANGE_CURSOR ) ;  \
  
			
		
	
		
			
				
														}  \
  
			
		
	
		
			
				
													}  while ( false )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					# define cursor_inside_region() (cursor.y >= TOP && cursor.y <= BTM)  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					//region --- Settings ---
  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					/** Export color for config */  
			
		
	
		
			
				
					void  ICACHE_FLASH_ATTR  
			
		
	
		
			
				
					xget_term_color ( char  * buff ,  u32  value )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						if  ( value  <  256 )  {   
			
		
	
		
			
				
							sprintf ( buff ,  " %d " ,  value ) ;   
			
		
	
		
			
				
						}  else  {   
			
		
	
		
			
				
							sprintf ( buff ,  " #%06X " ,  value  -  256 ) ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					/** Export button message as stirng for config */  
			
		
	
		
			
				
					void  ICACHE_FLASH_ATTR  
			
		
	
		
			
				
					xget_term_bm ( char  * buff ,  char  * value )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						char  c ;   
			
		
	
		
			
				
						char  * bp  =  buff ;   
			
		
	
		
			
				
						char  * cp  =  value ;   
			
		
	
		
			
				
						buff [ 0 ]  =  0 ;   
			
		
	
		
			
				
						int  n  =  0 ;   
			
		
	
		
			
				
						while ( ( c  =  * cp + + )  ! =  0 )  {   
			
		
	
		
			
				
							if ( n > 0 )  {   
			
		
	
		
			
				
								* bp  =  ' , ' ;   
			
		
	
		
			
				
								bp + + ;   
			
		
	
		
			
				
							}   
			
		
	
		
			
				
							bp  + =  sprintf ( bp ,  " %d " ,  ( u8 ) c ) ;   
			
		
	
		
			
				
							n + + ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					enum  xset_result  ICACHE_FLASH_ATTR  
			
		
	
		
			
				
					xset_term_bm ( const  char  * name ,  char  * field ,  const  char  * buff ,  const  void  * arg )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						cgi_dbg ( " Setting %s = %s " ,  name ,  buff ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// parse: comma,space or semicolon separated decimal values of ASCII codes
   
			
		
	
		
			
				
						char  c ;   
			
		
	
		
			
				
						const  char  * cp  =  buff ;   
			
		
	
		
			
				
						int  char_i  =  0 ;   
			
		
	
		
			
				
						int  acu  =  0 ;   
			
		
	
		
			
				
						bool  lastsp  =  1 ;   
			
		
	
		
			
				
						char  buff_bm [ TERM_BTN_MSG_LEN ] ;   
			
		
	
		
			
				
						while  ( ( c  =  * cp + + )  ! =  0 )  {   
			
		
	
		
			
				
							if  ( c  = =  '   '  | |  c  = =  ' , '  | |  c  = =  ' ; ' )  {   
			
		
	
		
			
				
								if ( lastsp )  continue ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								if  ( acu = = 0  | |  acu > 255 )  {   
			
		
	
		
			
				
									cgi_warn ( " Bad value! %d " ,  acu ) ;   
			
		
	
		
			
				
									return  XSET_FAIL ;   
			
		
	
		
			
				
								}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								if  ( char_i  > =  TERM_BTN_MSG_LEN - 1 )  {   
			
		
	
		
			
				
									cgi_warn ( " Too long! %d " ,  char_i ) ;   
			
		
	
		
			
				
									return  XSET_FAIL ;   
			
		
	
		
			
				
								}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								dbg ( " + %c " ,  acu ) ;   
			
		
	
		
			
				
								buff_bm [ char_i + + ]  =  ( char ) acu ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								// prepare for next char
   
			
		
	
		
			
				
								acu  =  0 ;   
			
		
	
		
			
				
								lastsp  =  1 ;   
			
		
	
		
			
				
							}  else  if  ( c > = ' 0 ' & & c < = ' 9 ' )  {   
			
		
	
		
			
				
								lastsp  =  0 ;   
			
		
	
		
			
				
								acu  * =  10 ;   
			
		
	
		
			
				
								acu  + =  c  -  ' 0 ' ;   
			
		
	
		
			
				
							}  else  {   
			
		
	
		
			
				
								cgi_warn ( " Bad syntax! " ) ;   
			
		
	
		
			
				
								return  XSET_FAIL ;   
			
		
	
		
			
				
							}   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
						if  ( lastsp  & &  char_i  = =  0 )  {   
			
		
	
		
			
				
							cgi_warn ( " Required! " ) ;   
			
		
	
		
			
				
							return  XSET_FAIL ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
						if  ( ! lastsp & & acu > 0 )  {   
			
		
	
		
			
				
							dbg ( " + %c " ,  acu ) ;   
			
		
	
		
			
				
							buff_bm [ char_i + + ]  =  ( char ) acu ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
						buff_bm [ char_i ]  =  0 ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( char_i  = =  0 )  {   
			
		
	
		
			
				
							cgi_warn ( " Required! " ) ;   
			
		
	
		
			
				
							return  XSET_FAIL ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( ! streq ( field ,  buff_bm ) )  {   
			
		
	
		
			
				
							strncpy ( field ,  buff_bm ,  TERM_BTN_MSG_LEN ) ;   
			
		
	
		
			
				
							return  XSET_SET ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
						return  XSET_UNCHANGED ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					/** convert hex number to int */  
			
		
	
		
			
				
					static  ICACHE_FLASH_ATTR  u32  
			
		
	
		
			
				
					decodehex ( const  char  * buf )  {  
			
		
	
		
			
				
						u32  n  =  0 ;   
			
		
	
		
			
				
						char  c ;   
			
		
	
		
			
				
						while  ( ( c  =  * buf + + )  ! =  0 )  {   
			
		
	
		
			
				
							if  ( c  > =  ' 0 '  & &  c  < =  ' 9 ' )  c  - =  ' 0 ' ;   
			
		
	
		
			
				
							else  if  ( c  > =  ' a '  & &  c  < =  ' f ' )  c  - =  ' a ' - 10 ;   
			
		
	
		
			
				
							else  if  ( c  > =  ' A '  & &  c  < =  ' F ' )  c  - =  ' A ' - 10 ;   
			
		
	
		
			
				
							else  c  =  0 ;   
			
		
	
		
			
				
							n  * =  16 ;   
			
		
	
		
			
				
							n  + =  c ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
						return  n ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					enum  xset_result  ICACHE_FLASH_ATTR  
			
		
	
		
			
				
					xset_term_color ( const  char  * name ,  u32  * field ,  const  char  * buff ,  const  void  * arg )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						cgi_dbg ( " Setting %s = %s " ,  name ,  buff ) ;   
			
		
	
		
			
				
						u32  n ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( buff [ 0 ]  = =  ' # ' )  {   
			
		
	
		
			
				
							// decode hex
   
			
		
	
		
			
				
							n  =  decodehex ( buff + 1 ) ;   
			
		
	
		
			
				
							n  + =  256 ;   
			
		
	
		
			
				
						}  else  {   
			
		
	
		
			
				
							n  =  atoi ( buff ) ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( * field  ! =  n )  {   
			
		
	
		
			
				
							* field  =  n ;   
			
		
	
		
			
				
							return  XSET_SET ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						return  XSET_UNCHANGED ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					enum  xset_result  ICACHE_FLASH_ATTR  
			
		
	
		
			
				
					xset_term_cursorshape ( const  char  * name ,  u32  * field ,  const  char  * buff ,  const  void  * arg )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						cgi_dbg ( " Setting %s = %s " ,  name ,  buff ) ;   
			
		
	
		
			
				
						u32  n  =  atoi ( buff ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( n  > =  0  & &  n  < =  6  & &  n  ! =  1 )  {   
			
		
	
		
			
				
							if  ( * field  ! =  n )  {   
			
		
	
		
			
				
								* field  =  n ;   
			
		
	
		
			
				
								return  XSET_SET ;   
			
		
	
		
			
				
							}   
			
		
	
		
			
				
							return  XSET_UNCHANGED ;   
			
		
	
		
			
				
						}  else  {   
			
		
	
		
			
				
							cgi_warn ( " Bad cursor_shape num: %s " ,  buff ) ;   
			
		
	
		
			
				
							return  XSET_FAIL ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					/**
  
			
		
	
		
			
				
					 *  Restore  hard  defaults   
			
		
	
		
			
				
					 */   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -364,21 +194,10 @@ terminal_restore_defaults(void) 
			
		
	
		
			
				
						termconf - > default_bg  =  0 ;   
			
		
	
		
			
				
						termconf - > default_fg  =  7 ;   
			
		
	
		
			
				
						sprintf ( termconf - > title ,  SCR_DEF_TITLE ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						strcpy ( termconf - > btn1 ,  " 1 " ) ;   
			
		
	
		
			
				
						strcpy ( termconf - > btn2 ,  " 2 " ) ;   
			
		
	
		
			
				
						strcpy ( termconf - > btn3 ,  " 3 " ) ;   
			
		
	
		
			
				
						strcpy ( termconf - > btn4 ,  " 4 " ) ;   
			
		
	
		
			
				
						strcpy ( termconf - > btn5 ,  " 5 " ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						strcpy ( ( char * ) termconf - > bm1 ,  " \x01 " ) ;   
			
		
	
		
			
				
						strcpy ( ( char * ) termconf - > bm2 ,  " \x02 " ) ;   
			
		
	
		
			
				
						strcpy ( ( char * ) termconf - > bm3 ,  " \x03 " ) ;   
			
		
	
		
			
				
						strcpy ( ( char * ) termconf - > bm4 ,  " \x04 " ) ;   
			
		
	
		
			
				
						strcpy ( ( char * ) termconf - > bm5 ,  " \x05 " ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						termconf - > bc1  =  termconf - > bc2  =  termconf - > bc3  =  termconf - > bc4  =  termconf - > bc5  =  0 ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						for ( int  i = 1 ;  i  < =  TERM_BTN_COUNT ;  i + + )  {   
			
		
	
		
			
				
							sprintf ( termconf - > btn [ i - 1 ] ,  " %d " ,  i ) ;   
			
		
	
		
			
				
							sprintf ( termconf - > btn_msg [ i - 1 ] ,  " %c " ,  i ) ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
						termconf - > theme  =  0 ;   
			
		
	
		
			
				
						termconf - > parser_tout_ms  =  SCR_DEF_PARSER_TOUT_MS ;   
			
		
	
		
			
				
						termconf - > display_tout_ms  =  SCR_DEF_DISPLAY_TOUT_MS ;   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -394,9 +213,6 @@ terminal_restore_defaults(void) 
			
		
	
		
			
				
						termconf - > debugbar  =  SCR_DEF_DEBUGBAR ;   
			
		
	
		
			
				
						termconf - > allow_decopt_12  =  SCR_DEF_DECOPT12 ;   
			
		
	
		
			
				
						termconf - > ascii_debug  =  SCR_DEF_ASCIIDEBUG ;   
			
		
	
		
			
				
						termconf - > backdrop [ 0 ]  =  0 ;   
			
		
	
		
			
				
						termconf - > font_stack [ 0 ]  =  0 ;   
			
		
	
		
			
				
						termconf - > font_size  =  20 ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					/**
  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -415,47 +231,22 @@ terminal_apply_settings_noclear(void) 
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						bool  changed  =  false ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					//		char buff[64];
  
			
		
	
		
			
				
					//#define XSTRUCT termconf
  
			
		
	
		
			
				
					//#define X XDUMP_FIELD
  
			
		
	
		
			
				
					//	XTABLE_TERMCONF
  
			
		
	
		
			
				
					//#undef X
  
			
		
	
		
			
				
					//	return;
  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// Migrate
   
			
		
	
		
			
				
						if  ( termconf - > config_version  <  1 )  {   
			
		
	
		
			
				
							persist_dbg ( " termconf: Updating to version 1 "  ) ;   
			
		
	
		
			
				
							persist_dbg ( " termconf: Updating to version %d " ,  1 ) ;   
			
		
	
		
			
				
							termconf - > debugbar  =  SCR_DEF_DEBUGBAR ;   
			
		
	
		
			
				
							changed  =  1 ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
						if  ( termconf - > config_version  <  2 )  {   
			
		
	
		
			
				
							persist_dbg ( " termconf: Updating to version 2 "  ) ;   
			
		
	
		
			
				
							persist_dbg ( " termconf: Updating to version %d " ,  1  ) ;   
			
		
	
		
			
				
							termconf - > allow_decopt_12  =  SCR_DEF_DECOPT12 ;   
			
		
	
		
			
				
							changed  =  1 ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
						if  ( termconf - > config_version  <  3 )  {   
			
		
	
		
			
				
							persist_dbg ( " termconf: Updating to version 3 "  ) ;   
			
		
	
		
			
				
							persist_dbg ( " termconf: Updating to version %d " ,  1  ) ;   
			
		
	
		
			
				
							termconf - > ascii_debug  =  SCR_DEF_ASCIIDEBUG ;   
			
		
	
		
			
				
							changed  =  1 ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
						if  ( termconf - > config_version  <  4 )  {   
			
		
	
		
			
				
							persist_dbg ( " termconf: Updating to version 4 " ) ;   
			
		
	
		
			
				
							termconf - > backdrop [ 0 ]  =  0 ;   
			
		
	
		
			
				
							changed  =  1 ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
						if  ( termconf - > config_version  <  5 )  {   
			
		
	
		
			
				
							persist_dbg ( " termconf: Updating to version 5 " ) ;   
			
		
	
		
			
				
							termconf - > button_count  =  SCR_DEF_BUTTON_COUNT ;   
			
		
	
		
			
				
							changed  =  1 ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
						if  ( termconf - > config_version  <  6 )  {   
			
		
	
		
			
				
							persist_dbg ( " termconf: Updating to version 6 " ) ;   
			
		
	
		
			
				
							termconf - > backdrop [ 0 ]  =  0 ;   
			
		
	
		
			
				
							termconf - > font_stack [ 0 ]  =  0 ;   
			
		
	
		
			
				
							termconf - > font_size  =  20 ;   
			
		
	
		
			
				
							termconf - > bc1  =  termconf - > bc2  =  termconf - > bc3  =  termconf - > bc4  =  termconf - > bc5  =  0 ;   
			
		
	
		
			
				
							changed  =  1 ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						termconf - > config_version  =  TERMCONF_VERSION ;   
			
		
	
		
			
				
					
 
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -555,12 +346,7 @@ screen_reset_sgr(void) 
			
		
	
		
			
				
					static  void  ICACHE_FLASH_ATTR  
			
		
	
		
			
				
					screen_reset_do ( bool  size ,  bool  labels )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						ScreenNotifyTopics  topics  =   
			
		
	
		
			
				
							TOPIC_CHANGE_SCREEN_OPTS   
			
		
	
		
			
				
							|  TOPIC_CHANGE_CURSOR   
			
		
	
		
			
				
							|  TOPIC_CHANGE_CONTENT_ALL   
			
		
	
		
			
				
							|  TOPIC_DOUBLE_LINES ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						ScreenNotifyTopics  topics  =  TOPIC_CHANGE_SCREEN_OPTS  |  TOPIC_CHANGE_CURSOR  |  TOPIC_CHANGE_CONTENT_ALL ;   
			
		
	
		
			
				
						NOTIFY_LOCK ( ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// DECopts
   
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -597,23 +383,18 @@ screen_reset_do(bool size, bool labels) 
			
		
	
		
			
				
							scr . tab_stops [ i ]  =  0x80808080 ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// clear line attribs
   
			
		
	
		
			
				
						memset ( scr . line_attribs ,  0 ,  LINE_ATTRS_COUNT ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( labels )  {   
			
		
	
		
			
				
							strcpy ( termconf_live . title ,  termconf - > title ) ;   
			
		
	
		
			
				
							strcpy ( termconf_live . backdrop ,  termconf - > backdrop ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							strcpy ( termconf_live . btn1 ,  termconf - > btn1 ) ;   
			
		
	
		
			
				
							strcpy ( termconf_live . btn2 ,  termconf - > btn2 ) ;   
			
		
	
		
			
				
							strcpy ( termconf_live . btn3 ,  termconf - > btn3 ) ;   
			
		
	
		
			
				
							strcpy ( termconf_live . btn4 ,  termconf - > btn4 ) ;   
			
		
	
		
			
				
							strcpy ( termconf_live . btn5 ,  termconf - > btn5 ) ;   
			
		
	
		
			
				
							for  ( int  i  =  1 ;  i  < =  TERM_BTN_COUNT ;  i + + )  {   
			
		
	
		
			
				
								strcpy ( termconf_live . btn [ i ] ,  termconf - > btn [ i ] ) ;   
			
		
	
		
			
				
								strcpy ( termconf_live . btn_msg [ i ] ,  termconf - > btn_msg [ i ] ) ;   
			
		
	
		
			
				
							}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							termconf_live . show_buttons  =  termconf - > show_buttons ;   
			
		
	
		
			
				
							termconf_live . show_config_links  =  termconf - > show_config_links ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							topics  | =  TOPIC_CHANGE_TITLE  |  TOPIC_CHANGE_BUTTONS  |  TOPIC_CHANGE_BACKDROP  ;   
			
		
	
		
			
				
							topics  | =  TOPIC_CHANGE_TITLE  |  TOPIC_CHANGE_BUTTONS ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// initial values in the save buffer in case of receiving restore without storing first
   
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -664,11 +445,8 @@ screen_swap_state(bool alternate) 
			
		
	
		
			
				
							ansi_dbg ( " Swap to alternate " ) ;   
			
		
	
		
			
				
							// store old state
   
			
		
	
		
			
				
							memcpy ( state_backup . title ,  termconf_live . title ,  TERM_TITLE_LEN ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							// copy multiple fields at once
   
			
		
	
		
			
				
							memcpy ( state_backup . btn1 ,  termconf_live . btn1 ,  sizeof ( termconf_live . btn1 ) * TERM_BTN_COUNT ) ;   
			
		
	
		
			
				
							memcpy ( state_backup . btn1_msg ,  termconf_live . bm1 ,  sizeof ( termconf_live . bm1 ) * TERM_BTN_COUNT ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							memcpy ( state_backup . btn ,  termconf_live . btn ,  sizeof ( termconf_live . btn ) ) ;   
			
		
	
		
			
				
							memcpy ( state_backup . btn_msg ,  termconf_live . btn_msg ,  sizeof ( termconf_live . btn_msg ) ) ;   
			
		
	
		
			
				
							memcpy ( state_backup . tab_stops ,  scr . tab_stops ,  sizeof ( scr . tab_stops ) ) ;   
			
		
	
		
			
				
							state_backup . vm0  =  scr . vm0 ;   
			
		
	
		
			
				
							state_backup . vm1  =  scr . vm1 ;   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -680,11 +458,8 @@ screen_swap_state(bool alternate) 
			
		
	
		
			
				
						else  {   
			
		
	
		
			
				
							ansi_dbg ( " Unswap from alternate " ) ;   
			
		
	
		
			
				
							memcpy ( termconf_live . title ,  state_backup . title ,  TERM_TITLE_LEN ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							// copy multiple fields at once
   
			
		
	
		
			
				
							memcpy ( termconf_live . btn1 ,  state_backup . btn1 ,  sizeof ( termconf_live . btn1 ) * TERM_BTN_COUNT ) ;   
			
		
	
		
			
				
							memcpy ( termconf_live . bm1 ,  state_backup . btn1_msg ,  sizeof ( termconf_live . bm1 ) * TERM_BTN_COUNT ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							memcpy ( termconf_live . btn ,  state_backup . btn ,  sizeof ( termconf_live . btn ) ) ;   
			
		
	
		
			
				
							memcpy ( termconf_live . btn_msg ,  state_backup . btn_msg ,  sizeof ( termconf_live . btn_msg ) ) ;   
			
		
	
		
			
				
							memcpy ( scr . tab_stops ,  state_backup . tab_stops ,  sizeof ( scr . tab_stops ) ) ;   
			
		
	
		
			
				
							scr . vm0  =  state_backup . vm0 ;   
			
		
	
		
			
				
							scr . vm1  =  state_backup . vm1 ;   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -699,32 +474,6 @@ screen_swap_state(bool alternate) 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					//endregion
  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					//region --- Double lines ---
  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					void  ICACHE_FLASH_ATTR  
			
		
	
		
			
				
					screen_set_line_attr ( uint8_t  double_w ,  uint8_t  double_h_top ,  uint8_t  double_h_bot )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						NOTIFY_LOCK ( ) ;   
			
		
	
		
			
				
						u8  attr  =  scr . line_attribs [ cursor . y ] ;   
			
		
	
		
			
				
						if  ( double_w = = 2 )  attr  | =  0 b001 ;   
			
		
	
		
			
				
						else  if  ( double_w = = 1 )  attr  & =  ~ 0 b001 ;   
			
		
	
		
			
				
						if  ( double_h_top = = 2 )  attr  | =  0 b010 ;   
			
		
	
		
			
				
						else  if  ( double_h_top = = 1 )  attr  & =  ~ 0 b010 ;   
			
		
	
		
			
				
						if  ( double_h_bot = = 2 )  attr  | =  0 b100 ;   
			
		
	
		
			
				
						else  if  ( double_h_bot = = 1 )  attr  & =  ~ 0 b100 ;   
			
		
	
		
			
				
						scr . line_attribs [ cursor . y ]  =  attr ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( attr  &  0 b001 )  {   
			
		
	
		
			
				
							// if we're using double width - clamp cursor X position
   
			
		
	
		
			
				
							// TODO this should happen in all cursor ops - now it can sometimes go offscreen
   
			
		
	
		
			
				
							if  ( cursor . x  > =  W / 2 )  cursor . x  =  W / 2 ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						NOTIFY_DONE ( TOPIC_DOUBLE_LINES ) ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					//endregion
  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					//region --- Tab stops ---
  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					void  ICACHE_FLASH_ATTR  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -760,7 +509,6 @@ next_tab_stop(void) 
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						// cursor must never go past EOL
   
			
		
	
		
			
				
						if  ( cursor . x  > =  W - 1 )  return  - 1 ;   
			
		
	
		
			
				
						if  ( IS_DOUBLE_WIDTH ( )  & &  cursor . x  > =  W / 2 - 1 )  return  - 1 ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// find first word to inspect
   
			
		
	
		
			
				
						int  idx  =  ( cursor . x + 1 ) / 32 ;   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -772,7 +520,6 @@ next_tab_stop(void) 
			
		
	
		
			
				
							for ( ; offs < 32 ; offs + + )  {   
			
		
	
		
			
				
								cp + + ;   
			
		
	
		
			
				
								if  ( cp  > =  W )  return  - 1 ;   
			
		
	
		
			
				
								if  ( IS_DOUBLE_WIDTH ( )  & &  cp  > =  W / 2 )  return  - 1 ;   
			
		
	
		
			
				
								if  ( w  &  1 )  return  cp ;   
			
		
	
		
			
				
								w  > > =  1 ;   
			
		
	
		
			
				
							}   
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -830,7 +577,6 @@ screen_tab_forward(int count) 
			
		
	
		
			
				
							}   
			
		
	
		
			
				
							else  {   
			
		
	
		
			
				
								cursor . x  =  W  -  1 ;   
			
		
	
		
			
				
								if  ( IS_DOUBLE_WIDTH ( ) )  cursor . x  =  W / 2  -  1 ;   
			
		
	
		
			
				
							}   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
						NOTIFY_DONE ( TOPIC_CHANGE_CURSOR ) ;   
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -1032,23 +778,19 @@ screen_clear(ClearMode mode) 
			
		
	
		
			
				
								unicode_cache_clear ( ) ;   
			
		
	
		
			
				
								clear_range_noutf ( 0 ,  W  *  H  -  1 ) ;   
			
		
	
		
			
				
								scr . last_char [ 0 ]   =  0 ;   
			
		
	
		
			
				
								for  ( int  i  =  0 ;  i  <  LINE_ATTRS_COUNT ;  i + + )  scr . line_attribs [ i ]  =  0 ;   
			
		
	
		
			
				
								break ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							case  CLEAR_FROM_CURSOR :   
			
		
	
		
			
				
								clear_range_utf ( ( cursor . y  *  W )  +  cursor . x ,  W  *  H  -  1 ) ;   
			
		
	
		
			
				
								expand_dirty ( cursor . y ,  H - 1 ,  0 ,  W - 1 ) ;   
			
		
	
		
			
				
								for  ( int  i  =  cursor . y ;  i  <  LINE_ATTRS_COUNT ;  i + + )  scr . line_attribs [ i ]  =  0 ;   
			
		
	
		
			
				
								break ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							case  CLEAR_TO_CURSOR :   
			
		
	
		
			
				
								clear_range_utf ( 0 ,  ( cursor . y  *  W )  +  cursor . x ) ;   
			
		
	
		
			
				
								expand_dirty ( 0 ,  cursor . y ,  0 ,  W - 1 ) ;   
			
		
	
		
			
				
								for  ( int  i  =  0 ;  i  < =  cursor . y ;  i + + )  scr . line_attribs [ i ]  =  0 ;   
			
		
	
		
			
				
								break ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
						NOTIFY_DONE ( ( mode  = =  CLEAR_ALL  ?  TOPIC_CHANGE_CONTENT_ALL  :  TOPIC_CHANGE_CONTENT_PART )   
			
		
	
		
			
				
									|  TOPIC_DOUBLE_LINES ) ;   
			
		
	
		
			
				
						NOTIFY_DONE ( mode  = =  CLEAR_ALL  ?  TOPIC_CHANGE_CONTENT_ALL  :  TOPIC_CHANGE_CONTENT_PART ) ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					/**
  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -1100,15 +842,11 @@ screen_insert_lines(unsigned int lines) 
			
		
	
		
			
				
						int  targetStart  =  cursor . y  +  lines ;   
			
		
	
		
			
				
						if  ( targetStart  >  BTM )  {   
			
		
	
		
			
				
							clear_range_utf ( cursor . y * W ,  ( BTM + 1 ) * W - 1 ) ;   
			
		
	
		
			
				
							for  ( int  i  =  cursor . y ;  i  < =  BTM ;  i + + )  {   
			
		
	
		
			
				
								scr . line_attribs [ i ]  =  0 ;   
			
		
	
		
			
				
							}   
			
		
	
		
			
				
						}  else  {   
			
		
	
		
			
				
							// do the moving
   
			
		
	
		
			
				
							for  ( int  i  =  BTM ;  i  > =  targetStart ;  i - - )  {   
			
		
	
		
			
				
								utf_free_row ( i ) ;  // release old characters
   
			
		
	
		
			
				
								copy_row ( i ,  i  -  lines ) ;   
			
		
	
		
			
				
								scr . line_attribs [ i ]  =  scr . line_attribs [ i - lines ] ;   
			
		
	
		
			
				
								if  ( i  ! =  targetStart )  utf_backup_row ( i ) ;   
			
		
	
		
			
				
							}   
			
		
	
		
			
				
					
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -1120,7 +858,7 @@ screen_insert_lines(unsigned int lines) 
			
		
	
		
			
				
							}   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
						expand_dirty ( cursor . y ,  BTM ,  0 ,  W  -  1 ) ;   
			
		
	
		
			
				
						NOTIFY_DONE ( TOPIC_CHANGE_CONTENT_PART | TOPIC_DOUBLE_LINES ) ;   
			
		
	
		
			
				
						NOTIFY_DONE ( TOPIC_CHANGE_CONTENT_PART ) ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					void  ICACHE_FLASH_ATTR  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -1135,26 +873,18 @@ screen_delete_lines(unsigned int lines) 
			
		
	
		
			
				
							// clear the entire rest of the screen
   
			
		
	
		
			
				
							movedBlockEnd  =  cursor . y ;   
			
		
	
		
			
				
							clear_range_utf ( movedBlockEnd * W ,  ( BTM + 1 ) * W - 1 ) ;   
			
		
	
		
			
				
							for  ( int  i  =  movedBlockEnd ;  i  < =  BTM ;  i + + )  {   
			
		
	
		
			
				
								scr . line_attribs [ i ]  =  0 ;   
			
		
	
		
			
				
							}   
			
		
	
		
			
				
						}  else  {   
			
		
	
		
			
				
							// move some lines up, clear the rest
   
			
		
	
		
			
				
							for  ( int  i  =  cursor . y ;  i  < =  movedBlockEnd ;  i + + )  {   
			
		
	
		
			
				
								utf_free_row ( i ) ;   
			
		
	
		
			
				
								copy_row ( i ,  i + lines ) ;   
			
		
	
		
			
				
								scr . line_attribs [ i ]  =  scr . line_attribs [ i + lines ] ;   
			
		
	
		
			
				
								if  ( i  ! =  movedBlockEnd )  utf_backup_row ( i ) ;   
			
		
	
		
			
				
							}   
			
		
	
		
			
				
							clear_range_noutf ( ( movedBlockEnd + 1 ) * W ,  ( BTM + 1 ) * W - 1 ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							for  ( int  i  =  movedBlockEnd + 1 ;  i  < =  BTM ;  i + + )  {   
			
		
	
		
			
				
								scr . line_attribs [ i ]  =  0 ;   
			
		
	
		
			
				
							}   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						expand_dirty ( cursor . y ,  BTM ,  0 ,  W  -  1 ) ;   
			
		
	
		
			
				
						NOTIFY_DONE ( TOPIC_CHANGE_CONTENT_PART | TOPIC_DOUBLE_LINES ) ;   
			
		
	
		
			
				
						NOTIFY_DONE ( TOPIC_CHANGE_CONTENT_PART ) ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					void  ICACHE_FLASH_ATTR  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -1252,8 +982,8 @@ screen_resize(int rows, int cols) 
			
		
	
		
			
				
						if  ( W  = =  cols  & &  H  = =  rows )  return ;  // Do nothing
   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						NOTIFY_LOCK ( ) ;   
			
		
	
		
			
				
						W  =  ( u32 )  cols ;   
			
		
	
		
			
				
						H  =  ( u32 )  rows ;   
			
		
	
		
			
				
						W  =  cols ;   
			
		
	
		
			
				
						H  =  rows ;   
			
		
	
		
			
				
						screen_reset_on_resize ( ) ;   
			
		
	
		
			
				
						NOTIFY_DONE ( TOPIC_CHANGE_SCREEN_OPTS | TOPIC_CHANGE_CONTENT_ALL | TOPIC_CHANGE_CURSOR ) ;   
			
		
	
		
			
				
					}  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -1275,82 +1005,10 @@ void ICACHE_FLASH_ATTR 
			
		
	
		
			
				
					screen_set_button_text ( int  num ,  const  char  * text )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						NOTIFY_LOCK ( ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( num  > =  1  & &  num  < =  TERM_BTN_COUNT )  {   
			
		
	
		
			
				
							char  * buf  =  TERM_BTN_N ( & termconf_live ,  num  -  1 ) ;   
			
		
	
		
			
				
							strncpy ( buf ,  text ,  TERM_BTN_MSG_LEN ) ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
						else  ansi_warn ( " Bad button num: %d " ,  num ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						NOTIFY_DONE ( TOPIC_CHANGE_BUTTONS ) ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					/**
  
			
		
	
		
			
				
					 *  Helper  function  to  set  terminal  button  label   
			
		
	
		
			
				
					 *  @ param  num  -  button  number  1 - 5   
			
		
	
		
			
				
					 *  @ param  str  -  button  text   
			
		
	
		
			
				
					 */   
			
		
	
		
			
				
					void  ICACHE_FLASH_ATTR  
			
		
	
		
			
				
					screen_set_button_message ( int  num ,  const  char  * msg )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						NOTIFY_LOCK ( ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( num  > =  1  & &  num  < =  TERM_BTN_COUNT )  {   
			
		
	
		
			
				
							char  * buf  =  TERM_BM_N ( & termconf_live ,  num  -  1 ) ;   
			
		
	
		
			
				
							strncpy ( buf ,  msg ,  TERM_BTN_MSG_LEN ) ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
						else  ansi_warn ( " Bad button num: %d " ,  num ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						NOTIFY_DONE ( TOPIC_CHANGE_BUTTONS ) ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					/**
  
			
		
	
		
			
				
					 *  Helper  function  to  set  terminal  button  label   
			
		
	
		
			
				
					 *  @ param  num  -  button  number  1 - 5   
			
		
	
		
			
				
					 *  @ param  str  -  button  text   
			
		
	
		
			
				
					 */   
			
		
	
		
			
				
					void  ICACHE_FLASH_ATTR  
			
		
	
		
			
				
					screen_set_button_color ( int  num ,  const  char  * buf )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						NOTIFY_LOCK ( ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( num  > =  1  & &  num  < =  TERM_BTN_COUNT )   {   
			
		
	
		
			
				
							u32  * fieldptr  =  & termconf_live . bc1  +  ( num - 1 ) ;   
			
		
	
		
			
				
							xset_term_color ( " " ,  fieldptr ,  buf ,  NULL ) ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
						else  ansi_warn ( " Bad button num: %d " ,  num ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						NOTIFY_DONE ( TOPIC_CHANGE_BUTTONS ) ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					/**
  
			
		
	
		
			
				
					 *  Set  button  count   
			
		
	
		
			
				
					 *  @ param  count  -  count  1 - 5   
			
		
	
		
			
				
					 */   
			
		
	
		
			
				
					void  ICACHE_FLASH_ATTR  
			
		
	
		
			
				
					screen_set_button_count ( int  count )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						NOTIFY_LOCK ( ) ;   
			
		
	
		
			
				
						if  ( count  > =  0  & &  count  < =  5 )  {   
			
		
	
		
			
				
							dbg ( " %d  " ,  count ) ;   
			
		
	
		
			
				
							termconf_live . button_count  =  ( u8 )  count ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
						else  ansi_warn ( " Bad button count: %d " ,  count ) ;   
			
		
	
		
			
				
						strncpy ( termconf_live . btn [ num - 1 ] ,  text ,  TERM_BTN_LEN ) ;   
			
		
	
		
			
				
						NOTIFY_DONE ( TOPIC_CHANGE_BUTTONS ) ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					/**
  
			
		
	
		
			
				
					 *  Helper  function  to  set  terminalbackdrop   
			
		
	
		
			
				
					 *  @ param  url  -  url   
			
		
	
		
			
				
					 */   
			
		
	
		
			
				
					void  ICACHE_FLASH_ATTR  
			
		
	
		
			
				
					screen_set_backdrop ( const  char  * url )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						NOTIFY_LOCK ( ) ;   
			
		
	
		
			
				
						strncpy ( termconf_live . backdrop ,  url ,  TERM_BACKDROP_LEN ) ;   
			
		
	
		
			
				
						NOTIFY_DONE ( TOPIC_CHANGE_BACKDROP ) ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					/**
  
			
		
	
		
			
				
					 *  Shift  screen  upwards   
			
		
	
		
			
				
					 */   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -1361,9 +1019,6 @@ screen_scroll_up(unsigned int lines) 
			
		
	
		
			
				
						if  ( lines  > =  RH )  {   
			
		
	
		
			
				
							// clear entire region
   
			
		
	
		
			
				
							clear_range_utf ( TOP  *  W ,  ( BTM  +  1 )  *  W  -  1 ) ;   
			
		
	
		
			
				
							for  ( int  i  =  TOP ;  i  < =  BTM ;  i + + )  {   
			
		
	
		
			
				
								scr . line_attribs [ i ]  =  0 ;   
			
		
	
		
			
				
							}   
			
		
	
		
			
				
							goto  done ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -1376,18 +1031,14 @@ screen_scroll_up(unsigned int lines) 
			
		
	
		
			
				
						for  ( y  =  TOP ;  y  < =  BTM  -  lines ;  y + + )  {   
			
		
	
		
			
				
							utf_free_row ( y ) ;   
			
		
	
		
			
				
							copy_row ( y ,  y + lines ) ;   
			
		
	
		
			
				
							scr . line_attribs [ y ]  =  scr . line_attribs [ y + lines ] ;   
			
		
	
		
			
				
							if  ( y  <  BTM  -  lines )  utf_backup_row ( y ) ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						clear_range_noutf ( y  *  W ,  ( BTM  +  1 )  *  W  -  1 ) ;   
			
		
	
		
			
				
						for  ( int  i  =  y ;  i  < =  BTM ;  i + + )  {   
			
		
	
		
			
				
							scr . line_attribs [ i ]  =  0 ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					done :  
			
		
	
		
			
				
						expand_dirty ( TOP ,  BTM ,  0 ,  W  -  1 ) ;   
			
		
	
		
			
				
						NOTIFY_DONE ( TOPIC_CHANGE_CONTENT_PART | TOPIC_DOUBLE_LINES ) ;   
			
		
	
		
			
				
						NOTIFY_DONE ( TOPIC_CHANGE_CONTENT_PART ) ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					/**
  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -1400,9 +1051,6 @@ screen_scroll_down(unsigned int lines) 
			
		
	
		
			
				
						if  ( lines  > =  RH )  {   
			
		
	
		
			
				
							// clear entire region
   
			
		
	
		
			
				
							clear_range_utf ( TOP  *  W ,  ( BTM  +  1 )  *  W  -  1 ) ;   
			
		
	
		
			
				
							for  ( int  i  =  TOP ;  i  < =  BTM ;  i + + )  {   
			
		
	
		
			
				
								scr . line_attribs [ i ]  =  0 ;   
			
		
	
		
			
				
							}   
			
		
	
		
			
				
							goto  done ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -1415,17 +1063,13 @@ screen_scroll_down(unsigned int lines) 
			
		
	
		
			
				
						for  ( y  =  BTM ;  y  > =  TOP + lines ;  y - - )  {   
			
		
	
		
			
				
							utf_free_row ( y ) ;   
			
		
	
		
			
				
							copy_row ( y ,  y - lines ) ;   
			
		
	
		
			
				
							scr . line_attribs [ y ]  =  scr . line_attribs [ y - lines ] ;   
			
		
	
		
			
				
							if  ( y  >  TOP  +  lines )  utf_backup_row ( y ) ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						clear_range_noutf ( TOP  *  W ,  ( TOP  +  lines )  *  W  -  1 ) ;   
			
		
	
		
			
				
						for  ( int  i  =  TOP ;  i  <  TOP  +  lines ;  i + + )  {   
			
		
	
		
			
				
							scr . line_attribs [ i ]  =  0 ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
						clear_range_noutf ( TOP  *  W ,  TOP  *  W  +  lines  *  W  -  1 ) ;   
			
		
	
		
			
				
					done :  
			
		
	
		
			
				
						expand_dirty ( TOP ,  BTM ,  0 ,  W  -  1 ) ;   
			
		
	
		
			
				
						NOTIFY_DONE ( TOPIC_CHANGE_CONTENT_PART | TOPIC_DOUBLE_LINES ) ;   
			
		
	
		
			
				
						NOTIFY_DONE ( TOPIC_CHANGE_CONTENT_PART ) ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					/** Set scrolling region */  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -1458,7 +1102,7 @@ void ICACHE_FLASH_ATTR 
			
		
	
		
			
				
					screen_cursor_shape ( enum  CursorShape  shape )  
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						NOTIFY_LOCK ( ) ;   
			
		
	
		
			
				
						if  ( shape  = =  CURSOR_DEFAULT )  shape  =  ( enum  CursorShape )  termconf - > cursor_shape ;   
			
		
	
		
			
				
						if  ( shape  = =  CURSOR_DEFAULT )  shape  =  termconf - > cursor_shape ;   
			
		
	
		
			
				
						termconf_live . cursor_shape  =  shape ;   
			
		
	
		
			
				
						NOTIFY_DONE ( TOPIC_CHANGE_SCREEN_OPTS ) ;   
			
		
	
		
			
				
					}  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -1530,9 +1174,6 @@ screen_cursor_set_x(int x) 
			
		
	
		
			
				
						// hanging happens when the cursor is virtually at col=81, which
   
			
		
	
		
			
				
						// cannot be set using the cursor-set commands.
   
			
		
	
		
			
				
						cursor . hanging  =  false ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( IS_DOUBLE_WIDTH ( )  & &  cursor . x  > =  W / 2 )  cursor . x  =  W / 2 - 1 ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						NOTIFY_DONE ( TOPIC_CHANGE_CURSOR ) ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -1577,7 +1218,6 @@ screen_cursor_move(int dy, int dx, bool scroll) 
			
		
	
		
			
				
						cursor . x  + =  dx ;   
			
		
	
		
			
				
						cursor . y  + =  dy ;   
			
		
	
		
			
				
						if  ( cursor . x  > =  ( int ) W )  cursor . x  =  W  -  1 ;   
			
		
	
		
			
				
						if  ( IS_DOUBLE_WIDTH ( )  & &  cursor . x  > =  W / 2 )  cursor . x  =  W / 2 - 1 ;   
			
		
	
		
			
				
						if  ( cursor . x  <  ( int ) 0 )  {   
			
		
	
		
			
				
							if  ( cursor . auto_wrap  & &  cursor . reverse_wrap )  {   
			
		
	
		
			
				
								// this is mimicking a behavior from xterm that allows any number of steps backwards with reverse wraparound enabled
   
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -1684,8 +1324,6 @@ screen_cursor_restore(bool withAttrs) 
			
		
	
		
			
				
							}   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( IS_DOUBLE_WIDTH ( )  & &  cursor . x  > =  W / 2 )  cursor . x  =  W / 2 - 1 ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						NOTIFY_DONE ( TOPIC_CHANGE_CURSOR ) ;   
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -1699,7 +1337,7 @@ screen_back_index(int count) 
			
		
	
		
			
				
							cursor . x  =  new_x ;   
			
		
	
		
			
				
						}  else  {   
			
		
	
		
			
				
							cursor . x  =  0 ;   
			
		
	
		
			
				
							screen_insert_characters ( ( unsigned  int )  - new_x ) ;   
			
		
	
		
			
				
							screen_insert_characters ( - new_x ) ;   
			
		
	
		
			
				
							topics  | =  TOPIC_CHANGE_CONTENT_PART ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
						NOTIFY_DONE ( topics ) ;   
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -1891,7 +1529,7 @@ do_save_private_opt(int n, bool save) 
			
		
	
		
			
				
					{  
			
		
	
		
			
				
						ScreenNotifyTopics  topics  =  TOPIC_INTERNAL ;   
			
		
	
		
			
				
						if  ( ! save )  NOTIFY_LOCK ( ) ;   
			
		
	
		
			
				
					# define SAVE_RESTORE(sf, of) do { if (save) ( sf) =(of); else ( of) =(sf); } while(0)  
			
		
	
		
			
				
					# define SAVE_RESTORE(sf, of) do { if (save) sf=(of); else of=(sf); } while(0)  
			
		
	
		
			
				
						switch  ( n )  {   
			
		
	
		
			
				
							case  1 :   
			
		
	
		
			
				
								SAVE_RESTORE ( opt_backup . cursors_alt_mode ,  scr . cursors_alt_mode ) ;   
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -2054,10 +1692,6 @@ putchar_graphic(const char *ch) 
			
		
	
		
			
				
							cursor . hanging  =  true ;  // hanging - next typed char wraps around, but backspace and arrows still stay on the same line.
   
			
		
	
		
			
				
							cursor . x  =  W  -  1 ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
						if  ( IS_DOUBLE_WIDTH ( )  & &  cursor . x  > =  W / 2 )  {   
			
		
	
		
			
				
							cursor . hanging  =  true ;  // hanging
   
			
		
	
		
			
				
							cursor . x  =  W / 2  -  1 ;   
			
		
	
		
			
				
						}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						NOTIFY_DONE ( topics ) ;   
			
		
	
		
			
				
						return  ch ;   
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -2257,15 +1891,6 @@ screenSerializeToBuffer(char *buffer, size_t buf_len, ScreenNotifyTopics topics, 
			
		
	
		
			
				
							bufput_utf8 ( ( num ) ) ;  \
  
			
		
	
		
			
				
						}  while ( 0 )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					# define bufput_color_utf8(c) do { \  
			
		
	
		
			
				
							if  ( ( c )  <  256 )  {  \
  
			
		
	
		
			
				
								bufput_utf8 ( c ) ;  \
  
			
		
	
		
			
				
							}  else  {  \
  
			
		
	
		
			
				
								bufput_utf8 ( ( ( ( c ) - 256 ) & 0xFFF )  |  0x10000 ) ;  \
  
			
		
	
		
			
				
								bufput_utf8 ( ( ( ( c ) - 256 ) > > 12 ) & 0xFFF ) ;  \
  
			
		
	
		
			
				
							}  \
  
			
		
	
		
			
				
						}  while ( 0 )   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// tags for screen serialization
   
			
		
	
		
			
				
					# define SEQ_TAG_SKIP '\x01'  
			
		
	
		
			
				
					# define SEQ_TAG_REPEAT '\x02'  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -2276,15 +1901,12 @@ screenSerializeToBuffer(char *buffer, size_t buf_len, ScreenNotifyTopics topics, 
			
		
	
		
			
				
					# define SEQ_TAG_ATTRS_0 '\x07'  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					# define TOPICMARK_SCREEN_OPTS 'O'  
			
		
	
		
			
				
					# define TOPICMARK_STATIC_OPTS 'P'  
			
		
	
		
			
				
					# define TOPICMARK_TITLE   'T'  
			
		
	
		
			
				
					# define TOPICMARK_BUTTONS 'B'  
			
		
	
		
			
				
					# define TOPICMARK_DEBUG   'D'  
			
		
	
		
			
				
					# define TOPICMARK_BELL    '!'  
			
		
	
		
			
				
					# define TOPICMARK_CURSOR  'C'  
			
		
	
		
			
				
					# define TOPICMARK_SCREEN   'S'  
			
		
	
		
			
				
					# define TOPICMARK_BACKDROP 'W'  
			
		
	
		
			
				
					# define TOPICMARK_DBL_LINE 'H'  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( ss  = =  NULL )  {   
			
		
	
		
			
				
							// START!
   
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -2375,8 +1997,12 @@ screenSerializeToBuffer(char *buffer, size_t buf_len, ScreenNotifyTopics topics, 
			
		
	
		
			
				
								bufput_utf8 ( H ) ;   
			
		
	
		
			
				
								bufput_utf8 ( W ) ;   
			
		
	
		
			
				
								bufput_utf8 ( termconf_live . theme ) ;   
			
		
	
		
			
				
								bufput_color_utf8 ( termconf_live . default_fg ) ;   
			
		
	
		
			
				
								bufput_color_utf8 ( termconf_live . default_bg ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								bufput_utf8 ( termconf_live . default_fg  &  0xFFFF ) ;   
			
		
	
		
			
				
								bufput_utf8 ( ( termconf_live . default_fg  > >  16 )  &  0xFFFF ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								bufput_utf8 ( termconf_live . default_bg  &  0xFFFF ) ;   
			
		
	
		
			
				
								bufput_utf8 ( ( termconf_live . default_bg  > >  16 )  &  0xFFFF ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								bufput_utf8 (   
			
		
	
		
			
				
									( scr . cursor_visible  < <  0 )  |   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -2395,79 +2021,28 @@ screenSerializeToBuffer(char *buffer, size_t buf_len, ScreenNotifyTopics topics, 
			
		
	
		
			
				
								) ;   
			
		
	
		
			
				
							END_TOPIC   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							BEGIN_TOPIC ( TOPIC_CHANGE_STATIC_OPTS ,  110 )   
			
		
	
		
			
				
								bufput_c ( TOPICMARK_STATIC_OPTS ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								size_t  len  =  strlen ( termconf_live . font_stack ) ;   
			
		
	
		
			
				
								if  ( len  >  0 )  {   
			
		
	
		
			
				
									memcpy ( bb ,  termconf_live . font_stack ,  len ) ;   
			
		
	
		
			
				
									bb  + =  len ;   
			
		
	
		
			
				
									remain  - =  len ;   
			
		
	
		
			
				
								}   
			
		
	
		
			
				
								bufput_c ( ' \x01 ' ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								bufput_utf8 ( termconf_live . font_size ) ;   
			
		
	
		
			
				
							END_TOPIC   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							BEGIN_TOPIC ( TOPIC_DOUBLE_LINES ,  70 )   
			
		
	
		
			
				
								bufput_c ( TOPICMARK_DBL_LINE ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								int  cnt  =  0 ;   
			
		
	
		
			
				
								for  ( int  i  =  0 ;  i  <  LINE_ATTRS_COUNT ;  i + + )  {   
			
		
	
		
			
				
									if  ( scr . line_attribs [ i ]  ! =  0 )  cnt + + ;   
			
		
	
		
			
				
								}   
			
		
	
		
			
				
								bufput_utf8 ( cnt ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								for  ( int  i  =  0 ;  i  <  LINE_ATTRS_COUNT ;  i + + )  {   
			
		
	
		
			
				
									if  ( scr . line_attribs [ i ]  ! =  0 )  {   
			
		
	
		
			
				
										bufput_utf8 ( ( i  < <  3 )  |  ( scr . line_attribs [ i ] & 0 b111 ) ) ;   
			
		
	
		
			
				
									}   
			
		
	
		
			
				
								}   
			
		
	
		
			
				
							END_TOPIC   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							BEGIN_TOPIC ( TOPIC_CHANGE_TITLE ,  TERM_TITLE_LEN + 4 + 1 )   
			
		
	
		
			
				
								bufput_c ( TOPICMARK_TITLE ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								size_t  len  =  strlen ( termconf_live . title ) ;   
			
		
	
		
			
				
								if  ( len  >  0 )  {   
			
		
	
		
			
				
									memcpy ( bb ,  termconf_live . title ,  len ) ;   
			
		
	
		
			
				
									bb  + =  len ;   
			
		
	
		
			
				
									remain  - =  len ;   
			
		
	
		
			
				
								}   
			
		
	
		
			
				
								int  len  =  ( int )  strlen ( termconf_live . title ) ;   
			
		
	
		
			
				
								memcpy ( bb ,  termconf_live . title ,  len ) ;   
			
		
	
		
			
				
								bb  + =  len ;   
			
		
	
		
			
				
								remain  - =  len ;   
			
		
	
		
			
				
								bufput_c ( ' \x01 ' ) ;   
			
		
	
		
			
				
							END_TOPIC   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							BEGIN_TOPIC ( TOPIC_CHANGE_BUTTONS ,  ( TERM_BTN_LEN + 4 ) * termconf_live . button_count + 1 + 4 )   
			
		
	
		
			
				
							BEGIN_TOPIC ( TOPIC_CHANGE_BUTTONS ,  ( TERM_BTN_LEN + 4 ) * TERM_BTN_COUNT + 1 + 4 )   
			
		
	
		
			
				
								bufput_c ( TOPICMARK_BUTTONS ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								bufput_utf8 ( termconf_live . button_count ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								u32  * cp  =  & termconf_live . bc1 ;   
			
		
	
		
			
				
								for  ( int  i  =  0 ;  i  <  termconf_live . button_count ;  i + + )  {   
			
		
	
		
			
				
									uint32_t  c  =  * cp + + ;   
			
		
	
		
			
				
									bufput_color_utf8 ( c ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
									size_t  len  =  strlen ( TERM_BTN_N ( & termconf_live ,  i ) ) ;   
			
		
	
		
			
				
									if  ( len  >  0 )  {   
			
		
	
		
			
				
										memcpy ( bb ,  TERM_BTN_N ( & termconf_live ,  i ) ,  len ) ;   
			
		
	
		
			
				
										bb  + =  len ;   
			
		
	
		
			
				
										remain  - =  len ;   
			
		
	
		
			
				
									}   
			
		
	
		
			
				
									bufput_c ( ' \x01 ' ) ;   
			
		
	
		
			
				
								}   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							END_TOPIC   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							BEGIN_TOPIC ( TOPIC_CHANGE_BACKDROP ,  TERM_BACKDROP_LEN + 1 + 1 )   
			
		
	
		
			
				
								bufput_c ( TOPICMARK_BACKDROP ) ;   
			
		
	
		
			
				
								bufput_utf8 ( TERM_BTN_COUNT ) ;   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								size_t  len  =  strlen ( termconf_live . backdrop ) ;   
			
		
	
		
			
				
								if  ( len  >  0 )  {   
			
		
	
		
			
				
									memcpy ( bb ,  termconf_live . backdrop  ,  len ) ;   
			
		
	
		
			
				
								for  ( int  i  =  0 ;  i  <  TERM_BTN_COUNT ;  i + + )  {   
			
		
	
		
			
				
									int  len  =  ( int )  strlen ( termconf_live . btn [ i ] ) ;   
			
		
	
		
			
				
									memcpy ( bb ,  termconf_live . btn [ i ] ,  len ) ;   
			
		
	
		
			
				
									bb  + =  len ;   
			
		
	
		
			
				
									remain  - =  len ;   
			
		
	
		
			
				
									bufput_c ( ' \x01 ' ) ;   
			
		
	
		
			
				
								}   
			
		
	
		
			
				
								bufput_c ( ' \x01 ' ) ;   
			
		
	
		
			
				
							END_TOPIC   
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							BEGIN_TOPIC ( TOPIC_INTERNAL ,  45 )   
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -2488,8 +2063,6 @@ screenSerializeToBuffer(char *buffer, size_t buf_len, ScreenNotifyTopics topics, 
			
		
	
		
			
				
								bufput_utf8 ( cursor . charsetN ) ;   
			
		
	
		
			
				
								bufput_c ( cursor . charset0 ) ;   
			
		
	
		
			
				
								bufput_c ( cursor . charset1 ) ;   
			
		
	
		
			
				
								bufput_color_utf8 ( cursor . fg ) ;   
			
		
	
		
			
				
								bufput_color_utf8 ( cursor . bg ) ;   
			
		
	
		
			
				
								bufput_utf8 ( system_get_free_heap_size ( ) ) ;   
			
		
	
		
			
				
								bufput_utf8 ( term_active_clients ) ;   
			
		
	
		
			
				
							END_TOPIC