upstream 1.3.2 + debian 1.3.2-2ubuntu3

Release tarball xfce4-systemload-plugin_1.3.2.orig.tar.bz2 with the Ubuntu
packaging (debian/ from 1.3.2-2ubuntu3) and its patch
01_Fix-build-failure-due-to-wrong-var-type applied. Files regenerated by
autoreconf on every build are not tracked (see .gitignore).
This commit is contained in:
4aiman 2026-11-03 22:23:45 +03:00
commit 56dd2917ba
111 changed files with 29376 additions and 0 deletions

61
panel-plugin/Makefile.am Normal file
View file

@ -0,0 +1,61 @@
plugindir = $(libdir)/xfce4/panel/plugins
plugin_LTLIBRARIES = libsystemload.la
AM_CPPFLAGS = \
-I$(top_srcdir) \
-DG_LOG_DOMAIN=\"xfce4-systemload-plugin\" \
-DPACKAGE_LOCALE_DIR=\"$(localedir)\" \
$(PLATFORM_CPPFLAGS)
libsystemload_la_CFLAGS = \
$(LIBXFCE4UI_CFLAGS) \
$(XFCONF_CFLAGS) \
$(LIBGTOP_CFLAGS) \
$(LIBXFCE4PANEL_CFLAGS) \
$(UPOWER_GLIB_CFLAGS) \
$(PLATFORM_CFLAGS)
libsystemload_la_CXXFLAGS = $(libsystemload_la_CFLAGS)
libsystemload_la_LIBADD = \
$(top_builddir)/xfce4++/util/libxfce4util_pp.la \
$(LIBXFCE4UI_LIBS) \
$(LIBXFCE4PANEL_LIBS) \
$(XFCONF_LIBS) \
$(LIBGTOP_LIBS) \
$(UPOWER_GLIB_LIBS) \
-lm
libsystemload_la_SOURCES = \
cpu.cc \
cpu.h \
memswap.cc \
memswap.h \
network.cc \
network.h \
plugin.h \
plugin.c \
settings.cc \
settings.h \
systemload.cc \
uptime.cc \
uptime.h
libsystemload_la_LDFLAGS = \
-avoid-version \
-module \
-no-undefined \
-export-symbols-regex '^xfce_panel_module_(preinit|init|construct)' \
$(PLATFORM_LDFLAGS)
#
# Desktop file
#
desktopdir = $(datadir)/xfce4/panel/plugins
desktop_DATA = systemload.desktop
@INTLTOOL_DESKTOP_RULE@
EXTRA_DIST = systemload.desktop.in
CLEANFILES = $(desktop_DATA)

299
panel-plugin/cpu.cc Normal file
View file

@ -0,0 +1,299 @@
/*
* This file is part of Xfce (https://gitlab.xfce.org).
*
* Copyright (c) 2003 Riccardo Persichetti <riccardo.persichetti@tin.it>
* Copyright (c) 2010 Florian Rivoal <frivoal@xfce.org>
* Copyright (c) 2022 Jan Ziak <0xe2.0x9a.0x9b@xfce.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <fcntl.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "cpu.h"
#if defined(__linux__) || defined(__FreeBSD_kernel__)
#include <glib/gi18n.h>
#include <stdint.h>
#define PROC_STAT "/proc/stat"
/* user, nice, system, interrupt(BSD specific), idle */
struct cpu_load_struct {
gulong load[5];
};
static gulong oldtotal, oldused;
gulong read_cpuload()
{
FILE *fd = fopen(PROC_STAT, "r");
if (!fd) {
g_warning("%s", _("File /proc/stat not found!"));
return 0;
}
/* Don't count steal time. It is neither busy nor free tiime. */
unsigned long long int user, unice, usystem, idle, iowait, irq, softirq, guest;
int nb_read = fscanf (fd, "%*s %llu %llu %llu %llu %llu %llu %llu %*u %llu",
&user, &unice, &usystem, &idle, &iowait, &irq, &softirq, &guest);
fclose(fd);
if (nb_read <= 4) iowait = 0;
if (nb_read <= 5) irq = 0;
if (nb_read <= 6) softirq = 0;
if (nb_read <= 7) guest = 0;
gulong used = user + unice + usystem + irq + softirq + guest;
gulong total = used + idle + iowait;
gulong cpu_used;
if ((total - oldtotal) != 0)
{
cpu_used = (100 * (double)(used - oldused)) / (double)(total - oldtotal);
}
else
{
cpu_used = 0;
}
oldused = used;
oldtotal = total;
return cpu_used;
}
#elif defined(__FreeBSD__) || defined(__DragonFly__)
#include <osreldate.h>
#include <sys/types.h>
#include <sys/resource.h>
#include <sys/sysctl.h>
#include <devstat.h>
#include <fcntl.h>
#include <nlist.h>
/* user, nice, system, interrupt(BSD specific), idle */
struct cpu_load_struct {
gulong load[5];
};
static gulong oldtotal, oldused;
gulong read_cpuload()
{
gulong cpu_used, used, total;
long cp_time[CPUSTATES];
size_t len = sizeof(cp_time);
if (sysctlbyname("kern.cp_time", &cp_time, &len, NULL, 0) < 0) {
g_warning("Cannot get kern.cp_time");
return 0;
}
used = cp_time[CP_USER] + cp_time[CP_NICE] + cp_time[CP_SYS] + cp_time[CP_INTR];
total = used + cp_time[CP_IDLE];
if ((total - oldtotal) != 0)
{
cpu_used = (100 * (double)(used - oldused)) / (double)(total - oldtotal);
}
else
{
cpu_used = 0;
}
oldused = used;
oldtotal = total;
return cpu_used;
}
#elif defined(__NetBSD__)
/*
* NetBSD defines MAX and MIN in sys/param.h, so undef the glib macros first
*/
#ifdef MAX
#undef MAX
#endif
#ifdef MIN
#undef MIN
#endif
#include <sys/param.h>
#include <sys/sched.h>
#include <sys/sysctl.h>
#include <fcntl.h>
#include <nlist.h>
/* user, nice, system, interrupt(BSD specific), idle */
struct cpu_load_struct {
gulong load[5];
};
static gulong oldtotal, oldused;
gulong read_cpuload()
{
gulong cpu_used, used, total;
static int mib[] = { CTL_KERN, KERN_CP_TIME };
u_int64_t cp_time[CPUSTATES];
size_t len = sizeof(cp_time);
if (sysctl(mib, 2, &cp_time, &len, NULL, 0) < 0) {
g_warning("Cannot get kern.cp_time");
return 0;
}
used = cp_time[CP_USER] + cp_time[CP_NICE] + cp_time[CP_SYS] + cp_time[CP_INTR];
total = used + cp_time[CP_IDLE];
if ((total - oldtotal) != 0)
{
cpu_used = (100 * (double)(used - oldused)) / (double)(total - oldtotal);
}
else
{
cpu_used = 0;
}
oldused = used;
oldtotal = total;
return cpu_used;
}
#elif defined(__OpenBSD__)
/*
* NetBSD defines MAX and MIN in sys/param.h, so undef the glib macros first
*/
#ifdef MAX
#undef MAX
#endif
#ifdef MIN
#undef MIN
#endif
#include <sys/param.h>
#include <sys/sched.h>
#include <sys/sysctl.h>
#include <fcntl.h>
#include <nlist.h>
/* user, nice, system, interrupt(BSD specific), idle */
struct cpu_load_struct {
gulong load[5];
};
static gulong oldtotal, oldused;
gulong read_cpuload()
{
gulong cpu_used, used, total;
static int mib[] = { CTL_KERN, KERN_CPTIME };
long cp_time[CPUSTATES];
size_t len = sizeof(cp_time);
if (sysctl(mib, 2, &cp_time, &len, NULL, 0) < 0) {
g_warning("Cannot get kern.cp_time");
return 0;
}
used = cp_time[CP_USER] + cp_time[CP_NICE] + cp_time[CP_SYS] + cp_time[CP_INTR];
total = used + cp_time[CP_IDLE];
if ((total - oldtotal) != 0)
{
cpu_used = (100 * (double)(used - oldused)) / (double)(total - oldtotal);
}
else
{
cpu_used = 0;
}
oldused = used;
oldtotal = total;
return cpu_used;
}
#elif defined(__sun__)
#include <kstat.h>
static kstat_ctl_t *kc;
static gulong oldtotal, oldused;
void init_stats()
{
kc = kstat_open();
}
gulong read_cpuload()
{
gulong cpu_used, used, total;
kstat_t *ksp;
kstat_named_t *knp;
if (!kc)
{
init_stats();
}
kstat_chain_update(kc);
used = 0;
total = 0;
for (ksp = kc->kc_chain; ksp != NULL; ksp = ksp->ks_next)
{
if (!strcmp(ksp->ks_module, "cpu") && !strcmp(ksp->ks_name, "sys"))
{
kstat_read(kc, ksp, NULL);
knp = kstat_data_lookup(ksp, "cpu_ticks_user");
used += knp->value.ui64;
total += knp->value.ui64;
knp = kstat_data_lookup(ksp, "cpu_ticks_kernel");
used += knp->value.ui64;
total += knp->value.ui64;
knp = kstat_data_lookup(ksp, "cpu_ticks_idle");
total += knp->value.ui64;
}
}
printf("CPU: %lu %lu %lu %lu\n", used, oldused, total, oldtotal);
if ((total - oldtotal) != 0)
{
cpu_used = (100 * (double)(used - oldused)) / (double)(total - oldtotal);
}
else
{
cpu_used = 0;
}
oldused = used;
oldtotal = total;
return cpu_used;
}
#else
#error "Your platform is not yet supported"
#endif

36
panel-plugin/cpu.h Normal file
View file

@ -0,0 +1,36 @@
/*
* This file is part of Xfce (https://gitlab.xfce.org).
*
* Copyright (c) 2003 Riccardo Persichetti <riccardo.persichetti@tin.it>
* Copyright (c) 2010 Florian Rivoal <frivoal@xfce.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _XFCE_SYSTEMLOAD_CPU_H_
#define _XFCE_SYSTEMLOAD_CPU_H_
#include <glib.h>
gulong read_cpuload();
#endif /* _XFCE_SYSTEMLOAD_CPU_H_ */

533
panel-plugin/memswap.cc Normal file
View file

