summaryrefslogtreecommitdiff
path: root/src/procman-app.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/procman-app.cpp')
-rw-r--r--src/procman-app.cpp428
1 files changed, 428 insertions, 0 deletions
diff --git a/src/procman-app.cpp b/src/procman-app.cpp
new file mode 100644
index 0000000..3a0c10a
--- /dev/null
+++ b/src/procman-app.cpp
@@ -0,0 +1,428 @@
+#include <glib/gi18n.h>
+#include <glibtop.h>
+#include <glibtop/close.h>
+#include <glibtop/cpu.h>
+#include <glibtop/sysinfo.h>
+
+#include "procman-app.h"
+#include "procman.h"
+#include "interface.h"
+#include "proctable.h"
+#include "callbacks.h"
+#include "load-graph.h"
+#include "settings-keys.h"
+#include "argv.h"
+#include "util.h"
+
+static void
+mount_changed(const Glib::RefPtr<Gio::Mount>&)
+{
+ cb_update_disks(ProcData::get_instance());
+}
+
+
+static void
+init_volume_monitor(ProcData *procdata)
+{
+ using namespace Gio;
+ using namespace Glib;
+
+ RefPtr<VolumeMonitor> monitor = VolumeMonitor::get();
+
+ monitor->signal_mount_added().connect(sigc::ptr_fun(&mount_changed));
+ monitor->signal_mount_changed().connect(sigc::ptr_fun(&mount_changed));
+ monitor->signal_mount_removed().connect(sigc::ptr_fun(&mount_changed));
+}
+
+static gboolean
+has_key (gchar **keys, const gchar *key)
+{
+ gchar **loop = keys;
+
+ while (*loop) {
+ if (!strcmp (*loop++, key))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+tree_changed_cb (GSettings *settings, const gchar *key, gpointer data)
+{
+ ProcData *procdata = static_cast<ProcData*>(data);
+
+ procdata->config.show_tree = g_settings_get_boolean(settings, key);
+
+ g_object_set(G_OBJECT(procdata->tree),
+ "show-expanders", procdata->config.show_tree,
+ NULL);
+
+ proctable_clear_tree (procdata);
+ proctable_update (procdata);
+}
+
+static void
+solaris_mode_changed_cb(GSettings *settings, const gchar *key, gpointer data)
+{
+ ProcData *procdata = static_cast<ProcData*>(data);
+
+ procdata->config.solaris_mode = g_settings_get_boolean(settings, key);
+ proctable_update (procdata);
+}
+
+
+static void
+network_in_bits_changed_cb(GSettings *settings, const gchar *key, gpointer data)
+{
+ ProcData *procdata = static_cast<ProcData*>(data);
+
+ procdata->config.network_in_bits = g_settings_get_boolean(settings, key);
+ // force scale to be redrawn
+ procdata->net_graph->clear_background();
+}
+
+static void
+view_as_changed_cb (GSettings *settings, const gchar *key, gpointer data)
+{
+ ProcData *procdata = static_cast<ProcData*>(data);
+
+ procdata->config.whose_process = g_settings_get_int (settings, key);
+ procdata->config.whose_process = CLAMP (procdata->config.whose_process, 0, 2);
+ proctable_clear_tree (procdata);
+ proctable_update (procdata);
+}
+
+static void
+warning_changed_cb (GSettings *settings, const gchar *key, gpointer data)
+{
+ ProcData *procdata = static_cast<ProcData*>(data);
+
+ if (g_str_equal (key, "kill-dialog")) {
+ procdata->config.show_kill_warning = g_settings_get_boolean (settings, key);
+ }
+}
+
+static void
+timeouts_changed_cb (GSettings *settings, const gchar *key, gpointer data)
+{
+ ProcData *procdata = static_cast<ProcData*>(data);
+
+ if (g_str_equal (key, "update-interval")) {
+ procdata->config.update_interval = g_settings_get_int (settings, key);
+ procdata->config.update_interval =
+ MAX (procdata->config.update_interval, 1000);
+
+ procdata->smooth_refresh->reset();
+
+ if(procdata->timeout) {
+ g_source_remove (procdata->timeout);
+ procdata->timeout = g_timeout_add (procdata->config.update_interval,
+ cb_timeout,
+ procdata);
+ }
+ }
+ else if (g_str_equal (key, "graph-update-interval")){
+ procdata->config.graph_update_interval = g_settings_get_int (settings, key);
+ procdata->config.graph_update_interval =
+ MAX (procdata->config.graph_update_interval,
+ 250);
+ load_graph_change_speed(procdata->cpu_graph,
+ procdata->config.graph_update_interval);
+ load_graph_change_speed(procdata->mem_graph,
+ procdata->config.graph_update_interval);
+ load_graph_change_speed(procdata->net_graph,
+ procdata->config.graph_update_interval);
+ }
+ else if (g_str_equal(key, "disks-interval")) {
+ procdata->config.disks_update_interval = g_settings_get_int (settings, key);
+ procdata->config.disks_update_interval =
+ MAX (procdata->config.disks_update_interval, 1000);
+
+ if(procdata->disk_timeout) {
+ g_source_remove (procdata->disk_timeout);
+ procdata->disk_timeout = \
+ g_timeout_add (procdata->config.disks_update_interval,
+ cb_update_disks,
+ procdata);
+ }
+ }
+ else {
+ g_assert_not_reached();
+ }
+}
+
+static void
+color_changed_cb (GSettings *settings, const gchar *key, gpointer data)
+{
+ ProcData * const procdata = static_cast<ProcData*>(data);
+ gchar *color = g_settings_get_string (settings, key);
+
+ if (g_str_has_prefix (key, "cpu-color")) {
+ for (int i = 0; i < procdata->config.num_cpus; i++) {
+ string cpu_key = make_string(g_strdup_printf("cpu-color%d", i));
+ if (cpu_key == key) {
+ gdk_rgba_parse (&procdata->config.cpu_color[i], color);
+ procdata->cpu_graph->colors.at(i) = procdata->config.cpu_color[i];
+ break;
+ }
+ }
+ }
+ else if (g_str_equal (key, "mem-color")) {
+ gdk_rgba_parse (&procdata->config.mem_color, color);
+ procdata->mem_graph->colors.at(0) = procdata->config.mem_color;
+ }
+ else if (g_str_equal (key, "swap-color")) {
+ gdk_rgba_parse (&procdata->config.swap_color, color);
+ procdata->mem_graph->colors.at(1) = procdata->config.swap_color;
+ }
+ else if (g_str_equal (key, "net-in-color")) {
+ gdk_rgba_parse (&procdata->config.net_in_color, color);
+ procdata->net_graph->colors.at(0) = procdata->config.net_in_color;
+ }
+ else if (g_str_equal (key, "net-out-color")) {
+ gdk_rgba_parse (&procdata->config.net_out_color, color);
+ procdata->net_graph->colors.at(1) = procdata->config.net_out_color;
+ }
+ else {
+ g_assert_not_reached();
+ }
+ g_free(color);
+}
+
+static void
+show_all_fs_changed_cb (GSettings *settings, const gchar *key, gpointer data)
+{
+ ProcData * const procdata = static_cast<ProcData*>(data);
+
+ procdata->config.show_all_fs = g_settings_get_boolean (settings, key);
+
+ cb_update_disks (data);
+}
+
+static ProcData *
+procman_data_new (GSettings *settings)
+{
+ GSettingsSchema *schema;
+ ProcData *pd;
+ gchar *color;
+ gchar **keys;
+ gint swidth, sheight;
+ glibtop_cpu cpu;
+
+ pd = ProcData::get_instance();
+
+ g_settings_get (settings, "window-state", "(iiii)",
+ &pd->config.width, &pd->config.height,
+ &pd->config.xpos, &pd->config.ypos);
+
+ pd->config.maximized = g_settings_get_boolean(settings, "maximized");
+
+ pd->config.show_tree = g_settings_get_boolean (settings, "show-tree");
+ g_signal_connect (G_OBJECT(settings), "changed::show-tree", G_CALLBACK(tree_changed_cb), pd);
+
+ pd->config.solaris_mode = g_settings_get_boolean(settings, procman::settings::solaris_mode.c_str());
+ std::string detail_string("changed::" + procman::settings::solaris_mode);
+ g_signal_connect(G_OBJECT(settings), detail_string.c_str(), G_CALLBACK(solaris_mode_changed_cb), pd);
+
+ pd->config.network_in_bits = g_settings_get_boolean(settings, procman::settings::network_in_bits.c_str());
+ detail_string = "changed::" + procman::settings::network_in_bits;
+ g_signal_connect(G_OBJECT(settings), detail_string.c_str(), G_CALLBACK(network_in_bits_changed_cb), pd);
+
+ pd->config.show_kill_warning = g_settings_get_boolean (settings, "kill-dialog");
+ g_signal_connect (G_OBJECT(settings), "changed::kill-dialog", G_CALLBACK(warning_changed_cb), pd);
+ pd->config.update_interval = g_settings_get_int (settings, "update-interval");
+ g_signal_connect (G_OBJECT(settings), "changed::update-interval", G_CALLBACK(timeouts_changed_cb), pd);
+ pd->config.graph_update_interval = g_settings_get_int (settings,
+ "graph-update-interval");
+ g_signal_connect (G_OBJECT(settings), "changed::graph-update-interval",
+ G_CALLBACK(timeouts_changed_cb), pd);
+ pd->config.disks_update_interval = g_settings_get_int (settings, "disks-interval");
+ g_signal_connect (G_OBJECT(settings), "changed::disks-interval", G_CALLBACK(timeouts_changed_cb), pd);
+
+
+ /* show_all_fs */
+ pd->config.show_all_fs = g_settings_get_boolean (settings, "show-all-fs");
+ g_signal_connect (settings, "changed::show-all-fs", G_CALLBACK(show_all_fs_changed_cb), pd);
+
+
+ pd->config.whose_process = g_settings_get_int (settings, "view-as");
+ g_signal_connect (G_OBJECT(settings), "changed::view-as", G_CALLBACK(view_as_changed_cb),pd);
+ pd->config.current_tab = g_settings_get_int (settings, "current-tab");
+
+ glibtop_get_cpu (&cpu);
+ pd->frequency = cpu.frequency;
+ pd->config.num_cpus = glibtop_get_sysinfo()->ncpu; // or server->ncpu + 1
+
+ g_object_get (settings, "settings-schema", &schema, NULL);
+ keys = g_settings_schema_list_keys (schema);
+ g_settings_schema_unref (schema);
+
+ for (int i = 0; i < pd->config.num_cpus; i++) {
+ gchar *key;
+ key = g_strdup_printf ("cpu-color%d", i);
+
+ if (has_key (keys, key))
+ color = g_settings_get_string (settings, key);
+ else
+ color = g_strdup ("#f25915e815e8");
+ detail_string = std::string("changed::") + std::string(key);
+ g_signal_connect (G_OBJECT(settings), detail_string.c_str(),
+ G_CALLBACK(color_changed_cb), pd);
+ gdk_rgba_parse (&pd->config.cpu_color[i], color);
+ g_free (color);
+ g_free (key);
+ }
+ g_strfreev (keys);
+
+ color = g_settings_get_string (settings, "mem-color");
+ if (!color)
+ color = g_strdup ("#000000ff0082");
+ g_signal_connect (G_OBJECT(settings), "changed::mem-color",
+ G_CALLBACK(color_changed_cb), pd);
+ gdk_rgba_parse(&pd->config.mem_color, color);
+ g_free (color);
+
+ color = g_settings_get_string (settings, "swap-color");
+ if (!color)
+ color = g_strdup ("#00b6000000ff");
+ g_signal_connect (G_OBJECT(settings), "changed::swap-color",
+ G_CALLBACK(color_changed_cb), pd);
+ gdk_rgba_parse(&pd->config.swap_color, color);
+ g_free (color);
+
+ color = g_settings_get_string (settings, "net-in-color");
+ if (!color)
+ color = g_strdup ("#000000f200f2");
+ g_signal_connect (G_OBJECT(settings), "changed::net-in-color",
+ G_CALLBACK(color_changed_cb), pd);
+ gdk_rgba_parse(&pd->config.net_in_color, color);
+ g_free (color);
+
+ color = g_settings_get_string (settings, "net-out-color");
+ if (!color)
+ color = g_strdup ("#00f2000000c1");
+ g_signal_connect (G_OBJECT(settings), "changed::net-out-color",
+ G_CALLBACK(color_changed_cb), pd);
+ gdk_rgba_parse(&pd->config.net_out_color, color);
+ g_free (color);
+
+ /* Sanity checks */
+ swidth = WidthOfScreen (gdk_x11_screen_get_xscreen (gdk_screen_get_default ()));
+ sheight = HeightOfScreen (gdk_x11_screen_get_xscreen (gdk_screen_get_default ()));
+ pd->config.width = CLAMP (pd->config.width, 50, swidth);
+ pd->config.height = CLAMP (pd->config.height, 50, sheight);
+ pd->config.update_interval = MAX (pd->config.update_interval, 1000);
+ pd->config.graph_update_interval = MAX (pd->config.graph_update_interval, 250);
+ pd->config.disks_update_interval = MAX (pd->config.disks_update_interval, 1000);
+ pd->config.whose_process = CLAMP (pd->config.whose_process, 0, 2);
+ pd->config.current_tab = CLAMP(pd->config.current_tab,
+ PROCMAN_TAB_SYSINFO,
+ PROCMAN_TAB_DISKS);
+
+ // delayed initialization as SmoothRefresh() needs ProcData
+ // i.e. we can't call ProcData::get_instance
+ pd->smooth_refresh = new SmoothRefresh(settings);
+
+ pd->terminating = FALSE;
+
+ return pd;
+}
+
+static void
+procman_free_data (ProcData *procdata)
+{
+
+ proctable_free_table (procdata);
+ delete procdata->smooth_refresh;
+}
+
+ProcmanApp::ProcmanApp() : Gtk::Application("org.mate.SystemMonitor", Gio::APPLICATION_HANDLES_COMMAND_LINE)
+{
+ Glib::set_application_name(_("System Monitor"));
+}
+
+Glib::RefPtr<ProcmanApp> ProcmanApp::create ()
+{
+ return Glib::RefPtr<ProcmanApp>(new ProcmanApp());
+}
+
+void ProcmanApp::on_activate()
+{
+ gtk_window_present (GTK_WINDOW (procdata->app));
+}
+
+static void
+set_tab(GtkNotebook* notebook, gint tab, ProcData* procdata)
+{
+ gtk_notebook_set_current_page(notebook, tab);
+ cb_change_current_page(notebook, tab, procdata);
+}
+
+int ProcmanApp::on_command_line(const Glib::RefPtr<Gio::ApplicationCommandLine>& command_line)
+{
+ int argc = 0;
+ char** argv = command_line->get_arguments(argc);
+
+ Glib::OptionContext context;
+ context.set_summary(_("A simple process and system monitor."));
+ context.set_ignore_unknown_options(true);
+ procman::OptionGroup option_group;
+ context.set_main_group(option_group);
+
+ try {
+ context.parse(argc, argv);
+ } catch (const Glib::Error& ex) {
+ g_error("Arguments parse error : %s", ex.what().c_str());
+ }
+
+ if (option_group.show_system_tab) {
+ procman_debug("Starting with PROCMAN_TAB_SYSINFO by commandline request");
+ set_tab(GTK_NOTEBOOK(procdata->notebook), PROCMAN_TAB_SYSINFO, procdata);
+ } else if (option_group.show_processes_tab) {
+ procman_debug("Starting with PROCMAN_TAB_PROCESSES by commandline request");
+ set_tab(GTK_NOTEBOOK(procdata->notebook), PROCMAN_TAB_PROCESSES, procdata);
+ } else if (option_group.show_resources_tab) {
+ procman_debug("Starting with PROCMAN_TAB_RESOURCES by commandline request");
+ set_tab(GTK_NOTEBOOK(procdata->notebook), PROCMAN_TAB_RESOURCES, procdata);
+ } else if (option_group.show_file_systems_tab) {
+ procman_debug("Starting with PROCMAN_TAB_DISKS by commandline request");
+ set_tab(GTK_NOTEBOOK(procdata->notebook), PROCMAN_TAB_DISKS, procdata);
+ }
+
+ on_activate ();
+
+ return 0;
+}
+
+void ProcmanApp::on_startup()
+{
+ Gtk::Application::on_startup();
+
+ GSettings *settings;
+
+ Gtk::Window::set_default_icon_name ("utilities-system-monitor");
+
+ settings = g_settings_new (GSM_GSETTINGS_SCHEMA);
+
+ glibtop_init ();
+
+ procdata = procman_data_new (settings);
+ procdata->settings = g_settings_new(GSM_GSETTINGS_SCHEMA);
+
+ create_main_window (procdata);
+ init_volume_monitor (procdata);
+
+ Gtk::Window *window = Glib::wrap(GTK_WINDOW(procdata->app));
+ window->show();
+ window->set_name ("mate-system-monitor");
+
+ add_window (*window);
+}
+
+void ProcmanApp::on_shutdown()
+{
+ procman_free_data(procdata);
+ glibtop_close();
+}
+