diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | 84da08d7b7fcda12c85caeb5a10b4903770a6f69 (patch) | |
tree | 2a6aea76f2dfffb4cc04bb907c4725af94f70e72 /kicker-applets/ktimemon | |
download | tdeaddons-84da08d7b7fcda12c85caeb5a10b4903770a6f69.tar.gz tdeaddons-84da08d7b7fcda12c85caeb5a10b4903770a6f69.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdeaddons@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kicker-applets/ktimemon')
-rw-r--r-- | kicker-applets/ktimemon/Makefile.am | 22 | ||||
-rw-r--r-- | kicker-applets/ktimemon/README | 65 | ||||
-rw-r--r-- | kicker-applets/ktimemon/TODO | 13 | ||||
-rw-r--r-- | kicker-applets/ktimemon/confdlg.cc | 295 | ||||
-rw-r--r-- | kicker-applets/ktimemon/confdlg.h | 99 | ||||
-rw-r--r-- | kicker-applets/ktimemon/configure.in.in | 3 | ||||
-rw-r--r-- | kicker-applets/ktimemon/cr16-app-ktimemon.png | bin | 0 -> 306 bytes | |||
-rw-r--r-- | kicker-applets/ktimemon/cr32-app-ktimemon.png | bin | 0 -> 345 bytes | |||
-rw-r--r-- | kicker-applets/ktimemon/ktimemon.desktop | 129 | ||||
-rw-r--r-- | kicker-applets/ktimemon/lo16-app-ktimemon.png | bin | 0 -> 306 bytes | |||
-rw-r--r-- | kicker-applets/ktimemon/lo32-app-ktimemon.png | bin | 0 -> 345 bytes | |||
-rw-r--r-- | kicker-applets/ktimemon/sample.cc | 508 | ||||
-rw-r--r-- | kicker-applets/ktimemon/sample.h | 94 | ||||
-rw-r--r-- | kicker-applets/ktimemon/timemon.cc | 435 | ||||
-rw-r--r-- | kicker-applets/ktimemon/timemon.h | 107 |
15 files changed, 1770 insertions, 0 deletions
diff --git a/kicker-applets/ktimemon/Makefile.am b/kicker-applets/ktimemon/Makefile.am new file mode 100644 index 0000000..fee10c7 --- /dev/null +++ b/kicker-applets/ktimemon/Makefile.am @@ -0,0 +1,22 @@ +kde_module_LTLIBRARIES = ktimemon_panelapplet.la + +ktimemon_panelapplet_la_SOURCES = confdlg.cc sample.cc timemon.cc +METASOURCES = AUTO + +noinst_HEADERS = confdlg.h sample.h timemon.h + +INCLUDES= $(all_includes) + +ktimemon_panelapplet_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) +ktimemon_panelapplet_la_LIBADD = $(LIB_KDEUI) $(LIBKSTAT) $(LIB_KIO) + +KDE_ICON = ktimemon + +lnk_DATA = ktimemon.desktop +lnkdir = $(kde_datadir)/kicker/applets + +EXTRA_DIST = $(lnk_DATA) + +messages: + $(XGETTEXT) *.cc -o $(podir)/ktimemon.pot + diff --git a/kicker-applets/ktimemon/README b/kicker-applets/ktimemon/README new file mode 100644 index 0000000..ec8fb3a --- /dev/null +++ b/kicker-applets/ktimemon/README @@ -0,0 +1,65 @@ + +This is the CVS version of KTimemon. Check out the original authors +homepage at + +http://www.fortunecity.com/victorian/university/394/sw/ktimemon.html + +for more information. This version is based (despite the original readme +below says) on KTimemon 0.3b and modified to compile under KDE 2.0 & +Qt 2.0 by Dirk A. Mueller <[email protected]>. + +2006-04-08: version 0.3c, modified to add iowait display +by Michael Blakeley <[email protected]> + +Credits go to the original author(s) Helmut & Martin Maierhofer for +writing such a useful tool and allowing me to include it into CVS :-). + +Please don't bother them with bugs, problems, etc. you may experience +with this version. It's likely that they're my fault, so report them +to [email protected]. Thanks! + +original README attached below.... + +========================================================================== + + +KTimemon 0.3a +------------- + +KTimemon is a small but nifty system monitor, which can display information +about CPU and memory/swap usage as well as ongoing paging/swapping and +context switch activity. It is well integrated in KDE and can be +configured graphically. For more information, see the associated +documentation (before installation it can be found in ktimemon/doc/*.html) + +KTimemon works on Linux using the /proc filesystem, on Solaris using the +kstat interface, and on Digital Unix (formerly known as DEC/OSF1) using +the table() system call interface. If you can help me to port it to other +platforms, please drop me a note! + +While I was able to test the system interface on Solaris and DEC/OSF1 in +isolation, I could not test the whole application for lack of KDE on the +machines I have access to. Hence I have no idea whether this thing +actually compiles, let alone works on these platforms. The machines I tested +were running DEC/OSF V4.0 and Solaris 2.5.1 respectively. If you get it to +work (or not) on such a system, please let me know! + + +Noteworthy changes from version 0.2: +- Port to DEC/OSF1 and Solaris +- Configurable mouse bindings +- Slight rearrangement of memory information +- Bars can be displayed vertically +- Improved (actually working) configuration interface +- Fixed a few bugs and doubtlessly introduced some more + +Version 0.3a has only minor improvements over 0.3: +- New tooltips with numeric information about system load +- Translation fixes + +Note that some of the configuration entry names have changed from version +0.2 to 0.3, so you may want to delete your current configuration in +$(HOME)/.kde/share/config/ktimemonrc and start with a fresh installation +if you are upgrading from 0.2 + +Martin <[email protected]> diff --git a/kicker-applets/ktimemon/TODO b/kicker-applets/ktimemon/TODO new file mode 100644 index 0000000..eec7578 --- /dev/null +++ b/kicker-applets/ktimemon/TODO @@ -0,0 +1,13 @@ +* port it to more platforms (what about remote monitoring?) + +* include some sort of support for SMP status (smaller bars?); also for + multiple swap partitions/files? + +* make it more flexible (plug-in concept?) + +* improve documentation (add images?), better internationalisation + +* add help button in configuration dialog + +* have some way of attaching watchdogs (e.g. if %idle > 90 for more than + 10 seconds, do this or that (or pop up a dialog)) diff --git a/kicker-applets/ktimemon/confdlg.cc b/kicker-applets/ktimemon/confdlg.cc new file mode 100644 index 0000000..ff5ab9d --- /dev/null +++ b/kicker-applets/ktimemon/confdlg.cc @@ -0,0 +1,295 @@ +/**********************************************************************/ +/* TimeMon (c) 1994 Helmut Maierhofer */ +/* KDE-ified M. Maierhofer 1998 */ +/**********************************************************************/ + +/* + * confdlg.h + * + * Definitions for the timemon configuration dialog. + */ + +#include <config.h> +#include <stdio.h> +#include <qgroupbox.h> +#include <qlineedit.h> +#include <qslider.h> +#include <qlayout.h> +#include <qlabel.h> +#include <qvgroupbox.h> +#include <qcheckbox.h> +#include <qcombobox.h> + +#include <kcolorbutton.h> +#include <klineedit.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kurlrequester.h> + +#include "confdlg.h" +#include "timemon.h" + +// -- KConfDialog definition --------------------------------------------- + +KConfDialog::KConfDialog(KTimeMon *t) + : KDialogBase( Tabbed, i18n("Configuration" ), + Ok|Cancel|Apply, Ok, t, 0, false ), + timemon(t) +{ + QFrame *page; + QBoxLayout *bl; + QGridLayout *gl; + QLabel *l; + QGroupBox *b; + KColorButton *cb; + unsigned i, j; + + setIcon( SmallIcon( "ktimemon" ) ); + + // first tab: general + page = addPage( i18n( "&General" ) ); + + bl = new QVBoxLayout(page, 0, spacingHint()); + + b = new QVGroupBox(i18n("Sample &Rate"), page); + bl->addWidget(b); + + intervalEdit = new KIntNumInput(250, b); + intervalEdit->setRange(20, 1000, 10); + intervalEdit->setSuffix(i18n(" msec")); + + // scaling group box + b = new QVGroupBox(i18n("Scaling"), page); + bl->addWidget(b); + + bl->addStretch(); + + autoScaleBox = new QCheckBox(i18n("&Automatic"), b); + connect(autoScaleBox, SIGNAL(toggled(bool)), this, SLOT(toggle(bool))); + + pageScaleEdit = new KIntNumInput(intervalEdit, 1000, b); + pageScaleEdit->setRange(10, 10000, 10); + pageScaleEdit->setLabel(i18n("&Paging:"), AlignVCenter | AlignLeft); + + swapScaleEdit = new KIntNumInput(pageScaleEdit, 1000, b); + swapScaleEdit->setRange(1, 10000, 5); + swapScaleEdit->setLabel(i18n("&Swapping:"), AlignVCenter | AlignLeft); + + ctxScaleEdit = new KIntNumInput(swapScaleEdit, 10000, b); + ctxScaleEdit->setLabel(i18n("&Context switch:"), AlignVCenter | AlignLeft); + ctxScaleEdit->setRange(1, 10000, 30); + + bl->addStretch(1); + + // second tab: colours + page = addPage( i18n( "C&olors" ) ); + + gl = new QGridLayout(page, 12, 10, 0, spacingHint()); + + gl->setColStretch(3, 1); gl->setColStretch(6, 1); // eat up horizontal space + gl->setRowStretch(11, 1); // eat up vertical space + + gl->addRowSpacing(0, 20); gl->addRowSpacing(4, 20); gl->addRowSpacing(8, 20); + gl->addRowSpacing(2, 8); gl->addRowSpacing(6, 8); gl->addRowSpacing(10, 8); + + gl->addColSpacing(0, 10); gl->addColSpacing(9, 25); + + QString cpuColourLabels[4]; + cpuColourLabels[0] = i18n("Kernel:"); + cpuColourLabels[1] = i18n("User:"); + cpuColourLabels[2] = i18n("Nice:"); + cpuColourLabels[3] = i18n("IOWait:"); + + QString memColourLabels[4]; + memColourLabels[0] = i18n("Kernel:"); + memColourLabels[1] = i18n("Used:"); + memColourLabels[2] = i18n("Buffers:"); + memColourLabels[3] = i18n("Cached:"); + + KColorButton **cpuColourButtons[4] = { &kernelCB, &userCB, &niceCB, &iowaitCB }; + b = new QGroupBox(i18n("CPU"), page); + gl->addMultiCellWidget(b, 0, 2, 0, 13); + + for (j = 0; j < 4; j++) { + l = new QLabel(cpuColourLabels[j], page); + gl->addWidget(l, 1, 3*j+1, AlignVCenter | AlignRight); + + cb = *cpuColourButtons[j] = new KColorButton(white, page); + gl->addWidget(cb, 1, 3*j+2, AlignCenter); + + connect(cb, SIGNAL(changed(const QColor &)), + this, SLOT(updateSampleWidget(const QColor &))); + } + + KColorButton **memColourButtons[4] = { &mkernelCB, &usedCB, &buffersCB, &cachedCB }; + b = new QGroupBox(i18n("Memory"), page); + gl->addMultiCellWidget(b, 4, 6, 0, 13); + + for (j = 0; j < 4; j++) { + l = new QLabel(memColourLabels[j], page); + gl->addWidget(l, 5, 3*j+1, AlignVCenter | AlignRight); + + cb = *memColourButtons[j] = new KColorButton(white, page); + gl->addWidget(cb, 5, 3*j+2, AlignCenter); + + connect(cb, SIGNAL(changed(const QColor &)), + this, SLOT(updateSampleWidget(const QColor &))); + } + + b = new QGroupBox(i18n("Swap"), page); + gl->addMultiCellWidget(b, 8, 10, 0, 6); + + l = new QLabel(i18n("Swap:"), page); + gl->addWidget(l, 9, 1, AlignVCenter | AlignRight); + + cb = swapCB = new KColorButton(red, page); + gl->addWidget(cb, 9, 2); + + connect(cb, SIGNAL(changed(const QColor &)), + this, SLOT(updateSampleWidget(const QColor &))); + + l = new QLabel(i18n("Backgd:"), page); + gl->addWidget(l, 9, 4, AlignVCenter | AlignRight); + + cb = bgCB = new KColorButton(blue, page); + gl->addWidget(cb, 9, 5); + + connect(cb, SIGNAL(changed(const QColor &)), + this, SLOT(updateSampleWidget(const QColor &))); + + //b = new QGroupBox(i18n("Sample"), page); + //gl->addMultiCellWidget(b, 8, 10, 7, 9); + + // third tab: interaction + page = addPage( i18n( "&Interaction" ) ); + + bl = new QVBoxLayout(page, 0, spacingHint()); + + b = new QGroupBox(i18n("Mouse Events"), page); + b->setColumnLayout( 0, Qt::Vertical ); + bl->addWidget(b); + bl->addStretch(); + + QVBoxLayout *vbox = new QVBoxLayout( b->layout() ); + + gl = new QGridLayout(b, MAX_MOUSE_ACTIONS + 1, 3, 0, 6 ); + + vbox->addLayout( gl ); + + for (i = 1; i < MAX_MOUSE_ACTIONS + 1; i++) + gl->setRowStretch(i, 1); + gl->setColStretch(2, 1); + + QString buttonText[MAX_MOUSE_ACTIONS] = { i18n("Left button:"), + i18n("Middle button:"), + i18n("Right button:") }; + + for (i = 0; i < (int) MAX_MOUSE_ACTIONS; i++) { + + l = new QLabel(buttonText[i], b); + gl->addWidget(l, i+1, 0); + + mouseC[i] = new KComboBox(false, b); + mouseC[i]->insertItem(i18n("Is Ignored"), KTimeMon::NOTHING); +// SWITCH doesn't DO anything. remove it from config dialog for now +// mouseC[i]->insertItem(i18n("Switches Mode"), KTimeMon::SWITCH); + mouseC[i]->insertItem(i18n("Pops Up Menu"), KTimeMon::MENU - 1); + mouseC[i]->insertItem(i18n("Starts"), KTimeMon::COMMAND - 1); + gl->addWidget(mouseC[i], i+1, 1); + + connect( mouseC[ i ], SIGNAL( activated( int ) ), this, + SLOT( mouseCommandEnable() ) ); + + mouseLE[i] = new KURLRequester(b); + mouseLE[i]->lineEdit()->setText(t->mouseActionCommand[i]); + gl->addWidget(mouseLE[i], i+1, 2); + } + + gl->activate(); + + resize(380, 300); + + connect(this, SIGNAL(applyClicked()), timemon, SLOT(apply())); + connect(this, SIGNAL(okClicked()), timemon, SLOT(apply())); +} + +// Adjust the colours of the sample widget in the configuration dialog. +void KConfDialog::updateSampleWidget(const QColor &) +{ +#if 0 + sample->kernelColour = kernelCB->color(); + sample->userColour = userCB->color(); + sample->niceColour = niceCB->color(); + sample->iowaitColour = iowaitCB->color(); + sample->kernelColour = kernelCB->color(); + sample->cachedColour = cachedCB->color(); + sample->usedColour = usedCB->color(); + sample->buffersColour = buffersCB->color(); + sample->swapColour = swapCB->color(); + sample->bgColour = bgCB->color(); + sample->update(); +#endif +} + +// ----------------------------------------------------------------------------- + +// enable/disable the scale widgets +void KConfDialog::toggle(bool state) +{ + swapScaleEdit->setEnabled(!state); + pageScaleEdit->setEnabled(!state); + ctxScaleEdit->setEnabled(!state); +} + +void KConfDialog::mouseCommandEnable() +{ + for ( int i = 0; i < MAX_MOUSE_ACTIONS; i++ ) { + unsigned action = mouseC[ i ]->currentItem(); + + // the - 1 is for compat with the no longer shown Switch option + mouseLE[ i ]->setEnabled( action == KTimeMon::COMMAND - 1); + } +} + +// update the dialog fields +void KConfDialog::update() +{ + intervalEdit->setValue(timemon->interval); + kernelCB->setColor(timemon->kernelColour); + userCB->setColor(timemon->userColour); + niceCB->setColor(timemon->niceColour); + iowaitCB->setColor(timemon->iowaitColour); + buffersCB->setColor(timemon->buffersColour); + mkernelCB->setColor(timemon->mkernelColour); + usedCB->setColor(timemon->usedColour); + cachedCB->setColor(timemon->cachedColour); + swapCB->setColor(timemon->swapColour); + bgCB->setColor(timemon->bgColour); + pageScaleEdit->setValue(timemon->pageScale); + swapScaleEdit->setValue(timemon->swapScale); + ctxScaleEdit->setValue(timemon->ctxScale); + autoScaleBox->setChecked(timemon->autoScale); + + for ( int i = 0; i < MAX_MOUSE_ACTIONS; i++ ) + { + int action = timemon->mouseAction[i]; + if (action > 0) + --action; // compat for the no longer shown Switch action + mouseC[i]->setCurrentItem(action); + } + mouseCommandEnable(); + + updateSampleWidget(white); // fake colour +} + +unsigned int KConfDialog::getMouseAction(int i) const +{ + int action = mouseC[i]->currentItem(); + + if (action > 0) + ++action; // compat for the no longer shown Switch action + + return action; +} + +#include "confdlg.moc" diff --git a/kicker-applets/ktimemon/confdlg.h b/kicker-applets/ktimemon/confdlg.h new file mode 100644 index 0000000..d458bf2 --- /dev/null +++ b/kicker-applets/ktimemon/confdlg.h @@ -0,0 +1,99 @@ +/* -*- C++ -*- */ + +/**********************************************************************/ +/* TimeMon (c) 1994 Helmut Maierhofer */ +/* KDE-ified M. Maierhofer 1998 */ +/* */ +/* Ported to KDE 2.0 and other stuff: */ +/* Copyright (c) Dirk A. Mueller <[email protected]> */ +/* */ +/**********************************************************************/ + +/* + * confdlg.h + * + * Definitions for the timemon configuration dialog. + */ + +#ifndef CONFDLG_H +#define CONFDLG_H + +#include <qcolor.h> +#include <qcheckbox.h> +#include <qtabdialog.h> + +#include <kcolorbutton.h> +#include <kcombobox.h> +#include <klineedit.h> +#include <knuminput.h> +#include <kdialogbase.h> +#include <kurlrequester.h> + +#include "timemon.h" + +// -- forward declaration ------------------------------------------------ + +class KTimeMon; +class QLineEdit; +class QSlider; +class KColorButton; + +// -- KConfDialog declaration -------------------------------------------- + +/* + * KConfDialog + */ + +class KConfDialog : public KDialogBase +{ + + Q_OBJECT + +public: + KConfDialog(KTimeMon *timemon); + ~KConfDialog() {} + + void update(); // get values from timemon + + unsigned getInterval() const { return intervalEdit->value(); } + QColor getKernelColour() const { return kernelCB->color(); } + QColor getUserColour() const { return userCB->color(); } + QColor getNiceColour() const { return niceCB->color(); } + QColor getIOWaitColour() const { return iowaitCB->color(); } + QColor getCachedColour() const { return cachedCB->color(); } + QColor getUsedColour() const { return usedCB->color(); } + QColor getBuffersColour() const { return buffersCB->color(); } + QColor getMKernelColour() const { return mkernelCB->color(); } + QColor getSwapColour() const { return swapCB->color(); } + QColor getBgColour() const { return bgCB->color(); } + + bool getAutoScale() const { return autoScaleBox->isChecked(); } + unsigned getPageScale() const { return pageScaleEdit->value(); } + unsigned getSwapScale() const { return swapScaleEdit->value(); } + unsigned getCtxScale() const { return ctxScaleEdit->value(); } + + unsigned getMouseAction(int i) const; + QString getMouseActionCommand(int i) const { return mouseLE[i]->lineEdit()->text(); } + +private slots: + void updateSampleWidget(const QColor &); // update colours in configuration + void toggle(bool state); // enable/disable scales + void mouseCommandEnable(); + +private: + + KTimeMon *timemon; + KIntNumInput *intervalEdit, *swapScaleEdit, *pageScaleEdit, *ctxScaleEdit; + QLineEdit *procFileEdit; + QCheckBox *autoScaleBox; + KColorButton *kernelCB, *userCB, *niceCB, *iowaitCB; + KColorButton *buffersCB, *usedCB, *cachedCB, *mkernelCB; + KColorButton *swapCB, *bgCB; + KURLRequester *mouseLE[MAX_MOUSE_ACTIONS]; + KComboBox *mouseC[MAX_MOUSE_ACTIONS]; + bool haveWarned; + + friend class KTimeMon; +}; + +#endif // CONFDLG_H diff --git a/kicker-applets/ktimemon/configure.in.in b/kicker-applets/ktimemon/configure.in.in new file mode 100644 index 0000000..7b9657e --- /dev/null +++ b/kicker-applets/ktimemon/configure.in.in @@ -0,0 +1,3 @@ +AC_CHECK_HEADERS(fcntl.h) +AC_CHECK_LIB(kstat, kstat_open, LIBKSTAT="-lkstat") +AC_SUBST(LIBKSTAT) diff --git a/kicker-applets/ktimemon/cr16-app-ktimemon.png b/kicker-applets/ktimemon/cr16-app-ktimemon.png Binary files differnew file mode 100644 index 0000000..d9295e6 --- /dev/null +++ b/kicker-applets/ktimemon/cr16-app-ktimemon.png diff --git a/kicker-applets/ktimemon/cr32-app-ktimemon.png b/kicker-applets/ktimemon/cr32-app-ktimemon.png Binary files differnew file mode 100644 index 0000000..71ff476 --- /dev/null +++ b/kicker-applets/ktimemon/cr32-app-ktimemon.png diff --git a/kicker-applets/ktimemon/ktimemon.desktop b/kicker-applets/ktimemon/ktimemon.desktop new file mode 100644 index 0000000..9f9013e --- /dev/null +++ b/kicker-applets/ktimemon/ktimemon.desktop @@ -0,0 +1,129 @@ +[Desktop Entry] +Type=Plugin +Icon=ktimemon +X-KDE-Library=ktimemon_panelapplet +X-KDE-UniqueApplet=true +Comment=A simple system monitor +Comment[ar]=مراقب النظام بسيط +Comment[bg]=Системен монитор за KDE +Comment[br]=Un diskweler reizhiad eeun +Comment[ca]=Un monitor del sistema senzill +Comment[cs]=Jednoduchý monitor systému +Comment[da]=En simpel systemovervåger til KDE +Comment[de]=Ein einfacher Systemmonitor +Comment[el]=Ένας απλός επόπτης συστήματος +Comment[eo]=Simpla sistemobservilo +Comment[es]=Un monitor de sistema sencillo +Comment[et]=Lihtne süsteemi monitor +Comment[eu]=Sistemaren monitore sinplea +Comment[fa]=نمایشگر سیستم ساده +Comment[fi]=Yksinkertainen järjestelmänvalvontaohjelma +Comment[fr]=Un moniteur système simple +Comment[fy]=In ienfâldige systeemmonitor +Comment[ga]=Monatóir simplí an chórais +Comment[gl]=Un monitor do sistema simples +Comment[he]=צג מערכת פשוט עבור KDE +Comment[hr]=Jednostavan nadzor sustava +Comment[hu]=Egyszerű rendszermonitor +Comment[is]=Einfalt kerfiseftirlit +Comment[it]=Un semplice monitor di sistema +Comment[ja]=シンプルなシステムモニタ +Comment[ka]=მარტივი სისტემური მონიტორი +Comment[kk]=Қарапайым жүйе қадағалауышы +Comment[km]=កម្មវិធីត្រួតពិនិត្យប្រព័ន្ធធម្មតាមួយ +Comment[lt]=Sistemos stebėjimo priemonė +Comment[mk]=Едноставен набљудувач на системот +Comment[nb]=En enkel systemovervåker +Comment[nds]=En eenfach Systeemkieker +Comment[ne]=एउट सामान्य प्रणाली मनिटर +Comment[nl]=Een eenvoudige systeemmonitor +Comment[nn]=Ein enkel systemovervakar +Comment[pa]=ਇੱਕ ਸਧਾਰਨ ਸਿਸਟਮ ਨਿਗਰਾਨ +Comment[pl]=Prosty monitor systemu +Comment[pt]=Um monitor do sistema simples +Comment[pt_BR]=Um monitor de sistema simples +Comment[ru]=Простой системный монитор +Comment[sk]=Jednoduchý monitor systému +Comment[sl]=Preprost nadzornik sistema +Comment[sr]=Једноставно надгледање система +Comment[sr@Latn]=Jednostavno nadgledanje sistema +Comment[sv]=En enkel systemövervakare +Comment[tr]=Basit bir sistem izleyici +Comment[uk]=Простий системний монітор +Comment[uz]=Tizimni nazorat qilish uchun oddiy vosita +Comment[uz@cyrillic]=Тизимни назорат қилиш учун оддий восита +Comment[vi]=Bộ theo dõi hệ thống đơn giản +Comment[zh_CN]=简单的系统监视器 +Comment[zh_TW]=簡單的系統監視器 +Name=System Monitor +Name[af]=Stelsel Monitor +Name[ar]=مراقب النظام +Name[az]=Sistem İzləyici +Name[bg]=Системен монитор +Name[br]=Diskwel saviad ar reizhiad +Name[bs]=Stanje sistema +Name[ca]=Monitor del sistema +Name[cs]=Monitor systému +Name[cy]=Gwarchodydd Cysawd +Name[da]=Systemovervåger +Name[de]=Systemmonitor +Name[el]=Εποπτεία συστήματος +Name[eo]=Sistemobservilo +Name[es]=Monitor de sistema +Name[et]=Süsteemi monitor +Name[eu]=Sistemaren monitorea +Name[fa]=نمایشگر سیستم +Name[fi]=Järjestelmänvalvonta +Name[fo]=Skipanaryvirvakari +Name[fr]=Surveillance du système +Name[fy]=Systeemmonitor +Name[ga]=Monatóir Córais +Name[gl]=Monitor do Sistema +Name[he]=צג מערכת +Name[hi]=तंत्र मॉनीटर +Name[hr]=Nadzor sustava +Name[hu]=Rendszermonitor +Name[is]=Kerfiseftirlit +Name[it]=Monitor di sistema +Name[ja]=システムモニタ +Name[ka]=სისტემური მონიტორი +Name[kk]=Жүйе қадағалауышы +Name[km]=កម្មវិធីត្រួតពិនិត្យប្រព័ន្ធ +Name[ko]=시스템 지켜보기 +Name[lt]=Sistemos stebėtojas +Name[lv]=Sistēmas Monitors +Name[mk]=Набљудувач на системот +Name[ms]=Monitor Sistem +Name[mt]=Monitur tas-sistema +Name[nb]=Systemovervåker +Name[nds]=Systeemkieker +Name[ne]=प्रणाली मनिटर +Name[nl]=Systeemmonitor +Name[nn]=Systemovervakar +Name[pa]=ਸਿਸਟਮ ਨਿਗਰਾਨ +Name[pl]=Monitor systemu +Name[pt]=Monitor do Sistema +Name[pt_BR]=Monitor do sistema +Name[ro]=Monitor de sistem +Name[ru]=Системный монитор +Name[sk]=Monitor systému +Name[sl]=Sistemski nadzornik +Name[sr]=Надгледање система +Name[sr@Latn]=Nadgledanje sistema +Name[sv]=Systemövervakare +Name[ta]=அமைப்பு திரை +Name[tg]=Монитори системавӣ +Name[th]=สอดส่องระบบ +Name[tr]=Sistem İzleyici +Name[uk]=Системний монітор +Name[uz]=Oddiy tizim nazoratchisi +Name[uz@cyrillic]=Оддий тизим назоратчиси +Name[ven]=Monitha wa Sistemu +Name[vi]=Bộ theo dõi hệ thống +Name[xh]=Indlela yokwenza yeCebo lokubonisa +Name[zh_CN]=系统监视器 +Name[zh_TW]=系統監視器 +Name[zu]=Umphendli Wendlela esetshenziswayo +DocPath=kicker-applets/ktimemon.html +X-KDE-StartupNotify=true +X-KDE-ParentApp=applets diff --git a/kicker-applets/ktimemon/lo16-app-ktimemon.png b/kicker-applets/ktimemon/lo16-app-ktimemon.png Binary files differnew file mode 100644 index 0000000..d9295e6 --- /dev/null +++ b/kicker-applets/ktimemon/lo16-app-ktimemon.png diff --git a/kicker-applets/ktimemon/lo32-app-ktimemon.png b/kicker-applets/ktimemon/lo32-app-ktimemon.png Binary files differnew file mode 100644 index 0000000..71ff476 --- /dev/null +++ b/kicker-applets/ktimemon/lo32-app-ktimemon.png diff --git a/kicker-applets/ktimemon/sample.cc b/kicker-applets/ktimemon/sample.cc new file mode 100644 index 0000000..25f25a3 --- /dev/null +++ b/kicker-applets/ktimemon/sample.cc @@ -0,0 +1,508 @@ +/**********************************************************************/ +/* TimeMon (c) 1994 Helmut Maierhofer */ +/* KDE-ified M. Maierhofer 1998 */ +/**********************************************************************/ + +/* + * sample.cc + * + * Definitions for the system dependent sampling class. + */ + +#include <config.h> + +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> +#include <string.h> +#include <stdarg.h> +#include <sys/types.h> +#include <sys/stat.h> +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif +#include <fstream> +#include <stdio.h> + +#ifdef __osf__ +#include <sys/table.h> +#elif defined(USE_SOLARIS) +#include <kstat.h> +#include <sys/sysinfo.h> +#include <sys/stat.h> +#include <sys/swap.h> +#endif + +#include <qwidget.h> +#include <klocale.h> +#include <kmessagebox.h> + +#include "timemon.h" +#include "sample.h" + +// -- global definitions ------------------------------------------------- + +#if defined(__osf__) || defined(USE_SOLARIS) +extern "C" int getpagesize(); // argh, have to define prototype! +#endif + +#ifdef __linux__ +// -- global constants --------------------------------------------------- +#define STAT_NAME "/proc/stat" +#define MEMINFO_NAME "/proc/meminfo" +#endif + +// -- KSample::Sample definition ----------------------------------------- + +// Fill sample with some default values (e.g. used in preview widget +// in configuration) +void KSample::Sample::fill(unsigned scale) +{ + user = scale * 40; user /= 100; + nice = scale * 25; user /= 100; + kernel = scale * 10; kernel /= 100; + iowait = scale * 5; iowait /= 100; + cpus = 1; + buffers = scale * 20; buffers /= 100; + used = scale * 30; used /= 100; + cached = scale * 20; cached /= 100; + sused = scale * 25; sused /= 100; +} + +// -- KSample definition ------------------------------------------------- + +// Initialise the member variables and try to open the standard files in +// the proc filesystem; for other platforms perform equivalent initialisation +KSample::KSample(KTimeMon *t, bool a, unsigned p, unsigned s, unsigned c) : + timemon(t), +#ifdef __linux__ + memFD(-1), statFD(-1), +#elif defined (USE_SOLARIS) + kc(0), warned(false), +#endif + pageScale(p), swapScale(s), cxScale(c), autoscale(a) +{ +#ifdef __linux__ + memstats[0].name = "SwapTotal:"; + memstats[0].stat = &sample.stotal; + memstats[1].name = "MemTotal:"; + memstats[1].stat = &sample.mtotal; + memstats[2].name = "MemFree:"; + memstats[2].stat = &sample.free; + memstats[3].name = "Buffers:"; + memstats[3].stat = &sample.buffers; + memstats[4].name = "Cached:"; + memstats[4].stat = &sample.cached; + memstats[5].name = "SwapFree:"; + memstats[5].stat = &sample.sfree; + memstats[6].name = 0; + memstats[6].stat = 0; + + if ((memFD = open(MEMINFO_NAME, O_RDONLY)) == -1) { + KMessageBox::error(timemon, + i18n("Unable to open the file '%1'. The diagnostics are:\n%2.\n" + "This file is required to determine current memory usage.\n" + "Maybe your proc filesystem is non-Linux standard?").arg(MEMINFO_NAME).arg(strerror(errno))); + exit(1); + } + + fcntl( memFD,F_SETFD, FD_CLOEXEC ); + + if ((statFD = open(STAT_NAME, O_RDONLY)) == -1) { + KMessageBox::error(timemon, + i18n("Unable to open the file '%1'. The diagnostics are:\n%2.\n" + "This file is required to determine current system info. " + "Maybe your proc filesystem is non-Linux standard?").arg(MEMINFO_NAME).arg(strerror(errno))); + exit(1); + } + + fcntl( statFD,F_SETFD, FD_CLOEXEC ); + +#elif defined (USE_SOLARIS) + if ((kc = kstat_open()) == 0) { + KMessageBox::error(timemon, i18n("Unable to initialize the 'kstat' library. " + "This library is used for accessing kernel information. " + "The diagnostics are:\n%1.\n" + "Are you really running Solaris? " + "Please contact the maintainer at [email protected] " + "who will try to figure out what went wrong.").arg(strerror(errno))); + exit(1); + } +#endif + +#if defined(USE_SOLARIS) || defined(__osf__) + pagesPerMB = (1024*1024) / getpagesize(); + if (pagesPerMB == 0) pagesPerMB = 1; // paranoia sanity check +#endif + + readSample(); + updateSample(); +} + +// Get rid of the resources we acquired in the constructor. +KSample::~KSample() +{ +#ifdef __linux__ + close(memFD); + close(statFD); +#elif defined (USE_SOLARIS) + if (kc != 0) kstat_close(kc); +#endif +} + +// Set the appropriate scaling parameters +void KSample::setScaling(bool a, unsigned p, unsigned s, unsigned c) +{ + autoscale = a; + pageScale = p; + swapScale = s; + cxScale = c; +} + +// ----------------------------------------------------------------------------- +// Show a message box with the given message and terminate the application. + +void KSample::fatal(const QString& msg) +{ + timemon->stop(); + + KMessageBox::error(timemon, msg); +// exit(1); +} + + +// ----------------------------------------------------------------------------- +// Show a message box with the given message and don't terminate the app ;-) + +void KSample::nonfatal(const QString& msg) +{ + timemon->stop(); + + KMessageBox::sorry(timemon, msg); + timemon->cont(); +} + + +// ----------------------------------------------------------------------------- +// Read a new sample from the files or whatever resource the OS implements + +/* For 2.5 kernels */ +static inline void +scan_one(const char* buff, const char *key, unsigned long int* val) +{ + const char *b = strstr(buff, key); + if (b) { + b = strstr(b, " "); + if (b) + sscanf(b, " %lu", val); + } +} + +void KSample::readSample() +{ + sample.cpus = 0; // just to make sure... + +#ifdef __linux__ // linux makes it simple: use the /proc if + int l; + char buffer[4096]; + + lseek(memFD, 0, 0); + if ((l = read(memFD, buffer, sizeof(buffer) - 1)) < 0) + { + fatal(i18n("Unable to read the memory usage file '%1'.\n" + "The diagnostics are: %2").arg(MEMINFO_NAME).arg(strerror(errno))); + } + buffer[l] = '\0'; + l = 0; + char *p; + while (memstats[l].name != 0) { + p = strstr(buffer, memstats[l].name); + if (p == 0 || + sscanf(p + strlen(memstats[l].name), "%lu kB", memstats[l].stat) < 1) + fatal(i18n("The memory usage file '%1' seems to use a " + "different file format than expected.\n" + "Maybe your version of the proc filesystem is " + "incompatible with supported versions. " + "Please contact the developer at http://bugs.kde.org/ who will try to sort this out.").arg(MEMINFO_NAME)); + l++; + } + + if ( ( p = strstr(buffer, "Slab:") ) ) { + unsigned long slabs; + sscanf(p + 5, "%lu kB", &slabs); + sample.mkernel = slabs; + } + + /* read the data for the cpu stats */ + lseek(statFD, 0, 0); + if ((l = read(statFD, buffer, sizeof(buffer)-1)) < 0) + fatal(i18n("Unable to read the system usage file '%1'.\n" + "The diagnostics are: %2").arg(STAT_NAME).arg(strerror(errno))); + + buffer[l] = '\0'; + + bool ok = (sscanf(buffer, "cpu %lu %lu %lu %lu %lu", &sample.user, + &sample.nice, &sample.kernel, &sample.idle, &sample.iowait) == 5); + + if (ok) { + for (l = 0; l < MAX_CPU; l++) { // get individual stat for SMP machines + char cpuname[10]; + sprintf(cpuname, "cpu%d", l); + + if ((p = strstr(buffer, cpuname)) == NULL) break; + + unsigned long u, n, k, i; + ok = sscanf(p, "cpu%*d %lu %lu %lu %lu", &u, &n, &k, &i); + if (!ok) break; + + sample.smptotal[l] = u+n+k+i; + sample.smpbusy[l] = sample.smptotal[l] - i; + } + } + sample.cpus = l; + +#elif defined(__osf__) // in OSF/2, we can use table() + + QString msg = i18n("Unable to obtain system information.\n" + "The table(2) system call returned an error " + "for table %1.\n" + "Please contact the maintainer at [email protected] " + "who will try to figure out what went wrong."); + + struct tbl_sysinfo sysinfo; + if (table(TBL_SYSINFO, 0, &sysinfo, 1, sizeof(sysinfo)) != 1) + fatal(msg.arg("TBL_SYSINFO")); + + sample.user = sysinfo.si_user; + sample.nice = sysinfo.si_nice; + sample.kernel = sysinfo.si_sys; + sample.iowait = sysinfo.wait; + sample.idle = sysinfo.si_idle; + + struct tbl_vmstats vmstats; + if (table(TBL_VMSTATS, 0, &vmstats, 1, sizeof(vmstats)) != 1) + fatal(msg.arg("TBL_VMSTATS")); + + sample.mtotal = vmstats.free_count + vmstats.active_count + + vmstats.inactive_count + vmstats.wire_count; + sample.free = vmstats.free_count; + sample.buffers = vmstats.inactive_count; // pages not used for some time + sample.cached = vmstats.wire_count; // kernel/driver memory + + struct tbl_swapinfo swapinfo; + if (table(TBL_SWAPINFO, -1, &swapinfo, 1, sizeof(swapinfo)) != 1) + fatal(msg.arg("TBL_SWAPINFO")); + + sample.stotal = swapinfo.size; + sample.sfree = swapinfo.free; + +#elif defined(USE_SOLARIS) + kstat_t *ksp; + + sample.cpus = 0; + for (ksp = kc->kc_chain; ksp != 0; ksp = ksp->ks_next) { + if (strncmp(ksp->ks_name, "cpu_stat", 8) != 0) continue; + sample.cpus++; + } + + if (sample.cpus == 0) + fatal(i18n("Unable to find any entries for CPU statistics " + "in the 'kstat' library. Are you running a non-standard " + "version of Solaris?\n" + "Please contact the maintainer via http://bugs.kde.org/ who will try to sort this out.")); + + sample.user = sample.nice = sample.kernel = sample.iowait = sample.idle = 0; + sample.stotal = sample.sfree = 0; + + int cpus = 0; + for (ksp = kc->kc_chain; ksp != 0; ksp = ksp->ks_next) { + if (strncmp(ksp->ks_name, "cpu_stat", 8) != 0) continue; + cpus++; + + cpu_stat_t cstat; + if (kstat_read(kc, ksp, 0) == -1 || // update from kernel + kstat_read(kc, ksp, &cstat) == -1) // and read into buffer + fatal(i18n("Unable to read the CPU statistics entry " + "from the 'kstat' library. The diagnostics are '%1'.\n" + "Please contact the maintainer via http://bugs.kde.org/ who will try to sort this out.").arg(strerror(errno))); + + // fields are: idle user kernel iowait (no nice info?) + sample.user += cstat.cpu_sysinfo.cpu[1] / sample.cpus; + sample.nice += 0; + sample.kernel += cstat.cpu_sysinfo.cpu[2] / sample.cpus; + sample.iowait += cstat.cpu_sysinfo.cpu[3] / sample.cpus; + sample.idle += cstat.cpu_sysinfo.cpu[0] / sample.cpus; + } + + if (cpus != sample.cpus) + fatal(i18n("The number of CPUs appears to have changed at " + "very short notice, or the 'kstat' library returns " + "inconsistent results (%1 vs. %2 CPUs).\n" + "Please contact the maintainer via http://bugs.kde.org/ who will try to sort this out.").arg(sample.cpus).arg(cpus)); + + // availrmem = pages of core for user-proc ( == physmem - kernelmem) + // freemem = no of free pages + // physmem == total mem in 4KB blocks + + errno = 0; + if ((ksp = kstat_lookup(kc, "unix", -1, "system_pages")) == 0 || + kstat_read(kc, ksp, 0) == -1) + fatal(i18n("Unable to read the memory statistics entry " + "from the 'kstat' library. The diagnostics are '%1'\n" + "You might want to contact the maintainer at " + "http://bugs.kde.org/ who will try to sort this out.").arg(strerror(errno))); + + int i; + unsigned long physmem = 0, freemem = 0, availrmem = 0; + + kstat_named_t *kn = (kstat_named_t *)ksp->ks_data; + for (i = 0; i < (int) ksp->ks_ndata; i++) { + if (strcmp(kn->name, "physmem") == 0) physmem = kn->value.ul; + else if (strcmp(kn->name, "freemem") == 0) freemem = kn->value.ul; + else if (strcmp(kn->name, "availrmem") == 0) availrmem = kn->value.ul; + kn++; + } + + if (physmem == 0) // sanity check, this should always be > 0 + fatal(i18n("There seems to be a problem with KTimeMon's handling " + "of the 'kstat' library: 0 bytes of physical memory determined!\n" + "Free memory is %1, available memory is %2.\n" + "Please contact the maintainer at [email protected] who will try to sort this out.").arg(freemem).arg(availrmem)); + + sample.mtotal = physmem; + sample.free = freemem; + sample.buffers = 0; + sample.cached = physmem - availrmem; // memory used by the kernel + + int swapentries; + if ((swapentries = swapctl(SC_GETNSWP, 0)) == -1) + fatal(i18n("Unable to determine the number of " + "swap spaces. The diagnostics are '%1'.\n" + "Please contact the maintainer at http://bugs.kde.org/ who will try to sort this out.").arg(strerror(errno))); + + if (swapentries != 0) { + // 2* to get some space for padding?? + swaptbl_t *stbl = (swaptbl_t *) malloc(2*sizeof(int) + swapentries * + sizeof(struct swapent)); + if (stbl == 0) + fatal(i18n("KTimeMon ran out of memory while " + "trying to determine the swap usage.\n" + "Attempted to allocate %1 bytes of memory (2 * %2 + %3 * %4).\n" + "Please contact the maintainer at http://bugs.kde.org/ who will try to sort this out.") + .arg(2 * sizeof(int) + swapentries * sizeof(struct swapent)) + .arg(sizeof(int)).arg(swapentries).arg(sizeof(struct swapent))); + + char path[1024]; + stbl->swt_n = swapentries; + for (i = 0; i < swapentries; i++) stbl->swt_ent[i].ste_path = path; + + if ((swapentries = swapctl(SC_LIST, stbl)) == -1) + fatal(i18n("Unable to determine the swap usage.\n" + "The diagnostics are '%1'.\n" + "Please contact the maintainer at http://bugs.kde.org/ who will try to sort this out.").arg(strerror(errno))); + + + if (!warned && swapentries != stbl->swt_n) { + warned = true; + nonfatal(i18n("Information was requested for " + "%1 swap spaces, but only %2 swap entries were returned.\n" + "KTimeMon will attempt to continue.\n" + "Please contact the maintainer at http://bugs.kde.org/ who will try to sort this out.").arg(stbl->swt_n).arg(swapentries)); + } + + for (i = 0; i < swapentries; i++) { + sample.stotal += stbl->swt_ent[i].ste_pages; + sample.sfree += stbl->swt_ent[i].ste_free; + } + + free(stbl); + } + +#else +#warning This type of system is not supported + sample.stotal = sample.sfree = 0; +#endif + + sample.cputotal = + sample.user + sample.nice + sample.kernel + sample.iowait + sample.idle; + sample.used = sample.mtotal - sample.mkernel - sample.free - sample.buffers - sample.cached; + sample.sused = sample.stotal - sample.sfree; +} + +// Read a new sample after copying the old one. +void KSample::updateSample() +{ + oldSample = sample; + readSample(); +} + +// Convert v to a value representing megabytes. +inline void KSample::makeMBytes(unsigned long &v) +{ +#ifdef __linux__ + v /= 1024; // can it be simpler ;-) +#elif defined (__osf__) || defined(USE_SOLARIS) + v /= pagesPerMB; +#endif +} + +// Return unscaled sample +KSample::Sample KSample::getRawSample() +{ + Sample diff = sample; + + diff.cputotal -= oldSample.cputotal; + + diff.user -= oldSample.user; + diff.nice -= oldSample.nice; + diff.kernel -= oldSample.kernel; + diff.iowait -= oldSample.iowait; + + for (int i = 0; i < diff.cpus; i++) { + diff.smptotal[i] -= oldSample.smptotal[i]; + diff.smpbusy[i] -= oldSample.smpbusy[i]; + } + + return diff; +} + +// Better scaling, round according to first decimal +inline unsigned long KSample::doScale(unsigned long value, unsigned scale1, + unsigned long scale2) +{ + if (scale2 == 0) scale2 = (unsigned long)~0; // avoid SEGVs + + unsigned long v = value * scale1 * 10; + v /= scale2; + unsigned r = v % 10; + v /= 10; + if (r > 4) v++; + return v; +} + +// Provide the difference from the last to the current sample, scale it +// and return it. +KSample::Sample KSample::getSample(unsigned scale) +{ + Sample s = getRawSample(); + + s.user = doScale(s.user, scale, s.cputotal); + s.nice = doScale(s.nice, scale, s.cputotal); + s.kernel = doScale(s.kernel, scale, s.cputotal); + s.iowait = doScale(s.iowait, scale, s.cputotal); + + for (int i = 0; i < s.cpus; i++) + s.smpbusy[i] = doScale(s.smpbusy[i], scale, s.smptotal[i]); + + s.cached = doScale(s.cached, scale, s.mtotal); + s.buffers = doScale(s.buffers, scale, s.mtotal); + s.used = doScale(s.used, scale, s.mtotal); + s.mkernel = doScale(s.mkernel, scale, s.mtotal); + makeMBytes(s.mtotal); + + s.sused = doScale(s.sused, scale, s.stotal); + makeMBytes(s.stotal); + + return s; +} + diff --git a/kicker-applets/ktimemon/sample.h b/kicker-applets/ktimemon/sample.h new file mode 100644 index 0000000..b4a0723 --- /dev/null +++ b/kicker-applets/ktimemon/sample.h @@ -0,0 +1,94 @@ +/* -*- C++ -*- */ + +/**********************************************************************/ +/* TimeMon (c) 1994 Helmut Maierhofer */ +/* KDE-ified M. Maierhofer 1998 */ +/**********************************************************************/ + +/* + * sample.h + * + * Definitions for the system dependent sampling class (currently relies + * on the linux /proc filesystem). + */ + +#ifndef SAMPLE_H +#define SAMPLE_H + +// -- global constants --------------------------------------------------- + +#define MAX_CPU 16 // max number of CPUS in an SMP machine + // we get the status for + +// -- forward declaration ------------------------------------------------ +class KTimeMon; + +#ifdef USE_SOLARIS +struct kstat_ctl; +#endif + +// -- class declaration -------------------------------------------------- + +/* + * KSample + * + * This class is responsible for reading the /proc file system and parsing + * the system information. + */ +class KSample { +public: + // -- Sample declaration ----------------------------------------------- + struct Sample { + unsigned long cputotal; + unsigned long user, nice, kernel, iowait, idle; + int cpus; + unsigned long smptotal[MAX_CPU], smpbusy[MAX_CPU]; + unsigned long mtotal, free, buffers, cached, mkernel, used; + unsigned long stotal, sused, sfree; + + void fill(unsigned scale); // fill sample with some fake values + }; + + struct MemStats { + const char *name; + unsigned long *stat; + }; + + KSample(KTimeMon *timemon, bool autoScale, unsigned pageScale, + unsigned swapScale, unsigned ctxScale); + virtual ~KSample(); + + void setScaling(bool autoScale, unsigned pageScale, + unsigned swapScale, unsigned ctxScale); + + Sample getSample(unsigned scale); // returns the current sample + Sample getRawSample(); // returns unscaled sample + void updateSample(); // updates the internally stored sample + +private: + void readSample(); // reads a new sample from /proc + unsigned long doScale(unsigned long value, unsigned scale1, + unsigned long scale2); + // converts pages to MB + void makeMBytes(unsigned long &pages); + + void fatal(const QString& msg); + void nonfatal(const QString& msg); + + KTimeMon *timemon; +#ifdef __linux__ + int memFD, statFD; +#elif defined(USE_SOLARIS) + struct kstat_ctl *kc; + bool warned; +#endif +#if defined(USE_SOLARIS) || defined(__osf__) + unsigned long pagesPerMB; +#endif + Sample sample, oldSample; + unsigned pageScale, swapScale, cxScale; + bool autoscale; + struct MemStats memstats[7]; +}; + +#endif // SAMPLE_H diff --git a/kicker-applets/ktimemon/timemon.cc b/kicker-applets/ktimemon/timemon.cc new file mode 100644 index 0000000..84b0e79 --- /dev/null +++ b/kicker-applets/ktimemon/timemon.cc @@ -0,0 +1,435 @@ + +/**********************************************************************/ +/* TimeMon (c) 1994 Helmut Maierhofer */ +/* KDE-ified M. Maierhofer 1998 */ +/* maintained by Dirk A. Mueller <[email protected]> */ +/**********************************************************************/ + +/* + * timemon.h + * + * Definitions for the timemon widget. + */ + +#include <config.h> + +#include <qpainter.h> +#include <qtimer.h> +#include <qtooltip.h> + +#include <kconfig.h> +#include <kglobal.h> +#include <klocale.h> +#include <khelpmenu.h> +#include <kpopupmenu.h> +#include <kprocess.h> +#include <kmessagebox.h> +#include <kdebug.h> + +#include "timemon.h" +#include "confdlg.h" +#include "sample.h" + +#include "timemon.moc" +#include <stdio.h> + +extern "C" +{ + KDE_EXPORT KPanelApplet* init(QWidget *parent, const QString& configFile) + { + KGlobal::locale()->insertCatalogue("ktimemon"); + KTimeMon *mon = new KTimeMon(configFile, KPanelApplet::Normal, + KPanelApplet::Preferences, parent, "ktimemon"); + return mon; + } +} + +// Update colour settings with the new ones from the config dialog. +void KTimeMon::updateConfig(KConfDialog *d) +{ + kernelColour = d->getKernelColour(); + userColour = d->getUserColour(); + iowaitColour = d->getIOWaitColour(); + niceColour = d->getNiceColour(); + cachedColour = d->getCachedColour(); + usedColour = d->getUsedColour(); + buffersColour = d->getBuffersColour(); + mkernelColour = d->getMKernelColour(); + swapColour = d->getSwapColour(); + bgColour = d->getBgColour(); +} + +// ----------------------------------------------------------------------------- +// some KPanelApplet API functions + +int KTimeMon::widthForHeight(int height) const +{ + int s = (int) (vertical ? 2/3.*height : height); + return s>=18? s : 18; +} + + +int KTimeMon::heightForWidth(int width) const +{ + int s = (int) (vertical ? width : 2/3.*width); + return s>=18? s : 18; +} + +void KTimeMon::preferences() +{ + configure(); +} + + +// ----------------------------------------------------------------------------- +// Repaint the object; get the current sample and paint the bar graphs +// correspondingly. Use a pixmap to minimise flicker. + +void KTimeMon::paintEvent(QPaintEvent *) +{ + int w, h, x, y, b, r; + + w = vertical ? width() : height(); + h = vertical ? height() : width(); + + r = w; // remaining height + + x = 0; + + KSample::Sample s; + + if (sample != 0) + s = sample->getSample(h); + else + s.fill(h); + + QPixmap pixmap(width(), height()); + pixmap.fill(this, 0, 0); + + QPainter painter(&pixmap); + + b = r / 3; // bar width + r -= b; + + if (bgColour != colorGroup().background()) + { + paintRect(x, 0, b, h, bgColour, &painter); + } + + y = h - s.kernel; paintRect(x, y, b, s.kernel, kernelColour, &painter); + y -= s.iowait; paintRect(x, y, b, s.iowait, iowaitColour, &painter); + y -= s.user; paintRect(x, y, b, s.user, userColour, &painter); + y -= s.nice; paintRect(x, y, b, s.nice, niceColour, &painter); + + x += b; + b = r / 2; + r -= b; + + if (bgColour != colorGroup().background()) + { + paintRect(x, 0, b, h, bgColour, &painter); + } + + y = h - s.mkernel; paintRect(x, y, b, s.mkernel, mkernelColour, &painter); + y -= s.used; paintRect(x, y, b, s.used, usedColour, &painter); + y -= s.buffers; paintRect(x, y, b, s.buffers, buffersColour, &painter); + y -= s.cached; paintRect(x, y, b, s.cached, cachedColour, &painter); + + x += b; + b = r; + + if (bgColour != colorGroup().background()) + { + paintRect(x, 0, b, h, bgColour, &painter); + } + + y = h - s.sused; paintRect(x, y, b, s.sused, swapColour, &painter); + painter.end(); + + bitBlt(this, 0, 0, &pixmap); +} + +// ----------------------------------------------------------------------------- +// Draw part of a bar, depending on the bar orientation. + +void KTimeMon::paintRect(int x, int y, int w, int h, QColor c, QPainter *p) +{ + if (vertical) + p->fillRect(x, y, w, h, c); + else + p->fillRect(width() - y - h, x, h, w, c); +} + +// Show a tool-tip with some status information. +void KTimeMon::maybeTip(const QPoint& p) +{ + if (sample == 0) return; // no associated sample... + if(!rect().contains(p)) return; + + KSample::Sample s = sample->getSample(100); // scale to 100(%) + int idle = 100 - s.kernel - s.user - s.nice; + if ( idle < 0 ) + idle = 0; + QString str = i18n("cpu: %1% idle\nmem: %2 MB %3% free\nswap: %4 MB %5% free") + .arg(idle) + .arg(KGlobal::locale()->formatNumber(s.used/100.*s.mtotal, 0)) + .arg(100-s.used) + .arg(KGlobal::locale()->formatNumber(s.stotal, 0)) + .arg(100-s.sused); + + tip(rect(), str); +} + +// -- KTimeMon definition ------------------------------------------------ + +// Initialise the member variables, read the configuration data base, +// set up the widget, and start the timer. +KTimeMon::KTimeMon(const QString& configFile, Type type, int actions, + QWidget *parent, const char *name) + : KPanelApplet(configFile, type, actions, parent, name, WRepaintNoErase), QToolTip(this), + configDialog(0), bgProcess(0), + kernelColour("red1"), userColour("blue"), + niceColour("yellow"), iowaitColour("darkgreen"), + usedColour("blue1"), buffersColour("yellow"), + cachedColour("darkgreen"), mkernelColour("red1"), + swapColour("cyan3"), bgColour(colorGroup().background()) +{ + mouseAction[0] = NOTHING; + mouseAction[1] = NOTHING; + mouseAction[2] = MENU; + + KConfig* conf = config(); + conf->setGroup("Parameters"); + interval = conf->readUnsignedNumEntry("Interval", 500); + autoScale = conf->readBoolEntry("AutoScale", true); + + pageScale = conf->readUnsignedNumEntry("PageScale", 10); + swapScale = conf->readUnsignedNumEntry("SwapScale", 5); + ctxScale = conf->readUnsignedNumEntry("ContextScale", 300); + for (int i = 0; i < MAX_MOUSE_ACTIONS; i++) { + QString n; + n.setNum(i); + + mouseAction[i] = (MouseAction) + conf->readUnsignedNumEntry(QString("MouseAction")+n, mouseAction[i]); + mouseActionCommand[i] = conf->readPathEntry(QString("MouseActionCommand")+n); + } + + conf->setGroup("Interface"); + kernelColour = conf->readColorEntry("KernelColour", &kernelColour); + userColour = conf->readColorEntry("UserColour", &userColour); + niceColour = conf->readColorEntry("NiceColour", &niceColour); + iowaitColour = conf->readColorEntry("IOWaitColour", &iowaitColour); + cachedColour = conf->readColorEntry("CachedColour", &cachedColour); + usedColour = conf->readColorEntry("UsedColour", &usedColour); + buffersColour = conf->readColorEntry("BuffersColour", &buffersColour); + swapColour = conf->readColorEntry("SwapColour", &swapColour); + mkernelColour = conf->readColorEntry("MKernelColour", &mkernelColour); + bgColour = conf->readColorEntry("BgColour", &bgColour); + + vertical = conf->readBoolEntry("Vertical", true); + + timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), this, SLOT(timeout())); + timer->start(interval); + + sample = new KSample(this, autoScale, pageScale, swapScale, ctxScale); + + QString aboutmsg = i18n("KTimeMon for KDE\n" + "Maintained by Dirk A. Mueller <[email protected]>\n" + "Written by M. Maierhofer ([email protected])\n" + "Based on timemon by H. Maierhofer"); + + hmenu = new KHelpMenu(this, aboutmsg); + menu = new KPopupMenu(this); + + menu->insertTitle( SmallIcon( "ktimemon" ), i18n( "System Monitor" ) ) ; + menu->insertItem(i18n("Horizontal Bars"), 4); + menu->insertItem(SmallIcon( "configure" ), i18n( "Preferences..." ), 2); + menu->insertSeparator(); + menu->insertItem(SmallIcon( "help" ), i18n("Help"), hmenu->menu(), 1); + + menu->connectItem(2, this, SLOT(configure())); + menu->connectItem(4, this, SLOT(orientation())); + + menu->setCheckable(true); + + vertical = !vertical; // and similar for orientation + orientation(); +} + +// ----------------------------------------------------------------------------- + +// delete the member variables +KTimeMon::~KTimeMon() +{ + delete sample; + delete bgProcess; + KGlobal::locale()->removeCatalogue("ktimemon"); +} + + +// Apply the settings from the configuration dialog and save them. +void KTimeMon::apply() +{ + stop(); + interval = configDialog->getInterval(); + cont(); + + updateConfig(configDialog); + + sample->setScaling(configDialog->getAutoScale(), + configDialog->getPageScale(), + configDialog->getSwapScale(), + configDialog->getCtxScale()); + + for (int i = 0; i < MAX_MOUSE_ACTIONS; i++) { + mouseAction[i] = (MouseAction) configDialog->getMouseAction(i); + mouseActionCommand[i] = configDialog->getMouseActionCommand(i); + } + + update(); + writeConfiguration(); +} + +void KTimeMon::stop() +{ + timer->stop(); +} + +void KTimeMon::cont() +{ + timer->start(interval); +} + +// Dump the current configuration entries to the data base. +void KTimeMon::writeConfiguration() +{ + KConfig* conf = config(); + conf->setGroup("Interface"); + conf->writeEntry("KernelColour", kernelColour); + conf->writeEntry("UserColour", userColour); + conf->writeEntry("NiceColour", niceColour); + conf->writeEntry("IOWaitColour", iowaitColour); + conf->writeEntry("CachedColour", cachedColour); + conf->writeEntry("UsedColour", usedColour); + conf->writeEntry("BuffersColour", buffersColour); + conf->writeEntry("MKernelColour", mkernelColour); + conf->writeEntry("SwapColour", swapColour); + conf->writeEntry("BgColour", bgColour); + conf->writeEntry("Mode", true); + conf->writeEntry("Vertical", vertical); + + conf->setGroup("Parameters"); + conf->writeEntry("Interval", interval); + conf->writeEntry("AutoScale", autoScale); + conf->writeEntry("PageScale", pageScale); + conf->writeEntry("SwapScale", swapScale); + conf->writeEntry("ContextScale", ctxScale); + conf->writeEntry("WidgetSize", size()); + for (int i = 0; i < MAX_MOUSE_ACTIONS; i++) { + QString n; + n.setNum(i); + + conf->writeEntry(QString("MouseAction")+n, (unsigned)mouseAction[i]); + conf->writePathEntry(QString("MouseActionCommand")+n, mouseActionCommand[i]); + } + conf->sync(); +} + +// Make the KSample object update its internal sample and repaint the +// object. +void KTimeMon::timeout() +{ + sample->updateSample(); + update(); +} + +// This is called when the session management strikes, and also when the +// main program exits with a code of 0 (i.e. there was no error). +void KTimeMon::save() +{ + writeConfiguration(); +} + +// ----------------------------------------------------------------------------- +// Update the configuration dialog with the current values and show it. + +void KTimeMon::configure() +{ + if (configDialog == 0) configDialog = new KConfDialog(this); + configDialog->update(); + configDialog->show(); +} + +// ----------------------------------------------------------------------------- +// Change the orientation of the status bars + +void KTimeMon::orientation() +{ + vertical = !vertical; + + KConfig* conf = config(); + conf->setGroup("Interface"); + conf->writeEntry("Vertical", vertical); + + menu->setItemChecked(4, !vertical); + + update(); + emit updateLayout(); +} + +// Pop up the menu when the appropriate button has been pressed. +void KTimeMon::mousePressEvent(QMouseEvent *event) +{ + if (event == 0) return; + + int index = -1; + if (event->button() == LeftButton) index = 0; + else if (event->button() == MidButton) index = 1; + else if (event->button() == RightButton) index = 2; + + if (index == -1) return; + + switch (mouseAction[index]) { + case NOTHING: + break; + case SWITCH: + break; + case MENU: + menu->popup(mapToGlobal(event->pos())); + break; + case COMMAND: + runCommand(index); + break; + } +} + +// Start the given command +void KTimeMon::runCommand(int index) +{ + // just in case it still hangs around + delete bgProcess; + + bgProcess = new KShellProcess; + *bgProcess << mouseActionCommand[index]; + connect(bgProcess, SIGNAL(receivedStderr(KProcess *, char *, int)), + this, SLOT(commandStderr(KProcess *, char *, int))); + bgProcess->start(KProcess::DontCare, KProcess::Stderr); +} + +// ----------------------------------------------------------------------------- +// Check if there is any diagnostic output (command not found or such) + +void KTimeMon::commandStderr(KProcess * /*proc*/, char *buffer, int /*length*/) +{ + QString msgbuf; + + msgbuf = i18n("Got diagnostic output from child command:\n\n"); + msgbuf += QString::fromLocal8Bit(buffer); + + KMessageBox::information(this, msgbuf); +} + + +// ----------------------------------------------------------------------------- diff --git a/kicker-applets/ktimemon/timemon.h b/kicker-applets/ktimemon/timemon.h new file mode 100644 index 0000000..8f5664c --- /dev/null +++ b/kicker-applets/ktimemon/timemon.h @@ -0,0 +1,107 @@ +/* -*- C++ -*- */ + +/**********************************************************************/ +/* TimeMon (c) 1994 Helmut Maierhofer */ +/* KDE-ified M. Maierhofer 1998 */ +/* maintained by Dirk A. Mueller <[email protected] */ +/**********************************************************************/ + +/* + * timemon.h + * + * Definitions for the timemon widget. + */ + +#ifndef TIMEMON_H +#define TIMEMON_H + +#include <qtooltip.h> +#include <kiconloader.h> +#include <kpanelapplet.h> + +// -- global constants --------------------------------------------------- + +const int MAX_MOUSE_ACTIONS = 3; // event handlers for the three buttons only + +// -- forward declaration ------------------------------------------------ +class KSample; +class KConfDialog; +class QPaintEvent; +class QMouseEvent; +class QPainter; +class KProcess; +class KShellProcess; +class KHelpMenu; +class KPopupMenu; + +// -- KTimeMon declaration ----------------------------------------------- + +/* + * KTimeMon + * + * This is the main widget of the application. It handles the configuration + * dialog and may have an associated KTimeMonWidget in the panel (in which + * case it hides itself). + */ + +class KTimeMon : public KPanelApplet, QToolTip { + Q_OBJECT +public: + enum MouseAction { NOTHING, SWITCH, MENU, COMMAND }; + + KTimeMon(const QString& configFile, Type t = Normal, int actions = 0, + QWidget *parent = 0, const char *name = 0); + virtual ~KTimeMon(); + + void writeConfiguration(); // write back the configuration data + + // reimplemented from KPanelApplet + virtual int widthForHeight(int height) const; + virtual int heightForWidth(int width) const; + + virtual void preferences(); + + void stop(); + void cont(); + +public slots: + void timeout(); // timer expired + void save(); // session management callback + void apply(); // apply configuration information + +protected: + virtual void maybeTip(const QPoint&); + virtual void mousePressEvent(QMouseEvent *event); + virtual void updateConfig(KConfDialog *d); + virtual void paintEvent(QPaintEvent *event); + +private slots: // called from the menu + void configure(); // show the configuration dialog + void orientation(); // switch vertical/horizontal orientation + void commandStderr(KProcess *proc, char *buffer, int length); + +private: + void runCommand(int index); + void paintRect(int x, int y, int w, int h, QColor c, QPainter *p); + + unsigned interval; + bool autoScale; + unsigned pageScale, swapScale, ctxScale; + KPopupMenu* menu; + KHelpMenu* hmenu; + QTimer* timer; + KConfDialog *configDialog; + MouseAction mouseAction[MAX_MOUSE_ACTIONS]; + QString mouseActionCommand[MAX_MOUSE_ACTIONS]; + KShellProcess *bgProcess; + + KSample *sample; + QColor kernelColour, userColour, niceColour, iowaitColour; + QColor usedColour, buffersColour, cachedColour, mkernelColour; + QColor swapColour, bgColour; + bool vertical, tooltip; + + friend class KConfDialog; +}; + +#endif // TIMEMON_H |