@ -0,0 +1,533 @@
/*
* This file is part of Xfce (https://gitlab.xfce.org).
*
* Copyright (c) 2003 Riccardo Persichetti <riccardo.persichetti@tin.it>
* Copyright (c) 2010 Florian Rivoal <frivoal@xfce.org>
* Copyright (c) 2022 Jan Ziak <0xe2.0x9a.0x9b@xfce.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <glib.h>
#include "memswap.h"
#if defined(__linux__) || defined(__FreeBSD_kernel__)
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MEMINFOBUFSIZE (2 * 1024)
static char MemInfoBuf[MEMINFOBUFSIZE];
static unsigned long MTotal = 0;
static unsigned long MFree = 0;
static unsigned long MBuffers = 0;
static unsigned long MCached = 0;
static unsigned long MAvail = 0;
static unsigned long MUsed = 0;
static unsigned long STotal = 0;
static unsigned long SFree = 0;
static unsigned long SUsed = 0;
gint read_memswap(gulong *mem, gulong *swap, gulong *MT, gulong *MU, gulong *ST, gulong *SU)
{
char *b_MTotal, *b_MFree, *b_MBuffers, *b_MCached, *b_MAvail, *b_STotal, *b_SFree;
const char *filepath = "/proc/meminfo";
int fd;
if ((fd = open(filepath, O_RDONLY)) < 0)
{
g_warning ("Cannot open '%s'", filepath);
return -1;
}
ssize_t n = read(fd, MemInfoBuf, MEMINFOBUFSIZE - 1);
close(fd);
if (n < 0)
{
g_warning ("Cannot read '%s'", filepath);
return -1;
}
if (n == MEMINFOBUFSIZE - 1)
{
g_warning ("Internal buffer too small to read '%s'", filepath);
return -1;
}
MemInfoBuf[n] = '\0';
b_MTotal = strstr(MemInfoBuf, "MemTotal");
if (!b_MTotal || !sscanf(b_MTotal + strlen("MemTotal"), ": %lu", &MTotal))
return -1;
b_MFree = strstr(MemInfoBuf, "MemFree");
if (!b_MFree || !sscanf(b_MFree + strlen("MemFree"), ": %lu", &MFree))
return -1;
b_MBuffers = strstr(MemInfoBuf, "Buffers");
if (!b_MBuffers || !sscanf(b_MBuffers + strlen("Buffers"), ": %lu", &MBuffers))
return -1;
b_MCached = strstr(MemInfoBuf, "Cached");
if (!b_MCached || !sscanf(b_MCached + strlen("Cached"), ": %lu", &MCached))
return -1;
/* In Linux 3.14+, use MemAvailable instead */
b_MAvail = strstr(MemInfoBuf, "MemAvailable");
if (b_MAvail && sscanf(b_MAvail + strlen("MemAvailable"), ": %lu", &MAvail))
{
MFree = MAvail;
MBuffers = 0;
MCached = 0;
}
b_STotal = strstr(MemInfoBuf, "SwapTotal");
if (!b_STotal || !sscanf(b_STotal + strlen("SwapTotal"), ": %lu", &STotal))
return -1;
b_SFree = strstr(MemInfoBuf, "SwapFree");
if (!b_SFree || !sscanf(b_SFree + strlen("SwapFree"), ": %lu", &SFree))
return -1;
MFree += MCached + MBuffers;
MUsed = MTotal - MFree;
SUsed = STotal - SFree;
*mem = MUsed * 100 / MTotal;
if(STotal)
*swap = SUsed * 100 / STotal;
else
*swap = 0;
*MT = MTotal;
*MU = MUsed;
*ST = STotal;
*SU = SUsed;
return 0;
}
#elif defined(__FreeBSD__) || defined(__DragonFly__)
/*
* This is inspired by /usr/src/usr.bin/top/machine.c
*
* Adapted by Thorsten Greiner <thorsten.greiner@web.de>
*
* Original authors: Christos Zoulas <christos@ee.cornell.edu>
* Steven Wallace <swallace@freebsd.org>
* Wolfram Schneider <wosch@FreeBSD.org>
* Thomas Moestl <tmoestl@gmx.net>
*/
/*
* FreeBSD defines MAX and MIN in sys/param.h, so undef the glib macros first
*/
#ifdef MAX
#undef MAX
#endif
#ifdef MIN
#undef MIN
#endif
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/sysctl.h>
#include <vm/vm_param.h>
#include <sys/vmmeter.h>
#include <unistd.h>
#include <kvm.h>
#define GETSYSCTL(name, var) getsysctl(name, &(var), sizeof(var))
static int getsysctl (char *name, void *ptr, size_t len)
{
size_t nlen = len;
if (sysctlbyname(name, ptr, &nlen, NULL, 0) == -1) {
return -1;
}
if (nlen != len) {
return -1;
}
return 0;
}
static kvm_t *kd = NULL;
static int swapmode(int *retavail, int *retfree)
{
int n;
int pagesize = getpagesize();
struct kvm_swap swapary[1];
static int kd_init = TRUE;
if(kd_init) {
kd_init = FALSE;
if ((kd = kvm_open("/dev/null", "/dev/null", "/dev/null",
O_RDONLY, "kvm_open")) == NULL) {
g_warning("Cannot read kvm.");
return -1;
}
}
if(kd == NULL) {
return -1;
}
*retavail = 0;
*retfree = 0;
#define CONVERT(v) ((quad_t)(v) * pagesize / 1024)
n = kvm_getswapinfo(kd, swapary, 1, 0);
if (n < 0 || swapary[0].ksw_total == 0)
return(0);
*retavail = CONVERT(swapary[0].ksw_total);
*retfree = CONVERT(swapary[0].ksw_total - swapary[0].ksw_used);
n = (int)((double)swapary[0].ksw_used * 100.0 /
(double)swapary[0].ksw_total);
return(n);
}
gint read_memswap(gulong *mem, gulong *swap, gulong *MT, gulong *MU, gulong *ST, gulong *SU)
{
int total_pages;
int free_pages;
int inactive_pages;
int pagesize = getpagesize();
int swap_avail;
int swap_free;
if(GETSYSCTL("vm.stats.vm.v_page_count", total_pages)) {
g_warning("Cannot read sysctl \"vm.stats.vm.v_page_count\"");
return -1;
}
if(GETSYSCTL("vm.stats.vm.v_free_count", free_pages)) {
g_warning("Cannot read sysctl \"vm.stats.vm.v_free_count\"");
return -1;
}
if(GETSYSCTL("vm.stats.vm.v_inactive_count", inactive_pages)) {
g_warning("Cannot read sysctl \"vm.stats.vm.v_inactive_count\"");
return -1;
}
*MT = CONVERT(total_pages);
*MU = CONVERT(total_pages-free_pages-inactive_pages);
*mem = *MU * 100 / *MT;
if((*swap = swapmode(&swap_avail, &swap_free)) >= 0) {
*ST = swap_avail;
*SU = (swap_avail - swap_free);
}
else {
*swap = 0;
*ST = 0;
*SU = 0;
}
return 0;
}
#elif defined(__NetBSD__)
/*
* NetBSD defines MAX and MIN in sys/param.h, so undef the glib macros first
*/
#ifdef MAX
#undef MAX
#endif
#ifdef MIN
#undef MIN
#endif
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/types.h>
#include <sys/vmmeter.h>
#include <unistd.h>
/* NetBSD-current post 1.6U uses swapctl */
#if __NetBSD_Version__ > 106210000
#include <sys/swap.h>
#elif __NetBSD_Version__ >= 105010000
/* Everything post 1.5.x uses uvm/uvm_* includes */
#include <uvm/uvm_param.h>
#else
#include <vm/vm_param.h>
#endif
static size_t MTotal = 0;
static size_t MFree = 0;
static size_t MUsed = 0;
static size_t STotal = 0;
static size_t SFree = 0;
static size_t SUsed = 0;
gint read_memswap(gulong *mem, gulong *swap, gulong *MT, gulong *MU, gulong *ST, gulong *SU)
{
int pagesize;
size_t len;
#define ARRLEN(X) (sizeof(X)/sizeof(X[0]))
{
static int mib[] = { CTL_HW, HW_PHYSMEM64 };
int64_t x;
len = sizeof(x);
sysctl(mib, ARRLEN(mib), &x, &len, NULL, 0);
MTotal = x >> 10;
}
{
static int mib[] = {CTL_HW, HW_PAGESIZE};
len = sizeof(pagesize);
sysctl(mib, ARRLEN(mib), &pagesize, &len, NULL, 0);
}
#if __NetBSD_Version__ > 106210000
{
struct swapent* swap;
int nswap, n;
STotal = SUsed = SFree = 0;
if ((nswap = swapctl(SWAP_NSWAP, NULL, 0)) > 0) {
swap = (struct swapent*)malloc(nswap * sizeof(*swap));
if (swapctl(SWAP_STATS, (void*)swap, nswap) == nswap) {
for (n = 0; n < nswap; n++) {
STotal += swap[n].se_nblks;
SUsed += swap[n].se_inuse;
}
STotal = dbtob(STotal >> 10);
SUsed = dbtob(SUsed >> 10);
SFree = STotal - SUsed;
}
free(swap);
}
}
#else
{
struct uvmexp x;
static int mib[] = { CTL_VM, VM_UVMEXP };
len = sizeof(x);
STotal = SUsed = SFree = -1;
pagesize = 1;
if (-1 < sysctl(mib, ARRLEN(mib), &x, &len, NULL, 0)) {
//pagesize = x.pagesize;
STotal = (pagesize*x.swpages) >> 10;
SUsed = (pagesize*x.swpginuse) >> 10;
SFree = STotal - SUsed;
}
}
#endif
{
static int mib[]={ CTL_VM, VM_METER };
struct vmtotal x;
len = sizeof(x);
MFree = MUsed = -1;
if (sysctl(mib, ARRLEN(mib), &x, &len, NULL, 0) > -1) {
MFree = (x.t_free * pagesize) >> 10;
MUsed = (x.t_rm * pagesize) >> 10;
}
}
*mem = MUsed * 100 / MTotal;
if(STotal)
*swap = SUsed * 100 / STotal;
else
*swap = 0;
*MT = MTotal;
*MU = MUsed;
*ST = STotal;
*SU = SUsed;
return 0;
}
#elif defined(__OpenBSD__)
/*
* OpenBSD defines MAX and MIN in sys/param.h, so undef the glib macros first
*/
#ifdef MAX
#undef MAX
#endif
#ifdef MIN
#undef MIN
#endif
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/types.h>
#include <sys/vmmeter.h>
#include <unistd.h>
#include <uvm/uvm_param.h>
static size_t MTotal = 0;
static size_t MFree = 0;
static size_t MUsed = 0;
static size_t STotal = 0;
static size_t SFree = 0;
static size_t SUsed = 0;
gint read_memswap(gulong *mem, gulong *swap, gulong *MT, gulong *MU, gulong *ST, gulong *SU)
{
long pagesize;
size_t len;
#define ARRLEN(X) (sizeof(X)/sizeof(X[0]))
{
static int mib[] = { CTL_HW, HW_PHYSMEM64 };
int64_t x;
len = sizeof(x);
sysctl(mib, ARRLEN(mib), &x, &len, NULL, 0);
MTotal = x >> 10;
}
{
struct uvmexp x;
static int mib[] = { CTL_VM, VM_UVMEXP };
len = sizeof(x);
STotal = SUsed = SFree = -1;
pagesize = 1;
if (-1 < sysctl(mib, ARRLEN(mib), &x, &len, NULL, 0)) {
pagesize = x.pagesize;
STotal = (pagesize*x.swpages) >> 10;
SUsed = (pagesize*x.swpginuse) >> 10;
SFree = STotal - SUsed;
}
}
{
static int mib[]={ CTL_VM, VM_METER };
struct vmtotal x;
len = sizeof(x);
MFree = MUsed = -1;
if (sysctl(mib, ARRLEN(mib), &x, &len, NULL, 0) > -1) {
MFree = (x.t_free * pagesize) >> 10;
MUsed = (x.t_rm * pagesize) >> 10;
}
}
*mem = MUsed * 100 / MTotal;
if(STotal)
*swap = SUsed * 100 / STotal;
else
*swap = 0;
*MT = MTotal;
*MU = MUsed;
*ST = STotal;
*SU = SUsed;
return 0;
}
#elif defined (__sun__)
#include <sys/stat.h>
#include <sys/swap.h>
#include <kstat.h>
kstat_ctl_t *kc;
static size_t MTotal = 0;
static size_t MFree = 0;
static size_t MUsed = 0;
static size_t STotal = 0;
static size_t SFree = 0;
static size_t SUsed = 0;
void mem_init_stats()
{
kc = kstat_open();
}
gint read_memswap(gulong *mem, gulong *swap, gulong *MT, gulong *MU, gulong *ST, gulong *SU)
{
long pagesize;
struct anoninfo swapinfo;
kstat_t *ksp;
kstat_named_t *knp;
pagesize = (long)(sysconf(_SC_PAGESIZE));
/* FIXME use real numbers, not fake data */
if (!kc)
{
mem_init_stats();
}
if (ksp = kstat_lookup(kc, "unix", 0, "system_pages"))
{
kstat_read(kc, ksp, NULL);
knp = kstat_data_lookup(ksp, "physmem");
MTotal = (pagesize * knp->value.ui64) >> 10;
knp = kstat_data_lookup(ksp, "freemem");
MUsed = MTotal - ((pagesize * knp->value.ui64) >> 10);
}
if (swapctl(SC_AINFO, &swapinfo) == 0) {
STotal = (swapinfo.ani_max * pagesize) >> 10;
SUsed = ((swapinfo.ani_max - swapinfo.ani_free) * pagesize) >> 10;
*swap = SUsed * 100 / STotal;
} else {
STotal = 0;
SUsed = 0;
*swap = 0;
}
*mem = MUsed * 100 / MTotal;
*MT = MTotal;
*MU = MUsed;
*ST = STotal;
*SU = SUsed;
return 0;
}
#else
#error "Your platform is not yet supported"
#endif

36
panel-plugin/memswap.h Normal file
View file

