cpufreq plugin, thermal plugin fix
authorDaniel Kesler <infinity_one@users.sourceforge.net>
Thu, 1 Oct 2009 10:20:13 +0000 (10:20 +0000)
committerDaniel Kesler <infinity_one@users.sourceforge.net>
Thu, 1 Oct 2009 10:20:13 +0000 (10:20 +0000)
configure.ac
data/images/cpufreq-icon.png [new file with mode: 0644]
src/plugins/Makefile.am
src/plugins/cpufreq/Makefile.am [new file with mode: 0644]
src/plugins/cpufreq/cpufreq.c [new file with mode: 0644]
src/plugins/thermal/thermal.c

index 0c8944a..a35c600 100644 (file)
@@ -155,6 +155,7 @@ plugin_batt=
 plugin_xkb=
 plugin_kbled=
 plugin_thermal=
+plugin_cpufreq=
 
 AC_MSG_CHECKING([which plugins should be built dynamically])
 AC_ARG_WITH(plugins,
@@ -162,7 +163,7 @@ AC_ARG_WITH(plugins,
 [                         plugins may be comma separated ]
 [                         'all' builds all plugins (default), 'none' builds none ]
 [                         Possible plugins are: ]
-[                         netstatus, volume, volumealsa, cpu, deskno, batt, kbled, xkb, thermal], plugins="$withval",[plugins="all"])
+[                         netstatus, volume, volumealsa, cpu, deskno, batt, kbled, xkb, thermal, cpufreq], plugins="$withval",[plugins="all"])
 
 if test x"$plugins" != xall -a x"$plugins" != xnone; then
     if test x"$plugins_loading" = xno; then
@@ -189,6 +190,7 @@ dnl    done
     plugin_kbled=kbled
     plugin_xkb=xkb
     plugin_thermal=thermal
+    plugin_cpufreq=cpufreq
 
     AC_MSG_RESULT(all)
 else
@@ -224,6 +226,9 @@ else
             thermal)
                 plugin_thermal=thermal
                 ;;
+            cpufreq)
+                plugin_cpufreq=cpufreq
+                ;;
             *)
                 echo "Unknown plugin $plugin."
                 exit 1
@@ -253,7 +258,8 @@ PLUGINS_LIST="\
     $plugin_batt \
     $plugin_kbled \
     $plugin_xkb \
-    $plugin_thermal"
+    $plugin_thermal \
+    $plugin_cpufreq"
 
 AC_SUBST(PLUGINS_LIST)
 
