@@ -11,18 +11,21 @@ use crate::{Adapter, Brand, Mux, TMUX, Unknown};
1111
1212#[ derive( Clone , Copy , Debug ) ]
1313pub struct Emulator {
14- pub kind : Either < Brand , Unknown > ,
15- pub light : bool ,
14+ pub kind : Either < Brand , Unknown > ,
15+ pub light : bool ,
16+ pub cell_size : Option < ( u16 , u16 ) > ,
1617}
1718
1819impl Default for Emulator {
19- fn default ( ) -> Self { Self { kind : Either :: Right ( Unknown :: default ( ) ) , light : false } }
20+ fn default ( ) -> Self {
21+ Self { kind : Either :: Right ( Unknown :: default ( ) ) , light : false , cell_size : None }
22+ }
2023}
2124
2225impl Emulator {
2326 pub fn detect ( ) -> Self {
2427 if let Some ( brand) = Brand :: from_env ( ) {
25- Self { kind : Either :: Left ( brand) , light : Self :: detect_base ( ) . unwrap_or_default ( ) . light }
28+ Self { kind : Either :: Left ( brand) , .. Self :: detect_base ( ) . unwrap_or_default ( ) }
2629 } else {
2730 Self :: detect_full ( ) . unwrap_or_default ( )
2831 }
@@ -37,6 +40,7 @@ impl Emulator {
3740 SavePosition ,
3841 Print ( Mux :: csi( "\x1b _Gi=31,s=1,v=1,a=q,t=d,f=24;AAAA\x1b \\ " ) ) , // Detect KGP
3942 Print ( Mux :: csi( "\x1b [>q" ) ) , // Request terminal version
43+ Print ( "\x1b [16t" ) , // Request cell size
4044 Print ( "\x1b ]11;?\x07 " ) , // Request background color
4145 Print ( Mux :: csi( "\x1b [0c" ) ) , // Request device attributes
4246 RestorePosition
@@ -52,7 +56,11 @@ impl Emulator {
5256 } )
5357 } ;
5458
55- Ok ( Self { kind, light : Self :: light_bg ( & resp) . unwrap_or_default ( ) } )
59+ Ok ( Self {
60+ kind,
61+ light : Self :: light_bg ( & resp) . unwrap_or_default ( ) ,
62+ cell_size : Self :: cell_size ( & resp) ,
63+ } )
5664 }
5765
5866 pub fn adapters ( self ) -> & ' static [ Adapter ] {
@@ -117,7 +125,7 @@ impl Emulator {
117125 match timeout ( Duration :: from_secs ( 10 ) , read) . await {
118126 Err ( e) => error ! ( "read_until_da1 timed out: {buf:?}, error: {e:?}" ) ,
119127 Ok ( Err ( e) ) => error ! ( "read_until_da1 failed: {buf:?}, error: {e:?}" ) ,
120- Ok ( Ok ( ( ) ) ) => { }
128+ Ok ( Ok ( ( ) ) ) => debug ! ( "read_until_da1: {buf:?}" ) ,
121129 }
122130 String :: from_utf8_lossy ( & buf) . into_owned ( )
123131 }
@@ -128,12 +136,30 @@ impl Emulator {
128136
129137 execute ! (
130138 LineWriter :: new( stderr( ) ) ,
139+ Print ( "\x1b [16t" ) , // Request cell size
131140 Print ( "\x1b ]11;?\x07 " ) , // Request background color
132141 Print ( Mux :: csi( "\x1b [0c" ) ) , // Request device attributes
133142 ) ?;
134143
135144 let resp = futures:: executor:: block_on ( Self :: read_until_da1 ( ) ) ;
136- Ok ( Self { light : Self :: light_bg ( & resp) . unwrap_or_default ( ) , ..Default :: default ( ) } )
145+ Ok ( Self {
146+ light : Self :: light_bg ( & resp) . unwrap_or_default ( ) ,
147+ cell_size : Self :: cell_size ( & resp) ,
148+ ..Default :: default ( )
149+ } )
150+ }
151+
152+ fn cell_size ( resp : & str ) -> Option < ( u16 , u16 ) > {
153+ let b = resp. split_at ( resp. find ( "\x1b [6;" ) ? + 4 ) . 1 . as_bytes ( ) ;
154+
155+ let h: Vec < _ > = b. iter ( ) . copied ( ) . take_while ( |& c| c. is_ascii_digit ( ) ) . collect ( ) ;
156+ b. get ( h. len ( ) ) . filter ( |& & c| c == b';' ) ?;
157+
158+ let w: Vec < _ > = b[ h. len ( ) + 1 ..] . iter ( ) . copied ( ) . take_while ( |& c| c. is_ascii_digit ( ) ) . collect ( ) ;
159+ b. get ( h. len ( ) + 1 + w. len ( ) ) . filter ( |& & c| c == b't' ) ?;
160+
161+ let ( w, h) = unsafe { ( String :: from_utf8_unchecked ( w) , String :: from_utf8_unchecked ( h) ) } ;
162+ Some ( ( w. parse ( ) . ok ( ) ?, h. parse ( ) . ok ( ) ?) )
137163 }
138164
139165 fn light_bg ( resp : & str ) -> Result < bool > {
0 commit comments