@ -0,0 +1,36 @@
/*
* This file is part of Xfce (https://gitlab.xfce.org).
*
* Copyright (c) 2003 Riccardo Persichetti <riccardo.persichetti@tin.it>
* Copyright (c) 2010 Florian Rivoal <frivoal@xfce.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _XFCE_SYSTEMLOAD_MEMSWAP_H_
#define _XFCE_SYSTEMLOAD_MEMSWAP_H_
#include <glib.h>
gint read_memswap(gulong *mem, gulong *swap, gulong *MT, gulong *MU, gulong *ST, gulong *SU);
#endif /* _XFCE_SYSTEMLOAD_MEMSWAP_H_ */

142
panel-plugin/network.cc Normal file
View file

@ -0,0 +1,142 @@
/*
* This file is part of Xfce (https://gitlab.xfce.org).
*
* Copyright (c) 2021-2022 Jan Ziak <0xe2.0x9a.0x9b@xfce.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <string.h>
#include "network.h"
#ifdef HAVE_LIBGTOP
#include <glibtop/netlist.h>
#include <glibtop/netload.h>
static gint
read_netload_libgtop (gulong *bytes)
{
glibtop_netlist netlist;
char **interfaces = glibtop_get_netlist (&netlist);
if (!interfaces)
return -1;
*bytes = 0;
for (char **i = interfaces; *i != NULL; i++)
{
glibtop_netload netload;
glibtop_get_netload (&netload, *i);
*bytes += netload.bytes_total;
}
return 0;
}
#else
static gint
read_netload_libgtop (gulong *bytes)
{
return -1;
}
#endif
static const char *const PROC_NET_NETSTAT = "/proc/net/netstat";
static gint
read_netload_proc (gulong *bytes)
{
char buf[4*1024];
unsigned long long dummy, in_octets, out_octets;
{
FILE *fd = fopen (PROC_NET_NETSTAT, "r");
if (!fd)
return -1;
size_t size = fread (buf, sizeof (*buf), G_N_ELEMENTS (buf) - 1, fd);
if (size == 0)
{
fclose(fd);
return -1;
}
buf[size] = '\0';
if (fclose (fd) != 0)
return -1;
}
const char *s = buf;
/* Skip first 3 lines */
s = strchr(s, '\n'); if (!s) return -1;
s++;
s = strchr(s, '\n'); if (!s) return -1;
s++;
s = strchr(s, '\n'); if (!s) return -1;
s++;
if (sscanf (s, "IpExt: %llu %llu %llu %llu %llu %llu %llu %llu",
&dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
&in_octets, &out_octets) != 8)
return -1;
*bytes = in_octets + out_octets;
return 0;
}
gint
read_netload (gulong *net, gulong *NTotal)
{
static gulong bytes[2];
static gint64 time[2];
*net = 0;
*NTotal = 0;
time[1] = g_get_monotonic_time ();
if (read_netload_proc (&bytes[1]) != 0)
if (read_netload_libgtop (&bytes[1]) != 0)
return -1;
if (time[0] != 0 && G_LIKELY (time[1] > time[0]) && G_LIKELY (bytes[1] >= bytes[0]))
{
guint64 diff_bits = 8 * (bytes[1] - bytes[0]);
gdouble diff_time = (time[1] - time[0]) / 1e6;
*net = MIN (100 * diff_bits / diff_time / MAX_BANDWIDTH_BITS, 100);
*NTotal = diff_bits / diff_time;
}
bytes[0] = bytes[1];
time[0] = time[1];
return 0;
}

38
panel-plugin/network.h Normal file
View file

@ -0,0 +1,38 @@
/*
* This file is part of Xfce (https://gitlab.xfce.org).
*
* Copyright (c) 2021 Jan Ziak <0xe2.0x9a.0x9b@xfce.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _XFCE_SYSTEMLOAD_NETWORK_H_
#define _XFCE_SYSTEMLOAD_NETWORK_H_
#include <glib.h>
/* 100 Mbit/s */
#define MAX_BANDWIDTH_BITS (100*1000*1000)
gint read_netload (gulong *net, gulong *NTotal);
#endif /* _XFCE_SYSTEMLOAD_NETWORK_H_ */

30
panel-plugin/plugin.c Normal file
View file

@ -0,0 +1,30 @@
/*
* This file is part of Xfce (https://gitlab.xfce.org).
*
* Copyright (c) 2022 Jan Ziak <0xe2.0x9a.0x9b@xfce.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "plugin.h"
XFCE_PANEL_PLUGIN_REGISTER (systemload_construct);

39
panel-plugin/plugin.h Normal file
View file

@ -0,0 +1,39 @@
/*
* This file is part of Xfce (https://gitlab.xfce.org).
*
* Copyright (c) 2022 Jan Ziak <0xe2.0x9a.0x9b@xfce.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _XFCE_SYSTEMLOAD_PLUGIN_H_
#define _XFCE_SYSTEMLOAD_PLUGIN_H_
#include <libxfce4panel/libxfce4panel.h>
G_BEGIN_DECLS
void systemload_construct (XfcePanelPlugin *plugin);
G_END_DECLS
#endif /* _XFCE_SYSTEMLOAD_PLUGIN_H_ */

887
panel-plugin/settings.cc Normal file
View file

