summaryrefslogtreecommitdiff
path: root/cpufreq/src
diff options
context:
space:
mode:
authorCarlos Garcia Campos <carlosgc@gnome.org>2004-12-24 15:07:15 +0000
committerCarlos Garcia Campos <carlosgc@src.gnome.org>2004-12-24 15:07:15 +0000
commit7da9459d91b1964ec1a2dab84f97e816cc4a5fb6 (patch)
tree46c244b9901225378c3184d738af319bd93ef077 /cpufreq/src
parentee94dc4e0a446365f23a93b478fc585f6c066424 (diff)
files added files removed rewrite the whole applet with a new code design
2004-12-24 Carlos Garcia Campos <carlosgc@gnome.org> * src/cpufreq-monitor-*.[ch]: files added * src/cpufreq.[ch]: files removed * src/*.[ch]: rewrite the whole applet with a new code design based on an object oriented model. Migrate from gnome_about o gtk_about. Some code cleanups.
Diffstat (limited to 'cpufreq/src')
-rw-r--r--cpufreq/src/Makefile.am13
-rw-r--r--cpufreq/src/cpufreq-applet.c634
-rw-r--r--cpufreq/src/cpufreq-applet.h47
-rw-r--r--cpufreq/src/cpufreq-monitor-cpuinfo.c215
-rw-r--r--cpufreq/src/cpufreq-monitor-cpuinfo.h48
-rw-r--r--cpufreq/src/cpufreq-monitor-factory.c54
-rw-r--r--cpufreq/src/cpufreq-monitor-factory.h (renamed from cpufreq/src/cpufreq.h)10
-rw-r--r--cpufreq/src/cpufreq-monitor-procfs.c348
-rw-r--r--cpufreq/src/cpufreq-monitor-procfs.h48
-rw-r--r--cpufreq/src/cpufreq-monitor-protected.h30
-rw-r--r--cpufreq/src/cpufreq-monitor-sysfs.c373
-rw-r--r--cpufreq/src/cpufreq-monitor-sysfs.h48
-rw-r--r--cpufreq/src/cpufreq-monitor.c375
-rw-r--r--cpufreq/src/cpufreq-monitor.h76
-rw-r--r--cpufreq/src/cpufreq-popup.c121
-rw-r--r--cpufreq/src/cpufreq-popup.h4
-rw-r--r--cpufreq/src/cpufreq-prefs.c78
-rw-r--r--cpufreq/src/cpufreq.c591
18 files changed, 2083 insertions, 1030 deletions
diff --git a/cpufreq/src/Makefile.am b/cpufreq/src/Makefile.am
index 8af777f02..b4577728c 100644
--- a/cpufreq/src/Makefile.am
+++ b/cpufreq/src/Makefile.am
@@ -17,10 +17,15 @@ INCLUDES = \
libexec_PROGRAMS = cpufreq-applet
cpufreq_applet_SOURCES = \
- cpufreq-applet.c cpufreq-applet.h \
- cpufreq-prefs.c cpufreq-prefs.h \
- cpufreq.c cpufreq.h \
- cpufreq-popup.c cpufreq-popup.h
+ cpufreq-applet.c cpufreq-applet.h \
+ cpufreq-prefs.c cpufreq-prefs.h \
+ cpufreq-popup.c cpufreq-popup.h \
+ cpufreq-monitor.c cpufreq-momintor.h \
+ cpufreq-monitor-protected.h \
+ cpufreq-monitor-factory.c cpufreq-monitor-factory.h \
+ cpufreq-monitor-procfs.c cpufreq-monitor-procfs.h \
+ cpufreq-monitor-sysfs.c cpufreq-monitor-sysfs.h \
+ cpufreq-monitor-cpuinfo.c cpufreq-monitor-cpuinfo.h
cpufreq_applet_LDADD = \
$(GNOME_APPLETS_LIBS) \
diff --git a/cpufreq/src/cpufreq-applet.c b/cpufreq/src/cpufreq-applet.c
index baa6cc672..d2a88ed56 100644
--- a/cpufreq/src/cpufreq-applet.c
+++ b/cpufreq/src/cpufreq-applet.c
@@ -24,35 +24,50 @@
#include <panel-applet.h>
#include <panel-applet-gconf.h>
#include <glade/glade.h>
+#include <glib/gi18n.h>
#include <string.h>
#include "cpufreq-applet.h"
#include "cpufreq-prefs.h"
#include "cpufreq-popup.h"
-#include "cpufreq.h"
-
-static void cpufreq_applet_preferences_dialog (BonoboUIComponent *uic, CPUFreqApplet *applet);
-static void cpufreq_applet_help_cb (BonoboUIComponent *uic, CPUFreqApplet *applet);
-static void cpufreq_applet_about_cb (BonoboUIComponent *uic, CPUFreqApplet *applet);
-static gint cpufreq_applet_get_max_cpu (void);
-static void cpufreq_applet_pixmap_set_image (CPUFreqApplet *applet);
-static void cpufreq_applet_destroy (CPUFreqApplet *applet);
-static void cpufreq_setup_widgets (CPUFreqApplet *applet);
-static void cpufreq_size_allocate_cb (PanelApplet *pa, GtkAllocation *allocation,
- gpointer gdata);
-static void cpufreq_change_orient_cb (PanelApplet *pa, PanelAppletOrient orient,
- gpointer gdata);
-static void cpufreq_background_changed (PanelApplet *pa, PanelAppletBackgroundType type,
- GdkColor *color, GdkPixmap *pixmap,
- CPUFreqApplet *applet);
-static GtkWidget *cpufreq_applet_new (CPUFreqApplet *applet);
-static gboolean cpufreq_applet_fill (CPUFreqApplet *applet);
-static gboolean cpufreq_applet_factory (CPUFreqApplet *applet, const gchar *iid,
- gpointer gdata);
-
-static const BonoboUIVerb cpufreq_menu_verbs [] = {
+#include "cpufreq-monitor.h"
+#include "cpufreq-monitor-factory.h"
+
+#define PARENT_TYPE PANEL_TYPE_APPLET
+
+static void cpufreq_applet_init (CPUFreqApplet *applet);
+static void cpufreq_applet_class_init (CPUFreqAppletClass *klass);
+
+static void cpufreq_applet_preferences_cb (BonoboUIComponent *uic, CPUFreqApplet *applet,
+ const gchar cname);
+static void cpufreq_applet_help_cb (BonoboUIComponent *uic, CPUFreqApplet *applet,
+ const gchar cname);
+static void cpufreq_applet_about_cb (BonoboUIComponent *uic, CPUFreqApplet *applet,
+ const gchar cname);
+
+static gint cpufreq_applet_get_max_cpu (void);
+static void cpufreq_applet_pixmap_set_image (CPUFreqApplet *applet, const gchar *percentage);
+
+static void cpufreq_applet_update (CPUFreqMonitor *monitor, gpointer gdata);
+static void cpufreq_applet_refresh (CPUFreqApplet *applet);
+
+static void cpufreq_applet_destroy (GtkObject *widget);
+static gboolean cpufreq_applet_button_press (GtkWidget *widget, GdkEventButton *event);
+static gboolean cpufreq_applet_key_press (GtkWidget *widget, GdkEventKey *event);
+static void cpufreq_applet_size_allocate (GtkWidget *widget, GtkAllocation *allocation);
+static void cpufreq_applet_change_orient (PanelApplet *pa, PanelAppletOrient orient);
+static void cpufreq_applet_change_background (PanelApplet *pa, PanelAppletBackgroundType type,
+ GdkColor *color, GdkPixmap *pixmap);
+
+static gboolean cpufreq_applet_fill (CPUFreqApplet *applet);
+static gboolean cpufreq_applet_factory (CPUFreqApplet *applet, const gchar *iid,
+ gpointer gdata);
+
+static PanelAppletClass *parent_class = NULL;
+
+static const BonoboUIVerb cpufreq_applet_menu_verbs[] = {
BONOBO_UI_UNSAFE_VERB ("CPUFreqAppletPreferences",
- cpufreq_applet_preferences_dialog),
+ cpufreq_applet_preferences_cb),
BONOBO_UI_UNSAFE_VERB ("CPUFreqAppletHelp",
cpufreq_applet_help_cb),
BONOBO_UI_UNSAFE_VERB ("CPUFreqAppletAbout",
@@ -60,32 +75,136 @@ static const BonoboUIVerb cpufreq_menu_verbs [] = {
BONOBO_UI_VERB_END
};
-static GType
+GType
cpufreq_applet_get_type (void)
{
static GType type = 0;
if (!type) {
static const GTypeInfo info = {
- sizeof (PanelAppletClass),
- NULL, NULL, NULL, NULL, NULL,
+ sizeof (CPUFreqAppletClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) cpufreq_applet_class_init,
+ NULL,
+ NULL,
sizeof (CPUFreqApplet),
- 0, NULL, NULL
+ 0,
+ (GInstanceInitFunc) cpufreq_applet_init
};
- type = g_type_register_static (
- PANEL_TYPE_APPLET, "CPUFreqApplet", &info, 0);
+ type = g_type_register_static (PARENT_TYPE, "CPUFreqApplet",
+ &info, 0);
}
return type;
}
+static void
+cpufreq_applet_init (CPUFreqApplet *applet)
+{
+ AtkObject *atk_obj;
+ gint i;
+ GError *error;
+ guint cpu;
+
+ applet->mcpu = cpufreq_applet_get_max_cpu ();
+ applet->prefs = NULL;
+ applet->popup = NULL;
+
+ applet->label = NULL;
+ applet->unit_label = NULL;
+ applet->pixmap = NULL;
+ applet->box = NULL;
+
+ for (i = 0; i <= 4; i++)
+ applet->pixbufs[i] = NULL;
+
+ applet->tips = gtk_tooltips_new ();
+ g_object_ref (G_OBJECT (applet->tips));
+
+ applet->container = gtk_alignment_new (0.5, 0.5, 0, 0);
+ gtk_container_add (GTK_CONTAINER (applet), applet->container);
+
+ panel_applet_add_preferences (PANEL_APPLET (applet),
+ "/schemas/apps/cpufreq-applet/prefs", NULL);
+
+ panel_applet_set_flags (PANEL_APPLET (applet), PANEL_APPLET_EXPAND_MINOR);
+
+ applet->size = panel_applet_get_size (PANEL_APPLET (applet));
+ applet->orient = panel_applet_get_orient (PANEL_APPLET (applet));
+
+ error = NULL;
+ cpu = panel_applet_gconf_get_int (PANEL_APPLET (applet),
+ "cpu", &error);
+
+ /* In case anything went wrong with gconf, get back to the default */
+ if (error || cpu < 0) {
+ cpu = 0;
+ if (error)
+ g_error_free (error);
+ }
+
+ error = NULL;
+ applet->show_mode = panel_applet_gconf_get_int (PANEL_APPLET (applet),
+ "show_mode", &error);
+
+ /* In case anything went wrong with gconf, get back to the default */
+ if (error || applet->show_mode < MODE_GRAPHIC || applet->show_mode > MODE_BOTH) {
+ applet->show_mode = MODE_BOTH;
+ if (error)
+ g_error_free (error);
+ }
+
+ error = NULL;
+ applet->show_text_mode = panel_applet_gconf_get_int (PANEL_APPLET (applet),
+ "show_text_mode", &error);
+
+ /* In case anything went wrong with gconf, get back to the default */
+ if (error || applet->show_text_mode < MODE_TEXT_FREQUENCY ||
+ applet->show_text_mode > MODE_TEXT_PERCENTAGE) {
+ applet->show_text_mode = MODE_TEXT_FREQUENCY_UNIT;
+ g_error_free (error);
+ }
+
+ atk_obj = gtk_widget_get_accessible (GTK_WIDGET (applet));
+
+ if (GTK_IS_ACCESSIBLE (atk_obj)) {
+ atk_object_set_name (atk_obj, _("CPU Frequency Scaling Monitor"));
+ atk_object_set_description (atk_obj, _("This utility shows the current CPU Frequency"));
+ }
+
+ applet->monitor = cpufreq_monitor_factory_create_monitor (cpu);
+ g_signal_connect (G_OBJECT (applet->monitor), "changed",
+ G_CALLBACK (cpufreq_applet_update),
+ (gpointer) applet);
+}
+
+static void
+cpufreq_applet_class_init (CPUFreqAppletClass *klass)
+{
+ PanelAppletClass *applet_class = PANEL_APPLET_CLASS (klass);
+ GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ gtkobject_class->destroy = cpufreq_applet_destroy;
+
+ widget_class->size_allocate = cpufreq_applet_size_allocate;
+ widget_class->key_press_event = cpufreq_applet_key_press;
+ widget_class->button_press_event = cpufreq_applet_button_press;
+
+ applet_class->change_orient = cpufreq_applet_change_orient;
+ applet_class->change_background = cpufreq_applet_change_background;
+}
+
void
cpufreq_applet_display_error (const gchar *message,
const gchar *secondary)
{
GtkWidget *dialog;
- gchar *bold_str;
+ gchar *bold_str;
bold_str = g_strconcat ("<span weight=\"bold\" size=\"larger\">", message, "</span>", NULL);
@@ -102,7 +221,7 @@ cpufreq_applet_display_error (const gchar *message,
}
static void
-cpufreq_applet_preferences_dialog (BonoboUIComponent *uic, CPUFreqApplet *applet)
+cpufreq_applet_preferences_cb (BonoboUIComponent *uic, CPUFreqApplet *applet, const gchar cname)
{
g_return_if_fail (PANEL_IS_APPLET (PANEL_APPLET (applet)));
@@ -110,7 +229,7 @@ cpufreq_applet_preferences_dialog (BonoboUIComponent *uic, CPUFreqApplet *applet
}
static void
-cpufreq_applet_help_cb (BonoboUIComponent *uic, CPUFreqApplet *applet)
+cpufreq_applet_help_cb (BonoboUIComponent *uic, CPUFreqApplet *applet, const gchar cname)
{
GError *error;
@@ -123,65 +242,48 @@ cpufreq_applet_help_cb (BonoboUIComponent *uic, CPUFreqApplet *applet)
if (error) {
cpufreq_applet_display_error (_("Could not open help document"),
- error->message);
+ error->message);
g_error_free (error);
}
}
static void
-cpufreq_applet_about_cb (BonoboUIComponent *uic, CPUFreqApplet *applet)
+cpufreq_applet_about_cb (BonoboUIComponent *uic, CPUFreqApplet *applet, const gchar cname)
{
- GdkPixbuf *pixbuf = NULL;
- const gchar *authors[] = {
+ GdkPixbuf *pixbuf = NULL;
+ static const gchar *authors[] = {
"Carlos Garcia Campos <carlosgc@gnome.org>",
- " ",
- _("Graphic Arts:"),
- "Pablo Arroyo Loma <zzioma@yahoo.es>",
NULL
};
- const gchar *documenters[] = {
+ static const gchar *documenters[] = {
"Carlos Garcia Campos <carlosgc@gnome.org>",
NULL
};
- const gchar *translator_credits = _("translator_credits");
+ static const gchar *artists[] = {
+ "Pablo Arroyo Loma <zzioma@yahoo.es>",
+ NULL
+ };
g_return_if_fail (PANEL_IS_APPLET (PANEL_APPLET (applet)));
- if (applet->about_dialog != NULL) {
- gtk_window_set_screen (GTK_WINDOW (applet->about_dialog),
- gtk_widget_get_screen (GTK_WIDGET (applet)));
-
- gtk_window_present (GTK_WINDOW (applet->about_dialog));
- return;
- }
-
pixbuf = gdk_pixbuf_new_from_file_at_size (ICONDIR"/cpufreq-applet/cpufreq-applet.png",
48, 48, NULL);
- applet->about_dialog = gnome_about_new (
- _("CPU Frequency Scaling Monitor"),
- VERSION,
- _("Copyright (C) 2004 Free Software Foundation. Inc."),
- _("This utility shows the current CPU Frequency Scaling."),
- authors,
- documenters,
- g_ascii_strcasecmp (
- translator_credits, "translator_credits") != 0 ? translator_credits : NULL,
- pixbuf);
+ gtk_show_about_dialog (
+ GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (applet))),
+ "name", _("CPU Frequency Scaling Monitor"),
+ "version", VERSION,
+ "copyright", _("Copyright (C) 2004 Free Software Foundation. Inc."),
+ "comments", _("This utility shows the current CPU Frequency Scaling."),
+ "authors", authors,
+ "documenters", documenters,
+ "artists", artists,
+ "translator-credits", _("translator_credits"),
+ "logo", pixbuf,
+ NULL);
if (pixbuf)
g_object_unref (pixbuf);
-
- gtk_window_set_screen (GTK_WINDOW (applet->about_dialog),
- gtk_widget_get_screen (GTK_WIDGET (applet)));
-
- g_signal_connect (applet->about_dialog, "destroy",
- G_CALLBACK (gtk_widget_destroyed),
- &applet->about_dialog);
-
- gtk_widget_show (applet->about_dialog);
-
- return;
}
static gint
@@ -218,7 +320,7 @@ cpufreq_applet_get_max_cpu ()
}
static void
-cpufreq_applet_pixmap_set_image (CPUFreqApplet *applet)
+cpufreq_applet_pixmap_set_image (CPUFreqApplet *applet, const gchar *percentage)
{
gint perc, image;
gchar *text_perc;
@@ -230,10 +332,10 @@ cpufreq_applet_pixmap_set_image (CPUFreqApplet *applet)
ICONDIR"/cpufreq-applet/cpufreq-na.png",
NULL };
- if (!applet->perc) {
+ if (!percentage) {
image = 4;
} else {
- text_perc = g_strndup (applet->perc, strlen (applet->perc) - 1);
+ text_perc = g_strndup (percentage, strlen (percentage) - 1);
perc = atoi (text_perc);
g_free (text_perc);
@@ -260,59 +362,70 @@ cpufreq_applet_pixmap_set_image (CPUFreqApplet *applet)
gtk_image_set_from_pixbuf (GTK_IMAGE (applet->pixmap), applet->pixbufs[image]);
}
-void
-cpufreq_applet_update (CPUFreqApplet *applet)
+static void
+cpufreq_applet_update (CPUFreqMonitor *monitor, gpointer gdata)
{
- gchar *text_tip, *text_mode;
- gchar *governor;
+ gchar *text_tip, *text_mode;
+ gchar *freq, *perc, *unit;
+ guint cpu;
+ gchar *governor;
+ CPUFreqApplet *applet;
- g_return_if_fail (PANEL_IS_APPLET (PANEL_APPLET (applet)));
+ applet = CPUFREQ_APPLET (gdata);
+
+ cpu = cpufreq_monitor_get_cpu (monitor);
+ freq = cpufreq_monitor_get_frequency (monitor);
+ perc = cpufreq_monitor_get_percentage (monitor);
+ unit = cpufreq_monitor_get_unit (monitor);
+ governor = cpufreq_monitor_get_governor (monitor);
if (applet->show_mode != MODE_GRAPHIC) {
if (applet->show_mode == MODE_TEXT) {
gtk_widget_hide (applet->pixmap);
} else {
- cpufreq_applet_pixmap_set_image (applet);
+ cpufreq_applet_pixmap_set_image (applet, perc);
gtk_widget_show (applet->pixmap);
}
switch (applet->show_text_mode) {
case MODE_TEXT_FREQUENCY:
- gtk_label_set_text (GTK_LABEL (applet->label), applet->freq);
+ gtk_label_set_text (GTK_LABEL (applet->label), freq);
gtk_widget_hide (applet->unit_label);
break;
case MODE_TEXT_FREQUENCY_UNIT:
- gtk_label_set_text (GTK_LABEL (applet->label), applet->freq);
- gtk_label_set_text (GTK_LABEL (applet->unit_label), applet->unit);
+ gtk_label_set_text (GTK_LABEL (applet->label), freq);
+ gtk_label_set_text (GTK_LABEL (applet->unit_label), unit);
gtk_widget_show (applet->unit_label);
break;
case MODE_TEXT_PERCENTAGE:
- gtk_label_set_text (GTK_LABEL (applet->label), applet->perc);
+ gtk_label_set_text (GTK_LABEL (applet->label), perc);
break;
}
gtk_widget_show (applet->label);
} else {
- cpufreq_applet_pixmap_set_image (applet);
+ cpufreq_applet_pixmap_set_image (applet, perc);
gtk_widget_show (applet->pixmap);
gtk_widget_hide (applet->label);
gtk_widget_hide (applet->unit_label);
}
- governor = g_strdup (applet->governor);
governor[0] = g_ascii_toupper (governor[0]);
- text_mode = g_strdup_printf ("%s\n%s %s (%s)", governor,
- applet->freq, applet->unit, applet->perc);
+ text_mode = g_strdup_printf ("%s\n%s %s (%s)", governor, freq, unit, perc);
+
+ g_free (freq);
+ g_free (unit);
+ g_free (perc);
g_free (governor);
if (applet->mcpu == 0)
text_tip = g_strdup_printf ("%s", text_mode);
else
- text_tip = g_strdup_printf ("CPU %d - %s", applet->cpu, text_mode);
+ text_tip = g_strdup_printf ("CPU %d - %s", cpu, text_mode);
g_free (text_mode);
@@ -327,48 +440,28 @@ free_string (gpointer str, gpointer gdata)
}
static void
-cpufreq_applet_destroy (CPUFreqApplet *applet)
+cpufreq_applet_destroy (GtkObject *widget)
{
- gint i;
-
- g_return_if_fail (PANEL_IS_APPLET (PANEL_APPLET (applet)));
-
- if (applet->timeout_handler > 0)
- g_source_remove (applet->timeout_handler);
+ CPUFreqApplet *applet;
+ gint i;
- if (applet->tips)
- g_object_unref (G_OBJECT (applet->tips));
+ applet = CPUFREQ_APPLET (widget);
- for (i=0; i<=3; i++) {
- if (applet->pixbufs[i])
- g_object_unref (G_OBJECT (applet->pixbufs[i]));
+ if (applet->monitor) {
+ g_object_unref (G_OBJECT (applet->monitor));
+ applet->monitor = NULL;
}
- if (applet->freq) {
- g_free (applet->freq);
- applet->freq = NULL;
- }
-
- if (applet->perc) {
- g_free (applet->perc);
- applet->perc = NULL;
+ if (applet->tips) {
+ g_object_unref (G_OBJECT (applet->tips));
+ applet->tips = NULL;
}
- if (applet->unit) {
- g_free (applet->unit);
- applet->unit = NULL;
- }
-
- if (applet->available_freqs) {
- g_list_foreach (applet->available_freqs,
- free_string, NULL);
- g_list_free (applet->available_freqs);
- applet->available_freqs = NULL;
- }
-
- if (applet->about_dialog) {
- gtk_widget_destroy (applet->about_dialog);
- applet->about_dialog = NULL;
+ for (i = 0; i <= 3; i++) {
+ if (applet->pixbufs[i]) {
+ g_object_unref (G_OBJECT (applet->pixbufs[i]));
+ applet->pixbufs[i] = NULL;
+ }
}
if (applet->prefs) {
@@ -380,10 +473,53 @@ cpufreq_applet_destroy (CPUFreqApplet *applet)
gtk_widget_destroy (applet->popup);
applet->popup = NULL;
}
+
+ (* GTK_OBJECT_CLASS (parent_class)->destroy) (widget);
}
+static gboolean
+cpufreq_applet_button_press (GtkWidget *widget, GdkEventButton *event)
+{
+ CPUFreqApplet *applet;
+
+ applet = CPUFREQ_APPLET (widget);
+
+ if (event->button == 1)
+ return cpufreq_popup_show (applet, event->time);
+
+ if (GTK_WIDGET_CLASS (parent_class)->button_press_event)
+ return (* GTK_WIDGET_CLASS (parent_class)->button_press_event) (widget, event);
+ else
+ return FALSE;
+}
+
+static gboolean
+cpufreq_applet_key_press (GtkWidget *widget, GdkEventKey *event)
+{
+ CPUFreqApplet *applet;
+
+ applet = CPUFREQ_APPLET (widget);
+
+ switch (event->keyval) {
+ case GDK_KP_Enter:
+ case GDK_ISO_Enter:
+ case GDK_3270_Enter:
+ case GDK_Return:
+ case GDK_space:
+ case GDK_KP_Space:
+ return cpufreq_popup_show (applet, event->time);
+ default:
+ break;
+ }
+
+ if (GTK_WIDGET_CLASS (parent_class)->key_press_event)
+ return (* GTK_WIDGET_CLASS (parent_class)->key_press_event) (widget, event);
+ else
+ return FALSE;
+}
+
static void
-cpufreq_setup_widgets (CPUFreqApplet *applet)
+cpufreq_applet_refresh (CPUFreqApplet *applet)
{
GtkWidget *labels_box;
GtkRequisition req;
@@ -391,8 +527,13 @@ cpufreq_setup_widgets (CPUFreqApplet *applet)
gboolean horizontal = FALSE;
gint panel_size, label_size, unit_label_size, pixmap_size;
gint size_step = 12;
+ gchar *freq, *perc, *unit;
g_return_if_fail (PANEL_IS_APPLET (PANEL_APPLET (applet)));
+
+ freq = cpufreq_monitor_get_frequency (applet->monitor);
+ perc = cpufreq_monitor_get_percentage (applet->monitor);
+ unit = cpufreq_monitor_get_unit (applet->monitor);
panel_size = applet->size - 1; /* 1 pixel margin */
@@ -411,8 +552,10 @@ cpufreq_setup_widgets (CPUFreqApplet *applet)
gtk_widget_destroy (applet->label);
applet->label = gtk_label_new (" --- ");
- if (applet->freq)
- gtk_label_set_text (GTK_LABEL (applet->label), applet->freq);
+ if (freq) {
+ gtk_label_set_text (GTK_LABEL (applet->label), freq);
+ g_free (freq);
+ }
gtk_widget_size_request (applet->label, &req);
if (applet->show_mode != MODE_GRAPHIC)
@@ -430,8 +573,10 @@ cpufreq_setup_widgets (CPUFreqApplet *applet)
gtk_widget_destroy (applet->unit_label);
applet->unit_label = gtk_label_new (" ? ");
- if (applet->unit)
- gtk_label_set_text (GTK_LABEL (applet->unit_label), applet->unit);
+ if (unit) {
+ gtk_label_set_text (GTK_LABEL (applet->unit_label), unit);
+ g_free (unit);
+ }
gtk_widget_size_request (applet->unit_label, &req);
if (applet->show_mode != MODE_GRAPHIC &&
@@ -451,7 +596,8 @@ cpufreq_setup_widgets (CPUFreqApplet *applet)
applet->pixmap = gtk_image_new ();
- cpufreq_applet_pixmap_set_image (applet);
+ cpufreq_applet_pixmap_set_image (applet, perc);
+ if (perc) g_free (perc);
gtk_widget_size_request (applet->pixmap, &req);
if (applet->show_mode != MODE_TEXT)
@@ -504,50 +650,66 @@ cpufreq_setup_widgets (CPUFreqApplet *applet)
}
static void
-cpufreq_size_allocate_cb (PanelApplet *pa, GtkAllocation *allocation,
- gpointer gdata)
+cpufreq_applet_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
{
CPUFreqApplet *applet;
+ gint size;
- applet = (CPUFreqApplet *) gdata;
+ applet = CPUFREQ_APPLET (widget);
if ((applet->orient == PANEL_APPLET_ORIENT_LEFT) ||
(applet->orient == PANEL_APPLET_ORIENT_RIGHT)) {
- if (applet->size == allocation->width)
- return;
- applet->size = allocation->width;
+ size = allocation->width;
} else {
- if (applet->size == allocation->height)
- return;
- applet->size = allocation->height;
+ size = allocation->height;
}
- cpufreq_setup_widgets (applet);
+ if (size != applet->size) {
+ applet->size = size;
+ cpufreq_applet_refresh (applet);
+ }
+
+ (* GTK_WIDGET_CLASS (parent_class)->size_allocate) (widget, allocation);
}
static void
-cpufreq_change_orient_cb (PanelApplet *pa, PanelAppletOrient orient, gpointer gdata)
+cpufreq_applet_change_orient (PanelApplet *pa, PanelAppletOrient orient)
{
CPUFreqApplet *applet;
+ gint size;
- applet = (CPUFreqApplet *) gdata;
+ applet = CPUFREQ_APPLET (pa);
applet->orient = orient;
+
+ if ((orient == PANEL_APPLET_ORIENT_LEFT) ||
+ (orient == PANEL_APPLET_ORIENT_RIGHT)) {
+ size = GTK_WIDGET (applet)->allocation.width;
+ } else {
+ size = GTK_WIDGET (applet)->allocation.height;
+ }
+
+ if (size != applet->size) {
+ applet->size = size;
+ cpufreq_applet_refresh (applet);
+ }
- cpufreq_setup_widgets (applet);
+ if (PANEL_APPLET_CLASS (parent_class)->change_orient)
+ (* PANEL_APPLET_CLASS (parent_class)->change_orient) (pa, orient);
}
static void
-cpufreq_background_changed (PanelApplet *pa,
- PanelAppletBackgroundType type,
- GdkColor *color,
- GdkPixmap *pixmap,
- CPUFreqApplet *applet)
+cpufreq_applet_change_background (PanelApplet *pa,
+ PanelAppletBackgroundType type,
+ GdkColor *color, GdkPixmap *pixmap)
{
+ CPUFreqApplet *applet;
/* Taken from TrashApplet */
- GtkRcStyle *rc_style;
- GtkStyle *style;
+ GtkRcStyle *rc_style;
+ GtkStyle *style;
+ applet = CPUFREQ_APPLET (pa);
+
/* reset style */
gtk_widget_set_style (GTK_WIDGET (applet), NULL);
rc_style = gtk_rc_style_new ();
@@ -574,151 +736,27 @@ cpufreq_background_changed (PanelApplet *pa,
}
}
-void
-cpufreq_applet_run (CPUFreqApplet *applet)
-{
- gchar *text_tip;
-
- if (applet->timeout_handler > 0)
- g_source_remove (applet->timeout_handler);
-
- switch (applet->iface) {
- case IFACE_SYSFS:
- applet->timeout_handler = g_timeout_add (1000, cpufreq_get_from_sysfs, (gpointer) applet);
-
- break;
- case IFACE_PROCFS:
- applet->timeout_handler = g_timeout_add (1000, cpufreq_get_from_procfs, (gpointer) applet);
-
- break;
- case IFACE_CPUINFO:
- /* If there is no cpufreq support it shows only the cpu frequency,
- * I thi nk is better than do nothing. I have to notify it to the user, because
- * he could think that cpufreq is supported but it doesn't work succesfully
- */
-
-
- cpufreq_applet_display_error (_("CPU frequency scaling unsupported"),
- _("You will not be able to modify the frequency of your machine. "
- "Your machine may be misconfigured or not have hardware support "
- "for CPU frequency scaling."));
-
- if (cpufreq_get_from_procfs_cpuinfo (applet)) {
- text_tip = g_strdup_printf (_("CPU %d - Frequency Scaling Unsupported\n%s %s (%s)"),
- applet->cpu, applet->freq, applet->unit, applet->perc);
- gtk_tooltips_set_tip (applet->tips, GTK_WIDGET (applet), text_tip, NULL);
- g_free (text_tip);
- } else {
- gtk_tooltips_set_tip (applet->tips, GTK_WIDGET (applet),
- _("Frequency Scaling Unsupported"),
- NULL);
- }
-
- gtk_widget_show (applet->pixmap);
-
- break;
- }
-}
-
-static GtkWidget *
-cpufreq_applet_new (CPUFreqApplet *applet)
+static gboolean
+cpufreq_applet_fill (CPUFreqApplet *applet)
{
- AtkObject *atk_obj;
- gint i;
- GError *error;
-
- panel_applet_add_preferences (PANEL_APPLET (applet),
- "/schemas/apps/cpufreq-applet/prefs", NULL);
+ BonoboUIComponent *popup_component;
- panel_applet_set_flags (PANEL_APPLET (applet), PANEL_APPLET_EXPAND_MINOR);
-
- /* New applet, default values */
- applet->timeout_handler = 0;
- applet->mcpu = cpufreq_applet_get_max_cpu ();
- applet->prefs = NULL;
- applet->about_dialog = NULL;
- applet->available_freqs = NULL;
- applet->popup = NULL;
-
- error = NULL;
- applet->cpu = panel_applet_gconf_get_int (PANEL_APPLET (applet),
- "cpu", &error);
-
- /* In case anything went wrong with gconf, get back to the default */
- if (error || applet->cpu < 0) {
- applet->cpu = 0;
- if (error)
- g_error_free (error);
- }
-
- error = NULL;
- applet->show_mode = panel_applet_gconf_get_int (PANEL_APPLET (applet),
- "show_mode", &error);
-
- /* In case anything went wrong with gconf, get back to the default */
- if (error || applet->show_mode < MODE_GRAPHIC || applet->show_mode > MODE_BOTH) {
- applet->show_mode = MODE_BOTH;
- if (error)
- g_error_free (error);
- }
-
- error = NULL;
- applet->show_text_mode = panel_applet_gconf_get_int (PANEL_APPLET (applet),
- "show_text_mode", &error);
-
- /* In case anything went wrong with gconf, get back to the default */
- if (error || applet->show_text_mode < MODE_TEXT_FREQUENCY ||
- applet->show_text_mode > MODE_TEXT_PERCENTAGE) {
- applet->show_text_mode = MODE_TEXT_FREQUENCY_UNIT;
- g_error_free (error);
- }
+ g_return_val_if_fail (PANEL_IS_APPLET (PANEL_APPLET (applet)), FALSE);
- applet->freq = NULL;
- applet->perc = NULL;
- applet->unit = NULL;
- applet->governor = NULL;
-
- for (i=0; i<=4; i++)
- applet->pixbufs[i] = NULL;
-
- applet->tips = gtk_tooltips_new ();
- g_object_ref (G_OBJECT (applet->tips));
-
- g_signal_connect (G_OBJECT (applet), "destroy",
- G_CALLBACK (cpufreq_applet_destroy),
- NULL);
- g_signal_connect (G_OBJECT (applet), "button_press_event",
- G_CALLBACK (cpufreq_popup_show),
- NULL);
- g_signal_connect (G_OBJECT (applet), "size_allocate",
- G_CALLBACK (cpufreq_size_allocate_cb),
- (gpointer) applet);
- g_signal_connect (G_OBJECT (applet), "change_orient",
- G_CALLBACK (cpufreq_change_orient_cb),
- (gpointer) applet);
- g_signal_connect (G_OBJECT (applet), "change_background",
- G_CALLBACK (cpufreq_background_changed),
- (gpointer) applet);
+ gnome_window_icon_set_default_from_file
+ (ICONDIR"/cpufreq-applet/cpufreq-applet.png");
- applet->container = gtk_alignment_new (0.5, 0.5, 0, 0);
- gtk_container_add (GTK_CONTAINER (applet), applet->container);
-
- applet->size = panel_applet_get_size (PANEL_APPLET (applet));
- applet->orient = panel_applet_get_orient (PANEL_APPLET (applet));
-
- cpufreq_setup_widgets (applet);
+ glade_gnome_init ();
/* Setup the menus */
panel_applet_setup_menu_from_file (PANEL_APPLET (applet),
DATADIR,
"GNOME_CPUFreqApplet.xml",
NULL,
- cpufreq_menu_verbs,
+ cpufreq_applet_menu_verbs,
applet);
if (panel_applet_get_locked_down (PANEL_APPLET (applet))) {
- BonoboUIComponent *popup_component;
-
popup_component = panel_applet_get_popup_component (PANEL_APPLET (applet));
bonobo_ui_component_set_prop (popup_component,
@@ -727,38 +765,10 @@ cpufreq_applet_new (CPUFreqApplet *applet)
NULL);
}
- if (g_file_test ("/sys/devices/system/cpu/cpu0/cpufreq", G_FILE_TEST_EXISTS)) { /* 2.6 kernel */
- applet->iface = IFACE_SYSFS;
- } else if (g_file_test ("/proc/cpufreq", G_FILE_TEST_EXISTS)) { /* 2.4 kernel */
- applet->iface = IFACE_PROCFS;
- } else if (g_file_test ("/proc/cpuinfo", G_FILE_TEST_EXISTS)) {
- applet->iface = IFACE_CPUINFO;
- }
-
- cpufreq_applet_run (applet);
+ cpufreq_applet_refresh (applet);
- atk_obj = gtk_widget_get_accessible (GTK_WIDGET (applet));
-
- if (GTK_IS_ACCESSIBLE (atk_obj)) {
- atk_object_set_name (atk_obj, _("CPU Frequency Scaling Monitor"));
- atk_object_set_description (atk_obj, _("This utility shows the current CPU Frequency"));
- }
-
- return GTK_WIDGET (applet);
-}
-
-static gboolean
-cpufreq_applet_fill (CPUFreqApplet *applet)
-{
- g_return_val_if_fail (PANEL_IS_APPLET (PANEL_APPLET (applet)), FALSE);
+ cpufreq_monitor_run (applet->monitor);
- gnome_window_icon_set_default_from_file
- (ICONDIR"/cpufreq-applet/cpufreq-applet.png");
-
- glade_gnome_init ();
-
- cpufreq_applet_new (applet);
-
gtk_widget_show (GTK_WIDGET (applet));
return TRUE;
@@ -776,7 +786,7 @@ cpufreq_applet_factory (CPUFreqApplet *applet, const gchar *iid, gpointer gdata)
}
PANEL_APPLET_BONOBO_FACTORY ("OAFIID:GNOME_CPUFreqApplet_Factory",
- cpufreq_applet_get_type (),
+ TYPE_CPUFREQ_APPLET,
"cpufreq-applet",
"0",
(PanelAppletFactoryCallback) cpufreq_applet_factory,
diff --git a/cpufreq/src/cpufreq-applet.h b/cpufreq/src/cpufreq-applet.h
index b94790874..3030d4550 100644
--- a/cpufreq/src/cpufreq-applet.h
+++ b/cpufreq/src/cpufreq-applet.h
@@ -18,10 +18,24 @@
* Authors : Carlos García Campos <carlosgc@gnome.org>
*/
+#ifndef __CPUFREQ_APPLET_H__
+#define __CPUFREQ_APPLET_H__
#include <gnome.h>
#include <panel-applet.h>
+#include "cpufreq-monitor.h"
+
+#define TYPE_CPUFREQ_APPLET (cpufreq_applet_get_type ())
+#define CPUFREQ_APPLET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_CPUFREQ_APPLET, CPUFreqApplet))
+#define CPUFREQ_APPLET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TYPE_CPUFREQ_APPLET, CPUFreqAppletClass))
+#define IS_CPUFREQ_APPLET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_CPUFREQ_APPLET))
+#define IS_CPUFREQ_APPLET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_CPUFREQ_APPLET))
+#define CPUFREQ_APPLET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_CPUFREQ_APPLET, CPUFreqAppletClass))
+
+typedef struct _CPUFreqApplet CPUFreqApplet;
+typedef struct _CPUFreqAppletClass CPUFreqAppletClass;
+
typedef enum {
MODE_GRAPHIC,
MODE_TEXT,
@@ -34,32 +48,20 @@ typedef enum {
MODE_TEXT_PERCENTAGE
} CPUFreqShowTextMode;
-typedef enum {
- IFACE_SYSFS,
- IFACE_PROCFS,
- IFACE_CPUINFO
-} CPUFreqIface;
-
-typedef struct {
+struct _CPUFreqApplet {
PanelApplet base;
+
guint cpu;
guint mcpu; /* Max cpu number (0 in a single cpu system) */
CPUFreqShowMode show_mode;
CPUFreqShowTextMode show_text_mode;
- CPUFreqIface iface;
+
+ CPUFreqMonitor *monitor;
PanelAppletOrient orient;
gint size;
- gchar *freq;
- gchar *perc;
- gchar *unit;
- gchar *governor;
- GList *available_freqs;
-
- guint timeout_handler;
-
GtkWidget *label;
GtkWidget *unit_label;
GtkWidget *pixmap;
@@ -69,11 +71,16 @@ typedef struct {
GtkTooltips *tips;
GtkWidget *prefs;
- GtkWidget *about_dialog;
GtkWidget *popup;
-} CPUFreqApplet;
+};
+
+struct _CPUFreqAppletClass {
+ PanelAppletClass parent_class;
+};
+
+GType cpufreq_applet_get_type ();
-void cpufreq_applet_update (CPUFreqApplet *applet);
void cpufreq_applet_display_error (const gchar *message,
const gchar *secondary);
-void cpufreq_applet_run (CPUFreqApplet *applet);
+
+#endif /* __CPUFREQ_APPLET_H__ */
diff --git a/cpufreq/src/cpufreq-monitor-cpuinfo.c b/cpufreq/src/cpufreq-monitor-cpuinfo.c
new file mode 100644
index 000000000..c24e3af18
--- /dev/null
+++ b/cpufreq/src/cpufreq-monitor-cpuinfo.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2001, 2002 Free Software Foundation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Authors : Carlos García Campos <carlosgc@gnome.org>
+ */
+
+
+#include <gnome.h>
+#include <libgnomevfs/gnome-vfs.h>
+#include <glib/gi18n.h>
+
+#include <string.h>
+
+#include "cpufreq-monitor-cpuinfo.h"
+#include "cpufreq-monitor-protected.h"
+
+#define PARENT_TYPE TYPE_CPUFREQ_MONITOR
+
+#define CPUFREQ_MONITOR_GET_PROTECTED(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), PARENT_TYPE, CPUFreqMonitorProtected))
+
+static void cpufreq_monitor_cpuinfo_class_init (CPUFreqMonitorCPUInfoClass *klass);
+static void cpufreq_monitor_cpuinfo_finalize (GObject *object);
+
+static void cpufreq_monitor_cpuinfo_run (CPUFreqMonitor *monitor);
+static gboolean cpufreq_monitor_cpuinfo_get (gpointer gdata);
+
+
+static CPUFreqMonitorClass *parent_class = NULL;
+
+typedef struct _CPUFreqMonitorProtected CPUFreqMonitorProtected;
+
+GType cpufreq_monitor_cpuinfo_get_type ()
+{
+ static GType type = 0;
+
+ if (!type) {
+ static const GTypeInfo info = {
+ sizeof (CPUFreqMonitorCPUInfoClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) cpufreq_monitor_cpuinfo_class_init,
+ NULL,
+ NULL,
+ sizeof (CPUFreqMonitorCPUInfo),
+ 0,
+ NULL
+ };
+
+ type = g_type_register_static (PARENT_TYPE, "CPUFreqMonitorCPUInfo",
+ &info, 0);
+ }
+
+ return type;
+}
+
+static void
+cpufreq_monitor_cpuinfo_class_init (CPUFreqMonitorCPUInfoClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ CPUFreqMonitorClass *monitor_class = CPUFREQ_MONITOR_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ monitor_class->run = cpufreq_monitor_cpuinfo_run;
+ monitor_class->get_available_frequencies = NULL;
+
+ object_class->finalize = cpufreq_monitor_cpuinfo_finalize;
+}
+
+static void
+cpufreq_monitor_cpuinfo_finalize (GObject *object)
+{
+ g_return_if_fail (IS_CPUFREQ_MONITOR_CPUINFO (object));
+
+ if (G_OBJECT_CLASS (parent_class)->finalize)
+ (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+}
+
+CPUFreqMonitor *
+cpufreq_monitor_cpuinfo_new (guint cpu)
+{
+ CPUFreqMonitorCPUInfo *monitor;
+
+ monitor = g_object_new (TYPE_CPUFREQ_MONITOR_CPUINFO, "cpu", cpu, NULL);
+
+ return CPUFREQ_MONITOR (monitor);
+}
+
+static gboolean
+cpufreq_monitor_cpuinfo_get (gpointer gdata)
+{
+ GnomeVFSHandle *handle;
+ GnomeVFSFileSize bytes_read;
+ GnomeVFSResult result;
+ gchar *uri, *file;
+ gchar **lines;
+ gchar buffer[256];
+ gchar *p;
+ gchar *freq, *perc, *unit, *governor;
+ gint cpu, i;
+ CPUFreqMonitorCPUInfo *monitor;
+ CPUFreqMonitorProtected *private;
+
+ monitor = (CPUFreqMonitorCPUInfo *) gdata;
+
+ private = CPUFREQ_MONITOR_GET_PROTECTED (CPUFREQ_MONITOR (monitor));
+
+ uri = gnome_vfs_get_uri_from_local_path ("/proc/cpuinfo");
+
+ result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
+ if (result != GNOME_VFS_OK) {
+ if (uri) g_free (uri);
+
+ return FALSE;
+ }
+
+ g_free (uri);
+
+ result = gnome_vfs_read (handle, buffer, 256, &bytes_read);
+ file = g_strndup (buffer, bytes_read);
+ if (result != GNOME_VFS_OK) {
+ g_free (file);
+ gnome_vfs_close (handle);
+
+ return FALSE;
+ }
+
+ result = gnome_vfs_close (handle);
+ if (result != GNOME_VFS_OK) {
+ g_free (file);
+
+ return FALSE;
+ }
+
+ /* TODO: SMP support */
+ lines = g_strsplit (file, "\n", -1);
+ for (i=0; lines[i]; i++) {
+ if (g_ascii_strncasecmp ("cpu MHz", lines[i], strlen ("cpu MHz")) == 0) {
+ p = g_strrstr (lines[i], ":");
+
+ if (p == NULL) {
+ g_strfreev (lines);
+ g_free (file);
+
+ return FALSE;
+ }
+
+ if (strlen (lines[i]) < (p - lines[i])) {
+ g_strfreev (lines);
+ g_free (file);
+
+ return FALSE;
+ }
+
+ if ((sscanf(p + 1, "%d.", &cpu)) != 1) {
+ g_strfreev (lines);
+ g_free (file);
+
+ return FALSE;
+ }
+
+ break;
+ }
+ }
+
+ g_strfreev (lines);
+ g_free (file);
+
+ governor = g_strdup (_("Frequency Scaling Unsupported"));
+ freq = parent_class->get_human_readable_freq (cpu * 1000); /* kHz are expected*/
+ unit = parent_class->get_human_readable_unit (cpu * 1000); /* kHz are expected*/
+ perc = g_strdup ("100%");
+
+ parent_class->free_data (CPUFREQ_MONITOR (monitor));
+
+ private->governor = governor;
+ private->freq = freq;
+ private->perc = perc;
+ private->unit = unit;
+
+ if (private->freq == NULL)
+ return FALSE;
+ if (private->unit == NULL)
+ return FALSE;
+
+ g_signal_emit (CPUFREQ_MONITOR (monitor), parent_class->signals[CHANGED], 0);
+
+ return TRUE;
+}
+
+static void
+cpufreq_monitor_cpuinfo_run (CPUFreqMonitor *monitor)
+{
+ CPUFreqMonitorProtected *private;
+
+ g_return_if_fail (IS_CPUFREQ_MONITOR_CPUINFO (monitor));
+
+ cpufreq_monitor_cpuinfo_get (monitor);
+}
+
+
diff --git a/cpufreq/src/cpufreq-monitor-cpuinfo.h b/cpufreq/src/cpufreq-monitor-cpuinfo.h
new file mode 100644
index 000000000..794255da1
--- /dev/null
+++ b/cpufreq/src/cpufreq-monitor-cpuinfo.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2001, 2002 Free Software Foundation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Authors : Carlos García Campos <carlosgc@gnome.org>
+ */
+
+#ifndef __CPUFREQ_MONITOR_CPUINFO_H__
+#define __CPUFREQ_MONITOR_CPUINFO_H__
+
+#include <glib-object.h>
+#include "cpufreq-monitor.h"
+
+#define TYPE_CPUFREQ_MONITOR_CPUINFO (cpufreq_monitor_cpuinfo_get_type ())
+#define CPUFREQ_MONITOR_CPUINFO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_CPUFREQ_MONITOR_CPUINFO, CPUFreqMonitorCPUInfo))
+#define CPUFREQ_MONITOR_CPUINFO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TYPE_CPUFREQ_MONITOR_CPUINFO, CPUFreqMonitorCPUInfoClass))
+#define IS_CPUFREQ_MONITOR_CPUINFO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_CPUFREQ_MONITOR_CPUINFO))
+#define IS_CPUFREQ_MONITOR_CPUINFO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_CPUFREQ_MONITOR_CPUINFO))
+#define CPUFREQ_MONITOR_CPUINFO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_CPUFREQ_MONITOR_CPUINFO, CPUFreqMonitorCPUInfoClass))
+
+typedef struct _CPUFreqMonitorCPUInfo CPUFreqMonitorCPUInfo;
+typedef struct _CPUFreqMonitorCPUInfoClass CPUFreqMonitorCPUInfoClass;
+
+struct _CPUFreqMonitorCPUInfo {
+ CPUFreqMonitor parent;
+};
+
+struct _CPUFreqMonitorCPUInfoClass {
+ CPUFreqMonitorClass parent_class;
+};
+
+GType cpufreq_monitor_cpuinfo_get_type ();
+CPUFreqMonitor *cpufreq_monitor_cpuinfo_new (guint cpu);
+
+#endif /* __CPUFREQ_MONITOR_CPUINFO_H__ */
diff --git a/cpufreq/src/cpufreq-monitor-factory.c b/cpufreq/src/cpufreq-monitor-factory.c
new file mode 100644
index 000000000..a6f848a10
--- /dev/null
+++ b/cpufreq/src/cpufreq-monitor-factory.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2001, 2002 Free Software Foundation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Authors : Carlos García Campos <carlosgc@gnome.org>
+ */
+
+#include <glib.h>
+
+#include "cpufreq-applet.h"
+#include "cpufreq-monitor-sysfs.h"
+#include "cpufreq-monitor-procfs.h"
+#include "cpufreq-monitor-cpuinfo.h"
+#include "cpufreq-monitor-factory.h"
+
+CPUFreqMonitor *
+cpufreq_monitor_factory_create_monitor (guint cpu)
+{
+ CPUFreqMonitor *monitor;
+
+ if (g_file_test ("/sys/devices/system/cpu/cpu0/cpufreq", G_FILE_TEST_EXISTS)) { /* 2.6 kernel */
+ monitor = cpufreq_monitor_sysfs_new (cpu);
+ } else if (g_file_test ("/proc/cpufreq", G_FILE_TEST_EXISTS)) { /* 2.4 kernel */
+ monitor = cpufreq_monitor_procfs_new (cpu);
+ } else if (g_file_test ("/proc/cpuinfo", G_FILE_TEST_EXISTS)) {
+ /* If there is no cpufreq support it shows only the cpu frequency,
+ * I thi nk is better than do nothing. I have to notify it to the user, because
+ * he could think that cpufreq is supported but it doesn't work succesfully
+ */
+
+ cpufreq_applet_display_error (_("CPU frequency scaling unsupported"),
+ _("You will not be able to modify the frequency of your machine. "
+ "Your machine may be misconfigured or not have hardware support "
+ "for CPU frequency scaling."));
+
+ monitor = cpufreq_monitor_cpuinfo_new (cpu);
+ }
+
+ return monitor;
+}
+
diff --git a/cpufreq/src/cpufreq.h b/cpufreq/src/cpufreq-monitor-factory.h
index 416f0f4f3..4744ed0f6 100644
--- a/cpufreq/src/cpufreq.h
+++ b/cpufreq/src/cpufreq-monitor-factory.h
@@ -18,12 +18,6 @@
* Authors : Carlos García Campos <carlosgc@gnome.org>
*/
-gchar *cpufreq_get_human_readble_freq (gint freq);
-gchar *cpufreq_get_human_readble_unit (gint freq);
-gchar *cpufreq_get_human_readble_perc (gint fmax, gint fmin);
+#include "cpufreq-monitor.h"
-gboolean cpufreq_get_from_procfs (gpointer gdata);
-gboolean cpufreq_get_from_sysfs (gpointer gdata);
-GList *cpufreq_get_frequencies_from_procfs (CPUFreqApplet *applet);
-GList *cpufreq_get_frequencies_from_sysfs (CPUFreqApplet *applet);
-gboolean cpufreq_get_from_procfs_cpuinfo (CPUFreqApplet *applet);
+CPUFreqMonitor *cpufreq_monitor_factory_create_monitor (guint cpu);
diff --git a/cpufreq/src/cpufreq-monitor-procfs.c b/cpufreq/src/cpufreq-monitor-procfs.c
new file mode 100644
index 000000000..4337b8e08
--- /dev/null
+++ b/cpufreq/src/cpufreq-monitor-procfs.c
@@ -0,0 +1,348 @@
+/*
+ * Copyright (C) 2001, 2002 Free Software Foundation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Authors : Carlos García Campos <carlosgc@gnome.org>
+ */
+
+#include <gnome.h>
+#include <libgnomevfs/gnome-vfs.h>
+#include <glib/gi18n.h>
+
+#include <string.h>
+
+#include "cpufreq-monitor-procfs.h"
+#include "cpufreq-monitor-protected.h"
+
+#define PARENT_TYPE TYPE_CPUFREQ_MONITOR
+
+#define CPUFREQ_MONITOR_GET_PROTECTED(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), PARENT_TYPE, CPUFreqMonitorProtected))
+
+static void cpufreq_monitor_procfs_class_init (CPUFreqMonitorProcfsClass *klass);
+static void cpufreq_monitor_procfs_finalize (GObject *object);
+
+static void cpufreq_monitor_procfs_run (CPUFreqMonitor *monitor);
+static GList *cpufreq_monitor_procfs_get_available_frequencies (CPUFreqMonitor *monitor);
+
+static gint cpufreq_monitor_procfs_get_freq_from_userspace (guint cpu);
+static gboolean cpufreq_monitor_procfs_parse (CPUFreqMonitorProcfs *monitor, gint *cpu, gint *fmax,
+ gint *pmin, gint *pmax, gint *fmin, gchar *mode);
+static gboolean cpufreq_monitor_procfs_get (gpointer gdata);
+
+
+static CPUFreqMonitorClass *parent_class = NULL;
+
+typedef struct _CPUFreqMonitorProtected CPUFreqMonitorProtected;
+
+GType cpufreq_monitor_procfs_get_type ()
+{
+ static GType type = 0;
+
+ if (!type) {
+ static const GTypeInfo info = {
+ sizeof (CPUFreqMonitorProcfsClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) cpufreq_monitor_procfs_class_init,
+ NULL,
+ NULL,
+ sizeof (CPUFreqMonitorProcfs),
+ 0,
+ NULL
+ };
+
+ type = g_type_register_static (PARENT_TYPE, "CPUFreqMonitorProcfs",
+ &info, 0);
+ }
+
+ return type;
+}
+
+static void
+cpufreq_monitor_procfs_class_init (CPUFreqMonitorProcfsClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ CPUFreqMonitorClass *monitor_class = CPUFREQ_MONITOR_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ monitor_class->run = cpufreq_monitor_procfs_run;
+ monitor_class->get_available_frequencies = cpufreq_monitor_procfs_get_available_frequencies;
+
+ object_class->finalize = cpufreq_monitor_procfs_finalize;
+}
+
+static void
+cpufreq_monitor_procfs_finalize (GObject *object)
+{
+ g_return_if_fail (IS_CPUFREQ_MONITOR_PROCFS (object));
+
+ if (G_OBJECT_CLASS (parent_class)->finalize)
+ (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+}
+
+CPUFreqMonitor *
+cpufreq_monitor_procfs_new (guint cpu)
+{
+ CPUFreqMonitorProcfs *monitor;
+
+ monitor = g_object_new (TYPE_CPUFREQ_MONITOR_PROCFS, "cpu", cpu, NULL);
+
+ return CPUFREQ_MONITOR (monitor);
+}
+
+static gint
+cpufreq_monitor_procfs_get_freq_from_userspace (guint cpu)
+{
+ GnomeVFSHandle *handle;
+ GnomeVFSFileSize bytes_read;
+ GnomeVFSResult result;
+ gchar *uri, *path;
+ gchar buffer[256];
+ gchar *frequency;
+ gint freq;
+
+ path = g_strdup_printf ("/proc/sys/cpu/%d/speed", cpu);
+ uri = gnome_vfs_get_uri_from_local_path (path);
+ g_free (path);
+
+ result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
+ if (result != GNOME_VFS_OK) {
+ if (uri) g_free (uri);
+
+ return -1;
+ }
+
+ g_free (uri);
+
+ result = gnome_vfs_read (handle, buffer, 256, &bytes_read);
+ frequency = g_strndup (buffer, bytes_read);
+ freq = atoi (frequency);
+ g_free (frequency);
+
+ if (result != GNOME_VFS_OK) {
+ return -1;
+ }
+
+ result = gnome_vfs_close (handle);
+ if (result != GNOME_VFS_OK) {
+ return -1;
+ }
+
+ return freq;
+}
+
+static gboolean
+cpufreq_monitor_procfs_parse (CPUFreqMonitorProcfs *monitor, gint *cpu, gint *fmax,
+ gint *pmin, gint *pmax, gint *fmin, gchar *mode)
+{
+ GnomeVFSHandle *handle;
+ GnomeVFSFileSize bytes_read;
+ GnomeVFSResult result;
+ gchar *uri, *file;
+ gchar **lines;
+ gchar buffer[256];
+ gint i, count;
+ CPUFreqMonitorProtected *private;
+
+ g_return_val_if_fail (IS_CPUFREQ_MONITOR (monitor), FALSE);
+
+ private = CPUFREQ_MONITOR_GET_PROTECTED (CPUFREQ_MONITOR (monitor));
+
+ uri = gnome_vfs_get_uri_from_local_path ("/proc/cpufreq");
+
+ result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
+ if (result != GNOME_VFS_OK) {
+ if (uri) g_free (uri);
+
+ return FALSE;
+ }
+
+ g_free (uri);
+
+ result = gnome_vfs_read (handle, buffer, 256, &bytes_read);
+ file = g_strndup (buffer, bytes_read);
+ if (result != GNOME_VFS_OK) {
+ g_free (file);
+
+ return FALSE;
+ }
+
+ result = gnome_vfs_close (handle);
+ if (result != GNOME_VFS_OK) {
+ g_free (file);
+
+ return FALSE;
+ }
+
+ lines = g_strsplit (file, "\n", -1);
+ for (i=0; lines[i]; i++) {
+ if (g_ascii_strncasecmp (lines[i], "CPU", 3) == 0) {
+ /* CPU 0 650000 kHz ( 81 %) - 800000 kHz (100 %) - powersave */
+ count = sscanf (lines[i], "CPU %d %d kHz (%d %%) - %d kHz (%d %%) - %20s",
+ cpu, fmin, pmin, fmax, pmax, mode);
+
+ if ((*cpu) == private->cpu)
+ break;
+ }
+ }
+
+ g_strfreev (lines);
+ g_free (file);
+
+ if (count != 6) {
+ /* TODO: manage error */
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+cpufreq_monitor_procfs_get (gpointer gdata)
+{
+ gint fmax, fmin, cpu, ifreq;
+ gint pmin, pmax;
+ gchar mode[21];
+ gchar *freq, *perc, *unit, *governor;
+ gboolean changed;
+ CPUFreqMonitorProcfs *monitor;
+ CPUFreqMonitorProtected *private;
+
+ monitor = (CPUFreqMonitorProcfs *) gdata;
+
+ if (!cpufreq_monitor_procfs_parse (monitor, &cpu, &fmax, &pmin, &pmax, &fmin, mode))
+ return FALSE;
+
+ private = CPUFREQ_MONITOR_GET_PROTECTED (CPUFREQ_MONITOR (monitor));
+
+ governor = g_strdup (mode);
+
+ if (g_ascii_strcasecmp (governor, "powersave") == 0) {
+ freq = parent_class->get_human_readable_freq (fmin);
+ perc = g_strdup_printf ("%d%%", pmin);
+ unit = parent_class->get_human_readable_unit (fmin);
+ } else if (g_ascii_strcasecmp (governor, "performance") == 0) {
+ freq = parent_class->get_human_readable_freq (fmax);
+ perc = g_strdup_printf ("%d%%", pmax);
+ unit = parent_class->get_human_readable_unit (fmax);
+ } else if (g_ascii_strcasecmp (governor, "userspace") == 0) {
+ ifreq = cpufreq_monitor_procfs_get_freq_from_userspace (private->cpu);
+ freq = parent_class->get_human_readable_freq (ifreq);
+ perc = parent_class->get_human_readable_perc (fmax, ifreq);
+ unit = parent_class->get_human_readable_unit (ifreq);
+ } else {
+ freq = g_strdup (_("Unknown"));
+ perc = g_strdup ("-");
+ unit = g_strdup ("-");
+ }
+
+ changed = FALSE;
+
+ if (!private->governor || (g_ascii_strcasecmp (governor, private->governor) != 0)) {
+ changed = TRUE;
+ }
+
+ if (!private->freq || (g_ascii_strcasecmp (freq, private->freq) != 0)) {
+ changed = TRUE;
+ }
+
+ if (!private->perc || (g_ascii_strcasecmp (perc, private->perc) != 0)) {
+ changed = TRUE;
+ }
+
+ if (!private->unit || (g_ascii_strcasecmp (unit, private->unit) != 0)) {
+ changed = TRUE;
+ }
+
+ parent_class->free_data (CPUFREQ_MONITOR (monitor));
+
+ private->governor = governor;
+ private->freq = freq;
+ private->perc = perc;
+ private->unit = unit;
+
+ if (private->governor == NULL)
+ return FALSE;
+ if (private->freq == NULL)
+ return FALSE;
+ if (private->perc == NULL)
+ return FALSE;
+ if (private->unit == NULL)
+ return FALSE;
+
+ if (changed)
+ g_signal_emit (CPUFREQ_MONITOR (monitor), parent_class->signals[CHANGED], 0);
+
+ return TRUE;
+}
+
+static void
+cpufreq_monitor_procfs_run (CPUFreqMonitor *monitor)
+{
+ CPUFreqMonitorProtected *private;
+
+ g_return_if_fail (IS_CPUFREQ_MONITOR_PROCFS (monitor));
+
+ private = CPUFREQ_MONITOR_GET_PROTECTED (CPUFREQ_MONITOR (monitor));
+
+ if (private->timeout_handler > 0)
+ g_source_remove (private->timeout_handler);
+
+ private->timeout_handler = g_timeout_add (1000, cpufreq_monitor_procfs_get, (gpointer) monitor);
+}
+
+static void
+free_string (gpointer str, gpointer gdata)
+{
+ if (str) g_free (str);
+}
+
+static GList *
+cpufreq_monitor_procfs_get_available_frequencies (CPUFreqMonitor *monitor)
+{
+ gint fmax, fmin, cpu, freq;
+ gint pmin, pmax;
+ gchar mode[21];
+ GList *list = NULL;
+ CPUFreqMonitorProtected *private;
+
+ g_return_val_if_fail (IS_CPUFREQ_MONITOR_PROCFS (monitor), NULL);
+
+ private = CPUFREQ_MONITOR_GET_PROTECTED (CPUFREQ_MONITOR (monitor));
+
+ if (private->available_freqs) {
+ g_list_foreach (private->available_freqs,
+ free_string, NULL);
+ g_list_free (private->available_freqs);
+ private->available_freqs = NULL;
+ }
+
+ if (!cpufreq_monitor_procfs_parse (CPUFREQ_MONITOR_PROCFS (monitor), &cpu, &fmax, &pmin, &pmax, &fmin, mode))
+ return NULL;
+
+ if ((pmax > 0) && (pmax != 100)) {
+ freq = (fmax * 100) / pmax;
+ private->available_freqs = g_list_append (private->available_freqs, g_strdup_printf ("%d", freq));
+ }
+
+ private->available_freqs = g_list_append (private->available_freqs, g_strdup_printf ("%d", fmax));
+ if (fmax != fmin)
+ private->available_freqs = g_list_append (private->available_freqs, g_strdup_printf ("%d", fmin));
+
+ return private->available_freqs;
+}
+
diff --git a/cpufreq/src/cpufreq-monitor-procfs.h b/cpufreq/src/cpufreq-monitor-procfs.h
new file mode 100644
index 000000000..19b1ceac3
--- /dev/null
+++ b/cpufreq/src/cpufreq-monitor-procfs.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2001, 2002 Free Software Foundation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Authors : Carlos García Campos <carlosgc@gnome.org>
+ */
+
+#ifndef __CPUFREQ_MONITOR_PROCFS_H__
+#define __CPUFREQ_MONITOR_PROCFS_H__
+
+#include <glib-object.h>
+#include "cpufreq-monitor.h"
+
+#define TYPE_CPUFREQ_MONITOR_PROCFS (cpufreq_monitor_procfs_get_type ())
+#define CPUFREQ_MONITOR_PROCFS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_CPUFREQ_MONITOR_PROCFS, CPUFreqMonitorProcfs))
+#define CPUFREQ_MONITOR_PROCFS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TYPE_CPUFREQ_MONITOR_PROCFS, CPUFreqMonitorProcfsClass))
+#define IS_CPUFREQ_MONITOR_PROCFS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_CPUFREQ_MONITOR_PROCFS))
+#define IS_CPUFREQ_MONITOR_PROCFS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_CPUFREQ_MONITOR_PROCFS))
+#define CPUFREQ_MONITOR_PROCFS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_CPUFREQ_MONITOR_PROCFS, CPUFreqMonitorProcfsClass))
+
+typedef struct _CPUFreqMonitorProcfs CPUFreqMonitorProcfs;
+typedef struct _CPUFreqMonitorProcfsClass CPUFreqMonitorProcfsClass;
+
+struct _CPUFreqMonitorProcfs {
+ CPUFreqMonitor parent;
+};
+
+struct _CPUFreqMonitorProcfsClass {
+ CPUFreqMonitorClass parent_class;
+};
+
+GType cpufreq_monitor_procfs_get_type ();
+CPUFreqMonitor *cpufreq_monitor_procfs_new (guint cpu);
+
+#endif /* __CPUFREQ_MONITOR_PROCFS_H__ */
diff --git a/cpufreq/src/cpufreq-monitor-protected.h b/cpufreq/src/cpufreq-monitor-protected.h
new file mode 100644
index 000000000..e776196f5
--- /dev/null
+++ b/cpufreq/src/cpufreq-monitor-protected.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2001, 2002 Free Software Foundation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Authors : Carlos García Campos <carlosgc@gnome.org>
+ */
+
+struct _CPUFreqMonitorProtected
+{
+ guint cpu;
+ gchar *freq;
+ gchar *perc;
+ gchar *unit;
+ gchar *governor;
+ GList *available_freqs;
+ guint timeout_handler;
+};
diff --git a/cpufreq/src/cpufreq-monitor-sysfs.c b/cpufreq/src/cpufreq-monitor-sysfs.c
new file mode 100644
index 000000000..c821862b7
--- /dev/null
+++ b/cpufreq/src/cpufreq-monitor-sysfs.c
@@ -0,0 +1,373 @@
+/*
+ * Copyright (C) 2001, 2002 Free Software Foundation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Authors : Carlos García Campos <carlosgc@gnome.org>
+ */
+
+
+#include <gnome.h>
+#include <libgnomevfs/gnome-vfs.h>
+#include <glib/gi18n.h>
+
+#include <string.h>
+
+#include "cpufreq-monitor-sysfs.h"
+#include "cpufreq-monitor-protected.h"
+
+#define PARENT_TYPE TYPE_CPUFREQ_MONITOR
+
+#define CPUFREQ_MONITOR_GET_PROTECTED(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), PARENT_TYPE, CPUFreqMonitorProtected))
+
+static void cpufreq_monitor_sysfs_class_init (CPUFreqMonitorSysfsClass *klass);
+static void cpufreq_monitor_sysfs_finalize (GObject *object);
+
+static void cpufreq_monitor_sysfs_run (CPUFreqMonitor *monitor);
+static GList *cpufreq_monitor_sysfs_get_available_frequencies (CPUFreqMonitor *monitor);
+
+static gboolean cpufreq_monitor_sysfs_get (gpointer gdata);
+
+
+static CPUFreqMonitorClass *parent_class = NULL;
+
+typedef struct _CPUFreqMonitorProtected CPUFreqMonitorProtected;
+
+GType cpufreq_monitor_sysfs_get_type ()
+{
+ static GType type = 0;
+
+ if (!type) {
+ static const GTypeInfo info = {
+ sizeof (CPUFreqMonitorSysfsClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) cpufreq_monitor_sysfs_class_init,
+ NULL,
+ NULL,
+ sizeof (CPUFreqMonitorSysfs),
+ 0,
+ NULL
+ };
+
+ type = g_type_register_static (PARENT_TYPE, "CPUFreqMonitorSysfs",
+ &info, 0);
+ }
+
+ return type;
+}
+
+static void
+cpufreq_monitor_sysfs_class_init (CPUFreqMonitorSysfsClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ CPUFreqMonitorClass *monitor_class = CPUFREQ_MONITOR_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ monitor_class->run = cpufreq_monitor_sysfs_run;
+ monitor_class->get_available_frequencies = cpufreq_monitor_sysfs_get_available_frequencies;
+
+ object_class->finalize = cpufreq_monitor_sysfs_finalize;
+}
+
+static void
+cpufreq_monitor_sysfs_finalize (GObject *object)
+{
+ g_return_if_fail (IS_CPUFREQ_MONITOR_SYSFS (object));
+
+ if (G_OBJECT_CLASS (parent_class)->finalize)
+ (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+}
+
+CPUFreqMonitor *
+cpufreq_monitor_sysfs_new (guint cpu)
+{
+ CPUFreqMonitorSysfs *monitor;
+
+ monitor = g_object_new (TYPE_CPUFREQ_MONITOR_SYSFS, "cpu", cpu, NULL);
+
+ return CPUFREQ_MONITOR (monitor);
+}
+
+static gboolean
+cpufreq_monitor_sysfs_get (gpointer gdata)
+{
+ GnomeVFSHandle *handle;
+ GnomeVFSFileSize bytes_read;
+ GnomeVFSResult result;
+ gchar *uri;
+ gchar buffer[20];
+ gint i;
+ gchar **cpufreq_data;
+ gchar *path;
+ gchar *freq, *perc, *unit, *governor;
+ gboolean changed;
+ CPUFreqMonitorSysfs *monitor;
+ CPUFreqMonitorProtected *private;
+ gchar *files[] = {
+ "scaling_max_freq",
+ "scaling_min_freq",
+ "scaling_governor",
+ "cpuinfo_max_freq",
+ "scaling_setspeed",
+ "scaling_cur_freq",
+ NULL };
+
+ enum {
+ SCALING_MAX,
+ SCALING_MIN,
+ GOVERNOR,
+ CPUINFO_MAX,
+ SCALING_SETSPEED,
+ SCALING_CUR_FREQ,
+ LAST
+ };
+
+ monitor = (CPUFreqMonitorSysfs *) gdata;
+
+ private = CPUFREQ_MONITOR_GET_PROTECTED (CPUFREQ_MONITOR (monitor));
+
+ /* /sys/devices/system/cpu/cpu[0]/cpufreq/scaling_max_freq
+ * /sys/devices/system/cpu/cpu[0]/cpufreq/scaling_min_freq
+ * /sys/devices/system/cpu/cpu[0]/cpufreq/scaling_governor
+ * /sys/devices/system/cpu/cpu[0]/cpufreq/cpuinfo_max_freq
+ * /sys/devices/system/cpu/cpu[0]/cpufreq/scaling_setspeed (userspace)
+ * /sys/devices/system/cpu/cpu[0]/cpufreq/scaling_cur_freq (new governors)
+ */
+
+ cpufreq_data = g_new (gchar *, LAST + 1);
+
+ for (i = 0; i < LAST; i++) {
+ cpufreq_data[i] = NULL;
+
+ path = g_strdup_printf ("/sys/devices/system/cpu/cpu%d/cpufreq/%s",
+ private->cpu, files[i]);
+
+ if (!g_file_test (path, G_FILE_TEST_EXISTS)) {
+ cpufreq_data[i] = g_strdup ("");
+ buffer[0] = '\0';
+ g_free (path);
+
+ continue;
+ }
+
+ uri = gnome_vfs_get_uri_from_local_path (path);
+ g_free (path);
+
+ result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
+ if (result != GNOME_VFS_OK) {
+ if (uri) g_free (uri);
+ g_strfreev (cpufreq_data);
+
+ return FALSE;
+ }
+
+ g_free (uri);
+
+ result = gnome_vfs_read (handle, buffer, sizeof (buffer), &bytes_read);
+
+ /* bytes_read - 1 in order to remove the \n character */
+ cpufreq_data[i] = g_strndup (buffer, bytes_read - 1);
+
+ if (result != GNOME_VFS_OK) {
+ g_strfreev (cpufreq_data);
+ gnome_vfs_close (handle);
+
+ return FALSE;
+ }
+
+ result = gnome_vfs_close (handle);
+ if (result != GNOME_VFS_OK) {
+ g_strfreev (cpufreq_data);
+
+ return FALSE;
+ }
+ buffer[0] = '\0';
+ }
+ cpufreq_data[LAST] = NULL;
+
+ governor = g_strdup (cpufreq_data[GOVERNOR]);
+
+ if (g_ascii_strcasecmp (governor, "userspace") == 0) {
+ freq = parent_class->get_human_readable_freq (atoi (cpufreq_data[SCALING_SETSPEED]));
+ perc = parent_class->get_human_readable_perc (atoi (cpufreq_data[CPUINFO_MAX]),
+ atoi (cpufreq_data[SCALING_SETSPEED]));
+ unit = parent_class->get_human_readable_unit (atoi (cpufreq_data[SCALING_SETSPEED]));
+ } else if (g_ascii_strcasecmp (governor, "powersave") == 0) {
+ freq = parent_class->get_human_readable_freq (atoi (cpufreq_data[SCALING_MIN]));
+ perc = parent_class->get_human_readable_perc (atoi (cpufreq_data[CPUINFO_MAX]),
+ atoi (cpufreq_data[SCALING_MIN]));
+ unit = parent_class->get_human_readable_unit (atoi (cpufreq_data[SCALING_MIN]));
+ } else if (g_ascii_strcasecmp (governor, "performance") == 0) {
+ freq = parent_class->get_human_readable_freq (atoi (cpufreq_data[SCALING_MAX]));
+ perc = parent_class->get_human_readable_perc (atoi (cpufreq_data[CPUINFO_MAX]),
+ atoi (cpufreq_data[SCALING_MAX]));
+ unit = parent_class->get_human_readable_unit (atoi (cpufreq_data[SCALING_MAX]));
+ } else {
+ freq = parent_class->get_human_readable_freq (atoi (cpufreq_data[SCALING_CUR_FREQ]));
+ perc = parent_class->get_human_readable_perc (atoi (cpufreq_data[CPUINFO_MAX]),
+ atoi (cpufreq_data[SCALING_CUR_FREQ]));
+ unit = parent_class->get_human_readable_unit (atoi (cpufreq_data[SCALING_CUR_FREQ]));
+ }
+
+ g_strfreev (cpufreq_data);
+
+ changed = FALSE;
+
+ if (!private->governor || (g_ascii_strcasecmp (governor, private->governor) != 0)) {
+ changed = TRUE;
+ }
+
+ if (!private->freq || (g_ascii_strcasecmp (freq, private->freq) != 0)) {
+
+ changed = TRUE;
+ }
+
+ if (!private->perc || (g_ascii_strcasecmp (perc, private->perc) != 0)) {
+ changed = TRUE;
+ }
+
+ if (!private->unit || (g_ascii_strcasecmp (unit, private->unit) != 0)) {
+ changed = TRUE;
+ }
+
+ parent_class->free_data (CPUFREQ_MONITOR (monitor));
+
+ private->governor = governor;
+ private->freq = freq;
+ private->perc = perc;
+ private->unit = unit;
+
+ if (private->governor == NULL)
+ return FALSE;
+ if (private->freq == NULL)
+ return FALSE;
+ if (private->perc == NULL)
+ return FALSE;
+ if (private->unit == NULL)
+ return FALSE;
+
+ if (changed)
+ g_signal_emit (CPUFREQ_MONITOR (monitor), parent_class->signals[CHANGED], 0);
+
+ return TRUE;
+}
+
+static void
+cpufreq_monitor_sysfs_run (CPUFreqMonitor *monitor)
+{
+ CPUFreqMonitorProtected *private;
+
+ g_return_if_fail (IS_CPUFREQ_MONITOR_SYSFS (monitor));
+
+ private = CPUFREQ_MONITOR_GET_PROTECTED (CPUFREQ_MONITOR (monitor));
+
+ if (private->timeout_handler > 0)
+ g_source_remove (private->timeout_handler);
+
+ private->timeout_handler = g_timeout_add (1000, cpufreq_monitor_sysfs_get, (gpointer) monitor);
+}
+
+static gint
+compare (gconstpointer a, gconstpointer b)
+{
+ gint aa, bb;
+
+ aa = atoi ((gchar *) a);
+ bb = atoi ((gchar *) b);
+
+ if (aa == bb)
+ return 0;
+ else if (aa > bb)
+ return -1;
+ else
+ return 1;
+}
+
+static GList *
+cpufreq_monitor_sysfs_get_available_frequencies (CPUFreqMonitor *monitor)
+{
+ GnomeVFSHandle *handle;
+ GnomeVFSFileSize bytes_read;
+ GnomeVFSResult result;
+ gchar *uri;
+ gchar buffer[256];
+ gchar *str;
+ gchar *path;
+ GList *list = NULL;
+ gchar **frequencies = NULL;
+ gint i;
+ CPUFreqMonitorProtected *private;
+
+ g_return_val_if_fail (IS_CPUFREQ_MONITOR_SYSFS (monitor), NULL);
+
+ private = CPUFREQ_MONITOR_GET_PROTECTED (CPUFREQ_MONITOR (monitor));
+
+ if (private->available_freqs) {
+ return private->available_freqs;
+ }
+
+ path = g_strdup_printf ("/sys/devices/system/cpu/cpu%d/cpufreq/scaling_available_frequencies",
+ private->cpu);
+
+ uri = gnome_vfs_get_uri_from_local_path (path);
+ g_free (path);
+
+ result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
+ if (result != GNOME_VFS_OK) {
+ if (uri) g_free (uri);
+
+ return FALSE;
+ }
+
+ g_free (uri);
+
+ result = gnome_vfs_read (handle, buffer, sizeof (buffer), &bytes_read);
+
+ str = g_strndup (buffer, bytes_read);
+ str = g_strchomp (str);
+
+ frequencies = g_strsplit (str, " ", 0);
+
+ if (result != GNOME_VFS_OK) {
+ g_strfreev (frequencies);
+ gnome_vfs_close (handle);
+
+ return FALSE;
+ }
+
+ result = gnome_vfs_close (handle);
+ if (result != GNOME_VFS_OK) {
+ g_strfreev (frequencies);
+
+ return FALSE;
+ }
+
+ i = 0;
+ while (frequencies[i] != NULL) {
+ if (!g_list_find_custom (list, frequencies[i], compare))
+ list = g_list_append (list, g_strdup (frequencies[i]));
+ i++;
+ }
+
+ g_strfreev (frequencies);
+ g_free (str);
+
+ private->available_freqs = g_list_sort (list, compare);
+
+ return private->available_freqs;
+}
+
diff --git a/cpufreq/src/cpufreq-monitor-sysfs.h b/cpufreq/src/cpufreq-monitor-sysfs.h
new file mode 100644
index 000000000..77263c53a
--- /dev/null
+++ b/cpufreq/src/cpufreq-monitor-sysfs.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2001, 2002 Free Software Foundation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Authors : Carlos García Campos <carlosgc@gnome.org>
+ */
+
+#ifndef __CPUFREQ_MONITOR_SYSFS_H__
+#define __CPUFREQ_MONITOR_SYSFS_H__
+
+#include <glib-object.h>
+#include "cpufreq-monitor.h"
+
+#define TYPE_CPUFREQ_MONITOR_SYSFS (cpufreq_monitor_sysfs_get_type ())
+#define CPUFREQ_MONITOR_SYSFS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_CPUFREQ_MONITOR_SYSFS, CPUFreqMonitorSysfs))
+#define CPUFREQ_MONITOR_SYSFS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TYPE_CPUFREQ_MONITOR_SYSFS, CPUFreqMonitorSysfsClass))
+#define IS_CPUFREQ_MONITOR_SYSFS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_CPUFREQ_MONITOR_SYSFS))
+#define IS_CPUFREQ_MONITOR_SYSFS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_CPUFREQ_MONITOR_SYSFS))
+#define CPUFREQ_MONITOR_SYSFS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_CPUFREQ_MONITOR_SYSFS, CPUFreqMonitorSysfsClass))
+
+typedef struct _CPUFreqMonitorSysfs CPUFreqMonitorSysfs;
+typedef struct _CPUFreqMonitorSysfsClass CPUFreqMonitorSysfsClass;
+
+struct _CPUFreqMonitorSysfs {
+ CPUFreqMonitor parent;
+};
+
+struct _CPUFreqMonitorSysfsClass {
+ CPUFreqMonitorClass parent_class;
+};
+
+GType cpufreq_monitor_sysfs_get_type ();
+CPUFreqMonitor *cpufreq_monitor_sysfs_new (guint cpu);
+
+#endif /* __CPUFREQ_MONITOR_SYSFS_H__ */
diff --git a/cpufreq/src/cpufreq-monitor.c b/cpufreq/src/cpufreq-monitor.c
new file mode 100644
index 000000000..8dc7d0a68
--- /dev/null
+++ b/cpufreq/src/cpufreq-monitor.c
@@ -0,0 +1,375 @@
+/*
+ * Copyright (C) 2001, 2002 Free Software Foundation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Authors : Carlos García Campos <carlosgc@gnome.org>
+ */
+
+
+#include <gnome.h>
+
+#include "cpufreq-monitor.h"
+#include "cpufreq-monitor-protected.h"
+
+#define PARENT_TYPE G_TYPE_OBJECT
+
+#define CPUFREQ_MONITOR_GET_PROTECTED(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), TYPE_CPUFREQ_MONITOR, CPUFreqMonitorProtected))
+
+enum {
+ PROP_0,
+ PROP_CPU
+};
+
+static void cpufreq_monitor_init (CPUFreqMonitor *monitor);
+static void cpufreq_monitor_class_init (CPUFreqMonitorClass *klass);
+static void cpufreq_monitor_finalize (GObject *object);
+
+static void cpufreq_monitor_set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *spec);
+static void cpufreq_monitor_get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *spec);
+
+static gchar *cpufreq_monitor_get_human_readable_freq (gint freq);
+static gchar *cpufreq_monitor_get_human_readable_unit (gint freq);
+static gchar *cpufreq_monitor_get_human_readable_perc (gint fmax, gint fmin);
+
+static void cpufreq_monitor_free_data (CPUFreqMonitor *monitor);
+
+static GObjectClass *parent_class = NULL;
+
+typedef struct _CPUFreqMonitorProtected CPUFreqMonitorProtected;
+
+GType cpufreq_monitor_get_type ()
+{
+ static GType type = 0;
+
+ if (!type) {
+ static const GTypeInfo info = {
+ sizeof (CPUFreqMonitorClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) cpufreq_monitor_class_init,
+ NULL,
+ NULL,
+ sizeof (CPUFreqMonitor),
+ 0,
+ (GInstanceInitFunc) cpufreq_monitor_init
+ };
+
+ type = g_type_register_static (PARENT_TYPE, "CPUFreqMonitor",
+ &info, G_TYPE_FLAG_ABSTRACT);
+ }
+
+ return type;
+}
+
+static void
+cpufreq_monitor_init (CPUFreqMonitor *monitor)
+{
+ CPUFreqMonitorProtected *private;
+
+ g_return_if_fail (IS_CPUFREQ_MONITOR (monitor));
+
+ private = CPUFREQ_MONITOR_GET_PROTECTED (monitor);
+ private->freq = NULL;
+ private->perc = NULL;
+ private->unit = NULL;
+ private->governor = NULL;
+ private->available_freqs = NULL;
+ private->timeout_handler = 0;
+}
+
+static void
+cpufreq_monitor_class_init (CPUFreqMonitorClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ CPUFreqMonitorClass *monitor_class = CPUFREQ_MONITOR_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ object_class->set_property = cpufreq_monitor_set_property;
+ object_class->get_property = cpufreq_monitor_get_property;
+
+ /* Public virtual methods */
+ monitor_class->run = NULL;
+ monitor_class->get_available_frequencies = NULL;
+
+ /* Protected methods */
+ monitor_class->get_human_readable_freq = cpufreq_monitor_get_human_readable_freq;
+ monitor_class->get_human_readable_unit = cpufreq_monitor_get_human_readable_unit;
+ monitor_class->get_human_readable_perc = cpufreq_monitor_get_human_readable_perc;
+
+ monitor_class->free_data = cpufreq_monitor_free_data;
+
+ /* Porperties */
+ g_object_class_install_property (object_class, PROP_CPU,
+ g_param_spec_uint ("cpu", NULL, NULL,
+ 0, /* MIN_UINT */
+ G_MAXUINT,
+ 0, /* Default */
+ G_PARAM_CONSTRUCT | G_PARAM_WRITABLE ));
+
+ /* Protected attributes */
+ g_type_class_add_private (klass, sizeof (CPUFreqMonitorProtected));
+
+ /* Signals */
+ monitor_class->signals[CHANGED] =
+ g_signal_new ("changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CPUFreqMonitorClass, changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ object_class->finalize = cpufreq_monitor_finalize;
+}
+
+static void
+free_string (gpointer str, gpointer gdata)
+{
+ if (str) g_free (str);
+}
+
+static void
+cpufreq_monitor_finalize (GObject *object)
+{
+ CPUFreqMonitorProtected *private;
+
+ g_return_if_fail (IS_CPUFREQ_MONITOR (object));
+
+ private = CPUFREQ_MONITOR_GET_PROTECTED (object);
+
+ if (private->timeout_handler > 0)
+ g_source_remove (private->timeout_handler);
+
+ cpufreq_monitor_free_data (CPUFREQ_MONITOR (object));
+
+ if (private->available_freqs) {
+ g_list_foreach (private->available_freqs,
+ free_string, NULL);
+ g_list_free (private->available_freqs);
+ private->available_freqs = NULL;
+ }
+
+ if (G_OBJECT_CLASS (parent_class)->finalize)
+ (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+}
+
+static gchar *
+cpufreq_monitor_get_human_readable_freq (gint freq)
+{
+ gint divisor;
+
+ if (freq > 999999) /* freq (kHz) */
+ divisor = (1000 * 1000);
+ else
+ divisor = 1000;
+
+ if (((freq % divisor) == 0) || divisor == 1000) /* integer */
+ return g_strdup_printf ("%d", freq / divisor);
+ else /* float */
+ return g_strdup_printf ("%3.2f", ((gfloat)freq / divisor));
+}
+
+static gchar *
+cpufreq_monitor_get_human_readable_unit (gint freq)
+{
+ if (freq > 999999) /* freq (kHz) */
+ return g_strdup ("GHz");
+ else
+ return g_strdup ("MHz");
+}
+
+static gchar *
+cpufreq_monitor_get_human_readable_perc (gint fmax, gint fmin)
+{
+ if (fmax > 0)
+ return g_strdup_printf ("%d%%", (fmin * 100) / fmax);
+ else
+ return NULL;
+}
+
+static void
+cpufreq_monitor_set_property (GObject *object, guint prop_id, const GValue *value,
+ GParamSpec *spec)
+{
+ CPUFreqMonitor *monitor;
+ CPUFreqMonitorProtected *private;
+
+ g_return_if_fail (IS_CPUFREQ_MONITOR (object));
+
+ monitor = CPUFREQ_MONITOR (object);
+ private = CPUFREQ_MONITOR_GET_PROTECTED (monitor);
+
+ switch (prop_id) {
+ case PROP_CPU:
+ private->cpu = g_value_get_uint (value);
+ break;
+ default:
+ break;
+ }
+}
+
+/* Is it neccesary?? */
+static void
+cpufreq_monitor_get_property (GObject *object, guint prop_id, GValue *value,
+ GParamSpec *spec)
+{
+ CPUFreqMonitor *monitor;
+ CPUFreqMonitorProtected *private;
+
+ g_return_if_fail (IS_CPUFREQ_MONITOR (object));
+
+ monitor = CPUFREQ_MONITOR (object);
+ private = CPUFREQ_MONITOR_GET_PROTECTED (monitor);
+
+ switch (prop_id) {
+ case PROP_CPU:
+ g_value_set_uint (value, private->cpu);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, spec);
+ }
+}
+
+static void
+cpufreq_monitor_free_data (CPUFreqMonitor *monitor)
+{
+ CPUFreqMonitorProtected *private;
+
+ g_return_if_fail (IS_CPUFREQ_MONITOR (monitor));
+
+ private = CPUFREQ_MONITOR_GET_PROTECTED (monitor);
+
+ if (private->freq) {
+ g_free (private->freq);
+ private->freq = NULL;
+ }
+
+ if (private->perc) {
+ g_free (private->perc);
+ private->perc = NULL;
+ }
+
+ if (private->unit) {
+ g_free (private->unit);
+ private->unit = NULL;
+ }
+
+ if (private->governor) {
+ g_free (private->governor);
+ private->governor = NULL;
+ }
+}
+
+void
+cpufreq_monitor_run (CPUFreqMonitor *monitor)
+{
+ g_return_if_fail (IS_CPUFREQ_MONITOR (monitor));
+
+ if (CPUFREQ_MONITOR_GET_CLASS (monitor)->run) {
+ return CPUFREQ_MONITOR_GET_CLASS (monitor)->run (monitor);
+ } else {
+ return;
+ }
+}
+
+GList *
+cpufreq_monitor_get_available_frequencies (CPUFreqMonitor *monitor)
+{
+ g_return_if_fail (IS_CPUFREQ_MONITOR (monitor));
+
+ if (CPUFREQ_MONITOR_GET_CLASS (monitor)->get_available_frequencies) {
+ return CPUFREQ_MONITOR_GET_CLASS (monitor)->get_available_frequencies (monitor);
+ } else {
+ return;
+ }
+}
+
+guint
+cpufreq_monitor_get_cpu (CPUFreqMonitor *monitor)
+{
+ CPUFreqMonitorProtected *private;
+
+ g_return_if_fail (IS_CPUFREQ_MONITOR (monitor));
+
+ private = CPUFREQ_MONITOR_GET_PROTECTED (monitor);
+
+ return private->cpu;
+}
+
+gchar *
+cpufreq_monitor_get_governor (CPUFreqMonitor *monitor)
+{
+ CPUFreqMonitorProtected *private;
+
+ g_return_if_fail (IS_CPUFREQ_MONITOR (monitor));
+
+ private = CPUFREQ_MONITOR_GET_PROTECTED (monitor);
+
+ return g_strdup (private->governor);
+}
+
+gchar *
+cpufreq_monitor_get_frequency (CPUFreqMonitor *monitor)
+{
+ CPUFreqMonitorProtected *private;
+
+ g_return_if_fail (IS_CPUFREQ_MONITOR (monitor));
+
+ private = CPUFREQ_MONITOR_GET_PROTECTED (monitor);
+
+ return g_strdup (private->freq);
+}
+
+gchar *
+cpufreq_monitor_get_percentage (CPUFreqMonitor *monitor)
+{
+ CPUFreqMonitorProtected *private;
+
+ g_return_if_fail (IS_CPUFREQ_MONITOR (monitor));
+
+ private = CPUFREQ_MONITOR_GET_PROTECTED (monitor);
+
+ return g_strdup (private->perc);
+}
+
+gchar *
+cpufreq_monitor_get_unit (CPUFreqMonitor *monitor)
+{
+ CPUFreqMonitorProtected *private;
+
+ g_return_if_fail (IS_CPUFREQ_MONITOR (monitor));
+
+ private = CPUFREQ_MONITOR_GET_PROTECTED (monitor);
+
+ return g_strdup (private->unit);
+}
+
+void
+cpufreq_monitor_set_cpu (CPUFreqMonitor *monitor, guint cpu)
+{
+ CPUFreqMonitorProtected *private;
+
+ g_return_if_fail (IS_CPUFREQ_MONITOR (monitor));
+
+ private = CPUFREQ_MONITOR_GET_PROTECTED (monitor);
+
+ private->cpu = cpu;
+}
+
+
diff --git a/cpufreq/src/cpufreq-monitor.h b/cpufreq/src/cpufreq-monitor.h
new file mode 100644
index 000000000..d0d2128da
--- /dev/null
+++ b/cpufreq/src/cpufreq-monitor.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2001, 2002 Free Software Foundation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Authors : Carlos García Campos <carlosgc@gnome.org>
+ */
+
+#ifndef __CPUFREQ_MONITOR_H__
+#define __CPUFREQ_MONITOR_H__
+
+#include <glib-object.h>
+
+#define TYPE_CPUFREQ_MONITOR (cpufreq_monitor_get_type ())
+#define CPUFREQ_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_CPUFREQ_MONITOR, CPUFreqMonitor))
+#define CPUFREQ_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TYPE_CPUFREQ_MONITOR, CPUFreqMonitorClass))
+#define IS_CPUFREQ_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_CPUFREQ_MONITOR))
+#define IS_CPUFREQ_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_CPUFREQ_MONITOR))
+#define CPUFREQ_MONITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_CPUFREQ_MONITOR, CPUFreqMonitorClass))
+
+enum {
+ CHANGED,
+ LAST
+};
+
+typedef struct _CPUFreqMonitor CPUFreqMonitor;
+typedef struct _CPUFreqMonitorClass CPUFreqMonitorClass;
+
+struct _CPUFreqMonitor {
+ GObject parent;
+};
+
+struct _CPUFreqMonitorClass {
+ GObjectClass parent_class;
+
+ /*< public >*/
+ void (* run) (CPUFreqMonitor *monitor);
+ GList *(* get_available_frequencies) (CPUFreqMonitor *monitor);
+
+ /*< protected >*/
+ gchar *(* get_human_readable_freq) (gint freq);
+ gchar *(* get_human_readable_unit) (gint freq);
+ gchar *(* get_human_readable_perc) (gint fmax, gint fmin);
+ void (* free_data) (CPUFreqMonitor *monitor);
+
+ /*< signals >*/
+ guint signals[LAST];
+ void (* changed) (CPUFreqMonitor *monitor);
+};
+
+GType cpufreq_monitor_get_type ();
+
+void cpufreq_monitor_run (CPUFreqMonitor *monitor);
+GList *cpufreq_monitor_get_available_frequencies (CPUFreqMonitor *monitor);
+
+guint cpufreq_monitor_get_cpu (CPUFreqMonitor *monitor);
+gchar *cpufreq_monitor_get_governor (CPUFreqMonitor *monitor);
+gchar *cpufreq_monitor_get_frequency (CPUFreqMonitor *monitor);
+gchar *cpufreq_monitor_get_percentage (CPUFreqMonitor *monitor);
+gchar *cpufreq_monitor_get_unit (CPUFreqMonitor *monitor);
+void cpufreq_monitor_set_cpu (CPUFreqMonitor *monitor,
+ guint cpu);
+
+#endif /* __CPUFREQ_MONITOR_H__ */
diff --git a/cpufreq/src/cpufreq-popup.c b/cpufreq/src/cpufreq-popup.c
index 811f88501..7c5e1b231 100644
--- a/cpufreq/src/cpufreq-popup.c
+++ b/cpufreq/src/cpufreq-popup.c
@@ -21,9 +21,9 @@
#include <config.h>
#include <gnome.h>
-#include "cpufreq-applet.h"
+
#include "cpufreq-popup.h"
-#include "cpufreq.h"
+#include "cpufreq-monitor.h"
static gboolean cpufreq_popup_selector_is_available (void);
static void cpufreq_popup_position_menu (GtkMenu *menu, int *x, int *y,
@@ -31,13 +31,13 @@ static void cpufreq_popup_position_menu (GtkMenu *menu, int *x, in
static void cpufreq_popup_set_frequency (GtkWidget *widget, gpointer gdata);
static void cpufreq_popup_menu_item_set_image (CPUFreqApplet *applet, GtkWidget *menu_item,
gint freq, gint max_freq);
-static GtkWidget *cpufreq_popup_new (CPUFreqApplet *applet);
+static GtkWidget *cpufreq_popup_new (CPUFreqApplet *applet, GList *available_freqs);
static gboolean
cpufreq_popup_selector_is_available ()
{
struct stat *info;
- gchar *path = NULL;
+ gchar *path = NULL;
path = g_find_program_in_path ("cpufreq-selector");
if (!path)
@@ -67,10 +67,10 @@ static void
cpufreq_popup_position_menu (GtkMenu *menu, int *x, int *y,
gboolean *push_in, gpointer gdata)
{
- GtkWidget *widget;
- GtkRequisition requisition;
- gint menu_xpos;
- gint menu_ypos;
+ GtkWidget *widget;
+ GtkRequisition requisition;
+ gint menu_xpos;
+ gint menu_ypos;
widget = GTK_WIDGET (gdata);
@@ -105,63 +105,31 @@ cpufreq_popup_position_menu (GtkMenu *menu, int *x, int *y,
*push_in = TRUE;
}
-static void
-free_string (gpointer str, gpointer gdata)
-{
- if (str) g_free (str);
-}
-
gboolean
-cpufreq_popup_show (GtkWidget *widget, GdkEventButton *event, gpointer gdata)
+cpufreq_popup_show (CPUFreqApplet *applet, guint32 time)
{
- CPUFreqApplet *applet;
-
- applet = (CPUFreqApplet *) widget;
-
- if (applet->iface == IFACE_CPUINFO)
- return FALSE;
+ GList *available_freqs = NULL;
if (!cpufreq_popup_selector_is_available ())
return FALSE;
- if (event->button == 1) {
- if (applet->popup) {
- gtk_widget_destroy (applet->popup);
- applet->popup = NULL;
- }
-
- switch (applet->iface) {
- case IFACE_SYSFS:
- if (!applet->available_freqs)
- applet->available_freqs = cpufreq_get_frequencies_from_sysfs (applet);
-
- break;
- case IFACE_PROCFS:
- if (!applet->available_freqs) {
- g_list_foreach (applet->available_freqs,
- free_string, NULL);
- g_list_free (applet->available_freqs);
- applet->available_freqs = NULL;
- }
-
- applet->available_freqs = cpufreq_get_frequencies_from_procfs (applet);
-
- break;
- default:
- return FALSE;
- }
+ if (applet->popup) {
+ gtk_widget_destroy (applet->popup);
+ applet->popup = NULL;
+ }
- applet->popup = cpufreq_popup_new (applet);
+ available_freqs = cpufreq_monitor_get_available_frequencies (applet->monitor);
+ if (!available_freqs)
+ return FALSE;
+
+ applet->popup = cpufreq_popup_new (applet, available_freqs);
- gtk_widget_grab_focus (widget);
+ gtk_widget_grab_focus (GTK_WIDGET (applet));
- gtk_menu_popup (GTK_MENU (applet->popup), NULL, NULL,
- cpufreq_popup_position_menu, (gpointer) applet,
- event->button, event->time);
- return TRUE;
- }
-
- return FALSE;
+ gtk_menu_popup (GTK_MENU (applet->popup), NULL, NULL,
+ cpufreq_popup_position_menu, (gpointer) applet,
+ 1, time);
+ return TRUE;
}
static void
@@ -219,34 +187,47 @@ cpufreq_popup_menu_item_set_image (CPUFreqApplet *applet, GtkWidget *menu_item,
}
static GtkWidget *
-cpufreq_popup_new (CPUFreqApplet *applet)
+cpufreq_popup_new (CPUFreqApplet *applet, GList *available_freqs)
{
GtkWidget *popup, *menu_item;
- GList *list = NULL;
gchar *label;
gchar *text_freq, *text_unit, *text_perc;
gint freq, max_freq;
+ gint divisor;
- list = applet->available_freqs;
-
- if (list == NULL)
+ if (available_freqs == NULL)
return NULL;
popup = gtk_menu_new ();
- max_freq = atoi ((gchar *) list->data); /* First item is the max freq */
+ max_freq = atoi ((gchar *) available_freqs->data); /* First item is the max freq */
- while (list) {
- freq = atoi ((gchar *) list->data);
+ while (available_freqs) {
+ freq = atoi ((gchar *) available_freqs->data);
if (applet->show_mode != MODE_GRAPHIC &&
applet->show_text_mode == MODE_TEXT_PERCENTAGE) {
- text_perc = cpufreq_get_human_readble_perc (max_freq, freq);
- label = g_strdup_printf ("%s", text_perc);
- g_free (text_perc);
+ if (freq > 0) {
+ text_perc = g_strdup_printf ("%d%%", (freq * 100) / max_freq);
+ label = g_strdup_printf ("%s", text_perc);
+ g_free (text_perc);
+ } else {
+ label = g_strdup (_("Unknown"));
+ }
} else {
- text_freq = cpufreq_get_human_readble_freq (freq);
- text_unit = cpufreq_get_human_readble_unit (freq);
+ if (freq > 999999) {
+ divisor = (1000 * 1000);
+ text_unit = g_strdup ("GHz");
+ } else {
+ divisor = 1000;
+ text_unit = g_strdup ("MHz");
+ }
+
+ if (((freq % divisor) == 0) || divisor == 1000)
+ text_freq = g_strdup_printf ("%d", freq / divisor);
+ else
+ text_freq = g_strdup_printf ("%3.2f", ((gfloat)freq / divisor));
+
label = g_strdup_printf ("%s %s", text_freq, text_unit);
g_free (text_freq);
g_free (text_unit);
@@ -265,7 +246,7 @@ cpufreq_popup_new (CPUFreqApplet *applet)
g_free (label);
- list = g_list_next (list);
+ available_freqs = g_list_next (available_freqs);
}
return popup;
diff --git a/cpufreq/src/cpufreq-popup.h b/cpufreq/src/cpufreq-popup.h
index ef5256d69..426e4d5a1 100644
--- a/cpufreq/src/cpufreq-popup.h
+++ b/cpufreq/src/cpufreq-popup.h
@@ -20,5 +20,7 @@
#include <gnome.h>
-gboolean cpufreq_popup_show (GtkWidget *widget, GdkEventButton *event, gpointer gdata);
+#include "cpufreq-applet.h"
+
+gboolean cpufreq_popup_show (CPUFreqApplet *applet, guint32 time);
diff --git a/cpufreq/src/cpufreq-prefs.c b/cpufreq/src/cpufreq-prefs.c
index 412466f35..5a9c37d0f 100644
--- a/cpufreq/src/cpufreq-prefs.c
+++ b/cpufreq/src/cpufreq-prefs.c
@@ -40,8 +40,8 @@ static void cpufreq_prefs_cpu_number_changed (GtkWidget *show_mode, gpointer
static gboolean
cpufreq_key_is_writable (CPUFreqApplet *applet, const gchar *key)
{
- gboolean writable;
- gchar *fullkey;
+ gboolean writable;
+ gchar *fullkey;
static GConfClient *gconf_client = NULL;
if (gconf_client == NULL)
@@ -59,8 +59,9 @@ cpufreq_key_is_writable (CPUFreqApplet *applet, const gchar *key)
static void
cpufreq_prefs_show_freq_toggled (GtkWidget *show_freq, gpointer *gdata)
{
- GtkWidget *show_unit;
- gboolean key_writable;
+ GtkWidget *show_unit;
+ gboolean key_writable;
+ gchar *freq, *unit;
CPUFreqApplet *applet;
applet = (CPUFreqApplet *) gdata;
@@ -76,16 +77,24 @@ cpufreq_prefs_show_freq_toggled (GtkWidget *show_freq, gpointer *gdata)
applet->show_text_mode = MODE_TEXT_FREQUENCY_UNIT;
else
applet->show_text_mode = MODE_TEXT_FREQUENCY;
+
+ freq = cpufreq_monitor_get_frequency (applet->monitor);
- if (applet->freq) {
- gtk_label_set_label (GTK_LABEL (applet->label), applet->freq);
+ if (freq) {
+ gtk_label_set_label (GTK_LABEL (applet->label), freq);
if (applet->show_text_mode == MODE_TEXT_FREQUENCY_UNIT) {
- gtk_label_set_label (GTK_LABEL (applet->unit_label), applet->unit);
- gtk_widget_show (applet->unit_label);
+ unit = cpufreq_monitor_get_unit (applet->monitor);
+ if (unit) {
+ gtk_label_set_label (GTK_LABEL (applet->unit_label), unit);
+ gtk_widget_show (applet->unit_label);
+ g_free (unit);
+ }
} else {
gtk_widget_hide (applet->unit_label);
}
+
+ g_free (freq);
}
gtk_widget_show (applet->label);
@@ -100,12 +109,20 @@ static void
cpufreq_prefs_show_unit_toggled (GtkWidget *show_unit, gpointer *gdata)
{
CPUFreqApplet *applet;
+ gchar *unit;
applet = (CPUFreqApplet *) gdata;
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (show_unit))) {
applet->show_text_mode = MODE_TEXT_FREQUENCY_UNIT;
- gtk_label_set_label (GTK_LABEL (applet->unit_label), applet->unit);
+
+ unit = cpufreq_monitor_get_unit (applet->monitor);
+ if (unit) {
+ gtk_label_set_label (GTK_LABEL (applet->unit_label), unit);
+
+ g_free (unit);
+ }
+
gtk_widget_show (applet->unit_label);
} else {
applet->show_text_mode = MODE_TEXT_FREQUENCY;
@@ -120,15 +137,20 @@ static void
cpufreq_prefs_show_perc_toggled (GtkWidget *show_perc, gpointer *gdata)
{
CPUFreqApplet *applet;
+ gchar *perc;
applet = (CPUFreqApplet *) gdata;
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (show_perc))) {
/* Show cpu usage in percentage */
applet->show_text_mode = MODE_TEXT_PERCENTAGE;
-
- if (applet->perc)
- gtk_label_set_label (GTK_LABEL (applet->label), applet->perc);
+
+ perc = cpufreq_monitor_get_percentage (applet->monitor);
+ if (perc) {
+ gtk_label_set_label (GTK_LABEL (applet->label), perc);
+
+ g_free (perc);
+ }
gtk_widget_show (applet->label);
gtk_widget_hide (applet->unit_label);
@@ -142,18 +164,23 @@ static void
cpufreq_prefs_cpu_number_changed (GtkWidget *cpu_number, gpointer *gdata)
{
CPUFreqApplet *applet;
+ gint cpu;
applet = (CPUFreqApplet *) gdata;
- applet->cpu = gtk_combo_box_get_active (GTK_COMBO_BOX (cpu_number));
- panel_applet_gconf_set_int (PANEL_APPLET (applet), "cpu", applet->cpu, NULL);
+ cpu = gtk_combo_box_get_active (GTK_COMBO_BOX (cpu_number));
+ if (cpu >= 0) {
+ cpufreq_monitor_set_cpu (applet->monitor, cpu);
+
+ panel_applet_gconf_set_int (PANEL_APPLET (applet), "cpu", cpu, NULL);
+ }
}
static void
cpufreq_prefs_show_mode_changed (GtkWidget *show_mode, gpointer *gdata)
{
- gboolean key_writable;
- GtkWidget *show_freq, *show_unit, *show_perc;
+ gboolean key_writable;
+ GtkWidget *show_freq, *show_unit, *show_perc;
CPUFreqApplet *applet;
applet = (CPUFreqApplet *) gdata;
@@ -205,7 +232,7 @@ cpufreq_prefs_show_mode_changed (GtkWidget *show_mode, gpointer *gdata)
static void
cpufreq_prefs_response_cb (GtkDialog *dialog, gint response, gpointer gdata)
{
- GError *error;
+ GError *error;
CPUFreqApplet *applet;
applet = (CPUFreqApplet *) gdata;
@@ -229,11 +256,12 @@ cpufreq_prefs_response_cb (GtkDialog *dialog, gint response, gpointer gdata)
void
cpufreq_prefs_cpu_combo_setup (GtkWidget *cpu_number, CPUFreqApplet *applet)
{
- GtkListStore *model;
- GtkTreeIter iter;
+ GtkListStore *model;
+ GtkTreeIter iter;
GtkCellRenderer *renderer;
- gint i;
- gchar *text_label;
+ gint i;
+ gchar *text_label;
+ guint cpu;
model = gtk_list_store_new (1, G_TYPE_STRING);
gtk_combo_box_set_model (GTK_COMBO_BOX (cpu_number),
@@ -258,7 +286,9 @@ cpufreq_prefs_cpu_combo_setup (GtkWidget *cpu_number, CPUFreqApplet *applet)
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (cpu_number), renderer,
"text", 0, NULL);
- gtk_combo_box_set_active (GTK_COMBO_BOX (cpu_number), applet->cpu);
+ cpu = cpufreq_monitor_get_cpu (applet->monitor);
+
+ gtk_combo_box_set_active (GTK_COMBO_BOX (cpu_number), cpu);
gtk_widget_set_sensitive (GTK_WIDGET (cpu_number),
cpufreq_key_is_writable (applet, "cpu"));
@@ -267,8 +297,8 @@ cpufreq_prefs_cpu_combo_setup (GtkWidget *cpu_number, CPUFreqApplet *applet)
void
cpufreq_prefs_show_mode_combo_setup (GtkWidget *show_mode, CPUFreqApplet *applet)
{
- GtkListStore *model;
- GtkTreeIter iter;
+ GtkListStore *model;
+ GtkTreeIter iter;
GtkCellRenderer *renderer;
model = gtk_list_store_new (1, G_TYPE_STRING);
diff --git a/cpufreq/src/cpufreq.c b/cpufreq/src/cpufreq.c
deleted file mode 100644
index b7e606c6d..000000000
--- a/cpufreq/src/cpufreq.c
+++ /dev/null
@@ -1,591 +0,0 @@
-/*
- * Copyright (C) 2001, 2002 Free Software Foundation
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Authors : Carlos García Campos <carlosgc@gnome.org>
- */
-
-
-#include <libgnomevfs/gnome-vfs.h>
-#include <gnome.h>
-#include <string.h>
-
-#include "cpufreq-applet.h"
-#include "cpufreq.h"
-
-static gboolean cpufreq_parse_procfs (CPUFreqApplet *applet, gint *cpu, gint *fmax,
- gint *pmin, gint *pmax, gint *fmin, gchar *mode);
-static void cpufreq_applet_prepare (CPUFreqApplet *applet);
-
-gchar *
-cpufreq_get_human_readble_freq (gint freq)
-{
- gint divisor;
-
- if (freq > 999999) /* freq (kHz) */
- divisor = (1000 * 1000);
- else
- divisor = 1000;
-
- if (((freq % divisor) == 0) || divisor == 1000) /* integer */
- return g_strdup_printf ("%d", freq / divisor);
- else /* float */
- return g_strdup_printf ("%3.2f", ((gfloat)freq / divisor));
-}
-
-gchar *
-cpufreq_get_human_readble_unit (gint freq)
-{
- if (freq > 999999) /* freq (kHz) */
- return g_strdup ("GHz");
- else
- return g_strdup ("MHz");
-}
-
-gchar *
-cpufreq_get_human_readble_perc (gint fmax, gint fmin)
-{
- return g_strdup_printf ("%d%%", (fmin * 100) / fmax);
-}
-
-static gint
-cpufreq_get_freq_from_userspace_procfs (guint cpu)
-{
- GnomeVFSHandle *handle;
- GnomeVFSFileSize bytes_read;
- GnomeVFSResult result;
- gchar *uri, *path;
- gchar buffer[256];
- gchar *frequency;
- gint freq;
-
-
- path = g_strdup_printf ("/proc/sys/cpu/%d/speed", cpu);
- uri = gnome_vfs_get_uri_from_local_path (path);
- g_free (path);
-
- result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
- if (result != GNOME_VFS_OK) {
- if (uri) g_free (uri);
-
- return -1;
- }
-
- g_free (uri);
-
- result = gnome_vfs_read (handle, buffer, 256, &bytes_read);
- frequency = g_strndup (buffer, bytes_read);
- freq = atoi (frequency);
- g_free (frequency);
-
- if (result != GNOME_VFS_OK) {
- return -1;
- }
-
- result = gnome_vfs_close (handle);
- if (result != GNOME_VFS_OK) {
- return -1;
- }
-
- return freq;
-}
-
-static gboolean
-cpufreq_parse_procfs (CPUFreqApplet *applet, gint *cpu, gint *fmax,
- gint *pmin, gint *pmax, gint *fmin, gchar *mode)
-{
- GnomeVFSHandle *handle;
- GnomeVFSFileSize bytes_read;
- GnomeVFSResult result;
- gchar *uri, *file;
- gchar **lines;
- gchar buffer[256];
- gint i, count;
-
- g_return_val_if_fail (PANEL_IS_APPLET (PANEL_APPLET (applet)), FALSE);
-
- uri = gnome_vfs_get_uri_from_local_path ("/proc/cpufreq");
-
- result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
- if (result != GNOME_VFS_OK) {
- if (uri) g_free (uri);
-
- return FALSE;
- }
-
- g_free (uri);
-
- result = gnome_vfs_read (handle, buffer, 256, &bytes_read);
- file = g_strndup (buffer, bytes_read);
- if (result != GNOME_VFS_OK) {
- g_free (file);
-
- return FALSE;
- }
-
- result = gnome_vfs_close (handle);
- if (result != GNOME_VFS_OK) {
- g_free (file);
-
- return FALSE;
- }
-
- lines = g_strsplit (file, "\n", -1);
- for (i=0; lines[i]; i++) {
- if (g_ascii_strncasecmp (lines[i], "CPU", 3) == 0) {
- /* CPU 0 650000 kHz ( 81 %) - 800000 kHz (100 %) - powersave */
- count = sscanf (lines[i], "CPU %d %d kHz (%d %%) - %d kHz (%d %%) - %20s",
- cpu, fmin, pmin, fmax, pmax, mode);
-
- if ((*cpu) == applet->cpu)
- break;
- }
- }
-
- g_strfreev (lines);
- g_free (file);
-
- if (count != 6) {
- /* /proc/cpufreq contains only the header */
- applet->iface = IFACE_CPUINFO;
- cpufreq_applet_run (applet);
-
- return FALSE;
- }
-
- return TRUE;
-}
-
-static void
-cpufreq_applet_prepare (CPUFreqApplet *applet)
-{
- g_return_if_fail (PANEL_IS_APPLET (PANEL_APPLET (applet)));
-
- if (applet->freq) {
- g_free (applet->freq);
- applet->freq = NULL;
- }
-
- if (applet->perc) {
- g_free (applet->perc);
- applet->perc = NULL;
- }
-
- if (applet->unit) {
- g_free (applet->unit);
- applet->unit = NULL;
- }
-
- if (applet->governor) {
- g_free (applet->governor);
- applet->governor = NULL;
- }
-}
-
-gboolean
-cpufreq_get_from_procfs (gpointer gdata)
-{
- gint fmax, fmin, cpu, freq;
- gint pmin, pmax;
- gchar mode[21];
- CPUFreqApplet *applet;
-
- applet = (CPUFreqApplet *) gdata;
-
- g_return_val_if_fail (PANEL_IS_APPLET (PANEL_APPLET (applet)), FALSE);
-
- if (!cpufreq_parse_procfs (applet, &cpu, &fmax, &pmin, &pmax, &fmin, mode))
- return FALSE;
-
- cpufreq_applet_prepare (applet);
-
- applet->governor = g_strdup (mode);
-
- if (g_ascii_strcasecmp (applet->governor, "powersave") == 0) {
- applet->freq = cpufreq_get_human_readble_freq (fmin);
- applet->perc = g_strdup_printf ("%d%%", pmin);
- applet->unit = cpufreq_get_human_readble_unit (fmin);
- } else if (g_ascii_strcasecmp (applet->governor, "performance") == 0) {
- applet->freq = cpufreq_get_human_readble_freq (fmax);
- applet->perc = g_strdup_printf ("%d%%", pmax);
- applet->unit = cpufreq_get_human_readble_unit (fmax);
- } else if (g_ascii_strcasecmp (applet->governor, "userspace") == 0) {
- freq = cpufreq_get_freq_from_userspace_procfs (applet->cpu);
- applet->freq = cpufreq_get_human_readble_freq (freq);
- applet->perc = cpufreq_get_human_readble_perc (fmax, freq);
- applet->unit = cpufreq_get_human_readble_unit (freq);
- } else {
- applet->freq = g_strdup (_("Unknown"));
- applet->perc = g_strdup ("-");
- applet->unit = g_strdup ("-");
- }
-
- if (applet->freq == NULL)
- return FALSE;
- if (applet->perc == NULL)
- return FALSE;
- if (applet->unit == NULL)
- return FALSE;
-
- cpufreq_applet_update (applet);
-
- return TRUE;
-}
-
-static gint
-compare (gconstpointer a, gconstpointer b)
-{
- gint aa, bb;
-
- aa = atoi ((gchar *) a);
- bb = atoi ((gchar *) b);
-
- if (aa == bb)
- return 0;
- else if (aa > bb)
- return -1;
- else
- return 1;
-}
-
-GList *
-cpufreq_get_frequencies_from_procfs (CPUFreqApplet *applet)
-{
- gint fmax, fmin, cpu, freq;
- gint pmin, pmax;
- gchar mode[21];
- GList *list = NULL;
-
- g_return_val_if_fail (PANEL_IS_APPLET (PANEL_APPLET (applet)), FALSE);
-
- if (!cpufreq_parse_procfs (applet, &cpu, &fmax, &pmin, &pmax, &fmin, mode))
- return FALSE;
-
- if (pmax != 100) {
- freq = (fmax * 100) / pmax;
- list = g_list_append (list, g_strdup_printf ("%d", freq));
- }
-
- list = g_list_append (list, g_strdup_printf ("%d", fmax));
- if (fmax != fmin)
- list = g_list_append (list, g_strdup_printf ("%d", fmin));
-
- return list;
-}
-
-gboolean
-cpufreq_get_from_sysfs (gpointer gdata)
-{
- GnomeVFSHandle *handle;
- GnomeVFSFileSize bytes_read;
- GnomeVFSResult result;
- gchar *uri;
- gchar buffer[20];
- gint i;
- CPUFreqApplet *applet;
- gchar **cpufreq_data;
- gchar *path;
- gchar *files[] = {
- "scaling_max_freq",
- "scaling_min_freq",
- "scaling_governor",
- "cpuinfo_max_freq",
- "scaling_setspeed",
- "scaling_cur_freq",
- NULL };
-
-
- enum {
- SCALING_MAX,
- SCALING_MIN,
- GOVERNOR,
- CPUINFO_MAX,
- SCALING_SETSPEED,
- SCALING_CUR_FREQ,
- LAST
- };
-
- applet = (CPUFreqApplet *) gdata;
-
- g_return_val_if_fail (PANEL_IS_APPLET (PANEL_APPLET (applet)), FALSE);
-
- /* /sys/devices/system/cpu/cpu[0]/cpufreq/scaling_max_freq
- * /sys/devices/system/cpu/cpu[0]/cpufreq/scaling_min_freq
- * /sys/devices/system/cpu/cpu[0]/cpufreq/scaling_governor
- * /sys/devices/system/cpu/cpu[0]/cpufreq/cpuinfo_max_freq
- * /sys/devices/system/cpu/cpu[0]/cpufreq/scaling_setspeed (userspace)
- * /sys/devices/system/cpu/cpu[0]/cpufreq/scaling_cur_freq (new governors)
- */
-
- cpufreq_data = g_new (gchar *, LAST + 1);
-
- for (i=0; i<LAST; i++) {
- cpufreq_data[i] = NULL;
-
- path = g_strdup_printf ("/sys/devices/system/cpu/cpu%d/cpufreq/%s",
- applet->cpu, files[i]);
-
- if (!g_file_test (path, G_FILE_TEST_EXISTS)) {
- cpufreq_data[i] = g_strdup ("");
- buffer[0] = '\0';
- g_free (path);
-
- continue;
- }
-
- uri = gnome_vfs_get_uri_from_local_path (path);
- g_free (path);
-
- result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
- if (result != GNOME_VFS_OK) {
- if (uri) g_free (uri);
- g_strfreev (cpufreq_data);
-
- return FALSE;
- }
-
- g_free (uri);
-
- result = gnome_vfs_read (handle, buffer, sizeof (buffer), &bytes_read);
-
- /* bytes_read - 1 in order to remove the \n character */
- cpufreq_data[i] = g_strndup (buffer, bytes_read - 1);
-
- if (result != GNOME_VFS_OK) {
- g_strfreev (cpufreq_data);
- gnome_vfs_close (handle);
-
- return FALSE;
- }
-
- result = gnome_vfs_close (handle);
- if (result != GNOME_VFS_OK) {
- g_strfreev (cpufreq_data);
-
- return FALSE;
- }
- buffer[0] = '\0';
- }
- cpufreq_data[LAST] = NULL;
-
- cpufreq_applet_prepare (applet);
-
- applet->governor = g_strdup (cpufreq_data[GOVERNOR]);
-
- if (g_ascii_strcasecmp (applet->governor, "userspace") == 0) {
- applet->freq = cpufreq_get_human_readble_freq (atoi (cpufreq_data[SCALING_SETSPEED]));
- applet->perc = cpufreq_get_human_readble_perc (atoi (cpufreq_data[CPUINFO_MAX]),
- atoi (cpufreq_data[SCALING_SETSPEED]));
- applet->unit = cpufreq_get_human_readble_unit (atoi (cpufreq_data[SCALING_SETSPEED]));
- } else if (g_ascii_strcasecmp (applet->governor, "powersave") == 0) {
- applet->freq = cpufreq_get_human_readble_freq (atoi (cpufreq_data[SCALING_MIN]));
- applet->perc = cpufreq_get_human_readble_perc (atoi (cpufreq_data[CPUINFO_MAX]),
- atoi (cpufreq_data[SCALING_MIN]));
- applet->unit = cpufreq_get_human_readble_unit (atoi (cpufreq_data[SCALING_MIN]));
- } else if (g_ascii_strcasecmp (applet->governor, "performance") == 0) {
- applet->freq = cpufreq_get_human_readble_freq (atoi (cpufreq_data[SCALING_MAX]));
- applet->perc = cpufreq_get_human_readble_perc (atoi (cpufreq_data[CPUINFO_MAX]),
- atoi (cpufreq_data[SCALING_MAX]));
- applet->unit = cpufreq_get_human_readble_unit (atoi (cpufreq_data[SCALING_MAX]));
- } else {
- applet->freq = cpufreq_get_human_readble_freq (atoi (cpufreq_data[SCALING_CUR_FREQ]));
- applet->perc = cpufreq_get_human_readble_perc (atoi (cpufreq_data[CPUINFO_MAX]),
- atoi (cpufreq_data[SCALING_CUR_FREQ]));
- applet->unit = cpufreq_get_human_readble_unit (atoi (cpufreq_data[SCALING_CUR_FREQ]));
- }
-
- if (applet->freq == NULL) {
- g_strfreev (cpufreq_data);
-
- return FALSE;
- }
-
- if (applet->perc == NULL) {
- g_strfreev (cpufreq_data);
-
- return FALSE;
- }
-
- if (applet->unit == NULL) {
- g_strfreev (cpufreq_data);
-
- return FALSE;
- }
-
- g_strfreev (cpufreq_data);
-
- cpufreq_applet_update (applet);
-
- return TRUE;
-}
-
-GList *
-cpufreq_get_frequencies_from_sysfs (CPUFreqApplet *applet)
-{
- GnomeVFSHandle *handle;
- GnomeVFSFileSize bytes_read;
- GnomeVFSResult result;
- gchar *uri;
- gchar buffer[256];
- gchar *str;
- gchar *path;
- GList *list = NULL;
- gchar **frequencies = NULL;
- gint i;
-
- path = g_strdup_printf ("/sys/devices/system/cpu/cpu%d/cpufreq/scaling_available_frequencies",
- applet->cpu);
-
- uri = gnome_vfs_get_uri_from_local_path (path);
- g_free (path);
-
- result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
- if (result != GNOME_VFS_OK) {
- if (uri) g_free (uri);
-
- return FALSE;
- }
-
- g_free (uri);
-
- result = gnome_vfs_read (handle, buffer, sizeof (buffer), &bytes_read);
-
- str = g_strndup (buffer, bytes_read);
- str = g_strchomp (str);
-
- frequencies = g_strsplit (str, " ", 0);
-
- if (result != GNOME_VFS_OK) {
- g_strfreev (frequencies);
- gnome_vfs_close (handle);
-
- return FALSE;
- }
-
- result = gnome_vfs_close (handle);
- if (result != GNOME_VFS_OK) {
- g_strfreev (frequencies);
-
- return FALSE;
- }
-
- i = 0;
- while (frequencies[i] != NULL) {
- if (!g_list_find_custom (list, frequencies[i], compare))
- list = g_list_append (list, g_strdup (frequencies[i]));
- i++;
- }
-
- g_strfreev (frequencies);
- g_free (str);
-
- list = g_list_sort (list, compare);
-
- return list;
-}
-
-gboolean
-cpufreq_get_from_procfs_cpuinfo (CPUFreqApplet *applet)
-{
- GnomeVFSHandle *handle;
- GnomeVFSFileSize bytes_read;
- GnomeVFSResult result;
- gchar *uri, *file;
- gchar **lines;
- gchar buffer[256];
- gchar *p;
- gint cpu, i;
-
- g_return_val_if_fail (PANEL_IS_APPLET (PANEL_APPLET (applet)), FALSE);
-
- uri = gnome_vfs_get_uri_from_local_path ("/proc/cpuinfo");
-
- result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
- if (result != GNOME_VFS_OK) {
- if (uri) g_free (uri);
-
- return FALSE;
- }
-
- g_free (uri);
-
- result = gnome_vfs_read (handle, buffer, 256, &bytes_read);
- file = g_strndup (buffer, bytes_read);
- if (result != GNOME_VFS_OK) {
- g_free (file);
- gnome_vfs_close (handle);
-
- return FALSE;
- }
-
- result = gnome_vfs_close (handle);
- if (result != GNOME_VFS_OK) {
- g_free (file);
-
- return FALSE;
- }
-
- lines = g_strsplit (file, "\n", -1);
- for (i=0; lines[i]; i++) {
- if (g_ascii_strncasecmp ("cpu MHz", lines[i], strlen ("cpu MHz")) == 0) {
- p = g_strrstr (lines[i], ":");
-
- if (p == NULL) {
- g_strfreev (lines);
- g_free (file);
-
- return FALSE;
- }
-
- if (strlen (lines[i]) < (p - lines[i])) {
- g_strfreev (lines);
- g_free (file);
-
- return FALSE;
- }
-
- if ((sscanf(p + 1, "%d.", &cpu)) != 1) {
- g_strfreev (lines);
- g_free (file);
-
- return FALSE;
- }
-
- break;
- }
- }
-
- g_strfreev (lines);
- g_free (file);
-
- cpufreq_applet_prepare (applet);
-
- applet->governor = g_strdup ("performance");
- applet->freq = cpufreq_get_human_readble_freq (cpu * 1000); /* kHz are expected*/
- applet->unit = cpufreq_get_human_readble_unit (cpu * 1000); /* kHz are expected*/
- applet->perc = g_strdup ("100%");
-
- if (applet->freq == NULL)
- return FALSE;
- if (applet->perc == NULL)
- return FALSE;
- if (applet->unit == NULL)
- return FALSE;
-
- cpufreq_applet_update (applet);
-
- return TRUE;
-}