@@ -5,7 +5,9 @@ use std::{
55 unix:: { io:: { AsFd , BorrowedFd , OwnedFd } , fs:: OpenOptionsExt }
66 } ,
77 path:: { Path , PathBuf } ,
8- collections:: HashMap
8+ collections:: HashMap ,
9+ time:: Instant ,
10+ io:: Write
911} ;
1012use cairo:: {
1113 ImageSurface , Format , Context , Surface ,
@@ -48,7 +50,7 @@ impl ControlDevice for Card {}
4850impl DrmDevice for Card { }
4951
5052impl Card {
51- fn open ( path : PathBuf ) -> Self {
53+ fn open ( path : & Path ) -> Self {
5254 let mut options = OpenOptions :: new ( ) ;
5355 options. read ( true ) ;
5456 options. write ( true ) ;
@@ -80,7 +82,7 @@ struct FunctionLayer {
8082}
8183
8284impl FunctionLayer {
83- fn draw ( & self , surface : & Surface , active_buttons : & [ bool ] , dim : f64 ) {
85+ fn draw ( & self , surface : & Surface , active_buttons : & [ bool ] ) {
8486 let c = Context :: new ( & surface) . unwrap ( ) ;
8587 c. translate ( DFR_HEIGHT as f64 , 0.0 ) ;
8688 c. rotate ( ( 90.0f64 ) . to_radians ( ) ) ;
@@ -92,11 +94,11 @@ impl FunctionLayer {
9294 c. set_font_size ( 24.0 ) ;
9395 for ( i, button) in self . buttons . iter ( ) . enumerate ( ) {
9496 let left_edge = i as f64 * ( button_width + spacing_width) + spacing_width;
95- let color = ( if active_buttons[ i] { BUTTON_COLOR_ACTIVE } else { BUTTON_COLOR_INACTIVE } ) * dim ;
97+ let color = if active_buttons[ i] { BUTTON_COLOR_ACTIVE } else { BUTTON_COLOR_INACTIVE } ;
9698 c. set_source_rgb ( color, color, color) ;
9799 c. rectangle ( left_edge, 0.09 * DFR_HEIGHT as f64 , button_width, 0.82 * DFR_HEIGHT as f64 ) ;
98100 c. fill ( ) . unwrap ( ) ;
99- c. set_source_rgb ( dim , dim , dim ) ;
101+ c. set_source_rgb ( 1.0 , 1.0 , 1.0 ) ;
100102 let extents = c. text_extents ( & button. text ) . unwrap ( ) ;
101103 c. move_to (
102104 left_edge + button_width / 2.0 - extents. width ( ) / 2.0 ,
@@ -122,7 +124,7 @@ fn find_prop_id<T: ResourceHandle>(
122124 return Err ( anyhow ! ( "Property not found" ) ) ;
123125}
124126
125- fn try_open_card ( path : PathBuf ) -> Result < DrmBackend > {
127+ fn try_open_card ( path : & Path ) -> Result < DrmBackend > {
126128 let card = Card :: open ( path) ;
127129 card. set_client_capability ( ClientCapability :: UniversalPlanes , true ) ?;
128130 card. set_client_capability ( ClientCapability :: Atomic , true ) ?;
@@ -234,19 +236,35 @@ fn try_open_card(path: PathBuf) -> Result<DrmBackend> {
234236}
235237
236238fn open_card ( ) -> Result < DrmBackend > {
237- for entry in fs:: read_dir ( "/dev/dri/" ) . unwrap ( ) {
238- let entry = entry. unwrap ( ) ;
239+ for entry in fs:: read_dir ( "/dev/dri/" ) ? {
240+ let entry = entry? ;
239241 if !entry. file_name ( ) . to_string_lossy ( ) . starts_with ( "card" ) {
240242 continue
241243 }
242- match try_open_card ( entry. path ( ) ) {
244+ match try_open_card ( & entry. path ( ) ) {
243245 Ok ( card) => return Ok ( card) ,
244246 Err ( _) => { }
245247 }
246248 }
247249 Err ( anyhow ! ( "No touchbar device found" ) )
248250}
249251
252+ fn find_backlight ( ) -> Result < PathBuf > {
253+ for entry in fs:: read_dir ( "/sys/class/backlight/" ) ? {
254+ let entry = entry?;
255+ if entry. file_name ( ) . to_string_lossy ( ) . contains ( "display-pipe" ) {
256+ let mut path = entry. path ( ) ;
257+ path. push ( "brightness" ) ;
258+ return Ok ( path) ;
259+ }
260+ }
261+ Err ( anyhow ! ( "No backlight device found" ) )
262+ }
263+
264+ fn set_backlight ( path : & Path , value : u32 ) {
265+ let mut file = OpenOptions :: new ( ) . write ( true ) . open ( path) . unwrap ( ) ;
266+ file. write ( format ! ( "{}\n " , value) . as_bytes ( ) ) . unwrap ( ) ;
267+ }
250268
251269struct Interface ;
252270
@@ -309,6 +327,7 @@ fn main() {
309327 let mut button_state = vec ! [ false ; 12 ] ;
310328 let mut needs_redraw = true ;
311329 let mut drm = open_card ( ) . unwrap ( ) ;
330+ let bl_path = find_backlight ( ) . unwrap ( ) ;
312331 let mut input = Libinput :: new_with_udev ( Interface ) ;
313332 input. udev_assign_seat ( "seat0" ) . unwrap ( ) ;
314333 let pollfd = PollFd :: new ( input. as_raw_fd ( ) , PollFlags :: POLLIN ) ;
@@ -338,10 +357,12 @@ fn main() {
338357 uinput. dev_create ( ) . unwrap ( ) ;
339358 let mut digitizer: Option < InputDevice > = None ;
340359 let mut touches = HashMap :: new ( ) ;
360+ let mut last_active = Instant :: now ( ) ;
361+ let mut current_bl = 42 ;
341362 loop {
342363 if needs_redraw {
343364 needs_redraw = false ;
344- layer. draw ( & surface, & button_state, 1.0 ) ;
365+ layer. draw ( & surface, & button_state) ;
345366 let mut map = drm. card . map_dumb_buffer ( & mut drm. db ) . unwrap ( ) ;
346367 let data = surface. data ( ) . unwrap ( ) ;
347368 map. as_mut ( ) [ ..data. len ( ) ] . copy_from_slice ( & data) ;
@@ -358,6 +379,7 @@ fn main() {
358379 }
359380 } ,
360381 Event :: Touch ( te) => {
382+ last_active = Instant :: now ( ) ;
361383 if Some ( te. device ( ) ) != digitizer {
362384 continue
363385 }
@@ -405,10 +427,23 @@ fn main() {
405427 _ => { }
406428 }
407429 } ,
430+ Event :: Keyboard ( _) | Event :: Pointer ( _) => {
431+ last_active = Instant :: now ( ) ;
432+ }
408433 _ => { }
409434 }
410435 }
436+ let since_last_active = ( Instant :: now ( ) - last_active) . as_millis ( ) as u64 ;
437+ let new_bl = if since_last_active < TIMEOUT_MS as u64 {
438+ 128
439+ } else if since_last_active < TIMEOUT_MS as u64 * 2 {
440+ 1
441+ } else {
442+ 0
443+ } ;
444+ if current_bl != new_bl {
445+ current_bl = new_bl;
446+ set_backlight ( & bl_path, current_bl) ;
447+ }
411448 }
412-
413-
414449}
0 commit comments