@ -0,0 +1,887 @@
/*
* This file is part of Xfce (https://gitlab.xfce.org).
*
* Copyright (C) 2021 Simon Steinbeiß <simon@xfce.org>
* Copyright (c) 2022 Jan Ziak <0xe2.0x9a.0x9b@xfce.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/*
* This file implements a configuration store. The class extends GObject.
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#include <libxfce4panel/xfce-panel-plugin.h>
#include <libxfce4util/libxfce4util.h>
#include <libxfce4ui/libxfce4ui.h>
#include <xfconf/xfconf.h>
#include "settings.h"
#define DEFAULT_TIMEOUT 500
#define DEFAULT_TIMEOUT_SECONDS 1
#define DEFAULT_SYSTEM_MONITOR_COMMAND "xfce4-taskmanager"
static const gchar *const DEFAULT_LABEL[] = {
"cpu",
"mem",
"net",
"swap",
};
static const gchar *const DEFAULT_COLOR[] = {
"#1c71d8", /* CPU */
"#2ec27e", /* MEM */
"#e66100", /* NET */
"#f5c211", /* SWAP */
};
static void systemload_config_finalize (GObject *object);
static void systemload_config_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
static void systemload_config_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
struct _SystemloadConfigClass {
GObjectClass __parent__;
};
struct _SystemloadConfig {
GObject __parent__;
XfconfChannel *channel;
gchar *property_base;
guint timeout;
guint timeout_seconds;
gchar *system_monitor_command;
bool uptime;
struct {
bool enabled;
bool use_label;
gchar *label;
GdkRGBA color;
} monitor[4];
};
enum SystemloadProperty {
PROP_0,
PROP_TIMEOUT,
PROP_TIMEOUT_SECONDS,
PROP_SYSTEM_MONITOR_COMMAND,
PROP_UPTIME,
PROP_CPU_ENABLED,
PROP_CPU_USE_LABEL,
PROP_CPU_LABEL,
PROP_CPU_COLOR,
PROP_MEMORY_ENABLED,
PROP_MEMORY_USE_LABEL,
PROP_MEMORY_LABEL,
PROP_MEMORY_COLOR,
PROP_NETWORK_ENABLED,
PROP_NETWORK_USE_LABEL,
PROP_NETWORK_LABEL,
PROP_NETWORK_COLOR,
PROP_SWAP_ENABLED,
PROP_SWAP_USE_LABEL,
PROP_SWAP_LABEL,
PROP_SWAP_COLOR,
N_PROPERTIES,
};
enum {
CONFIGURATION_CHANGED,
LAST_SIGNAL
};
static guint systemload_config_signals [LAST_SIGNAL] = { 0, };
static SystemloadMonitor
prop2monitor (SystemloadProperty p)
{
switch (p)
{
case PROP_CPU_ENABLED:
case PROP_CPU_USE_LABEL:
case PROP_CPU_LABEL:
case PROP_CPU_COLOR:
return CPU_MONITOR;
case PROP_MEMORY_ENABLED:
case PROP_MEMORY_USE_LABEL:
case PROP_MEMORY_LABEL:
case PROP_MEMORY_COLOR:
return MEM_MONITOR;
case PROP_NETWORK_ENABLED:
case PROP_NETWORK_USE_LABEL:
case PROP_NETWORK_LABEL:
case PROP_NETWORK_COLOR:
return NET_MONITOR;
case PROP_SWAP_ENABLED:
case PROP_SWAP_USE_LABEL:
case PROP_SWAP_LABEL:
case PROP_SWAP_COLOR:
return SWAP_MONITOR;
default:
/* Ideally, this codepath is never reached */
return CPU_MONITOR;
}
}
static GdkRGBA
rgba_float (GdkRGBA color)
{
return (GdkRGBA) {
(float) color.red,
(float) color.green,
(float) color.blue,
(float) color.alpha
};
}
/* Compare two GdkRGBA values with the precision of float32 instead of the default precision of float64.
* This is needed because the value of gdk_rgba_parse("#RRGGBB") can differ (by a delta of about 1e-17)
* from the value returned by GtkColorButton if exactly the same "#RRGGBB" string is input by the user,
* which indicates that either the GDK library or the GTK library is using mathematical operations
* with a lower precision than the other library when processing the same "#RRGGBB" string. */
static bool
rgba_equal (GdkRGBA a, GdkRGBA b)
{
a = rgba_float (a);
b = rgba_float (b);
return gdk_rgba_equal (&a, &b);
}
static bool
is_default_color (SystemloadMonitor m, const GdkRGBA *color)
{
GdkRGBA default_color;
if (G_LIKELY (gdk_rgba_parse (&default_color, DEFAULT_COLOR[m])))
return rgba_equal (*color, default_color);
else
return FALSE;
}
G_DEFINE_TYPE (SystemloadConfig, systemload_config, G_TYPE_OBJECT)
static void
systemload_config_class_init (SystemloadConfigClass *klass)
{
GObjectClass *gobject_class;
gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = systemload_config_finalize;
gobject_class->get_property = systemload_config_get_property;
gobject_class->set_property = systemload_config_set_property;
g_object_class_install_property (gobject_class,
PROP_TIMEOUT,
g_param_spec_uint ("timeout", NULL, NULL,
500, 10000, DEFAULT_TIMEOUT,
GParamFlags (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (gobject_class,
PROP_TIMEOUT_SECONDS,
g_param_spec_uint ("timeout-seconds", NULL, NULL,
1, 10, DEFAULT_TIMEOUT_SECONDS,
GParamFlags (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (gobject_class,
PROP_SYSTEM_MONITOR_COMMAND,
g_param_spec_string ("system-monitor-command", NULL, NULL,
DEFAULT_SYSTEM_MONITOR_COMMAND,
GParamFlags (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (gobject_class,
PROP_UPTIME,
g_param_spec_boolean ("uptime-enabled", NULL, NULL,
TRUE,
GParamFlags (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (gobject_class,
PROP_CPU_ENABLED,
g_param_spec_boolean ("cpu-enabled", NULL, NULL,
TRUE,
GParamFlags (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (gobject_class,
PROP_CPU_USE_LABEL,
g_param_spec_boolean ("cpu-use-label", NULL, NULL,
TRUE,
GParamFlags (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (gobject_class,
PROP_CPU_LABEL,
g_param_spec_string ("cpu-label", NULL, NULL,
DEFAULT_LABEL[CPU_MONITOR],
GParamFlags (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (gobject_class,
PROP_CPU_COLOR,
g_param_spec_boxed ("cpu-color",
NULL, NULL,
GDK_TYPE_RGBA,
GParamFlags (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (gobject_class,
PROP_MEMORY_ENABLED,
g_param_spec_boolean ("memory-enabled", NULL, NULL,
TRUE,
GParamFlags (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (gobject_class,
PROP_MEMORY_USE_LABEL,
g_param_spec_boolean ("memory-use-label", NULL, NULL,
TRUE,
GParamFlags (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (gobject_class,
PROP_MEMORY_LABEL,
g_param_spec_string ("memory-label", NULL, NULL,
DEFAULT_LABEL[MEM_MONITOR],
GParamFlags (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (gobject_class,
PROP_MEMORY_COLOR,
g_param_spec_boxed ("memory-color",
NULL, NULL,
GDK_TYPE_RGBA,
GParamFlags (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (gobject_class,
PROP_NETWORK_ENABLED,
g_param_spec_boolean ("network-enabled", NULL, NULL,
TRUE,
GParamFlags (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (gobject_class,
PROP_NETWORK_USE_LABEL,
g_param_spec_boolean ("network-use-label", NULL, NULL,
TRUE,
GParamFlags (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (gobject_class,
PROP_NETWORK_LABEL,
g_param_spec_string ("network-label", NULL, NULL,
DEFAULT_LABEL[NET_MONITOR],
GParamFlags (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (gobject_class,
PROP_NETWORK_COLOR,
g_param_spec_boxed ("network-color",
NULL, NULL,
GDK_TYPE_RGBA,
GParamFlags (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (gobject_class,
PROP_SWAP_ENABLED,
g_param_spec_boolean ("swap-enabled", NULL, NULL,
TRUE,
GParamFlags (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (gobject_class,
PROP_SWAP_USE_LABEL,
g_param_spec_boolean ("swap-use-label", NULL, NULL,
TRUE,
GParamFlags (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (gobject_class,
PROP_SWAP_LABEL,
g_param_spec_string ("swap-label", NULL, NULL,
DEFAULT_LABEL[SWAP_MONITOR],
GParamFlags (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (gobject_class,
PROP_SWAP_COLOR,
g_param_spec_boxed ("swap-color",
NULL, NULL,
GDK_TYPE_RGBA,
GParamFlags (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
systemload_config_signals[CONFIGURATION_CHANGED] =
g_signal_new (g_intern_static_string ("configuration-changed"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
}
static void
systemload_config_init (SystemloadConfig *config)
{
config->timeout = DEFAULT_TIMEOUT;
config->timeout_seconds = DEFAULT_TIMEOUT_SECONDS;
config->system_monitor_command = g_strdup (DEFAULT_SYSTEM_MONITOR_COMMAND);
config->uptime = true;
for (gsize i = 0; i < G_N_ELEMENTS (config->monitor); i++)
{
config->monitor[i].enabled = true;
config->monitor[i].use_label = true;
config->monitor[i].label = g_strdup (DEFAULT_LABEL[i]);
gdk_rgba_parse (&config->monitor[i].color, DEFAULT_COLOR[i]);
}
}
static void
systemload_config_finalize (GObject *object)
{
SystemloadConfig *config = SYSTEMLOAD_CONFIG (object);
xfconf_shutdown();
g_free (config->property_base);
g_free (config->system_monitor_command);
for (gsize i = 0; i < G_N_ELEMENTS (config->monitor); i++)
g_free (config->monitor[i].label);
G_OBJECT_CLASS (systemload_config_parent_class)->finalize (object);
}
static void
systemload_config_get_property (GObject *object,
guint _prop_id,
GValue *value,
GParamSpec *pspec)
{
const SystemloadConfig *config = SYSTEMLOAD_CONFIG (object);
auto prop_id = SystemloadProperty (_prop_id);
switch (prop_id)
{
case PROP_TIMEOUT:
g_value_set_uint (value, config->timeout);
break;
case PROP_TIMEOUT_SECONDS:
g_value_set_uint (value, config->timeout_seconds);
break;
case PROP_SYSTEM_MONITOR_COMMAND:
g_value_set_string (value, config->system_monitor_command);
break;
case PROP_UPTIME:
g_value_set_boolean (value, config->uptime);
break;
case PROP_CPU_ENABLED:
case PROP_MEMORY_ENABLED:
case PROP_NETWORK_ENABLED:
case PROP_SWAP_ENABLED:
g_value_set_boolean (value, config->monitor[prop2monitor(prop_id)].enabled);
break;
case PROP_CPU_USE_LABEL:
case PROP_MEMORY_USE_LABEL:
case PROP_NETWORK_USE_LABEL:
case PROP_SWAP_USE_LABEL:
g_value_set_boolean (value, config->monitor[prop2monitor(prop_id)].use_label);
break;
case PROP_CPU_LABEL:
case PROP_MEMORY_LABEL:
case PROP_NETWORK_LABEL:
case PROP_SWAP_LABEL:
g_value_set_string (value, config->monitor[prop2monitor(prop_id)].label);
break;
case PROP_CPU_COLOR:
case PROP_MEMORY_COLOR:
case PROP_NETWORK_COLOR:
case PROP_SWAP_COLOR:
g_value_set_boxed (value, &config->monitor[prop2monitor(prop_id)].color);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
systemload_config_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
SystemloadConfig *config = SYSTEMLOAD_CONFIG (object);
gboolean val_bool;
GdkRGBA *val_rgba;
const char *val_string;
guint val_uint;
switch (prop_id)
{
case PROP_TIMEOUT:
val_uint = g_value_get_uint (value);
if (config->timeout != val_uint)
{
config->timeout = val_uint;
g_object_notify (G_OBJECT (config), "timeout");
g_signal_emit (G_OBJECT (config), systemload_config_signals [CONFIGURATION_CHANGED], 0);
}
break;
case PROP_TIMEOUT_SECONDS:
val_uint = g_value_get_uint (value);
if (config->timeout_seconds != val_uint)
{
config->timeout_seconds = val_uint;
g_object_notify (G_OBJECT (config), "timeout-seconds");
g_signal_emit (G_OBJECT (config), systemload_config_signals [CONFIGURATION_CHANGED], 0);
}
break;
case PROP_SYSTEM_MONITOR_COMMAND:
val_string = g_value_get_string (value);
if (g_strcmp0 (config->system_monitor_command, val_string) != 0)
{
g_free (config->system_monitor_command);
config->system_monitor_command = g_value_dup_string (value);
g_object_notify (G_OBJECT (config), "system-monitor-command");
g_signal_emit (G_OBJECT (config), systemload_config_signals [CONFIGURATION_CHANGED], 0);
}
break;
case PROP_UPTIME:
val_bool = g_value_get_boolean (value);
if (config->uptime != val_bool)
{
config->uptime = val_bool;
g_object_notify (G_OBJECT (config), "uptime-enabled");
g_signal_emit (G_OBJECT (config), systemload_config_signals [CONFIGURATION_CHANGED], 0);
}
break;
case PROP_CPU_ENABLED:
val_bool = g_value_get_boolean (value);
if (config->monitor[CPU_MONITOR].enabled != val_bool)
{
config->monitor[CPU_MONITOR].enabled = val_bool;
g_object_notify (G_OBJECT (config), "cpu-enabled");
g_signal_emit (G_OBJECT (config), systemload_config_signals [CONFIGURATION_CHANGED], 0);
}
break;
case PROP_CPU_USE_LABEL:
val_bool = g_value_get_boolean (value);
if (config->monitor[CPU_MONITOR].use_label != val_bool)
{
config->monitor[CPU_MONITOR].use_label = val_bool;
g_object_notify (G_OBJECT (config), "cpu-use-label");
g_signal_emit (G_OBJECT (config), systemload_config_signals [CONFIGURATION_CHANGED], 0);
}
break;
case PROP_CPU_LABEL:
val_string = g_value_get_string (value);
if (g_strcmp0 (config->monitor[CPU_MONITOR].label, val_string) != 0)
{
g_free (config->monitor[CPU_MONITOR].label);
config->monitor[CPU_MONITOR].label = g_value_dup_string (value);
g_object_notify (G_OBJECT (config), "cpu-label");
g_signal_emit (G_OBJECT (config), systemload_config_signals [CONFIGURATION_CHANGED], 0);
}
break;
case PROP_CPU_COLOR:
val_rgba = (GdkRGBA*) g_value_dup_boxed (value);
if (!rgba_equal (config->monitor[CPU_MONITOR].color, *val_rgba))
{
config->monitor[CPU_MONITOR].color = *val_rgba;
g_object_notify (G_OBJECT (config), "cpu-color");
g_signal_emit (G_OBJECT (config), systemload_config_signals [CONFIGURATION_CHANGED], 0);
}
if (is_default_color (CPU_MONITOR, val_rgba))
{
char *property = g_strconcat (config->property_base, "/cpu/color", NULL);
xfconf_channel_reset_property (config->channel, property, TRUE);
g_free (property);
}
g_boxed_free (GDK_TYPE_RGBA, val_rgba);
break;
case PROP_MEMORY_ENABLED:
val_bool = g_value_get_boolean (value);
if (config->monitor[MEM_MONITOR].enabled != val_bool)
{
config->monitor[MEM_MONITOR].enabled = val_bool;
g_object_notify (G_OBJECT (config), "memory-enabled");
g_signal_emit (G_OBJECT (config), systemload_config_signals [CONFIGURATION_CHANGED], 0);
}
break;
case PROP_MEMORY_USE_LABEL:
val_bool = g_value_get_boolean (value);
if (config->monitor[MEM_MONITOR].use_label != val_bool)
{
config->monitor[MEM_MONITOR].use_label = val_bool;
g_object_notify (G_OBJECT (config), "memory-use-label");
g_signal_emit (G_OBJECT (config), systemload_config_signals [CONFIGURATION_CHANGED], 0);
}
break;
case PROP_MEMORY_LABEL:
val_string = g_value_get_string (value);
if (g_strcmp0 (config->monitor[MEM_MONITOR].label, val_string) != 0)
{
g_free (config->monitor[MEM_MONITOR].label);
config->monitor[MEM_MONITOR].label = g_value_dup_string (value);
g_object_notify (G_OBJECT (config), "memory-label");
g_signal_emit (G_OBJECT (config), systemload_config_signals [CONFIGURATION_CHANGED], 0);
}
break;
case PROP_MEMORY_COLOR:
val_rgba = (GdkRGBA*) g_value_dup_boxed (value);
if (!rgba_equal (config->monitor[MEM_MONITOR].color, *val_rgba))
{
config->monitor[MEM_MONITOR].color = *val_rgba;
g_object_notify (G_OBJECT (config), "memory-color");
g_signal_emit (G_OBJECT (config), systemload_config_signals [CONFIGURATION_CHANGED], 0);
}
if (is_default_color (MEM_MONITOR, val_rgba))
{
char *property = g_strconcat (config->property_base, "/memory/color", NULL);
xfconf_channel_reset_property (config->channel, property, TRUE);
g_free (property);
}
g_boxed_free (GDK_TYPE_RGBA, val_rgba);
break;
case PROP_NETWORK_ENABLED:
val_bool = g_value_get_boolean (value);
if (config->monitor[NET_MONITOR].enabled != val_bool)
{
config->monitor[NET_MONITOR].enabled = val_bool;
g_object_notify (G_OBJECT (config), "network-enabled");
g_signal_emit (G_OBJECT (config), systemload_config_signals [CONFIGURATION_CHANGED], 0);
}
break;
case PROP_NETWORK_USE_LABEL:
val_bool = g_value_get_boolean (value);
if (config->monitor[NET_MONITOR].use_label != val_bool)
{
config->monitor[NET_MONITOR].use_label = val_bool;
g_object_notify (G_OBJECT (config), "network-use-label");
g_signal_emit (G_OBJECT (config), systemload_config_signals [CONFIGURATION_CHANGED], 0);
}
break;
case PROP_NETWORK_LABEL:
val_string = g_value_get_string (value);
if (g_strcmp0 (config->monitor[NET_MONITOR].label, val_string) != 0)
{
g_free (config->monitor[NET_MONITOR].label);
config->monitor[NET_MONITOR].label = g_value_dup_string (value);
g_object_notify (G_OBJECT (config), "network-label");
g_signal_emit (G_OBJECT (config), systemload_config_signals [CONFIGURATION_CHANGED], 0);
}
break;
case PROP_NETWORK_COLOR:
val_rgba = (GdkRGBA*) g_value_dup_boxed (value);
if (!rgba_equal (config->monitor[NET_MONITOR].color, *val_rgba))
{
config->monitor[NET_MONITOR].color = *val_rgba;
g_object_notify (G_OBJECT (config), "network-color");
g_signal_emit (G_OBJECT (config), systemload_config_signals [CONFIGURATION_CHANGED], 0);
}
if (is_default_color (NET_MONITOR, val_rgba))
{
char *property = g_strconcat (config->property_base, "/network/color", NULL);
xfconf_channel_reset_property (config->channel, property, TRUE);
g_free (property);
}
g_boxed_free (GDK_TYPE_RGBA, val_rgba);
break;
case PROP_SWAP_ENABLED:
val_bool = g_value_get_boolean (value);
if (config->monitor[SWAP_MONITOR].enabled != val_bool)
{
config->monitor[SWAP_MONITOR].enabled = val_bool;
g_object_notify (G_OBJECT (config), "swap-enabled");
g_signal_emit (G_OBJECT (config), systemload_config_signals [CONFIGURATION_CHANGED], 0);
}
break;
case PROP_SWAP_USE_LABEL:
val_bool = g_value_get_boolean (value);
if (config->monitor[SWAP_MONITOR].use_label != val_bool)
{
config->monitor[SWAP_MONITOR].use_label = val_bool;
g_object_notify (G_OBJECT (config), "swap-use-label");
g_signal_emit (G_OBJECT (config), systemload_config_signals [CONFIGURATION_CHANGED], 0);
}
break;
case PROP_SWAP_LABEL:
val_string = g_value_get_string (value);
if (g_strcmp0 (config->monitor[SWAP_MONITOR].label, val_string) != 0)
{
g_free (config->monitor[SWAP_MONITOR].label);
config->monitor[SWAP_MONITOR].label = g_value_dup_string (value);
g_object_notify (G_OBJECT (config), "swap-label");
g_signal_emit (G_OBJECT (config), systemload_config_signals [CONFIGURATION_CHANGED], 0);
}
break;
case PROP_SWAP_COLOR:
val_rgba = (GdkRGBA*) g_value_dup_boxed (value);
if (!rgba_equal (config->monitor[SWAP_MONITOR].color, *val_rgba))
{
config->monitor[SWAP_MONITOR].color = *val_rgba;
g_object_notify (G_OBJECT (config), "swap-color");
g_signal_emit (G_OBJECT (config), systemload_config_signals [CONFIGURATION_CHANGED], 0);
}
if (is_default_color (SWAP_MONITOR, val_rgba))
{
char *property = g_strconcat (config->property_base, "/swap/color", NULL);
xfconf_channel_reset_property (config->channel, property, TRUE);
g_free (property);
}
g_boxed_free (GDK_TYPE_RGBA, val_rgba);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
guint
systemload_config_get_timeout (const SystemloadConfig *config)
{
g_return_val_if_fail (IS_SYSTEMLOAD_CONFIG (config), DEFAULT_TIMEOUT);
return config->timeout;
}
guint
systemload_config_get_timeout_seconds (const SystemloadConfig *config)
{
g_return_val_if_fail (IS_SYSTEMLOAD_CONFIG (config), DEFAULT_TIMEOUT_SECONDS);
return config->timeout_seconds;
}
const gchar*
systemload_config_get_system_monitor_command (const SystemloadConfig *config)
{
g_return_val_if_fail (IS_SYSTEMLOAD_CONFIG (config), DEFAULT_SYSTEM_MONITOR_COMMAND);
return config->system_monitor_command;
}
bool
systemload_config_get_uptime_enabled (const SystemloadConfig *config)
{
g_return_val_if_fail (IS_SYSTEMLOAD_CONFIG (config), true);
return config->uptime;
}
bool
systemload_config_get_enabled (const SystemloadConfig *config, SystemloadMonitor monitor)
{
g_return_val_if_fail (IS_SYSTEMLOAD_CONFIG (config), true);
if (monitor >= 0 && (gsize) monitor < G_N_ELEMENTS (config->monitor))
return config->monitor[monitor].enabled;
else
return true;
}
bool
systemload_config_get_use_label (const SystemloadConfig *config, SystemloadMonitor monitor)
{
g_return_val_if_fail (IS_SYSTEMLOAD_CONFIG (config), true);
if (monitor >= 0 && (gsize) monitor < G_N_ELEMENTS (config->monitor))
return config->monitor[monitor].use_label;
else
return true;
}
const gchar *
systemload_config_get_label (const SystemloadConfig *config, SystemloadMonitor monitor)
{
g_return_val_if_fail (IS_SYSTEMLOAD_CONFIG (config), "");
if (monitor >= 0 && (gsize) monitor < G_N_ELEMENTS (config->monitor))
return config->monitor[monitor].label;
else
return "";
}
const GdkRGBA *
systemload_config_get_color (const SystemloadConfig *config, SystemloadMonitor monitor)
{
g_return_val_if_fail (IS_SYSTEMLOAD_CONFIG (config), NULL);
if (monitor >= 0 && (gsize) monitor < G_N_ELEMENTS (config->monitor))
return &config->monitor[monitor].color;
else
return NULL;
}
SystemloadConfig *
systemload_config_new (const gchar *property_base)
{
auto config = (SystemloadConfig*) g_object_new (TYPE_SYSTEMLOAD_CONFIG, NULL);
if (xfconf_init (NULL))
{
XfconfChannel *channel = xfconf_channel_get ("xfce4-panel");
gchar *property;
config->channel = channel;
config->property_base = g_strdup (property_base);
property = g_strconcat (property_base, "/timeout", NULL);
xfconf_g_property_bind (channel, property, G_TYPE_UINT, config, "timeout");
g_free (property);
property = g_strconcat (property_base, "/timeout-seconds", NULL);
xfconf_g_property_bind (channel, property, G_TYPE_UINT, config, "timeout-seconds");
g_free (property);
property = g_strconcat (property_base, "/system-monitor-command", NULL);
xfconf_g_property_bind (channel, property, G_TYPE_STRING, config, "system-monitor-command");
g_free (property);
property = g_strconcat (property_base, "/uptime/enabled", NULL);
xfconf_g_property_bind (channel, property, G_TYPE_BOOLEAN, config, "uptime-enabled");
g_free (property);
property = g_strconcat (property_base, "/cpu/enabled", NULL);
xfconf_g_property_bind (channel, property, G_TYPE_BOOLEAN, config, "cpu-enabled");
g_free (property);
property = g_strconcat (property_base, "/cpu/use-label", NULL);
xfconf_g_property_bind (channel, property, G_TYPE_BOOLEAN, config, "cpu-use-label");
g_free (property);
property = g_strconcat (property_base, "/cpu/label", NULL);
xfconf_g_property_bind (channel, property, G_TYPE_STRING, config, "cpu-label");
g_free (property);
property = g_strconcat (property_base, "/cpu/color", NULL);
xfconf_g_property_bind_gdkrgba (channel, property, config, "cpu-color");
g_free (property);
property = g_strconcat (property_base, "/memory/enabled", NULL);
xfconf_g_property_bind (channel, property, G_TYPE_BOOLEAN, config, "memory-enabled");
g_free (property);
property = g_strconcat (property_base, "/memory/use-label", NULL);
xfconf_g_property_bind (channel, property, G_TYPE_BOOLEAN, config, "memory-use-label");
g_free (property);
property = g_strconcat (property_base, "/memory/label", NULL);
xfconf_g_property_bind (channel, property, G_TYPE_STRING, config, "memory-label");
g_free (property);
property = g_strconcat (property_base, "/memory/color", NULL);
xfconf_g_property_bind_gdkrgba (channel, property, config, "memory-color");
g_free (property);
property = g_strconcat (property_base, "/network/enabled", NULL);
xfconf_g_property_bind (channel, property, G_TYPE_BOOLEAN, config, "network-enabled");
g_free (property);
property = g_strconcat (property_base, "/network/use-label", NULL);
xfconf_g_property_bind (channel, property, G_TYPE_BOOLEAN, config, "network-use-label");
g_free (property);
property = g_strconcat (property_base, "/network/label", NULL);
xfconf_g_property_bind (channel, property, G_TYPE_STRING, config, "network-label");
g_free (property);
property = g_strconcat (property_base, "/network/color", NULL);
xfconf_g_property_bind_gdkrgba (channel, property, config, "network-color");
g_free (property);
property = g_strconcat (property_base, "/swap/enabled", NULL);
xfconf_g_property_bind (channel, property, G_TYPE_BOOLEAN, config, "swap-enabled");
g_free (property);
property = g_strconcat (property_base, "/swap/use-label", NULL);
xfconf_g_property_bind (channel, property, G_TYPE_BOOLEAN, config, "swap-use-label");
g_free (property);
property = g_strconcat (property_base, "/swap/label", NULL);
xfconf_g_property_bind (channel, property, G_TYPE_STRING, config, "swap-label");
g_free (property);
property = g_strconcat (property_base, "/swap/color", NULL);
xfconf_g_property_bind_gdkrgba (channel, property, config, "swap-color");
g_free (property);
}
return config;
}
void systemload_config_on_change (SystemloadConfig *config,
gboolean (*callback)(gpointer user_data),
gpointer user_data)
{
g_signal_connect_swapped (G_OBJECT (config), "configuration-changed", G_CALLBACK (callback), user_data);
}

64
panel-plugin/settings.h Normal file
View file

@ -0,0 +1,64 @@
/*
* This file is part of Xfce (https://gitlab.xfce.org).
*
* Copyright (C) 2021 Simon Steinbeiß <simon@xfce.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _XFCE_SYSTEMLOAD_SETTINGS_H_
#define _XFCE_SYSTEMLOAD_SETTINGS_H_
#include <glib.h>
#define MIN_TIMEOUT 500
#define MAX_TIMEOUT 10000
enum SystemloadMonitor {
CPU_MONITOR,
MEM_MONITOR,
NET_MONITOR,
SWAP_MONITOR,
};
typedef struct _SystemloadConfigClass SystemloadConfigClass;
typedef struct _SystemloadConfig SystemloadConfig;
#define TYPE_SYSTEMLOAD_CONFIG (systemload_config_get_type ())
#define SYSTEMLOAD_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_SYSTEMLOAD_CONFIG, SystemloadConfig))
#define SYSTEMLOAD_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_SYSTEMLOAD_CONFIG, SystemloadConfigClass))
#define IS_SYSTEMLOAD_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_SYSTEMLOAD_CONFIG))
#define IS_SYSTEMLOAD_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_SYSTEMLOAD_CONFIG))
#define SYSTEMLOAD_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_SYSTEMLOAD_CONFIG, SystemloadConfigClass))
GType systemload_config_get_type (void) G_GNUC_CONST;
SystemloadConfig *systemload_config_new (const gchar *property_base);
void systemload_config_on_change (SystemloadConfig *config,
gboolean (*callback)(gpointer user_data),
gpointer user_data);
guint systemload_config_get_timeout (const SystemloadConfig *config);
guint systemload_config_get_timeout_seconds (const SystemloadConfig *config);
const gchar *systemload_config_get_system_monitor_command (const SystemloadConfig *config);
bool systemload_config_get_uptime_enabled (const SystemloadConfig *config);
bool systemload_config_get_enabled (const SystemloadConfig *config, SystemloadMonitor monitor);
bool systemload_config_get_use_label (const SystemloadConfig *config, SystemloadMonitor monitor);
const gchar *systemload_config_get_label (const SystemloadConfig *config, SystemloadMonitor monitor);
const GdkRGBA *systemload_config_get_color (const SystemloadConfig *config, SystemloadMonitor monitor);
#endif /* _XFCE_SYSTEMLOAD_SETTINGS_H_ */

930
panel-plugin/systemload.cc Normal file
View file

@ -0,0 +1,930 @@
/*
* This file is part of Xfce (https://gitlab.xfce.org).
*
* Copyright (c) 2003 Riccardo Persichetti <riccardo.persichetti@tin.it>
* Copyright (c) 2010 Florian Rivoal <frivoal@xfce.org>
* Copyright (c) 2012 David Schneider <dnschneid@gmail.com>
* Copyright (c) 2014-2017 Landry Breuil <landry@xfce.org>
* Copyright (c) 2021 Simon Steinbeiss <simon@xfce.org>
* Copyright (c) 2022 Jan Ziak <0xe2.0x9a.0x9b@xfce.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
#include <libxfce4util/libxfce4util.h>
#include <libxfce4ui/libxfce4ui.h>
#include <libxfce4panel/libxfce4panel.h>
#ifdef HAVE_UPOWER_GLIB
#include <upower.h>
#endif
#include "cpu.h"
#include "memswap.h"
#include "network.h"
#include "plugin.h"
#include "settings.h"
#include "uptime.h"
struct t_command {
bool enabled;
gchar *command_text;
};
struct t_monitor {
GtkWidget *box;
GtkWidget *label;
GtkWidget *status;
GtkWidget *ebox;
gulong value_read; /* Range: 0% ... 100% */
};
struct t_uptime_monitor {
GtkWidget *label;
GtkWidget *ebox;
gulong value_read;
};
struct t_global_monitor {
XfcePanelPlugin *plugin;
SystemloadConfig *config;
GtkWidget *ebox;
GtkWidget *box;
guint timeout, timeout_seconds;
bool use_timeout_seconds;
guint timeout_id;
t_command command;
t_monitor *monitor[4];
t_uptime_monitor uptime;
#ifdef HAVE_UPOWER_GLIB
UpClient *upower;
#endif
};
static const SystemloadMonitor VISUAL_ORDER[] = {
CPU_MONITOR,
MEM_MONITOR,
SWAP_MONITOR,
NET_MONITOR,
};
static gboolean setup_monitor_cb(gpointer user_data);
static bool
spawn_system_monitor(GtkWidget *w, t_global_monitor *global)
{
// Spawn defined command; In-terminal: false, Startup-notify: false
return xfce_spawn_command_line_on_screen(gdk_screen_get_default(),
global->command.command_text,
FALSE, FALSE, NULL);
}
static gboolean
click_event(GtkWidget *w, GdkEventButton *event, t_global_monitor *global)
{
if(event->button == 1 && global->command.enabled && *(global->command.command_text))
return spawn_system_monitor(w, global);
return FALSE;
}
static void
set_fraction(GtkProgressBar *bar, gdouble fraction)
{
/*
* Try to avoid a call to GTK's bar_set_fraction() if the new fraction
* isn't changing the number of pixels (height or width of the bar) already
* displayed on the screen.
*
* max_alloc is independent from horizontal/vertical orientation of the bar.
*/
GtkAllocation alloc;
gtk_widget_get_allocation(GTK_WIDGET(bar), &alloc);
gint max_alloc = MAX(alloc.width, alloc.height);
if (max_alloc > 1)
fraction = round(fraction * max_alloc) / max_alloc;
if (gtk_progress_bar_get_fraction(bar) != fraction)
gtk_progress_bar_set_fraction(bar, fraction);
}
static void
set_label_text(GtkLabel *label, const gchar *text)
{
const gchar *displayed_text = gtk_label_get_text(label);
if (g_strcmp0(displayed_text, text) != 0)
gtk_label_set_text(label, text);
}
static void
set_tooltip(GtkWidget *w, const gchar *caption)
{
gchar *displayed_caption = gtk_widget_get_tooltip_text(w);
if (g_strcmp0(displayed_caption, caption) != 0)
gtk_widget_set_tooltip_text(w, caption);
g_free(displayed_caption);
}
static void
update_monitors(t_global_monitor *global)
{
const SystemloadConfig *config = global->config;
gulong MTotal = 0, MUsed = 0, NTotal = 0, STotal = 0, SUsed = 0;
for(gsize i = 0; i < G_N_ELEMENTS (global->monitor); i++)
global->monitor[i]->value_read = 0;
if (systemload_config_get_enabled (config, CPU_MONITOR))
global->monitor[CPU_MONITOR]->value_read = read_cpuload();
if (systemload_config_get_enabled (config, MEM_MONITOR) ||
systemload_config_get_enabled (config, SWAP_MONITOR))
{
gulong mem, swap;
if (read_memswap(&mem, &swap, &MTotal, &MUsed, &STotal, &SUsed) == 0)
{
global->monitor[MEM_MONITOR]->value_read = mem;
global->monitor[SWAP_MONITOR]->value_read = swap;
}
}
if (systemload_config_get_enabled (config, NET_MONITOR))
{
gulong net;
if (read_netload (&net, &NTotal) == 0)
global->monitor[NET_MONITOR]->value_read = net;
}
if (systemload_config_get_uptime_enabled (config))
global->uptime.value_read = read_uptime();
for(gsize i = 0; i < G_N_ELEMENTS (global->monitor); i++)
{
const auto monitor = (SystemloadMonitor) i;
t_monitor *m = global->monitor[monitor];
if (systemload_config_get_enabled (config, monitor))
{
gulong value = MIN(m->value_read, 100);
set_fraction(GTK_PROGRESS_BAR(global->monitor[i]->status), value / 100.0);
}
}
if (systemload_config_get_enabled (config, CPU_MONITOR))
{
gchar tooltip[128];
g_snprintf(tooltip, sizeof(tooltip), _("System Load: %ld%%"), global->monitor[CPU_MONITOR]->value_read);
set_tooltip(global->monitor[CPU_MONITOR]->ebox, tooltip);
}
if (systemload_config_get_enabled (config, MEM_MONITOR))
{
gchar tooltip[128];
g_snprintf(tooltip, sizeof(tooltip), _("Memory: %ldMB of %ldMB used"), MUsed >> 10 , MTotal >> 10);
set_tooltip(global->monitor[MEM_MONITOR]->ebox, tooltip);
}
if (systemload_config_get_enabled (config, NET_MONITOR))
{
gchar tooltip[128];
g_snprintf(tooltip, sizeof(tooltip), _("Network: %ld Mbit/s"), (glong) round (NTotal / 1e6));
set_tooltip(global->monitor[NET_MONITOR]->ebox, tooltip);
}
if (systemload_config_get_enabled (config, SWAP_MONITOR))
{
gchar tooltip[128];
if (STotal)
g_snprintf(tooltip, sizeof(tooltip), _("Swap: %ldMB of %ldMB used"), SUsed >> 10, STotal >> 10);
else
g_snprintf(tooltip, sizeof(tooltip), _("No swap"));
set_tooltip(global->monitor[SWAP_MONITOR]->ebox, tooltip);
}
if (systemload_config_get_uptime_enabled (config))
{
gchar days_str[2][32], hours_str[2][32], mins_str[2][32];
gchar text[128], tooltip[128];
gint days = global->uptime.value_read / 86400;
gint hours = (global->uptime.value_read / 3600) % 24;
gint mins = (global->uptime.value_read / 60) % 60;
g_snprintf(days_str[0], sizeof(days_str), _("%dd"), days);
g_snprintf(hours_str[0], sizeof(hours_str), _("%dh"), hours);
g_snprintf(mins_str[0], sizeof(mins_str), _("%dm"), mins);
g_snprintf(days_str[1], sizeof(days_str), ngettext("%d day", "%d days", days), days);
g_snprintf(hours_str[1], sizeof(hours_str), ngettext("%d hour", "%d hours", hours), hours);
g_snprintf(mins_str[1], sizeof(mins_str), ngettext("%d minute", "%d minutes", mins), mins);
if (days > 0)
g_snprintf(text, sizeof(text), "%s %s %s", days_str[0], hours_str[0], mins_str[0]);
else
g_snprintf(text, sizeof(text), "%s %s", hours_str[0], mins_str[0]);
g_snprintf(tooltip, sizeof(tooltip), _("Uptime: %s, %s, %s"), days_str[1], hours_str[1], mins_str[1]);
set_label_text(GTK_LABEL(global->uptime.label), text);
set_tooltip(global->uptime.ebox, tooltip);
}
}
static void
monitor_update_orientation (XfcePanelPlugin *plugin,
GtkOrientation panel_orientation,
GtkOrientation orientation,
t_global_monitor *global)
{
gtk_orientable_set_orientation(GTK_ORIENTABLE(global->box), panel_orientation);
for(gsize count = 0; count < G_N_ELEMENTS (global->monitor); count++)
{
gtk_orientable_set_orientation(GTK_ORIENTABLE(global->monitor[count]->box), panel_orientation);
gtk_label_set_angle(GTK_LABEL(global->monitor[count]->label),
(orientation == GTK_ORIENTATION_HORIZONTAL) ? 0 : -90);
gtk_progress_bar_set_inverted (GTK_PROGRESS_BAR(global->monitor[count]->status), (panel_orientation == GTK_ORIENTATION_HORIZONTAL));
gtk_orientable_set_orientation (GTK_ORIENTABLE(global->monitor[count]->status),
(panel_orientation == GTK_ORIENTATION_HORIZONTAL) ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL);
}
gtk_label_set_angle(GTK_LABEL(global->uptime.label),
(orientation == GTK_ORIENTATION_HORIZONTAL) ? 0 : -90);
}
static void
create_monitor (t_global_monitor *global)
{
const SystemloadConfig *config = global->config;
global->box = gtk_box_new(xfce_panel_plugin_get_orientation(global->plugin), 0);
gtk_widget_show(global->box);
for(gsize i = 0; i < G_N_ELEMENTS (global->monitor); i++)
{
SystemloadMonitor monitor = VISUAL_ORDER[i];
t_monitor *m = global->monitor[monitor];
m->label = gtk_label_new (systemload_config_get_label (config, monitor));
m->status = GTK_WIDGET(gtk_progress_bar_new());
#if GTK_CHECK_VERSION (3, 16, 0)
GtkCssProvider *css_provider = gtk_css_provider_new ();
gtk_style_context_add_provider (
GTK_STYLE_CONTEXT (gtk_widget_get_style_context (GTK_WIDGET (m->status))),
GTK_STYLE_PROVIDER (css_provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
gtk_css_provider_load_from_data (css_provider, "\
progressbar.horizontal trough { min-height: 4px; }\
progressbar.horizontal progress { min-height: 4px; }\
progressbar.vertical trough { min-width: 4px; }\
progressbar.vertical progress { min-width: 4px; }",
-1, NULL);
g_object_set_data(G_OBJECT(m->status), "css_provider", css_provider);
#endif
m->box = gtk_box_new(xfce_panel_plugin_get_orientation(global->plugin), 0);
gtk_box_pack_start(GTK_BOX(m->box), GTK_WIDGET(m->label), FALSE, FALSE, 0);
m->ebox = gtk_event_box_new();
gtk_widget_show(m->ebox);
gtk_container_add(GTK_CONTAINER(m->ebox), GTK_WIDGET(m->box));
gtk_event_box_set_visible_window(GTK_EVENT_BOX(m->ebox), FALSE);
gtk_event_box_set_above_child(GTK_EVENT_BOX(m->ebox), TRUE);
gtk_widget_show(GTK_WIDGET(m->status));
gtk_box_pack_start(GTK_BOX(m->box), GTK_WIDGET(m->status), FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(global->box), GTK_WIDGET(m->ebox), FALSE, FALSE, 0);
gtk_widget_show_all(GTK_WIDGET(m->ebox));
}
global->uptime.ebox = gtk_event_box_new();
if (systemload_config_get_uptime_enabled (config))
gtk_widget_show(global->uptime.ebox);
gtk_event_box_set_visible_window(GTK_EVENT_BOX(global->uptime.ebox), FALSE);
global->uptime.label = gtk_label_new("");
gtk_widget_show(global->uptime.label);
gtk_container_add(GTK_CONTAINER(global->uptime.ebox),
GTK_WIDGET(global->uptime.label));
gtk_box_pack_start(GTK_BOX(global->box),
GTK_WIDGET(global->uptime.ebox),
FALSE, FALSE, 0);
gtk_container_add(GTK_CONTAINER(global->ebox), GTK_WIDGET(global->box));
gtk_event_box_set_visible_window(GTK_EVENT_BOX(global->ebox), FALSE);
gtk_widget_show(GTK_WIDGET(global->ebox));
update_monitors (global);
}
static t_global_monitor *
monitor_control_new(XfcePanelPlugin *plugin)
{
t_global_monitor *global = g_new0 (t_global_monitor, 1);
#ifdef HAVE_UPOWER_GLIB
global->upower = up_client_new();
#endif
global->plugin = plugin;
/* initialize xfconf */
global->config = systemload_config_new (xfce_panel_plugin_get_property_base (plugin));
global->timeout = systemload_config_get_timeout (global->config);
if (global->timeout < MIN_TIMEOUT)
global->timeout = MIN_TIMEOUT;
global->timeout_seconds = systemload_config_get_timeout_seconds (global->config);
global->use_timeout_seconds = (global->timeout_seconds > 0);
global->ebox = gtk_event_box_new();
gtk_widget_show(global->ebox);
global->command.command_text = g_strdup (systemload_config_get_system_monitor_command (global->config));
if (strlen(global->command.command_text) > 0)
global->command.enabled = true;
xfce_panel_plugin_add_action_widget (plugin, global->ebox);
for(gsize i = 0; i < G_N_ELEMENTS (global->monitor); i++)
global->monitor[i] = g_new0 (t_monitor, 1);
systemload_config_on_change (global->config, setup_monitor_cb, global);
return global;
}
static void
monitor_free(XfcePanelPlugin *plugin, t_global_monitor *global)
{
#ifdef HAVE_UPOWER_GLIB
if (global->upower) {
g_object_unref(global->upower);
global->upower = NULL;
}
#endif
if (global->timeout_id)
g_source_remove(global->timeout_id);
g_free(global->command.command_text);
for(gsize i = 0; i < G_N_ELEMENTS (global->monitor); i++)
g_free (global->monitor[i]);
g_free(global);
}
static gboolean
update_monitors_cb(gpointer user_data)
{
auto global = (t_global_monitor*) user_data;
update_monitors (global);
return TRUE;
}
static void
setup_timer(t_global_monitor *global)
{
GtkSettings *settings;
if (global->timeout_id)
g_source_remove(global->timeout_id);
#ifdef HAVE_UPOWER_GLIB
if (global->upower && global->use_timeout_seconds) {
if (up_client_get_on_battery(global->upower)) {
if (!up_client_get_lid_is_closed(global->upower)) {
global->timeout_id = g_timeout_add_seconds(
global->timeout_seconds,
update_monitors_cb, global);
} else {
/* Don't do any timeout if the lid is closed on battery */
global->timeout_id = 0;
}
return;
}
}
#endif
global->timeout_id = g_timeout_add(global->timeout, update_monitors_cb, global);
/* reduce the default tooltip timeout to be smaller than the update interval otherwise
* we won't see tooltips on GTK 2.16 or newer */
settings = gtk_settings_get_default();
if (g_object_class_find_property(G_OBJECT_GET_CLASS(settings), "gtk-tooltip-timeout"))
g_object_set(settings, "gtk-tooltip-timeout",
global->timeout - 10, NULL);
}
static void
set_margin (const t_global_monitor *global, GtkWidget *w, gint margin)
{
if (xfce_panel_plugin_get_orientation (global->plugin) == GTK_ORIENTATION_HORIZONTAL)
{
gtk_widget_set_margin_start (w, margin);
gtk_widget_set_margin_top (w, 0);
}
else
{
gtk_widget_set_margin_start (w, 0);
gtk_widget_set_margin_top (w, margin);
}
}
static void
setup_monitors(t_global_monitor *global)
{
const SystemloadConfig *config = global->config;
gtk_widget_hide(GTK_WIDGET(global->uptime.ebox));
/* determine the number of enabled monitors and the number of enabled labels */
guint n_enabled = 0, n_enabled_labels = 0;
for(gsize i = 0; i < G_N_ELEMENTS (global->monitor); i++)
{
auto monitor = (SystemloadMonitor) i;
if (systemload_config_get_enabled (config, monitor))
{
bool label_visible = systemload_config_get_use_label (config, monitor) &&
strlen (systemload_config_get_label (config, monitor)) != 0;
n_enabled++;
n_enabled_labels += (label_visible ? 1 : 0);
}
}
for(gsize i = 0; i < G_N_ELEMENTS (global->monitor); i++)
{
const auto monitor = (SystemloadMonitor) i;
const t_monitor *m = global->monitor[monitor];
const GdkRGBA *color = NULL;
gtk_widget_hide(m->ebox);
gtk_widget_hide(m->label);
gtk_label_set_text(GTK_LABEL(m->label), systemload_config_get_label (config, monitor));
color = systemload_config_get_color (config, monitor);
if (G_LIKELY (color != NULL))
{
#if GTK_CHECK_VERSION (3, 16, 0)
gchar *color_str = gdk_rgba_to_string(color);
gchar *css;
#if GTK_CHECK_VERSION (3, 20, 0)
css = g_strdup_printf("progressbar progress { background-color: %s; background-image: none; border-color: %s; }",
color_str, color_str);
#else
css = g_strdup_printf(".progressbar progress { background-color: %s; background-image: none; }", color);
#endif
gtk_css_provider_load_from_data (
(GtkCssProvider*) g_object_get_data(G_OBJECT(m->status), "css_provider"),
css, strlen(css), NULL);
g_free(color_str);
g_free(css);
#else
gtk_widget_override_background_color(m->status, GTK_STATE_FLAG_PRELIGHT, color);
gtk_widget_override_background_color(m->status, GTK_STATE_FLAG_SELECTED, color);
gtk_widget_override_color(m->status, GTK_STATE_FLAG_SELECTED, color);
#endif
}
if (systemload_config_get_enabled (config, monitor))
{
bool label_visible = systemload_config_get_use_label (config, monitor) &&
strlen (systemload_config_get_label (config, monitor)) != 0;
gtk_widget_show_all(GTK_WIDGET(m->ebox));
gtk_widget_set_visible (m->label, label_visible);
set_margin (global, m->ebox, (n_enabled_labels == 0) ? 0 : 6);
}
}
if (systemload_config_get_uptime_enabled (config))
{
gtk_widget_show_all (global->uptime.ebox);
set_margin (global, global->uptime.ebox, (n_enabled == 0) ? 0 : 6);
}
setup_timer (global);
}
static gboolean
setup_monitor_cb(gpointer user_data)
{
auto global = (t_global_monitor*) user_data;
setup_monitors (global);
update_monitors (global);
return TRUE;
}
static gboolean
monitor_set_size(XfcePanelPlugin *plugin, int size, t_global_monitor *global)
{
gtk_container_set_border_width (GTK_CONTAINER (global->ebox), (size > 26 ? 2 : 1));
for(gsize i = 0; i < G_N_ELEMENTS (global->monitor); i++)
{
if (xfce_panel_plugin_get_orientation (plugin) == GTK_ORIENTATION_HORIZONTAL)
{
gtk_widget_set_size_request(GTK_WIDGET(global->monitor[i]->status), 8, -1);
}
else
{
gtk_widget_set_size_request(GTK_WIDGET(global->monitor[i]->status), -1, 8);
}
}
setup_monitors (global);
return TRUE;
}
static void
monitor_set_mode (XfcePanelPlugin *plugin, XfcePanelPluginMode mode, t_global_monitor *global)
{
GtkOrientation panel_orientation = xfce_panel_plugin_get_orientation (plugin);
GtkOrientation orientation = (mode == XFCE_PANEL_PLUGIN_MODE_VERTICAL) ?
GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL;
/* Set small in all modes except deskbar mode */
if (mode == XFCE_PANEL_PLUGIN_MODE_DESKBAR)
xfce_panel_plugin_set_small(XFCE_PANEL_PLUGIN(plugin), FALSE);
else
xfce_panel_plugin_set_small(XFCE_PANEL_PLUGIN(plugin), TRUE);
monitor_update_orientation (plugin, panel_orientation, orientation, global);
monitor_set_size (plugin, xfce_panel_plugin_get_size (plugin), global);
}
#ifdef HAVE_UPOWER_GLIB
static void
#if UP_CHECK_VERSION(0, 99, 0)
upower_changed_cb(UpClient *client, GParamSpec *pspec, t_global_monitor *global)
#else /* UP_CHECK_VERSION < 0.99 */
upower_changed_cb(UpClient *client, t_global_monitor *global)
#endif /* UP_CHECK_VERSION */
{
setup_timer(global);
}
#endif /* HAVE_UPOWER_GLIB */
static void
command_entry_changed_cb(GtkEntry *entry, t_global_monitor *global)
{
g_free (global->command.command_text);
global->command.command_text = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
global->command.enabled = (strlen (global->command.command_text) != 0);
}
static void
switch_cb(GtkSwitch *check_button, gboolean state, t_global_monitor *global)
{
gpointer sensitive_widget = g_object_get_data (G_OBJECT (check_button), "sensitive_widget");
gtk_switch_set_state (check_button, state);
if (sensitive_widget)
gtk_revealer_set_reveal_child (GTK_REVEALER (sensitive_widget), state);
}
static void
monitor_dialog_response (GtkWidget *dlg, int response,
t_global_monitor *global)
{
if (response == GTK_RESPONSE_HELP)
{
xfce_dialog_show_help (GTK_WINDOW (dlg), PACKAGE_NAME, NULL, NULL);
}
else
{
gtk_widget_destroy (dlg);
xfce_panel_plugin_unblock_menu (global->plugin);
}
}
static void
change_timeout_cb(GtkSpinButton *spin, t_global_monitor *global)
{
global->timeout = gtk_spin_button_get_value(spin);
setup_timer(global);
}
#ifdef HAVE_UPOWER_GLIB
static void
change_timeout_seconds_cb(GtkSpinButton *spin, t_global_monitor *global)
{
global->timeout_seconds = gtk_spin_button_get_value (spin);
global->use_timeout_seconds = (global->timeout_seconds != 0);
setup_timer (global);
}
#endif
/* Creates a label, its mnemonic will point to target.
* Returns the widget. */
static GtkWidget *new_label (GtkGrid *grid, guint row, const gchar *labeltext, GtkWidget *target)
{
GtkWidget *label = gtk_label_new_with_mnemonic (labeltext);
gtk_widget_set_halign(label, GTK_ALIGN_START);
gtk_widget_set_valign(label, GTK_ALIGN_CENTER);
gtk_widget_set_margin_start (label, 12);
gtk_label_set_mnemonic_widget(GTK_LABEL(label), target);
gtk_grid_attach(grid, label, 0, row, 1, 1);
return label;
}
/* Create a new monitor setting with gtkswitch, and eventually a color button and a checkbox + entry */
static void
new_monitor_setting (t_global_monitor *global,
GtkGrid *grid, int position,
const gchar *title, bool color,
const gchar *setting)
{
GtkWidget *sw, *label;
gchar *markup, *setting_name;
gboolean enabled = TRUE;
sw = gtk_switch_new();
gtk_widget_set_halign (sw, GTK_ALIGN_END);
gtk_widget_set_valign (sw, GTK_ALIGN_CENTER);
gtk_widget_set_margin_top (sw, 12);
setting_name = g_strconcat (setting, "-enabled", NULL);
g_object_get (G_OBJECT (global->config), setting_name, &enabled, NULL);
g_object_bind_property (G_OBJECT (global->config), setting_name,
G_OBJECT (sw), "active",
GBindingFlags (G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL));
g_signal_connect (GTK_WIDGET(sw), "state-set",
G_CALLBACK(switch_cb), global);
g_free (setting_name);
markup = g_markup_printf_escaped ("<b>%s</b>", title);
label = gtk_label_new (markup);
gtk_widget_set_halign(label, GTK_ALIGN_START);
gtk_widget_set_valign(label, GTK_ALIGN_CENTER);
gtk_widget_set_margin_top (label, 12);
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
g_free (markup);
gtk_grid_attach(GTK_GRID(grid), label, 0, position, 1, 1);
gtk_grid_attach(GTK_GRID(grid), sw, 1, position, 1, 1);
if (g_strcmp0 (setting, "uptime") != 0)
{
GtkWidget *revealer = gtk_revealer_new ();
GtkWidget *subgrid = gtk_grid_new ();
gtk_container_add (GTK_CONTAINER (revealer), subgrid);
gtk_revealer_set_reveal_child (GTK_REVEALER (revealer), TRUE);
g_object_set_data (G_OBJECT(sw), "sensitive_widget", revealer);
gtk_grid_attach(GTK_GRID(grid), revealer, 0, position + 1, 2, 1);
gtk_grid_set_column_spacing (GTK_GRID(subgrid), 12);
gtk_grid_set_row_spacing (GTK_GRID(subgrid), 6);
label = gtk_label_new_with_mnemonic (_("Label:"));
gtk_widget_set_halign (label, GTK_ALIGN_START);
gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
gtk_widget_set_margin_start (label, 12);
gtk_grid_attach (GTK_GRID(subgrid), label, 0, 0, 1, 1);
/* Entry for the optional monitor label */
GtkWidget *entry = gtk_entry_new ();
gtk_widget_set_hexpand (entry, TRUE);
gtk_widget_set_tooltip_text (entry, _("Leave empty to disable the label"));
setting_name = g_strconcat (setting, "-label", NULL);
g_object_bind_property (G_OBJECT (global->config), setting_name,
G_OBJECT (entry), "text",
GBindingFlags (G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL));
g_free (setting_name);
gtk_grid_attach(GTK_GRID(subgrid), entry, 1, 0, 1, 1);
if (color)
{
/* Colorbutton to set the progressbar color */
GtkWidget *button = gtk_color_button_new ();
gtk_color_chooser_set_use_alpha (GTK_COLOR_CHOOSER (button), TRUE);
gtk_label_set_mnemonic_widget (GTK_LABEL (label), button);
gtk_widget_set_halign(button, GTK_ALIGN_START);
gtk_widget_set_margin_start (button, 12);
setting_name = g_strconcat (setting, "-color", NULL);
g_object_bind_property (G_OBJECT (global->config), setting_name,
G_OBJECT (button), "rgba",
GBindingFlags (G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL));
g_free (setting_name);
gtk_grid_attach(GTK_GRID(subgrid), button, 2, 0, 1, 1);
}
}
switch_cb (GTK_SWITCH (sw), enabled, global);
}
static void
monitor_create_options(XfcePanelPlugin *plugin, t_global_monitor *global)
{
SystemloadConfig *config = global->config;
GtkWidget *label, *entry, *button, *box;
static const gchar *FRAME_TEXT[] = {
N_ ("CPU monitor"),
N_ ("Memory monitor"),
N_ ("Network monitor"),
N_ ("Swap monitor"),
N_ ("Uptime monitor")
};
static const gchar *SETTING_TEXT[] = {
"cpu",
"memory",
"network",
"swap"
};
xfce_panel_plugin_block_menu (plugin);
GtkWidget *dlg;
dlg = xfce_titled_dialog_new_with_mixed_buttons (_("System Load Monitor"),
GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (plugin))),
GTK_DIALOG_DESTROY_WITH_PARENT,
"window-close-symbolic", _("_Close"), GTK_RESPONSE_OK,
"help-browser", _("_Help"), GTK_RESPONSE_HELP,
NULL);
g_signal_connect (G_OBJECT (dlg), "response",
G_CALLBACK (monitor_dialog_response), global);
gtk_window_set_position (GTK_WINDOW (dlg), GTK_WIN_POS_CENTER);
gtk_window_set_icon_name (GTK_WINDOW (dlg), "org.xfce.panel.systemload");
GtkBox *content = GTK_BOX(gtk_dialog_get_content_area (GTK_DIALOG(dlg)));
GtkWidget *grid = gtk_grid_new();
gtk_grid_set_column_spacing (GTK_GRID(grid), 12);
gtk_grid_set_row_spacing (GTK_GRID(grid), 6);
gtk_container_set_border_width(GTK_CONTAINER(grid), 12);
gtk_box_pack_start (content, grid, TRUE, TRUE, 0);
label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (label), _("<b>General</b>"));
gtk_widget_set_halign(label, GTK_ALIGN_START);
gtk_widget_set_valign(label, GTK_ALIGN_CENTER);
gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
/* Update interval */
button = gtk_spin_button_new_with_range (MIN_TIMEOUT, MAX_TIMEOUT, 50);
gtk_label_set_mnemonic_widget (GTK_LABEL(label), button);
gtk_widget_set_halign (button, GTK_ALIGN_START);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (button), (gfloat)global->timeout);
g_object_bind_property (G_OBJECT (config), "timeout",
G_OBJECT (button), "value",
GBindingFlags (G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL));
g_signal_connect (G_OBJECT (button), "value-changed", G_CALLBACK(change_timeout_cb), global);
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
label = gtk_label_new ("ms");
gtk_box_pack_start (GTK_BOX (box), button, FALSE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
gtk_grid_attach (GTK_GRID (grid), box, 1, 1, 1, 1);
new_label (GTK_GRID (grid), 1, _("Update interval:"), button);
#ifdef HAVE_UPOWER_GLIB
/* Power-saving interval */
button = gtk_spin_button_new_with_range (0, 10, 1);
gtk_widget_set_halign (button, GTK_ALIGN_START);
gtk_widget_set_tooltip_text(GTK_WIDGET(button), _("Update interval when running on battery (uses regular update interval if set to zero)"));
gtk_spin_button_set_value (GTK_SPIN_BUTTON (button), (gfloat)global->timeout_seconds);
g_object_bind_property (G_OBJECT (config), "timeout-seconds",
G_OBJECT (button), "value",
GBindingFlags (G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL));
g_signal_connect (G_OBJECT (button), "value-changed", G_CALLBACK(change_timeout_seconds_cb), global);
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
label = gtk_label_new ("s");
gtk_box_pack_start (GTK_BOX (box), button, FALSE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
gtk_grid_attach (GTK_GRID (grid), box, 1, 2, 1, 1);
new_label (GTK_GRID (grid), 2, _("Power-saving interval:"), button);
#endif
/* System Monitor */
entry = gtk_entry_new ();
gtk_widget_set_hexpand (entry, TRUE);
gtk_entry_set_text (GTK_ENTRY(entry), global->command.command_text);
gtk_widget_set_tooltip_text(GTK_WIDGET(entry), _("Launched when clicking on the plugin"));
g_object_bind_property (G_OBJECT (config), "system-monitor-command",
G_OBJECT (entry), "text",
GBindingFlags (G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL));
g_signal_connect (G_OBJECT(entry), "changed",
G_CALLBACK(command_entry_changed_cb), global);
gtk_grid_attach (GTK_GRID (grid), entry, 1, 3, 1, 1);
label = new_label (GTK_GRID (grid), 3, _("System monitor:"), entry);
/* Add options for the monitors */
for(gsize i = 0; i < G_N_ELEMENTS (global->monitor); i++)
{
const SystemloadMonitor monitor = VISUAL_ORDER[i];
new_monitor_setting (global, GTK_GRID(grid), 4 + 2 * i,
_(FRAME_TEXT[monitor]),
true,
SETTING_TEXT[monitor]);
}
/* Uptime monitor options */
new_monitor_setting (global, GTK_GRID(grid), 4 + 2*G_N_ELEMENTS (global->monitor),
_(FRAME_TEXT[4]), FALSE, "uptime");
gtk_widget_show_all (dlg);
}
static void
monitor_show_about(XfcePanelPlugin *plugin, t_global_monitor *global)
{
/* List of authors (in alphabetical order) */
const gchar *auth[] = {
"David Schneider <dnschneid@gmail.com>",
"Florian Rivoal <frivoal@xfce.org>",
"Jan Ziak <0xe2.0x9a.0x9b@xfce.org>",
"Landry Breuil <landry@xfce.org>",
"Riccardo Persichetti <riccardo.persichetti@tin.it>",
"Simon Steinbeiß <simon@xfce.org>",
NULL
};
gtk_show_about_dialog (NULL,
"logo-icon-name", "org.xfce.panel.systemload",
"license", xfce_get_license_text (XFCE_LICENSE_TEXT_BSD),
"version", PACKAGE_VERSION,
"program-name", PACKAGE_NAME,
"comments", _("Monitor CPU load, swap usage and memory footprint"),
"website", "https://docs.xfce.org/panel-plugins/xfce4-systemload-plugin/start",
"copyright", _("Copyright (c) 2003-2022\n"),
"authors", auth, NULL);
}
void
systemload_construct (XfcePanelPlugin *plugin)
{
xfce_textdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
t_global_monitor *global = monitor_control_new (plugin);
create_monitor (global);
monitor_set_mode (plugin, xfce_panel_plugin_get_mode (plugin), global);
setup_monitors (global);
gtk_container_add (GTK_CONTAINER (plugin), global->ebox);
update_monitors (global);
#ifdef HAVE_UPOWER_GLIB
if (global->upower) {
#if UP_CHECK_VERSION(0, 99, 0)
g_signal_connect (global->upower, "notify", G_CALLBACK(upower_changed_cb), global);
#else /* UP_CHECK_VERSION < 0.99 */
g_signal_connect (global->upower, "changed", G_CALLBACK(upower_changed_cb), global);
#endif /* UP_CHECK_VERSION */
}
#endif /* HAVE_UPOWER_GLIB */
g_signal_connect (plugin, "free-data", G_CALLBACK (monitor_free), global);
g_signal_connect (plugin, "size-changed", G_CALLBACK (monitor_set_size), global);
g_signal_connect (plugin, "mode-changed", G_CALLBACK (monitor_set_mode), global);
g_signal_connect (plugin, "button-press-event", G_CALLBACK (click_event), global);
xfce_panel_plugin_menu_show_configure (plugin);
g_signal_connect (plugin, "configure-plugin", G_CALLBACK (monitor_create_options), global);
xfce_panel_plugin_menu_show_about(plugin);
g_signal_connect (plugin, "about", G_CALLBACK (monitor_show_about), global);
}

View file

@ -0,0 +1,9 @@
[Xfce Panel]
Type=X-XFCE-PanelPlugin
Encoding=UTF-8
_Name=System Load Monitor
_Comment=Monitor CPU load, swap usage and memory footprint
Icon=org.xfce.panel.systemload
X-XFCE-Module=systemload
X-XFCE-Internal=false
X-XFCE-API=2.0

140
panel-plugin/uptime.cc Normal file
View file

@ -0,0 +1,140 @@
/*
* This file is part of Xfce (https://gitlab.xfce.org).
*
* Copyright (c) 2003 Riccardo Persichetti <riccardo.persichetti@tin.it>
* Copyright (c) 2010 Florian Rivoal <frivoal@xfce.org>
* Copyright (c) 2022 Jan Ziak <0xe2.0x9a.0x9b@xfce.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "uptime.h"
#if defined(__linux__) || defined(__FreeBSD_kernel__)
#include <fcntl.h>
#include <glib/gi18n.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PROC_UPTIME "/proc/uptime"
gulong read_uptime()
{
FILE *fd = fopen(PROC_UPTIME, "r");
if (!fd) {
g_warning("%s", _("File /proc/uptime not found!"));
return 0;
}
gulong uptime;
if (!fscanf(fd, "%lu", &uptime))
uptime = 0;
fclose(fd);
return uptime;
}
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
#ifdef __NetBSD__
/*
* NetBSD defines MAX and MIN in sys/param.h, so undef the glib macros first
*/
#ifdef MAX
#undef MAX
#endif
#ifdef MIN
#undef MIN
#endif
#endif /* !__NetBSD__ */
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/types.h>
#include <sys/vmmeter.h>
#include <unistd.h>
#ifdef __FreeBSD__
#include <sys/time.h>
#endif /* !__FreeBSD__ */
gulong read_uptime()
{
int mib[2] = {CTL_KERN, KERN_BOOTTIME};
struct timeval boottime;
size_t size = sizeof(boottime);
gulong uptime;
if((sysctl(mib, 2, &boottime, &size, NULL, 0) != -1) && (boottime.tv_sec != 0)) {
time_t now;
time(&now);
uptime = now - boottime.tv_sec;
}
else
{
g_warning("Cannot get kern.boottime");
uptime = 0;
}
return uptime;
}
#elif defined(__sun__)
#include <kstat.h>
gulong read_uptime()
{
kstat_ctl_t *kc;
kstat_t *ks;
kstat_named_t *boottime;
gulong uptime;
if (((kc = kstat_open()) != 0) && ((ks = kstat_lookup(kc, "unix", 0, "system_misc")) != NULL) && (kstat_read(kc, ks, NULL) != -1) && ((boottime = kstat_data_lookup(ks, "boot_time")) != NULL)) {
time_t now;
time(&now);
uptime = now - boottime->value.ul;
kstat_close(kc);
}
else
{
g_warning("Cannot get boot_time");
uptime = 0;
}
return uptime;
}
#else
#error "Your platform is not yet supported"
#endif

36
panel-plugin/uptime.h Normal file
View file

@ -0,0 +1,36 @@
/*
* This file is part of Xfce (https://gitlab.xfce.org).
*
* Copyright (c) 2003 Riccardo Persichetti <riccardo.persichetti@tin.it>
* Copyright (c) 2010 Florian Rivoal <frivoal@xfce.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _XFCE_SYSTEMLOAD_UPTIME_H_
#define _XFCE_SYSTEMLOAD_UPTIME_H_
#include <glib.h>
gulong read_uptime();
#endif /* _XFCE_SYSTEMLOAD_UPTIME_H_ */