From 68f5774cb6a8a8a31f6f530b99fdcb7f1c5695fa Mon Sep 17 00:00:00 2001 From: David Date: Thu, 13 Feb 2014 19:00:50 +1300 Subject: First commit, only original (broken) source --- src/tray.c | 354 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 354 insertions(+) create mode 100644 src/tray.c (limited to 'src/tray.c') diff --git a/src/tray.c b/src/tray.c new file mode 100644 index 0000000..366cbf8 --- /dev/null +++ b/src/tray.c @@ -0,0 +1,354 @@ +/************************************************************************ + * This file is part of trayfreq. * + * * + * trayfreq 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 3 of the License, or * + * (at your option) any later version. * + * * + * trayfreq 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 trayfreq. If not, see . * + ************************************************************************/ + +#include "tray.h" +#include "widget_manager.h" +#include "getfreq.h" +#include "utilities.h" +#include "getcore.h" +#include "getgov.h" +#include "trayfreq_set_interface.h" +#include "defaults.h" +#include "getbat.h" + +#include +#include +#include +#include + +GtkStatusIcon* tray; +#define TOOLTIP_TEXT_SIZE 500 +gchar tooltip_text[TOOLTIP_TEXT_SIZE]; +/* 0 = nothing, 1 = was charging, 2 = was discharging */ +int state = 0; + + +GtkWidget* menu; +GSList* menu_items; +GtkWidget* checked_menu_item; + +static void freq_menu_item_toggled(GtkCheckMenuItem* item, + gpointer data) +{ + if(gtk_check_menu_item_get_active(item)) + { + checked_menu_item = GTK_WIDGET(item); + gint freq = GPOINTER_TO_INT(data); + int i = 0; + for(i = 0; i < gc_number(); ++i) + { + si_freq(freq, i); + } + } +} + +static void gov_menu_item_toggled(GtkCheckMenuItem* item, + gpointer data) +{ + if(gtk_check_menu_item_get_active(item)) + { + checked_menu_item = GTK_WIDGET(item); + gchar* gov = (gchar*)data; + int i = 0; + for(i = 0; i < gc_number(); ++i) + { + si_gov(gov, i); + } + } +} + +static gboolean governor_exists(gchar* governor) +{ + int i = 0; + for(i = 0; i < gf_number(); ++i) + { + if(g_strcmp0(governor, gg_gov(0, i)) == 0) + return TRUE; + } + return FALSE; +} + +static void remove_menu_item(GtkWidget* menu_item, gpointer data) +{ + gtk_widget_destroy(menu_item); +} + +static void tray_clear_menu() +{ + GtkContainer* cont = GTK_CONTAINER(menu); + gtk_container_foreach(cont, remove_menu_item, NULL); + menu_items = NULL; +} + +static void tray_init_menu() +{ + menu = gtk_menu_new(); +} + +static void tray_generate_menu() +{ + tray_clear_menu(); + gg_init(); + + gchar label[20]; + int i = 0; + + gchar current_governor[20]; + memset(current_governor, '\0', 20); + gg_current(0, current_governor, 20); + + gint current_frequency = gf_current(0); + + /* append the frequencies */ + for(i = 0; i < gf_number(); ++i) + { + memset(label, '\0', 20); + gf_get_frequency_label(gf_freqi(0, i), label); + + GtkWidget* item = gtk_radio_menu_item_new_with_label(menu_items, label); + menu_items = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM (item)); + + if(g_strcmp0(current_governor, "userspace") == 0 && gf_freqi(0, i) == current_frequency) + { + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE); + } + + g_signal_connect(G_OBJECT(item), "toggled", GTK_SIGNAL_FUNC(freq_menu_item_toggled), GINT_TO_POINTER(gf_freqi(0, i))); + + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + } + + /* append the seperator */ + GtkWidget* seperator = gtk_separator_menu_item_new(); + gtk_menu_append(menu, seperator); + + /* append the governors*/ + for(i = 0; i < gg_number(); ++i) + { + if(g_strcmp0(gg_gov(0, i), "userspace") == 0) + continue; + + GtkWidget* item = gtk_radio_menu_item_new_with_label(menu_items, gg_gov(0, i)); + menu_items = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM (item)); + + if(g_strcmp0(gg_gov(0, i), current_governor) == 0) + { + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE); + } + + g_signal_connect(G_OBJECT(item), "toggled", GTK_SIGNAL_FUNC(gov_menu_item_toggled), gg_gov(0, i)); + + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + } + + gtk_widget_show_all(menu); +} + +static gboolean update_tooltip(GtkStatusIcon* status_icon, + gint x, + gint y, + gboolean keyboard_mode, + GtkTooltip* tooltip, + gpointer data) +{ + gchar msg[500]; + gchar current_governer[20]; + gchar label[20]; + int i = 0; + + memset(msg, '\0', 500); + memset(current_governer, '\0', 20); + + /* change governor based on battery state */ + /* battery is discharging */ + if ((state == 0 || state == 1) && gb_discharging ()) + { + state = 2; + + if(def_get_bat_gov ()) + { + for(i = 0; i < gc_number(); ++i) + { + si_gov(def_get_bat_gov (), i); + } + } + } + /* battery is now charging (on ac) */ + else if ((state == 0 || state == 2) && gb_charging ()) + { + state = 1; + + if(def_get_ac_gov ()) + { + for(i = 0; i < gc_number(); ++i) + { + si_gov(def_get_ac_gov (), i); + } + } + } + + + + + gg_current(0, current_governer, 20); + sprintf(msg, "%sGovernor: %s\n", msg, current_governer); + + for(i = 0; i < gc_number(); ++i) + { + memset(label, '\0', 20); + gf_get_frequency_label(gf_current(i), label); + sprintf(msg, "%sCPU%i: %s%s", msg, i, label, i == gc_number()-1 ? "" : "\n"); + } + + tray_set_tooltip(msg); + gtk_tooltip_set_text(tooltip, tooltip_text); + + return TRUE; +}; + +static void popup_menu(GtkStatusIcon* statuc_icon, + guint button, + guint activate_time, + gpointer data) +{ + tray_generate_menu(); + gtk_menu_popup(GTK_MENU(menu), + NULL, + NULL, + gtk_status_icon_position_menu, + tray, + button, + activate_time); +} + +static void activate(GtkStatusIcon* statuc_icon, + gpointer data) +{ + gchar* def_prog = def_get_prog(); + if(def_prog) + g_spawn_command_line_async (def_prog, NULL); +} + +static gboolean update_icon(gpointer user_data) +{ + tray_update_icon_percent(); +} + +void tray_init() +{ + // set defaults + gchar* def_gov = def_get_gov(); + int i = 0; + if(def_gov) + { + for(i = 0; i < gc_number(); ++i) + { + si_gov(def_gov, i); + } + } + else + { + for(i = 0; i < gc_number(); ++i) + { + si_gov("ondemand", i); + } + } + gchar* def_freq = def_get_freq(); + if(def_freq) + { + for(i = 0; i < gc_number(); ++i) + { + si_freq(atoi(def_freq), i); + } + } + + tray = gtk_status_icon_new(); + gchar* icon_file = g_strconcat(util_get_prefix(), "/share/trayfreq/cpufreq-0.png", NULL); + gtk_status_icon_set_from_file(tray, icon_file); + gtk_status_icon_set_has_tooltip (tray, TRUE); + g_signal_connect(G_OBJECT(tray), "query-tooltip", GTK_SIGNAL_FUNC(update_tooltip), NULL); + g_signal_connect(G_OBJECT(tray), "popup-menu", GTK_SIGNAL_FUNC(popup_menu), NULL); + g_signal_connect(G_OBJECT(tray), "activate", GTK_SIGNAL_FUNC(activate), NULL); + gtk_timeout_add(1000, update_icon, NULL); + tray_init_menu(); +} + +void tray_set_tooltip(const gchar* msg) +{ + memset(tooltip_text, '\0', TOOLTIP_TEXT_SIZE); + memmove(tooltip_text, msg, strlen(msg)); +} + +void tray_update_icon_percent() +{ + gulong max_frequency = gf_freqi(0, 0); + + /* The percentange should only be 25, 50, 75, or 100, so we need to + round to one of these numbers. */ + gint percent = (gf_current(0) * 100)/max_frequency; + gint adjusted_percent = 0; + + if(percent == 100) + { + adjusted_percent = 100; + } + else if(percent >= 65.5) + { + adjusted_percent = 75; + } + else if(percent >= 37.5) + { + adjusted_percent = 50; + } + else if(percent >= 12.5) + { + adjusted_percent = 25; + } + else + { + adjusted_percent = 0; + } + + /* convert the int to a string */ + gchar adjusted_percent_string[] = {'\0', '\0', '\0', '\0'}; + sprintf(adjusted_percent_string, "%i", adjusted_percent); + + gchar* file = g_strconcat(util_get_prefix(), "/share/trayfreq/cpufreq-", adjusted_percent_string, ".png", NULL); + gtk_status_icon_set_from_file(tray, file); + + g_free(file); +} + +void tray_show() +{ + gtk_status_icon_set_visible(tray, TRUE); +} + +void tray_hide() +{ + gtk_status_icon_set_visible(tray, FALSE); +} + +gboolean tray_visible() +{ + return gtk_status_icon_get_visible(tray); +} + +gboolean tray_embedded() +{ + return gtk_status_icon_is_embedded(tray); +} -- cgit v1.1