diff options
author | Carlos Garcia Campos <carlosgc@gnome.org> | 2004-12-24 15:07:15 +0000 |
---|---|---|
committer | Carlos Garcia Campos <carlosgc@src.gnome.org> | 2004-12-24 15:07:15 +0000 |
commit | 7da9459d91b1964ec1a2dab84f97e816cc4a5fb6 (patch) | |
tree | 46c244b9901225378c3184d738af319bd93ef077 /cpufreq/src | |
parent | ee94dc4e0a446365f23a93b478fc585f6c066424 (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.am | 13 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-applet.c | 634 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-applet.h | 47 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-monitor-cpuinfo.c | 215 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-monitor-cpuinfo.h | 48 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-monitor-factory.c | 54 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-monitor-factory.h (renamed from cpufreq/src/cpufreq.h) | 10 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-monitor-procfs.c | 348 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-monitor-procfs.h | 48 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-monitor-protected.h | 30 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-monitor-sysfs.c | 373 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-monitor-sysfs.h | 48 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-monitor.c | 375 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-monitor.h | 76 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-popup.c | 121 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-popup.h | 4 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-prefs.c | 78 | ||||
-rw-r--r-- | cpufreq/src/cpufreq.c | 591 |
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; -} |