summaryrefslogtreecommitdiffstats
path: root/klaptopdaemon
diff options
context:
space:
mode:
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
+
+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 <[email protected]>
+ *
+ * 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 <[email protected]>
+ *
+ * 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 <[email protected]>
+ *
+ * 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 [email protected], 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 <[email protected]>
+ * Copyright (c) 2002 Marc Mutz <[email protected]>
+ *
+ * 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 <[email protected]>
+ *
+ * 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 <[email protected]>
+ * Copyright (c) 2002 Marc Mutz <[email protected]>
+ * Copyright (c) 2006 Flavio Castelli <[email protected]>
+ *
+ * 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 <[email protected]>
+ * Copyright (c) 2002 Marc Mutz <[email protected]>
+ * Copyright (c) 2006 Flavio Castelli <[email protected]>
+ *
+ * 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 <[email protected]>
+ * Copyright (c) 2002 Marc Mutz <[email protected]>
+ *
+ * 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 <[email protected]>
+ *
+ * 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 <[email protected]>
+ * 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 <[email protected]>
+ *
+ * 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 <[email protected]>
+ *
+ * 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 <[email protected]>
+ * Copyright (C) 2006 Flavio Castelli <[email protected]>
+ *
+ * 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 <[email protected]>
+ * Copyright (C) 2006 Flavio Castelli <[email protected]>
+ *
+ * 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 <[email protected]>
+ *
+ * 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 <[email protected]>
+ */
+
+#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 <[email protected]>
+ *
+ * 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 <[email protected]>
+ *
+ * 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 <[email protected]>
+ *
+ * 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 <[email protected]>
+
+ 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 <[email protected]>
+
+ 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 <[email protected]>
+ */
+
+/*
+ * 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 <[email protected]>
+ *
+ * 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, "[email protected]");
+ 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 <[email protected]>
+ *
+ * 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 <[email protected]>
+ *
+ * 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
+ * <[email protected]>. 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
+ * <[email protected]>. 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
+ * <[email protected]>. 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
+ * <[email protected]>. 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
+ * <[email protected]>. 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
+ * <[email protected]>. 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
+ * <[email protected]>. 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
+ * <[email protected]>. 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
+ * <[email protected]>. 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
+ * <[email protected]>. 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
+ * <[email protected]>. 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
+ * <[email protected]>. 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
+ * <[email protected]>. 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 <[email protected]>
+ *
+ * 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 [email protected]
+ *
+ * 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 <[email protected]>
+ * 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 <[email protected]>
+ *
+ * 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, "[email protected]");
+ 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 <[email protected]>
+ *
+ * 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
+
+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 <[email protected]>
+ *
+ * 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
+//
+//
+// Thanks to Cajus Pollmeier <[email protected]>
+// and Robert Ellis Parrott <[email protected]>
+// who both provided ACPI support
+// and Volker Krause <[email protected]> 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 <[email protected]> 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.
+// 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 [email protected]."), 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 <[email protected]>
+ *
+ * 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 <[email protected]>
+ * Copyright (c) 2002 Marc Mutz <[email protected]>
+ *
+ * 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 <[email protected]>
+ *
+ * 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 <[email protected]>
+ *
+ * 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 <[email protected]>
+ *
+ * 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 <[email protected]>
+ *
+ * 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 <[email protected]>
+ *
+ * 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 <[email protected]>
+ *
+ * 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 <[email protected]>
+ *
+ * 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 <[email protected]>
+ *
+ * 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 <[email protected]>
+ * Copyright (c) 2002 Marc Mutz <[email protected]>
+ *
+ * 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 <[email protected]>
+// Copyright (c) 2003 Lubos Lunak <[email protected]>
+//
+// 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 <[email protected]>
+//
+
+#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 [email protected].
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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 [email protected].
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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 [email protected].
+ *
+ * --------------------------------------------------------------------------
+ *
+ * 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