gnome-system-monitor-01-solaris.diff revision 9799
8403N/Adiff -Nrup gnome-system-monitor-2.17.5/src/callbacks.h gnome-system-monitor-2.17.5.trunk/src/callbacks.h
8403N/A--- gnome-system-monitor-2.17.5/src/callbacks.h 2007-01-03 06:15:36.000000000 +0800
8403N/A+++ gnome-system-monitor-2.17.5.trunk/src/callbacks.h 2007-01-23 11:55:37.101723000 +0800
8403N/A@@ -26,64 +26,64 @@
8403N/A #include <libgnomevfs/gnome-vfs.h>
8403N/A
8403N/A
8403N/A-void cb_show_memory_maps (GtkAction *action, gpointer data) G_GNUC_INTERNAL;
8403N/A-void cb_show_open_files (GtkAction *action, gpointer data) G_GNUC_INTERNAL;
8403N/A-void cb_show_lsof(GtkAction *action, gpointer data) G_GNUC_INTERNAL;
8403N/A-void cb_renice (GtkAction *action, gpointer data) G_GNUC_INTERNAL;
8403N/A-void cb_end_process (GtkAction *action, gpointer data) G_GNUC_INTERNAL;
8403N/A-void cb_kill_process (GtkAction *action, gpointer data) G_GNUC_INTERNAL;
8403N/A-void cb_hide_process (GtkAction *action, gpointer data) G_GNUC_INTERNAL;
8403N/A-void cb_show_hidden_processes (GtkAction *action, gpointer data) G_GNUC_INTERNAL;
8403N/A-void cb_edit_preferences (GtkAction *action, gpointer data) G_GNUC_INTERNAL;
8403N/A-
8403N/A-void cb_help_contents (GtkAction *action, gpointer data) G_GNUC_INTERNAL;
8403N/A-void cb_about (GtkAction *action, gpointer data) G_GNUC_INTERNAL;
8403N/A-
8403N/A-void cb_app_exit (GtkAction *action, gpointer data) G_GNUC_INTERNAL;
8403N/A-gboolean cb_app_delete (GtkWidget *window, GdkEventAny *event, gpointer data) G_GNUC_INTERNAL;
8403N/A-
8403N/A-void cb_end_process_button_pressed (GtkButton *button, gpointer data) G_GNUC_INTERNAL;
8403N/A-void cb_logout (GtkButton *button, gpointer data) G_GNUC_INTERNAL;
8403N/A-
8403N/A-void cb_info_button_pressed (GtkButton *button, gpointer user_data) G_GNUC_INTERNAL;
8403N/A-
8403N/A-void cb_cpu_color_changed (GtkColorButton *widget, gpointer user_data) G_GNUC_INTERNAL;
8403N/A-void cb_mem_color_changed (GtkColorButton *widget, gpointer user_data) G_GNUC_INTERNAL;
8403N/A-void cb_swap_color_changed (GtkColorButton *widget, gpointer user_data) G_GNUC_INTERNAL;
8403N/A-void cb_net_in_color_changed (GtkColorButton *widget, gpointer user_data) G_GNUC_INTERNAL;
8403N/A-void cb_net_out_color_changed (GtkColorButton *widget, gpointer user_data) G_GNUC_INTERNAL;
8403N/A-void cb_bg_color_changed (GtkColorButton *widget, gpointer user_data) G_GNUC_INTERNAL;
8403N/A-void cb_frame_color_changed (GtkColorButton *widget, gpointer user_data) G_GNUC_INTERNAL;
8403N/A-
8403N/A-void cb_row_selected (GtkTreeSelection *selection, gpointer data) G_GNUC_INTERNAL;
8403N/A-
8403N/A-gboolean cb_tree_popup_menu (GtkWidget *widget, gpointer data) G_GNUC_INTERNAL;
8403N/A-gboolean cb_tree_button_pressed (GtkWidget *widget, GdkEventButton *event,
8403N/A- gpointer data) G_GNUC_INTERNAL;
8403N/A-
8403N/A-
8403N/A-void cb_change_current_page (GtkNotebook *nb,
8403N/A- gint num, gpointer data) G_GNUC_INTERNAL;
8403N/A-void cb_switch_page (GtkNotebook *nb, GtkNotebookPage *page,
8403N/A- gint num, gpointer data) G_GNUC_INTERNAL;
8403N/A+G_GNUC_INTERNAL void cb_show_memory_maps (GtkAction *action, gpointer data);
8403N/A+G_GNUC_INTERNAL void cb_show_open_files (GtkAction *action, gpointer data);
8403N/A+G_GNUC_INTERNAL void cb_show_lsof(GtkAction *action, gpointer data);
8403N/A+G_GNUC_INTERNAL void cb_renice (GtkAction *action, gpointer data);
8403N/A+G_GNUC_INTERNAL void cb_end_process (GtkAction *action, gpointer data);
8403N/A+G_GNUC_INTERNAL void cb_kill_process (GtkAction *action, gpointer data);
8403N/A+G_GNUC_INTERNAL void cb_hide_process (GtkAction *action, gpointer data);
8403N/A+G_GNUC_INTERNAL void cb_show_hidden_processes (GtkAction *action, gpointer data);
8403N/A+G_GNUC_INTERNAL void cb_edit_preferences (GtkAction *action, gpointer data);
8403N/A+
8403N/A+G_GNUC_INTERNAL void cb_help_contents (GtkAction *action, gpointer data);
8403N/A+G_GNUC_INTERNAL void cb_about (GtkAction *action, gpointer data);
8403N/A+
8405N/A+G_GNUC_INTERNAL void cb_app_exit (GtkAction *action, gpointer data);
8405N/A+G_GNUC_INTERNAL gboolean cb_app_delete (GtkWidget *window, GdkEventAny *event, gpointer data);
8405N/A+
8405N/A+G_GNUC_INTERNAL void cb_end_process_button_pressed (GtkButton *button, gpointer data);
8405N/A+G_GNUC_INTERNAL void cb_logout (GtkButton *button, gpointer data);
8405N/A+
8405N/A+G_GNUC_INTERNAL void cb_info_button_pressed (GtkButton *button, gpointer user_data);
8405N/A+
8405N/A+G_GNUC_INTERNAL void cb_cpu_color_changed (GtkColorButton *widget, gpointer user_data);
8405N/A+G_GNUC_INTERNAL void cb_mem_color_changed (GtkColorButton *widget, gpointer user_data);
8405N/A+G_GNUC_INTERNAL void cb_swap_color_changed (GtkColorButton *widget, gpointer user_data);
8405N/A+G_GNUC_INTERNAL void cb_net_in_color_changed (GtkColorButton *widget, gpointer user_data);
8405N/A+G_GNUC_INTERNAL void cb_net_out_color_changed (GtkColorButton *widget, gpointer user_data);
8405N/A+G_GNUC_INTERNAL void cb_bg_color_changed (GtkColorButton *widget, gpointer user_data);
8405N/A+G_GNUC_INTERNAL void cb_frame_color_changed (GtkColorButton *widget, gpointer user_data);
8405N/A+
8405N/A+G_GNUC_INTERNAL void cb_row_selected (GtkTreeSelection *selection, gpointer data);
8405N/A+
8405N/A+G_GNUC_INTERNAL gboolean cb_tree_popup_menu (GtkWidget *widget, gpointer data);
8405N/A+G_GNUC_INTERNAL gboolean cb_tree_button_pressed (GtkWidget *widget, GdkEventButton *event,
8405N/A+ gpointer data);
8405N/A+
8405N/A+
8405N/A+G_GNUC_INTERNAL void cb_change_current_page (GtkNotebook *nb,
8405N/A+ gint num, gpointer data);
8405N/A+G_GNUC_INTERNAL void cb_switch_page (GtkNotebook *nb, GtkNotebookPage *page,
8405N/A+ gint num, gpointer data);
8405N/A
8405N/A-gint cb_update_disks (gpointer data) G_GNUC_INTERNAL;
8405N/A-gint cb_timeout (gpointer data) G_GNUC_INTERNAL;
8405N/A+G_GNUC_INTERNAL gint cb_update_disks (gpointer data);
8405N/A+G_GNUC_INTERNAL gint cb_timeout (gpointer data);
8405N/A
8405N/A-void cb_volume_mounted_or_unmounted(GnomeVFSVolumeMonitor *vfsvolumemonitor,
8405N/A+G_GNUC_INTERNAL void cb_volume_mounted_or_unmounted(GnomeVFSVolumeMonitor *vfsvolumemonitor,
8405N/A GnomeVFSVolume *vol,
8405N/A- gpointer procdata) G_GNUC_INTERNAL;
8405N/A+ gpointer procdata);
8405N/A
8405N/A-void cb_radio_processes(GtkAction *action,
8405N/A+G_GNUC_INTERNAL void cb_radio_processes(GtkAction *action,
8405N/A GtkRadioAction *current,
8405N/A- gpointer data) G_GNUC_INTERNAL;
8405N/A+ gpointer data);
8405N/A
8405N/A
8405N/A
8405N/A-void cb_kill_sigstop(GtkAction *action,
8405N/A- gpointer data) G_GNUC_INTERNAL;
8405N/A+G_GNUC_INTERNAL void cb_kill_sigstop(GtkAction *action,
8405N/A+ gpointer data);
8405N/A
8405N/A-void cb_kill_sigcont(GtkAction *action,
8405N/A- gpointer data) G_GNUC_INTERNAL;
8405N/A+G_GNUC_INTERNAL void cb_kill_sigcont(GtkAction *action,
8405N/A+ gpointer data);
8405N/A
8405N/A #endif /* _PROCMAN_CALLBACKS_H_ */
8405N/Adiff -Nrup gnome-system-monitor-2.17.5/src/favorites.h gnome-system-monitor-2.17.5.trunk/src/favorites.h
8405N/A--- gnome-system-monitor-2.17.5/src/favorites.h 2007-01-03 06:15:36.000000000 +0800
8405N/A+++ gnome-system-monitor-2.17.5.trunk/src/favorites.h 2007-01-23 11:41:38.526886000 +0800
8405N/A@@ -26,15 +26,15 @@
8405N/A
8405N/A #include "procman.h"
8405N/A
8405N/A-void save_blacklist (ProcData *procdata, GConfClient *client) G_GNUC_INTERNAL;
8405N/A-void add_to_blacklist (ProcData *procdata, gchar *name) G_GNUC_INTERNAL;
8405N/A-void add_selected_to_blacklist (ProcData *procdata) G_GNUC_INTERNAL;
8405N/A-void remove_from_blacklist (ProcData *procdata, gchar *name) G_GNUC_INTERNAL;
8405N/A+G_GNUC_INTERNAL void save_blacklist (ProcData *procdata, GConfClient *client);
8405N/A+G_GNUC_INTERNAL void add_to_blacklist (ProcData *procdata, gchar *name);
8405N/A+G_GNUC_INTERNAL void add_selected_to_blacklist (ProcData *procdata);
8405N/A+G_GNUC_INTERNAL void remove_from_blacklist (ProcData *procdata, gchar *name);
8405N/A
8405N/A-gboolean is_process_blacklisted (ProcData *procdata, gchar *name) G_GNUC_INTERNAL;
8405N/A+G_GNUC_INTERNAL gboolean is_process_blacklisted (ProcData *procdata, gchar *name);
8405N/A
8405N/A-void get_blacklist (ProcData *procdata, GConfClient *client) G_GNUC_INTERNAL;
8405N/A+G_GNUC_INTERNAL void get_blacklist (ProcData *procdata, GConfClient *client);
8405N/A
8405N/A-void create_blacklist_dialog (ProcData *procdata) G_GNUC_INTERNAL;
8405N/A+G_GNUC_INTERNAL void create_blacklist_dialog (ProcData *procdata);
8405N/A
8405N/A #endif
8405N/Adiff -Nrup gnome-system-monitor-2.17.5/src/interface.cpp gnome-system-monitor-2.17.5.trunk/src/interface.cpp
8405N/A--- gnome-system-monitor-2.17.5/src/interface.cpp 2007-01-06 06:38:46.000000000 +0800
8405N/A+++ gnome-system-monitor-2.17.5.trunk/src/interface.cpp 2007-01-23 14:05:54.223608000 +0800
8405N/A@@ -250,12 +250,13 @@ create_sys_view (ProcData *procdata)
8405N/A GtkWidget *cpu_box, *mem_box, *net_box;
8405N/A GtkWidget *cpu_hbox, *mem_hbox, *net_hbox;
8405N/A GtkWidget *cpu_graph_box, *mem_graph_box, *net_graph_box;
8405N/A- GtkWidget *label,*cpu_label, *spacer;
8405N/A+ GtkWidget *label,*label2,*label3, *label4,*label5, *cpu_label, *spacer;
8405N/A GtkWidget *table;
8405N/A GtkWidget *color_picker;
8405N/A GtkSizeGroup *sizegroup;
8405N/A LoadGraph *cpu_graph, *mem_graph, *net_graph;
8405N/A gint i;
8405N/A+ AtkObject *colorWidget, *label1Widget, *label2Widget, *label3Widget, *label4Widget, *label5Widget;
8405N/A
8405N/A
8405N/A vbox = gtk_vbox_new (FALSE, 18);
8405N/A@@ -304,6 +305,7 @@ create_sys_view (ProcData *procdata)
8405N/A
8405N/A color_picker = gtk_color_button_new_with_color (
8405N/A &load_graph_get_colors(cpu_graph)[2+i]);
8405N/A+ colorWidget = gtk_widget_get_accessible (color_picker);
8405N/A
8405N/A g_signal_connect (G_OBJECT (color_picker), "color_set",
8405N/A G_CALLBACK (cb_cpu_color_changed), GINT_TO_POINTER (i));
8405N/A@@ -316,10 +318,21 @@ create_sys_view (ProcData *procdata)
8405N/A text = g_strdup_printf (_("CPU%d:"), i+1);
8405N/A }
8405N/A label = gtk_label_new (text);
8405N/A+ /* in order to support accessibility, add the relationship between label and button */
8405N/A+ label1Widget = gtk_widget_get_accessible (label);
8405N/A+ atk_object_add_relationship (label1Widget,ATK_RELATION_LABEL_FOR,colorWidget);
8405N/A+
8405N/A gtk_box_pack_start (GTK_BOX (temp_hbox), label, FALSE, FALSE, 6);
8405N/A g_free (text);
8405N/A
8405N/A cpu_label = gtk_label_new (NULL);
8405N/A+ /* in order to support accessibility, add the relationship between button and cpu_label */
8405N/A+ label2Widget = gtk_widget_get_accessible (cpu_label);
8405N/A+ atk_object_add_relationship (label2Widget, ATK_RELATION_LABEL_FOR, colorWidget);
8405N/A+ /* in order to support accessibility, add the relationship between button and label/cpu_label */
8405N/A+ atk_object_add_relationship (colorWidget, ATK_RELATION_LABELLED_BY ,label1Widget);
8405N/A+ atk_object_add_relationship (colorWidget, ATK_RELATION_LABELLED_BY ,label2Widget);
8405N/A+
8405N/A gtk_box_pack_start (GTK_BOX (temp_hbox), cpu_label, FALSE, FALSE, 0);
8405N/A load_graph_get_labels(cpu_graph)->cpu[i] = cpu_label;
8405N/A
8405N/A@@ -360,21 +373,32 @@ create_sys_view (ProcData *procdata)
8405N/A gtk_box_pack_start (GTK_BOX (mem_graph_box), table,
8405N/A FALSE, FALSE, 0);
8405N/A
8405N/A+/* Draw User usage */
8405N/A color_picker = gtk_color_button_new_with_color (
8405N/A &load_graph_get_colors(mem_graph)[2]);
8405N/A+ colorWidget = gtk_widget_get_accessible (color_picker);
8405N/A g_signal_connect (G_OBJECT (color_picker), "color_set",
8405N/A G_CALLBACK (cb_mem_color_changed), procdata);
8405N/A gtk_table_attach (GTK_TABLE (table), color_picker, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
8405N/A
8405N/A label = gtk_label_new (_("User memory:"));
8405N/A+ label1Widget = gtk_widget_get_accessible (label);
8405N/A+ atk_object_add_relationship (label1Widget,ATK_RELATION_LABEL_FOR,colorWidget);
8405N/A gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
8405N/A gtk_table_attach (GTK_TABLE (table), label, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
8405N/A-
8405N/A- gtk_misc_set_alignment (GTK_MISC (load_graph_get_labels(mem_graph)->memused),
8405N/A+
8405N/A+ /* in order to support accessibility, and to promote performance and readable,
8405N/A+ let's call the load_graph_get_labels() only once here */
8405N/A+ label2 = load_graph_get_labels(mem_graph)->memused;
8405N/A+ label2Widget = gtk_widget_get_accessible (label2);
8405N/A+ atk_object_add_relationship (label2Widget,ATK_RELATION_LABEL_FOR,colorWidget);
8405N/A+/* gtk_misc_set_alignment (GTK_MISC (load_graph_get_labels(mem_graph)->memused),*/
8405N/A+ gtk_misc_set_alignment (GTK_MISC (label2),
8405N/A 0.0,
8403N/A 0.5);
8403N/A gtk_table_attach (GTK_TABLE (table),
8403N/A- load_graph_get_labels(mem_graph)->memused,
8403N/A+ /*load_graph_get_labels(mem_graph)->memused,*/
8403N/A+ label2,
8403N/A 2,
8403N/A 3,
8403N/A 0,
8403N/A@@ -384,17 +408,27 @@ create_sys_view (ProcData *procdata)
8403N/A 0,
8403N/A 0);
8403N/A
8403N/A- label = gtk_label_new (_("of"));
8403N/A- gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
8403N/A- gtk_table_attach (GTK_TABLE (table), label, 3, 4, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
8403N/A+ /* in order to support accessibility, add the relationship between label and button */
8403N/A+ label3 = gtk_label_new (_("of"));
8403N/A+ label3Widget = gtk_widget_get_accessible (label3);
8403N/A+ atk_object_add_relationship (label3Widget,ATK_RELATION_LABEL_FOR,colorWidget);
8403N/A+ gtk_misc_set_alignment (GTK_MISC (label3), 0.0, 0.5);
8403N/A+ gtk_table_attach (GTK_TABLE (table), label3, 3, 4, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
8403N/A
8403N/A
8403N/A- gtk_misc_set_alignment (GTK_MISC (load_graph_get_labels(mem_graph)->memtotal),
8403N/A+ /* in order to support accessibility, and to promote performance and readable,
8403N/A+ let's call the load_graph_get_labels() only once here */
8403N/A+ label4 = load_graph_get_labels(mem_graph)->memtotal;
8403N/A+ label4Widget = gtk_widget_get_accessible (label4);
8403N/A+ atk_object_add_relationship (label4Widget,ATK_RELATION_LABEL_FOR,colorWidget);
8403N/A+/* gtk_misc_set_alignment (GTK_MISC (load_graph_get_labels(mem_graph)->memtotal),*/
8403N/A+ gtk_misc_set_alignment (GTK_MISC (label4),
8403N/A 0.0,
8403N/A 0.5);
8403N/A
8403N/A gtk_table_attach (GTK_TABLE (table),
8403N/A- load_graph_get_labels(mem_graph)->memtotal,
8403N/A+/* load_graph_get_labels(mem_graph)->memtotal,*/
8403N/A+ label4,
8403N/A 4,
8403N/A 5,
8403N/A 0,
8403N/A@@ -404,12 +438,19 @@ create_sys_view (ProcData *procdata)
8403N/A 0,
8403N/A 0);
8403N/A
8403N/A+ /* in order to support accessibility, and to promote performance and readable,
8403N/A+ let's call the load_graph_get_labels() only once here */
8403N/A+ label5 = load_graph_get_labels(mem_graph)->mempercent;
8403N/A+ label5Widget = gtk_widget_get_accessible (label5);
8403N/A+ atk_object_add_relationship (label5Widget,ATK_RELATION_LABEL_FOR,colorWidget);
8403N/A
8403N/A- gtk_misc_set_alignment (GTK_MISC (load_graph_get_labels(mem_graph)->mempercent),
8403N/A+/* gtk_misc_set_alignment (GTK_MISC (load_graph_get_labels(mem_graph)->mempercent),*/
8403N/A+ gtk_misc_set_alignment (GTK_MISC (label5),
8403N/A 1.0,
8403N/A 0.5);
8403N/A gtk_table_attach (GTK_TABLE (table),
8403N/A- load_graph_get_labels(mem_graph)->mempercent,
8403N/A+/* load_graph_get_labels(mem_graph)->mempercent,*/
8403N/A+ label5,
8403N/A 5,
8403N/A 6,
8403N/A 0,
8403N/A@@ -419,22 +460,41 @@ create_sys_view (ProcData *procdata)
8403N/A 0,
8403N/A 0);
8403N/A
8403N/A+ /* in order to support accessibility, add the relationship between button and label */
8403N/A+ atk_object_add_relationship (colorWidget, ATK_RELATION_LABELLED_BY ,label1Widget);
8403N/A+ atk_object_add_relationship (colorWidget, ATK_RELATION_LABELLED_BY ,label2Widget);
8403N/A+ atk_object_add_relationship (colorWidget, ATK_RELATION_LABELLED_BY ,label3Widget);
8403N/A+ atk_object_add_relationship (colorWidget, ATK_RELATION_LABELLED_BY ,label4Widget);
8403N/A+ atk_object_add_relationship (colorWidget, ATK_RELATION_LABELLED_BY ,label5Widget);
8403N/A+
8403N/A+/* Draw the Swap Usage */
8403N/A color_picker = gtk_color_button_new_with_color (
8403N/A &load_graph_get_colors(mem_graph)[3]);
8403N/A+ colorWidget = gtk_widget_get_accessible (color_picker);
8403N/A g_signal_connect (G_OBJECT (color_picker), "color_set",
8403N/A G_CALLBACK (cb_swap_color_changed), procdata);
8403N/A gtk_table_attach (GTK_TABLE (table), color_picker, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
8403N/A
8403N/A label = gtk_label_new (_("Used swap:"));
8403N/A+ /* in order to support accessibility, add the relationship between label and button */
8403N/A+ label1Widget = gtk_widget_get_accessible (label);
8403N/A+ atk_object_add_relationship (label1Widget,ATK_RELATION_LABEL_FOR,colorWidget);
8403N/A gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
8403N/A gtk_table_attach (GTK_TABLE (table), label, 1, 2, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
8403N/A
8403N/A
8403N/A- gtk_misc_set_alignment (GTK_MISC (load_graph_get_labels(mem_graph)->swapused ),
8403N/A+ /* in order to support accessibility, and to promote performance and readable,
8403N/A+ let's call the load_graph_get_labels() only once here */
8403N/A+ label2 = load_graph_get_labels(mem_graph)->swapused;
8403N/A+ label2Widget = gtk_widget_get_accessible (label2);
8403N/A+ atk_object_add_relationship (label2Widget,ATK_RELATION_LABEL_FOR,colorWidget);
8403N/A+ gtk_misc_set_alignment (GTK_MISC (label2),
8403N/A+/* gtk_misc_set_alignment (GTK_MISC (load_graph_get_labels(mem_graph)->swapused ),*/
8403N/A 0.0,
8403N/A 0.5);
8403N/A gtk_table_attach (GTK_TABLE (table),
8403N/A- load_graph_get_labels(mem_graph)->swapused,
8403N/A+/* load_graph_get_labels(mem_graph)->swapused,*/
8403N/A+ label2,
8403N/A 2,
8403N/A 3,
8403N/A 1,
8403N/A@@ -444,16 +504,26 @@ create_sys_view (ProcData *procdata)
8403N/A 0,
8403N/A 0);
8403N/A
8403N/A- label = gtk_label_new (_("of"));
8403N/A- gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
8403N/A- gtk_table_attach (GTK_TABLE (table), label, 3, 4, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
8403N/A+ /* in order to support accessibility, add the relationship between label and button */
8403N/A+ label3 = gtk_label_new (_("of"));
8403N/A+ label3Widget = gtk_widget_get_accessible (label3);
8403N/A+ atk_object_add_relationship (label3Widget,ATK_RELATION_LABEL_FOR,colorWidget);
8403N/A+ gtk_misc_set_alignment (GTK_MISC (label3), 0.0, 0.5);
8403N/A+ gtk_table_attach (GTK_TABLE (table), label3, 3, 4, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
8403N/A
8403N/A
8403N/A- gtk_misc_set_alignment (GTK_MISC (load_graph_get_labels(mem_graph)->swaptotal),
8403N/A+ /* in order to support accessibility, and to promote performance and readable,
8403N/A+ let's call the load_graph_get_labels() only once here */
8403N/A+ label4 = load_graph_get_labels(mem_graph)->swaptotal;
8403N/A+ label4Widget = gtk_widget_get_accessible (label4);
8403N/A+ atk_object_add_relationship (label4Widget,ATK_RELATION_LABEL_FOR,colorWidget);
8403N/A+ gtk_misc_set_alignment (GTK_MISC (label4),
8403N/A+/* gtk_misc_set_alignment (GTK_MISC (load_graph_get_labels(mem_graph)->swaptotal),*/
8403N/A 0.0,
8403N/A 0.5);
8403N/A gtk_table_attach (GTK_TABLE (table),
8403N/A- load_graph_get_labels(mem_graph)->swaptotal,
8403N/A+/* load_graph_get_labels(mem_graph)->swaptotal,*/
8403N/A+ label4,
8403N/A 4,
8405N/A 5,
8405N/A 1,
8405N/A@@ -463,12 +533,19 @@ create_sys_view (ProcData *procdata)
8405N/A 0,
8405N/A 0);
8405N/A
8405N/A+ /* in order to support accessibility, and to promote performance and readable,
8405N/A+ let's call the load_graph_get_labels() only once here */
8405N/A+ label5 = load_graph_get_labels(mem_graph)->swappercent;
8405N/A+ label5Widget = gtk_widget_get_accessible (label5);
8405N/A+ atk_object_add_relationship (label5Widget,ATK_RELATION_LABEL_FOR,colorWidget);
8405N/A
8405N/A- gtk_misc_set_alignment (GTK_MISC (load_graph_get_labels(mem_graph)->swappercent),
8405N/A+/* gtk_misc_set_alignment (GTK_MISC (load_graph_get_labels(mem_graph)->swappercent),*/
8405N/A+ gtk_misc_set_alignment (GTK_MISC (label5),
8405N/A 1.0,
8405N/A 0.5);
8405N/A gtk_table_attach (GTK_TABLE (table),
8405N/A- load_graph_get_labels(mem_graph)->swappercent,
8405N/A+/* load_graph_get_labels(mem_graph)->swappercent,*/
8405N/A+ label5,
8405N/A 5,
8405N/A 6,
8405N/A 1,
8405N/A@@ -478,6 +555,13 @@ create_sys_view (ProcData *procdata)
8405N/A 0,
8405N/A 0);
8405N/A
8405N/A+ /* in order to support accessibility, add the relationship between button and label */
8405N/A+ atk_object_add_relationship (colorWidget, ATK_RELATION_LABELLED_BY ,label1Widget);
8405N/A+ atk_object_add_relationship (colorWidget, ATK_RELATION_LABELLED_BY ,label2Widget);
8405N/A+ atk_object_add_relationship (colorWidget, ATK_RELATION_LABELLED_BY ,label3Widget);
8405N/A+ atk_object_add_relationship (colorWidget, ATK_RELATION_LABELLED_BY ,label4Widget);
8405N/A+ atk_object_add_relationship (colorWidget, ATK_RELATION_LABELLED_BY ,label5Widget);
8405N/A+
8405N/A procdata->mem_graph = mem_graph;
8405N/A
8405N/A /* The net box */
8405N/A@@ -512,11 +596,15 @@ create_sys_view (ProcData *procdata)
8405N/A
8405N/A color_picker = gtk_color_button_new_with_color (
8405N/A &load_graph_get_colors(net_graph)[2]);
8405N/A+ colorWidget = gtk_widget_get_accessible (color_picker);
8405N/A g_signal_connect (G_OBJECT (color_picker), "color_set",
8405N/A G_CALLBACK (cb_net_in_color_changed), procdata);
8405N/A gtk_table_attach (GTK_TABLE (table), color_picker, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
8405N/A
8405N/A label = gtk_label_new (_("Received:"));
8405N/A+ /* in order to support accessibility, add the relationship between label and button */
8405N/A+ label1Widget = gtk_widget_get_accessible (label);
8405N/A+ atk_object_add_relationship (label1Widget,ATK_RELATION_LABEL_FOR,colorWidget);
8405N/A gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
8405N/A gtk_table_attach (GTK_TABLE (table), label, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
8405N/A
8405N/A@@ -525,26 +613,43 @@ create_sys_view (ProcData *procdata)
8405N/A G_CALLBACK (net_size_request), procdata);
8405N/A
8405N/A
8405N/A- gtk_misc_set_alignment (GTK_MISC (load_graph_get_labels(net_graph)->net_in),
8405N/A+ /* in order to support accessibility, and to promote performance and readable,
8405N/A+ let's call the load_graph_get_labels() only once here */
8405N/A+ label2 = load_graph_get_labels(net_graph)->net_in;
8405N/A+ label2Widget = gtk_widget_get_accessible (label2);
8405N/A+ atk_object_add_relationship (label2Widget,ATK_RELATION_LABEL_FOR,colorWidget);
8405N/A+ gtk_misc_set_alignment (GTK_MISC (label2),
8405N/A+/* gtk_misc_set_alignment (GTK_MISC (load_graph_get_labels(net_graph)->net_in),*/
8405N/A 0.0,
8405N/A 0.5);
8405N/A gtk_box_pack_start (GTK_BOX (hbox),
8405N/A- load_graph_get_labels(net_graph)->net_in,
8405N/A+/* load_graph_get_labels(net_graph)->net_in,*/
8405N/A+ label2,
8405N/A FALSE,
8405N/A FALSE,
8405N/A 0);
8405N/A
8405N/A gtk_table_attach (GTK_TABLE (table), hbox, 2, 3, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
8405N/A
8405N/A- label = gtk_label_new (_("Total:"));
8405N/A- gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
8405N/A- gtk_table_attach (GTK_TABLE (table), label, 3, 4, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
8405N/A-
8405N/A- gtk_misc_set_alignment (GTK_MISC (load_graph_get_labels(net_graph)->net_in_total),
8405N/A+ /* in order to support accessibility, add the relationship between label and button */
8405N/A+ label3 = gtk_label_new (_("Total:"));
8405N/A+ label3Widget = gtk_widget_get_accessible (label3);
8405N/A+ atk_object_add_relationship (label3Widget,ATK_RELATION_LABEL_FOR,colorWidget);
8405N/A+ gtk_misc_set_alignment (GTK_MISC (label3), 0.0, 0.5);
8405N/A+ gtk_table_attach (GTK_TABLE (table), label3, 3, 4, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
8405N/A+
8405N/A+ /* in order to support accessibility, and to promote performance and readable,
8405N/A+ let's call the load_graph_get_labels() only once here */
8405N/A+ label4 = load_graph_get_labels(net_graph)->net_in_total;
8405N/A+ label4Widget = gtk_widget_get_accessible (label4);
8405N/A+ atk_object_add_relationship (label4Widget,ATK_RELATION_LABEL_FOR,colorWidget);
8405N/A+ gtk_misc_set_alignment (GTK_MISC (label4),
8414N/A+/* gtk_misc_set_alignment (GTK_MISC (load_graph_get_labels(net_graph)->net_in_total),*/
8414N/A 0.0,
8414N/A 0.5);
8414N/A gtk_table_attach (GTK_TABLE (table),
8414N/A- load_graph_get_labels(net_graph)->net_in_total,
8414N/A+/* load_graph_get_labels(net_graph)->net_in_total,*/
8414N/A+ label4,
8414N/A 4,
8414N/A 5,
8414N/A 0,
8414N/A@@ -554,13 +659,23 @@ create_sys_view (ProcData *procdata)
8414N/A 0,
8414N/A 0);
8414N/A
8414N/A+ /* in order to support accessibility, add the relationship between button and label */
8414N/A+ atk_object_add_relationship (colorWidget, ATK_RELATION_LABELLED_BY ,label1Widget);
8414N/A+ atk_object_add_relationship (colorWidget, ATK_RELATION_LABELLED_BY ,label2Widget);
8414N/A+ atk_object_add_relationship (colorWidget, ATK_RELATION_LABELLED_BY ,label3Widget);
8414N/A+ atk_object_add_relationship (colorWidget, ATK_RELATION_LABELLED_BY ,label4Widget);
8414N/A+
8414N/A color_picker = gtk_color_button_new_with_color (
8414N/A &load_graph_get_colors(net_graph)[3]);
8414N/A+ colorWidget = gtk_widget_get_accessible (color_picker);
8414N/A g_signal_connect (G_OBJECT (color_picker), "color_set",
8414N/A G_CALLBACK (cb_net_out_color_changed), procdata);
8414N/A gtk_table_attach (GTK_TABLE (table), color_picker, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
8414N/A
8414N/A label = gtk_label_new (_("Sent:"));
8414N/A+ /* in order to support accessibility, add the relationship between label and button */
8414N/A+ label1Widget = gtk_widget_get_accessible (label);
8414N/A+ atk_object_add_relationship (label1Widget,ATK_RELATION_LABEL_FOR,colorWidget);
8414N/A gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
8414N/A gtk_table_attach (GTK_TABLE (table), label, 1, 2, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
8414N/A
8414N/A@@ -568,26 +683,43 @@ create_sys_view (ProcData *procdata)
8414N/A g_signal_connect (G_OBJECT (hbox), "size_request",
8414N/A G_CALLBACK (net_size_request), procdata);
8414N/A
8414N/A- gtk_misc_set_alignment (GTK_MISC (load_graph_get_labels(net_graph)->net_out),
8414N/A+ /* in order to support accessibility, and to promote performance and readable,
8414N/A+ let's call the load_graph_get_labels() only once here */
8414N/A+ label2 = load_graph_get_labels(net_graph)->net_out;
8414N/A+ label2Widget = gtk_widget_get_accessible (label2);
8414N/A+ atk_object_add_relationship (label2Widget,ATK_RELATION_LABEL_FOR,colorWidget);
8414N/A+ gtk_misc_set_alignment (GTK_MISC (label2),
8414N/A+/* gtk_misc_set_alignment (GTK_MISC (load_graph_get_labels(net_graph)->net_out),*/
8414N/A 0.0,
8414N/A 0.5);
8414N/A gtk_box_pack_start (GTK_BOX (hbox),
8414N/A- load_graph_get_labels(net_graph)->net_out,
8405N/A+/* load_graph_get_labels(net_graph)->net_out,*/
8405N/A+ label2,
8405N/A FALSE,
8405N/A FALSE,
8405N/A 0);
8405N/A
8405N/A gtk_table_attach (GTK_TABLE (table), hbox, 2, 3, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
8405N/A
8405N/A- label = gtk_label_new (_("Total:"));
8405N/A- gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
8405N/A- gtk_table_attach (GTK_TABLE (table), label, 3, 4, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
8405N/A-
8405N/A- gtk_misc_set_alignment (GTK_MISC (load_graph_get_labels(net_graph)->net_out_total),
8405N/A+ /* in order to support accessibility, add the relationship between label and button */
8403N/A+ label3 = gtk_label_new (_("Total:"));
8403N/A+ label3Widget = gtk_widget_get_accessible (label3);
8403N/A+ atk_object_add_relationship (label3Widget,ATK_RELATION_LABEL_FOR,colorWidget);
8403N/A+ gtk_misc_set_alignment (GTK_MISC (label3), 0.0, 0.5);
8403N/A+ gtk_table_attach (GTK_TABLE (table), label3, 3, 4, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
8403N/A+
8403N/A+ /* in order to support accessibility, and to promote performance and readable,
8403N/A+ let's call the load_graph_get_labels() only once here */
8403N/A+ label4 = load_graph_get_labels(net_graph)->net_out_total;
8403N/A+ label4Widget = gtk_widget_get_accessible (label4);
8403N/A+ atk_object_add_relationship (label4Widget,ATK_RELATION_LABEL_FOR,colorWidget);
8403N/A+ gtk_misc_set_alignment (GTK_MISC (label4),
8405N/A+/* gtk_misc_set_alignment (GTK_MISC (load_graph_get_labels(net_graph)->net_out_total),*/
8405N/A 0.0,
8405N/A 0.5);
8405N/A gtk_table_attach (GTK_TABLE (table),
8405N/A- load_graph_get_labels(net_graph)->net_out_total,
8405N/A+/* load_graph_get_labels(net_graph)->net_out_total,*/
8405N/A+ label4,
8405N/A 4,
8405N/A 5,
8405N/A 1,
8405N/A@@ -597,6 +729,12 @@ create_sys_view (ProcData *procdata)
8405N/A 0,
8405N/A 0);
8405N/A
8405N/A+ /* in order to support accessibility, add the relationship between button and label */
8405N/A+ atk_object_add_relationship (colorWidget, ATK_RELATION_LABELLED_BY ,label1Widget);
8405N/A+ atk_object_add_relationship (colorWidget, ATK_RELATION_LABELLED_BY ,label2Widget);
8405N/A+ atk_object_add_relationship (colorWidget, ATK_RELATION_LABELLED_BY ,label3Widget);
8405N/A+ atk_object_add_relationship (colorWidget, ATK_RELATION_LABELLED_BY ,label4Widget);
8405N/A+
8405N/A procdata->net_graph = net_graph;
8405N/A
8405N/A
8405N/Adiff -Nrup gnome-system-monitor-2.17.5/src/interface.h gnome-system-monitor-2.17.5.trunk/src/interface.h
8405N/A--- gnome-system-monitor-2.17.5/src/interface.h 2007-01-03 06:15:36.000000000 +0800
8405N/A+++ gnome-system-monitor-2.17.5.trunk/src/interface.h 2007-01-23 11:41:38.487261000 +0800
8405N/A@@ -24,9 +24,9 @@
8405N/A #include <gtk/gtk.h>
8405N/A #include "procman.h"
8405N/A
8405N/A-void create_main_window (ProcData *data) G_GNUC_INTERNAL;
8405N/A-void update_sensitivity (ProcData *data) G_GNUC_INTERNAL;
8405N/A-void do_popup_menu(ProcData *data, GdkEventButton *event) G_GNUC_INTERNAL;
8405N/A-GtkWidget * make_title_label (const char *text) G_GNUC_INTERNAL;
8405N/A+G_GNUC_INTERNAL void create_main_window (ProcData *data);
8405N/A+G_GNUC_INTERNAL void update_sensitivity (ProcData *data);
8405N/A+G_GNUC_INTERNAL void do_popup_menu(ProcData *data, GdkEventButton *event);
8405N/A+G_GNUC_INTERNAL GtkWidget * make_title_label (const char *text);
8405N/A
8405N/A #endif /* _PROCMAN_INTERFACE_H_ */
8405N/Adiff -Nrup gnome-system-monitor-2.17.5/src/load-graph.cpp gnome-system-monitor-2.17.5.trunk/src/load-graph.cpp
8403N/A--- gnome-system-monitor-2.17.5/src/load-graph.cpp 2007-01-03 06:15:36.000000000 +0800
8403N/A+++ gnome-system-monitor-2.17.5.trunk/src/load-graph.cpp 2007-01-23 11:41:38.514502000 +0800
8403N/A@@ -347,6 +347,20 @@ get_net (LoadGraph *g)
8403N/A float din, dout;
8403N/A gchar *text1, *text2;
8403N/A
8403N/A+ /* we have to optimize the performance of libgtop, because in some low level machine,
8403N/A+ to update the information will occupy too much cpu.
8403N/A+
8403N/A+ here I would like to make a little update:set glibtop_netlist.flags=1,so as to let glibtop_get_netlist()
8403N/A+ only return the ones whose first character of name is the same with the first one in their module,
8403N/A+ glibtop_get_netload() just try to find these devices, for example, bge0 and bge...
8403N/A+
8403N/A+ we do the check in glibtop_get_netlist(), I think this will accelerate the transaction lots,
8403N/A+ Also this will not affect the existing codes, because when nobody set glibtop_netlist.flags,
8403N/A+ glibtop_get_netlist() will return all devices with class "net".
8403N/A+ */
8403N/A+
8403N/A+ netlist.flags = 1;
8403N/A+
8403N/A ifnames = glibtop_get_netlist(&netlist);
8403N/A
8403N/A for (i = 0; i < netlist.number; ++i)
8403N/Adiff -Nrup gnome-system-monitor-2.17.5/src/load-graph.cpp~ gnome-system-monitor-2.17.5.trunk/src/load-graph.cpp~
8403N/A--- gnome-system-monitor-2.17.5/src/load-graph.cpp~ 1970-01-01 08:00:00.000000000 +0800
8403N/A+++ gnome-system-monitor-2.17.5.trunk/src/load-graph.cpp~ 2007-01-23 11:41:38.527761000 +0800
8403N/A@@ -0,0 +1,662 @@
8403N/A+#include <config.h>
8403N/A+#include <stdio.h>
8403N/A+#include <sys/stat.h>
8403N/A+#include <unistd.h>
8403N/A+#include <signal.h>
8403N/A+#include <dirent.h>
8403N/A+#include <string.h>
8403N/A+#include <time.h>
8403N/A+#include <gdk/gdkx.h>
8403N/A+
8403N/A+#include <glib/gi18n.h>
8403N/A+
8403N/A+#include <glibtop.h>
8403N/A+#include <glibtop/cpu.h>
8403N/A+#include <glibtop/mem.h>
8403N/A+#include <glibtop/swap.h>
8403N/A+#include <glibtop/netload.h>
8403N/A+#include <glibtop/netlist.h>
8403N/A+
8403N/A+#include <libgnomevfs/gnome-vfs-utils.h>
8403N/A+
8403N/A+#include "procman.h"
8403N/A+#include "load-graph.h"
8403N/A+#include "util.h"
8403N/A+
8403N/A+#define NUM_POINTS 100
8403N/A+#define GRAPH_MIN_HEIGHT 30
8403N/A+
8403N/A+
8403N/A+enum {
8403N/A+ CPU_TOTAL,
8403N/A+ CPU_USED,
8403N/A+ N_CPU_STATES
8403N/A+};
8403N/A+
8403N/A+struct _LoadGraph {
8403N/A+
8403N/A+ guint n;
8403N/A+ gint type;
8403N/A+ guint speed;
8403N/A+ guint draw_width, draw_height;
8403N/A+
8403N/A+ GdkColor *colors;
8403N/A+
8403N/A+ gfloat* data_block;
8405N/A+ gfloat* data[NUM_POINTS];
8405N/A+
8405N/A+ GtkWidget *main_widget;
8405N/A+ GtkWidget *disp;
8405N/A+
8405N/A+ cairo_surface_t *buffer;
8405N/A+
8405N/A+ guint timer_index;
8405N/A+
8405N/A+ gboolean draw;
8405N/A+
8405N/A+ LoadGraphLabels labels;
8405N/A+
8405N/A+ /* union { */
8405N/A+ struct {
8405N/A+ gboolean initialized;
8405N/A+ guint now; /* 0 -> current, 1 -> last
8405N/A+ now ^ 1 each time */
8405N/A+ /* times[now], times[now ^ 1] is last */
8405N/A+ guint64 times[2][GLIBTOP_NCPU][N_CPU_STATES];
8405N/A+ } cpu;
8405N/A+
8405N/A+ struct {
8405N/A+ guint64 last_in, last_out;
8405N/A+ GTimeVal time;
8405N/A+ float max;
8405N/A+ } net;
8405N/A+ /* }; */
8405N/A+};
8405N/A+
8405N/A+
8405N/A+
8405N/A+#define FRAME_WIDTH 4
8405N/A+
8405N/A+
8405N/A+/* Redraws the backing buffer for the load graph and updates the window */
8405N/A+void
8405N/A+load_graph_draw (LoadGraph *g)
8405N/A+{
8405N/A+ const double fontsize = 12.0;
8405N/A+ const double rmargin = 3.5 * fontsize;
8405N/A+ cairo_t *cr;
8405N/A+ int dely;
8405N/A+ double delx;
8405N/A+ int real_draw_height;
8405N/A+ guint i, j;
8405N/A+
8405N/A+ cr = cairo_create (g->buffer);
8405N/A+
8405N/A+ /* clear */
8405N/A+ gdk_cairo_set_source_color (cr, &(g->colors [0]));
8405N/A+ cairo_paint (cr);
8405N/A+
8405N/A+ /* draw frame */
8403N/A+ cairo_translate (cr, FRAME_WIDTH, FRAME_WIDTH);
8403N/A+ gdk_cairo_set_source_color (cr, &(g->colors [1]));
8403N/A+ cairo_set_line_width (cr, 1.0);
8403N/A+ cairo_select_font_face(cr,
8403N/A+ "monospace",
8403N/A+ CAIRO_FONT_SLANT_NORMAL,
8403N/A+ CAIRO_FONT_WEIGHT_NORMAL);
8403N/A+ cairo_set_font_size(cr, fontsize);
8403N/A+
8403N/A+ dely = (g->draw_height) / 5; /* round to int to avoid AA blur */
8403N/A+ real_draw_height = dely * 5;
8403N/A+
8403N/A+ for (i = 0; i <= 5; ++i) {
8403N/A+ char *caption;
8403N/A+ double y;
8403N/A+
8403N/A+ switch (i) {
8403N/A+ case 0:
8403N/A+ y = 0.5 + fontsize / 2.0;
8403N/A+ break;
8403N/A+ case 5:
8403N/A+ y = i * dely + 0.5;
8403N/A+ break;
8403N/A+ default:
8405N/A+ y = i * dely + fontsize / 2.0;
8405N/A+ break;
8405N/A+ }
8405N/A+
8405N/A+ cairo_move_to(cr, 0.0, y);
8405N/A+ caption = g_strdup_printf("%3d %%", 100 - i * 20);
8405N/A+ cairo_show_text(cr, caption);
8405N/A+ g_free(caption);
8405N/A+
8405N/A+ cairo_move_to (cr, rmargin, i * dely + 0.5);
8405N/A+ cairo_line_to (cr, g->draw_width - 0.5, i * dely + 0.5);
8405N/A+ }
8405N/A+
8405N/A+ cairo_move_to (cr, rmargin, 0.5);
8405N/A+ cairo_line_to (cr, rmargin, real_draw_height + 0.5);
8405N/A+
8405N/A+ cairo_move_to (cr, g->draw_width - 0.5, 0.5);
8405N/A+ cairo_line_to (cr, g->draw_width - 0.5, real_draw_height + 0.5);
8405N/A+
8405N/A+ cairo_stroke (cr);
8405N/A+
8405N/A+ /* draw the graph */
8405N/A+ cairo_set_line_width (cr, 2.0);
8405N/A+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
8405N/A+ cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
8405N/A+
8405N/A+ delx = (g->draw_width - 2.0 - rmargin) / (NUM_POINTS - 1);
8405N/A+
8405N/A+ for (j = 0; j < g->n; ++j) {
8405N/A+ cairo_move_to (cr,
8405N/A+ g->draw_width - 2.0,
8405N/A+ (1.0f - g->data[0][j]) * real_draw_height);
8405N/A+ gdk_cairo_set_source_color (cr, &(g->colors [j + 2]));
8405N/A+
8405N/A+ for (i = 1; i < NUM_POINTS; ++i) {
8405N/A+ if (g->data[i][j] == -1.0f)
8405N/A+ continue;
8405N/A+
8405N/A+ cairo_line_to (cr,
8405N/A+ g->draw_width - i * delx,
8405N/A+ (1.0f - g->data[i][j]) * real_draw_height);
8405N/A+ }
8405N/A+
8405N/A+ cairo_stroke (cr);
8405N/A+ }
8405N/A+
8405N/A+ cairo_destroy (cr);
8405N/A+
8405N/A+ /* repaint */
8405N/A+ gtk_widget_queue_draw (g->disp);
8405N/A+}
8405N/A+
8405N/A+static gboolean
8405N/A+load_graph_configure (GtkWidget *widget,
8405N/A+ GdkEventConfigure *event,
8405N/A+ gpointer data_ptr)
8405N/A+{
8405N/A+ LoadGraph * const g = static_cast<LoadGraph*>(data_ptr);
8405N/A+ cairo_t *cr;
8405N/A+
8405N/A+ g->draw_width = widget->allocation.width - 2 * FRAME_WIDTH;
8405N/A+ g->draw_height = widget->allocation.height - 2 * FRAME_WIDTH;
8405N/A+
8405N/A+ cr = gdk_cairo_create (widget->window);
8405N/A+
8405N/A+ if (g->buffer)
8405N/A+ cairo_surface_destroy (g->buffer);
8405N/A+
8405N/A+ g->buffer = cairo_surface_create_similar (cairo_get_target (cr),
8405N/A+ CAIRO_CONTENT_COLOR,
8405N/A+ widget->allocation.width,
8405N/A+ widget->allocation.height);
8405N/A+
8405N/A+ cairo_destroy (cr);
8405N/A+
8405N/A+ load_graph_draw (g);
8405N/A+
8405N/A+ return TRUE;
+}
+
+static gboolean
+load_graph_expose (GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer data_ptr)
+{
+ LoadGraph * const g = static_cast<LoadGraph*>(data_ptr);
+ cairo_t *cr;
+
+ cr = gdk_cairo_create(widget->window);
+
+ cairo_set_source_surface(cr, g->buffer, 0, 0);
+ cairo_rectangle(cr,
+ event->area.x, event->area.y,
+ event->area.width, event->area.height);
+ cairo_fill(cr);
+
+ cairo_destroy(cr);
+
+ return TRUE;
+}
+
+static void
+get_load (LoadGraph *g)
+{
+ guint i;
+ glibtop_cpu cpu;
+
+ glibtop_get_cpu (&cpu);
+
+#undef NOW
+#undef LAST
+#define NOW (g->cpu.times[g->cpu.now])
+#define LAST (g->cpu.times[g->cpu.now ^ 1])
+
+ if (g->n == 1) {
+ NOW[0][CPU_TOTAL] = cpu.total;
+ NOW[0][CPU_USED] = cpu.user + cpu.nice + cpu.sys;
+ } else {
+ for (i = 0; i < g->n; i++) {
+ NOW[i][CPU_TOTAL] = cpu.xcpu_total[i];
+ NOW[i][CPU_USED] = cpu.xcpu_user[i] + cpu.xcpu_nice[i]
+ + cpu.xcpu_sys[i];
+ }
+ }
+
+ if (G_UNLIKELY(!g->cpu.initialized)) {
+ /* No data yet */
+ g->cpu.initialized = TRUE;
+ } else {
+ for (i = 0; i < g->n; i++) {
+ float load;
+ float total, used;
+ gchar *text;
+
+ total = NOW[i][CPU_TOTAL] - LAST[i][CPU_TOTAL];
+ used = NOW[i][CPU_USED] - LAST[i][CPU_USED];
+
+ load = used / MAX(total, 1.0f);
+ g->data[0][i] = load;
+
+ /* Update label */
+ text = g_strdup_printf("%.1f%%", load * 100.0f);
+ gtk_label_set_text(GTK_LABEL(g->labels.cpu[i]), text);
+ g_free(text);
+ }
+ }
+
+ g->cpu.now ^= 1;
+
+#undef NOW
+#undef LAST
+}
+
+
+static void
+get_memory (LoadGraph *g)
+{
+ float mempercent, swappercent;
+ gchar *text1, *text2, *text3;
+
+ glibtop_mem mem;
+ glibtop_swap swap;
+
+ glibtop_get_mem (&mem);
+ glibtop_get_swap (&swap);
+
+ /* There's no swap on LiveCD : 0.0f is better than NaN :) */
+ swappercent = (swap.total ? (float)swap.used / (float)swap.total : 0.0f);
+ mempercent = (float)mem.user / (float)mem.total;
+
+ text1 = SI_gnome_vfs_format_file_size_for_display (mem.total);
+ text2 = SI_gnome_vfs_format_file_size_for_display (mem.user);
+ text3 = g_strdup_printf (" %.1f %%", mempercent * 100.0f);
+ gtk_label_set_text (GTK_LABEL (g->labels.memused), text2);
+ gtk_label_set_text (GTK_LABEL (g->labels.memtotal), text1);
+ gtk_label_set_text (GTK_LABEL (g->labels.mempercent), text3);
+ g_free (text1);
+ g_free (text2);
+ g_free (text3);
+
+ text1 = SI_gnome_vfs_format_file_size_for_display (swap.total);
+ text2 = SI_gnome_vfs_format_file_size_for_display (swap.used);
+ text3 = g_strdup_printf (" %.1f %%", swappercent * 100.0f);
+ gtk_label_set_text (GTK_LABEL (g->labels.swapused), text2);
+ gtk_label_set_text (GTK_LABEL (g->labels.swaptotal), text1);
+ gtk_label_set_text (GTK_LABEL (g->labels.swappercent), text3);
+ g_free (text1);
+ g_free (text2);
+ g_free (text3);
+
+ g->data[0][0] = mempercent;
+ g->data[0][1] = swappercent;
+}
+
+static void
+net_scale (LoadGraph *g, float new_max)
+{
+ gint i;
+ float old_max = MAX (g->net.max, 1.0f), scale;
+
+ if (new_max <= old_max)
+ return;
+
+ scale = old_max / new_max;
+
+ for (i = 0; i < NUM_POINTS; i++) {
+ if (g->data[i][0] >= 0.0f) {
+ g->data[i][0] *= scale;
+ g->data[i][1] *= scale;
+ }
+ }
+
+ g->net.max = new_max;
+}
+
+static void
+get_net (LoadGraph *g)
+{
+ glibtop_netlist netlist;
+ char **ifnames;
+ guint32 i;
+ guint64 in = 0, out = 0;
+ GTimeVal time;
+ float din, dout;
+ gchar *text1, *text2;
+
+ ifnames = glibtop_get_netlist(&netlist);
+
+ for (i = 0; i < netlist.number; ++i)
+ {
+ glibtop_netload netload;
+ glibtop_get_netload (&netload, ifnames[i]);
+
+ if (netload.if_flags & (1 << GLIBTOP_IF_FLAGS_LOOPBACK))
+ continue;
+
+ /* Don't skip interfaces that are down (GLIBTOP_IF_FLAGS_UP)
+ to avoid spikes when they are brought up */
+
+ in += netload.bytes_in;
+ out += netload.bytes_out;
+ }
+
+ g_strfreev(ifnames);
+
+ g_get_current_time (&time);
+
+ if (in >= g->net.last_in && out >= g->net.last_out &&
+ g->net.time.tv_sec != 0) {
+ float dtime;
+ dtime = time.tv_sec - g->net.time.tv_sec +
+ (float) (time.tv_usec - g->net.time.tv_usec) / G_USEC_PER_SEC;
+ din = (in - g->net.last_in) / dtime;
+ dout = (out - g->net.last_out) / dtime;
+ } else {
+ /* Don't calc anything if new data is less than old (interface
+ removed, counters reset, ...) or if it is the first time */
+ din = 0.0f;
+ dout = 0.0f;
+ }
+
+ g->net.last_in = in;
+ g->net.last_out = out;
+ g->net.time = time;
+
+ g->data[0][0] = din / MAX(g->net.max, 1.0f);
+ g->data[0][1] = dout / MAX(g->net.max, 1.0f);
+
+ net_scale (g, MAX (din, dout));
+
+ text1 = SI_gnome_vfs_format_file_size_for_display (din);
+ text2 = g_strdup_printf (_("%s/s"), text1);
+ gtk_label_set_text (GTK_LABEL (g->labels.net_in), text2);
+ g_free (text1);
+ g_free (text2);
+
+ text1 = SI_gnome_vfs_format_file_size_for_display (in);
+ gtk_label_set_text (GTK_LABEL (g->labels.net_in_total), text1);
+ g_free (text1);
+
+ text1 = SI_gnome_vfs_format_file_size_for_display (dout);
+ text2 = g_strdup_printf (_("%s/s"), text1);
+ gtk_label_set_text (GTK_LABEL (g->labels.net_out), text2);
+ g_free (text1);
+ g_free (text2);
+
+ text1 = SI_gnome_vfs_format_file_size_for_display (out);
+ gtk_label_set_text (GTK_LABEL (g->labels.net_out_total), text1);
+ g_free (text1);
+}
+
+
+/*
+ Shifts data right
+
+ data[i+1] = data[i]
+
+ data[i] are float*, so we just move the pointer, not the data.
+ But moving data loses data[n-1], so we save data[n-1] and reuse
+ it as new data[0]. In fact, we rotate data[].
+
+*/
+
+static void
+shift_right(LoadGraph *g)
+{
+ unsigned i;
+ float* last_data;
+
+ /* data[NUM_POINTS - 1] becomes data[0] */
+ last_data = g->data[NUM_POINTS - 1];
+
+ /* data[i+1] = data[i] */
+ for(i = NUM_POINTS - 1; i != 0; --i)
+ g->data[i] = g->data[i-1];
+
+ g->data[0] = last_data;
+}
+
+/* Updates the load graph when the timeout expires */
+static gboolean
+load_graph_update (gpointer user_data)
+{
+ LoadGraph * const g = static_cast<LoadGraph*>(user_data);
+
+ shift_right(g);
+
+ switch (g->type) {
+ case LOAD_GRAPH_CPU:
+ get_load(g);
+ break;
+ case LOAD_GRAPH_MEM:
+ get_memory(g);
+ break;
+ case LOAD_GRAPH_NET:
+ get_net(g);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ if (g->draw)
+ load_graph_draw (g);
+
+ return TRUE;
+}
+
+static void
+load_graph_unalloc (LoadGraph *g)
+{
+ g_free(g->data_block);
+
+ if (g->buffer) {
+ cairo_surface_destroy (g->buffer);
+ g->buffer = NULL;
+ }
+}
+
+static void
+load_graph_alloc (LoadGraph *g)
+{
+ guint i, j;
+
+ /* Allocate data in a contiguous block */
+ g->data_block = g_new(float, g->n * NUM_POINTS);
+
+ for (i = 0; i < NUM_POINTS; ++i) {
+ g->data[i] = g->data_block + i * g->n;
+ for (j = 0; j < g->n; ++j)
+ g->data[i][j] = -1.0f;
+ }
+}
+
+static gboolean
+load_graph_destroy (GtkWidget *widget, gpointer data_ptr)
+{
+ LoadGraph * const g = static_cast<LoadGraph*>(data_ptr);
+
+ load_graph_stop (g);
+
+ if (g->timer_index)
+ g_source_remove (g->timer_index);
+
+ load_graph_unalloc(g);
+
+ return FALSE;
+}
+
+LoadGraph *
+load_graph_new (gint type, ProcData *procdata)
+{
+ LoadGraph *g;
+ guint i = 0;
+
+ g = g_new0 (LoadGraph, 1);
+
+ g->type = type;
+ switch (type) {
+ case LOAD_GRAPH_CPU:
+ if (procdata->config.num_cpus == 0)
+ g->n = 1;
+ else
+ g->n = procdata->config.num_cpus;
+
+ for(i = 0; i < G_N_ELEMENTS(g->labels.cpu); ++i)
+ g->labels.cpu[i] = gtk_label_new(NULL);
+
+ break;
+
+ case LOAD_GRAPH_MEM:
+ g->n = 2;
+ g->labels.memused = gtk_label_new(NULL);
+ g->labels.memtotal = gtk_label_new(NULL);
+ g->labels.mempercent = gtk_label_new(NULL);
+ g->labels.swapused = gtk_label_new(NULL);
+ g->labels.swaptotal = gtk_label_new(NULL);
+ g->labels.swappercent = gtk_label_new(NULL);
+ break;
+
+ case LOAD_GRAPH_NET:
+ g->n = 2;
+ g->labels.net_in = gtk_label_new(NULL);
+ g->labels.net_in_total = gtk_label_new(NULL);
+ g->labels.net_out = gtk_label_new(NULL);
+ g->labels.net_out_total = gtk_label_new(NULL);
+ break;
+ }
+
+ g->speed = procdata->config.graph_update_interval;
+
+ g->colors = g_new0 (GdkColor, g->n + 2);
+
+ g->colors[0] = procdata->config.bg_color;
+ g->colors[1] = procdata->config.frame_color;
+ switch (type) {
+ case LOAD_GRAPH_CPU:
+ memcpy(g->colors + 2, procdata->config.cpu_color,
+ g->n * sizeof g->colors[0]);
+ break;
+ case LOAD_GRAPH_MEM:
+ g->colors[2] = procdata->config.mem_color;
+ g->colors[3] = procdata->config.swap_color;
+ break;
+ case LOAD_GRAPH_NET:
+ g->colors[2] = procdata->config.net_in_color;
+ g->colors[3] = procdata->config.net_out_color;
+ break;
+ }
+
+ g->timer_index = 0;
+
+ g->draw = FALSE;
+
+ g->main_widget = gtk_vbox_new (FALSE, FALSE);
+ gtk_widget_set_size_request(g->main_widget, -1, GRAPH_MIN_HEIGHT);
+ gtk_widget_show (g->main_widget);
+
+ g->disp = gtk_drawing_area_new ();
+ gtk_widget_show (g->disp);
+ g_signal_connect (G_OBJECT (g->disp), "expose_event",
+ G_CALLBACK (load_graph_expose), g);
+ g_signal_connect (G_OBJECT(g->disp), "configure_event",
+ G_CALLBACK (load_graph_configure), g);
+ g_signal_connect (G_OBJECT(g->disp), "destroy",
+ G_CALLBACK (load_graph_destroy), g);
+
+ gtk_widget_set_events (g->disp, GDK_EXPOSURE_MASK);
+
+ gtk_box_pack_start (GTK_BOX (g->main_widget), g->disp, TRUE, TRUE, 0);
+
+ load_graph_alloc (g);
+
+ gtk_widget_show_all (g->main_widget);
+
+ load_graph_start(g);
+ load_graph_stop(g);
+
+ return g;
+}
+
+void
+load_graph_start (LoadGraph *g)
+{
+ if(!g->timer_index) {
+
+ load_graph_update(g);
+
+ g->timer_index = g_timeout_add (g->speed,
+ load_graph_update,
+ g);
+ }
+
+ g->draw = TRUE;
+}
+
+void
+load_graph_stop (LoadGraph *g)
+{
+ /* don't draw anymore, but continue to poll */
+ g->draw = FALSE;
+}
+
+void
+load_graph_change_speed (LoadGraph *g,
+ guint new_speed)
+{
+ if (g->speed == new_speed)
+ return;
+
+ g->speed = new_speed;
+
+ g_assert(g->timer_index);
+
+ if(g->timer_index) {
+ g_source_remove (g->timer_index);
+ g->timer_index = g_timeout_add (g->speed,
+ load_graph_update,
+ g);
+ }
+}
+
+GdkColor*
+load_graph_get_colors (LoadGraph *g)
+{
+ return g->colors;
+}
+
+
+LoadGraphLabels*
+load_graph_get_labels (LoadGraph *g)
+{
+ return &g->labels;
+}
+
+GtkWidget*
+load_graph_get_widget (LoadGraph *g)
+{
+ return g->main_widget;
+}
diff -Nrup gnome-system-monitor-2.17.5/src/load-graph.h gnome-system-monitor-2.17.5.trunk/src/load-graph.h
--- gnome-system-monitor-2.17.5/src/load-graph.h 2007-01-03 06:15:36.000000000 +0800
+++ gnome-system-monitor-2.17.5.trunk/src/load-graph.h 2007-01-23 11:41:38.516172000 +0800
@@ -34,34 +34,34 @@ struct _LoadGraphLabels
/* Create new load graph. */
-LoadGraph *
-load_graph_new (gint type, ProcData *procdata) G_GNUC_INTERNAL;
+G_GNUC_INTERNAL LoadGraph *
+load_graph_new (gint type, ProcData *procdata);
/* Force a drawing update */
-void
-load_graph_draw (LoadGraph *g) G_GNUC_INTERNAL;
+G_GNUC_INTERNAL void
+load_graph_draw (LoadGraph *g);
/* Start load graph. */
-void
-load_graph_start (LoadGraph *g) G_GNUC_INTERNAL;
+G_GNUC_INTERNAL void
+load_graph_start (LoadGraph *g);
/* Stop load graph. */
-void
-load_graph_stop (LoadGraph *g) G_GNUC_INTERNAL;
+G_GNUC_INTERNAL void
+load_graph_stop (LoadGraph *g);
/* Change load graph speed and restart it if it has been previously started */
-void
+G_GNUC_INTERNAL void
load_graph_change_speed (LoadGraph *g,
- guint new_speed) G_GNUC_INTERNAL;
+ guint new_speed);
-GdkColor*
-load_graph_get_colors (LoadGraph *g) G_GNUC_INTERNAL G_GNUC_CONST;
+G_GNUC_INTERNAL GdkColor*
+load_graph_get_colors (LoadGraph *g) G_GNUC_CONST;
-LoadGraphLabels*
-load_graph_get_labels (LoadGraph *g) G_GNUC_INTERNAL G_GNUC_CONST;
+G_GNUC_INTERNAL LoadGraphLabels*
+load_graph_get_labels (LoadGraph *g) G_GNUC_CONST;
-GtkWidget*
-load_graph_get_widget (LoadGraph *g) G_GNUC_INTERNAL G_GNUC_CONST;
+G_GNUC_INTERNAL GtkWidget*
+load_graph_get_widget (LoadGraph *g) G_GNUC_CONST;
#endif /* _PROCMAN_LOAD_GRAPH_H_ */
diff -Nrup gnome-system-monitor-2.17.5/src/memmaps.h gnome-system-monitor-2.17.5.trunk/src/memmaps.h
--- gnome-system-monitor-2.17.5/src/memmaps.h 2007-01-03 06:15:36.000000000 +0800
+++ gnome-system-monitor-2.17.5.trunk/src/memmaps.h 2007-01-23 11:41:38.527136000 +0800
@@ -4,6 +4,6 @@
#include <glib.h>
#include "procman.h"
-void create_memmaps_dialog (ProcData *procdata) G_GNUC_INTERNAL;
+G_GNUC_INTERNAL void create_memmaps_dialog (ProcData *procdata);
#endif /* _PROCMAN_MEMMAPS_H_ */
diff -Nrup gnome-system-monitor-2.17.5/src/openfiles.h gnome-system-monitor-2.17.5.trunk/src/openfiles.h
--- gnome-system-monitor-2.17.5/src/openfiles.h 2007-01-03 06:15:36.000000000 +0800
+++ gnome-system-monitor-2.17.5.trunk/src/openfiles.h 2007-01-23 11:41:38.487429000 +0800
@@ -5,6 +5,6 @@
#include "procman.h"
-void create_openfiles_dialog (ProcData *procdata) G_GNUC_INTERNAL;
+G_GNUC_INTERNAL void create_openfiles_dialog (ProcData *procdata);
#endif
diff -Nrup gnome-system-monitor-2.17.5/src/procactions.cpp gnome-system-monitor-2.17.5.trunk/src/procactions.cpp
--- gnome-system-monitor-2.17.5/src/procactions.cpp 2007-01-03 06:15:36.000000000 +0800
+++ gnome-system-monitor-2.17.5.trunk/src/procactions.cpp 2007-01-23 11:41:38.516717000 +0800
@@ -128,6 +128,14 @@ kill_single_process (GtkTreeModel *model
if (!info)
return;
+ /*
+ * If the process 0 is a system process, we can't control it even as root
+ */
+ if ((args->signal == SIGTERM) || (args->signal == SIGKILL)){
+ if (info->pid == 0)
+ return;
+ }
+ /* if it is not a system process, we can kill it now */
error = kill (info->pid, args->signal);
/* success */
diff -Nrup gnome-system-monitor-2.17.5/src/procactions.h gnome-system-monitor-2.17.5.trunk/src/procactions.h
--- gnome-system-monitor-2.17.5/src/procactions.h 2007-01-03 06:15:36.000000000 +0800
+++ gnome-system-monitor-2.17.5.trunk/src/procactions.h 2007-01-23 11:41:38.488994000 +0800
@@ -21,8 +21,8 @@
#include "procman.h"
-void renice (ProcData *procdata, int nice) G_GNUC_INTERNAL;
-void kill_process (ProcData *procdata, int sig) G_GNUC_INTERNAL;
+G_GNUC_INTERNAL void renice (ProcData *procdata, int nice);
+G_GNUC_INTERNAL void kill_process (ProcData *procdata, int sig);
#endif
diff -Nrup gnome-system-monitor-2.17.5/src/procdialogs.cpp gnome-system-monitor-2.17.5.trunk/src/procdialogs.cpp
--- gnome-system-monitor-2.17.5/src/procdialogs.cpp 2007-01-06 22:35:14.000000000 +0800
+++ gnome-system-monitor-2.17.5.trunk/src/procdialogs.cpp 2007-01-23 14:34:54.093476000 +0800
@@ -334,6 +334,7 @@ smooth_refresh_toggled(GtkToggleButton *
gboolean toggled;
toggled = gtk_toggle_button_get_active(button);
+ /*toggled = TRUE; gtk_toggle_button_get_active(button);*/
gconf_client_set_bool(client, SmoothRefresh::KEY.c_str(), toggled, NULL);
}
@@ -705,7 +706,10 @@ procdialog_create_preferences_dialog (Pr
gtk_box_pack_start (GTK_BOX (hbox2), hbox3, TRUE, TRUE, 0);
update = (gfloat) procdata->config.graph_update_interval;
- adjustment = (GtkAdjustment *) gtk_adjustment_new(update / 1000.0, 0.25,
+ /* The interval is too small, and in some low level machine,
+ cause gconf can't work, so set its min value 1 sec*/
+ /*adjustment = (GtkAdjustment *) gtk_adjustment_new(update / 1000.0, 0.25,*/
+ adjustment = (GtkAdjustment *) gtk_adjustment_new(update / 1000.0, 1,
100.0, 0.25, 1.0, 1.0);
spin_button = gtk_spin_button_new (adjustment, 1.0, 2);
g_signal_connect (G_OBJECT (spin_button), "focus_out_event",
diff -Nrup gnome-system-monitor-2.17.5/src/procdialogs.h gnome-system-monitor-2.17.5.trunk/src/procdialogs.h
--- gnome-system-monitor-2.17.5/src/procdialogs.h 2007-01-03 06:15:36.000000000 +0800
+++ gnome-system-monitor-2.17.5.trunk/src/procdialogs.h 2007-01-23 11:41:38.526708000 +0800
@@ -42,14 +42,14 @@ typedef enum
} ProcmanActionType;
-void procdialog_create_hide_dialog (ProcData *data) G_GNUC_INTERNAL;
-void procdialog_create_kill_dialog (ProcData *data, int signal) G_GNUC_INTERNAL;
-void procdialog_create_renice_dialog (ProcData *data) G_GNUC_INTERNAL;
-gboolean procdialog_create_root_password_dialog (ProcmanActionType type,
+G_GNUC_INTERNAL void procdialog_create_hide_dialog (ProcData *data);
+G_GNUC_INTERNAL void procdialog_create_kill_dialog (ProcData *data, int signal);
+G_GNUC_INTERNAL void procdialog_create_renice_dialog (ProcData *data);
+G_GNUC_INTERNAL gboolean procdialog_create_root_password_dialog (ProcmanActionType type,
ProcData *procdata,
- gint pid, gint extra_value) G_GNUC_INTERNAL;
-void procdialog_create_memmaps_dialog (ProcData *data) G_GNUC_INTERNAL;
-void procdialog_create_preferences_dialog (ProcData *data) G_GNUC_INTERNAL;
+ gint pid, gint extra_value);
+G_GNUC_INTERNAL void procdialog_create_memmaps_dialog (ProcData *data);
+G_GNUC_INTERNAL void procdialog_create_preferences_dialog (ProcData *data);
#endif
diff -Nrup gnome-system-monitor-2.17.5/src/procman.cpp gnome-system-monitor-2.17.5.trunk/src/procman.cpp
--- gnome-system-monitor-2.17.5/src/procman.cpp 2007-01-07 09:08:02.000000000 +0800
+++ gnome-system-monitor-2.17.5.trunk/src/procman.cpp 2007-01-23 11:41:38.489448000 +0800
@@ -115,7 +115,10 @@ timeouts_changed_cb (GConfClient *client
procdata->config.graph_update_interval = gconf_value_get_int (value);
procdata->config.graph_update_interval =
MAX (procdata->config.graph_update_interval,
- 250);
+ /* The interval is too small, and in some low level machine,
+ cause gconf can't work, so set its min value 1 sec*/
+ /* 250);*/
+ 1000);
load_graph_change_speed(procdata->cpu_graph,
procdata->config.graph_update_interval);
load_graph_change_speed(procdata->mem_graph,
@@ -364,7 +367,10 @@ procman_data_new (GConfClient *client)
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);
+ /* The interval is too small, and in some low level machine,
+ cause gconf can't work, so set its min value 1 sec*/
+ /*pd->config.graph_update_interval = MAX (pd->config.graph_update_interval, 250);*/
+ pd->config.graph_update_interval = MAX (pd->config.graph_update_interval, 1000);
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,
diff -Nrup gnome-system-monitor-2.17.5/src/procman.cpp~ gnome-system-monitor-2.17.5.trunk/src/procman.cpp~
--- gnome-system-monitor-2.17.5/src/procman.cpp~ 1970-01-01 08:00:00.000000000 +0800
+++ gnome-system-monitor-2.17.5.trunk/src/procman.cpp~ 2007-01-23 11:41:38.528082000 +0800
@@ -0,0 +1,737 @@
+/* Procman
+ * Copyright (C) 2001 Kevin Vandersloot
+ *
+ * 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 Library 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 <config.h>
+
+#include <stdlib.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <gnome.h>
+#include <bacon-message-connection.h>
+#include <libgnomevfs/gnome-vfs.h>
+#include <gconf/gconf-client.h>
+#include <glibtop.h>
+#include <glibtop/close.h>
+#include <glibtop/loadavg.h>
+
+#include "load-graph.h"
+#include "procman.h"
+#include "interface.h"
+#include "proctable.h"
+#include "prettytable.h"
+#include "favorites.h"
+#include "callbacks.h"
+#include "smooth_refresh.h"
+
+
+ProcData* ProcData::get_instance()
+{
+ static ProcData instance;
+ return &instance;
+}
+
+
+static void
+tree_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
+{
+ ProcData *procdata = static_cast<ProcData*>(data);
+ GConfValue *value = gconf_entry_get_value (entry);
+
+ procdata->config.show_tree = gconf_value_get_bool (value);
+ proctable_clear_tree (procdata);
+ proctable_update_all (procdata);
+
+}
+
+static void
+view_as_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
+{
+ ProcData *procdata = static_cast<ProcData*>(data);
+ GConfValue *value = gconf_entry_get_value (entry);
+
+ procdata->config.whose_process = gconf_value_get_int (value);
+ procdata->config.whose_process = CLAMP (procdata->config.whose_process, 0, 2);
+ proctable_clear_tree (procdata);
+ proctable_update_all (procdata);
+
+}
+
+static void
+warning_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
+{
+ ProcData *procdata = static_cast<ProcData*>(data);
+ const gchar *key = gconf_entry_get_key (entry);
+ GConfValue *value = gconf_entry_get_value (entry);
+
+ if (g_str_equal (key, "/apps/procman/kill_dialog")) {
+ procdata->config.show_kill_warning = gconf_value_get_bool (value);
+ }
+ else {
+ procdata->config.show_hide_message = gconf_value_get_bool (value);
+ }
+}
+
+static void
+timeouts_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
+{
+ ProcData *procdata = static_cast<ProcData*>(data);
+ const gchar *key = gconf_entry_get_key (entry);
+ GConfValue *value = gconf_entry_get_value (entry);
+
+ if (g_str_equal (key, "/apps/procman/update_interval")) {
+ procdata->config.update_interval = gconf_value_get_int (value);
+ 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, "/apps/procman/graph_update_interval")){
+ procdata->config.graph_update_interval = gconf_value_get_int (value);
+ 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, "/apps/procman/disks_interval")) {
+
+ procdata->config.disks_update_interval = gconf_value_get_int (value);
+ 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 (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
+{
+ ProcData * const procdata = static_cast<ProcData*>(data);
+ const gchar *key = gconf_entry_get_key (entry);
+ GConfValue *value = gconf_entry_get_value (entry);
+ const gchar *color = gconf_value_get_string (value);
+
+ if (g_str_equal (key, "/apps/procman/bg_color")) {
+ gdk_color_parse (color, &procdata->config.bg_color);
+ load_graph_get_colors(procdata->cpu_graph)[0] = procdata->config.bg_color;
+ load_graph_get_colors(procdata->mem_graph)[0] = procdata->config.bg_color;
+ load_graph_get_colors(procdata->net_graph)[0] = procdata->config.bg_color;
+ }
+ else if (g_str_equal (key, "/apps/procman/frame_color")) {
+ gdk_color_parse (color, &procdata->config.frame_color);
+ load_graph_get_colors(procdata->cpu_graph)[1] = procdata->config.frame_color;
+ load_graph_get_colors(procdata->mem_graph)[1] = procdata->config.frame_color;
+ load_graph_get_colors(procdata->net_graph)[1] = procdata->config.frame_color;
+ }
+ else if (g_str_equal (key, "/apps/procman/cpu_color")) {
+ gdk_color_parse (color, &procdata->config.cpu_color[0]);
+ load_graph_get_colors(procdata->cpu_graph)[2] = procdata->config.cpu_color[0];
+ }
+ else if (g_str_has_prefix (key, "/apps/procman/cpu_color")) {
+ gint i;
+
+ for (i=1;i<GLIBTOP_NCPU;i++) {
+ gchar *cpu_key;
+ cpu_key = g_strdup_printf ("/apps/procman/cpu_color%d",i);
+ if (g_str_equal (key, cpu_key)) {
+ gdk_color_parse (color, &procdata->config.cpu_color[i]);
+ load_graph_get_colors(procdata->cpu_graph)[i+2] = procdata->config.cpu_color[i];
+ }
+ g_free (cpu_key);
+ }
+ }
+ else if (g_str_equal (key, "/apps/procman/mem_color")) {
+ gdk_color_parse (color, &procdata->config.mem_color);
+ load_graph_get_colors(procdata->mem_graph)[2] = procdata->config.mem_color;
+ }
+ else if (g_str_equal (key, "/apps/procman/swap_color")) {
+ gdk_color_parse (color, &procdata->config.swap_color);
+ load_graph_get_colors(procdata->mem_graph)[3] = procdata->config.swap_color;
+ }
+ else if (g_str_equal (key, "/apps/procman/net_in_color")) {
+ gdk_color_parse (color, &procdata->config.net_in_color);
+ load_graph_get_colors(procdata->net_graph)[2] = procdata->config.net_in_color;
+ }
+ else if (g_str_equal (key, "/apps/procman/net_out_color")) {
+ gdk_color_parse (color, &procdata->config.net_out_color);
+ load_graph_get_colors(procdata->net_graph)[3] = procdata->config.net_out_color;
+ }
+ else {
+ g_assert_not_reached();
+ }
+}
+
+
+
+static void
+show_all_fs_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
+{
+ ProcData * const procdata = static_cast<ProcData*>(data);
+ GConfValue *value = gconf_entry_get_value (entry);
+
+ procdata->config.show_all_fs = gconf_value_get_bool (value);
+
+ cb_update_disks (data);
+}
+
+
+static ProcData *
+procman_data_new (GConfClient *client)
+{
+
+ ProcData *pd;
+ gchar *color;
+ gint swidth, sheight;
+ gint i;
+ glibtop_cpu cpu;
+
+ pd = ProcData::get_instance();
+
+ pd->tree = NULL;
+ pd->info = NULL;
+ pd->pids = g_hash_table_new(NULL, NULL);
+ pd->selected_process = NULL;
+ pd->timeout = 0;
+ pd->blacklist = NULL;
+ pd->cpu_graph = NULL;
+ pd->mem_graph = NULL;
+ pd->net_graph = NULL;
+ pd->disk_timeout = 0;
+
+ /* username is usually 8 chars long
+ for caching, we create chunks of 128 chars */
+ pd->users = g_string_chunk_new(128);
+ /* push empty string */
+ g_string_chunk_insert_const(pd->users, "");
+
+ pd->config.width = gconf_client_get_int (client, "/apps/procman/width", NULL);
+ pd->config.height = gconf_client_get_int (client, "/apps/procman/height", NULL);
+ pd->config.show_tree = gconf_client_get_bool (client, "/apps/procman/show_tree", NULL);
+ gconf_client_notify_add (client, "/apps/procman/show_tree", tree_changed_cb,
+ pd, NULL, NULL);
+ pd->config.show_kill_warning = gconf_client_get_bool (client, "/apps/procman/kill_dialog",
+ NULL);
+ gconf_client_notify_add (client, "/apps/procman/kill_dialog", warning_changed_cb,
+ pd, NULL, NULL);
+ pd->config.show_hide_message = gconf_client_get_bool (client, "/apps/procman/hide_message",
+ NULL);
+ gconf_client_notify_add (client, "/apps/procman/hide_message", warning_changed_cb,
+ pd, NULL, NULL);
+ pd->config.update_interval = gconf_client_get_int (client, "/apps/procman/update_interval",
+ NULL);
+ gconf_client_notify_add (client, "/apps/procman/update_interval", timeouts_changed_cb,
+ pd, NULL, NULL);
+ pd->config.graph_update_interval = gconf_client_get_int (client,
+ "/apps/procman/graph_update_interval",
+ NULL);
+ gconf_client_notify_add (client, "/apps/procman/graph_update_interval", timeouts_changed_cb,
+ pd, NULL, NULL);
+ pd->config.disks_update_interval = gconf_client_get_int (client,
+ "/apps/procman/disks_interval",
+ NULL);
+ gconf_client_notify_add (client, "/apps/procman/disks_interval", timeouts_changed_cb,
+ pd, NULL, NULL);
+
+
+ /* /apps/procman/show_all_fs */
+ pd->config.show_all_fs = gconf_client_get_bool (
+ client, "/apps/procman/show_all_fs",
+ NULL);
+ gconf_client_notify_add
+ (client, "/apps/procman/show_all_fs",
+ show_all_fs_changed_cb, pd, NULL, NULL);
+
+
+ pd->config.whose_process = gconf_client_get_int (client, "/apps/procman/view_as", NULL);
+ gconf_client_notify_add (client, "/apps/procman/view_as", view_as_changed_cb,
+ pd, NULL, NULL);
+ pd->config.current_tab = gconf_client_get_int (client, "/apps/procman/current_tab", NULL);
+
+ color = gconf_client_get_string (client, "/apps/procman/bg_color", NULL);
+ if (!color)
+ color = g_strdup ("#000000");
+ gconf_client_notify_add (client, "/apps/procman/bg_color",
+ color_changed_cb, pd, NULL, NULL);
+ gdk_color_parse(color, &pd->config.bg_color);
+ g_free (color);
+
+ color = gconf_client_get_string (client, "/apps/procman/frame_color", NULL);
+ if (!color)
+ color = g_strdup ("#231e89aa2805");
+ gconf_client_notify_add (client, "/apps/procman/frame_color",
+ color_changed_cb, pd, NULL, NULL);
+ gdk_color_parse(color, &pd->config.frame_color);
+ g_free (color);
+
+ color = gconf_client_get_string (client, "/apps/procman/cpu_color", NULL);
+ if (!color)
+ color = g_strdup ("#000000a200ff");
+ gconf_client_notify_add (client, "/apps/procman/cpu_color",
+ color_changed_cb, pd, NULL, NULL);
+ gdk_color_parse(color, &pd->config.cpu_color[0]);
+ g_free (color);
+
+ for (i=1;i<GLIBTOP_NCPU;i++) {
+ gchar *key;
+ key = g_strdup_printf ("/apps/procman/cpu_color%d", i);
+
+ color = gconf_client_get_string (client, key, NULL);
+ if (!color)
+ color = g_strdup ("#f25915e815e8");
+ gconf_client_notify_add (client, key,
+ color_changed_cb, pd, NULL, NULL);
+ gdk_color_parse(color, &pd->config.cpu_color[i]);
+ g_free (color);
+ g_free (key);
+ }
+ color = gconf_client_get_string (client, "/apps/procman/mem_color", NULL);
+ if (!color)
+ color = g_strdup ("#000000ff0082");
+ gconf_client_notify_add (client, "/apps/procman/mem_color",
+ color_changed_cb, pd, NULL, NULL);
+ gdk_color_parse(color, &pd->config.mem_color);
+
+ g_free (color);
+
+ color = gconf_client_get_string (client, "/apps/procman/swap_color", NULL);
+ if (!color)
+ color = g_strdup ("#00b6000000ff");
+ gconf_client_notify_add (client, "/apps/procman/swap_color",
+ color_changed_cb, pd, NULL, NULL);
+ gdk_color_parse(color, &pd->config.swap_color);
+ g_free (color);
+
+ color = gconf_client_get_string (client, "/apps/procman/net_in_color", NULL);
+ if (!color)
+ color = g_strdup ("#000000f200f2");
+ gconf_client_notify_add (client, "/apps/procman/net_in_color",
+ color_changed_cb, pd, NULL, NULL);
+ gdk_color_parse(color, &pd->config.net_in_color);
+ g_free (color);
+
+ color = gconf_client_get_string (client, "/apps/procman/net_out_color", NULL);
+ if (!color)
+ color = g_strdup ("#00f2000000c1");
+ gconf_client_notify_add (client, "/apps/procman/net_out_color",
+ color_changed_cb, pd, NULL, NULL);
+ gdk_color_parse(color, &pd->config.net_out_color);
+ g_free (color);
+
+ get_blacklist (pd, client);
+
+ /* Sanity checks */
+ swidth = gdk_screen_width ();
+ sheight = gdk_screen_height ();
+ 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);
+
+ /* Determinie number of cpus since libgtop doesn't really tell you*/
+ pd->config.num_cpus = 0;
+ glibtop_get_cpu (&cpu);
+ pd->frequency = cpu.frequency;
+ i=0;
+ while (i < GLIBTOP_NCPU && cpu.xcpu_total[i] != 0) {
+ pd->config.num_cpus ++;
+ i++;
+ }
+ if (pd->config.num_cpus == 0)
+ pd->config.num_cpus = 1;
+
+ // delayed initialization as SmoothRefresh() needs ProcData
+ // i.e. we can't call ProcData::get_instance
+ pd->smooth_refresh = new SmoothRefresh();
+
+ return pd;
+
+}
+
+static void
+procman_free_data (ProcData *procdata)
+{
+
+ proctable_free_table (procdata);
+ g_string_chunk_free(procdata->users);
+ g_hash_table_destroy(procdata->pids);
+ delete procdata->smooth_refresh;
+}
+
+
+gboolean
+procman_get_tree_state (GConfClient *client, GtkWidget *tree, const gchar *prefix)
+{
+ GtkTreeModel *model;
+ GList *columns, *it;
+ gint sort_col;
+ GtkSortType order;
+ gchar *key;
+
+
+ g_assert(tree);
+ g_assert(prefix);
+
+ if (!gconf_client_dir_exists (client, prefix, NULL))
+ return FALSE;
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree));
+
+ key = g_strdup_printf ("%s/sort_col", prefix);
+ sort_col = gconf_client_get_int (client, key, NULL);
+ g_free (key);
+
+ key = g_strdup_printf ("%s/sort_order", prefix);
+ order = static_cast<GtkSortType>(gconf_client_get_int (client, key, NULL));
+ g_free (key);
+
+ if (sort_col != -1)
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model),
+ sort_col,
+ order);
+
+ columns = gtk_tree_view_get_columns (GTK_TREE_VIEW (tree));
+
+ for(it = columns; it; it = it->next)
+ {
+ GtkTreeViewColumn *column;
+ GConfValue *value = NULL;
+ gint width;
+ gboolean visible;
+ int id;
+
+ column = static_cast<GtkTreeViewColumn*>(it->data);
+ id = gtk_tree_view_column_get_sort_column_id (column);
+
+ key = g_strdup_printf ("%s/col_%d_width", prefix, id);
+ value = gconf_client_get (client, key, NULL);
+ g_free (key);
+
+ if (value != NULL) {
+ width = gconf_value_get_int(value);
+ gconf_value_free (value);
+
+ key = g_strdup_printf ("%s/col_%d_visible", prefix, id);
+ visible = gconf_client_get_bool (client, key, NULL);
+ g_free (key);
+
+ column = gtk_tree_view_get_column (GTK_TREE_VIEW (tree), id);
+ if(!column) continue;
+ gtk_tree_view_column_set_visible (column, visible);
+ if (visible) {
+ /* ensure column is really visible */
+ width = MAX(width, 10);
+ gtk_tree_view_column_set_fixed_width(column, width);
+ }
+ }
+ }
+
+ if(g_str_has_suffix(prefix, "proctree") || g_str_has_suffix(prefix, "disktreenew"))
+ {
+ GSList *order;
+ char *key;
+
+ key = g_strdup_printf("%s/columns_order", prefix);
+ order = gconf_client_get_list(client, key, GCONF_VALUE_INT, NULL);
+ proctable_set_columns_order(GTK_TREE_VIEW(tree), order);
+
+ g_slist_free(order);
+ g_free(key);
+ }
+
+ g_list_free(columns);
+
+ return TRUE;
+}
+
+void
+procman_save_tree_state (GConfClient *client, GtkWidget *tree, const gchar *prefix)
+{
+ GtkTreeModel *model;
+ GList *it, *columns;
+ gint sort_col;
+ GtkSortType order;
+
+ g_assert(tree);
+ g_assert(prefix);
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree));
+ if (gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (model), &sort_col,
+ &order)) {
+ gchar *key;
+
+ key = g_strdup_printf ("%s/sort_col", prefix);
+ gconf_client_set_int (client, key, sort_col, NULL);
+ g_free (key);
+
+ key = g_strdup_printf ("%s/sort_order", prefix);
+ gconf_client_set_int (client, key, order, NULL);
+ g_free (key);
+ }
+
+ columns = gtk_tree_view_get_columns (GTK_TREE_VIEW (tree));
+
+ for(it = columns; it; it = it->next)
+ {
+ GtkTreeViewColumn *column;
+ gboolean visible;
+ gint width;
+ gchar *key;
+ int id;
+
+ column = static_cast<GtkTreeViewColumn*>(it->data);
+ id = gtk_tree_view_column_get_sort_column_id (column);
+ visible = gtk_tree_view_column_get_visible (column);
+ width = gtk_tree_view_column_get_width (column);
+
+ key = g_strdup_printf ("%s/col_%d_width", prefix, id);
+ gconf_client_set_int (client, key, width, NULL);
+ g_free (key);
+
+ key = g_strdup_printf ("%s/col_%d_visible", prefix, id);
+ gconf_client_set_bool (client, key, visible, NULL);
+ g_free (key);
+ }
+
+ if(g_str_has_suffix(prefix, "proctree") || g_str_has_suffix(prefix, "disktreenew"))
+ {
+ GSList *order;
+ char *key;
+ GError *error = NULL;
+
+ key = g_strdup_printf("%s/columns_order", prefix);
+ order = proctable_get_columns_order(GTK_TREE_VIEW(tree));
+
+ if(!gconf_client_set_list(client, key, GCONF_VALUE_INT, order, &error))
+ {
+ g_critical("Could not save GConf key '%s' : %s",
+ key,
+ error->message);
+ g_error_free(error);
+ }
+
+ g_slist_free(order);
+ g_free(key);
+ }
+
+ g_list_free(columns);
+}
+
+void
+procman_save_config (ProcData *data)
+{
+ GConfClient *client = data->client;
+ gint width, height;
+
+ g_assert(data);
+
+ procman_save_tree_state (data->client, data->tree, "/apps/procman/proctree");
+ procman_save_tree_state (data->client, data->disk_list, "/apps/procman/disktreenew");
+
+ gdk_window_get_size (data->app->window, &width, &height);
+ data->config.width = width;
+ data->config.height = height;
+
+ gconf_client_set_int (client, "/apps/procman/width", data->config.width, NULL);
+ gconf_client_set_int (client, "/apps/procman/height", data->config.height, NULL);
+ gconf_client_set_int (client, "/apps/procman/current_tab", data->config.current_tab, NULL);
+
+ save_blacklist (data, client);
+
+ gconf_client_suggest_sync (client, NULL);
+
+
+
+}
+
+static guint32
+get_startup_timestamp ()
+{
+ const gchar *startup_id_env;
+ gchar *startup_id = NULL;
+ gchar *time_str;
+ gulong retval = 0;
+
+ /* we don't unset the env, since startup-notification
+ * may still need it */
+ startup_id_env = g_getenv ("DESKTOP_STARTUP_ID");
+ if (startup_id_env == NULL)
+ goto out;
+
+ startup_id = g_strdup (startup_id_env);
+
+ time_str = g_strrstr (startup_id, "_TIME");
+ if (time_str == NULL)
+ goto out;
+
+ /* Skip past the "_TIME" part */
+ time_str += 5;
+
+ retval = strtoul (time_str, NULL, 0);
+
+ out:
+ g_free (startup_id);
+
+ return retval;
+}
+
+
+static void
+cb_server (const gchar *msg, gpointer user_data)
+{
+ GdkWindow *window;
+ ProcData *procdata;
+ guint32 timestamp;
+
+ window = gdk_get_default_root_window ();
+
+ procdata = *(ProcData**)user_data;
+ g_assert (procdata != NULL);
+
+ timestamp = strtoul(msg, NULL, 0);
+
+ if (timestamp == 0)
+ {
+ /* fall back to rountripping to X */
+ timestamp = gdk_x11_get_server_time (window);
+ }
+
+ gdk_x11_window_set_user_time (window, timestamp);
+
+ gtk_window_present (GTK_WINDOW(procdata->app));
+}
+
+
+static void
+init_volume_monitor(ProcData *procdata)
+{
+ GnomeVFSVolumeMonitor *mon;
+ mon = gnome_vfs_get_volume_monitor();
+
+ g_signal_connect(mon, "volume_mounted",
+ G_CALLBACK(cb_volume_mounted_or_unmounted), procdata);
+
+ g_signal_connect(mon, "volume_unmounted",
+ G_CALLBACK(cb_volume_mounted_or_unmounted), procdata);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ guint32 startup_timestamp;
+ GnomeProgram *procman;
+ GConfClient *client;
+ ProcData *procdata;
+ BaconMessageConnection *conn;
+
+ bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+
+ startup_timestamp = get_startup_timestamp();
+
+ procman = gnome_program_init ("gnome-system-monitor", VERSION,
+ LIBGNOMEUI_MODULE, argc, argv,
+ GNOME_PARAM_APP_DATADIR,DATADIR, NULL);
+
+ conn = bacon_message_connection_new ("gnome-system-monitor");
+ if (!conn) g_error("Couldn't connect to gnome-system-monitor");
+
+ if (bacon_message_connection_get_is_server (conn))
+ {
+ bacon_message_connection_set_callback (conn, cb_server, &procdata);
+ }
+ else /* client */
+ {
+ char *timestamp;
+
+ timestamp = g_strdup_printf ("%" G_GUINT32_FORMAT, startup_timestamp);
+
+ bacon_message_connection_send (conn, timestamp);
+
+ gdk_notify_startup_complete ();
+
+ g_free (timestamp);
+ bacon_message_connection_free (conn);
+
+ exit (0);
+ }
+
+ gtk_window_set_default_icon_name ("utilities-system-monitor");
+ g_set_application_name(_("System Monitor"));
+
+ gconf_init (argc, argv, NULL);
+
+ client = gconf_client_get_default ();
+ gconf_client_add_dir(client, "/apps/procman", GCONF_CLIENT_PRELOAD_NONE, NULL);
+
+ gnome_vfs_init ();
+ glibtop_init ();
+
+ procdata = procman_data_new (client);
+ procdata->client = client;
+
+ create_main_window (procdata);
+
+ proctable_update_all (procdata);
+
+ init_volume_monitor (procdata);
+
+ g_assert(procdata->app);
+
+ gtk_widget_show(procdata->app);
+
+ gtk_main ();
+
+ procman_free_data (procdata);
+
+ glibtop_close ();
+ gnome_vfs_shutdown ();
+
+ return 0;
+}
+
diff -Nrup gnome-system-monitor-2.17.5/src/procman.h gnome-system-monitor-2.17.5.trunk/src/procman.h
--- gnome-system-monitor-2.17.5/src/procman.h 2007-01-07 22:05:20.000000000 +0800
+++ gnome-system-monitor-2.17.5.trunk/src/procman.h 2007-01-23 11:41:38.516527000 +0800
@@ -203,9 +203,9 @@ struct ProcData
SmoothRefresh *smooth_refresh;
};
-void procman_save_config (ProcData *data) G_GNUC_INTERNAL;
-void procman_save_tree_state (GConfClient *client, GtkWidget *tree, const gchar *prefix) G_GNUC_INTERNAL;
-gboolean procman_get_tree_state (GConfClient *client, GtkWidget *tree, const gchar *prefix) G_GNUC_INTERNAL;
+G_GNUC_INTERNAL void procman_save_config (ProcData *data);
+G_GNUC_INTERNAL void procman_save_tree_state (GConfClient *client, GtkWidget *tree, const gchar *prefix);
+G_GNUC_INTERNAL gboolean procman_get_tree_state (GConfClient *client, GtkWidget *tree, const gchar *prefix);
diff -Nrup gnome-system-monitor-2.17.5/src/procman.h~ gnome-system-monitor-2.17.5.trunk/src/procman.h~
--- gnome-system-monitor-2.17.5/src/procman.h~ 1970-01-01 08:00:00.000000000 +0800
+++ gnome-system-monitor-2.17.5.trunk/src/procman.h~ 2007-01-23 11:41:38.528287000 +0800
@@ -0,0 +1,227 @@
+/* Procman
+ * Copyright (C) 2001 Kevin Vandersloot
+ *
+ * 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 Library 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.
+ *
+ */
+#ifndef _PROCMAN_PROCMAN_H_
+#define _PROCMAN_PROCMAN_H_
+
+
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <gconf/gconf-client.h>
+#include <glibtop/cpu.h>
+
+#include <time.h>
+
+typedef struct _ProcConfig ProcConfig;
+typedef struct _ProcInfo ProcInfo;
+struct ProcData;
+
+#include "smooth_refresh.h"
+
+#include "load-graph.h"
+
+#include "prettytable.h"
+
+enum
+{
+ ALL_PROCESSES,
+ MY_PROCESSES,
+ ACTIVE_PROCESSES
+};
+
+
+static const unsigned MIN_UPDATE_INTERVAL = 1 * 1000;
+static const unsigned MAX_UPDATE_INTERVAL = 100 * 1000;
+
+
+enum ProcmanTab
+{
+ PROCMAN_TAB_SYSINFO,
+ PROCMAN_TAB_PROCESSES,
+ PROCMAN_TAB_RESOURCES,
+ PROCMAN_TAB_DISKS
+};
+
+
+struct _ProcConfig
+{
+ gint width;
+ gint height;
+ gboolean show_kill_warning;
+ gboolean show_hide_message;
+ gboolean show_tree;
+ gboolean show_all_fs;
+ int update_interval;
+ int graph_update_interval;
+ int disks_update_interval;
+ gint whose_process;
+ gint current_tab;
+ GdkColor cpu_color[GLIBTOP_NCPU];
+ GdkColor mem_color;
+ GdkColor swap_color;
+ GdkColor net_in_color;
+ GdkColor net_out_color;
+ GdkColor bg_color;
+ GdkColor frame_color;
+ gint num_cpus;
+};
+
+
+struct _ProcInfo
+{
+ // adds one more ref to icon
+ void set_icon(GdkPixbuf *icon);
+
+ GtkTreeIter node;
+ GtkTreePath *path;
+ ProcInfo *parent;
+ GSList *children;
+
+ GdkPixbuf *pixbuf;
+ gchar *tooltip;
+ gchar *name;
+ gchar *user; /* allocated with g_string_chunk, don't free it ! */
+ gchar *arguments;
+
+ gchar *status; /* shared, don't free it ! */
+ gchar *security_context;
+
+ time_t start_time;
+ guint64 cpu_time_last;
+
+ // all these members are filled with libgtop which uses
+ // guint64 (to have fixed size data) but we don't need more
+ // than an unsigned long (even for 32bit apps on a 64bit
+ // kernel) as these data are amounts, not offsets.
+ unsigned long vmsize;
+ unsigned long memres;
+ unsigned long memwritable;
+ unsigned long memshared;
+ unsigned long mem; /* estimated memory usage */
+
+ // wnck gives an unsigned long
+ unsigned long memxserver;
+
+ guint pid;
+ guint uid;
+
+ guint8 pcpu; /* 0% - 100% */
+ gint8 nice;
+
+ guint is_visible : 1;
+ guint is_running : 1;
+ guint is_blacklisted : 1;
+};
+
+struct ProcData
+{
+ // lazy initialization
+ static ProcData* get_instance();
+
+ GtkUIManager *uimanager;
+ GtkActionGroup *action_group;
+ GtkWidget *statusbar;
+ gint tip_message_cid;
+ GtkWidget *tree;
+ GtkWidget *loadavg;
+ GtkWidget *endprocessbutton;
+ GtkWidget *popup_menu;
+ GtkWidget *disk_list;
+ ProcConfig config;
+ LoadGraph *cpu_graph;
+ LoadGraph *mem_graph;
+ LoadGraph *net_graph;
+ gint cpu_label_fixed_width;
+ gint net_label_fixed_width;
+ ProcInfo *selected_process;
+ GtkTreeSelection *selection;
+ guint timeout;
+ guint disk_timeout;
+
+/*
+ 'info' is GList, which has very slow lookup. On each update, glibtop
+ retrieves the full system pid list. To update the table,
+
+ foreach pid in glibtop pid list:
+ - if there's not ProcInfo with pid, add a new ProcInfo to 'info'
+ - else, update the current ProcInfo
+
+ which is very inefficient, because if a process is running at time t,
+ it's very likely to be running at t+1.
+ So if is length('info') = N, N lookups are performed on each update.
+ Average lookup iterates over N / 2 ProcInfo to find that a pid already
+ has a ProcInfo.
+ -> cost = (N x N) / 2
+
+ With 200 processes, an update costs about 20000 g_list_next(), which
+ is huge because we only want to know if we have this pid or not.
+
+ So 'pids' is a hastable to perform fast lookups.
+
+ TODO: 'info' and 'pids' could be merged
+*/
+
+ GList *info;
+ GHashTable *pids;
+
+ PrettyTable pretty_table;
+ GList *blacklist;
+ gint blacklist_num;
+
+ GConfClient *client;
+ GtkWidget *app;
+ GtkUIManager *menu;
+
+
+ /* cached username */
+ GStringChunk *users;
+
+
+ /* libgtop uses guint64 but we use a float because
+ frequency is ~always == 100
+ and because we display cpu_time as %.1f seconds
+ */
+ float frequency;
+
+ SmoothRefresh *smooth_refresh;
+};
+
+void procman_save_config (ProcData *data) G_GNUC_INTERNAL;
+void procman_save_tree_state (GConfClient *client, GtkWidget *tree, const gchar *prefix) G_GNUC_INTERNAL;
+gboolean procman_get_tree_state (GConfClient *client, GtkWidget *tree, const gchar *prefix) G_GNUC_INTERNAL;
+
+
+
+
+
+struct ReniceArgs
+{
+ ProcData *procdata;
+ int nice_value;
+};
+
+
+struct KillArgs
+{
+ ProcData *procdata;
+ int signal;
+};
+
+#endif /* _PROCMAN_PROCMAN_H_ */
diff -Nrup gnome-system-monitor-2.17.5/src/proctable.cpp gnome-system-monitor-2.17.5.trunk/src/proctable.cpp
--- gnome-system-monitor-2.17.5/src/proctable.cpp 2007-01-07 19:56:00.000000000 +0800
+++ gnome-system-monitor-2.17.5.trunk/src/proctable.cpp 2007-01-23 14:51:18.220985000 +0800
@@ -555,6 +555,17 @@ static void get_process_memory_writable(
unsigned i;
info->memwritable = 0;
+ /* we have to optimize the performance of libgtop, because update the information will occupy too much cpu.
+
+ here I would like to make a little update:set glibtop_proc_map.flags=1,so as to let glibtop_get_proc_map_s()
+ only return the ones this function need: memwritable
+
+ we do the check in glibtop_get_proc_map_s(), don't run the others part which don't need by this function,
+ I think this will accelerate the transaction lots,
+ Also this will not affect the existing codes, because when nobody set glibtop_proc_map.flags,
+ glibtop_get_proc_map() will return all as before. zhua
+ */
+ buf.flags = 1;
maps = glibtop_get_proc_map(&buf, info->pid);
@@ -564,6 +575,9 @@ static void get_process_memory_writable(
#else
if (maps[i].perm & GLIBTOP_MAP_PERM_WRITE)
info->memwritable += maps[i].size;
+
+ if (maps[i].perm & GLIBTOP_MAP_PERM_SHARED)
+ info->memshared += maps[i].shared_clean;
#endif
}
@@ -574,24 +588,35 @@ static void get_process_memory_writable(
static void
get_process_memory_info(ProcInfo *info)
{
- glibtop_proc_mem procmem;
- WnckResourceUsage xresources;
+ glibtop_proc_mem procmem;
+ WnckResourceUsage xresources;
- wnck_pid_read_resource_usage (gdk_screen_get_display (gdk_screen_get_default ()),
- info->pid,
- &xresources);
+ wnck_pid_read_resource_usage (gdk_screen_get_display (gdk_screen_get_default ()),
+ info->pid,
+ &xresources);
+ info->memxserver = xresources.total_bytes_estimate;
- glibtop_get_proc_mem(&procmem, info->pid);
+ /*zhua: we have to optimize the performance of libgtop, because update the information will occupy too much cpu.
+ optimize the function call, let flags =1, so if glibtop_get_proc_mem()
+ find flags =1, don't call glibtop_get_proc_data_psinfo_s() */
- info->vmsize = procmem.vsize;
- info->memres = procmem.resident;
- info->memshared = procmem.share;
+ /* zhua: use get_process_memory_writable(), because it just call glibtop_get_proc_map_s(),
+ can get all need infor.
+ glibtop_get_proc_mem(&procmem, info->pid);
- info->memxserver = xresources.total_bytes_estimate;
+ info->memshared = procmem.share;
- get_process_memory_writable(info);
+ info->vmsize = procmem.vsize;
+ info->memres = procmem.resident;
- info->mem = info->memxserver + info->memwritable;
+#ifdef __sun
+ info->pcpu = procmem.load;
+#endif
+ */
+
+ get_process_memory_writable(info);
+
+ info->mem = info->memxserver + info->memwritable;
}
@@ -779,6 +804,28 @@ remove_children_from_tree (ProcData *pro
} while (gtk_tree_model_iter_next (model, parent));
}
+/* place the children process to blacklist if the parent is placed into */
+static void
+blacklist_children_from_tree (ProcData *procdata, GtkTreeModel *model,
+ GtkTreeIter *parent)
+{
+ do {
+ ProcInfo *child_info;
+ GtkTreeIter child;
+
+ if (gtk_tree_model_iter_children (model, &child, parent))
+ blacklist_children_from_tree (procdata, model, &child);
+
+ gtk_tree_model_get (model, parent, COL_POINTER, &child_info, -1);
+ if (child_info) {
+ if (procdata->selected_process == child_info)
+ procdata->selected_process = NULL;
+ add_to_blacklist (procdata, child_info->name);
+ child_info->is_visible = FALSE;
+ }
+ } while (gtk_tree_model_iter_next (model, parent));
+}
+
void
remove_info_from_tree (ProcInfo *info, ProcData *procdata)
@@ -794,6 +841,11 @@ remove_info_from_tree (ProcInfo *info, P
if (procdata->selected_process == info)
procdata->selected_process = NULL;
+ /* move all children from tree to blacklist */
+ GtkTreeIter child;
+ if (gtk_tree_model_iter_children (model, &child, &info->node))
+ blacklist_children_from_tree (procdata, model, &child);
+
gtk_tree_store_remove (GTK_TREE_STORE (model), &info->node);
@@ -858,23 +910,40 @@ update_info (ProcData *procdata, ProcInf
GtkTreeModel *model;
glibtop_proc_uid procuid;
glibtop_proc_time proctime;
+
+ /* zhua: let's delete this call, because we can get the value
+ from glibtop_get_proc_state
+ glibtop_get_proc_uid (&procuid, info->pid);*/
+ glibtop_get_proc_time (&proctime, info->pid);
+ info->cpu_time_last = proctime.rtime;
+
+ get_process_user(procdata, info, procstate.uid);
+
+ /* zhua: let's get from file directly
+ info->pcpu = (proctime.rtime - info->cpu_time_last) * 100 / total_time;
+ info->pcpu = MIN(info->pcpu, 100);*/
- glibtop_get_proc_uid (&procuid, info->pid);
- glibtop_get_proc_time (&proctime, info->pid);
+ /* zhua: get nice/ppid from procstate */
+ /*info->nice = procuid.nice;*/
+ info->nice = procstate.nice;
- get_process_memory_info(info);
- get_process_user(procdata, info, procstate.uid);
+ /* zhua: get start_time from procstate */
+ info->start_time = procstate.start_time;
- info->pcpu = (proctime.rtime - info->cpu_time_last) * 100 / total_time;
- info->pcpu = MIN(info->pcpu, 100);
- info->cpu_time_last = proctime.rtime;
- info->nice = procuid.nice;
+ /* if at Solaris, in get_process_memory_info() info->pcpu will
+ get again from glibtop_get_proc_mem() */
+ get_process_memory_info(info);
+ info->vmsize = procstate.vsize;
+ info->memres = procstate.resident;
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (procdata->tree));
+ info->pcpu = procstate.load;
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (procdata->tree));
+
+ update_info_mutable_cols(GTK_TREE_STORE (model), procdata, info);
- update_info_mutable_cols(GTK_TREE_STORE (model), procdata, info);
}
}
@@ -895,7 +964,9 @@ procinfo_new (ProcData *procdata, gint p
info->uid = -1;
glibtop_get_proc_state (&procstate, pid);
- glibtop_get_proc_uid (&procuid, pid);
+ /* zhua: delete this function, because we can get nice/ppid from glibtop_get_proc_state()
+ dont' need to open/pread/close psinfo, it will save some time
+ glibtop_get_proc_uid (&procuid, pid);*/
glibtop_get_proc_time (&proctime, pid);
arguments = glibtop_get_proc_argv (&procargs, pid, 0);
@@ -909,16 +980,26 @@ procinfo_new (ProcData *procdata, gint p
info->pcpu = 0;
info->cpu_time_last = proctime.rtime;
- info->start_time = proctime.start_time;
- info->nice = procuid.nice;
-
+ /* zhua */
+ info->vmsize = procstate.vsize;
+ info->memres = procstate.resident;
+
+ info->pcpu = procstate.load;
+
+ /* zhua: get start_time/nice/ppid from procstate */
+ /*info->start_time = proctime.start_time;
+ info->nice = procuid.nice; zhua */
+ info->start_time = procstate.start_time;
+ info->nice = procstate.nice;
+ gint32 ppid = procstate.ppid;
+
get_process_memory_info(info);
get_process_status (info, &procstate);
get_process_selinux_context (info);
info->pixbuf = procdata->pretty_table.get_icon(info->name, pid);
- info->parent = find_parent (procdata, procuid.ppid);
+ info->parent = find_parent (procdata, ppid);
if (info->parent) {
info->parent->children = g_slist_prepend (info->parent->children, info);
}
@@ -1030,9 +1111,10 @@ proctable_update_list (ProcData * const
/* FIXME: total cpu time elapsed should be calculated on an individual basis here
** should probably have a total_time_last gint in the ProcInfo structure */
+ /* zhua: delete these sentences, we can get cpu% from file directly.
glibtop_get_cpu (&cpu);
- total_time = MAX(cpu.total - total_time_last, 1);
- total_time_last = cpu.total;
+ total_time = MAX(cpu.total - total_time_last, 1);
+ total_time_last = cpu.total;*/
refresh_list (procdata, pid_list, proclist.number);
diff -Nrup gnome-system-monitor-2.17.5/src/proctable.cpp~ gnome-system-monitor-2.17.5.trunk/src/proctable.cpp~
--- gnome-system-monitor-2.17.5/src/proctable.cpp~ 1970-01-01 08:00:00.000000000 +0800
+++ gnome-system-monitor-2.17.5.trunk/src/proctable.cpp~ 2007-01-23 11:41:38.528614000 +0800
@@ -0,0 +1,1127 @@
+/* Procman tree view and process updating
+ * Copyright (C) 2001 Kevin Vandersloot
+ *
+ * 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 Library 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 <config.h>
+
+
+#include <string.h>
+#include <math.h>
+#include <glib/gi18n.h>
+#include <glibtop.h>
+#include <glibtop/loadavg.h>
+#include <glibtop/proclist.h>
+#include <glibtop/procstate.h>
+#include <glibtop/procmem.h>
+#include <glibtop/procmap.h>
+#include <glibtop/proctime.h>
+#include <glibtop/procuid.h>
+#include <glibtop/procargs.h>
+#include <glibtop/mem.h>
+#include <glibtop/swap.h>
+#include <sys/stat.h>
+#include <pwd.h>
+#include <time.h>
+
+#include <libgnomevfs/gnome-vfs-utils.h>
+
+#include "procman.h"
+#include "proctable.h"
+#include "callbacks.h"
+#include "prettytable.h"
+#include "util.h"
+#include "interface.h"
+#include "favorites.h"
+#include "selinux.h"
+extern "C" {
+#include "e_date.h"
+}
+
+static guint64 total_time = 1;
+static guint64 total_time_last = 1;
+
+
+static gint
+sort_ints (GtkTreeModel *model, GtkTreeIter *itera, GtkTreeIter *iterb, gpointer data)
+{
+ ProcInfo *infoa = NULL, *infob = NULL;
+ const gint col = GPOINTER_TO_INT (data);
+
+ gtk_tree_model_get (model, itera, COL_POINTER, &infoa, -1);
+ gtk_tree_model_get (model, iterb, COL_POINTER, &infob, -1);
+
+ g_assert(infoa);
+ g_assert(infob);
+
+ switch (col) {
+ case COL_VMSIZE:
+ return PROCMAN_RCMP(infoa->vmsize, infob->vmsize);
+
+ case COL_MEMRES:
+ return PROCMAN_RCMP(infoa->memres, infob->memres);
+
+ case COL_MEMWRITABLE:
+ return PROCMAN_RCMP(infoa->memwritable, infob->memwritable);
+
+ case COL_MEMSHARED:
+ return PROCMAN_RCMP(infoa->memshared, infob->memshared);
+
+ case COL_MEMXSERVER:
+ return PROCMAN_RCMP(infoa->memxserver, infob->memxserver);
+
+ case COL_CPU_TIME:
+ return PROCMAN_RCMP(infoa->cpu_time_last, infob->cpu_time_last);
+
+ case COL_START_TIME:
+ return PROCMAN_CMP(infoa->start_time, infob->start_time);
+
+ case COL_CPU:
+ return PROCMAN_RCMP(infoa->pcpu, infob->pcpu);
+
+ case COL_MEM:
+ return PROCMAN_RCMP(infoa->mem, infob->mem);
+
+ default:
+ g_assert_not_reached();
+ return 0;
+ }
+}
+
+
+
+static GtkWidget *
+create_proctree(GtkTreeModel *model)
+{
+ GtkWidget *proctree;
+ GtkWidget* (*sexy_new)(void);
+ void (*sexy_set_column)(void*, guint);
+
+
+ if (FALSE && load_symbols("libsexy.so",
+ "sexy_tree_view_new", &sexy_new,
+ "sexy_tree_view_set_tooltip_label_column", &sexy_set_column,
+ NULL)) {
+ proctree = sexy_new();
+ gtk_tree_view_set_model(GTK_TREE_VIEW(proctree), model);
+ sexy_set_column(proctree, COL_TOOLTIP);
+ } else {
+ proctree = gtk_tree_view_new_with_model(model);
+ }
+
+ return proctree;
+}
+
+
+
+
+
+static void
+set_proctree_reorderable(ProcData *procdata)
+{
+ GList *columns, *col;
+ GtkTreeView *proctree;
+
+ proctree = GTK_TREE_VIEW(procdata->tree);
+
+ columns = gtk_tree_view_get_columns (proctree);
+
+ for(col = columns; col; col = col->next)
+ gtk_tree_view_column_set_reorderable(static_cast<GtkTreeViewColumn*>(col->data), TRUE);
+
+ g_list_free(columns);
+}
+
+
+static void
+cb_columns_changed(GtkTreeView *treeview, gpointer user_data)
+{
+ ProcData * const procdata = static_cast<ProcData*>(user_data);
+
+ procman_save_tree_state(procdata->client,
+ GTK_WIDGET(treeview),
+ "/apps/procman/proctree");
+}
+
+
+static GtkTreeViewColumn*
+my_gtk_tree_view_get_column_with_sort_column_id(GtkTreeView *treeview, int id)
+{
+ GList *columns, *it;
+ GtkTreeViewColumn *col = NULL;
+
+ columns = gtk_tree_view_get_columns(treeview);
+
+ for(it = columns; it; it = it->next)
+ {
+ if(gtk_tree_view_column_get_sort_column_id(static_cast<GtkTreeViewColumn*>(it->data)) == id)
+ {
+ col = static_cast<GtkTreeViewColumn*>(it->data);
+ break;
+ }
+ }
+
+ g_list_free(columns);
+
+ return col;
+}
+
+
+void
+proctable_set_columns_order(GtkTreeView *treeview, GSList *order)
+{
+ GtkTreeViewColumn* last = NULL;
+ GSList *it;
+
+ for(it = order; it; it = it->next)
+ {
+ int id;
+ GtkTreeViewColumn *cur;
+
+ id = GPOINTER_TO_INT(it->data);
+
+ g_assert(id >= 0 && id < NUM_COLUMNS);
+
+ cur = my_gtk_tree_view_get_column_with_sort_column_id(treeview, id);
+
+ if(cur && cur != last)
+ {
+ gtk_tree_view_move_column_after(treeview, cur, last);
+ last = cur;
+ }
+ }
+}
+
+
+
+GSList*
+proctable_get_columns_order(GtkTreeView *treeview)
+{
+ GList *columns, *col;
+ GSList *order = NULL;
+
+ columns = gtk_tree_view_get_columns(treeview);
+
+ for(col = columns; col; col = col->next)
+ {
+ int id;
+
+ id = gtk_tree_view_column_get_sort_column_id(static_cast<GtkTreeViewColumn*>(col->data));
+ order = g_slist_prepend(order, GINT_TO_POINTER(id));
+ }
+
+ g_list_free(columns);
+
+ order = g_slist_reverse(order);
+
+ return order;
+}
+
+
+static gboolean
+search_equal_func(GtkTreeModel *model,
+ gint column,
+ const gchar *key,
+ GtkTreeIter *iter,
+ gpointer search_data)
+{
+ char* name;
+ char* user;
+ gboolean found;
+
+ gtk_tree_model_get(model, iter,
+ COL_NAME, &name,
+ COL_USER, &user,
+ -1);
+
+ found = !((name && strstr(name, key))
+ || (user && strstr(user, key)));
+
+ g_free(name);
+ g_free(user);
+
+ return found;
+}
+
+
+
+GtkWidget *
+proctable_new (ProcData * const procdata)
+{
+ GtkWidget *proctree;
+ GtkWidget *scrolled;
+ GtkTreeStore *model;
+ GtkTreeSelection *selection;
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *cell_renderer;
+
+ const gchar *titles[] = {
+ N_("Process Name"),
+ N_("User"),
+ N_("Status"),
+ N_("Virtual Memory"),
+ N_("Resident Memory"),
+ N_("Writable Memory"),
+ N_("Shared Memory"),
+ N_("X Server Memory"),
+ /* xgettext:no-c-format */ N_("% CPU"),
+ N_("CPU Time"),
+ N_("Started"),
+ N_("Nice"),
+ N_("ID"),
+ N_("Security Context"),
+ N_("Command Line"),
+ N_("Memory"),
+ NULL,
+ "POINTER"
+ };
+
+ g_assert(COL_MEM == 15);
+
+ gint i;
+
+ scrolled = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+
+ model = gtk_tree_store_new (NUM_COLUMNS,
+ G_TYPE_STRING, /* Process Name */
+ G_TYPE_STRING, /* User */
+ G_TYPE_STRING, /* Status */
+ G_TYPE_STRING, /* VM Size */
+ G_TYPE_STRING, /* Resident Memory */
+ G_TYPE_STRING, /* Writable Memory */
+ G_TYPE_STRING, /* Shared Memory */
+ G_TYPE_STRING, /* X Server Memory */
+ G_TYPE_UINT, /* % CPU */
+ G_TYPE_STRING, /* CPU time */
+ G_TYPE_STRING, /* Started */
+ G_TYPE_INT, /* Nice */
+ G_TYPE_UINT, /* ID */
+ G_TYPE_STRING, /* Security Context */
+ G_TYPE_STRING, /* Arguments */
+ G_TYPE_STRING, /* Memory */
+ GDK_TYPE_PIXBUF, /* Icon */
+ G_TYPE_POINTER, /* ProcInfo */
+ G_TYPE_STRING /* Sexy tooltip */
+ );
+
+ proctree = create_proctree(GTK_TREE_MODEL(model));
+ gtk_tree_view_set_search_equal_func (GTK_TREE_VIEW (proctree),
+ search_equal_func,
+ NULL,
+ NULL);
+ gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (proctree), TRUE);
+ g_object_unref (G_OBJECT (model));
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (proctree));
+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
+
+ column = gtk_tree_view_column_new ();
+
+ cell_renderer = gtk_cell_renderer_pixbuf_new ();
+ gtk_tree_view_column_pack_start (column, cell_renderer, FALSE);
+ gtk_tree_view_column_set_attributes (column, cell_renderer,
+ "pixbuf", COL_PIXBUF,
+ NULL);
+
+ cell_renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_column_pack_start (column, cell_renderer, FALSE);
+ gtk_tree_view_column_set_attributes (column, cell_renderer,
+ "text", COL_NAME,
+ NULL);
+ gtk_tree_view_column_set_title (column, _(titles[0]));
+ gtk_tree_view_column_set_sort_column_id (column, COL_NAME);
+ gtk_tree_view_column_set_resizable (column, TRUE);
+ gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
+ gtk_tree_view_column_set_min_width (column, 1);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (proctree), column);
+ gtk_tree_view_set_expander_column (GTK_TREE_VIEW (proctree), column);
+
+
+ for (i = COL_USER; i <= COL_MEM; i++) {
+ cell_renderer = gtk_cell_renderer_text_new ();
+
+ switch(i)
+ {
+ case COL_VMSIZE:
+ case COL_MEMRES:
+ case COL_MEMWRITABLE:
+ case COL_MEMSHARED:
+ case COL_MEMXSERVER:
+ case COL_CPU:
+ case COL_NICE:
+ case COL_PID:
+ case COL_CPU_TIME:
+ case COL_MEM:
+ g_object_set(G_OBJECT(cell_renderer),
+ "xalign", 1.0f,
+ NULL);
+ }
+
+ column = gtk_tree_view_column_new ();
+ gtk_tree_view_column_pack_start (column, cell_renderer, FALSE);
+ gtk_tree_view_column_set_attributes (column, cell_renderer,
+ "text", i,
+ NULL);
+ gtk_tree_view_column_set_title (column, _(titles[i]));
+ gtk_tree_view_column_set_sort_column_id (column, i);
+ gtk_tree_view_column_set_resizable (column, TRUE);
+
+ switch (i) {
+ case COL_ARGS:
+ gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
+ break;
+ }
+
+ gtk_tree_view_column_set_min_width (column, 1);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (proctree), column);
+ }
+
+ gtk_container_add (GTK_CONTAINER (scrolled), proctree);
+
+
+ for(i = COL_NAME; i <= COL_MEM; i++)
+ {
+ switch(i)
+ {
+ case COL_VMSIZE:
+ case COL_MEMRES:
+ case COL_MEMWRITABLE:
+ case COL_MEMSHARED:
+ case COL_MEMXSERVER:
+ case COL_CPU_TIME:
+ case COL_START_TIME:
+ case COL_CPU:
+ case COL_MEM:
+ gtk_tree_sortable_set_sort_func (
+ GTK_TREE_SORTABLE (model),
+ i,
+ sort_ints,
+ GINT_TO_POINTER(i),
+ NULL);
+ }
+ }
+
+ procdata->tree = proctree;
+
+ set_proctree_reorderable(procdata);
+
+ procman_get_tree_state (procdata->client, proctree, "/apps/procman/proctree");
+
+ /* Override column settings by hiding this column if it's meaningless: */
+ if (!can_show_security_context_column ()) {
+ GtkTreeViewColumn *column;
+ column = gtk_tree_view_get_column (GTK_TREE_VIEW (proctree), COL_SECURITYCONTEXT);
+ gtk_tree_view_column_set_visible (column, FALSE);
+ }
+
+ g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (proctree))),
+ "changed",
+ G_CALLBACK (cb_row_selected), procdata);
+ g_signal_connect (G_OBJECT (proctree), "popup_menu",
+ G_CALLBACK (cb_tree_popup_menu), procdata);
+ g_signal_connect (G_OBJECT (proctree), "button_press_event",
+ G_CALLBACK (cb_tree_button_pressed), procdata);
+
+ g_signal_connect (G_OBJECT(proctree), "columns-changed",
+ G_CALLBACK(cb_columns_changed), procdata);
+
+ return scrolled;
+}
+
+
+static void
+proctable_free_info(ProcInfo *info)
+{
+ g_assert(info != NULL);
+
+ if(info->pixbuf) {
+ g_object_unref (info->pixbuf);
+ }
+
+ g_free (info->name);
+ g_free(info->tooltip);
+ g_free (info->arguments);
+ g_free (info->security_context);
+ g_slist_free (info->children);
+ g_slice_free(ProcInfo, info);
+}
+
+
+static void
+get_process_status (ProcInfo *info, const glibtop_proc_state *buf)
+{
+
+ switch(buf->state)
+ {
+ case GLIBTOP_PROCESS_RUNNING:
+ info->status = _("Running");
+ info->is_running = TRUE;
+ break;
+
+ case GLIBTOP_PROCESS_STOPPED:
+ info->status = _("Stopped");
+ info->is_running = FALSE;
+ break;
+
+ case GLIBTOP_PROCESS_ZOMBIE:
+ info->status = _("Zombie");
+ info->is_running = FALSE;
+ break;
+
+ case GLIBTOP_PROCESS_UNINTERRUPTIBLE:
+ info->status = _("Uninterruptible");
+ info->is_running = FALSE;
+ break;
+
+ default:
+ info->status = _("Sleeping");
+ info->is_running = FALSE;
+ break;
+ }
+}
+
+
+static void
+get_process_name (ProcInfo *info,
+ const gchar *cmd, const gchar *args)
+{
+ if (args && *args)
+ {
+ char* basename;
+ basename = g_path_get_basename (args);
+
+ if(g_str_has_prefix (basename, cmd))
+ {
+ info->name = basename;
+ return;
+ }
+
+ g_free (basename);
+ }
+
+ info->name = g_strdup (cmd);
+}
+
+
+
+static void
+get_process_user(ProcData* procdata, ProcInfo* info, uid_t uid)
+{
+ struct passwd* pwd;
+ char* username;
+
+ if(G_LIKELY(info->uid == uid))
+ return;
+
+ info->uid = uid;
+
+ pwd = getpwuid(uid);
+
+ if(pwd && pwd->pw_name)
+ username = g_strdup(pwd->pw_name);
+ else
+ username = g_strdup_printf("%u", (unsigned)uid);
+
+ /* don't free, because info->user belongs to procdata->users */
+ info->user = g_string_chunk_insert_const(procdata->users, username);
+
+ g_free(username);
+}
+
+
+
+static void get_process_memory_writable(ProcInfo *info)
+{
+ glibtop_proc_map buf;
+ glibtop_map_entry *maps;
+ unsigned i;
+
+ info->memwritable = 0;
+
+ maps = glibtop_get_proc_map(&buf, info->pid);
+
+ for (i = 0; i < buf.number; ++i) {
+#ifdef __linux__
+ info->memwritable += maps[i].private_dirty;
+#else
+ if (maps[i].perm & GLIBTOP_MAP_PERM_WRITE)
+ info->memwritable += maps[i].size;
+#endif
+ }
+
+ g_free(maps);
+}
+
+
+static void
+get_process_memory_info(ProcInfo *info)
+{
+ glibtop_proc_mem procmem;
+ WnckResourceUsage xresources;
+
+ wnck_pid_read_resource_usage (gdk_screen_get_display (gdk_screen_get_default ()),
+ info->pid,
+ &xresources);
+
+ glibtop_get_proc_mem(&procmem, info->pid);
+
+ info->vmsize = procmem.vsize;
+ info->memres = procmem.resident;
+ info->memshared = procmem.share;
+
+ info->memxserver = xresources.total_bytes_estimate;
+
+ get_process_memory_writable(info);
+
+ info->mem = info->memxserver + info->memwritable;
+}
+
+
+
+ProcInfo *
+proctable_find_process (guint pid, ProcData *procdata)
+{
+ return static_cast<ProcInfo*>(g_hash_table_lookup(procdata->pids, GINT_TO_POINTER(pid)));
+}
+
+
+static ProcInfo *
+find_parent (ProcData *procdata, guint pid)
+{
+ /* ignore init as a parent process */
+ if (pid <= 1)
+ return NULL;
+
+ return proctable_find_process(pid, procdata);
+}
+
+
+static inline unsigned divide(unsigned *q, unsigned *r, unsigned d)
+{
+ *q = *r / d;
+ *r = *r % d;
+ return *q != 0;
+}
+
+/*
+ * @param d: duration in centiseconds
+ * @type d: unsigned
+ */
+static char *
+format_duration_for_display(unsigned centiseconds)
+{
+ unsigned weeks = 0, days = 0, hours = 0, minutes = 0, seconds = 0;
+
+ (void)(divide(&seconds, &centiseconds, 100)
+ && divide(&minutes, &seconds, 60)
+ && divide(&hours, &minutes, 60)
+ && divide(&days, &hours, 24)
+ && divide(&weeks, &days, 7));
+
+ if (weeks)
+ /* xgettext: weeks, days */
+ return g_strdup_printf(_("%uw%ud"), weeks, days);
+
+ if (days)
+ /* xgettext: days, hours (0 -> 23) */
+ return g_strdup_printf(_("%ud%02uh"), days, hours);
+
+ if (hours)
+ /* xgettext: hours (0 -> 23), minutes, seconds */
+ return g_strdup_printf(_("%u:%02u:%02u"), hours, minutes, seconds);
+
+ /* xgettext: minutes, seconds, centiseconds */
+ return g_strdup_printf(_("%u:%02u.%02u"), minutes, seconds, centiseconds);
+}
+
+
+static void
+update_info_mutable_cols(GtkTreeStore *store, ProcData *procdata, ProcInfo *info)
+{
+ gchar *vmsize, *memres, *memwritable, *memshared, *memxserver,
+ *cpu_time, *start_time, *mem;
+
+ vmsize = SI_gnome_vfs_format_file_size_for_display (info->vmsize);
+ memres = SI_gnome_vfs_format_file_size_for_display (info->memres);
+ memwritable = SI_gnome_vfs_format_file_size_for_display (info->memwritable);
+ memshared = SI_gnome_vfs_format_file_size_for_display (info->memshared);
+ memxserver = SI_gnome_vfs_format_file_size_for_display (info->memxserver);
+ mem = SI_gnome_vfs_format_file_size_for_display(info->mem);
+
+ cpu_time = format_duration_for_display(100 * info->cpu_time_last / procdata->frequency);
+
+ /* FIXME: does it worths it to display relative to $now date ?
+ absolute date wouldn't required to be updated on every refresh */
+ start_time = procman_format_date_for_display(info->start_time);
+
+ gtk_tree_store_set (store, &info->node,
+ COL_STATUS, info->status,
+ COL_USER, info->user,
+ COL_VMSIZE, vmsize,
+ COL_MEMRES, memres,
+ COL_MEMWRITABLE, memwritable,
+ COL_MEMSHARED, memshared,
+ COL_MEMXSERVER, memxserver,
+ COL_CPU, guint(info->pcpu),
+ COL_CPU_TIME, cpu_time,
+ COL_START_TIME, start_time,
+ COL_NICE, gint(info->nice),
+ COL_MEM, mem,
+ -1);
+
+ /* FIXME: We don't bother updating COL_SECURITYCONTEXT as it can never change.
+ even on fork ? */
+ g_free (vmsize);
+ g_free (memres);
+ g_free (memwritable);
+ g_free (memshared);
+ g_free (memxserver);
+ g_free (cpu_time);
+ g_free(start_time);
+ g_free(mem);
+}
+
+
+
+void
+insert_info_to_tree (ProcInfo *info, ProcData *procdata)
+{
+ GtkTreeModel *model;
+
+ /* Don't show process if it is not running */
+ if ((procdata->config.whose_process == ACTIVE_PROCESSES) &&
+ (!info->is_running))
+ return;
+
+ /* Don't show processes that user has blacklisted */
+ if (is_process_blacklisted (procdata, info->name))
+ {
+ info->is_blacklisted = TRUE;
+ return;
+ }
+ info->is_blacklisted = FALSE;
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (procdata->tree));
+ if (info->parent && procdata->config.show_tree && info->parent->is_visible) {
+ GtkTreePath *parent_node = gtk_tree_model_get_path (model, &info->parent->node);
+
+ gtk_tree_store_insert (GTK_TREE_STORE (model), &info->node, &info->parent->node, 0);
+ if (!gtk_tree_view_row_expanded (GTK_TREE_VIEW (procdata->tree), parent_node))
+ gtk_tree_view_expand_row (GTK_TREE_VIEW (procdata->tree),
+ parent_node,
+ FALSE);
+
+ gtk_tree_path_free (parent_node);
+ }
+ else
+ gtk_tree_store_insert (GTK_TREE_STORE (model), &info->node, NULL, 0);
+
+ /* COL_POINTER must be set first, because GtkTreeStore
+ * will call sort_ints as soon as we set the column
+ * that we're sorting on.
+ */
+
+ gtk_tree_store_set (GTK_TREE_STORE (model), &info->node,
+ COL_POINTER, info,
+ COL_PIXBUF, info->pixbuf,
+ COL_NAME, info->name,
+ COL_ARGS, info->arguments,
+ COL_TOOLTIP, info->tooltip,
+ COL_PID, info->pid,
+ COL_SECURITYCONTEXT, info->security_context,
+ -1);
+
+ update_info_mutable_cols(GTK_TREE_STORE (model), procdata, info);
+
+ info->is_visible = TRUE;
+}
+
+
+/* Removing a node with children - make sure the children are queued
+** to be readded.
+*/
+static void
+remove_children_from_tree (ProcData *procdata, GtkTreeModel *model,
+ GtkTreeIter *parent, GPtrArray *addition_list)
+{
+ do {
+ ProcInfo *child_info;
+ GtkTreeIter child;
+
+ if (gtk_tree_model_iter_children (model, &child, parent))
+ remove_children_from_tree (procdata, model, &child, addition_list);
+
+ gtk_tree_model_get (model, parent, COL_POINTER, &child_info, -1);
+ if (child_info) {
+ if (procdata->selected_process == child_info)
+ procdata->selected_process = NULL;
+ g_ptr_array_add(addition_list, child_info);
+ child_info->is_visible = FALSE;
+ }
+ } while (gtk_tree_model_iter_next (model, parent));
+}
+
+
+void
+remove_info_from_tree (ProcInfo *info, ProcData *procdata)
+{
+ GtkTreeModel *model;
+
+ g_assert(info);
+
+ if (!info->is_visible)
+ return;
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (procdata->tree));
+
+ if (procdata->selected_process == info)
+ procdata->selected_process = NULL;
+
+ gtk_tree_store_remove (GTK_TREE_STORE (model), &info->node);
+
+ info->is_visible = FALSE;
+}
+
+
+static void
+remove_info_from_list (ProcInfo *info, ProcData *procdata)
+{
+ GSList *child;
+ ProcInfo * const parent = info->parent;
+
+ /* Remove info from parent list */
+ if (parent)
+ parent->children = g_slist_remove (parent->children, info);
+
+ /* Add any children to parent list */
+ for(child = info->children; child; child = g_slist_next (child)) {
+ ProcInfo *child_info = static_cast<ProcInfo*>(child->data);
+ child_info->parent = parent;
+ }
+
+ if(parent) {
+ parent->children = g_slist_concat(parent->children,
+ info->children);
+ info->children = NULL;
+ }
+
+ /* Remove from list */
+ procdata->info = g_list_remove (procdata->info, info);
+ g_hash_table_remove(procdata->pids, GINT_TO_POINTER(info->pid));
+ proctable_free_info(info);
+}
+
+
+static void
+update_info (ProcData *procdata, ProcInfo *info)
+{
+ glibtop_proc_state procstate;
+
+ glibtop_get_proc_state (&procstate, info->pid);
+ get_process_status (info, &procstate);
+
+ if (procdata->config.whose_process == ACTIVE_PROCESSES) {
+
+ /* process started running */
+ if (info->is_running && (!info->is_visible)) {
+ insert_info_to_tree (info, procdata);
+ return;
+ }
+ /* process was running but not anymore */
+ else if ((!info->is_running) && info->is_visible) {
+ remove_info_from_tree (info, procdata);
+ return;
+ }
+ else if (!info->is_running)
+ return;
+ }
+
+ if (info->is_visible) {
+ GtkTreeModel *model;
+ glibtop_proc_uid procuid;
+ glibtop_proc_time proctime;
+
+ glibtop_get_proc_uid (&procuid, info->pid);
+ glibtop_get_proc_time (&proctime, info->pid);
+
+ get_process_memory_info(info);
+ get_process_user(procdata, info, procstate.uid);
+
+ info->pcpu = (proctime.rtime - info->cpu_time_last) * 100 / total_time;
+ info->pcpu = MIN(info->pcpu, 100);
+
+ info->cpu_time_last = proctime.rtime;
+ info->nice = procuid.nice;
+
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (procdata->tree));
+
+ update_info_mutable_cols(GTK_TREE_STORE (model), procdata, info);
+ }
+}
+
+
+static ProcInfo *
+procinfo_new (ProcData *procdata, gint pid)
+{
+ ProcInfo *info;
+ glibtop_proc_state procstate;
+ glibtop_proc_time proctime;
+ glibtop_proc_uid procuid;
+ glibtop_proc_args procargs;
+ gchar** arguments;
+
+ info = g_slice_new0(ProcInfo);
+
+ info->pid = pid;
+ info->uid = -1;
+
+ glibtop_get_proc_state (&procstate, pid);
+ glibtop_get_proc_uid (&procuid, pid);
+ glibtop_get_proc_time (&proctime, pid);
+ arguments = glibtop_get_proc_argv (&procargs, pid, 0);
+
+ /* FIXME : wrong. name and arguments may change with exec* */
+ get_process_name (info, procstate.cmd, arguments[0]);
+ get_process_user (procdata, info, procstate.uid);
+
+ info->tooltip = g_strjoinv(" ", arguments);
+ info->arguments = g_strescape(info->tooltip, "\\\"");
+ g_strfreev(arguments);
+
+ info->pcpu = 0;
+ info->cpu_time_last = proctime.rtime;
+ info->start_time = proctime.start_time;
+ info->nice = procuid.nice;
+
+ get_process_memory_info(info);
+ get_process_status (info, &procstate);
+ get_process_selinux_context (info);
+
+ info->pixbuf = procdata->pretty_table.get_icon(info->name, pid);
+
+ info->parent = find_parent (procdata, procuid.ppid);
+ if (info->parent) {
+ info->parent->children = g_slist_prepend (info->parent->children, info);
+ }
+
+ info->is_visible = FALSE;
+
+ return info;
+}
+
+
+
+static void cb_exclude(ProcInfo* info, GPtrArray *addition)
+{
+ g_ptr_array_remove_fast (addition, info);
+}
+
+
+static void
+refresh_list (ProcData *procdata, const unsigned *pid_list, const guint n)
+{
+ GHashTable *pid_hash;
+ GList *list;
+ GPtrArray *addition_list = g_ptr_array_new ();
+ GPtrArray *removal_list = g_ptr_array_new ();
+ GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (procdata->tree));
+ guint i;
+
+ /* Add or update processes */
+ for(i = 0; i < n; ++i) {
+ ProcInfo *info;
+
+ info = proctable_find_process (pid_list[i], procdata);
+ if (!info) {
+ info = procinfo_new (procdata, pid_list[i]);
+ g_ptr_array_add(addition_list, info);
+ procdata->info = g_list_prepend (procdata->info, info);
+ g_hash_table_insert(procdata->pids, GINT_TO_POINTER(info->pid), info);
+ }
+ else {
+ update_info (procdata, info);
+ }
+ }
+
+
+ /* Remove processes */
+
+ /* use a hash for fast lookup
+ !NULL as data for every key */
+
+ pid_hash = g_hash_table_new(NULL, NULL);
+ for(i = 0; i < n; ++i)
+ g_hash_table_insert(pid_hash,
+ GINT_TO_POINTER(pid_list[i]),
+ GINT_TO_POINTER(1 /* !NULL */));
+
+
+ for(list = procdata->info; list; list = g_list_next (list)) {
+ ProcInfo * const info = static_cast<ProcInfo*>(list->data);
+
+ if(!g_hash_table_lookup(pid_hash, GINT_TO_POINTER(info->pid)))
+ {
+ g_ptr_array_add (removal_list, info);
+ /* remove all children from tree */
+ if (info->is_visible) {
+ GtkTreeIter child;
+ if (gtk_tree_model_iter_children (model, &child, &info->node))
+ remove_children_from_tree (procdata, model, &child, addition_list);
+ }
+ }
+ }
+
+ g_hash_table_destroy(pid_hash);
+
+ g_ptr_array_foreach(removal_list, (GFunc) cb_exclude, addition_list);
+
+ /* Add or remove processes from the tree */
+ g_ptr_array_foreach(removal_list, (GFunc) remove_info_from_tree, procdata);
+ g_ptr_array_foreach(addition_list, (GFunc) insert_info_to_tree , procdata);
+
+ /* Remove processes from the internal GList */
+ g_ptr_array_foreach(removal_list, (GFunc) remove_info_from_list, procdata);
+
+ g_ptr_array_free (addition_list, TRUE);
+ g_ptr_array_free (removal_list, TRUE);
+}
+
+
+void
+proctable_update_list (ProcData * const procdata)
+{
+ unsigned *pid_list;
+ glibtop_proclist proclist;
+ glibtop_cpu cpu;
+ gint which, arg;
+
+ switch (procdata->config.whose_process) {
+ case ALL_PROCESSES:
+ case ACTIVE_PROCESSES:
+ which = GLIBTOP_KERN_PROC_ALL;
+ arg = 0;
+ break;
+ default:
+ which = GLIBTOP_KERN_PROC_UID;
+ arg = getuid ();
+ break;
+ }
+
+ pid_list = glibtop_get_proclist (&proclist, which, arg);
+
+ /* FIXME: total cpu time elapsed should be calculated on an individual basis here
+ ** should probably have a total_time_last gint in the ProcInfo structure */
+ glibtop_get_cpu (&cpu);
+ total_time = MAX(cpu.total - total_time_last, 1);
+ total_time_last = cpu.total;
+
+ refresh_list (procdata, pid_list, proclist.number);
+
+ g_free (pid_list);
+
+ /* proclist.number == g_list_length(procdata->info) == g_hash_table_size(procdata->pids) */
+}
+
+
+void
+proctable_update_all (ProcData * const procdata)
+{
+ char* string;
+
+ string = make_loadavg_string();
+ gtk_label_set_text (GTK_LABEL(procdata->loadavg), string);
+ g_free (string);
+
+ proctable_update_list (procdata);
+}
+
+
+void
+proctable_clear_tree (ProcData * const procdata)
+{
+ GtkTreeModel *model;
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (procdata->tree));
+
+ gtk_tree_store_clear (GTK_TREE_STORE (model));
+
+ proctable_free_table (procdata);
+
+ update_sensitivity(procdata);
+}
+
+
+void
+proctable_free_table (ProcData * const procdata)
+{
+ GList *list = procdata->info;
+
+ while (list)
+ {
+ ProcInfo *info = static_cast<ProcInfo*>(list->data);
+ proctable_free_info(info);
+ list = g_list_next (list);
+ }
+
+ g_list_free (procdata->info);
+ procdata->info = NULL;
+
+ g_hash_table_destroy(procdata->pids);
+ procdata->pids = g_hash_table_new(NULL, NULL);
+}
+
+
+
+char*
+make_loadavg_string(void)
+{
+ glibtop_loadavg buf;
+
+ glibtop_get_loadavg(&buf);
+
+ return g_strdup_printf(
+ _("Load averages for the last 1, 5, 15 minutes: "
+ "%0.2f, %0.2f, %0.2f"),
+ buf.loadavg[0],
+ buf.loadavg[1],
+ buf.loadavg[2]);
+}
+
+
+
+void
+_ProcInfo::set_icon(GdkPixbuf* icon)
+{
+ if (this->pixbuf)
+ g_object_unref(this->pixbuf);
+
+ this->pixbuf = icon;
+ g_object_ref(icon);
+
+ if (this->is_visible) {
+ GtkTreeModel *model;
+ model = gtk_tree_view_get_model(GTK_TREE_VIEW(ProcData::get_instance()->tree));
+ gtk_tree_store_set(GTK_TREE_STORE(model), &this->node,
+ COL_PIXBUF, this->pixbuf,
+ -1);
+ }
+}
diff -Nrup gnome-system-monitor-2.17.5/src/proctable.h gnome-system-monitor-2.17.5.trunk/src/proctable.h
--- gnome-system-monitor-2.17.5/src/proctable.h 2007-01-03 06:15:36.000000000 +0800
+++ gnome-system-monitor-2.17.5.trunk/src/proctable.h 2007-01-23 11:41:38.490012000 +0800
@@ -26,42 +26,45 @@
enum
{
- COL_NAME = 0,
- COL_USER,
- COL_STATUS,
- COL_VMSIZE,
- COL_MEMRES,
- COL_MEMWRITABLE,
- COL_MEMSHARED,
- COL_MEMXSERVER,
- COL_CPU,
- COL_CPU_TIME,
- COL_START_TIME,
- COL_NICE,
- COL_PID,
- COL_SECURITYCONTEXT,
- COL_ARGS,
- COL_MEM,
- COL_PIXBUF,
- COL_POINTER,
- COL_TOOLTIP,
- NUM_COLUMNS
+ COL_NAME = 0,
+ COL_USER,
+ COL_STATUS,
+ COL_VMSIZE,
+ COL_MEMRES,
+ COL_MEMWRITABLE,
+ COL_MEMSHARED,
+ COL_MEMXSERVER,
+ COL_CPU,
+ COL_CPU_TIME,
+ COL_START_TIME,
+ COL_NICE,
+ COL_PID,
+ COL_SECURITYCONTEXT,
+ COL_ARGS,
+ COL_MEM,
+ COL_PIXBUF,
+ COL_POINTER,
+ COL_TOOLTIP,
+ NUM_COLUMNS
};
+G_BEGIN_DECLS
-GtkWidget* proctable_new (ProcData *data) G_GNUC_INTERNAL;
-void proctable_update_table (ProcData *data) G_GNUC_INTERNAL;
-void proctable_update_list (ProcData *data) G_GNUC_INTERNAL;
-void insert_info_to_tree (ProcInfo *info, ProcData *procdata) G_GNUC_INTERNAL;
-void remove_info_from_tree (ProcInfo *info, ProcData *procdata) G_GNUC_INTERNAL;
-ProcInfo * proctable_find_process (guint pid, ProcData *procdata) G_GNUC_INTERNAL;
-void proctable_update_all (ProcData *data) G_GNUC_INTERNAL;
-void proctable_clear_tree (ProcData *data) G_GNUC_INTERNAL;
-void proctable_free_table (ProcData *data) G_GNUC_INTERNAL;
+G_GNUC_INTERNAL GtkWidget* proctable_new (ProcData *data);
+G_GNUC_INTERNAL void proctable_update_table (ProcData *data);
+G_GNUC_INTERNAL void proctable_update_list (ProcData *data);
+G_GNUC_INTERNAL void insert_info_to_tree (ProcInfo *info, ProcData *procdata);
+G_GNUC_INTERNAL void remove_info_from_tree (ProcInfo *info, ProcData *procdata);
+G_GNUC_INTERNAL ProcInfo * proctable_find_process (guint pid, ProcData *procdata);
+G_GNUC_INTERNAL void proctable_update_all (ProcData *data);
+G_GNUC_INTERNAL void proctable_clear_tree (ProcData *data);
+G_GNUC_INTERNAL void proctable_free_table (ProcData *data);
-GSList* proctable_get_columns_order(GtkTreeView *treeview) G_GNUC_INTERNAL;
-void proctable_set_columns_order(GtkTreeView *treeview, GSList *order) G_GNUC_INTERNAL;
+G_GNUC_INTERNAL GSList* proctable_get_columns_order(GtkTreeView *treeview);
+G_GNUC_INTERNAL void proctable_set_columns_order(GtkTreeView *treeview, GSList *order);
-char* make_loadavg_string(void) G_GNUC_INTERNAL;
+G_GNUC_INTERNAL char* make_loadavg_string(void);
+
+G_END_DECLS
#endif /* _PROCMAN_PROCTABLE_H_ */
diff -Nrup gnome-system-monitor-2.17.5/src/selinux.h gnome-system-monitor-2.17.5.trunk/src/selinux.h
--- gnome-system-monitor-2.17.5/src/selinux.h 2007-01-03 06:15:36.000000000 +0800
+++ gnome-system-monitor-2.17.5.trunk/src/selinux.h 2007-01-23 11:41:38.489168000 +0800
@@ -5,10 +5,10 @@
#include "procman.h"
-void
-get_process_selinux_context (ProcInfo *info) G_GNUC_INTERNAL;
+G_GNUC_INTERNAL void
+get_process_selinux_context (ProcInfo *info);
-gboolean
-can_show_security_context_column (void) G_GNUC_INTERNAL G_GNUC_CONST;
+G_GNUC_INTERNAL gboolean
+can_show_security_context_column (void) G_GNUC_CONST;
#endif /* PROCMAN_SELINUX_H_20050525 */
diff -Nrup gnome-system-monitor-2.17.5/src/util.h gnome-system-monitor-2.17.5.trunk/src/util.h
--- gnome-system-monitor-2.17.5/src/util.h 2007-01-05 05:08:49.000000000 +0800
+++ gnome-system-monitor-2.17.5.trunk/src/util.h 2007-01-23 11:41:38.516345000 +0800
@@ -25,22 +25,22 @@ inline int procman_cmp(T x, T y)
#define PROCMAN_CMP(X, Y) procman_cmp((X), (Y))
#define PROCMAN_RCMP(X, Y) procman_cmp((Y), (X));
-GtkWidget*
+G_GNUC_INTERNAL GtkWidget*
procman_make_label_for_mmaps_or_ofiles(const char *format,
const char *process_name,
- unsigned pid) G_GNUC_INTERNAL;
+ unsigned pid);
-gchar*
-SI_gnome_vfs_format_file_size_for_display (GnomeVFSFileSize size) G_GNUC_INTERNAL;
+G_GNUC_INTERNAL gchar*
+SI_gnome_vfs_format_file_size_for_display (GnomeVFSFileSize size);
-gboolean
-load_symbols(const char *module, ...) G_GNUC_INTERNAL G_GNUC_NULL_TERMINATED;
+G_GNUC_INTERNAL gboolean
+load_symbols(const char *module, ...) G_GNUC_NULL_TERMINATED;
-void
-procman_debug(const char *format, ...) G_GNUC_INTERNAL G_GNUC_PRINTF(1, 2);
+G_GNUC_INTERNAL void
+procman_debug(const char *format, ...) G_GNUC_PRINTF(1, 2);
inline string make_string(char *c_str)
diff -Nrup gnome-system-monitor-2.17.5/src/util.h~ gnome-system-monitor-2.17.5.trunk/src/util.h~
--- gnome-system-monitor-2.17.5/src/util.h~ 1970-01-01 08:00:00.000000000 +0800
+++ gnome-system-monitor-2.17.5.trunk/src/util.h~ 2007-01-23 11:41:38.528821000 +0800
@@ -0,0 +1,74 @@
+#ifndef H_GNOME_SYSTEM_MONITOR_UTIL_1123178725
+#define H_GNOME_SYSTEM_MONITOR_UTIL_1123178725
+
+#include <glib.h>
+#include <libgnomevfs/gnome-vfs-utils.h>
+#include <stddef.h>
+#include <string>
+#include <functional>
+#include <algorithm>
+
+using std::string;
+
+template<typename T>
+inline int procman_cmp(T x, T y)
+{
+ if (x == y)
+ return 0;
+
+ if (x < y)
+ return -1;
+
+ return 1;
+}
+
+#define PROCMAN_CMP(X, Y) procman_cmp((X), (Y))
+#define PROCMAN_RCMP(X, Y) procman_cmp((Y), (X));
+
+GtkWidget*
+procman_make_label_for_mmaps_or_ofiles(const char *format,
+ const char *process_name,
+ unsigned pid) G_GNUC_INTERNAL;
+
+
+gchar*
+SI_gnome_vfs_format_file_size_for_display (GnomeVFSFileSize size) G_GNUC_INTERNAL;
+
+
+gboolean
+load_symbols(const char *module, ...) G_GNUC_INTERNAL G_GNUC_NULL_TERMINATED;
+
+
+void
+procman_debug(const char *format, ...) G_GNUC_INTERNAL G_GNUC_PRINTF(1, 2);
+
+
+inline string make_string(char *c_str)
+{
+ string s(c_str);
+ g_free(c_str);
+ return s;
+}
+
+
+
+
+template<typename Map>
+class UnrefMapValues
+ : public std::unary_function<void, Map>
+{
+public:
+ void operator()(const typename Map::value_type &it) const
+ {
+ g_object_unref(it.second);
+ }
+};
+
+
+template<typename Map>
+inline void unref_map_values(Map &map)
+{
+ std::for_each(map.begin(), map.end(), UnrefMapValues<Map>());
+}
+
+#endif /* H_GNOME_SYSTEM_MONITOR_UTIL_1123178725 */