diff options
author | Carlos Garcia Campos <carlosgc@gnome.org> | 2006-06-14 10:14:18 +0000 |
---|---|---|
committer | Carlos Garcia Campos <carlosgc@src.gnome.org> | 2006-06-14 10:14:18 +0000 |
commit | 1c3f675005eb59d9f12713caba07d1f557db79e0 (patch) | |
tree | 704ed6d26427e194472876caad3782e4eb9c1d20 | |
parent | d1373d573fb620e722b1261c86cc81cbb8fae449 (diff) |
Removed Added
2006-06-14 Carlos Garcia Campos <carlosgc@gnome.org>
* src/Makefile.am:
* src/cpufreq-applet.[ch]:
* src/cpufreq-monitor-protected.h: Removed
* src/cpufreq-utils.[ch]: Added
* src/cpufreq-monitor.[ch]:
* src/cpufreq-monitor-cpuinfo.[ch]:
* src/cpufreq-monitor-procfs.[ch]:
* src/cpufreq-monitor-sysfs.[ch]:
* src/cpufreq-monitor-factory.c:
* src/cpufreq-popup.[ch]:
* src/cpufreq-prefs.[ch]:
Rework almost the whole applet in order to make it simpler and more
OO. Fixes bugs #336449, #338557. Lots of code cleanups.
-rw-r--r-- | cpufreq/ChangeLog | 17 | ||||
-rw-r--r-- | cpufreq/src/Makefile.am | 4 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-applet.c | 1204 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-applet.h | 84 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-monitor-cpuinfo.c | 145 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-monitor-cpuinfo.h | 13 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-monitor-factory.c | 32 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-monitor-procfs.c | 412 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-monitor-procfs.h | 1 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-monitor-sysfs.c | 461 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-monitor-sysfs.h | 13 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-monitor.c | 467 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-monitor.h | 51 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-popup.c | 806 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-popup.h | 44 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-prefs.c | 1065 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-prefs.h | 46 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-utils.c | 162 | ||||
-rw-r--r-- | cpufreq/src/cpufreq-utils.h (renamed from cpufreq/src/cpufreq-monitor-protected.h) | 32 |
19 files changed, 2818 insertions, 2241 deletions
diff --git a/cpufreq/ChangeLog b/cpufreq/ChangeLog index 88b88fa75..2c01d9d4b 100644 --- a/cpufreq/ChangeLog +++ b/cpufreq/ChangeLog @@ -1,3 +1,20 @@ +2006-06-14 Carlos Garcia Campos <carlosgc@gnome.org> + + * src/Makefile.am: + * src/cpufreq-applet.[ch]: + * src/cpufreq-monitor-protected.h: Removed + * src/cpufreq-utils.[ch]: Added + * src/cpufreq-monitor.[ch]: + * src/cpufreq-monitor-cpuinfo.[ch]: + * src/cpufreq-monitor-procfs.[ch]: + * src/cpufreq-monitor-sysfs.[ch]: + * src/cpufreq-monitor-factory.c: + * src/cpufreq-popup.[ch]: + * src/cpufreq-prefs.[ch]: + + Rework almost the whole applet in order to make it simpler and more + OO. Fixes bugs #336449, #338557. Lots of code cleanups. + 2006-05-28 Carlos Garcia Campos <carlosgc@gnome.org> * help/C/cpufreq-applet.xml: Fix a typo. Patch from Benoît Turpin. diff --git a/cpufreq/src/Makefile.am b/cpufreq/src/Makefile.am index 1f810bfc2..bc87f7c45 100644 --- a/cpufreq/src/Makefile.am +++ b/cpufreq/src/Makefile.am @@ -6,17 +6,16 @@ SUBDIRS = $(selector_SUBDIR) INCLUDES = \ $(GNOME_APPLETS_CFLAGS) \ - $(GNOME_VFS_APPLETS_CFLAGS) \ $(LIBGLADE_CFLAGS) libexec_PROGRAMS = cpufreq-applet cpufreq_applet_SOURCES = \ cpufreq-applet.c cpufreq-applet.h \ + cpufreq-utils.c cpufreq-utils.h \ cpufreq-prefs.c cpufreq-prefs.h \ cpufreq-popup.c cpufreq-popup.h \ cpufreq-monitor.c cpufreq-monitor.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 \ @@ -24,7 +23,6 @@ cpufreq_applet_SOURCES = \ cpufreq_applet_LDADD = \ $(GNOME_APPLETS_LIBS) \ - $(GNOME_VFS_APPLETS_LIBS) \ $(LIBGLADE_LIBS) diff --git a/cpufreq/src/cpufreq-applet.c b/cpufreq/src/cpufreq-applet.c index e1ad998b2..f7f76e673 100644 --- a/cpufreq/src/cpufreq-applet.c +++ b/cpufreq/src/cpufreq-applet.c @@ -19,9 +19,20 @@ * Authors : Carlos García Campos <carlosgc@gnome.org> */ -#include <config.h> - -#include <gnome.h> +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gtk/gtklabel.h> +#include <gtk/gtkbox.h> +#include <gtk/gtkhbox.h> +#include <gtk/gtkvbox.h> +#include <gtk/gtkimage.h> +#include <gtk/gtkaccessible.h> +#include <gtk/gtkalignment.h> +#include <gtk/gtkaboutdialog.h> +#include <gdk/gdkkeysyms.h> +#include <libgnomeui/gnome-help.h> #include <panel-applet.h> #include <panel-applet-gconf.h> #include <glade/glade.h> @@ -33,62 +44,154 @@ #include "cpufreq-popup.h" #include "cpufreq-monitor.h" #include "cpufreq-monitor-factory.h" +#include "cpufreq-utils.h" -#define PARENT_TYPE PANEL_TYPE_APPLET +struct _CPUFreqApplet { + PanelApplet base; -static void cpufreq_applet_init (CPUFreqApplet *applet); -static void cpufreq_applet_class_init (CPUFreqAppletClass *klass); + /* Visibility */ + gboolean show_freq; + gboolean show_perc; + gboolean show_unit; + gboolean show_icon; -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); + CPUFreqMonitor *monitor; -static gint cpufreq_applet_get_max_cpu (void); -static void cpufreq_applet_pixmap_set_image (CPUFreqApplet *applet, const gchar *percentage); + PanelAppletOrient orient; + gint size; -static void cpufreq_applet_setup (CPUFreqApplet *applet); -static void cpufreq_applet_update (CPUFreqMonitor *monitor, gpointer gdata); -static void cpufreq_applet_refresh (CPUFreqApplet *applet); + GtkWidget *label; + GtkWidget *unit_label; + GtkWidget *icon; + GtkWidget *box; + GtkWidget *container; + GdkPixbuf *pixbufs[5]; + GtkTooltips *tips; -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); + CPUFreqPrefs *prefs; + CPUFreqPopup *popup; +}; -static gboolean cpufreq_applet_factory (CPUFreqApplet *applet, const gchar *iid, - gpointer gdata); +struct _CPUFreqAppletClass { + PanelAppletClass parent_class; +}; + +static void cpufreq_applet_init (CPUFreqApplet *applet); +static void cpufreq_applet_class_init (CPUFreqAppletClass *klass); -static PanelAppletClass *parent_class = NULL; +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 void cpufreq_applet_pixmap_set_image (CPUFreqApplet *applet, + gint perc); + +static void cpufreq_applet_setup (CPUFreqApplet *applet); +static void cpufreq_applet_update (CPUFreqApplet *applet, + CPUFreqMonitor *monitor); +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_factory (CPUFreqApplet *applet, + const gchar *iid, + gpointer gdata); + +static const gchar *const cpufreq_icons[] = { + GNOME_PIXMAPSDIR"/cpufreq-applet/cpufreq-25.png", + GNOME_PIXMAPSDIR"/cpufreq-applet/cpufreq-50.png", + GNOME_PIXMAPSDIR"/cpufreq-applet/cpufreq-75.png", + GNOME_PIXMAPSDIR"/cpufreq-applet/cpufreq-100.png", + GNOME_PIXMAPSDIR"/cpufreq-applet/cpufreq-na.png", + NULL +}; + +static const BonoboUIVerb cpufreq_applet_menu_verbs[] = { + BONOBO_UI_UNSAFE_VERB ("CPUFreqAppletPreferences", + cpufreq_applet_preferences_cb), + BONOBO_UI_UNSAFE_VERB ("CPUFreqAppletHelp", + cpufreq_applet_help_cb), + BONOBO_UI_UNSAFE_VERB ("CPUFreqAppletAbout", + cpufreq_applet_about_cb), + BONOBO_UI_VERB_END +}; + +G_DEFINE_TYPE (CPUFreqApplet, cpufreq_applet, PANEL_TYPE_APPLET) + +/* Enum Types */ +GType +cpufreq_applet_show_mode_get_type (void) +{ + static GType etype = 0; + + if (etype == 0) { + static const GEnumValue values[] = { + { CPUFREQ_MODE_GRAPHIC, "CPUFREQ_MODE_GRAPHIC", "mode-graphic" }, + { CPUFREQ_MODE_TEXT, "CPUFREQ_MODE_TEXT", "mode-text" }, + { CPUFREQ_MODE_BOTH, "CPUFREQ_MODE_BOTH", "mode-both" }, + { 0, NULL, NULL } + }; + + etype = g_enum_register_static ("CPUFreqShowMode", values); + } + + return etype; +} GType -cpufreq_applet_get_type (void) +cpufreq_applet_show_text_mode_get_type (void) { - static GType type = 0; - - if (!type) { - static const GTypeInfo info = { - sizeof (CPUFreqAppletClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) cpufreq_applet_class_init, - NULL, - NULL, - sizeof (CPUFreqApplet), - 0, - (GInstanceInitFunc) cpufreq_applet_init + static GType etype = 0; + + if (etype == 0) { + static const GEnumValue values[] = { + { CPUFREQ_MODE_TEXT_FREQUENCY, "CPUFREQ_MODE_TEXT_FREQUENCY", "mode-text-frequency" }, + { CPUFREQ_MODE_TEXT_FREQUENCY_UNIT, "CPUFREQ_MODE_TEXT_FREQUENCY_UNIT", "mode-text-frequency-unit" }, + { CPUFREQ_MODE_TEXT_PERCENTAGE, "CPUFREQ_MODE_TEXT_PERCENTAGE", "mode-text-percentage" }, + { 0, NULL, NULL } }; - type = g_type_register_static (PARENT_TYPE, "CPUFreqApplet", - &info, 0); + etype = g_enum_register_static ("CPUFreqShowTextMode", values); } - return type; + return etype; +} + +GType +cpufreq_applet_selector_mode_get_type (void) +{ + static GType etype = 0; + + if (etype == 0) { + static const GEnumValue values[] = { + { CPUFREQ_SELECTOR_MODE_FREQUENCIES, "CPUFREQ_SELECTOR_MODE_FREQUENCIES", "selector-mode-frequencies" }, + { CPUFREQ_SELECTOR_MODE_GOVERNORS, "CPUFREQ_SELECTOR_MODE_GOVERNORS", "selector-mode-governors" }, + { CPUFREQ_SELECTOR_MODE_BOTH, "CPUFREQ_SELECTOR_MODE_BOTH", "selector-mode-both" }, + { 0, NULL, NULL } + }; + + etype = g_enum_register_static ("CPUFreqSelectorMode", values); + } + + return etype; } static void @@ -96,21 +199,20 @@ cpufreq_applet_init (CPUFreqApplet *applet) { gint i; - applet->mcpu = cpufreq_applet_get_max_cpu (); applet->prefs = NULL; applet->popup = NULL; applet->monitor = NULL; - applet->label = NULL; - applet->unit_label = NULL; - applet->pixmap = NULL; + applet->label = gtk_label_new (NULL); + applet->unit_label = gtk_label_new (NULL); + applet->icon = gtk_image_new (); applet->box = NULL; applet->container = gtk_alignment_new (0.5, 0.5, 0, 0); gtk_container_add (GTK_CONTAINER (applet), applet->container); + gtk_widget_show (applet->container); applet->tips = gtk_tooltips_new (); - g_object_ref (G_OBJECT (applet->tips)); for (i = 0; i <= 4; i++) applet->pixbufs[i] = NULL; @@ -119,6 +221,8 @@ cpufreq_applet_init (CPUFreqApplet *applet) applet->size = panel_applet_get_size (PANEL_APPLET (applet)); applet->orient = panel_applet_get_orient (PANEL_APPLET (applet)); + + gtk_widget_show (GTK_WIDGET (applet)); } static void @@ -128,86 +232,306 @@ cpufreq_applet_class_init (CPUFreqAppletClass *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; + widget_class->key_press_event = cpufreq_applet_key_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) +static void +cpufreq_applet_destroy (GtkObject *widget) { - GtkWidget *dialog; - - dialog = gtk_message_dialog_new (NULL, - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - message); - gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), - secondary); - gtk_window_set_title (GTK_WINDOW (dialog), ""); /* as per HIG */ - gtk_window_set_skip_taskbar_hint (GTK_WINDOW (dialog), TRUE); - g_signal_connect (G_OBJECT (dialog), - "response", - G_CALLBACK (gtk_widget_destroy), NULL); - gtk_widget_show (dialog); + CPUFreqApplet *applet; + gint i; + + applet = CPUFREQ_APPLET (widget); + + if (applet->monitor) { + g_object_unref (G_OBJECT (applet->monitor)); + applet->monitor = NULL; + } + + if (applet->tips) { + gtk_object_destroy (GTK_OBJECT (applet->tips)); + applet->tips = 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) { + g_object_unref (applet->prefs); + applet->prefs = NULL; + } + + if (applet->popup) { + g_object_unref (applet->popup); + applet->popup = NULL; + } + + GTK_OBJECT_CLASS (cpufreq_applet_parent_class)->destroy (widget); } static void -cpufreq_applet_preferences_cb (BonoboUIComponent *uic, CPUFreqApplet *applet, const gchar *cname) +cpufreq_applet_size_allocate (GtkWidget *widget, GtkAllocation *allocation) { - g_return_if_fail (PANEL_IS_APPLET (PANEL_APPLET (applet))); - - cpufreq_preferences_dialog_run (applet); + CPUFreqApplet *applet; + gint size = 0; + + applet = CPUFREQ_APPLET (widget); + + switch (applet->orient) { + case PANEL_APPLET_ORIENT_LEFT: + case PANEL_APPLET_ORIENT_RIGHT: + size = allocation->width; + break; + case PANEL_APPLET_ORIENT_UP: + case PANEL_APPLET_ORIENT_DOWN: + size = allocation->height; + break; + } + + if (size != applet->size) { + applet->size = size; + cpufreq_applet_refresh (applet); + } + + GTK_WIDGET_CLASS (cpufreq_applet_parent_class)->size_allocate (widget, allocation); } static void -cpufreq_applet_help_cb (BonoboUIComponent *uic, CPUFreqApplet *applet, const gchar *cname) +cpufreq_applet_popup_position_menu (GtkMenu *menu, + int *x, + int *y, + gboolean *push_in, + gpointer gdata) { - GError *error; - - g_return_if_fail (PANEL_IS_APPLET (PANEL_APPLET (applet))); + GtkWidget *widget; + GtkRequisition requisition; + gint menu_xpos; + gint menu_ypos; + + widget = GTK_WIDGET (gdata); + + gtk_widget_size_request (GTK_WIDGET (menu), &requisition); + + gdk_window_get_origin (widget->window, &menu_xpos, &menu_ypos); + + menu_xpos += widget->allocation.x; + menu_ypos += widget->allocation.y; + + switch (panel_applet_get_orient (PANEL_APPLET (widget))) { + case PANEL_APPLET_ORIENT_DOWN: + case PANEL_APPLET_ORIENT_UP: + if (menu_ypos > gdk_screen_get_height (gtk_widget_get_screen (widget)) / 2) + menu_ypos -= requisition.height; + else + menu_ypos += widget->allocation.height; + break; + case PANEL_APPLET_ORIENT_RIGHT: + case PANEL_APPLET_ORIENT_LEFT: + if (menu_xpos > gdk_screen_get_width (gtk_widget_get_screen (widget)) / 2) + menu_xpos -= requisition.width; + else + menu_xpos += widget->allocation.width; + break; + default: + g_assert_not_reached (); + } + + *x = menu_xpos; + *y = menu_ypos; + *push_in = TRUE; +} + +static void +cpufreq_applet_menu_popup (CPUFreqApplet *applet, + guint32 time) +{ + GtkWidget *menu; + + if (!cpufreq_utils_selector_is_available ()) + return; + + if (!applet->popup) { + applet->popup = cpufreq_popup_new (); + cpufreq_popup_set_preferences (applet->popup, applet->prefs); + cpufreq_popup_set_monitor (applet->popup, applet->monitor); + } + + menu = cpufreq_popup_get_menu (applet->popup); + + if (!menu) + return; + + gtk_menu_popup (GTK_MENU (menu), NULL, NULL, + cpufreq_applet_popup_position_menu, + (gpointer) applet, + 1, time); +} + +static gboolean +cpufreq_applet_button_press (GtkWidget *widget, GdkEventButton *event) +{ + CPUFreqApplet *applet; + + applet = CPUFREQ_APPLET (widget); + + if (event->button == 2) + return FALSE; + + if (event->button == 1 && + event->type != GDK_2BUTTON_PRESS && + event->type != GDK_3BUTTON_PRESS) { + cpufreq_applet_menu_popup (applet, event->time); + + return TRUE; + } + + return GTK_WIDGET_CLASS (cpufreq_applet_parent_class)->button_press_event (widget, event); +} + +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: + cpufreq_applet_menu_popup (applet, event->time); + + return TRUE; + default: + break; + } - error = NULL; + return FALSE; +} + +static void +cpufreq_applet_change_orient (PanelApplet *pa, PanelAppletOrient orient) +{ + CPUFreqApplet *applet; + gint size; + + 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); + } +} + +static void +cpufreq_applet_change_background (PanelApplet *pa, + PanelAppletBackgroundType type, + GdkColor *color, GdkPixmap *pixmap) +{ + CPUFreqApplet *applet; + /* Taken from TrashApplet */ + 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 (); + gtk_widget_modify_style (GTK_WIDGET (applet), rc_style); + gtk_rc_style_unref (rc_style); + + switch (type) { + case PANEL_PIXMAP_BACKGROUND: + style = gtk_style_copy (GTK_WIDGET (applet)->style); + if (style->bg_pixmap[GTK_STATE_NORMAL]) + g_object_unref ( + style->bg_pixmap[GTK_STATE_NORMAL]); + style->bg_pixmap[GTK_STATE_NORMAL] = g_object_ref ( + pixmap); + gtk_widget_set_style (GTK_WIDGET (applet), style); + g_object_unref (style); + break; + case PANEL_COLOR_BACKGROUND: + gtk_widget_modify_bg (GTK_WIDGET (applet), + GTK_STATE_NORMAL, color); + break; + case PANEL_NO_BACKGROUND: + default: + break; + } +} + +static void +cpufreq_applet_preferences_cb (BonoboUIComponent *uic, + CPUFreqApplet *applet, + const gchar *cname) +{ + cpufreq_preferences_dialog_run (applet->prefs, + gtk_widget_get_screen (GTK_WIDGET (applet))); +} + +static void +cpufreq_applet_help_cb (BonoboUIComponent *uic, + CPUFreqApplet *applet, + const gchar *cname) +{ + GError *error = NULL; + gnome_help_display_on_screen ("cpufreq-applet", NULL, gtk_widget_get_screen (GTK_WIDGET (applet)), &error); if (error) { - cpufreq_applet_display_error (_("Could not open help document"), - error->message); + cpufreq_utils_display_error (_("Could not open help document"), + error->message); g_error_free (error); } } static void -cpufreq_applet_about_cb (BonoboUIComponent *uic, CPUFreqApplet *applet, const gchar *cname) +cpufreq_applet_about_cb (BonoboUIComponent *uic, + CPUFreqApplet *applet, + const gchar *cname) { - static const gchar * const authors[] = { + static const gchar *const authors[] = { "Carlos Garcia Campos <carlosgc@gnome.org>", NULL }; - static const gchar * const documenters[] = { + static const gchar *const documenters[] = { "Carlos Garcia Campos <carlosgc@gnome.org>", "Davyd Madeley <davyd@madeley.id.au>", NULL }; - static const gchar * const artists[] = { + static const gchar *const artists[] = { "Pablo Arroyo Loma <zzioma@yahoo.es>", NULL }; GdkPixbuf *pixbuf = NULL; - g_return_if_fail (PANEL_IS_APPLET (PANEL_APPLET (applet))); - pixbuf = gdk_pixbuf_new_from_file_at_size ( GNOME_PIXMAPSDIR "/cpufreq-applet/cpufreq-applet.png", 48, 48, NULL); @@ -229,173 +553,164 @@ cpufreq_applet_about_cb (BonoboUIComponent *uic, CPUFreqApplet *applet, const gc g_object_unref (pixbuf); } -static gint -cpufreq_applet_get_max_cpu (void) +static void +cpufreq_applet_pixmap_set_image (CPUFreqApplet *applet, gint perc) { - gint mcpu = -1; - gchar *file = NULL; - - do { - if (file) g_free (file); - mcpu ++; - file = g_strdup_printf ("/sys/devices/system/cpu/cpu%d", mcpu); - } while (g_file_test (file, G_FILE_TEST_EXISTS)); - g_free (file); - mcpu --; - - if (mcpu >= 0) - return mcpu; - - mcpu = -1; - file = NULL; - do { - if (file) g_free (file); - mcpu ++; - file = g_strdup_printf ("/proc/sys/cpu/%d", mcpu); - } while (g_file_test (file, G_FILE_TEST_EXISTS)); - g_free (file); - mcpu --; - - if (mcpu >= 0) - return mcpu; + gint image; + + /* 0-29 -> 25% + * 30-69 -> 50% + * 70-89 -> 75% + * 90-100 -> 100% + */ + if (perc < 30) + image = 0; + else if ((perc >= 30) && (perc < 70)) + image = 1; + else if ((perc >= 70) && (perc < 90)) + image = 2; + else if ((perc >= 90) && (perc <= 100)) + image = 3; else - return 0; -} + image = 4; -gboolean -cpufreq_applet_selector_is_available (void) -{ - struct stat *info; - gchar *path = NULL; + if (applet->pixbufs[image] == NULL) { + applet->pixbufs[image] = gdk_pixbuf_new_from_file_at_size (cpufreq_icons[image], + 24, 24, NULL); + } - path = g_find_program_in_path ("cpufreq-selector"); - if (!path) - return FALSE; + gtk_image_set_from_pixbuf (GTK_IMAGE (applet->icon), applet->pixbufs[image]); +} - if (geteuid () == 0) - return TRUE; +static void +cpufreq_applet_update_visibility (CPUFreqApplet *applet) +{ + CPUFreqShowMode show_mode; + CPUFreqShowTextMode show_text_mode; + gboolean show_freq = FALSE; + gboolean show_perc = FALSE; + gboolean show_unit = FALSE; + gboolean show_icon = FALSE; + gboolean changed = FALSE; + gboolean need_update = FALSE; + + show_mode = cpufreq_prefs_get_show_mode (applet->prefs); + show_text_mode = cpufreq_prefs_get_show_text_mode (applet->prefs); + + if (show_mode != CPUFREQ_MODE_GRAPHIC) { + show_icon = (show_mode == CPUFREQ_MODE_BOTH); + + switch (show_text_mode) { + case CPUFREQ_MODE_TEXT_FREQUENCY: + show_freq = TRUE; + break; + case CPUFREQ_MODE_TEXT_PERCENTAGE: + show_perc = TRUE; + break; + case CPUFREQ_MODE_TEXT_FREQUENCY_UNIT: + show_freq = TRUE; + show_unit = TRUE; + break; + } + } else { + show_icon = TRUE; + } - info = (struct stat *) g_malloc (sizeof (struct stat)); + if ((applet->show_perc && show_freq) || + (applet->show_freq && show_perc)) + need_update = TRUE; + + if (show_freq != applet->show_freq) { + applet->show_freq = show_freq; + changed = TRUE; + } - if ((lstat (path, info)) != -1) { - if ((info->st_mode & S_ISUID) && (info->st_uid == 0)) { - g_free (info); - g_free (path); - - return TRUE; - } + if (show_perc != applet->show_perc) { + applet->show_perc = show_perc; + changed = TRUE; } - g_free (info); - g_free (path); + if (changed) { + g_object_set (G_OBJECT (applet->label), + "visible", + applet->show_freq || applet->show_perc, + NULL); + } - return FALSE; -} + if (show_unit != applet->show_unit) { + applet->show_unit = show_unit; + changed = TRUE; -static void -cpufreq_applet_pixmap_set_image (CPUFreqApplet *applet, const gchar *percentage) -{ - gint perc, image; - gchar *text_perc; - gchar *pixmaps[] = { - GNOME_PIXMAPSDIR"/cpufreq-applet/cpufreq-25.png", - GNOME_PIXMAPSDIR"/cpufreq-applet/cpufreq-50.png", - GNOME_PIXMAPSDIR"/cpufreq-applet/cpufreq-75.png", - GNOME_PIXMAPSDIR"/cpufreq-applet/cpufreq-100.png", - GNOME_PIXMAPSDIR"/cpufreq-applet/cpufreq-na.png", - NULL }; - - if (!percentage) { - image = 4; - } else { - text_perc = g_strndup (percentage, strlen (percentage) - 1); - perc = atoi (text_perc); - g_free (text_perc); - - /* 0-29 -> 25% - * 30-69 -> 50% - * 70-89 -> 75% - * 90-100 -> 100% - */ - if (perc < 30) - image = 0; - else if ((perc >= 30) && (perc < 70)) - image = 1; - else if ((perc >= 70) && (perc < 90)) - image = 2; - else - image = 3; + g_object_set (G_OBJECT (applet->unit_label), + "visible", applet->show_unit, + NULL); } - if (applet->pixbufs[image] == NULL) { - applet->pixbufs[image] = gdk_pixbuf_new_from_file_at_size (pixmaps[image], - 24, 24, NULL); + if (show_icon != applet->show_icon) { + applet->show_icon = show_icon; + changed = TRUE; + + g_object_set (G_OBJECT (applet->icon), + "visible", applet->show_icon, + NULL); } - gtk_image_set_from_pixbuf (GTK_IMAGE (applet->pixmap), applet->pixbufs[image]); + if (changed) + cpufreq_applet_refresh (applet); + + if (need_update) + cpufreq_applet_update (applet, applet->monitor); } static void -cpufreq_applet_update (CPUFreqMonitor *monitor, gpointer gdata) +cpufreq_applet_update (CPUFreqApplet *applet, CPUFreqMonitor *monitor) { - gchar *text_tip, *text_mode; - gchar *freq, *perc, *unit; - guint cpu; - gchar *governor; - CPUFreqApplet *applet; - - applet = CPUFREQ_APPLET (gdata); + gchar *text_tip, *text_mode; + gchar *freq_label, *unit_label; + gint freq; + gint perc; + guint cpu; + gchar *governor; + static gboolean do_refresh = TRUE; 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); - /* Setup widgets */ - if (applet->show_text_mode == MODE_TEXT_PERCENTAGE) - gtk_label_set_text (GTK_LABEL (applet->label), perc); - else - gtk_label_set_text (GTK_LABEL (applet->label), freq); - - gtk_label_set_text (GTK_LABEL (applet->unit_label), unit); - cpufreq_applet_pixmap_set_image (applet, perc); + freq_label = cpufreq_utils_get_frequency_label (freq); + unit_label = cpufreq_utils_get_frequency_unit (freq); + + if (applet->show_freq) { + gtk_label_set_text (GTK_LABEL (applet->label), freq_label); + } - /* Show or hide */ - if (applet->show_mode != MODE_GRAPHIC) { - if (applet->show_mode == MODE_TEXT) - gtk_widget_hide (applet->pixmap); - else - gtk_widget_show (applet->pixmap); + if (applet->show_perc) { + gchar *text_perc; - switch (applet->show_text_mode) { - case MODE_TEXT_FREQUENCY: - case MODE_TEXT_PERCENTAGE: - gtk_widget_hide (applet->unit_label); + text_perc = g_strdup_printf ("%d%%", perc); + gtk_label_set_text (GTK_LABEL (applet->label), text_perc); + g_free (text_perc); + } - break; - case MODE_TEXT_FREQUENCY_UNIT: - gtk_widget_show (applet->unit_label); + if (applet->show_unit) { + gtk_label_set_text (GTK_LABEL (applet->unit_label), unit_label); + } - break; - } - - gtk_widget_show (applet->label); - } else { - gtk_widget_show (applet->pixmap); - gtk_widget_hide (applet->label); - gtk_widget_hide (applet->unit_label); + if (applet->show_icon) { + cpufreq_applet_pixmap_set_image (applet, perc); } - + governor[0] = g_ascii_toupper (governor[0]); - text_mode = g_strdup_printf ("%s\n%s %s (%s)", governor, freq, unit, perc); + text_mode = g_strdup_printf ("%s\n%s %s (%d%%)", + governor, freq_label, + unit_label, perc); - g_free (freq); - g_free (unit); - g_free (perc); + g_free (freq_label); + g_free (unit_label); g_free (governor); - if (applet->mcpu == 0) + if (cpufreq_utils_get_n_cpus () == 1) text_tip = g_strdup_printf ("%s", text_mode); else text_tip = g_strdup_printf ("CPU %u - %s", cpu, text_mode); @@ -404,201 +719,88 @@ cpufreq_applet_update (CPUFreqMonitor *monitor, gpointer gdata) gtk_tooltips_set_tip (applet->tips, GTK_WIDGET (applet), text_tip, NULL); g_free (text_tip); -} -static void -cpufreq_applet_destroy (GtkObject *widget) -{ - CPUFreqApplet *applet; - gint i; - - applet = CPUFREQ_APPLET (widget); - - if (applet->monitor) { - g_object_unref (G_OBJECT (applet->monitor)); - applet->monitor = NULL; - } - - if (applet->tips) { - g_object_unref (G_OBJECT (applet->tips)); - applet->tips = 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) { - gtk_widget_destroy (applet->prefs); - applet->prefs = NULL; - } - - if (applet->popup) { - gtk_widget_destroy (applet->popup); - applet->popup = NULL; + /* Call refresh only the first time */ + if (do_refresh) { + cpufreq_applet_refresh (applet); + do_refresh = FALSE; } - - (* 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_applet_refresh (CPUFreqApplet *applet) +static gint +cpufreq_applet_get_widget_size (CPUFreqApplet *applet, + GtkWidget *widget) { - GtkWidget *labels_box; GtkRequisition req; - gint total_size = 0; - 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))); - - if (applet->monitor) { - freq = cpufreq_monitor_get_frequency (applet->monitor); - perc = cpufreq_monitor_get_percentage (applet->monitor); - unit = cpufreq_monitor_get_unit (applet->monitor); - } else { - freq = NULL; - perc = NULL; - unit = NULL; - } - - panel_size = applet->size - 1; /* 1 pixel margin */ + gint size; + if (!GTK_WIDGET_VISIBLE (widget)) + return 0; + + gtk_widget_size_request (widget, &req); + switch (applet->orient) { case PANEL_APPLET_ORIENT_LEFT: case PANEL_APPLET_ORIENT_RIGHT: - horizontal = FALSE; + size = req.width; break; case PANEL_APPLET_ORIENT_UP: case PANEL_APPLET_ORIENT_DOWN: - horizontal = TRUE; + size = req.height; break; + default: + g_assert_not_reached (); } - if (applet->label) - gtk_widget_destroy (applet->label); - - applet->label = gtk_label_new (" --- "); - if (applet->show_text_mode == MODE_TEXT_PERCENTAGE) { - if (perc) - gtk_label_set_text (GTK_LABEL (applet->label), perc); - } else { - if (freq) - gtk_label_set_text (GTK_LABEL (applet->label), freq); - } - if (freq) g_free (freq); - - gtk_widget_size_request (applet->label, &req); - if (applet->show_mode != MODE_GRAPHIC) - gtk_widget_show (applet->label); - - if (horizontal) { - label_size = req.height; - total_size += req.height; - } else { - label_size = req.width; - total_size += req.width; - } - - if (applet->unit_label) - gtk_widget_destroy (applet->unit_label); - - applet->unit_label = gtk_label_new (" ? "); - 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 && - applet->show_text_mode == MODE_TEXT_FREQUENCY_UNIT) - gtk_widget_show (applet->unit_label); - - if (horizontal) { - unit_label_size = req.height; - total_size += req.height; - } else { - unit_label_size = req.width; - total_size += req.width; - } - - if (applet->pixmap) - gtk_widget_destroy (applet->pixmap); - - applet->pixmap = gtk_image_new (); - - cpufreq_applet_pixmap_set_image (applet, perc); - if (perc) g_free (perc); + return size; +} - gtk_widget_size_request (applet->pixmap, &req); - if (applet->show_mode != MODE_TEXT) - gtk_widget_show (applet->pixmap); +static void +cpufreq_applet_refresh (CPUFreqApplet *applet) +{ + GtkWidget *labels_box = NULL; + gint total_size = 0; + gint panel_size, label_size; + gint unit_label_size, pixmap_size; + gint size_step = 12; + gboolean do_unref = FALSE; - if (horizontal) { - pixmap_size = req.height; - total_size += req.height; - } else { - pixmap_size = req.width; - total_size += req.width; - } + panel_size = applet->size - 1; /* 1 pixel margin */ - if (applet->box) + /* We want a fixed label size, the biggest */ + gtk_label_set_width_chars (GTK_LABEL (applet->label), 4); + label_size = cpufreq_applet_get_widget_size (applet, applet->label); + gtk_label_set_width_chars (GTK_LABEL (applet->label), -1); + total_size += label_size; + + unit_label_size = cpufreq_applet_get_widget_size (applet, applet->unit_label); + total_size += unit_label_size; + + pixmap_size = cpufreq_applet_get_widget_size (applet, applet->icon); + total_size += pixmap_size; + + if (applet->box) { + GtkWidget *child; + GList *children; + + do_unref = TRUE; + g_object_ref (applet->icon); + gtk_container_remove (GTK_CONTAINER (applet->box), applet->icon); + children = gtk_container_get_children (GTK_CONTAINER (applet->box)); + if (children && children->data) { + /* Should be labels_box */ + child = (GtkWidget *)children->data; + g_object_ref (applet->label); + gtk_container_remove (GTK_CONTAINER (child), applet->label); + g_object_ref (applet->unit_label); + gtk_container_remove (GTK_CONTAINER (child), applet->unit_label); + } gtk_widget_destroy (applet->box); + } - if (horizontal) { - labels_box = gtk_hbox_new (FALSE, 2); - if ((label_size + pixmap_size) <= panel_size) - applet->box = gtk_vbox_new (FALSE, 2); - else - applet->box = gtk_hbox_new (FALSE, 2); - } else { - + switch (applet->orient) { + case PANEL_APPLET_ORIENT_LEFT: + case PANEL_APPLET_ORIENT_RIGHT: if (total_size <= panel_size) { applet->box = gtk_hbox_new (FALSE, 2); labels_box = gtk_hbox_new (FALSE, 2); @@ -609,129 +811,51 @@ cpufreq_applet_refresh (CPUFreqApplet *applet) applet->box = gtk_vbox_new (FALSE, 2); labels_box = gtk_vbox_new (FALSE, 2); } + break; + case PANEL_APPLET_ORIENT_UP: + case PANEL_APPLET_ORIENT_DOWN: + labels_box = gtk_hbox_new (FALSE, 2); + if ((label_size + pixmap_size) <= panel_size) + applet->box = gtk_vbox_new (FALSE, 2); + else + applet->box = gtk_hbox_new (FALSE, 2); + break; + default: + g_assert_not_reached (); } - + gtk_box_pack_start (GTK_BOX (labels_box), applet->label, FALSE, TRUE, 0); gtk_box_pack_start (GTK_BOX (labels_box), applet->unit_label, FALSE, TRUE, 0); - - gtk_widget_show (labels_box); - - gtk_box_pack_start (GTK_BOX (applet->box), applet->pixmap, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (applet->box), applet->icon, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (applet->box), labels_box, FALSE, TRUE, 0); + gtk_widget_show (labels_box); - gtk_widget_show (applet->box); - gtk_container_add (GTK_CONTAINER (applet->container), applet->box); + gtk_widget_show (applet->box); - gtk_widget_show (applet->container); -} - -static void -cpufreq_applet_size_allocate (GtkWidget *widget, GtkAllocation *allocation) -{ - CPUFreqApplet *applet; - gint size; - - applet = CPUFREQ_APPLET (widget); - - if ((applet->orient == PANEL_APPLET_ORIENT_LEFT) || - (applet->orient == PANEL_APPLET_ORIENT_RIGHT)) { - size = allocation->width; - } else { - size = allocation->height; - } - - if (size != applet->size) { - applet->size = size; - cpufreq_applet_refresh (applet); + if (do_unref) { + g_object_unref (applet->label); + g_object_unref (applet->unit_label); + g_object_unref (applet->icon); } - - (* GTK_WIDGET_CLASS (parent_class)->size_allocate) (widget, allocation); } +/* Preferences callbacks */ static void -cpufreq_applet_change_orient (PanelApplet *pa, PanelAppletOrient orient) +cpufreq_applet_prefs_show_mode_changed (CPUFreqPrefs *prefs, + GParamSpec *arg1, + CPUFreqApplet *applet) { - CPUFreqApplet *applet; - gint size; - - 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); - } - - if (PANEL_APPLET_CLASS (parent_class)->change_orient) - (* PANEL_APPLET_CLASS (parent_class)->change_orient) (pa, orient); -} - -static void -cpufreq_applet_change_background (PanelApplet *pa, - PanelAppletBackgroundType type, - GdkColor *color, GdkPixmap *pixmap) -{ - CPUFreqApplet *applet; - /* Taken from TrashApplet */ - 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 (); - gtk_widget_modify_style (GTK_WIDGET (applet), rc_style); - gtk_rc_style_unref (rc_style); - - switch (type) { - case PANEL_PIXMAP_BACKGROUND: - style = gtk_style_copy (GTK_WIDGET (applet)->style); - if (style->bg_pixmap[GTK_STATE_NORMAL]) - g_object_unref ( - style->bg_pixmap[GTK_STATE_NORMAL]); - style->bg_pixmap[GTK_STATE_NORMAL] = g_object_ref ( - pixmap); - gtk_widget_set_style (GTK_WIDGET (applet), style); - g_object_unref (style); - break; - case PANEL_COLOR_BACKGROUND: - gtk_widget_modify_bg (GTK_WIDGET (applet), - GTK_STATE_NORMAL, color); - break; - case PANEL_NO_BACKGROUND: - default: - break; - } + cpufreq_applet_update_visibility (applet); } static void cpufreq_applet_setup (CPUFreqApplet *applet) { - BonoboUIComponent *popup_component; - AtkObject *atk_obj; - GError *error; - guint cpu; - static const BonoboUIVerb cpufreq_applet_menu_verbs[] = { - BONOBO_UI_UNSAFE_VERB ("CPUFreqAppletPreferences", - cpufreq_applet_preferences_cb), - BONOBO_UI_UNSAFE_VERB ("CPUFreqAppletHelp", - cpufreq_applet_help_cb), - BONOBO_UI_UNSAFE_VERB ("CPUFreqAppletAbout", - cpufreq_applet_about_cb), - BONOBO_UI_VERB_END - }; - - g_return_if_fail (PANEL_IS_APPLET (PANEL_APPLET (applet))); + BonoboUIComponent *popup_component; + AtkObject *atk_obj; + gchar *prefs_key; glade_gnome_init (); @@ -740,56 +864,32 @@ cpufreq_applet_setup (CPUFreqApplet *applet) panel_applet_add_preferences (PANEL_APPLET (applet), "/schemas/apps/cpufreq-applet/prefs", NULL); - error = NULL; - cpu = panel_applet_gconf_get_int (PANEL_APPLET (applet), - "cpu", &error); + /* Preferences */ + if (applet->prefs) + g_object_unref (applet->prefs); + + prefs_key = panel_applet_get_preferences_key (PANEL_APPLET (applet)); + applet->prefs = cpufreq_prefs_new (prefs_key); + g_free (prefs_key); + + g_signal_connect (G_OBJECT (applet->prefs), + "notify::show-mode", + G_CALLBACK (cpufreq_applet_prefs_show_mode_changed), + (gpointer) applet); + g_signal_connect (G_OBJECT (applet->prefs), + "notify::show-text-mode", + G_CALLBACK (cpufreq_applet_prefs_show_mode_changed), + (gpointer) applet); + + cpufreq_applet_update_visibility (applet); - /* In case anything went wrong with gconf, get back to the default */ - if (error) { - cpu = 0; - 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; - if (error) - g_error_free (error); - } - - error = NULL; - applet->selector_mode = panel_applet_gconf_get_int (PANEL_APPLET (applet), - "selector_mode", &error); - - /* In case anything went wrong with gconf, get back to the default */ - if (error || applet->selector_mode < SELECTOR_MODE_FREQUENCIES || - applet->selector_mode > SELECTOR_MODE_BOTH) { - applet->show_mode = SELECTOR_MODE_FREQUENCIES; - if (error) - g_error_free (error); - } - - applet->monitor = cpufreq_monitor_factory_create_monitor (cpu); + /* Monitor */ + applet->monitor = cpufreq_monitor_factory_create_monitor ( + cpufreq_prefs_get_cpu (applet->prefs)); cpufreq_monitor_run (applet->monitor); - g_signal_connect (G_OBJECT (applet->monitor), "changed", - G_CALLBACK (cpufreq_applet_update), - (gpointer) applet); + g_signal_connect_swapped (G_OBJECT (applet->monitor), "changed", + G_CALLBACK (cpufreq_applet_update), + (gpointer) applet); /* Setup the menus */ panel_applet_setup_menu_from_file (PANEL_APPLET (applet), @@ -814,8 +914,6 @@ cpufreq_applet_setup (CPUFreqApplet *applet) atk_object_set_name (atk_obj, _("CPU Frequency Scaling Monitor")); atk_object_set_description (atk_obj, _("This utility shows the current CPU Frequency")); } - - cpufreq_applet_refresh (applet); } static gboolean @@ -825,9 +923,7 @@ cpufreq_applet_factory (CPUFreqApplet *applet, const gchar *iid, gpointer gdata) if (!strcmp (iid, "OAFIID:GNOME_CPUFreqApplet")) { cpufreq_applet_setup (applet); - - gtk_widget_show (GTK_WIDGET (applet)); - + retval = TRUE; } @@ -835,7 +931,7 @@ cpufreq_applet_factory (CPUFreqApplet *applet, const gchar *iid, gpointer gdata) } PANEL_APPLET_BONOBO_FACTORY ("OAFIID:GNOME_CPUFreqApplet_Factory", - TYPE_CPUFREQ_APPLET, + CPUFREQ_TYPE_APPLET, "cpufreq-applet", "0", (PanelAppletFactoryCallback) cpufreq_applet_factory, diff --git a/cpufreq/src/cpufreq-applet.h b/cpufreq/src/cpufreq-applet.h index 3ff137dae..558fefa0e 100644 --- a/cpufreq/src/cpufreq-applet.h +++ b/cpufreq/src/cpufreq-applet.h @@ -19,77 +19,51 @@ * Authors : Carlos García Campos <carlosgc@gnome.org> */ -#ifndef __CPUFREQ_APPLET_H__ -#define __CPUFREQ_APPLET_H__ +#ifndef CPUFREQ_APPLET_H +#define CPUFREQ_APPLET_H -#include <glib.h> -#include <gtk/gtktooltips.h> -#include <panel-applet.h> +#include <glib-object.h> -#include "cpufreq-monitor.h" +G_BEGIN_DECLS -#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)) +#define CPUFREQ_TYPE_APPLET (cpufreq_applet_get_type ()) +#define CPUFREQ_APPLET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CPUFREQ_TYPE_APPLET, CPUFreqApplet)) +#define CPUFREQ_APPLET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), CPUFREQ_TYPE_APPLET, CPUFreqAppletClass)) +#define CPUFREQ_IS_APPLET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CPUFREQ_TYPE_APPLET)) +#define CPUFREQ_IS_APPLET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CPUFREQ_TYPE_APPLET)) +#define CPUFREQ_APPLET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CPUFREQ_TYPE_APPLET, CPUFreqAppletClass)) + +#define CPUFREQ_TYPE_SHOW_MODE (cpufreq_applet_show_mode_get_type ()) +#define CPUFREQ_TYPE_SHOW_TEXT_MODE (cpufreq_applet_show_text_mode_get_type ()) +#define CPUFREQ_TYPE_SELECTOR_MODE (cpufreq_applet_selector_mode_get_type ()) typedef struct _CPUFreqApplet CPUFreqApplet; typedef struct _CPUFreqAppletClass CPUFreqAppletClass; typedef enum { - MODE_GRAPHIC, - MODE_TEXT, - MODE_BOTH + CPUFREQ_MODE_GRAPHIC, + CPUFREQ_MODE_TEXT, + CPUFREQ_MODE_BOTH } CPUFreqShowMode; typedef enum { - MODE_TEXT_FREQUENCY, - MODE_TEXT_FREQUENCY_UNIT, - MODE_TEXT_PERCENTAGE + CPUFREQ_MODE_TEXT_FREQUENCY, + CPUFREQ_MODE_TEXT_FREQUENCY_UNIT, + CPUFREQ_MODE_TEXT_PERCENTAGE } CPUFreqShowTextMode; typedef enum { - SELECTOR_MODE_FREQUENCIES, - SELECTOR_MODE_GOVERNORS, - SELECTOR_MODE_BOTH + CPUFREQ_SELECTOR_MODE_FREQUENCIES, + CPUFREQ_SELECTOR_MODE_GOVERNORS, + CPUFREQ_SELECTOR_MODE_BOTH } CPUFreqSelectorMode; -struct _CPUFreqApplet { - PanelApplet base; - - guint mcpu; /* Max cpu number (0 in a single cpu system) */ - - CPUFreqShowMode show_mode; - CPUFreqShowTextMode show_text_mode; - CPUFreqSelectorMode selector_mode; - - CPUFreqMonitor *monitor; - - PanelAppletOrient orient; - gint size; - - GtkWidget *label; - GtkWidget *unit_label; - GtkWidget *pixmap; - GtkWidget *box; - GtkWidget *container; - GdkPixbuf *pixbufs[5]; - GtkTooltips *tips; - - GtkWidget *prefs; - GtkWidget *popup; -}; - -struct _CPUFreqAppletClass { - PanelAppletClass parent_class; -}; +GType cpufreq_applet_get_type (void) G_GNUC_CONST; -GType cpufreq_applet_get_type (void) G_GNUC_CONST; +GType cpufreq_applet_show_mode_get_type (void) G_GNUC_CONST; +GType cpufreq_applet_show_text_mode_get_type (void) G_GNUC_CONST; +GType cpufreq_applet_selector_mode_get_type (void) G_GNUC_CONST; -void cpufreq_applet_display_error (const gchar *message, - const gchar *secondary); -gboolean cpufreq_applet_selector_is_available (void); +G_END_DECLS -#endif /* __CPUFREQ_APPLET_H__ */ +#endif /* CPUFREQ_APPLET_H */ diff --git a/cpufreq/src/cpufreq-monitor-cpuinfo.c b/cpufreq/src/cpufreq-monitor-cpuinfo.c index cea138e5e..775b367da 100644 --- a/cpufreq/src/cpufreq-monitor-cpuinfo.c +++ b/cpufreq/src/cpufreq-monitor-cpuinfo.c @@ -21,74 +21,29 @@ #include <glib.h> #include <glib/gi18n.h> -#include <libgnomevfs/gnome-vfs.h> #include <string.h> #include <stdio.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 gboolean cpufreq_monitor_cpuinfo_run (CPUFreqMonitor *monitor); -static CPUFreqMonitorClass *parent_class = NULL; +G_DEFINE_TYPE (CPUFreqMonitorCPUInfo, cpufreq_monitor_cpuinfo, CPUFREQ_TYPE_MONITOR) -typedef struct _CPUFreqMonitorProtected CPUFreqMonitorProtected; - -GType cpufreq_monitor_cpuinfo_get_type () +static void +cpufreq_monitor_cpuinfo_init (CPUFreqMonitorCPUInfo *monitor) { - 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 * @@ -96,80 +51,57 @@ cpufreq_monitor_cpuinfo_new (guint cpu) { CPUFreqMonitorCPUInfo *monitor; - monitor = g_object_new (TYPE_CPUFREQ_MONITOR_CPUINFO, "cpu", cpu, NULL); + monitor = g_object_new (CPUFREQ_TYPE_MONITOR_CPUINFO, "cpu", cpu, NULL); return CPUFREQ_MONITOR (monitor); } static gboolean -cpufreq_monitor_cpuinfo_get (gpointer gdata) +cpufreq_monitor_cpuinfo_run (CPUFreqMonitor *monitor) { - GnomeVFSHandle *handle; - GnomeVFSFileSize bytes_read; - GnomeVFSResult result; - gchar *uri, *file; + gchar *file; gchar **lines; - gchar buffer[256]; + gchar *buffer = NULL; gchar *p; - gchar *freq, *perc, *unit, *governor; gint cpu, i; - CPUFreqMonitorCPUInfo *monitor; - CPUFreqMonitorProtected *private; - - monitor = (CPUFreqMonitorCPUInfo *) gdata; + gint cur_freq, max_freq; + gchar *governor; + GError *error = NULL; - private = CPUFREQ_MONITOR_GET_PROTECTED (CPUFREQ_MONITOR (monitor)); - - uri = gnome_vfs_get_uri_from_local_path ("/proc/cpuinfo"); + file = g_strdup ("/proc/cpuinfo"); + if (!g_file_get_contents (file, &buffer, NULL, &error)) { + g_warning (error->message); + g_error_free (error); - 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; } - + g_free (file); + /* TODO: SMP support */ - lines = g_strsplit (file, "\n", -1); - for (i=0; lines[i]; i++) { + lines = g_strsplit (buffer, "\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); + g_free (buffer); return FALSE; } if (strlen (lines[i]) < (size_t)(p - lines[i])) { g_strfreev (lines); - g_free (file); + g_free (buffer); return FALSE; } - if ((sscanf(p + 1, "%d.", &cpu)) != 1) { + if ((sscanf (p + 1, "%d.", &cpu)) != 1) { g_strfreev (lines); - g_free (file); + g_free (buffer); return FALSE; } @@ -179,36 +111,23 @@ cpufreq_monitor_cpuinfo_get (gpointer gdata) } g_strfreev (lines); - g_free (file); + g_free (buffer); 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%"); + cur_freq = cpu * 1000; + max_freq = cur_freq; - parent_class->free_data (CPUFREQ_MONITOR (monitor)); + g_object_set (G_OBJECT (monitor), + "governor", governor, + "frequency", cur_freq, + "max-frequency", max_freq, + NULL); - 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); + g_free (governor); return TRUE; } -static void -cpufreq_monitor_cpuinfo_run (CPUFreqMonitor *monitor) -{ - 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 index 32afeeb19..be80b2494 100644 --- a/cpufreq/src/cpufreq-monitor-cpuinfo.h +++ b/cpufreq/src/cpufreq-monitor-cpuinfo.h @@ -23,14 +23,15 @@ #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)) +#define CPUFREQ_TYPE_MONITOR_CPUINFO (cpufreq_monitor_cpuinfo_get_type ()) +#define CPUFREQ_MONITOR_CPUINFO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CPUFREQ_TYPE_MONITOR_CPUINFO, CPUFreqMonitorCPUInfo)) +#define CPUFREQ_MONITOR_CPUINFO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), CPUFREQ_TYPE_MONITOR_CPUINFO, CPUFreqMonitorCPUInfoClass)) +#define CPUFREQ_IS_MONITOR_CPUINFO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CPUFREQ_TYPE_MONITOR_CPUINFO)) +#define CPUFREQ_IS_MONITOR_CPUINFO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CPUFREQ_TYPE_MONITOR_CPUINFO)) +#define CPUFREQ_MONITOR_CPUINFO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CPUFREQ_TYPE_MONITOR_CPUINFO, CPUFreqMonitorCPUInfoClass)) typedef struct _CPUFreqMonitorCPUInfo CPUFreqMonitorCPUInfo; typedef struct _CPUFreqMonitorCPUInfoClass CPUFreqMonitorCPUInfoClass; diff --git a/cpufreq/src/cpufreq-monitor-factory.c b/cpufreq/src/cpufreq-monitor-factory.c index 1939698c6..efc28ab2c 100644 --- a/cpufreq/src/cpufreq-monitor-factory.c +++ b/cpufreq/src/cpufreq-monitor-factory.c @@ -20,8 +20,10 @@ */ #include <glib.h> +#include <glib/gi18n.h> #include "cpufreq-applet.h" +#include "cpufreq-utils.h" #include "cpufreq-monitor-sysfs.h" #include "cpufreq-monitor-procfs.h" #include "cpufreq-monitor-cpuinfo.h" @@ -33,23 +35,23 @@ cpufreq_monitor_factory_create_monitor (guint cpu) CPUFreqMonitor *monitor = NULL; if (g_file_test ("/sys/devices/system/cpu/cpu0/cpufreq", G_FILE_TEST_EXISTS)) { /* 2.6 kernel */ - monitor = cpufreq_monitor_sysfs_new (cpu); + monitor = cpufreq_monitor_sysfs_new (cpu); } else if (g_file_test ("/proc/cpufreq", G_FILE_TEST_EXISTS)) { /* 2.4 kernel (Deprecated)*/ - monitor = cpufreq_monitor_procfs_new (cpu); + 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); + /* If there is no cpufreq support it shows only the cpu frequency, + * I think 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_utils_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-monitor-procfs.c b/cpufreq/src/cpufreq-monitor-procfs.c index 7364dc1cb..073e54909 100644 --- a/cpufreq/src/cpufreq-monitor-procfs.c +++ b/cpufreq/src/cpufreq-monitor-procfs.c @@ -21,80 +21,32 @@ #include <glib.h> #include <glib/gi18n.h> -#include <libgnomevfs/gnome-vfs.h> #include <string.h> #include <stdlib.h> #include <stdio.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 gboolean cpufreq_monitor_procfs_run (CPUFreqMonitor *monitor); +static GList *cpufreq_monitor_procfs_get_available_frequencies (CPUFreqMonitor *monitor); - -static CPUFreqMonitorClass *parent_class = NULL; - -typedef struct _CPUFreqMonitorProtected CPUFreqMonitorProtected; - -GType cpufreq_monitor_procfs_get_type (void) -{ - 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; -} +G_DEFINE_TYPE (CPUFreqMonitorProcfs, cpufreq_monitor_procfs, CPUFREQ_TYPE_MONITOR) static void -cpufreq_monitor_procfs_class_init (CPUFreqMonitorProcfsClass *klass) +cpufreq_monitor_procfs_init (CPUFreqMonitorProcfs *monitor) { - 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) +cpufreq_monitor_procfs_class_init (CPUFreqMonitorProcfsClass *klass) { - g_return_if_fail (IS_CPUFREQ_MONITOR_PROCFS (object)); - - if (G_OBJECT_CLASS (parent_class)->finalize) - (* G_OBJECT_CLASS (parent_class)->finalize) (object); + CPUFreqMonitorClass *monitor_class = CPUFREQ_MONITOR_CLASS (klass); + + monitor_class->run = cpufreq_monitor_procfs_run; + monitor_class->get_available_frequencies = cpufreq_monitor_procfs_get_available_frequencies; } CPUFreqMonitor * @@ -110,242 +62,142 @@ cpufreq_monitor_procfs_new (guint cpu) 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/%u/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; + gchar *buffer = NULL; + gchar *path; + gchar *p; + gchar *frequency; + gint freq; + gint len; + GError *error = NULL; + + path = g_strdup_printf ("/proc/sys/cpu/%u/speed", cpu); + + if (!g_file_get_contents (path, &buffer, NULL, &error)) { + g_warning (error->message); + g_error_free (error); + + g_free (path); + + return -1; + } + + /* Try to remove the '\n' */ + p = g_strrstr (buffer, "\n"); + len = strlen (buffer); + if (p) + len -= strlen (p); + + frequency = g_strndup (buffer, len); + g_free (buffer); + + freq = atoi (frequency); + g_free (frequency); + + return freq; } static gboolean -cpufreq_monitor_procfs_parse (CPUFreqMonitorProcfs *monitor, gint *cpu, gint *fmax, - gint *pmin, gint *pmax, gint *fmin, gchar *mode) +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; - } - - count = 0; - 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 ((guint)(*cpu) == private->cpu) - break; - } - } - - g_strfreev (lines); - g_free (file); - - if (count != 6) { - /* TODO: manage error */ - return FALSE; - } - - return TRUE; + gchar **lines; + gchar *buffer = NULL; + gint i, count; + guint mon_cpu; + GError *error = NULL; + + if (!g_file_get_contents ("/proc/cpufreq", &buffer, NULL, &error)) { + g_warning (error->message); + g_error_free (error); + + return FALSE; + } + + g_object_get (G_OBJECT (monitor), + "cpu", &mon_cpu, NULL); + + count = 0; + lines = g_strsplit (buffer, "\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 ((guint)(*cpu) == mon_cpu) + break; + } + } + + g_strfreev (lines); + g_free (buffer); + + return (count == 6); } 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); + gint fmax, fmin, cpu; + gint pmin, pmax; + gchar mode[21]; + gint cur_freq, max_freq; + gchar *governor; + + if (!cpufreq_monitor_procfs_parse (CPUFREQ_MONITOR_PROCFS (monitor), + &cpu, &fmax, &pmin, &pmax, &fmin, mode)) { + return FALSE; + } + + governor = mode; + max_freq = fmax; + + if (g_ascii_strcasecmp (governor, "powersave") == 0) { + cur_freq = fmin; + } else if (g_ascii_strcasecmp (governor, "performance") == 0) { + cur_freq = fmax; + } else if (g_ascii_strcasecmp (governor, "userspace") == 0) { + cur_freq = cpufreq_monitor_procfs_get_freq_from_userspace (cpu); + } else { + cur_freq = fmax; + } + + g_object_set (G_OBJECT (monitor), + "governor", governor, + "frequency", cur_freq, + "max-frequency", max_freq, + NULL); + + return TRUE; } static GList * cpufreq_monitor_procfs_get_available_frequencies (CPUFreqMonitor *monitor) { - gint fmax, fmin, cpu, freq; - gint pmin, pmax; - gchar mode[21]; - 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; + gint fmax, fmin, cpu, freq; + gint pmin, pmax; + gchar mode[21]; + GList *list = 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; + list = g_list_prepend (list, g_strdup_printf ("%d", freq)); + } + + list = g_list_prepend (list, g_strdup_printf ("%d", fmax)); + if (fmax != fmin) + list = g_list_prepend (list, g_strdup_printf ("%d", fmin)); + + return g_list_reverse (list); } diff --git a/cpufreq/src/cpufreq-monitor-procfs.h b/cpufreq/src/cpufreq-monitor-procfs.h index d5504bc7c..2271aaae0 100644 --- a/cpufreq/src/cpufreq-monitor-procfs.h +++ b/cpufreq/src/cpufreq-monitor-procfs.h @@ -23,6 +23,7 @@ #define __CPUFREQ_MONITOR_PROCFS_H__ #include <glib-object.h> + #include "cpufreq-monitor.h" #define TYPE_CPUFREQ_MONITOR_PROCFS (cpufreq_monitor_procfs_get_type ()) diff --git a/cpufreq/src/cpufreq-monitor-sysfs.c b/cpufreq/src/cpufreq-monitor-sysfs.c index e2e8a9cf6..113cfd136 100644 --- a/cpufreq/src/cpufreq-monitor-sysfs.c +++ b/cpufreq/src/cpufreq-monitor-sysfs.c @@ -21,78 +21,62 @@ #include <glib.h> #include <glib/gi18n.h> -#include <libgnomevfs/gnome-vfs.h> #include <string.h> #include <stdlib.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)) +enum { + SCALING_MAX, + SCALING_MIN, + GOVERNOR, + CPUINFO_MAX, + SCALING_SETSPEED, + SCALING_CUR_FREQ, + N_FILES +}; 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 gboolean cpufreq_monitor_sysfs_run (CPUFreqMonitor *monitor); static GList *cpufreq_monitor_sysfs_get_available_frequencies (CPUFreqMonitor *monitor); static GList *cpufreq_monitor_sysfs_get_available_governors (CPUFreqMonitor *monitor); -static gboolean cpufreq_monitor_sysfs_get (gpointer gdata); - +/* /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) + */ +const gchar *monitor_sysfs_files[] = { + "scaling_max_freq", + "scaling_min_freq", + "scaling_governor", + "cpuinfo_max_freq", + "scaling_setspeed", + "scaling_cur_freq", + NULL +}; -static CPUFreqMonitorClass *parent_class = NULL; +#define CPUFREQ_SYSFS_BASE_PATH "/sys/devices/system/cpu/cpu%u/cpufreq/%s" -typedef struct _CPUFreqMonitorProtected CPUFreqMonitorProtected; +G_DEFINE_TYPE (CPUFreqMonitorSysfs, cpufreq_monitor_sysfs, CPUFREQ_TYPE_MONITOR) -GType cpufreq_monitor_sysfs_get_type (void) +static void +cpufreq_monitor_sysfs_init (CPUFreqMonitorSysfs *monitor) { - 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; - monitor_class->get_available_governors = cpufreq_monitor_sysfs_get_available_governors; - - 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); + monitor_class->get_available_governors = cpufreq_monitor_sysfs_get_available_governors; } CPUFreqMonitor * @@ -100,190 +84,100 @@ cpufreq_monitor_sysfs_new (guint cpu) { CPUFreqMonitorSysfs *monitor; - monitor = g_object_new (TYPE_CPUFREQ_MONITOR_SYSFS, "cpu", cpu, NULL); + monitor = g_object_new (CPUFREQ_TYPE_MONITOR_SYSFS, + "cpu", cpu, NULL); return CPUFREQ_MONITOR (monitor); } static gboolean -cpufreq_monitor_sysfs_get (gpointer gdata) +cpufreq_monitor_sysfs_run (CPUFreqMonitor *monitor) { - 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); + gint i; + gchar **data; + guint cpu; + gint cur_freq, max_freq; + gchar *governor; + + g_object_get (G_OBJECT (monitor), "cpu", &cpu, NULL); + + data = g_new0 (gchar *, N_FILES); - for (i = 0; i < LAST; i++) { - cpufreq_data[i] = NULL; - - path = g_strdup_printf ("/sys/devices/system/cpu/cpu%u/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; - } + for (i = 0; i < N_FILES; i++) { + gchar *path, *p; + gint len; + gchar *buffer = NULL; + GError *error = NULL; + + path = g_strdup_printf (CPUFREQ_SYSFS_BASE_PATH, + cpu, monitor_sysfs_files[i]); + + if (!g_file_get_contents (path, &buffer, NULL, &error)) { + int j; - 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); - + g_free (path); + + if (error->code == G_FILE_ERROR_NOENT) { + g_error_free (error); + continue; + } + + g_warning (error->message); + g_error_free (error); + + for (j = 0; j < N_FILES; j++) { + g_free (data[j]); + data[j] = NULL; + } + g_free (data); + return FALSE; } - g_free (uri); + g_free (path); - 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); + /* Try to remove the '\n' */ + p = g_strrstr (buffer, "\n"); + len = strlen (buffer); + if (p) + len -= strlen (p); + + data[i] = g_strndup (buffer, len); - 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'; + g_free (buffer); } - cpufreq_data[LAST] = NULL; - governor = g_strdup (cpufreq_data[GOVERNOR]); + governor = 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])); + cur_freq = atoi (data[SCALING_SETSPEED]); + max_freq = atoi (data[CPUINFO_MAX]); } 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])); + cur_freq = atoi (data[SCALING_MIN]); + max_freq = atoi (data[CPUINFO_MAX]); } 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; + cur_freq = atoi (data[SCALING_MAX]); + max_freq = atoi (data[CPUINFO_MAX]); + } else { /* Ondemand, Conservative, ... */ + cur_freq = atoi (data[SCALING_CUR_FREQ]); + max_freq = atoi (data[CPUINFO_MAX]); } - if (!private->freq || (g_ascii_strcasecmp (freq, private->freq) != 0)) { - - changed = TRUE; - } - - if (!private->perc || (g_ascii_strcasecmp (perc, private->perc) != 0)) { - changed = TRUE; - } + g_object_set (G_OBJECT (monitor), + "governor", governor, + "frequency", cur_freq, + "max-frequency", max_freq, + NULL); - if (!private->unit || (g_ascii_strcasecmp (unit, private->unit) != 0)) { - changed = TRUE; + for (i = 0; i < N_FILES; i++) { + g_free (data[i]); + data[i] = NULL; } - - 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); - + g_free (data); + 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) { @@ -303,146 +197,87 @@ compare (gconstpointer a, gconstpointer b) 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; - } + gchar *path; + GList *list = NULL; + gchar **frequencies = NULL; + gint i; + guint cpu; + gchar *buffer = NULL; + GError *error = NULL; - path = g_strdup_printf ("/sys/devices/system/cpu/cpu%u/cpufreq/scaling_available_frequencies", - private->cpu); + g_object_get (G_OBJECT (monitor), + "cpu", &cpu, NULL); - uri = gnome_vfs_get_uri_from_local_path (path); - g_free (path); + path = g_strdup_printf (CPUFREQ_SYSFS_BASE_PATH, cpu, + "scaling_available_frequencies"); - result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ); - if (result != GNOME_VFS_OK) { - if (uri) g_free (uri); + if (!g_file_get_contents (path, &buffer, NULL, &error)) { + g_warning (error->message); + g_error_free (error); + + g_free (path); return NULL; } - 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); + g_free (path); + + buffer = g_strchomp (buffer); + frequencies = g_strsplit (buffer, " ", -1); - if (result != GNOME_VFS_OK) { - g_strfreev (frequencies); - gnome_vfs_close (handle); - - return NULL; - } - - result = gnome_vfs_close (handle); - if (result != GNOME_VFS_OK) { - g_strfreev (frequencies); - - return NULL; - } - i = 0; - while (frequencies[i] != NULL) { + while (frequencies[i]) { if (!g_list_find_custom (list, frequencies[i], compare)) - list = g_list_append (list, g_strdup (frequencies[i])); + list = g_list_prepend (list, g_strdup (frequencies[i])); i++; } g_strfreev (frequencies); - g_free (str); + g_free (buffer); - private->available_freqs = g_list_sort (list, compare); - - return private->available_freqs; + return g_list_sort (list, compare); } static GList * cpufreq_monitor_sysfs_get_available_governors (CPUFreqMonitor *monitor) { - GnomeVFSHandle *handle; - GnomeVFSFileSize bytes_read; - GnomeVFSResult result; - gchar *uri; - gchar buffer[256]; - gchar *str; - gchar *path; - GList *list = NULL; - gchar **governors = 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_govs) { - return private->available_govs; - } + gchar *path; + GList *list = NULL; + gchar **governors = NULL; + gint i; + guint cpu; + gchar *buffer = NULL; + GError *error = NULL; + + g_object_get (G_OBJECT (monitor), + "cpu", &cpu, NULL); + + path = g_strdup_printf (CPUFREQ_SYSFS_BASE_PATH, cpu, + "scaling_available_governors"); + + if (!g_file_get_contents (path, &buffer, NULL, &error)) { + g_warning (error->message); + g_error_free (error); - path = g_strdup_printf ("/sys/devices/system/cpu/cpu%u/cpufreq/scaling_available_governors", - 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); + g_free (path); return NULL; } - g_free (uri); - - result = gnome_vfs_read (handle, buffer, sizeof (buffer), &bytes_read); - - str = g_strndup (buffer, bytes_read); - str = g_strchomp (str); + g_free (path); + + buffer = g_strchomp (buffer); - governors = g_strsplit (str, " ", 0); + governors = g_strsplit (buffer, " ", -1); - if (result != GNOME_VFS_OK) { - g_strfreev (governors); - gnome_vfs_close (handle); - - return NULL; - } - - result = gnome_vfs_close (handle); - if (result != GNOME_VFS_OK) { - g_strfreev (governors); - - return NULL; - } - i = 0; while (governors[i] != NULL) { - list = g_list_append (list, g_strdup (governors[i])); + list = g_list_prepend (list, g_strdup (governors[i])); i++; } g_strfreev (governors); - g_free (str); - - private->available_govs = list; + g_free (buffer); - return private->available_govs; + return list; } diff --git a/cpufreq/src/cpufreq-monitor-sysfs.h b/cpufreq/src/cpufreq-monitor-sysfs.h index 6cf78beba..0bd680861 100644 --- a/cpufreq/src/cpufreq-monitor-sysfs.h +++ b/cpufreq/src/cpufreq-monitor-sysfs.h @@ -23,14 +23,15 @@ #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)) +#define CPUFREQ_TYPE_MONITOR_SYSFS (cpufreq_monitor_sysfs_get_type ()) +#define CPUFREQ_MONITOR_SYSFS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CPUFREQ_TYPE_MONITOR_SYSFS, CPUFreqMonitorSysfs)) +#define CPUFREQ_MONITOR_SYSFS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), CPUFREQ_TYPE_MONITOR_SYSFS, CPUFreqMonitorSysfsClass)) +#define CPUFREQ_IS_MONITOR_SYSFS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CPUFREQ_TYPE_MONITOR_SYSFS)) +#define CPUFREQ_IS_MONITOR_SYSFS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CPUFREQ_TYPE_MONITOR_SYSFS)) +#define CPUFREQ_MONITOR_SYSFS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CPUFREQ_TYPE_MONITOR_SYSFS, CPUFreqMonitorSysfsClass)) typedef struct _CPUFreqMonitorSysfs CPUFreqMonitorSysfs; typedef struct _CPUFreqMonitorSysfsClass CPUFreqMonitorSysfsClass; diff --git a/cpufreq/src/cpufreq-monitor.c b/cpufreq/src/cpufreq-monitor.c index 9eeb4d1ab..cf4be34be 100644 --- a/cpufreq/src/cpufreq-monitor.c +++ b/cpufreq/src/cpufreq-monitor.c @@ -19,79 +19,68 @@ * 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_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), CPUFREQ_TYPE_MONITOR, CPUFreqMonitorPrivate)) -#define CPUFREQ_MONITOR_GET_PROTECTED(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), TYPE_CPUFREQ_MONITOR, CPUFreqMonitorProtected)) +#define CPUFREQ_MONITOR_INTERVAL 1000 +/* Properties */ enum { PROP_0, - PROP_CPU + PROP_CPU, + PROP_FREQUENCY, + PROP_MAX_FREQUENCY, + PROP_GOVERNOR }; -static void cpufreq_monitor_init (CPUFreqMonitor *monitor); -static void cpufreq_monitor_class_init (CPUFreqMonitorClass *klass); -static void cpufreq_monitor_finalize (GObject *object); +/* Signals */ +enum { + SIGNAL_CHANGED, + N_SIGNALS +}; -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); +struct _CPUFreqMonitorPrivate { + guint cpu; + gint cur_freq; + gint max_freq; + gchar *governor; + GList *available_freqs; + GList *available_govs; + guint timeout_handler; -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); + gboolean changed; +}; -static void cpufreq_monitor_free_data (CPUFreqMonitor *monitor); +static void cpufreq_monitor_init (CPUFreqMonitor *monitor); +static void cpufreq_monitor_class_init (CPUFreqMonitorClass *klass); +static void cpufreq_monitor_finalize (GObject *object); -static GObjectClass *parent_class = NULL; +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); -typedef struct _CPUFreqMonitorProtected CPUFreqMonitorProtected; +static guint signals[N_SIGNALS]; -GType cpufreq_monitor_get_type (void) -{ - 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; -} +G_DEFINE_ABSTRACT_TYPE (CPUFreqMonitor, cpufreq_monitor, G_TYPE_OBJECT) 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->available_govs = NULL; - private->timeout_handler = 0; + monitor->priv = CPUFREQ_MONITOR_GET_PRIVATE (monitor); + + monitor->priv->governor = NULL; + monitor->priv->available_freqs = NULL; + monitor->priv->available_govs = NULL; + monitor->priv->timeout_handler = 0; + + monitor->priv->changed = FALSE; } static void @@ -100,36 +89,55 @@ 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; - monitor_class->get_available_governors = 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; + monitor_class->get_available_governors = NULL; + g_type_class_add_private (klass, sizeof (CPUFreqMonitorPrivate)); + /* Porperties */ - g_object_class_install_property (object_class, PROP_CPU, - g_param_spec_uint ("cpu", NULL, NULL, - 0, /* MIN_UINT */ + g_object_class_install_property (object_class, + PROP_CPU, + g_param_spec_uint ("cpu", + "CPU", + "The cpu to monitor", + 0, G_MAXUINT, - 0, /* Default */ - G_PARAM_CONSTRUCT | G_PARAM_WRITABLE )); - - /* Protected attributes */ - g_type_class_add_private (klass, sizeof (CPUFreqMonitorProtected)); + 0, + G_PARAM_CONSTRUCT | + G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_FREQUENCY, + g_param_spec_int ("frequency", + "Frequency", + "The current cpu frequency", + 0, + G_MAXINT, + 0, + G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_MAX_FREQUENCY, + g_param_spec_int ("max-frequency", + "MaxFrequency", + "The max cpu frequency", + 0, + G_MAXINT, + 0, + G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_GOVERNOR, + g_param_spec_string ("governor", + "Governor", + "The current cpufreq governor", + NULL, + G_PARAM_READWRITE)); /* Signals */ - monitor_class->signals[CHANGED] = + signals[SIGNAL_CHANGED] = g_signal_new ("changed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, @@ -142,259 +150,230 @@ cpufreq_monitor_class_init (CPUFreqMonitorClass *klass) } static void -free_string (gpointer str, gpointer gdata) -{ - if (str) g_free (str); -} - -static void cpufreq_monitor_finalize (GObject *object) { - CPUFreqMonitorProtected *private; + CPUFreqMonitor *monitor = CPUFREQ_MONITOR (object); - 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 (monitor->priv->timeout_handler > 0) { + g_source_remove (monitor->priv->timeout_handler); + monitor->priv->timeout_handler = 0; } - if (private->available_govs) { - g_list_foreach (private->available_govs, - free_string, NULL); - g_list_free (private->available_govs); - private->available_govs = 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 (monitor->priv->governor) { + g_free (monitor->priv->governor); + monitor->priv->governor = NULL; + } - 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)); -} + if (monitor->priv->available_freqs) { + g_list_foreach (monitor->priv->available_freqs, + (GFunc) g_free, + NULL); + g_list_free (monitor->priv->available_freqs); + monitor->priv->available_freqs = NULL; + } -static gchar * -cpufreq_monitor_get_human_readable_unit (gint freq) -{ - if (freq > 999999) /* freq (kHz) */ - return g_strdup ("GHz"); - else - return g_strdup ("MHz"); -} + if (monitor->priv->available_govs) { + g_list_foreach (monitor->priv->available_govs, + (GFunc) g_free, + NULL); + g_list_free (monitor->priv->available_govs); + monitor->priv->available_govs = NULL; + } -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; + G_OBJECT_CLASS (cpufreq_monitor_parent_class)->finalize (object); } static void -cpufreq_monitor_set_property (GObject *object, guint prop_id, const GValue *value, - GParamSpec *spec) +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)); + CPUFreqMonitor *monitor; monitor = CPUFREQ_MONITOR (object); - private = CPUFREQ_MONITOR_GET_PROTECTED (monitor); switch (prop_id) { - case PROP_CPU: - private->cpu = g_value_get_uint (value); + case PROP_CPU: { + guint cpu = g_value_get_uint (value); + + if (cpu != monitor->priv->cpu) { + monitor->priv->cpu = cpu; + monitor->priv->changed = TRUE; + } + } + break; + case PROP_FREQUENCY: { + gint freq = g_value_get_int (value); + + if (freq != monitor->priv->cur_freq) { + monitor->priv->cur_freq = freq; + monitor->priv->changed = TRUE; + } + } + break; + case PROP_MAX_FREQUENCY: { + gint freq = g_value_get_int (value); + + if (freq != monitor->priv->max_freq) { + monitor->priv->max_freq = freq; + monitor->priv->changed = TRUE; + } + } + break; + case PROP_GOVERNOR: { + const gchar *gov = g_value_get_string (value); + + if (monitor->priv->governor) { + if (g_ascii_strcasecmp (gov, monitor->priv->governor) != 0) { + g_free (monitor->priv->governor); + monitor->priv->governor = gov ? g_strdup (gov) : NULL; + monitor->priv->changed = TRUE; + } + } else { + monitor->priv->governor = gov ? g_strdup (gov) : NULL; + monitor->priv->changed = TRUE; + } + } break; default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, spec); break; } } -/* Is it neccesary?? */ static void -cpufreq_monitor_get_property (GObject *object, guint prop_id, GValue *value, +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)); + CPUFreqMonitor *monitor; monitor = CPUFREQ_MONITOR (object); - private = CPUFREQ_MONITOR_GET_PROTECTED (monitor); switch (prop_id) { case PROP_CPU: - g_value_set_uint (value, private->cpu); + g_value_set_uint (value, monitor->priv->cpu); + break; + case PROP_FREQUENCY: + g_value_set_int (value, monitor->priv->cur_freq); + break; + case PROP_MAX_FREQUENCY: + g_value_set_int (value, monitor->priv->max_freq); + break; + case PROP_GOVERNOR: + g_value_set_string (value, monitor->priv->governor); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, spec); + break; } } -static void -cpufreq_monitor_free_data (CPUFreqMonitor *monitor) +static gboolean +cpufreq_monitor_run_cb (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; + gboolean retval = FALSE; + + if (CPUFREQ_MONITOR_GET_CLASS (monitor)->run) + retval = CPUFREQ_MONITOR_GET_CLASS (monitor)->run (monitor); + + if (monitor->priv->changed) { + g_signal_emit (monitor, signals[SIGNAL_CHANGED], 0); + monitor->priv->changed = FALSE; } - if (private->governor) { - g_free (private->governor); - private->governor = NULL; - } + return retval; } void cpufreq_monitor_run (CPUFreqMonitor *monitor) { - g_return_if_fail (IS_CPUFREQ_MONITOR (monitor)); + g_return_if_fail (CPUFREQ_IS_MONITOR (monitor)); - if (CPUFREQ_MONITOR_GET_CLASS (monitor)->run) { - return CPUFREQ_MONITOR_GET_CLASS (monitor)->run (monitor); - } else { + if (monitor->priv->timeout_handler > 0) return; - } + + monitor->priv->timeout_handler = + g_timeout_add (CPUFREQ_MONITOR_INTERVAL, + (GSourceFunc) cpufreq_monitor_run_cb, + (gpointer) monitor); } GList * cpufreq_monitor_get_available_frequencies (CPUFreqMonitor *monitor) { - g_return_val_if_fail (IS_CPUFREQ_MONITOR (monitor), NULL); + g_return_val_if_fail (CPUFREQ_IS_MONITOR (monitor), NULL); + + if (monitor->priv->available_freqs) + return monitor->priv->available_freqs; if (CPUFREQ_MONITOR_GET_CLASS (monitor)->get_available_frequencies) { - return CPUFREQ_MONITOR_GET_CLASS (monitor)->get_available_frequencies (monitor); - } else { - return NULL; + monitor->priv->available_freqs = + CPUFREQ_MONITOR_GET_CLASS (monitor)->get_available_frequencies (monitor); } + + return monitor->priv->available_freqs; } GList * cpufreq_monitor_get_available_governors (CPUFreqMonitor *monitor) { - g_return_val_if_fail (IS_CPUFREQ_MONITOR (monitor), NULL); + g_return_val_if_fail (CPUFREQ_IS_MONITOR (monitor), NULL); + + if (monitor->priv->available_govs) + return monitor->priv->available_govs; + + if (CPUFREQ_MONITOR_GET_CLASS (monitor)->get_available_governors) { + monitor->priv->available_govs = + CPUFREQ_MONITOR_GET_CLASS (monitor)->get_available_governors (monitor); + } - if (CPUFREQ_MONITOR_GET_CLASS (monitor)->get_available_governors) { - return CPUFREQ_MONITOR_GET_CLASS (monitor)->get_available_governors (monitor); - } else { - return NULL; - } + return monitor->priv->available_govs; } guint cpufreq_monitor_get_cpu (CPUFreqMonitor *monitor) { - CPUFreqMonitorProtected *private; - - g_return_val_if_fail (IS_CPUFREQ_MONITOR (monitor), 0); - - private = CPUFREQ_MONITOR_GET_PROTECTED (monitor); + g_return_val_if_fail (CPUFREQ_IS_MONITOR (monitor), 0); - return private->cpu; + return monitor->priv->cpu; } -gchar * -cpufreq_monitor_get_governor (CPUFreqMonitor *monitor) +void +cpufreq_monitor_set_cpu (CPUFreqMonitor *monitor, guint cpu) { - CPUFreqMonitorProtected *private; - - g_return_val_if_fail (IS_CPUFREQ_MONITOR (monitor), NULL); - - private = CPUFREQ_MONITOR_GET_PROTECTED (monitor); + g_return_if_fail (CPUFREQ_IS_MONITOR (monitor)); - return g_strdup (private->governor); + g_object_set (G_OBJECT (monitor), + "cpu", cpu, NULL); } -gchar * +gint cpufreq_monitor_get_frequency (CPUFreqMonitor *monitor) { - CPUFreqMonitorProtected *private; - - g_return_val_if_fail (IS_CPUFREQ_MONITOR (monitor), NULL); - - private = CPUFREQ_MONITOR_GET_PROTECTED (monitor); - - return g_strdup (private->freq); -} - -gchar * -cpufreq_monitor_get_percentage (CPUFreqMonitor *monitor) -{ - CPUFreqMonitorProtected *private; - - g_return_val_if_fail (IS_CPUFREQ_MONITOR (monitor), NULL); + g_return_val_if_fail (CPUFREQ_IS_MONITOR (monitor), -1); - private = CPUFREQ_MONITOR_GET_PROTECTED (monitor); - - return g_strdup (private->perc); + return monitor->priv->cur_freq; } gchar * -cpufreq_monitor_get_unit (CPUFreqMonitor *monitor) +cpufreq_monitor_get_governor (CPUFreqMonitor *monitor) { - CPUFreqMonitorProtected *private; - - g_return_val_if_fail (IS_CPUFREQ_MONITOR (monitor), NULL); + g_return_val_if_fail (CPUFREQ_IS_MONITOR (monitor), NULL); - private = CPUFREQ_MONITOR_GET_PROTECTED (monitor); - - return g_strdup (private->unit); + return g_strdup (monitor->priv->governor); } -void -cpufreq_monitor_set_cpu (CPUFreqMonitor *monitor, guint cpu) +gint +cpufreq_monitor_get_percentage (CPUFreqMonitor *monitor) { - CPUFreqMonitorProtected *private; - - g_return_if_fail (IS_CPUFREQ_MONITOR (monitor)); - - private = CPUFREQ_MONITOR_GET_PROTECTED (monitor); + g_return_val_if_fail (CPUFREQ_IS_MONITOR (monitor), -1); - if (private->cpu != cpu) { - private->cpu = cpu; - g_signal_emit (monitor, CPUFREQ_MONITOR_GET_CLASS (monitor)->signals[CHANGED], 0); + if (monitor->priv->max_freq > 0) { + return ((monitor->priv->cur_freq * 100) / monitor->priv->max_freq); } -} - + return -1; +} diff --git a/cpufreq/src/cpufreq-monitor.h b/cpufreq/src/cpufreq-monitor.h index a765471a9..dcb1a24b9 100644 --- a/cpufreq/src/cpufreq-monitor.h +++ b/cpufreq/src/cpufreq-monitor.h @@ -24,56 +24,45 @@ #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)) +#define CPUFREQ_TYPE_MONITOR (cpufreq_monitor_get_type ()) +#define CPUFREQ_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CPUFREQ_TYPE_MONITOR, CPUFreqMonitor)) +#define CPUFREQ_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), CPUFREQ_TYPE_MONITOR, CPUFreqMonitorClass)) +#define CPUFREQ_IS_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CPUFREQ_TYPE_MONITOR)) +#define CPUFREQ_IS_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CPUFREQ_TYPE_MONITOR)) +#define CPUFREQ_MONITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CPUFREQ_TYPE_MONITOR, CPUFreqMonitorClass)) -enum { - CHANGED, - LAST -}; - -typedef struct _CPUFreqMonitor CPUFreqMonitor; -typedef struct _CPUFreqMonitorClass CPUFreqMonitorClass; +typedef struct _CPUFreqMonitor CPUFreqMonitor; +typedef struct _CPUFreqMonitorClass CPUFreqMonitorClass; +typedef struct _CPUFreqMonitorPrivate CPUFreqMonitorPrivate; struct _CPUFreqMonitor { GObject parent; + + CPUFreqMonitorPrivate *priv; }; struct _CPUFreqMonitorClass { GObjectClass parent_class; - /*< public >*/ - void (* run) (CPUFreqMonitor *monitor); - GList *(* get_available_frequencies) (CPUFreqMonitor *monitor); - GList *(* get_available_governors) (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); + gboolean (* run) (CPUFreqMonitor *monitor); + GList *(* get_available_frequencies) (CPUFreqMonitor *monitor); + GList *(* get_available_governors) (CPUFreqMonitor *monitor); /*< signals >*/ - guint signals[LAST]; - void (* changed) (CPUFreqMonitor *monitor); + void (* changed) (CPUFreqMonitor *monitor); }; -GType cpufreq_monitor_get_type (void) G_GNUC_CONST; +GType cpufreq_monitor_get_type (void) G_GNUC_CONST; void cpufreq_monitor_run (CPUFreqMonitor *monitor); GList *cpufreq_monitor_get_available_frequencies (CPUFreqMonitor *monitor); GList *cpufreq_monitor_get_available_governors (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); + guint cpu); +gchar *cpufreq_monitor_get_governor (CPUFreqMonitor *monitor); +gint cpufreq_monitor_get_frequency (CPUFreqMonitor *monitor); +gint cpufreq_monitor_get_percentage (CPUFreqMonitor *monitor); #endif /* __CPUFREQ_MONITOR_H__ */ diff --git a/cpufreq/src/cpufreq-popup.c b/cpufreq/src/cpufreq-popup.c index b75786712..50cfd8011 100644 --- a/cpufreq/src/cpufreq-popup.c +++ b/cpufreq/src/cpufreq-popup.c @@ -19,309 +19,645 @@ * Authors : Carlos García Campos <carlosgc@gnome.org> */ -#include <config.h> +#include <glib/gi18n.h> -#include <gnome.h> +#include <gtk/gtkaction.h> +#include <gtk/gtktoggleaction.h> +#include <gtk/gtkradioaction.h> +#include <gtk/gtkuimanager.h> +#include <stdlib.h> +#include <string.h> #include "cpufreq-popup.h" -#include "cpufreq-monitor.h" - -static void cpufreq_popup_position_menu (GtkMenu *menu, int *x, int *y, - gboolean *push_in, gpointer gdata); -static void cpufreq_popup_set_frequency (GtkWidget *widget, gpointer gdata); -static void cpufreq_popup_set_governor (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_frequencies_menu_new (CPUFreqApplet *applet, GList *available_freqs); -static GtkWidget *cpufreq_popup_governors_menu_new (GList *available_govs); -static GtkWidget *cpufreq_popup_new (CPUFreqApplet *applet, GList *available_freqs, - GList *available_govs); - -typedef struct _cpufreq_t { - gint freq; - gint cpu; -} cpufreq_t; +#include "cpufreq-utils.h" + +struct _CPUFreqPopupPrivate { + GtkUIManager *ui_manager; + + GtkActionGroup *freqs_group; + GSList *freqs_radio_group; + GSList *freqs_actions; + + GtkActionGroup *govs_group; + GSList *govs_radio_group; + GSList *govs_actions; + + guint merge_id; + gboolean need_build; + + CPUFreqPrefs *prefs; + CPUFreqSelectorMode selector_mode; + CPUFreqMonitor *monitor; +}; + +#define CPUFREQ_POPUP_GET_PRIVATE(object) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((object), CPUFREQ_TYPE_POPUP, CPUFreqPopupPrivate)) + +static void cpufreq_popup_init (CPUFreqPopup *popup); +static void cpufreq_popup_class_init (CPUFreqPopupClass *klass); +static void cpufreq_popup_finalize (GObject *object); + +G_DEFINE_TYPE (CPUFreqPopup, cpufreq_popup, G_TYPE_OBJECT) + +static const gchar *ui_popup = +"<ui>" +" <popup name=\"CPUFreqSelectorPopup\" action=\"PopupAction\">" +" <menu name=\"FrequenciesMenu\" action=\"Frequencies\">" +" <placeholder name=\"FreqsItemsGroup\">" +" </placeholder>" +" </menu>" +" <menu name=\"GovernorsMenu\" action=\"Governors\">" +" <placeholder name=\"GovsItemsGroup\">" +" </placeholder>" +" </menu>" +" <placeholder name=\"FreqsItemsGroup\">" +" </placeholder>" +" <placeholder name=\"GovsItemsGroup\">" +" </placeholder>" +" </popup>" +"</ui>"; + +#define FREQS_PLACEHOLDER_PATH "/CPUFreqSelectorPopup/FreqsItemsGroup" +#define GOVS_PLACEHOLDER_PATH "/CPUFreqSelectorPopup/GovsItemsGroup" +#define BOTH_PLACEHOLDER_PATH "/CPUFreqSelectorPopup/BothMenu" +#define FREQS_SUBMENU_PLACEHOLDER_PATH "/CPUFreqSelectorPopup/FrequenciesMenu/FreqsItemsGroup" +#define GOVS_SUBMENU_PLACEHOLDER_PATH "/CPUFreqSelectorPopup/GovernorsMenu/GovsItemsGroup" + +static const GtkActionEntry both_menu_entries[] = +{ + { "Frequencies", NULL, N_("_Frequencies") }, + { "Governors", NULL, N_("_Governors") } +}; static void -cpufreq_popup_position_menu (GtkMenu *menu, int *x, int *y, - gboolean *push_in, gpointer gdata) +cpufreq_popup_init (CPUFreqPopup *popup) { - GtkWidget *widget; - GtkRequisition requisition; - gint menu_xpos; - gint menu_ypos; - - widget = GTK_WIDGET (gdata); - - gtk_widget_size_request (GTK_WIDGET (menu), &requisition); - - gdk_window_get_origin (widget->window, &menu_xpos, &menu_ypos); - - menu_xpos += widget->allocation.x; - menu_ypos += widget->allocation.y; - - switch (panel_applet_get_orient (PANEL_APPLET (widget))) { - case PANEL_APPLET_ORIENT_DOWN: - case PANEL_APPLET_ORIENT_UP: - if (menu_ypos > gdk_screen_get_height (gtk_widget_get_screen (widget)) / 2) - menu_ypos -= requisition.height; - else - menu_ypos += widget->allocation.height; - break; - case PANEL_APPLET_ORIENT_RIGHT: - case PANEL_APPLET_ORIENT_LEFT: - if (menu_xpos > gdk_screen_get_width (gtk_widget_get_screen (widget)) / 2) - menu_xpos -= requisition.width; - else - menu_xpos += widget->allocation.width; - break; - default: - g_assert_not_reached (); - } - - *x = menu_xpos; - *y = menu_ypos; - *push_in = TRUE; + GtkActionGroup *action_group; + + popup->priv = CPUFREQ_POPUP_GET_PRIVATE (popup); + + popup->priv->ui_manager = gtk_ui_manager_new (); + + popup->priv->freqs_group = NULL; + popup->priv->freqs_radio_group = NULL; + popup->priv->freqs_actions = NULL; + + popup->priv->govs_group = NULL; + popup->priv->govs_radio_group = NULL; + popup->priv->govs_actions = NULL; + + action_group = gtk_action_group_new ("BothActions"); + gtk_action_group_set_translation_domain (action_group, NULL); + + gtk_action_group_add_actions (action_group, + both_menu_entries, + G_N_ELEMENTS (both_menu_entries), + NULL); + gtk_ui_manager_insert_action_group (popup->priv->ui_manager, + action_group, 2); + g_object_unref (action_group); + + popup->priv->merge_id = 0; + popup->priv->need_build = TRUE; + + gtk_ui_manager_add_ui_from_string (popup->priv->ui_manager, + ui_popup, -1, NULL); + + popup->priv->prefs = NULL; + popup->priv->selector_mode = CPUFREQ_SELECTOR_MODE_FREQUENCIES; + popup->priv->monitor = NULL; } -gboolean -cpufreq_popup_show (CPUFreqApplet *applet, guint32 time) +static void +cpufreq_popup_class_init (CPUFreqPopupClass *klass) { - GList *available_freqs = NULL; - GList *available_govs = NULL; - - if (!cpufreq_applet_selector_is_available ()) - return FALSE; - - if (applet->popup) { - gtk_widget_destroy (applet->popup); - applet->popup = NULL; - } - - available_freqs = cpufreq_monitor_get_available_frequencies (applet->monitor); - available_govs = cpufreq_monitor_get_available_governors (applet->monitor); - if (!available_freqs) - return FALSE; - - applet->popup = cpufreq_popup_new (applet, available_freqs, available_govs); - - gtk_widget_grab_focus (GTK_WIDGET (applet)); - - gtk_menu_popup (GTK_MENU (applet->popup), NULL, NULL, - cpufreq_popup_position_menu, (gpointer) applet, - 1, time); - return TRUE; + GObjectClass *g_object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (g_object_class, sizeof (CPUFreqPopupPrivate)); + + g_object_class->finalize = cpufreq_popup_finalize; } static void -cpufreq_popup_set_frequency (GtkWidget *widget, gpointer gdata) +cpufreq_popup_finalize (GObject *object) +{ + CPUFreqPopup *popup = CPUFREQ_POPUP (object); + + if (popup->priv->ui_manager) { + g_object_unref (popup->priv->ui_manager); + popup->priv->ui_manager = NULL; + } + + if (popup->priv->freqs_group) { + g_object_unref (popup->priv->freqs_group); + popup->priv->freqs_group = NULL; + } + + if (popup->priv->freqs_actions) { + g_slist_free (popup->priv->freqs_actions); + popup->priv->freqs_actions = NULL; + } + + if (popup->priv->govs_group) { + g_object_unref (popup->priv->govs_group); + popup->priv->govs_group = NULL; + } + + if (popup->priv->govs_actions) { + g_slist_free (popup->priv->govs_actions); + popup->priv->govs_actions = NULL; + } + + if (popup->priv->prefs) { + g_object_unref (popup->priv->prefs); + popup->priv->prefs = NULL; + } + + if (popup->priv->monitor) { + g_object_unref (popup->priv->monitor); + popup->priv->monitor = NULL; + } + + G_OBJECT_CLASS (cpufreq_popup_parent_class)->finalize (object); +} + +CPUFreqPopup * +cpufreq_popup_new (void) { - gint freq, cpu; - gchar *path = NULL; - gchar *command; - cpufreq_t *cf; - - cf = (cpufreq_t *)gdata; - freq = cf->freq; - cpu = cf->cpu; - - path = g_find_program_in_path ("cpufreq-selector"); - - if (!path) - return; - - command = g_strdup_printf ("%s -f %d -c %d", path, freq, cpu); - - g_spawn_command_line_async (command, NULL); /* TODO: error */ - - g_free (command); - g_free (path); + CPUFreqPopup *popup; + + popup = CPUFREQ_POPUP (g_object_new (CPUFREQ_TYPE_POPUP, + NULL)); + + return popup; } static void -cpufreq_popup_set_governor (GtkWidget *widget, gpointer gdata) +cpufreq_popup_selector_mode_changed (CPUFreqPopup *popup, + GParamSpec *arg1, + CPUFreqPrefs *prefs) { - gchar *governor; - gchar *path = NULL; - gchar *command; + CPUFreqSelectorMode selector_mode; + + selector_mode = cpufreq_prefs_get_selector_mode (popup->priv->prefs); + if (selector_mode != popup->priv->selector_mode) { + popup->priv->selector_mode = selector_mode; + popup->priv->need_build = TRUE; + } +} + +/* Public methods */ +void +cpufreq_popup_set_preferences (CPUFreqPopup *popup, + CPUFreqPrefs *prefs) +{ + g_return_if_fail (CPUFREQ_IS_POPUP (popup)); + g_return_if_fail (CPUFREQ_IS_PREFS (prefs)); + + if (popup->priv->prefs == prefs) + return; + + if (popup->priv->prefs) + g_object_unref (popup->priv->prefs); + popup->priv->prefs = g_object_ref (prefs); + popup->priv->selector_mode = cpufreq_prefs_get_selector_mode (popup->priv->prefs); + g_signal_connect_swapped (G_OBJECT (popup->priv->prefs), + "notify::selector-mode", + G_CALLBACK (cpufreq_popup_selector_mode_changed), + (gpointer) popup); +} + +void +cpufreq_popup_set_monitor (CPUFreqPopup *popup, + CPUFreqMonitor *monitor) +{ + g_return_if_fail (CPUFREQ_IS_POPUP (popup)); + g_return_if_fail (CPUFREQ_IS_MONITOR (monitor)); + + if (popup->priv->monitor == monitor) + return; + + if (popup->priv->monitor) + g_object_unref (popup->priv->monitor); + popup->priv->monitor = g_object_ref (monitor); +} - governor = (gchar *) gdata; +static void +cpufreq_popup_run_selector (CPUFreqPopup *popup, + const gchar *params) +{ + gchar *path; + guint cpu; + gchar *command; + GError *error = NULL; path = g_find_program_in_path ("cpufreq-selector"); if (!path) return; - command = g_strdup_printf ("%s -g %s", path, governor); + cpu = cpufreq_prefs_get_cpu (popup->priv->prefs); - g_spawn_command_line_async (command, NULL); /* TODO: error */ + command = g_strdup_printf ("%s -c %d %s", path, cpu, params); + g_spawn_command_line_async (command, &error); g_free (command); - g_free (path); + + if (error) { + g_warning (error->message); + g_error_free (error); + } } static void -cpufreq_popup_menu_item_set_image (CPUFreqApplet *applet, GtkWidget *menu_item, - gint freq, gint max_freq) +cpufreq_popup_frequencies_menu_activate (GtkAction *action, + CPUFreqPopup *popup) { - gint perc, image; - gchar *pixmaps[] = { - GNOME_PIXMAPSDIR"/cpufreq-applet/cpufreq-25.png", - GNOME_PIXMAPSDIR"/cpufreq-applet/cpufreq-50.png", - GNOME_PIXMAPSDIR"/cpufreq-applet/cpufreq-75.png", - GNOME_PIXMAPSDIR"/cpufreq-applet/cpufreq-100.png", - NULL }; - - perc = (freq * 100) / max_freq; - - if (perc < 30) - image = 0; - else if ((perc >= 30) && (perc < 70)) - image = 1; - else if ((perc >= 70) && (perc < 90)) - image = 2; - else - image = 3; - - if (applet->pixbufs[image] == NULL) { - applet->pixbufs[image] = gdk_pixbuf_new_from_file_at_size (pixmaps[image], - 24, 24, NULL); - } - - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), - gtk_image_new_from_pixbuf (applet->pixbufs[image])); + const gchar *name; + const gchar *freq; + gchar *params; + + if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) + return; + + name = gtk_action_get_name (action); + freq = name + strlen ("Frequency"); + + params = g_strdup_printf ("-f %s", freq); + cpufreq_popup_run_selector (popup, params); + g_free (params); } -static GtkWidget * -cpufreq_popup_governors_menu_new (GList *available_govs) +static void +cpufreq_popup_governors_menu_activate (GtkAction *action, + CPUFreqPopup *popup) { - GtkWidget *menu_item, *submenu; - gchar *governor; + const gchar *name; + const gchar *governor; + gchar *params; - submenu = gtk_menu_new (); + if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) + return; + + name = gtk_action_get_name (action); + governor = name + strlen ("Governor"); - while (available_govs) { - governor = (gchar *) available_govs->data; - menu_item = gtk_menu_item_new_with_label (governor); - gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menu_item); - gtk_widget_show (menu_item); + params = g_strdup_printf ("-g %s", governor); + cpufreq_popup_run_selector (popup, params); + g_free (params); +} - g_signal_connect (G_OBJECT (menu_item), "activate", - G_CALLBACK (cpufreq_popup_set_governor), - (gpointer) governor); +static void +cpufreq_popup_menu_add_action (CPUFreqPopup *popup, + const gchar *menu, + GtkActionGroup *action_group, + const gchar *action_name, + const gchar *label, + gboolean sensitive) +{ + GtkToggleAction *action; + gchar *name; - available_govs = g_list_next (available_govs); + name = g_strdup_printf ("%s%s", menu, action_name); + + action = g_object_new (GTK_TYPE_RADIO_ACTION, + "name", name, + "label", label, + NULL); + + gtk_action_set_sensitive (GTK_ACTION (action), sensitive); + + if (g_ascii_strcasecmp (menu, "Frequency") == 0) { + gtk_radio_action_set_group (GTK_RADIO_ACTION (action), + popup->priv->freqs_radio_group); + popup->priv->freqs_radio_group = + gtk_radio_action_get_group (GTK_RADIO_ACTION (action)); + + popup->priv->freqs_actions = g_slist_prepend (popup->priv->freqs_actions, + (gpointer) action); + + g_signal_connect (action, "activate", + G_CALLBACK (cpufreq_popup_frequencies_menu_activate), + (gpointer) popup); + } else if (g_ascii_strcasecmp (menu, "Governor") == 0) { + gtk_radio_action_set_group (GTK_RADIO_ACTION (action), + popup->priv->govs_radio_group); + popup->priv->govs_radio_group = + gtk_radio_action_get_group (GTK_RADIO_ACTION (action)); + + popup->priv->govs_actions = g_slist_prepend (popup->priv->govs_actions, + (gpointer) action); + + g_signal_connect (action, "activate", + G_CALLBACK (cpufreq_popup_governors_menu_activate), + (gpointer) popup); } - return submenu; + gtk_action_group_add_action (action_group, GTK_ACTION (action)); + g_object_unref (action); + + g_free (name); } -static GtkWidget * -cpufreq_popup_frequencies_menu_new (CPUFreqApplet *applet, GList *available_freqs) +static void +frequencies_menu_create_actions (CPUFreqPopup *popup) { - GtkWidget *menu_item, *submenu; - gchar *label; - gchar *text_freq, *text_unit, *text_perc; - gint freq, max_freq, divisor, cpu; - cpufreq_t *cf; + GList *available_freqs; - max_freq = atoi ((gchar *) available_freqs->data); /* First item is the max freq */ - cpu = cpufreq_monitor_get_cpu (applet->monitor); + available_freqs = cpufreq_monitor_get_available_frequencies (popup->priv->monitor); - submenu = gtk_menu_new (); while (available_freqs) { - freq = atoi ((gchar *) available_freqs->data); - - if (applet->show_mode != MODE_GRAPHIC && - applet->show_text_mode == MODE_TEXT_PERCENTAGE) { - 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 { - 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); - } - - menu_item = gtk_image_menu_item_new_with_label (label); - if (applet->show_mode != MODE_TEXT) { - cpufreq_popup_menu_item_set_image (applet, menu_item, freq, max_freq); - } - gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menu_item); - gtk_widget_show (menu_item); - - cf = g_new (cpufreq_t, 1); - cf->freq = freq; - cf->cpu = cpu; + const gchar *text; + gchar *freq_text; + gchar *label; + gchar *unit; + gint freq; - g_signal_connect_data (G_OBJECT (menu_item), "activate", - G_CALLBACK (cpufreq_popup_set_frequency), - cf, (GClosureNotify)g_free, G_CONNECT_AFTER); + text = (const gchar *) available_freqs->data; + freq = atoi (text); + + freq_text = cpufreq_utils_get_frequency_label (freq); + unit = cpufreq_utils_get_frequency_unit (freq); + + label = g_strdup_printf ("%s %s", freq_text, unit); + g_free (freq_text); + g_free (unit); + cpufreq_popup_menu_add_action (popup, + "Frequency", + popup->priv->freqs_group, + text, label, TRUE); g_free (label); available_freqs = g_list_next (available_freqs); } - return submenu; + cpufreq_popup_menu_add_action (popup, + "Frequency", + popup->priv->freqs_group, + "Automatic", "Automatic", + FALSE); } -static GtkWidget * -cpufreq_popup_new (CPUFreqApplet *applet, GList *available_freqs, GList *available_govs) +static void +governors_menu_create_actions (CPUFreqPopup *popup) { - GtkWidget *popup = NULL; - GtkWidget *menu_item, *submenu; + GList *available_govs; - if ((available_freqs == NULL) && - (available_govs == NULL)) { - return NULL; + available_govs = cpufreq_monitor_get_available_governors (popup->priv->monitor); + + while (available_govs) { + const gchar *governor; + gchar *label; + + governor = (const gchar *) available_govs->data; + label = g_strdup (governor); + label[0] = g_ascii_toupper (label[0]); + + cpufreq_popup_menu_add_action (popup, + "Governor", + popup->priv->govs_group, + governor, label, TRUE); + g_free (label); + + available_govs = g_list_next (available_govs); } +} + +static void +cpufreq_popup_build_ui (CPUFreqPopup *popup, + GSList *actions, + const gchar *menu_path) +{ + GSList *l = NULL; - switch (applet->selector_mode) { - case SELECTOR_MODE_FREQUENCIES: - popup = cpufreq_popup_frequencies_menu_new (applet, available_freqs); + for (l = actions; l && l->data; l = g_slist_next (l)) { + GtkAction *action; + gchar *name = NULL; + gchar *label = NULL; + + action = (GtkAction *) l->data; + + g_object_get (G_OBJECT (action), + "name", &name, + "label", &label, + NULL); + + if (!g_strrstr (name, "Automatic")) { + gtk_ui_manager_add_ui (popup->priv->ui_manager, + popup->priv->merge_id, + menu_path, + label, name, + GTK_UI_MANAGER_MENUITEM, + FALSE); + } + + g_free (name); + g_free (label); + } +} - break; - case SELECTOR_MODE_GOVERNORS: - popup = cpufreq_popup_governors_menu_new (available_govs); +static void +cpufreq_popup_build_frequencies_menu (CPUFreqPopup *popup, + const gchar *path) +{ + if (!popup->priv->freqs_group) { + GtkActionGroup *action_group; + + action_group = gtk_action_group_new ("FreqsActions"); + popup->priv->freqs_group = action_group; + gtk_action_group_set_translation_domain (action_group, NULL); + + frequencies_menu_create_actions (popup); + popup->priv->freqs_actions = g_slist_reverse (popup->priv->freqs_actions); + gtk_ui_manager_insert_action_group (popup->priv->ui_manager, + action_group, 0); + } + + cpufreq_popup_build_ui (popup, + popup->priv->freqs_actions, + path); + + gtk_ui_manager_add_ui (popup->priv->ui_manager, + popup->priv->merge_id, + path, + "SepItem", "Sep", + GTK_UI_MANAGER_SEPARATOR, + FALSE); + + gtk_ui_manager_add_ui (popup->priv->ui_manager, + popup->priv->merge_id, + path, + "FrequencyAutomaticItem", + "FrequencyAutomatic", + GTK_UI_MANAGER_MENUITEM, + FALSE); +} + +static void +cpufreq_popup_build_governors_menu (CPUFreqPopup *popup, + const gchar *path) +{ + if (!popup->priv->govs_group) { + GtkActionGroup *action_group; + + action_group = gtk_action_group_new ("GovsActions"); + popup->priv->govs_group = action_group; + gtk_action_group_set_translation_domain (action_group, NULL); + + governors_menu_create_actions (popup); + popup->priv->govs_actions = g_slist_reverse (popup->priv->govs_actions); + gtk_ui_manager_insert_action_group (popup->priv->ui_manager, + action_group, 1); + } + + cpufreq_popup_build_ui (popup, + popup->priv->govs_actions, + path); +} + +static void +cpufreq_popup_build_menu (CPUFreqPopup *popup) +{ + if (popup->priv->merge_id > 0) { + gtk_ui_manager_remove_ui (popup->priv->ui_manager, + popup->priv->merge_id); + gtk_ui_manager_ensure_update (popup->priv->ui_manager); + } + + popup->priv->merge_id = gtk_ui_manager_new_merge_id (popup->priv->ui_manager); + switch (popup->priv->selector_mode) { + case CPUFREQ_SELECTOR_MODE_FREQUENCIES: + cpufreq_popup_build_frequencies_menu (popup, + FREQS_PLACEHOLDER_PATH); break; - case SELECTOR_MODE_BOTH: - popup = gtk_menu_new (); + case CPUFREQ_SELECTOR_MODE_GOVERNORS: + cpufreq_popup_build_governors_menu (popup, + GOVS_PLACEHOLDER_PATH); + break; + case CPUFREQ_SELECTOR_MODE_BOTH: + cpufreq_popup_build_frequencies_menu (popup, + FREQS_SUBMENU_PLACEHOLDER_PATH); + cpufreq_popup_build_governors_menu (popup, + GOVS_SUBMENU_PLACEHOLDER_PATH); + break; + default: + g_assert_not_reached (); + break; + } +} - submenu = cpufreq_popup_governors_menu_new (available_govs); +static void +cpufreq_popup_menu_set_active_action (CPUFreqPopup *popup, + GtkActionGroup *action_group, + const gchar *prefix, + const gchar *item) +{ + gchar name[128]; + GtkAction *action; + + g_snprintf (name, sizeof (name), "%s%s", prefix, item); + action = gtk_action_group_get_action (action_group, name); - menu_item = gtk_menu_item_new_with_label (_("Governors")); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), submenu); - gtk_menu_shell_append (GTK_MENU_SHELL (popup), menu_item); - gtk_widget_show (menu_item); + g_signal_handlers_block_by_func (action, + cpufreq_popup_frequencies_menu_activate, + popup); + g_signal_handlers_block_by_func (action, + cpufreq_popup_governors_menu_activate, + popup); + + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE); + + g_signal_handlers_unblock_by_func (action, + cpufreq_popup_frequencies_menu_activate, + popup); + g_signal_handlers_unblock_by_func (action, + cpufreq_popup_governors_menu_activate, + popup); +} + +static void +cpufreq_popup_menu_governors_set_active (CPUFreqPopup *popup) +{ + gchar *active; + + active = cpufreq_monitor_get_governor (popup->priv->monitor); + + cpufreq_popup_menu_set_active_action (popup, + popup->priv->govs_group, + "Governor", + active); + g_free (active); +} + +static void +cpufreq_popup_menu_frequencies_set_active (CPUFreqPopup *popup) +{ + gchar *active; + gchar *governor; - submenu = cpufreq_popup_frequencies_menu_new (applet, available_freqs); + governor = cpufreq_monitor_get_governor (popup->priv->monitor); - menu_item = gtk_menu_item_new_with_label (_("Frequencies")); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), submenu); - gtk_menu_shell_append (GTK_MENU_SHELL (popup), menu_item); - gtk_widget_show (menu_item); + if (cpufreq_utils_governor_is_automatic (governor)) { + active = g_strdup ("Automatic"); + } else { + active = g_strdup_printf ("%d", + cpufreq_monitor_get_frequency ( + popup->priv->monitor)); + } + g_free (governor); + + cpufreq_popup_menu_set_active_action (popup, + popup->priv->freqs_group, + "Frequency", + active); + g_free (active); +} + +static void +cpufreq_popup_menu_set_active (CPUFreqPopup *popup) +{ + switch (popup->priv->selector_mode) { + case CPUFREQ_SELECTOR_MODE_FREQUENCIES: + cpufreq_popup_menu_frequencies_set_active (popup); + break; + case CPUFREQ_SELECTOR_MODE_GOVERNORS: + cpufreq_popup_menu_governors_set_active (popup); + break; + case CPUFREQ_SELECTOR_MODE_BOTH: + cpufreq_popup_menu_frequencies_set_active (popup); + cpufreq_popup_menu_governors_set_active (popup); break; + default: + g_assert_not_reached (); + break; + } +} + +GtkWidget * +cpufreq_popup_get_menu (CPUFreqPopup *popup) +{ + GtkWidget *menu; + + g_return_val_if_fail (CPUFREQ_IS_POPUP (popup), NULL); + g_return_val_if_fail (CPUFREQ_IS_MONITOR (popup->priv->monitor), NULL); + g_return_val_if_fail (CPUFREQ_IS_PREFS (popup->priv->prefs), NULL); + + if (!cpufreq_utils_selector_is_available ()) + return NULL; + + if (popup->priv->need_build) { + cpufreq_popup_build_menu (popup); + popup->priv->need_build = FALSE; } - return popup; + cpufreq_popup_menu_set_active (popup); + + menu = gtk_ui_manager_get_widget (popup->priv->ui_manager, + "/CPUFreqSelectorPopup"); + + return menu; } + diff --git a/cpufreq/src/cpufreq-popup.h b/cpufreq/src/cpufreq-popup.h index 16c3ac32e..a01b17a38 100644 --- a/cpufreq/src/cpufreq-popup.h +++ b/cpufreq/src/cpufreq-popup.h @@ -19,8 +19,46 @@ * Authors : Carlos García Campos <carlosgc@gnome.org> */ -#include <glib.h> -#include "cpufreq-applet.h" +#ifndef CPUFREQ_POPUP_H +#define CPUFREQ_POPUP_H -gboolean cpufreq_popup_show (CPUFreqApplet *applet, guint32 time); +#include <glib-object.h> +#include "cpufreq-monitor.h" +#include "cpufreq-prefs.h" + +G_BEGIN_DECLS + +#define CPUFREQ_TYPE_POPUP (cpufreq_popup_get_type ()) +#define CPUFREQ_POPUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CPUFREQ_TYPE_POPUP, CPUFreqPopup)) +#define CPUFREQ_POPUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), CPUFREQ_TYPE_POPUP, CPUFreqPopupClass)) +#define CPUFREQ_IS_POPUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CPUFREQ_TYPE_POPUP)) +#define CPUFREQ_IS_POPUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CPUFREQ_TYPE_POPUP)) +#define CPUFREQ_POPUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CPUFREQ_TYPE_POPUP, CPUFreqPopupClass)) + +typedef struct _CPUFreqPopup CPUFreqPopup; +typedef struct _CPUFreqPopupClass CPUFreqPopupClass; +typedef struct _CPUFreqPopupPrivate CPUFreqPopupPrivate; + +struct _CPUFreqPopup { + GObject base; + + CPUFreqPopupPrivate *priv; +}; + +struct _CPUFreqPopupClass { + GObjectClass parent_class; +}; + +GType cpufreq_popup_get_type (void) G_GNUC_CONST; +CPUFreqPopup *cpufreq_popup_new (void); + +void cpufreq_popup_set_preferences (CPUFreqPopup *popup, + CPUFreqPrefs *prefs); +void cpufreq_popup_set_monitor (CPUFreqPopup *popup, + CPUFreqMonitor *monitor); +GtkWidget *cpufreq_popup_get_menu (CPUFreqPopup *popup); + +G_END_DECLS + +#endif /* CPUFREQ_POPUP_H */ diff --git a/cpufreq/src/cpufreq-prefs.c b/cpufreq/src/cpufreq-prefs.c index c1be9bfd6..19155ae1d 100644 --- a/cpufreq/src/cpufreq-prefs.c +++ b/cpufreq/src/cpufreq-prefs.c @@ -19,349 +19,720 @@ * Authors : Carlos García Campos <carlosgc@gnome.org> */ -#include <config.h> - -#include <gnome.h> -#include <panel-applet.h> -#include <panel-applet-gconf.h> +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gtk/gtktogglebutton.h> +#include <gtk/gtkcombobox.h> +#include <gtk/gtkdialog.h> +#include <gtk/gtkcelllayout.h> +#include <gtk/gtkcellrenderertext.h> +#include <glib/gi18n.h> +#include <libgnomeui/gnome-help.h> #include <gconf/gconf-client.h> #include <glade/glade.h> -#include "cpufreq-applet.h" #include "cpufreq-prefs.h" +#include "cpufreq-utils.h" + +enum { + PROP_0, + PROP_GCONF_KEY, + PROP_CPU, + PROP_SHOW_MODE, + PROP_SHOW_TEXT_MODE, + PROP_SELECTOR_MODE +}; + +struct _CPUFreqPrefsPrivate { + GConfClient *gconf_client; + gchar *gconf_key; + + guint cpu; + CPUFreqShowMode show_mode; + CPUFreqShowTextMode show_text_mode; + CPUFreqSelectorMode selector_mode; + + /* Preferences dialog */ + GtkWidget *dialog; + GtkWidget *show_freq; + GtkWidget *show_unit; + GtkWidget *show_perc; + GtkWidget *cpu_combo; + GtkWidget *monitor_settings_box; + GtkWidget *frequency_selector_box; + GtkWidget *show_mode_combo; + GtkWidget *selector_mode_combo; +}; -static gboolean cpufreq_key_is_writable (CPUFreqApplet *applet, const gchar *key); -static void cpufreq_prefs_response_cb (GtkDialog *dialog, gint response, gpointer gdata); -static void cpufreq_prefs_show_freq_toggled (GtkWidget *show_freq, gpointer *gdata); -static void cpufreq_prefs_show_unit_toggled (GtkWidget *show_unit, gpointer *gdata); -static void cpufreq_prefs_show_perc_toggled (GtkWidget *show_perc, gpointer *gdata); -static void cpufreq_prefs_show_mode_changed (GtkWidget *cpu_number, gpointer *gdata); -static void cpufreq_prefs_selector_mode_changed (GtkWidget *selector_mode, gpointer *gdata); -static void cpufreq_prefs_cpu_number_changed (GtkWidget *show_mode, gpointer *gdata); -static void cpufreq_prefs_cpu_combo_setup (GtkWidget *cpu_number, CPUFreqApplet *applet); -static void cpufreq_prefs_selector_mode_combo_setup (GtkWidget *selector_mode, CPUFreqApplet *applet); -static void cpufreq_prefs_show_mode_combo_setup (GtkWidget *show_mode, CPUFreqApplet *applet); +#define CPUFREQ_PREFS_GET_PRIVATE(object) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((object), CPUFREQ_TYPE_PREFS, CPUFreqPrefsPrivate)) -static gboolean -cpufreq_key_is_writable (CPUFreqApplet *applet, const gchar *key) +static void cpufreq_prefs_init (CPUFreqPrefs *prefs); +static void cpufreq_prefs_class_init (CPUFreqPrefsClass *klass); +static void cpufreq_prefs_finalize (GObject *object); + +static void cpufreq_prefs_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void cpufreq_prefs_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); + +static void cpufreq_prefs_dialog_update_sensitivity (CPUFreqPrefs *prefs); + + +G_DEFINE_TYPE (CPUFreqPrefs, cpufreq_prefs, G_TYPE_OBJECT) + +static void +cpufreq_prefs_init (CPUFreqPrefs *prefs) +{ + prefs->priv = CPUFREQ_PREFS_GET_PRIVATE (prefs); + + prefs->priv->gconf_client = gconf_client_get_default (); + prefs->priv->gconf_key = NULL; + + prefs->priv->cpu = 0; +} + +static void +cpufreq_prefs_class_init (CPUFreqPrefsClass *klass) +{ + GObjectClass *g_object_class = G_OBJECT_CLASS (klass); + + g_object_class->set_property = cpufreq_prefs_set_property; + g_object_class->get_property = cpufreq_prefs_get_property; + + g_type_class_add_private (g_object_class, sizeof (CPUFreqPrefsPrivate)); + + /* Properties */ + g_object_class_install_property (g_object_class, + PROP_GCONF_KEY, + g_param_spec_string ("gconf-key", + "GConfKey", + "The applet gconf key", + NULL, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (g_object_class, + PROP_CPU, + g_param_spec_uint ("cpu", + "CPU", + "The monitored cpu", + 0, + G_MAXUINT, + 0, + G_PARAM_READWRITE)); + g_object_class_install_property (g_object_class, + PROP_SHOW_MODE, + g_param_spec_enum ("show-mode", + "ShowMode", + "The applet show mode", + CPUFREQ_TYPE_SHOW_MODE, + CPUFREQ_MODE_BOTH, + G_PARAM_READWRITE)); + g_object_class_install_property (g_object_class, + PROP_SHOW_TEXT_MODE, + g_param_spec_enum ("show-text-mode", + "ShowTextMode", + "The applet show text mode", + CPUFREQ_TYPE_SHOW_TEXT_MODE, + CPUFREQ_MODE_TEXT_FREQUENCY_UNIT, + G_PARAM_READWRITE)); + g_object_class_install_property (g_object_class, + PROP_SELECTOR_MODE, + g_param_spec_enum ("selector-mode", + "SelectorMode", + "The applet selector mode", + CPUFREQ_TYPE_SELECTOR_MODE, + CPUFREQ_SELECTOR_MODE_FREQUENCIES, + G_PARAM_READWRITE)); + + g_object_class->finalize = cpufreq_prefs_finalize; +} + +static void +cpufreq_prefs_finalize (GObject *object) { - gboolean writable; - gchar *fullkey; - static GConfClient *gconf_client = NULL; + CPUFreqPrefs *prefs = CPUFREQ_PREFS (object); + + if (prefs->priv->gconf_client) { + g_object_unref (prefs->priv->gconf_client); + prefs->priv->gconf_client = NULL; + } - if (gconf_client == NULL) - gconf_client = gconf_client_get_default (); + if (prefs->priv->gconf_key) { + g_free (prefs->priv->gconf_key); + prefs->priv->gconf_key = NULL; + } + + if (prefs->priv->dialog) { + gtk_widget_destroy (prefs->priv->dialog); + prefs->priv->dialog = NULL; + } + + G_OBJECT_CLASS (cpufreq_prefs_parent_class)->finalize (object); +} + +static void +cpufreq_prefs_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + CPUFreqPrefs *prefs = CPUFREQ_PREFS (object); + gboolean update_sensitivity = FALSE; + + switch (prop_id) { + case PROP_GCONF_KEY: + prefs->priv->gconf_key = g_value_dup_string (value); + break; + case PROP_CPU: { + guint cpu; + + cpu = g_value_get_uint (value); + if (prefs->priv->cpu != cpu) { + gchar *key; + + prefs->priv->cpu = cpu; + key = g_strjoin ("/", + prefs->priv->gconf_key, + "cpu", + NULL); + gconf_client_set_int (prefs->priv->gconf_client, + key, prefs->priv->cpu, + NULL); + g_free (key); + } + } + break; + case PROP_SHOW_MODE: { + CPUFreqShowMode mode; + + mode = g_value_get_enum (value); + if (prefs->priv->show_mode != mode) { + gchar *key; + + update_sensitivity = TRUE; + prefs->priv->show_mode = mode; + key = g_strjoin ("/", + prefs->priv->gconf_key, + "show_mode", + NULL); + gconf_client_set_int (prefs->priv->gconf_client, + key, prefs->priv->show_mode, + NULL); + g_free (key); + } + } + break; + case PROP_SHOW_TEXT_MODE: { + CPUFreqShowTextMode mode; + + mode = g_value_get_enum (value); + if (prefs->priv->show_text_mode != mode) { + gchar *key; + + update_sensitivity = TRUE; + prefs->priv->show_text_mode = mode; + key = g_strjoin ("/", + prefs->priv->gconf_key, + "show_text_mode", + NULL); + gconf_client_set_int (prefs->priv->gconf_client, + key, prefs->priv->show_text_mode, + NULL); + g_free (key); + } + } + break; + case PROP_SELECTOR_MODE: { + CPUFreqSelectorMode mode; + + mode = g_value_get_enum (value); + if (prefs->priv->selector_mode != mode) { + gchar *key; + + prefs->priv->selector_mode = mode; + key = g_strjoin ("/", + prefs->priv->gconf_key, + "selector_mode", + NULL); + gconf_client_set_int (prefs->priv->gconf_client, + key, prefs->priv->selector_mode, + NULL); + g_free (key); + } + } + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } - fullkey = panel_applet_gconf_get_full_key (PANEL_APPLET (applet), key); + if (prefs->priv->dialog && update_sensitivity) + cpufreq_prefs_dialog_update_sensitivity (prefs); +} - writable = gconf_client_key_is_writable (gconf_client, fullkey, NULL); +static void +cpufreq_prefs_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + CPUFreqPrefs *prefs = CPUFREQ_PREFS (object); + + switch (prop_id) { + case PROP_GCONF_KEY: + /* Is not readable */ + break; + case PROP_CPU: + g_value_set_uint (value, prefs->priv->cpu); + break; + case PROP_SHOW_MODE: + g_value_set_enum (value, prefs->priv->show_mode); + break; + case PROP_SHOW_TEXT_MODE: + g_value_set_enum (value, prefs->priv->show_text_mode); + break; + case PROP_SELECTOR_MODE: + g_value_set_enum (value, prefs->priv->selector_mode); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} +static void +cpufreq_prefs_setup (CPUFreqPrefs *prefs) +{ + guint cpu; + CPUFreqShowMode show_mode; + CPUFreqShowTextMode show_text_mode; + CPUFreqSelectorMode selector_mode; + gchar *key; + GError *error = NULL; + + g_assert (GCONF_IS_CLIENT (prefs->priv->gconf_client)); + g_assert (prefs->priv->gconf_key != NULL); + + key = g_strjoin ("/", prefs->priv->gconf_key, "cpu", NULL); + cpu = gconf_client_get_int (prefs->priv->gconf_client, + key, &error); + g_free (key); + /* In case anything went wrong with gconf, get back to the default */ + if (error) { + g_warning (error->message); + cpu = 0; + g_error_free (error); + error = NULL; + } + prefs->priv->cpu = cpu; + + key = g_strjoin ("/", prefs->priv->gconf_key, "show_mode", NULL); + show_mode = gconf_client_get_int (prefs->priv->gconf_client, + key, &error); + g_free (key); + /* In case anything went wrong with gconf, get back to the default */ + if (error || + show_mode < CPUFREQ_MODE_GRAPHIC || + show_mode > CPUFREQ_MODE_BOTH) { + show_mode = CPUFREQ_MODE_BOTH; + if (error) { + g_warning (error->message); + g_error_free (error); + error = NULL; + } + } + prefs->priv->show_mode = show_mode; + + key = g_strjoin ("/", prefs->priv->gconf_key, "show_text_mode", NULL); + show_text_mode = gconf_client_get_int (prefs->priv->gconf_client, + key, &error); + g_free (key); + /* In case anything went wrong with gconf, get back to the default */ + if (error || + show_text_mode < CPUFREQ_MODE_TEXT_FREQUENCY || + show_text_mode > CPUFREQ_MODE_TEXT_PERCENTAGE) { + show_text_mode = CPUFREQ_MODE_TEXT_FREQUENCY_UNIT; + if (error) { + g_warning (error->message); + g_error_free (error); + error = NULL; + } + } + prefs->priv->show_text_mode = show_text_mode; + + key = g_strjoin ("/", prefs->priv->gconf_key, "selector_mode", NULL); + selector_mode = gconf_client_get_int (prefs->priv->gconf_client, + key, &error); + g_free (key); + /* In case anything went wrong with gconf, get back to the default */ + if (error || + selector_mode < CPUFREQ_SELECTOR_MODE_FREQUENCIES || + selector_mode > CPUFREQ_SELECTOR_MODE_BOTH) { + selector_mode = CPUFREQ_SELECTOR_MODE_FREQUENCIES; + if (error) { + g_warning (error->message); + g_error_free (error); + error = NULL; + } + } + prefs->priv->selector_mode = selector_mode; +} + +CPUFreqPrefs * +cpufreq_prefs_new (const gchar *gconf_key) +{ + CPUFreqPrefs *prefs; + + g_return_val_if_fail (gconf_key != NULL, NULL); + + prefs = CPUFREQ_PREFS (g_object_new (CPUFREQ_TYPE_PREFS, + "gconf-key", gconf_key, + NULL)); + + cpufreq_prefs_setup (prefs); + + return prefs; +} + +/* Public Methods */ +guint +cpufreq_prefs_get_cpu (CPUFreqPrefs *prefs) +{ + g_return_val_if_fail (CPUFREQ_IS_PREFS (prefs), 0); + + return prefs->priv->cpu; +} + +CPUFreqShowMode +cpufreq_prefs_get_show_mode (CPUFreqPrefs *prefs) +{ + g_return_val_if_fail (CPUFREQ_IS_PREFS (prefs), + CPUFREQ_MODE_BOTH); + + return prefs->priv->show_mode; +} + +CPUFreqShowTextMode +cpufreq_prefs_get_show_text_mode (CPUFreqPrefs *prefs) +{ + g_return_val_if_fail (CPUFREQ_IS_PREFS (prefs), + CPUFREQ_MODE_TEXT_FREQUENCY_UNIT); + + return prefs->priv->show_text_mode; +} + +CPUFreqSelectorMode +cpufreq_prefs_get_selector_mode (CPUFreqPrefs *prefs) +{ + g_return_val_if_fail (CPUFREQ_IS_PREFS (prefs), + CPUFREQ_SELECTOR_MODE_FREQUENCIES); + + return prefs->priv->selector_mode; +} + +/* Preferences Dialog */ +static gboolean +cpufreq_prefs_key_is_writable (CPUFreqPrefs *prefs, const gchar *key) +{ + gboolean writable; + gchar *fullkey; + + g_assert (prefs->priv->gconf_client != NULL); + + fullkey = g_strjoin ("/", prefs->priv->gconf_key, key, NULL); + writable = gconf_client_key_is_writable (prefs->priv->gconf_client, + fullkey, NULL); g_free (fullkey); return writable; } static void -cpufreq_prefs_show_freq_toggled (GtkWidget *show_freq, gpointer *gdata) +cpufreq_prefs_dialog_show_freq_toggled (GtkWidget *show_freq, CPUFreqPrefs *prefs) { - GtkWidget *show_unit; - gboolean key_writable; - gchar *freq, *unit; - CPUFreqApplet *applet; - - applet = (CPUFreqApplet *) gdata; + CPUFreqShowTextMode show_text_mode; - show_unit = g_object_get_data (G_OBJECT (applet->prefs), "prefs-show-unit"); - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (show_freq))) { - /* Show cpu usage in frequency (Hz) */ - key_writable = cpufreq_key_is_writable (applet, "show_text_mode"); - gtk_widget_set_sensitive (show_unit, (TRUE && key_writable)); + GtkWidget *show_unit = prefs->priv->show_unit; if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (show_unit))) - applet->show_text_mode = MODE_TEXT_FREQUENCY_UNIT; + show_text_mode = CPUFREQ_MODE_TEXT_FREQUENCY_UNIT; else - applet->show_text_mode = MODE_TEXT_FREQUENCY; - - freq = cpufreq_monitor_get_frequency (applet->monitor); - - if (freq) { - gtk_label_set_label (GTK_LABEL (applet->label), freq); - - if (applet->show_text_mode == MODE_TEXT_FREQUENCY_UNIT) { - 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); - panel_applet_gconf_set_int (PANEL_APPLET (applet), "show_text_mode", - applet->show_text_mode, NULL); - } else { - gtk_widget_set_sensitive (show_unit, FALSE); - } -} + show_text_mode = CPUFREQ_MODE_TEXT_FREQUENCY; + + g_object_set (G_OBJECT (prefs), + "show-text-mode", show_text_mode, + NULL); + } +} static void -cpufreq_prefs_show_unit_toggled (GtkWidget *show_unit, gpointer *gdata) +cpufreq_prefs_dialog_show_unit_toggled (GtkWidget *show_unit, CPUFreqPrefs *prefs) { - CPUFreqApplet *applet; - gchar *unit; - - applet = (CPUFreqApplet *) gdata; + CPUFreqShowTextMode show_text_mode; if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (show_unit))) { - applet->show_text_mode = MODE_TEXT_FREQUENCY_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); + show_text_mode = CPUFREQ_MODE_TEXT_FREQUENCY_UNIT; } else { - applet->show_text_mode = MODE_TEXT_FREQUENCY; - gtk_widget_hide (applet->unit_label); + show_text_mode = CPUFREQ_MODE_TEXT_FREQUENCY; } - panel_applet_gconf_set_int (PANEL_APPLET (applet), "show_text_mode", - applet->show_text_mode, NULL); + g_object_set (G_OBJECT (prefs), + "show-text-mode", show_text_mode, + NULL); } static void -cpufreq_prefs_show_perc_toggled (GtkWidget *show_perc, gpointer *gdata) +cpufreq_prefs_dialog_show_perc_toggled (GtkWidget *show_perc, CPUFreqPrefs *prefs) { - CPUFreqApplet *applet; - gchar *perc; - - applet = (CPUFreqApplet *) gdata; + CPUFreqShowTextMode show_text_mode; + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (show_perc))) { /* Show cpu usage in percentage */ - applet->show_text_mode = MODE_TEXT_PERCENTAGE; - - 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); - - panel_applet_gconf_set_int (PANEL_APPLET (applet), "show_text_mode", - applet->show_text_mode, NULL); + show_text_mode = CPUFREQ_MODE_TEXT_PERCENTAGE; + + g_object_set (G_OBJECT (prefs), + "show-text-mode", show_text_mode, + NULL); } } static void -cpufreq_prefs_cpu_number_changed (GtkWidget *cpu_number, gpointer *gdata) +cpufreq_prefs_dialog_cpu_number_changed (GtkWidget *cpu_combo, CPUFreqPrefs *prefs) { - CPUFreqApplet *applet; - gint cpu; - - applet = (CPUFreqApplet *) gdata; - - cpu = gtk_combo_box_get_active (GTK_COMBO_BOX (cpu_number)); + gint cpu; + + cpu = gtk_combo_box_get_active (GTK_COMBO_BOX (prefs->priv->cpu_combo)); + if (cpu >= 0) { - cpufreq_monitor_set_cpu (applet->monitor, cpu); - - panel_applet_gconf_set_int (PANEL_APPLET (applet), "cpu", cpu, NULL); + g_object_set (G_OBJECT (prefs), + "cpu", cpu, + NULL); } } static void -cpufreq_prefs_show_mode_changed (GtkWidget *show_mode, gpointer *gdata) +cpufreq_prefs_dialog_show_mode_changed (GtkWidget *show_mode_combo, CPUFreqPrefs *prefs) { - gboolean key_writable; - GtkWidget *show_freq, *show_unit, *show_perc; - CPUFreqApplet *applet; - - applet = (CPUFreqApplet *) gdata; - - show_freq = g_object_get_data (G_OBJECT (applet->prefs), "prefs-show-freq"); - show_unit = g_object_get_data (G_OBJECT (applet->prefs), "prefs-show-unit"); - show_perc = g_object_get_data (G_OBJECT (applet->prefs), "prefs-show-perc"); + CPUFreqShowMode show_mode; - applet->show_mode = gtk_combo_box_get_active (GTK_COMBO_BOX (show_mode)); - - if (applet->show_mode != MODE_GRAPHIC) { - key_writable = cpufreq_key_is_writable (applet, "show_text_mode"); - - if (applet->show_mode == MODE_TEXT) - gtk_widget_hide (applet->pixmap); - else - gtk_widget_show (applet->pixmap); - - gtk_widget_show (applet->label); - - if (applet->show_text_mode == MODE_TEXT_FREQUENCY_UNIT) - gtk_widget_show (applet->unit_label); - else - gtk_widget_hide (applet->unit_label); - - gtk_widget_set_sensitive (show_freq, (TRUE && key_writable)); - - if (applet->show_text_mode == MODE_TEXT_PERCENTAGE) { - gtk_widget_set_sensitive (show_unit, FALSE); - } else { - gtk_widget_set_sensitive (show_unit, (TRUE && key_writable)); - } - - gtk_widget_set_sensitive (show_perc, (TRUE && key_writable)); - } else { - gtk_widget_show (applet->pixmap); - gtk_widget_hide (applet->label); - gtk_widget_hide (applet->unit_label); - - gtk_widget_set_sensitive (show_freq, FALSE); - gtk_widget_set_sensitive (show_unit, FALSE); - gtk_widget_set_sensitive (show_perc, FALSE); - } - - panel_applet_gconf_set_int (PANEL_APPLET (applet), "show_mode", - applet->show_mode, NULL); + show_mode = gtk_combo_box_get_active (GTK_COMBO_BOX (show_mode_combo)); + g_object_set (G_OBJECT (prefs), + "show-mode", show_mode, + NULL); } static void -cpufreq_prefs_selector_mode_changed (GtkWidget *selector_mode, gpointer *gdata) +cpufreq_prefs_dialog_selector_mode_changed (GtkWidget *selector_mode_combo, CPUFreqPrefs *prefs) { - CPUFreqApplet *applet; - - applet = (CPUFreqApplet *) gdata; - - applet->selector_mode = gtk_combo_box_get_active (GTK_COMBO_BOX (selector_mode)); - - if (cpufreq_key_is_writable (applet, "selector_mode") == TRUE) - panel_applet_gconf_set_int (PANEL_APPLET (applet), "selector_mode", - applet->selector_mode, NULL); + CPUFreqSelectorMode selector_mode; + + selector_mode = gtk_combo_box_get_active (GTK_COMBO_BOX (selector_mode_combo)); + g_object_set (G_OBJECT (prefs), + "selector-mode", selector_mode, + NULL); } static void -cpufreq_prefs_response_cb (GtkDialog *dialog, gint response, gpointer gdata) +cpufreq_prefs_dialog_response_cb (CPUFreqPrefs *prefs, + gint response, + GtkDialog *dialog) { - GError *error; - CPUFreqApplet *applet; - - applet = (CPUFreqApplet *) gdata; + GError *error = NULL; if (response == GTK_RESPONSE_HELP) { - error = NULL; gnome_help_display_on_screen ("cpufreq-applet", "cpufreq-applet-prefs", - gtk_widget_get_screen (GTK_WIDGET (applet)), + gtk_widget_get_screen (prefs->priv->dialog), &error); if (error) { - cpufreq_applet_display_error (_("Could not open help document"), - error->message); + cpufreq_utils_display_error (_("Could not open help document"), + error->message); g_error_free (error); - } + } } else { - gtk_widget_destroy (applet->prefs); - applet->prefs = NULL; + gtk_widget_destroy (prefs->priv->dialog); + prefs->priv->dialog = NULL; } } static void -cpufreq_prefs_cpu_combo_setup (GtkWidget *cpu_number, CPUFreqApplet *applet) +cpufreq_prefs_dialog_update_visibility (CPUFreqPrefs *prefs) { - GtkListStore *model; - GtkTreeIter iter; - GtkCellRenderer *renderer; - guint 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), - GTK_TREE_MODEL (model)); + if (cpufreq_utils_get_n_cpus () > 1) + gtk_widget_show (prefs->priv->monitor_settings_box); + else + gtk_widget_hide (prefs->priv->monitor_settings_box); + + if (cpufreq_utils_selector_is_available ()) + gtk_widget_show (prefs->priv->frequency_selector_box); + else + gtk_widget_hide (prefs->priv->frequency_selector_box); +} - for (i=0; i <= applet->mcpu; i++) { - text_label = g_strdup_printf ("CPU %u", i); +static void +cpufreq_prefs_dialog_update_sensitivity (CPUFreqPrefs *prefs) +{ + gtk_widget_set_sensitive (prefs->priv->show_mode_combo, + cpufreq_prefs_key_is_writable (prefs, "show_mode")); + + if (prefs->priv->show_mode != CPUFREQ_MODE_GRAPHIC) { + gboolean key_writable; + + key_writable = cpufreq_prefs_key_is_writable (prefs, "show_text_mode"); + + gtk_widget_set_sensitive (prefs->priv->show_freq, + (TRUE && key_writable)); + gtk_widget_set_sensitive (prefs->priv->show_perc, + (TRUE && key_writable)); + + if (prefs->priv->show_text_mode == CPUFREQ_MODE_TEXT_PERCENTAGE) + gtk_widget_set_sensitive (prefs->priv->show_unit, + FALSE); + else + gtk_widget_set_sensitive (prefs->priv->show_unit, + (TRUE && key_writable)); + } else { + gtk_widget_set_sensitive (prefs->priv->show_freq, FALSE); + gtk_widget_set_sensitive (prefs->priv->show_unit, FALSE); + gtk_widget_set_sensitive (prefs->priv->show_perc, FALSE); + } - gtk_list_store_append (model, &iter); - gtk_list_store_set (model, &iter, - 0, text_label, - -1); + gtk_widget_set_sensitive (prefs->priv->selector_mode_combo, + cpufreq_prefs_key_is_writable (prefs, "selector_mode")); +} - g_free (text_label); - } +static void +cpufreq_prefs_dialog_update (CPUFreqPrefs *prefs) +{ + if (cpufreq_utils_get_n_cpus () > 1) { + gtk_combo_box_set_active (GTK_COMBO_BOX (prefs->priv->cpu_combo), + prefs->priv->cpu); + } - g_object_unref (model); + gtk_combo_box_set_active (GTK_COMBO_BOX (prefs->priv->show_mode_combo), + prefs->priv->show_mode); + + switch (prefs->priv->show_text_mode) { + case CPUFREQ_MODE_TEXT_FREQUENCY: + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (prefs->priv->show_freq), + TRUE); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (prefs->priv->show_unit), + FALSE); + + break; + case CPUFREQ_MODE_TEXT_FREQUENCY_UNIT: + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (prefs->priv->show_freq), + TRUE); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (prefs->priv->show_unit), + TRUE); + + break; + case CPUFREQ_MODE_TEXT_PERCENTAGE: + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (prefs->priv->show_perc), + TRUE); + + break; + } - renderer = gtk_cell_renderer_text_new (); - gtk_cell_layout_clear (GTK_CELL_LAYOUT (cpu_number)); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (cpu_number), renderer, TRUE); - gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (cpu_number), renderer, - "text", 0, NULL); + if (GTK_WIDGET_VISIBLE (prefs->priv->frequency_selector_box)) { + gtk_combo_box_set_active (GTK_COMBO_BOX (prefs->priv->selector_mode_combo), + prefs->priv->selector_mode); + } +} - cpu = cpufreq_monitor_get_cpu (applet->monitor); - - gtk_combo_box_set_active (GTK_COMBO_BOX (cpu_number), cpu); +static void +cpufreq_prefs_dialog_cpu_combo_setup (CPUFreqPrefs *prefs) +{ + GtkListStore *model; + GtkTreeIter iter; + GtkCellRenderer *renderer; + guint i; + guint n_cpus; - gtk_widget_set_sensitive (GTK_WIDGET (cpu_number), - cpufreq_key_is_writable (applet, "cpu")); + model = gtk_list_store_new (1, G_TYPE_STRING); + gtk_combo_box_set_model (GTK_COMBO_BOX (prefs->priv->cpu_combo), + GTK_TREE_MODEL (model)); + + n_cpus = cpufreq_utils_get_n_cpus (); + + for (i = 0; i <n_cpus; i++) { + gchar *text_label; + + text_label = g_strdup_printf ("CPU %u", i); + + gtk_list_store_append (model, &iter); + gtk_list_store_set (model, &iter, + 0, text_label, + -1); + + g_free (text_label); + } + + g_object_unref (model); + + renderer = gtk_cell_renderer_text_new (); + gtk_cell_layout_clear (GTK_CELL_LAYOUT (prefs->priv->cpu_combo)); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (prefs->priv->cpu_combo), + renderer, TRUE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (prefs->priv->cpu_combo), + renderer, + "text", 0, + NULL); } static void -cpufreq_prefs_show_mode_combo_setup (GtkWidget *show_mode, CPUFreqApplet *applet) +cpufreq_prefs_dialog_show_mode_combo_setup (CPUFreqPrefs *prefs) { - GtkListStore *model; - GtkTreeIter iter; - GtkCellRenderer *renderer; - - model = gtk_list_store_new (1, G_TYPE_STRING); - gtk_combo_box_set_model (GTK_COMBO_BOX (show_mode), - GTK_TREE_MODEL (model)); - - gtk_list_store_append (model, &iter); - gtk_list_store_set (model, &iter, - 0, _("Graphic"), - -1); - - gtk_list_store_append (model, &iter); - gtk_list_store_set (model, &iter, - 0, _("Text"), - -1); - - gtk_list_store_append (model, &iter); - gtk_list_store_set (model, &iter, - 0, _("Graphic and Text"), - -1); - - g_object_unref (model); + GtkListStore *model; + GtkTreeIter iter; + GtkCellRenderer *renderer; + + model = gtk_list_store_new (1, G_TYPE_STRING); + gtk_combo_box_set_model (GTK_COMBO_BOX (prefs->priv->show_mode_combo), + GTK_TREE_MODEL (model)); + + gtk_list_store_append (model, &iter); + gtk_list_store_set (model, &iter, + 0, _("Graphic"), + -1); + + gtk_list_store_append (model, &iter); + gtk_list_store_set (model, &iter, + 0, _("Text"), + -1); - renderer = gtk_cell_renderer_text_new (); - gtk_cell_layout_clear (GTK_CELL_LAYOUT (show_mode)); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (show_mode), renderer, TRUE); - gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (show_mode), renderer, - "text", 0, NULL); + gtk_list_store_append (model, &iter); + gtk_list_store_set (model, &iter, + 0, _("Graphic and Text"), + -1); - gtk_combo_box_set_active (GTK_COMBO_BOX (show_mode), applet->show_mode); + g_object_unref (model); - gtk_widget_set_sensitive (GTK_WIDGET (show_mode), - cpufreq_key_is_writable (applet, "show_mode")); + renderer = gtk_cell_renderer_text_new (); + gtk_cell_layout_clear (GTK_CELL_LAYOUT (prefs->priv->show_mode_combo)); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (prefs->priv->show_mode_combo), + renderer, TRUE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (prefs->priv->show_mode_combo), + renderer, + "text", 0, + NULL); } static void -cpufreq_prefs_selector_mode_combo_setup (GtkWidget *selector_mode, CPUFreqApplet *applet) +cpufreq_prefs_dialog_selector_mode_combo_setup (CPUFreqPrefs *prefs) { GtkListStore *model; GtkTreeIter iter; GtkCellRenderer *renderer; model = gtk_list_store_new (1, G_TYPE_STRING); - gtk_combo_box_set_model (GTK_COMBO_BOX (selector_mode), + gtk_combo_box_set_model (GTK_COMBO_BOX (prefs->priv->selector_mode_combo), GTK_TREE_MODEL (model)); gtk_list_store_append (model, &iter); @@ -382,135 +753,91 @@ cpufreq_prefs_selector_mode_combo_setup (GtkWidget *selector_mode, CPUFreqApplet g_object_unref (model); renderer = gtk_cell_renderer_text_new (); - gtk_cell_layout_clear (GTK_CELL_LAYOUT (selector_mode)); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (selector_mode), renderer, TRUE); - gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (selector_mode), renderer, - "text", 0, NULL); + gtk_cell_layout_clear (GTK_CELL_LAYOUT (prefs->priv->selector_mode_combo)); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (prefs->priv->selector_mode_combo), + renderer, TRUE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (prefs->priv->selector_mode_combo), + renderer, + "text", 0, + NULL); +} - gtk_combo_box_set_active (GTK_COMBO_BOX (selector_mode), applet->selector_mode); +static void +cpufreq_prefs_dialog_create (CPUFreqPrefs *prefs) +{ + GladeXML *xml = NULL; + gchar *glade_file; + + glade_file = g_build_filename (GNOME_GLADEDIR, + "cpufreq-preferences.glade", + NULL); + xml = glade_xml_new (glade_file, "prefs_dialog", NULL); + g_free (glade_file); + + prefs->priv->dialog = glade_xml_get_widget (xml, "prefs_dialog"); - gtk_widget_set_sensitive (GTK_WIDGET (selector_mode), - cpufreq_key_is_writable (applet, "selector_mode")); + prefs->priv->cpu_combo = glade_xml_get_widget (xml, "prefs_cpu_number"); + + prefs->priv->show_mode_combo = glade_xml_get_widget (xml, "prefs_show_mode"); + + prefs->priv->show_freq = glade_xml_get_widget (xml, "prefs_show_freq"); + prefs->priv->show_unit = glade_xml_get_widget (xml, "prefs_show_unit"); + prefs->priv->show_perc = glade_xml_get_widget (xml, "prefs_show_perc"); + + prefs->priv->selector_mode_combo = glade_xml_get_widget (xml, "prefs_selector_mode"); + + prefs->priv->monitor_settings_box = glade_xml_get_widget (xml, "monitor_settings_box"); + prefs->priv->frequency_selector_box = glade_xml_get_widget (xml, "frequency_selector_box"); + + g_object_unref (xml); + + cpufreq_prefs_dialog_show_mode_combo_setup (prefs); + cpufreq_prefs_dialog_selector_mode_combo_setup (prefs); + + if (cpufreq_utils_get_n_cpus () > 1) + cpufreq_prefs_dialog_cpu_combo_setup (prefs); + + g_signal_connect_swapped (G_OBJECT (prefs->priv->dialog), "response", + G_CALLBACK (cpufreq_prefs_dialog_response_cb), + (gpointer) prefs); + + g_signal_connect (G_OBJECT (prefs->priv->show_freq), "toggled", + G_CALLBACK (cpufreq_prefs_dialog_show_freq_toggled), + (gpointer) prefs); + g_signal_connect (G_OBJECT (prefs->priv->show_unit), "toggled", + G_CALLBACK (cpufreq_prefs_dialog_show_unit_toggled), + (gpointer) prefs); + g_signal_connect (G_OBJECT (prefs->priv->show_perc), "toggled", + G_CALLBACK (cpufreq_prefs_dialog_show_perc_toggled), + (gpointer) prefs); + g_signal_connect (G_OBJECT (prefs->priv->cpu_combo), "changed", + G_CALLBACK (cpufreq_prefs_dialog_cpu_number_changed), + (gpointer) prefs); + g_signal_connect (G_OBJECT (prefs->priv->show_mode_combo), "changed", + G_CALLBACK (cpufreq_prefs_dialog_show_mode_changed), + (gpointer) prefs); + g_signal_connect (G_OBJECT (prefs->priv->selector_mode_combo), "changed", + G_CALLBACK (cpufreq_prefs_dialog_selector_mode_changed), + (gpointer) prefs); } void -cpufreq_preferences_dialog_run (CPUFreqApplet *applet) +cpufreq_preferences_dialog_run (CPUFreqPrefs *prefs, GdkScreen *screen) { - GladeXML *xml; - GtkWidget *show_freq, *show_unit, *show_perc; - GtkWidget *cpu_number; - GtkWidget *monitor_settings_box; - GtkWidget *frequency_selector_box; - GtkWidget *show_mode, *selector_mode; - gboolean key_writable; + g_return_if_fail (CPUFREQ_IS_PREFS (prefs)); - g_return_if_fail (PANEL_IS_APPLET (PANEL_APPLET (applet))); - - if (applet->prefs) { /* the dialog already exist, only show it */ - gtk_window_present (GTK_WINDOW (applet->prefs)); + if (prefs->priv->dialog) { + /* Dialog already exist, only show it */ + gtk_window_present (GTK_WINDOW (prefs->priv->dialog)); return; } - - xml = glade_xml_new (GNOME_GLADEDIR"/cpufreq-preferences.glade", - "prefs_dialog", NULL); - - applet->prefs = glade_xml_get_widget (xml, "prefs_dialog"); - show_mode = glade_xml_get_widget (xml, "prefs_show_mode"); - show_freq = glade_xml_get_widget (xml, "prefs_show_freq"); - show_unit = glade_xml_get_widget (xml, "prefs_show_unit"); - show_perc = glade_xml_get_widget (xml, "prefs_show_perc"); - selector_mode = glade_xml_get_widget (xml, "prefs_selector_mode"); - cpu_number = glade_xml_get_widget (xml, "prefs_cpu_number"); - monitor_settings_box = glade_xml_get_widget (xml, "monitor_settings_box"); - frequency_selector_box = glade_xml_get_widget (xml, "frequency_selector_box"); - - g_object_unref (G_OBJECT (xml)); - - gtk_window_set_screen (GTK_WINDOW (applet->prefs), - gtk_widget_get_screen (GTK_WIDGET (applet))); - - switch (applet->show_text_mode) { - case MODE_TEXT_FREQUENCY: - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (show_freq), TRUE); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (show_unit), FALSE); - - break; - case MODE_TEXT_FREQUENCY_UNIT: - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (show_freq), TRUE); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (show_unit), TRUE); - - break; - case MODE_TEXT_PERCENTAGE: - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (show_perc), TRUE); - - break; - } - if (applet->show_mode != MODE_GRAPHIC) { - key_writable = cpufreq_key_is_writable (applet, "show_text_mode"); - - gtk_widget_set_sensitive (show_freq, (TRUE && key_writable)); - gtk_widget_set_sensitive (show_perc, (TRUE && key_writable)); - - if (applet->show_text_mode == MODE_TEXT_PERCENTAGE) - gtk_widget_set_sensitive (show_unit, FALSE); - else - gtk_widget_set_sensitive (show_unit, (TRUE && key_writable)); - } else { - gtk_widget_set_sensitive (show_freq, FALSE); - gtk_widget_set_sensitive (show_unit, FALSE); - gtk_widget_set_sensitive (show_perc, FALSE); - } + cpufreq_prefs_dialog_create (prefs); + gtk_window_set_screen (GTK_WINDOW (prefs->priv->dialog), screen); - /* Fill the cpu combo */ - - if (applet->mcpu > 0) { - cpufreq_prefs_cpu_combo_setup (cpu_number, applet); - gtk_widget_show (cpu_number); - gtk_widget_show (monitor_settings_box); - } else { - gtk_widget_hide (monitor_settings_box); - } + cpufreq_prefs_dialog_update_sensitivity (prefs); + cpufreq_prefs_dialog_update_visibility (prefs); + cpufreq_prefs_dialog_update (prefs); - cpufreq_prefs_show_mode_combo_setup (show_mode, applet); - gtk_widget_show (show_mode); - - g_object_set_data (G_OBJECT (applet->prefs), "prefs-show-freq", show_freq); - g_object_set_data (G_OBJECT (applet->prefs), "prefs-show-unit", show_unit); - g_object_set_data (G_OBJECT (applet->prefs), "prefs-show-perc", show_perc); - - if (cpufreq_applet_selector_is_available ()) { - cpufreq_prefs_selector_mode_combo_setup (selector_mode, applet); - gtk_widget_show (selector_mode); - gtk_widget_show (frequency_selector_box); - } else { - gtk_widget_hide (frequency_selector_box); - } - - g_signal_connect (G_OBJECT (applet->prefs), "response", - G_CALLBACK (cpufreq_prefs_response_cb), - (gpointer) applet); - g_signal_connect (G_OBJECT (applet->prefs), "destroy", - G_CALLBACK (gtk_widget_destroy), - NULL); - g_signal_connect (G_OBJECT (show_freq), "toggled", - G_CALLBACK (cpufreq_prefs_show_freq_toggled), - (gpointer) applet); - g_signal_connect (G_OBJECT (show_unit), "toggled", - G_CALLBACK (cpufreq_prefs_show_unit_toggled), - (gpointer) applet); - g_signal_connect (G_OBJECT (show_perc), "toggled", - G_CALLBACK (cpufreq_prefs_show_perc_toggled), - (gpointer) applet); - g_signal_connect (G_OBJECT (cpu_number), "changed", - G_CALLBACK (cpufreq_prefs_cpu_number_changed), - (gpointer) applet); - g_signal_connect (G_OBJECT (show_mode), "changed", - G_CALLBACK (cpufreq_prefs_show_mode_changed), - (gpointer) applet); - g_signal_connect (G_OBJECT (selector_mode), "changed", - G_CALLBACK (cpufreq_prefs_selector_mode_changed), - (gpointer) applet); - - gtk_widget_show (applet->prefs); + gtk_widget_show (prefs->priv->dialog); } diff --git a/cpufreq/src/cpufreq-prefs.h b/cpufreq/src/cpufreq-prefs.h index e98aac7e3..fa8dc84d0 100644 --- a/cpufreq/src/cpufreq-prefs.h +++ b/cpufreq/src/cpufreq-prefs.h @@ -19,7 +19,49 @@ * Authors : Carlos García Campos <carlosgc@gnome.org> */ +#ifndef CPUFREQ_PREFS_H +#define CPUFREQ_PREFS_H + +#include <gdk/gdkscreen.h> +#include <glib-object.h> #include "cpufreq-applet.h" -#include <panel-applet.h> -void cpufreq_preferences_dialog_run (CPUFreqApplet *applet); +G_BEGIN_DECLS + +#define CPUFREQ_TYPE_PREFS (cpufreq_prefs_get_type ()) +#define CPUFREQ_PREFS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CPUFREQ_TYPE_PREFS, CPUFreqPrefs)) +#define CPUFREQ_PREFS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), CPUFREQ_TYPE_PREFS, CPUFreqPrefsClass)) +#define CPUFREQ_IS_PREFS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CPUFREQ_TYPE_PREFS)) +#define CPUFREQ_IS_PREFS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CPUFREQ_TYPE_PREFS)) +#define CPUFREQ_PREFS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CPUFREQ_TYPE_PREFS, CPUFreqPrefsClass)) + +typedef struct _CPUFreqPrefs CPUFreqPrefs; +typedef struct _CPUFreqPrefsClass CPUFreqPrefsClass; +typedef struct _CPUFreqPrefsPrivate CPUFreqPrefsPrivate; + +struct _CPUFreqPrefs { + GObject base; + + CPUFreqPrefsPrivate *priv; +}; + +struct _CPUFreqPrefsClass { + GObjectClass parent_class; +}; + +GType cpufreq_prefs_get_type (void) G_GNUC_CONST; + +CPUFreqPrefs *cpufreq_prefs_new (const gchar *gconf_key); + +guint cpufreq_prefs_get_cpu (CPUFreqPrefs *prefs); +CPUFreqShowMode cpufreq_prefs_get_show_mode (CPUFreqPrefs *prefs); +CPUFreqShowTextMode cpufreq_prefs_get_show_text_mode (CPUFreqPrefs *prefs); +CPUFreqSelectorMode cpufreq_prefs_get_selector_mode (CPUFreqPrefs *prefs); + +/* Properties dialog */ +void cpufreq_preferences_dialog_run (CPUFreqPrefs *prefs, + GdkScreen *screen); + +G_END_DECLS + +#endif /* CPUFREQ_PREFS_H */ diff --git a/cpufreq/src/cpufreq-utils.c b/cpufreq/src/cpufreq-utils.c new file mode 100644 index 000000000..bb8dcf32e --- /dev/null +++ b/cpufreq/src/cpufreq-utils.c @@ -0,0 +1,162 @@ +/* + * GNOME CPUFreq Applet + * Copyright (C) 2006 Carlos Garcia Campos <carlosgc@gnome.org> + * + * 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 <gtk/gtkmessagedialog.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +#include "cpufreq-utils.h" + +guint +cpufreq_utils_get_n_cpus (void) +{ + gint mcpu = -1; + gchar *file = NULL; + static guint n_cpus = 0; + + if (n_cpus > 0) + return n_cpus; + + do { + if (file) + g_free (file); + mcpu ++; + file = g_strdup_printf ("/sys/devices/system/cpu/cpu%d", mcpu); + } while (g_file_test (file, G_FILE_TEST_EXISTS)); + g_free (file); + + if (mcpu >= 0) { + n_cpus = (guint)mcpu; + return mcpu; + } + + mcpu = -1; + file = NULL; + do { + if (file) + g_free (file); + mcpu ++; + file = g_strdup_printf ("/proc/sys/cpu/%d", mcpu); + } while (g_file_test (file, G_FILE_TEST_EXISTS)); + g_free (file); + + if (mcpu >= 0) { + n_cpus = (guint)mcpu; + return mcpu; + } + + n_cpus = 1; + + return 1; +} + +void +cpufreq_utils_display_error (const gchar *message, + const gchar *secondary) +{ + GtkWidget *dialog; + + g_return_if_fail (message != NULL); + + dialog = gtk_message_dialog_new (NULL, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + message); + if (secondary) { + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), + secondary); + } + + gtk_window_set_title (GTK_WINDOW (dialog), ""); /* as per HIG */ + gtk_window_set_skip_taskbar_hint (GTK_WINDOW (dialog), TRUE); + g_signal_connect (G_OBJECT (dialog), + "response", + G_CALLBACK (gtk_widget_destroy), NULL); + gtk_widget_show (dialog); +} + +gboolean +cpufreq_utils_selector_is_available (void) +{ + struct stat *info; + gchar *path = NULL; + + path = g_find_program_in_path ("cpufreq-selector"); + if (!path) + return FALSE; + + if (geteuid () == 0) + return TRUE; + + info = (struct stat *) g_malloc (sizeof (struct stat)); + + if ((lstat (path, info)) != -1) { + if ((info->st_mode & S_ISUID) && (info->st_uid == 0)) { + g_free (info); + g_free (path); + + return TRUE; + } + } + + g_free (info); + g_free (path); + + return FALSE; +} + +gchar * +cpufreq_utils_get_frequency_label (guint 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_utils_get_frequency_unit (guint freq) +{ + if (freq > 999999) /* freq (kHz) */ + return g_strdup ("GHz"); + else + return g_strdup ("MHz"); +} + +gboolean +cpufreq_utils_governor_is_automatic (const gchar *governor) +{ + g_return_val_if_fail (governor != NULL, FALSE); + + if (g_ascii_strcasecmp (governor, "userspace") == 0) + return FALSE; + + return TRUE; +} diff --git a/cpufreq/src/cpufreq-monitor-protected.h b/cpufreq/src/cpufreq-utils.h index aa5f0b0f1..4d2f7858a 100644 --- a/cpufreq/src/cpufreq-monitor-protected.h +++ b/cpufreq/src/cpufreq-utils.h @@ -1,6 +1,6 @@ /* * GNOME CPUFreq Applet - * Copyright (C) 2004 Carlos Garcia Campos <carlosgc@gnome.org> + * Copyright (C) 2006 Carlos Garcia Campos <carlosgc@gnome.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public @@ -19,14 +19,22 @@ * Authors : Carlos García Campos <carlosgc@gnome.org> */ -struct _CPUFreqMonitorProtected -{ - guint cpu; - gchar *freq; - gchar *perc; - gchar *unit; - gchar *governor; - GList *available_freqs; - GList *available_govs; - guint timeout_handler; -}; +#ifndef CPUFREQ_UTILS_H +#define CPUFREQ_UTILS_H + +#include <glib.h> + +G_BEGIN_DECLS + +/* Useful global methods */ +guint cpufreq_utils_get_n_cpus (void); +void cpufreq_utils_display_error (const gchar *message, + const gchar *secondary); +gboolean cpufreq_utils_selector_is_available (void); +gchar *cpufreq_utils_get_frequency_label (guint freq); +gchar *cpufreq_utils_get_frequency_unit (guint freq); +gboolean cpufreq_utils_governor_is_automatic (const gchar *governor); + +G_END_DECLS + +#endif /* CPUFREQ_UTILS_H */ |