summaryrefslogtreecommitdiffstats
path: root/kcpuload/kcpuload
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-15 18:16:33 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-15 18:16:33 +0000
commitec0343ea3ec3c0eb444db2ba98f3c8dbe4cf156b (patch)
tree0f5c292df974170aaa5b91d8b09e3fa58a0b7c61 /kcpuload/kcpuload
downloadkcpuload-ec0343ea3ec3c0eb444db2ba98f3c8dbe4cf156b.tar.gz
kcpuload-ec0343ea3ec3c0eb444db2ba98f3c8dbe4cf156b.zip
Added KDE3 version of kcpuload
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/kcpuload@1090658 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kcpuload/kcpuload')
-rw-r--r--kcpuload/kcpuload/Makefile.am49
-rw-r--r--kcpuload/kcpuload/cr16-app-kcpuload.pngbin0 -> 318 bytes
-rw-r--r--kcpuload/kcpuload/cr32-app-kcpuload.pngbin0 -> 572 bytes
-rw-r--r--kcpuload/kcpuload/cr48-app-kcpuload.pngbin0 -> 1386 bytes
-rw-r--r--kcpuload/kcpuload/icontoggleaction.cpp63
-rw-r--r--kcpuload/kcpuload/icontoggleaction.h61
-rw-r--r--kcpuload/kcpuload/kcpudock.cpp32
-rw-r--r--kcpuload/kcpuload/kcpudock.h41
-rw-r--r--kcpuload/kcpuload/kcpuload.cpp177
-rw-r--r--kcpuload/kcpuload/kcpuload.desktop11
-rw-r--r--kcpuload/kcpuload/kcpuload.h71
-rw-r--r--kcpuload/kcpuload/kcpuproc.cpp196
-rw-r--r--kcpuload/kcpuload/kcpuproc.h170
-rw-r--r--kcpuload/kcpuload/lo16-app-kcpuload.pngbin0 -> 327 bytes
-rw-r--r--kcpuload/kcpuload/lo32-app-kcpuload.pngbin0 -> 416 bytes
-rw-r--r--kcpuload/kcpuload/main.cpp64
-rw-r--r--kcpuload/kcpuload/speeddialog.cpp63
-rw-r--r--kcpuload/kcpuload/speeddialog.h49
-rw-r--r--kcpuload/kcpuload/statdock.cpp244
-rw-r--r--kcpuload/kcpuload/statdock.h160
-rw-r--r--kcpuload/kcpuload/statpopup.cpp485
-rw-r--r--kcpuload/kcpuload/statpopup.h319
22 files changed, 2255 insertions, 0 deletions
diff --git a/kcpuload/kcpuload/Makefile.am b/kcpuload/kcpuload/Makefile.am
new file mode 100644
index 0000000..b254d71
--- /dev/null
+++ b/kcpuload/kcpuload/Makefile.am
@@ -0,0 +1,49 @@
+
+############################################################################
+# #
+# Main KCPULoad sources. #
+# #
+# KCPULoad is copyright (c) 1999-2000, Markus Gustavsson #
+# (c) 2002, Ben Burton #
+# #
+# 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. #
+# #
+############################################################################
+
+INCLUDES = $(all_includes)
+
+bin_PROGRAMS = kcpuload
+
+kcpuload_LDFLAGS = $(KDE_RPATH) $(all_libraries)
+
+kcpuload_LDADD = $(LIB_KDEUI)
+
+kcpuload_SOURCES = \
+ icontoggleaction.cpp \
+ kcpudock.cpp \
+ kcpuload.cpp \
+ kcpuproc.cpp \
+ main.cpp \
+ statdock.cpp \
+ speeddialog.cpp \
+ statpopup.cpp
+
+noinst_HEADERS = \
+ icontoggleaction.h \
+ kcpudock.h \
+ kcpuload.h \
+ kcpuproc.h \
+ speeddialog.h \
+ statdock.h \
+ statpopup.h
+
+METASOURCES = AUTO
+
+appsdir = $(kde_appsdir)/System
+apps_DATA = kcpuload.desktop
+
+KDE_ICON = kcpuload
+
diff --git a/kcpuload/kcpuload/cr16-app-kcpuload.png b/kcpuload/kcpuload/cr16-app-kcpuload.png
new file mode 100644
index 0000000..038a684
--- /dev/null
+++ b/kcpuload/kcpuload/cr16-app-kcpuload.png
Binary files differ
diff --git a/kcpuload/kcpuload/cr32-app-kcpuload.png b/kcpuload/kcpuload/cr32-app-kcpuload.png
new file mode 100644
index 0000000..e2679aa
--- /dev/null
+++ b/kcpuload/kcpuload/cr32-app-kcpuload.png
Binary files differ
diff --git a/kcpuload/kcpuload/cr48-app-kcpuload.png b/kcpuload/kcpuload/cr48-app-kcpuload.png
new file mode 100644
index 0000000..7d7be85
--- /dev/null
+++ b/kcpuload/kcpuload/cr48-app-kcpuload.png
Binary files differ
diff --git a/kcpuload/kcpuload/icontoggleaction.cpp b/kcpuload/kcpuload/icontoggleaction.cpp
new file mode 100644
index 0000000..521a213
--- /dev/null
+++ b/kcpuload/kcpuload/icontoggleaction.cpp
@@ -0,0 +1,63 @@
+
+/***************************************************************************
+ * *
+ * KCPULoad and KNetLoad are copyright (c) 1999-2000, Markus Gustavsson *
+ * (c) 2002, Ben Burton *
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "icontoggleaction.h"
+
+IconToggleAction::IconToggleAction(
+ const QString& useTextUnchecked, const QString& useIconUnchecked,
+ const QString& useTextChecked, const QString& useIconChecked,
+ const KShortcut& cut, const QObject* receiver, const char* slot,
+ QObject* parent, const char* name) :
+ KToggleAction(useTextUnchecked, useIconUnchecked, cut, receiver,
+ slot, parent, name),
+ textChecked(useTextChecked), textUnchecked(useTextUnchecked),
+ iconChecked(useIconChecked), iconUnchecked(useIconUnchecked) {
+}
+
+IconToggleAction::IconToggleAction(const QString& useText,
+ const QString& useIconUnchecked, const QString& useIconChecked,
+ const KShortcut& cut, const QObject* receiver, const char* slot,
+ QObject* parent, const char* name) :
+ KToggleAction(useText, useIconUnchecked, cut, receiver,
+ slot, parent, name),
+ textChecked(useText), textUnchecked(useText),
+ iconChecked(useIconChecked), iconUnchecked(useIconUnchecked) {
+}
+
+IconToggleAction::IconToggleAction(
+ const QString& useTextUnchecked, const QString& useIconUnchecked,
+ const QString& useTextChecked, const QString& useIconChecked,
+ const KShortcut& cut, QObject* parent, const char* name) :
+ KToggleAction(useTextUnchecked, useIconUnchecked, cut, parent, name),
+ textChecked(useTextChecked), textUnchecked(useTextUnchecked),
+ iconChecked(useIconChecked), iconUnchecked(useIconUnchecked) {
+}
+
+IconToggleAction::IconToggleAction(const QString& useText,
+ const QString& useIconUnchecked, const QString& useIconChecked,
+ const KShortcut& cut, QObject* parent, const char* name) :
+ KToggleAction(useText, useIconUnchecked, cut, parent, name),
+ textChecked(useText), textUnchecked(useText),
+ iconChecked(useIconChecked), iconUnchecked(useIconUnchecked) {
+}
+
+void IconToggleAction::setChecked(bool value) {
+ if (value != isChecked()) {
+ setText(value ? textChecked : textUnchecked);
+ setIcon(value ? iconChecked : iconUnchecked);
+ }
+
+ KToggleAction::setChecked(value);
+}
+
+#include "icontoggleaction.moc"
diff --git a/kcpuload/kcpuload/icontoggleaction.h b/kcpuload/kcpuload/icontoggleaction.h
new file mode 100644
index 0000000..469f763
--- /dev/null
+++ b/kcpuload/kcpuload/icontoggleaction.h
@@ -0,0 +1,61 @@
+
+/***************************************************************************
+ * *
+ * KCPULoad and KNetLoad are copyright (c) 1999-2000, Markus Gustavsson *
+ * (c) 2002, Ben Burton *
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef __ICONTOGGLEACTION_H
+#define __ICONTOGGLEACTION_H
+
+#include <kaction.h>
+
+/**
+ * A toggle action that uses different labels and pixmaps in its
+ * different states.
+ */
+class IconToggleAction : public KToggleAction {
+ Q_OBJECT
+
+ public:
+ /**
+ * Constructors.
+ */
+ IconToggleAction(
+ const QString& useTextUnchecked, const QString& useIconUnchecked,
+ const QString& useTextChecked, const QString& useIconChecked,
+ const KShortcut& cut, const QObject* receiver, const char* slot,
+ QObject* parent, const char* name = 0);
+ IconToggleAction(const QString& useText,
+ const QString& useIconUnchecked, const QString& useIconChecked,
+ const KShortcut& cut, const QObject* receiver, const char* slot,
+ QObject* parent, const char* name = 0);
+ IconToggleAction(
+ const QString& useTextUnchecked, const QString& useIconUnchecked,
+ const QString& useTextChecked, const QString& useIconChecked,
+ const KShortcut& cut = KShortcut(), QObject* parent = 0,
+ const char* name = 0);
+ IconToggleAction(const QString& useText,
+ const QString& useIconUnchecked, const QString& useIconChecked,
+ const KShortcut& cut = KShortcut(), QObject* parent = 0,
+ const char* name = 0);
+
+ /**
+ * Overridden to include icon adjustment.
+ */
+ virtual void setChecked(bool);
+
+ private:
+ QString textChecked, textUnchecked;
+ /**< The labels to use in the checked and unchecked states. */
+ QString iconChecked, iconUnchecked;
+ /**< The icons to use in the checked and unchecked states. */
+};
+
+#endif
diff --git a/kcpuload/kcpuload/kcpudock.cpp b/kcpuload/kcpuload/kcpudock.cpp
new file mode 100644
index 0000000..32352c3
--- /dev/null
+++ b/kcpuload/kcpuload/kcpudock.cpp
@@ -0,0 +1,32 @@
+
+/***************************************************************************
+ * *
+ * KCPULoad is copyright (c) 1999-2000, Markus Gustavsson *
+ * (c) 2002, Ben Burton *
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "kcpudock.h"
+
+#include <klocale.h>
+
+KCPUDock::KCPUDock(int whichCPU, StatPopup *parent, const char *name) :
+ StatDock(whichCPU, i18n("C"), parent, name) {
+}
+
+void KCPUDock::setCPULabel(int set) {
+ if (set == 1)
+ setLabel(i18n("C 0"));
+ else if (set == 2)
+ setLabel(i18n("C 1"));
+ else
+ setLabel(i18n("C"));
+
+ repaint();
+}
+
diff --git a/kcpuload/kcpuload/kcpudock.h b/kcpuload/kcpuload/kcpudock.h
new file mode 100644
index 0000000..f96e411
--- /dev/null
+++ b/kcpuload/kcpuload/kcpudock.h
@@ -0,0 +1,41 @@
+
+/***************************************************************************
+ * *
+ * KCPULoad is copyright (c) 1999-2000, Markus Gustavsson *
+ * (c) 2002, Ben Burton *
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef __KCPUDOCK_H
+#define __KCPUDOCK_H
+
+#include "statdock.h"
+
+/**
+ * A KCPULoad system tray window for a specific CPU.
+ */
+class KCPUDock : public StatDock {
+
+public:
+ /**
+ * Constructor.
+ */
+ KCPUDock(int whichDock, StatPopup *parent = 0, const char *name = 0);
+
+ /**
+ * Sets the label for this diagram. The label will reflect which
+ * CPU the diagram represents.
+ *
+ * If multiple CPUs are not used, argument cpu should be 0.
+ * Otherwise argument cpu should be 1 or 2 for the first or second
+ * CPU respectively.
+ */
+ void setCPULabel(int cpu);
+};
+
+#endif
diff --git a/kcpuload/kcpuload/kcpuload.cpp b/kcpuload/kcpuload/kcpuload.cpp
new file mode 100644
index 0000000..369ff69
--- /dev/null
+++ b/kcpuload/kcpuload/kcpuload.cpp
@@ -0,0 +1,177 @@
+
+/***************************************************************************
+ * *
+ * KCPULoad is copyright (c) 1999-2000, Markus Gustavsson *
+ * (c) 2002, Ben Burton *
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "icontoggleaction.h"
+#include "kcpudock.h"
+#include "kcpuload.h"
+#include "kcpuproc.h"
+
+#include <kaction.h>
+#include <kconfig.h>
+#include <klocale.h>
+#include <kpopupmenu.h>
+
+KCPULoad::KCPULoad(QWidget *parent, const char *name) :
+ StatPopup(true, parent, name) {
+ // Create the /proc reading class and check for SMP.
+ proc = new KCPUProc();
+ supportSMP = proc->hasSMP();
+
+ // Set up actions and read the config file.
+ setupActions();
+
+ // the vector must not be reallocated during resizing because the class
+ // that it contains (Reading) cannot be copied safely
+ r.reserve(proc->cpu.size());
+
+ // Create system tray windows.
+ resizeReadings(supportSMP && actSMP->isChecked() ? proc->cpu.size() : 1);
+
+ // Initialise the pop-up window.
+ readPopupState();
+
+ // Off we go!
+ requestResize();
+ if (isActive())
+ startUpdates();
+}
+
+KCPULoad::~KCPULoad() {
+ delete proc;
+}
+
+void KCPULoad::setSMP(bool set) {
+ if (! supportSMP)
+ return;
+
+ resizeReadings(set ? proc->cpu.size() : 1);
+
+ requestResize();
+ if (isActive())
+ takeReading();
+
+ config->setGroup("General Options");
+ config->writeEntry("SMP", set);
+ config->sync();
+}
+
+QString KCPULoad::dockName(int which) const {
+ return i18n("CPU %1").arg(which+1);
+}
+
+QColor KCPULoad::defaultDockColor(int which) const {
+ static const QColor c[] = {
+ QColor(0, 255, 0),
+ QColor(255, 0, 0),
+ QColor(255, 255, 0),
+ QColor(0, 255, 255)
+ };
+ return c[which % (sizeof(c)/sizeof(c[0]))];
+}
+
+void KCPULoad::setupCustomActions() {
+ if (supportSMP) {
+ bool bVal = config->readBoolEntry("SMP", false);
+ actSMP = new IconToggleAction(i18n("Enable S&MP"), "smp",
+ i18n("S&MP Enabled"), "smpon", 0, coll, "smp");
+ actSMP->setChecked(bVal);
+ connect(actSMP, SIGNAL(toggled(bool)), this, SLOT(setSMP(bool)));
+ }
+}
+
+void KCPULoad::insertCustomItems(KPopupMenu* menu) {
+ if (supportSMP) {
+ actSMP->plug(menu);
+ menu->insertSeparator();
+ }
+}
+
+void KCPULoad::takeReadingInternal() {
+ proc->readLoad();
+
+ if (r.size() > 1) {
+ if (isSplit()) {
+ for (int i = 0; i < r.size(); i++) {
+ r[i].upper = proc->cpu[i].userPercent();
+ r[i].lower = proc->cpu[i].systemPercent();
+ }
+ } else {
+ for (int i = 0; i < r.size(); i++) {
+ r[i].upper = proc->cpu[i].totalPercent();
+ }
+ }
+ } else if (r.size() > 0) {
+ if (isSplit()) {
+ r[0].upper = proc->all.userPercent();
+ r[0].lower = proc->all.systemPercent();
+ } else {
+ r[0].upper = proc->all.totalPercent();
+ }
+ }
+
+ if (isVisible()) {
+ if (r.size() > 1) {
+ if (isSplit()) {
+ QString user =
+ i18n("Current CPU User: %1%")
+ .arg(proc->all.userPercent());
+ QString sys =
+ i18n("Current CPU System: %1%")
+ .arg(proc->all.systemPercent());
+ for (int i = 0; i < r.size(); i++) {
+ user += i18n(", C%1: %2%").arg(i+1).arg(r[i].upper);
+ sys += i18n(", C%1: %2%").arg(i+1).arg(r[i].lower);
+ }
+ fullReading = i18n("%1.\n%2.").arg(user, sys);
+ } else {
+ QString total =
+ i18n("Current CPU usage: %1%")
+ .arg(proc->all.totalPercent());
+ for (int i = 0; i < r.size(); i++) {
+ total += i18n(", C%1: %2%").arg(i+1).arg(r[i].upper);
+ }
+ fullReading = i18n("%1.").arg(total);
+ }
+ } else if (r.size() > 0) {
+ if (isSplit()) {
+ fullReading = i18n(
+ "Current CPU User: %1%.\n"
+ "Current CPU System: %2%.")
+ .arg(r[0].upper).arg(r[0].lower);
+ } else {
+ fullReading = i18n("Current CPU usage: %1%.").arg(r[0].upper);
+ }
+ }
+ }
+ }
+
+void KCPULoad::resizeReadings(int n)
+{
+ int i = r.size();
+ r.resize(n);
+ for (; i < n; i++) {
+ // action is needed by KCPUDock constructor
+ r[i].Init(i, this);
+ KCPUDock* dock = new KCPUDock(i, this);
+ dock->setCPULabel(i+1);
+ r[i].dock = dock;
+ }
+ // special case single CPU or total
+ if (n == 1) {
+ static_cast<KCPUDock*>(r[0].dock)->setCPULabel(0);
+ } else if (n > 1) {
+ static_cast<KCPUDock*>(r[0].dock)->setCPULabel(1);
+ }
+}
+
+#include "kcpuload.moc"
diff --git a/kcpuload/kcpuload/kcpuload.desktop b/kcpuload/kcpuload/kcpuload.desktop
new file mode 100644
index 0000000..96a909a
--- /dev/null
+++ b/kcpuload/kcpuload/kcpuload.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Type=Application
+Exec=kcpuload
+Icon=kcpuload
+DocPath=kcpuload/index.html
+Terminal=0
+Name=KCPULoad
+GenericName=CPU Monitor
+Comment=A small CPU usage meter for Kicker
+Categories=Qt;KDE;System
diff --git a/kcpuload/kcpuload/kcpuload.h b/kcpuload/kcpuload/kcpuload.h
new file mode 100644
index 0000000..f4ff85a
--- /dev/null
+++ b/kcpuload/kcpuload/kcpuload.h
@@ -0,0 +1,71 @@
+
+/***************************************************************************
+ * *
+ * KCPULoad is copyright (c) 1999-2000, Markus Gustavsson *
+ * (c) 2002, Ben Burton *
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef __KCPULOAD_H
+#define __KCPULOAD_H
+
+#include "statpopup.h"
+
+class KCPUProc;
+class KToggleAction;
+
+/**
+ * The specific pop-up window used by KCPULoad.
+ */
+class KCPULoad : public StatPopup {
+ Q_OBJECT
+
+public:
+ /**
+ * Constructor and destructor.
+ */
+ KCPULoad(QWidget *parent = 0, const char *name = 0);
+ ~KCPULoad();
+
+public slots:
+ /**
+ * Slots for menu items.
+ */
+ void setSMP(bool);
+
+protected:
+ /**
+ * Overrides from StatPopup.
+ */
+ virtual QString dockName(int which) const;
+ virtual QColor defaultDockColor(int which) const;
+ virtual void setupCustomActions();
+ virtual void insertCustomItems(KPopupMenu* menu);
+ virtual void takeReadingInternal();
+
+private:
+ /**
+ * Changes the number of readings.
+ */
+ void resizeReadings(int n);
+
+ /**
+ * Reading raw CPU information.
+ */
+ KCPUProc* proc;
+ /**< Used to obtain the raw information. */
+ bool supportSMP;
+ /**< Does this system support SMP at all? */
+
+ /**
+ * Actions.
+ */
+ KToggleAction* actSMP;
+};
+
+#endif
diff --git a/kcpuload/kcpuload/kcpuproc.cpp b/kcpuload/kcpuload/kcpuproc.cpp
new file mode 100644
index 0000000..7e5bc9b
--- /dev/null
+++ b/kcpuload/kcpuload/kcpuproc.cpp
@@ -0,0 +1,196 @@
+
+/***************************************************************************
+ * *
+ * KCPULoad is copyright (c) 1999-2000, Markus Gustavsson *
+ * (c) 2002, Ben Burton *
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "kcpuproc.h"
+
+#include <cstdlib>
+#include <cstring>
+
+// BSD-specific includes.
+#ifdef Q_OS_BSD4
+#include <sys/dkstat.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <string.h>
+#include <kvm.h>
+#ifdef Q_OS_NETBSD
+#include <sys/sched.h>
+#endif
+#endif
+
+/**
+ * Linux
+ * -----
+ *
+ * System information is read from /proc/stat.
+ *
+ * We assume /proc/stat is in one of the following formats:
+ *
+ * cpu %d %d %d %d
+ * ....
+ *
+ * cpu %d %d %d %d
+ * cpu0 %d %d %d %d
+ * ....
+ *
+ * cpu %d %d %d %d
+ * cpu0 %d %d %d %d
+ * cpu1 %d %d %d %d
+ * ....
+ *
+ * where each set of four numbers is of the form:
+ *
+ * user_ticks nice_ticks system_ticks idle_ticks
+ *
+ * We also allow sets of seven numbers instead of four (as provided by
+ * the 2.6 kernel); the last three of these numbers are ignored.
+ *
+ * BSD
+ * ---
+ *
+ * Currently only uni-processor mode is supported for BSD.
+ *
+ * BSD code by Andy Fawcett <andy@athame.co.uk> and
+ * Robbie Ward <linuxphreak@gmx.co.uk>, licensed under GPL2.
+ *
+ * Other Operating Systems
+ * -----------------------
+ *
+ * Please, send in a patch!
+ *
+ * The KCPULoad maintainer is currently Ben Burton <bab@debian.org>, or
+ * you could submit a patch through the KDE bug tracking system
+ * (bugs.kde.org).
+ */
+
+KCPUProc::CPU::Ticks::Ticks() :
+ U(0), S(0), N(0), I(0)
+{ }
+
+KCPUProc::KCPUProc() {
+ smp = false;
+
+ // Look for SMP support and take a current tick reading.
+
+ // ========== BSD-specific (begin) ==========
+#ifdef Q_OS_BSD4
+ readLoad();
+ return;
+#endif
+ // ========== BSD-specific (end) ==========
+
+ // ========== Linux-specific (begin) ==========
+#ifdef Q_OS_LINUX
+ if ((fd = fopen("/proc/stat", "r")) == 0)
+ return;
+
+ if (!all.parse(fd))
+ return;
+ CPU c;
+ while (c.parse(fd))
+ cpu.push_back(c);
+ smp = cpu.size() > 1;
+#endif
+ // ========== Linux-specific (end) ==========
+}
+
+void KCPUProc::readLoad() {
+ // OS-specific local variables.
+
+ // ========== Linux-specific (begin) ==========
+#ifdef Q_OS_LINUX
+ // Prepare to take the readings.
+
+ if ((fd = fopen("/proc/stat", "r")) == 0)
+ return;
+
+ // Take a fresh set of current readings (SMP mode).
+
+ all.parse(fd);
+ for (int i = 0; i < cpu.size(); i++) {
+ if (!cpu[i].parse(fd))
+ break;
+ }
+
+ // Clean up after taking readings.
+
+ fclose(fd);
+#endif
+ // ========== Linux-specific (end) ==========
+
+ // ========== BSD-specific (begin) ==========
+#ifdef Q_OS_BSD4
+ static int name2oid[2] = { 0, 3 };
+ static int oidCpuTime[CTL_MAXNAME + 2];
+ static size_t oidCpuTimeLen = sizeof(oidCpuTime);
+ long cpuTime[CPUSTATES];
+ unsigned int cpuTimeLen = sizeof(cpuTime);
+ static char *name = "kern.cp_time";
+ static int initialized = 0;
+
+ if(smp) {
+ // Take a fresh set of current readings (SMP mode).
+ // TODO: Add SMP support for BSD.
+ } else {
+ // Take a fresh set of current readings (uni-processor mode).
+
+ // The current readings must now become the previous readings.
+ all.p = all.c;
+
+ if (! initialized) {
+ if (sysctl(name2oid, 2, oidCpuTime, &oidCpuTimeLen, name,
+ strlen(name)) < 0)
+ return;
+
+ oidCpuTimeLen /= sizeof(int);
+ initialized = 1;
+ }
+
+ if (sysctl(oidCpuTime, oidCpuTimeLen, cpuTime, &cpuTimeLen, 0, 0) < 0)
+ return;
+
+ all.c.U = cpuTime[CP_USER];
+ all.c.N = cpuTime[CP_NICE];
+ all.c.S = cpuTime[CP_SYS];
+ all.c.I = cpuTime[CP_IDLE];
+ }
+#endif
+ // ========== BSD-specific (end) ==========
+}
+
+// ========== Linux-specific (begin) ==========
+#ifdef Q_OS_LINUX
+bool KCPUProc::CPU::parse(FILE* fd) {
+ char tagbuffer[32];
+ Ticks n; // new ticks
+ if (fscanf(fd, "%32s%d%d%d%d", tagbuffer, &n.U, &n.N, &n.S, &n.I) != 5) {
+ return false; // failure
+ }
+
+ if (strncmp(tagbuffer, "cpu", 3) != 0) {
+ return false; // tag mismatch
+ }
+
+ // shift readings
+ p = c;
+ c = n;
+
+ // ignore the rest of the line
+ int ch;
+ do {
+ ch = getc(fd);
+ } while (ch != '\n' && ch != EOF);
+ return true;
+}
+#endif
+// ========== Linux-specific (end) ==========
diff --git a/kcpuload/kcpuload/kcpuproc.h b/kcpuload/kcpuload/kcpuproc.h
new file mode 100644
index 0000000..5631a72
--- /dev/null
+++ b/kcpuload/kcpuload/kcpuproc.h
@@ -0,0 +1,170 @@
+
+/***************************************************************************
+ * *
+ * KCPULoad is copyright (c) 1999-2000, Markus Gustavsson *
+ * (c) 2002, Ben Burton *
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef __KCPUPROC_H
+#define __KCPUPROC_H
+
+#include <cstdio>
+#include <qglobal.h>
+#include <vector>
+
+/**
+ * A class used to read raw CPU load details from the system.
+ *
+ * See kcpuproc.cpp for details of supported operating systems.
+ */
+class KCPUProc {
+public:
+ /**
+ * Constructor.
+ *
+ * In the constructor, a set of initial CPU tick readings are taken
+ * and SMP support is determined.
+ */
+ KCPUProc();
+
+ /**
+ * Does this system appear to have SMP?
+ */
+ bool hasSMP() const;
+
+ /**
+ * Takes a fresh set of CPU tick readings. The numerical statistics
+ * returned refer to the time period between this reading and the
+ * previous (or between this reading and the object's construction
+ * if there was no previous reading).
+ */
+ void readLoad();
+
+ /**
+ * Contains tick differences for a CPU.
+ */
+ struct CPU {
+ /**
+ * Contains user/system/nice/idle tick readings.
+ */
+ struct Ticks {
+ int U, S, N, I;
+ Ticks();
+ /** Returns user ticks */
+ int u() const { return U; }
+ /** Returns system ticks */
+ int s() const { return S + N; }
+ /** Returns total (non-idle) ticks */
+ int t() const { return U + S + N; }
+ /** Returns elapsed ticks */
+ int e() const { return U + S + N + I; }
+ };
+
+ Ticks p; /**< The previous tick readings */
+ Ticks c; /**< The last (most recent) tick readings */
+
+ /**
+ * The percentage of ticks between the last reading and the previous
+ * reading used by the user loop (compared to the nice, system and
+ * idle loops).
+ *
+ * This routine involves a short arithmetical calculation.
+ * If you're paranoid about running time, you might want to cache
+ * the result.
+ */
+ int userPercent() const;
+
+ /**
+ * The percentage of ticks between the last reading and the previous
+ * reading used by the system and nice loops (compared to the user and
+ * idle loops).
+ *
+ * This routine involves a short arithmetical calculation.
+ * If you're paranoid about running time, you might want to cache
+ * the result.
+ */
+ int systemPercent() const;
+
+ /**
+ * The percentage of ticks between the last reading and the previous
+ * reading used by the user, system and nice loops (compared to the
+ * idle loop).
+ *
+ * This routine involves a short arithmetical calculation.
+ * If you're paranoid about running time, you might want to cache
+ * the result.
+ */
+ int totalPercent() const;
+
+ /**
+ * OS-specific helper routines.
+ */
+
+ // ========== Linux-specific (begin) ==========
+#ifdef Q_OS_LINUX
+ /**
+ * Parses the tick readings of the current line in #fd.
+ * The return value is \c false if the line does not begin with
+ * the tag "cpu" (optionally followed by a number).
+ * If the line can be parsed successfully, the last reading becomes
+ * the previous reading and the newly parsed reading becomes
+ * the last reading.
+ */
+ bool parse(FILE* fd);
+#endif
+ // ========== Linux-specific (end) ==========
+ };
+
+ /*
+ * Variables used in all modes.
+ */
+ CPU all; /**< Tick readings for all CPUs. */
+
+ /*
+ * Variables used only with SMP.
+ */
+ std::vector<CPU> cpu; /**< Tick readings for CPUs. */
+
+private:
+ /*
+ * SMP support.
+ */
+ bool smp;
+ /**< Does this system appear to have SMP? */
+
+ /**
+ * OS-specific data members.
+ */
+
+ // ========== Linux-specific (begin) ==========
+#ifdef Q_OS_LINUX
+ FILE *fd;
+ /**< The file /proc/stat. */
+#endif
+ // ========== Linux-specific (end) ==========
+};
+
+inline bool KCPUProc::hasSMP() const {
+ return smp;
+}
+
+inline int KCPUProc::CPU::userPercent() const {
+ int tot = c.e() - p.e();
+ return (tot > 0 ? (100 * (c.u() - p.u())) / tot : 0);
+}
+inline int KCPUProc::CPU::systemPercent() const {
+ int tot = c.e() - p.e();
+ return (tot > 0 ? (100 * (c.s() - p.s())) / tot : 0);
+}
+inline int KCPUProc::CPU::totalPercent() const {
+ int tot = c.e() - p.e();
+ return (tot > 0 ? (100 * (c.t() - p.t())) / tot : 0);
+}
+
+#endif
diff --git a/kcpuload/kcpuload/lo16-app-kcpuload.png b/kcpuload/kcpuload/lo16-app-kcpuload.png
new file mode 100644
index 0000000..edb85a8
--- /dev/null
+++ b/kcpuload/kcpuload/lo16-app-kcpuload.png
Binary files differ
diff --git a/kcpuload/kcpuload/lo32-app-kcpuload.png b/kcpuload/kcpuload/lo32-app-kcpuload.png
new file mode 100644
index 0000000..70f5459
--- /dev/null
+++ b/kcpuload/kcpuload/lo32-app-kcpuload.png
Binary files differ
diff --git a/kcpuload/kcpuload/main.cpp b/kcpuload/kcpuload/main.cpp
new file mode 100644
index 0000000..1be5ad3
--- /dev/null
+++ b/kcpuload/kcpuload/main.cpp
@@ -0,0 +1,64 @@
+
+/***************************************************************************
+ * *
+ * KCPULoad is copyright (c) 1999-2000, Markus Gustavsson *
+ * (c) 2002, Ben Burton *
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "kcpuload.h"
+
+#include <kaboutdata.h>
+#include <kcmdlineargs.h>
+#include <klocale.h>
+#include <kuniqueapplication.h>
+
+static const char *description =
+ I18N_NOOP("A small CPU usage meter for Kicker (the KDE panel).");
+static const char *message =
+ I18N_NOOP("KCPULoad was first released on the 8th of August, 1999.");
+static const char *version = "2.00";
+
+int main(int argc, char **argv) {
+ KAboutData aboutData("kcpuload", I18N_NOOP("KCPULoad"), version,
+ description, KAboutData::License_GPL,
+ "(c) 1999-2000, Markus Gustavsson\n"
+ "(c) 2002, Ben Burton\n"
+ "(c) 2009, Timothy Pearson",
+ message, 0 /* TODO: Website */, "bab@debian.org");
+
+ aboutData.addAuthor("Markus Gustavsson", "Original author",
+ "mighty@fragzone.se");
+ aboutData.addAuthor("Ben Burton", "KDE3 rewrite, current maintainer",
+ "bab@debian.org");
+ aboutData.addAuthor("Andy Fawcett", "BSD support",
+ "andy@athame.co.uk");
+ aboutData.addAuthor("Robbie Ward", "BSD support",
+ "linuxphreak@gmx.co.uk");
+
+ aboutData.addCredit("Njaard, Charles Samuels",
+ "Support and help with KDE", "charles@kde.org");
+ aboutData.addCredit("rikkus, Rik Hemsley",
+ "Support and help with KDE", "rik@kde.org");
+ aboutData.addCredit("Mark Halpaap",
+ "Independent port to KDE3", "mark.halpaap@gmx.net");
+ aboutData.addCredit("Thanks to everyone in #KDE OpenProjects for "
+ "being supportive and helpful!");
+
+ KCmdLineArgs::init(argc, argv, &aboutData);
+ KUniqueApplication::addCmdLineOptions();
+
+ if (! KUniqueApplication::start()) {
+ fprintf(stderr, I18N_NOOP("KCPULoad is already running!\n"));
+ return 1;
+ }
+
+ KUniqueApplication app;
+ app.setMainWidget(new KCPULoad());
+ return app.exec();
+}
diff --git a/kcpuload/kcpuload/speeddialog.cpp b/kcpuload/kcpuload/speeddialog.cpp
new file mode 100644
index 0000000..0d0588a
--- /dev/null
+++ b/kcpuload/kcpuload/speeddialog.cpp
@@ -0,0 +1,63 @@
+
+/***************************************************************************
+ * *
+ * KCPULoad and KNetLoad are copyright (c) 1999-2000, Markus Gustavsson *
+ * (c) 2002, Ben Burton *
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "speeddialog.h"
+
+#include <cstdlib>
+#include <kcombobox.h>
+#include <klocale.h>
+#include <qlabel.h>
+#include <qhbox.h>
+#include <qvalidator.h>
+
+static int stockSpeed[] = {
+ 100, 150, 200, 250, 300, 400, 600, 800, 1000, 1200, 1500, 2000, 2500,
+ 3000, 4000, 5000, 0
+};
+
+SpeedDialog::SpeedDialog(int defaultSpeed, QWidget* parent) :
+ KDialogBase(parent, "speed dialog", true,
+ i18n("Select Speed"), Ok|Cancel, Ok),
+ speed(defaultSpeed) {
+ QHBox* page = makeHBoxMainWidget();
+
+ new QLabel(i18n("Update interval in milliseconds:"), page);
+
+ KComboBox* speedBox = new KComboBox(true, page);
+
+ QIntValidator* val = new QIntValidator(this);
+ val->setBottom(1);
+ speedBox->setValidator(val);
+
+ QString speedStr;
+ for (int i = 0; stockSpeed[i]; i++) {
+ speedStr.setNum(stockSpeed[i]);
+ speedBox->insertItem(speedStr);
+ }
+
+ speedStr.setNum(defaultSpeed);
+ speedBox->setCurrentText(speedStr);
+
+ connect(speedBox, SIGNAL(textChanged(const QString&)),
+ this, SLOT(updateSpeed(const QString&)));
+}
+
+int SpeedDialog::getSpeed() const {
+ return speed;
+}
+
+void SpeedDialog::updateSpeed(const QString& text) {
+ speed = atoi(text.ascii());
+}
+
+#include "speeddialog.moc"
diff --git a/kcpuload/kcpuload/speeddialog.h b/kcpuload/kcpuload/speeddialog.h
new file mode 100644
index 0000000..491a6be
--- /dev/null
+++ b/kcpuload/kcpuload/speeddialog.h
@@ -0,0 +1,49 @@
+
+/***************************************************************************
+ * *
+ * KCPULoad and KNetLoad are copyright (c) 1999-2000, Markus Gustavsson *
+ * (c) 2002, Ben Burton *
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef __SPEEDDIALOG_H
+#define __SPEEDDIALOG_H
+
+#include <kdialogbase.h>
+
+/**
+ * A dialog used to select the update speed for a StatPopup.
+ */
+class SpeedDialog : public KDialogBase {
+ Q_OBJECT
+
+ public:
+ /**
+ * Constructor.
+ */
+ SpeedDialog(int defaultSpeed, QWidget* parent);
+
+ /**
+ * Returns the speed currently selected in the dialog.
+ * This is valid after the dialog has closed.
+ */
+ int getSpeed() const;
+
+ private slots:
+ /**
+ * Updates the speed variable to reflect the latest changes in
+ * the speed combo box.
+ */
+ virtual void updateSpeed(const QString&);
+
+ private:
+ int speed;
+ /**< The speed currently selected in the speed combo box. */
+};
+
+#endif
diff --git a/kcpuload/kcpuload/statdock.cpp b/kcpuload/kcpuload/statdock.cpp
new file mode 100644
index 0000000..95a13c5
--- /dev/null
+++ b/kcpuload/kcpuload/statdock.cpp
@@ -0,0 +1,244 @@
+
+/***************************************************************************
+ * *
+ * KCPULoad and KNetLoad are copyright (c) 1999-2000, Markus Gustavsson *
+ * (c) 2002, Ben Burton *
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "statdock.h"
+#include "statpopup.h"
+#include <qpainter.h>
+
+const int StatDock::fillLines = 0;
+const int StatDock::fillBars = 1;
+const int StatDock::fillShaded = 2;
+
+const QColor StatDock::colorGrid(120, 120, 120);
+const QColor StatDock::colorGridInactive(60, 60, 60);
+const QColor StatDock::colorLabel(255, 255, 255);
+const QColor StatDock::colorLabelInactive(125, 125, 125);
+const QColor StatDock::colorLower(255, 255, 255);
+const QColor StatDock::colorLowerInactive(125, 125, 125);
+const QColor StatDock::colorBlack(0, 0, 0);
+
+#define DOCK_SIZE 24
+#define DOCK_SCALE 4.34783 // Approx. 100/23.
+#define SOFT_STEP 3
+
+StatDock::StatDock(int whichDock, const QString& useLabel,
+ StatPopup *parent, const char *name) :
+ KSystemTray(parent,name),
+ label(useLabel),
+ bufUpper(new int[DOCK_SIZE]),
+ bufLower(new int[DOCK_SIZE]),
+ pos(0) {
+ // Initialise the stored readings.
+ for (i = 0; i < DOCK_SIZE; i++)
+ bufUpper[i] = bufLower[i] = 0;
+
+ // Initialise the display.
+ parent->initDock(this, contextMenu(), whichDock);
+ setBackgroundColor(colorBlack);
+ resize(24, 24);
+ show();
+}
+
+StatDock::~StatDock() {
+ delete[] bufUpper;
+ delete[] bufLower;
+}
+
+void StatDock::setGrid(bool set) {
+ grid = set;
+ repaint();
+}
+
+void StatDock::setActive(bool set) {
+ active = set;
+ repaint();
+}
+
+void StatDock::setSoft(bool set) {
+ soft = set;
+ repaint();
+}
+
+void StatDock::setSplit(bool set) {
+ split = set;
+ repaint();
+}
+
+void StatDock::setLabelled(bool set) {
+ labelled = set;
+ repaint();
+}
+
+void StatDock::setLabel(const QString& set) {
+ label = set;
+ repaint();
+}
+
+void StatDock::setFill(int set) {
+ fill = set;
+ repaint();
+}
+
+void StatDock::setColor(const QColor& set) {
+ colorUpper = set;
+ colorUpperInactive = colorUpper.dark();
+ repaint();
+}
+
+void StatDock::clearHistory(void) {
+ for (i = 0; i < DOCK_SIZE; i++)
+ bufUpper[i] = bufLower[i] = 0;
+ repaint();
+}
+
+void StatDock::addPercentReading(int upper, int lower) {
+ // Rescale the readings to a measure in pixels.
+ upper = (int) (((float) upper) / DOCK_SCALE);
+ lower = (split ? (int) (((float) lower) / DOCK_SCALE) : 0);
+
+ if (soft) {
+ // Do a bit of juggling to obtain a soft reading.
+ oldUpper = bufUpper[pos];
+ oldLower = bufLower[pos];
+ if(++pos >= DOCK_SIZE)
+ pos = 0;
+
+ // Modify the upper reading.
+ if (upper > oldUpper + SOFT_STEP)
+ upper = oldUpper + SOFT_STEP;
+ else if (upper < oldUpper - SOFT_STEP)
+ upper = oldUpper - SOFT_STEP;
+ bufUpper[pos] = upper;
+
+ // Modify the lower reading.
+ if (split) {
+ if (lower > oldLower + SOFT_STEP)
+ lower = oldLower + SOFT_STEP;
+ else if (lower < oldLower - SOFT_STEP)
+ lower = oldLower - SOFT_STEP;
+ }
+ bufLower[pos] = lower;
+ } else {
+ // Just a straight update.
+ if(++pos >= DOCK_SIZE)
+ pos = 0;
+ bufUpper[pos] = upper;
+ bufLower[pos] = lower;
+ }
+
+ // Refresh the diagram.
+ repaint();
+}
+
+void StatDock::paintEvent(QPaintEvent*) {
+ QPainter p(this);
+
+ // Start by drawing the grid.
+ if(grid) {
+ p.setPen((active) ? colorGrid : colorGridInactive);
+ p.drawLine(0, 4, 23, 4);
+ p.drawLine(0, 9, 23, 9);
+ p.drawLine(0, 14, 23, 14);
+ p.drawLine(0, 19, 23, 19);
+ }
+
+ if(fill == fillShaded) {
+ // Shaded
+ for(i = 0; i < 24; i++) {
+ tmpPos = (pos + i + 1) % DOCK_SIZE;
+ for(j = 0; j <= bufUpper[tmpPos]; j++) {
+ if (bufUpper[tmpPos] == 0 || j == 0)
+ p.setPen(colorBlack);
+ else if (active)
+ p.setPen(colorUpper.dark((100 * bufUpper[tmpPos]) / j));
+ else
+ p.setPen(colorUpper.dark((200 * bufUpper[tmpPos]) / j));
+
+ if(split)
+ p.drawPoint(i, DOCK_SIZE - 1 - j - bufLower[tmpPos]);
+ else
+ p.drawPoint(i, DOCK_SIZE - j);
+ }
+
+ if(split) {
+ for(j = 0; j <= bufLower[tmpPos]; j++) {
+ if (bufLower[tmpPos] == 0 || j == 0)
+ p.setPen(colorBlack);
+ else if (active)
+ p.setPen(colorLower.dark((100 * bufLower[tmpPos]) / j));
+ else
+ p.setPen(colorLower.dark((200 * bufLower[tmpPos]) / j));
+
+ p.drawPoint(i, 23 - j);
+ }
+ }
+ }
+ } else if (fill == fillBars) {
+ // Bars
+ if(split) {
+ // Draw the upper bars, then the lower to save on pen
+ // adjustments.
+ p.setPen(active ? colorUpper : colorUpperInactive);
+ for(i = 0; i < 24; i++) {
+ tmpPos = (pos + i + 1) % DOCK_SIZE;
+ p.drawLine(i, DOCK_SIZE - 1 - bufUpper[tmpPos] -
+ bufLower[tmpPos], i, DOCK_SIZE - 1 - bufLower[tmpPos]);
+ }
+ p.setPen(active ? colorLower : colorLowerInactive);
+ for(i = 0; i < 24; i++) {
+ tmpPos = (pos + i + 1) % DOCK_SIZE;
+ p.drawLine(i, DOCK_SIZE - 1 - bufLower[tmpPos],
+ i, DOCK_SIZE - 1);
+ }
+ } else {
+ p.setPen(active ? colorUpper : colorUpperInactive);
+ for(i = 0; i < 24; i++) {
+ tmpPos = (pos + i + 1) % DOCK_SIZE;
+ p.drawLine(i, DOCK_SIZE - 1 - bufUpper[tmpPos],
+ i, DOCK_SIZE - 1);
+ }
+ }
+ } else {
+ // Lines
+ if(split) {
+ // Draw the upper line, then the lower to save on pen
+ // adjustments.
+ p.setPen(active ? colorUpper : colorUpperInactive);
+ for(i = 0; i < 24; i++) {
+ tmpPos = (pos + i + 1) % DOCK_SIZE;
+ p.drawPoint(i, DOCK_SIZE - 1 -
+ bufUpper[tmpPos] - bufLower[tmpPos]);
+ }
+ p.setPen(active ? colorLower : colorLowerInactive);
+ for(i = 0; i < 24; i++) {
+ tmpPos = (pos + i + 1) % DOCK_SIZE;
+ p.drawPoint(i, DOCK_SIZE - 1 - bufLower[tmpPos]);
+ }
+ } else {
+ p.setPen(active ? colorUpper : colorUpperInactive);
+ for(i = 0; i < 24; i++) {
+ tmpPos = (pos + i + 1) % DOCK_SIZE;
+ p.drawPoint(i, DOCK_SIZE - 1 - bufUpper[tmpPos]);
+ }
+ }
+ }
+
+ // Finally label the diagrams.
+ if(labelled) {
+ p.setFont(QFont("Helvetica", 8));
+ p.setPen((active) ? colorLabel : colorLabelInactive);
+ p.drawText(rect(), AlignLeft | AlignTop, label);
+ }
+}
+
+#include "statdock.moc"
diff --git a/kcpuload/kcpuload/statdock.h b/kcpuload/kcpuload/statdock.h
new file mode 100644
index 0000000..a9eb256
--- /dev/null
+++ b/kcpuload/kcpuload/statdock.h
@@ -0,0 +1,160 @@
+
+/***************************************************************************
+ * *
+ * KCPULoad and KNetLoad are copyright (c) 1999-2000, Markus Gustavsson *
+ * (c) 2002, Ben Burton *
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef __STATDOCK_H
+#define __STATDOCK_H
+
+#include <qcolor.h>
+#include <ksystemtray.h>
+
+class StatPopup;
+
+/**
+ * A system tray window that displays a recent history of readings.
+ * A single application might have many of these windows.
+ *
+ * Two simultaneous sets of readings are supported; these will be
+ * referred to as upper and lower readings. When diagram splitting is
+ * switched on, these readings will be displayed together on the diagram
+ * with the upper readings shown above the lower readings. When diagram
+ * splitting is switched off, only the upper readings will be displayed.
+ *
+ * The parent window of a StatDock must be a StatPopup, which provides
+ * all of the actions in this window's context menu.
+ */
+class StatDock : public KSystemTray {
+ Q_OBJECT
+
+public:
+ /**
+ * Fill style constants.
+ */
+ static const int fillLines;
+ static const int fillBars;
+ static const int fillShaded;
+
+ /**
+ * Colour constants.
+ */
+ static const QColor colorGrid;
+ static const QColor colorGridInactive;
+ static const QColor colorLabel;
+ static const QColor colorLabelInactive;
+ static const QColor colorLower;
+ static const QColor colorLowerInactive;
+ static const QColor colorBlack;
+
+public:
+ /**
+ * Constructor and destructor.
+ *
+ * Note that the constructor will call parent->initDock().
+ *
+ * Parameter whichDock must be 0 or 1 to specify whether this dock
+ * will become dock[0] or dock[1] in the given StatPopup parent.
+ * Parameter useLabel should contain the label that will be drawn on
+ * the diagram if labelling is enabled.
+ */
+ StatDock(int whichDock, const QString& useLabel, StatPopup *parent,
+ const char *name = 0);
+ ~StatDock();
+
+ /**
+ * Setting display options.
+ */
+ void setGrid(bool);
+ void setActive(bool);
+ void setSoft(bool);
+ void setSplit(bool);
+ void setLabelled(bool);
+ void setLabel(const QString&);
+ void setFill(int);
+ void setColor(const QColor&);
+
+public slots:
+ /**
+ * Clear the history of recent readings.
+ * All readings will be reset to zero and the diagram will be
+ * updated.
+ */
+ void clearHistory();
+
+ /**
+ * Add the given pair of readings as the most recent in our list.
+ * The diagram will be updated accordingly.
+ *
+ * Each argument should be a percentage between 0 and 100.
+ * The sum of both arguments must not exceed 100.
+ *
+ * If diagram splitting is switched off, the given lower reading
+ * will be ignored completely and 0 will be used instead.
+ *
+ * @param upper the upper reading in this pair.
+ * @param lower the lower reading in this pair.
+ */
+ void addPercentReading(int upper, int lower);
+
+private:
+ /**
+ * Repaint this system tray window with a fresh diagram.
+ */
+ void paintEvent(QPaintEvent*);
+
+private:
+ /**
+ * Display options.
+ */
+ bool grid;
+ /**< Should the grid be displayed behind the diagram? */
+ bool active;
+ /**< Is this meter currently active? */
+ bool soft;
+ /**< Are we artificially modifying the readings to produce a
+ soft curve? */
+ bool split;
+ /**< Are we displaying both upper and lower readings? */
+ bool labelled;
+ /**< Should this diagram be labelled? */
+ QString label;
+ /**< The specific label to draw on this diagram. */
+ int fill;
+ /**< Specifies which of the predefined fill styles to use. */
+ QColor colorUpper;
+ /**< Colour for displaying the upper readings. */
+ QColor colorUpperInactive;
+ /**< Colour for displaying the upper readings whilst the diagram
+ is inactive. */
+
+ /**
+ * Stored readings.
+ */
+ int* bufUpper;
+ /**< Stores our list of recent upper readings.
+ This list begins at index (pos + 1) as the earliest reading
+ and cycles around to index (pos) as the latest reading. */
+ int* bufLower;
+ /**< Stores our list of recent lower readings.
+ This list begins at index (pos + 1) as the earliest reading
+ and cycles around to index (pos) as the latest reading. */
+ int pos;
+ /**< The index in our arrays of the most recent reading. */
+
+
+ /**
+ * Temporaries.
+ */
+ int i, j, tmpPos, oldUpper, oldLower;
+ /**< Temporary variables used during computations. */
+};
+
+#endif
diff --git a/kcpuload/kcpuload/statpopup.cpp b/kcpuload/kcpuload/statpopup.cpp
new file mode 100644
index 0000000..f6e7b4d
--- /dev/null
+++ b/kcpuload/kcpuload/statpopup.cpp
@@ -0,0 +1,485 @@
+
+/***************************************************************************
+ * *
+ * KCPULoad and KNetLoad are copyright (c) 1999-2000, Markus Gustavsson *
+ * (c) 2002, Ben Burton *
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "icontoggleaction.h"
+#include "speeddialog.h"
+#include "statdock.h"
+#include "statpopup.h"
+
+#include <qpainter.h>
+#include <qtimer.h>
+#include <kaction.h>
+#include <kcolordialog.h>
+#include <kconfig.h>
+#include <kdebug.h>
+#include <kglobal.h>
+#include <khelpmenu.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kpopupmenu.h>
+#include <kwin.h>
+#include <cstdlib>
+
+#define DEFAULT_SPEED 1000
+#define TEXT_EXPANSION_HORIZONTAL 10
+#define TEXT_EXPANSION_VERTICAL 3
+
+const QColor StatPopup::colorBorder(0, 0, 0);
+
+StatPopup::Reading::Reading() :
+ dock(0),
+ actColor(0)
+{ }
+
+StatPopup::Reading::~Reading()
+{
+ delete actColor;
+ delete dock;
+}
+
+void StatPopup::Reading::Init(int which, StatPopup* popup)
+{
+ char colorid[30];
+ sprintf(colorid, "Color%d", which);
+
+ color = popup->defaultDockColor(which);
+ color = popup->config->readColorEntry(colorid, &color);
+ actColor = new KAction(i18n("Color (%1)...").arg(popup->dockName(which)),
+ "color", 0, popup, SLOT(selectColor()), popup->coll, colorid);
+}
+
+
+StatPopup::StatPopup(bool useSupportSplit, QWidget *parent, const char *name) :
+ QWidget(parent, name, Qt::WStyle_Customize | Qt::WStyle_NoBorder |
+ Qt::WStyle_StaysOnTop | Qt::WDestructiveClose | Qt::WType_TopLevel),
+ supportSplit(useSupportSplit) {
+ // Window management.
+ KWin::setState(winId(), NET::SkipTaskbar | NET::SkipPager);
+
+ // TODO: Get all-desktops working, even after a hide/reshow.
+ //KWin::setOnAllDesktops(winId(), true);
+
+ // Basic variable initialisation.
+ relX = relY = 0;
+ isDragged = closing = false;
+
+ // Initialise the text contents of this pop-up.
+ fullReading = i18n("Inactive.");
+ resizeToText();
+
+ // Prepare for actions and the config file, but don't actually add
+ // any actions or read the configuration.
+ config = KGlobal::config();
+ coll = new KActionCollection(this);
+
+ // Set up a timer for our periodic updates.
+ timer = new QTimer(this);
+ connect(timer, SIGNAL(timeout()), this, SLOT(takeReading()));
+}
+
+StatPopup::~StatPopup() {
+}
+
+void StatPopup::readPopupState() {
+ config->setGroup("Popup Options");
+
+ // Read the position.
+ int useX = config->readNumEntry("PopupX", 0);
+ int useY = config->readNumEntry("PopupY", 0);
+ if (useX || useY)
+ move(useX, useY);
+
+ // Show the pop-up if appropriate.
+ if (config->readBoolEntry("PopupActive", false))
+ show();
+ else
+ hide();
+}
+
+void StatPopup::savePopupState() {
+ config->setGroup("Popup Options");
+ config->writeEntry("PopupActive", isVisible());
+ config->writeEntry("PopupX", x());
+ config->writeEntry("PopupY", y());
+ config->sync();
+}
+
+void StatPopup::initDock(StatDock* target, KPopupMenu* menu, int whichDock) {
+ // Initialise the menus.
+ actActive->plug(menu);
+ actClearHistory->plug(menu);
+ menu->insertSeparator();
+ actSpeed->plug(menu);
+ if (supportSplit)
+ actSplit->plug(menu);
+ menu->insertSeparator();
+
+ insertCustomItems(menu);
+
+ KPopupMenu* fillMenu = new KPopupMenu(menu);
+ actFillLines->plug(fillMenu);
+ actFillBars->plug(fillMenu);
+ actFillShaded->plug(fillMenu);
+ menu->insertItem(SmallIcon("style"), i18n("St&yle"), fillMenu);
+
+ actSoft->plug(menu);
+ actLabelled->plug(menu);
+ actGrid->plug(menu);
+ r[whichDock].actColor->plug(menu);
+ menu->insertSeparator();
+ menu->insertItem(SmallIcon("help"), i18n("&Help"),
+ (new KHelpMenu(0, KGlobal::instance()->aboutData(), false))->menu());
+
+ // Set up display properties for the dock.
+ target->setActive(actActive->isChecked());
+ target->setSplit(isSplit());
+ target->setFill(fillStyle);
+ target->setSoft(actSoft->isChecked());
+ target->setLabelled(actLabelled->isChecked());
+ target->setGrid(actGrid->isChecked());
+ target->setColor(r[whichDock].color);
+ setCustomProperties(target);
+}
+
+bool StatPopup::isActive() const {
+ return actActive->isChecked();
+}
+
+bool StatPopup::isSplit() const {
+ return (supportSplit ? actSplit->isChecked() : false);
+}
+
+void StatPopup::setActive(bool set) {
+ if (set)
+ startUpdates();
+ else
+ stopUpdates();
+
+ for (int i = 0; i < r.size(); i++) {
+ r[i].dock->setActive(set);
+ }
+
+ config->setGroup("General Options");
+ config->writeEntry("Active", set);
+ config->sync();
+}
+
+void StatPopup::clearHistory() {
+ for (int i = 0; i < r.size(); i++) {
+ r[i].dock->clearHistory();
+ }
+}
+
+void StatPopup::selectSpeed() {
+ SpeedDialog dlg(speed, firstDock());
+ if (dlg.exec()) {
+ int newSpeed = dlg.getSpeed();
+ if (newSpeed > 0) {
+ speed = newSpeed;
+ if (timer->isActive())
+ timer->changeInterval(speed);
+
+ config->setGroup("General Options");
+ config->writeEntry("Speed", speed);
+ config->sync();
+ }
+ }
+}
+
+void StatPopup::setSplit(bool set) {
+ if (! supportSplit)
+ return;
+
+ for (int i = 0; i < r.size(); i++) {
+ r[i].dock->setSplit(set);
+ }
+
+ requestResize();
+
+ config->setGroup("General Options");
+ config->writeEntry("Split", set);
+ config->sync();
+}
+
+void StatPopup::setFillLines() {
+ fillStyle = StatDock::fillLines;
+
+ actFillLines->setChecked(true);
+ actFillBars->setChecked(false);
+ actFillShaded->setChecked(false);
+
+ for (int i = 0; i < r.size(); i++) {
+ r[i].dock->setFill(StatDock::fillLines);
+ }
+
+ config->setGroup("General Options");
+ config->writeEntry("StyleID", StatDock::fillLines);
+ config->sync();
+}
+
+void StatPopup::setFillBars() {
+ fillStyle = StatDock::fillBars;
+
+ actFillLines->setChecked(false);
+ actFillBars->setChecked(true);
+ actFillShaded->setChecked(false);
+
+ for (int i = 0; i < r.size(); i++) {
+ r[i].dock->setFill(StatDock::fillBars);
+ }
+
+ config->setGroup("General Options");
+ config->writeEntry("StyleID", StatDock::fillBars);
+ config->sync();
+}
+
+void StatPopup::setFillShaded() {
+ fillStyle = StatDock::fillShaded;
+
+ actFillLines->setChecked(false);
+ actFillBars->setChecked(false);
+ actFillShaded->setChecked(true);
+
+ for (int i = 0; i < r.size(); i++) {
+ r[i].dock->setFill(StatDock::fillShaded);
+ }
+
+ config->setGroup("General Options");
+ config->writeEntry("StyleID", StatDock::fillShaded);
+ config->sync();
+}
+
+void StatPopup::setSoft(bool set) {
+ for (int i = 0; i < r.size(); i++) {
+ r[i].dock->setSoft(set);
+ }
+
+ config->setGroup("General Options");
+ config->writeEntry("Soft", set);
+ config->sync();
+}
+
+void StatPopup::setLabelled(bool set) {
+ for (int i = 0; i < r.size(); i++) {
+ r[i].dock->setLabelled(set);
+ }
+
+ config->setGroup("General Options");
+ config->writeEntry("Labelled", set);
+ config->sync();
+}
+
+void StatPopup::setGrid(bool set) {
+ for (int i = 0; i < r.size(); i++) {
+ r[i].dock->setGrid(set);
+ }
+
+ config->setGroup("General Options");
+ config->writeEntry("Grid", set);
+ config->sync();
+}
+
+void StatPopup::selectColor() {
+ // which color?
+ int whichDock;
+ if (sscanf(sender()->name(), "Color%d", &whichDock) != 1)
+ return;
+ if (whichDock < 0 || whichDock >= r.size())
+ return;
+
+ if (r[whichDock].dock) {
+ QColor ans;
+ if (KColorDialog::getColor(ans, r[whichDock].color, firstDock()) ==
+ QDialog::Accepted) {
+ r[whichDock].color = ans;
+ r[whichDock].dock->setColor(ans);
+
+ config->setGroup("General Options");
+ QString n;
+ n.sprintf("Color%d", whichDock);
+ config->writeEntry(n, ans);
+ config->sync();
+ }
+ }
+}
+
+StatDock* StatPopup::firstDock() {
+ return r.size() > 0 ? r[0].dock : 0;
+}
+
+void StatPopup::startUpdates() {
+ takeReading();
+ timer->start(speed);
+}
+
+void StatPopup::stopUpdates() {
+ timer->stop();
+ fullReading = i18n("Inactive.");
+}
+
+void StatPopup::setupActions() {
+ config->setGroup("General Options");
+ bool bVal;
+
+ bVal = config->readBoolEntry("Active", true);
+ actActive = new KToggleAction(i18n("&Active"), 0, coll, "active");
+ actActive->setChecked(bVal);
+ connect(actActive, SIGNAL(toggled(bool)), this, SLOT(setActive(bool)));
+
+ actClearHistory = new KAction(i18n("&Clear"), "editdelete", 0,
+ this, SLOT(clearHistory()), coll, "clear");
+
+ speed = config->readNumEntry("Speed", DEFAULT_SPEED);
+ actSpeed = new KAction(i18n("&Speed..."), "speedarrow", 0,
+ this, SLOT(selectSpeed()), coll, "speed");
+
+ if (supportSplit) {
+ bVal = config->readBoolEntry("Split", true);
+ actSplit = new IconToggleAction(i18n("Sp&lit Graph"), "split",
+ i18n("Graph Sp&litting Enabled"), "spliton", 0, coll, "split");
+ actSplit->setChecked(bVal);
+ connect(actSplit, SIGNAL(toggled(bool)), this, SLOT(setSplit(bool)));
+ }
+
+ fillStyle = config->readNumEntry("StyleID", StatDock::fillShaded);
+ actFillLines = new IconToggleAction(i18n("&Lines"), "lines", "lineson", 0,
+ this, SLOT(setFillLines()), coll, "filllines");
+ actFillLines->setChecked(fillStyle == StatDock::fillLines);
+ actFillBars = new IconToggleAction(i18n("&Bars"), "bars", "barson", 0,
+ this, SLOT(setFillBars()), coll, "fillbars");
+ actFillBars->setChecked(fillStyle == StatDock::fillBars);
+ actFillShaded = new IconToggleAction(i18n("&Shaded"), "shaded", "shadedon",
+ 0, this, SLOT(setFillShaded()), coll, "fillshaded");
+ actFillShaded->setChecked(fillStyle == StatDock::fillShaded);
+
+ bVal = config->readBoolEntry("Soft", false);
+ actSoft = new IconToggleAction(i18n("So&ft Curves"), "soft",
+ i18n("So&ft Curves Enabled"), "softon", 0, coll, "soft");
+ actSoft->setChecked(bVal);
+ connect(actSoft, SIGNAL(toggled(bool)), this, SLOT(setSoft(bool)));
+
+ bVal = config->readBoolEntry("Labelled", true);
+ actLabelled= new IconToggleAction(i18n("Show &Labels"), "labels",
+ i18n("&Labels Enabled"), "labelson", 0, coll, "labelled");
+ actLabelled->setChecked(bVal);
+ connect(actLabelled, SIGNAL(toggled(bool)), this, SLOT(setLabelled(bool)));
+
+ bVal = config->readBoolEntry("Grid", true);
+ actGrid = new IconToggleAction(i18n("Show &Grid"), "grid",
+ i18n("&Grid Enabled"), "gridon", 0, coll, "grid");
+ actGrid->setChecked(bVal);
+ connect(actGrid, SIGNAL(toggled(bool)), this, SLOT(setGrid(bool)));
+
+ setupCustomActions();
+}
+
+void StatPopup::paintEvent(QPaintEvent*) {
+ QPainter p(this);
+
+ // Draw the border.
+ p.setPen(colorBorder);
+ p.drawLine(0, 0, width(), 0);
+ p.drawLine(0, 1, width(), 1);
+ p.drawLine(0, 2, 0, height());
+ p.drawLine(1, 2, 1, height());
+ p.drawLine(width() - 2, 2, width() - 2, height());
+ p.drawLine(width() - 1, 2, width() - 1, height());
+ p.drawLine(2, height() - 2, width() - 2, height() - 2);
+ p.drawLine(2, height() - 1, width() - 2, height() - 1);
+
+ // Draw the text.
+ p.setFont(font());
+ p.setPen(colorGroup().foreground());
+ p.drawText(rect(), AlignHCenter | AlignVCenter, fullReading);
+}
+
+void StatPopup::mousePressEvent(QMouseEvent* e) {
+ if(e->button() == RightButton) {
+ // Hide the pop-up.
+ hide();
+ } else {
+ // Begin a drag operation.
+ isDragged = true;
+ relX = e->x();
+ relY = e->y();
+ repaint();
+ }
+}
+
+void StatPopup::mouseMoveEvent(QMouseEvent* e) {
+ // In the middle of a drag operation.
+ move(e->globalX() - relX, e->globalY() - relY);
+}
+
+void StatPopup::mouseReleaseEvent(QMouseEvent* e) {
+ // The end of a drag operation.
+ move(e->globalX() - relX, e->globalY() - relY);
+ isDragged = false;
+ repaint();
+}
+
+void StatPopup::closeEvent(QCloseEvent* e) {
+ // We're about to close. Save the current state for the last time.
+ savePopupState();
+ closing = true;
+ QWidget::closeEvent(e);
+}
+
+void StatPopup::hideEvent(QHideEvent* e) {
+ // We're about to hide. Save the current state if we're not
+ // closing altogether.
+ if (! closing)
+ savePopupState();
+ QWidget::hideEvent(e);
+}
+
+void StatPopup::showEvent(QShowEvent* e) {
+ // Make sure we're up-to-date and properly resized.
+ if (isActive())
+ takeReading();
+ else
+ resizeToText();
+
+ // Window management - fix so a taskbar button doesn't appear
+ KWin::setState(winId(), NET::SkipTaskbar | NET::SkipPager);
+
+ QWidget::showEvent(e);
+}
+
+void StatPopup::takeReading() {
+ takeReadingInternal();
+
+ for (int i = 0; i < r.size(); i++) {
+ r[i].dock->addPercentReading(r[i].upper, r[i].lower);
+ }
+
+ if (isVisible()) {
+ // Only resize if the pop-up is visible; otherwise fullReading
+ // might be stale anyway so we'll do it when we show the pop-up.
+ if (resizeRequested)
+ resizeToText();
+
+ repaint();
+ }
+}
+
+void StatPopup::resizeToText() {
+ resizeRequested = false;
+
+ QSize size = fontMetrics().size(0, fullReading);
+ resize(size.width() + 2 * TEXT_EXPANSION_HORIZONTAL,
+ size.height() + 2 * TEXT_EXPANSION_VERTICAL);
+ repaint();
+}
+
+#include "statpopup.moc"
diff --git a/kcpuload/kcpuload/statpopup.h b/kcpuload/kcpuload/statpopup.h
new file mode 100644
index 0000000..2cd7213
--- /dev/null
+++ b/kcpuload/kcpuload/statpopup.h
@@ -0,0 +1,319 @@
+
+/***************************************************************************
+ * *
+ * KCPULoad and KNetLoad are copyright (c) 1999-2000, Markus Gustavsson *
+ * (c) 2002, Ben Burton *
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef __STATPOPUP_H
+#define __STATPOPUP_H
+
+#include <qwidget.h>
+#include <vector> // sorry, QValueVector::erase() does not call destructors
+
+class KAction;
+class KActionCollection;
+class KConfig;
+class KPopupMenu;
+class KRadioAction;
+class KSelectAction;
+class KToggleAction;
+class QTimer;
+class StatDock;
+
+/**
+ * A small pop-up window that contains a continually updating display of
+ * statistics.
+ *
+ * This pop-up will be sticky and stay-on-top by default.
+ *
+ * Up to two windows docked in the system tray (of class StatDock) can
+ * be maintained by this pop-up. There should only be one StatPopup
+ * per application.
+ *
+ * Note that initDock() \e must be called when a system tray window is
+ * created, though it is generally called automatically from the StatDock
+ * constructor.
+ *
+ * Note also that the constructor for this class does \e not call
+ * setupActions(), readPopupState() or startUpdates(); these must all be
+ * called by other routines (such as subclass constructors), since they
+ * require either subclass initialisation or an existing system tray
+ * window.
+ */
+class StatPopup : public QWidget {
+ Q_OBJECT
+
+public:
+ /**
+ * Colour constants.
+ */
+ static const QColor colorBorder;
+
+public:
+ /**
+ * Constructors and destructors.
+ *
+ * This constructor will set the config variable but will not read
+ * any configuration information. See the general class notes also
+ * for a list of other routines this constructor will not call.
+ */
+ StatPopup(bool useSupportSplit, QWidget *parent = 0, const char *name = 0);
+ ~StatPopup();
+
+ /**
+ * Geometric pop-up state management.
+ */
+ void readPopupState();
+ void savePopupState();
+
+ /**
+ * Initialises the given system tray window and its context menu.
+ *
+ * All global application properties (i.e., properties held by this
+ * pop-up) will be propagated to the system tray window, and all
+ * global application actions will be added to the given menu.
+ *
+ * Parameter whichDock must be either 0 or 1 to specify whether the
+ * given system tray window will become window dock[0] or dock[1].
+ *
+ * This routine \e must be called when a system tray window is first
+ * created, though in general this will be done automatically by the
+ * StatDock constructor.
+ */
+ virtual void initDock(StatDock* target, KPopupMenu* menu, int whichDock);
+
+ /**
+ * Is this application currently active (i.e., taking periodic
+ * readings and displaying them)?
+ */
+ bool isActive() const;
+
+ /**
+ * Are split diagrams currently enabled?
+ */
+ bool isSplit() const;
+
+ /**
+ * Returns the frequency of updates in milliseconds.
+ */
+ int getSpeed() const;
+
+public slots:
+ /**
+ * Slots for menu items.
+ */
+ void setActive(bool);
+ void clearHistory();
+ void selectSpeed();
+ void setSplit(bool);
+ void setFillLines();
+ void setFillBars();
+ void setFillShaded();
+ void setSoft(bool);
+ void setLabelled(bool);
+ void setGrid(bool);
+ void selectColor();
+
+protected:
+ /**
+ * Return a human-readable name and default diagram colour for each
+ * system tray window.
+ * The argument given will be either 0 or 1, referring to window
+ * dock[0] or dock[1] respectively.
+ */
+ virtual QString dockName(int which) const = 0;
+ virtual QColor defaultDockColor(int which) const = 0;
+
+ /**
+ * Take a fresh reading. Subclasses must override this routine.
+ *
+ * This routine must update the array upper.
+ * If split readings are enabled, it must also update the array lower.
+ * If this pop-up is visible, it must also update the string fullReading.
+ */
+ virtual void takeReadingInternal() = 0;
+
+ /**
+ * Sets up any actions specific to subclasses of StatPopup.
+ * The global configuration should be read at this point to set the
+ * initial states of these actions.
+ *
+ * This routine will be called during setupActions().
+ */
+ virtual void setupCustomActions() {}
+
+ /**
+ * Inserts any menu items specific to subclasses of StatPopup into
+ * the given menu. If any items are inserted, a separator should
+ * be inserted after them.
+ *
+ * This routine will be called during initDock().
+ */
+ virtual void insertCustomItems(KPopupMenu*) {}
+
+ /**
+ * Propagates any properties specific to subclasses of StatPopup to
+ * the given system tray window during its initialisation.
+ *
+ * This routine will be called during initDock().
+ */
+ virtual void setCustomProperties(StatDock*) {}
+
+ /**
+ * Returns the first non-null pointer out of dock[0] and dock[1], or
+ * returns null if both these pointers are null.
+ */
+ StatDock* firstDock();
+
+ /**
+ * Start and stop the periodic taking of readings.
+ */
+ void startUpdates();
+ void stopUpdates();
+
+ /**
+ * Set up the collection of appliation-wide actions.
+ * The global configuration will be read at this point to set the
+ * initial states of these actions.
+ */
+ virtual void setupActions();
+
+ /**
+ * Request that this pop-up be resized at the next reading according
+ * to its text contents. The pop-up will be resized \e after the
+ * reading is taken.
+ */
+ void requestResize();
+
+ /**
+ * Custom painting routine.
+ */
+ void paintEvent(QPaintEvent *);
+
+ /**
+ * Overrides for dragging support.
+ */
+ void mousePressEvent(QMouseEvent *);
+ void mouseReleaseEvent(QMouseEvent *);
+ void mouseMoveEvent(QMouseEvent *);
+
+ /**
+ * Overrides for saving the popup state.
+ */
+ void closeEvent(QCloseEvent *);
+ void hideEvent(QHideEvent *);
+ void showEvent(QShowEvent *);
+
+protected slots:
+ /**
+ * Take a fresh reading and update all visual elements accordingly.
+ */
+ void takeReading();
+
+protected:
+ /**
+ * Configuration and GUI elements.
+ */
+ KConfig* config;
+ /**< The configuration for the underlying application. */
+
+ /**
+ * Contains the readings per CPU.
+ */
+ struct Reading {
+ StatDock* dock;
+ /**< The system tray window maintained by this pop-up.
+ May be null. */
+ int upper;
+ /**< The upper reading taken during the last reading. */
+ int lower;
+ /**< The lower reading taken during the last reading. */
+ QColor color;
+ /**< The colour used in the system tray diagram. */
+ KAction* actColor;
+ /**< The menu item to change the colour of this dock. */
+ Reading();
+ ~Reading();
+ void Init(int which, StatPopup* popup);
+ };
+ std::vector<Reading> r;
+ /**< The readings maintained by this pop-up. */
+ KActionCollection* coll;
+ /**< The collection of all application-level actions. */
+
+ QString fullReading;
+ /**< A full string describing the last reading taken,
+ to be displayed in this pop-up. */
+
+private:
+ /**
+ * Resize this pop-up according to its text contents (i.e., the
+ * variable fullReading). A little extra room will be added to
+ * accomodate potential minor variations in the text.
+ */
+ void resizeToText();
+
+private:
+ /**
+ * Update support.
+ */
+ QTimer* timer;
+ /**< The timer handling periodic updates. */
+ int speed;
+ /**< The frequency of updates in milliseconds. */
+
+ /*
+ * Diagram support.
+ */
+ int fillStyle;
+ /**< The fill style used in the system tray diagrams. */
+ bool supportSplit;
+ /**< Does this application support split diagrams? */
+
+ /**
+ * Pop-up support.
+ */
+ int relX;
+ /**< The X coordinate of this pop-up at the beginning of a drag
+ operation. */
+ int relY;
+ /**< The Y coordinate of this pop-up at the beginning of a drag
+ operation. */
+ bool isDragged;
+ /**< Are we in the middle of a drag operation? */
+ bool closing;
+ /**< Have we received a close event? */
+ bool resizeRequested;
+ /**< Has a pop-up resize been requested? */
+
+ /**
+ * Actions
+ */
+ KToggleAction* actActive;
+ KAction* actClearHistory;
+ KAction* actSpeed;
+ KToggleAction* actSplit;
+ KToggleAction* actFillLines;
+ KToggleAction* actFillBars;
+ KToggleAction* actFillShaded;
+ KToggleAction* actSoft;
+ KToggleAction* actLabelled;
+ KToggleAction* actGrid;
+};
+
+inline int StatPopup::getSpeed() const {
+ return speed;
+}
+
+inline void StatPopup::requestResize() {
+ resizeRequested = true;
+}
+
+#endif