Platon Technologies
not logged in Login Registration
EnglishSlovak
open source software development celebrating 10 years of open source development! Sunday, September 15, 2019

File: [Platon] / thinkpad-status / thinkpad.pl (download)

Revision 1.3, Fri Feb 16 00:25:42 2007 UTC (12 years, 7 months ago) by rajo


Changes since 1.2: +119 -26 lines

Parse basic CPU info, battery info, fan info.

#!/usr/bin/perl -w
# vim600: ts=4 fdm=marker fdl=0 fdc=3

#
# thinkpad.pl - show status of ThinkPad laptop
#
# Developed by Lubomir Host 'rajo' <rajo AT platon.sk>
# Copyright (c) 2007 Platon Group, http://platon.sk/
# Licensed under terms of GNU General Public License.
# All rights reserved.
#
# Changelog:
# 2007-02-11 - created
#

# $Platon: thinkpad-status/thinkpad.pl,v 1.2 2007-02-11 15:46:00 rajo Exp $

use strict;
use warnings;

use File::Spec; # portable path manipulations
use Gtk2 '-init'; # auto-initialize Gtk2
use Gtk2::GladeXML;
use Gtk2::SimpleList;   # easy wrapper for list views
use Gtk2::Gdk::Keysyms; # keyboard code constants
use Data::Dumper;
use English;
use Time::HiRes qw( gettimeofday );
use POSIX qw(strftime);

use vars qw (
    $glade
    $x_mainwin $x_status $x_preferences $x_about
    $x_refresh_interval

    $glib_refresh $refresh_interval $default_update_interval

    $x_cpu_scaling_driver $cpu_scaling_driver
    $x_cpu_scaling_governor $cpu_scaling_governor

    $xx_battery $x_battery @battery
    $xx_thermals $x_thermals @thermals
    $xx_fan $x_fan @fan
);

$default_update_interval = 1; # 1 second

# Load the UI from the Glade-2 file
my $data = <DATA>;
if ($data !~ m/^\s*<\?xml/m) {
    $glade = Gtk2::GladeXML->new("thinkpad.glade");
}
else {
    $glade = Gtk2::GladeXML->new_from_buffer($data);
}

# Connect signals magically
$glade->signal_autoconnect_from_package('main');

init_gui();

Gtk2->main; # Start Gtk2 main loop

exit 0;

sub init_gui
{ # {{{

    # connect a few widgets we'll access frequently

    $x_mainwin = $glade->get_widget('main');
    $x_status = $glade->get_widget('statusbar');
    $x_preferences = $glade->get_widget('preferences');
    $x_about = $glade->get_widget('about');

    # refresh interval
    $x_refresh_interval = $glade->get_widget('refresh_interval');

    # CPU {{{
    $x_cpu_scaling_driver = $glade->get_widget('cpu_scaling_driver');
    $cpu_scaling_driver = grab_data('/sys/devices/system/cpu/cpu0/cpufreq/scaling_driver');

    $x_cpu_scaling_governor = $glade->get_widget('cpu_scaling_governor');
    $cpu_scaling_governor = grab_data('/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor');

    # }}}

    # battery # {{{
    $xx_battery = $glade->get_widget('battery');
    $x_battery = Gtk2::SimpleList->new_from_treeview(
        $xx_battery,
        'Param'    => 'text',
        'Value'    => 'text',
    );
    # set some useful SimpleList properties
    $x_battery->set_headers_clickable(0);
    foreach ($x_battery->get_columns()) {
        $_->set_resizable(1);
        $_->set_sizing('grow-only');
    }
    # }}}

    # thermal # {{{
    $xx_thermals = $glade->get_widget('thermals');
    $x_thermals = Gtk2::SimpleList->new_from_treeview(
        $xx_thermals,
        'Name'            => 'text',
        'Temperature'    => 'text',
    );
    # set some useful SimpleList properties
    $x_thermals->set_headers_clickable(0);
    foreach ($x_thermals->get_columns()) {
        $_->set_resizable(1);
        $_->set_sizing('grow-only');
    }
    # }}}

    # fan {{{
    $xx_fan = $glade->get_widget('fan');
    $x_fan = Gtk2::SimpleList->new_from_treeview(
        $xx_fan,
        'Param'    => 'text',
        'Value'    => 'text',
    );
    # set some useful SimpleList properties
    $x_fan->set_headers_clickable(0);
    foreach ($x_fan->get_columns()) {
        $_->set_resizable(1);
        $_->set_sizing('grow-only');
    }
    # }}}

    # set up a 'refresh' timer
    $x_refresh_interval->set_text($default_update_interval);
    update_timer($default_update_interval);

    make_refresh();

} # }}}

sub make_refresh()
{ # {{{
    print_info("make_refresh() called");

    refresh_cpu();
    refresh_battery();
    refresh_thermal();
    refresh_fan();
    
    return 1;

} # }}}

