--- /dev/null
+#!/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 {}]
+ }
+}
+ 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] -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 <Enter> ::power::start_help
+ bind .power <Leave> ::power::cancel_help
+ bind .power <Motion> ::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