summaryrefslogtreecommitdiffstats
path: root/klaptopdaemon
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit2bda8f7717adf28da4af0d34fb82f63d2868c31d (patch)
tree8d927b7b47a90c4adb646482a52613f58acd6f8c /klaptopdaemon
downloadtdeutils-2bda8f7717adf28da4af0d34fb82f63d2868c31d.tar.gz
tdeutils-2bda8f7717adf28da4af0d34fb82f63d2868c31d.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/kdeutils@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'klaptopdaemon')
-rw-r--r--klaptopdaemon/Makefile.am49
-rw-r--r--klaptopdaemon/README8
-rw-r--r--klaptopdaemon/acpi.cpp281
-rw-r--r--klaptopdaemon/acpi.h72
-rw-r--r--klaptopdaemon/acpi_helper.cpp325
-rw-r--r--klaptopdaemon/apm.cpp285
-rw-r--r--klaptopdaemon/apm.h71
-rw-r--r--klaptopdaemon/applnk/.directory48
-rw-r--r--klaptopdaemon/applnk/Makefile.am4
-rw-r--r--klaptopdaemon/applnk/klaptopdaemon.desktop116
-rw-r--r--klaptopdaemon/applnk/laptop.desktop135
-rw-r--r--klaptopdaemon/applnk/pcmcia.desktop84
-rw-r--r--klaptopdaemon/battery.cpp390
-rw-r--r--klaptopdaemon/battery.h100
-rw-r--r--klaptopdaemon/buttons.cpp620
-rw-r--r--klaptopdaemon/buttons.h92
-rw-r--r--klaptopdaemon/checkcrc.h53
-rw-r--r--klaptopdaemon/configure.in.bot9
-rw-r--r--klaptopdaemon/configure.in.in49
-rw-r--r--klaptopdaemon/daemon_state.cpp282
-rw-r--r--klaptopdaemon/daemon_state.h141
-rw-r--r--klaptopdaemon/daemondock.cpp756
-rw-r--r--klaptopdaemon/daemondock.h108
-rw-r--r--klaptopdaemon/kpcmcia.cpp547
-rw-r--r--klaptopdaemon/kpcmcia.h214
-rw-r--r--klaptopdaemon/kpcmciainfo.cpp313
-rw-r--r--klaptopdaemon/kpcmciainfo.h116
-rw-r--r--klaptopdaemon/krichtextlabel.cpp112
-rw-r--r--klaptopdaemon/krichtextlabel.h65
-rw-r--r--klaptopdaemon/laptop_check.cpp53
-rw-r--r--klaptopdaemon/laptop_daemon.cpp1083
-rw-r--r--klaptopdaemon/laptop_daemon.h186
-rw-r--r--klaptopdaemon/linux/bulkmem.h184
-rw-r--r--klaptopdaemon/linux/ciscode.h96
-rw-r--r--klaptopdaemon/linux/cisreg.h105
-rw-r--r--klaptopdaemon/linux/cistpl.h543
-rw-r--r--klaptopdaemon/linux/cs.h455
-rw-r--r--klaptopdaemon/linux/cs_types.h50
-rw-r--r--klaptopdaemon/linux/driver_ops.h71
-rw-r--r--klaptopdaemon/linux/ds.h142
-rw-r--r--klaptopdaemon/linux/ftl.h62
-rw-r--r--klaptopdaemon/linux/k_compat.h246
-rw-r--r--klaptopdaemon/linux/mem_op.h120
-rw-r--r--klaptopdaemon/linux/memory.h30
-rw-r--r--klaptopdaemon/linux/ss.h113
-rw-r--r--klaptopdaemon/linux/version.h4
-rw-r--r--klaptopdaemon/main.cpp305
-rw-r--r--klaptopdaemon/main.h82
-rw-r--r--klaptopdaemon/makecrc.cpp38
-rw-r--r--klaptopdaemon/pcmcia.cpp122
-rw-r--r--klaptopdaemon/pcmcia.h70
-rw-r--r--klaptopdaemon/pics/Makefile.am6
-rw-r--r--klaptopdaemon/pics/README36
-rw-r--r--klaptopdaemon/pics/actions/Makefile.am3
-rw-r--r--klaptopdaemon/pics/actions/cr16-action-alt2_laptop_nobattery.pngbin0 -> 395 bytes
-rw-r--r--klaptopdaemon/pics/actions/cr16-action-alt2_laptop_nocharge.pngbin0 -> 280 bytes
-rw-r--r--klaptopdaemon/pics/actions/cr16-action-alt2_laptop_power.pngbin0 -> 317 bytes
-rw-r--r--klaptopdaemon/pics/actions/cr16-action-alt3_laptop_nocharge.pngbin0 -> 280 bytes
-rw-r--r--klaptopdaemon/pics/actions/cr16-action-alt3_laptop_power.pngbin0 -> 284 bytes
-rw-r--r--klaptopdaemon/pics/actions/cr16-action-alt_laptop_nocharge.pngbin0 -> 795 bytes
-rw-r--r--klaptopdaemon/pics/actions/cr16-action-alt_laptop_power.pngbin0 -> 775 bytes
-rw-r--r--klaptopdaemon/pics/actions/cr16-action-laptop_charge.pngbin0 -> 296 bytes
-rw-r--r--klaptopdaemon/pics/actions/cr16-action-laptop_nobattery.pngbin0 -> 352 bytes
-rw-r--r--klaptopdaemon/pics/actions/cr16-action-laptop_nocharge.pngbin0 -> 305 bytes
-rw-r--r--klaptopdaemon/pics/actions/cr16-action-power.pngbin0 -> 335 bytes
-rw-r--r--klaptopdaemon/pics/actions/cr22-action-laptop_charge.pngbin0 -> 966 bytes
-rw-r--r--klaptopdaemon/pics/actions/cr22-action-laptop_nobattery.pngbin0 -> 1022 bytes
-rw-r--r--klaptopdaemon/pics/actions/cr22-action-laptop_nocharge.pngbin0 -> 395 bytes
-rw-r--r--klaptopdaemon/pics/actions/cr22-action-laptop_power.pngbin0 -> 832 bytes
-rw-r--r--klaptopdaemon/pics/actions/cr32-action-power.pngbin0 -> 421 bytes
-rw-r--r--klaptopdaemon/pics/cr128-app-laptop_battery.pngbin0 -> 10017 bytes
-rw-r--r--klaptopdaemon/pics/cr16-app-laptop_battery.pngbin0 -> 912 bytes
-rw-r--r--klaptopdaemon/pics/cr16-app-laptop_pcmcia.pngbin0 -> 477 bytes
-rw-r--r--klaptopdaemon/pics/cr32-app-laptop_battery.pngbin0 -> 2374 bytes
-rw-r--r--klaptopdaemon/pics/cr32-app-laptop_pcmcia.pngbin0 -> 1375 bytes
-rw-r--r--klaptopdaemon/pics/cr48-app-laptop_battery.pngbin0 -> 3544 bytes
-rw-r--r--klaptopdaemon/pics/cr48-app-laptop_pcmcia.pngbin0 -> 1751 bytes
-rw-r--r--klaptopdaemon/pics/cr64-app-laptop_battery.pngbin0 -> 4730 bytes
-rw-r--r--klaptopdaemon/pics/crsc-app-laptop_battery.svgzbin0 -> 4371 bytes
-rw-r--r--klaptopdaemon/portable.cpp3087
-rw-r--r--klaptopdaemon/portable.h147
-rw-r--r--klaptopdaemon/power.cpp587
-rw-r--r--klaptopdaemon/power.h98
-rw-r--r--klaptopdaemon/profile.cpp424
-rw-r--r--klaptopdaemon/profile.h82
-rw-r--r--klaptopdaemon/smapi.h54
-rw-r--r--klaptopdaemon/smapibios.h93
-rw-r--r--klaptopdaemon/smapidev.c743
-rw-r--r--klaptopdaemon/smapidev.h273
-rw-r--r--klaptopdaemon/sony.cpp200
-rw-r--r--klaptopdaemon/sony.h71
-rw-r--r--klaptopdaemon/thinkpad_common.h127
-rw-r--r--klaptopdaemon/version.h19
-rw-r--r--klaptopdaemon/wake_laptop.cpp39
-rw-r--r--klaptopdaemon/warning.cpp602
-rw-r--r--klaptopdaemon/warning.h106
-rw-r--r--klaptopdaemon/xautolock.cc277
-rw-r--r--klaptopdaemon/xautolock.h77
-rw-r--r--klaptopdaemon/xautolock_c.h76
-rw-r--r--klaptopdaemon/xautolock_diy.c289
-rw-r--r--klaptopdaemon/xautolock_engine.c419
101 files changed, 17540 insertions, 0 deletions
diff --git a/klaptopdaemon/Makefile.am b/klaptopdaemon/Makefile.am
new file mode 100644
index 0000000..8a2e737
--- /dev/null
+++ b/klaptopdaemon/Makefile.am
@@ -0,0 +1,49 @@
+kde_module_LTLIBRARIES = kcm_laptop.la kded_klaptopdaemon.la
+bin_PROGRAMS = klaptop_acpi_helper klaptop_check
+lib_LTLIBRARIES = libkcmlaptop.la
+SUBDIRS = pics applnk
+
+libkcmlaptop_la_SOURCES = portable.cpp smapidev.c daemon_state.cpp wake_laptop.cpp krichtextlabel.cpp
+libkcmlaptop_la_LDFLAGS = $(all_libraries)
+libkcmlaptop_la_LIBADD = $(LIB_KDEUI)
+
+MESSAGE_SOURCES = laptop_daemon.cpp kpcmcia.cpp xautolock.cc kpcmciainfo.cpp daemondock.cpp xautolock_diy.c xautolock_engine.c
+kded_klaptopdaemon_la_SOURCES = $(MESSAGE_SOURCES) laptop_daemon.skel
+kded_klaptopdaemon_la_LDFLAGS = $(all_libraries) -module -avoid-version -lXtst
+kded_klaptopdaemon_la_LIBADD = $(LIB_KDEUI) $(LIB_XSS) libkcmlaptop.la
+
+klaptop_acpi_helper_SOURCES = acpi_helper.cpp
+
+klaptop_check_SOURCES = laptop_check.cpp
+klaptop_check_LDFLAGS = $(all_libraries)
+klaptop_check_LDADD = $(LIB_KFILE) $(LIB_KDEUI) libkcmlaptop.la
+
+kcm_laptop_la_SOURCES = battery.cpp main.cpp pcmcia.cpp power.cpp warning.cpp \
+ acpi.cpp sony.cpp profile.cpp buttons.cpp apm.cpp
+kcm_laptop_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module
+kcm_laptop_la_LIBADD = $(LIB_KFILE) $(LIB_KDEUI) libkcmlaptop.la
+kcm_laptop_la_COMPILE_FIRST = crcresult.h
+
+AM_CPPFLAGS = $(all_includes)
+
+AM_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+
+KDE_OPTIONS = nofinal
+
+kcm_laptop_la_METASOURCES = AUTO
+
+messages:
+ $(XGETTEXT) $(libkcmlaptop_la_SOURCES) $(klaptop_acpi_helper_SOURCES) $(klaptop_check_SOURCES) $(MESSAGE_SOURCES) -o $(podir)/klaptopdaemon.pot
+ $(XGETTEXT) $(kcm_laptop_la_SOURCES) -o $(podir)/kcmlaptop.pot
+
+dummy.cpp:
+ echo >dummy.cpp
+
+noinst_PROGRAMS = makecrc
+makecrc_SOURCES = makecrc.cpp
+makecrc_LDADD = $(LIBZ)
+
+crcresult.h: makecrc klaptop_acpi_helper
+ ./makecrc >crcresult.h
+
+CLEANFILES = crcresult.h makecrc
diff --git a/klaptopdaemon/README b/klaptopdaemon/README
new file mode 100644
index 0000000..858e0ff
--- /dev/null
+++ b/klaptopdaemon/README
@@ -0,0 +1,8 @@
+This is klaptop daemon it provides battery monitoring and management
+for laptops - this is a KDE 2 rewrite of kcmlaptop which is not
+supported for KDE >2.0. Please pass any bug reports to Paul Campbell
+paul@taniwha.com.
+
+The power management stuff is all abstracted out into portable.*
+if you feel the urge to port it to your OS/CPU please contact me for
+help - Paul
diff --git a/klaptopdaemon/acpi.cpp b/klaptopdaemon/acpi.cpp
new file mode 100644
index 0000000..cb13f40
--- /dev/null
+++ b/klaptopdaemon/acpi.cpp
@@ -0,0 +1,281 @@
+/*
+ * acpi.cpp
+ *
+ * Copyright (c) 1999, 2003 Paul Campbell <paul@taniwha.com>
+ *
+ * Requires the Qt widget libraries, available at no cost at
+ * http://www.troll.no/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+// my headers:
+#include "acpi.h"
+#include "version.h"
+#include "portable.h"
+#include <stdlib.h>
+#include <unistd.h>
+
+// other KDE headers:
+#include <klocale.h>
+#include <kconfig.h>
+#include <knuminput.h>
+#include <kiconloader.h>
+#include <kicondialog.h>
+#include <kapplication.h>
+#include <kmessagebox.h>
+#include <kstandarddirs.h>
+#include <kprocess.h>
+
+// other Qt headers:
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qcheckbox.h>
+#include <qhbox.h>
+#include <qvgroupbox.h>
+#include <qhgroupbox.h>
+#include <qgrid.h>
+#include <qpushbutton.h>
+#include <qtooltip.h>
+extern void wake_laptop_daemon();
+
+AcpiConfig::AcpiConfig (QWidget * parent, const char *name)
+ : KCModule(parent, name)
+{
+ KGlobal::locale()->insertCatalogue("klaptopdaemon"); // For translation of klaptopdaemon messages
+
+ config = new KConfig("kcmlaptoprc");
+
+ QVBoxLayout *top_layout = new QVBoxLayout( this, KDialog::marginHint(),
+ KDialog::spacingHint() );
+
+ QLabel *tmp_label = new QLabel( i18n("This panel provides information about your system's ACPI implementation "
+ "and lets you have access to some of the extra features provided by ACPI"), this );
+ tmp_label->setAlignment( Qt::WordBreak );
+ top_layout->addWidget( tmp_label );
+
+ tmp_label = new QLabel( i18n("NOTE: the Linux ACPI implementation is still a 'work in progress'. "
+ "Some features, in particular suspend and hibernate are not yet available "
+ "under 2.4 - and under 2.5 some particular ACPI implementations are still "
+ "unstable, these check boxes let you only enable the things that work reliably. "
+ "You should test these features very gingerly - save all your work, check them "
+ "on and try a suspend/standby/hibernate from the popup menu on the battery icon "
+ "in the panel if it fails to come back successfully uncheck the box again."), this );
+ tmp_label->setAlignment( Qt::WordBreak );
+ top_layout->addWidget( tmp_label );
+
+ tmp_label = new QLabel( i18n("Some changes made on this page may require you to quit the laptop panel "
+ "and start it again to take effect"), this );
+ tmp_label->setAlignment( Qt::WordBreak );
+ top_layout->addWidget( tmp_label );
+
+ bool can_enable = laptop_portable::has_acpi(1); // is helper ready
+ enableStandby = new QCheckBox( i18n("Enable standby"), this );
+ top_layout->addWidget( enableStandby );
+ QToolTip::add( enableStandby, i18n( "If checked this box enables transitions to the 'standby' state - a temporary powered down state" ) );
+ enableStandby->setEnabled(can_enable);
+ connect( enableStandby, SIGNAL(clicked()), this, SLOT(configChanged()) );
+
+ enableSuspend = new QCheckBox( i18n("Enable &suspend"), this );
+ top_layout->addWidget( enableSuspend );
+ QToolTip::add( enableSuspend, i18n( "If checked this box enables transitions to the 'suspend' state - a semi-powered down state, sometimes called 'suspend-to-ram'" ) );
+ enableSuspend->setEnabled(can_enable);
+ connect( enableSuspend, SIGNAL(clicked()), this, SLOT(configChanged()) );
+
+ QHBoxLayout *ll = new QHBoxLayout();
+ enableHibernate = new QCheckBox( i18n("Enable &hibernate"), this );
+ ll->addWidget( enableHibernate );
+ QToolTip::add( enableHibernate, i18n( "If checked this box enables transitions to the 'hibernate' state - a powered down state, sometimes called 'suspend-to-disk'" ) );
+ enableHibernate->setEnabled(can_enable);
+ connect( enableHibernate, SIGNAL(clicked()), this, SLOT(configChanged()) );
+ if (laptop_portable::has_software_suspend()) {
+ ll->addStretch(1);
+ enableSoftwareSuspendHibernate = new QCheckBox( i18n("Use software suspend for hibernate"), this );
+ ll->addWidget( enableSoftwareSuspendHibernate );
+ QToolTip::add( enableSoftwareSuspendHibernate, i18n( "If checked this box enables transitions to the 'hibernate' state - a powered down state, sometimes called 'suspend-to-disk' - the kernel 'Software Suspend' mechanism will be used instead of using ACPI directly" ) );
+ enableSoftwareSuspendHibernate->setEnabled(laptop_portable::has_software_suspend(2));
+ connect( enableSoftwareSuspendHibernate, SIGNAL(clicked()), this, SLOT(configChanged()) );
+ } else {
+ enableSoftwareSuspendHibernate = 0;
+ }
+ ll->addStretch(10);
+
+ top_layout->addLayout(ll);
+
+ enablePerformance = new QCheckBox( i18n("Enable &performance profiles"), this );
+ top_layout->addWidget( enablePerformance );
+ QToolTip::add( enablePerformance, i18n( "If checked this box enables access to ACPI performance profiles - usually OK in 2.4 and later" ) );
+ enablePerformance->setEnabled(can_enable);
+ connect( enablePerformance, SIGNAL(clicked()), this, SLOT(configChanged()) );
+
+ enableThrottle = new QCheckBox( i18n("Enable &CPU throttling"), this );
+ top_layout->addWidget( enableThrottle );
+ QToolTip::add( enableThrottle, i18n( "If checked this box enables access to ACPI throttle speed changes - usually OK in 2.4 and later" ) );
+ enableThrottle->setEnabled(can_enable);
+ connect( enableThrottle, SIGNAL(clicked()), this, SLOT(configChanged()) );
+
+ tmp_label = new QLabel(i18n("If the above boxes are disabled then there is no 'helper' "
+ "application set up to help change ACPI states, there are two "
+ "ways you can enable this application, either make the file "
+ "/proc/acpi/sleep writeable by anyone every time your system boots "
+ "or use the button below to make the KDE ACPI helper application "
+ "set-uid root"), this );
+ tmp_label->setAlignment( Qt::WordBreak );
+ top_layout->addWidget( tmp_label );
+ ll = new QHBoxLayout();
+ QPushButton *setupButton = new QPushButton(i18n("Setup Helper Application"), this);
+ connect( setupButton, SIGNAL(clicked()), this, SLOT(setupHelper()) );
+ QToolTip::add( setupButton, i18n( "This button can be used to enable the ACPI helper application" ) );
+ ll->addStretch(2);
+ ll->addWidget(setupButton);
+ ll->addStretch(8);
+ top_layout->addLayout(ll);
+
+
+ top_layout->addStretch(1);
+ top_layout->addWidget( new QLabel( i18n("Version: %1").arg(LAPTOP_VERSION), this), 0, Qt::AlignRight );
+
+
+ load();
+}
+
+AcpiConfig::~AcpiConfig()
+{
+ delete config;
+}
+
+#include "checkcrc.h"
+#include "crcresult.h"
+#include <qfile.h>
+
+void AcpiConfig::setupHelper()
+{
+ unsigned long len, crc;
+ QString helper = KStandardDirs::findExe("klaptop_acpi_helper");
+ checkcrc(QFile::encodeName(helper), len, crc);
+ if (len != file_len || crc != file_crc) {
+ QString str(i18n("The %1 application does not seem to have "
+ "the same size or checksum as when it was compiled we do NOT recommend "
+ "you proceed with making it setuid-root without further investigation").arg(helper));
+ int rc = KMessageBox::warningContinueCancel(0, str, i18n("KLaptopDaemon"), i18n("Run Nevertheless"));
+ if (rc != KMessageBox::Continue)
+ return;
+ }
+
+ QString kdesu = KStandardDirs::findExe("kdesu");
+ if (!kdesu.isEmpty()) {
+ int rc = KMessageBox::warningContinueCancel(0,
+ i18n("You will need to supply a root password "
+ "to allow the privileges of the klaptop_acpi_helper to change."),
+ i18n("KLaptopDaemon"), KStdGuiItem::cont(),
+ "");
+ if (rc == KMessageBox::Continue) {
+ KProcess proc;
+ proc << kdesu;
+ proc << "-u";
+ proc << "root";
+ proc << "chown root "+helper+"; chmod +s "+helper;
+ proc.start(KProcess::Block); // run it sync so has_acpi below sees the results
+ }
+ } else {
+ KMessageBox::sorry(0, i18n("The ACPI helper cannot be enabled because kdesu cannot be found. Please make sure that it is installed correctly."),
+ i18n("KLaptopDaemon"));
+ }
+ laptop_portable::acpi_set_mask(enablestandby, enablesuspend, enablehibernate, enableperformance, enablethrottle);
+ bool can_enable = laptop_portable::has_acpi(1); // is helper ready
+ enableStandby->setEnabled(can_enable);
+ enableSuspend->setEnabled(can_enable);
+ enableHibernate->setEnabled(can_enable);
+ enablePerformance->setEnabled(can_enable);
+ enableThrottle->setEnabled(can_enable);
+ if (enableSoftwareSuspendHibernate)
+ enableSoftwareSuspendHibernate->setEnabled(laptop_portable::has_software_suspend(2));
+ wake_laptop_daemon();
+}
+
+
+void AcpiConfig::save()
+{
+ enablestandby = enableStandby->isChecked();
+ enablesuspend = enableSuspend->isChecked();
+ enablehibernate = enableHibernate->isChecked();
+ enablesoftwaresuspend = (enableSoftwareSuspendHibernate?enableSoftwareSuspendHibernate->isChecked():0);
+ enableperformance = enablePerformance->isChecked();
+ enablethrottle = enableThrottle->isChecked();
+ laptop_portable::acpi_set_mask(enablestandby, enablesuspend, enablehibernate, enableperformance, enablethrottle);
+
+ config->setGroup("AcpiDefault");
+
+ config->writeEntry("EnableStandby", enablestandby);
+ config->writeEntry("EnableSuspend", enablesuspend);
+ config->writeEntry("EnableHibernate", enablehibernate);
+ config->writeEntry("EnableThrottle", enablethrottle);
+ config->writeEntry("EnablePerformance", enableperformance);
+ config->setGroup("SoftwareSuspendDefault");
+ config->writeEntry("EnableHibernate", enablesoftwaresuspend);
+ config->sync();
+ changed(false);
+ wake_laptop_daemon();
+}
+
+void AcpiConfig::load()
+{
+ load( false );
+}
+
+void AcpiConfig::load(bool useDefaults)
+{
+ config->setReadDefaults( useDefaults );
+
+ config->setGroup("AcpiDefault");
+
+ enablestandby = config->readBoolEntry("EnableStandby", false);
+ enableStandby->setChecked(enablestandby);
+ enablesuspend = config->readBoolEntry("EnableSuspend", false);
+ enableSuspend->setChecked(enablesuspend);
+ enablehibernate = config->readBoolEntry("EnableHibernate", false);
+ enableHibernate->setChecked(enablehibernate);
+ enableperformance = config->readBoolEntry("EnablePerformance", false);
+ enablePerformance->setChecked(enableperformance);
+ enablethrottle = config->readBoolEntry("EnableThrottle", false);
+ enableThrottle->setChecked(enablethrottle);
+ config->setGroup("SoftwareSuspendDefault");
+ enablesoftwaresuspend = config->readBoolEntry("EnableHibernate", false);
+ if (enableSoftwareSuspendHibernate)
+ enableSoftwareSuspendHibernate->setChecked(enablesoftwaresuspend);
+
+ emit changed(useDefaults);
+}
+
+void AcpiConfig::defaults()
+{
+ load( true );
+}
+
+
+void AcpiConfig::configChanged()
+{
+ emit changed(true);
+}
+
+
+QString AcpiConfig::quickHelp() const
+{
+ return i18n("<h1>ACPI Setup</h1>This module allows you to configure ACPI for your system");
+}
+
+#include "acpi.moc"
+
+
diff --git a/klaptopdaemon/acpi.h b/klaptopdaemon/acpi.h
new file mode 100644
index 0000000..a6a77cb
--- /dev/null
+++ b/klaptopdaemon/acpi.h
@@ -0,0 +1,72 @@
+/*
+ * acpi.h
+ *
+ * Copyright (c) 2002 Paul Campbell <paul@taniwha.com>
+ *
+ * Requires the Qt widget libraries, available at no cost at
+ * http://www.troll.no/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef __ACPICONFIG_H__
+#define __ACPICONFIG_H__
+
+#include <kcmodule.h>
+#include <qstring.h>
+
+class QWidget;
+class QSpinBox;
+class KConfig;
+class QCheckBox;
+class KIconLoader;
+class KIconButton;
+class QPushButton;
+
+
+class AcpiConfig : public KCModule
+{
+ Q_OBJECT
+public:
+ AcpiConfig( QWidget *parent=0, const char* name=0);
+ ~AcpiConfig( );
+
+ void save( void );
+ void load();
+ void load( bool useDefaults );
+ void defaults();
+
+ virtual QString quickHelp() const;
+
+private slots:
+
+ void configChanged();
+ void setupHelper();
+
+private:
+ KConfig *config;
+
+ QCheckBox *enableHibernate;
+ QCheckBox *enableSuspend;
+ QCheckBox *enableStandby;
+ QCheckBox *enablePerformance;
+ QCheckBox *enableThrottle;
+ QCheckBox *enableSoftwareSuspendHibernate;
+ bool enablestandby, enablesuspend, enablehibernate, enableperformance, enablethrottle, enablesoftwaresuspend;
+};
+
+#endif
+
diff --git a/klaptopdaemon/acpi_helper.cpp b/klaptopdaemon/acpi_helper.cpp
new file mode 100644
index 0000000..660d2cb
--- /dev/null
+++ b/klaptopdaemon/acpi_helper.cpp
@@ -0,0 +1,325 @@
+/*
+ * acpi_helper.cpp - acpi helper
+ *
+ * Copyright (c) 2002 Paul Campbell <paul@taniwha.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+//
+// README!!
+//
+// This file contains code that is intended to be run setuid root
+// (only if the end user enables it themselves, it's not set that
+// way as part of a standard KDE build).
+//
+// Because of this this code should be simple and easily visually
+// inspected for security holes and/or bugs - if you feel the need
+// to change this file please get someone else to review your work
+// (I'll happily do it for you - mail me at paul@taniwha.com, please
+// review mine!)
+//
+// I recommend the following practices here - both for safety and
+// transparency:
+//
+// - check all array references (snprintf/strncpy etc)
+//
+// - avoid malloc/new calls and pointers too if possible
+//
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <string.h>
+
+#define MAX_TOSHIBA_STRING 64
+
+/* Write a value to /proc/acpi/sleep, where value may be between
+ 1 and 4 (whatever they mean). Does not return; calls exit(). */
+
+void write_to_proc_sleep(int value)
+{
+ char tmp[256];
+ int fd;
+
+ /* Sanity check value */
+ if ((value<1) || (value>4))
+ exit(1);
+
+ /* Convert value to string */
+ snprintf(tmp,sizeof(tmp),"%d",value);
+ tmp[sizeof(tmp)-1]=0;
+
+ /* Broken imitation of typing sync <enter> sync <enter>
+ on the command line before shutting down the machine;
+ part of the lore of UNIX machines. */
+ sync();
+ sync();
+ fd = open("/proc/acpi/sleep", O_RDWR);
+ if (fd < 0)
+ exit(1);
+ write(fd, tmp, 1);
+ close(fd);
+ setuid(getuid()); // drop all priority asap
+ exit(0);
+}
+
+/* Write string to new acpi power interface */
+void write_to_power(const char * str)
+{
+ int fd;
+ /* Broken imitation of typing sync <enter> sync <enter>
+ on the command line before shutting down the machine;
+ part of the lore of UNIX machines. */
+ sync();
+ sync();
+ fd = open("/sys/power/state", O_RDWR);
+ if (fd < 0)
+ exit(1);
+ write(fd, str, strlen(str));
+ close(fd);
+ setuid(getuid()); // drop all priority asap
+ exit(0);
+}
+
+/* Run the program @param path, if it exists and seems safe to do so.
+ Returns only if the program does not exist; if the program exists
+ and is unsafe, exit; if the program exists and is safe, run it
+ and never return. */
+void run_program(const char *path)
+{
+ struct stat sb;
+ int err;
+
+ if (!path) exit(1); /* Bad pointer */
+ if (path[0] != '/') exit(1); /* Not an absolute path */
+
+ if ((err = stat(path, &sb)) != 0 || sb.st_mode&S_IWOTH) {
+ if (err != 0) {
+ fprintf(stderr, "Can't find %s\n", path);
+ return;
+ } else {
+ fprintf(stderr, "%s is writeable by anyone - we don't trust it\n", path);
+ }
+ exit(1);
+ }
+ ::setuid(::geteuid()); // otherwise bash will throw it away
+ ::execl(path, NULL); // this is not KDE environment code
+ exit(0);
+}
+
+int
+main(int argc, char **argv)
+{
+ int fd;
+ int i;
+ int toshibalcd_val = 0;
+ bool useSysPower=false;
+
+ fd = open("/sys/power/state", O_RDWR);
+ if (fd >= 0)
+ useSysPower=true;
+ close(fd);
+
+ ::close(0); // we're setuid - this is just in case
+ for (i = 1; i < argc; i++)
+ if (strcmp(argv[i], "--suspend") == 0 || strcmp(argv[i], "-suspend") == 0) {
+ /* Returns only if suspend does not exist. */
+ run_program("/usr/sbin/suspend");
+ if (useSysPower)
+ write_to_power("mem");
+ else
+ write_to_proc_sleep(3);
+ exit(0);
+ } else
+ if (strcmp(argv[i], "--standby") == 0 || strcmp(argv[i], "-standby") == 0) {
+ if (useSysPower)
+ write_to_power("standby");
+ else
+ write_to_proc_sleep(1);
+ exit(0);
+ } else
+ if (strcmp(argv[i], "--standby2") == 0 || strcmp(argv[i], "-standby2") == 0) {
+ write_to_proc_sleep(2);
+ exit(0);
+ } else
+ if (strcmp(argv[i], "--hibernate") == 0 || strcmp(argv[i], "-hibernate") == 0) {
+ run_program("/usr/sbin/hibernate");
+ if (useSysPower)
+ write_to_power("disk");
+ else
+ write_to_proc_sleep(4);
+ exit(0);
+ } else
+ if (strcmp(argv[i], "--software-suspend") == 0 || strcmp(argv[i], "-software-suspend") == 0) {
+ run_program("/usr/sbin/hibernate");
+ exit(0);
+ } else
+ if (strcmp(argv[i], "--throttling") == 0 || strcmp(argv[i], "-throttling") == 0) {
+ int val;
+ char tmp[256];
+
+ i++;
+ if (i >= argc)
+ break;
+ if (strlen(argv[i]) > 50 || strchr(argv[i], '.'))
+ break;
+ snprintf(tmp, sizeof(tmp), "/proc/acpi/processor/%s/throttling", argv[i]);
+ tmp[sizeof(tmp)-1] = 0;
+ i++;
+ if (i >= argc)
+ break;
+ val= atoi(argv[i]);
+ if (val < 0)
+ break;
+ sync();
+ sync();
+ fd = open(tmp, O_RDWR);
+ if (fd < 0)
+ exit(1);
+ snprintf(tmp, sizeof(tmp), "%d", val);
+ write(fd, tmp, strlen(tmp));
+ close(fd);
+ setuid(getuid()); // drop all priority asap
+ exit(0);
+ } else
+ if (strcmp(argv[i], "--performance") == 0 || strcmp(argv[i], "-performance") == 0) {
+ int val;
+ char tmp[256];
+
+ i++;
+ if (i >= argc)
+ break;
+ if (strlen(argv[i]) > 50 || strchr(argv[i], '.'))
+ break;
+ snprintf(tmp, sizeof(tmp), "/proc/acpi/processor/%s/performance", argv[i]);
+ tmp[sizeof(tmp)-1] = 0;
+ i++;
+ if (i >= argc)
+ break;
+ val= atoi(argv[i]);
+ if (val < 0)
+ break;
+ sync();
+ sync();
+ fd = open(tmp, O_RDWR);
+ if (fd < 0)
+ exit(1);
+ snprintf(tmp, sizeof(tmp), "%d", val);
+ write(fd, tmp, strlen(tmp));
+ close(fd);
+ setuid(getuid()); // drop all priority asap
+ exit(0);
+ } else
+ if (strcmp(argv[i], "--toshibalcd") == 0 || strcmp(argv[i], "-toshibalcd") == 0) {
+
+ i++;
+ if (i >= argc)
+ break;
+ toshibalcd_val= atoi(argv[i]);
+ if (toshibalcd_val < 0)
+ toshibalcd_val = 0;
+ if (toshibalcd_val > 7)
+ toshibalcd_val = 7;
+ fd = open("/proc/acpi/TOSHIBA1/lcd", O_RDWR);
+ if (fd >= 0 ) {
+ char c;
+
+ c = '0'+toshibalcd_val;
+ write(fd, &c, 1);
+ close(fd);
+ } else {
+ fd = open("/proc/acpi/toshiba/lcd", O_RDWR);
+ if (fd >= 0) {
+ char str[MAX_TOSHIBA_STRING];
+
+ snprintf(str,sizeof(str),"brightness : %d",toshibalcd_val);
+ str[sizeof(str)-1]=0;
+ write(fd,str,strlen(str));
+ close(fd);
+ }
+ }
+ setuid(getuid()); // drop all priority asap
+ exit(0);
+ } else
+ // CPUFreq support
+ if (strncmp(argv[i], "--cpufreq", 9) == 0 || strncmp(argv[i], "-cpufreq", 8) == 0) {
+ if ((i+1) >= argc)
+ break;
+ if (strlen(argv[i+1]) > 50 || strchr(argv[i+1], '.'))
+ break;
+ int val;
+ char tmp[256];
+ // CPUFreq support for the interface of the 2.4 kernell (/proc/sys/cpu/N/)
+ if (strcmp(argv[i], "--cpufreq-24") == 0 || strcmp(argv[i], "-cpufreq-24") == 0) {
+ ++i;
+ snprintf(tmp, sizeof(tmp), "/proc/sys/cpu/%s/speed", argv[i]);
+ tmp[sizeof(tmp)-1] = 0;
+ ++i;
+ if (i >= argc)
+ break;
+ val = atoi(argv[i]);
+ if (val < 0)
+ break;
+ fd = open(tmp, O_WRONLY);
+ if (fd < 0)
+ exit(1);
+ snprintf(tmp, sizeof(tmp), "%d", val);
+ write(fd, tmp, strlen(tmp));
+ } else
+ // CPUFreq support for the interface of the 2.5 kernel (/proc/cpufreq)
+ if (strcmp(argv[i], "--cpufreq-25") == 0 || strcmp(argv[i], "-cpufreq-25") == 0) {
+ ++i;
+ snprintf(tmp, sizeof(tmp), "%s", argv[i]);
+ tmp[sizeof(tmp)-1] = 0;
+ fd = open("/proc/cpufreq", O_WRONLY);
+ if (fd < 0)
+ exit(1);
+ write(fd, tmp, strlen(tmp));
+ } else
+ // CPUFreq support fot the sysfs interface of the 2.5 kernel (/sys/devices/sys/cpuN/cpufreq/)
+ if (strcmp(argv[i], "--cpufreq-sysfs") == 0 || strcmp(argv[i], "-cpufreq-sysfs") == 0) {
+ ++i;
+ snprintf(tmp, sizeof(tmp), "/sys/devices/system/cpu/%s/cpufreq/scaling_governor", argv[i]);
+ tmp[sizeof(tmp)-1] = 0;
+ ++i;
+ if (i >= argc)
+ break;
+ fd = open(tmp, O_WRONLY);
+ if (fd < 0)
+ exit(1);
+ if (strlen(argv[i]) > 50)
+ break;
+ snprintf(tmp, sizeof(tmp), "%s", argv[i]);
+ tmp[sizeof(tmp)-1] = 0;
+ write(fd, tmp, strlen(tmp));
+ } else {
+ break;
+ }
+ close(fd);
+ setuid(getuid()); // drop all priority asap
+ exit(0);
+ } else {
+usage:
+ setuid(getuid()); // drop all priority asap
+ fprintf(stderr, "Usage: %s [--suspend] [--standby] [--hibernate][--software-suspend][--toshibalcd N][--performance CPU N][--throttling CPU N][--cpufreq-[24|25|sysfs]]\n", argv[0]);
+ exit(1);
+ }
+ goto usage;
+
+}
+
diff --git a/klaptopdaemon/apm.cpp b/klaptopdaemon/apm.cpp
new file mode 100644
index 0000000..a13a907
--- /dev/null
+++ b/klaptopdaemon/apm.cpp
@@ -0,0 +1,285 @@
+/*
+ * battery.cpp
+ *
+ * Copyright (c) 1999 Paul Campbell <paul@taniwha.com>
+ * Copyright (c) 2002 Marc Mutz <mutz@kde.org>
+ *
+ * Requires the Qt widget libraries, available at no cost at
+ * http://www.troll.no/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+// my headers:
+#include "apm.h"
+#include "version.h"
+#include "portable.h"
+#include <stdlib.h>
+#include <unistd.h>
+
+// other KDE headers:
+#include <klocale.h>
+#include <kconfig.h>
+#include <knuminput.h>
+#include <kiconloader.h>
+#include <kicondialog.h>
+#include <kapplication.h>
+#include <kmessagebox.h>
+#include <kstandarddirs.h>
+#include <kprocess.h>
+
+// other Qt headers:
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qcheckbox.h>
+#include <qhbox.h>
+#include <qvgroupbox.h>
+#include <qgrid.h>
+#include <qpushbutton.h>
+#include <qtooltip.h>
+extern void wake_laptop_daemon();
+
+ApmConfig::ApmConfig (QWidget * parent, const char *name)
+ : KCModule(parent, name)
+{
+ KGlobal::locale()->insertCatalogue("klaptopdaemon"); // For translation of klaptopdaemon messages
+
+ config = new KConfig("kcmlaptoprc");
+
+ QVBoxLayout *top_layout = new QVBoxLayout( this, KDialog::marginHint(),
+ KDialog::spacingHint() );
+
+ QLabel *tmp_label = new QLabel( i18n("This panel lets you configure your APM system and lets "
+ "you have access to some of the extra features provided by it"), this );
+ tmp_label->setAlignment( Qt::WordBreak );
+ top_layout->addWidget( tmp_label );
+
+ tmp_label = new QLabel( i18n("NOTE: some APM implementations have buggy suspend/standby "
+ "implementations. You should test these features very gingerly - save "
+ "all your work, check them on and try a suspend/standby from "
+ "the popup menu on the battery icon in the panel if it fails to come "
+ "back successfully uncheck the box again."), this );
+ tmp_label->setAlignment( Qt::WordBreak );
+ top_layout->addWidget( tmp_label );
+
+ tmp_label = new QLabel( i18n("Some changes made on this page may require you to quit the laptop panel "
+ "and start it again to take effect"), this );
+ tmp_label->setAlignment( Qt::WordBreak );
+ top_layout->addWidget( tmp_label );
+
+ bool can_enable = laptop_portable::has_apm(1); // is helper ready
+ enableStandby = new QCheckBox( i18n("Enable standby"), this );
+ top_layout->addWidget( enableStandby );
+ QToolTip::add( enableStandby, i18n( "If checked this box enables transitions to the 'standby' state - a temporary powered down state" ) );
+ enableStandby->setEnabled(can_enable);
+ connect( enableStandby, SIGNAL(clicked()), this, SLOT(configChanged()) );
+
+ enableSuspend = new QCheckBox( i18n("Enable &suspend"), this );
+ top_layout->addWidget( enableSuspend );
+ QToolTip::add( enableSuspend, i18n( "If checked this box enables transitions to the 'suspend' state - a semi-powered down state, sometimes called 'suspend-to-ram'" ) );
+ enableSuspend->setEnabled(can_enable);
+ connect( enableSuspend, SIGNAL(clicked()), this, SLOT(configChanged()) );
+ apm_name = "/usr/bin/apm";
+ if (::access(apm_name, F_OK) != 0 && ::access("/usr/sbin/apm", F_OK) == 0)
+ apm_name = "/usr/sbin/apm";
+
+ tmp_label = new QLabel(i18n("If the above boxes are disabled then there is no 'helper' "
+ "application set up to help change APM states, there are two "
+ "ways you can enable this application, either make the file "
+ "/proc/apm writeable by anyone every time your system boots "
+ "or use the button below to make the %1 application "
+ "set-uid root").arg(apm_name), this );
+ tmp_label->setAlignment( Qt::WordBreak );
+ top_layout->addWidget( tmp_label );
+ QHBoxLayout *ll = new QHBoxLayout(top_layout);
+ QPushButton *setupButton = new QPushButton(i18n("Setup Helper Application"), this);
+ connect( setupButton, SIGNAL(clicked()), this, SLOT(setupHelper()) );
+ QToolTip::add( setupButton, i18n( "This button can be used to enable the APM helper application" ) );
+ ll->addStretch(2);
+ ll->addWidget(setupButton);
+ ll->addStretch(8);
+ if (laptop_portable::has_software_suspend()) {
+ tmp_label = new QLabel( i18n("Your system seems to have 'Software Suspend' installed, this can "
+ "be used to hibernate or 'suspend to disk' your system if you want "
+ "to use this for hibernation check the box below"), this );
+ tmp_label->setAlignment( Qt::WordBreak );
+ top_layout->addWidget( tmp_label );
+ enableSoftwareSuspendHibernate = new QCheckBox( i18n("Enable software suspend for hibernate"), this );
+ top_layout->addWidget( enableSoftwareSuspendHibernate );
+ QToolTip::add( enableSoftwareSuspendHibernate, i18n( "If checked this box enables transitions to the 'hibernate' state using the 'Software Suspend' mechanism" ) );
+ enableSoftwareSuspendHibernate->setEnabled(laptop_portable::has_software_suspend(2));
+ connect( enableSoftwareSuspendHibernate, SIGNAL(clicked()), this, SLOT(configChanged()) );
+ tmp_label = new QLabel( i18n("If the above box is disabled then you need to be logged in "
+ "as root or need a helper application to invoke the Software "
+ "Suspend utility - KDE provides a utility to do this, if you "
+ "wish to use it you must make it set-uid root, the button "
+ "below will do this for you"), this );
+ tmp_label->setAlignment( Qt::WordBreak );
+ top_layout->addWidget( tmp_label );
+ ll = new QHBoxLayout(this);
+ QPushButton *setupSSButton = new QPushButton(i18n("Setup SS Helper Application"), this);
+ connect( setupSSButton, SIGNAL(clicked()), this, SLOT(setupHelper2()) );
+ QToolTip::add( setupSSButton, i18n( "This button can be used to enable the Software Suspend helper application" ) );
+ ll->addStretch(2);
+ ll->addWidget(setupSSButton);
+ ll->addStretch(8);
+ } else {
+ enableSoftwareSuspendHibernate = 0;
+ }
+
+
+ top_layout->addStretch(1);
+ top_layout->addWidget( new QLabel( i18n("Version: %1").arg(LAPTOP_VERSION), this), 0, Qt::AlignRight );
+
+
+ load();
+}
+
+ApmConfig::~ApmConfig()
+{
+ delete config;
+}
+
+void ApmConfig::setupHelper()
+{
+ QString kdesu = KStandardDirs::findExe("kdesu");
+ if (!kdesu.isEmpty()) {
+ int rc = KMessageBox::warningContinueCancel(0,
+ i18n("You will need to supply a root password "
+ "to allow the privileges of the %1 application to change.").arg(apm_name),
+ "KLaptopDaemon", KStdGuiItem::cont(),
+ "");
+ if (rc == KMessageBox::Continue) {
+ KProcess proc;
+ proc << kdesu;
+ proc << "-u";
+ proc << "root";
+ proc << QString("chown root ")+apm_name+"; chmod +s "+apm_name;
+ proc.start(KProcess::Block); // run it sync so has_apm below sees the results
+ }
+ } else {
+ KMessageBox::sorry(0, i18n("%1 cannot be enabled because kdesu cannot be found. Please make sure that it is installed correctly.").arg(QString(apm_name)),
+ i18n("KLaptopDaemon"));
+ }
+ laptop_portable::apm_set_mask(enablestandby, enablesuspend);
+ bool can_enable = laptop_portable::has_apm(1); // is helper ready
+ enableStandby->setEnabled(can_enable);
+ enableSuspend->setEnabled(can_enable);
+ wake_laptop_daemon();
+}
+
+#include "checkcrc.h"
+#include "crcresult.h"
+void ApmConfig::setupHelper2() // we use the acpi helper to do software suspend
+{
+ unsigned long len, crc;
+ QString helper = KStandardDirs::findExe("klaptop_acpi_helper");
+ checkcrc(helper.latin1(), len, crc);
+ if (len != file_len || crc != file_crc) {
+ QString str(i18n("The %1 application does not seem to have "
+ "the same size or checksum as when it was compiled we do NOT recommend "
+ "you proceed with making it setuid-root without further investigation").arg(helper));
+ int rc = KMessageBox::warningContinueCancel(0, str, i18n("KLaptopDaemon"), i18n("Run Nevertheless"));
+ if (rc != KMessageBox::Continue)
+ return;
+ }
+
+ QString kdesu = KStandardDirs::findExe("kdesu");
+ if (!kdesu.isEmpty()) {
+ int rc = KMessageBox::warningContinueCancel(0,
+ i18n("You will need to supply a root password "
+ "to allow the privileges of the klaptop_acpi_helper to change."),
+ i18n("KLaptopDaemon"), KStdGuiItem::cont(),
+ "");
+ if (rc == KMessageBox::Continue) {
+ KProcess proc;
+ proc << kdesu;
+ proc << "-u";
+ proc << "root";
+ proc << "chown root "+helper+"; chmod +s "+helper;
+ proc.start(KProcess::Block); // run it sync so has_acpi below sees the results
+ }
+ } else {
+ KMessageBox::sorry(0, i18n("The Software Suspend helper cannot be enabled because kdesu cannot be found. Please make sure that it is installed correctly."),
+ i18n("KLaptopDaemon"));
+ }
+ laptop_portable::software_suspend_set_mask(enablesoftwaresuspend);
+ bool can_enable = laptop_portable::has_software_suspend(2); // is helper ready
+ enableSoftwareSuspendHibernate->setEnabled(can_enable);
+ wake_laptop_daemon();
+}
+
+
+void ApmConfig::save()
+{
+ enablestandby = enableStandby->isChecked();
+ enablesuspend = enableSuspend->isChecked();
+ laptop_portable::apm_set_mask(enablestandby, enablesuspend);
+ enablesoftwaresuspend = (enableSoftwareSuspendHibernate ? enableSoftwareSuspendHibernate->isChecked():0);
+ laptop_portable::software_suspend_set_mask(enablesoftwaresuspend);
+
+ config->setGroup("ApmDefault");
+
+ config->writeEntry("EnableStandby", enablestandby);
+ config->writeEntry("EnableSuspend", enablesuspend);
+
+ config->setGroup("SoftwareSuspendDefault");
+ config->writeEntry("EnableHibernate", enablesoftwaresuspend);
+ config->sync();
+ changed(false);
+ wake_laptop_daemon();
+}
+
+void ApmConfig::load()
+{
+ load( false );
+}
+
+void ApmConfig::load(bool useDefaults)
+{
+ config->setReadDefaults( useDefaults );
+ config->setGroup("ApmDefault");
+ enablestandby = config->readBoolEntry("EnableStandby", true);
+ enableStandby->setChecked(enablestandby);
+ enablesuspend = config->readBoolEntry("EnableSuspend", true);
+ enableSuspend->setChecked(enablesuspend);
+ config->setGroup("SoftwareSuspendDefault");
+ enablesoftwaresuspend = config->readBoolEntry("EnableHibernate", false);
+ if (enableSoftwareSuspendHibernate)
+ enableSoftwareSuspendHibernate->setChecked(enablesoftwaresuspend);
+ emit changed(useDefaults);
+}
+
+void ApmConfig::defaults()
+{
+ load( true );
+}
+
+
+void ApmConfig::configChanged()
+{
+ emit changed(true);
+}
+
+
+QString ApmConfig::quickHelp() const
+{
+ return i18n("<h1>APM Setup</h1>This module allows you to configure APM for your system");
+}
+
+
+#include "apm.moc"
+
+
diff --git a/klaptopdaemon/apm.h b/klaptopdaemon/apm.h
new file mode 100644
index 0000000..a2213e9
--- /dev/null
+++ b/klaptopdaemon/apm.h
@@ -0,0 +1,71 @@
+/*
+ * apm.h
+ *
+ * Copyright (c) 2003 Paul Campbell <paul@taniwha.com>
+ *
+ * Requires the Qt widget libraries, available at no cost at
+ * http://www.troll.no/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef __APMCONFIG_H__
+#define __APMCONFIG_H__
+
+#include <kcmodule.h>
+#include <qstring.h>
+
+class QWidget;
+class QSpinBox;
+class KConfig;
+class QCheckBox;
+class KIconLoader;
+class KIconButton;
+class QPushButton;
+
+
+class ApmConfig : public KCModule
+{
+ Q_OBJECT
+public:
+ ApmConfig( QWidget *parent=0, const char* name=0);
+ ~ApmConfig( );
+
+ void save( void );
+ void load();
+ void load(bool useDefaults);
+ void defaults();
+
+ virtual QString quickHelp() const;
+
+private slots:
+
+ void configChanged();
+ void setupHelper();
+ void setupHelper2();
+
+private:
+ KConfig *config;
+
+ QCheckBox *enableSuspend;
+ QCheckBox *enableStandby;
+ QCheckBox *enableSoftwareSuspendHibernate;
+ bool enablestandby, enablesuspend, enablesoftwaresuspend;
+ const char *apm_name;
+};
+
+#endif
+
diff --git a/klaptopdaemon/applnk/.directory b/klaptopdaemon/applnk/.directory
new file mode 100644
index 0000000..5099b09
--- /dev/null
+++ b/klaptopdaemon/applnk/.directory
@@ -0,0 +1,48 @@
+# KDE Config File
+[KDE Desktop Entry]
+Name=Laptop
+Name[af]=Draagbare rekenaar
+Name[az]=Dizüstü
+Name[bg]=Лаптоп
+Name[br]=Hezoug
+Name[ca]=Portàtil
+Name[cs]=Notebook
+Name[cy]=Gliniadur
+Name[da]=Bærbar
+Name[de]=Notebook
+Name[el]=Φορητό
+Name[eo]=Portkomputilo
+Name[es]=Portátil
+Name[et]=Sülearvuti
+Name[ga]=Ríomhaire Glúine
+Name[gl]=Portátil
+Name[hi]=लैपटॉप
+Name[hu]=Noteszgép
+Name[is]=Ferðavél
+Name[it]=Computer portatile
+Name[ja]=ラップトップ
+Name[km]=កុំព្យួទ័រ​យួរដៃ
+Name[ko]=랩탑
+Name[lv]=Laptops
+Name[mk]=Лаптоп
+Name[ms]=Komputer riba
+Name[nds]=Klappreekner
+Name[pt]=Portátil
+Name[ru]=Батарея ноутбука
+Name[sl]=Prenosnik
+Name[sr]=Лаптоп
+Name[sv]=Bärbar dator
+Name[ta]= மடிக் கணினி
+Name[tg]=Компютери Дастӣ
+Name[th]=แลปทอป
+Name[tr]=Dizüstü Bilgisayar
+Name[uz@cyrillic]=Лаптоп
+Name[ven]=Khomupwutha pfarwa
+Name[wa]=Poirtåve
+Name[xh]=Umphezulu osongiweyo
+Name[zh_TW]=筆記型電腦
+Name[zu]=Ikhomputha eyisicaba ephathwayo
+SortOrder=battery.desktop,bwarning.desktop,cwarning.desktop,power.desktop,pcmcia.desktop
+Icon=laptop_settings
+MiniIcon=laptop_settings
+
diff --git a/klaptopdaemon/applnk/Makefile.am b/klaptopdaemon/applnk/Makefile.am
new file mode 100644
index 0000000..77274c7
--- /dev/null
+++ b/klaptopdaemon/applnk/Makefile.am
@@ -0,0 +1,4 @@
+xdg_apps_DATA = laptop.desktop pcmcia.desktop
+
+data3_DATA = klaptopdaemon.desktop
+data3dir = $(kde_servicesdir)/kded
diff --git a/klaptopdaemon/applnk/klaptopdaemon.desktop b/klaptopdaemon/applnk/klaptopdaemon.desktop
new file mode 100644
index 0000000..0ba43cb
--- /dev/null
+++ b/klaptopdaemon/applnk/klaptopdaemon.desktop
@@ -0,0 +1,116 @@
+[Desktop Entry]
+Type=Service
+
+ServiceTypes=KDEDModule
+X-KDE-ModuleType=Library
+X-KDE-Library=klaptopdaemon
+X-KDE-FactoryName=klaptopdaemon
+X-KDE-Kded-autoload=false
+X-KDE-Kded-load-on-demand=true
+
+Icon=laptop_battery
+DocPath=kcontrol/battery-monitor.html
+Comment=Laptop battery monitor
+Comment[ar]=مراقب بطّاريّة الحاسوب المحمول
+Comment[bg]=Мониторинг на батериите на лаптоп
+Comment[bs]=Nadzor baterije laptopa
+Comment[ca]=Monitor de bateria de portàtils
+Comment[cs]=Monitor baterií laptopu
+Comment[da]=Batteriovervågning for bærbar
+Comment[de]=Benachrichtigung über den Akku-Ladezustand
+Comment[el]=Επόπτης μπαταρίας φορητού
+Comment[eo]=Portkomputila baterimonitoro
+Comment[es]=Monitor de batería del portátil
+Comment[et]=Sülearvuti aku monitooring
+Comment[eu]=Magalekoaren bateria begiralea
+Comment[fa]=نمایشگر باتری رایانۀ کیفی
+Comment[fi]=Kannettavan koneen akkutarkkailja
+Comment[fr]=Indicateur de batterie de portable
+Comment[ga]=Monatóir chadhnra ríomhaire glúine
+Comment[he]=מד סוללה למחשב ברכיים
+Comment[hu]=A telepek szintjelzője
+Comment[is]=Rafhlöðueftirlit fyrir ferðavélar
+Comment[it]=Controllo batteria computer portatile
+Comment[ja]=ラップトップバッテリモニタ
+Comment[ka]=ლეპტოპის კვების ელემენტის მონიტორი
+Comment[kk]=Ноутбук аккумуляторын бақылау
+Comment[km]=កម្មវិធី​ត្រួតពិនិត្យ​ថ្ម​របស់​កុំព្យូទ័រ​យួរដៃ
+Comment[lt]=Akumuliatoriaus stebėjimo priemonė
+Comment[nb]=Batteriovervåker for bærbar maskin
+Comment[nds]=Klappreekner-Batteriekieker
+Comment[ne]=ल्यापटप ब्याट्री मोनिटर
+Comment[nl]=Programma voor laptop-batterijbewaking
+Comment[nn]=Batteriovervaking for bærbar maskin
+Comment[pa]=ਲੈਪਟਾਪ ਬੈਟਰੀ ਨਿਗਰਾਨ
+Comment[pl]=Kontrola stanu baterii laptopa
+Comment[pt]=Monitor de bateria
+Comment[pt_BR]=Monitor de bateria de laptop
+Comment[ro]=Monitorează bateria laptop-ului
+Comment[ru]=Монитор состояния батареи
+Comment[sk]=Monitor nabitia bateriek
+Comment[sl]=Nadzornik baterije za prenosnik
+Comment[sr]=Надгледа батерију лаптопа
+Comment[sr@Latn]=Nadgleda bateriju laptopa
+Comment[sv]=Batterimonitor för bärbar dator
+Comment[ta]= மடிக் கணினி மின்கலம் கண்காணிப்பாளன்
+Comment[tr]=Dizüstü bilgisayarlar için pil izleyici
+Comment[uk]=Монітор батарей лептопа
+Comment[uz]=Laptopning batareyasini nazorat qilish
+Comment[uz@cyrillic]=Лаптопнинг батареясини назорат қилиш
+Comment[zh_CN]=便携电脑电池监视器
+Comment[zh_TW]=筆記型電腦電池監視器
+Name=Laptop Battery Monitor
+Name[ar]=مراقب بطّاريّة الحاسوب المحمول
+Name[bg]=Мониторинг на батериите
+Name[bs]=Nadzor baterije laptopa
+Name[ca]=Monitor de bateria de portàtils
+Name[cs]=Monitor baterií laptopu
+Name[cy]=Monitr Batri Gliniadur
+Name[da]=Batteriovervågning for bærbar
+Name[de]=Akku-Überwachung
+Name[el]=Επόπτης μπαταρίας φορητού
+Name[eo]=Portkomputila baterimonitoro
+Name[es]=Monitor de batería del portátil
+Name[et]=Sülearvuti aku monitooring
+Name[eu]=Magalekoaren Bateria Begiralea
+Name[fa]=نمایشگر باتری رایانۀ کیفی
+Name[fi]=Akkutarkkailija
+Name[fr]=Indicateur de batterie de portable
+Name[ga]=Monatóir Chadhnra Ríomhaire Glúine
+Name[he]=מד סוללה למחשב ברכיים
+Name[hi]=लैपटॉप बैटरी मॉनीटर
+Name[hu]=Feltöltöttségi szintjelző
+Name[is]=Rafhlöðueftirlit fyrir ferðavélar
+Name[it]=Controllo batteria portatile
+Name[ja]=ラップトップバッテリモニタ
+Name[ka]=ლეპტოპის კვების ელემენტის მონიტორი
+Name[kk]=Ноутбук аккумуляторын бақылау
+Name[km]=កម្មវិធី​ត្រួតពិនិត្យ​ថ្ម​កុំព្យូទ័រ​យួរដៃ
+Name[lt]=Akumuliatoriaus stebėjimo priemonė
+Name[mk]=Монитор на батеријата на лаптопот
+Name[ms]=Memerhatikan Bateri Komputer Riba
+Name[nb]=Batteriovervåker for bærbar maskin
+Name[nds]=Klappreekner-Batteriekieker
+Name[ne]=ल्यापटप ब्याट्री मोनिटर
+Name[nl]=Laptop-batterijbewaking
+Name[nn]=Batteriovervakar for bærbar maskin
+Name[pa]=ਲੈਪਟਾਪ ਬੈਟਰੀ ਨਿਗਰਾਨ
+Name[pl]=Monitor baterii
+Name[pt]=Monitor de Bateria
+Name[pt_BR]=Monitor de Bateria de Laptop
+Name[ro]=Monitor baterie de laptop
+Name[ru]=Состояние батареи
+Name[sk]=Monitor nabitia bateriek
+Name[sl]=Nadzornik baterije za prenosnik
+Name[sr]=Надгледање батерије лаптопа
+Name[sr@Latn]=Nadgledanje baterije laptopa
+Name[sv]=Batterimonitor för bärbar dator
+Name[ta]= மடிக் கணினி மின்கலம் கண்காணி
+Name[tg]=Дидабони Батареяи Компютери Дастӣ
+Name[tr]=Dizüstü Pil Monitörü
+Name[uk]=Монітор батарей
+Name[uz]=Laptopning batareyasini nazorat qilish
+Name[uz@cyrillic]=Лаптопнинг батареясини назорат қилиш
+Name[wa]=Corwaitoe del batreye do poirtåve
+Name[zh_CN]=便携电脑电池监视器
+Name[zh_TW]=筆記型電腦電池監視器
diff --git a/klaptopdaemon/applnk/laptop.desktop b/klaptopdaemon/applnk/laptop.desktop
new file mode 100644
index 0000000..5c4101c
--- /dev/null
+++ b/klaptopdaemon/applnk/laptop.desktop
@@ -0,0 +1,135 @@
+[Desktop Entry]
+X-KDE-Library=laptop
+X-KDE-FactoryName=laptop
+X-KDE-Init=laptop
+Exec=kcmshell laptop
+Icon=laptop_battery
+Type=Application
+DocPath=kcontrol/laptop/index.html
+Categories=Qt;KDE;X-KDE-settings-power;
+Comment=Laptop Battery
+Comment[af]=Draagbare rekenaar Batery
+Comment[ar]=بطّاريّة الحاسوب المحمول
+Comment[bg]=Мониторинг на батериите на лаптоп
+Comment[br]=Pod-tredan an hezoug
+Comment[bs]=Upozorenje istrošene baterije
+Comment[ca]=Bateria de portàtil
+Comment[cs]=Baterie notebooku
+Comment[cy]=Batri Gliniadur
+Comment[da]=Batteri for bærbar
+Comment[de]=Notebook-Akku
+Comment[el]=Μπαταρία φορητού
+Comment[eo]=Avertilo por maplenigo de la baterio
+Comment[es]=Batería del portátil
+Comment[et]=Sülearvuti aku
+Comment[eu]=Magalekoen Bateria
+Comment[fa]=باتری رایانۀ کیفی
+Comment[fi]=Kannettavan akku
+Comment[fr]=Batterie d'ordinateur portable
+Comment[ga]=Cadhnra Ríomhaire Glúine
+Comment[he]=סוללת מחשב נייד
+Comment[hi]=लैपटॉप बैटरी
+Comment[hr]=Baterija laptopa
+Comment[hu]=Energiakezelési beállítások noteszgép esetén
+Comment[is]=Rafhlaða ferðavélar
+Comment[it]=Batteria computer portatile
+Comment[ja]=ラップトップバッテリ
+Comment[ka]=ლეპტოპის კვების ელემენტი
+Comment[kk]=Ноутбуктің аккумуляторы
+Comment[km]=ថ្ម​កុំព្យូទ័រ​យួរដៃ
+Comment[lt]=Nešiojamo kompiuterio akumuliatorius
+Comment[mk]=Предупредува кога батеријата е слаба
+Comment[ms]=Bateri Komputer Riba
+Comment[mt]=Batterija tal-laptop
+Comment[nb]=Batteri til bærbar maskin
+Comment[nds]=Klappreekner-Batterie
+Comment[ne]=ल्यापटप ब्याट्री
+Comment[nl]=Laptopbatterij
+Comment[nn]=Batteri til bærbar
+Comment[pa]=ਲੈਪਟਾਪ ਬੈਟਰੀ
+Comment[pl]=Ostrzeżenie o słabych bateriach
+Comment[pt]=Bateria do portátil
+Comment[pt_BR]=Bateria do Laptop
+Comment[ro]=Baterie de laptop
+Comment[ru]=Батарея ноутбука
+Comment[sk]=Batérie laptopu
+Comment[sl]=Baterija prenosnika
+Comment[sr]=Батерија лаптопа
+Comment[sr@Latn]=Baterija laptopa
+Comment[sv]=Batteri för bärbar dator
+Comment[ta]= மடிக் கணினி மின்கலம்
+Comment[tg]=Батареяи Компютери Дастӣ
+Comment[th]=แบตเตอรีของเครื่องแลปทอบ
+Comment[tr]=Dizüstü Pili
+Comment[uk]=Батареї лептопа
+Comment[uz]=Laptopning batareyasi
+Comment[uz@cyrillic]=Лаптопнинг батареяси
+Comment[wa]=Batreye do poirtåve
+Comment[xh]=Ibhetri ye Laptop
+Comment[zh_CN]=便携电脑电池
+Comment[zh_TW]=筆記型電腦的電池
+Comment[zu]=Ibhetri Yekhomputha eyisicaba ephathwayo
+Name=Laptop Battery
+Name[af]=Draagbare rekenaar Batery
+Name[ar]=بطّاريّة الحاسوب المحمول
+Name[bg]=Батерии на лаптоп
+Name[br]=Pod-tredan an hezoug
+Name[bs]=Laptop baterija
+Name[ca]=Bateria de portàtil
+Name[cs]=Baterie notebooku
+Name[cy]=Batri Gliniadur
+Name[da]=Batteri for bærbar
+Name[de]=Notebook-Akku
+Name[el]=Μπαταρία φορητού
+Name[eo]=Portkomputila baterio
+Name[es]=Batería del portátil
+Name[et]=Sülearvuti aku
+Name[eu]=Magalekoen Bateria
+Name[fa]=باتری رایانۀ کیفی
+Name[fi]=Kannettavan akku
+Name[fr]=Batterie d'ordinateur portable
+Name[ga]=Cadhnra Ríomhaire Glúine
+Name[he]=סוללת מחשב נייד
+Name[hi]=लैपटॉप बैटरी
+Name[hr]=Laptop baterija
+Name[hu]=Noteszgép-telepek
+Name[is]=Ferðavélarafhlaða
+Name[it]=Batteria computer portatile
+Name[ja]=ラップトップバッテリ
+Name[ka]=ლეპტოპის კვების ელემენტი
+Name[kk]=Ноутбуктің аккумуляторы
+Name[km]=ថ្ម​កុំព្យូទ័រ​យួរដៃ
+Name[lt]=Laptop baterija
+Name[mk]=Батерија на лаптопот
+Name[ms]=Bateri Komputer Riba
+Name[mt]=Batterija tal-laptop
+Name[nb]=Batteri til bærbar maskin
+Name[nds]=Klappreekner-Batterie
+Name[ne]=ल्यापटप ब्याट्री
+Name[nl]=Laptopbatterij
+Name[nn]=Batteri til bærbar
+Name[pa]=ਲੈਪਟਾਪ ਬੈਟਰੀ
+Name[pl]=Bateria laptopa
+Name[pt]=Bateria do Portátil
+Name[pt_BR]=Bateria do Laptop
+Name[ro]=Baterie laptop
+Name[ru]=Батарея ноутбука
+Name[sk]=Batérie laptopu
+Name[sl]=Baterija prenosnika
+Name[sr]=Батерија лаптопа
+Name[sr@Latn]=Baterija laptopa
+Name[sv]=Batteri för bärbar dator
+Name[ta]= மடிக் கணினி மின்கலம்
+Name[tg]=Батареяи Компютери Дастӣ
+Name[th]=แบตเตอรีแลปทอบ
+Name[tr]=Dizüstü Pili
+Name[uk]=Батареї лептопа
+Name[uz]=Laptopning batareyasi
+Name[uz@cyrillic]=Лаптопнинг батареяси
+Name[wa]=Batreye do poirtåve
+Name[xh]=Ibhetri ye Laptop
+Name[zh_CN]=便携电脑电池
+Name[zh_TW]=筆記型電腦的電池
+Name[zu]=Ibhetri Yekhomputha eyisicaba ephathwayo
+Init=klaptop_check
+
diff --git a/klaptopdaemon/applnk/pcmcia.desktop b/klaptopdaemon/applnk/pcmcia.desktop
new file mode 100644
index 0000000..0b1249a
--- /dev/null
+++ b/klaptopdaemon/applnk/pcmcia.desktop
@@ -0,0 +1,84 @@
+[Desktop Entry]
+X-KDE-ModuleType=Library
+X-KDE-Library=laptop
+X-KDE-FactoryName=pcmcia
+Exec=kcmshell pcmcia
+Icon=laptop_pcmcia
+Type=Application
+DocPath=kinfocenter/pcmcia/index.html
+Comment=PCMCIA status
+Comment[af]=Pcmcia status
+Comment[ar]=حالة بطاقة PCMCIA
+Comment[az]=PCMCIA vəziyyəti
+Comment[bg]=Информация за PCMCIA
+Comment[br]=Saviad PCMCIA
+Comment[ca]=Estat de PCMCIA
+Comment[cs]=Stav PCMCIA
+Comment[cy]=Statws PCMCIA
+Comment[da]=PCMCIA-status
+Comment[de]=PCMCIA-Status
+Comment[el]=Κατάσταση PCMCIA
+Comment[eo]=PCMCIA-stato
+Comment[es]=Estado PCMCIA
+Comment[et]=PCMCIA olek
+Comment[eu]=PCMCIAren egoera
+Comment[fa]=PCMCIA وضعیت
+Comment[fi]=PCMCIA-tila
+Comment[fr]=État PCMCIA
+Comment[ga]=Stádas PCMCIA
+Comment[gl]=Estado de PCMCIA
+Comment[he]=מידע על מצב PCMCIA
+Comment[hi]=पीसीएमसीआईए स्थिति
+Comment[hr]=Stanje PCMCIA
+Comment[hu]=PCMCIA-állapot
+Comment[id]=Status PCMCIA
+Comment[is]=PCMCIA staða
+Comment[it]=Stato PCMCIA
+Comment[ja]=PCMCIA の状態
+Comment[ka]=PCMCIA სტატუსი
+Comment[kk]=PCMCIA күйі
+Comment[km]=ស្ថានភាព PCMCIA
+Comment[ko]=PCMCIA 현재 상태
+Comment[lt]=PCMCIA būsena
+Comment[mk]=Статус на PCMCIA
+Comment[ms]=Status PCMCIA
+Comment[mt]=Stat PCMCIA
+Comment[nb]=PCMCIA-status
+Comment[nds]=PCMCIA-Status
+Comment[ne]=PCMCIA स्थिति
+Comment[nl]=Status van PCMCIA
+Comment[nn]=PCMCIA-status
+Comment[pa]=PCMCIA ਹਾਲਤ
+Comment[pl]=Status kart PCMCIA
+Comment[pt]=Estado do PCMCIA
+Comment[pt_BR]=Estado do PCMCIA
+Comment[ro]=Starea PCMCIA
+Comment[ru]=Состояние PCMCIA
+Comment[sk]=stav PCMCIA
+Comment[sl]=Stanje PCMCIA
+Comment[sr]=Статус PCMCIA уређаја
+Comment[sr@Latn]=Status PCMCIA uređaja
+Comment[sv]=PCMCIA-status
+Comment[ta]=PCMCIA நிலை
+Comment[tg]=Ҳолати PCMCIA
+Comment[th]=สถานะอุปกรณ์ PCMCIA
+Comment[tr]=PCMCIA durumu
+Comment[uk]=Стан PCMCIA
+Comment[uz]=PCMCIA holati
+Comment[uz@cyrillic]=PCMCIA ҳолати
+Comment[ven]=Maimo a PCMCIA
+Comment[vi]=Trạng thái PCMCIA
+Comment[wa]=Estat do PCMCIA
+Comment[xh]=Indawo esemthethweni ye PCMCIA
+Comment[zh_CN]=PCMCIA 状态
+Comment[zh_TW]=PCMCIA 狀態
+Comment[zu]=Izinga le-PCMCIA
+Name=PCMCIA
+Name[af]=Pcmcia
+Name[he]=מצב PCMCIA
+Name[hi]=पीसीएमसीआईए
+Name[pt_BR]=Cartões PCMCIA
+Name[ta]= PCMCIA
+Name[th]=อุปกรณ์ PCMCIA
+
+Categories=Qt;KDE;X-KDE-information;
diff --git a/klaptopdaemon/battery.cpp b/klaptopdaemon/battery.cpp
new file mode 100644
index 0000000..ef43890
--- /dev/null
+++ b/klaptopdaemon/battery.cpp
@@ -0,0 +1,390 @@
+/*
+ * battery.cpp
+ *
+ * Copyright (c) 1999 Paul Campbell <paul@taniwha.com>
+ * Copyright (c) 2002 Marc Mutz <mutz@kde.org>
+ * Copyright (c) 2006 Flavio Castelli <flavio.castelli@gmail.com>
+ *
+ * Requires the Qt widget libraries, available at no cost at
+ * http://www.troll.no/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+// my headers:
+#include "battery.h"
+#include "version.h"
+#include "portable.h"
+
+// other KDE headers:
+#include <klocale.h>
+#include <kconfig.h>
+#include <knuminput.h>
+#include <kiconloader.h>
+#include <kicondialog.h>
+#include <kapplication.h>
+#include <kmessagebox.h>
+#include <krichtextlabel.h>
+
+// other Qt headers:
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qcheckbox.h>
+#include <qhbox.h>
+#include <qvgroupbox.h>
+#include <qhgroupbox.h>
+#include <qgrid.h>
+#include <qpushbutton.h>
+#include <qtooltip.h>
+extern void wake_laptop_daemon();
+
+
+BatteryConfig::BatteryConfig (QWidget * parent, const char *name)
+ : KCModule(parent, name),
+ editPoll(0),
+ iconloader(0),
+ buttonNoBattery(0),
+ buttonNoCharge(0),
+ buttonCharge(0)
+{
+ KGlobal::locale()->insertCatalogue("klaptopdaemon"); // For translation of klaptopdaemon messages
+
+ apm = laptop_portable::has_power_management();
+ config = new KConfig("kcmlaptoprc");
+ instance = new KInstance("klaptopdaemon");
+
+ QVBoxLayout *top_layout = new QVBoxLayout( this, KDialog::marginHint(),
+ KDialog::spacingHint() );
+
+ // do we show the monitor
+ runMonitor = new QCheckBox( i18n("&Show battery monitor"), this );
+ top_layout->addWidget( runMonitor );
+ QToolTip::add( runMonitor, i18n( "This box enables the battery state icon in the panel" ) );
+ connect( runMonitor, SIGNAL(clicked()), this, SLOT(configChanged()) );
+ connect( runMonitor, SIGNAL(clicked()), this, SLOT(runMonitorChanged()) );
+
+ // show also the battery level percentage
+ showLevel = new QCheckBox( i18n("Show battery level percentage"), this );
+ top_layout->addWidget( showLevel );
+ QToolTip::add( showLevel, i18n( "This box enables a text message near the battery state icon containing battery level percentage" ) );
+ connect( showLevel, SIGNAL(clicked()), this, SLOT(configChanged()) );
+
+ notifyMe = new QCheckBox( i18n("&Notify me whenever my battery becomes fully charged"), this );
+ top_layout->addWidget( notifyMe );
+ QToolTip::add( notifyMe, i18n( "This box enables a dialog box that pops up when your battery becomes fully charged" ) );
+ connect( notifyMe, SIGNAL(clicked()), this, SLOT(configChanged()) );
+
+ blankSaver = new QCheckBox( i18n("&Use a blank screen saver when running on battery"), this );
+ top_layout->addWidget( blankSaver );
+ connect( blankSaver, SIGNAL(clicked()), this, SLOT(configChanged()) );
+
+ if (!apm) {
+ top_layout->addWidget( laptop_portable::no_power_management_explanation(this) );
+ } else {
+ iconloader = new KIconLoader("klaptopdaemon");
+
+ // the poll time (in seconds)
+ QHBox *hb = new QHBox( this );
+ hb->setSpacing( KDialog::spacingHint() );
+ top_layout->addWidget( hb );
+
+ QLabel* poll_label = new QLabel( i18n("&Check status every:"), hb );
+ editPoll = new QSpinBox( 1, 3600, 1, hb ); // min,max,step
+ QToolTip::add( editPoll, i18n( "Choose how responsive the laptop software will be when it checks the battery status" ) );
+ editPoll->setSuffix( i18n("keep short, unit in spinbox", "sec") );
+ poll_label->setBuddy( editPoll );
+ connect( editPoll, SIGNAL(valueChanged(int)),
+ this, SLOT(configChanged()) );
+ QWidget* spacer = new QWidget( hb );
+ hb->setStretchFactor( spacer, 1 );
+
+ // group box to hold the icons together
+ QVGroupBox* icons_groupbox = new QVGroupBox( i18n("Select Battery Icons"), this );
+ icons_groupbox->layout()->setSpacing( KDialog::spacingHint() );
+ top_layout->addWidget( icons_groupbox, 0, Qt::AlignLeft );
+
+ // layout to hold the icons inside the groupbox
+ QGrid *icon_grid = new QGrid( 3 /*cols*/, icons_groupbox );
+ icon_grid->setSpacing( KDialog::spacingHint() );
+
+ buttonNoBattery = new KIconButton( iconloader, icon_grid );
+ buttonNoCharge = new KIconButton( iconloader, icon_grid );
+ buttonCharge = new KIconButton( iconloader, icon_grid );
+ (void)new QLabel( buttonNoBattery, i18n("No &battery"), icon_grid);
+ (void)new QLabel( buttonNoCharge, i18n("&Not charging"), icon_grid);
+ (void)new QLabel( buttonCharge, i18n("Char&ging"), icon_grid);
+ buttonNoBattery->setIconType( KIcon::NoGroup, KIcon::Any, 1);
+ buttonNoCharge->setIconType( KIcon::NoGroup, KIcon::Any, 1);
+ buttonCharge->setIconType( KIcon::NoGroup, KIcon::Any, 1);
+ connect(buttonNoBattery, SIGNAL(iconChanged(QString)), this, SLOT(iconChanged()));
+ connect(buttonNoCharge, SIGNAL(iconChanged(QString)), this, SLOT(iconChanged()));
+ connect(buttonCharge, SIGNAL(iconChanged(QString)), this, SLOT(configChanged()));
+
+
+ int num_batteries;
+ QStringList battery_names, battery_states, battery_values;
+ laptop_portable::get_battery_status(num_batteries, battery_names, battery_states, battery_values);
+ if (num_batteries > 0) {
+ QHBoxLayout *hl = new QHBoxLayout();
+ top_layout->addLayout(hl);
+
+ QHGroupBox *hb = new QHGroupBox(i18n("Current Battery Status"), this);
+ for (int i = 0; i < num_batteries; i++) {
+
+ QWidget *wp;
+ if (num_batteries == 1) {
+ wp = new QWidget(hb);
+ } else {
+ wp = new QVGroupBox(battery_names[i], hb);
+ }
+ QVBoxLayout *vb = new QVBoxLayout(wp);
+
+ QLabel *l;
+
+ l = new QLabel(wp); // icon indicating state
+ vb->addWidget(l);
+ batt_label_1.append(l);
+
+ l = new QLabel(QString(""), wp);
+ vb->addWidget(l);
+ batt_label_2.append(l);
+
+ l = new QLabel(QString(""), wp);
+ vb->addWidget(l);
+ batt_label_3.append(l);
+ }
+ hl->addWidget(hb);
+ hl->addStretch(1);
+ (void)startTimer(30*1000); // update 2x every minute
+ }
+
+ // TODO: remove linefeed from string, can't do it right now coz we have a string freeze
+ QLabel* explain = new KRichTextLabel( i18n("This panel controls whether the battery status monitor\nappears in the system tray and what it looks like.").replace("\n"," "), this);
+ top_layout->addWidget(explain, 0);
+ laptop_portable::extra_config(this, config, top_layout);
+ }
+
+ top_layout->addStretch(1);
+ startMonitor = new QPushButton( i18n("&Start Battery Monitor"), this);
+ connect(startMonitor, SIGNAL(clicked()), this, SLOT(slotStartMonitor()));
+ top_layout->addWidget( startMonitor, 0, Qt::AlignRight );
+
+ load();
+}
+
+BatteryConfig::~BatteryConfig()
+{
+ delete instance;
+ delete config;
+}
+
+
+void BatteryConfig::save()
+{
+ enablemonitor = runMonitor->isChecked();
+ showlevel = showLevel->isChecked();
+ useblanksaver = blankSaver->isChecked();
+ notifyme = notifyMe->isChecked();
+
+ if (apm) {
+ poll_time = editPoll->value();
+ nobattery = buttonNoBattery->icon();
+ chargebattery = buttonCharge->icon();
+ nochargebattery = buttonNoCharge->icon();
+ }
+ config->setGroup("BatteryDefault");
+
+ config->writeEntry("Enable", enablemonitor);
+ config->writeEntry("ShowLevel", showlevel);
+ config->writeEntry("NotifyMe", notifyme);
+ config->writeEntry("BlankSaver", useblanksaver);
+ config->writeEntry("Poll", poll_time);
+ config->writeEntry("NoBatteryPixmap", nobattery);
+ config->writeEntry("ChargePixmap", chargebattery);
+ config->writeEntry("NoChargePixmap", nochargebattery);
+ config->sync();
+ changed(false);
+ wake_laptop_daemon();
+}
+
+void BatteryConfig::load()
+{
+ load( false );
+}
+
+void BatteryConfig::load(bool useDefaults)
+{
+ config->setReadDefaults( useDefaults );
+ config->setGroup("BatteryDefault");
+
+ poll_time = config->readNumEntry("Poll", 20);
+ enablemonitor = config->readBoolEntry("Enable", true);
+ showlevel = config->readBoolEntry("ShowLevel", false);
+ notifyme = config->readBoolEntry("NotifyMe", false);
+ useblanksaver = config->readBoolEntry("BlankSaver", false);
+
+ nobattery = config->readEntry("NoBatteryPixmap", "laptop_nobattery");
+ nochargebattery = config->readEntry("NoChargePixmap", "laptop_nocharge");
+ chargebattery = config->readEntry("ChargePixmap", "laptop_charge");
+
+ runMonitor->setChecked(enablemonitor);
+ showLevel->setChecked(showlevel);
+ blankSaver->setChecked(useblanksaver);
+ notifyMe->setChecked(notifyme);
+ if (apm) {
+ editPoll->setValue(poll_time);
+ buttonNoCharge->setIcon(nochargebattery);
+ buttonCharge->setIcon(chargebattery);
+ buttonNoBattery->setIcon(nobattery);
+ }
+ battery_pm = SmallIcon(nochargebattery, 20, KIcon::DefaultState, instance);
+ battery_nopm = SmallIcon(nobattery, 20, KIcon::DefaultState, instance);
+ emit changed(useDefaults);
+ BatteryStateUpdate();
+}
+
+void BatteryConfig::defaults()
+{
+ load( true );
+}
+
+void BatteryConfig::runMonitorChanged()
+{
+ showLevel->setEnabled (runMonitor->isChecked());
+}
+
+void BatteryConfig::configChanged()
+{
+ emit changed(true);
+}
+
+
+QString BatteryConfig::quickHelp() const
+{
+ return i18n("<h1>Laptop Battery</h1>This module allows you to monitor "
+ "your batteries. To make use of this module, you must have power management system software "
+ "installed. (And, of course, you should have batteries in your machine.)");
+}
+
+
+void BatteryConfig::slotStartMonitor()
+{
+ wake_laptop_daemon();
+ if (!enablemonitor) {
+ KMessageBox::information(0, i18n("<qt>The battery monitor has been started, but the tray icon is currently disabled. You can make it appear by selecting the <b>Show battery monitor</b> entry on this page and applying your changes.</qt>"), QString::null, "howToEnableMonitor");
+ }
+}
+
+void
+BatteryConfig::ConvertIcon(int percent, QPixmap &pm, QPixmap &result)
+{
+ QImage image = pm.convertToImage();
+
+ int w = image.width();
+ int h = image.height();
+ int count = 0;
+ QRgb rgb;
+ int x, y;
+ for (x = 0; x < w; x++)
+ for (y = 0; y < h; y++) {
+ rgb = image.pixel(x, y);
+ if (qRed(rgb) == 0xff &&
+ qGreen(rgb) == 0xff &&
+ qBlue(rgb) == 0xff)
+ count++;
+ }
+ int c = (count*percent)/100;
+ if (percent == 100) {
+ c = count;
+ } else
+ if (percent != 100 && c == count)
+ c = count-1;
+
+
+ if (c) {
+ uint ui;
+ QRgb blue = qRgb(0x00,0x00,0xff);
+
+ if (image.depth() <= 8) {
+ ui = image.numColors(); // this fix thanks to Sven Krumpke
+ image.setNumColors(ui+1);
+ image.setColor(ui, blue);
+ } else {
+ ui = 0xff000000|blue;
+ }
+
+ for (y = h-1; y >= 0; y--)
+ for (x = 0; x < w; x++) {
+ rgb = image.pixel(x, y);
+ if (qRed(rgb) == 0xff &&
+ qGreen(rgb) == 0xff &&
+ qBlue(rgb) == 0xff) {
+ image.setPixel(x, y, ui);
+ c--;
+ if (c <= 0)
+ goto quit;
+ }
+ }
+ }
+quit:
+
+ result.convertFromImage(image);
+}
+
+void
+BatteryConfig::BatteryStateUpdate()
+{
+ int num_batteries;
+ QStringList battery_names, battery_states, battery_values;
+ laptop_portable::get_battery_status(num_batteries, battery_names, battery_states, battery_values);
+ if (num_batteries > 0) {
+ for (int i = 0; i < num_batteries; i++) {
+ if (battery_states[i] == "yes") {
+ QPixmap result;
+ ConvertIcon(battery_values[i].toInt(), battery_pm, result);
+ batt_label_1.at(i)->setPixmap(result);
+
+ batt_label_2.at(i)->setText(battery_values[i]+"%");
+
+ batt_label_3.at(i)->setText(i18n("Present"));
+ } else {
+ batt_label_1.at(i)->setPixmap(battery_nopm);
+
+ batt_label_2.at(i)->setText("");
+
+ batt_label_3.at(i)->setText(i18n("Not present"));
+ }
+ }
+ }
+}
+
+void BatteryConfig::iconChanged()
+{
+ nobattery = buttonNoBattery->icon();
+ nochargebattery = buttonNoCharge->icon();
+ battery_pm = SmallIcon(nochargebattery, 20, KIcon::DefaultState, instance);
+ battery_nopm = SmallIcon(nobattery, 20, KIcon::DefaultState, instance);
+ emit changed(true);
+ BatteryStateUpdate();
+}
+
+void BatteryConfig::timerEvent(QTimerEvent *)
+{
+ BatteryStateUpdate();
+}
+
+#include "battery.moc"
+
+
diff --git a/klaptopdaemon/battery.h b/klaptopdaemon/battery.h
new file mode 100644
index 0000000..3e484ef
--- /dev/null
+++ b/klaptopdaemon/battery.h
@@ -0,0 +1,100 @@
+/*
+ * battery.h
+ *
+ * Copyright (c) 1999 Paul Campbell <paul@taniwha.com>
+ * Copyright (c) 2002 Marc Mutz <mutz@kde.org>
+ * Copyright (c) 2006 Flavio Castelli <flavio.castelli@gmail.com>
+ *
+ * Requires the Qt widget libraries, available at no cost at
+ * http://www.troll.no/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef __BATTERYCONFIG_H__
+#define __BATTERYCONFIG_H__
+
+#include <kcmodule.h>
+#include <qstring.h>
+#include <qpixmap.h>
+#include <qptrlist.h>
+
+class QWidget;
+class QSpinBox;
+class KConfig;
+class QCheckBox;
+class KIconLoader;
+class KIconButton;
+class QPushButton;
+class QLabel;
+
+
+class BatteryConfig : public KCModule
+{
+ Q_OBJECT
+public:
+ BatteryConfig( QWidget *parent=0, const char* name=0);
+ ~BatteryConfig( );
+
+ void save( void );
+ void load();
+ void load(bool useDefaults);
+ void defaults();
+
+ virtual QString quickHelp() const;
+
+private slots:
+
+ void configChanged();
+ void runMonitorChanged();
+ void slotStartMonitor();
+ void iconChanged();
+ void BatteryStateUpdate();
+
+private:
+ void timerEvent(QTimerEvent *);
+ void ConvertIcon(int percent, QPixmap &pm, QPixmap &result);
+ KConfig *config;
+
+ QSpinBox* editPoll;
+ QCheckBox* runMonitor;
+ QCheckBox* showLevel;
+ QCheckBox* notifyMe;
+ QCheckBox* blankSaver;
+ bool enablemonitor;
+ bool showlevel;
+ bool enablequitmenu;
+ bool useblanksaver;
+ bool notifyme;
+
+ KIconLoader *iconloader;
+
+ KIconButton *buttonNoBattery;
+ KIconButton *buttonNoCharge;
+ KIconButton *buttonCharge;
+ QString nobattery, nochargebattery, chargebattery;
+ QPushButton *startMonitor;
+ bool apm;
+ int poll_time;
+
+ QPtrList<QLabel> batt_label_1, batt_label_2, batt_label_3;
+ QPixmap battery_pm, battery_nopm;
+
+ KInstance *instance;
+};
+
+#endif
+
diff --git a/klaptopdaemon/buttons.cpp b/klaptopdaemon/buttons.cpp
new file mode 100644
index 0000000..f9ccce4
--- /dev/null
+++ b/klaptopdaemon/buttons.cpp
@@ -0,0 +1,620 @@
+/*
+ * buttons.cpp
+ *
+ * Copyright (c) 1999 Paul Campbell <paul@taniwha.com>
+ * Copyright (c) 2002 Marc Mutz <mutz@kde.org>
+ *
+ * Requires the Qt widget libraries, available at no cost at
+ * http://www.troll.no/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "buttons.h"
+#include "portable.h"
+#include "version.h"
+
+#include <kglobal.h>
+#include <klocale.h>
+#include <kconfig.h>
+#include <knumvalidator.h>
+#include <kdialog.h>
+#include <kapplication.h>
+#include <kcombobox.h>
+
+#include <qlayout.h>
+#include <qvbuttongroup.h>
+#include <qspinbox.h>
+#include <qradiobutton.h>
+#include <qcheckbox.h>
+#include <qhbox.h>
+#include <qslider.h>
+#include <qtooltip.h>
+extern void wake_laptop_daemon();
+
+ButtonsConfig::ButtonsConfig (QWidget * parent, const char *name)
+ : KCModule(parent, name),
+ lidBox(0),
+ lidStandby(0),
+ lidSuspend(0),
+ lidOff(0),
+ lidHibernate(0),
+ lidShutdown(0),
+ lidLogout(0),
+ lidBrightness(0),
+ lidValBrightness(0),
+ lidThrottle(0),
+ lidValThrottle(0),
+ lidPerformance(0),
+ lidValPerformance(0),
+
+ powerBox(0),
+ powerStandby(0),
+ powerSuspend(0),
+ powerOff(0),
+ powerHibernate(0),
+ powerShutdown(0),
+ powerLogout(0),
+ powerBrightness(0),
+ powerValBrightness(0),
+ powerThrottle(0),
+ powerValThrottle(0),
+ powerPerformance(0),
+ powerValPerformance(0)
+{
+ int can_shutdown = 1; // fix me
+ int can_logout = 1; // fix me
+
+ KGlobal::locale()->insertCatalogue("klaptopdaemon"); // For translation of klaptopdaemon messages
+
+ apm = laptop_portable::has_power_management();
+ config = new KConfig("kcmlaptoprc");
+ int can_brightness = laptop_portable::has_brightness();
+ QStringList throttle_list;
+ int current_throttle;
+ bool *active_list;
+ bool has_throttle = laptop_portable::get_system_throttling(0, current_throttle, throttle_list, active_list);
+ QStringList performance_list;
+ int current_performance;
+ bool has_performance = laptop_portable::get_system_performance(0, current_performance, performance_list, active_list);
+
+ if (!apm && !can_brightness && !has_throttle && !has_performance) {
+ QVBoxLayout *top_layout = new QVBoxLayout(this, KDialog::marginHint(),
+ KDialog::spacingHint());
+
+ KActiveLabel* explain = laptop_portable::no_power_management_explanation(this);
+ top_layout->addWidget(explain);
+
+ top_layout->addStretch(1);
+ } else {
+ int can_standby = laptop_portable::has_standby();
+ int can_suspend = laptop_portable::has_suspend();
+ int can_hibernate = laptop_portable::has_hibernation();
+
+ if (!can_standby && !can_suspend && !can_hibernate && !can_brightness && !has_throttle && !has_performance)
+ apm = 0;
+ if (!apm) {
+ QVBoxLayout *top_layout = new QVBoxLayout(this, KDialog::marginHint(),
+ KDialog::spacingHint());
+
+ QLabel* explain = laptop_portable::how_to_do_suspend_resume(this);
+ top_layout->addWidget(explain);
+
+ top_layout->addStretch(1);
+ } else {
+ QVBoxLayout *top_layout = new QVBoxLayout(this, KDialog::marginHint(),
+ KDialog::spacingHint());
+ QHBoxLayout *hlay = new QHBoxLayout( top_layout );
+
+ if (laptop_portable::has_button(laptop_portable::LidButton)) {
+ lidBox = new QVButtonGroup(i18n("Lid Switch Closed"), this);
+ lidBox->layout()->setSpacing( KDialog::spacingHint() );
+ QToolTip::add( lidBox, i18n( "Select which actions will occur when the laptop's lid is closed" ) );
+ hlay->addWidget( lidBox );
+
+ if (can_standby) {
+ lidStandby = new QRadioButton(i18n("Standb&y"), lidBox);
+ QToolTip::add( lidStandby, i18n( "Causes the laptop to move into the standby temporary low-power state" ) );
+ }
+ if (can_suspend) {
+ lidSuspend = new QRadioButton(i18n("&Suspend"), lidBox);
+ QToolTip::add( lidSuspend, i18n( "Causes the laptop to move into the suspend 'save-to-ram' state" ) );
+ }
+ if (can_hibernate) {
+ lidHibernate = new QRadioButton(i18n("H&ibernate"), lidBox);
+ QToolTip::add( lidHibernate, i18n( "Causes the laptop to move into the hibernate 'save-to-disk' state" ) );
+ }
+ if (can_shutdown) {
+ lidShutdown = new QRadioButton(i18n("System power off"), lidBox);
+ QToolTip::add( lidShutdown, i18n( "Causes the laptop to power down" ) );
+ }
+ if (can_logout) {
+ lidLogout = new QRadioButton(i18n("Logout"), lidBox);
+ QToolTip::add( lidShutdown, i18n( "Causes you to be logged out" ) );
+ }
+ if (can_suspend||can_standby||can_hibernate||can_shutdown||can_logout)
+ lidOff = new QRadioButton(i18n("&Off"), lidBox);
+ if (can_brightness) {
+ lidBrightness = new QCheckBox(i18n("Brightness"), lidBox);
+ QToolTip::add( lidBrightness, i18n( "Causes the back panel brightness to be set" ) );
+ QWidget *wp = new QWidget(lidBox);
+ QHBoxLayout *xl = new QHBoxLayout( wp);
+ xl->addWidget(new QLabel("-", wp));
+ lidValBrightness = new QSlider(0, 255, 16, 255, Qt::Horizontal, wp);
+ lidValBrightness->setEnabled(0);
+ QToolTip::add( lidValBrightness, i18n( "How bright the back panel will be set to" ) );
+ connect (lidValBrightness, SIGNAL(valueChanged(int)), this, SLOT(configChanged()));
+ xl->addWidget(lidValBrightness);
+ xl->addWidget(new QLabel("+", wp));
+ xl->addStretch(1);
+ }
+ if (has_performance) {
+ lidPerformance = new QCheckBox(i18n("System performance"), lidBox);
+ QToolTip::add( lidPerformance, i18n( "Causes the performance profile to be changed" ) );
+
+ QWidget *wp = new QWidget(lidBox);
+ QHBoxLayout *xl = new QHBoxLayout( wp);
+ lidValPerformance = new KComboBox(0, wp);
+ QToolTip::add( lidValPerformance, i18n( "The performance profile to switch to" ) );
+ lidValPerformance->insertStringList(performance_list);
+ lidValPerformance->setEnabled(0);
+ connect (lidValPerformance, SIGNAL(activated(int)), this, SLOT(configChanged()));
+ xl->addWidget(lidValPerformance);
+ xl->addStretch(1);
+ }
+ if (has_throttle) {
+ lidThrottle = new QCheckBox(i18n("CPU throttle"), lidBox);
+ QToolTip::add( lidThrottle, i18n( "Causes the CPU to be throttled back" ) );
+
+ QWidget *wp = new QWidget(lidBox);
+ QHBoxLayout *xl = new QHBoxLayout( wp);
+ lidValThrottle = new KComboBox(0, wp);
+ QToolTip::add( lidValThrottle, i18n( "How much to throttle back the CPU" ) );
+ lidValThrottle->insertStringList(throttle_list);
+ lidValThrottle->setEnabled(0);
+ connect (lidValThrottle, SIGNAL(activated(int)), this, SLOT(configChanged()));
+ xl->addWidget(lidValThrottle);
+ xl->addStretch(1);
+
+
+ }
+ connect(lidBox, SIGNAL(clicked(int)), this, SLOT(configChanged()));
+ }
+
+ if (laptop_portable::has_button(laptop_portable::PowerButton)) {
+
+ powerBox = new QVButtonGroup(i18n("Power Switch Pressed"), this);
+ powerBox->layout()->setSpacing( KDialog::spacingHint() );
+ QToolTip::add( powerBox, i18n( "Select which actions will occur when the laptop's power button is pressed" ) );
+ hlay->addWidget( powerBox );
+
+ if (can_standby) {
+ powerStandby = new QRadioButton(i18n("Sta&ndby"), powerBox);
+ QToolTip::add( powerStandby, i18n( "Causes the laptop to move into the standby temporary low-power state" ) );
+ }
+ if (can_suspend) {
+ powerSuspend = new QRadioButton(i18n("S&uspend"), powerBox);
+ QToolTip::add( powerSuspend, i18n( "Causes the laptop to move into the suspend 'save-to-ram' state" ) );
+ }
+ if (can_hibernate) {
+ powerHibernate = new QRadioButton(i18n("Hi&bernate"), powerBox);
+ QToolTip::add( powerHibernate, i18n( "Causes the laptop to move into the hibernate 'save-to-disk' state" ) );
+ }
+ if (can_shutdown) {
+ powerShutdown = new QRadioButton(i18n("System power off"), powerBox);
+ QToolTip::add( powerShutdown, i18n( "Causes the laptop to power down" ) );
+ }
+ if (can_logout) {
+ powerLogout = new QRadioButton(i18n("Logout"), powerBox);
+ QToolTip::add( powerShutdown, i18n( "Causes you to be logged out" ) );
+ }
+ if (can_suspend||can_standby||can_hibernate||can_shutdown||can_logout)
+ powerOff = new QRadioButton(i18n("O&ff"), powerBox);
+ if (can_brightness) {
+ powerBrightness = new QCheckBox(i18n("Brightness"), powerBox);
+ QToolTip::add( powerBrightness, i18n( "Causes the back panel brightness to be set" ) );
+ QWidget *wp = new QWidget(powerBox);
+ QHBoxLayout *xl = new QHBoxLayout( wp);
+ xl->addWidget(new QLabel("-", wp));
+ powerValBrightness = new QSlider(0, 255, 16, 255, Qt::Horizontal, wp);
+ QToolTip::add( powerValBrightness, i18n( "How bright the back panel will be set to" ) );
+ powerValBrightness->setEnabled(0);
+ connect (powerValBrightness, SIGNAL(valueChanged(int)), this, SLOT(configChanged()));
+ xl->addWidget(powerValBrightness);
+ xl->addWidget(new QLabel("+", wp));
+ xl->addStretch(1);
+ }
+ if (has_performance) {
+ powerPerformance = new QCheckBox(i18n("System performance"), powerBox);
+ QToolTip::add( powerPerformance, i18n( "Causes the performance profile to be changed" ) );
+
+ QWidget *wp = new QWidget(powerBox);
+ QHBoxLayout *xl = new QHBoxLayout( wp);
+ powerValPerformance = new KComboBox(0, wp);
+ QToolTip::add( powerValPerformance, i18n( "The performance profile to switch to" ) );
+ powerValPerformance->insertStringList(performance_list);
+ powerValPerformance->setEnabled(0);
+ connect (powerValPerformance, SIGNAL(activated(int)), this, SLOT(configChanged()));
+ xl->addWidget(powerValPerformance);
+ xl->addStretch(1);
+ }
+ if (has_throttle) {
+ powerThrottle = new QCheckBox(i18n("CPU throttle"), powerBox);
+ QToolTip::add( powerThrottle, i18n( "Causes the CPU to be throttled back" ) );
+
+ QWidget *wp = new QWidget(powerBox);
+ QHBoxLayout *xl = new QHBoxLayout( wp);
+ powerValThrottle = new KComboBox(0, wp);
+ QToolTip::add( powerValThrottle, i18n( "How much to throttle back the CPU" ) );
+ powerValThrottle->insertStringList(throttle_list);
+ powerValThrottle->setEnabled(0);
+ connect (powerValThrottle, SIGNAL(activated(int)), this, SLOT(configChanged()));
+ xl->addWidget(powerValThrottle);
+ xl->addStretch(1);
+ }
+ connect(powerBox, SIGNAL(clicked(int)), this, SLOT(configChanged()));
+ }
+
+ hlay->addStretch(1);
+
+ QLabel* explain = new QLabel(i18n("This panel enables actions that are triggered when the lid closure switch "
+ "or power switch on your laptop is pressed. Some laptops may already "
+ "automatically do things like this, if you cannot disable them in your BIOS "
+ "you probably should not enable anything in this panel."), this);
+ explain->setAlignment( Qt::WordBreak );
+ top_layout->addWidget(explain);
+
+ top_layout->addStretch(1);
+
+ top_layout->addWidget( new QLabel( i18n("Version: %1").arg(LAPTOP_VERSION), this ), 0, Qt::AlignRight );
+ }
+ }
+
+ load();
+}
+
+ButtonsConfig::~ButtonsConfig()
+{
+ delete config;
+}
+
+void ButtonsConfig::save()
+{
+ power = getPower();
+ lid = getLid();
+ lid_bright_enabled = (lidBrightness?lidBrightness->isChecked():0);
+ power_bright_enabled = (powerBrightness?powerBrightness->isChecked():0);
+ lid_bright_val = (lidValBrightness?lidValBrightness->value():0);
+ power_bright_val = (powerValBrightness?powerValBrightness->value():0);
+ lid_performance_enabled = (lidPerformance?lidPerformance->isChecked():0);
+ power_performance_enabled = (powerPerformance?powerPerformance->isChecked():0);
+ lid_performance_val = (lidValPerformance?lidValPerformance->currentText():"");
+ power_performance_val = (powerValPerformance?powerValPerformance->currentText():"");
+ lid_throttle_enabled = (lidThrottle?lidThrottle->isChecked():0);
+ power_throttle_enabled = (powerThrottle?powerThrottle->isChecked():0);
+ lid_throttle_val = (lidValThrottle?lidValThrottle->currentText():"");
+ power_throttle_val = (powerValThrottle?powerValThrottle->currentText():"");
+
+ config->setGroup("LaptopButtons");
+ config->writeEntry("LidSuspend", lid);
+ config->writeEntry("PowerSuspend", power);
+ config->writeEntry("PowerBrightnessEnabled", power_bright_enabled);
+ config->writeEntry("LidBrightnessEnabled", lid_bright_enabled);
+ config->writeEntry("PowerBrightness", power_bright_val);
+ config->writeEntry("LidBrightness", lid_bright_val);
+ config->writeEntry("PowerPerformanceEnabled", power_performance_enabled);
+ config->writeEntry("LidPerformanceEnabled", lid_performance_enabled);
+ config->writeEntry("PowerPerformance", power_performance_val);
+ config->writeEntry("LidPerformance", lid_performance_val);
+ config->writeEntry("PowerThrottleEnabled", power_throttle_enabled);
+ config->writeEntry("LidThrottleEnabled", lid_throttle_enabled);
+ config->writeEntry("PowerThrottle", power_throttle_val);
+ config->writeEntry("LidThrottle", lid_throttle_val);
+ config->sync();
+ changed(false);
+ wake_laptop_daemon();
+}
+
+void ButtonsConfig::load()
+{
+ load( false );
+}
+
+void ButtonsConfig::load(bool useDefaults)
+{
+ config->setReadDefaults( useDefaults );
+
+ config->setGroup("LaptopButtons");
+ lid = config->readNumEntry("LidSuspend", 0);
+ power = config->readNumEntry("PowerSuspend", 0);
+ lid_bright_enabled = config->readBoolEntry("LidBrightnessEnabled", 0);
+ power_bright_enabled = config->readBoolEntry("PowerBrightnessEnabled", 0);
+ lid_bright_val = config->readNumEntry("LidBrightness", 0);
+ power_bright_val = config->readNumEntry("PowerBrightness", 0);
+ lid_performance_enabled = config->readBoolEntry("LidPerformanceEnabled", 0);
+ power_performance_enabled = config->readBoolEntry("PowerPerformanceEnabled", 0);
+ lid_performance_val = config->readEntry("LidPerformance", "");
+ power_performance_val = config->readEntry("PowerPerformance", "");
+ lid_throttle_enabled = config->readBoolEntry("LidThrottleEnabled", 0);
+ power_throttle_enabled = config->readBoolEntry("PowerThrottleEnabled", 0);
+ lid_throttle_val = config->readEntry("LidThrottle", "");
+ power_throttle_val = config->readEntry("PowerThrottle", "");
+
+ // the GUI should reflect the real values
+ setPower(power, lid);
+ if (lidBrightness)
+ lidBrightness->setChecked(lid_bright_enabled);
+ if (powerBrightness)
+ powerBrightness->setChecked(power_bright_enabled);
+ if (lidValBrightness) {
+ lidValBrightness->setValue(lid_bright_val);
+ lidValBrightness->setEnabled(lid_bright_enabled);
+ }
+ if (powerValBrightness) {
+ powerValBrightness->setValue(power_bright_val);
+ powerValBrightness->setEnabled(power_bright_enabled);
+ }
+ if (lidPerformance)
+ lidPerformance->setChecked(lid_performance_enabled);
+ if (powerPerformance)
+ powerPerformance->setChecked(power_performance_enabled);
+ if (lidValPerformance) {
+ int ind = 0;
+ for (int i = 0; i < lidValPerformance->count(); i++)
+ if (lidValPerformance->text(i) == lid_performance_val) {
+ ind = i;
+ break;
+ }
+ lidValPerformance->setCurrentItem(ind);
+ lidValPerformance->setEnabled(lid_performance_enabled);
+ }
+ if (powerValPerformance) {
+ int ind = 0;
+ for (int i = 0; i < powerValPerformance->count(); i++)
+ if (powerValPerformance->text(i) == power_performance_val) {
+ ind = i;
+ break;
+ }
+ powerValPerformance->setCurrentItem(ind);
+ powerValPerformance->setEnabled(power_performance_enabled);
+ }
+ if (lidThrottle)
+ lidThrottle->setChecked(lid_throttle_enabled);
+ if (powerThrottle)
+ powerThrottle->setChecked(power_throttle_enabled);
+ if (lidValThrottle) {
+ int ind = 0;
+ for (int i = 0; i < lidValThrottle->count(); i++)
+ if (lidValThrottle->text(i) == lid_throttle_val) {
+ ind = i;
+ break;
+ }
+ lidValThrottle->setCurrentItem(ind);
+ lidValThrottle->setEnabled(lid_throttle_enabled);
+ }
+ if (powerValThrottle) {
+ int ind = 0;
+ for (int i = 0; i < powerValThrottle->count(); i++)
+ if (powerValThrottle->text(i) == power_throttle_val) {
+ ind = i;
+ break;
+ }
+ powerValThrottle->setCurrentItem(ind);
+ powerValThrottle->setEnabled(power_throttle_enabled);
+ }
+ emit changed( useDefaults );
+}
+
+void ButtonsConfig::defaults()
+{
+ setPower(0, 0);
+ lid_bright_enabled = 0;
+ power_bright_enabled = 0;
+ lid_bright_val = 0;
+ power_bright_val = 0;
+ lid_performance_enabled = 0;
+ power_performance_enabled = 0;
+ lid_performance_val = "";
+ power_performance_val = "";
+ lid_throttle_enabled = 0;
+ power_throttle_enabled = 0;
+ lid_throttle_val = "";
+ power_throttle_val = "";
+ if (lidBrightness)
+ lidBrightness->setChecked(lid_bright_enabled);
+ if (powerBrightness)
+ powerBrightness->setChecked(power_bright_enabled);
+ if (lidValBrightness) {
+ lidValBrightness->setValue(lid_bright_val);
+ lidValBrightness->setEnabled(lid_bright_enabled);
+ }
+ if (powerValBrightness) {
+ powerValBrightness->setValue(power_bright_val);
+ powerValBrightness->setEnabled(power_bright_enabled);
+ }
+
+
+ if (lidPerformance)
+ lidPerformance->setChecked(lid_performance_enabled);
+ if (powerPerformance)
+ powerPerformance->setChecked(power_performance_enabled);
+ if (lidValPerformance) {
+ lidValPerformance->setCurrentItem(0);
+ lidValPerformance->setEnabled(lid_performance_enabled);
+ }
+ if (powerValPerformance) {
+ powerValPerformance->setCurrentItem(0);
+ powerValPerformance->setEnabled(power_performance_enabled);
+ }
+ if (lidThrottle)
+ lidThrottle->setChecked(lid_throttle_enabled);
+ if (powerThrottle)
+ powerThrottle->setChecked(power_throttle_enabled);
+ if (lidValThrottle) {
+ lidValThrottle->setCurrentItem(0);
+ lidValThrottle->setEnabled(lid_throttle_enabled);
+ }
+ if (powerValThrottle) {
+ powerValThrottle->setCurrentItem(0);
+ powerValThrottle->setEnabled(power_throttle_enabled);
+ }
+}
+
+int ButtonsConfig::getLid()
+{
+ if (!apm)
+ return(lid);
+ if (lidHibernate && lidHibernate->isChecked())
+ return 3;
+ if (lidStandby && lidStandby->isChecked())
+ return 1;
+ if (lidSuspend && lidSuspend->isChecked())
+ return 2;
+ if (lidLogout && lidLogout->isChecked())
+ return 4;
+ if (lidShutdown && lidShutdown->isChecked())
+ return 5;
+ return(0);
+}
+
+int ButtonsConfig::getPower()
+{
+ if (!apm)
+ return(power);
+ if (powerHibernate && powerHibernate->isChecked())
+ return 3;
+ if (powerStandby && powerStandby->isChecked())
+ return 1;
+ if (powerSuspend && powerSuspend->isChecked())
+ return 2;
+ if (powerLogout && powerLogout->isChecked())
+ return 4;
+ if (powerShutdown && powerShutdown->isChecked())
+ return 5;
+ return(0);
+}
+
+void ButtonsConfig::setPower(int p, int np)
+{
+ if (!apm)
+ return;
+ if (lidSuspend) {
+ lidSuspend->setChecked(FALSE);
+ } else {
+ if (np == 2) np = 0;
+ }
+ if (lidShutdown) {
+ lidShutdown->setChecked(FALSE);
+ } else {
+ if (np == 5) np = 0;
+ }
+ if (lidLogout) {
+ lidLogout->setChecked(FALSE);
+ } else {
+ if (np == 4) np = 0;
+ }
+ if (lidStandby) {
+ lidStandby->setChecked(FALSE);
+ } else {
+ if (np == 1) np = 0;
+ }
+ if (lidHibernate) {
+ lidHibernate->setChecked(FALSE);
+ } else {
+ if (np == 3) np = 0;
+ }
+ if (lidOff)
+ lidOff->setChecked(FALSE);
+ switch (np) {
+ case 0: if (lidOff)
+ lidOff->setChecked(TRUE);
+ break;
+ case 1: lidStandby->setChecked(TRUE);break;
+ case 2: lidSuspend->setChecked(TRUE);break;
+ case 3: lidHibernate->setChecked(TRUE);break;
+ case 4: lidLogout->setChecked(TRUE);break;
+ case 5: lidShutdown->setChecked(TRUE);break;
+ }
+ if (powerSuspend) {
+ powerSuspend->setChecked(FALSE);
+ } else {
+ if (p == 2) p = 0;
+ }
+ if (powerLogout) {
+ powerLogout->setChecked(FALSE);
+ } else {
+ if (p == 4) p = 0;
+ }
+ if (powerShutdown) {
+ powerShutdown->setChecked(FALSE);
+ } else {
+ if (p == 5) p = 0;
+ }
+ if (powerStandby) {
+ powerStandby->setChecked(FALSE);
+ } else {
+ if (p == 1) p = 0;
+ }
+ if (powerHibernate) {
+ powerHibernate->setChecked(FALSE);
+ } else {
+ if (p == 3) p = 0;
+ }
+ if (powerOff)
+ powerOff->setChecked(FALSE);
+ switch (p) {
+ case 0: if (powerOff)
+ powerOff->setChecked(TRUE);
+ break;
+ case 1: powerStandby->setChecked(TRUE);break;
+ case 2: powerSuspend->setChecked(TRUE);break;
+ case 3: powerHibernate->setChecked(TRUE);break;
+ case 4: powerLogout->setChecked(TRUE);break;
+ case 5: powerShutdown->setChecked(TRUE);break;
+ }
+}
+
+
+
+void ButtonsConfig::configChanged()
+{
+ if (powerBrightness)
+ powerValBrightness->setEnabled(powerBrightness->isChecked());
+ if (lidBrightness)
+ lidValBrightness->setEnabled(lidBrightness->isChecked());
+
+ if (powerPerformance)
+ powerValPerformance->setEnabled(powerPerformance->isChecked());
+ if (lidPerformance)
+ lidValPerformance->setEnabled(lidPerformance->isChecked());
+
+ if (powerThrottle)
+ powerValThrottle->setEnabled(powerThrottle->isChecked());
+ if (lidThrottle)
+ lidValThrottle->setEnabled(lidThrottle->isChecked());
+
+ emit changed(true);
+}
+
+
+QString ButtonsConfig::quickHelp() const
+{
+ return i18n("<h1>Laptop Power Control</h1>This module allows you to "
+ "configure the power switch or lid closure switch on your laptop "
+ "so they can trigger system actions");
+
+}
+
+#include "buttons.moc"
diff --git a/klaptopdaemon/buttons.h b/klaptopdaemon/buttons.h
new file mode 100644
index 0000000..5abd088
--- /dev/null
+++ b/klaptopdaemon/buttons.h
@@ -0,0 +1,92 @@
+/*
+ * pcmcia.h
+ *
+ * Copyright (c) 1999 Paul Campbell <paul@taniwha.com>
+ *
+ * Requires the Qt widget libraries, available at no cost at
+ * http://www.troll.no/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef __BUTTONSCONFIG_H__
+#define __BUTTONSCONFIG_H__
+
+#include <kcmodule.h>
+#include <qstring.h>
+
+class QWidget;
+class QSlider;
+class QButtonGroup;
+class QRadioButton;
+class QSpinBox;
+class KConfig;
+class QCheckBox;
+class KComboBox;
+
+class ButtonsConfig : public KCModule
+{
+ Q_OBJECT
+public:
+ ButtonsConfig( QWidget *parent=0, const char* name=0);
+ ~ButtonsConfig();
+ void save( void );
+ void load();
+ void load(bool useDefaults);
+ void defaults();
+
+ virtual QString quickHelp() const;
+
+private slots:
+
+ void configChanged();
+
+
+private:
+
+ int getPower();
+ int getLid();
+ void setPower( int, int );
+
+ QButtonGroup *lidBox;
+ QRadioButton *lidStandby, *lidSuspend, *lidOff, *lidHibernate, *lidShutdown, *lidLogout;
+ QCheckBox *lidBrightness;
+ QSlider *lidValBrightness;
+ QCheckBox *lidThrottle;
+ KComboBox *lidValThrottle;
+ QCheckBox *lidPerformance;
+ KComboBox *lidValPerformance;
+ QButtonGroup *powerBox;
+ QRadioButton *powerStandby, *powerSuspend, *powerOff, *powerHibernate, *powerShutdown, *powerLogout;
+ QCheckBox *powerBrightness;
+ QSlider *powerValBrightness;
+ QCheckBox *powerThrottle;
+ KComboBox *powerValThrottle;
+ QCheckBox *powerPerformance;
+ KComboBox *powerValPerformance;
+ int power_bright_val, lid_bright_val;
+ bool lid_bright_enabled, power_bright_enabled;
+ bool lid_throttle_enabled, power_throttle_enabled;
+ QString lid_throttle_val, power_throttle_val;
+ bool lid_performance_enabled, power_performance_enabled;
+ QString lid_performance_val, power_performance_val;
+
+ KConfig *config;
+ int power, lid, apm;
+};
+
+#endif
+
diff --git a/klaptopdaemon/checkcrc.h b/klaptopdaemon/checkcrc.h
new file mode 100644
index 0000000..149f28b
--- /dev/null
+++ b/klaptopdaemon/checkcrc.h
@@ -0,0 +1,53 @@
+/*
+ * checkcrc.h
+ *
+ * Copyright (c) 2003 Paul Campbell <paul@taniwha.com>
+ * Requires the Qt widget libraries, available at no cost at
+ * http://www.troll.no/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _CHECKCRC_H_
+#define _CHECKCRC_H_
+
+
+
+#include <zlib.h>
+#include <stdio.h>
+
+static void
+checkcrc(const char *name, unsigned long &len_res, unsigned long &crc_res)
+{
+ unsigned long crc = ::crc32(0L, Z_NULL, 0);
+ unsigned long len = 0;
+
+ FILE *f = ::fopen(name, "r");
+ if (f) {
+ unsigned char buffer[1024];
+ for (;;) {
+ int l = ::fread(buffer, 1, sizeof(buffer), f);
+ if (l <= 0)
+ break;
+ len += l;
+ crc = ::crc32(crc, buffer, l);
+ }
+ ::fclose(f);
+ }
+ crc_res = crc;
+ len_res = len;
+}
+
+#endif
diff --git a/klaptopdaemon/configure.in.bot b/klaptopdaemon/configure.in.bot
new file mode 100644
index 0000000..51630ed
--- /dev/null
+++ b/klaptopdaemon/configure.in.bot
@@ -0,0 +1,9 @@
+if test -z "$TPCTL"; then
+ echo ""
+ echo "You're missing tpctl. If you're using a ThinkPad, you may miss"
+ echo "some functionality of klaptopdaemon."
+ echo "You can get them from http://tpctl.sourceforge.net/tpctlhome.htm"
+ echo ""
+ all_tests=bad
+fi
+
diff --git a/klaptopdaemon/configure.in.in b/klaptopdaemon/configure.in.in
new file mode 100644
index 0000000..c1c5427
--- /dev/null
+++ b/klaptopdaemon/configure.in.in
@@ -0,0 +1,49 @@
+KDE_FIND_PATH(tpctl, TPCTL, [$exec_prefix/bin $prefix/bin /usr/bin /usr/local/bin /opt/local/bin], [TPCTL=""])
+AC_DEFINE_UNQUOTED(PATH_TPCTL, "$TPCTL", [Defines the executable of tpctl])
+
+AC_CHECK_HEADERS(machine/apm_bios.h)
+
+if test "x$kde_use_qt_mac" = "xyes"; then
+ DO_NOT_COMPILE="$DO_NOT_COMPILE klaptopdaemon"
+fi
+
+
+xss_save_ldflags="$LDFLAGS"
+LDFLAGS="$X_LDFLAGS"
+
+LIB_XSS=
+
+AC_ARG_WITH([xscreensaver],
+ AC_HELP_STRING([--without-xscreensaver], [Disable XScreenSaver support (default: check)]) )
+
+if test "x$with_xscreensaver" != "xno"; then
+ KDE_CHECK_HEADER(X11/extensions/scrnsaver.h,
+ [
+ AC_CHECK_LIB(Xext,XScreenSaverQueryInfo,
+ [
+ AC_DEFINE(HAVE_XSCREENSAVER, 1, [Define if you have the XScreenSaver extension])
+ LIB_XSS="-lXext"
+ ],
+ [
+ ld_shared_flag=
+ xss_save_cxxflags="$CXXFLAGS"
+ CXXFLAGS="$CXXFLAGS $lt_prog_compiler_pic_CXX"
+ KDE_CHECK_COMPILER_FLAG(shared, [ld_shared_flag="-shared"])
+ AC_CHECK_LIB(Xss,XScreenSaverQueryInfo,
+ [
+ AC_DEFINE(HAVE_XSCREENSAVER, 1, [Define if you have the XScreenSaver extension])
+ LIB_XSS="-lXss"
+ ],
+ [],
+ [ $ld_shared_flag $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS ])
+ CXXFLAGS="$xss_save_cxxflags"
+ ],
+ [ $X_PRE_LIBS -lX11 $X_EXTRA_LIBS ])
+ ], [],
+ [
+ #include <X11/Xlib.h>
+ ] )
+fi
+
+AC_SUBST(LIB_XSS)
+LDFLAGS="$xss_save_ldflags"
diff --git a/klaptopdaemon/daemon_state.cpp b/klaptopdaemon/daemon_state.cpp
new file mode 100644
index 0000000..5ca0d28
--- /dev/null
+++ b/klaptopdaemon/daemon_state.cpp
@@ -0,0 +1,282 @@
+/*
+ * daemon_state.cpp
+ * Copyright (C) 1999, 2003 Paul Campbell <paul@taniwha.com>
+ *
+ * this replaces kcmlaptop - there are 2 parts - one is the panels that
+ * put the setup configuration in the "kcmlaptop" configm, the other
+ * is the laptop_daemon (this guy) who watches the battery state
+ * and does stuff as a result
+ *
+ * This file contains the implementation of the main laptop battery monitoring daemon
+ *
+ * $Id$
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <stdlib.h>
+#include <fcntl.h>
+
+#include <qtimer.h>
+
+#include <kconfig.h>
+#include <klocale.h>
+#include <kcmdlineargs.h>
+#include "daemon_state.h"
+#include "portable.h"
+#include <kaboutdata.h>
+#include <kaudioplayer.h>
+#include <sys/ioctl.h>
+#include <kmessagebox.h>
+#include <dcopclient.h>
+#include <qsocketnotifier.h>
+#include <qcursor.h>
+
+
+#include <unistd.h>
+#include <sys/time.h>
+
+daemon_state::daemon_state()
+{
+ exists = laptop_portable::has_power_management();
+ has_brightness = laptop_portable::has_brightness();
+ QStringList profile_list;
+ int current_profile;
+ bool *active_list;
+ has_performance = laptop_portable::get_system_performance(0, current_profile, profile_list, active_list);
+ QStringList throttle_list;
+ int current_throttle;
+ has_throttle = laptop_portable::get_system_throttling(0, current_throttle, throttle_list, active_list);
+
+}
+
+daemon_state::~daemon_state()
+{
+}
+
+void daemon_state::load()
+{
+ KConfig *config = new KConfig("kcmlaptoprc");
+
+ if (config == 0) {
+ ::fprintf(stderr, "laptop_daemon: can't open kcmlaptop config files\n");
+ ::exit(2);
+ }
+
+
+ // acpi settings
+ config->setGroup("AcpiDefault");
+ bool enablestandby = config->readBoolEntry("EnableStandby", false);
+ bool enablesuspend = config->readBoolEntry("EnableSuspend", false);
+ bool enablehibernate = config->readBoolEntry("EnableHibernate", false);
+ bool enableperformance = config->readBoolEntry("EnablePerformance", false);
+ bool enablethrottle = config->readBoolEntry("EnableThrottle", false);
+ laptop_portable::acpi_set_mask(enablestandby, enablesuspend, enablehibernate, enableperformance, enablethrottle);
+
+ config->setGroup("ApmDefault");
+ enablestandby = config->readBoolEntry("EnableStandby", false);
+ enablesuspend = config->readBoolEntry("EnableSuspend", false);
+ laptop_portable::apm_set_mask(enablestandby, enablesuspend);
+
+ config->setGroup("SoftwareSuspendDefault");
+ enablehibernate = config->readBoolEntry("EnableHibernate", false);
+ laptop_portable::software_suspend_set_mask(enablehibernate);
+
+ exists = laptop_portable::has_power_management();
+ has_brightness = laptop_portable::has_brightness();
+ QStringList profile_list;
+ int current_profile;
+ bool *active_list;
+ has_performance = laptop_portable::get_system_performance(0, current_profile, profile_list, active_list);
+ QStringList throttle_list;
+ int current_throttle;
+ has_throttle = laptop_portable::get_system_throttling(0, current_throttle, throttle_list, active_list);
+
+ bool can_suspend = laptop_portable::has_suspend();
+ bool can_hibernate = laptop_portable::has_hibernation();
+ bool can_standby = laptop_portable::has_standby();
+
+ // power control settings
+ config->setGroup("LaptopPower");
+ power_action[0] = config->readNumEntry("PowerSuspend", 0);
+ switch (power_action[0]) {
+ case 1: if (!can_standby) power_action[0] = 0; break;
+ case 2: if (!can_suspend) power_action[0] = 0; break;
+ case 3: if (!can_hibernate) power_action[0] = 0; break;
+ }
+ power_action[1] = config->readNumEntry("NoPowerSuspend", 1);
+ switch (power_action[1]) {
+ case 1: if (!can_standby) power_action[1] = 0; break;
+ case 2: if (!can_suspend) power_action[1] = 0; break;
+ case 3: if (!can_hibernate) power_action[1] = 0; break;
+ }
+ power_brightness_enabled[0] = config->readBoolEntry("PowerBrightnessEnabled", 0)&has_brightness;
+ power_brightness_enabled[1] = config->readBoolEntry("NoPowerBrightnessEnabled", 0)&has_brightness;
+ power_brightness[0] = config->readNumEntry("PowerBrightness", 255);
+ power_brightness[1] = config->readNumEntry("NoPowerBrightness", 0);
+ power_performance_enabled[0] = config->readBoolEntry("PowerPerformanceEnabled", 0)&has_performance;
+ power_performance_enabled[1] = config->readBoolEntry("NoPowerPerformanceEnabled", 0)&has_performance;
+ power_performance[0] = config->readEntry("PowerPerformance", "");
+ power_performance[1] = config->readEntry("NoPowerPerformance", "");
+ power_throttle_enabled[0] = config->readBoolEntry("PowerThrottleEnabled", 0)&has_throttle;
+ power_throttle_enabled[1] = config->readBoolEntry("NoPowerThrottleEnabled", 0)&has_throttle;
+ power_throttle[0] = config->readEntry("PowerThrottle", "");
+ power_throttle[1] = config->readEntry("NoPowerThrottle", "");
+ power_wait[0] = 60*config->readNumEntry("PowerWait", 20);
+ power_wait[1] = 60*config->readNumEntry("NoPowerWait", 5);
+ lav_enabled[0] = config->readBoolEntry("LavEnabled", 0);
+ lav_enabled[1] = config->readBoolEntry("NoLavEnabled", 0);
+ lav_val[0] = config->readDoubleNumEntry("PowerLav", -1);
+ lav_val[1] = config->readDoubleNumEntry("NoPowerLav", -1);
+
+ // General settings
+ config->setGroup("BatteryDefault");
+ poll = config->readNumEntry("Poll", 20);
+ enabled = config->readBoolEntry("Enable", true)&exists;
+ notifyMeWhenFull = config->readBoolEntry("NotifyMe", false)&exists;
+ useBlankSaver = config->readBoolEntry("BlankSaver", false);
+ noBatteryIcon = config->readEntry("NoBatteryPixmap", "laptop_nobattery");
+ noChargeIcon = config->readEntry("NoChargePixmap", "laptop_nocharge");
+ chargeIcon = config->readEntry("ChargePixmap", "laptop_charge");
+
+
+ config->setGroup("BatteryLow");
+ time_based_action_low = config->readBoolEntry("TimeBasedAction", true);
+ low[0] = config->readNumEntry("LowValTime", 15);
+ low[1] = config->readNumEntry("LowValPercent", 7);
+ runCommand[0] = config->readBoolEntry("RunCommand", false)&exists;
+ runCommandPath[0] = config->readEntry("RunCommandPath");
+ playSound[0] = config->readBoolEntry("PlaySound", false)&exists;
+ playSoundPath[0] = config->readEntry("PlaySoundPath");
+ systemBeep[0] = config->readBoolEntry("SystemBeep", true)&exists;
+ logout[0] = config->readBoolEntry("Logout", false)&exists;
+ shutdown[0] = config->readBoolEntry("Shutdown", false)&exists;
+ notify[0] = config->readBoolEntry("Notify", true)&exists;
+ do_hibernate[0] = config->readBoolEntry("Hibernate", false)&can_hibernate&exists;
+ do_suspend[0] = config->readBoolEntry("Suspend", false)&can_suspend&exists;
+ do_standby[0] = config->readBoolEntry("Standby", false)&can_standby&exists;
+ do_brightness[0] = config->readBoolEntry("Brightness", false)&has_brightness&exists;
+ val_brightness[0] = config->readNumEntry("BrightnessValue", 0);
+ do_performance[0] = config->readBoolEntry("Performance", false)&has_performance&exists;
+ val_performance[0] = config->readEntry("PerformanceValue", "");
+ do_throttle[0] = config->readBoolEntry("Throttle", false)&has_throttle&exists;
+ val_throttle[0] = config->readEntry("ThrottleValue", "");
+ have_time = config->readNumEntry("HaveTime", 2);
+
+ if (!have_time && laptop_portable::has_battery_time())
+ have_time = 1;
+
+ config->setGroup("BatteryCritical");
+ time_based_action_critical = config->readBoolEntry("TimeBasedAction", true);
+ low[2] = config->readNumEntry("CriticalValTime", 5);
+ low[3] = config->readNumEntry("CriticalValPercent", 3);
+ runCommand[1] = config->readBoolEntry("RunCommand", false)&exists;
+ runCommandPath[1] = config->readEntry("RunCommandPath");
+ playSound[1] = config->readBoolEntry("PlaySound", false)&exists;
+ playSoundPath[1] = config->readEntry("PlaySoundPath");
+ systemBeep[1] = config->readBoolEntry("SystemBeep", true)&exists;
+ logout[1] = config->readBoolEntry("Logout", false)&exists;
+ shutdown[1] = config->readBoolEntry("Shutdown", false)&exists;
+ notify[1] = config->readBoolEntry("Notify", (can_suspend?false:true))&exists;
+ do_hibernate[1] = config->readBoolEntry("Hibernate", false)&can_hibernate&exists;
+ do_suspend[1] = config->readBoolEntry("Suspend", (can_suspend?true:false))&can_suspend&exists;
+ do_standby[1] = config->readBoolEntry("Standby", false)&can_standby&exists;
+ do_brightness[1] = config->readBoolEntry("Brightness", false)&has_brightness&exists;
+ val_brightness[1] = config->readNumEntry("BrightnessValue", 0);
+ do_performance[1] = config->readBoolEntry("Performance", false)&has_performance&exists;
+ val_performance[1] = config->readEntry("PerformanceValue", "");
+ do_throttle[1] = config->readBoolEntry("Throttle", false)&has_throttle&exists;
+ val_throttle[1] = config->readEntry("ThrottleValue", "");
+
+ config->setGroup("ProfileDefault");
+ bright_pon = config->readBoolEntry("EnableBrightnessOn", false)&has_brightness;
+ bright_poff = config->readBoolEntry("EnableBrightnessOff", false)&has_brightness;
+ performance_pon = config->readBoolEntry("EnablePerformanceOn", false)&has_performance;
+ performance_poff = config->readBoolEntry("EnablePerformanceOff", false)&has_performance;
+ throttle_pon = config->readBoolEntry("EnableThrottleOn", false)&has_throttle;
+ throttle_poff = config->readBoolEntry("EnableThrottleOff", false)&has_throttle;
+ bright_son = config->readNumEntry("BrightnessOnLevel", 255);
+ bright_soff = config->readNumEntry("BrightnessOffLevel", 160);
+ performance_val_on = config->readEntry("PerformanceOnLevel", "");
+ performance_val_off = config->readEntry("PerformanceOffLevel", "");
+ throttle_val_on = config->readEntry("ThrottleOnLevel", "");
+ throttle_val_off = config->readEntry("ThrottleOffLevel", "");
+
+ config->setGroup("LaptopButtons");
+ enable_lid_button = laptop_portable::has_button(laptop_portable::LidButton);
+ enable_power_button = laptop_portable::has_button(laptop_portable::PowerButton);
+ button_lid = (enable_lid_button?config->readNumEntry("LidSuspend", 0):0);
+ if (!enable_lid_button) {
+ button_lid = 0;
+ } else
+ switch (button_lid) {
+ case 1: if (!can_standby) button_lid = 0; break;
+ case 2: if (!can_suspend) button_lid = 0; break;
+ case 3: if (!can_hibernate) button_lid = 0; break;
+ }
+ button_power = (enable_power_button?config->readNumEntry("PowerSuspend", 0):0);
+ if (!enable_power_button) {
+ button_power = 0;
+ } else
+ switch (button_power) {
+ case 1: if (!can_standby) button_power = 0; break;
+ case 2: if (!can_suspend) button_power = 0; break;
+ case 3: if (!can_hibernate) button_power = 0; break;
+ }
+ button_lid_bright_enabled = config->readBoolEntry("LidBrightnessEnabled", 0)&enable_lid_button&has_brightness;
+ button_power_bright_enabled = config->readBoolEntry("PowerBrightnessEnabled", 0)&enable_power_button&has_brightness;
+ button_lid_bright_val = config->readNumEntry("LidBrightness", 0);
+ button_power_bright_val = config->readNumEntry("PowerBrightness", 0);
+ button_lid_performance_enabled = config->readBoolEntry("LidPerformanceEnabled", 0)&enable_lid_button&has_performance;
+ button_power_performance_enabled = config->readBoolEntry("PowerPerformanceEnabled", 0)&enable_power_button&has_performance;
+ button_lid_performance_val = config->readEntry("LidPerformance", "");
+ button_power_performance_val = config->readEntry("PowerPerformance", "");
+ button_lid_throttle_enabled = config->readBoolEntry("LidThrottleEnabled", 0)&enable_lid_button&has_throttle;
+ button_power_throttle_enabled = config->readBoolEntry("PowerThrottleEnabled", 0)&enable_power_button&has_throttle;
+ button_lid_throttle_val = config->readEntry("LidThrottle", "");
+ button_power_throttle_val = config->readEntry("PowerThrottle", "");
+
+ config->setGroup("SonyDefault");
+ sony_enablescrollbar = config->readBoolEntry("EnableScrollBar", false);
+ sony_middleemulation = config->readBoolEntry("EnableMiddleEmulation", false);
+
+ delete config;
+}
+
+bool
+daemon_state::need_to_run()
+{
+ //
+ // look for reasons NOT to run the daemon
+ //
+ if (!exists)
+ return(0);
+ if (!enabled && !notifyMeWhenFull &&
+ !runCommand[0] && !playSound[0] && !systemBeep[0] && !notify[0] && !do_suspend[0] &&
+ !do_standby[0] && !logout[0] && !shutdown[0] && !do_hibernate[0] &&
+ !runCommand[1] && !playSound[1] && !systemBeep[1] && !notify[1] && !do_suspend[1] &&
+ !do_standby[1] && !logout[1] && !shutdown[1] && !do_hibernate[0] &&
+ !sony_enablescrollbar && !sony_middleemulation && !do_brightness[0] && !do_brightness[1] &&
+ button_lid==0 && button_power==0 && !button_lid_bright_enabled && !button_power_bright_enabled &&
+ !button_lid_performance_enabled && !button_power_performance_enabled && !button_lid_throttle_enabled && !button_power_throttle_enabled &&
+ !do_performance[0] && !do_performance[1] && !do_throttle[0] && !do_throttle[1] &&
+ !bright_pon && !bright_poff && !performance_pon && !performance_poff && !throttle_pon && !throttle_poff &&
+ !power_brightness_enabled[0] && !power_brightness_enabled[0] &&
+ !power_performance_enabled[0] && !power_performance_enabled[1] && !power_throttle_enabled[0] && !power_throttle_enabled[1] &&
+ power_action[0] == 0 && power_action[1] == 0) // if no reason to be running quit
+ return(0);
+ return(1);
+}
+
diff --git a/klaptopdaemon/daemon_state.h b/klaptopdaemon/daemon_state.h
new file mode 100644
index 0000000..6da4e73
--- /dev/null
+++ b/klaptopdaemon/daemon_state.h
@@ -0,0 +1,141 @@
+#ifndef __DAEMON_STATE_H
+#define __DAEMON_STATE_H 1
+/*
+ * daemon_state.h
+ * Copyright (C) 1999, 2003 Paul Campbell <paul@taniwha.com>
+ *
+ * This file contains the saved config state for the laptop daemon
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#include <qdir.h>
+#include <unistd.h>
+#include <time.h>
+#include <qmovie.h>
+#include <qptrlist.h>
+#include <qfileinfo.h>
+#include <qimage.h>
+#include <kdelibs_export.h>
+
+class KDE_EXPORT daemon_state
+{
+public:
+ daemon_state();
+ ~daemon_state();
+ void load();
+ bool need_to_run();
+
+ bool exists;
+ bool has_brightness;
+ bool has_performance;
+ bool has_throttle;
+
+ QString noBatteryIcon;
+ QString chargeIcon;
+ QString noChargeIcon;
+
+ //
+ // power out actions
+ //
+
+ int power_wait[2]; // how close to the end when we trigger the action
+ int power_action[2]; // what to do when this action is triggered
+ int power_brightness[2]; // which brightness level to switch to
+ bool power_brightness_enabled[2]; // and whether to switch
+ QString power_performance[2]; // which performance level to switch to
+ bool power_performance_enabled[2]; // and whether to switch
+ QString power_throttle[2]; // which throttling level to switch to
+ bool power_throttle_enabled[2]; // and whether to switch
+ bool lav_enabled[2]; // check LAV first
+ float lav_val[2]; // don't act if higher than this
+
+ //
+ // power out warnings
+ //
+
+ bool systemBeep[2];
+ bool logout[2];
+ bool shutdown[2];
+ bool runCommand[2];
+ QString runCommandPath[2];
+ bool playSound[2];
+ QString playSoundPath[2];
+ bool notify[2];
+ bool do_suspend[2];
+ bool do_hibernate[2];
+ bool do_standby[2];
+ bool do_brightness[2];
+ int val_brightness[2];
+ bool do_performance[2];
+ QString val_performance[2];
+ bool do_throttle[2];
+ QString val_throttle[2];
+ bool time_based_action_low, time_based_action_critical;
+ int low[4];
+ int poll; // how often to pol
+
+
+
+ bool enabled;
+ bool notifyMeWhenFull;
+ bool useBlankSaver;
+
+
+ int have_time;
+
+ // sony jog-bar support
+
+ bool sony_enablescrollbar; // enable jog bar support
+ bool sony_middleemulation; // press on jog bar emulates mouse middle button
+
+ // brightness
+
+ bool bright_pon; // auto set brightness when powered
+ int bright_son; // value to set
+ bool bright_poff; // auto set brightness when on battery
+ int bright_soff; // value to set
+
+ // performance
+
+ bool performance_pon, performance_poff;
+ QString performance_val_on, performance_val_off;
+
+ // throttle
+
+ bool throttle_pon, throttle_poff;
+ QString throttle_val_on, throttle_val_off;
+
+ // button triggered stuff
+ int button_lid;
+ int button_power;
+ bool button_lid_bright_enabled;
+ bool button_power_bright_enabled;
+ int button_lid_bright_val;
+ int button_power_bright_val;
+ bool button_lid_performance_enabled;
+ bool button_power_performance_enabled;
+ QString button_lid_performance_val;
+ QString button_power_performance_val;
+ bool button_lid_throttle_enabled;
+ bool button_power_throttle_enabled;
+ QString button_lid_throttle_val;
+ QString button_power_throttle_val;
+ bool enable_lid_button;
+ bool enable_power_button;
+
+};
+#endif
diff --git a/klaptopdaemon/daemondock.cpp b/klaptopdaemon/daemondock.cpp
new file mode 100644
index 0000000..3551931
--- /dev/null
+++ b/klaptopdaemon/daemondock.cpp
@@ -0,0 +1,756 @@
+/*
+ * daemondock.cpp
+ * Copyright (C) 1999 Paul Campbell <paul@taniwha.com>
+ * Copyright (C) 2006 Flavio Castelli <flavio.castelli@gmail.com>
+ *
+ * This file contains the docked widget for the laptop battery monitor
+ *
+ * $Id$
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <qcursor.h>
+
+#include <qslider.h>
+#include <klocale.h>
+#include <kpopupmenu.h>
+#include <dcopclient.h>
+#include <dcopref.h>
+#include "kpcmciainfo.h"
+#include "daemondock.h"
+#include "portable.h"
+#include <kiconloader.h>
+#include <kapplication.h>
+#include <kprocess.h>
+#include <kstandarddirs.h>
+#include <kconfig.h>
+#include <kglobalsettings.h>
+#include <kmessagebox.h>
+#include <qvbox.h>
+#include <qstringlist.h>
+#include <qbitmap.h>
+#include <qpainter.h>
+#include <kiconeffect.h>
+extern void wake_laptop_daemon();
+
+laptop_dock::laptop_dock( laptop_daemon* parent )
+ : KSystemTray()
+{
+ setCaption(i18n("KLaptop Daemon"));
+ KGlobal::locale()->insertCatalogue("klaptopdaemon"); // For translation of klaptopdaemon messages
+ _pcmcia = NULL;
+ pdaemon = parent;
+ current_code = -1;
+ brightness_widget = 0;
+ instance = new KInstance("klaptopdaemon");
+ // popup menu for right mouse button
+ rightPopup = contextMenu();
+ SetupPopup();
+}
+
+void
+laptop_dock::SetupPopup()
+{
+ rightPopup->clear();
+ rightPopup->insertTitle(SmallIcon("laptop_battery"), "KLaptop", 999); // otherwise we look like KDED
+
+ int has_brightness = laptop_portable::has_brightness();
+ int can_standby = laptop_portable::has_standby();
+ int can_suspend = laptop_portable::has_suspend();
+ int can_hibernate = laptop_portable::has_hibernation();
+ QStringList profile_list;
+ int current_profile;
+ bool *active_list;
+ bool has_performance = laptop_portable::get_system_performance(0, current_profile, profile_list, active_list);
+ QStringList throttle_list;
+ int current_throttle;
+ bool has_throttle = laptop_portable::get_system_throttling(0, current_throttle, throttle_list, active_list);
+ rightPopup->insertItem(SmallIcon("configure"), i18n("&Configure KLaptop..."), this, SLOT(invokeSetup()));
+
+ if (has_brightness)
+ rightPopup->insertItem(i18n("Screen Brightness..."), this, SLOT(invokeBrightness()));
+ if (has_performance) {
+ performance_popup = new QPopupMenu(0, "performance");
+ performance_popup->setCheckable(1);
+ rightPopup->insertItem(i18n("Performance Profile..."), performance_popup);
+ connect( performance_popup, SIGNAL( activated( int ) ), this, SLOT( activate_performance( int ) ) );
+ connect( performance_popup, SIGNAL( aboutToShow() ), this, SLOT( fill_performance() ) );
+ } else {
+ performance_popup = 0;
+ }
+ if (has_throttle) {
+ throttle_popup = new QPopupMenu(0, "throttle");
+ throttle_popup->setCheckable(1);
+ rightPopup->insertItem(i18n("CPU Throttling..."), throttle_popup);
+ connect( throttle_popup, SIGNAL( activated( int ) ), this, SLOT( activate_throttle( int ) ) );
+ connect( throttle_popup, SIGNAL( aboutToShow() ), this, SLOT( fill_throttle() ) );
+ } else {
+ throttle_popup = 0;
+ }
+
+ if (can_standby || can_suspend || can_hibernate) {
+ rightPopup->insertSeparator();
+ if (can_standby) rightPopup->insertItem(i18n("Standby..."), this, SLOT(invokeStandby()));
+ if (can_suspend) rightPopup->insertItem(i18n("&Lock && Suspend..."), this, SLOT(invokeLockSuspend()));
+ if (can_suspend) rightPopup->insertItem(i18n("&Suspend..."), this, SLOT(invokeSuspend()));
+ if (can_hibernate) rightPopup->insertItem(i18n("&Lock && Hibernate..."), this, SLOT(invokeLockHibernation()));
+ if (can_hibernate) rightPopup->insertItem(i18n("&Hibernate..."), this, SLOT(invokeHibernation()));
+ }
+
+ rightPopup->insertSeparator();
+ rightPopup->insertItem(i18n("&Hide Monitor"), this, SLOT(slotHide()));
+ rightPopup->insertItem(SmallIcon("exit"), KStdGuiItem::quit().text(), this, SLOT(slotQuit()));
+}
+
+laptop_dock::~laptop_dock()
+{
+ delete instance;
+ if (brightness_widget)
+ delete brightness_widget;
+ if (throttle_popup)
+ delete throttle_popup;
+ if (performance_popup)
+ delete performance_popup;
+}
+
+void
+laptop_dock::activate_throttle(int ind)
+{
+ pdaemon->SetThrottle(throttle_popup->text(ind));
+}
+
+void
+laptop_dock::fill_throttle()
+{
+ throttle_popup->clear();
+ int current;
+ QStringList list;
+ bool *active_list;
+ bool has_throttle = laptop_portable::get_system_throttling(1, current, list, active_list);
+ if (!has_throttle && !list.empty())
+ return;
+ int n=0;
+ for (QValueListIterator<QString> i = list.begin();i != list.end();i++) {
+ throttle_popup->insertItem(*i, n);
+ throttle_popup->setItemEnabled(n, active_list[n]);
+ n++;
+ }
+ throttle_popup->setItemChecked(current, 1);
+}
+
+void
+laptop_dock::activate_performance(int ind)
+{
+ pdaemon->SetPerformance(performance_popup->text(ind));
+}
+
+void
+laptop_dock::fill_performance()
+{
+ performance_popup->clear();
+ int current;
+ QStringList list;
+ bool *active_list;
+ bool has_performance = laptop_portable::get_system_performance(1, current, list, active_list);
+ if (!has_performance && !list.empty())
+ return;
+ int n=0;
+ for (QValueListIterator<QString> i = list.begin();i != list.end();i++) {
+ performance_popup->insertItem(*i, n);
+ performance_popup->setItemEnabled(n, active_list[n]);
+ n++;
+ }
+ performance_popup->setItemChecked(current, 1);
+}
+
+void
+laptop_dock::invokeBrightnessSlider(int v)
+{
+ v=255-v;
+ pdaemon->SetBrightness(0, v);
+ brightness = v;
+}
+
+void
+laptop_dock::invokeBrightness()
+{
+ brightness = pdaemon->GetBrightness();
+
+ if (brightness < 0)
+ brightness = 255;
+
+ if (brightness_widget == 0) {
+ brightness_widget = new QVBox(0L, "Brightness", WStyle_Customize | WType_Popup);
+ brightness_widget->setFrameStyle(QFrame::PopupPanel);
+ brightness_widget->setMargin(KDialog::marginHint());
+ brightness_slider = new QSlider(0, 255, 16, 255-brightness, Qt::Vertical, brightness_widget, 0);
+ brightness_slider->setMinimumHeight(40);
+ brightness_slider->setMinimumWidth(15);
+ connect(brightness_slider, SIGNAL(valueChanged(int)), this, SLOT(invokeBrightnessSlider(int)));
+ brightness_widget->resize(brightness_widget->sizeHint());
+ } else {
+ brightness_slider->setValue(255-brightness);
+ }
+ if (!brightness_widget->isVisible()) {
+ QRect desktop = KGlobalSettings::desktopGeometry(this);
+ int sw = desktop.width();
+ int sh = desktop.height();
+ int sx = desktop.x();
+ int sy = desktop.y();
+ QPoint pos = QCursor::pos();
+ int x = pos.x();
+ int y = pos.y();
+ y -= brightness_widget->geometry().height();
+ int w = brightness_widget->width();
+ int h = brightness_widget->height();
+ if (x+w > sw)
+ x = pos.x()-w;
+ if (y+h > sh)
+ y = pos.y()-h;
+ if (x < sx)
+ x = pos.x();
+ if (y < sy)
+ y = pos.y();
+ brightness_widget->move(x, y);
+ brightness_widget->show();
+ }
+}
+
+void laptop_dock::slotGoRoot(int /*id*/) {
+#ifdef NOTDEF
+ QString kdesu = KStandardDirs::findExe("kdesu");
+ if (!kdesu.isEmpty()) {
+ int rc = KMessageBox::warningContinueCancel(0,
+ i18n("You will need to supply a root password "
+ "to allow KLaptopDaemon to restart "
+ "itself as the superuser. It may take "
+ "up to a minute for the new daemon to "
+ "start up and the old one to close."),
+ i18n("KLaptopDaemon"), KStdGuiItem::cont(),
+ "switchToPCMCIAPrompt");
+ if (rc == KMessageBox::Continue) {
+ KProcess *_rootProcess;
+ _rootProcess = new KProcess;
+ *_rootProcess << kdesu;
+ *_rootProcess << "-u";
+ *_rootProcess << "root";
+ //*_rootProcess << "--nonewdcop";
+ *_rootProcess << KStandardDirs::findExe("klaptopdaemon");
+ connect(_rootProcess, SIGNAL(processExited(KProcess*)),
+ this, SLOT(rootExited(KProcess*)));
+ _rootProcess->start(KProcess::NotifyOnExit);
+ // We should disable this menu item here now.
+ }
+ } else {
+ KMessageBox::sorry(0, i18n("PCMCIA cannot be enabled since kdesu cannot be found. Please make sure that it is installed correctly."),
+ i18n("KLaptopDaemon"));
+ }
+#else
+ KMessageBox::sorry(0, i18n("PCMCIA cannot be enabled just now."),
+ i18n("KLaptopDaemon"));
+#endif
+}
+
+
+void laptop_dock::slotHide() {
+ int confirm = KMessageBox::questionYesNo(0, i18n("Are you sure you want to hide the battery monitor? Your battery will still be monitored in the background."), QString::null, i18n("Hide Monitor"), i18n("Do Not Hide"), "hideConfirm");
+
+ if (confirm != KMessageBox::Yes)
+ return;
+
+ // just tell ourselves to hide the battery
+ KConfig *config = new KConfig("kcmlaptoprc");
+ if (config) {
+ config->setGroup("BatteryDefault");
+ config->writeEntry("Enable", false);
+ config->sync();
+ delete config;
+ }
+ wake_laptop_daemon();
+}
+
+
+void laptop_dock::slotQuit() {
+ int confirm = KMessageBox::questionYesNo(0, i18n("Are you sure you want to quit the battery monitor?"), QString::null, KStdGuiItem::quit(), KStdGuiItem::cancel(), "quitConfirm");
+
+ if (confirm != KMessageBox::Yes)
+ return;
+
+ confirm = KMessageBox::questionYesNo(0, i18n("Do you wish to disable the battery monitor from starting in the future?"), QString::null, i18n("Disable"), i18n("Keep Enabled"), "restartMonitor");
+
+ if (confirm == KMessageBox::Yes) {
+ // just tell ourselves to hide the battery
+ KConfig *config = new KConfig("kcmlaptoprc");
+ if (config) {
+ config->setGroup("BatteryDefault");
+ config->writeEntry("Enable", false);
+ config->sync();
+ delete config;
+ }
+ }
+ pdaemon->quit();
+}
+
+
+void laptop_dock::rootExited(KProcess *p) {
+ if (p && p->isRunning()) {
+ p->detach();
+ }
+ exit(0);
+}
+
+
+void laptop_dock::slotEjectAction(int id) {
+KPCMCIACard *f = NULL;
+ f = _ejectActions[id];
+
+ if (f) f->eject();
+}
+
+
+void laptop_dock::slotSuspendAction(int id) {
+KPCMCIACard *f = NULL;
+ f = _suspendActions[id];
+
+ if (f) f->suspend();
+}
+
+
+void laptop_dock::slotResumeAction(int id) {
+KPCMCIACard *f = NULL;
+ f = _resumeActions[id];
+
+ if (f) f->resume();
+}
+
+
+void laptop_dock::slotResetAction(int id) {
+KPCMCIACard *f = NULL;
+ f = _resetActions[id];
+
+ if (f) f->reset();
+}
+
+
+void laptop_dock::slotInsertAction(int id) {
+KPCMCIACard *f = NULL;
+ f = _insertActions[id];
+
+ if (f) f->insert();
+}
+
+
+void laptop_dock::slotDisplayAction(int id) {
+KPCMCIAInfo *f = new KPCMCIAInfo(_pcmcia);
+ f->showTab(_displayActions[id]->num());
+}
+
+void laptop_dock::mousePressEvent( QMouseEvent *event )
+{
+ if(event->button() == LeftButton) {
+ QPopupMenu *popup = new QPopupMenu(0, "popup");
+
+ if (!pdaemon->exists()) {
+ popup->insertItem(i18n("Power Manager Not Found"));
+ } else {
+ QString tmp;
+
+ if (pdaemon->val >= 0) {
+ if (pdaemon->left >= 0) {
+ QString num3;
+ num3.setNum(pdaemon->left%60);
+ num3 = num3.rightJustify(2, '0');
+ tmp = i18n("%1:%2 hours left").arg(pdaemon->left/60).arg(num3);
+ } else {
+ // no remaining time available
+ tmp = i18n("%1% charged").arg(pdaemon->val);
+ }
+ } else {
+ tmp = i18n("No Battery");
+ }
+ popup->insertItem(tmp);
+ popup->setItemEnabled(0, 0);
+ popup->insertSeparator();
+ if (pdaemon->powered && pdaemon->val >= 0) {
+ popup->insertItem(i18n("Charging"));
+ } else {
+ popup->insertItem(i18n("Not Charging"));
+ }
+ popup->setItemEnabled(1, 0);
+ }
+
+ /**
+ * CPU Frequency scaling support
+ * - show the cpu profile and current frequency
+ */
+ if (laptop_portable::has_cpufreq()) {
+ QString speed = laptop_portable::cpu_frequency();
+ if (!speed.isEmpty()) {
+ popup->insertSeparator();
+ popup->insertItem(i18n("CPU: %1").arg(speed));
+ }
+ }
+
+ /**
+ * ADD the PCMCIA entries here
+ */
+ if (_pcmcia && _pcmcia->haveCardServices()) {
+ QString slotname = i18n("Slot %1"); // up here so we only construct it once
+ int id;
+ popup->insertSeparator();
+ _ejectActions.clear();
+ _resetActions.clear();
+ _insertActions.clear();
+ _suspendActions.clear();
+ _resumeActions.clear();
+ _displayActions.clear();
+ id = popup->insertItem(i18n("Card Slots..."), this, SLOT(slotDisplayAction(int)));
+ _displayActions.insert(id, _pcmcia->getCard(0));
+ for (int i = 0; i < _pcmcia->getCardCount(); i++) {
+ KPCMCIACard *thiscard;
+ thiscard = _pcmcia->getCard(i);
+ if (thiscard && (thiscard->present())) {
+ QPopupMenu *thisSub = new QPopupMenu(popup, thiscard->name().latin1());
+ id = thisSub->insertItem(i18n("Details..."), this, SLOT(slotDisplayAction(int)));
+ _displayActions.insert(id, thiscard);
+
+ // add the actions
+ QPopupMenu *actionsSub = new QPopupMenu(thisSub, "actions");
+ id = actionsSub->insertItem(i18n("Eject"), this, SLOT(slotEjectAction(int)));
+ actionsSub->setItemEnabled(id, !(thiscard->status() & CARD_STATUS_BUSY));
+ _ejectActions.insert(id, thiscard);
+ id = actionsSub->insertItem(i18n("Suspend"), this, SLOT(slotSuspendAction(int)));
+ actionsSub->setItemEnabled(id, !(thiscard->status() & (CARD_STATUS_SUSPEND|CARD_STATUS_BUSY)));
+ _suspendActions.insert(id, thiscard);
+ id = actionsSub->insertItem(i18n("Resume"), this, SLOT(slotResumeAction(int)));
+ actionsSub->setItemEnabled(id, (thiscard->status() & CARD_STATUS_SUSPEND));
+ _resumeActions.insert(id, thiscard);
+ id = actionsSub->insertItem(i18n("Reset"), this, SLOT(slotResetAction(int)));
+ _resetActions.insert(id, thiscard);
+ id = actionsSub->insertItem(i18n("Insert"), this, SLOT(slotInsertAction(int)));
+ _insertActions.insert(id, thiscard);
+ actionsSub->setItemEnabled(id, !(thiscard->status() & (CARD_STATUS_READY|CARD_STATUS_SUSPEND)));
+ thisSub->insertItem(i18n("Actions"), actionsSub);
+
+ // add a few bits of information
+ thisSub->insertSeparator();
+ thisSub->insertItem(slotname.arg(thiscard->num()+1));
+ if (thiscard->status() & CARD_STATUS_READY)
+ thisSub->insertItem(i18n("Ready"));
+ if (thiscard->status() & CARD_STATUS_BUSY)
+ thisSub->insertItem(i18n("Busy"));
+ if (thiscard->status() & CARD_STATUS_SUSPEND)
+ thisSub->insertItem(i18n("Suspended"));
+ popup->insertItem(thiscard->name(), thisSub);
+ }
+ }
+ } else if (_pcmcia && geteuid() != 0) {
+ popup->insertItem(i18n("Enable PCMCIA"));
+ }
+
+ popup->popup(QCursor::pos());
+ }
+
+}
+void laptop_dock::mouseReleaseEvent( QMouseEvent *e )
+{
+ if ( !rect().contains( e->pos() ) )
+ return;
+
+ switch ( e->button() ) {
+ case LeftButton:
+ break;
+ case MidButton:
+ // fall through
+ case RightButton:
+ {
+ KPopupMenu *menu = contextMenu();
+ contextMenuAboutToShow( menu );
+ menu->popup( e->globalPos() );
+ }
+ break;
+ default:
+ // nothing
+ break;
+ }
+}
+void laptop_dock::showEvent( QShowEvent * )
+{
+
+}
+void laptop_dock::invokeHibernation()
+{
+ laptop_portable::invoke_hibernation();
+}
+
+void laptop_dock::invokeLockHibernation()
+{
+ DCOPRef dr("kdesktop", "KScreensaverIface");
+ DCOPReply reply=dr.call("lock");
+
+ laptop_portable::invoke_hibernation();
+}
+void laptop_dock::invokeStandby()
+{
+ laptop_portable::invoke_standby();
+}
+
+void laptop_dock::invokeSuspend()
+{
+ laptop_portable::invoke_suspend();
+}
+
+void laptop_dock::invokeLockSuspend()
+{
+ DCOPClient* client = kapp->dcopClient();
+ if (client)
+ client->send("kdesktop", "KScreensaverIface", "lock()", "");
+ laptop_portable::invoke_suspend();
+}
+
+void laptop_dock::invokeSetup()
+{
+ KProcess proc;
+ proc << KStandardDirs::findExe("kcmshell");
+ proc << "laptop";
+ proc.start(KProcess::DontCare);
+ proc.detach();
+}
+
+void
+laptop_dock::reload_icon()
+{
+ // we will try to deduce the pixmap (or gif) name now. it will
+ // vary depending on the dock and power
+ QString pixmap_name;
+
+ if (!pdaemon->exists())
+ pixmap_name = pdaemon->noBatteryIcon();
+ else if (!pdaemon->powered)
+ pixmap_name = pdaemon->noChargeIcon();
+ else
+ pixmap_name = pdaemon->chargeIcon();
+
+ pm = loadIcon( pixmap_name, instance );
+}
+
+void laptop_dock::displayPixmap()
+{
+ int new_code;
+
+ if (!pdaemon->exists())
+ new_code = 1;
+ else if (!pdaemon->powered)
+ new_code = 2;
+ else
+ new_code = 3;
+
+ if (current_code != new_code) {
+ current_code = new_code;
+ reload_icon();
+ }
+
+ // at this point, we have the file to display. so display it
+
+ QImage image = pm.convertToImage();
+ const QBitmap *bmmask = pm.mask();
+ QImage mask;
+ if (bmmask)
+ mask = bmmask->convertToImage();
+
+ int w = image.width();
+ int h = image.height();
+ int count = 0;
+ QRgb rgb;
+ int x, y;
+ for (x = 0; x < w; x++)
+ for (y = 0; y < h; y++)
+ if (!bmmask || mask.pixelIndex(x, y) != 0){
+ rgb = image.pixel(x, y);
+ if (qRed(rgb) == 0xff &&
+ qGreen(rgb) == 0xff &&
+ qBlue(rgb) == 0xff)
+ count++;
+ }
+ int c = (count*pdaemon->val)/100;
+ if (pdaemon->val == 100) {
+ c = count;
+ } else
+ if (pdaemon->val != 100 && c == count)
+ c = count-1;
+
+
+ if (c) {
+ uint ui;
+ QRgb blue = qRgb(0x00,0x00,0xff);
+
+ if (image.depth() <= 8) {
+ ui = image.numColors(); // this fix thanks to Sven Krumpke
+ image.setNumColors(ui+1);
+ image.setColor(ui, blue);
+ } else {
+ ui = 0xff000000|blue;
+ }
+
+ for (y = h-1; y >= 0; y--)
+ for (x = 0; x < w; x++)
+ if (!bmmask || mask.pixelIndex(x, y) != 0){
+ rgb = image.pixel(x, y);
+ if (qRed(rgb) == 0xff &&
+ qGreen(rgb) == 0xff &&
+ qBlue(rgb) == 0xff) {
+ image.setPixel(x, y, ui);
+ c--;
+ if (c <= 0)
+ goto quit;
+ }
+ }
+ }
+quit:
+
+ QString tmp;
+ QString levelString;
+
+ if (!pdaemon->exists()) {
+ tmp = i18n("Laptop power management not available");
+ levelString = i18n("N/A");
+ } else
+ if (pdaemon->powered) {
+ if (pdaemon->val == 100) {
+ tmp = i18n("Plugged in - fully charged");;
+ levelString = "100%";
+ } else if (pdaemon->val >= 0) {
+ levelString.sprintf ("%i%%", pdaemon->val);
+ if (pdaemon->left >= 0) {
+ QString num3;
+ num3.setNum(pdaemon->left%60);
+ num3 = num3.rightJustify(2, '0');
+ tmp = i18n("Plugged in - %1% charged (%2:%3 hours left)")
+ .arg(pdaemon->val).arg(pdaemon->left/60).arg(num3);
+ } else {
+ // no remaining time available
+ tmp = i18n("Plugged in - %1% charged").arg(pdaemon->val);
+ }
+ } else {
+ tmp = i18n("Plugged in - no battery");
+ levelString = i18n("N/A");
+ }
+ } else {
+ if (pdaemon->val >= 0) {
+ levelString.sprintf ("%i%%", pdaemon->val);
+ if (pdaemon->left >= 0) {
+ QString num3;
+ num3.setNum(pdaemon->left%60);
+ num3 = num3.rightJustify(2, '0');
+ tmp = i18n("Running on batteries - %1% charged (%2:%3 hours left)")
+ .arg(pdaemon->val).arg(pdaemon->left/60).arg(num3);
+ } else {
+ tmp = i18n("Running on batteries - %1% charged").arg(pdaemon->val);
+ }
+ } else {
+ // running without any power source...
+ // happens eg. due to ACPI not being able to handle battery hot-plugin
+ tmp = i18n("No power source found");
+ levelString = i18n("N/A");
+ }
+ }
+
+
+ // prepare icon for systemtray
+
+ KConfig* config = new KConfig("kcmlaptoprc");
+ bool showlevel = false;
+
+ if (config)
+ {
+ config->setGroup("BatteryDefault");
+ showlevel= config->readBoolEntry("ShowLevel", false);
+ delete config;
+ }
+
+ if (showlevel)
+ {
+ // lot of code taken from kmail kmsystemtray class
+
+ int oldPixmapWidth = image.size().width();
+ int oldPixmapHeight = image.size().height();
+
+ QFont percentageFont = KGlobalSettings::generalFont();
+ percentageFont.setBold(true);
+
+ // decrease the size of the font for the number of unread messages if the
+ // number doesn't fit into the available space
+ float percentageFontSize = percentageFont.pointSizeFloat();
+ QFontMetrics qfm( percentageFont );
+ int width = qfm.width( levelString );
+ if( width > oldPixmapWidth )
+ {
+ percentageFontSize *= float( oldPixmapWidth ) / float( width );
+ percentageFont.setPointSizeFloat( percentageFontSize );
+ }
+
+ // Create an image which represents the number of unread messages
+ // and which has a transparent background.
+ // Unfortunately this required the following twisted code because for some
+ // reason text that is drawn on a transparent pixmap is invisible
+ // (apparently the alpha channel isn't changed when the text is drawn).
+ // Therefore I have to draw the text on a solid background and then remove
+ // the background by making it transparent with QPixmap::setMask. This
+ // involves the slow createHeuristicMask() function (from the API docs:
+ // "This function is slow because it involves transformation to a QImage,
+ // non-trivial computations and a transformation back to a QBitmap."). Then
+ // I have to convert the resulting QPixmap to a QImage in order to overlay
+ // the light KMail icon with the number (because KIconEffect::overlay only
+ // works with QImage). Finally the resulting QImage has to be converted
+ // back to a QPixmap.
+ // That's a lot of work for overlaying the KMail icon with the number of
+ // unread messages, but every other approach I tried failed miserably.
+ // IK, 2003-09-22
+ QPixmap percentagePixmap( oldPixmapWidth, oldPixmapHeight );
+ percentagePixmap.fill( Qt::white );
+ QPainter p( &percentagePixmap );
+ p.setFont( percentageFont );
+ p.setPen( Qt::black );
+ p.drawText( percentagePixmap.rect(), Qt::AlignCenter, levelString );
+ percentagePixmap.setMask( percentagePixmap.createHeuristicMask() );
+ QImage percentageImage = percentagePixmap.convertToImage();
+
+ // Overlay the light KMail icon with the number image
+ QImage iconWithPercentageImage = image.copy();
+ KIconEffect::overlay( iconWithPercentageImage, percentageImage );
+
+ QPixmap iconWithPercentage;
+ iconWithPercentage.convertFromImage( iconWithPercentageImage );
+
+ setPixmap( iconWithPercentage );
+ }
+ else
+ {
+ QPixmap q;
+ q.convertFromImage(image);
+ if (bmmask)
+ q.setMask(*bmmask);
+ setPixmap(q);
+ }
+ adjustSize();
+
+ QToolTip::add(this, tmp);
+}
+
+#include "daemondock.moc"
+
diff --git a/klaptopdaemon/daemondock.h b/klaptopdaemon/daemondock.h
new file mode 100644
index 0000000..7577ffd
--- /dev/null
+++ b/klaptopdaemon/daemondock.h
@@ -0,0 +1,108 @@
+#ifndef DAEMONDOCK
+#define DAEMONDOCK 1
+/*
+ * daemondock.h
+ * Copyright (C) 1999 Paul Campbell <paul@taniwha.com>
+ * Copyright (C) 2006 Flavio Castelli <flavio.castelli@gmail.com>
+ *
+ * This file contains the docked widget for the laptop battery monitor
+ *
+ * $Id$
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#include "laptop_daemon.h"
+#include <ksystemtray.h>
+
+class laptop_daemon;
+class KPCMCIA;
+class KPCMCIACard;
+class QPopupMenu;
+class QVBox;
+class QSlider;
+class KPopupMenu;
+
+#include <qmap.h>
+
+class laptop_dock : public KSystemTray {
+
+ Q_OBJECT
+
+public:
+ laptop_dock(laptop_daemon* parent);
+ ~laptop_dock();
+ void displayPixmap();
+
+ void mousePressEvent( QMouseEvent * );
+ void mouseReleaseEvent( QMouseEvent * );
+ void showEvent( QShowEvent * );
+ void reload_icon();
+
+ inline void setPCMCIA(KPCMCIA *p) { _pcmcia = p; }
+
+ void SetupPopup();
+
+private slots:
+ void invokeStandby();
+ void invokeSuspend();
+ void invokeLockSuspend();
+ void invokeHibernation();
+ void invokeLockHibernation();
+ void invokeSetup();
+ void invokeBrightness();
+ void invokeBrightnessSlider(int v);
+
+ void slotEjectAction(int id);
+ void slotResumeAction(int id);
+ void slotSuspendAction(int id);
+ void slotInsertAction(int id);
+ void slotResetAction(int id);
+ void slotDisplayAction(int id);
+
+ void activate_throttle(int ind);
+ void fill_throttle();
+ void activate_performance(int ind);
+ void fill_performance();
+
+
+ void rootExited(KProcess *p);
+ void slotGoRoot(int id);
+ void slotQuit();
+ void slotHide();
+
+private:
+ int brightness;
+ QVBox *brightness_widget;
+ QSlider *brightness_slider;
+ laptop_daemon *pdaemon;
+ QPixmap pm;
+ QPopupMenu *performance_popup, *throttle_popup;
+ int current_code;
+ KPCMCIA *_pcmcia;
+ QMap<int,KPCMCIACard *> _ejectActions,
+ _suspendActions,
+ _resumeActions,
+ _resetActions,
+ _displayActions,
+ _insertActions;
+
+ KInstance *instance; // handle so we get our pretty icons right
+ KPopupMenu *rightPopup;
+
+};
+#endif
+
diff --git a/klaptopdaemon/kpcmcia.cpp b/klaptopdaemon/kpcmcia.cpp
new file mode 100644
index 0000000..9dec605
--- /dev/null
+++ b/klaptopdaemon/kpcmcia.cpp
@@ -0,0 +1,547 @@
+/* This file is part of the KDE project
+ *
+ * Copyright (C) 2001 George Staikos <staikos@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/*
+ * Much of the linux code was migrated from:
+ * kardinfo Copyright 1999, Mirko Sucker <mirko.sucker@unibw-hamburg.de>
+ */
+
+#include <qtimer.h>
+#include <qfile.h>
+#include <qregexp.h>
+
+#include <klocale.h>
+#include <kinstance.h>
+#include <kstandarddirs.h>
+
+
+#include "kpcmcia.h"
+
+
+#ifdef __linux__
+ extern "C" {
+ #include <sys/types.h>
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include <sys/stat.h>
+ #include <sys/ioctl.h>
+ #include <sys/file.h>
+ #include <sys/time.h>
+ #include "linux/version.h"
+ #include "linux/cs_types.h"
+ #include "linux/cs.h"
+ #include "linux/cistpl.h"
+ #include "linux/ds.h"
+ }
+
+// Taken from cardinfo.c
+typedef struct event_tag_t {
+ event_t event;
+ const char *name;
+} event_tag_t;
+
+
+static event_tag_t event_tag[] = {
+ { CS_EVENT_CARD_INSERTION, "card insertion" },
+ { CS_EVENT_CARD_REMOVAL, "card removal" },
+ { CS_EVENT_RESET_PHYSICAL, "prepare for reset" },
+ { CS_EVENT_CARD_RESET, "card reset successful" },
+ { CS_EVENT_RESET_COMPLETE, "reset request complete" },
+ { CS_EVENT_EJECTION_REQUEST, "user eject request" },
+ { CS_EVENT_INSERTION_REQUEST, "user insert request" },
+ { CS_EVENT_PM_SUSPEND, "suspend card" },
+ { CS_EVENT_PM_RESUME, "resume card" },
+ { CS_EVENT_REQUEST_ATTENTION, "request attention" }
+};
+
+#define NTAGS (sizeof(event_tag)/sizeof(event_tag_t))
+
+static int lookupDevice(const char *x);
+static int openDevice(dev_t dev);
+
+#else
+#include <unistd.h>
+#endif
+
+
+
+KPCMCIACard::KPCMCIACard() {
+ _fd = -1;
+ _num = 9999999;
+ _status = 0;
+ _last = 0;
+ _interrupt = -1;
+ _ports = "";
+ _device = "";
+ _module = "";
+ _type = "";
+ _iotype = 0;
+ _cardname = i18n("Empty slot.");
+ _vcc = _vpp = _vpp2 = 0;
+ _inttype = 0;
+ _cfgbase = 0;
+}
+
+
+KPCMCIACard::~KPCMCIACard() {
+ if (_fd != -1) close(_fd);
+}
+
+
+
+// RETURN: <0 => error
+// =0 => no error, no update
+// >0 => no error, update happened
+//
+int KPCMCIACard::refresh() {
+//////////////////////////////////////////////
+///////////// LINUX ONLY
+///////////////////////////////////////////////
+#ifdef __linux__
+struct timeval tv;
+cs_status_t status;
+fd_set rfds;
+int rc;
+event_t event;
+struct stat sb;
+config_info_t cfg;
+KPCMCIACard oldValues(*this);
+int updated = 0;
+oldValues._fd = -1;
+
+#define CHECK_CHANGED(x, y) do { if (x.y != y) updated = 1; } while(0)
+
+ /**
+ * Get any events on the pcmcia device
+ */
+tv.tv_sec = 0; tv.tv_usec = 0;
+ FD_ZERO(&rfds);
+ FD_SET(_fd, &rfds);
+ rc = select(_fd+1, &rfds, NULL, NULL, &tv);
+ if (rc > 0) {
+ rc = read(_fd, (void *)&event, 4);
+ if (rc == 4) {
+ int thisEvent = -1; // thisEvent is the index of event in event_tag
+ for (unsigned int j = 0; j < NTAGS; j++) {
+ if (event_tag[j].event == event) {
+ thisEvent = j;
+ break;
+ }
+ if (thisEvent < 0) return -1;
+ }
+ } else {
+ return -1;
+ }
+ } else return updated;
+
+ if (event == CS_EVENT_EJECTION_REQUEST) {
+ _interrupt = -1;
+ _ports = "";
+ _device = "";
+ _module = "";
+ _type = "";
+ _iotype = 0;
+ _inttype = 0;
+ _cfgbase = 0;
+ _cardname = i18n("Empty slot.");
+ _vcc = _vpp = _vpp2 = 0;
+ return updated;
+ }
+
+ /**
+ * Read in the stab file.
+ */
+ if (!stat(_stabPath.latin1(), &sb) && sb.st_mtime >= _last) {
+ QFile f(_stabPath.latin1());
+
+ if (f.open(IO_ReadOnly)) {
+ QTextStream ts(&f);
+ bool foundit = false;
+ QString _thisreg = "^Socket %1: ";
+ QRegExp thisreg ( _thisreg.arg(_num) );
+
+ if (flock(f.handle(), LOCK_SH)) return updated;
+
+ _last = sb.st_mtime;
+
+ // find the card
+ while(!foundit) {
+ QString s;
+ if (ts.eof()) break;
+ s = ts.readLine();
+ if (s.contains(thisreg)) {
+ _cardname = s.right(s.length() - s.find(':') - 1);
+ _cardname = _cardname.stripWhiteSpace();
+ foundit = true;
+ CHECK_CHANGED(oldValues, _cardname);
+ }
+ }
+
+ // read it in
+ if (foundit && !ts.eof()) { // FIXME: ts.eof() is a bad error!!
+ QString s = ts.readLine();
+ int end;
+ s.simplifyWhiteSpace();
+
+ end = s.find(QRegExp("[ \r\t\n]"));
+ s = s.remove(0, end+1);
+
+ end = s.find(QRegExp("[ \r\t\n]"));
+ _type = s;
+ _type.truncate(end);
+ s = s.remove(0, end+1);
+
+ end = s.find(QRegExp("[ \r\t\n]"));
+ _module = s;
+ _module.truncate(end);
+ s = s.remove(0, end+1);
+
+ end = s.find(QRegExp("[ \r\t\n]"));
+ s = s.remove(0, end+1);
+
+ end = s.find(QRegExp("[ \r\t\n]"));
+ _device = s;
+ _device.truncate(end);
+ s = s.remove(0, end+1);
+ CHECK_CHANGED(oldValues, _type);
+ CHECK_CHANGED(oldValues, _module);
+ CHECK_CHANGED(oldValues, _device);
+ }
+
+ flock(f.handle(), LOCK_UN);
+ f.close();
+ } else return -1;
+ } else return updated;
+
+
+ /**
+ * Get the card's status and configuration information
+ */
+ status.Function = 0;
+ ioctl(_fd, DS_GET_STATUS, &status);
+ memset(&cfg, 0, sizeof(cfg));
+ ioctl(_fd, DS_GET_CONFIGURATION_INFO, &cfg);
+ // status is looked up in the table at the top
+ if (cfg.Attributes & CONF_VALID_CLIENT) {
+ if (cfg.AssignedIRQ == 0)
+ _interrupt = -1;
+ else _interrupt = cfg.AssignedIRQ;
+
+ if (cfg.NumPorts1 > 0) {
+ int stop = cfg.BasePort1 + cfg.NumPorts1;
+ if (cfg.NumPorts2 > 0) {
+ if (stop == cfg.BasePort2) {
+ _ports.sprintf("%#x-%#x", cfg.BasePort1, stop+cfg.NumPorts2-1);
+ } else {
+ _ports.sprintf("%#x-%#x, %#x-%#x", cfg.BasePort1, stop-1,
+ cfg.BasePort2, cfg.BasePort2+cfg.NumPorts2-1);
+ }
+ } else {
+ _ports.sprintf("%#x-%#x", cfg.BasePort1, stop-1);
+ }
+ }
+ CHECK_CHANGED(oldValues, _ports);
+ CHECK_CHANGED(oldValues, _interrupt);
+ }
+
+ _vcc = cfg.Vcc;
+ _vpp = cfg.Vpp1;
+ _vpp2 = cfg.Vpp2;
+ CHECK_CHANGED(oldValues, _vcc);
+ CHECK_CHANGED(oldValues, _vpp);
+ CHECK_CHANGED(oldValues, _vpp2);
+ _inttype = cfg.IntType;
+ CHECK_CHANGED(oldValues, _inttype);
+ _iotype = cfg.IOAddrLines;
+ CHECK_CHANGED(oldValues, _iotype);
+ _cfgbase = cfg.ConfigBase;
+ CHECK_CHANGED(oldValues, _cfgbase);
+
+ if (status.CardState & CS_EVENT_CARD_DETECT)
+ _status |= CARD_STATUS_PRESENT;
+ if (status.CardState & CS_EVENT_CARD_REMOVAL)
+ _status &= ~CARD_STATUS_PRESENT;
+ if (event & CS_EVENT_CARD_REMOVAL)
+ _status &= ~CARD_STATUS_PRESENT;
+
+ if (!(status.CardState & CS_EVENT_PM_SUSPEND)) {
+ if (status.CardState & CS_EVENT_READY_CHANGE) {
+ _status |= CARD_STATUS_READY;
+ _status &= ~(CARD_STATUS_BUSY|CARD_STATUS_SUSPEND);
+ } else {
+ _status |= CARD_STATUS_BUSY;
+ _status &= ~(CARD_STATUS_READY|CARD_STATUS_SUSPEND);
+ }
+ } else if (status.CardState & CS_EVENT_PM_SUSPEND) {
+ _status |= CARD_STATUS_SUSPEND;
+ _status &= ~(CARD_STATUS_READY|CARD_STATUS_BUSY);
+ }
+
+ CHECK_CHANGED(oldValues, _status);
+
+return updated;
+#else
+return 0;
+#endif
+}
+
+
+int KPCMCIACard::insert() {
+#ifdef __linux__
+ ioctl(_fd, DS_INSERT_CARD);
+ return 0;
+#else
+ return -1;
+#endif
+}
+
+
+
+int KPCMCIACard::eject() {
+#ifdef __linux__
+ ioctl(_fd, DS_EJECT_CARD);
+ return 0;
+#else
+ return -1;
+#endif
+}
+
+
+
+int KPCMCIACard::reset() {
+#ifdef __linux__
+ ioctl(_fd, DS_RESET_CARD);
+ return 0;
+#else
+ return -1;
+#endif
+}
+
+
+
+int KPCMCIACard::suspend() {
+#ifdef __linux__
+ ioctl(_fd, DS_SUSPEND_CARD);
+ return 0;
+#else
+ return -1;
+#endif
+}
+
+
+
+int KPCMCIACard::resume() {
+#ifdef __linux__
+ ioctl(_fd, DS_RESUME_CARD);
+ return 0;
+#else
+ return -1;
+#endif
+}
+
+
+
+
+
+KPCMCIA::KPCMCIA(int maxSlots, const char *stabpath) : _maxSlots(maxSlots),
+ _stabPath(stabpath) {
+
+_refreshSpeed = 750;
+
+_haveCardServices = false;
+_timer = new QTimer(this);
+connect(_timer, SIGNAL(timeout()), this, SLOT(updateCardInfo()));
+_cards = new QMemArray<KPCMCIACard *>(_maxSlots+1);
+_cardCnt = 0;
+
+
+///////////////////////////////////////////////////
+// LINUX code
+///////////////////////////////////////////////////
+#ifdef __linux__
+servinfo_t serv;
+
+ int device = lookupDevice("pcmcia");
+
+ if (device >= 0) {
+ for (int z = 0; z < _maxSlots; z++) {
+ int fd = openDevice((device << 8) + z);
+ if (fd < 0) break;
+ (*_cards)[_cardCnt] = new KPCMCIACard;
+ (*_cards)[_cardCnt]->_stabPath = _stabPath;
+ (*_cards)[_cardCnt]->_fd = fd;
+ (*_cards)[_cardCnt]->_num = _cardCnt;
+ //(*_cards)[_cardCnt]->refresh();
+ _cardCnt++;
+ //kdDebug() << "Found a pcmcia slot" << endl;
+ }
+
+ if (_cardCnt > 0) {
+ if (ioctl((*_cards)[0]->_fd, DS_GET_CARD_SERVICES_INFO, &serv) == 0) {
+ // FIXME: what to do here?
+ }
+ _haveCardServices = true;
+ }
+ }
+
+
+
+_timer->start(_refreshSpeed, true);
+
+///////////////////////////////////////////////////
+// No supported platform.
+///////////////////////////////////////////////////
+#else
+
+#endif
+}
+
+
+
+
+
+
+
+
+KPCMCIA::~KPCMCIA() {
+///////////////////////////////////////////////////
+// LINUX code
+///////////////////////////////////////////////////
+#ifdef __linux__
+
+
+///////////////////////////////////////////////////
+// No supported platform.
+///////////////////////////////////////////////////
+#else
+
+#endif
+
+
+delete _timer;
+delete _cards;
+}
+
+
+
+
+
+
+
+KPCMCIACard* KPCMCIA::getCard(int num) {
+ if (num >= _cardCnt || num < 0) return NULL;
+ return (*_cards)[num];
+}
+
+
+
+
+void KPCMCIA::updateCardInfo() {
+ for (int i = 0; i < _cardCnt; i++) {
+ int rc = (*_cards)[i]->refresh();
+ /*
+ kdDebug() << "CARD UPDATED: " << i << endl
+ << " Name: " << (*_cards)[i]->_cardname << endl
+ << " Device: " << (*_cards)[i]->_device << endl
+ << " VCC: " << (*_cards)[i]->_vcc << endl
+ << " VPP: " << (*_cards)[i]->_vpp << endl
+ << " IRQ: " << (*_cards)[i]->_interrupt << endl
+ << " Ports: " << (*_cards)[i]->_ports << endl
+ << " Type: " << (*_cards)[i]->_type << endl
+ << " Module: " << (*_cards)[i]->_module << endl
+ << endl;
+ */
+ if (rc > 0) emit cardUpdated(i);
+ }
+_timer->start(_refreshSpeed, true);
+}
+
+
+
+void KPCMCIA::setRefreshSpeed(int msec) {
+ _refreshSpeed = msec;
+}
+
+
+int KPCMCIA::getCardCount() {
+ return _cardCnt;
+}
+
+
+bool KPCMCIA::haveCardServices() {
+ return _haveCardServices;
+}
+
+
+#include "kpcmcia.moc"
+
+
+
+#ifdef __linux__
+static int lookupDevice(const char *x) {
+QFile df("/proc/devices");
+QString thisreg;
+
+ thisreg = "^[0-9]+ %1$";
+ thisreg = thisreg.arg(x);
+
+ if (df.open(IO_ReadOnly)) {
+ QTextStream t(&df);
+ QString s;
+ while (!t.eof()) {
+ s = t.readLine();
+
+ if (s.contains(QRegExp(thisreg))) {
+ int n = (s.left(3).stripWhiteSpace()).toInt();
+ df.close();
+ return n;
+ }
+ }
+ df.close();
+ }
+return -1;
+}
+
+static int openDevice(dev_t dev) {
+QString tmp_path = locateLocal("tmp", KGlobal::instance()->instanceName());
+QString ext = "_socket%1";
+
+ tmp_path += ext.arg((int)dev);
+
+ int rc = mknod(tmp_path.latin1(), (S_IFCHR | S_IREAD), dev);
+ if (rc < 0) return -1;
+
+ int fd = open(tmp_path.latin1(), O_RDONLY);
+ if (fd < 0) {
+ unlink(tmp_path.latin1());
+ return -1;
+ }
+
+ if (unlink(tmp_path.latin1()) < 0) {
+ close(fd);
+ return -1;
+ }
+
+ return fd;
+}
+
+#endif
+
+
diff --git a/klaptopdaemon/kpcmcia.h b/klaptopdaemon/kpcmcia.h
new file mode 100644
index 0000000..c821926
--- /dev/null
+++ b/klaptopdaemon/kpcmcia.h
@@ -0,0 +1,214 @@
+/* This file is part of the KDE project
+ *
+ * Copyright (C) 2001 George Staikos <staikos@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef _KPCMCIA_H
+#define _KPCMCIA_H
+
+class QTimer;
+class KPCMCIA;
+
+#include <qmemarray.h>
+
+#include <sys/types.h>
+
+#define CARD_STATUS_PRESENT 1
+#define CARD_STATUS_READY 2
+#define CARD_STATUS_BUSY 4
+#define CARD_STATUS_SUSPEND 8
+#define CARD_STATUS_SUSPENDED 8
+
+
+class KPCMCIACard {
+friend class KPCMCIA;
+protected:
+ KPCMCIACard();
+ ~KPCMCIACard();
+
+ int _fd;
+
+ int _interrupt;
+ QString _device, _ports;
+ QString _module;
+ QString _cardname;
+ QString _type;
+ int _vcc, _vpp, _vpp2;
+ QString _stabPath;
+ int _iotype;
+ int _inttype;
+ int _cfgbase;
+
+ int _status;
+ int _num;
+
+ // Other fields for the future
+ // etc look in linux/cs.h for more info
+
+public:
+
+ /**
+ * Base address for configuration
+ */
+ inline int configBase() { return _cfgbase; }
+
+ /**
+ * Interrupt type
+ */
+ inline int intType() { return _inttype; }
+
+ /**
+ * 16/32 bit
+ */
+ inline int busWidth() { return _iotype; }
+
+ /**
+ * True if the card is present
+ */
+ inline bool present() { return _status & CARD_STATUS_PRESENT; }
+
+ /**
+ * Return the card status
+ */
+ inline int status() { return _status; }
+
+ /**
+ * Request to eject the card
+ */
+ int eject();
+
+ /**
+ * Request to resume from suspend
+ */
+ int resume();
+
+ /**
+ * Request to suspend
+ */
+ int suspend();
+
+ /**
+ * Request to reset the card
+ */
+ int reset();
+
+ /**
+ * Insert a card (mostly not needed?)
+ */
+ int insert();
+
+ /**
+ * Return the card number
+ */
+ inline int num() { return _num; }
+
+ /**
+ * Return the interrupt in use (or -1 if none)
+ */
+ inline int irq() { return _interrupt; }
+
+ /**
+ * Return the VCC status
+ */
+ inline int vcc() { return _vcc; }
+
+ /**
+ * Return the card programming power (1)
+ */
+ inline int vpp() { return _vpp; }
+
+ /**
+ * Return the card programming power (2)
+ */
+ inline int vpp2() { return _vpp2; }
+
+ /**
+ * Return the card name
+ */
+ inline QString& name() { return _cardname; }
+
+ /**
+ * Return the port range
+ */
+ inline QString& ports() { return _ports; }
+
+ /**
+ * Return the device name
+ */
+ inline QString& device() { return _device; }
+
+ /**
+ * Return the device type (ie network, modem, etc)
+ */
+ inline QString& type() { return _type; }
+
+ /**
+ * Return the driver (module) name
+ */
+ inline QString& driver() { return _module; }
+
+ /**
+ * Refresh the card information - return < 0 on error.
+ * (this is called automatically [by KPCMCIA] on a timer normally)
+ */
+ int refresh();
+
+private:
+ time_t _last;
+};
+
+
+
+
+class KPCMCIA : public QObject {
+Q_OBJECT
+public:
+
+ KPCMCIA(int maxSlots = 8, const char *stabPath = "/var/run/stab");
+ ~KPCMCIA();
+
+ void setRefreshSpeed(int msec);
+ int getCardCount();
+ KPCMCIACard *getCard(int num);
+
+ bool haveCardServices();
+
+signals:
+ void cardUpdated(int num);
+
+
+public slots:
+ void updateCardInfo();
+
+private:
+ int _refreshSpeed;
+ QTimer *_timer;
+ QMemArray<KPCMCIACard *> *_cards;
+ int _cardCnt;
+ bool _haveCardServices;
+ int _maxSlots;
+ QString _stabPath;
+
+};
+
+
+
+
+#endif
+
diff --git a/klaptopdaemon/kpcmciainfo.cpp b/klaptopdaemon/kpcmciainfo.cpp
new file mode 100644
index 0000000..82da914
--- /dev/null
+++ b/klaptopdaemon/kpcmciainfo.cpp
@@ -0,0 +1,313 @@
+
+/* This file is part of the KDE project
+ *
+ * Copyright (C) 2001 George Staikos <staikos@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+
+#include <qtabwidget.h>
+#include <qlayout.h>
+#include <qtimer.h>
+#include <kstatusbar.h>
+#include <klocale.h>
+#include <kpushbutton.h>
+#include <kstdguiitem.h>
+
+#include <kpushbutton.h>
+#include <kstdguiitem.h>
+#include "kpcmcia.h"
+
+#include "kpcmciainfo.h"
+
+
+KPCMCIAInfo::KPCMCIAInfo(KPCMCIA *pcmcia, QWidget *parent, const char *name)
+ : KDialog(parent, name, false), _pcmcia(pcmcia) {
+
+ setMinimumSize(300,400);
+
+ _mainGrid = new QGridLayout(this, 9, 5);
+
+ _mainTab = new QTabWidget(this);
+ _mainGrid->addMultiCellWidget(_mainTab, 0, 6, 0, 4);
+ _mainGrid->setRowStretch(0, 1);
+ _mainGrid->setRowStretch(1, 1);
+ _mainGrid->setRowStretch(2, 1);
+ _mainGrid->setRowStretch(3, 1);
+ _mainGrid->setRowStretch(4, 1);
+ _mainGrid->setRowStretch(5, 1);
+ _mainGrid->setRowStretch(6, 1);
+
+ setCaption(i18n("PCMCIA & CardBus Slots"));
+
+ prepareCards();
+
+ _mainTab->resize(KDialog::sizeHint());
+ resize(KDialog::sizeHint());
+
+ connect(_pcmcia, SIGNAL(cardUpdated(int)), this, SLOT(updateCard(int)));
+
+ _sb = new KStatusBar(this);
+ _sb->insertItem(i18n("Ready."), 0, 1, true);
+ _sb->resize(KDialog::sizeHint());
+ _mainGrid->addMultiCellWidget(_sb, 8, 8, 0, 4);
+ _mainGrid->setRowStretch(8, 0);
+
+ _updateButton = new QPushButton(i18n("&Update"), this);
+ _mainGrid->addWidget(_updateButton, 7, 3);
+ connect(_updateButton, SIGNAL(pressed()), this, SLOT(update()));
+ _closeButton = new KPushButton(KStdGuiItem::close(), this);
+ _mainGrid->addWidget(_closeButton, 7, 4);
+ connect(_closeButton, SIGNAL(pressed()), this, SLOT(slotClose()));
+ _mainGrid->setRowStretch(7, 0);
+
+ show();
+}
+
+
+
+KPCMCIAInfo::~KPCMCIAInfo() {
+
+}
+
+
+void KPCMCIAInfo::showTab(int num) {
+ _mainTab->showPage(_pages[num]);
+}
+
+
+void KPCMCIAInfo::slotResetStatus() {
+ _sb->changeItem(i18n("Ready."), 0);
+}
+
+
+void KPCMCIAInfo::statusNotice(const QString& text, int life) {
+ _sb->changeItem(text, 0);
+ if (life > 0)
+ QTimer::singleShot(life, this, SLOT(slotResetStatus()));
+}
+
+
+
+void KPCMCIAInfo::slotTabSetStatus(const QString& text) {
+ statusNotice(text);
+}
+
+
+void KPCMCIAInfo::slotClose() {
+ delete this;
+}
+
+
+void KPCMCIAInfo::update() {
+ emit updateNow();
+}
+
+
+void KPCMCIAInfo::updateCard(int num) {
+ _pages[num]->update();
+}
+
+
+void KPCMCIAInfo::prepareCards() {
+ if (!_pcmcia) {
+ // FIXME: display error
+ return;
+ }
+
+ for (int i = 0; i < _pcmcia->getCardCount(); i++) {
+ QString tabname = i18n("Card Slot %1");
+ KPCMCIAInfoPage *tp = new KPCMCIAInfoPage(_pcmcia->getCard(i), _mainTab);
+ connect(this, SIGNAL(updateNow()), tp, SLOT(update()));
+ connect(tp, SIGNAL(setStatusBar(const QString&)), this, SLOT(slotTabSetStatus(const QString&)));
+ tp->resize(_mainTab->sizeHint());
+ _mainTab->addTab(tp, tabname.arg(i+1));
+ _pages.insert(i, tp);
+ }
+}
+
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////
+
+
+KPCMCIAInfoPage::KPCMCIAInfoPage(KPCMCIACard *card, QWidget *parent, const char *name)
+ : QFrame(parent, name), _card(card) {
+ _mainGrid = new QGridLayout(this, 10, 10);
+ if (!_card) {
+ // display an error
+ } else {
+ _card_name = new QLabel(this);
+ _mainGrid->addMultiCellWidget(_card_name, 0, 0, 0, 5);
+ _card_type = new QLabel(this);
+ _mainGrid->addMultiCellWidget(_card_type, 0, 0, 6, 9);
+ _card_driver = new QLabel(this);
+ _mainGrid->addMultiCellWidget(_card_driver, 1, 1, 0, 4);
+ _card_irq = new QLabel(this);
+ _mainGrid->addMultiCellWidget(_card_irq, 2, 2, 0, 3);
+ _card_io = new QLabel(this);
+ _mainGrid->addMultiCellWidget(_card_io, 3, 3, 0, 6);
+ _card_dev = new QLabel(this);
+ _mainGrid->addMultiCellWidget(_card_dev, 4, 4, 0, 4);
+ _card_vcc = new QLabel(this);
+ _mainGrid->addMultiCellWidget(_card_vcc, 5, 5, 0, 2);
+ _card_vpp = new QLabel(this);
+ _mainGrid->addMultiCellWidget(_card_vpp, 5, 5, 5, 9);
+ _card_bus = new QLabel(this);
+ _mainGrid->addMultiCellWidget(_card_bus, 6, 6, 0, 4);
+ _card_cfgbase = new QLabel(this);
+ _mainGrid->addMultiCellWidget(_card_cfgbase, 6, 6, 5, 9);
+
+ _card_ej_ins = new QPushButton(i18n("&Eject"), this);
+ _card_sus_res = new QPushButton(i18n("&Suspend"), this);
+ _card_reset = new QPushButton(i18n("&Reset"), this);
+ _mainGrid->addWidget(_card_ej_ins, 9, 5);
+ _mainGrid->addWidget(_card_sus_res, 9, 6);
+ _mainGrid->addWidget(_card_reset, 9, 7);
+ connect(_card_reset, SIGNAL(pressed()), this, SLOT(slotResetCard()));
+ connect(_card_sus_res, SIGNAL(pressed()), this, SLOT(slotSuspendResume()));
+ connect(_card_ej_ins, SIGNAL(pressed()), this, SLOT(slotInsertEject()));
+
+ update();
+ }
+}
+
+
+KPCMCIAInfoPage::~KPCMCIAInfoPage() {
+
+}
+
+
+
+void KPCMCIAInfoPage::slotResetCard() {
+ emit setStatusBar(i18n("Resetting card..."));
+ _card->reset();
+}
+
+
+void KPCMCIAInfoPage::slotInsertEject() {
+ if (!(_card->status() & (CARD_STATUS_READY|CARD_STATUS_SUSPEND))) {
+ emit setStatusBar(i18n("Inserting new card..."));
+ _card->insert();
+ _card->reset();
+ } else {
+ emit setStatusBar(i18n("Ejecting card..."));
+ if (_card->status() & CARD_STATUS_SUSPEND)
+ _card->resume();
+ _card->eject();
+ }
+}
+
+
+void KPCMCIAInfoPage::slotSuspendResume() {
+ if (!(_card->status() & CARD_STATUS_BUSY))
+ if (!(_card->status() & CARD_STATUS_SUSPEND)) {
+ emit setStatusBar(i18n("Suspending card..."));
+ _card->suspend();
+ } else {
+ emit setStatusBar(i18n("Resuming card..."));
+ _card->resume();
+ }
+}
+
+
+void KPCMCIAInfoPage::update() {
+ if (_card) {
+ QString tmp;
+ _card_name->setText(_card->name());
+ _card_name->resize(_card_name->sizeHint());
+ tmp = i18n("Card type: %1 ");
+ _card_type->setText(tmp.arg(_card->type()));
+ _card_type->resize(_card_type->sizeHint());
+ tmp = i18n("Driver: %1");
+ _card_driver->setText(tmp.arg(_card->driver()));
+ _card_driver->resize(_card_driver->sizeHint());
+ tmp = i18n("IRQ: %1%2");
+ QString tmp2;
+ switch (_card->intType()) {
+ case 1:
+ tmp2 = i18n(" (used for memory)");
+ break;
+ case 2:
+ tmp2 = i18n(" (used for memory and I/O)");
+ break;
+ case 4:
+ tmp2 = i18n(" (used for CardBus)");
+ break;
+ default:
+ tmp2 = "";
+ };
+ if (_card->irq() <= 0)
+ _card_irq->setText(tmp.arg(i18n("none")).arg(""));
+ else _card_irq->setText(tmp.arg(_card->irq()).arg(tmp2));
+ _card_irq->resize(_card_irq->sizeHint());
+ tmp = i18n("I/O port(s): %1");
+ if (_card->ports().isEmpty())
+ _card_io->setText(tmp.arg(i18n("none")));
+ else _card_io->setText(tmp.arg(_card->ports()));
+ _card_io->resize(_card_io->sizeHint());
+ tmp = i18n("Bus: %1 bit %2");
+ if (_card->busWidth() == 0)
+ _card_bus->setText(i18n("Bus: unknown"));
+ else _card_bus->setText(tmp.arg(_card->busWidth()).arg(_card->busWidth() == 16 ? i18n("PC Card") : i18n("Cardbus")));
+ _card_bus->resize(_card_bus->sizeHint());
+ tmp = i18n("Device: %1");
+ _card_dev->setText(tmp.arg(_card->device()));
+ _card_dev->resize(_card_dev->sizeHint());
+ tmp = i18n("Power: +%1V");
+ _card_vcc->setText(tmp.arg(_card->vcc()/10));
+ _card_vcc->resize(_card_vcc->sizeHint());
+ tmp = i18n("Programming power: +%1V, +%2V");
+ _card_vpp->setText(tmp.arg(_card->vpp()/10).arg(_card->vpp2()/10));
+ _card_vpp->resize(_card_vpp->sizeHint());
+ tmp = i18n("Configuration base: 0x%1");
+ if (_card->configBase() == 0)
+ _card_cfgbase->setText(i18n("Configuration base: none"));
+ else _card_cfgbase->setText(tmp.arg(_card->configBase(), -1, 16));
+ _card_cfgbase->resize(_card_cfgbase->sizeHint());
+
+ if (!(_card->status() & (CARD_STATUS_READY|CARD_STATUS_SUSPEND))) {
+ _card_ej_ins->setText(i18n("&Insert"));
+ } else {
+ _card_ej_ins->setText(i18n("&Eject"));
+ }
+ if (!(_card->status() & (CARD_STATUS_BUSY|CARD_STATUS_SUSPEND))) {
+ _card_sus_res->setText(i18n("&Suspend"));
+ } else {
+ _card_sus_res->setText(i18n("Resu&me"));
+ }
+ if (!(_card->status() & (CARD_STATUS_READY|CARD_STATUS_SUSPEND))) {
+ _card_sus_res->setEnabled(false);
+ _card_reset->setEnabled(false);
+ } else {
+ _card_sus_res->setEnabled(true);
+ if (!(_card->status() & CARD_STATUS_SUSPEND))
+ _card_reset->setEnabled(true);
+ else _card_reset->setEnabled(false);
+ }
+ }
+}
+
+
+
+
+#include "kpcmciainfo.moc"
+
diff --git a/klaptopdaemon/kpcmciainfo.h b/klaptopdaemon/kpcmciainfo.h
new file mode 100644
index 0000000..0cc7cea
--- /dev/null
+++ b/klaptopdaemon/kpcmciainfo.h
@@ -0,0 +1,116 @@
+
+/* This file is part of the KDE project
+ *
+ * Copyright (C) 2001 George Staikos <staikos@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef _KPCMCIAINFO_H
+#define _KPCMCIAINFO_H
+
+#include <kdialog.h>
+#include <qframe.h>
+
+class KPCMCIA;
+class KPCMCIACard;
+class KPCMCIAInfoPage;
+class QTabWidget;
+class KStatusBar;
+class QGridLayout;
+class QPushButton;
+class KPushButton;
+
+#include <qmap.h>
+
+class KPCMCIAInfo : public KDialog {
+Q_OBJECT
+public:
+
+ KPCMCIAInfo(KPCMCIA *pcmcia, QWidget *parent = NULL, const char *name = 0);
+ virtual ~KPCMCIAInfo();
+
+ void showTab(int num);
+ void statusNotice(const QString& text, int life = 1500);
+
+public slots:
+ void slotClose();
+ void update();
+ void updateCard(int num);
+ void slotResetStatus();
+ void slotTabSetStatus(const QString& text);
+
+signals:
+ void updateNow();
+
+private:
+ QFrame *_mainFrame;
+ QTabWidget *_mainTab;
+ QGridLayout *_mainGrid;
+ KPCMCIA *_pcmcia;
+ QMap<int,KPCMCIAInfoPage*> _pages;
+ KStatusBar *_sb;
+ KPushButton *_closeButton;
+ QPushButton *_updateButton;
+
+
+ void prepareCards();
+};
+
+
+class QLabel;
+
+
+class KPCMCIAInfoPage : public QFrame {
+Q_OBJECT
+public:
+ KPCMCIAInfoPage(KPCMCIACard *card, QWidget *parent = NULL, const char *name = 0);
+ virtual ~KPCMCIAInfoPage();
+
+public slots:
+ void update();
+ void slotResetCard();
+ void slotInsertEject();
+ void slotSuspendResume();
+
+signals:
+ void setStatusBar(const QString&);
+
+private:
+
+ KPCMCIACard *_card;
+ QGridLayout *_mainGrid;
+
+ QLabel *_card_name;
+ QLabel *_card_type;
+ QLabel *_card_irq;
+ QLabel *_card_io;
+ QLabel *_card_dev;
+ QLabel *_card_driver;
+ QLabel *_card_vcc;
+ QLabel *_card_vpp;
+ QLabel *_card_cfgbase;
+ QLabel *_card_bus;
+
+ QPushButton *_card_ej_ins;
+ QPushButton *_card_sus_res;
+ QPushButton *_card_reset;
+
+};
+
+#endif
+
diff --git a/klaptopdaemon/krichtextlabel.cpp b/klaptopdaemon/krichtextlabel.cpp
new file mode 100644
index 0000000..458ade6
--- /dev/null
+++ b/klaptopdaemon/krichtextlabel.cpp
@@ -0,0 +1,112 @@
+/* This file is part of the KDE libraries
+ Copyright (C) 2005 Waldo Bastian <bastian@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "krichtextlabel.h"
+
+#include <qtooltip.h>
+#include <qstylesheet.h>
+#include <qsimplerichtext.h>
+
+#include <kglobalsettings.h>
+
+static QString qrichtextify( const QString& text )
+{
+ if ( text.isEmpty() || text[0] == '<' )
+ return text;
+
+ QStringList lines = QStringList::split('\n', text);
+ for(QStringList::Iterator it = lines.begin(); it != lines.end(); ++it)
+ {
+ *it = QStyleSheet::convertFromPlainText( *it, QStyleSheetItem::WhiteSpaceNormal );
+ }
+
+ return lines.join(QString::null);
+}
+
+KRichTextLabel::KRichTextLabel( const QString &text , QWidget *parent, const char *name )
+ : QLabel ( parent, name ) {
+ m_defaultWidth = QMIN(400, KGlobalSettings::desktopGeometry(this).width()*2/5);
+ setAlignment( Qt::WordBreak );
+ setText(text);
+}
+
+KRichTextLabel::KRichTextLabel( QWidget *parent, const char *name )
+ : QLabel ( parent, name ) {
+ m_defaultWidth = QMIN(400, KGlobalSettings::desktopGeometry(this).width()*2/5);
+ setAlignment( Qt::WordBreak );
+}
+
+void KRichTextLabel::setDefaultWidth(int defaultWidth)
+{
+ m_defaultWidth = defaultWidth;
+ updateGeometry();
+}
+
+QSizePolicy KRichTextLabel::sizePolicy() const
+{
+ return QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum, false);
+}
+
+QSize KRichTextLabel::minimumSizeHint() const
+{
+ QString qt_text = qrichtextify( text() );
+ int pref_width = 0;
+ int pref_height = 0;
+ QSimpleRichText rt(qt_text, font());
+ pref_width = m_defaultWidth;
+ rt.setWidth(pref_width);
+ int used_width = rt.widthUsed();
+ if (used_width <= pref_width)
+ {
+ while(true)
+ {
+ int new_width = (used_width * 9) / 10;
+ rt.setWidth(new_width);
+ int new_height = rt.height();
+ if (new_height > pref_height)
+ break;
+ used_width = rt.widthUsed();
+ if (used_width > new_width)
+ break;
+ }
+ pref_width = used_width;
+ }
+ else
+ {
+ if (used_width > (pref_width *2))
+ pref_width = pref_width *2;
+ else
+ pref_width = used_width;
+ }
+
+ return QSize(pref_width, rt.height());
+}
+
+QSize KRichTextLabel::sizeHint() const
+{
+ return minimumSizeHint();
+}
+
+void KRichTextLabel::setText( const QString &text ) {
+ QLabel::setText(text);
+}
+
+void KRichTextLabel::virtual_hook( int, void* )
+{ /*BASE::virtual_hook( id, data );*/ }
+
+#include "krichtextlabel.moc"
diff --git a/klaptopdaemon/krichtextlabel.h b/klaptopdaemon/krichtextlabel.h
new file mode 100644
index 0000000..e03fe25
--- /dev/null
+++ b/klaptopdaemon/krichtextlabel.h
@@ -0,0 +1,65 @@
+/* This file is part of the KDE libraries
+ Copyright (C) 2005 Waldo Bastian <bastian@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KRICHTEXTLABEL_H
+#define KRICHTEXTLABEL_H
+
+#include <qlabel.h>
+
+#include <kdelibs_export.h>
+
+/**
+ * @short A replacement for QLabel that supports richtext and proper layout management
+ *
+ * @author Waldo Bastian <bastian@kde.org>
+ */
+
+/*
+ * QLabel
+ */
+class KDEUI_EXPORT KRichTextLabel : public QLabel {
+ Q_OBJECT
+
+public:
+ /**
+ * Default constructor.
+ */
+ KRichTextLabel( QWidget *parent, const char *name = 0 );
+ KRichTextLabel( const QString &text, QWidget *parent, const char *name = 0 );
+
+ int defaultWidth() const { return m_defaultWidth; }
+ void setDefaultWidth(int defaultWidth);
+
+ virtual QSize minimumSizeHint() const;
+ virtual QSize sizeHint() const;
+ QSizePolicy sizePolicy() const;
+
+public slots:
+ void setText( const QString & );
+
+protected:
+ int m_defaultWidth;
+
+protected:
+ virtual void virtual_hook( int id, void* data );
+private:
+ class KRichTextLabelPrivate;
+ KRichTextLabelPrivate *d;
+};
+
+#endif // KRICHTEXTLABEL_H
diff --git a/klaptopdaemon/laptop_check.cpp b/klaptopdaemon/laptop_check.cpp
new file mode 100644
index 0000000..7ba7b40
--- /dev/null
+++ b/klaptopdaemon/laptop_check.cpp
@@ -0,0 +1,53 @@
+/*
+ * laptop_check.cpp
+ * Copyright (C) 2003 Paul Campbell <paul@taniwha.com>
+ *
+ * quick check application - runs from kcminit - makes the check
+ * to see if kded should be told to run the laptop daemon at
+ * book time
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#include "daemon_state.h"
+#include <stdlib.h>
+#include <kaboutdata.h>
+#include <kapplication.h>
+#include <kcmdlineargs.h>
+#include <klocale.h>
+static const char description[] =
+ I18N_NOOP("KDE laptop daemon starter");
+
+static const char version[] = "v0.0.1";
+
+extern void wake_laptop_daemon();
+
+int
+main(int argc, char **argv)
+{
+ KAboutData aboutData( "klaptop_check", I18N_NOOP("KLaptop"),
+ version, description, KAboutData::License_GPL,
+ "(c) 2003, Paul Campbell");
+ aboutData.addAuthor("Paul Campbell",0, "paul@taniwha.com");
+ KCmdLineArgs::init( argc, argv, &aboutData );
+
+ KApplication a;
+ daemon_state s;
+ s.load();
+ if (s.need_to_run())
+ wake_laptop_daemon();
+ return(0);
+}
diff --git a/klaptopdaemon/laptop_daemon.cpp b/klaptopdaemon/laptop_daemon.cpp
new file mode 100644
index 0000000..6b66a64
--- /dev/null
+++ b/klaptopdaemon/laptop_daemon.cpp
@@ -0,0 +1,1083 @@
+/*
+ * laptop_daemon.cpp
+ * Copyright (C) 1999 Paul Campbell <paul@taniwha.com>
+ *
+ * this replaces kcmlaptop - there are 2 parts - one is the panels that
+ * put the setup configuration in the "kcmlaptop" configm, the other
+ * is the laptop_daemon (this guy) who watches the battery state
+ * and does stuff as a result
+ *
+ * This file contains the implementation of the main laptop battery monitoring daemon
+ *
+ * $Id$
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <stdlib.h>
+#include <fcntl.h>
+
+#include <qtimer.h>
+
+#include <kconfig.h>
+#include <klocale.h>
+#include <kcmdlineargs.h>
+#include "laptop_daemon.h"
+#include "portable.h"
+#include <kaboutdata.h>
+#include <kaudioplayer.h>
+#include <kapplication.h>
+#include <sys/ioctl.h>
+#include <kmessagebox.h>
+#include <kpassivepopup.h>
+#include <dcopclient.h>
+#include <qsocketnotifier.h>
+#include <qcursor.h>
+
+#include <unistd.h>
+#include <sys/time.h>
+
+extern "C"
+{
+ KDE_EXPORT KDEDModule *create_klaptopdaemon(const QCString& name) {
+ return new laptop_daemon(name);
+ }
+}
+
+
+class XWidget: public QWidget {
+public:
+ XWidget(laptop_daemon *p):QWidget(0) { pd = p; }
+private:
+ bool x11Event(XEvent *event);
+ laptop_daemon *pd;
+};
+bool XWidget::x11Event(XEvent *event) { return pd->x11Event(event); }
+
+laptop_daemon::laptop_daemon(const QCString& obj): KDEDModule(obj)
+{
+ xwidget = new XWidget(this);
+ xwidget->hide();
+ kapp->installX11EventFilter(xwidget);
+
+ mLavEnabled = false;
+ backoffTimer = 0;
+ need_wait = 0;
+ saved_brightness = 0;
+ saved_throttle = 0;
+ saved_performance = 0;
+ wake_timer = 0;
+ button_bright_saved=0;
+ button_bright_val=0;
+ button_saved_performance = 0;
+ button_saved_throttle = 0;
+ power_button_off = 0;
+
+ if (laptop_portable::has_brightness()) {
+ brightness = laptop_portable::get_brightness();
+ } else {
+ brightness = 0;
+ }
+ buttonThread.sethandle(this);
+ triggered[0] = 0;
+ triggered[1] = 0;
+ timer = 0;
+ dock_widget = 0;
+ oldTimer = 0;
+ sony_fd = -1;
+ sony_notifier = 0;
+ knownFullyCharged = 0;
+ sony_disp = 0;
+ connect(this, SIGNAL(signal_checkBattery()), SLOT(checkBatteryNow()));
+
+ //hasAudio = (audioServer.serverStatus() == 0) ? true : false;
+
+ // FIXME: make these configurable. Some system definitely don't
+ // use /var/run/stab
+ if (!access("/var/run/stab", R_OK|F_OK))
+ _pcmcia = new KPCMCIA(8, "/var/run/stab");
+ else if (!access("/var/lib/pcmcia/stab", R_OK|F_OK))
+ _pcmcia = new KPCMCIA(8, "/var/lib/pcmcia/stab");
+ else _pcmcia = NULL;
+
+ if (_pcmcia)
+ connect(_pcmcia, SIGNAL(cardUpdated(int)), this, SLOT(updatePCMCIA(int)));
+ connect( &autoLock, SIGNAL(timeout()), this, SLOT(timerDone()) );
+
+}
+
+laptop_daemon::~laptop_daemon()
+{
+ delete xwidget;
+ delete _pcmcia;
+ delete dock_widget;
+ delete sony_notifier;
+ if (sony_disp)
+ XCloseDisplay(sony_disp);
+}
+
+void
+laptop_daemon::quit()
+{
+ deleteLater();
+}
+
+void laptop_daemon::restart()
+{
+ if (oldTimer > 0) {
+ killTimer(oldTimer);
+ oldTimer=0;
+ }
+ if (timer) {
+ autoLock.stop();
+ timer = 0;
+ }
+ s.load();
+ if (s.has_brightness) {
+ brightness = laptop_portable::get_brightness();
+ } else {
+ brightness = 0;
+ }
+
+ if (!s.need_to_run()) {
+ quit();
+ return;
+ }
+
+ if (sony_fd < 0)
+ sony_fd = ::open("/dev/sonypi", O_RDONLY|O_NONBLOCK);
+ if (s.sony_enablescrollbar||s.sony_middleemulation) {
+ if (sony_disp == 0 && sony_fd >= 0)
+ sony_disp = XOpenDisplay(NULL);
+ if (sony_fd < 0 || sony_disp == 0) {
+ s.sony_enablescrollbar = 0;
+ s.sony_middleemulation = 0;
+ }
+ }
+
+ // change the dock state if necessary
+
+ if (s.enabled) {
+ if (!dock_widget) {
+ dock_widget = new laptop_dock(this);
+ dock_widget->setPCMCIA(_pcmcia);
+ dock_widget->show();
+ }
+ dock_widget->reload_icon();
+ dock_widget->SetupPopup();
+ } else {
+ if (dock_widget) {
+ delete dock_widget;
+ dock_widget = 0;
+ }
+ }
+
+ if (s.enable_lid_button && (lid_state = laptop_portable::get_button(laptop_portable::LidButton))) {
+ if (s.button_lid_bright_enabled)
+ SetBrightness(0, s.button_lid_bright_val);
+ if (s.button_lid_performance_enabled)
+ SetPerformance(s.button_lid_performance_val);
+ if (s.button_lid_throttle_enabled)
+ SetThrottle(s.button_lid_throttle_val);
+ switch (s.button_lid) {
+ case 1: invokeStandby();
+ break;
+ case 2: invokeSuspend();
+ break;
+ case 3: invokeHibernate();
+ break;
+ case 4: invokeLogout();
+ break;
+ case 5: invokeShutdown();
+ break;
+ }
+ }
+ if (s.enable_power_button && (power_state = laptop_portable::get_button(laptop_portable::PowerButton))) {
+ if (s.button_power_bright_enabled)
+ SetBrightness(0, s.button_power_bright_val);
+ if (s.button_power_performance_enabled)
+ SetPerformance(s.button_power_performance_val);
+ if (s.button_power_throttle_enabled)
+ SetThrottle(s.button_power_throttle_val);
+ switch (s.button_power) {
+ case 1: invokeStandby();
+ break;
+ case 2: invokeSuspend();
+ break;
+ case 3: invokeHibernate();
+ break;
+ case 4: invokeLogout();
+ break;
+ case 5: invokeShutdown();
+ break;
+ }
+ }
+ if (s.button_power_bright_enabled || s.button_power_performance_enabled || s.button_power_throttle_enabled ||
+ s.button_lid_bright_enabled || s.button_lid_performance_enabled || s.button_lid_throttle_enabled ||
+ s.button_lid != 0 || s.button_power != 0) { // need a fast thread to poll every sec
+ if (!buttonThread.running()) {
+ buttonThread.start();
+ }
+ } else {
+ if (buttonThread.running()) {
+ buttonThread.quit();
+ buttonThread.done();
+ }
+ }
+
+
+ // Do setup
+ struct power_result p = laptop_portable::poll_battery_state();
+ powered = p.powered;
+
+ need_wait = 0;
+ saved_brightness = 0;
+ saved_throttle = 0;
+ saved_performance = 0;
+ if (s.power_action[0] || s.power_action[1] || s.power_brightness_enabled[0] || s.power_brightness_enabled[0] ||
+ s.power_performance_enabled[0] || s.power_performance_enabled[1] || s.power_throttle_enabled[0] || s.power_throttle_enabled[1]) {
+ power_time = s.power_wait[powered?0:1];
+ timer = 1;
+ setLoadAverage(s.lav_enabled[powered?0:1], s.lav_val[powered?0:1]);
+ autoLock.setTimeout(power_time);
+ autoLock.start();
+ } else {
+ timer = 0;
+ }
+
+
+ if (s.useBlankSaver) {
+ setBlankSaver(!p.powered);
+ }
+
+ start_monitor();
+
+ // brightness control
+
+ if (s.has_brightness) {
+ if (s.bright_pon && powered) {
+ SetBrightness(0, s.bright_son);
+ } else
+ if (s.bright_poff && !powered) {
+ SetBrightness(0, s.bright_soff);
+ }
+ }
+ if (s.has_performance) {
+ if (s.performance_pon && powered) {
+ SetPerformance(s.performance_val_on);
+ } else
+ if (s.performance_poff && !powered) {
+ SetPerformance(s.performance_val_off);
+ }
+ }
+ if (s.has_throttle) {
+ if (s.throttle_pon && powered) {
+ SetThrottle(s.throttle_val_on);
+ } else
+ if (s.throttle_poff && !powered) {
+ SetThrottle(s.throttle_val_off);
+ }
+ }
+
+ // sony support
+
+ if (s.sony_enablescrollbar||s.sony_middleemulation) {
+ if (sony_notifier == 0) {
+ sony_notifier = new QSocketNotifier( sony_fd, QSocketNotifier::Read, this );
+ if (sony_notifier)
+ QObject::connect( sony_notifier, SIGNAL(activated(int)),
+ this, SLOT(sonyDataReceived()) );
+ }
+ } else {
+ if (sony_notifier) {
+ delete sony_notifier;
+ sony_notifier = 0;
+ }
+ }
+}
+
+
+void laptop_daemon::setBlankSaver(bool blanked)
+{
+ QByteArray ba;
+ QDataStream ds(ba, IO_WriteOnly);
+ ds << bool(blanked);
+ // can't use kapp->dcopClient() because it breaks KUniqueApplication
+ DCOPClient c;
+ c.attach();
+ c.send("kdesktop", "KScreensaverIface", "setBlankOnly(bool)", ba);
+ c.detach();
+}
+
+
+void laptop_daemon::timerDone()
+{
+ if (mLavEnabled && laptop_portable::get_load_average() >= mLav) {
+ autoLock.postpone(); // will call timerDone() again later
+ return;
+ }
+ int action;
+
+ timer = 0;
+ autoLock.stop(); // stop - see the note below about backoff
+ if (powered) {
+ action = s.power_action[0];
+ } else {
+ action = s.power_action[1];
+ }
+ switch (action) {
+ case 1: invokeStandby();
+ break;
+ case 2: invokeSuspend();
+ break;
+ case 3: invokeHibernate();
+ break;
+ }
+ if ((powered?s.power_brightness_enabled[0]:s.power_brightness_enabled[1])) {
+ need_wait = 1;
+ if (!saved_brightness) {
+ saved_brightness = 1;
+ saved_brightness_val = brightness;
+ }
+ SetBrightness(1, powered?s.power_brightness[0]:s.power_brightness[1]);
+ }
+ if ((powered?s.power_performance_enabled[0]:s.power_performance_enabled[1])) {
+ need_wait = 1;
+ if (!saved_performance) {
+ QStringList profile_list;
+ int current_profile;
+ bool *active_list;
+ if (laptop_portable::get_system_performance(1, current_profile, profile_list, active_list)) {
+ saved_performance = 1;
+ saved_performance_val = profile_list[current_profile];
+ }
+ }
+ SetPerformance(powered?s.power_performance[0]:s.power_performance[1]);
+ }
+ if ((powered?s.power_throttle_enabled[0]:s.power_throttle_enabled[1])) {
+ need_wait = 1;
+ if (!saved_throttle) {
+ QStringList profile_list;
+ int current_profile;
+ bool *active_list;
+ if (laptop_portable::get_system_throttling(1, current_profile, profile_list, active_list)) {
+ saved_throttle = 1;
+ saved_throttle_val = profile_list[current_profile];
+ }
+ }
+ SetPerformance(powered?s.power_throttle[0]:s.power_throttle[1]);
+ }
+ //
+ // we must give ourself enough time to handle any necessary evil before we start looking again
+ // (many of the above things cause unexpected time discontinuities)
+ //
+ if (need_wait) {
+ wakepos.setX(QCursor::pos().x());
+ wakepos.setY(QCursor::pos().y());
+ if (!wake_timer) {
+ wake_timer = new QTimer(this);
+ connect(wake_timer, SIGNAL(timeout()), this, SLOT(WakeCheck()));
+ wake_timer->start(1*1000, 1);
+ }
+ } else {
+ if (!backoffTimer) {
+ backoffTimer = new QTimer(this);
+ connect(backoffTimer, SIGNAL(timeout()), this, SLOT(BackoffRestart()));
+ backoffTimer->start(60*1000, 1);
+ }
+ }
+}
+
+void
+laptop_daemon::BackoffRestart()
+{
+ delete backoffTimer;
+ backoffTimer = 0;
+ if (!timer) {
+ timer = 1;
+ autoLock.start();
+ }
+}
+
+void
+laptop_daemon::WakeCheck()
+{
+ if (!wake_timer)
+ return;
+ if (!need_wait) {
+ wake_timer->stop();
+ delete wake_timer;
+ wake_timer = 0;
+ return;
+ }
+ if (wakepos.x() != QCursor::pos().x() || wakepos.y() != QCursor::pos().y()) {
+ wake_timer->stop();
+ delete wake_timer;
+ wake_timer = 0;
+ WakeUpAuto();
+ }
+}
+
+void
+laptop_daemon::WakeUpAuto()
+{
+ if (!need_wait)
+ return;
+ need_wait = 0;
+ if (saved_brightness) {
+ SetBrightness(0, saved_brightness_val);
+ saved_brightness = 0;
+ }
+ if (saved_throttle) {
+ SetThrottle(saved_throttle_val);
+ saved_throttle = 0;
+ }
+ if (saved_performance) {
+ SetPerformance(saved_performance_val);
+ saved_performance = 0;
+ }
+ if (!timer) {
+ timer = 1;
+ autoLock.start();
+ }
+}
+
+bool
+laptop_daemon::x11Event(XEvent *event)
+{
+ switch (event->type) {
+ case KeyPress:
+ case ButtonPress:
+ if (need_wait)
+ WakeUpAuto();
+ break;
+
+ }
+ return(0);
+}
+
+void laptop_daemon::dock_quit()
+{
+ if (dock_widget)
+ delete dock_widget;
+ dock_widget = 0;
+}
+
+
+void laptop_daemon::updatePCMCIA(int num)
+{
+ Q_UNUSED(num);
+ //kdDebug() << "PCMCIA card " << num << " was updated." << endl;
+
+ // Two things we do here. We provide notifications for cards
+ // being inserted / cards going to sleep / cards waking up
+ // and cards being safe to eject.
+ // The second thing we do is provide the desktop icon actions
+ // via dcop.
+}
+
+
+void laptop_daemon::haveBatteryLow(int t, const int num, const int type)
+{
+ displayPixmap();
+
+ // beep if we are allowed to
+ if (s.systemBeep[t]) {
+ //KNotifyClient::beep();
+ (void)kapp->beep();
+ }
+
+ // run a command if we have to
+ if (s.runCommand[t]) {
+ // make sure the command exists
+ if (!s.runCommandPath[t].isEmpty()) {
+ KProcess command;
+ command << s.runCommandPath[t];
+ command.start(KProcess::DontCare);
+ }
+ }
+
+ if (s.do_brightness[t])
+ SetBrightness(0, s.val_brightness[t]);
+ if (s.do_throttle[t])
+ SetThrottle(s.val_throttle[t]);
+ if (s.do_performance[t])
+ SetPerformance(s.val_performance[t]);
+
+ // play a sound if we have to
+ if (s.playSound[t]) {
+ KAudioPlayer::play(s.playSoundPath[t]);
+ }
+
+
+ if (s.do_hibernate[t])
+ invokeHibernate();
+ if (s.do_suspend[t])
+ invokeSuspend();
+ if (s.do_standby[t])
+ invokeStandby();
+ if (s.logout[t])
+ invokeLogout();
+ if (s.shutdown[t])
+ invokeShutdown();
+ // notify if we must (must be last since it's synchronous)
+ if (s.notify[t]) {
+ if (type) {
+ if (s.time_based_action_critical) {
+ KPassivePopup::message(i18n("Battery power is running out."),
+ i18n("%1 % charge left.").arg(num),
+ BarIcon("laptop_battery"), dock_widget,
+ 0, 20000);
+ } else {
+ // Will this ever be reached?
+ KPassivePopup::message(i18n("Battery power is running out."),
+ i18n("%1 % charge left.").arg(num),
+ BarIcon("laptop_battery"), dock_widget,
+ 0, 20000);
+ }
+ }
+ else {
+ if (s.time_based_action_low) {
+ KPassivePopup::message(i18n("Battery power is running out."),
+ i18n("1 minute left.","%n minutes left.", num),
+ BarIcon("laptop_battery"), dock_widget,
+ 0, 20000);
+ } else {
+ KPassivePopup::message(i18n("Battery power is running out."),
+ i18n("1% left.", "%n percent left.", num),
+ BarIcon("laptop_battery"), dock_widget,
+ 0, 20000);
+ }
+ }
+ }
+}
+
+int laptop_daemon::calcBatteryTime(int percent, long time, bool restart)
+{
+#define MAX_SAMPLES_USED 3
+ static int percents[MAX_SAMPLES_USED];
+ static long times[MAX_SAMPLES_USED];
+ static int lastused=-1;
+ int r=-1;
+
+ if ( (lastused==-1) || restart )
+ {
+ percents[0]=percent;
+ times[0]=time;
+ lastused=0;
+ }
+ else
+ {
+ // Add the % and time to the arrays
+ // (or just update the time if the % hasn't changed)
+ if (percents[lastused]!=percent)
+ if (lastused!=MAX_SAMPLES_USED-1)
+ {
+ lastused++;
+ percents[lastused]=percent;
+ times[lastused]=time;
+ }
+ else
+ {
+ for (int i=1;i<MAX_SAMPLES_USED;i++)
+ { percents[i-1]=percents[i]; times[i-1]=times[i]; };
+ }
+ percents[lastused]=percent;
+ times[lastused]=time;
+
+ //Now let's do the real calculations
+
+ if (lastused==0) return -1;
+
+ // Copy the data to temporary variables
+ double tp[MAX_SAMPLES_USED];
+ double tt[MAX_SAMPLES_USED];
+
+ for (int i=0;i<=lastused;i++)
+ { tp[i]=percents[i]; tt[i]=times[i]; };
+
+ for (int c=lastused; c>1; c--)
+ {
+ for (int i=0; i<c-1; i++)
+ {
+ tp[i]=(tp[i]+tp[i+1])/2;
+ tt[i]=(tt[i]+tt[i+1])/2;
+ }
+ }
+
+ // Now we've reduced all the samples to an approximation with just a line
+
+ if (tp[1]-tp[0]!=0)
+ r=static_cast<int>(tt[0]-(tp[0]/(tp[1]-tp[0]))*(tt[1]-tt[0])-time);
+
+
+ }
+
+ return r;
+}
+
+void laptop_daemon::checkBatteryNow()
+{
+ struct power_result p;
+
+ p = laptop_portable::poll_battery_state();
+
+ if (s.useBlankSaver && oldpowered != p.powered) {
+ setBlankSaver(!p.powered);
+ }
+
+ powered = p.powered;
+ left = p.time;
+ val = p.percentage;
+
+ if (oldpowered != powered && s.has_brightness) {
+ if (s.bright_pon && powered) {
+ SetBrightness(0, s.bright_son);
+ } else
+ if (s.bright_poff && !powered) {
+ SetBrightness(0, s.bright_soff);
+ }
+ if (s.performance_pon && powered) {
+ SetPerformance(s.performance_val_on);
+ } else
+ if (s.performance_poff && !powered) {
+ SetPerformance(s.performance_val_off);
+ }
+ if (s.throttle_pon && powered) {
+ SetThrottle(s.throttle_val_on);
+ } else
+ if (s.throttle_poff && !powered) {
+ SetThrottle(s.throttle_val_off);
+ }
+
+ }
+
+ if (left==-1) // Let's try to calculate the expected battery time left
+ {
+ timeval tv;
+ gettimeofday(&tv, 0);
+ left=calcBatteryTime(((powered)?100-val:val), tv.tv_sec, oldpowered!=powered );
+ }
+
+ if (timer && oldpowered != powered) {
+ need_wait = 0;
+ saved_brightness = 0;
+ saved_throttle = 0;
+ saved_performance = 0;
+ setLoadAverage(s.lav_enabled[powered?0:1], s.lav_val[powered?0:1]);
+ if (power_time != s.power_wait[powered?0:1]) {
+ power_time = s.power_wait[powered?0:1];
+ autoLock.stop();
+ autoLock.setTimeout(power_time);
+ autoLock.start();
+ }
+ }
+ if (!knownFullyCharged) {
+ knownFullyCharged = 1;
+ } else
+ if (s.notifyMeWhenFull && oldval != val && val == 100)
+ KMessageBox::queuedMessageBox(0, KMessageBox::Information, i18n("Your battery is now fully charged."), i18n("Laptop Battery"));
+ changed = oldpowered != powered||oldexists != s.exists||oldval != val || oldleft!=left;
+ oldpowered = powered;
+ oldexists = s.exists;
+ oldval = val;
+ oldleft = left;
+ if (changed)
+ displayPixmap();
+}
+
+void laptop_daemon::start_monitor()
+{
+ checkBatteryNow();
+ displayPixmap();
+ oldTimer = startTimer(s.poll * 1000);
+}
+
+void laptop_daemon::setPollInterval(const int interval)
+{
+ s.poll = interval;
+
+ // Kill any old timers that may be running
+ if (oldTimer > 0) {
+ killTimer(oldTimer);
+
+ // Start a new timer will the specified time
+ oldTimer = startTimer(interval * 1000);
+
+ emit(signal_checkBattery());
+ }
+}
+
+void laptop_daemon::timerEvent(QTimerEvent *)
+{
+ emit(signal_checkBattery());
+}
+
+void laptop_daemon::displayPixmap()
+{
+ if (s.have_time == 2 && s.exists && !powered) { // in some circumstances
+ s.have_time = (val < 0 ? 0 : 1); // the battery is not charging
+ KConfig *config = new KConfig("kcmlaptoprc");
+ if (config) {
+ config->setGroup("BatteryLow"); // we can;t figure this out 'till
+ config->writeEntry("HaveTime", s.have_time);
+ config->sync();
+ delete config;
+ }
+ }
+
+ if (dock_widget)
+ dock_widget->displayPixmap();
+
+ if (left >= 0) {
+ if (!triggered[0]) {
+ if (s.time_based_action_low) {
+ if (s.exists && !powered && left <= s.low[0]) {
+ triggered[0] = 1;
+ haveBatteryLow(0, left, 0);
+ }
+ } else {
+ if (s.exists && !powered && val <= s.low[1]) {
+ triggered[0] = 1;
+ haveBatteryLow(0, val, 0);
+ }
+ }
+ }
+ if (!triggered[1]) {
+ if (s.time_based_action_critical) {
+ if (s.exists && !powered && left <= s.low[2]) {
+ triggered[1] = 1;
+ haveBatteryLow(1, left, 0);
+ }
+ } else {
+ if (s.exists && !powered && val <= s.low[3]) {
+ triggered[1] = 1;
+ haveBatteryLow(1, val, 0);
+ }
+ }
+ }
+ }
+
+ if (s.time_based_action_low || s.time_based_action_critical) {
+ if (left > (s.low[2]+1))
+ triggered[1] = 0;
+ if (left > s.low[0])
+ triggered[0] = 0;
+ } else {
+ if (val > (s.low[3]+1))
+ triggered[1] = 0;
+ if (val > s.low[1])
+ triggered[0] = 0;
+ }
+
+ if (s.have_time != 1) {
+ if (!triggered[0]) {
+ if (s.exists && !powered && val <= s.low[0]) {
+ triggered[0] = 1;
+ haveBatteryLow(0, val, 1);
+ }
+ } else {
+ if (!triggered[1]) {
+ if (s.exists && !powered && val <= s.low[1]) {
+ triggered[1] = 1;
+ haveBatteryLow(1, val, 1);
+ }
+ }
+ if (val > (s.low[1]+1))
+ triggered[1] = 0;
+ if (val > s.low[0])
+ triggered[0] = 0;
+ }
+ }
+}
+
+void laptop_daemon::invokeStandby()
+{
+ laptop_portable::invoke_standby();
+}
+
+void laptop_daemon::invokeSuspend()
+{
+ laptop_portable::invoke_suspend();
+}
+
+void laptop_daemon::invokeHibernate()
+{
+ laptop_portable::invoke_hibernation();
+}
+
+void laptop_daemon::invokeLogout()
+{
+ bool rc = kapp->requestShutDown(KApplication::ShutdownConfirmNo, KApplication::ShutdownTypeNone, KApplication::ShutdownModeForceNow);
+ if (!rc)
+ KMessageBox::sorry(0, i18n("Logout failed."));
+}
+
+void laptop_daemon::invokeShutdown()
+{
+ bool rc = kapp->requestShutDown(KApplication::ShutdownConfirmNo, KApplication::ShutdownTypeHalt, KApplication::ShutdownModeForceNow);
+ if (!rc)
+ KMessageBox::sorry(0, i18n("Shutdown failed."));
+}
+
+/*
+ * Portions of the following code borrowed with thanks from:
+ *
+ * Sony Programmable I/O Control Device driver for VAIO.
+ * Userspace X11 Daemon Utility
+ *
+ * Copyright 2001 Stelian Pop, Alcove
+ *
+ * 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, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+static void simulateButton(Display *disp, int button) {
+ XTestGrabControl(disp, True);
+ XTestFakeButtonEvent(disp, button, True, 0);
+ XTestFakeButtonEvent(disp, button, False, 0);
+ XSync(disp, False);
+ XTestGrabControl(disp, False);
+}
+
+static void simulateButtonDown(Display *disp, int button) {
+ XTestGrabControl(disp, True);
+ XTestFakeButtonEvent(disp, button, True, 0);
+ XSync(disp, False);
+ XTestGrabControl(disp, False);
+}
+
+static void simulateButtonUp(Display *disp, int button) {
+ XTestGrabControl(disp, True);
+ XTestFakeButtonEvent(disp, button, False, 0);
+ XSync(disp, False);
+ XTestGrabControl(disp, False);
+}
+
+#define SONYPI_EVENT_JOGDIAL_DOWN 1
+#define SONYPI_EVENT_JOGDIAL_UP 2
+#define SONYPI_EVENT_JOGDIAL_DOWN_PRESSED 3
+#define SONYPI_EVENT_JOGDIAL_UP_PRESSED 4
+#define SONYPI_EVENT_JOGDIAL_PRESSED 5
+#define SONYPI_EVENT_JOGDIAL_RELEASED 6
+
+void laptop_daemon::sonyDataReceived()
+{
+ unsigned char event;
+
+ if (::read(sony_fd, &event, sizeof(event)) != sizeof(event))
+ return;
+ switch(event) {
+ case SONYPI_EVENT_JOGDIAL_UP:
+ if (sony_disp && s.sony_enablescrollbar) {
+ simulateButton(sony_disp, 4);
+ }
+ break;
+ case SONYPI_EVENT_JOGDIAL_DOWN:
+ if (sony_disp && s.sony_enablescrollbar) {
+ simulateButton(sony_disp, 5);
+ }
+ break;
+ case SONYPI_EVENT_JOGDIAL_PRESSED:
+ if (sony_disp && s.sony_middleemulation) {
+ simulateButtonDown(sony_disp, 2);
+ }
+ break;
+ case SONYPI_EVENT_JOGDIAL_RELEASED:
+ if (sony_disp && s.sony_middleemulation) {
+ simulateButtonUp(sony_disp, 2);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void laptop_daemon::SetBrightness(bool blank, int v)
+{
+ if (v < 0)
+ return;
+ brightness = v;
+ laptop_portable::set_brightness(blank, v);
+}
+
+void laptop_daemon::SetThrottle(QString v)
+{
+ laptop_portable::set_system_throttling(v);
+}
+
+void laptop_daemon::SetPerformance(QString v)
+{
+ laptop_portable::set_system_performance(v);
+}
+
+void
+ButtonThread::run()
+{
+ while (!quitting) {
+ handle->ButtonThreadInternals();
+ msleep(500); // have to run fast because if the power button is held down for too long
+ } // the system actually gets powered off
+}
+
+void
+laptop_daemon::ButtonThreadInternals()
+{
+ //
+ // the lid button turns stuff on when it's down and back off again when it's raised
+ // (kind of like the fridge door light)
+ //
+ if (lid_state != laptop_portable::get_button(laptop_portable::LidButton)) {
+ lid_state = !lid_state;
+ if (lid_state) {
+ if (s.button_lid_bright_enabled) {
+ if (!button_bright_val)
+ button_bright_val = brightness;
+ button_bright_saved = 1;
+ SetBrightness(1, s.button_lid_bright_val);
+ }
+ if (s.button_lid_performance_enabled) {
+ if (!button_saved_performance) {
+ QStringList profile_list;
+ int current_profile;
+ bool *active_list;
+ if (laptop_portable::get_system_performance(1, current_profile, profile_list, active_list)) {
+ button_saved_performance = 1;
+ button_saved_performance_val = profile_list[current_profile];
+ }
+ }
+ SetPerformance(s.button_lid_performance_val);
+ }
+ if (s.button_lid_throttle_enabled) {
+ if (!button_saved_throttle) {
+ QStringList profile_list;
+ int current_profile;
+ bool *active_list;
+ if (laptop_portable::get_system_throttling(1, current_profile, profile_list, active_list)) {
+ button_saved_throttle = 1;
+ button_saved_throttle_val = profile_list[current_profile];
+ }
+ }
+ SetThrottle(s.button_lid_throttle_val);
+ }
+ switch (s.button_lid) {
+ case 1: invokeStandby();
+ break;
+ case 2: invokeSuspend();
+ break;
+ case 3: invokeHibernate();
+ break;
+ case 4: invokeLogout();
+ break;
+ case 5: invokeShutdown();
+ break;
+ }
+ } else {
+ if (button_bright_saved) {
+ SetBrightness(0, button_bright_val);
+ button_bright_saved = 0;
+ }
+ if (button_saved_performance) {
+ button_saved_performance = 0;
+ SetPerformance( button_saved_performance_val);
+ }
+ if (button_saved_throttle) {
+ button_saved_throttle = 0;
+ SetThrottle(button_saved_throttle_val);
+ }
+ }
+ }
+ //
+ // the power button on the other hand is an off/on switch for non-suspend type ops
+ //
+ if (power_state != laptop_portable::get_button(laptop_portable::PowerButton)) {
+ power_state = !power_state;
+ if (power_state) {
+ if (power_button_off) {
+ if (button_bright_saved) {
+ SetBrightness(0, button_bright_val);
+ button_bright_saved = 0;
+ }
+ if (button_saved_performance) {
+ button_saved_performance = 0;
+ SetPerformance( button_saved_performance_val);
+ }
+ if (button_saved_throttle) {
+ button_saved_throttle = 0;
+ SetThrottle(button_saved_throttle_val);
+ }
+ } else {
+ if (s.button_power_bright_enabled) {
+ if (!button_bright_val)
+ button_bright_val = brightness;
+ button_bright_saved = 1;
+ SetBrightness(1, s.button_power_bright_val);
+ }
+ if (s.button_power_performance_enabled) {
+ if (!button_saved_performance) {
+ QStringList profile_list;
+ int current_profile;
+ bool *active_list;
+ if (laptop_portable::get_system_performance(1, current_profile, profile_list, active_list)) {
+ button_saved_performance = 1;
+ button_saved_performance_val = profile_list[current_profile];
+ }
+ }
+ SetPerformance(s.button_power_performance_val);
+ }
+ if (s.button_power_throttle_enabled) {
+ if (!button_saved_throttle) {
+ QStringList profile_list;
+ int current_profile;
+ bool *active_list;
+ if (laptop_portable::get_system_throttling(1, current_profile, profile_list, active_list)) {
+ button_saved_throttle = 1;
+ button_saved_throttle_val = profile_list[current_profile];
+ }
+ }
+ SetThrottle(s.button_power_throttle_val);
+ }
+ }
+ switch (s.button_power) {
+ case 1: invokeStandby();
+ break;
+ case 2: invokeSuspend();
+ break;
+ case 3: invokeHibernate();
+ break;
+ case 4: invokeLogout();
+ break;
+ case 5: invokeShutdown();
+ break;
+ }
+ power_button_off = !power_button_off;
+ }
+ }
+}
+
+#include "laptop_daemon.moc"
diff --git a/klaptopdaemon/laptop_daemon.h b/klaptopdaemon/laptop_daemon.h
new file mode 100644
index 0000000..b1537e1
--- /dev/null
+++ b/klaptopdaemon/laptop_daemon.h
@@ -0,0 +1,186 @@
+#ifndef LAPTOPDAEMON
+#define LAPTOPDAEMON 1
+/*
+ * laptop_daemon.h
+ * Copyright (C) 1999 Paul Campbell <paul@taniwha.com>
+ *
+ * This file contains the implementation of the main laptop battery monitoring daemon
+ *
+ * $Id$
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "daemon_state.h"
+
+#include <qdir.h>
+#include <unistd.h>
+#include <time.h>
+#include <qmovie.h>
+#include <qptrlist.h>
+#include <qfileinfo.h>
+#include <qimage.h>
+
+#include <kiconloader.h>
+#include <kprocess.h>
+//#include <kaudio.h>
+#include <qtooltip.h>
+
+#include <X11/Xlib.h>
+#include <X11/extensions/XTest.h>
+
+#include <qsocketnotifier.h>
+
+
+
+#include <kdebug.h>
+#include <qthread.h>
+
+#include "kpcmcia.h"
+
+#include "daemondock.h"
+#include "xautolock.h"
+#include <kdedmodule.h>
+
+
+class laptop_daemon;
+class XWidget;
+
+class ButtonThread : public QThread {
+public:
+ ButtonThread() { quitting = 0; }
+ void sethandle(laptop_daemon *h) { handle = h; }
+ void quit() { quitting = 1; } // make it quit
+ void done() { while (!finished()) msleep(100); quitting = 0; }// wait 'till it's done
+ virtual void run();
+private:
+ bool quitting;
+ laptop_daemon *handle;
+};
+
+class laptop_dock;
+class laptop_daemon: public KDEDModule
+{
+ Q_OBJECT
+ K_DCOP
+public:
+ laptop_daemon(const QCString& obj);
+ ~laptop_daemon();
+ void setPollInterval(const int poll=60);
+ void SetBrightness(bool blank, int v); // routine to do it
+ int GetBrightness() { return brightness; }
+ void SetThrottle(QString v);
+ void SetPerformance(QString v);
+ void ButtonThreadInternals();
+k_dcop:
+ void restart();
+ void quit();
+signals:
+ void signal_checkBattery();
+protected:
+ void timerEvent(QTimerEvent *);
+protected slots:
+ void checkBatteryNow();
+ void timerDone();
+ void dock_quit();
+ void updatePCMCIA(int num);
+ void sonyDataReceived();
+ void BackoffRestart();
+ void WakeCheck();
+private:
+ void haveBatteryLow(int t, const int num, const int type);
+ int calcBatteryTime(int percent, long time, bool restart);
+ void start_monitor();
+ void invokeStandby();
+ void invokeSuspend();
+ void invokeHibernate();
+ void invokeShutdown();
+ void invokeLogout();
+ void displayPixmap();
+ void setBlankSaver(bool);
+ void setLoadAverage(bool enable, float value) {mLavEnabled=enable&&(value>=0.0); mLav=value;}
+
+ laptop_dock *dock_widget;
+
+ // Capability
+ bool hasAudio;
+ //KAudio audioServer;
+
+ // General settings
+public:
+ int val;
+ int powered;
+ int left;
+ bool x11Event(XEvent *event);
+ bool exists() { return s.exists; }
+ QString noBatteryIcon() { return s.noBatteryIcon; }
+ QString chargeIcon() { return s.chargeIcon; }
+ QString noChargeIcon() { return s.noChargeIcon; }
+protected:
+ int triggered[2];
+
+ int oldval, oldexists, oldpowered, oldleft, knownFullyCharged;
+
+ int changed;
+
+ int oldTimer;
+ bool timer; // autolock timer is active
+
+ int power_time;
+
+ // PCMCIA related
+ KPCMCIA *_pcmcia;
+
+ // sony jog-bar support
+
+ int sony_fd; // file desc form open /dev/sonypi
+ Display *sony_disp; // X display
+ QSocketNotifier *sony_notifier; // how we know data is waiting
+
+ // brightness
+
+ int brightness; // actual brightness, -1 if not known
+
+ bool lid_state;
+ bool power_state;
+ ButtonThread buttonThread;
+
+
+ //
+ XAutoLock autoLock; // timer/UI maint
+ float mLav;
+ bool mLavEnabled;
+ bool need_wait; // undo sleep stuff
+ bool saved_brightness, saved_throttle, saved_performance;
+ int saved_brightness_val;
+ QString saved_performance_val, saved_throttle_val;
+ QTimer *wake_timer; // the timer for the above running
+ QPoint wakepos; // the mouse pos at the beginning of time
+ void WakeUpAuto();
+ QTimer *backoffTimer; // backoff
+
+ bool power_button_off; // imagined state of the power button
+ bool button_bright_saved; // saved button state
+ int button_bright_val;
+ bool button_saved_performance;
+ QString button_saved_performance_val;
+ bool button_saved_throttle;
+ QString button_saved_throttle_val;
+
+ daemon_state s; // saved daemon state from config file
+
+ XWidget *xwidget;
+};
+#endif
diff --git a/klaptopdaemon/linux/bulkmem.h b/klaptopdaemon/linux/bulkmem.h
new file mode 100644
index 0000000..e0bafc8
--- /dev/null
+++ b/klaptopdaemon/linux/bulkmem.h
@@ -0,0 +1,184 @@
+/*
+ * Definitions for bulk memory services
+ *
+ * bulkmem.h 1.8 1998/05/10 12:10:34
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * The initial developer of the original code is David A. Hinds
+ * <dhinds@hyper.stanford.edu>. Portions created by David A. Hinds
+ * are Copyright (C) 1998 David A. Hinds. All Rights Reserved.
+ * bulkmem.h 1.3 1995/05/27 04:49:49
+ */
+
+#ifndef _LINUX_BULKMEM_H
+#define _LINUX_BULKMEM_H
+
+/* For GetFirstRegion and GetNextRegion */
+typedef struct region_info_t {
+ u_int Attributes;
+ u_int CardOffset;
+ u_int RegionSize;
+ u_int AccessSpeed;
+ u_int BlockSize;
+ u_int PartMultiple;
+ u_char JedecMfr, JedecInfo;
+ memory_handle_t next;
+} region_info_t;
+
+#define REGION_TYPE 0x0001
+#define REGION_TYPE_CM 0x0000
+#define REGION_TYPE_AM 0x0001
+#define REGION_PREFETCH 0x0008
+#define REGION_CACHEABLE 0x0010
+#define REGION_BAR_MASK 0xe000
+#define REGION_BAR_SHIFT 13
+
+/* For OpenMemory */
+typedef struct open_mem_t {
+ u_int Attributes;
+ u_int Offset;
+} open_mem_t;
+
+/* Attributes for OpenMemory */
+#define MEMORY_TYPE 0x0001
+#define MEMORY_TYPE_CM 0x0000
+#define MEMORY_TYPE_AM 0x0001
+#define MEMORY_EXCLUSIVE 0x0002
+#define MEMORY_PREFETCH 0x0008
+#define MEMORY_CACHEABLE 0x0010
+#define MEMORY_BAR_MASK 0xe000
+#define MEMORY_BAR_SHIFT 13
+
+typedef struct eraseq_entry_t {
+ memory_handle_t Handle;
+ u_char State;
+ u_int Size;
+ u_int Offset;
+ void *Optional;
+} eraseq_entry_t;
+
+typedef struct eraseq_hdr_t {
+ int QueueEntryCnt;
+ eraseq_entry_t *QueueEntryArray;
+} eraseq_hdr_t;
+
+#define ERASE_QUEUED 0x00
+#define ERASE_IN_PROGRESS(n) (((n) > 0) && ((n) < 0x80))
+#define ERASE_IDLE 0xff
+#define ERASE_PASSED 0xe0
+#define ERASE_FAILED 0xe1
+
+#define ERASE_MISSING 0x80
+#define ERASE_MEDIA_WRPROT 0x84
+#define ERASE_NOT_ERASABLE 0x85
+#define ERASE_BAD_OFFSET 0xc1
+#define ERASE_BAD_TECH 0xc2
+#define ERASE_BAD_SOCKET 0xc3
+#define ERASE_BAD_VCC 0xc4
+#define ERASE_BAD_VPP 0xc5
+#define ERASE_BAD_SIZE 0xc6
+
+/* For CopyMemory */
+typedef struct copy_op_t {
+ u_int Attributes;
+ u_int SourceOffset;
+ u_int DestOffset;
+ u_int Count;
+} copy_op_t;
+
+/* For ReadMemory and WriteMemory */
+typedef struct mem_op_t {
+ u_int Attributes;
+ u_int Offset;
+ u_int Count;
+} mem_op_t;
+
+#define MEM_OP_BUFFER 0x01
+#define MEM_OP_BUFFER_USER 0x00
+#define MEM_OP_BUFFER_KERNEL 0x01
+#define MEM_OP_DISABLE_ERASE 0x02
+#define MEM_OP_VERIFY 0x04
+
+/* For RegisterMTD */
+typedef struct mtd_reg_t {
+ u_int Attributes;
+ u_int Offset;
+ u_long MediaID;
+} mtd_reg_t;
+
+/*
+ * Definitions for MTD requests
+ */
+
+typedef struct mtd_request_t {
+ u_int SrcCardOffset;
+ u_int DestCardOffset;
+ u_int TransferLength;
+ u_int Function;
+ u_long MediaID;
+ u_int Status;
+ u_int Timeout;
+} mtd_request_t;
+
+/* Fields in MTD Function */
+#define MTD_REQ_ACTION 0x003
+#define MTD_REQ_ERASE 0x000
+#define MTD_REQ_READ 0x001
+#define MTD_REQ_WRITE 0x002
+#define MTD_REQ_COPY 0x003
+#define MTD_REQ_NOERASE 0x004
+#define MTD_REQ_VERIFY 0x008
+#define MTD_REQ_READY 0x010
+#define MTD_REQ_TIMEOUT 0x020
+#define MTD_REQ_LAST 0x040
+#define MTD_REQ_FIRST 0x080
+#define MTD_REQ_KERNEL 0x100
+
+/* Status codes */
+#define MTD_WAITREQ 0x00
+#define MTD_WAITTIMER 0x01
+#define MTD_WAITRDY 0x02
+#define MTD_WAITPOWER 0x03
+
+/*
+ * Definitions for MTD helper functions
+ */
+
+/* For MTDModifyWindow */
+typedef struct mtd_mod_win_t {
+ u_int Attributes;
+ u_int AccessSpeed;
+ u_int CardOffset;
+} mtd_mod_win_t;
+
+/* For MTDSetVpp */
+typedef struct mtd_vpp_req_t {
+ u_char Vpp1, Vpp2;
+} mtd_vpp_req_t;
+
+/* For MTDRDYMask */
+typedef struct mtd_rdy_req_t {
+ u_int Mask;
+} mtd_rdy_req_t;
+
+enum mtd_helper {
+ MTDRequestWindow, MTDModifyWindow, MTDReleaseWindow,
+ MTDSetVpp, MTDRDYMask
+};
+
+#ifdef IN_CARD_SERVICES
+extern int MTDHelperEntry(int func, void *a1, void *a2);
+#else
+extern int MTDHelperEntry(int func, ...);
+#endif
+
+#endif /* _LINUX_BULKMEM_H */
diff --git a/klaptopdaemon/linux/ciscode.h b/klaptopdaemon/linux/ciscode.h
new file mode 100644
index 0000000..1c536d1
--- /dev/null
+++ b/klaptopdaemon/linux/ciscode.h
@@ -0,0 +1,96 @@
+/*
+ * ciscode.h 1.31 1999/02/16 01:16:46
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * The initial developer of the original code is David A. Hinds
+ * <dhinds@hyper.stanford.edu>. Portions created by David A. Hinds
+ * are Copyright (C) 1998 David A. Hinds. All Rights Reserved.
+ */
+
+#ifndef _LINUX_CISCODE_H
+#define _LINUX_CISCODE_H
+
+/* Manufacturer and Product ID codes */
+
+#define MANFID_3COM 0x0101
+#define PRODID_3COM_3CXEM556 0x0035
+#define PRODID_3COM_3CCFEM556 0x0556
+#define PRODID_3COM_3C562 0x0562
+
+#define MANFID_ADAPTEC 0x012f
+#define PRODID_ADAPTEC_SCSI 0x0001
+
+#define MANFID_ATT 0xffff
+#define PRODID_ATT_KIT 0x0100
+
+#define MANFID_CONTEC 0xc001
+
+#define MANFID_FUJITSU 0x0004
+#define PRODID_FUJITSU_MBH10302 0x0004
+#define PRODID_FUJITSU_MBH10304 0x1003
+#define PRODID_FUJITSU_LA501 0x2000
+
+#define MANFID_IBM 0x00a4
+#define PRODID_IBM_HOME_AND_AWAY 0x002e
+
+#define MANFID_INTEL 0x0089
+#define PRODID_INTEL_DUAL_RS232 0x0301
+#define PRODID_INTEL_2PLUS 0x8422
+
+#define MANFID_LINKSYS 0x0143
+#define PRODID_LINKSYS_PCMLM28 0xc0ab
+#define PRODID_LINKSYS_3400 0x3341
+
+#define MANFID_MEGAHERTZ 0x0102
+#define PRODID_MEGAHERTZ_VARIOUS 0x0000
+#define PRODID_MEGAHERTZ_EM3288 0x0006
+
+#define MANFID_MACNICA 0xc00b
+
+#define MANFID_MOTOROLA 0x0109
+#define PRODID_MOTOROLA_MARINER 0x0501
+
+#define MANFID_NEW_MEDIA 0x0057
+
+#define MANFID_OLICOM 0x0121
+#define PRODID_OLICOM_OC2231 0x3122
+#define PRODID_OLICOM_OC2232 0x3222
+
+#define MANFID_OMEGA 0x0137
+#define PRODID_OMEGA_QSP_100 0x0025
+
+#define MANFID_OSITECH 0x0140
+#define PRODID_OSITECH_JACK_144 0x0001
+#define PRODID_OSITECH_JACK_288 0x0002
+#define PRODID_OSITECH_JACK_336 0x0007
+
+#define MANFID_PSION 0x016c
+
+#define MANFID_QUATECH 0x0137
+#define PRODID_QUATECH_DUAL_RS232 0x0012
+#define PRODID_QUATECH_DUAL_RS232_D1 0x0007
+#define PRODID_QUATECH_QUAD_RS232 0x001b
+
+#define MANFID_SMC 0x0108
+#define PRODID_SMC_ETHER 0x0105
+
+#define MANFID_SOCKET 0x0104
+#define PRODID_SOCKET_DUAL_RS232 0x0006
+#define PRODID_SOCKET_LPE 0x000d
+
+#define MANFID_SUNDISK 0x0045
+
+#define MANFID_TDK 0x0105
+
+#define MANFID_XIRCOM 0x0105
+
+#endif /* _LINUX_CISCODE_H */
diff --git a/klaptopdaemon/linux/cisreg.h b/klaptopdaemon/linux/cisreg.h
new file mode 100644
index 0000000..ebe54fc
--- /dev/null
+++ b/klaptopdaemon/linux/cisreg.h
@@ -0,0 +1,105 @@
+/*
+ * cisreg.h 1.11 1998/09/11 08:54:47
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * The initial developer of the original code is David A. Hinds
+ * <dhinds@hyper.stanford.edu>. Portions created by David A. Hinds
+ * are Copyright (C) 1998 David A. Hinds. All Rights Reserved.
+ */
+
+#ifndef _LINUX_CISREG_H
+#define _LINUX_CISREG_H
+
+/* Offsets from ConfigBase for CIS registers */
+#define CISREG_COR 0x00
+#define CISREG_CCSR 0x02
+#define CISREG_PRR 0x04
+#define CISREG_SCR 0x06
+#define CISREG_ESR 0x08
+#define CISREG_IOBASE_0 0x0a
+#define CISREG_IOBASE_1 0x0c
+#define CISREG_IOBASE_2 0x0e
+#define CISREG_IOBASE_3 0x10
+#define CISREG_IOSIZE 0x12
+
+/*
+ * Configuration Option Register
+ */
+#define COR_CONFIG_MASK 0x3f
+#define COR_MFC_CONFIG_MASK 0x38
+#define COR_FUNC_ENA 0x01
+#define COR_ADDR_DECODE 0x02
+#define COR_IREQ_ENA 0x04
+#define COR_LEVEL_REQ 0x40
+#define COR_SOFT_RESET 0x80
+
+/*
+ * Card Configuration and Status Register
+ */
+#define CCSR_INTR_ACK 0x01
+#define CCSR_INTR_PENDING 0x02
+#define CCSR_POWER_DOWN 0x04
+#define CCSR_AUDIO_ENA 0x08
+#define CCSR_IOIS8 0x20
+#define CCSR_SIGCHG_ENA 0x40
+#define CCSR_CHANGED 0x80
+
+/*
+ * Pin Replacement Register
+ */
+#define PRR_WP_STATUS 0x01
+#define PRR_READY_STATUS 0x02
+#define PRR_BVD2_STATUS 0x04
+#define PRR_BVD1_STATUS 0x08
+#define PRR_WP_EVENT 0x10
+#define PRR_READY_EVENT 0x20
+#define PRR_BVD2_EVENT 0x40
+#define PRR_BVD1_EVENT 0x80
+
+/*
+ * Socket and Copy Register
+ */
+#define SCR_SOCKET_NUM 0x0f
+#define SCR_COPY_NUM 0x70
+
+/*
+ * Extended Status Register
+ */
+#define ESR_REQ_ATTN_ENA 0x01
+#define ESR_REQ_ATTN 0x10
+
+/*
+ * CardBus Function Status Registers
+ */
+#define CBFN_EVENT 0x00
+#define CBFN_MASK 0x04
+#define CBFN_STATE 0x08
+#define CBFN_FORCE 0x0c
+
+/*
+ * These apply to all the CardBus function registers
+ */
+#define CBFN_WP 0x0001
+#define CBFN_READY 0x0002
+#define CBFN_BVD2 0x0004
+#define CBFN_BVD1 0x0008
+#define CBFN_GWAKE 0x0010
+#define CBFN_INTR 0x8000
+
+/*
+ * Extra bits in the Function Event Mask Register
+ */
+#define FEMR_BAM_ENA 0x0020
+#define FEMR_PWM_ENA 0x0040
+#define FEMR_WKUP_MASK 0x4000
+
+#endif /* _LINUX_CISREG_H */
diff --git a/klaptopdaemon/linux/cistpl.h b/klaptopdaemon/linux/cistpl.h
new file mode 100644
index 0000000..8fee55b
--- /dev/null
+++ b/klaptopdaemon/linux/cistpl.h
@@ -0,0 +1,543 @@
+/*
+ * cistpl.h 1.27 1998/09/30 18:08:46
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * The initial developer of the original code is David A. Hinds
+ * <dhinds@hyper.stanford.edu>. Portions created by David A. Hinds
+ * are Copyright (C) 1998 David A. Hinds. All Rights Reserved.
+ */
+
+#ifndef _LINUX_CISTPL_H
+#define _LINUX_CISTPL_H
+
+#define CISTPL_NULL 0x00
+#define CISTPL_DEVICE 0x01
+#define CISTPL_LONGLINK_CB 0x02
+#define CISTPL_CONFIG_CB 0x04
+#define CISTPL_CFTABLE_ENTRY_CB 0x05
+#define CISTPL_LONGLINK_MFC 0x06
+#define CISTPL_BAR 0x07
+#define CISTPL_CHECKSUM 0x10
+#define CISTPL_LONGLINK_A 0x11
+#define CISTPL_LONGLINK_C 0x12
+#define CISTPL_LINKTARGET 0x13
+#define CISTPL_NO_LINK 0x14
+#define CISTPL_VERS_1 0x15
+#define CISTPL_ALTSTR 0x16
+#define CISTPL_DEVICE_A 0x17
+#define CISTPL_JEDEC_C 0x18
+#define CISTPL_JEDEC_A 0x19
+#define CISTPL_CONFIG 0x1a
+#define CISTPL_CFTABLE_ENTRY 0x1b
+#define CISTPL_DEVICE_OC 0x1c
+#define CISTPL_DEVICE_OA 0x1d
+#define CISTPL_DEVICE_GEO 0x1e
+#define CISTPL_DEVICE_GEO_A 0x1f
+#define CISTPL_MANFID 0x20
+#define CISTPL_FUNCID 0x21
+#define CISTPL_FUNCE 0x22
+#define CISTPL_SWIL 0x23
+#define CISTPL_END 0xff
+/* Layer 2 tuples */
+#define CISTPL_VERS_2 0x40
+#define CISTPL_FORMAT 0x41
+#define CISTPL_GEOMETRY 0x42
+#define CISTPL_BYTEORDER 0x43
+#define CISTPL_DATE 0x44
+#define CISTPL_BATTERY 0x45
+/* Layer 3 tuples */
+#define CISTPL_ORG 0x46
+
+typedef struct cistpl_longlink_t {
+ u_int addr;
+} cistpl_longlink_t;
+
+typedef struct cistpl_checksum_t {
+ u_short addr;
+ u_short len;
+ u_char sum;
+} cistpl_checksum_t;
+
+#define CISTPL_MAX_FUNCTIONS 8
+#define CISTPL_MFC_ATTR 0x00
+#define CISTPL_MFC_COMMON 0x01
+
+typedef struct cistpl_longlink_mfc_t {
+ u_char nfn;
+ struct {
+ u_char space;
+ u_int addr;
+ } fn[CISTPL_MAX_FUNCTIONS];
+} cistpl_longlink_mfc_t;
+
+#define CISTPL_MAX_ALTSTR_STRINGS 4
+
+typedef struct cistpl_altstr_t {
+ u_char ns;
+ u_char ofs[CISTPL_MAX_ALTSTR_STRINGS];
+ char str[254];
+} cistpl_altstr_t;
+
+#define CISTPL_DTYPE_NULL 0x00
+#define CISTPL_DTYPE_ROM 0x01
+#define CISTPL_DTYPE_OTPROM 0x02
+#define CISTPL_DTYPE_EPROM 0x03
+#define CISTPL_DTYPE_EEPROM 0x04
+#define CISTPL_DTYPE_FLASH 0x05
+#define CISTPL_DTYPE_SRAM 0x06
+#define CISTPL_DTYPE_DRAM 0x07
+#define CISTPL_DTYPE_FUNCSPEC 0x0d
+#define CISTPL_DTYPE_EXTEND 0x0e
+
+#define CISTPL_MAX_DEVICES 4
+
+typedef struct cistpl_device_t {
+ u_char ndev;
+ struct {
+ u_char type;
+ u_char wp;
+ u_int speed;
+ u_int size;
+ } dev[CISTPL_MAX_DEVICES];
+} cistpl_device_t;
+
+#define CISTPL_DEVICE_MWAIT 0x01
+#define CISTPL_DEVICE_3VCC 0x02
+
+typedef struct cistpl_device_o_t {
+ u_char flags;
+ cistpl_device_t device;
+} cistpl_device_o_t;
+
+#define CISTPL_VERS_1_MAX_PROD_STRINGS 4
+
+typedef struct cistpl_vers_1_t {
+ u_char major;
+ u_char minor;
+ u_char ns;
+ u_char ofs[CISTPL_VERS_1_MAX_PROD_STRINGS];
+ char str[254];
+} cistpl_vers_1_t;
+
+typedef struct cistpl_jedec_t {
+ u_char nid;
+ struct {
+ u_char mfr;
+ u_char info;
+ } id[CISTPL_MAX_DEVICES];
+} cistpl_jedec_t;
+
+typedef struct cistpl_manfid_t {
+ u_short manf;
+ u_short card;
+} cistpl_manfid_t;
+
+#define CISTPL_FUNCID_MULTI 0x00
+#define CISTPL_FUNCID_MEMORY 0x01
+#define CISTPL_FUNCID_SERIAL 0x02
+#define CISTPL_FUNCID_PARALLEL 0x03
+#define CISTPL_FUNCID_FIXED 0x04
+#define CISTPL_FUNCID_VIDEO 0x05
+#define CISTPL_FUNCID_NETWORK 0x06
+#define CISTPL_FUNCID_AIMS 0x07
+#define CISTPL_FUNCID_SCSI 0x08
+
+#define CISTPL_SYSINIT_POST 0x01
+#define CISTPL_SYSINIT_ROM 0x02
+
+typedef struct cistpl_funcid_t {
+ u_char func;
+ u_char sysinit;
+} cistpl_funcid_t;
+
+typedef struct cistpl_funce_t {
+ u_char type;
+ u_char data[1];
+} cistpl_funce_t;
+
+/*======================================================================
+
+ Modem Function Extension Tuples
+
+======================================================================*/
+
+#define CISTPL_FUNCE_SERIAL 0x00
+#define CISTPL_FUNCE_SERIAL_DATA 0x08
+#define CISTPL_FUNCE_SERIAL_FAX 0x09
+#define CISTPL_FUNCE_SERIAL_VOICE 0x0a
+#define CISTPL_FUNCE_CAP 0x01
+#define CISTPL_FUNCE_CAP_DATA 0x05
+#define CISTPL_FUNCE_CAP_FAX 0x06
+#define CISTPL_FUNCE_CAP_VOICE 0x07
+#define CISTPL_FUNCE_SERV_DATA 0x02
+#define CISTPL_FUNCE_SERV_FAX_1 0x13
+#define CISTPL_FUNCE_SERV_FAX_2 0x23
+#define CISTPL_FUNCE_SERV_FAX_3 0x33
+#define CISTPL_FUNCE_SERV_VOICE 0x84
+
+/* UART identification */
+#define CISTPL_SERIAL_UART_8250 0x00
+#define CISTPL_SERIAL_UART_16450 0x01
+#define CISTPL_SERIAL_UART_16550 0x02
+
+/* UART capabilities */
+#define CISTPL_SERIAL_UART_SPACE 0x01
+#define CISTPL_SERIAL_UART_MARK 0x02
+#define CISTPL_SERIAL_UART_ODD 0x04
+#define CISTPL_SERIAL_UART_EVEN 0x08
+#define CISTPL_SERIAL_UART_5BIT 0x01
+#define CISTPL_SERIAL_UART_6BIT 0x02
+#define CISTPL_SERIAL_UART_7BIT 0x04
+#define CISTPL_SERIAL_UART_8BIT 0x08
+#define CISTPL_SERIAL_UART_1STOP 0x10
+#define CISTPL_SERIAL_UART_MSTOP 0x20
+#define CISTPL_SERIAL_UART_2STOP 0x40
+
+typedef struct cistpl_serial_t {
+ u_char uart_type;
+ u_char uart_cap_0;
+ u_char uart_cap_1;
+} cistpl_serial_t;
+
+typedef struct cistpl_modem_cap_t {
+ u_char flow;
+ u_char cmd_buf;
+ u_int rcv_buf:24;
+ u_int xmit_buf:24;
+} cistpl_modem_cap_t;
+
+typedef struct cistpl_data_serv_t {
+ u_char max_data_0;
+ u_char max_data_1;
+ u_char modulation_0;
+ u_char modulation_1;
+ u_char error_control;
+ u_char compression;
+ u_char cmd_protocol;
+ u_char escape;
+ u_char encrypt;
+ u_char misc_features;
+ u_char ccitt_code[1];
+} cistpl_data_serv_t;
+
+typedef struct cistpl_fax_serv_t {
+ u_char max_data_0;
+ u_char max_data_1;
+ u_char modulation;
+ u_char encrypt;
+ u_char features_0;
+ u_char features_1;
+ u_char ccitt_code[1];
+} cistpl_fax_serv_t;
+
+typedef struct cistpl_voice_serv_t {
+ u_char max_data_0;
+ u_char max_data_1;
+} cistpl_voice_serv_t;
+
+/*======================================================================
+
+ LAN Function Extension Tuples
+
+======================================================================*/
+
+#define CISTPL_FUNCE_LAN_TECH 0x01
+#define CISTPL_FUNCE_LAN_SPEED 0x02
+#define CISTPL_FUNCE_LAN_MEDIA 0x03
+#define CISTPL_FUNCE_LAN_NODE_ID 0x04
+#define CISTPL_FUNCE_LAN_CONNECTOR 0x05
+
+/* LAN technologies */
+#define CISTPL_LAN_TECH_ARCNET 0x01
+#define CISTPL_LAN_TECH_ETHERNET 0x02
+#define CISTPL_LAN_TECH_TOKENRING 0x03
+#define CISTPL_LAN_TECH_LOCALTALK 0x04
+#define CISTPL_LAN_TECH_FDDI 0x05
+#define CISTPL_LAN_TECH_ATM 0x06
+#define CISTPL_LAN_TECH_WIRELESS 0x07
+
+typedef struct cistpl_lan_tech_t {
+ u_char tech;
+} cistpl_lan_tech_t;
+
+typedef struct cistpl_lan_speed_t {
+ u_int speed;
+} cistpl_lan_speed_t;
+
+/* LAN media definitions */
+#define CISTPL_LAN_MEDIA_UTP 0x01
+#define CISTPL_LAN_MEDIA_STP 0x02
+#define CISTPL_LAN_MEDIA_THIN_COAX 0x03
+#define CISTPL_LAN_MEDIA_THICK_COAX 0x04
+#define CISTPL_LAN_MEDIA_FIBER 0x05
+#define CISTPL_LAN_MEDIA_900MHZ 0x06
+#define CISTPL_LAN_MEDIA_2GHZ 0x07
+#define CISTPL_LAN_MEDIA_5GHZ 0x08
+#define CISTPL_LAN_MEDIA_DIFF_IR 0x09
+#define CISTPL_LAN_MEDIA_PTP_IR 0x0a
+
+typedef struct cistpl_lan_media_t {
+ u_char media;
+} cistpl_lan_media_t;
+
+typedef struct cistpl_lan_node_id_t {
+ u_char nb;
+ u_char id[16];
+} cistpl_lan_node_id_t;
+
+typedef struct cistpl_lan_connector_t {
+ u_char code;
+} cistpl_lan_connector_t;
+
+/*======================================================================
+
+ IDE Function Extension Tuples
+
+======================================================================*/
+
+#define CISTPL_IDE_INTERFACE 0x01
+
+typedef struct cistpl_ide_interface_t {
+ u_char interface;
+} cistpl_ide_interface_t;
+
+/* First feature byte */
+#define CISTPL_IDE_SILICON 0x04
+#define CISTPL_IDE_UNIQUE 0x08
+#define CISTPL_IDE_DUAL 0x10
+
+/* Second feature byte */
+#define CISTPL_IDE_HAS_SLEEP 0x01
+#define CISTPL_IDE_HAS_STANDBY 0x02
+#define CISTPL_IDE_HAS_IDLE 0x04
+#define CISTPL_IDE_LOW_POWER 0x08
+#define CISTPL_IDE_REG_INHIBIT 0x10
+#define CISTPL_IDE_HAS_INDEX 0x20
+#define CISTPL_IDE_IOIS16 0x40
+
+typedef struct cistpl_ide_feature_t {
+ u_char feature1;
+ u_char feature2;
+} cistpl_ide_feature_t;
+
+#define CISTPL_FUNCE_IDE_IFACE 0x01
+#define CISTPL_FUNCE_IDE_MASTER 0x02
+#define CISTPL_FUNCE_IDE_SLAVE 0x03
+
+/*======================================================================
+
+ Configuration Table Entries
+
+======================================================================*/
+
+#define CISTPL_BAR_SPACE 0x07
+#define CISTPL_BAR_SPACE_IO 0x10
+#define CISTPL_BAR_PREFETCH 0x20
+#define CISTPL_BAR_CACHEABLE 0x40
+#define CISTPL_BAR_1MEG_MAP 0x80
+
+typedef struct cistpl_bar_t {
+ u_char attr;
+ u_int size;
+} cistpl_bar_t;
+
+typedef struct cistpl_config_t {
+ u_char last_idx;
+ u_int base;
+ u_int rmask[4];
+ u_char subtuples;
+} cistpl_config_t;
+
+/* These are bits in the 'present' field, and indices in 'param' */
+#define CISTPL_POWER_VNOM 0
+#define CISTPL_POWER_VMIN 1
+#define CISTPL_POWER_VMAX 2
+#define CISTPL_POWER_ISTATIC 3
+#define CISTPL_POWER_IAVG 4
+#define CISTPL_POWER_IPEAK 5
+#define CISTPL_POWER_IDOWN 6
+
+#define CISTPL_POWER_HIGHZ_OK 0x01
+#define CISTPL_POWER_HIGHZ_REQ 0x02
+
+typedef struct cistpl_power_t {
+ u_char present;
+ u_char flags;
+ u_int param[7];
+} cistpl_power_t;
+
+typedef struct cistpl_timing_t {
+ u_int wait, waitscale;
+ u_int ready, rdyscale;
+ u_int reserved, rsvscale;
+} cistpl_timing_t;
+
+#define CISTPL_IO_LINES_MASK 0x1f
+#define CISTPL_IO_8BIT 0x20
+#define CISTPL_IO_16BIT 0x40
+#define CISTPL_IO_RANGE 0x80
+
+#define CISTPL_IO_MAX_WIN 16
+
+typedef struct cistpl_io_t {
+ u_char flags;
+ u_char nwin;
+ struct {
+ u_int base;
+ u_int len;
+ } win[CISTPL_IO_MAX_WIN];
+} cistpl_io_t;
+
+typedef struct cistpl_irq_t {
+ u_int IRQInfo1;
+ u_int IRQInfo2;
+} cistpl_irq_t;
+
+#define CISTPL_MEM_MAX_WIN 8
+
+typedef struct cistpl_mem_t {
+ u_char flags;
+ u_char nwin;
+ struct {
+ u_int len;
+ u_int card_addr;
+ u_int host_addr;
+ } win[CISTPL_MEM_MAX_WIN];
+} cistpl_mem_t;
+
+#define CISTPL_CFTABLE_DEFAULT 0x0001
+#define CISTPL_CFTABLE_BVDS 0x0002
+#define CISTPL_CFTABLE_WP 0x0004
+#define CISTPL_CFTABLE_RDYBSY 0x0008
+#define CISTPL_CFTABLE_MWAIT 0x0010
+#define CISTPL_CFTABLE_AUDIO 0x0800
+#define CISTPL_CFTABLE_READONLY 0x1000
+#define CISTPL_CFTABLE_PWRDOWN 0x2000
+
+typedef struct cistpl_cftable_entry_t {
+ u_char index;
+ u_short flags;
+ u_char interface;
+ cistpl_power_t vcc, vpp1, vpp2;
+ cistpl_timing_t timing;
+ cistpl_io_t io;
+ cistpl_irq_t irq;
+ cistpl_mem_t mem;
+ u_char subtuples;
+} cistpl_cftable_entry_t;
+
+#define CISTPL_CFTABLE_MASTER 0x000100
+#define CISTPL_CFTABLE_INVALIDATE 0x000200
+#define CISTPL_CFTABLE_VGA_PALETTE 0x000400
+#define CISTPL_CFTABLE_PARITY 0x000800
+#define CISTPL_CFTABLE_WAIT 0x001000
+#define CISTPL_CFTABLE_SERR 0x002000
+#define CISTPL_CFTABLE_FAST_BACK 0x004000
+#define CISTPL_CFTABLE_BINARY_AUDIO 0x010000
+#define CISTPL_CFTABLE_PWM_AUDIO 0x020000
+
+typedef struct cistpl_cftable_entry_cb_t {
+ u_char index;
+ u_int flags;
+ cistpl_power_t vcc, vpp1, vpp2;
+ u_char io;
+ cistpl_irq_t irq;
+ u_char mem;
+ u_char subtuples;
+} cistpl_cftable_entry_cb_t;
+
+typedef struct cistpl_device_geo_t {
+ u_char ngeo;
+ struct {
+ u_char buswidth;
+ u_int erase_block;
+ u_int read_block;
+ u_int write_block;
+ u_int partition;
+ u_int interleave;
+ } geo[CISTPL_MAX_DEVICES];
+} cistpl_device_geo_t;
+
+typedef struct cistpl_vers_2_t {
+ u_char vers;
+ u_char comply;
+ u_short dindex;
+ u_char vspec8, vspec9;
+ u_char nhdr;
+ u_char vendor, info;
+ char str[244];
+} cistpl_vers_2_t;
+
+typedef struct cistpl_org_t {
+ u_char data_org;
+ char desc[30];
+} cistpl_org_t;
+
+#define CISTPL_ORG_FS 0x00
+#define CISTPL_ORG_APPSPEC 0x01
+#define CISTPL_ORG_XIP 0x02
+
+typedef union cisparse_t {
+ cistpl_device_t device;
+ cistpl_checksum_t checksum;
+ cistpl_longlink_t longlink;
+ cistpl_longlink_mfc_t longlink_mfc;
+ cistpl_vers_1_t version_1;
+ cistpl_altstr_t altstr;
+ cistpl_jedec_t jedec;
+ cistpl_manfid_t manfid;
+ cistpl_funcid_t funcid;
+ cistpl_funce_t funce;
+ cistpl_bar_t bar;
+ cistpl_config_t config;
+ cistpl_cftable_entry_t cftable_entry;
+ cistpl_cftable_entry_cb_t cftable_entry_cb;
+ cistpl_device_geo_t device_geo;
+ cistpl_vers_2_t vers_2;
+ cistpl_org_t org;
+} cisparse_t;
+
+typedef struct tuple_t {
+ u_int Attributes;
+ cisdata_t DesiredTuple;
+ u_int Flags; /* internal use */
+ u_int LinkOffset; /* internal use */
+ u_int CISOffset; /* internal use */
+ cisdata_t TupleCode;
+ cisdata_t TupleLink;
+ cisdata_t TupleOffset;
+ cisdata_t TupleDataMax;
+ cisdata_t TupleDataLen;
+ cisdata_t *TupleData;
+} tuple_t;
+
+/* Special cisdata_t value */
+#define RETURN_FIRST_TUPLE 0xff
+
+/* Attributes for tuple calls */
+#define TUPLE_RETURN_LINK 0x01
+#define TUPLE_RETURN_COMMON 0x02
+
+/* For ValidateCIS */
+typedef struct cisinfo_t {
+ u_int Chains;
+} cisinfo_t;
+
+#define CISTPL_MAX_CIS_SIZE 0x200
+
+/* For ReplaceCIS */
+typedef struct cisdump_t {
+ u_int Length;
+ cisdata_t Data[CISTPL_MAX_CIS_SIZE];
+} cisdump_t;
+
+#endif /* LINUX_CISTPL_H */
diff --git a/klaptopdaemon/linux/cs.h b/klaptopdaemon/linux/cs.h
new file mode 100644
index 0000000..b8610ca
--- /dev/null
+++ b/klaptopdaemon/linux/cs.h
@@ -0,0 +1,455 @@
+/*
+ * cs.h 1.63 1998/12/09 07:36:24
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * The initial developer of the original code is David A. Hinds
+ * <dhinds@hyper.stanford.edu>. Portions created by David A. Hinds
+ * are Copyright (C) 1998 David A. Hinds. All Rights Reserved.
+ */
+
+#ifndef _LINUX_CS_H
+#define _LINUX_CS_H
+
+/* For AccessConfigurationRegister */
+typedef struct conf_reg_t {
+ u_char Function;
+ u_int Action;
+ off_t Offset;
+ u_int Value;
+} conf_reg_t;
+
+/* Actions */
+#define CS_READ 1
+#define CS_WRITE 2
+
+/* for AdjustResourceInfo */
+typedef struct adjust_t {
+ u_int Action;
+ u_int Resource;
+ u_int Attributes;
+ union {
+ struct memory {
+ u_long Base;
+ u_long Size;
+ } memory;
+ struct io {
+ ioaddr_t BasePort;
+ ioaddr_t NumPorts;
+ u_int IOAddrLines;
+ } io;
+ struct irq {
+ u_int IRQ;
+ } irq;
+ } resource;
+} adjust_t;
+
+/* Action field */
+#define REMOVE_MANAGED_RESOURCE 1
+#define ADD_MANAGED_RESOURCE 2
+#define GET_FIRST_MANAGED_RESOURCE 3
+#define GET_NEXT_MANAGED_RESOURCE 4
+/* Resource field */
+#define RES_MEMORY_RANGE 1
+#define RES_IO_RANGE 2
+#define RES_IRQ 3
+/* Attribute field */
+#define RES_IRQ_TYPE 0x03
+#define RES_IRQ_TYPE_EXCLUSIVE 0
+#define RES_IRQ_TYPE_TIME 1
+#define RES_IRQ_TYPE_DYNAMIC 2
+#define RES_IRQ_CSC 0x04
+#define RES_SHARED 0x08
+#define RES_RESERVED 0x10
+#define RES_ALLOCATED 0x20
+#define RES_REMOVED 0x40
+
+typedef struct servinfo_t {
+ char Signature[2];
+ u_int Count;
+ u_int Revision;
+ u_int CSLevel;
+ char *VendorString;
+} servinfo_t;
+
+typedef struct event_callback_args_t {
+ client_handle_t client_handle;
+ void *info;
+ void *mtdrequest;
+ void *buffer;
+ void *misc;
+ void *client_data;
+} event_callback_args_t;
+
+/* for GetConfigurationInfo */
+typedef struct config_info_t {
+ u_char Function;
+ u_int Attributes;
+ u_int Vcc, Vpp1, Vpp2;
+ u_int IntType;
+ u_int ConfigBase;
+ u_char Status, Pin, Copy, Option, ExtStatus;
+ u_int Present;
+ u_int CardValues;
+ u_int AssignedIRQ;
+ u_int IRQAttributes;
+ ioaddr_t BasePort1;
+ ioaddr_t NumPorts1;
+ u_int Attributes1;
+ ioaddr_t BasePort2;
+ ioaddr_t NumPorts2;
+ u_int Attributes2;
+ u_int IOAddrLines;
+} config_info_t;
+
+/* For CardValues field */
+#define CV_OPTION_VALUE 0x01
+#define CV_STATUS_VALUE 0x02
+#define CV_PIN_REPLACEMENT 0x04
+#define CV_COPY_VALUE 0x08
+#define CV_EXT_STATUS 0x10
+
+/* For GetFirst/NextClient */
+typedef struct client_req_t {
+ socket_t Socket;
+ u_int Attributes;
+} client_req_t;
+
+#define CLIENT_THIS_SOCKET 0x01
+
+/* For RegisterClient */
+typedef struct client_reg_t {
+ dev_info_t *dev_info;
+ u_int Attributes;
+ u_int EventMask;
+ int (*event_handler)(event_t event, int priority,
+ event_callback_args_t *);
+ event_callback_args_t event_callback_args;
+ u_int Version;
+} client_reg_t;
+
+/* ModifyConfiguration */
+typedef struct modconf_t {
+ u_int Attributes;
+ u_int Vcc, Vpp1, Vpp2;
+} modconf_t;
+
+/* Attributes for ModifyConfiguration */
+#define CONF_IRQ_CHANGE_VALID 0x100
+#define CONF_VCC_CHANGE_VALID 0x200
+#define CONF_VPP1_CHANGE_VALID 0x400
+#define CONF_VPP2_CHANGE_VALID 0x800
+
+/* For RequestConfiguration */
+typedef struct config_req_t {
+ u_int Attributes;
+ u_int Vcc, Vpp1, Vpp2;
+ u_int IntType;
+ u_int ConfigBase;
+ u_char Status, Pin, Copy, ExtStatus;
+ u_char ConfigIndex;
+ u_int Present;
+} config_req_t;
+
+/* Attributes for RequestConfiguration */
+#define CONF_ENABLE_IRQ 0x01
+#define CONF_ENABLE_DMA 0x02
+#define CONF_ENABLE_SPKR 0x04
+#define CONF_VALID_CLIENT 0x100
+
+/* IntType field */
+#define INT_MEMORY 0x01
+#define INT_MEMORY_AND_IO 0x02
+#define INT_CARDBUS 0x04
+
+/* For RequestIO and ReleaseIO */
+typedef struct io_req_t {
+ ioaddr_t BasePort1;
+ ioaddr_t NumPorts1;
+ u_int Attributes1;
+ ioaddr_t BasePort2;
+ ioaddr_t NumPorts2;
+ u_int Attributes2;
+ u_int IOAddrLines;
+} io_req_t;
+
+/* Attributes for RequestIO and ReleaseIO */
+#define IO_SHARED 0x01
+#define IO_FIRST_SHARED 0x02
+#define IO_FORCE_ALIAS_ACCESS 0x04
+#define IO_DATA_PATH_WIDTH 0x18
+#define IO_DATA_PATH_WIDTH_8 0x00
+#define IO_DATA_PATH_WIDTH_16 0x08
+#define IO_DATA_PATH_WIDTH_AUTO 0x10
+
+/* For RequestIRQ and ReleaseIRQ */
+typedef struct irq_req_t {
+ u_int Attributes;
+ u_int AssignedIRQ;
+ u_int IRQInfo1, IRQInfo2;
+ void *Handler;
+ void *Instance;
+} irq_req_t;
+
+/* Attributes for RequestIRQ and ReleaseIRQ */
+#define IRQ_TYPE 0x03
+#define IRQ_TYPE_EXCLUSIVE 0x00
+#define IRQ_TYPE_TIME 0x01
+#define IRQ_TYPE_DYNAMIC_SHARING 0x02
+#define IRQ_FORCED_PULSE 0x04
+#define IRQ_FIRST_SHARED 0x08
+#define IRQ_HANDLE_PRESENT 0x10
+#define IRQ_PULSE_ALLOCATED 0x100
+
+/* Bits in IRQInfo1 field */
+#define IRQ_MASK 0x0f
+#define IRQ_NMI_ID 0x01
+#define IRQ_IOCK_ID 0x02
+#define IRQ_BERR_ID 0x04
+#define IRQ_VEND_ID 0x08
+#define IRQ_INFO2_VALID 0x10
+#define IRQ_LEVEL_ID 0x20
+#define IRQ_PULSE_ID 0x40
+#define IRQ_SHARE_ID 0x80
+
+typedef struct eventmask_t {
+ u_int Attributes;
+ u_int EventMask;
+} eventmask_t;
+
+#define CONF_EVENT_MASK_VALID 0x01
+
+/* Configuration registers present */
+#define PRESENT_OPTION 0x001
+#define PRESENT_STATUS 0x002
+#define PRESENT_PIN_REPLACE 0x004
+#define PRESENT_COPY 0x008
+#define PRESENT_EXT_STATUS 0x010
+#define PRESENT_IOBASE_0 0x020
+#define PRESENT_IOBASE_1 0x040
+#define PRESENT_IOBASE_2 0x080
+#define PRESENT_IOBASE_3 0x100
+#define PRESENT_IOSIZE 0x200
+
+/* Attributes for Request/GetConfiguration */
+#define CONF_ENABLE_IRQ 0x01
+#define EXCLUSIVE_USE 0x02
+#define VALID_CLIENT 0x04
+
+/* For MapMemPage */
+typedef struct memreq_t {
+ u_int CardOffset;
+ page_t Page;
+} memreq_t;
+
+/* For ModifyWindow */
+typedef struct modwin_t {
+ u_int Attributes;
+ u_int AccessSpeed;
+} modwin_t;
+
+/* For RequestWindow */
+typedef struct win_req_t {
+ u_int Attributes;
+ u_long Base;
+ u_int Size;
+ u_int AccessSpeed;
+} win_req_t;
+
+/* Attributes for RequestWindow */
+#define WIN_ADDR_SPACE 0x0001
+#define WIN_ADDR_SPACE_MEM 0x0000
+#define WIN_ADDR_SPACE_IO 0x0001
+#define WIN_MEMORY_TYPE 0x0002
+#define WIN_MEMORY_TYPE_CM 0x0000
+#define WIN_MEMORY_TYPE_AM 0x0002
+#define WIN_ENABLE 0x0004
+#define WIN_DATA_WIDTH 0x0018
+#define WIN_DATA_WIDTH_8 0x0000
+#define WIN_DATA_WIDTH_16 0x0008
+#define WIN_DATA_WIDTH_32 0x0010
+#define WIN_PAGED 0x0020
+#define WIN_SHARED 0x0040
+#define WIN_FIRST_SHARED 0x0080
+#define WIN_USE_WAIT 0x0100
+#define WIN_MAP_BELOW_1MB 0x0400
+#define WIN_PREFETCH 0x0800
+#define WIN_CACHEABLE 0x1000
+#define WIN_BAR_MASK 0xe000
+#define WIN_BAR_SHIFT 13
+
+/* Attributes for RegisterClient */
+#define INFO_MASTER_CLIENT 0x01
+#define INFO_IO_CLIENT 0x02
+#define INFO_MTD_CLIENT 0x04
+#define INFO_MEM_CLIENT 0x08
+#define MAX_NUM_CLIENTS 3
+
+#define INFO_CARD_SHARE 0x10
+#define INFO_CARD_EXCL 0x20
+
+typedef struct cs_status_t {
+ u_char Function;
+ event_t CardState;
+ event_t SocketState;
+} cs_status_t;
+
+typedef struct error_info_t {
+ int func;
+ int retcode;
+} error_info_t;
+
+/* Special stuff for binding drivers to sockets */
+typedef struct bind_req_t {
+ socket_t Socket;
+ u_char Function;
+ dev_info_t *dev_info;
+} bind_req_t;
+
+/* Flag to bind to all functions */
+#define BIND_FN_ALL 0xff
+
+typedef struct mtd_bind_t {
+ socket_t Socket;
+ u_int Attributes;
+ u_int CardOffset;
+ dev_info_t *dev_info;
+} mtd_bind_t;
+
+/* Events */
+#define CS_EVENT_PRI_LOW 0
+#define CS_EVENT_PRI_HIGH 1
+
+#define CS_EVENT_WRITE_PROTECT 0x000001
+#define CS_EVENT_CARD_LOCK 0x000002
+#define CS_EVENT_CARD_INSERTION 0x000004
+#define CS_EVENT_CARD_REMOVAL 0x000008
+#define CS_EVENT_BATTERY_DEAD 0x000010
+#define CS_EVENT_BATTERY_LOW 0x000020
+#define CS_EVENT_READY_CHANGE 0x000040
+#define CS_EVENT_CARD_DETECT 0x000080
+#define CS_EVENT_RESET_REQUEST 0x000100
+#define CS_EVENT_RESET_PHYSICAL 0x000200
+#define CS_EVENT_CARD_RESET 0x000400
+#define CS_EVENT_REGISTRATION_COMPLETE 0x000800
+#define CS_EVENT_RESET_COMPLETE 0x001000
+#define CS_EVENT_PM_SUSPEND 0x002000
+#define CS_EVENT_PM_RESUME 0x004000
+#define CS_EVENT_INSERTION_REQUEST 0x008000
+#define CS_EVENT_EJECTION_REQUEST 0x010000
+#define CS_EVENT_MTD_REQUEST 0x020000
+#define CS_EVENT_ERASE_COMPLETE 0x040000
+#define CS_EVENT_REQUEST_ATTENTION 0x080000
+#define CS_EVENT_CB_DETECT 0x100000
+#define CS_EVENT_3VCARD 0x200000
+#define CS_EVENT_XVCARD 0x400000
+
+/* Return codes */
+#define CS_SUCCESS 0x00
+#define CS_BAD_ADAPTER 0x01
+#define CS_BAD_ATTRIBUTE 0x02
+#define CS_BAD_BASE 0x03
+#define CS_BAD_EDC 0x04
+#define CS_BAD_IRQ 0x06
+#define CS_BAD_OFFSET 0x07
+#define CS_BAD_PAGE 0x08
+#define CS_READ_FAILURE 0x09
+#define CS_BAD_SIZE 0x0a
+#define CS_BAD_SOCKET 0x0b
+#define CS_BAD_TYPE 0x0d
+#define CS_BAD_VCC 0x0e
+#define CS_BAD_VPP 0x0f
+#define CS_BAD_WINDOW 0x11
+#define CS_WRITE_FAILURE 0x12
+#define CS_NO_CARD 0x14
+#define CS_UNSUPPORTED_FUNCTION 0x15
+#define CS_UNSUPPORTED_MODE 0x16
+#define CS_BAD_SPEED 0x17
+#define CS_BUSY 0x18
+#define CS_GENERAL_FAILURE 0x19
+#define CS_WRITE_PROTECTED 0x1a
+#define CS_BAD_ARG_LENGTH 0x1b
+#define CS_BAD_ARGS 0x1c
+#define CS_CONFIGURATION_LOCKED 0x1d
+#define CS_IN_USE 0x1e
+#define CS_NO_MORE_ITEMS 0x1f
+#define CS_OUT_OF_RESOURCE 0x20
+#define CS_BAD_HANDLE 0x21
+
+#define CS_BAD_TUPLE 0x40
+
+#ifdef __KERNEL__
+
+/*
+ * Calls to set up low-level "Socket Services" drivers
+ */
+
+typedef int (*ss_entry_t)(u_int sock, u_int cmd, void *arg);
+extern int register_ss_entry(int nsock, ss_entry_t entry);
+extern void unregister_ss_entry(ss_entry_t entry);
+
+/*
+ * The main Card Services entry point
+ */
+
+enum service {
+ AccessConfigurationRegister, AddSocketServices,
+ AdjustResourceInfo, CheckEraseQueue, CloseMemory, CopyMemory,
+ DeregisterClient, DeregisterEraseQueue, GetCardServicesInfo,
+ GetClientInfo, GetConfigurationInfo, GetEventMask,
+ GetFirstClient, GetFirstPartion, GetFirstRegion, GetFirstTuple,
+ GetNextClient, GetNextPartition, GetNextRegion, GetNextTuple,
+ GetStatus, GetTupleData, MapLogSocket, MapLogWindow, MapMemPage,
+ MapPhySocket, MapPhyWindow, ModifyConfiguration, ModifyWindow,
+ OpenMemory, ParseTuple, ReadMemory, RegisterClient,
+ RegisterEraseQueue, RegisterMTD, RegisterTimer,
+ ReleaseConfiguration, ReleaseExclusive, ReleaseIO, ReleaseIRQ,
+ ReleaseSocketMask, ReleaseWindow, ReplaceSocketServices,
+ RequestConfiguration, RequestExclusive, RequestIO, RequestIRQ,
+ RequestSocketMask, RequestWindow, ResetCard, ReturnSSEntry,
+ SetEventMask, SetRegion, ValidateCIS, VendorSpecific,
+ WriteMemory, BindDevice, BindMTD, ReportError,
+ SuspendCard, ResumeCard, EjectCard, InsertCard, ReplaceCIS
+};
+
+#ifdef IN_CARD_SERVICES
+extern int CardServices(int func, void *a1, void *a2, void *a3);
+#else
+extern int CardServices(int func, ...);
+#endif
+
+#ifdef __BEOS__
+#define SS_MODULE_NAME(s) ("busses/pcmcia/" s "/v1")
+#define MTD_MODULE_NAME(s) ("busses/pcmcia/" s "/v1")
+#define CS_CLIENT_MODULE_NAME "bus_managers/pcmcia_cs/client/v1"
+typedef struct cs_client_module_info {
+ bus_manager_info binfo;
+ int (*_CardServices)(int, ...);
+ int (*_MTDHelperEntry)(int, ...);
+ void (*_add_timer)(struct timer_list *);
+ void (*_del_timer)(struct timer_list *);
+} cs_client_module_info;
+#define CS_SOCKET_MODULE_NAME "bus_managers/pcmcia_cs/socket/v1"
+typedef struct cs_socket_module_info {
+ bus_manager_info binfo;
+ int (*_register_ss_entry)(int, ss_entry_t);
+ void (*_unregister_ss_entry)(ss_entry_t);
+ void (*_add_timer)(struct timer_list *);
+ void (*_del_timer)(struct timer_list *);
+ int (*register_resource)(int, u_long, u_long);
+ int (*release_resource)(int, u_long, u_long);
+ int (*check_resource)(int, u_long, u_long);
+} cs_socket_module_info;
+#endif
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_CS_H */
diff --git a/klaptopdaemon/linux/cs_types.h b/klaptopdaemon/linux/cs_types.h
new file mode 100644
index 0000000..8f9df45
--- /dev/null
+++ b/klaptopdaemon/linux/cs_types.h
@@ -0,0 +1,50 @@
+/*
+ * cs_types.h 1.13 1998/07/14 00:52:20
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * The initial developer of the original code is David A. Hinds
+ * <dhinds@hyper.stanford.edu>. Portions created by David A. Hinds
+ * are Copyright (C) 1998 David A. Hinds. All Rights Reserved.
+ */
+
+#ifndef _LINUX_CS_TYPES_H
+#define _LINUX_CS_TYPES_H
+
+#ifdef __linux__
+#include <linux/types.h>
+#endif
+
+typedef u_short socket_t;
+typedef u_short ioaddr_t;
+typedef u_int event_t;
+typedef u_char cisdata_t;
+typedef u_short page_t;
+
+struct client_t;
+typedef struct client_t *client_handle_t;
+
+struct window_t;
+typedef struct window_t *window_handle_t;
+
+struct region_t;
+typedef struct region_t *memory_handle_t;
+
+struct eraseq_t;
+typedef struct eraseq_t *eraseq_handle_t;
+
+#ifndef DEV_NAME_LEN
+#define DEV_NAME_LEN 32
+#endif
+
+typedef char dev_info_t[DEV_NAME_LEN];
+
+#endif /* _LINUX_CS_TYPES_H */
diff --git a/klaptopdaemon/linux/driver_ops.h b/klaptopdaemon/linux/driver_ops.h
new file mode 100644
index 0000000..a6a71ee
--- /dev/null
+++ b/klaptopdaemon/linux/driver_ops.h
@@ -0,0 +1,71 @@
+/*
+ * driver_ops.h 1.11 1998/11/18 07:01:50
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * The initial developer of the original code is David A. Hinds
+ * <dhinds@hyper.stanford.edu>. Portions created by David A. Hinds
+ * are Copyright (C) 1998 David A. Hinds. All Rights Reserved.
+ */
+
+#ifndef _LINUX_DRIVER_OPS_H
+#define _LINUX_DRIVER_OPS_H
+
+#ifndef DEV_NAME_LEN
+#define DEV_NAME_LEN 32
+#endif
+
+#ifdef __KERNEL__
+
+typedef struct dev_node_t {
+ char dev_name[DEV_NAME_LEN];
+ u_short major, minor;
+ struct dev_node_t *next;
+} dev_node_t;
+
+typedef struct dev_locator_t {
+ enum { LOC_ISA, LOC_PCI } bus;
+ union {
+ struct {
+ u_short io_base_1, io_base_2;
+ u_long mem_base;
+ u_char irq, dma;
+ } isa;
+ struct {
+ u_char bus;
+ u_char devfn;
+ } pci;
+ } b;
+} dev_locator_t;
+
+typedef struct driver_operations {
+ char *name;
+ dev_node_t *(*attach) (dev_locator_t *loc);
+ void (*suspend) (dev_node_t *dev);
+ void (*resume) (dev_node_t *dev);
+ void (*detach) (dev_node_t *dev);
+} driver_operations;
+
+int register_driver(struct driver_operations *ops);
+void unregister_driver(struct driver_operations *ops);
+
+#ifdef __BEOS__
+#define CB_ENABLER_MODULE_NAME "bus_managers/cb_enabler/v1"
+typedef struct cb_enabler_module_info {
+ bus_manager_info binfo;
+ int (*register_driver)(struct driver_operations *ops);
+ void (*unregister_driver)(struct driver_operations *ops);
+} cb_enabler_module_info;
+#endif /* __BEOS__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_DRIVER_OPS_H */
diff --git a/klaptopdaemon/linux/ds.h b/klaptopdaemon/linux/ds.h
new file mode 100644
index 0000000..11e0740
--- /dev/null
+++ b/klaptopdaemon/linux/ds.h
@@ -0,0 +1,142 @@
+/*
+ * ds.h 1.49 1998/08/03 19:12:23
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * The initial developer of the original code is David A. Hinds
+ * <dhinds@hyper.stanford.edu>. Portions created by David A. Hinds
+ * are Copyright (C) 1998 David A. Hinds. All Rights Reserved.
+ */
+
+#ifndef _LINUX_DS_H
+#define _LINUX_DS_H
+
+#include "driver_ops.h"
+#include "bulkmem.h"
+
+typedef struct tuple_parse_t {
+ tuple_t tuple;
+ cisdata_t data[255];
+ cisparse_t parse;
+} tuple_parse_t;
+
+typedef struct bind_info_t {
+ dev_info_t dev_info;
+ u_char function;
+ struct dev_link_t *instance;
+ char name[DEV_NAME_LEN];
+ u_short major, minor;
+ void *next;
+} bind_info_t;
+
+typedef struct mtd_info_t {
+ dev_info_t dev_info;
+ u_int Attributes;
+ u_int CardOffset;
+} mtd_info_t;
+
+typedef union ds_ioctl_arg_t {
+ servinfo_t servinfo;
+ adjust_t adjust;
+ config_info_t config;
+ tuple_t tuple;
+ tuple_parse_t tuple_parse;
+ client_req_t client_req;
+ cs_status_t status;
+ conf_reg_t conf_reg;
+ cisinfo_t cisinfo;
+ region_info_t region;
+ bind_info_t bind_info;
+ mtd_info_t mtd_info;
+ cisdump_t cisdump;
+} ds_ioctl_arg_t;
+
+#define DS_GET_CARD_SERVICES_INFO _IOR ('d', 1, servinfo_t)
+#define DS_ADJUST_RESOURCE_INFO _IOWR('d', 2, adjust_t)
+#define DS_GET_CONFIGURATION_INFO _IOWR('d', 3, config_info_t)
+#define DS_GET_FIRST_TUPLE _IOWR('d', 4, tuple_t)
+#define DS_GET_NEXT_TUPLE _IOWR('d', 5, tuple_t)
+#define DS_GET_TUPLE_DATA _IOWR('d', 6, tuple_parse_t)
+#define DS_PARSE_TUPLE _IOWR('d', 7, tuple_parse_t)
+#define DS_RESET_CARD _IO ('d', 8)
+#define DS_GET_STATUS _IOWR('d', 9, cs_status_t)
+#define DS_ACCESS_CONFIGURATION_REGISTER _IOWR('d', 10, conf_reg_t)
+#define DS_VALIDATE_CIS _IOR ('d', 11, cisinfo_t)
+#define DS_SUSPEND_CARD _IO ('d', 12)
+#define DS_RESUME_CARD _IO ('d', 13)
+#define DS_EJECT_CARD _IO ('d', 14)
+#define DS_INSERT_CARD _IO ('d', 15)
+#define DS_GET_FIRST_REGION _IOWR('d', 16, region_info_t)
+#define DS_GET_NEXT_REGION _IOWR('d', 17, region_info_t)
+#define DS_REPLACE_CIS _IOWR('d', 18, cisdump_t)
+
+#define DS_BIND_REQUEST _IOWR('d', 60, bind_info_t)
+#define DS_GET_DEVICE_INFO _IOWR('d', 61, bind_info_t)
+#define DS_GET_NEXT_DEVICE _IOWR('d', 62, bind_info_t)
+#define DS_UNBIND_REQUEST _IOW ('d', 63, bind_info_t)
+#define DS_BIND_MTD _IOWR('d', 64, mtd_info_t)
+
+#ifdef __KERNEL__
+
+typedef struct dev_link_t {
+ dev_node_t *dev;
+ u_int state, open;
+ struct wait_queue *pending;
+ struct timer_list release;
+ client_handle_t handle;
+ io_req_t io;
+ irq_req_t irq;
+ config_req_t conf;
+ window_handle_t win;
+ void *priv;
+ struct dev_link_t *next;
+} dev_link_t;
+
+/* Flags for device state */
+#define DEV_PRESENT 0x01
+#define DEV_CONFIG 0x02
+#define DEV_STALE_CONFIG 0x04 /* release on close */
+#define DEV_STALE_LINK 0x08 /* detach on release */
+#define DEV_CONFIG_PENDING 0x10
+#define DEV_RELEASE_PENDING 0x20
+#define DEV_SUSPEND 0x40
+#define DEV_BUSY 0x80
+
+#define DEV_OK(l) \
+ ((l) && ((l->state & ~DEV_BUSY) == (DEV_CONFIG|DEV_PRESENT)))
+
+int register_pccard_driver(dev_info_t *dev_info,
+ dev_link_t *(*attach)(void),
+ void (*detach)(dev_link_t *));
+
+int unregister_pccard_driver(dev_info_t *dev_info);
+
+#define register_pcmcia_driver register_pccard_driver
+#define unregister_pcmcia_driver unregister_pccard_driver
+
+#ifdef __BEOS__
+#define DS_MODULE_NAME "bus_managers/pcmcia_ds/v1"
+typedef struct ds_module_info {
+ bus_manager_info binfo;
+ int (*_register_pccard_driver)(dev_info_t *,
+ dev_link_t *(*)(void),
+ void (*)(dev_link_t *));
+ int (*_unregister_pccard_driver)(dev_info_t *);
+ struct driver_info_t **root_driver;
+ int *sockets;
+ struct socket_info_t **socket_table;
+ sem_id *list_sem;
+} ds_module_info;
+#endif /* __BEOS__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_DS_H */
diff --git a/klaptopdaemon/linux/ftl.h b/klaptopdaemon/linux/ftl.h
new file mode 100644
index 0000000..9357d17
--- /dev/null
+++ b/klaptopdaemon/linux/ftl.h
@@ -0,0 +1,62 @@
+/*
+ * ftl.h 1.4 1998/05/10 12:10:34
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * The initial developer of the original code is David A. Hinds
+ * <dhinds@hyper.stanford.edu>. Portions created by David A. Hinds
+ * are Copyright (C) 1998 David A. Hinds. All Rights Reserved.
+ */
+
+#ifndef _LINUX_FTL_H
+#define _LINUX_FTL_H
+
+typedef struct erase_unit_header_t {
+ u_char LinkTargetTuple[5];
+ u_char DataOrgTuple[10];
+ u_char NumTransferUnits;
+ u_int EraseCount;
+ u_short LogicalEUN;
+ u_char BlockSize;
+ u_char EraseUnitSize;
+ u_short FirstPhysicalEUN;
+ u_short NumEraseUnits;
+ u_int FormattedSize;
+ u_int FirstVMAddress;
+ u_short NumVMPages;
+ u_char Flags;
+ u_char Code;
+ u_int SerialNumber;
+ u_int AltEUHOffset;
+ u_int BAMOffset;
+ u_char Reserved[12];
+ u_char EndTuple[2];
+} erase_unit_header_t;
+
+/* Flags in erase_unit_header_t */
+#define HIDDEN_AREA 0x01
+#define REVERSE_POLARITY 0x02
+#define DOUBLE_BAI 0x04
+
+/* Definitions for block allocation information */
+
+#define BLOCK_FREE(b) ((b) == 0xffffffff)
+#define BLOCK_DELETED(b) (((b) == 0) || ((b) == 0xfffffffe))
+
+#define BLOCK_TYPE(b) ((b) & 0x7f)
+#define BLOCK_ADDRESS(b) ((b) & ~0x7f)
+#define BLOCK_NUMBER(b) ((b) >> 9)
+#define BLOCK_CONTROL 0x30
+#define BLOCK_DATA 0x40
+#define BLOCK_REPLACEMENT 0x60
+#define BLOCK_BAD 0x70
+
+#endif /* _LINUX_FTL_H */
diff --git a/klaptopdaemon/linux/k_compat.h b/klaptopdaemon/linux/k_compat.h
new file mode 100644
index 0000000..2b14312
--- /dev/null
+++ b/klaptopdaemon/linux/k_compat.h
@@ -0,0 +1,246 @@
+/*
+ * k_compat.h 1.74 1999/01/07 03:46:29
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * The initial developer of the original code is David A. Hinds
+ * <dhinds@hyper.stanford.edu>. Portions created by David A. Hinds
+ * are Copyright (C) 1998 David A. Hinds. All Rights Reserved.
+ */
+
+#ifndef _LINUX_K_COMPAT_H
+#define _LINUX_K_COMPAT_H
+
+#define __LINUX__
+#define VERSION(v,p,s) (((v)<<16)+(p<<8)+s)
+
+#define RUN_AT(x) (jiffies+(x))
+#define CONST const
+#define ALLOC_SKB(len) dev_alloc_skb(len+2)
+#define DEVICE(req) ((req)->rq_dev)
+#define GET_PACKET(dev, skb, count) \
+ skb_reserve((skb), 2); \
+ BLOCK_INPUT(skb_put((skb), (count)), (count)); \
+ (skb)->protocol = eth_type_trans((skb), (dev))
+
+#define BLK_DEV_HDR "linux/blk.h"
+#define NEW_MULTICAST
+
+#define FREE_IRQ(i,d) free_irq(i, d)
+#define REQUEST_IRQ(i,h,f,n,d) request_irq(i,h,f,n,d)
+#define IRQ(a,b,c) (a,b,c)
+#define DEV_ID dev_id
+
+#if (LINUX_VERSION_CODE < VERSION(2,0,16))
+#define init_waitqueue(p) (*(p) = NULL)
+#endif
+
+#if (LINUX_VERSION_CODE < VERSION(2,1,4)) && !defined(__alpha__)
+#define FS_SIZE_T int
+#define U_FS_SIZE_T int
+#else
+#if (LINUX_VERSION_CODE < VERSION(2,1,60))
+#define FS_SIZE_T long
+#define U_FS_SIZE_T unsigned long
+#else
+#define FS_SIZE_T ssize_t
+#define U_FS_SIZE_T size_t
+#endif
+#endif
+
+#if (LINUX_VERSION_CODE < VERSION(2,1,25))
+#define net_device_stats enet_statistics
+#endif
+
+#if (LINUX_VERSION_CODE < VERSION(2,1,31))
+#define FS_RELEASE_T void
+#else
+#define FS_RELEASE_T int
+#endif
+
+#if (LINUX_VERSION_CODE < VERSION(2,1,38))
+#define test_and_set_bit set_bit
+#endif
+
+#if (LINUX_VERSION_CODE > VERSION(2,1,16))
+#define AUTOCONF_INCLUDED
+#define EXPORT_SYMTAB
+#endif
+#ifdef CONFIG_MODVERSIONS
+#define MODVERSIONS 1
+#include <linux/modversions.h>
+#endif
+#include <linux/module.h>
+
+#if (LINUX_VERSION_CODE < VERSION(2,1,18))
+#define MODULE_PARM(a,b) extern int __bogus_decl
+#undef GET_USE_COUNT
+#define GET_USE_COUNT(m) mod_use_count_
+#endif
+
+#if (LINUX_VERSION_CODE < VERSION(2,1,0))
+#define copy_from_user memcpy_fromfs
+#define copy_to_user memcpy_tofs
+
+#if (!defined(__alpha__) || (LINUX_VERSION_CODE < VERSION(2,0,34)))
+#define ioremap(a,b) \
+ (((a) < 0x100000) ? (void *)((u_long)(a)) : vremap(a,b))
+#define iounmap(v) \
+ do { if ((u_long)(v) > 0x100000) vfree(v); } while (0)
+#endif
+/* This is evil... throw away the built-in get_user in 2.0 */
+#include <asm/segment.h>
+#undef get_user
+
+#ifdef __alpha__
+#define get_user(x, ptr) ((x) = __get_user((ptr), sizeof(*(ptr))))
+#undef get_fs_long
+#undef put_fs_long
+#define get_fs_long(ptr) __get_user((ptr), sizeof(int))
+#define put_fs_long(x, ptr) __put_user((x), (ptr), sizeof(int))
+#else
+#define get_user(x, ptr) \
+ ((sizeof(*ptr) == 4) ? (x = get_fs_long(ptr)) : \
+ (sizeof(*ptr) == 2) ? (x = get_fs_word(ptr)) : \
+ (x = get_fs_byte(ptr)))
+#endif
+
+#else /* 2.1.X */
+#include <asm/uaccess.h>
+#endif
+
+#if (LINUX_VERSION_CODE < VERSION(2,1,45))
+#define F_INODE(file) ((file)->f_inode)
+#else
+#define F_INODE(file) ((file)->f_dentry->d_inode)
+#endif
+
+#if (LINUX_VERSION_CODE < VERSION(2,1,51))
+#define INVALIDATE_INODES(r) invalidate_inodes(r)
+#else
+#define INVALIDATE_INODES(r) \
+ do { struct super_block *sb = get_super(r); \
+ if (sb) invalidate_inodes(sb); } while (0)
+#endif
+
+#if (LINUX_VERSION_CODE < VERSION(2,1,60))
+#define IRQ_MAP(irq, dev) irq2dev_map[irq] = dev
+#define FOPS(i,f,b,c,p) (i,f,b,c)
+#define FPOS (file->f_pos)
+#else
+#define IRQ_MAP(irq, dev) while (0)
+#define FOPS(i,f,b,c,p) (f,b,c,p)
+#define FPOS (*ppos)
+#endif
+
+#if (LINUX_VERSION_CODE < VERSION(2,1,68))
+#define signal_pending(cur) ((cur)->signal & ~(cur)->blocked)
+#endif
+
+#if (LINUX_VERSION_CODE < VERSION(2,1,86))
+#define DEV_KFREE_SKB(skb) dev_kfree_skb(skb, FREE_WRITE)
+#else
+#define DEV_KFREE_SKB(skb) dev_kfree_skb(skb)
+#endif
+
+#if (LINUX_VERSION_CODE < VERSION(2,1,89))
+#define POLL_WAIT(f, q, w) poll_wait(q, w)
+#else
+#define POLL_WAIT(f, q, w) poll_wait(f, q, w)
+#endif
+
+#include <asm/byteorder.h>
+#ifndef le16_to_cpu
+#define le16_to_cpu(x) (x)
+#define le32_to_cpu(x) (x)
+#define cpu_to_le16(x) (x)
+#define cpu_to_le32(x) (x)
+#endif
+
+#if (LINUX_VERSION_CODE < VERSION(2,1,90))
+#define spin_lock(l) do { } while (0)
+#define spin_unlock(l) do { } while (0)
+#define spin_lock_irqsave(l,f) do { save_flags(f); cli(); } while (0)
+#define spin_unlock_irqrestore(l,f) do { restore_flags(f); } while (0)
+#else
+#include <asm/spinlock.h>
+#endif
+
+#if (LINUX_VERSION_CODE < VERSION(2,1,104))
+#define mdelay(x) { int i; for (i=0;i<x;i++) udelay(1000); }
+#endif
+
+#define wacquire(w) do { } while (0)
+#define wrelease(w) do { } while (0)
+#define wsleep(w) interruptible_sleep_on(w)
+#define wakeup(w) wake_up_interruptible(w)
+#define wsleeptimeout(w,t) interruptible_sleep_on_timeout(w,t)
+#if (LINUX_VERSION_CODE < VERSION(2,1,127))
+#define interruptible_sleep_on_timeout(w,t) \
+ ({(current->timeout=jiffies+(t));wsleep(w);current->timeout;})
+#define schedule_timeout(t) \
+ do { current->timeout = jiffies+(t); schedule(); } while (0)
+#endif
+
+#include <asm/io.h>
+#ifndef readw_ns
+#ifdef __powerpc__
+#define readw_ns(p) ld_be16((volatile unsigned short *)(p))
+#define readl_ns(p) ld_be32((volatile unsigned *)(p))
+#define writew_ns(v,p) st_le16((volatile unsigned short *)(p),(v))
+#define writel_ns(v,p) st_le32((volatile unsigned *)(p),(v))
+#define inw_ns(p) in_be16((unsigned short *)((p)+_IO_BASE))
+#define inl_ns(p) in_be32((unsigned *)((p)+_IO_BASE))
+#define outw_ns(v,p) out_be16((unsigned short *)((p)+_IO_BASE),(v))
+#define outl_ns(v,p) out_be32((unsigned *)((p)+_IO_BASE),(v))
+#else
+#define readw_ns(p) readw(p)
+#define readl_ns(p) readl(p)
+#define writew_ns(v,p) writew(v,p)
+#define writel_ns(v,p) writel(v,p)
+#define inw_ns(p) inw(p)
+#define inl_ns(p) inl(p)
+#define outw_ns(v,p) outw(v,p)
+#define outl_ns(v,p) outl(v,p)
+#endif
+#endif
+#ifndef insw_ns
+#define insw_ns(p,b,l) insw(p,b,l)
+#define insl_ns(p,b,l) insl(p,b,l)
+#define outsw_ns(p,b,l) outsw(p,b,l)
+#define outsl_ns(p,b,l) outsl(p,b,l)
+#endif
+
+#if (LINUX_VERSION_CODE < VERSION(2,1,93))
+#include <linux/bios32.h>
+#endif
+#include <linux/pci.h>
+#ifndef PCI_FUNC
+#define PCI_FUNC(devfn) ((devfn)&7)
+#define PCI_SLOT(devfn) ((devfn)>>3)
+#define PCI_DEVFN(dev,fn) (((dev)<<3)|((fn)&7))
+#endif
+
+#if (LINUX_VERSION_CODE > VERSION(2,1,117))
+#define NULL_FLUSH NULL,
+#else
+#define NULL_FLUSH
+#endif
+
+#if (LINUX_VERSION_CODE < VERSION(2,1,126))
+#define SCSI_DISK0_MAJOR SCSI_DISK_MAJOR
+#endif
+
+typedef unsigned long k_time_t;
+#define ACQUIRE_RESOURCE_LOCK do {} while (0)
+#define RELEASE_RESOURCE_LOCK do {} while (0)
+
+#endif /* _LINUX_K_COMPAT_H */
diff --git a/klaptopdaemon/linux/mem_op.h b/klaptopdaemon/linux/mem_op.h
new file mode 100644
index 0000000..85f1ba2
--- /dev/null
+++ b/klaptopdaemon/linux/mem_op.h
@@ -0,0 +1,120 @@
+/*
+ * mem_op.h 1.8 1998/07/17 10:12:23
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * The initial developer of the original code is David A. Hinds
+ * <dhinds@hyper.stanford.edu>. Portions created by David A. Hinds
+ * are Copyright (C) 1998 David A. Hinds. All Rights Reserved.
+ */
+
+#ifndef _LINUX_MEM_OP_H
+#define _LINUX_MEM_OP_H
+
+/*
+ If UNSAFE_MEMCPY is defined, we use the (optimized) system routines
+ to copy between a card and kernel memory. These routines do 32-bit
+ operations which may not work with all PCMCIA controllers. The
+ safe versions defined here will do only 8-bit and 16-bit accesses.
+*/
+
+#ifdef UNSAFE_MEMCPY
+
+#define copy_from_pc memcpy_fromio
+#define copy_to_pc memcpy_toio
+
+static inline void copy_pc_to_user(void *to, const void *from, size_t n)
+{
+ size_t odd = (n & 3);
+ n -= odd;
+ while (n) {
+ put_user(readl_ns(from), (int *)to);
+ (char *)from += 4; (char *)to += 4; n -= 4;
+ }
+ while (odd--)
+ put_user(readb((char *)from++), (char *)to++);
+}
+
+static inline void copy_user_to_pc(void *to, const void *from, size_t n)
+{
+ int l;
+ char c;
+ size_t odd = (n & 3);
+ n -= odd;
+ while (n) {
+ get_user(l, (int *)from);
+ writel_ns(l, to);
+ (char *)to += 4; (char *)from += 4; n -= 4;
+ }
+ while (odd--) {
+ get_user(c, (char *)from++);
+ writeb(c, (char *)to++);
+ }
+}
+
+#else /* UNSAFE_MEMCPY */
+
+static inline void copy_from_pc(void *to, const void *from, size_t n)
+{
+ size_t odd = (n & 1);
+ n -= odd;
+ while (n) {
+ *(u_short *)to = readw_ns(from);
+ (char *)to += 2; (char *)from += 2; n -= 2;
+ }
+ if (odd)
+ *(u_char *)to = readb(from);
+}
+
+static inline void copy_to_pc(void *to, const void *from, size_t n)
+{
+ size_t odd = (n & 1);
+ n -= odd;
+ while (n) {
+ writew_ns(*(u_short *)from, to);
+ (char *)to += 2; (char *)from += 2; n -= 2;
+ }
+ if (odd)
+ writeb(*(u_char *)from, to);
+}
+
+static inline void copy_pc_to_user(void *to, const void *from, size_t n)
+{
+ size_t odd = (n & 1);
+ n -= odd;
+ while (n) {
+ put_user(readw_ns(from), (short *)to);
+ (char *)to += 2; (char *)from += 2; n -= 2;
+ }
+ if (odd)
+ put_user(readb(from), (char *)to);
+}
+
+static inline void copy_user_to_pc(void *to, const void *from, size_t n)
+{
+ short s;
+ char c;
+ size_t odd = (n & 1);
+ n -= odd;
+ while (n) {
+ get_user(s, (short *)from);
+ writew_ns(s, to);
+ (char *)to += 2; (char *)from += 2; n -= 2;
+ }
+ if (odd) {
+ get_user(c, (char *)from);
+ writeb(c, to);
+ }
+}
+
+#endif /* UNSAFE_MEMCPY */
+
+#endif /* _LINUX_MEM_OP_H */
diff --git a/klaptopdaemon/linux/memory.h b/klaptopdaemon/linux/memory.h
new file mode 100644
index 0000000..d7aa9de
--- /dev/null
+++ b/klaptopdaemon/linux/memory.h
@@ -0,0 +1,30 @@
+/*
+ * memory.h 1.3 1998/05/10 12:10:34
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * The initial developer of the original code is David A. Hinds
+ * <dhinds@hyper.stanford.edu>. Portions created by David A. Hinds
+ * are Copyright (C) 1998 David A. Hinds. All Rights Reserved.
+ */
+
+#ifndef _LINUX_MEMORY_H
+#define _LINUX_MEMORY_H
+
+typedef struct erase_info_t {
+ u_long Offset;
+ u_long Size;
+} erase_info_t;
+
+#define MEMGETINFO _IOR('M', 1, region_info_t)
+#define MEMERASE _IOW('M', 2, erase_info_t)
+
+#endif /* _LINUX_MEMORY_H */
diff --git a/klaptopdaemon/linux/ss.h b/klaptopdaemon/linux/ss.h
new file mode 100644
index 0000000..57ad769
--- /dev/null
+++ b/klaptopdaemon/linux/ss.h
@@ -0,0 +1,113 @@
+/*
+ * ss.h 1.18 1998/10/01 20:54:49
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * The initial developer of the original code is David A. Hinds
+ * <dhinds@hyper.stanford.edu>. Portions created by David A. Hinds
+ * are Copyright (C) 1998 David A. Hinds. All Rights Reserved.
+ */
+
+#ifndef _LINUX_SS_H
+#define _LINUX_SS_H
+
+/* For RegisterCallback */
+typedef struct ss_callback_t {
+ void (*handler)(void *info, u_int events);
+ void *info;
+} ss_callback_t;
+
+/* Definitions for card status flags for GetStatus */
+#define SS_WRPROT 0x0001
+#define SS_CARDLOCK 0x0002
+#define SS_EJECTION 0x0004
+#define SS_INSERTION 0x0008
+#define SS_BATDEAD 0x0010
+#define SS_BATWARN 0x0020
+#define SS_READY 0x0040
+#define SS_DETECT 0x0080
+#define SS_POWERON 0x0100
+#define SS_GPI 0x0200
+#define SS_STSCHG 0x0400
+#define SS_CARDBUS 0x0800
+#define SS_3VCARD 0x1000
+#define SS_XVCARD 0x2000
+
+/* for InquireSocket */
+typedef struct socket_cap_t {
+ u_int features;
+ u_int irq_mask;
+ u_int map_size;
+ u_char pci_irq;
+ u_char cardbus;
+} socket_cap_t;
+
+/* InquireSocket features */
+#define SS_HAS_PAGE_REGS 0x0001
+
+/* for GetSocket, SetSocket */
+typedef struct socket_state_t {
+ u_int flags;
+ u_int csc_mask;
+ u_char Vcc, Vpp;
+ u_char io_irq;
+} socket_state_t;
+
+/* Various card configuration flags */
+#define SS_PWR_AUTO 0x0010
+#define SS_IOCARD 0x0020
+#define SS_RESET 0x0040
+#define SS_DMA_MODE 0x0080
+#define SS_SPKR_ENA 0x0100
+#define SS_OUTPUT_ENA 0x0200
+
+/* Flags for I/O port and memory windows */
+#define MAP_ACTIVE 0x01
+#define MAP_16BIT 0x02
+#define MAP_AUTOSZ 0x04
+#define MAP_0WS 0x08
+#define MAP_WRPROT 0x10
+#define MAP_ATTRIB 0x20
+#define MAP_USE_WAIT 0x40
+#define MAP_PREFETCH 0x80
+
+/* Use this just for bridge windows */
+#define MAP_IOSPACE 0x20
+
+typedef struct pccard_io_map {
+ u_char map;
+ u_char flags;
+ u_short speed;
+ u_short start, stop;
+} pccard_io_map;
+
+typedef struct pccard_mem_map {
+ u_char map;
+ u_char flags;
+ u_short speed;
+ u_long sys_start, sys_stop;
+ u_int card_start;
+} pccard_mem_map;
+
+typedef struct cb_bridge_map {
+ u_char map;
+ u_char flags;
+ u_int start, stop;
+} cb_bridge_map;
+
+enum ss_service {
+ SS_RegisterCallback, SS_InquireSocket,
+ SS_GetStatus, SS_GetSocket, SS_SetSocket,
+ SS_GetIOMap, SS_SetIOMap, SS_GetMemMap, SS_SetMemMap,
+ SS_GetBridge, SS_SetBridge, SS_ProcSetup
+};
+
+#endif /* _LINUX_SS_H */
diff --git a/klaptopdaemon/linux/version.h b/klaptopdaemon/linux/version.h
new file mode 100644
index 0000000..86f556e
--- /dev/null
+++ b/klaptopdaemon/linux/version.h
@@ -0,0 +1,4 @@
+/* version.h 1.55 1998/02/25 22:21:07 (David Hinds) */
+
+#define CS_RELEASE "3.0.9"
+#define CS_RELEASE_CODE 0x3009
diff --git a/klaptopdaemon/main.cpp b/klaptopdaemon/main.cpp
new file mode 100644
index 0000000..9dc0419
--- /dev/null
+++ b/klaptopdaemon/main.cpp
@@ -0,0 +1,305 @@
+/*
+ * main.cpp
+ *
+ * Copyright (c) 1999 Paul Campbell <paul@taniwha.com>
+ *
+ * Requires the Qt widget libraries, available at no cost at
+ * http://www.troll.no/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#include <klocale.h>
+#include <kprocess.h>
+#include <kconfig.h>
+#include <kglobal.h>
+#include <qlayout.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "main.h"
+#include "version.h"
+#include "warning.h"
+#include "power.h"
+#include "battery.h"
+#include "buttons.h"
+#include "pcmcia.h"
+#include "acpi.h"
+#include "apm.h"
+#include "sony.h"
+#include "profile.h"
+#include "portable.h"
+extern void wake_laptop_daemon();
+
+
+extern "C"
+{
+
+ KDE_EXPORT KCModule *create_pcmcia(QWidget *parent, const char *)
+ {
+ return new PcmciaConfig(parent, "kcmlaptop");
+ }
+
+ KDE_EXPORT KCModule *create_bwarning(QWidget *parent, const char *)
+ {
+ return new WarningConfig(0, parent, "kcmlaptop");
+ }
+ KDE_EXPORT KCModule *create_cwarning(QWidget *parent, const char *)
+ {
+ return new WarningConfig(1, parent, "kcmlaptop");
+ }
+ KDE_EXPORT KCModule *create_battery(QWidget *parent, const char *)
+ {
+ return new BatteryConfig(parent, "kcmlaptop");
+ }
+ KDE_EXPORT KCModule *create_power(QWidget *parent, const char *)
+ {
+ return new PowerConfig(parent, "kcmlaptop");
+ }
+ KDE_EXPORT KCModule *create_acpi(QWidget *parent, const char *)
+ {
+ return new AcpiConfig(parent, "kcmlaptop");
+ }
+ KDE_EXPORT KCModule *create_apm(QWidget *parent, const char *)
+ {
+ return new ApmConfig(parent, "kcmlaptop");
+ }
+ KDE_EXPORT KCModule *create_Profile(QWidget *parent, const char *)
+ {
+ return new ProfileConfig(parent, "kcmlaptop");
+ }
+ KDE_EXPORT KCModule *create_sony(QWidget *parent, const char *)
+ {
+ return new SonyConfig(parent, "kcmlaptop");
+ }
+ KDE_EXPORT KCModule *create_buttons(QWidget *parent, const char *)
+ {
+ return new ButtonsConfig(parent, "kcmlaptop");
+ }
+
+ KDE_EXPORT void init_battery()
+ {
+ KConfig config("kcmlaptoprc", true /*readonly*/, false /*no globals*/);
+ config.setGroup("BatteryDefault");
+ bool enable = false;
+ if (!config.hasKey("Enable")) { // if they have APM or PCMCIA, Enable=true
+ struct power_result pr = laptop_portable::poll_battery_state();
+ if ((laptop_portable::has_power_management() &&
+ !(pr.powered &&
+ (pr.percentage < 0 || pr.percentage == 0xff)))||
+ 0 == access("/var/run/stab", R_OK|F_OK) ||
+ 0 == access("/var/lib/pcmcia/stab", R_OK|F_OK))
+ enable = true;
+ } else {
+ enable = config.readBoolEntry("Enable", false);
+ }
+ if (!enable)
+ return;
+ wake_laptop_daemon();
+ }
+
+ KDE_EXPORT KCModule *create_laptop(QWidget *parent, const char *)
+ {
+ return new LaptopModule(parent, "kcmlaptop");
+ }
+
+ KDE_EXPORT void init_laptop()
+ {
+ init_battery();
+ }
+}
+
+
+
+LaptopModule::LaptopModule(QWidget *parent, const char *)
+ : KCModule(parent, "kcmlaptop")
+{
+ { // export ACPI options
+ KConfig config("kcmlaptoprc", true /*readonly*/, false /*no globals*/);
+ config.setGroup("AcpiDefault");
+
+ bool enablestandby = config.readBoolEntry("EnableStandby", false);
+ bool enablesuspend = config.readBoolEntry("EnableSuspend", false);
+ bool enablehibernate = config.readBoolEntry("EnableHibernate", false);
+ bool enableperformance = config.readBoolEntry("EnablePerformance", false);
+ bool enablethrottle = config.readBoolEntry("EnableThrottle", false);
+ laptop_portable::acpi_set_mask(enablestandby, enablesuspend, enablehibernate, enableperformance, enablethrottle);
+
+ config.setGroup("ApmDefault");
+
+ enablestandby = config.readBoolEntry("EnableStandby", false);
+ enablesuspend = config.readBoolEntry("EnableSuspend", false);
+ laptop_portable::apm_set_mask(enablestandby, enablesuspend);
+ config.setGroup("SoftwareSuspendDefault");
+ enablehibernate = config.readBoolEntry("EnableHibernate", false);
+ laptop_portable::software_suspend_set_mask(enablehibernate);
+ }
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ tab = new QTabWidget(this);
+ layout->addWidget(tab);
+
+ battery = new BatteryConfig(parent, "kcmlaptop");
+ tab->addTab(battery, i18n("&Battery"));
+ connect(battery, SIGNAL(changed(bool)), this, SLOT(moduleChanged(bool)));
+
+ power = new PowerConfig(parent, "kcmlaptop");
+ tab->addTab(power, i18n("&Power Control"));
+ connect(power, SIGNAL(changed(bool)), this, SLOT(moduleChanged(bool)));
+
+ warning = new WarningConfig(0, parent, "kcmlaptop");
+ tab->addTab(warning, i18n("Low Battery &Warning"));
+ connect(warning, SIGNAL(changed(bool)), this, SLOT(moduleChanged(bool)));
+
+ critical = new WarningConfig(1, parent, "kcmlaptop");
+ tab->addTab(critical, i18n("Low Battery &Critical"));
+ connect(critical, SIGNAL(changed(bool)), this, SLOT(moduleChanged(bool)));
+
+ QStringList profile_list;
+ int current_profile;
+ bool *active_list;
+ bool has_profile = laptop_portable::get_system_performance(0, current_profile, profile_list, active_list);
+ QStringList throttle_list;
+ int current_throttle;
+ bool has_throttling = laptop_portable::get_system_throttling(0, current_throttle, throttle_list, active_list);
+ if (laptop_portable::has_brightness() || has_profile || has_throttling) {
+ profile = new ProfileConfig(parent, "kcmlaptop");
+ tab->addTab(profile, i18n("Default Power Profiles"));
+ connect(profile, SIGNAL(changed(bool)), this, SLOT(moduleChanged(bool)));
+ } else {
+ profile = 0;
+ }
+ if (laptop_portable::has_button(laptop_portable::LidButton) || laptop_portable::has_button(laptop_portable::PowerButton)) {
+ buttons = new ButtonsConfig(parent, "kcmlaptop");
+ tab->addTab(buttons, i18n("Button Actions"));
+ connect(buttons, SIGNAL(changed(bool)), this, SLOT(moduleChanged(bool)));
+ } else {
+ buttons = 0;
+ }
+ if (laptop_portable::has_acpi()) {
+ acpi = new AcpiConfig(parent, "kcmlaptop");
+ tab->addTab(acpi, i18n("&ACPI Config"));
+ connect(acpi, SIGNAL(changed(bool)), this, SLOT(moduleChanged(bool)));
+ } else {
+ acpi = 0;
+ }
+ if (laptop_portable::has_apm()) {
+ apm = new ApmConfig(parent, "kcmlaptop");
+ tab->addTab(apm, i18n("&APM Config"));
+ connect(apm, SIGNAL(changed(bool)), this, SLOT(moduleChanged(bool)));
+ } else {
+ apm = 0;
+ }
+ if (::access("/dev/sonypi", F_OK) == 0) {
+ bool do_sony = 1;
+ if (::access("/dev/sonypi", R_OK) == 0) {
+ int fd = ::open("/dev/sonypi", O_RDONLY); // make sure the driver's there as well as the /dev inode
+ if (fd >= 0) {
+ ::close(fd);
+ } else {
+ do_sony = 0;
+ }
+ }
+ if (do_sony) {
+ sony = new SonyConfig(parent, "kcmlaptop");
+ tab->addTab(sony, i18n("&Sony Laptop Config"));
+ connect(sony, SIGNAL(changed(bool)), this, SLOT(moduleChanged(bool)));
+ } else {
+ sony = 0;
+ }
+ } else {
+ sony = 0;
+ }
+
+ KAboutData* about =
+ new KAboutData("kcmlaptop", I18N_NOOP("Laptop Battery Configuration"), LAPTOP_VERSION,
+ I18N_NOOP("Battery Control Panel Module"),
+ KAboutData::License_GPL,
+ I18N_NOOP("(c) 1999 Paul Campbell"), 0, 0);
+ //about->addAuthor("NAME", 0, "e-mail addy");
+ setAboutData( about );
+}
+
+void LaptopModule::load()
+{
+ battery->load();
+ warning->load();
+ critical->load();
+ power->load();
+ if (apm)
+ apm->load();
+ if (acpi)
+ acpi->load();
+ if (profile)
+ profile->load();
+ if (sony)
+ sony->load();
+ if (buttons)
+ buttons->load();
+}
+
+void LaptopModule::save()
+{
+ battery->save();
+ warning->save();
+ critical->save();
+ power->save();
+ if (profile)
+ profile->save();
+ if (acpi)
+ acpi->save();
+ if (apm)
+ apm->save();
+ if (sony)
+ sony->save();
+ if (buttons)
+ buttons->save();
+}
+
+
+void LaptopModule::defaults()
+{
+ battery->defaults();
+ warning->defaults();
+ critical->defaults();
+ power->defaults();
+ if (acpi)
+ acpi->defaults();
+ if (apm)
+ apm->defaults();
+ if (profile)
+ profile->defaults();
+ if (sony)
+ sony->defaults();
+ if (buttons)
+ buttons->defaults();
+}
+
+QString LaptopModule::quickHelp() const
+{
+ return i18n("<h1>Laptop Battery</h1>This module allows you to monitor "
+ "your batteries. To make use of this module, you must have power management software "
+ "installed. (And, of course, you should have batteries in your "
+ "machine.)");
+}
+
+
+void LaptopModule::moduleChanged(bool state)
+{
+ emit changed(state);
+}
+
+
+#include "main.moc"
diff --git a/klaptopdaemon/main.h b/klaptopdaemon/main.h
new file mode 100644
index 0000000..81d6e41
--- /dev/null
+++ b/klaptopdaemon/main.h
@@ -0,0 +1,82 @@
+/*
+ * main.h
+ *
+ * Copyright (c) 2002 Paul Campbell paul@taniwha.com
+ *
+ * Requires the Qt widget libraries, available at no cost at
+ * http://www.troll.no/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef __MAIN_H__
+#define __MAIN_H__
+
+
+#include <qtabwidget.h>
+
+
+#include <kcmodule.h>
+
+
+class WarningConfig;
+class BatteryConfig;
+class PowerConfig;
+class AcpiConfig;
+class ApmConfig;
+class SonyConfig;
+class ProfileConfig;
+class ButtonsConfig;
+
+class LaptopModule : public KCModule
+{
+ Q_OBJECT
+
+public:
+
+ LaptopModule(QWidget *parent, const char *name);
+
+ void load();
+ void save();
+ void defaults();
+ QString quickHelp() const;
+
+
+
+protected slots:
+
+ void moduleChanged(bool state);
+
+
+private:
+
+ QTabWidget *tab;
+
+ WarningConfig *warning;
+ WarningConfig *critical;
+ BatteryConfig *battery;
+ PowerConfig *power;
+ AcpiConfig *acpi;
+ ApmConfig *apm;
+ ProfileConfig *profile;
+ SonyConfig *sony;
+ ButtonsConfig *buttons;
+};
+
+
+#endif
+
+
diff --git a/klaptopdaemon/makecrc.cpp b/klaptopdaemon/makecrc.cpp
new file mode 100644
index 0000000..ce3d415
--- /dev/null
+++ b/klaptopdaemon/makecrc.cpp
@@ -0,0 +1,38 @@
+/*
+ * makecrc.cpp
+ *
+ * Copyright (c) 2003 Paul Campbell <paul@taniwha.com>
+ * Requires the Qt widget libraries, available at no cost at
+ * http://www.troll.no/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+
+
+#include "checkcrc.h"
+
+int main(int, char**)
+{
+ unsigned long len, crc;
+ checkcrc("./klaptop_acpi_helper", len, crc);
+ printf("#ifndef _CRCRESULT_H_\n");
+ printf("#define _CRCRESULT_H_\n");
+ printf("static unsigned long file_len = 0x%lx;\n", len);
+ printf("static unsigned long file_crc = 0x%lx;\n", crc);
+ printf("#endif\n");
+ return(0);
+}
diff --git a/klaptopdaemon/pcmcia.cpp b/klaptopdaemon/pcmcia.cpp
new file mode 100644
index 0000000..ed17789
--- /dev/null
+++ b/klaptopdaemon/pcmcia.cpp
@@ -0,0 +1,122 @@
+/*
+ * pcmcia.cpp
+ *
+ * Copyright (c) 1999 Paul Campbell <paul@taniwha.com>
+ *
+ * Requires the Qt widget libraries, available at no cost at
+ * http://www.troll.no/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+
+#include <qfileinfo.h>
+#include <qlayout.h>
+
+#include <kglobal.h>
+#include <klocale.h>
+#include <stdio.h>
+
+#include "pcmcia.h"
+#include "portable.h"
+#include "version.h"
+
+PcmciaConfig::PcmciaConfig (QWidget * parent, const char *name)
+ : KCModule(parent, name)
+{
+ KAboutData *about =
+ new KAboutData(I18N_NOOP("kcmlaptop"),
+ I18N_NOOP("KDE Panel System Information Control Module"),
+ 0, 0, KAboutData::License_GPL,
+ I18N_NOOP("(c) 1999 - 2002 Paul Campbell"));
+ about->addAuthor("Paul Campbell", 0, "paul@taniwha.com");
+ setAboutData( about );
+
+ KGlobal::locale()->insertCatalogue("klaptopdaemon"); // For translation of klaptopdaemon messages
+
+ label0 = laptop_portable::pcmcia_info(0, this);
+ label0_text = laptop_portable::pcmcia_info(1, this);
+ label1 = laptop_portable::pcmcia_info(2, this);
+ label1_text = laptop_portable::pcmcia_info(3, this);
+
+
+ QVBoxLayout *top_layout = new QVBoxLayout(this, 15, 5);
+ QGridLayout *top_grid = new QGridLayout(2, 2);
+ top_layout->addLayout(top_grid);
+
+ top_grid->setColStretch(0, 0);
+ top_grid->setColStretch(1, 1);
+ top_grid->addRowSpacing(0, 40);
+ top_grid->addRowSpacing(1, 40);
+
+ label0->setFixedSize(80, 24);
+ top_grid->addWidget(label0, 0, 0);
+ label0_text->adjustSize();
+ top_grid->addWidget(label0_text, 0, 1);
+
+ label1->setFixedSize(80, 24);
+ top_grid->addWidget(label1, 1, 0);
+ label1_text->adjustSize();
+ top_grid->addWidget(label1_text, 1, 1);
+
+
+ top_layout->addStretch(1);
+
+ QHBoxLayout *v1 = new QHBoxLayout;
+ top_layout->addLayout(v1, 0);
+ v1->addStretch(1);
+ QString s1 = LAPTOP_VERSION;
+ QString s2 = i18n("Version: ")+s1;
+ QLabel* vers = new QLabel(s2, this);
+ vers->setMinimumSize(vers->sizeHint());
+ v1->addWidget(vers, 0);
+
+ top_layout->activate();
+
+ load();
+ setButtons(Help);
+}
+
+
+void PcmciaConfig::save()
+{
+}
+
+void PcmciaConfig::load()
+{
+}
+
+void PcmciaConfig::defaults()
+{
+}
+
+
+void PcmciaConfig::changed()
+{
+ emit KCModule::changed(true);
+}
+
+
+QString PcmciaConfig::quickHelp() const
+{
+ return i18n("<h1>PCMCIA Config</h1>This module shows information about "
+ "the PCMCIA cards in your system, if there are PCMCIA cards.");
+}
+
+#include "pcmcia.moc"
diff --git a/klaptopdaemon/pcmcia.h b/klaptopdaemon/pcmcia.h
new file mode 100644
index 0000000..e163742
--- /dev/null
+++ b/klaptopdaemon/pcmcia.h
@@ -0,0 +1,70 @@
+/*
+ * pcmcia.h
+ *
+ * Copyright (c) 1999 Paul Campbell <paul@taniwha.com>
+ *
+ * Requires the Qt widget libraries, available at no cost at
+ * http://www.troll.no/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef __PCMCIACONFIG_H__
+#define __PCMCIACONFIG_H__
+
+#include <qdialog.h>
+#include <qpushbutton.h>
+#include <qlabel.h>
+#include <qlcdnumber.h>
+#include <qradiobutton.h>
+#include <qbuttongroup.h>
+
+#include <kapplication.h>
+#include <knuminput.h>
+
+#include <kcmodule.h>
+#include <kaboutdata.h>
+
+class PcmciaConfig : public KCModule
+{
+ Q_OBJECT
+public:
+ PcmciaConfig( QWidget *parent=0, const char* name=0);
+
+ void save( void );
+ void load();
+ void defaults();
+
+ virtual QString quickHelp() const;
+
+private slots:
+
+ void changed();
+
+
+private:
+ void GetSettings( void );
+
+ QLabel *label0;
+ QLabel *label1;
+ QLabel *label0_text;
+ QLabel *label1_text;
+
+
+};
+
+#endif
+
diff --git a/klaptopdaemon/pics/Makefile.am b/klaptopdaemon/pics/Makefile.am
new file mode 100644
index 0000000..2828fc2
--- /dev/null
+++ b/klaptopdaemon/pics/Makefile.am
@@ -0,0 +1,6 @@
+# $Id$
+# kdebase/kcontrol/input/pics
+SUBDIRS = actions
+
+KDE_ICON = laptop_battery laptop laptop_pcmcia klaptopdaemon
+
diff --git a/klaptopdaemon/pics/README b/klaptopdaemon/pics/README
new file mode 100644
index 0000000..29a1b13
--- /dev/null
+++ b/klaptopdaemon/pics/README
@@ -0,0 +1,36 @@
+Notes about laptop daemon's icons:
+
+ lo16-app-klaptopdaemon.png - is only used for the context menu
+ only the 16x16 is actually needed
+
+ in fact with recent changes to the iconloader icons other than
+ the 16x16 (really 20x20) are BAD - please don't create them
+
+ the 3 icons in the action directory:
+ laptop_charge/laptop_concharge/laptop_nobattery
+
+ are 'special' - they are read by the application and
+ modified on-the-fly to create a bar-graph of how full
+ the battery is - you can't just edit them the way you would
+ a normal icon - basically any white pixels will be replaced
+ with a proportional number of blue ones from the bottom of
+ the icon to the top (so pure white pixels are 'magic' and
+ should be treated as the portion of the icon that is the graph)
+ you can use slightly off-white or a not-quite-saturated
+ white if you want 'white'
+
+ I'd love some cool new battery icons but please contact me
+ if you need some testing before committing
+
+
+
+ Paul Campbell - laptop support author
+ paul@taniwha.com
+
+We also have some contributed icons:
+
+the 2 'alt_' ones came from Percy Leonhardt <percy at eris23.de>
+the 3 'alt2_' ones came from Keunwoo Lee <klee at cs.washington.edu>
+the 2 'alt3_' ones came from Jason Dixon <jasondixon at myrealbox.com>
+
+thanks guys!
diff --git a/klaptopdaemon/pics/actions/Makefile.am b/klaptopdaemon/pics/actions/Makefile.am
new file mode 100644
index 0000000..4f9cf71
--- /dev/null
+++ b/klaptopdaemon/pics/actions/Makefile.am
@@ -0,0 +1,3 @@
+klaptopdaemoniconsdir = $(kde_datadir)/klaptopdaemon/icons
+klaptopdaemonicons_ICON = AUTO
+
diff --git a/klaptopdaemon/pics/actions/cr16-action-alt2_laptop_nobattery.png b/klaptopdaemon/pics/actions/cr16-action-alt2_laptop_nobattery.png
new file mode 100644
index 0000000..3018b38
--- /dev/null
+++ b/klaptopdaemon/pics/actions/cr16-action-alt2_laptop_nobattery.png
Binary files differ
diff --git a/klaptopdaemon/pics/actions/cr16-action-alt2_laptop_nocharge.png b/klaptopdaemon/pics/actions/cr16-action-alt2_laptop_nocharge.png
new file mode 100644
index 0000000..6c4951b
--- /dev/null
+++ b/klaptopdaemon/pics/actions/cr16-action-alt2_laptop_nocharge.png
Binary files differ
diff --git a/klaptopdaemon/pics/actions/cr16-action-alt2_laptop_power.png b/klaptopdaemon/pics/actions/cr16-action-alt2_laptop_power.png
new file mode 100644
index 0000000..743d809
--- /dev/null
+++ b/klaptopdaemon/pics/actions/cr16-action-alt2_laptop_power.png
Binary files differ
diff --git a/klaptopdaemon/pics/actions/cr16-action-alt3_laptop_nocharge.png b/klaptopdaemon/pics/actions/cr16-action-alt3_laptop_nocharge.png
new file mode 100644
index 0000000..fd3e6ff
--- /dev/null
+++ b/klaptopdaemon/pics/actions/cr16-action-alt3_laptop_nocharge.png
Binary files differ
diff --git a/klaptopdaemon/pics/actions/cr16-action-alt3_laptop_power.png b/klaptopdaemon/pics/actions/cr16-action-alt3_laptop_power.png
new file mode 100644
index 0000000..87962a6
--- /dev/null
+++ b/klaptopdaemon/pics/actions/cr16-action-alt3_laptop_power.png
Binary files differ
diff --git a/klaptopdaemon/pics/actions/cr16-action-alt_laptop_nocharge.png b/klaptopdaemon/pics/actions/cr16-action-alt_laptop_nocharge.png
new file mode 100644
index 0000000..8a257fd
--- /dev/null
+++ b/klaptopdaemon/pics/actions/cr16-action-alt_laptop_nocharge.png
Binary files differ
diff --git a/klaptopdaemon/pics/actions/cr16-action-alt_laptop_power.png b/klaptopdaemon/pics/actions/cr16-action-alt_laptop_power.png
new file mode 100644
index 0000000..211b5f6
--- /dev/null
+++ b/klaptopdaemon/pics/actions/cr16-action-alt_laptop_power.png
Binary files differ
diff --git a/klaptopdaemon/pics/actions/cr16-action-laptop_charge.png b/klaptopdaemon/pics/actions/cr16-action-laptop_charge.png
new file mode 100644
index 0000000..717d37f
--- /dev/null
+++ b/klaptopdaemon/pics/actions/cr16-action-laptop_charge.png
Binary files differ
diff --git a/klaptopdaemon/pics/actions/cr16-action-laptop_nobattery.png b/klaptopdaemon/pics/actions/cr16-action-laptop_nobattery.png
new file mode 100644
index 0000000..7c6b8bc
--- /dev/null
+++ b/klaptopdaemon/pics/actions/cr16-action-laptop_nobattery.png
Binary files differ
diff --git a/klaptopdaemon/pics/actions/cr16-action-laptop_nocharge.png b/klaptopdaemon/pics/actions/cr16-action-laptop_nocharge.png
new file mode 100644
index 0000000..e5e8418
--- /dev/null
+++ b/klaptopdaemon/pics/actions/cr16-action-laptop_nocharge.png
Binary files differ
diff --git a/klaptopdaemon/pics/actions/cr16-action-power.png b/klaptopdaemon/pics/actions/cr16-action-power.png
new file mode 100644
index 0000000..ac7deec
--- /dev/null
+++ b/klaptopdaemon/pics/actions/cr16-action-power.png
Binary files differ
diff --git a/klaptopdaemon/pics/actions/cr22-action-laptop_charge.png b/klaptopdaemon/pics/actions/cr22-action-laptop_charge.png
new file mode 100644
index 0000000..4a9fad1
--- /dev/null
+++ b/klaptopdaemon/pics/actions/cr22-action-laptop_charge.png
Binary files differ
diff --git a/klaptopdaemon/pics/actions/cr22-action-laptop_nobattery.png b/klaptopdaemon/pics/actions/cr22-action-laptop_nobattery.png
new file mode 100644
index 0000000..07e9f0d
--- /dev/null
+++ b/klaptopdaemon/pics/actions/cr22-action-laptop_nobattery.png
Binary files differ
diff --git a/klaptopdaemon/pics/actions/cr22-action-laptop_nocharge.png b/klaptopdaemon/pics/actions/cr22-action-laptop_nocharge.png
new file mode 100644
index 0000000..1eda606
--- /dev/null
+++ b/klaptopdaemon/pics/actions/cr22-action-laptop_nocharge.png
Binary files differ
diff --git a/klaptopdaemon/pics/actions/cr22-action-laptop_power.png b/klaptopdaemon/pics/actions/cr22-action-laptop_power.png
new file mode 100644
index 0000000..92b6328
--- /dev/null
+++ b/klaptopdaemon/pics/actions/cr22-action-laptop_power.png
Binary files differ
diff --git a/klaptopdaemon/pics/actions/cr32-action-power.png b/klaptopdaemon/pics/actions/cr32-action-power.png
new file mode 100644
index 0000000..e785191
--- /dev/null
+++ b/klaptopdaemon/pics/actions/cr32-action-power.png
Binary files differ
diff --git a/klaptopdaemon/pics/cr128-app-laptop_battery.png b/klaptopdaemon/pics/cr128-app-laptop_battery.png
new file mode 100644
index 0000000..48561f6
--- /dev/null
+++ b/klaptopdaemon/pics/cr128-app-laptop_battery.png
Binary files differ
diff --git a/klaptopdaemon/pics/cr16-app-laptop_battery.png b/klaptopdaemon/pics/cr16-app-laptop_battery.png
new file mode 100644
index 0000000..7deaf05
--- /dev/null
+++ b/klaptopdaemon/pics/cr16-app-laptop_battery.png
Binary files differ
diff --git a/klaptopdaemon/pics/cr16-app-laptop_pcmcia.png b/klaptopdaemon/pics/cr16-app-laptop_pcmcia.png
new file mode 100644
index 0000000..e8eda78
--- /dev/null
+++ b/klaptopdaemon/pics/cr16-app-laptop_pcmcia.png
Binary files differ
diff --git a/klaptopdaemon/pics/cr32-app-laptop_battery.png b/klaptopdaemon/pics/cr32-app-laptop_battery.png
new file mode 100644
index 0000000..5358826
--- /dev/null
+++ b/klaptopdaemon/pics/cr32-app-laptop_battery.png
Binary files differ
diff --git a/klaptopdaemon/pics/cr32-app-laptop_pcmcia.png b/klaptopdaemon/pics/cr32-app-laptop_pcmcia.png
new file mode 100644
index 0000000..534e548
--- /dev/null
+++ b/klaptopdaemon/pics/cr32-app-laptop_pcmcia.png
Binary files differ
diff --git a/klaptopdaemon/pics/cr48-app-laptop_battery.png b/klaptopdaemon/pics/cr48-app-laptop_battery.png
new file mode 100644
index 0000000..4038d44
--- /dev/null
+++ b/klaptopdaemon/pics/cr48-app-laptop_battery.png
Binary files differ
diff --git a/klaptopdaemon/pics/cr48-app-laptop_pcmcia.png b/klaptopdaemon/pics/cr48-app-laptop_pcmcia.png
new file mode 100644
index 0000000..faad8ff
--- /dev/null
+++ b/klaptopdaemon/pics/cr48-app-laptop_pcmcia.png
Binary files differ
diff --git a/klaptopdaemon/pics/cr64-app-laptop_battery.png b/klaptopdaemon/pics/cr64-app-laptop_battery.png
new file mode 100644
index 0000000..8a6a92d
--- /dev/null
+++ b/klaptopdaemon/pics/cr64-app-laptop_battery.png
Binary files differ
diff --git a/klaptopdaemon/pics/crsc-app-laptop_battery.svgz b/klaptopdaemon/pics/crsc-app-laptop_battery.svgz
new file mode 100644
index 0000000..07ae4e5
--- /dev/null
+++ b/klaptopdaemon/pics/crsc-app-laptop_battery.svgz
Binary files differ
diff --git a/klaptopdaemon/portable.cpp b/klaptopdaemon/portable.cpp
new file mode 100644
index 0000000..f56dc1e
--- /dev/null
+++ b/klaptopdaemon/portable.cpp
@@ -0,0 +1,3087 @@
+/*
+ * portable.cpp
+ *
+ * $Id$
+ *
+ * Copyright (c) 1999 Paul Campbell <paul@taniwha.com>
+ *
+ * Requires the Qt widget libraries, available at no cost at
+ * http://www.troll.no/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+//
+// this file contains the machine specific laptop power management stuff
+// to add support for your own OS this is should be the only place you need
+// to change - to add your own stuff insert above the line marked
+// 'INSERT HERE' :
+//
+// #ifdef MY_OS"
+// .. copy of linux code or whatever you want to use as a base
+// # else
+//
+// then tag an extra '#endif' at the end
+//
+// There is support for the following OSsen right now:
+//
+// Linux (#if __linux__)
+// FreeBSD (#elif __FreeBSD__)
+// NetBSD (#elif __NetBSD_APM__)
+// generic nothing (#else)
+//
+//
+// The code here is written in a C rather than C++ like to encourage
+// people more used to kernel types to do stuff here
+//
+// If you have any problems, questions, whatever please get in touch
+//
+// Paul Campbell
+// paul@taniwha.com
+//
+//
+// Thanks to Cajus Pollmeier <C.Pollmeier@gmx.net>
+// and Robert Ellis Parrott <parrott@fas.harvard.edu>
+// who both provided ACPI support
+// and Volker Krause <volker.krause@rwth-aachen.de> who provided ACPI bug fixes
+//
+
+#include <config.h>
+#include <klocale.h>
+#include <kdebug.h>
+#include <stdio.h>
+#include "portable.h"
+
+#ifdef __linux__
+
+/*
+** This is the Linux-specific laptop code.
+*/
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <stdlib.h>
+#include <math.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <dirent.h>
+#include <qpushbutton.h>
+#include <qdir.h>
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qstringlist.h>
+#include <qstring.h>
+#include <qobject.h>
+#include <qregexp.h>
+#include <qiodevice.h>
+#include <qlayout.h>
+#include <qvgroupbox.h>
+#include <qvaluevector.h>
+
+#include <kactivelabel.h>
+#include <kconfig.h>
+#include <kstandarddirs.h>
+#include <kprocess.h>
+#include <krichtextlabel.h>
+
+// ibm specific stuff
+extern "C"{
+#include "thinkpad_common.h"
+#include "smapi.h"
+#include "smapidev.h"
+}
+
+//
+// here's the Linux specific laptop control panel stuff
+//
+
+typedef struct apm_info {
+ unsigned int apm_flags;
+ unsigned int ac_line_status;
+ int battery_percentage;
+ int battery_time;
+} apm_info;
+
+static int
+apm_read(apm_info *ap)
+{
+ FILE *f = 0;
+ char tmp2[10];
+ int tmp, s;
+ unsigned int utmp;
+ char version[256];
+
+ f = fopen("/proc/apm", "r");
+ if (f == NULL)
+ return(1);
+ s = fscanf(f, "%255s %d.%d %x %x %x %x %d%% %d %s\n",
+ version,
+ &tmp,
+ &tmp,
+ &ap->apm_flags,
+ &ap->ac_line_status,
+ &utmp,
+ &utmp,
+ &ap->battery_percentage,
+ &ap->battery_time,
+ tmp2);
+ fclose(f);
+ if (s < 9)
+ return(1);
+ if (version[0] == 'B')
+ return(2);
+ if (ap->battery_percentage > 100)
+ ap->battery_percentage = -1;
+ if (strcmp(tmp2, "sec") == 0)
+ ap->battery_time /= 60;
+ return(0);
+}
+
+
+// 0 => unknown
+// 1 => have it
+// -1 => don't have it
+static int pmustate = 0;
+
+static bool
+have_pmu(void)
+{
+ if (pmustate != 0)
+ return (pmustate == 1);
+ if (!access("/proc/pmu", R_OK|X_OK)) {
+ kdDebug() << "Found powermac PMU. Using that." << endl;
+ pmustate = 1;
+ return true;
+ }
+ pmustate = -1;
+ return false;
+}
+
+/* Only supports 1 battery right now - all batteries are merged into one stat */
+static int
+pmu_read(apm_info *ap)
+{
+ int bcnt = 0;
+ memset(ap, 0, sizeof(apm_info));
+ QFile f("/proc/pmu/info");
+ if (!f.open(IO_ReadOnly))
+ return 1;
+
+ while (!f.atEnd()) {
+ QString l;
+ f.readLine(l, 500);
+ QStringList ll = QStringList::split(':', l, false);
+ if (ll[0].stripWhiteSpace() == "AC Power") {
+ ap->ac_line_status = ll[1].stripWhiteSpace().toInt();
+ //kdDebug() << "line status " << ap->ac_line_status << endl;
+ } else if (ll[0].stripWhiteSpace() == "Battery count") {
+ bcnt = ll[1].stripWhiteSpace().toInt();
+ //kdDebug() << "batteries: " << bcnt << endl;
+ }
+ }
+
+ f.close();
+
+ int charge = 0;
+ int timerem = 0;
+ int maxcharge = 0;
+ for (int i = 0; i < bcnt; i++) {
+ QFile bf(QString("/proc/pmu/battery_%1").arg(i));
+ if (!bf.open(IO_ReadOnly))
+ continue;
+
+ while(!bf.atEnd()) {
+ QString l;
+ bf.readLine(l, 500);
+ QStringList ll = QStringList::split(':', l, false);
+ if (ll[0].stripWhiteSpace() == "charge") {
+ charge += ll[1].stripWhiteSpace().toInt();
+ //kdDebug() << "charge: " << charge << endl;
+ } else if (ll[0].stripWhiteSpace() == "max_charge") {
+ maxcharge += ll[1].stripWhiteSpace().toInt();
+ //kdDebug() << "max charge: " << maxcharge << endl;
+ } else if (ll[0].stripWhiteSpace() == "time rem.") {
+ timerem += ll[1].stripWhiteSpace().toInt();
+ //kdDebug() << "time: " << timerem << endl;
+ }
+ }
+ bf.close();
+ }
+ ap->battery_percentage = int(rint(100.0*float(float(charge)/float(maxcharge))));
+ ap->battery_time = timerem;
+
+ if (ap->ac_line_status > 0 || timerem == 0 ||
+ (ap->ac_line_status == 0 && charge > 100 && timerem == 0))
+ ap->battery_time = -1;
+
+ return 0;
+}
+
+
+struct acpi_battery_info {
+ int percentage;
+ bool present;
+ int cap;
+ int cap_low;
+ int remaining;
+ int rate;
+ QString name;
+ QString state_file;
+ QString info_file;
+};
+
+static QValueVector<acpi_battery_info> acpi_batteries;
+static int acpi_last_known=0;
+static int last_seed=1; // increment this to force revaluation
+
+static unsigned char acpi_ac_ok;
+
+//
+// linux APCI doesn't return useful stuff like how much TIME is left yet
+// the 'rate' is not smoothed over time so it's faked out here
+// it's not pretty and it's a quick estimate
+//
+// for the moment we prefer APM
+//
+
+static int
+acpi_ac_status()
+{
+ DIR *dfd;
+ struct dirent *dp;
+ FILE *f = NULL;
+ static char buff[NAME_MAX+50];
+ static bool inited=0;
+ static bool bad=0;
+
+ if (inited) {
+ if (bad)
+ return(-1);
+ f = fopen(buff, "r");
+ goto readit;
+ }
+ inited = 1;
+
+ dfd = opendir("/proc/acpi/ac_adapter/");
+ if (dfd) {
+ for (;;) {
+ dp = readdir(dfd);
+ if (dp == 0)
+ break;
+ if (strcmp(dp->d_name, ".") == 0 ||
+ strcmp(dp->d_name, "..") == 0)
+ continue;
+ strcpy(buff, "/proc/acpi/ac_adapter/");
+ strcat(buff, dp->d_name);
+ strcat(buff, "/status");
+ f = fopen(buff, "r");
+ if (!f) {
+ strcpy(buff, "/proc/acpi/ac_adapter/");
+ strcat(buff, dp->d_name);
+ strcat(buff, "/state");
+ f = fopen(buff, "r");
+ }
+ if (f)
+ break;
+ }
+ closedir(dfd);
+readit:
+ if (f) {
+ for (;;) {
+ char buff2[1024];
+ if (fgets(buff2, sizeof(buff), f) == NULL)
+ break;
+ if (strstr(buff2, "Status:") != NULL ||
+ strstr(buff2, "state:") != NULL) {
+ if (strstr(buff2, "on-line") != NULL) {
+ fclose(f);
+ return(1);
+ }
+ }
+ }
+ fclose(f);
+ return(0);
+ }
+ }
+ bad=1;
+ return(-1);
+}
+
+static void acpi_read_batteries() {
+ QString buff;
+ QFile *f;
+ static int test_count = 0;
+ bool skip = false;
+
+ for(unsigned int i = 0; i < acpi_batteries.count(); ++i) {
+ acpi_battery_info& bat = acpi_batteries[i];
+ bool present = false;
+ if ((test_count==0 || acpi_last_known != last_seed) && !bat.info_file.isNull()) {
+ f = new QFile(bat.info_file);
+ if (f && f->open(IO_ReadOnly)) {
+ while(f->readLine(buff,1024) > 0) {
+ if (buff.contains("design capacity low:", false)) {
+ QRegExp rx("(\\d*)\\D*$");
+ rx.search(buff);
+ bat.cap_low = rx.cap(1).toInt();
+ if (bat.cap_low < 0)
+ bat.cap_low = 0;
+ continue;
+ }
+ if (buff.contains("last full capacity:", false)) {
+ QRegExp rx("(\\d*)\\D*$");
+ rx.search(buff);
+ bat.cap = rx.cap(1).toInt();
+ continue;
+ }
+ }
+ f->close();
+ bat.cap -= bat.cap_low;
+ }
+ delete f;
+ }
+ if (bat.cap <= 0) {
+ KConfig* config = new KConfig("kcmlaptoprc", true /*readonly*/, false /*useKDEGlobals*/);
+ config->setGroup("AcpiBattery");
+ bat.cap = config->readNumEntry(bat.name,0);
+ delete config;
+ }
+ if (!bat.state_file.isNull()) {
+ f = new QFile(bat.state_file);
+ if (f && f->open(IO_ReadOnly)) {
+ while(f->readLine(buff,1024) > 0) {
+ if (buff.contains("present rate:", false)) {
+ QRegExp rx("(\\d*)\\D*$");
+ rx.search(buff);
+ bat.rate = rx.cap(1).toInt();
+ if (bat.rate < 0)
+ bat.rate = 0;
+ present = true;
+ continue;
+ }
+ if (buff.contains("remaining capacity:", false)) {
+ QRegExp rx("(\\d*)\\D*$");
+ rx.search(buff);
+ bat.remaining = rx.cap(1).toInt();
+ bat.remaining -= bat.cap_low;
+ if (bat.remaining < 0)
+ bat.remaining = 0;
+ present = true;
+ continue;
+ }
+ }
+ f->close();
+ }
+ delete f;
+ }
+ if(present && !bat.present) // recheck capacity if a battery was put in
+ skip = true;
+ bat.present = present;
+ if (bat.present) {
+ if (bat.remaining > bat.cap) { // happens e.g. if the system doesn't provide a capacity value
+ bat.cap = bat.remaining;
+ KConfig* config = new KConfig("kcmlaptoprc", false /*readonly*/, false /*useKDEGlobals*/);
+ config->setGroup("AcpiBattery");
+ config->writeEntry(bat.name, bat.cap);
+ config->sync();
+ delete config;
+ skip = true;
+ }
+ if (bat.cap == 0)
+ bat.percentage = 0;
+ else
+ bat.percentage = bat.remaining*100/bat.cap;
+ }
+ else
+ bat.percentage = 0;
+ }
+
+ if (!skip) {
+ acpi_last_known = last_seed;
+ test_count++;
+ }
+ else
+ test_count = 0;
+ if (test_count > 1000) // every 1000 or so times recheck the battery capacity
+ test_count = 0;
+
+}
+
+static int
+acpi_read(apm_info *ap)
+{
+ int rate, part, total;
+ int ret = 1;
+ bool present = 0;
+
+ part = 0;
+ total = 0;
+ rate = 0;
+
+ acpi_read_batteries();
+
+ for(unsigned int i = 0; i < acpi_batteries.count(); ++i) {
+ acpi_battery_info& bat = acpi_batteries[i];
+ present |= bat.present;
+ if(bat.present) {
+ total += bat.cap;
+ part += bat.remaining;
+ rate += bat.rate;
+ }
+ ret = 0;
+ }
+
+ // some broken ACPI implementations don't return a rate
+ // compute a 'fake' rate by diffing remaining values
+ if (rate == 0)
+ {
+ static int last_remaining = 0;
+ static time_t last_time = 0;
+ if (last_remaining != 0
+ && last_time != 0)
+ {
+ int diff_time = time(0) - last_time;
+ if (diff_time > 0)
+ rate = (last_remaining - part) * 3600 / diff_time;
+ }
+ last_remaining = part;
+ last_time = time(0);
+ if (rate < 0)
+ rate = 0;
+ }
+
+ static int nrates = 0;
+ static int saved_rate[8];
+ static unsigned char ignore_next = 2; // ignore the first couple
+
+ ap->ac_line_status = 0;
+ //
+ // ACPI (unlike nice systems like some APM implementations) doesn't
+ // tell us how much battery TIME we have left - here we
+ // do a weighted average of the discharge rate (in mW) and
+ // figure out how long we have left by dividing it into the
+ // remaining capacity
+ //
+ // because some ACPI implementations return bogus
+ // rates when charging we can't estimate the battery life
+ // so we only collect discharge rate data when we're actually
+ // discharging
+ //
+ if (acpi_ac_status() == 1) {
+ ap->ac_line_status |= 1;
+ ignore_next = 2;
+ } else {
+ // after switching from power to unpowered we often get
+ // a bad reading from ACPI resulting in bizarre
+ // readings
+ if (ignore_next == 0) {
+ if (nrates < 8) // smooth the power flow
+ nrates++; // simple box filter
+ for (int i = 8-1; i > 0; i--)
+ saved_rate[i] = saved_rate[i-1];
+ saved_rate[0] = rate;
+ } else {
+ ignore_next--;
+ }
+ }
+ //
+ // if we haven't got any discharge rate data yet don't return a
+ // battery time - probably happens when you start up with the
+ // ac adaptor plugged in
+ //
+ if (nrates == 0) {
+ ap->battery_time = -1;
+ } else {
+ rate = 0;
+ for (int i = 0; i < nrates; i++)
+ rate += saved_rate[i];
+ rate = (rate+2*saved_rate[0])/(nrates+2); // weight it slighly
+ ap->battery_time = (rate==0 ? -1 : 60*part/rate);
+ }
+ ap->battery_percentage = (total==0?0:100*part/total);
+ if (!present) {
+ ap->battery_percentage = -1;
+ ap->battery_time = -1;
+ }
+ ap->apm_flags = 0;
+ return(ret);
+}
+
+static int apm_no_time;
+static apm_info apmx = {0,0,0,0};
+static int
+has_apm()
+{
+ static int init = 0;
+ static int val;
+ if (init)
+ return(val);
+ init = 1;
+ val = 1;
+ apm_no_time=0;
+ if (apm_read(&apmx) || (apmx.apm_flags&0x20)) {
+ val = 0;
+ apm_no_time = 1;
+ } else {
+ apm_no_time = apmx.battery_time < 0;
+ }
+
+ if (val == 0) {
+ val = have_pmu();
+ if (val && pmu_read(&apmx)) {
+ val = 0;
+ }
+ }
+ return(val);
+}
+
+// Power to the powermacs!!
+static int
+has_pmu()
+{
+ static int init = 0;
+ static int val;
+ if (init)
+ return val;
+ init = 1;
+ val = 1;
+ if (!QDir("/proc/pmu").exists()) {
+ val = 0;
+ }
+ return val;
+}
+
+static bool software_suspend_is_preferred = false; // user prefers to use SS for hibernate
+static bool acpi_helper_ok(bool type);
+static bool
+has_software_suspend(int type)
+{
+ static int known=0;
+ static bool present=0; // functionality seems to be here
+ static bool available=0; // helper can work
+ if (known != last_seed) {
+ known = last_seed;
+ available = 0;
+ present = (((::access("/proc/sys/kernel/swsusp", F_OK) == 0) ||
+ (::access("/proc/software_suspend", F_OK) == 0) ||
+ (::access("/proc/suspend2", F_OK) == 0)) &&
+ ::access("/usr/sbin/hibernate", F_OK) == 0);
+ if (present) {
+ if (::getuid() == 0) { // running as root
+ available = ::access("/usr/sbin/hibernate", X_OK) == 0 && acpi_helper_ok(1);
+ } else {
+ available = acpi_helper_ok(0);
+ }
+ }
+ }
+ switch (type) {
+ case 0: return(present);
+ case 1: return(present&available&software_suspend_is_preferred);
+ case 2: return(present&available);
+ default:return(0);
+ }
+}
+
+bool
+laptop_portable::has_software_suspend(int type)
+{
+ return(::has_software_suspend(type));
+}
+
+void
+laptop_portable::software_suspend_set_mask(bool hibernate)
+{
+ software_suspend_is_preferred = hibernate;
+}
+
+
+static int x_acpi_init = 0;
+static bool
+has_acpi()
+{
+ static bool val;
+ static bool checked = 0;
+
+ if (!checked) {
+ val = ::access("/proc/acpi", F_OK) == 0;
+ checked = 1;
+ }
+ return(val);
+}
+
+static int
+has_acpi_power()
+{
+ static int val;
+
+ if (x_acpi_init)
+ return(val);
+ x_acpi_init = 1;
+ val = 0;
+
+ acpi_batteries.clear();
+
+ if (acpi_ac_status() >= 0)
+ acpi_ac_ok = 1;
+
+ QDir battdir("/proc/acpi/battery");
+ battdir.setFilter(QDir::Dirs);
+ if(!battdir.isReadable())
+ return(val = 0);
+ for(uint i = 0; !battdir[i].isNull(); ++i) {
+ if(battdir[i] == "." || battdir[i] == "..")
+ continue;
+ bool ok = 0;
+ acpi_battery_info bat = {0,0,0,0,0,0,0,0,0};
+ QString base = battdir.path() + "/" + battdir[i] + "/";
+ QString name(base + "state");
+ QFileInfo f(name);
+ if(f.isReadable()) {
+ bat.state_file = name;
+ ok = true;
+ } else {
+ name = base + "status";
+ f.setFile(name);
+ if(f.isReadable()) {
+ bat.state_file = name;
+ ok = true;
+ }
+ }
+ name = base + "info";
+ f.setFile(name);
+ if(f.isReadable()) {
+ bat.info_file = name;
+ ok = true;
+ }
+ if (ok) {
+ bat.name = battdir[i];
+ acpi_batteries.append(bat);
+ val = 1;
+ }
+ }
+ if (!acpi_ac_ok)
+ val = 0;
+ return(val);
+}
+
+static unsigned long acpi_sleep_enabled = 0x00; // acpi sleep functions enabled mask
+
+
+static bool
+has_acpi_sleep(int state)
+{
+ static int known=0;
+ static unsigned long mask=0;
+ if (known != last_seed) {
+ known = last_seed;
+ mask = 0;
+
+ QFile p("/sys/power/state");
+ QFile f("/proc/acpi/sleep");
+
+ if (p.open(IO_ReadOnly)) {
+ QString l;
+ QTextStream t(&p);
+ l = t.readLine();
+ QStringList ll = QStringList::split(' ',l,false);
+ for (QValueListIterator<QString> i = ll.begin(); i!=ll.end(); i++) {
+ QString s = *i;
+
+ if (s.compare("standby")==0)
+ mask |= (1<<1);
+ else if (s.compare("mem")==0)
+ mask |= (1<<3);
+ else if (s.compare("disk")==0)
+ mask |= (1<<4);
+ }
+ p.close();
+ }
+ else if (f.open(IO_ReadOnly)) {
+ QString l;
+ QTextStream t(&f);
+ l = t.readLine();
+ QStringList ll = QStringList::split(' ',l,false);
+ for (QValueListIterator<QString> i = ll.begin(); i!=ll.end(); i++) {
+ QString s = *i;
+ if (s[0] == 'S') {
+ int c = s[1].digitValue();
+ if (c >= 0 && c <= 9)
+ mask |= 1<<c;
+ }
+ }
+ f.close();
+ }
+ }
+ return((mask&acpi_sleep_enabled&(1<<state)) != 0);
+}
+
+static bool acpi_performance_enabled = 0;
+static bool acpi_throttle_enabled = 0;
+void
+laptop_portable::acpi_set_mask(bool standby, bool suspend, bool hibernate, bool perf, bool throttle)
+{
+ acpi_sleep_enabled =
+ (standby ? (1<<1)|(1<<2) : 0) |
+ (suspend ? 1<<3 : 0) |
+ (hibernate ? 1<<4 : 0);
+ acpi_performance_enabled = perf;
+ acpi_throttle_enabled = throttle;
+ last_seed++;
+}
+
+static void
+invoke_acpi_helper(const char *param, const char *param2, const char *param3)
+{
+ KProcess proc;
+ proc << KStandardDirs::findExe("klaptop_acpi_helper");
+ proc << param;
+ if (param2)
+ proc << param2;
+ if (param3)
+ proc << param3;
+ proc.start(KProcess::Block); // helper runs fast and we want to see the result
+}
+
+static unsigned long apm_sleep_enabled = 0x0c; // apm sleep functions enabled mask
+static bool
+has_apm_sleep(int state)
+{
+ return((apm_sleep_enabled&(1<<state)) != 0);
+}
+
+void
+laptop_portable::apm_set_mask(bool standby, bool suspend)
+{
+ apm_sleep_enabled =
+ (standby ? 1<<2 : 0) |
+ (suspend ? 1<<3 : 0);
+ last_seed++;
+}
+
+static bool apm_sleep_access_ok();
+static bool acpi_sleep_access_ok();
+
+static int
+apm_has_time()
+{
+ return(!apm_no_time);
+}
+
+//
+// something changed maybe we need to check out environment again
+//
+void
+laptop_portable::power_management_restart()
+{
+ last_seed++;
+ x_acpi_init = 0;
+}
+
+int laptop_portable::has_apm(int type)
+{
+ switch (type) {
+ case 0:
+ return(::has_apm());
+ case 1:
+ return(::has_apm() && ::apm_sleep_access_ok());
+ default:
+ return(0);
+ }
+}
+
+//
+// returns 1 if we support acpi
+//
+int laptop_portable::has_acpi(int type)
+{
+ switch (type) {
+ case 0:
+ return(::has_acpi_power());
+ case 1:
+ return(::has_acpi() && ::acpi_sleep_access_ok());
+ case 3:
+ return(::has_acpi() &&::acpi_sleep_access_ok() && (::has_acpi_sleep(1)||::has_acpi_sleep(2)));
+ case 4:
+ return(::has_acpi() &&::acpi_sleep_access_ok() && ::has_acpi_sleep(3));
+ case 5:
+ return(::has_acpi() &&::acpi_sleep_access_ok() && ::has_acpi_sleep(4));
+ default:
+ return(0);
+ }
+}
+
+//
+// The following code was derived from tpctl for IBM thinkpad support
+// (Thomas Hood, Bill Mair - tpctl.sourceforge.net)
+//
+// we check for the existence of /dev/thinkpad/thinkpad or /dev/thinkpad
+//
+static const char *ibm_device;
+static int ibm_fd = -1;
+
+static bool has_ibm()
+{
+ static int known=0;
+ static bool result;
+ if (known == last_seed)
+ return(result);
+ known = last_seed;
+ result = 0;
+ if (ibm_fd >= 0) {
+ result = 1;
+ return(1);
+ }
+ ibm_device = "/dev/thinkpad/thinkpad";
+ if ((ibm_fd = open(ibm_device, O_RDWR)) < 0) {
+ ibm_device = "/dev/thinkpad";
+ if ((ibm_fd = open(ibm_device, O_RDWR)) < 0)
+ return(0);
+ }
+ result = 1;
+ return(1);
+}
+//
+// returns 1 if we support power management
+//
+int laptop_portable::has_power_management()
+{
+ if (::has_apm())
+ return 1;
+ if (::has_pmu())
+ return 1;
+ if (::has_acpi_power())
+ return 1;
+ if (::has_ibm())
+ return 1;
+ // INSERT HERE
+ return 0;
+}
+//
+// returns 1 if the BIOS returns the time left in the battery rather than a % of full
+//
+int laptop_portable::has_battery_time()
+{
+ if (::has_acpi_power())
+ return 1;
+ if (::apm_has_time())
+ return 1;
+ // INSERT HERE
+ return 0;
+}
+//
+// returns 1 if we can perform a change-to-suspend-mode operation for the user
+// (has_power_management() has already returned 1)
+//
+int laptop_portable::has_suspend()
+{
+ if (::has_acpi())
+ return ::acpi_sleep_access_ok() && ::has_acpi_sleep(3);
+ if (::has_pmu())
+ return 1;
+ if (::has_ibm())
+ return 1;
+ if (::has_apm())
+ return ::apm_sleep_access_ok() && ::has_apm_sleep(3);
+ // INSERT HERE
+ return 0;
+}
+//
+// returns 1 if we can perform a change-to-standby-mode operation for the user
+// (has_power_management() has already returned 1)
+//
+int laptop_portable::has_standby()
+{
+ if (::has_pmu())
+ return 0;
+ if (::has_acpi())
+ return ::acpi_sleep_access_ok() && (::has_acpi_sleep(1)||::has_acpi_sleep(2));
+ if (::has_ibm())
+ return 1;
+ if (::has_apm())
+ return ::apm_sleep_access_ok() && ::has_apm_sleep(2);
+ // INSERT HERE
+ return 0;
+}
+//
+// returns 1 if we can perform a change-to-hibernate-mode for a user
+// (has_power_management() has already returned 1) [hibernate is the save-to-disk mode
+// not supported by linux APM]
+//
+int laptop_portable::has_hibernation()
+{
+ if (::has_pmu())
+ return 0;
+ if (::has_software_suspend(1)) // must be before acpi
+ return 1;
+ if (::has_acpi())
+ return ::acpi_sleep_access_ok() && ::has_acpi_sleep(4);
+ if (::has_ibm())
+ return 1;
+ // INSERT HERE
+ return 0;
+}
+
+//
+// explain to the user what they need to do if has_power_management() returned 0
+// to get any software they lack
+//
+
+KActiveLabel *laptop_portable::no_power_management_explanation(QWidget *parent)
+{
+ if (access("/proc/acpi", F_OK) == 0) { // probably has default kernel ACPI installed
+ KActiveLabel* explain = new KActiveLabel(i18n("Your computer seems to have a partial ACPI installation. ACPI was probably enabled, but some of the sub-options were not - you need to enable at least 'AC Adaptor' and 'Control Method Battery' and then rebuild your kernel."), parent);
+ return(explain);
+ }
+
+ KActiveLabel* explain = new KActiveLabel(i18n("Your computer doesn't have the Linux APM (Advanced Power Management) or ACPI software installed, or doesn't have the APM kernel drivers installed - check out the <a href=\"http://www.linuxdoc.org/HOWTO/Laptop-HOWTO.html\">Linux Laptop-HOWTO</a> document for information on how to install APM."), parent);
+
+ return(explain);
+}
+
+//
+// explain to the user what they need to do to get suspend/resume to work from user mode
+//
+QLabel *laptop_portable::how_to_do_suspend_resume(QWidget *parent)
+{
+ if (::has_apm()) {
+ // TODO: remove linefeed from string, can't do it right now coz we have a string freeze
+ QLabel* note = new KRichTextLabel(i18n("\nIf you make /usr/bin/apm setuid then you will also "
+ "be able to choose 'suspend' and 'standby' in the above "
+ "dialog - check out the help button below to find out "
+ "how to do this").replace("\n", QString::null), parent);
+ return(note);
+ }
+ if (::has_acpi()) {
+ // TODO: remove linefeed from string, can't do it right now coz we have a string freeze
+ QLabel* note = new KRichTextLabel(i18n("\nYou may need to enable ACPI suspend/resume in the ACPI panel").replace("\n", QString::null), parent);
+ return(note);
+ }
+ // TODO: remove linefeed from string, can't do it right now coz we have a string freeze
+ QLabel* note = new KRichTextLabel(i18n("\nYour system does not support suspend/standby").replace("\n", QString::null), parent);
+ return(note);
+}
+
+static char tmp0[256], tmp1[256];
+static int present=0;
+static
+void get_pcmcia_info()
+{
+ FILE *f = fopen("/var/lib/pcmcia/stab", "r");
+ if (!f) f = fopen("/var/run/stab", "r");
+ if (f) {
+ int c;
+ char *cp;
+
+ present = 1;
+ cp = tmp0;
+ for (;;) {
+ c = fgetc(f);
+ if (c == EOF || c == '\n')
+ break;
+ if (c == ':') {
+ while ((c = fgetc(f)) == ' ')
+ ;
+ if (c == EOF)
+ break;
+ for (;;) {
+ *cp++ = c;
+ c = fgetc(f);
+ if (c == EOF || c == '\n')
+ break;
+ }
+ break;
+ }
+ }
+ *cp = 0;
+
+ if (c != EOF) {
+ cp = tmp1;
+ for (;;) {
+ c = fgetc(f);
+ if (c == EOF)
+ break;
+ if (c == ':') {
+ while ((c = fgetc(f)) == ' ')
+ ;
+ if (c == EOF)
+ break;
+ for (;;) {
+ *cp++ = c;
+ c = fgetc(f);
+ if (c == EOF || c == '\n')
+ break;
+ }
+ break;
+ }
+ }
+ *cp = 0;
+ }
+
+ fclose(f);
+ } else {
+ present = 0;
+ }
+}
+
+//
+// pcmcia support - this will be replaced by better - pcmcia support being worked on by
+// others
+//
+QLabel *laptop_portable::pcmcia_info(int x, QWidget *parent)
+{
+ if (x == 0)
+ get_pcmcia_info();
+ if (!present) {
+ if (x == 1)
+ return(new QLabel(i18n("No PCMCIA controller detected"), parent));
+ return(new QLabel(i18n(""), parent));
+ } else {
+ switch (x) {
+ case 0: return(new QLabel(i18n("Card 0:"), parent));
+ case 1: return(new QLabel(tmp0, parent));
+ case 2: return(new QLabel(i18n("Card 1:"), parent));
+ default:return(new QLabel(tmp1, parent));
+ }
+ }
+}
+
+//
+// puts us into standby mode
+//
+void laptop_portable::invoke_standby()
+{
+ last_seed++; // make it look for battery removal/return
+ if (::has_acpi()) {
+ if (::has_acpi_sleep(1)) { // people seem to argue as to which is 'standby' the S1 people are winning
+ ::invoke_acpi_helper("--standby", 0, 0);
+ } else {
+ ::invoke_acpi_helper("--standby2", 0, 0);
+ }
+ return;
+ }
+ if (::has_ibm()) {
+ smapi_ioparm_t ioparmMy;
+ sync();
+ ioparmMy.in.bFunc = (byte) 0x70;
+ ioparmMy.in.bSubFunc = (byte) 0;
+ ioparmMy.in.wParm1 = (word) 0;
+ ioparmMy.in.wParm2 = (word) 0;
+ ioparmMy.in.wParm3 = (word) 0;
+ ioparmMy.in.dwParm4 = (dword) 0;
+ ioparmMy.in.dwParm5 = (dword) 0;
+ (void)ioctl_smapi( ibm_fd, &ioparmMy );
+ return;
+ }
+ // add other machine specific standbys here
+ KProcess proc;
+ proc << "/usr/bin/apm";
+ proc << "--standby";
+ proc.start(KProcess::Block); // helper runs fast and we want to see the result
+}
+
+//
+// puts us into suspend mode
+//
+void laptop_portable::invoke_suspend()
+{
+ last_seed++; // make it look for battery removal/return
+
+ if (::has_pmu()) {
+ KProcess proc;
+ proc << "/usr/bin/apm";
+ proc << "-f";
+ proc.start(KProcess::Block); // helper runs fast and we want to see the result
+ return;
+ }
+
+ if (::has_acpi()) {
+ ::invoke_acpi_helper("--suspend", 0, 0);
+ return;
+ }
+ if (::has_ibm()) {
+ smapi_ioparm_t ioparmMy;
+ sync();
+ ioparmMy.in.bFunc = (byte) 0x70;
+ ioparmMy.in.bSubFunc = (byte) 1;
+ ioparmMy.in.wParm1 = (word) 0;
+ ioparmMy.in.wParm2 = (word) 0;
+ ioparmMy.in.wParm3 = (word) 0;
+ ioparmMy.in.dwParm4 = (dword) 0;
+ ioparmMy.in.dwParm5 = (dword) 0;
+ (void)ioctl_smapi( ibm_fd, &ioparmMy );
+ return;
+ }
+ // add other machine specific suspends here
+ KProcess proc;
+ proc << "/usr/bin/apm";
+ proc << "--suspend";
+ proc.start(KProcess::Block); // helper runs fast and we want to see the result
+}
+
+//
+// puts us into hibernate mode
+//
+void laptop_portable::invoke_hibernation()
+{
+ last_seed++; // make it look for battery removal/return
+ if (::has_software_suspend(1)) { // must be before acpi
+ ::invoke_acpi_helper("--software-suspend", 0, 0);
+ return;
+ }
+ if (::has_acpi()) {
+ ::invoke_acpi_helper("--hibernate", 0, 0);
+ return;
+ }
+ if (::has_ibm()) {
+ smapi_ioparm_t ioparmMy;
+ sync();
+ ioparmMy.in.bFunc = (byte) 0x70;
+ ioparmMy.in.bSubFunc = (byte) 2;
+ ioparmMy.in.wParm1 = (word) 0;
+ ioparmMy.in.wParm2 = (word) 0;
+ ioparmMy.in.wParm3 = (word) 0;
+ ioparmMy.in.dwParm4 = (dword) 0;
+ ioparmMy.in.dwParm5 = (dword) 0;
+ (void)ioctl_smapi( ibm_fd, &ioparmMy );
+ return;
+ }
+ // add other machine specific hibernates here
+}
+
+void
+laptop_portable::extra_config(QWidget *wp, KConfig *, QVBoxLayout *top_layout)
+{
+ if (laptop_portable::has_apm(1) || laptop_portable::has_acpi(1))
+ return;
+ if (laptop_portable::has_apm(0)) {
+ QLabel* explain = new KRichTextLabel( i18n("Your system has APM installed but may not be able to use all "
+ "of its features without further setup - look in the 'APM Config' "
+ "tab for information about setting up APM for suspend and resume"), wp);
+ top_layout->addWidget(explain, 0);
+ }
+ if (laptop_portable::has_acpi(0)) {
+ QLabel* explain = new KRichTextLabel( i18n("Your system has ACPI installed but may not be able to use all "
+ "of its features without further setup - look in the 'ACPI Config' "
+ "tab for information about setting up ACPI for suspend and resume"), wp);
+ top_layout->addWidget(explain, 0);
+ }
+}
+
+//
+// return current battery state
+//
+struct power_result laptop_portable::poll_battery_state()
+{
+ struct power_result p;
+
+ apm_info x = {0,0,0,-1};
+ if (have_pmu()) {
+ pmu_read(&x);
+ } else
+ if ((::has_acpi_power() ? ::acpi_read(&x) : ::apm_read(&x)) || (x.apm_flags&0x20)) {
+ // INSERT HERE
+ p.powered = 0;
+ p.percentage=0;
+ p.time = -1;
+ return p;
+ }
+ p.powered = x.ac_line_status&1;
+ p.percentage = x.battery_percentage;
+ p.time = x.battery_time;
+ return(p);
+}
+
+void
+laptop_portable::get_battery_status(int &num_batteries, QStringList &names, QStringList &state, QStringList &values)
+{
+ struct power_result r;
+
+ if (!has_power_management()) {
+ num_batteries = 0;
+ names.clear();
+ state.clear();
+ values.clear();
+ return;
+ }
+
+ if (::has_acpi_power()) {
+ names.clear();
+ state.clear();
+ values.clear();
+ acpi_read_batteries();
+ num_batteries = acpi_batteries.count();
+ for(unsigned int i = 0; i < acpi_batteries.count(); ++i) {
+ acpi_battery_info& bat = acpi_batteries[i];
+ names.append(bat.name);
+ values.append(QString("%1").arg(bat.percentage));
+ state.append(bat.present ? "yes" : "no");
+ }
+ return;
+ }
+
+ // INSERT HERE
+
+ num_batteries = 1;
+ r = poll_battery_state();
+ names.append("BAT1");
+ state.append("yes");
+ QString s;
+ s.setNum(r.percentage);
+ values.append(s);
+}
+
+
+//
+// returns the current system load average, -1 if none
+//
+static QFile lav_file;
+static bool lav_inited=0;
+static bool lav_openok=0;
+
+static bool has_lav()
+{
+ if (!lav_inited) {
+ lav_inited =1;
+ lav_file.setName("/proc/loadavg");
+ lav_openok = lav_file.open( IO_ReadOnly );
+ if (lav_openok)
+ lav_file.close();
+ }
+ return(lav_openok);
+}
+
+bool laptop_portable::has_lav()
+{
+ return ::has_lav();
+}
+
+float laptop_portable::get_load_average()
+{
+ if (!::has_lav())
+ return(-1);
+ lav_file.open( IO_ReadOnly );
+ QString l;
+ lav_file.readLine(l, 500);
+ lav_file.close();
+ QStringList ll = QStringList::split(' ', l, false);
+ l = ll[0];
+ bool ok;
+ float f = l.toFloat(&ok);
+ if (!ok)
+ f = -1;
+ return(f);
+}
+
+
+int laptop_portable::has_cpufreq() {
+ struct stat sb;
+ int rc;
+ rc = stat("/proc/cpufreq", &sb);
+ if (rc == 0) {
+ rc = stat("/proc/cpuinfo", &sb);
+ if (rc == 0)
+ return 1;
+ }
+ // INSERT HERE
+ return 0;
+}
+
+
+QString laptop_portable::cpu_frequency() {
+ QString rc;
+ QFile cf("/proc/cpufreq");
+ bool haveProfile = false;
+
+ if (cf.open(IO_ReadOnly)) {
+ while (!cf.atEnd()) {
+ QString l;
+ cf.readLine(l, 500);
+ if (l.left(3) == "CPU") {
+ QStringList ll = QStringList::split(' ', l, false);
+ rc = ll.last();
+ haveProfile = true;
+ break;
+ }
+ }
+
+ }
+ if (haveProfile) {
+ QFile ci("/proc/cpuinfo");
+ if (ci.open(IO_ReadOnly)) {
+ while (!ci.atEnd()) {
+ QString l;
+ ci.readLine(l, 500);
+ QStringList ll =
+ QStringList::split(':',l,false);
+ if (ll.count() != 2)
+ continue;
+ if (ll.first().stripWhiteSpace()
+ == "cpu MHz") {
+ rc = i18n("%1 MHz (%2)").arg(ll.last().stripWhiteSpace()).arg(rc);
+ break;
+ } else if (ll.first().stripWhiteSpace()
+ == "clock") {
+ rc = QString("%1 (%2)").arg(ll.last().stripWhiteSpace()).arg(rc);
+ break;
+ }
+ }
+ }
+ }
+
+ return rc;
+}
+
+static int sonyFd = -1;
+static int has_toshiba_brightness = 0;
+
+static bool
+acpi_helper_ok(bool type)
+{
+ static int known[2]={0,0};
+ static bool known_res[2];
+
+ if (known[type] == last_seed)
+ return(known_res[type]);
+ known[type] = last_seed;
+ known_res[type] = 0;
+ struct stat sb;
+ QString str = KStandardDirs::findExe("klaptop_acpi_helper");
+ if (str.isNull() || str.isEmpty())
+ return(0);
+
+ if (stat(str.latin1(), &sb) < 0)
+ return(0);
+ if (!S_ISREG(sb.st_mode))
+ return(0);
+ if (!type && getuid() != 0 && (sb.st_uid != 0 || !(sb.st_mode&S_ISUID)))
+ return(0);
+ if (!(sb.st_mode&0x111))
+ return(0);
+ known_res[type] = 1;
+ return(1);
+}
+
+static bool
+acpi_sleep_access_ok()
+{
+ static int known=0;
+ static int known_res=1;
+
+ if (known != last_seed) {
+ known = last_seed;
+ known_res = (::access("/proc/acpi/sleep", R_OK|W_OK)==0 && ::acpi_helper_ok(1)) ||
+ (::access("/proc/acpi/sleep", R_OK)==0 && ::acpi_helper_ok(0)) ||
+ (::access("/sys/power/state", R_OK|W_OK)==0 && ::acpi_helper_ok(1)) ||
+ (::access("/sys/power/state", R_OK)==0 && ::acpi_helper_ok(0));
+ }
+ return(known_res);
+}
+
+static bool
+apm_helper_ok(bool type)
+{
+ static int known[2]={0,0};
+ static bool known_res[2];
+
+ if (known[type] == last_seed)
+ return(known_res[type]);
+ known[type] = last_seed;
+ known_res[type] = 0;
+ struct stat sb;
+ QString str = "/usr/bin/apm";
+ if (str.isNull() || str.isEmpty())
+ return(0);
+ if (stat(str.latin1(), &sb) < 0)
+ return(0);
+ if (!S_ISREG(sb.st_mode))
+ return(0);
+ if (!type && getuid() != 0 && (sb.st_uid != 0 || !(sb.st_mode&S_ISUID)))
+ return(0);
+ if (!(sb.st_mode&0x111))
+ return(0);
+ known_res[type] = 1;
+ return(1);
+}
+
+static bool
+apm_sleep_access_ok()
+{
+ static int known=0;
+ static int known_res=1;
+
+ if (known != last_seed) {
+ known = last_seed;
+ known_res = (::access("/proc/apm", R_OK|W_OK)==0 && ::apm_helper_ok(1)) ||
+ (::access("/proc/apm", R_OK)==0 && ::apm_helper_ok(0));
+ }
+ return(known_res);
+}
+
+int
+laptop_portable::has_brightness()
+{
+ static int known=0;
+ static int known_res=1;
+
+ if (known == last_seed)
+ return(known_res);
+ known = last_seed;
+ if (sonyFd == -1 && ::access("/dev/sonypi", R_OK) == 0)
+ sonyFd = ::open("/dev/sonypi", O_RDONLY|O_NONBLOCK);
+ if (sonyFd >= 0)
+ return(1);
+ if (::has_acpi() &&
+ (((::access("/proc/acpi/TOSHIBA1/lcd", R_OK|W_OK)==0 || ::access("/proc/acpi/toshiba/lcd", R_OK|W_OK)==0) && ::acpi_helper_ok(1)) ||
+ ((::access("/proc/acpi/TOSHIBA1/lcd", R_OK)==0 || ::access("/proc/acpi/toshiba/lcd", R_OK)==0) && ::acpi_helper_ok(0)))) {
+ has_toshiba_brightness = 1;
+ return(1);
+ }
+ // check for new devices here
+ // INSERT HERE
+ known_res = 0;
+ return 0;
+}
+
+#define SONYPI_IOCSBRT _IOW('v', 0, unsigned char)
+
+//
+// There are two sorts of brightness calls - ones where we expect the user to raise the brightness themselves
+// by doing something (for these we don't allow the panel to go completely dark), and those where the
+// laptop software is going to remember the brightness and set it back later (like closing the lid
+// where we can go all the way black)
+//
+// NOTE: some panel interfaces (sony) can't actually go all the way blank anyway so we ignore the blank tag
+//
+void
+laptop_portable::set_brightness(bool blank, int val) // val = 0-255 255 brightest, 0 means dimmest (if !blank it must be still visible),
+{
+ if (sonyFd >= 0) {
+ unsigned char v;
+ if (val < 0)
+ val = 0;
+ if (val > 255)
+ val = 255;
+ v = val;
+ (void)::ioctl(sonyFd, SONYPI_IOCSBRT, &v);
+ return;
+ }
+ if (has_toshiba_brightness) {
+ char tmp[20];
+
+ if (val < 0)
+ val = 0;
+ if (val > 255)
+ val = 255;
+ val >>= 5;
+ if (val == 0 && !blank)
+ val = 1;
+ snprintf(tmp, sizeof(tmp), "%d", val&7);
+ ::invoke_acpi_helper("--toshibalcd", tmp, 0);
+ return;
+ }
+ // INSERT HERE
+}
+
+int
+laptop_portable::get_brightness() // return a val 0-255, or -1 if you can't
+{
+ if (sonyFd >= 0)
+ return(-1); // sonypi doesn't seem to return this reliably
+
+ // INSERT HERE
+ return(-1); // means can't extract it
+}
+
+#define MAP_SIZE 20
+static int acpi_performance_map[MAP_SIZE]; // hidden acpi state map
+static bool acpi_performance_enable[MAP_SIZE];
+static QStringList performance_list;
+static QString acpi_performance_cpu;
+static int acpi_throttle_map[MAP_SIZE];
+static bool acpi_throttle_enable[MAP_SIZE];
+static QStringList throttle_list;
+static QString acpi_throttle_cpu;
+
+static bool
+get_acpi_list(char p, int *map, const char *dev, QStringList &list, int &index, QString &cpu, bool get_enable, bool *enable_list)
+{
+ DIR *dfd;
+ struct dirent *dp;
+ unsigned int i = 0;
+ bool result = 0;
+
+ index = 0;
+ list.clear();
+ dfd = opendir("/proc/acpi/processor/");
+ if (dfd) {
+ for (dp = readdir(dfd);dp ;dp = readdir(dfd)) {
+ if (strcmp(dp->d_name, ".") == 0 ||
+ strcmp(dp->d_name, "..") == 0)
+ continue;
+ QString name("/proc/acpi/processor/");
+ name += dp->d_name;
+ name += dev;
+ if (!(::access(name.latin1(), R_OK|W_OK)==0 && ::acpi_helper_ok(1)) &&
+ !(::access(name.latin1(), R_OK)==0 && ::acpi_helper_ok(0)))
+ continue;
+ QFile f(name);
+ if (f.open(IO_ReadOnly)) {
+ while (!f.atEnd() && i < MAP_SIZE) {
+ QString l;
+ f.readLine(l, 500);
+ QStringList ll = QStringList::split(':',l,false);
+ QString tag = ll[0].stripWhiteSpace();
+ bool is_this = tag[0] == '*';
+ if (is_this) {
+ if (tag[1] != p)
+ continue;
+ tag.remove(0, 2);
+ } else {
+ if (tag[0] != p)
+ continue;
+ tag.remove(0, 1);
+ }
+ bool ok;
+ int val = tag.toInt(&ok);
+ if (ok) {
+ if (!result)
+ cpu = dp->d_name;
+ if (is_this)
+ index = i;
+ map[i] = val;
+ list.append(ll[1].stripWhiteSpace());
+ result = 1;
+ enable_list[i] = 1;
+ i++;
+ }
+ }
+ f.close();
+
+ //
+ // get the limit info if asked for
+ //
+ if (get_enable) {
+ name = QString("/proc/acpi/processor/")+dp->d_name+"/limit";
+ f.setName(name);
+ if (f.open(IO_ReadOnly)) {
+ while (!f.atEnd() && i < MAP_SIZE) {
+ QString l;
+ f.readLine(l, 500);
+ if (l.contains("active limit", false)) {
+ QRegExp rx(QString("%1(\\d+)").arg(p));
+ if (rx.search(l) >= 0) {
+ bool ok;
+ int min = rx.cap(1).toInt(&ok);
+ if (ok) {
+ for (int j = 0; j < min; j++)
+ enable_list[j] = 0;
+
+ }
+ }
+ break;
+ }
+ }
+ f.close();
+ }
+ }
+ break;
+ }
+ }
+ closedir(dfd);
+ }
+ return(result);
+}
+
+#define CPUFREQ_NONE 0
+#define CPUFREQ_24 1
+#define CPUFREQ_25 2
+#define CPUFREQ_SYSFS 3
+
+static QString cpufreq_cpu = "";
+static QString cpufreq_minmax_frequency[2];
+
+// get CPUFreq scaling policies via the sysfs interface
+static int get_cpufreq_sysfs_state(QStringList &states, int &current, const QString cpu) {
+ QString cur, buffer;
+
+ // read current scaling policy
+ QFile f("/sys/devices/system/cpu/" + cpu + "/cpufreq/scaling_governor");
+ if(!f.open(IO_ReadOnly) || f.atEnd())
+ return CPUFREQ_NONE;
+ f.readLine(buffer, 256);
+ cur = buffer.stripWhiteSpace();
+ f.close();
+
+ // read available scaling policies
+ states.clear();
+ f.setName("/sys/devices/system/cpu/" + cpu + "/cpufreq/scaling_available_governors");
+ if(!f.open(IO_ReadOnly))
+ return CPUFREQ_NONE;
+ int count = 0;
+ if(!f.atEnd()) {
+ f.readLine(buffer, 1024);
+ QStringList l = QStringList::split(' ', buffer.stripWhiteSpace(), false);
+ for(unsigned int i = 0; i < l.size(); ++i, ++count) {
+ states.append(l[i].stripWhiteSpace());
+ if(states[i] == cur)
+ current = count;
+ }
+ }
+ f.close();
+
+ return CPUFREQ_SYSFS;
+}
+
+// get CPUFreq scaling policies via the 2.5 /proc interface
+// sample output of cat /proc/cpufreq:
+// minimum CPU frequency - maximum CPU frequency - policy
+// CPU 0 700000 kHz ( 70 %) - 1000000 kHz (100 %) - powersave
+static int get_cpufreq_25_state(QStringList &states, int &current) {
+ current = -1;
+ states.clear();
+
+ QFile f("/proc/cpufreq");
+ if (f.open(IO_ReadOnly)) {
+ while (!f.atEnd()) {
+ QString l;
+ f.readLine(l, 1024);
+ QRegExp rx("CPU.*\\d+.*(\\d+).*-.*(\\d+).*-\\W*(\\w*)");
+ if (rx.search(l) >= 0) {
+ cpufreq_minmax_frequency[0] = rx.cap(1);
+ cpufreq_minmax_frequency[1] = rx.cap(2);
+ if(rx.cap(3) == "performance")
+ current = 0;
+ else
+ current = 1;
+ break;
+ }
+ }
+ }
+ f.close();
+
+ if(current < 0)
+ return CPUFREQ_NONE;
+
+ // we don't know all available scaling governors, so use only a minimal set
+ states.append("performance");
+ states.append("powersave");
+ return CPUFREQ_25;
+}
+
+// get CPUFreq scaling policies via the 2.4 /proc interface
+// The old interface doesn't support policies yet, we only get the min and max frequency,
+// so we use these as performance states.
+static int get_cpufreq_24_state(QStringList &states, int &current, const QString cpu) {
+ QString buffer, cur;
+ states.clear();
+
+ // current frequency
+ QFile f("/proc/sys/cpu/" + cpu + "/speed");
+ if(!f.open(IO_ReadOnly) || f.atEnd())
+ return CPUFREQ_NONE;
+ f.readLine(buffer, 16);
+ f.close();
+ cur = buffer.stripWhiteSpace();
+
+ // read maximal and minimal frequency
+ const char* files[] = { "max", "min" };
+ for(int i = 0; i <= 1; ++i) {
+ f.setName("/proc/sys/cpu/" + cpu + "/speed-" + files[i]);
+ if(!f.open(IO_ReadOnly) || f.atEnd())
+ return CPUFREQ_NONE;
+ f.readLine(buffer, 16);
+ f.close();
+ cpufreq_minmax_frequency[i] = buffer;
+ unsigned int val = buffer.toUInt() / 1000;
+ states.append(i18n("%1 MHz").arg(val));
+ if(buffer.stripWhiteSpace() == cur)
+ current = i;
+ }
+ return CPUFREQ_24;
+}
+
+// check for CPUFreq support and get a list of all available scaling policies
+// this method doesn't support multiple CPU's (neither does get_acpi_list() above),
+// but this shouldn't be a problem on notebooks...
+static int get_cpufreq_state(bool force, QStringList &states, int &current) {
+ static int known = -1;
+
+ // check wether we already know which interface to use
+ if(!force && known >= 0) {
+ switch(known) {
+ case CPUFREQ_SYSFS:
+ return get_cpufreq_sysfs_state(states, current, cpufreq_cpu);
+ break;
+ case CPUFREQ_25:
+ return get_cpufreq_25_state(states, current);
+ break;
+ case CPUFREQ_24:
+ return get_cpufreq_24_state(states, current, cpufreq_cpu);
+ break;
+ default:
+ return CPUFREQ_NONE;
+ }
+ }
+
+ // look for the CPUFreq sysfs interface first
+ QDir dir("/sys/devices/system/cpu");
+ dir.setFilter(QDir::Dirs);
+ if(dir.isReadable()) {
+ for(unsigned int i = 0; !dir[i].isNull(); ++i) {
+ if(dir[i] == "." || dir[i] == "..")
+ continue;
+ cpufreq_cpu = dir[i];
+ if(get_cpufreq_sysfs_state(states, current, cpufreq_cpu))
+ return (known = CPUFREQ_SYSFS);
+ }
+ }
+
+ // try the /proc interface from the 2.5 kernel series next
+ if(get_cpufreq_25_state(states, current))
+ return (known = CPUFREQ_25);
+
+ // last chance: the /proc interface from the 2.4 kernel series
+ dir.setPath("/proc/sys/cpu");
+ dir.setFilter(QDir::Dirs);
+ if(dir.isReadable()) {
+ for(unsigned int i = 0; !dir[i].isNull(); ++i) {
+ if(dir[i] == "." || dir[i] == "..")
+ continue;
+ cpufreq_cpu = dir[i];
+ if(get_cpufreq_24_state(states, current, cpufreq_cpu))
+ return (known = CPUFREQ_24);
+ }
+ }
+
+ // no CPUFreq support found
+ return (known = CPUFREQ_NONE);
+}
+
+bool
+laptop_portable::get_system_performance(bool force, int &current, QStringList &s, bool *&active) // do something to help get system profiles from places like ACPI
+{
+ if(!acpi_performance_enabled)
+ return false;
+ static int known=0;
+ static int index=0;
+ static bool result = 0;
+ if (known != last_seed || force) {
+ known = last_seed;
+ performance_list.clear();
+ result = 0;
+ current = 0;
+ if (::has_acpi()) {
+ active = acpi_performance_enable;
+ result = get_acpi_list('P', acpi_performance_map, "/performance", performance_list, index, acpi_performance_cpu, force, acpi_performance_enable);
+ }
+ // CPUFreq support
+ if (!result && get_cpufreq_state(force, performance_list, index)) {
+ for(unsigned int i = 0; i < performance_list.size(); ++i)
+ acpi_performance_enable[i] = true;
+ active = acpi_performance_enable;
+ result = true;
+ }
+ if (!result) {
+ // INSERT HERE
+ }
+ }
+ current = index;
+ s = performance_list;
+ return(result);
+}
+
+bool
+laptop_portable::get_system_throttling(bool force, int &current, QStringList &s, bool *&active) // do something to help get system throttling data from places like ACPI
+{
+ static int known=0;
+ static int index=0;
+ static bool result = 0;
+ if (known != last_seed || force) {
+ known = last_seed;
+ throttle_list.clear();
+ result = 0;
+ current = 0;
+ if (::has_acpi() && acpi_throttle_enabled) {
+ active = acpi_throttle_enable;
+ result = get_acpi_list('T', acpi_throttle_map, "/throttling", throttle_list, index, acpi_throttle_cpu, force, acpi_throttle_enable);
+ }
+ if (!result) {
+ // INSERT HERE
+ }
+ }
+ current = index;
+ s = throttle_list;
+ return(result);
+}
+
+void
+laptop_portable::set_system_performance(QString val) // val = string given by get_system_performance above
+{
+ if(!acpi_performance_enabled)
+ return;
+ int current, result;
+ if((result = get_acpi_list('P', acpi_performance_map, "/performance", performance_list, current, acpi_performance_cpu, false, acpi_performance_enable))) {
+ char tmp[20];
+ int ind = performance_list.findIndex(val);
+ if (ind < 0 || ind >= MAP_SIZE || current == ind)
+ return;
+ snprintf(tmp, sizeof(tmp), "%d", acpi_performance_map[ind]);
+ tmp[sizeof(tmp)-1]=0;
+ ::invoke_acpi_helper("--performance", acpi_performance_cpu.latin1(), tmp);
+ return;
+ }
+ // CPUFreq support
+ if((result = get_cpufreq_state(false, performance_list, current))) {
+ if(performance_list[current] == val)
+ return;
+ QString tmp;
+ switch(result) {
+ case CPUFREQ_SYSFS:
+ invoke_acpi_helper("--cpufreq-sysfs", cpufreq_cpu.latin1(), val.latin1());
+ return;
+ case CPUFREQ_25:
+ tmp = cpufreq_minmax_frequency[0] + ":" + cpufreq_minmax_frequency[1] + ":" + val;
+ invoke_acpi_helper("--cpufreq-25", tmp.latin1(), 0);
+ return;
+ case CPUFREQ_24:
+ int target = performance_list.findIndex(val);
+ invoke_acpi_helper("--cpufreq-24", cpufreq_cpu.latin1(), cpufreq_minmax_frequency[target].latin1());
+ return;
+ }
+ }
+ // INSERT HERE
+ return;
+}
+
+void
+laptop_portable::set_system_throttling(QString val) // val = string given by get_system_throttle above
+{
+ if (::has_acpi()) {
+ char tmp[20];
+ int ind = throttle_list.findIndex(val);
+ if (ind < 0 || ind >= MAP_SIZE)
+ return;
+ snprintf(tmp, sizeof(tmp), "%d", acpi_throttle_map[ind]);
+ tmp[sizeof(tmp)-1]=0;
+ ::invoke_acpi_helper("--throttling", acpi_throttle_cpu.latin1(), tmp);
+ return;
+ }
+ // INSERT HERE
+ return;
+}
+
+static QString acpi_power_name, acpi_lid_name; // names of paths to ACPI lid states
+
+static bool
+acpi_check_button(const char *prefix, QString &result)
+{
+ DIR *dfd;
+ struct dirent *dp;
+ bool v=0;
+
+ dfd = opendir(prefix);
+ if (dfd) {
+ for (dp = readdir(dfd);dp ;dp = readdir(dfd)) {
+ if (strcmp(dp->d_name, ".") == 0 ||
+ strcmp(dp->d_name, "..") == 0)
+ continue;
+ QString name(prefix);
+ name += "/";
+ name += dp->d_name;
+ name += "/state";
+ if (::access(name.latin1(), R_OK)!=0)
+ continue;
+ QFile f(name);
+ if (f.open(IO_ReadOnly)) {
+ while (!f.atEnd()) {
+ QString l;
+ f.readLine(l, 500);
+ if (l.contains("state:")) {
+ result = name;
+ v = 1;
+ break;
+ }
+ }
+ f.close();
+ if (v)
+ break;
+ }
+ }
+ closedir(dfd);
+ }
+ return(v);
+}
+
+bool
+laptop_portable::has_button(LaptopButton l) // true if we have support for a particular button
+{
+ static int known[2]={0,0};
+ static bool result[2] = {0,0};
+ int type = (l==LidButton?0:1);
+ if (known[type] != last_seed) {
+ result[type] = 0;
+ known[type] = last_seed;
+ if (::has_acpi()) {
+ switch (l) {
+ case LidButton:
+ result[type] = ::acpi_check_button("/proc/acpi/button/lid", acpi_lid_name);
+ break;
+ case PowerButton:
+ result[type] = ::acpi_check_button("/proc/acpi/button/power", acpi_power_name);
+ break;
+ default:
+ break;
+ }
+ }
+ if (!result[type] && ::has_ibm() && l == LidButton)
+ result[type] = 1;
+ if (!result[type]) {
+ // INSERT HERE
+ }
+ }
+ return(result[type]);
+}
+
+bool
+laptop_portable::get_button(LaptopButton l) // true if a button is pressed
+{
+ if (::has_acpi()) {
+ QString name;
+ switch (l) {
+ case LidButton:
+ name = acpi_lid_name;
+ break;
+ case PowerButton:
+ name = acpi_power_name;
+ break;
+ default:
+ break;
+ }
+ if (!name.isEmpty()) {
+ QFile f(name);
+ if (f.open(IO_ReadOnly)) {
+ while (!f.atEnd()) {
+ QString l;
+ f.readLine(l, 500);
+ QStringList ll = QStringList::split(':',l,false);
+ if (ll[0].stripWhiteSpace() == "state") {
+ if (ll[1].stripWhiteSpace() == "open") {
+ f.close();
+ return(0);
+ }
+ if (ll[1].stripWhiteSpace() == "closed") {
+ f.close();
+ return(1);
+ }
+ break;
+ }
+ }
+ f.close();
+ }
+
+ }
+ }
+ if (::has_ibm() && l == LidButton) {
+ smapidev_sensorinfo_t t;
+ if (smapidev_GetSensorInfo(ibm_fd, &t) == 0)
+ return(t.fLidClosed != 0);
+ }
+ // INSERT HERE
+ return(0);
+}
+
+#elif defined(__FreeBSD__) && HAVE_MACHINE_APM_BIOS_H
+
+/*
+** This is the FreeBSD-specific code.
+*/
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <machine/apm_bios.h>
+#include <sys/stat.h>
+#include <qpushbutton.h>
+#include <qobject.h>
+#include <kactivelabel.h>
+#include <kprocess.h>
+
+#define APMDEV "/dev/apm"
+
+// FreeBSD support by yours truly. Yay.
+// Actually this code was "adapted" from apm(8) from
+// FreeBSD's collection of tools. The original apm program
+// was pieced together by Tatsumi Hosokawa <hosokawa@jp.FreeBSD.org> in 1994
+
+//
+// returns 1 if we support power management
+//
+
+#include <iostream>
+using namespace std;
+
+//
+// something changed maybe we need to check out environment again
+//
+void
+laptop_portable::power_management_restart()
+{
+ // INSERT HERE
+}
+
+int
+laptop_portable::has_power_management()
+{
+ int ret, fd = ::open(APMDEV, O_RDWR);
+
+ if (fd == -1) {
+ return 0;
+ }
+
+ struct apm_info info;
+ ret=ioctl(fd, APMIO_GETINFO, &info);
+ ::close(fd);
+
+ if (ret == -1) {
+ return 0;
+ }
+
+ return info.ai_status;
+}
+//
+// returns 1 if the BIOS returns the time left in the battery rather than a % of full
+//
+int laptop_portable::has_battery_time()
+{
+ int ret, fd = ::open(APMDEV, O_RDWR);
+
+ if (fd == -1)
+ return 0;
+
+ struct apm_info info;
+ ret=ioctl(fd, APMIO_GETINFO, &info);
+ ::close(fd);
+
+ if (ret == -1)
+ return 0;
+
+ return (info.ai_batt_time != 0xffff);
+}
+
+//
+// returns 1 if we can perform a change-to-suspend-mode operation for the user
+// (has_power_management() has already returned 1)
+//
+int laptop_portable::has_suspend()
+{
+ int ret, fd = ::open(APMDEV, O_RDWR);
+
+ if (fd == -1)
+ return 0;
+
+ struct apm_info info;
+ ret=ioctl(fd, APMIO_GETINFO, &info);
+ ::close(fd);
+
+ if (ret == -1)
+ return 0;
+
+ return (info.ai_capabilities & 0x02);
+}
+//
+// returns 1 if we can perform a change-to-standby-mode operation for the user
+// (has_power_management() has already returned 1)
+//
+int laptop_portable::has_standby()
+{
+ int ret, fd = ::open(APMDEV, O_RDWR);
+
+ if (fd == -1)
+ return 0;
+
+ struct apm_info info;
+ ret=ioctl(fd, APMIO_GETINFO, &info);
+ ::close(fd);
+
+ if (ret == -1)
+ return 0;
+
+ return (info.ai_capabilities & 0x01);
+}
+//
+// returns 1 if we can perform a change-to-hibernate-mode for a user
+// (has_power_management() has already returned 1) [hibernate is the save-to-disk mode
+// not supported by linux - different laptops have their own - the first here is for
+// a ThinkPad]
+//
+int laptop_portable::has_hibernation()
+{
+ if (::access(PATH_TPCTL, X_OK)==0)
+ return(1);
+ return(0);
+}
+
+//
+// explain to the user what they need to do if has_power_management() returned 0
+// to get any software they lack
+//
+KActiveLabel *laptop_portable::no_power_management_explanation(QWidget *parent)
+{
+ int fd;
+ KActiveLabel *explain;
+
+ fd = ::open(APMDEV, O_RDWR);
+ if (fd == -1) {
+ switch (errno) {
+ case ENOENT:
+ explain = new KActiveLabel(i18n("There is no /dev/apm file on this system. Please review the FreeBSD handbook on how to create a device node for the APM device driver (man 4 apm)."), parent);
+ break;
+ case EACCES:
+ explain = new KActiveLabel(i18n("Your system has the proper device node for APM support, however you cannot access it. If you are logged in as root right now, you have a problem, otherwise contact your local sysadmin and ask for read/write access to /dev/apm."), parent);
+ break;
+ case ENXIO:
+ explain = new KActiveLabel(i18n("Your kernel lacks support for Advanced Power Management."), parent);
+ break;
+ break;
+ default:
+ explain = new KActiveLabel(i18n("There was a generic error while opening /dev/apm."), parent);
+ break;
+ }
+ } else {
+ close(fd);
+ explain = new KActiveLabel(i18n("APM has most likely been disabled."), parent);
+ }
+
+ return(explain);
+}
+
+//
+// explain to the user what they need to do to get suspend/resume to work from user mode
+//
+QLabel *laptop_portable::how_to_do_suspend_resume(QWidget *parent)
+{
+ QLabel* note = new QLabel(" ", parent);
+ return(note);
+}
+
+
+//
+// pcmcia support - this will be replaced by better - pcmcia support being worked on by
+// others
+//
+QLabel *laptop_portable::pcmcia_info(int x, QWidget *parent)
+{
+ if (x == 0)
+ return(new QLabel(i18n("No PCMCIA controller detected"), parent));
+ return(new QLabel(i18n(""), parent));
+}
+//
+// puts us into standby mode
+//
+void laptop_portable::invoke_standby()
+{
+ int fd = ::open(APMDEV, O_RDWR);
+
+ if (fd == -1)
+ return;
+
+ ioctl(fd, APMIO_STANDBY, NULL);
+ ::close(fd);
+
+ return;
+}
+
+//
+// puts us into suspend mode
+//
+void laptop_portable::invoke_suspend()
+{
+ int fd = ::open(APMDEV, O_RDWR);
+
+ if (fd == -1)
+ return;
+
+ ioctl(fd, APMIO_SUSPEND, NULL);
+ ::close(fd);
+
+ return;
+}
+//
+// puts us into hibernate mode
+//
+void laptop_portable::invoke_hibernation()
+{
+ KProcess thisProc;
+
+ if (::access(PATH_TPCTL, X_OK)==0) {
+ thisProc << PATH_TPCTL;
+ thisProc << "---hibernate";
+ thisProc.start(KProcess::Block);
+ return;
+ }
+}
+
+//
+//ACPI specific - chances are you don't need to implement this one
+//
+void
+laptop_portable::acpi_set_mask(bool, bool, bool, bool, bool )
+{
+ // INSERT HERE
+}
+
+int laptop_portable::has_acpi(int)
+{
+ // INSERT HERE
+ return (0);
+}
+
+int laptop_portable::has_apm(int type)
+{
+ if (type == 1) // implement me .... this is the hook that pops up the panel for making /usr/sbin/apm setuid
+ return(0); // or in this case you could make an acpi_helper type app freebsd
+ return (1);
+}
+
+void
+laptop_portable::apm_set_mask(bool , bool )
+{
+}
+
+
+//
+// adds extra widgets to the battery panel
+//
+void
+laptop_portable::extra_config(QWidget * /*parent*/, KConfig * /*config*/, QVBoxLayout * /*layout*/)
+{
+ // INSERT HERE
+}
+
+
+
+//
+// return current battery state
+//
+struct power_result laptop_portable::poll_battery_state()
+{
+ struct power_result p;
+ int ret;
+
+ int fd = ::open(APMDEV, O_RDWR);
+
+ if (fd == -1)
+ goto bad;
+
+ struct apm_info info;
+ ret=ioctl(fd, APMIO_GETINFO, &info);
+ ::close(fd);
+
+ if (ret == -1)
+ goto bad;
+
+ p.powered = info.ai_acline;
+ p.percentage = (info.ai_batt_life==255 ? 100 : info.ai_batt_life);
+ p.time = (info.ai_batt_time != 0xffff ? info.ai_batt_time/60 : -1);
+ return(p);
+
+bad:
+ p.powered = 1;
+ p.percentage = 100;
+ p.time = 0;
+ return(p);
+}
+
+//
+// return the system load
+//
+
+bool laptop_portable::has_lav() { return 0; }
+
+float laptop_portable::get_load_average()
+{
+ // INSERT HERE
+ return(-1);
+}
+
+int laptop_portable::has_cpufreq() {
+ // INSERT HERE
+ return 0;
+}
+
+QString laptop_portable::cpu_frequency() {
+ // INSERT HERE
+ return "";
+}
+
+int
+laptop_portable::has_brightness()
+{
+ // INSERT HERE
+ return 0;
+}
+
+void
+laptop_portable::set_brightness(bool /*blank*/, int /*val*/) // val = 0-255 255 brightest, 0 means dimmest (if !blank it must be still visible),
+{
+ // INSERT HERE
+}
+
+int
+laptop_portable::get_brightness()
+{
+ // INSERT HERE
+ return(-1); // means can't extract it
+}
+
+bool
+laptop_portable::get_system_performance(bool, int &current, QStringList &s, bool *&) // do something to help get system profiles from places like ACPI
+{
+ // INSERT HERE
+ current = 0;
+ s.clear();
+ return(0); // if no profiles are available
+}
+
+bool
+laptop_portable::get_system_throttling(bool, int &current, QStringList &s, bool *&) // do something to help get system throttling data from places like ACPI
+{
+ // INSERT HERE
+ current = 0;
+ s.clear();
+ return(0);
+}
+
+void
+laptop_portable::set_system_performance(QString)
+{
+ // INSERT HERE
+}
+
+void
+laptop_portable::set_system_throttling(QString)
+{
+ // INSERT HERE
+}
+
+bool
+laptop_portable::has_button(LaptopButton) // true if we have support for a particular button
+{
+ // INSERT HERE
+ return(0);
+}
+
+bool
+laptop_portable::get_button(LaptopButton) // true if a button is pressed
+{
+ // INSERT HERE
+ return(0);
+}
+
+void
+laptop_portable::get_battery_status(int &num_batteries, QStringList &names, QStringList &state, QStringList &values) // get multiple battery status
+{
+ struct power_result r;
+
+ if (!has_power_management()) {
+ num_batteries = 0;
+ names.clear();
+ state.clear();
+ values.clear();
+ return;
+ }
+
+ // INSERT HERE
+
+ num_batteries = 1;
+ r = poll_battery_state();
+ names.append("BAT1");
+ state.append("yes");
+ QString s;
+ s.setNum(r.percentage);
+ values.append(s);
+}
+
+bool
+laptop_portable::has_software_suspend(int /*type*/)
+{
+ return false; // (::has_software_suspend(type));
+}
+
+void
+laptop_portable::software_suspend_set_mask(bool /*hibernate*/)
+{
+ // software_suspend_is_preferred = hibernate;
+}
+
+
+#elif defined(__NetBSD_APM__)
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <machine/apmvar.h>
+#include <iostream.h>
+
+//
+// klaptopdeamon interface to NetBSD 1.5 apm.
+// Scott Presnell, srp@zgi.com, srp@tworoads.net
+// Fri Jun 29 17:21:25 PDT 2001
+// Tested on Dell I4K running NetBSD 1.5R
+//
+#define APMDEV "/dev/apm"
+
+//
+// Check for apm in kernel by talking to /dev/apm
+// (opening read only is allowed by any process).
+// returns 1 if we support power management
+//
+int
+laptop_portable::has_power_management()
+{
+ int ret, fd = ::open(APMDEV, O_RDONLY);
+
+ if (fd == -1) {
+ return 0;
+ }
+
+ struct apm_power_info info;
+ ret=ioctl(fd, APM_IOC_GETPOWER, &info);
+ ::close(fd);
+
+ if (ret == -1) {
+ return 0;
+ }
+
+ return 1;
+}
+
+void
+laptop_portable::power_management_restart()
+{
+ // INSERT HERE
+}
+
+//
+// returns 1 if the BIOS returns the time left in the battery rather than a % of full
+//
+int laptop_portable::has_battery_time()
+{
+ int ret, fd = ::open(APMDEV, O_RDONLY);
+
+ if (fd == -1)
+ return 0;
+
+ struct apm_power_info info;
+ ret=ioctl(fd, APM_IOC_GETPOWER, &info);
+ ::close(fd);
+
+ if (ret == -1)
+ return 0;
+
+ return (info.minutes_left != 0xffff);
+}
+
+//
+// returns 1 if we can perform a change-to-suspend-mode operation for the user
+// (ust check to see if we have the binary)
+// (has_power_management() has already returned 1)
+//
+int laptop_portable::has_suspend()
+{
+
+ struct stat s;
+ if (stat("/usr/sbin/apm", &s))
+ return(0);
+ return(1);
+}
+
+//
+// returns 1 if we can perform a change-to-standby-mode operation for the user
+// (just check to see if we have the binary)
+// (has_power_management() has already returned 1)
+//
+int laptop_portable::has_standby()
+{
+
+ struct stat s;
+ if (stat("/usr/sbin/apm", &s))
+ return(0);
+ return(1);
+}
+
+//
+// returns 1 if we can perform a change-to-hibernate-mode for a user
+// (has_power_management() has already returned 1) [hibernate is the save-to-disk mode
+// not supported by linux - different laptops have their own - the first here is for
+// a ThinkPad]
+// No support in NetBSD at this time.
+//
+int laptop_portable::has_hibernation()
+{
+ // INSERT HERE
+ return(0);
+}
+
+//
+// explain to the user what they need to do if has_power_management() returned 0
+// to get any software they lack
+//
+KActiveLabel *laptop_portable::no_power_management_explanation(QWidget *parent)
+{
+ int fd;
+ KActiveLabel *explain;
+
+ fd = ::open(APMDEV, O_RDONLY);
+ if (fd == -1) {
+ switch (errno) {
+ case ENOENT:
+ explain = new KActiveLabel(i18n("There is no /dev/apm file on this system. Please review the NetBSD documentation on how to create a device node for the APM device driver (man 4 apm)."), parent);
+ break;
+ case EACCES:
+ explain = new KActiveLabel(i18n("Your system has the proper device node for APM support, however you cannot access it. If you have APM compiled into the kernel this should not happen."), parent);
+ break;
+ case ENXIO:
+ explain = new KActiveLabel(i18n("Your kernel lacks support for Advanced Power Management."), parent);
+ break;
+ break;
+ default:
+ explain = new KActiveLabel(i18n("There was a generic error while opening /dev/apm."), parent);
+ break;
+ }
+ } else {
+ close(fd);
+ explain = new KActiveLabel(i18n("APM has most likely been disabled."), parent);
+ }
+
+ return(explain);
+}
+
+//
+// explain to the user what they need to do to get suspend/resume to work from user mode
+//
+QLabel *laptop_portable::how_to_do_suspend_resume(QWidget *parent)
+{
+ // INSERT HERE
+ QLabel* note = new QLabel(" ", parent);
+ return(note);
+}
+
+//
+// pcmcia support - this will be replaced by better - pcmcia support being worked on by
+// others
+//
+QLabel *laptop_portable::pcmcia_info(int x, QWidget *parent)
+{
+ // INSERT HERE
+ if (x == 0)
+ return(new QLabel(i18n("No PCMCIA controller detected"), parent));
+ return(new QLabel(i18n(""), parent));
+}
+
+//
+// puts us into standby mode
+// Use apm rather than ioctls in case they are running apmd
+// (as they should be).
+//
+void laptop_portable::invoke_standby()
+{
+ KProcess proc;
+ proc << "/usr/sbin/apm";
+ proc << "-S";
+ proc.start(KProcess::Block); // helper runs fast and we want to see the result
+}
+
+//
+// puts us into suspend mode
+// Use apm rather than ioctls in case they are running apmd
+// (as they should be).
+//
+void laptop_portable::invoke_suspend()
+{
+ KProcess proc;
+ proc << "/usr/sbin/apm";
+ proc << "-z";
+ proc.start(KProcess::Block); // helper runs fast and we want to see the result
+}
+
+//
+// puts us into hibernate mode
+// No hibernate mode for NetBSD.
+//
+void laptop_portable::invoke_hibernation()
+{
+ // INSERT HERE
+ return;
+}
+
+//
+//ACPI specific - chances are you don't need to implement this one
+//
+void
+laptop_portable::acpi_set_mask(bool, bool, bool, bool, bool )
+{
+ // INSERT HERE
+}
+
+int laptop_portable::has_acpi(int)
+{
+ // INSERT HERE
+ return (0);
+}
+
+int laptop_portable::has_apm(int type)
+{
+ if (type == 1) // implement me .... this is the hook that pops up the panel for making /usr/sbin/apm setuid
+ return(0);
+ return (1);
+}
+
+void
+laptop_portable::apm_set_mask(bool , bool )
+{
+}
+
+
+//
+// return current battery state
+//
+struct power_result laptop_portable::poll_battery_state()
+{
+ struct power_result p;
+ int ret;
+
+ int fd = ::open(APMDEV, O_RDONLY);
+
+ if (fd == -1)
+ goto bad;
+
+ struct apm_power_info info;
+ ret=ioctl(fd, APM_IOC_GETPOWER, &info);
+ ::close(fd);
+
+ if (ret == -1)
+ goto bad;
+
+ p.powered = (info.ac_state == APM_AC_ON);
+ p.percentage = (info.battery_life==255 ? 100 : info.battery_life);
+ p.time = (info.minutes_left != 0xffff ? info.minutes_left : -1);
+ return(p);
+
+bad:
+ p.powered = 1;
+ p.percentage = 100;
+ p.time = 0;
+ return(p);
+}
+
+//
+// return the system load
+//
+
+bool laptop_portable::has_lav() { return 0; }
+
+float laptop_portable::get_load_average()
+{
+ // INSERT HERE
+ return(-1);
+}
+
+
+int laptop_portable::has_cpufreq() {
+ // INSERT HERE
+ return 0;
+}
+
+QString laptop_portable::cpu_frequency() {
+ // INSERT HERE
+ return "";
+}
+
+int
+laptop_portable::has_brightness()
+{
+ // INSERT HERE
+ return 0;
+}
+
+void
+laptop_portable::set_brightness(bool blank, int val) // val = 0-255 255 brightest, 0 means dimmest (if !blank it must be still visible),
+{
+ // INSERT HERE
+}
+
+int
+laptop_portable::get_brightness()
+{
+ // INSERT HERE
+ return(-1); // means can't extract it
+}
+
+bool
+laptop_portable::get_system_throttling(bool, int &current, QStringList &s) // do something to help get system throttling data from places like ACPI
+{
+ // INSERT HERE
+ current = 0;
+ s.clear();
+ return(0);
+}
+
+void
+laptop_portable::set_system_performance(QString)
+{
+ // INSERT HERE
+}
+
+void
+laptop_portable::set_system_throttling(QString)
+{
+ // INSERT HERE
+}
+
+bool
+laptop_portable::has_button(LaptopButton) // true if we have support for a particular button
+{
+ // INSERT HERE
+ return(0);
+}
+
+bool
+laptop_portable::get_button(LaptopButton) // true if a button is pressed
+{
+ // INSERT HERE
+ return(0);
+}
+
+void
+laptop_portable::get_battery_status(int &num_batteries, QStringList &names, QStringList &state, QStringList &values) // get multiple battery status
+{
+ struct power_result r;
+
+ if (!has_power_management()) {
+ num_batteries = 0;
+ names.clear();
+ state.clear();
+ values.clear();
+ return;
+ }
+
+ // INSERT HERE
+
+ num_batteries = 1;
+ r = poll_battery_state();
+ names.append("BAT1");
+ state.append("yes");
+ QString s;
+ s.setNum(r.percentage);
+ values.append(s);
+}
+
+#else
+
+/*
+** This is utterly generic code.
+*/
+
+//
+// something changed maybe we need to check out environment again
+//
+void
+laptop_portable::power_management_restart()
+{
+ // INSERT HERE
+}
+
+//
+// returns 1 if we support power management
+//
+int
+laptop_portable::has_power_management()
+{
+ // INSERT HERE
+ return(0);
+}
+
+//
+// returns 1 if the BIOS returns the time left in the battery rather than a % of full
+//
+int laptop_portable::has_battery_time()
+{
+ // INSERT HERE
+ return (0);
+}
+
+//
+// returns 1 if we can perform a change-to-suspend-mode operation for the user
+// (has_power_management() has already returned 1)
+//
+int laptop_portable::has_suspend()
+{
+ // INSERT HERE
+ return(0);
+}
+//
+// returns 1 if we can perform a change-to-standby-mode operation for the user
+// (has_power_management() has already returned 1)
+//
+int laptop_portable::has_standby()
+{
+ // INSERT HERE
+ return(0);
+}
+//
+// returns 1 if we can perform a change-to-hibernate-mode for a user
+// (has_power_management() has already returned 1) [hibernate is the save-to-disk mode
+// not supported by linux]
+//
+int laptop_portable::has_hibernation()
+{
+ // INSERT HERE
+ return(0);
+}
+
+//
+// explain to the user what they need to do if has_power_management() returned 0
+// to get any software they lack
+//
+KActiveLabel *laptop_portable::no_power_management_explanation(QWidget *parent)
+{
+ KActiveLabel* explain = new KActiveLabel(i18n("Your computer or operating system is not supported by the current version of the\nKDE laptop control panels. If you want help porting these panels to work with it\nplease contact paul@taniwha.com."), parent);
+ // INSERT HERE
+ return(explain);
+}
+
+//
+// explain to the user what they need to do to get suspend/resume to work from user mode
+//
+QLabel *laptop_portable::how_to_do_suspend_resume(QWidget *parent)
+{
+ QLabel* note = new QLabel(" ", parent);
+ // INSERT HERE
+ return(note);
+}
+
+
+//
+// pcmcia support - this will be replaced by better - pcmcia support being worked on by
+// others
+//
+QLabel *laptop_portable::pcmcia_info(int x, QWidget *parent)
+{
+ // INSERT HERE
+ if (x == 0)
+ return(new QLabel(i18n("No PCMCIA controller detected"), parent));
+ return(new QLabel(i18n(""), parent));
+}
+//
+// puts us into standby mode
+//
+void laptop_portable::invoke_standby()
+{
+ // INSERT HERE
+}
+
+//
+// puts us into suspend mode
+//
+void laptop_portable::invoke_suspend()
+{
+ // INSERT HERE
+}
+//
+// puts us into hibernate mode
+//
+void laptop_portable::invoke_hibernation()
+{
+ // INSERT HERE
+}
+
+//
+//ACPI specific - chances are you don't need to implement this one
+//
+void
+laptop_portable::acpi_set_mask(bool, bool, bool, bool, bool )
+{
+ // INSERT HERE
+}
+
+int laptop_portable::has_acpi(int)
+{
+ // INSERT HERE
+ return (0);
+}
+
+void
+laptop_portable::apm_set_mask(bool, bool)
+{
+ // INSERT HERE
+}
+
+int laptop_portable::has_apm(int)
+{
+ // INSERT HERE
+ return (0);
+}
+
+
+//
+// adds extra widgets to the battery panel
+//
+void
+laptop_portable::extra_config(QWidget *parent, KConfig *config, QVBoxLayout *layout)
+{
+ // INSERT HERE
+}
+
+//
+// return current battery state
+//
+struct power_result laptop_portable::poll_battery_state()
+{
+ struct power_result p;
+ // INSERT HERE
+ p.powered = 0;
+ p.percentage = 0;
+ p.time = 0;
+ return(p);
+}
+
+//
+// return the system load
+//
+
+bool laptop_portable::has_lav() { return 0; }
+
+float laptop_portable::get_load_average()
+{
+ // INSERT HERE
+ return(-1);
+}
+
+int laptop_portable::has_cpufreq() {
+ // INSERT HERE
+ return 0;
+}
+
+QString laptop_portable::cpu_frequency() {
+ // INSERT HERE
+ return "";
+}
+
+int
+laptop_portable::has_brightness()
+{
+ // INSERT HERE
+ return 0;
+}
+
+void
+laptop_portable::set_brightness(bool blank, int val) // val = 0-255 255 brightest, 0 means dimmest (if !blank it must be still visible),
+{
+ // INSERT HERE
+}
+
+int
+laptop_portable::get_brightness()
+{
+ // INSERT HERE
+ return(-1); // means can't extract it
+}
+
+bool
+laptop_portable::get_system_performance(bool, int &current, QStringList &s, bool *&) // do something to help get system profiles from places like ACPI
+{
+ // INSERT HERE
+ current = 0;
+ s.clear();
+ return(0); // if no profiles are available
+}
+
+bool
+laptop_portable::get_system_throttling(bool, int &current, QStringList &s, bool *&) // do something to help get system throttling data from places like ACPI
+{
+ // INSERT HERE
+ current = 0;
+ s.clear();
+ return(0);
+}
+
+void
+laptop_portable::set_system_performance(QString)
+{
+ // INSERT HERE
+}
+
+void
+laptop_portable::set_system_throttling(QString)
+{
+ // INSERT HERE
+}
+
+bool
+laptop_portable::has_button(LaptopButton) // true if we have support for a particular button
+{
+ // INSERT HERE
+ return(0);
+}
+
+bool
+laptop_portable::get_button(LaptopButton) // true if a button is pressed
+{
+ // INSERT HERE
+ return(0);
+}
+
+void
+laptop_portable::get_battery_status(int &num_batteries, QStringList &names, QStringList &state, QStringList &values) // get multiple battery status
+{
+ struct power_result r;
+
+ if (!has_power_management()) {
+ num_batteries = 0;
+ names.clear();
+ state.clear();
+ values.clear();
+ return;
+ }
+
+ // INSERT HERE
+
+ num_batteries = 1;
+ r = poll_battery_state();
+ names.append("BAT1");
+ state.append("yes");
+ QString s;
+ s.setNum(r.percentage);
+ values.append(s);
+}
+
+bool
+laptop_portable::has_software_suspend(int type)
+{
+ return false; // (::has_software_suspend(type));
+}
+
+void
+laptop_portable::software_suspend_set_mask(bool hibernate)
+{
+ // software_suspend_is_preferred = hibernate;
+}
+#endif
diff --git a/klaptopdaemon/portable.h b/klaptopdaemon/portable.h
new file mode 100644
index 0000000..62d325c
--- /dev/null
+++ b/klaptopdaemon/portable.h
@@ -0,0 +1,147 @@
+#include <qlabel.h>
+#include <kactivelabel.h>
+#include <kconfig.h>
+#include <qvgroupbox.h>
+#include <qstringlist.h>
+
+#ifndef PORTABLE_H
+#define PORTABLE_H
+/*
+ * Copyright (c) 2002 Paul Campbell <paul@taniwha.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+struct power_result {
+ int powered ; // true if we're plugged into the wall
+ int percentage; // value 0-100 percentage of battery left
+ int time; // time in minutes left - -1 if this is not supported by the BIOS
+};
+
+
+// ATTENTION: if you change something in here, please update ALL of the
+// ported sections in the implementation file!
+
+class KDE_EXPORT laptop_portable {
+public:
+ static void power_management_restart(); // reset internal state
+ static int has_power_management(); // returns 1 if this computer has power management
+ static int has_battery_time(); // returns 1 if this give BIOS battery time info
+
+ /**
+ * Returns 1 if this computer can perform a suspend, i.e. supports some kind
+ * of suspend-to-ram energy saving mode (average wakeup time and energy
+ * saving).
+ */
+ static int has_suspend();
+
+ /**
+ * Returns 1 if this computer can perform a standby, i.e. supports an energy
+ * saving mode with a very fast wakeup time (neither suspend-to-disk nor
+ * suspend-to-ram).
+ */
+ static int has_standby();
+
+ /**
+ * Returns 1 if this computer can perform hibernatation, i.e. supports some
+ * kind of suspend-to-disk energy saving mode (highest energy saving,
+ * slowest wakeup time).
+ */
+ static int has_hibernation();
+
+ static int has_apm(int); // returns 1 if this computer has linux-style apm of some particular type
+ static int has_apm() { return has_apm(0); } // returns 1 if this computer has linux-style apm
+ static int has_acpi(int); // returns 1 if this computer has linux-style acpi of some particular type
+ static int has_acpi() { return has_acpi(0); } // returns 1 if this computer has linux-style acpi
+ static bool has_software_suspend(int type); // // returns 1 if the system has software suspend available
+ static bool has_software_suspend() { return has_software_suspend(0); }
+ static int has_cpufreq(); // returns 1 if this computer can scale the cpu frequency
+ static int has_brightness(); // returns 1 if this computer can set tyhe back panel brightness
+ static void set_brightness(bool blank, int val); // val = 0-255 255 brightest, 0 means dimmest (if !blank it must be still visible),
+ static int get_brightness(); // returns 0-255 brightness, -1 if you can't
+ static QString cpu_frequency(); // Returns the cpu freq.
+ static KActiveLabel *no_power_management_explanation(QWidget *parent);
+ static QLabel *how_to_do_suspend_resume(QWidget *parent);
+ static QLabel *pcmcia_info(int x, QWidget *parent);
+
+ /**
+ * Put this computer into standby mode.
+ * @see has_standby()
+ */
+ static void invoke_standby();
+
+ /**
+ * Put this computer into suspend mode.
+ * @see has_suspend()
+ */
+ static void invoke_suspend();
+
+ /**
+ * Put this computer into hibernatation mode.
+ * @see has_hibernation()
+ */
+ static void invoke_hibernation();
+
+ static struct power_result poll_battery_state();
+ static void get_battery_status(int &num_batteries, QStringList &names, QStringList &state, QStringList &values); // get multiple battery status
+ static bool has_lav(); // true if the following returns a valid value
+ static float get_load_average(); // current short term load average
+ static void extra_config(QWidget *parent, KConfig *config, QVBoxLayout *layout);
+ static void acpi_set_mask(bool standby, bool suspend, bool hibernate, bool perf, bool throttle);
+ static void apm_set_mask(bool standby, bool suspend);
+ static void software_suspend_set_mask(bool hibernate);
+
+ /**
+ * Get a list of available performance profiles.
+ * @param force - Force re-evaluation or use cached values.
+ * @param current - Index of the currently active profile.
+ * @param s - A list of available profiles.
+ * @param active - Marks profiles as enabled or disabled (used e.g. for ACPI
+ * limits).
+ * @return True if this system provides performance profiles.
+ */
+ static bool get_system_performance(bool force, int &current, QStringList &s, bool *&active);
+
+ /**
+ * Set performance profile.
+ * @param val - Name of the performance profile as provided by
+ * get_system_performance().
+ */
+ static void set_system_performance(QString val);
+
+ /**
+ * Get a list of available throttling levels.
+ * @param force - Force re-evaluation or use cached values.
+ * @param current - Index of the currently active throttling level.
+ * @param s - A list of available throttling levels.
+ * @param active - Marks throttling labels as enabled or disabled (used e.g.
+ * for ACPI limits).
+ * @return True if this system provides throttling levels.
+ */
+ static bool get_system_throttling(bool force, int &current, QStringList &s, bool *&active);
+
+ /**
+ * Set throttling level.
+ * @param val - Name of the throttling level as provided by
+ * get_system_throttling().
+ */
+ static void set_system_throttling(QString val);
+
+ enum LaptopButton {LidButton=0, PowerButton};
+ static bool has_button(LaptopButton p); // true if we have support for a particular button
+ static bool get_button(LaptopButton p); // true if a button is pressed
+};
+
+#endif
diff --git a/klaptopdaemon/power.cpp b/klaptopdaemon/power.cpp
new file mode 100644
index 0000000..2477cee
--- /dev/null
+++ b/klaptopdaemon/power.cpp
@@ -0,0 +1,587 @@
+/*
+ * power.cpp
+ *
+ * Copyright (c) 1999 Paul Campbell <paul@taniwha.com>
+ * Copyright (c) 2002 Marc Mutz <mutz@kde.org>
+ *
+ * Requires the Qt widget libraries, available at no cost at
+ * http://www.troll.no/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "power.h"
+#include "portable.h"
+#include "version.h"
+
+#include <kglobal.h>
+#include <klocale.h>
+#include <kconfig.h>
+#include <knumvalidator.h>
+#include <kdialog.h>
+#include <kapplication.h>
+#include <kcombobox.h>
+#include <knuminput.h>
+
+#include <qlayout.h>
+#include <qvbuttongroup.h>
+#include <qspinbox.h>
+#include <qradiobutton.h>
+#include <qcheckbox.h>
+#include <qhbox.h>
+#include <qslider.h>
+#include <qtooltip.h>
+extern void wake_laptop_daemon();
+
+PowerConfig::PowerConfig (QWidget * parent, const char *name)
+ : KCModule(parent, name),
+ nopowerBox(0),
+ nopowerStandby(0),
+ nopowerSuspend(0),
+ nopowerOff(0),
+ nopowerHibernate(0),
+ nopowerBrightness(0),
+ nopowerValBrightness(0),
+ nopowerThrottle(0),
+ nopowerValThrottle(0),
+ nopowerPerformance(0),
+ nopowerValPerformance(0),
+
+ powerBox(0),
+ powerStandby(0),
+ powerSuspend(0),
+ powerOff(0),
+ powerHibernate(0),
+ powerBrightness(0),
+ powerValBrightness(0),
+ powerThrottle(0),
+ powerValThrottle(0),
+ powerPerformance(0),
+ powerValPerformance(0),
+
+
+ noeditwait(0),
+ editwait(0),
+ enablelav(0),
+ noenablelav(0),
+ noeditlav(0),
+ editlav(0)
+{
+ KGlobal::locale()->insertCatalogue("klaptopdaemon"); // For translation of klaptopdaemon messages
+
+ apm = laptop_portable::has_power_management();
+ config = new KConfig("kcmlaptoprc");
+ int can_brightness = laptop_portable::has_brightness();
+ QStringList throttle_list;
+ int current_throttle;
+ bool *active_list;
+ bool has_throttle = laptop_portable::get_system_throttling(0, current_throttle, throttle_list, active_list);
+ QStringList performance_list;
+ int current_performance;
+ bool has_performance = laptop_portable::get_system_performance(0, current_performance, performance_list, active_list);
+
+ if (!apm && !can_brightness && !has_throttle && !has_performance) {
+ QVBoxLayout *top_layout = new QVBoxLayout(this, KDialog::marginHint(),
+ KDialog::spacingHint());
+
+ KActiveLabel* explain = laptop_portable::no_power_management_explanation(this);
+ top_layout->addWidget(explain);
+
+ top_layout->addStretch(1);
+ } else {
+ int can_standby = laptop_portable::has_standby();
+ int can_suspend = laptop_portable::has_suspend();
+ int can_hibernate = laptop_portable::has_hibernation();
+
+ if (!can_standby && !can_suspend && !can_hibernate && !can_brightness && !has_throttle && !has_performance)
+ apm = 0;
+ if (!apm) {
+ QVBoxLayout *top_layout = new QVBoxLayout(this, KDialog::marginHint(),
+ KDialog::spacingHint());
+
+ QLabel* explain = laptop_portable::how_to_do_suspend_resume(this);
+ top_layout->addWidget(explain);
+
+ top_layout->addStretch(1);
+ } else {
+ QVBoxLayout *top_layout = new QVBoxLayout(this, KDialog::marginHint(),
+ KDialog::spacingHint());
+ QHBoxLayout *hlay = new QHBoxLayout( top_layout );
+
+ nopowerBox = new QVButtonGroup(i18n("Not Powered"), this);
+ QToolTip::add( nopowerBox, i18n( "Options in this box apply when the laptop is unplugged from the wall and has been idle for a while" ) );
+ nopowerBox->layout()->setSpacing( KDialog::spacingHint() );
+ hlay->addWidget( nopowerBox );
+
+ if (can_standby) {
+ nopowerStandby = new QRadioButton(i18n("Standb&y"), nopowerBox);
+ QToolTip::add( nopowerStandby, i18n( "Causes the laptop to change to a standby temporary-low power state" ) );
+ }
+ if (can_suspend) {
+ nopowerSuspend = new QRadioButton(i18n("&Suspend"), nopowerBox);
+ QToolTip::add( nopowerSuspend, i18n( "Causes the laptop to change to a suspend 'save-to-ram' state" ) );
+ }
+ if (can_hibernate) {
+ nopowerHibernate = new QRadioButton(i18n("H&ibernate"), nopowerBox);
+ QToolTip::add( nopowerHibernate, i18n( "Causes the laptop to change to a hibernate 'save-to-disk' state" ) );
+ }
+ if (can_suspend||can_standby||can_hibernate)
+ nopowerOff = new QRadioButton(i18n("None"), nopowerBox);
+ if (can_brightness) {
+ nopowerBrightness = new QCheckBox(i18n("Brightness"), nopowerBox);
+ QToolTip::add( nopowerBrightness, i18n( "Enables changing the laptop's back panel brightness" ) );
+ QWidget *wp = new QWidget(nopowerBox);
+ QHBoxLayout *xl = new QHBoxLayout( wp);
+ xl->addWidget(new QLabel("-", wp));
+ nopowerValBrightness = new QSlider(0, 255, 16, 255, Qt::Horizontal, wp);
+ QToolTip::add( nopowerValBrightness, i18n( "How bright to change the back panel" ) );
+ nopowerValBrightness->setEnabled(0);
+ connect(nopowerValBrightness, SIGNAL(valueChanged(int)), this, SLOT(changed()));
+ connect(nopowerBrightness, SIGNAL(toggled(bool)), nopowerValBrightness, SLOT(setEnabled(bool)));
+ xl->addWidget(nopowerValBrightness);
+ xl->addWidget(new QLabel("+", wp));
+ xl->addStretch(1);
+ }
+ if (has_performance) {
+ nopowerPerformance = new QCheckBox(i18n("System performance"), nopowerBox);
+ QToolTip::add( nopowerPerformance, i18n( "Enables changing the laptop's performance profile" ) );
+
+ QWidget *wp = new QWidget(nopowerBox);
+ QHBoxLayout *xl = new QHBoxLayout( wp);
+ nopowerValPerformance = new KComboBox(0, wp);
+ QToolTip::add( nopowerValPerformance, i18n( "Which profile to change it to" ) );
+ nopowerValPerformance->insertStringList(performance_list);
+ nopowerValPerformance->setEnabled(0);
+ connect(nopowerValPerformance, SIGNAL(activated(int)), this, SLOT(changed()));
+ connect(nopowerPerformance, SIGNAL(toggled(bool)), nopowerValPerformance, SLOT(setEnabled(bool)));
+ xl->addWidget(nopowerValPerformance);
+ xl->addStretch(1);
+ }
+ if (has_throttle) {
+ nopowerThrottle = new QCheckBox(i18n("CPU throttle"), nopowerBox);
+ QToolTip::add( nopowerThrottle, i18n( "Enables throttling the laptop's CPU" ) );
+
+ QWidget *wp = new QWidget(nopowerBox);
+ QHBoxLayout *xl = new QHBoxLayout( wp);
+ nopowerValThrottle = new KComboBox(0, wp);
+ QToolTip::add( nopowerValThrottle, i18n( "How much to throttle the laptop's CPU" ) );
+ nopowerValThrottle->insertStringList(throttle_list);
+ nopowerValThrottle->setEnabled(0);
+ connect(nopowerValThrottle, SIGNAL(activated(int)), this, SLOT(changed()));
+ connect(nopowerThrottle, SIGNAL(toggled(bool)), nopowerValThrottle, SLOT(setEnabled(bool)));
+ xl->addWidget(nopowerValThrottle);
+ xl->addStretch(1);
+ }
+
+
+ connect(nopowerBox, SIGNAL(clicked(int)), this, SLOT(changed()));
+
+ bool can_lav = laptop_portable::has_lav();
+ QHBox *hbox;
+ if (can_lav) {
+ hbox = new QHBox( nopowerBox );
+ noenablelav = new QCheckBox(i18n("Don't act if LAV is >"), hbox);
+ connect(noenablelav, SIGNAL(clicked()), this, SLOT(changed()));
+ noeditlav = new KDoubleSpinBox(0.0, 10.0, 0.0, 0.1, 1, hbox);
+ QToolTip::add( noeditlav, i18n( "If enabled and the system load average is greater than this value none of the above options will be applied" ) );
+ connect(noeditlav, SIGNAL(valueChanged(double)), this, SLOT(changed()));
+ connect(noenablelav, SIGNAL(toggled(bool)), noeditlav, SLOT(setEnabled(bool)));
+ }
+
+ hbox = new QHBox( nopowerBox );
+ QLabel* noedlabel = new QLabel(i18n("&Wait for:"), hbox);
+ noeditwait = new QSpinBox( 1, 60*24 /*1 day*/, 1, hbox );
+ QToolTip::add( noeditwait, i18n( "How long the computer has to be idle before these values take effect" ) );
+ noeditwait->setSuffix( i18n("keep short, unit in spinbox", "min") );
+ noedlabel->setBuddy( noeditwait );
+ hbox->setStretchFactor( noeditwait, 1 );
+ connect( noeditwait, SIGNAL(valueChanged(int)), this, SLOT(changed()));
+
+
+ ///////////////////////////////////////////////////////////////
+
+
+ powerBox = new QVButtonGroup(i18n("Powered"), this);
+ powerBox->layout()->setSpacing( KDialog::spacingHint() );
+ QToolTip::add( powerBox, i18n( "Options in this box apply when the laptop is plugged into the wall and has been idle for a while" ) );
+ hlay->addWidget( powerBox );
+
+ if (can_standby) {
+ powerStandby = new QRadioButton(i18n("Sta&ndby"), powerBox);
+ QToolTip::add( powerStandby, i18n( "Causes the laptop to change to a standby temporary-low power state" ) );
+ }
+ if (can_suspend) {
+ powerSuspend = new QRadioButton(i18n("S&uspend"), powerBox);
+ QToolTip::add( powerSuspend, i18n( "Causes the laptop to change to a suspend 'save-to-ram' state" ) );
+ }
+ if (can_hibernate) {
+ powerHibernate = new QRadioButton(i18n("Hi&bernate"), powerBox);
+ QToolTip::add( powerHibernate, i18n( "Causes the laptop to change to a hibernate 'save-to-disk' state" ) );
+ }
+ if (can_suspend||can_standby||can_hibernate)
+ powerOff = new QRadioButton(i18n("None"), powerBox);
+ if (can_brightness) {
+ powerBrightness = new QCheckBox(i18n("Brightness"), powerBox);
+ QToolTip::add( powerBrightness, i18n( "Enables changing the laptop's back panel brightness" ) );
+ QWidget *wp = new QWidget(powerBox);
+ QHBoxLayout *xl = new QHBoxLayout( wp);
+ xl->addWidget(new QLabel("-", wp));
+ powerValBrightness = new QSlider(0, 255, 16, 255, Qt::Horizontal, wp);
+ QToolTip::add( powerValBrightness, i18n( "How bright to change the back panel" ) );
+ powerValBrightness->setEnabled(0);
+ connect(powerValBrightness, SIGNAL(valueChanged(int)), this, SLOT(changed()));
+ connect(powerBrightness, SIGNAL(toggled(bool)), powerValBrightness, SLOT(setEnabled(bool)));
+ xl->addWidget(powerValBrightness);
+ xl->addWidget(new QLabel("+", wp));
+ xl->addStretch(1);
+ }
+ if (has_performance) {
+ powerPerformance = new QCheckBox(i18n("System performance"), powerBox);
+ QToolTip::add( powerPerformance, i18n( "Enables changing the laptop's performance profile" ) );
+
+ QWidget *wp = new QWidget(powerBox);
+ QHBoxLayout *xl = new QHBoxLayout( wp);
+ powerValPerformance = new KComboBox(0, wp);
+ QToolTip::add( powerValPerformance, i18n( "Which profile to change it to" ) );
+ powerValPerformance->insertStringList(performance_list);
+ powerValPerformance->setEnabled(0);
+ connect(powerValPerformance, SIGNAL(activated(int)), this, SLOT(changed()));
+ connect(powerPerformance, SIGNAL(toggled(bool)), powerValPerformance, SLOT(setEnabled(bool)));
+ xl->addWidget(powerValPerformance);
+ xl->addStretch(1);
+ }
+ if (has_throttle) {
+ powerThrottle = new QCheckBox(i18n("CPU throttle"), powerBox);
+ QToolTip::add( powerThrottle, i18n( "Enables throttling the laptop's CPU" ) );
+
+ QWidget *wp = new QWidget(powerBox);
+ QHBoxLayout *xl = new QHBoxLayout( wp);
+ powerValThrottle = new KComboBox(0, wp);
+ QToolTip::add( powerValThrottle, i18n( "How much to throttle the laptop's CPU" ) );
+ powerValThrottle->insertStringList(throttle_list);
+ powerValThrottle->setEnabled(0);
+ connect(powerValThrottle, SIGNAL(activated(int)), this, SLOT(changed()));
+ connect(powerThrottle, SIGNAL(toggled(bool)), powerValThrottle, SLOT(setEnabled(bool)));
+ xl->addWidget(powerValThrottle);
+ xl->addStretch(1);
+ }
+
+ connect(powerBox, SIGNAL(clicked(int)), this, SLOT(changed()));
+
+ if (can_lav) {
+ hbox = new QHBox( powerBox );
+ enablelav = new QCheckBox(i18n("Don't act if LAV is >"), hbox);
+ connect( enablelav, SIGNAL(clicked()), this, SLOT(changed()));
+ editlav = new KDoubleSpinBox(0.0, 10.0, 0.0, 0.1, 1, hbox);
+ QToolTip::add( editlav, i18n( "If enabled and the system load average is greater than this value none of the above options will be applied" ) );
+ connect( editlav, SIGNAL(valueChanged(double)), this, SLOT(changed()));
+ connect( enablelav, SIGNAL(toggled(bool)), editlav, SLOT(setEnabled(bool)) );
+ }
+
+ hbox = new QHBox( powerBox );
+ QLabel* edlabel = new QLabel(i18n("Wai&t for:"), hbox);
+ editwait = new QSpinBox( 1, 60*24 /*1 day*/, 1, hbox );
+ QToolTip::add( editwait, i18n( "How long the computer has to be idle before these values take effect" ) );
+ editwait->setSuffix( i18n("keep short, unit in spinbox", "min") );
+ edlabel->setBuddy( editwait );
+ hbox->setStretchFactor( editwait, 1 );
+ connect( editwait, SIGNAL(valueChanged(int)), this, SLOT(changed()));
+
+ hlay->addStretch(1);
+
+ QLabel* explain = new QLabel(i18n("This panel configures the behavior of the automatic power-down feature - "
+ "it works as a sort of extreme screen saver. You can configure different "
+ "timeouts and types of behavior depending on whether or not your laptop is "
+ "plugged in to the mains supply."), this );
+ explain->setAlignment( Qt::WordBreak );
+ top_layout->addWidget(explain);
+
+ if (can_standby) {
+ QLabel* explain3 = new QLabel(i18n("Different laptops may respond to 'standby' in different ways - in many "
+ "it is only a temporary state and may not be useful for you."), this);
+ explain3->setAlignment( Qt::WordBreak );
+ top_layout->addWidget(explain3, 0, Qt::AlignLeft);
+ }
+
+ top_layout->addStretch(1);
+
+ top_layout->addWidget( new QLabel( i18n("Version: %1").arg(LAPTOP_VERSION), this ), 0, Qt::AlignRight );
+ }
+ }
+
+ load();
+}
+
+PowerConfig::~PowerConfig()
+{
+ delete config;
+}
+
+void PowerConfig::save()
+{
+ if (editwait) {
+ power = getPower();
+ nopower = getNoPower();
+ edit_wait = editwait->value();
+ noedit_wait = noeditwait->value();
+ nopower_bright_enabled = (nopowerBrightness?nopowerBrightness->isChecked():0);
+ power_bright_enabled = (powerBrightness?powerBrightness->isChecked():0);
+ nopower_bright_val = (nopowerValBrightness?nopowerValBrightness->value():0);
+ power_bright_val = (powerValBrightness?powerValBrightness->value():255);
+ nopower_performance_enabled = (nopowerPerformance?nopowerPerformance->isChecked():0);
+ power_performance_enabled = (powerPerformance?powerPerformance->isChecked():0);
+ nopower_performance_val = (nopowerValPerformance?nopowerValPerformance->currentText():"");
+ power_performance_val = (powerValPerformance?powerValPerformance->currentText():"");
+ nopower_throttle_enabled = (nopowerThrottle?nopowerThrottle->isChecked():0);
+ power_throttle_enabled = (powerThrottle?powerThrottle->isChecked():0);
+ nopower_throttle_val = (nopowerValThrottle?nopowerValThrottle->currentText():"");
+ power_throttle_val = (powerValThrottle?powerValThrottle->currentText():"");
+ edit_lav = (editlav?editlav->value():-1);
+ noedit_lav = (noeditlav?noeditlav->value():-1);
+ lav_enabled = (enablelav?enablelav->isChecked():0);
+ nolav_enabled = (noenablelav?noenablelav->isChecked():0);
+ }
+
+ config->setGroup("LaptopPower");
+ config->writeEntry("NoPowerSuspend", nopower);
+ config->writeEntry("PowerSuspend", power);
+ config->writeEntry("PowerWait", edit_wait);
+ config->writeEntry("NoPowerWait", noedit_wait);
+ config->writeEntry("PowerLav", edit_lav);
+ config->writeEntry("NoPowerLav", noedit_lav);
+ config->writeEntry("LavEnabled", lav_enabled);
+ config->writeEntry("NoLavEnabled", nolav_enabled);
+ config->writeEntry("PowerBrightnessEnabled", power_bright_enabled);
+ config->writeEntry("NoPowerBrightnessEnabled", nopower_bright_enabled);
+ config->writeEntry("PowerBrightness", power_bright_val);
+ config->writeEntry("NoPowerBrightness", nopower_bright_val);
+ config->writeEntry("PowerPerformanceEnabled", power_performance_enabled);
+ config->writeEntry("NoPowerPerformanceEnabled", nopower_performance_enabled);
+ config->writeEntry("PowerPerformance", power_performance_val);
+ config->writeEntry("NoPowerPerformance", nopower_performance_val);
+ config->writeEntry("PowerThrottleEnabled", power_throttle_enabled);
+ config->writeEntry("NoPowerThrottleEnabled", nopower_throttle_enabled);
+ config->writeEntry("PowerThrottle", power_throttle_val);
+ config->writeEntry("NoPowerThrottle", nopower_throttle_val);
+ config->sync();
+ changed(false);
+ wake_laptop_daemon();
+}
+
+void PowerConfig::load()
+{
+ load( false );
+}
+
+void PowerConfig::load(bool useDefaults)
+{
+ config->setReadDefaults( useDefaults );
+
+ config->setGroup("LaptopPower");
+ nopower = config->readNumEntry("NoPowerSuspend", (nopowerStandby?1:nopowerSuspend?2:0));
+ power = config->readNumEntry("PowerSuspend", 0);
+ edit_wait = config->readNumEntry("PowerWait", 20);
+ noedit_wait = config->readNumEntry("NoPowerWait", 5);
+ edit_lav = config->readDoubleNumEntry("PowerLav", -1);
+ noedit_lav = config->readDoubleNumEntry("NoPowerLav", -1);
+ lav_enabled = config->readBoolEntry("LavEnabled", 0);
+ nolav_enabled = config->readBoolEntry("NoLavEnabled", 0);
+ nopower_bright_enabled = config->readBoolEntry("NoPowerBrightnessEnabled", 0);
+ power_bright_enabled = config->readBoolEntry("PowerBrightnessEnabled", 0);
+ nopower_bright_val = config->readNumEntry("NoPowerBrightness", 0);
+ power_bright_val = config->readNumEntry("PowerBrightness", 255);
+ nopower_performance_enabled = config->readBoolEntry("NoPowerPerformanceEnabled", 0);
+ power_performance_enabled = config->readBoolEntry("PowerPerformanceEnabled", 0);
+ nopower_performance_val = config->readEntry("NoPowerPerformance", "");
+ power_performance_val = config->readEntry("PowerPerformance", "");
+ nopower_throttle_enabled = config->readBoolEntry("NoPowerThrottleEnabled", 0);
+ power_throttle_enabled = config->readBoolEntry("PowerThrottleEnabled", 0);
+ nopower_throttle_val = config->readEntry("NoPowerThrottle", "");
+ power_throttle_val = config->readEntry("PowerThrottle", "");
+
+ // the GUI should reflect the real values
+ if (editwait) {
+ editwait->setValue(edit_wait);
+ noeditwait->setValue(noedit_wait);
+ if (editlav) {
+ editlav->setValue(edit_lav);
+ editlav->setEnabled(lav_enabled);
+ }
+ if (noeditlav) {
+ noeditlav->setValue(noedit_lav);
+ noeditlav->setEnabled(nolav_enabled);
+ }
+ if (enablelav)
+ enablelav->setChecked(lav_enabled);
+ if (noenablelav)
+ noenablelav->setChecked(nolav_enabled);
+ setPower(power, nopower);
+ if (nopowerBrightness)
+ nopowerBrightness->setChecked(nopower_bright_enabled);
+ if (powerBrightness)
+ powerBrightness->setChecked(power_bright_enabled);
+ if (nopowerValBrightness) {
+ nopowerValBrightness->setValue(nopower_bright_val);
+ nopowerValBrightness->setEnabled(nopower_bright_enabled);
+ }
+ if (powerValBrightness) {
+ powerValBrightness->setValue(power_bright_val);
+ powerValBrightness->setEnabled(power_bright_enabled);
+ }
+ if (nopowerPerformance)
+ nopowerPerformance->setChecked(nopower_performance_enabled);
+ if (powerPerformance)
+ powerPerformance->setChecked(power_performance_enabled);
+ if (nopowerValPerformance) {
+ int ind = 0;
+ for (int i = 0; i < nopowerValPerformance->count(); i++)
+ if (nopowerValPerformance->text(i) == nopower_performance_val) {
+ ind = i;
+ break;
+ }
+ nopowerValPerformance->setCurrentItem(ind);
+ nopowerValPerformance->setEnabled(nopower_performance_enabled);
+ }
+ if (powerValPerformance) {
+ int ind = 0;
+ for (int i = 0; i < powerValPerformance->count(); i++)
+ if (powerValPerformance->text(i) == power_performance_val) {
+ ind = i;
+ break;
+ }
+ powerValPerformance->setCurrentItem(ind);
+ powerValPerformance->setEnabled(power_performance_enabled);
+ }
+ if (nopowerThrottle)
+ nopowerThrottle->setChecked(nopower_throttle_enabled);
+ if (powerThrottle)
+ powerThrottle->setChecked(power_throttle_enabled);
+ if (nopowerValThrottle) {
+ int ind = 0;
+ for (int i = 0; i < nopowerValThrottle->count(); i++)
+ if (nopowerValThrottle->text(i) == nopower_throttle_val) {
+ ind = i;
+ break;
+ }
+ nopowerValThrottle->setCurrentItem(ind);
+ nopowerValThrottle->setEnabled(nopower_throttle_enabled);
+ }
+ if (powerValThrottle) {
+ int ind = 0;
+ for (int i = 0; i < powerValThrottle->count(); i++)
+ if (powerValThrottle->text(i) == power_throttle_val) {
+ ind = i;
+ break;
+ }
+ powerValThrottle->setCurrentItem(ind);
+ powerValThrottle->setEnabled(power_throttle_enabled);
+ }
+ }
+ emit changed( useDefaults );
+}
+
+void PowerConfig::defaults()
+{
+ load( true );
+}
+
+int PowerConfig::getNoPower()
+{
+ if (!apm)
+ return(nopower);
+ if (nopowerHibernate && nopowerHibernate->isChecked())
+ return 3;
+ if (nopowerStandby && nopowerStandby->isChecked())
+ return 1;
+ if (nopowerSuspend && nopowerSuspend->isChecked())
+ return 2;
+ return(0);
+}
+
+int PowerConfig::getPower()
+{
+ if (!apm || !powerOff)
+ return(power);
+ if (powerHibernate && powerHibernate->isChecked())
+ return 3;
+ if (powerStandby && powerStandby->isChecked())
+ return 1;
+ if (powerSuspend && powerSuspend->isChecked())
+ return 2;
+ return(0);
+}
+
+void PowerConfig::setPower(int p, int np)
+{
+ if (!apm || nopowerOff == 0)
+ return;
+ if (nopowerSuspend) {
+ nopowerSuspend->setChecked(FALSE);
+ } else {
+ if (np == 2) np = 0;
+ }
+ if (nopowerStandby) {
+ nopowerStandby->setChecked(FALSE);
+ } else {
+ if (np == 1) np = 0;
+ }
+ if (nopowerHibernate) {
+ nopowerHibernate->setChecked(FALSE);
+ } else {
+ if (np == 3) np = 0;
+ }
+ if (nopowerOff)
+ nopowerOff->setChecked(FALSE);
+ switch (np) {
+ case 0: nopowerOff->setChecked(TRUE);break;
+ case 1: nopowerStandby->setChecked(TRUE);break;
+ case 2: nopowerSuspend->setChecked(TRUE);break;
+ case 3: nopowerHibernate->setChecked(TRUE);break;
+ }
+ if (powerSuspend) {
+ powerSuspend->setChecked(FALSE);
+ } else {
+ if (p == 2) p = 0;
+ }
+ if (powerStandby) {
+ powerStandby->setChecked(FALSE);
+ } else {
+ if (p == 1) p = 0;
+ }
+ if (powerHibernate) {
+ powerHibernate->setChecked(FALSE);
+ } else {
+ if (p == 3) p = 0;
+ }
+ if (powerOff)
+ powerOff->setChecked(FALSE);
+ switch (p) {
+ case 0: powerOff->setChecked(TRUE);break;
+ case 1: powerStandby->setChecked(TRUE);break;
+ case 2: powerSuspend->setChecked(TRUE);break;
+ case 3: powerHibernate->setChecked(TRUE);break;
+ }
+}
+
+
+QString PowerConfig::quickHelp() const
+{
+ return i18n("<h1>Laptop Power Control</h1>This module allows you to "
+ "control the power settings of your laptop and set timouts that will trigger "
+ "state changes you can use to save power");
+
+}
+
+#include "power.moc"
diff --git a/klaptopdaemon/power.h b/klaptopdaemon/power.h
new file mode 100644
index 0000000..0d9d624
--- /dev/null
+++ b/klaptopdaemon/power.h
@@ -0,0 +1,98 @@
+/*
+ * power.h
+ *
+ * Copyright (c) 1999 Paul Campbell <paul@taniwha.com>
+ *
+ * Requires the Qt widget libraries, available at no cost at
+ * http://www.troll.no/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef __POWERCONFIG_H__
+#define __POWERCONFIG_H__
+
+#include <kcmodule.h>
+#include <qstring.h>
+
+class QWidget;
+class QSlider;
+class QButtonGroup;
+class QRadioButton;
+class QSpinBox;
+class KConfig;
+class QCheckBox;
+class KComboBox;
+class KDoubleSpinBox;
+
+class PowerConfig : public KCModule
+{
+ Q_OBJECT
+public:
+ PowerConfig( QWidget *parent=0, const char* name=0);
+ ~PowerConfig();
+ void save( void );
+ void load();
+ void load(bool useDefaults);
+ void defaults();
+
+ virtual QString quickHelp() const;
+
+
+private:
+
+ int getPower();
+ int getNoPower();
+ void setPower( int, int );
+
+ QButtonGroup *nopowerBox;
+ QRadioButton *nopowerStandby, *nopowerSuspend, *nopowerOff, *nopowerHibernate;
+ QCheckBox *nopowerBrightness;
+ QSlider *nopowerValBrightness;
+ QCheckBox *nopowerThrottle;
+ KComboBox *nopowerValThrottle;
+ QCheckBox *nopowerPerformance;
+ KComboBox *nopowerValPerformance;
+ QButtonGroup *powerBox;
+ QRadioButton *powerStandby, *powerSuspend, *powerOff, *powerHibernate;
+ QCheckBox *powerBrightness;
+ QSlider *powerValBrightness;
+ QCheckBox *powerThrottle;
+ KComboBox *powerValThrottle;
+ QCheckBox *powerPerformance;
+ KComboBox *powerValPerformance;
+ QSpinBox *noeditwait;
+ QSpinBox *editwait;
+ QCheckBox *enablelav;
+ QCheckBox *noenablelav;
+ KDoubleSpinBox *noeditlav;
+ KDoubleSpinBox *editlav;
+ int edit_wait, noedit_wait;
+ int power_bright_val, nopower_bright_val;
+ bool nopower_bright_enabled, power_bright_enabled;
+ bool nopower_throttle_enabled, power_throttle_enabled;
+ QString nopower_throttle_val, power_throttle_val;
+ bool nopower_performance_enabled, power_performance_enabled;
+ bool lav_enabled, nolav_enabled;
+ float edit_lav, noedit_lav;
+ QString nopower_performance_val, power_performance_val;
+
+ KConfig *config;
+ int power, nopower, apm;
+};
+
+#endif
+
diff --git a/klaptopdaemon/profile.cpp b/klaptopdaemon/profile.cpp
new file mode 100644
index 0000000..a6285cb
--- /dev/null
+++ b/klaptopdaemon/profile.cpp
@@ -0,0 +1,424 @@
+/*
+ * brightness.cpp
+ *
+ * Copyright (c) 2003 Paul Campbell <paul@taniwha.com>
+ *
+ * Requires the Qt widget libraries, available at no cost at
+ * http://www.troll.no/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+// my headers:
+#include "profile.h"
+#include "version.h"
+#include "portable.h"
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+// other KDE headers:
+#include <klocale.h>
+#include <kconfig.h>
+#include <knuminput.h>
+#include <kiconloader.h>
+#include <kicondialog.h>
+#include <kapplication.h>
+#include <kmessagebox.h>
+#include <kcombobox.h>
+
+// other Qt headers:
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qcheckbox.h>
+#include <qhbox.h>
+#include <qvgroupbox.h>
+#include <qgrid.h>
+#include <qpushbutton.h>
+#include <qslider.h>
+#include <qtooltip.h>
+
+extern void wake_laptop_daemon();
+
+ProfileConfig::ProfileConfig(QWidget * parent, const char *name)
+ : KCModule(parent, name)
+{
+ QStringList performance_list;
+ int current_performance;
+ bool *active_list;
+ bool has_performance = laptop_portable::get_system_performance(0, current_performance, performance_list, active_list);
+ QStringList throttle_list;
+ int current_throttle;
+ bool has_throttle = laptop_portable::get_system_throttling(0, current_throttle, throttle_list, active_list);
+
+ KGlobal::locale()->insertCatalogue("klaptopdaemon"); // For translation of klaptopdaemon messages
+
+ config = new KConfig("kcmlaptoprc");
+
+ QVBoxLayout *top_layout = new QVBoxLayout( this, KDialog::marginHint(),
+ KDialog::spacingHint() );
+
+ QHBoxLayout *ll = new QHBoxLayout();
+
+ QVGroupBox *gb = new QVGroupBox(i18n("Not Powered"), this);
+ QToolTip::add( gb, i18n( "Items in this box take effect whenever the laptop is unplugged from the wall" ) );
+ if (laptop_portable::has_brightness()) {
+ QWidget *wp = new QWidget(gb);
+ QHBoxLayout *xl = new QHBoxLayout( wp);
+ poff = new QCheckBox(i18n("Back panel brightness"), wp);
+ QToolTip::add( poff, i18n( "Enables the changing of the back panel brightness" ) );
+ xl->addWidget(poff);
+ connect (poff, SIGNAL(toggled(bool)), this, SLOT(poff_changed(bool)));
+
+ xl->addWidget(new QLabel("-", wp));
+ soff = new QSlider(0, 255, 16, 160, Qt::Horizontal, wp);
+ soff->setEnabled(0);
+ QToolTip::add( soff, i18n( "How bright it should be when it is changed" ) );
+ connect (soff, SIGNAL(valueChanged(int)), this, SLOT(configChanged()));
+ xl->addWidget(soff);
+ xl->addWidget(new QLabel("+", wp));
+ xl->addStretch(1);
+ } else {
+ poff = 0;
+ soff = 0;
+ }
+
+ if (has_performance) {
+ QWidget *wp = new QWidget(gb);
+ QHBoxLayout *xl = new QHBoxLayout( wp);
+ performance_off = new QCheckBox(i18n("System performance"), wp);
+ QToolTip::add( performance_off, i18n( "Enables the changing of the system performance profile" ) );
+ xl->addWidget(performance_off);
+ connect (performance_off, SIGNAL(toggled(bool)), this, SLOT(performance_off_changed(bool)));
+
+ performance_val_off = new KComboBox(0, wp);
+ QToolTip::add( performance_val_off, i18n( "The new system performance profile to change to" ) );
+ performance_val_off->insertStringList(performance_list);
+ performance_val_off->setEnabled(0);
+ connect (performance_val_off, SIGNAL(activated(int)), this, SLOT(configChanged()));
+ xl->addWidget(performance_val_off);
+ xl->addStretch(1);
+ } else {
+ performance_off = 0;
+ performance_val_off = 0;
+ }
+ if (has_throttle) {
+ QWidget *wp = new QWidget(gb);
+ QHBoxLayout *xl = new QHBoxLayout( wp);
+ throttle_off = new QCheckBox(i18n("CPU throttling"), wp);
+ QToolTip::add( throttle_off, i18n( "Enables the throttling of the CPU performance" ) );
+ xl->addWidget(throttle_off);
+ connect (throttle_off, SIGNAL(toggled(bool)), this, SLOT(throttle_off_changed(bool)));
+
+ throttle_val_off = new KComboBox(0, wp);
+ throttle_val_off->insertStringList(throttle_list);
+ throttle_val_off->setEnabled(0);
+ QToolTip::add( throttle_val_off, i18n( "How much to throttle the CPU by" ) );
+ connect (throttle_val_off, SIGNAL(activated(int)), this, SLOT(configChanged()));
+ xl->addWidget(throttle_val_off);
+ xl->addStretch(1);
+ } else {
+ throttle_off = 0;
+ throttle_val_off = 0;
+ }
+
+ ll->addWidget(gb);
+
+ gb = new QVGroupBox(i18n("Powered"), this);
+ QToolTip::add( gb, i18n( "Items in this box take effect whenever the laptop is plugged into the wall" ) );
+ if (laptop_portable::has_brightness()) {
+ QWidget *wp = new QWidget(gb);
+ QHBoxLayout *xl = new QHBoxLayout( wp);
+ pon = new QCheckBox(i18n("Back panel brightness"), wp);
+ QToolTip::add( pon, i18n( "Enables the changing of the back panel brightness" ) );
+ xl->addWidget(pon);
+ connect (pon, SIGNAL(toggled(bool)), this, SLOT(pon_changed(bool)));
+
+ xl->addWidget(new QLabel("-", wp));
+ son = new QSlider(0, 255, 16, 255, Qt::Horizontal, wp);
+ son->setEnabled(0);
+ QToolTip::add( son, i18n( "How bright it should be when it is changed" ) );
+ connect (son, SIGNAL(valueChanged(int)), this, SLOT(configChanged()));
+ xl->addWidget(son);
+ xl->addWidget(new QLabel("+", wp));
+ xl->addStretch(1);
+ } else {
+ pon = 0;
+ son = 0;
+ }
+ if (has_performance) {
+ QWidget *wp = new QWidget(gb);
+ QHBoxLayout *xl = new QHBoxLayout( wp);
+ performance_on = new QCheckBox(i18n("System performance"), wp);
+ QToolTip::add( performance_on, i18n( "Enables the changing of the system performance profile" ) );
+ xl->addWidget(performance_on);
+ connect (performance_on, SIGNAL(toggled(bool)), this, SLOT(performance_on_changed(bool)));
+
+ performance_val_on = new KComboBox(0, wp);
+ performance_val_on->insertStringList(performance_list);
+ performance_val_on->setEnabled(0);
+ QToolTip::add( performance_val_on, i18n( "The new system performance profile to change to" ) );
+ connect (performance_val_on, SIGNAL(activated(int)), this, SLOT(configChanged()));
+ xl->addWidget(performance_val_on);
+ xl->addStretch(1);
+ } else {
+ performance_on = 0;
+ performance_val_on = 0;
+ }
+ if (has_throttle) {
+ QWidget *wp = new QWidget(gb);
+ QHBoxLayout *xl = new QHBoxLayout( wp);
+ throttle_on = new QCheckBox(i18n("CPU throttle"), wp);
+ QToolTip::add( throttle_on, i18n( "Enables the throttling of the CPU performance" ) );
+ xl->addWidget(throttle_on);
+ connect (throttle_on, SIGNAL(toggled(bool)), this, SLOT(throttle_on_changed(bool)));
+
+ throttle_val_on = new KComboBox(0, wp);
+ throttle_val_on->insertStringList(throttle_list);
+ throttle_val_on->setEnabled(0);
+ QToolTip::add( throttle_val_on, i18n( "How much to throttle the CPU by" ) );
+ connect (throttle_val_on, SIGNAL(activated(int)), this, SLOT(configChanged()));
+ xl->addWidget(throttle_val_on);
+ xl->addStretch(1);
+ } else {
+ throttle_on = 0;
+ throttle_val_on = 0;
+ }
+ ll->addWidget(gb);
+
+ ll->addStretch(1);
+
+ top_layout->addLayout(ll);
+ QLabel *tmp_label = new QLabel(i18n("This panel allows you to set default values for system attributes "
+ "so that they change when the laptop is plugged in to the wall or "
+ "running on batteries."), this );
+ tmp_label->setAlignment( Qt::WordBreak );
+ top_layout->addWidget( tmp_label );
+
+ tmp_label = new QLabel(i18n("You can also set options for these values that will be set by low battery "
+ "conditions, or system inactivity in the other panels"), this );
+ tmp_label->setAlignment( Qt::WordBreak );
+ top_layout->addWidget( tmp_label );
+ top_layout->addStretch(1);
+ top_layout->addWidget( new QLabel( i18n("Version: %1").arg(LAPTOP_VERSION), this), 0, Qt::AlignRight );
+
+
+ load();
+}
+
+ProfileConfig::~ProfileConfig()
+{
+ delete config;
+}
+
+void ProfileConfig::pon_changed(bool v)
+{
+ if (son)
+ son->setEnabled(v);
+ configChanged();
+}
+
+void ProfileConfig::poff_changed(bool v)
+{
+ if (soff)
+ soff->setEnabled(v);
+ configChanged();
+}
+
+void ProfileConfig::performance_on_changed(bool v)
+{
+ if (performance_val_on)
+ performance_val_on->setEnabled(v);
+ configChanged();
+}
+
+void ProfileConfig::performance_off_changed(bool v)
+{
+ if (performance_val_off)
+ performance_val_off->setEnabled(v);
+ configChanged();
+}
+
+void ProfileConfig::throttle_on_changed(bool v)
+{
+ if (throttle_val_on)
+ throttle_val_on->setEnabled(v);
+ configChanged();
+}
+
+void ProfileConfig::throttle_off_changed(bool v)
+{
+ if (throttle_val_off)
+ throttle_val_off->setEnabled(v);
+ configChanged();
+}
+
+
+void ProfileConfig::save()
+{
+ config->setGroup("ProfileDefault");
+
+ config->writeEntry("EnableBrightnessOn", (pon?pon->isChecked():0));
+ config->writeEntry("BrightnessOnLevel", (son?son->value():255));
+ config->writeEntry("EnableBrightnessOff", (poff?poff->isChecked():0));
+ config->writeEntry("BrightnessOffLevel", (soff?soff->value():160));
+ config->writeEntry("EnablePerformanceOn", (performance_on?performance_on->isChecked():0));
+ config->writeEntry("PerformanceOnLevel", (performance_val_on?performance_val_on->currentText():""));
+ config->writeEntry("EnablePerformanceOff", (performance_off?performance_off->isChecked():0));
+ config->writeEntry("PerformanceOffLevel", (performance_val_off?performance_val_off->currentText():""));
+ config->writeEntry("EnableThrottleOn", (throttle_on?throttle_on->isChecked():0));
+ config->writeEntry("ThrottleOnLevel", (throttle_val_on?throttle_val_on->currentText():""));
+ config->writeEntry("EnableThrottleOff", (throttle_off?throttle_off->isChecked():0));
+ config->writeEntry("ThrottleOffLevel", (throttle_val_off?throttle_val_off->currentText():""));
+ config->sync();
+ changed(false);
+ wake_laptop_daemon();
+}
+
+void ProfileConfig::load()
+{
+ load( false );
+}
+
+void ProfileConfig::load(bool useDefaults)
+{
+ config->setReadDefaults( useDefaults );
+
+ config->setGroup("ProfileDefault");
+
+ bool v;
+ if (pon) {
+ v = config->readBoolEntry("EnableBrightnessOn", false);
+ pon->setChecked(v);
+ } else {
+ v = 0;
+ }
+ int x;
+ if (son) {
+ x = config->readNumEntry("BrightnessOnLevel", 255);
+ son->setValue(x);
+ son->setEnabled(v);
+ }
+ if (poff) {
+ v = config->readBoolEntry("EnableBrightnessOff", false);
+ poff->setChecked(v);
+ } else {
+ v = 0;
+ }
+ if (soff) {
+ x = config->readNumEntry("BrightnessOffLevel", 160);
+ soff->setValue(x);
+ soff->setEnabled(v);
+ }
+ if (performance_on) {
+ v = config->readBoolEntry("EnablePerformanceOn", false);
+ performance_on->setChecked(v);
+ } else {
+ v = 0;
+ }
+ if (performance_val_on) {
+ QString s = config->readEntry("PerformanceOnLevel", "");
+ int ind = 0;
+ for (int i = 0; i < performance_val_on->count(); i++)
+ if (performance_val_on->text(i) == s) {
+ ind = i;
+ break;
+ }
+ performance_val_on->setCurrentItem(ind);
+ performance_val_on->setEnabled(v);
+ }
+ if (performance_off) {
+ v = config->readBoolEntry("EnablePerformanceOff", false);
+ performance_off->setChecked(v);
+ } else {
+ v = 0;
+ }
+ if (performance_val_off) {
+ QString s = config->readEntry("PerformanceOffLevel", "");
+ int ind = 0;
+ for (int i = 0; i < performance_val_off->count(); i++)
+ if (performance_val_off->text(i) == s) {
+ ind = i;
+ break;
+ }
+ performance_val_off->setCurrentItem(ind);
+ performance_val_off->setEnabled(v);
+ }
+ if (throttle_on) {
+ v = config->readBoolEntry("EnableThrottleOn", false);
+ throttle_on->setChecked(v);
+ } else {
+ v = 0;
+ }
+ if (throttle_val_on) {
+ QString s = config->readEntry("ThrottleOnLevel", "");
+ int ind = 0;
+ for (int i = 0; i < throttle_val_on->count(); i++)
+ if (throttle_val_on->text(i) == s) {
+ ind = i;
+ break;
+ }
+ throttle_val_on->setCurrentItem(ind);
+ throttle_val_on->setEnabled(v);
+ }
+ if (throttle_off) {
+ v = config->readBoolEntry("EnableThrottleOff", false);
+ throttle_off->setChecked(v);
+ } else {
+ v = 0;
+ }
+ if (throttle_val_off) {
+ QString s = config->readEntry("ThrottleOffLevel", "");
+ int ind = 0;
+ for (int i = 0; i < throttle_val_off->count(); i++)
+ if (throttle_val_off->text(i) == s) {
+ ind = i;
+ break;
+ }
+ throttle_val_off->setCurrentItem(ind);
+ throttle_val_off->setEnabled(v);
+ }
+ emit changed( useDefaults );
+}
+
+void ProfileConfig::defaults()
+{
+ load( true );
+}
+
+
+void ProfileConfig::configChanged()
+{
+ emit changed(true);
+}
+
+
+QString ProfileConfig::quickHelp() const
+{
+ return i18n("<h1>Laptop Power Profile Setup</h1>This module allows you to configure default values for static laptop "
+ "system attributes that will change when the laptop is plugged in or unplugged from the wall.");
+}
+
+
+void ProfileConfig::slotStartMonitor()
+{
+ wake_laptop_daemon();
+}
+
+
+#include "profile.moc"
+
+
diff --git a/klaptopdaemon/profile.h b/klaptopdaemon/profile.h
new file mode 100644
index 0000000..a9a81be
--- /dev/null
+++ b/klaptopdaemon/profile.h
@@ -0,0 +1,82 @@
+/*
+ * brightness.h
+ *
+ * Copyright (c) 2003 Paul Campbell <paul@taniwha.com>
+ *
+ * Requires the Qt widget libraries, available at no cost at
+ * http://www.troll.no/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef __BRIGHTNESSCONFIG_H__
+#define __BRIGHTNESSCONFIG_H__
+
+#include <kcmodule.h>
+#include <qstring.h>
+
+class QWidget;
+class QSpinBox;
+class KConfig;
+class QCheckBox;
+class QSlider;
+class KIconLoader;
+class KIconButton;
+class QPushButton;
+class KComboBox;
+
+
+class ProfileConfig : public KCModule
+{
+ Q_OBJECT
+public:
+ ProfileConfig( QWidget *parent=0, const char* name=0);
+ ~ProfileConfig( );
+
+ void save( void );
+ void load();
+ void load(bool useDefaults);
+ void defaults();
+
+ virtual QString quickHelp() const;
+
+private slots:
+
+ void configChanged();
+ void slotStartMonitor();
+ void poff_changed(bool);
+ void pon_changed(bool);
+ void throttle_off_changed(bool);
+ void throttle_on_changed(bool);
+ void performance_off_changed(bool);
+ void performance_on_changed(bool);
+
+
+private:
+ KConfig *config;
+
+ QCheckBox *pon, *performance_on, *throttle_on;
+ QSlider *son;
+ KComboBox *performance_val_on, *throttle_val_on;
+ QCheckBox *poff, *performance_off, *throttle_off;
+ QSlider *soff;
+ KComboBox *performance_val_off, *throttle_val_off;
+
+
+};
+
+#endif
+
diff --git a/klaptopdaemon/smapi.h b/klaptopdaemon/smapi.h
new file mode 100644
index 0000000..fff1285
--- /dev/null
+++ b/klaptopdaemon/smapi.h
@@ -0,0 +1,54 @@
+
+/*********************************************************************
+ *
+ * Filename: smapi.h
+ * Description: header file for the smapi driver
+ * Author: Thomas Hood
+ * Created: 19 July 1999
+ *
+ * Please report bugs to the author ASAP.
+ *
+ * Copyright (c) 1999 J.D. Thomas Hood, All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * To receive a copy of the GNU General Public License, please write
+ * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ ********************************************************************/
+
+#ifndef __SMAPI_H__
+#define __SMAPI_H__
+
+#include "smapibios.h"
+
+
+/****** typedefs ******/
+
+typedef smb_inparm_t smapi_inparm_t;
+typedef smb_outparm_t smapi_outparm_t;
+
+typedef union _smapi_ioparm_t {
+ smapi_inparm_t in;
+ smapi_outparm_t out;
+} smapi_ioparm_t;
+
+
+/****** declarations ******/
+
+int smapi_do(
+ unsigned long ulongIoctlArg,
+ flag_t fCallerHasWritePerm
+);
+
+
+#endif
diff --git a/klaptopdaemon/smapibios.h b/klaptopdaemon/smapibios.h
new file mode 100644
index 0000000..2751dc8
--- /dev/null
+++ b/klaptopdaemon/smapibios.h
@@ -0,0 +1,93 @@
+
+/*********************************************************************
+ *
+ * Filename: smapibios.h
+ * Description: header file for the IBM SMAPI BIOS
+ * Author: Thomas Hood
+ * Created: 14 July 1999
+ *
+ * Please report bugs to the author ASAP.
+ *
+ * Copyright (c) 1999 J.D. Thomas Hood, All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * To receive a copy of the GNU General Public License, please write
+ * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ ********************************************************************/
+
+#ifndef __SMAPIBIOS_H__
+#define __SMAPIBIOS_H__
+
+/* Is included by smapi.h */
+
+/*** SMAPI BIOS error codes ***/
+#define ERR_SMB_MIN ((byte)0x01)
+#define ERR_SMB_FUNC_NOT_AVAIL ((byte)0x53)
+#define ERR_SMB_FUNC_NOT_SUPPORTED ((byte)0x86)
+#define ERR_SMB_SYSTEM_ERROR ((byte)0x90)
+#define ERR_SMB_SYSTEM_INVALID ((byte)0x91)
+#define ERR_SMB_SYSTEM_BUSY ((byte)0x92)
+#define ERR_SMB_DEVICE_ERROR ((byte)0xA0)
+#define ERR_SMB_DEVICE_BUSY ((byte)0xA1)
+#define ERR_SMB_DEVICE_NOT_ATTACHED ((byte)0xA2)
+#define ERR_SMB_DEVICE_DISABLED ((byte)0xA3)
+#define ERR_SMB_PARM_INVALID ((byte)0x81)
+#define ERR_SMB_PARM_OUT_OF_RANGE ((byte)0xA4)
+#define ERR_SMB_PARM_NOT_ACCEPTED ((byte)0xA5)
+#define ERR_SMB_MAX ((byte)0xFF)
+
+/* The following structure definitions come from the ThinkPad 560Z Technical Reference */
+
+/*** SMAPI BIOS header ***/
+typedef struct _smb_header {
+ byte bSig[4]; /* signature */
+ byte bVerMajor; /* major version */
+ byte bVerMinor; /* minor version */
+ byte bLen; /* length */
+ byte bChksum; /* checksum */
+ word wInfo; /* information word */
+ word wRsv1; /* reserve 1 */
+ word wR_offset; /* real mode offset */
+ word wR_segment; /* real mode segment */
+ word wRsv2; /* reserve 2 */
+ word wP16_offset; /* 16-bit protect mode offset */
+ dword dwP16_base; /* 16-bit protect mode base address */
+ dword dwP32_offset; /* 32-bit protect mode offset */
+ dword dwP32_base; /* 32-bit protect mode base address */
+} smb_header_t;
+
+/*** SMAPI BIOS call input parameters ***/
+typedef struct _smb_inparm {
+ byte bFunc;
+ byte bSubFunc;
+ word wParm1;
+ word wParm2;
+ word wParm3;
+ dword dwParm4;
+ dword dwParm5;
+} smb_inparm_t;
+
+
+/*** SMAPI BIOS call output parameters ***/
+typedef struct _smb_outparm {
+ byte bRc;
+ byte bSubRc;
+ word wParm1;
+ word wParm2;
+ word wParm3;
+ dword dwParm4;
+ dword dwParm5;
+} smb_outparm_t;
+
+#endif
diff --git a/klaptopdaemon/smapidev.c b/klaptopdaemon/smapidev.c
new file mode 100644
index 0000000..3dbcd6d
--- /dev/null
+++ b/klaptopdaemon/smapidev.c
@@ -0,0 +1,743 @@
+#if defined(__linux__) || defined(__FreeBSD__)
+/*********************************************************************
+ *
+ * Filename: smapidev.c
+ * Description: IBM SMAPI (System Management API) interface functions
+ * Author: Bill Mair, Thomas Hood
+ * Created: 19 July 1999
+ *
+ * Please report bugs to the author ASAP.
+ *
+ * Copyright (c) 1999 J.D. Thomas Hood and Bill Mair,
+ * All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * To receive a copy of the GNU General Public License, please write
+ * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ ********************************************************************/
+
+#include <fcntl.h>
+#include <stdlib.h>
+#ifdef __linux__
+#include <linux/unistd.h>
+#else
+#include <unistd.h>
+#endif
+#include <getopt.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#ifdef __linux__
+#include <linux/types.h>
+#else
+#include <sys/types.h>
+#endif
+#include <stdio.h>
+#include <string.h>
+
+#ifndef __linux__
+typedef uint8_t __u8 ;
+typedef uint16_t __u16 ;
+typedef uint32_t __u32 ;
+#endif
+
+#include "thinkpad_common.h"
+/*#include "thinkpad.h" */
+#include "smapi.h"
+#include "smapidev.h"
+
+/****** defines ******/
+
+#define SZ_SMAPIDEV_VERSION "2.0"
+
+#define SZ_SMAPIDEV_NAME "smapidev"
+
+/*
+ * The structures may need to be extended if more
+ * functionality is added to the SMAPI by IBM.
+ *
+ * To cover this, future releases can check the size
+ * defined in sizeStruct, and reduce the amount of
+ * information put into the structure accordingly.
+ */
+
+#define SIZE_BIOSINFO_V1 ((size_t)24)
+#define SIZE_CPUINFO_V1 ((size_t)16)
+#define SIZE_DISPLAYINFO_V1 ((size_t) 8)
+#define SIZE_DOCKINGINFO_V1 ((size_t)12)
+#define SIZE_ULTRABAYINFO_V1 ((size_t) 8)
+#define SIZE_SLAVEINFO_V1 ((size_t)12)
+#define SIZE_SENSORINFO_V1 ((size_t) 8)
+#define SIZE_SCREENREFRESHINFO_V1 ((size_t)12)
+#define SIZE_DISPLAYCAP_V1 ((size_t)12)
+
+
+/****** variables ******/
+
+char szSmapidevName[] = SZ_SMAPIDEV_NAME;
+
+
+/****** utility functions ******/
+
+/*
+ * This function returns the binary value of a two-digit bcd number
+ * If the bcd8 value is 0xFF, as it may be if a location has never been
+ * initialized in the ThinkPad CMOS RAM, then 0xFF is returned as the
+ * binary equivalent.
+ */
+byte byte_of_bcd8( bcd8_t bcd8The )
+{
+ byte bTens, bUnits;
+
+ /* catch uninitialized values: simply return them */
+ if ( bcd8The == 0xFF ) return 0xFF;
+
+ bUnits = (byte)bcd8The & 0xF;
+ bTens = (byte)(bcd8The & 0xF0) >> 4;
+
+ if ( bUnits > 9 || bTens > 9 ) {
+ printf( "%s: Warning: value 0x%x which is supposed to be in BCD format is not; not converting.\n", szSmapidevName, bcd8The );
+ return (byte)bcd8The;
+ }
+
+ return bUnits + (bTens * 10);
+}
+
+
+bcd8_t bcd8_of_byte( byte bThe )
+{
+ byte bTens, bUnits;
+
+ if ( bThe > 99 ) {
+ printf( "%s: the value %d being converted to BCD format will be limited to 99.\n", szSmapidevName, bThe );
+ bThe = 99;
+ }
+
+ bTens = bThe / (byte)10;
+ bUnits = bThe - (bTens * (byte)10);
+
+ return (bTens << 4) | bUnits;
+}
+
+/*
+ * This function returns the SMAPI BIOS error code if there is one,
+ * otherwise the ioctl errno as a negative number
+ */
+int ioctl_smapi( int intFiledesc, smapi_ioparm_t *pioparmThe )
+{
+ int intRtn;
+
+ intRtn = ioctl( intFiledesc, IOCTL_SMAPI_REQUEST, pioparmThe );
+ if ( intRtn && errno == ETHINKPAD_SUBDRIVER ) return pioparmThe->out.bRc;
+ if ( intRtn ) return -errno;
+ return 0;
+}
+
+
+/****** functions ******/
+
+int smapidev_GetInfo( smapidev_info_t *pinfoThe )
+{
+
+ strncpy( pinfoThe->szVersion, SZ_SMAPIDEV_VERSION, LEN_VERSION_MAX );
+
+ /*** Make sure that the returned string is terminated ***/
+ pinfoThe->szVersion[LEN_VERSION_MAX] = '\0';
+
+ return 0;
+}
+
+
+/*** smapi-module-access functions ***/
+
+
+/*
+ * The Technical Reference fails to mention that the returned
+ * BIOS revision values are in BCD format
+ */
+int smapidev_GetBiosInfo(
+ int intFiledesc,
+ smapidev_biosinfo_t *pbiosinfoThe
+) {
+ bcd8_t bcd8SysHigh, bcd8SysLow;
+ bcd8_t bcd8SysMgmtHigh, bcd8SysMgmtLow;
+ bcd8_t bcd8SMAPIIfaceHigh, bcd8SMAPIIfaceLow;
+ bcd8_t bcd8VideoHigh, bcd8VideoLow;
+ smapi_ioparm_t ioparmThe;
+ int intRtn;
+
+ /* Check structure size */
+ if( pbiosinfoThe->sizeStruct != SIZE_BIOSINFO_V1 ) {
+# if DEBUG_STRUCT_SIZES
+ printf( "Declared size %d does not match expected size %d in GetBiosInfo\n" , pbiosinfoThe->sizeStruct, SIZE_BIOSINFO_V1 );
+# endif
+ return ERR_SMAPIDEV_STRUCTURE_SIZE_INVALID;
+ }
+
+ memset( &ioparmThe, 0, sizeof( ioparmThe ) );
+
+ ioparmThe.in.bFunc = (byte) 0;
+ ioparmThe.in.bSubFunc = (byte) 0;
+
+ intRtn = ioctl_smapi( intFiledesc, &ioparmThe );
+ if ( intRtn ) return intRtn;
+
+ pbiosinfoThe->wSysId = ioparmThe.out.wParm1;
+ pbiosinfoThe->wCountryCode = ioparmThe.out.wParm2;
+
+ bcd8SysHigh = (bcd8_t)( ioparmThe.out.wParm3 >> 8 );
+ bcd8SysLow = (bcd8_t)( ioparmThe.out.wParm3 & 0xFF );
+ pbiosinfoThe->wSysBiosRevMajor = (word) byte_of_bcd8( bcd8SysHigh );
+ pbiosinfoThe->wSysBiosRevMinor = (word) byte_of_bcd8( bcd8SysLow );
+
+ bcd8SysMgmtHigh = (bcd8_t)( (ioparmThe.out.dwParm4 >> 8) & 0xFF );
+ bcd8SysMgmtLow = (bcd8_t)( ioparmThe.out.dwParm4 & 0xFF );
+ pbiosinfoThe->wSysMgmtBiosRevMajor = (word) byte_of_bcd8( bcd8SysMgmtHigh );
+ pbiosinfoThe->wSysMgmtBiosRevMinor = (word) byte_of_bcd8( bcd8SysMgmtLow );
+
+ bcd8SMAPIIfaceHigh = (bcd8_t)( (ioparmThe.out.dwParm5 >> 8) & 0xFF );
+ bcd8SMAPIIfaceLow = (bcd8_t)( ioparmThe.out.dwParm5 & 0xFF );
+ pbiosinfoThe->wSmapiBiosIfaceRevMajor = (word) byte_of_bcd8( bcd8SMAPIIfaceHigh );
+ pbiosinfoThe->wSmapiBiosIfaceRevMinor = (word) byte_of_bcd8( bcd8SMAPIIfaceLow );
+
+ /*** Video BIOS info ***/
+ ioparmThe.in.bFunc = (byte) 0;
+ ioparmThe.in.bSubFunc = (byte) 8;
+
+ intRtn = ioctl_smapi( intFiledesc, &ioparmThe );
+ if ( intRtn ) return intRtn;
+
+ bcd8VideoHigh = (bcd8_t)( (ioparmThe.out.wParm1 >> 8) );
+ bcd8VideoLow = (bcd8_t)( ioparmThe.out.wParm1 & 0xFF );
+
+ pbiosinfoThe->wVideoBiosRevMajor = (word) byte_of_bcd8( bcd8VideoHigh );
+ pbiosinfoThe->wVideoBiosRevMinor = (word) byte_of_bcd8( bcd8VideoLow );
+
+ return 0;
+}
+
+
+int smapidev_GetCpuInfo(
+ int intFiledesc,
+ smapidev_cpuinfo_t *pcpuinfoThe
+) {
+ smapi_ioparm_t ioparmThe;
+ int intRtn;
+
+ /* Check structure size */
+ if( pcpuinfoThe->sizeStruct != SIZE_CPUINFO_V1 ) {
+# if DEBUG_STRUCT_SIZES
+ printf( "Declared size %d does not match expected size %d in GetCpuInfo\n" , pcpuinfoThe->sizeStruct, SIZE_CPUINFO_V1 );
+# endif
+ return ERR_SMAPIDEV_STRUCTURE_SIZE_INVALID;
+ }
+
+ memset( &ioparmThe, 0, sizeof( ioparmThe ) );
+ ioparmThe.in.bFunc = (byte) 0;
+ ioparmThe.in.bSubFunc = (byte) 1;
+
+ intRtn = ioctl_smapi( intFiledesc, &ioparmThe );
+ if ( intRtn ) return intRtn;
+
+ pcpuinfoThe->wManufacturer = (word)( 0xFF & ioparmThe.out.wParm1 );
+ pcpuinfoThe->wType = (word)( 0xFF & (ioparmThe.out.wParm2 >> 8) );
+ pcpuinfoThe->wStepping = (word)( 0xFF & ioparmThe.out.wParm2 );
+
+ pcpuinfoThe->wClock = (word)( 0xFF & (ioparmThe.out.wParm3 >> 8) );
+
+ if ( pcpuinfoThe->wClock == 0xfe )
+ pcpuinfoThe->wClock = (word) ioparmThe.out.dwParm4;
+
+ pcpuinfoThe->wInternalClock = (word)( 0xFF & ioparmThe.out.wParm3 );
+ if ( pcpuinfoThe->wInternalClock == 0xfe )
+ pcpuinfoThe->wInternalClock = (word) ioparmThe.out.dwParm5;
+
+ return 0;
+}
+
+
+int smapidev_GetDisplayInfo(
+ int intFiledesc,
+ smapidev_displayinfo_t *pdisplayinfoThe
+) {
+ smapi_ioparm_t ioparmThe;
+ int intRtn;
+
+ /* Check structure size */
+ if( pdisplayinfoThe->sizeStruct != SIZE_DISPLAYINFO_V1 ) {
+# if DEBUG_STRUCT_SIZES
+ printf( "Declared size %d does not match expected size %d in GetDisplayInfo\n" , pdisplayinfoThe->sizeStruct, SIZE_DISPLAYINFO_V1 );
+# endif
+ return ERR_SMAPIDEV_STRUCTURE_SIZE_INVALID;
+ }
+
+ memset( &ioparmThe, 0, sizeof( ioparmThe ) );
+ ioparmThe.in.bFunc = (byte) 0;
+ ioparmThe.in.bSubFunc = (byte) 2;
+ ioparmThe.in.wParm1 = (word) 0x300;
+
+ intRtn = ioctl_smapi( intFiledesc, &ioparmThe );
+ if ( intRtn ) return intRtn;
+
+ pdisplayinfoThe->bPanelType = (byte)(ioparmThe.out.wParm1 >> 8);
+ pdisplayinfoThe->bPanelDim = (byte)(ioparmThe.out.wParm1 & 0xFF);
+ pdisplayinfoThe->bCrtType = (byte)(ioparmThe.out.wParm2 >> 8);
+ pdisplayinfoThe->bCrtFeatures = (byte)(ioparmThe.out.wParm2 & 0xFF);
+
+ return 0;
+}
+
+
+int smapidev_GetDockingInfo(
+ int intFiledesc,
+ smapidev_dockinginfo_t *pdockinginfoThe
+) {
+ smapi_ioparm_t ioparmThe;
+ int intRtn;
+
+ /* Check structure size */
+ if( pdockinginfoThe->sizeStruct != SIZE_DOCKINGINFO_V1 ) {
+# if DEBUG_STRUCT_SIZES
+ printf( "Declared size %d does not match expected size %d in GetDockingInfo\n" , pdockinginfoThe->sizeStruct, SIZE_DOCKINGINFO_V1 );
+# endif
+ return ERR_SMAPIDEV_STRUCTURE_SIZE_INVALID;
+ }
+
+ memset( &ioparmThe, 0, sizeof( ioparmThe ) );
+ ioparmThe.in.bFunc = (byte) 0;
+ ioparmThe.in.bSubFunc = (byte) 3;
+
+ intRtn = ioctl_smapi( intFiledesc, &ioparmThe );
+ if ( intRtn ) return intRtn;
+
+ pdockinginfoThe->wID = ioparmThe.out.wParm1;
+ pdockinginfoThe->fDocked = (flag_t)( ioparmThe.out.bSubRc & 1);
+ pdockinginfoThe->fKeyUnlocked = (flag_t)((ioparmThe.out.bSubRc >> 6) & 1);
+ pdockinginfoThe->fBusConnected = (flag_t)((ioparmThe.out.bSubRc >> 7) & 1);
+
+ return 0;
+}
+
+
+int smapidev_GetUltrabayInfo(
+ int intFiledesc,
+ smapidev_ultrabayinfo_t *pultrabayinfoThe
+) {
+ smapi_ioparm_t ioparmThe;
+ int intRtn;
+
+ /* Check structure size */
+ if( pultrabayinfoThe->sizeStruct != SIZE_ULTRABAYINFO_V1 ) {
+# if DEBUG_STRUCT_SIZES
+ printf( "Declared size %d does not match expected size %d in GetUltrabayInfo\n" , pultrabayinfoThe->sizeStruct, SIZE_ULTRABAYINFO_V1 );
+# endif
+ return ERR_SMAPIDEV_STRUCTURE_SIZE_INVALID;
+ }
+
+ memset( &ioparmThe, 0, sizeof( ioparmThe ) );
+ ioparmThe.in.bFunc = (byte) 0;
+ ioparmThe.in.bSubFunc = (byte) 4;
+
+ intRtn = ioctl_smapi( intFiledesc, &ioparmThe );
+ if ( intRtn ) return intRtn;
+
+ pultrabayinfoThe->bType = (byte)(ioparmThe.out.wParm2 >> 8);
+ pultrabayinfoThe->bID = (byte)(ioparmThe.out.wParm2 & 0xFF);
+
+ return 0;
+}
+
+
+/*
+ * The ThinkPad 560Z Technical Reference describes function 0:6 as
+ * "Get Power Management Module Information" while the ThinkPad 600
+ * describes it as "Get Slave Micro Control Unit Information"
+ */
+int smapidev_GetSlaveControllerInfo(
+ int intFiledesc,
+ smapidev_slaveinfo_t *pslaveinfoThe
+) {
+ smapi_ioparm_t ioparmThe;
+ bcd8_t bcd8High = 0, bcd8Low = 0;
+ flag_t fInvalidID;
+ int intRtn;
+
+ /* Check structure size */
+ if( pslaveinfoThe->sizeStruct != SIZE_SLAVEINFO_V1 ) {
+# if DEBUG_STRUCT_SIZES
+ printf( "Declared size %d does not match expected size %d in GetSlaveControllerInfo\n" , pslaveinfoThe->sizeStruct, SIZE_SLAVEINFO_V1 );
+# endif
+ return ERR_SMAPIDEV_STRUCTURE_SIZE_INVALID;
+ }
+
+ memset( &ioparmThe, 0, sizeof( ioparmThe ) );
+ ioparmThe.in.bFunc = (byte) 0;
+ ioparmThe.in.bSubFunc = (byte) 6;
+
+ intRtn = ioctl_smapi( intFiledesc, &ioparmThe );
+ if ( intRtn ) return intRtn;
+
+ if ( ioparmThe.out.wParm2 == 0xFFFF ) {
+ fInvalidID = 1;
+ } else {
+ fInvalidID = 0;
+ bcd8High = (bcd8_t)( ioparmThe.out.wParm2 >> 8 );
+ bcd8Low = (bcd8_t)( ioparmThe.out.wParm2 & 0xFF );
+ }
+
+ pslaveinfoThe->fAscii = (ioparmThe.out.bSubRc == 0);
+ if ( fInvalidID ) {
+ pslaveinfoThe->wIDMajor = 0xFFFF;
+ pslaveinfoThe->wIDMinor = 0xFFFF;
+ } else {
+ pslaveinfoThe->wIDMajor = byte_of_bcd8( bcd8High );
+ pslaveinfoThe->wIDMinor = byte_of_bcd8( bcd8Low );
+ }
+ pslaveinfoThe->szID[0] = (char)(0xFF&(ioparmThe.out.wParm2>>8));
+ pslaveinfoThe->szID[1] = (char)(0xFF&ioparmThe.out.wParm2);
+ pslaveinfoThe->szID[2] = '\0'; /* Add zero termination */
+
+ return 0;
+}
+
+
+int smapidev_GetSensorInfo(
+ int intFiledesc,
+ smapidev_sensorinfo_t *psensorinfoThe
+) {
+ smapi_ioparm_t ioparmThe;
+ int intRtn;
+
+ /* Check structure size */
+ if( psensorinfoThe->sizeStruct != SIZE_SENSORINFO_V1 ) {
+# if DEBUG_STRUCT_SIZES
+ printf( "Declared size %d does not match expected size %d in GetSensorInfo\n" , psensorinfoThe->sizeStruct, SIZE_SENSORINFO_V1 );
+# endif
+ return ERR_SMAPIDEV_STRUCTURE_SIZE_INVALID;
+ }
+
+ memset( &ioparmThe, 0, sizeof( ioparmThe ) );
+ ioparmThe.in.bFunc = (byte) 0;
+ ioparmThe.in.bSubFunc = (byte) 7;
+
+ intRtn = ioctl_smapi( intFiledesc, &ioparmThe );
+ if ( intRtn ) return intRtn;
+
+ psensorinfoThe->fLidClosed = (ioparmThe.out.wParm2 >> 8) & 1;
+ psensorinfoThe->fKeyboardOpen = (ioparmThe.out.wParm2 >> 9) & 1;
+ psensorinfoThe->fACAdapterAttached = (ioparmThe.out.wParm2 >> 10) & 1;
+
+ return 0;
+}
+
+int smapidev_GetScreenRefreshInfo(
+ int intFiledesc,
+ word wMode,
+ smapidev_screenrefreshinfo_t *pscreenrefreshinfoThe
+) {
+ smapi_ioparm_t ioparmThe;
+ int intRtn;
+
+ /* Check structure size */
+ if( pscreenrefreshinfoThe->sizeStruct != SIZE_SCREENREFRESHINFO_V1 ) {
+# if DEBUG_STRUCT_SIZES
+ printf( "Declared size %d does not match expected size %d in GetScreenRefreshInfo\n" , pscreenrefreshinfoThe->sizeStruct, SIZE_SCREENREFRESHINFO_V1 );
+# endif
+ return ERR_SMAPIDEV_STRUCTURE_SIZE_INVALID;
+ }
+
+ memset( &ioparmThe, 0, sizeof( ioparmThe ) );
+ ioparmThe.in.bFunc = (byte) 0;
+ ioparmThe.in.bSubFunc = (byte) 9;
+ ioparmThe.in.wParm1 = wMode;
+
+ intRtn = ioctl_smapi( intFiledesc, &ioparmThe );
+ if ( intRtn ) return intRtn;
+
+ pscreenrefreshinfoThe->f43i = (ioparmThe.out.wParm2 >> 3) & 1;
+ pscreenrefreshinfoThe->f48i = (ioparmThe.out.wParm2 >> 7) & 1;
+ pscreenrefreshinfoThe->f56 = (ioparmThe.out.wParm2 >> 4) & 1;
+ pscreenrefreshinfoThe->f60 = ioparmThe.out.wParm2 & 1;
+ pscreenrefreshinfoThe->f70 = (ioparmThe.out.wParm2 >> 5) & 1;
+ pscreenrefreshinfoThe->f72 = (ioparmThe.out.wParm2 >> 1) & 1;
+ pscreenrefreshinfoThe->f75 = (ioparmThe.out.wParm2 >> 2) & 1;
+ pscreenrefreshinfoThe->f85 = (ioparmThe.out.wParm2 >> 6) & 1;
+
+ return 0;
+}
+
+
+int smapidev_GetDisplayCapability(
+ int intFiledesc,
+ smapidev_stateplace_t stateplace,
+ smapidev_displaycap_t *pdisplaycapThe
+) {
+ smapi_ioparm_t ioparmThe;
+ int intRtn;
+
+ /* Check structure size */
+ if( pdisplaycapThe->sizeStruct != SIZE_DISPLAYCAP_V1 ) {
+# if DEBUG_STRUCT_SIZES
+ printf( "Declared size %d does not match expected size %d in GetDisplayCapability\n" , pdisplaycapThe->sizeStruct, SIZE_DISPLAYCAP_V1 );
+# endif
+ return ERR_SMAPIDEV_STRUCTURE_SIZE_INVALID;
+ }
+
+ memset( &ioparmThe, 0, sizeof( ioparmThe ) );
+ ioparmThe.in.bFunc = (byte) 0x10;
+ ioparmThe.in.bSubFunc = (byte) 0;
+ switch ( stateplace ) {
+ case SMAPIDEV_STATEPLACE_CMOS: ioparmThe.in.wParm1 = (word) 1; break;
+ case SMAPIDEV_STATEPLACE_CURR: ioparmThe.in.wParm1 = (word) 0; break;
+ case SMAPIDEV_STATEPLACE_CMOS_AND_CURR:
+ default: return ERR_SMAPIDEV_PARM_INVALID;
+ }
+
+ intRtn = ioctl_smapi( intFiledesc, &ioparmThe );
+ if ( intRtn ) return intRtn;
+
+ pdisplaycapThe->fSupported = (flag_t)(ioparmThe.out.wParm2 & 1);
+ switch ( ioparmThe.out.wParm2 & 0xFF ) {
+ case 0:
+ pdisplaycapThe->tv = SMAPIDEV_DISPLAYCAPTV_NONE;
+ break;
+ case 1:
+ pdisplaycapThe->tv = SMAPIDEV_DISPLAYCAPTV_NONSIMULTANEOUS;
+ break;
+ default:
+ pdisplaycapThe->tv = SMAPIDEV_DISPLAYCAPTV_OTHER;
+ return ERR_SMAPIDEV_SMAPI_RESULT_NOT_UNDERSTOOD;
+ }
+
+ return 0;
+}
+
+
+int smapidev_GetDisplayState(
+ int intFiledesc,
+ smapidev_stateplace_t stateplace,
+ smapidev_dispmode_t dispmodeThe,
+ smapidev_ablestate_t *pablestateThe
+) {
+ smapi_ioparm_t ioparmThe;
+ int intRtn;
+
+ memset( &ioparmThe, 0, sizeof( ioparmThe ) );
+ ioparmThe.in.bFunc = (byte) 0x10;
+ ioparmThe.in.bSubFunc = (byte) 0;
+ switch ( stateplace ) {
+ case SMAPIDEV_STATEPLACE_CMOS: ioparmThe.in.wParm1 = (word) 1; break;
+ case SMAPIDEV_STATEPLACE_CURR: ioparmThe.in.wParm1 = (word) 0; break;
+ case SMAPIDEV_STATEPLACE_CMOS_AND_CURR:
+ default: return ERR_SMAPIDEV_PARM_INVALID;
+ }
+
+ intRtn = ioctl_smapi( intFiledesc, &ioparmThe );
+ if ( intRtn ) return intRtn;
+
+ switch( dispmodeThe )
+ {
+ case SMAPIDEV_DISPMODE_INTERNAL :
+ *pablestateThe = ( ioparmThe.out.wParm2 & 0x100 ) ? SMAPIDEV_ABLESTATE_ENABLED : SMAPIDEV_ABLESTATE_DISABLED ;
+ break;
+
+ case SMAPIDEV_DISPMODE_CRT :
+ *pablestateThe = ( ioparmThe.out.wParm2 & 0x200 ) ? SMAPIDEV_ABLESTATE_ENABLED : SMAPIDEV_ABLESTATE_DISABLED ;
+ break;
+
+ case SMAPIDEV_DISPMODE_TV :
+ *pablestateThe = ( ioparmThe.out.wParm2 & 0x400 ) ? SMAPIDEV_ABLESTATE_ENABLED : SMAPIDEV_ABLESTATE_DISABLED ;
+ break;
+
+ case SMAPIDEV_DISPMODE_CRT_DETECTION_IGNORE :
+ *pablestateThe = ( ioparmThe.out.wParm2 & 0x4000 ) ? SMAPIDEV_ABLESTATE_ENABLED : SMAPIDEV_ABLESTATE_DISABLED ;
+ break;
+
+ case SMAPIDEV_DISPMODE_DUAL :
+ *pablestateThe = ( ioparmThe.out.wParm2 & 0x8000 ) ? SMAPIDEV_ABLESTATE_ENABLED : SMAPIDEV_ABLESTATE_DISABLED ;
+ break;
+
+ case SMAPIDEV_DISPMODE_SELECT_TV :
+ *pablestateThe = ( ioparmThe.out.dwParm4 & 1 ) ? SMAPIDEV_ABLESTATE_ENABLED : SMAPIDEV_ABLESTATE_DISABLED ;
+ break;
+
+ default:
+ return ERR_SMAPIDEV_PARM_INVALID;
+ }
+
+ return 0;
+}
+
+
+int smapidev_SetDisplayState(
+ int intFiledesc,
+ smapidev_stateplace_t stateplace,
+ smapidev_dispmode_t dispmodeThe,
+ smapidev_ablestate_t ablestateThe
+) {
+ smapi_ioparm_t ioparmGet;
+ smapi_ioparm_t ioparmSet;
+ int intRtn;
+
+ /* We can only update CMOS and current state together */
+ if ( stateplace != SMAPIDEV_STATEPLACE_CMOS_AND_CURR )
+ return ERR_SMAPIDEV_PARM_INVALID;
+
+ /* No SMAPIDEV_STATE_AUTO or other invalid values are allowed here */
+ if( ablestateThe != SMAPIDEV_ABLESTATE_DISABLED && ablestateThe != SMAPIDEV_ABLESTATE_ENABLED )
+ {
+ return ERR_SMAPIDEV_PARM_INVALID;
+ }
+
+ /* Get the current CMOS state */
+ memset( &ioparmGet, 0, sizeof( ioparmGet ) );
+ ioparmGet.in.bFunc = (byte) 0x10;
+ ioparmGet.in.bSubFunc = (byte) 0;
+ ioparmGet.in.wParm1 = (word) 1;
+
+ intRtn = ioctl_smapi( intFiledesc, &ioparmGet );
+ if ( intRtn ) return intRtn;
+
+ memset( &ioparmSet, 0, sizeof( ioparmSet ) );
+ ioparmSet.in.bFunc = (byte) 0x10;
+ ioparmSet.in.bSubFunc = (byte) 1;
+ ioparmSet.in.wParm1 = ioparmGet.out.wParm2 & 0xC700;
+ ioparmSet.in.dwParm4 = ioparmGet.out.dwParm4 & 0x0001;
+
+ switch( dispmodeThe )
+ {
+
+ case SMAPIDEV_DISPMODE_INTERNAL :
+ if( ablestateThe == SMAPIDEV_ABLESTATE_ENABLED )
+ ioparmSet.in.wParm1 |= 0x100;
+ else
+ ioparmSet.in.wParm1 &= ~0x100;
+ break;
+
+ case SMAPIDEV_DISPMODE_CRT :
+ if( ablestateThe == SMAPIDEV_ABLESTATE_ENABLED )
+ ioparmSet.in.wParm1 |= 0x200;
+ else
+ ioparmSet.in.wParm1 &= ~0x200;
+ break;
+
+ case SMAPIDEV_DISPMODE_TV :
+ if( ablestateThe == SMAPIDEV_ABLESTATE_ENABLED )
+ ioparmSet.in.wParm1 |= 0x400;
+ else
+ ioparmSet.in.wParm1 &= ~0x400;
+ break;
+
+ case SMAPIDEV_DISPMODE_CRT_DETECTION_IGNORE :
+ if( ablestateThe == SMAPIDEV_ABLESTATE_ENABLED )
+ ioparmSet.in.wParm1 |= 0x4000;
+ else
+ ioparmSet.in.wParm1 &= ~0x4000;
+ break;
+
+ case SMAPIDEV_DISPMODE_DUAL :
+ if( ablestateThe == SMAPIDEV_ABLESTATE_ENABLED )
+ ioparmSet.in.wParm1 |= 0x8000;
+ else
+ ioparmSet.in.wParm1 &= ~0x8000;
+ break;
+
+ case SMAPIDEV_DISPMODE_SELECT_TV :
+ if( ablestateThe == SMAPIDEV_ABLESTATE_ENABLED )
+ ioparmSet.in.dwParm4 |= 0x1;
+ else
+ ioparmSet.in.dwParm4 &= ~0x1;
+ break;
+
+ default:
+ return ERR_SMAPIDEV_PARM_INVALID;
+ }
+
+ return ioctl_smapi( intFiledesc, &ioparmSet );
+}
+
+
+int smapidev_GetPowerExpenditureMode(
+ int intFiledesc,
+ smapidev_powersrc_t powersrcThe,
+ smapidev_powermode_t *ppowermodeThe
+) {
+ smapi_ioparm_t ioparmThe;
+ int intRtn;
+ byte bModeAC, bModeBat, bModeSelected;
+
+ memset( &ioparmThe, 0, sizeof( ioparmThe ) );
+ ioparmThe.in.bFunc = (byte) 0x22;
+ ioparmThe.in.bSubFunc = (byte) 0;
+
+ intRtn = ioctl_smapi( intFiledesc, &ioparmThe );
+ if ( intRtn ) return intRtn;
+
+ bModeAC = (byte)(ioparmThe.out.wParm2 & 0xFF);
+ bModeBat = (byte)(ioparmThe.out.wParm2 >> 8);
+ bModeSelected = (powersrcThe == SMAPIDEV_POWERSRC_AC) ? bModeAC : bModeBat;
+
+ switch ( bModeSelected ) {
+ case 0: *ppowermodeThe = SMAPIDEV_POWERMODE_HIGH; break;
+ case 1: *ppowermodeThe = SMAPIDEV_POWERMODE_AUTO; break;
+ case 2: *ppowermodeThe = SMAPIDEV_POWERMODE_MANUAL; break;
+ default:
+ case 3: *ppowermodeThe = SMAPIDEV_POWERMODE_UNRECOGNIZED; break;
+ }
+
+ return 0;
+}
+
+
+
+int smapidev_SetPowerExpenditureMode(
+ int intFiledesc,
+ smapidev_powersrc_t powersrcThe,
+ smapidev_powermode_t powermodeThe
+) {
+ smapi_ioparm_t ioparmThe;
+ int intRtn;
+ byte bMode;
+
+ bMode =
+ (powermodeThe == SMAPIDEV_POWERMODE_HIGH) ? 0 :
+ (powermodeThe == SMAPIDEV_POWERMODE_AUTO) ? 1 :
+ 2
+ ;
+
+ memset( &ioparmThe, 0, sizeof( ioparmThe ) );
+ ioparmThe.in.bFunc = (byte) 0x22;
+ ioparmThe.in.bSubFunc = (byte) 0;
+
+ intRtn = ioctl_smapi( intFiledesc, &ioparmThe );
+ if ( intRtn ) return intRtn;
+
+ ioparmThe.in.bFunc = (byte) 0x22;
+ ioparmThe.in.bSubFunc = (byte) 1;
+ ioparmThe.in.wParm1 = ioparmThe.out.wParm2;
+ if ( powersrcThe == SMAPIDEV_POWERSRC_AC ) {
+ ioparmThe.in.wParm1 &= 0xff00;
+ ioparmThe.in.wParm1 |= bMode;
+ } else { /* powersrcThe == SMAPIDEV_POWERSRC_BATTERY */
+ ioparmThe.in.wParm1 &= 0x00ff;
+ ioparmThe.in.wParm1 |= ((word)bMode) << 8;
+ }
+
+ intRtn = ioctl_smapi( intFiledesc, &ioparmThe );
+ if ( intRtn ) return intRtn;
+
+ return 0;
+}
+#else
+int smapi_dummy(){}
+#endif
diff --git a/klaptopdaemon/smapidev.h b/klaptopdaemon/smapidev.h
new file mode 100644
index 0000000..22deedb
--- /dev/null
+++ b/klaptopdaemon/smapidev.h
@@ -0,0 +1,273 @@
+
+/*********************************************************************
+ *
+ * Filename: smapidev.h
+ * Description: Header for the SMAPI device driver access library
+ * Author: Bill Mair, Thomas Hood
+ * Created: 13 July 1999
+ *
+ * Please report bugs to the author ASAP.
+ *
+ * Copyright (c) 1999 Bill Mair, All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * To receive a copy of the GNU General Public License, please write
+ * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ ********************************************************************/
+
+#ifndef __SMAPIDEV_H__
+#define __SMAPIDEV_H__
+
+/****** defines ******/
+
+/*** smapidev function error codes ***/
+/*
+ * These codes must not fall in the range 0x0-0xFF which is
+ * reserved for SMAPI BIOS error codes
+ */
+#define ERR_SMAPIDEV_MIN ((int)0x1000)
+#define ERR_SMAPIDEV_PARM_INVALID ((int)0x1050)
+#define ERR_SMAPIDEV_STRUCTURE_SIZE_INVALID ((int)0x1051)
+#define ERR_SMAPIDEV_SMAPI_RESULT_NOT_UNDERSTOOD ((int)0x1090)
+#define ERR_SMAPIDEV_MAX ((int)0x10FF)
+
+/****** typedefs ******/
+
+/*** enum ***/
+
+typedef enum _smapidev_stateplace {
+ SMAPIDEV_STATEPLACE_CURR=0,
+ SMAPIDEV_STATEPLACE_CMOS,
+ SMAPIDEV_STATEPLACE_CMOS_AND_CURR
+} smapidev_stateplace_t;
+
+typedef enum _smapidev_ablestate {
+ SMAPIDEV_ABLESTATE_DISABLED=0,
+ SMAPIDEV_ABLESTATE_ENABLED,
+ SMAPIDEV_ABLESTATE_AUTO
+} smapidev_ablestate_t;
+
+typedef enum _smapidev_displaycaptv {
+ SMAPIDEV_DISPLAYCAPTV_NONE=0,
+ SMAPIDEV_DISPLAYCAPTV_NONSIMULTANEOUS,
+ SMAPIDEV_DISPLAYCAPTV_OTHER
+} smapidev_displaycaptv_t;
+
+/*
+ * The following are the display modes that can be enabled or disabled
+ */
+typedef enum _smapidev_dispmode {
+ SMAPIDEV_DISPMODE_INTERNAL=0,
+ SMAPIDEV_DISPMODE_CRT,
+ SMAPIDEV_DISPMODE_TV,
+ SMAPIDEV_DISPMODE_CRT_DETECTION_IGNORE,
+ SMAPIDEV_DISPMODE_DUAL,
+ SMAPIDEV_DISPMODE_SELECT_TV
+} smapidev_dispmode_t;
+
+typedef enum _smapidev_fnkeymode {
+ SMAPIDEV_FNKEY_NORMAL=0,
+ SMAPIDEV_FNKEY_STICKY,
+ SMAPIDEV_FNKEY_LOCKED
+} smapidev_fnkeymode_t;
+
+typedef enum _smapidev_ternality {
+ SMAPIDEV_TERNALITY_IN=0,
+ SMAPIDEV_TERNALITY_EX
+} smapidev_ternality_t;
+
+typedef enum _smapidev_powersrc {
+ SMAPIDEV_POWERSRC_AC=0,
+ SMAPIDEV_POWERSRC_BATTERY
+} smapidev_powersrc_t;
+
+typedef enum _smapidev_powermode {
+ SMAPIDEV_POWERMODE_HIGH=0,
+ SMAPIDEV_POWERMODE_AUTO,
+ SMAPIDEV_POWERMODE_MANUAL,
+ SMAPIDEV_POWERMODE_UNRECOGNIZED
+} smapidev_powermode_t;
+
+
+/*** struct ***/
+
+typedef struct _smapidev_info
+{
+ char szVersion[LEN_VERSION_MAX+1];
+} smapidev_info_t;
+
+typedef struct _smapidev_biosinfo
+{
+ size_t sizeStruct;
+ word wSysId;
+ word wCountryCode;
+ word wSysBiosRevMajor;
+ word wSysBiosRevMinor;
+ word wSysMgmtBiosRevMajor;
+ word wSysMgmtBiosRevMinor;
+ word wSmapiBiosIfaceRevMajor;
+ word wSmapiBiosIfaceRevMinor;
+ word wVideoBiosRevMajor;
+ word wVideoBiosRevMinor;
+} smapidev_biosinfo_t;
+
+typedef struct _smapidev_cpuinfo
+{
+ size_t sizeStruct;
+ word wManufacturer;
+ word wType;
+ word wStepping;
+ word wClock;
+ word wInternalClock;
+} smapidev_cpuinfo_t;
+
+typedef struct _smapidev_displayinfo
+{
+ size_t sizeStruct;
+ byte bPanelType;
+ byte bPanelDim;
+ byte bCrtType;
+ byte bCrtFeatures;
+} smapidev_displayinfo_t;
+
+typedef struct _smapidev_dockinginfo
+{
+ size_t sizeStruct;
+ word wID;
+ flag_t fDocked;
+ flag_t fKeyUnlocked;
+ flag_t fBusConnected;
+} smapidev_dockinginfo_t;
+
+typedef struct _smapidev_ultrabayinfo
+{
+ size_t sizeStruct;
+ byte bType;
+ byte bID;
+} smapidev_ultrabayinfo_t;
+
+typedef struct _smapidev_slaveinfo
+{
+ size_t sizeStruct;
+ flag_t fAscii;
+ char szID[3];
+ word wIDMajor;
+ word wIDMinor;
+} smapidev_slaveinfo_t;
+
+typedef struct _smapidev_sensorinfo
+{
+ size_t sizeStruct;
+ flag_t fLidClosed;
+ flag_t fKeyboardOpen;
+ flag_t fACAdapterAttached;
+} smapidev_sensorinfo_t;
+
+typedef struct _smapidev_screenrefreshinfo
+{
+ size_t sizeStruct;
+ flag_t f43i;
+ flag_t f48i;
+ flag_t f56;
+ flag_t f60;
+ flag_t f70;
+ flag_t f72;
+ flag_t f75;
+ flag_t f85;
+} smapidev_screenrefreshinfo_t;
+
+typedef struct _smapidev_displaycap {
+ size_t sizeStruct;
+ flag_t fSupported;
+ smapidev_displaycaptv_t tv;
+} smapidev_displaycap_t;
+
+
+/****** function declarations ******/
+
+bcd8_t bcd8_of_byte( byte bThe );
+byte byte_of_bcd8( bcd8_t bcd8The );
+int ioctl_smapi( int intFiledesc, smapi_ioparm_t *pioparmThe );
+
+/*** Get/Set####Info ***/
+
+int smapidev_GetInfo( smapidev_info_t *pinfoThe );
+int smapidev_GetBiosInfo(
+ int intFiledesc,
+ smapidev_biosinfo_t *pbiosinfoThe
+);
+int smapidev_GetCpuInfo(
+ int intFiledesc,
+ smapidev_cpuinfo_t *pcpuinfoThe
+);
+int smapidev_GetDisplayInfo(
+ int intFiledesc,
+ smapidev_displayinfo_t *pdisplayinfoThe
+);
+int smapidev_GetDockingInfo(
+ int intFiledesc,
+ smapidev_dockinginfo_t *pdockinginfoThe
+);
+int smapidev_GetUltrabayInfo(
+ int intFiledesc,
+ smapidev_ultrabayinfo_t *pultrabayinfoThe
+);
+int smapidev_GetSlaveControllerInfo(
+ int intFiledesc,
+ smapidev_slaveinfo_t *pslaveinfoThe
+);
+int smapidev_GetSensorInfo(
+ int intFiledesc,
+ smapidev_sensorinfo_t *psensorinfoThe
+);
+int smapidev_GetScreenRefreshInfo(
+ int intFiledesc,
+ word wMode,
+ smapidev_screenrefreshinfo_t *pscreenrefreshinfoThe
+);
+
+/*** Get/Set####State ***/
+
+int smapidev_GetDisplayCapability(
+ int intFiledesc,
+ smapidev_stateplace_t stateplace,
+ smapidev_displaycap_t *pdisplaycap
+);
+int smapidev_GetDisplayState(
+ int intFiledesc,
+ smapidev_stateplace_t stateplace,
+ smapidev_dispmode_t dispmode,
+ smapidev_ablestate_t *pablestate
+);
+int smapidev_SetDisplayState(
+ int intFiledesc,
+ smapidev_stateplace_t stateplace,
+ smapidev_dispmode_t dispmode,
+ smapidev_ablestate_t ablestate
+);
+
+/*** PM ***/
+
+int smapidev_GetPowerExpenditureMode(
+ int intFiledesc,
+ smapidev_powersrc_t powersrc,
+ smapidev_powermode_t *ppowermode
+);
+int smapidev_SetPowerExpenditureMode(
+ int intFiledesc,
+ smapidev_powersrc_t powersrc,
+ smapidev_powermode_t powermode
+);
+
+#endif
diff --git a/klaptopdaemon/sony.cpp b/klaptopdaemon/sony.cpp
new file mode 100644
index 0000000..8183f21
--- /dev/null
+++ b/klaptopdaemon/sony.cpp
@@ -0,0 +1,200 @@
+/*
+ * sony.cpp
+ *
+ * Copyright (c) 2002 Paul Campbell <paul@taniwha.com>
+ *
+ * Requires the Qt widget libraries, available at no cost at
+ * http://www.troll.no/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+// my headers:
+#include "sony.h"
+#include "version.h"
+#include "portable.h"
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+// other KDE headers:
+#include <klocale.h>
+#include <kconfig.h>
+#include <knuminput.h>
+#include <kiconloader.h>
+#include <kicondialog.h>
+#include <kapplication.h>
+#include <kprocess.h>
+#include <kstandarddirs.h>
+#include <kmessagebox.h>
+#include <krichtextlabel.h>
+
+// other Qt headers:
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qcheckbox.h>
+#include <qhbox.h>
+#include <qvgroupbox.h>
+#include <qgrid.h>
+#include <qpushbutton.h>
+#include <qslider.h>
+#include <qtooltip.h>
+
+extern void wake_laptop_daemon();
+
+SonyConfig::SonyConfig(QWidget * parent, const char *name)
+ : KCModule(parent, name)
+{
+ KGlobal::locale()->insertCatalogue("klaptopdaemon"); // For translation of klaptopdaemon messages
+
+ config = new KConfig("kcmlaptoprc");
+
+ QVBoxLayout *top_layout = new QVBoxLayout( this, KDialog::marginHint(),
+ KDialog::spacingHint() );
+
+ // TODO: remove linefeed from string, can't do it right now coz we have a string freeze
+ top_layout->addWidget(new KRichTextLabel(i18n("This panel allows you to control some of the features of the\n"
+ "'sonypi' device for your laptop - you should not enable the options below if you\nalso "
+ "use the 'sonypid' program in your system").replace("\n", " "), this));
+
+ enableScrollBar = new QCheckBox( i18n("Enable &scroll bar"), this );
+ QToolTip::add( enableScrollBar, i18n( "When checked this box enables the scrollbar so that it works under KDE" ) );
+ top_layout->addWidget( enableScrollBar );
+ connect( enableScrollBar, SIGNAL(clicked()), this, SLOT(configChanged()) );
+
+ enableMiddleEmulation = new QCheckBox( i18n("&Emulate middle mouse button with scroll bar press"), this );
+ QToolTip::add( enableMiddleEmulation, i18n( "When checked this box enables pressing the scroll bar to act in the same way as pressing the middle button on a 3 button mouse" ) );
+ top_layout->addWidget( enableMiddleEmulation );
+ connect( enableMiddleEmulation, SIGNAL(clicked()), this, SLOT(configChanged()) );
+
+ if (::access("/dev/sonypi", R_OK) != 0) {
+ enableMiddleEmulation->setEnabled(0);
+ enableScrollBar->setEnabled(0);
+
+ // TODO: remove linefeed from string, can't do it right now coz we have a string freeze
+ top_layout->addWidget(new KRichTextLabel(i18n("The /dev/sonypi is not accessable, if you wish to use the above features its\n"
+ "protections need to be changed. Clicking on the button below will change them\n").replace("\n", " "), this));
+ QHBoxLayout *ll = new QHBoxLayout();
+ QPushButton *setupButton = new QPushButton(i18n("Setup /dev/sonypi"), this);
+ connect( setupButton, SIGNAL(clicked()), this, SLOT(setupHelper()) );
+ QToolTip::add( setupButton, i18n( "This button can be used to enable the sony specific features" ) );
+ ll->addStretch(2);
+ ll->addWidget(setupButton);
+ ll->addStretch(8);
+ top_layout->addLayout(ll);
+ }
+
+
+ top_layout->addStretch(1);
+ top_layout->addWidget( new QLabel( i18n("Version: %1").arg(LAPTOP_VERSION), this), 0, Qt::AlignRight );
+
+
+ load();
+}
+
+void SonyConfig::setupHelper()
+{
+ QString kdesu = KStandardDirs::findExe("kdesu");
+ if (!kdesu.isEmpty()) {
+ int rc = KMessageBox::warningContinueCancel(0,
+ i18n("You will need to supply a root password "
+ "to allow the protections of /dev/sonypi to be changed."),
+ i18n("KLaptopDaemon"), KStdGuiItem::cont(),
+ "");
+ if (rc == KMessageBox::Continue) {
+ KProcess proc;
+ proc << kdesu;
+ proc << "-u";
+ proc << "root";
+ proc << "chmod +r /dev/sonypi";
+ proc.start(KProcess::Block); // run it sync so has_acpi below sees the results
+ }
+ } else {
+ KMessageBox::sorry(0, i18n("The /dev/sonypi protections cannot be changed because kdesu cannot be found. Please make sure that it is installed correctly."),
+ i18n("KLaptopDaemon"));
+ }
+ bool enable = ::access("/dev/sonypi", R_OK) == 0;
+ enableMiddleEmulation->setEnabled(enable);
+ enableScrollBar->setEnabled(enable);
+ wake_laptop_daemon();
+}
+
+SonyConfig::~SonyConfig()
+{
+ delete config;
+}
+
+void SonyConfig::save()
+{
+ enablescrollbar = enableScrollBar->isChecked();
+ middleemulation = enableMiddleEmulation->isChecked();
+
+ config->setGroup("SonyDefault");
+
+ config->writeEntry("EnableScrollBar", enablescrollbar);
+ config->writeEntry("EnableMiddleEmulation", middleemulation);
+ config->sync();
+ changed(false);
+ wake_laptop_daemon();
+}
+
+void SonyConfig::load()
+{
+ load( false );
+}
+
+void SonyConfig::load(bool useDefaults)
+{
+ config->setReadDefaults( useDefaults );
+
+ config->setGroup("SonyDefault");
+
+ enablescrollbar = config->readBoolEntry("EnableScrollBar", false);
+ enableScrollBar->setChecked(enablescrollbar);
+ middleemulation = config->readBoolEntry("EnableMiddleEmulation", false);
+ enableMiddleEmulation->setChecked(middleemulation);
+
+ emit changed( useDefaults );
+}
+
+void SonyConfig::defaults()
+{
+ load( true );
+}
+
+
+void SonyConfig::configChanged()
+{
+ emit changed(true);
+}
+
+
+QString SonyConfig::quickHelp() const
+{
+ return i18n("<h1>Sony Laptop Hardware Setup</h1>This module allows you to configure "
+ "some Sony laptop hardware for your system");
+}
+
+
+void SonyConfig::slotStartMonitor()
+{
+ wake_laptop_daemon();
+}
+
+
+#include "sony.moc"
+
+
diff --git a/klaptopdaemon/sony.h b/klaptopdaemon/sony.h
new file mode 100644
index 0000000..ab31065
--- /dev/null
+++ b/klaptopdaemon/sony.h
@@ -0,0 +1,71 @@
+/*
+ * sony.h
+ *
+ * Copyright (c) 2002 Paul Campbell <paul@taniwha.com>
+ *
+ * Requires the Qt widget libraries, available at no cost at
+ * http://www.troll.no/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef __SONYCONFIG_H__
+#define __SONYCONFIG_H__
+
+#include <kcmodule.h>
+#include <qstring.h>
+
+class QWidget;
+class QSpinBox;
+class KConfig;
+class QCheckBox;
+class QSlider;
+class KIconLoader;
+class KIconButton;
+class QPushButton;
+
+
+class SonyConfig : public KCModule
+{
+ Q_OBJECT
+public:
+ SonyConfig( QWidget *parent=0, const char* name=0);
+ ~SonyConfig( );
+
+ void save( void );
+ void load();
+ void load(bool useDefaults);
+ void defaults();
+
+ virtual QString quickHelp() const;
+
+private slots:
+
+ void configChanged();
+ void slotStartMonitor();
+ void setupHelper();
+
+private:
+ KConfig *config;
+
+ QCheckBox *enableScrollBar;
+ bool enablescrollbar;
+ QCheckBox *enableMiddleEmulation;
+ bool middleemulation;
+};
+
+#endif
+
diff --git a/klaptopdaemon/thinkpad_common.h b/klaptopdaemon/thinkpad_common.h
new file mode 100644
index 0000000..c347e06
--- /dev/null
+++ b/klaptopdaemon/thinkpad_common.h
@@ -0,0 +1,127 @@
+
+/*********************************************************************
+ *
+ * Filename: thinkpad_common.h
+ * Description: stuff required by the "thinkpad" drivers and
+ * by programs accessing them
+ * Author: Thomas Hood
+ * Created: 19 July 1999
+ *
+ * Please report bugs to the author ASAP.
+ *
+ * Copyright (c) 1999 J.D. Thomas Hood, All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * To receive a copy of the GNU General Public License, please write
+ * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ ********************************************************************/
+
+#ifndef __THINKPAD_COMMON_H__
+#define __THINKPAD_COMMON_H__
+
+#include <config.h>
+#include <sys/types.h>
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+/* All module (etc.) names should be no longer than this: */
+#define LEN_NAME_MAX 80
+
+/* All version strings should be no longer than this: */
+#define LEN_VERSION_MAX 30
+
+/****** macros ******/
+
+#ifdef DEBUG_IOPARM
+#define DEBUG_PRINT_OUTPARMS( ioparmThe ) { \
+ printf( "bRc: 0x%x\n", ioparmThe.out.bRc ); \
+ printf( "bSubRc: 0x%x\n", ioparmThe.out.bSubRc ); \
+ printf( "wParm1: 0x%x\n", ioparmThe.out.wParm1 ); \
+ printf( "wParm2: 0x%x\n", ioparmThe.out.wParm2 ); \
+ printf( "wParm3: 0x%x\n", ioparmThe.out.wParm3 ); \
+ printf( "dwParm4: 0x%lx\n", (unsigned long) ioparmThe.out.dwParm4 ); \
+ printf( "dwParm5: 0x%lx\n", (unsigned long) ioparmThe.out.dwParm5 ); \
+}
+#define DEBUG_PRINT_INPARMS( ioparmThe ) { \
+ printf( "bFunc: 0x%x\n", ioparmThe.in.bFunc ); \
+ printf( "bSubFunc: 0x%x\n", ioparmThe.in.bSubFunc ); \
+ printf( "wParm1: 0x%x\n", ioparmThe.in.wParm1 ); \
+ printf( "wParm2: 0x%x\n", ioparmThe.in.wParm2 ); \
+ printf( "wParm3: 0x%x\n", ioparmThe.in.wParm3 ); \
+ printf( "dwParm4: 0x%lx\n", (unsigned long) ioparmThe.in.dwParm4 ); \
+ printf( "dwParm5: 0x%lx\n", (unsigned long) ioparmThe.in.dwParm5 ); \
+}
+#else
+#define DEBUG_PRINT_OUTPARMS( ioparmThe )
+#define DEBUG_PRINT_INPARMS( ioparmThe )
+#endif
+
+
+/****** types ******/
+typedef uint8_t byte;
+typedef uint16_t word;
+typedef uint32_t dword;
+typedef char flag_t;
+typedef byte bcd8_t;
+
+/*** ioctl commands ***/
+
+/*#include "thinkpad.h" */
+#include "smapi.h"
+/*#include "superio.h" */
+/*#include "rtcmosram.h" */
+/*#include "thinkpadpm.h" */
+
+#define MAGIC_THINKPAD_IOCTL ('(')
+#define IOCTL_THINKPAD_GETVER _IOR (MAGIC_THINKPAD_IOCTL,0x1,thinkpad_ioparm_t)
+#define IOCTL_THINKPAD_ENABLE _IOWR(MAGIC_THINKPAD_IOCTL,0x2,thinkpad_ioparm_t)
+#define IOCTL_THINKPAD_DISABLE _IOWR(MAGIC_THINKPAD_IOCTL,0x3,thinkpad_ioparm_t)
+#define IOCTL_SMAPI_REQUEST _IOWR(MAGIC_THINKPAD_IOCTL,0x10,smapi_ioparm_t)
+#define IOCTL_SUPERIO_REQUEST _IOWR(MAGIC_THINKPAD_IOCTL,0x11,superio_ioparm_t)
+#define IOCTL_RTCMOSRAM_REQUEST _IOWR(MAGIC_THINKPAD_IOCTL,0x12,rtcmosram_ioparm_t)
+#define IOCTL_THINKPADPM_REQUEST _IOWR(MAGIC_THINKPAD_IOCTL,0x20,thinkpadpm_ioparm_t)
+
+/****** return values ******/
+
+/* 0 as a return value always means OK */
+
+/*
+ * We use the following standard UNIX errno's, defined in <asm/errno.h>
+ * EFAULT memory error
+ * EBUSY device is already open
+ * EINVAL function code not recognized
+ * ENOTTY ioctl code not recognized
+ * EACCESS inadequate permission to perform action
+ *
+ * We use the following standard errnos under names more descriptive
+ * of our circumstances. Remember that the ioctl handler in the
+ * driver returns the negatives of these, but they turn up positive
+ * in user space in errno after an ioctl() call. Our convention
+ * for ioctl_blah() wrapper functions is to return the errno as a
+ * negative number.
+ */
+#define ETHINKPAD_PROGRAMMING (1024)
+#define ETHINKPAD_HW_NOT_FOUND (1025)
+#define ETHINKPAD_MODULE_DISABLED (1026)
+#define ETHINKPAD_MODULE_NOT_FOUND (1027)
+#define ETHINKPAD_SUBDRIVER (1028)
+
+/*
+ * Subdriver error codes are returned in the parameter block
+ * and errno is set to THINKPAD_SUBDRIVER
+ *
+ */
+
+#endif /* __THINKPAD_COMMON_H__ */
diff --git a/klaptopdaemon/version.h b/klaptopdaemon/version.h
new file mode 100644
index 0000000..aa0cdd4
--- /dev/null
+++ b/klaptopdaemon/version.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2002 Paul Campbell <paul@taniwha.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#define LAPTOP_VERSION "1.4"
diff --git a/klaptopdaemon/wake_laptop.cpp b/klaptopdaemon/wake_laptop.cpp
new file mode 100644
index 0000000..6b2a2b9
--- /dev/null
+++ b/klaptopdaemon/wake_laptop.cpp
@@ -0,0 +1,39 @@
+/*
+ * wake_laptop.cpp
+ * Copyright (C) 2003 Paul Campbell <paul@taniwha.com>
+ *
+ * send restart message to laptop daemon thru kded so that the daemon
+ * gets started if required
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <kprocess.h>
+#include <kconfig.h>
+#include <kdatastream.h>
+#include <dcopclient.h>
+#include <kapplication.h>
+
+KDE_EXPORT void
+wake_laptop_daemon()
+{
+ DCOPClient *dclient = kapp->dcopClient();
+ if (!dclient || (!dclient->isAttached() && !dclient->attach()))
+ return;
+
+ QByteArray data;
+ QDataStream arg( data, IO_WriteOnly );
+ (void) dclient->send( "kded", "klaptopdaemon", "restart()", data );
+}
diff --git a/klaptopdaemon/warning.cpp b/klaptopdaemon/warning.cpp
new file mode 100644
index 0000000..29944e0
--- /dev/null
+++ b/klaptopdaemon/warning.cpp
@@ -0,0 +1,602 @@
+/*
+ * warning.cpp
+ *
+ * Copyright (c) 1999 Paul Campbell <paul@taniwha.com>
+ *
+ * Requires the Qt widget libraries, available at no cost at
+ * http://www.troll.no/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "warning.h"
+#include "portable.h"
+#include "version.h"
+
+#include <klocale.h>
+#include <kfiledialog.h>
+#include <kmessagebox.h>
+#include <kconfig.h>
+#include <kurlrequester.h>
+#include <kapplication.h>
+#include <kcombobox.h>
+
+#include <qlayout.h>
+#include <qcheckbox.h>
+#include <qspinbox.h>
+#include <qslider.h>
+#include <qhbox.h>
+#include <qvbuttongroup.h>
+#include <qradiobutton.h>
+#include <qtooltip.h>
+
+extern void wake_laptop_daemon();
+
+WarningConfig::WarningConfig (int t, QWidget * parent, const char *name)
+ : KCModule(parent, name),
+ checkSuspend(0),
+ checkStandby(0),
+ checkHibernate(0)
+{
+ KGlobal::locale()->insertCatalogue("klaptopdaemon"); // For translation of klaptopdaemon messages
+
+ type = t;
+ apm = laptop_portable::has_power_management();
+ config = new KConfig("kcmlaptoprc");
+
+ my_load(0);
+
+ if (!apm) {
+ QVBoxLayout *top_layout = new QVBoxLayout( this, KDialog::marginHint(),
+ KDialog::spacingHint() );
+
+ KActiveLabel* explain = laptop_portable::no_power_management_explanation(this);
+ top_layout->addWidget(explain, 0);
+
+ top_layout->addStretch(1);
+ } else {
+ QGridLayout *grid = new QGridLayout( this, 11, 2, /* rows x cols */
+ KDialog::marginHint(),
+ KDialog::spacingHint() );
+ grid->setColStretch( 1, 1 );
+
+ int curRow = 0;
+ // setup the trigger stuff:
+ if (type) {
+ checkCriticalTime = new QCheckBox( i18n("Critical &trigger:"), this );
+ checkCriticalPercent = new QCheckBox( i18n("Critical &trigger:"), this );
+ editCriticalTime = new QSpinBox(1, 60*24, 1, this);
+ editCriticalTime->setSuffix(i18n("keep short, unit in spinbox", "min"));
+ QToolTip::add(editCriticalTime, i18n("When this amount of battery life is left the actions below will be triggered"));
+ editCriticalPercent = new QSpinBox(1, 100, 1, this);
+ editCriticalPercent->setSuffix(i18n("keep short, unit in spinbox", "%"));
+ QToolTip::add(editCriticalPercent, i18n("When this amount of battery life is left the actions below will be triggered"));
+ grid->addWidget(checkCriticalTime, curRow, 0);
+ grid->addWidget(editCriticalTime, curRow++, Qt::AlignLeft);
+ grid->addWidget(checkCriticalPercent, curRow, 0);
+ grid->addWidget(editCriticalPercent, curRow++, Qt::AlignLeft);
+
+ connect(editCriticalTime, SIGNAL(valueChanged(int)), this, SLOT(configChanged()));
+ connect(editCriticalPercent, SIGNAL(valueChanged(int)), this, SLOT(configChanged()));
+ connect(checkCriticalTime, SIGNAL(toggled(bool)), this, SLOT(configChanged()));
+ connect(checkCriticalPercent, SIGNAL(toggled(bool)), this, SLOT(configChanged()));
+ connect(checkCriticalTime, SIGNAL(toggled(bool)), this, SLOT(checkCriticalTimeChanged(bool)));
+ connect(checkCriticalPercent, SIGNAL(toggled(bool)), this, SLOT(checkCriticalPercentChanged(bool)));
+ } else {
+ checkLowTime = new QCheckBox( i18n("Low &trigger:"), this );
+ checkLowPercent = new QCheckBox( i18n("Low &trigger:"), this );
+ editLowTime = new QSpinBox(1, 60*24, 1, this);
+ editLowTime->setSuffix(i18n("keep short, unit in spinbox", "min"));
+ QToolTip::add(editLowTime, i18n("When this amount of battery life is left the actions below will be triggered"));
+ editLowPercent = new QSpinBox(1, 100, 1, this);
+ editLowPercent->setSuffix(i18n("keep short, unit in spinbox", "%"));
+ QToolTip::add(editLowPercent, i18n("When this amount of battery life is left the actions below will be triggered"));
+ grid->addWidget(checkLowTime, curRow, 0);
+ grid->addWidget(editLowTime, curRow++, Qt::AlignLeft);
+ grid->addWidget(checkLowPercent, curRow, 0);
+ grid->addWidget(editLowPercent, curRow++, Qt::AlignLeft);
+
+ connect(editLowTime, SIGNAL(valueChanged(int)), this, SLOT(configChanged()));
+ connect(editLowPercent, SIGNAL(valueChanged(int)), this, SLOT(configChanged()));
+ connect(checkLowTime, SIGNAL(toggled(bool)), this, SLOT(configChanged()));
+ connect(checkLowPercent, SIGNAL(toggled(bool)), this, SLOT(configChanged()));
+ connect(checkLowTime, SIGNAL(toggled(bool)), this, SLOT(checkLowTimeChanged(bool)));
+ connect(checkLowPercent, SIGNAL(toggled(bool)), this, SLOT(checkLowPercentChanged(bool)));
+ }
+
+
+ // setup the Run Command stuff
+ checkRunCommand = new QCheckBox(i18n("Run &command:"), this);
+ grid->addWidget(checkRunCommand, curRow, 0);
+
+ editRunCommand = new KURLRequester( this );
+ editRunCommand->setEnabled(false);
+ connect( checkRunCommand, SIGNAL(toggled(bool)),
+ editRunCommand, SLOT(setEnabled(bool)) );
+ connect( checkRunCommand, SIGNAL(clicked()),
+ this, SLOT(configChanged()) );
+ connect( editRunCommand, SIGNAL(textChanged(const QString&)),
+ this, SLOT(configChanged()) );
+ grid->addWidget(editRunCommand, curRow++, 1);
+ QToolTip::add( editRunCommand, i18n( "This command will be run when the battery gets low" ) );
+
+ // setup the Play Sound stuff
+ checkPlaySound = new QCheckBox(i18n("&Play sound:"), this);
+ grid->addWidget(checkPlaySound, curRow, 0);
+
+ editPlaySound = new KURLRequester( this );
+ editPlaySound->setEnabled(false);
+ connect( checkPlaySound, SIGNAL(toggled(bool)),
+ editPlaySound, SLOT(setEnabled(bool)) );
+ connect( checkPlaySound, SIGNAL(clicked()),
+ this, SLOT(configChanged()) );
+ connect( editPlaySound, SIGNAL(textChanged(const QString&)),
+ this, SLOT(configChanged()) );
+ grid->addWidget(editPlaySound, curRow++, 1);
+ QToolTip::add( editPlaySound, i18n( "This sound will play when the battery gets low" ) );
+
+ // setup the System Sound stuff
+ checkBeep = new QCheckBox(i18n("System &beep"), this);
+ grid->addWidget(checkBeep, curRow++, 0);
+ connect(checkBeep, SIGNAL(clicked()), this, SLOT(configChanged()));
+ QToolTip::add( checkBeep, i18n( "The system will beep if this is enabled" ) );
+
+ checkNotify = new QCheckBox(i18n("&Notify"), this);
+ grid->addWidget(checkNotify, curRow++, 0);
+ connect(checkNotify, SIGNAL(clicked()), this, SLOT(configChanged()));
+
+ int can_suspend = laptop_portable::has_suspend();
+ int can_standby = laptop_portable::has_standby();
+ int can_hibernate = laptop_portable::has_hibernation();
+ int can_brightness = laptop_portable::has_brightness();
+
+ if (can_brightness) {
+ checkBrightness = new QCheckBox(i18n("Panel b&rightness"), this);
+ checkBrightness->setMinimumSize(checkBrightness->sizeHint());
+ QToolTip::add( checkBrightness, i18n( "If enabled the back panel brightness will change" ) );
+ grid->addWidget(checkBrightness, curRow, 0);
+ connect(checkBrightness, SIGNAL(toggled(bool)), this, SLOT(brightness_changed(bool)));
+ QHBoxLayout *v = new QHBoxLayout();
+ v->addWidget(new QLabel("-", this));
+ valueBrightness = new QSlider(0, 255, 16, 160, Qt::Horizontal, this);
+ QToolTip::add( valueBrightness, i18n( "How bright or dim to make the back panel" ) );
+ valueBrightness->setMaximumWidth(70);
+ v->addWidget(valueBrightness);
+ v->addWidget(new QLabel("+", this));
+ v->addStretch(1);
+ grid->addLayout(v, curRow, 1);
+ valueBrightness->setEnabled(0);
+ connect(valueBrightness, SIGNAL(valueChanged(int)), this, SLOT(configChanged()));
+ ++curRow;
+ } else {
+ checkBrightness = 0;
+ valueBrightness = 0;
+ }
+ QStringList performance_list;
+ int current_performance;
+ bool *active_list;
+ bool has_performance = laptop_portable::get_system_performance(0, current_performance, performance_list, active_list);
+ if (has_performance) {
+ performance = new QCheckBox(i18n("System performance"), this);
+ QToolTip::add( performance, i18n( "If enabled the laptop's power performance profile will change" ) );
+ grid->addWidget(performance, curRow, 0);
+ connect (performance, SIGNAL(toggled(bool)), this, SLOT(performance_changed(bool)));
+
+ QHBoxLayout *v = new QHBoxLayout();
+ performance_val = new KComboBox(0, this);
+ performance_val->insertStringList(performance_list);
+ performance_val->setEnabled(0);
+ connect (performance_val, SIGNAL(activated(int)), this, SLOT(configChanged()));
+ QToolTip::add( performance_val, i18n( "The performance profile to change to" ) );
+ v->addWidget(performance_val);
+ v->addStretch(1);
+ grid->addLayout(v, curRow, 1);
+ ++curRow;
+ } else {
+ performance = 0;
+ performance_val = 0;
+ }
+ QStringList throttle_list;
+ int current_throttle;
+ bool has_throttle = laptop_portable::get_system_throttling(0, current_throttle, throttle_list, active_list);
+ if (has_throttle) {
+ throttle = new QCheckBox(i18n("CPU throttling"), this);
+ QToolTip::add( throttle, i18n( "If enabled the CPU performance will be throttled" ) );
+ grid->addWidget(throttle, curRow, 0);
+ connect (throttle, SIGNAL(toggled(bool)), this, SLOT(throttle_changed(bool)));
+
+ QHBoxLayout *v = new QHBoxLayout();
+ throttle_val = new KComboBox(0, this);
+ throttle_val->insertStringList(throttle_list);
+ throttle_val->setEnabled(0);
+ connect (throttle_val, SIGNAL(activated(int)), this, SLOT(configChanged()));
+ QToolTip::add( throttle_val, i18n( "How much to throttle the CPU performance by" ) );
+ v->addWidget(throttle_val);
+ v->addStretch(1);
+ grid->addLayout(v, curRow, 1);
+ ++curRow;
+ } else {
+ throttle = 0;
+ throttle_val = 0;
+ }
+
+
+
+ QVButtonGroup *b = new QVButtonGroup(i18n("System State Change"), this);
+ QToolTip::add( b, i18n( "You may choose one of the following to occur when the battery gets low" ) );
+ b->layout()->setSpacing( KDialog::spacingHint() );
+ if (can_standby) {
+ checkStandby = new QRadioButton(i18n("Standb&y"), b);
+ QToolTip::add( checkStandby, i18n( "Move the system into the standby state - a temporary lower power state" ) );
+ checkStandby->setMinimumSize(checkStandby->sizeHint());
+ connect(checkStandby, SIGNAL(clicked()), this, SLOT(configChanged()));
+ }
+ if (can_suspend) {
+ checkSuspend = new QRadioButton(i18n("&Suspend"), b);
+ QToolTip::add( checkSuspend, i18n( "Move the system into the suspend state - also known as 'save-to-ram'" ) );
+ checkSuspend->setMinimumSize(checkSuspend->sizeHint());
+ connect(checkSuspend, SIGNAL(clicked()), this, SLOT(configChanged()));
+ }
+ if (can_hibernate) {
+ checkHibernate = new QRadioButton(i18n("H&ibernate"), b);
+ QToolTip::add( checkHibernate, i18n( "Move the system into the hibernate state - also known as 'save-to-disk'" ) );
+ checkHibernate->setMinimumSize(checkHibernate->sizeHint());
+ connect(checkHibernate, SIGNAL(clicked()), this, SLOT(configChanged()));
+ }
+ // setup the logout option
+ checkLogout = new QRadioButton(i18n("&Logout"), b);
+ connect(checkLogout, SIGNAL(clicked()), this, SLOT(configChanged()));
+ // setup the shutdown option
+ checkShutdown = new QRadioButton(i18n("System power off"), b);
+ QToolTip::add( checkShutdown, i18n( "Power the laptop off" ) );
+ connect(checkShutdown, SIGNAL(clicked()), this, SLOT(configChanged()));
+
+ checkNone = new QRadioButton(i18n("&None"), b);
+ connect(checkNone, SIGNAL(clicked()), this, SLOT(configChanged()));
+
+ grid->addMultiCellWidget(b, curRow, curRow, 0, 1, Qt::AlignLeft|Qt::AlignTop);
+ curRow++;
+
+
+ QLabel* explain;
+ if (type) {
+ explain = new QLabel(i18n("This panel controls how and when you receive warnings that your battery power is going to run out VERY VERY soon."), this);
+ } else {
+ explain = new QLabel(i18n("This panel controls how and when you receive warnings that your battery power is about to run out"), this);
+ }
+ explain->setAlignment( Qt::WordBreak );
+ grid->addMultiCellWidget(explain, curRow, curRow, 0, 1);
+ ++curRow;
+
+ if (!can_suspend && !can_standby && !can_hibernate) {
+ // display help text:
+ QLabel* note = laptop_portable::how_to_do_suspend_resume(this);
+ grid->addMultiCellWidget(note, curRow, curRow, 0, 1);
+ ++curRow;
+ }
+ grid->setRowStretch(curRow++, 1);
+
+ grid->addWidget(new QLabel( i18n("Version: %1").arg(LAPTOP_VERSION), this),
+ curRow, 1, Qt::AlignRight);
+
+ }
+ my_load(1);
+}
+
+WarningConfig::~WarningConfig()
+{
+ delete config;
+}
+
+void WarningConfig::brightness_changed(bool v)
+{
+ valueBrightness->setEnabled(v);
+ configChanged();
+}
+
+void WarningConfig::throttle_changed(bool v)
+{
+ throttle_val->setEnabled(v);
+ configChanged();
+}
+
+void WarningConfig::performance_changed(bool v)
+{
+ performance_val->setEnabled(v);
+ configChanged();
+}
+
+void WarningConfig::checkLowTimeChanged(bool state)
+{
+ checkLowPercent->setChecked(state ? false : true);
+ editLowPercent->setEnabled(state ? false : true);
+}
+
+void WarningConfig::checkLowPercentChanged(bool state)
+{
+ checkLowTime->setChecked(state ? false : true);
+ editLowTime->setEnabled(state ? false : true);
+}
+
+void WarningConfig::checkCriticalTimeChanged(bool state)
+{
+ checkCriticalPercent->setChecked(state ? false : true);
+ editCriticalPercent->setEnabled(state ? false : true);
+}
+
+void WarningConfig::checkCriticalPercentChanged(bool state)
+{
+ checkCriticalTime->setChecked(state ? false: true);
+ editCriticalTime->setEnabled(state ? false : true);
+}
+
+
+void WarningConfig::save()
+{
+ if (apm) {
+ runcommand = checkRunCommand->isChecked();
+ playsound = checkPlaySound->isChecked();
+ logout = checkLogout->isChecked();
+ shutdown = checkShutdown->isChecked();
+ beep = checkBeep->isChecked();
+ notify = checkNotify->isChecked();
+ do_suspend = (checkSuspend? checkSuspend->isChecked() : false);
+ do_standby = (checkStandby? checkStandby->isChecked() : false);
+ do_hibernate = (checkHibernate? checkHibernate->isChecked() : false);
+ do_brightness = (checkBrightness? checkBrightness->isChecked() : false);
+ val_brightness = (valueBrightness? valueBrightness->value() : 255);
+ do_performance = (performance? performance->isChecked() : false);
+ val_performance = (performance_val? performance_val->currentText() : "");
+ do_throttle = (throttle? throttle->isChecked() : false);
+ val_throttle = (throttle_val? throttle_val->currentText() : "");
+ runcommand_val = editRunCommand->url();
+ if (type) {
+ time_based_action_critical = checkCriticalTime->isChecked();
+ critical_val_time = editCriticalTime->value();
+ critical_val_percent = editCriticalPercent->value();
+ } else {
+ time_based_action_low = checkLowTime->isChecked();
+ low_val_time = editLowTime->value();
+ low_val_percent = editLowPercent->value();
+ }
+
+ sound_val = editPlaySound->url();
+ }
+ config->setGroup((type?"BatteryCritical":"BatteryLow"));
+
+ if (config->group() == "BatteryLow") {
+ config->writeEntry("TimeBasedAction", time_based_action_low);
+ config->writeEntry("LowValTime", low_val_time);
+ config->writeEntry("LowValPercent", low_val_percent);
+ } else {
+ config->writeEntry("TimeBasedAction", time_based_action_critical);
+ config->writeEntry("CriticalValTime", critical_val_time);
+ config->writeEntry("CriticalValPercent", critical_val_percent);
+ }
+ config->writeEntry("RunCommand", runcommand);
+ config->writeEntry("PlaySound", playsound);
+ config->writeEntry("Logout", logout);
+ config->writeEntry("Shutdown", shutdown);
+ config->writeEntry("SystemBeep", beep);
+ config->writeEntry("Notify", notify);
+ config->writeEntry("Suspend", do_suspend);
+ config->writeEntry("Standby", do_standby);
+ config->writeEntry("Hibernate", do_hibernate);
+ config->writeEntry("Brightness", do_brightness);
+ config->writeEntry("BrightnessValue", val_brightness);
+ config->writeEntry("Performance", do_performance);
+ config->writeEntry("PerformanceValue", val_performance);
+ config->writeEntry("Throttle", do_throttle);
+ config->writeEntry("ThrottleValue", val_throttle);
+ config->writeEntry("RunCommandPath", runcommand_val);
+ config->writeEntry("PlaySoundPath", sound_val);
+ config->sync();
+ wake_laptop_daemon();
+}
+
+void WarningConfig::load()
+{
+ load( false );
+}
+
+void WarningConfig::load(bool useDefaults)
+{
+ if (config == NULL)
+ return;
+ my_load(0, useDefaults);
+ my_load(1, useDefaults);
+}
+
+void WarningConfig::my_load(int x, bool useDefaults )
+{
+ config->setReadDefaults( useDefaults );
+
+ // open the config file
+ if (!x) {
+ config->setGroup((type?"BatteryCritical":"BatteryLow"));
+
+ if (config->group() == "BatteryLow") {
+ time_based_action_low = config->readBoolEntry("TimeBasedAction", true);
+ low_val_time = config->readNumEntry("LowValTime", 15);
+ low_val_percent = config->readNumEntry("LowValPercent", 7);
+ } else {
+ time_based_action_critical = config->readBoolEntry("TimeBasedAction", true);
+ critical_val_time = config->readNumEntry("CriticalValTime", 5);
+ critical_val_percent = config->readNumEntry("CriticalValPercent", 3);
+ }
+ runcommand = config->readBoolEntry("RunCommand", false);
+ playsound = config->readBoolEntry("PlaySound", false);
+ logout = config->readBoolEntry("Logout", false);
+ shutdown = config->readBoolEntry("Shutdown", false);
+ beep = config->readBoolEntry("SystemBeep", true);
+ notify = config->readBoolEntry("Notify", (type && checkSuspend ? false : true));
+ do_suspend = config->readBoolEntry("Suspend", (type && checkSuspend ? true :false));
+ do_standby = config->readBoolEntry("Standby", false);
+ do_hibernate = config->readBoolEntry("Hibernate", false);
+ do_brightness = config->readBoolEntry("Brightness", false);
+ val_brightness = config->readNumEntry("BrightnessValue", 255);
+ do_performance = config->readBoolEntry("Performance", false);
+ val_performance = config->readEntry("PerformanceValue", "");
+ do_throttle = config->readBoolEntry("Throttle", false);
+ val_throttle = config->readEntry("ThrottleValue", "");
+ runcommand_val = config->readEntry("RunCommandPath");
+ sound_val = config->readEntry("PlaySoundPath");
+ have_time = config->readNumEntry("HaveTime", 2);
+ if (laptop_portable::has_power_management())
+ have_time = laptop_portable::has_battery_time();
+
+ } else
+ if (apm) {
+ checkRunCommand->setChecked(runcommand);
+ checkPlaySound->setChecked(playsound);
+ checkBeep->setChecked(beep);
+ if (checkBrightness)
+ checkBrightness->setChecked(do_brightness);
+ if (valueBrightness) {
+ valueBrightness->setValue(val_brightness);
+ valueBrightness->setEnabled(do_brightness);
+ }
+ if (performance)
+ performance->setChecked(do_performance);
+ if (performance_val) {
+ int ind = 0;
+ for (int i = 0; i < performance_val->count(); i++)
+ if (performance_val->text(i) == val_performance) {
+ ind = i;
+ break;
+ }
+ performance_val->setCurrentItem(ind);
+ performance_val->setEnabled(do_performance);
+ }
+ if (throttle)
+ throttle->setChecked(do_throttle);
+ if (throttle_val) {
+ int ind = 0;
+ for (int i = 0; i < throttle_val->count(); i++)
+ if (throttle_val->text(i) == val_throttle) {
+ ind = i;
+ break;
+ }
+ throttle_val->setCurrentItem(ind);
+ throttle_val->setEnabled(do_throttle);
+ }
+
+ checkLogout->setChecked(logout);
+ checkNotify->setChecked(notify);
+ checkShutdown->setChecked(shutdown);
+ if (checkHibernate) {
+ checkHibernate->setChecked(do_hibernate);
+ } else {
+ do_hibernate = 0;
+ }
+ if (checkStandby) {
+ checkStandby->setChecked(do_standby);
+ } else {
+ do_standby = 0;
+ }
+ if (checkSuspend) {
+ checkSuspend->setChecked(do_suspend);
+ } else {
+ do_suspend = 0;
+ }
+ checkNone->setChecked(!do_suspend&!do_standby&!do_hibernate&!logout&!shutdown);
+ editRunCommand->setURL(runcommand_val);
+
+ if(type) {
+ checkCriticalTime->setChecked(time_based_action_critical ? true : false);
+ editCriticalTime->setValue(critical_val_time);
+ checkCriticalPercent->setChecked(time_based_action_critical ? false : true);
+ editCriticalPercent->setValue(critical_val_percent);
+ } else {
+ checkLowTime->setChecked(time_based_action_low ? true : false);
+ editLowTime->setValue(low_val_time);
+ checkLowPercent->setChecked(time_based_action_low ? false : true);
+ editLowPercent->setValue(low_val_percent);
+ }
+
+ editPlaySound->setURL(sound_val);
+ }
+ emit changed(useDefaults);
+}
+
+void WarningConfig::defaults()
+{
+ load( true );
+}
+
+
+void WarningConfig::configChanged()
+{
+ emit changed(true);
+}
+
+
+#if 0
+void WarningConfig::enableRunCommand(bool enable)
+{
+ editRunCommand->setEnabled(enable);
+ buttonBrowseRunCommand->setEnabled(enable);
+ configChanged();
+}
+
+void WarningConfig::enablePlaySound(bool enable)
+{
+ editPlaySound->setEnabled(enable);
+ buttonBrowsePlaySound->setEnabled(enable);
+ configChanged();
+}
+
+void WarningConfig::browseRunCommand()
+{
+ KURL url = KFileDialog::getOpenURL(QString::null, QString::null, this );
+
+ if( url.isEmpty() )
+ return;
+
+ if( !url.isLocalFile() )
+ {
+ KMessageBox::sorry( 0L, i18n( "Only local files are currently supported." ) );
+ return;
+ }
+
+ editRunCommand->setText( url.path() );
+ configChanged();
+}
+
+void WarningConfig::browsePlaySound()
+{
+ KURL url = KFileDialog::getOpenURL(QString::null, QString::null, this );
+
+ if( url.isEmpty() )
+ return;
+
+ if( !url.isLocalFile() )
+ {
+ KMessageBox::sorry( 0L, i18n( "Only local files are currently supported." ) );
+ return;
+ }
+
+ editPlaySound->setText( url.path() );
+ configChanged();
+}
+#endif
+
+QString WarningConfig::quickHelp() const
+{
+ return i18n("<h1>Low battery Warning</h1>This module allows you to "
+ "set an alarm in case your battery's charge is about to run out.");
+}
+
+#include "warning.moc"
diff --git a/klaptopdaemon/warning.h b/klaptopdaemon/warning.h
new file mode 100644
index 0000000..3eb1b04
--- /dev/null
+++ b/klaptopdaemon/warning.h
@@ -0,0 +1,106 @@
+/*
+ * warning.h
+ *
+ * Copyright (c) 1999 Paul Campbell <paul@taniwha.com>
+ * Copyright (c) 2002 Marc Mutz <mutz@kde.org>
+ *
+ * Requires the Qt widget libraries, available at no cost at
+ * http://www.troll.no/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef __WARNINGCONFIG_H__
+#define __WARNINGCONFIG_H__
+
+#include <kcmodule.h>
+#include <qstring.h>
+
+class QWidget;
+class KConfig;
+class KURLRequester;
+class QCheckBox;
+class QRadioButton;
+class QSpinBox;
+class QSlider;
+class KComboBox;
+
+class WarningConfig : public KCModule
+{
+ Q_OBJECT
+public:
+ WarningConfig(int x, QWidget *parent=0, const char* name=0);
+ ~WarningConfig();
+ void save( void );
+ void load();
+ void load(bool useDefaults);
+ void defaults();
+
+ virtual QString quickHelp() const;
+
+private slots:
+ void configChanged();
+ void brightness_changed(bool v);
+ void throttle_changed(bool v);
+ void performance_changed(bool v);
+ void checkLowTimeChanged(bool state);
+ void checkLowPercentChanged(bool state);
+ void checkCriticalTimeChanged(bool state);
+ void checkCriticalPercentChanged(bool state);
+
+private:
+ void my_load(int x, bool useDefaults=false );
+
+ KConfig *config;
+
+ KURLRequester* editRunCommand;
+ KURLRequester* editPlaySound;
+ QCheckBox* checkLowTime;
+ QCheckBox* checkLowPercent;
+ QCheckBox* checkCriticalTime;
+ QCheckBox* checkCriticalPercent;
+ QSpinBox* editLowTime;
+ QSpinBox* editLowPercent;
+ QSpinBox* editCriticalTime;
+ QSpinBox* editCriticalPercent;
+
+ QCheckBox *checkRunCommand;
+ QCheckBox *checkPlaySound;
+ QCheckBox *checkBeep;
+ QCheckBox *checkNotify;
+ QCheckBox *checkBrightness;
+ QSlider *valueBrightness;
+ QCheckBox *performance, *throttle;
+ KComboBox *performance_val, *throttle_val;
+ QRadioButton *checkNone;
+ QRadioButton *checkShutdown;
+ QRadioButton *checkLogout;
+ QRadioButton *checkSuspend;
+ QRadioButton *checkStandby;
+ QRadioButton *checkHibernate;
+
+ bool apm, runcommand, playsound, beep, notify, do_suspend, do_standby, do_hibernate, logout, shutdown, do_brightness;
+ bool do_performance, do_throttle;
+ bool time_based_action_low, time_based_action_critical;
+ QString val_performance, val_throttle;
+ int val_brightness;
+ QString runcommand_val, sound_val;
+ int low_val_time, low_val_percent, critical_val_time, critical_val_percent;
+ int have_time, type;
+};
+
+#endif
+
diff --git a/klaptopdaemon/xautolock.cc b/klaptopdaemon/xautolock.cc
new file mode 100644
index 0000000..4f856e1
--- /dev/null
+++ b/klaptopdaemon/xautolock.cc
@@ -0,0 +1,277 @@
+//----------------------------------------------------------------------------
+//
+// This file is part of the KDE project
+//
+// Copyright (c) 1999 Martin R. Jones <mjones@kde.org>
+// Copyright (c) 2003 Lubos Lunak <l.lunak@kde.org>
+//
+// KDE screensaver engine
+//
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "xautolock.h"
+#include "xautolock.moc"
+
+#include <kapplication.h>
+#include <kdebug.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <ctime>
+#include "xautolock_c.h"
+
+#ifdef HAVE_DPMS
+extern "C" {
+#include <X11/Xmd.h>
+#ifndef Bool
+#define Bool BOOL
+#endif
+#include <X11/extensions/dpms.h>
+
+#ifndef HAVE_DPMSINFO_PROTO
+Status DPMSInfo ( Display *, CARD16 *, BOOL * );
+#endif
+}
+#endif
+
+int xautolock_useXidle = 0;
+int xautolock_useMit = 0;
+xautolock_corner_t xautolock_corners[ 4 ];
+
+static XAutoLock* self = NULL;
+
+static int catchFalseAlarms(Display *, XErrorEvent *)
+{
+ return 0;
+}
+
+//===========================================================================
+//
+// Detect user inactivity.
+// Named XAutoLock after the program that it is based on.
+//
+XAutoLock::XAutoLock()
+{
+ self = this;
+ int dummy = 0;
+ dummy = dummy; // shut up
+ xautolock_useXidle = 0;
+ xautolock_useMit = 0;
+#ifdef HAVE_XIDLE
+ useXidle = XidleQueryExtension( qt_xdisplay(), &dummy, &dummy );
+#endif
+#ifdef HAVE_XSCREENSAVER
+ if( !xautolock_useXidle )
+ xautolock_useMit = XScreenSaverQueryExtension( qt_xdisplay(), &dummy, &dummy );
+#endif
+ if( !xautolock_useXidle && !xautolock_useMit )
+ {
+ kapp->installX11EventFilter( this );
+ int (*oldHandler)(Display *, XErrorEvent *);
+ oldHandler = XSetErrorHandler(catchFalseAlarms);
+ XSync(qt_xdisplay(), False );
+ xautolock_initDiy( qt_xdisplay());
+ XSync(qt_xdisplay(), False );
+ XSetErrorHandler(oldHandler);
+ }
+
+ mTimeout = DEFAULT_TIMEOUT;
+ mDPMS = true;
+ resetTrigger();
+
+ time(&mLastTimeout);
+ mActive = false;
+
+ mTimerId = startTimer( CHECK_INTERVAL );
+
+}
+
+//---------------------------------------------------------------------------
+//
+// Destructor.
+//
+XAutoLock::~XAutoLock()
+{
+ self = NULL;
+}
+
+//---------------------------------------------------------------------------
+//
+// The time in seconds of continuous inactivity.
+//
+void XAutoLock::setTimeout(int t)
+{
+ mTimeout = t;
+ resetTrigger();
+}
+
+void XAutoLock::setDPMS(bool s)
+{
+ mDPMS = s;
+}
+
+//---------------------------------------------------------------------------
+//
+// Start watching Activity
+//
+void XAutoLock::start()
+{
+ resetTrigger();
+ time(&mLastTimeout);
+ mActive = true;
+}
+
+//---------------------------------------------------------------------------
+//
+// Stop watching Activity
+//
+void XAutoLock::stop()
+{
+ mActive = false;
+}
+
+//---------------------------------------------------------------------------
+//
+// Reset the trigger time.
+//
+void XAutoLock::resetTrigger()
+{
+ mTrigger = time(0) + mTimeout;
+}
+
+//---------------------------------------------------------------------------
+//
+// Move the trigger time in order to postpone (repeat) emitting of timeout().
+//
+void XAutoLock::postpone()
+{
+ mTrigger = time(0) + 60; // delay by 60sec
+}
+
+//---------------------------------------------------------------------------
+//
+// Set the remaining time to 't', if it's shorter than already set.
+//
+void XAutoLock::setTrigger( time_t t )
+{
+ if( t < mTrigger )
+ mTrigger = t;
+}
+
+//---------------------------------------------------------------------------
+//
+// Process new windows and check the mouse.
+//
+void XAutoLock::timerEvent(QTimerEvent *ev)
+{
+ if (ev->timerId() != mTimerId)
+ {
+ return;
+ }
+
+ int (*oldHandler)(Display *, XErrorEvent *) = NULL;
+ if( !xautolock_useXidle && !xautolock_useMit )
+ { // only the diy way needs special X handler
+ XSync( qt_xdisplay(), False );
+ oldHandler = XSetErrorHandler(catchFalseAlarms);
+ }
+
+ xautolock_processQueue();
+
+ time_t now = time(0);
+ if ((now > mLastTimeout && now - mLastTimeout > TIME_CHANGE_LIMIT) ||
+ (mLastTimeout > now && mLastTimeout - now > TIME_CHANGE_LIMIT+1))
+ {
+ /* the time has changed in one large jump. This could be because
+ the date was changed, or the machine was suspended. We'll just
+ reset the triger. */
+ resetTrigger();
+ }
+
+ mLastTimeout = now;
+
+ xautolock_queryIdleTime( qt_xdisplay());
+ xautolock_queryPointer( qt_xdisplay());
+
+ if( !xautolock_useXidle && !xautolock_useMit )
+ XSetErrorHandler(oldHandler);
+
+ bool activate = false;
+
+ //kdDebug() << now << " " << mTrigger << endl;
+ if (now >= mTrigger)
+ {
+ resetTrigger();
+ activate = true;
+ }
+
+#ifdef HAVE_DPMS
+ BOOL on;
+ CARD16 state;
+ DPMSInfo( qt_xdisplay(), &state, &on );
+
+ //kdDebug() << "DPMSInfo " << state << " " << on << endl;
+ // If DPMS is active, it makes XScreenSaverQueryInfo() report idle time
+ // that is always smaller than DPMS timeout (X bug I guess). So if DPMS
+ // saving is active, simply always activate our saving too, otherwise
+ // this could prevent locking from working.
+ if(state == DPMSModeStandby || state == DPMSModeSuspend || state == DPMSModeOff)
+ activate = true;
+ if(!on && mDPMS) {
+ activate = false;
+ resetTrigger();
+ }
+#endif
+
+#ifdef HAVE_XSCREENSAVER
+ static XScreenSaverInfo* mitInfo = 0;
+ if (!mitInfo) mitInfo = XScreenSaverAllocInfo ();
+ if (XScreenSaverQueryInfo (qt_xdisplay(), DefaultRootWindow (qt_xdisplay()), mitInfo)) {
+ //kdDebug() << "XScreenSaverQueryInfo " << mitInfo->state << " " << ScreenSaverDisabled << endl;
+ if (mitInfo->state == ScreenSaverDisabled)
+ activate = false;
+ }
+#endif
+
+ if(mActive && activate)
+ emit timeout();
+}
+
+bool XAutoLock::x11Event( XEvent* ev )
+{
+ xautolock_processEvent( ev );
+// don't futher process key events that were received only because XAutoLock wants them
+ if( ev->type == KeyPress && !ev->xkey.send_event
+ && !xautolock_useXidle && !xautolock_useMit
+ && !QWidget::find( ev->xkey.window ))
+ return true;
+ return false;
+}
+
+bool XAutoLock::ignoreWindow( WId w )
+{
+ if( w != qt_xrootwin() && QWidget::find( w ))
+ return true;
+ return false;
+}
+
+extern "C"
+void xautolock_resetTriggers()
+{
+ self->resetTrigger();
+}
+
+extern "C"
+void xautolock_setTrigger( time_t t )
+{
+ self->setTrigger( t );
+}
+
+extern "C"
+int xautolock_ignoreWindow( Window w )
+{
+ return self->ignoreWindow( w );
+}
diff --git a/klaptopdaemon/xautolock.h b/klaptopdaemon/xautolock.h
new file mode 100644
index 0000000..aa618f2
--- /dev/null
+++ b/klaptopdaemon/xautolock.h
@@ -0,0 +1,77 @@
+//===========================================================================
+//
+// This file is part of the KDE project
+//
+// Copyright (c) 1999 Martin R. Jones <mjones@kde.org>
+//
+
+#ifndef __XAUTOLOCK_H__
+#define __XAUTOLOCK_H__
+
+#include <qwidget.h>
+
+#include <X11/Xlib.h>
+
+//===========================================================================
+//
+// Detect user inactivity.
+// Named XAutoLock after the program that it is based on.
+//
+class XAutoLock : public QWidget
+{
+ Q_OBJECT
+public:
+ XAutoLock();
+ ~XAutoLock();
+
+ //-----------------------------------------------------------------------
+ //
+ // The time in seconds of continuous inactivity.
+ //
+ void setTimeout(int t);
+
+ void setDPMS(bool s);
+
+ //-----------------------------------------------------------------------
+ //
+ // Start watching Activity
+ //
+ void start();
+
+ //-----------------------------------------------------------------------
+ //
+ // Stop watching Activity
+ //
+ void stop();
+
+ //-----------------------------------------------------------------------
+ //
+ // Should be called only from a slot connected to the timeout() signal. Will
+ // result in the timeout() signal being emitted again with a delay (i.e. postponed).
+ //
+ void postpone();
+
+ // internal
+ void resetTrigger();
+ // internal
+ void setTrigger( time_t );
+ // internal
+ bool ignoreWindow( WId );
+
+signals:
+ void timeout();
+
+protected:
+ virtual void timerEvent(QTimerEvent *ev);
+ virtual bool x11Event( XEvent* );
+
+protected:
+ int mTimerId;
+ int mTimeout;
+ time_t mTrigger;
+ bool mActive;
+ time_t mLastTimeout;
+ bool mDPMS;
+};
+
+#endif
diff --git a/klaptopdaemon/xautolock_c.h b/klaptopdaemon/xautolock_c.h
new file mode 100644
index 0000000..a53ad93
--- /dev/null
+++ b/klaptopdaemon/xautolock_c.h
@@ -0,0 +1,76 @@
+/*****************************************************************************
+ *
+ * Authors: Michel Eyckmans (MCE) & Stefan De Troch (SDT)
+ *
+ * Content: This file is part of version 2.x of xautolock. It takes care
+ * of most OS dependencies, and defines the program's default
+ * settings.
+ *
+ * Please send bug reports etc. to eyckmans@imec.be.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Copyright 1990,1992-1999,2001-2002 by Stefan De Troch and Michel Eyckmans.
+ *
+ * Versions 2.0 and above of xautolock are available under version 2 of the
+ * GNU GPL. Earlier versions are available under other conditions. For more
+ * information, see the License file.
+ *
+ *****************************************************************************/
+
+#ifndef __xautolock_c_h
+#define __xautolock_c_h
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_XSCREENSAVER
+#define HasScreenSaver
+#include <X11/extensions/scrnsaver.h>
+#endif
+
+/* I'd first need to get my hands on this */
+#undef HAVE_XIDLE
+#undef HasXidle
+
+#define DEFAULT_TIMEOUT 600
+
+#define CHECK_INTERVAL 5000 /* ms */
+
+#define CREATION_DELAY 30 /* should be > 10 and
+ < min (45,(MIN_MINUTES*30)) */
+#define TIME_CHANGE_LIMIT 120 /* if the time changes by more
+ than x secs then we will
+ assume someone has changed
+ date or machine has suspended */
+
+#define cornerSize 5
+
+#define cornerDelay 5
+
+#define cornerRedelay 5
+
+typedef enum { ca_nothing, ca_dontLock, ca_forceLock } xautolock_corner_t;
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+void xautolock_processEvent( XEvent* ev );
+void xautolock_queryIdleTime( Display* d);
+void xautolock_processQueue( void );
+void xautolock_queryPointer (Display* d);
+void xautolock_initDiy (Display* d);
+void xautolock_resetTriggers( void );
+void xautolock_setTrigger( time_t );
+int xautolock_ignoreWindow( Window );
+extern int xautolock_useXidle;
+extern int xautolock_useMit;
+extern xautolock_corner_t xautolock_corners[ 4 ];
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/klaptopdaemon/xautolock_diy.c b/klaptopdaemon/xautolock_diy.c
new file mode 100644
index 0000000..b9df2f8
--- /dev/null
+++ b/klaptopdaemon/xautolock_diy.c
@@ -0,0 +1,289 @@
+/*****************************************************************************
+ *
+ * Authors: Michel Eyckmans (MCE) & Stefan De Troch (SDT)
+ *
+ * Content: This file is part of version 2.x of xautolock. It implements
+ * the stuff used when the program is not using a screen saver
+ * extension and thus has to use the good old "do it yourself"
+ * approach for detecting user activity.
+ *
+ * The basic idea is that we initially traverse the window tree,
+ * selecting SubstructureNotify on all windows and adding each
+ * window to a temporary list. About +- 30 seconds later, we
+ * scan this list, now asking for KeyPress events. The delay
+ * is needed in order to interfere as little as possible with
+ * the event propagation mechanism. Whenever a new window is
+ * created by an application, a similar process takes place.
+ *
+ * Please send bug reports etc. to eyckmans@imec.be.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Copyright 1990,1992-1999,2001-2002 by Stefan De Troch and Michel Eyckmans.
+ *
+ * Versions 2.0 and above of xautolock are available under version 2 of the
+ * GNU GPL. Earlier versions are available under other conditions. For more
+ * information, see the License file.
+ *
+ *****************************************************************************/
+
+#include <X11/Xlib.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "xautolock_c.h"
+
+static void selectEvents (Window window, Bool substructureOnly);
+
+/*
+ * Window queue management.
+ */
+typedef struct item
+{
+ Window window;
+ time_t creationtime;
+ struct item* next;
+} xautolock_anItem, *xautolock_item;
+
+static struct
+{
+ Display* display;
+ struct item* head;
+ struct item* tail;
+} queue;
+
+static void
+addToQueue (Window window)
+{
+ xautolock_item newItem = malloc(sizeof(xautolock_anItem));
+
+ newItem->window = window;
+ newItem->creationtime = time (0);
+ newItem->next = 0;
+
+ if (!queue.head) queue.head = newItem;
+ if ( queue.tail) queue.tail->next = newItem;
+
+ queue.tail = newItem;
+}
+
+static void
+processQueue (time_t age)
+{
+ if (queue.head)
+ {
+ time_t now = time (0);
+ xautolock_item current = queue.head;
+
+ while (current && current->creationtime + age < now)
+ {
+ selectEvents (current->window, False);
+ queue.head = current->next;
+ free (current);
+ current = queue.head;
+ }
+
+ if (!queue.head) queue.tail = 0;
+ }
+}
+
+/*
+ * Function for selecting all interesting events on a given
+ * (tree of) window(s).
+ */
+static void
+selectEvents (Window window, Bool substructureOnly)
+{
+ Window root; /* root window of the window */
+ Window parent; /* parent of the window */
+ Window* children; /* children of the window */
+ unsigned nofChildren = 0; /* number of children */
+ unsigned i; /* loop counter */
+ XWindowAttributes attribs; /* attributes of the window */
+
+ if( xautolock_ignoreWindow( window ))
+ return;
+ /*
+ * Start by querying the server about the root and parent windows.
+ */
+ if (!XQueryTree (queue.display, window, &root, &parent,
+ &children, &nofChildren))
+ {
+ return;
+ }
+
+ if (nofChildren) (void) XFree ((char*) children);
+
+ /*
+ * Build the appropriate event mask. The basic idea is that we don't
+ * want to interfere with the normal event propagation mechanism if
+ * we don't have to.
+ *
+ * On the root window, we need to ask for both substructureNotify
+ * and KeyPress events. On all other windows, we always need
+ * substructureNotify, but only need Keypress if some other client
+ * also asked for them, or if they are not being propagated up the
+ * window tree.
+ */
+#if 0
+ if (substructureOnly)
+ {
+ (void) XSelectInput (queue.display, window, SubstructureNotifyMask);
+ }
+ else
+ {
+ if (parent == None) /* the *real* rootwindow */
+ {
+ attribs.all_event_masks =
+ attribs.do_not_propagate_mask = KeyPressMask;
+ }
+ else if (!XGetWindowAttributes (queue.display, window, &attribs))
+#else
+ {
+ if (!XGetWindowAttributes (queue.display, window, &attribs))
+#endif
+ {
+ return;
+ }
+
+#if 0
+ (void) XSelectInput (queue.display, window,
+ SubstructureNotifyMask
+ | ( ( attribs.all_event_masks
+ | attribs.do_not_propagate_mask)
+ & KeyPressMask));
+#else
+ {
+ int mask = SubstructureNotifyMask | attribs.your_event_mask;
+ if( !substructureOnly )
+ {
+ mask |= ( ( attribs.all_event_masks
+ | attribs.do_not_propagate_mask)
+ & KeyPressMask );
+ }
+ (void) XSelectInput (queue.display, window, mask );
+ }
+#endif
+
+ }
+
+ /*
+ * Now ask for the list of children again, since it might have changed
+ * in between the last time and us selecting SubstructureNotifyMask.
+ *
+ * There is a (very small) chance that we might process a subtree twice:
+ * child windows that have been created after our XSelectinput() has
+ * been processed but before we get to the XQueryTree() bit will be
+ * in this situation. This is harmless. It could be avoided by using
+ * XGrabServer(), but that'd be an impolite thing to do, and since it
+ * isn't required...
+ */
+ if (!XQueryTree (queue.display, window, &root, &parent,
+ &children, &nofChildren))
+ {
+ return;
+ }
+
+ /*
+ * Now do the same thing for all children.
+ */
+ for (i = 0; i < nofChildren; ++i)
+ {
+ selectEvents (children[i], substructureOnly);
+ }
+
+ if (nofChildren) (void) XFree ((char*) children);
+}
+
+#if 0
+/*
+ * Function for processing any events that have come in since
+ * last time. It is crucial that this function does not block
+ * in case nothing interesting happened.
+ */
+void
+processEvents (void)
+{
+ while (XPending (queue.display))
+ {
+ XEvent event;
+
+ if (XCheckMaskEvent (queue.display, SubstructureNotifyMask, &event))
+ {
+ if (event.type == CreateNotify)
+ {
+ addToQueue (event.xcreatewindow.window);
+ }
+ }
+ else
+ {
+ (void) XNextEvent (queue.display, &event);
+ }
+
+ /*
+ * Reset the triggers if and only if the event is a
+ * KeyPress event *and* was not generated by XSendEvent().
+ */
+ if ( event.type == KeyPress
+ && !event.xany.send_event)
+ {
+ resetTriggers ();
+ }
+ }
+
+ /*
+ * Check the window queue for entries that are older than
+ * CREATION_DELAY seconds.
+ */
+ processQueue ((time_t) CREATION_DELAY);
+}
+#else
+void xautolock_processEvent( XEvent* event )
+{
+ if (event->type == CreateNotify)
+ {
+ addToQueue (event->xcreatewindow.window);
+ }
+ /*
+ * Reset the triggers if and only if the event is a
+ * KeyPress event *and* was not generated by XSendEvent().
+ */
+ if ( event->type == KeyPress
+ && !event->xany.send_event)
+ {
+ xautolock_resetTriggers ();
+ }
+}
+
+void xautolock_processQueue()
+{
+ /*
+ * Check the window queue for entries that are older than
+ * CREATION_DELAY seconds.
+ */
+ processQueue ((time_t) CREATION_DELAY);
+}
+#endif
+
+
+/*
+ * Function for initialising the whole shebang.
+ */
+void
+xautolock_initDiy (Display* d)
+{
+ int s;
+
+ queue.display = d;
+ queue.tail = 0;
+ queue.head = 0;
+
+ for (s = -1; ++s < ScreenCount (d); )
+ {
+ Window root = RootWindowOfScreen (ScreenOfDisplay (d, s));
+ addToQueue (root);
+#if 0
+ selectEvents (root, True);
+#endif
+ }
+}
diff --git a/klaptopdaemon/xautolock_engine.c b/klaptopdaemon/xautolock_engine.c
new file mode 100644
index 0000000..62f968a
--- /dev/null
+++ b/klaptopdaemon/xautolock_engine.c
@@ -0,0 +1,419 @@
+/*****************************************************************************
+ *
+ * Authors: Michel Eyckmans (MCE) & Stefan De Troch (SDT)
+ *
+ * Content: This file is part of version 2.x of xautolock. It implements
+ * the program's core functions.
+ *
+ * Please send bug reports etc. to eyckmans@imec.be.
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Copyright 1990,1992-1999,2001-2002 by Stefan De Troch and Michel Eyckmans.
+ *
+ * Versions 2.0 and above of xautolock are available under version 2 of the
+ * GNU GPL. Earlier versions are available under other conditions. For more
+ * information, see the License file.
+ *
+ *****************************************************************************/
+
+#include <X11/Xlib.h>
+#include <time.h>
+
+#include "xautolock_c.h"
+
+/*
+ * Function for querying the idle time from the server.
+ * Only used if either the Xidle or the Xscreensaver
+ * extension is present.
+ */
+void
+xautolock_queryIdleTime (Display* d)
+{
+ Time idleTime = 0; /* millisecs since last input event */
+
+#ifdef HasXidle
+ if (xautolock_useXidle)
+ {
+ XGetIdleTime (d, &idleTime);
+ }
+ else
+#endif /* HasXIdle */
+ {
+#ifdef HasScreenSaver
+ if( xautolock_useMit )
+ {
+ static XScreenSaverInfo* mitInfo = 0;
+ if (!mitInfo) mitInfo = XScreenSaverAllocInfo ();
+ XScreenSaverQueryInfo (d, DefaultRootWindow (d), mitInfo);
+ idleTime = mitInfo->idle;
+ }
+ else
+#endif /* HasScreenSaver */
+ {
+ d = d; /* shut up */
+ return; /* DIY */
+ }
+ }
+
+ if (idleTime < CHECK_INTERVAL )
+ {
+ xautolock_resetTriggers ();
+ }
+}
+
+/*
+ * Function for monitoring pointer movements. This implements the
+ * `corners' feature and as a side effect also tracks pointer
+ * related user activity. The latter actually is only needed when
+ * we're using the DIY mode of operations, but it's much simpler
+ * to do it unconditionally.
+ */
+void
+xautolock_queryPointer (Display* d)
+{
+ Window dummyWin; /* as it says */
+ int dummyInt; /* as it says */
+ unsigned mask; /* modifier mask */
+ int rootX; /* as it says */
+ int rootY; /* as it says */
+ int corner; /* corner index */
+ time_t now; /* as it says */
+ time_t newTrigger; /* temporary storage */
+ int i; /* loop counter */
+ static Window root; /* root window the pointer is on */
+ static Screen* screen; /* screen the pointer is on */
+ static unsigned prevMask = 0; /* as it says */
+ static int prevRootX = -1; /* as it says */
+ static int prevRootY = -1; /* as it says */
+ static Bool firstCall = True; /* as it says */
+
+ /*
+ * Have a guess...
+ */
+ if (firstCall)
+ {
+ firstCall = False;
+ root = DefaultRootWindow (d);
+ screen = ScreenOfDisplay (d, DefaultScreen (d));
+ }
+
+ /*
+ * Find out whether the pointer has moved. Using XQueryPointer for this
+ * is gross, but it also is the only way never to mess up propagation
+ * of pointer events.
+ */
+ if (!XQueryPointer (d, root, &root, &dummyWin, &rootX, &rootY,
+ &dummyInt, &dummyInt, &mask))
+ {
+ /*
+ * Pointer has moved to another screen, so let's find out which one.
+ */
+ for (i = -1; ++i < ScreenCount (d); )
+ {
+ if (root == RootWindow (d, i))
+ {
+ screen = ScreenOfDisplay (d, i);
+ break;
+ }
+ }
+ }
+
+ if ( rootX == prevRootX
+ && rootY == prevRootY
+ && mask == prevMask)
+ {
+ xautolock_corner_t* corners = xautolock_corners;
+ /*
+ * If the pointer has not moved since the previous call and
+ * is inside one of the 4 corners, we act according to the
+ * contents of the "corners" array.
+ *
+ * If rootX and rootY are less than zero, don't lock even if
+ * ca_forceLock is set in the upper-left corner. Why? 'cause
+ * on initial server startup, if (and only if) the pointer is
+ * never moved, XQueryPointer() can return values less than
+ * zero (only some servers, Openwindows 2.0 and 3.0 in
+ * particular).
+ */
+ if ( (corner = 0,
+ rootX <= cornerSize && rootX >= 0
+ && rootY <= cornerSize && rootY >= 0)
+ || (corner++,
+ rootX >= WidthOfScreen (screen) - cornerSize - 1
+ && rootY <= cornerSize)
+ || (corner++,
+ rootX <= cornerSize
+ && rootY >= HeightOfScreen (screen) - cornerSize - 1)
+ || (corner++,
+ rootX >= WidthOfScreen (screen) - cornerSize - 1
+ && rootY >= HeightOfScreen (screen) - cornerSize - 1))
+ {
+ now = time (0);
+
+ switch (corners[corner])
+ {
+ case ca_forceLock:
+#if 0
+ newTrigger = now + (useRedelay ? cornerRedelay : cornerDelay) - 1;
+#else
+ newTrigger = now + 2 - 1;
+#endif
+
+#if 0
+ if (newTrigger < lockTrigger)
+ {
+ setLockTrigger (newTrigger - now);
+ }
+#else
+ xautolock_setTrigger( newTrigger );
+#endif
+ break;
+
+ case ca_dontLock:
+ xautolock_resetTriggers ();
+
+#ifdef __GNUC__
+ default: ; /* Makes gcc -Wall shut up. */
+#endif /* __GNUC__ */
+ }
+ }
+ }
+ else
+ {
+#if 0
+ useRedelay = False;
+#endif
+ prevRootX = rootX;
+ prevRootY = rootY;
+ prevMask = mask;
+
+ xautolock_resetTriggers ();
+ }
+}
+
+#if 0
+/*
+ * Support for deciding whether to lock or kill.
+ */
+void
+evaluateTriggers (Display* d)
+{
+ static time_t prevNotification = 0;
+ time_t now = 0;
+
+ /*
+ * Obvious things first.
+ *
+ * The triggers are being moved all the time while in disabled
+ * mode in order to make absolutely sure we cannot run into
+ * trouble by an enable message coming in at an odd moment.
+ * Otherwise we possibly might lock or kill too soon.
+ */
+ if (disabled)
+ {
+ resetTriggers ();
+ }
+
+ /*
+ * Next, wait for (or kill, if we were so told) the previous
+ * locker (if any). Note that this must also be done while in
+ * disabled mode. Not only to avoid a potential zombie proces
+ * hanging around until we are re-enabled, but also to prevent
+ * us from incorrectly setting a kill trigger at the moment
+ * when we are finally re-enabled.
+ */
+#ifdef VMS
+ if (vmsStatus == 0)
+ {
+#else /* VMS */
+ if (lockerPid)
+ {
+#if !defined (UTEKV) && !defined (SYSV) && !defined (SVR4)
+ union wait status; /* childs process status */
+#else /* !UTEKV && !SYSV && !SVR4 */
+ int status = 0; /* childs process status */
+#endif /* !UTEKV && !SYSV && !SVR4 */
+
+ if (unlockNow && !disabled)
+ {
+ (void) kill (lockerPid, SIGTERM);
+ }
+
+#if !defined (UTEKV) && !defined (SYSV) && !defined (SVR4)
+ if (wait3 (&status, WNOHANG, 0))
+#else /* !UTEKV && !SYSV && !SVR4 */
+ if (waitpid (-1, &status, WNOHANG))
+#endif /* !UTEKV && !SYSV && !SVR4 */
+ {
+ /*
+ * If the locker exited normally, we disable any pending kill
+ * trigger. Otherwise, we assume that it either has crashed or
+ * was not able to lock the display because of an existing
+ * locker (which may have been started manually). In both of
+ * the later cases, disabling the kill trigger would open a
+ * loop hole.
+ */
+ if ( WIFEXITED (status)
+ && WEXITSTATUS (status) == EXIT_SUCCESS)
+ {
+ disableKillTrigger ();
+ }
+
+ useRedelay = True;
+ lockerPid = 0;
+ }
+#endif /* VMS */
+
+ setLockTrigger (lockTime);
+
+ /*
+ * No return here! The pointer may be sitting in a corner, while
+ * parameter settings may be such that we need to start another
+ * locker without further delay. If you think this cannot happen,
+ * consider the case in which the locker simply crashed.
+ */
+ }
+
+ unlockNow = False;
+
+ /*
+ * Note that the above lot needs to be done even when we're in
+ * disabled mode, since we may have entered said mode with an
+ * active locker around.
+ */
+ if (disabled) return;
+
+ /*
+ * Is it time to run the killer command?
+ */
+ now = time (0);
+
+ if (killTrigger && now >= killTrigger)
+ {
+ /*
+ * There is a dirty trick here. On the one hand, we don't want
+ * to block until the killer returns, but on the other one
+ * we don't want to have it interfere with the wait() stuff we
+ * do to keep track of the locker. To obtain both, the killer
+ * command has already been patched by KillerChecker() so that
+ * it gets backgrounded by the shell started by system().
+ *
+ * For the time being, VMS users are out of luck: their xautolock
+ * will indeed block until the killer returns.
+ */
+ (void) system (killer);
+ setKillTrigger (killTime);
+ }
+
+ /*
+ * Now trigger the notifier if required.
+ */
+ if ( notifyLock
+ && now + notifyMargin >= lockTrigger
+ && prevNotification < now - notifyMargin - 1)
+ {
+ if (notifierSpecified)
+ {
+ /*
+ * Here we use the same dirty trick as for the killer command.
+ */
+ (void) system (notifier);
+ }
+ else
+ {
+ (void) XBell (d, bellPercent);
+ (void) XSync (d, 0);
+ }
+
+ prevNotification = now;
+ }
+
+ /*
+ * Finally fire up the locker if time has somehow come.
+ */
+ if ( lockNow
+ || now >= lockTrigger)
+ {
+#ifdef VMS
+ if (vmsStatus != 0)
+#else /* VMS */
+ if (!lockerPid)
+#endif /* VMS */
+ {
+ switch (lockerPid = vfork ())
+ {
+ case -1:
+ lockerPid = 0;
+ break;
+
+ case 0:
+ (void) close (ConnectionNumber (d));
+#ifdef VMS
+ vmsStatus = 0;
+ lockerPid = lib$spawn ((lockNow ? &nowLockerDescr : &lockerDescr),
+ 0, 0, &1, 0, 0, &vmsStatus);
+
+ if (!(lockerPid & 1)) exit (lockerPid);
+
+#ifdef SLOW_VMS
+ (void) sleep (SLOW_VMS_DELAY);
+#endif /* SLOW_VMS */
+#else /* VMS */
+ (void) execl ("/bin/sh", "/bin/sh", "-c",
+ (lockNow ? nowLocker : locker), 0);
+#endif /* VMS */
+ _exit (EXIT_FAILURE);
+
+ default:
+ /*
+ * In general xautolock should keep its fingers off the real
+ * screensaver because no universally acceptable policy can
+ * be defined. In no case should it decide to disable or enable
+ * it all by itself. Setting the screensaver policy is something
+ * the locker should take care of. After all, xautolock is not
+ * supposed to know what the "locker" does and doesn't do.
+ * People might be using xautolock for totally different
+ * purposes (which, by the way, is why it will accept a
+ * different set of X resources after being renamed).
+ *
+ * Nevertheless, simply resetting the screensaver is a
+ * convenience action that aids many xlock users, and doesn't
+ * harm anyone (*). The problem with older versions of xlock
+ * is that they can be told to replace (= disable) the real
+ * screensaver, but forget to reset that same screensaver if
+ * it was already active at the time xlock starts. I guess
+ * xlock initially wasn't designed to be run without a user
+ * actually typing the comand ;-).
+ *
+ * (*) Well, at least it used not to harm anyone, but with the
+ * advent of DPMS monitors, it now can mess up the power
+ * saving setup. Hence we better make it optional.
+ *
+ * Also, some xlock versions also unconditionally call
+ * XResetScreenSaver, yielding the same kind of problems
+ * with DPMS that xautolock did. The latest and greatest
+ * xlocks also have a -resetsaver option for this very
+ * reason. You may want to upgrade.
+ */
+ if (resetSaver) (void) XResetScreenSaver(d);
+
+ setLockTrigger (lockTime);
+ (void) XSync (d,0);
+ }
+
+ /*
+ * Once the locker is running, all that needs to be done is to
+ * set the killTrigger if needed. Notice that this must be done
+ * even if we actually failed to start the locker. Otherwise
+ * the error would "propagate" from one feature to another.
+ */
+ if (killerSpecified) setKillTrigger (killTime);
+
+ useRedelay = False;
+ }
+
+ lockNow = False;
+ }
+}
+#endif