# refresh data for tab 'CPU'
sub refresh_cpu()
{ # {{{

    $cpu_scaling_driver = grab_data('/sys/devices/system/cpu/cpu0/cpufreq/scaling_driver');
    $x_cpu_scaling_driver->set_text($cpu_scaling_driver);

    $cpu_scaling_governor = grab_data('/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor');
    $x_cpu_scaling_governor->set_text($cpu_scaling_governor);

} # }}}

# refresh data for tab 'Battery'
sub refresh_battery()
{ # {{{

    grab_data_by_colon('/proc/acpi/battery/BAT0/state', $x_battery->{data});

} # }}}

# refresh data for tab 'Thermal'
sub refresh_thermal()
{ # {{{
    @{$x_thermals->{data}} = ();

    open(THERMAL, "</proc/acpi/ibm/thermal") or do { warn "Can't open /proc/acpi/ibm/thermal: $!"; return ; };
    @thermals = split(/\s+/, <THERMAL>, 9);
    shift @thermals; # remove description
    close (THERMAL);

    # http://www.thinkwiki.org/wiki/Thermal_sensors
    foreach my $desc ('Processor', 'Mini-PCI', 'Harddisk',  'Graphics', 'System battery', 'UltraBay battery', 'System battery', 'UltraBay battery') {
        push @{$x_thermals->{data}}, [$desc, shift(@thermals)];
    }

} # }}}

# refresh data for tab 'Fan'
sub refresh_fan()
{ # {{{

    grab_data_by_colon('/proc/acpi/ibm/fan', $x_fan->{data});

} # }}}

sub grab_data($)
{ # {{{
    my ($file) = @_;
    my $data;

    open(FILE, "<$file") or do { warn  "Can't open '$file': $!"; return; };
    {
        local $/;
        $data = <FILE>;
    }
    close(FILE);

    $data =~ s/[^\p{IsPrint}]//g;

    return $data;

} # }}}

sub grab_data_by_colon($$)
{ # {{{
    my ($file, $arr) = @_;
    @$arr = ();

    open(COLON, "<$file") or do { warn  "Can't open '$file': $!"; return; };
    while (my $line = <COLON>) {
        chomp $line;
        my ($name, $val) = split(/:\s+/, $line, 2);
        push @{$arr}, [$name, $val];
    }
    close(COLON);

} # }}}

sub update_timer($)
{ # {{{
    my ($delay) = @_;
    return unless $delay; # avoid setting interval to 0
    if (defined $glib_refresh) {
        Glib::Source->remove($glib_refresh);
    }
    print_info("update_timer( $delay )");
    $glib_refresh = Glib::Timeout->add(1000 * $delay, \&make_refresh);

} # }}}

# Refresh interval in preferences
sub on_refresh_interval_value_changed
{ # {{{
    my $w = shift; 
    update_timer($w->get_text());
} # }}}

sub print_info($;@)
{ # {{{
    my ($info, @text) = @_;

    printf "[%s PID = $PID ] $0: %s", cur_date(), $info;
    print @text if (scalar(@text) > 0);
    print "\r\n";

} # }}}

sub cur_date()
{ # {{{
    my ($sec, $msec) = Time::HiRes::gettimeofday;
    my $time_string = strftime("%Y-%m-%d %X", localtime) . sprintf('.%04d', $msec / 1E4);

    return $time_string;
} # }}}

# Glade 2 basic handlers {{{
#----------------------------------------------------------------------
# Signal handlers to match signals defined using Glade-2
#----------------------------------------------------------------------

# Some very simple handlers

sub on_quit_activate {Gtk2->main_quit;}
sub on_prefs_button_clicked {$x_preferences->show_all;}
sub on_preferences_activate {$x_preferences->show_all;}
sub on_about_activate {$x_about->show_all;}
sub on_main_delete_event {Gtk2->main_quit;}
sub on_prefs_cancelbutton_clicked {$x_preferences->hide;}
sub on_about_okbutton_clicked {$x_about->hide;}

#----------------------------------------------------------------------
# Handle dialog 'close' (window-decoration induced close)
#   * Just hide the dialog, and tell Gtk not to do anything else
#
sub on_dialog_delete_event {
    my $w = shift; 
    $w->hide; 
    1; # consume this event!
}

#----------------------------------------------------------------------
# Handle preferencess apply click
#
sub on_prefs_applybutton_clicked {
    my $x_context = $x_status->get_context_id('Main');
    $x_status->push($x_context, 'Preferences updated');
}
    
#----------------------------------------------------------------------
# Handle prefs ok click (apply/dismiss dialog)
#
sub on_prefs_okbutton_clicked {
    on_prefs_applybutton_clicked();
    $x_preferences->hide;
}

# }}}

__DATA__

Platon Group <platon@platon.org> http://platon.org/
Copyright © 2002-2006 Platon Group
Site powered by Metafox CMS
Go to Top