From 61e25238728dd5cb9922932a5b7279eb6cdb15da Mon Sep 17 00:00:00 2001 From: rbuj Date: Wed, 2 Dec 2020 09:54:00 +0100 Subject: multiload: Use common subdirs - src, data --- configure.ac | 4 +- multiload/Makefile.am | 67 +- multiload/autoscaler.c | 51 -- multiload/autoscaler.h | 26 - multiload/data/Makefile.am | 44 ++ multiload/data/multiload-applet-menu.xml | 6 + ...MultiLoadApplet.mate-panel-applet.desktop.in.in | 17 + ....panel.applet.MultiLoadAppletFactory.service.in | 3 + .../org.mate.panel.applet.multiload.gschema.xml.in | 156 ++++ multiload/global.h | 164 ---- multiload/linux-proc.c | 442 ----------- multiload/linux-proc.h | 13 - multiload/load-graph.c | 501 ------------ multiload/load-graph.h | 24 - multiload/main.c | 575 -------------- multiload/multiload-applet-menu.xml | 6 - multiload/netspeed.c | 70 -- multiload/netspeed.h | 15 - ...MultiLoadApplet.mate-panel-applet.desktop.in.in | 17 - ....panel.applet.MultiLoadAppletFactory.service.in | 3 - .../org.mate.panel.applet.multiload.gschema.xml.in | 156 ---- multiload/properties.c | 868 --------------------- multiload/src/Makefile.am | 29 + multiload/src/autoscaler.c | 51 ++ multiload/src/autoscaler.h | 26 + multiload/src/global.h | 164 ++++ multiload/src/linux-proc.c | 442 +++++++++++ multiload/src/linux-proc.h | 13 + multiload/src/load-graph.c | 501 ++++++++++++ multiload/src/load-graph.h | 24 + multiload/src/main.c | 573 ++++++++++++++ multiload/src/netspeed.c | 70 ++ multiload/src/netspeed.h | 15 + multiload/src/properties.c | 868 +++++++++++++++++++++ po/POTFILES.in | 14 +- 35 files changed, 3013 insertions(+), 3005 deletions(-) delete mode 100644 multiload/autoscaler.c delete mode 100644 multiload/autoscaler.h create mode 100644 multiload/data/Makefile.am create mode 100644 multiload/data/multiload-applet-menu.xml create mode 100644 multiload/data/org.mate.applets.MultiLoadApplet.mate-panel-applet.desktop.in.in create mode 100644 multiload/data/org.mate.panel.applet.MultiLoadAppletFactory.service.in create mode 100644 multiload/data/org.mate.panel.applet.multiload.gschema.xml.in delete mode 100644 multiload/global.h delete mode 100644 multiload/linux-proc.c delete mode 100644 multiload/linux-proc.h delete mode 100644 multiload/load-graph.c delete mode 100644 multiload/load-graph.h delete mode 100644 multiload/main.c delete mode 100644 multiload/multiload-applet-menu.xml delete mode 100644 multiload/netspeed.c delete mode 100644 multiload/netspeed.h delete mode 100644 multiload/org.mate.applets.MultiLoadApplet.mate-panel-applet.desktop.in.in delete mode 100644 multiload/org.mate.panel.applet.MultiLoadAppletFactory.service.in delete mode 100644 multiload/org.mate.panel.applet.multiload.gschema.xml.in delete mode 100644 multiload/properties.c create mode 100644 multiload/src/Makefile.am create mode 100644 multiload/src/autoscaler.c create mode 100644 multiload/src/autoscaler.h create mode 100644 multiload/src/global.h create mode 100644 multiload/src/linux-proc.c create mode 100644 multiload/src/linux-proc.h create mode 100644 multiload/src/load-graph.c create mode 100644 multiload/src/load-graph.h create mode 100644 multiload/src/main.c create mode 100644 multiload/src/netspeed.c create mode 100644 multiload/src/netspeed.h create mode 100644 multiload/src/properties.c diff --git a/configure.ac b/configure.ac index 7b5df13c..3e5884dc 100644 --- a/configure.ac +++ b/configure.ac @@ -564,8 +564,10 @@ drivemount/data/org.mate.drivemount.gschema.xml drivemount/help/Makefile drivemount/src/Makefile multiload/Makefile -multiload/org.mate.panel.applet.multiload.gschema.xml +multiload/data/Makefile +multiload/data/org.mate.panel.applet.multiload.gschema.xml multiload/docs/Makefile +multiload/src/Makefile charpick/Makefile charpick/org.mate.panel.applet.charpick.gschema.xml charpick/help/Makefile diff --git a/multiload/Makefile.am b/multiload/Makefile.am index ae48940a..576d2297 100644 --- a/multiload/Makefile.am +++ b/multiload/Makefile.am @@ -1,68 +1,3 @@ -SUBDIRS = docs - -AM_CPPFLAGS = \ - -I$(srcdir) \ - -DMULTILOAD_MENU_UI_DIR=\""$(uidir)"\" \ - $(MATE_APPLETS4_CFLAGS) \ - $(GTOP_APPLETS_CFLAGS) \ - $(GIO_CFLAGS) \ - ${WARN_CFLAGS} - -libexec_PROGRAMS = mate-multiload-applet - -mate_multiload_applet_SOURCES = \ - global.h \ - linux-proc.h \ - load-graph.h \ - linux-proc.c \ - load-graph.c \ - main.c \ - properties.c \ - netspeed.c netspeed.h \ - autoscaler.c \ - autoscaler.h - -mate_multiload_applet_LDADD = \ - $(MATE_APPLETS4_LIBS) \ - $(GTOP_APPLETS_LIBS) \ - $(GIO_LIBS) \ - -lm - -multiload_gschema_in_files = org.mate.panel.applet.multiload.gschema.xml.in -gsettings_SCHEMAS = $(multiload_gschema_in_files:.xml.in=.xml) -@GSETTINGS_RULES@ - -EXTRA_DIST = \ - $(applet_in_files).in \ - $(service_in_files) \ - $(multiload_gschema_in_files) \ - $(ui_DATA) - -uidir = $(datadir)/mate/ui -ui_DATA = multiload-applet-menu.xml - -appletdir = $(datadir)/mate-panel/applets -applet_in_files = org.mate.applets.MultiLoadApplet.mate-panel-applet.desktop.in -applet_DATA = $(applet_in_files:.mate-panel-applet.desktop.in=.mate-panel-applet) - -$(applet_in_files): $(applet_in_files).in Makefile - $(AM_V_GEN)sed \ - -e "s|\@LIBEXECDIR\@|$(libexecdir)|" \ - -e "s|\@VERSION\@|$(PACKAGE_VERSION)|" \ - $< > $@ - -$(applet_DATA): $(applet_in_files) Makefile - $(AM_V_GEN) $(MSGFMT) --desktop --keyword=Name --keyword=Description --template $< -d $(top_srcdir)/po -o $@ - -servicedir = $(datadir)/dbus-1/services -service_in_files = org.mate.panel.applet.MultiLoadAppletFactory.service.in -service_DATA = $(service_in_files:.service.in=.service) - -org.mate.panel.applet.MultiLoadAppletFactory.service: $(service_in_files) - $(AM_V_GEN)sed \ - -e "s|\@LIBEXECDIR\@|$(libexecdir)|" \ - $< > $@ - -CLEANFILES = $(applet_DATA) $(applet_in_files) $(service_DATA) $(gsettings_SCHEMAS) *.gschema.valid +SUBDIRS = docs data src -include $(top_srcdir)/git.mk diff --git a/multiload/autoscaler.c b/multiload/autoscaler.c deleted file mode 100644 index 735b2713..00000000 --- a/multiload/autoscaler.c +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include - -#include "autoscaler.h" - -/* i wish i could have used C99 initializers instead of writing this function */ -void autoscaler_init(AutoScaler *that, unsigned interval, unsigned floor) -{ - that->update_interval = interval; - that->floor = floor; - that->max = 0; - that->count = 0; - that->last_update = 0; - that->sum = 0.0f; - that->last_average = 0.0f; -} - - -unsigned autoscaler_get_max(AutoScaler *that, unsigned current) -{ - time_t now; - - that->sum += current; - that->count++; - time(&now); - - if((float)difftime(now, that->last_update) > that->update_interval) - { - float new_average = that->sum / that->count; - float average; - - if(new_average < that->last_average) - average = ((that->last_average * 0.5f) + new_average) / 1.5f; - else - average = new_average; - - that->max = average * 1.2f; - - that->sum = 0.0f; - that->count = 0; - that->last_update = now; - that->last_average = average; - } - - that->max = MAX(that->max, current); - that->max = MAX(that->max, that->floor); -#if 0 - printf("%p max = %u, current = %u, last_average = %f\n", that, that->max, current, that->last_average); -#endif - return that->max; -} diff --git a/multiload/autoscaler.h b/multiload/autoscaler.h deleted file mode 100644 index d0ae4cd6..00000000 --- a/multiload/autoscaler.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef MATE_APPLETS_MULTILOAD_AUTOSCALER_H -#define MATE_APPLETS_MULTILOAD_AUTOSCALER_H - -#include -#include - -typedef struct _AutoScaler AutoScaler; - -struct _AutoScaler -{ - /* const */ unsigned update_interval; - /* const */ unsigned floor; - unsigned max; - unsigned count; - time_t last_update; - float sum; - float last_average; -}; - - -G_GNUC_INTERNAL void autoscaler_init(AutoScaler *that, unsigned interval, unsigned floor); - -G_GNUC_INTERNAL unsigned autoscaler_get_max(AutoScaler *that, unsigned current); - - -#endif /* MATE_APPLETS_MULTILOAD_AUTOSCALER_H */ diff --git a/multiload/data/Makefile.am b/multiload/data/Makefile.am new file mode 100644 index 00000000..bacb6f1e --- /dev/null +++ b/multiload/data/Makefile.am @@ -0,0 +1,44 @@ +multiload_gschema_in_files = org.mate.panel.applet.multiload.gschema.xml.in +gsettings_SCHEMAS = $(multiload_gschema_in_files:.xml.in=.xml) +@GSETTINGS_RULES@ + +uidir = $(datadir)/mate/ui +ui_DATA = multiload-applet-menu.xml + +appletdir = $(datadir)/mate-panel/applets +applet_in_in_files = org.mate.applets.MultiLoadApplet.mate-panel-applet.desktop.in.in +applet_in_files = $(applet_in_in_files:.desktop.in.in=.desktop.in) +applet_DATA = $(applet_in_files:.mate-panel-applet.desktop.in=.mate-panel-applet) + +$(applet_in_files): $(applet_in_files).in Makefile + $(AM_V_GEN)sed \ + -e "s|\@LIBEXECDIR\@|$(libexecdir)|" \ + -e "s|\@VERSION\@|$(PACKAGE_VERSION)|" \ + $< > $@ + +$(applet_DATA): $(applet_in_files) Makefile + $(AM_V_GEN) $(MSGFMT) --desktop --keyword=Name --keyword=Description --template $< -d $(top_srcdir)/po -o $@ + +servicedir = $(datadir)/dbus-1/services +service_in_files = org.mate.panel.applet.MultiLoadAppletFactory.service.in +service_DATA = $(service_in_files:.service.in=.service) + +org.mate.panel.applet.MultiLoadAppletFactory.service: $(service_in_files) + $(AM_V_GEN)sed \ + -e "s|\@LIBEXECDIR\@|$(libexecdir)|" \ + $< > $@ + +CLEANFILES = \ + $(applet_DATA) \ + $(applet_in_files) \ + $(service_DATA) \ + $(gsettings_SCHEMAS) \ + *.gschema.valid + +EXTRA_DIST = \ + $(applet_in_in_files) \ + $(service_in_files) \ + $(multiload_gschema_in_files) \ + $(ui_DATA) + +-include $(top_srcdir)/git.mk diff --git a/multiload/data/multiload-applet-menu.xml b/multiload/data/multiload-applet-menu.xml new file mode 100644 index 00000000..88d28dd9 --- /dev/null +++ b/multiload/data/multiload-applet-menu.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/multiload/data/org.mate.applets.MultiLoadApplet.mate-panel-applet.desktop.in.in b/multiload/data/org.mate.applets.MultiLoadApplet.mate-panel-applet.desktop.in.in new file mode 100644 index 00000000..3eacb2fb --- /dev/null +++ b/multiload/data/org.mate.applets.MultiLoadApplet.mate-panel-applet.desktop.in.in @@ -0,0 +1,17 @@ +[Applet Factory] +Id=MultiLoadAppletFactory +Location=@LIBEXECDIR@/mate-multiload-applet +Name=MultiLoad Applet Factory +Description=Factory for creating the load applet. + +[MultiLoadApplet] +Name=System Monitor +Description=A system load indicator +# Translators: Do NOT translate or transliterate this text (this is an icon file name)! +Icon=utilities-system-monitor +MateComponentId=OAFIID:MATE_MultiLoadApplet +X-MATE-Bugzilla-Bugzilla=MATE +X-MATE-Bugzilla-Product=mate-applets +X-MATE-Bugzilla-Component=multiload +X-MATE-Bugzilla-Version=@VERSION@ +X-MATE-Bugzilla-OtherBinaries=multiload-applet-2 diff --git a/multiload/data/org.mate.panel.applet.MultiLoadAppletFactory.service.in b/multiload/data/org.mate.panel.applet.MultiLoadAppletFactory.service.in new file mode 100644 index 00000000..d4c7da3c --- /dev/null +++ b/multiload/data/org.mate.panel.applet.MultiLoadAppletFactory.service.in @@ -0,0 +1,3 @@ +[D-BUS Service] +Name=org.mate.panel.applet.MultiLoadAppletFactory +Exec=@LIBEXECDIR@/mate-multiload-applet diff --git a/multiload/data/org.mate.panel.applet.multiload.gschema.xml.in b/multiload/data/org.mate.panel.applet.multiload.gschema.xml.in new file mode 100644 index 00000000..9f199bc3 --- /dev/null +++ b/multiload/data/org.mate.panel.applet.multiload.gschema.xml.in @@ -0,0 +1,156 @@ + + + + true + Enable CPU load graph + + + false + Enable memory load graph + + + false + Enable network load graph + + + false + Enable swap load graph + + + false + Enable load average graph + + + false + Enable disk load graph + + + 500 + Applet refresh rate in milliseconds + + + 40 + Graph size + For horizontal panels, the width of the graphs in pixels. For vertical panels, this is the height of the graphs. + + + '#0072b3' + Graph color for user-related CPU activity + + + '#0092e6' + Graph color for system-related CPU activity + + + '#00a3ff' + Graph color for nice-related CPU activity + + + '#002f3d' + Graph color for iowait related CPU activity + + + '#000000' + CPU graph background color + + + '#00b35b' + Graph color for user-related memory usage + + + '#00e675' + Graph color for shared memory + + + '#00ff82' + Graph color for buffer memory + + + '#AAF5D0' + Graph color for cached memory + + + '#000000' + Memory graph background color + + + '#fce94f' + Graph color for input network activity + + + '#edd400' + Graph color for output network activity + + + '#c4a000' + Graph color for loopback network usage + + + '#000000' + Network graph background color + + + '#ffffff' + Grid line color + + + '#0000ff' + Indicator color + + + + 1000000 + Network threshold 1 in bytes + + + + 10000000 + Network threshold 2 in bytes + + + + 100000000 + Network threshold 3 in bytes + + + '#8b00c3' + Graph color for user-related swap usage + + + '#000000' + Swap graph background color + + + '#d50000' + Graph color for load average + + + '#000000' + Load graph background color + + + '#ffffff' + Grid line color + + + '#C65000' + Graph color for disk read + + + '#FF6700' + Graph color for disk write + + + '#000000' + Background color for disk load graph + + + false + Uses /proc/diskstats to determine NVMe disk load + + + 'mate-system-monitor.desktop' + The desktop description file to execute as the system monitor + + + diff --git a/multiload/global.h b/multiload/global.h deleted file mode 100644 index da3383c4..00000000 --- a/multiload/global.h +++ /dev/null @@ -1,164 +0,0 @@ -#ifndef __GLOBAL_H__ -#define __GLOBAL_H__ - -#include -#include -#include -#include -#include -#include - -G_BEGIN_DECLS - -#define MIN_NET_THRESHOLD1 10 -#define MIN_NET_THRESHOLD2 11 -#define MIN_NET_THRESHOLD3 12 -#define MAX_NET_THRESHOLD1 999999998 -#define MAX_NET_THRESHOLD2 999999999 -#define MAX_NET_THRESHOLD3 1000000000 - -#define VIEW_CPULOAD_KEY "view-cpuload" -#define VIEW_MEMLOAD_KEY "view-memload" -#define VIEW_NETLOAD_KEY "view-netload" -#define VIEW_SWAPLOAD_KEY "view-swapload" -#define VIEW_LOADAVG_KEY "view-loadavg" -#define VIEW_DISKLOAD_KEY "view-diskload" - -typedef struct _MultiloadApplet MultiloadApplet; -typedef struct _LoadGraph LoadGraph; -typedef void (*LoadGraphDataFunc) (int, int [], LoadGraph *); - -#include "netspeed.h" - -typedef enum { - graph_cpuload = 0, - graph_memload, - graph_netload2, - graph_swapload, - graph_loadavg, - graph_diskload, - graph_n, -} E_graph; - -typedef enum { - memload_user = 0, - memload_shared, - memload_buffer, - memload_cached, - memload_free, - memload_n -} E_memload; - -typedef enum { - cpuload_usr = 0, - cpuload_sys, - cpuload_nice, - cpuload_iowait, - cpuload_free, - cpuload_n -} E_cpuload; - -typedef enum { - diskload_read = 0, - diskload_write, - diskload_free, - diskload_n -} E_diskload; - -typedef enum { - swapload_used = 0, - swapload_free, - swapload_n -} E_swapload; - -struct _LoadGraph { - MultiloadApplet *multiload; - - guint n, id; - guint speed, size; - guint orient, pixel_size; - guint draw_width, draw_height; - LoadGraphDataFunc get_data; - - guint allocated; - - GdkRGBA *colors; - gint **data; - guint data_size; - guint *pos; - - GtkWidget *main_widget; - GtkWidget *frame, *box, *disp; - cairo_surface_t *surface; - int timer_index; - - gboolean visible; - gboolean tooltip_update; - const gchar *name; -}; - -struct _MultiloadApplet -{ - MatePanelApplet *applet; - - GSettings *settings; - - LoadGraph *graphs [graph_n]; - - GtkWidget *box; - - gboolean view_cpuload; - gboolean view_memload; - gboolean view_netload; - gboolean view_swapload; - gboolean view_loadavg; - gboolean view_diskload; - - GtkWidget *about_dialog; - GtkWidget *check_boxes [graph_n]; - GtkWidget *prop_dialog; - GtkWidget *notebook; - int last_clicked; - - float cpu_used_ratio; - long cpu_time [cpuload_n]; - long cpu_last [cpuload_n]; - int cpu_initialized; - - double loadavg1; - - guint64 memload_user; - guint64 memload_cache; - guint64 memload_total; - - float swapload_used_ratio; - - float diskload_used_ratio; - gboolean nvme_diskstats; - - NetSpeed *netspeed_in; - NetSpeed *netspeed_out; - guint net_threshold1; - guint net_threshold2; - guint net_threshold3; -}; - -#include "load-graph.h" -#include "linux-proc.h" - -/* show properties dialog */ -G_GNUC_INTERNAL void -multiload_properties_cb (GtkAction *action, - MultiloadApplet *ma); - -/* remove the old graphs and rebuild them */ -G_GNUC_INTERNAL void -multiload_applet_refresh (MultiloadApplet *ma); - -/* update the tooltip to the graph's current "used" percentage */ -G_GNUC_INTERNAL void -multiload_applet_tooltip_update (LoadGraph *g); - -G_END_DECLS - -#endif diff --git a/multiload/linux-proc.c b/multiload/linux-proc.c deleted file mode 100644 index 6059e9e3..00000000 --- a/multiload/linux-proc.c +++ /dev/null @@ -1,442 +0,0 @@ -/* From wmload.c, v0.9.2, licensed under the GPL. */ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "linux-proc.h" -#include "autoscaler.h" - -static const unsigned needed_cpu_flags = -(1 << GLIBTOP_CPU_USER) + -(1 << GLIBTOP_CPU_IDLE) + -(1 << GLIBTOP_CPU_SYS) + -(1 << GLIBTOP_CPU_NICE); - -#if 0 -static const unsigned needed_page_flags = -(1 << GLIBTOP_SWAP_PAGEIN) + -(1 << GLIBTOP_SWAP_PAGEOUT); -#endif - -static const unsigned needed_mem_flags = -(1 << GLIBTOP_MEM_USED) + -(1 << GLIBTOP_MEM_FREE); - -static const unsigned needed_swap_flags = -(1 << GLIBTOP_SWAP_USED) + -(1 << GLIBTOP_SWAP_FREE); - -static const unsigned needed_loadavg_flags = -(1 << GLIBTOP_LOADAVG_LOADAVG); - -static const unsigned needed_netload_flags = -(1 << GLIBTOP_NETLOAD_IF_FLAGS) + -(1 << GLIBTOP_NETLOAD_BYTES_TOTAL); - -void -GetLoad (int Maximum, - int data [cpuload_n], - LoadGraph *g) -{ - MultiloadApplet *multiload; - glibtop_cpu cpu; - long cpu_aux [cpuload_n], used = 0, total = 0; - int current_scaled, used_scaled = 0; - int i; - - glibtop_get_cpu (&cpu); - - g_return_if_fail ((cpu.flags & needed_cpu_flags) == needed_cpu_flags); - - multiload = g->multiload; - - multiload->cpu_time [cpuload_usr] = cpu.user; - multiload->cpu_time [cpuload_nice] = cpu.nice; - multiload->cpu_time [cpuload_sys] = cpu.sys; - multiload->cpu_time [cpuload_iowait] = cpu.iowait + cpu.irq + cpu.softirq; - multiload->cpu_time [cpuload_free] = cpu.idle; - - if (!multiload->cpu_initialized) { - memcpy (multiload->cpu_last, multiload->cpu_time, sizeof (multiload->cpu_last)); - multiload->cpu_initialized = 1; - } - - for (i = 0; i < cpuload_n; i++) { - cpu_aux [i] = multiload->cpu_time [i] - multiload->cpu_last [i]; - total += cpu_aux [i]; - } - - for (i = 0; i < cpuload_free; i++) { - used += cpu_aux [i]; - current_scaled = rint ((float)(cpu_aux [i] * Maximum) / (float)total); - used_scaled += current_scaled; - data [i] = current_scaled; - } - data [cpuload_free] = Maximum - used_scaled; - - multiload->cpu_used_ratio = (float)(used) / (float)total; - - memcpy (multiload->cpu_last, multiload->cpu_time, sizeof multiload->cpu_last); -} - -void -GetDiskLoad (int Maximum, - int data [diskload_n], - LoadGraph *g) -{ - static gboolean first_call = TRUE; - static guint64 lastread = 0, lastwrite = 0; - static AutoScaler scaler; - - guint i; - int max; - - guint64 read, write; - guint64 readdiff, writediff; - - MultiloadApplet *multiload; - - multiload = g->multiload; - - - if(first_call) - { - autoscaler_init(&scaler, 60, 500); - } - - read = write = 0; - - if (multiload->nvme_diskstats) - { - FILE *fdr; - char line[255]; - guint64 s_read, s_write; - - fdr = fopen("/proc/diskstats", "r"); - if (!fdr) - { - multiload->nvme_diskstats = FALSE; - g_settings_set_boolean (multiload->settings, "diskload-nvme-diskstats", FALSE); - return; - } - - while (fgets(line, 255, fdr)) - { - /* Match main device, rather than individual partitions (e.g. nvme0n1) */ - if (!g_regex_match_simple("\\snvme\\d+\\w+\\d+\\s", line, 0, 0)) - { - continue; - } - - /* - 6 - sectors read - 10 - sectors written - */ - if (sscanf(line, "%*d %*d %*s %*d %*d %ld %*d %*d %*d %ld", &s_read, &s_write) == 2) - { - read += 512 * s_read; - write += 512 * s_write; - } - } - fclose(fdr); - } - else - { - glibtop_mountlist mountlist; - glibtop_mountentry *mountentries; - - mountentries = glibtop_get_mountlist (&mountlist, FALSE); - - for (i = 0; i < mountlist.number; i++) - { - struct statvfs statresult; - glibtop_fsusage fsusage; - - if (strstr (mountentries[i].devname, "/dev/") == NULL) - continue; - - if (strstr (mountentries[i].mountdir, "/media/") != NULL) - continue; - - if (statvfs (mountentries[i].mountdir, &statresult) < 0) - { - g_debug ("Failed to get statistics for mount entry: %s. Reason: %s. Skipping entry.", - mountentries[i].mountdir, strerror(errno)); - continue; - } - - glibtop_get_fsusage(&fsusage, mountentries[i].mountdir); - read += fsusage.read; write += fsusage.write; - } - - g_free(mountentries); - } - - readdiff = read - lastread; - writediff = write - lastwrite; - - lastread = read; - lastwrite = write; - - if(first_call) - { - first_call = FALSE; - memset(data, 0, 3 * sizeof data[0]); - return; - } - - max = autoscaler_get_max(&scaler, readdiff + writediff); - - multiload->diskload_used_ratio = (float)(readdiff + writediff) / (float)max; - - data [diskload_read] = rint ((float)Maximum * (float)readdiff / (float)max); - data [diskload_write] = rint ((float)Maximum * (float)writediff / (float)max); - data [diskload_free] = Maximum - (data [0] + data[1]); -} - -/* GNU/Linux: - * aux [memload_user] = (mem.total - mem.free) - (mem.cached + mem.buffer) - * aux [memload_shared] = mem.shared; - * aux [memload_cached] = mem.cached - mem.shared; - * aux [memload_buffer] = mem.buffer; - * - * Other operating systems: - * aux [memload_user] = mem.user; - * aux [memload_shared] = mem.shared; - * aux [memload_cached] = mem.cached; - * aux [memload_buffer] = mem.buffer; - */ -void -GetMemory (int Maximum, - int data [memload_n], - LoadGraph *g) -{ - MultiloadApplet *multiload; - glibtop_mem mem; - guint64 aux [memload_n], cache = 0; - int current_scaled, used_scaled = 0; - int i; - - glibtop_get_mem (&mem); - - g_return_if_fail ((mem.flags & needed_mem_flags) == needed_mem_flags); - -#ifndef __linux__ - aux [memload_user] = mem.user; - aux [memload_cached] = mem.cached; -#else - aux [memload_user] = mem.total - mem.free - mem.buffer - mem.cached;; - aux [memload_cached] = mem.cached - mem.shared; -#endif /* __linux__ */ - aux [memload_shared] = mem.shared; - aux [memload_buffer] = mem.buffer; - - for (i = 0; i < memload_free; i++) { - current_scaled = rint ((float)(aux [i] * Maximum) / (float)mem.total); - if (i != memload_user) { - cache += aux [i]; - } - used_scaled += current_scaled; - data [i] = current_scaled; - } - data [memload_free] = MAX (Maximum - used_scaled, 0); - - multiload = g->multiload; - multiload->memload_user = aux [memload_user]; - multiload->memload_cache = cache; - multiload->memload_total = mem.total; -} - -void -GetSwap (int Maximum, - int data [swapload_n], - LoadGraph *g) -{ - int used; - MultiloadApplet *multiload; - glibtop_swap swap; - - glibtop_get_swap (&swap); - g_return_if_fail ((swap.flags & needed_swap_flags) == needed_swap_flags); - - multiload = g->multiload; - - if (swap.total == 0) { - used = 0; - multiload->swapload_used_ratio = 0.0f; - } - else { - float ratio; - - ratio = (float)swap.used / (float)swap.total; - used = rint ((float) Maximum * ratio); - multiload->swapload_used_ratio = ratio; - } - - data [0] = used; - data [1] = Maximum - used; -} - -void -GetLoadAvg (int Maximum, - int data [2], - LoadGraph *g) -{ - glibtop_loadavg loadavg; - MultiloadApplet *multiload; - - glibtop_get_loadavg (&loadavg); - - g_return_if_fail ((loadavg.flags & needed_loadavg_flags) == needed_loadavg_flags); - - multiload = g->multiload; - multiload->loadavg1 = loadavg.loadavg[0]; - - data [0] = rint ((float) Maximum * loadavg.loadavg[0]); - data [1] = Maximum - data[0]; -} - -/* - * Return true if a network device (identified by its name) is virtual - * (ie: not corresponding to a physical device). In case it is a physical - * device or unknown, returns false. - */ -static gboolean -is_net_device_virtual(char *device) -{ - /* - * There is not definitive way to find out. On some systems (Linux - * kernels ≳ 2.19 without option SYSFS_DEPRECATED), there exist a - * directory /sys/devices/virtual/net which only contains virtual - * devices. It's also possible to detect by the fact that virtual - * devices do not have a symlink "device" in - * /sys/class/net/name-of-dev/ . This second method is more complex - * but more reliable. - */ - gboolean ret = FALSE; - char *path = malloc (strlen (device) + strlen ("/sys/class/net//device") + 1); - - if (path == NULL) - return FALSE; - - /* Check if /sys/class/net/name-of-dev/ exists (may be old linux kernel - * or not linux at all). */ - do { - if (sprintf(path, "/sys/class/net/%s", device) < 0) - break; - if (access(path, F_OK) != 0) - break; /* unknown */ - - if (sprintf(path, "/sys/class/net/%s/device", device) < 0) - break; - if (access(path, F_OK) != 0) - ret = TRUE; - } while (0); - - free (path); - return ret; -} - -void -GetNet (int Maximum, - int data [4], - LoadGraph *g) -{ - enum Types { - IN_COUNT = 0, - OUT_COUNT = 1, - LOCAL_COUNT = 2, - COUNT_TYPES = 3 - }; - - static int ticks = 0; - static gulong past[COUNT_TYPES] = {0}; - static AutoScaler scaler; - - gulong present[COUNT_TYPES] = {0}; - - guint i; - gchar **devices; - glibtop_netlist netlist; - - MultiloadApplet *multiload; - - multiload = g->multiload; - - if(ticks == 0) - { - autoscaler_init(&scaler, 60, 501); - } - - devices = glibtop_get_netlist(&netlist); - - for(i = 0; i < netlist.number; ++i) - { - glibtop_netload netload; - - glibtop_get_netload(&netload, devices[i]); - - g_return_if_fail((netload.flags & needed_netload_flags) == needed_netload_flags); - - if (!(netload.if_flags & (1L << GLIBTOP_IF_FLAGS_UP))) - continue; - - if (netload.if_flags & (1L << GLIBTOP_IF_FLAGS_LOOPBACK)) { - /* for loopback in and out are identical, so only count in */ - present[LOCAL_COUNT] += netload.bytes_in; - continue; - } - - /* - * Do not include virtual devices (VPN, PPPOE...) to avoid - * counting the same throughput several times. - */ - if (is_net_device_virtual(devices[i])) - continue; - - present[IN_COUNT] += netload.bytes_in; - present[OUT_COUNT] += netload.bytes_out; - } - - g_strfreev(devices); - netspeed_add (multiload->netspeed_in, present[IN_COUNT]); - netspeed_add (multiload->netspeed_out, present[OUT_COUNT]); - - if(ticks < 2) /* avoid initial spike */ - { - ticks++; - memset(data, 0, COUNT_TYPES * sizeof data[0]); - } - else - { - int delta[COUNT_TYPES]; - - for (i = 0; i < COUNT_TYPES; i++) - { - /* protect against weirdness */ - if (present[i] >= past[i]) - delta[i] = (present[i] - past[i]); - else - delta[i] = 0; - } - - for (i = 0; i < COUNT_TYPES; i++) - data[i] = delta[i]; - - } - - memcpy(past, present, sizeof past); -} diff --git a/multiload/linux-proc.h b/multiload/linux-proc.h deleted file mode 100644 index 0aba1a0e..00000000 --- a/multiload/linux-proc.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef LINUX_PROC_H__ -#define LINUX_PROC_H__ - -#include - -G_GNUC_INTERNAL void GetLoad (int Maximum, int data [cpuload_n], LoadGraph *g); -G_GNUC_INTERNAL void GetDiskLoad (int Maximum, int data [diskload_n], LoadGraph *g); -G_GNUC_INTERNAL void GetMemory (int Maximum, int data [memload_n], LoadGraph *g); -G_GNUC_INTERNAL void GetSwap (int Maximum, int data [swapload_n], LoadGraph *g); -G_GNUC_INTERNAL void GetLoadAvg (int Maximum, int data [2], LoadGraph *g); -G_GNUC_INTERNAL void GetNet (int Maximum, int data [4], LoadGraph *g); - -#endif diff --git a/multiload/load-graph.c b/multiload/load-graph.c deleted file mode 100644 index 953dc5b2..00000000 --- a/multiload/load-graph.c +++ /dev/null @@ -1,501 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "global.h" - -/* - Shifts data right - - data[i+1] = data[i] - - data[i] are int*, 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; - int* last_data; - - /* data[g->draw_width - 1] becomes data[0] */ - last_data = g->data[g->draw_width - 1]; - - /* data[i+1] = data[i] */ - for(i = g->draw_width - 1; i != 0; --i) - g->data[i] = g->data[i - 1]; - - g->data[0] = last_data; -} - - -/* Redraws the backing pixmap for the load graph and updates the window */ -static void -load_graph_draw (LoadGraph *g) -{ - guint i, j, k; - cairo_t *cr; - int load; - MultiloadApplet *multiload; - - multiload = g->multiload; - - /* we might get called before the configure event so that - * g->disp->allocation may not have the correct size - * (after the user resized the applet in the prop dialog). */ - - if (!g->surface) - g->surface = gdk_window_create_similar_surface (gtk_widget_get_window (g->disp), - CAIRO_CONTENT_COLOR, - g->draw_width, g->draw_height); - - cr = cairo_create (g->surface); - cairo_set_line_width (cr, 1.0); - cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); - cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); - - /* all graphs except Load and Net go this path */ - if (g->id != graph_loadavg && g->id != graph_netload2) - { - for (i = 0; i < g->draw_width; i++) - g->pos [i] = g->draw_height - 1; - - for (j = 0; j < g->n; j++) - { - gdk_cairo_set_source_rgba (cr, &(g->colors [j])); - - for (i = 0; i < g->draw_width; i++) - { - if (g->data [i][j] != 0) - { - cairo_move_to (cr, g->draw_width - i - 0.5, g->pos[i] + 0.5); - cairo_line_to (cr, g->draw_width - i - 0.5, g->pos[i] - (g->data [i][j] - 0.5)); - } - g->pos [i] -= g->data [i][j]; - } - cairo_stroke (cr); - } - } - /* This is for network graph */ - else if (g->id == graph_netload2) - { - guint maxnet = 1; - gint segments = 1; - gint combined; - guint net_threshold; - - for (i = 0; i < g->draw_width; i++) - { - g->pos [i] = g->draw_height - 1; - combined = g->data[i][0] + - g->data[i][1] + - g->data[i][2]; - if (combined > maxnet) - maxnet = combined; - } - //printf("max = %d ", maxnet); - guint level = 0; - if (maxnet > multiload->net_threshold3) { - net_threshold = multiload->net_threshold3; - level = 3; - } - else - if (maxnet > multiload->net_threshold2) { - net_threshold = multiload->net_threshold2; - level = 2; - } - else { - net_threshold = multiload->net_threshold1; - level = 1; - if (maxnet < multiload->net_threshold1) - level = 0; - } - - //printf("level %d maxnet = %d ", level, maxnet); - maxnet = maxnet/net_threshold; - segments = MAX (maxnet+1,1); - float ratio = (float)g->draw_height/net_threshold/segments; - //printf("segments %d ratio = %f t1=%ld t2=%ld t3=%ld t=%ld\n", segments, ratio, multiload->net_threshold1, multiload->net_threshold2, multiload->net_threshold3, multiload->net_threshold); - - for (j = 0; j < g->n-1; j++) - { - gdk_cairo_set_source_rgba (cr, &(g->colors [j])); - - for (i = 0; i < g->draw_width; i++) - { - cairo_move_to (cr, g->draw_width - i - 0.5, g->pos[i] + 0.5); - cairo_line_to (cr, g->draw_width - i - 0.5, g->pos[i] - 0.5 - ((g->data [i][j] * ratio))); - g->pos [i] -= ((g->data [i][j] * ratio)); - } - cairo_stroke (cr); - } - - for (j = g->n-1; j < g->n; j++) - { - gdk_cairo_set_source_rgba (cr, &(g->colors [j])); - for (i = 0; i < g->draw_width; i++) - { - cairo_move_to (cr, g->draw_width - i - 0.5, g->pos[i] + 0.5); - cairo_line_to (cr, g->draw_width - i - 0.5, 0.5); - } - cairo_stroke (cr); - } - - /* draw grid lines if needed */ - gdk_cairo_set_source_rgba (cr, &(g->colors [4])); - double spacing; - for (k = 0; k < segments -1; k++) - { - spacing = ((double) g->draw_height/segments) * (k+1); - cairo_move_to (cr, 0.5, spacing); - cairo_line_to (cr, g->draw_width-0.5, spacing); - } - cairo_stroke (cr); - /* draw indicator if needed */ - if (level > 0) - { - gdk_cairo_set_source_rgba (cr, &(g->colors [5])); - for (k = 0; k< level; k++ ) - cairo_rectangle(cr, 0.5, (k*2) * g->draw_height/5, 5, g->draw_height/5); - cairo_fill(cr); - } - cairo_stroke (cr); - } - /* this is Load graph */ - else - { - guint maxload = 1; - for (i = 0; i < g->draw_width; i++) - { - g->pos [i] = g->draw_height - 1; - /* find maximum value */ - if (g->data[i][0] > maxload) - maxload = g->data[i][0]; - } - load = ceil ((double) (maxload/g->draw_height)) + 1; - load = MAX (load,1); - - for (j = 0; j < g->n; j++) - { - gdk_cairo_set_source_rgba (cr, &(g->colors [j])); - - for (i = 0; i < g->draw_width; i++) - { - cairo_move_to (cr, g->draw_width - i - 0.5, g->pos[i] + 0.5); - if (j == 0) - { - cairo_line_to (cr, g->draw_width - i - 0.5, g->pos[i] - ((g->data [i][j] - 0.5)/load)); - } - else - { - cairo_line_to (cr, g->draw_width - i - 0.5, 0.5); - } - g->pos [i] -= g->data [i][j] / load; - } - cairo_stroke (cr); - } - - /* draw grid lines in Load graph if needed */ - gdk_cairo_set_source_rgba (cr, &(g->colors [2])); - - double spacing; - for (k = 0; k < load - 1; k++) - { - spacing = ((double) g->draw_height/load) * (k+1); - cairo_move_to (cr, 0.5, spacing); - cairo_line_to (cr, g->draw_width-0.5, spacing); - } - - cairo_stroke (cr); - } - gtk_widget_queue_draw (g->disp); - - cairo_destroy (cr); -} - -/* Updates the load graph when the timeout expires */ -static gboolean -load_graph_update (LoadGraph *g) -{ - if (g->data == NULL) - return TRUE; - - shift_right(g); - - if (g->tooltip_update) - multiload_applet_tooltip_update(g); - - g->get_data (g->draw_height, g->data [0], g); - - load_graph_draw (g); - return TRUE; -} - -void -load_graph_unalloc (LoadGraph *g) -{ - guint i; - - if (!g->allocated) - return; - - for (i = 0; i < g->draw_width; i++) - { - g_free (g->data [i]); - } - - g_free (g->data); - g_free (g->pos); - - g->pos = NULL; - g->data = NULL; - - g->size = g_settings_get_int(g->multiload->settings, "size"); - g->size = MAX (g->size, 10); - - if (g->surface) { - cairo_surface_destroy (g->surface); - g->surface = NULL; - } - - g->allocated = FALSE; -} - -static void -load_graph_alloc (LoadGraph *g) -{ - guint i; - - if (g->allocated) - return; - - g->data = g_new0 (gint *, g->draw_width); - g->pos = g_new0 (guint, g->draw_width); - - g->data_size = sizeof (guint) * g->n; - - for (i = 0; i < g->draw_width; i++) { - g->data [i] = g_malloc0 (g->data_size); - } - - g->allocated = TRUE; -} - -static gint -load_graph_configure (GtkWidget *widget, GdkEventConfigure *event, - gpointer data_ptr) -{ - GtkAllocation allocation; - LoadGraph *c = (LoadGraph *) data_ptr; - - load_graph_unalloc (c); - - gtk_widget_get_allocation (c->disp, &allocation); - - c->draw_width = allocation.width; - c->draw_height = allocation.height; - c->draw_width = MAX (c->draw_width, 1); - c->draw_height = MAX (c->draw_height, 1); - - load_graph_alloc (c); - - if (!c->surface) - c->surface = gdk_window_create_similar_surface (gtk_widget_get_window (c->disp), - CAIRO_CONTENT_COLOR, - c->draw_width, c->draw_height); - gtk_widget_queue_draw (widget); - - return TRUE; -} - -static gint -load_graph_expose (GtkWidget *widget, - cairo_t *cr, - gpointer data_ptr) -{ - LoadGraph *g = (LoadGraph *) data_ptr; - - cairo_set_source_surface (cr, g->surface, 0, 0); - cairo_paint (cr); - - return FALSE; -} - -static void -load_graph_destroy (GtkWidget *widget, gpointer data_ptr) -{ - LoadGraph *g = (LoadGraph *) data_ptr; - - load_graph_stop (g); - - gtk_widget_destroy(widget); -} - -static gboolean -load_graph_clicked (GtkWidget *widget, GdkEventButton *event, LoadGraph *load) -{ - load->multiload->last_clicked = load->id; - - return FALSE; -} - -static gboolean -load_graph_enter_cb(GtkWidget *widget, GdkEventCrossing *event, gpointer data) -{ - LoadGraph *graph; - graph = (LoadGraph *)data; - - graph->tooltip_update = TRUE; - multiload_applet_tooltip_update(graph); - - return TRUE; -} - -static gboolean -load_graph_leave_cb(GtkWidget *widget, GdkEventCrossing *event, gpointer data) -{ - LoadGraph *graph; - graph = (LoadGraph *)data; - - graph->tooltip_update = FALSE; - - return TRUE; -} - -static void -load_graph_load_config (LoadGraph *g) -{ - gchar *name, *temp; - guint i; - - if (!g->colors) - g->colors = g_new0(GdkRGBA, g->n); - - for (i = 0; i < g->n; i++) - { - name = g_strdup_printf ("%s-color%u", g->name, i); - temp = g_settings_get_string(g->multiload->settings, name); - if (!temp) - temp = g_strdup ("#000000"); - gdk_rgba_parse(&(g->colors[i]), temp); - g_free(temp); - g_free(name); - } -} - -LoadGraph * -load_graph_new (MultiloadApplet *ma, guint n, const gchar *label, - guint id, guint speed, guint size, gboolean visible, - const gchar *name, LoadGraphDataFunc get_data) -{ - LoadGraph *g; - MatePanelAppletOrient orient; - - g = g_new0 (LoadGraph, 1); - g->visible = visible; - g->name = name; - g->n = n; - g->id = id; - g->speed = MAX (speed, 50); - g->size = MAX (size, 10); - g->pixel_size = mate_panel_applet_get_size (ma->applet); - g->tooltip_update = FALSE; - g->multiload = ma; - - g->main_widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - - g->box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - - orient = mate_panel_applet_get_orient (g->multiload->applet); - switch (orient) - { - case MATE_PANEL_APPLET_ORIENT_UP: - case MATE_PANEL_APPLET_ORIENT_DOWN: - { - g->orient = FALSE; - break; - } - case MATE_PANEL_APPLET_ORIENT_LEFT: - case MATE_PANEL_APPLET_ORIENT_RIGHT: - { - g->orient = TRUE; - break; - } - default: - g_assert_not_reached (); - } - - g->frame = gtk_frame_new (NULL); - gtk_frame_set_shadow_type (GTK_FRAME (g->frame), GTK_SHADOW_IN); - gtk_container_add (GTK_CONTAINER (g->frame), g->box); - gtk_box_pack_start (GTK_BOX (g->main_widget), g->frame, TRUE, TRUE, 0); - - load_graph_load_config (g); - - g->get_data = get_data; - - g->timer_index = -1; - - if (g->orient) - gtk_widget_set_size_request (g->main_widget, -1, g->size); - else - gtk_widget_set_size_request (g->main_widget, g->size, -1); - - g->disp = gtk_drawing_area_new (); - gtk_widget_set_events (g->disp, GDK_EXPOSURE_MASK | - GDK_ENTER_NOTIFY_MASK | - GDK_LEAVE_NOTIFY_MASK | - GDK_BUTTON_PRESS_MASK); - - g_signal_connect (G_OBJECT (g->disp), "draw", - 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); - g_signal_connect (G_OBJECT(g->disp), "button-press-event", - G_CALLBACK (load_graph_clicked), g); - g_signal_connect (G_OBJECT(g->disp), "enter-notify-event", - G_CALLBACK(load_graph_enter_cb), g); - g_signal_connect (G_OBJECT(g->disp), "leave-notify-event", - G_CALLBACK(load_graph_leave_cb), g); - - gtk_box_pack_start (GTK_BOX (g->box), g->disp, TRUE, TRUE, 0); - gtk_widget_show_all(g->box); - - return g; -} - -void -load_graph_start (LoadGraph *g) -{ - if (g->timer_index != -1) - g_source_remove (g->timer_index); - - g->timer_index = g_timeout_add (g->speed, - (GSourceFunc) load_graph_update, g); -} - -void -load_graph_stop (LoadGraph *g) -{ - if (g->timer_index != -1) - g_source_remove (g->timer_index); - - g->timer_index = -1; -} diff --git a/multiload/load-graph.h b/multiload/load-graph.h deleted file mode 100644 index 76effcd6..00000000 --- a/multiload/load-graph.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef LOAD_GRAPH_H__ -#define LOAD_GRAPH_H__ - -#include "global.h" - -/* Create new load graph. */ -G_GNUC_INTERNAL LoadGraph * -load_graph_new (MultiloadApplet *multiload, guint n, const gchar *label, - guint id, guint speed, guint size, gboolean visible, - const gchar *name, LoadGraphDataFunc get_data); - -/* Start load graph. */ -G_GNUC_INTERNAL void -load_graph_start (LoadGraph *g); - -/* Stop load graph. */ -G_GNUC_INTERNAL void -load_graph_stop (LoadGraph *g); - -/* free load graph */ -G_GNUC_INTERNAL void -load_graph_unalloc (LoadGraph *g); - -#endif diff --git a/multiload/main.c b/multiload/main.c deleted file mode 100644 index 7c2886f8..00000000 --- a/multiload/main.c +++ /dev/null @@ -1,575 +0,0 @@ -/* MATE multiload panel applet - * (C) 1997 The Free Software Foundation - * - * Authors: Tim P. Gerla - * Martin Baulig - * Todd Kulesza - * - * With code from wmload.c, v0.9.2, apparently by Ryan Land, rland@bc1.com. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "global.h" - -static void -about_cb (GtkAction *action, - MultiloadApplet *ma) -{ - const gchar * const authors[] = - { - "Martin Baulig ", - "Todd Kulesza ", - "Benoît Dejean ", - "Davyd Madeley ", - NULL - }; - - const gchar* documenters[] = - { - "Chee Bin HOH ", - N_("Sun GNOME Documentation Team "), - N_("MATE Documentation Team"), - NULL - }; - -#ifdef ENABLE_NLS - const char **p; - for (p = documenters; *p; ++p) - *p = _(*p); -#endif - - gtk_show_about_dialog (NULL, - "title", _("About System Monitor"), - "version", VERSION, - "copyright", _("Copyright \xc2\xa9 1999-2005 Free Software Foundation and others\n" - "Copyright \xc2\xa9 2012-2020 MATE developers"), - "comments", _("A system load monitor capable of displaying graphs " - "for CPU, ram, and swap space use, plus network " - "traffic."), - "authors", authors, - "documenters", documenters, - "translator-credits", _("translator-credits"), - "logo-icon-name", "utilities-system-monitor", - NULL); -} - -static void -help_cb (GtkAction *action, - MultiloadApplet *ma) -{ - GError *error = NULL; - - gtk_show_uri_on_window (NULL, - "help:mate-multiload", - gtk_get_current_event_time (), - &error); - - if (error) { /* FIXME: the user needs to see this */ - g_warning ("help error: %s\n", error->message); - g_error_free (error); - error = NULL; - } -} - -/* run the full-scale system process monitor */ - -static void -start_procman (MultiloadApplet *ma) -{ - GError *error = NULL; - GDesktopAppInfo *appinfo; - gchar *monitor; - GdkAppLaunchContext *launch_context; - GdkDisplay *display; - GAppInfo *app_info; - GdkScreen *screen; - - g_return_if_fail (ma != NULL); - - monitor = g_settings_get_string (ma->settings, "system-monitor"); - if (monitor == NULL) - monitor = g_strdup ("mate-system-monitor.desktop"); - - screen = gtk_widget_get_screen (GTK_WIDGET (ma->applet)); - appinfo = g_desktop_app_info_new (monitor); - if (appinfo) { - GdkAppLaunchContext *context; - display = gdk_screen_get_display (screen); - context = gdk_display_get_app_launch_context (display); - gdk_app_launch_context_set_screen (context, screen); - g_app_info_launch (G_APP_INFO (appinfo), NULL, G_APP_LAUNCH_CONTEXT (context), &error); - g_object_unref (context); - g_object_unref (appinfo); - } - else { - app_info = g_app_info_create_from_commandline ("mate-system-monitor", - _("Start system-monitor"), - G_APP_INFO_CREATE_NONE, - &error); - - if (!error) { - display = gdk_screen_get_display (screen); - launch_context = gdk_display_get_app_launch_context (display); - gdk_app_launch_context_set_screen (launch_context, screen); - g_app_info_launch (app_info, NULL, G_APP_LAUNCH_CONTEXT (launch_context), &error); - - g_object_unref (launch_context); - } - } - g_free (monitor); - - if (error) { - GtkWidget *dialog; - - dialog = gtk_message_dialog_new (NULL, - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - _("There was an error executing '%s': %s"), - "mate-system-monitor", - error->message); - - g_signal_connect (dialog, "response", - G_CALLBACK (gtk_widget_destroy), - NULL); - - gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); - gtk_window_set_screen (GTK_WINDOW (dialog), screen); - - gtk_widget_show (dialog); - - g_error_free (error); - } -} - -static void -start_procman_cb (GtkAction *action, - MultiloadApplet *ma) -{ - start_procman (ma); -} - -static void -multiload_change_size_cb(MatePanelApplet *applet, gint size, gpointer data) -{ - MultiloadApplet *ma = (MultiloadApplet *)data; - - multiload_applet_refresh(ma); - - return; -} - -static void -multiload_change_orient_cb(MatePanelApplet *applet, gint arg1, gpointer data) -{ - MultiloadApplet *ma = data; - multiload_applet_refresh((MultiloadApplet *)data); - gtk_widget_show (GTK_WIDGET (ma->applet)); - return; -} - -static void -multiload_destroy_cb(GtkWidget *widget, gpointer data) -{ - gint i; - MultiloadApplet *ma = data; - - for (i = 0; i < graph_n; i++) - { - load_graph_stop(ma->graphs[i]); - if (ma->graphs[i]->colors) - { - g_free (ma->graphs[i]->colors); - ma->graphs[i]->colors = NULL; - } - gtk_widget_destroy(ma->graphs[i]->main_widget); - - load_graph_unalloc(ma->graphs[i]); - g_free(ma->graphs[i]); - } - - netspeed_delete (ma->netspeed_in); - netspeed_delete (ma->netspeed_out); - - if (ma->about_dialog) - gtk_widget_destroy (ma->about_dialog); - - if (ma->prop_dialog) - gtk_widget_destroy (ma->prop_dialog); - - gtk_widget_destroy(GTK_WIDGET(ma->applet)); - - g_free (ma); - - return; -} - - -static gboolean -multiload_button_press_event_cb (GtkWidget *widget, GdkEventButton *event, MultiloadApplet *ma) -{ - g_return_val_if_fail (event != NULL, FALSE); - g_return_val_if_fail (ma != NULL, FALSE); - - if (event->button == 1 && event->type == GDK_BUTTON_PRESS) { - start_procman (ma); - return TRUE; - } - return FALSE; -} - -static gboolean -multiload_key_press_event_cb (GtkWidget *widget, GdkEventKey *event, MultiloadApplet *ma) -{ - g_return_val_if_fail (event != NULL, FALSE); - g_return_val_if_fail (ma != NULL, FALSE); - - switch (event->keyval) { - /* this list of keyvals taken from mixer applet, which seemed to have - a good list of keys to use */ - case GDK_KEY_KP_Enter: - case GDK_KEY_ISO_Enter: - case GDK_KEY_3270_Enter: - case GDK_KEY_Return: - case GDK_KEY_space: - case GDK_KEY_KP_Space: - /* activate */ - start_procman (ma); - return TRUE; - - default: - break; - } - - return FALSE; -} - -/* update the tooltip to the graph's current "used" percentage */ -void -multiload_applet_tooltip_update(LoadGraph *g) -{ - gchar *tooltip_text; - MultiloadApplet *multiload; - const char *tooltip_label [graph_n] = { - [graph_cpuload] = N_("Processor"), - [graph_memload] = N_("Memory"), - [graph_netload2] = N_("Network"), - [graph_swapload] = N_("Swap Space"), - [graph_loadavg] = N_("Load Average"), - [graph_diskload] = N_("Disk") - }; - const char *name; - - g_assert(g); - - multiload = g->multiload; - - /* label the tooltip intuitively */ - name = gettext (tooltip_label [g->id]); - - switch (g->id) { - case graph_memload: { - float user_percent, cache_percent; - - user_percent = MIN ((float)(100 * multiload->memload_user) / (float)(multiload->memload_total), 100.0f); - cache_percent = MIN ((float)(100 * multiload->memload_cache) / (float)(multiload->memload_total), 100.0f); - tooltip_text = g_strdup_printf (_("%s:\n" - "%.01f%% in use by programs\n" - "%.01f%% in use as cache"), - name, - user_percent, - cache_percent); - break; - } - case graph_loadavg: { - tooltip_text = g_strdup_printf (_("The system load average is %0.02f"), - multiload->loadavg1); - break; - } - case graph_netload2: { - char *tx_in, *tx_out; - - tx_in = netspeed_get(multiload->netspeed_in); - tx_out = netspeed_get(multiload->netspeed_out); - /* xgettext: same as in graphic tab of g-s-m */ - tooltip_text = g_strdup_printf(_("%s:\n" - "Receiving %s\n" - "Sending %s"), - name, tx_in, tx_out); - g_free(tx_in); - g_free(tx_out); - break; - } - default: { - float ratio; - float percent; - - if (g->id == graph_cpuload) - ratio = multiload->cpu_used_ratio; - else if (g->id == graph_swapload) - ratio = multiload->swapload_used_ratio; - else if (g->id == graph_diskload) - ratio = multiload->diskload_used_ratio; - else - g_assert_not_reached (); - - percent = CLAMP (ratio * 100.0f, 0.0f, 100.0f); - tooltip_text = g_strdup_printf(_("%s:\n" - "%.01f%% in use"), - name, - percent); - } - } - - gtk_widget_set_tooltip_text(g->disp, tooltip_text); - - g_free(tooltip_text); -} - -static void -multiload_create_graphs(MultiloadApplet *ma) -{ - struct { const char *label; - const char *visibility_key; - const char *name; - int num_colours; - LoadGraphDataFunc callback; - } graph_types [graph_n] = { - [graph_cpuload] = { _("CPU Load"), VIEW_CPULOAD_KEY, "cpuload", cpuload_n, GetLoad }, - [graph_memload] = { _("Memory Load"), VIEW_MEMLOAD_KEY, "memload", memload_n, GetMemory }, - [graph_netload2] = { _("Net Load"), VIEW_NETLOAD_KEY, "netload2", 6, GetNet }, - [graph_swapload] = { _("Swap Load"), VIEW_SWAPLOAD_KEY, "swapload", swapload_n, GetSwap }, - [graph_loadavg] = { _("Load Average"), VIEW_LOADAVG_KEY, "loadavg", 3, GetLoadAvg }, - [graph_diskload] = { _("Disk Load"), VIEW_DISKLOAD_KEY, "diskload", diskload_n, GetDiskLoad } - }; - - gint speed, size; - guint net_threshold1; - guint net_threshold2; - guint net_threshold3; - gint i; - - speed = g_settings_get_int (ma->settings, "speed"); - size = g_settings_get_int (ma->settings, "size"); - net_threshold1 = CLAMP (g_settings_get_uint (ma->settings, "netthreshold1"), MIN_NET_THRESHOLD1, MAX_NET_THRESHOLD1); - net_threshold2 = CLAMP (g_settings_get_uint (ma->settings, "netthreshold2"), MIN_NET_THRESHOLD2, MAX_NET_THRESHOLD2); - net_threshold3 = CLAMP (g_settings_get_uint (ma->settings, "netthreshold3"), MIN_NET_THRESHOLD3, MAX_NET_THRESHOLD3); - if (net_threshold1 >= net_threshold2) - { - net_threshold1 = net_threshold2 - 1; - } - if (net_threshold2 >= net_threshold3) - { - net_threshold3 = net_threshold2 + 1; - } - speed = MAX (speed, 50); - size = CLAMP (size, 10, 400); - - for (i = 0; i < graph_n; i++) - { - ma->graphs[i] = load_graph_new (ma, - graph_types[i].num_colours, - graph_types[i].label, - i, - speed, - size, - g_settings_get_boolean (ma->settings, graph_types[i].visibility_key), - graph_types[i].name, - graph_types[i].callback); - } - ma->nvme_diskstats = g_settings_get_boolean (ma->settings, "diskload-nvme-diskstats"); - /* for Network graph, colors[4] is grid line color, it should not be used in loop in load-graph.c */ - /* for Network graph, colors[5] is indicator color, it should not be used in loop in load-graph.c */ - ma->graphs[graph_netload2]->n = 4; - ma->net_threshold1 = net_threshold1; - ma->net_threshold2 = net_threshold2; - ma->net_threshold3 = net_threshold3; - ma->netspeed_in = netspeed_new (ma->graphs [graph_netload2]); - ma->netspeed_out = netspeed_new (ma->graphs [graph_netload2]); - /* for Load graph, colors[2] is grid line color, it should not be used in loop in load-graph.c */ - ma->graphs[graph_loadavg]->n = 2; -} - -/* remove the old graphs and rebuild them */ -void -multiload_applet_refresh(MultiloadApplet *ma) -{ - gint i; - MatePanelAppletOrient orientation; - - /* stop and free the old graphs */ - for (i = 0; i < graph_n; i++) - { - if (!ma->graphs[i]) - continue; - - load_graph_stop(ma->graphs[i]); - gtk_widget_destroy(ma->graphs[i]->main_widget); - - load_graph_unalloc(ma->graphs[i]); - g_free(ma->graphs[i]); - } - - if (ma->box) - gtk_widget_destroy(ma->box); - - orientation = mate_panel_applet_get_orient(ma->applet); - - if ( (orientation == MATE_PANEL_APPLET_ORIENT_UP) || - (orientation == MATE_PANEL_APPLET_ORIENT_DOWN) ) { - ma->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); - } - else - ma->box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - - gtk_container_add(GTK_CONTAINER(ma->applet), ma->box); - - /* create the N graphs, passing in their user-configurable properties with gsettings. */ - multiload_create_graphs (ma); - - /* only start and display the graphs the user has turned on */ - - for (i = 0; i < graph_n; i++) { - gtk_box_pack_start(GTK_BOX(ma->box), - ma->graphs[i]->main_widget, - TRUE, TRUE, 1); - if (ma->graphs[i]->visible) { - gtk_widget_show_all (ma->graphs[i]->main_widget); - load_graph_start(ma->graphs[i]); - } - } - gtk_widget_show (ma->box); - - return; -} - -static const GtkActionEntry multiload_menu_actions [] = { - { "MultiLoadProperties", "document-properties", N_("_Preferences"), - NULL, NULL, - G_CALLBACK (multiload_properties_cb) }, - { "MultiLoadRunProcman", "system-run", N_("_Open System Monitor"), - NULL, NULL, - G_CALLBACK (start_procman_cb) }, - { "MultiLoadHelp", "help-browser", N_("_Help"), - NULL, NULL, - G_CALLBACK (help_cb) }, - { "MultiLoadAbout", "help-about", N_("_About"), - NULL, NULL, - G_CALLBACK (about_cb) } -}; - -/* create a box and stuff the load graphs inside of it */ -static gboolean -multiload_applet_new(MatePanelApplet *applet, const gchar *iid, gpointer data) -{ - GtkStyleContext *context; - MultiloadApplet *ma; - GSettings *lockdown_settings; - GtkActionGroup *action_group; - gchar *ui_path; - - context = gtk_widget_get_style_context (GTK_WIDGET (applet)); - gtk_style_context_add_class (context, "multiload-applet"); - - ma = g_new0(MultiloadApplet, 1); - - ma->applet = applet; - - ma->about_dialog = NULL; - ma->prop_dialog = NULL; - ma->last_clicked = 0; - - g_set_application_name (_("System Monitor")); - - gtk_window_set_default_icon_name ("utilities-system-monitor"); - - ma->settings = mate_panel_applet_settings_new (applet, "org.mate.panel.applet.multiload"); - mate_panel_applet_set_flags (applet, MATE_PANEL_APPLET_EXPAND_MINOR); - - action_group = gtk_action_group_new ("Multiload Applet Actions"); - gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE); - gtk_action_group_add_actions (action_group, - multiload_menu_actions, - G_N_ELEMENTS (multiload_menu_actions), - ma); - ui_path = g_build_filename (MULTILOAD_MENU_UI_DIR, "multiload-applet-menu.xml", NULL); - mate_panel_applet_setup_menu_from_file (applet, ui_path, action_group); - g_free (ui_path); - - - if (mate_panel_applet_get_locked_down (applet)) { - GtkAction *action; - - action = gtk_action_group_get_action (action_group, "MultiLoadProperties"); - gtk_action_set_visible (action, FALSE); - } - - lockdown_settings = g_settings_new ("org.mate.lockdown"); - if (g_settings_get_boolean (lockdown_settings, "disable-command-line") || - mate_panel_applet_get_locked_down (applet)) { - GtkAction *action; - - /* When the panel is locked down or when the command line is inhibited, - it seems very likely that running the procman would be at least harmful */ - action = gtk_action_group_get_action (action_group, "MultiLoadRunProcman"); - gtk_action_set_visible (action, FALSE); - } - g_object_unref (lockdown_settings); - - g_object_unref (action_group); - - g_signal_connect(G_OBJECT(applet), "change_size", - G_CALLBACK(multiload_change_size_cb), ma); - g_signal_connect(G_OBJECT(applet), "change_orient", - G_CALLBACK(multiload_change_orient_cb), ma); - g_signal_connect(G_OBJECT(applet), "destroy", - G_CALLBACK(multiload_destroy_cb), ma); - g_signal_connect(G_OBJECT(applet), "button_press_event", - G_CALLBACK(multiload_button_press_event_cb), ma); - g_signal_connect(G_OBJECT(applet), "key_press_event", - G_CALLBACK(multiload_key_press_event_cb), ma); - - multiload_applet_refresh (ma); - - gtk_widget_show(GTK_WIDGET(applet)); - - return TRUE; -} - -static gboolean -multiload_factory (MatePanelApplet *applet, - const gchar *iid, - gpointer data) -{ - gboolean retval = FALSE; - - glibtop_init(); - - retval = multiload_applet_new(applet, iid, data); - - return retval; -} - -MATE_PANEL_APPLET_OUT_PROCESS_FACTORY ("MultiLoadAppletFactory", - PANEL_TYPE_APPLET, - "multiload", - multiload_factory, - NULL) diff --git a/multiload/multiload-applet-menu.xml b/multiload/multiload-applet-menu.xml deleted file mode 100644 index 88d28dd9..00000000 --- a/multiload/multiload-applet-menu.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/multiload/netspeed.c b/multiload/netspeed.c deleted file mode 100644 index 3e889c8f..00000000 --- a/multiload/netspeed.c +++ /dev/null @@ -1,70 +0,0 @@ -#include -#include -#include - -#include "netspeed.h" - -enum { N_STATES = 4 }; - -struct _NetSpeed -{ - LoadGraph *graph; - gulong states[N_STATES]; - size_t cur; -}; - -NetSpeed* netspeed_new(LoadGraph *g) -{ - NetSpeed *ns = g_new0(NetSpeed, 1); - ns->graph = g; - return ns; -} - -void netspeed_delete(NetSpeed *ns) -{ - g_free(ns); -} - -void netspeed_add(NetSpeed *ns, gulong tx) -{ - ns->cur = (ns->cur + 1) % N_STATES; - ns->states[ns->cur] = tx; -} - -/* Something very similar to g_format_size() but for rates. - * This should give the same display as in g-s-m */ -static char* -format_rate_for_display(guint rate) -{ - char *bytes; - char *text; - - bytes = g_format_size (rate); - text = g_strdup_printf (_("%s/s"), bytes); - g_free (bytes); - - return text; -} - -char* netspeed_get(NetSpeed *ns) -{ - gulong older, newer; - guint rate; - - newer = ns->states[ns->cur]; - older = ns->states[(ns->cur + 1) % N_STATES]; - - if ((older != 0) && (newer > older)) - rate = (newer - older) * 1000 / ((N_STATES - 1) * ns->graph->speed); - else - /* We end up here if we haven't got enough data yet or the - network interface has jumped back (or there has never - been any activity on any interface). A value of 0 is - likely to be accurate, but if it is wrong it will be - clearly wrong. In any event, it should fix itself in a - few seconds. */ - rate = 0; - - return format_rate_for_display(rate); -} - diff --git a/multiload/netspeed.h b/multiload/netspeed.h deleted file mode 100644 index 5bc19cf1..00000000 --- a/multiload/netspeed.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef H_MULTILOAD_NETSPEED_ -#define H_MULTILOAD_NETSPEED_ - -#include - -typedef struct _NetSpeed NetSpeed; - -#include "global.h" - -NetSpeed* netspeed_new(LoadGraph *graph); -void netspeed_delete(NetSpeed *ns); -void netspeed_add(NetSpeed *ns, gulong tx); -char* netspeed_get(NetSpeed *ns); - -#endif /* H_MULTILOAD_NETSPEED_ */ diff --git a/multiload/org.mate.applets.MultiLoadApplet.mate-panel-applet.desktop.in.in b/multiload/org.mate.applets.MultiLoadApplet.mate-panel-applet.desktop.in.in deleted file mode 100644 index 3eacb2fb..00000000 --- a/multiload/org.mate.applets.MultiLoadApplet.mate-panel-applet.desktop.in.in +++ /dev/null @@ -1,17 +0,0 @@ -[Applet Factory] -Id=MultiLoadAppletFactory -Location=@LIBEXECDIR@/mate-multiload-applet -Name=MultiLoad Applet Factory -Description=Factory for creating the load applet. - -[MultiLoadApplet] -Name=System Monitor -Description=A system load indicator -# Translators: Do NOT translate or transliterate this text (this is an icon file name)! -Icon=utilities-system-monitor -MateComponentId=OAFIID:MATE_MultiLoadApplet -X-MATE-Bugzilla-Bugzilla=MATE -X-MATE-Bugzilla-Product=mate-applets -X-MATE-Bugzilla-Component=multiload -X-MATE-Bugzilla-Version=@VERSION@ -X-MATE-Bugzilla-OtherBinaries=multiload-applet-2 diff --git a/multiload/org.mate.panel.applet.MultiLoadAppletFactory.service.in b/multiload/org.mate.panel.applet.MultiLoadAppletFactory.service.in deleted file mode 100644 index d4c7da3c..00000000 --- a/multiload/org.mate.panel.applet.MultiLoadAppletFactory.service.in +++ /dev/null @@ -1,3 +0,0 @@ -[D-BUS Service] -Name=org.mate.panel.applet.MultiLoadAppletFactory -Exec=@LIBEXECDIR@/mate-multiload-applet diff --git a/multiload/org.mate.panel.applet.multiload.gschema.xml.in b/multiload/org.mate.panel.applet.multiload.gschema.xml.in deleted file mode 100644 index 9f199bc3..00000000 --- a/multiload/org.mate.panel.applet.multiload.gschema.xml.in +++ /dev/null @@ -1,156 +0,0 @@ - - - - true - Enable CPU load graph - - - false - Enable memory load graph - - - false - Enable network load graph - - - false - Enable swap load graph - - - false - Enable load average graph - - - false - Enable disk load graph - - - 500 - Applet refresh rate in milliseconds - - - 40 - Graph size - For horizontal panels, the width of the graphs in pixels. For vertical panels, this is the height of the graphs. - - - '#0072b3' - Graph color for user-related CPU activity - - - '#0092e6' - Graph color for system-related CPU activity - - - '#00a3ff' - Graph color for nice-related CPU activity - - - '#002f3d' - Graph color for iowait related CPU activity - - - '#000000' - CPU graph background color - - - '#00b35b' - Graph color for user-related memory usage - - - '#00e675' - Graph color for shared memory - - - '#00ff82' - Graph color for buffer memory - - - '#AAF5D0' - Graph color for cached memory - - - '#000000' - Memory graph background color - - - '#fce94f' - Graph color for input network activity - - - '#edd400' - Graph color for output network activity - - - '#c4a000' - Graph color for loopback network usage - - - '#000000' - Network graph background color - - - '#ffffff' - Grid line color - - - '#0000ff' - Indicator color - - - - 1000000 - Network threshold 1 in bytes - - - - 10000000 - Network threshold 2 in bytes - - - - 100000000 - Network threshold 3 in bytes - - - '#8b00c3' - Graph color for user-related swap usage - - - '#000000' - Swap graph background color - - - '#d50000' - Graph color for load average - - - '#000000' - Load graph background color - - - '#ffffff' - Grid line color - - - '#C65000' - Graph color for disk read - - - '#FF6700' - Graph color for disk write - - - '#000000' - Background color for disk load graph - - - false - Uses /proc/diskstats to determine NVMe disk load - - - 'mate-system-monitor.desktop' - The desktop description file to execute as the system monitor - - - diff --git a/multiload/properties.c b/multiload/properties.c deleted file mode 100644 index c1ee09b6..00000000 --- a/multiload/properties.c +++ /dev/null @@ -1,868 +0,0 @@ -/* MATE cpuload/memload panel applet - * (C) 2002 The Free Software Foundation - * - * Authors: - * Todd Kulesza - * - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include - -#include -#include -#include - -#include "global.h" - -#define PROP_CPU 0 -#define PROP_MEM 1 -#define PROP_NET 2 -#define PROP_SWAP 3 -#define PROP_AVG 4 -#define PROP_DISK 5 - -#define PROP_SPEED 6 -#define PROP_SIZE 7 -#define PROP_NET_THRESHOLD1 8 -#define PROP_NET_THRESHOLD2 9 -#define PROP_NET_THRESHOLD3 10 -#define HIG_IDENTATION " " -#define NEVER_SENSITIVE "never_sensitive" - -/* set sensitive and setup NEVER_SENSITIVE appropriately */ -static void -hard_set_sensitive (GtkWidget *w, gboolean sensitivity) -{ - gtk_widget_set_sensitive (w, sensitivity); - g_object_set_data (G_OBJECT (w), NEVER_SENSITIVE, - GINT_TO_POINTER ( ! sensitivity)); -} - - -/* set sensitive, but always insensitive if NEVER_SENSITIVE is set */ -static void -soft_set_sensitive (GtkWidget *w, gboolean sensitivity) -{ - if (g_object_get_data (G_OBJECT (w), NEVER_SENSITIVE)) - gtk_widget_set_sensitive (w, FALSE); - else - gtk_widget_set_sensitive (w, sensitivity); -} - -static void -properties_set_insensitive(MultiloadApplet *ma) -{ - gint i, total_graphs, last_graph; - - total_graphs = 0; - last_graph = 0; - - for (i = 0; i < graph_n; i++) - if (ma->graphs[i]->visible) - { - last_graph = i; - total_graphs++; - } - - if (total_graphs < 2) - soft_set_sensitive(ma->check_boxes[last_graph], FALSE); - - return; -} - -static void -properties_close_cb (GtkWidget *widget, gint arg, MultiloadApplet *ma) -{ - GError *error = NULL; - - switch (arg) - { - case GTK_RESPONSE_HELP: - - gtk_show_uri_on_window (NULL, - "help:mate-multiload/multiload-prefs", - gtk_get_current_event_time (), - &error); - - if (error) { /* FIXME: the user needs to see this */ - g_warning ("help error: %s\n", error->message); - g_error_free (error); - error = NULL; - } - break; - - case GTK_RESPONSE_CLOSE: - default: - gtk_widget_destroy (widget); - ma->prop_dialog = NULL; - } -} - -static void -property_toggled_cb(GtkWidget *widget, gpointer name) -{ - MultiloadApplet *ma; - gint prop_type, i; - gboolean active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); - - ma = g_object_get_data(G_OBJECT(widget), "MultiloadApplet"); - prop_type = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "prop_type")); - - /* FIXME: the first toggle button to be checked/dechecked does not work, but after that everything is cool. what gives? */ - /* FIXME: check if this is still valid for gsettings */ - g_settings_set_boolean (ma->settings, (gchar *)name, active); - g_settings_set_boolean (ma->settings, (gchar *)name, active); - - if (active) - { - for (i = 0; i < graph_n; i++) - soft_set_sensitive(ma->check_boxes[i], TRUE); - gtk_widget_show_all (ma->graphs[prop_type]->main_widget); - ma->graphs[prop_type]->visible = TRUE; - load_graph_start(ma->graphs[prop_type]); - } - else - { - load_graph_stop(ma->graphs[prop_type]); - gtk_widget_hide (ma->graphs[prop_type]->main_widget); - ma->graphs[prop_type]->visible = FALSE; - properties_set_insensitive(ma); - } - - return; -} - -static void -spin_button_changed_cb(GtkWidget *widget, gpointer name) -{ - MultiloadApplet *ma; - gint value; - gint prop_type, i; - - ma = g_object_get_data(G_OBJECT(widget), "MultiloadApplet"); - prop_type = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "prop_type")); - value = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); - - switch(prop_type) - { - case PROP_SPEED: - g_settings_set_int (ma->settings, (gchar *)name, value); - for (i = 0; i < graph_n; i++) - { - load_graph_stop(ma->graphs[i]); - ma->graphs[i]->speed = value; - if (ma->graphs[i]->visible) - load_graph_start(ma->graphs[i]); - } - - break; - - case PROP_SIZE: - for (i = 0; i < graph_n; i++) - { - g_settings_set_int (ma->settings, (gchar *)name, value); - ma->graphs[i]->size = value ; - - if (ma->graphs[i]->orient) - gtk_widget_set_size_request ( - ma->graphs[i]->main_widget, - ma->graphs[i]->pixel_size, - ma->graphs[i]->size); - else - gtk_widget_set_size_request ( - ma->graphs[i]->main_widget, - ma->graphs[i]->size, - ma->graphs[i]->pixel_size); - } - break; - - case PROP_NET_THRESHOLD1: - g_settings_set_uint (ma->settings, (gchar *)name, value); - if (value >= ma->net_threshold2) - { - gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), - (gdouble)g_settings_get_uint (ma->settings, - "netthreshold2") - 1); - ma->net_threshold1 = g_settings_get_uint (ma->settings, - "netthreshold2") - 1; - } - else - ma->net_threshold1 = value; - break; - - case PROP_NET_THRESHOLD2: - g_settings_set_uint (ma->settings, (gchar *)name, value); - if (value >= ma->net_threshold3) - { - gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), - (gdouble)g_settings_get_uint (ma->settings, - "netthreshold3") - 1); - ma->net_threshold2 = g_settings_get_uint (ma->settings, - "netthreshold3") - 1; - } - else if (value <= ma->net_threshold1) - { - gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), - (gdouble)g_settings_get_uint (ma->settings, - "netthreshold1") + 1); - ma->net_threshold2 = g_settings_get_uint (ma->settings, - "netthreshold1") + 1; - } - else - ma->net_threshold2 = value; - break; - - case PROP_NET_THRESHOLD3: - g_settings_set_uint (ma->settings, (gchar *)name, value); - if (value <= ma->net_threshold2) - { - gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), - (gdouble)g_settings_get_uint (ma->settings, - "netthreshold2") + 1); - ma->net_threshold3 = g_settings_get_uint (ma->settings, - "netthreshold2") + 1; - } - else - ma->net_threshold3 = value; - break; - default: - g_assert_not_reached(); - } - - return; -} - -/* create a new page in the notebook widget, add it, and return a pointer to it */ -static GtkWidget * -add_page(GtkWidget *notebook, gchar *label) -{ - GtkWidget *page; - GtkWidget *page_label; - - page = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); - gtk_box_set_homogeneous (GTK_BOX (page), TRUE); - page_label = gtk_label_new(label); - gtk_container_set_border_width(GTK_CONTAINER(page), 6); - - gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page, page_label); - - return page; -} - -/* save the selected color to gsettings and apply it on the applet */ -static void -color_picker_set_cb(GtkColorChooser *color_picker, gchar *key) -{ - gchar *color_string; - guint8 prop_type; - GdkRGBA color; - MultiloadApplet *ma; - - ma = g_object_get_data (G_OBJECT (color_picker), "MultiloadApplet"); - - if (strstr(key, "cpuload")) - prop_type = PROP_CPU; - else if (strstr(key, "memload")) - prop_type = PROP_MEM; - else if (strstr(key, "netload2")) - prop_type = PROP_NET; - else if (strstr(key, "swapload")) - prop_type = PROP_SWAP; - else if (strstr(key, "loadavg")) - prop_type = PROP_AVG; - else if (strstr(key, "diskload")) - prop_type = PROP_DISK; - else - g_assert_not_reached(); - - gtk_color_chooser_get_rgba(color_picker, &color); - - color_string = gdk_rgba_to_string (&color); - g_settings_set_string(ma->settings, key, color_string); - - gdk_rgba_parse(&(ma->graphs[prop_type]->colors[g_ascii_digit_value(key[strlen(key) - 1]) ]), - color_string); - - return; -} - -/* create a color selector */ -static void -add_color_selector(GtkWidget *page, gchar *name, gchar *key, MultiloadApplet *ma) -{ - GtkWidget *vbox; - GtkWidget *label; - GtkWidget *color_picker; - GdkRGBA color; - gchar *color_string; - - color_string = g_settings_get_string (ma->settings, key); - if (!color_string) - color_string = g_strdup ("#000000"); - gdk_rgba_parse (&color, color_string); - g_free (color_string); - - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); - label = gtk_label_new_with_mnemonic(name); - color_picker = gtk_color_button_new(); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), color_picker); - - gtk_box_pack_start(GTK_BOX(vbox), color_picker, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); - - gtk_box_pack_start(GTK_BOX(page), vbox, FALSE, FALSE, 0); - - g_object_set_data (G_OBJECT (color_picker), "MultiloadApplet", ma); - - gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(color_picker), &color); - - g_signal_connect(G_OBJECT(color_picker), "color_set", G_CALLBACK(color_picker_set_cb), key); - - if ( ! g_settings_is_writable (ma->settings, key)) - hard_set_sensitive (vbox, FALSE); - - return; -} - -/* save the checkbox option to gsettings and apply it on the applet */ -static void -nvme_checkbox_toggled_cb (GtkCheckButton *checkbox, - MultiloadApplet *ma) -{ - gboolean option; - - option = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbox)); - ma->nvme_diskstats = option; - g_settings_set_boolean (ma->settings, "diskload-nvme-diskstats", option); - - return; -} - -/* creates the properties dialog using up-to-the-minute info from gsettings */ -static void -fill_properties(GtkWidget *dialog, MultiloadApplet *ma) -{ - GtkWidget *page; - GtkWidget *hbox, *vbox; - GtkWidget *categories_vbox; - GtkWidget *category_vbox; - GtkWidget *control_vbox; - GtkWidget *control_hbox; - GtkWidget *check_box; - GtkWidget *indent; - GtkWidget *spin_button; - GtkWidget *label; - MatePanelAppletOrient orient; - GtkSizeGroup *label_size; - GtkSizeGroup *spin_size; - gchar *label_text; - gchar *title; - - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - gtk_container_set_border_width (GTK_CONTAINER (vbox), 5); - gtk_widget_show (vbox); - - gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), - vbox, TRUE, TRUE, 0); - - categories_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 18); - gtk_box_pack_start (GTK_BOX (vbox), categories_vbox, TRUE, TRUE, 0); - gtk_widget_show (categories_vbox); - - category_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); - gtk_box_pack_start (GTK_BOX (categories_vbox), category_vbox, TRUE, TRUE, 0); - gtk_widget_show (category_vbox); - - title = g_strconcat ("", _("Monitored Resources"), "", NULL); - label = gtk_label_new_with_mnemonic (_(title)); - gtk_label_set_use_markup (GTK_LABEL (label), TRUE); - gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT); - gtk_label_set_xalign (GTK_LABEL (label), 0.0); - gtk_box_pack_start (GTK_BOX (category_vbox), label, FALSE, FALSE, 0); - g_free (title); - - hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); - gtk_box_pack_start (GTK_BOX (category_vbox), hbox, TRUE, TRUE, 0); - gtk_widget_show (hbox); - - indent = gtk_label_new (HIG_IDENTATION); - gtk_label_set_justify (GTK_LABEL (indent), GTK_JUSTIFY_LEFT); - gtk_box_pack_start (GTK_BOX (hbox), indent, FALSE, FALSE, 0); - gtk_widget_show (indent); - - control_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); - gtk_box_pack_start (GTK_BOX (hbox), control_vbox, TRUE, TRUE, 0); - gtk_widget_show (control_vbox); - - control_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); - gtk_box_pack_start (GTK_BOX (control_vbox), control_hbox, TRUE, TRUE, 0); - gtk_widget_show (control_hbox); - - check_box = gtk_check_button_new_with_mnemonic(_("_Processor")); - ma->check_boxes[0] = check_box; - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_box), - g_settings_get_boolean (ma->settings, - VIEW_CPULOAD_KEY)); - g_object_set_data(G_OBJECT(check_box), "MultiloadApplet", ma); - g_object_set_data(G_OBJECT(check_box), "prop_type", GINT_TO_POINTER(PROP_CPU)); - g_signal_connect(G_OBJECT(check_box), "toggled", - G_CALLBACK(property_toggled_cb), VIEW_CPULOAD_KEY); - gtk_box_pack_start (GTK_BOX (control_hbox), check_box, FALSE, FALSE, 0); - - if ( ! g_settings_is_writable (ma->settings, VIEW_CPULOAD_KEY)) - hard_set_sensitive (check_box, FALSE); - - check_box = gtk_check_button_new_with_mnemonic(_("_Memory")); - ma->check_boxes[1] = check_box; - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_box), - g_settings_get_boolean (ma->settings, VIEW_MEMLOAD_KEY)); - g_object_set_data(G_OBJECT(check_box), "MultiloadApplet", ma); - g_object_set_data(G_OBJECT(check_box), "prop_type", GINT_TO_POINTER(PROP_MEM)); - g_signal_connect(G_OBJECT(check_box), "toggled", - G_CALLBACK(property_toggled_cb), VIEW_MEMLOAD_KEY); - gtk_box_pack_start (GTK_BOX (control_hbox), check_box, FALSE, FALSE, 0); - - if ( ! g_settings_is_writable (ma->settings, VIEW_MEMLOAD_KEY)) - hard_set_sensitive (check_box, FALSE); - - check_box = gtk_check_button_new_with_mnemonic(_("_Network")); - ma->check_boxes[2] = check_box; - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_box), - g_settings_get_boolean (ma->settings, VIEW_NETLOAD_KEY)); - g_object_set_data(G_OBJECT(check_box), "MultiloadApplet", ma); - g_object_set_data(G_OBJECT(check_box), "prop_type", GINT_TO_POINTER(PROP_NET)); - g_signal_connect(G_OBJECT(check_box), "toggled", - G_CALLBACK(property_toggled_cb), VIEW_NETLOAD_KEY); - gtk_box_pack_start (GTK_BOX (control_hbox), check_box, FALSE, FALSE, 0); - - if ( ! g_settings_is_writable (ma->settings, VIEW_NETLOAD_KEY)) - hard_set_sensitive (check_box, FALSE); - - check_box = gtk_check_button_new_with_mnemonic (_("S_wap Space")); - ma->check_boxes[3] = check_box; - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_box), - g_settings_get_boolean (ma->settings, VIEW_SWAPLOAD_KEY)); - g_object_set_data(G_OBJECT(check_box), "MultiloadApplet", ma); - g_object_set_data(G_OBJECT(check_box), "prop_type", GINT_TO_POINTER(PROP_SWAP)); - g_signal_connect(G_OBJECT(check_box), "toggled", - G_CALLBACK(property_toggled_cb), VIEW_SWAPLOAD_KEY); - gtk_box_pack_start (GTK_BOX (control_hbox), check_box, FALSE, FALSE, 0); - - if ( ! g_settings_is_writable (ma->settings, VIEW_SWAPLOAD_KEY)) - hard_set_sensitive (check_box, FALSE); - - check_box = gtk_check_button_new_with_mnemonic(_("_Load")); - ma->check_boxes[4] = check_box; - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_box), - g_settings_get_boolean (ma->settings, VIEW_LOADAVG_KEY)); - g_object_set_data(G_OBJECT(check_box), "MultiloadApplet", ma); - g_object_set_data(G_OBJECT(check_box), "prop_type", GINT_TO_POINTER(PROP_AVG)); - g_signal_connect(G_OBJECT(check_box), "toggled", - G_CALLBACK(property_toggled_cb), VIEW_LOADAVG_KEY); - gtk_box_pack_start(GTK_BOX(control_hbox), check_box, FALSE, FALSE, 0); - - if ( ! g_settings_is_writable (ma->settings, VIEW_LOADAVG_KEY)) - hard_set_sensitive (check_box, FALSE); - - check_box = gtk_check_button_new_with_mnemonic(_("_Harddisk")); - ma->check_boxes[5] = check_box; - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_box), - g_settings_get_boolean (ma->settings, VIEW_DISKLOAD_KEY)); - g_object_set_data (G_OBJECT (check_box), "MultiloadApplet", ma); - g_object_set_data (G_OBJECT (check_box), "prop_type", - GINT_TO_POINTER (PROP_DISK)); - g_signal_connect (G_OBJECT (check_box), "toggled", - G_CALLBACK (property_toggled_cb), VIEW_DISKLOAD_KEY); - gtk_box_pack_start (GTK_BOX (control_hbox), check_box, FALSE, FALSE, 0); - - if ( ! g_settings_is_writable (ma->settings, VIEW_DISKLOAD_KEY)) - hard_set_sensitive (check_box, FALSE); - - category_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); - gtk_box_pack_start (GTK_BOX (categories_vbox), category_vbox, TRUE, TRUE, 0); - gtk_widget_show (category_vbox); - - title = g_strconcat ("", _("Options"), "", NULL); - label = gtk_label_new (title); - gtk_label_set_use_markup (GTK_LABEL (label), TRUE); - gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT); - gtk_label_set_xalign (GTK_LABEL (label), 0.0); - gtk_box_pack_start (GTK_BOX (category_vbox), label, FALSE, FALSE, 0); - gtk_widget_show (label); - g_free (title); - - hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); - gtk_box_pack_start (GTK_BOX (category_vbox), hbox, TRUE, TRUE, 0); - gtk_widget_show (hbox); - - indent = gtk_label_new (HIG_IDENTATION); - gtk_label_set_justify (GTK_LABEL (indent), GTK_JUSTIFY_LEFT); - gtk_box_pack_start (GTK_BOX (hbox), indent, FALSE, FALSE, 0); - gtk_widget_show (indent); - - control_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); - gtk_box_pack_start (GTK_BOX (hbox), control_vbox, TRUE, TRUE, 0); - gtk_widget_show (control_vbox); - - control_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); - gtk_box_pack_start (GTK_BOX (control_vbox), control_hbox, TRUE, TRUE, 0); - gtk_widget_show (control_hbox); - - label_size = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); - - orient = mate_panel_applet_get_orient(ma->applet); - if ( (orient == MATE_PANEL_APPLET_ORIENT_UP) || (orient == MATE_PANEL_APPLET_ORIENT_DOWN) ) - label_text = g_strdup(_("System m_onitor width: ")); - else - label_text = g_strdup(_("System m_onitor height: ")); - - label = gtk_label_new_with_mnemonic(label_text); - gtk_label_set_xalign (GTK_LABEL (label), 0.0f); - gtk_size_group_add_widget (label_size, label); - gtk_box_pack_start (GTK_BOX (control_hbox), label, FALSE, FALSE, 0); - - hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - gtk_box_pack_start (GTK_BOX (control_hbox), hbox, TRUE, TRUE, 0); - gtk_widget_show (hbox); - - spin_size = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); - - spin_button = gtk_spin_button_new_with_range(10, 1000, 5); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), spin_button); - g_object_set_data(G_OBJECT(spin_button), "MultiloadApplet", ma); - g_object_set_data(G_OBJECT(spin_button), "prop_type", - GINT_TO_POINTER(PROP_SIZE)); - gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin_button), - (gdouble)g_settings_get_int(ma->settings, "size")); - g_signal_connect(G_OBJECT(spin_button), "value_changed", - G_CALLBACK(spin_button_changed_cb), "size"); - - if ( ! g_settings_is_writable (ma->settings, "size")) { - hard_set_sensitive (label, FALSE); - hard_set_sensitive (hbox, FALSE); - } - - gtk_size_group_add_widget (spin_size, spin_button); - gtk_box_pack_start (GTK_BOX (hbox), spin_button, FALSE, FALSE, 0); - - label = gtk_label_new (_("pixels")); - gtk_label_set_xalign (GTK_LABEL (label), 0.0f); - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); - - control_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); - gtk_box_pack_start (GTK_BOX (control_vbox), control_hbox, TRUE, TRUE, 0); - gtk_widget_show (control_hbox); - - label = gtk_label_new_with_mnemonic(_("Sys_tem monitor update interval: ")); - gtk_label_set_xalign (GTK_LABEL (label), 0.0f); - gtk_size_group_add_widget (label_size, label); - gtk_box_pack_start (GTK_BOX (control_hbox), label, FALSE, FALSE, 0); - - hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - gtk_box_pack_start (GTK_BOX (control_hbox), hbox, TRUE, TRUE, 0); - gtk_widget_show (hbox); - - spin_button = gtk_spin_button_new_with_range(50, 10000, 50); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), spin_button); - g_object_set_data(G_OBJECT(spin_button), "MultiloadApplet", ma); - g_object_set_data(G_OBJECT(spin_button), "prop_type", - GINT_TO_POINTER(PROP_SPEED)); - gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin_button), - (gdouble)g_settings_get_int (ma->settings, "speed")); - g_signal_connect(G_OBJECT(spin_button), "value_changed", - G_CALLBACK(spin_button_changed_cb), "speed"); - gtk_size_group_add_widget (spin_size, spin_button); - gtk_box_pack_start (GTK_BOX (hbox), spin_button, FALSE, FALSE, 0); - - if ( ! g_settings_is_writable (ma->settings, "speed")) { - hard_set_sensitive (label, FALSE); - hard_set_sensitive (hbox, FALSE); - } - - label = gtk_label_new(_("milliseconds")); - gtk_label_set_xalign (GTK_LABEL (label), 0.0f); - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); - - g_free(label_text); - - - category_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); - gtk_box_pack_start (GTK_BOX (categories_vbox), category_vbox, TRUE, TRUE, 0); - gtk_widget_show (category_vbox); - - title = g_strconcat ("", _("Colors"), "", NULL); - label = gtk_label_new (title); - gtk_label_set_use_markup (GTK_LABEL (label), TRUE); - gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT); - gtk_label_set_xalign (GTK_LABEL (label), 0.0); - gtk_box_pack_start (GTK_BOX (category_vbox), label, FALSE, FALSE, 0); - gtk_widget_show (label); - g_free (title); - - hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); - gtk_box_pack_start (GTK_BOX (category_vbox), hbox, TRUE, TRUE, 0); - gtk_widget_show (hbox); - - indent = gtk_label_new (HIG_IDENTATION); - gtk_label_set_justify (GTK_LABEL (indent), GTK_JUSTIFY_LEFT); - gtk_box_pack_start (GTK_BOX (hbox), indent, FALSE, FALSE, 0); - gtk_widget_show (indent); - - control_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); - gtk_box_pack_start (GTK_BOX (hbox), control_vbox, TRUE, TRUE, 0); - gtk_widget_show (control_vbox); - - ma->notebook = gtk_notebook_new(); - gtk_container_add (GTK_CONTAINER (control_vbox), ma->notebook); - - page = add_page(ma->notebook, _("Processor")); - gtk_container_set_border_width (GTK_CONTAINER (page), 12); - add_color_selector(page, _("_User"), "cpuload-color0", ma); - add_color_selector(page, _("S_ystem"), "cpuload-color1", ma); - add_color_selector(page, _("N_ice"), "cpuload-color2", ma); - add_color_selector(page, _("I_OWait"), "cpuload-color3", ma); - add_color_selector(page, _("I_dle"), "cpuload-color4", ma); - - page = add_page(ma->notebook, _("Memory")); - gtk_container_set_border_width (GTK_CONTAINER (page), 12); - add_color_selector(page, _("_User"), "memload-color0", ma); - add_color_selector(page, _("Sh_ared"), "memload-color1", ma); - add_color_selector(page, _("_Buffers"), "memload-color2", ma); - add_color_selector (page, _("Cach_ed"), "memload-color3", ma); - add_color_selector(page, _("F_ree"), "memload-color4", ma); - - page = add_page(ma->notebook, _("Network")); - gtk_container_set_border_width (GTK_CONTAINER (page), 12); - add_color_selector (page, _("_In"), "netload2-color0", ma); - add_color_selector(page, _("_Out"), "netload2-color1", ma); - add_color_selector (page, _("_Local"), "netload2-color2", ma); - add_color_selector(page, _("_Background"), "netload2-color3", ma); - add_color_selector(page, _("_Gridline"), "netload2-color4", ma); - add_color_selector(page, _("_Indicator"), "netload2-color5", ma); - - page = add_page(ma->notebook, _("Swap Space")); - gtk_container_set_border_width (GTK_CONTAINER (page), 12); - add_color_selector(page, _("_Used"), "swapload-color0", ma); - add_color_selector(page, _("_Free"), "swapload-color1", ma); - - page = add_page(ma->notebook, _("Load")); - gtk_container_set_border_width (GTK_CONTAINER (page), 12); - add_color_selector(page, _("_Average"), "loadavg-color0", ma); - add_color_selector(page, _("_Background"), "loadavg-color1", ma); - add_color_selector(page, _("_Gridline"), "loadavg-color2", ma); - - page = add_page (ma->notebook, _("Harddisk")); - gtk_container_set_border_width (GTK_CONTAINER (page), 12); - add_color_selector (page, _("_Read"), "diskload-color0", ma); - add_color_selector (page, _("_Write"), "diskload-color1", ma); - add_color_selector (page, _("_Background"), "diskload-color2", ma); - GtkWidget *nvme_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); - GtkWidget *nvme_checkbox = gtk_check_button_new_with_mnemonic (_("Use diskstats for NVMe")); - ma->nvme_diskstats = g_settings_get_boolean (ma->settings, "diskload-nvme-diskstats"); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (nvme_checkbox), - ma->nvme_diskstats); - g_signal_connect (G_OBJECT (nvme_checkbox), "toggled", - G_CALLBACK (nvme_checkbox_toggled_cb), ma); - gtk_box_pack_start (GTK_BOX(nvme_box), nvme_checkbox, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX(page), nvme_box, FALSE, FALSE, 0); - gtk_widget_show (nvme_box); - - title = g_strconcat ("", _("Network speed thresholds"), "", NULL); - label = gtk_label_new (title); - gtk_label_set_use_markup (GTK_LABEL (label), TRUE); - gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT); - gtk_label_set_xalign (GTK_LABEL (label), 0.0); - gtk_box_pack_start (GTK_BOX (category_vbox), label, FALSE, FALSE, 0); - gtk_widget_show (label); - g_free (title); - - hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); - gtk_box_pack_start (GTK_BOX (category_vbox), hbox, TRUE, TRUE, 0); - gtk_widget_show (hbox); - - indent = gtk_label_new (HIG_IDENTATION); - gtk_label_set_justify (GTK_LABEL (indent), GTK_JUSTIFY_LEFT); - gtk_box_pack_start (GTK_BOX (hbox), indent, FALSE, FALSE, 0); - gtk_widget_show (indent); - - control_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); - gtk_box_pack_start (GTK_BOX (hbox), control_vbox, TRUE, TRUE, 0); - gtk_widget_show (control_vbox); - - control_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); - gtk_box_pack_start (GTK_BOX (control_vbox), control_hbox, TRUE, TRUE, 0); - gtk_widget_show (control_hbox); - - label_size = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); - - label_text = g_strdup(_("Threshold 1: ")); - label = gtk_label_new_with_mnemonic(label_text); - gtk_label_set_xalign (GTK_LABEL (label), 0.0f); - gtk_size_group_add_widget (label_size, label); - gtk_box_pack_start (GTK_BOX (control_hbox), label, FALSE, FALSE, 0); - - hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - gtk_box_pack_start (GTK_BOX (control_hbox), hbox, TRUE, TRUE, 0); - gtk_widget_show (hbox); - - spin_size = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); - - spin_button = gtk_spin_button_new_with_range (MIN_NET_THRESHOLD1, MAX_NET_THRESHOLD1, 5); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), spin_button); - g_object_set_data(G_OBJECT(spin_button), "MultiloadApplet", ma); - g_object_set_data(G_OBJECT(spin_button), "prop_type", - GUINT_TO_POINTER(PROP_NET_THRESHOLD1)); - gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin_button), - (gdouble)g_settings_get_uint(ma->settings, "netthreshold1")); - g_signal_connect(G_OBJECT(spin_button), "value_changed", - G_CALLBACK(spin_button_changed_cb), "netthreshold1"); - - if ( ! g_settings_is_writable (ma->settings, "netthreshold1")) - { - hard_set_sensitive (label, FALSE); - hard_set_sensitive (hbox, FALSE); - } - - gtk_size_group_add_widget (spin_size, spin_button); - gtk_box_pack_start (GTK_BOX (hbox), spin_button, FALSE, FALSE, 0); - - label = gtk_label_new (_("bytes")); - gtk_label_set_xalign (GTK_LABEL (label), 0.0f); - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); - - control_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); - gtk_box_pack_start (GTK_BOX (control_vbox), control_hbox, TRUE, TRUE, 0); - gtk_widget_show (control_hbox); - - label = gtk_label_new_with_mnemonic(_("Threshold 2: ")); - gtk_label_set_xalign (GTK_LABEL (label), 0.0f); - gtk_size_group_add_widget (label_size, label); - gtk_box_pack_start (GTK_BOX (control_hbox), label, FALSE, FALSE, 0); - - hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - gtk_box_pack_start (GTK_BOX (control_hbox), hbox, TRUE, TRUE, 0); - gtk_widget_show (hbox); - - spin_button = gtk_spin_button_new_with_range (MIN_NET_THRESHOLD2, MAX_NET_THRESHOLD2, 5); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), spin_button); - g_object_set_data(G_OBJECT(spin_button), "MultiloadApplet", ma); - g_object_set_data(G_OBJECT(spin_button), "prop_type", - GINT_TO_POINTER(PROP_NET_THRESHOLD2)); - gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin_button), - (gdouble)g_settings_get_uint (ma->settings, "netthreshold2")); - g_signal_connect(G_OBJECT(spin_button), "value_changed", - G_CALLBACK(spin_button_changed_cb), "netthreshold2"); - gtk_size_group_add_widget (spin_size, spin_button); - gtk_box_pack_start (GTK_BOX (hbox), spin_button, FALSE, FALSE, 0); - - if ( ! g_settings_is_writable (ma->settings, "netthreshold2")) - { - hard_set_sensitive (label, FALSE); - hard_set_sensitive (hbox, FALSE); - } - - label = gtk_label_new(_("bytes")); - gtk_label_set_xalign (GTK_LABEL (label), 0.0f); - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); - - control_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); - gtk_box_pack_start (GTK_BOX (control_vbox), control_hbox, TRUE, TRUE, 0); - gtk_widget_show (control_hbox); - - label = gtk_label_new_with_mnemonic(_("Threshold 3: ")); - gtk_label_set_xalign (GTK_LABEL (label), 0.0f); - gtk_size_group_add_widget (label_size, label); - gtk_box_pack_start (GTK_BOX (control_hbox), label, FALSE, FALSE, 0); - - hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - gtk_box_pack_start (GTK_BOX (control_hbox), hbox, TRUE, TRUE, 0); - gtk_widget_show (hbox); - - spin_button = gtk_spin_button_new_with_range (MIN_NET_THRESHOLD3, MAX_NET_THRESHOLD3, 5); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), spin_button); - g_object_set_data(G_OBJECT(spin_button), "MultiloadApplet", ma); - g_object_set_data(G_OBJECT(spin_button), "prop_type", - GINT_TO_POINTER(PROP_NET_THRESHOLD3)); - gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin_button), - (gdouble)g_settings_get_uint (ma->settings, "netthreshold3")); - g_signal_connect(G_OBJECT(spin_button), "value_changed", - G_CALLBACK(spin_button_changed_cb), "netthreshold3"); - gtk_size_group_add_widget (spin_size, spin_button); - gtk_box_pack_start (GTK_BOX (hbox), spin_button, FALSE, FALSE, 0); - - if ( ! g_settings_is_writable (ma->settings, "netthreshold3")) - { - hard_set_sensitive (label, FALSE); - hard_set_sensitive (hbox, FALSE); - } - - label = gtk_label_new(_("bytes")); - gtk_label_set_xalign (GTK_LABEL (label), 0.0f); - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); - - g_free(label_text); - - category_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); - gtk_box_pack_start (GTK_BOX (categories_vbox), category_vbox, TRUE, TRUE, 0); - - control_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); - gtk_box_pack_start (GTK_BOX (control_vbox), control_hbox, TRUE, TRUE, 0); - gtk_widget_show (control_hbox); - - gtk_widget_show (category_vbox); - - return; -} - -/* show properties dialog */ -void -multiload_properties_cb (GtkAction *action, - MultiloadApplet *ma) -{ - GtkWidget *dialog = NULL; - - if (ma->prop_dialog) { - dialog = ma->prop_dialog; - - gtk_window_set_screen (GTK_WINDOW (dialog), - gtk_widget_get_screen (GTK_WIDGET (ma->applet))); - - gtk_notebook_set_current_page (GTK_NOTEBOOK (ma->notebook), - ma->last_clicked); - gtk_window_present (GTK_WINDOW (dialog)); - return; - } - - dialog = gtk_dialog_new_with_buttons (_("System Monitor Preferences"), - NULL, 0, - "gtk-help", GTK_RESPONSE_HELP, - "gtk-close", GTK_RESPONSE_CLOSE, - NULL); - gtk_window_set_screen (GTK_WINDOW (dialog), - gtk_widget_get_screen (GTK_WIDGET (ma->applet))); - gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE); - gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); - gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); - gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), 2); - - fill_properties(dialog, ma); - - properties_set_insensitive(ma); - - g_signal_connect(G_OBJECT(dialog), "response", - G_CALLBACK(properties_close_cb), ma); - - ma->prop_dialog = dialog; - - gtk_widget_show_all(dialog); - - gtk_notebook_set_current_page (GTK_NOTEBOOK (ma->notebook), - ma->last_clicked); -} diff --git a/multiload/src/Makefile.am b/multiload/src/Makefile.am new file mode 100644 index 00000000..ab0ab6fd --- /dev/null +++ b/multiload/src/Makefile.am @@ -0,0 +1,29 @@ +AM_CPPFLAGS = \ + -I$(srcdir) \ + -DMULTILOAD_MENU_UI_DIR=\""$(datadir)/mate/ui/"\" \ + $(MATE_APPLETS4_CFLAGS) \ + $(GTOP_APPLETS_CFLAGS) \ + $(GIO_CFLAGS) \ + ${WARN_CFLAGS} + +libexec_PROGRAMS = mate-multiload-applet + +mate_multiload_applet_SOURCES = \ + global.h \ + linux-proc.h \ + load-graph.h \ + linux-proc.c \ + load-graph.c \ + main.c \ + properties.c \ + netspeed.c netspeed.h \ + autoscaler.c \ + autoscaler.h + +mate_multiload_applet_LDADD = \ + $(MATE_APPLETS4_LIBS) \ + $(GTOP_APPLETS_LIBS) \ + $(GIO_LIBS) \ + -lm + +-include $(top_srcdir)/git.mk diff --git a/multiload/src/autoscaler.c b/multiload/src/autoscaler.c new file mode 100644 index 00000000..735b2713 --- /dev/null +++ b/multiload/src/autoscaler.c @@ -0,0 +1,51 @@ +#include +#include + +#include "autoscaler.h" + +/* i wish i could have used C99 initializers instead of writing this function */ +void autoscaler_init(AutoScaler *that, unsigned interval, unsigned floor) +{ + that->update_interval = interval; + that->floor = floor; + that->max = 0; + that->count = 0; + that->last_update = 0; + that->sum = 0.0f; + that->last_average = 0.0f; +} + + +unsigned autoscaler_get_max(AutoScaler *that, unsigned current) +{ + time_t now; + + that->sum += current; + that->count++; + time(&now); + + if((float)difftime(now, that->last_update) > that->update_interval) + { + float new_average = that->sum / that->count; + float average; + + if(new_average < that->last_average) + average = ((that->last_average * 0.5f) + new_average) / 1.5f; + else + average = new_average; + + that->max = average * 1.2f; + + that->sum = 0.0f; + that->count = 0; + that->last_update = now; + that->last_average = average; + } + + that->max = MAX(that->max, current); + that->max = MAX(that->max, that->floor); +#if 0 + printf("%p max = %u, current = %u, last_average = %f\n", that, that->max, current, that->last_average); +#endif + return that->max; +} diff --git a/multiload/src/autoscaler.h b/multiload/src/autoscaler.h new file mode 100644 index 00000000..d0ae4cd6 --- /dev/null +++ b/multiload/src/autoscaler.h @@ -0,0 +1,26 @@ +#ifndef MATE_APPLETS_MULTILOAD_AUTOSCALER_H +#define MATE_APPLETS_MULTILOAD_AUTOSCALER_H + +#include +#include + +typedef struct _AutoScaler AutoScaler; + +struct _AutoScaler +{ + /* const */ unsigned update_interval; + /* const */ unsigned floor; + unsigned max; + unsigned count; + time_t last_update; + float sum; + float last_average; +}; + + +G_GNUC_INTERNAL void autoscaler_init(AutoScaler *that, unsigned interval, unsigned floor); + +G_GNUC_INTERNAL unsigned autoscaler_get_max(AutoScaler *that, unsigned current); + + +#endif /* MATE_APPLETS_MULTILOAD_AUTOSCALER_H */ diff --git a/multiload/src/global.h b/multiload/src/global.h new file mode 100644 index 00000000..da3383c4 --- /dev/null +++ b/multiload/src/global.h @@ -0,0 +1,164 @@ +#ifndef __GLOBAL_H__ +#define __GLOBAL_H__ + +#include +#include +#include +#include +#include +#include + +G_BEGIN_DECLS + +#define MIN_NET_THRESHOLD1 10 +#define MIN_NET_THRESHOLD2 11 +#define MIN_NET_THRESHOLD3 12 +#define MAX_NET_THRESHOLD1 999999998 +#define MAX_NET_THRESHOLD2 999999999 +#define MAX_NET_THRESHOLD3 1000000000 + +#define VIEW_CPULOAD_KEY "view-cpuload" +#define VIEW_MEMLOAD_KEY "view-memload" +#define VIEW_NETLOAD_KEY "view-netload" +#define VIEW_SWAPLOAD_KEY "view-swapload" +#define VIEW_LOADAVG_KEY "view-loadavg" +#define VIEW_DISKLOAD_KEY "view-diskload" + +typedef struct _MultiloadApplet MultiloadApplet; +typedef struct _LoadGraph LoadGraph; +typedef void (*LoadGraphDataFunc) (int, int [], LoadGraph *); + +#include "netspeed.h" + +typedef enum { + graph_cpuload = 0, + graph_memload, + graph_netload2, + graph_swapload, + graph_loadavg, + graph_diskload, + graph_n, +} E_graph; + +typedef enum { + memload_user = 0, + memload_shared, + memload_buffer, + memload_cached, + memload_free, + memload_n +} E_memload; + +typedef enum { + cpuload_usr = 0, + cpuload_sys, + cpuload_nice, + cpuload_iowait, + cpuload_free, + cpuload_n +} E_cpuload; + +typedef enum { + diskload_read = 0, + diskload_write, + diskload_free, + diskload_n +} E_diskload; + +typedef enum { + swapload_used = 0, + swapload_free, + swapload_n +} E_swapload; + +struct _LoadGraph { + MultiloadApplet *multiload; + + guint n, id; + guint speed, size; + guint orient, pixel_size; + guint draw_width, draw_height; + LoadGraphDataFunc get_data; + + guint allocated; + + GdkRGBA *colors; + gint **data; + guint data_size; + guint *pos; + + GtkWidget *main_widget; + GtkWidget *frame, *box, *disp; + cairo_surface_t *surface; + int timer_index; + + gboolean visible; + gboolean tooltip_update; + const gchar *name; +}; + +struct _MultiloadApplet +{ + MatePanelApplet *applet; + + GSettings *settings; + + LoadGraph *graphs [graph_n]; + + GtkWidget *box; + + gboolean view_cpuload; + gboolean view_memload; + gboolean view_netload; + gboolean view_swapload; + gboolean view_loadavg; + gboolean view_diskload; + + GtkWidget *about_dialog; + GtkWidget *check_boxes [graph_n]; + GtkWidget *prop_dialog; + GtkWidget *notebook; + int last_clicked; + + float cpu_used_ratio; + long cpu_time [cpuload_n]; + long cpu_last [cpuload_n]; + int cpu_initialized; + + double loadavg1; + + guint64 memload_user; + guint64 memload_cache; + guint64 memload_total; + + float swapload_used_ratio; + + float diskload_used_ratio; + gboolean nvme_diskstats; + + NetSpeed *netspeed_in; + NetSpeed *netspeed_out; + guint net_threshold1; + guint net_threshold2; + guint net_threshold3; +}; + +#include "load-graph.h" +#include "linux-proc.h" + +/* show properties dialog */ +G_GNUC_INTERNAL void +multiload_properties_cb (GtkAction *action, + MultiloadApplet *ma); + +/* remove the old graphs and rebuild them */ +G_GNUC_INTERNAL void +multiload_applet_refresh (MultiloadApplet *ma); + +/* update the tooltip to the graph's current "used" percentage */ +G_GNUC_INTERNAL void +multiload_applet_tooltip_update (LoadGraph *g); + +G_END_DECLS + +#endif diff --git a/multiload/src/linux-proc.c b/multiload/src/linux-proc.c new file mode 100644 index 00000000..6059e9e3 --- /dev/null +++ b/multiload/src/linux-proc.c @@ -0,0 +1,442 @@ +/* From wmload.c, v0.9.2, licensed under the GPL. */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "linux-proc.h" +#include "autoscaler.h" + +static const unsigned needed_cpu_flags = +(1 << GLIBTOP_CPU_USER) + +(1 << GLIBTOP_CPU_IDLE) + +(1 << GLIBTOP_CPU_SYS) + +(1 << GLIBTOP_CPU_NICE); + +#if 0 +static const unsigned needed_page_flags = +(1 << GLIBTOP_SWAP_PAGEIN) + +(1 << GLIBTOP_SWAP_PAGEOUT); +#endif + +static const unsigned needed_mem_flags = +(1 << GLIBTOP_MEM_USED) + +(1 << GLIBTOP_MEM_FREE); + +static const unsigned needed_swap_flags = +(1 << GLIBTOP_SWAP_USED) + +(1 << GLIBTOP_SWAP_FREE); + +static const unsigned needed_loadavg_flags = +(1 << GLIBTOP_LOADAVG_LOADAVG); + +static const unsigned needed_netload_flags = +(1 << GLIBTOP_NETLOAD_IF_FLAGS) + +(1 << GLIBTOP_NETLOAD_BYTES_TOTAL); + +void +GetLoad (int Maximum, + int data [cpuload_n], + LoadGraph *g) +{ + MultiloadApplet *multiload; + glibtop_cpu cpu; + long cpu_aux [cpuload_n], used = 0, total = 0; + int current_scaled, used_scaled = 0; + int i; + + glibtop_get_cpu (&cpu); + + g_return_if_fail ((cpu.flags & needed_cpu_flags) == needed_cpu_flags); + + multiload = g->multiload; + + multiload->cpu_time [cpuload_usr] = cpu.user; + multiload->cpu_time [cpuload_nice] = cpu.nice; + multiload->cpu_time [cpuload_sys] = cpu.sys; + multiload->cpu_time [cpuload_iowait] = cpu.iowait + cpu.irq + cpu.softirq; + multiload->cpu_time [cpuload_free] = cpu.idle; + + if (!multiload->cpu_initialized) { + memcpy (multiload->cpu_last, multiload->cpu_time, sizeof (multiload->cpu_last)); + multiload->cpu_initialized = 1; + } + + for (i = 0; i < cpuload_n; i++) { + cpu_aux [i] = multiload->cpu_time [i] - multiload->cpu_last [i]; + total += cpu_aux [i]; + } + + for (i = 0; i < cpuload_free; i++) { + used += cpu_aux [i]; + current_scaled = rint ((float)(cpu_aux [i] * Maximum) / (float)total); + used_scaled += current_scaled; + data [i] = current_scaled; + } + data [cpuload_free] = Maximum - used_scaled; + + multiload->cpu_used_ratio = (float)(used) / (float)total; + + memcpy (multiload->cpu_last, multiload->cpu_time, sizeof multiload->cpu_last); +} + +void +GetDiskLoad (int Maximum, + int data [diskload_n], + LoadGraph *g) +{ + static gboolean first_call = TRUE; + static guint64 lastread = 0, lastwrite = 0; + static AutoScaler scaler; + + guint i; + int max; + + guint64 read, write; + guint64 readdiff, writediff; + + MultiloadApplet *multiload; + + multiload = g->multiload; + + + if(first_call) + { + autoscaler_init(&scaler, 60, 500); + } + + read = write = 0; + + if (multiload->nvme_diskstats) + { + FILE *fdr; + char line[255]; + guint64 s_read, s_write; + + fdr = fopen("/proc/diskstats", "r"); + if (!fdr) + { + multiload->nvme_diskstats = FALSE; + g_settings_set_boolean (multiload->settings, "diskload-nvme-diskstats", FALSE); + return; + } + + while (fgets(line, 255, fdr)) + { + /* Match main device, rather than individual partitions (e.g. nvme0n1) */ + if (!g_regex_match_simple("\\snvme\\d+\\w+\\d+\\s", line, 0, 0)) + { + continue; + } + + /* + 6 - sectors read + 10 - sectors written + */ + if (sscanf(line, "%*d %*d %*s %*d %*d %ld %*d %*d %*d %ld", &s_read, &s_write) == 2) + { + read += 512 * s_read; + write += 512 * s_write; + } + } + fclose(fdr); + } + else + { + glibtop_mountlist mountlist; + glibtop_mountentry *mountentries; + + mountentries = glibtop_get_mountlist (&mountlist, FALSE); + + for (i = 0; i < mountlist.number; i++) + { + struct statvfs statresult; + glibtop_fsusage fsusage; + + if (strstr (mountentries[i].devname, "/dev/") == NULL) + continue; + + if (strstr (mountentries[i].mountdir, "/media/") != NULL) + continue; + + if (statvfs (mountentries[i].mountdir, &statresult) < 0) + { + g_debug ("Failed to get statistics for mount entry: %s. Reason: %s. Skipping entry.", + mountentries[i].mountdir, strerror(errno)); + continue; + } + + glibtop_get_fsusage(&fsusage, mountentries[i].mountdir); + read += fsusage.read; write += fsusage.write; + } + + g_free(mountentries); + } + + readdiff = read - lastread; + writediff = write - lastwrite; + + lastread = read; + lastwrite = write; + + if(first_call) + { + first_call = FALSE; + memset(data, 0, 3 * sizeof data[0]); + return; + } + + max = autoscaler_get_max(&scaler, readdiff + writediff); + + multiload->diskload_used_ratio = (float)(readdiff + writediff) / (float)max; + + data [diskload_read] = rint ((float)Maximum * (float)readdiff / (float)max); + data [diskload_write] = rint ((float)Maximum * (float)writediff / (float)max); + data [diskload_free] = Maximum - (data [0] + data[1]); +} + +/* GNU/Linux: + * aux [memload_user] = (mem.total - mem.free) - (mem.cached + mem.buffer) + * aux [memload_shared] = mem.shared; + * aux [memload_cached] = mem.cached - mem.shared; + * aux [memload_buffer] = mem.buffer; + * + * Other operating systems: + * aux [memload_user] = mem.user; + * aux [memload_shared] = mem.shared; + * aux [memload_cached] = mem.cached; + * aux [memload_buffer] = mem.buffer; + */ +void +GetMemory (int Maximum, + int data [memload_n], + LoadGraph *g) +{ + MultiloadApplet *multiload; + glibtop_mem mem; + guint64 aux [memload_n], cache = 0; + int current_scaled, used_scaled = 0; + int i; + + glibtop_get_mem (&mem); + + g_return_if_fail ((mem.flags & needed_mem_flags) == needed_mem_flags); + +#ifndef __linux__ + aux [memload_user] = mem.user; + aux [memload_cached] = mem.cached; +#else + aux [memload_user] = mem.total - mem.free - mem.buffer - mem.cached;; + aux [memload_cached] = mem.cached - mem.shared; +#endif /* __linux__ */ + aux [memload_shared] = mem.shared; + aux [memload_buffer] = mem.buffer; + + for (i = 0; i < memload_free; i++) { + current_scaled = rint ((float)(aux [i] * Maximum) / (float)mem.total); + if (i != memload_user) { + cache += aux [i]; + } + used_scaled += current_scaled; + data [i] = current_scaled; + } + data [memload_free] = MAX (Maximum - used_scaled, 0); + + multiload = g->multiload; + multiload->memload_user = aux [memload_user]; + multiload->memload_cache = cache; + multiload->memload_total = mem.total; +} + +void +GetSwap (int Maximum, + int data [swapload_n], + LoadGraph *g) +{ + int used; + MultiloadApplet *multiload; + glibtop_swap swap; + + glibtop_get_swap (&swap); + g_return_if_fail ((swap.flags & needed_swap_flags) == needed_swap_flags); + + multiload = g->multiload; + + if (swap.total == 0) { + used = 0; + multiload->swapload_used_ratio = 0.0f; + } + else { + float ratio; + + ratio = (float)swap.used / (float)swap.total; + used = rint ((float) Maximum * ratio); + multiload->swapload_used_ratio = ratio; + } + + data [0] = used; + data [1] = Maximum - used; +} + +void +GetLoadAvg (int Maximum, + int data [2], + LoadGraph *g) +{ + glibtop_loadavg loadavg; + MultiloadApplet *multiload; + + glibtop_get_loadavg (&loadavg); + + g_return_if_fail ((loadavg.flags & needed_loadavg_flags) == needed_loadavg_flags); + + multiload = g->multiload; + multiload->loadavg1 = loadavg.loadavg[0]; + + data [0] = rint ((float) Maximum * loadavg.loadavg[0]); + data [1] = Maximum - data[0]; +} + +/* + * Return true if a network device (identified by its name) is virtual + * (ie: not corresponding to a physical device). In case it is a physical + * device or unknown, returns false. + */ +static gboolean +is_net_device_virtual(char *device) +{ + /* + * There is not definitive way to find out. On some systems (Linux + * kernels ≳ 2.19 without option SYSFS_DEPRECATED), there exist a + * directory /sys/devices/virtual/net which only contains virtual + * devices. It's also possible to detect by the fact that virtual + * devices do not have a symlink "device" in + * /sys/class/net/name-of-dev/ . This second method is more complex + * but more reliable. + */ + gboolean ret = FALSE; + char *path = malloc (strlen (device) + strlen ("/sys/class/net//device") + 1); + + if (path == NULL) + return FALSE; + + /* Check if /sys/class/net/name-of-dev/ exists (may be old linux kernel + * or not linux at all). */ + do { + if (sprintf(path, "/sys/class/net/%s", device) < 0) + break; + if (access(path, F_OK) != 0) + break; /* unknown */ + + if (sprintf(path, "/sys/class/net/%s/device", device) < 0) + break; + if (access(path, F_OK) != 0) + ret = TRUE; + } while (0); + + free (path); + return ret; +} + +void +GetNet (int Maximum, + int data [4], + LoadGraph *g) +{ + enum Types { + IN_COUNT = 0, + OUT_COUNT = 1, + LOCAL_COUNT = 2, + COUNT_TYPES = 3 + }; + + static int ticks = 0; + static gulong past[COUNT_TYPES] = {0}; + static AutoScaler scaler; + + gulong present[COUNT_TYPES] = {0}; + + guint i; + gchar **devices; + glibtop_netlist netlist; + + MultiloadApplet *multiload; + + multiload = g->multiload; + + if(ticks == 0) + { + autoscaler_init(&scaler, 60, 501); + } + + devices = glibtop_get_netlist(&netlist); + + for(i = 0; i < netlist.number; ++i) + { + glibtop_netload netload; + + glibtop_get_netload(&netload, devices[i]); + + g_return_if_fail((netload.flags & needed_netload_flags) == needed_netload_flags); + + if (!(netload.if_flags & (1L << GLIBTOP_IF_FLAGS_UP))) + continue; + + if (netload.if_flags & (1L << GLIBTOP_IF_FLAGS_LOOPBACK)) { + /* for loopback in and out are identical, so only count in */ + present[LOCAL_COUNT] += netload.bytes_in; + continue; + } + + /* + * Do not include virtual devices (VPN, PPPOE...) to avoid + * counting the same throughput several times. + */ + if (is_net_device_virtual(devices[i])) + continue; + + present[IN_COUNT] += netload.bytes_in; + present[OUT_COUNT] += netload.bytes_out; + } + + g_strfreev(devices); + netspeed_add (multiload->netspeed_in, present[IN_COUNT]); + netspeed_add (multiload->netspeed_out, present[OUT_COUNT]); + + if(ticks < 2) /* avoid initial spike */ + { + ticks++; + memset(data, 0, COUNT_TYPES * sizeof data[0]); + } + else + { + int delta[COUNT_TYPES]; + + for (i = 0; i < COUNT_TYPES; i++) + { + /* protect against weirdness */ + if (present[i] >= past[i]) + delta[i] = (present[i] - past[i]); + else + delta[i] = 0; + } + + for (i = 0; i < COUNT_TYPES; i++) + data[i] = delta[i]; + + } + + memcpy(past, present, sizeof past); +} diff --git a/multiload/src/linux-proc.h b/multiload/src/linux-proc.h new file mode 100644 index 00000000..0aba1a0e --- /dev/null +++ b/multiload/src/linux-proc.h @@ -0,0 +1,13 @@ +#ifndef LINUX_PROC_H__ +#define LINUX_PROC_H__ + +#include + +G_GNUC_INTERNAL void GetLoad (int Maximum, int data [cpuload_n], LoadGraph *g); +G_GNUC_INTERNAL void GetDiskLoad (int Maximum, int data [diskload_n], LoadGraph *g); +G_GNUC_INTERNAL void GetMemory (int Maximum, int data [memload_n], LoadGraph *g); +G_GNUC_INTERNAL void GetSwap (int Maximum, int data [swapload_n], LoadGraph *g); +G_GNUC_INTERNAL void GetLoadAvg (int Maximum, int data [2], LoadGraph *g); +G_GNUC_INTERNAL void GetNet (int Maximum, int data [4], LoadGraph *g); + +#endif diff --git a/multiload/src/load-graph.c b/multiload/src/load-graph.c new file mode 100644 index 00000000..953dc5b2 --- /dev/null +++ b/multiload/src/load-graph.c @@ -0,0 +1,501 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "global.h" + +/* + Shifts data right + + data[i+1] = data[i] + + data[i] are int*, 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; + int* last_data; + + /* data[g->draw_width - 1] becomes data[0] */ + last_data = g->data[g->draw_width - 1]; + + /* data[i+1] = data[i] */ + for(i = g->draw_width - 1; i != 0; --i) + g->data[i] = g->data[i - 1]; + + g->data[0] = last_data; +} + + +/* Redraws the backing pixmap for the load graph and updates the window */ +static void +load_graph_draw (LoadGraph *g) +{ + guint i, j, k; + cairo_t *cr; + int load; + MultiloadApplet *multiload; + + multiload = g->multiload; + + /* we might get called before the configure event so that + * g->disp->allocation may not have the correct size + * (after the user resized the applet in the prop dialog). */ + + if (!g->surface) + g->surface = gdk_window_create_similar_surface (gtk_widget_get_window (g->disp), + CAIRO_CONTENT_COLOR, + g->draw_width, g->draw_height); + + cr = cairo_create (g->surface); + cairo_set_line_width (cr, 1.0); + cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); + cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); + + /* all graphs except Load and Net go this path */ + if (g->id != graph_loadavg && g->id != graph_netload2) + { + for (i = 0; i < g->draw_width; i++) + g->pos [i] = g->draw_height - 1; + + for (j = 0; j < g->n; j++) + { + gdk_cairo_set_source_rgba (cr, &(g->colors [j])); + + for (i = 0; i < g->draw_width; i++) + { + if (g->data [i][j] != 0) + { + cairo_move_to (cr, g->draw_width - i - 0.5, g->pos[i] + 0.5); + cairo_line_to (cr, g->draw_width - i - 0.5, g->pos[i] - (g->data [i][j] - 0.5)); + } + g->pos [i] -= g->data [i][j]; + } + cairo_stroke (cr); + } + } + /* This is for network graph */ + else if (g->id == graph_netload2) + { + guint maxnet = 1; + gint segments = 1; + gint combined; + guint net_threshold; + + for (i = 0; i < g->draw_width; i++) + { + g->pos [i] = g->draw_height - 1; + combined = g->data[i][0] + + g->data[i][1] + + g->data[i][2]; + if (combined > maxnet) + maxnet = combined; + } + //printf("max = %d ", maxnet); + guint level = 0; + if (maxnet > multiload->net_threshold3) { + net_threshold = multiload->net_threshold3; + level = 3; + } + else + if (maxnet > multiload->net_threshold2) { + net_threshold = multiload->net_threshold2; + level = 2; + } + else { + net_threshold = multiload->net_threshold1; + level = 1; + if (maxnet < multiload->net_threshold1) + level = 0; + } + + //printf("level %d maxnet = %d ", level, maxnet); + maxnet = maxnet/net_threshold; + segments = MAX (maxnet+1,1); + float ratio = (float)g->draw_height/net_threshold/segments; + //printf("segments %d ratio = %f t1=%ld t2=%ld t3=%ld t=%ld\n", segments, ratio, multiload->net_threshold1, multiload->net_threshold2, multiload->net_threshold3, multiload->net_threshold); + + for (j = 0; j < g->n-1; j++) + { + gdk_cairo_set_source_rgba (cr, &(g->colors [j])); + + for (i = 0; i < g->draw_width; i++) + { + cairo_move_to (cr, g->draw_width - i - 0.5, g->pos[i] + 0.5); + cairo_line_to (cr, g->draw_width - i - 0.5, g->pos[i] - 0.5 - ((g->data [i][j] * ratio))); + g->pos [i] -= ((g->data [i][j] * ratio)); + } + cairo_stroke (cr); + } + + for (j = g->n-1; j < g->n; j++) + { + gdk_cairo_set_source_rgba (cr, &(g->colors [j])); + for (i = 0; i < g->draw_width; i++) + { + cairo_move_to (cr, g->draw_width - i - 0.5, g->pos[i] + 0.5); + cairo_line_to (cr, g->draw_width - i - 0.5, 0.5); + } + cairo_stroke (cr); + } + + /* draw grid lines if needed */ + gdk_cairo_set_source_rgba (cr, &(g->colors [4])); + double spacing; + for (k = 0; k < segments -1; k++) + { + spacing = ((double) g->draw_height/segments) * (k+1); + cairo_move_to (cr, 0.5, spacing); + cairo_line_to (cr, g->draw_width-0.5, spacing); + } + cairo_stroke (cr); + /* draw indicator if needed */ + if (level > 0) + { + gdk_cairo_set_source_rgba (cr, &(g->colors [5])); + for (k = 0; k< level; k++ ) + cairo_rectangle(cr, 0.5, (k*2) * g->draw_height/5, 5, g->draw_height/5); + cairo_fill(cr); + } + cairo_stroke (cr); + } + /* this is Load graph */ + else + { + guint maxload = 1; + for (i = 0; i < g->draw_width; i++) + { + g->pos [i] = g->draw_height - 1; + /* find maximum value */ + if (g->data[i][0] > maxload) + maxload = g->data[i][0]; + } + load = ceil ((double) (maxload/g->draw_height)) + 1; + load = MAX (load,1); + + for (j = 0; j < g->n; j++) + { + gdk_cairo_set_source_rgba (cr, &(g->colors [j])); + + for (i = 0; i < g->draw_width; i++) + { + cairo_move_to (cr, g->draw_width - i - 0.5, g->pos[i] + 0.5); + if (j == 0) + { + cairo_line_to (cr, g->draw_width - i - 0.5, g->pos[i] - ((g->data [i][j] - 0.5)/load)); + } + else + { + cairo_line_to (cr, g->draw_width - i - 0.5, 0.5); + } + g->pos [i] -= g->data [i][j] / load; + } + cairo_stroke (cr); + } + + /* draw grid lines in Load graph if needed */ + gdk_cairo_set_source_rgba (cr, &(g->colors [2])); + + double spacing; + for (k = 0; k < load - 1; k++) + { + spacing = ((double) g->draw_height/load) * (k+1); + cairo_move_to (cr, 0.5, spacing); + cairo_line_to (cr, g->draw_width-0.5, spacing); + } + + cairo_stroke (cr); + } + gtk_widget_queue_draw (g->disp); + + cairo_destroy (cr); +} + +/* Updates the load graph when the timeout expires */ +static gboolean +load_graph_update (LoadGraph *g) +{ + if (g->data == NULL) + return TRUE; + + shift_right(g); + + if (g->tooltip_update) + multiload_applet_tooltip_update(g); + + g->get_data (g->draw_height, g->data [0], g); + + load_graph_draw (g); + return TRUE; +} + +void +load_graph_unalloc (LoadGraph *g) +{ + guint i; + + if (!g->allocated) + return; + + for (i = 0; i < g->draw_width; i++) + { + g_free (g->data [i]); + } + + g_free (g->data); + g_free (g->pos); + + g->pos = NULL; + g->data = NULL; + + g->size = g_settings_get_int(g->multiload->settings, "size"); + g->size = MAX (g->size, 10); + + if (g->surface) { + cairo_surface_destroy (g->surface); + g->surface = NULL; + } + + g->allocated = FALSE; +} + +static void +load_graph_alloc (LoadGraph *g) +{ + guint i; + + if (g->allocated) + return; + + g->data = g_new0 (gint *, g->draw_width); + g->pos = g_new0 (guint, g->draw_width); + + g->data_size = sizeof (guint) * g->n; + + for (i = 0; i < g->draw_width; i++) { + g->data [i] = g_malloc0 (g->data_size); + } + + g->allocated = TRUE; +} + +static gint +load_graph_configure (GtkWidget *widget, GdkEventConfigure *event, + gpointer data_ptr) +{ + GtkAllocation allocation; + LoadGraph *c = (LoadGraph *) data_ptr; + + load_graph_unalloc (c); + + gtk_widget_get_allocation (c->disp, &allocation); + + c->draw_width = allocation.width; + c->draw_height = allocation.height; + c->draw_width = MAX (c->draw_width, 1); + c->draw_height = MAX (c->draw_height, 1); + + load_graph_alloc (c); + + if (!c->surface) + c->surface = gdk_window_create_similar_surface (gtk_widget_get_window (c->disp), + CAIRO_CONTENT_COLOR, + c->draw_width, c->draw_height); + gtk_widget_queue_draw (widget); + + return TRUE; +} + +static gint +load_graph_expose (GtkWidget *widget, + cairo_t *cr, + gpointer data_ptr) +{ + LoadGraph *g = (LoadGraph *) data_ptr; + + cairo_set_source_surface (cr, g->surface, 0, 0); + cairo_paint (cr); + + return FALSE; +} + +static void +load_graph_destroy (GtkWidget *widget, gpointer data_ptr) +{ + LoadGraph *g = (LoadGraph *) data_ptr; + + load_graph_stop (g); + + gtk_widget_destroy(widget); +} + +static gboolean +load_graph_clicked (GtkWidget *widget, GdkEventButton *event, LoadGraph *load) +{ + load->multiload->last_clicked = load->id; + + return FALSE; +} + +static gboolean +load_graph_enter_cb(GtkWidget *widget, GdkEventCrossing *event, gpointer data) +{ + LoadGraph *graph; + graph = (LoadGraph *)data; + + graph->tooltip_update = TRUE; + multiload_applet_tooltip_update(graph); + + return TRUE; +} + +static gboolean +load_graph_leave_cb(GtkWidget *widget, GdkEventCrossing *event, gpointer data) +{ + LoadGraph *graph; + graph = (LoadGraph *)data; + + graph->tooltip_update = FALSE; + + return TRUE; +} + +static void +load_graph_load_config (LoadGraph *g) +{ + gchar *name, *temp; + guint i; + + if (!g->colors) + g->colors = g_new0(GdkRGBA, g->n); + + for (i = 0; i < g->n; i++) + { + name = g_strdup_printf ("%s-color%u", g->name, i); + temp = g_settings_get_string(g->multiload->settings, name); + if (!temp) + temp = g_strdup ("#000000"); + gdk_rgba_parse(&(g->colors[i]), temp); + g_free(temp); + g_free(name); + } +} + +LoadGraph * +load_graph_new (MultiloadApplet *ma, guint n, const gchar *label, + guint id, guint speed, guint size, gboolean visible, + const gchar *name, LoadGraphDataFunc get_data) +{ + LoadGraph *g; + MatePanelAppletOrient orient; + + g = g_new0 (LoadGraph, 1); + g->visible = visible; + g->name = name; + g->n = n; + g->id = id; + g->speed = MAX (speed, 50); + g->size = MAX (size, 10); + g->pixel_size = mate_panel_applet_get_size (ma->applet); + g->tooltip_update = FALSE; + g->multiload = ma; + + g->main_widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); + + g->box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); + + orient = mate_panel_applet_get_orient (g->multiload->applet); + switch (orient) + { + case MATE_PANEL_APPLET_ORIENT_UP: + case MATE_PANEL_APPLET_ORIENT_DOWN: + { + g->orient = FALSE; + break; + } + case MATE_PANEL_APPLET_ORIENT_LEFT: + case MATE_PANEL_APPLET_ORIENT_RIGHT: + { + g->orient = TRUE; + break; + } + default: + g_assert_not_reached (); + } + + g->frame = gtk_frame_new (NULL); + gtk_frame_set_shadow_type (GTK_FRAME (g->frame), GTK_SHADOW_IN); + gtk_container_add (GTK_CONTAINER (g->frame), g->box); + gtk_box_pack_start (GTK_BOX (g->main_widget), g->frame, TRUE, TRUE, 0); + + load_graph_load_config (g); + + g->get_data = get_data; + + g->timer_index = -1; + + if (g->orient) + gtk_widget_set_size_request (g->main_widget, -1, g->size); + else + gtk_widget_set_size_request (g->main_widget, g->size, -1); + + g->disp = gtk_drawing_area_new (); + gtk_widget_set_events (g->disp, GDK_EXPOSURE_MASK | + GDK_ENTER_NOTIFY_MASK | + GDK_LEAVE_NOTIFY_MASK | + GDK_BUTTON_PRESS_MASK); + + g_signal_connect (G_OBJECT (g->disp), "draw", + 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); + g_signal_connect (G_OBJECT(g->disp), "button-press-event", + G_CALLBACK (load_graph_clicked), g); + g_signal_connect (G_OBJECT(g->disp), "enter-notify-event", + G_CALLBACK(load_graph_enter_cb), g); + g_signal_connect (G_OBJECT(g->disp), "leave-notify-event", + G_CALLBACK(load_graph_leave_cb), g); + + gtk_box_pack_start (GTK_BOX (g->box), g->disp, TRUE, TRUE, 0); + gtk_widget_show_all(g->box); + + return g; +} + +void +load_graph_start (LoadGraph *g) +{ + if (g->timer_index != -1) + g_source_remove (g->timer_index); + + g->timer_index = g_timeout_add (g->speed, + (GSourceFunc) load_graph_update, g); +} + +void +load_graph_stop (LoadGraph *g) +{ + if (g->timer_index != -1) + g_source_remove (g->timer_index); + + g->timer_index = -1; +} diff --git a/multiload/src/load-graph.h b/multiload/src/load-graph.h new file mode 100644 index 00000000..76effcd6 --- /dev/null +++ b/multiload/src/load-graph.h @@ -0,0 +1,24 @@ +#ifndef LOAD_GRAPH_H__ +#define LOAD_GRAPH_H__ + +#include "global.h" + +/* Create new load graph. */ +G_GNUC_INTERNAL LoadGraph * +load_graph_new (MultiloadApplet *multiload, guint n, const gchar *label, + guint id, guint speed, guint size, gboolean visible, + const gchar *name, LoadGraphDataFunc get_data); + +/* Start load graph. */ +G_GNUC_INTERNAL void +load_graph_start (LoadGraph *g); + +/* Stop load graph. */ +G_GNUC_INTERNAL void +load_graph_stop (LoadGraph *g); + +/* free load graph */ +G_GNUC_INTERNAL void +load_graph_unalloc (LoadGraph *g); + +#endif diff --git a/multiload/src/main.c b/multiload/src/main.c new file mode 100644 index 00000000..50732e01 --- /dev/null +++ b/multiload/src/main.c @@ -0,0 +1,573 @@ +/* MATE multiload panel applet + * (C) 1997 The Free Software Foundation + * + * Authors: Tim P. Gerla + * Martin Baulig + * Todd Kulesza + * + * With code from wmload.c, v0.9.2, apparently by Ryan Land, rland@bc1.com. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "global.h" + +static void +about_cb (GtkAction *action, + MultiloadApplet *ma) +{ + const gchar * const authors[] = + { + "Martin Baulig ", + "Todd Kulesza ", + "Benoît Dejean ", + "Davyd Madeley ", + NULL + }; + + const gchar* documenters[] = + { + "Chee Bin HOH ", + N_("Sun GNOME Documentation Team "), + N_("MATE Documentation Team"), + NULL + }; + +#ifdef ENABLE_NLS + const char **p; + for (p = documenters; *p; ++p) + *p = _(*p); +#endif + + gtk_show_about_dialog (NULL, + "title", _("About System Monitor"), + "version", VERSION, + "copyright", _("Copyright \xc2\xa9 1999-2005 Free Software Foundation and others\n" + "Copyright \xc2\xa9 2012-2020 MATE developers"), + "comments", _("A system load monitor capable of displaying graphs " + "for CPU, ram, and swap space use, plus network " + "traffic."), + "authors", authors, + "documenters", documenters, + "translator-credits", _("translator-credits"), + "logo-icon-name", "utilities-system-monitor", + NULL); +} + +static void +help_cb (GtkAction *action, + MultiloadApplet *ma) +{ + GError *error = NULL; + + gtk_show_uri_on_window (NULL, + "help:mate-multiload", + gtk_get_current_event_time (), + &error); + + if (error) { /* FIXME: the user needs to see this */ + g_warning ("help error: %s\n", error->message); + g_error_free (error); + error = NULL; + } +} + +/* run the full-scale system process monitor */ + +static void +start_procman (MultiloadApplet *ma) +{ + GError *error = NULL; + GDesktopAppInfo *appinfo; + gchar *monitor; + GdkAppLaunchContext *launch_context; + GdkDisplay *display; + GAppInfo *app_info; + GdkScreen *screen; + + g_return_if_fail (ma != NULL); + + monitor = g_settings_get_string (ma->settings, "system-monitor"); + if (monitor == NULL) + monitor = g_strdup ("mate-system-monitor.desktop"); + + screen = gtk_widget_get_screen (GTK_WIDGET (ma->applet)); + appinfo = g_desktop_app_info_new (monitor); + if (appinfo) { + GdkAppLaunchContext *context; + display = gdk_screen_get_display (screen); + context = gdk_display_get_app_launch_context (display); + gdk_app_launch_context_set_screen (context, screen); + g_app_info_launch (G_APP_INFO (appinfo), NULL, G_APP_LAUNCH_CONTEXT (context), &error); + g_object_unref (context); + g_object_unref (appinfo); + } + else { + app_info = g_app_info_create_from_commandline ("mate-system-monitor", + _("Start system-monitor"), + G_APP_INFO_CREATE_NONE, + &error); + + if (!error) { + display = gdk_screen_get_display (screen); + launch_context = gdk_display_get_app_launch_context (display); + gdk_app_launch_context_set_screen (launch_context, screen); + g_app_info_launch (app_info, NULL, G_APP_LAUNCH_CONTEXT (launch_context), &error); + + g_object_unref (launch_context); + } + } + g_free (monitor); + + if (error) { + GtkWidget *dialog; + + dialog = gtk_message_dialog_new (NULL, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _("There was an error executing '%s': %s"), + "mate-system-monitor", + error->message); + + g_signal_connect (dialog, "response", + G_CALLBACK (gtk_widget_destroy), + NULL); + + gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); + gtk_window_set_screen (GTK_WINDOW (dialog), screen); + + gtk_widget_show (dialog); + + g_error_free (error); + } +} + +static void +start_procman_cb (GtkAction *action, + MultiloadApplet *ma) +{ + start_procman (ma); +} + +static void +multiload_change_size_cb(MatePanelApplet *applet, gint size, gpointer data) +{ + MultiloadApplet *ma = (MultiloadApplet *)data; + + multiload_applet_refresh(ma); + + return; +} + +static void +multiload_change_orient_cb(MatePanelApplet *applet, gint arg1, gpointer data) +{ + MultiloadApplet *ma = data; + multiload_applet_refresh((MultiloadApplet *)data); + gtk_widget_show (GTK_WIDGET (ma->applet)); + return; +} + +static void +multiload_destroy_cb(GtkWidget *widget, gpointer data) +{ + gint i; + MultiloadApplet *ma = data; + + for (i = 0; i < graph_n; i++) + { + load_graph_stop(ma->graphs[i]); + if (ma->graphs[i]->colors) + { + g_free (ma->graphs[i]->colors); + ma->graphs[i]->colors = NULL; + } + gtk_widget_destroy(ma->graphs[i]->main_widget); + + load_graph_unalloc(ma->graphs[i]); + g_free(ma->graphs[i]); + } + + netspeed_delete (ma->netspeed_in); + netspeed_delete (ma->netspeed_out); + + if (ma->about_dialog) + gtk_widget_destroy (ma->about_dialog); + + if (ma->prop_dialog) + gtk_widget_destroy (ma->prop_dialog); + + gtk_widget_destroy(GTK_WIDGET(ma->applet)); + + g_free (ma); + + return; +} + + +static gboolean +multiload_button_press_event_cb (GtkWidget *widget, GdkEventButton *event, MultiloadApplet *ma) +{ + g_return_val_if_fail (event != NULL, FALSE); + g_return_val_if_fail (ma != NULL, FALSE); + + if (event->button == 1 && event->type == GDK_BUTTON_PRESS) { + start_procman (ma); + return TRUE; + } + return FALSE; +} + +static gboolean +multiload_key_press_event_cb (GtkWidget *widget, GdkEventKey *event, MultiloadApplet *ma) +{ + g_return_val_if_fail (event != NULL, FALSE); + g_return_val_if_fail (ma != NULL, FALSE); + + switch (event->keyval) { + /* this list of keyvals taken from mixer applet, which seemed to have + a good list of keys to use */ + case GDK_KEY_KP_Enter: + case GDK_KEY_ISO_Enter: + case GDK_KEY_3270_Enter: + case GDK_KEY_Return: + case GDK_KEY_space: + case GDK_KEY_KP_Space: + /* activate */ + start_procman (ma); + return TRUE; + + default: + break; + } + + return FALSE; +} + +/* update the tooltip to the graph's current "used" percentage */ +void +multiload_applet_tooltip_update(LoadGraph *g) +{ + gchar *tooltip_text; + MultiloadApplet *multiload; + const char *tooltip_label [graph_n] = { + [graph_cpuload] = N_("Processor"), + [graph_memload] = N_("Memory"), + [graph_netload2] = N_("Network"), + [graph_swapload] = N_("Swap Space"), + [graph_loadavg] = N_("Load Average"), + [graph_diskload] = N_("Disk") + }; + const char *name; + + g_assert(g); + + multiload = g->multiload; + + /* label the tooltip intuitively */ + name = gettext (tooltip_label [g->id]); + + switch (g->id) { + case graph_memload: { + float user_percent, cache_percent; + + user_percent = MIN ((float)(100 * multiload->memload_user) / (float)(multiload->memload_total), 100.0f); + cache_percent = MIN ((float)(100 * multiload->memload_cache) / (float)(multiload->memload_total), 100.0f); + tooltip_text = g_strdup_printf (_("%s:\n" + "%.01f%% in use by programs\n" + "%.01f%% in use as cache"), + name, + user_percent, + cache_percent); + break; + } + case graph_loadavg: { + tooltip_text = g_strdup_printf (_("The system load average is %0.02f"), + multiload->loadavg1); + break; + } + case graph_netload2: { + char *tx_in, *tx_out; + + tx_in = netspeed_get(multiload->netspeed_in); + tx_out = netspeed_get(multiload->netspeed_out); + /* xgettext: same as in graphic tab of g-s-m */ + tooltip_text = g_strdup_printf(_("%s:\n" + "Receiving %s\n" + "Sending %s"), + name, tx_in, tx_out); + g_free(tx_in); + g_free(tx_out); + break; + } + default: { + float ratio; + float percent; + + if (g->id == graph_cpuload) + ratio = multiload->cpu_used_ratio; + else if (g->id == graph_swapload) + ratio = multiload->swapload_used_ratio; + else if (g->id == graph_diskload) + ratio = multiload->diskload_used_ratio; + else + g_assert_not_reached (); + + percent = CLAMP (ratio * 100.0f, 0.0f, 100.0f); + tooltip_text = g_strdup_printf(_("%s:\n" + "%.01f%% in use"), + name, + percent); + } + } + + gtk_widget_set_tooltip_text(g->disp, tooltip_text); + + g_free(tooltip_text); +} + +static void +multiload_create_graphs(MultiloadApplet *ma) +{ + struct { const char *label; + const char *visibility_key; + const char *name; + int num_colours; + LoadGraphDataFunc callback; + } graph_types [graph_n] = { + [graph_cpuload] = { _("CPU Load"), VIEW_CPULOAD_KEY, "cpuload", cpuload_n, GetLoad }, + [graph_memload] = { _("Memory Load"), VIEW_MEMLOAD_KEY, "memload", memload_n, GetMemory }, + [graph_netload2] = { _("Net Load"), VIEW_NETLOAD_KEY, "netload2", 6, GetNet }, + [graph_swapload] = { _("Swap Load"), VIEW_SWAPLOAD_KEY, "swapload", swapload_n, GetSwap }, + [graph_loadavg] = { _("Load Average"), VIEW_LOADAVG_KEY, "loadavg", 3, GetLoadAvg }, + [graph_diskload] = { _("Disk Load"), VIEW_DISKLOAD_KEY, "diskload", diskload_n, GetDiskLoad } + }; + + gint speed, size; + guint net_threshold1; + guint net_threshold2; + guint net_threshold3; + gint i; + + speed = g_settings_get_int (ma->settings, "speed"); + size = g_settings_get_int (ma->settings, "size"); + net_threshold1 = CLAMP (g_settings_get_uint (ma->settings, "netthreshold1"), MIN_NET_THRESHOLD1, MAX_NET_THRESHOLD1); + net_threshold2 = CLAMP (g_settings_get_uint (ma->settings, "netthreshold2"), MIN_NET_THRESHOLD2, MAX_NET_THRESHOLD2); + net_threshold3 = CLAMP (g_settings_get_uint (ma->settings, "netthreshold3"), MIN_NET_THRESHOLD3, MAX_NET_THRESHOLD3); + if (net_threshold1 >= net_threshold2) + { + net_threshold1 = net_threshold2 - 1; + } + if (net_threshold2 >= net_threshold3) + { + net_threshold3 = net_threshold2 + 1; + } + speed = MAX (speed, 50); + size = CLAMP (size, 10, 400); + + for (i = 0; i < graph_n; i++) + { + ma->graphs[i] = load_graph_new (ma, + graph_types[i].num_colours, + graph_types[i].label, + i, + speed, + size, + g_settings_get_boolean (ma->settings, graph_types[i].visibility_key), + graph_types[i].name, + graph_types[i].callback); + } + ma->nvme_diskstats = g_settings_get_boolean (ma->settings, "diskload-nvme-diskstats"); + /* for Network graph, colors[4] is grid line color, it should not be used in loop in load-graph.c */ + /* for Network graph, colors[5] is indicator color, it should not be used in loop in load-graph.c */ + ma->graphs[graph_netload2]->n = 4; + ma->net_threshold1 = net_threshold1; + ma->net_threshold2 = net_threshold2; + ma->net_threshold3 = net_threshold3; + ma->netspeed_in = netspeed_new (ma->graphs [graph_netload2]); + ma->netspeed_out = netspeed_new (ma->graphs [graph_netload2]); + /* for Load graph, colors[2] is grid line color, it should not be used in loop in load-graph.c */ + ma->graphs[graph_loadavg]->n = 2; +} + +/* remove the old graphs and rebuild them */ +void +multiload_applet_refresh(MultiloadApplet *ma) +{ + gint i; + MatePanelAppletOrient orientation; + + /* stop and free the old graphs */ + for (i = 0; i < graph_n; i++) + { + if (!ma->graphs[i]) + continue; + + load_graph_stop(ma->graphs[i]); + gtk_widget_destroy(ma->graphs[i]->main_widget); + + load_graph_unalloc(ma->graphs[i]); + g_free(ma->graphs[i]); + } + + if (ma->box) + gtk_widget_destroy(ma->box); + + orientation = mate_panel_applet_get_orient(ma->applet); + + if ( (orientation == MATE_PANEL_APPLET_ORIENT_UP) || + (orientation == MATE_PANEL_APPLET_ORIENT_DOWN) ) { + ma->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + } + else + ma->box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); + + gtk_container_add(GTK_CONTAINER(ma->applet), ma->box); + + /* create the N graphs, passing in their user-configurable properties with gsettings. */ + multiload_create_graphs (ma); + + /* only start and display the graphs the user has turned on */ + + for (i = 0; i < graph_n; i++) { + gtk_box_pack_start(GTK_BOX(ma->box), + ma->graphs[i]->main_widget, + TRUE, TRUE, 1); + if (ma->graphs[i]->visible) { + gtk_widget_show_all (ma->graphs[i]->main_widget); + load_graph_start(ma->graphs[i]); + } + } + gtk_widget_show (ma->box); + + return; +} + +static const GtkActionEntry multiload_menu_actions [] = { + { "MultiLoadProperties", "document-properties", N_("_Preferences"), + NULL, NULL, + G_CALLBACK (multiload_properties_cb) }, + { "MultiLoadRunProcman", "system-run", N_("_Open System Monitor"), + NULL, NULL, + G_CALLBACK (start_procman_cb) }, + { "MultiLoadHelp", "help-browser", N_("_Help"), + NULL, NULL, + G_CALLBACK (help_cb) }, + { "MultiLoadAbout", "help-about", N_("_About"), + NULL, NULL, + G_CALLBACK (about_cb) } +}; + +/* create a box and stuff the load graphs inside of it */ +static gboolean +multiload_applet_new(MatePanelApplet *applet, const gchar *iid, gpointer data) +{ + GtkStyleContext *context; + MultiloadApplet *ma; + GSettings *lockdown_settings; + GtkActionGroup *action_group; + + context = gtk_widget_get_style_context (GTK_WIDGET (applet)); + gtk_style_context_add_class (context, "multiload-applet"); + + ma = g_new0(MultiloadApplet, 1); + + ma->applet = applet; + + ma->about_dialog = NULL; + ma->prop_dialog = NULL; + ma->last_clicked = 0; + + g_set_application_name (_("System Monitor")); + + gtk_window_set_default_icon_name ("utilities-system-monitor"); + + ma->settings = mate_panel_applet_settings_new (applet, "org.mate.panel.applet.multiload"); + mate_panel_applet_set_flags (applet, MATE_PANEL_APPLET_EXPAND_MINOR); + + action_group = gtk_action_group_new ("Multiload Applet Actions"); + gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE); + gtk_action_group_add_actions (action_group, + multiload_menu_actions, + G_N_ELEMENTS (multiload_menu_actions), + ma); + mate_panel_applet_setup_menu_from_file (applet, + MULTILOAD_MENU_UI_DIR "multiload-applet-menu.xml", + action_group); + + if (mate_panel_applet_get_locked_down (applet)) { + GtkAction *action; + + action = gtk_action_group_get_action (action_group, "MultiLoadProperties"); + gtk_action_set_visible (action, FALSE); + } + + lockdown_settings = g_settings_new ("org.mate.lockdown"); + if (g_settings_get_boolean (lockdown_settings, "disable-command-line") || + mate_panel_applet_get_locked_down (applet)) { + GtkAction *action; + + /* When the panel is locked down or when the command line is inhibited, + it seems very likely that running the procman would be at least harmful */ + action = gtk_action_group_get_action (action_group, "MultiLoadRunProcman"); + gtk_action_set_visible (action, FALSE); + } + g_object_unref (lockdown_settings); + + g_object_unref (action_group); + + g_signal_connect(G_OBJECT(applet), "change_size", + G_CALLBACK(multiload_change_size_cb), ma); + g_signal_connect(G_OBJECT(applet), "change_orient", + G_CALLBACK(multiload_change_orient_cb), ma); + g_signal_connect(G_OBJECT(applet), "destroy", + G_CALLBACK(multiload_destroy_cb), ma); + g_signal_connect(G_OBJECT(applet), "button_press_event", + G_CALLBACK(multiload_button_press_event_cb), ma); + g_signal_connect(G_OBJECT(applet), "key_press_event", + G_CALLBACK(multiload_key_press_event_cb), ma); + + multiload_applet_refresh (ma); + + gtk_widget_show(GTK_WIDGET(applet)); + + return TRUE; +} + +static gboolean +multiload_factory (MatePanelApplet *applet, + const gchar *iid, + gpointer data) +{ + gboolean retval = FALSE; + + glibtop_init(); + + retval = multiload_applet_new(applet, iid, data); + + return retval; +} + +MATE_PANEL_APPLET_OUT_PROCESS_FACTORY ("MultiLoadAppletFactory", + PANEL_TYPE_APPLET, + "multiload", + multiload_factory, + NULL) diff --git a/multiload/src/netspeed.c b/multiload/src/netspeed.c new file mode 100644 index 00000000..3e889c8f --- /dev/null +++ b/multiload/src/netspeed.c @@ -0,0 +1,70 @@ +#include +#include +#include + +#include "netspeed.h" + +enum { N_STATES = 4 }; + +struct _NetSpeed +{ + LoadGraph *graph; + gulong states[N_STATES]; + size_t cur; +}; + +NetSpeed* netspeed_new(LoadGraph *g) +{ + NetSpeed *ns = g_new0(NetSpeed, 1); + ns->graph = g; + return ns; +} + +void netspeed_delete(NetSpeed *ns) +{ + g_free(ns); +} + +void netspeed_add(NetSpeed *ns, gulong tx) +{ + ns->cur = (ns->cur + 1) % N_STATES; + ns->states[ns->cur] = tx; +} + +/* Something very similar to g_format_size() but for rates. + * This should give the same display as in g-s-m */ +static char* +format_rate_for_display(guint rate) +{ + char *bytes; + char *text; + + bytes = g_format_size (rate); + text = g_strdup_printf (_("%s/s"), bytes); + g_free (bytes); + + return text; +} + +char* netspeed_get(NetSpeed *ns) +{ + gulong older, newer; + guint rate; + + newer = ns->states[ns->cur]; + older = ns->states[(ns->cur + 1) % N_STATES]; + + if ((older != 0) && (newer > older)) + rate = (newer - older) * 1000 / ((N_STATES - 1) * ns->graph->speed); + else + /* We end up here if we haven't got enough data yet or the + network interface has jumped back (or there has never + been any activity on any interface). A value of 0 is + likely to be accurate, but if it is wrong it will be + clearly wrong. In any event, it should fix itself in a + few seconds. */ + rate = 0; + + return format_rate_for_display(rate); +} + diff --git a/multiload/src/netspeed.h b/multiload/src/netspeed.h new file mode 100644 index 00000000..5bc19cf1 --- /dev/null +++ b/multiload/src/netspeed.h @@ -0,0 +1,15 @@ +#ifndef H_MULTILOAD_NETSPEED_ +#define H_MULTILOAD_NETSPEED_ + +#include + +typedef struct _NetSpeed NetSpeed; + +#include "global.h" + +NetSpeed* netspeed_new(LoadGraph *graph); +void netspeed_delete(NetSpeed *ns); +void netspeed_add(NetSpeed *ns, gulong tx); +char* netspeed_get(NetSpeed *ns); + +#endif /* H_MULTILOAD_NETSPEED_ */ diff --git a/multiload/src/properties.c b/multiload/src/properties.c new file mode 100644 index 00000000..c1ee09b6 --- /dev/null +++ b/multiload/src/properties.c @@ -0,0 +1,868 @@ +/* MATE cpuload/memload panel applet + * (C) 2002 The Free Software Foundation + * + * Authors: + * Todd Kulesza + * + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include + +#include +#include +#include + +#include "global.h" + +#define PROP_CPU 0 +#define PROP_MEM 1 +#define PROP_NET 2 +#define PROP_SWAP 3 +#define PROP_AVG 4 +#define PROP_DISK 5 + +#define PROP_SPEED 6 +#define PROP_SIZE 7 +#define PROP_NET_THRESHOLD1 8 +#define PROP_NET_THRESHOLD2 9 +#define PROP_NET_THRESHOLD3 10 +#define HIG_IDENTATION " " +#define NEVER_SENSITIVE "never_sensitive" + +/* set sensitive and setup NEVER_SENSITIVE appropriately */ +static void +hard_set_sensitive (GtkWidget *w, gboolean sensitivity) +{ + gtk_widget_set_sensitive (w, sensitivity); + g_object_set_data (G_OBJECT (w), NEVER_SENSITIVE, + GINT_TO_POINTER ( ! sensitivity)); +} + + +/* set sensitive, but always insensitive if NEVER_SENSITIVE is set */ +static void +soft_set_sensitive (GtkWidget *w, gboolean sensitivity) +{ + if (g_object_get_data (G_OBJECT (w), NEVER_SENSITIVE)) + gtk_widget_set_sensitive (w, FALSE); + else + gtk_widget_set_sensitive (w, sensitivity); +} + +static void +properties_set_insensitive(MultiloadApplet *ma) +{ + gint i, total_graphs, last_graph; + + total_graphs = 0; + last_graph = 0; + + for (i = 0; i < graph_n; i++) + if (ma->graphs[i]->visible) + { + last_graph = i; + total_graphs++; + } + + if (total_graphs < 2) + soft_set_sensitive(ma->check_boxes[last_graph], FALSE); + + return; +} + +static void +properties_close_cb (GtkWidget *widget, gint arg, MultiloadApplet *ma) +{ + GError *error = NULL; + + switch (arg) + { + case GTK_RESPONSE_HELP: + + gtk_show_uri_on_window (NULL, + "help:mate-multiload/multiload-prefs", + gtk_get_current_event_time (), + &error); + + if (error) { /* FIXME: the user needs to see this */ + g_warning ("help error: %s\n", error->message); + g_error_free (error); + error = NULL; + } + break; + + case GTK_RESPONSE_CLOSE: + default: + gtk_widget_destroy (widget); + ma->prop_dialog = NULL; + } +} + +static void +property_toggled_cb(GtkWidget *widget, gpointer name) +{ + MultiloadApplet *ma; + gint prop_type, i; + gboolean active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); + + ma = g_object_get_data(G_OBJECT(widget), "MultiloadApplet"); + prop_type = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "prop_type")); + + /* FIXME: the first toggle button to be checked/dechecked does not work, but after that everything is cool. what gives? */ + /* FIXME: check if this is still valid for gsettings */ + g_settings_set_boolean (ma->settings, (gchar *)name, active); + g_settings_set_boolean (ma->settings, (gchar *)name, active); + + if (active) + { + for (i = 0; i < graph_n; i++) + soft_set_sensitive(ma->check_boxes[i], TRUE); + gtk_widget_show_all (ma->graphs[prop_type]->main_widget); + ma->graphs[prop_type]->visible = TRUE; + load_graph_start(ma->graphs[prop_type]); + } + else + { + load_graph_stop(ma->graphs[prop_type]); + gtk_widget_hide (ma->graphs[prop_type]->main_widget); + ma->graphs[prop_type]->visible = FALSE; + properties_set_insensitive(ma); + } + + return; +} + +static void +spin_button_changed_cb(GtkWidget *widget, gpointer name) +{ + MultiloadApplet *ma; + gint value; + gint prop_type, i; + + ma = g_object_get_data(G_OBJECT(widget), "MultiloadApplet"); + prop_type = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "prop_type")); + value = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); + + switch(prop_type) + { + case PROP_SPEED: + g_settings_set_int (ma->settings, (gchar *)name, value); + for (i = 0; i < graph_n; i++) + { + load_graph_stop(ma->graphs[i]); + ma->graphs[i]->speed = value; + if (ma->graphs[i]->visible) + load_graph_start(ma->graphs[i]); + } + + break; + + case PROP_SIZE: + for (i = 0; i < graph_n; i++) + { + g_settings_set_int (ma->settings, (gchar *)name, value); + ma->graphs[i]->size = value ; + + if (ma->graphs[i]->orient) + gtk_widget_set_size_request ( + ma->graphs[i]->main_widget, + ma->graphs[i]->pixel_size, + ma->graphs[i]->size); + else + gtk_widget_set_size_request ( + ma->graphs[i]->main_widget, + ma->graphs[i]->size, + ma->graphs[i]->pixel_size); + } + break; + + case PROP_NET_THRESHOLD1: + g_settings_set_uint (ma->settings, (gchar *)name, value); + if (value >= ma->net_threshold2) + { + gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), + (gdouble)g_settings_get_uint (ma->settings, + "netthreshold2") - 1); + ma->net_threshold1 = g_settings_get_uint (ma->settings, + "netthreshold2") - 1; + } + else + ma->net_threshold1 = value; + break; + + case PROP_NET_THRESHOLD2: + g_settings_set_uint (ma->settings, (gchar *)name, value); + if (value >= ma->net_threshold3) + { + gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), + (gdouble)g_settings_get_uint (ma->settings, + "netthreshold3") - 1); + ma->net_threshold2 = g_settings_get_uint (ma->settings, + "netthreshold3") - 1; + } + else if (value <= ma->net_threshold1) + { + gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), + (gdouble)g_settings_get_uint (ma->settings, + "netthreshold1") + 1); + ma->net_threshold2 = g_settings_get_uint (ma->settings, + "netthreshold1") + 1; + } + else + ma->net_threshold2 = value; + break; + + case PROP_NET_THRESHOLD3: + g_settings_set_uint (ma->settings, (gchar *)name, value); + if (value <= ma->net_threshold2) + { + gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), + (gdouble)g_settings_get_uint (ma->settings, + "netthreshold2") + 1); + ma->net_threshold3 = g_settings_get_uint (ma->settings, + "netthreshold2") + 1; + } + else + ma->net_threshold3 = value; + break; + default: + g_assert_not_reached(); + } + + return; +} + +/* create a new page in the notebook widget, add it, and return a pointer to it */ +static GtkWidget * +add_page(GtkWidget *notebook, gchar *label) +{ + GtkWidget *page; + GtkWidget *page_label; + + page = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + gtk_box_set_homogeneous (GTK_BOX (page), TRUE); + page_label = gtk_label_new(label); + gtk_container_set_border_width(GTK_CONTAINER(page), 6); + + gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page, page_label); + + return page; +} + +/* save the selected color to gsettings and apply it on the applet */ +static void +color_picker_set_cb(GtkColorChooser *color_picker, gchar *key) +{ + gchar *color_string; + guint8 prop_type; + GdkRGBA color; + MultiloadApplet *ma; + + ma = g_object_get_data (G_OBJECT (color_picker), "MultiloadApplet"); + + if (strstr(key, "cpuload")) + prop_type = PROP_CPU; + else if (strstr(key, "memload")) + prop_type = PROP_MEM; + else if (strstr(key, "netload2")) + prop_type = PROP_NET; + else if (strstr(key, "swapload")) + prop_type = PROP_SWAP; + else if (strstr(key, "loadavg")) + prop_type = PROP_AVG; + else if (strstr(key, "diskload")) + prop_type = PROP_DISK; + else + g_assert_not_reached(); + + gtk_color_chooser_get_rgba(color_picker, &color); + + color_string = gdk_rgba_to_string (&color); + g_settings_set_string(ma->settings, key, color_string); + + gdk_rgba_parse(&(ma->graphs[prop_type]->colors[g_ascii_digit_value(key[strlen(key) - 1]) ]), + color_string); + + return; +} + +/* create a color selector */ +static void +add_color_selector(GtkWidget *page, gchar *name, gchar *key, MultiloadApplet *ma) +{ + GtkWidget *vbox; + GtkWidget *label; + GtkWidget *color_picker; + GdkRGBA color; + gchar *color_string; + + color_string = g_settings_get_string (ma->settings, key); + if (!color_string) + color_string = g_strdup ("#000000"); + gdk_rgba_parse (&color, color_string); + g_free (color_string); + + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); + label = gtk_label_new_with_mnemonic(name); + color_picker = gtk_color_button_new(); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), color_picker); + + gtk_box_pack_start(GTK_BOX(vbox), color_picker, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); + + gtk_box_pack_start(GTK_BOX(page), vbox, FALSE, FALSE, 0); + + g_object_set_data (G_OBJECT (color_picker), "MultiloadApplet", ma); + + gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(color_picker), &color); + + g_signal_connect(G_OBJECT(color_picker), "color_set", G_CALLBACK(color_picker_set_cb), key); + + if ( ! g_settings_is_writable (ma->settings, key)) + hard_set_sensitive (vbox, FALSE); + + return; +} + +/* save the checkbox option to gsettings and apply it on the applet */ +static void +nvme_checkbox_toggled_cb (GtkCheckButton *checkbox, + MultiloadApplet *ma) +{ + gboolean option; + + option = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbox)); + ma->nvme_diskstats = option; + g_settings_set_boolean (ma->settings, "diskload-nvme-diskstats", option); + + return; +} + +/* creates the properties dialog using up-to-the-minute info from gsettings */ +static void +fill_properties(GtkWidget *dialog, MultiloadApplet *ma) +{ + GtkWidget *page; + GtkWidget *hbox, *vbox; + GtkWidget *categories_vbox; + GtkWidget *category_vbox; + GtkWidget *control_vbox; + GtkWidget *control_hbox; + GtkWidget *check_box; + GtkWidget *indent; + GtkWidget *spin_button; + GtkWidget *label; + MatePanelAppletOrient orient; + GtkSizeGroup *label_size; + GtkSizeGroup *spin_size; + gchar *label_text; + gchar *title; + + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 5); + gtk_widget_show (vbox); + + gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), + vbox, TRUE, TRUE, 0); + + categories_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 18); + gtk_box_pack_start (GTK_BOX (vbox), categories_vbox, TRUE, TRUE, 0); + gtk_widget_show (categories_vbox); + + category_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); + gtk_box_pack_start (GTK_BOX (categories_vbox), category_vbox, TRUE, TRUE, 0); + gtk_widget_show (category_vbox); + + title = g_strconcat ("", _("Monitored Resources"), "", NULL); + label = gtk_label_new_with_mnemonic (_(title)); + gtk_label_set_use_markup (GTK_LABEL (label), TRUE); + gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT); + gtk_label_set_xalign (GTK_LABEL (label), 0.0); + gtk_box_pack_start (GTK_BOX (category_vbox), label, FALSE, FALSE, 0); + g_free (title); + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + gtk_box_pack_start (GTK_BOX (category_vbox), hbox, TRUE, TRUE, 0); + gtk_widget_show (hbox); + + indent = gtk_label_new (HIG_IDENTATION); + gtk_label_set_justify (GTK_LABEL (indent), GTK_JUSTIFY_LEFT); + gtk_box_pack_start (GTK_BOX (hbox), indent, FALSE, FALSE, 0); + gtk_widget_show (indent); + + control_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); + gtk_box_pack_start (GTK_BOX (hbox), control_vbox, TRUE, TRUE, 0); + gtk_widget_show (control_vbox); + + control_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); + gtk_box_pack_start (GTK_BOX (control_vbox), control_hbox, TRUE, TRUE, 0); + gtk_widget_show (control_hbox); + + check_box = gtk_check_button_new_with_mnemonic(_("_Processor")); + ma->check_boxes[0] = check_box; + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_box), + g_settings_get_boolean (ma->settings, + VIEW_CPULOAD_KEY)); + g_object_set_data(G_OBJECT(check_box), "MultiloadApplet", ma); + g_object_set_data(G_OBJECT(check_box), "prop_type", GINT_TO_POINTER(PROP_CPU)); + g_signal_connect(G_OBJECT(check_box), "toggled", + G_CALLBACK(property_toggled_cb), VIEW_CPULOAD_KEY); + gtk_box_pack_start (GTK_BOX (control_hbox), check_box, FALSE, FALSE, 0); + + if ( ! g_settings_is_writable (ma->settings, VIEW_CPULOAD_KEY)) + hard_set_sensitive (check_box, FALSE); + + check_box = gtk_check_button_new_with_mnemonic(_("_Memory")); + ma->check_boxes[1] = check_box; + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_box), + g_settings_get_boolean (ma->settings, VIEW_MEMLOAD_KEY)); + g_object_set_data(G_OBJECT(check_box), "MultiloadApplet", ma); + g_object_set_data(G_OBJECT(check_box), "prop_type", GINT_TO_POINTER(PROP_MEM)); + g_signal_connect(G_OBJECT(check_box), "toggled", + G_CALLBACK(property_toggled_cb), VIEW_MEMLOAD_KEY); + gtk_box_pack_start (GTK_BOX (control_hbox), check_box, FALSE, FALSE, 0); + + if ( ! g_settings_is_writable (ma->settings, VIEW_MEMLOAD_KEY)) + hard_set_sensitive (check_box, FALSE); + + check_box = gtk_check_button_new_with_mnemonic(_("_Network")); + ma->check_boxes[2] = check_box; + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_box), + g_settings_get_boolean (ma->settings, VIEW_NETLOAD_KEY)); + g_object_set_data(G_OBJECT(check_box), "MultiloadApplet", ma); + g_object_set_data(G_OBJECT(check_box), "prop_type", GINT_TO_POINTER(PROP_NET)); + g_signal_connect(G_OBJECT(check_box), "toggled", + G_CALLBACK(property_toggled_cb), VIEW_NETLOAD_KEY); + gtk_box_pack_start (GTK_BOX (control_hbox), check_box, FALSE, FALSE, 0); + + if ( ! g_settings_is_writable (ma->settings, VIEW_NETLOAD_KEY)) + hard_set_sensitive (check_box, FALSE); + + check_box = gtk_check_button_new_with_mnemonic (_("S_wap Space")); + ma->check_boxes[3] = check_box; + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_box), + g_settings_get_boolean (ma->settings, VIEW_SWAPLOAD_KEY)); + g_object_set_data(G_OBJECT(check_box), "MultiloadApplet", ma); + g_object_set_data(G_OBJECT(check_box), "prop_type", GINT_TO_POINTER(PROP_SWAP)); + g_signal_connect(G_OBJECT(check_box), "toggled", + G_CALLBACK(property_toggled_cb), VIEW_SWAPLOAD_KEY); + gtk_box_pack_start (GTK_BOX (control_hbox), check_box, FALSE, FALSE, 0); + + if ( ! g_settings_is_writable (ma->settings, VIEW_SWAPLOAD_KEY)) + hard_set_sensitive (check_box, FALSE); + + check_box = gtk_check_button_new_with_mnemonic(_("_Load")); + ma->check_boxes[4] = check_box; + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_box), + g_settings_get_boolean (ma->settings, VIEW_LOADAVG_KEY)); + g_object_set_data(G_OBJECT(check_box), "MultiloadApplet", ma); + g_object_set_data(G_OBJECT(check_box), "prop_type", GINT_TO_POINTER(PROP_AVG)); + g_signal_connect(G_OBJECT(check_box), "toggled", + G_CALLBACK(property_toggled_cb), VIEW_LOADAVG_KEY); + gtk_box_pack_start(GTK_BOX(control_hbox), check_box, FALSE, FALSE, 0); + + if ( ! g_settings_is_writable (ma->settings, VIEW_LOADAVG_KEY)) + hard_set_sensitive (check_box, FALSE); + + check_box = gtk_check_button_new_with_mnemonic(_("_Harddisk")); + ma->check_boxes[5] = check_box; + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_box), + g_settings_get_boolean (ma->settings, VIEW_DISKLOAD_KEY)); + g_object_set_data (G_OBJECT (check_box), "MultiloadApplet", ma); + g_object_set_data (G_OBJECT (check_box), "prop_type", + GINT_TO_POINTER (PROP_DISK)); + g_signal_connect (G_OBJECT (check_box), "toggled", + G_CALLBACK (property_toggled_cb), VIEW_DISKLOAD_KEY); + gtk_box_pack_start (GTK_BOX (control_hbox), check_box, FALSE, FALSE, 0); + + if ( ! g_settings_is_writable (ma->settings, VIEW_DISKLOAD_KEY)) + hard_set_sensitive (check_box, FALSE); + + category_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); + gtk_box_pack_start (GTK_BOX (categories_vbox), category_vbox, TRUE, TRUE, 0); + gtk_widget_show (category_vbox); + + title = g_strconcat ("", _("Options"), "", NULL); + label = gtk_label_new (title); + gtk_label_set_use_markup (GTK_LABEL (label), TRUE); + gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT); + gtk_label_set_xalign (GTK_LABEL (label), 0.0); + gtk_box_pack_start (GTK_BOX (category_vbox), label, FALSE, FALSE, 0); + gtk_widget_show (label); + g_free (title); + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + gtk_box_pack_start (GTK_BOX (category_vbox), hbox, TRUE, TRUE, 0); + gtk_widget_show (hbox); + + indent = gtk_label_new (HIG_IDENTATION); + gtk_label_set_justify (GTK_LABEL (indent), GTK_JUSTIFY_LEFT); + gtk_box_pack_start (GTK_BOX (hbox), indent, FALSE, FALSE, 0); + gtk_widget_show (indent); + + control_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); + gtk_box_pack_start (GTK_BOX (hbox), control_vbox, TRUE, TRUE, 0); + gtk_widget_show (control_vbox); + + control_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); + gtk_box_pack_start (GTK_BOX (control_vbox), control_hbox, TRUE, TRUE, 0); + gtk_widget_show (control_hbox); + + label_size = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + + orient = mate_panel_applet_get_orient(ma->applet); + if ( (orient == MATE_PANEL_APPLET_ORIENT_UP) || (orient == MATE_PANEL_APPLET_ORIENT_DOWN) ) + label_text = g_strdup(_("System m_onitor width: ")); + else + label_text = g_strdup(_("System m_onitor height: ")); + + label = gtk_label_new_with_mnemonic(label_text); + gtk_label_set_xalign (GTK_LABEL (label), 0.0f); + gtk_size_group_add_widget (label_size, label); + gtk_box_pack_start (GTK_BOX (control_hbox), label, FALSE, FALSE, 0); + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); + gtk_box_pack_start (GTK_BOX (control_hbox), hbox, TRUE, TRUE, 0); + gtk_widget_show (hbox); + + spin_size = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + + spin_button = gtk_spin_button_new_with_range(10, 1000, 5); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), spin_button); + g_object_set_data(G_OBJECT(spin_button), "MultiloadApplet", ma); + g_object_set_data(G_OBJECT(spin_button), "prop_type", + GINT_TO_POINTER(PROP_SIZE)); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin_button), + (gdouble)g_settings_get_int(ma->settings, "size")); + g_signal_connect(G_OBJECT(spin_button), "value_changed", + G_CALLBACK(spin_button_changed_cb), "size"); + + if ( ! g_settings_is_writable (ma->settings, "size")) { + hard_set_sensitive (label, FALSE); + hard_set_sensitive (hbox, FALSE); + } + + gtk_size_group_add_widget (spin_size, spin_button); + gtk_box_pack_start (GTK_BOX (hbox), spin_button, FALSE, FALSE, 0); + + label = gtk_label_new (_("pixels")); + gtk_label_set_xalign (GTK_LABEL (label), 0.0f); + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); + + control_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); + gtk_box_pack_start (GTK_BOX (control_vbox), control_hbox, TRUE, TRUE, 0); + gtk_widget_show (control_hbox); + + label = gtk_label_new_with_mnemonic(_("Sys_tem monitor update interval: ")); + gtk_label_set_xalign (GTK_LABEL (label), 0.0f); + gtk_size_group_add_widget (label_size, label); + gtk_box_pack_start (GTK_BOX (control_hbox), label, FALSE, FALSE, 0); + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); + gtk_box_pack_start (GTK_BOX (control_hbox), hbox, TRUE, TRUE, 0); + gtk_widget_show (hbox); + + spin_button = gtk_spin_button_new_with_range(50, 10000, 50); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), spin_button); + g_object_set_data(G_OBJECT(spin_button), "MultiloadApplet", ma); + g_object_set_data(G_OBJECT(spin_button), "prop_type", + GINT_TO_POINTER(PROP_SPEED)); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin_button), + (gdouble)g_settings_get_int (ma->settings, "speed")); + g_signal_connect(G_OBJECT(spin_button), "value_changed", + G_CALLBACK(spin_button_changed_cb), "speed"); + gtk_size_group_add_widget (spin_size, spin_button); + gtk_box_pack_start (GTK_BOX (hbox), spin_button, FALSE, FALSE, 0); + + if ( ! g_settings_is_writable (ma->settings, "speed")) { + hard_set_sensitive (label, FALSE); + hard_set_sensitive (hbox, FALSE); + } + + label = gtk_label_new(_("milliseconds")); + gtk_label_set_xalign (GTK_LABEL (label), 0.0f); + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); + + g_free(label_text); + + + category_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); + gtk_box_pack_start (GTK_BOX (categories_vbox), category_vbox, TRUE, TRUE, 0); + gtk_widget_show (category_vbox); + + title = g_strconcat ("", _("Colors"), "", NULL); + label = gtk_label_new (title); + gtk_label_set_use_markup (GTK_LABEL (label), TRUE); + gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT); + gtk_label_set_xalign (GTK_LABEL (label), 0.0); + gtk_box_pack_start (GTK_BOX (category_vbox), label, FALSE, FALSE, 0); + gtk_widget_show (label); + g_free (title); + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + gtk_box_pack_start (GTK_BOX (category_vbox), hbox, TRUE, TRUE, 0); + gtk_widget_show (hbox); + + indent = gtk_label_new (HIG_IDENTATION); + gtk_label_set_justify (GTK_LABEL (indent), GTK_JUSTIFY_LEFT); + gtk_box_pack_start (GTK_BOX (hbox), indent, FALSE, FALSE, 0); + gtk_widget_show (indent); + + control_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); + gtk_box_pack_start (GTK_BOX (hbox), control_vbox, TRUE, TRUE, 0); + gtk_widget_show (control_vbox); + + ma->notebook = gtk_notebook_new(); + gtk_container_add (GTK_CONTAINER (control_vbox), ma->notebook); + + page = add_page(ma->notebook, _("Processor")); + gtk_container_set_border_width (GTK_CONTAINER (page), 12); + add_color_selector(page, _("_User"), "cpuload-color0", ma); + add_color_selector(page, _("S_ystem"), "cpuload-color1", ma); + add_color_selector(page, _("N_ice"), "cpuload-color2", ma); + add_color_selector(page, _("I_OWait"), "cpuload-color3", ma); + add_color_selector(page, _("I_dle"), "cpuload-color4", ma); + + page = add_page(ma->notebook, _("Memory")); + gtk_container_set_border_width (GTK_CONTAINER (page), 12); + add_color_selector(page, _("_User"), "memload-color0", ma); + add_color_selector(page, _("Sh_ared"), "memload-color1", ma); + add_color_selector(page, _("_Buffers"), "memload-color2", ma); + add_color_selector (page, _("Cach_ed"), "memload-color3", ma); + add_color_selector(page, _("F_ree"), "memload-color4", ma); + + page = add_page(ma->notebook, _("Network")); + gtk_container_set_border_width (GTK_CONTAINER (page), 12); + add_color_selector (page, _("_In"), "netload2-color0", ma); + add_color_selector(page, _("_Out"), "netload2-color1", ma); + add_color_selector (page, _("_Local"), "netload2-color2", ma); + add_color_selector(page, _("_Background"), "netload2-color3", ma); + add_color_selector(page, _("_Gridline"), "netload2-color4", ma); + add_color_selector(page, _("_Indicator"), "netload2-color5", ma); + + page = add_page(ma->notebook, _("Swap Space")); + gtk_container_set_border_width (GTK_CONTAINER (page), 12); + add_color_selector(page, _("_Used"), "swapload-color0", ma); + add_color_selector(page, _("_Free"), "swapload-color1", ma); + + page = add_page(ma->notebook, _("Load")); + gtk_container_set_border_width (GTK_CONTAINER (page), 12); + add_color_selector(page, _("_Average"), "loadavg-color0", ma); + add_color_selector(page, _("_Background"), "loadavg-color1", ma); + add_color_selector(page, _("_Gridline"), "loadavg-color2", ma); + + page = add_page (ma->notebook, _("Harddisk")); + gtk_container_set_border_width (GTK_CONTAINER (page), 12); + add_color_selector (page, _("_Read"), "diskload-color0", ma); + add_color_selector (page, _("_Write"), "diskload-color1", ma); + add_color_selector (page, _("_Background"), "diskload-color2", ma); + GtkWidget *nvme_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); + GtkWidget *nvme_checkbox = gtk_check_button_new_with_mnemonic (_("Use diskstats for NVMe")); + ma->nvme_diskstats = g_settings_get_boolean (ma->settings, "diskload-nvme-diskstats"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (nvme_checkbox), + ma->nvme_diskstats); + g_signal_connect (G_OBJECT (nvme_checkbox), "toggled", + G_CALLBACK (nvme_checkbox_toggled_cb), ma); + gtk_box_pack_start (GTK_BOX(nvme_box), nvme_checkbox, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX(page), nvme_box, FALSE, FALSE, 0); + gtk_widget_show (nvme_box); + + title = g_strconcat ("", _("Network speed thresholds"), "", NULL); + label = gtk_label_new (title); + gtk_label_set_use_markup (GTK_LABEL (label), TRUE); + gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT); + gtk_label_set_xalign (GTK_LABEL (label), 0.0); + gtk_box_pack_start (GTK_BOX (category_vbox), label, FALSE, FALSE, 0); + gtk_widget_show (label); + g_free (title); + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + gtk_box_pack_start (GTK_BOX (category_vbox), hbox, TRUE, TRUE, 0); + gtk_widget_show (hbox); + + indent = gtk_label_new (HIG_IDENTATION); + gtk_label_set_justify (GTK_LABEL (indent), GTK_JUSTIFY_LEFT); + gtk_box_pack_start (GTK_BOX (hbox), indent, FALSE, FALSE, 0); + gtk_widget_show (indent); + + control_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); + gtk_box_pack_start (GTK_BOX (hbox), control_vbox, TRUE, TRUE, 0); + gtk_widget_show (control_vbox); + + control_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); + gtk_box_pack_start (GTK_BOX (control_vbox), control_hbox, TRUE, TRUE, 0); + gtk_widget_show (control_hbox); + + label_size = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + + label_text = g_strdup(_("Threshold 1: ")); + label = gtk_label_new_with_mnemonic(label_text); + gtk_label_set_xalign (GTK_LABEL (label), 0.0f); + gtk_size_group_add_widget (label_size, label); + gtk_box_pack_start (GTK_BOX (control_hbox), label, FALSE, FALSE, 0); + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); + gtk_box_pack_start (GTK_BOX (control_hbox), hbox, TRUE, TRUE, 0); + gtk_widget_show (hbox); + + spin_size = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + + spin_button = gtk_spin_button_new_with_range (MIN_NET_THRESHOLD1, MAX_NET_THRESHOLD1, 5); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), spin_button); + g_object_set_data(G_OBJECT(spin_button), "MultiloadApplet", ma); + g_object_set_data(G_OBJECT(spin_button), "prop_type", + GUINT_TO_POINTER(PROP_NET_THRESHOLD1)); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin_button), + (gdouble)g_settings_get_uint(ma->settings, "netthreshold1")); + g_signal_connect(G_OBJECT(spin_button), "value_changed", + G_CALLBACK(spin_button_changed_cb), "netthreshold1"); + + if ( ! g_settings_is_writable (ma->settings, "netthreshold1")) + { + hard_set_sensitive (label, FALSE); + hard_set_sensitive (hbox, FALSE); + } + + gtk_size_group_add_widget (spin_size, spin_button); + gtk_box_pack_start (GTK_BOX (hbox), spin_button, FALSE, FALSE, 0); + + label = gtk_label_new (_("bytes")); + gtk_label_set_xalign (GTK_LABEL (label), 0.0f); + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); + + control_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); + gtk_box_pack_start (GTK_BOX (control_vbox), control_hbox, TRUE, TRUE, 0); + gtk_widget_show (control_hbox); + + label = gtk_label_new_with_mnemonic(_("Threshold 2: ")); + gtk_label_set_xalign (GTK_LABEL (label), 0.0f); + gtk_size_group_add_widget (label_size, label); + gtk_box_pack_start (GTK_BOX (control_hbox), label, FALSE, FALSE, 0); + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); + gtk_box_pack_start (GTK_BOX (control_hbox), hbox, TRUE, TRUE, 0); + gtk_widget_show (hbox); + + spin_button = gtk_spin_button_new_with_range (MIN_NET_THRESHOLD2, MAX_NET_THRESHOLD2, 5); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), spin_button); + g_object_set_data(G_OBJECT(spin_button), "MultiloadApplet", ma); + g_object_set_data(G_OBJECT(spin_button), "prop_type", + GINT_TO_POINTER(PROP_NET_THRESHOLD2)); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin_button), + (gdouble)g_settings_get_uint (ma->settings, "netthreshold2")); + g_signal_connect(G_OBJECT(spin_button), "value_changed", + G_CALLBACK(spin_button_changed_cb), "netthreshold2"); + gtk_size_group_add_widget (spin_size, spin_button); + gtk_box_pack_start (GTK_BOX (hbox), spin_button, FALSE, FALSE, 0); + + if ( ! g_settings_is_writable (ma->settings, "netthreshold2")) + { + hard_set_sensitive (label, FALSE); + hard_set_sensitive (hbox, FALSE); + } + + label = gtk_label_new(_("bytes")); + gtk_label_set_xalign (GTK_LABEL (label), 0.0f); + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); + + control_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); + gtk_box_pack_start (GTK_BOX (control_vbox), control_hbox, TRUE, TRUE, 0); + gtk_widget_show (control_hbox); + + label = gtk_label_new_with_mnemonic(_("Threshold 3: ")); + gtk_label_set_xalign (GTK_LABEL (label), 0.0f); + gtk_size_group_add_widget (label_size, label); + gtk_box_pack_start (GTK_BOX (control_hbox), label, FALSE, FALSE, 0); + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); + gtk_box_pack_start (GTK_BOX (control_hbox), hbox, TRUE, TRUE, 0); + gtk_widget_show (hbox); + + spin_button = gtk_spin_button_new_with_range (MIN_NET_THRESHOLD3, MAX_NET_THRESHOLD3, 5); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), spin_button); + g_object_set_data(G_OBJECT(spin_button), "MultiloadApplet", ma); + g_object_set_data(G_OBJECT(spin_button), "prop_type", + GINT_TO_POINTER(PROP_NET_THRESHOLD3)); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin_button), + (gdouble)g_settings_get_uint (ma->settings, "netthreshold3")); + g_signal_connect(G_OBJECT(spin_button), "value_changed", + G_CALLBACK(spin_button_changed_cb), "netthreshold3"); + gtk_size_group_add_widget (spin_size, spin_button); + gtk_box_pack_start (GTK_BOX (hbox), spin_button, FALSE, FALSE, 0); + + if ( ! g_settings_is_writable (ma->settings, "netthreshold3")) + { + hard_set_sensitive (label, FALSE); + hard_set_sensitive (hbox, FALSE); + } + + label = gtk_label_new(_("bytes")); + gtk_label_set_xalign (GTK_LABEL (label), 0.0f); + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); + + g_free(label_text); + + category_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); + gtk_box_pack_start (GTK_BOX (categories_vbox), category_vbox, TRUE, TRUE, 0); + + control_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); + gtk_box_pack_start (GTK_BOX (control_vbox), control_hbox, TRUE, TRUE, 0); + gtk_widget_show (control_hbox); + + gtk_widget_show (category_vbox); + + return; +} + +/* show properties dialog */ +void +multiload_properties_cb (GtkAction *action, + MultiloadApplet *ma) +{ + GtkWidget *dialog = NULL; + + if (ma->prop_dialog) { + dialog = ma->prop_dialog; + + gtk_window_set_screen (GTK_WINDOW (dialog), + gtk_widget_get_screen (GTK_WIDGET (ma->applet))); + + gtk_notebook_set_current_page (GTK_NOTEBOOK (ma->notebook), + ma->last_clicked); + gtk_window_present (GTK_WINDOW (dialog)); + return; + } + + dialog = gtk_dialog_new_with_buttons (_("System Monitor Preferences"), + NULL, 0, + "gtk-help", GTK_RESPONSE_HELP, + "gtk-close", GTK_RESPONSE_CLOSE, + NULL); + gtk_window_set_screen (GTK_WINDOW (dialog), + gtk_widget_get_screen (GTK_WIDGET (ma->applet))); + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE); + gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); + gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); + gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), 2); + + fill_properties(dialog, ma); + + properties_set_insensitive(ma); + + g_signal_connect(G_OBJECT(dialog), "response", + G_CALLBACK(properties_close_cb), ma); + + ma->prop_dialog = dialog; + + gtk_widget_show_all(dialog); + + gtk_notebook_set_current_page (GTK_NOTEBOOK (ma->notebook), + ma->last_clicked); +} diff --git a/po/POTFILES.in b/po/POTFILES.in index 3f85ec69..aa7d1bc8 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -42,13 +42,13 @@ mateweather/mateweather-pref.c mateweather/main.c mateweather/org.mate.applets.MateWeatherApplet.mate-panel-applet.desktop.in.in # NB. these are actually separate files -multiload/linux-proc.c -multiload/load-graph.c -multiload/main.c -multiload/netspeed.c -multiload/org.mate.applets.MultiLoadApplet.mate-panel-applet.desktop.in.in -multiload/org.mate.panel.applet.multiload.gschema.xml.in -multiload/properties.c +multiload/data/org.mate.applets.MultiLoadApplet.mate-panel-applet.desktop.in.in +multiload/data/org.mate.panel.applet.multiload.gschema.xml.in +multiload/src/linux-proc.c +multiload/src/load-graph.c +multiload/src/main.c +multiload/src/netspeed.c +multiload/src/properties.c netspeed/data/netspeed-details.ui netspeed/data/netspeed-preferences.ui netspeed/data/org.mate.panel.applet.netspeed.gschema.xml.in -- cgit v1.2.1