Monday, August 04, 2008

autoglade

This document can be read in Google Docs (http://docs.google.com/Edit?tab=view&docid=ddwc44gs_458qnjwvgr)


Introduction

This article will guide you through the steps needed to provide a graphical user interface (GUI) to some commands requiring almost no programming using autoglade.

As a real life example we will be using some commands to control cpu frequency scaling in Asus EeePC.
EeePC features a Celeron-M (4G) with On Demand Frequency Modulation (ODFM) originally set to performance, which actually disables ODFM and fixes CPU speed to 900 MHz (or 630 MHz, as it's underclocked in BIOS prior to 8804).

From some post in eeeuser forum:
"The cpu in the EEE consumes the same wattage running idle at 900mhz(630 real) as it does running idle at the 'scaled' frequency of 112.5mhz, because the actual frequency *does not change* it's just the forced execution of halt instructions. Halt instructions do save power; when a halt instruction is executed the cpu gets a bit of 'rest' where it consumes significantly less power than if it was executing a complex SSE2 instruction."

ODFM additionally provides ondemand mode. Available governors can be obtained using this command
$ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors
ondemand performance
current scaling governor can be obtained with
$ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
performance
as well as maximum allowed frequency
$ cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq
900000
While it's not completely clear if you can save some power and extend battery life using ondemand scaling or limiting the maximum frequency, we will be using this example to create a GUI around these commands and you can test for yourself. Anyway, our final objective is the creation of the GUI and analyzing the patterns used in order to be able to reproduce this with other commands lacking a GUI.

autoglade

autoglade is a tool that will take our GUI design and will automate most common usage patterns to be able to give the GUI functionality with no programming.

Design the GUI

We will be using another computer to design the GUI where glade user interface builder version 3 is installed. There's nothing wrong installing glade-3 on the EeePC, but the screen would be too small to confortably design the interface and you may need an external monitor.
glade-3 it's available for Linux and Windows, and because the GUI is described as an XML file it's platform independent.

This is an overview of the GUI, in this particular case using glade-3 on Windows Vista
our expanded widget tree should be something like this.

We can see some widget that have been highlighted. These widgets have received special names.

This is one of the way that autoglade uses to receive some messages from our design. Let's review them.
We have an horizontal scale widget whose name is freq:auto:init:env, that is our widget name is freq, because we are going to change the cpu frequency using it and we ask autoglade (auto) to initialize it (init) using the process environment (env) and by default autoglade will look for a variable named after the widget name (freq). Its value will be taken form the environment upon startup and the horizontal scale will be initialized having this value.

Next, we have two radio buttons to set the scaling governor to performance or ondemand.
Radio buttons are named as an incremental sequence, for example name1, name2, name3, ..., namen. In this particular case the name is governor.
In all but the first one we have to set the group property to be able to operate them as a group, that is only one can be active at a time.
As explained before the names are governor1:auto:init:env and governor2:auto:init:env, because they are the first (1) and second (2) radio buttons of the group, and we ask autoglade (auto) to initinalize (init) them using the process environment (env). In this case the variable will be governor and depending on its value (performance or ondemand) the corresponding radio will be activated on startup.

We need to send a message to autoglade to tell it how do we want to exit the event loop and thus closing the dialog and passing a value to its parent process. We do this by setting the response ID on OK and Cancel buttons to RESPONSE_OK (-5) and RESPONSE_CANCEL (-6).

Running with autoglade

Let's save it as cpufreq.glade and we are ready to test it.
$ autoglade cpufreq.glade
and most of the required behavior of our GUI is already there.

Specifying initial values

You can specify the initial value for frequency
$ freq=500 autoglade cpufreq.glade
or for both frequency and governor
$ freq=130 governor=ondemand autoglade cpufreq.glade

Obtaining return values

Running autoglade in one of the previously mentioned froms will give us these results
freq='225'
governor='ondemand'
autoargs='$freq $governor'
to standard output with the values we have selected in the GUI.

Shell wrapper

We are now in condition of putting everything togheter with a shell wrapper script.
Let's start with a simple one and then we can add more sophisticated features.
#! /bin/bash

AUTOGLADE=autoglade # set absolute path if autoglade is not installed

CPUFREQDIR=/sys/devices/system/cpu/cpu0/cpufreq

freq()
{
# get or set freqency
local F=$CPUFREQDIR/scaling_max_freq
local S=1000

[ -n "$1" ] && echo $(( $1 * $S )) > $F || export freq=$(( $(< $F) / $S ))
}

governor()
{
# get or set governor
local F=$CPUFREQDIR/scaling_governor

[ -n "$1" ] && echo "$1" > $F || export governor=$(< $F)
}

freq
governor

DUMP=$( $AUTOGLADE cpufreq.glade )
if [ $? -eq 0 ]
then
eval "$DUMP"
freq $freq
governor $governor
fi


Previous wrapper illustrates various common patterns.
Next time, we will be using more advanced features to finish our cpufreq application.