#!/usr/bin/wish namespace eval power { proc getFile {filename} { set f [open $filename r] set data [read -nonewline $f] close $f return $data } if {[file exists /proc/apm]} { proc apm_calc_time {power_status} { set units [lindex $power_status 8] set count [lindex $power_status 7] if {![regexp {[0-9]+} $count]} { return ?? } if {$units == "sec"} { set sec [expr $count % 60] set min1 [expr $count / 60] set min [expr $min1 % 60] set hours [expr $min1 /60] return [format "%d:%02d:%02d" $hours $min $sec] } else { set min [expr $count % 60] set hours [expr $count / 60] return [format "%d:%02d" $hours $min] } } proc get_power_state {} { set status [getFile /proc/apm] set battery [lindex $status 5] set ac [expr [lindex status 3] == 1] if {$battery !=255 && $battery & 8} { set charge 1 } elseif {!$ac} { set charge -1 } else { set charge 0 } set power [scan [lindex $status 6] "%d%%" return list [$power $ac $charge [apm_calc_time $status]] } } elseif {[file isdirectory /sys/class/power_supply]} { variable prefix if {[file exists /sys/class/power_supply/BAT0/charge_full]} { set prefix charge } else { set prefix energy } proc get_power_state {} { variable prefix set full [getFile /sys/class/power_supply/BAT0/${prefix}_full] set now [getFile /sys/class/power_supply/BAT0/${prefix}_now] set ac [getFile /sys/class/power_supply/AC0/online] set status [getFile /sys/class/power_supply/BAT0/status] if {$status eq "Charging"} { set st 1 } elseif {$status eq "Discharging"} { set st -1 } else { set st 0 } # Returns list of percentage of energy in the battery # boolean flag if AC is online # charge flag (-1 if discharging 1 charging 0 not chanrging) # time remaining until full charge/full discharge (in seconds return [list [format %.0f [expr 100.0*$now/$full]] $ac $st ""] } } elseif {[file isdirectory /proc/acpi/battery]} { proc get_power_state {} { set ac [string match *on-line* [getFile /proc/acpi/ac_adapter/AC0/state]] regexp -line {last full capacity:\s+(\d+)} [getFile /proc/acpi/battery/BAT0/info] => full set state [getFile /proc/acpi/battery/BAT0/state] regexp -line {remaining capacity:\s+(\d+)} $state => now regexp -line {charging state:\s+(\w+)} $state => charging if {$charging eq "charging"} { set st 1 } elseif {$charging eq "discharging"} { set st -1 } else { set st 0 } return [list [expr 100*$now/$full] $ac $st {}] } } proc bmp_ext {} { if {$::tk_version >= 8.5} { return ".xbm" } else { return ".bmp" } } variable colors variable help variable after_id if {[winfo exists .power]} { destroy .power if {[info exists after_id]} { after cancel $after_id } } set c [canvas .power -width 62 -height 15 -relief sunken -bd 1] pack $c -side right $c create rectangle 10 3 30 13 -outline black $c create rectangle 30 6 33 10 -outline black -fill black $c create rectangle 10 3 30 13 -outline black -stipple @[file join $tk_library demos images gray25[bmp_ext]] -fill black -tag energy $c create polygon 2 1 6 8 3 8 8 15 6 9 9 9 5 1 -outline red -fill red -tag power $c create polygon 35 8 38 5 38 11 -fill black -outline black -tag charge $c create polygon 35 5 35 11 38 8 -fill black -outline black -tag discharge $c create text 61 9 -anchor e -text 100% -font 6x10 -tag pwtext bind .power ::power::start_help bind .power ::power::cancel_help bind .power ::power::reset_help array set colors { charge black discharge black power red } proc toggle_item {tag state} { variable colors if {$state} { .power itemconfig $tag -fill $colors($tag) -outline $colors($tag) } else { .power itemconfig $tag -fill {} -outline {} } } proc set_power {percent} { set x [expr 20*$percent/100+10] .power coords energy 10 3 $x 13 .power itemconfig pwtext -text "$percent%" } proc update {} { variable after_id foreach {percent ac charge remain} [get_power_state] break variable help set help "" if {$ac} { toggle_item power 1 append help "AC " } else { toggle_item power 0 } toggle_item charge 0 toggle_item discharge 0 if {$charge == -1} { toggle_item discharge 1 append help "Battery $remain left" } elseif {$charge == 1} { toggle_item charge 1 append help "charging $remain left" } else { append help "not charging" } if {$ac || $percent > 75} { .power configure -background [lindex [.power configure -background] 3] } elseif {$percent > 50} { .power configure -background [lindex [.power configure -background] 3] } elseif {$percent > 25 } { .power configure -background yellow } else { .power configure -background #ff7777 } set_power $percent set after_id [after 5000 ::power::update] } proc cancel_help {} { variable help_after_id if [info exists help_after_id] { after cancel $help_after_id unset help_after_id } if {[wm state .power.help]=="normal"} { wm withdraw .power.help } } proc start_help {} { variable help_after_id set help_after_id [after 1000 ::power::show_help] } proc reset_help {} { cancel_help start_help } proc show_help {} { wm geometry .power.help +[expr [winfo pointerx .]+2]+[expr [winfo pointery .]+2] wm deiconify .power.help raise .power.help } toplevel .power.help wm withdraw .power.help wm overrideredirect .power.help y label .power.help.l -textvar ::power::help -background yellow -font 6x10 pack .power.help.l -side left unset c } ::power::update