@@ -316,6 +322,7 @@ AC_CONFIG_FILES([
     src/plugins/kbled/Makefile
     src/plugins/xkb/Makefile
     src/plugins/thermal/Makefile
+    src/plugins/cpufreq/Makefile
     po/Makefile.in
     data/Makefile
     data/default/panels/panel
@@ -356,6 +363,9 @@ echo Building dynamic plugins:
     if test x"$plugin_thermal" != x; then
         AC_MSG_RESULT([    thermal - Temperature monitor])
     fi
+    if test x"$plugin_cpufreq" != x; then
+        AC_MSG_RESULT([    cpufreq - CpuFreq frontend])
+    fi
 else
 echo Dynamic loader for plugins....... : disabled.
 fi
diff --git a/data/images/cpufreq-icon.png b/data/images/cpufreq-icon.png
new file mode 100644 (file)
index 0000000..3e7a343
Binary files /dev/null and b/data/images/cpufreq-icon.png differ
index b34cadc..f6d3c27 100644 (file)
@@ -35,7 +35,7 @@ PLUGINS_SOURCES = \
        separator.c \
        pager.c \
        space.c \
-    tray.c \
+       tray.c \
        wincmd.c \
        dirmenu.c
 
diff --git a/src/plugins/cpufreq/Makefile.am b/src/plugins/cpufreq/Makefile.am
new file mode 100644 (file)
index 0000000..eb71fc5
--- /dev/null
@@ -0,0 +1,20 @@
+INCLUDES = \
+       -I. \
+       -I$(top_srcdir)/src \
+       $(PACKAGE_CFLAGS) \
+       -DPACKAGE_DATA_DIR=\""$(datadir)"\" \
+       $(G_CAST_CHECKS)
+
+module_LTLIBRARIES = cpufreq.la
+
+moduledir = $(libdir)/lxpanel/plugins
+
+cpufreq_la_SOURCES = \
+       cpufreq.c
+
+cpufreq_la_LIBADD = \
+       $(PACKAGE_LIBS)
+
+cpufreq_la_LDFLAGS = \
+       -module \
+       @LXPANEL_MODULE@
diff --git a/src/plugins/cpufreq/cpufreq.c b/src/plugins/cpufreq/cpufreq.c
new file mode 100644 (file)
index 0000000..c421e4e
--- /dev/null
@@ -0,0 +1,446 @@
+/**
+ * CPUFreq plugin to lxpanel
+ *
+ * Copyright (C) 2009 by Daniel Kesler <kesler.daniel@gmail.com>
+ *
+ * This program 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 program 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 program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <glib/gi18n.h>
+
+#include <string.h>
+
+#include "panel.h"
+#include "misc.h"
+#include "plugin.h"
+
+#include "dbg.h"
+
+#define PROC_ICON            PACKAGE_DATA_DIR "/lxpanel/images/cpufreq-icon.png"
+#define SYSFS_CPU_DIRECTORY "/sys/devices/system/cpu/"
+#define SCALING_GOV         "scaling_governor"
+#define SCALING_AGOV        "scaling_available_governors"
+#define SCALING_AFREQ       "scaling_available_frequencies"
+#define CPUINFO_CUR_FREQ    "cpuinfo_cur_freq"
+#define SCALING_SETFREQ     "scaling_setspeed"
+#define SCALING_MAX         "scaling_max_freq"
+#define SCALING_MIN         "scaling_min_freq"
+
+
+typedef struct {
+    GtkWidget *main;
+    GtkWidget *namew;
+    GtkTooltips *tip;
+    GList *governors;
+    GList *cpus;
+    int has_cpufreq;
+    char* cur_governor;
+    int   cur_freq;
+    unsigned int timer;
+    gboolean remember;
+} cpufreq;
+
+typedef struct {
+    void *data;
+    cpufreq *cf;
+} Param;
+
+static void
+get_cur_governor(cpufreq *cf){
+    FILE *fp;
+    char buf[ 100 ], sstmp [ 256 ];
+
+    sprintf(sstmp,"%s%s",cf->cpus->data, SCALING_GOV);
+    if ((fp = fopen( sstmp, "r")) != NULL) {
+        fgets(buf, 100, fp);
+        buf[strlen(buf)-1] = '\0';
+        if(cf->cur_governor)
+        {
+          g_free(cf->cur_governor);
+          cf->cur_governor = NULL;
+        }
+        cf->cur_governor = strdup(buf);
+        fclose(fp);
+    }
+}
+
+static void
+get_cur_freq(cpufreq *cf){
+    FILE *fp;
+    char buf[ 100 ], sstmp [ 256 ];
+
+    sprintf(sstmp,"%s%s",cf->cpus->data, CPUINFO_CUR_FREQ);
+    if ((fp = fopen( sstmp, "r")) != NULL) {
+        fgets(buf, 100, fp);
+        buf[strlen(buf)-1] = '\0';
+        cf->cur_freq = atoi(buf);
+        fclose(fp);
+    }
+}
+
+static void
+get_governors(cpufreq *cf){
+    FILE *fp;
+    GList *l;
+    char buf[ 100 ], sstmp [ 256 ], c, bufl = 0;
+
+    g_list_free(cf->governors);
+    cf->governors = NULL;
+
+    get_cur_governor(cf);
+
+    if(cf->cpus == NULL){
+        cf->governors = NULL;
+        return;
+    }
+    sprintf(sstmp,"%s%s",cf->cpus->data, SCALING_AGOV);
+
+    if (!(fp = fopen( sstmp, "r"))) {
+        printf("cpufreq: cannot open %s\n",sstmp);
+        return;
+    }
+
+    while((c = fgetc(fp)) != EOF){
+        if(c == ' '){
+            if(bufl > 1){
+                buf[bufl] = '\0';
+                cf->governors = g_list_append(cf->governors, strdup(buf));
+            }
+            bufl = 0;
+            buf[0] = '\0';
+        }else{
+            buf[bufl++] = c;
+        }
+    }
+
+    fclose(fp);
+}
+
+static void
+cpufreq_set_freq(GtkWidget *widget, Param* p){
+    FILE *fp;
+    char buf[ 100 ], sstmp [ 256 ];
+
+    if(strcmp(p->cf->cur_governor, "userspace")) return;
+
+    sprintf(sstmp,"%s%s",p->cf->cpus->data, SCALING_SETFREQ);
+    if ((fp = fopen( sstmp, "w")) != NULL) {
+        fprintf(fp,"%s",p->data);
+        fclose(fp);
+    }
+}
+
+static GtkWidget *
+frequency_menu(cpufreq *cf){
+    FILE *fp;
+    Param* param;
+    char buf[ 100 ], sstmp [ 256 ], c, bufl = 0;
+
+    sprintf(sstmp,"%s%s",cf->cpus->data, SCALING_AFREQ);
+
+    if (!(fp = fopen( sstmp, "r"))) {
+        printf("cpufreq: cannot open %s\n",sstmp);
+        return;
+    }
+
+    GtkMenu* menu = GTK_MENU(gtk_menu_new());
+    GtkWidget* menuitem;
+
+    while((c = fgetc(fp)) != EOF){
+        if(c == ' '){
+            if(bufl > 1){
+                buf[bufl] = '\0';
+                menuitem = GTK_MENU_ITEM(gtk_menu_item_new_with_label(strdup(buf)));
+                gtk_menu_append (GTK_MENU_SHELL (menu), menuitem);
+                gtk_widget_show (menuitem);
+                param = g_new0(Param, 1);
+                param->data = strdup(buf);
+                param->cf = cf;
+                g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(cpufreq_set_freq), param);
+                g_object_weak_ref(menuitem, g_free, param);
+            }
+            bufl = 0;
+            buf[0] = '\0';
+        }else{
+            buf[bufl++] = c;
+        }
+    }
+
+    fclose(fp);
+    return menu;
+}
+
+static void
+get_cpus(cpufreq *cf){
+    GDir *cpuDirectory;
+    GDir *cpufreqDir;
+    const char *cpu;
+    char cpu_path[100];
+
+    if (! (cpuDirectory = g_dir_open(SYSFS_CPU_DIRECTORY, 0, NULL)))
+    {
+        cf->cpus = NULL;
+        printf("cpufreq: no cpu found\n");
+        return;
+    }
+
+    while ((cpu = g_dir_read_name(cpuDirectory))) {
+        if ((cpu[0] != '.') && (cpu[0] == 'c')) {
+            sprintf(cpu_path,"%s%s/",SYSFS_CPU_DIRECTORY, cpu);
+            sprintf(cpu_path,"%s%s",cpu_path, "cpufreq/");
+
+            if (! (cpufreqDir = g_dir_open(SYSFS_CPU_DIRECTORY, 0, NULL)))
+            {
+                cf->cpus = NULL;
+                cf->has_cpufreq = 0;
+                return;
+            }else{
+                cf->has_cpufreq = 1;
+                cf->cpus = g_list_append(cf->cpus, strdup(cpu_path));
+            }
+        }
+    }
+    g_dir_close(cpuDirectory);
+}
+
+static void
+cpufreq_set_governor(GtkWidget *widget, Param* p){
+    FILE *fp;
+    char buf[ 100 ], sstmp [ 256 ];
+
+    sprintf(sstmp,"%s%s",p->cf->cpus->data, SCALING_GOV);
+    if ((fp = fopen( sstmp, "w")) != NULL) {
+        fprintf(fp,"%s",p->data);
+        fclose(fp);
+    }
+}
+
+static GtkWidget *
+cpufreq_menu(cpufreq *cf){
+    GList *l;
+    GSList *group;
+    char buff[100];
+    GtkMenuItem* menuitem;
+    Param* param;
+
+    GtkMenu* menu = GTK_MENU(gtk_menu_new());
+        g_signal_connect(menu, "selection-done", gtk_widget_destroy, NULL);
+
+    get_governors(cf);
+    group = NULL;
+
+    if((cf->governors == NULL) || (!cf->has_cpufreq)){
+        menuitem = GTK_MENU_ITEM(gtk_menu_item_new_with_label("CPUFreq not supported"));
+        gtk_menu_append (GTK_MENU_SHELL (menu), menuitem);
+        gtk_widget_show (menuitem);
+        return menu;
+    }
+
+    if(strcmp(cf->cur_governor, "userspace") == 0){
+        menuitem = GTK_MENU_ITEM(gtk_menu_item_new_with_label("  Frequency"));
+        gtk_menu_append (GTK_MENU_SHELL (menu), menuitem);
+        gtk_widget_show (menuitem);
+        gtk_menu_item_set_submenu(menuitem, frequency_menu(cf));
+        menuitem = GTK_MENU_ITEM(gtk_separator_menu_item_new());
+        gtk_menu_append (GTK_MENU_SHELL (menu), menuitem);
+        gtk_widget_show (GTK_WIDGET(menuitem));
+    }
+
+    for( l = cf->governors; l; l = l->next )
+    {
+      if(strcmp((char*)l->data, cf->cur_governor) == 0){
+        sprintf(buff,"> %s", l->data);
+        menuitem = GTK_MENU_ITEM(gtk_menu_item_new_with_label(strdup(buff)));
+      }else{
+        sprintf(buff,"   %s", l->data);
+        menuitem = GTK_MENU_ITEM(gtk_menu_item_new_with_label(strdup(buff)));
+      }
+
+      gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+      gtk_widget_show (menuitem);
+      param = g_new0(Param, 1);
+      param->data = l->data;
+      param->cf = cf;
+      g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(cpufreq_set_governor), param);
+      g_object_weak_ref(menuitem, g_free, param);
+    }
+
+    return menu;
+}
+
+
+
+static  gboolean
+clicked( GtkWidget *widget, GdkEventButton* evt, Plugin* plugin)
+{
+    ENTER2;
+    if( evt->button == 1 )
+    {
+      gtk_menu_popup( cpufreq_menu((cpufreq*)plugin->priv), NULL, NULL, NULL, NULL, 
+                      evt->button, evt->time );
+      return TRUE;
+    }else if ( evt->button == 3 )
+    {
+        GtkMenu* popup = lxpanel_get_panel_menu( plugin->panel, plugin, FALSE );
+        gtk_menu_popup( popup, NULL, NULL, NULL, NULL, evt->button, evt->time );
+        return TRUE;
+      return TRUE;
+    }
+
+    RET2(TRUE);
+}
+
+static gint
+update_tooltip(cpufreq *cf)
+{
+    char *tooltip;
+
+    get_cur_freq(cf);
+    get_cur_governor(cf);
+
+    ENTER;
+
+    tooltip = g_strdup_printf("Frequency: %d MHz\n  Governor: %s", 
+                              cf->cur_freq / 1000, cf->cur_governor);
+    gtk_tooltips_set_tip(cf->tip, cf->main, tooltip, NULL);
+    g_free(tooltip);
+    RET(TRUE);
+}
+
+static int
+cpufreq_constructor(Plugin *p, char** fp)
+{
+    cpufreq *cf;
+    GtkWidget *button;
+
+    ENTER;
+    cf = g_new0(cpufreq, 1);
+    cf->governors = NULL;
+    cf->cpus = NULL;
+    g_return_val_if_fail(cf != NULL, 0);
+    p->priv = cf;
+
+    p->pwid = gtk_event_box_new();
+    GTK_WIDGET_SET_FLAGS( p->pwid, GTK_NO_WINDOW );
+    gtk_container_set_border_width( GTK_CONTAINER(p->pwid), 2 );
+
+    cf->namew = gtk_image_new_from_file(PROC_ICON);
+    gtk_container_add(GTK_CONTAINER(p->pwid), cf->namew);
+
+    cf->main = p->pwid;
+    cf->tip = gtk_tooltips_new();
+
+#if GLIB_CHECK_VERSION( 2, 10, 0 )
+    g_object_ref_sink( cf->tip );
+#else
+    g_object_ref( cf->tip );
+    gtk_object_sink( cf->tip );
+#endif
+
+    g_signal_connect (G_OBJECT (p->pwid), "button_press_event", G_CALLBACK (clicked), (gpointer) p);
+
+    cf->has_cpufreq = 0;
+
+    get_cpus(cf);
+
+/*    line s;
+    s.len = 256;
+
+    if (fp) {
+        while (lxpanel_get_line(fp, &s) != LINE_BLOCK_END) {
+            if (s.type == LINE_NONE) {
+                ERR( "cpufreq: illegal token %s\n", s.str);
+                goto error;
+            }
+            if (s.type == LINE_VAR) {
+                if (!g_ascii_strcasecmp(s.t[0], "DefaultGovernor")){
+                    //cf->str_cl_normal = g_strdup(s.t[1]);
+                }else {
+                    ERR( "cpufreq: unknown var %s\n", s.t[0]);
+                    continue;
+                }
+            }
+            else {
+                ERR( "cpufreq: illegal in cfis context %s\n", s.str);
+                goto error;
+            }
+        }
+
+    }*/
+    update_tooltip(cf);
+    cf->timer = g_timeout_add(2000, (GSourceFunc)update_tooltip, (gpointer)cf);
+
+    gtk_widget_show(cf->namew);
+
+    RET(TRUE);
+
+/*error:
+    RET(FALSE);*/
+}
+
+static void applyConfig(Plugin* p) { }
+
+static void config(Plugin *p, GtkWindow* parent) {
+    ENTER;
+
+    GtkWidget *dialog;
+    cpufreq *cf = (cpufreq *) p->priv;
+    dialog = create_generic_config_dlg(_(p->class->name),
+            GTK_WIDGET(parent),
+            (GSourceFunc) applyConfig, (gpointer) p,
+            _("Remember governor and frequency"), &cf->remember, CONF_TYPE_BOOL,
+            NULL);
+    gtk_window_present(GTK_WINDOW(dialog));
+
+    RET();
+}
+
+static void
+cpufreq_destructor(Plugin *p)
+{
+    cpufreq *cf = (cpufreq *)p->priv;
+    g_list_free ( cf->cpus );
+    g_list_free ( cf->governors );
+    g_source_remove(cf->timer);
+    g_free(cf);
+}
+
+static void save_config( Plugin* p, FILE* fp )
+{
+    cpufreq *cf = (cpufreq *)p->priv;
+
+    lxpanel_put_bool( fp, "Remember", cf->remember);
+    lxpanel_put_str( fp, "Governor", cf->cur_governor );
+    lxpanel_put_int( fp, "Frequency", cf->cur_freq );
+}
+
+PluginClass cpufreq_plugin_class = {
+    PLUGINCLASS_VERSIONING,
+
+    type : "cpufreq",
+    name : N_("CPUFreq frontend"),
+    version: "0.1",
+    description : N_("Display CPU frequency and allow to change governors and frequency"),
+
+    constructor : cpufreq_constructor,
+    destructor  : cpufreq_destructor,
+    config : config,
+    save : NULL,
+    panel_configuration_changed : NULL
+};
index 19711cf..b95672b 100644 (file)
@@ -1,4 +1,23 @@
-//  by Daniel Kesler <kesler.daniel@gmail.com>
+/**
+ * Thermal plugin to lxpanel
+ *
+ * Copyright (C) 2007 by Daniel Kesler <kesler.daniel@gmail.com>
+ *
+ * This program 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 program 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 program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
 
 #include <sys/types.h>
 #include <stdio.h>
@@ -175,7 +194,7 @@ thermal_constructor(Plugin *p, char** fp)
     th->namew = gtk_label_new("ww");
     gtk_container_add(GTK_CONTAINER(p->pwid), th->namew);
 
-    th->main = gtk_event_box_new();
+    th->main = p->pwid;
     th->tip  = gtk_tooltips_new();
 
     g_signal_connect (G_OBJECT (p->pwid), "button_press_event",
@@ -242,6 +261,8 @@ thermal_constructor(Plugin *p, char** fp)
         th->warning2 = th->critical - 5;
     }
 
+    gtk_widget_show(th->namew);
+
     update_display(th);
     th->timer = g_timeout_add(1000, (GSourceFunc) update_display, (gpointer)th);
 
@@ -331,10 +352,11 @@ PluginClass thermal_plugin_class = {
     type : "thermal",
     name : N_("Temperature Monitor"),
     version: "0.6",
-    description : N_("Display system temperature, by kesler.daniel@gmail.com"),
+    description : N_("Display system temperature"),
 
     constructor : thermal_constructor,
     destructor  : thermal_destructor,
     config : config,
     save : save_config
+    panel_configuration_changed : NULL
 };