#!/usr/bin/perl

# This script is kinda extendable, but not completely.  It assumes one 
# CPU with freq control in /sys and throttling control in /proc.  It 
# also ignores throttling level 7, because on my laptop, for some 
# reason, level 7 locks the computer up hard.  The presets make certain
# assumptions too (2 freq controls, 8-ish throttling controls).

use Glib qw(TRUE FALSE);
use Gtk2;

sub button_cb {
  my($button, $info) = @_;
  $bpressed = $button->get_label();
  if($bpressed eq "Full") {
    $info->{bbox_freq}->{cbox_freq}->set_active(0);
    $info->{bbox_thr}->{cbox_thr}->set_active(0);
  } elsif($bpressed eq "Half") {
    $info->{bbox_freq}->{cbox_freq}->set_active(1);
    $info->{bbox_thr}->{cbox_thr}->set_active(0);
  } elsif($bpressed eq "Quarter") {
    $info->{bbox_freq}->{cbox_freq}->set_active(1);
    $info->{bbox_thr}->{cbox_thr}->set_active(4);
  }
}

sub response_cb {
  my ($dialog, $response_id, $info) = @_;
  if (($response_id eq 'ok') || ($response_id eq 'apply')) {
    $freq = $info->{bbox_freq}->{cbox_freq}->get_active_text();
    $thr = $info->{bbox_thr}->{cbox_thr}->get_active();
    open(FILE, "> /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq");
    print FILE "$freq";
    close(FILE);
    open(FILE, "> /proc/acpi/processor/CPU0/throttling");
    print FILE "$thr";
    close(FILE);
    if($response_id eq 'ok') {
      Gtk2->main_quit;
    }
  } else {
    Gtk2->main_quit;
  }
}

Gtk2->init;

$info->{bbox_freq} = Gtk2::HButtonBox->new;
$info->{bbox_freq}->set_border_width(5);
$info->{bbox_freq}->add(Gtk2::Label->new("CPU Frequency"));
$info->{bbox_freq}->{cbox_freq} = Gtk2::ComboBox->new_text;
open(FILE, "/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies");
$fileline = <FILE>;
close(FILE);
chomp $fileline;
@freqs = split(/ /, $fileline);
open(FILE, "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq");
$curfreq = <FILE>;
close(FILE);
chomp $curfreq;
$i = 0;
foreach $freq (@freqs) {
  $info->{bbox_freq}->{cbox_freq}->append_text($freq);
  if($freq eq $curfreq) {
    $info->{bbox_freq}->{cbox_freq}->set_active($i);
  }
  $i++;
}
$info->{bbox_freq}->add($info->{bbox_freq}->{cbox_freq});

$info->{bbox_thr} = Gtk2::HButtonBox->new;
$info->{bbox_thr}->set_border_width(5);
$info->{bbox_thr}->add(Gtk2::Label->new("CPU Throttling"));
$info->{bbox_thr}->{cbox_thr} = Gtk2::ComboBox->new_text;
open(FILE, "/proc/acpi/processor/CPU0/throttling");
while($linein = <FILE>) {
  chomp $linein;
  #   *T0:                  00%
  if($linein =~ /^\s+(.*?)T(\d+):\s+(\d+)\%/) {
    $ast = $1;
    $numline = $2;
    $numthr = $3;
    next if($numline eq "7");
    $info->{bbox_thr}->{cbox_thr}->append_text("$numthr%");
    if($ast eq "*") {
      $info->{bbox_thr}->{cbox_thr}->set_active($numline);
    }
  }
}
$info->{bbox_thr}->add($info->{bbox_thr}->{cbox_thr});

$info->{bbox_common} = Gtk2::HButtonBox->new;
$info->{bbox_common}->set_border_width(5);
$info->{bbox_common}->{full} = Gtk2::Button->new('Full');
$info->{bbox_common}->{full}->signal_connect (clicked => \&button_cb, $info);
$info->{bbox_common}->add($info->{bbox_common}->{full});
$info->{bbox_common}->{half} = Gtk2::Button->new('Half');
$info->{bbox_common}->{half}->signal_connect (clicked => \&button_cb, $info);
$info->{bbox_common}->add($info->{bbox_common}->{half});
$info->{bbox_common}->{quarter} = Gtk2::Button->new('Quarter');
$info->{bbox_common}->{quarter}->signal_connect (clicked => \&button_cb, $info);
$info->{bbox_common}->add($info->{bbox_common}->{quarter});

my $window = Gtk2::Dialog->new("CPU Manipulate", undef, 'no-separator', 'gtk-cancel' => 'cancel', 'gtk-ok' => 'ok', 'gtk-apply' => 'apply');
$window->signal_connect (destroy => \&response_cb, $info);
$window->signal_connect (response => \&response_cb, $info);
$window->vbox->pack_start ($info->{bbox_common}, TRUE, TRUE, 0);
$window->vbox->pack_start ($info->{bbox_freq}, TRUE, TRUE, 0);
$window->vbox->pack_start ($info->{bbox_thr}, TRUE, TRUE, 0);

$window->show_all;
Gtk2->main;
